From 5029bf68358740742ccf9fecf867da1d15662186 Mon Sep 17 00:00:00 2001 From: Rene Rubalcava Date: Tue, 22 Nov 2011 21:00:13 +0000 Subject: [PATCH] first version --- Procfile | 1 + esritogeo.js | 66 + node_modules/.bin/express | 1 + node_modules/.bin/jade | 1 + node_modules/.bin/stylus | 1 + node_modules/express/.npmignore | 7 + node_modules/express/History.md | 770 +++++ node_modules/express/LICENSE | 22 + node_modules/express/Makefile | 29 + node_modules/express/Readme.md | 145 + node_modules/express/bin/express | 428 +++ node_modules/express/index.js | 2 + node_modules/express/lib/express.js | 79 + node_modules/express/lib/http.js | 583 ++++ node_modules/express/lib/https.js | 52 + node_modules/express/lib/request.js | 321 ++ node_modules/express/lib/response.js | 460 +++ node_modules/express/lib/router/collection.js | 53 + node_modules/express/lib/router/index.js | 398 +++ node_modules/express/lib/router/methods.js | 70 + node_modules/express/lib/router/route.js | 88 + node_modules/express/lib/utils.js | 152 + node_modules/express/lib/view.js | 457 +++ node_modules/express/lib/view/partial.js | 40 + node_modules/express/lib/view/view.js | 210 ++ .../express/node_modules/connect/.npmignore | 11 + .../express/node_modules/connect/LICENSE | 24 + .../express/node_modules/connect/index.js | 2 + .../express/node_modules/connect/lib/cache.js | 81 + .../node_modules/connect/lib/connect.js | 106 + .../express/node_modules/connect/lib/http.js | 217 ++ .../express/node_modules/connect/lib/https.js | 47 + .../express/node_modules/connect/lib/index.js | 46 + .../connect/lib/middleware/basicAuth.js | 93 + .../connect/lib/middleware/bodyParser.js | 172 + .../connect/lib/middleware/compiler.js | 163 + .../connect/lib/middleware/cookieParser.js | 46 + .../connect/lib/middleware/csrf.js | 105 + .../connect/lib/middleware/directory.js | 222 ++ .../connect/lib/middleware/errorHandler.js | 100 + .../connect/lib/middleware/favicon.js | 76 + .../connect/lib/middleware/limit.js | 82 + .../connect/lib/middleware/logger.js | 299 ++ .../connect/lib/middleware/methodOverride.js | 38 + .../connect/lib/middleware/profiler.js | 100 + .../connect/lib/middleware/query.js | 40 + .../connect/lib/middleware/responseTime.js | 34 + .../connect/lib/middleware/router.js | 379 ++ .../connect/lib/middleware/session.js | 346 ++ .../connect/lib/middleware/session/cookie.js | 126 + .../connect/lib/middleware/session/memory.js | 131 + .../connect/lib/middleware/session/session.js | 137 + .../connect/lib/middleware/session/store.js | 87 + .../connect/lib/middleware/static.js | 225 ++ .../connect/lib/middleware/staticCache.js | 175 + .../connect/lib/middleware/vhost.js | 44 + .../express/node_modules/connect/lib/patch.js | 79 + .../connect/lib/public/directory.html | 75 + .../connect/lib/public/error.html | 13 + .../connect/lib/public/favicon.ico | Bin 0 -> 1406 bytes .../connect/lib/public/icons/page.png | Bin 0 -> 635 bytes .../connect/lib/public/icons/page_add.png | Bin 0 -> 739 bytes .../connect/lib/public/icons/page_attach.png | Bin 0 -> 794 bytes .../connect/lib/public/icons/page_code.png | Bin 0 -> 818 bytes .../connect/lib/public/icons/page_copy.png | Bin 0 -> 663 bytes .../connect/lib/public/icons/page_delete.png | Bin 0 -> 740 bytes .../connect/lib/public/icons/page_edit.png | Bin 0 -> 807 bytes .../connect/lib/public/icons/page_error.png | Bin 0 -> 793 bytes .../connect/lib/public/icons/page_excel.png | Bin 0 -> 817 bytes .../connect/lib/public/icons/page_find.png | Bin 0 -> 879 bytes .../connect/lib/public/icons/page_gear.png | Bin 0 -> 833 bytes .../connect/lib/public/icons/page_go.png | Bin 0 -> 779 bytes .../connect/lib/public/icons/page_green.png | Bin 0 -> 621 bytes .../connect/lib/public/icons/page_key.png | Bin 0 -> 801 bytes .../lib/public/icons/page_lightning.png | Bin 0 -> 839 bytes .../connect/lib/public/icons/page_link.png | Bin 0 -> 830 bytes .../lib/public/icons/page_paintbrush.png | Bin 0 -> 813 bytes .../connect/lib/public/icons/page_paste.png | Bin 0 -> 703 bytes .../connect/lib/public/icons/page_red.png | Bin 0 -> 641 bytes .../connect/lib/public/icons/page_refresh.png | Bin 0 -> 858 bytes .../connect/lib/public/icons/page_save.png | Bin 0 -> 774 bytes .../connect/lib/public/icons/page_white.png | Bin 0 -> 294 bytes .../lib/public/icons/page_white_acrobat.png | Bin 0 -> 591 bytes .../public/icons/page_white_actionscript.png | Bin 0 -> 664 bytes .../lib/public/icons/page_white_add.png | Bin 0 -> 512 bytes .../connect/lib/public/icons/page_white_c.png | Bin 0 -> 587 bytes .../lib/public/icons/page_white_camera.png | Bin 0 -> 656 bytes .../lib/public/icons/page_white_cd.png | Bin 0 -> 666 bytes .../lib/public/icons/page_white_code.png | Bin 0 -> 603 bytes .../lib/public/icons/page_white_code_red.png | Bin 0 -> 587 bytes .../public/icons/page_white_coldfusion.png | Bin 0 -> 592 bytes .../public/icons/page_white_compressed.png | Bin 0 -> 724 bytes .../lib/public/icons/page_white_copy.png | Bin 0 -> 309 bytes .../lib/public/icons/page_white_cplusplus.png | Bin 0 -> 621 bytes .../lib/public/icons/page_white_csharp.png | Bin 0 -> 700 bytes .../lib/public/icons/page_white_cup.png | Bin 0 -> 639 bytes .../lib/public/icons/page_white_database.png | Bin 0 -> 579 bytes .../lib/public/icons/page_white_delete.png | Bin 0 -> 536 bytes .../lib/public/icons/page_white_dvd.png | Bin 0 -> 638 bytes .../lib/public/icons/page_white_edit.png | Bin 0 -> 618 bytes .../lib/public/icons/page_white_error.png | Bin 0 -> 623 bytes .../lib/public/icons/page_white_excel.png | Bin 0 -> 663 bytes .../lib/public/icons/page_white_find.png | Bin 0 -> 676 bytes .../lib/public/icons/page_white_flash.png | Bin 0 -> 582 bytes .../lib/public/icons/page_white_freehand.png | Bin 0 -> 639 bytes .../lib/public/icons/page_white_gear.png | Bin 0 -> 402 bytes .../lib/public/icons/page_white_get.png | Bin 0 -> 516 bytes .../lib/public/icons/page_white_go.png | Bin 0 -> 612 bytes .../connect/lib/public/icons/page_white_h.png | Bin 0 -> 603 bytes .../public/icons/page_white_horizontal.png | Bin 0 -> 296 bytes .../lib/public/icons/page_white_key.png | Bin 0 -> 616 bytes .../lib/public/icons/page_white_lightning.png | Bin 0 -> 669 bytes .../lib/public/icons/page_white_link.png | Bin 0 -> 614 bytes .../lib/public/icons/page_white_magnify.png | Bin 0 -> 554 bytes .../lib/public/icons/page_white_medal.png | Bin 0 -> 706 bytes .../lib/public/icons/page_white_office.png | Bin 0 -> 779 bytes .../lib/public/icons/page_white_paint.png | Bin 0 -> 688 bytes .../public/icons/page_white_paintbrush.png | Bin 0 -> 618 bytes .../lib/public/icons/page_white_paste.png | Bin 0 -> 620 bytes .../lib/public/icons/page_white_php.png | Bin 0 -> 538 bytes .../lib/public/icons/page_white_picture.png | Bin 0 -> 650 bytes .../public/icons/page_white_powerpoint.png | Bin 0 -> 588 bytes .../lib/public/icons/page_white_put.png | Bin 0 -> 523 bytes .../lib/public/icons/page_white_ruby.png | Bin 0 -> 626 bytes .../lib/public/icons/page_white_stack.png | Bin 0 -> 317 bytes .../lib/public/icons/page_white_star.png | Bin 0 -> 565 bytes .../lib/public/icons/page_white_swoosh.png | Bin 0 -> 634 bytes .../lib/public/icons/page_white_text.png | Bin 0 -> 342 bytes .../public/icons/page_white_text_width.png | Bin 0 -> 315 bytes .../lib/public/icons/page_white_tux.png | Bin 0 -> 668 bytes .../lib/public/icons/page_white_vector.png | Bin 0 -> 644 bytes .../public/icons/page_white_visualstudio.png | Bin 0 -> 702 bytes .../lib/public/icons/page_white_width.png | Bin 0 -> 309 bytes .../lib/public/icons/page_white_word.png | Bin 0 -> 651 bytes .../lib/public/icons/page_white_world.png | Bin 0 -> 734 bytes .../lib/public/icons/page_white_wrench.png | Bin 0 -> 613 bytes .../lib/public/icons/page_white_zip.png | Bin 0 -> 386 bytes .../connect/lib/public/icons/page_word.png | Bin 0 -> 777 bytes .../connect/lib/public/icons/page_world.png | Bin 0 -> 903 bytes .../node_modules/connect/lib/public/style.css | 141 + .../express/node_modules/connect/lib/utils.js | 451 +++ .../node_modules/formidable/.gitignore | 4 + .../node_modules/formidable/.npmignore | 4 + .../connect/node_modules/formidable/Makefile | 14 + .../connect/node_modules/formidable/Readme.md | 284 ++ .../connect/node_modules/formidable/TODO | 3 + .../benchmark/bench-multipart-parser.js | 70 + .../node_modules/formidable/example/post.js | 43 + .../node_modules/formidable/example/upload.js | 48 + .../connect/node_modules/formidable/index.js | 1 + .../node_modules/formidable/lib/file.js | 61 + .../formidable/lib/incoming_form.js | 374 ++ .../node_modules/formidable/lib/index.js | 3 + .../formidable/lib/multipart_parser.js | 312 ++ .../formidable/lib/querystring_parser.js | 25 + .../node_modules/formidable/lib/util.js | 6 + .../node_modules/formidable/package.json | 19 + .../node_modules/formidable/test/common.js | 20 + .../test/fast/test-incoming-form.js | 45 + .../test/fixture/file/funkyfilename.txt | 1 + .../formidable/test/fixture/file/plain.txt | 1 + .../http/special-chars-in-filename/info.md | 3 + .../formidable/test/fixture/js/no-filename.js | 3 + .../fixture/js/special-chars-in-filename.js | 21 + .../formidable/test/fixture/multipart.js | 72 + .../formidable/test/legacy/common.js | 24 + .../integration/test-multipart-parser.js | 80 + .../test/legacy/simple/test-file.js | 104 + .../test/legacy/simple/test-incoming-form.js | 715 ++++ .../legacy/simple/test-multipart-parser.js | 50 + .../legacy/simple/test-querystring-parser.js | 45 + .../legacy/system/test-multi-video-upload.js | 72 + .../node_modules/formidable/test/run.js | 7 + .../formidable/test/slow/test-fixtures.js | 84 + .../node_modules/formidable/tool/record.js | 47 + .../connect/node_modules/mime/LICENSE | 19 + .../connect/node_modules/mime/README.md | 50 + .../connect/node_modules/mime/mime.js | 92 + .../connect/node_modules/mime/package.json | 22 + .../connect/node_modules/mime/test.js | 79 + .../node_modules/mime/types/mime.types | 1479 ++++++++ .../node_modules/mime/types/node.types | 43 + .../connect/node_modules/qs/.gitignore | 1 + .../connect/node_modules/qs/.gitmodules | 6 + .../connect/node_modules/qs/History.md | 63 + .../connect/node_modules/qs/Makefile | 5 + .../connect/node_modules/qs/Readme.md | 47 + .../connect/node_modules/qs/benchmark.js | 17 + .../connect/node_modules/qs/examples.js | 48 + .../connect/node_modules/qs/index.js | 2 + .../node_modules/qs/lib/querystring.js | 262 ++ .../connect/node_modules/qs/package.json | 16 + .../connect/node_modules/qs/test/mocha.opts | 2 + .../connect/node_modules/qs/test/parse.js | 155 + .../connect/node_modules/qs/test/stringify.js | 95 + .../express/node_modules/connect/package.json | 25 + .../express/node_modules/connect/test.js | 11 + .../express/node_modules/mime/LICENSE | 19 + .../express/node_modules/mime/README.md | 50 + .../express/node_modules/mime/mime.js | 92 + .../express/node_modules/mime/package.json | 22 + .../express/node_modules/mime/test.js | 79 + .../node_modules/mime/types/mime.types | 1479 ++++++++ .../node_modules/mime/types/node.types | 43 + .../express/node_modules/mkdirp/.gitignore | 2 + .../node_modules/mkdirp/.gitignore.orig | 2 + .../node_modules/mkdirp/.gitignore.rej | 5 + .../express/node_modules/mkdirp/LICENSE | 21 + .../node_modules/mkdirp/README.markdown | 21 + .../node_modules/mkdirp/examples/pow.js | 6 + .../node_modules/mkdirp/examples/pow.js.orig | 6 + .../node_modules/mkdirp/examples/pow.js.rej | 19 + .../express/node_modules/mkdirp/index.js | 20 + .../express/node_modules/mkdirp/package.json | 23 + .../node_modules/mkdirp/test/mkdirp.js | 28 + .../express/node_modules/mkdirp/test/race.js | 41 + .../express/node_modules/mkdirp/test/rel.js | 32 + .../express/node_modules/qs/.gitignore | 1 + .../express/node_modules/qs/.gitmodules | 6 + .../express/node_modules/qs/History.md | 63 + node_modules/express/node_modules/qs/Makefile | 5 + .../express/node_modules/qs/Readme.md | 47 + .../express/node_modules/qs/benchmark.js | 17 + .../express/node_modules/qs/examples.js | 48 + node_modules/express/node_modules/qs/index.js | 2 + .../node_modules/qs/lib/querystring.js | 262 ++ .../express/node_modules/qs/package.json | 16 + .../express/node_modules/qs/test/mocha.opts | 2 + .../express/node_modules/qs/test/parse.js | 155 + .../express/node_modules/qs/test/stringify.js | 95 + node_modules/express/package.json | 39 + node_modules/express/testing/foo/app.js | 35 + node_modules/express/testing/foo/package.json | 9 + .../testing/foo/public/stylesheets/style.css | 8 + .../express/testing/foo/routes/index.js | 10 + .../express/testing/foo/views/index.jade | 2 + .../express/testing/foo/views/layout.jade | 6 + node_modules/express/testing/index.js | 43 + node_modules/express/testing/public/test.txt | 2971 ++++++++++++++++ node_modules/express/testing/views/page.html | 1 + node_modules/express/testing/views/page.jade | 3 + node_modules/express/testing/views/test.md | 1 + .../express/testing/views/user/index.jade | 1 + .../express/testing/views/user/list.jade | 1 + node_modules/jade/.gitignore | 4 + node_modules/jade/.gitmodules | 21 + node_modules/jade/.npmignore | 4 + node_modules/jade/History.md | 491 +++ node_modules/jade/LICENSE | 22 + node_modules/jade/Makefile | 37 + node_modules/jade/Readme.md | 966 ++++++ node_modules/jade/bin/jade | 125 + node_modules/jade/examples/attributes.jade | 8 + node_modules/jade/examples/attributes.js | 11 + node_modules/jade/examples/code.jade | 13 + node_modules/jade/examples/code.js | 16 + node_modules/jade/examples/csrf.jade | 5 + node_modules/jade/examples/csrf.js | 42 + node_modules/jade/examples/dynamicscript.jade | 5 + node_modules/jade/examples/dynamicscript.js | 20 + node_modules/jade/examples/each.jade | 3 + node_modules/jade/examples/each.js | 16 + node_modules/jade/examples/extend-layout.jade | 10 + node_modules/jade/examples/extend.jade | 11 + node_modules/jade/examples/extend.js | 18 + node_modules/jade/examples/form.jade | 29 + node_modules/jade/examples/form.js | 18 + node_modules/jade/examples/includes.jade | 7 + node_modules/jade/examples/includes.js | 11 + node_modules/jade/examples/includes/foot.jade | 2 + node_modules/jade/examples/includes/head.jade | 6 + .../jade/examples/includes/scripts.jade | 2 + node_modules/jade/examples/includes/style.css | 5 + node_modules/jade/examples/layout-debug.js | 11 + node_modules/jade/examples/layout.jade | 14 + node_modules/jade/examples/layout.js | 11 + node_modules/jade/examples/mixins.jade | 16 + node_modules/jade/examples/mixins.js | 16 + node_modules/jade/examples/mixins/dialog.jade | 15 + .../jade/examples/mixins/profile.jade | 10 + node_modules/jade/examples/model.jade | 9 + node_modules/jade/examples/model.js | 124 + .../jade/examples/nested-filters.jade | 8 + node_modules/jade/examples/nested-filters.js | 73 + node_modules/jade/examples/pet.jade | 3 + node_modules/jade/examples/rss.jade | 14 + node_modules/jade/examples/rss.js | 17 + node_modules/jade/examples/text.jade | 36 + node_modules/jade/examples/text.js | 11 + node_modules/jade/examples/whitespace.jade | 11 + node_modules/jade/examples/whitespace.js | 11 + node_modules/jade/index.js | 2 + node_modules/jade/jade.js | 3047 +++++++++++++++++ node_modules/jade/jade.min.js | 3 + node_modules/jade/lib/compiler.js | 501 +++ node_modules/jade/lib/doctypes.js | 18 + node_modules/jade/lib/filters.js | 92 + node_modules/jade/lib/index.js | 1 + node_modules/jade/lib/inline-tags.js | 28 + node_modules/jade/lib/jade.js | 235 ++ node_modules/jade/lib/lexer.js | 656 ++++ node_modules/jade/lib/nodes/block-comment.js | 33 + node_modules/jade/lib/nodes/block.js | 96 + node_modules/jade/lib/nodes/case.js | 43 + node_modules/jade/lib/nodes/code.js | 35 + node_modules/jade/lib/nodes/comment.js | 32 + node_modules/jade/lib/nodes/doctype.js | 29 + node_modules/jade/lib/nodes/each.js | 35 + node_modules/jade/lib/nodes/filter.js | 35 + node_modules/jade/lib/nodes/index.js | 20 + node_modules/jade/lib/nodes/literal.js | 31 + node_modules/jade/lib/nodes/mixin.js | 34 + node_modules/jade/lib/nodes/node.js | 14 + node_modules/jade/lib/nodes/tag.js | 80 + node_modules/jade/lib/nodes/text.js | 42 + node_modules/jade/lib/parser.js | 625 ++++ node_modules/jade/lib/runtime.js | 118 + node_modules/jade/lib/self-closing.js | 18 + node_modules/jade/lib/utils.js | 49 + node_modules/jade/package.json | 25 + node_modules/jade/runtime.js | 123 + node_modules/jade/runtime.min.js | 1 + node_modules/jade/support/benchmark.js | 62 + .../jade/support/coffee-script/.gitignore | 8 + .../jade/support/coffee-script/Cakefile | 134 + .../jade/support/coffee-script/LICENSE | 22 + .../jade/support/coffee-script/README | 48 + .../jade/support/coffee-script/Rakefile | 53 + .../jade/support/coffee-script/bin/cake | 8 + .../jade/support/coffee-script/bin/coffee | 8 + .../documentation/coffee/aliases.coffee | 11 + .../coffee/array_comprehensions.coffee | 7 + .../documentation/coffee/block_comment.coffee | 4 + .../documentation/coffee/cake_tasks.coffee | 9 + .../documentation/coffee/classes.coffee | 25 + .../documentation/coffee/comparisons.coffee | 5 + .../documentation/coffee/conditionals.coffee | 11 + .../documentation/coffee/embedded.coffee | 5 + .../documentation/coffee/existence.coffee | 8 + .../documentation/coffee/expressions.coffee | 9 + .../coffee/expressions_assignment.coffee | 1 + .../coffee/expressions_comprehension.coffee | 3 + .../coffee/expressions_try.coffee | 6 + .../documentation/coffee/fat_arrow.coffee | 6 + .../documentation/coffee/functions.coffee | 2 + .../documentation/coffee/heredocs.coffee | 5 + .../documentation/coffee/interpolation.coffee | 2 + .../coffee/interpolation_expression.coffee | 6 + .../coffee/multiple_return_values.coffee | 5 + .../coffee/object_comprehensions.coffee | 4 + .../coffee/object_extraction.coffee | 11 + .../coffee/objects_and_arrays.coffee | 17 + .../coffee/objects_reserved.coffee | 1 + .../documentation/coffee/overview.coffee | 28 + .../coffee/parallel_assignment.coffee | 4 + .../coffee/patterns_and_splats.coffee | 7 + .../documentation/coffee/prototypes.coffee | 2 + .../coffee/range_comprehensions.coffee | 6 + .../documentation/coffee/scope.coffee | 5 + .../documentation/coffee/slices.coffee | 6 + .../documentation/coffee/soaks.coffee | 1 + .../documentation/coffee/splats.coffee | 25 + .../documentation/coffee/splices.coffee | 5 + .../documentation/coffee/strings.coffee | 8 + .../documentation/coffee/switch.coffee | 10 + .../documentation/coffee/try.coffee | 7 + .../documentation/coffee/while.coffee | 10 + .../coffee-script/documentation/css/docs.css | 284 ++ .../coffee-script/documentation/css/idle.css | 64 + .../documentation/docs/browser.html | 24 + .../documentation/docs/cake.html | 43 + .../documentation/docs/coffee-script.html | 50 + .../documentation/docs/command.html | 148 + .../documentation/docs/docco.css | 185 + .../documentation/docs/grammar.html | 421 +++ .../documentation/docs/helpers.html | 37 + .../documentation/docs/index.html | 3 + .../documentation/docs/lexer.html | 431 +++ .../documentation/docs/nodes.html | 1245 +++++++ .../documentation/docs/optparse.html | 75 + .../documentation/docs/repl.html | 23 + .../documentation/docs/rewriter.html | 265 ++ .../documentation/docs/scope.html | 57 + .../documentation/docs/underscore.html | 296 ++ .../documentation/images/favicon.ico | Bin 0 -> 1406 bytes .../documentation/images/logo.png | Bin 0 -> 6059 bytes .../documentation/index.html.erb | 1364 ++++++++ .../coffee-script/documentation/js/aliases.js | 17 + .../documentation/js/array_comprehensions.js | 20 + .../documentation/js/block_comment.js | 4 + .../documentation/js/cake_tasks.js | 10 + .../coffee-script/documentation/js/classes.js | 42 + .../documentation/js/comparisons.js | 3 + .../documentation/js/conditionals.js | 12 + .../documentation/js/embedded.js | 4 + .../documentation/js/existence.js | 5 + .../documentation/js/expressions.js | 5 + .../js/expressions_assignment.js | 2 + .../js/expressions_comprehension.js | 10 + .../documentation/js/expressions_try.js | 7 + .../documentation/js/fat_arrow.js | 11 + .../documentation/js/functions.js | 7 + .../documentation/js/heredocs.js | 2 + .../documentation/js/interpolation.js | 3 + .../js/interpolation_expression.js | 4 + .../js/multiple_return_values.js | 5 + .../documentation/js/object_comprehensions.js | 16 + .../documentation/js/object_extraction.js | 10 + .../documentation/js/objects_and_arrays.js | 17 + .../documentation/js/objects_reserved.js | 3 + .../documentation/js/overview.js | 34 + .../documentation/js/parallel_assignment.js | 4 + .../documentation/js/patterns_and_splats.js | 4 + .../documentation/js/prototypes.js | 3 + .../documentation/js/range_comprehensions.js | 19 + .../coffee-script/documentation/js/scope.js | 8 + .../coffee-script/documentation/js/slices.js | 4 + .../coffee-script/documentation/js/soaks.js | 2 + .../coffee-script/documentation/js/splats.js | 15 + .../coffee-script/documentation/js/splices.js | 3 + .../coffee-script/documentation/js/strings.js | 2 + .../coffee-script/documentation/js/switch.js | 23 + .../coffee-script/documentation/js/try.js | 8 + .../coffee-script/documentation/js/while.js | 17 + .../beautiful_code/binary_search.coffee | 16 + .../beautiful_code/quicksort_runtime.coffee | 13 + .../regular_expression_matcher.coffee | 34 + .../coffee-script/examples/blocks.coffee | 54 + .../coffee-script/examples/code.coffee | 171 + .../examples/computer_science/README | 4 + .../computer_science/binary_search.coffee | 25 + .../computer_science/bubble_sort.coffee | 11 + .../computer_science/linked_list.coffee | 108 + .../computer_science/luhn_algorithm.coffee | 36 + .../computer_science/merge_sort.coffee | 19 + .../computer_science/selection_sort.coffee | 23 + .../coffee-script/examples/poignant.coffee | 181 + .../coffee-script/examples/potion.coffee | 206 ++ .../coffee-script/examples/underscore.coffee | 684 ++++ .../coffee-script/examples/web_server.coffee | 13 + .../jade/support/coffee-script/extras/EXTRAS | 7 + .../coffee-script/extras/coffee-script.js | 8 + .../support/coffee-script/extras/jsl.conf | 44 + .../jade/support/coffee-script/index.html | 2225 ++++++++++++ .../jade/support/coffee-script/lib/browser.js | 46 + .../jade/support/coffee-script/lib/cake.js | 73 + .../coffee-script/lib/coffee-script.js | 74 + .../jade/support/coffee-script/lib/command.js | 227 ++ .../jade/support/coffee-script/lib/grammar.js | 622 ++++ .../jade/support/coffee-script/lib/helpers.js | 78 + .../jade/support/coffee-script/lib/index.js | 9 + .../jade/support/coffee-script/lib/lexer.js | 638 ++++ .../jade/support/coffee-script/lib/nodes.js | 1981 +++++++++++ .../support/coffee-script/lib/optparse.js | 107 + .../jade/support/coffee-script/lib/parser.js | 687 ++++ .../jade/support/coffee-script/lib/repl.js | 38 + .../support/coffee-script/lib/rewriter.js | 378 ++ .../jade/support/coffee-script/lib/scope.js | 134 + .../support/coffee-script/lib/utilities.js | 12 + .../jade/support/coffee-script/package.json | 22 + .../support/coffee-script/src/browser.coffee | 41 + .../support/coffee-script/src/cake.coffee | 69 + .../coffee-script/src/coffee-script.coffee | 90 + .../support/coffee-script/src/command.coffee | 195 ++ .../support/coffee-script/src/grammar.coffee | 613 ++++ .../support/coffee-script/src/helpers.coffee | 72 + .../support/coffee-script/src/index.coffee | 2 + .../support/coffee-script/src/lexer.coffee | 635 ++++ .../support/coffee-script/src/nodes.coffee | 1710 +++++++++ .../support/coffee-script/src/optparse.coffee | 96 + .../support/coffee-script/src/repl.coffee | 35 + .../support/coffee-script/src/rewriter.coffee | 349 ++ .../support/coffee-script/src/scope.coffee | 109 + .../jade/support/coffee-script/test/test.html | 95 + .../coffee-script/test/test_arguments.coffee | 43 + .../coffee-script/test/test_assignment.coffee | 33 + .../coffee-script/test/test_break.coffee | 28 + .../coffee-script/test/test_chaining.coffee | 56 + .../coffee-script/test/test_classes.coffee | 291 ++ .../coffee-script/test/test_comments.coffee | 166 + .../test/test_compilation.coffee | 11 + .../test/test_compound_assignment.coffee | 26 + .../test/test_comprehensions.coffee | 172 + .../coffee-script/test/test_existence.coffee | 145 + .../test/test_expressions.coffee | 40 + .../coffee-script/test/test_functions.coffee | 346 ++ .../coffee-script/test/test_helpers.coffee | 49 + .../coffee-script/test/test_heredocs.coffee | 111 + .../support/coffee-script/test/test_if.coffee | 146 + .../coffee-script/test/test_importing.coffee | 3 + .../coffee-script/test/test_literals.coffee | 247 ++ .../coffee-script/test/test_module.coffee | 4 + .../coffee-script/test/test_operations.coffee | 154 + .../test/test_option_parser.coffee | 27 + .../test/test_pattern_matching.coffee | 160 + .../test_ranges_slices_and_splices.coffee | 75 + .../coffee-script/test/test_regexps.coffee | 45 + .../coffee-script/test/test_returns.coffee | 33 + .../coffee-script/test/test_splats.coffee | 125 + .../coffee-script/test/test_strings.coffee | 101 + .../coffee-script/test/test_switch.coffee | 98 + .../coffee-script/test/test_try_catch.coffee | 45 + .../coffee-script/test/test_while.coffee | 53 + node_modules/jade/support/compile.js | 173 + node_modules/jade/support/expresso/.gitignore | 3 + .../jade/support/expresso/.gitmodules | 3 + node_modules/jade/support/expresso/History.md | 97 + node_modules/jade/support/expresso/Makefile | 53 + node_modules/jade/support/expresso/Readme.md | 39 + .../jade/support/expresso/bin/expresso | 837 +++++ .../jade/support/expresso/docs/api.html | 1048 ++++++ .../jade/support/expresso/docs/index.html | 373 ++ .../jade/support/expresso/docs/index.md | 290 ++ .../support/expresso/docs/layout/foot.html | 3 + .../support/expresso/docs/layout/head.html | 42 + node_modules/jade/support/expresso/lib/bar.js | 4 + node_modules/jade/support/expresso/lib/foo.js | 16 + .../jade/support/expresso/package.json | 12 + .../jade/support/expresso/test/assert.test.js | 84 + .../jade/support/expresso/test/async.test.js | 6 + .../jade/support/expresso/test/bar.test.js | 12 + .../jade/support/expresso/test/foo.test.js | 13 + .../jade/support/expresso/test/http.test.js | 82 + .../expresso/test/serial/async.test.js | 38 + .../support/expresso/test/serial/http.test.js | 47 + node_modules/jade/support/foot.js | 4 + node_modules/jade/support/head.js | 2 + node_modules/jade/support/sass/.gitignore | 7 + node_modules/jade/support/sass/History.md | 42 + node_modules/jade/support/sass/Makefile | 11 + node_modules/jade/support/sass/Readme.md | 167 + node_modules/jade/support/sass/index.js | 1 + node_modules/jade/support/sass/lib/sass.js | 299 ++ node_modules/jade/support/sass/package.json | 10 + node_modules/jade/support/sass/seed.yml | 4 + .../support/sass/spec/fixtures/collect.sass | 3 + .../support/sass/spec/fixtures/comment.css | 2 + .../support/sass/spec/fixtures/comment.sass | 6 + .../sass/spec/fixtures/continuation.css | 8 + .../sass/spec/fixtures/continuation.sass | 8 + .../support/sass/spec/fixtures/literal.css | 2 + .../support/sass/spec/fixtures/literal.sass | 4 + .../jade/support/sass/spec/fixtures/mixin.css | 8 + .../support/sass/spec/fixtures/mixin.sass | 11 + .../sass/spec/fixtures/mixin.undefined.sass | 2 + .../support/sass/spec/fixtures/properties.css | 3 + .../sass/spec/fixtures/properties.expand.css | 3 + .../sass/spec/fixtures/properties.expand.sass | 2 + .../spec/fixtures/properties.invalid.sass | 2 + .../sass/spec/fixtures/properties.nested.css | 13 + .../fixtures/properties.nested.invalid.sass | 5 + .../sass/spec/fixtures/properties.nested.sass | 13 + .../sass/spec/fixtures/properties.sass | 3 + .../support/sass/spec/fixtures/selectors.css | 6 + .../support/sass/spec/fixtures/selectors.sass | 10 + .../spec/fixtures/variables.alternate.css | 2 + .../spec/fixtures/variables.alternate.sass | 4 + .../support/sass/spec/fixtures/variables.css | 2 + .../sass/spec/fixtures/variables.regular.css | 2 + .../sass/spec/fixtures/variables.regular.sass | 3 + .../support/sass/spec/fixtures/variables.sass | 5 + .../jade/support/sass/spec/lib/images/bg.png | Bin 0 -> 154 bytes .../jade/support/sass/spec/lib/images/hr.png | Bin 0 -> 321 bytes .../support/sass/spec/lib/images/loading.gif | Bin 0 -> 2608 bytes .../sass/spec/lib/images/sprites.bg.png | Bin 0 -> 4876 bytes .../support/sass/spec/lib/images/sprites.png | Bin 0 -> 3629 bytes .../jade/support/sass/spec/lib/images/vr.png | Bin 0 -> 145 bytes .../jade/support/sass/spec/lib/jspec.css | 149 + .../jade/support/sass/spec/lib/jspec.growl.js | 115 + .../support/sass/spec/lib/jspec.jquery.js | 79 + .../jade/support/sass/spec/lib/jspec.js | 1893 ++++++++++ .../support/sass/spec/lib/jspec.nodejs.js | 18 + .../jade/support/sass/spec/lib/jspec.shell.js | 39 + .../support/sass/spec/lib/jspec.timers.js | 90 + .../jade/support/sass/spec/lib/jspec.xhr.js | 210 ++ node_modules/jade/support/sass/spec/node.js | 9 + .../jade/support/sass/spec/spec.core.js | 134 + node_modules/jade/support/stylus/.gitignore | 4 + node_modules/jade/support/stylus/.gitmodules | 3 + node_modules/jade/support/stylus/.npmignore | 5 + node_modules/jade/support/stylus/History.md | 231 ++ node_modules/jade/support/stylus/LICENSE | 22 + node_modules/jade/support/stylus/Makefile | 20 + node_modules/jade/support/stylus/Readme.md | 118 + node_modules/jade/support/stylus/bin/stylus | 456 +++ .../jade/support/stylus/bin/stylus-tutorial | 287 ++ node_modules/jade/support/stylus/bm.js | 22 + node_modules/jade/support/stylus/docs/bifs.md | 453 +++ .../jade/support/stylus/docs/comments.md | 17 + .../jade/support/stylus/docs/compare.md | 81 + .../jade/support/stylus/docs/conditionals.md | 107 + .../jade/support/stylus/docs/css-style.md | 77 + .../support/stylus/docs/error-reporting.md | 50 + .../jade/support/stylus/docs/escape.md | 27 + .../jade/support/stylus/docs/executable.md | 92 + .../jade/support/stylus/docs/font-face.md | 26 + .../jade/support/stylus/docs/functions.md | 192 ++ .../jade/support/stylus/docs/functions.url.md | 30 + .../jade/support/stylus/docs/import.md | 73 + .../jade/support/stylus/docs/interpolation.md | 43 + .../jade/support/stylus/docs/introspection.md | 39 + .../jade/support/stylus/docs/iteration.md | 100 + node_modules/jade/support/stylus/docs/js.md | 108 + .../jade/support/stylus/docs/keyframes.md | 52 + .../jade/support/stylus/docs/literal.md | 16 + .../jade/support/stylus/docs/media.md | 18 + .../jade/support/stylus/docs/middleware.md | 55 + .../jade/support/stylus/docs/mixins.md | 132 + .../jade/support/stylus/docs/operators.md | 418 +++ .../jade/support/stylus/docs/selectors.md | 132 + .../jade/support/stylus/docs/textmate.md | 7 + .../jade/support/stylus/docs/vargs.md | 84 + .../jade/support/stylus/docs/variables.md | 29 + .../Syntaxes/Stylus.tmLanguage | 166 + .../stylus/editors/Stylus.tmbundle/info.plist | 10 + .../support/stylus/examples/arithmetic.js | 12 + .../support/stylus/examples/arithmetic.styl | 29 + .../jade/support/stylus/examples/basic.js | 12 + .../jade/support/stylus/examples/basic.styl | 8 + .../jade/support/stylus/examples/builtins.js | 12 + .../support/stylus/examples/builtins.styl | 56 + .../jade/support/stylus/examples/comments.js | 11 + .../support/stylus/examples/comments.styl | 15 + .../jade/support/stylus/examples/compress.js | 12 + .../support/stylus/examples/conversions.js | 12 + .../support/stylus/examples/conversions.styl | 34 + .../jade/support/stylus/examples/functions.js | 12 + .../support/stylus/examples/functions.styl | 30 + .../jade/support/stylus/examples/images.js | 20 + .../jade/support/stylus/examples/images.styl | 12 + .../support/stylus/examples/images/gopher.jpg | Bin 0 -> 50615 bytes .../support/stylus/examples/images/jesus.gif | Bin 0 -> 40716 bytes .../support/stylus/examples/images/sprite.gif | Bin 0 -> 935 bytes .../stylus/examples/implicit-functions.js | 12 + .../stylus/examples/implicit-functions.styl | 23 + .../jade/support/stylus/examples/import.js | 12 + .../jade/support/stylus/examples/import.styl | 11 + .../support/stylus/examples/js-functions.js | 55 + .../support/stylus/examples/js-functions.styl | 23 + .../jade/support/stylus/examples/literal.js | 12 + .../jade/support/stylus/examples/literal.styl | 8 + .../support/stylus/examples/middleware.js | 22 + .../support/stylus/examples/mixins/box.styl | 14 + .../jade/support/stylus/examples/nesting.js | 12 + .../jade/support/stylus/examples/nesting.styl | 14 + .../support/stylus/examples/public/.gitignore | 1 + .../jade/support/stylus/examples/variables.js | 12 + .../support/stylus/examples/variables.styl | 24 + node_modules/jade/support/stylus/index.js | 2 + .../jade/support/stylus/lib/colors.js | 156 + .../jade/support/stylus/lib/convert/css.js | 130 + .../support/stylus/lib/functions/image.js | 120 + .../support/stylus/lib/functions/index.js | 554 +++ .../support/stylus/lib/functions/index.styl | 131 + .../jade/support/stylus/lib/functions/url.js | 97 + node_modules/jade/support/stylus/lib/lexer.js | 672 ++++ .../jade/support/stylus/lib/middleware.js | 198 ++ .../jade/support/stylus/lib/nodes/binop.js | 52 + .../jade/support/stylus/lib/nodes/block.js | 98 + .../jade/support/stylus/lib/nodes/boolean.js | 83 + .../jade/support/stylus/lib/nodes/call.js | 56 + .../jade/support/stylus/lib/nodes/charset.js | 42 + .../jade/support/stylus/lib/nodes/each.js | 55 + .../support/stylus/lib/nodes/expression.js | 143 + .../jade/support/stylus/lib/nodes/function.js | 92 + .../jade/support/stylus/lib/nodes/group.js | 78 + .../jade/support/stylus/lib/nodes/hsla.js | 230 ++ .../jade/support/stylus/lib/nodes/ident.js | 97 + .../jade/support/stylus/lib/nodes/if.js | 54 + .../jade/support/stylus/lib/nodes/import.js | 30 + .../jade/support/stylus/lib/nodes/index.js | 48 + .../support/stylus/lib/nodes/keyframes.js | 57 + .../jade/support/stylus/lib/nodes/literal.js | 70 + .../jade/support/stylus/lib/nodes/media.js | 42 + .../jade/support/stylus/lib/nodes/node.js | 175 + .../jade/support/stylus/lib/nodes/null.js | 61 + .../jade/support/stylus/lib/nodes/page.js | 43 + .../jade/support/stylus/lib/nodes/params.js | 71 + .../jade/support/stylus/lib/nodes/property.js | 47 + .../jade/support/stylus/lib/nodes/return.js | 43 + .../jade/support/stylus/lib/nodes/rgba.js | 243 ++ .../jade/support/stylus/lib/nodes/root.js | 50 + .../jade/support/stylus/lib/nodes/selector.js | 55 + .../jade/support/stylus/lib/nodes/string.js | 101 + .../jade/support/stylus/lib/nodes/ternary.js | 50 + .../jade/support/stylus/lib/nodes/unaryop.js | 45 + .../jade/support/stylus/lib/nodes/unit.js | 188 + .../jade/support/stylus/lib/parser.js | 1360 ++++++++ .../jade/support/stylus/lib/renderer.js | 103 + .../jade/support/stylus/lib/stack/frame.js | 66 + .../jade/support/stylus/lib/stack/index.js | 146 + .../jade/support/stylus/lib/stack/scope.js | 53 + .../jade/support/stylus/lib/stylus.js | 132 + node_modules/jade/support/stylus/lib/token.js | 53 + node_modules/jade/support/stylus/lib/utils.js | 175 + .../support/stylus/lib/visitor/compiler.js | 370 ++ .../support/stylus/lib/visitor/evaluator.js | 911 +++++ .../jade/support/stylus/lib/visitor/index.js | 32 + node_modules/jade/support/stylus/package.json | 16 + .../stylus/test/cases/arithmetic.color.css | 7 + .../stylus/test/cases/arithmetic.color.styl | 7 + .../support/stylus/test/cases/arithmetic.css | 12 + .../support/stylus/test/cases/arithmetic.styl | 18 + .../stylus/test/cases/arithmetic.unary.css | 16 + .../stylus/test/cases/arithmetic.unary.styl | 16 + .../stylus/test/cases/bifs.components.css | 9 + .../stylus/test/cases/bifs.components.styl | 9 + .../support/stylus/test/cases/bifs.dark.css | 5 + .../support/stylus/test/cases/bifs.dark.styl | 4 + .../stylus/test/cases/bifs.darken-by.css | 5 + .../stylus/test/cases/bifs.darken-by.styl | 4 + .../stylus/test/cases/bifs.image-size.css | 9 + .../stylus/test/cases/bifs.image-size.styl | 19 + .../support/stylus/test/cases/bifs.join.css | 11 + .../support/stylus/test/cases/bifs.join.styl | 11 + .../support/stylus/test/cases/bifs.last.css | 5 + .../support/stylus/test/cases/bifs.last.styl | 6 + .../support/stylus/test/cases/bifs.length.css | 10 + .../stylus/test/cases/bifs.length.styl | 18 + .../support/stylus/test/cases/bifs.light.css | 5 + .../support/stylus/test/cases/bifs.light.styl | 4 + .../stylus/test/cases/bifs.lighten-by.css | 6 + .../stylus/test/cases/bifs.lighten-by.styl | 6 + .../stylus/test/cases/bifs.lookup.complex.css | 4 + .../test/cases/bifs.lookup.complex.styl | 11 + .../support/stylus/test/cases/bifs.lookup.css | 3 + .../stylus/test/cases/bifs.lookup.styl | 8 + .../support/stylus/test/cases/bifs.match.css | 4 + .../support/stylus/test/cases/bifs.match.styl | 9 + .../test/cases/bifs.opposite-position.css | 8 + .../test/cases/bifs.opposite-position.styl | 9 + .../support/stylus/test/cases/bifs.rgba.css | 5 + .../support/stylus/test/cases/bifs.rgba.styl | 4 + .../support/stylus/test/cases/bifs.type.css | 11 + .../support/stylus/test/cases/bifs.type.styl | 12 + .../support/stylus/test/cases/bifs.unit.css | 6 + .../support/stylus/test/cases/bifs.unit.styl | 5 + .../stylus/test/cases/bifs.unquote.css | 5 + .../stylus/test/cases/bifs.unquote.styl | 8 + .../support/stylus/test/cases/bifs.url.css | 11 + .../support/stylus/test/cases/bifs.url.styl | 15 + .../support/stylus/test/cases/coercion.css | 6 + .../support/stylus/test/cases/coercion.styl | 5 + .../support/stylus/test/cases/comments.css | 11 + .../support/stylus/test/cases/comments.styl | 28 + .../stylus/test/cases/compress.units.css | 2 + .../stylus/test/cases/compress.units.styl | 18 + .../test/cases/conditional-assignment.css | 4 + .../test/cases/conditional-assignment.styl | 9 + .../test/cases/css.functions.single-line.css | 9 + .../test/cases/css.functions.single-line.styl | 13 + .../jade/support/stylus/test/cases/css.if.css | 8 + .../support/stylus/test/cases/css.if.styl | 21 + .../stylus/test/cases/css.keyframes.css | 48 + .../stylus/test/cases/css.keyframes.styl | 39 + .../support/stylus/test/cases/css.large.css | 172 + .../support/stylus/test/cases/css.large.styl | 172 + .../support/stylus/test/cases/css.media.css | 15 + .../support/stylus/test/cases/css.media.styl | 17 + .../stylus/test/cases/css.mixins.braces.css | 31 + .../stylus/test/cases/css.mixins.braces.styl | 53 + .../support/stylus/test/cases/css.mixins.css | 31 + .../stylus/test/cases/css.mixins.root.css | 26 + .../stylus/test/cases/css.mixins.root.styl | 25 + .../test/cases/css.mixins.root.wonky.css | 26 + .../test/cases/css.mixins.root.wonky.styl | 17 + .../support/stylus/test/cases/css.mixins.styl | 47 + .../stylus/test/cases/css.selectors.css | 37 + .../stylus/test/cases/css.selectors.styl | 53 + .../stylus/test/cases/css.whitespace.css | 37 + .../stylus/test/cases/css.whitespace.styl | 36 + .../jade/support/stylus/test/cases/escape.css | 4 + .../support/stylus/test/cases/escape.styl | 4 + .../support/stylus/test/cases/for.complex.css | 44 + .../stylus/test/cases/for.complex.styl | 28 + .../jade/support/stylus/test/cases/for.css | 52 + .../stylus/test/cases/for.function.css | 20 + .../stylus/test/cases/for.function.styl | 51 + .../jade/support/stylus/test/cases/for.styl | 44 + .../stylus/test/cases/function.arguments.css | 4 + .../stylus/test/cases/function.arguments.styl | 14 + .../stylus/test/cases/function.literals.css | 6 + .../stylus/test/cases/function.literals.styl | 12 + .../stylus/test/cases/functions.arg-calls.css | 3 + .../test/cases/functions.arg-calls.styl | 9 + .../stylus/test/cases/functions.call.css | 4 + .../stylus/test/cases/functions.call.styl | 7 + .../support/stylus/test/cases/functions.css | 11 + .../stylus/test/cases/functions.defaults.css | 15 + .../stylus/test/cases/functions.defaults.styl | 30 + .../test/cases/functions.multi-line.css | 9 + .../test/cases/functions.multi-line.styl | 25 + .../test/cases/functions.multiple-calls.css | 13 + .../test/cases/functions.multiple-calls.styl | 26 + .../test/cases/functions.nested-calls.css | 3 + .../test/cases/functions.nested-calls.styl | 9 + .../stylus/test/cases/functions.nested.css | 10 + .../stylus/test/cases/functions.nested.styl | 37 + .../stylus/test/cases/functions.property.css | 10 + .../stylus/test/cases/functions.property.styl | 11 + .../stylus/test/cases/functions.return.css | 15 + .../test/cases/functions.return.each.css | 10 + .../test/cases/functions.return.each.styl | 23 + .../stylus/test/cases/functions.return.styl | 86 + .../support/stylus/test/cases/functions.styl | 34 + .../stylus/test/cases/functions.variable.css | 9 + .../test/cases/functions.variable.ident.css | 3 + .../test/cases/functions.variable.ident.styl | 11 + .../stylus/test/cases/functions.variable.styl | 27 + .../jade/support/stylus/test/cases/if.css | 43 + .../support/stylus/test/cases/if.else.css | 6 + .../support/stylus/test/cases/if.else.styl | 16 + .../support/stylus/test/cases/if.mixin.css | 7 + .../support/stylus/test/cases/if.mixin.styl | 24 + .../support/stylus/test/cases/if.postfix.css | 61 + .../support/stylus/test/cases/if.postfix.styl | 110 + .../stylus/test/cases/if.selectors.css | 6 + .../stylus/test/cases/if.selectors.styl | 12 + .../jade/support/stylus/test/cases/if.styl | 99 + .../stylus/test/cases/import.basic.css | 9 + .../stylus/test/cases/import.basic.styl | 2 + .../stylus/test/cases/import.basic/a.styl | 5 + .../stylus/test/cases/import.basic/b.styl | 5 + .../stylus/test/cases/import.basic/c.styl | 3 + .../stylus/test/cases/import.complex.css | 9 + .../stylus/test/cases/import.complex.styl | 1 + .../stylus/test/cases/import.complex/a.styl | 4 + .../stylus/test/cases/import.complex/c.styl | 2 + .../test/cases/import.complex/nested/b.styl | 4 + .../stylus/test/cases/import.index.css | 9 + .../stylus/test/cases/import.index.styl | 2 + .../test/cases/import.index/vendor/a.styl | 2 + .../test/cases/import.index/vendor/b.styl | 2 + .../test/cases/import.index/vendor/c.styl | 2 + .../test/cases/import.index/vendor/index.styl | 4 + .../stylus/test/cases/import.literal.css | 2 + .../stylus/test/cases/import.literal.styl | 3 + .../stylus/test/cases/import.mixins.css | 7 + .../stylus/test/cases/import.mixins.styl | 9 + .../stylus/test/cases/import.ordering.css | 15 + .../stylus/test/cases/import.ordering.styl | 12 + .../test/cases/import.ordering/five.styl | 2 + .../test/cases/import.ordering/four.styl | 4 + .../test/cases/import.ordering/two.styl | 2 + .../support/stylus/test/cases/important.css | 6 + .../support/stylus/test/cases/important.styl | 6 + .../test/cases/interpolation.properties.css | 40 + .../test/cases/interpolation.properties.styl | 56 + .../stylus/test/cases/introspection.css | 7 + .../stylus/test/cases/introspection.styl | 14 + .../jade/support/stylus/test/cases/jquery.css | 3 + .../support/stylus/test/cases/jquery.styl | 5 + .../jade/support/stylus/test/cases/list.css | 3 + .../jade/support/stylus/test/cases/list.styl | 3 + .../support/stylus/test/cases/literal.css | 5 + .../support/stylus/test/cases/literal.styl | 7 + .../jade/support/stylus/test/cases/media.css | 14 + .../jade/support/stylus/test/cases/media.styl | 11 + .../stylus/test/cases/mixin.conditional.css | 19 + .../stylus/test/cases/mixin.conditional.styl | 36 + .../test/cases/mixin.order.conditional.css | 11 + .../test/cases/mixin.order.conditional.styl | 20 + .../support/stylus/test/cases/mixin.order.css | 9 + .../stylus/test/cases/mixin.order.nested.css | 9 + .../stylus/test/cases/mixin.order.nested.styl | 21 + .../stylus/test/cases/mixin.order.styl | 20 + .../stylus/test/cases/mixins.complex.css | 30 + .../test/cases/mixins.complex.fix-to.css | 15 + .../test/cases/mixins.complex.fix-to.styl | 28 + .../stylus/test/cases/mixins.complex.styl | 41 + .../stylus/test/cases/mixins.conditional.css | 3 + .../stylus/test/cases/mixins.conditional.styl | 8 + .../stylus/test/cases/mixins.nested.css | 7 + .../test/cases/mixins.nested.selectors.css | 21 + .../test/cases/mixins.nested.selectors.styl | 31 + .../stylus/test/cases/mixins.nested.styl | 14 + .../stylus/test/cases/mixins.order.2.css | 11 + .../stylus/test/cases/mixins.order.2.styl | 16 + .../stylus/test/cases/mixins.return.css | 4 + .../stylus/test/cases/mixins.return.styl | 8 + .../support/stylus/test/cases/mixins.root.css | 3 + .../stylus/test/cases/mixins.root.styl | 5 + .../support/stylus/test/cases/mixins/box.styl | 11 + .../stylus/test/cases/operator.range.css | 15 + .../stylus/test/cases/operator.range.styl | 23 + .../cases/operators.assignment.function.css | 15 + .../cases/operators.assignment.function.styl | 34 + .../test/cases/operators.assignment.mixin.css | 15 + .../cases/operators.assignment.mixin.styl | 39 + .../test/cases/operators.assignment.root.css | 19 + .../test/cases/operators.assignment.root.styl | 43 + .../stylus/test/cases/operators.complex.css | 9 + .../stylus/test/cases/operators.complex.styl | 32 + .../support/stylus/test/cases/operators.css | 32 + .../stylus/test/cases/operators.equality.css | 12 + .../stylus/test/cases/operators.equality.styl | 31 + .../stylus/test/cases/operators.in.css | 36 + .../stylus/test/cases/operators.in.styl | 50 + .../stylus/test/cases/operators.mixins.css | 10 + .../stylus/test/cases/operators.mixins.styl | 25 + .../test/cases/operators.precedence.css | 51 + .../test/cases/operators.precedence.styl | 82 + .../support/stylus/test/cases/operators.styl | 86 + .../stylus/test/cases/operators.subscript.css | 59 + .../test/cases/operators.subscript.range.css | 14 + .../test/cases/operators.subscript.range.styl | 15 + .../test/cases/operators.subscript.styl | 81 + .../jade/support/stylus/test/cases/page.css | 13 + .../jade/support/stylus/test/cases/page.styl | 13 + .../jade/support/stylus/test/cases/parent.css | 32 + .../support/stylus/test/cases/parent.styl | 33 + .../stylus/test/cases/properties.colons.css | 8 + .../stylus/test/cases/properties.colons.styl | 10 + .../support/stylus/test/cases/properties.css | 4 + .../stylus/test/cases/properties.one-line.css | 10 + .../test/cases/properties.one-line.styl | 11 + .../support/stylus/test/cases/properties.styl | 4 + .../cases/regression.107.lookup-failure.css | 12 + .../cases/regression.107.lookup-failure.styl | 13 + .../stylus/test/cases/regression.127.css | 3 + .../stylus/test/cases/regression.127.styl | 2 + .../stylus/test/cases/regression.130.css | 16 + .../stylus/test/cases/regression.130.styl | 6 + .../stylus/test/cases/regression.131.css | 6 + .../stylus/test/cases/regression.131.styl | 2 + .../stylus/test/cases/regression.137.css | 7 + .../stylus/test/cases/regression.137.styl | 7 + .../stylus/test/cases/regression.139.css | 5 + .../stylus/test/cases/regression.139.styl | 21 + .../stylus/test/cases/regression.142.css | 39 + .../stylus/test/cases/regression.142.styl | 54 + .../stylus/test/cases/regression.146.css | 30 + .../stylus/test/cases/regression.146.styl | 31 + .../stylus/test/cases/regression.153.css | 8 + .../stylus/test/cases/regression.153.styl | 9 + .../stylus/test/cases/regression.154.css | 8 + .../stylus/test/cases/regression.154.styl | 14 + .../stylus/test/cases/regression.156.css | 4 + .../stylus/test/cases/regression.156.styl | 6 + .../stylus/test/cases/rule.charset.css | 1 + .../stylus/test/cases/rule.charset.styl | 2 + .../jade/support/stylus/test/cases/rulset.css | 4 + .../stylus/test/cases/rulset.newline.css | 5 + .../stylus/test/cases/rulset.newline.styl | 5 + .../support/stylus/test/cases/rulset.styl | 3 + .../stylus/test/cases/scope.complex.css | 10 + .../stylus/test/cases/scope.complex.styl | 16 + .../jade/support/stylus/test/cases/scope.css | 5 + .../stylus/test/cases/scope.nested.css | 9 + .../stylus/test/cases/scope.nested.styl | 10 + .../jade/support/stylus/test/cases/scope.styl | 12 + .../stylus/test/cases/selectors.complex.css | 28 + .../stylus/test/cases/selectors.complex.styl | 27 + .../support/stylus/test/cases/selectors.css | 44 + .../test/cases/selectors.nested.comma.css | 9 + .../test/cases/selectors.nested.comma.styl | 8 + .../stylus/test/cases/selectors.nested.css | 34 + .../stylus/test/cases/selectors.nested.styl | 33 + .../stylus/test/cases/selectors.pseudo.css | 27 + .../stylus/test/cases/selectors.pseudo.styl | 24 + .../support/stylus/test/cases/selectors.styl | 41 + .../stylus/test/cases/self-assignment.css | 3 + .../stylus/test/cases/self-assignment.styl | 4 + .../support/stylus/test/cases/vargs.call.css | 24 + .../support/stylus/test/cases/vargs.call.styl | 40 + .../jade/support/stylus/test/cases/vargs.css | 30 + .../jade/support/stylus/test/cases/vargs.styl | 49 + .../support/stylus/test/cases/variable.css | 3 + .../support/stylus/test/cases/variable.styl | 4 + .../support/stylus/test/cases/variables.css | 12 + .../support/stylus/test/cases/variables.styl | 17 + .../jade/support/stylus/test/images/gif | Bin 0 -> 59920 bytes .../support/stylus/test/images/squirrel.jpeg | Bin 0 -> 21805 bytes .../jade/support/stylus/test/images/tux.png | Bin 0 -> 41236 bytes node_modules/jade/support/stylus/test/run.js | 81 + node_modules/jade/test/filters.test.js | 151 + .../jade/test/fixtures/case-blocks.html | 1 + .../jade/test/fixtures/case-blocks.jade | 10 + node_modules/jade/test/fixtures/case.html | 1 + node_modules/jade/test/fixtures/case.jade | 8 + .../test/fixtures/conditional-comment.html | 6 + .../test/fixtures/conditional-comment.jade | 6 + node_modules/jade/test/fixtures/invalid.jade | 3 + node_modules/jade/test/fixtures/layout.jade | 3 + node_modules/jade/test/fixtures/mixins.html | 12 + node_modules/jade/test/fixtures/mixins.jade | 10 + node_modules/jade/test/fixtures/pet-page.jade | 11 + node_modules/jade/test/fixtures/pet.html | 15 + node_modules/jade/test/fixtures/pet.jade | 5 + node_modules/jade/test/fixtures/scripts.jade | 2 + .../jade/test/fixtures/super-pet.html | 15 + .../jade/test/fixtures/super-pet.jade | 5 + node_modules/jade/test/fixtures/test.css | 3 + .../jade/test/fixtures/user-layout.jade | 8 + node_modules/jade/test/fixtures/user.jade | 1 + node_modules/jade/test/fixtures/users.html | 17 + node_modules/jade/test/fixtures/users.jade | 11 + node_modules/jade/test/jade.test.js | 1023 ++++++ node_modules/stylus/.gitignore | 5 + node_modules/stylus/.gitmodules | 0 node_modules/stylus/.npmignore | 6 + node_modules/stylus/History.md | 565 +++ node_modules/stylus/LICENSE | 22 + node_modules/stylus/Makefile | 20 + node_modules/stylus/Readme.md | 149 + node_modules/stylus/bin/stylus | 606 ++++ node_modules/stylus/bm.js | 22 + node_modules/stylus/docs/bifs.md | 582 ++++ node_modules/stylus/docs/comments.md | 35 + node_modules/stylus/docs/compare.md | 81 + node_modules/stylus/docs/conditionals.md | 107 + node_modules/stylus/docs/css-style.md | 77 + node_modules/stylus/docs/error-reporting.md | 50 + node_modules/stylus/docs/escape.md | 27 + node_modules/stylus/docs/executable.md | 159 + node_modules/stylus/docs/firebug.md | 60 + node_modules/stylus/docs/font-face.md | 26 + node_modules/stylus/docs/functions.md | 192 ++ node_modules/stylus/docs/functions.url.md | 30 + node_modules/stylus/docs/gedit.md | 24 + node_modules/stylus/docs/import.md | 73 + node_modules/stylus/docs/interpolation.md | 55 + node_modules/stylus/docs/introspection.md | 39 + node_modules/stylus/docs/iteration.md | 100 + node_modules/stylus/docs/js.md | 145 + node_modules/stylus/docs/keyframes.md | 120 + node_modules/stylus/docs/kwargs.md | 35 + node_modules/stylus/docs/literal.md | 16 + node_modules/stylus/docs/media.md | 18 + node_modules/stylus/docs/middleware.md | 73 + node_modules/stylus/docs/mixins.md | 130 + node_modules/stylus/docs/operators.md | 451 +++ node_modules/stylus/docs/selectors.md | 131 + node_modules/stylus/docs/textmate.md | 4 + node_modules/stylus/docs/vargs.md | 84 + node_modules/stylus/docs/variables.md | 85 + .../Compile and Display CSS.tmCommand | 33 + .../Preferences/Comments.tmPreferences | 36 + .../Syntaxes/Stylus.tmLanguage | 166 + .../stylus/editors/Stylus.tmbundle/info.plist | 10 + node_modules/stylus/editors/gedit/styl.lang | 475 +++ node_modules/stylus/examples/arithmetic.js | 12 + node_modules/stylus/examples/arithmetic.styl | 29 + node_modules/stylus/examples/basic.js | 12 + node_modules/stylus/examples/basic.styl | 8 + node_modules/stylus/examples/builtins.js | 12 + node_modules/stylus/examples/builtins.styl | 56 + node_modules/stylus/examples/comments.js | 11 + node_modules/stylus/examples/comments.styl | 15 + node_modules/stylus/examples/compress.js | 12 + node_modules/stylus/examples/conversions.js | 12 + node_modules/stylus/examples/conversions.styl | 34 + node_modules/stylus/examples/functions.js | 12 + node_modules/stylus/examples/functions.styl | 30 + node_modules/stylus/examples/gradients.js | 13 + node_modules/stylus/examples/gradients.styl | 8 + node_modules/stylus/examples/images.js | 20 + node_modules/stylus/examples/images.styl | 15 + .../stylus/examples/images/gopher.jpg | Bin 0 -> 50615 bytes .../stylus/examples/images/gradient.svg | 9 + node_modules/stylus/examples/images/jesus.gif | Bin 0 -> 40716 bytes .../stylus/examples/images/sprite.gif | Bin 0 -> 935 bytes .../stylus/examples/implicit-functions.js | 12 + .../stylus/examples/implicit-functions.styl | 23 + node_modules/stylus/examples/import.js | 12 + node_modules/stylus/examples/import.styl | 11 + node_modules/stylus/examples/js-functions.js | 55 + .../stylus/examples/js-functions.styl | 23 + node_modules/stylus/examples/literal.js | 12 + node_modules/stylus/examples/literal.styl | 8 + node_modules/stylus/examples/middleware.js | 23 + node_modules/stylus/examples/mixins/box.styl | 14 + .../stylus/examples/mixins/gradients.styl | 92 + node_modules/stylus/examples/nesting.js | 12 + node_modules/stylus/examples/nesting.styl | 14 + .../stylus/examples/public/.gitignore | 1 + node_modules/stylus/examples/variables.js | 12 + node_modules/stylus/examples/variables.styl | 24 + node_modules/stylus/index.js | 2 + node_modules/stylus/lib/colors.js | 156 + node_modules/stylus/lib/convert/css.js | 130 + node_modules/stylus/lib/errors.js | 58 + node_modules/stylus/lib/functions/image.js | 120 + node_modules/stylus/lib/functions/index.js | 725 ++++ node_modules/stylus/lib/functions/index.styl | 137 + node_modules/stylus/lib/functions/url.js | 98 + node_modules/stylus/lib/lexer.js | 776 +++++ node_modules/stylus/lib/middleware.js | 227 ++ node_modules/stylus/lib/nodes/arguments.js | 65 + node_modules/stylus/lib/nodes/binop.js | 54 + node_modules/stylus/lib/nodes/block.js | 99 + node_modules/stylus/lib/nodes/boolean.js | 103 + node_modules/stylus/lib/nodes/call.js | 57 + node_modules/stylus/lib/nodes/charset.js | 42 + node_modules/stylus/lib/nodes/comment.js | 32 + node_modules/stylus/lib/nodes/each.js | 56 + node_modules/stylus/lib/nodes/expression.js | 200 ++ node_modules/stylus/lib/nodes/fontface.js | 55 + node_modules/stylus/lib/nodes/function.js | 104 + node_modules/stylus/lib/nodes/group.js | 79 + node_modules/stylus/lib/nodes/hsla.js | 256 ++ node_modules/stylus/lib/nodes/ident.js | 127 + node_modules/stylus/lib/nodes/if.js | 55 + node_modules/stylus/lib/nodes/import.js | 30 + node_modules/stylus/lib/nodes/index.js | 74 + node_modules/stylus/lib/nodes/jsliteral.js | 32 + node_modules/stylus/lib/nodes/keyframes.js | 78 + node_modules/stylus/lib/nodes/literal.js | 92 + node_modules/stylus/lib/nodes/media.js | 42 + node_modules/stylus/lib/nodes/node.js | 223 ++ node_modules/stylus/lib/nodes/null.js | 72 + node_modules/stylus/lib/nodes/page.js | 43 + node_modules/stylus/lib/nodes/params.js | 72 + node_modules/stylus/lib/nodes/property.js | 73 + node_modules/stylus/lib/nodes/return.js | 44 + node_modules/stylus/lib/nodes/rgba.js | 337 ++ node_modules/stylus/lib/nodes/root.js | 50 + node_modules/stylus/lib/nodes/selector.js | 57 + node_modules/stylus/lib/nodes/string.js | 122 + node_modules/stylus/lib/nodes/ternary.js | 51 + node_modules/stylus/lib/nodes/unaryop.js | 46 + node_modules/stylus/lib/nodes/unit.js | 207 ++ node_modules/stylus/lib/parser.js | 1530 +++++++++ node_modules/stylus/lib/renderer.js | 157 + node_modules/stylus/lib/stack/frame.js | 66 + node_modules/stylus/lib/stack/index.js | 146 + node_modules/stylus/lib/stack/scope.js | 53 + node_modules/stylus/lib/stylus.js | 103 + node_modules/stylus/lib/token.js | 53 + node_modules/stylus/lib/utils.js | 237 ++ node_modules/stylus/lib/visitor/compiler.js | 474 +++ node_modules/stylus/lib/visitor/evaluator.js | 1117 ++++++ node_modules/stylus/lib/visitor/index.js | 31 + node_modules/stylus/package.json | 16 + .../stylus/test/cases/arithmetic.color.css | 44 + .../stylus/test/cases/arithmetic.color.styl | 48 + node_modules/stylus/test/cases/arithmetic.css | 23 + .../stylus/test/cases/arithmetic.styl | 30 + .../stylus/test/cases/arithmetic.unary.css | 16 + .../stylus/test/cases/arithmetic.unary.styl | 16 + node_modules/stylus/test/cases/atscope.css | 21 + node_modules/stylus/test/cases/atscope.styl | 23 + .../stylus/test/cases/bifs.add-property.css | 21 + .../stylus/test/cases/bifs.add-property.styl | 48 + .../stylus/test/cases/bifs.components.css | 9 + .../stylus/test/cases/bifs.components.styl | 9 + node_modules/stylus/test/cases/bifs.dark.css | 5 + node_modules/stylus/test/cases/bifs.dark.styl | 4 + .../stylus/test/cases/bifs.darken.css | 8 + .../stylus/test/cases/bifs.darken.styl | 9 + node_modules/stylus/test/cases/bifs.fade.css | 6 + node_modules/stylus/test/cases/bifs.fade.styl | 6 + .../stylus/test/cases/bifs.image-size.css | 9 + .../stylus/test/cases/bifs.image-size.styl | 16 + node_modules/stylus/test/cases/bifs.join.css | 18 + node_modules/stylus/test/cases/bifs.join.styl | 21 + node_modules/stylus/test/cases/bifs.last.css | 5 + node_modules/stylus/test/cases/bifs.last.styl | 6 + .../stylus/test/cases/bifs.length.css | 10 + .../stylus/test/cases/bifs.length.styl | 18 + node_modules/stylus/test/cases/bifs.light.css | 5 + .../stylus/test/cases/bifs.light.styl | 4 + .../stylus/test/cases/bifs.lighten.css | 14 + .../stylus/test/cases/bifs.lighten.styl | 14 + .../stylus/test/cases/bifs.lookup.css | 3 + .../stylus/test/cases/bifs.lookup.styl | 8 + node_modules/stylus/test/cases/bifs.match.css | 4 + .../stylus/test/cases/bifs.match.styl | 9 + .../test/cases/bifs.opposite-position.css | 8 + .../test/cases/bifs.opposite-position.styl | 9 + node_modules/stylus/test/cases/bifs.push.css | 25 + node_modules/stylus/test/cases/bifs.push.styl | 48 + node_modules/stylus/test/cases/bifs.rgba.css | 5 + node_modules/stylus/test/cases/bifs.rgba.styl | 4 + node_modules/stylus/test/cases/bifs.s.css | 11 + node_modules/stylus/test/cases/bifs.s.styl | 12 + node_modules/stylus/test/cases/bifs.type.css | 11 + node_modules/stylus/test/cases/bifs.type.styl | 12 + node_modules/stylus/test/cases/bifs.unit.css | 6 + node_modules/stylus/test/cases/bifs.unit.styl | 5 + .../stylus/test/cases/bifs.unquote.css | 5 + .../stylus/test/cases/bifs.unquote.styl | 8 + node_modules/stylus/test/cases/bifs.url.css | 11 + node_modules/stylus/test/cases/bifs.url.styl | 15 + node_modules/stylus/test/cases/coercion.css | 6 + node_modules/stylus/test/cases/coercion.styl | 5 + node_modules/stylus/test/cases/comments.css | 18 + node_modules/stylus/test/cases/comments.styl | 28 + .../stylus/test/cases/compress.comments.css | 2 + .../stylus/test/cases/compress.comments.styl | 5 + .../stylus/test/cases/compress.units.css | 2 + .../stylus/test/cases/compress.units.styl | 18 + .../test/cases/conditional-assignment.css | 4 + .../test/cases/conditional-assignment.styl | 9 + .../test/cases/control.blueprint.ie.css | 126 + .../test/cases/control.blueprint.ie.styl | 36 + .../test/cases/control.blueprint.screen.css | 1103 ++++++ .../test/cases/control.blueprint.screen.styl | 265 ++ .../stylus/test/cases/control.boilerplate.css | 473 +++ .../test/cases/control.boilerplate.styl | 265 ++ .../test/cases/css.functions.single-line.css | 9 + .../test/cases/css.functions.single-line.styl | 13 + node_modules/stylus/test/cases/css.if.css | 8 + node_modules/stylus/test/cases/css.if.styl | 21 + .../stylus/test/cases/css.keyframes.css | 57 + .../stylus/test/cases/css.keyframes.styl | 48 + node_modules/stylus/test/cases/css.large.css | 172 + node_modules/stylus/test/cases/css.large.styl | 172 + node_modules/stylus/test/cases/css.media.css | 15 + node_modules/stylus/test/cases/css.media.styl | 17 + .../stylus/test/cases/css.mixins.braces.css | 38 + .../stylus/test/cases/css.mixins.braces.styl | 53 + node_modules/stylus/test/cases/css.mixins.css | 38 + .../stylus/test/cases/css.mixins.root.css | 26 + .../stylus/test/cases/css.mixins.root.styl | 25 + .../test/cases/css.mixins.root.wonky.css | 26 + .../test/cases/css.mixins.root.wonky.styl | 17 + .../stylus/test/cases/css.mixins.styl | 47 + .../test/cases/css.selector.interpolation.css | 91 + .../cases/css.selector.interpolation.styl | 90 + .../stylus/test/cases/css.selectors.css | 38 + .../stylus/test/cases/css.selectors.styl | 53 + .../stylus/test/cases/css.whitespace.css | 37 + .../stylus/test/cases/css.whitespace.styl | 38 + node_modules/stylus/test/cases/eol-escape.css | 11 + .../stylus/test/cases/eol-escape.styl | 27 + node_modules/stylus/test/cases/escape.css | 4 + node_modules/stylus/test/cases/escape.styl | 4 + node_modules/stylus/test/cases/fontface.css | 4 + node_modules/stylus/test/cases/fontface.styl | 5 + .../stylus/test/cases/for.complex.css | 44 + .../stylus/test/cases/for.complex.styl | 28 + node_modules/stylus/test/cases/for.css | 52 + .../stylus/test/cases/for.function.css | 20 + .../stylus/test/cases/for.function.styl | 51 + node_modules/stylus/test/cases/for.styl | 44 + .../stylus/test/cases/function.arguments.css | 4 + .../stylus/test/cases/function.arguments.styl | 14 + .../stylus/test/cases/function.literals.css | 6 + .../stylus/test/cases/function.literals.styl | 12 + .../stylus/test/cases/functions.arg-calls.css | 3 + .../test/cases/functions.arg-calls.styl | 9 + .../stylus/test/cases/functions.call.css | 4 + .../stylus/test/cases/functions.call.styl | 7 + node_modules/stylus/test/cases/functions.css | 11 + .../stylus/test/cases/functions.defaults.css | 15 + .../stylus/test/cases/functions.defaults.styl | 30 + .../test/cases/functions.multi-line.css | 9 + .../test/cases/functions.multi-line.styl | 25 + .../test/cases/functions.multiple-calls.css | 13 + .../test/cases/functions.multiple-calls.styl | 26 + .../test/cases/functions.nested-calls.css | 3 + .../test/cases/functions.nested-calls.styl | 9 + .../stylus/test/cases/functions.nested.css | 10 + .../stylus/test/cases/functions.nested.styl | 37 + .../stylus/test/cases/functions.property.css | 10 + .../stylus/test/cases/functions.property.styl | 11 + .../stylus/test/cases/functions.return.css | 15 + .../test/cases/functions.return.each.css | 10 + .../test/cases/functions.return.each.styl | 23 + .../stylus/test/cases/functions.return.styl | 86 + node_modules/stylus/test/cases/functions.styl | 34 + .../stylus/test/cases/functions.variable.css | 9 + .../test/cases/functions.variable.ident.css | 3 + .../test/cases/functions.variable.ident.styl | 11 + .../stylus/test/cases/functions.variable.styl | 27 + node_modules/stylus/test/cases/hack.star.css | 27 + node_modules/stylus/test/cases/hack.star.styl | 37 + node_modules/stylus/test/cases/if.css | 43 + node_modules/stylus/test/cases/if.else.css | 6 + node_modules/stylus/test/cases/if.else.styl | 16 + node_modules/stylus/test/cases/if.mixin.css | 7 + node_modules/stylus/test/cases/if.mixin.styl | 24 + node_modules/stylus/test/cases/if.postfix.css | 61 + .../stylus/test/cases/if.postfix.styl | 110 + .../stylus/test/cases/if.selectors.css | 16 + .../stylus/test/cases/if.selectors.styl | 22 + node_modules/stylus/test/cases/if.styl | 99 + .../stylus/test/cases/import.basic.css | 11 + .../stylus/test/cases/import.basic.styl | 4 + .../stylus/test/cases/import.basic/a.styl | 5 + .../stylus/test/cases/import.basic/b.styl | 5 + .../stylus/test/cases/import.basic/c.styl | 3 + .../stylus/test/cases/import.complex.css | 9 + .../stylus/test/cases/import.complex.styl | 1 + .../stylus/test/cases/import.complex/a.styl | 4 + .../stylus/test/cases/import.complex/c.styl | 2 + .../test/cases/import.complex/nested/b.styl | 4 + .../stylus/test/cases/import.index.css | 9 + .../stylus/test/cases/import.index.styl | 2 + .../test/cases/import.index/vendor/a.styl | 2 + .../test/cases/import.index/vendor/b.styl | 2 + .../test/cases/import.index/vendor/c.styl | 2 + .../test/cases/import.index/vendor/index.styl | 4 + .../stylus/test/cases/import.literal.css | 2 + .../stylus/test/cases/import.literal.styl | 3 + .../stylus/test/cases/import.mixins.css | 7 + .../stylus/test/cases/import.mixins.styl | 9 + .../stylus/test/cases/import.ordering.css | 15 + .../stylus/test/cases/import.ordering.styl | 12 + .../test/cases/import.ordering/five.styl | 2 + .../test/cases/import.ordering/four.styl | 4 + .../test/cases/import.ordering/two.styl | 2 + node_modules/stylus/test/cases/important.css | 6 + node_modules/stylus/test/cases/important.styl | 6 + .../test/cases/interpolation.properties.css | 40 + .../test/cases/interpolation.properties.styl | 56 + .../stylus/test/cases/introspection.css | 7 + .../stylus/test/cases/introspection.styl | 14 + node_modules/stylus/test/cases/jquery.css | 3 + node_modules/stylus/test/cases/jquery.styl | 5 + node_modules/stylus/test/cases/keyframes.css | 9 + .../test/cases/keyframes.fabrication.css | 18 + .../cases/keyframes.fabrication.defaults.css | 45 + .../cases/keyframes.fabrication.defaults.styl | 9 + .../test/cases/keyframes.fabrication.styl | 11 + node_modules/stylus/test/cases/keyframes.styl | 6 + node_modules/stylus/test/cases/kwargs.css | 63 + node_modules/stylus/test/cases/kwargs.styl | 74 + node_modules/stylus/test/cases/list.css | 3 + node_modules/stylus/test/cases/list.styl | 3 + .../stylus/test/cases/literal.color.css | 10 + .../stylus/test/cases/literal.color.styl | 9 + node_modules/stylus/test/cases/literal.css | 10 + node_modules/stylus/test/cases/literal.styl | 18 + node_modules/stylus/test/cases/media.css | 14 + node_modules/stylus/test/cases/media.styl | 11 + .../stylus/test/cases/mixin.conditional.css | 19 + .../stylus/test/cases/mixin.conditional.styl | 36 + .../test/cases/mixin.order.conditional.css | 11 + .../test/cases/mixin.order.conditional.styl | 20 + .../stylus/test/cases/mixin.order.css | 9 + .../stylus/test/cases/mixin.order.nested.css | 9 + .../stylus/test/cases/mixin.order.nested.styl | 21 + .../stylus/test/cases/mixin.order.styl | 20 + .../stylus/test/cases/mixins.complex.css | 30 + .../test/cases/mixins.complex.fix-to.css | 15 + .../test/cases/mixins.complex.fix-to.styl | 28 + .../stylus/test/cases/mixins.complex.styl | 41 + .../stylus/test/cases/mixins.conditional.css | 3 + .../stylus/test/cases/mixins.conditional.styl | 8 + .../stylus/test/cases/mixins.nested.css | 7 + .../test/cases/mixins.nested.selectors.css | 21 + .../test/cases/mixins.nested.selectors.styl | 31 + .../stylus/test/cases/mixins.nested.styl | 14 + .../stylus/test/cases/mixins.order.2.css | 11 + .../stylus/test/cases/mixins.order.2.styl | 16 + .../stylus/test/cases/mixins.reset.css | 75 + .../stylus/test/cases/mixins.reset.styl | 27 + .../stylus/test/cases/mixins.return.css | 4 + .../stylus/test/cases/mixins.return.styl | 8 + .../stylus/test/cases/mixins.root.css | 3 + .../stylus/test/cases/mixins.root.styl | 5 + .../stylus/test/cases/mixins/box.styl | 11 + .../stylus/test/cases/operator.range.css | 15 + .../stylus/test/cases/operator.range.styl | 23 + .../cases/operators.assignment.function.css | 15 + .../cases/operators.assignment.function.styl | 34 + .../test/cases/operators.assignment.mixin.css | 15 + .../cases/operators.assignment.mixin.styl | 39 + .../test/cases/operators.assignment.root.css | 25 + .../test/cases/operators.assignment.root.styl | 55 + .../stylus/test/cases/operators.complex.css | 9 + .../stylus/test/cases/operators.complex.styl | 32 + node_modules/stylus/test/cases/operators.css | 40 + .../stylus/test/cases/operators.equality.css | 55 + .../stylus/test/cases/operators.equality.styl | 55 + .../stylus/test/cases/operators.in.css | 37 + .../stylus/test/cases/operators.in.styl | 51 + .../stylus/test/cases/operators.mixins.css | 10 + .../stylus/test/cases/operators.mixins.styl | 25 + .../test/cases/operators.precedence.css | 51 + .../test/cases/operators.precedence.styl | 82 + node_modules/stylus/test/cases/operators.styl | 96 + .../test/cases/operators.subscript.assign.css | 21 + .../cases/operators.subscript.assign.styl | 45 + .../stylus/test/cases/operators.subscript.css | 59 + .../test/cases/operators.subscript.range.css | 14 + .../test/cases/operators.subscript.range.styl | 15 + .../test/cases/operators.subscript.styl | 81 + node_modules/stylus/test/cases/page.css | 13 + node_modules/stylus/test/cases/page.styl | 13 + node_modules/stylus/test/cases/parent.css | 32 + node_modules/stylus/test/cases/parent.styl | 33 + .../stylus/test/cases/properties.colons.css | 8 + .../stylus/test/cases/properties.colons.styl | 10 + node_modules/stylus/test/cases/properties.css | 4 + .../stylus/test/cases/properties.one-line.css | 10 + .../test/cases/properties.one-line.styl | 11 + .../stylus/test/cases/properties.styl | 4 + .../test/cases/property-access.bubble.css | 38 + .../test/cases/property-access.bubble.styl | 46 + .../stylus/test/cases/property-access.css | 48 + .../test/cases/property-access.siblings.css | 19 + .../test/cases/property-access.siblings.styl | 20 + .../stylus/test/cases/property-access.styl | 62 + .../cases/regression.107.lookup-failure.css | 12 + .../cases/regression.107.lookup-failure.styl | 13 + .../stylus/test/cases/regression.127.css | 3 + .../stylus/test/cases/regression.127.styl | 2 + .../stylus/test/cases/regression.130.css | 16 + .../stylus/test/cases/regression.130.styl | 6 + .../stylus/test/cases/regression.131.css | 7 + .../stylus/test/cases/regression.131.styl | 2 + .../stylus/test/cases/regression.137.css | 7 + .../stylus/test/cases/regression.137.styl | 7 + .../stylus/test/cases/regression.139.css | 5 + .../stylus/test/cases/regression.139.styl | 21 + .../stylus/test/cases/regression.142.css | 39 + .../stylus/test/cases/regression.142.styl | 54 + .../stylus/test/cases/regression.146.css | 30 + .../stylus/test/cases/regression.146.styl | 31 + .../stylus/test/cases/regression.153.css | 8 + .../stylus/test/cases/regression.153.styl | 9 + .../stylus/test/cases/regression.154.css | 8 + .../stylus/test/cases/regression.154.styl | 14 + .../stylus/test/cases/regression.156.css | 4 + .../stylus/test/cases/regression.156.styl | 6 + .../stylus/test/cases/regression.212.css | 15 + .../stylus/test/cases/regression.212.styl | 14 + .../stylus/test/cases/regression.216.css | 10 + .../stylus/test/cases/regression.216.styl | 8 + .../stylus/test/cases/regression.220.css | 5 + .../stylus/test/cases/regression.220.styl | 5 + .../stylus/test/cases/regression.229.css | 12 + .../stylus/test/cases/regression.229.styl | 9 + .../stylus/test/cases/regression.233.css | 6 + .../stylus/test/cases/regression.233.styl | 7 + .../stylus/test/cases/regression.235.css | 11 + .../stylus/test/cases/regression.235.styl | 13 + .../stylus/test/cases/regression.243.css | 3 + .../stylus/test/cases/regression.243.styl | 4 + .../stylus/test/cases/regression.244.css | 3 + .../stylus/test/cases/regression.244.styl | 3 + .../stylus/test/cases/regression.247.css | 6 + .../stylus/test/cases/regression.247.styl | 6 + .../test/cases/regression.248.compressed.css | 4 + .../test/cases/regression.248.compressed.styl | 10 + .../stylus/test/cases/regression.252.css | 13 + .../stylus/test/cases/regression.252.styl | 13 + .../stylus/test/cases/regression.260.css | 6 + .../stylus/test/cases/regression.260.styl | 6 + .../stylus/test/cases/regression.267.css | 3 + .../stylus/test/cases/regression.267.styl | 3 + .../stylus/test/cases/regression.270.css | 5 + .../stylus/test/cases/regression.270.styl | 7 + .../stylus/test/cases/regression.272.css | 11 + .../stylus/test/cases/regression.272.styl | 17 + .../stylus/test/cases/regression.274.css | 14 + .../stylus/test/cases/regression.274.styl | 16 + .../stylus/test/cases/regression.360.css | 19 + .../stylus/test/cases/regression.360.styl | 1 + .../stylus/test/cases/regression.368.css | 4 + .../stylus/test/cases/regression.368.styl | 3 + .../stylus/test/cases/regression.379.css | 6 + .../stylus/test/cases/regression.379.styl | 10 + .../stylus/test/cases/regression.380.css | 8 + .../stylus/test/cases/regression.380.styl | 14 + .../stylus/test/cases/regression.388.css | 2 + .../stylus/test/cases/regression.388.styl | 6 + .../stylus/test/cases/regression.415.css | 5 + .../stylus/test/cases/regression.415.styl | 3 + .../stylus/test/cases/regression.420.css | 21 + .../stylus/test/cases/regression.420.styl | 29 + .../stylus/test/cases/regression.440.css | 5 + .../stylus/test/cases/regression.440.styl | 7 + .../stylus/test/cases/regression.458.css | 3 + .../stylus/test/cases/regression.458.styl | 3 + .../stylus/test/cases/regression.460.css | 13 + .../stylus/test/cases/regression.460.styl | 18 + node_modules/stylus/test/cases/reset.css | 70 + node_modules/stylus/test/cases/reset.styl | 16 + .../stylus/test/cases/rule.charset.css | 1 + .../stylus/test/cases/rule.charset.styl | 2 + node_modules/stylus/test/cases/rulset.css | 4 + .../stylus/test/cases/rulset.newline.css | 5 + .../stylus/test/cases/rulset.newline.styl | 5 + node_modules/stylus/test/cases/rulset.styl | 3 + .../stylus/test/cases/scope.complex.css | 10 + .../stylus/test/cases/scope.complex.styl | 16 + node_modules/stylus/test/cases/scope.css | 5 + .../stylus/test/cases/scope.nested.css | 9 + .../stylus/test/cases/scope.nested.styl | 10 + node_modules/stylus/test/cases/scope.styl | 12 + .../test/cases/selector.interpolation.css | 57 + .../test/cases/selector.interpolation.styl | 45 + .../stylus/test/cases/selectors.complex.css | 28 + .../stylus/test/cases/selectors.complex.styl | 27 + node_modules/stylus/test/cases/selectors.css | 50 + .../test/cases/selectors.nested.comma.css | 9 + .../test/cases/selectors.nested.comma.styl | 8 + .../stylus/test/cases/selectors.nested.css | 34 + .../stylus/test/cases/selectors.nested.styl | 33 + .../stylus/test/cases/selectors.pseudo.css | 27 + .../test/cases/selectors.pseudo.elements.css | 26 + .../test/cases/selectors.pseudo.elements.styl | 29 + .../stylus/test/cases/selectors.pseudo.styl | 24 + node_modules/stylus/test/cases/selectors.styl | 46 + .../stylus/test/cases/self-assignment.css | 3 + .../stylus/test/cases/self-assignment.styl | 4 + node_modules/stylus/test/cases/vargs.call.css | 24 + .../stylus/test/cases/vargs.call.styl | 40 + node_modules/stylus/test/cases/vargs.css | 30 + node_modules/stylus/test/cases/vargs.styl | 49 + node_modules/stylus/test/cases/variable.css | 3 + node_modules/stylus/test/cases/variable.styl | 4 + node_modules/stylus/test/cases/variables.css | 12 + node_modules/stylus/test/cases/variables.styl | 17 + node_modules/stylus/test/images/gif | Bin 0 -> 59920 bytes node_modules/stylus/test/images/squirrel.jpeg | Bin 0 -> 21805 bytes node_modules/stylus/test/images/tux.png | Bin 0 -> 41236 bytes node_modules/stylus/test/run.js | 152 + package.json | 9 + public/stylesheets/mixins/css3.styl | 56 + public/stylesheets/partials/typography.styl | 54 + public/stylesheets/style.styl | 116 + views/index.jade | 11 + views/layout.jade | 8 + web.js | 49 + 1519 files changed, 101090 insertions(+) create mode 100644 Procfile create mode 100644 esritogeo.js create mode 120000 node_modules/.bin/express create mode 120000 node_modules/.bin/jade create mode 120000 node_modules/.bin/stylus create mode 100644 node_modules/express/.npmignore create mode 100644 node_modules/express/History.md create mode 100644 node_modules/express/LICENSE create mode 100644 node_modules/express/Makefile create mode 100644 node_modules/express/Readme.md create mode 100755 node_modules/express/bin/express create mode 100644 node_modules/express/index.js create mode 100644 node_modules/express/lib/express.js create mode 100644 node_modules/express/lib/http.js create mode 100644 node_modules/express/lib/https.js create mode 100644 node_modules/express/lib/request.js create mode 100644 node_modules/express/lib/response.js create mode 100644 node_modules/express/lib/router/collection.js create mode 100644 node_modules/express/lib/router/index.js create mode 100644 node_modules/express/lib/router/methods.js create mode 100644 node_modules/express/lib/router/route.js create mode 100644 node_modules/express/lib/utils.js create mode 100644 node_modules/express/lib/view.js create mode 100644 node_modules/express/lib/view/partial.js create mode 100644 node_modules/express/lib/view/view.js create mode 100644 node_modules/express/node_modules/connect/.npmignore create mode 100644 node_modules/express/node_modules/connect/LICENSE create mode 100644 node_modules/express/node_modules/connect/index.js create mode 100644 node_modules/express/node_modules/connect/lib/cache.js create mode 100644 node_modules/express/node_modules/connect/lib/connect.js create mode 100644 node_modules/express/node_modules/connect/lib/http.js create mode 100644 node_modules/express/node_modules/connect/lib/https.js create mode 100644 node_modules/express/node_modules/connect/lib/index.js create mode 100644 node_modules/express/node_modules/connect/lib/middleware/basicAuth.js create mode 100644 node_modules/express/node_modules/connect/lib/middleware/bodyParser.js create mode 100644 node_modules/express/node_modules/connect/lib/middleware/compiler.js create mode 100644 node_modules/express/node_modules/connect/lib/middleware/cookieParser.js create mode 100644 node_modules/express/node_modules/connect/lib/middleware/csrf.js create mode 100644 node_modules/express/node_modules/connect/lib/middleware/directory.js create mode 100644 node_modules/express/node_modules/connect/lib/middleware/errorHandler.js create mode 100644 node_modules/express/node_modules/connect/lib/middleware/favicon.js create mode 100644 node_modules/express/node_modules/connect/lib/middleware/limit.js create mode 100644 node_modules/express/node_modules/connect/lib/middleware/logger.js create mode 100644 node_modules/express/node_modules/connect/lib/middleware/methodOverride.js create mode 100644 node_modules/express/node_modules/connect/lib/middleware/profiler.js create mode 100644 node_modules/express/node_modules/connect/lib/middleware/query.js create mode 100644 node_modules/express/node_modules/connect/lib/middleware/responseTime.js create mode 100644 node_modules/express/node_modules/connect/lib/middleware/router.js create mode 100644 node_modules/express/node_modules/connect/lib/middleware/session.js create mode 100644 node_modules/express/node_modules/connect/lib/middleware/session/cookie.js create mode 100644 node_modules/express/node_modules/connect/lib/middleware/session/memory.js create mode 100644 node_modules/express/node_modules/connect/lib/middleware/session/session.js create mode 100644 node_modules/express/node_modules/connect/lib/middleware/session/store.js create mode 100644 node_modules/express/node_modules/connect/lib/middleware/static.js create mode 100644 node_modules/express/node_modules/connect/lib/middleware/staticCache.js create mode 100644 node_modules/express/node_modules/connect/lib/middleware/vhost.js create mode 100644 node_modules/express/node_modules/connect/lib/patch.js create mode 100644 node_modules/express/node_modules/connect/lib/public/directory.html create mode 100644 node_modules/express/node_modules/connect/lib/public/error.html create mode 100644 node_modules/express/node_modules/connect/lib/public/favicon.ico create mode 100755 node_modules/express/node_modules/connect/lib/public/icons/page.png create mode 100755 node_modules/express/node_modules/connect/lib/public/icons/page_add.png create mode 100755 node_modules/express/node_modules/connect/lib/public/icons/page_attach.png create mode 100755 node_modules/express/node_modules/connect/lib/public/icons/page_code.png create mode 100755 node_modules/express/node_modules/connect/lib/public/icons/page_copy.png create mode 100755 node_modules/express/node_modules/connect/lib/public/icons/page_delete.png create mode 100755 node_modules/express/node_modules/connect/lib/public/icons/page_edit.png create mode 100755 node_modules/express/node_modules/connect/lib/public/icons/page_error.png create mode 100755 node_modules/express/node_modules/connect/lib/public/icons/page_excel.png create mode 100755 node_modules/express/node_modules/connect/lib/public/icons/page_find.png create mode 100755 node_modules/express/node_modules/connect/lib/public/icons/page_gear.png create mode 100755 node_modules/express/node_modules/connect/lib/public/icons/page_go.png create mode 100755 node_modules/express/node_modules/connect/lib/public/icons/page_green.png create mode 100755 node_modules/express/node_modules/connect/lib/public/icons/page_key.png create mode 100755 node_modules/express/node_modules/connect/lib/public/icons/page_lightning.png create mode 100755 node_modules/express/node_modules/connect/lib/public/icons/page_link.png create mode 100755 node_modules/express/node_modules/connect/lib/public/icons/page_paintbrush.png create mode 100755 node_modules/express/node_modules/connect/lib/public/icons/page_paste.png create mode 100755 node_modules/express/node_modules/connect/lib/public/icons/page_red.png create mode 100755 node_modules/express/node_modules/connect/lib/public/icons/page_refresh.png create mode 100755 node_modules/express/node_modules/connect/lib/public/icons/page_save.png create mode 100755 node_modules/express/node_modules/connect/lib/public/icons/page_white.png create mode 100755 node_modules/express/node_modules/connect/lib/public/icons/page_white_acrobat.png create mode 100755 node_modules/express/node_modules/connect/lib/public/icons/page_white_actionscript.png create mode 100755 node_modules/express/node_modules/connect/lib/public/icons/page_white_add.png create mode 100755 node_modules/express/node_modules/connect/lib/public/icons/page_white_c.png create mode 100755 node_modules/express/node_modules/connect/lib/public/icons/page_white_camera.png create mode 100755 node_modules/express/node_modules/connect/lib/public/icons/page_white_cd.png create mode 100755 node_modules/express/node_modules/connect/lib/public/icons/page_white_code.png create mode 100755 node_modules/express/node_modules/connect/lib/public/icons/page_white_code_red.png create mode 100755 node_modules/express/node_modules/connect/lib/public/icons/page_white_coldfusion.png create mode 100755 node_modules/express/node_modules/connect/lib/public/icons/page_white_compressed.png create mode 100755 node_modules/express/node_modules/connect/lib/public/icons/page_white_copy.png create mode 100755 node_modules/express/node_modules/connect/lib/public/icons/page_white_cplusplus.png create mode 100755 node_modules/express/node_modules/connect/lib/public/icons/page_white_csharp.png create mode 100755 node_modules/express/node_modules/connect/lib/public/icons/page_white_cup.png create mode 100755 node_modules/express/node_modules/connect/lib/public/icons/page_white_database.png create mode 100755 node_modules/express/node_modules/connect/lib/public/icons/page_white_delete.png create mode 100755 node_modules/express/node_modules/connect/lib/public/icons/page_white_dvd.png create mode 100755 node_modules/express/node_modules/connect/lib/public/icons/page_white_edit.png create mode 100755 node_modules/express/node_modules/connect/lib/public/icons/page_white_error.png create mode 100755 node_modules/express/node_modules/connect/lib/public/icons/page_white_excel.png create mode 100755 node_modules/express/node_modules/connect/lib/public/icons/page_white_find.png create mode 100755 node_modules/express/node_modules/connect/lib/public/icons/page_white_flash.png create mode 100755 node_modules/express/node_modules/connect/lib/public/icons/page_white_freehand.png create mode 100755 node_modules/express/node_modules/connect/lib/public/icons/page_white_gear.png create mode 100755 node_modules/express/node_modules/connect/lib/public/icons/page_white_get.png create mode 100755 node_modules/express/node_modules/connect/lib/public/icons/page_white_go.png create mode 100755 node_modules/express/node_modules/connect/lib/public/icons/page_white_h.png create mode 100755 node_modules/express/node_modules/connect/lib/public/icons/page_white_horizontal.png create mode 100755 node_modules/express/node_modules/connect/lib/public/icons/page_white_key.png create mode 100755 node_modules/express/node_modules/connect/lib/public/icons/page_white_lightning.png create mode 100755 node_modules/express/node_modules/connect/lib/public/icons/page_white_link.png create mode 100755 node_modules/express/node_modules/connect/lib/public/icons/page_white_magnify.png create mode 100755 node_modules/express/node_modules/connect/lib/public/icons/page_white_medal.png create mode 100755 node_modules/express/node_modules/connect/lib/public/icons/page_white_office.png create mode 100755 node_modules/express/node_modules/connect/lib/public/icons/page_white_paint.png create mode 100755 node_modules/express/node_modules/connect/lib/public/icons/page_white_paintbrush.png create mode 100755 node_modules/express/node_modules/connect/lib/public/icons/page_white_paste.png create mode 100755 node_modules/express/node_modules/connect/lib/public/icons/page_white_php.png create mode 100755 node_modules/express/node_modules/connect/lib/public/icons/page_white_picture.png create mode 100755 node_modules/express/node_modules/connect/lib/public/icons/page_white_powerpoint.png create mode 100755 node_modules/express/node_modules/connect/lib/public/icons/page_white_put.png create mode 100755 node_modules/express/node_modules/connect/lib/public/icons/page_white_ruby.png create mode 100755 node_modules/express/node_modules/connect/lib/public/icons/page_white_stack.png create mode 100755 node_modules/express/node_modules/connect/lib/public/icons/page_white_star.png create mode 100755 node_modules/express/node_modules/connect/lib/public/icons/page_white_swoosh.png create mode 100755 node_modules/express/node_modules/connect/lib/public/icons/page_white_text.png create mode 100755 node_modules/express/node_modules/connect/lib/public/icons/page_white_text_width.png create mode 100755 node_modules/express/node_modules/connect/lib/public/icons/page_white_tux.png create mode 100755 node_modules/express/node_modules/connect/lib/public/icons/page_white_vector.png create mode 100755 node_modules/express/node_modules/connect/lib/public/icons/page_white_visualstudio.png create mode 100755 node_modules/express/node_modules/connect/lib/public/icons/page_white_width.png create mode 100755 node_modules/express/node_modules/connect/lib/public/icons/page_white_word.png create mode 100755 node_modules/express/node_modules/connect/lib/public/icons/page_white_world.png create mode 100755 node_modules/express/node_modules/connect/lib/public/icons/page_white_wrench.png create mode 100755 node_modules/express/node_modules/connect/lib/public/icons/page_white_zip.png create mode 100755 node_modules/express/node_modules/connect/lib/public/icons/page_word.png create mode 100755 node_modules/express/node_modules/connect/lib/public/icons/page_world.png create mode 100644 node_modules/express/node_modules/connect/lib/public/style.css create mode 100644 node_modules/express/node_modules/connect/lib/utils.js create mode 100644 node_modules/express/node_modules/connect/node_modules/formidable/.gitignore create mode 100644 node_modules/express/node_modules/connect/node_modules/formidable/.npmignore create mode 100644 node_modules/express/node_modules/connect/node_modules/formidable/Makefile create mode 100644 node_modules/express/node_modules/connect/node_modules/formidable/Readme.md create mode 100644 node_modules/express/node_modules/connect/node_modules/formidable/TODO create mode 100644 node_modules/express/node_modules/connect/node_modules/formidable/benchmark/bench-multipart-parser.js create mode 100644 node_modules/express/node_modules/connect/node_modules/formidable/example/post.js create mode 100644 node_modules/express/node_modules/connect/node_modules/formidable/example/upload.js create mode 100644 node_modules/express/node_modules/connect/node_modules/formidable/index.js create mode 100644 node_modules/express/node_modules/connect/node_modules/formidable/lib/file.js create mode 100644 node_modules/express/node_modules/connect/node_modules/formidable/lib/incoming_form.js create mode 100644 node_modules/express/node_modules/connect/node_modules/formidable/lib/index.js create mode 100644 node_modules/express/node_modules/connect/node_modules/formidable/lib/multipart_parser.js create mode 100644 node_modules/express/node_modules/connect/node_modules/formidable/lib/querystring_parser.js create mode 100644 node_modules/express/node_modules/connect/node_modules/formidable/lib/util.js create mode 100644 node_modules/express/node_modules/connect/node_modules/formidable/package.json create mode 100644 node_modules/express/node_modules/connect/node_modules/formidable/test/common.js create mode 100644 node_modules/express/node_modules/connect/node_modules/formidable/test/fast/test-incoming-form.js create mode 100644 node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/file/funkyfilename.txt create mode 100644 node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/file/plain.txt create mode 100644 node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/http/special-chars-in-filename/info.md create mode 100644 node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/js/no-filename.js create mode 100644 node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/js/special-chars-in-filename.js create mode 100644 node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/multipart.js create mode 100644 node_modules/express/node_modules/connect/node_modules/formidable/test/legacy/common.js create mode 100644 node_modules/express/node_modules/connect/node_modules/formidable/test/legacy/integration/test-multipart-parser.js create mode 100644 node_modules/express/node_modules/connect/node_modules/formidable/test/legacy/simple/test-file.js create mode 100644 node_modules/express/node_modules/connect/node_modules/formidable/test/legacy/simple/test-incoming-form.js create mode 100644 node_modules/express/node_modules/connect/node_modules/formidable/test/legacy/simple/test-multipart-parser.js create mode 100644 node_modules/express/node_modules/connect/node_modules/formidable/test/legacy/simple/test-querystring-parser.js create mode 100644 node_modules/express/node_modules/connect/node_modules/formidable/test/legacy/system/test-multi-video-upload.js create mode 100755 node_modules/express/node_modules/connect/node_modules/formidable/test/run.js create mode 100644 node_modules/express/node_modules/connect/node_modules/formidable/test/slow/test-fixtures.js create mode 100644 node_modules/express/node_modules/connect/node_modules/formidable/tool/record.js create mode 100644 node_modules/express/node_modules/connect/node_modules/mime/LICENSE create mode 100644 node_modules/express/node_modules/connect/node_modules/mime/README.md create mode 100644 node_modules/express/node_modules/connect/node_modules/mime/mime.js create mode 100644 node_modules/express/node_modules/connect/node_modules/mime/package.json create mode 100644 node_modules/express/node_modules/connect/node_modules/mime/test.js create mode 100644 node_modules/express/node_modules/connect/node_modules/mime/types/mime.types create mode 100644 node_modules/express/node_modules/connect/node_modules/mime/types/node.types create mode 100644 node_modules/express/node_modules/connect/node_modules/qs/.gitignore create mode 100644 node_modules/express/node_modules/connect/node_modules/qs/.gitmodules create mode 100644 node_modules/express/node_modules/connect/node_modules/qs/History.md create mode 100644 node_modules/express/node_modules/connect/node_modules/qs/Makefile create mode 100644 node_modules/express/node_modules/connect/node_modules/qs/Readme.md create mode 100644 node_modules/express/node_modules/connect/node_modules/qs/benchmark.js create mode 100644 node_modules/express/node_modules/connect/node_modules/qs/examples.js create mode 100644 node_modules/express/node_modules/connect/node_modules/qs/index.js create mode 100644 node_modules/express/node_modules/connect/node_modules/qs/lib/querystring.js create mode 100644 node_modules/express/node_modules/connect/node_modules/qs/package.json create mode 100644 node_modules/express/node_modules/connect/node_modules/qs/test/mocha.opts create mode 100644 node_modules/express/node_modules/connect/node_modules/qs/test/parse.js create mode 100644 node_modules/express/node_modules/connect/node_modules/qs/test/stringify.js create mode 100644 node_modules/express/node_modules/connect/package.json create mode 100644 node_modules/express/node_modules/connect/test.js create mode 100644 node_modules/express/node_modules/mime/LICENSE create mode 100644 node_modules/express/node_modules/mime/README.md create mode 100644 node_modules/express/node_modules/mime/mime.js create mode 100644 node_modules/express/node_modules/mime/package.json create mode 100644 node_modules/express/node_modules/mime/test.js create mode 100644 node_modules/express/node_modules/mime/types/mime.types create mode 100644 node_modules/express/node_modules/mime/types/node.types create mode 100644 node_modules/express/node_modules/mkdirp/.gitignore create mode 100644 node_modules/express/node_modules/mkdirp/.gitignore.orig create mode 100644 node_modules/express/node_modules/mkdirp/.gitignore.rej create mode 100644 node_modules/express/node_modules/mkdirp/LICENSE create mode 100644 node_modules/express/node_modules/mkdirp/README.markdown create mode 100644 node_modules/express/node_modules/mkdirp/examples/pow.js create mode 100644 node_modules/express/node_modules/mkdirp/examples/pow.js.orig create mode 100644 node_modules/express/node_modules/mkdirp/examples/pow.js.rej create mode 100644 node_modules/express/node_modules/mkdirp/index.js create mode 100644 node_modules/express/node_modules/mkdirp/package.json create mode 100644 node_modules/express/node_modules/mkdirp/test/mkdirp.js create mode 100644 node_modules/express/node_modules/mkdirp/test/race.js create mode 100644 node_modules/express/node_modules/mkdirp/test/rel.js create mode 100644 node_modules/express/node_modules/qs/.gitignore create mode 100644 node_modules/express/node_modules/qs/.gitmodules create mode 100644 node_modules/express/node_modules/qs/History.md create mode 100644 node_modules/express/node_modules/qs/Makefile create mode 100644 node_modules/express/node_modules/qs/Readme.md create mode 100644 node_modules/express/node_modules/qs/benchmark.js create mode 100644 node_modules/express/node_modules/qs/examples.js create mode 100644 node_modules/express/node_modules/qs/index.js create mode 100644 node_modules/express/node_modules/qs/lib/querystring.js create mode 100644 node_modules/express/node_modules/qs/package.json create mode 100644 node_modules/express/node_modules/qs/test/mocha.opts create mode 100644 node_modules/express/node_modules/qs/test/parse.js create mode 100644 node_modules/express/node_modules/qs/test/stringify.js create mode 100644 node_modules/express/package.json create mode 100644 node_modules/express/testing/foo/app.js create mode 100644 node_modules/express/testing/foo/package.json create mode 100644 node_modules/express/testing/foo/public/stylesheets/style.css create mode 100644 node_modules/express/testing/foo/routes/index.js create mode 100644 node_modules/express/testing/foo/views/index.jade create mode 100644 node_modules/express/testing/foo/views/layout.jade create mode 100644 node_modules/express/testing/index.js create mode 100644 node_modules/express/testing/public/test.txt create mode 100644 node_modules/express/testing/views/page.html create mode 100644 node_modules/express/testing/views/page.jade create mode 100644 node_modules/express/testing/views/test.md create mode 100644 node_modules/express/testing/views/user/index.jade create mode 100644 node_modules/express/testing/views/user/list.jade create mode 100644 node_modules/jade/.gitignore create mode 100644 node_modules/jade/.gitmodules create mode 100644 node_modules/jade/.npmignore create mode 100644 node_modules/jade/History.md create mode 100644 node_modules/jade/LICENSE create mode 100644 node_modules/jade/Makefile create mode 100644 node_modules/jade/Readme.md create mode 100755 node_modules/jade/bin/jade create mode 100644 node_modules/jade/examples/attributes.jade create mode 100644 node_modules/jade/examples/attributes.js create mode 100644 node_modules/jade/examples/code.jade create mode 100644 node_modules/jade/examples/code.js create mode 100644 node_modules/jade/examples/csrf.jade create mode 100644 node_modules/jade/examples/csrf.js create mode 100644 node_modules/jade/examples/dynamicscript.jade create mode 100644 node_modules/jade/examples/dynamicscript.js create mode 100644 node_modules/jade/examples/each.jade create mode 100644 node_modules/jade/examples/each.js create mode 100644 node_modules/jade/examples/extend-layout.jade create mode 100644 node_modules/jade/examples/extend.jade create mode 100644 node_modules/jade/examples/extend.js create mode 100644 node_modules/jade/examples/form.jade create mode 100644 node_modules/jade/examples/form.js create mode 100644 node_modules/jade/examples/includes.jade create mode 100644 node_modules/jade/examples/includes.js create mode 100644 node_modules/jade/examples/includes/foot.jade create mode 100644 node_modules/jade/examples/includes/head.jade create mode 100644 node_modules/jade/examples/includes/scripts.jade create mode 100644 node_modules/jade/examples/includes/style.css create mode 100644 node_modules/jade/examples/layout-debug.js create mode 100644 node_modules/jade/examples/layout.jade create mode 100644 node_modules/jade/examples/layout.js create mode 100644 node_modules/jade/examples/mixins.jade create mode 100644 node_modules/jade/examples/mixins.js create mode 100644 node_modules/jade/examples/mixins/dialog.jade create mode 100644 node_modules/jade/examples/mixins/profile.jade create mode 100644 node_modules/jade/examples/model.jade create mode 100644 node_modules/jade/examples/model.js create mode 100644 node_modules/jade/examples/nested-filters.jade create mode 100644 node_modules/jade/examples/nested-filters.js create mode 100644 node_modules/jade/examples/pet.jade create mode 100644 node_modules/jade/examples/rss.jade create mode 100644 node_modules/jade/examples/rss.js create mode 100644 node_modules/jade/examples/text.jade create mode 100644 node_modules/jade/examples/text.js create mode 100644 node_modules/jade/examples/whitespace.jade create mode 100644 node_modules/jade/examples/whitespace.js create mode 100644 node_modules/jade/index.js create mode 100644 node_modules/jade/jade.js create mode 100644 node_modules/jade/jade.min.js create mode 100644 node_modules/jade/lib/compiler.js create mode 100644 node_modules/jade/lib/doctypes.js create mode 100644 node_modules/jade/lib/filters.js create mode 120000 node_modules/jade/lib/index.js create mode 100644 node_modules/jade/lib/inline-tags.js create mode 100644 node_modules/jade/lib/jade.js create mode 100644 node_modules/jade/lib/lexer.js create mode 100644 node_modules/jade/lib/nodes/block-comment.js create mode 100644 node_modules/jade/lib/nodes/block.js create mode 100644 node_modules/jade/lib/nodes/case.js create mode 100644 node_modules/jade/lib/nodes/code.js create mode 100644 node_modules/jade/lib/nodes/comment.js create mode 100644 node_modules/jade/lib/nodes/doctype.js create mode 100644 node_modules/jade/lib/nodes/each.js create mode 100644 node_modules/jade/lib/nodes/filter.js create mode 100644 node_modules/jade/lib/nodes/index.js create mode 100644 node_modules/jade/lib/nodes/literal.js create mode 100644 node_modules/jade/lib/nodes/mixin.js create mode 100644 node_modules/jade/lib/nodes/node.js create mode 100644 node_modules/jade/lib/nodes/tag.js create mode 100644 node_modules/jade/lib/nodes/text.js create mode 100644 node_modules/jade/lib/parser.js create mode 100644 node_modules/jade/lib/runtime.js create mode 100644 node_modules/jade/lib/self-closing.js create mode 100644 node_modules/jade/lib/utils.js create mode 100644 node_modules/jade/package.json create mode 100644 node_modules/jade/runtime.js create mode 100644 node_modules/jade/runtime.min.js create mode 100644 node_modules/jade/support/benchmark.js create mode 100644 node_modules/jade/support/coffee-script/.gitignore create mode 100644 node_modules/jade/support/coffee-script/Cakefile create mode 100644 node_modules/jade/support/coffee-script/LICENSE create mode 100644 node_modules/jade/support/coffee-script/README create mode 100644 node_modules/jade/support/coffee-script/Rakefile create mode 100755 node_modules/jade/support/coffee-script/bin/cake create mode 100755 node_modules/jade/support/coffee-script/bin/coffee create mode 100644 node_modules/jade/support/coffee-script/documentation/coffee/aliases.coffee create mode 100644 node_modules/jade/support/coffee-script/documentation/coffee/array_comprehensions.coffee create mode 100644 node_modules/jade/support/coffee-script/documentation/coffee/block_comment.coffee create mode 100644 node_modules/jade/support/coffee-script/documentation/coffee/cake_tasks.coffee create mode 100644 node_modules/jade/support/coffee-script/documentation/coffee/classes.coffee create mode 100644 node_modules/jade/support/coffee-script/documentation/coffee/comparisons.coffee create mode 100644 node_modules/jade/support/coffee-script/documentation/coffee/conditionals.coffee create mode 100644 node_modules/jade/support/coffee-script/documentation/coffee/embedded.coffee create mode 100644 node_modules/jade/support/coffee-script/documentation/coffee/existence.coffee create mode 100644 node_modules/jade/support/coffee-script/documentation/coffee/expressions.coffee create mode 100644 node_modules/jade/support/coffee-script/documentation/coffee/expressions_assignment.coffee create mode 100644 node_modules/jade/support/coffee-script/documentation/coffee/expressions_comprehension.coffee create mode 100644 node_modules/jade/support/coffee-script/documentation/coffee/expressions_try.coffee create mode 100644 node_modules/jade/support/coffee-script/documentation/coffee/fat_arrow.coffee create mode 100644 node_modules/jade/support/coffee-script/documentation/coffee/functions.coffee create mode 100644 node_modules/jade/support/coffee-script/documentation/coffee/heredocs.coffee create mode 100644 node_modules/jade/support/coffee-script/documentation/coffee/interpolation.coffee create mode 100644 node_modules/jade/support/coffee-script/documentation/coffee/interpolation_expression.coffee create mode 100644 node_modules/jade/support/coffee-script/documentation/coffee/multiple_return_values.coffee create mode 100644 node_modules/jade/support/coffee-script/documentation/coffee/object_comprehensions.coffee create mode 100644 node_modules/jade/support/coffee-script/documentation/coffee/object_extraction.coffee create mode 100644 node_modules/jade/support/coffee-script/documentation/coffee/objects_and_arrays.coffee create mode 100644 node_modules/jade/support/coffee-script/documentation/coffee/objects_reserved.coffee create mode 100644 node_modules/jade/support/coffee-script/documentation/coffee/overview.coffee create mode 100644 node_modules/jade/support/coffee-script/documentation/coffee/parallel_assignment.coffee create mode 100644 node_modules/jade/support/coffee-script/documentation/coffee/patterns_and_splats.coffee create mode 100644 node_modules/jade/support/coffee-script/documentation/coffee/prototypes.coffee create mode 100644 node_modules/jade/support/coffee-script/documentation/coffee/range_comprehensions.coffee create mode 100644 node_modules/jade/support/coffee-script/documentation/coffee/scope.coffee create mode 100644 node_modules/jade/support/coffee-script/documentation/coffee/slices.coffee create mode 100644 node_modules/jade/support/coffee-script/documentation/coffee/soaks.coffee create mode 100644 node_modules/jade/support/coffee-script/documentation/coffee/splats.coffee create mode 100644 node_modules/jade/support/coffee-script/documentation/coffee/splices.coffee create mode 100644 node_modules/jade/support/coffee-script/documentation/coffee/strings.coffee create mode 100644 node_modules/jade/support/coffee-script/documentation/coffee/switch.coffee create mode 100644 node_modules/jade/support/coffee-script/documentation/coffee/try.coffee create mode 100644 node_modules/jade/support/coffee-script/documentation/coffee/while.coffee create mode 100644 node_modules/jade/support/coffee-script/documentation/css/docs.css create mode 100644 node_modules/jade/support/coffee-script/documentation/css/idle.css create mode 100644 node_modules/jade/support/coffee-script/documentation/docs/browser.html create mode 100644 node_modules/jade/support/coffee-script/documentation/docs/cake.html create mode 100644 node_modules/jade/support/coffee-script/documentation/docs/coffee-script.html create mode 100644 node_modules/jade/support/coffee-script/documentation/docs/command.html create mode 100644 node_modules/jade/support/coffee-script/documentation/docs/docco.css create mode 100644 node_modules/jade/support/coffee-script/documentation/docs/grammar.html create mode 100644 node_modules/jade/support/coffee-script/documentation/docs/helpers.html create mode 100644 node_modules/jade/support/coffee-script/documentation/docs/index.html create mode 100644 node_modules/jade/support/coffee-script/documentation/docs/lexer.html create mode 100644 node_modules/jade/support/coffee-script/documentation/docs/nodes.html create mode 100644 node_modules/jade/support/coffee-script/documentation/docs/optparse.html create mode 100644 node_modules/jade/support/coffee-script/documentation/docs/repl.html create mode 100644 node_modules/jade/support/coffee-script/documentation/docs/rewriter.html create mode 100644 node_modules/jade/support/coffee-script/documentation/docs/scope.html create mode 100644 node_modules/jade/support/coffee-script/documentation/docs/underscore.html create mode 100644 node_modules/jade/support/coffee-script/documentation/images/favicon.ico create mode 100644 node_modules/jade/support/coffee-script/documentation/images/logo.png create mode 100644 node_modules/jade/support/coffee-script/documentation/index.html.erb create mode 100644 node_modules/jade/support/coffee-script/documentation/js/aliases.js create mode 100644 node_modules/jade/support/coffee-script/documentation/js/array_comprehensions.js create mode 100644 node_modules/jade/support/coffee-script/documentation/js/block_comment.js create mode 100644 node_modules/jade/support/coffee-script/documentation/js/cake_tasks.js create mode 100644 node_modules/jade/support/coffee-script/documentation/js/classes.js create mode 100644 node_modules/jade/support/coffee-script/documentation/js/comparisons.js create mode 100644 node_modules/jade/support/coffee-script/documentation/js/conditionals.js create mode 100644 node_modules/jade/support/coffee-script/documentation/js/embedded.js create mode 100644 node_modules/jade/support/coffee-script/documentation/js/existence.js create mode 100644 node_modules/jade/support/coffee-script/documentation/js/expressions.js create mode 100644 node_modules/jade/support/coffee-script/documentation/js/expressions_assignment.js create mode 100644 node_modules/jade/support/coffee-script/documentation/js/expressions_comprehension.js create mode 100644 node_modules/jade/support/coffee-script/documentation/js/expressions_try.js create mode 100644 node_modules/jade/support/coffee-script/documentation/js/fat_arrow.js create mode 100644 node_modules/jade/support/coffee-script/documentation/js/functions.js create mode 100644 node_modules/jade/support/coffee-script/documentation/js/heredocs.js create mode 100644 node_modules/jade/support/coffee-script/documentation/js/interpolation.js create mode 100644 node_modules/jade/support/coffee-script/documentation/js/interpolation_expression.js create mode 100644 node_modules/jade/support/coffee-script/documentation/js/multiple_return_values.js create mode 100644 node_modules/jade/support/coffee-script/documentation/js/object_comprehensions.js create mode 100644 node_modules/jade/support/coffee-script/documentation/js/object_extraction.js create mode 100644 node_modules/jade/support/coffee-script/documentation/js/objects_and_arrays.js create mode 100644 node_modules/jade/support/coffee-script/documentation/js/objects_reserved.js create mode 100644 node_modules/jade/support/coffee-script/documentation/js/overview.js create mode 100644 node_modules/jade/support/coffee-script/documentation/js/parallel_assignment.js create mode 100644 node_modules/jade/support/coffee-script/documentation/js/patterns_and_splats.js create mode 100644 node_modules/jade/support/coffee-script/documentation/js/prototypes.js create mode 100644 node_modules/jade/support/coffee-script/documentation/js/range_comprehensions.js create mode 100644 node_modules/jade/support/coffee-script/documentation/js/scope.js create mode 100644 node_modules/jade/support/coffee-script/documentation/js/slices.js create mode 100644 node_modules/jade/support/coffee-script/documentation/js/soaks.js create mode 100644 node_modules/jade/support/coffee-script/documentation/js/splats.js create mode 100644 node_modules/jade/support/coffee-script/documentation/js/splices.js create mode 100644 node_modules/jade/support/coffee-script/documentation/js/strings.js create mode 100644 node_modules/jade/support/coffee-script/documentation/js/switch.js create mode 100644 node_modules/jade/support/coffee-script/documentation/js/try.js create mode 100644 node_modules/jade/support/coffee-script/documentation/js/while.js create mode 100644 node_modules/jade/support/coffee-script/examples/beautiful_code/binary_search.coffee create mode 100644 node_modules/jade/support/coffee-script/examples/beautiful_code/quicksort_runtime.coffee create mode 100644 node_modules/jade/support/coffee-script/examples/beautiful_code/regular_expression_matcher.coffee create mode 100644 node_modules/jade/support/coffee-script/examples/blocks.coffee create mode 100644 node_modules/jade/support/coffee-script/examples/code.coffee create mode 100644 node_modules/jade/support/coffee-script/examples/computer_science/README create mode 100644 node_modules/jade/support/coffee-script/examples/computer_science/binary_search.coffee create mode 100644 node_modules/jade/support/coffee-script/examples/computer_science/bubble_sort.coffee create mode 100644 node_modules/jade/support/coffee-script/examples/computer_science/linked_list.coffee create mode 100644 node_modules/jade/support/coffee-script/examples/computer_science/luhn_algorithm.coffee create mode 100644 node_modules/jade/support/coffee-script/examples/computer_science/merge_sort.coffee create mode 100644 node_modules/jade/support/coffee-script/examples/computer_science/selection_sort.coffee create mode 100644 node_modules/jade/support/coffee-script/examples/poignant.coffee create mode 100644 node_modules/jade/support/coffee-script/examples/potion.coffee create mode 100644 node_modules/jade/support/coffee-script/examples/underscore.coffee create mode 100644 node_modules/jade/support/coffee-script/examples/web_server.coffee create mode 100644 node_modules/jade/support/coffee-script/extras/EXTRAS create mode 100644 node_modules/jade/support/coffee-script/extras/coffee-script.js create mode 100644 node_modules/jade/support/coffee-script/extras/jsl.conf create mode 100644 node_modules/jade/support/coffee-script/index.html create mode 100644 node_modules/jade/support/coffee-script/lib/browser.js create mode 100755 node_modules/jade/support/coffee-script/lib/cake.js create mode 100755 node_modules/jade/support/coffee-script/lib/coffee-script.js create mode 100644 node_modules/jade/support/coffee-script/lib/command.js create mode 100644 node_modules/jade/support/coffee-script/lib/grammar.js create mode 100644 node_modules/jade/support/coffee-script/lib/helpers.js create mode 100644 node_modules/jade/support/coffee-script/lib/index.js create mode 100644 node_modules/jade/support/coffee-script/lib/lexer.js create mode 100644 node_modules/jade/support/coffee-script/lib/nodes.js create mode 100755 node_modules/jade/support/coffee-script/lib/optparse.js create mode 100755 node_modules/jade/support/coffee-script/lib/parser.js create mode 100644 node_modules/jade/support/coffee-script/lib/repl.js create mode 100644 node_modules/jade/support/coffee-script/lib/rewriter.js create mode 100644 node_modules/jade/support/coffee-script/lib/scope.js create mode 100644 node_modules/jade/support/coffee-script/lib/utilities.js create mode 100644 node_modules/jade/support/coffee-script/package.json create mode 100644 node_modules/jade/support/coffee-script/src/browser.coffee create mode 100644 node_modules/jade/support/coffee-script/src/cake.coffee create mode 100755 node_modules/jade/support/coffee-script/src/coffee-script.coffee create mode 100644 node_modules/jade/support/coffee-script/src/command.coffee create mode 100644 node_modules/jade/support/coffee-script/src/grammar.coffee create mode 100644 node_modules/jade/support/coffee-script/src/helpers.coffee create mode 100644 node_modules/jade/support/coffee-script/src/index.coffee create mode 100644 node_modules/jade/support/coffee-script/src/lexer.coffee create mode 100644 node_modules/jade/support/coffee-script/src/nodes.coffee create mode 100644 node_modules/jade/support/coffee-script/src/optparse.coffee create mode 100644 node_modules/jade/support/coffee-script/src/repl.coffee create mode 100644 node_modules/jade/support/coffee-script/src/rewriter.coffee create mode 100644 node_modules/jade/support/coffee-script/src/scope.coffee create mode 100644 node_modules/jade/support/coffee-script/test/test.html create mode 100644 node_modules/jade/support/coffee-script/test/test_arguments.coffee create mode 100644 node_modules/jade/support/coffee-script/test/test_assignment.coffee create mode 100644 node_modules/jade/support/coffee-script/test/test_break.coffee create mode 100644 node_modules/jade/support/coffee-script/test/test_chaining.coffee create mode 100644 node_modules/jade/support/coffee-script/test/test_classes.coffee create mode 100644 node_modules/jade/support/coffee-script/test/test_comments.coffee create mode 100644 node_modules/jade/support/coffee-script/test/test_compilation.coffee create mode 100644 node_modules/jade/support/coffee-script/test/test_compound_assignment.coffee create mode 100644 node_modules/jade/support/coffee-script/test/test_comprehensions.coffee create mode 100644 node_modules/jade/support/coffee-script/test/test_existence.coffee create mode 100644 node_modules/jade/support/coffee-script/test/test_expressions.coffee create mode 100644 node_modules/jade/support/coffee-script/test/test_functions.coffee create mode 100644 node_modules/jade/support/coffee-script/test/test_helpers.coffee create mode 100644 node_modules/jade/support/coffee-script/test/test_heredocs.coffee create mode 100644 node_modules/jade/support/coffee-script/test/test_if.coffee create mode 100644 node_modules/jade/support/coffee-script/test/test_importing.coffee create mode 100644 node_modules/jade/support/coffee-script/test/test_literals.coffee create mode 100644 node_modules/jade/support/coffee-script/test/test_module.coffee create mode 100644 node_modules/jade/support/coffee-script/test/test_operations.coffee create mode 100644 node_modules/jade/support/coffee-script/test/test_option_parser.coffee create mode 100644 node_modules/jade/support/coffee-script/test/test_pattern_matching.coffee create mode 100644 node_modules/jade/support/coffee-script/test/test_ranges_slices_and_splices.coffee create mode 100644 node_modules/jade/support/coffee-script/test/test_regexps.coffee create mode 100644 node_modules/jade/support/coffee-script/test/test_returns.coffee create mode 100644 node_modules/jade/support/coffee-script/test/test_splats.coffee create mode 100644 node_modules/jade/support/coffee-script/test/test_strings.coffee create mode 100644 node_modules/jade/support/coffee-script/test/test_switch.coffee create mode 100644 node_modules/jade/support/coffee-script/test/test_try_catch.coffee create mode 100644 node_modules/jade/support/coffee-script/test/test_while.coffee create mode 100644 node_modules/jade/support/compile.js create mode 100644 node_modules/jade/support/expresso/.gitignore create mode 100644 node_modules/jade/support/expresso/.gitmodules create mode 100644 node_modules/jade/support/expresso/History.md create mode 100644 node_modules/jade/support/expresso/Makefile create mode 100644 node_modules/jade/support/expresso/Readme.md create mode 100755 node_modules/jade/support/expresso/bin/expresso create mode 100644 node_modules/jade/support/expresso/docs/api.html create mode 100644 node_modules/jade/support/expresso/docs/index.html create mode 100644 node_modules/jade/support/expresso/docs/index.md create mode 100644 node_modules/jade/support/expresso/docs/layout/foot.html create mode 100644 node_modules/jade/support/expresso/docs/layout/head.html create mode 100644 node_modules/jade/support/expresso/lib/bar.js create mode 100644 node_modules/jade/support/expresso/lib/foo.js create mode 100644 node_modules/jade/support/expresso/package.json create mode 100644 node_modules/jade/support/expresso/test/assert.test.js create mode 100644 node_modules/jade/support/expresso/test/async.test.js create mode 100644 node_modules/jade/support/expresso/test/bar.test.js create mode 100644 node_modules/jade/support/expresso/test/foo.test.js create mode 100644 node_modules/jade/support/expresso/test/http.test.js create mode 100644 node_modules/jade/support/expresso/test/serial/async.test.js create mode 100644 node_modules/jade/support/expresso/test/serial/http.test.js create mode 100644 node_modules/jade/support/foot.js create mode 100644 node_modules/jade/support/head.js create mode 100644 node_modules/jade/support/sass/.gitignore create mode 100644 node_modules/jade/support/sass/History.md create mode 100644 node_modules/jade/support/sass/Makefile create mode 100644 node_modules/jade/support/sass/Readme.md create mode 120000 node_modules/jade/support/sass/index.js create mode 100644 node_modules/jade/support/sass/lib/sass.js create mode 100644 node_modules/jade/support/sass/package.json create mode 100644 node_modules/jade/support/sass/seed.yml create mode 100644 node_modules/jade/support/sass/spec/fixtures/collect.sass create mode 100644 node_modules/jade/support/sass/spec/fixtures/comment.css create mode 100644 node_modules/jade/support/sass/spec/fixtures/comment.sass create mode 100644 node_modules/jade/support/sass/spec/fixtures/continuation.css create mode 100644 node_modules/jade/support/sass/spec/fixtures/continuation.sass create mode 100644 node_modules/jade/support/sass/spec/fixtures/literal.css create mode 100644 node_modules/jade/support/sass/spec/fixtures/literal.sass create mode 100644 node_modules/jade/support/sass/spec/fixtures/mixin.css create mode 100644 node_modules/jade/support/sass/spec/fixtures/mixin.sass create mode 100644 node_modules/jade/support/sass/spec/fixtures/mixin.undefined.sass create mode 100644 node_modules/jade/support/sass/spec/fixtures/properties.css create mode 100644 node_modules/jade/support/sass/spec/fixtures/properties.expand.css create mode 100644 node_modules/jade/support/sass/spec/fixtures/properties.expand.sass create mode 100644 node_modules/jade/support/sass/spec/fixtures/properties.invalid.sass create mode 100644 node_modules/jade/support/sass/spec/fixtures/properties.nested.css create mode 100644 node_modules/jade/support/sass/spec/fixtures/properties.nested.invalid.sass create mode 100644 node_modules/jade/support/sass/spec/fixtures/properties.nested.sass create mode 100644 node_modules/jade/support/sass/spec/fixtures/properties.sass create mode 100644 node_modules/jade/support/sass/spec/fixtures/selectors.css create mode 100644 node_modules/jade/support/sass/spec/fixtures/selectors.sass create mode 100644 node_modules/jade/support/sass/spec/fixtures/variables.alternate.css create mode 100644 node_modules/jade/support/sass/spec/fixtures/variables.alternate.sass create mode 100644 node_modules/jade/support/sass/spec/fixtures/variables.css create mode 100644 node_modules/jade/support/sass/spec/fixtures/variables.regular.css create mode 100644 node_modules/jade/support/sass/spec/fixtures/variables.regular.sass create mode 100644 node_modules/jade/support/sass/spec/fixtures/variables.sass create mode 100644 node_modules/jade/support/sass/spec/lib/images/bg.png create mode 100644 node_modules/jade/support/sass/spec/lib/images/hr.png create mode 100644 node_modules/jade/support/sass/spec/lib/images/loading.gif create mode 100644 node_modules/jade/support/sass/spec/lib/images/sprites.bg.png create mode 100644 node_modules/jade/support/sass/spec/lib/images/sprites.png create mode 100644 node_modules/jade/support/sass/spec/lib/images/vr.png create mode 100644 node_modules/jade/support/sass/spec/lib/jspec.css create mode 100644 node_modules/jade/support/sass/spec/lib/jspec.growl.js create mode 100644 node_modules/jade/support/sass/spec/lib/jspec.jquery.js create mode 100644 node_modules/jade/support/sass/spec/lib/jspec.js create mode 100644 node_modules/jade/support/sass/spec/lib/jspec.nodejs.js create mode 100644 node_modules/jade/support/sass/spec/lib/jspec.shell.js create mode 100644 node_modules/jade/support/sass/spec/lib/jspec.timers.js create mode 100644 node_modules/jade/support/sass/spec/lib/jspec.xhr.js create mode 100644 node_modules/jade/support/sass/spec/node.js create mode 100644 node_modules/jade/support/sass/spec/spec.core.js create mode 100644 node_modules/jade/support/stylus/.gitignore create mode 100644 node_modules/jade/support/stylus/.gitmodules create mode 100644 node_modules/jade/support/stylus/.npmignore create mode 100644 node_modules/jade/support/stylus/History.md create mode 100644 node_modules/jade/support/stylus/LICENSE create mode 100644 node_modules/jade/support/stylus/Makefile create mode 100644 node_modules/jade/support/stylus/Readme.md create mode 100755 node_modules/jade/support/stylus/bin/stylus create mode 100755 node_modules/jade/support/stylus/bin/stylus-tutorial create mode 100644 node_modules/jade/support/stylus/bm.js create mode 100644 node_modules/jade/support/stylus/docs/bifs.md create mode 100644 node_modules/jade/support/stylus/docs/comments.md create mode 100644 node_modules/jade/support/stylus/docs/compare.md create mode 100644 node_modules/jade/support/stylus/docs/conditionals.md create mode 100644 node_modules/jade/support/stylus/docs/css-style.md create mode 100644 node_modules/jade/support/stylus/docs/error-reporting.md create mode 100644 node_modules/jade/support/stylus/docs/escape.md create mode 100644 node_modules/jade/support/stylus/docs/executable.md create mode 100644 node_modules/jade/support/stylus/docs/font-face.md create mode 100644 node_modules/jade/support/stylus/docs/functions.md create mode 100644 node_modules/jade/support/stylus/docs/functions.url.md create mode 100644 node_modules/jade/support/stylus/docs/import.md create mode 100644 node_modules/jade/support/stylus/docs/interpolation.md create mode 100644 node_modules/jade/support/stylus/docs/introspection.md create mode 100644 node_modules/jade/support/stylus/docs/iteration.md create mode 100644 node_modules/jade/support/stylus/docs/js.md create mode 100644 node_modules/jade/support/stylus/docs/keyframes.md create mode 100644 node_modules/jade/support/stylus/docs/literal.md create mode 100644 node_modules/jade/support/stylus/docs/media.md create mode 100644 node_modules/jade/support/stylus/docs/middleware.md create mode 100644 node_modules/jade/support/stylus/docs/mixins.md create mode 100644 node_modules/jade/support/stylus/docs/operators.md create mode 100644 node_modules/jade/support/stylus/docs/selectors.md create mode 100644 node_modules/jade/support/stylus/docs/textmate.md create mode 100644 node_modules/jade/support/stylus/docs/vargs.md create mode 100644 node_modules/jade/support/stylus/docs/variables.md create mode 100644 node_modules/jade/support/stylus/editors/Stylus.tmbundle/Syntaxes/Stylus.tmLanguage create mode 100644 node_modules/jade/support/stylus/editors/Stylus.tmbundle/info.plist create mode 100644 node_modules/jade/support/stylus/examples/arithmetic.js create mode 100644 node_modules/jade/support/stylus/examples/arithmetic.styl create mode 100644 node_modules/jade/support/stylus/examples/basic.js create mode 100644 node_modules/jade/support/stylus/examples/basic.styl create mode 100644 node_modules/jade/support/stylus/examples/builtins.js create mode 100644 node_modules/jade/support/stylus/examples/builtins.styl create mode 100644 node_modules/jade/support/stylus/examples/comments.js create mode 100644 node_modules/jade/support/stylus/examples/comments.styl create mode 100644 node_modules/jade/support/stylus/examples/compress.js create mode 100644 node_modules/jade/support/stylus/examples/conversions.js create mode 100644 node_modules/jade/support/stylus/examples/conversions.styl create mode 100644 node_modules/jade/support/stylus/examples/functions.js create mode 100644 node_modules/jade/support/stylus/examples/functions.styl create mode 100644 node_modules/jade/support/stylus/examples/images.js create mode 100644 node_modules/jade/support/stylus/examples/images.styl create mode 100644 node_modules/jade/support/stylus/examples/images/gopher.jpg create mode 100644 node_modules/jade/support/stylus/examples/images/jesus.gif create mode 100644 node_modules/jade/support/stylus/examples/images/sprite.gif create mode 100644 node_modules/jade/support/stylus/examples/implicit-functions.js create mode 100644 node_modules/jade/support/stylus/examples/implicit-functions.styl create mode 100644 node_modules/jade/support/stylus/examples/import.js create mode 100644 node_modules/jade/support/stylus/examples/import.styl create mode 100644 node_modules/jade/support/stylus/examples/js-functions.js create mode 100644 node_modules/jade/support/stylus/examples/js-functions.styl create mode 100644 node_modules/jade/support/stylus/examples/literal.js create mode 100644 node_modules/jade/support/stylus/examples/literal.styl create mode 100644 node_modules/jade/support/stylus/examples/middleware.js create mode 100644 node_modules/jade/support/stylus/examples/mixins/box.styl create mode 100644 node_modules/jade/support/stylus/examples/nesting.js create mode 100644 node_modules/jade/support/stylus/examples/nesting.styl create mode 100644 node_modules/jade/support/stylus/examples/public/.gitignore create mode 100644 node_modules/jade/support/stylus/examples/variables.js create mode 100644 node_modules/jade/support/stylus/examples/variables.styl create mode 100644 node_modules/jade/support/stylus/index.js create mode 100644 node_modules/jade/support/stylus/lib/colors.js create mode 100644 node_modules/jade/support/stylus/lib/convert/css.js create mode 100644 node_modules/jade/support/stylus/lib/functions/image.js create mode 100644 node_modules/jade/support/stylus/lib/functions/index.js create mode 100644 node_modules/jade/support/stylus/lib/functions/index.styl create mode 100644 node_modules/jade/support/stylus/lib/functions/url.js create mode 100644 node_modules/jade/support/stylus/lib/lexer.js create mode 100644 node_modules/jade/support/stylus/lib/middleware.js create mode 100644 node_modules/jade/support/stylus/lib/nodes/binop.js create mode 100644 node_modules/jade/support/stylus/lib/nodes/block.js create mode 100644 node_modules/jade/support/stylus/lib/nodes/boolean.js create mode 100644 node_modules/jade/support/stylus/lib/nodes/call.js create mode 100644 node_modules/jade/support/stylus/lib/nodes/charset.js create mode 100644 node_modules/jade/support/stylus/lib/nodes/each.js create mode 100644 node_modules/jade/support/stylus/lib/nodes/expression.js create mode 100644 node_modules/jade/support/stylus/lib/nodes/function.js create mode 100644 node_modules/jade/support/stylus/lib/nodes/group.js create mode 100644 node_modules/jade/support/stylus/lib/nodes/hsla.js create mode 100644 node_modules/jade/support/stylus/lib/nodes/ident.js create mode 100644 node_modules/jade/support/stylus/lib/nodes/if.js create mode 100644 node_modules/jade/support/stylus/lib/nodes/import.js create mode 100644 node_modules/jade/support/stylus/lib/nodes/index.js create mode 100644 node_modules/jade/support/stylus/lib/nodes/keyframes.js create mode 100644 node_modules/jade/support/stylus/lib/nodes/literal.js create mode 100644 node_modules/jade/support/stylus/lib/nodes/media.js create mode 100644 node_modules/jade/support/stylus/lib/nodes/node.js create mode 100644 node_modules/jade/support/stylus/lib/nodes/null.js create mode 100644 node_modules/jade/support/stylus/lib/nodes/page.js create mode 100644 node_modules/jade/support/stylus/lib/nodes/params.js create mode 100644 node_modules/jade/support/stylus/lib/nodes/property.js create mode 100644 node_modules/jade/support/stylus/lib/nodes/return.js create mode 100644 node_modules/jade/support/stylus/lib/nodes/rgba.js create mode 100644 node_modules/jade/support/stylus/lib/nodes/root.js create mode 100644 node_modules/jade/support/stylus/lib/nodes/selector.js create mode 100644 node_modules/jade/support/stylus/lib/nodes/string.js create mode 100644 node_modules/jade/support/stylus/lib/nodes/ternary.js create mode 100644 node_modules/jade/support/stylus/lib/nodes/unaryop.js create mode 100644 node_modules/jade/support/stylus/lib/nodes/unit.js create mode 100644 node_modules/jade/support/stylus/lib/parser.js create mode 100644 node_modules/jade/support/stylus/lib/renderer.js create mode 100644 node_modules/jade/support/stylus/lib/stack/frame.js create mode 100644 node_modules/jade/support/stylus/lib/stack/index.js create mode 100644 node_modules/jade/support/stylus/lib/stack/scope.js create mode 100644 node_modules/jade/support/stylus/lib/stylus.js create mode 100644 node_modules/jade/support/stylus/lib/token.js create mode 100644 node_modules/jade/support/stylus/lib/utils.js create mode 100644 node_modules/jade/support/stylus/lib/visitor/compiler.js create mode 100644 node_modules/jade/support/stylus/lib/visitor/evaluator.js create mode 100644 node_modules/jade/support/stylus/lib/visitor/index.js create mode 100644 node_modules/jade/support/stylus/package.json create mode 100644 node_modules/jade/support/stylus/test/cases/arithmetic.color.css create mode 100644 node_modules/jade/support/stylus/test/cases/arithmetic.color.styl create mode 100644 node_modules/jade/support/stylus/test/cases/arithmetic.css create mode 100644 node_modules/jade/support/stylus/test/cases/arithmetic.styl create mode 100644 node_modules/jade/support/stylus/test/cases/arithmetic.unary.css create mode 100644 node_modules/jade/support/stylus/test/cases/arithmetic.unary.styl create mode 100644 node_modules/jade/support/stylus/test/cases/bifs.components.css create mode 100644 node_modules/jade/support/stylus/test/cases/bifs.components.styl create mode 100644 node_modules/jade/support/stylus/test/cases/bifs.dark.css create mode 100644 node_modules/jade/support/stylus/test/cases/bifs.dark.styl create mode 100644 node_modules/jade/support/stylus/test/cases/bifs.darken-by.css create mode 100644 node_modules/jade/support/stylus/test/cases/bifs.darken-by.styl create mode 100644 node_modules/jade/support/stylus/test/cases/bifs.image-size.css create mode 100644 node_modules/jade/support/stylus/test/cases/bifs.image-size.styl create mode 100644 node_modules/jade/support/stylus/test/cases/bifs.join.css create mode 100644 node_modules/jade/support/stylus/test/cases/bifs.join.styl create mode 100644 node_modules/jade/support/stylus/test/cases/bifs.last.css create mode 100644 node_modules/jade/support/stylus/test/cases/bifs.last.styl create mode 100644 node_modules/jade/support/stylus/test/cases/bifs.length.css create mode 100644 node_modules/jade/support/stylus/test/cases/bifs.length.styl create mode 100644 node_modules/jade/support/stylus/test/cases/bifs.light.css create mode 100644 node_modules/jade/support/stylus/test/cases/bifs.light.styl create mode 100644 node_modules/jade/support/stylus/test/cases/bifs.lighten-by.css create mode 100644 node_modules/jade/support/stylus/test/cases/bifs.lighten-by.styl create mode 100644 node_modules/jade/support/stylus/test/cases/bifs.lookup.complex.css create mode 100644 node_modules/jade/support/stylus/test/cases/bifs.lookup.complex.styl create mode 100644 node_modules/jade/support/stylus/test/cases/bifs.lookup.css create mode 100644 node_modules/jade/support/stylus/test/cases/bifs.lookup.styl create mode 100644 node_modules/jade/support/stylus/test/cases/bifs.match.css create mode 100644 node_modules/jade/support/stylus/test/cases/bifs.match.styl create mode 100644 node_modules/jade/support/stylus/test/cases/bifs.opposite-position.css create mode 100644 node_modules/jade/support/stylus/test/cases/bifs.opposite-position.styl create mode 100644 node_modules/jade/support/stylus/test/cases/bifs.rgba.css create mode 100644 node_modules/jade/support/stylus/test/cases/bifs.rgba.styl create mode 100644 node_modules/jade/support/stylus/test/cases/bifs.type.css create mode 100644 node_modules/jade/support/stylus/test/cases/bifs.type.styl create mode 100644 node_modules/jade/support/stylus/test/cases/bifs.unit.css create mode 100644 node_modules/jade/support/stylus/test/cases/bifs.unit.styl create mode 100644 node_modules/jade/support/stylus/test/cases/bifs.unquote.css create mode 100644 node_modules/jade/support/stylus/test/cases/bifs.unquote.styl create mode 100644 node_modules/jade/support/stylus/test/cases/bifs.url.css create mode 100644 node_modules/jade/support/stylus/test/cases/bifs.url.styl create mode 100644 node_modules/jade/support/stylus/test/cases/coercion.css create mode 100644 node_modules/jade/support/stylus/test/cases/coercion.styl create mode 100644 node_modules/jade/support/stylus/test/cases/comments.css create mode 100644 node_modules/jade/support/stylus/test/cases/comments.styl create mode 100644 node_modules/jade/support/stylus/test/cases/compress.units.css create mode 100644 node_modules/jade/support/stylus/test/cases/compress.units.styl create mode 100644 node_modules/jade/support/stylus/test/cases/conditional-assignment.css create mode 100644 node_modules/jade/support/stylus/test/cases/conditional-assignment.styl create mode 100644 node_modules/jade/support/stylus/test/cases/css.functions.single-line.css create mode 100644 node_modules/jade/support/stylus/test/cases/css.functions.single-line.styl create mode 100644 node_modules/jade/support/stylus/test/cases/css.if.css create mode 100644 node_modules/jade/support/stylus/test/cases/css.if.styl create mode 100644 node_modules/jade/support/stylus/test/cases/css.keyframes.css create mode 100644 node_modules/jade/support/stylus/test/cases/css.keyframes.styl create mode 100644 node_modules/jade/support/stylus/test/cases/css.large.css create mode 100644 node_modules/jade/support/stylus/test/cases/css.large.styl create mode 100644 node_modules/jade/support/stylus/test/cases/css.media.css create mode 100644 node_modules/jade/support/stylus/test/cases/css.media.styl create mode 100644 node_modules/jade/support/stylus/test/cases/css.mixins.braces.css create mode 100644 node_modules/jade/support/stylus/test/cases/css.mixins.braces.styl create mode 100644 node_modules/jade/support/stylus/test/cases/css.mixins.css create mode 100644 node_modules/jade/support/stylus/test/cases/css.mixins.root.css create mode 100644 node_modules/jade/support/stylus/test/cases/css.mixins.root.styl create mode 100644 node_modules/jade/support/stylus/test/cases/css.mixins.root.wonky.css create mode 100644 node_modules/jade/support/stylus/test/cases/css.mixins.root.wonky.styl create mode 100644 node_modules/jade/support/stylus/test/cases/css.mixins.styl create mode 100644 node_modules/jade/support/stylus/test/cases/css.selectors.css create mode 100644 node_modules/jade/support/stylus/test/cases/css.selectors.styl create mode 100644 node_modules/jade/support/stylus/test/cases/css.whitespace.css create mode 100644 node_modules/jade/support/stylus/test/cases/css.whitespace.styl create mode 100644 node_modules/jade/support/stylus/test/cases/escape.css create mode 100644 node_modules/jade/support/stylus/test/cases/escape.styl create mode 100644 node_modules/jade/support/stylus/test/cases/for.complex.css create mode 100644 node_modules/jade/support/stylus/test/cases/for.complex.styl create mode 100644 node_modules/jade/support/stylus/test/cases/for.css create mode 100644 node_modules/jade/support/stylus/test/cases/for.function.css create mode 100644 node_modules/jade/support/stylus/test/cases/for.function.styl create mode 100644 node_modules/jade/support/stylus/test/cases/for.styl create mode 100644 node_modules/jade/support/stylus/test/cases/function.arguments.css create mode 100644 node_modules/jade/support/stylus/test/cases/function.arguments.styl create mode 100644 node_modules/jade/support/stylus/test/cases/function.literals.css create mode 100644 node_modules/jade/support/stylus/test/cases/function.literals.styl create mode 100644 node_modules/jade/support/stylus/test/cases/functions.arg-calls.css create mode 100644 node_modules/jade/support/stylus/test/cases/functions.arg-calls.styl create mode 100644 node_modules/jade/support/stylus/test/cases/functions.call.css create mode 100644 node_modules/jade/support/stylus/test/cases/functions.call.styl create mode 100644 node_modules/jade/support/stylus/test/cases/functions.css create mode 100644 node_modules/jade/support/stylus/test/cases/functions.defaults.css create mode 100644 node_modules/jade/support/stylus/test/cases/functions.defaults.styl create mode 100644 node_modules/jade/support/stylus/test/cases/functions.multi-line.css create mode 100644 node_modules/jade/support/stylus/test/cases/functions.multi-line.styl create mode 100644 node_modules/jade/support/stylus/test/cases/functions.multiple-calls.css create mode 100644 node_modules/jade/support/stylus/test/cases/functions.multiple-calls.styl create mode 100644 node_modules/jade/support/stylus/test/cases/functions.nested-calls.css create mode 100644 node_modules/jade/support/stylus/test/cases/functions.nested-calls.styl create mode 100644 node_modules/jade/support/stylus/test/cases/functions.nested.css create mode 100644 node_modules/jade/support/stylus/test/cases/functions.nested.styl create mode 100644 node_modules/jade/support/stylus/test/cases/functions.property.css create mode 100644 node_modules/jade/support/stylus/test/cases/functions.property.styl create mode 100644 node_modules/jade/support/stylus/test/cases/functions.return.css create mode 100644 node_modules/jade/support/stylus/test/cases/functions.return.each.css create mode 100644 node_modules/jade/support/stylus/test/cases/functions.return.each.styl create mode 100644 node_modules/jade/support/stylus/test/cases/functions.return.styl create mode 100644 node_modules/jade/support/stylus/test/cases/functions.styl create mode 100644 node_modules/jade/support/stylus/test/cases/functions.variable.css create mode 100644 node_modules/jade/support/stylus/test/cases/functions.variable.ident.css create mode 100644 node_modules/jade/support/stylus/test/cases/functions.variable.ident.styl create mode 100644 node_modules/jade/support/stylus/test/cases/functions.variable.styl create mode 100644 node_modules/jade/support/stylus/test/cases/if.css create mode 100644 node_modules/jade/support/stylus/test/cases/if.else.css create mode 100644 node_modules/jade/support/stylus/test/cases/if.else.styl create mode 100644 node_modules/jade/support/stylus/test/cases/if.mixin.css create mode 100644 node_modules/jade/support/stylus/test/cases/if.mixin.styl create mode 100644 node_modules/jade/support/stylus/test/cases/if.postfix.css create mode 100644 node_modules/jade/support/stylus/test/cases/if.postfix.styl create mode 100644 node_modules/jade/support/stylus/test/cases/if.selectors.css create mode 100644 node_modules/jade/support/stylus/test/cases/if.selectors.styl create mode 100644 node_modules/jade/support/stylus/test/cases/if.styl create mode 100644 node_modules/jade/support/stylus/test/cases/import.basic.css create mode 100644 node_modules/jade/support/stylus/test/cases/import.basic.styl create mode 100644 node_modules/jade/support/stylus/test/cases/import.basic/a.styl create mode 100644 node_modules/jade/support/stylus/test/cases/import.basic/b.styl create mode 100644 node_modules/jade/support/stylus/test/cases/import.basic/c.styl create mode 100644 node_modules/jade/support/stylus/test/cases/import.complex.css create mode 100644 node_modules/jade/support/stylus/test/cases/import.complex.styl create mode 100644 node_modules/jade/support/stylus/test/cases/import.complex/a.styl create mode 100644 node_modules/jade/support/stylus/test/cases/import.complex/c.styl create mode 100644 node_modules/jade/support/stylus/test/cases/import.complex/nested/b.styl create mode 100644 node_modules/jade/support/stylus/test/cases/import.index.css create mode 100644 node_modules/jade/support/stylus/test/cases/import.index.styl create mode 100644 node_modules/jade/support/stylus/test/cases/import.index/vendor/a.styl create mode 100644 node_modules/jade/support/stylus/test/cases/import.index/vendor/b.styl create mode 100644 node_modules/jade/support/stylus/test/cases/import.index/vendor/c.styl create mode 100644 node_modules/jade/support/stylus/test/cases/import.index/vendor/index.styl create mode 100644 node_modules/jade/support/stylus/test/cases/import.literal.css create mode 100644 node_modules/jade/support/stylus/test/cases/import.literal.styl create mode 100644 node_modules/jade/support/stylus/test/cases/import.mixins.css create mode 100644 node_modules/jade/support/stylus/test/cases/import.mixins.styl create mode 100644 node_modules/jade/support/stylus/test/cases/import.ordering.css create mode 100644 node_modules/jade/support/stylus/test/cases/import.ordering.styl create mode 100644 node_modules/jade/support/stylus/test/cases/import.ordering/five.styl create mode 100644 node_modules/jade/support/stylus/test/cases/import.ordering/four.styl create mode 100644 node_modules/jade/support/stylus/test/cases/import.ordering/two.styl create mode 100644 node_modules/jade/support/stylus/test/cases/important.css create mode 100644 node_modules/jade/support/stylus/test/cases/important.styl create mode 100644 node_modules/jade/support/stylus/test/cases/interpolation.properties.css create mode 100644 node_modules/jade/support/stylus/test/cases/interpolation.properties.styl create mode 100644 node_modules/jade/support/stylus/test/cases/introspection.css create mode 100644 node_modules/jade/support/stylus/test/cases/introspection.styl create mode 100644 node_modules/jade/support/stylus/test/cases/jquery.css create mode 100644 node_modules/jade/support/stylus/test/cases/jquery.styl create mode 100644 node_modules/jade/support/stylus/test/cases/list.css create mode 100644 node_modules/jade/support/stylus/test/cases/list.styl create mode 100644 node_modules/jade/support/stylus/test/cases/literal.css create mode 100644 node_modules/jade/support/stylus/test/cases/literal.styl create mode 100644 node_modules/jade/support/stylus/test/cases/media.css create mode 100644 node_modules/jade/support/stylus/test/cases/media.styl create mode 100644 node_modules/jade/support/stylus/test/cases/mixin.conditional.css create mode 100644 node_modules/jade/support/stylus/test/cases/mixin.conditional.styl create mode 100644 node_modules/jade/support/stylus/test/cases/mixin.order.conditional.css create mode 100644 node_modules/jade/support/stylus/test/cases/mixin.order.conditional.styl create mode 100644 node_modules/jade/support/stylus/test/cases/mixin.order.css create mode 100644 node_modules/jade/support/stylus/test/cases/mixin.order.nested.css create mode 100644 node_modules/jade/support/stylus/test/cases/mixin.order.nested.styl create mode 100644 node_modules/jade/support/stylus/test/cases/mixin.order.styl create mode 100644 node_modules/jade/support/stylus/test/cases/mixins.complex.css create mode 100644 node_modules/jade/support/stylus/test/cases/mixins.complex.fix-to.css create mode 100644 node_modules/jade/support/stylus/test/cases/mixins.complex.fix-to.styl create mode 100644 node_modules/jade/support/stylus/test/cases/mixins.complex.styl create mode 100644 node_modules/jade/support/stylus/test/cases/mixins.conditional.css create mode 100644 node_modules/jade/support/stylus/test/cases/mixins.conditional.styl create mode 100644 node_modules/jade/support/stylus/test/cases/mixins.nested.css create mode 100644 node_modules/jade/support/stylus/test/cases/mixins.nested.selectors.css create mode 100644 node_modules/jade/support/stylus/test/cases/mixins.nested.selectors.styl create mode 100644 node_modules/jade/support/stylus/test/cases/mixins.nested.styl create mode 100644 node_modules/jade/support/stylus/test/cases/mixins.order.2.css create mode 100644 node_modules/jade/support/stylus/test/cases/mixins.order.2.styl create mode 100644 node_modules/jade/support/stylus/test/cases/mixins.return.css create mode 100644 node_modules/jade/support/stylus/test/cases/mixins.return.styl create mode 100644 node_modules/jade/support/stylus/test/cases/mixins.root.css create mode 100644 node_modules/jade/support/stylus/test/cases/mixins.root.styl create mode 100644 node_modules/jade/support/stylus/test/cases/mixins/box.styl create mode 100644 node_modules/jade/support/stylus/test/cases/operator.range.css create mode 100644 node_modules/jade/support/stylus/test/cases/operator.range.styl create mode 100644 node_modules/jade/support/stylus/test/cases/operators.assignment.function.css create mode 100644 node_modules/jade/support/stylus/test/cases/operators.assignment.function.styl create mode 100644 node_modules/jade/support/stylus/test/cases/operators.assignment.mixin.css create mode 100644 node_modules/jade/support/stylus/test/cases/operators.assignment.mixin.styl create mode 100644 node_modules/jade/support/stylus/test/cases/operators.assignment.root.css create mode 100644 node_modules/jade/support/stylus/test/cases/operators.assignment.root.styl create mode 100644 node_modules/jade/support/stylus/test/cases/operators.complex.css create mode 100644 node_modules/jade/support/stylus/test/cases/operators.complex.styl create mode 100644 node_modules/jade/support/stylus/test/cases/operators.css create mode 100644 node_modules/jade/support/stylus/test/cases/operators.equality.css create mode 100644 node_modules/jade/support/stylus/test/cases/operators.equality.styl create mode 100644 node_modules/jade/support/stylus/test/cases/operators.in.css create mode 100644 node_modules/jade/support/stylus/test/cases/operators.in.styl create mode 100644 node_modules/jade/support/stylus/test/cases/operators.mixins.css create mode 100644 node_modules/jade/support/stylus/test/cases/operators.mixins.styl create mode 100644 node_modules/jade/support/stylus/test/cases/operators.precedence.css create mode 100644 node_modules/jade/support/stylus/test/cases/operators.precedence.styl create mode 100644 node_modules/jade/support/stylus/test/cases/operators.styl create mode 100644 node_modules/jade/support/stylus/test/cases/operators.subscript.css create mode 100644 node_modules/jade/support/stylus/test/cases/operators.subscript.range.css create mode 100644 node_modules/jade/support/stylus/test/cases/operators.subscript.range.styl create mode 100644 node_modules/jade/support/stylus/test/cases/operators.subscript.styl create mode 100644 node_modules/jade/support/stylus/test/cases/page.css create mode 100644 node_modules/jade/support/stylus/test/cases/page.styl create mode 100644 node_modules/jade/support/stylus/test/cases/parent.css create mode 100644 node_modules/jade/support/stylus/test/cases/parent.styl create mode 100644 node_modules/jade/support/stylus/test/cases/properties.colons.css create mode 100644 node_modules/jade/support/stylus/test/cases/properties.colons.styl create mode 100644 node_modules/jade/support/stylus/test/cases/properties.css create mode 100644 node_modules/jade/support/stylus/test/cases/properties.one-line.css create mode 100644 node_modules/jade/support/stylus/test/cases/properties.one-line.styl create mode 100644 node_modules/jade/support/stylus/test/cases/properties.styl create mode 100644 node_modules/jade/support/stylus/test/cases/regression.107.lookup-failure.css create mode 100644 node_modules/jade/support/stylus/test/cases/regression.107.lookup-failure.styl create mode 100644 node_modules/jade/support/stylus/test/cases/regression.127.css create mode 100644 node_modules/jade/support/stylus/test/cases/regression.127.styl create mode 100644 node_modules/jade/support/stylus/test/cases/regression.130.css create mode 100644 node_modules/jade/support/stylus/test/cases/regression.130.styl create mode 100644 node_modules/jade/support/stylus/test/cases/regression.131.css create mode 100644 node_modules/jade/support/stylus/test/cases/regression.131.styl create mode 100644 node_modules/jade/support/stylus/test/cases/regression.137.css create mode 100644 node_modules/jade/support/stylus/test/cases/regression.137.styl create mode 100644 node_modules/jade/support/stylus/test/cases/regression.139.css create mode 100644 node_modules/jade/support/stylus/test/cases/regression.139.styl create mode 100644 node_modules/jade/support/stylus/test/cases/regression.142.css create mode 100644 node_modules/jade/support/stylus/test/cases/regression.142.styl create mode 100644 node_modules/jade/support/stylus/test/cases/regression.146.css create mode 100644 node_modules/jade/support/stylus/test/cases/regression.146.styl create mode 100644 node_modules/jade/support/stylus/test/cases/regression.153.css create mode 100644 node_modules/jade/support/stylus/test/cases/regression.153.styl create mode 100644 node_modules/jade/support/stylus/test/cases/regression.154.css create mode 100644 node_modules/jade/support/stylus/test/cases/regression.154.styl create mode 100644 node_modules/jade/support/stylus/test/cases/regression.156.css create mode 100644 node_modules/jade/support/stylus/test/cases/regression.156.styl create mode 100644 node_modules/jade/support/stylus/test/cases/rule.charset.css create mode 100644 node_modules/jade/support/stylus/test/cases/rule.charset.styl create mode 100644 node_modules/jade/support/stylus/test/cases/rulset.css create mode 100644 node_modules/jade/support/stylus/test/cases/rulset.newline.css create mode 100644 node_modules/jade/support/stylus/test/cases/rulset.newline.styl create mode 100644 node_modules/jade/support/stylus/test/cases/rulset.styl create mode 100644 node_modules/jade/support/stylus/test/cases/scope.complex.css create mode 100644 node_modules/jade/support/stylus/test/cases/scope.complex.styl create mode 100644 node_modules/jade/support/stylus/test/cases/scope.css create mode 100644 node_modules/jade/support/stylus/test/cases/scope.nested.css create mode 100644 node_modules/jade/support/stylus/test/cases/scope.nested.styl create mode 100644 node_modules/jade/support/stylus/test/cases/scope.styl create mode 100644 node_modules/jade/support/stylus/test/cases/selectors.complex.css create mode 100644 node_modules/jade/support/stylus/test/cases/selectors.complex.styl create mode 100644 node_modules/jade/support/stylus/test/cases/selectors.css create mode 100644 node_modules/jade/support/stylus/test/cases/selectors.nested.comma.css create mode 100644 node_modules/jade/support/stylus/test/cases/selectors.nested.comma.styl create mode 100644 node_modules/jade/support/stylus/test/cases/selectors.nested.css create mode 100644 node_modules/jade/support/stylus/test/cases/selectors.nested.styl create mode 100644 node_modules/jade/support/stylus/test/cases/selectors.pseudo.css create mode 100644 node_modules/jade/support/stylus/test/cases/selectors.pseudo.styl create mode 100644 node_modules/jade/support/stylus/test/cases/selectors.styl create mode 100644 node_modules/jade/support/stylus/test/cases/self-assignment.css create mode 100644 node_modules/jade/support/stylus/test/cases/self-assignment.styl create mode 100644 node_modules/jade/support/stylus/test/cases/vargs.call.css create mode 100644 node_modules/jade/support/stylus/test/cases/vargs.call.styl create mode 100644 node_modules/jade/support/stylus/test/cases/vargs.css create mode 100644 node_modules/jade/support/stylus/test/cases/vargs.styl create mode 100644 node_modules/jade/support/stylus/test/cases/variable.css create mode 100644 node_modules/jade/support/stylus/test/cases/variable.styl create mode 100644 node_modules/jade/support/stylus/test/cases/variables.css create mode 100644 node_modules/jade/support/stylus/test/cases/variables.styl create mode 100644 node_modules/jade/support/stylus/test/images/gif create mode 100644 node_modules/jade/support/stylus/test/images/squirrel.jpeg create mode 100644 node_modules/jade/support/stylus/test/images/tux.png create mode 100644 node_modules/jade/support/stylus/test/run.js create mode 100644 node_modules/jade/test/filters.test.js create mode 100644 node_modules/jade/test/fixtures/case-blocks.html create mode 100644 node_modules/jade/test/fixtures/case-blocks.jade create mode 100644 node_modules/jade/test/fixtures/case.html create mode 100644 node_modules/jade/test/fixtures/case.jade create mode 100644 node_modules/jade/test/fixtures/conditional-comment.html create mode 100644 node_modules/jade/test/fixtures/conditional-comment.jade create mode 100644 node_modules/jade/test/fixtures/invalid.jade create mode 100644 node_modules/jade/test/fixtures/layout.jade create mode 100644 node_modules/jade/test/fixtures/mixins.html create mode 100644 node_modules/jade/test/fixtures/mixins.jade create mode 100644 node_modules/jade/test/fixtures/pet-page.jade create mode 100644 node_modules/jade/test/fixtures/pet.html create mode 100644 node_modules/jade/test/fixtures/pet.jade create mode 100644 node_modules/jade/test/fixtures/scripts.jade create mode 100644 node_modules/jade/test/fixtures/super-pet.html create mode 100644 node_modules/jade/test/fixtures/super-pet.jade create mode 100644 node_modules/jade/test/fixtures/test.css create mode 100644 node_modules/jade/test/fixtures/user-layout.jade create mode 100644 node_modules/jade/test/fixtures/user.jade create mode 100644 node_modules/jade/test/fixtures/users.html create mode 100644 node_modules/jade/test/fixtures/users.jade create mode 100644 node_modules/jade/test/jade.test.js create mode 100644 node_modules/stylus/.gitignore create mode 100644 node_modules/stylus/.gitmodules create mode 100644 node_modules/stylus/.npmignore create mode 100644 node_modules/stylus/History.md create mode 100644 node_modules/stylus/LICENSE create mode 100644 node_modules/stylus/Makefile create mode 100644 node_modules/stylus/Readme.md create mode 100755 node_modules/stylus/bin/stylus create mode 100644 node_modules/stylus/bm.js create mode 100644 node_modules/stylus/docs/bifs.md create mode 100644 node_modules/stylus/docs/comments.md create mode 100644 node_modules/stylus/docs/compare.md create mode 100644 node_modules/stylus/docs/conditionals.md create mode 100644 node_modules/stylus/docs/css-style.md create mode 100644 node_modules/stylus/docs/error-reporting.md create mode 100644 node_modules/stylus/docs/escape.md create mode 100644 node_modules/stylus/docs/executable.md create mode 100644 node_modules/stylus/docs/firebug.md create mode 100644 node_modules/stylus/docs/font-face.md create mode 100644 node_modules/stylus/docs/functions.md create mode 100644 node_modules/stylus/docs/functions.url.md create mode 100644 node_modules/stylus/docs/gedit.md create mode 100644 node_modules/stylus/docs/import.md create mode 100644 node_modules/stylus/docs/interpolation.md create mode 100644 node_modules/stylus/docs/introspection.md create mode 100644 node_modules/stylus/docs/iteration.md create mode 100644 node_modules/stylus/docs/js.md create mode 100644 node_modules/stylus/docs/keyframes.md create mode 100644 node_modules/stylus/docs/kwargs.md create mode 100644 node_modules/stylus/docs/literal.md create mode 100644 node_modules/stylus/docs/media.md create mode 100644 node_modules/stylus/docs/middleware.md create mode 100644 node_modules/stylus/docs/mixins.md create mode 100644 node_modules/stylus/docs/operators.md create mode 100644 node_modules/stylus/docs/selectors.md create mode 100644 node_modules/stylus/docs/textmate.md create mode 100644 node_modules/stylus/docs/vargs.md create mode 100644 node_modules/stylus/docs/variables.md create mode 100644 node_modules/stylus/editors/Stylus.tmbundle/Commands/Compile and Display CSS.tmCommand create mode 100644 node_modules/stylus/editors/Stylus.tmbundle/Preferences/Comments.tmPreferences create mode 100644 node_modules/stylus/editors/Stylus.tmbundle/Syntaxes/Stylus.tmLanguage create mode 100644 node_modules/stylus/editors/Stylus.tmbundle/info.plist create mode 100644 node_modules/stylus/editors/gedit/styl.lang create mode 100644 node_modules/stylus/examples/arithmetic.js create mode 100644 node_modules/stylus/examples/arithmetic.styl create mode 100644 node_modules/stylus/examples/basic.js create mode 100644 node_modules/stylus/examples/basic.styl create mode 100644 node_modules/stylus/examples/builtins.js create mode 100644 node_modules/stylus/examples/builtins.styl create mode 100644 node_modules/stylus/examples/comments.js create mode 100644 node_modules/stylus/examples/comments.styl create mode 100644 node_modules/stylus/examples/compress.js create mode 100644 node_modules/stylus/examples/conversions.js create mode 100644 node_modules/stylus/examples/conversions.styl create mode 100644 node_modules/stylus/examples/functions.js create mode 100644 node_modules/stylus/examples/functions.styl create mode 100644 node_modules/stylus/examples/gradients.js create mode 100644 node_modules/stylus/examples/gradients.styl create mode 100644 node_modules/stylus/examples/images.js create mode 100644 node_modules/stylus/examples/images.styl create mode 100644 node_modules/stylus/examples/images/gopher.jpg create mode 100644 node_modules/stylus/examples/images/gradient.svg create mode 100644 node_modules/stylus/examples/images/jesus.gif create mode 100644 node_modules/stylus/examples/images/sprite.gif create mode 100644 node_modules/stylus/examples/implicit-functions.js create mode 100644 node_modules/stylus/examples/implicit-functions.styl create mode 100644 node_modules/stylus/examples/import.js create mode 100644 node_modules/stylus/examples/import.styl create mode 100644 node_modules/stylus/examples/js-functions.js create mode 100644 node_modules/stylus/examples/js-functions.styl create mode 100644 node_modules/stylus/examples/literal.js create mode 100644 node_modules/stylus/examples/literal.styl create mode 100644 node_modules/stylus/examples/middleware.js create mode 100644 node_modules/stylus/examples/mixins/box.styl create mode 100644 node_modules/stylus/examples/mixins/gradients.styl create mode 100644 node_modules/stylus/examples/nesting.js create mode 100644 node_modules/stylus/examples/nesting.styl create mode 100644 node_modules/stylus/examples/public/.gitignore create mode 100644 node_modules/stylus/examples/variables.js create mode 100644 node_modules/stylus/examples/variables.styl create mode 100644 node_modules/stylus/index.js create mode 100644 node_modules/stylus/lib/colors.js create mode 100644 node_modules/stylus/lib/convert/css.js create mode 100644 node_modules/stylus/lib/errors.js create mode 100644 node_modules/stylus/lib/functions/image.js create mode 100644 node_modules/stylus/lib/functions/index.js create mode 100644 node_modules/stylus/lib/functions/index.styl create mode 100644 node_modules/stylus/lib/functions/url.js create mode 100644 node_modules/stylus/lib/lexer.js create mode 100644 node_modules/stylus/lib/middleware.js create mode 100644 node_modules/stylus/lib/nodes/arguments.js create mode 100644 node_modules/stylus/lib/nodes/binop.js create mode 100644 node_modules/stylus/lib/nodes/block.js create mode 100644 node_modules/stylus/lib/nodes/boolean.js create mode 100644 node_modules/stylus/lib/nodes/call.js create mode 100644 node_modules/stylus/lib/nodes/charset.js create mode 100644 node_modules/stylus/lib/nodes/comment.js create mode 100644 node_modules/stylus/lib/nodes/each.js create mode 100644 node_modules/stylus/lib/nodes/expression.js create mode 100644 node_modules/stylus/lib/nodes/fontface.js create mode 100644 node_modules/stylus/lib/nodes/function.js create mode 100644 node_modules/stylus/lib/nodes/group.js create mode 100644 node_modules/stylus/lib/nodes/hsla.js create mode 100644 node_modules/stylus/lib/nodes/ident.js create mode 100644 node_modules/stylus/lib/nodes/if.js create mode 100644 node_modules/stylus/lib/nodes/import.js create mode 100644 node_modules/stylus/lib/nodes/index.js create mode 100644 node_modules/stylus/lib/nodes/jsliteral.js create mode 100644 node_modules/stylus/lib/nodes/keyframes.js create mode 100644 node_modules/stylus/lib/nodes/literal.js create mode 100644 node_modules/stylus/lib/nodes/media.js create mode 100644 node_modules/stylus/lib/nodes/node.js create mode 100644 node_modules/stylus/lib/nodes/null.js create mode 100644 node_modules/stylus/lib/nodes/page.js create mode 100644 node_modules/stylus/lib/nodes/params.js create mode 100644 node_modules/stylus/lib/nodes/property.js create mode 100644 node_modules/stylus/lib/nodes/return.js create mode 100644 node_modules/stylus/lib/nodes/rgba.js create mode 100644 node_modules/stylus/lib/nodes/root.js create mode 100644 node_modules/stylus/lib/nodes/selector.js create mode 100644 node_modules/stylus/lib/nodes/string.js create mode 100644 node_modules/stylus/lib/nodes/ternary.js create mode 100644 node_modules/stylus/lib/nodes/unaryop.js create mode 100644 node_modules/stylus/lib/nodes/unit.js create mode 100644 node_modules/stylus/lib/parser.js create mode 100644 node_modules/stylus/lib/renderer.js create mode 100644 node_modules/stylus/lib/stack/frame.js create mode 100644 node_modules/stylus/lib/stack/index.js create mode 100644 node_modules/stylus/lib/stack/scope.js create mode 100644 node_modules/stylus/lib/stylus.js create mode 100644 node_modules/stylus/lib/token.js create mode 100644 node_modules/stylus/lib/utils.js create mode 100644 node_modules/stylus/lib/visitor/compiler.js create mode 100644 node_modules/stylus/lib/visitor/evaluator.js create mode 100644 node_modules/stylus/lib/visitor/index.js create mode 100644 node_modules/stylus/package.json create mode 100644 node_modules/stylus/test/cases/arithmetic.color.css create mode 100644 node_modules/stylus/test/cases/arithmetic.color.styl create mode 100644 node_modules/stylus/test/cases/arithmetic.css create mode 100644 node_modules/stylus/test/cases/arithmetic.styl create mode 100644 node_modules/stylus/test/cases/arithmetic.unary.css create mode 100644 node_modules/stylus/test/cases/arithmetic.unary.styl create mode 100644 node_modules/stylus/test/cases/atscope.css create mode 100644 node_modules/stylus/test/cases/atscope.styl create mode 100644 node_modules/stylus/test/cases/bifs.add-property.css create mode 100644 node_modules/stylus/test/cases/bifs.add-property.styl create mode 100644 node_modules/stylus/test/cases/bifs.components.css create mode 100644 node_modules/stylus/test/cases/bifs.components.styl create mode 100644 node_modules/stylus/test/cases/bifs.dark.css create mode 100644 node_modules/stylus/test/cases/bifs.dark.styl create mode 100644 node_modules/stylus/test/cases/bifs.darken.css create mode 100644 node_modules/stylus/test/cases/bifs.darken.styl create mode 100644 node_modules/stylus/test/cases/bifs.fade.css create mode 100644 node_modules/stylus/test/cases/bifs.fade.styl create mode 100644 node_modules/stylus/test/cases/bifs.image-size.css create mode 100644 node_modules/stylus/test/cases/bifs.image-size.styl create mode 100644 node_modules/stylus/test/cases/bifs.join.css create mode 100644 node_modules/stylus/test/cases/bifs.join.styl create mode 100644 node_modules/stylus/test/cases/bifs.last.css create mode 100644 node_modules/stylus/test/cases/bifs.last.styl create mode 100644 node_modules/stylus/test/cases/bifs.length.css create mode 100644 node_modules/stylus/test/cases/bifs.length.styl create mode 100644 node_modules/stylus/test/cases/bifs.light.css create mode 100644 node_modules/stylus/test/cases/bifs.light.styl create mode 100644 node_modules/stylus/test/cases/bifs.lighten.css create mode 100644 node_modules/stylus/test/cases/bifs.lighten.styl create mode 100644 node_modules/stylus/test/cases/bifs.lookup.css create mode 100644 node_modules/stylus/test/cases/bifs.lookup.styl create mode 100644 node_modules/stylus/test/cases/bifs.match.css create mode 100644 node_modules/stylus/test/cases/bifs.match.styl create mode 100644 node_modules/stylus/test/cases/bifs.opposite-position.css create mode 100644 node_modules/stylus/test/cases/bifs.opposite-position.styl create mode 100644 node_modules/stylus/test/cases/bifs.push.css create mode 100644 node_modules/stylus/test/cases/bifs.push.styl create mode 100644 node_modules/stylus/test/cases/bifs.rgba.css create mode 100644 node_modules/stylus/test/cases/bifs.rgba.styl create mode 100644 node_modules/stylus/test/cases/bifs.s.css create mode 100644 node_modules/stylus/test/cases/bifs.s.styl create mode 100644 node_modules/stylus/test/cases/bifs.type.css create mode 100644 node_modules/stylus/test/cases/bifs.type.styl create mode 100644 node_modules/stylus/test/cases/bifs.unit.css create mode 100644 node_modules/stylus/test/cases/bifs.unit.styl create mode 100644 node_modules/stylus/test/cases/bifs.unquote.css create mode 100644 node_modules/stylus/test/cases/bifs.unquote.styl create mode 100644 node_modules/stylus/test/cases/bifs.url.css create mode 100644 node_modules/stylus/test/cases/bifs.url.styl create mode 100644 node_modules/stylus/test/cases/coercion.css create mode 100644 node_modules/stylus/test/cases/coercion.styl create mode 100644 node_modules/stylus/test/cases/comments.css create mode 100644 node_modules/stylus/test/cases/comments.styl create mode 100644 node_modules/stylus/test/cases/compress.comments.css create mode 100644 node_modules/stylus/test/cases/compress.comments.styl create mode 100644 node_modules/stylus/test/cases/compress.units.css create mode 100644 node_modules/stylus/test/cases/compress.units.styl create mode 100644 node_modules/stylus/test/cases/conditional-assignment.css create mode 100644 node_modules/stylus/test/cases/conditional-assignment.styl create mode 100644 node_modules/stylus/test/cases/control.blueprint.ie.css create mode 100644 node_modules/stylus/test/cases/control.blueprint.ie.styl create mode 100644 node_modules/stylus/test/cases/control.blueprint.screen.css create mode 100644 node_modules/stylus/test/cases/control.blueprint.screen.styl create mode 100644 node_modules/stylus/test/cases/control.boilerplate.css create mode 100644 node_modules/stylus/test/cases/control.boilerplate.styl create mode 100644 node_modules/stylus/test/cases/css.functions.single-line.css create mode 100644 node_modules/stylus/test/cases/css.functions.single-line.styl create mode 100644 node_modules/stylus/test/cases/css.if.css create mode 100644 node_modules/stylus/test/cases/css.if.styl create mode 100644 node_modules/stylus/test/cases/css.keyframes.css create mode 100644 node_modules/stylus/test/cases/css.keyframes.styl create mode 100644 node_modules/stylus/test/cases/css.large.css create mode 100644 node_modules/stylus/test/cases/css.large.styl create mode 100644 node_modules/stylus/test/cases/css.media.css create mode 100644 node_modules/stylus/test/cases/css.media.styl create mode 100644 node_modules/stylus/test/cases/css.mixins.braces.css create mode 100644 node_modules/stylus/test/cases/css.mixins.braces.styl create mode 100644 node_modules/stylus/test/cases/css.mixins.css create mode 100644 node_modules/stylus/test/cases/css.mixins.root.css create mode 100644 node_modules/stylus/test/cases/css.mixins.root.styl create mode 100644 node_modules/stylus/test/cases/css.mixins.root.wonky.css create mode 100644 node_modules/stylus/test/cases/css.mixins.root.wonky.styl create mode 100644 node_modules/stylus/test/cases/css.mixins.styl create mode 100644 node_modules/stylus/test/cases/css.selector.interpolation.css create mode 100644 node_modules/stylus/test/cases/css.selector.interpolation.styl create mode 100644 node_modules/stylus/test/cases/css.selectors.css create mode 100644 node_modules/stylus/test/cases/css.selectors.styl create mode 100644 node_modules/stylus/test/cases/css.whitespace.css create mode 100644 node_modules/stylus/test/cases/css.whitespace.styl create mode 100644 node_modules/stylus/test/cases/eol-escape.css create mode 100644 node_modules/stylus/test/cases/eol-escape.styl create mode 100644 node_modules/stylus/test/cases/escape.css create mode 100644 node_modules/stylus/test/cases/escape.styl create mode 100644 node_modules/stylus/test/cases/fontface.css create mode 100644 node_modules/stylus/test/cases/fontface.styl create mode 100644 node_modules/stylus/test/cases/for.complex.css create mode 100644 node_modules/stylus/test/cases/for.complex.styl create mode 100644 node_modules/stylus/test/cases/for.css create mode 100644 node_modules/stylus/test/cases/for.function.css create mode 100644 node_modules/stylus/test/cases/for.function.styl create mode 100644 node_modules/stylus/test/cases/for.styl create mode 100644 node_modules/stylus/test/cases/function.arguments.css create mode 100644 node_modules/stylus/test/cases/function.arguments.styl create mode 100644 node_modules/stylus/test/cases/function.literals.css create mode 100644 node_modules/stylus/test/cases/function.literals.styl create mode 100644 node_modules/stylus/test/cases/functions.arg-calls.css create mode 100644 node_modules/stylus/test/cases/functions.arg-calls.styl create mode 100644 node_modules/stylus/test/cases/functions.call.css create mode 100644 node_modules/stylus/test/cases/functions.call.styl create mode 100644 node_modules/stylus/test/cases/functions.css create mode 100644 node_modules/stylus/test/cases/functions.defaults.css create mode 100644 node_modules/stylus/test/cases/functions.defaults.styl create mode 100644 node_modules/stylus/test/cases/functions.multi-line.css create mode 100644 node_modules/stylus/test/cases/functions.multi-line.styl create mode 100644 node_modules/stylus/test/cases/functions.multiple-calls.css create mode 100644 node_modules/stylus/test/cases/functions.multiple-calls.styl create mode 100644 node_modules/stylus/test/cases/functions.nested-calls.css create mode 100644 node_modules/stylus/test/cases/functions.nested-calls.styl create mode 100644 node_modules/stylus/test/cases/functions.nested.css create mode 100644 node_modules/stylus/test/cases/functions.nested.styl create mode 100644 node_modules/stylus/test/cases/functions.property.css create mode 100644 node_modules/stylus/test/cases/functions.property.styl create mode 100644 node_modules/stylus/test/cases/functions.return.css create mode 100644 node_modules/stylus/test/cases/functions.return.each.css create mode 100644 node_modules/stylus/test/cases/functions.return.each.styl create mode 100644 node_modules/stylus/test/cases/functions.return.styl create mode 100644 node_modules/stylus/test/cases/functions.styl create mode 100644 node_modules/stylus/test/cases/functions.variable.css create mode 100644 node_modules/stylus/test/cases/functions.variable.ident.css create mode 100644 node_modules/stylus/test/cases/functions.variable.ident.styl create mode 100644 node_modules/stylus/test/cases/functions.variable.styl create mode 100644 node_modules/stylus/test/cases/hack.star.css create mode 100644 node_modules/stylus/test/cases/hack.star.styl create mode 100644 node_modules/stylus/test/cases/if.css create mode 100644 node_modules/stylus/test/cases/if.else.css create mode 100644 node_modules/stylus/test/cases/if.else.styl create mode 100644 node_modules/stylus/test/cases/if.mixin.css create mode 100644 node_modules/stylus/test/cases/if.mixin.styl create mode 100644 node_modules/stylus/test/cases/if.postfix.css create mode 100644 node_modules/stylus/test/cases/if.postfix.styl create mode 100644 node_modules/stylus/test/cases/if.selectors.css create mode 100644 node_modules/stylus/test/cases/if.selectors.styl create mode 100644 node_modules/stylus/test/cases/if.styl create mode 100644 node_modules/stylus/test/cases/import.basic.css create mode 100644 node_modules/stylus/test/cases/import.basic.styl create mode 100644 node_modules/stylus/test/cases/import.basic/a.styl create mode 100644 node_modules/stylus/test/cases/import.basic/b.styl create mode 100644 node_modules/stylus/test/cases/import.basic/c.styl create mode 100644 node_modules/stylus/test/cases/import.complex.css create mode 100644 node_modules/stylus/test/cases/import.complex.styl create mode 100644 node_modules/stylus/test/cases/import.complex/a.styl create mode 100644 node_modules/stylus/test/cases/import.complex/c.styl create mode 100644 node_modules/stylus/test/cases/import.complex/nested/b.styl create mode 100644 node_modules/stylus/test/cases/import.index.css create mode 100644 node_modules/stylus/test/cases/import.index.styl create mode 100644 node_modules/stylus/test/cases/import.index/vendor/a.styl create mode 100644 node_modules/stylus/test/cases/import.index/vendor/b.styl create mode 100644 node_modules/stylus/test/cases/import.index/vendor/c.styl create mode 100644 node_modules/stylus/test/cases/import.index/vendor/index.styl create mode 100644 node_modules/stylus/test/cases/import.literal.css create mode 100644 node_modules/stylus/test/cases/import.literal.styl create mode 100644 node_modules/stylus/test/cases/import.mixins.css create mode 100644 node_modules/stylus/test/cases/import.mixins.styl create mode 100644 node_modules/stylus/test/cases/import.ordering.css create mode 100644 node_modules/stylus/test/cases/import.ordering.styl create mode 100644 node_modules/stylus/test/cases/import.ordering/five.styl create mode 100644 node_modules/stylus/test/cases/import.ordering/four.styl create mode 100644 node_modules/stylus/test/cases/import.ordering/two.styl create mode 100644 node_modules/stylus/test/cases/important.css create mode 100644 node_modules/stylus/test/cases/important.styl create mode 100644 node_modules/stylus/test/cases/interpolation.properties.css create mode 100644 node_modules/stylus/test/cases/interpolation.properties.styl create mode 100644 node_modules/stylus/test/cases/introspection.css create mode 100644 node_modules/stylus/test/cases/introspection.styl create mode 100644 node_modules/stylus/test/cases/jquery.css create mode 100644 node_modules/stylus/test/cases/jquery.styl create mode 100644 node_modules/stylus/test/cases/keyframes.css create mode 100644 node_modules/stylus/test/cases/keyframes.fabrication.css create mode 100644 node_modules/stylus/test/cases/keyframes.fabrication.defaults.css create mode 100644 node_modules/stylus/test/cases/keyframes.fabrication.defaults.styl create mode 100644 node_modules/stylus/test/cases/keyframes.fabrication.styl create mode 100644 node_modules/stylus/test/cases/keyframes.styl create mode 100644 node_modules/stylus/test/cases/kwargs.css create mode 100644 node_modules/stylus/test/cases/kwargs.styl create mode 100644 node_modules/stylus/test/cases/list.css create mode 100644 node_modules/stylus/test/cases/list.styl create mode 100644 node_modules/stylus/test/cases/literal.color.css create mode 100644 node_modules/stylus/test/cases/literal.color.styl create mode 100644 node_modules/stylus/test/cases/literal.css create mode 100644 node_modules/stylus/test/cases/literal.styl create mode 100644 node_modules/stylus/test/cases/media.css create mode 100644 node_modules/stylus/test/cases/media.styl create mode 100644 node_modules/stylus/test/cases/mixin.conditional.css create mode 100644 node_modules/stylus/test/cases/mixin.conditional.styl create mode 100644 node_modules/stylus/test/cases/mixin.order.conditional.css create mode 100644 node_modules/stylus/test/cases/mixin.order.conditional.styl create mode 100644 node_modules/stylus/test/cases/mixin.order.css create mode 100644 node_modules/stylus/test/cases/mixin.order.nested.css create mode 100644 node_modules/stylus/test/cases/mixin.order.nested.styl create mode 100644 node_modules/stylus/test/cases/mixin.order.styl create mode 100644 node_modules/stylus/test/cases/mixins.complex.css create mode 100644 node_modules/stylus/test/cases/mixins.complex.fix-to.css create mode 100644 node_modules/stylus/test/cases/mixins.complex.fix-to.styl create mode 100644 node_modules/stylus/test/cases/mixins.complex.styl create mode 100644 node_modules/stylus/test/cases/mixins.conditional.css create mode 100644 node_modules/stylus/test/cases/mixins.conditional.styl create mode 100644 node_modules/stylus/test/cases/mixins.nested.css create mode 100644 node_modules/stylus/test/cases/mixins.nested.selectors.css create mode 100644 node_modules/stylus/test/cases/mixins.nested.selectors.styl create mode 100644 node_modules/stylus/test/cases/mixins.nested.styl create mode 100644 node_modules/stylus/test/cases/mixins.order.2.css create mode 100644 node_modules/stylus/test/cases/mixins.order.2.styl create mode 100644 node_modules/stylus/test/cases/mixins.reset.css create mode 100644 node_modules/stylus/test/cases/mixins.reset.styl create mode 100644 node_modules/stylus/test/cases/mixins.return.css create mode 100644 node_modules/stylus/test/cases/mixins.return.styl create mode 100644 node_modules/stylus/test/cases/mixins.root.css create mode 100644 node_modules/stylus/test/cases/mixins.root.styl create mode 100644 node_modules/stylus/test/cases/mixins/box.styl create mode 100644 node_modules/stylus/test/cases/operator.range.css create mode 100644 node_modules/stylus/test/cases/operator.range.styl create mode 100644 node_modules/stylus/test/cases/operators.assignment.function.css create mode 100644 node_modules/stylus/test/cases/operators.assignment.function.styl create mode 100644 node_modules/stylus/test/cases/operators.assignment.mixin.css create mode 100644 node_modules/stylus/test/cases/operators.assignment.mixin.styl create mode 100644 node_modules/stylus/test/cases/operators.assignment.root.css create mode 100644 node_modules/stylus/test/cases/operators.assignment.root.styl create mode 100644 node_modules/stylus/test/cases/operators.complex.css create mode 100644 node_modules/stylus/test/cases/operators.complex.styl create mode 100644 node_modules/stylus/test/cases/operators.css create mode 100644 node_modules/stylus/test/cases/operators.equality.css create mode 100644 node_modules/stylus/test/cases/operators.equality.styl create mode 100644 node_modules/stylus/test/cases/operators.in.css create mode 100644 node_modules/stylus/test/cases/operators.in.styl create mode 100644 node_modules/stylus/test/cases/operators.mixins.css create mode 100644 node_modules/stylus/test/cases/operators.mixins.styl create mode 100644 node_modules/stylus/test/cases/operators.precedence.css create mode 100644 node_modules/stylus/test/cases/operators.precedence.styl create mode 100644 node_modules/stylus/test/cases/operators.styl create mode 100644 node_modules/stylus/test/cases/operators.subscript.assign.css create mode 100644 node_modules/stylus/test/cases/operators.subscript.assign.styl create mode 100644 node_modules/stylus/test/cases/operators.subscript.css create mode 100644 node_modules/stylus/test/cases/operators.subscript.range.css create mode 100644 node_modules/stylus/test/cases/operators.subscript.range.styl create mode 100644 node_modules/stylus/test/cases/operators.subscript.styl create mode 100644 node_modules/stylus/test/cases/page.css create mode 100644 node_modules/stylus/test/cases/page.styl create mode 100644 node_modules/stylus/test/cases/parent.css create mode 100644 node_modules/stylus/test/cases/parent.styl create mode 100644 node_modules/stylus/test/cases/properties.colons.css create mode 100644 node_modules/stylus/test/cases/properties.colons.styl create mode 100644 node_modules/stylus/test/cases/properties.css create mode 100644 node_modules/stylus/test/cases/properties.one-line.css create mode 100644 node_modules/stylus/test/cases/properties.one-line.styl create mode 100644 node_modules/stylus/test/cases/properties.styl create mode 100644 node_modules/stylus/test/cases/property-access.bubble.css create mode 100644 node_modules/stylus/test/cases/property-access.bubble.styl create mode 100644 node_modules/stylus/test/cases/property-access.css create mode 100644 node_modules/stylus/test/cases/property-access.siblings.css create mode 100644 node_modules/stylus/test/cases/property-access.siblings.styl create mode 100644 node_modules/stylus/test/cases/property-access.styl create mode 100644 node_modules/stylus/test/cases/regression.107.lookup-failure.css create mode 100644 node_modules/stylus/test/cases/regression.107.lookup-failure.styl create mode 100644 node_modules/stylus/test/cases/regression.127.css create mode 100644 node_modules/stylus/test/cases/regression.127.styl create mode 100644 node_modules/stylus/test/cases/regression.130.css create mode 100644 node_modules/stylus/test/cases/regression.130.styl create mode 100644 node_modules/stylus/test/cases/regression.131.css create mode 100644 node_modules/stylus/test/cases/regression.131.styl create mode 100644 node_modules/stylus/test/cases/regression.137.css create mode 100644 node_modules/stylus/test/cases/regression.137.styl create mode 100644 node_modules/stylus/test/cases/regression.139.css create mode 100644 node_modules/stylus/test/cases/regression.139.styl create mode 100644 node_modules/stylus/test/cases/regression.142.css create mode 100644 node_modules/stylus/test/cases/regression.142.styl create mode 100644 node_modules/stylus/test/cases/regression.146.css create mode 100644 node_modules/stylus/test/cases/regression.146.styl create mode 100644 node_modules/stylus/test/cases/regression.153.css create mode 100644 node_modules/stylus/test/cases/regression.153.styl create mode 100644 node_modules/stylus/test/cases/regression.154.css create mode 100644 node_modules/stylus/test/cases/regression.154.styl create mode 100644 node_modules/stylus/test/cases/regression.156.css create mode 100644 node_modules/stylus/test/cases/regression.156.styl create mode 100644 node_modules/stylus/test/cases/regression.212.css create mode 100644 node_modules/stylus/test/cases/regression.212.styl create mode 100644 node_modules/stylus/test/cases/regression.216.css create mode 100644 node_modules/stylus/test/cases/regression.216.styl create mode 100644 node_modules/stylus/test/cases/regression.220.css create mode 100644 node_modules/stylus/test/cases/regression.220.styl create mode 100644 node_modules/stylus/test/cases/regression.229.css create mode 100644 node_modules/stylus/test/cases/regression.229.styl create mode 100644 node_modules/stylus/test/cases/regression.233.css create mode 100644 node_modules/stylus/test/cases/regression.233.styl create mode 100644 node_modules/stylus/test/cases/regression.235.css create mode 100644 node_modules/stylus/test/cases/regression.235.styl create mode 100644 node_modules/stylus/test/cases/regression.243.css create mode 100644 node_modules/stylus/test/cases/regression.243.styl create mode 100644 node_modules/stylus/test/cases/regression.244.css create mode 100644 node_modules/stylus/test/cases/regression.244.styl create mode 100644 node_modules/stylus/test/cases/regression.247.css create mode 100644 node_modules/stylus/test/cases/regression.247.styl create mode 100644 node_modules/stylus/test/cases/regression.248.compressed.css create mode 100644 node_modules/stylus/test/cases/regression.248.compressed.styl create mode 100644 node_modules/stylus/test/cases/regression.252.css create mode 100644 node_modules/stylus/test/cases/regression.252.styl create mode 100644 node_modules/stylus/test/cases/regression.260.css create mode 100644 node_modules/stylus/test/cases/regression.260.styl create mode 100644 node_modules/stylus/test/cases/regression.267.css create mode 100644 node_modules/stylus/test/cases/regression.267.styl create mode 100644 node_modules/stylus/test/cases/regression.270.css create mode 100644 node_modules/stylus/test/cases/regression.270.styl create mode 100644 node_modules/stylus/test/cases/regression.272.css create mode 100644 node_modules/stylus/test/cases/regression.272.styl create mode 100644 node_modules/stylus/test/cases/regression.274.css create mode 100644 node_modules/stylus/test/cases/regression.274.styl create mode 100644 node_modules/stylus/test/cases/regression.360.css create mode 100644 node_modules/stylus/test/cases/regression.360.styl create mode 100644 node_modules/stylus/test/cases/regression.368.css create mode 100644 node_modules/stylus/test/cases/regression.368.styl create mode 100644 node_modules/stylus/test/cases/regression.379.css create mode 100644 node_modules/stylus/test/cases/regression.379.styl create mode 100644 node_modules/stylus/test/cases/regression.380.css create mode 100644 node_modules/stylus/test/cases/regression.380.styl create mode 100644 node_modules/stylus/test/cases/regression.388.css create mode 100644 node_modules/stylus/test/cases/regression.388.styl create mode 100644 node_modules/stylus/test/cases/regression.415.css create mode 100644 node_modules/stylus/test/cases/regression.415.styl create mode 100644 node_modules/stylus/test/cases/regression.420.css create mode 100644 node_modules/stylus/test/cases/regression.420.styl create mode 100644 node_modules/stylus/test/cases/regression.440.css create mode 100644 node_modules/stylus/test/cases/regression.440.styl create mode 100644 node_modules/stylus/test/cases/regression.458.css create mode 100644 node_modules/stylus/test/cases/regression.458.styl create mode 100644 node_modules/stylus/test/cases/regression.460.css create mode 100644 node_modules/stylus/test/cases/regression.460.styl create mode 100644 node_modules/stylus/test/cases/reset.css create mode 100644 node_modules/stylus/test/cases/reset.styl create mode 100644 node_modules/stylus/test/cases/rule.charset.css create mode 100644 node_modules/stylus/test/cases/rule.charset.styl create mode 100644 node_modules/stylus/test/cases/rulset.css create mode 100644 node_modules/stylus/test/cases/rulset.newline.css create mode 100644 node_modules/stylus/test/cases/rulset.newline.styl create mode 100644 node_modules/stylus/test/cases/rulset.styl create mode 100644 node_modules/stylus/test/cases/scope.complex.css create mode 100644 node_modules/stylus/test/cases/scope.complex.styl create mode 100644 node_modules/stylus/test/cases/scope.css create mode 100644 node_modules/stylus/test/cases/scope.nested.css create mode 100644 node_modules/stylus/test/cases/scope.nested.styl create mode 100644 node_modules/stylus/test/cases/scope.styl create mode 100644 node_modules/stylus/test/cases/selector.interpolation.css create mode 100644 node_modules/stylus/test/cases/selector.interpolation.styl create mode 100644 node_modules/stylus/test/cases/selectors.complex.css create mode 100644 node_modules/stylus/test/cases/selectors.complex.styl create mode 100644 node_modules/stylus/test/cases/selectors.css create mode 100644 node_modules/stylus/test/cases/selectors.nested.comma.css create mode 100644 node_modules/stylus/test/cases/selectors.nested.comma.styl create mode 100644 node_modules/stylus/test/cases/selectors.nested.css create mode 100644 node_modules/stylus/test/cases/selectors.nested.styl create mode 100644 node_modules/stylus/test/cases/selectors.pseudo.css create mode 100644 node_modules/stylus/test/cases/selectors.pseudo.elements.css create mode 100644 node_modules/stylus/test/cases/selectors.pseudo.elements.styl create mode 100644 node_modules/stylus/test/cases/selectors.pseudo.styl create mode 100644 node_modules/stylus/test/cases/selectors.styl create mode 100644 node_modules/stylus/test/cases/self-assignment.css create mode 100644 node_modules/stylus/test/cases/self-assignment.styl create mode 100644 node_modules/stylus/test/cases/vargs.call.css create mode 100644 node_modules/stylus/test/cases/vargs.call.styl create mode 100644 node_modules/stylus/test/cases/vargs.css create mode 100644 node_modules/stylus/test/cases/vargs.styl create mode 100644 node_modules/stylus/test/cases/variable.css create mode 100644 node_modules/stylus/test/cases/variable.styl create mode 100644 node_modules/stylus/test/cases/variables.css create mode 100644 node_modules/stylus/test/cases/variables.styl create mode 100644 node_modules/stylus/test/images/gif create mode 100644 node_modules/stylus/test/images/squirrel.jpeg create mode 100644 node_modules/stylus/test/images/tux.png create mode 100644 node_modules/stylus/test/run.js create mode 100644 package.json create mode 100644 public/stylesheets/mixins/css3.styl create mode 100644 public/stylesheets/partials/typography.styl create mode 100644 public/stylesheets/style.styl create mode 100644 views/index.jade create mode 100644 views/layout.jade create mode 100644 web.js diff --git a/Procfile b/Procfile new file mode 100644 index 0000000..d1913eb --- /dev/null +++ b/Procfile @@ -0,0 +1 @@ +web: node web.js \ No newline at end of file diff --git a/esritogeo.js b/esritogeo.js new file mode 100644 index 0000000..f828ceb --- /dev/null +++ b/esritogeo.js @@ -0,0 +1,66 @@ +var jsonToObject = function(stringIn) { + console.log("parse with JSON.parse()"); + + /* + var data = JSON.parse(stringIn, function(key, value) { + var type; + if (value && typeof value === 'object') { + type = value.type; + if (typeof type === 'string' && typeof window[type] === 'function') { + return new (window[type])(value); + } + } + return value; + }); + */ + + var data = JSON.parse(stringIn); + console.log("json converted to object"); + return data; +}; + +var parseGeometryType = function(type) { + if (type === "esriGeometryPolygon") { + return "Polygon"; + } + return "none"; +}; + +var deserialize = function(js, callback) { + console.log("begin parsing json"); + var geoJS = {}; + var o = jsonToObject(js); + var geomType; + geomType = parseGeometryType(o.geometryType); + + // prepare the main parts of the GeoJSON + var geometry = {}; + geometry.type = geomType; + + // grab the rings to coordinates + var coordinates = o.features[0].geometry.rings; + geometry.coordinates = coordinates; + + // convert attributes to properties + var properties = {}; + var attr = o.features[0].attributes; + for (var field in attr) { + properties[field] = attr[field]; + } + + geoJS.geometry = geometry; + geoJS.properties = properties; + + var result = JSON.stringify(geoJS, function(key, value) { + if (typeof value === 'number' && !isFinite(value)) { + return String(value); + } + return value; + }); + + console.log("json parsed, return it"); + + callback(null, result); +}; + +exports.deserialize = deserialize; \ No newline at end of file diff --git a/node_modules/.bin/express b/node_modules/.bin/express new file mode 120000 index 0000000..b741d99 --- /dev/null +++ b/node_modules/.bin/express @@ -0,0 +1 @@ +../express/bin/express \ No newline at end of file diff --git a/node_modules/.bin/jade b/node_modules/.bin/jade new file mode 120000 index 0000000..571fae7 --- /dev/null +++ b/node_modules/.bin/jade @@ -0,0 +1 @@ +../jade/bin/jade \ No newline at end of file diff --git a/node_modules/.bin/stylus b/node_modules/.bin/stylus new file mode 120000 index 0000000..4113f9b --- /dev/null +++ b/node_modules/.bin/stylus @@ -0,0 +1 @@ +../stylus/bin/stylus \ No newline at end of file diff --git a/node_modules/express/.npmignore b/node_modules/express/.npmignore new file mode 100644 index 0000000..74bd365 --- /dev/null +++ b/node_modules/express/.npmignore @@ -0,0 +1,7 @@ +.git* +docs/ +examples/ +support/ +test/ +testing.js +.DS_Store diff --git a/node_modules/express/History.md b/node_modules/express/History.md new file mode 100644 index 0000000..0527ec2 --- /dev/null +++ b/node_modules/express/History.md @@ -0,0 +1,770 @@ + +2.5.1 / 2011-11-17 +================== + + * Changed: updated connect to 1.8.x + * Removed sass.js support from express(1) + +2.5.0 / 2011-10-24 +================== + + * Added ./routes dir for generated app by default + * Added npm install reminder to express(1) app gen + * Added 0.5.x support + * Removed `make test-cov` since it wont work with node 0.5.x + * Fixed express(1) public dir for windows. Closes #866 + +2.4.7 / 2011-10-05 +================== + + * Added mkdirp to express(1). Closes #795 + * Added simple _json-config_ example + * Added shorthand for the parsed request's pathname via `req.path` + * Changed connect dep to 1.7.x to fix npm issue... + * Fixed `res.redirect()` __HEAD__ support. [reported by xerox] + * Fixed `req.flash()`, only escape args + * Fixed absolute path checking on windows. Closes #829 [reported by andrewpmckenzie] + +2.4.6 / 2011-08-22 +================== + + * Fixed multiple param callback regression. Closes #824 [reported by TroyGoode] + +2.4.5 / 2011-08-19 +================== + + * Added support for routes to handle errors. Closes #809 + * Added `app.routes.all()`. Closes #803 + * Added "basepath" setting to work in conjunction with reverse proxies etc. + * Refactored `Route` to use a single array of callbacks + * Added support for multiple callbacks for `app.param()`. Closes #801 +Closes #805 + * Changed: removed .call(self) for route callbacks + * Dependency: `qs >= 0.3.1` + * Fixed `res.redirect()` on windows due to `join()` usage. Closes #808 + +2.4.4 / 2011-08-05 +================== + + * Fixed `res.header()` intention of a set, even when `undefined` + * Fixed `*`, value no longer required + * Fixed `res.send(204)` support. Closes #771 + +2.4.3 / 2011-07-14 +================== + + * Added docs for `status` option special-case. Closes #739 + * Fixed `options.filename`, exposing the view path to template engines + +2.4.2. / 2011-07-06 +================== + + * Revert "removed jsonp stripping" for XSS + +2.4.1 / 2011-07-06 +================== + + * Added `res.json()` JSONP support. Closes #737 + * Added _extending-templates_ example. Closes #730 + * Added "strict routing" setting for trailing slashes + * Added support for multiple envs in `app.configure()` calls. Closes #735 + * Changed: `res.send()` using `res.json()` + * Changed: when cookie `path === null` don't default it + * Changed; default cookie path to "home" setting. Closes #731 + * Removed _pids/logs_ creation from express(1) + +2.4.0 / 2011-06-28 +================== + + * Added chainable `res.status(code)` + * Added `res.json()`, an explicit version of `res.send(obj)` + * Added simple web-service example + +2.3.12 / 2011-06-22 +================== + + * \#express is now on freenode! come join! + * Added `req.get(field, param)` + * Added links to Japanese documentation, thanks @hideyukisaito! + * Added; the `express(1)` generated app outputs the env + * Added `content-negotiation` example + * Dependency: connect >= 1.5.1 < 2.0.0 + * Fixed view layout bug. Closes #720 + * Fixed; ignore body on 304. Closes #701 + +2.3.11 / 2011-06-04 +================== + + * Added `npm test` + * Removed generation of dummy test file from `express(1)` + * Fixed; `express(1)` adds express as a dep + * Fixed; prune on `prepublish` + +2.3.10 / 2011-05-27 +================== + + * Added `req.route`, exposing the current route + * Added _package.json_ generation support to `express(1)` + * Fixed call to `app.param()` function for optional params. Closes #682 + +2.3.9 / 2011-05-25 +================== + + * Fixed bug-ish with `../' in `res.partial()` calls + +2.3.8 / 2011-05-24 +================== + + * Fixed `app.options()` + +2.3.7 / 2011-05-23 +================== + + * Added route `Collection`, ex: `app.get('/user/:id').remove();` + * Added support for `app.param(fn)` to define param logic + * Removed `app.param()` support for callback with return value + * Removed module.parent check from express(1) generated app. Closes #670 + * Refactored router. Closes #639 + +2.3.6 / 2011-05-20 +================== + + * Changed; using devDependencies instead of git submodules + * Fixed redis session example + * Fixed markdown example + * Fixed view caching, should not be enabled in development + +2.3.5 / 2011-05-20 +================== + + * Added export `.view` as alias for `.View` + +2.3.4 / 2011-05-08 +================== + + * Added `./examples/say` + * Fixed `res.sendfile()` bug preventing the transfer of files with spaces + +2.3.3 / 2011-05-03 +================== + + * Added "case sensitive routes" option. + * Changed; split methods supported per rfc [slaskis] + * Fixed route-specific middleware when using the same callback function several times + +2.3.2 / 2011-04-27 +================== + + * Fixed view hints + +2.3.1 / 2011-04-26 +================== + + * Added `app.match()` as `app.match.all()` + * Added `app.lookup()` as `app.lookup.all()` + * Added `app.remove()` for `app.remove.all()` + * Added `app.remove.VERB()` + * Fixed template caching collision issue. Closes #644 + * Moved router over from connect and started refactor + +2.3.0 / 2011-04-25 +================== + + * Added options support to `res.clearCookie()` + * Added `res.helpers()` as alias of `res.locals()` + * Added; json defaults to UTF-8 with `res.send()`. Closes #632. [Daniel * Dependency `connect >= 1.4.0` + * Changed; auto set Content-Type in res.attachement [Aaron Heckmann] + * Renamed "cache views" to "view cache". Closes #628 + * Fixed caching of views when using several apps. Closes #637 + * Fixed gotcha invoking `app.param()` callbacks once per route middleware. +Closes #638 + * Fixed partial lookup precedence. Closes #631 +Shaw] + +2.2.2 / 2011-04-12 +================== + + * Added second callback support for `res.download()` connection errors + * Fixed `filename` option passing to template engine + +2.2.1 / 2011-04-04 +================== + + * Added `layout(path)` helper to change the layout within a view. Closes #610 + * Fixed `partial()` collection object support. + Previously only anything with `.length` would work. + When `.length` is present one must still be aware of holes, + however now `{ collection: {foo: 'bar'}}` is valid, exposes + `keyInCollection` and `keysInCollection`. + + * Performance improved with better view caching + * Removed `request` and `response` locals + * Changed; errorHandler page title is now `Express` instead of `Connect` + +2.2.0 / 2011-03-30 +================== + + * Added `app.lookup.VERB()`, ex `app.lookup.put('/user/:id')`. Closes #606 + * Added `app.match.VERB()`, ex `app.match.put('/user/12')`. Closes #606 + * Added `app.VERB(path)` as alias of `app.lookup.VERB()`. + * Dependency `connect >= 1.2.0` + +2.1.1 / 2011-03-29 +================== + + * Added; expose `err.view` object when failing to locate a view + * Fixed `res.partial()` call `next(err)` when no callback is given [reported by aheckmann] + * Fixed; `res.send(undefined)` responds with 204 [aheckmann] + +2.1.0 / 2011-03-24 +================== + + * Added `/_?` partial lookup support. Closes #447 + * Added `request`, `response`, and `app` local variables + * Added `settings` local variable, containing the app's settings + * Added `req.flash()` exception if `req.session` is not available + * Added `res.send(bool)` support (json response) + * Fixed stylus example for latest version + * Fixed; wrap try/catch around `res.render()` + +2.0.0 / 2011-03-17 +================== + + * Fixed up index view path alternative. + * Changed; `res.locals()` without object returns the locals + +2.0.0rc3 / 2011-03-17 +================== + + * Added `res.locals(obj)` to compliment `res.local(key, val)` + * Added `res.partial()` callback support + * Fixed recursive error reporting issue in `res.render()` + +2.0.0rc2 / 2011-03-17 +================== + + * Changed; `partial()` "locals" are now optional + * Fixed `SlowBuffer` support. Closes #584 [reported by tyrda01] + * Fixed .filename view engine option [reported by drudge] + * Fixed blog example + * Fixed `{req,res}.app` reference when mounting [Ben Weaver] + +2.0.0rc / 2011-03-14 +================== + + * Fixed; expose `HTTPSServer` constructor + * Fixed express(1) default test charset. Closes #579 [reported by secoif] + * Fixed; default charset to utf-8 instead of utf8 for lame IE [reported by NickP] + +2.0.0beta3 / 2011-03-09 +================== + + * Added support for `res.contentType()` literal + The original `res.contentType('.json')`, + `res.contentType('application/json')`, and `res.contentType('json')` + will work now. + * Added `res.render()` status option support back + * Added charset option for `res.render()` + * Added `.charset` support (via connect 1.0.4) + * Added view resolution hints when in development and a lookup fails + * Added layout lookup support relative to the page view. + For example while rendering `./views/user/index.jade` if you create + `./views/user/layout.jade` it will be used in favour of the root layout. + * Fixed `res.redirect()`. RFC states absolute url [reported by unlink] + * Fixed; default `res.send()` string charset to utf8 + * Removed `Partial` constructor (not currently used) + +2.0.0beta2 / 2011-03-07 +================== + + * Added res.render() `.locals` support back to aid in migration process + * Fixed flash example + +2.0.0beta / 2011-03-03 +================== + + * Added HTTPS support + * Added `res.cookie()` maxAge support + * Added `req.header()` _Referrer_ / _Referer_ special-case, either works + * Added mount support for `res.redirect()`, now respects the mount-point + * Added `union()` util, taking place of `merge(clone())` combo + * Added stylus support to express(1) generated app + * Added secret to session middleware used in examples and generated app + * Added `res.local(name, val)` for progressive view locals + * Added default param support to `req.param(name, default)` + * Added `app.disabled()` and `app.enabled()` + * Added `app.register()` support for omitting leading ".", either works + * Added `res.partial()`, using the same interface as `partial()` within a view. Closes #539 + * Added `app.param()` to map route params to async/sync logic + * Added; aliased `app.helpers()` as `app.locals()`. Closes #481 + * Added extname with no leading "." support to `res.contentType()` + * Added `cache views` setting, defaulting to enabled in "production" env + * Added index file partial resolution, eg: partial('user') may try _views/user/index.jade_. + * Added `req.accepts()` support for extensions + * Changed; `res.download()` and `res.sendfile()` now utilize Connect's + static file server `connect.static.send()`. + * Changed; replaced `connect.utils.mime()` with npm _mime_ module + * Changed; allow `req.query` to be pre-defined (via middleware or other parent + * Changed view partial resolution, now relative to parent view + * Changed view engine signature. no longer `engine.render(str, options, callback)`, now `engine.compile(str, options) -> Function`, the returned function accepts `fn(locals)`. + * Fixed `req.param()` bug returning Array.prototype methods. Closes #552 + * Fixed; using `Stream#pipe()` instead of `sys.pump()` in `res.sendfile()` + * Fixed; using _qs_ module instead of _querystring_ + * Fixed; strip unsafe chars from jsonp callbacks + * Removed "stream threshold" setting + +1.0.8 / 2011-03-01 +================== + + * Allow `req.query` to be pre-defined (via middleware or other parent app) + * "connect": ">= 0.5.0 < 1.0.0". Closes #547 + * Removed the long deprecated __EXPRESS_ENV__ support + +1.0.7 / 2011-02-07 +================== + + * Fixed `render()` setting inheritance. + Mounted apps would not inherit "view engine" + +1.0.6 / 2011-02-07 +================== + + * Fixed `view engine` setting bug when period is in dirname + +1.0.5 / 2011-02-05 +================== + + * Added secret to generated app `session()` call + +1.0.4 / 2011-02-05 +================== + + * Added `qs` dependency to _package.json_ + * Fixed namespaced `require()`s for latest connect support + +1.0.3 / 2011-01-13 +================== + + * Remove unsafe characters from JSONP callback names [Ryan Grove] + +1.0.2 / 2011-01-10 +================== + + * Removed nested require, using `connect.router` + +1.0.1 / 2010-12-29 +================== + + * Fixed for middleware stacked via `createServer()` + previously the `foo` middleware passed to `createServer(foo)` + would not have access to Express methods such as `res.send()` + or props like `req.query` etc. + +1.0.0 / 2010-11-16 +================== + + * Added; deduce partial object names from the last segment. + For example by default `partial('forum/post', postObject)` will + give you the _post_ object, providing a meaningful default. + * Added http status code string representation to `res.redirect()` body + * Added; `res.redirect()` supporting _text/plain_ and _text/html_ via __Accept__. + * Added `req.is()` to aid in content negotiation + * Added partial local inheritance [suggested by masylum]. Closes #102 + providing access to parent template locals. + * Added _-s, --session[s]_ flag to express(1) to add session related middleware + * Added _--template_ flag to express(1) to specify the + template engine to use. + * Added _--css_ flag to express(1) to specify the + stylesheet engine to use (or just plain css by default). + * Added `app.all()` support [thanks aheckmann] + * Added partial direct object support. + You may now `partial('user', user)` providing the "user" local, + vs previously `partial('user', { object: user })`. + * Added _route-separation_ example since many people question ways + to do this with CommonJS modules. Also view the _blog_ example for + an alternative. + * Performance; caching view path derived partial object names + * Fixed partial local inheritance precedence. [reported by Nick Poulden] Closes #454 + * Fixed jsonp support; _text/javascript_ as per mailinglist discussion + +1.0.0rc4 / 2010-10-14 +================== + + * Added _NODE_ENV_ support, _EXPRESS_ENV_ is deprecated and will be removed in 1.0.0 + * Added route-middleware support (very helpful, see the [docs](http://expressjs.com/guide.html#Route-Middleware)) + * Added _jsonp callback_ setting to enable/disable jsonp autowrapping [Dav Glass] + * Added callback query check on response.send to autowrap JSON objects for simple webservice implementations [Dav Glass] + * Added `partial()` support for array-like collections. Closes #434 + * Added support for swappable querystring parsers + * Added session usage docs. Closes #443 + * Added dynamic helper caching. Closes #439 [suggested by maritz] + * Added authentication example + * Added basic Range support to `res.sendfile()` (and `res.download()` etc) + * Changed; `express(1)` generated app using 2 spaces instead of 4 + * Default env to "development" again [aheckmann] + * Removed _context_ option is no more, use "scope" + * Fixed; exposing _./support_ libs to examples so they can run without installs + * Fixed mvc example + +1.0.0rc3 / 2010-09-20 +================== + + * Added confirmation for `express(1)` app generation. Closes #391 + * Added extending of flash formatters via `app.flashFormatters` + * Added flash formatter support. Closes #411 + * Added streaming support to `res.sendfile()` using `sys.pump()` when >= "stream threshold" + * Added _stream threshold_ setting for `res.sendfile()` + * Added `res.send()` __HEAD__ support + * Added `res.clearCookie()` + * Added `res.cookie()` + * Added `res.render()` headers option + * Added `res.redirect()` response bodies + * Added `res.render()` status option support. Closes #425 [thanks aheckmann] + * Fixed `res.sendfile()` responding with 403 on malicious path + * Fixed `res.download()` bug; when an error occurs remove _Content-Disposition_ + * Fixed; mounted apps settings now inherit from parent app [aheckmann] + * Fixed; stripping Content-Length / Content-Type when 204 + * Fixed `res.send()` 204. Closes #419 + * Fixed multiple _Set-Cookie_ headers via `res.header()`. Closes #402 + * Fixed bug messing with error handlers when `listenFD()` is called instead of `listen()`. [thanks guillermo] + + +1.0.0rc2 / 2010-08-17 +================== + + * Added `app.register()` for template engine mapping. Closes #390 + * Added `res.render()` callback support as second argument (no options) + * Added callback support to `res.download()` + * Added callback support for `res.sendfile()` + * Added support for middleware access via `express.middlewareName()` vs `connect.middlewareName()` + * Added "partials" setting to docs + * Added default expresso tests to `express(1)` generated app. Closes #384 + * Fixed `res.sendfile()` error handling, defer via `next()` + * Fixed `res.render()` callback when a layout is used [thanks guillermo] + * Fixed; `make install` creating ~/.node_libraries when not present + * Fixed issue preventing error handlers from being defined anywhere. Closes #387 + +1.0.0rc / 2010-07-28 +================== + + * Added mounted hook. Closes #369 + * Added connect dependency to _package.json_ + + * Removed "reload views" setting and support code + development env never caches, production always caches. + + * Removed _param_ in route callbacks, signature is now + simply (req, res, next), previously (req, res, params, next). + Use _req.params_ for path captures, _req.query_ for GET params. + + * Fixed "home" setting + * Fixed middleware/router precedence issue. Closes #366 + * Fixed; _configure()_ callbacks called immediately. Closes #368 + +1.0.0beta2 / 2010-07-23 +================== + + * Added more examples + * Added; exporting `Server` constructor + * Added `Server#helpers()` for view locals + * Added `Server#dynamicHelpers()` for dynamic view locals. Closes #349 + * Added support for absolute view paths + * Added; _home_ setting defaults to `Server#route` for mounted apps. Closes #363 + * Added Guillermo Rauch to the contributor list + * Added support for "as" for non-collection partials. Closes #341 + * Fixed _install.sh_, ensuring _~/.node_libraries_ exists. Closes #362 [thanks jf] + * Fixed `res.render()` exceptions, now passed to `next()` when no callback is given [thanks guillermo] + * Fixed instanceof `Array` checks, now `Array.isArray()` + * Fixed express(1) expansion of public dirs. Closes #348 + * Fixed middleware precedence. Closes #345 + * Fixed view watcher, now async [thanks aheckmann] + +1.0.0beta / 2010-07-15 +================== + + * Re-write + - much faster + - much lighter + - Check [ExpressJS.com](http://expressjs.com) for migration guide and updated docs + +0.14.0 / 2010-06-15 +================== + + * Utilize relative requires + * Added Static bufferSize option [aheckmann] + * Fixed caching of view and partial subdirectories [aheckmann] + * Fixed mime.type() comments now that ".ext" is not supported + * Updated haml submodule + * Updated class submodule + * Removed bin/express + +0.13.0 / 2010-06-01 +================== + + * Added node v0.1.97 compatibility + * Added support for deleting cookies via Request#cookie('key', null) + * Updated haml submodule + * Fixed not-found page, now using using charset utf-8 + * Fixed show-exceptions page, now using using charset utf-8 + * Fixed view support due to fs.readFile Buffers + * Changed; mime.type() no longer accepts ".type" due to node extname() changes + +0.12.0 / 2010-05-22 +================== + + * Added node v0.1.96 compatibility + * Added view `helpers` export which act as additional local variables + * Updated haml submodule + * Changed ETag; removed inode, modified time only + * Fixed LF to CRLF for setting multiple cookies + * Fixed cookie complation; values are now urlencoded + * Fixed cookies parsing; accepts quoted values and url escaped cookies + +0.11.0 / 2010-05-06 +================== + + * Added support for layouts using different engines + - this.render('page.html.haml', { layout: 'super-cool-layout.html.ejs' }) + - this.render('page.html.haml', { layout: 'foo' }) // assumes 'foo.html.haml' + - this.render('page.html.haml', { layout: false }) // no layout + * Updated ext submodule + * Updated haml submodule + * Fixed EJS partial support by passing along the context. Issue #307 + +0.10.1 / 2010-05-03 +================== + + * Fixed binary uploads. + +0.10.0 / 2010-04-30 +================== + + * Added charset support via Request#charset (automatically assigned to 'UTF-8' when respond()'s + encoding is set to 'utf8' or 'utf-8'. + * Added "encoding" option to Request#render(). Closes #299 + * Added "dump exceptions" setting, which is enabled by default. + * Added simple ejs template engine support + * Added error reponse support for text/plain, application/json. Closes #297 + * Added callback function param to Request#error() + * Added Request#sendHead() + * Added Request#stream() + * Added support for Request#respond(304, null) for empty response bodies + * Added ETag support to Request#sendfile() + * Added options to Request#sendfile(), passed to fs.createReadStream() + * Added filename arg to Request#download() + * Performance enhanced due to pre-reversing plugins so that plugins.reverse() is not called on each request + * Performance enhanced by preventing several calls to toLowerCase() in Router#match() + * Changed; Request#sendfile() now streams + * Changed; Renamed Request#halt() to Request#respond(). Closes #289 + * Changed; Using sys.inspect() instead of JSON.encode() for error output + * Changed; run() returns the http.Server instance. Closes #298 + * Changed; Defaulting Server#host to null (INADDR_ANY) + * Changed; Logger "common" format scale of 0.4f + * Removed Logger "request" format + * Fixed; Catching ENOENT in view caching, preventing error when "views/partials" is not found + * Fixed several issues with http client + * Fixed Logger Content-Length output + * Fixed bug preventing Opera from retaining the generated session id. Closes #292 + +0.9.0 / 2010-04-14 +================== + + * Added DSL level error() route support + * Added DSL level notFound() route support + * Added Request#error() + * Added Request#notFound() + * Added Request#render() callback function. Closes #258 + * Added "max upload size" setting + * Added "magic" variables to collection partials (\_\_index\_\_, \_\_length\_\_, \_\_isFirst\_\_, \_\_isLast\_\_). Closes #254 + * Added [haml.js](http://github.com/visionmedia/haml.js) submodule; removed haml-js + * Added callback function support to Request#halt() as 3rd/4th arg + * Added preprocessing of route param wildcards using param(). Closes #251 + * Added view partial support (with collections etc) + * Fixed bug preventing falsey params (such as ?page=0). Closes #286 + * Fixed setting of multiple cookies. Closes #199 + * Changed; view naming convention is now NAME.TYPE.ENGINE (for example page.html.haml) + * Changed; session cookie is now httpOnly + * Changed; Request is no longer global + * Changed; Event is no longer global + * Changed; "sys" module is no longer global + * Changed; moved Request#download to Static plugin where it belongs + * Changed; Request instance created before body parsing. Closes #262 + * Changed; Pre-caching views in memory when "cache view contents" is enabled. Closes #253 + * Changed; Pre-caching view partials in memory when "cache view partials" is enabled + * Updated support to node --version 0.1.90 + * Updated dependencies + * Removed set("session cookie") in favour of use(Session, { cookie: { ... }}) + * Removed utils.mixin(); use Object#mergeDeep() + +0.8.0 / 2010-03-19 +================== + + * Added coffeescript example app. Closes #242 + * Changed; cache api now async friendly. Closes #240 + * Removed deprecated 'express/static' support. Use 'express/plugins/static' + +0.7.6 / 2010-03-19 +================== + + * Added Request#isXHR. Closes #229 + * Added `make install` (for the executable) + * Added `express` executable for setting up simple app templates + * Added "GET /public/*" to Static plugin, defaulting to /public + * Added Static plugin + * Fixed; Request#render() only calls cache.get() once + * Fixed; Namespacing View caches with "view:" + * Fixed; Namespacing Static caches with "static:" + * Fixed; Both example apps now use the Static plugin + * Fixed set("views"). Closes #239 + * Fixed missing space for combined log format + * Deprecated Request#sendfile() and 'express/static' + * Removed Server#running + +0.7.5 / 2010-03-16 +================== + + * Added Request#flash() support without args, now returns all flashes + * Updated ext submodule + +0.7.4 / 2010-03-16 +================== + + * Fixed session reaper + * Changed; class.js replacing js-oo Class implementation (quite a bit faster, no browser cruft) + +0.7.3 / 2010-03-16 +================== + + * Added package.json + * Fixed requiring of haml / sass due to kiwi removal + +0.7.2 / 2010-03-16 +================== + + * Fixed GIT submodules (HAH!) + +0.7.1 / 2010-03-16 +================== + + * Changed; Express now using submodules again until a PM is adopted + * Changed; chat example using millisecond conversions from ext + +0.7.0 / 2010-03-15 +================== + + * Added Request#pass() support (finds the next matching route, or the given path) + * Added Logger plugin (default "common" format replaces CommonLogger) + * Removed Profiler plugin + * Removed CommonLogger plugin + +0.6.0 / 2010-03-11 +================== + + * Added seed.yml for kiwi package management support + * Added HTTP client query string support when method is GET. Closes #205 + + * Added support for arbitrary view engines. + For example "foo.engine.html" will now require('engine'), + the exports from this module are cached after the first require(). + + * Added async plugin support + + * Removed usage of RESTful route funcs as http client + get() etc, use http.get() and friends + + * Removed custom exceptions + +0.5.0 / 2010-03-10 +================== + + * Added ext dependency (library of js extensions) + * Removed extname() / basename() utils. Use path module + * Removed toArray() util. Use arguments.values + * Removed escapeRegexp() util. Use RegExp.escape() + * Removed process.mixin() dependency. Use utils.mixin() + * Removed Collection + * Removed ElementCollection + * Shameless self promotion of ebook "Advanced JavaScript" (http://dev-mag.com) ;) + +0.4.0 / 2010-02-11 +================== + + * Added flash() example to sample upload app + * Added high level restful http client module (express/http) + * Changed; RESTful route functions double as HTTP clients. Closes #69 + * Changed; throwing error when routes are added at runtime + * Changed; defaulting render() context to the current Request. Closes #197 + * Updated haml submodule + +0.3.0 / 2010-02-11 +================== + + * Updated haml / sass submodules. Closes #200 + * Added flash message support. Closes #64 + * Added accepts() now allows multiple args. fixes #117 + * Added support for plugins to halt. Closes #189 + * Added alternate layout support. Closes #119 + * Removed Route#run(). Closes #188 + * Fixed broken specs due to use(Cookie) missing + +0.2.1 / 2010-02-05 +================== + + * Added "plot" format option for Profiler (for gnuplot processing) + * Added request number to Profiler plugin + * Fixed binary encoding for multi-part file uploads, was previously defaulting to UTF8 + * Fixed issue with routes not firing when not files are present. Closes #184 + * Fixed process.Promise -> events.Promise + +0.2.0 / 2010-02-03 +================== + + * Added parseParam() support for name[] etc. (allows for file inputs with "multiple" attr) Closes #180 + * Added Both Cache and Session option "reapInterval" may be "reapEvery". Closes #174 + * Added expiration support to cache api with reaper. Closes #133 + * Added cache Store.Memory#reap() + * Added Cache; cache api now uses first class Cache instances + * Added abstract session Store. Closes #172 + * Changed; cache Memory.Store#get() utilizing Collection + * Renamed MemoryStore -> Store.Memory + * Fixed use() of the same plugin several time will always use latest options. Closes #176 + +0.1.0 / 2010-02-03 +================== + + * Changed; Hooks (before / after) pass request as arg as well as evaluated in their context + * Updated node support to 0.1.27 Closes #169 + * Updated dirname(__filename) -> __dirname + * Updated libxmljs support to v0.2.0 + * Added session support with memory store / reaping + * Added quick uid() helper + * Added multi-part upload support + * Added Sass.js support / submodule + * Added production env caching view contents and static files + * Added static file caching. Closes #136 + * Added cache plugin with memory stores + * Added support to StaticFile so that it works with non-textual files. + * Removed dirname() helper + * Removed several globals (now their modules must be required) + +0.0.2 / 2010-01-10 +================== + + * Added view benchmarks; currently haml vs ejs + * Added Request#attachment() specs. Closes #116 + * Added use of node's parseQuery() util. Closes #123 + * Added `make init` for submodules + * Updated Haml + * Updated sample chat app to show messages on load + * Updated libxmljs parseString -> parseHtmlString + * Fixed `make init` to work with older versions of git + * Fixed specs can now run independant specs for those who cant build deps. Closes #127 + * Fixed issues introduced by the node url module changes. Closes 126. + * Fixed two assertions failing due to Collection#keys() returning strings + * Fixed faulty Collection#toArray() spec due to keys() returning strings + * Fixed `make test` now builds libxmljs.node before testing + +0.0.1 / 2010-01-03 +================== + + * Initial release diff --git a/node_modules/express/LICENSE b/node_modules/express/LICENSE new file mode 100644 index 0000000..36075a3 --- /dev/null +++ b/node_modules/express/LICENSE @@ -0,0 +1,22 @@ +(The MIT License) + +Copyright (c) 2009-2011 TJ Holowaychuk + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/node_modules/express/Makefile b/node_modules/express/Makefile new file mode 100644 index 0000000..dfbfd67 --- /dev/null +++ b/node_modules/express/Makefile @@ -0,0 +1,29 @@ + +DOCS = $(shell find docs/*.md) +HTMLDOCS = $(DOCS:.md=.html) +TESTS = $(shell find test/*.test.js) + +test: + @NODE_ENV=test ./node_modules/.bin/expresso $(TESTS) + +docs: $(HTMLDOCS) + @ echo "... generating TOC" + @./support/toc.js docs/guide.html + +%.html: %.md + @echo "... $< -> $@" + @markdown $< \ + | cat docs/layout/head.html - docs/layout/foot.html \ + > $@ + +site: + rm -fr /tmp/docs \ + && cp -fr docs /tmp/docs \ + && git checkout gh-pages \ + && cp -fr /tmp/docs/* . \ + && echo "done" + +docclean: + rm -f docs/*.{1,html} + +.PHONY: site test docs docclean \ No newline at end of file diff --git a/node_modules/express/Readme.md b/node_modules/express/Readme.md new file mode 100644 index 0000000..d2c64c7 --- /dev/null +++ b/node_modules/express/Readme.md @@ -0,0 +1,145 @@ + +# Express + + Insanely fast (and small) server-side JavaScript web development framework + built on [node](http://nodejs.org) and [Connect](http://github.com/senchalabs/connect). + + var app = express.createServer(); + + app.get('/', function(req, res){ + res.send('Hello World'); + }); + + app.listen(3000); + +## Installation + + $ npm install express + +or to access the `express(1)` executable install globally: + + $ npm install -g express + +## Quick Start + + The quickest way to get started with express is to utilize the executable `express(1)` to generate an application as shown below: + + Create the app: + + $ npm install -g express + $ express /tmp/foo && cd /tmp/foo + + Install dependencies: + + $ npm install -d + + Start the server: + + $ node app.js + +## Features + + * Robust routing + * Redirection helpers + * Dynamic view helpers + * Content negotiation + * Focus on high performance + * View rendering and partials support + * Environment based configuration + * Session based flash notifications + * Built on [Connect](http://github.com/senchalabs/connect) + * High test coverage + * Executable for generating applications quickly + * Application level view options + +Via Connect: + + * Session support + * Cache API + * Mime helpers + * ETag support + * Persistent flash notifications + * Cookie support + * JSON-RPC + * Logging + * and _much_ more! + +## Contributors + +The following are the major contributors of Express (in no specific order). + + * TJ Holowaychuk ([visionmedia](http://github.com/visionmedia)) + * Ciaran Jessup ([ciaranj](http://github.com/ciaranj)) + * Aaron Heckmann ([aheckmann](http://github.com/aheckmann)) + * Guillermo Rauch ([guille](http://github.com/guille)) + +## More Information + + * #express on freenode + * [express-expose](http://github.com/visionmedia/express-expose) expose objects, functions, modules and more to client-side js with ease + * [express-configure](http://github.com/visionmedia/express-configuration) async configuration support + * [express-messages](http://github.com/visionmedia/express-messages) flash notification rendering helper + * [express-namespace](http://github.com/visionmedia/express-namespace) namespaced route support + * [express-params](https://github.com/visionmedia/express-params) param pre-condition functions + * [express-mongoose](https://github.com/LearnBoost/express-mongoose) plugin for easy rendering of Mongoose async Query results + * Follow [tjholowaychuk](http://twitter.com/tjholowaychuk) on twitter for updates + * [Google Group](http://groups.google.com/group/express-js) for discussion + * Visit the [Wiki](http://github.com/visionmedia/express/wiki) + * [日本語ドキュメンテーション](http://hideyukisaito.com/doc/expressjs/) by [hideyukisaito](https://github.com/hideyukisaito) + * Screencast - [Introduction](http://bit.ly/eRYu0O) + * Screencast - [View Partials](http://bit.ly/dU13Fx) + * Screencast - [Route Specific Middleware](http://bit.ly/hX4IaH) + * Screencast - [Route Path Placeholder Preconditions](http://bit.ly/eNqmVs) + +## Node Compatibility + +Express 1.x is compatible with node 0.2.x and connect < 1.0. + +Express 2.x is compatible with node 0.4.x or 0.6.x, and connect 1.x + +Express 3.x (master) will be compatible with node 0.6.x and connect 2.x + +## Viewing Examples + +First install the dev dependencies to install all the example / test suite deps: + + $ npm install + +then run whichever tests you want: + + $ node examples/jade/app.js + +## Running Tests + +To run the test suite first invoke the following command within the repo, installing the development dependencies: + + $ npm install + +then run the tests: + + $ make test + +## License + +(The MIT License) + +Copyright (c) 2009-2011 TJ Holowaychuk <tj@vision-media.ca> + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/express/bin/express b/node_modules/express/bin/express new file mode 100755 index 0000000..eebb724 --- /dev/null +++ b/node_modules/express/bin/express @@ -0,0 +1,428 @@ +#!/usr/bin/env node + +/** + * Module dependencies. + */ + +var fs = require('fs') + , exec = require('child_process').exec + , mkdirp = require('mkdirp'); + +/** + * Framework version. + */ + +var version = '2.5.1'; + +/** + * Add session support. + */ + +var sessions = false; + +/** + * CSS engine to utilize. + */ + +var cssEngine; + +/** + * Template engine to utilize. + */ + +var templateEngine = 'jade'; + +/** + * Usage documentation. + */ + +var usage = '' + + '\n' + + ' Usage: express [options] [path]\n' + + '\n' + + ' Options:\n' + + ' -s, --sessions add session support\n' + + ' -t, --template add template support (jade|ejs). default=jade\n' + + ' -c, --css add stylesheet support (less|stylus). default=plain css\n' + + ' -v, --version output framework version\n' + + ' -h, --help output help information\n' + ; + +/** + * Routes index template. + */ + +var index = [ + '' + , '/*' + , ' * GET home page.' + , ' */' + , '' + , 'exports.index = function(req, res){' + , ' res.render(\'index\', { title: \'Express\' })' + , '};' +].join('\n'); + +/** + * Jade layout template. + */ + +var jadeLayout = [ + '!!!' + , 'html' + , ' head' + , ' title= title' + , ' link(rel=\'stylesheet\', href=\'/stylesheets/style.css\')' + , ' body!= body' +].join('\n'); + +/** + * Jade index template. + */ + +var jadeIndex = [ + 'h1= title' + , 'p Welcome to #{title}' +].join('\n'); + +/** + * EJS layout template. + */ + +var ejsLayout = [ + '' + , '' + , ' ' + , ' <%= title %>' + , ' ' + , ' ' + , ' ' + , ' <%- body %>' + , ' ' + , '' +].join('\n'); + +/** + * EJS index template. + */ + +var ejsIndex = [ + '

<%= title %>

' + , '

Welcome to <%= title %>

' + ].join('\n'); + +/** + * Default css template. + */ + +var css = [ + 'body {' + , ' padding: 50px;' + , ' font: 14px "Lucida Grande", Helvetica, Arial, sans-serif;' + , '}' + , '' + , 'a {' + , ' color: #00B7FF;' + , '}' +].join('\n'); + +/** + * Default less template. + */ + +var less = [ + 'body {' + , ' padding: 50px;' + , ' font: 14px "Lucida Grande", Helvetica, Arial, sans-serif;' + , '}' + , '' + , 'a {' + , ' color: #00B7FF;' + , '}' +].join('\n'); + +/** + * Default stylus template. + */ + +var stylus = [ + 'body' + , ' padding: 50px' + , ' font: 14px "Lucida Grande", Helvetica, Arial, sans-serif' + , 'a' + , ' color: #00B7FF' +].join('\n'); + +/** + * App template. + */ + +var app = [ + '' + , '/**' + , ' * Module dependencies.' + , ' */' + , '' + , 'var express = require(\'express\')' + , ' , routes = require(\'./routes\')' + , '' + , 'var app = module.exports = express.createServer();' + , '' + , '// Configuration' + , '' + , 'app.configure(function(){' + , ' app.set(\'views\', __dirname + \'/views\');' + , ' app.set(\'view engine\', \':TEMPLATE\');' + , ' app.use(express.bodyParser());' + , ' app.use(express.methodOverride());{sess}{css}' + , ' app.use(app.router);' + , ' app.use(express.static(__dirname + \'/public\'));' + , '});' + , '' + , 'app.configure(\'development\', function(){' + , ' app.use(express.errorHandler({ dumpExceptions: true, showStack: true })); ' + , '});' + , '' + , 'app.configure(\'production\', function(){' + , ' app.use(express.errorHandler()); ' + , '});' + , '' + , '// Routes' + , '' + , 'app.get(\'/\', routes.index);' + , '' + , 'app.listen(3000);' + , 'console.log("Express server listening on port %d in %s mode", app.address().port, app.settings.env);' + , '' +].join('\n'); + +// Parse arguments + +var args = process.argv.slice(2) + , path = '.'; + +while (args.length) { + var arg = args.shift(); + switch (arg) { + case '-h': + case '--help': + abort(usage); + break; + case '-v': + case '--version': + abort(version); + break; + case '-s': + case '--session': + case '--sessions': + sessions = true; + break; + case '-c': + case '--css': + args.length + ? (cssEngine = args.shift()) + : abort('--css requires an argument'); + break; + case '-t': + case '--template': + args.length + ? (templateEngine = args.shift()) + : abort('--template requires an argument'); + break; + default: + path = arg; + } +} + +// Generate application + +(function createApplication(path) { + emptyDirectory(path, function(empty){ + if (empty) { + createApplicationAt(path); + } else { + confirm('destination is not empty, continue? ', function(ok){ + if (ok) { + process.stdin.destroy(); + createApplicationAt(path); + } else { + abort('aborting'); + } + }); + } + }); +})(path); + +/** + * Create application at the given directory `path`. + * + * @param {String} path + */ + +function createApplicationAt(path) { + console.log(); + process.on('exit', function(){ + console.log(); + console.log(' dont forget to install dependencies:'); + console.log(' $ cd %s && npm install', path); + console.log(); + }); + + mkdir(path, function(){ + mkdir(path + '/public'); + mkdir(path + '/public/javascripts'); + mkdir(path + '/public/images'); + mkdir(path + '/public/stylesheets', function(){ + switch (cssEngine) { + case 'stylus': + write(path + '/public/stylesheets/style.styl', stylus); + break; + case 'less': + write(path + '/public/stylesheets/style.less', less); + break; + default: + write(path + '/public/stylesheets/style.css', css); + } + }); + + mkdir(path + '/routes', function(){ + write(path + '/routes/index.js', index); + }); + + mkdir(path + '/views', function(){ + switch (templateEngine) { + case 'ejs': + write(path + '/views/layout.ejs', ejsLayout); + write(path + '/views/index.ejs', ejsIndex); + break; + case 'jade': + write(path + '/views/layout.jade', jadeLayout); + write(path + '/views/index.jade', jadeIndex); + break; + } + }); + + // CSS Engine support + switch (cssEngine) { + case 'less': + app = app.replace('{css}', '\n app.use(express.compiler({ src: __dirname + \'/public\', enable: [\'' + cssEngine + '\'] }));'); + break; + case 'stylus': + app = app.replace('{css}', '\n app.use(require(\'stylus\').middleware({ src: __dirname + \'/public\' }));'); + break; + default: + app = app.replace('{css}', ''); + } + + // Session support + app = app.replace('{sess}', sessions + ? '\n app.use(express.cookieParser());\n app.use(express.session({ secret: \'your secret here\' }));' + : ''); + + // Template support + app = app.replace(':TEMPLATE', templateEngine); + + // package.json + var json = '{\n'; + json += ' "name": "application-name"\n'; + json += ' , "version": "0.0.1"\n'; + json += ' , "private": true\n'; + json += ' , "dependencies": {\n'; + json += ' "express": "' + version + '"\n'; + if (cssEngine) json += ' , "' + cssEngine + '": ">= 0.0.1"\n'; + if (templateEngine) json += ' , "' + templateEngine + '": ">= 0.0.1"\n'; + json += ' }\n'; + json += '}'; + + + write(path + '/package.json', json); + write(path + '/app.js', app); + }); +} + +/** + * Check if the given directory `path` is empty. + * + * @param {String} path + * @param {Function} fn + */ + +function emptyDirectory(path, fn) { + fs.readdir(path, function(err, files){ + if (err && 'ENOENT' != err.code) throw err; + fn(!files || !files.length); + }); +} + +/** + * echo str > path. + * + * @param {String} path + * @param {String} str + */ + +function write(path, str) { + fs.writeFile(path, str); + console.log(' \x1b[36mcreate\x1b[0m : ' + path); +} + +/** + * Prompt confirmation with the given `msg`. + * + * @param {String} msg + * @param {Function} fn + */ + +function confirm(msg, fn) { + prompt(msg, function(val){ + fn(/^ *y(es)?/i.test(val)); + }); +} + +/** + * Prompt input with the given `msg` and callback `fn`. + * + * @param {String} msg + * @param {Function} fn + */ + +function prompt(msg, fn) { + // prompt + if (' ' == msg[msg.length - 1]) { + process.stdout.write(msg); + } else { + console.log(msg); + } + + // stdin + process.stdin.setEncoding('ascii'); + process.stdin.once('data', function(data){ + fn(data); + }).resume(); +} + +/** + * Mkdir -p. + * + * @param {String} path + * @param {Function} fn + */ + +function mkdir(path, fn) { + mkdirp(path, 0755, function(err){ + if (err) throw err; + console.log(' \033[36mcreate\033[0m : ' + path); + fn && fn(); + }); +} + +/** + * Exit with the given `str`. + * + * @param {String} str + */ + +function abort(str) { + console.error(str); + process.exit(1); +} diff --git a/node_modules/express/index.js b/node_modules/express/index.js new file mode 100644 index 0000000..8d81ea7 --- /dev/null +++ b/node_modules/express/index.js @@ -0,0 +1,2 @@ + +module.exports = require('./lib/express'); \ No newline at end of file diff --git a/node_modules/express/lib/express.js b/node_modules/express/lib/express.js new file mode 100644 index 0000000..072a010 --- /dev/null +++ b/node_modules/express/lib/express.js @@ -0,0 +1,79 @@ + +/*! + * Express + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var connect = require('connect') + , HTTPSServer = require('./https') + , HTTPServer = require('./http') + , Route = require('./router/route') + +/** + * Re-export connect auto-loaders. + * + * This prevents the need to `require('connect')` in order + * to access core middleware, so for example `express.logger()` instead + * of `require('connect').logger()`. + */ + +var exports = module.exports = connect.middleware; + +/** + * Framework version. + */ + +exports.version = '2.5.1'; + +/** + * Shortcut for `new Server(...)`. + * + * @param {Function} ... + * @return {Server} + * @api public + */ + +exports.createServer = function(options){ + if ('object' == typeof options) { + return new HTTPSServer(options, Array.prototype.slice.call(arguments, 1)); + } else { + return new HTTPServer(Array.prototype.slice.call(arguments)); + } +}; + +/** + * Expose constructors. + */ + +exports.HTTPServer = HTTPServer; +exports.HTTPSServer = HTTPSServer; +exports.Route = Route; + +/** + * View extensions. + */ + +exports.View = +exports.view = require('./view'); + +/** + * Response extensions. + */ + +require('./response'); + +/** + * Request extensions. + */ + +require('./request'); + +// Error handler title + +exports.errorHandler.title = 'Express'; + diff --git a/node_modules/express/lib/http.js b/node_modules/express/lib/http.js new file mode 100644 index 0000000..4256dc4 --- /dev/null +++ b/node_modules/express/lib/http.js @@ -0,0 +1,583 @@ + +/*! + * Express - HTTPServer + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var qs = require('qs') + , connect = require('connect') + , router = require('./router') + , Router = require('./router') + , view = require('./view') + , toArray = require('./utils').toArray + , methods = router.methods.concat('del', 'all') + , url = require('url') + , utils = connect.utils; + +/** + * Expose `HTTPServer`. + */ + +exports = module.exports = HTTPServer; + +/** + * Server proto. + */ + +var app = HTTPServer.prototype; + +/** + * Initialize a new `HTTPServer` with optional `middleware`. + * + * @param {Array} middleware + * @api public + */ + +function HTTPServer(middleware){ + connect.HTTPServer.call(this, []); + this.init(middleware); +}; + +/** + * Inherit from `connect.HTTPServer`. + */ + +app.__proto__ = connect.HTTPServer.prototype; + +/** + * Initialize the server. + * + * @param {Array} middleware + * @api private + */ + +app.init = function(middleware){ + var self = this; + this.cache = {}; + this.settings = {}; + this.redirects = {}; + this.isCallbacks = {}; + this._locals = {}; + this.dynamicViewHelpers = {}; + this.errorHandlers = []; + + this.set('env', process.env.NODE_ENV || 'development'); + + // expose objects to each other + this.use(function(req, res, next){ + req.query = req.query || {}; + res.setHeader('X-Powered-By', 'Express'); + req.app = res.app = self; + req.res = res; + res.req = req; + req.next = next; + // assign req.query + if (req.url.indexOf('?') > 0) { + var query = url.parse(req.url).query; + req.query = qs.parse(query); + } + next(); + }); + + // apply middleware + if (middleware) middleware.forEach(self.use.bind(self)); + + // router + this.routes = new Router(this); + this.__defineGetter__('router', function(){ + this.__usedRouter = true; + return self.routes.middleware; + }); + + // default locals + this.locals({ + settings: this.settings + , app: this + }); + + // default development configuration + this.configure('development', function(){ + this.enable('hints'); + }); + + // default production configuration + this.configure('production', function(){ + this.enable('view cache'); + }); + + // register error handlers on "listening" + // so that they disregard definition position. + this.on('listening', this.registerErrorHandlers.bind(this)); + + // route manipulation methods + methods.forEach(function(method){ + self.lookup[method] = function(path){ + return self.routes.lookup(method, path); + }; + + self.match[method] = function(path){ + return self.routes.match(method, path); + }; + + self.remove[method] = function(path){ + return self.routes.lookup(method, path).remove(); + }; + }); + + // del -> delete + self.lookup.del = self.lookup.delete; + self.match.del = self.match.delete; + self.remove.del = self.remove.delete; +}; + +/** + * Remove routes matching the given `path`. + * + * @param {Route} path + * @return {Boolean} + * @api public + */ + +app.remove = function(path){ + return this.routes.lookup('all', path).remove(); +}; + +/** + * Lookup routes defined with a path + * equivalent to `path`. + * + * @param {Stirng} path + * @return {Array} + * @api public + */ + +app.lookup = function(path){ + return this.routes.lookup('all', path); +}; + +/** + * Lookup routes matching the given `url`. + * + * @param {Stirng} url + * @return {Array} + * @api public + */ + +app.match = function(url){ + return this.routes.match('all', url); +}; + +/** + * When using the vhost() middleware register error handlers. + */ + +app.onvhost = function(){ + this.registerErrorHandlers(); +}; + +/** + * Register error handlers. + * + * @return {Server} for chaining + * @api public + */ + +app.registerErrorHandlers = function(){ + this.errorHandlers.forEach(function(fn){ + this.use(function(err, req, res, next){ + fn.apply(this, arguments); + }); + }, this); + return this; +}; + +/** + * Proxy `connect.HTTPServer#use()` to apply settings to + * mounted applications. + * + * @param {String|Function|Server} route + * @param {Function|Server} middleware + * @return {Server} for chaining + * @api public + */ + +app.use = function(route, middleware){ + var app, base, handle; + + if ('string' != typeof route) { + middleware = route, route = '/'; + } + + // express app + if (middleware.handle && middleware.set) app = middleware; + + // restore .app property on req and res + if (app) { + app.route = route; + middleware = function(req, res, next) { + var orig = req.app; + app.handle(req, res, function(err){ + req.app = res.app = orig; + next(err); + }); + }; + } + + connect.HTTPServer.prototype.use.call(this, route, middleware); + + // mounted an app, invoke the hook + // and adjust some settings + if (app) { + base = this.set('basepath') || this.route; + if ('/' == base) base = ''; + base = base + (app.set('basepath') || app.route); + app.set('basepath', base); + app.parent = this; + if (app.__mounted) app.__mounted.call(app, this); + } + + return this; +}; + +/** + * Assign a callback `fn` which is called + * when this `Server` is passed to `Server#use()`. + * + * Examples: + * + * var app = express.createServer() + * , blog = express.createServer(); + * + * blog.mounted(function(parent){ + * // parent is app + * // "this" is blog + * }); + * + * app.use(blog); + * + * @param {Function} fn + * @return {Server} for chaining + * @api public + */ + +app.mounted = function(fn){ + this.__mounted = fn; + return this; +}; + +/** + * See: view.register. + * + * @return {Server} for chaining + * @api public + */ + +app.register = function(){ + view.register.apply(this, arguments); + return this; +}; + +/** + * Register the given view helpers `obj`. This method + * can be called several times to apply additional helpers. + * + * @param {Object} obj + * @return {Server} for chaining + * @api public + */ + +app.helpers = +app.locals = function(obj){ + utils.merge(this._locals, obj); + return this; +}; + +/** + * Register the given dynamic view helpers `obj`. This method + * can be called several times to apply additional helpers. + * + * @param {Object} obj + * @return {Server} for chaining + * @api public + */ + +app.dynamicHelpers = function(obj){ + utils.merge(this.dynamicViewHelpers, obj); + return this; +}; + +/** + * Map the given param placeholder `name`(s) to the given callback(s). + * + * Param mapping is used to provide pre-conditions to routes + * which us normalized placeholders. This callback has the same + * signature as regular middleware, for example below when ":userId" + * is used this function will be invoked in an attempt to load the user. + * + * app.param('userId', function(req, res, next, id){ + * User.find(id, function(err, user){ + * if (err) { + * next(err); + * } else if (user) { + * req.user = user; + * next(); + * } else { + * next(new Error('failed to load user')); + * } + * }); + * }); + * + * Passing a single function allows you to map logic + * to the values passed to `app.param()`, for example + * this is useful to provide coercion support in a concise manner. + * + * The following example maps regular expressions to param values + * ensuring that they match, otherwise passing control to the next + * route: + * + * app.param(function(name, regexp){ + * if (regexp instanceof RegExp) { + * return function(req, res, next, val){ + * var captures; + * if (captures = regexp.exec(String(val))) { + * req.params[name] = captures; + * next(); + * } else { + * next('route'); + * } + * } + * } + * }); + * + * We can now use it as shown below, where "/commit/:commit" expects + * that the value for ":commit" is at 5 or more digits. The capture + * groups are then available as `req.params.commit` as we defined + * in the function above. + * + * app.param('commit', /^\d{5,}$/); + * + * For more of this useful functionality take a look + * at [express-params](http://github.com/visionmedia/express-params). + * + * @param {String|Array|Function} name + * @param {Function} fn + * @return {Server} for chaining + * @api public + */ + +app.param = function(name, fn){ + var self = this + , fns = [].slice.call(arguments, 1); + + // array + if (Array.isArray(name)) { + name.forEach(function(name){ + fns.forEach(function(fn){ + self.param(name, fn); + }); + }); + // param logic + } else if ('function' == typeof name) { + this.routes.param(name); + // single + } else { + if (':' == name[0]) name = name.substr(1); + fns.forEach(function(fn){ + self.routes.param(name, fn); + }); + } + + return this; +}; + +/** + * Assign a custom exception handler callback `fn`. + * These handlers are always _last_ in the middleware stack. + * + * @param {Function} fn + * @return {Server} for chaining + * @api public + */ + +app.error = function(fn){ + this.errorHandlers.push(fn); + return this; +}; + +/** + * Register the given callback `fn` for the given `type`. + * + * @param {String} type + * @param {Function} fn + * @return {Server} for chaining + * @api public + */ + +app.is = function(type, fn){ + if (!fn) return this.isCallbacks[type]; + this.isCallbacks[type] = fn; + return this; +}; + +/** + * Assign `setting` to `val`, or return `setting`'s value. + * Mounted servers inherit their parent server's settings. + * + * @param {String} setting + * @param {String} val + * @return {Server|Mixed} for chaining, or the setting value + * @api public + */ + +app.set = function(setting, val){ + if (val === undefined) { + if (this.settings.hasOwnProperty(setting)) { + return this.settings[setting]; + } else if (this.parent) { + return this.parent.set(setting); + } + } else { + this.settings[setting] = val; + return this; + } +}; + +/** + * Check if `setting` is enabled. + * + * @param {String} setting + * @return {Boolean} + * @api public + */ + +app.enabled = function(setting){ + return !!this.set(setting); +}; + +/** + * Check if `setting` is disabled. + * + * @param {String} setting + * @return {Boolean} + * @api public + */ + +app.disabled = function(setting){ + return !this.set(setting); +}; + +/** + * Enable `setting`. + * + * @param {String} setting + * @return {Server} for chaining + * @api public + */ + +app.enable = function(setting){ + return this.set(setting, true); +}; + +/** + * Disable `setting`. + * + * @param {String} setting + * @return {Server} for chaining + * @api public + */ + +app.disable = function(setting){ + return this.set(setting, false); +}; + +/** + * Redirect `key` to `url`. + * + * @param {String} key + * @param {String} url + * @return {Server} for chaining + * @api public + */ + +app.redirect = function(key, url){ + this.redirects[key] = url; + return this; +}; + +/** + * Configure callback for zero or more envs, + * when no env is specified that callback will + * be invoked for all environments. Any combination + * can be used multiple times, in any order desired. + * + * Examples: + * + * app.configure(function(){ + * // executed for all envs + * }); + * + * app.configure('stage', function(){ + * // executed staging env + * }); + * + * app.configure('stage', 'production', function(){ + * // executed for stage and production + * }); + * + * @param {String} env... + * @param {Function} fn + * @return {Server} for chaining + * @api public + */ + +app.configure = function(env, fn){ + var envs = 'all' + , args = toArray(arguments); + fn = args.pop(); + if (args.length) envs = args; + if ('all' == envs || ~envs.indexOf(this.settings.env)) fn.call(this); + return this; +}; + +/** + * Delegate `.VERB(...)` calls to `.route(VERB, ...)`. + */ + +methods.forEach(function(method){ + app[method] = function(path){ + if (1 == arguments.length) return this.routes.lookup(method, path); + var args = [method].concat(toArray(arguments)); + if (!this.__usedRouter) this.use(this.router); + return this.routes._route.apply(this.routes, args); + } +}); + +/** + * Special-cased "all" method, applying the given route `path`, + * middleware, and callback to _every_ HTTP method. + * + * @param {String} path + * @param {Function} ... + * @return {Server} for chaining + * @api public + */ + +app.all = function(path){ + var args = arguments; + if (1 == args.length) return this.routes.lookup('all', path); + methods.forEach(function(method){ + if ('all' == method) return; + app[method].apply(this, args); + }, this); + return this; +}; + +// del -> delete alias + +app.del = app.delete; + diff --git a/node_modules/express/lib/https.js b/node_modules/express/lib/https.js new file mode 100644 index 0000000..8a8c008 --- /dev/null +++ b/node_modules/express/lib/https.js @@ -0,0 +1,52 @@ + +/*! + * Express - HTTPSServer + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var connect = require('connect') + , HTTPServer = require('./http') + , https = require('https'); + +/** + * Expose `HTTPSServer`. + */ + +exports = module.exports = HTTPSServer; + +/** + * Server proto. + */ + +var app = HTTPSServer.prototype; + +/** + * Initialize a new `HTTPSServer` with the + * given `options`, and optional `middleware`. + * + * @param {Object} options + * @param {Array} middleware + * @api public + */ + +function HTTPSServer(options, middleware){ + connect.HTTPSServer.call(this, options, []); + this.init(middleware); +}; + +/** + * Inherit from `connect.HTTPSServer`. + */ + +app.__proto__ = connect.HTTPSServer.prototype; + +// mixin HTTPServer methods + +Object.keys(HTTPServer.prototype).forEach(function(method){ + app[method] = HTTPServer.prototype[method]; +}); diff --git a/node_modules/express/lib/request.js b/node_modules/express/lib/request.js new file mode 100644 index 0000000..bc95eae --- /dev/null +++ b/node_modules/express/lib/request.js @@ -0,0 +1,321 @@ + +/*! + * Express - request + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var http = require('http') + , req = http.IncomingMessage.prototype + , utils = require('./utils') + , parse = require('url').parse + , mime = require('mime'); + +/** + * Default flash formatters. + * + * @type Object + */ + +var flashFormatters = exports.flashFormatters = { + s: function(val){ + return String(val); + } +}; + +/** + * Return request header or optional default. + * + * The `Referrer` header field is special-cased, + * both `Referrer` and `Referer` will yield are + * interchangeable. + * + * Examples: + * + * req.header('Content-Type'); + * // => "text/plain" + * + * req.header('content-type'); + * // => "text/plain" + * + * req.header('Accept'); + * // => undefined + * + * req.header('Accept', 'text/html'); + * // => "text/html" + * + * @param {String} name + * @param {String} defaultValue + * @return {String} + * @api public + */ + +req.header = function(name, defaultValue){ + switch (name = name.toLowerCase()) { + case 'referer': + case 'referrer': + return this.headers.referrer + || this.headers.referer + || defaultValue; + default: + return this.headers[name] || defaultValue; + } +}; + +/** + * Get `field`'s `param` value, defaulting to ''. + * + * Examples: + * + * req.get('content-disposition', 'filename'); + * // => "something.png" + * + * @param {String} field + * @param {String} param + * @return {String} + * @api public + */ + +req.get = function(field, param){ + var val = this.header(field); + if (!val) return ''; + var regexp = new RegExp(param + ' *= *(?:"([^"]+)"|([^;]+))', 'i'); + if (!regexp.exec(val)) return ''; + return RegExp.$1 || RegExp.$2; +}; + +/** + * Short-hand for `require('url').parse(req.url).pathname`. + * + * @return {String} + * @api public + */ + +req.__defineGetter__('path', function(){ + return parse(this.url).pathname; +}); + +/** + * Check if the _Accept_ header is present, and includes the given `type`. + * + * When the _Accept_ header is not present `true` is returned. Otherwise + * the given `type` is matched by an exact match, and then subtypes. You + * may pass the subtype such as "html" which is then converted internally + * to "text/html" using the mime lookup table. + * + * Examples: + * + * // Accept: text/html + * req.accepts('html'); + * // => true + * + * // Accept: text/*; application/json + * req.accepts('html'); + * req.accepts('text/html'); + * req.accepts('text/plain'); + * req.accepts('application/json'); + * // => true + * + * req.accepts('image/png'); + * req.accepts('png'); + * // => false + * + * @param {String} type + * @return {Boolean} + * @api public + */ + +req.accepts = function(type){ + var accept = this.header('Accept'); + + // normalize extensions ".json" -> "json" + if (type && '.' == type[0]) type = type.substr(1); + + // when Accept does not exist, or is '*/*' return true + if (!accept || '*/*' == accept) { + return true; + } else if (type) { + // allow "html" vs "text/html" etc + if (!~type.indexOf('/')) type = mime.lookup(type); + + // check if we have a direct match + if (~accept.indexOf(type)) return true; + + // check if we have type/* + type = type.split('/')[0] + '/*'; + return !!~accept.indexOf(type); + } else { + return false; + } +}; + +/** + * Return the value of param `name` when present or `defaultValue`. + * + * - Checks route placeholders, ex: _/user/:id_ + * - Checks query string params, ex: ?id=12 + * - Checks urlencoded body params, ex: id=12 + * + * To utilize urlencoded request bodies, `req.body` + * should be an object. This can be done by using + * the `connect.bodyParser` middleware. + * + * @param {String} name + * @param {Mixed} defaultValue + * @return {String} + * @api public + */ + +req.param = function(name, defaultValue){ + // route params like /user/:id + if (this.params && this.params.hasOwnProperty(name) && undefined !== this.params[name]) { + return this.params[name]; + } + // query string params + if (undefined !== this.query[name]) { + return this.query[name]; + } + // request body params via connect.bodyParser + if (this.body && undefined !== this.body[name]) { + return this.body[name]; + } + return defaultValue; +}; + +/** + * Queue flash `msg` of the given `type`. + * + * Examples: + * + * req.flash('info', 'email sent'); + * req.flash('error', 'email delivery failed'); + * req.flash('info', 'email re-sent'); + * // => 2 + * + * req.flash('info'); + * // => ['email sent', 'email re-sent'] + * + * req.flash('info'); + * // => [] + * + * req.flash(); + * // => { error: ['email delivery failed'], info: [] } + * + * Formatting: + * + * Flash notifications also support arbitrary formatting support. + * For example you may pass variable arguments to `req.flash()` + * and use the %s specifier to be replaced by the associated argument: + * + * req.flash('info', 'email has been sent to %s.', userName); + * + * To add custom formatters use the `exports.flashFormatters` object. + * + * @param {String} type + * @param {String} msg + * @return {Array|Object|Number} + * @api public + */ + +req.flash = function(type, msg){ + if (this.session === undefined) throw Error('req.flash() requires sessions'); + var msgs = this.session.flash = this.session.flash || {}; + if (type && msg) { + var i = 2 + , args = arguments + , formatters = this.app.flashFormatters || {}; + formatters.__proto__ = flashFormatters; + msg = utils.miniMarkdown(msg); + msg = msg.replace(/%([a-zA-Z])/g, function(_, format){ + var formatter = formatters[format]; + if (formatter) return formatter(utils.escape(args[i++])); + }); + return (msgs[type] = msgs[type] || []).push(msg); + } else if (type) { + var arr = msgs[type]; + delete msgs[type]; + return arr || []; + } else { + this.session.flash = {}; + return msgs; + } +}; + +/** + * Check if the incoming request contains the "Content-Type" + * header field, and it contains the give mime `type`. + * + * Examples: + * + * // With Content-Type: text/html; charset=utf-8 + * req.is('html'); + * req.is('text/html'); + * // => true + * + * // When Content-Type is application/json + * req.is('json'); + * req.is('application/json'); + * // => true + * + * req.is('html'); + * // => false + * + * Ad-hoc callbacks can also be registered with Express, to perform + * assertions again the request, for example if we need an expressive + * way to check if our incoming request is an image, we can register "an image" + * callback: + * + * app.is('an image', function(req){ + * return 0 == req.headers['content-type'].indexOf('image'); + * }); + * + * Now within our route callbacks, we can use to to assert content types + * such as "image/jpeg", "image/png", etc. + * + * app.post('/image/upload', function(req, res, next){ + * if (req.is('an image')) { + * // do something + * } else { + * next(); + * } + * }); + * + * @param {String} type + * @return {Boolean} + * @api public + */ + +req.is = function(type){ + var fn = this.app.is(type); + if (fn) return fn(this); + var contentType = this.headers['content-type']; + if (!contentType) return; + if (!~type.indexOf('/')) type = mime.lookup(type); + if (~type.indexOf('*')) { + type = type.split('/') + contentType = contentType.split('/'); + if ('*' == type[0] && type[1] == contentType[1]) return true; + if ('*' == type[1] && type[0] == contentType[0]) return true; + } + return !! ~contentType.indexOf(type); +}; + +// Callback for isXMLHttpRequest / xhr + +function isxhr() { + return this.header('X-Requested-With', '').toLowerCase() === 'xmlhttprequest'; +} + +/** + * Check if the request was an _XMLHttpRequest_. + * + * @return {Boolean} + * @api public + */ + +req.__defineGetter__('isXMLHttpRequest', isxhr); +req.__defineGetter__('xhr', isxhr); diff --git a/node_modules/express/lib/response.js b/node_modules/express/lib/response.js new file mode 100644 index 0000000..a671771 --- /dev/null +++ b/node_modules/express/lib/response.js @@ -0,0 +1,460 @@ + +/*! + * Express - response + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var fs = require('fs') + , http = require('http') + , path = require('path') + , connect = require('connect') + , utils = connect.utils + , parseRange = require('./utils').parseRange + , res = http.ServerResponse.prototype + , send = connect.static.send + , mime = require('mime') + , basename = path.basename + , join = path.join; + +/** + * Send a response with the given `body` and optional `headers` and `status` code. + * + * Examples: + * + * res.send(); + * res.send(new Buffer('wahoo')); + * res.send({ some: 'json' }); + * res.send('

some html

'); + * res.send('Sorry, cant find that', 404); + * res.send('text', { 'Content-Type': 'text/plain' }, 201); + * res.send(404); + * + * @param {String|Object|Number|Buffer} body or status + * @param {Object|Number} headers or status + * @param {Number} status + * @return {ServerResponse} + * @api public + */ + +res.send = function(body, headers, status){ + // allow status as second arg + if ('number' == typeof headers) { + status = headers, + headers = null; + } + + // default status + status = status || this.statusCode; + + // allow 0 args as 204 + if (!arguments.length || undefined === body) status = 204; + + // determine content type + switch (typeof body) { + case 'number': + if (!this.header('Content-Type')) { + this.contentType('.txt'); + } + body = http.STATUS_CODES[status = body]; + break; + case 'string': + if (!this.header('Content-Type')) { + this.charset = this.charset || 'utf-8'; + this.contentType('.html'); + } + break; + case 'boolean': + case 'object': + if (Buffer.isBuffer(body)) { + if (!this.header('Content-Type')) { + this.contentType('.bin'); + } + } else { + return this.json(body, headers, status); + } + break; + } + + // populate Content-Length + if (undefined !== body && !this.header('Content-Length')) { + this.header('Content-Length', Buffer.isBuffer(body) + ? body.length + : Buffer.byteLength(body)); + } + + // merge headers passed + if (headers) { + var fields = Object.keys(headers); + for (var i = 0, len = fields.length; i < len; ++i) { + var field = fields[i]; + this.header(field, headers[field]); + } + } + + // strip irrelevant headers + if (204 == status || 304 == status) { + this.removeHeader('Content-Type'); + this.removeHeader('Content-Length'); + body = ''; + } + + // respond + this.statusCode = status; + this.end('HEAD' == this.req.method ? null : body); + return this; +}; + +/** + * Send JSON response with `obj`, optional `headers`, and optional `status`. + * + * Examples: + * + * res.json(null); + * res.json({ user: 'tj' }); + * res.json('oh noes!', 500); + * res.json('I dont have that', 404); + * + * @param {Mixed} obj + * @param {Object|Number} headers or status + * @param {Number} status + * @return {ServerResponse} + * @api public + */ + +res.json = function(obj, headers, status){ + var body = JSON.stringify(obj) + , callback = this.req.query.callback + , jsonp = this.app.enabled('jsonp callback'); + + this.charset = this.charset || 'utf-8'; + this.header('Content-Type', 'application/json'); + + if (callback && jsonp) { + this.header('Content-Type', 'text/javascript'); + body = callback.replace(/[^\w$.]/g, '') + '(' + body + ');'; + } + + return this.send(body, headers, status); +}; + +/** + * Set status `code`. + * + * @param {Number} code + * @return {ServerResponse} + * @api public + */ + +res.status = function(code){ + this.statusCode = code; + return this; +}; + +/** + * Transfer the file at the given `path`. Automatically sets + * the _Content-Type_ response header field. `next()` is called + * when `path` is a directory, or when an error occurs. + * + * Options: + * + * - `maxAge` defaulting to 0 + * - `root` root directory for relative filenames + * + * @param {String} path + * @param {Object|Function} options or fn + * @param {Function} fn + * @api public + */ + +res.sendfile = function(path, options, fn){ + var next = this.req.next; + options = options || {}; + + // support function as second arg + if ('function' == typeof options) { + fn = options; + options = {}; + } + + options.path = encodeURIComponent(path); + options.callback = fn; + send(this.req, this, next, options); +}; + +/** + * Set _Content-Type_ response header passed through `mime.lookup()`. + * + * Examples: + * + * var filename = 'path/to/image.png'; + * res.contentType(filename); + * // res.headers['Content-Type'] is now "image/png" + * + * res.contentType('.html'); + * res.contentType('html'); + * res.contentType('json'); + * res.contentType('png'); + * + * @param {String} type + * @return {String} the resolved mime type + * @api public + */ + +res.contentType = function(type){ + return this.header('Content-Type', mime.lookup(type)); +}; + +/** + * Set _Content-Disposition_ header to _attachment_ with optional `filename`. + * + * @param {String} filename + * @return {ServerResponse} + * @api public + */ + +res.attachment = function(filename){ + if (filename) this.contentType(filename); + this.header('Content-Disposition', filename + ? 'attachment; filename="' + basename(filename) + '"' + : 'attachment'); + return this; +}; + +/** + * Transfer the file at the given `path`, with optional + * `filename` as an attachment and optional callback `fn(err)`, + * and optional `fn2(err)` which is invoked when an error has + * occurred after header has been sent. + * + * @param {String} path + * @param {String|Function} filename or fn + * @param {Function} fn + * @param {Function} fn2 + * @api public + */ + +res.download = function(path, filename, fn, fn2){ + var self = this; + + // support callback as second arg + if ('function' == typeof filename) { + fn2 = fn; + fn = filename; + filename = null; + } + + // transfer the file + this.attachment(filename || path).sendfile(path, function(err){ + var sentHeader = self._header; + if (err) { + if (!sentHeader) self.removeHeader('Content-Disposition'); + if (sentHeader) { + fn2 && fn2(err); + } else if (fn) { + fn(err); + } else { + self.req.next(err); + } + } else if (fn) { + fn(); + } + }); +}; + +/** + * Set or get response header `name` with optional `val`. + * + * @param {String} name + * @param {String} val + * @return {ServerResponse} for chaining + * @api public + */ + +res.header = function(name, val){ + if (1 == arguments.length) return this.getHeader(name); + this.setHeader(name, val); + return this; +}; + +/** + * Clear cookie `name`. + * + * @param {String} name + * @param {Object} options + * @api public + */ + +res.clearCookie = function(name, options){ + var opts = { expires: new Date(1) }; + this.cookie(name, '', options + ? utils.merge(options, opts) + : opts); +}; + +/** + * Set cookie `name` to `val`, with the given `options`. + * + * Options: + * + * - `maxAge` max-age in milliseconds, converted to `expires` + * - `path` defaults to the "basepath" setting which is typically "/" + * + * Examples: + * + * // "Remember Me" for 15 minutes + * res.cookie('rememberme', '1', { expires: new Date(Date.now() + 900000), httpOnly: true }); + * + * // save as above + * res.cookie('rememberme', '1', { maxAge: 900000, httpOnly: true }) + * + * @param {String} name + * @param {String} val + * @param {Options} options + * @api public + */ + +res.cookie = function(name, val, options){ + options = options || {}; + if ('maxAge' in options) options.expires = new Date(Date.now() + options.maxAge); + if (undefined === options.path) options.path = this.app.set('basepath'); + var cookie = utils.serializeCookie(name, val, options); + this.header('Set-Cookie', cookie); +}; + +/** + * Redirect to the given `url` with optional response `status` + * defauling to 302. + * + * The given `url` can also be the name of a mapped url, for + * example by default express supports "back" which redirects + * to the _Referrer_ or _Referer_ headers or the application's + * "basepath" setting. Express also supports "basepath" out of the box, + * which can be set via `app.set('basepath', '/blog');`, and defaults + * to '/'. + * + * Redirect Mapping: + * + * To extend the redirect mapping capabilities that Express provides, + * we may use the `app.redirect()` method: + * + * app.redirect('google', 'http://google.com'); + * + * Now in a route we may call: + * + * res.redirect('google'); + * + * We may also map dynamic redirects: + * + * app.redirect('comments', function(req, res){ + * return '/post/' + req.params.id + '/comments'; + * }); + * + * So now we may do the following, and the redirect will dynamically adjust to + * the context of the request. If we called this route with _GET /post/12_ our + * redirect _Location_ would be _/post/12/comments_. + * + * app.get('/post/:id', function(req, res){ + * res.redirect('comments'); + * }); + * + * Unless an absolute `url` is given, the app's mount-point + * will be respected. For example if we redirect to `/posts`, + * and our app is mounted at `/blog` we will redirect to `/blog/posts`. + * + * @param {String} url + * @param {Number} code + * @api public + */ + +res.redirect = function(url, status){ + var app = this.app + , req = this.req + , base = app.set('basepath') || app.route + , status = status || 302 + , head = 'HEAD' == req.method + , body; + + // Setup redirect map + var map = { + back: req.header('Referrer', base) + , home: base + }; + + // Support custom redirect map + map.__proto__ = app.redirects; + + // Attempt mapped redirect + var mapped = 'function' == typeof map[url] + ? map[url](req, this) + : map[url]; + + // Perform redirect + url = mapped || url; + + // Relative + if (!~url.indexOf('://')) { + // Respect mount-point + if ('/' != base && 0 != url.indexOf(base)) url = base + url; + + // Absolute + var host = req.headers.host + , tls = req.connection.encrypted; + url = 'http' + (tls ? 's' : '') + '://' + host + url; + } + + // Support text/{plain,html} by default + if (req.accepts('html')) { + body = '

' + http.STATUS_CODES[status] + '. Redirecting to ' + url + '

'; + this.header('Content-Type', 'text/html'); + } else { + body = http.STATUS_CODES[status] + '. Redirecting to ' + url; + this.header('Content-Type', 'text/plain'); + } + + // Respond + this.statusCode = status; + this.header('Location', url); + this.end(head ? null : body); +}; + +/** + * Assign the view local variable `name` to `val` or return the + * local previously assigned to `name`. + * + * @param {String} name + * @param {Mixed} val + * @return {Mixed} val + * @api public + */ + +res.local = function(name, val){ + this._locals = this._locals || {}; + return undefined === val + ? this._locals[name] + : this._locals[name] = val; +}; + +/** + * Assign several locals with the given `obj`, + * or return the locals. + * + * @param {Object} obj + * @return {Object|Undefined} + * @api public + */ + +res.locals = +res.helpers = function(obj){ + if (obj) { + for (var key in obj) { + this.local(key, obj[key]); + } + } else { + return this._locals; + } +}; diff --git a/node_modules/express/lib/router/collection.js b/node_modules/express/lib/router/collection.js new file mode 100644 index 0000000..991a9a2 --- /dev/null +++ b/node_modules/express/lib/router/collection.js @@ -0,0 +1,53 @@ + +/*! + * Express - router - Collection + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Expose `Collection`. + */ + +module.exports = Collection; + +/** + * Initialize a new route `Collection` + * with the given `router`. + * + * @param {Router} router + * @api private + */ + +function Collection(router) { + Array.apply(this, arguments); + this.router = router; +} + +/** + * Inherit from `Array.prototype`. + */ + +Collection.prototype.__proto__ = Array.prototype; + +/** + * Remove the routes in this collection. + * + * @return {Collection} of routes removed + * @api public + */ + +Collection.prototype.remove = function(){ + var router = this.router + , len = this.length + , ret = new Collection(this.router); + + for (var i = 0; i < len; ++i) { + if (router.remove(this[i])) { + ret.push(this[i]); + } + } + + return ret; +}; + diff --git a/node_modules/express/lib/router/index.js b/node_modules/express/lib/router/index.js new file mode 100644 index 0000000..ff1498b --- /dev/null +++ b/node_modules/express/lib/router/index.js @@ -0,0 +1,398 @@ + +/*! + * Express - Router + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var Route = require('./route') + , Collection = require('./collection') + , utils = require('../utils') + , parse = require('url').parse + , toArray = utils.toArray; + +/** + * Expose `Router` constructor. + */ + +exports = module.exports = Router; + +/** + * Expose HTTP methods. + */ + +var methods = exports.methods = require('./methods'); + +/** + * Initialize a new `Router` with the given `app`. + * + * @param {express.HTTPServer} app + * @api private + */ + +function Router(app) { + var self = this; + this.app = app; + this.routes = {}; + this.params = {}; + this._params = []; + + this.middleware = function(req, res, next){ + self._dispatch(req, res, next); + }; +} + +/** + * Register a param callback `fn` for the given `name`. + * + * @param {String|Function} name + * @param {Function} fn + * @return {Router} for chaining + * @api public + */ + +Router.prototype.param = function(name, fn){ + // param logic + if ('function' == typeof name) { + this._params.push(name); + return; + } + + // apply param functions + var params = this._params + , len = params.length + , ret; + + for (var i = 0; i < len; ++i) { + if (ret = params[i](name, fn)) { + fn = ret; + } + } + + // ensure we end up with a + // middleware function + if ('function' != typeof fn) { + throw new Error('invalid param() call for ' + name + ', got ' + fn); + } + + (this.params[name] = this.params[name] || []).push(fn); + return this; +}; + +/** + * Return a `Collection` of all routes defined. + * + * @return {Collection} + * @api public + */ + +Router.prototype.all = function(){ + return this.find(function(){ + return true; + }); +}; + +/** + * Remove the given `route`, returns + * a bool indicating if the route was present + * or not. + * + * @param {Route} route + * @return {Boolean} + * @api public + */ + +Router.prototype.remove = function(route){ + var routes = this.routes[route.method] + , len = routes.length; + + for (var i = 0; i < len; ++i) { + if (route == routes[i]) { + routes.splice(i, 1); + return true; + } + } +}; + +/** + * Return routes with route paths matching `path`. + * + * @param {String} method + * @param {String} path + * @return {Collection} + * @api public + */ + +Router.prototype.lookup = function(method, path){ + return this.find(function(route){ + return path == route.path + && (route.method == method + || method == 'all'); + }); +}; + +/** + * Return routes with regexps that match the given `url`. + * + * @param {String} method + * @param {String} url + * @return {Collection} + * @api public + */ + +Router.prototype.match = function(method, url){ + return this.find(function(route){ + return route.match(url) + && (route.method == method + || method == 'all'); + }); +}; + +/** + * Find routes based on the return value of `fn` + * which is invoked once per route. + * + * @param {Function} fn + * @return {Collection} + * @api public + */ + +Router.prototype.find = function(fn){ + var len = methods.length + , ret = new Collection(this) + , method + , routes + , route; + + for (var i = 0; i < len; ++i) { + method = methods[i]; + routes = this.routes[method]; + if (!routes) continue; + for (var j = 0, jlen = routes.length; j < jlen; ++j) { + route = routes[j]; + if (fn(route)) ret.push(route); + } + } + + return ret; +}; + +/** + * Route dispatcher aka the route "middleware". + * + * @param {IncomingMessage} req + * @param {ServerResponse} res + * @param {Function} next + * @api private + */ + +Router.prototype._dispatch = function(req, res, next){ + var params = this.params + , self = this; + + // route dispatch + (function pass(i, err){ + var paramCallbacks + , paramIndex = 0 + , paramVal + , route + , keys + , key + , ret; + + // match next route + function nextRoute(err) { + pass(req._route_index + 1, err); + } + + // match route + req.route = route = self._match(req, i); + + // implied OPTIONS + if (!route && 'OPTIONS' == req.method) return self._options(req, res); + + // no route + if (!route) return next(err); + + // we have a route + // start at param 0 + req.params = route.params; + keys = route.keys; + i = 0; + + // param callbacks + function param(err) { + paramIndex = 0; + key = keys[i++]; + paramVal = key && req.params[key.name]; + paramCallbacks = key && params[key.name]; + + try { + if ('route' == err) { + nextRoute(); + } else if (err) { + i = 0; + callbacks(err); + } else if (paramCallbacks && undefined !== paramVal) { + paramCallback(); + } else if (key) { + param(); + } else { + i = 0; + callbacks(); + } + } catch (err) { + param(err); + } + }; + + param(err); + + // single param callbacks + function paramCallback(err) { + var fn = paramCallbacks[paramIndex++]; + if (err || !fn) return param(err); + fn(req, res, paramCallback, paramVal, key.name); + } + + // invoke route callbacks + function callbacks(err) { + var fn = route.callbacks[i++]; + try { + if ('route' == err) { + nextRoute(); + } else if (err && fn) { + if (fn.length < 4) return callbacks(err); + fn(err, req, res, callbacks); + } else if (fn) { + fn(req, res, callbacks); + } else { + nextRoute(err); + } + } catch (err) { + callbacks(err); + } + } + })(0); +}; + +/** + * Respond to __OPTIONS__ method. + * + * @param {IncomingMessage} req + * @param {ServerResponse} res + * @api private + */ + +Router.prototype._options = function(req, res){ + var path = parse(req.url).pathname + , body = this._optionsFor(path).join(','); + res.send(body, { Allow: body }); +}; + +/** + * Return an array of HTTP verbs or "options" for `path`. + * + * @param {String} path + * @return {Array} + * @api private + */ + +Router.prototype._optionsFor = function(path){ + var self = this; + return methods.filter(function(method){ + var routes = self.routes[method]; + if (!routes || 'options' == method) return; + for (var i = 0, len = routes.length; i < len; ++i) { + if (routes[i].match(path)) return true; + } + }).map(function(method){ + return method.toUpperCase(); + }); +}; + +/** + * Attempt to match a route for `req` + * starting from offset `i`. + * + * @param {IncomingMessage} req + * @param {Number} i + * @return {Route} + * @api private + */ + +Router.prototype._match = function(req, i){ + var method = req.method.toLowerCase() + , url = parse(req.url) + , path = url.pathname + , routes = this.routes + , captures + , route + , keys; + + // pass HEAD to GET routes + if ('head' == method) method = 'get'; + + // routes for this method + if (routes = routes[method]) { + + // matching routes + for (var len = routes.length; i < len; ++i) { + route = routes[i]; + if (captures = route.match(path)) { + keys = route.keys; + route.params = []; + + // params from capture groups + for (var j = 1, jlen = captures.length; j < jlen; ++j) { + var key = keys[j-1] + , val = 'string' == typeof captures[j] + ? decodeURIComponent(captures[j]) + : captures[j]; + if (key) { + route.params[key.name] = val; + } else { + route.params.push(val); + } + } + + // all done + req._route_index = i; + return route; + } + } + } +}; + +/** + * Route `method`, `path`, and one or more callbacks. + * + * @param {String} method + * @param {String} path + * @param {Function} callback... + * @return {Router} for chaining + * @api private + */ + +Router.prototype._route = function(method, path, callbacks){ + var app = this.app + , callbacks = utils.flatten(toArray(arguments, 2)); + + // ensure path was given + if (!path) throw new Error('app.' + method + '() requires a path'); + + // create the route + var route = new Route(method, path, callbacks, { + sensitive: app.enabled('case sensitive routes') + , strict: app.enabled('strict routing') + }); + + // add it + (this.routes[method] = this.routes[method] || []) + .push(route); + return this; +}; diff --git a/node_modules/express/lib/router/methods.js b/node_modules/express/lib/router/methods.js new file mode 100644 index 0000000..e19787b --- /dev/null +++ b/node_modules/express/lib/router/methods.js @@ -0,0 +1,70 @@ + +/*! + * Express - router - methods + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Hypertext Transfer Protocol -- HTTP/1.1 + * http://www.ietf.org/rfc/rfc2616.txt + */ + +var RFC2616 = ['OPTIONS', 'GET', 'POST', 'PUT', 'DELETE', 'TRACE', 'CONNECT']; + +/** + * HTTP Extensions for Distributed Authoring -- WEBDAV + * http://www.ietf.org/rfc/rfc2518.txt + */ + +var RFC2518 = ['PROPFIND', 'PROPPATCH', 'MKCOL', 'COPY', 'MOVE', 'LOCK', 'UNLOCK']; + +/** + * Versioning Extensions to WebDAV + * http://www.ietf.org/rfc/rfc3253.txt + */ + +var RFC3253 = ['VERSION-CONTROL', 'REPORT', 'CHECKOUT', 'CHECKIN', 'UNCHECKOUT', 'MKWORKSPACE', 'UPDATE', 'LABEL', 'MERGE', 'BASELINE-CONTROL', 'MKACTIVITY']; + +/** + * Ordered Collections Protocol (WebDAV) + * http://www.ietf.org/rfc/rfc3648.txt + */ + +var RFC3648 = ['ORDERPATCH']; + +/** + * Web Distributed Authoring and Versioning (WebDAV) Access Control Protocol + * http://www.ietf.org/rfc/rfc3744.txt + */ + +var RFC3744 = ['ACL']; + +/** + * Web Distributed Authoring and Versioning (WebDAV) SEARCH + * http://www.ietf.org/rfc/rfc5323.txt + */ + +var RFC5323 = ['SEARCH']; + +/** + * PATCH Method for HTTP + * http://www.ietf.org/rfc/rfc5789.txt + */ + +var RFC5789 = ['PATCH']; + +/** + * Expose the methods. + */ + +module.exports = [].concat( + RFC2616 + , RFC2518 + , RFC3253 + , RFC3648 + , RFC3744 + , RFC5323 + , RFC5789).map(function(method){ + return method.toLowerCase(); + }); diff --git a/node_modules/express/lib/router/route.js b/node_modules/express/lib/router/route.js new file mode 100644 index 0000000..7f2965c --- /dev/null +++ b/node_modules/express/lib/router/route.js @@ -0,0 +1,88 @@ + +/*! + * Express - router - Route + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Expose `Route`. + */ + +module.exports = Route; + +/** + * Initialize `Route` with the given HTTP `method`, `path`, + * and an array of `callbacks` and `options`. + * + * Options: + * + * - `sensitive` enable case-sensitive routes + * - `strict` enable strict matching for trailing slashes + * + * @param {String} method + * @param {String} path + * @param {Array} callbacks + * @param {Object} options. + * @api private + */ + +function Route(method, path, callbacks, options) { + options = options || {}; + this.path = path; + this.method = method; + this.callbacks = callbacks; + this.regexp = normalize(path + , this.keys = [] + , options.sensitive + , options.strict); +} + +/** + * Check if this route matches `path` and return captures made. + * + * @param {String} path + * @return {Array} + * @api private + */ + +Route.prototype.match = function(path){ + return this.regexp.exec(path); +}; + +/** + * Normalize the given path string, + * returning a regular expression. + * + * An empty array should be passed, + * which will contain the placeholder + * key names. For example "/user/:id" will + * then contain ["id"]. + * + * @param {String|RegExp} path + * @param {Array} keys + * @param {Boolean} sensitive + * @param {Boolean} strict + * @return {RegExp} + * @api private + */ + +function normalize(path, keys, sensitive, strict) { + if (path instanceof RegExp) return path; + path = path + .concat(strict ? '' : '/?') + .replace(/\/\(/g, '(?:/') + .replace(/(\/)?(\.)?:(\w+)(?:(\(.*?\)))?(\?)?/g, function(_, slash, format, key, capture, optional){ + keys.push({ name: key, optional: !! optional }); + slash = slash || ''; + return '' + + (optional ? '' : slash) + + '(?:' + + (optional ? slash : '') + + (format || '') + (capture || (format && '([^/.]+?)' || '([^/]+?)')) + ')' + + (optional || ''); + }) + .replace(/([\/.])/g, '\\$1') + .replace(/\*/g, '(.*)'); + return new RegExp('^' + path + '$', sensitive ? '' : 'i'); +} diff --git a/node_modules/express/lib/utils.js b/node_modules/express/lib/utils.js new file mode 100644 index 0000000..d579f7c --- /dev/null +++ b/node_modules/express/lib/utils.js @@ -0,0 +1,152 @@ + +/*! + * Express - Utils + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Check if `path` looks absolute. + * + * @param {String} path + * @return {Boolean} + * @api private + */ + +exports.isAbsolute = function(path){ + if ('/' == path[0]) return true; + if (':' == path[1] && '\\' == path[2]) return true; +}; + +/** + * Merge object `b` with `a` giving precedence to + * values in object `a`. + * + * @param {Object} a + * @param {Object} b + * @return {Object} a + * @api private + */ + +exports.union = function(a, b){ + if (a && b) { + var keys = Object.keys(b) + , len = keys.length + , key; + for (var i = 0; i < len; ++i) { + key = keys[i]; + if (!a.hasOwnProperty(key)) { + a[key] = b[key]; + } + } + } + return a; +}; + +/** + * Flatten the given `arr`. + * + * @param {Array} arr + * @return {Array} + * @api private + */ + +exports.flatten = function(arr, ret){ + var ret = ret || [] + , len = arr.length; + for (var i = 0; i < len; ++i) { + if (Array.isArray(arr[i])) { + exports.flatten(arr[i], ret); + } else { + ret.push(arr[i]); + } + } + return ret; +}; + +/** + * Parse mini markdown implementation. + * The following conversions are supported, + * primarily for the "flash" middleware: + * + * _foo_ or *foo* become foo + * __foo__ or **foo** become foo + * [A](B) becomes A + * + * @param {String} str + * @return {String} + * @api private + */ + +exports.miniMarkdown = function(str){ + return String(str) + .replace(/(__|\*\*)(.*?)\1/g, '$2') + .replace(/(_|\*)(.*?)\1/g, '$2') + .replace(/\[([^\]]+)\]\(([^)]+)\)/g, '$1'); +}; + +/** + * Escape special characters in the given string of html. + * + * @param {String} html + * @return {String} + * @api private + */ + +exports.escape = function(html) { + return String(html) + .replace(/&/g, '&') + .replace(/"/g, '"') + .replace(//g, '>'); +}; + +/** + * Parse "Range" header `str` relative to the given file `size`. + * + * @param {Number} size + * @param {String} str + * @return {Array} + * @api private + */ + +exports.parseRange = function(size, str){ + var valid = true; + var arr = str.substr(6).split(',').map(function(range){ + var range = range.split('-') + , start = parseInt(range[0], 10) + , end = parseInt(range[1], 10); + + // -500 + if (isNaN(start)) { + start = size - end; + end = size - 1; + // 500- + } else if (isNaN(end)) { + end = size - 1; + } + + // Invalid + if (isNaN(start) || isNaN(end) || start > end) valid = false; + + return { start: start, end: end }; + }); + return valid ? arr : undefined; +}; + +/** + * Fast alternative to `Array.prototype.slice.call()`. + * + * @param {Arguments} args + * @param {Number} n + * @return {Array} + * @api public + */ + +exports.toArray = function(args, i){ + var arr = [] + , len = args.length + , i = i || 0; + for (; i < len; ++i) arr.push(args[i]); + return arr; +}; diff --git a/node_modules/express/lib/view.js b/node_modules/express/lib/view.js new file mode 100644 index 0000000..876d795 --- /dev/null +++ b/node_modules/express/lib/view.js @@ -0,0 +1,457 @@ + +/*! + * Express - view + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var path = require('path') + , extname = path.extname + , dirname = path.dirname + , basename = path.basename + , utils = require('connect').utils + , View = require('./view/view') + , partial = require('./view/partial') + , union = require('./utils').union + , merge = utils.merge + , http = require('http') + , res = http.ServerResponse.prototype; + +/** + * Expose constructors. + */ + +exports = module.exports = View; + +/** + * Export template engine registrar. + */ + +exports.register = View.register; + +/** + * Lookup and compile `view` with cache support by supplying + * both the `cache` object and `cid` string, + * followed by `options` passed to `exports.lookup()`. + * + * @param {String} view + * @param {Object} cache + * @param {Object} cid + * @param {Object} options + * @return {View} + * @api private + */ + +exports.compile = function(view, cache, cid, options){ + if (cache && cid && cache[cid]) return cache[cid]; + + // lookup + view = exports.lookup(view, options); + + // hints + if (!view.exists) { + if (options.hint) hintAtViewPaths(view.original, options); + var err = new Error('failed to locate view "' + view.original.view + '"'); + err.view = view.original; + throw err; + } + + // compile + options.filename = view.path; + view.fn = view.templateEngine.compile(view.contents, options); + cache[cid] = view; + + return view; +}; + +/** + * Lookup `view`, returning an instanceof `View`. + * + * Options: + * + * - `root` root directory path + * - `defaultEngine` default template engine + * - `parentView` parent `View` object + * - `cache` cache object + * - `cacheid` optional cache id + * + * Lookup: + * + * - partial `_` + * - any `/index` + * - non-layout `..//index` + * - any `/` + * - partial `/_` + * + * @param {String} view + * @param {Object} options + * @return {View} + * @api private + */ + +exports.lookup = function(view, options){ + var orig = view = new View(view, options) + , partial = options.isPartial + , layout = options.isLayout; + + // Try _ prefix ex: ./views/_.jade + // taking precedence over the direct path + if (partial) { + view = new View(orig.prefixPath, options); + if (!view.exists) view = orig; + } + + // Try index ex: ./views/user/index.jade + if (!layout && !view.exists) view = new View(orig.indexPath, options); + + // Try ..//index ex: ../user/index.jade + // when calling partial('user') within the same dir + if (!layout && !view.exists) view = new View(orig.upIndexPath, options); + + // Try root ex: /user.jade + if (!view.exists) view = new View(orig.rootPath, options); + + // Try root _ prefix ex: /_user.jade + if (!view.exists && partial) view = new View(view.prefixPath, options); + + view.original = orig; + return view; +}; + +/** + * Partial render helper. + * + * @api private + */ + +function renderPartial(res, view, options, parentLocals, parent){ + var collection, object, locals; + + if (options) { + // collection + if (options.collection) { + collection = options.collection; + delete options.collection; + } else if ('length' in options) { + collection = options; + options = {}; + } + + // locals + if (options.locals) { + locals = options.locals; + delete options.locals; + } + + // object + if ('Object' != options.constructor.name) { + object = options; + options = {}; + } else if (undefined != options.object) { + object = options.object; + delete options.object; + } + } else { + options = {}; + } + + // Inherit locals from parent + union(options, parentLocals); + + // Merge locals + if (locals) merge(options, locals); + + // Partials dont need layouts + options.isPartial = true; + options.layout = false; + + // Deduce name from view path + var name = options.as || partial.resolveObjectName(view); + + // Render partial + function render(){ + if (object) { + if ('string' == typeof name) { + options[name] = object; + } else if (name === global) { + merge(options, object); + } + } + return res.render(view, options, null, parent, true); + } + + // Collection support + if (collection) { + var len = collection.length + , buf = '' + , keys + , key + , val; + + options.collectionLength = len; + + if ('number' == typeof len || Array.isArray(collection)) { + for (var i = 0; i < len; ++i) { + val = collection[i]; + options.firstInCollection = i == 0; + options.indexInCollection = i; + options.lastInCollection = i == len - 1; + object = val; + buf += render(); + } + } else { + keys = Object.keys(collection); + len = keys.length; + options.collectionLength = len; + options.collectionKeys = keys; + for (var i = 0; i < len; ++i) { + key = keys[i]; + val = collection[key]; + options.keyInCollection = key; + options.firstInCollection = i == 0; + options.indexInCollection = i; + options.lastInCollection = i == len - 1; + object = val; + buf += render(); + } + } + + return buf; + } else { + return render(); + } +}; + +/** + * Render `view` partial with the given `options`. Optionally a + * callback `fn(err, str)` may be passed instead of writing to + * the socket. + * + * Options: + * + * - `object` Single object with name derived from the view (unless `as` is present) + * + * - `as` Variable name for each `collection` value, defaults to the view name. + * * as: 'something' will add the `something` local variable + * * as: this will use the collection value as the template context + * * as: global will merge the collection value's properties with `locals` + * + * - `collection` Array of objects, the name is derived from the view name itself. + * For example _video.html_ will have a object _video_ available to it. + * + * @param {String} view + * @param {Object|Array|Function} options, collection, callback, or object + * @param {Function} fn + * @return {String} + * @api public + */ + +res.partial = function(view, options, fn){ + var app = this.app + , options = options || {} + , viewEngine = app.set('view engine') + , parent = {}; + + // accept callback as second argument + if ('function' == typeof options) { + fn = options; + options = {}; + } + + // root "views" option + parent.dirname = app.set('views') || process.cwd() + '/views'; + + // utilize "view engine" option + if (viewEngine) parent.engine = viewEngine; + + // render the partial + try { + var str = renderPartial(this, view, options, null, parent); + } catch (err) { + if (fn) { + fn(err); + } else { + this.req.next(err); + } + return; + } + + // callback or transfer + if (fn) { + fn(null, str); + } else { + this.send(str); + } +}; + +/** + * Render `view` with the given `options` and optional callback `fn`. + * When a callback function is given a response will _not_ be made + * automatically, however otherwise a response of _200_ and _text/html_ is given. + * + * Options: + * + * - `scope` Template evaluation context (the value of `this`) + * - `debug` Output debugging information + * - `status` Response status code + * + * @param {String} view + * @param {Object|Function} options or callback function + * @param {Function} fn + * @api public + */ + +res.render = function(view, opts, fn, parent, sub){ + // support callback function as second arg + if ('function' == typeof opts) { + fn = opts, opts = null; + } + + try { + return this._render(view, opts, fn, parent, sub); + } catch (err) { + // callback given + if (fn) { + fn(err); + // unwind to root call to prevent multiple callbacks + } else if (sub) { + throw err; + // root template, next(err) + } else { + this.req.next(err); + } + } +}; + +// private render() + +res._render = function(view, opts, fn, parent, sub){ + var options = {} + , self = this + , app = this.app + , helpers = app._locals + , dynamicHelpers = app.dynamicViewHelpers + , viewOptions = app.set('view options') + , root = app.set('views') || process.cwd() + '/views'; + + // cache id + var cid = app.enabled('view cache') + ? view + (parent ? ':' + parent.path : '') + : false; + + // merge "view options" + if (viewOptions) merge(options, viewOptions); + + // merge res._locals + if (this._locals) merge(options, this._locals); + + // merge render() options + if (opts) merge(options, opts); + + // merge render() .locals + if (opts && opts.locals) merge(options, opts.locals); + + // status support + if (options.status) this.statusCode = options.status; + + // capture attempts + options.attempts = []; + + var partial = options.isPartial + , layout = options.layout; + + // Layout support + if (true === layout || undefined === layout) { + layout = 'layout'; + } + + // Default execution scope to a plain object + options.scope = options.scope || {}; + + // Populate view + options.parentView = parent; + + // "views" setting + options.root = root; + + // "view engine" setting + options.defaultEngine = app.set('view engine'); + + // charset option + if (options.charset) this.charset = options.charset; + + // Dynamic helper support + if (false !== options.dynamicHelpers) { + // cache + if (!this.__dynamicHelpers) { + this.__dynamicHelpers = {}; + for (var key in dynamicHelpers) { + this.__dynamicHelpers[key] = dynamicHelpers[key].call( + this.app + , this.req + , this); + } + } + + // apply + merge(options, this.__dynamicHelpers); + } + + // Merge view helpers + union(options, helpers); + + // Always expose partial() as a local + options.partial = function(path, opts){ + return renderPartial(self, path, opts, options, view); + }; + + // View lookup + options.hint = app.enabled('hints'); + view = exports.compile(view, app.cache, cid, options); + + // layout helper + options.layout = function(path){ + layout = path; + }; + + // render + var str = view.fn.call(options.scope, options); + + // layout expected + if (layout) { + options.isLayout = true; + options.layout = false; + options.body = str; + this.render(layout, options, fn, view, true); + // partial return + } else if (partial) { + return str; + // render complete, and + // callback given + } else if (fn) { + fn(null, str); + // respond + } else { + this.send(str); + } +} + +/** + * Hint at view path resolution, outputting the + * paths that Express has tried. + * + * @api private + */ + +function hintAtViewPaths(view, options) { + console.error(); + console.error('failed to locate view "' + view.view + '", tried:'); + options.attempts.forEach(function(path){ + console.error(' - %s', path); + }); + console.error(); +} \ No newline at end of file diff --git a/node_modules/express/lib/view/partial.js b/node_modules/express/lib/view/partial.js new file mode 100644 index 0000000..7d2f69b --- /dev/null +++ b/node_modules/express/lib/view/partial.js @@ -0,0 +1,40 @@ + +/*! + * Express - view - Partial + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Memory cache. + */ + +var cache = {}; + +/** + * Resolve partial object name from the view path. + * + * Examples: + * + * "user.ejs" becomes "user" + * "forum thread.ejs" becomes "forumThread" + * "forum/thread/post.ejs" becomes "post" + * "blog-post.ejs" becomes "blogPost" + * + * @return {String} + * @api private + */ + +exports.resolveObjectName = function(view){ + return cache[view] || (cache[view] = view + .split('/') + .slice(-1)[0] + .split('.')[0] + .replace(/^_/, '') + .replace(/[^a-zA-Z0-9 ]+/g, ' ') + .split(/ +/).map(function(word, i){ + return i + ? word[0].toUpperCase() + word.substr(1) + : word; + }).join('')); +}; \ No newline at end of file diff --git a/node_modules/express/lib/view/view.js b/node_modules/express/lib/view/view.js new file mode 100644 index 0000000..7d9392c --- /dev/null +++ b/node_modules/express/lib/view/view.js @@ -0,0 +1,210 @@ + +/*! + * Express - View + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var path = require('path') + , utils = require('../utils') + , extname = path.extname + , dirname = path.dirname + , basename = path.basename + , fs = require('fs') + , stat = fs.statSync; + +/** + * Expose `View`. + */ + +exports = module.exports = View; + +/** + * Require cache. + */ + +var cache = {}; + +/** + * Initialize a new `View` with the given `view` path and `options`. + * + * @param {String} view + * @param {Object} options + * @api private + */ + +function View(view, options) { + options = options || {}; + this.view = view; + this.root = options.root; + this.relative = false !== options.relative; + this.defaultEngine = options.defaultEngine; + this.parent = options.parentView; + this.basename = basename(view); + this.engine = this.resolveEngine(); + this.extension = '.' + this.engine; + this.name = this.basename.replace(this.extension, ''); + this.path = this.resolvePath(); + this.dirname = dirname(this.path); + if (options.attempts) { + if (!~options.attempts.indexOf(this.path)) + options.attempts.push(this.path); + } +}; + +/** + * Check if the view path exists. + * + * @return {Boolean} + * @api public + */ + +View.prototype.__defineGetter__('exists', function(){ + try { + stat(this.path); + return true; + } catch (err) { + return false; + } +}); + +/** + * Resolve view engine. + * + * @return {String} + * @api private + */ + +View.prototype.resolveEngine = function(){ + // Explicit + if (~this.basename.indexOf('.')) return extname(this.basename).substr(1); + // Inherit from parent + if (this.parent) return this.parent.engine; + // Default + return this.defaultEngine; +}; + +/** + * Resolve view path. + * + * @return {String} + * @api private + */ + +View.prototype.resolvePath = function(){ + var path = this.view; + // Implicit engine + if (!~this.basename.indexOf('.')) path += this.extension; + // Absolute + if (utils.isAbsolute(path)) return path; + // Relative to parent + if (this.relative && this.parent) return this.parent.dirname + '/' + path; + // Relative to root + return this.root + ? this.root + '/' + path + : path; +}; + +/** + * Get view contents. This is a one-time hit, so we + * can afford to be sync. + * + * @return {String} + * @api public + */ + +View.prototype.__defineGetter__('contents', function(){ + return fs.readFileSync(this.path, 'utf8'); +}); + +/** + * Get template engine api, cache exports to reduce + * require() calls. + * + * @return {Object} + * @api public + */ + +View.prototype.__defineGetter__('templateEngine', function(){ + var ext = this.extension; + return cache[ext] || (cache[ext] = require(this.engine)); +}); + +/** + * Return root path alternative. + * + * @return {String} + * @api public + */ + +View.prototype.__defineGetter__('rootPath', function(){ + this.relative = false; + return this.resolvePath(); +}); + +/** + * Return index path alternative. + * + * @return {String} + * @api public + */ + +View.prototype.__defineGetter__('indexPath', function(){ + return this.dirname + + '/' + this.basename.replace(this.extension, '') + + '/index' + this.extension; +}); + +/** + * Return ..//index path alternative. + * + * @return {String} + * @api public + */ + +View.prototype.__defineGetter__('upIndexPath', function(){ + return this.dirname + '/../' + this.name + '/index' + this.extension; +}); + +/** + * Return _ prefix path alternative + * + * @return {String} + * @api public + */ + +View.prototype.__defineGetter__('prefixPath', function(){ + return this.dirname + '/_' + this.basename; +}); + +/** + * Register the given template engine `exports` + * as `ext`. For example we may wish to map ".html" + * files to jade: + * + * app.register('.html', require('jade')); + * + * or + * + * app.register('html', require('jade')); + * + * This is also useful for libraries that may not + * match extensions correctly. For example my haml.js + * library is installed from npm as "hamljs" so instead + * of layout.hamljs, we can register the engine as ".haml": + * + * app.register('.haml', require('haml-js')); + * + * @param {String} ext + * @param {Object} obj + * @api public + */ + +exports.register = function(ext, exports) { + if ('.' != ext[0]) ext = '.' + ext; + cache[ext] = exports; +}; diff --git a/node_modules/express/node_modules/connect/.npmignore b/node_modules/express/node_modules/connect/.npmignore new file mode 100644 index 0000000..b04a224 --- /dev/null +++ b/node_modules/express/node_modules/connect/.npmignore @@ -0,0 +1,11 @@ +*.markdown +*.md +.git* +Makefile +benchmarks/ +docs/ +examples/ +install.sh +support/ +test/ +.DS_Store diff --git a/node_modules/express/node_modules/connect/LICENSE b/node_modules/express/node_modules/connect/LICENSE new file mode 100644 index 0000000..0c5d22d --- /dev/null +++ b/node_modules/express/node_modules/connect/LICENSE @@ -0,0 +1,24 @@ +(The MIT License) + +Copyright (c) 2010 Sencha Inc. +Copyright (c) 2011 LearnBoost +Copyright (c) 2011 TJ Holowaychuk + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/node_modules/express/node_modules/connect/index.js b/node_modules/express/node_modules/connect/index.js new file mode 100644 index 0000000..7477048 --- /dev/null +++ b/node_modules/express/node_modules/connect/index.js @@ -0,0 +1,2 @@ + +module.exports = require('./lib/connect'); \ No newline at end of file diff --git a/node_modules/express/node_modules/connect/lib/cache.js b/node_modules/express/node_modules/connect/lib/cache.js new file mode 100644 index 0000000..4aa026e --- /dev/null +++ b/node_modules/express/node_modules/connect/lib/cache.js @@ -0,0 +1,81 @@ + +/*! + * Connect - Cache + * Copyright(c) 2011 Sencha Inc. + * MIT Licensed + */ + +/** + * Expose `Cache`. + */ + +module.exports = Cache; + +/** + * LRU cache store. + * + * @param {Number} limit + * @api private + */ + +function Cache(limit) { + this.store = {}; + this.keys = []; + this.limit = limit; +} + +/** + * Touch `key`, promoting the object. + * + * @param {String} key + * @param {Number} i + * @api private + */ + +Cache.prototype.touch = function(key, i){ + this.keys.splice(i,1); + this.keys.push(key); +}; + +/** + * Remove `key`. + * + * @param {String} key + * @api private + */ + +Cache.prototype.remove = function(key){ + delete this.store[key]; +}; + +/** + * Get the object stored for `key`. + * + * @param {String} key + * @return {Array} + * @api private + */ + +Cache.prototype.get = function(key){ + return this.store[key]; +}; + +/** + * Add a cache `key`. + * + * @param {String} key + * @return {Array} + * @api private + */ + +Cache.prototype.add = function(key){ + // initialize store + var len = this.keys.push(key); + + // limit reached, invalid LRU + if (len > this.limit) this.remove(this.keys.shift()); + + var arr = this.store[key] = []; + arr.createdAt = new Date; + return arr; +}; diff --git a/node_modules/express/node_modules/connect/lib/connect.js b/node_modules/express/node_modules/connect/lib/connect.js new file mode 100644 index 0000000..332375f --- /dev/null +++ b/node_modules/express/node_modules/connect/lib/connect.js @@ -0,0 +1,106 @@ + +/*! + * Connect + * Copyright(c) 2010 Sencha Inc. + * Copyright(c) 2011 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var HTTPServer = require('./http').Server + , HTTPSServer = require('./https').Server + , fs = require('fs'); + +// node patches + +require('./patch'); + +// expose createServer() as the module + +exports = module.exports = createServer; + +/** + * Framework version. + */ + +exports.version = '1.8.1'; + +/** + * Initialize a new `connect.HTTPServer` with the middleware + * passed to this function. When an object is passed _first_, + * we assume these are the tls options, and return a `connect.HTTPSServer`. + * + * Examples: + * + * An example HTTP server, accepting several middleware. + * + * var server = connect.createServer( + * connect.logger() + * , connect.static(__dirname + '/public') + * ); + * + * An HTTPS server, utilizing the same middleware as above. + * + * var server = connect.createServer( + * { key: key, cert: cert } + * , connect.logger() + * , connect.static(__dirname + '/public') + * ); + * + * Alternatively with connect 1.0 we may omit `createServer()`. + * + * connect( + * connect.logger() + * , connect.static(__dirname + '/public') + * ).listen(3000); + * + * @param {Object|Function} ... + * @return {Server} + * @api public + */ + +function createServer() { + if ('object' == typeof arguments[0]) { + return new HTTPSServer(arguments[0], Array.prototype.slice.call(arguments, 1)); + } else { + return new HTTPServer(Array.prototype.slice.call(arguments)); + } +}; + +// support connect.createServer() + +exports.createServer = createServer; + +// auto-load getters + +exports.middleware = {}; + +/** + * Auto-load bundled middleware with getters. + */ + +fs.readdirSync(__dirname + '/middleware').forEach(function(filename){ + if (/\.js$/.test(filename)) { + var name = filename.substr(0, filename.lastIndexOf('.')); + exports.middleware.__defineGetter__(name, function(){ + return require('./middleware/' + name); + }); + } +}); + +// expose utils + +exports.utils = require('./utils'); + +// expose getters as first-class exports + +exports.utils.merge(exports, exports.middleware); + +// expose constructors + +exports.HTTPServer = HTTPServer; +exports.HTTPSServer = HTTPSServer; + diff --git a/node_modules/express/node_modules/connect/lib/http.js b/node_modules/express/node_modules/connect/lib/http.js new file mode 100644 index 0000000..09898e2 --- /dev/null +++ b/node_modules/express/node_modules/connect/lib/http.js @@ -0,0 +1,217 @@ + +/*! + * Connect - HTTPServer + * Copyright(c) 2010 Sencha Inc. + * Copyright(c) 2011 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var http = require('http') + , parse = require('url').parse + , assert = require('assert'); + +// environment + +var env = process.env.NODE_ENV || 'development'; + +/** + * Initialize a new `Server` with the given `middleware`. + * + * Examples: + * + * var server = connect.createServer( + * connect.favicon() + * , connect.logger() + * , connect.static(__dirname + '/public') + * ); + * + * @params {Array} middleware + * @return {Server} + * @api public + */ + +var Server = exports.Server = function HTTPServer(middleware) { + this.stack = []; + middleware.forEach(function(fn){ + this.use(fn); + }, this); + http.Server.call(this, this.handle); +}; + +/** + * Inherit from `http.Server.prototype`. + */ + +Server.prototype.__proto__ = http.Server.prototype; + +/** + * Utilize the given middleware `handle` to the given `route`, + * defaulting to _/_. This "route" is the mount-point for the + * middleware, when given a value other than _/_ the middleware + * is only effective when that segment is present in the request's + * pathname. + * + * For example if we were to mount a function at _/admin_, it would + * be invoked on _/admin_, and _/admin/settings_, however it would + * not be invoked for _/_, or _/posts_. + * + * This is effectively the same as passing middleware to `connect.createServer()`, + * however provides a progressive api. + * + * Examples: + * + * var server = connect.createServer(); + * server.use(connect.favicon()); + * server.use(connect.logger()); + * server.use(connect.static(__dirname + '/public')); + * + * If we wanted to prefix static files with _/public_, we could + * "mount" the `static()` middleware: + * + * server.use('/public', connect.static(__dirname + '/public')); + * + * This api is chainable, meaning the following is valid: + * + * connect.createServer() + * .use(connect.favicon()) + * .use(connect.logger()) + * .use(connect.static(__dirname + '/public')) + * .listen(3000); + * + * @param {String|Function} route or handle + * @param {Function} handle + * @return {Server} + * @api public + */ + +Server.prototype.use = function(route, handle){ + this.route = '/'; + + // default route to '/' + if ('string' != typeof route) { + handle = route; + route = '/'; + } + + // wrap sub-apps + if ('function' == typeof handle.handle) { + var server = handle; + server.route = route; + handle = function(req, res, next) { + server.handle(req, res, next); + }; + } + + // wrap vanilla http.Servers + if (handle instanceof http.Server) { + handle = handle.listeners('request')[0]; + } + + // normalize route to not trail with slash + if ('/' == route[route.length - 1]) { + route = route.substr(0, route.length - 1); + } + + // add the middleware + this.stack.push({ route: route, handle: handle }); + + // allow chaining + return this; +}; + +/** + * Handle server requests, punting them down + * the middleware stack. + * + * @api private + */ + +Server.prototype.handle = function(req, res, out) { + var writeHead = res.writeHead + , stack = this.stack + , removed = '' + , index = 0; + + function next(err) { + var layer, path, c; + req.url = removed + req.url; + req.originalUrl = req.originalUrl || req.url; + removed = ''; + + layer = stack[index++]; + + // all done + if (!layer || res.headerSent) { + // but wait! we have a parent + if (out) return out(err); + + // error + if (err) { + var msg = 'production' == env + ? 'Internal Server Error' + : err.stack || err.toString(); + + // output to stderr in a non-test env + if ('test' != env) console.error(err.stack || err.toString()); + + // unable to respond + if (res.headerSent) return req.socket.destroy(); + + res.statusCode = 500; + res.setHeader('Content-Type', 'text/plain'); + if ('HEAD' == req.method) return res.end(); + res.end(msg); + } else { + res.statusCode = 404; + res.setHeader('Content-Type', 'text/plain'); + if ('HEAD' == req.method) return res.end(); + res.end('Cannot ' + req.method + ' ' + req.url); + } + return; + } + + try { + path = parse(req.url).pathname; + if (undefined == path) path = '/'; + + // skip this layer if the route doesn't match. + if (0 != path.indexOf(layer.route)) return next(err); + + c = path[layer.route.length]; + if (c && '/' != c && '.' != c) return next(err); + + // Call the layer handler + // Trim off the part of the url that matches the route + removed = layer.route; + req.url = req.url.substr(removed.length); + + // Ensure leading slash + if ('/' != req.url[0]) req.url = '/' + req.url; + + var arity = layer.handle.length; + if (err) { + if (arity === 4) { + layer.handle(err, req, res, next); + } else { + next(err); + } + } else if (arity < 4) { + layer.handle(req, res, next); + } else { + next(); + } + } catch (e) { + if (e instanceof assert.AssertionError) { + console.error(e.stack + '\n'); + next(e); + } else { + next(e); + } + } + } + next(); +}; \ No newline at end of file diff --git a/node_modules/express/node_modules/connect/lib/https.js b/node_modules/express/node_modules/connect/lib/https.js new file mode 100644 index 0000000..9b09fa4 --- /dev/null +++ b/node_modules/express/node_modules/connect/lib/https.js @@ -0,0 +1,47 @@ + +/*! + * Connect - HTTPServer + * Copyright(c) 2010 Sencha Inc. + * Copyright(c) 2011 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var HTTPServer = require('./http').Server + , https = require('https'); + +/** + * Initialize a new `Server` with the given + *`options` and `middleware`. The HTTPS api + * is identical to the [HTTP](http.html) server, + * however TLS `options` must be provided before + * passing in the optional middleware. + * + * @params {Object} options + * @params {Array} middleawre + * @return {Server} + * @api public + */ + +var Server = exports.Server = function HTTPSServer(options, middleware) { + this.stack = []; + middleware.forEach(function(fn){ + this.use(fn); + }, this); + https.Server.call(this, options, this.handle); +}; + +/** + * Inherit from `http.Server.prototype`. + */ + +Server.prototype.__proto__ = https.Server.prototype; + +// mixin HTTPServer methods + +Object.keys(HTTPServer.prototype).forEach(function(method){ + Server.prototype[method] = HTTPServer.prototype[method]; +}); \ No newline at end of file diff --git a/node_modules/express/node_modules/connect/lib/index.js b/node_modules/express/node_modules/connect/lib/index.js new file mode 100644 index 0000000..77b14c3 --- /dev/null +++ b/node_modules/express/node_modules/connect/lib/index.js @@ -0,0 +1,46 @@ + +/** + * # Connect + * + * Connect is a middleware framework for node, + * shipping with over 11 bundled middleware and a rich choice of + * [3rd-party middleware](https://github.com/senchalabs/connect/wiki). + * + * Installation: + * + * $ npm install connect + * + * API: + * + * - [connect](connect.html) general + * - [http](http.html) http server + * - [https](https.html) https server + * + * Middleware: + * + * - [logger](middleware-logger.html) request logger with custom format support + * - [csrf](middleware-csrf.html) Cross-site request forgery protection + * - [basicAuth](middleware-basicAuth.html) basic http authentication + * - [bodyParser](middleware-bodyParser.html) extensible request body parser + * - [cookieParser](middleware-cookieParser.html) cookie parser + * - [session](middleware-session.html) session management support with bundled [MemoryStore](middleware-session-memory.html) + * - [compiler](middleware-compiler.html) static asset compiler (sass, less, coffee-script, etc) + * - [methodOverride](middleware-methodOverride.html) faux HTTP method support + * - [responseTime](middleware-responseTime.html) calculates response-time and exposes via X-Response-Time + * - [router](middleware-router.html) provides rich Sinatra / Express-like routing + * - [staticCache](middleware-staticCache.html) memory cache layer for the static() middleware + * - [static](middleware-static.html) streaming static file server supporting `Range` and more + * - [directory](middleware-directory.html) directory listing middleware + * - [vhost](middleware-vhost.html) virtual host sub-domain mapping middleware + * - [favicon](middleware-favicon.html) efficient favicon server (with default icon) + * - [limit](middleware-limit.html) limit the bytesize of request bodies + * - [profiler](middleware-profiler.html) request profiler reporting response-time, memory usage, etc + * - [query](middleware-query.html) automatic querystring parser, populating `req.query` + * - [errorHandler](middleware-errorHandler.html) flexible error handler + * + * Internals: + * + * - connect [utilities](utils.html) + * - node monkey [patches](patch.html) + * + */ \ No newline at end of file diff --git a/node_modules/express/node_modules/connect/lib/middleware/basicAuth.js b/node_modules/express/node_modules/connect/lib/middleware/basicAuth.js new file mode 100644 index 0000000..3ff472b --- /dev/null +++ b/node_modules/express/node_modules/connect/lib/middleware/basicAuth.js @@ -0,0 +1,93 @@ + +/*! + * Connect - basicAuth + * Copyright(c) 2010 Sencha Inc. + * Copyright(c) 2011 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var utils = require('../utils') + , unauthorized = utils.unauthorized + , badRequest = utils.badRequest; + +/** + * Enfore basic authentication by providing a `callback(user, pass)`, + * which must return `true` in order to gain access. Alternatively an async + * method is provided as well, invoking `callback(user, pass, callback)`. Populates + * `req.remoteUser`. The final alternative is simply passing username / password + * strings. + * + * Examples: + * + * connect(connect.basicAuth('username', 'password')); + * + * connect( + * connect.basicAuth(function(user, pass){ + * return 'tj' == user & 'wahoo' == pass; + * }) + * ); + * + * connect( + * connect.basicAuth(function(user, pass, fn){ + * User.authenticate({ user: user, pass: pass }, fn); + * }) + * ); + * + * @param {Function|String} callback or username + * @param {String} realm + * @api public + */ + +module.exports = function basicAuth(callback, realm) { + var username, password; + + // user / pass strings + if ('string' == typeof callback) { + username = callback; + password = realm; + if ('string' != typeof password) throw new Error('password argument required'); + realm = arguments[2]; + callback = function(user, pass){ + return user == username && pass == password; + } + } + + realm = realm || 'Authorization Required'; + + return function(req, res, next) { + var authorization = req.headers.authorization; + + if (req.remoteUser) return next(); + if (!authorization) return unauthorized(res, realm); + + var parts = authorization.split(' ') + , scheme = parts[0] + , credentials = new Buffer(parts[1], 'base64').toString().split(':'); + + if ('Basic' != scheme) return badRequest(res); + + // async + if (callback.length >= 3) { + var pause = utils.pause(req); + callback(credentials[0], credentials[1], function(err, user){ + if (err || !user) return unauthorized(res, realm); + req.remoteUser = user; + next(); + pause.resume(); + }); + // sync + } else { + if (callback(credentials[0], credentials[1])) { + req.remoteUser = credentials[0]; + next(); + } else { + unauthorized(res, realm); + } + } + } +}; + diff --git a/node_modules/express/node_modules/connect/lib/middleware/bodyParser.js b/node_modules/express/node_modules/connect/lib/middleware/bodyParser.js new file mode 100644 index 0000000..97467c6 --- /dev/null +++ b/node_modules/express/node_modules/connect/lib/middleware/bodyParser.js @@ -0,0 +1,172 @@ + +/*! + * Connect - bodyParser + * Copyright(c) 2010 Sencha Inc. + * Copyright(c) 2011 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var qs = require('qs') + , formidable = require('formidable'); + +/** + * Extract the mime type from the given request's + * _Content-Type_ header. + * + * @param {IncomingMessage} req + * @return {String} + * @api private + */ + +function mime(req) { + var str = req.headers['content-type'] || ''; + return str.split(';')[0]; +} + +/** + * Parse request bodies. + * + * By default _application/json_, _application/x-www-form-urlencoded_, + * and _multipart/form-data_ are supported, however you may map `connect.bodyParser.parse[contentType]` + * to a function receiving `(req, options, callback)`. + * + * Examples: + * + * connect.createServer( + * connect.bodyParser() + * , function(req, res) { + * res.end('viewing user ' + req.body.user.name); + * } + * ); + * + * $ curl -d 'user[name]=tj' http://localhost/ + * $ curl -d '{"user":{"name":"tj"}}' -H "Content-Type: application/json" http://localhost/ + * + * Multipart configuration: + * + * The `options` passed are provided to each parser function. + * The _multipart/form-data_ parser merges these with formidable's + * IncomingForm object, allowing you to tweak the upload directory, + * size limits, etc. For example you may wish to retain the file extension + * and change the upload directory: + * + * server.use(bodyParser({ + * keepExtensions: true + * , uploadDir: '/www/mysite.com/uploads' + * })); + * + * View https://github.com/felixge/node-formidable for more information. + * + * @param {Object} options + * @return {Function} + * @api public + */ + +exports = module.exports = function bodyParser(options){ + options = options || {}; + return function bodyParser(req, res, next) { + if (req.body) return next(); + req.body = {}; + + if ('GET' == req.method || 'HEAD' == req.method) return next(); + var parser = exports.parse[mime(req)]; + if (parser) { + parser(req, options, next); + } else { + next(); + } + } +}; + +/** + * Parsers. + */ + +exports.parse = {}; + +/** + * Parse application/x-www-form-urlencoded. + */ + +exports.parse['application/x-www-form-urlencoded'] = function(req, options, fn){ + var buf = ''; + req.setEncoding('utf8'); + req.on('data', function(chunk){ buf += chunk }); + req.on('end', function(){ + try { + req.body = qs.parse(buf); + fn(); + } catch (err){ + fn(err); + } + }); +}; + +/** + * Parse application/json. + */ + +exports.parse['application/json'] = function(req, options, fn){ + var buf = ''; + req.setEncoding('utf8'); + req.on('data', function(chunk){ buf += chunk }); + req.on('end', function(){ + try { + req.body = JSON.parse(buf); + fn(); + } catch (err){ + fn(err); + } + }); +}; + +/** + * Parse multipart/form-data. + * + * TODO: make multiple support optional + * TODO: revisit "error" flag if it's a formidable bug + */ + +exports.parse['multipart/form-data'] = function(req, options, fn){ + var form = new formidable.IncomingForm + , data = {} + , done; + + Object.keys(options).forEach(function(key){ + form[key] = options[key]; + }); + + function ondata(name, val){ + if (Array.isArray(data[name])) { + data[name].push(val); + } else if (data[name]) { + data[name] = [data[name], val]; + } else { + data[name] = val; + } + } + + form.on('field', ondata); + form.on('file', ondata); + + form.on('error', function(err){ + fn(err); + done = true; + }); + + form.on('end', function(){ + if (done) return; + try { + req.body = qs.parse(data); + fn(); + } catch (err) { + fn(err); + } + }); + + form.parse(req); +}; \ No newline at end of file diff --git a/node_modules/express/node_modules/connect/lib/middleware/compiler.js b/node_modules/express/node_modules/connect/lib/middleware/compiler.js new file mode 100644 index 0000000..dc4dd66 --- /dev/null +++ b/node_modules/express/node_modules/connect/lib/middleware/compiler.js @@ -0,0 +1,163 @@ + +/*! + * Connect - compiler + * Copyright(c) 2010 Sencha Inc. + * Copyright(c) 2011 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var fs = require('fs') + , path = require('path') + , parse = require('url').parse; + +/** + * Require cache. + */ + +var cache = {}; + +/** + * Setup compiler. + * + * Options: + * + * - `src` Source directory, defaults to **CWD**. + * - `dest` Destination directory, defaults `src`. + * - `enable` Array of enabled compilers. + * + * Compilers: + * + * - `sass` Compiles sass to css + * - `less` Compiles less to css + * - `coffeescript` Compiles coffee to js + * + * @param {Object} options + * @api public + */ + +exports = module.exports = function compiler(options){ + options = options || {}; + + var srcDir = options.src || process.cwd() + , destDir = options.dest || srcDir + , enable = options.enable; + + if (!enable || enable.length === 0) { + throw new Error('compiler\'s "enable" option is not set, nothing will be compiled.'); + } + + return function compiler(req, res, next){ + if ('GET' != req.method) return next(); + var pathname = parse(req.url).pathname; + for (var i = 0, len = enable.length; i < len; ++i) { + var name = enable[i] + , compiler = compilers[name]; + if (compiler.match.test(pathname)) { + var src = (srcDir + pathname).replace(compiler.match, compiler.ext) + , dest = destDir + pathname; + + // Compare mtimes + fs.stat(src, function(err, srcStats){ + if (err) { + if ('ENOENT' == err.code) { + next(); + } else { + next(err); + } + } else { + fs.stat(dest, function(err, destStats){ + if (err) { + // Oh snap! it does not exist, compile it + if ('ENOENT' == err.code) { + compile(); + } else { + next(err); + } + } else { + // Source has changed, compile it + if (srcStats.mtime > destStats.mtime) { + compile(); + } else { + // Defer file serving + next(); + } + } + }); + } + }); + + // Compile to the destination + function compile() { + fs.readFile(src, 'utf8', function(err, str){ + if (err) { + next(err); + } else { + compiler.compile(str, function(err, str){ + if (err) { + next(err); + } else { + fs.writeFile(dest, str, 'utf8', function(err){ + next(err); + }); + } + }); + } + }); + } + return; + } + } + next(); + }; +}; + +/** + * Bundled compilers: + * + * - [sass](http://github.com/visionmedia/sass.js) to _css_ + * - [less](http://github.com/cloudhead/less.js) to _css_ + * - [coffee](http://github.com/jashkenas/coffee-script) to _js_ + */ + +var compilers = exports.compilers = { + sass: { + match: /\.css$/, + ext: '.sass', + compile: function(str, fn){ + var sass = cache.sass || (cache.sass = require('sass')); + try { + fn(null, sass.render(str)); + } catch (err) { + fn(err); + } + } + }, + less: { + match: /\.css$/, + ext: '.less', + compile: function(str, fn){ + var less = cache.less || (cache.less = require('less')); + try { + less.render(str, fn); + } catch (err) { + fn(err); + } + } + }, + coffeescript: { + match: /\.js$/, + ext: '.coffee', + compile: function(str, fn){ + var coffee = cache.coffee || (cache.coffee = require('coffee-script')); + try { + fn(null, coffee.compile(str)); + } catch (err) { + fn(err); + } + } + } +}; \ No newline at end of file diff --git a/node_modules/express/node_modules/connect/lib/middleware/cookieParser.js b/node_modules/express/node_modules/connect/lib/middleware/cookieParser.js new file mode 100644 index 0000000..d6b69de --- /dev/null +++ b/node_modules/express/node_modules/connect/lib/middleware/cookieParser.js @@ -0,0 +1,46 @@ + +/*! + * Connect - cookieParser + * Copyright(c) 2010 Sencha Inc. + * Copyright(c) 2011 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var utils = require('./../utils'); + +/** + * Parse _Cookie_ header and populate `req.cookies` + * with an object keyed by the cookie names. + * + * Examples: + * + * connect.createServer( + * connect.cookieParser() + * , function(req, res, next){ + * res.end(JSON.stringify(req.cookies)); + * } + * ); + * + * @return {Function} + * @api public + */ + +module.exports = function cookieParser(){ + return function cookieParser(req, res, next) { + var cookie = req.headers.cookie; + if (req.cookies) return next(); + req.cookies = {}; + if (cookie) { + try { + req.cookies = utils.parseCookie(cookie); + } catch (err) { + return next(err); + } + } + next(); + }; +}; \ No newline at end of file diff --git a/node_modules/express/node_modules/connect/lib/middleware/csrf.js b/node_modules/express/node_modules/connect/lib/middleware/csrf.js new file mode 100644 index 0000000..1dcf0d1 --- /dev/null +++ b/node_modules/express/node_modules/connect/lib/middleware/csrf.js @@ -0,0 +1,105 @@ + +/*! + * Connect - csrf + * Copyright(c) 2011 Sencha Inc. + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var utils = require('../utils') + , crypto = require('crypto'); + +/** + * CRSF protection middleware. + * + * By default this middleware generates a token named "_csrf" + * which should be added to requests which mutate + * state, within a hidden form field, query-string etc. This + * token is validated against the visitor's `req.session._csrf` + * property which is re-generated per request. + * + * The default `value` function checks `req.body` generated + * by the `bodyParser()` middleware, `req.query` generated + * by `query()`, and the "X-CSRF-Token" header field. + * + * This middleware requires session support, thus should be added + * somewhere _below_ `session()` and `cookieParser()`. + * + * Examples: + * + * var form = '\n\ + *
\n\ + * \n\ + * \n\ + * \n\ + * \n\ + *
\n\ + * '; + * + * connect( + * connect.cookieParser() + * , connect.session({ secret: 'keyboard cat' }) + * , connect.bodyParser() + * , connect.csrf() + * + * , function(req, res, next){ + * if ('POST' != req.method) return next(); + * req.session.user = req.body.user; + * next(); + * } + * + * , function(req, res){ + * res.setHeader('Content-Type', 'text/html'); + * var body = form + * .replace('{token}', req.session._csrf) + * .replace('{user}', req.session.user && req.session.user.name || ''); + * res.end(body); + * } + * ).listen(3000); + * + * Options: + * + * - `value` a function accepting the request, returning the token + * + * @param {Object} options + * @api public + */ + +module.exports = function csrf(options) { + var options = options || {} + , value = options.value || defaultValue; + + return function(req, res, next){ + // generate CSRF token + var token = req.session._csrf || (req.session._csrf = utils.uid(24)); + + // ignore GET (for now) + if ('GET' == req.method) return next(); + + // determine value + var val = value(req); + + // check + if (val != token) return utils.forbidden(res); + + next(); + } +}; + +/** + * Default value function, checking the `req.body` + * and `req.query` for the CSRF token. + * + * @param {IncomingMessage} req + * @return {String} + * @api private + */ + +function defaultValue(req) { + return (req.body && req.body._csrf) + || (req.query && req.query._csrf) + || (req.headers['x-csrf-token']); +} \ No newline at end of file diff --git a/node_modules/express/node_modules/connect/lib/middleware/directory.js b/node_modules/express/node_modules/connect/lib/middleware/directory.js new file mode 100644 index 0000000..df5b5e6 --- /dev/null +++ b/node_modules/express/node_modules/connect/lib/middleware/directory.js @@ -0,0 +1,222 @@ + +/*! + * Connect - directory + * Copyright(c) 2011 Sencha Inc. + * Copyright(c) 2011 TJ Holowaychuk + * MIT Licensed + */ + +// TODO: icon / style for directories +// TODO: arrow key navigation +// TODO: make icons extensible + +/** + * Module dependencies. + */ + +var fs = require('fs') + , parse = require('url').parse + , utils = require('../utils') + , path = require('path') + , normalize = path.normalize + , extname = path.extname + , join = path.join; + +/** + * Icon cache. + */ + +var cache = {}; + +/** + * Serve directory listings with the given `root` path. + * + * Options: + * + * - `hidden` display hidden (dot) files. Defaults to false. + * - `icons` display icons. Defaults to false. + * - `filter` Apply this filter function to files. Defaults to false. + * + * @param {String} root + * @param {Object} options + * @return {Function} + * @api public + */ + +exports = module.exports = function directory(root, options){ + options = options || {}; + + // root required + if (!root) throw new Error('directory() root path required'); + var hidden = options.hidden + , icons = options.icons + , filter = options.filter + , root = normalize(root); + + return function directory(req, res, next) { + var accept = req.headers.accept || 'text/plain' + , url = parse(req.url) + , dir = decodeURIComponent(url.pathname) + , path = normalize(join(root, dir)) + , originalUrl = parse(req.originalUrl) + , originalDir = decodeURIComponent(originalUrl.pathname) + , showUp = path != root && path != root + '/'; + + // null byte(s) + if (~path.indexOf('\0')) return utils.badRequest(res); + + // malicious path + if (0 != path.indexOf(root)) return utils.forbidden(res); + + // check if we have a directory + fs.stat(path, function(err, stat){ + if (err) return 'ENOENT' == err.code + ? next() + : next(err); + + if (!stat.isDirectory()) return next(); + + // fetch files + fs.readdir(path, function(err, files){ + if (err) return next(err); + if (!hidden) files = removeHidden(files); + if (filter) files = files.filter(filter); + files.sort(); + // content-negotiation + for (var key in exports) { + if (~accept.indexOf(key) || ~accept.indexOf('*/*')) { + exports[key](req, res, files, next, originalDir, showUp, icons); + return; + } + } + utils.notAcceptable(res); + }); + }); + }; +}; + +/** + * Respond with text/html. + */ + +exports.html = function(req, res, files, next, dir, showUp, icons){ + fs.readFile(__dirname + '/../public/directory.html', 'utf8', function(err, str){ + if (err) return next(err); + fs.readFile(__dirname + '/../public/style.css', 'utf8', function(err, style){ + if (err) return next(err); + if (showUp) files.unshift('..'); + str = str + .replace('{style}', style) + .replace('{files}', html(files, dir, icons)) + .replace('{directory}', dir) + .replace('{linked-path}', htmlPath(dir)); + res.setHeader('Content-Type', 'text/html'); + res.setHeader('Content-Length', str.length); + res.end(str); + }); + }); +}; + +/** + * Respond with application/json. + */ + +exports.json = function(req, res, files){ + files = JSON.stringify(files); + res.setHeader('Content-Type', 'application/json'); + res.setHeader('Content-Length', files.length); + res.end(files); +}; + +/** + * Respond with text/plain. + */ + +exports.plain = function(req, res, files){ + files = files.join('\n') + '\n'; + res.setHeader('Content-Type', 'text/plain'); + res.setHeader('Content-Length', files.length); + res.end(files); +}; + +/** + * Map html `dir`, returning a linked path. + */ + +function htmlPath(dir) { + var curr = []; + return dir.split('/').map(function(part){ + curr.push(part); + return '' + part + ''; + }).join(' / '); +} + +/** + * Map html `files`, returning an html unordered list. + */ + +function html(files, dir, useIcons) { + return '
    ' + files.map(function(file){ + var icon = '' + , classes = []; + + if (useIcons && '..' != file) { + icon = icons[extname(file)] || icons.default; + icon = ''; + classes.push('icon'); + } + + return '
  • ' + + icon + file + '
  • '; + + }).join('\n') + '
'; +} + +/** + * Load and cache the given `icon`. + * + * @param {String} icon + * @return {String} + * @api private + */ + +function load(icon) { + if (cache[icon]) return cache[icon]; + return cache[icon] = fs.readFileSync(__dirname + '/../public/icons/' + icon, 'base64'); +} + +/** + * Filter "hidden" `files`, aka files + * beginning with a `.`. + * + * @param {Array} files + * @return {Array} + * @api private + */ + +function removeHidden(files) { + return files.filter(function(file){ + return '.' != file[0]; + }); +} + +/** + * Icon map. + */ + +var icons = { + '.js': 'page_white_code_red.png' + , '.c': 'page_white_c.png' + , '.h': 'page_white_h.png' + , '.cc': 'page_white_cplusplus.png' + , '.php': 'page_white_php.png' + , '.rb': 'page_white_ruby.png' + , '.cpp': 'page_white_cplusplus.png' + , '.swf': 'page_white_flash.png' + , '.pdf': 'page_white_acrobat.png' + , 'default': 'page_white.png' +}; diff --git a/node_modules/express/node_modules/connect/lib/middleware/errorHandler.js b/node_modules/express/node_modules/connect/lib/middleware/errorHandler.js new file mode 100644 index 0000000..f2fc44f --- /dev/null +++ b/node_modules/express/node_modules/connect/lib/middleware/errorHandler.js @@ -0,0 +1,100 @@ +/*! + * Connect - errorHandler + * Copyright(c) 2010 Sencha Inc. + * Copyright(c) 2011 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var utils = require('../utils') + , url = require('url') + , fs = require('fs'); + +/** + * Flexible error handler, providing (_optional_) stack traces + * and error message responses for requests accepting text, html, + * or json. + * + * Options: + * + * - `showStack`, `stack` respond with both the error message and stack trace. Defaults to `false` + * - `showMessage`, `message`, respond with the exception message only. Defaults to `false` + * - `dumpExceptions`, `dump`, dump exceptions to stderr (without terminating the process). Defaults to `false` + * + * Text: + * + * By default, and when _text/plain_ is accepted a simple stack trace + * or error message will be returned. + * + * JSON: + * + * When _application/json_ is accepted, connect will respond with + * an object in the form of `{ "error": error }`. + * + * HTML: + * + * When accepted connect will output a nice html stack trace. + * + * @param {Object} options + * @return {Function} + * @api public + */ + +exports = module.exports = function errorHandler(options){ + options = options || {}; + + // defaults + var showStack = options.showStack || options.stack + , showMessage = options.showMessage || options.message + , dumpExceptions = options.dumpExceptions || options.dump + , formatUrl = options.formatUrl; + + return function errorHandler(err, req, res, next){ + res.statusCode = 500; + if (dumpExceptions) console.error(err.stack); + if (showStack) { + var accept = req.headers.accept || ''; + // html + if (~accept.indexOf('html')) { + fs.readFile(__dirname + '/../public/style.css', 'utf8', function(e, style){ + fs.readFile(__dirname + '/../public/error.html', 'utf8', function(e, html){ + var stack = (err.stack || '') + .split('\n').slice(1) + .map(function(v){ return '
  • ' + v + '
  • '; }).join(''); + html = html + .replace('{style}', style) + .replace('{stack}', stack) + .replace('{title}', exports.title) + .replace(/\{error\}/g, utils.escape(err.toString())); + res.setHeader('Content-Type', 'text/html'); + res.end(html); + }); + }); + // json + } else if (~accept.indexOf('json')) { + var json = JSON.stringify({ error: err }); + res.setHeader('Content-Type', 'application/json'); + res.end(json); + // plain text + } else { + res.writeHead(500, { 'Content-Type': 'text/plain' }); + res.end(err.stack); + } + } else { + var body = showMessage + ? err.toString() + : 'Internal Server Error'; + res.setHeader('Content-Type', 'text/plain'); + res.end(body); + } + }; +}; + +/** + * Template title. + */ + +exports.title = 'Connect'; \ No newline at end of file diff --git a/node_modules/express/node_modules/connect/lib/middleware/favicon.js b/node_modules/express/node_modules/connect/lib/middleware/favicon.js new file mode 100644 index 0000000..8eeafba --- /dev/null +++ b/node_modules/express/node_modules/connect/lib/middleware/favicon.js @@ -0,0 +1,76 @@ + +/*! + * Connect - favicon + * Copyright(c) 2010 Sencha Inc. + * Copyright(c) 2011 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var fs = require('fs') + , utils = require('../utils'); + +/** + * Favicon cache. + */ + +var icon; + +/** + * By default serves the connect favicon, or the favicon + * located by the given `path`. + * + * Options: + * + * - `maxAge` cache-control max-age directive, defaulting to 1 day + * + * Examples: + * + * connect.createServer( + * connect.favicon() + * ); + * + * connect.createServer( + * connect.favicon(__dirname + '/public/favicon.ico') + * ); + * + * @param {String} path + * @param {Object} options + * @return {Function} + * @api public + */ + +module.exports = function favicon(path, options){ + var options = options || {} + , path = path || __dirname + '/../public/favicon.ico' + , maxAge = options.maxAge || 86400000; + + return function favicon(req, res, next){ + if ('/favicon.ico' == req.url) { + if (icon) { + res.writeHead(200, icon.headers); + res.end(icon.body); + } else { + fs.readFile(path, function(err, buf){ + if (err) return next(err); + icon = { + headers: { + 'Content-Type': 'image/x-icon' + , 'Content-Length': buf.length + , 'ETag': '"' + utils.md5(buf) + '"' + , 'Cache-Control': 'public, max-age=' + (maxAge / 1000) + }, + body: buf + }; + res.writeHead(200, icon.headers); + res.end(icon.body); + }); + } + } else { + next(); + } + }; +}; \ No newline at end of file diff --git a/node_modules/express/node_modules/connect/lib/middleware/limit.js b/node_modules/express/node_modules/connect/lib/middleware/limit.js new file mode 100644 index 0000000..4dafdd3 --- /dev/null +++ b/node_modules/express/node_modules/connect/lib/middleware/limit.js @@ -0,0 +1,82 @@ + +/*! + * Connect - limit + * Copyright(c) 2011 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Limit request bodies to the given size in `bytes`. + * + * A string representation of the bytesize may also be passed, + * for example "5mb", "200kb", "1gb", etc. + * + * Examples: + * + * var server = connect( + * connect.limit('5.5mb') + * ).listen(3000); + * + * TODO: pause EV_READ + * + * @param {Number|String} bytes + * @return {Function} + * @api public + */ + +module.exports = function limit(bytes){ + if ('string' == typeof bytes) bytes = parse(bytes); + if ('number' != typeof bytes) throw new Error('limit() bytes required'); + return function limit(req, res, next){ + var received = 0 + , len = req.headers['content-length'] + ? parseInt(req.headers['content-length'], 10) + : null; + + // deny the request + function deny() { + req.destroy(); + } + + // self-awareness + if (req._limit) return next(); + req._limit = true; + + // limit by content-length + if (len && len > bytes) { + res.statusCode = 413; + res.end('Request Entity Too Large'); + return; + } + + // limit + req.on('data', function(chunk){ + received += chunk.length; + if (received > bytes) deny(); + }); + + next(); + }; +}; + +/** + * Parse byte `size` string. + * + * @param {String} size + * @return {Number} + * @api private + */ + +function parse(size) { + var parts = size.match(/^(\d+(?:\.\d+)?) *(kb|mb|gb)$/) + , n = parseFloat(parts[1]) + , type = parts[2]; + + var map = { + kb: 1024 + , mb: 1024 * 1024 + , gb: 1024 * 1024 * 1024 + }; + + return map[type] * n; +} \ No newline at end of file diff --git a/node_modules/express/node_modules/connect/lib/middleware/logger.js b/node_modules/express/node_modules/connect/lib/middleware/logger.js new file mode 100644 index 0000000..75cc5aa --- /dev/null +++ b/node_modules/express/node_modules/connect/lib/middleware/logger.js @@ -0,0 +1,299 @@ + +/*! + * Connect - logger + * Copyright(c) 2010 Sencha Inc. + * Copyright(c) 2011 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Log buffer. + */ + +var buf = []; + +/** + * Default log buffer duration. + */ + +var defaultBufferDuration = 1000; + +/** + * Log requests with the given `options` or a `format` string. + * + * Options: + * + * - `format` Format string, see below for tokens + * - `stream` Output stream, defaults to _stdout_ + * - `buffer` Buffer duration, defaults to 1000ms when _true_ + * - `immediate` Write log line on request instead of response (for response times) + * + * Tokens: + * + * - `:req[header]` ex: `:req[Accept]` + * - `:res[header]` ex: `:res[Content-Length]` + * - `:http-version` + * - `:response-time` + * - `:remote-addr` + * - `:date` + * - `:method` + * - `:url` + * - `:referrer` + * - `:user-agent` + * - `:status` + * + * Formats: + * + * Pre-defined formats that ship with connect: + * + * - `default` ':remote-addr - - [:date] ":method :url HTTP/:http-version" :status :res[content-length] ":referrer" ":user-agent"' + * - `short` ':remote-addr - :method :url HTTP/:http-version :status :res[content-length] - :response-time ms' + * - `tiny` ':method :url :status :res[content-length] - :response-time ms' + * - `dev` concise output colored by response status for development use + * + * Examples: + * + * connect.logger() // default + * connect.logger('short') + * connect.logger('tiny') + * connect.logger('dev') + * connect.logger(':method :url - :referrer') + * connect.logger(':req[content-type] -> :res[content-type]') + * connect.logger(function(req, res){ return 'some format string' }) + * + * Defining Tokens: + * + * To define a token, simply invoke `connect.logger.token()` with the + * name and a callback function. The value returned is then available + * as ":type" in this case. + * + * connect.logger.token('type', function(req, res){ return req.headers['content-type']; }) + * + * Defining Formats: + * + * All default formats are defined this way, however it's public API as well: + * + * connect.logger.format('name', 'string or function') + * + * @param {String|Function|Object} format or options + * @return {Function} + * @api public + */ + +exports = module.exports = function logger(options) { + if ('object' == typeof options) { + options = options || {}; + } else if (options) { + options = { format: options }; + } else { + options = {}; + } + + // output on request instead of response + var immediate = options.immediate; + + // format name + var fmt = exports[options.format] || options.format || exports.default; + + // compile format + if ('function' != typeof fmt) fmt = compile(fmt); + + // options + var stream = options.stream || process.stdout + , buffer = options.buffer; + + // buffering support + if (buffer) { + var realStream = stream + , interval = 'number' == typeof buffer + ? buffer + : defaultBufferDuration; + + // flush interval + setInterval(function(){ + if (buf.length) { + realStream.write(buf.join(''), 'ascii'); + buf.length = 0; + } + }, interval); + + // swap the stream + stream = { + write: function(str){ + buf.push(str); + } + }; + } + + return function logger(req, res, next) { + req._startTime = new Date; + + // mount safety + if (req._logging) return next(); + + // flag as logging + req._logging = true; + + // immediate + if (immediate) { + var line = fmt(exports, req, res); + if (null == line) return; + stream.write(line + '\n', 'ascii'); + } else { + // proxy end to output loggging + var end = res.end; + res.end = function(chunk, encoding){ + res.end = end; + res.end(chunk, encoding); + var line = fmt(exports, req, res); + if (null == line) return; + stream.write(line + '\n', 'ascii'); + }; + } + + + next(); + }; +}; + +/** + * Compile `fmt` into a function. + * + * @param {String} fmt + * @return {Function} + * @api private + */ + +function compile(fmt) { + fmt = fmt.replace(/"/g, '\\"'); + var js = ' return "' + fmt.replace(/:([-\w]{2,})(?:\[([^\]]+)\])?/g, function(_, name, arg){ + return '"\n + (tokens["' + name + '"](req, res, "' + arg + '") || "-") + "'; + }) + '";' + return new Function('tokens, req, res', js); +}; + +/** + * Define a token function with the given `name`, + * and callback `fn(req, res)`. + * + * @param {String} name + * @param {Function} fn + * @return {Object} exports for chaining + * @api public + */ + +exports.token = function(name, fn) { + exports[name] = fn; + return this; +}; + +/** + * Define a `fmt` with the given `name`. + * + * @param {String} name + * @param {String|Function} fmt + * @return {Object} exports for chaining + * @api public + */ + +exports.format = function(name, str){ + exports[name] = str; + return this; +}; + +// default format + +exports.format('default', ':remote-addr - - [:date] ":method :url HTTP/:http-version" :status :res[content-length] ":referrer" ":user-agent"'); + +// short format + +exports.format('short', ':remote-addr - :method :url HTTP/:http-version :status :res[content-length] - :response-time ms'); + +// tiny format + +exports.format('tiny', ':method :url :status :res[content-length] - :response-time ms'); + +// dev (colored) + +exports.format('dev', function(tokens, req, res){ + var status = res.statusCode + , color = 32; + + if (status >= 500) color = 31 + else if (status >= 400) color = 33 + else if (status >= 300) color = 36; + + return '\033[90m' + req.method + + ' ' + req.originalUrl + ' ' + + '\033[' + color + 'm' + res.statusCode + + ' \033[90m' + + (new Date - req._startTime) + + 'ms\033[0m'; +}); + +// request url + +exports.token('url', function(req){ + return req.originalUrl; +}); + +// request method + +exports.token('method', function(req){ + return req.method; +}); + +// response time in milliseconds + +exports.token('response-time', function(req){ + return new Date - req._startTime; +}); + +// UTC date + +exports.token('date', function(){ + return new Date().toUTCString(); +}); + +// response status code + +exports.token('status', function(req, res){ + return res.statusCode; +}); + +// normalized referrer + +exports.token('referrer', function(req){ + return req.headers['referer'] || req.headers['referrer']; +}); + +// remote address + +exports.token('remote-addr', function(req){ + return req.socket && (req.socket.remoteAddress || (req.socket.socket && req.socket.socket.remoteAddress)); +}); + +// HTTP version + +exports.token('http-version', function(req){ + return req.httpVersionMajor + '.' + req.httpVersionMinor; +}); + +// UA string + +exports.token('user-agent', function(req){ + return req.headers['user-agent']; +}); + +// request header + +exports.token('req', function(req, res, field){ + return req.headers[field.toLowerCase()]; +}); + +// response header + +exports.token('res', function(req, res, field){ + return (res._headers || {})[field.toLowerCase()]; +}); + diff --git a/node_modules/express/node_modules/connect/lib/middleware/methodOverride.js b/node_modules/express/node_modules/connect/lib/middleware/methodOverride.js new file mode 100644 index 0000000..db4e9f3 --- /dev/null +++ b/node_modules/express/node_modules/connect/lib/middleware/methodOverride.js @@ -0,0 +1,38 @@ + +/*! + * Connect - methodOverride + * Copyright(c) 2010 Sencha Inc. + * Copyright(c) 2011 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Provides faux HTTP method support. + * + * Pass an optional `key` to use when checking for + * a method override, othewise defaults to _\_method_. + * The original method is available via `req.originalMethod`. + * + * @param {String} key + * @return {Function} + * @api public + */ + +module.exports = function methodOverride(key){ + key = key || "_method"; + return function methodOverride(req, res, next) { + req.originalMethod = req.originalMethod || req.method; + + // req.body + if (req.body && key in req.body) { + req.method = req.body[key].toUpperCase(); + delete req.body[key]; + // check X-HTTP-Method-Override + } else if (req.headers['x-http-method-override']) { + req.method = req.headers['x-http-method-override'].toUpperCase(); + } + + next(); + }; +}; + diff --git a/node_modules/express/node_modules/connect/lib/middleware/profiler.js b/node_modules/express/node_modules/connect/lib/middleware/profiler.js new file mode 100644 index 0000000..b0b5bac --- /dev/null +++ b/node_modules/express/node_modules/connect/lib/middleware/profiler.js @@ -0,0 +1,100 @@ + +/*! + * Connect - profiler + * Copyright(c) 2011 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Profile the duration of a request. + * + * Typically this middleware should be utilized + * _above_ all others, as it proxies the `res.end()` + * method, being first allows it to encapsulate all + * other middleware. + * + * Example Output: + * + * GET / + * response time 2ms + * memory rss 52.00kb + * memory vsize 2.07mb + * heap before 3.76mb / 8.15mb + * heap after 3.80mb / 8.15mb + * + * @api public + */ + +module.exports = function profiler(){ + return function(req, res, next){ + var end = res.end + , start = snapshot(); + + // state snapshot + function snapshot() { + return { + mem: process.memoryUsage() + , time: new Date + }; + } + + // proxy res.end() + res.end = function(data, encoding){ + res.end = end; + res.end(data, encoding); + compare(req, start, snapshot()) + }; + + next(); + } +}; + +/** + * Compare `start` / `end` snapshots. + * + * @param {IncomingRequest} req + * @param {Object} start + * @param {Object} end + * @api private + */ + +function compare(req, start, end) { + console.log(); + row(req.method, req.url); + row('response time:', (end.time - start.time) + 'ms'); + row('memory rss:', formatBytes(end.mem.rss - start.mem.rss)); + row('memory vsize:', formatBytes(end.mem.vsize - start.mem.vsize)); + row('heap before:', formatBytes(start.mem.heapUsed) + ' / ' + formatBytes(start.mem.heapTotal)); + row('heap after:', formatBytes(end.mem.heapUsed) + ' / ' + formatBytes(end.mem.heapTotal)); + console.log(); +} + +/** + * Row helper + * + * @param {String} key + * @param {String} val + * @api private + */ + +function row(key, val) { + console.log(' \033[90m%s\033[0m \033[36m%s\033[0m', key, val); +} + +/** + * Format byte-size. + * + * @param {Number} bytes + * @return {String} + * @api private + */ + +function formatBytes(bytes) { + var kb = 1024 + , mb = 1024 * kb + , gb = 1024 * mb; + if (bytes < kb) return bytes + 'b'; + if (bytes < mb) return (bytes / kb).toFixed(2) + 'kb'; + if (bytes < gb) return (bytes / mb).toFixed(2) + 'mb'; + return (bytes / gb).toFixed(2) + 'gb'; +}; diff --git a/node_modules/express/node_modules/connect/lib/middleware/query.js b/node_modules/express/node_modules/connect/lib/middleware/query.js new file mode 100644 index 0000000..d3b1acd --- /dev/null +++ b/node_modules/express/node_modules/connect/lib/middleware/query.js @@ -0,0 +1,40 @@ + +/*! + * Connect - query + * Copyright(c) 2011 TJ Holowaychuk + * Copyright(c) 2011 Sencha Inc. + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var qs = require('qs') + , parse = require('url').parse; + +/** + * Automatically parse the query-string when available, + * populating the `req.query` object. + * + * Examples: + * + * connect( + * connect.query() + * , function(req, res){ + * res.end(JSON.stringify(req.query)); + * } + * ).listen(3000); + * + * @return {Function} + * @api public + */ + +module.exports = function query(){ + return function query(req, res, next){ + req.query = ~req.url.indexOf('?') + ? qs.parse(parse(req.url).query) + : {}; + next(); + }; +}; diff --git a/node_modules/express/node_modules/connect/lib/middleware/responseTime.js b/node_modules/express/node_modules/connect/lib/middleware/responseTime.js new file mode 100644 index 0000000..2b2133a --- /dev/null +++ b/node_modules/express/node_modules/connect/lib/middleware/responseTime.js @@ -0,0 +1,34 @@ + +/*! + * Connect - responseTime + * Copyright(c) 2011 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Adds the `X-Response-Time` header displaying the response + * duration in milliseconds. + * + * @return {Function} + * @api public + */ + +module.exports = function responseTime(){ + return function(req, res, next){ + var writeHead = res.writeHead + , start = new Date; + + if (res._responseTime) return next(); + res._responseTime = true; + + // proxy writeHead to calculate duration + res.writeHead = function(status, headers){ + var duration = new Date - start; + res.setHeader('X-Response-Time', duration + 'ms'); + res.writeHead = writeHead; + res.writeHead(status, headers); + }; + + next(); + }; +}; diff --git a/node_modules/express/node_modules/connect/lib/middleware/router.js b/node_modules/express/node_modules/connect/lib/middleware/router.js new file mode 100644 index 0000000..a07452e --- /dev/null +++ b/node_modules/express/node_modules/connect/lib/middleware/router.js @@ -0,0 +1,379 @@ + +/*! + * Connect - router + * Copyright(c) 2010 Sencha Inc. + * Copyright(c) 2011 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var utils = require('../utils') + , parse = require('url').parse; + +/** + * Expose router. + */ + +exports = module.exports = router; + +/** + * Supported HTTP / WebDAV methods. + */ + +var _methods = exports.methods = [ + 'get' + , 'post' + , 'put' + , 'delete' + , 'connect' + , 'options' + , 'trace' + , 'copy' + , 'lock' + , 'mkcol' + , 'move' + , 'propfind' + , 'proppatch' + , 'unlock' + , 'report' + , 'mkactivity' + , 'checkout' + , 'merge' +]; + +/** + * Provides Sinatra and Express-like routing capabilities. + * + * Examples: + * + * connect.router(function(app){ + * app.get('/user/:id', function(req, res, next){ + * // populates req.params.id + * }); + * app.put('/user/:id', function(req, res, next){ + * // populates req.params.id + * }); + * }) + * + * @param {Function} fn + * @return {Function} + * @api public + */ + +function router(fn){ + var self = this + , methods = {} + , routes = {} + , params = {}; + + if (!fn) throw new Error('router provider requires a callback function'); + + // Generate method functions + _methods.forEach(function(method){ + methods[method] = generateMethodFunction(method.toUpperCase()); + }); + + // Alias del -> delete + methods.del = methods.delete; + + // Apply callback to all methods + methods.all = function(){ + var args = arguments; + _methods.forEach(function(name){ + methods[name].apply(this, args); + }); + return self; + }; + + // Register param callback + methods.param = function(name, fn){ + params[name] = fn; + }; + + fn.call(this, methods); + + function generateMethodFunction(name) { + var localRoutes = routes[name] = routes[name] || []; + return function(path, fn){ + var keys = [] + , middleware = []; + + // slice middleware + if (arguments.length > 2) { + middleware = Array.prototype.slice.call(arguments, 1, arguments.length); + fn = middleware.pop(); + middleware = utils.flatten(middleware); + } + + fn.middleware = middleware; + + if (!path) throw new Error(name + ' route requires a path'); + if (!fn) throw new Error(name + ' route ' + path + ' requires a callback'); + var regexp = path instanceof RegExp + ? path + : normalizePath(path, keys); + localRoutes.push({ + fn: fn + , path: regexp + , keys: keys + , orig: path + , method: name + }); + return self; + }; + } + + function router(req, res, next){ + var route + , self = this; + + (function pass(i){ + if (route = match(req, routes, i)) { + var i = 0 + , keys = route.keys; + + req.params = route.params; + + // Param preconditions + (function param(err) { + try { + var key = keys[i++] + , val = req.params[key] + , fn = params[key]; + + if ('route' == err) { + pass(req._route_index + 1); + // Error + } else if (err) { + next(err); + // Param has callback + } else if (fn) { + // Return style + if (1 == fn.length) { + req.params[key] = fn(val); + param(); + // Middleware style + } else { + fn(req, res, param, val); + } + // Finished processing params + } else if (!key) { + // route middleware + i = 0; + (function nextMiddleware(err){ + var fn = route.middleware[i++]; + if ('route' == err) { + pass(req._route_index + 1); + } else if (err) { + next(err); + } else if (fn) { + fn(req, res, nextMiddleware); + } else { + route.call(self, req, res, function(err){ + if (err) { + next(err); + } else { + pass(req._route_index + 1); + } + }); + } + })(); + // More params + } else { + param(); + } + } catch (err) { + next(err); + } + })(); + } else if ('OPTIONS' == req.method) { + options(req, res, routes); + } else { + next(); + } + })(); + }; + + router.remove = function(path, method){ + var fns = router.lookup(path, method); + fns.forEach(function(fn){ + routes[fn.method].splice(fn.index, 1); + }); + }; + + router.lookup = function(path, method, ret){ + ret = ret || []; + + // method specific lookup + if (method) { + method = method.toUpperCase(); + if (routes[method]) { + routes[method].forEach(function(route, i){ + if (path == route.orig) { + var fn = route.fn; + fn.regexp = route.path; + fn.keys = route.keys; + fn.path = route.orig; + fn.method = route.method; + fn.index = i; + ret.push(fn); + } + }); + } + // global lookup + } else { + _methods.forEach(function(method){ + router.lookup(path, method, ret); + }); + } + + return ret; + }; + + router.match = function(url, method, ret){ + var ret = ret || [] + , i = 0 + , fn + , req; + + // method specific matches + if (method) { + method = method.toUpperCase(); + req = { url: url, method: method }; + while (fn = match(req, routes, i)) { + i = req._route_index + 1; + ret.push(fn); + } + // global matches + } else { + _methods.forEach(function(method){ + router.match(url, method, ret); + }); + } + + return ret; + }; + + return router; +} + +/** + * Respond to OPTIONS. + * + * @param {ServerRequest} req + * @param {ServerResponse} req + * @param {Array} routes + * @api private + */ + +function options(req, res, routes) { + var pathname = parse(req.url).pathname + , body = optionsFor(pathname, routes).join(','); + res.writeHead(200, { + 'Content-Length': body.length + , 'Allow': body + }); + res.end(body); +} + +/** + * Return OPTIONS array for the given `path`, matching `routes`. + * + * @param {String} path + * @param {Array} routes + * @return {Array} + * @api private + */ + +function optionsFor(path, routes) { + return _methods.filter(function(method){ + var arr = routes[method.toUpperCase()]; + for (var i = 0, len = arr.length; i < len; ++i) { + if (arr[i].path.test(path)) return true; + } + }).map(function(method){ + return method.toUpperCase(); + }); +} + +/** + * Normalize the given path string, + * returning a regular expression. + * + * An empty array should be passed, + * which will contain the placeholder + * key names. For example "/user/:id" will + * then contain ["id"]. + * + * @param {String} path + * @param {Array} keys + * @return {RegExp} + * @api private + */ + +function normalizePath(path, keys) { + path = path + .concat('/?') + .replace(/\/\(/g, '(?:/') + .replace(/(\/)?(\.)?:(\w+)(?:(\(.*?\)))?(\?)?/g, function(_, slash, format, key, capture, optional){ + keys.push(key); + slash = slash || ''; + return '' + + (optional ? '' : slash) + + '(?:' + + (optional ? slash : '') + + (format || '') + (capture || '([^/]+?)') + ')' + + (optional || ''); + }) + .replace(/([\/.])/g, '\\$1') + .replace(/\*/g, '(.+)'); + return new RegExp('^' + path + '$', 'i'); +} + +/** + * Attempt to match the given request to + * one of the routes. When successful + * a route function is returned. + * + * @param {ServerRequest} req + * @param {Object} routes + * @return {Function} + * @api private + */ + +function match(req, routes, i) { + var captures + , method = req.method + , i = i || 0; + if ('HEAD' == method) method = 'GET'; + if (routes = routes[method]) { + var url = parse(req.url) + , pathname = url.pathname; + for (var len = routes.length; i < len; ++i) { + var route = routes[i] + , fn = route.fn + , path = route.path + , keys = fn.keys = route.keys; + if (captures = path.exec(pathname)) { + fn.method = method; + fn.params = []; + for (var j = 1, len = captures.length; j < len; ++j) { + var key = keys[j-1], + val = typeof captures[j] === 'string' + ? decodeURIComponent(captures[j]) + : captures[j]; + if (key) { + fn.params[key] = val; + } else { + fn.params.push(val); + } + } + req._route_index = i; + return fn; + } + } + } +} diff --git a/node_modules/express/node_modules/connect/lib/middleware/session.js b/node_modules/express/node_modules/connect/lib/middleware/session.js new file mode 100644 index 0000000..7fbeb18 --- /dev/null +++ b/node_modules/express/node_modules/connect/lib/middleware/session.js @@ -0,0 +1,346 @@ + +/*! + * Connect - session + * Copyright(c) 2010 Sencha Inc. + * Copyright(c) 2011 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var Session = require('./session/session') + , MemoryStore = require('./session/memory') + , Cookie = require('./session/cookie') + , Store = require('./session/store') + , utils = require('./../utils') + , parse = require('url').parse + , crypto = require('crypto'); + +// environment + +var env = process.env.NODE_ENV; + +/** + * Expose the middleware. + */ + +exports = module.exports = session; + +/** + * Expose constructors. + */ + +exports.Store = Store; +exports.Cookie = Cookie; +exports.Session = Session; +exports.MemoryStore = MemoryStore; + +/** + * Warning message for `MemoryStore` usage in production. + */ + +var warning = 'Warning: connection.session() MemoryStore is not\n' + + 'designed for a production environment, as it will leak\n' + + 'memory, and obviously only work within a single process.'; + +/** + * Default finger-printing function. + */ + +function defaultFingerprint(req) { + var ua = req.headers['user-agent'] || ''; + return ua.replace(/;?\schromeframe\/[\d\.]+/, ''); +}; + +/** + * Paths to ignore. + */ + +exports.ignore = []; + +/** + * Setup session store with the given `options`. + * + * Session data is _not_ saved in the cookie itself, however + * cookies are used, so we must use the [cookieParser()](middleware-cookieParser.html) + * middleware _before_ `session()`. + * + * Examples: + * + * connect.createServer( + * connect.cookieParser() + * , connect.session({ secret: 'keyboard cat' }) + * ); + * + * Options: + * + * - `key` cookie name defaulting to `connect.sid` + * - `store` Session store instance + * - `fingerprint` Custom fingerprint generating function + * - `cookie` Session cookie settings, defaulting to `{ path: '/', httpOnly: true, maxAge: 14400000 }` + * - `secret` Secret string used to compute hash + * + * Ignore Paths: + * + * By default `/favicon.ico` is the only ignored path, all others + * will utilize sessions, to manipulate the paths ignored, use + * `connect.session.ignore.push('/my/path')`. This works for _full_ + * pathnames only, not segments nor substrings. + * + * connect.session.ignore.push('/robots.txt'); + * + * ## req.session + * + * To store or access session data, simply use the request property `req.session`, + * which is (generally) serialized as JSON by the store, so nested objects + * are typically fine. For example below is a user-specific view counter: + * + * connect( + * connect.cookieParser() + * , connect.session({ secret: 'keyboard cat', cookie: { maxAge: 60000 }}) + * , connect.favicon() + * , function(req, res, next){ + * var sess = req.session; + * if (sess.views) { + * res.setHeader('Content-Type', 'text/html'); + * res.write('

    views: ' + sess.views + '

    '); + * res.write('

    expires in: ' + (sess.cookie.maxAge / 1000) + 's

    '); + * res.end(); + * sess.views++; + * } else { + * sess.views = 1; + * res.end('welcome to the session demo. refresh!'); + * } + * } + * ).listen(3000); + * + * ## Session#regenerate() + * + * To regenerate the session simply invoke the method, once complete + * a new SID and `Session` instance will be initialized at `req.session`. + * + * req.session.regenerate(function(err){ + * // will have a new session here + * }); + * + * ## Session#destroy() + * + * Destroys the session, removing `req.session`, will be re-generated next request. + * + * req.session.destroy(function(err){ + * // cannot access session here + * }); + * + * ## Session#reload() + * + * Reloads the session data. + * + * req.session.reload(function(err){ + * // session updated + * }); + * + * ## Session#save() + * + * Save the session. + * + * req.session.save(function(err){ + * // session saved + * }); + * + * ## Session#touch() + * + * Updates the `.maxAge`, and `.lastAccess` properties. Typically this is + * not necessary to call, as the session middleware does this for you. + * + * ## Session#cookie + * + * Each session has a unique cookie object accompany it. This allows + * you to alter the session cookie per visitor. For example we can + * set `req.session.cookie.expires` to `false` to enable the cookie + * to remain for only the duration of the user-agent. + * + * ## Session#maxAge + * + * Alternatively `req.session.cookie.maxAge` will return the time + * remaining in milliseconds, which we may also re-assign a new value + * to adjust the `.expires` property appropriately. The following + * are essentially equivalent + * + * var hour = 3600000; + * req.session.cookie.expires = new Date(Date.now() + hour); + * req.session.cookie.maxAge = hour; + * + * For example when `maxAge` is set to `60000` (one minute), and 30 seconds + * has elapsed it will return `30000` until the current request has completed, + * at which time `req.session.touch()` is called to update `req.session.lastAccess`, + * and reset `req.session.maxAge` to its original value. + * + * req.session.cookie.maxAge; + * // => 30000 + * + * Session Store Implementation: + * + * Every session store _must_ implement the following methods + * + * - `.get(sid, callback)` + * - `.set(sid, session, callback)` + * - `.destroy(sid, callback)` + * + * Recommended methods include, but are not limited to: + * + * - `.length(callback)` + * - `.clear(callback)` + * + * For an example implementation view the [connect-redis](http://github.com/visionmedia/connect-redis) repo. + * + * @param {Object} options + * @return {Function} + * @api public + */ + +function session(options){ + var options = options || {} + , key = options.key || 'connect.sid' + , secret = options.secret + , store = options.store || new MemoryStore + , fingerprint = options.fingerprint || defaultFingerprint + , cookie = options.cookie; + + // notify user that this store is not + // meant for a production environment + if ('production' == env && store instanceof MemoryStore) { + console.warn(warning); + } + + // ensure secret is present + if (!secret) { + throw new Error('connect.session({ secret: "string" }) required for security'); + } + + // session hashing function + store.hash = function(req, base) { + return crypto + .createHmac('sha256', secret) + .update(base + fingerprint(req)) + .digest('base64') + .replace(/=*$/, ''); + }; + + // generates the new session + store.generate = function(req){ + var base = utils.uid(24); + var sessionID = base + '.' + store.hash(req, base); + req.sessionID = sessionID; + req.session = new Session(req); + req.session.cookie = new Cookie(cookie); + }; + + return function session(req, res, next) { + // self-awareness + if (req.session) return next(); + + // parse url + var url = parse(req.url) + , path = url.pathname; + + // ignorable paths + if (~exports.ignore.indexOf(path)) return next(); + + // expose store + req.sessionStore = store; + + // proxy writeHead() to Set-Cookie + var writeHead = res.writeHead; + res.writeHead = function(status, headers){ + if (req.session) { + var cookie = req.session.cookie; + // only send secure session cookies when there is a secure connection. + // proxySecure is a custom attribute to allow for a reverse proxy + // to handle SSL connections and to communicate to connect over HTTP that + // the incoming connection is secure. + var secured = cookie.secure && (req.connection.encrypted || req.connection.proxySecure); + if (secured || !cookie.secure) { + res.setHeader('Set-Cookie', cookie.serialize(key, req.sessionID)); + } + } + + res.writeHead = writeHead; + return res.writeHead(status, headers); + }; + + // proxy end() to commit the session + var end = res.end; + res.end = function(data, encoding){ + res.end = end; + if (req.session) { + // HACK: ensure Set-Cookie for implicit writeHead() + if (!res._header) res._implicitHeader(); + req.session.resetMaxAge(); + req.session.save(function(){ + res.end(data, encoding); + }); + } else { + res.end(data, encoding); + } + }; + + // session hashing + function hash(base) { + return store.hash(req, base); + } + + // generate the session + function generate() { + store.generate(req); + } + + // get the sessionID from the cookie + req.sessionID = req.cookies[key]; + + // make a new session if the browser doesn't send a sessionID + if (!req.sessionID) { + generate(); + next(); + return; + } + + // check the fingerprint + var parts = req.sessionID.split('.'); + if (parts[1] != hash(parts[0])) { + generate(); + next(); + return; + } + + // generate the session object + var pause = utils.pause(req); + store.get(req.sessionID, function(err, sess){ + // proxy to resume() events + var _next = next; + next = function(err){ + _next(err); + pause.resume(); + } + + // error handling + if (err) { + if ('ENOENT' == err.code) { + generate(); + next(); + } else { + next(err); + } + // no session + } else if (!sess) { + generate(); + next(); + // populate req.session + } else { + store.createSession(req, sess); + next(); + } + }); + }; +}; diff --git a/node_modules/express/node_modules/connect/lib/middleware/session/cookie.js b/node_modules/express/node_modules/connect/lib/middleware/session/cookie.js new file mode 100644 index 0000000..793c2e9 --- /dev/null +++ b/node_modules/express/node_modules/connect/lib/middleware/session/cookie.js @@ -0,0 +1,126 @@ + +/*! + * Connect - session - Cookie + * Copyright(c) 2010 Sencha Inc. + * Copyright(c) 2011 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var utils = require('../../utils'); + +/** + * Initialize a new `Cookie` with the given `options`. + * + * @param {Object} options + * @api private + */ + +var Cookie = module.exports = function Cookie(options) { + this.path = '/'; + this.httpOnly = true; + this.maxAge = 14400000; + if (options) utils.merge(this, options); + this.originalMaxAge = undefined == this.originalMaxAge + ? this.maxAge + : this.originalMaxAge; +}; + +/** + * Prototype. + */ + +Cookie.prototype = { + + /** + * Set expires `date`. + * + * @param {Date} date + * @api public + */ + + set expires(date) { + this._expires = date; + this.originalMaxAge = this.maxAge; + }, + + /** + * Get expires `date`. + * + * @return {Date} + * @api public + */ + + get expires() { + return this._expires; + }, + + /** + * Set expires via max-age in `ms`. + * + * @param {Number} ms + * @api public + */ + + set maxAge(ms) { + this.expires = 'number' == typeof ms + ? new Date(Date.now() + ms) + : ms; + }, + + /** + * Get expires max-age in `ms`. + * + * @return {Number} + * @api public + */ + + get maxAge() { + return this.expires instanceof Date + ? this.expires.valueOf() - Date.now() + : this.expires; + }, + + /** + * Return cookie data object. + * + * @return {Object} + * @api private + */ + + get data() { + return { + originalMaxAge: this.originalMaxAge + , expires: this._expires + , secure: this.secure + , httpOnly: this.httpOnly + , domain: this.domain + , path: this.path + } + }, + + /** + * Return a serialized cookie string. + * + * @return {String} + * @api public + */ + + serialize: function(name, val){ + return utils.serializeCookie(name, val, this.data); + }, + + /** + * Return JSON representation of this cookie. + * + * @return {Object} + * @api private + */ + + toJSON: function(){ + return this.data; + } +}; diff --git a/node_modules/express/node_modules/connect/lib/middleware/session/memory.js b/node_modules/express/node_modules/connect/lib/middleware/session/memory.js new file mode 100644 index 0000000..ec569f5 --- /dev/null +++ b/node_modules/express/node_modules/connect/lib/middleware/session/memory.js @@ -0,0 +1,131 @@ + +/*! + * Connect - session - MemoryStore + * Copyright(c) 2010 Sencha Inc. + * Copyright(c) 2011 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var Store = require('./store') + , utils = require('../../utils') + , Session = require('./session'); + +/** + * Initialize a new `MemoryStore`. + * + * @api public + */ + +var MemoryStore = module.exports = function MemoryStore() { + this.sessions = {}; +}; + +/** + * Inherit from `Store.prototype`. + */ + +MemoryStore.prototype.__proto__ = Store.prototype; + +/** + * Attempt to fetch session by the given `sid`. + * + * @param {String} sid + * @param {Function} fn + * @api public + */ + +MemoryStore.prototype.get = function(sid, fn){ + var self = this; + process.nextTick(function(){ + var expires + , sess = self.sessions[sid]; + if (sess) { + sess = JSON.parse(sess); + expires = 'string' == typeof sess.cookie.expires + ? new Date(sess.cookie.expires) + : sess.cookie.expires; + if (!expires || new Date < expires) { + fn(null, sess); + } else { + self.destroy(sid, fn); + } + } else { + fn(); + } + }); +}; + +/** + * Commit the given `sess` object associated with the given `sid`. + * + * @param {String} sid + * @param {Session} sess + * @param {Function} fn + * @api public + */ + +MemoryStore.prototype.set = function(sid, sess, fn){ + var self = this; + process.nextTick(function(){ + self.sessions[sid] = JSON.stringify(sess); + fn && fn(); + }); +}; + +/** + * Destroy the session associated with the given `sid`. + * + * @param {String} sid + * @api public + */ + +MemoryStore.prototype.destroy = function(sid, fn){ + var self = this; + process.nextTick(function(){ + delete self.sessions[sid]; + fn && fn(); + }); +}; + +/** + * Invoke the given callback `fn` with all active sessions. + * + * @param {Function} fn + * @api public + */ + +MemoryStore.prototype.all = function(fn){ + var arr = [] + , keys = Object.keys(this.sessions); + for (var i = 0, len = keys.length; i < len; ++i) { + arr.push(this.sessions[keys[i]]); + } + fn(null, arr); +}; + +/** + * Clear all sessions. + * + * @param {Function} fn + * @api public + */ + +MemoryStore.prototype.clear = function(fn){ + this.sessions = {}; + fn && fn(); +}; + +/** + * Fetch number of sessions. + * + * @param {Function} fn + * @api public + */ + +MemoryStore.prototype.length = function(fn){ + fn(null, Object.keys(this.sessions).length); +}; diff --git a/node_modules/express/node_modules/connect/lib/middleware/session/session.js b/node_modules/express/node_modules/connect/lib/middleware/session/session.js new file mode 100644 index 0000000..4e7e1a6 --- /dev/null +++ b/node_modules/express/node_modules/connect/lib/middleware/session/session.js @@ -0,0 +1,137 @@ + +/*! + * Connect - session - Session + * Copyright(c) 2010 Sencha Inc. + * Copyright(c) 2011 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var utils = require('../../utils') + , Cookie = require('./cookie'); + +/** + * Create a new `Session` with the given request and `data`. + * + * @param {IncomingRequest} req + * @param {Object} data + * @api private + */ + +var Session = module.exports = function Session(req, data) { + Object.defineProperty(this, 'req', { value: req }); + Object.defineProperty(this, 'id', { value: req.sessionID }); + if ('object' == typeof data) { + utils.merge(this, data); + } else { + this.lastAccess = Date.now(); + } +}; + +/** + * Update `.lastAccess` timestamp, + * and reset `.cookie.maxAge` to prevent + * the cookie from expiring when the + * session is still active. + * + * @return {Session} for chaining + * @api public + */ + +Session.prototype.touch = function(){ + return this + .resetLastAccess() + .resetMaxAge(); +}; + +/** + * Update `.lastAccess` timestamp. + * + * @return {Session} for chaining + * @api public + */ + +Session.prototype.resetLastAccess = function(){ + this.lastAccess = Date.now(); + return this; +}; + +/** + * Reset `.maxAge` to `.originalMaxAge`. + * + * @return {Session} for chaining + * @api public + */ + +Session.prototype.resetMaxAge = function(){ + this.cookie.maxAge = this.cookie.originalMaxAge; + return this; +}; + +/** + * Save the session data with optional callback `fn(err)`. + * + * @param {Function} fn + * @return {Session} for chaining + * @api public + */ + +Session.prototype.save = function(fn){ + this.req.sessionStore.set(this.id, this, fn || function(){}); + return this; +}; + +/** + * Re-loads the session data _without_ altering + * the maxAge or lastAccess properties. Invokes the + * callback `fn(err)`, after which time if no exception + * has occurred the `req.session` property will be + * a new `Session` object, although representing the + * same session. + * + * @param {Function} fn + * @return {Session} for chaining + * @api public + */ + +Session.prototype.reload = function(fn){ + var req = this.req + , store = this.req.sessionStore; + store.get(this.id, function(err, sess){ + if (err) return fn(err); + if (!sess) return fn(new Error('failed to load session')); + store.createSession(req, sess); + fn(); + }); + return this; +}; + +/** + * Destroy `this` session. + * + * @param {Function} fn + * @return {Session} for chaining + * @api public + */ + +Session.prototype.destroy = function(fn){ + delete this.req.session; + this.req.sessionStore.destroy(this.id, fn); + return this; +}; + +/** + * Regenerate this request's session. + * + * @param {Function} fn + * @return {Session} for chaining + * @api public + */ + +Session.prototype.regenerate = function(fn){ + this.req.sessionStore.regenerate(this.req, fn); + return this; +}; diff --git a/node_modules/express/node_modules/connect/lib/middleware/session/store.js b/node_modules/express/node_modules/connect/lib/middleware/session/store.js new file mode 100644 index 0000000..6a3d47d --- /dev/null +++ b/node_modules/express/node_modules/connect/lib/middleware/session/store.js @@ -0,0 +1,87 @@ + +/*! + * Connect - session - Store + * Copyright(c) 2010 Sencha Inc. + * Copyright(c) 2011 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var EventEmitter = require('events').EventEmitter + , Session = require('./session') + , Cookie = require('./cookie') + , utils = require('../../utils'); + +/** + * Initialize abstract `Store`. + * + * @api private + */ + +var Store = module.exports = function Store(options){}; + +/** + * Inherit from `EventEmitter.prototype`. + */ + +Store.prototype.__proto__ = EventEmitter.prototype; + +/** + * Re-generate the given requests's session. + * + * @param {IncomingRequest} req + * @return {Function} fn + * @api public + */ + +Store.prototype.regenerate = function(req, fn){ + var self = this; + this.destroy(req.sessionID, function(err){ + self.generate(req); + fn(err); + }); +}; + +/** + * Load a `Session` instance via the given `sid` + * and invoke the callback `fn(err, sess)`. + * + * @param {String} sid + * @param {Function} fn + * @api public + */ + +Store.prototype.load = function(sid, fn){ + var self = this; + this.get(sid, function(err, sess){ + if (err) return fn(err); + if (!sess) return fn(); + var req = { sessionID: sid, sessionStore: self }; + sess = self.createSession(req, sess, false); + fn(null, sess); + }); +}; + +/** + * Create session from JSON `sess` data. + * + * @param {IncomingRequest} req + * @param {Object} sess + * @return {Session} + * @api private + */ + +Store.prototype.createSession = function(req, sess, update){ + var expires = sess.cookie.expires + , orig = sess.cookie.originalMaxAge + , update = null == update ? true : false; + sess.cookie = new Cookie(sess.cookie); + if ('string' == typeof expires) sess.cookie.expires = new Date(expires); + sess.cookie.originalMaxAge = orig; + req.session = new Session(req, sess); + if (update) req.session.resetLastAccess(); + return req.session; +}; \ No newline at end of file diff --git a/node_modules/express/node_modules/connect/lib/middleware/static.js b/node_modules/express/node_modules/connect/lib/middleware/static.js new file mode 100644 index 0000000..df5fd92 --- /dev/null +++ b/node_modules/express/node_modules/connect/lib/middleware/static.js @@ -0,0 +1,225 @@ + +/*! + * Connect - staticProvider + * Copyright(c) 2010 Sencha Inc. + * Copyright(c) 2011 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var fs = require('fs') + , path = require('path') + , join = path.join + , basename = path.basename + , normalize = path.normalize + , utils = require('../utils') + , Buffer = require('buffer').Buffer + , parse = require('url').parse + , mime = require('mime'); + +/** + * Static file server with the given `root` path. + * + * Examples: + * + * var oneDay = 86400000; + * + * connect( + * connect.static(__dirname + '/public') + * ).listen(3000); + * + * connect( + * connect.static(__dirname + '/public', { maxAge: oneDay }) + * ).listen(3000); + * + * Options: + * + * - `maxAge` Browser cache maxAge in milliseconds. defaults to 0 + * - `hidden` Allow transfer of hidden files. defaults to false + * - `redirect` Redirect to trailing "/" when the pathname is a dir + * + * @param {String} root + * @param {Object} options + * @return {Function} + * @api public + */ + +exports = module.exports = function static(root, options){ + options = options || {}; + + // root required + if (!root) throw new Error('static() root path required'); + options.root = root; + + return function static(req, res, next) { + options.path = req.url; + options.getOnly = true; + send(req, res, next, options); + }; +}; + +/** + * Expose mime module. + */ + +exports.mime = mime; + +/** + * Respond with 416 "Requested Range Not Satisfiable" + * + * @param {ServerResponse} res + * @api private + */ + +function invalidRange(res) { + var body = 'Requested Range Not Satisfiable'; + res.setHeader('Content-Type', 'text/plain'); + res.setHeader('Content-Length', body.length); + res.statusCode = 416; + res.end(body); +} + +/** + * Attempt to tranfer the requseted file to `res`. + * + * @param {ServerRequest} + * @param {ServerResponse} + * @param {Function} next + * @param {Object} options + * @api private + */ + +var send = exports.send = function(req, res, next, options){ + options = options || {}; + if (!options.path) throw new Error('path required'); + + // setup + var maxAge = options.maxAge || 0 + , ranges = req.headers.range + , head = 'HEAD' == req.method + , get = 'GET' == req.method + , root = options.root ? normalize(options.root) : null + , redirect = false === options.redirect ? false : true + , getOnly = options.getOnly + , fn = options.callback + , hidden = options.hidden + , done; + + // replace next() with callback when available + if (fn) next = fn; + + // ignore non-GET requests + if (getOnly && !get && !head) return next(); + + // parse url + var url = parse(options.path) + , path = decodeURIComponent(url.pathname) + , type; + + // null byte(s) + if (~path.indexOf('\0')) return utils.badRequest(res); + + // when root is not given, consider .. malicious + if (!root && ~path.indexOf('..')) return utils.forbidden(res); + + // join / normalize from optional root dir + path = normalize(join(root, path)); + + // malicious path + if (root && 0 != path.indexOf(root)) return fn + ? fn(new Error('Forbidden')) + : utils.forbidden(res); + + // index.html support + if ('/' == path[path.length - 1]) path += 'index.html'; + + // "hidden" file + if (!hidden && '.' == basename(path)[0]) return next(); + + fs.stat(path, function(err, stat){ + // mime type + type = mime.lookup(path); + + // ignore ENOENT + if (err) { + if (fn) return fn(err); + return 'ENOENT' == err.code + ? next() + : next(err); + // redirect directory in case index.html is present + } else if (stat.isDirectory()) { + if (!redirect) return next(); + res.statusCode = 301; + res.setHeader('Location', url.pathname + '/'); + res.end('Redirecting to ' + url.pathname + '/'); + return; + } + + // header fields + if (!res.getHeader('Date')) res.setHeader('Date', new Date().toUTCString()); + if (!res.getHeader('Cache-Control')) res.setHeader('Cache-Control', 'public, max-age=' + (maxAge / 1000)); + if (!res.getHeader('Last-Modified')) res.setHeader('Last-Modified', stat.mtime.toUTCString()); + if (!res.getHeader('ETag')) res.setHeader('ETag', utils.etag(stat)); + if (!res.getHeader('content-type')) { + var charset = mime.charsets.lookup(type); + res.setHeader('Content-Type', type + (charset ? '; charset=' + charset : '')); + } + res.setHeader('Accept-Ranges', 'bytes'); + + // conditional GET support + if (utils.conditionalGET(req)) { + if (!utils.modified(req, res)) { + req.emit('static'); + return utils.notModified(res); + } + } + + var opts = {}; + var chunkSize = stat.size; + + // we have a Range request + if (ranges) { + ranges = utils.parseRange(stat.size, ranges); + // valid + if (ranges) { + // TODO: stream options + // TODO: multiple support + opts.start = ranges[0].start; + opts.end = ranges[0].end; + chunkSize = opts.end - opts.start + 1; + res.statusCode = 206; + res.setHeader('Content-Range', 'bytes ' + + opts.start + + '-' + + opts.end + + '/' + + stat.size); + // invalid + } else { + return fn + ? fn(new Error('Requested Range Not Satisfiable')) + : invalidRange(res); + } + } + + res.setHeader('Content-Length', chunkSize); + + // transfer + if (head) return res.end(); + + // stream + var stream = fs.createReadStream(path, opts); + req.emit('static', stream); + stream.pipe(res); + + // callback + if (fn) { + function callback(err) { done || fn(err); done = true } + req.on('close', callback); + stream.on('end', callback); + } + }); +}; diff --git a/node_modules/express/node_modules/connect/lib/middleware/staticCache.js b/node_modules/express/node_modules/connect/lib/middleware/staticCache.js new file mode 100644 index 0000000..9ea8eb7 --- /dev/null +++ b/node_modules/express/node_modules/connect/lib/middleware/staticCache.js @@ -0,0 +1,175 @@ + +/*! + * Connect - staticCache + * Copyright(c) 2011 Sencha Inc. + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var http = require('http') + , utils = require('../utils') + , Cache = require('../cache') + , url = require('url') + , fs = require('fs'); + +/** + * Enables a memory cache layer on top of + * the `static()` middleware, serving popular + * static files. + * + * By default a maximum of 128 objects are + * held in cache, with a max of 256k each, + * totalling ~32mb. + * + * A Least-Recently-Used (LRU) cache algo + * is implemented through the `Cache` object, + * simply rotating cache objects as they are + * hit. This means that increasingly popular + * objects maintain their positions while + * others get shoved out of the stack and + * garbage collected. + * + * Benchmarks: + * + * static(): 2700 rps + * node-static: 5300 rps + * static() + staticCache(): 7500 rps + * + * Options: + * + * - `maxObjects` max cache objects [128] + * - `maxLength` max cache object length 256kb + * + * @param {Type} name + * @return {Type} + * @api public + */ + +module.exports = function staticCache(options){ + var options = options || {} + , cache = new Cache(options.maxObjects || 128) + , maxlen = options.maxLength || 1024 * 256; + + return function staticCache(req, res, next){ + var path = url.parse(req.url).pathname + , ranges = req.headers.range + , hit = cache.get(path) + , hitCC + , uaCC + , header + , age; + + // cache static + req.on('static', function(stream){ + var headers = res._headers + , cc = utils.parseCacheControl(headers['cache-control'] || '') + , contentLength = headers['content-length'] + , hit; + + // ignore larger files + if (!contentLength || contentLength > maxlen) return; + + // dont cache items we shouldn't be + if ( cc['no-cache'] + || cc['no-store'] + || cc['private'] + || cc['must-revalidate']) return; + + // if already in cache then validate + if (hit = cache.get(path)){ + if (headers.etag == hit[0].etag) { + hit[0].date = new Date; + return; + } else { + cache.remove(path); + } + } + + // validation notifiactions don't contain a steam + if (null == stream) return; + + // add the cache object + var arr = cache.add(path); + arr.push(headers); + + // store the chunks + stream.on('data', function(chunk){ + arr.push(chunk); + }); + + // flag it as complete + stream.on('end', function(){ + arr.complete = true; + }); + }); + + // cache hit, doesnt support range requests + if (hit && hit.complete && !ranges) { + header = utils.merge({}, hit[0]); + header.Age = age = (new Date - new Date(header.date)) / 1000 | 0; + header.date = new Date().toUTCString(); + + // parse cache-controls + hitCC = utils.parseCacheControl(header['cache-control'] || ''); + uaCC = utils.parseCacheControl(req.headers['cache-control'] || ''); + + // check if we must revalidate(bypass) + if (hitCC['no-cache'] || uaCC['no-cache']) return next(); + + // check freshness of entity + if (isStale(hitCC, age) || isStale(uaCC, age)) return next(); + + // conditional GET support + if (utils.conditionalGET(req)) { + if (!utils.modified(req, res, header)) { + header['content-length'] = 0; + res.writeHead(304, header); + return res.end(); + } + } + + // HEAD support + if ('HEAD' == req.method) { + header['content-length'] = 0; + res.writeHead(200, header); + return res.end(); + } + + // respond with cache + res.writeHead(200, header); + + // backpressure + function write(i) { + var buf = hit[i]; + if (!buf) return res.end(); + if (false === res.write(buf)) { + res.once('drain', function(){ + write(++i); + }); + } else { + write(++i); + } + } + + return write(1); + } + + next(); + } +}; + +/** + * Check if cache item is stale + * + * @param {Object} cc + * @param {Number} age + * @return {Boolean} + * @api private + */ + +function isStale(cc, age) { + return cc['max-age'] && cc['max-age'] <= age; +} \ No newline at end of file diff --git a/node_modules/express/node_modules/connect/lib/middleware/vhost.js b/node_modules/express/node_modules/connect/lib/middleware/vhost.js new file mode 100644 index 0000000..913d756 --- /dev/null +++ b/node_modules/express/node_modules/connect/lib/middleware/vhost.js @@ -0,0 +1,44 @@ + +/*! + * Connect - vhost + * Copyright(c) 2010 Sencha Inc. + * Copyright(c) 2011 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Setup vhost for the given `hostname` and `server`. + * + * Examples: + * + * connect( + * connect.vhost('foo.com', + * connect.createServer(...middleware...) + * ), + * connect.vhost('bar.com', + * connect.createServer(...middleware...) + * ) + * ); + * + * @param {String} hostname + * @param {Server} server + * @return {Function} + * @api public + */ + +module.exports = function vhost(hostname, server){ + if (!hostname) throw new Error('vhost hostname required'); + if (!server) throw new Error('vhost server required'); + var regexp = new RegExp('^' + hostname.replace(/[*]/g, '(.*?)') + '$'); + if (server.onvhost) server.onvhost(hostname); + return function vhost(req, res, next){ + if (!req.headers.host) return next(); + var host = req.headers.host.split(':')[0]; + if (req.subdomains = regexp.exec(host)) { + req.subdomains = req.subdomains[0].split('.').slice(0, -1); + server.emit("request", req, res); + } else { + next(); + } + }; +}; diff --git a/node_modules/express/node_modules/connect/lib/patch.js b/node_modules/express/node_modules/connect/lib/patch.js new file mode 100644 index 0000000..a6ff297 --- /dev/null +++ b/node_modules/express/node_modules/connect/lib/patch.js @@ -0,0 +1,79 @@ + +/*! + * Connect + * Copyright(c) 2011 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var http = require('http') + , res = http.OutgoingMessage.prototype; + +// original setHeader() + +var setHeader = res.setHeader; + +// original _renderHeaders() + +var _renderHeaders = res._renderHeaders; + +if (res._hasConnectPatch) return; + +/** + * Provide a public "header sent" flag + * until node does. + * + * @return {Boolean} + * @api public + */ + +res.__defineGetter__('headerSent', function(){ + return this._headerSent; +}); + +/** + * Set header `field` to `val`, special-casing + * the `Set-Cookie` field for multiple support. + * + * @param {String} field + * @param {String} val + * @api public + */ + +res.setHeader = function(field, val){ + var key = field.toLowerCase() + , prev; + + // special-case Set-Cookie + if (this._headers && 'set-cookie' == key) { + if (prev = this.getHeader(field)) { + val = Array.isArray(prev) + ? prev.concat(val) + : [prev, val]; + } + // charset + } else if ('content-type' == key && this.charset) { + val += '; charset=' + this.charset; + } + + return setHeader.call(this, field, val); +}; + +/** + * Proxy `res.end()` to expose a 'header' event, + * allowing arbitrary augmentation before the header + * fields are written to the socket. + * + * NOTE: this _only_ supports node's progressive header + * field API aka `res.setHeader()`. + */ + +res._renderHeaders = function(){ + this.emit('header'); + return _renderHeaders.call(this); +}; + +res._hasConnectPatch = true; diff --git a/node_modules/express/node_modules/connect/lib/public/directory.html b/node_modules/express/node_modules/connect/lib/public/directory.html new file mode 100644 index 0000000..15164bb --- /dev/null +++ b/node_modules/express/node_modules/connect/lib/public/directory.html @@ -0,0 +1,75 @@ + + + listing directory {directory} + + + + + +
    +

    {linked-path}

    + {files} +
    + + \ No newline at end of file diff --git a/node_modules/express/node_modules/connect/lib/public/error.html b/node_modules/express/node_modules/connect/lib/public/error.html new file mode 100644 index 0000000..34e0df5 --- /dev/null +++ b/node_modules/express/node_modules/connect/lib/public/error.html @@ -0,0 +1,13 @@ + + + {error} + + + +
    +

    {title}

    +

    500 {error}

    +
      {stack}
    +
    + + \ No newline at end of file diff --git a/node_modules/express/node_modules/connect/lib/public/favicon.ico b/node_modules/express/node_modules/connect/lib/public/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..895fc96a76b68b4924f1c51d022e1b82fa0f461f GIT binary patch literal 1406 zcmZQzU<5(|0R}M0U}azs1F|%L7$l?s#Ec9aKoZP=&}i&OouUjIY8@C}uZw4x5z5N2 zvEG^C^vXtt_xtJ?p3O32c(KTx;lsgZhW%5M85Sf}k-mf`L80)|7ga~M{a znlL=>m1Q`#uoPkbC~GtXMnhnDh5$DU1D6mx+;2QAKt3ZQFH}H~1y~00GcqzVg9QXw z_<%(a7y$V|wJgF=E>MgE#Aid|14}IyCM5MhEnxFF;pTzOK(>#80puP=gnOXwAd33` mpMe2}f66m3eB@_fcnmb^7!b1nO#opK8zcsj1F30)+jEP);68^d)m`eN0o>(5%D`Q(1;j>g@G;xlf`0VBQ`PFY?6)!N&f?*K}$p; zB!U=NBn{eB8${1}&-2_L*HuZp@ZP1@clS@cHp)4iM1ewzw59vko7eMM{e9z|%NNdX z0V;`?KKSzTCvTm5bc{L^CIKLUxc2X{i{ISz$8Sgf{q)1nXTP{`{s?9mQ$4&hPiKC- zY8q7(Y1Xu5iCf33=O4Vy(+|zQ?rW#gkKB0f%}?+6{G*qT22|DQB-73`YzA{N4W^=s zq0kQYcbtFfz zLz)H<&|z(Y4kBG67=JY6c|L1R-#TR>fC$3^Y%QEnYO1xHsf)+GU`3F<{J0kR(;pbF3)zyg$H+idfnl-wl5Wkh!vUH z4Z32YP=l_}1rZd1W_D&^$A($A+&a0e&P?xx0!ctY2}*<#p+qPVN*B(YzvAWXa*%bzq z7Fz41LKILT(GWohi9|LgIzSZBhb*Zf6R6O}WYQ4GOi&71s9lmll0x6;8&ILOl$j(c z0Z1T(6Tg09{?wd{moFHNN6PS?$|e>1MxSJ(0Z7o2)J-Zv|>acY@f`(Y@g7GwsEj5NLQo+q|HsxQ5}XSX_d@*^A9ZT9=A{W~j+$GyI1 zc4oqTHx@1FlRjw4XWyPN5i2~l_F3@aBk!0yu^aoRDvXy}8@HCjUVQUsuSH4$T5|r< zzZOn^?Wfa6y|Q($Hx4{ws+)wX6-HP4zo!S?4KJ@7PG@G3G{CjXs(p*kIrj6rHs7_y z+=<-=Q62s9FuWa^X~WKgJIAAZJR&XBB002ovPDHLkV1jCMPILeO literal 0 HcmV?d00001 diff --git a/node_modules/express/node_modules/connect/lib/public/icons/page_attach.png b/node_modules/express/node_modules/connect/lib/public/icons/page_attach.png new file mode 100755 index 0000000000000000000000000000000000000000..89ee2da0753040d1ba0a3487473a715a8fe89322 GIT binary patch literal 794 zcmV+#1LgdQP)i_t#ewV_0K6;=bl;e_Jt7$~$sQ)q$+ia<4Ec+jeaGt9oWH@O|2`W6&O0t!k{B9sUvLWxkCaPsd9W(`fa z;j-|^ZI^2XnzhgZWYRW-kP&J>DWPo`%;JaBX}or79k=+Jo@h%4Eo72tqev+cB?PjP zO<|ByL#>Tehyq$jR74O$B9WDW1`tK`LzYyL3A9iAcRxLkJ`I)n}v%Od-3H>j$OTBtk>(k-9o?8PqI=0 zB&f-+KOXVnjyKJlf4iHOtnuiE_4+ZVJ$dHjU<^o^YCjQ-wt^!;rPpBv(@pFO{9rdw98 z_s@3+yta93oyfL>7AD5}r=|`zS3Gm$_|(iSl8XBd9k%=91J0j2=ivT5cJ18ZmDjh{ z$-RMd{jQ#X79#Sc literal 0 HcmV?d00001 diff --git a/node_modules/express/node_modules/connect/lib/public/icons/page_code.png b/node_modules/express/node_modules/connect/lib/public/icons/page_code.png new file mode 100755 index 0000000000000000000000000000000000000000..f7ea90419d950f9e69d977a1f5847456d96a5f0b GIT binary patch literal 818 zcmV-21I_%2P)@LCln44|RX7Ti z0HI3&7jPq){odH{?_{%nYVq_;n_c4WbUpvU(&Cvnj!vq|kVC-vpF6vp^;;e0mm6HW z+WPzA`AZ|;pPp$&dNjzrc??4rt`k%Q1l*u-BPD0MQ}Fbm8jnsyezNt7+u{23>t7Em zJtETY?ja9KrVs^!LJ$xEMF3-bAZO;-IQJavE60KA7fO$VY_%N)R6s>g5mW>fL4&aR z*EVgKKTBXm!=L?S0?xM zYqL@C$|EDF2q*3zWW7;PDZ}SK*IE8;i!3U62=qn80C&*I1Le7WwNP5EcX;_oh2dJn zf#HgBe4@r$GcjHjmj2vAfT%(YN?}kK=(*+1*DkNNc1H5R++vfBMhACi<5uFUU+N4+ z<&U*CPmWi}REa7C6-t>2im1CWv5Jkefxa6>)dEj-CAW wWa{_}BJ!}~75?MkfaCnj>Dn=~vkLS70Pk`;z)@TQj{pDw07*qoM6N<$f@imYHUIzs literal 0 HcmV?d00001 diff --git a/node_modules/express/node_modules/connect/lib/public/icons/page_copy.png b/node_modules/express/node_modules/connect/lib/public/icons/page_copy.png new file mode 100755 index 0000000000000000000000000000000000000000..195dc6d6c365d298e466026b37c1959d96119ea7 GIT binary patch literal 663 zcmV;I0%-k-P)^@R5;6Z z(>-WZK@^7J_sq=QY_e{46@P+~LNG}sRzZsxQHvCsN*h5ir6^j7pq-$xu$N#V1gx}9 zClV7;5)7zih-s3DB)G=7|99>ji@So7-P24n=VQ(@GctDX!^_@$bj%oviY6e4Dh;od zooe%Wvs8LEKQ&&bL&@bwi=STIAI@!-gB2jC5+?y?VR~VkrNxam-`6*8&po|RZ5LpS zNKdJ%c4bTX`XjKsnecf%W>1%6WT?pKNdLLq{=(f(Col?P1+oq@R>)W(n=x!|*BIIh z6DJGw_w`)u6yN|vAhMteYK5#b%r5^v+VCFl1IGssaclZZMS{vs-LJ2$)n7DAr6==K z<29#%AXsBsDoO}SBaXR#_Ap!JKx)(1)3O2pj0_dYWz5By*X74fRT01$Fk%P_RzOMDtV?GU{nsYq#K8iy zb6qzLYDj`_f5$BwC*WE(t0m#xYJ*=jC2|HQYHh=pf#QG7oowi`h!L!{DB$8|qY{~X zu8@sU1tWq;n$XThR0%;45mdqXM892|{CJ@0DS*}>?ami06Q_^tvM~Y3K(_-`#m!8f z8f!QIrH4y#61;0Ym0cCoLl8{IPombPHtnn7%SbTdI&G-d>ZQo!_wBMF9nzX!g8HVY xYTJPGciz9XMh3w2fmZ(7v{)r*QZD48?mrio{~IaoqP z|1Ep}yDQG09bP~E^Dk?@JiKQJ z6-pO(3~IOP)IYisL6D6;oAEd;E%zR}{U$rMRNuD6nQV7nesKS>)yLo7JuDCrD>Abi zbj3uW23?^GA}9jQ{M^8v?ejL?HaT7AX5WPZNkBmfN`w-jL?{tT7ykZt$%Yln?p_m~ z-?>&d(LD(jAd}h=LPltPQbO$*Wbyl@G-_k5jXbb#qffHY03>M1jfEqoPJQ6Mr=Byp=^jfzePZV1 zLjCmNi31hdIJHa%e;5g=1(`u3BRzfeExY%=VCu{loOr{`%2hUR*x>tL^W_TTaj);0 zpPR6CUD1+0>4TQ6zVfH3TQ;%l6#(_%yspK@3gcmG#Q4!WCPyLU93nMKk7E2pcA=l45({2jNho>sdF*A~bA zxX?-cp~y_z_kFf+yqu3m#QiB}03?Z&9vvR5TNgj<)($Vm)xq5G>|o2sFMag&6aNF+ WAT1?sQBYt20000iHtsh1EzPArg^Q zIZrOk#rNsfjaSbMAL;<4h;Z=jvu8dzyz8N&Nb7=z03ZUw?9z%8KQEa6yM5=kUnka& z3?FJk2}L7q>na=T#;<7U*P91xfF`;`6%pVgWgRy0?1ZryL@%z52=-!fGXWGEn4M351L4<+7eDgwo|moqXT+s1&Kmn>-uQQ8mL7XY)w5Zk*(g+<3Y3tmkR!bL zOUKaUtj_pX26sH+=Iorwu}MGd`_%O-_sS}8VpG#fJA)Fcs#ezwtZf?q?Ac70mDv`rVs{$od?VPKeqf<-kUjNtS6ecB*mq<&M97K^6IVsDO zt2$Ru!b+>2S<}_H>$RcInusU_8PMNdf(W{sNlJ3FkrwMJPeBPO#d}Y^a{9TH(#{Y) l0D?dWAV4eUJX#h`!2gmISk&ZKd4B)^002ovPDHLkV1g&sd|Lnj literal 0 HcmV?d00001 diff --git a/node_modules/express/node_modules/connect/lib/public/icons/page_error.png b/node_modules/express/node_modules/connect/lib/public/icons/page_error.png new file mode 100755 index 0000000000000000000000000000000000000000..f07f449a44ff2761bfc7b752db3d08d0e1238b02 GIT binary patch literal 793 zcmV+!1LpjRP)lHwhvrAu0-@MQwt}+5~MQTtu}C0%;W( z1<{R?aHBz*g;pk%AyQVBR_Zu5m~;ES_vxI-O!vIF|H*|T{l`n#garr?$RMk>)?Y48 z(ZF2yTneKb};DNWF+jK)IF`6_IfJ{i|F3o%Q+l&4_HGBD|ACE8na_6>L z=s{^>-C(a7J$6=8A_%h5W!1K6dcL!D?XX+Ndk)oei?UundDpX_E&1Y&`)3P8#Ny0s z2Ag7_&ZPhyGj%)g&S6V2LNun1;iBQm#Fwlfv zgyESZR$X}2P;=RW!2zid1r$hBL{K7>2qi*f7>pT1=RdT3@-anEoH{ z={KFOO;Dh#bV*jaN>}M>RZqQd`S=6O9C3KpI~I>l%QFYfo;jqQYe5fcn`)+)zMm6P z4X&L(>gnN0!%J4^rhX->?$S5bY<=GEU%jc!KLL8sww-Eg;h z`H-yBHa)yfojYT}&G*GFc$<(Yja_q=lZvj66DC^O5%$B)|Z(CeD=n`|eM04SP; z>-=-l+xdJjA~vR6^xB#o{ehf~tSM`iwaQv$O<8NIHA}W_WOw*~ XD^gE}t;YAo00000NkvXXu0mjfl6ZQ> literal 0 HcmV?d00001 diff --git a/node_modules/express/node_modules/connect/lib/public/icons/page_excel.png b/node_modules/express/node_modules/connect/lib/public/icons/page_excel.png new file mode 100755 index 0000000000000000000000000000000000000000..eb6158eb5ca9c4b64c81e70e0fd894dbc8e2bed9 GIT binary patch literal 817 zcmV-11J3-3P)hdKqhFO_H1|Vn1E?(=|cjAh_&P}y{{^`u< zcYD@PK?$)4i~7o9*6F_$F$4lR(d4AAvrez^(88Hk+)+B7E)M3jc=Ewl4$S^`_qwSF zA%qz@=c2EOsz@0qB1IqsqJU)HaG&+}%`-OM8YqW{K85hqj@4&V9vz!Cm_n0-W#f;# zeEpJde%vdgRn5?(+PY=W*z~|lT2-mtown({ll8&3S5+lWz5K}LTRW{k{eJn3Qz!SU zQ`@qI_n2;K?RG~pYJ9=dj-RWgG;P&wEuoAxL~Q)<>x0b=dED^Outj&xQ^rA;u3pw| zca_ClTh_d9cxXg_U!lLRl0`xU@$=UXO|_dRdtXfKwPawmnf(LC7u}-U>8k6}3u|{8 zs9LHr>MIJZGD^r9h|q2yF24Wuh+PM^yMN9GP1$khlDkdyCY}D{kg}jEf-(kW5jBY> z0rB29ZhG-r=i_R{;+1k0?A-sBM;AP6(k1i9ZuixR4?MqXOvphQgCYj~RnXKKL~J9Q zIDNz~XMfO{ZhUg&BTtMyXJqDVqc<x643?SvKHx004lTvR=0a5$dUw z>Xb470000$S;ka1sfH4I-R8njUol7M4dtApOahDylptpYswf1hD#CwFoz6oEA>(SIECU&IQ%a}GXdnC!9$70`0uH1B00000NkvXXu0mjf!8w72 literal 0 HcmV?d00001 diff --git a/node_modules/express/node_modules/connect/lib/public/icons/page_find.png b/node_modules/express/node_modules/connect/lib/public/icons/page_find.png new file mode 100755 index 0000000000000000000000000000000000000000..2f193889f7ea091c292acdd684c595dcb206b5c4 GIT binary patch literal 879 zcmV-#1CacQP)@+1&aazfGU7ezSm^v zpACwO+tu0su66!(dT=`e05DeeCnCFJW(8|RKtKa{4LGONnx2V85A4m%PEQ?MEtR-esdM$pB-`H542D0)N2zSC6Imf)4L8?>%ZrW+H>xCKi$unm zvGZq-*Q%Aahx;C*=l+K%-?>XB)6TB$-L$r*`RUvlA`xP1NG2?)ge8@TQ4EN|Jks0u zcDg;oFC#-#R`YbWB`D?Q`1#y7l$LXhjSLf8AvQuB84}i#j0^!#g{VE#(K7h@5pFHy zSenl=@XBEdxp`h2Ji>CR%=qXJ7!e|?paKet-~;#ok#jETyeB(5&Bkhp;!+;51~G=) zH?L7xmDUu_h+a$+xuWom;AWW!mS$%%+436Rjc@}y?l1134kgD0AOf$OmjOR zstUlshZk$ZC!bAyIg{Y29z#&@3SJ;6D4+_eFume9^#TmMccC5u0J!ZCTnO6m$lnD| z5JeFHf`Xs~1vP>RLKI1GKDY<~pjr2&bi(fX;6Nj-ss@Ds0CcoO0H{JsEQkm{q03skAA);_bv3q{k31qwVo&s-q`Z?_e+j^w(WL? zl+uETs5+~xBU2};OqEE9ETLGwsMGe1%iTRNue)9}|0~E4B*@5#oRXZ9oRXZ9TqRep zPrGZuoOON4n@=uPbyP1y4G=+HktC6l(gZoFD>@_lXDrN?wo+zozGt3P=Qh+3L7+}q z2!WK7geXLnO3Vw;o12Skp%_E#+N#9;DDWP?Q-VS3B$v~Ha)dDzWn0zG~O(^_1!n0HYp-( z+;wPIdoFgQlpYV!10V>5@a)1LyGBMvoa}miyp(bxbMTM-FYNyx;V@TfYddyT00000 LNkvXXu0mjf90!wr literal 0 HcmV?d00001 diff --git a/node_modules/express/node_modules/connect/lib/public/icons/page_go.png b/node_modules/express/node_modules/connect/lib/public/icons/page_go.png new file mode 100755 index 0000000000000000000000000000000000000000..80fe1ed0cc75fbb67e9398ae686641f8fb287238 GIT binary patch literal 779 zcmV+m1N8ifP)JNR2Ufr z!Apo%Wf%b9=l#x^8AolrB&K9H?Pg_|78WA8(M3toqE%3B#7*srcF`i*xhupr27%Nr ziguah1+mN)U5GNmyEfQ3-e%_i&-vb-Co#(>FJ+EhQEwjRYVQ(&UYy{U@%vbY||>@4x=B^vIqabI?L* z;-S&DS^V3-ni4^fl|HMkOEbgX)(390>A}|VIypb5Xee4g;7ck zwKh^A3Mi1Mh@eC$5lV!}Fw%sP623U`g3pd_Hr5sunLvTskx4}&Gm%Q6L}(l4x}jCe z*81q1_4-O*ffi~_nMslo?EQ8t*&Ec(pzEw$vc}pKn_Qp0>D7Jr>ATNC3w@9f|Y+U&+)#!t7l&wKp+nP{PQsb+fb=Yf!Fu&5j8vpRj{FT>jD z>d>$sx;A&+`n$HcF}&sYKSyR;=(=9tvvOj@hUG;~4qTYk^_@E=?$*^_pVh_bGnOt~ z;pEw)j{SK$XVc;qy181rT655gW9NG{(yeablViIL>cDI_ux8m>Pp{tY$J0lgo4#ax za?j0EA3s0S!f>{~ykN9h_RhM&g3K(E`q(dE(Rd49+%xMeR9{qlWnmd{s#(SQ>PmFtSQqUjAtB;_Vvt6}AS_5YgM`Uqu`yva+H8^=4U$e4gHb}u zAQ2N{V3A%pO|?Pv?tb6z=jC}SiRa$G^v3q?*6XcYz$p|cq{uLj@#~Fi`J(>5{@&&N zy%T^+;>8cXx%|o77anP?&W1?1A(>-T49z9pyeCl@7YI+Si zKti7=B~``}TImz(G{0PnlQA3P#MAd}sorMjkP!50B7$nAkU^%#nl{Q9lW0@}9fE-> zN(q7tRuiC_T1r|BBtVBTlQ2+70$Rf;eF`Z;lx46Cpu-rEgb)EBKq(b^W8l<^We(`D z43?0=01z<3G6+UUv6`CsWCk6^93!#+<;ws7007{zS3k2k9-zZKFO~(k`>s0y006+1 zgF_jyIhsL-`FMf~JL~C=cV75(CrJ|q;MVO961G=O zm9d)YpJg5g(4i_HKL75eSE}mq$Y}r}hyVdcV~p>6a}oXr80q`oj%+s700000NkvXX Hu0mjfPs|!l literal 0 HcmV?d00001 diff --git a/node_modules/express/node_modules/connect/lib/public/icons/page_key.png b/node_modules/express/node_modules/connect/lib/public/icons/page_key.png new file mode 100755 index 0000000000000000000000000000000000000000..d6626cb09eb11a298b90a8a27b0d8eab41f49a82 GIT binary patch literal 801 zcmV++1K#|JP)$lC4gU2-`f*>nhR-;k6IP7e>YO!0^w)WK%3$w02v-#>5Ep64PCP| zJihT#O|N+nT7XR2h7dAB?UEAOhJF^mol1i`QtQB`HSY}RE7=r! z)zaVIHr5?>v2Gz&fdYw&2ug$!p+txby(aWZ7(4QT)l2`jX7eMQ{>)lG6ev(fWKxmH zOr%mM5$6B%u~qGtCf40#`mbGj3s!n+^%wnJ&#rl>g<4Z)lB5J6f!?|AP275)Zswr* z%T}4~{;_(?waU!#?JabbF3Cy-kf0{R{z}6$e=5yMQKt3BPcl2>zoTPMqMwF;3!_n|>sT?~bK_-2O_m+o>GJ6h zt=+g$4n7y%1qVJI7*5Yw(hqM=JusY{d}*?U(Oj*gT655eZ>Ksn(qrd7v3}DX1}C>` z+X+8@+4-pVq_fxG zlU}~Ye!0+%>J+pPk+0wV{GM$QaYM?5ux)w2z59=S&H2+K?;gH$bZGzL&g5>G ft+noNiyiPkP9r@8gT|RZ00000NkvXXu0mjfuqTIu literal 0 HcmV?d00001 diff --git a/node_modules/express/node_modules/connect/lib/public/icons/page_lightning.png b/node_modules/express/node_modules/connect/lib/public/icons/page_lightning.png new file mode 100755 index 0000000000000000000000000000000000000000..7e568703d6432c530224e443771a04fc1e2e59c6 GIT binary patch literal 839 zcmV-N1GxN&P)73{`^;G#xwAtHz%LU)4b zqTRU=ve1RNa3QT=ZM7C`iJ~QFQ*9t7<~pX$d^7W%^M8FFCkcQj-~0ZRTBCB(J0^iD z-~e!d9LR`f3#|=(>$bPvx_D-~2jC%pJ=n_e_OK zeJ_2b-KdDDh@@UlzBSMC;EPygH_MwjWBnPGQegihBV73D?-x9PlHL9A=(Vg=8^d<4 z<9r=UkxuIm)*CO=9e###7PztDxUv}e?$0)rQicmYhV`pQ%S!g@;K(?TVfhM#E?bM| z=B0gfb6h@a8bf5FVT-SV~6}?X}9lK@@Yynoty&1zdZP@?RfODsl=2XzzU% zS8gIN43How+9%bK2S@Xbc`O>`z5`%^;pXGy8^4f>9^3!Sp@|O&)m;dOa3q6d;4P-l zca|=H_{G&m?D_+&-}r{u-J$5T=(X4R&)q|O^gN8cgv;s#@5sEPT5_Z)oFo9Ac>l+I zc4ng5zHpps|9)<_Rw>5bKzE(M1j)dFWI_%OH$BJSz0?T+02W0)_a>#vFqb!*d|5wB zzBUN|M&ty51O@=i?kiDrjQ{{}e|^rU?OS|RdxxP1p5mAw36cX72#`R6UsoeCQFI~! z0ATITp!vfeYyQ?Dr=^5BAshfEa0nB~JG?nUa2Aur006MC*<9`)86SPS(W^`H2n+xi ztOWohsFfVfVWrI7PSKW}BmkyPoj(-|J?ES|BGd-}fIxr{00@ANnO*ZR`#)pee4I5T Rmm>fG002ovPDHLkV1i|Hc$okI literal 0 HcmV?d00001 diff --git a/node_modules/express/node_modules/connect/lib/public/icons/page_link.png b/node_modules/express/node_modules/connect/lib/public/icons/page_link.png new file mode 100755 index 0000000000000000000000000000000000000000..312eab0914ab59271384686255d1be913a6b3add GIT binary patch literal 830 zcmV-E1Ht@>P)VWgGzD=Y79#JI$lhEn`|2MpRa?Bt#-nSD~P0P(mbVe{KrOBoKnSsk>m|ML{6l zBosu@om4j#WzNLRAk+{k1JRvL(MfE&vvbb->v>W{*z*1_uMP}0cIRX*?mz+wk%*#O z%0D-+$B*g1nRkvI+_3E8Pr1NC6@5M&4vWaLCnNlr;lNlr4i91z&)eBGqL{L{GNu;Fof}GS9{gM5BJuH;2QWk8yuOZdB3pGR#s8bd~ zAmt<>3Q=YH$t5YJ5;7@+8Uh6=ktBgY6#6Pa%2F?h910?U8cLT43KAj$Z1*==ra&gILO{WkHfs(--F=bly9l~${z@AT>V$oat!YAD@M zBE0v_F{`g#^wOSP-u~!wvlmXdd*uqFqoZ0^{&nEMDU+=!>({S0wrQhFmoB}Yq1)~0 z^{A)L8Xjzdr(W4_exYO6u3a{4*kIeXZMJUR>Q=ksjW_p!rAwDKYUs90>6Q|C>56o@ zbrSq^Xk7Gq#>dAsn@un`Hz$?w$;Ss`%jV7L%9ShgHFV~C)6M>B`Tp%|nqPc&G*A3| z)Qe+}vT4-x^t1~XE@(6wR;^lPWMo9n*~E!cy~)YRsT2{`?fqeIw-e7N@mOA%UcCIq z_kH(_EK7|>pM*1Wt2^DaDAp|cvp*@(ZZDKpYkKC^?97(`0sb&XTXy7N#sB~S07*qo IM6N<$f;YmCWB>pF literal 0 HcmV?d00001 diff --git a/node_modules/express/node_modules/connect/lib/public/icons/page_paintbrush.png b/node_modules/express/node_modules/connect/lib/public/icons/page_paintbrush.png new file mode 100755 index 0000000000000000000000000000000000000000..246a2f0b426faa0c7f5ba009e32b1deaf88d1288 GIT binary patch literal 813 zcmV+|1JeA7P)otxGRZMDZ!_a~nK|b_-`n%VosaL{KDuPV10`(1LIen8kX2Xff$3BE zah#djvFGJ&eE^89Pk*-O^+&d>FC~^GjRYVQ(uuPJyS|-v?9lxA-+tM5>1Qu*n+Ir1 z6KhA>X4$XDH6?-|E5oe1E?pQ5-M;2xw_ex!x}I2+b=}mPFW$U%^;o(Zg*LP!K^1kP%8ynsD^= z1y^6xD1#GLjO{VLdh@0GKY7;d$+NGukV)GRLPn^=q=dF%B#XaJrNP`0E6=}e&Gj3d zKJbQre*WXt!60_DnIzgMQc6S#fvjXxsE1v7;T;njHkdy2miIqAS(nX~o%cO+q+b#h z5tIleLWvL=dQE8OC#{%y*Tnku&K`Tuub&_ELI0t_ea{@3f>Jv&sYqld(%}3_GY3Dm z;O{3*Y?v^A`a|D;^qrM=ykI)U6QHd%WhO~VF!SGjGn0GOZrc3mGZudNl9{Q#X5&-F zuGwVReFLBjE5jr!!^-5*L%!I%PkYH#Hs5rMrEBl^)9)9XTD;xjHFxVZMc3~Dw6#k$ z(-S}RE$bgMHv6Z`mS5|u$$78sp4G-8b@lVkl`HtEv+MGn!F&bKcHPi$$oP_;=BrPf z$(~b3&p3CsuQxhoV$%jIR;`lB-s7FDX)xCTXuJ7ZyIQk96uIR=HBt%-P?N*bp`)EF zq14c}QM+O70NTOa@V~_)&GMZ$^cQDlkyOCa(H3Mf+6xhCuZh`VSN{cQBl5Ys9{cp( rh`2H3A^=GuC6HjQ*7|*0>;m{7QlnX3z3MSD00000NkvXXu0mjfR5FYo literal 0 HcmV?d00001 diff --git a/node_modules/express/node_modules/connect/lib/public/icons/page_paste.png b/node_modules/express/node_modules/connect/lib/public/icons/page_paste.png new file mode 100755 index 0000000000000000000000000000000000000000..968f073fdddc1cc0f0800b1ac4001cd9a55f053d GIT binary patch literal 703 zcmV;w0zmzVP)AVs!l4K}n~L(tL`6d4Up4iSWnZ3Qg~4n+_J zDGk-qQdogO5JUtO-d5pRp7Nd7_r1^a|M&Zq%mn9Oe((|e0sw%Ur!K7T1pojj=U#f? zQM`qbQrM^DPkwa?DK_be^~z<~RgSMIa<`xP_4P7gg2jCwJ{9^k!fsU=#Ti|%I3p;>90Qd+7|~0h&mIklA#nb>ATL2+v$&u)OBgB z;nsHb)I&QRKeX40H~~cIZxCd}5C} z=79lXoXK%6YlyLtsV$~bSm?Upq|DJh#{|*a7XMm`4QJWZ>s6nL2R1|&J z0VPEwJ9?!n`o5PKAjc->P1Gi8BY*%!5&FVp=#)$mMJYul1Jton}gujiUf??eOy!x&!tsjxy;=Q3_DdcXx=a^OBhW0N~`A@4xB0a*%F? l+@c^sQA%W+?pa#c`9H5UNfS6T{e=Jk002ovPDHLkV1grvM=byV literal 0 HcmV?d00001 diff --git a/node_modules/express/node_modules/connect/lib/public/icons/page_red.png b/node_modules/express/node_modules/connect/lib/public/icons/page_red.png new file mode 100755 index 0000000000000000000000000000000000000000..0b18247da5850f3c2486373a3e179acd2772e8aa GIT binary patch literal 641 zcmV-{0)G98P);68^@7JE5sw#jpE*579S@TLkU(6yap1yN*Zuy>-hV%Q_v4Ar&!63c8OBr(ZRhFu z_kWs36-AmgZCT>x!RqM;Zu9tqvoHI~k@UmYo_g(*J3c%2{N8}7I+|qKPQzv}7t>%W zsu&9G)UmCzkDYSw{fBnuW4j;1fKV_nicw`$8C6D=F_qu`zUiK$2Oc?5UVY+D(`I@R zW`KlwqLftWHH3Z2_XVNfKn>VgT~k=@- z+N>c>0|@A_HbI9Jn`v0~7cfIF(TS69zaomDS1QtgvaBBfGEPLHccO2~3jc>n^6}^HAEh-2#VxC7YYcDXv!L9X= z-R*SOUvIs;n`8(LxP4~^2|JsiN^hq6cU}5dn4v1~Kl{eT7pm&f$PoY`hyVe%y8G*S bxB&kH@RuR86sIAS00000NkvXXu0mjfZBi!% literal 0 HcmV?d00001 diff --git a/node_modules/express/node_modules/connect/lib/public/icons/page_refresh.png b/node_modules/express/node_modules/connect/lib/public/icons/page_refresh.png new file mode 100755 index 0000000000000000000000000000000000000000..cf347c7d4685128a4a447abb9fb8e939417644f4 GIT binary patch literal 858 zcmV-g1Eu_lP)`6pHR2Ufr z!EI=jWf;Km|8+n2IrHqe<9xxFVk)&(Nh?w$Xk`TAyvb=#e=0aySC z00NkRDM597_LiNIJ2M^qhuTvB004REvvU8@of{r?P8tmo3;+Pk0F0@*jAMhdOkS&1 zhJPPfQa;pP0|4+Yk%#j>X}o-s#EF1_DMV93FsfPP`G*>Ks>L&)Q}w2g%slu0kBfW1 z+*$*0BC^oTl6>OGIq(9BgG4|C90Dk-N_mPazGrQ7uHZ|>BLD!-KmZ)z1e^#?1Sf(M z!6m}K(^b|i%$TcA5bC}r$tAA?0C)g1@CgWliJ;NAk&ZF+-w#}$`-3nZ32C6IVKrHp zr+(!L2hRfF&AsTw>_@ z1y23;E%Oz}?q^Q2d($ayO;-sON2t7$w(Z|o0Pw1YnSp^}0PI+I5HnDNsFCA?oorkG z5sUIGIq=FSyxcj+xlhkm0en=52Bx3@02o12gdAU$_i?v6iyFMuc7P9#zQ-Hf; zVuV$t9P5`m)F2w1?t6{<8%wk{w-PP#Sj#%1MbsjrSI6n;D_@8q9`~W98dNQf$j=iI z6~hpgww&be%X_HI50Hhx@W==u4TLPB;ei-J-1}G8wH}|{i#Lk-WZAyfv}k4y0|fvU zZTy^$u6L>2nWo(NDSV2@MRD}JQ4(c%G%=dG@_vxH?>gcH#*Ue2HC}9sapf8X?R$Z;XEnm&g zW99mh)5jNw008mK8)r^`_{yH0rNn%u1|SpC(tjf#om=+r#lh+?Kb>DVb9`|C0Bvbv zN3U(>f4-tAC1hosRoA7p(b(hL*V}(j>ug<`&U)|l$6o$)!>PBQ9RQSwn9asj2p*|xhU*R^vq?*Twb0t!lm5}`yW5lRy-U0ZYK?8to!;o!r!XeOE$ z0HB3T+6EEoI4PlR=wonwqJ+TvCoWh&$?CAPVYcU= zD{DS0?AkOtb@-hh^ZLq~FMjxYf19X?pa_YqtgZGvv2TaxcF#KT?O%=_*a-kW_;N|D zakkWsOe!)HsT5WRBiC+p;N-c>0Qwy(1D2MDBC595oXSiR07)sKNk-%9*rDBOO^HUD zZW#;)R&EZpqha<(HK$(tZYU#V29<@0qCXgU{gXeGpc_|pTqQD-WO|}%yKZbeX7k*H z2W~CK$v8NBAq~czrc5A(v51g0Wma7`G8}f=ZcuAiYYxZan@gP(;Ku66M6?bquGiHe z3Q0ya)%Lvk@kLixZfZyU@#UFbv+>pYhcj8TRKSr_sWG8i^X~UA**LvbD3(_Lba3xm ziYcpup*A9qJ$?AA=Og05lndxfwr`!C+O~h|B~4 z01q8H`StcY);%&mId7_+)76ovRpeNWRp&4M?#jx@|E-)x%P*A6t^fc407*qoM6N<$ Ef@ddc(f|Me literal 0 HcmV?d00001 diff --git a/node_modules/express/node_modules/connect/lib/public/icons/page_white.png b/node_modules/express/node_modules/connect/lib/public/icons/page_white.png new file mode 100755 index 0000000000000000000000000000000000000000..8b8b1ca0000bc8fa8d0379926736029f8fabe364 GIT binary patch literal 294 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6SkfJR9T^zbpD<_bdI{u9mbgZg z1m~xflqVLYGB~E>C#5QQ<|d}62BjvZR2H60wE-&H;pyTSqH(@-Vl>|&1p(LP>kg~E zYiz5X^`c$+%8#zC{u)yfe-5 zmgid={Z3k(ERKCKrE7DF;=x4^O+ pzO8rLO8p|Ip=x)jHOtWj`bJBmKdh_V<`47(gQu&X%Q~loCIFbEay|e6 literal 0 HcmV?d00001 diff --git a/node_modules/express/node_modules/connect/lib/public/icons/page_white_acrobat.png b/node_modules/express/node_modules/connect/lib/public/icons/page_white_acrobat.png new file mode 100755 index 0000000000000000000000000000000000000000..8f8095e46fa4965700afe1f9d065d8a37b101676 GIT binary patch literal 591 zcmV-V0~O9lw>B8WRlD)Gm}Jrz31u-X&&gn2lvjs=i{7nIaL6v2==uw+8Lcs(8j27 z;|c`rmSv@Lx!heopGP^^Ieb3f=R!%Lpp$}iMS-&P3EJ)s48wrJ_Ni0~k|c47D2nj= z{jS6bt|kFpFf|p5cM`_&0Zh|`rfEp0(}=}lT#(6RpzAsUfxv^LSYX>WlAaN$>)*J5 z0#sE+JRUD8iT9*fz{)_^7@6P&!sEjTcD+I9Z4YjT1`wH@fV{cEvneYGFU%maIEU2s55&K(LixD|{p-uiS@?KNj zk-Go8G$hH6g002ovPDHLkV1hVj1#|!a literal 0 HcmV?d00001 diff --git a/node_modules/express/node_modules/connect/lib/public/icons/page_white_actionscript.png b/node_modules/express/node_modules/connect/lib/public/icons/page_white_actionscript.png new file mode 100755 index 0000000000000000000000000000000000000000..159b24075191fc259cfd80c797a1b0d74c168422 GIT binary patch literal 664 zcmV;J0%!e+P)7Z7t2}reCh0o`+ zAlt$F2tW%oO@m<=(B8a-_VgLl#~yUMUDWG!0qFPppd^03e+x1WpkO1NhIaKD2A)-@ z=Py8(Wi%R%JtYZG#sTKH@6Z+&!S3Edf8jFJJNKuva#KJQD3X^7;H^fd2di znEN&c58aUG>`>P{Vqq$kLb+TP{?I!d4(|o59X_%|nVEZq2Rk60n7072SWJ{64CV?3 zgS!EB=eYxwQ>P2&$}(iT6UMvuFgHHIEdNA29!EBtg=v~X!DxxEH~}L2zn|52%xalaq@DTdhh{EVwv0IaQ=!?daer zTKp4I`l8SDt;d{8Q`5Ko;BXUi&oAG1l4}59P-{|^S(Rmord5s6qsh<&m@Ab^wqCD) zHyRD}lKLDzpYN&@q5&*47mGzGiqcXpmqR9#K|CH8kXS4RNs`(iEF%HjP%f8ItyaZK z6$%Apvsok(2>~dTO5jTZfq;N?0ch4l01f$k9?4{~Youl-#x{UDMr#AFIkz@SDwPtQ z$gQ^$2|*(Ps9LQiav_8o8Ne<=Zx1*M*syo80sEO1tB%>5 zfdHB`1z+!R@?ghPRKmL)hWEvZE$=*54ose*0JiUNTM_)cMDXhxEKg(?-pD=y<)L4J zT0dSyD0&NhJ$^_8Ko9uom%-ZM4BTM{Tw$9qyPj=-9W;N(Wi@3*-Q4pq`Gcp}^vvNr zyd&PsmG>fpCSZz?K}UIEd;HGgG%0MG>ymxKPwy{>wy(m*Atq7)0000~7 zMNw2LQirBVQoa8G3P(rY+l;L4iy+JwSqmy$9JlSkk z&*$^Eg+c)@!R|v4gdc8+TTn&eWHO0VD&>$!B%o;;WLf4CNs=Inq9d`xA4otCWHK38 zmc{pkX`0Y=9g3oGK{}lVy~OYL|C5lQ&U^l;wrg|7w=BcA9L4-r411?K7f`@348&rw zXD#uW)DK;H`hxO}u%=@Cj{;#u#_;bb1_KgUOT2Hp6;)MvC6P$vQP3=g1O5#aU%I!K zZ1dc@f}YvG&*Spnplm2rIp^VdA^HydZ0X1axdms2!RKi5x-SFA4p@ zC@N|PI$ryHL@t-(!zBsf2-+sYAukhDHU7Lxm88-p zDk^c;sHj}OKUc4lGZU}6umlGVNAJx0%sKDOFwQx|V2pVvxhYKe|L9TNk!~md3BVrm zYPDL8Hk*yU-ER3~LGwJ7N`0ZV&nOhBI{~~A;@ND*=kxg?#^W&`4u`zk?Mg_e)8XlK z`T#M+OaR1!<#Nf_>$S`xrqd}OjYhoJ>q)?3vEX8pY&I()ERjfjrXM$k7e+-Qs3Ihj zNyOuEQ2EGYG7ro!o6VOBQEwuV2z)*tR8>WxP{616FY)p1Pn1d}#9}cxolZC$4n(6- z35hJq0;FlHC{ zp*iF(lgUK(E`($(s9pJ8Kn?(M734H_63WHtf}6SQQ_MXEP!#0|&@>J8dL5TfG&tBw z#tYn{TCGZvAr>cca%YYn^!t73tg8OOJ2FvJ(`YpCyVZi*?Ur+1uUA$hAg8-aK)c;e zQ<)!XwHh|n&ND=$@^)>aF-`~n}#*WMkD*M|f8r$i*z7+W! qF|A!t*4fE(R`<_YIkN&?Jng?3oQ|aAqClPi0000t>5xmo{nArfL4CJwMMm+N`pQ3p^Le$?rMud6Rbxz!-yG7bz2z$^USP5(;udf(gfQ zG~f68y^)EvcNWp#bUoDt2=h+^%o-?-|mo~iieWqLNP<0m@2PTB7ftyb= z@H`K$>v9Pr5X`L|rw&CEN2(9SB7A2SE;d|j9@*F}sd(@*2l|P*fWfK>1drZUrtUA7 zNXO~pKn1cjf~~TLbje1g>EPPzN2GH#UIBxJ{}S9=E`{zs-w#hO?vcH+hJxroI5v?j zD!4lP0WXq8zUx3RAP@|Gq$}6wXCjFLZY^YSWBxN9#&g)ro$%5}aYn#y=tJ_aIT%4d z5d4u`rlp!};XGmbZkJE*kYJoi&N0pd*yxY{0${xD;;Q1h^8f$<07*qoM6N<$f(}t7 Ae*gdg literal 0 HcmV?d00001 diff --git a/node_modules/express/node_modules/connect/lib/public/icons/page_white_code.png b/node_modules/express/node_modules/connect/lib/public/icons/page_white_code.png new file mode 100755 index 0000000000000000000000000000000000000000..0c76bd1297751b66230f74719504b2adb02b1615 GIT binary patch literal 603 zcmV-h0;K(kP)^~*-1fljz_B$LUvK}k?BNXe#Y!m=zM!!V#}8bncK5m;8VP zw86G*RI63?Cd%b9bX|ueNlZ|wR6rj|r_)VIP@r2imh3?SN+^{|kY%~8B{maJ@F*OK z&VH9LwOeGt#DRjj0~v~8`>iO7!Ybi;zE$va`A^T#yW`y44;k^#O~K5*jD=qcUhPSc zvyy~q;5H_1WT1l~cqje9yfa+l!hu6xjdOJ8s;8E^+=QQ$tw p?%p!Hy#YapB=@+^9(46X{{RQg%9y;OKjr`c002ovPDHLkV1g7l326WT literal 0 HcmV?d00001 diff --git a/node_modules/express/node_modules/connect/lib/public/icons/page_white_code_red.png b/node_modules/express/node_modules/connect/lib/public/icons/page_white_code_red.png new file mode 100755 index 0000000000000000000000000000000000000000..87a69145075afd8f8fd8b391c5da1249ec8b2889 GIT binary patch literal 587 zcmV-R0<`^!P)LWh{^|hy<@Q*xw+qo|KpY<+vaXbbW{L4q( zTsjXEJvb}e%bgb=o%W0h?4u1;^bWTqH8}5Th002ovPDHLkV1nrS0P+9; literal 0 HcmV?d00001 diff --git a/node_modules/express/node_modules/connect/lib/public/icons/page_white_coldfusion.png b/node_modules/express/node_modules/connect/lib/public/icons/page_white_coldfusion.png new file mode 100755 index 0000000000000000000000000000000000000000..c66011fb0fbdcbf210483d676b7131542a0e282b GIT binary patch literal 592 zcmV-W0k7R5;6x zlV4BMP#DI+Z{WQcKZBTk0lfkj5F$ztWhP#lcuyb@0@rA^#Kpu5KLA&Rgc}o#aSmis zrZC__xY^&#cI&!!{c|4Q_tcec*#b>|Y15wPcY2=o3;-Bl=(t4;6Ok*pL)-{*A;GX^ zS(@WGp6j~k1wBVR9)BB_gar`}HyRBXh7nM!)u5^>N~MyN6bc0-5{W?44iB<`2biXb zR;wk?jIQg@G!5l)SqhrXCU}x$GU-dY1sra}0uCq@153FUULT=jNwSk}0WBjKz}Jdu z<5gB*<^XtpAmp3m^ZEXQZWd1krhft}CoYaF4cSMvTJ01}X3X37KYdx-D0$c{doUe8 ztY{vlGr-e*;N!WAV%_hgUawyYrhegW>^F)pv%uUTFslHn; zvJ)l{%w(~{!O4`KTmK{Q{zCYltLfs&4?nz|6IdlqHCvX;|HGv~!QW?8P~_d#e0$v$ z)5XHEz{3>qMiH`1+qNYf?huS+@L`J9_$cjJF)Hf?@pu;)`9}BXwGUM{2!{y-4|Z{L zG>z?O%Cp8P5T#j1DID7u_*(Jg?7iss8AZQ+&;u_J{FmILf((9eoiL5nGUe>Fgq*U$z0000 zJ3A|*qoWOonz+4ZQ0KNhDB07SX1?#FrNy8%K)_l}y&kh`*KYdy`Y99&tgNgMLSSrc z?B?+B@HO@P-jS~z2Rgc6yy~Y~%>oJpBxsb$5<&nRLqiuR7K=@0SZj~jTs|sv_jWVX zGe?WflejOaq|Vec=s9+ahmXbyJ|T)Sl*?s82sr2H?Ce~HD5WI+Sz&tmWrN()wI2}+ zKqg92t*l^-#ae~;9%KFlWkmwnY=-UK`_|%ICZ#P1gdjK<2n38VXsuC7{WiU!fZFmm zW~Sda9(Qi@pxO}$ARY+;t##Ao27usOqNt7Hwq6K7G1il@xitj=LIM&{N&#SuX;x4x zmG6FhCg-$PI;hQ=;1iZ>F>^~@)IPi;l}fX?SZ!QiO=X<|pSVkNpJuLHzW(FT_~W-v z?vFpkyE>8ee4d=7wKauH5~dd_M7d2Aa=ICC{Nj7Blqv&DQEP#j_VeWV&WXL>c=LLK zsmYg^_JiDb;%U!UxO%qjFAvsDFj-kzT2$GbV(ZopPM$i$z`!7jvEk07BcC=6FMt4` z*0u3Sy`0b~%#(0000K literal 0 HcmV?d00001 diff --git a/node_modules/express/node_modules/connect/lib/public/icons/page_white_copy.png b/node_modules/express/node_modules/connect/lib/public/icons/page_white_copy.png new file mode 100755 index 0000000000000000000000000000000000000000..a9f31a278e17993d8d4e13beac2f9d5f7b42d08f GIT binary patch literal 309 zcmV-50m}Y~P)sF~CC`eaI+m%Y8jfzomMvZQaNUIT3LIrJ$h)_W{ zwF|LDNlB-g`Hb_G$;>3F$9JF3WYR|3fy2C+_wH}*xp!_4fF2UN4lt#d26oXwru}hT z0+0%Vz-l&|Tdh_L-Ng1G2*RBtBncRx;99K)&+}s0whhxXp{go}$g&Jk6k|vfypI5M z!1sNGVaV?!*L7i87Bo%cfO@?S`bajL{R<($@$|PtgBRcCGIJ_2a|&kO>G-s2aR3E4 zjssoScUa;zIdOeGHBnH13G)W-zt$kUQgNfG;96b=v&4NzRt&@7nN%v3HsG`<<+F$cumMs448N!W3r&2Z*b~D5^$^d6Jxn@SFK5Q8*uKSR7x{I|H-_N1f+AD zSYC5@2K4OKL$==F9U@CH;ONNL(W}oZICHn;d?~pw?GRIsH*x-68Oy6SuK`)`{E)46 z9^3(-HXa#X89SBv?u_YP)WjsQrp;}0X?Bxrvf12IKW8>3t`e~W9|JS<{btTNbNT@EQIWBSNJTX8AMGXD z-SsH|s#>j9Xf~VMtyT-YMD}5^SWHTY5->o`k|d#AE_YQd79j`%GMS7FNvG3b7^Vy9 zn0HYCJy5MyQLoqKnW|JOp-?D*<2V^msZ>BOv0ANd2n7t@{=V;sZrQ>3c})5_%ms4z z7!qXwHHe~!QFj8aR~&*-3F?O|;#(ESIXP~Os%|~y^7c15*q5`gz2-5ol!fU92NIGT z_ves+>+Tf3gfcL?!nimYmR}cw*|BGULzI^7!;k#3K^YO#;!+vM@N~(99+<;fdqr zYPJm+pXYFYk;neQyXXEcTQDNQx57i`Okp9A#n?<7!{#tnKJdsF>utb@JH7dU01gfL zEK2hoPZAnO5+je3&^i*hWM`qCW^vLK!O*?U-#IvXV?#6koWqrwnD{j&K`7N>^tR3G z8zr1(qVOzcF#nF1&0MZ5C$l8*E^Uth0000zE0Ay_3@1Z_7#f-XWL#E{8Al7>L$ z0Rx7lnddoqAyfT%&#`$;v0@*5YdW3w z7mLNoa=FAshK% zDiy@zakyMAxr-H?iQDZi^!t5;Eno2A=?>mMx`Vg(Z!?<53LHLvfTPa`$mjDcX*Qdv zR;ylN4OH+m)fVX&Z#yZpUae;ss@a$K&})gHovkhr@w#xyPVlfVgXti1_357y%I-UHDvRWYvPEX+#g+j4Q9ayba zh7uQN1j%HQgA=Fp9DfODAU^*3*FCs^6IpO7xg`RUXyP)(;=d!ly=#I^l3e0Cub`{H Z`5PU3+D2e&<<>s`J(VpX#y^kqzQ;#=2x({YMw9Q&ndHT&`BD$#%Ql?{+)-OuSA`r}MWJ zVg+2Gc(GW}a=BERPNy^;kEz$|38dTYlFQ{%5S!g@|8f8D_!Nu9_Ni2glF1}xG8xi! zorc39&F6EPOeWOt_XS`W2H_Bo$MXugy}SEctJQj=(TLXTHL(jRXfzs>NF=0SHk;94 zF!&HjdZNX(3U3;LY64IMX__Xv%_wjLC!J2`0Jw?X=zPK$C$`&dYPDKaC={e16bcE@ zgun^<0k;ak*=xLE)@(Lqu~MmsFoMCLY&0Qog`NO(h@kyxaA%EbwJLy8sU*Vi`~52K zX0wrqW;_LmMq@evX4iAM9Od(Q0eHP$1%L|xAh@vrqB`HPQLon}f3aAka=9!3hr=O- z5F9`#J_7Jhah=U(4RjaRhkS4Xkk98kDz-`i!r|~~AQ1TFcDw(@<8g{aBE)l)PNxNE zI(RPyc>9e{@WGSMU%i7*v{!&P$WLz25)0oc=Dl-yy%xYZAm4b-rttL7UjR#%`#j_F R;_m(?iiXTHIMmcoLoO94I8;j@ zv^2DJ5#orqydFJX|Gm$_Bi_vyew+j6{r}$Qc@D1%fQqeAhJj)1!z4pP83k2MV2~s! zSt^w(<#HLFVBg_#xz1W8ioi(WY&Hu~6zil?DI^jJgu`K35(hkP)H%@Imesbg#5!Ps_$Ni*SiR8&sKb9?M`0-mH)gtg&YgRX#*TXz@Z+| z;|2H@xzE0TfuORhuO2k6#K8#sW^J`mQ0+E@$K`QkFV+DTlI$w{GJ;zid{*v9xeIe_ z$|Bp`@iKkgoFK3{4Z)#DWKV~W4K@5WZN+Ql_7%YxNqSx7%cWud&cX>)_PvD*UzxZg a%Kia9Rjz_59@~-t0000)l$0ECbfb-0$}>7z|u>IvuoHEmW&j4lzv=KA+EpIObc7e7{sGA)QVmnM@*^ z%|h38^m;wC+ilpk%>l#V5LCqP_y2_Cayd^XlX;j*r54R*lW!zbqtSpQNyz8(JVmWm zyV4S$2{Uhyc{Cb0QQbf{ZGT{Kr zvJi{K_&f+q^Pv4MK$hhS4TgFj_FD*rLOePdE-E^T7ZzTFCRUB`*?9&h(a#C!-v8lWG#k3AOJQaUey6Oasked^kDPe=Khg@7s584 zg`XfS1)&u*_c;I76#%`kkBfiZgKKo@0)9d6vZw=ExQUtV?eW{Y1Xv}=4X(2zy85d> Y0C^(qLv?Ui{{R3007*qoM6N<$f-gW7od5s; literal 0 HcmV?d00001 diff --git a/node_modules/express/node_modules/connect/lib/public/icons/page_white_edit.png b/node_modules/express/node_modules/connect/lib/public/icons/page_white_edit.png new file mode 100755 index 0000000000000000000000000000000000000000..b93e77600def75c9a144d3d0a5088a62c02cbb0b GIT binary patch literal 618 zcmV-w0+s!VP)$>5Y&axjp2O=VLu>*f>1L;s0)kkvKC!*u?s6CVL=HJ6oP~pNfZc; zsKr=bq;7MITw8NXw{SZm%59TId2x_9BQ zV86`NuvGI!>o^V!Na!=$7GJE{Cq`b+XwknM{UcGHFTTfmuS+ zm-zYC!P3+zmY;SG$?!fYkOih`QYaLxyF}A86h$GGN}kFj)_o*0e zjPMP%zTG7FYMAfO2Nn1D`D0Cj?Wl>5q%@CE10nX)KxpNmwk+!IWkzywiYD( zqUXiYYIq3qcRyMGJ;IY`(Gz~E$J$zu2+R{)xGlE*88b3WK6V*J>}2iPY1HH|tER0W z_+^^FdppY?o)Gt5M2`%xwRDH@R3G}^i1l4|6uchm0X0f!@&YdVLB5K&dd7Rv{)DXX zt^&vP;}kqj3f>94j+4xd93>s|Q!Ezi>?r8(Il$P}PFxSqu{d*!Y%*#cX(R0f|Juz# z3o0_xI14Al->1uky@W-rCI_%l&>PK^TXNSN{byMk2AI5vbwp!K-%-@!-vPR3iikL1L7HA!^!~ChCFU#lnGzp88=I z67V8PHBo4(l$u?-AKmT8?#_0rKW9dUNRbpLc`}piywAM9$xZ-3fR1C75T(BjCn-l* zjUcci2oXXo-}iqun@#)+`W@kL_-U&|2>MxZy~3IdmRm&8b)9!2%ksg3R)nNnT*TJOC=6{2hG86Dz+<^p6qfG5$i^UNUh+u)CD7O2 zK>Ioazn;U|+X0x$=feveYZL1W*Fm%e5P1sajd#eW#^5(ddx76*pt$^)b}$Q4oPabL zLc^HF>Z{8za;f$LtN0P$6C?1{X*jtXkRJ8IEeyiSzencvH3Ux_y>y^}wfJrRCQN#9 z?&e+C>sSAfrE%mZD5RfZ`gSndD)=P?+nG5Oq$zmY&-v+gc7R6c0u8^Ke#|XOq?gF@othF3zFpM8Il<8BJrWqBtF>b#_ye4{0)Xbu6j&@UIhRE002ov JPDHLkV1nWI9dZBw literal 0 HcmV?d00001 diff --git a/node_modules/express/node_modules/connect/lib/public/icons/page_white_excel.png b/node_modules/express/node_modules/connect/lib/public/icons/page_white_excel.png new file mode 100755 index 0000000000000000000000000000000000000000..b977d7e52e2446ea01201c5c7209ac3a05f12c9f GIT binary patch literal 663 zcmV;I0%-k-P)^@R5;6x zlTS!gQ5431_q{u#M2 zg&W%y6a}>qj1Z|7Vu&-DW6d~k-n;jnHsjb-q#u0C^W!_5^C=MlKq<8oNCQ6qS00!X z5eI;XP=g!^f}j{hku}E1zZ?XCjE;`p19k(Rh%^AQQ54xysU+ocx$c#f61Z4HnT#3u~FR(3>BnZniMIF4DouI8Hi4u>cAK%EN)5PO(ip3(% zIgBx+QYirR){Z8QwV$9Z(Mpt=L-Or3#bf-G@66}txq0yc*T(zNTBDT0T8rO^JeNbSI-Tzf5!pBioy4NwAN^?iN#{;fH1Jke4Xa`^fR8m z%h6dq%xX)S?7`zae))(Xst^Scp6B8FejQW?RLTM8@0=vnnntuRGBM2dpo>gbCnTD= z^<;=JuqdSf@O>Z8^XdR?s+KEfhDdB_#ahFj^giCtzT(s8kA$AViyTqaAR;KGaLzUU z<=GqA4bRwpX|IG~*x>pZ!@zLr`XQ`od>m(`;jz|M_*1GDO#$7;n74ppb8=eiqh760 x0yt}J1#p`gw$`o!R{d7zU9~!Un@nJV{4bstt4Au+Up@c;002ovPDHLkV1kWhGjjj{ literal 0 HcmV?d00001 diff --git a/node_modules/express/node_modules/connect/lib/public/icons/page_white_find.png b/node_modules/express/node_modules/connect/lib/public/icons/page_white_find.png new file mode 100755 index 0000000000000000000000000000000000000000..581843637079359a6a58fcdccf0763690c67b063 GIT binary patch literal 676 zcmV;V0$crwP)_k3`4d{s8lK_6bi^@vq&To98fNoK}7)fx$e2^Y&@<^jR_Ee+8}KG;X`@ z@bCyiolqX>bb1ZIs%QGnjzFU~L8H~d?e;*XP(h(S262}XyZ3a0h07r{KV?E70l+e- zE`%3x|M5#q+;HOC(h@A^M)7Rn13dm0&>K$j%k_F4wOWlsNCIH+!c_#{eS&TL8v4yc zcpnPEY`cQzZ$ILq{U-MA6Z6Z|1p!FZjQ}tXSb25J@HphEqX-6Hqo?-_Zn@{d#>2Ml zJGhxTAd&emK$lV-QK&VM&ix0Xy{GyS3Wp(+E1^8BhD3T0a)m-Lw@Lu4zQRrP)9(3F z^>$hh@N>OAXrmPYunLi|fJ$_*5i`46;M>~*5D{bp>-OL3{+!MJa`3kv~Q#QfQ%c z)1s}QE<_XaYBG;IuRF=td#+}fi4h(6HgoUyJLi0t(*dA^B)%@8kkG&bdM5P5^Z5WF z%d%>m^SbN0XeV)wbUOXn5Ag#A$gJx+7-OCkMM1S%MWIlTkbFLmOeW(&n&wUd&;`>p zVcRy$Z{K0=?SpNnP^;BYEEXleFbq(UY&LrXX$6qkJ~)8+b{=jj3HEXds;Z(?D%}}L zX3`39&dy=Zyar!ehA}e>w)(*vrCct{PI9^2Jpj&OZS8<3-@{0(gNv%1{)zAiLY+_^ zl}e>Ofd4&#Irj#7>=o=Uhv5IJ@?sN0^J|(WL2Uun$4}si6}TG-s3T#p&6GE<<2W)O zf{^Y2HlO#*QDvTp3v&d@;8*}aUC4lisG9(w7@d5Y8y)}U#FwCkqp*Mcgme4{&gGRf zlBfd`nF9cQBKB2_L{F8G2)7pAf$i)Ds`|}-c>pc^LRW{w4SQ)3N^BbZx)6BlCZts! zKph%`(m#xg-q3I7=(us;9<)*2%iuQ1J`oV3gU6V~T}^JU5714JN33&GwEEru0d}Uo U{MPL+lmGw#07*qoM6N<$f^vibe*gdg literal 0 HcmV?d00001 diff --git a/node_modules/express/node_modules/connect/lib/public/icons/page_white_freehand.png b/node_modules/express/node_modules/connect/lib/public/icons/page_white_freehand.png new file mode 100755 index 0000000000000000000000000000000000000000..8d719df5205f7415ce657e5c277db4533c82f346 GIT binary patch literal 639 zcmV-_0)YLAP)p{{sC7)XB-g4w*W1a1)XtvxrMYa1o?wn&v~3 zHnC|#(>B_M1d`_7gfzLiHy=0c<2kQQdXu*33(xYN_xYW39(cz9jEVT%VokB8|DoF~ z8u%Q5sdl@4VB7X#uh+v_;yOGY&pRi?378ghv)P1cngiAAb<}D#l*?rWDV0j_dc6Zk z-|P~AJZQCA=yWcQjG8fYnimzj*3KqTfN0Cy!G^$7)+bQ$+mHVd1J zvwOR^5Lm<|R+uyB1Nu4vL?d4qa3tn?9H7SZH@~u=fFHEDfSH|bHU6kh0O3%cLdyny z{`9S2Sw~WMy0MPy!64i`jdk4Z3>^+KIL_fN2V_d&ywBt`^IJpxUI$=YAph~5`;xCe Z{s%Y0vkUXDnO6V+002ovPDHLkV1loX8z=w( literal 0 HcmV?d00001 diff --git a/node_modules/express/node_modules/connect/lib/public/icons/page_white_gear.png b/node_modules/express/node_modules/connect/lib/public/icons/page_white_gear.png new file mode 100755 index 0000000000000000000000000000000000000000..106f5aa3611a4807ec8c21701c631730275089a4 GIT binary patch literal 402 zcmV;D0d4+?P)<@FR}JvtGRKa0_WfK^c7uXaFH3q@Y!Hnl8VySc`OtkPN3;#l*y*l23+99h*9JzA00}rAC!#M1dZ#v9YOBH|eC*${MmzzYjBu!!-< zK8tujf&(6i)1biy*F>4{f*Kd(IU-JsG&#b_@NgTnx@40)2@2%c;*=?-2Za=}O}7&( w%_K#(S>e1j&gfY?mR})n>>0+8p`iTe2d1K2h8#$+)&Kwi07*qoM6N<$f(2cptN;K2 literal 0 HcmV?d00001 diff --git a/node_modules/express/node_modules/connect/lib/public/icons/page_white_get.png b/node_modules/express/node_modules/connect/lib/public/icons/page_white_get.png new file mode 100755 index 0000000000000000000000000000000000000000..e4a1ecba1b60e54f3777717ed105cdde745b7184 GIT binary patch literal 516 zcmV+f0{i`mP)o)wchR-92qq~y6`XqbKmElbB3z{pkZs0VPF`CFvS?7jDn^mFo>d9Y&06* z&1MsS!M-CH3ee+h_sy)Ms%B*ec3R0RpVi9?*mU84yoq(Bw8 z<4(999dJJE!V%pWT~HGRIAb;(#O%2K3?uRpz}AfgE8e9q&OSdr^e^}lC$QXZz;S2A z)w>^oHy>?v)q--`!pmuBe96PxP0u*inQvyFW(llfv9 zXV1s*Jh`y2H%B3ZTA(AzpsQ?hb6_PyZ=c1?_B4fbl>G%!@ubJln=!)x0000#DY{xaiib^#X=YT4@yE_&2#eBulEdzjE`u&@G%2(&u{J-<}d(^uY4W_kMfEX z@!X)AR9F&FL?RJyJRUzvBoeqN{5kY`z3wcM0+du73~_0|*lac! z42Dw(Eg1o{Ash}P8jXrqN+1w`*XxDD;ShmPCZC7#4;wWbHoMvBl$=zF-`?*9j*Nbjd=v@OWt_BgKxP-3wd zy37?ATx&$b+&zRM!K;BD%Okw`Sb@&Pak8$KRX19jWZmC0&n*Ggv%j8nvSPDFw zEkV65AGOoBQ8kf`R|}Px*&INNS%osq9b{Fq2I(x6@xM>tg=vRLF?I`0rWzHyRc>}g~)F_Qn`A>)C_iwK%Z zrIJ;xR)UI1Y4Ozts|-Nho;q zVk9-bX)%F~!;63iu$Fk=VJn3~fmb5S@@)ZqjBT2{f`vT`b2}zxb0$o;EF@G3&BHK^ zc)`1kUzo^Qkk$?KFKHNBD?nP-MJ3b@&4fg;g5l2wMi^g?9qj+~@b;62o_U1_S1J`g z7m^UMg25FX1MJ5AQxAJ5F5WDt=$=-@JV-!LHA2vuxl9kN>PS8x??^AINH6LjF*#nbk4}=n3gfWp$kEX5IpHS zYiQ{@d7Nl&d$#+7-TckP&Q}N91e-C#5QQ<|d}62BjvZR2H60wE-&H<>}%WqH(_V;zPbB1rgSSSC(0? zWlQ#?N3UgnJ9m2C29w!SwoOo5_2Iq!<8vCyEoDoj@#oV($oJEg6Bj@;nD|2g8 s%L|>IZ381yx9RvPhV4J)*SeoEV4lyr#k*`nfWBbxboFyt=akR{0DpOPi2wiq literal 0 HcmV?d00001 diff --git a/node_modules/express/node_modules/connect/lib/public/icons/page_white_key.png b/node_modules/express/node_modules/connect/lib/public/icons/page_white_key.png new file mode 100755 index 0000000000000000000000000000000000000000..d61648452284da1bc28b10385f95b5d2bf027901 GIT binary patch literal 616 zcmV-u0+;=XP)-tZUVHjYHp;RjQ0M0pRlXN=mLv{hk9Ebp9&~+Wj-T9IkpzWPWd#fZ)d=zV^~S`;LE*!&u-?g42^wwN&Xr1~#d5ifl_2*B1OoS}CDno^8a50ArfE8;stQF>AP54J@H~%T zFz84s;dO!QJKD36(~!QOg!t_^gfFcSKDU4yK0+Ypg$NT^mIYcQ6bk*3P(lBLh7Df_ zTu=2xC#+-_%)|{Cv8zz0t|0y4D5M`xAc{gwOKc`ou<*&VjUREFHs1qd<_xSkKeTBt zgyCi=@jj;&Ns^GsWWaIUl0Y2azcDlF@u{(P*!+EH;lnU~b|Lv{4|4Hdkh!qoQHiE$ zY#y>KFA0QEw=4Z|uV{0A^`Y=D}hB$GP&<$bi8q(u;p^0(my3Rz7fP}|# zGZ&#uor4@c3q9r|f?H6-UZmfgKx(iV(MQ`MPWB>iC~SxnN5H*zb*A3#zWwgu&c|}3 zn^g87H{pdeasl%Lhmab&jC?lES}7C?4BFDNA<}20hoY@w_IU%i*T;}}wh!589}7~7 z#Ug`-R~4j&+K_y4kW@X7qLr-)S5qVKU)tO;+kXJ++{vPI@{hVK|PhMVVx_`)vx~zUs}c9O-Ok{00000NkvXXu0mjf DS5_-g literal 0 HcmV?d00001 diff --git a/node_modules/express/node_modules/connect/lib/public/icons/page_white_link.png b/node_modules/express/node_modules/connect/lib/public/icons/page_white_link.png new file mode 100755 index 0000000000000000000000000000000000000000..bf7bd1c9bfd78d689c73ba67cf914182933ee68c GIT binary patch literal 614 zcmV-s0-61ZP)OOAS;jTeL{ZSdz-%)SMH9tDF;N4B6%j=d15J&5qy`F#vB?Ar zqS1nH@%ny_XSI*Y>) z1f5QYdmzT>YciP<3WehS<{GovEaLGv27>{*-7f0&I$yJ^L%ZGPv1YT$V|u;*+ZCWz ztHI~CDVsuy($SfR6-`N~K?9GTB#l%%0h7 z-q`K-y~E)+s8lMyTrPL8^_pUo)9G|SluG5pPqw6!LJB_PzyJUM07*qoM6N<$f^=yZ AYybcN literal 0 HcmV?d00001 diff --git a/node_modules/express/node_modules/connect/lib/public/icons/page_white_magnify.png b/node_modules/express/node_modules/connect/lib/public/icons/page_white_magnify.png new file mode 100755 index 0000000000000000000000000000000000000000..f6b74cc40f82fc83e4dfa6e9647ccc1b34e6ed7e GIT binary patch literal 554 zcmV+_0@eMAP)Vb2f>2}Fa82O3m(Ob=t*sniin`NpInLyMJgI`saru@YOPfh zy4g0#G*cV!#N%;Gq9_VH9?v%kjS3Rb1j8^;C={$Gp=lbj z*(?%?geA!5^Pok%UauwjA)v4g2`HedDw4_Mk4hhBQt?e7YJ5(hcj|3dNu^TOPGnjB zTTsqd3GIZ=Bb`n=7no)dflv&K(lsWw?lH6T1Yht0F9qgIuzh}ym0%n<3d3EBWB*pg z+G!I0lbAEXyd>k|QNuwr4=KX1D+tLPv)j@C1=N4sA4NF9A>HcO3G47*Y6!+SrUH-7 z1hb;^#S=r|`aMh>J#dWruAEf}gcR(DRUC`ZUev&$Sbh0SgLiTXeeHEU<$_YV;9281 zym`igIE%Sm8DpDw7@71Tv^EB5xSdUR*0$Mqp+Wq8OoaZtOg52&)zZ;;M=7#C1Yd6x svjx>8ad4e2x|*xHHwRjcjs6zA0XLDUqKT6dS^xk507*qoM6N<$f*wetruo^Ag2=LamM1T#~4RmC^m`_ zs}H7d&XJ}mg+hU?tu0noRvyjI&o2SRAeYZFesYkts79I^jJ7!A7%6nJwq8O?iT55M z1OQ` zbL{!Cp5o*IRmE9PInMCSPjTwfT~J+EYkz}tjxY=fg5Yf6EQ@DG$0kMJ9h^&$W}9BU zP1oj2;?MWVkKIEl)r=Y;L^Cx2q|>!)qJJ8zE7-V*-Cf7V8_2#1c0N975t~+&QUpQJ z5(uo(-O_`%Rj@U@t>JYAgd!>L?0Idxtd#oW2gc!jinsAEva8|kF4#Ic**mmml_{d^$s}Q5Q)KCys4sfck5bP1SyeHwh2`A<@N&t2j0^lgHC_^(pAAPCNjwl+>AN%C4Ll>_8Hjda%9 oS~i=#*e)>KsPlg0=2)Qg6BCqJ=F8HdGXMYp07*qoM6N<$f@i)wr~m)} literal 0 HcmV?d00001 diff --git a/node_modules/express/node_modules/connect/lib/public/icons/page_white_office.png b/node_modules/express/node_modules/connect/lib/public/icons/page_white_office.png new file mode 100755 index 0000000000000000000000000000000000000000..a65bcb3e1e9613cd9e4950850db43d7025a5fdf9 GIT binary patch literal 779 zcmV+m1N8ifP)JNR5;6x zll@CmQ5eTZ^k*a#RQf}fVOdd`5NJh6S(>6Cf$wEW#f&JyAR#GAn9>Gml;nOf3WCDa z5({5&UB$(IF?G#$x4X@Ickg!Y-HU!Z_rzX=qAq-XI_LS^=lOCT0|0{#{kBkYDS7{3 zD`iu%E=`cDX_^#^#n$5SIQ|4Zhsk8>N|zXHXG@*41$i-7`Jr{8`3S_OEcmY|RF48wXkk?WpdVM4OePBSbfh z#4_=eXJg@3epx~gi>QbUmO}Bm(ENN3+@c?jWiKvSrm(o|W}Ud*?vy~fn1!V~Cl4kB zI-;c!8f~-v)jX82%EG($>?;KSD$64f2&4qQ#=Yyrcpy$57RAVuV#vKMP)0hT$r6m# zc^F^XaJ8R9Q|}x^NoJYIvYZkq-z}Tnj@UJK2l2H zG}p+VvtjP2Z%bsb$~7QLJ9#pC0dKi`ppOd^_V;ME6tdzC0PtV|r=@e@37O`%0k^=5^`%cf$eu00N17Ro!{^30krz>a%3j34C?*{Mt2^a4~ zK=P+Qq%|f;Tc&+9ps;@Mw`EE%rgs&#y=j6BUGg96oIqdwj9-fiy*N(|@o)eD002ov JPDHLkV1j#pUPb@_ literal 0 HcmV?d00001 diff --git a/node_modules/express/node_modules/connect/lib/public/icons/page_white_paint.png b/node_modules/express/node_modules/connect/lib/public/icons/page_white_paint.png new file mode 100755 index 0000000000000000000000000000000000000000..23a37b891c2f5faa3b8128d45373ceab794ca609 GIT binary patch literal 688 zcmV;h0#E&kP)PK^TXt2QS_@2qt2T|9~baC-vaPn=ziepcfAwB$0!O2Q)E}1e8!q+9)KT5JVKU z7HNY}h##OS-BxWHWjD0wrPDeEfUClHs%Q6&2u@FTOJkKMQN|_Rlw6rQz$gPzqGNtj z#ruSeFeh835JJFiM6vp@6M5bXj%k7CMt%SIwfbF_fD-3*Os`9Ly_Q3WQ_SX33E{pX z9_WIeeTCGQ3wYALpBcK+P-iuw;3i&7xCua37k5# z`>c`M@sGeC7cdsdz`aE9lOz!hPholbyz%T85LYf6O*@SA+9&+^7k>+4M8$A8iNQq{ zQvn8k?-+dU`Z@gK0z$EtPV#+`^OH`R@cE-cuE&_!D)SZGxmQxeobP_Zwq zMEgi6ePN45N`|V1so0uE8^}1xw8s;VM%Ai@7} z2-&Cyvez_-O4?6uv{zTaj|YeYEk34i~K@`8YW2g{x* zc;7z3lItpVy_et{Z-ZZ)<@*%{l7Ao8mu@V7*gz<_1##mwW*%LEwCdzNsVLYx2*T-J z#HeQ*_a=R~KDdVNk$EVgAIRl$oQi_(`_IrdJciDpH|Xe{K-YsMtc!cRnFi$qzsr4z z5*$;ecov%3->1{YNy6-Gf(Ecy&_I$CjI#laeuE+S120^|Vjsf)W&i*H07*qoM6N<$ Ef)^4A_ab^avY?n0hpS-#mn_4{O$e%cm-@NH=3`90Wq+3`~HKArSdfX`&Z12 z(CY$VW-MNtXX4xy%yUeE?}*~0-|iByA@ZrwXgph4S*bhcc5{HB!DFVm_v}P*g7+Q~K}7K0lcp(^N@X>U zV`{ZpeIf${R6Hgg4FL^`X$Eu75k(PE6ycl$AW0Ic)#@rR7Z(7;V?i-dR1K935Jgcx zPfkwK>2wGokf!Nih^ARp6-6arYFG#(9Ta!x93nFEjoA==z(g?#sDg?Owk?Mg7K+>l zWYsf(<`#+$h9Sp6gFOg_dd+80SkUpk&xM7h0`Sov9W73spU;GP073|VfZ&Gd$J$*0<~TV5aPS|qWH57|VJz+d0000vYep8SaFV10Q$h+;hIUPX_=v5b}%>Tm<(&j1&5;I!55C)oN0s(P%ZB zP3Q#ahfpXKWF@S?jm4U#fv)QovMhrriclyNs6-G12#3R##4PSZ0VY(dRWJ;Lwuq{# zAW0Gwi$yA^R4RZ!;W+L`f&%x{=D^VK#BBWL4Ys{;*!A7Q;!=dN<&D8*GzGaF4`hV4 zDbY0{NrMX>ZqF=0((gR5-zL$kC*b)!fwu{Euru|XrG<$^n#@)7i_>rCmRxnDq>$Y%gJaCkRd|tE*a2x05Pe!I^e13o69#&RQZ36s0 zB=O|K2Yi(jsMqThn}9t?f5E-)L^naZ+db$&%M$!bCdm=jv7?t_lB?3&%Ltq(>ESw? c;MI421LCcoDG!2@;{X5v07*qoM6N<$f`UZt7XSbN literal 0 HcmV?d00001 diff --git a/node_modules/express/node_modules/connect/lib/public/icons/page_white_picture.png b/node_modules/express/node_modules/connect/lib/public/icons/page_white_picture.png new file mode 100755 index 0000000000000000000000000000000000000000..134b6693687b2fa5fe36d48a9c0b8001f937c741 GIT binary patch literal 650 zcmV;50(Jd~P)VHAd+bMNh~)LLRqN>D)-jd9UvB%+hyKX5U|&4t0)fzgD-MPpQ$nHU%yoz=vI zMGb>1Xu!6Hw$NT~@Au<4P-+{9;Uw?&oj31uzH>xX0T7Xkz!(tn|Ed9-s_FqyReC13 z(ll)vW1O{Ck5ihay12Ob2ABc@RUI;zHpaMiyRDs0r>|D4rHw{ItJSJnYjt~jTbGuW z`X(~}?!&86q40R8<4zYw;$qi0^3ec=c&<&H;r`8W%H=Xymf^i;Wo6~<+}zx2UMzpC z*6MZN?(FMv`n|KO3(KFiUaucP0;Z!@LcUNa%8#vGK5aZ>wDgB0Gi=t*argWJcdlMQ z2#MpEX0wU+9&0U?N(F#OgpviU_Y{jYMsj65U3|PjwUOY}lUYj?MTiK_Il}NCVx-Eh zDx-TzMk7se+M#W_>?A1-x}ZXw3kkyz5kW)_hkjsi@RhKadN#H$Hq)$07*qoM6N<$f}lhwPXGV_ literal 0 HcmV?d00001 diff --git a/node_modules/express/node_modules/connect/lib/public/icons/page_white_powerpoint.png b/node_modules/express/node_modules/connect/lib/public/icons/page_white_powerpoint.png new file mode 100755 index 0000000000000000000000000000000000000000..c4eff0387d5888c638ba09473ba6d2369f7b56f0 GIT binary patch literal 588 zcmV-S0<-;zP)HU2HvUSp%6 z*n}iP63IK?dpo;h@sj9~pcxo;VVTc-XLiP@DgefqE#NE=@oyUd-&HjLpsLIuSFXV-EMck)oQ(A`s%*^&wf0(rNiNHsU%=0Rw;WC z(kbc37l6fo`-0uR!pYkYv8U^3?nsh^@pw!K0TH3uYyx1_2>|JbXPmfskJ|1YAw9w! z9`N)1^Aesr;y5Nr5-ODn)oOL|CGi}f9!&iVwpK$khlIX10X$H6^A_stBJqvLhU$?V`QXqKme*s~gVDJ4A;LTs_e15jhc1;By a82kqHEPVYFAD2!50000JNR5;6( zlS@kiVHAe7MZY2;Xi-5)WxDDgv@tCUl*&p14T@Z~3ThM5LP4tuQfLu@EnG;nXc<8S z6&3BN?fx-cv-Kp6>HRiNTHE>$X( zD&=w+?GWC>?RLAGC6Yix;an~UmSt)tSf}1VS6N1N2ONORdD? zaj}w6DAZZdOud9Ep?M?{iQWbE5^9HLLZZF|1kdy0Tu4InEuboP9@nvbZ-P0n4AZTy zyMRIxRDmUE#LdqYuD=-Qz4N^bC`_#S7vcLn1M}{J(Wl3#c4VWczu&)AjUlh(11>gp>f`wv{KnjF%!aA*Jk N002ovPDHLkV1kkt*XsZP literal 0 HcmV?d00001 diff --git a/node_modules/express/node_modules/connect/lib/public/icons/page_white_ruby.png b/node_modules/express/node_modules/connect/lib/public/icons/page_white_ruby.png new file mode 100755 index 0000000000000000000000000000000000000000..f59b7c4365fa1720af1aa04eb47167ddaa6eeed4 GIT binary patch literal 626 zcmV-&0*(ENP)ZS(e|#C2>JN4>y}l*tQ*E7zP@R2CCJnkW?xa6bgk%(hgtZ z0=~d?U3i`+Mvi4!&~+WPT1^NX#{u6&QIx+DE(oR{&T5&-ovF?@wGw)P&AtpHZa|G%V*GUUqL@@!d4V$`8=##4)ytY959JG zdc&Kho)&AL70^i z!PEmeeDWCB-UbK(*4JST44^tV2z_J(dn~+vBMJT97_7rzFio=~XczIv?PQ5$v%u~y zu(bteXb5I1h2zCV{Jc2~V{{yzZipgsP6;k264$*#5q?GzCm|CPa9CKqm4b116h3Pu z?+%Cm52plC8|5P0@igf2GV1KkCfk{Zecu=G@VNrf>s%g9c5D%@cfxVb6$nY`1IW=4 zt10QqSps_2JLp0f3I0j0u>#qA;v!+T))KEbCg|mo3q0pG{OR}p0fPds8+K~d>Hq)$ M07*qoM6N<$g1S2e3jhEB literal 0 HcmV?d00001 diff --git a/node_modules/express/node_modules/connect/lib/public/icons/page_white_stack.png b/node_modules/express/node_modules/connect/lib/public/icons/page_white_stack.png new file mode 100755 index 0000000000000000000000000000000000000000..44084add79b9a0fc3354d16bbd4b4b5ff8095da7 GIT binary patch literal 317 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6SkfJR9T^zbpD<_bdI{u9mbgZg z1m~xflqVLYGB~E>C#5QQ<|d}62BjvZR2H60wE-$R@9E+gqH(@-qA%AW0|7U8+xDRI z0k`B18}ImRw2g{jTGP$Pmx3yI6F_2s&$|`cJ!i0UN zB3H;=r{#{FwLaNVJ&hZl9+MTHGx1T^-A=Q0?hRb#8a~x50X%;`b6ik3cw=#XdxWy= zgrpBoDjpwP&g9<9h3x!k_B!?vuTJVkmIJ-U N;OXk;vd$@?2>|rNdMN+^ literal 0 HcmV?d00001 diff --git a/node_modules/express/node_modules/connect/lib/public/icons/page_white_star.png b/node_modules/express/node_modules/connect/lib/public/icons/page_white_star.png new file mode 100755 index 0000000000000000000000000000000000000000..3a1441c9a12062a4bb3d706000d3ca14399aebca GIT binary patch literal 565 zcmV-50?Pe~P)SCZIX8XZzY2l?gCw6LlgWJ5Avz#QX4|&mI8LN)w~J1vgL=KLAhlWz*=#m~gyvxa z&;iC6gb?aZvMdXxX`<0+D1hs_pqJ!wxqlEH;CJ)je~uL(gpi@v>!I0f_Kl=E(E+Tq z26na*9gribxx-Oft(HnstyXUUy!39&E-cI%J5Rsy;(PGZH{g{ty!HVC&yGPT3H8x# zw{^gBPW)O0FMoh{k%l<`1a|To_Wl&u&-GXm8izU|&<&utILc4wc6s@u1bmTz6x{qg zTw@7=FQRcg&r`h+gcR$*Jbv+*DPk7v)B@e0o2 z6IlBXW&8xh@9)YKiV~2>+z&XKd24JT55YWz&JtfvCg4r^~bLP79-yS@n$OW00000NkvXXu0mjf DStt2z literal 0 HcmV?d00001 diff --git a/node_modules/express/node_modules/connect/lib/public/icons/page_white_swoosh.png b/node_modules/express/node_modules/connect/lib/public/icons/page_white_swoosh.png new file mode 100755 index 0000000000000000000000000000000000000000..e7708292adabf4821612bfca032cbd019c63180b GIT binary patch literal 634 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 literal 0 HcmV?d00001 diff --git a/node_modules/express/node_modules/connect/lib/public/icons/page_white_width.png b/node_modules/express/node_modules/connect/lib/public/icons/page_white_width.png new file mode 100755 index 0000000000000000000000000000000000000000..1eb880947ddf3e745c29e8d9dc90f09c7e6e323c GIT binary patch literal 309 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6SkfJR9T^zbpD<_bdI{u9mbgZg z1m~xflqVLYGB~E>C#5QQ<|d}62BjvZR2H60wE-$R?&;zfqH(@;q9b3Efq-lM(nr^( z=EYR73-9e)UYMWsXy%?aZsD68Yyv^2$~6QgEcljw%kx>O(f-gQ?@fOOx3A-0+Qw?O zRx~W)kn~Qe2d6f9nMG#g9Q04Mk==M~N!Dglvxk!fgVh#w@ZV$IY1+Xc`d{d2UcaP~ zfWp)_Ivqj}l2SPy^9ZWy6rG9Yx4v67_uA&&9|XA~5-#3)W3%em1peD8RWH^#O%XoM zxMPud%}GTj#~*+7JMxTd!`{^Q+>(D3*|@KV`*G2;{QnANOxu1$r2xIe;OXk;vd$@? F2>@zac~<}c literal 0 HcmV?d00001 diff --git a/node_modules/express/node_modules/connect/lib/public/icons/page_white_word.png b/node_modules/express/node_modules/connect/lib/public/icons/page_white_word.png new file mode 100755 index 0000000000000000000000000000000000000000..ae8ecbf47672a874c0958d0d113a56162c2bd364 GIT binary patch literal 651 zcmV;60(AX}P)hkjP zNW|QGv-YFNLN^qH@tJycPNG5ti6B7;r4mEr#lr@*T8*M85D`{ZR^BWwF23T<%MYIh zdC)S*p=|xk^!~H=+HSZ183~y8v4|mYmZxt&)5{{~>J`>E223Q5>T$=~mtA71q-jdG z+eJhOAyBW^0k9Gk1+rX8)zFx((CG^&tDY>6XaS~Fy!WJON|Gdujg5^~Vzt@o%BcYLiNiTQSD`zL^ociBz_>bDlpw3kriQ@Z`bVsGz-_6N>$&gTDiKDTKR^ z-hB*tHa^>!oD~5TK^0UK5rZ}RBm50Bv}S-yA%s=Ha5RYb{)!z2N&$&64gfhybBu8p lh~_|?8^bu;BRYt{<}Yrwd83Y=s?Goa002ovPDHLkV1l%3CP4rI literal 0 HcmV?d00001 diff --git a/node_modules/express/node_modules/connect/lib/public/icons/page_white_world.png b/node_modules/express/node_modules/connect/lib/public/icons/page_white_world.png new file mode 100755 index 0000000000000000000000000000000000000000..6ed2490ed1432d5d667a76235360824a1088e928 GIT binary patch literal 734 zcmV<40wMj0P)JT{hN;C#tgf#9krG=I>5!<*aE1_(spcgF}<`n4i zJi-}^6UUeU4jUFwdCiVPDm%`Zx^UBa8J(mnR6wEgz^}o8;)M*Y(@l_!Kfv)}4+NuM zaPXE50z)r)9=D=SR|RIqfQ^j}Hu!fzMeQBo+@PZk1G8hOw|vBTvkx`HM)Xe9q3xao z@`p0`NO!2904FHSLA6E@Y-O6zH$DQzvq@aHsz}}<(!v(Z_+EodX%R&NZW75g+nENo zV0020rxE^;7d!067AN>6*+&YLp$9uH6F-=In`XC{Cn%+o|5)b&boEPr02w@|P*oGm QmjD0&07*qoM6N<$g78X0Q~&?~ literal 0 HcmV?d00001 diff --git a/node_modules/express/node_modules/connect/lib/public/icons/page_white_wrench.png b/node_modules/express/node_modules/connect/lib/public/icons/page_white_wrench.png new file mode 100755 index 0000000000000000000000000000000000000000..fecadd08afed92536be91ab12d8e37b6bf410d5d GIT binary patch literal 613 zcmV-r0-F7aP)wK%m(L+9IV|s|#(WRl-O^4GvaQsnHq|OstfO zIJ3}3<01}YGARE4m!7=)QisvlHUo!Qymx-@-t*p_129Ko-#pVI)6#!*kLj-AGXWNR zyA_{wKii_amK7^YT-v z6#plaNm#8`-kz@OvjIt^4%IN{@J3bR zRI}ME1Mv85p|%;RK>ViR>APPLB4;;BpCtqE@P+*7!G>I4UjNx~e>r3HA^tWCQ@S)l z{BslcSwL-CxQ&_ZZSv_g0Tu{yi*X){Mt|W7)lbE`SQxFP00000NkvXXu0mjf;)M*S literal 0 HcmV?d00001 diff --git a/node_modules/express/node_modules/connect/lib/public/icons/page_white_zip.png b/node_modules/express/node_modules/connect/lib/public/icons/page_white_zip.png new file mode 100755 index 0000000000000000000000000000000000000000..fd4bbccdf1643f4ff5022fbc59b82546e259317e GIT binary patch literal 386 zcmV-|0e$|7P)_QM!1S$Bhw4w+iRuFWf;tfR6D%SMJrb+tx zC9R6{2>Ou6#juIy6u(I?|;&Owi$sRB4^20apB5xE2 z#B9XekY66S6lzfCL!eEQRgo0LokTA55@Y#%_wN!TXPw^Q4IIXsG~v#u_4t;x_HM16EQ@QRY+rut&97&UefsPmLrQ5P zBC2kcbux9L%2bJz$P$XV$*zSxb2e@6_3O#;&!FD<&hLjGn%~%en;7)djE^d6!t$lW7GyIOKlQ46hr`Z zjLNuRDP_53dNoN?wd&HMgL^m1DXFU<5dQsrceN>fSz00000)O9XRTN^$%%`*Fg>ryDtc(lF@?b>dE!20r+y z#Q*>(wbV5H`-E4Do={CJp7=ERhw15hgZi)?jRG88 zzVz(5;g?Td1izJyO33bhjg2Qc7FVY@f9!o)Gu?DII~vm-Dc?}3M!fsgjP?F(7`rgg z+xOk8XD)e?Zl=5+un`5!7kr?F=eq)K-5uqr%yU$1hLv){Vlm=)*5~`lwMciiXFu*g z)*Jkz6AF>#zb(Vx`Iv{bdGZHtlW)v(y5k^|xgSUc9%0}S20nrYrO}78ofk?bV!5)4 z=Ngz@+$9N1>>mA%IWx`Fqa240bWkiW;2TZgd8CZS0U}@mknC;!2;wi$eI@`h0y2JS`Eae0CW}q(2(%!m8 zWq$`PDU>LT1_y*bBv#P5<@q0@ttz$hIH}YMDvAigCc=y*)jY-VOpTd;A8@3t7Xh4r z0KTWOk;N2Ox4!&&^4B*no$WtTX!BXB)rg!y8dvGgKBQKLJNXRRp0}Bsjd1|LNQX~c zbC~fjrk2iL@4dYF*vt;}dFn(%h)n_-vzEIHMOKRkdF%3Lq|zBgKm_h>TEq!))nWjq zzn;B!?!(dQcHu$#=JF`cS&W~C`WHFW^B!~MI#k)>1Vk&eQy8P1O`J6V04{D@|7d6^ zyBABnh-d^H0FX&L07M||E0n_dp4v&Q%PSE9p#R#Hq)`5I_(B5CE#q dxjPz0{s-<+c#AC!i7@~G002ovPDHLkV1iPlpuqqD literal 0 HcmV?d00001 diff --git a/node_modules/express/node_modules/connect/lib/public/style.css b/node_modules/express/node_modules/connect/lib/public/style.css new file mode 100644 index 0000000..32b6507 --- /dev/null +++ b/node_modules/express/node_modules/connect/lib/public/style.css @@ -0,0 +1,141 @@ +body { + margin: 0; + padding: 80px 100px; + font: 13px "Helvetica Neue", "Lucida Grande", "Arial"; + background: #ECE9E9 -webkit-gradient(linear, 0% 0%, 0% 100%, from(#fff), to(#ECE9E9)); + background: #ECE9E9 -moz-linear-gradient(top, #fff, #ECE9E9); + background-repeat: no-repeat; + color: #555; + -webkit-font-smoothing: antialiased; +} +h1, h2, h3 { + margin: 0; + font-size: 22px; + color: #343434; +} +h1 em, h2 em { + padding: 0 5px; + font-weight: normal; +} +h1 { + font-size: 60px; +} +h2 { + margin-top: 10px; +} +h3 { + margin: 5px 0 10px 0; + padding-bottom: 5px; + border-bottom: 1px solid #eee; + font-size: 18px; +} +ul { + margin: 0; + padding: 0; +} +ul li { + margin: 5px 0; + padding: 3px 8px; + list-style: none; +} +ul li:hover { + cursor: pointer; + color: #2e2e2e; +} +ul li .path { + padding-left: 5px; + font-weight: bold; +} +ul li .line { + padding-right: 5px; + font-style: italic; +} +ul li:first-child .path { + padding-left: 0; +} +p { + line-height: 1.5; +} +a { + color: #555; + text-decoration: none; +} +a:hover { + color: #303030; +} +#stacktrace { + margin-top: 15px; +} +.directory h1 { + margin-bottom: 15px; + font-size: 18px; +} +ul#files { + width: 100%; + height: 500px; +} +ul#files li { + padding: 0; +} +ul#files li img { + position: absolute; + top: 5px; + left: 5px; +} +ul#files li a { + position: relative; + display: block; + margin: 1px; + width: 30%; + height: 25px; + line-height: 25px; + text-indent: 8px; + float: left; + border: 1px solid transparent; + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + border-radius: 5px; + overflow: hidden; + text-overflow: ellipsis; +} +ul#files li a.icon { + text-indent: 25px; +} +ul#files li a:focus, +ul#files li a:hover { + outline: none; + background: rgba(255,255,255,0.65); + border: 1px solid #ececec; +} +ul#files li a.highlight { + -webkit-transition: background .4s ease-in-out; + background: #ffff4f; + border-color: #E9DC51; +} +#search { + display: block; + position: fixed; + top: 20px; + right: 20px; + width: 90px; + -webkit-transition: width ease 0.2s, opacity ease 0.4s; + -moz-transition: width ease 0.2s, opacity ease 0.4s; + -webkit-border-radius: 32px; + -moz-border-radius: 32px; + -webkit-box-shadow: inset 0px 0px 3px rgba(0, 0, 0, 0.25), inset 0px 1px 3px rgba(0, 0, 0, 0.7), 0px 1px 0px rgba(255, 255, 255, 0.03); + -moz-box-shadow: inset 0px 0px 3px rgba(0, 0, 0, 0.25), inset 0px 1px 3px rgba(0, 0, 0, 0.7), 0px 1px 0px rgba(255, 255, 255, 0.03); + -webkit-font-smoothing: antialiased; + text-align: left; + font: 13px "Helvetica Neue", Arial, sans-serif; + padding: 4px 10px; + border: none; + background: transparent; + margin-bottom: 0; + outline: none; + opacity: 0.7; + color: #888; +} +#search:focus { + width: 120px; + opacity: 1.0; +} diff --git a/node_modules/express/node_modules/connect/lib/utils.js b/node_modules/express/node_modules/connect/lib/utils.js new file mode 100644 index 0000000..d0bc172 --- /dev/null +++ b/node_modules/express/node_modules/connect/lib/utils.js @@ -0,0 +1,451 @@ + +/*! + * Connect - utils + * Copyright(c) 2010 Sencha Inc. + * Copyright(c) 2011 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var crypto = require('crypto') + , Path = require('path') + , fs = require('fs'); + +/** + * Flatten the given `arr`. + * + * @param {Array} arr + * @return {Array} + * @api private + */ + +exports.flatten = function(arr, ret){ + var ret = ret || [] + , len = arr.length; + for (var i = 0; i < len; ++i) { + if (Array.isArray(arr[i])) { + exports.flatten(arr[i], ret); + } else { + ret.push(arr[i]); + } + } + return ret; +}; + +/** + * Return md5 hash of the given string and optional encoding, + * defaulting to hex. + * + * utils.md5('wahoo'); + * // => "e493298061761236c96b02ea6aa8a2ad" + * + * @param {String} str + * @param {String} encoding + * @return {String} + * @api public + */ + +exports.md5 = function(str, encoding){ + return crypto + .createHash('md5') + .update(str) + .digest(encoding || 'hex'); +}; + +/** + * Merge object b with object a. + * + * var a = { foo: 'bar' } + * , b = { bar: 'baz' }; + * + * utils.merge(a, b); + * // => { foo: 'bar', bar: 'baz' } + * + * @param {Object} a + * @param {Object} b + * @return {Object} + * @api public + */ + +exports.merge = function(a, b){ + if (a && b) { + for (var key in b) { + a[key] = b[key]; + } + } + return a; +}; + +/** + * Escape the given string of `html`. + * + * @param {String} html + * @return {String} + * @api public + */ + +exports.escape = function(html){ + return String(html) + .replace(/&(?!\w+;)/g, '&') + .replace(//g, '>') + .replace(/"/g, '"'); +}; + + +/** + * Return a unique identifier with the given `len`. + * + * utils.uid(10); + * // => "FDaS435D2z" + * + * @param {Number} len + * @return {String} + * @api public + */ + +exports.uid = function(len) { + var buf = [] + , chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789' + , charlen = chars.length; + + for (var i = 0; i < len; ++i) { + buf.push(chars[getRandomInt(0, charlen - 1)]); + } + + return buf.join(''); +}; + +/** + * Parse the given cookie string into an object. + * + * @param {String} str + * @return {Object} + * @api public + */ + +exports.parseCookie = function(str){ + var obj = {} + , pairs = str.split(/[;,] */); + for (var i = 0, len = pairs.length; i < len; ++i) { + var pair = pairs[i] + , eqlIndex = pair.indexOf('=') + , key = pair.substr(0, eqlIndex).trim().toLowerCase() + , val = pair.substr(++eqlIndex, pair.length).trim(); + + // quoted values + if ('"' == val[0]) val = val.slice(1, -1); + + // only assign once + if (undefined == obj[key]) { + val = val.replace(/\+/g, ' '); + try { + obj[key] = decodeURIComponent(val); + } catch (err) { + if (err instanceof URIError) { + obj[key] = val; + } else { + throw err; + } + } + } + } + return obj; +}; + +/** + * Serialize the given object into a cookie string. + * + * utils.serializeCookie('name', 'tj', { httpOnly: true }) + * // => "name=tj; httpOnly" + * + * @param {String} name + * @param {String} val + * @param {Object} obj + * @return {String} + * @api public + */ + +exports.serializeCookie = function(name, val, obj){ + var pairs = [name + '=' + encodeURIComponent(val)] + , obj = obj || {}; + + if (obj.domain) pairs.push('domain=' + obj.domain); + if (obj.path) pairs.push('path=' + obj.path); + if (obj.expires) pairs.push('expires=' + obj.expires.toUTCString()); + if (obj.httpOnly) pairs.push('httpOnly'); + if (obj.secure) pairs.push('secure'); + + return pairs.join('; '); +}; + +/** + * Pause `data` and `end` events on the given `obj`. + * Middleware performing async tasks _should_ utilize + * this utility (or similar), to re-emit data once + * the async operation has completed, otherwise these + * events may be lost. + * + * var pause = utils.pause(req); + * fs.readFile(path, function(){ + * next(); + * pause.resume(); + * }); + * + * @param {Object} obj + * @return {Object} + * @api public + */ + +exports.pause = function(obj){ + var onData + , onEnd + , events = []; + + // buffer data + obj.on('data', onData = function(data, encoding){ + events.push(['data', data, encoding]); + }); + + // buffer end + obj.on('end', onEnd = function(data, encoding){ + events.push(['end', data, encoding]); + }); + + return { + end: function(){ + obj.removeListener('data', onData); + obj.removeListener('end', onEnd); + }, + resume: function(){ + this.end(); + for (var i = 0, len = events.length; i < len; ++i) { + obj.emit.apply(obj, events[i]); + } + } + }; +}; + +/** + * Check `req` and `res` to see if it has been modified. + * + * @param {IncomingMessage} req + * @param {ServerResponse} res + * @return {Boolean} + * @api public + */ + +exports.modified = function(req, res, headers) { + var headers = headers || res._headers || {} + , modifiedSince = req.headers['if-modified-since'] + , lastModified = headers['last-modified'] + , noneMatch = req.headers['if-none-match'] + , etag = headers['etag']; + + if (noneMatch) noneMatch = noneMatch.split(/ *, */); + + // check If-None-Match + if (noneMatch && etag && ~noneMatch.indexOf(etag)) { + return false; + } + + // check If-Modified-Since + if (modifiedSince && lastModified) { + modifiedSince = new Date(modifiedSince); + lastModified = new Date(lastModified); + // Ignore invalid dates + if (!isNaN(modifiedSince.getTime())) { + if (lastModified <= modifiedSince) return false; + } + } + + return true; +}; + +/** + * Strip `Content-*` headers from `res`. + * + * @param {ServerResponse} res + * @api public + */ + +exports.removeContentHeaders = function(res){ + Object.keys(res._headers).forEach(function(field){ + if (0 == field.indexOf('content')) { + res.removeHeader(field); + } + }); +}; + +/** + * Check if `req` is a conditional GET request. + * + * @param {IncomingMessage} req + * @return {Boolean} + * @api public + */ + +exports.conditionalGET = function(req) { + return req.headers['if-modified-since'] + || req.headers['if-none-match']; +}; + +/** + * Respond with 403 "Forbidden". + * + * @param {ServerResponse} res + * @api public + */ + +exports.forbidden = function(res) { + var body = 'Forbidden'; + res.setHeader('Content-Type', 'text/plain'); + res.setHeader('Content-Length', body.length); + res.statusCode = 403; + res.end(body); +}; + +/** + * Respond with 401 "Unauthorized". + * + * @param {ServerResponse} res + * @param {String} realm + * @api public + */ + +exports.unauthorized = function(res, realm) { + res.statusCode = 401; + res.setHeader('WWW-Authenticate', 'Basic realm="' + realm + '"'); + res.end('Unauthorized'); +}; + +/** + * Respond with 400 "Bad Request". + * + * @param {ServerResponse} res + * @api public + */ + +exports.badRequest = function(res) { + res.statusCode = 400; + res.end('Bad Request'); +}; + +/** + * Respond with 304 "Not Modified". + * + * @param {ServerResponse} res + * @param {Object} headers + * @api public + */ + +exports.notModified = function(res) { + exports.removeContentHeaders(res); + res.statusCode = 304; + res.end(); +}; + +/** + * Return an ETag in the form of `"-"` + * from the given `stat`. + * + * @param {Object} stat + * @return {String} + * @api public + */ + +exports.etag = function(stat) { + return '"' + stat.size + '-' + Number(stat.mtime) + '"'; +}; + +/** + * Parse "Range" header `str` relative to the given file `size`. + * + * @param {Number} size + * @param {String} str + * @return {Array} + * @api public + */ + +exports.parseRange = function(size, str){ + var valid = true; + var arr = str.substr(6).split(',').map(function(range){ + var range = range.split('-') + , start = parseInt(range[0], 10) + , end = parseInt(range[1], 10); + + // -500 + if (isNaN(start)) { + start = size - end; + end = size - 1; + // 500- + } else if (isNaN(end)) { + end = size - 1; + } + + // Invalid + if (isNaN(start) || isNaN(end) || start > end) valid = false; + + return { start: start, end: end }; + }); + return valid ? arr : undefined; +}; + +/** + * Parse the given Cache-Control `str`. + * + * @param {String} str + * @return {Object} + * @api public + */ + +exports.parseCacheControl = function(str){ + var directives = str.split(',') + , obj = {}; + + for(var i = 0, len = directives.length; i < len; i++) { + var parts = directives[i].split('=') + , key = parts.shift().trim() + , val = parseInt(parts.shift(), 10); + + obj[key] = isNaN(val) ? true : val; + } + + return obj; +}; + + +/** + * Convert array-like object to an `Array`. + * + * node-bench measured "16.5 times faster than Array.prototype.slice.call()" + * + * @param {Object} obj + * @return {Array} + * @api public + */ + +var toArray = exports.toArray = function(obj){ + var len = obj.length + , arr = new Array(len); + for (var i = 0; i < len; ++i) { + arr[i] = obj[i]; + } + return arr; +}; + +/** + * Retrun a random int, used by `utils.uid()` + * + * @param {Number} min + * @param {Number} max + * @return {Number} + * @api private + */ + +function getRandomInt(min, max) { + return Math.floor(Math.random() * (max - min + 1)) + min; +} diff --git a/node_modules/express/node_modules/connect/node_modules/formidable/.gitignore b/node_modules/express/node_modules/connect/node_modules/formidable/.gitignore new file mode 100644 index 0000000..b72f74f --- /dev/null +++ b/node_modules/express/node_modules/connect/node_modules/formidable/.gitignore @@ -0,0 +1,4 @@ +/test/tmp +*.upload +*.un~ +/node_modules diff --git a/node_modules/express/node_modules/connect/node_modules/formidable/.npmignore b/node_modules/express/node_modules/connect/node_modules/formidable/.npmignore new file mode 100644 index 0000000..4fbabb3 --- /dev/null +++ b/node_modules/express/node_modules/connect/node_modules/formidable/.npmignore @@ -0,0 +1,4 @@ +/test/tmp/ +*.upload +*.un~ +*.http diff --git a/node_modules/express/node_modules/connect/node_modules/formidable/Makefile b/node_modules/express/node_modules/connect/node_modules/formidable/Makefile new file mode 100644 index 0000000..8945872 --- /dev/null +++ b/node_modules/express/node_modules/connect/node_modules/formidable/Makefile @@ -0,0 +1,14 @@ +SHELL := /bin/bash + +test: + @./test/run.js + +build: npm test + +npm: + npm install . + +clean: + rm test/tmp/* + +.PHONY: test clean build diff --git a/node_modules/express/node_modules/connect/node_modules/formidable/Readme.md b/node_modules/express/node_modules/connect/node_modules/formidable/Readme.md new file mode 100644 index 0000000..68d6cba --- /dev/null +++ b/node_modules/express/node_modules/connect/node_modules/formidable/Readme.md @@ -0,0 +1,284 @@ +# Formidable + +## Purpose + +A node.js module for parsing form data, especially file uploads. + +## Current status + +This module was developed for [Transloadit](http://transloadit.com/), a service focused on uploading +and encoding images and videos. It has been battle-tested against hundreds of GB of file uploads from +a large variety of clients and is considered production-ready. + +## Features + +* Fast (~500mb/sec), non-buffering multipart parser +* Automatically writing file uploads to disk +* Low memory footprint +* Graceful error handling +* Very high test coverage + +## Changelog + +### v1.0.6 + +* Do not default to the default to the field name for file uploads where + filename="". + +### v1.0.5 + +* Support filename="" in multipart parts +* Explain unexpected end() errors in parser better + +**Note:** Starting with this version, formidable emits 'file' events for empty +file input fields. Previously those were incorrectly emitted as regular file +input fields with value = "". + +### v1.0.4 + +* Detect a good default tmp directory regardless of platform. (#88) + +### v1.0.3 + +* Fix problems with utf8 characters (#84) / semicolons in filenames (#58) +* Small performance improvements +* New test suite and fixture system + +### v1.0.2 + +* Exclude node\_modules folder from git +* Implement new `'aborted'` event +* Fix files in example folder to work with recent node versions +* Make gently a devDependency + +[See Commits](https://github.com/felixge/node-formidable/compare/v1.0.1...v1.0.2) + +### v1.0.1 + +* Fix package.json to refer to proper main directory. (#68, Dean Landolt) + +[See Commits](https://github.com/felixge/node-formidable/compare/v1.0.0...v1.0.1) + +### v1.0.0 + +* Add support for multipart boundaries that are quoted strings. (Jeff Craig) + +This marks the beginning of development on version 2.0 which will include +several architectural improvements. + +[See Commits](https://github.com/felixge/node-formidable/compare/v0.9.11...v1.0.0) + +### v0.9.11 + +* Emit `'progress'` event when receiving data, regardless of parsing it. (Tim Koschützki) +* Use [W3C FileAPI Draft](http://dev.w3.org/2006/webapi/FileAPI/) properties for File class + +**Important:** The old property names of the File class will be removed in a +future release. + +[See Commits](https://github.com/felixge/node-formidable/compare/v0.9.10...v0.9.11) + +### Older releases + +These releases were done before starting to maintain the above Changelog: + +* [v0.9.10](https://github.com/felixge/node-formidable/compare/v0.9.9...v0.9.10) +* [v0.9.9](https://github.com/felixge/node-formidable/compare/v0.9.8...v0.9.9) +* [v0.9.8](https://github.com/felixge/node-formidable/compare/v0.9.7...v0.9.8) +* [v0.9.7](https://github.com/felixge/node-formidable/compare/v0.9.6...v0.9.7) +* [v0.9.6](https://github.com/felixge/node-formidable/compare/v0.9.5...v0.9.6) +* [v0.9.5](https://github.com/felixge/node-formidable/compare/v0.9.4...v0.9.5) +* [v0.9.4](https://github.com/felixge/node-formidable/compare/v0.9.3...v0.9.4) +* [v0.9.3](https://github.com/felixge/node-formidable/compare/v0.9.2...v0.9.3) +* [v0.9.2](https://github.com/felixge/node-formidable/compare/v0.9.1...v0.9.2) +* [v0.9.1](https://github.com/felixge/node-formidable/compare/v0.9.0...v0.9.1) +* [v0.9.0](https://github.com/felixge/node-formidable/compare/v0.8.0...v0.9.0) +* [v0.9.0](https://github.com/felixge/node-formidable/compare/v0.8.0...v0.9.0) +* [v0.9.0](https://github.com/felixge/node-formidable/compare/v0.8.0...v0.9.0) +* [v0.9.0](https://github.com/felixge/node-formidable/compare/v0.8.0...v0.9.0) +* [v0.9.0](https://github.com/felixge/node-formidable/compare/v0.8.0...v0.9.0) +* [v0.9.0](https://github.com/felixge/node-formidable/compare/v0.8.0...v0.9.0) +* [v0.9.0](https://github.com/felixge/node-formidable/compare/v0.8.0...v0.9.0) +* [v0.9.0](https://github.com/felixge/node-formidable/compare/v0.8.0...v0.9.0) +* [v0.1.0](https://github.com/felixge/node-formidable/commits/v0.1.0) + +## Installation + +Via [npm](http://github.com/isaacs/npm): + + npm install formidable@latest + +Manually: + + git clone git://github.com/felixge/node-formidable.git formidable + vim my.js + # var formidable = require('./formidable'); + +Note: Formidable requires [gently](http://github.com/felixge/node-gently) to run the unit tests, but you won't need it for just using the library. + +## Example + +Parse an incoming file upload. + + var formidable = require('formidable'), + http = require('http'), + + sys = require('sys'); + + http.createServer(function(req, res) { + if (req.url == '/upload' && req.method.toLowerCase() == 'post') { + // parse a file upload + var form = new formidable.IncomingForm(); + form.parse(req, function(err, fields, files) { + res.writeHead(200, {'content-type': 'text/plain'}); + res.write('received upload:\n\n'); + res.end(sys.inspect({fields: fields, files: files})); + }); + return; + } + + // show a file upload form + res.writeHead(200, {'content-type': 'text/html'}); + res.end( + '
    '+ + '
    '+ + '
    '+ + ''+ + '
    ' + ); + }).listen(80); + +## API + +### formidable.IncomingForm + +#### new formidable.IncomingForm() + +Creates a new incoming form. + +#### incomingForm.encoding = 'utf-8' + +The encoding to use for incoming form fields. + +#### incomingForm.uploadDir = process.env.TMP || '/tmp' || process.cwd() + +The directory for placing file uploads in. You can move them later on using +`fs.rename()`. The default directory is picked at module load time depending on +the first existing directory from those listed above. + +#### incomingForm.keepExtensions = false + +If you want the files written to `incomingForm.uploadDir` to include the extensions of the original files, set this property to `true`. + +#### incomingForm.type + +Either 'multipart' or 'urlencoded' depending on the incoming request. + +#### incomingForm.maxFieldsSize = 2 * 1024 * 1024 + +Limits the amount of memory a field (not file) can allocate in bytes. +If this value is exceeded, an `'error'` event is emitted. The default +size is 2MB. + +#### incomingForm.bytesReceived + +The amount of bytes received for this form so far. + +#### incomingForm.bytesExpected + +The expected number of bytes in this form. + +#### incomingForm.parse(request, [cb]) + +Parses an incoming node.js `request` containing form data. If `cb` is provided, all fields an files are collected and passed to the callback: + + incomingForm.parse(req, function(err, fields, files) { + // ... + }); + +#### incomingForm.onPart(part) + +You may overwrite this method if you are interested in directly accessing the multipart stream. Doing so will disable any `'field'` / `'file'` events processing which would occur otherwise, making you fully responsible for handling the processing. + + incomingForm.onPart = function(part) { + part.addListener('data', function() { + // ... + }); + } + +If you want to use formidable to only handle certain parts for you, you can do so: + + incomingForm.onPart = function(part) { + if (!part.filename) { + // let formidable handle all non-file parts + incomingForm.handlePart(part); + } + } + +Check the code in this method for further inspiration. + +#### Event: 'progress' (bytesReceived, bytesExpected) + +Emitted after each incoming chunk of data that has been parsed. Can be used to roll your own progress bar. + +#### Event: 'field' (name, value) + +Emitted whenever a field / value pair has been received. + +#### Event: 'fileBegin' (name, file) + +Emitted whenever a new file is detected in the upload stream. Use this even if +you want to stream the file to somewhere else while buffering the upload on +the file system. + +#### Event: 'file' (name, file) + +Emitted whenever a field / file pair has been received. `file` is an instance of `File`. + +#### Event: 'error' (err) + +Emitted when there is an error processing the incoming form. A request that experiences an error is automatically paused, you will have to manually call `request.resume()` if you want the request to continue firing `'data'` events. + +#### Event: 'aborted' + +Emitted when the request was aborted by the user. Right now this can be due to a 'timeout' or 'close' event on the socket. In the future there will be a separate 'timeout' event (needs a change in the node core). + +#### Event: 'end' () + +Emitted when the entire request has been received, and all contained files have finished flushing to disk. This is a great place for you to send your response. + +### formidable.File + +#### file.size = 0 + +The size of the uploaded file in bytes. If the file is still being uploaded (see `'fileBegin'` event), this property says how many bytes of the file have been written to disk yet. + +#### file.path = null + +The path this file is being written to. You can modify this in the `'fileBegin'` event in +case you are unhappy with the way formidable generates a temporary path for your files. + +#### file.name = null + +The name this file had according to the uploading client. + +#### file.type = null + +The mime type of this file, according to the uploading client. + +#### file.lastModifiedDate = null + +A date object (or `null`) containing the time this file was last written to. Mostly +here for compatibility with the [W3C File API Draft](http://dev.w3.org/2006/webapi/FileAPI/). + +## License + +Formidable is licensed under the MIT license. + +## Ports + +* [multipart-parser](http://github.com/FooBarWidget/multipart-parser): a C++ parser based on formidable + +## Credits + +* [Ryan Dahl](http://twitter.com/ryah) for his work on [http-parser](http://github.com/ry/http-parser) which heavily inspired multipart_parser.js diff --git a/node_modules/express/node_modules/connect/node_modules/formidable/TODO b/node_modules/express/node_modules/connect/node_modules/formidable/TODO new file mode 100644 index 0000000..e1107f2 --- /dev/null +++ b/node_modules/express/node_modules/connect/node_modules/formidable/TODO @@ -0,0 +1,3 @@ +- Better bufferMaxSize handling approach +- Add tests for JSON parser pull request and merge it +- Implement QuerystringParser the same way as MultipartParser diff --git a/node_modules/express/node_modules/connect/node_modules/formidable/benchmark/bench-multipart-parser.js b/node_modules/express/node_modules/connect/node_modules/formidable/benchmark/bench-multipart-parser.js new file mode 100644 index 0000000..bff41f1 --- /dev/null +++ b/node_modules/express/node_modules/connect/node_modules/formidable/benchmark/bench-multipart-parser.js @@ -0,0 +1,70 @@ +require('../test/common'); +var multipartParser = require('../lib/multipart_parser'), + MultipartParser = multipartParser.MultipartParser, + parser = new MultipartParser(), + Buffer = require('buffer').Buffer, + boundary = '-----------------------------168072824752491622650073', + mb = 100, + buffer = createMultipartBuffer(boundary, mb * 1024 * 1024), + callbacks = + { partBegin: -1, + partEnd: -1, + headerField: -1, + headerValue: -1, + partData: -1, + end: -1, + }; + + +parser.initWithBoundary(boundary); +parser.onHeaderField = function() { + callbacks.headerField++; +}; + +parser.onHeaderValue = function() { + callbacks.headerValue++; +}; + +parser.onPartBegin = function() { + callbacks.partBegin++; +}; + +parser.onPartData = function() { + callbacks.partData++; +}; + +parser.onPartEnd = function() { + callbacks.partEnd++; +}; + +parser.onEnd = function() { + callbacks.end++; +}; + +var start = +new Date(), + nparsed = parser.write(buffer), + duration = +new Date - start, + mbPerSec = (mb / (duration / 1000)).toFixed(2); + +console.log(mbPerSec+' mb/sec'); + +assert.equal(nparsed, buffer.length); + +function createMultipartBuffer(boundary, size) { + var head = + '--'+boundary+'\r\n' + + 'content-disposition: form-data; name="field1"\r\n' + + '\r\n' + , tail = '\r\n--'+boundary+'--\r\n' + , buffer = new Buffer(size); + + buffer.write(head, 'ascii', 0); + buffer.write(tail, 'ascii', buffer.length - tail.length); + return buffer; +} + +process.on('exit', function() { + for (var k in callbacks) { + assert.equal(0, callbacks[k], k+' count off by '+callbacks[k]); + } +}); diff --git a/node_modules/express/node_modules/connect/node_modules/formidable/example/post.js b/node_modules/express/node_modules/connect/node_modules/formidable/example/post.js new file mode 100644 index 0000000..f6c15a6 --- /dev/null +++ b/node_modules/express/node_modules/connect/node_modules/formidable/example/post.js @@ -0,0 +1,43 @@ +require('../test/common'); +var http = require('http'), + util = require('util'), + formidable = require('formidable'), + server; + +server = http.createServer(function(req, res) { + if (req.url == '/') { + res.writeHead(200, {'content-type': 'text/html'}); + res.end( + '
    '+ + '
    '+ + '
    '+ + ''+ + '
    ' + ); + } else if (req.url == '/post') { + var form = new formidable.IncomingForm(), + fields = []; + + form + .on('error', function(err) { + res.writeHead(200, {'content-type': 'text/plain'}); + res.end('error:\n\n'+util.inspect(err)); + }) + .on('field', function(field, value) { + console.log(field, value); + fields.push([field, value]); + }) + .on('end', function() { + console.log('-> post done'); + res.writeHead(200, {'content-type': 'text/plain'}); + res.end('received fields:\n\n '+util.inspect(fields)); + }); + form.parse(req); + } else { + res.writeHead(404, {'content-type': 'text/plain'}); + res.end('404'); + } +}); +server.listen(TEST_PORT); + +console.log('listening on http://localhost:'+TEST_PORT+'/'); diff --git a/node_modules/express/node_modules/connect/node_modules/formidable/example/upload.js b/node_modules/express/node_modules/connect/node_modules/formidable/example/upload.js new file mode 100644 index 0000000..050cdd9 --- /dev/null +++ b/node_modules/express/node_modules/connect/node_modules/formidable/example/upload.js @@ -0,0 +1,48 @@ +require('../test/common'); +var http = require('http'), + util = require('util'), + formidable = require('formidable'), + server; + +server = http.createServer(function(req, res) { + if (req.url == '/') { + res.writeHead(200, {'content-type': 'text/html'}); + res.end( + '
    '+ + '
    '+ + '
    '+ + ''+ + '
    ' + ); + } else if (req.url == '/upload') { + var form = new formidable.IncomingForm(), + files = [], + fields = []; + + form.uploadDir = TEST_TMP; + + form + .on('field', function(field, value) { + console.log(field, value); + fields.push([field, value]); + }) + .on('file', function(field, file) { + console.log(field, file); + files.push([field, file]); + }) + .on('end', function() { + console.log('-> upload done'); + res.writeHead(200, {'content-type': 'text/plain'}); + res.write('received fields:\n\n '+util.inspect(fields)); + res.write('\n\n'); + res.end('received files:\n\n '+util.inspect(files)); + }); + form.parse(req); + } else { + res.writeHead(404, {'content-type': 'text/plain'}); + res.end('404'); + } +}); +server.listen(TEST_PORT); + +console.log('listening on http://localhost:'+TEST_PORT+'/'); diff --git a/node_modules/express/node_modules/connect/node_modules/formidable/index.js b/node_modules/express/node_modules/connect/node_modules/formidable/index.js new file mode 100644 index 0000000..be41032 --- /dev/null +++ b/node_modules/express/node_modules/connect/node_modules/formidable/index.js @@ -0,0 +1 @@ +module.exports = require('./lib/formidable'); \ No newline at end of file diff --git a/node_modules/express/node_modules/connect/node_modules/formidable/lib/file.js b/node_modules/express/node_modules/connect/node_modules/formidable/lib/file.js new file mode 100644 index 0000000..6dc8720 --- /dev/null +++ b/node_modules/express/node_modules/connect/node_modules/formidable/lib/file.js @@ -0,0 +1,61 @@ +if (global.GENTLY) require = GENTLY.hijack(require); + +var util = require('./util'), + WriteStream = require('fs').WriteStream, + EventEmitter = require('events').EventEmitter; + +function File(properties) { + EventEmitter.call(this); + + this.size = 0; + this.path = null; + this.name = null; + this.type = null; + this.lastModifiedDate = null; + + this._writeStream = null; + + for (var key in properties) { + this[key] = properties[key]; + } + + this._backwardsCompatibility(); +} +module.exports = File; +util.inherits(File, EventEmitter); + +// @todo Next release: Show error messages when accessing these +File.prototype._backwardsCompatibility = function() { + var self = this; + this.__defineGetter__('length', function() { + return self.size; + }); + this.__defineGetter__('filename', function() { + return self.name; + }); + this.__defineGetter__('mime', function() { + return self.type; + }); +}; + +File.prototype.open = function() { + this._writeStream = new WriteStream(this.path); +}; + +File.prototype.write = function(buffer, cb) { + var self = this; + this._writeStream.write(buffer, function() { + self.lastModifiedDate = new Date(); + self.size += buffer.length; + self.emit('progress', self.size); + cb(); + }); +}; + +File.prototype.end = function(cb) { + var self = this; + this._writeStream.end(function() { + self.emit('end'); + cb(); + }); +}; diff --git a/node_modules/express/node_modules/connect/node_modules/formidable/lib/incoming_form.js b/node_modules/express/node_modules/connect/node_modules/formidable/lib/incoming_form.js new file mode 100644 index 0000000..efc1dea --- /dev/null +++ b/node_modules/express/node_modules/connect/node_modules/formidable/lib/incoming_form.js @@ -0,0 +1,374 @@ +if (global.GENTLY) require = GENTLY.hijack(require); + +var fs = require('fs'); +var util = require('./util'), + path = require('path'), + File = require('./file'), + MultipartParser = require('./multipart_parser').MultipartParser, + QuerystringParser = require('./querystring_parser').QuerystringParser, + StringDecoder = require('string_decoder').StringDecoder, + EventEmitter = require('events').EventEmitter; + +function IncomingForm() { + if (!(this instanceof IncomingForm)) return new IncomingForm; + EventEmitter.call(this); + + this.error = null; + this.ended = false; + + this.maxFieldsSize = 2 * 1024 * 1024; + this.keepExtensions = false; + this.uploadDir = IncomingForm.UPLOAD_DIR; + this.encoding = 'utf-8'; + this.headers = null; + this.type = null; + + this.bytesReceived = null; + this.bytesExpected = null; + + this._parser = null; + this._flushing = 0; + this._fieldsSize = 0; +}; +util.inherits(IncomingForm, EventEmitter); +exports.IncomingForm = IncomingForm; + +IncomingForm.UPLOAD_DIR = (function() { + var dirs = [process.env.TMP, '/tmp', process.cwd()]; + for (var i = 0; i < dirs.length; i++) { + var dir = dirs[i]; + var isDirectory = false; + + try { + isDirectory = fs.statSync(dir).isDirectory(); + } catch (e) {} + + if (isDirectory) return dir; + } +})(); + +IncomingForm.prototype.parse = function(req, cb) { + this.pause = function() { + try { + req.pause(); + } catch (err) { + // the stream was destroyed + if (!this.ended) { + // before it was completed, crash & burn + this._error(err); + } + return false; + } + return true; + }; + + this.resume = function() { + try { + req.resume(); + } catch (err) { + // the stream was destroyed + if (!this.ended) { + // before it was completed, crash & burn + this._error(err); + } + return false; + } + + return true; + }; + + this.writeHeaders(req.headers); + + var self = this; + req + .on('error', function(err) { + self._error(err); + }) + .on('aborted', function() { + self.emit('aborted'); + }) + .on('data', function(buffer) { + self.write(buffer); + }) + .on('end', function() { + if (self.error) { + return; + } + + var err = self._parser.end(); + if (err) { + self._error(err); + } + }); + + if (cb) { + var fields = {}, files = {}; + this + .on('field', function(name, value) { + fields[name] = value; + }) + .on('file', function(name, file) { + files[name] = file; + }) + .on('error', function(err) { + cb(err, fields, files); + }) + .on('end', function() { + cb(null, fields, files); + }); + } + + return this; +}; + +IncomingForm.prototype.writeHeaders = function(headers) { + this.headers = headers; + this._parseContentLength(); + this._parseContentType(); +}; + +IncomingForm.prototype.write = function(buffer) { + if (!this._parser) { + this._error(new Error('unintialized parser')); + return; + } + + this.bytesReceived += buffer.length; + this.emit('progress', this.bytesReceived, this.bytesExpected); + + var bytesParsed = this._parser.write(buffer); + if (bytesParsed !== buffer.length) { + this._error(new Error('parser error, '+bytesParsed+' of '+buffer.length+' bytes parsed')); + } + + return bytesParsed; +}; + +IncomingForm.prototype.pause = function() { + // this does nothing, unless overwritten in IncomingForm.parse + return false; +}; + +IncomingForm.prototype.resume = function() { + // this does nothing, unless overwritten in IncomingForm.parse + return false; +}; + +IncomingForm.prototype.onPart = function(part) { + // this method can be overwritten by the user + this.handlePart(part); +}; + +IncomingForm.prototype.handlePart = function(part) { + var self = this; + + if (part.filename === undefined) { + var value = '' + , decoder = new StringDecoder(this.encoding); + + part.on('data', function(buffer) { + self._fieldsSize += buffer.length; + if (self._fieldsSize > self.maxFieldsSize) { + self._error(new Error('maxFieldsSize exceeded, received '+self._fieldsSize+' bytes of field data')); + return; + } + value += decoder.write(buffer); + }); + + part.on('end', function() { + self.emit('field', part.name, value); + }); + return; + } + + this._flushing++; + + var file = new File({ + path: this._uploadPath(part.filename), + name: part.filename, + type: part.mime, + }); + + this.emit('fileBegin', part.name, file); + + file.open(); + + part.on('data', function(buffer) { + self.pause(); + file.write(buffer, function() { + self.resume(); + }); + }); + + part.on('end', function() { + file.end(function() { + self._flushing--; + self.emit('file', part.name, file); + self._maybeEnd(); + }); + }); +}; + +IncomingForm.prototype._parseContentType = function() { + if (!this.headers['content-type']) { + this._error(new Error('bad content-type header, no content-type')); + return; + } + + if (this.headers['content-type'].match(/urlencoded/i)) { + this._initUrlencoded(); + return; + } + + if (this.headers['content-type'].match(/multipart/i)) { + var m; + if (m = this.headers['content-type'].match(/boundary=(?:"([^"]+)"|([^;]+))/i)) { + this._initMultipart(m[1] || m[2]); + } else { + this._error(new Error('bad content-type header, no multipart boundary')); + } + return; + } + + this._error(new Error('bad content-type header, unknown content-type: '+this.headers['content-type'])); +}; + +IncomingForm.prototype._error = function(err) { + if (this.error) { + return; + } + + this.error = err; + this.pause(); + this.emit('error', err); +}; + +IncomingForm.prototype._parseContentLength = function() { + if (this.headers['content-length']) { + this.bytesReceived = 0; + this.bytesExpected = parseInt(this.headers['content-length'], 10); + } +}; + +IncomingForm.prototype._newParser = function() { + return new MultipartParser(); +}; + +IncomingForm.prototype._initMultipart = function(boundary) { + this.type = 'multipart'; + + var parser = new MultipartParser(), + self = this, + headerField, + headerValue, + part; + + parser.initWithBoundary(boundary); + + parser.onPartBegin = function() { + part = new EventEmitter(); + part.headers = {}; + part.name = null; + part.filename = null; + part.mime = null; + headerField = ''; + headerValue = ''; + }; + + parser.onHeaderField = function(b, start, end) { + headerField += b.toString(self.encoding, start, end); + }; + + parser.onHeaderValue = function(b, start, end) { + headerValue += b.toString(self.encoding, start, end); + }; + + parser.onHeaderEnd = function() { + headerField = headerField.toLowerCase(); + part.headers[headerField] = headerValue; + + var m; + if (headerField == 'content-disposition') { + if (m = headerValue.match(/name="([^"]+)"/i)) { + part.name = m[1]; + } + + part.filename = self._fileName(headerValue); + } else if (headerField == 'content-type') { + part.mime = headerValue; + } + + headerField = ''; + headerValue = ''; + }; + + parser.onHeadersEnd = function() { + self.onPart(part); + }; + + parser.onPartData = function(b, start, end) { + part.emit('data', b.slice(start, end)); + }; + + parser.onPartEnd = function() { + part.emit('end'); + }; + + parser.onEnd = function() { + self.ended = true; + self._maybeEnd(); + }; + + this._parser = parser; +}; + +IncomingForm.prototype._fileName = function(headerValue) { + var m = headerValue.match(/filename="(.*?)"($|; )/i) + if (!m) return; + + var filename = m[1].substr(m[1].lastIndexOf('\\') + 1); + filename = filename.replace(/%22/g, '"'); + filename = filename.replace(/&#([\d]{4});/g, function(m, code) { + return String.fromCharCode(code); + }); + return filename; +}; + +IncomingForm.prototype._initUrlencoded = function() { + this.type = 'urlencoded'; + + var parser = new QuerystringParser() + , self = this; + + parser.onField = function(key, val) { + self.emit('field', key, val); + }; + + parser.onEnd = function() { + self.ended = true; + self._maybeEnd(); + }; + + this._parser = parser; +}; + +IncomingForm.prototype._uploadPath = function(filename) { + var name = ''; + for (var i = 0; i < 32; i++) { + name += Math.floor(Math.random() * 16).toString(16); + } + + if (this.keepExtensions) { + name += path.extname(filename); + } + + return path.join(this.uploadDir, name); +}; + +IncomingForm.prototype._maybeEnd = function() { + if (!this.ended || this._flushing) { + return; + } + + this.emit('end'); +}; diff --git a/node_modules/express/node_modules/connect/node_modules/formidable/lib/index.js b/node_modules/express/node_modules/connect/node_modules/formidable/lib/index.js new file mode 100644 index 0000000..7a6e3e1 --- /dev/null +++ b/node_modules/express/node_modules/connect/node_modules/formidable/lib/index.js @@ -0,0 +1,3 @@ +var IncomingForm = require('./incoming_form').IncomingForm; +IncomingForm.IncomingForm = IncomingForm; +module.exports = IncomingForm; diff --git a/node_modules/express/node_modules/connect/node_modules/formidable/lib/multipart_parser.js b/node_modules/express/node_modules/connect/node_modules/formidable/lib/multipart_parser.js new file mode 100644 index 0000000..9ca567c --- /dev/null +++ b/node_modules/express/node_modules/connect/node_modules/formidable/lib/multipart_parser.js @@ -0,0 +1,312 @@ +var Buffer = require('buffer').Buffer, + s = 0, + S = + { PARSER_UNINITIALIZED: s++, + START: s++, + START_BOUNDARY: s++, + HEADER_FIELD_START: s++, + HEADER_FIELD: s++, + HEADER_VALUE_START: s++, + HEADER_VALUE: s++, + HEADER_VALUE_ALMOST_DONE: s++, + HEADERS_ALMOST_DONE: s++, + PART_DATA_START: s++, + PART_DATA: s++, + PART_END: s++, + END: s++, + }, + + f = 1, + F = + { PART_BOUNDARY: f, + LAST_BOUNDARY: f *= 2, + }, + + LF = 10, + CR = 13, + SPACE = 32, + HYPHEN = 45, + COLON = 58, + A = 97, + Z = 122, + + lower = function(c) { + return c | 0x20; + }; + +for (var s in S) { + exports[s] = S[s]; +} + +function MultipartParser() { + this.boundary = null; + this.boundaryChars = null; + this.lookbehind = null; + this.state = S.PARSER_UNINITIALIZED; + + this.index = null; + this.flags = 0; +}; +exports.MultipartParser = MultipartParser; + +MultipartParser.stateToString = function(stateNumber) { + for (var state in S) { + var number = S[state]; + if (number === stateNumber) return state; + } +}; + +MultipartParser.prototype.initWithBoundary = function(str) { + this.boundary = new Buffer(str.length+4); + this.boundary.write('\r\n--', 'ascii', 0); + this.boundary.write(str, 'ascii', 4); + this.lookbehind = new Buffer(this.boundary.length+8); + this.state = S.START; + + this.boundaryChars = {}; + for (var i = 0; i < this.boundary.length; i++) { + this.boundaryChars[this.boundary[i]] = true; + } +}; + +MultipartParser.prototype.write = function(buffer) { + var self = this, + i = 0, + len = buffer.length, + prevIndex = this.index, + index = this.index, + state = this.state, + flags = this.flags, + lookbehind = this.lookbehind, + boundary = this.boundary, + boundaryChars = this.boundaryChars, + boundaryLength = this.boundary.length, + boundaryEnd = boundaryLength - 1, + bufferLength = buffer.length, + c, + cl, + + mark = function(name) { + self[name+'Mark'] = i; + }, + clear = function(name) { + delete self[name+'Mark']; + }, + callback = function(name, buffer, start, end) { + if (start !== undefined && start === end) { + return; + } + + var callbackSymbol = 'on'+name.substr(0, 1).toUpperCase()+name.substr(1); + if (callbackSymbol in self) { + self[callbackSymbol](buffer, start, end); + } + }, + dataCallback = function(name, clear) { + var markSymbol = name+'Mark'; + if (!(markSymbol in self)) { + return; + } + + if (!clear) { + callback(name, buffer, self[markSymbol], buffer.length); + self[markSymbol] = 0; + } else { + callback(name, buffer, self[markSymbol], i); + delete self[markSymbol]; + } + }; + + for (i = 0; i < len; i++) { + c = buffer[i]; + switch (state) { + case S.PARSER_UNINITIALIZED: + return i; + case S.START: + index = 0; + state = S.START_BOUNDARY; + case S.START_BOUNDARY: + if (index == boundary.length - 2) { + if (c != CR) { + return i; + } + index++; + break; + } else if (index - 1 == boundary.length - 2) { + if (c != LF) { + return i; + } + index = 0; + callback('partBegin'); + state = S.HEADER_FIELD_START; + break; + } + + if (c != boundary[index+2]) { + return i; + } + index++; + break; + case S.HEADER_FIELD_START: + state = S.HEADER_FIELD; + mark('headerField'); + index = 0; + case S.HEADER_FIELD: + if (c == CR) { + clear('headerField'); + state = S.HEADERS_ALMOST_DONE; + break; + } + + index++; + if (c == HYPHEN) { + break; + } + + if (c == COLON) { + if (index == 1) { + // empty header field + return i; + } + dataCallback('headerField', true); + state = S.HEADER_VALUE_START; + break; + } + + cl = lower(c); + if (cl < A || cl > Z) { + return i; + } + break; + case S.HEADER_VALUE_START: + if (c == SPACE) { + break; + } + + mark('headerValue'); + state = S.HEADER_VALUE; + case S.HEADER_VALUE: + if (c == CR) { + dataCallback('headerValue', true); + callback('headerEnd'); + state = S.HEADER_VALUE_ALMOST_DONE; + } + break; + case S.HEADER_VALUE_ALMOST_DONE: + if (c != LF) { + return i; + } + state = S.HEADER_FIELD_START; + break; + case S.HEADERS_ALMOST_DONE: + if (c != LF) { + return i; + } + + callback('headersEnd'); + state = S.PART_DATA_START; + break; + case S.PART_DATA_START: + state = S.PART_DATA + mark('partData'); + case S.PART_DATA: + prevIndex = index; + + if (index == 0) { + // boyer-moore derrived algorithm to safely skip non-boundary data + i += boundaryEnd; + while (i < bufferLength && !(buffer[i] in boundaryChars)) { + i += boundaryLength; + } + i -= boundaryEnd; + c = buffer[i]; + } + + if (index < boundary.length) { + if (boundary[index] == c) { + if (index == 0) { + dataCallback('partData', true); + } + index++; + } else { + index = 0; + } + } else if (index == boundary.length) { + index++; + if (c == CR) { + // CR = part boundary + flags |= F.PART_BOUNDARY; + } else if (c == HYPHEN) { + // HYPHEN = end boundary + flags |= F.LAST_BOUNDARY; + } else { + index = 0; + } + } else if (index - 1 == boundary.length) { + if (flags & F.PART_BOUNDARY) { + index = 0; + if (c == LF) { + // unset the PART_BOUNDARY flag + flags &= ~F.PART_BOUNDARY; + callback('partEnd'); + callback('partBegin'); + state = S.HEADER_FIELD_START; + break; + } + } else if (flags & F.LAST_BOUNDARY) { + if (c == HYPHEN) { + callback('partEnd'); + callback('end'); + state = S.END; + } else { + index = 0; + } + } else { + index = 0; + } + } + + if (index > 0) { + // when matching a possible boundary, keep a lookbehind reference + // in case it turns out to be a false lead + lookbehind[index-1] = c; + } else if (prevIndex > 0) { + // if our boundary turned out to be rubbish, the captured lookbehind + // belongs to partData + callback('partData', lookbehind, 0, prevIndex); + prevIndex = 0; + mark('partData'); + + // reconsider the current character even so it interrupted the sequence + // it could be the beginning of a new sequence + i--; + } + + break; + case S.END: + break; + default: + return i; + } + } + + dataCallback('headerField'); + dataCallback('headerValue'); + dataCallback('partData'); + + this.index = index; + this.state = state; + this.flags = flags; + + return len; +}; + +MultipartParser.prototype.end = function() { + if (this.state != S.END) { + return new Error('MultipartParser.end(): stream ended unexpectedly: ' + this.explain()); + } +}; + +MultipartParser.prototype.explain = function() { + return 'state = ' + MultipartParser.stateToString(this.state); +}; diff --git a/node_modules/express/node_modules/connect/node_modules/formidable/lib/querystring_parser.js b/node_modules/express/node_modules/connect/node_modules/formidable/lib/querystring_parser.js new file mode 100644 index 0000000..63f109e --- /dev/null +++ b/node_modules/express/node_modules/connect/node_modules/formidable/lib/querystring_parser.js @@ -0,0 +1,25 @@ +if (global.GENTLY) require = GENTLY.hijack(require); + +// This is a buffering parser, not quite as nice as the multipart one. +// If I find time I'll rewrite this to be fully streaming as well +var querystring = require('querystring'); + +function QuerystringParser() { + this.buffer = ''; +}; +exports.QuerystringParser = QuerystringParser; + +QuerystringParser.prototype.write = function(buffer) { + this.buffer += buffer.toString('ascii'); + return buffer.length; +}; + +QuerystringParser.prototype.end = function() { + var fields = querystring.parse(this.buffer); + for (var field in fields) { + this.onField(field, fields[field]); + } + this.buffer = ''; + + this.onEnd(); +}; \ No newline at end of file diff --git a/node_modules/express/node_modules/connect/node_modules/formidable/lib/util.js b/node_modules/express/node_modules/connect/node_modules/formidable/lib/util.js new file mode 100644 index 0000000..e9493e9 --- /dev/null +++ b/node_modules/express/node_modules/connect/node_modules/formidable/lib/util.js @@ -0,0 +1,6 @@ +// Backwards compatibility ... +try { + module.exports = require('util'); +} catch (e) { + module.exports = require('sys'); +} diff --git a/node_modules/express/node_modules/connect/node_modules/formidable/package.json b/node_modules/express/node_modules/connect/node_modules/formidable/package.json new file mode 100644 index 0000000..1c285d5 --- /dev/null +++ b/node_modules/express/node_modules/connect/node_modules/formidable/package.json @@ -0,0 +1,19 @@ +{ + "name": "formidable", + "version": "1.0.7", + "dependencies": {}, + "devDependencies": { + "gently": "0.8.0", + "far": "0.0.7", + "fast-or-slow": "0.0.5", + "findit": "0.1.1", + "hashish": "0.0.4" + }, + "directories": { + "lib": "./lib" + }, + "main": "./lib/index", + "engines": { + "node": "*" + } +} \ No newline at end of file diff --git a/node_modules/express/node_modules/connect/node_modules/formidable/test/common.js b/node_modules/express/node_modules/connect/node_modules/formidable/test/common.js new file mode 100644 index 0000000..30172ec --- /dev/null +++ b/node_modules/express/node_modules/connect/node_modules/formidable/test/common.js @@ -0,0 +1,20 @@ +var mysql = require('..'); +var path = require('path'); + +var root = path.join(__dirname, '../'); +exports.dir = { + root: root, + lib: root + '/lib', + fixture: root + '/test/fixture', + tmp: root + '/test/tmp', +}; + +exports.port = 13532; + +exports.formidable = require('..'); +exports.fastOrSlow = require('fast-or-slow'); +exports.assert = require('assert'); + +exports.require = function(lib) { + return require(exports.dir.lib + '/' + lib); +}; diff --git a/node_modules/express/node_modules/connect/node_modules/formidable/test/fast/test-incoming-form.js b/node_modules/express/node_modules/connect/node_modules/formidable/test/fast/test-incoming-form.js new file mode 100644 index 0000000..14a4d06 --- /dev/null +++ b/node_modules/express/node_modules/connect/node_modules/formidable/test/fast/test-incoming-form.js @@ -0,0 +1,45 @@ +var common = require('../common'); +var test = common.fastOrSlow.fast(); +var assert = common.assert; + +var IncomingForm = common.require('incoming_form').IncomingForm; + +var form; +test.before(function() { + form = new IncomingForm(); +}); + +function makeHeader(filename) { + return 'Content-Disposition: form-data; name="upload"; filename="' + filename + '"'; +} + +test('#_fileName with regular characters', function() { + var filename = 'foo.txt'; + assert.equal(form._fileName(makeHeader(filename)), 'foo.txt'); +}); + +test('#_fileName with unescaped quote', function() { + var filename = 'my".txt'; + assert.equal(form._fileName(makeHeader(filename)), 'my".txt'); +}); + +test('#_fileName with escaped quote', function() { + var filename = 'my%22.txt'; + assert.equal(form._fileName(makeHeader(filename)), 'my".txt'); +}); + +test('#_fileName with bad quote and additional sub-header', function() { + var filename = 'my".txt'; + var header = makeHeader(filename) + '; foo="bar"'; + assert.equal(form._fileName(header), filename); +}); + +test('#_fileName with semicolon', function() { + var filename = 'my;.txt'; + assert.equal(form._fileName(makeHeader(filename)), 'my;.txt'); +}); + +test('#_fileName with utf8 character', function() { + var filename = 'my☃.txt'; + assert.equal(form._fileName(makeHeader(filename)), 'my☃.txt'); +}); diff --git a/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/file/funkyfilename.txt b/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/file/funkyfilename.txt new file mode 100644 index 0000000..e7a4785 --- /dev/null +++ b/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/file/funkyfilename.txt @@ -0,0 +1 @@ +I am a text file with a funky name! diff --git a/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/file/plain.txt b/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/file/plain.txt new file mode 100644 index 0000000..9b6903e --- /dev/null +++ b/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/file/plain.txt @@ -0,0 +1 @@ +I am a plain text file diff --git a/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/http/special-chars-in-filename/info.md b/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/http/special-chars-in-filename/info.md new file mode 100644 index 0000000..3c9dbe3 --- /dev/null +++ b/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/http/special-chars-in-filename/info.md @@ -0,0 +1,3 @@ +* Opera does not allow submitting this file, it shows a warning to the + user that the file could not be found instead. Tested in 9.8, 11.51 on OSX. + Reported to Opera on 08.09.2011 (tracking email DSK-346009@bugs.opera.com). diff --git a/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/js/no-filename.js b/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/js/no-filename.js new file mode 100644 index 0000000..0bae449 --- /dev/null +++ b/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/js/no-filename.js @@ -0,0 +1,3 @@ +module.exports['generic.http'] = [ + {type: 'file', name: 'upload', filename: '', fixture: 'plain.txt'}, +]; diff --git a/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/js/special-chars-in-filename.js b/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/js/special-chars-in-filename.js new file mode 100644 index 0000000..eb76fdc --- /dev/null +++ b/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/js/special-chars-in-filename.js @@ -0,0 +1,21 @@ +var properFilename = 'funkyfilename.txt'; + +function expect(filename) { + return [ + {type: 'field', name: 'title', value: 'Weird filename'}, + {type: 'file', name: 'upload', filename: filename, fixture: properFilename}, + ]; +}; + +var webkit = " ? % * | \" < > . ? ; ' @ # $ ^ & ( ) - _ = + { } [ ] ` ~.txt"; +var ffOrIe = " ? % * | \" < > . ☃ ; ' @ # $ ^ & ( ) - _ = + { } [ ] ` ~.txt"; + +module.exports = { + 'osx-chrome-13.http' : expect(webkit), + 'osx-firefox-3.6.http' : expect(ffOrIe), + 'osx-safari-5.http' : expect(webkit), + 'xp-chrome-12.http' : expect(webkit), + 'xp-ie-7.http' : expect(ffOrIe), + 'xp-ie-8.http' : expect(ffOrIe), + 'xp-safari-5.http' : expect(webkit), +}; diff --git a/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/multipart.js b/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/multipart.js new file mode 100644 index 0000000..a476169 --- /dev/null +++ b/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/multipart.js @@ -0,0 +1,72 @@ +exports['rfc1867'] = + { boundary: 'AaB03x', + raw: + '--AaB03x\r\n'+ + 'content-disposition: form-data; name="field1"\r\n'+ + '\r\n'+ + 'Joe Blow\r\nalmost tricked you!\r\n'+ + '--AaB03x\r\n'+ + 'content-disposition: form-data; name="pics"; filename="file1.txt"\r\n'+ + 'Content-Type: text/plain\r\n'+ + '\r\n'+ + '... contents of file1.txt ...\r\r\n'+ + '--AaB03x--\r\n', + parts: + [ { headers: { + 'content-disposition': 'form-data; name="field1"', + }, + data: 'Joe Blow\r\nalmost tricked you!', + }, + { headers: { + 'content-disposition': 'form-data; name="pics"; filename="file1.txt"', + 'Content-Type': 'text/plain', + }, + data: '... contents of file1.txt ...\r', + } + ] + }; + +exports['noTrailing\r\n'] = + { boundary: 'AaB03x', + raw: + '--AaB03x\r\n'+ + 'content-disposition: form-data; name="field1"\r\n'+ + '\r\n'+ + 'Joe Blow\r\nalmost tricked you!\r\n'+ + '--AaB03x\r\n'+ + 'content-disposition: form-data; name="pics"; filename="file1.txt"\r\n'+ + 'Content-Type: text/plain\r\n'+ + '\r\n'+ + '... contents of file1.txt ...\r\r\n'+ + '--AaB03x--', + parts: + [ { headers: { + 'content-disposition': 'form-data; name="field1"', + }, + data: 'Joe Blow\r\nalmost tricked you!', + }, + { headers: { + 'content-disposition': 'form-data; name="pics"; filename="file1.txt"', + 'Content-Type': 'text/plain', + }, + data: '... contents of file1.txt ...\r', + } + ] + }; + +exports['emptyHeader'] = + { boundary: 'AaB03x', + raw: + '--AaB03x\r\n'+ + 'content-disposition: form-data; name="field1"\r\n'+ + ': foo\r\n'+ + '\r\n'+ + 'Joe Blow\r\nalmost tricked you!\r\n'+ + '--AaB03x\r\n'+ + 'content-disposition: form-data; name="pics"; filename="file1.txt"\r\n'+ + 'Content-Type: text/plain\r\n'+ + '\r\n'+ + '... contents of file1.txt ...\r\r\n'+ + '--AaB03x--\r\n', + expectError: true, + }; diff --git a/node_modules/express/node_modules/connect/node_modules/formidable/test/legacy/common.js b/node_modules/express/node_modules/connect/node_modules/formidable/test/legacy/common.js new file mode 100644 index 0000000..2b98598 --- /dev/null +++ b/node_modules/express/node_modules/connect/node_modules/formidable/test/legacy/common.js @@ -0,0 +1,24 @@ +var path = require('path'), + fs = require('fs'); + +try { + global.Gently = require('gently'); +} catch (e) { + throw new Error('this test suite requires node-gently'); +} + +exports.lib = path.join(__dirname, '../../lib'); + +global.GENTLY = new Gently(); + +global.assert = require('assert'); +global.TEST_PORT = 13532; +global.TEST_FIXTURES = path.join(__dirname, '../fixture'); +global.TEST_TMP = path.join(__dirname, '../tmp'); + +// Stupid new feature in node that complains about gently attaching too many +// listeners to process 'exit'. This is a workaround until I can think of a +// better way to deal with this. +if (process.setMaxListeners) { + process.setMaxListeners(10000); +} diff --git a/node_modules/express/node_modules/connect/node_modules/formidable/test/legacy/integration/test-multipart-parser.js b/node_modules/express/node_modules/connect/node_modules/formidable/test/legacy/integration/test-multipart-parser.js new file mode 100644 index 0000000..75232aa --- /dev/null +++ b/node_modules/express/node_modules/connect/node_modules/formidable/test/legacy/integration/test-multipart-parser.js @@ -0,0 +1,80 @@ +var common = require('../common'); +var CHUNK_LENGTH = 10, + multipartParser = require(common.lib + '/multipart_parser'), + MultipartParser = multipartParser.MultipartParser, + parser = new MultipartParser(), + fixtures = require(TEST_FIXTURES + '/multipart'), + Buffer = require('buffer').Buffer; + +Object.keys(fixtures).forEach(function(name) { + var fixture = fixtures[name], + buffer = new Buffer(Buffer.byteLength(fixture.raw, 'binary')), + offset = 0, + chunk, + nparsed, + + parts = [], + part = null, + headerField, + headerValue, + endCalled = ''; + + parser.initWithBoundary(fixture.boundary); + parser.onPartBegin = function() { + part = {headers: {}, data: ''}; + parts.push(part); + headerField = ''; + headerValue = ''; + }; + + parser.onHeaderField = function(b, start, end) { + headerField += b.toString('ascii', start, end); + }; + + parser.onHeaderValue = function(b, start, end) { + headerValue += b.toString('ascii', start, end); + } + + parser.onHeaderEnd = function() { + part.headers[headerField] = headerValue; + headerField = ''; + headerValue = ''; + }; + + parser.onPartData = function(b, start, end) { + var str = b.toString('ascii', start, end); + part.data += b.slice(start, end); + } + + parser.onEnd = function() { + endCalled = true; + } + + buffer.write(fixture.raw, 'binary', 0); + + while (offset < buffer.length) { + if (offset + CHUNK_LENGTH < buffer.length) { + chunk = buffer.slice(offset, offset+CHUNK_LENGTH); + } else { + chunk = buffer.slice(offset, buffer.length); + } + offset = offset + CHUNK_LENGTH; + + nparsed = parser.write(chunk); + if (nparsed != chunk.length) { + if (fixture.expectError) { + return; + } + puts('-- ERROR --'); + p(chunk.toString('ascii')); + throw new Error(chunk.length+' bytes written, but only '+nparsed+' bytes parsed!'); + } + } + + if (fixture.expectError) { + throw new Error('expected parse error did not happen'); + } + + assert.ok(endCalled); + assert.deepEqual(parts, fixture.parts); +}); diff --git a/node_modules/express/node_modules/connect/node_modules/formidable/test/legacy/simple/test-file.js b/node_modules/express/node_modules/connect/node_modules/formidable/test/legacy/simple/test-file.js new file mode 100644 index 0000000..52ceedb --- /dev/null +++ b/node_modules/express/node_modules/connect/node_modules/formidable/test/legacy/simple/test-file.js @@ -0,0 +1,104 @@ +var common = require('../common'); +var WriteStreamStub = GENTLY.stub('fs', 'WriteStream'); + +var File = require(common.lib + '/file'), + EventEmitter = require('events').EventEmitter, + file, + gently; + +function test(test) { + gently = new Gently(); + file = new File(); + test(); + gently.verify(test.name); +} + +test(function constructor() { + assert.ok(file instanceof EventEmitter); + assert.strictEqual(file.size, 0); + assert.strictEqual(file.path, null); + assert.strictEqual(file.name, null); + assert.strictEqual(file.type, null); + assert.strictEqual(file.lastModifiedDate, null); + + assert.strictEqual(file._writeStream, null); + + (function testSetProperties() { + var file2 = new File({foo: 'bar'}); + assert.equal(file2.foo, 'bar'); + })(); +}); + +test(function open() { + var WRITE_STREAM; + file.path = '/foo'; + + gently.expect(WriteStreamStub, 'new', function (path) { + WRITE_STREAM = this; + assert.strictEqual(path, file.path); + }); + + file.open(); + assert.strictEqual(file._writeStream, WRITE_STREAM); +}); + +test(function write() { + var BUFFER = {length: 10}, + CB_STUB, + CB = function() { + CB_STUB.apply(this, arguments); + }; + + file._writeStream = {}; + + gently.expect(file._writeStream, 'write', function (buffer, cb) { + assert.strictEqual(buffer, BUFFER); + + gently.expect(file, 'emit', function (event, bytesWritten) { + assert.ok(file.lastModifiedDate instanceof Date); + assert.equal(event, 'progress'); + assert.equal(bytesWritten, file.size); + }); + + CB_STUB = gently.expect(function writeCb() { + assert.equal(file.size, 10); + }); + + cb(); + + gently.expect(file, 'emit', function (event, bytesWritten) { + assert.equal(event, 'progress'); + assert.equal(bytesWritten, file.size); + }); + + CB_STUB = gently.expect(function writeCb() { + assert.equal(file.size, 20); + }); + + cb(); + }); + + file.write(BUFFER, CB); +}); + +test(function end() { + var CB_STUB, + CB = function() { + CB_STUB.apply(this, arguments); + }; + + file._writeStream = {}; + + gently.expect(file._writeStream, 'end', function (cb) { + gently.expect(file, 'emit', function (event) { + assert.equal(event, 'end'); + }); + + CB_STUB = gently.expect(function endCb() { + }); + + cb(); + }); + + file.end(CB); +}); diff --git a/node_modules/express/node_modules/connect/node_modules/formidable/test/legacy/simple/test-incoming-form.js b/node_modules/express/node_modules/connect/node_modules/formidable/test/legacy/simple/test-incoming-form.js new file mode 100644 index 0000000..de2bd0c --- /dev/null +++ b/node_modules/express/node_modules/connect/node_modules/formidable/test/legacy/simple/test-incoming-form.js @@ -0,0 +1,715 @@ +var common = require('../common'); +var MultipartParserStub = GENTLY.stub('./multipart_parser', 'MultipartParser'), + QuerystringParserStub = GENTLY.stub('./querystring_parser', 'QuerystringParser'), + EventEmitterStub = GENTLY.stub('events', 'EventEmitter'), + FileStub = GENTLY.stub('./file'); + +var formidable = require(common.lib + '/index'), + IncomingForm = formidable.IncomingForm, + events = require('events'), + fs = require('fs'), + path = require('path'), + Buffer = require('buffer').Buffer, + fixtures = require(TEST_FIXTURES + '/multipart'), + form, + gently; + +function test(test) { + gently = new Gently(); + gently.expect(EventEmitterStub, 'call'); + form = new IncomingForm(); + test(); + gently.verify(test.name); +} + +test(function constructor() { + assert.strictEqual(form.error, null); + assert.strictEqual(form.ended, false); + assert.strictEqual(form.type, null); + assert.strictEqual(form.headers, null); + assert.strictEqual(form.keepExtensions, false); + assert.strictEqual(form.uploadDir, '/tmp'); + assert.strictEqual(form.encoding, 'utf-8'); + assert.strictEqual(form.bytesReceived, null); + assert.strictEqual(form.bytesExpected, null); + assert.strictEqual(form.maxFieldsSize, 2 * 1024 * 1024); + assert.strictEqual(form._parser, null); + assert.strictEqual(form._flushing, 0); + assert.strictEqual(form._fieldsSize, 0); + assert.ok(form instanceof EventEmitterStub); + assert.equal(form.constructor.name, 'IncomingForm'); + + (function testSimpleConstructor() { + gently.expect(EventEmitterStub, 'call'); + var form = IncomingForm(); + assert.ok(form instanceof IncomingForm); + })(); + + (function testSimpleConstructorShortcut() { + gently.expect(EventEmitterStub, 'call'); + var form = formidable(); + assert.ok(form instanceof IncomingForm); + })(); +}); + +test(function parse() { + var REQ = {headers: {}} + , emit = {}; + + gently.expect(form, 'writeHeaders', function(headers) { + assert.strictEqual(headers, REQ.headers); + }); + + var events = ['error', 'aborted', 'data', 'end']; + gently.expect(REQ, 'on', events.length, function(event, fn) { + assert.equal(event, events.shift()); + emit[event] = fn; + return this; + }); + + form.parse(REQ); + + (function testPause() { + gently.expect(REQ, 'pause'); + assert.strictEqual(form.pause(), true); + })(); + + (function testPauseCriticalException() { + form.ended = false; + + var ERR = new Error('dasdsa'); + gently.expect(REQ, 'pause', function() { + throw ERR; + }); + + gently.expect(form, '_error', function(err) { + assert.strictEqual(err, ERR); + }); + + assert.strictEqual(form.pause(), false); + })(); + + (function testPauseHarmlessException() { + form.ended = true; + + var ERR = new Error('dasdsa'); + gently.expect(REQ, 'pause', function() { + throw ERR; + }); + + assert.strictEqual(form.pause(), false); + })(); + + (function testResume() { + gently.expect(REQ, 'resume'); + assert.strictEqual(form.resume(), true); + })(); + + (function testResumeCriticalException() { + form.ended = false; + + var ERR = new Error('dasdsa'); + gently.expect(REQ, 'resume', function() { + throw ERR; + }); + + gently.expect(form, '_error', function(err) { + assert.strictEqual(err, ERR); + }); + + assert.strictEqual(form.resume(), false); + })(); + + (function testResumeHarmlessException() { + form.ended = true; + + var ERR = new Error('dasdsa'); + gently.expect(REQ, 'resume', function() { + throw ERR; + }); + + assert.strictEqual(form.resume(), false); + })(); + + (function testEmitError() { + var ERR = new Error('something bad happened'); + gently.expect(form, '_error',function(err) { + assert.strictEqual(err, ERR); + }); + emit.error(ERR); + })(); + + (function testEmitAborted() { + gently.expect(form, 'emit',function(event) { + assert.equal(event, 'aborted'); + }); + + emit.aborted(); + })(); + + + (function testEmitData() { + var BUFFER = [1, 2, 3]; + gently.expect(form, 'write', function(buffer) { + assert.strictEqual(buffer, BUFFER); + }); + emit.data(BUFFER); + })(); + + (function testEmitEnd() { + form._parser = {}; + + (function testWithError() { + var ERR = new Error('haha'); + gently.expect(form._parser, 'end', function() { + return ERR; + }); + + gently.expect(form, '_error', function(err) { + assert.strictEqual(err, ERR); + }); + + emit.end(); + })(); + + (function testWithoutError() { + gently.expect(form._parser, 'end'); + emit.end(); + })(); + + (function testAfterError() { + form.error = true; + emit.end(); + })(); + })(); + + (function testWithCallback() { + gently.expect(EventEmitterStub, 'call'); + var form = new IncomingForm(), + REQ = {headers: {}}, + parseCalled = 0; + + gently.expect(form, 'writeHeaders'); + gently.expect(REQ, 'on', 4, function() { + return this; + }); + + gently.expect(form, 'on', 4, function(event, fn) { + if (event == 'field') { + fn('field1', 'foo'); + fn('field1', 'bar'); + fn('field2', 'nice'); + } + + if (event == 'file') { + fn('file1', '1'); + fn('file1', '2'); + fn('file2', '3'); + } + + if (event == 'end') { + fn(); + } + return this; + }); + + form.parse(REQ, gently.expect(function parseCbOk(err, fields, files) { + assert.deepEqual(fields, {field1: 'bar', field2: 'nice'}); + assert.deepEqual(files, {file1: '2', file2: '3'}); + })); + + gently.expect(form, 'writeHeaders'); + gently.expect(REQ, 'on', 4, function() { + return this; + }); + + var ERR = new Error('test'); + gently.expect(form, 'on', 3, function(event, fn) { + if (event == 'field') { + fn('foo', 'bar'); + } + + if (event == 'error') { + fn(ERR); + gently.expect(form, 'on'); + } + return this; + }); + + form.parse(REQ, gently.expect(function parseCbErr(err, fields, files) { + assert.strictEqual(err, ERR); + assert.deepEqual(fields, {foo: 'bar'}); + })); + })(); +}); + +test(function pause() { + assert.strictEqual(form.pause(), false); +}); + +test(function resume() { + assert.strictEqual(form.resume(), false); +}); + + +test(function writeHeaders() { + var HEADERS = {}; + gently.expect(form, '_parseContentLength'); + gently.expect(form, '_parseContentType'); + + form.writeHeaders(HEADERS); + assert.strictEqual(form.headers, HEADERS); +}); + +test(function write() { + var parser = {}, + BUFFER = [1, 2, 3]; + + form._parser = parser; + form.bytesExpected = 523423; + + (function testBasic() { + gently.expect(form, 'emit', function(event, bytesReceived, bytesExpected) { + assert.equal(event, 'progress'); + assert.equal(bytesReceived, BUFFER.length); + assert.equal(bytesExpected, form.bytesExpected); + }); + + gently.expect(parser, 'write', function(buffer) { + assert.strictEqual(buffer, BUFFER); + return buffer.length; + }); + + assert.equal(form.write(BUFFER), BUFFER.length); + assert.equal(form.bytesReceived, BUFFER.length); + })(); + + (function testParserError() { + gently.expect(form, 'emit'); + + gently.expect(parser, 'write', function(buffer) { + assert.strictEqual(buffer, BUFFER); + return buffer.length - 1; + }); + + gently.expect(form, '_error', function(err) { + assert.ok(err.message.match(/parser error/i)); + }); + + assert.equal(form.write(BUFFER), BUFFER.length - 1); + assert.equal(form.bytesReceived, BUFFER.length + BUFFER.length); + })(); + + (function testUninitialized() { + delete form._parser; + + gently.expect(form, '_error', function(err) { + assert.ok(err.message.match(/unintialized parser/i)); + }); + form.write(BUFFER); + })(); +}); + +test(function parseContentType() { + var HEADERS = {}; + + form.headers = {'content-type': 'application/x-www-form-urlencoded'}; + gently.expect(form, '_initUrlencoded'); + form._parseContentType(); + + // accept anything that has 'urlencoded' in it + form.headers = {'content-type': 'broken-client/urlencoded-stupid'}; + gently.expect(form, '_initUrlencoded'); + form._parseContentType(); + + var BOUNDARY = '---------------------------57814261102167618332366269'; + form.headers = {'content-type': 'multipart/form-data; boundary='+BOUNDARY}; + + gently.expect(form, '_initMultipart', function(boundary) { + assert.equal(boundary, BOUNDARY); + }); + form._parseContentType(); + + (function testQuotedBoundary() { + form.headers = {'content-type': 'multipart/form-data; boundary="' + BOUNDARY + '"'}; + + gently.expect(form, '_initMultipart', function(boundary) { + assert.equal(boundary, BOUNDARY); + }); + form._parseContentType(); + })(); + + (function testNoBoundary() { + form.headers = {'content-type': 'multipart/form-data'}; + + gently.expect(form, '_error', function(err) { + assert.ok(err.message.match(/no multipart boundary/i)); + }); + form._parseContentType(); + })(); + + (function testNoContentType() { + form.headers = {}; + + gently.expect(form, '_error', function(err) { + assert.ok(err.message.match(/no content-type/i)); + }); + form._parseContentType(); + })(); + + (function testUnknownContentType() { + form.headers = {'content-type': 'invalid'}; + + gently.expect(form, '_error', function(err) { + assert.ok(err.message.match(/unknown content-type/i)); + }); + form._parseContentType(); + })(); +}); + +test(function parseContentLength() { + var HEADERS = {}; + + form.headers = {}; + form._parseContentLength(); + assert.strictEqual(form.bytesExpected, null); + + form.headers['content-length'] = '8'; + form._parseContentLength(); + assert.strictEqual(form.bytesReceived, 0); + assert.strictEqual(form.bytesExpected, 8); + + // JS can be evil, lets make sure we are not + form.headers['content-length'] = '08'; + form._parseContentLength(); + assert.strictEqual(form.bytesExpected, 8); +}); + +test(function _initMultipart() { + var BOUNDARY = '123', + PARSER; + + gently.expect(MultipartParserStub, 'new', function() { + PARSER = this; + }); + + gently.expect(MultipartParserStub.prototype, 'initWithBoundary', function(boundary) { + assert.equal(boundary, BOUNDARY); + }); + + form._initMultipart(BOUNDARY); + assert.equal(form.type, 'multipart'); + assert.strictEqual(form._parser, PARSER); + + (function testRegularField() { + var PART; + gently.expect(EventEmitterStub, 'new', function() { + PART = this; + }); + + gently.expect(form, 'onPart', function(part) { + assert.strictEqual(part, PART); + assert.deepEqual + ( part.headers + , { 'content-disposition': 'form-data; name="field1"' + , 'foo': 'bar' + } + ); + assert.equal(part.name, 'field1'); + + var strings = ['hello', ' world']; + gently.expect(part, 'emit', 2, function(event, b) { + assert.equal(event, 'data'); + assert.equal(b.toString(), strings.shift()); + }); + + gently.expect(part, 'emit', function(event, b) { + assert.equal(event, 'end'); + }); + }); + + PARSER.onPartBegin(); + PARSER.onHeaderField(new Buffer('content-disposition'), 0, 10); + PARSER.onHeaderField(new Buffer('content-disposition'), 10, 19); + PARSER.onHeaderValue(new Buffer('form-data; name="field1"'), 0, 14); + PARSER.onHeaderValue(new Buffer('form-data; name="field1"'), 14, 24); + PARSER.onHeaderEnd(); + PARSER.onHeaderField(new Buffer('foo'), 0, 3); + PARSER.onHeaderValue(new Buffer('bar'), 0, 3); + PARSER.onHeaderEnd(); + PARSER.onHeadersEnd(); + PARSER.onPartData(new Buffer('hello world'), 0, 5); + PARSER.onPartData(new Buffer('hello world'), 5, 11); + PARSER.onPartEnd(); + })(); + + (function testFileField() { + var PART; + gently.expect(EventEmitterStub, 'new', function() { + PART = this; + }); + + gently.expect(form, 'onPart', function(part) { + assert.deepEqual + ( part.headers + , { 'content-disposition': 'form-data; name="field2"; filename="C:\\Documents and Settings\\IE\\Must\\Die\\Sun"et.jpg"' + , 'content-type': 'text/plain' + } + ); + assert.equal(part.name, 'field2'); + assert.equal(part.filename, 'Sun"et.jpg'); + assert.equal(part.mime, 'text/plain'); + + gently.expect(part, 'emit', function(event, b) { + assert.equal(event, 'data'); + assert.equal(b.toString(), '... contents of file1.txt ...'); + }); + + gently.expect(part, 'emit', function(event, b) { + assert.equal(event, 'end'); + }); + }); + + PARSER.onPartBegin(); + PARSER.onHeaderField(new Buffer('content-disposition'), 0, 19); + PARSER.onHeaderValue(new Buffer('form-data; name="field2"; filename="C:\\Documents and Settings\\IE\\Must\\Die\\Sun"et.jpg"'), 0, 85); + PARSER.onHeaderEnd(); + PARSER.onHeaderField(new Buffer('Content-Type'), 0, 12); + PARSER.onHeaderValue(new Buffer('text/plain'), 0, 10); + PARSER.onHeaderEnd(); + PARSER.onHeadersEnd(); + PARSER.onPartData(new Buffer('... contents of file1.txt ...'), 0, 29); + PARSER.onPartEnd(); + })(); + + (function testEnd() { + gently.expect(form, '_maybeEnd'); + PARSER.onEnd(); + assert.ok(form.ended); + })(); +}); + +test(function _fileName() { + // TODO + return; +}); + +test(function _initUrlencoded() { + var PARSER; + + gently.expect(QuerystringParserStub, 'new', function() { + PARSER = this; + }); + + form._initUrlencoded(); + assert.equal(form.type, 'urlencoded'); + assert.strictEqual(form._parser, PARSER); + + (function testOnField() { + var KEY = 'KEY', VAL = 'VAL'; + gently.expect(form, 'emit', function(field, key, val) { + assert.equal(field, 'field'); + assert.equal(key, KEY); + assert.equal(val, VAL); + }); + + PARSER.onField(KEY, VAL); + })(); + + (function testOnEnd() { + gently.expect(form, '_maybeEnd'); + + PARSER.onEnd(); + assert.equal(form.ended, true); + })(); +}); + +test(function _error() { + var ERR = new Error('bla'); + + gently.expect(form, 'pause'); + gently.expect(form, 'emit', function(event, err) { + assert.equal(event, 'error'); + assert.strictEqual(err, ERR); + }); + + form._error(ERR); + assert.strictEqual(form.error, ERR); + + // make sure _error only does its thing once + form._error(ERR); +}); + +test(function onPart() { + var PART = {}; + gently.expect(form, 'handlePart', function(part) { + assert.strictEqual(part, PART); + }); + + form.onPart(PART); +}); + +test(function handlePart() { + (function testUtf8Field() { + var PART = new events.EventEmitter(); + PART.name = 'my_field'; + + gently.expect(form, 'emit', function(event, field, value) { + assert.equal(event, 'field'); + assert.equal(field, 'my_field'); + assert.equal(value, 'hello world: €'); + }); + + form.handlePart(PART); + PART.emit('data', new Buffer('hello')); + PART.emit('data', new Buffer(' world: ')); + PART.emit('data', new Buffer([0xE2])); + PART.emit('data', new Buffer([0x82, 0xAC])); + PART.emit('end'); + })(); + + (function testBinaryField() { + var PART = new events.EventEmitter(); + PART.name = 'my_field2'; + + gently.expect(form, 'emit', function(event, field, value) { + assert.equal(event, 'field'); + assert.equal(field, 'my_field2'); + assert.equal(value, 'hello world: '+new Buffer([0xE2, 0x82, 0xAC]).toString('binary')); + }); + + form.encoding = 'binary'; + form.handlePart(PART); + PART.emit('data', new Buffer('hello')); + PART.emit('data', new Buffer(' world: ')); + PART.emit('data', new Buffer([0xE2])); + PART.emit('data', new Buffer([0x82, 0xAC])); + PART.emit('end'); + })(); + + (function testFieldSize() { + form.maxFieldsSize = 8; + var PART = new events.EventEmitter(); + PART.name = 'my_field'; + + gently.expect(form, '_error', function(err) { + assert.equal(err.message, 'maxFieldsSize exceeded, received 9 bytes of field data'); + }); + + form.handlePart(PART); + form._fieldsSize = 1; + PART.emit('data', new Buffer(7)); + PART.emit('data', new Buffer(1)); + })(); + + (function testFilePart() { + var PART = new events.EventEmitter(), + FILE = new events.EventEmitter(), + PATH = '/foo/bar'; + + PART.name = 'my_file'; + PART.filename = 'sweet.txt'; + PART.mime = 'sweet.txt'; + + gently.expect(form, '_uploadPath', function(filename) { + assert.equal(filename, PART.filename); + return PATH; + }); + + gently.expect(FileStub, 'new', function(properties) { + assert.equal(properties.path, PATH); + assert.equal(properties.name, PART.filename); + assert.equal(properties.type, PART.mime); + FILE = this; + + gently.expect(form, 'emit', function (event, field, file) { + assert.equal(event, 'fileBegin'); + assert.strictEqual(field, PART.name); + assert.strictEqual(file, FILE); + }); + + gently.expect(FILE, 'open'); + }); + + form.handlePart(PART); + assert.equal(form._flushing, 1); + + var BUFFER; + gently.expect(form, 'pause'); + gently.expect(FILE, 'write', function(buffer, cb) { + assert.strictEqual(buffer, BUFFER); + gently.expect(form, 'resume'); + // @todo handle cb(new Err) + cb(); + }); + + PART.emit('data', BUFFER = new Buffer('test')); + + gently.expect(FILE, 'end', function(cb) { + gently.expect(form, 'emit', function(event, field, file) { + assert.equal(event, 'file'); + assert.strictEqual(file, FILE); + }); + + gently.expect(form, '_maybeEnd'); + + cb(); + assert.equal(form._flushing, 0); + }); + + PART.emit('end'); + })(); +}); + +test(function _uploadPath() { + (function testUniqueId() { + var UUID_A, UUID_B; + gently.expect(GENTLY.hijacked.path, 'join', function(uploadDir, uuid) { + assert.equal(uploadDir, form.uploadDir); + UUID_A = uuid; + }); + form._uploadPath(); + + gently.expect(GENTLY.hijacked.path, 'join', function(uploadDir, uuid) { + UUID_B = uuid; + }); + form._uploadPath(); + + assert.notEqual(UUID_A, UUID_B); + })(); + + (function testFileExtension() { + form.keepExtensions = true; + var FILENAME = 'foo.jpg', + EXT = '.bar'; + + gently.expect(GENTLY.hijacked.path, 'extname', function(filename) { + assert.equal(filename, FILENAME); + gently.restore(path, 'extname'); + + return EXT; + }); + + gently.expect(GENTLY.hijacked.path, 'join', function(uploadDir, name) { + assert.equal(path.extname(name), EXT); + }); + form._uploadPath(FILENAME); + })(); +}); + +test(function _maybeEnd() { + gently.expect(form, 'emit', 0); + form._maybeEnd(); + + form.ended = true; + form._flushing = 1; + form._maybeEnd(); + + gently.expect(form, 'emit', function(event) { + assert.equal(event, 'end'); + }); + + form.ended = true; + form._flushing = 0; + form._maybeEnd(); +}); diff --git a/node_modules/express/node_modules/connect/node_modules/formidable/test/legacy/simple/test-multipart-parser.js b/node_modules/express/node_modules/connect/node_modules/formidable/test/legacy/simple/test-multipart-parser.js new file mode 100644 index 0000000..d8dc968 --- /dev/null +++ b/node_modules/express/node_modules/connect/node_modules/formidable/test/legacy/simple/test-multipart-parser.js @@ -0,0 +1,50 @@ +var common = require('../common'); +var multipartParser = require(common.lib + '/multipart_parser'), + MultipartParser = multipartParser.MultipartParser, + events = require('events'), + Buffer = require('buffer').Buffer, + parser; + +function test(test) { + parser = new MultipartParser(); + test(); +} + +test(function constructor() { + assert.equal(parser.boundary, null); + assert.equal(parser.state, 0); + assert.equal(parser.flags, 0); + assert.equal(parser.boundaryChars, null); + assert.equal(parser.index, null); + assert.equal(parser.lookbehind, null); + assert.equal(parser.constructor.name, 'MultipartParser'); +}); + +test(function initWithBoundary() { + var boundary = 'abc'; + parser.initWithBoundary(boundary); + assert.deepEqual(Array.prototype.slice.call(parser.boundary), [13, 10, 45, 45, 97, 98, 99]); + assert.equal(parser.state, multipartParser.START); + + assert.deepEqual(parser.boundaryChars, {10: true, 13: true, 45: true, 97: true, 98: true, 99: true}); +}); + +test(function parserError() { + var boundary = 'abc', + buffer = new Buffer(5); + + parser.initWithBoundary(boundary); + buffer.write('--ad', 'ascii', 0); + assert.equal(parser.write(buffer), 3); +}); + +test(function end() { + (function testError() { + assert.equal(parser.end().message, 'MultipartParser.end(): stream ended unexpectedly: ' + parser.explain()); + })(); + + (function testRegular() { + parser.state = multipartParser.END; + assert.strictEqual(parser.end(), undefined); + })(); +}); diff --git a/node_modules/express/node_modules/connect/node_modules/formidable/test/legacy/simple/test-querystring-parser.js b/node_modules/express/node_modules/connect/node_modules/formidable/test/legacy/simple/test-querystring-parser.js new file mode 100644 index 0000000..54d3e2d --- /dev/null +++ b/node_modules/express/node_modules/connect/node_modules/formidable/test/legacy/simple/test-querystring-parser.js @@ -0,0 +1,45 @@ +var common = require('../common'); +var QuerystringParser = require(common.lib + '/querystring_parser').QuerystringParser, + Buffer = require('buffer').Buffer, + gently, + parser; + +function test(test) { + gently = new Gently(); + parser = new QuerystringParser(); + test(); + gently.verify(test.name); +} + +test(function constructor() { + assert.equal(parser.buffer, ''); + assert.equal(parser.constructor.name, 'QuerystringParser'); +}); + +test(function write() { + var a = new Buffer('a=1'); + assert.equal(parser.write(a), a.length); + + var b = new Buffer('&b=2'); + parser.write(b); + assert.equal(parser.buffer, a + b); +}); + +test(function end() { + var FIELDS = {a: ['b', {c: 'd'}], e: 'f'}; + + gently.expect(GENTLY.hijacked.querystring, 'parse', function(str) { + assert.equal(str, parser.buffer); + return FIELDS; + }); + + gently.expect(parser, 'onField', Object.keys(FIELDS).length, function(key, val) { + assert.deepEqual(FIELDS[key], val); + }); + + gently.expect(parser, 'onEnd'); + + parser.buffer = 'my buffer'; + parser.end(); + assert.equal(parser.buffer, ''); +}); diff --git a/node_modules/express/node_modules/connect/node_modules/formidable/test/legacy/system/test-multi-video-upload.js b/node_modules/express/node_modules/connect/node_modules/formidable/test/legacy/system/test-multi-video-upload.js new file mode 100644 index 0000000..fcfdb94 --- /dev/null +++ b/node_modules/express/node_modules/connect/node_modules/formidable/test/legacy/system/test-multi-video-upload.js @@ -0,0 +1,72 @@ +var common = require('../common'); +var BOUNDARY = '---------------------------10102754414578508781458777923', + FIXTURE = TEST_FIXTURES+'/multi_video.upload', + fs = require('fs'), + util = require(common.lib + '/util'), + http = require('http'), + formidable = require(common.lib + '/index'), + server = http.createServer(); + +server.on('request', function(req, res) { + var form = new formidable.IncomingForm(), + uploads = {}; + + form.uploadDir = TEST_TMP; + form.parse(req); + + form + .on('fileBegin', function(field, file) { + assert.equal(field, 'upload'); + + var tracker = {file: file, progress: [], ended: false}; + uploads[file.filename] = tracker; + file + .on('progress', function(bytesReceived) { + tracker.progress.push(bytesReceived); + assert.equal(bytesReceived, file.length); + }) + .on('end', function() { + tracker.ended = true; + }); + }) + .on('field', function(field, value) { + assert.equal(field, 'title'); + assert.equal(value, ''); + }) + .on('file', function(field, file) { + assert.equal(field, 'upload'); + assert.strictEqual(uploads[file.filename].file, file); + }) + .on('end', function() { + assert.ok(uploads['shortest_video.flv']); + assert.ok(uploads['shortest_video.flv'].ended); + assert.ok(uploads['shortest_video.flv'].progress.length > 3); + assert.equal(uploads['shortest_video.flv'].progress.slice(-1), uploads['shortest_video.flv'].file.length); + assert.ok(uploads['shortest_video.mp4']); + assert.ok(uploads['shortest_video.mp4'].ended); + assert.ok(uploads['shortest_video.mp4'].progress.length > 3); + + server.close(); + res.writeHead(200); + res.end('good'); + }); +}); + +server.listen(TEST_PORT, function() { + var client = http.createClient(TEST_PORT), + stat = fs.statSync(FIXTURE), + headers = { + 'content-type': 'multipart/form-data; boundary='+BOUNDARY, + 'content-length': stat.size, + } + request = client.request('POST', '/', headers), + fixture = new fs.ReadStream(FIXTURE); + + fixture + .on('data', function(b) { + request.write(b); + }) + .on('end', function() { + request.end(); + }); +}); diff --git a/node_modules/express/node_modules/connect/node_modules/formidable/test/run.js b/node_modules/express/node_modules/connect/node_modules/formidable/test/run.js new file mode 100755 index 0000000..0bb8e82 --- /dev/null +++ b/node_modules/express/node_modules/connect/node_modules/formidable/test/run.js @@ -0,0 +1,7 @@ +#!/usr/bin/env node +var far = require('far').create(); + +far.add(__dirname); +far.include(/test-.*\.js$/); + +far.execute(); diff --git a/node_modules/express/node_modules/connect/node_modules/formidable/test/slow/test-fixtures.js b/node_modules/express/node_modules/connect/node_modules/formidable/test/slow/test-fixtures.js new file mode 100644 index 0000000..e54210f --- /dev/null +++ b/node_modules/express/node_modules/connect/node_modules/formidable/test/slow/test-fixtures.js @@ -0,0 +1,84 @@ +var hashish = require('hashish'); +var fs = require('fs'); +var findit = require('findit'); +var path = require('path'); +var http = require('http'); +var net = require('net'); +var assert = require('assert'); + +var common = require('../common'); +var test = common.fastOrSlow.slow(); +var formidable = common.formidable; + +var server; +test.before(function(done) { + if (server) return done(); + + server = http.createServer(); + server.listen(common.port, done); +}); + +findit + .sync(common.dir.fixture + '/js') + .forEach(function(jsPath) { + if (!/\.js$/.test(jsPath)) return; + + var group = path.basename(jsPath, '.js'); + hashish.forEach(require(jsPath), function(fixture, name) { + addTest(group + '/' + name, fixture); + }); + }); + +function addTest(name, fixture) { + test('fixture: ' + name, function(done) { + console.error(this.name); + uploadFixture(name, function(err, parts) { + if (err) return done(err); + + fixture.forEach(function(expectedPart, i) { + var parsedPart = parts[i]; + assert.equal(parsedPart.type, expectedPart.type); + assert.equal(parsedPart.name, expectedPart.name); + + if (parsedPart.type === 'file') { + var filename = parsedPart.value.name; + assert.equal(filename, expectedPart.filename); + } + }); + + done(); + }); + }); +}; + +function uploadFixture(name, cb) { + server.once('request', function(req, res) { + var form = new formidable.IncomingForm(); + form.uploadDir = common.dir.tmp; + form.parse(req); + + function callback() { + var realCallback = cb; + cb = function() {}; + realCallback.apply(null, arguments); + } + + var parts = []; + form + .on('error', callback) + .on('fileBegin', function(name, value) { + parts.push({type: 'file', name: name, value: value}); + }) + .on('field', function(name, value) { + parts.push({type: 'field', name: name, value: value}); + }) + .on('end', function() { + callback(null, parts); + }); + }); + + var socket = net.createConnection(common.port); + var file = fs.createReadStream(common.dir.fixture + '/http/' + name); + + file.pipe(socket); +} diff --git a/node_modules/express/node_modules/connect/node_modules/formidable/tool/record.js b/node_modules/express/node_modules/connect/node_modules/formidable/tool/record.js new file mode 100644 index 0000000..9f1cef8 --- /dev/null +++ b/node_modules/express/node_modules/connect/node_modules/formidable/tool/record.js @@ -0,0 +1,47 @@ +var http = require('http'); +var fs = require('fs'); +var connections = 0; + +var server = http.createServer(function(req, res) { + var socket = req.socket; + console.log('Request: %s %s -> %s', req.method, req.url, socket.filename); + + req.on('end', function() { + if (req.url !== '/') { + res.end(JSON.stringify({ + method: req.method, + url: req.url, + filename: socket.filename, + })); + return; + } + + res.writeHead(200, {'content-type': 'text/html'}); + res.end( + '
    '+ + '
    '+ + '
    '+ + ''+ + '
    ' + ); + }); +}); + +server.on('connection', function(socket) { + connections++; + + socket.id = connections; + socket.filename = 'connection-' + socket.id + '.http'; + socket.file = fs.createWriteStream(socket.filename); + socket.pipe(socket.file); + + console.log('--> %s', socket.filename); + socket.on('close', function() { + console.log('<-- %s', socket.filename); + }); +}); + +var port = process.env.PORT || 8080; +server.listen(port, function() { + console.log('Recording connections on port %s', port); +}); diff --git a/node_modules/express/node_modules/connect/node_modules/mime/LICENSE b/node_modules/express/node_modules/connect/node_modules/mime/LICENSE new file mode 100644 index 0000000..451fc45 --- /dev/null +++ b/node_modules/express/node_modules/connect/node_modules/mime/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2010 Benjamin Thomas, Robert Kieffer + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/node_modules/express/node_modules/connect/node_modules/mime/README.md b/node_modules/express/node_modules/connect/node_modules/mime/README.md new file mode 100644 index 0000000..a157de1 --- /dev/null +++ b/node_modules/express/node_modules/connect/node_modules/mime/README.md @@ -0,0 +1,50 @@ +# mime + +Support for mapping between file extensions and MIME types. This module uses the latest version of the Apache "mime.types" file (maps over 620 types to 800+ extensions). It is also trivially easy to add your own types and extensions, should you need to do that. + +## Install + +Install with [npm](http://github.com/isaacs/npm): + + npm install mime + +## API - Queries + +### mime.lookup(path) +Get the mime type associated with a file. This is method is case-insensitive. Everything in path up to and including the last '/' or '.' is ignored, so you can pass it paths, filenames, or extensions, like so: + + var mime = require('mime'); + + mime.lookup('/path/to/file.txt'); // => 'text/plain' + mime.lookup('file.txt'); // => 'text/plain' + mime.lookup('.txt'); // => 'text/plain' + mime.lookup('htm'); // => 'text/html' + +### mime.extension(type) - lookup the default extension for type + + mime.extension('text/html'); // => 'html' + mime.extension('application/octet-stream'); // => 'bin' + +### mime.charsets.lookup() - map mime-type to charset + + mime.charsets.lookup('text/plain'); // => 'UTF-8' + +(The logic for charset lookups is pretty rudimentary. Feel free to suggest improvements.) + +## API - Customizing + +The following APIs allow you to add your own type mappings within your project. If you feel a type should be included as part of node-mime, see [requesting new types](https://github.com/bentomas/node-mime/wiki/Requesting-New-Types). +### mime.define() - Add custom mime/extension mappings + + mime.define({ + 'text/x-some-format': ['x-sf', 'x-sft', 'x-sfml'], + 'application/x-my-type': ['x-mt', 'x-mtt'], + // etc ... + }); + + mime.lookup('x-sft'); // => 'text/x-some-format' + mime.extension('text/x-some-format'); // => 'x-sf' + +### mime.load(filepath) - Load mappings from an Apache ".types" format file + + mime.load('./my_project.types'); diff --git a/node_modules/express/node_modules/connect/node_modules/mime/mime.js b/node_modules/express/node_modules/connect/node_modules/mime/mime.js new file mode 100644 index 0000000..5fac753 --- /dev/null +++ b/node_modules/express/node_modules/connect/node_modules/mime/mime.js @@ -0,0 +1,92 @@ +var path = require('path'), + fs = require('fs'); + +var mime = module.exports = { + /** Map of extension to mime type */ + types: {}, + + /** Map of mime type to extension */ + extensions :{}, + + /** + * Define mimetype -> extension mappings. Each key is a mime-type that maps + * to an array of extensions associated with the type. The first extension is + * used as the default extension for the type. + * + * e.g. mime.define({'audio/ogg', ['oga', 'ogg', 'spx']}); + * + * @param map (Object) type definitions + */ + define: function(map) { + for (var type in map) { + var exts = map[type]; + + for (var i = 0; i < exts.length; i++) { + mime.types[exts[i]] = type; + } + + // Default extension is the first one we encounter + if (!mime.extensions[type]) { + mime.extensions[type] = exts[0]; + } + } + }, + + /** + * Load an Apache2-style ".types" file + * + * This may be called multiple times (it's expected). Where files declare + * overlapping types/extensions, the last file wins. + * + * @param file (String) path of file to load. + */ + load: function(file) { + // Read file and split into lines + var map = {}, + content = fs.readFileSync(file, 'ascii'), + lines = content.split(/[\r\n]+/); + + lines.forEach(function(line, lineno) { + // Clean up whitespace/comments, and split into fields + var fields = line.replace(/\s*#.*|^\s*|\s*$/g, '').split(/\s+/); + map[fields.shift()] = fields; + }); + + mime.define(map); + }, + + /** + * Lookup a mime type based on extension + */ + lookup: function(path, fallback) { + var ext = path.replace(/.*[\.\/]/, '').toLowerCase(); + return mime.types[ext] || fallback || mime.default_type; + }, + + /** + * Return file extension associated with a mime type + */ + extension: function(mimeType) { + return mime.extensions[mimeType]; + }, + + /** + * Lookup a charset based on mime type. + */ + charsets: { + lookup: function (mimeType, fallback) { + // Assume text types are utf8. Modify mime logic as needed. + return (/^text\//).test(mimeType) ? 'UTF-8' : fallback; + } + } +}; + +// Load our local copy of +// http://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types +mime.load(path.join(__dirname, 'types/mime.types')); + +// Overlay enhancements submitted by the node.js community +mime.load(path.join(__dirname, 'types/node.types')); + +// Set the default type +mime.default_type = mime.types.bin; diff --git a/node_modules/express/node_modules/connect/node_modules/mime/package.json b/node_modules/express/node_modules/connect/node_modules/mime/package.json new file mode 100644 index 0000000..85277b0 --- /dev/null +++ b/node_modules/express/node_modules/connect/node_modules/mime/package.json @@ -0,0 +1,22 @@ +{ + "author": { + "name": "Robert Kieffer", + "url": "http://github.com/broofa", + "email": "robert@broofa.com" + }, + "contributors": [ + { + "name": "Benjamin Thomas", + "url": "http://github.com/bentomas", + "email": "benjamin@benjaminthomas.org" + } + ], + "dependencies": {}, + "description": "A comprehensive library for mime-type mapping", + "devDependencies": {"async_testing": ""}, + "keywords": ["util", "mime"], + "main": "mime.js", + "name": "mime", + "repository": {"url": "http://github.com/bentomas/node-mime", "type": "git"}, + "version": "1.2.4" +} diff --git a/node_modules/express/node_modules/connect/node_modules/mime/test.js b/node_modules/express/node_modules/connect/node_modules/mime/test.js new file mode 100644 index 0000000..b904895 --- /dev/null +++ b/node_modules/express/node_modules/connect/node_modules/mime/test.js @@ -0,0 +1,79 @@ +/** + * Requires the async_testing module + * + * Usage: node test.js + */ +var mime = require('./mime'); +exports["test mime lookup"] = function(test) { + // easy + test.equal('text/plain', mime.lookup('text.txt')); + + // hidden file or multiple periods + test.equal('text/plain', mime.lookup('.text.txt')); + + // just an extension + test.equal('text/plain', mime.lookup('.txt')); + + // just an extension without a dot + test.equal('text/plain', mime.lookup('txt')); + + // default + test.equal('application/octet-stream', mime.lookup('text.nope')); + + // fallback + test.equal('fallback', mime.lookup('text.fallback', 'fallback')); + + test.finish(); +}; + +exports["test extension lookup"] = function(test) { + // easy + test.equal('txt', mime.extension(mime.types.text)); + test.equal('html', mime.extension(mime.types.htm)); + test.equal('bin', mime.extension('application/octet-stream')); + + test.finish(); +}; + +exports["test mime lookup uppercase"] = function(test) { + // easy + test.equal('text/plain', mime.lookup('TEXT.TXT')); + + // just an extension + test.equal('text/plain', mime.lookup('.TXT')); + + // just an extension without a dot + test.equal('text/plain', mime.lookup('TXT')); + + // default + test.equal('application/octet-stream', mime.lookup('TEXT.NOPE')); + + // fallback + test.equal('fallback', mime.lookup('TEXT.FALLBACK', 'fallback')); + + test.finish(); +}; + +exports["test custom types"] = function(test) { + test.equal('application/octet-stream', mime.lookup('file.buffer')); + test.equal('audio/mp4', mime.lookup('file.m4a')); + + test.finish(); +}; + +exports["test charset lookup"] = function(test) { + // easy + test.equal('UTF-8', mime.charsets.lookup('text/plain')); + + // none + test.ok(typeof mime.charsets.lookup(mime.types.js) == 'undefined'); + + // fallback + test.equal('fallback', mime.charsets.lookup('application/octet-stream', 'fallback')); + + test.finish(); +}; + +if (module == require.main) { + require('async_testing').run(__filename, process.ARGV); +} diff --git a/node_modules/express/node_modules/connect/node_modules/mime/types/mime.types b/node_modules/express/node_modules/connect/node_modules/mime/types/mime.types new file mode 100644 index 0000000..6a90929 --- /dev/null +++ b/node_modules/express/node_modules/connect/node_modules/mime/types/mime.types @@ -0,0 +1,1479 @@ +# This file maps Internet media types to unique file extension(s). +# Although created for httpd, this file is used by many software systems +# and has been placed in the public domain for unlimited redisribution. +# +# The table below contains both registered and (common) unregistered types. +# A type that has no unique extension can be ignored -- they are listed +# here to guide configurations toward known types and to make it easier to +# identify "new" types. File extensions are also commonly used to indicate +# content languages and encodings, so choose them carefully. +# +# Internet media types should be registered as described in RFC 4288. +# The registry is at . +# +# MIME type (lowercased) Extensions +# ============================================ ========== +# application/1d-interleaved-parityfec +# application/3gpp-ims+xml +# application/activemessage +application/andrew-inset ez +# application/applefile +application/applixware aw +application/atom+xml atom +application/atomcat+xml atomcat +# application/atomicmail +application/atomsvc+xml atomsvc +# application/auth-policy+xml +# application/batch-smtp +# application/beep+xml +# application/cals-1840 +application/ccxml+xml ccxml +application/cdmi-capability cdmia +application/cdmi-container cdmic +application/cdmi-domain cdmid +application/cdmi-object cdmio +application/cdmi-queue cdmiq +# application/cea-2018+xml +# application/cellml+xml +# application/cfw +# application/cnrp+xml +# application/commonground +# application/conference-info+xml +# application/cpl+xml +# application/csta+xml +# application/cstadata+xml +application/cu-seeme cu +# application/cybercash +application/davmount+xml davmount +# application/dca-rft +# application/dec-dx +# application/dialog-info+xml +# application/dicom +# application/dns +# application/dskpp+xml +application/dssc+der dssc +application/dssc+xml xdssc +# application/dvcs +application/ecmascript ecma +# application/edi-consent +# application/edi-x12 +# application/edifact +application/emma+xml emma +# application/epp+xml +application/epub+zip epub +# application/eshop +# application/example +application/exi exi +# application/fastinfoset +# application/fastsoap +# application/fits +application/font-tdpfr pfr +# application/framework-attributes+xml +# application/h224 +# application/held+xml +# application/http +application/hyperstudio stk +# application/ibe-key-request+xml +# application/ibe-pkg-reply+xml +# application/ibe-pp-data +# application/iges +# application/im-iscomposing+xml +# application/index +# application/index.cmd +# application/index.obj +# application/index.response +# application/index.vnd +# application/iotp +application/ipfix ipfix +# application/ipp +# application/isup +application/java-archive jar +application/java-serialized-object ser +application/java-vm class +application/javascript js +application/json json +# application/kpml-request+xml +# application/kpml-response+xml +application/lost+xml lostxml +application/mac-binhex40 hqx +application/mac-compactpro cpt +# application/macwriteii +application/mads+xml mads +application/marc mrc +application/marcxml+xml mrcx +application/mathematica ma nb mb +# application/mathml-content+xml +# application/mathml-presentation+xml +application/mathml+xml mathml +# application/mbms-associated-procedure-description+xml +# application/mbms-deregister+xml +# application/mbms-envelope+xml +# application/mbms-msk+xml +# application/mbms-msk-response+xml +# application/mbms-protection-description+xml +# application/mbms-reception-report+xml +# application/mbms-register+xml +# application/mbms-register-response+xml +# application/mbms-user-service-description+xml +application/mbox mbox +# application/media_control+xml +application/mediaservercontrol+xml mscml +application/metalink4+xml meta4 +application/mets+xml mets +# application/mikey +application/mods+xml mods +# application/moss-keys +# application/moss-signature +# application/mosskey-data +# application/mosskey-request +application/mp21 m21 mp21 +application/mp4 mp4s +# application/mpeg4-generic +# application/mpeg4-iod +# application/mpeg4-iod-xmt +# application/msc-ivr+xml +# application/msc-mixer+xml +application/msword doc dot +application/mxf mxf +# application/nasdata +# application/news-checkgroups +# application/news-groupinfo +# application/news-transmission +# application/nss +# application/ocsp-request +# application/ocsp-response +application/octet-stream bin dms lha lrf lzh so iso dmg dist distz pkg bpk dump elc deploy +application/oda oda +application/oebps-package+xml opf +application/ogg ogx +application/onenote onetoc onetoc2 onetmp onepkg +# application/parityfec +application/patch-ops-error+xml xer +application/pdf pdf +application/pgp-encrypted pgp +# application/pgp-keys +application/pgp-signature asc sig +application/pics-rules prf +# application/pidf+xml +# application/pidf-diff+xml +application/pkcs10 p10 +application/pkcs7-mime p7m p7c +application/pkcs7-signature p7s +application/pkcs8 p8 +application/pkix-attr-cert ac +application/pkix-cert cer +application/pkix-crl crl +application/pkix-pkipath pkipath +application/pkixcmp pki +application/pls+xml pls +# application/poc-settings+xml +application/postscript ai eps ps +# application/prs.alvestrand.titrax-sheet +application/prs.cww cww +# application/prs.nprend +# application/prs.plucker +# application/prs.rdf-xml-crypt +# application/prs.xsf+xml +application/pskc+xml pskcxml +# application/qsig +application/rdf+xml rdf +application/reginfo+xml rif +application/relax-ng-compact-syntax rnc +# application/remote-printing +application/resource-lists+xml rl +application/resource-lists-diff+xml rld +# application/riscos +# application/rlmi+xml +application/rls-services+xml rs +application/rsd+xml rsd +application/rss+xml rss +application/rtf rtf +# application/rtx +# application/samlassertion+xml +# application/samlmetadata+xml +application/sbml+xml sbml +application/scvp-cv-request scq +application/scvp-cv-response scs +application/scvp-vp-request spq +application/scvp-vp-response spp +application/sdp sdp +# application/set-payment +application/set-payment-initiation setpay +# application/set-registration +application/set-registration-initiation setreg +# application/sgml +# application/sgml-open-catalog +application/shf+xml shf +# application/sieve +# application/simple-filter+xml +# application/simple-message-summary +# application/simplesymbolcontainer +# application/slate +# application/smil +application/smil+xml smi smil +# application/soap+fastinfoset +# application/soap+xml +application/sparql-query rq +application/sparql-results+xml srx +# application/spirits-event+xml +application/srgs gram +application/srgs+xml grxml +application/sru+xml sru +application/ssml+xml ssml +# application/tamp-apex-update +# application/tamp-apex-update-confirm +# application/tamp-community-update +# application/tamp-community-update-confirm +# application/tamp-error +# application/tamp-sequence-adjust +# application/tamp-sequence-adjust-confirm +# application/tamp-status-query +# application/tamp-status-response +# application/tamp-update +# application/tamp-update-confirm +application/tei+xml tei teicorpus +application/thraud+xml tfi +# application/timestamp-query +# application/timestamp-reply +application/timestamped-data tsd +# application/tve-trigger +# application/ulpfec +# application/vemmi +# application/vividence.scriptfile +# application/vnd.3gpp.bsf+xml +application/vnd.3gpp.pic-bw-large plb +application/vnd.3gpp.pic-bw-small psb +application/vnd.3gpp.pic-bw-var pvb +# application/vnd.3gpp.sms +# application/vnd.3gpp2.bcmcsinfo+xml +# application/vnd.3gpp2.sms +application/vnd.3gpp2.tcap tcap +application/vnd.3m.post-it-notes pwn +application/vnd.accpac.simply.aso aso +application/vnd.accpac.simply.imp imp +application/vnd.acucobol acu +application/vnd.acucorp atc acutc +application/vnd.adobe.air-application-installer-package+zip air +application/vnd.adobe.fxp fxp fxpl +# application/vnd.adobe.partial-upload +application/vnd.adobe.xdp+xml xdp +application/vnd.adobe.xfdf xfdf +# application/vnd.aether.imp +# application/vnd.ah-barcode +application/vnd.ahead.space ahead +application/vnd.airzip.filesecure.azf azf +application/vnd.airzip.filesecure.azs azs +application/vnd.amazon.ebook azw +application/vnd.americandynamics.acc acc +application/vnd.amiga.ami ami +# application/vnd.amundsen.maze+xml +application/vnd.android.package-archive apk +application/vnd.anser-web-certificate-issue-initiation cii +application/vnd.anser-web-funds-transfer-initiation fti +application/vnd.antix.game-component atx +application/vnd.apple.installer+xml mpkg +application/vnd.apple.mpegurl m3u8 +# application/vnd.arastra.swi +application/vnd.aristanetworks.swi swi +application/vnd.audiograph aep +# application/vnd.autopackage +# application/vnd.avistar+xml +application/vnd.blueice.multipass mpm +# application/vnd.bluetooth.ep.oob +application/vnd.bmi bmi +application/vnd.businessobjects rep +# application/vnd.cab-jscript +# application/vnd.canon-cpdl +# application/vnd.canon-lips +# application/vnd.cendio.thinlinc.clientconf +application/vnd.chemdraw+xml cdxml +application/vnd.chipnuts.karaoke-mmd mmd +application/vnd.cinderella cdy +# application/vnd.cirpack.isdn-ext +application/vnd.claymore cla +application/vnd.cloanto.rp9 rp9 +application/vnd.clonk.c4group c4g c4d c4f c4p c4u +application/vnd.cluetrust.cartomobile-config c11amc +application/vnd.cluetrust.cartomobile-config-pkg c11amz +# application/vnd.commerce-battelle +application/vnd.commonspace csp +application/vnd.contact.cmsg cdbcmsg +application/vnd.cosmocaller cmc +application/vnd.crick.clicker clkx +application/vnd.crick.clicker.keyboard clkk +application/vnd.crick.clicker.palette clkp +application/vnd.crick.clicker.template clkt +application/vnd.crick.clicker.wordbank clkw +application/vnd.criticaltools.wbs+xml wbs +application/vnd.ctc-posml pml +# application/vnd.ctct.ws+xml +# application/vnd.cups-pdf +# application/vnd.cups-postscript +application/vnd.cups-ppd ppd +# application/vnd.cups-raster +# application/vnd.cups-raw +application/vnd.curl.car car +application/vnd.curl.pcurl pcurl +# application/vnd.cybank +application/vnd.data-vision.rdz rdz +application/vnd.dece.data uvf uvvf uvd uvvd +application/vnd.dece.ttml+xml uvt uvvt +application/vnd.dece.unspecified uvx uvvx +application/vnd.denovo.fcselayout-link fe_launch +# application/vnd.dir-bi.plate-dl-nosuffix +application/vnd.dna dna +application/vnd.dolby.mlp mlp +# application/vnd.dolby.mobile.1 +# application/vnd.dolby.mobile.2 +application/vnd.dpgraph dpg +application/vnd.dreamfactory dfac +application/vnd.dvb.ait ait +# application/vnd.dvb.dvbj +# application/vnd.dvb.esgcontainer +# application/vnd.dvb.ipdcdftnotifaccess +# application/vnd.dvb.ipdcesgaccess +# application/vnd.dvb.ipdcesgaccess2 +# application/vnd.dvb.ipdcesgpdd +# application/vnd.dvb.ipdcroaming +# application/vnd.dvb.iptv.alfec-base +# application/vnd.dvb.iptv.alfec-enhancement +# application/vnd.dvb.notif-aggregate-root+xml +# application/vnd.dvb.notif-container+xml +# application/vnd.dvb.notif-generic+xml +# application/vnd.dvb.notif-ia-msglist+xml +# application/vnd.dvb.notif-ia-registration-request+xml +# application/vnd.dvb.notif-ia-registration-response+xml +# application/vnd.dvb.notif-init+xml +# application/vnd.dvb.pfr +application/vnd.dvb.service svc +# application/vnd.dxr +application/vnd.dynageo geo +# application/vnd.easykaraoke.cdgdownload +# application/vnd.ecdis-update +application/vnd.ecowin.chart mag +# application/vnd.ecowin.filerequest +# application/vnd.ecowin.fileupdate +# application/vnd.ecowin.series +# application/vnd.ecowin.seriesrequest +# application/vnd.ecowin.seriesupdate +# application/vnd.emclient.accessrequest+xml +application/vnd.enliven nml +application/vnd.epson.esf esf +application/vnd.epson.msf msf +application/vnd.epson.quickanime qam +application/vnd.epson.salt slt +application/vnd.epson.ssf ssf +# application/vnd.ericsson.quickcall +application/vnd.eszigno3+xml es3 et3 +# application/vnd.etsi.aoc+xml +# application/vnd.etsi.cug+xml +# application/vnd.etsi.iptvcommand+xml +# application/vnd.etsi.iptvdiscovery+xml +# application/vnd.etsi.iptvprofile+xml +# application/vnd.etsi.iptvsad-bc+xml +# application/vnd.etsi.iptvsad-cod+xml +# application/vnd.etsi.iptvsad-npvr+xml +# application/vnd.etsi.iptvservice+xml +# application/vnd.etsi.iptvsync+xml +# application/vnd.etsi.iptvueprofile+xml +# application/vnd.etsi.mcid+xml +# application/vnd.etsi.overload-control-policy-dataset+xml +# application/vnd.etsi.sci+xml +# application/vnd.etsi.simservs+xml +# application/vnd.etsi.tsl+xml +# application/vnd.etsi.tsl.der +# application/vnd.eudora.data +application/vnd.ezpix-album ez2 +application/vnd.ezpix-package ez3 +# application/vnd.f-secure.mobile +application/vnd.fdf fdf +application/vnd.fdsn.mseed mseed +application/vnd.fdsn.seed seed dataless +# application/vnd.ffsns +# application/vnd.fints +application/vnd.flographit gph +application/vnd.fluxtime.clip ftc +# application/vnd.font-fontforge-sfd +application/vnd.framemaker fm frame maker book +application/vnd.frogans.fnc fnc +application/vnd.frogans.ltf ltf +application/vnd.fsc.weblaunch fsc +application/vnd.fujitsu.oasys oas +application/vnd.fujitsu.oasys2 oa2 +application/vnd.fujitsu.oasys3 oa3 +application/vnd.fujitsu.oasysgp fg5 +application/vnd.fujitsu.oasysprs bh2 +# application/vnd.fujixerox.art-ex +# application/vnd.fujixerox.art4 +# application/vnd.fujixerox.hbpl +application/vnd.fujixerox.ddd ddd +application/vnd.fujixerox.docuworks xdw +application/vnd.fujixerox.docuworks.binder xbd +# application/vnd.fut-misnet +application/vnd.fuzzysheet fzs +application/vnd.genomatix.tuxedo txd +# application/vnd.geocube+xml +application/vnd.geogebra.file ggb +application/vnd.geogebra.tool ggt +application/vnd.geometry-explorer gex gre +application/vnd.geonext gxt +application/vnd.geoplan g2w +application/vnd.geospace g3w +# application/vnd.globalplatform.card-content-mgt +# application/vnd.globalplatform.card-content-mgt-response +application/vnd.gmx gmx +application/vnd.google-earth.kml+xml kml +application/vnd.google-earth.kmz kmz +application/vnd.grafeq gqf gqs +# application/vnd.gridmp +application/vnd.groove-account gac +application/vnd.groove-help ghf +application/vnd.groove-identity-message gim +application/vnd.groove-injector grv +application/vnd.groove-tool-message gtm +application/vnd.groove-tool-template tpl +application/vnd.groove-vcard vcg +application/vnd.hal+xml hal +application/vnd.handheld-entertainment+xml zmm +application/vnd.hbci hbci +# application/vnd.hcl-bireports +application/vnd.hhe.lesson-player les +application/vnd.hp-hpgl hpgl +application/vnd.hp-hpid hpid +application/vnd.hp-hps hps +application/vnd.hp-jlyt jlt +application/vnd.hp-pcl pcl +application/vnd.hp-pclxl pclxl +# application/vnd.httphone +application/vnd.hydrostatix.sof-data sfd-hdstx +application/vnd.hzn-3d-crossword x3d +# application/vnd.ibm.afplinedata +# application/vnd.ibm.electronic-media +application/vnd.ibm.minipay mpy +application/vnd.ibm.modcap afp listafp list3820 +application/vnd.ibm.rights-management irm +application/vnd.ibm.secure-container sc +application/vnd.iccprofile icc icm +application/vnd.igloader igl +application/vnd.immervision-ivp ivp +application/vnd.immervision-ivu ivu +# application/vnd.informedcontrol.rms+xml +# application/vnd.informix-visionary +# application/vnd.infotech.project +# application/vnd.infotech.project+xml +application/vnd.insors.igm igm +application/vnd.intercon.formnet xpw xpx +application/vnd.intergeo i2g +# application/vnd.intertrust.digibox +# application/vnd.intertrust.nncp +application/vnd.intu.qbo qbo +application/vnd.intu.qfx qfx +# application/vnd.iptc.g2.conceptitem+xml +# application/vnd.iptc.g2.knowledgeitem+xml +# application/vnd.iptc.g2.newsitem+xml +# application/vnd.iptc.g2.packageitem+xml +application/vnd.ipunplugged.rcprofile rcprofile +application/vnd.irepository.package+xml irp +application/vnd.is-xpr xpr +application/vnd.isac.fcs fcs +application/vnd.jam jam +# application/vnd.japannet-directory-service +# application/vnd.japannet-jpnstore-wakeup +# application/vnd.japannet-payment-wakeup +# application/vnd.japannet-registration +# application/vnd.japannet-registration-wakeup +# application/vnd.japannet-setstore-wakeup +# application/vnd.japannet-verification +# application/vnd.japannet-verification-wakeup +application/vnd.jcp.javame.midlet-rms rms +application/vnd.jisp jisp +application/vnd.joost.joda-archive joda +application/vnd.kahootz ktz ktr +application/vnd.kde.karbon karbon +application/vnd.kde.kchart chrt +application/vnd.kde.kformula kfo +application/vnd.kde.kivio flw +application/vnd.kde.kontour kon +application/vnd.kde.kpresenter kpr kpt +application/vnd.kde.kspread ksp +application/vnd.kde.kword kwd kwt +application/vnd.kenameaapp htke +application/vnd.kidspiration kia +application/vnd.kinar kne knp +application/vnd.koan skp skd skt skm +application/vnd.kodak-descriptor sse +application/vnd.las.las+xml lasxml +# application/vnd.liberty-request+xml +application/vnd.llamagraphics.life-balance.desktop lbd +application/vnd.llamagraphics.life-balance.exchange+xml lbe +application/vnd.lotus-1-2-3 123 +application/vnd.lotus-approach apr +application/vnd.lotus-freelance pre +application/vnd.lotus-notes nsf +application/vnd.lotus-organizer org +application/vnd.lotus-screencam scm +application/vnd.lotus-wordpro lwp +application/vnd.macports.portpkg portpkg +# application/vnd.marlin.drm.actiontoken+xml +# application/vnd.marlin.drm.conftoken+xml +# application/vnd.marlin.drm.license+xml +# application/vnd.marlin.drm.mdcf +application/vnd.mcd mcd +application/vnd.medcalcdata mc1 +application/vnd.mediastation.cdkey cdkey +# application/vnd.meridian-slingshot +application/vnd.mfer mwf +application/vnd.mfmp mfm +application/vnd.micrografx.flo flo +application/vnd.micrografx.igx igx +application/vnd.mif mif +# application/vnd.minisoft-hp3000-save +# application/vnd.mitsubishi.misty-guard.trustweb +application/vnd.mobius.daf daf +application/vnd.mobius.dis dis +application/vnd.mobius.mbk mbk +application/vnd.mobius.mqy mqy +application/vnd.mobius.msl msl +application/vnd.mobius.plc plc +application/vnd.mobius.txf txf +application/vnd.mophun.application mpn +application/vnd.mophun.certificate mpc +# application/vnd.motorola.flexsuite +# application/vnd.motorola.flexsuite.adsi +# application/vnd.motorola.flexsuite.fis +# application/vnd.motorola.flexsuite.gotap +# application/vnd.motorola.flexsuite.kmr +# application/vnd.motorola.flexsuite.ttc +# application/vnd.motorola.flexsuite.wem +# application/vnd.motorola.iprm +application/vnd.mozilla.xul+xml xul +application/vnd.ms-artgalry cil +# application/vnd.ms-asf +application/vnd.ms-cab-compressed cab +application/vnd.ms-excel xls xlm xla xlc xlt xlw +application/vnd.ms-excel.addin.macroenabled.12 xlam +application/vnd.ms-excel.sheet.binary.macroenabled.12 xlsb +application/vnd.ms-excel.sheet.macroenabled.12 xlsm +application/vnd.ms-excel.template.macroenabled.12 xltm +application/vnd.ms-fontobject eot +application/vnd.ms-htmlhelp chm +application/vnd.ms-ims ims +application/vnd.ms-lrm lrm +# application/vnd.ms-office.activex+xml +application/vnd.ms-officetheme thmx +application/vnd.ms-pki.seccat cat +application/vnd.ms-pki.stl stl +# application/vnd.ms-playready.initiator+xml +application/vnd.ms-powerpoint ppt pps pot +application/vnd.ms-powerpoint.addin.macroenabled.12 ppam +application/vnd.ms-powerpoint.presentation.macroenabled.12 pptm +application/vnd.ms-powerpoint.slide.macroenabled.12 sldm +application/vnd.ms-powerpoint.slideshow.macroenabled.12 ppsm +application/vnd.ms-powerpoint.template.macroenabled.12 potm +application/vnd.ms-project mpp mpt +# application/vnd.ms-tnef +# application/vnd.ms-wmdrm.lic-chlg-req +# application/vnd.ms-wmdrm.lic-resp +# application/vnd.ms-wmdrm.meter-chlg-req +# application/vnd.ms-wmdrm.meter-resp +application/vnd.ms-word.document.macroenabled.12 docm +application/vnd.ms-word.template.macroenabled.12 dotm +application/vnd.ms-works wps wks wcm wdb +application/vnd.ms-wpl wpl +application/vnd.ms-xpsdocument xps +application/vnd.mseq mseq +# application/vnd.msign +# application/vnd.multiad.creator +# application/vnd.multiad.creator.cif +# application/vnd.music-niff +application/vnd.musician mus +application/vnd.muvee.style msty +# application/vnd.ncd.control +# application/vnd.ncd.reference +# application/vnd.nervana +# application/vnd.netfpx +application/vnd.neurolanguage.nlu nlu +application/vnd.noblenet-directory nnd +application/vnd.noblenet-sealer nns +application/vnd.noblenet-web nnw +# application/vnd.nokia.catalogs +# application/vnd.nokia.conml+wbxml +# application/vnd.nokia.conml+xml +# application/vnd.nokia.isds-radio-presets +# application/vnd.nokia.iptv.config+xml +# application/vnd.nokia.landmark+wbxml +# application/vnd.nokia.landmark+xml +# application/vnd.nokia.landmarkcollection+xml +# application/vnd.nokia.n-gage.ac+xml +application/vnd.nokia.n-gage.data ngdat +application/vnd.nokia.n-gage.symbian.install n-gage +# application/vnd.nokia.ncd +# application/vnd.nokia.pcd+wbxml +# application/vnd.nokia.pcd+xml +application/vnd.nokia.radio-preset rpst +application/vnd.nokia.radio-presets rpss +application/vnd.novadigm.edm edm +application/vnd.novadigm.edx edx +application/vnd.novadigm.ext ext +# application/vnd.ntt-local.file-transfer +# application/vnd.ntt-local.sip-ta_remote +# application/vnd.ntt-local.sip-ta_tcp_stream +application/vnd.oasis.opendocument.chart odc +application/vnd.oasis.opendocument.chart-template otc +application/vnd.oasis.opendocument.database odb +application/vnd.oasis.opendocument.formula odf +application/vnd.oasis.opendocument.formula-template odft +application/vnd.oasis.opendocument.graphics odg +application/vnd.oasis.opendocument.graphics-template otg +application/vnd.oasis.opendocument.image odi +application/vnd.oasis.opendocument.image-template oti +application/vnd.oasis.opendocument.presentation odp +application/vnd.oasis.opendocument.presentation-template otp +application/vnd.oasis.opendocument.spreadsheet ods +application/vnd.oasis.opendocument.spreadsheet-template ots +application/vnd.oasis.opendocument.text odt +application/vnd.oasis.opendocument.text-master odm +application/vnd.oasis.opendocument.text-template ott +application/vnd.oasis.opendocument.text-web oth +# application/vnd.obn +# application/vnd.oipf.contentaccessdownload+xml +# application/vnd.oipf.contentaccessstreaming+xml +# application/vnd.oipf.cspg-hexbinary +# application/vnd.oipf.dae.svg+xml +# application/vnd.oipf.dae.xhtml+xml +# application/vnd.oipf.mippvcontrolmessage+xml +# application/vnd.oipf.pae.gem +# application/vnd.oipf.spdiscovery+xml +# application/vnd.oipf.spdlist+xml +# application/vnd.oipf.ueprofile+xml +# application/vnd.oipf.userprofile+xml +application/vnd.olpc-sugar xo +# application/vnd.oma-scws-config +# application/vnd.oma-scws-http-request +# application/vnd.oma-scws-http-response +# application/vnd.oma.bcast.associated-procedure-parameter+xml +# application/vnd.oma.bcast.drm-trigger+xml +# application/vnd.oma.bcast.imd+xml +# application/vnd.oma.bcast.ltkm +# application/vnd.oma.bcast.notification+xml +# application/vnd.oma.bcast.provisioningtrigger +# application/vnd.oma.bcast.sgboot +# application/vnd.oma.bcast.sgdd+xml +# application/vnd.oma.bcast.sgdu +# application/vnd.oma.bcast.simple-symbol-container +# application/vnd.oma.bcast.smartcard-trigger+xml +# application/vnd.oma.bcast.sprov+xml +# application/vnd.oma.bcast.stkm +# application/vnd.oma.cab-address-book+xml +# application/vnd.oma.cab-pcc+xml +# application/vnd.oma.dcd +# application/vnd.oma.dcdc +application/vnd.oma.dd2+xml dd2 +# application/vnd.oma.drm.risd+xml +# application/vnd.oma.group-usage-list+xml +# application/vnd.oma.poc.detailed-progress-report+xml +# application/vnd.oma.poc.final-report+xml +# application/vnd.oma.poc.groups+xml +# application/vnd.oma.poc.invocation-descriptor+xml +# application/vnd.oma.poc.optimized-progress-report+xml +# application/vnd.oma.push +# application/vnd.oma.scidm.messages+xml +# application/vnd.oma.xcap-directory+xml +# application/vnd.omads-email+xml +# application/vnd.omads-file+xml +# application/vnd.omads-folder+xml +# application/vnd.omaloc-supl-init +application/vnd.openofficeorg.extension oxt +# application/vnd.openxmlformats-officedocument.custom-properties+xml +# application/vnd.openxmlformats-officedocument.customxmlproperties+xml +# application/vnd.openxmlformats-officedocument.drawing+xml +# application/vnd.openxmlformats-officedocument.drawingml.chart+xml +# application/vnd.openxmlformats-officedocument.drawingml.chartshapes+xml +# application/vnd.openxmlformats-officedocument.drawingml.diagramcolors+xml +# application/vnd.openxmlformats-officedocument.drawingml.diagramdata+xml +# application/vnd.openxmlformats-officedocument.drawingml.diagramlayout+xml +# application/vnd.openxmlformats-officedocument.drawingml.diagramstyle+xml +# application/vnd.openxmlformats-officedocument.extended-properties+xml +# application/vnd.openxmlformats-officedocument.presentationml.commentauthors+xml +# application/vnd.openxmlformats-officedocument.presentationml.comments+xml +# application/vnd.openxmlformats-officedocument.presentationml.handoutmaster+xml +# application/vnd.openxmlformats-officedocument.presentationml.notesmaster+xml +# application/vnd.openxmlformats-officedocument.presentationml.notesslide+xml +application/vnd.openxmlformats-officedocument.presentationml.presentation pptx +# application/vnd.openxmlformats-officedocument.presentationml.presentation.main+xml +# application/vnd.openxmlformats-officedocument.presentationml.presprops+xml +application/vnd.openxmlformats-officedocument.presentationml.slide sldx +# application/vnd.openxmlformats-officedocument.presentationml.slide+xml +# application/vnd.openxmlformats-officedocument.presentationml.slidelayout+xml +# application/vnd.openxmlformats-officedocument.presentationml.slidemaster+xml +application/vnd.openxmlformats-officedocument.presentationml.slideshow ppsx +# application/vnd.openxmlformats-officedocument.presentationml.slideshow.main+xml +# application/vnd.openxmlformats-officedocument.presentationml.slideupdateinfo+xml +# application/vnd.openxmlformats-officedocument.presentationml.tablestyles+xml +# application/vnd.openxmlformats-officedocument.presentationml.tags+xml +application/vnd.openxmlformats-officedocument.presentationml.template potx +# application/vnd.openxmlformats-officedocument.presentationml.template.main+xml +# application/vnd.openxmlformats-officedocument.presentationml.viewprops+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.calcchain+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.chartsheet+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.connections+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.dialogsheet+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.externallink+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.pivotcachedefinition+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.pivotcacherecords+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.pivottable+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.querytable+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.revisionheaders+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.revisionlog+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.sharedstrings+xml +application/vnd.openxmlformats-officedocument.spreadsheetml.sheet xlsx +# application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.sheetmetadata+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.table+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.tablesinglecells+xml +application/vnd.openxmlformats-officedocument.spreadsheetml.template xltx +# application/vnd.openxmlformats-officedocument.spreadsheetml.template.main+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.usernames+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.volatiledependencies+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml +# application/vnd.openxmlformats-officedocument.theme+xml +# application/vnd.openxmlformats-officedocument.themeoverride+xml +# application/vnd.openxmlformats-officedocument.vmldrawing +# application/vnd.openxmlformats-officedocument.wordprocessingml.comments+xml +application/vnd.openxmlformats-officedocument.wordprocessingml.document docx +# application/vnd.openxmlformats-officedocument.wordprocessingml.document.glossary+xml +# application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml +# application/vnd.openxmlformats-officedocument.wordprocessingml.endnotes+xml +# application/vnd.openxmlformats-officedocument.wordprocessingml.fonttable+xml +# application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml +# application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml +# application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml +# application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml +# application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml +application/vnd.openxmlformats-officedocument.wordprocessingml.template dotx +# application/vnd.openxmlformats-officedocument.wordprocessingml.template.main+xml +# application/vnd.openxmlformats-officedocument.wordprocessingml.websettings+xml +# application/vnd.openxmlformats-package.core-properties+xml +# application/vnd.openxmlformats-package.digital-signature-xmlsignature+xml +# application/vnd.openxmlformats-package.relationships+xml +# application/vnd.quobject-quoxdocument +# application/vnd.osa.netdeploy +application/vnd.osgeo.mapguide.package mgp +# application/vnd.osgi.bundle +application/vnd.osgi.dp dp +# application/vnd.otps.ct-kip+xml +application/vnd.palm pdb pqa oprc +# application/vnd.paos.xml +application/vnd.pawaafile paw +application/vnd.pg.format str +application/vnd.pg.osasli ei6 +# application/vnd.piaccess.application-licence +application/vnd.picsel efif +application/vnd.pmi.widget wg +# application/vnd.poc.group-advertisement+xml +application/vnd.pocketlearn plf +application/vnd.powerbuilder6 pbd +# application/vnd.powerbuilder6-s +# application/vnd.powerbuilder7 +# application/vnd.powerbuilder7-s +# application/vnd.powerbuilder75 +# application/vnd.powerbuilder75-s +# application/vnd.preminet +application/vnd.previewsystems.box box +application/vnd.proteus.magazine mgz +application/vnd.publishare-delta-tree qps +application/vnd.pvi.ptid1 ptid +# application/vnd.pwg-multiplexed +# application/vnd.pwg-xhtml-print+xml +# application/vnd.qualcomm.brew-app-res +application/vnd.quark.quarkxpress qxd qxt qwd qwt qxl qxb +# application/vnd.radisys.moml+xml +# application/vnd.radisys.msml+xml +# application/vnd.radisys.msml-audit+xml +# application/vnd.radisys.msml-audit-conf+xml +# application/vnd.radisys.msml-audit-conn+xml +# application/vnd.radisys.msml-audit-dialog+xml +# application/vnd.radisys.msml-audit-stream+xml +# application/vnd.radisys.msml-conf+xml +# application/vnd.radisys.msml-dialog+xml +# application/vnd.radisys.msml-dialog-base+xml +# application/vnd.radisys.msml-dialog-fax-detect+xml +# application/vnd.radisys.msml-dialog-fax-sendrecv+xml +# application/vnd.radisys.msml-dialog-group+xml +# application/vnd.radisys.msml-dialog-speech+xml +# application/vnd.radisys.msml-dialog-transform+xml +# application/vnd.rainstor.data +# application/vnd.rapid +application/vnd.realvnc.bed bed +application/vnd.recordare.musicxml mxl +application/vnd.recordare.musicxml+xml musicxml +# application/vnd.renlearn.rlprint +application/vnd.rig.cryptonote cryptonote +application/vnd.rim.cod cod +application/vnd.rn-realmedia rm +application/vnd.route66.link66+xml link66 +# application/vnd.ruckus.download +# application/vnd.s3sms +application/vnd.sailingtracker.track st +# application/vnd.sbm.cid +# application/vnd.sbm.mid2 +# application/vnd.scribus +# application/vnd.sealed.3df +# application/vnd.sealed.csf +# application/vnd.sealed.doc +# application/vnd.sealed.eml +# application/vnd.sealed.mht +# application/vnd.sealed.net +# application/vnd.sealed.ppt +# application/vnd.sealed.tiff +# application/vnd.sealed.xls +# application/vnd.sealedmedia.softseal.html +# application/vnd.sealedmedia.softseal.pdf +application/vnd.seemail see +application/vnd.sema sema +application/vnd.semd semd +application/vnd.semf semf +application/vnd.shana.informed.formdata ifm +application/vnd.shana.informed.formtemplate itp +application/vnd.shana.informed.interchange iif +application/vnd.shana.informed.package ipk +application/vnd.simtech-mindmapper twd twds +application/vnd.smaf mmf +# application/vnd.smart.notebook +application/vnd.smart.teacher teacher +# application/vnd.software602.filler.form+xml +# application/vnd.software602.filler.form-xml-zip +application/vnd.solent.sdkm+xml sdkm sdkd +application/vnd.spotfire.dxp dxp +application/vnd.spotfire.sfs sfs +# application/vnd.sss-cod +# application/vnd.sss-dtf +# application/vnd.sss-ntf +application/vnd.stardivision.calc sdc +application/vnd.stardivision.draw sda +application/vnd.stardivision.impress sdd +application/vnd.stardivision.math smf +application/vnd.stardivision.writer sdw vor +application/vnd.stardivision.writer-global sgl +application/vnd.stepmania.stepchart sm +# application/vnd.street-stream +application/vnd.sun.xml.calc sxc +application/vnd.sun.xml.calc.template stc +application/vnd.sun.xml.draw sxd +application/vnd.sun.xml.draw.template std +application/vnd.sun.xml.impress sxi +application/vnd.sun.xml.impress.template sti +application/vnd.sun.xml.math sxm +application/vnd.sun.xml.writer sxw +application/vnd.sun.xml.writer.global sxg +application/vnd.sun.xml.writer.template stw +# application/vnd.sun.wadl+xml +application/vnd.sus-calendar sus susp +application/vnd.svd svd +# application/vnd.swiftview-ics +application/vnd.symbian.install sis sisx +application/vnd.syncml+xml xsm +application/vnd.syncml.dm+wbxml bdm +application/vnd.syncml.dm+xml xdm +# application/vnd.syncml.dm.notification +# application/vnd.syncml.ds.notification +application/vnd.tao.intent-module-archive tao +application/vnd.tmobile-livetv tmo +application/vnd.trid.tpt tpt +application/vnd.triscape.mxs mxs +application/vnd.trueapp tra +# application/vnd.truedoc +# application/vnd.ubisoft.webplayer +application/vnd.ufdl ufd ufdl +application/vnd.uiq.theme utz +application/vnd.umajin umj +application/vnd.unity unityweb +application/vnd.uoml+xml uoml +# application/vnd.uplanet.alert +# application/vnd.uplanet.alert-wbxml +# application/vnd.uplanet.bearer-choice +# application/vnd.uplanet.bearer-choice-wbxml +# application/vnd.uplanet.cacheop +# application/vnd.uplanet.cacheop-wbxml +# application/vnd.uplanet.channel +# application/vnd.uplanet.channel-wbxml +# application/vnd.uplanet.list +# application/vnd.uplanet.list-wbxml +# application/vnd.uplanet.listcmd +# application/vnd.uplanet.listcmd-wbxml +# application/vnd.uplanet.signal +application/vnd.vcx vcx +# application/vnd.vd-study +# application/vnd.vectorworks +# application/vnd.verimatrix.vcas +# application/vnd.vidsoft.vidconference +application/vnd.visio vsd vst vss vsw +application/vnd.visionary vis +# application/vnd.vividence.scriptfile +application/vnd.vsf vsf +# application/vnd.wap.sic +# application/vnd.wap.slc +application/vnd.wap.wbxml wbxml +application/vnd.wap.wmlc wmlc +application/vnd.wap.wmlscriptc wmlsc +application/vnd.webturbo wtb +# application/vnd.wfa.wsc +# application/vnd.wmc +# application/vnd.wmf.bootstrap +# application/vnd.wolfram.mathematica +# application/vnd.wolfram.mathematica.package +application/vnd.wolfram.player nbp +application/vnd.wordperfect wpd +application/vnd.wqd wqd +# application/vnd.wrq-hp3000-labelled +application/vnd.wt.stf stf +# application/vnd.wv.csp+wbxml +# application/vnd.wv.csp+xml +# application/vnd.wv.ssp+xml +application/vnd.xara xar +application/vnd.xfdl xfdl +# application/vnd.xfdl.webform +# application/vnd.xmi+xml +# application/vnd.xmpie.cpkg +# application/vnd.xmpie.dpkg +# application/vnd.xmpie.plan +# application/vnd.xmpie.ppkg +# application/vnd.xmpie.xlim +application/vnd.yamaha.hv-dic hvd +application/vnd.yamaha.hv-script hvs +application/vnd.yamaha.hv-voice hvp +application/vnd.yamaha.openscoreformat osf +application/vnd.yamaha.openscoreformat.osfpvg+xml osfpvg +# application/vnd.yamaha.remote-setup +application/vnd.yamaha.smaf-audio saf +application/vnd.yamaha.smaf-phrase spf +# application/vnd.yamaha.tunnel-udpencap +application/vnd.yellowriver-custom-menu cmp +application/vnd.zul zir zirz +application/vnd.zzazz.deck+xml zaz +application/voicexml+xml vxml +# application/vq-rtcpxr +# application/watcherinfo+xml +# application/whoispp-query +# application/whoispp-response +application/widget wgt +application/winhlp hlp +# application/wita +# application/wordperfect5.1 +application/wsdl+xml wsdl +application/wspolicy+xml wspolicy +application/x-7z-compressed 7z +application/x-abiword abw +application/x-ace-compressed ace +application/x-authorware-bin aab x32 u32 vox +application/x-authorware-map aam +application/x-authorware-seg aas +application/x-bcpio bcpio +application/x-bittorrent torrent +application/x-bzip bz +application/x-bzip2 bz2 boz +application/x-cdlink vcd +application/x-chat chat +application/x-chess-pgn pgn +# application/x-compress +application/x-cpio cpio +application/x-csh csh +application/x-debian-package deb udeb +application/x-director dir dcr dxr cst cct cxt w3d fgd swa +application/x-doom wad +application/x-dtbncx+xml ncx +application/x-dtbook+xml dtb +application/x-dtbresource+xml res +application/x-dvi dvi +application/x-font-bdf bdf +# application/x-font-dos +# application/x-font-framemaker +application/x-font-ghostscript gsf +# application/x-font-libgrx +application/x-font-linux-psf psf +application/x-font-otf otf +application/x-font-pcf pcf +application/x-font-snf snf +# application/x-font-speedo +# application/x-font-sunos-news +application/x-font-ttf ttf ttc +application/x-font-type1 pfa pfb pfm afm +application/x-font-woff woff +# application/x-font-vfont +application/x-futuresplash spl +application/x-gnumeric gnumeric +application/x-gtar gtar +# application/x-gzip +application/x-hdf hdf +application/x-java-jnlp-file jnlp +application/x-latex latex +application/x-mobipocket-ebook prc mobi +application/x-ms-application application +application/x-ms-wmd wmd +application/x-ms-wmz wmz +application/x-ms-xbap xbap +application/x-msaccess mdb +application/x-msbinder obd +application/x-mscardfile crd +application/x-msclip clp +application/x-msdownload exe dll com bat msi +application/x-msmediaview mvb m13 m14 +application/x-msmetafile wmf +application/x-msmoney mny +application/x-mspublisher pub +application/x-msschedule scd +application/x-msterminal trm +application/x-mswrite wri +application/x-netcdf nc cdf +application/x-pkcs12 p12 pfx +application/x-pkcs7-certificates p7b spc +application/x-pkcs7-certreqresp p7r +application/x-rar-compressed rar +application/x-sh sh +application/x-shar shar +application/x-shockwave-flash swf +application/x-silverlight-app xap +application/x-stuffit sit +application/x-stuffitx sitx +application/x-sv4cpio sv4cpio +application/x-sv4crc sv4crc +application/x-tar tar +application/x-tcl tcl +application/x-tex tex +application/x-tex-tfm tfm +application/x-texinfo texinfo texi +application/x-ustar ustar +application/x-wais-source src +application/x-x509-ca-cert der crt +application/x-xfig fig +application/x-xpinstall xpi +# application/x400-bp +# application/xcap-att+xml +# application/xcap-caps+xml +application/xcap-diff+xml xdf +# application/xcap-el+xml +# application/xcap-error+xml +# application/xcap-ns+xml +# application/xcon-conference-info-diff+xml +# application/xcon-conference-info+xml +application/xenc+xml xenc +application/xhtml+xml xhtml xht +# application/xhtml-voice+xml +application/xml xml xsl +application/xml-dtd dtd +# application/xml-external-parsed-entity +# application/xmpp+xml +application/xop+xml xop +application/xslt+xml xslt +application/xspf+xml xspf +application/xv+xml mxml xhvml xvml xvm +application/yang yang +application/yin+xml yin +application/zip zip +# audio/1d-interleaved-parityfec +# audio/32kadpcm +# audio/3gpp +# audio/3gpp2 +# audio/ac3 +audio/adpcm adp +# audio/amr +# audio/amr-wb +# audio/amr-wb+ +# audio/asc +# audio/atrac-advanced-lossless +# audio/atrac-x +# audio/atrac3 +audio/basic au snd +# audio/bv16 +# audio/bv32 +# audio/clearmode +# audio/cn +# audio/dat12 +# audio/dls +# audio/dsr-es201108 +# audio/dsr-es202050 +# audio/dsr-es202211 +# audio/dsr-es202212 +# audio/dvi4 +# audio/eac3 +# audio/evrc +# audio/evrc-qcp +# audio/evrc0 +# audio/evrc1 +# audio/evrcb +# audio/evrcb0 +# audio/evrcb1 +# audio/evrcwb +# audio/evrcwb0 +# audio/evrcwb1 +# audio/example +# audio/g719 +# audio/g722 +# audio/g7221 +# audio/g723 +# audio/g726-16 +# audio/g726-24 +# audio/g726-32 +# audio/g726-40 +# audio/g728 +# audio/g729 +# audio/g7291 +# audio/g729d +# audio/g729e +# audio/gsm +# audio/gsm-efr +# audio/gsm-hr-08 +# audio/ilbc +# audio/l16 +# audio/l20 +# audio/l24 +# audio/l8 +# audio/lpc +audio/midi mid midi kar rmi +# audio/mobile-xmf +audio/mp4 mp4a +# audio/mp4a-latm +# audio/mpa +# audio/mpa-robust +audio/mpeg mpga mp2 mp2a mp3 m2a m3a +# audio/mpeg4-generic +audio/ogg oga ogg spx +# audio/parityfec +# audio/pcma +# audio/pcma-wb +# audio/pcmu-wb +# audio/pcmu +# audio/prs.sid +# audio/qcelp +# audio/red +# audio/rtp-enc-aescm128 +# audio/rtp-midi +# audio/rtx +# audio/smv +# audio/smv0 +# audio/smv-qcp +# audio/sp-midi +# audio/speex +# audio/t140c +# audio/t38 +# audio/telephone-event +# audio/tone +# audio/uemclip +# audio/ulpfec +# audio/vdvi +# audio/vmr-wb +# audio/vnd.3gpp.iufp +# audio/vnd.4sb +# audio/vnd.audiokoz +# audio/vnd.celp +# audio/vnd.cisco.nse +# audio/vnd.cmles.radio-events +# audio/vnd.cns.anp1 +# audio/vnd.cns.inf1 +audio/vnd.dece.audio uva uvva +audio/vnd.digital-winds eol +# audio/vnd.dlna.adts +# audio/vnd.dolby.heaac.1 +# audio/vnd.dolby.heaac.2 +# audio/vnd.dolby.mlp +# audio/vnd.dolby.mps +# audio/vnd.dolby.pl2 +# audio/vnd.dolby.pl2x +# audio/vnd.dolby.pl2z +# audio/vnd.dolby.pulse.1 +audio/vnd.dra dra +audio/vnd.dts dts +audio/vnd.dts.hd dtshd +# audio/vnd.everad.plj +# audio/vnd.hns.audio +audio/vnd.lucent.voice lvp +audio/vnd.ms-playready.media.pya pya +# audio/vnd.nokia.mobile-xmf +# audio/vnd.nortel.vbk +audio/vnd.nuera.ecelp4800 ecelp4800 +audio/vnd.nuera.ecelp7470 ecelp7470 +audio/vnd.nuera.ecelp9600 ecelp9600 +# audio/vnd.octel.sbc +# audio/vnd.qcelp +# audio/vnd.rhetorex.32kadpcm +audio/vnd.rip rip +# audio/vnd.sealedmedia.softseal.mpeg +# audio/vnd.vmx.cvsd +# audio/vorbis +# audio/vorbis-config +audio/webm weba +audio/x-aac aac +audio/x-aiff aif aiff aifc +audio/x-mpegurl m3u +audio/x-ms-wax wax +audio/x-ms-wma wma +audio/x-pn-realaudio ram ra +audio/x-pn-realaudio-plugin rmp +audio/x-wav wav +chemical/x-cdx cdx +chemical/x-cif cif +chemical/x-cmdf cmdf +chemical/x-cml cml +chemical/x-csml csml +# chemical/x-pdb +chemical/x-xyz xyz +image/bmp bmp +image/cgm cgm +# image/example +# image/fits +image/g3fax g3 +image/gif gif +image/ief ief +# image/jp2 +image/jpeg jpeg jpg jpe +# image/jpm +# image/jpx +image/ktx ktx +# image/naplps +image/png png +image/prs.btif btif +# image/prs.pti +image/svg+xml svg svgz +# image/t38 +image/tiff tiff tif +# image/tiff-fx +image/vnd.adobe.photoshop psd +# image/vnd.cns.inf2 +image/vnd.dece.graphic uvi uvvi uvg uvvg +image/vnd.dvb.subtitle sub +image/vnd.djvu djvu djv +image/vnd.dwg dwg +image/vnd.dxf dxf +image/vnd.fastbidsheet fbs +image/vnd.fpx fpx +image/vnd.fst fst +image/vnd.fujixerox.edmics-mmr mmr +image/vnd.fujixerox.edmics-rlc rlc +# image/vnd.globalgraphics.pgb +# image/vnd.microsoft.icon +# image/vnd.mix +image/vnd.ms-modi mdi +image/vnd.net-fpx npx +# image/vnd.radiance +# image/vnd.sealed.png +# image/vnd.sealedmedia.softseal.gif +# image/vnd.sealedmedia.softseal.jpg +# image/vnd.svf +image/vnd.wap.wbmp wbmp +image/vnd.xiff xif +image/webp webp +image/x-cmu-raster ras +image/x-cmx cmx +image/x-freehand fh fhc fh4 fh5 fh7 +image/x-icon ico +image/x-pcx pcx +image/x-pict pic pct +image/x-portable-anymap pnm +image/x-portable-bitmap pbm +image/x-portable-graymap pgm +image/x-portable-pixmap ppm +image/x-rgb rgb +image/x-xbitmap xbm +image/x-xpixmap xpm +image/x-xwindowdump xwd +# message/cpim +# message/delivery-status +# message/disposition-notification +# message/example +# message/external-body +# message/feedback-report +# message/global +# message/global-delivery-status +# message/global-disposition-notification +# message/global-headers +# message/http +# message/imdn+xml +# message/news +# message/partial +message/rfc822 eml mime +# message/s-http +# message/sip +# message/sipfrag +# message/tracking-status +# message/vnd.si.simp +# model/example +model/iges igs iges +model/mesh msh mesh silo +model/vnd.collada+xml dae +model/vnd.dwf dwf +# model/vnd.flatland.3dml +model/vnd.gdl gdl +# model/vnd.gs-gdl +# model/vnd.gs.gdl +model/vnd.gtw gtw +# model/vnd.moml+xml +model/vnd.mts mts +# model/vnd.parasolid.transmit.binary +# model/vnd.parasolid.transmit.text +model/vnd.vtu vtu +model/vrml wrl vrml +# multipart/alternative +# multipart/appledouble +# multipart/byteranges +# multipart/digest +# multipart/encrypted +# multipart/example +# multipart/form-data +# multipart/header-set +# multipart/mixed +# multipart/parallel +# multipart/related +# multipart/report +# multipart/signed +# multipart/voice-message +# text/1d-interleaved-parityfec +text/calendar ics ifb +text/css css +text/csv csv +# text/directory +# text/dns +# text/ecmascript +# text/enriched +# text/example +text/html html htm +# text/javascript +text/n3 n3 +# text/parityfec +text/plain txt text conf def list log in +# text/prs.fallenstein.rst +text/prs.lines.tag dsc +# text/vnd.radisys.msml-basic-layout +# text/red +# text/rfc822-headers +text/richtext rtx +# text/rtf +# text/rtp-enc-aescm128 +# text/rtx +text/sgml sgml sgm +# text/t140 +text/tab-separated-values tsv +text/troff t tr roff man me ms +text/turtle ttl +# text/ulpfec +text/uri-list uri uris urls +# text/vnd.abc +text/vnd.curl curl +text/vnd.curl.dcurl dcurl +text/vnd.curl.scurl scurl +text/vnd.curl.mcurl mcurl +# text/vnd.dmclientscript +# text/vnd.esmertec.theme-descriptor +text/vnd.fly fly +text/vnd.fmi.flexstor flx +text/vnd.graphviz gv +text/vnd.in3d.3dml 3dml +text/vnd.in3d.spot spot +# text/vnd.iptc.newsml +# text/vnd.iptc.nitf +# text/vnd.latex-z +# text/vnd.motorola.reflex +# text/vnd.ms-mediapackage +# text/vnd.net2phone.commcenter.command +# text/vnd.si.uricatalogue +text/vnd.sun.j2me.app-descriptor jad +# text/vnd.trolltech.linguist +# text/vnd.wap.si +# text/vnd.wap.sl +text/vnd.wap.wml wml +text/vnd.wap.wmlscript wmls +text/x-asm s asm +text/x-c c cc cxx cpp h hh dic +text/x-fortran f for f77 f90 +text/x-pascal p pas +text/x-java-source java +text/x-setext etx +text/x-uuencode uu +text/x-vcalendar vcs +text/x-vcard vcf +# text/xml +# text/xml-external-parsed-entity +# video/1d-interleaved-parityfec +video/3gpp 3gp +# video/3gpp-tt +video/3gpp2 3g2 +# video/bmpeg +# video/bt656 +# video/celb +# video/dv +# video/example +video/h261 h261 +video/h263 h263 +# video/h263-1998 +# video/h263-2000 +video/h264 h264 +# video/h264-rcdo +# video/h264-svc +video/jpeg jpgv +# video/jpeg2000 +video/jpm jpm jpgm +video/mj2 mj2 mjp2 +# video/mp1s +# video/mp2p +# video/mp2t +video/mp4 mp4 mp4v mpg4 +# video/mp4v-es +video/mpeg mpeg mpg mpe m1v m2v +# video/mpeg4-generic +# video/mpv +# video/nv +video/ogg ogv +# video/parityfec +# video/pointer +video/quicktime qt mov +# video/raw +# video/rtp-enc-aescm128 +# video/rtx +# video/smpte292m +# video/ulpfec +# video/vc1 +# video/vnd.cctv +video/vnd.dece.hd uvh uvvh +video/vnd.dece.mobile uvm uvvm +# video/vnd.dece.mp4 +video/vnd.dece.pd uvp uvvp +video/vnd.dece.sd uvs uvvs +video/vnd.dece.video uvv uvvv +# video/vnd.directv.mpeg +# video/vnd.directv.mpeg-tts +# video/vnd.dlna.mpeg-tts +video/vnd.fvt fvt +# video/vnd.hns.video +# video/vnd.iptvforum.1dparityfec-1010 +# video/vnd.iptvforum.1dparityfec-2005 +# video/vnd.iptvforum.2dparityfec-1010 +# video/vnd.iptvforum.2dparityfec-2005 +# video/vnd.iptvforum.ttsavc +# video/vnd.iptvforum.ttsmpeg2 +# video/vnd.motorola.video +# video/vnd.motorola.videop +video/vnd.mpegurl mxu m4u +video/vnd.ms-playready.media.pyv pyv +# video/vnd.nokia.interleaved-multimedia +# video/vnd.nokia.videovoip +# video/vnd.objectvideo +# video/vnd.sealed.mpeg1 +# video/vnd.sealed.mpeg4 +# video/vnd.sealed.swf +# video/vnd.sealedmedia.softseal.mov +video/vnd.uvvu.mp4 uvu uvvu +video/vnd.vivo viv +video/webm webm +video/x-f4v f4v +video/x-fli fli +video/x-flv flv +video/x-m4v m4v +video/x-ms-asf asf asx +video/x-ms-wm wm +video/x-ms-wmv wmv +video/x-ms-wmx wmx +video/x-ms-wvx wvx +video/x-msvideo avi +video/x-sgi-movie movie +x-conference/x-cooltalk ice diff --git a/node_modules/express/node_modules/connect/node_modules/mime/types/node.types b/node_modules/express/node_modules/connect/node_modules/mime/types/node.types new file mode 100644 index 0000000..fdabaa4 --- /dev/null +++ b/node_modules/express/node_modules/connect/node_modules/mime/types/node.types @@ -0,0 +1,43 @@ +# What: Google Chrome Extension +# Why: To allow apps to (work) be served with the right content type header. +# http://codereview.chromium.org/2830017 +# Added by: niftylettuce +application/x-chrome-extension crx + +# What: OTF Message Silencer +# Why: To silence the "Resource interpreted as font but transferred with MIME +# type font/otf" message that occurs in Google Chrome +# Added by: niftylettuce +font/opentype otf + +# What: HTC support +# Why: To properly render .htc files such as CSS3PIE +# Added by: niftylettuce +text/x-component htc + +# What: HTML5 application cache manifest +# Why: De-facto standard. Required by Mozilla browser when serving HTML5 apps +# per https://developer.mozilla.org/en/offline_resources_in_firefox +# Added by: louisremi +text/cache-manifest appcache manifest + +# What: node binary buffer format +# Why: semi-standard extension w/in the node community +# Added by: tootallnate +application/octet-stream buffer + +# What: The "protected" MP-4 formats used by iTunes. +# Why: Required for streaming music to browsers (?) +# Added by: broofa +application/mp4 m4p +audio/mp4 m4a + +# What: Music playlist format (http://en.wikipedia.org/wiki/M3U) +# Why: See https://github.com/bentomas/node-mime/pull/6 +# Added by: mjrusso +application/x-mpegURL m3u8 + +# What: Video format, Part of RFC1890 +# Why: See https://github.com/bentomas/node-mime/pull/6 +# Added by: mjrusso +video/MP2T ts diff --git a/node_modules/express/node_modules/connect/node_modules/qs/.gitignore b/node_modules/express/node_modules/connect/node_modules/qs/.gitignore new file mode 100644 index 0000000..3c3629e --- /dev/null +++ b/node_modules/express/node_modules/connect/node_modules/qs/.gitignore @@ -0,0 +1 @@ +node_modules diff --git a/node_modules/express/node_modules/connect/node_modules/qs/.gitmodules b/node_modules/express/node_modules/connect/node_modules/qs/.gitmodules new file mode 100644 index 0000000..49e31da --- /dev/null +++ b/node_modules/express/node_modules/connect/node_modules/qs/.gitmodules @@ -0,0 +1,6 @@ +[submodule "support/expresso"] + path = support/expresso + url = git://github.com/visionmedia/expresso.git +[submodule "support/should"] + path = support/should + url = git://github.com/visionmedia/should.js.git diff --git a/node_modules/express/node_modules/connect/node_modules/qs/History.md b/node_modules/express/node_modules/connect/node_modules/qs/History.md new file mode 100644 index 0000000..09b90be --- /dev/null +++ b/node_modules/express/node_modules/connect/node_modules/qs/History.md @@ -0,0 +1,63 @@ + +0.4.0 / 2011-11-21 +================== + + * Allow parsing of an existing object (for `bodyParser()`) [jackyz] + * Replaced expresso with mocha + +0.3.2 / 2011-11-08 +================== + + * Fixed global variable leak + +0.3.1 / 2011-08-17 +================== + + * Added `try/catch` around malformed uri components + * Add test coverage for Array native method bleed-though + +0.3.0 / 2011-07-19 +================== + + * Allow `array[index]` and `object[property]` syntaxes [Aria Stewart] + +0.2.0 / 2011-06-29 +================== + + * Added `qs.stringify()` [Cory Forsyth] + +0.1.0 / 2011-04-13 +================== + + * Added jQuery-ish array support + +0.0.7 / 2011-03-13 +================== + + * Fixed; handle empty string and `== null` in `qs.parse()` [dmit] + allows for convenient `qs.parse(url.parse(str).query)` + +0.0.6 / 2011-02-14 +================== + + * Fixed; support for implicit arrays + +0.0.4 / 2011-02-09 +================== + + * Fixed `+` as a space + +0.0.3 / 2011-02-08 +================== + + * Fixed case when right-hand value contains "]" + +0.0.2 / 2011-02-07 +================== + + * Fixed "=" presence in key + +0.0.1 / 2011-02-07 +================== + + * Initial release \ No newline at end of file diff --git a/node_modules/express/node_modules/connect/node_modules/qs/Makefile b/node_modules/express/node_modules/connect/node_modules/qs/Makefile new file mode 100644 index 0000000..e4df837 --- /dev/null +++ b/node_modules/express/node_modules/connect/node_modules/qs/Makefile @@ -0,0 +1,5 @@ + +test: + @./node_modules/.bin/mocha + +.PHONY: test \ No newline at end of file diff --git a/node_modules/express/node_modules/connect/node_modules/qs/Readme.md b/node_modules/express/node_modules/connect/node_modules/qs/Readme.md new file mode 100644 index 0000000..a3148ff --- /dev/null +++ b/node_modules/express/node_modules/connect/node_modules/qs/Readme.md @@ -0,0 +1,47 @@ +# node-querystring + + query string parser for node supporting nesting, as it was removed from `0.3.x`, so this library provides the previous and commonly desired behaviour (and twice as fast). Used by [express](http://expressjs.com), [connect](http://senchalabs.github.com/connect) and others. + +## Installation + + $ npm install qs + +## Examples + + require('qs').parse('user[name][first]=tj&user[email]=tj'); + // => { user: { name: { first: 'tj' }, email: 'tj' } } + +## Testing + +Install dev dependencies: + + $ npm install -d + +and execute: + + $ make test + +## License + +(The MIT License) + +Copyright (c) 2010 TJ Holowaychuk <tj@vision-media.ca> + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/node_modules/express/node_modules/connect/node_modules/qs/benchmark.js b/node_modules/express/node_modules/connect/node_modules/qs/benchmark.js new file mode 100644 index 0000000..97e2c93 --- /dev/null +++ b/node_modules/express/node_modules/connect/node_modules/qs/benchmark.js @@ -0,0 +1,17 @@ + +var qs = require('./'); + +var times = 100000 + , start = new Date + , n = times; + +console.log('times: %d', times); + +while (n--) qs.parse('foo=bar'); +console.log('simple: %dms', new Date - start); + +var start = new Date + , n = times; + +while (n--) qs.parse('user[name][first]=tj&user[name][last]=holowaychuk'); +console.log('nested: %dms', new Date - start); \ No newline at end of file diff --git a/node_modules/express/node_modules/connect/node_modules/qs/examples.js b/node_modules/express/node_modules/connect/node_modules/qs/examples.js new file mode 100644 index 0000000..9b652b0 --- /dev/null +++ b/node_modules/express/node_modules/connect/node_modules/qs/examples.js @@ -0,0 +1,48 @@ + +/** + * Module dependencies. + */ + +var qs = require('./'); + +var obj = qs.parse('foo'); +console.log(obj) + +var obj = qs.parse('foo=bar=baz'); +console.log(obj) + +var obj = qs.parse('users[]'); +console.log(obj) + +var obj = qs.parse('name=tj&email=tj@vision-media.ca'); +console.log(obj) + +var obj = qs.parse('users[]=tj&users[]=tobi&users[]=jane'); +console.log(obj) + +var obj = qs.parse('user[name][first]=tj&user[name][last]=holowaychuk'); +console.log(obj) + +var obj = qs.parse('users[][name][first]=tj&users[][name][last]=holowaychuk'); +console.log(obj) + +var obj = qs.parse('a=a&a=b&a=c'); +console.log(obj) + +var obj = qs.parse('user[tj]=tj&user[tj]=TJ'); +console.log(obj) + +var obj = qs.parse('user[names]=tj&user[names]=TJ&user[names]=Tyler'); +console.log(obj) + +var obj = qs.parse('user[name][first]=tj&user[name][first]=TJ'); +console.log(obj) + +var obj = qs.parse('user[0]=tj&user[1]=TJ'); +console.log(obj) + +var obj = qs.parse('user[0]=tj&user[]=TJ'); +console.log(obj) + +var obj = qs.parse('user[0]=tj&user[foo]=TJ'); +console.log(obj) diff --git a/node_modules/express/node_modules/connect/node_modules/qs/index.js b/node_modules/express/node_modules/connect/node_modules/qs/index.js new file mode 100644 index 0000000..d177d20 --- /dev/null +++ b/node_modules/express/node_modules/connect/node_modules/qs/index.js @@ -0,0 +1,2 @@ + +module.exports = require('./lib/querystring'); \ No newline at end of file diff --git a/node_modules/express/node_modules/connect/node_modules/qs/lib/querystring.js b/node_modules/express/node_modules/connect/node_modules/qs/lib/querystring.js new file mode 100644 index 0000000..36be1b0 --- /dev/null +++ b/node_modules/express/node_modules/connect/node_modules/qs/lib/querystring.js @@ -0,0 +1,262 @@ + +/*! + * querystring + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Library version. + */ + +exports.version = '0.4.0'; + +/** + * Object#toString() ref for stringify(). + */ + +var toString = Object.prototype.toString; + +/** + * Cache non-integer test regexp. + */ + +var notint = /[^0-9]/; + +function promote(parent, key) { + if (parent[key].length == 0) return parent[key] = {}; + var t = {}; + for (var i in parent[key]) t[i] = parent[key][i]; + parent[key] = t; + return t; +} + +function parse(parts, parent, key, val) { + var part = parts.shift(); + // end + if (!part) { + if (Array.isArray(parent[key])) { + parent[key].push(val); + } else if ('object' == typeof parent[key]) { + parent[key] = val; + } else if ('undefined' == typeof parent[key]) { + parent[key] = val; + } else { + parent[key] = [parent[key], val]; + } + // array + } else { + var obj = parent[key] = parent[key] || []; + if (']' == part) { + if (Array.isArray(obj)) { + if ('' != val) obj.push(val); + } else if ('object' == typeof obj) { + obj[Object.keys(obj).length] = val; + } else { + obj = parent[key] = [parent[key], val]; + } + // prop + } else if (~part.indexOf(']')) { + part = part.substr(0, part.length - 1); + if(notint.test(part) && Array.isArray(obj)) obj = promote(parent, key); + parse(parts, obj, part, val); + // key + } else { + if(notint.test(part) && Array.isArray(obj)) obj = promote(parent, key); + parse(parts, obj, part, val); + } + } +} + +/** + * Merge parent key/val pair. + */ + +function merge(parent, key, val){ + if (~key.indexOf(']')) { + var parts = key.split('[') + , len = parts.length + , last = len - 1; + parse(parts, parent, 'base', val); + // optimize + } else { + if (notint.test(key) && Array.isArray(parent.base)) { + var t = {}; + for (var k in parent.base) t[k] = parent.base[k]; + parent.base = t; + } + set(parent.base, key, val); + } + + return parent; +} + +/** + * Parse the given obj. + */ + +function parseObject(obj){ + var ret = { base: {} }; + Object.keys(obj).forEach(function(name){ + merge(ret, name, obj[name]); + }); + return ret.base; +} + +/** + * Parse the given str. + */ + +function parseString(str){ + return String(str) + .split('&') + .reduce(function(ret, pair){ + try{ + pair = decodeURIComponent(pair.replace(/\+/g, ' ')); + } catch(e) { + // ignore + } + + var eql = pair.indexOf('=') + , brace = lastBraceInKey(pair) + , key = pair.substr(0, brace || eql) + , val = pair.substr(brace || eql, pair.length) + , val = val.substr(val.indexOf('=') + 1, val.length); + + // ?foo + if ('' == key) key = pair, val = ''; + + return merge(ret, key, val); + }, { base: {} }).base; +} + +/** + * Parse the given query `str` or `obj`, returning an object. + * + * @param {String} str | {Object} obj + * @return {Object} + * @api public + */ + +exports.parse = function(str){ + if (null == str || '' == str) return {}; + return 'object' == typeof str + ? parseObject(str) + : parseString(str); +}; + +/** + * Turn the given `obj` into a query string + * + * @param {Object} obj + * @return {String} + * @api public + */ + +var stringify = exports.stringify = function(obj, prefix) { + if (Array.isArray(obj)) { + return stringifyArray(obj, prefix); + } else if ('[object Object]' == toString.call(obj)) { + return stringifyObject(obj, prefix); + } else if ('string' == typeof obj) { + return stringifyString(obj, prefix); + } else { + return prefix; + } +}; + +/** + * Stringify the given `str`. + * + * @param {String} str + * @param {String} prefix + * @return {String} + * @api private + */ + +function stringifyString(str, prefix) { + if (!prefix) throw new TypeError('stringify expects an object'); + return prefix + '=' + encodeURIComponent(str); +} + +/** + * Stringify the given `arr`. + * + * @param {Array} arr + * @param {String} prefix + * @return {String} + * @api private + */ + +function stringifyArray(arr, prefix) { + var ret = []; + if (!prefix) throw new TypeError('stringify expects an object'); + for (var i = 0; i < arr.length; i++) { + ret.push(stringify(arr[i], prefix + '[]')); + } + return ret.join('&'); +} + +/** + * Stringify the given `obj`. + * + * @param {Object} obj + * @param {String} prefix + * @return {String} + * @api private + */ + +function stringifyObject(obj, prefix) { + var ret = [] + , keys = Object.keys(obj) + , key; + for (var i = 0, len = keys.length; i < len; ++i) { + key = keys[i]; + ret.push(stringify(obj[key], prefix + ? prefix + '[' + encodeURIComponent(key) + ']' + : encodeURIComponent(key))); + } + return ret.join('&'); +} + +/** + * Set `obj`'s `key` to `val` respecting + * the weird and wonderful syntax of a qs, + * where "foo=bar&foo=baz" becomes an array. + * + * @param {Object} obj + * @param {String} key + * @param {String} val + * @api private + */ + +function set(obj, key, val) { + var v = obj[key]; + if (undefined === v) { + obj[key] = val; + } else if (Array.isArray(v)) { + v.push(val); + } else { + obj[key] = [v, val]; + } +} + +/** + * Locate last brace in `str` within the key. + * + * @param {String} str + * @return {Number} + * @api private + */ + +function lastBraceInKey(str) { + var len = str.length + , brace + , c; + for (var i = 0; i < len; ++i) { + c = str[i]; + if (']' == c) brace = false; + if ('[' == c) brace = true; + if ('=' == c && !brace) return i; + } +} diff --git a/node_modules/express/node_modules/connect/node_modules/qs/package.json b/node_modules/express/node_modules/connect/node_modules/qs/package.json new file mode 100644 index 0000000..e04d72b --- /dev/null +++ b/node_modules/express/node_modules/connect/node_modules/qs/package.json @@ -0,0 +1,16 @@ +{ + "name": "qs", + "description": "querystring parser", + "version": "0.4.0", + "repository": { + "type" : "git", + "url" : "git://github.com/visionmedia/node-querystring.git" + }, + "devDependencies": { + "mocha": "*" + , "should": "*" + }, + "author": "TJ Holowaychuk (http://tjholowaychuk.com)", + "main": "index", + "engines": { "node": "*" } +} \ No newline at end of file diff --git a/node_modules/express/node_modules/connect/node_modules/qs/test/mocha.opts b/node_modules/express/node_modules/connect/node_modules/qs/test/mocha.opts new file mode 100644 index 0000000..521cbb2 --- /dev/null +++ b/node_modules/express/node_modules/connect/node_modules/qs/test/mocha.opts @@ -0,0 +1,2 @@ +--require should +--ui exports diff --git a/node_modules/express/node_modules/connect/node_modules/qs/test/parse.js b/node_modules/express/node_modules/connect/node_modules/qs/test/parse.js new file mode 100644 index 0000000..2a28cf3 --- /dev/null +++ b/node_modules/express/node_modules/connect/node_modules/qs/test/parse.js @@ -0,0 +1,155 @@ + +/** + * Module dependencies. + */ + +var qs = require('../'); + +module.exports = { + 'test basics': function(){ + qs.parse('0=foo').should.eql({ '0': 'foo' }); + + qs.parse('foo=c++') + .should.eql({ foo: 'c ' }); + + qs.parse('a[>=]=23') + .should.eql({ a: { '>=': '23' }}); + + qs.parse('a[<=>]==23') + .should.eql({ a: { '<=>': '=23' }}); + + qs.parse('a[==]=23') + .should.eql({ a: { '==': '23' }}); + + qs.parse('foo') + .should.eql({ foo: '' }); + + qs.parse('foo=bar') + .should.eql({ foo: 'bar' }); + + qs.parse('foo%3Dbar=baz') + .should.eql({ foo: 'bar=baz' }); + + qs.parse(' foo = bar = baz ') + .should.eql({ ' foo ': ' bar = baz ' }); + + qs.parse('foo=bar=baz') + .should.eql({ foo: 'bar=baz' }); + + qs.parse('foo=bar&bar=baz') + .should.eql({ foo: 'bar', bar: 'baz' }); + + qs.parse('foo=bar&baz') + .should.eql({ foo: 'bar', baz: '' }); + + qs.parse('cht=p3&chd=t:60,40&chs=250x100&chl=Hello|World') + .should.eql({ + cht: 'p3' + , chd: 't:60,40' + , chs: '250x100' + , chl: 'Hello|World' + }); + }, + + 'test nesting': function(){ + qs.parse('ops[>=]=25') + .should.eql({ ops: { '>=': '25' }}); + + qs.parse('user[name]=tj') + .should.eql({ user: { name: 'tj' }}); + + qs.parse('user[name][first]=tj&user[name][last]=holowaychuk') + .should.eql({ user: { name: { first: 'tj', last: 'holowaychuk' }}}); + }, + + 'test escaping': function(){ + qs.parse('foo=foo%20bar') + .should.eql({ foo: 'foo bar' }); + }, + + 'test arrays': function(){ + qs.parse('images[]') + .should.eql({ images: [] }); + + qs.parse('user[]=tj') + .should.eql({ user: ['tj'] }); + + qs.parse('user[]=tj&user[]=tobi&user[]=jane') + .should.eql({ user: ['tj', 'tobi', 'jane'] }); + + qs.parse('user[names][]=tj&user[names][]=tyler') + .should.eql({ user: { names: ['tj', 'tyler'] }}); + + qs.parse('user[names][]=tj&user[names][]=tyler&user[email]=tj@vision-media.ca') + .should.eql({ user: { names: ['tj', 'tyler'], email: 'tj@vision-media.ca' }}); + + qs.parse('items=a&items=b') + .should.eql({ items: ['a', 'b'] }); + + qs.parse('user[names]=tj&user[names]=holowaychuk&user[names]=TJ') + .should.eql({ user: { names: ['tj', 'holowaychuk', 'TJ'] }}); + + qs.parse('user[name][first]=tj&user[name][first]=TJ') + .should.eql({ user: { name: { first: ['tj', 'TJ'] }}}); + }, + + 'test right-hand brackets': function(){ + qs.parse('pets=["tobi"]') + .should.eql({ pets: '["tobi"]' }); + + qs.parse('operators=[">=", "<="]') + .should.eql({ operators: '[">=", "<="]' }); + + qs.parse('op[>=]=[1,2,3]') + .should.eql({ op: { '>=': '[1,2,3]' }}); + + qs.parse('op[>=]=[1,2,3]&op[=]=[[[[1]]]]') + .should.eql({ op: { '>=': '[1,2,3]', '=': '[[[[1]]]]' }}); + }, + + 'test duplicates': function(){ + qs.parse('items=bar&items=baz&items=raz') + .should.eql({ items: ['bar', 'baz', 'raz'] }); + }, + + 'test empty': function(){ + qs.parse('').should.eql({}); + qs.parse(undefined).should.eql({}); + qs.parse(null).should.eql({}); + }, + + 'test arrays with indexes': function(){ + qs.parse('foo[0]=bar&foo[1]=baz').should.eql({ foo: ['bar', 'baz'] }); + qs.parse('foo[1]=bar&foo[0]=baz').should.eql({ foo: ['baz', 'bar'] }); + qs.parse('foo[base64]=RAWR').should.eql({ foo: { base64: 'RAWR' }}); + qs.parse('foo[64base]=RAWR').should.eql({ foo: { '64base': 'RAWR' }}); + }, + + 'test arrays becoming objects': function(){ + qs.parse('foo[0]=bar&foo[bad]=baz').should.eql({ foo: { 0: "bar", bad: "baz" }}); + qs.parse('foo[bad]=baz&foo[0]=bar').should.eql({ foo: { 0: "bar", bad: "baz" }}); + }, + + 'test bleed-through of Array native properties/methods': function(){ + Array.prototype.protoProperty = true; + Array.prototype.protoFunction = function () {}; + qs.parse('foo=bar').should.eql({ foo: 'bar' }); + }, + + 'test malformed uri': function(){ + qs.parse('{%:%}').should.eql({ '{%:%}': '' }); + qs.parse('foo=%:%}').should.eql({ 'foo': '%:%}' }); + } + + // 'test complex': function(){ + // qs.parse('users[][name][first]=tj&users[foo]=bar') + // .should.eql({ + // users: [ { name: 'tj' }, { name: 'tobi' }, { foo: 'bar' }] + // }); + // + // qs.parse('users[][name][first]=tj&users[][name][first]=tobi') + // .should.eql({ + // users: [ { name: 'tj' }, { name: 'tobi' }] + // }); + // } +}; diff --git a/node_modules/express/node_modules/connect/node_modules/qs/test/stringify.js b/node_modules/express/node_modules/connect/node_modules/qs/test/stringify.js new file mode 100644 index 0000000..5f688d8 --- /dev/null +++ b/node_modules/express/node_modules/connect/node_modules/qs/test/stringify.js @@ -0,0 +1,95 @@ + +/** + * Module dependencies. + */ + +var qs = require('../') + , should = require('should') + , query_string_identities = { + 'basics': [ + {query_string: 'foo=bar', parsed: {'foo' : 'bar'}}, + {query_string: 'foo=%22bar%22', parsed: {'foo' : '\"bar\"'}}, + {query_string: 'foo=', parsed: {'foo': ''}}, + {query_string: 'foo=1&bar=2', parsed: {'foo' : '1', 'bar' : '2'}}, + {query_string: 'my%20weird%20field=q1!2%22\'w%245%267%2Fz8)%3F', parsed: {'my weird field': "q1!2\"'w$5&7/z8)?"}}, + {query_string: 'foo%3Dbaz=bar', parsed: {'foo=baz': 'bar'}}, + {query_string: 'foo=bar&bar=baz', parsed: {foo: 'bar', bar: 'baz'}} + ], + 'escaping': [ + {query_string: 'foo=foo%20bar', parsed: {foo: 'foo bar'}}, + {query_string: 'cht=p3&chd=t%3A60%2C40&chs=250x100&chl=Hello%7CWorld', parsed: { + cht: 'p3' + , chd: 't:60,40' + , chs: '250x100' + , chl: 'Hello|World' + }} + ], + 'nested': [ + {query_string: 'foo[]=bar&foo[]=quux', parsed: {'foo' : ['bar', 'quux']}}, + {query_string: 'foo[]=bar', parsed: {foo: ['bar']}}, + {query_string: 'foo[]=1&foo[]=2', parsed: {'foo' : ['1', '2']}}, + {query_string: 'foo=bar&baz[]=1&baz[]=2&baz[]=3', parsed: {'foo' : 'bar', 'baz' : ['1', '2', '3']}}, + {query_string: 'foo[]=bar&baz[]=1&baz[]=2&baz[]=3', parsed: {'foo' : ['bar'], 'baz' : ['1', '2', '3']}}, + {query_string: 'x[y][z]=1', parsed: {'x' : {'y' : {'z' : '1'}}}}, + {query_string: 'x[y][z][]=1', parsed: {'x' : {'y' : {'z' : ['1']}}}}, + {query_string: 'x[y][z]=2', parsed: {'x' : {'y' : {'z' : '2'}}}}, + {query_string: 'x[y][z][]=1&x[y][z][]=2', parsed: {'x' : {'y' : {'z' : ['1', '2']}}}}, + {query_string: 'x[y][][z]=1', parsed: {'x' : {'y' : [{'z' : '1'}]}}}, + {query_string: 'x[y][][z][]=1', parsed: {'x' : {'y' : [{'z' : ['1']}]}}}, + {query_string: 'x[y][][z]=1&x[y][][w]=2', parsed: {'x' : {'y' : [{'z' : '1', 'w' : '2'}]}}}, + {query_string: 'x[y][][v][w]=1', parsed: {'x' : {'y' : [{'v' : {'w' : '1'}}]}}}, + {query_string: 'x[y][][z]=1&x[y][][v][w]=2', parsed: {'x' : {'y' : [{'z' : '1', 'v' : {'w' : '2'}}]}}}, + {query_string: 'x[y][][z]=1&x[y][][z]=2', parsed: {'x' : {'y' : [{'z' : '1'}, {'z' : '2'}]}}}, + {query_string: 'x[y][][z]=1&x[y][][w]=a&x[y][][z]=2&x[y][][w]=3', parsed: {'x' : {'y' : [{'z' : '1', 'w' : 'a'}, {'z' : '2', 'w' : '3'}]}}}, + {query_string: 'user[name][first]=tj&user[name][last]=holowaychuk', parsed: { user: { name: { first: 'tj', last: 'holowaychuk' }}}} + ], + 'errors': [ + { parsed: 'foo=bar', message: 'stringify expects an object' }, + { parsed: ['foo', 'bar'], message: 'stringify expects an object' } + ] + }; + + +// Assert error +function err(fn, msg){ + var err; + try { + fn(); + } catch (e) { + should.equal(e.message, msg); + return; + } + throw new Error('no exception thrown, expected "' + msg + '"'); +} + +function test(type) { + var str, obj; + for (var i = 0; i < query_string_identities[type].length; i++) { + str = query_string_identities[type][i].query_string; + obj = query_string_identities[type][i].parsed; + qs.stringify(obj).should.eql(str); + } +} + +module.exports = { + 'test basics': function() { + test('basics'); + }, + + 'test escaping': function() { + test('escaping'); + }, + + 'test nested': function() { + test('nested'); + }, + + 'test errors': function() { + var parsed, message; + for (var i = 0; i < query_string_identities['errors'].length; i++) { + message = query_string_identities['errors'][i].message; + parsed = query_string_identities['errors'][i].parsed; + err(function(){ qs.stringify(parsed) }, message); + } + } +}; \ No newline at end of file diff --git a/node_modules/express/node_modules/connect/package.json b/node_modules/express/node_modules/connect/package.json new file mode 100644 index 0000000..667fea0 --- /dev/null +++ b/node_modules/express/node_modules/connect/package.json @@ -0,0 +1,25 @@ +{ + "name": "connect", + "version": "1.8.1", + "description": "High performance middleware framework", + "keywords": ["framework", "web", "middleware", "connect", "rack"], + "repository": "git://github.com/senchalabs/connect.git", + "author": "TJ Holowaychuk (http://tjholowaychuk.com)", + "repository": "git://github.com/senchalabs/connect", + "dependencies": { + "qs": ">= 0.3.1", + "mime": ">= 0.0.1", + "formidable": "1.0.x" + }, + "devDependencies": { + "expresso": "0.9.2", + "koala": "0.1.2", + "less": "1.1.1", + "sass": "0.5.0", + "markdown": "0.2.1", + "ejs": "0.4.3", + "should": "0.3.2" + }, + "main": "index", + "engines": { "node": ">= 0.4.1 < 0.7.0" } +} \ No newline at end of file diff --git a/node_modules/express/node_modules/connect/test.js b/node_modules/express/node_modules/connect/test.js new file mode 100644 index 0000000..d7ace4d --- /dev/null +++ b/node_modules/express/node_modules/connect/test.js @@ -0,0 +1,11 @@ + +/** + * Module dependencies. + */ + +var connect = require('./') + , utils = connect.utils + , http = require('http') + , url = require('url') + , path = require('path') + , fs = require('fs'); diff --git a/node_modules/express/node_modules/mime/LICENSE b/node_modules/express/node_modules/mime/LICENSE new file mode 100644 index 0000000..451fc45 --- /dev/null +++ b/node_modules/express/node_modules/mime/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2010 Benjamin Thomas, Robert Kieffer + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/node_modules/express/node_modules/mime/README.md b/node_modules/express/node_modules/mime/README.md new file mode 100644 index 0000000..a157de1 --- /dev/null +++ b/node_modules/express/node_modules/mime/README.md @@ -0,0 +1,50 @@ +# mime + +Support for mapping between file extensions and MIME types. This module uses the latest version of the Apache "mime.types" file (maps over 620 types to 800+ extensions). It is also trivially easy to add your own types and extensions, should you need to do that. + +## Install + +Install with [npm](http://github.com/isaacs/npm): + + npm install mime + +## API - Queries + +### mime.lookup(path) +Get the mime type associated with a file. This is method is case-insensitive. Everything in path up to and including the last '/' or '.' is ignored, so you can pass it paths, filenames, or extensions, like so: + + var mime = require('mime'); + + mime.lookup('/path/to/file.txt'); // => 'text/plain' + mime.lookup('file.txt'); // => 'text/plain' + mime.lookup('.txt'); // => 'text/plain' + mime.lookup('htm'); // => 'text/html' + +### mime.extension(type) - lookup the default extension for type + + mime.extension('text/html'); // => 'html' + mime.extension('application/octet-stream'); // => 'bin' + +### mime.charsets.lookup() - map mime-type to charset + + mime.charsets.lookup('text/plain'); // => 'UTF-8' + +(The logic for charset lookups is pretty rudimentary. Feel free to suggest improvements.) + +## API - Customizing + +The following APIs allow you to add your own type mappings within your project. If you feel a type should be included as part of node-mime, see [requesting new types](https://github.com/bentomas/node-mime/wiki/Requesting-New-Types). +### mime.define() - Add custom mime/extension mappings + + mime.define({ + 'text/x-some-format': ['x-sf', 'x-sft', 'x-sfml'], + 'application/x-my-type': ['x-mt', 'x-mtt'], + // etc ... + }); + + mime.lookup('x-sft'); // => 'text/x-some-format' + mime.extension('text/x-some-format'); // => 'x-sf' + +### mime.load(filepath) - Load mappings from an Apache ".types" format file + + mime.load('./my_project.types'); diff --git a/node_modules/express/node_modules/mime/mime.js b/node_modules/express/node_modules/mime/mime.js new file mode 100644 index 0000000..5fac753 --- /dev/null +++ b/node_modules/express/node_modules/mime/mime.js @@ -0,0 +1,92 @@ +var path = require('path'), + fs = require('fs'); + +var mime = module.exports = { + /** Map of extension to mime type */ + types: {}, + + /** Map of mime type to extension */ + extensions :{}, + + /** + * Define mimetype -> extension mappings. Each key is a mime-type that maps + * to an array of extensions associated with the type. The first extension is + * used as the default extension for the type. + * + * e.g. mime.define({'audio/ogg', ['oga', 'ogg', 'spx']}); + * + * @param map (Object) type definitions + */ + define: function(map) { + for (var type in map) { + var exts = map[type]; + + for (var i = 0; i < exts.length; i++) { + mime.types[exts[i]] = type; + } + + // Default extension is the first one we encounter + if (!mime.extensions[type]) { + mime.extensions[type] = exts[0]; + } + } + }, + + /** + * Load an Apache2-style ".types" file + * + * This may be called multiple times (it's expected). Where files declare + * overlapping types/extensions, the last file wins. + * + * @param file (String) path of file to load. + */ + load: function(file) { + // Read file and split into lines + var map = {}, + content = fs.readFileSync(file, 'ascii'), + lines = content.split(/[\r\n]+/); + + lines.forEach(function(line, lineno) { + // Clean up whitespace/comments, and split into fields + var fields = line.replace(/\s*#.*|^\s*|\s*$/g, '').split(/\s+/); + map[fields.shift()] = fields; + }); + + mime.define(map); + }, + + /** + * Lookup a mime type based on extension + */ + lookup: function(path, fallback) { + var ext = path.replace(/.*[\.\/]/, '').toLowerCase(); + return mime.types[ext] || fallback || mime.default_type; + }, + + /** + * Return file extension associated with a mime type + */ + extension: function(mimeType) { + return mime.extensions[mimeType]; + }, + + /** + * Lookup a charset based on mime type. + */ + charsets: { + lookup: function (mimeType, fallback) { + // Assume text types are utf8. Modify mime logic as needed. + return (/^text\//).test(mimeType) ? 'UTF-8' : fallback; + } + } +}; + +// Load our local copy of +// http://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types +mime.load(path.join(__dirname, 'types/mime.types')); + +// Overlay enhancements submitted by the node.js community +mime.load(path.join(__dirname, 'types/node.types')); + +// Set the default type +mime.default_type = mime.types.bin; diff --git a/node_modules/express/node_modules/mime/package.json b/node_modules/express/node_modules/mime/package.json new file mode 100644 index 0000000..85277b0 --- /dev/null +++ b/node_modules/express/node_modules/mime/package.json @@ -0,0 +1,22 @@ +{ + "author": { + "name": "Robert Kieffer", + "url": "http://github.com/broofa", + "email": "robert@broofa.com" + }, + "contributors": [ + { + "name": "Benjamin Thomas", + "url": "http://github.com/bentomas", + "email": "benjamin@benjaminthomas.org" + } + ], + "dependencies": {}, + "description": "A comprehensive library for mime-type mapping", + "devDependencies": {"async_testing": ""}, + "keywords": ["util", "mime"], + "main": "mime.js", + "name": "mime", + "repository": {"url": "http://github.com/bentomas/node-mime", "type": "git"}, + "version": "1.2.4" +} diff --git a/node_modules/express/node_modules/mime/test.js b/node_modules/express/node_modules/mime/test.js new file mode 100644 index 0000000..b904895 --- /dev/null +++ b/node_modules/express/node_modules/mime/test.js @@ -0,0 +1,79 @@ +/** + * Requires the async_testing module + * + * Usage: node test.js + */ +var mime = require('./mime'); +exports["test mime lookup"] = function(test) { + // easy + test.equal('text/plain', mime.lookup('text.txt')); + + // hidden file or multiple periods + test.equal('text/plain', mime.lookup('.text.txt')); + + // just an extension + test.equal('text/plain', mime.lookup('.txt')); + + // just an extension without a dot + test.equal('text/plain', mime.lookup('txt')); + + // default + test.equal('application/octet-stream', mime.lookup('text.nope')); + + // fallback + test.equal('fallback', mime.lookup('text.fallback', 'fallback')); + + test.finish(); +}; + +exports["test extension lookup"] = function(test) { + // easy + test.equal('txt', mime.extension(mime.types.text)); + test.equal('html', mime.extension(mime.types.htm)); + test.equal('bin', mime.extension('application/octet-stream')); + + test.finish(); +}; + +exports["test mime lookup uppercase"] = function(test) { + // easy + test.equal('text/plain', mime.lookup('TEXT.TXT')); + + // just an extension + test.equal('text/plain', mime.lookup('.TXT')); + + // just an extension without a dot + test.equal('text/plain', mime.lookup('TXT')); + + // default + test.equal('application/octet-stream', mime.lookup('TEXT.NOPE')); + + // fallback + test.equal('fallback', mime.lookup('TEXT.FALLBACK', 'fallback')); + + test.finish(); +}; + +exports["test custom types"] = function(test) { + test.equal('application/octet-stream', mime.lookup('file.buffer')); + test.equal('audio/mp4', mime.lookup('file.m4a')); + + test.finish(); +}; + +exports["test charset lookup"] = function(test) { + // easy + test.equal('UTF-8', mime.charsets.lookup('text/plain')); + + // none + test.ok(typeof mime.charsets.lookup(mime.types.js) == 'undefined'); + + // fallback + test.equal('fallback', mime.charsets.lookup('application/octet-stream', 'fallback')); + + test.finish(); +}; + +if (module == require.main) { + require('async_testing').run(__filename, process.ARGV); +} diff --git a/node_modules/express/node_modules/mime/types/mime.types b/node_modules/express/node_modules/mime/types/mime.types new file mode 100644 index 0000000..6a90929 --- /dev/null +++ b/node_modules/express/node_modules/mime/types/mime.types @@ -0,0 +1,1479 @@ +# This file maps Internet media types to unique file extension(s). +# Although created for httpd, this file is used by many software systems +# and has been placed in the public domain for unlimited redisribution. +# +# The table below contains both registered and (common) unregistered types. +# A type that has no unique extension can be ignored -- they are listed +# here to guide configurations toward known types and to make it easier to +# identify "new" types. File extensions are also commonly used to indicate +# content languages and encodings, so choose them carefully. +# +# Internet media types should be registered as described in RFC 4288. +# The registry is at . +# +# MIME type (lowercased) Extensions +# ============================================ ========== +# application/1d-interleaved-parityfec +# application/3gpp-ims+xml +# application/activemessage +application/andrew-inset ez +# application/applefile +application/applixware aw +application/atom+xml atom +application/atomcat+xml atomcat +# application/atomicmail +application/atomsvc+xml atomsvc +# application/auth-policy+xml +# application/batch-smtp +# application/beep+xml +# application/cals-1840 +application/ccxml+xml ccxml +application/cdmi-capability cdmia +application/cdmi-container cdmic +application/cdmi-domain cdmid +application/cdmi-object cdmio +application/cdmi-queue cdmiq +# application/cea-2018+xml +# application/cellml+xml +# application/cfw +# application/cnrp+xml +# application/commonground +# application/conference-info+xml +# application/cpl+xml +# application/csta+xml +# application/cstadata+xml +application/cu-seeme cu +# application/cybercash +application/davmount+xml davmount +# application/dca-rft +# application/dec-dx +# application/dialog-info+xml +# application/dicom +# application/dns +# application/dskpp+xml +application/dssc+der dssc +application/dssc+xml xdssc +# application/dvcs +application/ecmascript ecma +# application/edi-consent +# application/edi-x12 +# application/edifact +application/emma+xml emma +# application/epp+xml +application/epub+zip epub +# application/eshop +# application/example +application/exi exi +# application/fastinfoset +# application/fastsoap +# application/fits +application/font-tdpfr pfr +# application/framework-attributes+xml +# application/h224 +# application/held+xml +# application/http +application/hyperstudio stk +# application/ibe-key-request+xml +# application/ibe-pkg-reply+xml +# application/ibe-pp-data +# application/iges +# application/im-iscomposing+xml +# application/index +# application/index.cmd +# application/index.obj +# application/index.response +# application/index.vnd +# application/iotp +application/ipfix ipfix +# application/ipp +# application/isup +application/java-archive jar +application/java-serialized-object ser +application/java-vm class +application/javascript js +application/json json +# application/kpml-request+xml +# application/kpml-response+xml +application/lost+xml lostxml +application/mac-binhex40 hqx +application/mac-compactpro cpt +# application/macwriteii +application/mads+xml mads +application/marc mrc +application/marcxml+xml mrcx +application/mathematica ma nb mb +# application/mathml-content+xml +# application/mathml-presentation+xml +application/mathml+xml mathml +# application/mbms-associated-procedure-description+xml +# application/mbms-deregister+xml +# application/mbms-envelope+xml +# application/mbms-msk+xml +# application/mbms-msk-response+xml +# application/mbms-protection-description+xml +# application/mbms-reception-report+xml +# application/mbms-register+xml +# application/mbms-register-response+xml +# application/mbms-user-service-description+xml +application/mbox mbox +# application/media_control+xml +application/mediaservercontrol+xml mscml +application/metalink4+xml meta4 +application/mets+xml mets +# application/mikey +application/mods+xml mods +# application/moss-keys +# application/moss-signature +# application/mosskey-data +# application/mosskey-request +application/mp21 m21 mp21 +application/mp4 mp4s +# application/mpeg4-generic +# application/mpeg4-iod +# application/mpeg4-iod-xmt +# application/msc-ivr+xml +# application/msc-mixer+xml +application/msword doc dot +application/mxf mxf +# application/nasdata +# application/news-checkgroups +# application/news-groupinfo +# application/news-transmission +# application/nss +# application/ocsp-request +# application/ocsp-response +application/octet-stream bin dms lha lrf lzh so iso dmg dist distz pkg bpk dump elc deploy +application/oda oda +application/oebps-package+xml opf +application/ogg ogx +application/onenote onetoc onetoc2 onetmp onepkg +# application/parityfec +application/patch-ops-error+xml xer +application/pdf pdf +application/pgp-encrypted pgp +# application/pgp-keys +application/pgp-signature asc sig +application/pics-rules prf +# application/pidf+xml +# application/pidf-diff+xml +application/pkcs10 p10 +application/pkcs7-mime p7m p7c +application/pkcs7-signature p7s +application/pkcs8 p8 +application/pkix-attr-cert ac +application/pkix-cert cer +application/pkix-crl crl +application/pkix-pkipath pkipath +application/pkixcmp pki +application/pls+xml pls +# application/poc-settings+xml +application/postscript ai eps ps +# application/prs.alvestrand.titrax-sheet +application/prs.cww cww +# application/prs.nprend +# application/prs.plucker +# application/prs.rdf-xml-crypt +# application/prs.xsf+xml +application/pskc+xml pskcxml +# application/qsig +application/rdf+xml rdf +application/reginfo+xml rif +application/relax-ng-compact-syntax rnc +# application/remote-printing +application/resource-lists+xml rl +application/resource-lists-diff+xml rld +# application/riscos +# application/rlmi+xml +application/rls-services+xml rs +application/rsd+xml rsd +application/rss+xml rss +application/rtf rtf +# application/rtx +# application/samlassertion+xml +# application/samlmetadata+xml +application/sbml+xml sbml +application/scvp-cv-request scq +application/scvp-cv-response scs +application/scvp-vp-request spq +application/scvp-vp-response spp +application/sdp sdp +# application/set-payment +application/set-payment-initiation setpay +# application/set-registration +application/set-registration-initiation setreg +# application/sgml +# application/sgml-open-catalog +application/shf+xml shf +# application/sieve +# application/simple-filter+xml +# application/simple-message-summary +# application/simplesymbolcontainer +# application/slate +# application/smil +application/smil+xml smi smil +# application/soap+fastinfoset +# application/soap+xml +application/sparql-query rq +application/sparql-results+xml srx +# application/spirits-event+xml +application/srgs gram +application/srgs+xml grxml +application/sru+xml sru +application/ssml+xml ssml +# application/tamp-apex-update +# application/tamp-apex-update-confirm +# application/tamp-community-update +# application/tamp-community-update-confirm +# application/tamp-error +# application/tamp-sequence-adjust +# application/tamp-sequence-adjust-confirm +# application/tamp-status-query +# application/tamp-status-response +# application/tamp-update +# application/tamp-update-confirm +application/tei+xml tei teicorpus +application/thraud+xml tfi +# application/timestamp-query +# application/timestamp-reply +application/timestamped-data tsd +# application/tve-trigger +# application/ulpfec +# application/vemmi +# application/vividence.scriptfile +# application/vnd.3gpp.bsf+xml +application/vnd.3gpp.pic-bw-large plb +application/vnd.3gpp.pic-bw-small psb +application/vnd.3gpp.pic-bw-var pvb +# application/vnd.3gpp.sms +# application/vnd.3gpp2.bcmcsinfo+xml +# application/vnd.3gpp2.sms +application/vnd.3gpp2.tcap tcap +application/vnd.3m.post-it-notes pwn +application/vnd.accpac.simply.aso aso +application/vnd.accpac.simply.imp imp +application/vnd.acucobol acu +application/vnd.acucorp atc acutc +application/vnd.adobe.air-application-installer-package+zip air +application/vnd.adobe.fxp fxp fxpl +# application/vnd.adobe.partial-upload +application/vnd.adobe.xdp+xml xdp +application/vnd.adobe.xfdf xfdf +# application/vnd.aether.imp +# application/vnd.ah-barcode +application/vnd.ahead.space ahead +application/vnd.airzip.filesecure.azf azf +application/vnd.airzip.filesecure.azs azs +application/vnd.amazon.ebook azw +application/vnd.americandynamics.acc acc +application/vnd.amiga.ami ami +# application/vnd.amundsen.maze+xml +application/vnd.android.package-archive apk +application/vnd.anser-web-certificate-issue-initiation cii +application/vnd.anser-web-funds-transfer-initiation fti +application/vnd.antix.game-component atx +application/vnd.apple.installer+xml mpkg +application/vnd.apple.mpegurl m3u8 +# application/vnd.arastra.swi +application/vnd.aristanetworks.swi swi +application/vnd.audiograph aep +# application/vnd.autopackage +# application/vnd.avistar+xml +application/vnd.blueice.multipass mpm +# application/vnd.bluetooth.ep.oob +application/vnd.bmi bmi +application/vnd.businessobjects rep +# application/vnd.cab-jscript +# application/vnd.canon-cpdl +# application/vnd.canon-lips +# application/vnd.cendio.thinlinc.clientconf +application/vnd.chemdraw+xml cdxml +application/vnd.chipnuts.karaoke-mmd mmd +application/vnd.cinderella cdy +# application/vnd.cirpack.isdn-ext +application/vnd.claymore cla +application/vnd.cloanto.rp9 rp9 +application/vnd.clonk.c4group c4g c4d c4f c4p c4u +application/vnd.cluetrust.cartomobile-config c11amc +application/vnd.cluetrust.cartomobile-config-pkg c11amz +# application/vnd.commerce-battelle +application/vnd.commonspace csp +application/vnd.contact.cmsg cdbcmsg +application/vnd.cosmocaller cmc +application/vnd.crick.clicker clkx +application/vnd.crick.clicker.keyboard clkk +application/vnd.crick.clicker.palette clkp +application/vnd.crick.clicker.template clkt +application/vnd.crick.clicker.wordbank clkw +application/vnd.criticaltools.wbs+xml wbs +application/vnd.ctc-posml pml +# application/vnd.ctct.ws+xml +# application/vnd.cups-pdf +# application/vnd.cups-postscript +application/vnd.cups-ppd ppd +# application/vnd.cups-raster +# application/vnd.cups-raw +application/vnd.curl.car car +application/vnd.curl.pcurl pcurl +# application/vnd.cybank +application/vnd.data-vision.rdz rdz +application/vnd.dece.data uvf uvvf uvd uvvd +application/vnd.dece.ttml+xml uvt uvvt +application/vnd.dece.unspecified uvx uvvx +application/vnd.denovo.fcselayout-link fe_launch +# application/vnd.dir-bi.plate-dl-nosuffix +application/vnd.dna dna +application/vnd.dolby.mlp mlp +# application/vnd.dolby.mobile.1 +# application/vnd.dolby.mobile.2 +application/vnd.dpgraph dpg +application/vnd.dreamfactory dfac +application/vnd.dvb.ait ait +# application/vnd.dvb.dvbj +# application/vnd.dvb.esgcontainer +# application/vnd.dvb.ipdcdftnotifaccess +# application/vnd.dvb.ipdcesgaccess +# application/vnd.dvb.ipdcesgaccess2 +# application/vnd.dvb.ipdcesgpdd +# application/vnd.dvb.ipdcroaming +# application/vnd.dvb.iptv.alfec-base +# application/vnd.dvb.iptv.alfec-enhancement +# application/vnd.dvb.notif-aggregate-root+xml +# application/vnd.dvb.notif-container+xml +# application/vnd.dvb.notif-generic+xml +# application/vnd.dvb.notif-ia-msglist+xml +# application/vnd.dvb.notif-ia-registration-request+xml +# application/vnd.dvb.notif-ia-registration-response+xml +# application/vnd.dvb.notif-init+xml +# application/vnd.dvb.pfr +application/vnd.dvb.service svc +# application/vnd.dxr +application/vnd.dynageo geo +# application/vnd.easykaraoke.cdgdownload +# application/vnd.ecdis-update +application/vnd.ecowin.chart mag +# application/vnd.ecowin.filerequest +# application/vnd.ecowin.fileupdate +# application/vnd.ecowin.series +# application/vnd.ecowin.seriesrequest +# application/vnd.ecowin.seriesupdate +# application/vnd.emclient.accessrequest+xml +application/vnd.enliven nml +application/vnd.epson.esf esf +application/vnd.epson.msf msf +application/vnd.epson.quickanime qam +application/vnd.epson.salt slt +application/vnd.epson.ssf ssf +# application/vnd.ericsson.quickcall +application/vnd.eszigno3+xml es3 et3 +# application/vnd.etsi.aoc+xml +# application/vnd.etsi.cug+xml +# application/vnd.etsi.iptvcommand+xml +# application/vnd.etsi.iptvdiscovery+xml +# application/vnd.etsi.iptvprofile+xml +# application/vnd.etsi.iptvsad-bc+xml +# application/vnd.etsi.iptvsad-cod+xml +# application/vnd.etsi.iptvsad-npvr+xml +# application/vnd.etsi.iptvservice+xml +# application/vnd.etsi.iptvsync+xml +# application/vnd.etsi.iptvueprofile+xml +# application/vnd.etsi.mcid+xml +# application/vnd.etsi.overload-control-policy-dataset+xml +# application/vnd.etsi.sci+xml +# application/vnd.etsi.simservs+xml +# application/vnd.etsi.tsl+xml +# application/vnd.etsi.tsl.der +# application/vnd.eudora.data +application/vnd.ezpix-album ez2 +application/vnd.ezpix-package ez3 +# application/vnd.f-secure.mobile +application/vnd.fdf fdf +application/vnd.fdsn.mseed mseed +application/vnd.fdsn.seed seed dataless +# application/vnd.ffsns +# application/vnd.fints +application/vnd.flographit gph +application/vnd.fluxtime.clip ftc +# application/vnd.font-fontforge-sfd +application/vnd.framemaker fm frame maker book +application/vnd.frogans.fnc fnc +application/vnd.frogans.ltf ltf +application/vnd.fsc.weblaunch fsc +application/vnd.fujitsu.oasys oas +application/vnd.fujitsu.oasys2 oa2 +application/vnd.fujitsu.oasys3 oa3 +application/vnd.fujitsu.oasysgp fg5 +application/vnd.fujitsu.oasysprs bh2 +# application/vnd.fujixerox.art-ex +# application/vnd.fujixerox.art4 +# application/vnd.fujixerox.hbpl +application/vnd.fujixerox.ddd ddd +application/vnd.fujixerox.docuworks xdw +application/vnd.fujixerox.docuworks.binder xbd +# application/vnd.fut-misnet +application/vnd.fuzzysheet fzs +application/vnd.genomatix.tuxedo txd +# application/vnd.geocube+xml +application/vnd.geogebra.file ggb +application/vnd.geogebra.tool ggt +application/vnd.geometry-explorer gex gre +application/vnd.geonext gxt +application/vnd.geoplan g2w +application/vnd.geospace g3w +# application/vnd.globalplatform.card-content-mgt +# application/vnd.globalplatform.card-content-mgt-response +application/vnd.gmx gmx +application/vnd.google-earth.kml+xml kml +application/vnd.google-earth.kmz kmz +application/vnd.grafeq gqf gqs +# application/vnd.gridmp +application/vnd.groove-account gac +application/vnd.groove-help ghf +application/vnd.groove-identity-message gim +application/vnd.groove-injector grv +application/vnd.groove-tool-message gtm +application/vnd.groove-tool-template tpl +application/vnd.groove-vcard vcg +application/vnd.hal+xml hal +application/vnd.handheld-entertainment+xml zmm +application/vnd.hbci hbci +# application/vnd.hcl-bireports +application/vnd.hhe.lesson-player les +application/vnd.hp-hpgl hpgl +application/vnd.hp-hpid hpid +application/vnd.hp-hps hps +application/vnd.hp-jlyt jlt +application/vnd.hp-pcl pcl +application/vnd.hp-pclxl pclxl +# application/vnd.httphone +application/vnd.hydrostatix.sof-data sfd-hdstx +application/vnd.hzn-3d-crossword x3d +# application/vnd.ibm.afplinedata +# application/vnd.ibm.electronic-media +application/vnd.ibm.minipay mpy +application/vnd.ibm.modcap afp listafp list3820 +application/vnd.ibm.rights-management irm +application/vnd.ibm.secure-container sc +application/vnd.iccprofile icc icm +application/vnd.igloader igl +application/vnd.immervision-ivp ivp +application/vnd.immervision-ivu ivu +# application/vnd.informedcontrol.rms+xml +# application/vnd.informix-visionary +# application/vnd.infotech.project +# application/vnd.infotech.project+xml +application/vnd.insors.igm igm +application/vnd.intercon.formnet xpw xpx +application/vnd.intergeo i2g +# application/vnd.intertrust.digibox +# application/vnd.intertrust.nncp +application/vnd.intu.qbo qbo +application/vnd.intu.qfx qfx +# application/vnd.iptc.g2.conceptitem+xml +# application/vnd.iptc.g2.knowledgeitem+xml +# application/vnd.iptc.g2.newsitem+xml +# application/vnd.iptc.g2.packageitem+xml +application/vnd.ipunplugged.rcprofile rcprofile +application/vnd.irepository.package+xml irp +application/vnd.is-xpr xpr +application/vnd.isac.fcs fcs +application/vnd.jam jam +# application/vnd.japannet-directory-service +# application/vnd.japannet-jpnstore-wakeup +# application/vnd.japannet-payment-wakeup +# application/vnd.japannet-registration +# application/vnd.japannet-registration-wakeup +# application/vnd.japannet-setstore-wakeup +# application/vnd.japannet-verification +# application/vnd.japannet-verification-wakeup +application/vnd.jcp.javame.midlet-rms rms +application/vnd.jisp jisp +application/vnd.joost.joda-archive joda +application/vnd.kahootz ktz ktr +application/vnd.kde.karbon karbon +application/vnd.kde.kchart chrt +application/vnd.kde.kformula kfo +application/vnd.kde.kivio flw +application/vnd.kde.kontour kon +application/vnd.kde.kpresenter kpr kpt +application/vnd.kde.kspread ksp +application/vnd.kde.kword kwd kwt +application/vnd.kenameaapp htke +application/vnd.kidspiration kia +application/vnd.kinar kne knp +application/vnd.koan skp skd skt skm +application/vnd.kodak-descriptor sse +application/vnd.las.las+xml lasxml +# application/vnd.liberty-request+xml +application/vnd.llamagraphics.life-balance.desktop lbd +application/vnd.llamagraphics.life-balance.exchange+xml lbe +application/vnd.lotus-1-2-3 123 +application/vnd.lotus-approach apr +application/vnd.lotus-freelance pre +application/vnd.lotus-notes nsf +application/vnd.lotus-organizer org +application/vnd.lotus-screencam scm +application/vnd.lotus-wordpro lwp +application/vnd.macports.portpkg portpkg +# application/vnd.marlin.drm.actiontoken+xml +# application/vnd.marlin.drm.conftoken+xml +# application/vnd.marlin.drm.license+xml +# application/vnd.marlin.drm.mdcf +application/vnd.mcd mcd +application/vnd.medcalcdata mc1 +application/vnd.mediastation.cdkey cdkey +# application/vnd.meridian-slingshot +application/vnd.mfer mwf +application/vnd.mfmp mfm +application/vnd.micrografx.flo flo +application/vnd.micrografx.igx igx +application/vnd.mif mif +# application/vnd.minisoft-hp3000-save +# application/vnd.mitsubishi.misty-guard.trustweb +application/vnd.mobius.daf daf +application/vnd.mobius.dis dis +application/vnd.mobius.mbk mbk +application/vnd.mobius.mqy mqy +application/vnd.mobius.msl msl +application/vnd.mobius.plc plc +application/vnd.mobius.txf txf +application/vnd.mophun.application mpn +application/vnd.mophun.certificate mpc +# application/vnd.motorola.flexsuite +# application/vnd.motorola.flexsuite.adsi +# application/vnd.motorola.flexsuite.fis +# application/vnd.motorola.flexsuite.gotap +# application/vnd.motorola.flexsuite.kmr +# application/vnd.motorola.flexsuite.ttc +# application/vnd.motorola.flexsuite.wem +# application/vnd.motorola.iprm +application/vnd.mozilla.xul+xml xul +application/vnd.ms-artgalry cil +# application/vnd.ms-asf +application/vnd.ms-cab-compressed cab +application/vnd.ms-excel xls xlm xla xlc xlt xlw +application/vnd.ms-excel.addin.macroenabled.12 xlam +application/vnd.ms-excel.sheet.binary.macroenabled.12 xlsb +application/vnd.ms-excel.sheet.macroenabled.12 xlsm +application/vnd.ms-excel.template.macroenabled.12 xltm +application/vnd.ms-fontobject eot +application/vnd.ms-htmlhelp chm +application/vnd.ms-ims ims +application/vnd.ms-lrm lrm +# application/vnd.ms-office.activex+xml +application/vnd.ms-officetheme thmx +application/vnd.ms-pki.seccat cat +application/vnd.ms-pki.stl stl +# application/vnd.ms-playready.initiator+xml +application/vnd.ms-powerpoint ppt pps pot +application/vnd.ms-powerpoint.addin.macroenabled.12 ppam +application/vnd.ms-powerpoint.presentation.macroenabled.12 pptm +application/vnd.ms-powerpoint.slide.macroenabled.12 sldm +application/vnd.ms-powerpoint.slideshow.macroenabled.12 ppsm +application/vnd.ms-powerpoint.template.macroenabled.12 potm +application/vnd.ms-project mpp mpt +# application/vnd.ms-tnef +# application/vnd.ms-wmdrm.lic-chlg-req +# application/vnd.ms-wmdrm.lic-resp +# application/vnd.ms-wmdrm.meter-chlg-req +# application/vnd.ms-wmdrm.meter-resp +application/vnd.ms-word.document.macroenabled.12 docm +application/vnd.ms-word.template.macroenabled.12 dotm +application/vnd.ms-works wps wks wcm wdb +application/vnd.ms-wpl wpl +application/vnd.ms-xpsdocument xps +application/vnd.mseq mseq +# application/vnd.msign +# application/vnd.multiad.creator +# application/vnd.multiad.creator.cif +# application/vnd.music-niff +application/vnd.musician mus +application/vnd.muvee.style msty +# application/vnd.ncd.control +# application/vnd.ncd.reference +# application/vnd.nervana +# application/vnd.netfpx +application/vnd.neurolanguage.nlu nlu +application/vnd.noblenet-directory nnd +application/vnd.noblenet-sealer nns +application/vnd.noblenet-web nnw +# application/vnd.nokia.catalogs +# application/vnd.nokia.conml+wbxml +# application/vnd.nokia.conml+xml +# application/vnd.nokia.isds-radio-presets +# application/vnd.nokia.iptv.config+xml +# application/vnd.nokia.landmark+wbxml +# application/vnd.nokia.landmark+xml +# application/vnd.nokia.landmarkcollection+xml +# application/vnd.nokia.n-gage.ac+xml +application/vnd.nokia.n-gage.data ngdat +application/vnd.nokia.n-gage.symbian.install n-gage +# application/vnd.nokia.ncd +# application/vnd.nokia.pcd+wbxml +# application/vnd.nokia.pcd+xml +application/vnd.nokia.radio-preset rpst +application/vnd.nokia.radio-presets rpss +application/vnd.novadigm.edm edm +application/vnd.novadigm.edx edx +application/vnd.novadigm.ext ext +# application/vnd.ntt-local.file-transfer +# application/vnd.ntt-local.sip-ta_remote +# application/vnd.ntt-local.sip-ta_tcp_stream +application/vnd.oasis.opendocument.chart odc +application/vnd.oasis.opendocument.chart-template otc +application/vnd.oasis.opendocument.database odb +application/vnd.oasis.opendocument.formula odf +application/vnd.oasis.opendocument.formula-template odft +application/vnd.oasis.opendocument.graphics odg +application/vnd.oasis.opendocument.graphics-template otg +application/vnd.oasis.opendocument.image odi +application/vnd.oasis.opendocument.image-template oti +application/vnd.oasis.opendocument.presentation odp +application/vnd.oasis.opendocument.presentation-template otp +application/vnd.oasis.opendocument.spreadsheet ods +application/vnd.oasis.opendocument.spreadsheet-template ots +application/vnd.oasis.opendocument.text odt +application/vnd.oasis.opendocument.text-master odm +application/vnd.oasis.opendocument.text-template ott +application/vnd.oasis.opendocument.text-web oth +# application/vnd.obn +# application/vnd.oipf.contentaccessdownload+xml +# application/vnd.oipf.contentaccessstreaming+xml +# application/vnd.oipf.cspg-hexbinary +# application/vnd.oipf.dae.svg+xml +# application/vnd.oipf.dae.xhtml+xml +# application/vnd.oipf.mippvcontrolmessage+xml +# application/vnd.oipf.pae.gem +# application/vnd.oipf.spdiscovery+xml +# application/vnd.oipf.spdlist+xml +# application/vnd.oipf.ueprofile+xml +# application/vnd.oipf.userprofile+xml +application/vnd.olpc-sugar xo +# application/vnd.oma-scws-config +# application/vnd.oma-scws-http-request +# application/vnd.oma-scws-http-response +# application/vnd.oma.bcast.associated-procedure-parameter+xml +# application/vnd.oma.bcast.drm-trigger+xml +# application/vnd.oma.bcast.imd+xml +# application/vnd.oma.bcast.ltkm +# application/vnd.oma.bcast.notification+xml +# application/vnd.oma.bcast.provisioningtrigger +# application/vnd.oma.bcast.sgboot +# application/vnd.oma.bcast.sgdd+xml +# application/vnd.oma.bcast.sgdu +# application/vnd.oma.bcast.simple-symbol-container +# application/vnd.oma.bcast.smartcard-trigger+xml +# application/vnd.oma.bcast.sprov+xml +# application/vnd.oma.bcast.stkm +# application/vnd.oma.cab-address-book+xml +# application/vnd.oma.cab-pcc+xml +# application/vnd.oma.dcd +# application/vnd.oma.dcdc +application/vnd.oma.dd2+xml dd2 +# application/vnd.oma.drm.risd+xml +# application/vnd.oma.group-usage-list+xml +# application/vnd.oma.poc.detailed-progress-report+xml +# application/vnd.oma.poc.final-report+xml +# application/vnd.oma.poc.groups+xml +# application/vnd.oma.poc.invocation-descriptor+xml +# application/vnd.oma.poc.optimized-progress-report+xml +# application/vnd.oma.push +# application/vnd.oma.scidm.messages+xml +# application/vnd.oma.xcap-directory+xml +# application/vnd.omads-email+xml +# application/vnd.omads-file+xml +# application/vnd.omads-folder+xml +# application/vnd.omaloc-supl-init +application/vnd.openofficeorg.extension oxt +# application/vnd.openxmlformats-officedocument.custom-properties+xml +# application/vnd.openxmlformats-officedocument.customxmlproperties+xml +# application/vnd.openxmlformats-officedocument.drawing+xml +# application/vnd.openxmlformats-officedocument.drawingml.chart+xml +# application/vnd.openxmlformats-officedocument.drawingml.chartshapes+xml +# application/vnd.openxmlformats-officedocument.drawingml.diagramcolors+xml +# application/vnd.openxmlformats-officedocument.drawingml.diagramdata+xml +# application/vnd.openxmlformats-officedocument.drawingml.diagramlayout+xml +# application/vnd.openxmlformats-officedocument.drawingml.diagramstyle+xml +# application/vnd.openxmlformats-officedocument.extended-properties+xml +# application/vnd.openxmlformats-officedocument.presentationml.commentauthors+xml +# application/vnd.openxmlformats-officedocument.presentationml.comments+xml +# application/vnd.openxmlformats-officedocument.presentationml.handoutmaster+xml +# application/vnd.openxmlformats-officedocument.presentationml.notesmaster+xml +# application/vnd.openxmlformats-officedocument.presentationml.notesslide+xml +application/vnd.openxmlformats-officedocument.presentationml.presentation pptx +# application/vnd.openxmlformats-officedocument.presentationml.presentation.main+xml +# application/vnd.openxmlformats-officedocument.presentationml.presprops+xml +application/vnd.openxmlformats-officedocument.presentationml.slide sldx +# application/vnd.openxmlformats-officedocument.presentationml.slide+xml +# application/vnd.openxmlformats-officedocument.presentationml.slidelayout+xml +# application/vnd.openxmlformats-officedocument.presentationml.slidemaster+xml +application/vnd.openxmlformats-officedocument.presentationml.slideshow ppsx +# application/vnd.openxmlformats-officedocument.presentationml.slideshow.main+xml +# application/vnd.openxmlformats-officedocument.presentationml.slideupdateinfo+xml +# application/vnd.openxmlformats-officedocument.presentationml.tablestyles+xml +# application/vnd.openxmlformats-officedocument.presentationml.tags+xml +application/vnd.openxmlformats-officedocument.presentationml.template potx +# application/vnd.openxmlformats-officedocument.presentationml.template.main+xml +# application/vnd.openxmlformats-officedocument.presentationml.viewprops+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.calcchain+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.chartsheet+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.connections+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.dialogsheet+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.externallink+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.pivotcachedefinition+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.pivotcacherecords+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.pivottable+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.querytable+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.revisionheaders+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.revisionlog+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.sharedstrings+xml +application/vnd.openxmlformats-officedocument.spreadsheetml.sheet xlsx +# application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.sheetmetadata+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.table+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.tablesinglecells+xml +application/vnd.openxmlformats-officedocument.spreadsheetml.template xltx +# application/vnd.openxmlformats-officedocument.spreadsheetml.template.main+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.usernames+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.volatiledependencies+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml +# application/vnd.openxmlformats-officedocument.theme+xml +# application/vnd.openxmlformats-officedocument.themeoverride+xml +# application/vnd.openxmlformats-officedocument.vmldrawing +# application/vnd.openxmlformats-officedocument.wordprocessingml.comments+xml +application/vnd.openxmlformats-officedocument.wordprocessingml.document docx +# application/vnd.openxmlformats-officedocument.wordprocessingml.document.glossary+xml +# application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml +# application/vnd.openxmlformats-officedocument.wordprocessingml.endnotes+xml +# application/vnd.openxmlformats-officedocument.wordprocessingml.fonttable+xml +# application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml +# application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml +# application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml +# application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml +# application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml +application/vnd.openxmlformats-officedocument.wordprocessingml.template dotx +# application/vnd.openxmlformats-officedocument.wordprocessingml.template.main+xml +# application/vnd.openxmlformats-officedocument.wordprocessingml.websettings+xml +# application/vnd.openxmlformats-package.core-properties+xml +# application/vnd.openxmlformats-package.digital-signature-xmlsignature+xml +# application/vnd.openxmlformats-package.relationships+xml +# application/vnd.quobject-quoxdocument +# application/vnd.osa.netdeploy +application/vnd.osgeo.mapguide.package mgp +# application/vnd.osgi.bundle +application/vnd.osgi.dp dp +# application/vnd.otps.ct-kip+xml +application/vnd.palm pdb pqa oprc +# application/vnd.paos.xml +application/vnd.pawaafile paw +application/vnd.pg.format str +application/vnd.pg.osasli ei6 +# application/vnd.piaccess.application-licence +application/vnd.picsel efif +application/vnd.pmi.widget wg +# application/vnd.poc.group-advertisement+xml +application/vnd.pocketlearn plf +application/vnd.powerbuilder6 pbd +# application/vnd.powerbuilder6-s +# application/vnd.powerbuilder7 +# application/vnd.powerbuilder7-s +# application/vnd.powerbuilder75 +# application/vnd.powerbuilder75-s +# application/vnd.preminet +application/vnd.previewsystems.box box +application/vnd.proteus.magazine mgz +application/vnd.publishare-delta-tree qps +application/vnd.pvi.ptid1 ptid +# application/vnd.pwg-multiplexed +# application/vnd.pwg-xhtml-print+xml +# application/vnd.qualcomm.brew-app-res +application/vnd.quark.quarkxpress qxd qxt qwd qwt qxl qxb +# application/vnd.radisys.moml+xml +# application/vnd.radisys.msml+xml +# application/vnd.radisys.msml-audit+xml +# application/vnd.radisys.msml-audit-conf+xml +# application/vnd.radisys.msml-audit-conn+xml +# application/vnd.radisys.msml-audit-dialog+xml +# application/vnd.radisys.msml-audit-stream+xml +# application/vnd.radisys.msml-conf+xml +# application/vnd.radisys.msml-dialog+xml +# application/vnd.radisys.msml-dialog-base+xml +# application/vnd.radisys.msml-dialog-fax-detect+xml +# application/vnd.radisys.msml-dialog-fax-sendrecv+xml +# application/vnd.radisys.msml-dialog-group+xml +# application/vnd.radisys.msml-dialog-speech+xml +# application/vnd.radisys.msml-dialog-transform+xml +# application/vnd.rainstor.data +# application/vnd.rapid +application/vnd.realvnc.bed bed +application/vnd.recordare.musicxml mxl +application/vnd.recordare.musicxml+xml musicxml +# application/vnd.renlearn.rlprint +application/vnd.rig.cryptonote cryptonote +application/vnd.rim.cod cod +application/vnd.rn-realmedia rm +application/vnd.route66.link66+xml link66 +# application/vnd.ruckus.download +# application/vnd.s3sms +application/vnd.sailingtracker.track st +# application/vnd.sbm.cid +# application/vnd.sbm.mid2 +# application/vnd.scribus +# application/vnd.sealed.3df +# application/vnd.sealed.csf +# application/vnd.sealed.doc +# application/vnd.sealed.eml +# application/vnd.sealed.mht +# application/vnd.sealed.net +# application/vnd.sealed.ppt +# application/vnd.sealed.tiff +# application/vnd.sealed.xls +# application/vnd.sealedmedia.softseal.html +# application/vnd.sealedmedia.softseal.pdf +application/vnd.seemail see +application/vnd.sema sema +application/vnd.semd semd +application/vnd.semf semf +application/vnd.shana.informed.formdata ifm +application/vnd.shana.informed.formtemplate itp +application/vnd.shana.informed.interchange iif +application/vnd.shana.informed.package ipk +application/vnd.simtech-mindmapper twd twds +application/vnd.smaf mmf +# application/vnd.smart.notebook +application/vnd.smart.teacher teacher +# application/vnd.software602.filler.form+xml +# application/vnd.software602.filler.form-xml-zip +application/vnd.solent.sdkm+xml sdkm sdkd +application/vnd.spotfire.dxp dxp +application/vnd.spotfire.sfs sfs +# application/vnd.sss-cod +# application/vnd.sss-dtf +# application/vnd.sss-ntf +application/vnd.stardivision.calc sdc +application/vnd.stardivision.draw sda +application/vnd.stardivision.impress sdd +application/vnd.stardivision.math smf +application/vnd.stardivision.writer sdw vor +application/vnd.stardivision.writer-global sgl +application/vnd.stepmania.stepchart sm +# application/vnd.street-stream +application/vnd.sun.xml.calc sxc +application/vnd.sun.xml.calc.template stc +application/vnd.sun.xml.draw sxd +application/vnd.sun.xml.draw.template std +application/vnd.sun.xml.impress sxi +application/vnd.sun.xml.impress.template sti +application/vnd.sun.xml.math sxm +application/vnd.sun.xml.writer sxw +application/vnd.sun.xml.writer.global sxg +application/vnd.sun.xml.writer.template stw +# application/vnd.sun.wadl+xml +application/vnd.sus-calendar sus susp +application/vnd.svd svd +# application/vnd.swiftview-ics +application/vnd.symbian.install sis sisx +application/vnd.syncml+xml xsm +application/vnd.syncml.dm+wbxml bdm +application/vnd.syncml.dm+xml xdm +# application/vnd.syncml.dm.notification +# application/vnd.syncml.ds.notification +application/vnd.tao.intent-module-archive tao +application/vnd.tmobile-livetv tmo +application/vnd.trid.tpt tpt +application/vnd.triscape.mxs mxs +application/vnd.trueapp tra +# application/vnd.truedoc +# application/vnd.ubisoft.webplayer +application/vnd.ufdl ufd ufdl +application/vnd.uiq.theme utz +application/vnd.umajin umj +application/vnd.unity unityweb +application/vnd.uoml+xml uoml +# application/vnd.uplanet.alert +# application/vnd.uplanet.alert-wbxml +# application/vnd.uplanet.bearer-choice +# application/vnd.uplanet.bearer-choice-wbxml +# application/vnd.uplanet.cacheop +# application/vnd.uplanet.cacheop-wbxml +# application/vnd.uplanet.channel +# application/vnd.uplanet.channel-wbxml +# application/vnd.uplanet.list +# application/vnd.uplanet.list-wbxml +# application/vnd.uplanet.listcmd +# application/vnd.uplanet.listcmd-wbxml +# application/vnd.uplanet.signal +application/vnd.vcx vcx +# application/vnd.vd-study +# application/vnd.vectorworks +# application/vnd.verimatrix.vcas +# application/vnd.vidsoft.vidconference +application/vnd.visio vsd vst vss vsw +application/vnd.visionary vis +# application/vnd.vividence.scriptfile +application/vnd.vsf vsf +# application/vnd.wap.sic +# application/vnd.wap.slc +application/vnd.wap.wbxml wbxml +application/vnd.wap.wmlc wmlc +application/vnd.wap.wmlscriptc wmlsc +application/vnd.webturbo wtb +# application/vnd.wfa.wsc +# application/vnd.wmc +# application/vnd.wmf.bootstrap +# application/vnd.wolfram.mathematica +# application/vnd.wolfram.mathematica.package +application/vnd.wolfram.player nbp +application/vnd.wordperfect wpd +application/vnd.wqd wqd +# application/vnd.wrq-hp3000-labelled +application/vnd.wt.stf stf +# application/vnd.wv.csp+wbxml +# application/vnd.wv.csp+xml +# application/vnd.wv.ssp+xml +application/vnd.xara xar +application/vnd.xfdl xfdl +# application/vnd.xfdl.webform +# application/vnd.xmi+xml +# application/vnd.xmpie.cpkg +# application/vnd.xmpie.dpkg +# application/vnd.xmpie.plan +# application/vnd.xmpie.ppkg +# application/vnd.xmpie.xlim +application/vnd.yamaha.hv-dic hvd +application/vnd.yamaha.hv-script hvs +application/vnd.yamaha.hv-voice hvp +application/vnd.yamaha.openscoreformat osf +application/vnd.yamaha.openscoreformat.osfpvg+xml osfpvg +# application/vnd.yamaha.remote-setup +application/vnd.yamaha.smaf-audio saf +application/vnd.yamaha.smaf-phrase spf +# application/vnd.yamaha.tunnel-udpencap +application/vnd.yellowriver-custom-menu cmp +application/vnd.zul zir zirz +application/vnd.zzazz.deck+xml zaz +application/voicexml+xml vxml +# application/vq-rtcpxr +# application/watcherinfo+xml +# application/whoispp-query +# application/whoispp-response +application/widget wgt +application/winhlp hlp +# application/wita +# application/wordperfect5.1 +application/wsdl+xml wsdl +application/wspolicy+xml wspolicy +application/x-7z-compressed 7z +application/x-abiword abw +application/x-ace-compressed ace +application/x-authorware-bin aab x32 u32 vox +application/x-authorware-map aam +application/x-authorware-seg aas +application/x-bcpio bcpio +application/x-bittorrent torrent +application/x-bzip bz +application/x-bzip2 bz2 boz +application/x-cdlink vcd +application/x-chat chat +application/x-chess-pgn pgn +# application/x-compress +application/x-cpio cpio +application/x-csh csh +application/x-debian-package deb udeb +application/x-director dir dcr dxr cst cct cxt w3d fgd swa +application/x-doom wad +application/x-dtbncx+xml ncx +application/x-dtbook+xml dtb +application/x-dtbresource+xml res +application/x-dvi dvi +application/x-font-bdf bdf +# application/x-font-dos +# application/x-font-framemaker +application/x-font-ghostscript gsf +# application/x-font-libgrx +application/x-font-linux-psf psf +application/x-font-otf otf +application/x-font-pcf pcf +application/x-font-snf snf +# application/x-font-speedo +# application/x-font-sunos-news +application/x-font-ttf ttf ttc +application/x-font-type1 pfa pfb pfm afm +application/x-font-woff woff +# application/x-font-vfont +application/x-futuresplash spl +application/x-gnumeric gnumeric +application/x-gtar gtar +# application/x-gzip +application/x-hdf hdf +application/x-java-jnlp-file jnlp +application/x-latex latex +application/x-mobipocket-ebook prc mobi +application/x-ms-application application +application/x-ms-wmd wmd +application/x-ms-wmz wmz +application/x-ms-xbap xbap +application/x-msaccess mdb +application/x-msbinder obd +application/x-mscardfile crd +application/x-msclip clp +application/x-msdownload exe dll com bat msi +application/x-msmediaview mvb m13 m14 +application/x-msmetafile wmf +application/x-msmoney mny +application/x-mspublisher pub +application/x-msschedule scd +application/x-msterminal trm +application/x-mswrite wri +application/x-netcdf nc cdf +application/x-pkcs12 p12 pfx +application/x-pkcs7-certificates p7b spc +application/x-pkcs7-certreqresp p7r +application/x-rar-compressed rar +application/x-sh sh +application/x-shar shar +application/x-shockwave-flash swf +application/x-silverlight-app xap +application/x-stuffit sit +application/x-stuffitx sitx +application/x-sv4cpio sv4cpio +application/x-sv4crc sv4crc +application/x-tar tar +application/x-tcl tcl +application/x-tex tex +application/x-tex-tfm tfm +application/x-texinfo texinfo texi +application/x-ustar ustar +application/x-wais-source src +application/x-x509-ca-cert der crt +application/x-xfig fig +application/x-xpinstall xpi +# application/x400-bp +# application/xcap-att+xml +# application/xcap-caps+xml +application/xcap-diff+xml xdf +# application/xcap-el+xml +# application/xcap-error+xml +# application/xcap-ns+xml +# application/xcon-conference-info-diff+xml +# application/xcon-conference-info+xml +application/xenc+xml xenc +application/xhtml+xml xhtml xht +# application/xhtml-voice+xml +application/xml xml xsl +application/xml-dtd dtd +# application/xml-external-parsed-entity +# application/xmpp+xml +application/xop+xml xop +application/xslt+xml xslt +application/xspf+xml xspf +application/xv+xml mxml xhvml xvml xvm +application/yang yang +application/yin+xml yin +application/zip zip +# audio/1d-interleaved-parityfec +# audio/32kadpcm +# audio/3gpp +# audio/3gpp2 +# audio/ac3 +audio/adpcm adp +# audio/amr +# audio/amr-wb +# audio/amr-wb+ +# audio/asc +# audio/atrac-advanced-lossless +# audio/atrac-x +# audio/atrac3 +audio/basic au snd +# audio/bv16 +# audio/bv32 +# audio/clearmode +# audio/cn +# audio/dat12 +# audio/dls +# audio/dsr-es201108 +# audio/dsr-es202050 +# audio/dsr-es202211 +# audio/dsr-es202212 +# audio/dvi4 +# audio/eac3 +# audio/evrc +# audio/evrc-qcp +# audio/evrc0 +# audio/evrc1 +# audio/evrcb +# audio/evrcb0 +# audio/evrcb1 +# audio/evrcwb +# audio/evrcwb0 +# audio/evrcwb1 +# audio/example +# audio/g719 +# audio/g722 +# audio/g7221 +# audio/g723 +# audio/g726-16 +# audio/g726-24 +# audio/g726-32 +# audio/g726-40 +# audio/g728 +# audio/g729 +# audio/g7291 +# audio/g729d +# audio/g729e +# audio/gsm +# audio/gsm-efr +# audio/gsm-hr-08 +# audio/ilbc +# audio/l16 +# audio/l20 +# audio/l24 +# audio/l8 +# audio/lpc +audio/midi mid midi kar rmi +# audio/mobile-xmf +audio/mp4 mp4a +# audio/mp4a-latm +# audio/mpa +# audio/mpa-robust +audio/mpeg mpga mp2 mp2a mp3 m2a m3a +# audio/mpeg4-generic +audio/ogg oga ogg spx +# audio/parityfec +# audio/pcma +# audio/pcma-wb +# audio/pcmu-wb +# audio/pcmu +# audio/prs.sid +# audio/qcelp +# audio/red +# audio/rtp-enc-aescm128 +# audio/rtp-midi +# audio/rtx +# audio/smv +# audio/smv0 +# audio/smv-qcp +# audio/sp-midi +# audio/speex +# audio/t140c +# audio/t38 +# audio/telephone-event +# audio/tone +# audio/uemclip +# audio/ulpfec +# audio/vdvi +# audio/vmr-wb +# audio/vnd.3gpp.iufp +# audio/vnd.4sb +# audio/vnd.audiokoz +# audio/vnd.celp +# audio/vnd.cisco.nse +# audio/vnd.cmles.radio-events +# audio/vnd.cns.anp1 +# audio/vnd.cns.inf1 +audio/vnd.dece.audio uva uvva +audio/vnd.digital-winds eol +# audio/vnd.dlna.adts +# audio/vnd.dolby.heaac.1 +# audio/vnd.dolby.heaac.2 +# audio/vnd.dolby.mlp +# audio/vnd.dolby.mps +# audio/vnd.dolby.pl2 +# audio/vnd.dolby.pl2x +# audio/vnd.dolby.pl2z +# audio/vnd.dolby.pulse.1 +audio/vnd.dra dra +audio/vnd.dts dts +audio/vnd.dts.hd dtshd +# audio/vnd.everad.plj +# audio/vnd.hns.audio +audio/vnd.lucent.voice lvp +audio/vnd.ms-playready.media.pya pya +# audio/vnd.nokia.mobile-xmf +# audio/vnd.nortel.vbk +audio/vnd.nuera.ecelp4800 ecelp4800 +audio/vnd.nuera.ecelp7470 ecelp7470 +audio/vnd.nuera.ecelp9600 ecelp9600 +# audio/vnd.octel.sbc +# audio/vnd.qcelp +# audio/vnd.rhetorex.32kadpcm +audio/vnd.rip rip +# audio/vnd.sealedmedia.softseal.mpeg +# audio/vnd.vmx.cvsd +# audio/vorbis +# audio/vorbis-config +audio/webm weba +audio/x-aac aac +audio/x-aiff aif aiff aifc +audio/x-mpegurl m3u +audio/x-ms-wax wax +audio/x-ms-wma wma +audio/x-pn-realaudio ram ra +audio/x-pn-realaudio-plugin rmp +audio/x-wav wav +chemical/x-cdx cdx +chemical/x-cif cif +chemical/x-cmdf cmdf +chemical/x-cml cml +chemical/x-csml csml +# chemical/x-pdb +chemical/x-xyz xyz +image/bmp bmp +image/cgm cgm +# image/example +# image/fits +image/g3fax g3 +image/gif gif +image/ief ief +# image/jp2 +image/jpeg jpeg jpg jpe +# image/jpm +# image/jpx +image/ktx ktx +# image/naplps +image/png png +image/prs.btif btif +# image/prs.pti +image/svg+xml svg svgz +# image/t38 +image/tiff tiff tif +# image/tiff-fx +image/vnd.adobe.photoshop psd +# image/vnd.cns.inf2 +image/vnd.dece.graphic uvi uvvi uvg uvvg +image/vnd.dvb.subtitle sub +image/vnd.djvu djvu djv +image/vnd.dwg dwg +image/vnd.dxf dxf +image/vnd.fastbidsheet fbs +image/vnd.fpx fpx +image/vnd.fst fst +image/vnd.fujixerox.edmics-mmr mmr +image/vnd.fujixerox.edmics-rlc rlc +# image/vnd.globalgraphics.pgb +# image/vnd.microsoft.icon +# image/vnd.mix +image/vnd.ms-modi mdi +image/vnd.net-fpx npx +# image/vnd.radiance +# image/vnd.sealed.png +# image/vnd.sealedmedia.softseal.gif +# image/vnd.sealedmedia.softseal.jpg +# image/vnd.svf +image/vnd.wap.wbmp wbmp +image/vnd.xiff xif +image/webp webp +image/x-cmu-raster ras +image/x-cmx cmx +image/x-freehand fh fhc fh4 fh5 fh7 +image/x-icon ico +image/x-pcx pcx +image/x-pict pic pct +image/x-portable-anymap pnm +image/x-portable-bitmap pbm +image/x-portable-graymap pgm +image/x-portable-pixmap ppm +image/x-rgb rgb +image/x-xbitmap xbm +image/x-xpixmap xpm +image/x-xwindowdump xwd +# message/cpim +# message/delivery-status +# message/disposition-notification +# message/example +# message/external-body +# message/feedback-report +# message/global +# message/global-delivery-status +# message/global-disposition-notification +# message/global-headers +# message/http +# message/imdn+xml +# message/news +# message/partial +message/rfc822 eml mime +# message/s-http +# message/sip +# message/sipfrag +# message/tracking-status +# message/vnd.si.simp +# model/example +model/iges igs iges +model/mesh msh mesh silo +model/vnd.collada+xml dae +model/vnd.dwf dwf +# model/vnd.flatland.3dml +model/vnd.gdl gdl +# model/vnd.gs-gdl +# model/vnd.gs.gdl +model/vnd.gtw gtw +# model/vnd.moml+xml +model/vnd.mts mts +# model/vnd.parasolid.transmit.binary +# model/vnd.parasolid.transmit.text +model/vnd.vtu vtu +model/vrml wrl vrml +# multipart/alternative +# multipart/appledouble +# multipart/byteranges +# multipart/digest +# multipart/encrypted +# multipart/example +# multipart/form-data +# multipart/header-set +# multipart/mixed +# multipart/parallel +# multipart/related +# multipart/report +# multipart/signed +# multipart/voice-message +# text/1d-interleaved-parityfec +text/calendar ics ifb +text/css css +text/csv csv +# text/directory +# text/dns +# text/ecmascript +# text/enriched +# text/example +text/html html htm +# text/javascript +text/n3 n3 +# text/parityfec +text/plain txt text conf def list log in +# text/prs.fallenstein.rst +text/prs.lines.tag dsc +# text/vnd.radisys.msml-basic-layout +# text/red +# text/rfc822-headers +text/richtext rtx +# text/rtf +# text/rtp-enc-aescm128 +# text/rtx +text/sgml sgml sgm +# text/t140 +text/tab-separated-values tsv +text/troff t tr roff man me ms +text/turtle ttl +# text/ulpfec +text/uri-list uri uris urls +# text/vnd.abc +text/vnd.curl curl +text/vnd.curl.dcurl dcurl +text/vnd.curl.scurl scurl +text/vnd.curl.mcurl mcurl +# text/vnd.dmclientscript +# text/vnd.esmertec.theme-descriptor +text/vnd.fly fly +text/vnd.fmi.flexstor flx +text/vnd.graphviz gv +text/vnd.in3d.3dml 3dml +text/vnd.in3d.spot spot +# text/vnd.iptc.newsml +# text/vnd.iptc.nitf +# text/vnd.latex-z +# text/vnd.motorola.reflex +# text/vnd.ms-mediapackage +# text/vnd.net2phone.commcenter.command +# text/vnd.si.uricatalogue +text/vnd.sun.j2me.app-descriptor jad +# text/vnd.trolltech.linguist +# text/vnd.wap.si +# text/vnd.wap.sl +text/vnd.wap.wml wml +text/vnd.wap.wmlscript wmls +text/x-asm s asm +text/x-c c cc cxx cpp h hh dic +text/x-fortran f for f77 f90 +text/x-pascal p pas +text/x-java-source java +text/x-setext etx +text/x-uuencode uu +text/x-vcalendar vcs +text/x-vcard vcf +# text/xml +# text/xml-external-parsed-entity +# video/1d-interleaved-parityfec +video/3gpp 3gp +# video/3gpp-tt +video/3gpp2 3g2 +# video/bmpeg +# video/bt656 +# video/celb +# video/dv +# video/example +video/h261 h261 +video/h263 h263 +# video/h263-1998 +# video/h263-2000 +video/h264 h264 +# video/h264-rcdo +# video/h264-svc +video/jpeg jpgv +# video/jpeg2000 +video/jpm jpm jpgm +video/mj2 mj2 mjp2 +# video/mp1s +# video/mp2p +# video/mp2t +video/mp4 mp4 mp4v mpg4 +# video/mp4v-es +video/mpeg mpeg mpg mpe m1v m2v +# video/mpeg4-generic +# video/mpv +# video/nv +video/ogg ogv +# video/parityfec +# video/pointer +video/quicktime qt mov +# video/raw +# video/rtp-enc-aescm128 +# video/rtx +# video/smpte292m +# video/ulpfec +# video/vc1 +# video/vnd.cctv +video/vnd.dece.hd uvh uvvh +video/vnd.dece.mobile uvm uvvm +# video/vnd.dece.mp4 +video/vnd.dece.pd uvp uvvp +video/vnd.dece.sd uvs uvvs +video/vnd.dece.video uvv uvvv +# video/vnd.directv.mpeg +# video/vnd.directv.mpeg-tts +# video/vnd.dlna.mpeg-tts +video/vnd.fvt fvt +# video/vnd.hns.video +# video/vnd.iptvforum.1dparityfec-1010 +# video/vnd.iptvforum.1dparityfec-2005 +# video/vnd.iptvforum.2dparityfec-1010 +# video/vnd.iptvforum.2dparityfec-2005 +# video/vnd.iptvforum.ttsavc +# video/vnd.iptvforum.ttsmpeg2 +# video/vnd.motorola.video +# video/vnd.motorola.videop +video/vnd.mpegurl mxu m4u +video/vnd.ms-playready.media.pyv pyv +# video/vnd.nokia.interleaved-multimedia +# video/vnd.nokia.videovoip +# video/vnd.objectvideo +# video/vnd.sealed.mpeg1 +# video/vnd.sealed.mpeg4 +# video/vnd.sealed.swf +# video/vnd.sealedmedia.softseal.mov +video/vnd.uvvu.mp4 uvu uvvu +video/vnd.vivo viv +video/webm webm +video/x-f4v f4v +video/x-fli fli +video/x-flv flv +video/x-m4v m4v +video/x-ms-asf asf asx +video/x-ms-wm wm +video/x-ms-wmv wmv +video/x-ms-wmx wmx +video/x-ms-wvx wvx +video/x-msvideo avi +video/x-sgi-movie movie +x-conference/x-cooltalk ice diff --git a/node_modules/express/node_modules/mime/types/node.types b/node_modules/express/node_modules/mime/types/node.types new file mode 100644 index 0000000..fdabaa4 --- /dev/null +++ b/node_modules/express/node_modules/mime/types/node.types @@ -0,0 +1,43 @@ +# What: Google Chrome Extension +# Why: To allow apps to (work) be served with the right content type header. +# http://codereview.chromium.org/2830017 +# Added by: niftylettuce +application/x-chrome-extension crx + +# What: OTF Message Silencer +# Why: To silence the "Resource interpreted as font but transferred with MIME +# type font/otf" message that occurs in Google Chrome +# Added by: niftylettuce +font/opentype otf + +# What: HTC support +# Why: To properly render .htc files such as CSS3PIE +# Added by: niftylettuce +text/x-component htc + +# What: HTML5 application cache manifest +# Why: De-facto standard. Required by Mozilla browser when serving HTML5 apps +# per https://developer.mozilla.org/en/offline_resources_in_firefox +# Added by: louisremi +text/cache-manifest appcache manifest + +# What: node binary buffer format +# Why: semi-standard extension w/in the node community +# Added by: tootallnate +application/octet-stream buffer + +# What: The "protected" MP-4 formats used by iTunes. +# Why: Required for streaming music to browsers (?) +# Added by: broofa +application/mp4 m4p +audio/mp4 m4a + +# What: Music playlist format (http://en.wikipedia.org/wiki/M3U) +# Why: See https://github.com/bentomas/node-mime/pull/6 +# Added by: mjrusso +application/x-mpegURL m3u8 + +# What: Video format, Part of RFC1890 +# Why: See https://github.com/bentomas/node-mime/pull/6 +# Added by: mjrusso +video/MP2T ts diff --git a/node_modules/express/node_modules/mkdirp/.gitignore b/node_modules/express/node_modules/mkdirp/.gitignore new file mode 100644 index 0000000..9303c34 --- /dev/null +++ b/node_modules/express/node_modules/mkdirp/.gitignore @@ -0,0 +1,2 @@ +node_modules/ +npm-debug.log \ No newline at end of file diff --git a/node_modules/express/node_modules/mkdirp/.gitignore.orig b/node_modules/express/node_modules/mkdirp/.gitignore.orig new file mode 100644 index 0000000..9303c34 --- /dev/null +++ b/node_modules/express/node_modules/mkdirp/.gitignore.orig @@ -0,0 +1,2 @@ +node_modules/ +npm-debug.log \ No newline at end of file diff --git a/node_modules/express/node_modules/mkdirp/.gitignore.rej b/node_modules/express/node_modules/mkdirp/.gitignore.rej new file mode 100644 index 0000000..69244ff --- /dev/null +++ b/node_modules/express/node_modules/mkdirp/.gitignore.rej @@ -0,0 +1,5 @@ +--- /dev/null ++++ .gitignore +@@ -0,0 +1,2 @@ ++node_modules/ ++npm-debug.log \ No newline at end of file diff --git a/node_modules/express/node_modules/mkdirp/LICENSE b/node_modules/express/node_modules/mkdirp/LICENSE new file mode 100644 index 0000000..432d1ae --- /dev/null +++ b/node_modules/express/node_modules/mkdirp/LICENSE @@ -0,0 +1,21 @@ +Copyright 2010 James Halliday (mail@substack.net) + +This project is free software released under the MIT/X11 license: + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/node_modules/express/node_modules/mkdirp/README.markdown b/node_modules/express/node_modules/mkdirp/README.markdown new file mode 100644 index 0000000..0393c4e --- /dev/null +++ b/node_modules/express/node_modules/mkdirp/README.markdown @@ -0,0 +1,21 @@ +mkdirp +====== + +Like `mkdir -p`, but in node.js! + +Example +======= + +pow.js +------ + var mkdirp = require('mkdirp'); + + mkdirp('/tmp/foo/bar/baz', 0755, function (err) { + if (err) console.error(err) + else console.log('pow!') + }); + +Output + pow! + +And now /tmp/foo/bar/baz exists, huzzah! diff --git a/node_modules/express/node_modules/mkdirp/examples/pow.js b/node_modules/express/node_modules/mkdirp/examples/pow.js new file mode 100644 index 0000000..7741462 --- /dev/null +++ b/node_modules/express/node_modules/mkdirp/examples/pow.js @@ -0,0 +1,6 @@ +var mkdirp = require('mkdirp'); + +mkdirp('/tmp/foo/bar/baz', 0755, function (err) { + if (err) console.error(err) + else console.log('pow!') +}); diff --git a/node_modules/express/node_modules/mkdirp/examples/pow.js.orig b/node_modules/express/node_modules/mkdirp/examples/pow.js.orig new file mode 100644 index 0000000..7741462 --- /dev/null +++ b/node_modules/express/node_modules/mkdirp/examples/pow.js.orig @@ -0,0 +1,6 @@ +var mkdirp = require('mkdirp'); + +mkdirp('/tmp/foo/bar/baz', 0755, function (err) { + if (err) console.error(err) + else console.log('pow!') +}); diff --git a/node_modules/express/node_modules/mkdirp/examples/pow.js.rej b/node_modules/express/node_modules/mkdirp/examples/pow.js.rej new file mode 100644 index 0000000..81e7f43 --- /dev/null +++ b/node_modules/express/node_modules/mkdirp/examples/pow.js.rej @@ -0,0 +1,19 @@ +--- examples/pow.js ++++ examples/pow.js +@@ -1,6 +1,15 @@ +-var mkdirp = require('mkdirp').mkdirp; ++var mkdirp = require('../').mkdirp, ++ mkdirpSync = require('../').mkdirpSync; + + mkdirp('/tmp/foo/bar/baz', 0755, function (err) { + if (err) console.error(err) + else console.log('pow!') + }); ++ ++try { ++ mkdirpSync('/tmp/bar/foo/baz', 0755); ++ console.log('double pow!'); ++} ++catch (ex) { ++ console.log(ex); ++} \ No newline at end of file diff --git a/node_modules/express/node_modules/mkdirp/index.js b/node_modules/express/node_modules/mkdirp/index.js new file mode 100644 index 0000000..30e9600 --- /dev/null +++ b/node_modules/express/node_modules/mkdirp/index.js @@ -0,0 +1,20 @@ +var path = require('path'); +var fs = require('fs'); + +var exports = module.exports = function mkdirP (p, mode, f) { + var cb = f || function () {}; + p = path.resolve(p); + + var ps = path.normalize(p).split('/'); + path.exists(p, function (exists) { + if (exists) cb(null); + else mkdirP(ps.slice(0,-1).join('/'), mode, function (err) { + if (err && err.code !== 'EEXIST') cb(err) + else fs.mkdir(p, mode, function (err) { + if (err && err.code !== 'EEXIST') cb(err) + else cb() + }); + }); + }); +}; +exports.mkdirp = exports.mkdirP = module.exports; diff --git a/node_modules/express/node_modules/mkdirp/package.json b/node_modules/express/node_modules/mkdirp/package.json new file mode 100644 index 0000000..f5ceb00 --- /dev/null +++ b/node_modules/express/node_modules/mkdirp/package.json @@ -0,0 +1,23 @@ +{ + "name" : "mkdirp", + "description" : "Recursively mkdir, like `mkdir -p`", + "version" : "0.0.7", + "author" : "James Halliday (http://substack.net)", + "main" : "./index", + "keywords" : [ + "mkdir", + "directory" + ], + "repository" : { + "type" : "git", + "url" : "http://github.com/substack/node-mkdirp.git" + }, + "scripts" : { + "test" : "node node_modules/tap/bin/tap.js test/*.js" + }, + "devDependencies" : { + "tap" : "0.0.x" + }, + "license" : "MIT/X11", + "engines": { "node": "*" } +} diff --git a/node_modules/express/node_modules/mkdirp/test/mkdirp.js b/node_modules/express/node_modules/mkdirp/test/mkdirp.js new file mode 100644 index 0000000..b07cd70 --- /dev/null +++ b/node_modules/express/node_modules/mkdirp/test/mkdirp.js @@ -0,0 +1,28 @@ +var mkdirp = require('../'); +var path = require('path'); +var fs = require('fs'); +var test = require('tap').test; + +test('woo', function (t) { + t.plan(2); + var x = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + var y = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + var z = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + + var file = '/tmp/' + [x,y,z].join('/'); + + mkdirp(file, 0755, function (err) { + if (err) t.fail(err); + else path.exists(file, function (ex) { + if (!ex) t.fail('file not created') + else fs.stat(file, function (err, stat) { + if (err) t.fail(err) + else { + t.equal(stat.mode & 0777, 0755); + t.ok(stat.isDirectory(), 'target not a directory'); + t.end(); + } + }) + }) + }); +}); diff --git a/node_modules/express/node_modules/mkdirp/test/race.js b/node_modules/express/node_modules/mkdirp/test/race.js new file mode 100644 index 0000000..96a0447 --- /dev/null +++ b/node_modules/express/node_modules/mkdirp/test/race.js @@ -0,0 +1,41 @@ +var mkdirp = require('../').mkdirp; +var path = require('path'); +var fs = require('fs'); +var test = require('tap').test; + +test('race', function (t) { + t.plan(4); + var ps = [ '', 'tmp' ]; + + for (var i = 0; i < 25; i++) { + var dir = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + ps.push(dir); + } + var file = ps.join('/'); + + var res = 2; + mk(file, function () { + if (--res === 0) t.end(); + }); + + mk(file, function () { + if (--res === 0) t.end(); + }); + + function mk (file, cb) { + mkdirp(file, 0755, function (err) { + if (err) t.fail(err); + else path.exists(file, function (ex) { + if (!ex) t.fail('file not created') + else fs.stat(file, function (err, stat) { + if (err) t.fail(err) + else { + t.equal(stat.mode & 0777, 0755); + t.ok(stat.isDirectory(), 'target not a directory'); + if (cb) cb(); + } + }) + }) + }); + } +}); diff --git a/node_modules/express/node_modules/mkdirp/test/rel.js b/node_modules/express/node_modules/mkdirp/test/rel.js new file mode 100644 index 0000000..7985824 --- /dev/null +++ b/node_modules/express/node_modules/mkdirp/test/rel.js @@ -0,0 +1,32 @@ +var mkdirp = require('../'); +var path = require('path'); +var fs = require('fs'); +var test = require('tap').test; + +test('rel', function (t) { + t.plan(2); + var x = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + var y = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + var z = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + + var cwd = process.cwd(); + process.chdir('/tmp'); + + var file = [x,y,z].join('/'); + + mkdirp(file, 0755, function (err) { + if (err) t.fail(err); + else path.exists(file, function (ex) { + if (!ex) t.fail('file not created') + else fs.stat(file, function (err, stat) { + if (err) t.fail(err) + else { + process.chdir(cwd); + t.equal(stat.mode & 0777, 0755); + t.ok(stat.isDirectory(), 'target not a directory'); + t.end(); + } + }) + }) + }); +}); diff --git a/node_modules/express/node_modules/qs/.gitignore b/node_modules/express/node_modules/qs/.gitignore new file mode 100644 index 0000000..3c3629e --- /dev/null +++ b/node_modules/express/node_modules/qs/.gitignore @@ -0,0 +1 @@ +node_modules diff --git a/node_modules/express/node_modules/qs/.gitmodules b/node_modules/express/node_modules/qs/.gitmodules new file mode 100644 index 0000000..49e31da --- /dev/null +++ b/node_modules/express/node_modules/qs/.gitmodules @@ -0,0 +1,6 @@ +[submodule "support/expresso"] + path = support/expresso + url = git://github.com/visionmedia/expresso.git +[submodule "support/should"] + path = support/should + url = git://github.com/visionmedia/should.js.git diff --git a/node_modules/express/node_modules/qs/History.md b/node_modules/express/node_modules/qs/History.md new file mode 100644 index 0000000..09b90be --- /dev/null +++ b/node_modules/express/node_modules/qs/History.md @@ -0,0 +1,63 @@ + +0.4.0 / 2011-11-21 +================== + + * Allow parsing of an existing object (for `bodyParser()`) [jackyz] + * Replaced expresso with mocha + +0.3.2 / 2011-11-08 +================== + + * Fixed global variable leak + +0.3.1 / 2011-08-17 +================== + + * Added `try/catch` around malformed uri components + * Add test coverage for Array native method bleed-though + +0.3.0 / 2011-07-19 +================== + + * Allow `array[index]` and `object[property]` syntaxes [Aria Stewart] + +0.2.0 / 2011-06-29 +================== + + * Added `qs.stringify()` [Cory Forsyth] + +0.1.0 / 2011-04-13 +================== + + * Added jQuery-ish array support + +0.0.7 / 2011-03-13 +================== + + * Fixed; handle empty string and `== null` in `qs.parse()` [dmit] + allows for convenient `qs.parse(url.parse(str).query)` + +0.0.6 / 2011-02-14 +================== + + * Fixed; support for implicit arrays + +0.0.4 / 2011-02-09 +================== + + * Fixed `+` as a space + +0.0.3 / 2011-02-08 +================== + + * Fixed case when right-hand value contains "]" + +0.0.2 / 2011-02-07 +================== + + * Fixed "=" presence in key + +0.0.1 / 2011-02-07 +================== + + * Initial release \ No newline at end of file diff --git a/node_modules/express/node_modules/qs/Makefile b/node_modules/express/node_modules/qs/Makefile new file mode 100644 index 0000000..e4df837 --- /dev/null +++ b/node_modules/express/node_modules/qs/Makefile @@ -0,0 +1,5 @@ + +test: + @./node_modules/.bin/mocha + +.PHONY: test \ No newline at end of file diff --git a/node_modules/express/node_modules/qs/Readme.md b/node_modules/express/node_modules/qs/Readme.md new file mode 100644 index 0000000..a3148ff --- /dev/null +++ b/node_modules/express/node_modules/qs/Readme.md @@ -0,0 +1,47 @@ +# node-querystring + + query string parser for node supporting nesting, as it was removed from `0.3.x`, so this library provides the previous and commonly desired behaviour (and twice as fast). Used by [express](http://expressjs.com), [connect](http://senchalabs.github.com/connect) and others. + +## Installation + + $ npm install qs + +## Examples + + require('qs').parse('user[name][first]=tj&user[email]=tj'); + // => { user: { name: { first: 'tj' }, email: 'tj' } } + +## Testing + +Install dev dependencies: + + $ npm install -d + +and execute: + + $ make test + +## License + +(The MIT License) + +Copyright (c) 2010 TJ Holowaychuk <tj@vision-media.ca> + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/node_modules/express/node_modules/qs/benchmark.js b/node_modules/express/node_modules/qs/benchmark.js new file mode 100644 index 0000000..97e2c93 --- /dev/null +++ b/node_modules/express/node_modules/qs/benchmark.js @@ -0,0 +1,17 @@ + +var qs = require('./'); + +var times = 100000 + , start = new Date + , n = times; + +console.log('times: %d', times); + +while (n--) qs.parse('foo=bar'); +console.log('simple: %dms', new Date - start); + +var start = new Date + , n = times; + +while (n--) qs.parse('user[name][first]=tj&user[name][last]=holowaychuk'); +console.log('nested: %dms', new Date - start); \ No newline at end of file diff --git a/node_modules/express/node_modules/qs/examples.js b/node_modules/express/node_modules/qs/examples.js new file mode 100644 index 0000000..9b652b0 --- /dev/null +++ b/node_modules/express/node_modules/qs/examples.js @@ -0,0 +1,48 @@ + +/** + * Module dependencies. + */ + +var qs = require('./'); + +var obj = qs.parse('foo'); +console.log(obj) + +var obj = qs.parse('foo=bar=baz'); +console.log(obj) + +var obj = qs.parse('users[]'); +console.log(obj) + +var obj = qs.parse('name=tj&email=tj@vision-media.ca'); +console.log(obj) + +var obj = qs.parse('users[]=tj&users[]=tobi&users[]=jane'); +console.log(obj) + +var obj = qs.parse('user[name][first]=tj&user[name][last]=holowaychuk'); +console.log(obj) + +var obj = qs.parse('users[][name][first]=tj&users[][name][last]=holowaychuk'); +console.log(obj) + +var obj = qs.parse('a=a&a=b&a=c'); +console.log(obj) + +var obj = qs.parse('user[tj]=tj&user[tj]=TJ'); +console.log(obj) + +var obj = qs.parse('user[names]=tj&user[names]=TJ&user[names]=Tyler'); +console.log(obj) + +var obj = qs.parse('user[name][first]=tj&user[name][first]=TJ'); +console.log(obj) + +var obj = qs.parse('user[0]=tj&user[1]=TJ'); +console.log(obj) + +var obj = qs.parse('user[0]=tj&user[]=TJ'); +console.log(obj) + +var obj = qs.parse('user[0]=tj&user[foo]=TJ'); +console.log(obj) diff --git a/node_modules/express/node_modules/qs/index.js b/node_modules/express/node_modules/qs/index.js new file mode 100644 index 0000000..d177d20 --- /dev/null +++ b/node_modules/express/node_modules/qs/index.js @@ -0,0 +1,2 @@ + +module.exports = require('./lib/querystring'); \ No newline at end of file diff --git a/node_modules/express/node_modules/qs/lib/querystring.js b/node_modules/express/node_modules/qs/lib/querystring.js new file mode 100644 index 0000000..36be1b0 --- /dev/null +++ b/node_modules/express/node_modules/qs/lib/querystring.js @@ -0,0 +1,262 @@ + +/*! + * querystring + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Library version. + */ + +exports.version = '0.4.0'; + +/** + * Object#toString() ref for stringify(). + */ + +var toString = Object.prototype.toString; + +/** + * Cache non-integer test regexp. + */ + +var notint = /[^0-9]/; + +function promote(parent, key) { + if (parent[key].length == 0) return parent[key] = {}; + var t = {}; + for (var i in parent[key]) t[i] = parent[key][i]; + parent[key] = t; + return t; +} + +function parse(parts, parent, key, val) { + var part = parts.shift(); + // end + if (!part) { + if (Array.isArray(parent[key])) { + parent[key].push(val); + } else if ('object' == typeof parent[key]) { + parent[key] = val; + } else if ('undefined' == typeof parent[key]) { + parent[key] = val; + } else { + parent[key] = [parent[key], val]; + } + // array + } else { + var obj = parent[key] = parent[key] || []; + if (']' == part) { + if (Array.isArray(obj)) { + if ('' != val) obj.push(val); + } else if ('object' == typeof obj) { + obj[Object.keys(obj).length] = val; + } else { + obj = parent[key] = [parent[key], val]; + } + // prop + } else if (~part.indexOf(']')) { + part = part.substr(0, part.length - 1); + if(notint.test(part) && Array.isArray(obj)) obj = promote(parent, key); + parse(parts, obj, part, val); + // key + } else { + if(notint.test(part) && Array.isArray(obj)) obj = promote(parent, key); + parse(parts, obj, part, val); + } + } +} + +/** + * Merge parent key/val pair. + */ + +function merge(parent, key, val){ + if (~key.indexOf(']')) { + var parts = key.split('[') + , len = parts.length + , last = len - 1; + parse(parts, parent, 'base', val); + // optimize + } else { + if (notint.test(key) && Array.isArray(parent.base)) { + var t = {}; + for (var k in parent.base) t[k] = parent.base[k]; + parent.base = t; + } + set(parent.base, key, val); + } + + return parent; +} + +/** + * Parse the given obj. + */ + +function parseObject(obj){ + var ret = { base: {} }; + Object.keys(obj).forEach(function(name){ + merge(ret, name, obj[name]); + }); + return ret.base; +} + +/** + * Parse the given str. + */ + +function parseString(str){ + return String(str) + .split('&') + .reduce(function(ret, pair){ + try{ + pair = decodeURIComponent(pair.replace(/\+/g, ' ')); + } catch(e) { + // ignore + } + + var eql = pair.indexOf('=') + , brace = lastBraceInKey(pair) + , key = pair.substr(0, brace || eql) + , val = pair.substr(brace || eql, pair.length) + , val = val.substr(val.indexOf('=') + 1, val.length); + + // ?foo + if ('' == key) key = pair, val = ''; + + return merge(ret, key, val); + }, { base: {} }).base; +} + +/** + * Parse the given query `str` or `obj`, returning an object. + * + * @param {String} str | {Object} obj + * @return {Object} + * @api public + */ + +exports.parse = function(str){ + if (null == str || '' == str) return {}; + return 'object' == typeof str + ? parseObject(str) + : parseString(str); +}; + +/** + * Turn the given `obj` into a query string + * + * @param {Object} obj + * @return {String} + * @api public + */ + +var stringify = exports.stringify = function(obj, prefix) { + if (Array.isArray(obj)) { + return stringifyArray(obj, prefix); + } else if ('[object Object]' == toString.call(obj)) { + return stringifyObject(obj, prefix); + } else if ('string' == typeof obj) { + return stringifyString(obj, prefix); + } else { + return prefix; + } +}; + +/** + * Stringify the given `str`. + * + * @param {String} str + * @param {String} prefix + * @return {String} + * @api private + */ + +function stringifyString(str, prefix) { + if (!prefix) throw new TypeError('stringify expects an object'); + return prefix + '=' + encodeURIComponent(str); +} + +/** + * Stringify the given `arr`. + * + * @param {Array} arr + * @param {String} prefix + * @return {String} + * @api private + */ + +function stringifyArray(arr, prefix) { + var ret = []; + if (!prefix) throw new TypeError('stringify expects an object'); + for (var i = 0; i < arr.length; i++) { + ret.push(stringify(arr[i], prefix + '[]')); + } + return ret.join('&'); +} + +/** + * Stringify the given `obj`. + * + * @param {Object} obj + * @param {String} prefix + * @return {String} + * @api private + */ + +function stringifyObject(obj, prefix) { + var ret = [] + , keys = Object.keys(obj) + , key; + for (var i = 0, len = keys.length; i < len; ++i) { + key = keys[i]; + ret.push(stringify(obj[key], prefix + ? prefix + '[' + encodeURIComponent(key) + ']' + : encodeURIComponent(key))); + } + return ret.join('&'); +} + +/** + * Set `obj`'s `key` to `val` respecting + * the weird and wonderful syntax of a qs, + * where "foo=bar&foo=baz" becomes an array. + * + * @param {Object} obj + * @param {String} key + * @param {String} val + * @api private + */ + +function set(obj, key, val) { + var v = obj[key]; + if (undefined === v) { + obj[key] = val; + } else if (Array.isArray(v)) { + v.push(val); + } else { + obj[key] = [v, val]; + } +} + +/** + * Locate last brace in `str` within the key. + * + * @param {String} str + * @return {Number} + * @api private + */ + +function lastBraceInKey(str) { + var len = str.length + , brace + , c; + for (var i = 0; i < len; ++i) { + c = str[i]; + if (']' == c) brace = false; + if ('[' == c) brace = true; + if ('=' == c && !brace) return i; + } +} diff --git a/node_modules/express/node_modules/qs/package.json b/node_modules/express/node_modules/qs/package.json new file mode 100644 index 0000000..e04d72b --- /dev/null +++ b/node_modules/express/node_modules/qs/package.json @@ -0,0 +1,16 @@ +{ + "name": "qs", + "description": "querystring parser", + "version": "0.4.0", + "repository": { + "type" : "git", + "url" : "git://github.com/visionmedia/node-querystring.git" + }, + "devDependencies": { + "mocha": "*" + , "should": "*" + }, + "author": "TJ Holowaychuk (http://tjholowaychuk.com)", + "main": "index", + "engines": { "node": "*" } +} \ No newline at end of file diff --git a/node_modules/express/node_modules/qs/test/mocha.opts b/node_modules/express/node_modules/qs/test/mocha.opts new file mode 100644 index 0000000..521cbb2 --- /dev/null +++ b/node_modules/express/node_modules/qs/test/mocha.opts @@ -0,0 +1,2 @@ +--require should +--ui exports diff --git a/node_modules/express/node_modules/qs/test/parse.js b/node_modules/express/node_modules/qs/test/parse.js new file mode 100644 index 0000000..2a28cf3 --- /dev/null +++ b/node_modules/express/node_modules/qs/test/parse.js @@ -0,0 +1,155 @@ + +/** + * Module dependencies. + */ + +var qs = require('../'); + +module.exports = { + 'test basics': function(){ + qs.parse('0=foo').should.eql({ '0': 'foo' }); + + qs.parse('foo=c++') + .should.eql({ foo: 'c ' }); + + qs.parse('a[>=]=23') + .should.eql({ a: { '>=': '23' }}); + + qs.parse('a[<=>]==23') + .should.eql({ a: { '<=>': '=23' }}); + + qs.parse('a[==]=23') + .should.eql({ a: { '==': '23' }}); + + qs.parse('foo') + .should.eql({ foo: '' }); + + qs.parse('foo=bar') + .should.eql({ foo: 'bar' }); + + qs.parse('foo%3Dbar=baz') + .should.eql({ foo: 'bar=baz' }); + + qs.parse(' foo = bar = baz ') + .should.eql({ ' foo ': ' bar = baz ' }); + + qs.parse('foo=bar=baz') + .should.eql({ foo: 'bar=baz' }); + + qs.parse('foo=bar&bar=baz') + .should.eql({ foo: 'bar', bar: 'baz' }); + + qs.parse('foo=bar&baz') + .should.eql({ foo: 'bar', baz: '' }); + + qs.parse('cht=p3&chd=t:60,40&chs=250x100&chl=Hello|World') + .should.eql({ + cht: 'p3' + , chd: 't:60,40' + , chs: '250x100' + , chl: 'Hello|World' + }); + }, + + 'test nesting': function(){ + qs.parse('ops[>=]=25') + .should.eql({ ops: { '>=': '25' }}); + + qs.parse('user[name]=tj') + .should.eql({ user: { name: 'tj' }}); + + qs.parse('user[name][first]=tj&user[name][last]=holowaychuk') + .should.eql({ user: { name: { first: 'tj', last: 'holowaychuk' }}}); + }, + + 'test escaping': function(){ + qs.parse('foo=foo%20bar') + .should.eql({ foo: 'foo bar' }); + }, + + 'test arrays': function(){ + qs.parse('images[]') + .should.eql({ images: [] }); + + qs.parse('user[]=tj') + .should.eql({ user: ['tj'] }); + + qs.parse('user[]=tj&user[]=tobi&user[]=jane') + .should.eql({ user: ['tj', 'tobi', 'jane'] }); + + qs.parse('user[names][]=tj&user[names][]=tyler') + .should.eql({ user: { names: ['tj', 'tyler'] }}); + + qs.parse('user[names][]=tj&user[names][]=tyler&user[email]=tj@vision-media.ca') + .should.eql({ user: { names: ['tj', 'tyler'], email: 'tj@vision-media.ca' }}); + + qs.parse('items=a&items=b') + .should.eql({ items: ['a', 'b'] }); + + qs.parse('user[names]=tj&user[names]=holowaychuk&user[names]=TJ') + .should.eql({ user: { names: ['tj', 'holowaychuk', 'TJ'] }}); + + qs.parse('user[name][first]=tj&user[name][first]=TJ') + .should.eql({ user: { name: { first: ['tj', 'TJ'] }}}); + }, + + 'test right-hand brackets': function(){ + qs.parse('pets=["tobi"]') + .should.eql({ pets: '["tobi"]' }); + + qs.parse('operators=[">=", "<="]') + .should.eql({ operators: '[">=", "<="]' }); + + qs.parse('op[>=]=[1,2,3]') + .should.eql({ op: { '>=': '[1,2,3]' }}); + + qs.parse('op[>=]=[1,2,3]&op[=]=[[[[1]]]]') + .should.eql({ op: { '>=': '[1,2,3]', '=': '[[[[1]]]]' }}); + }, + + 'test duplicates': function(){ + qs.parse('items=bar&items=baz&items=raz') + .should.eql({ items: ['bar', 'baz', 'raz'] }); + }, + + 'test empty': function(){ + qs.parse('').should.eql({}); + qs.parse(undefined).should.eql({}); + qs.parse(null).should.eql({}); + }, + + 'test arrays with indexes': function(){ + qs.parse('foo[0]=bar&foo[1]=baz').should.eql({ foo: ['bar', 'baz'] }); + qs.parse('foo[1]=bar&foo[0]=baz').should.eql({ foo: ['baz', 'bar'] }); + qs.parse('foo[base64]=RAWR').should.eql({ foo: { base64: 'RAWR' }}); + qs.parse('foo[64base]=RAWR').should.eql({ foo: { '64base': 'RAWR' }}); + }, + + 'test arrays becoming objects': function(){ + qs.parse('foo[0]=bar&foo[bad]=baz').should.eql({ foo: { 0: "bar", bad: "baz" }}); + qs.parse('foo[bad]=baz&foo[0]=bar').should.eql({ foo: { 0: "bar", bad: "baz" }}); + }, + + 'test bleed-through of Array native properties/methods': function(){ + Array.prototype.protoProperty = true; + Array.prototype.protoFunction = function () {}; + qs.parse('foo=bar').should.eql({ foo: 'bar' }); + }, + + 'test malformed uri': function(){ + qs.parse('{%:%}').should.eql({ '{%:%}': '' }); + qs.parse('foo=%:%}').should.eql({ 'foo': '%:%}' }); + } + + // 'test complex': function(){ + // qs.parse('users[][name][first]=tj&users[foo]=bar') + // .should.eql({ + // users: [ { name: 'tj' }, { name: 'tobi' }, { foo: 'bar' }] + // }); + // + // qs.parse('users[][name][first]=tj&users[][name][first]=tobi') + // .should.eql({ + // users: [ { name: 'tj' }, { name: 'tobi' }] + // }); + // } +}; diff --git a/node_modules/express/node_modules/qs/test/stringify.js b/node_modules/express/node_modules/qs/test/stringify.js new file mode 100644 index 0000000..5f688d8 --- /dev/null +++ b/node_modules/express/node_modules/qs/test/stringify.js @@ -0,0 +1,95 @@ + +/** + * Module dependencies. + */ + +var qs = require('../') + , should = require('should') + , query_string_identities = { + 'basics': [ + {query_string: 'foo=bar', parsed: {'foo' : 'bar'}}, + {query_string: 'foo=%22bar%22', parsed: {'foo' : '\"bar\"'}}, + {query_string: 'foo=', parsed: {'foo': ''}}, + {query_string: 'foo=1&bar=2', parsed: {'foo' : '1', 'bar' : '2'}}, + {query_string: 'my%20weird%20field=q1!2%22\'w%245%267%2Fz8)%3F', parsed: {'my weird field': "q1!2\"'w$5&7/z8)?"}}, + {query_string: 'foo%3Dbaz=bar', parsed: {'foo=baz': 'bar'}}, + {query_string: 'foo=bar&bar=baz', parsed: {foo: 'bar', bar: 'baz'}} + ], + 'escaping': [ + {query_string: 'foo=foo%20bar', parsed: {foo: 'foo bar'}}, + {query_string: 'cht=p3&chd=t%3A60%2C40&chs=250x100&chl=Hello%7CWorld', parsed: { + cht: 'p3' + , chd: 't:60,40' + , chs: '250x100' + , chl: 'Hello|World' + }} + ], + 'nested': [ + {query_string: 'foo[]=bar&foo[]=quux', parsed: {'foo' : ['bar', 'quux']}}, + {query_string: 'foo[]=bar', parsed: {foo: ['bar']}}, + {query_string: 'foo[]=1&foo[]=2', parsed: {'foo' : ['1', '2']}}, + {query_string: 'foo=bar&baz[]=1&baz[]=2&baz[]=3', parsed: {'foo' : 'bar', 'baz' : ['1', '2', '3']}}, + {query_string: 'foo[]=bar&baz[]=1&baz[]=2&baz[]=3', parsed: {'foo' : ['bar'], 'baz' : ['1', '2', '3']}}, + {query_string: 'x[y][z]=1', parsed: {'x' : {'y' : {'z' : '1'}}}}, + {query_string: 'x[y][z][]=1', parsed: {'x' : {'y' : {'z' : ['1']}}}}, + {query_string: 'x[y][z]=2', parsed: {'x' : {'y' : {'z' : '2'}}}}, + {query_string: 'x[y][z][]=1&x[y][z][]=2', parsed: {'x' : {'y' : {'z' : ['1', '2']}}}}, + {query_string: 'x[y][][z]=1', parsed: {'x' : {'y' : [{'z' : '1'}]}}}, + {query_string: 'x[y][][z][]=1', parsed: {'x' : {'y' : [{'z' : ['1']}]}}}, + {query_string: 'x[y][][z]=1&x[y][][w]=2', parsed: {'x' : {'y' : [{'z' : '1', 'w' : '2'}]}}}, + {query_string: 'x[y][][v][w]=1', parsed: {'x' : {'y' : [{'v' : {'w' : '1'}}]}}}, + {query_string: 'x[y][][z]=1&x[y][][v][w]=2', parsed: {'x' : {'y' : [{'z' : '1', 'v' : {'w' : '2'}}]}}}, + {query_string: 'x[y][][z]=1&x[y][][z]=2', parsed: {'x' : {'y' : [{'z' : '1'}, {'z' : '2'}]}}}, + {query_string: 'x[y][][z]=1&x[y][][w]=a&x[y][][z]=2&x[y][][w]=3', parsed: {'x' : {'y' : [{'z' : '1', 'w' : 'a'}, {'z' : '2', 'w' : '3'}]}}}, + {query_string: 'user[name][first]=tj&user[name][last]=holowaychuk', parsed: { user: { name: { first: 'tj', last: 'holowaychuk' }}}} + ], + 'errors': [ + { parsed: 'foo=bar', message: 'stringify expects an object' }, + { parsed: ['foo', 'bar'], message: 'stringify expects an object' } + ] + }; + + +// Assert error +function err(fn, msg){ + var err; + try { + fn(); + } catch (e) { + should.equal(e.message, msg); + return; + } + throw new Error('no exception thrown, expected "' + msg + '"'); +} + +function test(type) { + var str, obj; + for (var i = 0; i < query_string_identities[type].length; i++) { + str = query_string_identities[type][i].query_string; + obj = query_string_identities[type][i].parsed; + qs.stringify(obj).should.eql(str); + } +} + +module.exports = { + 'test basics': function() { + test('basics'); + }, + + 'test escaping': function() { + test('escaping'); + }, + + 'test nested': function() { + test('nested'); + }, + + 'test errors': function() { + var parsed, message; + for (var i = 0; i < query_string_identities['errors'].length; i++) { + message = query_string_identities['errors'][i].message; + parsed = query_string_identities['errors'][i].parsed; + err(function(){ qs.stringify(parsed) }, message); + } + } +}; \ No newline at end of file diff --git a/node_modules/express/package.json b/node_modules/express/package.json new file mode 100644 index 0000000..b36433c --- /dev/null +++ b/node_modules/express/package.json @@ -0,0 +1,39 @@ +{ + "name": "express", + "description": "Sinatra inspired web development framework", + "version": "2.5.1", + "author": "TJ Holowaychuk ", + "contributors": [ + { "name": "TJ Holowaychuk", "email": "tj@vision-media.ca" }, + { "name": "Aaron Heckmann", "email": "aaron.heckmann+github@gmail.com" }, + { "name": "Ciaran Jessup", "email": "ciaranj@gmail.com" }, + { "name": "Guillermo Rauch", "email": "rauchg@gmail.com" } + ], + "dependencies": { + "connect": "1.8.x", + "mime": ">= 0.0.1", + "qs": ">= 0.3.1", + "mkdirp": "0.0.7" + }, + "devDependencies": { + "connect-form": "0.2.1", + "ejs": "0.4.2", + "expresso": "0.9.2", + "hamljs": "0.5.1", + "jade": "0.16.2", + "stylus": "0.13.0", + "should": "0.3.2", + "express-messages": "0.0.2", + "node-markdown": ">= 0.0.1", + "connect-redis": ">= 0.0.1" + }, + "keywords": ["framework", "sinatra", "web", "rest", "restful"], + "repository": "git://github.com/visionmedia/express", + "main": "index", + "bin": { "express": "./bin/express" }, + "scripts": { + "test": "make test", + "prepublish" : "npm prune" + }, + "engines": { "node": ">= 0.4.1 < 0.7.0" } +} \ No newline at end of file diff --git a/node_modules/express/testing/foo/app.js b/node_modules/express/testing/foo/app.js new file mode 100644 index 0000000..7574676 --- /dev/null +++ b/node_modules/express/testing/foo/app.js @@ -0,0 +1,35 @@ + +/** + * Module dependencies. + */ + +var express = require('express') + , routes = require('./routes') + +var app = module.exports = express.createServer(); + +// Configuration + +app.configure(function(){ + app.set('views', __dirname + '/views'); + app.set('view engine', 'jade'); + app.use(express.bodyParser()); + app.use(express.methodOverride()); + app.use(app.router); + app.use(express.static(__dirname + '/public')); +}); + +app.configure('development', function(){ + app.use(express.errorHandler({ dumpExceptions: true, showStack: true })); +}); + +app.configure('production', function(){ + app.use(express.errorHandler()); +}); + +// Routes + +app.get('/', routes.index); + +app.listen(3000); +console.log("Express server listening on port %d in %s mode", app.address().port, app.settings.env); diff --git a/node_modules/express/testing/foo/package.json b/node_modules/express/testing/foo/package.json new file mode 100644 index 0000000..dd54123 --- /dev/null +++ b/node_modules/express/testing/foo/package.json @@ -0,0 +1,9 @@ +{ + "name": "application-name" + , "version": "0.0.1" + , "private": true + , "dependencies": { + "express": "2.5.0" + , "jade": ">= 0.0.1" + } +} \ No newline at end of file diff --git a/node_modules/express/testing/foo/public/stylesheets/style.css b/node_modules/express/testing/foo/public/stylesheets/style.css new file mode 100644 index 0000000..30e047d --- /dev/null +++ b/node_modules/express/testing/foo/public/stylesheets/style.css @@ -0,0 +1,8 @@ +body { + padding: 50px; + font: 14px "Lucida Grande", Helvetica, Arial, sans-serif; +} + +a { + color: #00B7FF; +} \ No newline at end of file diff --git a/node_modules/express/testing/foo/routes/index.js b/node_modules/express/testing/foo/routes/index.js new file mode 100644 index 0000000..0b2205c --- /dev/null +++ b/node_modules/express/testing/foo/routes/index.js @@ -0,0 +1,10 @@ + +/* + * GET home page. + */ + +exports.index = function(req, res){ + res.writeHead(200); + req.doesnotexist(); + // res.render('index', { title: 'Express' }) +}; \ No newline at end of file diff --git a/node_modules/express/testing/foo/views/index.jade b/node_modules/express/testing/foo/views/index.jade new file mode 100644 index 0000000..c9c35fa --- /dev/null +++ b/node_modules/express/testing/foo/views/index.jade @@ -0,0 +1,2 @@ +h1= title +p Welcome to #{title} \ No newline at end of file diff --git a/node_modules/express/testing/foo/views/layout.jade b/node_modules/express/testing/foo/views/layout.jade new file mode 100644 index 0000000..1a36941 --- /dev/null +++ b/node_modules/express/testing/foo/views/layout.jade @@ -0,0 +1,6 @@ +!!! +html + head + title= title + link(rel='stylesheet', href='/stylesheets/style.css') + body!= body \ No newline at end of file diff --git a/node_modules/express/testing/index.js b/node_modules/express/testing/index.js new file mode 100644 index 0000000..3c5185d --- /dev/null +++ b/node_modules/express/testing/index.js @@ -0,0 +1,43 @@ + +/** + * Module dependencies. + */ + +var express = require('../') + , http = require('http') + , connect = require('connect'); + +var app = express.createServer(); + +app.get('/', function(req, res){ + req.foo(); + res.send('test'); +}); + +// app.set('views', __dirname + '/views'); +// app.set('view engine', 'jade'); +// +// app.configure(function(){ +// app.use(function(req, res, next){ +// debugger +// res.write('first'); +// console.error('first'); +// next(); +// }); +// +// app.use(app.router); +// +// app.use(function(req, res, next){ +// console.error('last'); +// res.end('last'); +// }); +// }); +// +// app.get('/', function(req, res, next){ +// console.error('middle'); +// res.write(' route '); +// next(); +// }); + +app.listen(3000); +console.log('listening on port 3000'); \ No newline at end of file diff --git a/node_modules/express/testing/public/test.txt b/node_modules/express/testing/public/test.txt new file mode 100644 index 0000000..cb9a165 --- /dev/null +++ b/node_modules/express/testing/public/test.txt @@ -0,0 +1,2971 @@ +foo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +bazfoo +bar +baz \ No newline at end of file diff --git a/node_modules/express/testing/views/page.html b/node_modules/express/testing/views/page.html new file mode 100644 index 0000000..4ff9827 --- /dev/null +++ b/node_modules/express/testing/views/page.html @@ -0,0 +1 @@ +p register test \ No newline at end of file diff --git a/node_modules/express/testing/views/page.jade b/node_modules/express/testing/views/page.jade new file mode 100644 index 0000000..9c3f888 --- /dev/null +++ b/node_modules/express/testing/views/page.jade @@ -0,0 +1,3 @@ +html + body + h1 test \ No newline at end of file diff --git a/node_modules/express/testing/views/test.md b/node_modules/express/testing/views/test.md new file mode 100644 index 0000000..9139ff4 --- /dev/null +++ b/node_modules/express/testing/views/test.md @@ -0,0 +1 @@ +testing _some_ markdown \ No newline at end of file diff --git a/node_modules/express/testing/views/user/index.jade b/node_modules/express/testing/views/user/index.jade new file mode 100644 index 0000000..1b66a4f --- /dev/null +++ b/node_modules/express/testing/views/user/index.jade @@ -0,0 +1 @@ +p user page \ No newline at end of file diff --git a/node_modules/express/testing/views/user/list.jade b/node_modules/express/testing/views/user/list.jade new file mode 100644 index 0000000..ed2b471 --- /dev/null +++ b/node_modules/express/testing/views/user/list.jade @@ -0,0 +1 @@ +p user list page \ No newline at end of file diff --git a/node_modules/jade/.gitignore b/node_modules/jade/.gitignore new file mode 100644 index 0000000..5eb48f0 --- /dev/null +++ b/node_modules/jade/.gitignore @@ -0,0 +1,4 @@ +.DS_Store +lib-cov +testing +node_modules diff --git a/node_modules/jade/.gitmodules b/node_modules/jade/.gitmodules new file mode 100644 index 0000000..b5b4321 --- /dev/null +++ b/node_modules/jade/.gitmodules @@ -0,0 +1,21 @@ +[submodule "support/expresso"] + path = support/expresso + url = git://github.com/visionmedia/expresso.git +[submodule "support/sass"] + path = support/sass + url = git://github.com/visionmedia/sass.js.git +[submodule "benchmarks/haml-js"] + path = benchmarks/haml-js + url = git://github.com/creationix/haml-js.git +[submodule "benchmarks/ejs"] + path = benchmarks/ejs + url = git://github.com/visionmedia/ejs.git +[submodule "benchmarks/haml"] + path = benchmarks/haml + url = git://github.com/visionmedia/haml.js.git +[submodule "support/coffee-script"] + path = support/coffee-script + url = http://github.com/jashkenas/coffee-script.git +[submodule "support/stylus"] + path = support/stylus + url = git://github.com/LearnBoost/stylus.git diff --git a/node_modules/jade/.npmignore b/node_modules/jade/.npmignore new file mode 100644 index 0000000..10fd0d4 --- /dev/null +++ b/node_modules/jade/.npmignore @@ -0,0 +1,4 @@ +test +support +benchmarks +examples diff --git a/node_modules/jade/History.md b/node_modules/jade/History.md new file mode 100644 index 0000000..c62c92a --- /dev/null +++ b/node_modules/jade/History.md @@ -0,0 +1,491 @@ + +0.18.0 / 2011-11-21 +================== + + * Changed: only ['script', 'style'] are text-only. Closes #398' + +0.17.0 / 2011-11-10 +================== + + * jade.renderFile() is back! (for express 3.x) + * Fixed `Object.keys()` failover bug + +0.16.4 / 2011-10-24 +================== + + * Fixed a test due to reserved keyword + * Fixed: commander 0.1.x dep for 0.5.x + +0.16.3 / 2011-10-24 +================== + + * Added: allow leading space for conditional comments + * Added quick implementation of a switch statement + * Fixed parens in mixin args. Closes #380 + * Fixed: include files with a .jade extension as jade files + +0.16.2 / 2011-09-30 +================== + + * Fixed include regression. Closes #354 + +0.16.1 / 2011-09-29 +================== + + * Fixed unexpected `else` bug when compileDebug: false + * Fixed attr state issue for balancing pairs. Closes #353 + +0.16.0 / 2011-09-26 +================== + + * Added `include` block support. Closes #303 + * Added template inheritance via `block` and `extends`. Closes #242 + * Added 'type="text/css"' to the style tags generated by filters. + * Added 'uglifyjs' as an explicit devDependency. + * Added -p, --path flag to jade(1) + * Added support for any arbitrary doctype + * Added `jade.render(str[,options], fn)` back + * Added first-class `while` support + * Added first-class assignment support + * Fixed runtime.js `Array.isArray()` polyfill. Closes #345 + * Fixed: set .filename option in jade(1) when passing filenames + * Fixed `Object.keys()` polyfill typo. Closes #331 + * Fixed `include` error context + * Renamed magic "index" to "$index". Closes #350 + +0.15.4 / 2011-09-05 +================== + + * Fixed script template html. Closes #316 + * Revert "Fixed script() tag with trailing ".". Closes #314" + +0.15.3 / 2011-08-30 +================== + + * Added Makefile example. Closes #312 + * Fixed script() tag with trailing ".". Closes #314 + +0.15.2 / 2011-08-26 +================== + + * Fixed new conditional boundaries. Closes #307 + +0.15.1 / 2011-08-26 +================== + + * Fixed jade(1) support due to `res.render()` removal + * Removed --watch support (use a makefile + watch...) + +0.15.0 / 2011-08-26 +================== + + * Added `client` option to reference runtime helpers + * Added `Array.isArray()` for runtime.js as well + * Added `Object.keys()` for the client-side runtime + * Added first-class `if`, `unless`, `else` and `else if` support + * Added first-class `each` / `for` support + * Added `make benchmark` for continuous-bench + * Removed `inline` option, SS helpers are no longer inlined either + * Removed `Parser#debug()` + * Removed `jade.render()` and `jade.renderFile()` + * Fixed runtime.js `escape()` bug causing window.escape to be used + * Fixed a bunch of tests + +0.14.2 / 2011-08-16 +================== + + * Added `include` support for non-jade files + * Fixed code indentation when followed by newline(s). Closes #295 [reported by masylum] + +0.14.1 / 2011-08-14 +================== + + * Added `colons` option for everyone stuck with ":". Closes #231 + * Optimization: consecutive lines are merged in compiled js + +0.14.0 / 2011-08-08 +================== + + * Added array iteration with index example. Closes #276 + * Added _runtime.js_ + * Added `compileDebug` option to enable lineno instrumentation + * Added `inline` option to disable inlining of helpers (for client-side) + +0.13.0 / 2011-07-13 +================== + + * Added `mixin` support + * Added `include` support + * Added array support for the class attribute + +0.12.4 / 2011-06-23 +================== + + * Fixed filter indentation bug. Closes #243 + +0.12.3 / 2011-06-21 +================== + + * Fixed empty strings support. Closes #223 + * Fixed conditional comments documentation. Closes #245 + +0.12.2 / 2011-06-16 +================== + + * Fixed `make test` + * Fixed block comments + +0.12.1 / 2011-06-04 +================== + + * Fixed attribute interpolation with double quotes. Fixes #232 [topaxi] + +0.12.0 / 2011-06-03 +================== + + * Added `doctype` as alias of `!!!` + * Added; doctype value is now case-insensitive + * Added attribute interpolation support + * Fixed; retain original indentation spaces in text blocks + +0.11.1 / 2011-06-01 +================== + + * Fixed text block indentation [Laszlo Bacsi] + * Changed; utilizing devDependencies + * Fixed try/catch issue with renderFile(). Closes #227 + * Removed attribute ":" support, use "=" (option for ':' coming soon) + +0.11.0 / 2011-05-14 +================== + + * Added `self` object to avoid poor `with(){}` performance [masylum] + * Added `doctype` option [Jeremy Larkin] + +0.10.7 / 2011-05-04 +================== + + * expose Parser + +0.10.6 / 2011-04-29 +================== + + * Fixed CS `Object.keys()` [reported by robholland] + +0.10.5 / 2011-04-26 +================== + + * Added error context after the lineno + * Added; indicate failing lineno with ">" + * Added `Object.keys()` for the client-side + * Fixed attr strings when containing the opposite quote. Closes 207 + * Fixed attr issue with js expressions within strings + * Fixed single-quote filter escape bug. Closes #196 + + +0.10.4 / 2011-04-05 +================== + + * Added `html` doctype, same as "5" + * Fixed `pre`, no longer text-only + +0.10.3 / 2011-03-30 +================== + + * Fixed support for quoted attribute keys ex `rss("xmlns:atom"="atom")` + +0.10.2 / 2011-03-30 +================== + + * Fixed pipeless text bug with missing outdent + +0.10.1 / 2011-03-28 +================== + + * Fixed `support/compile.js` to exclude browser js in node + * Fixes for IE [Patrick Pfeiffer] + +0.10.0 / 2011-03-25 +================== + + * Added AST-filter support back in the form of `[attrs]<:>` + +0.9.3 / 2011-03-24 +================== + + * Added `Block#unshift(node)` + * Added `jade.js` for the client-side to the repo + * Added `jade.min.js` for the client-side to the repo + * Removed need for pipes in filters. Closes #185 + Note that this _will_ break filters used to + manipulate the AST, until we have a different + syntax for doing so. + +0.9.2 / 2011-03-23 +================== + + * Added jade `--version` + * Removed `${}` interpolation support, use `#{}` + +0.9.1 / 2011-03-16 +================== + + * Fixed invalid `.map()` call due to recent changes + +0.9.0 / 2011-03-16 +================== + + * Added client-side browser support via `make jade.js` and `make jade.min.js`. + +0.8.9 / 2011-03-15 +================== + + * Fixed preservation of newlines in text blocks + +0.8.8 / 2011-03-14 +================== + + * Fixed jade(1) stdio + +0.8.7 / 2011-03-14 +================== + + * Added `mkdirs()` to jade(1) + * Added jade(1) stdio support + * Added new features to jade(1), `--watch`, recursive compilation etc [khingebjerg] + * Fixed pipe-less text newlines + * Removed jade(1) `--pipe` flag + +0.8.6 / 2011-03-11 +================== + + * Fixed parenthesized expressions in attrs. Closes #170 + * Changed; default interpolation values `== null` to ''. Closes #167 + +0.8.5 / 2011-03-09 +================== + + * Added pipe-less text support with immediate ".". Closes #157 + * Fixed object support in attrs + * Fixed array support for attrs + +0.8.4 / 2011-03-08 +================== + + * Fixed issue with expressions being evaluated several times. closes #162 + +0.8.2 / 2011-03-07 +================== + + * Added markdown, discount, and markdown-js support to `:markdown`. Closes #160 + * Removed `:discount` + +0.8.1 / 2011-03-04 +================== + + * Added `pre` pipe-less text support (and auto-escaping) + +0.8.0 / 2011-03-04 +================== + + * Added block-expansion support. Closes #74 + * Added support for multi-line attrs without commas. Closes #65 + +0.7.1 / 2011-03-04 +================== + + * Fixed `script()` etc pipe-less text with attrs + +0.7.0 / 2011-03-04 +================== + + * Removed `:javascript` filter (it doesn't really do anything special, use `script` tags) + * Added pipe-less text support. Tags that only accept text nodes (`script`, `textarea`, etc) do not require `|`. + * Added `:text` filter for ad-hoc pipe-less + * Added flexible indentation. Tabs, arbitrary number of spaces etc + * Added conditional-comment support. Closes #146 + * Added block comment support + * Added rss example + * Added `:stylus` filter + * Added `:discount` filter + * Fixed; auto-detect xml and do not self-close tags. Closes #147 + * Fixed whitespace issue. Closes #118 + * Fixed attrs. `,`, `=`, and `:` within attr value strings are valid Closes #133 + * Fixed; only output "" when code == null. Ex: `span.name= user.name` when undefined or null will not output "undefined". Closes #130 + * Fixed; throw on unexpected token instead of hanging + +0.6.3 / 2011-02-02 +================== + + * Added `each` support for Array-like objects [guillermo] + +0.6.2 / 2011-02-02 +================== + + * Added CSRF example, showing how you can transparently add inputs to a form + * Added link to vim-jade + * Fixed self-closing col support [guillermo] + * Fixed exception when getAttribute or removeAttribute run into removed attributes [Naitik Shah] + +0.6.0 / 2010-12-19 +================== + + * Added unescaped interpolation variant `!{code}`. Closes #124 + * Changed; escape interpolated code by default `#{code}` + +0.5.7 / 2010-12-08 +================== + + * Fixed; hyphen in get `tag()` + +0.5.6 / 2010-11-24 +================== + + * Added `exports.compile(str, options)` + * Renamed internal `_` to `__`, since `_()` is commonly used for translation + +0.5.5 / 2010-10-30 +================== + + * Add _coffeescript_ filter [Michael Hampton] + * Added link to _slim_; a ruby implementation + * Fixed quoted attributes issue. + + * Fixed attribute issue with over greedy regexp. + Previously "p(foo=(((('bar')))))= ((('baz')))" + would __fail__ for example since the regexp + would lookahead to far. Now we simply pair + the delimiters. + +0.5.4 / 2010-10-18 +================== + + * Adding newline when using tag code when preceding text + * Assume newline in tag text when preceding text + * Changed; retain leading text whitespace + * Fixed code block support to prevent multiple buffer openings [Jake Luer] + * Fixed nested filter support + +0.5.3 / 2010-10-06 +================== + + * Fixed bug when tags with code also have a block [reported by chrisirhc] + +0.5.2 / 2010-10-05 +================== + + * Added; Text introduces newlines to mimic the grammar. + Whitespace handling is a little tricky with this sort of grammar. + Jade will now mimic the written grammar, meaning that text blocks + using the "|" margin character will introduce a literal newline, + where as immediate tag text (ex "a(href='#') Link") will not. + + This may not be ideal, but it makes more sense than what Jade was + previously doing. + + * Added `Tag#text` to disambiguate between immediate / block text + * Removed _pretty_ option (was kinda useless in the state it was in) + * Reverted ignoring of newlines. Closes #92. + * Fixed; `Parser#parse()` ignoring newlines + +0.5.1 / 2010-10-04 +================== + + * Added many examples + * Added; compiler api is now public + * Added; filters can accept / manipulate the parse tree + * Added filter attribute support. Closes #79 + * Added LL(*) capabilities + * Performance; wrapping code blocks in {} instead of `(function(){}).call(this)` + * Performance; Optimized attribute buffering + * Fixed trailing newlines in blocks + +0.5.0 / 2010-09-11 +================== + + * __Major__ refactor. Logic now separated into lexer/parser/compiler for future extensibility. + * Added _pretty_ option + * Added parse tree output for _debug_ option + * Added new examples + * Removed _context_ option, use _scope_ + +0.4.1 / 2010-09-09 +================== + + * Added support for arbitrary indentation for single-line comments. Closes #71 + * Only strip first space in text (ex '| foo' will buffer ' foo') + +0.4.0 / 2010-08-30 +================== + + * Added tab naive support (tabs are converted to a single indent, aka two spaces). Closes #24 + * Added unbuffered comment support. Closes #62 + * Added hyphen support for tag names, ex: "fb:foo-bar" + * Fixed bug with single quotes in comments. Closes #61 + * Fixed comment whitespace issue, previously padding. Closes #55 + +0.3.0 / 2010-08-04 +================== + + * Added single line comment support. Closes #25 + * Removed CDATA from _:javascript_ filter. Closes #47 + * Removed _sys_ local + * Fixed code following tag + +0.2.4 / 2010-08-02 +================== + + * Added Buffer support to `render()` + * Fixed filter text block exception reporting + * Fixed tag exception reporting + +0.2.3 / 2010-07-27 +================== + + * Fixed newlines before block + * Fixed; tag text allowing arbitrary trailing whitespace + +0.2.2 / 2010-07-16 +================== + + * Added support for `jade.renderFile()` to utilize primed cache + * Added link to [textmate bundle](http://github.com/miksago/jade-tmbundle) + * Fixed filter issue with single quotes + * Fixed hyphenated attr bug + * Fixed interpolation single quotes. Closes #28 + * Fixed issue with comma in attrs + +0.2.1 / 2010-07-09 +================== + + * Added support for node-discount and markdown-js + depending on which is available. + + * Added support for tags to have blocks _and_ text. + this kinda fucks with arbitrary whitespace unfortunately, + but also fixes trailing spaces after tags _with_ blocks. + + * Caching generated functions. Closes #46 + +0.2.0 / 2010-07-08 +================== + + * Added `- each` support for readable iteration + * Added [markdown-js](http://github.com/evilstreak/markdown-js) support (no compilation required) + * Removed node-discount support + +0.1.0 / 2010-07-05 +================== + + * Added `${}` support for interpolation. Closes #45 + * Added support for quoted attr keys: `label("for": 'something')` is allowed (_although not required_) [Guillermo] + * Added `:less` filter [jakeluer] + +0.0.2 / 2010-07-03 +================== + + * Added `context` as synonym for `scope` option [Guillermo] + * Fixed attr splitting: `div(style:"color: red")` is now allowed + * Fixed issue with `(` and `)` within attrs: `a(class: (a ? 'a' : 'b'))` is now allowed + * Fixed issue with leading / trailing spaces in attrs: `a( href="#" )` is now allowed [Guillermo] + diff --git a/node_modules/jade/LICENSE b/node_modules/jade/LICENSE new file mode 100644 index 0000000..8ad0e0d --- /dev/null +++ b/node_modules/jade/LICENSE @@ -0,0 +1,22 @@ +(The MIT License) + +Copyright (c) 2009-2010 TJ Holowaychuk + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/node_modules/jade/Makefile b/node_modules/jade/Makefile new file mode 100644 index 0000000..356582b --- /dev/null +++ b/node_modules/jade/Makefile @@ -0,0 +1,37 @@ + +TESTS = test/*.js +SRC = $(shell find lib -name "*.js" -type f) +UGLIFY = $(shell find node_modules -name "uglifyjs" -type f) +UGLIFY_FLAGS = --no-mangle + +all: jade.min.js runtime.min.js + +test: + @./node_modules/.bin/expresso $(TESTS) + +benchmark: + @node support/benchmark + +jade.js: $(SRC) + @node support/compile.js $^ + +jade.min.js: jade.js + @$(UGLIFY) $(UGLIFY_FLAGS) $< > $@ \ + && du jade.min.js \ + && du jade.js + +runtime.js: lib/runtime.js + @cat support/head.js $< support/foot.js > $@ + +runtime.min.js: runtime.js + @$(UGLIFY) $(UGLIFY_FLAGS) $< > $@ \ + && du runtime.min.js \ + && du runtime.js + +clean: + rm -f jade.js + rm -f jade.min.js + rm -f runtime.js + rm -f runtime.min.js + +.PHONY: test benchmark clean diff --git a/node_modules/jade/Readme.md b/node_modules/jade/Readme.md new file mode 100644 index 0000000..c256592 --- /dev/null +++ b/node_modules/jade/Readme.md @@ -0,0 +1,966 @@ +# Jade - template engine + + Jade is a high performance template engine heavily influenced by [Haml](http://haml-lang.com) + and implemented with JavaScript for [node](http://nodejs.org). + +## Features + + - client-side support + - great readability + - flexible indentation + - block-expansion + - mixins + - static includes + - attribute interpolation + - code is escaped by default for security + - contextual error reporting at compile & run time + - executable for compiling jade templates via the command line + - html 5 mode (using the _!!! 5_ doctype) + - optional memory caching + - combine dynamic and static tag classes + - parse tree manipulation via _filters_ + - template inheritance + - supports [Express JS](http://expressjs.com) out of the box + - transparent iteration over objects, arrays, and even non-enumerables via `each` + - block comments + - no tag prefix + - AST filters + - filters + - :stylus must have [stylus](http://github.com/LearnBoost/stylus) installed + - :sass must have [sass.js](http://github.com/visionmedia/sass.js) installed + - :less must have [less.js](http://github.com/cloudhead/less.js) installed + - :markdown must have [markdown-js](http://github.com/evilstreak/markdown-js) installed or [node-discount](http://github.com/visionmedia/node-discount) + - :cdata + - :coffeescript must have [coffee-script](http://jashkenas.github.com/coffee-script/) installed + - [Vim Syntax](https://github.com/digitaltoad/vim-jade) + - [TextMate Bundle](http://github.com/miksago/jade-tmbundle) + - [Screencasts](http://tjholowaychuk.com/post/1004255394/jade-screencast-template-engine-for-nodejs) + - [html2jade](https://github.com/donpark/html2jade) converter + +## Implementations + + - [php](http://github.com/everzet/jade.php) + - [scala](http://scalate.fusesource.org/versions/snapshot/documentation/scaml-reference.html) + - [ruby](http://github.com/stonean/slim) + +## Installation + +via npm: + + npm install jade + +## Browser Support + + To compile jade to a single file compatible for client-side use simply execute: + + $ make jade.js + + Alternatively, if uglifyjs is installed via npm (`npm install uglify-js`) you may execute the following which will create both files. However each release builds these for you. + + $ make jade.min.js + + By default Jade instruments templates with line number statements such as `__.lineno = 3` for debugging purposes. When used in a browser it's useful to minimize this boiler plate, you can do so by passing the option `{ compileDebug: false }`. The following template + + p Hello #{name} + + Can then be as small as the following generated function: + +```js +function anonymous(locals, attrs, escape, rethrow) { + var buf = []; + with (locals || {}) { + var interp; + buf.push('\n

    Hello ' + escape((interp = name) == null ? '' : interp) + '\n

    '); + } + return buf.join(""); +} +``` + + Through the use of Jade's `./runtime.js` you may utilize these pre-compiled templates on the client-side _without_ Jade itself, all you need is the associated utility functions (in runtime.js), which are then available as `jade.attrs`, `jade.escape` etc. To enable this you should pass `{ client: true }` to `jade.compile()` to tell Jade to reference the helper functions + via `jade.attrs`, `jade.escape` etc. + +```js +function anonymous(locals, attrs, escape, rethrow) { + var attrs = jade.attrs, escape = jade.escape, rethrow = jade.rethrow; + var buf = []; + with (locals || {}) { + var interp; + buf.push('\n

    Hello ' + escape((interp = name) == null ? '' : interp) + '\n

    '); + } + return buf.join(""); +} +``` + +## Public API + +```javascript + var jade = require('jade'); + + // Compile a function + var fn = jade.compile('string of jade', options); + fn(locals); +``` + +### Options + + - `self` Use a `self` namespace to hold the locals. _false by default_ + - `locals` Local variable object + - `filename` Used in exceptions, and required when using includes + - `debug` Outputs tokens and function body generated + - `compiler` Compiler to replace jade's default + - `compileDebug` When `false` no debug instrumentation is compiled + +## Syntax + +### Line Endings + +**CRLF** and **CR** are converted to **LF** before parsing. + +### Tags + +A tag is simply a leading word: + + html + +for example is converted to `` + +tags can also have ids: + + div#container + +which would render `
    ` + +how about some classes? + + div.user-details + +renders `
    ` + +multiple classes? _and_ an id? sure: + + div#foo.bar.baz + +renders `
    ` + +div div div sure is annoying, how about: + + #foo + .bar + +which is syntactic sugar for what we have already been doing, and outputs: + + `
    ` + +### Tag Text + +Simply place some content after the tag: + + p wahoo! + +renders `

    wahoo!

    `. + +well cool, but how about large bodies of text: + + p + | foo bar baz + | rawr rawr + | super cool + | go jade go + +renders `

    foo bar baz rawr.....

    ` + +interpolation? yup! both types of text can utilize interpolation, +if we passed `{ name: 'tj', email: 'tj@vision-media.ca' }` to the compiled function we can do the following: + + #user #{name} <#{email}> + +outputs `
    tj <tj@vision-media.ca>
    ` + +Actually want `#{}` for some reason? escape it! + + p \#{something} + +now we have `

    #{something}

    ` + +We can also utilize the unescaped variant `!{html}`, so the following +will result in a literal script tag: + + - var html = "" + | !{html} + +Nested tags that also contain text can optionally use a text block: + + label + | Username: + input(name='user[name]') + +or immediate tag text: + + label Username: + input(name='user[name]') + +Tags that accept _only_ text such as `script` and `style` do not +need the leading `|` character, for example: + + html + head + title Example + script + if (foo) { + bar(); + } else { + baz(); + } + +Once again as an alternative, we may use a trailing '.' to indicate a text block, for example: + + p. + foo asdf + asdf + asdfasdfaf + asdf + asd. + +outputs: + +

    foo asdf + asdf + asdfasdfaf + asdf + asd + . +

    + +This however differs from a trailing '.' followed by a space, which although is ignored by the Jade parser, tells Jade that this period is a literal: + + p . + +outputs: + +

    .

    + + +It should be noted that text blocks should be doubled escaped. For example if you desire the following output. + +

    foo\bar

    + +use: + + p. + foo\\bar + +### Comments + +Single line comments currently look the same as JavaScript comments, +aka "//" and must be placed on their own line: + + // just some paragraphs + p foo + p bar + +would output + + +

    foo

    +

    bar

    + +Jade also supports unbuffered comments, by simply adding a hyphen: + + //- will not output within markup + p foo + p bar + +outputting + +

    foo

    +

    bar

    + +### Block Comments + + A block comment is legal as well: + + body + // + #content + h1 Example + +outputting + + + + + +Jade supports conditional-comments as well, for example: + + head + //if lt IE 8 + script(src='/ie-sucks.js') + +outputs: + + + + + + +### Nesting + + Jade supports nesting to define the tags in a natural way: + + ul + li.first + a(href='#') foo + li + a(href='#') bar + li.last + a(href='#') baz + +### Block Expansion + + Block expansion allows you to create terse single-line nested tags, + the following example is equivalent to the nesting example above. + + ul + li.first: a(href='#') foo + li: a(href='#') bar + li.last: a(href='#') baz + + +### Attributes + +Jade currently supports '(' and ')' as attribute delimiters. + + a(href='/login', title='View login page') Login + +When a value is `undefined` or `null` the attribute is _not_ added, +so this is fine, it will not compile 'something="null"'. + + div(something=null) + +Boolean attributes are also supported: + + input(type="checkbox", checked) + +Boolean attributes with code will only output the attribute when `true`: + + input(type="checkbox", checked=someValue) + +Multiple lines work too: + + input(type='checkbox', + name='agreement', + checked) + +Multiple lines without the comma work fine: + + input(type='checkbox' + name='agreement' + checked) + +Funky whitespace? fine: + + + input( + type='checkbox' + name='agreement' + checked) + +Colons work: + + rss(xmlns:atom="atom") + +Suppose we have the `user` local `{ id: 12, name: 'tobi' }` +and we wish to create an anchor tag with `href` pointing to "/user/12" +we could use regular javascript concatenation: + + a(href='/user/' + user.id)= user.name + +or we could use jade's interpolation, which I added because everyone +using Ruby or CoffeeScript seems to think this is legal js..: + + a(href='/user/#{user.id}')= user.name + +The `class` attribute is special-cased when an array is given, +allowing you to pass an array such as `bodyClasses = ['user', 'authenticated']` directly: + + body(class=bodyClasses) + +### HTML + + Inline html is fine, we can use the pipe syntax to + write arbitrary text, in this case some html: + +``` +html + body + |

    Title

    + |

    foo bar baz

    +``` + + Or we can use the trailing `.` to indicate to Jade that we + only want text in this block, allowing us to omit the pipes: + +``` +html + body. +

    Title

    +

    foo bar baz

    +``` + + Both of these examples yield the same result: + +``` +

    Title

    +

    foo bar baz

    + +``` + + The same rule applies for anywhere you can have text + in jade, raw html is fine: + +``` +html + body + h1 User #{name} +``` + +### Doctypes + +To add a doctype simply use `!!!`, or `doctype` followed by an optional value: + + !!! + +Will output the _transitional_ doctype, however: + + !!! 5 + +or + + !!! html + +or + + doctype html + +doctypes are case-insensitive, so the following are equivalent: + + doctype Basic + doctype basic + +it's also possible to simply pass a doctype literal: + + doctype html PUBLIC "-//W3C//DTD XHTML Basic 1.1//EN + +yielding: + + + +Will output the _html 5_ doctype. Below are the doctypes +defined by default, which can easily be extended: + +```javascript + var doctypes = exports.doctypes = { + '5': '', + 'xml': '', + 'default': '', + 'transitional': '', + 'strict': '', + 'frameset': '', + '1.1': '', + 'basic': '', + 'mobile': '' + }; +``` + +To alter the default simply change: + +```javascript + jade.doctypes.default = 'whatever you want'; +``` + +## Filters + +Filters are prefixed with `:`, for example `:markdown` and +pass the following block of text to an arbitrary function for processing. View the _features_ +at the top of this document for available filters. + + body + :markdown + Woah! jade _and_ markdown, very **cool** + we can even link to [stuff](http://google.com) + +Renders: + +

    Woah! jade and markdown, very cool we can even link to stuff

    + +## Code + +Jade currently supports three classifications of executable code. The first +is prefixed by `-`, and is not buffered: + + - var foo = 'bar'; + +This can be used for conditionals, or iteration: + + - for (var key in obj) + p= obj[key] + +Due to Jade's buffering techniques the following is valid as well: + + - if (foo) + ul + li yay + li foo + li worked + - else + p oh no! didnt work + +Hell, even verbose iteration: + + - if (items.length) + ul + - items.forEach(function(item){ + li= item + - }) + +Anything you want! + +Next up we have _escaped_ buffered code, which is used to +buffer a return value, which is prefixed by `=`: + + - var foo = 'bar' + = foo + h1= foo + +Which outputs `bar

    bar

    `. Code buffered by `=` is escaped +by default for security, however to output unescaped return values +you may use `!=`: + + p!= aVarContainingMoreHTML + + Jade also has designer-friendly variants, making the literal JavaScript + more expressive and declarative. For example the following assignments + are equivalent, and the expression is still regular javascript: + + - var foo = 'foo ' + 'bar' + foo = 'foo ' + 'bar' + + Likewise Jade has first-class `if`, `else if`, `else`, `until`, `while`, `unless` among others, however you must remember that the expressions are still regular javascript: + + if foo == 'bar' + ul + li yay + li foo + li worked + else + p oh no! didnt work + +## Iteration + + Along with vanilla JavaScript Jade also supports a subset of + constructs that allow you to create more designer-friendly templates, + one of these constructs is `each`, taking the form: + + each VAL[, KEY] in OBJ + +An example iterating over an array: + + - var items = ["one", "two", "three"] + each item in items + li= item + +outputs: + +
  • one
  • +
  • two
  • +
  • three
  • + +iterating an array with index: + + items = ["one", "two", "three"] + each item, i in items + li #{item}: #{i} + +outputs: + +
  • one: 0
  • +
  • two: 1
  • +
  • three: 2
  • + +iterating an object's keys and values: + + obj = { foo: 'bar' } + each val, key in obj + li #{key}: #{val} + +would output `
  • foo: bar
  • ` + +Internally Jade converts these statements to regular +JavaScript loops such as `users.forEach(function(user){`, +so lexical scope and nesting applies as it would with regular +JavaScript: + + each user in users + each role in user.roles + li= role + + You may also use `for` if you prefer: + + for user in users + for role in user.roles + li= role + +## Conditionals + + Jade conditionals are equivalent to those using the code (`-`) prefix, + however allow you to ditch parenthesis to become more designer friendly, + however keep in mind the expression given is _regular_ JavaScript: + + for user in users + if user.role == 'admin' + p #{user.name} is an admin + else + p= user.name + + is equivalent to the following using vanilla JavaScript literals: + + for user in users + - if (user.role == 'admin') + p #{user.name} is an admin + - else + p= user.name + + Jade also provides have `unless` which is equivalent to `if (!(expr))`: + + for user in users + unless user.isAnonymous + p + | Click to view + a(href='/users/' + user.id)= user.name + +## Template inheritance + + Jade supports template inheritance via the `block` and `extends` keywords. A block is simply a "block" of Jade that may be replaced within a child template, this process is recursive. + + Jade blocks can provide default content if desired, however optional as shown below by `block scripts`, `block content`, and `block foot`. + +``` +html + head + h1 My Site - #{title} + block scripts + script(src='/jquery.js') + body + block content + block foot + #footer + p some footer content +``` + + Now to extend the layout, simply create a new file and use the `extends` directive as shown below, giving the path (with or without the .jade extension). You may now define one or more blocks that will override the parent block content, note that here the `foot` block is _not_ redefined and will output "some footer content". + +``` +extends extend-layout + +block scripts + script(src='/jquery.js') + script(src='/pets.js') + +block content + h1= title + each pet in pets + include pet +``` + + It's also possible to override a block to provide additional blocks, as shown in the following example where `content` now exposes a `sidebar` and `primary` block for overriding, or the child template could override `content` all together. + +``` +extends regular-layout + +block content + .sidebar + block sidebar + p nothing + .primary + block primary + p nothing +``` + +## Includes + + Includes allow you to statically include chunks of Jade, + or other content like css, or html which lives in separate files. The classical example is including a header and footer. Suppose we have the following directory structure: + + ./layout.jade + ./includes/ + ./head.jade + ./tail.jade + +and the following _layout.jade_: + + html + include includes/head + body + h1 My Site + p Welcome to my super amazing site. + include includes/foot + +both includes _includes/head_ and _includes/foot_ are +read relative to the `filename` option given to _layout.jade_, +which should be an absolute path to this file, however Express does this for you. Include then parses these files, and injects the AST produced to render what you would expect: + +```html + + + My Site + + + +

    My Site

    +

    Welcome to my super lame site.

    + + + +``` + + As mentioned `include` can be used to include other content + such as html or css. By providing an extension Jade will not + assume that the file is Jade source and will include it as + a literal: + +``` +html + body + include content.html +``` + + Include directives may also accept a block, in which case the + the given block will be appended to the _last_ block defined + in the file. For example if `head.jade` contains: + +``` +head + script(src='/jquery.js') +``` + + We may append values by providing a block to `include head` + as shown below, adding the two scripts. + +``` +html + include head + script(src='/foo.js') + script(src='/bar.js') + body + h1 test +``` + + +## Mixins + + Mixins are converted to regular JavaScript functions in + the compiled template that Jade constructs. Mixins may + take arguments, though not required: + + mixin list + ul + li foo + li bar + li baz + + Utilizing a mixin without args looks similar, just without a block: + + h2 Groceries + mixin list + + Mixins may take one or more arguments as well, the arguments + are regular javascripts expressions, so for example the following: + + mixin pets(pets) + ul.pets + - each pet in pets + li= pet + + mixin profile(user) + .user + h2= user.name + mixin pets(user.pets) + + Would yield something similar to the following html: + +```html +
    +

    tj

    +
      +
    • tobi
    • +
    • loki
    • +
    • jane
    • +
    • manny
    • +
    +
    +``` + +## Generated Output + + Suppose we have the following Jade: + +``` +- var title = 'yay' +h1.title #{title} +p Just an example +``` + + When the `compileDebug` option is not explicitly `false`, Jade + will compile the function instrumented with `__.lineno = n;`, which + in the event of an exception is passed to `rethrow()` which constructs + a useful message relative to the initial Jade input. + +```js +function anonymous(locals) { + var __ = { lineno: 1, input: "- var title = 'yay'\nh1.title #{title}\np Just an example", filename: "testing/test.js" }; + var rethrow = jade.rethrow; + try { + var attrs = jade.attrs, escape = jade.escape; + var buf = []; + with (locals || {}) { + var interp; + __.lineno = 1; + var title = 'yay' + __.lineno = 2; + buf.push(''); + buf.push('' + escape((interp = title) == null ? '' : interp) + ''); + buf.push(''); + __.lineno = 3; + buf.push('

    '); + buf.push('Just an example'); + buf.push('

    '); + } + return buf.join(""); + } catch (err) { + rethrow(err, __.input, __.filename, __.lineno); + } +} +``` + +When the `compileDebug` option _is_ explicitly `false`, this instrumentation +is stripped, which is very helpful for light-weight client-side templates. Combining Jade's options with the `./runtime.js` file in this repo allows you +to toString() compiled templates and avoid running the entire Jade library on +the client, increasing performance, and decreasing the amount of JavaScript +required. + +```js +function anonymous(locals) { + var attrs = jade.attrs, escape = jade.escape; + var buf = []; + with (locals || {}) { + var interp; + var title = 'yay' + buf.push(''); + buf.push('' + escape((interp = title) == null ? '' : interp) + ''); + buf.push(''); + buf.push('

    '); + buf.push('Just an example'); + buf.push('

    '); + } + return buf.join(""); +} +``` + +## Example Makefile + + Below is an example Makefile used to compile _pages/*.jade_ + into _pages/*.html_ files by simply executing `make`. + +```make +JADE = $(shell find pages/*.jade) +HTML = $(JADE:.jade=.html) + +all: $(HTML) + +%.html: %.jade + jade < $< --path $< > $@ + +clean: + rm -f $(HTML) + +.PHONY: clean +``` + +this can be combined with the `watch(1)` command to produce +a watcher-like behaviour: + + $ watch make + +## jade(1) + +``` + +Usage: jade [options] [dir|file ...] + +Options: + + -h, --help output usage information + -v, --version output the version number + -o, --obj javascript options object + -O, --out output the compiled html to + -p, --path filename used to resolve includes over stdio + +Examples: + + # translate jade the templates dir + $ jade templates + + # create {foo,bar}.html + $ jade {foo,bar}.jade + + # jade over stdio + $ jade < my.jade > my.html + + # jade over stdio specifying filename to resolve include directives + $ jade < my.jade -p my.jade > my.html + + # jade over stdio + $ echo "h1 Jade!" | jade + + # foo, bar dirs rendering to /tmp + $ jade foo bar --out /tmp + +``` + +## License + +(The MIT License) + +Copyright (c) 2009-2010 TJ Holowaychuk <tj@vision-media.ca> + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/jade/bin/jade b/node_modules/jade/bin/jade new file mode 100755 index 0000000..fd4122c --- /dev/null +++ b/node_modules/jade/bin/jade @@ -0,0 +1,125 @@ +#!/usr/bin/env node + +/** + * Module dependencies. + */ + +var fs = require('fs') + , program = require('commander') + , path = require('path') + , basename = path.basename + , dirname = path.dirname + , resolve = path.resolve + , join = path.join + , mkdirp = require('mkdirp') + , jade = require('../'); + +// jade options + +var options = {}; + +// options + +program + .version(jade.version) + .usage('[options] [dir|file ...]') + .option('-o, --obj ', 'javascript options object') + .option('-O, --out ', 'output the compiled html to ') + .option('-p, --path ', 'filename used to resolve includes') + +program.on('--help', function(){ + console.log(' Examples:'); + console.log(''); + console.log(' # translate jade the templates dir'); + console.log(' $ jade templates'); + console.log(''); + console.log(' # create {foo,bar}.html'); + console.log(' $ jade {foo,bar}.jade'); + console.log(''); + console.log(' # jade over stdio'); + console.log(' $ jade < my.jade > my.html'); + console.log(''); + console.log(' # jade over stdio'); + console.log(' $ echo "h1 Jade!" | jade'); + console.log(''); + console.log(' # foo, bar dirs rendering to /tmp'); + console.log(' $ jade foo bar --out /tmp '); + console.log(''); +}); + +program.parse(process.argv); + +// options given, parse them + +if (program.obj) options = eval('(' + program.obj + ')'); + +// filename + +if (program.path) options.filename = program.path; + +// left-over args are file paths + +var files = program.args; + +// compile files + +if (files.length) { + console.log(); + files.forEach(renderFile); + process.on('exit', console.log); +// stdio +} else { + stdin(); +} + +/** + * Compile from stdin. + */ + +function stdin() { + var buf = ''; + process.stdin.setEncoding('utf8'); + process.stdin.on('data', function(chunk){ buf += chunk; }); + process.stdin.on('end', function(){ + var fn = jade.compile(buf, options); + process.stdout.write(fn(options)); + }).resume(); +} + +/** + * Process the given path, compiling the jade files found. + * Always walk the subdirectories. + */ + +function renderFile(path) { + var re = /\.jade$/; + fs.lstat(path, function(err, stat) { + if (err) throw err; + // Found jade file + if (stat.isFile() && re.test(path)) { + fs.readFile(path, 'utf8', function(err, str){ + if (err) throw err; + options.filename = path; + var fn = jade.compile(str, options); + path = path.replace(re, '.html'); + if (program.out) path = join(program.out, basename(path)); + var dir = resolve(dirname(path)); + mkdirp(dir, 0755, function(err){ + if (err) throw err; + fs.writeFile(path, fn(options), function(err){ + if (err) throw err; + console.log(' \033[90mrendered \033[36m%s\033[0m', path); + }); + }); + }); + // Found directory + } else if (stat.isDirectory()) { + fs.readdir(path, function(err, files) { + if (err) throw err; + files.map(function(filename) { + return path + '/' + filename; + }).forEach(renderFile); + }); + } + }); +} diff --git a/node_modules/jade/examples/attributes.jade b/node_modules/jade/examples/attributes.jade new file mode 100644 index 0000000..b8d8ff4 --- /dev/null +++ b/node_modules/jade/examples/attributes.jade @@ -0,0 +1,8 @@ +div#id.left(class='user user-' + name).container + h1.title= name + form + //- unbuffered comment :) + // An example of attributes. + input(type='text', name='user[name]', value=name) + input(checked, type='checkbox', name='user[blocked]') + input(type='submit', value='Update') \ No newline at end of file diff --git a/node_modules/jade/examples/attributes.js b/node_modules/jade/examples/attributes.js new file mode 100644 index 0000000..f4dd730 --- /dev/null +++ b/node_modules/jade/examples/attributes.js @@ -0,0 +1,11 @@ + +/** + * Module dependencies. + */ + +var jade = require('./../') + , path = __dirname + '/attributes.jade' + , str = require('fs').readFileSync(path, 'utf8') + , fn = jade.compile(str, { filename: path, pretty: true }); + +console.log(fn({ name: 'tj' })); \ No newline at end of file diff --git a/node_modules/jade/examples/code.jade b/node_modules/jade/examples/code.jade new file mode 100644 index 0000000..40263a6 --- /dev/null +++ b/node_modules/jade/examples/code.jade @@ -0,0 +1,13 @@ + +// this expands to var title = "Things" +title = "Things" + +h1= title + +ul#users + each user, name in users + // expands to if (user.isA == 'ferret') + if user.isA == 'ferret' + li(class='user-' + name) #{name} is just a ferret + else + li(class='user-' + name) #{name} #{user.email} \ No newline at end of file diff --git a/node_modules/jade/examples/code.js b/node_modules/jade/examples/code.js new file mode 100644 index 0000000..9a35d1f --- /dev/null +++ b/node_modules/jade/examples/code.js @@ -0,0 +1,16 @@ + +/** + * Module dependencies. + */ + +var jade = require('./../') + , path = __dirname + '/code.jade' + , str = require('fs').readFileSync(path, 'utf8') + , fn = jade.compile(str, { filename: path, pretty: true }); + +var users = { + tj: { age: 23, email: 'tj@vision-media.ca', isA: 'human' }, + tobi: { age: 1, email: 'tobi@is-amazing.com', isA: 'ferret' } +}; + +console.log(fn({ users: users })); \ No newline at end of file diff --git a/node_modules/jade/examples/csrf.jade b/node_modules/jade/examples/csrf.jade new file mode 100644 index 0000000..283986b --- /dev/null +++ b/node_modules/jade/examples/csrf.jade @@ -0,0 +1,5 @@ + +form(method='post', action='/') + input(type='text', name='user[name]') + input(type='text', name='user[email]') + input(type='submit', value='Submit') diff --git a/node_modules/jade/examples/csrf.js b/node_modules/jade/examples/csrf.js new file mode 100644 index 0000000..21abf60 --- /dev/null +++ b/node_modules/jade/examples/csrf.js @@ -0,0 +1,42 @@ + + +/** + * Module dependencies. + */ + +var jade = require('./../lib/jade'), + Compiler = jade.Compiler, + nodes = jade.nodes; + +var options = { + compiler: CSRF + , locals: { + csrf: 'WAHOOOOOO' + } +}; + +jade.renderFile(__dirname + '/csrf.jade', options, function(err, html){ + if (err) throw err; + console.log(html); +}); + +function CSRF(node, options) { + Compiler.call(this, node, options); +} + +CSRF.prototype.__proto__ = Compiler.prototype; + +CSRF.prototype.visitTag = function(node){ + var parent = Compiler.prototype.visitTag; + switch (node.name) { + case 'form': + if ("'post'" == node.getAttribute('method')) { + var tok = new nodes.Tag('input'); + tok.setAttribute('type', '"hidden"'); + tok.setAttribute('name', '"csrf"'); + tok.setAttribute('value', 'csrf'); + node.block.unshift(tok); + } + } + parent.call(this, node); +}; diff --git a/node_modules/jade/examples/dynamicscript.jade b/node_modules/jade/examples/dynamicscript.jade new file mode 100644 index 0000000..a705899 --- /dev/null +++ b/node_modules/jade/examples/dynamicscript.jade @@ -0,0 +1,5 @@ +html + head + title Dynamic Inline JavaScript + script + var users = !{JSON.stringify(users)} \ No newline at end of file diff --git a/node_modules/jade/examples/dynamicscript.js b/node_modules/jade/examples/dynamicscript.js new file mode 100644 index 0000000..d2b3a0d --- /dev/null +++ b/node_modules/jade/examples/dynamicscript.js @@ -0,0 +1,20 @@ + +/** + * Module dependencies. + */ + +var jade = require('./../lib/jade'); + +var options = { + locals: { + users: { + tj: { age: 23, email: 'tj@vision-media.ca', isA: 'human' }, + tobi: { age: 1, email: 'tobi@is-amazing.com', isA: 'ferret' } + } + } +}; + +jade.renderFile(__dirname + '/dynamicscript.jade', options, function(err, html){ + if (err) throw err; + console.log(html); +}); \ No newline at end of file diff --git a/node_modules/jade/examples/each.jade b/node_modules/jade/examples/each.jade new file mode 100644 index 0000000..206c740 --- /dev/null +++ b/node_modules/jade/examples/each.jade @@ -0,0 +1,3 @@ +ul#users + each user, name in users + li(class='user-' + name) #{name} #{user.email} \ No newline at end of file diff --git a/node_modules/jade/examples/each.js b/node_modules/jade/examples/each.js new file mode 100644 index 0000000..0f3cce5 --- /dev/null +++ b/node_modules/jade/examples/each.js @@ -0,0 +1,16 @@ + +/** + * Module dependencies. + */ + +var jade = require('./../') + , path = __dirname + '/each.jade' + , str = require('fs').readFileSync(path, 'utf8') + , fn = jade.compile(str, { filename: path, pretty: true }); + +var users = { + tj: { age: 23, email: 'tj@vision-media.ca', isA: 'human' }, + tobi: { age: 1, email: 'tobi@is-amazing.com', isA: 'ferret' } +}; + +console.log(fn({ users: users })); \ No newline at end of file diff --git a/node_modules/jade/examples/extend-layout.jade b/node_modules/jade/examples/extend-layout.jade new file mode 100644 index 0000000..0767f5f --- /dev/null +++ b/node_modules/jade/examples/extend-layout.jade @@ -0,0 +1,10 @@ +html + head + h1 My Site - #{title} + block scripts + script(src='/jquery.js') + body + block content + block foot + #footer + p some footer content \ No newline at end of file diff --git a/node_modules/jade/examples/extend.jade b/node_modules/jade/examples/extend.jade new file mode 100644 index 0000000..74ea8d8 --- /dev/null +++ b/node_modules/jade/examples/extend.jade @@ -0,0 +1,11 @@ + +extends extend-layout + +block scripts + script(src='/jquery.js') + script(src='/pets.js') + +block content + h1= title + each pet in pets + include pet \ No newline at end of file diff --git a/node_modules/jade/examples/extend.js b/node_modules/jade/examples/extend.js new file mode 100644 index 0000000..604798d --- /dev/null +++ b/node_modules/jade/examples/extend.js @@ -0,0 +1,18 @@ + +/** + * Module dependencies. + */ + +var jade = require('./../') + , path = __dirname + '/extend.jade' + , str = require('fs').readFileSync(path, 'utf8') + , fn = jade.compile(str, { filename: path, pretty: true }); + +var tobi = { name: 'tobi', age: 2 }; +var loki = { name: 'loki', age: 1 }; +var jane = { name: 'jane', age: 5 }; + +console.log(fn({ + title: 'pets' + , pets: [tobi, loki, jane] +})); \ No newline at end of file diff --git a/node_modules/jade/examples/form.jade b/node_modules/jade/examples/form.jade new file mode 100644 index 0000000..afe3249 --- /dev/null +++ b/node_modules/jade/examples/form.jade @@ -0,0 +1,29 @@ +form(method="post") + fieldset + legend General + p + label(for="user[name]") Username: + input(type="text", name="user[name]", value=user.name) + p + label(for="user[email]") Email: + input(type="text", name="user[email]", value=user.email) + .tip. + Enter a valid + email address + such as tj@vision-media.ca. + fieldset + legend Location + p + label(for="user[city]") City: + input(type="text", name="user[city]", value=user.city) + p + select(name="user[province]") + option(value="") -- Select Province -- + option(value="AB") Alberta + option(value="BC") British Columbia + option(value="SK") Saskatchewan + option(value="MB") Manitoba + option(value="ON") Ontario + option(value="QC") Quebec + p.buttons + input(type="submit", value="Save") \ No newline at end of file diff --git a/node_modules/jade/examples/form.js b/node_modules/jade/examples/form.js new file mode 100644 index 0000000..dc2b8be --- /dev/null +++ b/node_modules/jade/examples/form.js @@ -0,0 +1,18 @@ + +/** + * Module dependencies. + */ + +var jade = require('../') + , path = __dirname + '/form.jade' + , str = require('fs').readFileSync(path, 'utf8') + , fn = jade.compile(str, { filename: path, pretty: true }); + +var user = { + name: 'TJ', + email: 'tj@vision-media.ca', + city: 'Victoria', + province: 'BC' +}; + +console.log(fn({ user: user })); \ No newline at end of file diff --git a/node_modules/jade/examples/includes.jade b/node_modules/jade/examples/includes.jade new file mode 100644 index 0000000..bd8c2dc --- /dev/null +++ b/node_modules/jade/examples/includes.jade @@ -0,0 +1,7 @@ + +html + include includes/head + body + h1 My Site + p Welcome to my super lame site. + include includes/foot \ No newline at end of file diff --git a/node_modules/jade/examples/includes.js b/node_modules/jade/examples/includes.js new file mode 100644 index 0000000..6c062d6 --- /dev/null +++ b/node_modules/jade/examples/includes.js @@ -0,0 +1,11 @@ + +/** + * Module dependencies. + */ + +var jade = require('./../') + , path = __dirname + '/includes.jade' + , str = require('fs').readFileSync(path, 'utf8') + , fn = jade.compile(str, { filename: path, pretty: true }); + +console.log(fn()); \ No newline at end of file diff --git a/node_modules/jade/examples/includes/foot.jade b/node_modules/jade/examples/includes/foot.jade new file mode 100644 index 0000000..b7f5889 --- /dev/null +++ b/node_modules/jade/examples/includes/foot.jade @@ -0,0 +1,2 @@ +#footer + p Copyright (c) foobar \ No newline at end of file diff --git a/node_modules/jade/examples/includes/head.jade b/node_modules/jade/examples/includes/head.jade new file mode 100644 index 0000000..6b297fc --- /dev/null +++ b/node_modules/jade/examples/includes/head.jade @@ -0,0 +1,6 @@ +head + title My Site + // including other jade works + include scripts + // including .html, .css, etc works + include style.css \ No newline at end of file diff --git a/node_modules/jade/examples/includes/scripts.jade b/node_modules/jade/examples/includes/scripts.jade new file mode 100644 index 0000000..2f478fc --- /dev/null +++ b/node_modules/jade/examples/includes/scripts.jade @@ -0,0 +1,2 @@ +script(src='/javascripts/jquery.js') +script(src='/javascripts/app.js') diff --git a/node_modules/jade/examples/includes/style.css b/node_modules/jade/examples/includes/style.css new file mode 100644 index 0000000..950708e --- /dev/null +++ b/node_modules/jade/examples/includes/style.css @@ -0,0 +1,5 @@ + \ No newline at end of file diff --git a/node_modules/jade/examples/layout-debug.js b/node_modules/jade/examples/layout-debug.js new file mode 100644 index 0000000..ca0d03b --- /dev/null +++ b/node_modules/jade/examples/layout-debug.js @@ -0,0 +1,11 @@ + +/** + * Module dependencies. + */ + +var jade = require('./../lib/jade'); + +jade.renderFile(__dirname + '/layout.jade', { debug: true }, function(err, html){ + if (err) throw err; + console.log(html); +}); \ No newline at end of file diff --git a/node_modules/jade/examples/layout.jade b/node_modules/jade/examples/layout.jade new file mode 100644 index 0000000..45738bf --- /dev/null +++ b/node_modules/jade/examples/layout.jade @@ -0,0 +1,14 @@ +!!! 5 +html(lang="en") + head + title Example + script + if (foo) { + bar(); + } + body + h1 Jade - node template engine + #container + :markdown + Jade is a _high performance_ template engine for [node](http://nodejs.org), + inspired by [haml](http://haml-lang.com/), and written by [TJ Holowaychuk](http://github.com/visionmedia). \ No newline at end of file diff --git a/node_modules/jade/examples/layout.js b/node_modules/jade/examples/layout.js new file mode 100644 index 0000000..ab20635 --- /dev/null +++ b/node_modules/jade/examples/layout.js @@ -0,0 +1,11 @@ + +/** + * Module dependencies. + */ + +var jade = require('./../') + , path = __dirname + '/layout.jade' + , str = require('fs').readFileSync(path, 'utf8') + , fn = jade.compile(str, { filename: path, pretty: true }); + +console.log(fn()); \ No newline at end of file diff --git a/node_modules/jade/examples/mixins.jade b/node_modules/jade/examples/mixins.jade new file mode 100644 index 0000000..49603a9 --- /dev/null +++ b/node_modules/jade/examples/mixins.jade @@ -0,0 +1,16 @@ + +include mixins/dialog +include mixins/profile + +.one + mixin dialog + +.two + mixin dialog-title('Whoop') + +.three + mixin dialog-title-desc('Whoop', 'Just a mixin') + + +#profile + mixin profile(user) diff --git a/node_modules/jade/examples/mixins.js b/node_modules/jade/examples/mixins.js new file mode 100644 index 0000000..6b8d64d --- /dev/null +++ b/node_modules/jade/examples/mixins.js @@ -0,0 +1,16 @@ + +/** + * Module dependencies. + */ + +var jade = require('./../') + , path = __dirname + '/mixins.jade' + , str = require('fs').readFileSync(path, 'utf8') + , fn = jade.compile(str, { filename: path, pretty: true }); + +var user = { + name: 'tj' + , pets: ['tobi', 'loki', 'jane', 'manny'] +}; + +console.log(fn({ user: user })); \ No newline at end of file diff --git a/node_modules/jade/examples/mixins/dialog.jade b/node_modules/jade/examples/mixins/dialog.jade new file mode 100644 index 0000000..ba2ec93 --- /dev/null +++ b/node_modules/jade/examples/mixins/dialog.jade @@ -0,0 +1,15 @@ + +mixin dialog + .dialog + h1 Whoop + p stuff + +mixin dialog-title(title) + .dialog + h1= title + p stuff + +mixin dialog-title-desc(title, desc) + .dialog + h1= title + p= desc diff --git a/node_modules/jade/examples/mixins/profile.jade b/node_modules/jade/examples/mixins/profile.jade new file mode 100644 index 0000000..b1542dd --- /dev/null +++ b/node_modules/jade/examples/mixins/profile.jade @@ -0,0 +1,10 @@ + +mixin pets(pets) + ul.pets + - each pet in pets + li= pet + +mixin profile(user) + .user + h2= user.name + mixin pets(user.pets) \ No newline at end of file diff --git a/node_modules/jade/examples/model.jade b/node_modules/jade/examples/model.jade new file mode 100644 index 0000000..00cf248 --- /dev/null +++ b/node_modules/jade/examples/model.jade @@ -0,0 +1,9 @@ +model: + form(user) + p + field(name) + p + field(email) + p + field(summary, as: 'textarea') + buttons \ No newline at end of file diff --git a/node_modules/jade/examples/model.js b/node_modules/jade/examples/model.js new file mode 100644 index 0000000..145e01d --- /dev/null +++ b/node_modules/jade/examples/model.js @@ -0,0 +1,124 @@ + + +/** + * Module dependencies. + */ + +var jade = require('./../lib/jade'), + Compiler = jade.Compiler, + nodes = jade.nodes; + +var options = { + locals: { + user: { + name: 'Tobi', + email: 'vision-media.ca', + summary: 'Tobi is a ferret, he is supes cool.', + errors: { email: 'Invalid email' }, + new: false + } + } +}; + +jade.renderFile(__dirname + '/model.jade', options, function(err, html){ + if (err) throw err; + console.log(html); +}); + +// First define a filter named "model", +// which accepts a node (a Block node), +// and the parent Compiler + +jade.filters.model = function(block, compiler){ + // pass the block / previous options to our new Visitor + return new Visitor(block, compiler.options).compile(); +}; + +function Visitor(node, options) { + // "super" to the Compiler() constructor + Compiler.call(this, node, options); +} + +// Inherit from Compiler + +Visitor.prototype.__proto__ = Compiler.prototype; + +// Overwrite visitTag method + +Visitor.prototype.visitTag = function(node){ + var parent = Compiler.prototype.visitTag; + switch (node.name) { + case 'form': + // Store the record variable name, + // in our case "user" is our first + // anonymous attribute + this.record = node.attrs[0].name; + // remove the record name attribute + node.removeAttribute(this.record); + node.setAttribute('id', '"' + this.record + '-model-form"'); + node.setAttribute('method', '"post"'); + + // when the record is not new, we probably want a _method hidden + // field to tell our server to use PUT with frameworks like Express + var code = new nodes.Code('if (!' + this.record + '.new)'); + var put = new nodes.Tag('input'); + put.setAttribute('type', '"hidden"'); + put.setAttribute('name', '"_method"'); + put.setAttribute('value', '"put"'); + code.block = new nodes.Block(put); + node.block.push(code); + + parent.call(this, node); + break; + case 'field': + // Grab "as" attribute, defaulting it to "text" + // perform some surgery on it since it IS literal JavaScript + var name = node.attrs[0].name, + as = (node.getAttribute('as') || 'text').trim().replace(/'/g, ''), + capitalized = name.charAt(0).toUpperCase() + name.slice(1); + + // Field label + var label = new nodes.Tag('label'); + label.setAttribute('for', '"' + this.record + '[' + name + ']"'); + label.block.push(new nodes.Text(capitalized + ':')); + parent.call(this, label); + + // Field input + switch (as) { + case 'textarea': + var code = new nodes.Code(this.record + '.' + name, true, true); + node = new nodes.Tag('textarea'); + node.block.push(code); + break; + case 'text': + node = new nodes.Tag('input'); + node.setAttribute('type', '"text"'); + node.setAttribute('value', this.record + '.' + name); + } + node.setAttribute('name', '"' + this.record + '[' + name + ']"'); + parent.call(this, node); + + // Potential error tag + var err = this.record + '.errors.' + name; + node = new nodes.Code('if (' + err + ')'); + node.block = new nodes.Block; + var p = new nodes.Tag('p', new nodes.Block(new nodes.Code(err, true, true))); + p.setAttribute('class', '"error"'); + node.block.push(p); + + Visitor.prototype.visitCode.call(this, node); + break; + case 'buttons': + // Generate context sensative buttons which + // check the record's state. + node = new nodes.Tag('input'); + node.setAttribute('type', '"submit"'); + node.setAttribute('value', this.record + '.new ? "Save" : "Update"'); + var p = new nodes.Tag('p', new nodes.Block(node)); + p.setAttribute('class', '"buttons"'); + parent.call(this, p); + break; + default: + parent.call(this, node); + } +}; diff --git a/node_modules/jade/examples/nested-filters.jade b/node_modules/jade/examples/nested-filters.jade new file mode 100644 index 0000000..5ffc2d8 --- /dev/null +++ b/node_modules/jade/examples/nested-filters.jade @@ -0,0 +1,8 @@ +stylesheets: + stylesheet('/path/to/a.css') + stylesheet('/path/to/b.css') + stylesheet('/path/to/c.css') + javascripts: + js('/path/to/a.js') + js('/path/to/b.js') + js('/path/to/c.js') \ No newline at end of file diff --git a/node_modules/jade/examples/nested-filters.js b/node_modules/jade/examples/nested-filters.js new file mode 100644 index 0000000..e7068b4 --- /dev/null +++ b/node_modules/jade/examples/nested-filters.js @@ -0,0 +1,73 @@ + +/** + * Module dependencies. + */ + +var jade = require('./../lib/jade'), + nodes = jade.nodes, + Compiler = jade.Compiler; + +jade.renderFile(__dirname + '/nested-filters.jade', function(err, html){ + if (err) throw err; + console.log(html); +}); + +// :javascripts + +jade.filters.javascripts = function(block, compiler){ + return new JavascriptsVisitor(block, compiler.options).compile(); +}; + +function JavascriptsVisitor(node, options) { + Compiler.call(this, node, options); +} + +// Inherit from Compiler + +JavascriptsVisitor.prototype.__proto__ = Compiler.prototype; + +// Overwrite visitTag method + +JavascriptsVisitor.prototype.visitTag = function(node){ + var parent = Compiler.prototype.visitTag; + switch (node.name) { + case 'js': + var script = new nodes.Tag('script'); + script.setAttribute('type', "'text/javascript'"); + script.setAttribute('src', "'" + node.attrs[0].name + "'") + parent.call(this, script); + break; + default: + parent.call(this, node); + } +}; + +// :stylesheets + +jade.filters.stylesheets = function(block, compiler){ + return new StylesheetsVisitor(block, compiler.options).compile(); +}; + +function StylesheetsVisitor(node, options) { + Compiler.call(this, node, options); +} + +// Inherit from Compiler + +StylesheetsVisitor.prototype.__proto__ = Compiler.prototype; + +// Overwrite visitTag method + +StylesheetsVisitor.prototype.visitTag = function(node){ + var parent = Compiler.prototype.visitTag; + switch (node.name) { + case 'stylesheet': + var style = new nodes.Tag('link'); + style.setAttribute('rel', "'stylesheet'"); + style.setAttribute('href', "'" + node.attrs[0].name + "'") + parent.call(this, style); + break; + default: + parent.call(this, node); + } +}; diff --git a/node_modules/jade/examples/pet.jade b/node_modules/jade/examples/pet.jade new file mode 100644 index 0000000..e5dbab9 --- /dev/null +++ b/node_modules/jade/examples/pet.jade @@ -0,0 +1,3 @@ +.pet + h2= pet.name + p #{pet.name} is #{pet.age} year(s) old. \ No newline at end of file diff --git a/node_modules/jade/examples/rss.jade b/node_modules/jade/examples/rss.jade new file mode 100644 index 0000000..165dffb --- /dev/null +++ b/node_modules/jade/examples/rss.jade @@ -0,0 +1,14 @@ +doctype xml +rss(version='2.0') +channel + title RSS Title + description Some description here + link http://google.com + lastBuildDate Mon, 06 Sep 2010 00:01:00 +0000 + pubDate Mon, 06 Sep 2009 16:45:00 +0000 + + each item in items + item + title= item.title + description= item.description + link= item.link diff --git a/node_modules/jade/examples/rss.js b/node_modules/jade/examples/rss.js new file mode 100644 index 0000000..861986a --- /dev/null +++ b/node_modules/jade/examples/rss.js @@ -0,0 +1,17 @@ + +/** + * Module dependencies. + */ + +var jade = require('./../') + , path = __dirname + '/rss.jade' + , str = require('fs').readFileSync(path, 'utf8') + , fn = jade.compile(str, { filename: path, pretty: true }); + +var items = []; + +items.push({ title: 'Example', description: 'Something', link: 'http://google.com' }); +items.push({ title: 'LearnBoost', description: 'Cool', link: 'http://learnboost.com' }); +items.push({ title: 'Express', description: 'Cool', link: 'http://expressjs.com' }); + +console.log(fn({ items: items })); \ No newline at end of file diff --git a/node_modules/jade/examples/text.jade b/node_modules/jade/examples/text.jade new file mode 100644 index 0000000..c18e7e0 --- /dev/null +++ b/node_modules/jade/examples/text.jade @@ -0,0 +1,36 @@ +| An example of an +a(href='#') inline +| link. + +form + label Username: + input(type='text', name='user[name]') + p + | Just an example of some text usage. + | You can have inline html, + | as well as + strong tags + | . + + | Interpolation is also supported. The + | username is currently "#{name}". + + label Email: + input(type='text', name='user[email]') + p + | Email is currently + em= email + | . + + // alternatively, if we plan on having only + // text or inline-html, we can use a trailing + // "." to let jade know we want to omit pipes + + label Username: + input(type='text') + p. + Just an example, like before + however now we can omit those + annoying pipes!. + + Wahoo. \ No newline at end of file diff --git a/node_modules/jade/examples/text.js b/node_modules/jade/examples/text.js new file mode 100644 index 0000000..503d563 --- /dev/null +++ b/node_modules/jade/examples/text.js @@ -0,0 +1,11 @@ + +/** + * Module dependencies. + */ + +var jade = require('./../') + , path = __dirname + '/text.jade' + , str = require('fs').readFileSync(path, 'utf8') + , fn = jade.compile(str, { filename: path, pretty: true }); + +console.log(fn({ name: 'tj', email: 'tj@vision-media.ca' })); \ No newline at end of file diff --git a/node_modules/jade/examples/whitespace.jade b/node_modules/jade/examples/whitespace.jade new file mode 100644 index 0000000..25b6ba9 --- /dev/null +++ b/node_modules/jade/examples/whitespace.jade @@ -0,0 +1,11 @@ +js = '' +!!! 5 +html + + head + title= "Some " + "JavaScript" + != js + + + + body \ No newline at end of file diff --git a/node_modules/jade/examples/whitespace.js b/node_modules/jade/examples/whitespace.js new file mode 100644 index 0000000..1651d13 --- /dev/null +++ b/node_modules/jade/examples/whitespace.js @@ -0,0 +1,11 @@ + +/** + * Module dependencies. + */ + +var jade = require('./../') + , path = __dirname + '/whitespace.jade' + , str = require('fs').readFileSync(path, 'utf8') + , fn = jade.compile(str, { filename: path, pretty: true }); + +console.log(fn()); \ No newline at end of file diff --git a/node_modules/jade/index.js b/node_modules/jade/index.js new file mode 100644 index 0000000..857e431 --- /dev/null +++ b/node_modules/jade/index.js @@ -0,0 +1,2 @@ + +module.exports = require('./lib/jade'); \ No newline at end of file diff --git a/node_modules/jade/jade.js b/node_modules/jade/jade.js new file mode 100644 index 0000000..ea05bb2 --- /dev/null +++ b/node_modules/jade/jade.js @@ -0,0 +1,3047 @@ + +// CommonJS require() + +function require(p){ + var path = require.resolve(p) + , mod = require.modules[path]; + if (!mod) throw new Error('failed to require "' + p + '"'); + if (!mod.exports) { + mod.exports = {}; + mod.call(mod.exports, mod, mod.exports, require.relative(path)); + } + return mod.exports; + } + +require.modules = {}; + +require.resolve = function (path){ + var orig = path + , reg = path + '.js' + , index = path + '/index.js'; + return require.modules[reg] && reg + || require.modules[index] && index + || orig; + }; + +require.register = function (path, fn){ + require.modules[path] = fn; + }; + +require.relative = function (parent) { + return function(p){ + if ('.' != p[0]) return require(p); + + var path = parent.split('/') + , segs = p.split('/'); + path.pop(); + + for (var i = 0; i < segs.length; i++) { + var seg = segs[i]; + if ('..' == seg) path.pop(); + else if ('.' != seg) path.push(seg); + } + + return require(path.join('/')); + }; + }; + + +require.register("compiler.js", function(module, exports, require){ + +/*! + * Jade - Compiler + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var nodes = require('./nodes') + , filters = require('./filters') + , doctypes = require('./doctypes') + , selfClosing = require('./self-closing') + , inlineTags = require('./inline-tags') + , utils = require('./utils'); + + + if (!Object.keys) { + Object.keys = function(obj){ + var arr = []; + for (var key in obj) { + if (obj.hasOwnProperty(key)) { + arr.push(key); + } + } + return arr; + } + } + + if (!String.prototype.trimLeft) { + String.prototype.trimLeft = function(){ + return this.replace(/^\s+/, ''); + } + } + + + +/** + * Initialize `Compiler` with the given `node`. + * + * @param {Node} node + * @param {Object} options + * @api public + */ + +var Compiler = module.exports = function Compiler(node, options) { + this.options = options = options || {}; + this.node = node; + this.hasCompiledDoctype = false; + this.hasCompiledTag = false; + this.pp = options.pretty || false; + this.debug = false !== options.compileDebug; + this.indents = 0; + if (options.doctype) this.setDoctype(options.doctype); +}; + +/** + * Compiler prototype. + */ + +Compiler.prototype = { + + /** + * Compile parse tree to JavaScript. + * + * @api public + */ + + compile: function(){ + this.buf = ['var interp;']; + this.lastBufferedIdx = -1 + this.visit(this.node); + return this.buf.join('\n'); + }, + + /** + * Sets the default doctype `name`. Sets terse mode to `true` when + * html 5 is used, causing self-closing tags to end with ">" vs "/>", + * and boolean attributes are not mirrored. + * + * @param {string} name + * @api public + */ + + setDoctype: function(name){ + var doctype = doctypes[(name || 'default').toLowerCase()]; + doctype = doctype || ''; + this.doctype = doctype; + this.terse = '5' == name || 'html' == name; + this.xml = 0 == this.doctype.indexOf('" vs "/>", + * and boolean attributes are not mirrored. + * + * @param {Doctype} doctype + * @api public + */ + + visitDoctype: function(doctype){ + if (doctype && (doctype.val || !this.doctype)) { + this.setDoctype(doctype.val || 'default'); + } + + if (this.doctype) this.buffer(this.doctype); + this.hasCompiledDoctype = true; + }, + + /** + * Visit `mixin`, generating a function that + * may be called within the template. + * + * @param {Mixin} mixin + * @api public + */ + + visitMixin: function(mixin){ + var name = mixin.name.replace(/-/g, '_') + '_mixin' + , args = mixin.args || ''; + + if (mixin.block) { + this.buf.push('var ' + name + ' = function(' + args + '){'); + this.visit(mixin.block); + this.buf.push('}'); + } else { + this.buf.push(name + '(' + args + ');'); + } + }, + + /** + * Visit `tag` buffering tag markup, generating + * attributes, visiting the `tag`'s code and block. + * + * @param {Tag} tag + * @api public + */ + + visitTag: function(tag){ + this.indents++; + var name = tag.name; + + if (!this.hasCompiledTag) { + if (!this.hasCompiledDoctype && 'html' == name) { + this.visitDoctype(); + } + this.hasCompiledTag = true; + } + + // pretty print + if (this.pp && inlineTags.indexOf(name) == -1) { + this.buffer('\\n' + Array(this.indents).join(' ')); + } + + if (~selfClosing.indexOf(name) && !this.xml) { + this.buffer('<' + name); + this.visitAttributes(tag.attrs); + this.terse + ? this.buffer('>') + : this.buffer('/>'); + } else { + // Optimize attributes buffering + if (tag.attrs.length) { + this.buffer('<' + name); + if (tag.attrs.length) this.visitAttributes(tag.attrs); + this.buffer('>'); + } else { + this.buffer('<' + name + '>'); + } + if (tag.code) this.visitCode(tag.code); + if (tag.text) this.buffer(utils.text(tag.text.nodes[0].trimLeft())); + this.escape = 'pre' == tag.name; + this.visit(tag.block); + + // pretty print + if (this.pp && !~inlineTags.indexOf(name) && !tag.textOnly) { + this.buffer('\\n' + Array(this.indents).join(' ')); + } + + this.buffer(''); + } + this.indents--; + }, + + /** + * Visit `filter`, throwing when the filter does not exist. + * + * @param {Filter} filter + * @api public + */ + + visitFilter: function(filter){ + var fn = filters[filter.name]; + + // unknown filter + if (!fn) { + if (filter.isASTFilter) { + throw new Error('unknown ast filter "' + filter.name + ':"'); + } else { + throw new Error('unknown filter ":' + filter.name + '"'); + } + } + if (filter.isASTFilter) { + this.buf.push(fn(filter.block, this, filter.attrs)); + } else { + var text = filter.block.nodes.join(''); + this.buffer(utils.text(fn(text, filter.attrs))); + } + }, + + /** + * Visit `text` node. + * + * @param {Text} text + * @api public + */ + + visitText: function(text){ + text = utils.text(text.nodes.join('')); + if (this.escape) text = escape(text); + this.buffer(text); + this.buffer('\\n'); + }, + + /** + * Visit a `comment`, only buffering when the buffer flag is set. + * + * @param {Comment} comment + * @api public + */ + + visitComment: function(comment){ + if (!comment.buffer) return; + if (this.pp) this.buffer('\\n' + Array(this.indents + 1).join(' ')); + this.buffer(''); + }, + + /** + * Visit a `BlockComment`. + * + * @param {Comment} comment + * @api public + */ + + visitBlockComment: function(comment){ + if (!comment.buffer) return; + if (0 == comment.val.trim().indexOf('if')) { + this.buffer(''); + } else { + this.buffer(''); + } + }, + + /** + * Visit `code`, respecting buffer / escape flags. + * If the code is followed by a block, wrap it in + * a self-calling function. + * + * @param {Code} code + * @api public + */ + + visitCode: function(code){ + // Wrap code blocks with {}. + // we only wrap unbuffered code blocks ATM + // since they are usually flow control + + // Buffer code + if (code.buffer) { + var val = code.val.trimLeft(); + this.buf.push('var __val__ = ' + val); + val = 'null == __val__ ? "" : __val__'; + if (code.escape) val = 'escape(' + val + ')'; + this.buf.push("buf.push(" + val + ");"); + } else { + this.buf.push(code.val); + } + + // Block support + if (code.block) { + if (!code.buffer) this.buf.push('{'); + this.visit(code.block); + if (!code.buffer) this.buf.push('}'); + } + }, + + /** + * Visit `each` block. + * + * @param {Each} each + * @api public + */ + + visitEach: function(each){ + this.buf.push('' + + '// iterate ' + each.obj + '\n' + + '(function(){\n' + + ' if (\'number\' == typeof ' + each.obj + '.length) {\n' + + ' for (var ' + each.key + ' = 0, $$l = ' + each.obj + '.length; ' + each.key + ' < $$l; ' + each.key + '++) {\n' + + ' var ' + each.val + ' = ' + each.obj + '[' + each.key + '];\n'); + + this.visit(each.block); + + this.buf.push('' + + ' }\n' + + ' } else {\n' + + ' for (var ' + each.key + ' in ' + each.obj + ') {\n' + + ' if (' + each.obj + '.hasOwnProperty(' + each.key + ')){' + + ' var ' + each.val + ' = ' + each.obj + '[' + each.key + '];\n'); + + this.visit(each.block); + + this.buf.push(' }\n'); + + this.buf.push(' }\n }\n}).call(this);\n'); + }, + + /** + * Visit `attrs`. + * + * @param {Array} attrs + * @api public + */ + + visitAttributes: function(attrs){ + var buf = [] + , classes = []; + + if (this.terse) buf.push('terse: true'); + + attrs.forEach(function(attr){ + if (attr.name == 'class') { + classes.push('(' + attr.val + ')'); + } else { + var pair = "'" + attr.name + "':(" + attr.val + ')'; + buf.push(pair); + } + }); + + if (classes.length) { + classes = classes.join(" + ' ' + "); + buf.push("class: " + classes); + } + + buf = buf.join(', ').replace('class:', '"class":'); + + this.buf.push("buf.push(attrs({ " + buf + " }));"); + } +}; + +/** + * Escape the given string of `html`. + * + * @param {String} html + * @return {String} + * @api private + */ + +function escape(html){ + return String(html) + .replace(/&(?!\w+;)/g, '&') + .replace(//g, '>') + .replace(/"/g, '"'); +} + +}); // module: compiler.js + +require.register("doctypes.js", function(module, exports, require){ + +/*! + * Jade - doctypes + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +module.exports = { + '5': '' + , 'xml': '' + , 'default': '' + , 'transitional': '' + , 'strict': '' + , 'frameset': '' + , '1.1': '' + , 'basic': '' + , 'mobile': '' +}; +}); // module: doctypes.js + +require.register("filters.js", function(module, exports, require){ + +/*! + * Jade - filters + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +module.exports = { + + /** + * Wrap text with CDATA block. + */ + + cdata: function(str){ + return ''; + }, + + /** + * Transform sass to css, wrapped in style tags. + */ + + sass: function(str){ + str = str.replace(/\\n/g, '\n'); + var sass = require('sass').render(str).replace(/\n/g, '\\n'); + return ''; + }, + + /** + * Transform stylus to css, wrapped in style tags. + */ + + stylus: function(str, options){ + var ret; + str = str.replace(/\\n/g, '\n'); + var stylus = require('stylus'); + stylus(str, options).render(function(err, css){ + if (err) throw err; + ret = css.replace(/\n/g, '\\n'); + }); + return ''; + }, + + /** + * Transform less to css, wrapped in style tags. + */ + + less: function(str){ + var ret; + str = str.replace(/\\n/g, '\n'); + require('less').render(str, function(err, css){ + if (err) throw err; + ret = ''; + }); + return ret; + }, + + /** + * Transform markdown to html. + */ + + markdown: function(str){ + var md; + + // support markdown / discount + try { + md = require('markdown'); + } catch (err){ + try { + md = require('discount'); + } catch (err) { + try { + md = require('markdown-js'); + } catch (err) { + throw new Error('Cannot find markdown library, install markdown or discount'); + } + } + } + + str = str.replace(/\\n/g, '\n'); + return md.parse(str).replace(/\n/g, '\\n').replace(/'/g,'''); + }, + + /** + * Transform coffeescript to javascript. + */ + + coffeescript: function(str){ + str = str.replace(/\\n/g, '\n'); + var js = require('coffee-script').compile(str).replace(/\n/g, '\\n'); + return ''; + } +}; + +}); // module: filters.js + +require.register("inline-tags.js", function(module, exports, require){ + +/*! + * Jade - inline tags + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +module.exports = [ + 'a' + , 'abbr' + , 'acronym' + , 'b' + , 'br' + , 'code' + , 'em' + , 'font' + , 'i' + , 'img' + , 'ins' + , 'kbd' + , 'map' + , 'samp' + , 'small' + , 'span' + , 'strong' + , 'sub' + , 'sup' +]; +}); // module: inline-tags.js + +require.register("jade.js", function(module, exports, require){ + +/*! + * Jade + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var Parser = require('./parser') + , Lexer = require('./lexer') + , Compiler = require('./compiler') + , runtime = require('./runtime') + +/** + * Library version. + */ + +exports.version = '0.17.0'; + +/** + * Expose self closing tags. + */ + +exports.selfClosing = require('./self-closing'); + +/** + * Default supported doctypes. + */ + +exports.doctypes = require('./doctypes'); + +/** + * Text filters. + */ + +exports.filters = require('./filters'); + +/** + * Utilities. + */ + +exports.utils = require('./utils'); + +/** + * Expose `Compiler`. + */ + +exports.Compiler = Compiler; + +/** + * Expose `Parser`. + */ + +exports.Parser = Parser; + +/** + * Expose `Lexer`. + */ + +exports.Lexer = Lexer; + +/** + * Nodes. + */ + +exports.nodes = require('./nodes'); + +/** + * Jade runtime helpers. + */ + +exports.runtime = runtime; + +/** + * Template function cache. + */ + +exports.cache = {}; + +/** + * Parse the given `str` of jade and return a function body. + * + * @param {String} str + * @param {Object} options + * @return {String} + * @api private + */ + +function parse(str, options){ + try { + // Parse + var parser = new Parser(str, options.filename, options); + + // Compile + var compiler = new (options.compiler || Compiler)(parser.parse(), options) + , js = compiler.compile(); + + // Debug compiler + if (options.debug) { + console.error('\nCompiled Function:\n\n\033[90m%s\033[0m', js.replace(/^/gm, ' ')); + } + + return '' + + 'var buf = [];\n' + + (options.self + ? 'var self = locals || {};\n' + js + : 'with (locals || {}) {\n' + js + '\n}\n') + + 'return buf.join("");'; + } catch (err) { + parser = parser.context(); + runtime.rethrow(err, parser.filename, parser.lexer.lineno); + } +} + +/** + * Compile a `Function` representation of the given jade `str`. + * + * Options: + * + * - `compileDebug` when `false` debugging code is stripped from the compiled template + * - `client` when `true` the helper functions `escape()` etc will reference `jade.escape()` + * for use with the Jade client-side runtime.js + * + * @param {String} str + * @param {Options} options + * @return {Function} + * @api public + */ + +exports.compile = function(str, options){ + var options = options || {} + , client = options.client + , filename = options.filename + ? JSON.stringify(options.filename) + : 'undefined' + , fn; + + if (options.compileDebug !== false) { + fn = [ + 'var __ = [{ lineno: 1, filename: ' + filename + ' }];' + , 'try {' + , parse(String(str), options || {}) + , '} catch (err) {' + , ' rethrow(err, __[0].filename, __[0].lineno);' + , '}' + ].join('\n'); + } else { + fn = parse(String(str), options || {}); + } + + if (client) { + fn = 'var attrs = jade.attrs, escape = jade.escape, rethrow = jade.rethrow;\n' + fn; + } + + fn = new Function('locals, attrs, escape, rethrow', fn); + + if (client) return fn; + + return function(locals){ + return fn(locals, runtime.attrs, runtime.escape, runtime.rethrow); + }; +}; + +/** + * Render the given `str` of jade and invoke + * the callback `fn(err, str)`. + * + * Options: + * + * - `cache` enable template caching + * - `filename` filename required for `include` / `extends` and caching + * + * @param {String} str + * @param {Object|Function} options or fn + * @param {Function} fn + * @api public + */ + +exports.render = function(str, options, fn){ + // swap args + if ('function' == typeof options) { + fn = options, options = {}; + } + + // cache requires .filename + if (options.cache && !options.filename) { + return fn(new Error('the "filename" option is required for caching')); + } + + try { + var path = options.filename; + var tmpl = options.cache + ? exports.cache[path] || (exports.cache[path] = exports.compile(str, options)) + : exports.compile(str, options); + fn(null, tmpl(options)); + } catch (err) { + fn(err); + } +}; + +/** + * Render a Jade file at the given `path` and callback `fn(err, str)`. + * + * @param {String} path + * @param {Object|Function} options or callback + * @param {Function} fn + * @api public + */ + +exports.renderFile = function(path, options, fn){ + var key = path + ':string'; + + if ('function' == typeof options) { + fn = options, options = {}; + } + + options.filename = path; + var str = options.cache + ? exports.cache[key] || (exports.cache[key] = fs.readFileSync(path, 'utf8')) + : fs.readFileSync(path, 'utf8'); + + exports.render(str, options, fn); +}; + +/** + * Express support. + */ + +exports.__express = exports.renderFile; +}); // module: jade.js + +require.register("lexer.js", function(module, exports, require){ + +/*! + * Jade - Lexer + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Initialize `Lexer` with the given `str`. + * + * Options: + * + * - `colons` allow colons for attr delimiters + * + * @param {String} str + * @param {Object} options + * @api private + */ + +var Lexer = module.exports = function Lexer(str, options) { + options = options || {}; + this.input = str.replace(/\r\n|\r/g, '\n'); + this.colons = options.colons; + this.deferredTokens = []; + this.lastIndents = 0; + this.lineno = 1; + this.stash = []; + this.indentStack = []; + this.indentRe = null; + this.pipeless = false; +}; + +/** + * Lexer prototype. + */ + +Lexer.prototype = { + + /** + * Construct a token with the given `type` and `val`. + * + * @param {String} type + * @param {String} val + * @return {Object} + * @api private + */ + + tok: function(type, val){ + return { + type: type + , line: this.lineno + , val: val + } + }, + + /** + * Consume the given `len` of input. + * + * @param {Number} len + * @api private + */ + + consume: function(len){ + this.input = this.input.substr(len); + }, + + /** + * Scan for `type` with the given `regexp`. + * + * @param {String} type + * @param {RegExp} regexp + * @return {Object} + * @api private + */ + + scan: function(regexp, type){ + var captures; + if (captures = regexp.exec(this.input)) { + this.consume(captures[0].length); + return this.tok(type, captures[1]); + } + }, + + /** + * Defer the given `tok`. + * + * @param {Object} tok + * @api private + */ + + defer: function(tok){ + this.deferredTokens.push(tok); + }, + + /** + * Lookahead `n` tokens. + * + * @param {Number} n + * @return {Object} + * @api private + */ + + lookahead: function(n){ + var fetch = n - this.stash.length; + while (fetch-- > 0) this.stash.push(this.next()); + return this.stash[--n]; + }, + + /** + * Return the indexOf `start` / `end` delimiters. + * + * @param {String} start + * @param {String} end + * @return {Number} + * @api private + */ + + indexOfDelimiters: function(start, end){ + var str = this.input + , nstart = 0 + , nend = 0 + , pos = 0; + for (var i = 0, len = str.length; i < len; ++i) { + if (start == str[i]) { + ++nstart; + } else if (end == str[i]) { + if (++nend == nstart) { + pos = i; + break; + } + } + } + return pos; + }, + + /** + * Stashed token. + */ + + stashed: function() { + return this.stash.length + && this.stash.shift(); + }, + + /** + * Deferred token. + */ + + deferred: function() { + return this.deferredTokens.length + && this.deferredTokens.shift(); + }, + + /** + * end-of-source. + */ + + eos: function() { + if (this.input.length) return; + if (this.indentStack.length) { + this.indentStack.shift(); + return this.tok('outdent'); + } else { + return this.tok('eos'); + } + }, + + /** + * Comment. + */ + + comment: function() { + var captures; + if (captures = /^ *\/\/(-)?([^\n]*)/.exec(this.input)) { + this.consume(captures[0].length); + var tok = this.tok('comment', captures[2]); + tok.buffer = '-' != captures[1]; + return tok; + } + }, + + /** + * Tag. + */ + + tag: function() { + var captures; + if (captures = /^(\w[-:\w]*)/.exec(this.input)) { + this.consume(captures[0].length); + var tok, name = captures[1]; + if (':' == name[name.length - 1]) { + name = name.slice(0, -1); + tok = this.tok('tag', name); + this.defer(this.tok(':')); + while (' ' == this.input[0]) this.input = this.input.substr(1); + } else { + tok = this.tok('tag', name); + } + return tok; + } + }, + + /** + * Filter. + */ + + filter: function() { + return this.scan(/^:(\w+)/, 'filter'); + }, + + /** + * Doctype. + */ + + doctype: function() { + return this.scan(/^(?:!!!|doctype) *([^\n]+)?/, 'doctype'); + }, + + /** + * Id. + */ + + id: function() { + return this.scan(/^#([\w-]+)/, 'id'); + }, + + /** + * Class. + */ + + className: function() { + return this.scan(/^\.([\w-]+)/, 'class'); + }, + + /** + * Text. + */ + + text: function() { + return this.scan(/^(?:\| ?)?([^\n]+)/, 'text'); + }, + + /** + * Extends. + */ + + extends: function() { + return this.scan(/^extends +([^\n]+)/, 'extends'); + }, + + /** + * Block. + */ + + block: function() { + return this.scan(/^block +([^\n]+)/, 'block'); + }, + + /** + * Include. + */ + + include: function() { + return this.scan(/^include +([^\n]+)/, 'include'); + }, + + /** + * Case. + */ + + case: function() { + return this.scan(/^case +([^\n]+)/, 'case'); + }, + + /** + * When. + */ + + when: function() { + return this.scan(/^when +([^:\n]+)/, 'when'); + }, + + /** + * Default. + */ + + default: function() { + return this.scan(/^default */, 'default'); + }, + + /** + * Assignment. + */ + + assignment: function() { + var captures; + if (captures = /^(\w+) += *([^;\n]+)( *;? *)/.exec(this.input)) { + this.consume(captures[0].length); + var name = captures[1] + , val = captures[2]; + return this.tok('code', 'var ' + name + ' = (' + val + ');'); + } + }, + + /** + * Mixin. + */ + + mixin: function(){ + var captures; + if (captures = /^mixin +([-\w]+)(?:\((.*)\))?/.exec(this.input)) { + this.consume(captures[0].length); + var tok = this.tok('mixin', captures[1]); + tok.args = captures[2]; + return tok; + } + }, + + /** + * Conditional. + */ + + conditional: function() { + var captures; + if (captures = /^(if|unless|else if|else)\b([^\n]*)/.exec(this.input)) { + this.consume(captures[0].length); + var type = captures[1] + , js = captures[2]; + + switch (type) { + case 'if': js = 'if (' + js + ')'; break; + case 'unless': js = 'if (!(' + js + '))'; break; + case 'else if': js = 'else if (' + js + ')'; break; + case 'else': js = 'else'; break; + } + + return this.tok('code', js); + } + }, + + /** + * While. + */ + + while: function() { + var captures; + if (captures = /^while +([^\n]+)/.exec(this.input)) { + this.consume(captures[0].length); + return this.tok('code', 'while (' + captures[1] + ')'); + } + }, + + /** + * Each. + */ + + each: function() { + var captures; + if (captures = /^(?:- *)?(?:each|for) +(\w+)(?: *, *(\w+))? * in *([^\n]+)/.exec(this.input)) { + this.consume(captures[0].length); + var tok = this.tok('each', captures[1]); + tok.key = captures[2] || '$index'; + tok.code = captures[3]; + return tok; + } + }, + + /** + * Code. + */ + + code: function() { + var captures; + if (captures = /^(!?=|-)([^\n]+)/.exec(this.input)) { + this.consume(captures[0].length); + var flags = captures[1]; + captures[1] = captures[2]; + var tok = this.tok('code', captures[1]); + tok.escape = flags[0] === '='; + tok.buffer = flags[0] === '=' || flags[1] === '='; + return tok; + } + }, + + /** + * Attributes. + */ + + attrs: function() { + if ('(' == this.input[0]) { + var index = this.indexOfDelimiters('(', ')') + , str = this.input.substr(1, index-1) + , tok = this.tok('attrs') + , len = str.length + , colons = this.colons + , states = ['key'] + , key = '' + , val = '' + , quote + , c; + + function state(){ + return states[states.length - 1]; + } + + function interpolate(attr) { + return attr.replace(/#\{([^}]+)\}/g, function(_, expr){ + return quote + " + (" + expr + ") + " + quote; + }); + } + + this.consume(index + 1); + tok.attrs = {}; + + function parse(c) { + var real = c; + // TODO: remove when people fix ":" + if (colons && ':' == c) c = '='; + switch (c) { + case ',': + case '\n': + switch (state()) { + case 'expr': + case 'array': + case 'string': + case 'object': + val += c; + break; + default: + states.push('key'); + val = val.trim(); + key = key.trim(); + if ('' == key) return; + tok.attrs[key.replace(/^['"]|['"]$/g, '')] = '' == val + ? true + : interpolate(val); + key = val = ''; + } + break; + case '=': + switch (state()) { + case 'key char': + key += real; + break; + case 'val': + case 'expr': + case 'array': + case 'string': + case 'object': + val += real; + break; + default: + states.push('val'); + } + break; + case '(': + if ('val' == state() + || 'expr' == state()) states.push('expr'); + val += c; + break; + case ')': + if ('expr' == state() + || 'val' == state()) states.pop(); + val += c; + break; + case '{': + if ('val' == state()) states.push('object'); + val += c; + break; + case '}': + if ('object' == state()) states.pop(); + val += c; + break; + case '[': + if ('val' == state()) states.push('array'); + val += c; + break; + case ']': + if ('array' == state()) states.pop(); + val += c; + break; + case '"': + case "'": + switch (state()) { + case 'key': + states.push('key char'); + break; + case 'key char': + states.pop(); + break; + case 'string': + if (c == quote) states.pop(); + val += c; + break; + default: + states.push('string'); + val += c; + quote = c; + } + break; + case '': + break; + default: + switch (state()) { + case 'key': + case 'key char': + key += c; + break; + default: + val += c; + } + } + } + + for (var i = 0; i < len; ++i) { + parse(str[i]); + } + + parse(','); + + return tok; + } + }, + + /** + * Indent | Outdent | Newline. + */ + + indent: function() { + var captures, re; + + // established regexp + if (this.indentRe) { + captures = this.indentRe.exec(this.input); + // determine regexp + } else { + // tabs + re = /^\n(\t*) */; + captures = re.exec(this.input); + + // spaces + if (captures && !captures[1].length) { + re = /^\n( *)/; + captures = re.exec(this.input); + } + + // established + if (captures && captures[1].length) this.indentRe = re; + } + + if (captures) { + var tok + , indents = captures[1].length; + + ++this.lineno; + this.consume(indents + 1); + + if (' ' == this.input[0] || '\t' == this.input[0]) { + throw new Error('Invalid indentation, you can use tabs or spaces but not both'); + } + + // blank line + if ('\n' == this.input[0]) return this.tok('newline'); + + // outdent + if (this.indentStack.length && indents < this.indentStack[0]) { + while (this.indentStack.length && this.indentStack[0] > indents) { + this.stash.push(this.tok('outdent')); + this.indentStack.shift(); + } + tok = this.stash.pop(); + // indent + } else if (indents && indents != this.indentStack[0]) { + this.indentStack.unshift(indents); + tok = this.tok('indent', indents); + // newline + } else { + tok = this.tok('newline'); + } + + return tok; + } + }, + + /** + * Pipe-less text consumed only when + * pipeless is true; + */ + + pipelessText: function() { + if (this.pipeless) { + if ('\n' == this.input[0]) return; + var i = this.input.indexOf('\n'); + if (-1 == i) i = this.input.length; + var str = this.input.substr(0, i); + this.consume(str.length); + return this.tok('text', str); + } + }, + + /** + * ':' + */ + + colon: function() { + return this.scan(/^: */, ':'); + }, + + /** + * Return the next token object, or those + * previously stashed by lookahead. + * + * @return {Object} + * @api private + */ + + advance: function(){ + return this.stashed() + || this.next(); + }, + + /** + * Return the next token object. + * + * @return {Object} + * @api private + */ + + next: function() { + return this.deferred() + || this.eos() + || this.pipelessText() + || this.doctype() + || this.case() + || this.when() + || this.default() + || this.extends() + || this.block() + || this.include() + || this.mixin() + || this.conditional() + || this.each() + || this.while() + || this.assignment() + || this.tag() + || this.filter() + || this.code() + || this.id() + || this.className() + || this.attrs() + || this.indent() + || this.comment() + || this.colon() + || this.text(); + } +}; + +}); // module: lexer.js + +require.register("nodes/block-comment.js", function(module, exports, require){ + +/*! + * Jade - nodes - BlockComment + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var Node = require('./node'); + +/** + * Initialize a `BlockComment` with the given `block`. + * + * @param {String} val + * @param {Block} block + * @param {Boolean} buffer + * @api public + */ + +var BlockComment = module.exports = function BlockComment(val, block, buffer) { + this.block = block; + this.val = val; + this.buffer = buffer; +}; + +/** + * Inherit from `Node`. + */ + +BlockComment.prototype = new Node; +BlockComment.prototype.constructor = BlockComment; + +}); // module: nodes/block-comment.js + +require.register("nodes/block.js", function(module, exports, require){ + +/*! + * Jade - nodes - Block + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var Node = require('./node'); + +/** + * Initialize a new `Block` with an optional `node`. + * + * @param {Node} node + * @api public + */ + +var Block = module.exports = function Block(node){ + this.nodes = []; + if (node) this.push(node); +}; + +/** + * Inherit from `Node`. + */ + +Block.prototype = new Node; +Block.prototype.constructor = Block; + + +/** + * Replace the nodes in `other` with the nodes + * in `this` block. + * + * @param {Block} other + * @api private + */ + +Block.prototype.replace = function(other){ + other.nodes = this.nodes; +}; + +/** + * Pust the given `node`. + * + * @param {Node} node + * @return {Number} + * @api public + */ + +Block.prototype.push = function(node){ + return this.nodes.push(node); +}; + +/** + * Check if this block is empty. + * + * @return {Boolean} + * @api public + */ + +Block.prototype.isEmpty = function(){ + return 0 == this.nodes.length; +}; + +/** + * Unshift the given `node`. + * + * @param {Node} node + * @return {Number} + * @api public + */ + +Block.prototype.unshift = function(node){ + return this.nodes.unshift(node); +}; + +/** + * Return the "last" block. + * + * @return {Block} + * @api private + */ + +Block.prototype.lastBlock = function(){ + var last = this + , node; + for (var i = 0, len = this.nodes.length; i < len; ++i) { + node = this.nodes[i]; + if (node.nodes) last = node.lastBlock(); + else if (node.block && !node.block.isEmpty()) last = node.block.lastBlock(); + } + return last; +}; + + +}); // module: nodes/block.js + +require.register("nodes/case.js", function(module, exports, require){ + +/*! + * Jade - nodes - Case + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var Node = require('./node'); + +/** + * Initialize a new `Case` with `expr`. + * + * @param {String} expr + * @api public + */ + +var Case = exports = module.exports = function Case(expr, block){ + this.expr = expr; + this.block = block; +}; + +/** + * Inherit from `Node`. + */ + +Case.prototype = new Node; +Case.prototype.constructor = Case; + + +var When = exports.When = function When(expr, block){ + this.expr = expr; + this.block = block; + this.debug = false; +}; + +/** + * Inherit from `Node`. + */ + +When.prototype = new Node; +When.prototype.constructor = When; + + + +}); // module: nodes/case.js + +require.register("nodes/code.js", function(module, exports, require){ + +/*! + * Jade - nodes - Code + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var Node = require('./node'); + +/** + * Initialize a `Code` node with the given code `val`. + * Code may also be optionally buffered and escaped. + * + * @param {String} val + * @param {Boolean} buffer + * @param {Boolean} escape + * @api public + */ + +var Code = module.exports = function Code(val, buffer, escape) { + this.val = val; + this.buffer = buffer; + this.escape = escape; + if (val.match(/^ *else/)) this.debug = false; +}; + +/** + * Inherit from `Node`. + */ + +Code.prototype = new Node; +Code.prototype.constructor = Code; + +}); // module: nodes/code.js + +require.register("nodes/comment.js", function(module, exports, require){ + +/*! + * Jade - nodes - Comment + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var Node = require('./node'); + +/** + * Initialize a `Comment` with the given `val`, optionally `buffer`, + * otherwise the comment may render in the output. + * + * @param {String} val + * @param {Boolean} buffer + * @api public + */ + +var Comment = module.exports = function Comment(val, buffer) { + this.val = val; + this.buffer = buffer; +}; + +/** + * Inherit from `Node`. + */ + +Comment.prototype = new Node; +Comment.prototype.constructor = Comment; + +}); // module: nodes/comment.js + +require.register("nodes/doctype.js", function(module, exports, require){ + +/*! + * Jade - nodes - Doctype + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var Node = require('./node'); + +/** + * Initialize a `Doctype` with the given `val`. + * + * @param {String} val + * @api public + */ + +var Doctype = module.exports = function Doctype(val) { + this.val = val; +}; + +/** + * Inherit from `Node`. + */ + +Doctype.prototype = new Node; +Doctype.prototype.constructor = Doctype; + +}); // module: nodes/doctype.js + +require.register("nodes/each.js", function(module, exports, require){ + +/*! + * Jade - nodes - Each + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var Node = require('./node'); + +/** + * Initialize an `Each` node, representing iteration + * + * @param {String} obj + * @param {String} val + * @param {String} key + * @param {Block} block + * @api public + */ + +var Each = module.exports = function Each(obj, val, key, block) { + this.obj = obj; + this.val = val; + this.key = key; + this.block = block; +}; + +/** + * Inherit from `Node`. + */ + +Each.prototype = new Node; +Each.prototype.constructor = Each; + +}); // module: nodes/each.js + +require.register("nodes/filter.js", function(module, exports, require){ + +/*! + * Jade - nodes - Filter + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var Node = require('./node') + , Block = require('./block'); + +/** + * Initialize a `Filter` node with the given + * filter `name` and `block`. + * + * @param {String} name + * @param {Block|Node} block + * @api public + */ + +var Filter = module.exports = function Filter(name, block, attrs) { + this.name = name; + this.block = block; + this.attrs = attrs; + this.isASTFilter = block instanceof Block; +}; + +/** + * Inherit from `Node`. + */ + +Filter.prototype = new Node; +Filter.prototype.constructor = Filter; + +}); // module: nodes/filter.js + +require.register("nodes/index.js", function(module, exports, require){ + +/*! + * Jade - nodes + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +exports.Node = require('./node'); +exports.Tag = require('./tag'); +exports.Code = require('./code'); +exports.Each = require('./each'); +exports.Case = require('./case'); +exports.Text = require('./text'); +exports.Block = require('./block'); +exports.Mixin = require('./mixin'); +exports.Filter = require('./filter'); +exports.Comment = require('./comment'); +exports.Literal = require('./literal'); +exports.BlockComment = require('./block-comment'); +exports.Doctype = require('./doctype'); + +}); // module: nodes/index.js + +require.register("nodes/literal.js", function(module, exports, require){ + +/*! + * Jade - nodes - Literal + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var Node = require('./node'); + +/** + * Initialize a `Literal` node with the given `str. + * + * @param {String} str + * @api public + */ + +var Literal = module.exports = function Literal(str) { + this.str = str + .replace(/\n/g, "\\n") + .replace(/'/g, "\\'"); +}; + +/** + * Inherit from `Node`. + */ + +Literal.prototype = new Node; +Literal.prototype.constructor = Literal; + + +}); // module: nodes/literal.js + +require.register("nodes/mixin.js", function(module, exports, require){ + +/*! + * Jade - nodes - Mixin + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var Node = require('./node'); + +/** + * Initialize a new `Mixin` with `name` and `block`. + * + * @param {String} name + * @param {String} args + * @param {Block} block + * @api public + */ + +var Mixin = module.exports = function Mixin(name, args, block){ + this.name = name; + this.args = args; + this.block = block; +}; + +/** + * Inherit from `Node`. + */ + +Mixin.prototype = new Node; +Mixin.prototype.constructor = Mixin; + + + +}); // module: nodes/mixin.js + +require.register("nodes/node.js", function(module, exports, require){ + +/*! + * Jade - nodes - Node + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Initialize a `Node`. + * + * @api public + */ + +var Node = module.exports = function Node(){}; +}); // module: nodes/node.js + +require.register("nodes/tag.js", function(module, exports, require){ + +/*! + * Jade - nodes - Tag + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var Node = require('./node'), + Block = require('./block'); + +/** + * Initialize a `Tag` node with the given tag `name` and optional `block`. + * + * @param {String} name + * @param {Block} block + * @api public + */ + +var Tag = module.exports = function Tag(name, block) { + this.name = name; + this.attrs = []; + this.block = block || new Block; +}; + +/** + * Inherit from `Node`. + */ + +Tag.prototype = new Node; +Tag.prototype.constructor = Tag; + + +/** + * Set attribute `name` to `val`, keep in mind these become + * part of a raw js object literal, so to quote a value you must + * '"quote me"', otherwise or example 'user.name' is literal JavaScript. + * + * @param {String} name + * @param {String} val + * @return {Tag} for chaining + * @api public + */ + +Tag.prototype.setAttribute = function(name, val){ + this.attrs.push({ name: name, val: val }); + return this; +}; + +/** + * Remove attribute `name` when present. + * + * @param {String} name + * @api public + */ + +Tag.prototype.removeAttribute = function(name){ + for (var i = 0, len = this.attrs.length; i < len; ++i) { + if (this.attrs[i] && this.attrs[i].name == name) { + delete this.attrs[i]; + } + } +}; + +/** + * Get attribute value by `name`. + * + * @param {String} name + * @return {String} + * @api public + */ + +Tag.prototype.getAttribute = function(name){ + for (var i = 0, len = this.attrs.length; i < len; ++i) { + if (this.attrs[i] && this.attrs[i].name == name) { + return this.attrs[i].val; + } + } +}; + +}); // module: nodes/tag.js + +require.register("nodes/text.js", function(module, exports, require){ + +/*! + * Jade - nodes - Text + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var Node = require('./node'); + +/** + * Initialize a `Text` node with optional `line`. + * + * @param {String} line + * @api public + */ + +var Text = module.exports = function Text(line) { + this.nodes = []; + if ('string' == typeof line) this.push(line); +}; + +/** + * Inherit from `Node`. + */ + +Text.prototype = new Node; +Text.prototype.constructor = Text; + + +/** + * Push the given `node.` + * + * @param {Node} node + * @return {Number} + * @api public + */ + +Text.prototype.push = function(node){ + return this.nodes.push(node); +}; + +}); // module: nodes/text.js + +require.register("parser.js", function(module, exports, require){ + +/*! + * Jade - Parser + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var Lexer = require('./lexer') + , nodes = require('./nodes'); + +/** + * Initialize `Parser` with the given input `str` and `filename`. + * + * @param {String} str + * @param {String} filename + * @param {Object} options + * @api public + */ + +var Parser = exports = module.exports = function Parser(str, filename, options){ + this.input = str; + this.lexer = new Lexer(str, options); + this.filename = filename; + this.blocks = {}; + this.options = options; + this.contexts = [this]; +}; + +/** + * Tags that may not contain tags. + */ + +var textOnly = exports.textOnly = ['code', 'script', 'textarea', 'style', 'title']; + +/** + * Parser prototype. + */ + +Parser.prototype = { + + /** + * Push `parser` onto the context stack, + * or pop and return a `Parser`. + */ + + context: function(parser){ + if (parser) { + this.contexts.push(parser); + } else { + return this.contexts.pop(); + } + }, + + /** + * Return the next token object. + * + * @return {Object} + * @api private + */ + + advance: function(){ + return this.lexer.advance(); + }, + + /** + * Skip `n` tokens. + * + * @param {Number} n + * @api private + */ + + skip: function(n){ + while (n--) this.advance(); + }, + + /** + * Single token lookahead. + * + * @return {Object} + * @api private + */ + + peek: function() { + return this.lookahead(1); + }, + + /** + * Return lexer lineno. + * + * @return {Number} + * @api private + */ + + line: function() { + return this.lexer.lineno; + }, + + /** + * `n` token lookahead. + * + * @param {Number} n + * @return {Object} + * @api private + */ + + lookahead: function(n){ + return this.lexer.lookahead(n); + }, + + /** + * Parse input returning a string of js for evaluation. + * + * @return {String} + * @api public + */ + + parse: function(){ + var block = new nodes.Block, parser; + block.line = this.line(); + + while ('eos' != this.peek().type) { + if ('newline' == this.peek().type) { + this.advance(); + } else { + block.push(this.parseExpr()); + } + } + + if (parser = this.extending) { + this.context(parser); + var ast = parser.parse(); + this.context(); + return ast; + } + + return block; + }, + + /** + * Expect the given type, or throw an exception. + * + * @param {String} type + * @api private + */ + + expect: function(type){ + if (this.peek().type === type) { + return this.advance(); + } else { + throw new Error('expected "' + type + '", but got "' + this.peek().type + '"'); + } + }, + + /** + * Accept the given `type`. + * + * @param {String} type + * @api private + */ + + accept: function(type){ + if (this.peek().type === type) { + return this.advance(); + } + }, + + /** + * tag + * | doctype + * | mixin + * | include + * | filter + * | comment + * | text + * | each + * | code + * | id + * | class + */ + + parseExpr: function(){ + switch (this.peek().type) { + case 'tag': + return this.parseTag(); + case 'mixin': + return this.parseMixin(); + case 'block': + return this.parseBlock(); + case 'case': + return this.parseCase(); + case 'when': + return this.parseWhen(); + case 'default': + return this.parseDefault(); + case 'extends': + return this.parseExtends(); + case 'include': + return this.parseInclude(); + case 'doctype': + return this.parseDoctype(); + case 'filter': + return this.parseFilter(); + case 'comment': + return this.parseComment(); + case 'text': + return this.parseText(); + case 'each': + return this.parseEach(); + case 'code': + return this.parseCode(); + case 'id': + case 'class': + var tok = this.advance(); + this.lexer.defer(this.lexer.tok('tag', 'div')); + this.lexer.defer(tok); + return this.parseExpr(); + default: + throw new Error('unexpected token "' + this.peek().type + '"'); + } + }, + + /** + * Text + */ + + parseText: function(){ + var tok = this.expect('text') + , node = new nodes.Text(tok.val); + node.line = this.line(); + return node; + }, + + /** + * ':' expr + * | block + */ + + parseBlockExpansion: function(){ + if (':' == this.peek().type) { + this.advance(); + return new nodes.Block(this.parseExpr()); + } else { + return this.block(); + } + }, + + /** + * case + */ + + parseCase: function(){ + var val = this.expect('case').val + , node = new nodes.Case(val); + node.line = this.line(); + node.block = this.block(); + return node; + }, + + /** + * when + */ + + parseWhen: function(){ + var val = this.expect('when').val + return new nodes.Case.When(val, this.parseBlockExpansion()); + }, + + /** + * default + */ + + parseDefault: function(){ + this.expect('default'); + return new nodes.Case.When('default', this.parseBlockExpansion()); + }, + + /** + * code + */ + + parseCode: function(){ + var tok = this.expect('code') + , node = new nodes.Code(tok.val, tok.buffer, tok.escape) + , block + , i = 1; + node.line = this.line(); + while (this.lookahead(i) && 'newline' == this.lookahead(i).type) ++i; + block = 'indent' == this.lookahead(i).type; + if (block) { + this.skip(i-1); + node.block = this.block(); + } + return node; + }, + + /** + * comment + */ + + parseComment: function(){ + var tok = this.expect('comment') + , node; + + if ('indent' == this.peek().type) { + node = new nodes.BlockComment(tok.val, this.block(), tok.buffer); + } else { + node = new nodes.Comment(tok.val, tok.buffer); + } + + node.line = this.line(); + return node; + }, + + /** + * doctype + */ + + parseDoctype: function(){ + var tok = this.expect('doctype') + , node = new nodes.Doctype(tok.val); + node.line = this.line(); + return node; + }, + + /** + * filter attrs? text-block + */ + + parseFilter: function(){ + var block + , tok = this.expect('filter') + , attrs = this.accept('attrs'); + + this.lexer.pipeless = true; + block = this.parseTextBlock(); + this.lexer.pipeless = false; + + var node = new nodes.Filter(tok.val, block, attrs && attrs.attrs); + node.line = this.line(); + return node; + }, + + /** + * tag ':' attrs? block + */ + + parseASTFilter: function(){ + var block + , tok = this.expect('tag') + , attrs = this.accept('attrs'); + + this.expect(':'); + block = this.block(); + + var node = new nodes.Filter(tok.val, block, attrs && attrs.attrs); + node.line = this.line(); + return node; + }, + + /** + * each block + */ + + parseEach: function(){ + var tok = this.expect('each') + , node = new nodes.Each(tok.code, tok.val, tok.key); + node.line = this.line(); + node.block = this.block(); + return node; + }, + + /** + * 'extends' name + */ + + parseExtends: function(){ + var path = require('path') + , fs = require('fs') + , dirname = path.dirname + , basename = path.basename + , join = path.join; + + if (!this.filename) + throw new Error('the "filename" option is required to extend templates'); + + var path = name = this.expect('extends').val.trim() + , dir = dirname(this.filename); + + var path = join(dir, path + '.jade') + , str = fs.readFileSync(path, 'utf8') + , parser = new Parser(str, path, this.options); + + parser.blocks = this.blocks; + parser.contexts = this.contexts; + this.extending = parser; + + // TODO: null node + return new nodes.Literal(''); + }, + + /** + * 'block' name block + */ + + parseBlock: function(){ + var name = this.expect('block').val.trim(); + var block = 'indent' == this.peek().type + ? this.block() + : new nodes.Block(new nodes.Literal('')); + return this.blocks[name] = this.blocks[name] || block; + }, + + /** + * include block? + */ + + parseInclude: function(){ + var path = require('path') + , fs = require('fs') + , dirname = path.dirname + , basename = path.basename + , join = path.join; + + var path = name = this.expect('include').val.trim() + , dir = dirname(this.filename); + + if (!this.filename) + throw new Error('the "filename" option is required to use includes'); + + // no extension + if (!~basename(path).indexOf('.')) { + path += '.jade'; + } + + // non-jade + if ('.jade' != path.substr(-5)) { + var path = join(dir, path) + , str = fs.readFileSync(path, 'utf8'); + return new nodes.Literal(str); + } + + var path = join(dir, path) + , str = fs.readFileSync(path, 'utf8') + , parser = new Parser(str, path, this.options); + + this.context(parser); + var ast = parser.parse(); + this.context(); + ast.filename = path; + + if ('indent' == this.peek().type) { + ast.lastBlock().push(this.block()); + } + + return ast; + }, + + /** + * mixin block + */ + + parseMixin: function(){ + var tok = this.expect('mixin') + , name = tok.val + , args = tok.args; + var block = 'indent' == this.peek().type + ? this.block() + : null; + return new nodes.Mixin(name, args, block); + }, + + /** + * indent (text | newline)* outdent + */ + + parseTextBlock: function(){ + var text = new nodes.Text; + text.line = this.line(); + var spaces = this.expect('indent').val; + if (null == this._spaces) this._spaces = spaces; + var indent = Array(spaces - this._spaces + 1).join(' '); + while ('outdent' != this.peek().type) { + switch (this.peek().type) { + case 'newline': + text.push('\\n'); + this.advance(); + break; + case 'indent': + text.push('\\n'); + this.parseTextBlock().nodes.forEach(function(node){ + text.push(node); + }); + text.push('\\n'); + break; + default: + text.push(indent + this.advance().val); + } + } + + if (spaces == this._spaces) this._spaces = null; + this.expect('outdent'); + return text; + }, + + /** + * indent expr* outdent + */ + + block: function(){ + var block = new nodes.Block; + block.line = this.line(); + this.expect('indent'); + while ('outdent' != this.peek().type) { + if ('newline' == this.peek().type) { + this.advance(); + } else { + block.push(this.parseExpr()); + } + } + this.expect('outdent'); + return block; + }, + + /** + * tag (attrs | class | id)* (text | code | ':')? newline* block? + */ + + parseTag: function(){ + // ast-filter look-ahead + var i = 2; + if ('attrs' == this.lookahead(i).type) ++i; + if (':' == this.lookahead(i).type) { + if ('indent' == this.lookahead(++i).type) { + return this.parseASTFilter(); + } + } + + var name = this.advance().val + , tag = new nodes.Tag(name) + , dot; + + tag.line = this.line(); + + // (attrs | class | id)* + out: + while (true) { + switch (this.peek().type) { + case 'id': + case 'class': + var tok = this.advance(); + tag.setAttribute(tok.type, "'" + tok.val + "'"); + continue; + case 'attrs': + var obj = this.advance().attrs + , names = Object.keys(obj); + for (var i = 0, len = names.length; i < len; ++i) { + var name = names[i] + , val = obj[name]; + tag.setAttribute(name, val); + } + continue; + default: + break out; + } + } + + // check immediate '.' + if ('.' == this.peek().val) { + dot = tag.textOnly = true; + this.advance(); + } + + // (text | code | ':')? + switch (this.peek().type) { + case 'text': + tag.text = this.parseText(); + break; + case 'code': + tag.code = this.parseCode(); + break; + case ':': + this.advance(); + tag.block = new nodes.Block; + tag.block.push(this.parseTag()); + break; + } + + // newline* + while ('newline' == this.peek().type) this.advance(); + + tag.textOnly = tag.textOnly || ~textOnly.indexOf(tag.name); + + // script special-case + if ('script' == tag.name) { + var type = tag.getAttribute('type'); + if (!dot && type && 'text/javascript' != type.replace(/^['"]|['"]$/g, '')) { + tag.textOnly = false; + } + } + + // block? + if ('indent' == this.peek().type) { + if (tag.textOnly) { + this.lexer.pipeless = true; + tag.block = this.parseTextBlock(); + this.lexer.pipeless = false; + } else { + var block = this.block(); + if (tag.block) { + for (var i = 0, len = block.nodes.length; i < len; ++i) { + tag.block.push(block.nodes[i]); + } + } else { + tag.block = block; + } + } + } + + return tag; + } +}; + +}); // module: parser.js + +require.register("runtime.js", function(module, exports, require){ + +/*! + * Jade - runtime + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Lame Array.isArray() polyfill for now. + */ + +if (!Array.isArray) { + Array.isArray = function(arr){ + return '[object Array]' == Object.prototype.toString.call(arr); + }; +} + +/** + * Lame Object.keys() polyfill for now. + */ + +if (!Object.keys) { + Object.keys = function(obj){ + var arr = []; + for (var key in obj) { + if (obj.hasOwnProperty(key)) { + arr.push(key); + } + } + return arr; + } +} + +/** + * Render the given attributes object. + * + * @param {Object} obj + * @return {String} + * @api private + */ + +exports.attrs = function attrs(obj){ + var buf = [] + , terse = obj.terse; + delete obj.terse; + var keys = Object.keys(obj) + , len = keys.length; + if (len) { + buf.push(''); + for (var i = 0; i < len; ++i) { + var key = keys[i] + , val = obj[key]; + if ('boolean' == typeof val || null == val) { + if (val) { + terse + ? buf.push(key) + : buf.push(key + '="' + key + '"'); + } + } else if ('class' == key && Array.isArray(val)) { + buf.push(key + '="' + exports.escape(val.join(' ')) + '"'); + } else { + buf.push(key + '="' + exports.escape(val) + '"'); + } + } + } + return buf.join(' '); +}; + +/** + * Escape the given string of `html`. + * + * @param {String} html + * @return {String} + * @api private + */ + +exports.escape = function escape(html){ + return String(html) + .replace(/&(?!\w+;)/g, '&') + .replace(//g, '>') + .replace(/"/g, '"'); +}; + +/** + * Re-throw the given `err` in context to the + * the jade in `filename` at the given `lineno`. + * + * @param {Error} err + * @param {String} filename + * @param {String} lineno + * @api private + */ + +exports.rethrow = function rethrow(err, filename, lineno){ + if (!filename) throw err; + + var context = 3 + , str = require('fs').readFileSync(filename, 'utf8') + , lines = str.split('\n') + , start = Math.max(lineno - context, 0) + , end = Math.min(lines.length, lineno + context); + + // Error context + var context = lines.slice(start, end).map(function(line, i){ + var curr = i + start + 1; + return (curr == lineno ? ' > ' : ' ') + + curr + + '| ' + + line; + }).join('\n'); + + // Alter exception message + err.path = filename; + err.message = (filename || 'Jade') + ':' + lineno + + '\n' + context + '\n\n' + err.message; + throw err; +}; + +}); // module: runtime.js + +require.register("self-closing.js", function(module, exports, require){ + +/*! + * Jade - self closing tags + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +module.exports = [ + 'meta' + , 'img' + , 'link' + , 'input' + , 'area' + , 'base' + , 'col' + , 'br' + , 'hr' +]; +}); // module: self-closing.js + +require.register("utils.js", function(module, exports, require){ + +/*! + * Jade - utils + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Convert interpolation in the given string to JavaScript. + * + * @param {String} str + * @return {String} + * @api private + */ + +var interpolate = exports.interpolate = function(str){ + return str.replace(/(\\)?([#!]){(.*?)}/g, function(str, escape, flag, code){ + return escape + ? str + : "' + " + + ('!' == flag ? '' : 'escape') + + "((interp = " + code.replace(/\\'/g, "'") + + ") == null ? '' : interp) + '"; + }); +}; + +/** + * Escape single quotes in `str`. + * + * @param {String} str + * @return {String} + * @api private + */ + +var escape = exports.escape = function(str) { + return str.replace(/'/g, "\\'"); +}; + +/** + * Interpolate, and escape the given `str`. + * + * @param {String} str + * @return {String} + * @api private + */ + +exports.text = function(str){ + return interpolate(escape(str)); +}; +}); // module: utils.js diff --git a/node_modules/jade/jade.min.js b/node_modules/jade/jade.min.js new file mode 100644 index 0000000..52e2332 --- /dev/null +++ b/node_modules/jade/jade.min.js @@ -0,0 +1,3 @@ +// CommonJS require() +function require(p){var path=require.resolve(p),mod=require.modules[path];if(!mod)throw new Error('failed to require "'+p+'"');return mod.exports||(mod.exports={},mod.call(mod.exports,mod,mod.exports,require.relative(path))),mod.exports}require.modules={},require.resolve=function(path){var orig=path,reg=path+".js",index=path+"/index.js";return require.modules[reg]&®||require.modules[index]&&index||orig},require.register=function(path,fn){require.modules[path]=fn},require.relative=function(parent){return function(p){if("."!=p[0])return require(p);var path=parent.split("/"),segs=p.split("/");path.pop();for(var i=0;i",this.doctype=doctype,this.terse="5"==name||"html"==name,this.xml=0==this.doctype.indexOf(""):this.buffer("/>")):(tag.attrs.length?(this.buffer("<"+name),tag.attrs.length&&this.visitAttributes(tag.attrs),this.buffer(">")):this.buffer("<"+name+">"),tag.code&&this.visitCode(tag.code),tag.text&&this.buffer(utils.text(tag.text.nodes[0].trimLeft())),this.escape="pre"==tag.name,this.visit(tag.block),this.pp&&!~inlineTags.indexOf(name)&&!tag.textOnly&&this.buffer("\\n"+Array(this.indents).join(" ")),this.buffer("")),this.indents--},visitFilter:function(filter){var fn=filters[filter.name];if(!fn)throw filter.isASTFilter?new Error('unknown ast filter "'+filter.name+':"'):new Error('unknown filter ":'+filter.name+'"');if(filter.isASTFilter)this.buf.push(fn(filter.block,this,filter.attrs));else{var text=filter.block.nodes.join("");this.buffer(utils.text(fn(text,filter.attrs)))}},visitText:function(text){text=utils.text(text.nodes.join("")),this.escape&&(text=escape(text)),this.buffer(text),this.buffer("\\n")},visitComment:function(comment){if(!comment.buffer)return;this.pp&&this.buffer("\\n"+Array(this.indents+1).join(" ")),this.buffer("")},visitBlockComment:function(comment){if(!comment.buffer)return;0==comment.val.trim().indexOf("if")?(this.buffer("")):(this.buffer(""))},visitCode:function(code){if(code.buffer){var val=code.val.trimLeft();this.buf.push("var __val__ = "+val),val='null == __val__ ? "" : __val__',code.escape&&(val="escape("+val+")"),this.buf.push("buf.push("+val+");")}else this.buf.push(code.val);code.block&&(code.buffer||this.buf.push("{"),this.visit(code.block),code.buffer||this.buf.push("}"))},visitEach:function(each){this.buf.push("// iterate "+each.obj+"\n"+"(function(){\n"+" if ('number' == typeof "+each.obj+".length) {\n"+" for (var "+each.key+" = 0, $$l = "+each.obj+".length; "+each.key+" < $$l; "+each.key+"++) {\n"+" var "+each.val+" = "+each.obj+"["+each.key+"];\n"),this.visit(each.block),this.buf.push(" }\n } else {\n for (var "+each.key+" in "+each.obj+") {\n"+" if ("+each.obj+".hasOwnProperty("+each.key+")){"+" var "+each.val+" = "+each.obj+"["+each.key+"];\n"),this.visit(each.block),this.buf.push(" }\n"),this.buf.push(" }\n }\n}).call(this);\n")},visitAttributes:function(attrs){var buf=[],classes=[];this.terse&&buf.push("terse: true"),attrs.forEach(function(attr){if(attr.name=="class")classes.push("("+attr.val+")");else{var pair="'"+attr.name+"':("+attr.val+")";buf.push(pair)}}),classes.length&&(classes=classes.join(" + ' ' + "),buf.push("class: "+classes)),buf=buf.join(", ").replace("class:",'"class":'),this.buf.push("buf.push(attrs({ "+buf+" }));")}};function escape(html){return String(html).replace(/&(?!\w+;)/g,"&").replace(//g,">").replace(/"/g,""")}}),require.register("doctypes.js",function(module,exports,require){module.exports={5:"",xml:'',"default":'',transitional:'',strict:'',frameset:'',1.1:'',basic:'',mobile:''}}),require.register("filters.js",function(module,exports,require){module.exports={cdata:function(str){return""},sass:function(str){str=str.replace(/\\n/g,"\n");var sass=require("sass").render(str).replace(/\n/g,"\\n");return'"},stylus:function(str,options){var ret;str=str.replace(/\\n/g,"\n");var stylus=require("stylus");return stylus(str,options).render(function(err,css){if(err)throw err;ret=css.replace(/\n/g,"\\n")}),'"},less:function(str){var ret;return str=str.replace(/\\n/g,"\n"),require("less").render(str,function(err,css){if(err)throw err;ret='"}),ret},markdown:function(str){var md;try{md=require("markdown")}catch(err){try{md=require("discount")}catch(err){try{md=require("markdown-js")}catch(err){throw new Error("Cannot find markdown library, install markdown or discount")}}}return str=str.replace(/\\n/g,"\n"),md.parse(str).replace(/\n/g,"\\n").replace(/'/g,"'")},coffeescript:function(str){str=str.replace(/\\n/g,"\n");var js=require("coffee-script").compile(str).replace(/\n/g,"\\n");return'"}}}),require.register("inline-tags.js",function(module,exports,require){module.exports=["a","abbr","acronym","b","br","code","em","font","i","img","ins","kbd","map","samp","small","span","strong","sub","sup"]}),require.register("jade.js",function(module,exports,require){var Parser=require("./parser"),Lexer=require("./lexer"),Compiler=require("./compiler"),runtime=require("./runtime");exports.version="0.17.0",exports.selfClosing=require("./self-closing"),exports.doctypes=require("./doctypes"),exports.filters=require("./filters"),exports.utils=require("./utils"),exports.Compiler=Compiler,exports.Parser=Parser,exports.Lexer=Lexer,exports.nodes=require("./nodes"),exports.runtime=runtime,exports.cache={};function parse(str,options){try{var parser=new Parser(str,options.filename,options),compiler=new(options.compiler||Compiler)(parser.parse(),options),js=compiler.compile();return options.debug&&console.error("\nCompiled Function:\n\n%s",js.replace(/^/gm," ")),"var buf = [];\n"+(options.self?"var self = locals || {};\n"+js:"with (locals || {}) {\n"+js+"\n}\n")+'return buf.join("");'}catch(err){parser=parser.context(),runtime.rethrow(err,parser.filename,parser.lexer.lineno)}}exports.compile=function(str,options){var options=options||{},client=options.client,filename=options.filename?JSON.stringify(options.filename):"undefined",fn;return options.compileDebug!==!1?fn=["var __ = [{ lineno: 1, filename: "+filename+" }];","try {",parse(String(str),options||{}),"} catch (err) {"," rethrow(err, __[0].filename, __[0].lineno);","}"].join("\n"):fn=parse(String(str),options||{}),client&&(fn="var attrs = jade.attrs, escape = jade.escape, rethrow = jade.rethrow;\n"+fn),fn=new Function("locals, attrs, escape, rethrow",fn),client?fn:function(locals){return fn(locals,runtime.attrs,runtime.escape,runtime.rethrow)}},exports.render=function(str,options,fn){"function"==typeof options&&(fn=options,options={});if(options.cache&&!options.filename)return fn(new Error('the "filename" option is required for caching'));try{var path=options.filename,tmpl=options.cache?exports.cache[path]||(exports.cache[path]=exports.compile(str,options)):exports.compile(str,options);fn(null,tmpl(options))}catch(err){fn(err)}},exports.renderFile=function(path,options,fn){var key=path+":string";"function"==typeof options&&(fn=options,options={}),options.filename=path;var str=options.cache?exports.cache[key]||(exports.cache[key]=fs.readFileSync(path,"utf8")):fs.readFileSync(path,"utf8");exports.render(str,options,fn)},exports.__express=exports.renderFile}),require.register("lexer.js",function(module,exports,require){var Lexer=module.exports=function(str,options){options=options||{},this.input=str.replace(/\r\n|\r/g,"\n"),this.colons=options.colons,this.deferredTokens=[],this.lastIndents=0,this.lineno=1,this.stash=[],this.indentStack=[],this.indentRe=null,this.pipeless=!1};Lexer.prototype={tok:function(type,val){return{type:type,line:this.lineno,val:val}},consume:function(len){this.input=this.input.substr(len)},scan:function(regexp,type){var captures;if(captures=regexp.exec(this.input))return this.consume(captures[0].length),this.tok(type,captures[1])},defer:function(tok){this.deferredTokens.push(tok)},lookahead:function(n){var fetch=n-this.stash.length;while(fetch-->0)this.stash.push(this.next());return this.stash[--n]},indexOfDelimiters:function(start,end){var str=this.input,nstart=0,nend=0,pos=0;for(var i=0,len=str.length;iindents)this.stash.push(this.tok("outdent")),this.indentStack.shift();tok=this.stash.pop()}else indents&&indents!=this.indentStack[0]?(this.indentStack.unshift(indents),tok=this.tok("indent",indents)):tok=this.tok("newline");return tok}},pipelessText:function(){if(this.pipeless){if("\n"==this.input[0])return;var i=this.input.indexOf("\n");-1==i&&(i=this.input.length);var str=this.input.substr(0,i);return this.consume(str.length),this.tok("text",str)}},colon:function(){return this.scan(/^: */,":")},advance:function(){return this.stashed()||this.next()},next:function(){return this.deferred()||this.eos()||this.pipelessText()||this.doctype()||this.case()||this.when()||this.default()||this.extends()||this.block()||this.include()||this.mixin()||this.conditional()||this.each()||this.while()||this.assignment()||this.tag()||this.filter()||this.code()||this.id()||this.className()||this.attrs()||this.indent()||this.comment()||this.colon()||this.text()}}}),require.register("nodes/block-comment.js",function(module,exports,require){var Node=require("./node"),BlockComment=module.exports=function(val,block,buffer){this.block=block,this.val=val,this.buffer=buffer};BlockComment.prototype=new Node,BlockComment.prototype.constructor=BlockComment}),require.register("nodes/block.js",function(module,exports,require){var Node=require("./node"),Block=module.exports=function(node){this.nodes=[],node&&this.push(node)};Block.prototype=new Node,Block.prototype.constructor=Block,Block.prototype.replace=function(other){other.nodes=this.nodes},Block.prototype.push=function(node){return this.nodes.push(node)},Block.prototype.isEmpty=function(){return 0==this.nodes.length},Block.prototype.unshift=function(node){return this.nodes.unshift(node)},Block.prototype.lastBlock=function(){var last=this,node;for(var i=0,len=this.nodes.length;i/g,">").replace(/"/g,""")},exports.rethrow=function(err,filename,lineno){if(!filename)throw err;var context=3,str=require("fs").readFileSync(filename,"utf8"),lines=str.split("\n"),start=Math.max(lineno-context,0),end=Math.min(lines.length,lineno+context),context=lines.slice(start,end).map(function(line,i){var curr=i+start+1;return(curr==lineno?" > ":" ")+curr+"| "+line}).join("\n");throw err.path=filename,err.message=(filename||"Jade")+":"+lineno+"\n"+context+"\n\n"+err.message,err}}),require.register("self-closing.js",function(module,exports,require){module.exports=["meta","img","link","input","area","base","col","br","hr"]}),require.register("utils.js",function(module,exports,require){var interpolate=exports.interpolate=function(str){return str.replace(/(\\)?([#!]){(.*?)}/g,function(str,escape +,flag,code){return escape?str:"' + "+("!"==flag?"":"escape")+"((interp = "+code.replace(/\\'/g,"'")+") == null ? '' : interp) + '"})},escape=exports.escape=function(str){return str.replace(/'/g,"\\'")};exports.text=function(str){return interpolate(escape(str))}}); \ No newline at end of file diff --git a/node_modules/jade/lib/compiler.js b/node_modules/jade/lib/compiler.js new file mode 100644 index 0000000..cb785d1 --- /dev/null +++ b/node_modules/jade/lib/compiler.js @@ -0,0 +1,501 @@ + +/*! + * Jade - Compiler + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var nodes = require('./nodes') + , filters = require('./filters') + , doctypes = require('./doctypes') + , selfClosing = require('./self-closing') + , inlineTags = require('./inline-tags') + , utils = require('./utils'); + +// if browser +// +// if (!Object.keys) { +// Object.keys = function(obj){ +// var arr = []; +// for (var key in obj) { +// if (obj.hasOwnProperty(key)) { +// arr.push(key); +// } +// } +// return arr; +// } +// } +// +// if (!String.prototype.trimLeft) { +// String.prototype.trimLeft = function(){ +// return this.replace(/^\s+/, ''); +// } +// } +// +// end + + +/** + * Initialize `Compiler` with the given `node`. + * + * @param {Node} node + * @param {Object} options + * @api public + */ + +var Compiler = module.exports = function Compiler(node, options) { + this.options = options = options || {}; + this.node = node; + this.hasCompiledDoctype = false; + this.hasCompiledTag = false; + this.pp = options.pretty || false; + this.debug = false !== options.compileDebug; + this.indents = 0; + if (options.doctype) this.setDoctype(options.doctype); +}; + +/** + * Compiler prototype. + */ + +Compiler.prototype = { + + /** + * Compile parse tree to JavaScript. + * + * @api public + */ + + compile: function(){ + this.buf = ['var interp;']; + this.lastBufferedIdx = -1 + this.visit(this.node); + return this.buf.join('\n'); + }, + + /** + * Sets the default doctype `name`. Sets terse mode to `true` when + * html 5 is used, causing self-closing tags to end with ">" vs "/>", + * and boolean attributes are not mirrored. + * + * @param {string} name + * @api public + */ + + setDoctype: function(name){ + var doctype = doctypes[(name || 'default').toLowerCase()]; + doctype = doctype || ''; + this.doctype = doctype; + this.terse = '5' == name || 'html' == name; + this.xml = 0 == this.doctype.indexOf('" vs "/>", + * and boolean attributes are not mirrored. + * + * @param {Doctype} doctype + * @api public + */ + + visitDoctype: function(doctype){ + if (doctype && (doctype.val || !this.doctype)) { + this.setDoctype(doctype.val || 'default'); + } + + if (this.doctype) this.buffer(this.doctype); + this.hasCompiledDoctype = true; + }, + + /** + * Visit `mixin`, generating a function that + * may be called within the template. + * + * @param {Mixin} mixin + * @api public + */ + + visitMixin: function(mixin){ + var name = mixin.name.replace(/-/g, '_') + '_mixin' + , args = mixin.args || ''; + + if (mixin.block) { + this.buf.push('var ' + name + ' = function(' + args + '){'); + this.visit(mixin.block); + this.buf.push('}'); + } else { + this.buf.push(name + '(' + args + ');'); + } + }, + + /** + * Visit `tag` buffering tag markup, generating + * attributes, visiting the `tag`'s code and block. + * + * @param {Tag} tag + * @api public + */ + + visitTag: function(tag){ + this.indents++; + var name = tag.name; + + if (!this.hasCompiledTag) { + if (!this.hasCompiledDoctype && 'html' == name) { + this.visitDoctype(); + } + this.hasCompiledTag = true; + } + + // pretty print + if (this.pp && inlineTags.indexOf(name) == -1) { + this.buffer('\\n' + Array(this.indents).join(' ')); + } + + if (~selfClosing.indexOf(name) && !this.xml) { + this.buffer('<' + name); + this.visitAttributes(tag.attrs); + this.terse + ? this.buffer('>') + : this.buffer('/>'); + } else { + // Optimize attributes buffering + if (tag.attrs.length) { + this.buffer('<' + name); + if (tag.attrs.length) this.visitAttributes(tag.attrs); + this.buffer('>'); + } else { + this.buffer('<' + name + '>'); + } + if (tag.code) this.visitCode(tag.code); + if (tag.text) this.buffer(utils.text(tag.text.nodes[0].trimLeft())); + this.escape = 'pre' == tag.name; + this.visit(tag.block); + + // pretty print + if (this.pp && !~inlineTags.indexOf(name) && !tag.textOnly) { + this.buffer('\\n' + Array(this.indents).join(' ')); + } + + this.buffer(''); + } + this.indents--; + }, + + /** + * Visit `filter`, throwing when the filter does not exist. + * + * @param {Filter} filter + * @api public + */ + + visitFilter: function(filter){ + var fn = filters[filter.name]; + + // unknown filter + if (!fn) { + if (filter.isASTFilter) { + throw new Error('unknown ast filter "' + filter.name + ':"'); + } else { + throw new Error('unknown filter ":' + filter.name + '"'); + } + } + if (filter.isASTFilter) { + this.buf.push(fn(filter.block, this, filter.attrs)); + } else { + var text = filter.block.nodes.join(''); + this.buffer(utils.text(fn(text, filter.attrs))); + } + }, + + /** + * Visit `text` node. + * + * @param {Text} text + * @api public + */ + + visitText: function(text){ + text = utils.text(text.nodes.join('')); + if (this.escape) text = escape(text); + this.buffer(text); + this.buffer('\\n'); + }, + + /** + * Visit a `comment`, only buffering when the buffer flag is set. + * + * @param {Comment} comment + * @api public + */ + + visitComment: function(comment){ + if (!comment.buffer) return; + if (this.pp) this.buffer('\\n' + Array(this.indents + 1).join(' ')); + this.buffer(''); + }, + + /** + * Visit a `BlockComment`. + * + * @param {Comment} comment + * @api public + */ + + visitBlockComment: function(comment){ + if (!comment.buffer) return; + if (0 == comment.val.trim().indexOf('if')) { + this.buffer(''); + } else { + this.buffer(''); + } + }, + + /** + * Visit `code`, respecting buffer / escape flags. + * If the code is followed by a block, wrap it in + * a self-calling function. + * + * @param {Code} code + * @api public + */ + + visitCode: function(code){ + // Wrap code blocks with {}. + // we only wrap unbuffered code blocks ATM + // since they are usually flow control + + // Buffer code + if (code.buffer) { + var val = code.val.trimLeft(); + this.buf.push('var __val__ = ' + val); + val = 'null == __val__ ? "" : __val__'; + if (code.escape) val = 'escape(' + val + ')'; + this.buf.push("buf.push(" + val + ");"); + } else { + this.buf.push(code.val); + } + + // Block support + if (code.block) { + if (!code.buffer) this.buf.push('{'); + this.visit(code.block); + if (!code.buffer) this.buf.push('}'); + } + }, + + /** + * Visit `each` block. + * + * @param {Each} each + * @api public + */ + + visitEach: function(each){ + this.buf.push('' + + '// iterate ' + each.obj + '\n' + + '(function(){\n' + + ' if (\'number\' == typeof ' + each.obj + '.length) {\n' + + ' for (var ' + each.key + ' = 0, $$l = ' + each.obj + '.length; ' + each.key + ' < $$l; ' + each.key + '++) {\n' + + ' var ' + each.val + ' = ' + each.obj + '[' + each.key + '];\n'); + + this.visit(each.block); + + this.buf.push('' + + ' }\n' + + ' } else {\n' + + ' for (var ' + each.key + ' in ' + each.obj + ') {\n' + // if browser + // + ' if (' + each.obj + '.hasOwnProperty(' + each.key + ')){' + // end + + ' var ' + each.val + ' = ' + each.obj + '[' + each.key + '];\n'); + + this.visit(each.block); + + // if browser + // this.buf.push(' }\n'); + // end + + this.buf.push(' }\n }\n}).call(this);\n'); + }, + + /** + * Visit `attrs`. + * + * @param {Array} attrs + * @api public + */ + + visitAttributes: function(attrs){ + var buf = [] + , classes = []; + + if (this.terse) buf.push('terse: true'); + + attrs.forEach(function(attr){ + if (attr.name == 'class') { + classes.push('(' + attr.val + ')'); + } else { + var pair = "'" + attr.name + "':(" + attr.val + ')'; + buf.push(pair); + } + }); + + if (classes.length) { + classes = classes.join(" + ' ' + "); + buf.push("class: " + classes); + } + + buf = buf.join(', ').replace('class:', '"class":'); + + this.buf.push("buf.push(attrs({ " + buf + " }));"); + } +}; + +/** + * Escape the given string of `html`. + * + * @param {String} html + * @return {String} + * @api private + */ + +function escape(html){ + return String(html) + .replace(/&(?!\w+;)/g, '&') + .replace(//g, '>') + .replace(/"/g, '"'); +} diff --git a/node_modules/jade/lib/doctypes.js b/node_modules/jade/lib/doctypes.js new file mode 100644 index 0000000..feeb560 --- /dev/null +++ b/node_modules/jade/lib/doctypes.js @@ -0,0 +1,18 @@ + +/*! + * Jade - doctypes + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +module.exports = { + '5': '' + , 'xml': '' + , 'default': '' + , 'transitional': '' + , 'strict': '' + , 'frameset': '' + , '1.1': '' + , 'basic': '' + , 'mobile': '' +}; \ No newline at end of file diff --git a/node_modules/jade/lib/filters.js b/node_modules/jade/lib/filters.js new file mode 100644 index 0000000..dd1b99d --- /dev/null +++ b/node_modules/jade/lib/filters.js @@ -0,0 +1,92 @@ + +/*! + * Jade - filters + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +module.exports = { + + /** + * Wrap text with CDATA block. + */ + + cdata: function(str){ + return ''; + }, + + /** + * Transform sass to css, wrapped in style tags. + */ + + sass: function(str){ + str = str.replace(/\\n/g, '\n'); + var sass = require('sass').render(str).replace(/\n/g, '\\n'); + return ''; + }, + + /** + * Transform stylus to css, wrapped in style tags. + */ + + stylus: function(str, options){ + var ret; + str = str.replace(/\\n/g, '\n'); + var stylus = require('stylus'); + stylus(str, options).render(function(err, css){ + if (err) throw err; + ret = css.replace(/\n/g, '\\n'); + }); + return ''; + }, + + /** + * Transform less to css, wrapped in style tags. + */ + + less: function(str){ + var ret; + str = str.replace(/\\n/g, '\n'); + require('less').render(str, function(err, css){ + if (err) throw err; + ret = ''; + }); + return ret; + }, + + /** + * Transform markdown to html. + */ + + markdown: function(str){ + var md; + + // support markdown / discount + try { + md = require('markdown'); + } catch (err){ + try { + md = require('discount'); + } catch (err) { + try { + md = require('markdown-js'); + } catch (err) { + throw new Error('Cannot find markdown library, install markdown or discount'); + } + } + } + + str = str.replace(/\\n/g, '\n'); + return md.parse(str).replace(/\n/g, '\\n').replace(/'/g,'''); + }, + + /** + * Transform coffeescript to javascript. + */ + + coffeescript: function(str){ + str = str.replace(/\\n/g, '\n'); + var js = require('coffee-script').compile(str).replace(/\n/g, '\\n'); + return ''; + } +}; diff --git a/node_modules/jade/lib/index.js b/node_modules/jade/lib/index.js new file mode 120000 index 0000000..6a783c2 --- /dev/null +++ b/node_modules/jade/lib/index.js @@ -0,0 +1 @@ +jade.js \ No newline at end of file diff --git a/node_modules/jade/lib/inline-tags.js b/node_modules/jade/lib/inline-tags.js new file mode 100644 index 0000000..491de0b --- /dev/null +++ b/node_modules/jade/lib/inline-tags.js @@ -0,0 +1,28 @@ + +/*! + * Jade - inline tags + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +module.exports = [ + 'a' + , 'abbr' + , 'acronym' + , 'b' + , 'br' + , 'code' + , 'em' + , 'font' + , 'i' + , 'img' + , 'ins' + , 'kbd' + , 'map' + , 'samp' + , 'small' + , 'span' + , 'strong' + , 'sub' + , 'sup' +]; \ No newline at end of file diff --git a/node_modules/jade/lib/jade.js b/node_modules/jade/lib/jade.js new file mode 100644 index 0000000..14e32db --- /dev/null +++ b/node_modules/jade/lib/jade.js @@ -0,0 +1,235 @@ + +/*! + * Jade + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var Parser = require('./parser') + , Lexer = require('./lexer') + , Compiler = require('./compiler') + , runtime = require('./runtime') +// if node + , fs = require('fs'); +// end + +/** + * Library version. + */ + +exports.version = '0.18.0'; + +/** + * Expose self closing tags. + */ + +exports.selfClosing = require('./self-closing'); + +/** + * Default supported doctypes. + */ + +exports.doctypes = require('./doctypes'); + +/** + * Text filters. + */ + +exports.filters = require('./filters'); + +/** + * Utilities. + */ + +exports.utils = require('./utils'); + +/** + * Expose `Compiler`. + */ + +exports.Compiler = Compiler; + +/** + * Expose `Parser`. + */ + +exports.Parser = Parser; + +/** + * Expose `Lexer`. + */ + +exports.Lexer = Lexer; + +/** + * Nodes. + */ + +exports.nodes = require('./nodes'); + +/** + * Jade runtime helpers. + */ + +exports.runtime = runtime; + +/** + * Template function cache. + */ + +exports.cache = {}; + +/** + * Parse the given `str` of jade and return a function body. + * + * @param {String} str + * @param {Object} options + * @return {String} + * @api private + */ + +function parse(str, options){ + try { + // Parse + var parser = new Parser(str, options.filename, options); + + // Compile + var compiler = new (options.compiler || Compiler)(parser.parse(), options) + , js = compiler.compile(); + + // Debug compiler + if (options.debug) { + console.error('\nCompiled Function:\n\n\033[90m%s\033[0m', js.replace(/^/gm, ' ')); + } + + return '' + + 'var buf = [];\n' + + (options.self + ? 'var self = locals || {};\n' + js + : 'with (locals || {}) {\n' + js + '\n}\n') + + 'return buf.join("");'; + } catch (err) { + parser = parser.context(); + runtime.rethrow(err, parser.filename, parser.lexer.lineno); + } +} + +/** + * Compile a `Function` representation of the given jade `str`. + * + * Options: + * + * - `compileDebug` when `false` debugging code is stripped from the compiled template + * - `client` when `true` the helper functions `escape()` etc will reference `jade.escape()` + * for use with the Jade client-side runtime.js + * + * @param {String} str + * @param {Options} options + * @return {Function} + * @api public + */ + +exports.compile = function(str, options){ + var options = options || {} + , client = options.client + , filename = options.filename + ? JSON.stringify(options.filename) + : 'undefined' + , fn; + + if (options.compileDebug !== false) { + fn = [ + 'var __ = [{ lineno: 1, filename: ' + filename + ' }];' + , 'try {' + , parse(String(str), options || {}) + , '} catch (err) {' + , ' rethrow(err, __[0].filename, __[0].lineno);' + , '}' + ].join('\n'); + } else { + fn = parse(String(str), options || {}); + } + + if (client) { + fn = 'var attrs = jade.attrs, escape = jade.escape, rethrow = jade.rethrow;\n' + fn; + } + + fn = new Function('locals, attrs, escape, rethrow', fn); + + if (client) return fn; + + return function(locals){ + return fn(locals, runtime.attrs, runtime.escape, runtime.rethrow); + }; +}; + +/** + * Render the given `str` of jade and invoke + * the callback `fn(err, str)`. + * + * Options: + * + * - `cache` enable template caching + * - `filename` filename required for `include` / `extends` and caching + * + * @param {String} str + * @param {Object|Function} options or fn + * @param {Function} fn + * @api public + */ + +exports.render = function(str, options, fn){ + // swap args + if ('function' == typeof options) { + fn = options, options = {}; + } + + // cache requires .filename + if (options.cache && !options.filename) { + return fn(new Error('the "filename" option is required for caching')); + } + + try { + var path = options.filename; + var tmpl = options.cache + ? exports.cache[path] || (exports.cache[path] = exports.compile(str, options)) + : exports.compile(str, options); + fn(null, tmpl(options)); + } catch (err) { + fn(err); + } +}; + +/** + * Render a Jade file at the given `path` and callback `fn(err, str)`. + * + * @param {String} path + * @param {Object|Function} options or callback + * @param {Function} fn + * @api public + */ + +exports.renderFile = function(path, options, fn){ + var key = path + ':string'; + + if ('function' == typeof options) { + fn = options, options = {}; + } + + options.filename = path; + var str = options.cache + ? exports.cache[key] || (exports.cache[key] = fs.readFileSync(path, 'utf8')) + : fs.readFileSync(path, 'utf8'); + + exports.render(str, options, fn); +}; + +/** + * Express support. + */ + +exports.__express = exports.renderFile; \ No newline at end of file diff --git a/node_modules/jade/lib/lexer.js b/node_modules/jade/lib/lexer.js new file mode 100644 index 0000000..51bd998 --- /dev/null +++ b/node_modules/jade/lib/lexer.js @@ -0,0 +1,656 @@ + +/*! + * Jade - Lexer + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Initialize `Lexer` with the given `str`. + * + * Options: + * + * - `colons` allow colons for attr delimiters + * + * @param {String} str + * @param {Object} options + * @api private + */ + +var Lexer = module.exports = function Lexer(str, options) { + options = options || {}; + this.input = str.replace(/\r\n|\r/g, '\n'); + this.colons = options.colons; + this.deferredTokens = []; + this.lastIndents = 0; + this.lineno = 1; + this.stash = []; + this.indentStack = []; + this.indentRe = null; + this.pipeless = false; +}; + +/** + * Lexer prototype. + */ + +Lexer.prototype = { + + /** + * Construct a token with the given `type` and `val`. + * + * @param {String} type + * @param {String} val + * @return {Object} + * @api private + */ + + tok: function(type, val){ + return { + type: type + , line: this.lineno + , val: val + } + }, + + /** + * Consume the given `len` of input. + * + * @param {Number} len + * @api private + */ + + consume: function(len){ + this.input = this.input.substr(len); + }, + + /** + * Scan for `type` with the given `regexp`. + * + * @param {String} type + * @param {RegExp} regexp + * @return {Object} + * @api private + */ + + scan: function(regexp, type){ + var captures; + if (captures = regexp.exec(this.input)) { + this.consume(captures[0].length); + return this.tok(type, captures[1]); + } + }, + + /** + * Defer the given `tok`. + * + * @param {Object} tok + * @api private + */ + + defer: function(tok){ + this.deferredTokens.push(tok); + }, + + /** + * Lookahead `n` tokens. + * + * @param {Number} n + * @return {Object} + * @api private + */ + + lookahead: function(n){ + var fetch = n - this.stash.length; + while (fetch-- > 0) this.stash.push(this.next()); + return this.stash[--n]; + }, + + /** + * Return the indexOf `start` / `end` delimiters. + * + * @param {String} start + * @param {String} end + * @return {Number} + * @api private + */ + + indexOfDelimiters: function(start, end){ + var str = this.input + , nstart = 0 + , nend = 0 + , pos = 0; + for (var i = 0, len = str.length; i < len; ++i) { + if (start == str[i]) { + ++nstart; + } else if (end == str[i]) { + if (++nend == nstart) { + pos = i; + break; + } + } + } + return pos; + }, + + /** + * Stashed token. + */ + + stashed: function() { + return this.stash.length + && this.stash.shift(); + }, + + /** + * Deferred token. + */ + + deferred: function() { + return this.deferredTokens.length + && this.deferredTokens.shift(); + }, + + /** + * end-of-source. + */ + + eos: function() { + if (this.input.length) return; + if (this.indentStack.length) { + this.indentStack.shift(); + return this.tok('outdent'); + } else { + return this.tok('eos'); + } + }, + + /** + * Comment. + */ + + comment: function() { + var captures; + if (captures = /^ *\/\/(-)?([^\n]*)/.exec(this.input)) { + this.consume(captures[0].length); + var tok = this.tok('comment', captures[2]); + tok.buffer = '-' != captures[1]; + return tok; + } + }, + + /** + * Tag. + */ + + tag: function() { + var captures; + if (captures = /^(\w[-:\w]*)/.exec(this.input)) { + this.consume(captures[0].length); + var tok, name = captures[1]; + if (':' == name[name.length - 1]) { + name = name.slice(0, -1); + tok = this.tok('tag', name); + this.defer(this.tok(':')); + while (' ' == this.input[0]) this.input = this.input.substr(1); + } else { + tok = this.tok('tag', name); + } + return tok; + } + }, + + /** + * Filter. + */ + + filter: function() { + return this.scan(/^:(\w+)/, 'filter'); + }, + + /** + * Doctype. + */ + + doctype: function() { + return this.scan(/^(?:!!!|doctype) *([^\n]+)?/, 'doctype'); + }, + + /** + * Id. + */ + + id: function() { + return this.scan(/^#([\w-]+)/, 'id'); + }, + + /** + * Class. + */ + + className: function() { + return this.scan(/^\.([\w-]+)/, 'class'); + }, + + /** + * Text. + */ + + text: function() { + return this.scan(/^(?:\| ?)?([^\n]+)/, 'text'); + }, + + /** + * Extends. + */ + + extends: function() { + return this.scan(/^extends +([^\n]+)/, 'extends'); + }, + + /** + * Block. + */ + + block: function() { + return this.scan(/^block +([^\n]+)/, 'block'); + }, + + /** + * Include. + */ + + include: function() { + return this.scan(/^include +([^\n]+)/, 'include'); + }, + + /** + * Case. + */ + + case: function() { + return this.scan(/^case +([^\n]+)/, 'case'); + }, + + /** + * When. + */ + + when: function() { + return this.scan(/^when +([^:\n]+)/, 'when'); + }, + + /** + * Default. + */ + + default: function() { + return this.scan(/^default */, 'default'); + }, + + /** + * Assignment. + */ + + assignment: function() { + var captures; + if (captures = /^(\w+) += *([^;\n]+)( *;? *)/.exec(this.input)) { + this.consume(captures[0].length); + var name = captures[1] + , val = captures[2]; + return this.tok('code', 'var ' + name + ' = (' + val + ');'); + } + }, + + /** + * Mixin. + */ + + mixin: function(){ + var captures; + if (captures = /^mixin +([-\w]+)(?:\((.*)\))?/.exec(this.input)) { + this.consume(captures[0].length); + var tok = this.tok('mixin', captures[1]); + tok.args = captures[2]; + return tok; + } + }, + + /** + * Conditional. + */ + + conditional: function() { + var captures; + if (captures = /^(if|unless|else if|else)\b([^\n]*)/.exec(this.input)) { + this.consume(captures[0].length); + var type = captures[1] + , js = captures[2]; + + switch (type) { + case 'if': js = 'if (' + js + ')'; break; + case 'unless': js = 'if (!(' + js + '))'; break; + case 'else if': js = 'else if (' + js + ')'; break; + case 'else': js = 'else'; break; + } + + return this.tok('code', js); + } + }, + + /** + * While. + */ + + while: function() { + var captures; + if (captures = /^while +([^\n]+)/.exec(this.input)) { + this.consume(captures[0].length); + return this.tok('code', 'while (' + captures[1] + ')'); + } + }, + + /** + * Each. + */ + + each: function() { + var captures; + if (captures = /^(?:- *)?(?:each|for) +(\w+)(?: *, *(\w+))? * in *([^\n]+)/.exec(this.input)) { + this.consume(captures[0].length); + var tok = this.tok('each', captures[1]); + tok.key = captures[2] || '$index'; + tok.code = captures[3]; + return tok; + } + }, + + /** + * Code. + */ + + code: function() { + var captures; + if (captures = /^(!?=|-)([^\n]+)/.exec(this.input)) { + this.consume(captures[0].length); + var flags = captures[1]; + captures[1] = captures[2]; + var tok = this.tok('code', captures[1]); + tok.escape = flags[0] === '='; + tok.buffer = flags[0] === '=' || flags[1] === '='; + return tok; + } + }, + + /** + * Attributes. + */ + + attrs: function() { + if ('(' == this.input[0]) { + var index = this.indexOfDelimiters('(', ')') + , str = this.input.substr(1, index-1) + , tok = this.tok('attrs') + , len = str.length + , colons = this.colons + , states = ['key'] + , key = '' + , val = '' + , quote + , c; + + function state(){ + return states[states.length - 1]; + } + + function interpolate(attr) { + return attr.replace(/#\{([^}]+)\}/g, function(_, expr){ + return quote + " + (" + expr + ") + " + quote; + }); + } + + this.consume(index + 1); + tok.attrs = {}; + + function parse(c) { + var real = c; + // TODO: remove when people fix ":" + if (colons && ':' == c) c = '='; + switch (c) { + case ',': + case '\n': + switch (state()) { + case 'expr': + case 'array': + case 'string': + case 'object': + val += c; + break; + default: + states.push('key'); + val = val.trim(); + key = key.trim(); + if ('' == key) return; + tok.attrs[key.replace(/^['"]|['"]$/g, '')] = '' == val + ? true + : interpolate(val); + key = val = ''; + } + break; + case '=': + switch (state()) { + case 'key char': + key += real; + break; + case 'val': + case 'expr': + case 'array': + case 'string': + case 'object': + val += real; + break; + default: + states.push('val'); + } + break; + case '(': + if ('val' == state() + || 'expr' == state()) states.push('expr'); + val += c; + break; + case ')': + if ('expr' == state() + || 'val' == state()) states.pop(); + val += c; + break; + case '{': + if ('val' == state()) states.push('object'); + val += c; + break; + case '}': + if ('object' == state()) states.pop(); + val += c; + break; + case '[': + if ('val' == state()) states.push('array'); + val += c; + break; + case ']': + if ('array' == state()) states.pop(); + val += c; + break; + case '"': + case "'": + switch (state()) { + case 'key': + states.push('key char'); + break; + case 'key char': + states.pop(); + break; + case 'string': + if (c == quote) states.pop(); + val += c; + break; + default: + states.push('string'); + val += c; + quote = c; + } + break; + case '': + break; + default: + switch (state()) { + case 'key': + case 'key char': + key += c; + break; + default: + val += c; + } + } + } + + for (var i = 0; i < len; ++i) { + parse(str[i]); + } + + parse(','); + + return tok; + } + }, + + /** + * Indent | Outdent | Newline. + */ + + indent: function() { + var captures, re; + + // established regexp + if (this.indentRe) { + captures = this.indentRe.exec(this.input); + // determine regexp + } else { + // tabs + re = /^\n(\t*) */; + captures = re.exec(this.input); + + // spaces + if (captures && !captures[1].length) { + re = /^\n( *)/; + captures = re.exec(this.input); + } + + // established + if (captures && captures[1].length) this.indentRe = re; + } + + if (captures) { + var tok + , indents = captures[1].length; + + ++this.lineno; + this.consume(indents + 1); + + if (' ' == this.input[0] || '\t' == this.input[0]) { + throw new Error('Invalid indentation, you can use tabs or spaces but not both'); + } + + // blank line + if ('\n' == this.input[0]) return this.tok('newline'); + + // outdent + if (this.indentStack.length && indents < this.indentStack[0]) { + while (this.indentStack.length && this.indentStack[0] > indents) { + this.stash.push(this.tok('outdent')); + this.indentStack.shift(); + } + tok = this.stash.pop(); + // indent + } else if (indents && indents != this.indentStack[0]) { + this.indentStack.unshift(indents); + tok = this.tok('indent', indents); + // newline + } else { + tok = this.tok('newline'); + } + + return tok; + } + }, + + /** + * Pipe-less text consumed only when + * pipeless is true; + */ + + pipelessText: function() { + if (this.pipeless) { + if ('\n' == this.input[0]) return; + var i = this.input.indexOf('\n'); + if (-1 == i) i = this.input.length; + var str = this.input.substr(0, i); + this.consume(str.length); + return this.tok('text', str); + } + }, + + /** + * ':' + */ + + colon: function() { + return this.scan(/^: */, ':'); + }, + + /** + * Return the next token object, or those + * previously stashed by lookahead. + * + * @return {Object} + * @api private + */ + + advance: function(){ + return this.stashed() + || this.next(); + }, + + /** + * Return the next token object. + * + * @return {Object} + * @api private + */ + + next: function() { + return this.deferred() + || this.eos() + || this.pipelessText() + || this.doctype() + || this.case() + || this.when() + || this.default() + || this.extends() + || this.block() + || this.include() + || this.mixin() + || this.conditional() + || this.each() + || this.while() + || this.assignment() + || this.tag() + || this.filter() + || this.code() + || this.id() + || this.className() + || this.attrs() + || this.indent() + || this.comment() + || this.colon() + || this.text(); + } +}; diff --git a/node_modules/jade/lib/nodes/block-comment.js b/node_modules/jade/lib/nodes/block-comment.js new file mode 100644 index 0000000..4f41e4a --- /dev/null +++ b/node_modules/jade/lib/nodes/block-comment.js @@ -0,0 +1,33 @@ + +/*! + * Jade - nodes - BlockComment + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var Node = require('./node'); + +/** + * Initialize a `BlockComment` with the given `block`. + * + * @param {String} val + * @param {Block} block + * @param {Boolean} buffer + * @api public + */ + +var BlockComment = module.exports = function BlockComment(val, block, buffer) { + this.block = block; + this.val = val; + this.buffer = buffer; +}; + +/** + * Inherit from `Node`. + */ + +BlockComment.prototype.__proto__ = Node.prototype; \ No newline at end of file diff --git a/node_modules/jade/lib/nodes/block.js b/node_modules/jade/lib/nodes/block.js new file mode 100644 index 0000000..25264e4 --- /dev/null +++ b/node_modules/jade/lib/nodes/block.js @@ -0,0 +1,96 @@ + +/*! + * Jade - nodes - Block + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var Node = require('./node'); + +/** + * Initialize a new `Block` with an optional `node`. + * + * @param {Node} node + * @api public + */ + +var Block = module.exports = function Block(node){ + this.nodes = []; + if (node) this.push(node); +}; + +/** + * Inherit from `Node`. + */ + +Block.prototype.__proto__ = Node.prototype; + +/** + * Replace the nodes in `other` with the nodes + * in `this` block. + * + * @param {Block} other + * @api private + */ + +Block.prototype.replace = function(other){ + other.nodes = this.nodes; +}; + +/** + * Pust the given `node`. + * + * @param {Node} node + * @return {Number} + * @api public + */ + +Block.prototype.push = function(node){ + return this.nodes.push(node); +}; + +/** + * Check if this block is empty. + * + * @return {Boolean} + * @api public + */ + +Block.prototype.isEmpty = function(){ + return 0 == this.nodes.length; +}; + +/** + * Unshift the given `node`. + * + * @param {Node} node + * @return {Number} + * @api public + */ + +Block.prototype.unshift = function(node){ + return this.nodes.unshift(node); +}; + +/** + * Return the "last" block. + * + * @return {Block} + * @api private + */ + +Block.prototype.lastBlock = function(){ + var last = this + , node; + for (var i = 0, len = this.nodes.length; i < len; ++i) { + node = this.nodes[i]; + if (node.nodes) last = node.lastBlock(); + else if (node.block && !node.block.isEmpty()) last = node.block.lastBlock(); + } + return last; +}; + diff --git a/node_modules/jade/lib/nodes/case.js b/node_modules/jade/lib/nodes/case.js new file mode 100644 index 0000000..08ff033 --- /dev/null +++ b/node_modules/jade/lib/nodes/case.js @@ -0,0 +1,43 @@ + +/*! + * Jade - nodes - Case + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var Node = require('./node'); + +/** + * Initialize a new `Case` with `expr`. + * + * @param {String} expr + * @api public + */ + +var Case = exports = module.exports = function Case(expr, block){ + this.expr = expr; + this.block = block; +}; + +/** + * Inherit from `Node`. + */ + +Case.prototype.__proto__ = Node.prototype; + +var When = exports.When = function When(expr, block){ + this.expr = expr; + this.block = block; + this.debug = false; +}; + +/** + * Inherit from `Node`. + */ + +When.prototype.__proto__ = Node.prototype; + diff --git a/node_modules/jade/lib/nodes/code.js b/node_modules/jade/lib/nodes/code.js new file mode 100644 index 0000000..babc675 --- /dev/null +++ b/node_modules/jade/lib/nodes/code.js @@ -0,0 +1,35 @@ + +/*! + * Jade - nodes - Code + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var Node = require('./node'); + +/** + * Initialize a `Code` node with the given code `val`. + * Code may also be optionally buffered and escaped. + * + * @param {String} val + * @param {Boolean} buffer + * @param {Boolean} escape + * @api public + */ + +var Code = module.exports = function Code(val, buffer, escape) { + this.val = val; + this.buffer = buffer; + this.escape = escape; + if (val.match(/^ *else/)) this.debug = false; +}; + +/** + * Inherit from `Node`. + */ + +Code.prototype.__proto__ = Node.prototype; \ No newline at end of file diff --git a/node_modules/jade/lib/nodes/comment.js b/node_modules/jade/lib/nodes/comment.js new file mode 100644 index 0000000..2e1469e --- /dev/null +++ b/node_modules/jade/lib/nodes/comment.js @@ -0,0 +1,32 @@ + +/*! + * Jade - nodes - Comment + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var Node = require('./node'); + +/** + * Initialize a `Comment` with the given `val`, optionally `buffer`, + * otherwise the comment may render in the output. + * + * @param {String} val + * @param {Boolean} buffer + * @api public + */ + +var Comment = module.exports = function Comment(val, buffer) { + this.val = val; + this.buffer = buffer; +}; + +/** + * Inherit from `Node`. + */ + +Comment.prototype.__proto__ = Node.prototype; \ No newline at end of file diff --git a/node_modules/jade/lib/nodes/doctype.js b/node_modules/jade/lib/nodes/doctype.js new file mode 100644 index 0000000..b8f33e5 --- /dev/null +++ b/node_modules/jade/lib/nodes/doctype.js @@ -0,0 +1,29 @@ + +/*! + * Jade - nodes - Doctype + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var Node = require('./node'); + +/** + * Initialize a `Doctype` with the given `val`. + * + * @param {String} val + * @api public + */ + +var Doctype = module.exports = function Doctype(val) { + this.val = val; +}; + +/** + * Inherit from `Node`. + */ + +Doctype.prototype.__proto__ = Node.prototype; \ No newline at end of file diff --git a/node_modules/jade/lib/nodes/each.js b/node_modules/jade/lib/nodes/each.js new file mode 100644 index 0000000..f54101f --- /dev/null +++ b/node_modules/jade/lib/nodes/each.js @@ -0,0 +1,35 @@ + +/*! + * Jade - nodes - Each + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var Node = require('./node'); + +/** + * Initialize an `Each` node, representing iteration + * + * @param {String} obj + * @param {String} val + * @param {String} key + * @param {Block} block + * @api public + */ + +var Each = module.exports = function Each(obj, val, key, block) { + this.obj = obj; + this.val = val; + this.key = key; + this.block = block; +}; + +/** + * Inherit from `Node`. + */ + +Each.prototype.__proto__ = Node.prototype; \ No newline at end of file diff --git a/node_modules/jade/lib/nodes/filter.js b/node_modules/jade/lib/nodes/filter.js new file mode 100644 index 0000000..5a0a237 --- /dev/null +++ b/node_modules/jade/lib/nodes/filter.js @@ -0,0 +1,35 @@ + +/*! + * Jade - nodes - Filter + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var Node = require('./node') + , Block = require('./block'); + +/** + * Initialize a `Filter` node with the given + * filter `name` and `block`. + * + * @param {String} name + * @param {Block|Node} block + * @api public + */ + +var Filter = module.exports = function Filter(name, block, attrs) { + this.name = name; + this.block = block; + this.attrs = attrs; + this.isASTFilter = block instanceof Block; +}; + +/** + * Inherit from `Node`. + */ + +Filter.prototype.__proto__ = Node.prototype; \ No newline at end of file diff --git a/node_modules/jade/lib/nodes/index.js b/node_modules/jade/lib/nodes/index.js new file mode 100644 index 0000000..386ad2f --- /dev/null +++ b/node_modules/jade/lib/nodes/index.js @@ -0,0 +1,20 @@ + +/*! + * Jade - nodes + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +exports.Node = require('./node'); +exports.Tag = require('./tag'); +exports.Code = require('./code'); +exports.Each = require('./each'); +exports.Case = require('./case'); +exports.Text = require('./text'); +exports.Block = require('./block'); +exports.Mixin = require('./mixin'); +exports.Filter = require('./filter'); +exports.Comment = require('./comment'); +exports.Literal = require('./literal'); +exports.BlockComment = require('./block-comment'); +exports.Doctype = require('./doctype'); diff --git a/node_modules/jade/lib/nodes/literal.js b/node_modules/jade/lib/nodes/literal.js new file mode 100644 index 0000000..3ddab65 --- /dev/null +++ b/node_modules/jade/lib/nodes/literal.js @@ -0,0 +1,31 @@ + +/*! + * Jade - nodes - Literal + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var Node = require('./node'); + +/** + * Initialize a `Literal` node with the given `str. + * + * @param {String} str + * @api public + */ + +var Literal = module.exports = function Literal(str) { + this.str = str + .replace(/\n/g, "\\n") + .replace(/'/g, "\\'"); +}; + +/** + * Inherit from `Node`. + */ + +Literal.prototype.__proto__ = Node.prototype; diff --git a/node_modules/jade/lib/nodes/mixin.js b/node_modules/jade/lib/nodes/mixin.js new file mode 100644 index 0000000..f007c84 --- /dev/null +++ b/node_modules/jade/lib/nodes/mixin.js @@ -0,0 +1,34 @@ + +/*! + * Jade - nodes - Mixin + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var Node = require('./node'); + +/** + * Initialize a new `Mixin` with `name` and `block`. + * + * @param {String} name + * @param {String} args + * @param {Block} block + * @api public + */ + +var Mixin = module.exports = function Mixin(name, args, block){ + this.name = name; + this.args = args; + this.block = block; +}; + +/** + * Inherit from `Node`. + */ + +Mixin.prototype.__proto__ = Node.prototype; + diff --git a/node_modules/jade/lib/nodes/node.js b/node_modules/jade/lib/nodes/node.js new file mode 100644 index 0000000..0669e67 --- /dev/null +++ b/node_modules/jade/lib/nodes/node.js @@ -0,0 +1,14 @@ + +/*! + * Jade - nodes - Node + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Initialize a `Node`. + * + * @api public + */ + +var Node = module.exports = function Node(){}; \ No newline at end of file diff --git a/node_modules/jade/lib/nodes/tag.js b/node_modules/jade/lib/nodes/tag.js new file mode 100644 index 0000000..35993c9 --- /dev/null +++ b/node_modules/jade/lib/nodes/tag.js @@ -0,0 +1,80 @@ + +/*! + * Jade - nodes - Tag + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var Node = require('./node'), + Block = require('./block'); + +/** + * Initialize a `Tag` node with the given tag `name` and optional `block`. + * + * @param {String} name + * @param {Block} block + * @api public + */ + +var Tag = module.exports = function Tag(name, block) { + this.name = name; + this.attrs = []; + this.block = block || new Block; +}; + +/** + * Inherit from `Node`. + */ + +Tag.prototype.__proto__ = Node.prototype; + +/** + * Set attribute `name` to `val`, keep in mind these become + * part of a raw js object literal, so to quote a value you must + * '"quote me"', otherwise or example 'user.name' is literal JavaScript. + * + * @param {String} name + * @param {String} val + * @return {Tag} for chaining + * @api public + */ + +Tag.prototype.setAttribute = function(name, val){ + this.attrs.push({ name: name, val: val }); + return this; +}; + +/** + * Remove attribute `name` when present. + * + * @param {String} name + * @api public + */ + +Tag.prototype.removeAttribute = function(name){ + for (var i = 0, len = this.attrs.length; i < len; ++i) { + if (this.attrs[i] && this.attrs[i].name == name) { + delete this.attrs[i]; + } + } +}; + +/** + * Get attribute value by `name`. + * + * @param {String} name + * @return {String} + * @api public + */ + +Tag.prototype.getAttribute = function(name){ + for (var i = 0, len = this.attrs.length; i < len; ++i) { + if (this.attrs[i] && this.attrs[i].name == name) { + return this.attrs[i].val; + } + } +}; diff --git a/node_modules/jade/lib/nodes/text.js b/node_modules/jade/lib/nodes/text.js new file mode 100644 index 0000000..3baff4b --- /dev/null +++ b/node_modules/jade/lib/nodes/text.js @@ -0,0 +1,42 @@ + +/*! + * Jade - nodes - Text + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var Node = require('./node'); + +/** + * Initialize a `Text` node with optional `line`. + * + * @param {String} line + * @api public + */ + +var Text = module.exports = function Text(line) { + this.nodes = []; + if ('string' == typeof line) this.push(line); +}; + +/** + * Inherit from `Node`. + */ + +Text.prototype.__proto__ = Node.prototype; + +/** + * Push the given `node.` + * + * @param {Node} node + * @return {Number} + * @api public + */ + +Text.prototype.push = function(node){ + return this.nodes.push(node); +}; diff --git a/node_modules/jade/lib/parser.js b/node_modules/jade/lib/parser.js new file mode 100644 index 0000000..2ea70f0 --- /dev/null +++ b/node_modules/jade/lib/parser.js @@ -0,0 +1,625 @@ + +/*! + * Jade - Parser + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var Lexer = require('./lexer') + , nodes = require('./nodes'); + +/** + * Initialize `Parser` with the given input `str` and `filename`. + * + * @param {String} str + * @param {String} filename + * @param {Object} options + * @api public + */ + +var Parser = exports = module.exports = function Parser(str, filename, options){ + this.input = str; + this.lexer = new Lexer(str, options); + this.filename = filename; + this.blocks = {}; + this.options = options; + this.contexts = [this]; +}; + +/** + * Tags that may not contain tags. + */ + +var textOnly = exports.textOnly = ['script', 'style']; + +/** + * Parser prototype. + */ + +Parser.prototype = { + + /** + * Push `parser` onto the context stack, + * or pop and return a `Parser`. + */ + + context: function(parser){ + if (parser) { + this.contexts.push(parser); + } else { + return this.contexts.pop(); + } + }, + + /** + * Return the next token object. + * + * @return {Object} + * @api private + */ + + advance: function(){ + return this.lexer.advance(); + }, + + /** + * Skip `n` tokens. + * + * @param {Number} n + * @api private + */ + + skip: function(n){ + while (n--) this.advance(); + }, + + /** + * Single token lookahead. + * + * @return {Object} + * @api private + */ + + peek: function() { + return this.lookahead(1); + }, + + /** + * Return lexer lineno. + * + * @return {Number} + * @api private + */ + + line: function() { + return this.lexer.lineno; + }, + + /** + * `n` token lookahead. + * + * @param {Number} n + * @return {Object} + * @api private + */ + + lookahead: function(n){ + return this.lexer.lookahead(n); + }, + + /** + * Parse input returning a string of js for evaluation. + * + * @return {String} + * @api public + */ + + parse: function(){ + var block = new nodes.Block, parser; + block.line = this.line(); + + while ('eos' != this.peek().type) { + if ('newline' == this.peek().type) { + this.advance(); + } else { + block.push(this.parseExpr()); + } + } + + if (parser = this.extending) { + this.context(parser); + var ast = parser.parse(); + this.context(); + return ast; + } + + return block; + }, + + /** + * Expect the given type, or throw an exception. + * + * @param {String} type + * @api private + */ + + expect: function(type){ + if (this.peek().type === type) { + return this.advance(); + } else { + throw new Error('expected "' + type + '", but got "' + this.peek().type + '"'); + } + }, + + /** + * Accept the given `type`. + * + * @param {String} type + * @api private + */ + + accept: function(type){ + if (this.peek().type === type) { + return this.advance(); + } + }, + + /** + * tag + * | doctype + * | mixin + * | include + * | filter + * | comment + * | text + * | each + * | code + * | id + * | class + */ + + parseExpr: function(){ + switch (this.peek().type) { + case 'tag': + return this.parseTag(); + case 'mixin': + return this.parseMixin(); + case 'block': + return this.parseBlock(); + case 'case': + return this.parseCase(); + case 'when': + return this.parseWhen(); + case 'default': + return this.parseDefault(); + case 'extends': + return this.parseExtends(); + case 'include': + return this.parseInclude(); + case 'doctype': + return this.parseDoctype(); + case 'filter': + return this.parseFilter(); + case 'comment': + return this.parseComment(); + case 'text': + return this.parseText(); + case 'each': + return this.parseEach(); + case 'code': + return this.parseCode(); + case 'id': + case 'class': + var tok = this.advance(); + this.lexer.defer(this.lexer.tok('tag', 'div')); + this.lexer.defer(tok); + return this.parseExpr(); + default: + throw new Error('unexpected token "' + this.peek().type + '"'); + } + }, + + /** + * Text + */ + + parseText: function(){ + var tok = this.expect('text') + , node = new nodes.Text(tok.val); + node.line = this.line(); + return node; + }, + + /** + * ':' expr + * | block + */ + + parseBlockExpansion: function(){ + if (':' == this.peek().type) { + this.advance(); + return new nodes.Block(this.parseExpr()); + } else { + return this.block(); + } + }, + + /** + * case + */ + + parseCase: function(){ + var val = this.expect('case').val + , node = new nodes.Case(val); + node.line = this.line(); + node.block = this.block(); + return node; + }, + + /** + * when + */ + + parseWhen: function(){ + var val = this.expect('when').val + return new nodes.Case.When(val, this.parseBlockExpansion()); + }, + + /** + * default + */ + + parseDefault: function(){ + this.expect('default'); + return new nodes.Case.When('default', this.parseBlockExpansion()); + }, + + /** + * code + */ + + parseCode: function(){ + var tok = this.expect('code') + , node = new nodes.Code(tok.val, tok.buffer, tok.escape) + , block + , i = 1; + node.line = this.line(); + while (this.lookahead(i) && 'newline' == this.lookahead(i).type) ++i; + block = 'indent' == this.lookahead(i).type; + if (block) { + this.skip(i-1); + node.block = this.block(); + } + return node; + }, + + /** + * comment + */ + + parseComment: function(){ + var tok = this.expect('comment') + , node; + + if ('indent' == this.peek().type) { + node = new nodes.BlockComment(tok.val, this.block(), tok.buffer); + } else { + node = new nodes.Comment(tok.val, tok.buffer); + } + + node.line = this.line(); + return node; + }, + + /** + * doctype + */ + + parseDoctype: function(){ + var tok = this.expect('doctype') + , node = new nodes.Doctype(tok.val); + node.line = this.line(); + return node; + }, + + /** + * filter attrs? text-block + */ + + parseFilter: function(){ + var block + , tok = this.expect('filter') + , attrs = this.accept('attrs'); + + this.lexer.pipeless = true; + block = this.parseTextBlock(); + this.lexer.pipeless = false; + + var node = new nodes.Filter(tok.val, block, attrs && attrs.attrs); + node.line = this.line(); + return node; + }, + + /** + * tag ':' attrs? block + */ + + parseASTFilter: function(){ + var block + , tok = this.expect('tag') + , attrs = this.accept('attrs'); + + this.expect(':'); + block = this.block(); + + var node = new nodes.Filter(tok.val, block, attrs && attrs.attrs); + node.line = this.line(); + return node; + }, + + /** + * each block + */ + + parseEach: function(){ + var tok = this.expect('each') + , node = new nodes.Each(tok.code, tok.val, tok.key); + node.line = this.line(); + node.block = this.block(); + return node; + }, + + /** + * 'extends' name + */ + + parseExtends: function(){ + var path = require('path') + , fs = require('fs') + , dirname = path.dirname + , basename = path.basename + , join = path.join; + + if (!this.filename) + throw new Error('the "filename" option is required to extend templates'); + + var path = name = this.expect('extends').val.trim() + , dir = dirname(this.filename); + + var path = join(dir, path + '.jade') + , str = fs.readFileSync(path, 'utf8') + , parser = new Parser(str, path, this.options); + + parser.blocks = this.blocks; + parser.contexts = this.contexts; + this.extending = parser; + + // TODO: null node + return new nodes.Literal(''); + }, + + /** + * 'block' name block + */ + + parseBlock: function(){ + var name = this.expect('block').val.trim(); + var block = 'indent' == this.peek().type + ? this.block() + : new nodes.Block(new nodes.Literal('')); + return this.blocks[name] = this.blocks[name] || block; + }, + + /** + * include block? + */ + + parseInclude: function(){ + var path = require('path') + , fs = require('fs') + , dirname = path.dirname + , basename = path.basename + , join = path.join; + + var path = name = this.expect('include').val.trim() + , dir = dirname(this.filename); + + if (!this.filename) + throw new Error('the "filename" option is required to use includes'); + + // no extension + if (!~basename(path).indexOf('.')) { + path += '.jade'; + } + + // non-jade + if ('.jade' != path.substr(-5)) { + var path = join(dir, path) + , str = fs.readFileSync(path, 'utf8'); + return new nodes.Literal(str); + } + + var path = join(dir, path) + , str = fs.readFileSync(path, 'utf8') + , parser = new Parser(str, path, this.options); + + this.context(parser); + var ast = parser.parse(); + this.context(); + ast.filename = path; + + if ('indent' == this.peek().type) { + ast.lastBlock().push(this.block()); + } + + return ast; + }, + + /** + * mixin block + */ + + parseMixin: function(){ + var tok = this.expect('mixin') + , name = tok.val + , args = tok.args; + var block = 'indent' == this.peek().type + ? this.block() + : null; + return new nodes.Mixin(name, args, block); + }, + + /** + * indent (text | newline)* outdent + */ + + parseTextBlock: function(){ + var text = new nodes.Text; + text.line = this.line(); + var spaces = this.expect('indent').val; + if (null == this._spaces) this._spaces = spaces; + var indent = Array(spaces - this._spaces + 1).join(' '); + while ('outdent' != this.peek().type) { + switch (this.peek().type) { + case 'newline': + text.push('\\n'); + this.advance(); + break; + case 'indent': + text.push('\\n'); + this.parseTextBlock().nodes.forEach(function(node){ + text.push(node); + }); + text.push('\\n'); + break; + default: + text.push(indent + this.advance().val); + } + } + + if (spaces == this._spaces) this._spaces = null; + this.expect('outdent'); + return text; + }, + + /** + * indent expr* outdent + */ + + block: function(){ + var block = new nodes.Block; + block.line = this.line(); + this.expect('indent'); + while ('outdent' != this.peek().type) { + if ('newline' == this.peek().type) { + this.advance(); + } else { + block.push(this.parseExpr()); + } + } + this.expect('outdent'); + return block; + }, + + /** + * tag (attrs | class | id)* (text | code | ':')? newline* block? + */ + + parseTag: function(){ + // ast-filter look-ahead + var i = 2; + if ('attrs' == this.lookahead(i).type) ++i; + if (':' == this.lookahead(i).type) { + if ('indent' == this.lookahead(++i).type) { + return this.parseASTFilter(); + } + } + + var name = this.advance().val + , tag = new nodes.Tag(name) + , dot; + + tag.line = this.line(); + + // (attrs | class | id)* + out: + while (true) { + switch (this.peek().type) { + case 'id': + case 'class': + var tok = this.advance(); + tag.setAttribute(tok.type, "'" + tok.val + "'"); + continue; + case 'attrs': + var obj = this.advance().attrs + , names = Object.keys(obj); + for (var i = 0, len = names.length; i < len; ++i) { + var name = names[i] + , val = obj[name]; + tag.setAttribute(name, val); + } + continue; + default: + break out; + } + } + + // check immediate '.' + if ('.' == this.peek().val) { + dot = tag.textOnly = true; + this.advance(); + } + + // (text | code | ':')? + switch (this.peek().type) { + case 'text': + tag.text = this.parseText(); + break; + case 'code': + tag.code = this.parseCode(); + break; + case ':': + this.advance(); + tag.block = new nodes.Block; + tag.block.push(this.parseTag()); + break; + } + + // newline* + while ('newline' == this.peek().type) this.advance(); + + tag.textOnly = tag.textOnly || ~textOnly.indexOf(tag.name); + + // script special-case + if ('script' == tag.name) { + var type = tag.getAttribute('type'); + if (!dot && type && 'text/javascript' != type.replace(/^['"]|['"]$/g, '')) { + tag.textOnly = false; + } + } + + // block? + if ('indent' == this.peek().type) { + if (tag.textOnly) { + this.lexer.pipeless = true; + tag.block = this.parseTextBlock(); + this.lexer.pipeless = false; + } else { + var block = this.block(); + if (tag.block) { + for (var i = 0, len = block.nodes.length; i < len; ++i) { + tag.block.push(block.nodes[i]); + } + } else { + tag.block = block; + } + } + } + + return tag; + } +}; diff --git a/node_modules/jade/lib/runtime.js b/node_modules/jade/lib/runtime.js new file mode 100644 index 0000000..7b357ca --- /dev/null +++ b/node_modules/jade/lib/runtime.js @@ -0,0 +1,118 @@ + +/*! + * Jade - runtime + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Lame Array.isArray() polyfill for now. + */ + +if (!Array.isArray) { + Array.isArray = function(arr){ + return '[object Array]' == Object.prototype.toString.call(arr); + }; +} + +/** + * Lame Object.keys() polyfill for now. + */ + +if (!Object.keys) { + Object.keys = function(obj){ + var arr = []; + for (var key in obj) { + if (obj.hasOwnProperty(key)) { + arr.push(key); + } + } + return arr; + } +} + +/** + * Render the given attributes object. + * + * @param {Object} obj + * @return {String} + * @api private + */ + +exports.attrs = function attrs(obj){ + var buf = [] + , terse = obj.terse; + delete obj.terse; + var keys = Object.keys(obj) + , len = keys.length; + if (len) { + buf.push(''); + for (var i = 0; i < len; ++i) { + var key = keys[i] + , val = obj[key]; + if ('boolean' == typeof val || null == val) { + if (val) { + terse + ? buf.push(key) + : buf.push(key + '="' + key + '"'); + } + } else if ('class' == key && Array.isArray(val)) { + buf.push(key + '="' + exports.escape(val.join(' ')) + '"'); + } else { + buf.push(key + '="' + exports.escape(val) + '"'); + } + } + } + return buf.join(' '); +}; + +/** + * Escape the given string of `html`. + * + * @param {String} html + * @return {String} + * @api private + */ + +exports.escape = function escape(html){ + return String(html) + .replace(/&(?!\w+;)/g, '&') + .replace(//g, '>') + .replace(/"/g, '"'); +}; + +/** + * Re-throw the given `err` in context to the + * the jade in `filename` at the given `lineno`. + * + * @param {Error} err + * @param {String} filename + * @param {String} lineno + * @api private + */ + +exports.rethrow = function rethrow(err, filename, lineno){ + if (!filename) throw err; + + var context = 3 + , str = require('fs').readFileSync(filename, 'utf8') + , lines = str.split('\n') + , start = Math.max(lineno - context, 0) + , end = Math.min(lines.length, lineno + context); + + // Error context + var context = lines.slice(start, end).map(function(line, i){ + var curr = i + start + 1; + return (curr == lineno ? ' > ' : ' ') + + curr + + '| ' + + line; + }).join('\n'); + + // Alter exception message + err.path = filename; + err.message = (filename || 'Jade') + ':' + lineno + + '\n' + context + '\n\n' + err.message; + throw err; +}; diff --git a/node_modules/jade/lib/self-closing.js b/node_modules/jade/lib/self-closing.js new file mode 100644 index 0000000..293e7f8 --- /dev/null +++ b/node_modules/jade/lib/self-closing.js @@ -0,0 +1,18 @@ + +/*! + * Jade - self closing tags + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +module.exports = [ + 'meta' + , 'img' + , 'link' + , 'input' + , 'area' + , 'base' + , 'col' + , 'br' + , 'hr' +]; \ No newline at end of file diff --git a/node_modules/jade/lib/utils.js b/node_modules/jade/lib/utils.js new file mode 100644 index 0000000..ff46d02 --- /dev/null +++ b/node_modules/jade/lib/utils.js @@ -0,0 +1,49 @@ + +/*! + * Jade - utils + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Convert interpolation in the given string to JavaScript. + * + * @param {String} str + * @return {String} + * @api private + */ + +var interpolate = exports.interpolate = function(str){ + return str.replace(/(\\)?([#!]){(.*?)}/g, function(str, escape, flag, code){ + return escape + ? str + : "' + " + + ('!' == flag ? '' : 'escape') + + "((interp = " + code.replace(/\\'/g, "'") + + ") == null ? '' : interp) + '"; + }); +}; + +/** + * Escape single quotes in `str`. + * + * @param {String} str + * @return {String} + * @api private + */ + +var escape = exports.escape = function(str) { + return str.replace(/'/g, "\\'"); +}; + +/** + * Interpolate, and escape the given `str`. + * + * @param {String} str + * @return {String} + * @api private + */ + +exports.text = function(str){ + return interpolate(escape(str)); +}; \ No newline at end of file diff --git a/node_modules/jade/package.json b/node_modules/jade/package.json new file mode 100644 index 0000000..ddcc7e2 --- /dev/null +++ b/node_modules/jade/package.json @@ -0,0 +1,25 @@ +{ + "name": "jade", + "description": "Jade template engine", + "version": "0.18.0", + "author": "TJ Holowaychuk ", + "repository": "git://github.com/visionmedia/jade", + "main": "./index.js", + "bin": { "jade": "./bin/jade" }, + "dependencies": { + "commander": "0.2.x", + "mkdirp": ">= 0.0.7" + }, + "devDependencies": { + "expresso": "0.9.2", + "coffee-script": ">= 0.0.1", + "sass": ">= 0.0.1", + "less": ">= 0.0.1", + "markdown": ">= 0.0.1", + "stylus": ">= 0.0.1", + "uubench": "0.0.1", + "uglify-js": ">= 1.0.7" + }, + "scripts" : { "prepublish" : "npm prune" }, + "engines": { "node": ">= 0.1.98" } +} diff --git a/node_modules/jade/runtime.js b/node_modules/jade/runtime.js new file mode 100644 index 0000000..39f8a28 --- /dev/null +++ b/node_modules/jade/runtime.js @@ -0,0 +1,123 @@ + +var jade = (function(exports){ +/*! + * Jade - runtime + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Lame Array.isArray() polyfill for now. + */ + +if (!Array.isArray) { + Array.isArray = function(arr){ + return '[object Array]' == Object.prototype.toString.call(arr); + }; +} + +/** + * Lame Object.keys() polyfill for now. + */ + +if (!Object.keys) { + Object.keys = function(obj){ + var arr = []; + for (var key in obj) { + if (obj.hasOwnProperty(key)) { + arr.push(key); + } + } + return arr; + } +} + +/** + * Render the given attributes object. + * + * @param {Object} obj + * @return {String} + * @api private + */ + +exports.attrs = function attrs(obj){ + var buf = [] + , terse = obj.terse; + delete obj.terse; + var keys = Object.keys(obj) + , len = keys.length; + if (len) { + buf.push(''); + for (var i = 0; i < len; ++i) { + var key = keys[i] + , val = obj[key]; + if ('boolean' == typeof val || null == val) { + if (val) { + terse + ? buf.push(key) + : buf.push(key + '="' + key + '"'); + } + } else if ('class' == key && Array.isArray(val)) { + buf.push(key + '="' + exports.escape(val.join(' ')) + '"'); + } else { + buf.push(key + '="' + exports.escape(val) + '"'); + } + } + } + return buf.join(' '); +}; + +/** + * Escape the given string of `html`. + * + * @param {String} html + * @return {String} + * @api private + */ + +exports.escape = function escape(html){ + return String(html) + .replace(/&(?!\w+;)/g, '&') + .replace(//g, '>') + .replace(/"/g, '"'); +}; + +/** + * Re-throw the given `err` in context to the + * the jade in `filename` at the given `lineno`. + * + * @param {Error} err + * @param {String} filename + * @param {String} lineno + * @api private + */ + +exports.rethrow = function rethrow(err, filename, lineno){ + if (!filename) throw err; + + var context = 3 + , str = require('fs').readFileSync(filename, 'utf8') + , lines = str.split('\n') + , start = Math.max(lineno - context, 0) + , end = Math.min(lines.length, lineno + context); + + // Error context + var context = lines.slice(start, end).map(function(line, i){ + var curr = i + start + 1; + return (curr == lineno ? ' > ' : ' ') + + curr + + '| ' + + line; + }).join('\n'); + + // Alter exception message + err.path = filename; + err.message = (filename || 'Jade') + ':' + lineno + + '\n' + context + '\n\n' + err.message; + throw err; +}; + + return exports; + +})({}); \ No newline at end of file diff --git a/node_modules/jade/runtime.min.js b/node_modules/jade/runtime.min.js new file mode 100644 index 0000000..8c19a98 --- /dev/null +++ b/node_modules/jade/runtime.min.js @@ -0,0 +1 @@ +var jade=function(exports){return Array.isArray||(Array.isArray=function(arr){return"[object Array]"==Object.prototype.toString.call(arr)}),Object.keys||(Object.keys=function(obj){var arr=[];for(var key in obj)obj.hasOwnProperty(key)&&arr.push(key);return arr}),exports.attrs=function(obj){var buf=[],terse=obj.terse;delete obj.terse;var keys=Object.keys(obj),len=keys.length;if(len){buf.push("");for(var i=0;i/g,">").replace(/"/g,""")},exports.rethrow=function(err,filename,lineno){if(!filename)throw err;var context=3,str=require("fs").readFileSync(filename,"utf8"),lines=str.split("\n"),start=Math.max(lineno-context,0),end=Math.min(lines.length,lineno+context),context=lines.slice(start,end).map(function(line,i){var curr=i+start+1;return(curr==lineno?" > ":" ")+curr+"| "+line}).join("\n");throw err.path=filename,err.message=(filename||"Jade")+":"+lineno+"\n"+context+"\n\n"+err.message,err},exports}({}) \ No newline at end of file diff --git a/node_modules/jade/support/benchmark.js b/node_modules/jade/support/benchmark.js new file mode 100644 index 0000000..85c2f3f --- /dev/null +++ b/node_modules/jade/support/benchmark.js @@ -0,0 +1,62 @@ + +/** + * Module dependencies. + */ + +var uubench = require('uubench') + , jade = require('../'); + + +var suite = new uubench.Suite({ + min: 200, + result: function(name, stats){ + var persec = 1000 / stats.elapsed + , ops = stats.iterations * persec; + console.log('%s: %d', name, ops | 0); + } +}); + +var str = 'html\n body\n h1 Title' + , fn = jade.compile(str); + +suite.bench('tiny', function(next){ + fn(); + next(); +}); + +str = '\ +html\n\ + body\n\ + h1 Title\n\ + ul#menu\n\ + li: a(href="#") Home\n\ + li: a(href="#") About Us\n\ + li: a(href="#") Store\n\ + li: a(href="#") FAQ\n\ + li: a(href="#") Contact\n\ +'; + +var fn2 = jade.compile(str); + +suite.bench('small', function(next){ + fn2(); + next(); +}); + +str = '\ +html\n\ + body\n\ + h1 #{title}\n\ + ul#menu\n\ + - each link in links\r\n\ + li: a(href="#")= link\r\n\ +'; + +var fn3 = jade.compile(str); + +suite.bench('small locals', function(next){ + fn3({ title: 'Title', links: ['Home', 'About Us', 'Store', 'FAQ', 'Contact'] }); + next(); +}); + +suite.run(); \ No newline at end of file diff --git a/node_modules/jade/support/coffee-script/.gitignore b/node_modules/jade/support/coffee-script/.gitignore new file mode 100644 index 0000000..529b521 --- /dev/null +++ b/node_modules/jade/support/coffee-script/.gitignore @@ -0,0 +1,8 @@ +raw +presentation +test.coffee +parser.output +test/fixtures/underscore +test/*.js +examples/beautiful_code/parse.coffee +*.gem \ No newline at end of file diff --git a/node_modules/jade/support/coffee-script/Cakefile b/node_modules/jade/support/coffee-script/Cakefile new file mode 100644 index 0000000..552d598 --- /dev/null +++ b/node_modules/jade/support/coffee-script/Cakefile @@ -0,0 +1,134 @@ +fs = require 'fs' +helpers = require './lib/helpers' +CoffeeScript = require './lib/coffee-script' +{spawn, exec} = require 'child_process' +path = require 'path' + +# ANSI Terminal Colors. +red = '\033[0;31m' +green = '\033[0;32m' +reset = '\033[0m' + +# Run a CoffeeScript through our node/coffee interpreter. +run = (args) -> + proc = spawn 'bin/coffee', args + proc.stderr.on 'data', (buffer) -> puts buffer.toString() + proc.on 'exit', (status) -> process.exit(1) if status != 0 + +# Log a message with a color. +log = (message, color, explanation) -> + puts color + message + reset + ' ' + (explanation or '') + +option '-p', '--prefix [DIR]', 'set the installation prefix for `cake install`' + +task 'install', 'install CoffeeScript into /usr/local (or --prefix)', (options) -> + base = options.prefix or '/usr/local' + lib = "#{base}/lib/coffee-script" + bin = "#{base}/bin" + node = "~/.node_libraries/coffee-script" + puts "Installing CoffeeScript to #{lib}" + puts "Linking to #{node}" + puts "Linking 'coffee' to #{bin}/coffee" + exec([ + "mkdir -p #{lib} #{bin}" + "cp -rf bin lib LICENSE README package.json src #{lib}" + "ln -sf #{lib}/bin/coffee #{bin}/coffee" + "ln -sf #{lib}/bin/cake #{bin}/cake" + "mkdir -p ~/.node_libraries" + "ln -sf #{lib}/lib #{node}" + ].join(' && '), (err, stdout, stderr) -> + if err then print stderr else log 'done', green + ) + + +task 'build', 'build the CoffeeScript language from source', -> + files = fs.readdirSync 'src' + files = 'src/' + file for file in files when file.match(/\.coffee$/) + run ['-c', '-o', 'lib'].concat(files) + + +task 'build:full', 'rebuild the source twice, and run the tests', -> + exec 'bin/cake build && bin/cake build && bin/cake test', (err, stdout, stderr) -> + print stdout if stdout + print stderr if stderr + throw err if err + + +task 'build:parser', 'rebuild the Jison parser (run build first)', -> + require 'jison' + parser = require('./lib/grammar').parser + js = parser.generate() + # TODO: Remove this when the Jison patch is released. + js = js.replace 'if (require.main === module)', "if (typeof module !== 'undefined' && require.main === module)" + fs.writeFile 'lib/parser.js', js + + +task 'build:ultraviolet', 'build and install the Ultraviolet syntax highlighter', -> + exec 'plist2syntax ../coffee-script-tmbundle/Syntaxes/CoffeeScript.tmLanguage', (err) -> + throw err if err + exec 'sudo mv coffeescript.yaml /usr/local/lib/ruby/gems/1.8/gems/ultraviolet-0.10.2/syntax/coffeescript.syntax' + + +task 'build:browser', 'rebuild the merged script for inclusion in the browser', -> + exec 'rake browser', (err) -> + throw err if err + + +task 'doc:site', 'watch and continually rebuild the documentation for the website', -> + exec 'rake doc' + + +task 'doc:source', 'rebuild the internal documentation', -> + exec 'docco src/*.coffee && cp -rf docs documentation && rm -r docs', (err) -> + throw err if err + + +task 'doc:underscore', 'rebuild the Underscore.coffee documentation page', -> + exec 'docco examples/underscore.coffee && cp -rf docs documentation && rm -r docs', (err) -> + throw err if err + +task 'bench', 'quick benchmark of compilation time (of everything in src)', -> + exec 'time bin/coffee -p src/ > /dev/null', (err, stdout, stderr) -> + print stderr + +task 'loc', 'count the lines of source code in the CoffeeScript compiler', -> + sources = ['src/coffee-script.coffee', 'src/grammar.coffee', 'src/helpers.coffee', 'src/lexer.coffee', 'src/nodes.coffee', 'src/rewriter.coffee', 'src/scope.coffee'] + exec "cat #{ sources.join(' ') } | grep -v '^\\( *#\\|\\s*$\\)' | wc -l | tr -s ' '", (err, stdout) -> + print stdout + + +runTests = (CoffeeScript) -> + startTime = Date.now() + passedTests = failedTests = 0 + for all name, func of require 'assert' + global[name] = -> ++passedTests; func arguments... + global.eq = global.strictEqual + global.CoffeeScript = CoffeeScript + process.on 'exit', -> + time = ((Date.now() - startTime) / 1000).toFixed(2) + message = "passed #{passedTests} tests in #{time} seconds#{reset}" + if failedTests + log "failed #{failedTests} and #{message}", red + else + log message, green + fs.readdir 'test', (err, files) -> + files.forEach (file) -> + return unless file.match(/\.coffee$/i) + fileName = path.join 'test', file + fs.readFile fileName, (err, code) -> + try + CoffeeScript.run code.toString(), {fileName} + catch err + failedTests += 1 + log "failed #{fileName}", red, '\n' + err.stack.toString() + + +task 'test', 'run the CoffeeScript language test suite', -> + runTests CoffeeScript + + +task 'test:browser', 'run the test suite against the merged browser script', -> + source = fs.readFileSync 'extras/coffee-script.js', 'utf-8' + result = {} + (-> eval source).call result + runTests result.CoffeeScript diff --git a/node_modules/jade/support/coffee-script/LICENSE b/node_modules/jade/support/coffee-script/LICENSE new file mode 100644 index 0000000..38e580c --- /dev/null +++ b/node_modules/jade/support/coffee-script/LICENSE @@ -0,0 +1,22 @@ +Copyright (c) 2010 Jeremy Ashkenas + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/node_modules/jade/support/coffee-script/README b/node_modules/jade/support/coffee-script/README new file mode 100644 index 0000000..70ce760 --- /dev/null +++ b/node_modules/jade/support/coffee-script/README @@ -0,0 +1,48 @@ += + { + } } { + { { } } + } }{ { + { }{ } } _____ __ __ + ( }{ }{ { ) / ____| / _|/ _| + .- { { } { }} -. | | ___ | |_| |_ ___ ___ + ( ( } { } { } } ) | | / _ \| _| _/ _ \/ _ \ + |`-..________ ..-'| | |___| (_) | | | || __/ __/ + | | \_____\___/|_| |_| \___|\___| + | ;--. + | (__ \ _____ _ _ + | | ) ) / ____| (_) | | + | |/ / | (___ ___ _ __ _ _ __ | |_ + | ( / \___ \ / __| '__| | '_ \| __| + | |/ ____) | (__| | | | |_) | |_ + | | |_____/ \___|_| |_| .__/ \__| + `-.._________..-' | | + |_| + + + CoffeeScript is a little language that compiles into JavaScript. + + Install Node.js, and then the CoffeeScript compiler: + sudo bin/cake install + + Or, if you have the Node Package Manager installed: + sudo npm install coffee-script + + Compile a script: + coffee /path/to/script.coffee + + For documentation, usage, and examples, see: + http://coffeescript.org/ + + To suggest a feature, report a bug, or general discussion: + http://github.com/jashkenas/coffee-script/issues/ + + If you'd like to chat, drop by #coffeescript on Freenode IRC, + or on webchat.freenode.net. + + The source repository: + git://github.com/jashkenas/coffee-script.git + + All contributors are listed here: + http://github.com/jashkenas/coffee-script/contributors + \ No newline at end of file diff --git a/node_modules/jade/support/coffee-script/Rakefile b/node_modules/jade/support/coffee-script/Rakefile new file mode 100644 index 0000000..b88fc44 --- /dev/null +++ b/node_modules/jade/support/coffee-script/Rakefile @@ -0,0 +1,53 @@ +require 'erb' +require 'fileutils' +require 'rake/testtask' +require 'rubygems' +require 'yui/compressor' + +HEADER = <<-EOS +/** + * CoffeeScript Compiler v0.9.4 + * http://coffeescript.org + * + * Copyright 2010, Jeremy Ashkenas + * Released under the MIT License + */ +EOS + +desc "Build the documentation page" +task :doc do + source = 'documentation/index.html.erb' + child = fork { exec "bin/coffee -bcw -o documentation/js documentation/coffee/*.coffee" } + at_exit { Process.kill("INT", child) } + Signal.trap("INT") { exit } + loop do + mtime = File.stat(source).mtime + if !@mtime || mtime > @mtime + rendered = ERB.new(File.read(source)).result(binding) + File.open('index.html', 'w+') {|f| f.write(rendered) } + end + @mtime = mtime + sleep 1 + end +end + +desc "Build the single concatenated and minified script for the browser" +task :browser do + sources = %w(helpers rewriter lexer parser scope nodes coffee-script browser) + code = sources.inject '' do |js, name| + js << <<-"JS" + require['./#{name}'] = new function(){ + var exports = this; + #{ File.read "lib/#{name}.js" } + } + JS + end + code = YUI::JavaScriptCompressor.new.compress(<<-"JS") + this.CoffeeScript = function(){ + function require(path){ return require[path] } + #{ code } + return require['./coffee-script'] + }() + JS + File.open('extras/coffee-script.js', 'wb+') {|f| f.write(HEADER + code) } +end diff --git a/node_modules/jade/support/coffee-script/bin/cake b/node_modules/jade/support/coffee-script/bin/cake new file mode 100755 index 0000000..aa7475a --- /dev/null +++ b/node_modules/jade/support/coffee-script/bin/cake @@ -0,0 +1,8 @@ +#!/usr/bin/env node + +var path = require('path'); +var fs = require('fs'); +var lib = path.join(path.dirname(fs.realpathSync(__filename)), '../lib'); + +require(lib + '/helpers').extend(global, require('sys')); +require(lib + '/cake').run(); diff --git a/node_modules/jade/support/coffee-script/bin/coffee b/node_modules/jade/support/coffee-script/bin/coffee new file mode 100755 index 0000000..c6dc359 --- /dev/null +++ b/node_modules/jade/support/coffee-script/bin/coffee @@ -0,0 +1,8 @@ +#!/usr/bin/env node + +var path = require('path'); +var fs = require('fs'); +var lib = path.join(path.dirname(fs.realpathSync(__filename)), '../lib'); + +require(lib + '/helpers').extend(global, require('sys')); +require(lib + '/command').run(); diff --git a/node_modules/jade/support/coffee-script/documentation/coffee/aliases.coffee b/node_modules/jade/support/coffee-script/documentation/coffee/aliases.coffee new file mode 100644 index 0000000..9301fe8 --- /dev/null +++ b/node_modules/jade/support/coffee-script/documentation/coffee/aliases.coffee @@ -0,0 +1,11 @@ +launch() if ignition is on + +volume = 10 if band isnt SpinalTap + +letTheWildRumpusBegin() unless answer is no + +if car.speed < limit then accelerate() + +winner = yes if pick in [47, 92, 13] + +print inspect "My name is " + @name diff --git a/node_modules/jade/support/coffee-script/documentation/coffee/array_comprehensions.coffee b/node_modules/jade/support/coffee-script/documentation/coffee/array_comprehensions.coffee new file mode 100644 index 0000000..b9d9e16 --- /dev/null +++ b/node_modules/jade/support/coffee-script/documentation/coffee/array_comprehensions.coffee @@ -0,0 +1,7 @@ +# Eat lunch. +lunch = eat food for food in ['toast', 'cheese', 'wine'] + +# Naive collision detection. +for roid, pos in asteroids + for roid2 in asteroids when roid isnt roid2 + roid.explode() if roid.overlaps roid2 \ No newline at end of file diff --git a/node_modules/jade/support/coffee-script/documentation/coffee/block_comment.coffee b/node_modules/jade/support/coffee-script/documentation/coffee/block_comment.coffee new file mode 100644 index 0000000..3cfd9e9 --- /dev/null +++ b/node_modules/jade/support/coffee-script/documentation/coffee/block_comment.coffee @@ -0,0 +1,4 @@ +### +CoffeeScript Compiler v0.9.4 +Released under the MIT License +### \ No newline at end of file diff --git a/node_modules/jade/support/coffee-script/documentation/coffee/cake_tasks.coffee b/node_modules/jade/support/coffee-script/documentation/coffee/cake_tasks.coffee new file mode 100644 index 0000000..780337f --- /dev/null +++ b/node_modules/jade/support/coffee-script/documentation/coffee/cake_tasks.coffee @@ -0,0 +1,9 @@ +fs = require 'fs' + +option '-o', '--output [DIR]', 'directory for compiled code' + +task 'build:parser', 'rebuild the Jison parser', (options) -> + require 'jison' + code = require('./lib/grammar').parser.generate() + dir = options.output or 'lib' + fs.writeFile "#{dir}/parser.js", code \ No newline at end of file diff --git a/node_modules/jade/support/coffee-script/documentation/coffee/classes.coffee b/node_modules/jade/support/coffee-script/documentation/coffee/classes.coffee new file mode 100644 index 0000000..6794518 --- /dev/null +++ b/node_modules/jade/support/coffee-script/documentation/coffee/classes.coffee @@ -0,0 +1,25 @@ +class Animal + constructor: (@name) -> + + move: (meters) -> + alert @name + " moved " + meters + "m." + +class Snake extends Animal + move: -> + alert "Slithering..." + super 5 + +class Horse extends Animal + move: -> + alert "Galloping..." + super 45 + +sam = new Snake "Sammy the Python" +tom = new Horse "Tommy the Palomino" + +sam.move() +tom.move() + + + + diff --git a/node_modules/jade/support/coffee-script/documentation/coffee/comparisons.coffee b/node_modules/jade/support/coffee-script/documentation/coffee/comparisons.coffee new file mode 100644 index 0000000..6cac549 --- /dev/null +++ b/node_modules/jade/support/coffee-script/documentation/coffee/comparisons.coffee @@ -0,0 +1,5 @@ +cholesterol = 127 + +healthy = 200 > cholesterol > 60 + + diff --git a/node_modules/jade/support/coffee-script/documentation/coffee/conditionals.coffee b/node_modules/jade/support/coffee-script/documentation/coffee/conditionals.coffee new file mode 100644 index 0000000..7aa329b --- /dev/null +++ b/node_modules/jade/support/coffee-script/documentation/coffee/conditionals.coffee @@ -0,0 +1,11 @@ +mood = greatlyImproved if singing + +if happy and knowsIt + clapsHands() + chaChaCha() +else + showIt() + +date = if friday then sue else jill + +options or= defaults \ No newline at end of file diff --git a/node_modules/jade/support/coffee-script/documentation/coffee/embedded.coffee b/node_modules/jade/support/coffee-script/documentation/coffee/embedded.coffee new file mode 100644 index 0000000..bb16b79 --- /dev/null +++ b/node_modules/jade/support/coffee-script/documentation/coffee/embedded.coffee @@ -0,0 +1,5 @@ +hi = `function() { + return [document.title, "Hello JavaScript"].join(": "); +}` + + diff --git a/node_modules/jade/support/coffee-script/documentation/coffee/existence.coffee b/node_modules/jade/support/coffee-script/documentation/coffee/existence.coffee new file mode 100644 index 0000000..d4405e3 --- /dev/null +++ b/node_modules/jade/support/coffee-script/documentation/coffee/existence.coffee @@ -0,0 +1,8 @@ +solipsism = true if mind? and not world? + +speed ?= 140 + + + + + diff --git a/node_modules/jade/support/coffee-script/documentation/coffee/expressions.coffee b/node_modules/jade/support/coffee-script/documentation/coffee/expressions.coffee new file mode 100644 index 0000000..f4e59c4 --- /dev/null +++ b/node_modules/jade/support/coffee-script/documentation/coffee/expressions.coffee @@ -0,0 +1,9 @@ +grade = (student) -> + if student.excellentWork + "A+" + else if student.okayStuff + if student.triedHard then "B" else "B-" + else + "C" + +eldest = if 24 > 21 then "Liz" else "Ike" \ No newline at end of file diff --git a/node_modules/jade/support/coffee-script/documentation/coffee/expressions_assignment.coffee b/node_modules/jade/support/coffee-script/documentation/coffee/expressions_assignment.coffee new file mode 100644 index 0000000..0ba0daa --- /dev/null +++ b/node_modules/jade/support/coffee-script/documentation/coffee/expressions_assignment.coffee @@ -0,0 +1 @@ +six = (one = 1) + (two = 2) + (three = 3) \ No newline at end of file diff --git a/node_modules/jade/support/coffee-script/documentation/coffee/expressions_comprehension.coffee b/node_modules/jade/support/coffee-script/documentation/coffee/expressions_comprehension.coffee new file mode 100644 index 0000000..0af075d --- /dev/null +++ b/node_modules/jade/support/coffee-script/documentation/coffee/expressions_comprehension.coffee @@ -0,0 +1,3 @@ +# The first ten global properties. + +globals = (name for name of window)[0...10] \ No newline at end of file diff --git a/node_modules/jade/support/coffee-script/documentation/coffee/expressions_try.coffee b/node_modules/jade/support/coffee-script/documentation/coffee/expressions_try.coffee new file mode 100644 index 0000000..13fdfec --- /dev/null +++ b/node_modules/jade/support/coffee-script/documentation/coffee/expressions_try.coffee @@ -0,0 +1,6 @@ +alert( + try + nonexistent / undefined + catch error + "And the error is ... " + error +) \ No newline at end of file diff --git a/node_modules/jade/support/coffee-script/documentation/coffee/fat_arrow.coffee b/node_modules/jade/support/coffee-script/documentation/coffee/fat_arrow.coffee new file mode 100644 index 0000000..836eb7a --- /dev/null +++ b/node_modules/jade/support/coffee-script/documentation/coffee/fat_arrow.coffee @@ -0,0 +1,6 @@ +Account = (customer, cart) -> + @customer = customer + @cart = cart + + $('.shopping_cart').bind 'click', (event) => + @customer.purchase @cart \ No newline at end of file diff --git a/node_modules/jade/support/coffee-script/documentation/coffee/functions.coffee b/node_modules/jade/support/coffee-script/documentation/coffee/functions.coffee new file mode 100644 index 0000000..60cc7ca --- /dev/null +++ b/node_modules/jade/support/coffee-script/documentation/coffee/functions.coffee @@ -0,0 +1,2 @@ +square = (x) -> x * x +cube = (x) -> square(x) * x diff --git a/node_modules/jade/support/coffee-script/documentation/coffee/heredocs.coffee b/node_modules/jade/support/coffee-script/documentation/coffee/heredocs.coffee new file mode 100644 index 0000000..ec76c14 --- /dev/null +++ b/node_modules/jade/support/coffee-script/documentation/coffee/heredocs.coffee @@ -0,0 +1,5 @@ +html = ''' + + cup of coffeescript + + ''' \ No newline at end of file diff --git a/node_modules/jade/support/coffee-script/documentation/coffee/interpolation.coffee b/node_modules/jade/support/coffee-script/documentation/coffee/interpolation.coffee new file mode 100644 index 0000000..de02de4 --- /dev/null +++ b/node_modules/jade/support/coffee-script/documentation/coffee/interpolation.coffee @@ -0,0 +1,2 @@ +author = "Wittgenstein" +quote = "A picture is a fact. -- #{author}" \ No newline at end of file diff --git a/node_modules/jade/support/coffee-script/documentation/coffee/interpolation_expression.coffee b/node_modules/jade/support/coffee-script/documentation/coffee/interpolation_expression.coffee new file mode 100644 index 0000000..49332cd --- /dev/null +++ b/node_modules/jade/support/coffee-script/documentation/coffee/interpolation_expression.coffee @@ -0,0 +1,6 @@ +sentence = "#{ 22 / 7 } is a decent approximation of π" + +sep = "[.\\/\\- ]" +dates = /\d+#{sep}\d+#{sep}\d+/g + + diff --git a/node_modules/jade/support/coffee-script/documentation/coffee/multiple_return_values.coffee b/node_modules/jade/support/coffee-script/documentation/coffee/multiple_return_values.coffee new file mode 100644 index 0000000..ec350ba --- /dev/null +++ b/node_modules/jade/support/coffee-script/documentation/coffee/multiple_return_values.coffee @@ -0,0 +1,5 @@ +weatherReport = (location) -> + # Make an Ajax request to fetch the weather... + [location, 72, "Mostly Sunny"] + +[city, temp, forecast] = weatherReport "Berkeley, CA" \ No newline at end of file diff --git a/node_modules/jade/support/coffee-script/documentation/coffee/object_comprehensions.coffee b/node_modules/jade/support/coffee-script/documentation/coffee/object_comprehensions.coffee new file mode 100644 index 0000000..f5e2ce8 --- /dev/null +++ b/node_modules/jade/support/coffee-script/documentation/coffee/object_comprehensions.coffee @@ -0,0 +1,4 @@ +yearsOld = max: 10, ida: 9, tim: 11 + +ages = for child, age of yearsOld + child + " is " + age \ No newline at end of file diff --git a/node_modules/jade/support/coffee-script/documentation/coffee/object_extraction.coffee b/node_modules/jade/support/coffee-script/documentation/coffee/object_extraction.coffee new file mode 100644 index 0000000..d3625d6 --- /dev/null +++ b/node_modules/jade/support/coffee-script/documentation/coffee/object_extraction.coffee @@ -0,0 +1,11 @@ +futurists = + sculptor: "Umberto Boccioni" + painter: "Vladimir Burliuk" + poet: + name: "F.T. Marinetti" + address: [ + "Via Roma 42R" + "Bellagio, Italy 22021" + ] + +{poet: {name, address: [street, city]}} = futurists \ No newline at end of file diff --git a/node_modules/jade/support/coffee-script/documentation/coffee/objects_and_arrays.coffee b/node_modules/jade/support/coffee-script/documentation/coffee/objects_and_arrays.coffee new file mode 100644 index 0000000..d98be8b --- /dev/null +++ b/node_modules/jade/support/coffee-script/documentation/coffee/objects_and_arrays.coffee @@ -0,0 +1,17 @@ +song = ["do", "re", "mi", "fa", "so"] + +singers = {Jagger: "Rock", Elvis: "Roll"} + +matrix = [ + 1, 0, 1 + 0, 0, 1 + 1, 1, 0 +] + +kids = + brother: + name: "Max" + age: 11 + sister: + name: "Ida" + age: 9 \ No newline at end of file diff --git a/node_modules/jade/support/coffee-script/documentation/coffee/objects_reserved.coffee b/node_modules/jade/support/coffee-script/documentation/coffee/objects_reserved.coffee new file mode 100644 index 0000000..492b80a --- /dev/null +++ b/node_modules/jade/support/coffee-script/documentation/coffee/objects_reserved.coffee @@ -0,0 +1 @@ +$('.account').css class: 'active' \ No newline at end of file diff --git a/node_modules/jade/support/coffee-script/documentation/coffee/overview.coffee b/node_modules/jade/support/coffee-script/documentation/coffee/overview.coffee new file mode 100644 index 0000000..7ab4e71 --- /dev/null +++ b/node_modules/jade/support/coffee-script/documentation/coffee/overview.coffee @@ -0,0 +1,28 @@ +# Assignment: +number = 42 +opposite = true + +# Conditions: +number = -42 if opposite + +# Functions: +square = (x) -> x * x + +# Arrays: +list = [1, 2, 3, 4, 5] + +# Objects: +math = + root: Math.sqrt + square: square + cube: (x) -> x * square x + +# Splats: +race = (winner, runners...) -> + print winner, runners + +# Existence: +alert "I knew it!" if elvis? + +# Array comprehensions: +cubes = math.cube num for num in list diff --git a/node_modules/jade/support/coffee-script/documentation/coffee/parallel_assignment.coffee b/node_modules/jade/support/coffee-script/documentation/coffee/parallel_assignment.coffee new file mode 100644 index 0000000..bbe03a8 --- /dev/null +++ b/node_modules/jade/support/coffee-script/documentation/coffee/parallel_assignment.coffee @@ -0,0 +1,4 @@ +theBait = 1000 +theSwitch = 0 + +[theBait, theSwitch] = [theSwitch, theBait] \ No newline at end of file diff --git a/node_modules/jade/support/coffee-script/documentation/coffee/patterns_and_splats.coffee b/node_modules/jade/support/coffee-script/documentation/coffee/patterns_and_splats.coffee new file mode 100644 index 0000000..12eb818 --- /dev/null +++ b/node_modules/jade/support/coffee-script/documentation/coffee/patterns_and_splats.coffee @@ -0,0 +1,7 @@ +tag = "" + +[open, contents..., close] = tag.split("") + + + + diff --git a/node_modules/jade/support/coffee-script/documentation/coffee/prototypes.coffee b/node_modules/jade/support/coffee-script/documentation/coffee/prototypes.coffee new file mode 100644 index 0000000..ebefb17 --- /dev/null +++ b/node_modules/jade/support/coffee-script/documentation/coffee/prototypes.coffee @@ -0,0 +1,2 @@ +String::dasherize = -> + this.replace /_/g, "-" \ No newline at end of file diff --git a/node_modules/jade/support/coffee-script/documentation/coffee/range_comprehensions.coffee b/node_modules/jade/support/coffee-script/documentation/coffee/range_comprehensions.coffee new file mode 100644 index 0000000..d5e0b68 --- /dev/null +++ b/node_modules/jade/support/coffee-script/documentation/coffee/range_comprehensions.coffee @@ -0,0 +1,6 @@ +countdown = num for num in [10..1] + +deliverEggs = -> + for i in [0...eggs.length] by 12 + dozen = eggs[i...i+12] + deliver new eggCarton dozen diff --git a/node_modules/jade/support/coffee-script/documentation/coffee/scope.coffee b/node_modules/jade/support/coffee-script/documentation/coffee/scope.coffee new file mode 100644 index 0000000..d0a5f1e --- /dev/null +++ b/node_modules/jade/support/coffee-script/documentation/coffee/scope.coffee @@ -0,0 +1,5 @@ +outer = 1 +changeNumbers = -> + inner = -1 + outer = 10 +inner = changeNumbers() \ No newline at end of file diff --git a/node_modules/jade/support/coffee-script/documentation/coffee/slices.coffee b/node_modules/jade/support/coffee-script/documentation/coffee/slices.coffee new file mode 100644 index 0000000..794e8e0 --- /dev/null +++ b/node_modules/jade/support/coffee-script/documentation/coffee/slices.coffee @@ -0,0 +1,6 @@ +numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] + +threeToSix = numbers[3..6] + +copy = numbers[0...numbers.length] + diff --git a/node_modules/jade/support/coffee-script/documentation/coffee/soaks.coffee b/node_modules/jade/support/coffee-script/documentation/coffee/soaks.coffee new file mode 100644 index 0000000..16b2350 --- /dev/null +++ b/node_modules/jade/support/coffee-script/documentation/coffee/soaks.coffee @@ -0,0 +1 @@ +lottery.drawWinner?().address?.zipcode diff --git a/node_modules/jade/support/coffee-script/documentation/coffee/splats.coffee b/node_modules/jade/support/coffee-script/documentation/coffee/splats.coffee new file mode 100644 index 0000000..c48a3cd --- /dev/null +++ b/node_modules/jade/support/coffee-script/documentation/coffee/splats.coffee @@ -0,0 +1,25 @@ +gold = silver = rest = "unknown" + +awardMedals = (first, second, others...) -> + gold = first + silver = second + rest = others + +contenders = [ + "Michael Phelps" + "Liu Xiang" + "Yao Ming" + "Allyson Felix" + "Shawn Johnson" + "Roman Sebrle" + "Guo Jingjing" + "Tyson Gay" + "Asafa Powell" + "Usain Bolt" +] + +awardMedals contenders... + +alert "Gold: " + gold +alert "Silver: " + silver +alert "The Field: " + rest \ No newline at end of file diff --git a/node_modules/jade/support/coffee-script/documentation/coffee/splices.coffee b/node_modules/jade/support/coffee-script/documentation/coffee/splices.coffee new file mode 100644 index 0000000..ecf9d57 --- /dev/null +++ b/node_modules/jade/support/coffee-script/documentation/coffee/splices.coffee @@ -0,0 +1,5 @@ +numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] + +numbers[3..6] = [-3, -4, -5, -6] + + diff --git a/node_modules/jade/support/coffee-script/documentation/coffee/strings.coffee b/node_modules/jade/support/coffee-script/documentation/coffee/strings.coffee new file mode 100644 index 0000000..3fc27a4 --- /dev/null +++ b/node_modules/jade/support/coffee-script/documentation/coffee/strings.coffee @@ -0,0 +1,8 @@ +mobyDick = "Call me Ishmael. Some years ago -- + never mind how long precisely -- having little + or no money in my purse, and nothing particular + to interest me on shore, I thought I would sail + about a little and see the watery part of the + world..." + + diff --git a/node_modules/jade/support/coffee-script/documentation/coffee/switch.coffee b/node_modules/jade/support/coffee-script/documentation/coffee/switch.coffee new file mode 100644 index 0000000..12a66f4 --- /dev/null +++ b/node_modules/jade/support/coffee-script/documentation/coffee/switch.coffee @@ -0,0 +1,10 @@ +switch day + when "Mon" then go work + when "Tue" then go relax + when "Thu" then go iceFishing + when "Fri", "Sat" + if day is bingoDay + go bingo + go dancing + when "Sun" then go church + else go work \ No newline at end of file diff --git a/node_modules/jade/support/coffee-script/documentation/coffee/try.coffee b/node_modules/jade/support/coffee-script/documentation/coffee/try.coffee new file mode 100644 index 0000000..d424495 --- /dev/null +++ b/node_modules/jade/support/coffee-script/documentation/coffee/try.coffee @@ -0,0 +1,7 @@ +try + allHellBreaksLoose() + catsAndDogsLivingTogether() +catch error + print error +finally + cleanUp() \ No newline at end of file diff --git a/node_modules/jade/support/coffee-script/documentation/coffee/while.coffee b/node_modules/jade/support/coffee-script/documentation/coffee/while.coffee new file mode 100644 index 0000000..81b12cb --- /dev/null +++ b/node_modules/jade/support/coffee-script/documentation/coffee/while.coffee @@ -0,0 +1,10 @@ +# Econ 101 +if this.studyingEconomics + buy() while supply > demand + sell() until supply > demand + +# Nursery Rhyme +num = 6 +lyrics = while num -= 1 + num + " little monkeys, jumping on the bed. + One fell out and bumped his head." diff --git a/node_modules/jade/support/coffee-script/documentation/css/docs.css b/node_modules/jade/support/coffee-script/documentation/css/docs.css new file mode 100644 index 0000000..b47c1ff --- /dev/null +++ b/node_modules/jade/support/coffee-script/documentation/css/docs.css @@ -0,0 +1,284 @@ +body { + font-size: 13px; + line-height: 20px; + color: #191933; + font-family: "Lucida Grande", "Lucida Sans Unicode", Helvetica, Arial, sans-serif !important; +} +.container { + width: 950px; + margin: 0; + padding: 80px 0px 50px 50px; +} +p, li { + width: 625px; +} +a { + color: #000055; +} +h1, h2, h3, h4, h5, h6 { + margin-top: 50px; +} +br.clear { + height: 0; + clear: both; +} +ul { + padding-left: 20px; +} +b.header { + color: #000055; + display: block; + margin: 40px 0 5px 0; + font-size: 16px; +} +li { + margin-bottom: 10px; +} +table { + margin: 16px 0 0 13px; padding: 0; + width: 625px; +} + tr, td { + margin: 0; padding: 0; + } + td { + padding: 9px 15px 9px 0; + } +code, pre, tt, textarea { + font-family: Monaco, Consolas, "Lucida Console", monospace; + font-size: 12px; + line-height: 18px; + color: #191955; + white-space: pre-wrap; + word-wrap: break-word; +} + tt { + background: #f8f8ff; + border: 1px solid #dedede; + font-size: 85%; + padding: 0px 0.2em; + } + pre { + border-left: 6px solid #222255; + margin-left: 13px; + padding: 3px 0 3px 12px; + font-size: 12px; + } + pre.no_bar { + border-left: 0; + margin-left: 0; + padding-left: 0; + } +div.code { + position: relative; + border: 1px solid #cacaca; + background: #fafaff; + padding: 7px 0 10px 0; + -moz-border-radius: 5px; -webkit-border-radius: 5px; border-radius: 5px; + -webkit-box-shadow: 0px 0px 7px #cacaca; + zoom: 1; +} + div.code button { + position: absolute; + right: 8px; bottom: 8px; + } + div.code pre, div.code textarea { + float: left; + width: 450px; + background: #fafaff; + border-left: 1px dotted #559; + padding: 0 0 0 12px; + margin: 0; + } + div.code pre:first-child { + border-left: 0; + } + +#fadeout { + z-index: 50; + position: fixed; + left: 0; top: 0; right: 0; + height: 100px; + background: -webkit-gradient(linear, left top, left bottom, from(rgba(255, 255, 255, 255)), to(rgba(255, 255, 255, 0))); + background: -moz-linear-gradient(top, rgba(255, 255, 255, 255), rgba(255, 255, 255, 0)); +} + +#flybar { + position: fixed; + z-index: 100; + height: 50px; + min-width: 490px; + left: 40px; right: 40px; top: 25px; + padding-left: 235px; + background: #eee; + background: -webkit-gradient(linear, left top, left bottom, from(#f5f5f5), to(#d0d0d0)); + background: -moz-linear-gradient(top, #f5f5f5, #d0d0d0); + border: 1px solid #aaa; + -webkit-border-radius: 20px; -moz-border-radius: 20px; border-radius: 20px; + -webkit-box-shadow: 0 0 7px #aaa; -moz-box-shadow: 0 0 7px #aaa; +} + #logo { + display: block; + width: 215px; height: 50px; + background: url('../images/logo.png'); + position: absolute; + top: 0px; left: 10px; + } + #error { + position: absolute; + -webkit-border-radius: 6px; -moz-border-radius: 6px; border-radius: 6px; + right: 15px; top: 15px; left: 730px; + height: 15px; + padding: 2px 5px; + background: #fdcdcc; + color: #864544; + border: 1px solid #864544; + font-size: 10px; + line-height: 15px; + overflow: hidden; + text-transform: uppercase; + } + .navigation { + height: 50px; + font-size: 11px; + line-height: 50px; + text-transform: uppercase; + position: relative; + float: left; + padding: 0 20px; + border: 1px solid #bbb; + border-top: 0; border-bottom: 0; border-left-width: 0; + cursor: pointer; + } + body.full_screen .navigation { + position: static; + } + .navigation.toc { + border-left-width: 1px; + } + .navigation:hover, + .navigation.active { + background: #eee; + background: -webkit-gradient(linear, left top, left bottom, from(#f0f0f0), to(#c0c0c0)); + background: -moz-linear-gradient(top, #f0f0f0, #c0c0c0); + } + .navigation .button { + font-weight: bold; + } + .navigation .contents { + display: none; + position: absolute; + background: #fff; + top: 51px; left: 0; + padding: 5px 0; + margin-left: -1px; + border: 1px solid #aaa; border-top: 0; + -webkit-border-radius: 5px; -moz-border-radius: 5px; border-radius: 5px; + -webkit-border-top-left-radius: 0; -moz-border-radius-topleft: 0; + -webkit-border-top-right-radius: 0; -moz-border-radius-topright: 0; + -webkit-box-shadow: 0 5px 10px #999; -moz-box-shadow: 0 5px 10px #999; + } + .navigation.active .contents { + display: block; + } + .navigation .contents.repl_wrapper { + left: -162px; + width: 700px; + padding: 0; + } + body.full_screen .navigation .contents.repl_wrapper { + position: fixed; + width: auto; height: auto; + left: 60px; top: 77px; right: 60px; bottom: 30px; + } + .navigation .contents.repl_wrapper .code { + -webkit-box-shadow: none; -moz-box-shadow: none; + background: transparent; + border: 0; + position: static; + } + body.full_screen .navigation .contents.repl_wrapper .code { + height: 100%; + padding: 0; margin: 0; + } + .navigation .code button { + bottom: 10px; + text-transform: none; + line-height: 14px; + left: auto; right: auto; + } + .navigation .code .run { + width: 40px; + right: 10px; + } + .navigation .code .full_screen, .navigation .code .minimize { + left: 10px; + display: none; + width: 90px; + } + body.minimized .code .full_screen, body.full_screen .code .minimize { + display: inline; + } + .navigation .contents a { + display: block; + width: 290px; + text-transform: none; + text-decoration: none; + font-weight: normal; + height: 12px; + line-height: 12px; + padding: 4px 10px; + } + .navigation .contents a:hover { + background: #f0f0f0; + } + +.bookmark { + display: block; + width: 0; height: 0; + position: relative; + top: -90px; +} + +#repl_source, #repl_results { + background: transparent; + outline: none; + margin: 5px 0 20px; +} + #repl_source_wrap { + margin-left: 5px; + height: 250px; + width: 307px; + position: relative; + float: left; + } + #repl_source { + width: 96%; + height: 250px; + border: 0; + resize: none; + } + #repl_results { + font-family: Monaco, Consolas, "Lucida Console", monospace; + text-transform: none; + font-weight: normal; + height: 260px; + margin-bottom: 25px; + overflow-y: auto; + width: 370px; + } + body.full_screen #repl_results, body.full_screen #repl_source_wrap { + width: auto; height: auto; + position: absolute; + margin-bottom: 0; + top: 10px; left: 10px; right: 10px; bottom: 40px; + } + body.full_screen #repl_source { + height: 100%; + } + body.full_screen #repl_source_wrap { + right: 50%; + } + body.full_screen #repl_results { + left: 50%; + } diff --git a/node_modules/jade/support/coffee-script/documentation/css/idle.css b/node_modules/jade/support/coffee-script/documentation/css/idle.css new file mode 100644 index 0000000..e1e8a1a --- /dev/null +++ b/node_modules/jade/support/coffee-script/documentation/css/idle.css @@ -0,0 +1,64 @@ +pre.idle .InheritedClass { +} +pre.idle .TypeName { + color: #21439C; +} +pre.idle .Number { +} +pre.idle .LibraryVariable { + color: #A535AE; +} +pre.idle .Storage { + color: #FF5600; +} +pre.idle .line-numbers { + background-color: #BAD6FD; + color: #000000; +} +pre.idle { + background-color: #FFFFFF; + color: #000000; +} +pre.idle .StringInterpolation { + color: #990000; +} +pre.idle .TagName { +} +pre.idle .LibraryConstant { + color: #A535AE; +} +pre.idle .FunctionArgument { + color: #0076ad; +} +pre.idle .BuiltInConstant { + color: #A535AE; +} +pre.idle .Invalid { + background-color: #990000; + color: #FFFFFF; +} +pre.idle .LibraryClassType { + color: #A535AE; +} +pre.idle .LibraryFunction { + color: #A535AE; +} +pre.idle .TagAttribute { +} +pre.idle .Keyword { + color: #FF5600; +} +pre.idle .UserDefinedConstant { +} +pre.idle .String { + color: #00A33F; +} +pre.idle .FunctionName { + color: #21439C; +} +pre.idle .Variable { + color: #A535AE; +} +pre.idle .Comment { + color: #919191; +} diff --git a/node_modules/jade/support/coffee-script/documentation/docs/browser.html b/node_modules/jade/support/coffee-script/documentation/docs/browser.html new file mode 100644 index 0000000..54d4861 --- /dev/null +++ b/node_modules/jade/support/coffee-script/documentation/docs/browser.html @@ -0,0 +1,24 @@ + browser.coffee

    browser.coffee

    #

    Override exported methods for non-Node.js engines.

    CoffeeScript = require './coffee-script'
    #

    Use standard JavaScript eval to eval code.

    CoffeeScript.eval = (code, options) ->
    +  eval CoffeeScript.compile code, options
    #

    Running code does not provide access to this scope.

    CoffeeScript.run = (code, options) ->
    +  (Function CoffeeScript.compile code, options)()
    #

    If we're not in a browser environment, we're finished with the public API.

    return unless window?
    #

    Load a remote script from the current domain via XHR.

    CoffeeScript.load = (url, options) ->
    +  xhr = new (window.ActiveXObject or XMLHttpRequest)('Microsoft.XMLHTTP')
    +  xhr.open 'GET', url, true
    +  xhr.overrideMimeType 'text/plain' if 'overrideMimeType' of xhr
    +  xhr.onreadystatechange = ->
    +    CoffeeScript.run xhr.responseText, options if xhr.readyState is 4
    +  xhr.send null
    #

    Activate CoffeeScript in the browser by having it compile and evaluate +all script tags with a content-type of text/coffeescript. +This happens on page load.

    processScripts = ->
    +  for script in document.getElementsByTagName 'script'
    +    if script.type is 'text/coffeescript'
    +      if script.src
    +        CoffeeScript.load script.src
    +      else
    +        setTimeout -> CoffeeScript.run script.innerHTML
    +  null
    +if window.addEventListener
    +  addEventListener 'DOMContentLoaded', processScripts, false
    +else
    +  attachEvent 'onload', processScripts
    +
    +
    \ No newline at end of file diff --git a/node_modules/jade/support/coffee-script/documentation/docs/cake.html b/node_modules/jade/support/coffee-script/documentation/docs/cake.html new file mode 100644 index 0000000..7189e51 --- /dev/null +++ b/node_modules/jade/support/coffee-script/documentation/docs/cake.html @@ -0,0 +1,43 @@ + cake.coffee

    cake.coffee

    #

    cake is a simplified version of Make +(Rake, Jake) +for CoffeeScript. You define tasks with names and descriptions in a Cakefile, +and can call them from the command line, or invoke them from other tasks.

    + +

    Running cake with no arguments will print out a list of all the tasks in the +current directory's Cakefile.

    #

    External dependencies.

    fs           = require 'fs'
    +path         = require 'path'
    +helpers      = require('./helpers').helpers
    +optparse     = require './optparse'
    +CoffeeScript = require './coffee-script'
    #

    Keep track of the list of defined tasks, the accepted options, and so on.

    tasks     = {}
    +options   = {}
    +switches  = []
    +oparse    = null
    #

    Mixin the top-level Cake functions for Cakefiles to use directly.

    helpers.extend global,
    #

    Define a Cake task with a short name, an optional sentence description, +and the function to run as the action itself.

      task: (name, description, action) ->
    +    [action, description] = [description, action] unless action
    +    tasks[name] = {name, description, action}
    #

    Define an option that the Cakefile accepts. The parsed options hash, +containing all of the command-line options passed, will be made available +as the first argument to the action.

      option: (letter, flag, description) ->
    +    switches.push [letter, flag, description]
    #

    Invoke another task in the current Cakefile.

      invoke: (name) ->
    +    missingTask name unless tasks[name]
    +    tasks[name].action options
    #

    Run cake. Executes all of the tasks you pass, in order. Note that Node's +asynchrony may cause tasks to execute in a different order than you'd expect. +If no tasks are passed, print the help screen.

    exports.run = ->
    +  path.exists 'Cakefile', (exists) ->
    +    throw new Error("Cakefile not found in #{process.cwd()}") unless exists
    +    args = process.argv[2...process.argv.length]
    +    CoffeeScript.run fs.readFileSync('Cakefile').toString(), fileName: 'Cakefile'
    +    oparse = new optparse.OptionParser switches
    +    return printTasks() unless args.length
    +    options = oparse.parse(args)
    +    invoke arg for arg in options.arguments
    #

    Display the list of Cake tasks in a format similar to rake -T

    printTasks = ->
    +  puts ''
    +  for all name, task of tasks
    +    spaces = 20 - name.length
    +    spaces = if spaces > 0 then Array(spaces + 1).join(' ') else ''
    +    desc   = if task.description then "# #{task.description}" else ''
    +    puts "cake #{name}#{spaces} #{desc}"
    +  puts oparse.help() if switches.length
    #

    Print an error and exit when attempting to all an undefined task.

    missingTask = (task) ->
    +  puts "No such task: \"#{task}\""
    +  process.exit 1
    +
    +
    \ No newline at end of file diff --git a/node_modules/jade/support/coffee-script/documentation/docs/coffee-script.html b/node_modules/jade/support/coffee-script/documentation/docs/coffee-script.html new file mode 100644 index 0000000..36b3849 --- /dev/null +++ b/node_modules/jade/support/coffee-script/documentation/docs/coffee-script.html @@ -0,0 +1,50 @@ + coffee-script.coffee

    coffee-script.coffee

    #

    CoffeeScript can be used both on the server, as a command-line compiler based +on Node.js/V8, or to run CoffeeScripts directly in the browser. This module +contains the main entry functions for tokenzing, parsing, and compiling source +CoffeeScript into JavaScript.

    + +

    If included on a webpage, it will automatically sniff out, compile, and +execute all scripts present in text/coffeescript tags.

    path      = require 'path'
    +{Lexer}   = require './lexer'
    +{parser}  = require './parser'
    #

    TODO: Remove registerExtension when fully deprecated

    if require.extensions
    +  fs = require 'fs'
    +  require.extensions['.coffee'] = (module, filename) ->
    +    content = compile fs.readFileSync filename, 'utf8'
    +    module.filename = "#{filename} (compiled)"
    +    module._compile content, module.filename
    +else if require.registerExtension
    +  require.registerExtension '.coffee', (content) -> compile content
    #

    The current CoffeeScript version number.

    exports.VERSION = '0.9.4'
    #

    Compile a string of CoffeeScript code to JavaScript, using the Coffee/Jison +compiler.

    exports.compile = compile = (code, options) ->
    +  options or= {}
    +  try
    +    (parser.parse lexer.tokenize code).compile options
    +  catch err
    +    err.message = "In #{options.fileName}, #{err.message}" if options.fileName
    +    throw err
    #

    Tokenize a string of CoffeeScript code, and return the array of tokens.

    exports.tokens = (code) ->
    +  lexer.tokenize code
    #

    Tokenize and parse a string of CoffeeScript code, and return the AST. You can +then compile it by calling .compile() on the root, or traverse it by using +.traverse() with a callback.

    exports.nodes = (code) ->
    +  parser.parse lexer.tokenize code
    #

    Compile and execute a string of CoffeeScript (on the server), correctly +setting __filename, __dirname, and relative require().

    exports.run = (code, options) ->
    #

    We want the root module.

      root = module
    +  while root.parent
    +    root = root.parent
    #

    Set the filename

      root.filename = __filename = "#{options.fileName} (compiled)"
    #

    Clear the module cache

      root.moduleCache = {} if root.moduleCache
    #

    Compile

      root._compile exports.compile(code, options), root.filename
    #

    Compile and evaluate a string of CoffeeScript (in a Node.js-like environment). +The CoffeeScript REPL uses this to run the input.

    exports.eval = (code, options) ->
    +  __filename = options.fileName
    +  __dirname  = path.dirname __filename
    +  eval exports.compile(code, options)
    #

    Instantiate a Lexer for our use here.

    lexer = new Lexer
    #

    The real Lexer produces a generic stream of tokens. This object provides a +thin wrapper around it, compatible with the Jison API. We can then pass it +directly as a "Jison lexer".

    parser.lexer =
    +  lex: ->
    +    token = @tokens[@pos] or [""]
    +    @pos += 1
    +    this.yylineno = token[2]
    +    this.yytext   = token[1]
    +    token[0]
    +  setInput: (tokens) ->
    +    @tokens = tokens
    +    @pos    = 0
    +  upcomingInput: -> ""
    +
    +parser.yy = require './nodes'
    +
    +
    \ No newline at end of file diff --git a/node_modules/jade/support/coffee-script/documentation/docs/command.html b/node_modules/jade/support/coffee-script/documentation/docs/command.html new file mode 100644 index 0000000..d870c91 --- /dev/null +++ b/node_modules/jade/support/coffee-script/documentation/docs/command.html @@ -0,0 +1,148 @@ + command.coffee

    command.coffee

    #

    The coffee utility. Handles command-line compilation of CoffeeScript +into various forms: saved into .js files or printed to stdout, piped to +JSLint or recompiled every time the source is +saved, printed as a token stream or as the syntax tree, or launch an +interactive REPL.

    #

    External dependencies.

    fs             = require 'fs'
    +path           = require 'path'
    +optparse       = require './optparse'
    +CoffeeScript   = require './coffee-script'
    +{helpers}      = require './helpers'
    +{spawn, exec}  = require 'child_process'
    +{EventEmitter} = require 'events'
    #

    Allow CoffeeScript to emit Node.js events, and add it to global scope.

    helpers.extend CoffeeScript, new EventEmitter
    +global.CoffeeScript = CoffeeScript
    #

    The help banner that is printed when coffee is called without arguments.

    BANNER = '''
    +  coffee compiles CoffeeScript source files into JavaScript.
    +
    +  Usage:
    +    coffee path/to/script.coffee
    +         '''
    #

    The list of all the valid option flags that coffee knows how to handle.

    SWITCHES = [
    +  ['-c', '--compile',         'compile to JavaScript and save as .js files']
    +  ['-i', '--interactive',     'run an interactive CoffeeScript REPL']
    +  ['-o', '--output [DIR]',    'set the directory for compiled JavaScript']
    +  ['-w', '--watch',           'watch scripts for changes, and recompile']
    +  ['-p', '--print',           'print the compiled JavaScript to stdout']
    +  ['-l', '--lint',            'pipe the compiled JavaScript through JSLint']
    +  ['-s', '--stdio',           'listen for and compile scripts over stdio']
    +  ['-e', '--eval',            'compile a string from the command line']
    +  ['-r', '--require [FILE*]', 'require a library before executing your script']
    +  [      '--no-wrap',         'compile without the top-level function wrapper']
    +  ['-t', '--tokens',          'print the tokens that the lexer produces']
    +  ['-n', '--nodes',           'print the parse tree that Jison produces']
    +  ['-v', '--version',         'display CoffeeScript version']
    +  ['-h', '--help',            'display this help message']
    +]
    #

    Top-level objects shared by all the functions.

    opts         = {}
    +sources      = []
    +optionParser = null
    #

    Run coffee by parsing passed options and determining what action to take. +Many flags cause us to divert before compiling anything. Flags passed after +-- will be passed verbatim to your script as arguments in process.argv

    exports.run = ->
    +  parseOptions()
    +  return usage()                              if opts.help
    +  return version()                            if opts.version
    +  return require './repl'                     if opts.interactive
    +  return compileStdio()                       if opts.stdio
    +  return compileScript 'console', sources[0]  if opts.eval
    +  return require './repl'                     unless sources.length
    +  separator = sources.indexOf '--'
    +  flags = []
    +  if separator >= 0
    +    flags   = sources[(separator + 1)...sources.length]
    +    sources = sources[0...separator]
    +  if opts.run
    +    flags   = sources[1..sources.length].concat flags
    +    sources = [sources[0]]
    +  process.ARGV = process.argv = flags
    +  compileScripts()
    #

    Asynchronously read in each CoffeeScript in a list of source files and +compile them. If a directory is passed, recursively compile all +'.coffee' extension source files in it and all subdirectories.

    compileScripts = ->
    +  for source in sources
    +    base = source
    +    compile = (source, topLevel) ->
    +      path.exists source, (exists) ->
    +        throw new Error "File not found: #{source}" unless exists
    +        fs.stat source, (err, stats) ->
    +          if stats.isDirectory()
    +            fs.readdir source, (err, files) ->
    +              for file in files
    +                compile path.join(source, file)
    +          else if topLevel or path.extname(source) is '.coffee'
    +            fs.readFile source, (err, code) -> compileScript(source, code.toString(), base)
    +            watch source, base if opts.watch
    +    compile source, true
    #

    Compile a single source script, containing the given code, according to the +requested options. If evaluating the script directly sets __filename, +__dirname and module.filename to be correct relative to the script's path.

    compileScript = (file, input, base) ->
    +  o = opts
    +  options = compileOptions file
    +  if o.require
    +    require(if helpers.starts(req, '.') then fs.realpathSync(req) else req) for req in o.require
    +  try
    +    t = task = {file, input, options}
    +    CoffeeScript.emit 'compile', task
    +    if      o.tokens      then printTokens CoffeeScript.tokens t.input
    +    else if o.nodes       then puts CoffeeScript.nodes(t.input).toString()
    +    else if o.run         then CoffeeScript.run t.input, t.options
    +    else
    +      t.output = CoffeeScript.compile t.input, t.options
    +      CoffeeScript.emit 'success', task
    +      if o.print          then print t.output
    +      else if o.compile   then writeJs t.file, t.output, base
    +      else if o.lint      then lint t.output
    +  catch err
    #

    Avoid using 'error' as it is a special event -- if there is no handler, +node will print a stack trace and exit the program.

        CoffeeScript.emit 'failure', err, task
    +    return if CoffeeScript.listeners('failure').length
    +    return puts err.message if o.watch
    +    error err.stack
    +    process.exit 1
    #

    Attach the appropriate listeners to compile scripts incoming over stdin, +and write them back to stdout.

    compileStdio = ->
    +  code = ''
    +  stdin = process.openStdin()
    +  stdin.on 'data', (buffer) ->
    +    code += buffer.toString() if buffer
    +  stdin.on 'end', ->
    +    compileScript 'stdio', code
    #

    Watch a source CoffeeScript file using fs.watchFile, recompiling it every +time the file is updated. May be used in combination with other options, +such as --lint or --print.

    watch = (source, base) ->
    +  fs.watchFile source, {persistent: true, interval: 500}, (curr, prev) ->
    +    return if curr.size is prev.size and curr.mtime.getTime() is prev.mtime.getTime()
    +    fs.readFile source, (err, code) ->
    +      throw err if err
    +      compileScript(source, code.toString(), base)
    #

    Write out a JavaScript source file with the compiled code. By default, files +are written out in cwd as .js files with the same name, but the output +directory can be customized with --output.

    writeJs = (source, js, base) ->
    +  filename  = path.basename(source, path.extname(source)) + '.js'
    +  srcDir    = path.dirname source
    +  baseDir   = srcDir.substring base.length
    +  dir       = if opts.output then path.join opts.output, baseDir else srcDir
    +  jsPath    = path.join dir, filename
    +  compile   = ->
    +    js = ' ' if js.length <= 0
    +    fs.writeFile jsPath, js, (err) ->
    +      puts "Compiled #{source}" if opts.compile and opts.watch
    +  path.exists dir, (exists) ->
    +    if exists then compile() else exec "mkdir -p #{dir}", compile
    #

    Pipe compiled JS through JSLint (requires a working jsl command), printing +any errors or warnings that arise.

    lint = (js) ->
    +  printIt = (buffer) -> puts buffer.toString().trim()
    +  conf = __dirname + '/../extras/jsl.conf'
    +  jsl = spawn 'jsl', ['-nologo', '-stdin', '-conf', conf]
    +  jsl.stdout.on 'data', printIt
    +  jsl.stderr.on 'data', printIt
    +  jsl.stdin.write js
    +  jsl.stdin.end()
    #

    Pretty-print a stream of tokens.

    printTokens = (tokens) ->
    +  strings = for token in tokens
    +    [tag, value] = [token[0], token[1].toString().replace(/\n/, '\\n')]
    +    "[#{tag} #{value}]"
    +  puts strings.join(' ')
    #

    Use the OptionParser module to extract all options from +process.argv that are specified in SWITCHES.

    parseOptions = ->
    +  optionParser  = new optparse.OptionParser SWITCHES, BANNER
    +  o = opts      = optionParser.parse(process.argv[2...process.argv.length])
    +  o.compile     or=  !!o.output
    +  o.run         = not (o.compile or o.print or o.lint)
    +  o.print       = !!  (o.print or (o.eval or o.stdio and o.compile))
    +  sources       = o.arguments
    #

    The compile-time options to pass to the CoffeeScript compiler.

    compileOptions = (fileName) ->
    +  o = {fileName}
    +  o.noWrap = opts['no-wrap']
    +  o
    #

    Print the --help usage message and exit.

    usage = ->
    +  puts optionParser.help()
    +  process.exit 0
    #

    Print the --version message and exit.

    version = ->
    +  puts "CoffeeScript version #{CoffeeScript.VERSION}"
    +  process.exit 0
    +
    +
    \ No newline at end of file diff --git a/node_modules/jade/support/coffee-script/documentation/docs/docco.css b/node_modules/jade/support/coffee-script/documentation/docs/docco.css new file mode 100644 index 0000000..1ddec89 --- /dev/null +++ b/node_modules/jade/support/coffee-script/documentation/docs/docco.css @@ -0,0 +1,185 @@ +/*--------------------- Layout and Typography ----------------------------*/ +body { + font-family: 'Palatino Linotype', 'Book Antiqua', Palatino, FreeSerif, serif; + font-size: 16px; + line-height: 24px; + color: #252519; + margin: 0; padding: 0; +} +a { + color: #261a3b; +} + a:visited { + color: #261a3b; + } +p { + margin: 0 0 15px 0; +} +h1, h2, h3, h4, h5, h6 { + margin: 40px 0 15px 0; +} + h3, h4, h5, h6 { + margin-top: 20px; + } +#container { + position: relative; +} +#background { + position: fixed; + top: 0; left: 575px; right: 0; bottom: 0; + background: #f5f5ff; + border-left: 1px solid #e5e5ee; + z-index: -1; +} +#jump_to, #jump_page { + background: white; + -webkit-box-shadow: 0 0 25px #777; -moz-box-shadow: 0 0 25px #777; + -webkit-border-bottom-left-radius: 5px; -moz-border-radius-bottomleft: 5px; + font: 10px Arial; + text-transform: uppercase; + cursor: pointer; + text-align: right; +} +#jump_to, #jump_wrapper { + position: fixed; + right: 0; top: 0; + padding: 5px 10px; +} + #jump_wrapper { + padding: 0; + display: none; + } + #jump_to:hover #jump_wrapper { + display: block; + } + #jump_page { + padding: 5px 0 3px; + margin: 0 0 25px 25px; + } + #jump_page .source { + display: block; + padding: 5px 10px; + text-decoration: none; + border-top: 1px solid #eee; + } + #jump_page .source:hover { + background: #f5f5ff; + } + #jump_page .source:first-child { + } +table td { + border: 0; + outline: 0; +} + td.docs, th.docs { + max-width: 500px; + min-width: 500px; + min-height: 5px; + padding: 10px 25px 1px 50px; + vertical-align: top; + text-align: left; + } + .docs pre { + margin: 15px 0 15px; + padding-left: 15px; + } + .docs p tt, .docs p code { + background: #f8f8ff; + border: 1px solid #dedede; + font-size: 12px; + padding: 0 0.2em; + } + .octowrap { + position: relative; + } + .octothorpe { + font: 12px Arial; + text-decoration: none; + color: #454545; + position: absolute; + top: 3px; left: -20px; + padding: 1px 2px; + opacity: 0; + -webkit-transition: opacity 0.2s linear; + } + td.docs:hover .octothorpe { + opacity: 1; + } + td.code, th.code { + padding: 14px 15px 16px 50px; + width: 100%; + vertical-align: top; + background: #f5f5ff; + border-left: 1px solid #e5e5ee; + } + pre, tt, code { + font-size: 12px; line-height: 18px; + font-family: Monaco, Consolas, "Lucida Console", monospace; + margin: 0; padding: 0; + } + + +/*---------------------- Syntax Highlighting -----------------------------*/ +td.linenos { background-color: #f0f0f0; padding-right: 10px; } +span.lineno { background-color: #f0f0f0; padding: 0 5px 0 5px; } +body .hll { background-color: #ffffcc } +body .c { color: #408080; font-style: italic } /* Comment */ +body .err { border: 1px solid #FF0000 } /* Error */ +body .k { color: #954121 } /* Keyword */ +body .o { color: #666666 } /* Operator */ +body .cm { color: #408080; font-style: italic } /* Comment.Multiline */ +body .cp { color: #BC7A00 } /* Comment.Preproc */ +body .c1 { color: #408080; font-style: italic } /* Comment.Single */ +body .cs { color: #408080; font-style: italic } /* Comment.Special */ +body .gd { color: #A00000 } /* Generic.Deleted */ +body .ge { font-style: italic } /* Generic.Emph */ +body .gr { color: #FF0000 } /* Generic.Error */ +body .gh { color: #000080; font-weight: bold } /* Generic.Heading */ +body .gi { color: #00A000 } /* Generic.Inserted */ +body .go { color: #808080 } /* Generic.Output */ +body .gp { color: #000080; font-weight: bold } /* Generic.Prompt */ +body .gs { font-weight: bold } /* Generic.Strong */ +body .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ +body .gt { color: #0040D0 } /* Generic.Traceback */ +body .kc { color: #954121 } /* Keyword.Constant */ +body .kd { color: #954121; font-weight: bold } /* Keyword.Declaration */ +body .kn { color: #954121; font-weight: bold } /* Keyword.Namespace */ +body .kp { color: #954121 } /* Keyword.Pseudo */ +body .kr { color: #954121; font-weight: bold } /* Keyword.Reserved */ +body .kt { color: #B00040 } /* Keyword.Type */ +body .m { color: #666666 } /* Literal.Number */ +body .s { color: #219161 } /* Literal.String */ +body .na { color: #7D9029 } /* Name.Attribute */ +body .nb { color: #954121 } /* Name.Builtin */ +body .nc { color: #0000FF; font-weight: bold } /* Name.Class */ +body .no { color: #880000 } /* Name.Constant */ +body .nd { color: #AA22FF } /* Name.Decorator */ +body .ni { color: #999999; font-weight: bold } /* Name.Entity */ +body .ne { color: #D2413A; font-weight: bold } /* Name.Exception */ +body .nf { color: #0000FF } /* Name.Function */ +body .nl { color: #A0A000 } /* Name.Label */ +body .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */ +body .nt { color: #954121; font-weight: bold } /* Name.Tag */ +body .nv { color: #19469D } /* Name.Variable */ +body .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */ +body .w { color: #bbbbbb } /* Text.Whitespace */ +body .mf { color: #666666 } /* Literal.Number.Float */ +body .mh { color: #666666 } /* Literal.Number.Hex */ +body .mi { color: #666666 } /* Literal.Number.Integer */ +body .mo { color: #666666 } /* Literal.Number.Oct */ +body .sb { color: #219161 } /* Literal.String.Backtick */ +body .sc { color: #219161 } /* Literal.String.Char */ +body .sd { color: #219161; font-style: italic } /* Literal.String.Doc */ +body .s2 { color: #219161 } /* Literal.String.Double */ +body .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */ +body .sh { color: #219161 } /* Literal.String.Heredoc */ +body .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */ +body .sx { color: #954121 } /* Literal.String.Other */ +body .sr { color: #BB6688 } /* Literal.String.Regex */ +body .s1 { color: #219161 } /* Literal.String.Single */ +body .ss { color: #19469D } /* Literal.String.Symbol */ +body .bp { color: #954121 } /* Name.Builtin.Pseudo */ +body .vc { color: #19469D } /* Name.Variable.Class */ +body .vg { color: #19469D } /* Name.Variable.Global */ +body .vi { color: #19469D } /* Name.Variable.Instance */ +body .il { color: #666666 } /* Literal.Number.Integer.Long */ \ No newline at end of file diff --git a/node_modules/jade/support/coffee-script/documentation/docs/grammar.html b/node_modules/jade/support/coffee-script/documentation/docs/grammar.html new file mode 100644 index 0000000..0154097 --- /dev/null +++ b/node_modules/jade/support/coffee-script/documentation/docs/grammar.html @@ -0,0 +1,421 @@ + grammar.coffee

    grammar.coffee

    #

    The CoffeeScript parser is generated by Jison +from this grammar file. Jison is a bottom-up parser generator, similar in +style to Bison, implemented in JavaScript. +It can recognize LALR(1), LR(0), SLR(1), and LR(1) +type grammars. To create the Jison parser, we list the pattern to match +on the left-hand side, and the action to take (usually the creation of syntax +tree nodes) on the right. As the parser runs, it +shifts tokens from our token stream, from left to right, and +attempts to match +the token sequence against the rules below. When a match can be made, it +reduces into the nonterminal +(the enclosing name at the top), and we proceed from there.

    + +

    If you run the cake build:parser command, Jison constructs a parse table +from our rules and saves it into lib/parser.js.

    #

    The only dependency is on the Jison.Parser.

    Parser = require('jison').Parser
    #

    Jison DSL

    #

    Since we're going to be wrapped in a function by Jison in any case, if our +action immediately returns a value, we can optimize by removing the function +wrapper and just returning the value directly.

    unwrap = /function\s*\(\)\s*\{\s*return\s*([\s\S]*);\s*\}/
    #

    Our handy DSL for Jison grammar generation, thanks to +Tim Caswell. For every rule in the grammar, +we pass the pattern-defining string, the action to run, and extra options, +optionally. If no action is specified, we simply pass the value of the +previous nonterminal.

    o = (patternString, action, options) ->
    +  return [patternString, '$$ = $1;', options] unless action
    +  action = if match = (action + '').match(unwrap) then match[1] else "(#{action}())"
    +  action = action.replace /\b(?:[A-Z][a-z]+Node|Expressions)\b/g, 'yy.$&'
    +  [patternString, "$$ = #{action};", options]
    #

    Grammatical Rules

    #

    In all of the rules that follow, you'll see the name of the nonterminal as +the key to a list of alternative matches. With each match's action, the +dollar-sign variables are provided by Jison as references to the value of +their numeric position, so in this rule:

    + +
    "Expression UNLESS Expression"
    +
    + +

    $1 would be the value of the first Expression, $2 would be the token +for the UNLESS terminal, and $3 would be the value of the second +Expression.

    grammar =
    #

    The Root is the top-level node in the syntax tree. Since we parse bottom-up, +all parsing must end here.

      Root: [
    +    o "",                                       -> new Expressions
    +    o "TERMINATOR",                             -> new Expressions
    +    o "Body"
    +    o "Block TERMINATOR"
    +  ]
    #

    Any list of statements and expressions, seperated by line breaks or semicolons.

      Body: [
    +    o "Line",                                   -> Expressions.wrap [$1]
    +    o "Body TERMINATOR Line",                   -> $1.push $3
    +    o "Body TERMINATOR"
    +  ]
    #

    Expressions and statements, which make up a line in a body.

      Line: [
    +    o "Expression"
    +    o "Statement"
    +  ]
    #

    Pure statements which cannot be expressions.

      Statement: [
    +    o "Return"
    +    o "Throw"
    +    o "BREAK",                                  -> new LiteralNode $1
    +    o "CONTINUE",                               -> new LiteralNode $1
    +    o "DEBUGGER",                               -> new LiteralNode $1
    +  ]
    #

    All the different types of expressions in our language. The basic unit of +CoffeeScript is the Expression -- everything that can be an expression +is one. Expressions serve as the building blocks of many other rules, making +them somewhat circular.

      Expression: [
    +    o "Value"
    +    o "Call"
    +    o "Code"
    +    o "Operation"
    +    o "Assign"
    +    o "If"
    +    o "Try"
    +    o "While"
    +    o "For"
    +    o "Switch"
    +    o "Extends"
    +    o "Class"
    +    o "Existence"
    +    o "Comment"
    +  ]
    #

    An indented block of expressions. Note that the Rewriter +will convert some postfix forms into blocks for us, by adjusting the +token stream.

      Block: [
    +    o "INDENT Body OUTDENT",                    -> $2
    +    o "INDENT OUTDENT",                         -> new Expressions
    +    o "TERMINATOR Comment",                     -> Expressions.wrap [$2]
    +  ]
    #

    A literal identifier, a variable name or property.

      Identifier: [
    +    o "IDENTIFIER",                             -> new LiteralNode $1
    +  ]
    #

    Alphanumerics are separated from the other Literal matchers because +they can also serve as keys in object literals.

      AlphaNumeric: [
    +    o "NUMBER",                                 -> new LiteralNode $1
    +    o "STRING",                                 -> new LiteralNode $1
    +  ]
    #

    All of our immediate values. These can (in general), be passed straight +through and printed to JavaScript.

      Literal: [
    +    o "AlphaNumeric"
    +    o "JS",                                     -> new LiteralNode $1
    +    o "REGEX",                                  -> new LiteralNode $1
    +    o "TRUE",                                   -> new LiteralNode true
    +    o "FALSE",                                  -> new LiteralNode false
    +    o "YES",                                    -> new LiteralNode true
    +    o "NO",                                     -> new LiteralNode false
    +    o "ON",                                     -> new LiteralNode true
    +    o "OFF",                                    -> new LiteralNode false
    +  ]
    #

    Assignment of a variable, property, or index to a value.

      Assign: [
    +    o "Assignable = Expression",                -> new AssignNode $1, $3
    +    o "Assignable = INDENT Expression OUTDENT", -> new AssignNode $1, $4
    +  ]
    #

    Assignment when it happens within an object literal. The difference from +the ordinary Assign is that these allow numbers and strings as keys.

      AssignObj: [
    +    o "Identifier",                             -> new ValueNode $1
    +    o "AlphaNumeric"
    +    o "Identifier : Expression",                -> new AssignNode new ValueNode($1), $3, 'object'
    +    o "AlphaNumeric : Expression",              -> new AssignNode new ValueNode($1), $3, 'object'
    +    o "Identifier : INDENT Expression OUTDENT", -> new AssignNode new ValueNode($1), $4, 'object'
    +    o "AlphaNumeric : INDENT Expression OUTDENT", -> new AssignNode new ValueNode($1), $4, 'object'
    +    o "Comment"
    +  ]
    #

    A return statement from a function body.

      Return: [
    +    o "RETURN Expression",                      -> new ReturnNode $2
    +    o "RETURN",                                 -> new ReturnNode new ValueNode new LiteralNode 'null'
    +  ]
    #

    A block comment.

      Comment: [
    +    o "HERECOMMENT",                            -> new CommentNode $1
    +  ]
    #

    The existential operator.

      Existence: [
    +    o "Expression ?",                           -> new ExistenceNode $1
    +  ]
    #

    The Code node is the function literal. It's defined by an indented block +of Expressions preceded by a function arrow, with an optional parameter +list.

      Code: [
    +    o "PARAM_START ParamList PARAM_END FuncGlyph Block", -> new CodeNode $2, $5, $4
    +    o "FuncGlyph Block",                        -> new CodeNode [], $2, $1
    +  ]
    #

    CoffeeScript has two different symbols for functions. -> is for ordinary +functions, and => is for functions bound to the current value of this.

      FuncGlyph: [
    +    o "->",                                     -> 'func'
    +    o "=>",                                     -> 'boundfunc'
    +  ]
    #

    An optional, trailing comma.

      OptComma: [
    +    o ''
    +    o ','
    +  ]
    #

    The list of parameters that a function accepts can be of any length.

      ParamList: [
    +    o "",                                       -> []
    +    o "Param",                                  -> [$1]
    +    o "ParamList , Param",                      -> $1.concat [$3]
    +  ]
    #

    A single parameter in a function definition can be ordinary, or a splat +that hoovers up the remaining arguments.

      Param: [
    +    o "PARAM",                                  -> new LiteralNode $1
    +    o "@ PARAM",                                -> new ParamNode $2, true
    +    o "PARAM . . .",                            -> new ParamNode $1, false, true
    +    o "@ PARAM . . .",                          -> new ParamNode $2, true, true
    +  ]
    #

    A splat that occurs outside of a parameter list.

      Splat: [
    +    o "Expression . . .",                       -> new SplatNode $1
    +  ]
    #

    Variables and properties that can be assigned to.

      SimpleAssignable: [
    +    o "Identifier",                             -> new ValueNode $1
    +    o "Value Accessor",                         -> $1.push $2
    +    o "Invocation Accessor",                    -> new ValueNode $1, [$2]
    +    o "ThisProperty"
    +  ]
    #

    Everything that can be assigned to.

      Assignable: [
    +    o "SimpleAssignable"
    +    o "Array",                                  -> new ValueNode $1
    +    o "Object",                                 -> new ValueNode $1
    +  ]
    #

    The types of things that can be treated as values -- assigned to, invoked +as functions, indexed into, named as a class, etc.

      Value: [
    +    o "Assignable"
    +    o "Literal",                                -> new ValueNode $1
    +    o "Parenthetical",                          -> new ValueNode $1
    +    o "Range",                                  -> new ValueNode $1
    +    o "This"
    +    o "NULL",                                   -> new ValueNode new LiteralNode 'null'
    +  ]
    #

    The general group of accessors into an object, by property, by prototype +or by array index or slice.

      Accessor: [
    +    o "PROPERTY_ACCESS Identifier",             -> new AccessorNode $2
    +    o "PROTOTYPE_ACCESS Identifier",            -> new AccessorNode $2, 'prototype'
    +    o "::",                                     -> new AccessorNode(new LiteralNode('prototype'))
    +    o "SOAK_ACCESS Identifier",                 -> new AccessorNode $2, 'soak'
    +    o "Index"
    +    o "Slice",                                  -> new SliceNode $1
    +  ]
    #

    Indexing into an object or array using bracket notation.

      Index: [
    +    o "INDEX_START Expression INDEX_END",       -> new IndexNode $2
    +    o "INDEX_SOAK Index",                       -> $2.soakNode = yes; $2
    +    o "INDEX_PROTO Index",                      -> $2.proto = yes; $2
    +  ]
    #

    In CoffeeScript, an object literal is simply a list of assignments.

      Object: [
    +    o "{ AssignList OptComma }",                -> new ObjectNode $2
    +  ]
    #

    Assignment of properties within an object literal can be separated by +comma, as in JavaScript, or simply by newline.

      AssignList: [
    +    o "",                                       -> []
    +    o "AssignObj",                              -> [$1]
    +    o "AssignList , AssignObj",                 -> $1.concat [$3]
    +    o "AssignList OptComma TERMINATOR AssignObj", -> $1.concat [$4]
    +    o "AssignList OptComma INDENT AssignList OptComma OUTDENT", -> $1.concat $4
    +  ]
    #

    Class definitions have optional bodies of prototype property assignments, +and optional references to the superclass.

      Class: [
    +    o "CLASS SimpleAssignable",                 -> new ClassNode $2
    +    o "CLASS SimpleAssignable EXTENDS Value",   -> new ClassNode $2, $4
    +    o "CLASS SimpleAssignable INDENT ClassBody OUTDENT", -> new ClassNode $2, null, $4
    +    o "CLASS SimpleAssignable EXTENDS Value INDENT ClassBody OUTDENT", -> new ClassNode $2, $4, $6
    +    o "CLASS INDENT ClassBody OUTDENT",         -> new ClassNode '__temp__', null, $3
    +  ]
    #

    Assignments that can happen directly inside a class declaration.

      ClassAssign: [
    +    o "AssignObj",                              -> $1
    +    o "ThisProperty : Expression",              -> new AssignNode new ValueNode($1), $3, 'this'
    +    o "ThisProperty : INDENT Expression OUTDENT", -> new AssignNode new ValueNode($1), $4, 'this'
    +  ]
    #

    A list of assignments to a class.

      ClassBody: [
    +    o "",                                       -> []
    +    o "ClassAssign",                            -> [$1]
    +    o "ClassBody TERMINATOR ClassAssign",       -> $1.concat $3
    +    o "{ ClassBody }",                          -> $2
    +  ]
    #

    The two flavors of function call: normal, and object instantiation with new.

      Call: [
    +    o "Invocation"
    +    o "NEW Invocation",                         -> $2.newInstance()
    +    o "NEW Value",                              -> (new CallNode($2, [])).newInstance()
    +  ]
    #

    Extending an object by setting its prototype chain to reference a parent +object.

      Extends: [
    +    o "SimpleAssignable EXTENDS Value",         -> new ExtendsNode $1, $3
    +  ]
    #

    Ordinary function invocation, or a chained series of calls.

      Invocation: [
    +    o "Value OptFuncExist Arguments",           -> new CallNode $1, $3, $2
    +    o "Invocation OptFuncExist Arguments",      -> new CallNode $1, $3, $2
    +    o "SUPER",                                  -> new CallNode 'super', [new SplatNode(new LiteralNode('arguments'))]
    +    o "SUPER Arguments",                        -> new CallNode 'super', $2
    +  ]
    #

    An optional existence check on a function.

      OptFuncExist: [
    +    o "",                                       -> no
    +    o "FUNC_EXIST",                             -> yes
    +  ]
    #

    The list of arguments to a function call.

      Arguments: [
    +    o "CALL_START CALL_END",                    -> []
    +    o "CALL_START ArgList OptComma CALL_END",   -> $2
    +  ]
    #

    A reference to the this current object.

      This: [
    +    o "THIS",                                   -> new ValueNode new LiteralNode 'this'
    +    o "@",                                      -> new ValueNode new LiteralNode 'this'
    +  ]
    +
    +  RangeDots: [
    +    o ". .",                                    -> 'inclusive'
    +    o ". . .",                                  -> 'exclusive'
    +  ]
    #

    A reference to a property on this.

      ThisProperty: [
    +    o "@ Identifier",                           -> new ValueNode new LiteralNode('this'), [new AccessorNode($2)]
    +  ]
    #

    The CoffeeScript range literal.

      Range: [
    +    o "[ Expression RangeDots Expression ]",    -> new RangeNode $2, $4, $3
    +  ]
    #

    The slice literal.

      Slice: [
    +    o "INDEX_START Expression RangeDots Expression INDEX_END", -> new RangeNode $2, $4, $3
    +    o "INDEX_START Expression RangeDots INDEX_END", -> new RangeNode $2, null, $3
    +    o "INDEX_START RangeDots Expression INDEX_END", -> new RangeNode null, $3, $2
    +  ]
    #

    The array literal.

      Array: [
    +    o "[ ]",                                    -> new ArrayNode []
    +    o "[ ArgList OptComma ]",                   -> new ArrayNode $2
    +  ]
    #

    The ArgList is both the list of objects passed into a function call, +as well as the contents of an array literal +(i.e. comma-separated expressions). Newlines work as well.

      ArgList: [
    +    o "Arg",                                    -> [$1]
    +    o "ArgList , Arg",                          -> $1.concat [$3]
    +    o "ArgList OptComma TERMINATOR Arg",        -> $1.concat [$4]
    +    o "INDENT ArgList OptComma OUTDENT",        -> $2
    +    o "ArgList OptComma INDENT ArgList OptComma OUTDENT", -> $1.concat $4
    +  ]
    #

    Valid arguments are Expressions or Splats.

      Arg: [
    +    o "Expression"
    +    o "Splat"
    +  ]
    #

    Just simple, comma-separated, required arguments (no fancy syntax). We need +this to be separate from the ArgList for use in Switch blocks, where +having the newlines wouldn't make sense.

      SimpleArgs: [
    +    o "Expression"
    +    o "SimpleArgs , Expression",                ->
    +      if $1 instanceof Array then $1.concat([$3]) else [$1].concat([$3])
    +  ]
    #

    The variants of try/catch/finally exception handling blocks.

      Try: [
    +    o "TRY Block Catch",                        -> new TryNode $2, $3[0], $3[1]
    +    o "TRY Block FINALLY Block",                -> new TryNode $2, null, null, $4
    +    o "TRY Block Catch FINALLY Block",          -> new TryNode $2, $3[0], $3[1], $5
    +  ]
    #

    A catch clause names its error and runs a block of code.

      Catch: [
    +    o "CATCH Identifier Block",                 -> [$2, $3]
    +  ]
    #

    Throw an exception object.

      Throw: [
    +    o "THROW Expression",                       -> new ThrowNode $2
    +  ]
    #

    Parenthetical expressions. Note that the Parenthetical is a Value, +not an Expression, so if you need to use an expression in a place +where only values are accepted, wrapping it in parentheses will always do +the trick.

      Parenthetical: [
    +    o "( Line )",                               -> new ParentheticalNode $2
    +    o "( )",                                    -> new ParentheticalNode new LiteralNode ''
    +  ]
    #

    The condition portion of a while loop.

      WhileSource: [
    +    o "WHILE Expression",                       -> new WhileNode $2
    +    o "WHILE Expression WHEN Expression",       -> new WhileNode $2, guard: $4
    +    o "UNTIL Expression",                       -> new WhileNode $2, invert: true
    +    o "UNTIL Expression WHEN Expression",       -> new WhileNode $2, invert: true, guard: $4
    +  ]
    #

    The while loop can either be normal, with a block of expressions to execute, +or postfix, with a single expression. There is no do..while.

      While: [
    +    o "WhileSource Block",                      -> $1.addBody $2
    +    o "Statement WhileSource",                  -> $2.addBody Expressions.wrap [$1]
    +    o "Expression WhileSource",                 -> $2.addBody Expressions.wrap [$1]
    +    o "Loop",                                   -> $1
    +  ]
    +
    +  Loop: [
    +    o "LOOP Block",                             -> new WhileNode(new LiteralNode 'true').addBody $2
    +    o "LOOP Expression",                        -> new WhileNode(new LiteralNode 'true').addBody Expressions.wrap [$2]
    +  ]
    #

    Array, object, and range comprehensions, at the most generic level. +Comprehensions can either be normal, with a block of expressions to execute, +or postfix, with a single expression.

      For: [
    +    o "Statement ForBody",                      -> new ForNode $1, $2, $2.vars[0], $2.vars[1]
    +    o "Expression ForBody",                     -> new ForNode $1, $2, $2.vars[0], $2.vars[1]
    +    o "ForBody Block",                          -> new ForNode $2, $1, $1.vars[0], $1.vars[1]
    +  ]
    +
    +  ForBody: [
    +    o "FOR Range",                              -> source: new ValueNode($2), vars: []
    +    o "ForStart ForSource",                     -> $2.raw = $1.raw; $2.vars = $1; $2
    +  ]
    +
    +  ForStart: [
    +    o "FOR ForVariables",                       -> $2
    +    o "FOR ALL ForVariables",                   -> $3.raw = true; $3
    +  ]
    #

    An array of all accepted values for a variable inside the loop. This +enables support for pattern matching.

      ForValue: [
    +    o "Identifier"
    +    o "Array",                                  -> new ValueNode $1
    +    o "Object",                                 -> new ValueNode $1
    +  ]
    #

    An array or range comprehension has variables for the current element and +(optional) reference to the current index. Or, key, value, in the case +of object comprehensions.

      ForVariables: [
    +    o "ForValue",                               -> [$1]
    +    o "ForValue , ForValue",                    -> [$1, $3]
    +  ]
    #

    The source of a comprehension is an array or object with an optional guard +clause. If it's an array comprehension, you can also choose to step through +in fixed-size increments.

      ForSource: [
    +    o "IN Expression",                               -> source: $2
    +    o "OF Expression",                               -> source: $2, object: true
    +    o "IN Expression WHEN Expression",               -> source: $2, guard: $4
    +    o "OF Expression WHEN Expression",               -> source: $2, guard: $4, object: true
    +    o "IN Expression BY Expression",                 -> source: $2, step:  $4
    +    o "IN Expression WHEN Expression BY Expression", -> source: $2, guard: $4, step:   $6
    +    o "IN Expression BY Expression WHEN Expression", -> source: $2, step:  $4, guard: $6
    +  ]
    +
    +  Switch: [
    +    o "SWITCH Expression INDENT Whens OUTDENT", -> new SwitchNode $2, $4
    +    o "SWITCH Expression INDENT Whens ELSE Block OUTDENT", -> new SwitchNode $2, $4, $6
    +    o "SWITCH INDENT Whens OUTDENT",            -> new SwitchNode null, $3
    +    o "SWITCH INDENT Whens ELSE Block OUTDENT", -> new SwitchNode null, $3, $5
    +  ]
    +
    +  Whens: [
    +    o "When"
    +    o "Whens When",                             -> $1.concat $2
    +  ]
    #

    An individual When clause, with action.

      When: [
    +    o "LEADING_WHEN SimpleArgs Block",            -> [[$2, $3]]
    +    o "LEADING_WHEN SimpleArgs Block TERMINATOR", -> [[$2, $3]]
    +  ]
    #

    The most basic form of if is a condition and an action. The following +if-related rules are broken up along these lines in order to avoid +ambiguity.

      IfBlock: [
    +    o "IF Expression Block",                    -> new IfNode $2, $3
    +    o "UNLESS Expression Block",                -> new IfNode $2, $3, invert: true
    +    o "IfBlock ELSE IF Expression Block",       -> $1.addElse (new IfNode($4, $5)).forceStatement()
    +    o "IfBlock ELSE Block",                     -> $1.addElse $3
    +  ]
    #

    The full complement of if expressions, including postfix one-liner +if and unless.

      If: [
    +    o "IfBlock"
    +    o "Statement POST_IF Expression",           -> new IfNode $3, Expressions.wrap([$1]), statement: true
    +    o "Expression POST_IF Expression",          -> new IfNode $3, Expressions.wrap([$1]), statement: true
    +    o "Statement POST_UNLESS Expression",       -> new IfNode $3, Expressions.wrap([$1]), statement: true, invert: true
    +    o "Expression POST_UNLESS Expression",      -> new IfNode $3, Expressions.wrap([$1]), statement: true, invert: true
    +  ]
    #

    Arithmetic and logical operators, working on one or more operands. +Here they are grouped by order of precedence. The actual precedence rules +are defined at the bottom of the page. It would be shorter if we could +combine most of these rules into a single generic Operand OpSymbol Operand +-type rule, but in order to make the precedence binding possible, separate +rules are necessary.

      Operation: [
    +    o "UNARY Expression",                       -> new OpNode $1, $2
    +    o("- Expression",                           (-> new OpNode('-', $2)), {prec: 'UNARY'})
    +    o("+ Expression",                           (-> new OpNode('+', $2)), {prec: 'UNARY'})
    +
    +    o "-- Expression",                          -> new OpNode '--', $2
    +    o "++ Expression",                          -> new OpNode '++', $2
    +    o "Expression --",                          -> new OpNode '--', $1, null, true
    +    o "Expression ++",                          -> new OpNode '++', $1, null, true
    +
    +    o "Expression ? Expression",                -> new OpNode '?', $1, $3
    +    o "Expression + Expression",                -> new OpNode '+', $1, $3
    +    o "Expression - Expression",                -> new OpNode '-', $1, $3
    +    o "Expression == Expression",               -> new OpNode '==', $1, $3
    +    o "Expression != Expression",               -> new OpNode '!=', $1, $3
    +
    +    o "Expression MATH Expression",             -> new OpNode $2, $1, $3
    +    o "Expression SHIFT Expression",            -> new OpNode $2, $1, $3
    +    o "Expression COMPARE Expression",          -> new OpNode $2, $1, $3
    +    o "Expression LOGIC Expression",            -> new OpNode $2, $1, $3
    +    o "Value COMPOUND_ASSIGN Expression",       -> new OpNode $2, $1, $3
    +    o "Value COMPOUND_ASSIGN INDENT Expression OUTDENT", -> new OpNode $2, $1, $4
    +
    +    o "Expression IN Expression",               -> new InNode $1, $3
    +    o "Expression OF Expression",               -> new OpNode 'in', $1, $3
    +    o "Expression INSTANCEOF Expression",       -> new OpNode 'instanceof', $1, $3
    +    o "Expression UNARY IN Expression",         -> new OpNode $2, new InNode $1, $4
    +    o "Expression UNARY OF Expression",         -> new OpNode $2, new ParentheticalNode new OpNode 'in', $1, $4
    +    o "Expression UNARY INSTANCEOF Expression", -> new OpNode $2, new ParentheticalNode new OpNode 'instanceof', $1, $4
    +  ]
    #

    Precedence

    #

    Operators at the top of this list have higher precedence than the ones lower +down. Following these rules is what makes 2 + 3 * 4 parse as:

    + +
    2 + (3 * 4)
    +
    + +

    And not:

    + +
    (2 + 3) * 4
    +
    operators = [
    +  ["right",     '?', 'NEW']
    +  ["left",      'CALL_START', 'CALL_END']
    +  ["nonassoc",  '++', '--']
    +  ["right",     'UNARY']
    +  ["left",      'MATH']
    +  ["left",      '+', '-']
    +  ["left",      'SHIFT']
    +  ["left",      'COMPARE']
    +  ["left",      'INSTANCEOF']
    +  ["left",      '==', '!=']
    +  ["left",      'LOGIC']
    +  ["right",     'COMPOUND_ASSIGN']
    +  ["left",      '.']
    +  ["nonassoc",  'INDENT', 'OUTDENT']
    +  ["right",     'WHEN', 'LEADING_WHEN', 'IN', 'OF', 'BY', 'THROW']
    +  ["right",     'IF', 'UNLESS', 'ELSE', 'FOR', 'WHILE', 'UNTIL', 'LOOP', 'SUPER', 'CLASS', 'EXTENDS']
    +  ["right",     '=', ':', 'RETURN']
    +  ["right",     '->', '=>', 'UNLESS', 'POST_IF', 'POST_UNLESS']
    +]
    #

    Wrapping Up

    #

    Finally, now what we have our grammar and our operators, we can create +our Jison.Parser. We do this by processing all of our rules, recording all +terminals (every symbol which does not appear as the name of a rule above) +as "tokens".

    tokens = []
    +for name, alternatives of grammar
    +  grammar[name] = for alt in alternatives
    +    for token in alt[0].split ' '
    +      tokens.push token unless grammar[token]
    +    alt[1] = "return #{alt[1]}" if name is 'Root'
    +    alt
    #

    Initialize the Parser with our list of terminal tokens, our grammar +rules, and the name of the root. Reverse the operators because Jison orders +precedence from low to high, and we have it high to low +(as in Yacc).

    exports.parser = new Parser
    +  tokens:       tokens.join ' '
    +  bnf:          grammar
    +  operators:    operators.reverse()
    +  startSymbol:  'Root'
    +
    +
    \ No newline at end of file diff --git a/node_modules/jade/support/coffee-script/documentation/docs/helpers.html b/node_modules/jade/support/coffee-script/documentation/docs/helpers.html new file mode 100644 index 0000000..d3bc7ad --- /dev/null +++ b/node_modules/jade/support/coffee-script/documentation/docs/helpers.html @@ -0,0 +1,37 @@ + helpers.coffee

    helpers.coffee

    #

    This file contains the common helper functions that we'd like to share among +the Lexer, Rewriter, and the Nodes. Merge objects, flatten +arrays, count characters, that sort of thing.

    helpers = exports.helpers = {}
    #

    Cross-browser indexOf, so that IE can join the party.

    helpers.indexOf = indexOf = (array, item, from) ->
    +  return array.indexOf item, from if array.indexOf
    +  for other, index in array
    +    if other is item and (not from or (from <= index))
    +      return index
    +  -1
    #

    Does a list include a value?

    helpers.include = include = (list, value) ->
    +  indexOf(list, value) >= 0
    #

    Peek at the beginning of a given string to see if it matches a sequence.

    helpers.starts = starts = (string, literal, start) ->
    +  string.substring(start, (start or 0) + literal.length) is literal
    #

    Peek at the end of a given string to see if it matches a sequence.

    helpers.ends = ends = (string, literal, back) ->
    +  start = string.length - literal.length - (back ? 0)
    +  string.substring(start, start + literal.length) is literal
    #

    Trim out all falsy values from an array.

    helpers.compact = compact = (array) -> item for item in array when item
    #

    Count the number of occurences of a character in a string.

    helpers.count = count = (string, letter) ->
    +  num = 0
    +  pos = indexOf string, letter
    +  while pos isnt -1
    +    num += 1
    +    pos = indexOf string, letter, pos + 1
    +  num
    #

    Merge objects, returning a fresh copy with attributes from both sides. +Used every time BaseNode#compile is called, to allow properties in the +options hash to propagate down the tree without polluting other branches.

    helpers.merge = merge = (options, overrides) ->
    +  fresh = {}
    +  (fresh[key] = val) for all key, val of options
    +  (fresh[key] = val) for all key, val of overrides if overrides
    +  fresh
    #

    Extend a source object with the properties of another object (shallow copy). +We use this to simulate Node's deprecated process.mixin

    helpers.extend = extend = (object, properties) ->
    +  (object[key] = val) for all key, val of properties
    #

    Return a completely flattened version of an array. Handy for getting a +list of children from the nodes.

    helpers.flatten = flatten = (array) ->
    +  memo = []
    +  for item in array
    +    if item instanceof Array then memo = memo.concat(item) else memo.push(item)
    +  memo
    #

    Delete a key from an object, returning the value. Useful when a node is +looking for a particular method in an options hash.

    helpers.del = del = (obj, key) ->
    +  val = obj[key]
    +  delete obj[key]
    +  val
    +
    +
    \ No newline at end of file diff --git a/node_modules/jade/support/coffee-script/documentation/docs/index.html b/node_modules/jade/support/coffee-script/documentation/docs/index.html new file mode 100644 index 0000000..4dcd19c --- /dev/null +++ b/node_modules/jade/support/coffee-script/documentation/docs/index.html @@ -0,0 +1,3 @@ + index.coffee \ No newline at end of file diff --git a/node_modules/jade/support/coffee-script/documentation/docs/lexer.html b/node_modules/jade/support/coffee-script/documentation/docs/lexer.html new file mode 100644 index 0000000..fc3d1f5 --- /dev/null +++ b/node_modules/jade/support/coffee-script/documentation/docs/lexer.html @@ -0,0 +1,431 @@ + lexer.coffee

    lexer.coffee

    #

    The CoffeeScript Lexer. Uses a series of token-matching regexes to attempt +matches against the beginning of the source code. When a match is found, +a token is produced, we consume the match, and start again. Tokens are in the +form:

    + +
    [tag, value, lineNumber]
    +
    + +

    Which is a format that can be fed directly into Jison.

    {Rewriter} = require './rewriter'
    #

    Import the helpers we need.

    {include, count, starts, compact} = require('./helpers').helpers
    #

    The Lexer Class

    #

    The Lexer class reads a stream of CoffeeScript and divvys it up into tagged +tokens. Some potential ambiguity in the grammar has been avoided by +pushing some extra smarts into the Lexer.

    exports.Lexer = class Lexer
    #

    tokenize is the Lexer's main method. Scan by attempting to match tokens +one at a time, using a regular expression anchored at the start of the +remaining code, or a custom recursive token-matching method +(for interpolations). When the next token has been recorded, we move forward +within the code past the token, and begin again.

    + +

    Each tokenizing method is responsible for incrementing @i by the number of +characters it has consumed. @i can be thought of as our finger on the page +of source.

    + +

    Before returning the token stream, run it through the Rewriter +unless explicitly asked not to.

      tokenize: (code, options) ->
    +    code     = code.replace /(\r|\s+$)/g, ''
    +    o        = options or {}
    +    @code    = code         # The remainder of the source code.
    +    @i       = 0            # Current character position we're parsing.
    +    @line    = o.line or 0  # The current line.
    +    @indent  = 0            # The current indentation level.
    +    @indebt  = 0            # The over-indentation at the current level.
    +    @outdebt = 0            # The under-outdentation at the current level.
    +    @indents = []           # The stack of all current indentation levels.
    +    @tokens  = []           # Stream of parsed tokens in the form ['TYPE', value, line]
    +    while @i < @code.length
    +      @chunk = @code[@i..]
    +      @extractNextToken()
    +    @closeIndentation()
    +    return @tokens if o.rewrite is off
    +    (new Rewriter).rewrite @tokens
    #

    At every position, run through this list of attempted matches, +short-circuiting if any of them succeed. Their order determines precedence: +@literalToken is the fallback catch-all.

      extractNextToken: ->
    +    return if @identifierToken()
    +    return if @commentToken()
    +    return if @whitespaceToken()
    +    return if @lineToken()
    +    return if @heredocToken()
    +    return if @stringToken()
    +    return if @numberToken()
    +    return if @regexToken()
    +    return if @jsToken()
    +    return    @literalToken()
    #

    Tokenizers

    #

    Matches identifying literals: variables, keywords, method names, etc. +Check to ensure that JavaScript reserved words aren't being used as +identifiers. Because CoffeeScript reserves a handful of keywords that are +allowed in JavaScript, we're careful not to tag them as keywords when +referenced as property names here, so you can still do jQuery.is() even +though is means === otherwise.

      identifierToken: ->
    +    return false unless id = @match IDENTIFIER, 1
    +    @i += id.length
    +    forcedIdentifier = @tagAccessor() or @match ASSIGNED, 1
    +    tag = 'IDENTIFIER'
    +    tag = id.toUpperCase() if include(JS_KEYWORDS, id) or (not forcedIdentifier and include(COFFEE_KEYWORDS, id))
    +    tag = 'LEADING_WHEN'   if tag is 'WHEN' and include LINE_BREAK, @tag()
    +    tag = 'ALL'            if id is 'all' and @tag() is 'FOR'
    +    tag = 'UNARY'          if include UNARY, tag
    +    if include(JS_FORBIDDEN, id)
    +      if forcedIdentifier
    +        tag = 'STRING'
    +        id  = "\"#{id}\""
    +        if forcedIdentifier is 'accessor'
    +          close_index = true
    +          @tokens.pop() if @tag() isnt '@'
    +          @token 'INDEX_START', '['
    +      else if include(RESERVED, id)
    +        @identifierError id
    +    unless forcedIdentifier
    +      tag = id = CONVERSIONS[id] if include COFFEE_ALIASES, id
    +      tag = 'LOGIC' if include LOGIC, id
    +      tag = 'UNARY' if id is '!'
    +    @token tag, id
    +    @token ']', ']' if close_index
    +    true
    #

    Matches numbers, including decimals, hex, and exponential notation. +Be careful not to interfere with ranges-in-progress.

      numberToken: ->
    +    return false unless number = @match NUMBER, 1
    +    return false if @tag() is '.' and starts number, '.'
    +    @i += number.length
    +    @token 'NUMBER', number
    +    true
    #

    Matches strings, including multi-line strings. Ensures that quotation marks +are balanced within the string's contents, and within nested interpolations.

      stringToken: ->
    +    return false unless starts(@chunk, '"') or starts(@chunk, "'")
    +    return false unless string =
    +      @balancedToken(['"', '"'], ['#{', '}']) or
    +      @balancedToken ["'", "'"]
    +    @interpolateString string.replace /\n/g, '\\\n'
    +    @line += count string, "\n"
    +    @i += string.length
    +    true
    #

    Matches heredocs, adjusting indentation to the correct level, as heredocs +preserve whitespace, but ignore indentation to the left.

      heredocToken: ->
    +    return false unless match = @chunk.match HEREDOC
    +    quote = match[1].substr 0, 1
    +    doc = @sanitizeHeredoc match[2] or match[4] or '', {quote}
    +    @interpolateString quote + doc + quote, heredoc: yes
    +    @line += count match[1], "\n"
    +    @i += match[1].length
    +    true
    #

    Matches and consumes comments.

      commentToken: ->
    +    return false unless match = @chunk.match(COMMENT)
    +    @line += count match[1], "\n"
    +    @i += match[1].length
    +    if match[2]
    +      @token 'HERECOMMENT', @sanitizeHeredoc match[2],
    +        herecomment: true, indent: Array(@indent + 1).join(' ')
    +      @token 'TERMINATOR', '\n'
    +    true
    #

    Matches JavaScript interpolated directly into the source via backticks.

      jsToken: ->
    +    return false unless starts @chunk, '`'
    +    return false unless script = @balancedToken ['`', '`']
    +    @token 'JS', script.replace JS_CLEANER, ''
    +    @i += script.length
    +    true
    #

    Matches regular expression literals. Lexing regular expressions is difficult +to distinguish from division, so we borrow some basic heuristics from +JavaScript and Ruby, borrow slash balancing from @balancedToken, and +borrow interpolation from @interpolateString.

      regexToken: ->
    +    return false unless first = @chunk.match REGEX_START
    +    return false if first[1] is ' ' and @tag() not in ['CALL_START', '=']
    +    return false if     include NOT_REGEX, @tag()
    +    return false unless regex = @balancedToken ['/', '/']
    +    return false unless end = @chunk.substr(regex.length).match REGEX_END
    +    regex += flags = end[2] if end[2]
    +    if regex.match REGEX_INTERPOLATION
    +      str = regex.substring(1).split('/')[0]
    +      str = str.replace REGEX_ESCAPE, (escaped) -> '\\' + escaped
    +      @tokens = @tokens.concat [['(', '('], ['NEW', 'new'], ['IDENTIFIER', 'RegExp'], ['CALL_START', '(']]
    +      @interpolateString "\"#{str}\"", escapeQuotes: yes
    +      @tokens.splice @tokens.length, 0, [',', ','], ['STRING', "\"#{flags}\""] if flags
    +      @tokens.splice @tokens.length, 0, [')', ')'], [')', ')']
    +    else
    +      @token 'REGEX', regex
    +    @i += regex.length
    +    true
    #

    Matches a token in which which the passed delimiter pairs must be correctly +balanced (ie. strings, JS literals).

      balancedToken: (delimited...) ->
    +    @balancedString @chunk, delimited
    #

    Matches newlines, indents, and outdents, and determines which is which. +If we can detect that the current line is continued onto the the next line, +then the newline is suppressed:

    + +
    elements
    +  .each( ... )
    +  .map( ... )
    +
    + +

    Keeps track of the level of indentation, because a single outdent token +can close multiple indents, so we need to know how far in we happen to be.

      lineToken: ->
    +    return false unless indent = @match MULTI_DENT, 1
    +    @line += count indent, "\n"
    +    @i    += indent.length
    +    prev = @prev(2)
    +    size = indent.match(LAST_DENTS).reverse()[0].match(LAST_DENT)[1].length
    +    nextCharacter = @match NEXT_CHARACTER, 1
    +    noNewlines = nextCharacter is '.' or nextCharacter is ',' or @unfinished()
    +    if size - @indebt is @indent
    +      return @suppressNewlines() if noNewlines
    +      return @newlineToken indent
    +    else if size > @indent
    +      if noNewlines
    +        @indebt = size - @indent
    +        return @suppressNewlines()
    +      diff = size - @indent + @outdebt
    +      @token 'INDENT', diff
    +      @indents.push diff
    +      @outdebt = @indebt = 0
    +    else
    +      @indebt = 0
    +      @outdentToken @indent - size, noNewlines
    +    @indent = size
    +    true
    #

    Record an outdent token or multiple tokens, if we happen to be moving back +inwards past several recorded indents.

      outdentToken: (moveOut, noNewlines, close) ->
    +    while moveOut > 0
    +      len = @indents.length - 1
    +      if @indents[len] is undefined
    +        moveOut = 0
    +      else if @indents[len] is @outdebt
    +        moveOut -= @outdebt
    +        @outdebt = 0
    +      else if @indents[len] < @outdebt
    +        @outdebt -= @indents[len]
    +        moveOut -= @indents[len]
    +      else
    +        dent = @indents.pop()
    +        dent -= @outdebt
    +        moveOut -= dent
    +        @outdebt = 0
    +        @token 'OUTDENT', dent
    +    @outdebt -= moveOut if dent
    +    @token 'TERMINATOR', "\n" unless @tag() is 'TERMINATOR' or noNewlines
    +    true
    #

    Matches and consumes non-meaningful whitespace. Tag the previous token +as being "spaced", because there are some cases where it makes a difference.

      whitespaceToken: ->
    +    return false unless space = @match WHITESPACE, 1
    +    prev = @prev()
    +    prev.spaced = true if prev
    +    @i += space.length
    +    true
    #

    Generate a newline token. Consecutive newlines get merged together.

      newlineToken: (newlines) ->
    +    @token 'TERMINATOR', "\n" unless @tag() is 'TERMINATOR'
    +    true
    #

    Use a \ at a line-ending to suppress the newline. +The slash is removed here once its job is done.

      suppressNewlines: ->
    +    @tokens.pop() if @value() is "\\"
    +    true
    #

    We treat all other single characters as a token. Eg.: ( ) , . ! +Multi-character operators are also literal tokens, so that Jison can assign +the proper order of operations. There are some symbols that we tag specially +here. ; and newlines are both treated as a TERMINATOR, we distinguish +parentheses that indicate a method call from regular parentheses, and so on.

      literalToken: ->
    +    match = @chunk.match OPERATOR
    +    value = match and match[1]
    +    space = match and match[2]
    +    @tagParameters() if value and value.match CODE
    +    value or= @chunk.substr 0, 1
    +    @i += value.length
    +    spaced = (prev = @prev()) and prev.spaced
    +    tag = value
    +    if value is '='
    +      @assignmentError() if include JS_FORBIDDEN, @value()
    +      if @value() in ['or', 'and']
    +        @tokens.splice(@tokens.length - 1, 1, ['COMPOUND_ASSIGN', CONVERSIONS[@value()] + '=', prev[2]])
    +        return true
    +    if value is ';'                         then tag = 'TERMINATOR'
    +    else if include(LOGIC, value)           then tag = 'LOGIC'
    +    else if include(MATH, value)            then tag = 'MATH'
    +    else if include(COMPARE, value)         then tag = 'COMPARE'
    +    else if include(COMPOUND_ASSIGN, value) then tag = 'COMPOUND_ASSIGN'
    +    else if include(UNARY, value)           then tag = 'UNARY'
    +    else if include(SHIFT, value)           then tag = 'SHIFT'
    +    else if include(CALLABLE, @tag()) and not spaced
    +      if value is '('
    +        prev[0] = 'FUNC_EXIST' if prev[0] is '?'
    +        tag = 'CALL_START'
    +      else if value is '['
    +        tag = 'INDEX_START'
    +        @tag 1, 'INDEX_SOAK'  if @tag() is '?'
    +        @tag 1, 'INDEX_PROTO' if @tag() is '::'
    +    @token tag, value
    +    true
    #

    Token Manipulators

    #

    As we consume a new IDENTIFIER, look at the previous token to determine +if it's a special kind of accessor. Return true if any type of accessor +is the previous token.

      tagAccessor: ->
    +    return false if (not prev = @prev()) or (prev and prev.spaced)
    +    accessor = if prev[1] is '::'
    +      @tag 1, 'PROTOTYPE_ACCESS'
    +    else if prev[1] is '.' and not (@value(2) is '.')
    +      if @tag(2) is '?'
    +        @tag(1, 'SOAK_ACCESS')
    +        @tokens.splice(-2, 1)
    +      else
    +        @tag 1, 'PROPERTY_ACCESS'
    +    else
    +      prev[0] is '@'
    +    if accessor then 'accessor' else false
    #

    Sanitize a heredoc or herecomment by escaping internal double quotes and +erasing all external indentation on the left-hand side.

      sanitizeHeredoc: (doc, options) ->
    +    indent = options.indent
    +    return doc if options.herecomment and not include doc, '\n'
    +    unless options.herecomment
    +      while (match = HEREDOC_INDENT.exec(doc)) isnt null
    +        attempt = if match[2]? then match[2] else match[3]
    +        indent = attempt if not indent? or attempt.length < indent.length
    +    indent or= ''
    +    doc = doc.replace(new RegExp("^" + indent, 'gm'), '')
    +    return doc if options.herecomment
    +    doc = doc.replace(/^\n/, '')
    +    doc.replace(MULTILINER, "\\n")
    +       .replace(new RegExp(options.quote, 'g'), "\\#{options.quote}")
    #

    A source of ambiguity in our grammar used to be parameter lists in function +definitions versus argument lists in function calls. Walk backwards, tagging +parameters specially in order to make things easier for the parser.

      tagParameters: ->
    +    return if @tag() isnt ')'
    +    i = 0
    +    loop
    +      i += 1
    +      tok = @prev i
    +      return if not tok
    +      switch tok[0]
    +        when 'IDENTIFIER'       then tok[0] = 'PARAM'
    +        when ')'                then tok[0] = 'PARAM_END'
    +        when '(', 'CALL_START'  then return tok[0] = 'PARAM_START'
    +    true
    #

    Close up all remaining open blocks at the end of the file.

      closeIndentation: ->
    +    @outdentToken @indent
    #

    The error for when you try to use a forbidden word in JavaScript as +an identifier.

      identifierError: (word) ->
    +    throw new Error "SyntaxError: Reserved word \"#{word}\" on line #{@line + 1}"
    #

    The error for when you try to assign to a reserved word in JavaScript, +like "function" or "default".

      assignmentError: ->
    +    throw new Error "SyntaxError: Reserved word \"#{@value()}\" on line #{@line + 1} can't be assigned"
    #

    Matches a balanced group such as a single or double-quoted string. Pass in +a series of delimiters, all of which must be nested correctly within the +contents of the string. This method allows us to have strings within +interpolations within strings, ad infinitum.

      balancedString: (str, delimited, options) ->
    +    options or= {}
    +    slash = delimited[0][0] is '/'
    +    levels = []
    +    i = 0
    +    while i < str.length
    +      if levels.length and starts str, '\\', i
    +        i += 1
    +      else
    +        for pair in delimited
    +          [open, close] = pair
    +          if levels.length and starts(str, close, i) and levels[levels.length - 1] is pair
    +            levels.pop()
    +            i += close.length - 1
    +            i += 1 unless levels.length
    +            break
    +          else if starts str, open, i
    +            levels.push(pair)
    +            i += open.length - 1
    +            break
    +      break if not levels.length or slash and starts str, '\n', i
    +      i += 1
    +    if levels.length
    +      return false if slash
    +      throw new Error "SyntaxError: Unterminated #{levels.pop()[0]} starting on line #{@line + 1}"
    +    if not i then false else str.substring(0, i)
    #

    Expand variables and expressions inside double-quoted strings using +ECMA Harmony's interpolation syntax +for substitution of bare variables as well as arbitrary expressions.

    + +
    "Hello #{name.capitalize()}."
    +
    + +

    If it encounters an interpolation, this method will recursively create a +new Lexer, tokenize the interpolated contents, and merge them into the +token stream.

      interpolateString: (str, options) ->
    +    options or= {}
    +    if str.length < 3 or not starts str, '"'
    +      @token 'STRING', str
    +    else
    +      lexer   = new Lexer
    +      tokens  = []
    +      quote   = str.substring 0, 1
    +      [i, pi] = [1, 1]
    +      while i < str.length - 1
    +        if starts str, '\\', i
    +          i += 1
    +        else if expr = @balancedString(str.substring(i), [['#{', '}']])
    +          tokens.push ['STRING', quote + str.substring(pi, i) + quote] if pi < i
    +          inner = expr.substring(2, expr.length - 1)
    +          if inner.length
    +            inner = inner.replace new RegExp('\\\\' + quote, 'g'), quote if options.heredoc
    +            nested = lexer.tokenize "(#{inner})", line: @line
    +            (tok[0] = ')') for tok, idx in nested when tok[0] is 'CALL_END'
    +            nested.pop()
    +            tokens.push ['TOKENS', nested]
    +          else
    +            tokens.push ['STRING', quote + quote]
    +          i += expr.length - 1
    +          pi = i + 1
    +        i += 1
    +      tokens.push ['STRING', quote + str.substring(pi, i) + quote] if pi < i and pi < str.length - 1
    +      tokens.unshift ['STRING', '""'] unless tokens[0][0] is 'STRING'
    +      interpolated = tokens.length > 1
    +      @token '(', '(' if interpolated
    +      for token, i in tokens
    +        [tag, value] = token
    +        if tag is 'TOKENS'
    +          @tokens = @tokens.concat value
    +        else if tag is 'STRING' and options.escapeQuotes
    +          escaped = value.substring(1, value.length - 1).replace(/"/g, '\\"')
    +          @token tag, "\"#{escaped}\""
    +        else
    +          @token tag, value
    +        @token '+', '+' if i < tokens.length - 1
    +      @token ')', ')' if interpolated
    +      tokens
    #

    Helpers

    #

    Add a token to the results, taking note of the line number.

      token: (tag, value) ->
    +    @tokens.push [tag, value, @line]
    #

    Peek at a tag in the current token stream.

      tag: (index, newTag) ->
    +    return unless tok = @prev index
    +    return tok[0] = newTag if newTag?
    +    tok[0]
    #

    Peek at a value in the current token stream.

      value: (index, val) ->
    +    return unless tok = @prev index
    +    return tok[1] = val if val?
    +    tok[1]
    #

    Peek at a previous token, entire.

      prev: (index) ->
    +    @tokens[@tokens.length - (index or 1)]
    #

    Attempt to match a string against the current chunk, returning the indexed +match if successful, and false otherwise.

      match: (regex, index) ->
    +    return false unless m = @chunk.match regex
    +    if m then m[index] else false
    #

    Are we in the midst of an unfinished expression?

      unfinished: ->
    +    prev = @prev(2)
    +    @value() and @value().match and @value().match(NO_NEWLINE) and
    +      prev and (prev[0] isnt '.') and not @value().match(CODE) and
    +      not @chunk.match ASSIGNED
    #

    Constants

    #

    Keywords that CoffeeScript shares in common with JavaScript.

    JS_KEYWORDS = [
    +  "if", "else",
    +  "true", "false",
    +  "new", "return",
    +  "try", "catch", "finally", "throw",
    +  "break", "continue",
    +  "for", "in", "while",
    +  "delete", "instanceof", "typeof",
    +  "switch", "super", "extends", "class",
    +  "this", "null", "debugger"
    +]
    #

    CoffeeScript-only keywords, which we're more relaxed about allowing. They can't +be used standalone, but you can reference them as an attached property.

    COFFEE_ALIASES =  ["and", "or", "is", "isnt", "not"]
    +COFFEE_KEYWORDS = COFFEE_ALIASES.concat [
    +  "then", "unless", "until", "loop",
    +  "yes", "no", "on", "off",
    +  "of", "by", "where", "when"
    +]
    #

    The list of keywords that are reserved by JavaScript, but not used, or are +used by CoffeeScript internally. We throw an error when these are encountered, +to avoid having a JavaScript error at runtime.

    RESERVED = [
    +  "case", "default", "do", "function", "var", "void", "with",
    +  "const", "let", "enum", "export", "import", "native",
    +  "__hasProp", "__extends", "__slice"
    +]
    #

    The superset of both JavaScript keywords and reserved words, none of which may +be used as identifiers or properties.

    JS_FORBIDDEN = JS_KEYWORDS.concat RESERVED
    #

    Token matching regexes.

    IDENTIFIER    = /^([a-zA-Z\$_](\w|\$)*)/
    +NUMBER        = /^(((\b0(x|X)[0-9a-fA-F]+)|((\b[0-9]+(\.[0-9]+)?|\.[0-9]+)(e[+\-]?[0-9]+)?)))\b/i
    +HEREDOC       = /^("{6}|'{6}|"{3}([\s\S]*?)\n?([ \t]*)"{3}|'{3}([\s\S]*?)\n?([ \t]*)'{3})/
    +OPERATOR      = /^(-[\-=>]?|\+[+=]?|[*&|\/%=<>^:!?]+)([ \t]*)/
    +WHITESPACE    = /^([ \t]+)/
    +COMMENT       = /^(###([^#][\s\S]*?)(###[ \t]*\n|(###)?$)|(\s*#(?!##[^#])[^\n]*)+)/
    +CODE          = /^((-|=)>)/
    +MULTI_DENT    = /^((\n([ \t]*))+)(\.)?/
    +LAST_DENTS    = /\n([ \t]*)/g
    +LAST_DENT     = /\n([ \t]*)/
    #

    Regex-matching-regexes.

    REGEX_START         = /^\/([^\/])/
    +REGEX_INTERPOLATION = /([^\\]#\{.*[^\\]\})/
    +REGEX_END           = /^(([imgy]{1,4})\b|\W|$)/
    +REGEX_ESCAPE        = /\\[^\$]/g
    #

    Token cleaning regexes.

    JS_CLEANER      = /(^`|`$)/g
    +MULTILINER      = /\n/g
    +NO_NEWLINE      = /^([+\*&|\/\-%=<>!.\\][<>=&|]*|and|or|is|isnt|not|delete|typeof|instanceof)$/
    +HEREDOC_INDENT  = /(\n+([ \t]*)|^([ \t]+))/g
    +ASSIGNED        = /^\s*(([a-zA-Z\$_@]\w*|["'][^\r\n]+?["']|\d+)[ \t]*?[:=][^:=])/
    +NEXT_CHARACTER  = /^\s*(\S)/
    #

    Compound assignment tokens.

    COMPOUND_ASSIGN = ['-=', '+=', '/=', '*=', '%=', '||=', '&&=', '?=', '<<=', '>>=', '>>>=', '&=', '^=', '|=']
    #

    Unary tokens.

    UNARY   = ['UMINUS', 'UPLUS', '!', '!!', '~', 'TYPEOF', 'DELETE']
    #

    Logical tokens.

    LOGIC   = ['&', '|', '^', '&&', '||']
    #

    Bit-shifting tokens.

    SHIFT   = ['<<', '>>', '>>>']
    #

    Comparison tokens.

    COMPARE = ['<=', '<', '>', '>=']
    #

    Mathmatical tokens.

    MATH    = ['*', '/', '%']
    #

    Tokens which a regular expression will never immediately follow, but which +a division operator might.

    + +

    See: http://www.mozilla.org/js/language/js20-2002-04/rationale/syntax.html#regular-expressions

    + +

    Our list is shorter, due to sans-parentheses method calls.

    NOT_REGEX = ['NUMBER', 'REGEX', '++', '--', 'FALSE', 'NULL', 'TRUE', ']']
    #

    Tokens which could legitimately be invoked or indexed. A opening +parentheses or bracket following these tokens will be recorded as the start +of a function invocation or indexing operation.

    CALLABLE = ['IDENTIFIER', 'SUPER', ')', ']', '}', 'STRING', '@', 'THIS', '?', '::']
    #

    Tokens that, when immediately preceding a WHEN, indicate that the WHEN +occurs at the start of a line. We disambiguate these from trailing whens to +avoid an ambiguity in the grammar.

    LINE_BREAK = ['INDENT', 'OUTDENT', 'TERMINATOR']
    #

    Conversions from CoffeeScript operators into JavaScript ones.

    CONVERSIONS =
    +  'and':  '&&'
    +  'or':   '||'
    +  'is':   '=='
    +  'isnt': '!='
    +  'not':  '!'
    +  '===':  '=='
    +
    +
    \ No newline at end of file diff --git a/node_modules/jade/support/coffee-script/documentation/docs/nodes.html b/node_modules/jade/support/coffee-script/documentation/docs/nodes.html new file mode 100644 index 0000000..181e035 --- /dev/null +++ b/node_modules/jade/support/coffee-script/documentation/docs/nodes.html @@ -0,0 +1,1245 @@ + nodes.coffee

    nodes.coffee

    #

    nodes.coffee contains all of the node classes for the syntax tree. Most +nodes are created as the result of actions in the grammar, +but some are created by other nodes as a method of code generation. To convert +the syntax tree into a string of JavaScript code, call compile() on the root.

    {Scope} = require './scope'
    #

    Import the helpers we plan to use.

    {compact, flatten, merge, del, include, indexOf, starts, ends} = require('./helpers').helpers
    #

    BaseNode

    #

    The BaseNode is the abstract base class for all nodes in the syntax tree. +Each subclass implements the compileNode method, which performs the +code generation for that node. To compile a node to JavaScript, +call compile on it, which wraps compileNode in some generic extra smarts, +to know when the generated code needs to be wrapped up in a closure. +An options hash is passed and cloned throughout, containing information about +the environment from higher in the tree (such as if a returned value is +being requested by the surrounding function), information about the current +scope, and indentation level.

    exports.BaseNode = class BaseNode
    +
    +  constructor: ->
    +    @tags = {}
    #

    Common logic for determining whether to wrap this node in a closure before +compiling it, or to compile directly. We need to wrap if this node is a +statement, and it's not a pureStatement, and we're not at +the top level of a block (which would be unnecessary), and we haven't +already been asked to return the result (because statements know how to +return results).

    + +

    If a Node is topSensitive, that means that it needs to compile differently +depending on whether it's being used as part of a larger expression, or is a +top-level statement within the function body.

      compile: (o) ->
    +    @options = merge o or {}
    +    @tab     = o.indent
    +    del @options, 'chainRoot' unless this instanceof AccessorNode or this instanceof IndexNode
    +    top     = if @topSensitive() then @options.top else del @options, 'top'
    +    closure = @isStatement(o) and not @isPureStatement() and not top and
    +              not @options.asStatement and this not instanceof CommentNode and
    +              not @containsPureStatement()
    +    o.scope.startLevel() if not o.keepLevel
    +    code = if closure then @compileClosure(@options) else @compileNode(@options)
    +    o.scope.endLevel() if not o.keepLevel
    +    code
    #

    Statements converted into expressions via closure-wrapping share a scope +object with their parent closure, to preserve the expected lexical scope.

      compileClosure: (o) ->
    +    @tab = o.indent
    +    o.sharedScope = o.scope
    +    ClosureNode.wrap(this).compile o
    #

    If the code generation wishes to use the result of a complex expression +in multiple places, ensure that the expression is only ever evaluated once, +by assigning it to a temporary variable.

      compileReference: (o, options) ->
    +    options or= {}
    +    pair = if not (@containsType(CallNode) or
    +                  (this instanceof ValueNode and (not (@base instanceof LiteralNode) or @hasProperties())))
    +      [this, this]
    +    else if this instanceof ValueNode and options.assignment
    +      this.cacheIndexes(o)
    +    else
    +      reference = literal o.scope.freeVariable 'ref'
    +      compiled  = new AssignNode reference, this
    +      [compiled, reference]
    +    return [pair[0].compile(o), pair[1].compile(o)] if options.precompile
    +    pair
    #

    Convenience method to grab the current indentation level, plus tabbing in.

      idt: (tabs) ->
    +    idt = @tab or ''
    +    num = (tabs or 0) + 1
    +    idt += TAB while num -= 1
    +    idt
    #

    Construct a node that returns the current node's result. +Note that this is overridden for smarter behavior for +many statement nodes (eg IfNode, ForNode)...

      makeReturn: ->
    +    new ReturnNode this
    #

    Does this node, or any of its children, contain a node of a certain kind? +Recursively traverses down the children of the nodes, yielding to a block +and returning true when the block finds a match. contains does not cross +scope boundaries.

      contains: (block) ->
    +    contains = false
    +    @traverseChildren false, (node) ->
    +      if block(node)
    +        contains = true
    +        return false
    +    contains
    #

    Is this node of a certain type, or does it contain the type?

      containsType: (type) ->
    +    this instanceof type or @contains (n) -> n instanceof type
    #

    Convenience for the most common use of contains. Does the node contain +a pure statement?

      containsPureStatement: ->
    +    @isPureStatement() or @contains (n) -> n.isPureStatement and n.isPureStatement()
    #

    Perform an in-order traversal of the AST. Crosses scope boundaries.

      traverse: (block) -> @traverseChildren true, block
    #

    toString representation of the node, for inspecting the parse tree. +This is what coffee --nodes prints out.

      toString: (idt, override) ->
    +    idt or= ''
    +    children = (child.toString idt + TAB for child in @collectChildren()).join('')
    +    '\n' + idt + (override or @class) + children
    +
    +  eachChild: (func) ->
    +    return unless @children
    +    for attr in @children when this[attr]
    +      for child in flatten [this[attr]]
    +        return if func(child) is false
    +
    +  collectChildren: ->
    +    nodes = []
    +    @eachChild (node) -> nodes.push node
    +    nodes
    +
    +  traverseChildren: (crossScope, func) ->
    +    @eachChild (child) ->
    +      func.apply(this, arguments)
    +      child.traverseChildren(crossScope, func) if child instanceof BaseNode
    #

    Default implementations of the common node properties and methods. Nodes +will override these with custom logic, if needed.

      class:    'BaseNode'
    +  children: []
    +
    +  unwrap          : -> this
    +  isStatement     : -> no
    +  isPureStatement : -> no
    +  topSensitive    : -> no
    #

    Expressions

    #

    The expressions body is the list of expressions that forms the body of an +indented block of code -- the implementation of a function, a clause in an +if, switch, or try, and so on...

    exports.Expressions = class Expressions extends BaseNode
    +
    +  class:        'Expressions'
    +  children:     ['expressions']
    +  isStatement:  -> yes
    +
    +  constructor: (nodes) ->
    +    super()
    +    @expressions = compact flatten nodes or []
    #

    Tack an expression on to the end of this expression list.

      push: (node) ->
    +    @expressions.push(node)
    +    this
    #

    Add an expression at the beginning of this expression list.

      unshift: (node) ->
    +    @expressions.unshift(node)
    +    this
    #

    If this Expressions consists of just a single node, unwrap it by pulling +it back out.

      unwrap: ->
    +    if @expressions.length is 1 then @expressions[0] else this
    #

    Is this an empty block of code?

      empty: ->
    +    @expressions.length is 0
    #

    An Expressions node does not return its entire body, rather it +ensures that the final expression is returned.

      makeReturn: ->
    +    idx  = @expressions.length - 1
    +    last = @expressions[idx]
    +    last = @expressions[idx -= 1] if last instanceof CommentNode
    +    return this if not last or last instanceof ReturnNode
    +    @expressions[idx] = last.makeReturn()
    +    this
    #

    An Expressions is the only node that can serve as the root.

      compile: (o) ->
    +    o or= {}
    +    if o.scope then super(o) else @compileRoot(o)
    +
    +  compileNode: (o) ->
    +    (@compileExpression(node, merge(o)) for node in @expressions).join("\n")
    #

    If we happen to be the top-level Expressions, wrap everything in +a safety closure, unless requested not to. +It would be better not to generate them in the first place, but for now, +clean up obvious double-parentheses.

      compileRoot: (o) ->
    +    o.indent  = @tab = if o.noWrap then '' else TAB
    +    o.scope   = new Scope(null, this, null)
    +    code      = @compileWithDeclarations(o)
    +    code      = code.replace(TRAILING_WHITESPACE, '')
    +    if o.noWrap then code else "(function() {\n#{code}\n}).call(this);\n"
    #

    Compile the expressions body for the contents of a function, with +declarations of all inner variables pushed up to the top.

      compileWithDeclarations: (o) ->
    +    code = @compileNode(o)
    +    code = "#{@tab}var #{o.scope.compiledAssignments()};\n#{code}"  if o.scope.hasAssignments(this)
    +    code = "#{@tab}var #{o.scope.compiledDeclarations()};\n#{code}" if not o.globals and o.scope.hasDeclarations(this)
    +    code
    #

    Compiles a single expression within the expressions body. If we need to +return the result, and it's an expression, simply return it. If it's a +statement, ask the statement to do so.

      compileExpression: (node, o) ->
    +    @tab = o.indent
    +    compiledNode = node.compile merge o, top: true
    +    if node.isStatement(o) then compiledNode else "#{@idt()}#{compiledNode};"
    #

    Wrap up the given nodes as an Expressions, unless it already happens +to be one.

    Expressions.wrap = (nodes) ->
    +  return nodes[0] if nodes.length is 1 and nodes[0] instanceof Expressions
    +  new Expressions(nodes)
    #

    LiteralNode

    #

    Literals are static values that can be passed through directly into +JavaScript without translation, such as: strings, numbers, +true, false, null...

    exports.LiteralNode = class LiteralNode extends BaseNode
    +
    +  class: 'LiteralNode'
    +
    +  constructor: (@value) ->
    +    super()
    +
    +  makeReturn: ->
    +    if @isStatement() then this else super()
    #

    Break and continue must be treated as pure statements -- they lose their +meaning when wrapped in a closure.

      isStatement: ->
    +    @value is 'break' or @value is 'continue' or @value is 'debugger'
    +  isPureStatement: LiteralNode::isStatement
    +
    +  compileNode: (o) ->
    +    idt = if @isStatement(o) then @idt() else ''
    +    end = if @isStatement(o) then ';' else ''
    +    idt + @value + end
    +
    +  toString: (idt) ->
    +    '"' + @value + '"'
    #

    ReturnNode

    #

    A return is a pureStatement -- wrapping it in a closure wouldn't +make sense.

    exports.ReturnNode = class ReturnNode extends BaseNode
    +
    +  class:            'ReturnNode'
    +  isStatement:      -> yes
    +  isPureStatement:  -> yes
    +  children:         ['expression']
    +
    +  constructor: (@expression) ->
    +    super()
    +
    +  makeReturn: ->
    +    this
    +
    +  compile: (o) ->
    +    expr = @expression.makeReturn()
    +    return expr.compile o unless expr instanceof ReturnNode
    +    super o
    +
    +  compileNode: (o) ->
    +    o.asStatement = true if @expression.isStatement(o)
    +    "#{@tab}return #{@expression.compile(o)};"
    #

    ValueNode

    #

    A value, variable or literal or parenthesized, indexed or dotted into, +or vanilla.

    exports.ValueNode = class ValueNode extends BaseNode
    +
    +  class:     'ValueNode'
    +  children: ['base', 'properties']
    #

    A ValueNode has a base and a list of property accesses.

      constructor: (@base, @properties) ->
    +    super()
    +    @properties or= []
    #

    Add a property access to the list.

      push: (prop) ->
    +    @properties.push(prop)
    +    this
    +
    +  hasProperties: ->
    +    !!@properties.length
    #

    Some boolean checks for the benefit of other nodes.

      isArray: ->
    +    @base instanceof ArrayNode and not @hasProperties()
    +
    +  isObject: ->
    +    @base instanceof ObjectNode and not @hasProperties()
    +
    +  isSplice: ->
    +    @hasProperties() and @properties[@properties.length - 1] instanceof SliceNode
    +
    +  makeReturn: ->
    +    if @hasProperties() then super() else @base.makeReturn()
    #

    The value can be unwrapped as its inner node, if there are no attached +properties.

      unwrap: ->
    +    if @properties.length then this else @base
    #

    Values are considered to be statements if their base is a statement.

      isStatement: (o) ->
    +    @base.isStatement and @base.isStatement(o) and not @hasProperties()
    +
    +  isNumber: ->
    +    @base instanceof LiteralNode and @base.value.match NUMBER
    #

    If the value node has indexes containing function calls, and the value node +needs to be used twice, in compound assignment ... then we need to cache +the value of the indexes.

      cacheIndexes: (o) ->
    +    copy = new ValueNode @base, @properties[0..]
    +    if @base instanceof CallNode
    +      [@base, copy.base] = @base.compileReference o
    +    for prop, i in copy.properties
    +      if prop instanceof IndexNode and prop.contains((n) -> n instanceof CallNode)
    +        [index, indexVar] = prop.index.compileReference o
    +        this.properties[i] = new IndexNode index
    +        copy.properties[i] = new IndexNode indexVar
    +    [this, copy]
    #

    Override compile to unwrap the value when possible.

      compile: (o) ->
    +    if not o.top or @properties.length then super(o) else @base.compile(o)
    #

    We compile a value to JavaScript by compiling and joining each property. +Things get much more insteresting if the chain of properties has soak +operators ?. interspersed. Then we have to take care not to accidentally +evaluate a anything twice when building the soak chain.

      compileNode: (o) ->
    +    only        = del o, 'onlyFirst'
    +    op          = @tags.operation
    +    props       = if only then @properties[0...@properties.length - 1] else @properties
    +    o.chainRoot or= this
    +    for prop in props
    +      hasSoak = yes if prop.soakNode
    +    if hasSoak and @containsType CallNode
    +      [me, copy] = @cacheIndexes o
    +    @base.parenthetical = yes if @parenthetical and not props.length
    +    baseline    = @base.compile o
    +    baseline    = "(#{baseline})" if @hasProperties() and (@base instanceof ObjectNode or @isNumber())
    +    complete    = @last = baseline
    +
    +    for prop, i in props
    +      @source = baseline
    +      if prop.soakNode
    +        if @base.containsType(CallNode) and i is 0
    +          temp = o.scope.freeVariable 'ref'
    +          complete = "(#{ baseline = temp } = (#{complete}))"
    +        complete = if i is 0
    +          "(typeof #{complete} === \"undefined\" || #{baseline} === null) ? undefined : "
    +        else
    +          "#{complete} == null ? undefined : "
    +        complete += (baseline += prop.compile(o))
    +      else
    +        part = prop.compile(o)
    +        if hasSoak and prop.containsType CallNode
    +          baseline += copy.properties[i].compile o
    +        else
    +          baseline += part
    +        complete += part
    +        @last = part
    +
    +    if op and @wrapped then "(#{complete})" else complete
    #

    CommentNode

    #

    CoffeeScript passes through block comments as JavaScript block comments +at the same position.

    exports.CommentNode = class CommentNode extends BaseNode
    +
    +  class: 'CommentNode'
    +  isStatement: -> yes
    +
    +  constructor: (@comment) ->
    +    super()
    +
    +  makeReturn: ->
    +    this
    +
    +  compileNode: (o) ->
    +    @tab + '/*' + @comment.replace(/\r?\n/g, '\n' + @tab) + '*/'
    #

    CallNode

    #

    Node for a function invocation. Takes care of converting super() calls into +calls against the prototype's function of the same name.

    exports.CallNode = class CallNode extends BaseNode
    +
    +  class:     'CallNode'
    +  children: ['variable', 'args']
    +
    +  constructor: (variable, @args, @exist) ->
    +    super()
    +    @isNew    = false
    +    @isSuper  = variable is 'super'
    +    @variable = if @isSuper then null else variable
    +    @args     or= []
    +    @first = @last = ''
    +    @compileSplatArguments = (o) ->
    +      SplatNode.compileSplattedArray.call(this, @args, o)
    #

    Tag this invocation as creating a new instance.

      newInstance: ->
    +    @isNew = true
    +    this
    +
    +  prefix: ->
    +    if @isNew then 'new ' else ''
    #

    Grab the reference to the superclass' implementation of the current method.

      superReference: (o) ->
    +    throw new Error "cannot call super outside of a function" unless o.scope.method
    +    methname = o.scope.method.name
    +    meth = if o.scope.method.proto
    +      "#{o.scope.method.proto}.__super__.#{methname}"
    +    else if methname
    +      "#{methname}.__super__.constructor"
    +    else throw new Error "cannot call super on an anonymous function."
    #

    Compile a vanilla function call.

      compileNode: (o) ->
    +    o.chainRoot = this unless o.chainRoot
    +    op = @tags.operation
    +    if @exist
    +      if @variable instanceof ValueNode and @variable.properties[@variable.properties.length - 1] instanceof AccessorNode
    +        methodAccessor = @variable.properties.pop()
    +        [first, meth] = @variable.compileReference o
    +        @first = new ValueNode(first, [methodAccessor]).compile o
    +        @meth = new ValueNode(meth, [methodAccessor]).compile o
    +      else
    +        [@first, @meth] = @variable.compileReference o, precompile: yes
    +      @first = "(typeof #{@first} === \"function\" ? "
    +      @last  = " : undefined)"
    +    else if @variable
    +      @meth = @variable.compile o
    +    for arg in @args when arg instanceof SplatNode
    +      code = @compileSplat(o)
    +    if not code
    +      args = for arg in @args
    +        arg.parenthetical = true
    +        arg.compile o
    +      code = if @isSuper
    +        @compileSuper(args.join(', '), o)
    +      else
    +        "#{@first}#{@prefix()}#{@meth}(#{ args.join(', ') })#{@last}"
    +    if op and @variable and @variable.wrapped then "(#{code})" else code
    #

    super() is converted into a call against the superclass's implementation +of the current function.

      compileSuper: (args, o) ->
    +    "#{@superReference(o)}.call(this#{ if args.length then ', ' else '' }#{args})"
    #

    If you call a function with a splat, it's converted into a JavaScript +.apply() call to allow an array of arguments to be passed. +If it's a constructor, then things get real tricky. We have to inject an +inner constructor in order to be able to pass the varargs.

      compileSplat: (o) ->
    +    meth = @meth or @superReference(o)
    +    obj  = @variable and @variable.source or 'this'
    +    if obj.match(/\(/)
    +      temp = o.scope.freeVariable 'ref'
    +      obj  = temp
    +      meth = "(#{temp} = #{ @variable.source })#{ @variable.last }"
    +    if @isNew
    +      mentionsArgs = no
    +      for arg in @args
    +        arg.contains (n) -> mentionsArgs or= n instanceof LiteralNode and (n.value is 'arguments')
    +      utility 'extends'
    +      a = o.scope.freeVariable 'ctor'
    +      b = o.scope.freeVariable 'ref'
    +      c = o.scope.freeVariable 'result'
    +      """
    +
    +#DIVIDER
    +      """
    +    else
    +      "#{@first}#{@prefix()}#{meth}.apply(#{obj}, #{ @compileSplatArguments(o) })#{@last}"
    #

    {@first}(function() { +{@idt(1)}var ctor = function(){}; +{@idt(1)}__extends(ctor, #{a} = #{meth}); +{@idt(1)}return typeof (#{c} = #{a}.apply(#{b} = new ctor, #{ @compileSplatArguments(o) })) === "object" ? #{c} : #{b}; +{@tab}}).#{ if mentionsArgs then 'apply(this, arguments)' else 'call(this)'}#{@last}

    #

    ExtendsNode

    exports.ExtendsNode = class ExtendsNode extends BaseNode
    +
    +  class:     'ExtendsNode'
    +  children: ['child', 'parent']
    +
    +  constructor: (@child, @parent) ->
    +    super()
    #

    Node to extend an object's prototype with an ancestor object. +After goog.inherits from the +Closure Library.

      compileNode: (o) ->
    +    ref =  new ValueNode literal utility 'extends'
    +    (new CallNode ref, [@child, @parent]).compile o
    #

    Hooks one constructor into another's prototype chain.

    #

    AccessorNode

    exports.AccessorNode = class AccessorNode extends BaseNode
    +
    +  class:     'AccessorNode'
    +  children: ['name']
    +
    +  constructor: (@name, tag) ->
    +    super()
    +    @prototype = if tag is 'prototype' then '.prototype' else ''
    +    @soakNode = tag is 'soak'
    +
    +  compileNode: (o) ->
    +    name = @name.compile o
    +    o.chainRoot.wrapped or= @soakNode
    +    namePart = if name.match(IS_STRING) then "[#{name}]" else ".#{name}"
    +    @prototype + namePart
    #

    A . accessor into a property of a value, or the :: shorthand for +an accessor into the object's prototype.

    #

    IndexNode

    exports.IndexNode = class IndexNode extends BaseNode
    +
    +  class:     'IndexNode'
    +  children: ['index']
    +
    +  constructor: (@index) ->
    +    super()
    +
    +  compileNode: (o) ->
    +    o.chainRoot.wrapped or= @soakNode
    +    idx = @index.compile o
    +    prefix = if @proto then '.prototype' else ''
    +    "#{prefix}[#{idx}]"
    #

    A [ ... ] indexed accessor into an array or object.

    #

    RangeNode

    exports.RangeNode = class RangeNode extends BaseNode
    +
    +  class:     'RangeNode'
    +  children: ['from', 'to']
    +
    +  constructor: (@from, @to, tag) ->
    +    super()
    +    @exclusive = tag is 'exclusive'
    +    @equals = if @exclusive then '' else '='
    #

    A range literal. Ranges can be used to extract portions (slices) of arrays, +to specify a range for comprehensions, or as a value, to be expanded into the +corresponding array of integers at runtime.

      compileVariables: (o) ->
    +    o = merge(o, top: true)
    +    [@from, @fromVar] =  @from.compileReference o, precompile: yes
    +    [@to, @toVar] =      @to.compileReference o, precompile: yes
    +    [@fromNum, @toNum] = [@fromVar.match(SIMPLENUM), @toVar.match(SIMPLENUM)]
    +    parts = []
    +    parts.push @from if @from isnt @fromVar
    +    parts.push @to if @to isnt @toVar
    +    if parts.length then "#{parts.join('; ')}; " else ''
    #

    Compiles the range's source variables -- where it starts and where it ends. +But only if they need to be cached to avoid double evaluation.

      compileNode: (o) ->
    +    return    @compileArray(o)  unless o.index
    +    return    @compileSimple(o) if @fromNum and @toNum
    +    idx      = del o, 'index'
    +    step     = del o, 'step'
    +    vars     = "#{idx} = #{@fromVar}"
    +    intro    = "(#{@fromVar} <= #{@toVar} ? #{idx}"
    +    compare  = "#{intro} <#{@equals} #{@toVar} : #{idx} >#{@equals} #{@toVar})"
    +    stepPart = if step then step.compile(o) else '1'
    +    incr     = if step then "#{idx} += #{stepPart}" else "#{intro} += #{stepPart} : #{idx} -= #{stepPart})"
    +    "#{vars}; #{compare}; #{incr}"
    #

    When compiled normally, the range returns the contents of the for loop +needed to iterate over the values in the range. Used by comprehensions.

      compileSimple: (o) ->
    +    [from, to] = [parseInt(@fromNum, 10), parseInt(@toNum, 10)]
    +    idx        = del o, 'index'
    +    step       = del o, 'step'
    +    step       and= "#{idx} += #{step.compile(o)}"
    +    if from <= to
    +      "#{idx} = #{from}; #{idx} <#{@equals} #{to}; #{step or "#{idx}++"}"
    +    else
    +      "#{idx} = #{from}; #{idx} >#{@equals} #{to}; #{step or "#{idx}--"}"
    #

    Compile a simple range comprehension, with integers.

      compileArray: (o) ->
    +    idt    = @idt 1
    +    vars   = @compileVariables merge o, indent: idt
    +    if @fromNum and @toNum and Math.abs(+@fromNum - +@toNum) <= 20
    +      range = [+@fromNum..+@toNum]
    +      range.pop() if @exclusive
    +      return "[#{ range.join(', ') }]"
    +    i = o.scope.freeVariable 'i'
    +    result = o.scope.freeVariable 'result'
    +    pre    = "\n#{idt}#{result} = []; #{vars}"
    +    if @fromNum and @toNum
    +      o.index = i
    +      body = @compileSimple o
    +    else
    +      clause = "#{@fromVar} <= #{@toVar} ?"
    +      body   = "var #{i} = #{@fromVar}; #{clause} #{i} <#{@equals} #{@toVar} : #{i} >#{@equals} #{@toVar}; #{clause} #{i} += 1 : #{i} -= 1"
    +    post   = "{ #{result}.push(#{i}); }\n#{idt}return #{result};\n#{o.indent}"
    +    "(function() {#{pre}\n#{idt}for (#{body})#{post}}).call(this)"
    #

    When used as a value, expand the range into the equivalent array.

    #

    SliceNode

    exports.SliceNode = class SliceNode extends BaseNode
    +
    +  class:     'SliceNode'
    +  children: ['range']
    +
    +  constructor: (@range) ->
    +    super()
    +
    +  compileNode: (o) ->
    +    from  =  if @range.from then @range.from.compile(o) else '0'
    +    to    =  if @range.to then @range.to.compile(o) else ''
    +    to    += if not to or @range.exclusive then '' else ' + 1'
    +    to    =  ', ' + to if to
    +    ".slice(#{from}#{to})"
    #

    An array slice literal. Unlike JavaScript's Array#slice, the second parameter +specifies the index of the end of the slice, just as the first parameter +is the index of the beginning.

    #

    ObjectNode

    exports.ObjectNode = class ObjectNode extends BaseNode
    +
    +  class:     'ObjectNode'
    +  children: ['properties']
    +
    +  topSensitive: -> true
    +
    +  constructor: (props) ->
    +    super()
    +    @objects = @properties = props or []
    +
    +  compileNode: (o) ->
    +    top = del o, 'top'
    +    o.indent = @idt 1
    +    nonComments = prop for prop in @properties when (prop not instanceof CommentNode)
    +    lastNoncom =  nonComments[nonComments.length - 1]
    +    props = for prop, i in @properties
    +      join   = ",\n"
    +      join   = "\n" if (prop is lastNoncom) or (prop instanceof CommentNode)
    +      join   = '' if i is @properties.length - 1
    +      indent = if prop instanceof CommentNode then '' else @idt 1
    +      prop   = new AssignNode prop, prop, 'object' unless prop instanceof AssignNode or prop instanceof CommentNode
    +      indent + prop.compile(o) + join
    +    props = props.join('')
    +    obj   = '{' + (if props then '\n' + props + '\n' + @idt() else '') + '}'
    +    if top then "(#{obj})" else obj
    #

    An object literal, nothing fancy.

    #

    ArrayNode

    exports.ArrayNode = class ArrayNode extends BaseNode
    +
    +  class:     'ArrayNode'
    +  children: ['objects']
    +
    +  constructor: (@objects) ->
    +    super()
    +    @objects or= []
    +    @compileSplatLiteral = (o) ->
    +      SplatNode.compileSplattedArray.call(this, @objects, o)
    +
    +  compileNode: (o) ->
    +    o.indent = @idt 1
    +    objects = []
    +    for obj, i in @objects
    +      code = obj.compile(o)
    +      if obj instanceof SplatNode
    +        return @compileSplatLiteral o
    +      else if obj instanceof CommentNode
    +        objects.push "\n#{code}\n#{o.indent}"
    +      else if i is @objects.length - 1
    +        objects.push code
    +      else
    +        objects.push "#{code}, "
    +    objects = objects.join('')
    +    if indexOf(objects, '\n') >= 0
    +      "[\n#{@idt(1)}#{objects}\n#{@tab}]"
    +    else
    +      "[#{objects}]"
    #

    An array literal.

    #

    ClassNode

    exports.ClassNode = class ClassNode extends BaseNode
    +
    +  class:        'ClassNode'
    +  children:     ['variable', 'parent', 'properties']
    +  isStatement:  -> yes
    #

    The CoffeeScript class definition.

      constructor: (@variable, @parent, @properties) ->
    +    super()
    +    @properties or= []
    +    @returns    = false
    +
    +  makeReturn: ->
    +    @returns = true
    +    this
    #

    Initialize a ClassNode with its name, an optional superclass, and a +list of prototype property assignments.

      compileNode: (o) ->
    +    @variable  = literal o.scope.freeVariable 'ctor' if @variable is '__temp__'
    +    extension  = @parent and new ExtendsNode(@variable, @parent)
    +    props      = new Expressions
    +    o.top      = true
    +    me         = null
    +    className  = @variable.compile o
    +    constScope = null
    +
    +    if @parent
    +      applied = new ValueNode(@parent, [new AccessorNode(literal('apply'))])
    +      constructor = new CodeNode([], new Expressions([
    +        new CallNode(applied, [literal('this'), literal('arguments')])
    +      ]))
    +    else
    +      constructor = new CodeNode
    +
    +    for prop in @properties
    +      [pvar, func] = [prop.variable, prop.value]
    +      if pvar and pvar.base.value is 'constructor' and func instanceof CodeNode
    +        throw new Error "cannot define a constructor as a bound function." if func.bound
    +        func.name = className
    +        func.body.push new ReturnNode literal 'this'
    +        @variable = new ValueNode @variable
    +        @variable.namespaced = include func.name, '.'
    +        constructor = func
    +        continue
    +      if func instanceof CodeNode and func.bound
    +        if prop.context is 'this'
    +          func.context = className
    +        else
    +          func.bound = false
    +          constScope or= new Scope(o.scope, constructor.body, constructor)
    +          me or= constScope.freeVariable 'this'
    +          pname = pvar.compile(o)
    +          constructor.body.push    new ReturnNode literal 'this' if constructor.body.empty()
    +          constructor.body.unshift literal "this.#{pname} = function(){ return #{className}.prototype.#{pname}.apply(#{me}, arguments); }"
    +      if pvar
    +        access = if prop.context is 'this' then pvar.base.properties[0] else new AccessorNode(pvar, 'prototype')
    +        val    = new ValueNode(@variable, [access])
    +        prop   = new AssignNode(val, func)
    +      props.push prop
    +
    +    constructor.body.unshift literal "#{me} = this" if me
    +    construct = @idt() + (new AssignNode(@variable, constructor)).compile(merge o, {sharedScope: constScope}) + ';'
    +    props     = if !props.empty() then '\n' + props.compile(o)                     else ''
    +    extension = if extension      then '\n' + @idt() + extension.compile(o) + ';'  else ''
    +    returns   = if @returns       then '\n' + new ReturnNode(@variable).compile(o) else ''
    +    construct + extension + props + returns
    #

    Instead of generating the JavaScript string directly, we build up the +equivalent syntax tree and compile that, in pieces. You can see the +constructor, property assignments, and inheritance getting built out below.

    #

    AssignNode

    exports.AssignNode = class AssignNode extends BaseNode
    #

    The AssignNode is used to assign a local variable to value, or to set the +property of an object -- including within object literals.

      PROTO_ASSIGN: /^(\S+)\.prototype/
    +  LEADING_DOT:  /^\.(prototype\.)?/
    +
    +  class:     'AssignNode'
    +  children: ['variable', 'value']
    +
    +  constructor: (@variable, @value, @context) ->
    +    super()
    +
    +  topSensitive: ->
    +    true
    +
    +  isValue: ->
    +    @variable instanceof ValueNode
    +
    +  makeReturn: ->
    +    if @isStatement()
    +      return new Expressions [this, new ReturnNode(@variable)]
    +    else
    +      super()
    +
    +  isStatement: ->
    +    @isValue() and (@variable.isArray() or @variable.isObject())
    #

    Matchers for detecting prototype assignments.

      compileNode: (o) ->
    +    top    = del o, 'top'
    +    return   @compilePatternMatch(o) if @isStatement(o)
    +    return   @compileSplice(o) if @isValue() and @variable.isSplice()
    +    stmt   = del o, 'asStatement'
    +    name   = @variable.compile(o)
    +    last   = if @isValue() then @variable.last.replace(@LEADING_DOT, '') else name
    +    match  = name.match(@PROTO_ASSIGN)
    +    proto  = match and match[1]
    +    if @value instanceof CodeNode
    +      @value.name =  last  if last.match(IDENTIFIER)
    +      @value.proto = proto if proto
    +    val = @value.compile o
    +    return "#{name}: #{val}" if @context is 'object'
    +    o.scope.find name unless @isValue() and (@variable.hasProperties() or @variable.namespaced)
    +    val = "#{name} = #{val}"
    +    return "#{@tab}#{val};" if stmt
    +    if top or @parenthetical then val else "(#{val})"
    #

    Compile an assignment, delegating to compilePatternMatch or +compileSplice if appropriate. Keep track of the name of the base object +we've been assigned to, for correct internal references. If the variable +has not been seen yet within the current scope, declare it.

      compilePatternMatch: (o) ->
    +    valVar        = o.scope.freeVariable 'ref'
    +    value         = if @value.isStatement(o) then ClosureNode.wrap(@value) else @value
    +    assigns       = ["#{@tab}#{valVar} = #{ value.compile(o) };"]
    +    o.top         = true
    +    o.asStatement = true
    +    splat         = false
    +    for obj, i in @variable.base.objects
    #

    Brief implementation of recursive pattern matching, when assigning array or +object literals to a value. Peeks at their properties to assign inner names. +See the ECMAScript Harmony Wiki +for details.

          idx = i
    +      if @variable.isObject()
    +        if obj instanceof AssignNode
    #

    A regular array pattern-match.

              [obj, idx] = [obj.value, obj.variable.base]
    +        else
    #

    A regular object pattern-match.

              idx = obj
    +      if not (obj instanceof ValueNode or obj instanceof SplatNode)
    +        throw new Error 'pattern matching must use only identifiers on the left-hand side.'
    +      isString = idx.value and idx.value.match IS_STRING
    +      accessClass = if isString or @variable.isArray() then IndexNode else AccessorNode
    +      if obj instanceof SplatNode and not splat
    +        val = literal obj.compileValue o, valVar,
    +          (oindex = indexOf(@variable.base.objects, obj)),
    +          (olength = @variable.base.objects.length) - oindex - 1
    +        splat = true
    +      else
    +        idx = literal(if splat then "#{valVar}.length - #{olength - idx}" else idx) if typeof idx isnt 'object'
    +        val = new ValueNode(literal(valVar), [new accessClass(idx)])
    +      assigns.push(new AssignNode(obj, val).compile(o))
    +    code = assigns.join("\n")
    +    code
    #

    A shorthand {a, b, c} = val pattern-match.

      compileSplice: (o) ->
    +    name  = @variable.compile merge o, onlyFirst: true
    +    l     = @variable.properties.length
    +    range = @variable.properties[l - 1].range
    +    plus  = if range.exclusive then '' else ' + 1'
    +    from  = if range.from then range.from.compile(o) else '0'
    +    to    = if range.to then range.to.compile(o) + ' - ' + from + plus else "#{name}.length"
    +    val   = @value.compile(o)
    +    "#{name}.splice.apply(#{name}, [#{from}, #{to}].concat(#{val}))"
    #

    Compile the assignment from an array splice literal, using JavaScript's +Array#splice method.

    #

    CodeNode

    exports.CodeNode = class CodeNode extends BaseNode
    +
    +  class:     'CodeNode'
    +  children: ['params', 'body']
    +
    +  constructor: (@params, @body, tag) ->
    +    super()
    +    @params   or= []
    +    @body     or= new Expressions
    +    @bound    = tag is 'boundfunc'
    +    @context  = 'this' if @bound
    #

    A function definition. This is the only node that creates a new Scope. +When for the purposes of walking the contents of a function body, the CodeNode +has no children -- they're within the inner scope.

      compileNode: (o) ->
    +    sharedScope = del o, 'sharedScope'
    +    top         = del o, 'top'
    +    o.scope     = sharedScope or new Scope(o.scope, @body, this)
    +    o.top       = true
    +    o.indent    = @idt(1)
    +    empty       = @body.expressions.length is 0
    +    del o, 'noWrap'
    +    del o, 'globals'
    +    splat = undefined
    +    params = []
    +    for param, i in @params
    +      if splat
    +        if param.attach
    +          param.assign = new AssignNode new ValueNode literal('this'), [new AccessorNode param.value]
    +          @body.expressions.splice splat.index + 1, 0, param.assign
    +        splat.trailings.push param
    +      else
    +        if param.attach
    +          {value} = param
    +          [param, param.splat] = [literal(o.scope.freeVariable 'arg'), param.splat]
    +          @body.unshift new AssignNode new ValueNode(literal('this'), [new AccessorNode value]), param
    +        if param.splat
    +          splat           = new SplatNode param.value
    +          splat.index     = i
    +          splat.trailings = []
    +          splat.arglength = @params.length
    +          @body.unshift(splat)
    +        else
    +          params.push param
    +    params = (param.compile(o) for param in params)
    +    @body.makeReturn() unless empty
    +    (o.scope.parameter(param)) for param in params
    +    code = if @body.expressions.length then "\n#{ @body.compileWithDeclarations(o) }\n" else ''
    +    func = "function(#{ params.join(', ') }) {#{code}#{ code and @tab }}"
    +    return "#{utility('bind')}(#{func}, #{@context})" if @bound
    +    if top then "(#{func})" else func
    +
    +  topSensitive: ->
    +    true
    #

    Compilation creates a new scope unless explicitly asked to share with the +outer scope. Handles splat parameters in the parameter list by peeking at +the JavaScript arguments objects. If the function is bound with the => +arrow, generates a wrapper that saves the current value of this through +a closure.

      traverseChildren: (crossScope, func) -> super(crossScope, func) if crossScope
    +
    +  toString: (idt) ->
    +    idt or= ''
    +    children = (child.toString(idt + TAB) for child in @collectChildren()).join('')
    +    '\n' + idt + children
    #

    Short-circuit traverseChildren method to prevent it from crossing scope boundaries +unless crossScope is true

    #

    ParamNode

    exports.ParamNode = class ParamNode extends BaseNode
    +
    +  class:    'ParamNode'
    +  children: ['name']
    +
    +  constructor: (@name, @attach, @splat) ->
    +    super()
    +    @value = literal @name
    +
    +  compileNode: (o) ->
    +    @value.compile o
    +
    +  toString: (idt) ->
    +    if @attach then (literal '@' + @name).toString idt else @value.toString idt
    #

    A parameter in a function definition. Beyond a typical Javascript parameter, +these parameters can also attach themselves to the context of the function, +as well as be a splat, gathering up a group of parameters into an array.

    #

    SplatNode

    exports.SplatNode = class SplatNode extends BaseNode
    +
    +  class:     'SplatNode'
    +  children: ['name']
    +
    +  constructor: (name) ->
    +    super()
    +    name = literal(name) unless name.compile
    +    @name = name
    +
    +  compileNode: (o) ->
    +    if @index? then @compileParam(o) else @name.compile(o)
    #

    A splat, either as a parameter to a function, an argument to a call, +or as part of a destructuring assignment.

      compileParam: (o) ->
    +    name = @name.compile(o)
    +    o.scope.find name
    +    end = ''
    +    if @trailings.length
    +      len = o.scope.freeVariable 'len'
    +      o.scope.assign len, "arguments.length"
    +      variadic = o.scope.freeVariable 'result'
    +      o.scope.assign variadic, len + ' >= ' + @arglength
    +      end = if @trailings.length then ", #{len} - #{@trailings.length}"
    +      for trailing, idx in @trailings
    +        if trailing.attach
    +          assign        = trailing.assign
    +          trailing      = literal o.scope.freeVariable 'arg'
    +          assign.value  = trailing
    +        pos = @trailings.length - idx
    +        o.scope.assign(trailing.compile(o), "arguments[#{variadic} ? #{len} - #{pos} : #{@index + idx}]")
    +    "#{name} = #{utility('slice')}.call(arguments, #{@index}#{end})"
    #

    Compiling a parameter splat means recovering the parameters that succeed +the splat in the parameter list, by slicing the arguments object.

      compileValue: (o, name, index, trailings) ->
    +    trail = if trailings then ", #{name}.length - #{trailings}" else ''
    +    "#{utility 'slice'}.call(#{name}, #{index}#{trail})"
    #

    A compiling a splat as a destructuring assignment means slicing arguments +from the right-hand-side's corresponding array.

      @compileSplattedArray: (list, o) ->
    +    args = []
    +    for arg, i in list
    +      code = arg.compile o
    +      prev = args[last = args.length - 1]
    +      if arg not instanceof SplatNode
    +        if prev and starts(prev, '[') and ends(prev, ']')
    +          args[last] = "#{prev.substr(0, prev.length - 1)}, #{code}]"
    +          continue
    +        else if prev and starts(prev, '.concat([') and ends(prev, '])')
    +          args[last] = "#{prev.substr(0, prev.length - 2)}, #{code}])"
    +          continue
    +        else
    +          code = "[#{code}]"
    +      args.push(if i is 0 then code else ".concat(#{code})")
    +    args.join('')
    #

    Utility function that converts arbitrary number of elements, mixed with +splats, to a proper array

    #

    WhileNode

    exports.WhileNode = class WhileNode extends BaseNode
    +
    +  class:         'WhileNode'
    +  children:     ['condition', 'guard', 'body']
    +  isStatement: -> yes
    +
    +  constructor: (condition, opts) ->
    +    super()
    +    if opts and opts.invert
    +      condition = new ParentheticalNode condition if condition instanceof OpNode
    +      condition = new OpNode('!', condition)
    +    @condition  = condition
    +    @guard = opts and opts.guard
    +
    +  addBody: (body) ->
    +    @body = body
    +    this
    +
    +  makeReturn: ->
    +    @returns = true
    +    this
    +
    +  topSensitive: ->
    +    true
    #

    A while loop, the only sort of low-level loop exposed by CoffeeScript. From +it, all other loops can be manufactured. Useful in cases where you need more +flexibility or more speed than a comprehension can provide.

      compileNode: (o) ->
    +    top      =  del(o, 'top') and not @returns
    +    o.indent =  @idt 1
    +    o.top    =  true
    +    @condition.parenthetical = yes
    +    cond     =  @condition.compile(o)
    +    set      =  ''
    +    unless top
    +      rvar  = o.scope.freeVariable 'result'
    +      set   = "#{@tab}#{rvar} = [];\n"
    +      @body = PushNode.wrap(rvar, @body) if @body
    +    pre     = "#{set}#{@tab}while (#{cond})"
    +    @body   = Expressions.wrap([new IfNode(@guard, @body)]) if @guard
    +    if @returns
    +      post = '\n' + new ReturnNode(literal(rvar)).compile(merge(o, indent: @idt()))
    +    else
    +      post = ''
    +    "#{pre} {\n#{ @body.compile(o) }\n#{@tab}}#{post}"
    #

    The main difference from a JavaScript while is that the CoffeeScript +while can be used as a part of a larger expression -- while loops may +return an array containing the computed result of each iteration.

    #

    OpNode

    exports.OpNode = class OpNode extends BaseNode
    #

    Simple Arithmetic and logical operations. Performs some conversion from +CoffeeScript operations into their JavaScript equivalents.

      CONVERSIONS:
    +    '==': '==='
    +    '!=': '!=='
    #

    The map of conversions from CoffeeScript to JavaScript symbols.

      INVERSIONS:
    +    '!==': '==='
    +    '===': '!=='
    #

    The map of invertible operators.

      CHAINABLE:        ['<', '>', '>=', '<=', '===', '!==']
    #

    The list of operators for which we perform +Python-style comparison chaining.

      ASSIGNMENT:       ['||=', '&&=', '?=']
    #

    Our assignment operators that have no JavaScript equivalent.

      PREFIX_OPERATORS: ['typeof', 'delete']
    +
    +  class:     'OpNode'
    +  children: ['first', 'second']
    +
    +  constructor: (@operator, @first, @second, flip) ->
    +    super()
    +    @operator = @CONVERSIONS[@operator] or @operator
    +    @flip     = !!flip
    +    if @first instanceof ValueNode and @first.base instanceof ObjectNode
    +      @first = new ParentheticalNode @first
    +    @first.tags.operation = yes
    +    @second.tags.operation = yes if @second
    +
    +  isUnary: ->
    +    not @second
    +
    +  isInvertible: ->
    +    (@operator in ['===', '!==']) and
    +      not (@first instanceof OpNode) and not (@second instanceof OpNode)
    +
    +
    +  isMutator: ->
    +    ends(@operator, '=') and not (@operator in ['===', '!=='])
    +
    +  isChainable: ->
    +    include(@CHAINABLE, @operator)
    +
    +  invert: ->
    +    @operator = @INVERSIONS[@operator]
    +
    +  toString: (idt) ->
    +    super(idt, @class + ' ' + @operator)
    +
    +  compileNode: (o) ->
    +    return @compileChain(o)      if @isChainable() and @first.unwrap() instanceof OpNode and @first.unwrap().isChainable()
    +    return @compileAssignment(o) if indexOf(@ASSIGNMENT, @operator) >= 0
    +    return @compileUnary(o)      if @isUnary()
    +    return @compileExistence(o)  if @operator is '?'
    +    @first  = new ParentheticalNode(@first)  if @first instanceof OpNode and @first.isMutator()
    +    @second = new ParentheticalNode(@second) if @second instanceof OpNode and @second.isMutator()
    +    [@first.compile(o), @operator, @second.compile(o)].join ' '
    #

    Operators must come before their operands with a space.

      compileChain: (o) ->
    +    shared = @first.unwrap().second
    +    [@first.second, shared] = shared.compileReference(o) if shared.containsType CallNode
    +    [first, second, shared] = [@first.compile(o), @second.compile(o), shared.compile(o)]
    +    "(#{first}) && (#{shared} #{@operator} #{second})"
    #

    Mimic Python's chained comparisons when multiple comparison operators are +used sequentially. For example:

    + +
    bin/coffee -e "puts 50 < 65 > 10"
    +true
    +
      compileAssignment: (o) ->
    +    [first, firstVar] = @first.compileReference o, precompile: yes, assignment: yes
    +    second = @second.compile o
    +    second = "(#{second})" if @second instanceof OpNode
    +    o.scope.find(first) if first.match(IDENTIFIER)
    +    return "#{first} = #{ ExistenceNode.compileTest(o, literal(firstVar))[0] } ? #{firstVar} : #{second}" if @operator is '?='
    +    "#{first} #{ @operator.substr(0, 2) } (#{firstVar} = #{second})"
    #

    When compiling a conditional assignment, take care to ensure that the +operands are only evaluated once, even though we have to reference them +more than once.

      compileExistence: (o) ->
    +    [test, ref] = ExistenceNode.compileTest(o, @first)
    +    "#{test} ? #{ref} : #{ @second.compile(o) }"
    #

    If this is an existence operator, we delegate to ExistenceNode.compileTest +to give us the safe references for the variables.

      compileUnary: (o) ->
    +    space = if indexOf(@PREFIX_OPERATORS, @operator) >= 0 then ' ' else ''
    +    parts = [@operator, space, @first.compile(o)]
    +    parts = parts.reverse() if @flip
    +    parts.join('')
    #

    Compile a unary OpNode.

    exports.InNode = class InNode extends BaseNode
    +
    +  class:    'InNode'
    +  children: ['object', 'array']
    +
    +  constructor: (@object, @array) ->
    +    super()
    +
    +  isArray: ->
    +    @array instanceof ValueNode and @array.isArray()
    +
    +  compileNode: (o) ->
    +    [@obj1, @obj2] = @object.compileReference o, precompile: yes
    +    if @isArray() then @compileOrTest(o) else @compileLoopTest(o)
    +
    +  compileOrTest: (o) ->
    +    tests = for item, i in @array.base.objects
    +      "#{item.compile(o)} === #{if i then @obj2 else @obj1}"
    +    "(#{tests.join(' || ')})"
    +
    +  compileLoopTest: (o) ->
    +    [@arr1, @arr2] = @array.compileReference o, precompile: yes
    +    [i, l] = [o.scope.freeVariable('i'), o.scope.freeVariable('len')]
    +    prefix = if @obj1 isnt @obj2 then @obj1 + '; ' else ''
    +    "(function(){ #{prefix}for (var #{i}=0, #{l}=#{@arr1}.length; #{i}<#{l}; #{i}++) { if (#{@arr2}[#{i}] === #{@obj2}) return true; } return false; }).call(this)"
    #

    InNode

    #

    TryNode

    exports.TryNode = class TryNode extends BaseNode
    +
    +  class:        'TryNode'
    +  children:     ['attempt', 'recovery', 'ensure']
    +  isStatement:  -> yes
    +
    +  constructor: (@attempt, @error, @recovery, @ensure) ->
    +    super()
    +
    +  makeReturn: ->
    +    @attempt  = @attempt.makeReturn() if @attempt
    +    @recovery = @recovery.makeReturn() if @recovery
    +    this
    #

    A classic try/catch/finally block.

      compileNode: (o) ->
    +    o.indent    = @idt 1
    +    o.top       = true
    +    attemptPart = @attempt.compile(o)
    +    errorPart   = if @error then " (#{ @error.compile(o) }) " else ' '
    +    catchPart   = if @recovery then " catch#{errorPart}{\n#{ @recovery.compile(o) }\n#{@tab}}" else ''
    +    finallyPart = (@ensure or '') and ' finally {\n' + @ensure.compile(merge(o)) + "\n#{@tab}}"
    +    "#{@tab}try {\n#{attemptPart}\n#{@tab}}#{catchPart}#{finallyPart}"
    #

    Compilation is more or less as you would expect -- the finally clause +is optional, the catch is not.

    #

    ThrowNode

    exports.ThrowNode = class ThrowNode extends BaseNode
    +
    +  class:         'ThrowNode'
    +  children:     ['expression']
    +  isStatement: -> yes
    +
    +  constructor: (@expression) ->
    +    super()
    #

    Simple node to throw an exception.

      makeReturn: ->
    +    return this
    +
    +  compileNode: (o) ->
    +    "#{@tab}throw #{@expression.compile(o)};"
    #

    A ThrowNode is already a return, of sorts...

    #

    ExistenceNode

    exports.ExistenceNode = class ExistenceNode extends BaseNode
    +
    +  class:     'ExistenceNode'
    +  children: ['expression']
    +
    +  constructor: (@expression) ->
    +    super()
    +
    +  compileNode: (o) ->
    +    test = ExistenceNode.compileTest(o, @expression)[0]
    +    if @parenthetical then test.substring(1, test.length - 1) else test
    #

    Checks a variable for existence -- not null and not undefined. This is +similar to .nil? in Ruby, and avoids having to consult a JavaScript truth +table.

      @compileTest: (o, variable) ->
    +    [first, second] = variable.compileReference o, precompile: yes
    +    ["(typeof #{first} !== \"undefined\" && #{second} !== null)", second]
    #

    The meat of the ExistenceNode is in this static compileTest method +because other nodes like to check the existence of their variables as well. +Be careful not to double-evaluate anything.

    #

    ParentheticalNode

    exports.ParentheticalNode = class ParentheticalNode extends BaseNode
    +
    +  class:     'ParentheticalNode'
    +  children: ['expression']
    +
    +  constructor: (@expression) ->
    +    super()
    +
    +  isStatement: (o) ->
    +    @expression.isStatement(o)
    +
    +  makeReturn: ->
    +    @expression.makeReturn()
    +
    +  topSensitive: ->
    +    yes
    +
    +  compileNode: (o) ->
    +    top  = del o, 'top'
    +    @expression.parenthetical = true
    +    code = @expression.compile(o)
    +    return code if top and @expression.isPureStatement o
    +    if @parenthetical or @isStatement o
    +      return if top then @tab + code + ';' else code
    +    "(#{code})"
    #

    An extra set of parentheses, specified explicitly in the source. At one time +we tried to clean up the results by detecting and removing redundant +parentheses, but no longer -- you can put in as many as you please.

    + +

    Parentheses are a good way to force any statement to become an expression.

    #

    ForNode

    exports.ForNode = class ForNode extends BaseNode
    +
    +  class:         'ForNode'
    +  children:     ['body', 'source', 'guard']
    +  isStatement: -> yes
    +
    +  constructor: (@body, source, @name, @index) ->
    +    super()
    +    @index  or= null
    +    @source = source.source
    +    @guard  = source.guard
    +    @step   = source.step
    +    @raw    = !!source.raw
    +    @object = !!source.object
    +    [@name, @index] = [@index, @name] if @object
    +    @pattern = @name instanceof ValueNode
    +    throw new Error('index cannot be a pattern matching expression') if @index instanceof ValueNode
    +    @returns = false
    +
    +  topSensitive: ->
    +    true
    +
    +  makeReturn: ->
    +    @returns = true
    +    this
    +
    +  compileReturnValue: (val, o) ->
    +    return '\n' + new ReturnNode(literal(val)).compile(o) if @returns
    +    return '\n' + val if val
    +    ''
    #

    CoffeeScript's replacement for the for loop is our array and object +comprehensions, that compile into for loops here. They also act as an +expression, able to return the result of each filtered iteration.

    + +

    Unlike Python array comprehensions, they can be multi-line, and you can pass +the current index of the loop as a second parameter. Unlike Ruby blocks, +you can map and filter in a single pass.

      compileNode: (o) ->
    +    topLevel      = del(o, 'top') and not @returns
    +    range         = @source instanceof ValueNode and @source.base instanceof RangeNode and not @source.properties.length
    +    source        = if range then @source.base else @source
    +    codeInBody    = @body.contains (n) -> n instanceof CodeNode
    +    scope         = o.scope
    +    name          = (@name and @name.compile(o)) or scope.freeVariable 'i'
    +    index         = @index and @index.compile o
    +    scope.find(name,  immediate: yes) if name and not @pattern and (range or not codeInBody)
    +    scope.find(index, immediate: yes) if index
    +    rvar          = scope.freeVariable 'result' unless topLevel
    +    ivar          = if codeInBody then scope.freeVariable 'i' else if range then name else index or scope.freeVariable 'i'
    +    varPart       = ''
    +    guardPart     = ''
    +    body          = Expressions.wrap([@body])
    +    if range
    +      sourcePart  = source.compileVariables(o)
    +      forPart     = source.compile merge o, index: ivar, step: @step
    +    else
    +      svar        = scope.freeVariable 'ref'
    +      sourcePart  = "#{svar} = #{ @source.compile(o) };"
    +      if @pattern
    +        namePart  = new AssignNode(@name, literal("#{svar}[#{ivar}]")).compile(merge o, {indent: @idt(1), top: true, keepLevel: yes}) + '\n'
    +      else
    +        namePart  = "#{name} = #{svar}[#{ivar}]" if name
    +      unless @object
    +        lvar      = scope.freeVariable 'len'
    +        stepPart  = if @step then "#{ivar} += #{ @step.compile(o) }" else "#{ivar}++"
    +        forPart   = "#{ivar} = 0, #{lvar} = #{svar}.length; #{ivar} < #{lvar}; #{stepPart}"
    +    sourcePart    = (if rvar then "#{rvar} = []; " else '') + sourcePart
    +    sourcePart    = if sourcePart then "#{@tab}#{sourcePart}\n#{@tab}" else @tab
    +    returnResult  = @compileReturnValue(rvar, o)
    +
    +    body          = PushNode.wrap(rvar, body) unless topLevel
    +    if @guard
    +      body        = Expressions.wrap([new IfNode(@guard, body)])
    +    if codeInBody
    +      body.unshift  literal "var #{name} = #{ivar}" if range
    +      body.unshift  literal "var #{namePart}" if namePart
    +      body.unshift  literal "var #{index} = #{ivar}" if index
    +      body        = ClosureNode.wrap(body, true)
    +    else
    +      varPart     = (namePart or '') and (if @pattern then namePart else "#{@idt(1)}#{namePart};\n")
    +    if @object
    +      forPart     = "#{ivar} in #{svar}"
    +      guardPart   = "\n#{@idt(1)}if (!#{utility('hasProp')}.call(#{svar}, #{ivar})) continue;" unless @raw
    +    body          = body.compile(merge(o, {indent: @idt(1), top: true}))
    +    vars          = if range then name else "#{name}, #{ivar}"
    +    "#{sourcePart}for (#{forPart}) {#{guardPart}\n#{varPart}#{body}\n#{@tab}}#{returnResult}"
    #

    Welcome to the hairiest method in all of CoffeeScript. Handles the inner +loop, filtering, stepping, and result saving for array, object, and range +comprehensions. Some of the generated code can be shared in common, and +some cannot.

    #

    SwitchNode

    exports.SwitchNode = class SwitchNode extends BaseNode
    +
    +  class:     'SwitchNode'
    +  children: ['subject', 'cases', 'otherwise']
    +
    +  isStatement: -> yes
    +
    +  constructor: (@subject, @cases, @otherwise) ->
    +    super()
    +    @tags.subjectless = !@subject
    +    @subject or= literal 'true'
    +
    +  makeReturn: ->
    +    pair[1].makeReturn() for pair in @cases
    +    @otherwise.makeReturn() if @otherwise
    +    this
    +
    +  compileNode: (o) ->
    +    idt = o.indent = @idt 2
    +    o.top = yes
    +    code = "#{ @tab }switch (#{ @subject.compile o }) {"
    +    for pair in @cases
    +      [conditions, block] = pair
    +      exprs = block.expressions
    +      for condition in flatten [conditions]
    +        condition = new OpNode '!!', new ParentheticalNode condition if @tags.subjectless
    +        code += "\n#{ @idt(1) }case #{ condition.compile o }:"
    +      code += "\n#{ block.compile o }"
    +      code += "\n#{ idt }break;" unless exprs[exprs.length - 1] instanceof ReturnNode
    +    if @otherwise
    +      code += "\n#{ @idt(1) }default:\n#{ @otherwise.compile o }"
    +    code += "\n#{ @tab }}"
    +    code
    #

    A JavaScript switch statement. Converts into a returnable expression on-demand.

    #

    IfNode

    exports.IfNode = class IfNode extends BaseNode
    +
    +  class:     'IfNode'
    +  children: ['condition', 'body', 'elseBody', 'assigner']
    +
    +  topSensitive: -> true
    +
    +  constructor: (@condition, @body, @tags) ->
    +    @tags or= {}
    +    if @tags.invert
    +      if @condition instanceof OpNode and @condition.isInvertible()
    +        @condition.invert()
    +      else
    +        @condition = new OpNode '!', new ParentheticalNode @condition
    +    @elseBody = null
    +    @isChain  = false
    +
    +  bodyNode: -> @body?.unwrap()
    +  elseBodyNode: -> @elseBody?.unwrap()
    +
    +  forceStatement: ->
    +    @tags.statement = true
    +    this
    #

    If/else statements. Acts as an expression by pushing down requested returns +to the last line of each clause.

    + +

    Single-expression IfNodes are compiled into ternary operators if possible, +because ternaries are already proper expressions, and don't need conversion.

      addElse: (elseBody, statement) ->
    +    if @isChain
    +      @elseBodyNode().addElse elseBody, statement
    +    else
    +      @isChain = elseBody instanceof IfNode
    +      @elseBody = @ensureExpressions elseBody
    +    this
    #

    Rewrite a chain of IfNodes to add a default case as the final else.

      isStatement: (o) ->
    +    @statement or= !!((o and o.top) or @tags.statement or @bodyNode().isStatement(o) or (@elseBody and @elseBodyNode().isStatement(o)))
    +
    +  compileCondition: (o) ->
    +    conditions = flatten [@condition]
    +    conditions[0].parenthetical = yes if conditions.length is 1
    +    (cond.compile(o) for cond in conditions).join(' || ')
    +
    +  compileNode: (o) ->
    +    if @isStatement(o) then @compileStatement(o) else @compileTernary(o)
    +
    +  makeReturn: ->
    +    if @isStatement()
    +      @body     and= @ensureExpressions(@body.makeReturn())
    +      @elseBody and= @ensureExpressions(@elseBody.makeReturn())
    +      this
    +    else
    +      new ReturnNode this
    +
    +  ensureExpressions: (node) ->
    +    if node instanceof Expressions then node else new Expressions [node]
    #

    The IfNode only compiles into a statement if either of its bodies needs +to be a statement. Otherwise a ternary is safe.

      compileStatement: (o) ->
    +    top      = del o, 'top'
    +    child    = del o, 'chainChild'
    +    condO    = merge o
    +    o.indent = @idt 1
    +    o.top    = true
    +    ifDent   = if child or (top and not @isStatement(o)) then '' else @idt()
    +    comDent  = if child then @idt() else ''
    +    body     = @body.compile(o)
    +    ifPart   = "#{ifDent}if (#{ @compileCondition(condO) }) {\n#{body}\n#{@tab}}"
    +    return ifPart unless @elseBody
    +    elsePart = if @isChain
    +      ' else ' + @elseBodyNode().compile(merge(o, {indent: @idt(), chainChild: true}))
    +    else
    +      " else {\n#{ @elseBody.compile(o) }\n#{@tab}}"
    +    "#{ifPart}#{elsePart}"
    #

    Compile the IfNode as a regular if-else statement. Flattened chains +force inner else bodies into statement form.

      compileTernary: (o) ->
    +    @bodyNode().tags.operation = @condition.tags.operation = yes
    +    @elseBodyNode().tags.operation = yes if @elseBody
    +    ifPart      = @condition.compile(o) + ' ? ' + @bodyNode().compile(o)
    +    elsePart    = if @elseBody then @elseBodyNode().compile(o) else 'null'
    +    code        = "#{ifPart} : #{elsePart}"
    +    if @tags.operation then "(#{code})" else code
    #

    Compile the IfNode as a ternary operator.

    #

    Faux-Nodes

    #

    PushNode

    PushNode = exports.PushNode =
    +  wrap: (array, expressions) ->
    +    expr = expressions.unwrap()
    +    return expressions if expr.isPureStatement() or expr.containsPureStatement()
    +    Expressions.wrap([new CallNode(
    +      new ValueNode(literal(array), [new AccessorNode(literal('push'))]), [expr]
    +    )])
    #

    Faux-nodes are never created by the grammar, but are used during code +generation to generate other combinations of nodes. The PushNode creates +the tree for array.push(value), which is helpful for recording the result +arrays from comprehensions.

    #

    ClosureNode

    ClosureNode = exports.ClosureNode =
    #

    A faux-node used to wrap an expressions body in a closure.

      wrap: (expressions, statement) ->
    +    return expressions if expressions.containsPureStatement()
    +    func = new ParentheticalNode(new CodeNode([], Expressions.wrap([expressions])))
    +    args = []
    +    mentionsArgs = expressions.contains (n) ->
    +      n instanceof LiteralNode and (n.value is 'arguments')
    +    mentionsThis = expressions.contains (n) ->
    +      (n instanceof LiteralNode and (n.value is 'this')) or
    +      (n instanceof CodeNode and n.bound)
    +    if mentionsArgs or mentionsThis
    +      meth = literal(if mentionsArgs then 'apply' else 'call')
    +      args = [literal('this')]
    +      args.push literal 'arguments' if mentionsArgs
    +      func = new ValueNode func, [new AccessorNode(meth)]
    +    call = new CallNode(func, args)
    +    if statement then Expressions.wrap([call]) else call
    #

    Wrap the expressions body, unless it contains a pure statement, +in which case, no dice. If the body mentions this or arguments, +then make sure that the closure wrapper preserves the original values.

    UTILITIES =
    #

    Utility Functions

      extends:  """
    +            function(child, parent) {
    +                var ctor = function(){};
    +                ctor.prototype = parent.prototype;
    +                child.prototype = new ctor();
    +                child.prototype.constructor = child;
    +                if (typeof parent.extended === "function") parent.extended(child);
    +                child.__super__ = parent.prototype;
    +              }
    +            """
    #

    Correctly set up a prototype chain for inheritance, including a reference +to the superclass for super() calls. See: +goog.inherits.

      bind: """
    +        function(func, context) {
    +            return function(){ return func.apply(context, arguments); };
    +          }
    +        """
    #

    Create a function bound to the current value of "this".

      hasProp: 'Object.prototype.hasOwnProperty'
    +  slice:   'Array.prototype.slice'
    #

    Shortcuts to speed up the lookup time for native functions.

    #

    Constants

    TAB = '  '
    #

    Tabs are two spaces for pretty printing.

    TRAILING_WHITESPACE = /[ \t]+$/gm
    #

    Trim out all trailing whitespace, so that the generated code plays nice +with Git.

    IDENTIFIER = /^[a-zA-Z\$_](\w|\$)*$/
    +NUMBER     = /^(((\b0(x|X)[0-9a-fA-F]+)|((\b[0-9]+(\.[0-9]+)?|\.[0-9]+)(e[+\-]?[0-9]+)?)))\b$/i
    +SIMPLENUM  = /^-?\d+$/
    #

    Keep these identifier regexes in sync with the Lexer.

    IS_STRING = /^['"]/
    #

    Is a literal value a string?

    #

    Utility Functions

    literal = (name) ->
    +  new LiteralNode(name)
    #

    Handy helper for a generating LiteralNode.

    utility = (name) ->
    +  ref = "__#{name}"
    +  Scope.root.assign ref, UTILITIES[name]
    +  ref
    +
    +
    #

    Helper for ensuring that utility functions are assigned at the top level.

    undefined
    \ No newline at end of file diff --git a/node_modules/jade/support/coffee-script/documentation/docs/optparse.html b/node_modules/jade/support/coffee-script/documentation/docs/optparse.html new file mode 100644 index 0000000..8b59e3c --- /dev/null +++ b/node_modules/jade/support/coffee-script/documentation/docs/optparse.html @@ -0,0 +1,75 @@ + optparse.coffee

    optparse.coffee

    #

    A simple OptionParser class to parse option flags from the command-line. +Use it like so:

    + +
    parser  = new OptionParser switches, helpBanner
    +options = parser.parse process.argv
    +
    + +

    The first non-option is considered to be the start of the file (and file +option) list, and all subsequent arguments are left unparsed.

    exports.OptionParser = class OptionParser
    #

    Initialize with a list of valid options, in the form:

    + +
    [short-flag, long-flag, description]
    +
    + +

    Along with an an optional banner for the usage help.

      constructor: (rules, banner) ->
    +    @banner = banner
    +    @rules  = buildRules rules
    #

    Parse the list of arguments, populating an options object with all of the +specified options, and returning it. options.arguments will be an array +containing the remaning non-option arguments. This is a simpler API than +many option parsers that allow you to attach callback actions for every +flag. Instead, you're responsible for interpreting the options object.

      parse: (args) ->
    +    options = arguments: []
    +    args    = normalizeArguments args
    +    for arg, i in args
    +      isOption = !!(arg.match(LONG_FLAG) or arg.match(SHORT_FLAG))
    +      matchedRule = no
    +      for rule in @rules
    +        if rule.shortFlag is arg or rule.longFlag is arg
    +          value = if rule.hasArgument then args[i += 1] else true
    +          options[rule.name] = if rule.isList then (options[rule.name] or []).concat value else value
    +          matchedRule = yes
    +          break
    +      throw new Error "unrecognized option: #{arg}" if isOption and not matchedRule
    +      if not isOption
    +        options.arguments = args[i...args.length]
    +        break
    +    options
    #

    Return the help text for this OptionParser, listing and describing all +of the valid options, for --help and such.

      help: ->
    +    lines = ['Available options:']
    +    lines.unshift "#{@banner}\n" if @banner
    +    for rule in @rules
    +      spaces  = 15 - rule.longFlag.length
    +      spaces  = if spaces > 0 then Array(spaces + 1).join(' ') else ''
    +      letPart = if rule.shortFlag then rule.shortFlag + ', ' else '    '
    +      lines.push '  ' + letPart + rule.longFlag + spaces + rule.description
    +    "\n#{ lines.join('\n') }\n"
    #

    Helpers

    #

    Regex matchers for option flags.

    LONG_FLAG  = /^(--\w[\w\-]+)/
    +SHORT_FLAG = /^(-\w)/
    +MULTI_FLAG = /^-(\w{2,})/
    +OPTIONAL   = /\[(\w+(\*?))\]/
    #

    Build and return the list of option rules. If the optional short-flag is +unspecified, leave it out by padding with null.

    buildRules = (rules) ->
    +  for tuple in rules
    +    tuple.unshift null if tuple.length < 3
    +    buildRule tuple...
    #

    Build a rule from a -o short flag, a --output [DIR] long flag, and the +description of what the option does.

    buildRule = (shortFlag, longFlag, description, options) ->
    +  match     = longFlag.match(OPTIONAL)
    +  longFlag  = longFlag.match(LONG_FLAG)[1]
    +  options or= {}
    +  {
    +    name:         longFlag.substr 2
    +    shortFlag:    shortFlag
    +    longFlag:     longFlag
    +    description:  description
    +    hasArgument:  !!(match and match[1])
    +    isList:       !!(match and match[2])
    +  }
    #

    Normalize arguments by expanding merged flags into multiple flags. This allows +you to have -wl be the same as --watch --lint.

    normalizeArguments = (args) ->
    +  args = args.slice 0
    +  result = []
    +  for arg in args
    +    if match = arg.match MULTI_FLAG
    +      result.push '-' + l for l in match[1].split ''
    +    else
    +      result.push arg
    +  result
    +
    +
    \ No newline at end of file diff --git a/node_modules/jade/support/coffee-script/documentation/docs/repl.html b/node_modules/jade/support/coffee-script/documentation/docs/repl.html new file mode 100644 index 0000000..3b64130 --- /dev/null +++ b/node_modules/jade/support/coffee-script/documentation/docs/repl.html @@ -0,0 +1,23 @@ + repl.coffee

    repl.coffee

    #

    A very simple Read-Eval-Print-Loop. Compiles one line at a time to JavaScript +and evaluates it. Good for simple tests, or poking around the Node.js API. +Using it looks like this:

    + +
    coffee> puts "#{num} bottles of beer" for num in [99..1]
    +
    #

    Require the coffee-script module to get access to the compiler.

    CoffeeScript = require './coffee-script'
    +helpers      = require('./helpers').helpers
    +readline     = require 'readline'
    #

    Start by opening up stdio.

    stdio = process.openStdin()
    #

    Quick alias for quitting the REPL.

    helpers.extend global, quit: -> process.exit(0)
    #

    The main REPL function. run is called every time a line of code is entered. +Attempt to evaluate the command. If there's an exception, print it out instead +of exiting.

    run = (buffer) ->
    +  try
    +    val = CoffeeScript.eval buffer.toString(), noWrap: true, globals: true, fileName: 'repl'
    +    puts inspect val if val isnt undefined
    +  catch err
    +    puts err.stack or err.toString()
    +  repl.prompt()
    #

    Create the REPL by listening to stdin.

    repl = readline.createInterface stdio
    +repl.setPrompt 'coffee> '
    +stdio.on 'data',   (buffer) -> repl.write buffer
    +repl.on  'close',  -> stdio.destroy()
    +repl.on  'line',   run
    +repl.prompt()
    +
    +
    \ No newline at end of file diff --git a/node_modules/jade/support/coffee-script/documentation/docs/rewriter.html b/node_modules/jade/support/coffee-script/documentation/docs/rewriter.html new file mode 100644 index 0000000..40a9394 --- /dev/null +++ b/node_modules/jade/support/coffee-script/documentation/docs/rewriter.html @@ -0,0 +1,265 @@ + rewriter.coffee

    rewriter.coffee

    #

    The CoffeeScript language has a good deal of optional syntax, implicit syntax, +and shorthand syntax. This can greatly complicate a grammar and bloat +the resulting parse table. Instead of making the parser handle it all, we take +a series of passes over the token stream, using this Rewriter to convert +shorthand into the unambiguous long form, add implicit indentation and +parentheses, balance incorrect nestings, and generally clean things up.

    #

    Import the helpers we need.

    {include} = require('./helpers').helpers
    #

    The Rewriter class is used by the Lexer, directly against +its internal array of tokens.

    exports.Rewriter = class Rewriter
    #

    Helpful snippet for debugging: + puts (t[0] + '/' + t[1] for t in @tokens).join ' '

    #

    Rewrite the token stream in multiple passes, one logical filter at +a time. This could certainly be changed into a single pass through the +stream, with a big ol' efficient switch, but it's much nicer to work with +like this. The order of these passes matters -- indentation must be +corrected before implicit parentheses can be wrapped around blocks of code.

      rewrite: (tokens) ->
    +    @tokens = tokens
    +    @adjustComments()
    +    @removeLeadingNewlines()
    +    @removeMidExpressionNewlines()
    +    @closeOpenCalls()
    +    @closeOpenIndexes()
    +    @addImplicitIndentation()
    +    @tagPostfixConditionals()
    +    @addImplicitBraces()
    +    @addImplicitParentheses()
    +    @ensureBalance BALANCED_PAIRS
    +    @rewriteClosingParens()
    +    @tokens
    #

    Rewrite the token stream, looking one token ahead and behind. +Allow the return value of the block to tell us how many tokens to move +forwards (or backwards) in the stream, to make sure we don't miss anything +as tokens are inserted and removed, and the stream changes length under +our feet.

      scanTokens: (block) ->
    +    i = 0
    +    loop
    +      break unless @tokens[i]
    +      move = block.call this, @tokens[i], i
    +      i += move
    +    true
    +
    +  detectEnd: (i, condition, action) ->
    +    levels = 0
    +    loop
    +      token = @tokens[i]
    +      return action.call this, token, i     if levels is 0 and condition.call this, token, i
    +      return action.call this, token, i - 1 if not token or levels < 0
    +      levels += 1 if include EXPRESSION_START, token[0]
    +      levels -= 1 if include EXPRESSION_END, token[0]
    +      i += 1
    +    i - 1
    #

    Massage newlines and indentations so that comments don't have to be +correctly indented, or appear on a line of their own.

      adjustComments: ->
    +    @scanTokens (token, i) ->
    +      return 1 unless token[0] is 'HERECOMMENT'
    +      [before, prev, post, after] = [@tokens[i - 2], @tokens[i - 1], @tokens[i + 1], @tokens[i + 2]]
    +      if after and after[0] is 'INDENT'
    +        @tokens.splice i + 2, 1
    +        if before and before[0] is 'OUTDENT' and post and prev[0] is post[0] is 'TERMINATOR'
    +          @tokens.splice i - 2, 1
    +        else
    +          @tokens.splice i, 0, after
    +      else if prev and prev[0] not in ['TERMINATOR', 'INDENT', 'OUTDENT']
    +        if post and post[0] is 'TERMINATOR' and after and after[0] is 'OUTDENT'
    +          @tokens.splice(i + 2, 0, @tokens.splice(i, 2)...)
    +          if @tokens[i + 2][0] isnt 'TERMINATOR'
    +            @tokens.splice i + 2, 0, ['TERMINATOR', "\n", prev[2]]
    +        else
    +          @tokens.splice i, 0, ['TERMINATOR', "\n", prev[2]]
    +        return 2
    +      return 1
    #

    Leading newlines would introduce an ambiguity in the grammar, so we +dispatch them here.

      removeLeadingNewlines: ->
    +    @tokens.shift() while @tokens[0] and @tokens[0][0] is 'TERMINATOR'
    #

    Some blocks occur in the middle of expressions -- when we're expecting +this, remove their trailing newlines.

      removeMidExpressionNewlines: ->
    +    @scanTokens (token, i) ->
    +      return 1 unless include(EXPRESSION_CLOSE, @tag(i + 1)) and token[0] is 'TERMINATOR'
    +      @tokens.splice i, 1
    +      return 0
    #

    The lexer has tagged the opening parenthesis of a method call. Match it with +its paired close. We have the mis-nested outdent case included here for +calls that close on the same line, just before their outdent.

      closeOpenCalls: ->
    +    @scanTokens (token, i) ->
    +      if token[0] is 'CALL_START'
    +        condition = (token, i) ->
    +          (token[0] in [')', 'CALL_END']) or (token[0] is 'OUTDENT' and @tokens[i - 1][0] is ')')
    +        action = (token, i) ->
    +          idx = if token[0] is 'OUTDENT' then i - 1 else i
    +          @tokens[idx][0] = 'CALL_END'
    +        @detectEnd i + 1, condition, action
    +      return 1
    #

    The lexer has tagged the opening parenthesis of an indexing operation call. +Match it with its paired close.

      closeOpenIndexes: ->
    +    @scanTokens (token, i) ->
    +      if token[0] is 'INDEX_START'
    +        condition = (token, i) -> token[0] in [']', 'INDEX_END']
    +        action    = (token, i) -> token[0] = 'INDEX_END'
    +        @detectEnd i + 1, condition, action
    +      return 1
    #

    Object literals may be written with implicit braces, for simple cases. +Insert the missing braces here, so that the parser doesn't have to.

      addImplicitBraces: ->
    +    stack = []
    +    @scanTokens (token, i) ->
    +      if include EXPRESSION_START, token[0]
    +        stack.push(if (token[0] is 'INDENT' and (@tag(i - 1) is '{')) then '{' else token[0])
    +      if include EXPRESSION_END, token[0]
    +        stack.pop()
    +      last = stack[stack.length - 1]
    +      if token[0] is ':' and (not last or last[0] isnt '{')
    +        stack.push '{'
    +        idx = if @tag(i - 2) is '@' then i - 2 else i - 1
    +        idx -= 2 if @tag(idx - 2) is 'HERECOMMENT'
    +        tok = ['{', '{', token[2]]
    +        tok.generated = yes
    +        @tokens.splice idx, 0, tok
    +        condition = (token, i) ->
    +          [one, two, three] = @tokens.slice(i + 1, i + 4)
    +          return false if 'HERECOMMENT' in [@tag(i + 1), @tag(i - 1)]
    +          ((token[0] in ['TERMINATOR', 'OUTDENT']) and not ((two and two[0] is ':') or (one and one[0] is '@' and three and three[0] is ':'))) or
    +            (token[0] is ',' and one and (one[0] not in ['IDENTIFIER', 'STRING', '@', 'TERMINATOR', 'OUTDENT']))
    +        action = (token, i) ->
    +          @tokens.splice i, 0, ['}', '}', token[2]]
    +        @detectEnd i + 2, condition, action
    +        return 2
    +      return 1
    #

    Methods may be optionally called without parentheses, for simple cases. +Insert the implicit parentheses here, so that the parser doesn't have to +deal with them.

      addImplicitParentheses: ->
    +    classLine    = no
    +    @scanTokens (token, i) ->
    +      classLine  = yes if token[0] is 'CLASS'
    +      prev       = @tokens[i - 1]
    +      next       = @tokens[i + 1]
    +      idx        = 1
    +      callObject = not classLine and token[0] is 'INDENT' and next and next.generated and next[0] is '{' and prev and include(IMPLICIT_FUNC, prev[0])
    +      idx        = 2 if callObject
    +      seenSingle = no
    +      classLine  = no  if include(LINEBREAKS, token[0])
    +      token.call = yes if prev and not prev.spaced and token[0] is '?'
    +      if prev and (prev.spaced and (include(IMPLICIT_FUNC, prev[0]) or prev.call) and include(IMPLICIT_CALL, token[0]) and
    +          not (token[0] is 'UNARY' and (@tag(i + 1) in ['IN', 'OF', 'INSTANCEOF']))) or callObject
    +        @tokens.splice i, 0, ['CALL_START', '(', token[2]]
    +        condition = (token, i) ->
    +          return yes if not seenSingle and token.fromThen
    +          seenSingle = yes if token[0] in ['IF', 'ELSE', 'UNLESS', '->', '=>']
    +          post = @tokens[i + 1]
    +          (not token.generated and @tokens[i - 1][0] isnt ',' and include(IMPLICIT_END, token[0]) and
    +            not (token[0] is 'INDENT' and (include(IMPLICIT_BLOCK, @tag(i - 1)) or @tag(i - 2) is 'CLASS' or (post and post.generated and post[0] is '{')))) or
    +            token[0] is 'PROPERTY_ACCESS' and @tag(i - 1) is 'OUTDENT'
    +        action = (token, i) ->
    +          idx = if token[0] is 'OUTDENT' then i + 1 else i
    +          @tokens.splice idx, 0, ['CALL_END', ')', token[2]]
    +        @detectEnd i + idx, condition, action
    +        prev[0] = 'FUNC_EXIST' if prev[0] is '?'
    +        return 2
    +      return 1
    #

    Because our grammar is LALR(1), it can't handle some single-line +expressions that lack ending delimiters. The Rewriter adds the implicit +blocks, so it doesn't need to. ')' can close a single-line block, +but we need to make sure it's balanced.

      addImplicitIndentation: ->
    +    @scanTokens (token, i) ->
    +      if token[0] is 'ELSE' and @tag(i - 1) isnt 'OUTDENT'
    +        @tokens.splice i, 0, @indentation(token)...
    +        return 2
    +      if token[0] is 'CATCH' and
    +          (@tag(i + 2) is 'TERMINATOR' or @tag(i + 2) is 'FINALLY')
    +        @tokens.splice i + 2, 0, @indentation(token)...
    +        return 4
    +      if include(SINGLE_LINERS, token[0]) and @tag(i + 1) isnt 'INDENT' and
    +          not (token[0] is 'ELSE' and @tag(i + 1) is 'IF')
    +        starter = token[0]
    +        [indent, outdent] = @indentation token
    +        indent.fromThen   = true if starter is 'THEN'
    +        indent.generated  = outdent.generated = true
    +        @tokens.splice i + 1, 0, indent
    +        condition = (token, i) ->
    +          (include(SINGLE_CLOSERS, token[0]) and token[1] isnt ';') and
    +            not (token[0] is 'ELSE' and starter not in ['IF', 'THEN'])
    +        action = (token, i) ->
    +          idx = if @tokens[i - 1][0] is ',' then i - 1 else i
    +          @tokens.splice idx, 0, outdent
    +        @detectEnd i + 2, condition, action
    +        @tokens.splice i, 1 if token[0] is 'THEN'
    +        return 2
    +      return 1
    #

    Tag postfix conditionals as such, so that we can parse them with a +different precedence.

      tagPostfixConditionals: ->
    +    @scanTokens (token, i) ->
    +      if token[0] in ['IF', 'UNLESS']
    +        original  = token
    +        condition = (token, i) ->
    +          token[0] in ['TERMINATOR', 'INDENT']
    +        action    = (token, i) ->
    +          original[0] = 'POST_' + original[0] if token[0] isnt 'INDENT'
    +        @detectEnd i + 1, condition, action
    +        return 1
    +      return 1
    #

    Ensure that all listed pairs of tokens are correctly balanced throughout +the course of the token stream.

      ensureBalance: (pairs) ->
    +    levels   = {}
    +    openLine = {}
    +    @scanTokens (token, i) ->
    +      for pair in pairs
    +        [open, close] = pair
    +        levels[open] or= 0
    +        if token[0] is open
    +          openLine[open] = token[2] if levels[open] == 0
    +          levels[open] += 1
    +        levels[open] -= 1 if token[0] is close
    +        throw new Error("too many #{token[1]} on line #{token[2] + 1}") if levels[open] < 0
    +      return 1
    +    unclosed = key for key, value of levels when value > 0
    +    if unclosed.length
    +      open = unclosed[0]
    +      line = openLine[open] + 1
    +      throw new Error "unclosed #{open} on line #{line}"
    #

    We'd like to support syntax like this:

    + +
    el.click((event) ->
    +  el.hide())
    +
    + +

    In order to accomplish this, move outdents that follow closing parens +inwards, safely. The steps to accomplish this are:

    + +
      +
    1. Check that all paired tokens are balanced and in order.
    2. +
    3. Rewrite the stream with a stack: if you see an EXPRESSION_START, add it +to the stack. If you see an EXPRESSION_END, pop the stack and replace +it with the inverse of what we've just popped.
    4. +
    5. Keep track of "debt" for tokens that we manufacture, to make sure we end +up balanced in the end.
    6. +
    7. Be careful not to alter array or parentheses delimiters with overzealous +rewriting.
    8. +
      rewriteClosingParens: ->
    +    stack = []
    +    debt  = {}
    +    (debt[key] = 0) for key, val of INVERSES
    +    @scanTokens (token, i) ->
    +      tag = token[0]
    +      inv = INVERSES[token[0]]
    +      if include EXPRESSION_START, tag
    +        stack.push token
    +        return 1
    +      else if include EXPRESSION_END, tag
    +        if debt[inv] > 0
    +          debt[inv] -= 1
    +          @tokens.splice i, 1
    +          return 0
    +        else
    +          match = stack.pop()
    +          mtag  = match[0]
    +          oppos = INVERSES[mtag]
    +          return 1 if tag is oppos
    +          debt[mtag] += 1
    +          val = [oppos, if mtag is 'INDENT' then match[1] else oppos]
    +          if @tokens[i + 2]?[0] is mtag
    +            @tokens.splice i + 3, 0, val
    +            stack.push(match)
    +          else
    +            @tokens.splice i, 0, val
    +          return 1
    +      else
    +        return 1
    #

    Generate the indentation tokens, based on another token on the same line.

      indentation: (token) ->
    +    [['INDENT', 2, token[2]], ['OUTDENT', 2, token[2]]]
    #

    Look up a tag by token index.

      tag: (i) ->
    +    @tokens[i] and @tokens[i][0]
    #

    Constants

    #

    List of the token pairs that must be balanced.

    BALANCED_PAIRS = [['(', ')'], ['[', ']'], ['{', '}'], ['INDENT', 'OUTDENT'],
    +  ['PARAM_START', 'PARAM_END'], ['CALL_START', 'CALL_END'], ['INDEX_START', 'INDEX_END']]
    #

    The inverse mappings of BALANCED_PAIRS we're trying to fix up, so we can +look things up from either end.

    INVERSES = {}
    +for pair in BALANCED_PAIRS
    +  INVERSES[pair[0]] = pair[1]
    +  INVERSES[pair[1]] = pair[0]
    #

    The tokens that signal the start of a balanced pair.

    EXPRESSION_START = pair[0] for pair in BALANCED_PAIRS
    #

    The tokens that signal the end of a balanced pair.

    EXPRESSION_END   = pair[1] for pair in BALANCED_PAIRS
    #

    Tokens that indicate the close of a clause of an expression.

    EXPRESSION_CLOSE = ['CATCH', 'WHEN', 'ELSE', 'FINALLY'].concat EXPRESSION_END
    #

    Tokens that, if followed by an IMPLICIT_CALL, indicate a function invocation.

    IMPLICIT_FUNC    = ['IDENTIFIER', 'SUPER', ')', 'CALL_END', ']', 'INDEX_END', '@', 'THIS']
    #

    If preceded by an IMPLICIT_FUNC, indicates a function invocation.

    IMPLICIT_CALL    = [
    +  'IDENTIFIER', 'NUMBER', 'STRING', 'JS', 'REGEX', 'NEW', 'PARAM_START', 'CLASS',
    +  'IF', 'UNLESS', 'TRY', 'SWITCH', 'THIS', 'NULL', 'UNARY'
    +  'TRUE', 'FALSE', 'YES', 'NO', 'ON', 'OFF',
    +  '@', '->', '=>', '[', '(', '{'
    +]
    #

    Tokens indicating that the implicit call must enclose a block of expressions.

    IMPLICIT_BLOCK   = ['->', '=>', '{', '[', ',']
    #

    Tokens that always mark the end of an implicit call for single-liners.

    IMPLICIT_END     = ['POST_IF', 'POST_UNLESS', 'FOR', 'WHILE', 'UNTIL', 'LOOP', 'TERMINATOR', 'INDENT']
    #

    Single-line flavors of block expressions that have unclosed endings. +The grammar can't disambiguate them, so we insert the implicit indentation.

    SINGLE_LINERS    = ['ELSE', "->", "=>", 'TRY', 'FINALLY', 'THEN']
    +SINGLE_CLOSERS   = ['TERMINATOR', 'CATCH', 'FINALLY', 'ELSE', 'OUTDENT', 'LEADING_WHEN']
    #

    Tokens that end a line.

    LINEBREAKS       = ['TERMINATOR', 'INDENT', 'OUTDENT']
    +
    +
    \ No newline at end of file diff --git a/node_modules/jade/support/coffee-script/documentation/docs/scope.html b/node_modules/jade/support/coffee-script/documentation/docs/scope.html new file mode 100644 index 0000000..661d5b3 --- /dev/null +++ b/node_modules/jade/support/coffee-script/documentation/docs/scope.html @@ -0,0 +1,57 @@ + scope.coffee

    scope.coffee

    #

    The Scope class regulates lexical scoping within CoffeeScript. As you +generate code, you create a tree of scopes in the same shape as the nested +function bodies. Each scope knows about the variables declared within it, +and has a reference to its parent enclosing scope. In this way, we know which +variables are new and need to be declared with var, and which are shared +with the outside.

    #

    Import the helpers we plan to use.

    {extend} = require('./helpers').helpers
    +
    +exports.Scope = class Scope
    #

    The top-level Scope object.

      @root: null
    #

    Initialize a scope with its parent, for lookups up the chain, +as well as a reference to the Expressions node is belongs to, which is +where it should declare its variables, and a reference to the function that +it wraps.

      constructor: (parent, expressions, method) ->
    +    [@parent, @expressions, @method] = [parent, expressions, method]
    +    @variables = {}
    +    if @parent
    +      @garbage = @parent.garbage
    +    else
    +      @garbage   = []
    +      Scope.root = this
    #

    Create a new garbage level

      startLevel: ->
    +    @garbage.push []
    #

    Return to the previous garbage level and erase referenced temporary +variables in current level from scope.

      endLevel: ->
    +    (@variables[name] = 'reuse') for name in @garbage.pop() when @variables[name] is 'var'
    #

    Look up a variable name in lexical scope, and declare it if it does not +already exist.

      find: (name, options) ->
    +    return true if @check name, options
    +    @variables[name] = 'var'
    +    false
    #

    Test variables and return true the first time fn(v, k) returns true

      any: (fn) ->
    +    for v, k of @variables when fn(v, k)
    +      return true
    +    return false
    #

    Reserve a variable name as originating from a function parameter for this +scope. No var required for internal references.

      parameter: (name) ->
    +    @variables[name] = 'param'
    #

    Just check to see if a variable has already been declared, without reserving, +walks up to the root scope.

      check: (name, options) ->
    +    immediate = Object::hasOwnProperty.call @variables, name
    +    return immediate if immediate or (options and options.immediate)
    +    !!(@parent and @parent.check(name))
    #

    Generate a temporary variable name at the given index.

      temporary: (type, index) ->
    +    if type.length > 1
    +      '_' + type + if index > 1 then index else ''
    +    else
    +      '_' + (index + parseInt type, 36).toString(36).replace /\d/g, 'a'
    #

    If we need to store an intermediate result, find an available name for a +compiler-generated variable. _var, _var2, and so on...

      freeVariable: (type) ->
    +    index = 0
    +    index++ while @check(temp = @temporary type, index) and @variables[temp] isnt 'reuse'
    +    @variables[temp] = 'var'
    +    @garbage[@garbage.length - 1].push temp if @garbage.length
    +    temp
    #

    Ensure that an assignment is made at the top of this scope +(or at the top-level scope, if requested).

      assign: (name, value) ->
    +    @variables[name] = value: value, assigned: true
    #

    Does this scope reference any variables that need to be declared in the +given function body?

      hasDeclarations: (body) ->
    +    body is @expressions and @any (k, val) -> val is 'var' or val is 'reuse'
    #

    Does this scope reference any assignments that need to be declared at the +top of the given function body?

      hasAssignments: (body) ->
    +    body is @expressions and @any (k, val) -> val.assigned
    #

    Return the list of variables first declared in this scope.

      declaredVariables: ->
    +    (key for key, val of @variables when val is 'var' or val is 'reuse').sort()
    #

    Return the list of assignments that are supposed to be made at the top +of this scope.

      assignedVariables: ->
    +    "#{key} = #{val.value}" for key, val of @variables when val.assigned
    #

    Compile the JavaScript for all of the variable declarations in this scope.

      compiledDeclarations: ->
    +    @declaredVariables().join ', '
    #

    Compile the JavaScript forall of the variable assignments in this scope.

      compiledAssignments: ->
    +    @assignedVariables().join ', '
    +
    +
    \ No newline at end of file diff --git a/node_modules/jade/support/coffee-script/documentation/docs/underscore.html b/node_modules/jade/support/coffee-script/documentation/docs/underscore.html new file mode 100644 index 0000000..d812711 --- /dev/null +++ b/node_modules/jade/support/coffee-script/documentation/docs/underscore.html @@ -0,0 +1,296 @@ + underscore.coffee

    underscore.coffee

    #
    #

    Underscore.coffee +(c) 2010 Jeremy Ashkenas, DocumentCloud Inc. +Underscore is freely distributable under the terms of the +MIT license. +Portions of Underscore are inspired by or borrowed from +Prototype.js, Oliver Steele's +Functional, and John Resig's +Micro-Templating. +For all details and documentation: +http://documentcloud.github.com/underscore/

    #

    Baseline setup

    #

    Establish the root object, window in the browser, or global on the server.

      root = this
    #

    Save the previous value of the _ variable.

      previousUnderscore = root._
    #

    Establish the object that gets thrown to break out of a loop iteration. +StopIteration is SOP on Mozilla.

      breaker = if typeof(StopIteration) is 'undefined' then '__break__' else StopIteration
    #

    Helper function to escape RegExp contents, because JS doesn't have one.

      escapeRegExp = (string) -> string.replace(/([.*+?^${}()|[\]\/\\])/g, '\\$1')
    #

    Save bytes in the minified (but not gzipped) version:

      ArrayProto           = Array.prototype
    +  ObjProto             = Object.prototype
    #

    Create quick reference variables for speed access to core prototypes.

      slice                = ArrayProto.slice
    +  unshift              = ArrayProto.unshift
    +  toString             = ObjProto.toString
    +  hasOwnProperty       = ObjProto.hasOwnProperty
    +  propertyIsEnumerable = ObjProto.propertyIsEnumerable
    #

    All ECMA5 native implementations we hope to use are declared here.

      nativeForEach        = ArrayProto.forEach
    +  nativeMap            = ArrayProto.map
    +  nativeReduce         = ArrayProto.reduce
    +  nativeReduceRight    = ArrayProto.reduceRight
    +  nativeFilter         = ArrayProto.filter
    +  nativeEvery          = ArrayProto.every
    +  nativeSome           = ArrayProto.some
    +  nativeIndexOf        = ArrayProto.indexOf
    +  nativeLastIndexOf    = ArrayProto.lastIndexOf
    +  nativeIsArray        = Array.isArray
    +  nativeKeys           = Object.keys
    #

    Create a safe reference to the Underscore object for use below.

      _ = (obj) -> new wrapper(obj)
    #

    Export the Underscore object for CommonJS.

      if typeof(exports) != 'undefined' then exports._ = _
    #

    Export Underscore to global scope.

      root._ = _
    #

    Current version.

      _.VERSION = '1.1.0'
    #

    Collection Functions

    #

    The cornerstone, an each implementation. +Handles objects implementing forEach, arrays, and raw objects.

      _.each = (obj, iterator, context) ->
    +    try
    +      if nativeForEach and obj.forEach is nativeForEach
    +        obj.forEach iterator, context
    +      else if _.isNumber obj.length
    +        iterator.call(context, obj[i], i, obj) for i in [0...obj.length]
    +      else
    +        iterator.call(context, val, key, obj) for key, val of obj
    +    catch e
    +      throw e if e isnt breaker
    +    obj
    #

    Return the results of applying the iterator to each element. Use JavaScript +1.6's version of map, if possible.

      _.map = (obj, iterator, context) ->
    +    return obj.map(iterator, context) if nativeMap and obj.map is nativeMap
    +    results = []
    +    _.each obj, (value, index, list) ->
    +      results.push iterator.call context, value, index, list
    +    results
    #

    Reduce builds up a single result from a list of values. Also known as +inject, or foldl. Uses JavaScript 1.8's version of reduce, if possible.

      _.reduce = (obj, iterator, memo, context) ->
    +    if nativeReduce and obj.reduce is nativeReduce
    +      iterator = _.bind iterator, context if context
    +      return obj.reduce iterator, memo
    +    _.each obj, (value, index, list) ->
    +      memo = iterator.call context, memo, value, index, list
    +    memo
    #

    The right-associative version of reduce, also known as foldr. Uses +JavaScript 1.8's version of reduceRight, if available.

      _.reduceRight = (obj, iterator, memo, context) ->
    +    if nativeReduceRight and obj.reduceRight is nativeReduceRight
    +      iterator = _.bind iterator, context if context
    +      return obj.reduceRight iterator, memo
    +    reversed = _.clone(_.toArray(obj)).reverse()
    +    _.reduce reversed, iterator, memo, context
    #

    Return the first value which passes a truth test.

      _.detect = (obj, iterator, context) ->
    +    result = null
    +    _.each obj, (value, index, list) ->
    +      if iterator.call context, value, index, list
    +        result = value
    +        _.breakLoop()
    +    result
    #

    Return all the elements that pass a truth test. Use JavaScript 1.6's +filter, if it exists.

      _.filter = (obj, iterator, context) ->
    +    return obj.filter iterator, context if nativeFilter and obj.filter is nativeFilter
    +    results = []
    +    _.each obj, (value, index, list) ->
    +      results.push value if iterator.call context, value, index, list
    +    results
    #

    Return all the elements for which a truth test fails.

      _.reject = (obj, iterator, context) ->
    +    results = []
    +    _.each obj, (value, index, list) ->
    +      results.push value if not iterator.call context, value, index, list
    +    results
    #

    Determine whether all of the elements match a truth test. Delegate to +JavaScript 1.6's every, if it is present.

      _.every = (obj, iterator, context) ->
    +    iterator ||= _.identity
    +    return obj.every iterator, context if nativeEvery and obj.every is nativeEvery
    +    result = true
    +    _.each obj, (value, index, list) ->
    +      _.breakLoop() unless (result = result and iterator.call(context, value, index, list))
    +    result
    #

    Determine if at least one element in the object matches a truth test. Use +JavaScript 1.6's some, if it exists.

      _.some = (obj, iterator, context) ->
    +    iterator ||= _.identity
    +    return obj.some iterator, context if nativeSome and obj.some is nativeSome
    +    result = false
    +    _.each obj, (value, index, list) ->
    +      _.breakLoop() if (result = iterator.call(context, value, index, list))
    +    result
    #

    Determine if a given value is included in the array or object, +based on ===.

      _.include = (obj, target) ->
    +    return _.indexOf(obj, target) isnt -1 if nativeIndexOf and obj.indexOf is nativeIndexOf
    +    for key, val of obj
    +      return true if val is target
    +    false
    #

    Invoke a method with arguments on every item in a collection.

      _.invoke = (obj, method) ->
    +    args = _.rest arguments, 2
    +    (if method then val[method] else val).apply(val, args) for val in obj
    #

    Convenience version of a common use case of map: fetching a property.

      _.pluck = (obj, key) ->
    +    _.map(obj, (val) -> val[key])
    #

    Return the maximum item or (item-based computation).

      _.max = (obj, iterator, context) ->
    +    return Math.max.apply(Math, obj) if not iterator and _.isArray(obj)
    +    result = computed: -Infinity
    +    _.each obj, (value, index, list) ->
    +      computed = if iterator then iterator.call(context, value, index, list) else value
    +      computed >= result.computed and (result = {value: value, computed: computed})
    +    result.value
    #

    Return the minimum element (or element-based computation).

      _.min = (obj, iterator, context) ->
    +    return Math.min.apply(Math, obj) if not iterator and _.isArray(obj)
    +    result = computed: Infinity
    +    _.each obj, (value, index, list) ->
    +      computed = if iterator then iterator.call(context, value, index, list) else value
    +      computed < result.computed and (result = {value: value, computed: computed})
    +    result.value
    #

    Sort the object's values by a criterion produced by an iterator.

      _.sortBy = (obj, iterator, context) ->
    +    _.pluck(((_.map obj, (value, index, list) ->
    +      {value: value, criteria: iterator.call(context, value, index, list)}
    +    ).sort((left, right) ->
    +      a = left.criteria; b = right.criteria
    +      if a < b then -1 else if a > b then 1 else 0
    +    )), 'value')
    #

    Use a comparator function to figure out at what index an object should +be inserted so as to maintain order. Uses binary search.

      _.sortedIndex = (array, obj, iterator) ->
    +    iterator ||= _.identity
    +    low =  0
    +    high = array.length
    +    while low < high
    +      mid = (low + high) >> 1
    +      if iterator(array[mid]) < iterator(obj) then low = mid + 1 else high = mid
    +    low
    #

    Convert anything iterable into a real, live array.

      _.toArray = (iterable) ->
    +    return []                   if (!iterable)
    +    return iterable.toArray()   if (iterable.toArray)
    +    return iterable             if (_.isArray(iterable))
    +    return slice.call(iterable) if (_.isArguments(iterable))
    +    _.values(iterable)
    #

    Return the number of elements in an object.

      _.size = (obj) -> _.toArray(obj).length
    #

    Array Functions

    #

    Get the first element of an array. Passing n will return the first N +values in the array. Aliased as head. The guard check allows it to work +with map.

      _.first = (array, n, guard) ->
    +    if n and not guard then slice.call(array, 0, n) else array[0]
    #

    Returns everything but the first entry of the array. Aliased as tail. +Especially useful on the arguments object. Passing an index will return +the rest of the values in the array from that index onward. The guard +check allows it to work with map.

      _.rest = (array, index, guard) ->
    +    slice.call(array, if _.isUndefined(index) or guard then 1 else index)
    #

    Get the last element of an array.

      _.last = (array) -> array[array.length - 1]
    #

    Trim out all falsy values from an array.

      _.compact = (array) -> item for item in array when item
    #

    Return a completely flattened version of an array.

      _.flatten = (array) ->
    +    _.reduce array, (memo, value) ->
    +      return memo.concat(_.flatten(value)) if _.isArray value
    +      memo.push value
    +      memo
    +    , []
    #

    Return a version of the array that does not contain the specified value(s).

      _.without = (array) ->
    +    values = _.rest arguments
    +    val for val in _.toArray(array) when not _.include values, val
    #

    Produce a duplicate-free version of the array. If the array has already +been sorted, you have the option of using a faster algorithm.

      _.uniq = (array, isSorted) ->
    +    memo = []
    +    for el, i in _.toArray array
    +      memo.push el if i is 0 || (if isSorted is true then _.last(memo) isnt el else not _.include(memo, el))
    +    memo
    #

    Produce an array that contains every item shared between all the +passed-in arrays.

      _.intersect = (array) ->
    +    rest = _.rest arguments
    +    _.select _.uniq(array), (item) ->
    +      _.all rest, (other) ->
    +        _.indexOf(other, item) >= 0
    #

    Zip together multiple lists into a single array -- elements that share +an index go together.

      _.zip = ->
    +    length =  _.max _.pluck arguments, 'length'
    +    results = new Array length
    +    for i in [0...length]
    +      results[i] = _.pluck arguments, String i
    +    results
    #

    If the browser doesn't supply us with indexOf (I'm looking at you, MSIE), +we need this function. Return the position of the first occurence of an +item in an array, or -1 if the item is not included in the array.

      _.indexOf = (array, item) ->
    +    return array.indexOf item if nativeIndexOf and array.indexOf is nativeIndexOf
    +    i = 0; l = array.length
    +    while l - i
    +      if array[i] is item then return i else i++
    +    -1
    #

    Provide JavaScript 1.6's lastIndexOf, delegating to the native function, +if possible.

      _.lastIndexOf = (array, item) ->
    +    return array.lastIndexOf(item) if nativeLastIndexOf and array.lastIndexOf is nativeLastIndexOf
    +    i = array.length
    +    while i
    +      if array[i] is item then return i else i--
    +    -1
    #

    Generate an integer Array containing an arithmetic progression. A port of +the native Python range function.

      _.range = (start, stop, step) ->
    +    a         = arguments
    +    solo      = a.length <= 1
    +    i = start = if solo then 0 else a[0]
    +    stop      = if solo then a[0] else a[1]
    +    step      = a[2] or 1
    +    len       = Math.ceil((stop - start) / step)
    +    return []   if len <= 0
    +    range     = new Array len
    +    idx       = 0
    +    loop
    +      return range if (if step > 0 then i - stop else stop - i) >= 0
    +      range[idx] = i
    +      idx++
    +      i+= step
    #

    Function Functions

    #

    Create a function bound to a given object (assigning this, and arguments, +optionally). Binding with arguments is also known as curry.

      _.bind = (func, obj) ->
    +    args = _.rest arguments, 2
    +    -> func.apply obj or root, args.concat arguments
    #

    Bind all of an object's methods to that object. Useful for ensuring that +all callbacks defined on an object belong to it.

      _.bindAll = (obj) ->
    +    funcs = if arguments.length > 1 then _.rest(arguments) else _.functions(obj)
    +    _.each funcs, (f) -> obj[f] = _.bind obj[f], obj
    +    obj
    #

    Delays a function for the given number of milliseconds, and then calls +it with the arguments supplied.

      _.delay = (func, wait) ->
    +    args = _.rest arguments, 2
    +    setTimeout((-> func.apply(func, args)), wait)
    #

    Memoize an expensive function by storing its results.

      _.memoize = (func, hasher) ->
    +    memo = {}
    +    hasher or= _.identity
    +    ->
    +      key = hasher.apply this, arguments
    +      return memo[key] if key of memo
    +      memo[key] = func.apply this, arguments
    #

    Defers a function, scheduling it to run after the current call stack has +cleared.

      _.defer = (func) ->
    +    _.delay.apply _, [func, 1].concat _.rest arguments
    #

    Returns the first function passed as an argument to the second, +allowing you to adjust arguments, run code before and after, and +conditionally execute the original function.

      _.wrap = (func, wrapper) ->
    +    -> wrapper.apply wrapper, [func].concat arguments
    #

    Returns a function that is the composition of a list of functions, each +consuming the return value of the function that follows.

      _.compose = ->
    +    funcs = arguments
    +    ->
    +      args = arguments
    +      for i in [(funcs.length - 1)..0]
    +        args = [funcs[i].apply(this, args)]
    +      args[0]
    #

    Object Functions

    #

    Retrieve the names of an object's properties.

      _.keys = nativeKeys or (obj) ->
    +    return _.range 0, obj.length if _.isArray(obj)
    +    key for key, val of obj
    #

    Retrieve the values of an object's properties.

      _.values = (obj) ->
    +    _.map obj, _.identity
    #

    Return a sorted list of the function names available in Underscore.

      _.functions = (obj) ->
    +    _.filter(_.keys(obj), (key) -> _.isFunction(obj[key])).sort()
    #

    Extend a given object with all of the properties in a source object.

      _.extend = (obj) ->
    +    for source in _.rest(arguments)
    +      (obj[key] = val) for key, val of source
    +    obj
    #

    Create a (shallow-cloned) duplicate of an object.

      _.clone = (obj) ->
    +    return obj.slice 0 if _.isArray obj
    +    _.extend {}, obj
    #

    Invokes interceptor with the obj, and then returns obj. +The primary purpose of this method is to "tap into" a method chain, in order to perform operations on intermediate results within the chain.

      _.tap = (obj, interceptor) ->
    +    interceptor obj
    +    obj
    #

    Perform a deep comparison to check if two objects are equal.

      _.isEqual = (a, b) ->
    #

    Check object identity.

        return true if a is b
    #

    Different types?

        atype = typeof(a); btype = typeof(b)
    +    return false if atype isnt btype
    #

    Basic equality test (watch out for coercions).

        return true if `a == b`
    #

    One is falsy and the other truthy.

        return false if (!a and b) or (a and !b)
    #

    One of them implements an isEqual()?

        return a.isEqual(b) if a.isEqual
    #

    Check dates' integer values.

        return a.getTime() is b.getTime() if _.isDate(a) and _.isDate(b)
    #

    Both are NaN?

        return false if _.isNaN(a) and _.isNaN(b)
    #

    Compare regular expressions.

        if _.isRegExp(a) and _.isRegExp(b)
    +      return a.source     is b.source and
    +             a.global     is b.global and
    +             a.ignoreCase is b.ignoreCase and
    +             a.multiline  is b.multiline
    #

    If a is not an object by this point, we can't handle it.

        return false if atype isnt 'object'
    #

    Check for different array lengths before comparing contents.

        return false if a.length and (a.length isnt b.length)
    #

    Nothing else worked, deep compare the contents.

        aKeys = _.keys(a); bKeys = _.keys(b)
    #

    Different object sizes?

        return false if aKeys.length isnt bKeys.length
    #

    Recursive comparison of contents.

        (return false) for all key, val of a when !(key of b) or !_.isEqual(val, b[key])
    +    true
    #

    Is a given array or object empty?

      _.isEmpty = (obj) ->
    +    return obj.length is 0 if _.isArray(obj) or _.isString(obj)
    +    (return false) for key of obj when hasOwnProperty.call(obj, key)
    +    true
    #

    Is a given value a DOM element?

      _.isElement   = (obj) -> obj and obj.nodeType is 1
    #

    Is a given value an array?

      _.isArray     = nativeIsArray or (obj) -> !!(obj and obj.concat and obj.unshift and not obj.callee)
    #

    Is a given variable an arguments object?

      _.isArguments = (obj) -> obj and obj.callee
    #

    Is the given value a function?

      _.isFunction  = (obj) -> !!(obj and obj.constructor and obj.call and obj.apply)
    #

    Is the given value a string?

      _.isString    = (obj) -> !!(obj is '' or (obj and obj.charCodeAt and obj.substr))
    #

    Is a given value a number?

      _.isNumber    = (obj) -> (obj is +obj) or toString.call(obj) is '[object Number]'
    #

    Is a given value a boolean?

      _.isBoolean   = (obj) -> obj is true or obj is false
    #

    Is a given value a Date?

      _.isDate      = (obj) -> !!(obj and obj.getTimezoneOffset and obj.setUTCFullYear)
    #

    Is the given value a regular expression?

      _.isRegExp    = (obj) -> !!(obj and obj.exec and (obj.ignoreCase or obj.ignoreCase is false))
    #

    Is the given value NaN -- this one is interesting. NaN != NaN, and +isNaN(undefined) == true, so we make sure it's a number first.

      _.isNaN       = (obj) -> _.isNumber(obj) and window.isNaN(obj)
    #

    Is a given value equal to null?

      _.isNull      = (obj) -> obj is null
    #

    Is a given variable undefined?

      _.isUndefined = (obj) -> typeof obj is 'undefined'
    #

    Utility Functions

    #

    Run Underscore.js in noConflict mode, returning the _ variable to its +previous owner. Returns a reference to the Underscore object.

      _.noConflict = ->
    +    root._ = previousUnderscore
    +    this
    #

    Keep the identity function around for default iterators.

      _.identity = (value) -> value
    #

    Run a function n times.

      _.times = (n, iterator, context) ->
    +    iterator.call(context, i) for i in [0...n]
    #

    Break out of the middle of an iteration.

      _.breakLoop = -> throw breaker
    #

    Add your own custom functions to the Underscore object, ensuring that +they're correctly added to the OOP wrapper as well.

      _.mixin = (obj) ->
    +    for name in _.functions(obj)
    +      addToWrapper name, _[name] = obj[name]
    #

    Generate a unique integer id (unique within the entire client session). +Useful for temporary DOM ids.

      idCounter = 0
    +  _.uniqueId = (prefix) ->
    +    (prefix or '') + idCounter++
    #

    By default, Underscore uses ERB-style template delimiters, change the +following template settings to use alternative delimiters.

      _.templateSettings = {
    +    start:        '<%'
    +    end:          '%>'
    +    interpolate:  /<%=(.+?)%>/g
    +  }
    #

    JavaScript templating a-la ERB, pilfered from John Resig's +Secrets of the JavaScript Ninja, page 83. +Single-quote fix from Rick Strahl. +With alterations for arbitrary delimiters, and to preserve whitespace.

      _.template = (str, data) ->
    +    c = _.templateSettings
    +    endMatch = new RegExp("'(?=[^"+c.end.substr(0, 1)+"]*"+escapeRegExp(c.end)+")","g")
    +    fn = new Function 'obj',
    +      'var p=[],print=function(){p.push.apply(p,arguments);};' +
    +      'with(obj||{}){p.push(\'' +
    +      str.replace(/\r/g, '\\r')
    +         .replace(/\n/g, '\\n')
    +         .replace(/\t/g, '\\t')
    +         .replace(endMatch,"✄")
    +         .split("'").join("\\'")
    +         .split("✄").join("'")
    +         .replace(c.interpolate, "',$1,'")
    +         .split(c.start).join("');")
    +         .split(c.end).join("p.push('") +
    +         "');}return p.join('');"
    +    if data then fn(data) else fn
    #

    Aliases

      _.forEach  = _.each
    +  _.foldl    = _.inject = _.reduce
    +  _.foldr    = _.reduceRight
    +  _.select   = _.filter
    +  _.all      = _.every
    +  _.any      = _.some
    +  _.contains = _.include
    +  _.head     = _.first
    +  _.tail     = _.rest
    +  _.methods  = _.functions
    #

    Setup the OOP Wrapper

    #

    If Underscore is called as a function, it returns a wrapped object that +can be used OO-style. This wrapper holds altered versions of all the +underscore functions. Wrapped objects may be chained.

      wrapper = (obj) ->
    +    this._wrapped = obj
    +    this
    #

    Helper function to continue chaining intermediate results.

      result = (obj, chain) ->
    +    if chain then _(obj).chain() else obj
    #

    A method to easily add functions to the OOP wrapper.

      addToWrapper = (name, func) ->
    +    wrapper.prototype[name] = ->
    +      args = _.toArray arguments
    +      unshift.call args, this._wrapped
    +      result func.apply(_, args), this._chain
    #

    Add all of the Underscore functions to the wrapper object.

      _.mixin _
    #

    Add all mutator Array functions to the wrapper.

      _.each ['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], (name) ->
    +    method = Array.prototype[name]
    +    wrapper.prototype[name] = ->
    +      method.apply(this._wrapped, arguments)
    +      result(this._wrapped, this._chain)
    #

    Add all accessor Array functions to the wrapper.

      _.each ['concat', 'join', 'slice'], (name) ->
    +    method = Array.prototype[name]
    +    wrapper.prototype[name] = ->
    +      result(method.apply(this._wrapped, arguments), this._chain)
    #

    Start chaining a wrapped Underscore object.

      wrapper::chain = ->
    +    this._chain = true
    +    this
    #

    Extracts the result from a wrapped and chained object.

      wrapper::value = -> this._wrapped
    +
    +
    \ No newline at end of file diff --git a/node_modules/jade/support/coffee-script/documentation/images/favicon.ico b/node_modules/jade/support/coffee-script/documentation/images/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..ecf4a86584314832ad9469e1bd05a751b479e04e GIT binary patch literal 1406 zcmZQzU<5(|0R}M0U}azs1F|%L7$l?s#Ec9aKoZP=&}i)Sr#~>v-}9KkxbzG|&+01- z3{pW1>M2_pDwaKF2%Y?l;qaBm2z{fh(GVC7f#DMZY^)H#2JsRr8w>yo5+Gn@V`O4s z=U`@L!{7t;p~wR@vZAWT&xfjq+XpcZ>Krf!>;g_sP6iN$11tgz$SNR;;X3eh8|;DR p%0n?TkY)s8Nhk)fL1IApBlQdnkAP}F1KE$~GcX(nvis^87yw!E9U1@t literal 0 HcmV?d00001 diff --git a/node_modules/jade/support/coffee-script/documentation/images/logo.png b/node_modules/jade/support/coffee-script/documentation/images/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..2b1e40a4e87914c33e888c63c26409337956c636 GIT binary patch literal 6059 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 literal 0 HcmV?d00001 diff --git a/node_modules/jade/support/coffee-script/documentation/index.html.erb b/node_modules/jade/support/coffee-script/documentation/index.html.erb new file mode 100644 index 0000000..ad79164 --- /dev/null +++ b/node_modules/jade/support/coffee-script/documentation/index.html.erb @@ -0,0 +1,1364 @@ +<% + require 'uv' + def code_for(file, executable=false) + return '' unless File.exists?("documentation/js/#{file}.js") + cs = File.read("documentation/coffee/#{file}.coffee") + js = File.read("documentation/js/#{file}.js") + cshtml = Uv.parse(cs, 'xhtml', 'coffeescript', false, 'idle', false) + jshtml = Uv.parse(js, 'xhtml', 'javascript', false, 'idle', false) + append = executable == true ? '' : "alert(#{executable});" + run = executable == true ? 'run' : "run: #{executable}" + button = executable ? "" : '' + "
    #{cshtml}#{jshtml}#{button}
    " + end +%> + + + + + + + CoffeeScript + + + + + + +
    + + + +
    + + +

    + CoffeeScript is a little language that compiles into JavaScript. Think + of it as JavaScript's less ostentatious kid brother — the same genes, + roughly the same height, but a different sense of style. Apart from a handful of + bonus goodies, statements in CoffeeScript correspond one-to-one with their + equivalent in JavaScript, it's just another way of saying it. +

    + +

    + Disclaimer: + CoffeeScript is just for fun. Until it reaches 1.0, there are no guarantees + that the syntax won't change between versions. That said, + it compiles into clean JavaScript (the good parts) that can use existing + JavaScript libraries seamlessly, and passes through + JSLint without warnings. The compiled + output is pretty-printed and quite readable. +

    + +

    + Latest Version: + 0.9.4 +

    + +

    + + Mini Overview +

    + +

    CoffeeScript on the left, compiled JavaScript output on the right.

    + + <%= code_for('overview', 'cubes') %> + +

    + For a longer CoffeeScript example, check out + Underscore.coffee, a port + of the Underscore.js + library of helper functions. Underscore.coffee can pass the entire Underscore.js + test suite. The CoffeeScript version is faster than the original for a number + of methods (in general, due to the speed of CoffeeScript's array comprehensions), and + after being minified and gzipped, is only 241 bytes larger than the original + JavaScript version. + Additional examples are included in the source repository, inside the + examples folder. +

    + +

    + + Installation and Usage +

    + +

    + The CoffeeScript compiler is written in pure CoffeeScript, using a + small DSL + on top of the Jison parser generator, and is available + as a Node.js utility. The core compiler however, + does not depend on Node, and can be run in other server-side-JavaScript environments, + or in the browser (see "Try CoffeeScript", above). +

    + +

    + To install, first make sure you have a working copy of the latest tagged version of + Node.js, currently 0.1.102 or higher. + Then clone the CoffeeScript + source repository + from GitHub, or download the latest + release: 0.9.4. + To install the CoffeeScript compiler system-wide + under /usr/local, open the directory and run: +

    + +
    +sudo bin/cake install
    + +

    + Alternatively, if you already have the + Node Package Manager installed, + you can use that to grab the latest CoffeeScript: +

    + +
    +sudo npm install coffee-script
    + +

    + Both of these provide the coffee command, which will execute CoffeeScripts + under Node.js by default, but is also used to compile CoffeeScript + .coffee files into JavaScript, or to run an an interactive REPL. + When compiling to JavaScript, coffee writes the output + as .js files in the same directory by default, but output + can be customized with the following options: +

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    -c, --compile + Compile a .coffee script into a .js JavaScript file + of the same name. +
    -i, --interactive + Launch an interactive CoffeeScript session to try short snippets. + More pleasant if wrapped with + rlwrap. +
    -o, --output [DIR] + Write out all compiled JavaScript files into the specified directory. + Use in conjunction with --compile or --watch. +
    -w, --watch + Watch the modification times of the coffee-scripts, recompiling as + soon as a change occurs. +
    -p, --print + Instead of writing out the JavaScript as a file, print it + directly to stdout. +
    -l, --lint + If the jsl + (JavaScript Lint) + command is installed, use it + to check the compilation of a CoffeeScript file. (Handy in + conjunction with
    --watch) +
    -s, --stdio + Pipe in CoffeeScript to STDIN and get back JavaScript over STDOUT. + Good for use with processes written in other languages. An example:
    + cat src/cake.coffee | coffee -sc +
    -e, --eval + Compile and print a little snippet of CoffeeScript directly from the + command line. For example:
    coffee -e "puts num for num in [10..1]" +
    -r, --require + Load a library before compiling or executing your script. Can be used + to hook in to the compiler (to add Growl notifications, for example). +
    -b, --bare + Compile the JavaScript without the top-level function safety wrapper. + (Used for CoffeeScript as a Node.js module.) +
    -t, --tokens + Instead of parsing the CoffeeScript, just lex it, and print out the + token stream: [IDENTIFIER square] [ASSIGN =] [PARAM_START (] ... +
    -n, --nodes + Instead of compiling the CoffeeScript, just lex and parse it, and print + out the parse tree: +
    +Expressions
    +  Assign
    +    Value "square"
    +    Code "x"
    +      Op *
    +        Value "x"
    +        Value "x"
    +
    + +

    + Examples: +

    + +
    +coffee -c path/to/script.coffee
    +coffee --interactive
    +coffee --watch --lint experimental.coffee
    +coffee --print app/scripts/*.coffee > concatenation.js
    + +

    + + Language Reference +

    + +

    + + This reference is structured so that it can be read from top to bottom, + if you like. Later sections use ideas and syntax previously introduced. + Familiarity with JavaScript is assumed. + In all of the following examples, the source CoffeeScript is provided on + the left, and the direct compilation into JavaScript is on the right. + +

    + +

    + + Many of the examples can be run (where it makes sense) by pressing the "run" + button towards the bottom right. You can also paste examples into + "Try CoffeeScript" in the toolbar, and play with them from there. + +

    + + Significant Whitespace + CoffeeScript uses Python-style significant whitespace: You don't need to + use semicolons ; to terminate expressions, ending + the line will do just as well. Semicolons can still be used to fit + multiple expressions onto a single line. Instead of using curly braces + { } to delimit blocks of code (like functions, + if-statements, + switch, and try/catch), + use indentation. +

    + +

    + You don't need to use parentheses to invoke a function if you're passing + arguments:
    print "coffee". Implicit parentheses wrap forwards + to the end of the line, or block expression. +

    + +

    + You can use newlines to break up your expression into smaller pieces, + as long as CoffeeScript can determine that the line hasn't finished yet, + because it ends with an operator or a dot ... seen most commonly + in jQuery-chaining style JavaScript. +

    + +

    + + Functions and Invocation + Functions are defined by a list of parameters, an arrow, and the + function body. The empty function looks like this: -> +

    + <%= code_for('functions', 'cube(5)') %> + +

    + + Objects and Arrays + Object and Array literals look very similar to their JavaScript cousins. + When you spread out each property on a separate line, the commas are + optional. Implicit objects may be created with indentation instead of + brackets, winding up looking quite similar to YAML. +

    + <%= code_for('objects_and_arrays', 'song.join(",")') %> +

    + In JavaScript, you can't use reserved words, like class, as properties + of an object, without quoting them as strings. CoffeeScript notices and quotes + them for you, so you don't have to worry about it (say, when using jQuery). +

    + <%= code_for('objects_reserved') %> + +

    + + Lexical Scoping and Variable Safety + The CoffeeScript compiler takes care to make sure that all of your variables + are properly declared within lexical scope — you never need to write + var yourself. +

    + <%= code_for('scope', 'inner') %> +

    + Notice how all of the variable declarations have been pushed up to + the top of the closest scope, the first time they appear. + outer is not redeclared within the inner function, because it's + already in scope; inner within the function, on the other hand, + should not be able to change the value of the external variable of the same name, and + therefore has a declaration of its own. +

    +

    + This behavior is effectively identical to Ruby's scope for local variables. + Because you don't have direct access to the var keyword, + it's impossible to shadow an outer variable on purpose, you may only refer + to it. So be careful that you're not reusing the name of an external + variable accidentally, if you're writing a deeply nested function. +

    +

    + Although suppressed within this documentation for clarity, all + CoffeeScript output is wrapped in an anonymous function: + (function(){ ... })(); This safety wrapper, combined with the + automatic generation of the var keyword, make it exceedingly difficult + to pollute the global namespace by accident. +

    +

    + If you'd like to create top-level variables for other scripts to use, + attach them as properties on window, or on the exports + object in CommonJS. The existential operator (covered below), gives you a + reliable way to figure out where to add them, if you're targeting both + CommonJS and the browser: root = exports ? this +

    + +

    + + If, Else, Unless, and Conditional Assignment + If/else statements can be written without the use of parentheses and + curly brackets. As with functions and other block expressions, + multi-line conditionals are delimited by indentation. There's also a handy + postfix form, with the if or unless at the end. +

    +

    + CoffeeScript can compile if statements into JavaScript expressions, + using the ternary operator when possible, and closure wrapping otherwise. There + is no explicit ternary statement in CoffeeScript — you simply use + a regular if statement inline. +

    + <%= code_for('conditionals') %> + +

    + + Aliases + Because the == operator frequently causes undesirable coercion, + is intransitive, and has a different meaning than in other languages, + CoffeeScript compiles == into ===, and != into + !==. + In addition, is compiles into ===, + and isnt into !==. +

    +

    + You can use not as an alias for !. +

    +

    + For logic, and compiles to &&, and or + into ||. +

    +

    + Instead of a newline or semicolon, then can be used to separate + conditions from expressions, in while, + if/else, and switch/when statements. +

    +

    + As in YAML, on and yes + are the same as boolean true, while off and no are boolean false. +

    +

    + For single-line statements, unless can be used as the inverse of if. +

    +

    + As a shortcut for this.property, you can use @property. +

    +

    + You can use in to test for array presence, and of to + test for JavaScript object-key presence. +

    + <%= code_for('aliases') %> + +

    + + Splats... + The JavaScript arguments object is a useful way to work with + functions that accept variable numbers of arguments. CoffeeScript provides + splats ..., both for function definition as well as invocation, + making variable numbers of arguments a little bit more palatable. +

    + <%= code_for('splats', true) %> + +

    + + While, Until, and Loop + The only low-level loop that CoffeeScript provides is the while loop. The + main difference from JavaScript is that the while loop can be used + as an expression, returning an array containing the result of each iteration + through the loop. +

    + <%= code_for('while', 'lyrics.join("\n")') %> +

    + For readability, the until keyword is equivalent to while not, + and the loop keyword is equivalent to while true. + Other JavaScript loops, such as for loops and do-while loops + can be mimicked by variations on loop, but the hope is that you + won't need to do that with CoffeeScript, either because you're using + each (forEach) style iterators, or... +

    + +

    + + Comprehensions (Arrays, Objects, and Ranges) + For your looping needs, CoffeeScript provides array comprehensions + similar to Python's. They replace (and compile into) for loops, with + optional guard clauses and the value of the current array index. + Unlike for loops, array comprehensions are expressions, and can be returned + and assigned. They should be able to handle most places where you otherwise + would use a loop, each/forEach, map, or select/filter. +

    + <%= code_for('array_comprehensions') %> +

    + If you know the start and end of your loop, or would like to step through + in fixed-size increments, you can use a range to specify the start and + end of your comprehension. +

    + <%= code_for('range_comprehensions', 'countdown') %> +

    + Comprehensions can also be used to iterate over the keys and values in + an object. Use of to signal comprehension over the properties of + an object instead of the values in an array. +

    + <%= code_for('object_comprehensions', 'ages.join(", ")') %> +

    + By default, object comprehensions are safe, and use a hasOwnProperty + check to make sure that you're dealing with properties on the current + object. If you'd like the regular JavaScript
    for (key in obj) ... + loop, for speed or for another reason, you can use
    + for all key, value of object in CoffeeScript. +

    + +

    + + Array Slicing and Splicing with Ranges + CoffeeScript borrows Ruby's + range syntax + for extracting slices of arrays. With two dots (3..5), the range + is inclusive: the first argument is the index of the first element in + the slice, and the second is the index of the last one. Three dots signify + a range that excludes the end. +

    + <%= code_for('slices', 'copy') %> +

    + The same syntax can be used with assignment to replace a segment of an + array with new values (to splice it). +

    + <%= code_for('splices', 'numbers') %> + +

    + + Everything is an Expression (at least, as much as possible) + You might have noticed how even though we don't add return statements + to CoffeeScript functions, they nonetheless return their final value. + The CoffeeScript compiler tries to make sure that all statements in the + language can be used as expressions. Watch how the return gets + pushed down into each possible branch of execution, in the function + below. +

    + <%= code_for('expressions', 'eldest') %> +

    + Even though functions will always return their final value, it's both possible + and encouraged to return early from a function body writing out the explicit + return (return value), when you know that you're done. +

    +

    + Because variable declarations occur at the top of scope, assignment can + be used within expressions, even for variables that haven't been seen before: +

    + <%= code_for('expressions_assignment', 'six') %> +

    + Things that would otherwise be statements in JavaScript, when used + as part of an expression in CoffeeScript, are converted into expressions + by wrapping them in a closure. This lets you do useful things, like assign + the result of a comprehension to a variable: +

    + <%= code_for('expressions_comprehension', 'globals') %> +

    + As well as silly things, like passing a try/catch statement directly + into a function call: +

    + <%= code_for('expressions_try', true) %> +

    + There are a handful of statements in JavaScript that can't be meaningfully + converted into expressions, namely break, continue, + and return. If you make use of them within a block of code, + CoffeeScript won't try to perform the conversion. +

    + +

    + + The Existential Operator + It's a little difficult to check for the existence of a variable in + JavaScript. if (variable) ... comes close, but fails for zero, + the empty string, and false. CoffeeScript's existential operator ? returns true unless + a variable is null or undefined, which makes it analogous + to Ruby's nil? +

    +

    + It can also be used for safer conditional assignment than ||= + provides, for cases where you may be handling numbers or strings. +

    + <%= code_for('existence', 'speed') %> +

    + The accessor variant of the existential operator ?. can be used to soak + up null references in a chain of properties. Use it instead + of the dot accessor . in cases where the base value may be null + or undefined. If all of the properties exist then you'll get the expected + result, if the chain is broken, undefined is returned instead of + the TypeError that would be raised otherwise. +

    + <%= code_for('soaks') %> +

    + Soaking up nulls is similar to Ruby's + andand gem, and to the + safe navigation operator + in Groovy. +

    + +

    + + Classes, Inheritance, and Super + JavaScript's prototypal inheritance has always been a bit of a + brain-bender, with a whole family tree of libraries that provide a cleaner + syntax for classical inheritance on top of JavaScript's prototypes: + Base2, + Prototype.js, + JS.Class, etc. + The libraries provide syntactic sugar, but the built-in inheritance would + be completely usable if it weren't for a couple of small exceptions: + it's awkward to call super (the prototype object's + implementation of the current function), and it's awkward to correctly + set the prototype chain. +

    +

    + Instead of repetitively attaching functions to a prototype, CoffeeScript + provides a basic class structure that allows you to name your class, + set the superclass, assign prototypal properties, and define the constructor, + in a single assignable expression. +

    + <%= code_for('classes', true) %> +

    + If structuring your prototypes classically isn't your cup of tea, CoffeeScript + provides a couple of lower-level conveniences. The extends operator + helps with proper prototype setup, :: gives you + quick access to an object's prototype, and super() + is converted into a call against the immediate ancestor's method of the same name. +

    + <%= code_for('prototypes', '"one_two".dasherize()') %> +

    + Finally, you may assign Class-level (static) properties within a class + definition by using
    @property: value +

    + +

    + + Pattern Matching (Destructuring Assignment) + To make extracting values from complex arrays and objects more convenient, + CoffeeScript implements ECMAScript Harmony's proposed + destructuring assignment + syntax. When you assign an array or object literal to a value, CoffeeScript + breaks up and matches both sides against each other, assigning the values + on the right to the variables on the left. In the simplest case, it can be + used for parallel assignment: +

    + <%= code_for('parallel_assignment', 'theBait') %> +

    + But it's also helpful for dealing with functions that return multiple + values. +

    + <%= code_for('multiple_return_values', 'forecast') %> +

    + Pattern matching can be used with any depth of array and object nesting, + to help pull out deeply nested properties. +

    + <%= code_for('object_extraction', 'name + " — " + street') %> +

    + Pattern matching can even be combined with splats. +

    + <%= code_for('patterns_and_splats', 'contents.join("")') %> + +

    + + Function binding + In JavaScript, the this keyword is dynamically scoped to mean the + object that the current function is attached to. If you pass a function as + as callback, or attach it to a different object, the original value of this + will be lost. If you're not familiar with this behavior, + this Digital Web article + gives a good overview of the quirks. +

    +

    + The fat arrow => can be used to both define a function, and to bind + it to the current value of this, right on the spot. This is helpful + when using callback-based libraries like Prototype or jQuery, for creating + iterator functions to pass to each, or event-handler functions + to use with bind. Functions created with the fat arrow are able to access + properties of the this where they're defined. +

    + <%= code_for('fat_arrow') %> +

    + If we had used -> in the callback above, @customer would + have referred to the undefined "customer" property of the DOM element, + and trying to call purchase() on it would have raised an exception. +

    + +

    + + Embedded JavaScript + Hopefully, you'll never need to use it, but if you ever need to intersperse + snippets of JavaScript within your CoffeeScript, you can + use backticks to pass it straight through. +

    + <%= code_for('embedded', 'hi()') %> + +

    + + Switch/When/Else + Switch statements in JavaScript are a bit awkward. You need to + remember to break at the end of every case statement to + avoid accidentally falling through to the default case. + CoffeeScript prevents accidental fall-through, and can convert the switch + into a returnable, assignable expression. The format is: switch condition, + when clauses, else the default case. +

    +

    + As in Ruby, switch statements in CoffeeScript can take multiple + values for each when clause. If any of the values match, the clause + runs. +

    + <%= code_for('switch') %> + +

    + + Try/Catch/Finally + Try/catch statements are just about the same as JavaScript (although + they work as expressions). +

    + <%= code_for('try') %> + +

    + + Chained Comparisons + CoffeeScript borrows + chained comparisons + from Python — making it easy to test if a value falls within a + certain range. +

    + <%= code_for('comparisons', 'healthy') %> + +

    + + String and RegExp Interpolation + Ruby-style string interpolation is included in CoffeeScript. Double-quoted + strings allow for interpolated values, while single-quoted strings are literal. +

    + <%= code_for('interpolation', 'quote') %> +

    + And arbitrary expressions can be interpolated by using brackets #{ ... }
    + Interpolation works the same way within regular expressions. +

    + <%= code_for('interpolation_expression', 'sentence') %> + +

    + + Multiline Strings, Heredocs, and Block Comments + Multiline strings are allowed in CoffeeScript. +

    + <%= code_for('strings', 'mobyDick') %> +

    + Heredocs can be used to hold formatted or indentation-sensitive text + (or, if you just don't feel like escaping quotes and apostrophes). The + indentation level that begins the heredoc is maintained throughout, so + you can keep it all aligned with the body of your code. +

    + <%= code_for('heredocs') %> +

    + Double-quoted heredocs, like double-quoted strings, allow interpolation. +

    +

    + Sometimes you'd like to pass a block comment through to the generated + JavaScript. For example, when you need to embed a licensing header at + the top of a file. Block comments, which mirror the synax for heredocs, + are preserved in the generated code. +

    + <%= code_for('block_comment') %> + +

    + + Cake, and Cakefiles +

    + +

    + CoffeeScript includes a simple build system similar to + Make and + Rake. Naturally, + it's called Cake, and is used for the build and test tasks for the CoffeeScript + language itself. Tasks are defined in a file named Cakefile, and + can be invoked by running cake taskname from within the directory. + To print a list of all the tasks and options, just run cake. +

    + +

    + Task definitions are written in CoffeeScript, so you can put arbitrary code + in your Cakefile. Define a task with a name, a long description, and the + function to invoke when the task is run. If your task takes a command-line + option, you can define the option with short and long flags, and it will + be made available in the options object. Here's a task that uses + the Node.js API to rebuild CoffeeScript's parser: +

    + <%= code_for('cake_tasks') %> +

    + If you need to invoke one task before another — for example, running + build before test, you can use the invoke function: + invoke 'build' +

    + +

    + + "text/coffeescript" Script Tags +

    + +

    + While it's not recommended for serious use, CoffeeScripts may be included + directly within the browser using <script type="text/coffeescript"> + tags. The source includes a compressed and minified version of the compiler + (Download current version here, 43k when gzipped) + as extras/coffee-script.js. Include this file on a page with + inline CoffeeScript tags, and it will compile and evaluate them in order. +

    + +

    + In fact, the little bit of glue script that runs "Try CoffeeScript" above, + as well as jQuery for the menu, is implemented in just this way. + View source and look at the bottom of the page to see the example. + Including the script also gives you access to CoffeeScript.compile() + so you can pop open Firebug and try compiling some strings. +

    + +

    + The usual caveats about CoffeeScript apply — your inline scripts will + run within a closure wrapper, so if you want to expose global variables or + functions, attach them to the window object. +

    + +

    + + Resources +

    + +
      +
    • + Source Code
      + Use bin/coffee to test your changes,
      + bin/cake test to run the test suite,
      + bin/cake build to rebuild the CoffeeScript compiler, and
      + bin/cake build:parser to regenerate the Jison parser if you're + working on the grammar.

      + git checkout lib && bin/cake build:full is a good command to run when you're working + on the core language. It'll refresh the lib directory + (in case you broke something), build your altered compiler, use that to + rebuild itself (a good sanity test) and then run all of the tests. If + they pass, there's a good chance you've made a successful change. +
    • +
    • + CoffeeScript Issues
      + Bugs reports, feature requests, and general discussion all belong here. +
    • +
    • + If you'd like to chat, stop by #coffeescript on Freenode in the + IRC client of your choice, or on + webchat.freenode.net. +
    • +
    • + yeungda's JCoffeeScript + — A Java Library that uses Rhino to compile CoffeeScript, allowing + compilation within Java projects or on systems that Node.js doesn't support. +
    • +
    • + defunkt's CoffeeScript Major Mode + — a Emacs major mode that provides syntax highlighting, indentation + support, and some bonus commands. +
    • +
    • + jashkenas's CoffeeScript TextMate Bundle + — which provides syntax highlighting, snippet expansion, and the + ability to run bits of CoffeeScript from within TextMate itself. +
    • +
    • + kchmck's Vim CoffeeScript + — which adds Vim syntax highlighting and indentation support. +
    • +
    • + wavded's gedit-coffeescript + — a CoffeeScript syntax highlighter for the gedit text editor. +
    • +
    • + yeungda's coffeescript-idea + — a plugin for IntelliJ IDEA and RubyMine providing syntax highlighting. +
    • +
    • + mattly's rack-coffee + — a small Rack middleware for serving CoffeeScript files as + compiled JavaScript on the fly. +
    • +
    • + jnicklas's BistroCar + — a plugin that serves and bundles CoffeeScript from within your + Rails application. +
    • +
    • + dsc's CoffeeCup + — a Python WSGI middleware that compiles CoffeeScript to JavaScript + on-demand during development. +
    • +
    • + sutto's Barista + — a BistroCar alternative that integrates well with + Jammit and Rails 3. +
    • +
    • + inem and gerad's coffee-haml-filter + — a custom filter for rendering CoffeeScript inline within + HAML templates. +
    • +
    • + chrislloyd's Roast + — a CoffeeScript compiler plug-in that allows you to include external + source files. +
    • +
    • + andrzejsliwa's CoffeeApp + — a CoffeeScript wrapper for CouchApps, web applications served + directly from CouchDB. +
    • +
    • + mauricemach's CoffeeKup + — Markup as CoffeeScript. After _why's + Markaby. +
    • +
    • + jashkenas's Docco + — a quick-and-dirty literate-programming-style documentation generator + for CoffeeScript. Used to produce the annotated source. +
    • +
    + +

    + + Web Chat (IRC) +

    + +

    + Quick help and advice can usually be found in the CoffeeScript IRC room. + Join #coffeescript on irc.freenode.net, or click the + button below to open a webchat session on this page. +

    + +

    + +

    + +

    + + Change Log +

    + +

    + 0.9.4 + CoffeeScript now uses appropriately-named temporary variables, and recycles + their references after use. Added require.extensions support for + Node.js 0.3. Loading CoffeeScript in the browser now adds just a + single CoffeeScript object to global scope. + Fixes for implicit object and block comment edge cases. +

    + +

    + 0.9.3 + CoffeeScript switch statements now compile into JS switch + statements — they previously compiled into if/else chains + for JavaScript 1.3 compatibility. + Soaking a function invocation is now supported. Users of the RubyMine + editor should now be able to use --watch mode. +

    + +

    + 0.9.2 + Specifying the start and end of a range literal is now optional, eg. array[3..]. + You can now say a not instanceof b. + Fixed important bugs with nested significant and non-significant indentation (Issue #637). + Added a --require flag that allows you to hook into the coffee command. + Added a custom jsl.conf file for our preferred JavaScriptLint setup. + Sped up Jison grammar compilation time by flattening rules for operations. + Block comments can now be used with JavaScript-minifier-friendly syntax. + Added JavaScript's compound assignment bitwise operators. Bugfixes to + implicit object literals with leading number and string keys, as the subject + of implicit calls, and as part of compound assignment. +

    + +

    + 0.9.1 + Bugfix release for 0.9.1. Greatly improves the handling of mixed + implicit objects, implicit function calls, and implicit indentation. + String and regex interpolation is now strictly #{ ... } (Ruby style). + The compiler now takes a --require flag, which specifies scripts + to run before compilation. +

    + +

    + 0.9.0 + The CoffeeScript 0.9 series is considered to be a release candidate + for 1.0; let's give her a shakedown cruise. 0.9.0 introduces a massive + backwards-incompatible change: Assignment now uses =, and object + literals use :, as in JavaScript. This allows us to have implicit + object literals, and YAML-style object definitions. Half assignments are + removed, in favor of +=, or=, and friends. + Interpolation now uses a hash mark # instead of the dollar sign + $ — because dollar signs may be part of a valid JS identifier. + Downwards range comprehensions are now safe again, and are optimized to + straight for loops when created with integer endpoints. + A fast, unguarded form of object comprehension was added: + for all key, value of object. Mentioning the super keyword + with no arguments now forwards all arguments passed to the function, + as in Ruby. If you extend class B from parent class A, if + A has an extended method defined, it will be called, passing in B — + this enables static inheritance, among other things. Cleaner output for + functions bound with the fat arrow. @variables can now be used + in parameter lists, with the parameter being automatically set as a property + on the object — useful in constructors and setter functions. + Constructor functions can now take splats. +

    + +

    + 0.7.2 + Quick bugfix (right after 0.7.1) for a problem that prevented coffee + command-line options from being parsed in some circumstances. +

    + +

    + 0.7.1 + Block-style comments are now passed through and printed as JavaScript block + comments -- making them useful for licenses and copyright headers. Better + support for running coffee scripts standalone via hashbangs. + Improved syntax errors for tokens that are not in the grammar. +

    + +

    + 0.7.0 + Official CoffeeScript variable style is now camelCase, as in JavaScript. + Reserved words are now allowed as object keys, and will be quoted for you. + Range comprehensions now generate cleaner code, but you have to specify by -1 + if you'd like to iterate downward. Reporting of syntax errors is greatly + improved from the previous release. Running coffee with no arguments + now launches the REPL, with Readline support. The <- bind operator + has been removed from CoffeeScript. The loop keyword was added, + which is equivalent to a while true loop. Comprehensions that contain + closures will now close over their variables, like the semantics of a forEach. + You can now use bound function in class definitions (bound to the instance). + For consistency, a in b is now an array presence check, and a of b + is an object-key check. Comments are no longer passed through to the generated + JavaScript. +

    + +

    + 0.6.2 + The coffee command will now preserve directory structure when + compiling a directory full of scripts. Fixed two omissions that were preventing + the CoffeeScript compiler from running live within Internet Explorer. + There's now a syntax for block comments, similar in spirit to CoffeeScript's heredocs. + ECMA Harmony DRY-style pattern matching is now supported, where the name + of the property is the same as the name of the value: {name, length}: func. + Pattern matching is now allowed within comprehension variables. unless + is now allowed in block form. until loops were added, as the inverse + of while loops. switch statements are now allowed without + switch object clauses. Compatible + with Node.js v0.1.95. +

    + +

    + 0.6.1 + Upgraded CoffeeScript for compatibility with the new Node.js v0.1.90 + series. +

    + +

    + 0.6.0 + Trailing commas are now allowed, a-la Python. Static + properties may be assigned directly within class definitions, + using @property notation. +

    + +

    + 0.5.6 + Interpolation can now be used within regular expressions and heredocs, as well as + strings. Added the <- bind operator. + Allowing assignment to half-expressions instead of special ||=-style + operators. The arguments object is no longer automatically converted into + an array. After requiring coffee-script, Node.js can now directly + load .coffee files, thanks to registerExtension. Multiple + splats can now be used in function calls, arrays, and pattern matching. +

    + +

    + 0.5.5 + String interpolation, contributed by + Stan Angeloff. + Since --run has been the default since 0.5.3, updating + --stdio and --eval to run by default, pass --compile + as well if you'd like to print the result. +

    + +

    + 0.5.4 + Bugfix that corrects the Node.js global constants __filename and + __dirname. Tweaks for more flexible parsing of nested function + literals and improperly-indented comments. Updates for the latest Node.js API. +

    + +

    + 0.5.3 + CoffeeScript now has a syntax for defining classes. Many of the core + components (Nodes, Lexer, Rewriter, Scope, Optparse) are using them. + Cakefiles can use optparse.coffee to define options for tasks. + --run is now the default flag for the coffee command, + use --compile to save JavaScripts. Bugfix for an ambiguity between + RegExp literals and chained divisions. +

    + +

    + 0.5.2 + Added a compressed version of the compiler for inclusion in web pages as +
    extras/coffee-script.js. It'll automatically run any script tags + with type text/coffeescript for you. Added a --stdio option + to the coffee command, for piped-in compiles. +

    + + +

    + 0.5.1 + Improvements to null soaking with the existential operator, including + soaks on indexed properties. Added conditions to while loops, + so you can use them as filters with when, in the same manner as + comprehensions. +

    + +

    + 0.5.0 + CoffeeScript 0.5.0 is a major release, While there are no language changes, + the Ruby compiler has been removed in favor of a self-hosting + compiler written in pure CoffeeScript. +

    + +

    + 0.3.2 + @property is now a shorthand for this.property.
    + Switched the default JavaScript engine from Narwhal to Node.js. Pass + the --narwhal flag if you'd like to continue using it. +

    + +

    + 0.3.0 + CoffeeScript 0.3 includes major syntax changes: +
    + The function symbol was changed to + ->, and the bound function symbol is now =>. +
    + Parameter lists in function definitions must now be wrapped in parentheses. +
    + Added property soaking, with the ?. operator. +
    + Made parentheses optional, when invoking functions with arguments. +
    + Removed the obsolete block literal syntax. +

    + +

    + 0.2.6 + Added Python-style chained comparisons, the conditional existence + operator ?=, and some examples from Beautiful Code. + Bugfixes relating to statement-to-expression conversion, arguments-to-array + conversion, and the TextMate syntax highlighter. +

    + +

    + 0.2.5 + The conditions in switch statements can now take multiple values at once — + If any of them are true, the case will run. Added the long arrow ==>, + which defines and immediately binds a function to this. While loops can + now be used as expressions, in the same way that comprehensions can. Splats + can be used within pattern matches to soak up the rest of an array. +

    + +

    + 0.2.4 + Added ECMAScript Harmony style destructuring assignment, for dealing with + extracting values from nested arrays and objects. Added indentation-sensitive + heredocs for nicely formatted strings or chunks of code. +

    + +

    + 0.2.3 + Axed the unsatisfactory ino keyword, replacing it with of for + object comprehensions. They now look like: for prop, value of object. +

    + +

    + 0.2.2 + When performing a comprehension over an object, use ino, instead + of in, which helps us generate smaller, more efficient code at + compile time. +
    + Added :: as a shorthand for saying .prototype. +
    + The "splat" symbol has been changed from a prefix asterisk *, to + a postfix ellipsis ... +
    + Added JavaScript's in operator, + empty return statements, and empty while loops. +
    + Constructor functions that start with capital letters now include a + safety check to make sure that the new instance of the object is returned. +
    + The extends keyword now functions identically to goog.inherits + in Google's Closure Library. +

    + +

    + 0.2.1 + Arguments objects are now converted into real arrays when referenced. +

    + +

    + 0.2.0 + Major release. Significant whitespace. Better statement-to-expression + conversion. Splats. Splice literals. Object comprehensions. Blocks. + The existential operator. Many thanks to all the folks who posted issues, + with special thanks to + Liam O'Connor-Davis for whitespace + and expression help. +

    + +

    + 0.1.6 + Bugfix for running coffee --interactive and --run + from outside of the CoffeeScript directory. Bugfix for nested + function/if-statements. +

    + +

    + 0.1.5 + Array slice literals and array comprehensions can now both take Ruby-style + ranges to specify the start and end. JavaScript variable declaration is + now pushed up to the top of the scope, making all assignment statements into + expressions. You can use \ to escape newlines. + The coffee-script command is now called coffee. +

    + +

    + 0.1.4 + The official CoffeeScript extension is now .coffee instead of + .cs, which properly belongs to + C#. + Due to popular demand, you can now also use = to assign. Unlike + JavaScript, = can also be used within object literals, interchangeably + with :. Made a grammatical fix for chained function calls + like func(1)(2)(3)(4). Inheritance and super no longer use + __proto__, so they should be IE-compatible now. +

    + +

    + 0.1.3 + The coffee command now includes --interactive, + which launches an interactive CoffeeScript session, and --run, + which directly compiles and executes a script. Both options depend on a + working installation of Narwhal. + The aint keyword has been replaced by isnt, which goes + together a little smoother with is. + Quoted strings are now allowed as identifiers within object literals: eg. + {"5+5": 10}. + All assignment operators now use a colon: +:, -:, + *:, etc. +

    + +

    + 0.1.2 + Fixed a bug with calling super() through more than one level of + inheritance, with the re-addition of the extends keyword. + Added experimental Narwhal + support (as a Tusk package), contributed by + Tom Robinson, including + bin/cs as a CoffeeScript REPL and interpreter. + New --no-wrap option to suppress the safety function + wrapper. +

    + +

    + 0.1.1 + Added instanceof and typeof as operators. +

    + +

    + 0.1.0 + Initial CoffeeScript release. +

    + +
    + + + + + + + + diff --git a/node_modules/jade/support/coffee-script/documentation/js/aliases.js b/node_modules/jade/support/coffee-script/documentation/js/aliases.js new file mode 100644 index 0000000..a3675d6 --- /dev/null +++ b/node_modules/jade/support/coffee-script/documentation/js/aliases.js @@ -0,0 +1,17 @@ +var volume, winner; +if (ignition === true) { + launch(); +} +if (band !== SpinalTap) { + volume = 10; +} +if (answer !== false) { + letTheWildRumpusBegin(); +} +if (car.speed < limit) { + accelerate(); +} +if ((47 === pick || 92 === pick || 13 === pick)) { + winner = true; +} +print(inspect("My name is " + this.name)); \ No newline at end of file diff --git a/node_modules/jade/support/coffee-script/documentation/js/array_comprehensions.js b/node_modules/jade/support/coffee-script/documentation/js/array_comprehensions.js new file mode 100644 index 0000000..2260db7 --- /dev/null +++ b/node_modules/jade/support/coffee-script/documentation/js/array_comprehensions.js @@ -0,0 +1,20 @@ +var _i, _len, _len2, _ref, _result, food, lunch, pos, roid, roid2; +lunch = (function() { + _result = []; _ref = ['toast', 'cheese', 'wine']; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + food = _ref[_i]; + _result.push(eat(food)); + } + return _result; +})(); +for (pos = 0, _len = asteroids.length; pos < _len; pos++) { + roid = asteroids[pos]; + for (_i = 0, _len2 = asteroids.length; _i < _len2; _i++) { + roid2 = asteroids[_i]; + if (roid !== roid2) { + if (roid.overlaps(roid2)) { + roid.explode(); + } + } + } +} \ No newline at end of file diff --git a/node_modules/jade/support/coffee-script/documentation/js/block_comment.js b/node_modules/jade/support/coffee-script/documentation/js/block_comment.js new file mode 100644 index 0000000..ae602e6 --- /dev/null +++ b/node_modules/jade/support/coffee-script/documentation/js/block_comment.js @@ -0,0 +1,4 @@ +/* +CoffeeScript Compiler v0.9.4 +Released under the MIT License +*/ \ No newline at end of file diff --git a/node_modules/jade/support/coffee-script/documentation/js/cake_tasks.js b/node_modules/jade/support/coffee-script/documentation/js/cake_tasks.js new file mode 100644 index 0000000..b1c0914 --- /dev/null +++ b/node_modules/jade/support/coffee-script/documentation/js/cake_tasks.js @@ -0,0 +1,10 @@ +var fs; +fs = require('fs'); +option('-o', '--output [DIR]', 'directory for compiled code'); +task('build:parser', 'rebuild the Jison parser', function(options) { + var code, dir; + require('jison'); + code = require('./lib/grammar').parser.generate(); + dir = options.output || 'lib'; + return fs.writeFile("" + dir + "/parser.js", code); +}); \ No newline at end of file diff --git a/node_modules/jade/support/coffee-script/documentation/js/classes.js b/node_modules/jade/support/coffee-script/documentation/js/classes.js new file mode 100644 index 0000000..279885f --- /dev/null +++ b/node_modules/jade/support/coffee-script/documentation/js/classes.js @@ -0,0 +1,42 @@ +var Animal, Horse, Snake, sam, tom; +var __extends = function(child, parent) { + var ctor = function() {}; + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.prototype.constructor = child; + if (typeof parent.extended === "function") parent.extended(child); + child.__super__ = parent.prototype; +}; +Animal = (function() { + return function Animal(_arg) { + this.name = _arg; + return this; + }; +})(); +Animal.prototype.move = function(meters) { + return alert(this.name + " moved " + meters + "m."); +}; +Snake = (function() { + return function Snake() { + return Animal.apply(this, arguments); + }; +})(); +__extends(Snake, Animal); +Snake.prototype.move = function() { + alert("Slithering..."); + return Snake.__super__.move.call(this, 5); +}; +Horse = (function() { + return function Horse() { + return Animal.apply(this, arguments); + }; +})(); +__extends(Horse, Animal); +Horse.prototype.move = function() { + alert("Galloping..."); + return Horse.__super__.move.call(this, 45); +}; +sam = new Snake("Sammy the Python"); +tom = new Horse("Tommy the Palomino"); +sam.move(); +tom.move(); \ No newline at end of file diff --git a/node_modules/jade/support/coffee-script/documentation/js/comparisons.js b/node_modules/jade/support/coffee-script/documentation/js/comparisons.js new file mode 100644 index 0000000..e1ce0cc --- /dev/null +++ b/node_modules/jade/support/coffee-script/documentation/js/comparisons.js @@ -0,0 +1,3 @@ +var cholesterol, healthy; +cholesterol = 127; +healthy = (200 > cholesterol) && (cholesterol > 60); \ No newline at end of file diff --git a/node_modules/jade/support/coffee-script/documentation/js/conditionals.js b/node_modules/jade/support/coffee-script/documentation/js/conditionals.js new file mode 100644 index 0000000..bee05fb --- /dev/null +++ b/node_modules/jade/support/coffee-script/documentation/js/conditionals.js @@ -0,0 +1,12 @@ +var date, mood, options; +if (singing) { + mood = greatlyImproved; +} +if (happy && knowsIt) { + clapsHands(); + chaChaCha(); +} else { + showIt(); +} +date = friday ? sue : jill; +options || (options = defaults); \ No newline at end of file diff --git a/node_modules/jade/support/coffee-script/documentation/js/embedded.js b/node_modules/jade/support/coffee-script/documentation/js/embedded.js new file mode 100644 index 0000000..3db2b0f --- /dev/null +++ b/node_modules/jade/support/coffee-script/documentation/js/embedded.js @@ -0,0 +1,4 @@ +var hi; +hi = function() { + return [document.title, "Hello JavaScript"].join(": "); +}; \ No newline at end of file diff --git a/node_modules/jade/support/coffee-script/documentation/js/existence.js b/node_modules/jade/support/coffee-script/documentation/js/existence.js new file mode 100644 index 0000000..6fc021b --- /dev/null +++ b/node_modules/jade/support/coffee-script/documentation/js/existence.js @@ -0,0 +1,5 @@ +var solipsism, speed; +if ((typeof mind !== "undefined" && mind !== null) && !(typeof world !== "undefined" && world !== null)) { + solipsism = true; +} +(typeof speed !== "undefined" && speed !== null) ? speed : (speed = 140); \ No newline at end of file diff --git a/node_modules/jade/support/coffee-script/documentation/js/expressions.js b/node_modules/jade/support/coffee-script/documentation/js/expressions.js new file mode 100644 index 0000000..6ea42bc --- /dev/null +++ b/node_modules/jade/support/coffee-script/documentation/js/expressions.js @@ -0,0 +1,5 @@ +var eldest, grade; +grade = function(student) { + return student.excellentWork ? "A+" : (student.okayStuff ? (student.triedHard ? "B" : "B-") : "C"); +}; +eldest = 24 > 21 ? "Liz" : "Ike"; \ No newline at end of file diff --git a/node_modules/jade/support/coffee-script/documentation/js/expressions_assignment.js b/node_modules/jade/support/coffee-script/documentation/js/expressions_assignment.js new file mode 100644 index 0000000..e75323d --- /dev/null +++ b/node_modules/jade/support/coffee-script/documentation/js/expressions_assignment.js @@ -0,0 +1,2 @@ +var one, six, three, two; +six = (one = 1) + (two = 2) + (three = 3); \ No newline at end of file diff --git a/node_modules/jade/support/coffee-script/documentation/js/expressions_comprehension.js b/node_modules/jade/support/coffee-script/documentation/js/expressions_comprehension.js new file mode 100644 index 0000000..771e67f --- /dev/null +++ b/node_modules/jade/support/coffee-script/documentation/js/expressions_comprehension.js @@ -0,0 +1,10 @@ +var _result, globals, name; +var __hasProp = Object.prototype.hasOwnProperty; +globals = (function() { + _result = []; + for (name in window) { + if (!__hasProp.call(window, name)) continue; + _result.push(name); + } + return _result; +})().slice(0, 10); \ No newline at end of file diff --git a/node_modules/jade/support/coffee-script/documentation/js/expressions_try.js b/node_modules/jade/support/coffee-script/documentation/js/expressions_try.js new file mode 100644 index 0000000..19a9506 --- /dev/null +++ b/node_modules/jade/support/coffee-script/documentation/js/expressions_try.js @@ -0,0 +1,7 @@ +alert((function() { + try { + return nonexistent / undefined; + } catch (error) { + return "And the error is ... " + error; + } +})()); \ No newline at end of file diff --git a/node_modules/jade/support/coffee-script/documentation/js/fat_arrow.js b/node_modules/jade/support/coffee-script/documentation/js/fat_arrow.js new file mode 100644 index 0000000..9f8f50d --- /dev/null +++ b/node_modules/jade/support/coffee-script/documentation/js/fat_arrow.js @@ -0,0 +1,11 @@ +var Account; +var __bind = function(func, context) { + return function() { return func.apply(context, arguments); }; +}; +Account = function(customer, cart) { + this.customer = customer; + this.cart = cart; + return $('.shopping_cart').bind('click', __bind(function(event) { + return this.customer.purchase(this.cart); + }, this)); +}; \ No newline at end of file diff --git a/node_modules/jade/support/coffee-script/documentation/js/functions.js b/node_modules/jade/support/coffee-script/documentation/js/functions.js new file mode 100644 index 0000000..ec38bc7 --- /dev/null +++ b/node_modules/jade/support/coffee-script/documentation/js/functions.js @@ -0,0 +1,7 @@ +var cube, square; +square = function(x) { + return x * x; +}; +cube = function(x) { + return square(x) * x; +}; \ No newline at end of file diff --git a/node_modules/jade/support/coffee-script/documentation/js/heredocs.js b/node_modules/jade/support/coffee-script/documentation/js/heredocs.js new file mode 100644 index 0000000..0cbcb2a --- /dev/null +++ b/node_modules/jade/support/coffee-script/documentation/js/heredocs.js @@ -0,0 +1,2 @@ +var html; +html = '\n cup of coffeescript\n'; \ No newline at end of file diff --git a/node_modules/jade/support/coffee-script/documentation/js/interpolation.js b/node_modules/jade/support/coffee-script/documentation/js/interpolation.js new file mode 100644 index 0000000..6b4e124 --- /dev/null +++ b/node_modules/jade/support/coffee-script/documentation/js/interpolation.js @@ -0,0 +1,3 @@ +var author, quote; +author = "Wittgenstein"; +quote = ("A picture is a fact. -- " + author); \ No newline at end of file diff --git a/node_modules/jade/support/coffee-script/documentation/js/interpolation_expression.js b/node_modules/jade/support/coffee-script/documentation/js/interpolation_expression.js new file mode 100644 index 0000000..166e08d --- /dev/null +++ b/node_modules/jade/support/coffee-script/documentation/js/interpolation_expression.js @@ -0,0 +1,4 @@ +var dates, sentence, sep; +sentence = ("" + (22 / 7) + " is a decent approximation of π"); +sep = "[.\\/\\- ]"; +dates = /\d+#{sep}\d+#{sep}\d+/g; \ No newline at end of file diff --git a/node_modules/jade/support/coffee-script/documentation/js/multiple_return_values.js b/node_modules/jade/support/coffee-script/documentation/js/multiple_return_values.js new file mode 100644 index 0000000..e4bf1e6 --- /dev/null +++ b/node_modules/jade/support/coffee-script/documentation/js/multiple_return_values.js @@ -0,0 +1,5 @@ +var _ref, city, forecast, temp, weatherReport; +weatherReport = function(location) { + return [location, 72, "Mostly Sunny"]; +}; +_ref = weatherReport("Berkeley, CA"), city = _ref[0], temp = _ref[1], forecast = _ref[2]; \ No newline at end of file diff --git a/node_modules/jade/support/coffee-script/documentation/js/object_comprehensions.js b/node_modules/jade/support/coffee-script/documentation/js/object_comprehensions.js new file mode 100644 index 0000000..8d719ed --- /dev/null +++ b/node_modules/jade/support/coffee-script/documentation/js/object_comprehensions.js @@ -0,0 +1,16 @@ +var _result, age, ages, child, yearsOld; +var __hasProp = Object.prototype.hasOwnProperty; +yearsOld = { + max: 10, + ida: 9, + tim: 11 +}; +ages = (function() { + _result = []; + for (child in yearsOld) { + if (!__hasProp.call(yearsOld, child)) continue; + age = yearsOld[child]; + _result.push(child + " is " + age); + } + return _result; +})(); \ No newline at end of file diff --git a/node_modules/jade/support/coffee-script/documentation/js/object_extraction.js b/node_modules/jade/support/coffee-script/documentation/js/object_extraction.js new file mode 100644 index 0000000..90eff3d --- /dev/null +++ b/node_modules/jade/support/coffee-script/documentation/js/object_extraction.js @@ -0,0 +1,10 @@ +var _ref, _ref2, city, futurists, name, street; +futurists = { + sculptor: "Umberto Boccioni", + painter: "Vladimir Burliuk", + poet: { + name: "F.T. Marinetti", + address: ["Via Roma 42R", "Bellagio, Italy 22021"] + } +}; +_ref = futurists.poet, name = _ref.name, _ref2 = _ref.address, street = _ref2[0], city = _ref2[1]; \ No newline at end of file diff --git a/node_modules/jade/support/coffee-script/documentation/js/objects_and_arrays.js b/node_modules/jade/support/coffee-script/documentation/js/objects_and_arrays.js new file mode 100644 index 0000000..57b544d --- /dev/null +++ b/node_modules/jade/support/coffee-script/documentation/js/objects_and_arrays.js @@ -0,0 +1,17 @@ +var kids, matrix, singers, song; +song = ["do", "re", "mi", "fa", "so"]; +singers = { + Jagger: "Rock", + Elvis: "Roll" +}; +matrix = [1, 0, 1, 0, 0, 1, 1, 1, 0]; +kids = { + brother: { + name: "Max", + age: 11 + }, + sister: { + name: "Ida", + age: 9 + } +}; \ No newline at end of file diff --git a/node_modules/jade/support/coffee-script/documentation/js/objects_reserved.js b/node_modules/jade/support/coffee-script/documentation/js/objects_reserved.js new file mode 100644 index 0000000..db54cf6 --- /dev/null +++ b/node_modules/jade/support/coffee-script/documentation/js/objects_reserved.js @@ -0,0 +1,3 @@ +$('.account').css({ + "class": 'active' +}); \ No newline at end of file diff --git a/node_modules/jade/support/coffee-script/documentation/js/overview.js b/node_modules/jade/support/coffee-script/documentation/js/overview.js new file mode 100644 index 0000000..5bdbffa --- /dev/null +++ b/node_modules/jade/support/coffee-script/documentation/js/overview.js @@ -0,0 +1,34 @@ +var _i, _len, _result, cubes, list, math, num, number, opposite, race, square; +var __slice = Array.prototype.slice; +number = 42; +opposite = true; +if (opposite) { + number = -42; +} +square = function(x) { + return x * x; +}; +list = [1, 2, 3, 4, 5]; +math = { + root: Math.sqrt, + square: square, + cube: function(x) { + return x * square(x); + } +}; +race = function(winner) { + var runners; + runners = __slice.call(arguments, 1); + return print(winner, runners); +}; +if (typeof elvis !== "undefined" && elvis !== null) { + alert("I knew it!"); +} +cubes = (function() { + _result = []; + for (_i = 0, _len = list.length; _i < _len; _i++) { + num = list[_i]; + _result.push(math.cube(num)); + } + return _result; +})(); \ No newline at end of file diff --git a/node_modules/jade/support/coffee-script/documentation/js/parallel_assignment.js b/node_modules/jade/support/coffee-script/documentation/js/parallel_assignment.js new file mode 100644 index 0000000..a24e7f6 --- /dev/null +++ b/node_modules/jade/support/coffee-script/documentation/js/parallel_assignment.js @@ -0,0 +1,4 @@ +var _ref, theBait, theSwitch; +theBait = 1000; +theSwitch = 0; +_ref = [theSwitch, theBait], theBait = _ref[0], theSwitch = _ref[1]; \ No newline at end of file diff --git a/node_modules/jade/support/coffee-script/documentation/js/patterns_and_splats.js b/node_modules/jade/support/coffee-script/documentation/js/patterns_and_splats.js new file mode 100644 index 0000000..46b2260 --- /dev/null +++ b/node_modules/jade/support/coffee-script/documentation/js/patterns_and_splats.js @@ -0,0 +1,4 @@ +var _ref, close, contents, open, tag; +var __slice = Array.prototype.slice; +tag = ""; +_ref = tag.split(""), open = _ref[0], contents = __slice.call(_ref, 1, _ref.length - 1), close = _ref[_ref.length - 1]; \ No newline at end of file diff --git a/node_modules/jade/support/coffee-script/documentation/js/prototypes.js b/node_modules/jade/support/coffee-script/documentation/js/prototypes.js new file mode 100644 index 0000000..418bc10 --- /dev/null +++ b/node_modules/jade/support/coffee-script/documentation/js/prototypes.js @@ -0,0 +1,3 @@ +String.prototype.dasherize = function() { + return this.replace(/_/g, "-"); +}; \ No newline at end of file diff --git a/node_modules/jade/support/coffee-script/documentation/js/range_comprehensions.js b/node_modules/jade/support/coffee-script/documentation/js/range_comprehensions.js new file mode 100644 index 0000000..220d689 --- /dev/null +++ b/node_modules/jade/support/coffee-script/documentation/js/range_comprehensions.js @@ -0,0 +1,19 @@ +var _result, countdown, deliverEggs, num; +countdown = (function() { + _result = []; + for (num = 10; num >= 1; num--) { + _result.push(num); + } + return _result; +})(); +deliverEggs = function() { + var _ref, _result2, dozen, i; + _result2 = []; _ref = eggs.length; + for (i = 0; (0 <= _ref ? i < _ref : i > _ref); i += 12) { + _result2.push((function() { + dozen = eggs.slice(i, i + 12); + return deliver(new eggCarton(dozen)); + })()); + } + return _result2; +}; \ No newline at end of file diff --git a/node_modules/jade/support/coffee-script/documentation/js/scope.js b/node_modules/jade/support/coffee-script/documentation/js/scope.js new file mode 100644 index 0000000..478badf --- /dev/null +++ b/node_modules/jade/support/coffee-script/documentation/js/scope.js @@ -0,0 +1,8 @@ +var changeNumbers, inner, outer; +outer = 1; +changeNumbers = function() { + var inner; + inner = -1; + return (outer = 10); +}; +inner = changeNumbers(); \ No newline at end of file diff --git a/node_modules/jade/support/coffee-script/documentation/js/slices.js b/node_modules/jade/support/coffee-script/documentation/js/slices.js new file mode 100644 index 0000000..064c502 --- /dev/null +++ b/node_modules/jade/support/coffee-script/documentation/js/slices.js @@ -0,0 +1,4 @@ +var copy, numbers, threeToSix; +numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; +threeToSix = numbers.slice(3, 6 + 1); +copy = numbers.slice(0, numbers.length); \ No newline at end of file diff --git a/node_modules/jade/support/coffee-script/documentation/js/soaks.js b/node_modules/jade/support/coffee-script/documentation/js/soaks.js new file mode 100644 index 0000000..5cf887e --- /dev/null +++ b/node_modules/jade/support/coffee-script/documentation/js/soaks.js @@ -0,0 +1,2 @@ +var _ref, _ref2; +(((_ref = lottery.drawWinner()) != null) ? (((_ref2 = _ref.address) != null) ? _ref2.zipcode : undefined) : undefined); \ No newline at end of file diff --git a/node_modules/jade/support/coffee-script/documentation/js/splats.js b/node_modules/jade/support/coffee-script/documentation/js/splats.js new file mode 100644 index 0000000..3f16b83 --- /dev/null +++ b/node_modules/jade/support/coffee-script/documentation/js/splats.js @@ -0,0 +1,15 @@ +var awardMedals, contenders, gold, rest, silver; +var __slice = Array.prototype.slice; +gold = (silver = (rest = "unknown")); +awardMedals = function(first, second) { + var others; + others = __slice.call(arguments, 2); + gold = first; + silver = second; + return (rest = others); +}; +contenders = ["Michael Phelps", "Liu Xiang", "Yao Ming", "Allyson Felix", "Shawn Johnson", "Roman Sebrle", "Guo Jingjing", "Tyson Gay", "Asafa Powell", "Usain Bolt"]; +awardMedals.apply(awardMedals, contenders); +alert("Gold: " + gold); +alert("Silver: " + silver); +alert("The Field: " + rest); \ No newline at end of file diff --git a/node_modules/jade/support/coffee-script/documentation/js/splices.js b/node_modules/jade/support/coffee-script/documentation/js/splices.js new file mode 100644 index 0000000..944f1e3 --- /dev/null +++ b/node_modules/jade/support/coffee-script/documentation/js/splices.js @@ -0,0 +1,3 @@ +var _ref, numbers; +numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; +([].splice.apply(numbers, [3, 6 - 3 + 1].concat(_ref = [-3, -4, -5, -6])), _ref); \ No newline at end of file diff --git a/node_modules/jade/support/coffee-script/documentation/js/strings.js b/node_modules/jade/support/coffee-script/documentation/js/strings.js new file mode 100644 index 0000000..cfdf5d5 --- /dev/null +++ b/node_modules/jade/support/coffee-script/documentation/js/strings.js @@ -0,0 +1,2 @@ +var mobyDick; +mobyDick = "Call me Ishmael. Some years ago -- never mind how long precisely -- having little or no money in my purse, and nothing particular to interest me on shore, I thought I would sail about a little and see the watery part of the world..."; \ No newline at end of file diff --git a/node_modules/jade/support/coffee-script/documentation/js/switch.js b/node_modules/jade/support/coffee-script/documentation/js/switch.js new file mode 100644 index 0000000..2449cb9 --- /dev/null +++ b/node_modules/jade/support/coffee-script/documentation/js/switch.js @@ -0,0 +1,23 @@ +switch (day) { + case "Mon": + go(work); + break; + case "Tue": + go(relax); + break; + case "Thu": + go(iceFishing); + break; + case "Fri": + case "Sat": + if (day === bingoDay) { + go(bingo); + go(dancing); + } + break; + case "Sun": + go(church); + break; + default: + go(work); +} \ No newline at end of file diff --git a/node_modules/jade/support/coffee-script/documentation/js/try.js b/node_modules/jade/support/coffee-script/documentation/js/try.js new file mode 100644 index 0000000..97b089f --- /dev/null +++ b/node_modules/jade/support/coffee-script/documentation/js/try.js @@ -0,0 +1,8 @@ +try { + allHellBreaksLoose(); + catsAndDogsLivingTogether(); +} catch (error) { + print(error); +} finally { + cleanUp(); +} \ No newline at end of file diff --git a/node_modules/jade/support/coffee-script/documentation/js/while.js b/node_modules/jade/support/coffee-script/documentation/js/while.js new file mode 100644 index 0000000..910b839 --- /dev/null +++ b/node_modules/jade/support/coffee-script/documentation/js/while.js @@ -0,0 +1,17 @@ +var _result, lyrics, num; +if (this.studyingEconomics) { + while (supply > demand) { + buy(); + } + while (!(supply > demand)) { + sell(); + } +} +num = 6; +lyrics = (function() { + _result = []; + while (num -= 1) { + _result.push(num + " little monkeys, jumping on the bed. One fell out and bumped his head."); + } + return _result; +})(); \ No newline at end of file diff --git a/node_modules/jade/support/coffee-script/examples/beautiful_code/binary_search.coffee b/node_modules/jade/support/coffee-script/examples/beautiful_code/binary_search.coffee new file mode 100644 index 0000000..6ad42c8 --- /dev/null +++ b/node_modules/jade/support/coffee-script/examples/beautiful_code/binary_search.coffee @@ -0,0 +1,16 @@ +# Beautiful Code, Chapter 6. +# The implementation of binary search that is tested. + +# Return the index of an element in a sorted list. (or -1, if not present) +index = (list, target) -> + [low, high] = [0, list.length] + while low < high + mid = (low + high) >> 1 + val = list[mid] + return mid if val is target + if val < target then low = mid + 1 else high = mid + return -1 + +puts 2 is index [10, 20, 30, 40, 50], 30 +puts 4 is index [-97, 35, 67, 88, 1200], 1200 +puts 0 is index [0, 45, 70], 0 \ No newline at end of file diff --git a/node_modules/jade/support/coffee-script/examples/beautiful_code/quicksort_runtime.coffee b/node_modules/jade/support/coffee-script/examples/beautiful_code/quicksort_runtime.coffee new file mode 100644 index 0000000..27794f4 --- /dev/null +++ b/node_modules/jade/support/coffee-script/examples/beautiful_code/quicksort_runtime.coffee @@ -0,0 +1,13 @@ +# Beautiful Code, Chapter 3. +# Produces the expected runtime of Quicksort, for every integer from 1 to N. + +runtime = (N) -> + [sum, t] = [0, 0] + for n in [1..N] + sum += 2 * t + t = n - 1 + sum / n + t + +puts runtime(3) is 2.6666666666666665 +puts runtime(5) is 7.4 +puts runtime(8) is 16.92142857142857 diff --git a/node_modules/jade/support/coffee-script/examples/beautiful_code/regular_expression_matcher.coffee b/node_modules/jade/support/coffee-script/examples/beautiful_code/regular_expression_matcher.coffee new file mode 100644 index 0000000..99ed0a1 --- /dev/null +++ b/node_modules/jade/support/coffee-script/examples/beautiful_code/regular_expression_matcher.coffee @@ -0,0 +1,34 @@ +# Beautiful Code, Chapter 1. +# Implements a regular expression matcher that supports character matches, +# '.', '^', '$', and '*'. + +# Search for the regexp anywhere in the text. +match = (regexp, text) -> + return match_here(regexp.slice(1), text) if regexp[0] is '^' + while text + return true if match_here(regexp, text) + text = text.slice(1) + false + +# Search for the regexp at the beginning of the text. +match_here = (regexp, text) -> + [cur, next] = [regexp[0], regexp[1]] + if regexp.length is 0 then return true + if next is '*' then return match_star(cur, regexp.slice(2), text) + if cur is '$' and not next then return text.length is 0 + if text and (cur is '.' or cur is text[0]) then return match_here(regexp.slice(1), text.slice(1)) + false + +# Search for a kleene star match at the beginning of the text. +match_star = (c, regexp, text) -> + loop + return true if match_here(regexp, text) + return false unless text and (text[0] is c or c is '.') + text = text.slice(1) + +puts match("ex", "some text") +puts match("s..t", "spit") +puts match("^..t", "buttercup") +puts match("i..$", "cherries") +puts match("o*m", "vrooooommm!") +puts match("^hel*o$", "hellllllo") \ No newline at end of file diff --git a/node_modules/jade/support/coffee-script/examples/blocks.coffee b/node_modules/jade/support/coffee-script/examples/blocks.coffee new file mode 100644 index 0000000..f9e67ff --- /dev/null +++ b/node_modules/jade/support/coffee-script/examples/blocks.coffee @@ -0,0 +1,54 @@ +# After wycats' http://yehudakatz.com/2010/02/07/the-building-blocks-of-ruby/ + +# Sinatra. +get '/hello', -> + 'Hello World' + + +# Append. +append = (location, data) -> + path = new Pathname location + throw new Error("Location does not exist") unless path.exists() + + File.open path, 'a', (file) -> + file.puts YAML.dump data + + data + + +# Rubinius' File.open implementation. +File.open = (path, mode, block) -> + io = new File path, mode + + return io unless block + + try + block io + finally + io.close() unless io.closed() + + +# Write. +write = (location, data) -> + path = new Pathname location + raise "Location does not exist" unless path.exists() + + File.open path, 'w', (file) -> + return false if Digest.MD5.hexdigest(file.read()) is data.hash() + file.puts YAML.dump data + true + + +# Rails' respond_to. +index = -> + people = Person.find 'all' + + respond_to (format) -> + format.html() + format.xml -> render xml: people.xml() + + +# Synchronization. +synchronize = (block) -> + lock() + try block() finally unlock() diff --git a/node_modules/jade/support/coffee-script/examples/code.coffee b/node_modules/jade/support/coffee-script/examples/code.coffee new file mode 100644 index 0000000..255feba --- /dev/null +++ b/node_modules/jade/support/coffee-script/examples/code.coffee @@ -0,0 +1,171 @@ +# Functions: +square = (x) -> x * x + +sum = (x, y) -> x + y + +odd = (x) -> x % 2 isnt 0 + +even = (x) -> x % 2 is 0 + +run_loop = -> + fire_events((e) -> e.stopPropagation()) + listen() + wait() + +# Objects: +dense_object_literal = {one: 1, two: 2, three: 3} + +spaced_out_multiline_object = + pi: 3.14159 + list: [1, 2, 3, 4] + regex: /match[ing](every|thing|\/)/gi + three: new Idea + + inner_obj: + freedom: -> _.freedom() + +# Arrays: +stooges = [{moe: 45}, {curly: 43}, {larry: 46}] + +exponents = [((x) -> x), ((x) -> x * x), ((x) -> x * x * x)] + +empty = [] + +multiline = [ + 'line one' + 'line two' +] + +# Conditionals and ternaries. +if submarine.shields_up + full_speed_ahead() + fire_torpedos() +else if submarine.sinking + abandon_ship() +else + run_away() + +eldest = if 25 > 21 then liz else marge + +decoration = medal_of_honor if war_hero + +go_to_sleep() unless coffee + +# Returning early: +race = -> + run() + walk() + crawl() + if tired then return sleep() + race() + +# Conditional assignment: +good or= evil +wine and= cheese + +# Nested property access and calls. +((moon.turn(360))).shapes[3].move({x: 45, y: 30}).position['top'].offset('x') + +a = b = c = 5 + +# Embedded JavaScript. +callback( + `function(e) { e.stop(); }` +) + +# Try/Catch/Finally/Throw. +try + all_hell_breaks_loose() + dogs_and_cats_living_together() + throw "up" +catch error + print(error) +finally + clean_up() + +try all_hell_breaks_loose() catch error then print(error) finally clean_up() + +# While loops, break and continue. +while demand > supply + sell() + restock() + +while supply > demand then buy() + +loop + break if broken + continue if continuing + +# Unary operators. +!!true + +# Lexical scoping. +v_1 = 5 +change_a_and_set_b = -> + v_1 = 10 + v_2 = 15 +v_2 = 20 + +# Array comprehensions. +supper = food.capitalize() for food in ['toast', 'cheese', 'wine'] + +drink bottle for bottle, i in ['soda', 'wine', 'lemonade'] when even i + +# Switch statements ("else" serves as a default). +activity = switch day + when "Tuesday" then eat_breakfast() + when "Sunday" then go_to_church() + when "Saturday" then go_to_the_park() + when "Wednesday" + if day is bingo_day + go_to_bingo() + else + eat_breakfast() + go_to_work() + eat_dinner() + else go_to_work() + +# Semicolons can optionally be used instead of newlines. +wednesday = -> eat_breakfast(); go_to_work(); eat_dinner() + +# Array slice literals. +zero_to_nine = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] +three_to_six = zero_to_nine[3..6] + +# Multiline strings with inner quotes. +story = "Lorem ipsum dolor \"sit\" amet, consectetuer adipiscing elit, +sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna +aliquam erat volutpat. Ut wisi enim ad." + +# Inheritance and calling super. +class Animal + constructor: (@name) -> + + move: (meters) -> + alert this.name + " moved " + meters + "m." + +class Snake extends Animal + move: -> + alert 'Slithering...' + super 5 + +class Horse extends Animal + move: -> + alert 'Galloping...' + super 45 + +sam = new Snake "Sammy the Snake" +tom = new Horse "Tommy the Horse" + +sam.move() +tom.move() + +# Numbers. +a_googol = 1e100 +hex = 0xff0000 +negative = -1.0 +infinity = Infinity +nan = NaN + +# Deleting. +delete secret.identity \ No newline at end of file diff --git a/node_modules/jade/support/coffee-script/examples/computer_science/README b/node_modules/jade/support/coffee-script/examples/computer_science/README new file mode 100644 index 0000000..1046f9f --- /dev/null +++ b/node_modules/jade/support/coffee-script/examples/computer_science/README @@ -0,0 +1,4 @@ +Ported from Nicholas Zakas' collection of computer science fundamentals, written +in JavaScript. Originals available here: + +http://github.com/nzakas/computer-science-in-javascript diff --git a/node_modules/jade/support/coffee-script/examples/computer_science/binary_search.coffee b/node_modules/jade/support/coffee-script/examples/computer_science/binary_search.coffee new file mode 100644 index 0000000..69fc678 --- /dev/null +++ b/node_modules/jade/support/coffee-script/examples/computer_science/binary_search.coffee @@ -0,0 +1,25 @@ +# Uses a binary search algorithm to locate a value in the specified array. +binary_search = (items, value) -> + + start = 0 + stop = items.length - 1 + pivot = Math.floor (start + stop) / 2 + + while items[pivot] isnt value and start < stop + + # Adjust the search area. + stop = pivot - 1 if value < items[pivot] + start = pivot + 1 if value > items[pivot] + + # Recalculate the pivot. + pivot = Math.floor (stop + start) / 2 + + # Make sure we've found the correct value. + if items[pivot] is value then pivot else -1 + + +# Test the function. +puts 2 is binary_search [10, 20, 30, 40, 50], 30 +puts 4 is binary_search [-97, 35, 67, 88, 1200], 1200 +puts 0 is binary_search [0, 45, 70], 0 +puts(-1 is binary_search [0, 45, 70], 10) \ No newline at end of file diff --git a/node_modules/jade/support/coffee-script/examples/computer_science/bubble_sort.coffee b/node_modules/jade/support/coffee-script/examples/computer_science/bubble_sort.coffee new file mode 100644 index 0000000..4757c8e --- /dev/null +++ b/node_modules/jade/support/coffee-script/examples/computer_science/bubble_sort.coffee @@ -0,0 +1,11 @@ +# A bubble sort implementation, sorting the given array in-place. +bubble_sort = (list) -> + for i in [0...list.length] + for j in [0...list.length - i] + [list[j], list[j+1]] = [list[j+1], list[j]] if list[j] > list[j+1] + list + + +# Test the function. +puts bubble_sort([3, 2, 1]).join(' ') is '1 2 3' +puts bubble_sort([9, 2, 7, 0, 1]).join(' ') is '0 1 2 7 9' \ No newline at end of file diff --git a/node_modules/jade/support/coffee-script/examples/computer_science/linked_list.coffee b/node_modules/jade/support/coffee-script/examples/computer_science/linked_list.coffee new file mode 100644 index 0000000..95bb2ef --- /dev/null +++ b/node_modules/jade/support/coffee-script/examples/computer_science/linked_list.coffee @@ -0,0 +1,108 @@ +# "Classic" linked list implementation that doesn't keep track of its size. +class LinkedList + + constructor: -> + this._head = null # Pointer to the first item in the list. + + + # Appends some data to the end of the list. This method traverses the existing + # list and places the value at the end in a new node. + add: (data) -> + + # Create a new node object to wrap the data. + node = data: data, next: null + + current = this._head or= node + + if this._head isnt node + (current = current.next) while current.next + current.next = node + + this + + + # Retrieves the data at the given position in the list. + item: (index) -> + + # Check for out-of-bounds values. + return null if index < 0 + + current = this._head or null + i = -1 + + # Advance through the list. + (current = current.next) while current and index > (i += 1) + + # Return null if we've reached the end. + current and current.data + + + # Remove the item from the given location in the list. + remove: (index) -> + + # Check for out-of-bounds values. + return null if index < 0 + + current = this._head or null + i = -1 + + # Special case: removing the first item. + if index is 0 + this._head = current.next + else + + # Find the right location. + ([previous, current] = [current, current.next]) while index > (i += 1) + + # Skip over the item to remove. + previous.next = current.next + + # Return the value. + current and current.data + + + # Calculate the number of items in the list. + size: -> + current = this._head + count = 0 + + while current + count += 1 + current = current.next + + count + + + # Convert the list into an array. + toArray: -> + result = [] + current = this._head + + while current + result.push current.data + current = current.next + + result + + + # The string representation of the linked list. + toString: -> this.toArray().toString() + + +# Tests. +list = new LinkedList + +list.add("Hi") +puts list.size() is 1 +puts list.item(0) is "Hi" +puts list.item(1) is null + +list = new LinkedList +list.add("zero").add("one").add("two") +puts list.size() is 3 +puts list.item(2) is "two" +puts list.remove(1) is "one" +puts list.item(0) is "zero" +puts list.item(1) is "two" +puts list.size() is 2 +puts list.item(-10) is null diff --git a/node_modules/jade/support/coffee-script/examples/computer_science/luhn_algorithm.coffee b/node_modules/jade/support/coffee-script/examples/computer_science/luhn_algorithm.coffee new file mode 100644 index 0000000..db1c544 --- /dev/null +++ b/node_modules/jade/support/coffee-script/examples/computer_science/luhn_algorithm.coffee @@ -0,0 +1,36 @@ +# Use the Luhn algorithm to validate a numeric identifier, such as credit card +# numbers, national insurance numbers, etc. +# See: http://en.wikipedia.org/wiki/Luhn_algorithm + +is_valid_identifier = (identifier) -> + + sum = 0 + alt = false + + for i in [(identifier.length - 1)..0] + + # Get the next digit. + num = parseInt identifier.charAt(i), 10 + + # If it's not a valid number, abort. + return false if isNaN(num) + + # If it's an alternate number... + if alt + num *= 2 + num = (num % 10) + 1 if num > 9 + + # Flip the alternate bit. + alt = !alt + + # Add to the rest of the sum. + sum += num + + # Determine if it's valid. + sum % 10 is 0 + + +# Tests. +puts is_valid_identifier("49927398716") is true +puts is_valid_identifier("4408041234567893") is true +puts is_valid_identifier("4408041234567890") is false diff --git a/node_modules/jade/support/coffee-script/examples/computer_science/merge_sort.coffee b/node_modules/jade/support/coffee-script/examples/computer_science/merge_sort.coffee new file mode 100644 index 0000000..4fb6907 --- /dev/null +++ b/node_modules/jade/support/coffee-script/examples/computer_science/merge_sort.coffee @@ -0,0 +1,19 @@ +# Sorts an array in ascending natural order using merge sort. +merge_sort = (list) -> + + return list if list.length is 1 + + result = [] + pivot = Math.floor list.length / 2 + left = merge_sort list.slice 0, pivot + right = merge_sort list.slice pivot + + while left.length and right.length + result.push(if left[0] < right[0] then left.shift() else right.shift()) + + result.concat(left).concat(right) + + +# Test the function. +puts merge_sort([3, 2, 1]).join(' ') is '1 2 3' +puts merge_sort([9, 2, 7, 0, 1]).join(' ') is '0 1 2 7 9' \ No newline at end of file diff --git a/node_modules/jade/support/coffee-script/examples/computer_science/selection_sort.coffee b/node_modules/jade/support/coffee-script/examples/computer_science/selection_sort.coffee new file mode 100644 index 0000000..1e87d56 --- /dev/null +++ b/node_modules/jade/support/coffee-script/examples/computer_science/selection_sort.coffee @@ -0,0 +1,23 @@ +# An in-place selection sort. +selection_sort = (list) -> + len = list.length + + # For each item in the list. + for i in [0...len] + + # Set the minimum to this position. + min = i + + # Check the rest of the array to see if anything is smaller. + (min = j if list[j] < list[min]) for j in [(i+1)...len] + + # Swap if a smaller item has been found. + [list[i], list[min]] = [list[min], list[i]] if i isnt min + + # The list is now sorted. + list + + +# Test the function. +puts selection_sort([3, 2, 1]).join(' ') is '1 2 3' +puts selection_sort([9, 2, 7, 0, 1]).join(' ') is '0 1 2 7 9' \ No newline at end of file diff --git a/node_modules/jade/support/coffee-script/examples/poignant.coffee b/node_modules/jade/support/coffee-script/examples/poignant.coffee new file mode 100644 index 0000000..dc07ef8 --- /dev/null +++ b/node_modules/jade/support/coffee-script/examples/poignant.coffee @@ -0,0 +1,181 @@ +# Examples from the Poignant Guide. + +# ['toast', 'cheese', 'wine'].each { |food| print food.capitalize } + +['toast', 'wine', 'cheese'].each (food) -> print food.capitalize() + + + +# class LotteryTicket +# def picks; @picks; end +# def picks=(var); @picks = var; end +# def purchased; @purchased; end +# def purchased=(var); @purchased = var; end +# end + +LotteryTicket = + get_picks: -> @picks + set_picks: (@picks) -> + get_purchased: -> @purchase + set_purchased: (@purchased) -> + + + +# class << LotteryDraw +# def play +# result = LotteryTicket.new_random +# winners = {} +# @@tickets.each do |buyer, ticket_list| +# ticket_list.each do |ticket| +# score = ticket.score( result ) +# next if score.zero? +# winners[buyer] ||= [] +# winners[buyer] << [ ticket, score ] +# end +# end +# @@tickets.clear +# winners +# end +# end + +LotteryDraw = + play: -> + result = LotteryTicket.new_random() + winners = {} + this.tickets.each (buyer, ticket_list) -> + ticket_list.each (ticket) -> + score = ticket.score result + return if score is 0 + winners[buyer] or= [] + winners[buyer].push [ticket, score] + this.tickets = {} + winners + + + +# module WishScanner +# def scan_for_a_wish +# wish = self.read.detect do |thought| +# thought.index( 'wish: ' ) == 0 +# end +# wish.gsub( 'wish: ', '' ) +# end +# end + +WishScanner = + scan_for_a_wish: -> + wish = this.read().detect (thought) -> thought.index('wish: ') is 0 + wish.replace 'wish: ', '' + + + +# class Creature +# +# # This method applies a hit taken during a fight. +# def hit( damage ) +# p_up = rand( charisma ) +# if p_up % 9 == 7 +# @life += p_up / 4 +# puts "[#{ self.class } magick powers up #{ p_up }!]" +# end +# @life -= damage +# puts "[#{ self.class } has died.]" if @life <= 0 +# end +# +# # This method takes one turn in a fight. +# def fight( enemy, weapon ) +# if life <= 0 +# puts "[#{ self.class } is too dead to fight!]" +# return +# end +# +# # Attack the opponent +# your_hit = rand( strength + weapon ) +# puts "[You hit with #{ your_hit } points of damage!]" +# enemy.hit( your_hit ) +# +# # Retaliation +# p enemy +# if enemy.life > 0 +# enemy_hit = rand( enemy.strength + enemy.weapon ) +# puts "[Your enemy hit with #{ enemy_hit } points of damage!]" +# self.hit( enemy_hit ) +# end +# end +# +# end + +Creature = + + # This method applies a hit taken during a fight. + hit: (damage) -> + p_up = Math.rand this.charisma + if p_up % 9 is 7 + this.life += p_up / 4 + puts "[" + this.name + " magick powers up " + p_up + "!]" + this.life -= damage + if this.life <= 0 then puts "[" + this.name + " has died.]" + + # This method takes one turn in a fight. + fight: (enemy, weapon) -> + if this.life <= 0 then return puts "[" + this.name + "is too dead to fight!]" + + # Attack the opponent. + your_hit = Math.rand this.strength + weapon + puts "[You hit with " + your_hit + "points of damage!]" + enemy.hit your_hit + + # Retaliation. + puts enemy + if enemy.life > 0 + enemy_hit = Math.rand enemy.strength + enemy.weapon + puts "[Your enemy hit with " + enemy_hit + "points of damage!]" + this.hit enemy_hit + + + +# # Get evil idea and swap in code words +# print "Enter your new idea: " +# idea = gets +# code_words.each do |real, code| +# idea.gsub!( real, code ) +# end +# +# # Save the jibberish to a new file +# print "File encoded. Please enter a name for this idea: " +# idea_name = gets.strip +# File::open( "idea-" + idea_name + ".txt", "w" ) do |f| +# f << idea +# end + +# Get evil idea and swap in code words +print "Enter your new idea: " +idea = gets() +code_words.each (real, code) -> idea.replace(real, code) + +# Save the jibberish to a new file +print "File encoded. Please enter a name for this idea: " +idea_name = gets().strip() +File.open "idea-" + idea_name + '.txt', 'w', (file) -> file.write idea + + + +# def wipe_mutterings_from( sentence ) +# unless sentence.respond_to? :include? +# raise ArgumentError, +# "cannot wipe mutterings from a #{ sentence.class }" +# end +# while sentence.include? '(' +# open = sentence.index( '(' ) +# close = sentence.index( ')', open ) +# sentence[open..close] = '' if close +# end +# end + +wipe_mutterings_from = (sentence) -> + throw new Error "cannot wipe mutterings" unless sentence.indexOf + while sentence.indexOf('(') >= 0 + open = sentence.indexOf('(') - 1 + close = sentence.indexOf(')') + 1 + sentence = sentence[0..open] + sentence[close..sentence.length] + sentence diff --git a/node_modules/jade/support/coffee-script/examples/potion.coffee b/node_modules/jade/support/coffee-script/examples/potion.coffee new file mode 100644 index 0000000..66c126a --- /dev/null +++ b/node_modules/jade/support/coffee-script/examples/potion.coffee @@ -0,0 +1,206 @@ +# Examples from _why's Potion, the Readme and "Potion: A Short Pamphlet". + +# 5 times: "Odelay!" print. + +print "Odelay!" for [1..5] + + +# add = (x, y): x + y. +# add(2, 4) string print + +add = (x, y) -> x + y +print add 2, 4 + + +# loop: 'quaff' print. + +loop print 'quaff' + + +# ('cheese', 'bread', 'mayo') at (1) print + +print ['cheese', 'bread', 'mayo'][1] + + +# (language='Potion', pointless=true) at (key='language') print + +print {language: 'Potion', pointless: true}['language'] + + +# minus = (x, y): x - y. +# minus (y=10, x=6) + +minus = (x, y) -> x - y +minus 6, 10 + + +# foods = ('cheese', 'bread', 'mayo') +# foods (2) + +foods = ['cheese', 'bread', 'mayo'] +foods[2] + + +# (dog='canine', cat='feline', fox='vulpine') each (key, val): +# (key, ' is a ', val) join print. + +for key, val of {dog: 'canine', cat: 'feline', fox: 'vulpine'} + print key + ' is a ' + val + + +# Person = class: /name, /age, /sex. +# Person print = (): +# ('My name is ', /name, '.') join print. + +class Person + print: -> + print 'My name is ' + @name + '.' + + +# p = Person () +# p /name string print + +p = new Person +print p.name + + +# Policeman = Person class (rank): /rank = rank. +# Policeman print = (): +# ('My name is ', /name, ' and I'm a ', /rank, '.') join print. +# +# Policeman ('Constable') print + +class Policeman extends Person + constructor: (@rank) -> + + print: -> + print 'My name is ' + @name + " and I'm a " + @rank + '.' + +print new Policeman 'Constable' + + +# app = [window (width=200, height=400) +# [para 'Welcome.', button 'OK']] +# app first name + +app = + window: + width: 200 + height: 200 + para: 'Welcome.' + button: 'OK' + +app.window + + +# x = 1 +# y = 2 +# +# x = 1, y = 2 + +x = 1 +y = 2 + +x = 1; y = 2 + + +# table = (language='Potion' +# pointless=true) + +table = + language: 'Potion' + pointless: yes + + +# # this foul business... +# String length = (): 10. + +# this foul business... +String::length = -> 10 + + +# block = : +# 'potion' print. + +block = -> + print 'potion' + + +# if (age > 100): 'ancient'. + +if age > 100 then 'ancient' + + +# author = +# if (title == 'Jonathan Strange & Mr. Norrell'): +# 'Susanna Clarke'. +# elsif (title == 'The Star Diaries'): +# 'Stanislaw Lem'. +# elsif (title == 'The Slynx'): +# 'Tatyana Tolstaya'. +# else: +# '... probably Philip K. Dick'. + +switch author + when 'Jonathan Strange & Mr. Norrell' + 'Susanna Clarke' + when 'The Star Diaries' + 'Stanislaw Lem' + when 'The Slynx' + 'Tatyana Tolstaya' + else + '... probably Philip K. Dick' + + +# count = 8 +# while (count > 0): +# 'quaff' print +# count--. + +count = 8 +while count > 0 + print 'quaff' + count-- + + +# 1 to 5 (a): +# a string print. + +print a for a in [1..5] + + +# if (3 ?gender): +# "Huh? Numbers are sexed? That's amazing." print. + +if (3).gender? + print "Huh? Numbers are sexed? That's amazing." + + +# HomePage get = (url): +# session = url query ? at ('session'). + +HomePage::get = (url) -> + session = url.query.session if url.query? + + +# BTree = class: /left, /right. +# b = BTree () +# b /left = BTree () +# b /right = BTree () + +BTree = -> +b = new BTree +b.left = new BTree +b.right = new BTree + + +# BTree = class: /left, /right. +# b = BTree () +# +# if (b ? /left): +# 'left path found!' print. + +BTree = -> +b = new BTree + +print 'left path found!' if b.left? diff --git a/node_modules/jade/support/coffee-script/examples/underscore.coffee b/node_modules/jade/support/coffee-script/examples/underscore.coffee new file mode 100644 index 0000000..d6ef6b9 --- /dev/null +++ b/node_modules/jade/support/coffee-script/examples/underscore.coffee @@ -0,0 +1,684 @@ + + # **Underscore.coffee + # (c) 2010 Jeremy Ashkenas, DocumentCloud Inc.** + # Underscore is freely distributable under the terms of the + # [MIT license](http://en.wikipedia.org/wiki/MIT_License). + # Portions of Underscore are inspired by or borrowed from + # [Prototype.js](http://prototypejs.org/api), Oliver Steele's + # [Functional](http://osteele.com), and John Resig's + # [Micro-Templating](http://ejohn.org). + # For all details and documentation: + # http://documentcloud.github.com/underscore/ + + + # Baseline setup + # -------------- + + # Establish the root object, `window` in the browser, or `global` on the server. + root = this + + + # Save the previous value of the `_` variable. + previousUnderscore = root._ + + + # Establish the object that gets thrown to break out of a loop iteration. + # `StopIteration` is SOP on Mozilla. + breaker = if typeof(StopIteration) is 'undefined' then '__break__' else StopIteration + + + # Helper function to escape **RegExp** contents, because JS doesn't have one. + escapeRegExp = (string) -> string.replace(/([.*+?^${}()|[\]\/\\])/g, '\\$1') + + + # Save bytes in the minified (but not gzipped) version: + ArrayProto = Array.prototype + ObjProto = Object.prototype + + + # Create quick reference variables for speed access to core prototypes. + slice = ArrayProto.slice + unshift = ArrayProto.unshift + toString = ObjProto.toString + hasOwnProperty = ObjProto.hasOwnProperty + propertyIsEnumerable = ObjProto.propertyIsEnumerable + + + # All **ECMA5** native implementations we hope to use are declared here. + nativeForEach = ArrayProto.forEach + nativeMap = ArrayProto.map + nativeReduce = ArrayProto.reduce + nativeReduceRight = ArrayProto.reduceRight + nativeFilter = ArrayProto.filter + nativeEvery = ArrayProto.every + nativeSome = ArrayProto.some + nativeIndexOf = ArrayProto.indexOf + nativeLastIndexOf = ArrayProto.lastIndexOf + nativeIsArray = Array.isArray + nativeKeys = Object.keys + + + # Create a safe reference to the Underscore object for use below. + _ = (obj) -> new wrapper(obj) + + + # Export the Underscore object for **CommonJS**. + if typeof(exports) != 'undefined' then exports._ = _ + + + # Export Underscore to global scope. + root._ = _ + + + # Current version. + _.VERSION = '1.1.0' + + + # Collection Functions + # -------------------- + + # The cornerstone, an **each** implementation. + # Handles objects implementing **forEach**, arrays, and raw objects. + _.each = (obj, iterator, context) -> + try + if nativeForEach and obj.forEach is nativeForEach + obj.forEach iterator, context + else if _.isNumber obj.length + iterator.call(context, obj[i], i, obj) for i in [0...obj.length] + else + iterator.call(context, val, key, obj) for key, val of obj + catch e + throw e if e isnt breaker + obj + + + # Return the results of applying the iterator to each element. Use JavaScript + # 1.6's version of **map**, if possible. + _.map = (obj, iterator, context) -> + return obj.map(iterator, context) if nativeMap and obj.map is nativeMap + results = [] + _.each obj, (value, index, list) -> + results.push iterator.call context, value, index, list + results + + + # **Reduce** builds up a single result from a list of values. Also known as + # **inject**, or **foldl**. Uses JavaScript 1.8's version of **reduce**, if possible. + _.reduce = (obj, iterator, memo, context) -> + if nativeReduce and obj.reduce is nativeReduce + iterator = _.bind iterator, context if context + return obj.reduce iterator, memo + _.each obj, (value, index, list) -> + memo = iterator.call context, memo, value, index, list + memo + + + # The right-associative version of **reduce**, also known as **foldr**. Uses + # JavaScript 1.8's version of **reduceRight**, if available. + _.reduceRight = (obj, iterator, memo, context) -> + if nativeReduceRight and obj.reduceRight is nativeReduceRight + iterator = _.bind iterator, context if context + return obj.reduceRight iterator, memo + reversed = _.clone(_.toArray(obj)).reverse() + _.reduce reversed, iterator, memo, context + + + # Return the first value which passes a truth test. + _.detect = (obj, iterator, context) -> + result = null + _.each obj, (value, index, list) -> + if iterator.call context, value, index, list + result = value + _.breakLoop() + result + + + # Return all the elements that pass a truth test. Use JavaScript 1.6's + # **filter**, if it exists. + _.filter = (obj, iterator, context) -> + return obj.filter iterator, context if nativeFilter and obj.filter is nativeFilter + results = [] + _.each obj, (value, index, list) -> + results.push value if iterator.call context, value, index, list + results + + + # Return all the elements for which a truth test fails. + _.reject = (obj, iterator, context) -> + results = [] + _.each obj, (value, index, list) -> + results.push value if not iterator.call context, value, index, list + results + + + # Determine whether all of the elements match a truth test. Delegate to + # JavaScript 1.6's **every**, if it is present. + _.every = (obj, iterator, context) -> + iterator ||= _.identity + return obj.every iterator, context if nativeEvery and obj.every is nativeEvery + result = true + _.each obj, (value, index, list) -> + _.breakLoop() unless (result = result and iterator.call(context, value, index, list)) + result + + + # Determine if at least one element in the object matches a truth test. Use + # JavaScript 1.6's **some**, if it exists. + _.some = (obj, iterator, context) -> + iterator ||= _.identity + return obj.some iterator, context if nativeSome and obj.some is nativeSome + result = false + _.each obj, (value, index, list) -> + _.breakLoop() if (result = iterator.call(context, value, index, list)) + result + + + # Determine if a given value is included in the array or object, + # based on `===`. + _.include = (obj, target) -> + return _.indexOf(obj, target) isnt -1 if nativeIndexOf and obj.indexOf is nativeIndexOf + for key, val of obj + return true if val is target + false + + + # Invoke a method with arguments on every item in a collection. + _.invoke = (obj, method) -> + args = _.rest arguments, 2 + (if method then val[method] else val).apply(val, args) for val in obj + + + # Convenience version of a common use case of **map**: fetching a property. + _.pluck = (obj, key) -> + _.map(obj, (val) -> val[key]) + + + # Return the maximum item or (item-based computation). + _.max = (obj, iterator, context) -> + return Math.max.apply(Math, obj) if not iterator and _.isArray(obj) + result = computed: -Infinity + _.each obj, (value, index, list) -> + computed = if iterator then iterator.call(context, value, index, list) else value + computed >= result.computed and (result = {value: value, computed: computed}) + result.value + + + # Return the minimum element (or element-based computation). + _.min = (obj, iterator, context) -> + return Math.min.apply(Math, obj) if not iterator and _.isArray(obj) + result = computed: Infinity + _.each obj, (value, index, list) -> + computed = if iterator then iterator.call(context, value, index, list) else value + computed < result.computed and (result = {value: value, computed: computed}) + result.value + + + # Sort the object's values by a criterion produced by an iterator. + _.sortBy = (obj, iterator, context) -> + _.pluck(((_.map obj, (value, index, list) -> + {value: value, criteria: iterator.call(context, value, index, list)} + ).sort((left, right) -> + a = left.criteria; b = right.criteria + if a < b then -1 else if a > b then 1 else 0 + )), 'value') + + + # Use a comparator function to figure out at what index an object should + # be inserted so as to maintain order. Uses binary search. + _.sortedIndex = (array, obj, iterator) -> + iterator ||= _.identity + low = 0 + high = array.length + while low < high + mid = (low + high) >> 1 + if iterator(array[mid]) < iterator(obj) then low = mid + 1 else high = mid + low + + + # Convert anything iterable into a real, live array. + _.toArray = (iterable) -> + return [] if (!iterable) + return iterable.toArray() if (iterable.toArray) + return iterable if (_.isArray(iterable)) + return slice.call(iterable) if (_.isArguments(iterable)) + _.values(iterable) + + + # Return the number of elements in an object. + _.size = (obj) -> _.toArray(obj).length + + + # Array Functions + # --------------- + + # Get the first element of an array. Passing `n` will return the first N + # values in the array. Aliased as **head**. The `guard` check allows it to work + # with **map**. + _.first = (array, n, guard) -> + if n and not guard then slice.call(array, 0, n) else array[0] + + + # Returns everything but the first entry of the array. Aliased as **tail**. + # Especially useful on the arguments object. Passing an `index` will return + # the rest of the values in the array from that index onward. The `guard` + # check allows it to work with **map**. + _.rest = (array, index, guard) -> + slice.call(array, if _.isUndefined(index) or guard then 1 else index) + + + # Get the last element of an array. + _.last = (array) -> array[array.length - 1] + + + # Trim out all falsy values from an array. + _.compact = (array) -> item for item in array when item + + + # Return a completely flattened version of an array. + _.flatten = (array) -> + _.reduce array, (memo, value) -> + return memo.concat(_.flatten(value)) if _.isArray value + memo.push value + memo + , [] + + + # Return a version of the array that does not contain the specified value(s). + _.without = (array) -> + values = _.rest arguments + val for val in _.toArray(array) when not _.include values, val + + + # Produce a duplicate-free version of the array. If the array has already + # been sorted, you have the option of using a faster algorithm. + _.uniq = (array, isSorted) -> + memo = [] + for el, i in _.toArray array + memo.push el if i is 0 || (if isSorted is true then _.last(memo) isnt el else not _.include(memo, el)) + memo + + + # Produce an array that contains every item shared between all the + # passed-in arrays. + _.intersect = (array) -> + rest = _.rest arguments + _.select _.uniq(array), (item) -> + _.all rest, (other) -> + _.indexOf(other, item) >= 0 + + + # Zip together multiple lists into a single array -- elements that share + # an index go together. + _.zip = -> + length = _.max _.pluck arguments, 'length' + results = new Array length + for i in [0...length] + results[i] = _.pluck arguments, String i + results + + + # If the browser doesn't supply us with **indexOf** (I'm looking at you, MSIE), + # we need this function. Return the position of the first occurence of an + # item in an array, or -1 if the item is not included in the array. + _.indexOf = (array, item) -> + return array.indexOf item if nativeIndexOf and array.indexOf is nativeIndexOf + i = 0; l = array.length + while l - i + if array[i] is item then return i else i++ + -1 + + + # Provide JavaScript 1.6's **lastIndexOf**, delegating to the native function, + # if possible. + _.lastIndexOf = (array, item) -> + return array.lastIndexOf(item) if nativeLastIndexOf and array.lastIndexOf is nativeLastIndexOf + i = array.length + while i + if array[i] is item then return i else i-- + -1 + + + # Generate an integer Array containing an arithmetic progression. A port of + # [the native Python **range** function](http://docs.python.org/library/functions.html#range). + _.range = (start, stop, step) -> + a = arguments + solo = a.length <= 1 + i = start = if solo then 0 else a[0] + stop = if solo then a[0] else a[1] + step = a[2] or 1 + len = Math.ceil((stop - start) / step) + return [] if len <= 0 + range = new Array len + idx = 0 + loop + return range if (if step > 0 then i - stop else stop - i) >= 0 + range[idx] = i + idx++ + i+= step + + + # Function Functions + # ------------------ + + # Create a function bound to a given object (assigning `this`, and arguments, + # optionally). Binding with arguments is also known as **curry**. + _.bind = (func, obj) -> + args = _.rest arguments, 2 + -> func.apply obj or root, args.concat arguments + + + # Bind all of an object's methods to that object. Useful for ensuring that + # all callbacks defined on an object belong to it. + _.bindAll = (obj) -> + funcs = if arguments.length > 1 then _.rest(arguments) else _.functions(obj) + _.each funcs, (f) -> obj[f] = _.bind obj[f], obj + obj + + + # Delays a function for the given number of milliseconds, and then calls + # it with the arguments supplied. + _.delay = (func, wait) -> + args = _.rest arguments, 2 + setTimeout((-> func.apply(func, args)), wait) + + + # Memoize an expensive function by storing its results. + _.memoize = (func, hasher) -> + memo = {} + hasher or= _.identity + -> + key = hasher.apply this, arguments + return memo[key] if key of memo + memo[key] = func.apply this, arguments + + + # Defers a function, scheduling it to run after the current call stack has + # cleared. + _.defer = (func) -> + _.delay.apply _, [func, 1].concat _.rest arguments + + + # Returns the first function passed as an argument to the second, + # allowing you to adjust arguments, run code before and after, and + # conditionally execute the original function. + _.wrap = (func, wrapper) -> + -> wrapper.apply wrapper, [func].concat arguments + + + # Returns a function that is the composition of a list of functions, each + # consuming the return value of the function that follows. + _.compose = -> + funcs = arguments + -> + args = arguments + for i in [(funcs.length - 1)..0] + args = [funcs[i].apply(this, args)] + args[0] + + + # Object Functions + # ---------------- + + # Retrieve the names of an object's properties. + _.keys = nativeKeys or (obj) -> + return _.range 0, obj.length if _.isArray(obj) + key for key, val of obj + + + # Retrieve the values of an object's properties. + _.values = (obj) -> + _.map obj, _.identity + + + # Return a sorted list of the function names available in Underscore. + _.functions = (obj) -> + _.filter(_.keys(obj), (key) -> _.isFunction(obj[key])).sort() + + + # Extend a given object with all of the properties in a source object. + _.extend = (obj) -> + for source in _.rest(arguments) + (obj[key] = val) for key, val of source + obj + + + # Create a (shallow-cloned) duplicate of an object. + _.clone = (obj) -> + return obj.slice 0 if _.isArray obj + _.extend {}, obj + + + # Invokes interceptor with the obj, and then returns obj. + # The primary purpose of this method is to "tap into" a method chain, in order to perform operations on intermediate results within the chain. + _.tap = (obj, interceptor) -> + interceptor obj + obj + + + # Perform a deep comparison to check if two objects are equal. + _.isEqual = (a, b) -> + # Check object identity. + return true if a is b + # Different types? + atype = typeof(a); btype = typeof(b) + return false if atype isnt btype + # Basic equality test (watch out for coercions). + return true if `a == b` + # One is falsy and the other truthy. + return false if (!a and b) or (a and !b) + # One of them implements an `isEqual()`? + return a.isEqual(b) if a.isEqual + # Check dates' integer values. + return a.getTime() is b.getTime() if _.isDate(a) and _.isDate(b) + # Both are NaN? + return false if _.isNaN(a) and _.isNaN(b) + # Compare regular expressions. + if _.isRegExp(a) and _.isRegExp(b) + return a.source is b.source and + a.global is b.global and + a.ignoreCase is b.ignoreCase and + a.multiline is b.multiline + # If a is not an object by this point, we can't handle it. + return false if atype isnt 'object' + # Check for different array lengths before comparing contents. + return false if a.length and (a.length isnt b.length) + # Nothing else worked, deep compare the contents. + aKeys = _.keys(a); bKeys = _.keys(b) + # Different object sizes? + return false if aKeys.length isnt bKeys.length + # Recursive comparison of contents. + (return false) for all key, val of a when !(key of b) or !_.isEqual(val, b[key]) + true + + + # Is a given array or object empty? + _.isEmpty = (obj) -> + return obj.length is 0 if _.isArray(obj) or _.isString(obj) + (return false) for key of obj when hasOwnProperty.call(obj, key) + true + + + # Is a given value a DOM element? + _.isElement = (obj) -> obj and obj.nodeType is 1 + + + # Is a given value an array? + _.isArray = nativeIsArray or (obj) -> !!(obj and obj.concat and obj.unshift and not obj.callee) + + + # Is a given variable an arguments object? + _.isArguments = (obj) -> obj and obj.callee + + + # Is the given value a function? + _.isFunction = (obj) -> !!(obj and obj.constructor and obj.call and obj.apply) + + + # Is the given value a string? + _.isString = (obj) -> !!(obj is '' or (obj and obj.charCodeAt and obj.substr)) + + + # Is a given value a number? + _.isNumber = (obj) -> (obj is +obj) or toString.call(obj) is '[object Number]' + + + # Is a given value a boolean? + _.isBoolean = (obj) -> obj is true or obj is false + + + # Is a given value a Date? + _.isDate = (obj) -> !!(obj and obj.getTimezoneOffset and obj.setUTCFullYear) + + + # Is the given value a regular expression? + _.isRegExp = (obj) -> !!(obj and obj.exec and (obj.ignoreCase or obj.ignoreCase is false)) + + + # Is the given value NaN -- this one is interesting. `NaN != NaN`, and + # `isNaN(undefined) == true`, so we make sure it's a number first. + _.isNaN = (obj) -> _.isNumber(obj) and window.isNaN(obj) + + + # Is a given value equal to null? + _.isNull = (obj) -> obj is null + + + # Is a given variable undefined? + _.isUndefined = (obj) -> typeof obj is 'undefined' + + + # Utility Functions + # ----------------- + + # Run Underscore.js in noConflict mode, returning the `_` variable to its + # previous owner. Returns a reference to the Underscore object. + _.noConflict = -> + root._ = previousUnderscore + this + + + # Keep the identity function around for default iterators. + _.identity = (value) -> value + + + # Run a function `n` times. + _.times = (n, iterator, context) -> + iterator.call(context, i) for i in [0...n] + + + # Break out of the middle of an iteration. + _.breakLoop = -> throw breaker + + + # Add your own custom functions to the Underscore object, ensuring that + # they're correctly added to the OOP wrapper as well. + _.mixin = (obj) -> + for name in _.functions(obj) + addToWrapper name, _[name] = obj[name] + + + # Generate a unique integer id (unique within the entire client session). + # Useful for temporary DOM ids. + idCounter = 0 + _.uniqueId = (prefix) -> + (prefix or '') + idCounter++ + + + # By default, Underscore uses **ERB**-style template delimiters, change the + # following template settings to use alternative delimiters. + _.templateSettings = { + start: '<%' + end: '%>' + interpolate: /<%=(.+?)%>/g + } + + + # JavaScript templating a-la **ERB**, pilfered from John Resig's + # *Secrets of the JavaScript Ninja*, page 83. + # Single-quote fix from Rick Strahl. + # With alterations for arbitrary delimiters, and to preserve whitespace. + _.template = (str, data) -> + c = _.templateSettings + endMatch = new RegExp("'(?=[^"+c.end.substr(0, 1)+"]*"+escapeRegExp(c.end)+")","g") + fn = new Function 'obj', + 'var p=[],print=function(){p.push.apply(p,arguments);};' + + 'with(obj||{}){p.push(\'' + + str.replace(/\r/g, '\\r') + .replace(/\n/g, '\\n') + .replace(/\t/g, '\\t') + .replace(endMatch,"✄") + .split("'").join("\\'") + .split("✄").join("'") + .replace(c.interpolate, "',$1,'") + .split(c.start).join("');") + .split(c.end).join("p.push('") + + "');}return p.join('');" + if data then fn(data) else fn + + + # Aliases + # ------- + + _.forEach = _.each + _.foldl = _.inject = _.reduce + _.foldr = _.reduceRight + _.select = _.filter + _.all = _.every + _.any = _.some + _.contains = _.include + _.head = _.first + _.tail = _.rest + _.methods = _.functions + + + # Setup the OOP Wrapper + # --------------------- + + # If Underscore is called as a function, it returns a wrapped object that + # can be used OO-style. This wrapper holds altered versions of all the + # underscore functions. Wrapped objects may be chained. + wrapper = (obj) -> + this._wrapped = obj + this + + + # Helper function to continue chaining intermediate results. + result = (obj, chain) -> + if chain then _(obj).chain() else obj + + + # A method to easily add functions to the OOP wrapper. + addToWrapper = (name, func) -> + wrapper.prototype[name] = -> + args = _.toArray arguments + unshift.call args, this._wrapped + result func.apply(_, args), this._chain + + + # Add all of the Underscore functions to the wrapper object. + _.mixin _ + + + # Add all mutator Array functions to the wrapper. + _.each ['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], (name) -> + method = Array.prototype[name] + wrapper.prototype[name] = -> + method.apply(this._wrapped, arguments) + result(this._wrapped, this._chain) + + + # Add all accessor Array functions to the wrapper. + _.each ['concat', 'join', 'slice'], (name) -> + method = Array.prototype[name] + wrapper.prototype[name] = -> + result(method.apply(this._wrapped, arguments), this._chain) + + + # Start chaining a wrapped Underscore object. + wrapper::chain = -> + this._chain = true + this + + + # Extracts the result from a wrapped and chained object. + wrapper::value = -> this._wrapped diff --git a/node_modules/jade/support/coffee-script/examples/web_server.coffee b/node_modules/jade/support/coffee-script/examples/web_server.coffee new file mode 100644 index 0000000..c2ee089 --- /dev/null +++ b/node_modules/jade/support/coffee-script/examples/web_server.coffee @@ -0,0 +1,13 @@ +# Contributed by Jason Huggins + +sys = require 'sys' +http = require 'http' + +server = http.createServer (req, res) -> + res.writeHeader 200, 'Content-Type': 'text/plain' + res.write 'Hello, World!' + res.end() + +server.listen 3000 + +sys.puts "Server running at http://localhost:3000/" diff --git a/node_modules/jade/support/coffee-script/extras/EXTRAS b/node_modules/jade/support/coffee-script/extras/EXTRAS new file mode 100644 index 0000000..79ec413 --- /dev/null +++ b/node_modules/jade/support/coffee-script/extras/EXTRAS @@ -0,0 +1,7 @@ +EXTRAS: + +"extras/coffee-script.js" is a concatenated and compressed version of the +CoffeeScript compiler. To use it in the browser, include the script after any +inline script tags of type "text/coffeescript" on the page. It will compile +and evaluate all of the scripts in order. + diff --git a/node_modules/jade/support/coffee-script/extras/coffee-script.js b/node_modules/jade/support/coffee-script/extras/coffee-script.js new file mode 100644 index 0000000..71b8181 --- /dev/null +++ b/node_modules/jade/support/coffee-script/extras/coffee-script.js @@ -0,0 +1,8 @@ +/** + * CoffeeScript Compiler v0.9.4 + * http://coffeescript.org + * + * Copyright 2010, Jeremy Ashkenas + * Released under the MIT License + */ +this.CoffeeScript=function(){function require(path){return require[path]}require["./helpers"]=new function(){var exports=this;(function(){var extend,flatten,indexOf;indexOf=(exports.indexOf=Array.indexOf||(Array.prototype.indexOf?function(array,item,from){return array.indexOf(item,from)}:function(array,item,from){var _len,index,other;for(index=0,_len=array.length;index<_len;index++){other=array[index];if(other===item&&(!from||(from<=index))){return index}}return -1}));exports.include=function(list,value){return indexOf(list,value)>=0};exports.starts=function(string,literal,start){return literal===string.substr(start,literal.length)};exports.ends=function(string,literal,back){var len;len=literal.length;return literal===string.substr(string.length-len-(back||0),len)};exports.compact=function(array){var _i,_len,_result,item;_result=[];for(_i=0,_len=array.length;_i<_len;_i++){item=array[_i];if(item){_result.push(item)}}return _result};exports.count=function(string,letter){var num,pos;num=(pos=0);while(pos=1+string.indexOf(letter,pos)){num++}return num};exports.merge=function(options,overrides){return extend(extend({},options),overrides)};extend=(exports.extend=function(object,properties){var key,val;for(key in properties){val=properties[key];object[key]=val}return object});exports.flatten=(flatten=function(array){var _i,_len,element,flattened;flattened=[];for(_i=0,_len=array.length;_i<_len;_i++){element=array[_i];if(element instanceof Array){flattened=flattened.concat(flatten(element))}else{flattened.push(element)}}return flattened});exports.del=function(obj,key){var val;val=obj[key];delete obj[key];return val};exports.last=function(array,back){return array[array.length-(back||0)-1]}}).call(this)};require["./rewriter"]=new function(){var exports=this;(function(){var BALANCED_PAIRS,EXPRESSION_CLOSE,EXPRESSION_END,EXPRESSION_START,IMPLICIT_BLOCK,IMPLICIT_CALL,IMPLICIT_END,IMPLICIT_FUNC,INVERSES,LINEBREAKS,SINGLE_CLOSERS,SINGLE_LINERS,_i,_len,_ref,include,left,rite;include=require("./helpers").include;exports.Rewriter=(function(){function Rewriter(){}return Rewriter})();exports.Rewriter.prototype.rewrite=function(_arg){this.tokens=_arg;this.adjustComments();this.removeLeadingNewlines();this.removeMidExpressionNewlines();this.closeOpenCalls();this.closeOpenIndexes();this.addImplicitIndentation();this.tagPostfixConditionals();this.addImplicitBraces();this.addImplicitParentheses();this.ensureBalance(BALANCED_PAIRS);this.rewriteClosingParens();return this.tokens};exports.Rewriter.prototype.scanTokens=function(block){var i,token,tokens;tokens=this.tokens;i=0;while(token=tokens[i]){i+=block.call(this,token,i,tokens)}return true};exports.Rewriter.prototype.detectEnd=function(i,condition,action){var levels,token,tokens;tokens=this.tokens;levels=0;while(token=tokens[i]){if(levels===0&&condition.call(this,token,i)){return action.call(this,token,i)}if(!token||levels<0){return action.call(this,token,i-1)}if(include(EXPRESSION_START,token[0])){levels+=1}else{if(include(EXPRESSION_END,token[0])){levels-=1}}i+=1}return i-1};exports.Rewriter.prototype.adjustComments=function(){return this.scanTokens(function(token,i,tokens){var _ref,after,before,post,prev;if(token[0]!=="HERECOMMENT"){return 1}before=tokens[i-2];prev=tokens[i-1];post=tokens[i+1];after=tokens[i+2];if(((after!=null)?after[0]:undefined)==="INDENT"){tokens.splice(i+2,1);if(((before!=null)?before[0]:undefined)==="OUTDENT"&&((post!=null)?post[0]:undefined)==="TERMINATOR"){tokens.splice(i-2,1)}else{tokens.splice(i,0,after)}}else{if(prev&&!((_ref=prev[0])==="TERMINATOR"||_ref==="INDENT"||_ref==="OUTDENT")){if(((post!=null)?post[0]:undefined)==="TERMINATOR"&&((after!=null)?after[0]:undefined)==="OUTDENT"){tokens.splice.apply(tokens,[i+2,0].concat(tokens.splice(i,2)));if(tokens[i+2][0]!=="TERMINATOR"){tokens.splice(i+2,0,["TERMINATOR","\n",prev[2]])}}else{tokens.splice(i,0,["TERMINATOR","\n",prev[2]])}return 2}}return 1})};exports.Rewriter.prototype.removeLeadingNewlines=function(){var _len,_ref,i,tag;for(i=0,_len=(_ref=this.tokens).length;i<_len;i++){tag=_ref[i][0];if(tag!=="TERMINATOR"){break}}return i?this.tokens.splice(0,i):undefined};exports.Rewriter.prototype.removeMidExpressionNewlines=function(){return this.scanTokens(function(token,i,tokens){if(!(token[0]==="TERMINATOR"&&include(EXPRESSION_CLOSE,this.tag(i+1)))){return 1}tokens.splice(i,1);return 0})};exports.Rewriter.prototype.closeOpenCalls=function(){var action,condition;condition=function(token,i){var _ref;return((_ref=token[0])===")"||_ref==="CALL_END")||token[0]==="OUTDENT"&&this.tag(i-1)===")"};action=function(token,i){return(this.tokens[token[0]==="OUTDENT"?i-1:i][0]="CALL_END")};return this.scanTokens(function(token,i){if(token[0]==="CALL_START"){this.detectEnd(i+1,condition,action)}return 1})};exports.Rewriter.prototype.closeOpenIndexes=function(){var action,condition;condition=function(token,i){var _ref;return((_ref=token[0])==="]"||_ref==="INDEX_END")};action=function(token,i){return(token[0]="INDEX_END")};return this.scanTokens(function(token,i){if(token[0]==="INDEX_START"){this.detectEnd(i+1,condition,action)}return 1})};exports.Rewriter.prototype.addImplicitBraces=function(){var action,condition,stack;stack=[];condition=function(token,i){var _ref,_ref2,one,tag,three,two;if(("HERECOMMENT"===this.tag(i+1)||"HERECOMMENT"===this.tag(i-1))){return false}_ref=this.tokens.slice(i+1,i+4),one=_ref[0],two=_ref[1],three=_ref[2];tag=token[0];return(tag==="TERMINATOR"||tag==="OUTDENT")&&!(((two!=null)?two[0]:undefined)===":"||((one!=null)?one[0]:undefined)==="@"&&((three!=null)?three[0]:undefined)===":")||tag===","&&!((_ref2=((one!=null)?one[0]:undefined))==="IDENTIFIER"||_ref2==="NUMBER"||_ref2==="STRING"||_ref2==="@"||_ref2==="TERMINATOR"||_ref2==="OUTDENT")};action=function(token,i){return this.tokens.splice(i,0,["}","}",token[2]])};return this.scanTokens(function(token,i,tokens){var idx,tag,tok;if(include(EXPRESSION_START,tag=token[0])){stack.push(tag==="INDENT"&&this.tag(i-1)==="{"?"{":tag);return 1}if(include(EXPRESSION_END,tag)){stack.pop();return 1}if(!(tag===":"&&stack[stack.length-1]!=="{")){return 1}stack.push("{");idx=this.tag(i-2)==="@"?i-2:i-1;if(this.tag(idx-2)==="HERECOMMENT"){idx-=2}tok=["{","{",token[2]];tok.generated=true;tokens.splice(idx,0,tok);this.detectEnd(i+2,condition,action);return 2})};exports.Rewriter.prototype.addImplicitParentheses=function(){var action,classLine;classLine=false;action=function(token,i){var idx;idx=token[0]==="OUTDENT"?i+1:i;return this.tokens.splice(idx,0,["CALL_END",")",token[2]])};return this.scanTokens(function(token,i,tokens){var callObject,next,prev,seenSingle,tag;tag=token[0];if(tag==="CLASS"){classLine=true}prev=tokens[i-1];next=tokens[i+1];callObject=!classLine&&tag==="INDENT"&&next&&next.generated&&next[0]==="{"&&prev&&include(IMPLICIT_FUNC,prev[0]);seenSingle=false;if(include(LINEBREAKS,tag)){classLine=false}if(prev&&!prev.spaced&&tag==="?"){token.call=true}if(!(callObject||((prev!=null)?prev.spaced:undefined)&&(prev.call||include(IMPLICIT_FUNC,prev[0]))&&include(IMPLICIT_CALL,tag))){return 1}tokens.splice(i,0,["CALL_START","(",token[2]]);this.detectEnd(i+(callObject?2:1),function(token,i){var post;if(!seenSingle&&token.fromThen){return true}tag=token[0];if((tag==="IF"||tag==="ELSE"||tag==="UNLESS"||tag==="->"||tag==="=>")){seenSingle=true}if(tag==="PROPERTY_ACCESS"&&this.tag(i-1)==="OUTDENT"){return true}return !token.generated&&this.tag(i-1)!==","&&include(IMPLICIT_END,tag)&&(tag!=="INDENT"||(this.tag(i-2)!=="CLASS"&&!include(IMPLICIT_BLOCK,this.tag(i-1))&&!((post=this.tokens[i+1])&&post.generated&&post[0]==="{")))},action);if(prev[0]==="?"){prev[0]="FUNC_EXIST"}return 2})};exports.Rewriter.prototype.addImplicitIndentation=function(){return this.scanTokens(function(token,i,tokens){var _ref,_ref2,action,condition,indent,outdent,starter,tag;tag=token[0];if(tag==="ELSE"&&this.tag(i-1)!=="OUTDENT"){tokens.splice.apply(tokens,[i,0].concat(this.indentation(token)));return 2}if(tag==="CATCH"&&((_ref=this.tag(i+2))==="TERMINATOR"||_ref==="FINALLY")){tokens.splice.apply(tokens,[i+2,0].concat(this.indentation(token)));return 4}if(include(SINGLE_LINERS,tag)&&this.tag(i+1)!=="INDENT"&&!(tag==="ELSE"&&this.tag(i+1)==="IF")){starter=tag;_ref2=this.indentation(token),indent=_ref2[0],outdent=_ref2[1];if(starter==="THEN"){indent.fromThen=true}indent.generated=(outdent.generated=true);tokens.splice(i+1,0,indent);condition=function(token,i){return token[1]!==";"&&include(SINGLE_CLOSERS,token[0])&&!(token[0]==="ELSE"&&!(starter==="IF"||starter==="THEN"))};action=function(token,i){return this.tokens.splice(this.tag(i-1)===","?i-1:i,0,outdent)};this.detectEnd(i+2,condition,action);if(tag==="THEN"){tokens.splice(i,1)}return 1}return 1})};exports.Rewriter.prototype.tagPostfixConditionals=function(){var condition;condition=function(token,i){var _ref;return((_ref=token[0])==="TERMINATOR"||_ref==="INDENT")};return this.scanTokens(function(token,i){var _ref,original;if(!((_ref=token[0])==="IF"||_ref==="UNLESS")){return 1}original=token;this.detectEnd(i+1,condition,function(token,i){return token[0]!=="INDENT"?(original[0]="POST_"+original[0]):undefined});return 1})};exports.Rewriter.prototype.ensureBalance=function(pairs){var _result,key,levels,open,openLine,unclosed,value;levels={};openLine={};this.scanTokens(function(token,i){var _i,_len,_ref,_ref2,close,open,tag;tag=token[0];for(_i=0,_len=(_ref=pairs).length;_i<_len;_i++){_ref2=_ref[_i],open=_ref2[0],close=_ref2[1];levels[open]|=0;if(tag===open){if(levels[open]===0){openLine[open]=token[2]}levels[open]+=1}else{if(tag===close){levels[open]-=1}}if(levels[open]<0){throw Error("too many "+(token[1])+" on line "+(token[2]+1))}}return 1});unclosed=(function(){_result=[];for(key in levels){value=levels[key];if(value>0){_result.push(key)}}return _result})();if(unclosed.length){throw Error("unclosed "+(open=unclosed[0])+" on line "+(openLine[open]+1))}};exports.Rewriter.prototype.rewriteClosingParens=function(){var debt,key,stack;stack=[];debt={};for(key in INVERSES){(debt[key]=0)}return this.scanTokens(function(token,i,tokens){var inv,match,mtag,oppos,tag,val;if(include(EXPRESSION_START,tag=token[0])){stack.push(token);return 1}if(!include(EXPRESSION_END,tag)){return 1}if(debt[(inv=INVERSES[tag])]>0){debt[inv]-=1;tokens.splice(i,1);return 0}match=stack.pop();mtag=match[0];oppos=INVERSES[mtag];if(tag===oppos){return 1}debt[mtag]+=1;val=[oppos,mtag==="INDENT"?match[1]:oppos];if(this.tag(i+2)===mtag){tokens.splice(i+3,0,val);stack.push(match)}else{tokens.splice(i,0,val)}return 1})};exports.Rewriter.prototype.indentation=function(token){return[["INDENT",2,token[2]],["OUTDENT",2,token[2]]]};exports.Rewriter.prototype.tag=function(i){var _ref;return(((_ref=this.tokens[i])!=null)?_ref[0]:undefined)};BALANCED_PAIRS=[["(",")"],["[","]"],["{","}"],["INDENT","OUTDENT"],["CALL_START","CALL_END"],["PARAM_START","PARAM_END"],["INDEX_START","INDEX_END"]];INVERSES={};EXPRESSION_START=[];EXPRESSION_END=[];for(_i=0,_len=BALANCED_PAIRS.length;_i<_len;_i++){_ref=BALANCED_PAIRS[_i],left=_ref[0],rite=_ref[1];EXPRESSION_START.push(INVERSES[rite]=left);EXPRESSION_END.push(INVERSES[left]=rite)}EXPRESSION_CLOSE=["CATCH","WHEN","ELSE","FINALLY"].concat(EXPRESSION_END);IMPLICIT_FUNC=["IDENTIFIER","SUPER",")","CALL_END","]","INDEX_END","@","THIS"];IMPLICIT_CALL=["IDENTIFIER","NUMBER","STRING","JS","REGEX","NEW","PARAM_START","CLASS","IF","UNLESS","TRY","SWITCH","THIS","BOOL","UNARY","@","->","=>","[","(","{"];IMPLICIT_BLOCK=["->","=>","{","[",","];IMPLICIT_END=["POST_IF","POST_UNLESS","FOR","WHILE","UNTIL","LOOP","TERMINATOR","INDENT"];SINGLE_LINERS=["ELSE","->","=>","TRY","FINALLY","THEN"];SINGLE_CLOSERS=["TERMINATOR","CATCH","FINALLY","ELSE","OUTDENT","LEADING_WHEN"];LINEBREAKS=["TERMINATOR","INDENT","OUTDENT"]}).call(this)};require["./lexer"]=new function(){var exports=this;(function(){var ASSIGNED,BOOL,CALLABLE,CODE,COFFEE_ALIASES,COFFEE_KEYWORDS,COMMENT,COMPARE,COMPOUND_ASSIGN,HEREDOC,HEREDOC_INDENT,HEREGEX,HEREGEX_OMIT,IDENTIFIER,INDEXABLE,JSTOKEN,JS_FORBIDDEN,JS_KEYWORDS,LEADING_SPACES,LINE_BREAK,LOGIC,Lexer,MATH,MULTILINER,MULTI_DENT,NEXT_CHARACTER,NEXT_ELLIPSIS,NOT_REGEX,NO_NEWLINE,NUMBER,OPERATOR,REGEX,RELATION,RESERVED,Rewriter,SHIFT,SIMPLESTR,TRAILING_SPACES,UNARY,WHITESPACE,_ref,compact,count,include,last,op,starts;Rewriter=require("./rewriter").Rewriter;_ref=require("./helpers"),include=_ref.include,count=_ref.count,starts=_ref.starts,compact=_ref.compact,last=_ref.last;exports.Lexer=(function(){Lexer=(function(){function Lexer(){}return Lexer})();Lexer.prototype.tokenize=function(code,options){var o;code=code.replace(/\r/g,"").replace(TRAILING_SPACES,"");o=options||{};this.code=code;this.i=0;this.line=o.line||0;this.indent=0;this.indebt=0;this.outdebt=0;this.seenFor=false;this.indents=[];this.tokens=[];while(this.chunk=code.slice(this.i)){this.identifierToken()||this.commentToken()||this.whitespaceToken()||this.lineToken()||this.heredocToken()||this.stringToken()||this.numberToken()||this.regexToken()||this.jsToken()||this.literalToken()}this.closeIndentation();if(o.rewrite===false){return this.tokens}return(new Rewriter).rewrite(this.tokens)};Lexer.prototype.identifierToken=function(){var colon,forcedIdentifier,id,input,match,tag;if(!(match=IDENTIFIER.exec(this.chunk))){return false}input=match[0],id=match[1],colon=match[2];this.i+=input.length;if(id==="all"&&this.tag()==="FOR"){this.token("ALL",id);return true}forcedIdentifier=colon||this.tagAccessor();tag="IDENTIFIER";if(include(JS_KEYWORDS,id)||!forcedIdentifier&&include(COFFEE_KEYWORDS,id)){tag=id.toUpperCase();if(tag==="WHEN"&&include(LINE_BREAK,this.tag())){tag="LEADING_WHEN"}else{if(tag==="FOR"){this.seenFor=true}else{if(include(UNARY,tag)){tag="UNARY"}else{if(include(RELATION,tag)){if(tag!=="INSTANCEOF"&&this.seenFor){this.seenFor=false;tag="FOR"+tag}else{tag="RELATION";if(this.value()==="!"){this.tokens.pop();id="!"+id}}}}}}}if(include(JS_FORBIDDEN,id)){if(forcedIdentifier){tag="IDENTIFIER";id=new String(id);id.reserved=true}else{if(include(RESERVED,id)){this.identifierError(id)}}}if(!forcedIdentifier){if(COFFEE_ALIASES.hasOwnProperty(id)){tag=(id=COFFEE_ALIASES[id])}if(id==="!"){tag="UNARY"}else{if(include(LOGIC,id)){tag="LOGIC"}else{if(include(BOOL,tag)){id=tag.toLowerCase();tag="BOOL"}}}}this.token(tag,id);if(colon){this.token(":",":")}return true};Lexer.prototype.numberToken=function(){var match,number;if(!(match=NUMBER.exec(this.chunk))){return false}number=match[0];if(this.tag()==="."&&number.charAt(0)==="."){return false}this.i+=number.length;this.token("NUMBER",number);return true};Lexer.prototype.stringToken=function(){var match,string;switch(this.chunk.charAt(0)){case"'":if(!(match=SIMPLESTR.exec(this.chunk))){return false}this.token("STRING",(string=match[0]).replace(MULTILINER,"\\\n"));break;case'"':if(!(string=this.balancedString(this.chunk,[['"','"'],["#{","}"]]))){return false}if(0body.indexOf("#{")){re=body.replace(HEREGEX_OMIT,"").replace(/\//g,"\\/");this.token("REGEX","/"+(re||"(?:)")+"/"+flags);return true}this.token("IDENTIFIER","RegExp");this.tokens.push(["CALL_START","("]);tokens=[];for(_i=0,_len=(_ref2=this.interpolateString(body,{regex:true})).length;_i<_len;_i++){_ref3=_ref2[_i],tag=_ref3[0],value=_ref3[1];if(tag==="TOKENS"){tokens.push.apply(tokens,value)}else{if(!(value=value.replace(HEREGEX_OMIT,""))){continue}value=value.replace(/\\/g,"\\\\");tokens.push(["STRING",this.makeString(value,'"',true)])}tokens.push(["+","+"])}tokens.pop();if((((_ref4=tokens[0])!=null)?_ref4[0]:undefined)!=="STRING"){this.tokens.push(["STRING",'""'],["+","+"])}(_this=this.tokens).push.apply(_this,tokens);if(flags){this.tokens.push([",",","],["STRING",'"'+flags+'"'])}this.token(")",")");return true};Lexer.prototype.lineToken=function(){var diff,indent,match,nextCharacter,noNewlines,prev,size;if(!(match=MULTI_DENT.exec(this.chunk))){return false}indent=match[0];this.line+=count(indent,"\n");this.i+=indent.length;prev=last(this.tokens,1);size=indent.length-1-indent.lastIndexOf("\n");nextCharacter=NEXT_CHARACTER.exec(this.chunk)[1];noNewlines=((nextCharacter==="."||nextCharacter===",")&&!NEXT_ELLIPSIS.test(this.chunk))||this.unfinished();if(size-this.indebt===this.indent){if(noNewlines){return this.suppressNewlines()}return this.newlineToken(indent)}else{if(size>this.indent){if(noNewlines){this.indebt=size-this.indent;return this.suppressNewlines()}diff=size-this.indent+this.outdebt;this.token("INDENT",diff);this.indents.push(diff);this.outdebt=(this.indebt=0)}else{this.indebt=0;this.outdentToken(this.indent-size,noNewlines)}}this.indent=size;return true};Lexer.prototype.outdentToken=function(moveOut,noNewlines,close){var dent,len;while(moveOut>0){len=this.indents.length-1;if(this.indents[len]===undefined){moveOut=0}else{if(this.indents[len]===this.outdebt){moveOut-=this.outdebt;this.outdebt=0}else{if(this.indents[len]doc.indexOf("\n")){return doc}if(!herecomment){while(match=HEREDOC_INDENT.exec(doc)){attempt=match[1];if(indent===null||(0<(_ref2=attempt.length))&&(_ref21){nested.unshift(["(","("]);nested.push([")",")"])}tokens.push(["TOKENS",nested])}i+=expr.length;pi=i+1}if((i>pi)&&(pi1){this.token("(","(")}for(i=0,_len=tokens.length;i<_len;i++){_ref3=tokens[i],tag=_ref3[0],value=_ref3[1];if(i){this.token("+","+")}if(tag==="TOKENS"){(_this=this.tokens).push.apply(_this,value)}else{this.token("STRING",this.makeString(value,'"',heredoc))}}if(interpolated){this.token(")",")")}return tokens};Lexer.prototype.token=function(tag,value){return this.tokens.push([tag,value,this.line])};Lexer.prototype.tag=function(index,tag){var tok;return(tok=last(this.tokens,index))&&((tag!=null)?(tok[0]=tag):tok[0])};Lexer.prototype.value=function(index,val){var tok;return(tok=last(this.tokens,index))&&((val!=null)?(tok[1]=val):tok[1])};Lexer.prototype.unfinished=function(){var prev,value;return(prev=last(this.tokens,1))&&prev[0]!=="."&&(value=this.value())&&!value.reserved&&NO_NEWLINE.test(value)&&!CODE.test(value)&&!ASSIGNED.test(this.chunk)};Lexer.prototype.escapeLines=function(str,heredoc){return str.replace(MULTILINER,heredoc?"\\n":"")};Lexer.prototype.makeString=function(body,quote,heredoc){if(!body){return quote+quote}body=body.replace(/\\([\s\S])/g,function(match,contents){return(contents==="\n"||contents===quote)?contents:match});body=body.replace(RegExp(""+quote,"g"),"\\$&");return quote+this.escapeLines(body,heredoc)+quote};return Lexer})();JS_KEYWORDS=["true","false","null","this","new","delete","typeof","in","instanceof","return","throw","break","continue","debugger","if","else","switch","for","while","try","catch","finally","class","extends","super"];COFFEE_KEYWORDS=["then","unless","until","loop","of","by","when"];for(op in (COFFEE_ALIASES={and:"&&",or:"||",is:"==",isnt:"!=",not:"!",yes:"TRUE",no:"FALSE",on:"TRUE",off:"FALSE"})){COFFEE_KEYWORDS.push(op)}COFFEE_ALIASES["==="]="==";RESERVED=["case","default","do","function","var","void","with","const","let","enum","export","import","native","__hasProp","__extends","__slice"];JS_FORBIDDEN=JS_KEYWORDS.concat(RESERVED);IDENTIFIER=/^([$A-Za-z_][$\w]*)([^\n\S]*:(?!:))?/;NUMBER=/^0x[\da-f]+|^(?:\d+(\.\d+)?|\.\d+)(?:e[+-]?\d+)?/i;HEREDOC=/^("""|''')([\s\S]*?)(?:\n[ \t]*)?\1/;OPERATOR=/^(?:-[-=>]?|\+[+=]?|\.\.\.?|[*&|\/%=<>^:!?]+)/;WHITESPACE=/^[ \t]+/;COMMENT=/^###([^#][\s\S]*?)(?:###[ \t]*\n|(?:###)?$)|^(?:\s*#(?!##[^#]).*)+/;CODE=/^[-=]>/;MULTI_DENT=/^(?:\n[ \t]*)+/;SIMPLESTR=/^'[^\\']*(?:\\.[^\\']*)*'/;JSTOKEN=/^`[^\\`]*(?:\\.[^\\`]*)*`/;REGEX=/^\/(?!\s)(?:[^[\/\n\\]+|\\[\s\S]|\[([^\]\n\\]+|\\[\s\S])*])+\/[imgy]{0,4}(?![A-Za-z])/;HEREGEX=/^\/{3}([\s\S]+?)\/{3}([imgy]{0,4})(?![A-Za-z])/;HEREGEX_OMIT=/\s+(?:#.*)?/g;MULTILINER=/\n/g;HEREDOC_INDENT=/\n+([ \t]*)/g;ASSIGNED=/^\s*@?[$A-Za-z_][$\w]*[ \t]*?[:=][^:=>]/;NEXT_CHARACTER=/^\s*(\S?)/;NEXT_ELLIPSIS=/^\s*\.\.\.?/;LEADING_SPACES=/^\s+/;TRAILING_SPACES=/\s+$/;NO_NEWLINE=/^(?:[-+*&|\/%=<>!.\\][<>=&|]*|and|or|is(?:nt)?|n(?:ot|ew)|delete|typeof|instanceof)$/;COMPOUND_ASSIGN=["-=","+=","/=","*=","%=","||=","&&=","?=","<<=",">>=",">>>=","&=","^=","|="];UNARY=["UMINUS","UPLUS","!","!!","~","NEW","TYPEOF","DELETE"];LOGIC=["&","|","^","&&","||"];SHIFT=["<<",">>",">>>"];COMPARE=["<=","<",">",">="];MATH=["*","/","%"];RELATION=["IN","OF","INSTANCEOF"];BOOL=["TRUE","FALSE","NULL"];NOT_REGEX=["NUMBER","REGEX","BOOL","++","--","]"];CALLABLE=["IDENTIFIER","STRING","REGEX",")","]","}","?","::","@","THIS","SUPER"];INDEXABLE=CALLABLE.concat("NUMBER","BOOL");LINE_BREAK=["INDENT","OUTDENT","TERMINATOR"]}).call(this)};require["./parser"]=new function(){var exports=this;var parser=(function(){var parser={trace:function trace(){},yy:{},symbols_:{error:2,Root:3,TERMINATOR:4,Body:5,Block:6,Line:7,Expression:8,Statement:9,Return:10,Throw:11,BREAK:12,CONTINUE:13,DEBUGGER:14,Value:15,Invocation:16,Code:17,Operation:18,Assign:19,If:20,Try:21,While:22,For:23,Switch:24,Extends:25,Class:26,Existence:27,Comment:28,INDENT:29,OUTDENT:30,Identifier:31,IDENTIFIER:32,AlphaNumeric:33,NUMBER:34,STRING:35,Literal:36,JS:37,REGEX:38,BOOL:39,Assignable:40,"=":41,AssignObj:42,ThisProperty:43,":":44,RETURN:45,HERECOMMENT:46,"?":47,PARAM_START:48,ParamList:49,PARAM_END:50,FuncGlyph:51,"->":52,"=>":53,OptComma:54,",":55,Param:56,PARAM:57,"@":58,"...":59,Splat:60,SimpleAssignable:61,Accessor:62,Array:63,Object:64,Parenthetical:65,Range:66,This:67,PROPERTY_ACCESS:68,PROTOTYPE_ACCESS:69,"::":70,SOAK_ACCESS:71,Index:72,Slice:73,INDEX_START:74,INDEX_END:75,INDEX_SOAK:76,INDEX_PROTO:77,"{":78,AssignList:79,"}":80,CLASS:81,EXTENDS:82,ClassBody:83,ClassAssign:84,OptFuncExist:85,Arguments:86,SUPER:87,FUNC_EXIST:88,CALL_START:89,CALL_END:90,ArgList:91,THIS:92,RangeDots:93,"..":94,"[":95,"]":96,Arg:97,SimpleArgs:98,TRY:99,Catch:100,FINALLY:101,CATCH:102,THROW:103,"(":104,")":105,WhileSource:106,WHILE:107,WHEN:108,UNTIL:109,Loop:110,LOOP:111,ForBody:112,FOR:113,ForStart:114,ForSource:115,ForVariables:116,ALL:117,ForValue:118,FORIN:119,FOROF:120,BY:121,SWITCH:122,Whens:123,ELSE:124,When:125,LEADING_WHEN:126,IfBlock:127,IF:128,UNLESS:129,POST_IF:130,POST_UNLESS:131,UNARY:132,"-":133,"+":134,"--":135,"++":136,"==":137,"!=":138,MATH:139,SHIFT:140,COMPARE:141,LOGIC:142,COMPOUND_ASSIGN:143,RELATION:144,"$accept":0,"$end":1},terminals_:{"2":"error","4":"TERMINATOR","12":"BREAK","13":"CONTINUE","14":"DEBUGGER","29":"INDENT","30":"OUTDENT","32":"IDENTIFIER","34":"NUMBER","35":"STRING","37":"JS","38":"REGEX","39":"BOOL","41":"=","44":":","45":"RETURN","46":"HERECOMMENT","47":"?","48":"PARAM_START","50":"PARAM_END","52":"->","53":"=>","55":",","57":"PARAM","58":"@","59":"...","68":"PROPERTY_ACCESS","69":"PROTOTYPE_ACCESS","70":"::","71":"SOAK_ACCESS","74":"INDEX_START","75":"INDEX_END","76":"INDEX_SOAK","77":"INDEX_PROTO","78":"{","80":"}","81":"CLASS","82":"EXTENDS","87":"SUPER","88":"FUNC_EXIST","89":"CALL_START","90":"CALL_END","92":"THIS","94":"..","95":"[","96":"]","99":"TRY","101":"FINALLY","102":"CATCH","103":"THROW","104":"(","105":")","107":"WHILE","108":"WHEN","109":"UNTIL","111":"LOOP","113":"FOR","117":"ALL","119":"FORIN","120":"FOROF","121":"BY","122":"SWITCH","124":"ELSE","126":"LEADING_WHEN","128":"IF","129":"UNLESS","130":"POST_IF","131":"POST_UNLESS","132":"UNARY","133":"-","134":"+","135":"--","136":"++","137":"==","138":"!=","139":"MATH","140":"SHIFT","141":"COMPARE","142":"LOGIC","143":"COMPOUND_ASSIGN","144":"RELATION"},productions_:[0,[3,0],[3,1],[3,1],[3,2],[5,1],[5,3],[5,2],[7,1],[7,1],[9,1],[9,1],[9,1],[9,1],[9,1],[8,1],[8,1],[8,1],[8,1],[8,1],[8,1],[8,1],[8,1],[8,1],[8,1],[8,1],[8,1],[8,1],[8,1],[6,3],[6,2],[6,2],[31,1],[33,1],[33,1],[36,1],[36,1],[36,1],[36,1],[19,3],[19,5],[42,1],[42,1],[42,1],[42,3],[42,3],[42,5],[42,5],[42,1],[10,2],[10,1],[28,1],[27,2],[17,5],[17,2],[51,1],[51,1],[54,0],[54,1],[49,0],[49,1],[49,3],[56,1],[56,2],[56,2],[56,3],[60,2],[61,1],[61,2],[61,2],[61,1],[40,1],[40,1],[40,1],[15,1],[15,1],[15,1],[15,1],[15,1],[62,2],[62,2],[62,1],[62,2],[62,1],[62,1],[72,3],[72,2],[72,2],[64,4],[79,0],[79,1],[79,3],[79,4],[79,6],[26,2],[26,4],[26,5],[26,7],[26,4],[26,1],[26,3],[26,6],[84,1],[84,3],[84,5],[83,0],[83,1],[83,3],[83,3],[25,3],[16,3],[16,3],[16,1],[16,2],[85,0],[85,1],[86,2],[86,4],[67,1],[67,1],[93,1],[93,1],[43,2],[66,5],[73,5],[73,4],[73,4],[63,2],[63,4],[91,1],[91,3],[91,4],[91,4],[91,6],[97,1],[97,1],[98,1],[98,3],[21,2],[21,3],[21,4],[21,5],[100,3],[11,2],[65,3],[65,2],[106,2],[106,4],[106,2],[106,4],[22,2],[22,2],[22,2],[22,1],[110,2],[110,2],[23,2],[23,2],[23,2],[112,2],[112,2],[114,2],[114,3],[118,1],[118,1],[118,1],[116,1],[116,3],[115,2],[115,2],[115,4],[115,4],[115,4],[115,6],[115,6],[24,5],[24,7],[24,4],[24,6],[123,1],[123,2],[125,3],[125,4],[127,3],[127,3],[127,5],[127,3],[20,1],[20,3],[20,3],[20,3],[20,3],[18,2],[18,2],[18,2],[18,2],[18,2],[18,2],[18,2],[18,3],[18,3],[18,3],[18,3],[18,3],[18,3],[18,3],[18,3],[18,3],[18,5],[18,3]],performAction:function anonymous(yytext,yyleng,yylineno,yy){var $$=arguments[5],$0=arguments[5].length;switch(arguments[4]){case 1:return this.$=new yy.Expressions;break;case 2:return this.$=new yy.Expressions;break;case 3:return this.$=$$[$0-1+1-1];break;case 4:return this.$=$$[$0-2+1-1];break;case 5:this.$=yy.Expressions.wrap([$$[$0-1+1-1]]);break;case 6:this.$=$$[$0-3+1-1].push($$[$0-3+3-1]);break;case 7:this.$=$$[$0-2+1-1];break;case 8:this.$=$$[$0-1+1-1];break;case 9:this.$=$$[$0-1+1-1];break;case 10:this.$=$$[$0-1+1-1];break;case 11:this.$=$$[$0-1+1-1];break;case 12:this.$=new yy.Literal($$[$0-1+1-1]);break;case 13:this.$=new yy.Literal($$[$0-1+1-1]);break;case 14:this.$=new yy.Literal($$[$0-1+1-1]);break;case 15:this.$=$$[$0-1+1-1];break;case 16:this.$=$$[$0-1+1-1];break;case 17:this.$=$$[$0-1+1-1];break;case 18:this.$=$$[$0-1+1-1];break;case 19:this.$=$$[$0-1+1-1];break;case 20:this.$=$$[$0-1+1-1];break;case 21:this.$=$$[$0-1+1-1];break;case 22:this.$=$$[$0-1+1-1];break;case 23:this.$=$$[$0-1+1-1];break;case 24:this.$=$$[$0-1+1-1];break;case 25:this.$=$$[$0-1+1-1];break;case 26:this.$=$$[$0-1+1-1];break;case 27:this.$=$$[$0-1+1-1];break;case 28:this.$=$$[$0-1+1-1];break;case 29:this.$=$$[$0-3+2-1];break;case 30:this.$=new yy.Expressions;break;case 31:this.$=yy.Expressions.wrap([$$[$0-2+2-1]]);break;case 32:this.$=new yy.Literal($$[$0-1+1-1]);break;case 33:this.$=new yy.Literal($$[$0-1+1-1]);break;case 34:this.$=new yy.Literal($$[$0-1+1-1]);break;case 35:this.$=$$[$0-1+1-1];break;case 36:this.$=new yy.Literal($$[$0-1+1-1]);break;case 37:this.$=new yy.Literal($$[$0-1+1-1]);break;case 38:this.$=new yy.Literal($$[$0-1+1-1]);break;case 39:this.$=new yy.Assign($$[$0-3+1-1],$$[$0-3+3-1]);break;case 40:this.$=new yy.Assign($$[$0-5+1-1],$$[$0-5+4-1]);break;case 41:this.$=new yy.Value($$[$0-1+1-1]);break;case 42:this.$=$$[$0-1+1-1];break;case 43:this.$=$$[$0-1+1-1];break;case 44:this.$=new yy.Assign(new yy.Value($$[$0-3+1-1]),$$[$0-3+3-1],"object");break;case 45:this.$=new yy.Assign(new yy.Value($$[$0-3+1-1]),$$[$0-3+3-1],"object");break;case 46:this.$=new yy.Assign(new yy.Value($$[$0-5+1-1]),$$[$0-5+4-1],"object");break;case 47:this.$=new yy.Assign(new yy.Value($$[$0-5+1-1]),$$[$0-5+4-1],"object");break;case 48:this.$=$$[$0-1+1-1];break;case 49:this.$=new yy.Return($$[$0-2+2-1]);break;case 50:this.$=new yy.Return;break;case 51:this.$=new yy.Comment($$[$0-1+1-1]);break;case 52:this.$=new yy.Existence($$[$0-2+1-1]);break;case 53:this.$=new yy.Code($$[$0-5+2-1],$$[$0-5+5-1],$$[$0-5+4-1]);break;case 54:this.$=new yy.Code([],$$[$0-2+2-1],$$[$0-2+1-1]);break;case 55:this.$="func";break;case 56:this.$="boundfunc";break;case 57:this.$=$$[$0-1+1-1];break;case 58:this.$=$$[$0-1+1-1];break;case 59:this.$=[];break;case 60:this.$=[$$[$0-1+1-1]];break;case 61:this.$=$$[$0-3+1-1].concat($$[$0-3+3-1]);break;case 62:this.$=new yy.Literal($$[$0-1+1-1]);break;case 63:this.$=new yy.Param($$[$0-2+2-1],true);break;case 64:this.$=new yy.Param($$[$0-2+1-1],false,true);break;case 65:this.$=new yy.Param($$[$0-3+2-1],true,true);break;case 66:this.$=new yy.Splat($$[$0-2+1-1]);break;case 67:this.$=new yy.Value($$[$0-1+1-1]);break;case 68:this.$=$$[$0-2+1-1].push($$[$0-2+2-1]);break;case 69:this.$=new yy.Value($$[$0-2+1-1],[$$[$0-2+2-1]]);break;case 70:this.$=$$[$0-1+1-1];break;case 71:this.$=$$[$0-1+1-1];break;case 72:this.$=new yy.Value($$[$0-1+1-1]);break;case 73:this.$=new yy.Value($$[$0-1+1-1]);break;case 74:this.$=$$[$0-1+1-1];break;case 75:this.$=new yy.Value($$[$0-1+1-1]);break;case 76:this.$=new yy.Value($$[$0-1+1-1]);break;case 77:this.$=new yy.Value($$[$0-1+1-1]);break;case 78:this.$=$$[$0-1+1-1];break;case 79:this.$=new yy.Accessor($$[$0-2+2-1]);break;case 80:this.$=new yy.Accessor($$[$0-2+2-1],"prototype");break;case 81:this.$=new yy.Accessor(new yy.Literal("prototype"));break;case 82:this.$=new yy.Accessor($$[$0-2+2-1],"soak");break;case 83:this.$=$$[$0-1+1-1];break;case 84:this.$=new yy.Slice($$[$0-1+1-1]);break;case 85:this.$=new yy.Index($$[$0-3+2-1]);break;case 86:this.$=(function(){$$[$0-2+2-1].soakNode=true;return $$[$0-2+2-1]}());break;case 87:this.$=(function(){$$[$0-2+2-1].proto=true;return $$[$0-2+2-1]}());break;case 88:this.$=new yy.ObjectLiteral($$[$0-4+2-1]);break;case 89:this.$=[];break;case 90:this.$=[$$[$0-1+1-1]];break;case 91:this.$=$$[$0-3+1-1].concat($$[$0-3+3-1]);break;case 92:this.$=$$[$0-4+1-1].concat($$[$0-4+4-1]);break;case 93:this.$=$$[$0-6+1-1].concat($$[$0-6+4-1]);break;case 94:this.$=new yy.Class($$[$0-2+2-1]);break;case 95:this.$=new yy.Class($$[$0-4+2-1],$$[$0-4+4-1]);break;case 96:this.$=new yy.Class($$[$0-5+2-1],null,$$[$0-5+4-1]);break;case 97:this.$=new yy.Class($$[$0-7+2-1],$$[$0-7+4-1],$$[$0-7+6-1]);break;case 98:this.$=new yy.Class("__temp__",null,$$[$0-4+3-1]);break;case 99:this.$=new yy.Class("__temp__",null,new yy.Expressions);break;case 100:this.$=new yy.Class("__temp__",$$[$0-3+3-1],new yy.Expressions);break;case 101:this.$=new yy.Class("__temp__",$$[$0-6+3-1],$$[$0-6+5-1]);break;case 102:this.$=$$[$0-1+1-1];break;case 103:this.$=new yy.Assign(new yy.Value($$[$0-3+1-1]),$$[$0-3+3-1],"this");break;case 104:this.$=new yy.Assign(new yy.Value($$[$0-5+1-1]),$$[$0-5+4-1],"this");break;case 105:this.$=[];break;case 106:this.$=[$$[$0-1+1-1]];break;case 107:this.$=$$[$0-3+1-1].concat($$[$0-3+3-1]);break;case 108:this.$=$$[$0-3+2-1];break;case 109:this.$=new yy.Extends($$[$0-3+1-1],$$[$0-3+3-1]);break;case 110:this.$=new yy.Call($$[$0-3+1-1],$$[$0-3+3-1],$$[$0-3+2-1]);break;case 111:this.$=new yy.Call($$[$0-3+1-1],$$[$0-3+3-1],$$[$0-3+2-1]);break;case 112:this.$=new yy.Call("super",[new yy.Splat(new yy.Literal("arguments"))]);break;case 113:this.$=new yy.Call("super",$$[$0-2+2-1]);break;case 114:this.$=false;break;case 115:this.$=true;break;case 116:this.$=[];break;case 117:this.$=$$[$0-4+2-1];break;case 118:this.$=new yy.Value(new yy.Literal("this"));break;case 119:this.$=new yy.Value(new yy.Literal("this"));break;case 120:this.$="inclusive";break;case 121:this.$="exclusive";break;case 122:this.$=new yy.Value(new yy.Literal("this"),[new yy.Accessor($$[$0-2+2-1])],"this");break;case 123:this.$=new yy.Range($$[$0-5+2-1],$$[$0-5+4-1],$$[$0-5+3-1]);break;case 124:this.$=new yy.Range($$[$0-5+2-1],$$[$0-5+4-1],$$[$0-5+3-1]);break;case 125:this.$=new yy.Range($$[$0-4+2-1],null,$$[$0-4+3-1]);break;case 126:this.$=new yy.Range(null,$$[$0-4+3-1],$$[$0-4+2-1]);break;case 127:this.$=new yy.ArrayLiteral([]);break;case 128:this.$=new yy.ArrayLiteral($$[$0-4+2-1]);break;case 129:this.$=[$$[$0-1+1-1]];break;case 130:this.$=$$[$0-3+1-1].concat($$[$0-3+3-1]);break;case 131:this.$=$$[$0-4+1-1].concat($$[$0-4+4-1]);break;case 132:this.$=$$[$0-4+2-1];break;case 133:this.$=$$[$0-6+1-1].concat($$[$0-6+4-1]);break;case 134:this.$=$$[$0-1+1-1];break;case 135:this.$=$$[$0-1+1-1];break;case 136:this.$=$$[$0-1+1-1];break;case 137:this.$=[].concat($$[$0-3+1-1],$$[$0-3+3-1]);break;case 138:this.$=new yy.Try($$[$0-2+2-1]);break;case 139:this.$=new yy.Try($$[$0-3+2-1],$$[$0-3+3-1][0],$$[$0-3+3-1][1]);break;case 140:this.$=new yy.Try($$[$0-4+2-1],null,null,$$[$0-4+4-1]);break;case 141:this.$=new yy.Try($$[$0-5+2-1],$$[$0-5+3-1][0],$$[$0-5+3-1][1],$$[$0-5+5-1]);break;case 142:this.$=[$$[$0-3+2-1],$$[$0-3+3-1]];break;case 143:this.$=new yy.Throw($$[$0-2+2-1]);break;case 144:this.$=new yy.Parens($$[$0-3+2-1]);break;case 145:this.$=new yy.Parens(new yy.Literal(""));break;case 146:this.$=new yy.While($$[$0-2+2-1]);break;case 147:this.$=new yy.While($$[$0-4+2-1],{guard:$$[$0-4+4-1]});break;case 148:this.$=new yy.While($$[$0-2+2-1],{invert:true});break;case 149:this.$=new yy.While($$[$0-4+2-1],{invert:true,guard:$$[$0-4+4-1]});break;case 150:this.$=$$[$0-2+1-1].addBody($$[$0-2+2-1]);break;case 151:this.$=$$[$0-2+2-1].addBody(yy.Expressions.wrap([$$[$0-2+1-1]]));break;case 152:this.$=$$[$0-2+2-1].addBody(yy.Expressions.wrap([$$[$0-2+1-1]]));break;case 153:this.$=$$[$0-1+1-1];break;case 154:this.$=new yy.While(new yy.Literal("true")).addBody($$[$0-2+2-1]);break;case 155:this.$=new yy.While(new yy.Literal("true")).addBody(yy.Expressions.wrap([$$[$0-2+2-1]]));break;case 156:this.$=new yy.For($$[$0-2+1-1],$$[$0-2+2-1],$$[$0-2+2-1].vars[0],$$[$0-2+2-1].vars[1]);break;case 157:this.$=new yy.For($$[$0-2+1-1],$$[$0-2+2-1],$$[$0-2+2-1].vars[0],$$[$0-2+2-1].vars[1]);break;case 158:this.$=new yy.For($$[$0-2+2-1],$$[$0-2+1-1],$$[$0-2+1-1].vars[0],$$[$0-2+1-1].vars[1]);break;case 159:this.$={source:new yy.Value($$[$0-2+2-1]),vars:[]};break;case 160:this.$=(function(){$$[$0-2+2-1].raw=$$[$0-2+1-1].raw;$$[$0-2+2-1].vars=$$[$0-2+1-1];return $$[$0-2+2-1]}());break;case 161:this.$=$$[$0-2+2-1];break;case 162:this.$=(function(){$$[$0-3+3-1].raw=true;return $$[$0-3+3-1]}());break;case 163:this.$=$$[$0-1+1-1];break;case 164:this.$=new yy.Value($$[$0-1+1-1]);break;case 165:this.$=new yy.Value($$[$0-1+1-1]);break;case 166:this.$=[$$[$0-1+1-1]];break;case 167:this.$=[$$[$0-3+1-1],$$[$0-3+3-1]];break;case 168:this.$={source:$$[$0-2+2-1]};break;case 169:this.$={source:$$[$0-2+2-1],object:true};break;case 170:this.$={source:$$[$0-4+2-1],guard:$$[$0-4+4-1]};break;case 171:this.$={source:$$[$0-4+2-1],guard:$$[$0-4+4-1],object:true};break;case 172:this.$={source:$$[$0-4+2-1],step:$$[$0-4+4-1]};break;case 173:this.$={source:$$[$0-6+2-1],guard:$$[$0-6+4-1],step:$$[$0-6+6-1]};break;case 174:this.$={source:$$[$0-6+2-1],step:$$[$0-6+4-1],guard:$$[$0-6+6-1]};break;case 175:this.$=new yy.Switch($$[$0-5+2-1],$$[$0-5+4-1]);break;case 176:this.$=new yy.Switch($$[$0-7+2-1],$$[$0-7+4-1],$$[$0-7+6-1]);break;case 177:this.$=new yy.Switch(null,$$[$0-4+3-1]);break;case 178:this.$=new yy.Switch(null,$$[$0-6+3-1],$$[$0-6+5-1]);break;case 179:this.$=$$[$0-1+1-1];break;case 180:this.$=$$[$0-2+1-1].concat($$[$0-2+2-1]);break;case 181:this.$=[[$$[$0-3+2-1],$$[$0-3+3-1]]];break;case 182:this.$=[[$$[$0-4+2-1],$$[$0-4+3-1]]];break;case 183:this.$=new yy.If($$[$0-3+2-1],$$[$0-3+3-1]);break;case 184:this.$=new yy.If($$[$0-3+2-1],$$[$0-3+3-1],{invert:true});break;case 185:this.$=$$[$0-5+1-1].addElse(new yy.If($$[$0-5+4-1],$$[$0-5+5-1]));break;case 186:this.$=$$[$0-3+1-1].addElse($$[$0-3+3-1]);break;case 187:this.$=$$[$0-1+1-1];break;case 188:this.$=new yy.If($$[$0-3+3-1],yy.Expressions.wrap([$$[$0-3+1-1]]),{statement:true});break;case 189:this.$=new yy.If($$[$0-3+3-1],yy.Expressions.wrap([$$[$0-3+1-1]]),{statement:true});break;case 190:this.$=new yy.If($$[$0-3+3-1],yy.Expressions.wrap([$$[$0-3+1-1]]),{statement:true,invert:true});break;case 191:this.$=new yy.If($$[$0-3+3-1],yy.Expressions.wrap([$$[$0-3+1-1]]),{statement:true,invert:true});break;case 192:this.$=new yy.Op($$[$0-2+1-1],$$[$0-2+2-1]);break;case 193:this.$=new yy.Op("-",$$[$0-2+2-1]);break;case 194:this.$=new yy.Op("+",$$[$0-2+2-1]);break;case 195:this.$=new yy.Op("--",$$[$0-2+2-1]);break;case 196:this.$=new yy.Op("++",$$[$0-2+2-1]);break;case 197:this.$=new yy.Op("--",$$[$0-2+1-1],null,true);break;case 198:this.$=new yy.Op("++",$$[$0-2+1-1],null,true);break;case 199:this.$=new yy.Op("+",$$[$0-3+1-1],$$[$0-3+3-1]);break;case 200:this.$=new yy.Op("-",$$[$0-3+1-1],$$[$0-3+3-1]);break;case 201:this.$=new yy.Op("==",$$[$0-3+1-1],$$[$0-3+3-1]);break;case 202:this.$=new yy.Op("!=",$$[$0-3+1-1],$$[$0-3+3-1]);break;case 203:this.$=new yy.Op($$[$0-3+2-1],$$[$0-3+1-1],$$[$0-3+3-1]);break;case 204:this.$=new yy.Op($$[$0-3+2-1],$$[$0-3+1-1],$$[$0-3+3-1]);break;case 205:this.$=new yy.Op($$[$0-3+2-1],$$[$0-3+1-1],$$[$0-3+3-1]);break;case 206:this.$=new yy.Op($$[$0-3+2-1],$$[$0-3+1-1],$$[$0-3+3-1]);break;case 207:this.$=new yy.Op($$[$0-3+2-1],$$[$0-3+1-1],$$[$0-3+3-1]);break;case 208:this.$=new yy.Op($$[$0-5+2-1],$$[$0-5+1-1],$$[$0-5+4-1]);break;case 209:this.$=$$[$0-3+2-1].charAt(0)==="!"?($$[$0-3+2-1]==="!in"?new yy.Op("!",new yy.In($$[$0-3+1-1],$$[$0-3+3-1])):new yy.Op("!",new yy.Parens(new yy.Op($$[$0-3+2-1].slice(1),$$[$0-3+1-1],$$[$0-3+3-1])))):($$[$0-3+2-1]==="in"?new yy.In($$[$0-3+1-1],$$[$0-3+3-1]):new yy.Op($$[$0-3+2-1],$$[$0-3+1-1],$$[$0-3+3-1]));break}},table:[{"1":[2,1],"3":1,"4":[1,2],"5":3,"6":4,"7":5,"8":7,"9":8,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"29":[1,6],"31":71,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":72,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":47,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,42],"103":[1,51],"104":[1,58],"106":43,"107":[1,66],"109":[1,67],"110":44,"111":[1,68],"112":45,"113":[1,69],"114":70,"122":[1,46],"127":41,"128":[1,64],"129":[1,65],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"1":[3]},{"1":[2,2],"28":77,"46":[1,49]},{"1":[2,3],"4":[1,78]},{"4":[1,79]},{"1":[2,5],"4":[2,5],"30":[2,5]},{"5":80,"7":5,"8":7,"9":8,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"30":[1,81],"31":71,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":72,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":47,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,42],"103":[1,51],"104":[1,58],"106":43,"107":[1,66],"109":[1,67],"110":44,"111":[1,68],"112":45,"113":[1,69],"114":70,"122":[1,46],"127":41,"128":[1,64],"129":[1,65],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"1":[2,8],"4":[2,8],"30":[2,8],"47":[1,97],"105":[2,8],"106":95,"107":[1,66],"109":[1,67],"112":96,"113":[1,69],"114":70,"130":[1,93],"131":[1,94],"133":[1,85],"134":[1,84],"135":[1,82],"136":[1,83],"137":[1,86],"138":[1,87],"139":[1,88],"140":[1,89],"141":[1,90],"142":[1,91],"144":[1,92]},{"1":[2,9],"4":[2,9],"30":[2,9],"105":[2,9],"106":100,"107":[1,66],"109":[1,67],"112":101,"113":[1,69],"114":70,"130":[1,98],"131":[1,99]},{"1":[2,15],"4":[2,15],"29":[2,15],"30":[2,15],"47":[2,15],"55":[2,15],"59":[2,15],"62":104,"68":[1,106],"69":[1,107],"70":[1,108],"71":[1,109],"72":110,"73":111,"74":[1,112],"75":[2,15],"76":[1,113],"77":[1,114],"80":[2,15],"85":102,"88":[1,105],"89":[2,114],"90":[2,15],"94":[2,15],"96":[2,15],"105":[2,15],"107":[2,15],"108":[2,15],"109":[2,15],"113":[2,15],"121":[2,15],"130":[2,15],"131":[2,15],"133":[2,15],"134":[2,15],"135":[2,15],"136":[2,15],"137":[2,15],"138":[2,15],"139":[2,15],"140":[2,15],"141":[2,15],"142":[2,15],"143":[1,103],"144":[2,15]},{"1":[2,16],"4":[2,16],"29":[2,16],"30":[2,16],"47":[2,16],"55":[2,16],"59":[2,16],"62":116,"68":[1,106],"69":[1,107],"70":[1,108],"71":[1,109],"72":110,"73":111,"74":[1,112],"75":[2,16],"76":[1,113],"77":[1,114],"80":[2,16],"85":115,"88":[1,105],"89":[2,114],"90":[2,16],"94":[2,16],"96":[2,16],"105":[2,16],"107":[2,16],"108":[2,16],"109":[2,16],"113":[2,16],"121":[2,16],"130":[2,16],"131":[2,16],"133":[2,16],"134":[2,16],"135":[2,16],"136":[2,16],"137":[2,16],"138":[2,16],"139":[2,16],"140":[2,16],"141":[2,16],"142":[2,16],"144":[2,16]},{"1":[2,17],"4":[2,17],"29":[2,17],"30":[2,17],"47":[2,17],"55":[2,17],"59":[2,17],"75":[2,17],"80":[2,17],"90":[2,17],"94":[2,17],"96":[2,17],"105":[2,17],"107":[2,17],"108":[2,17],"109":[2,17],"113":[2,17],"121":[2,17],"130":[2,17],"131":[2,17],"133":[2,17],"134":[2,17],"135":[2,17],"136":[2,17],"137":[2,17],"138":[2,17],"139":[2,17],"140":[2,17],"141":[2,17],"142":[2,17],"144":[2,17]},{"1":[2,18],"4":[2,18],"29":[2,18],"30":[2,18],"47":[2,18],"55":[2,18],"59":[2,18],"75":[2,18],"80":[2,18],"90":[2,18],"94":[2,18],"96":[2,18],"105":[2,18],"107":[2,18],"108":[2,18],"109":[2,18],"113":[2,18],"121":[2,18],"130":[2,18],"131":[2,18],"133":[2,18],"134":[2,18],"135":[2,18],"136":[2,18],"137":[2,18],"138":[2,18],"139":[2,18],"140":[2,18],"141":[2,18],"142":[2,18],"144":[2,18]},{"1":[2,19],"4":[2,19],"29":[2,19],"30":[2,19],"47":[2,19],"55":[2,19],"59":[2,19],"75":[2,19],"80":[2,19],"90":[2,19],"94":[2,19],"96":[2,19],"105":[2,19],"107":[2,19],"108":[2,19],"109":[2,19],"113":[2,19],"121":[2,19],"130":[2,19],"131":[2,19],"133":[2,19],"134":[2,19],"135":[2,19],"136":[2,19],"137":[2,19],"138":[2,19],"139":[2,19],"140":[2,19],"141":[2,19],"142":[2,19],"144":[2,19]},{"1":[2,20],"4":[2,20],"29":[2,20],"30":[2,20],"47":[2,20],"55":[2,20],"59":[2,20],"75":[2,20],"80":[2,20],"90":[2,20],"94":[2,20],"96":[2,20],"105":[2,20],"107":[2,20],"108":[2,20],"109":[2,20],"113":[2,20],"121":[2,20],"130":[2,20],"131":[2,20],"133":[2,20],"134":[2,20],"135":[2,20],"136":[2,20],"137":[2,20],"138":[2,20],"139":[2,20],"140":[2,20],"141":[2,20],"142":[2,20],"144":[2,20]},{"1":[2,21],"4":[2,21],"29":[2,21],"30":[2,21],"47":[2,21],"55":[2,21],"59":[2,21],"75":[2,21],"80":[2,21],"90":[2,21],"94":[2,21],"96":[2,21],"105":[2,21],"107":[2,21],"108":[2,21],"109":[2,21],"113":[2,21],"121":[2,21],"130":[2,21],"131":[2,21],"133":[2,21],"134":[2,21],"135":[2,21],"136":[2,21],"137":[2,21],"138":[2,21],"139":[2,21],"140":[2,21],"141":[2,21],"142":[2,21],"144":[2,21]},{"1":[2,22],"4":[2,22],"29":[2,22],"30":[2,22],"47":[2,22],"55":[2,22],"59":[2,22],"75":[2,22],"80":[2,22],"90":[2,22],"94":[2,22],"96":[2,22],"105":[2,22],"107":[2,22],"108":[2,22],"109":[2,22],"113":[2,22],"121":[2,22],"130":[2,22],"131":[2,22],"133":[2,22],"134":[2,22],"135":[2,22],"136":[2,22],"137":[2,22],"138":[2,22],"139":[2,22],"140":[2,22],"141":[2,22],"142":[2,22],"144":[2,22]},{"1":[2,23],"4":[2,23],"29":[2,23],"30":[2,23],"47":[2,23],"55":[2,23],"59":[2,23],"75":[2,23],"80":[2,23],"90":[2,23],"94":[2,23],"96":[2,23],"105":[2,23],"107":[2,23],"108":[2,23],"109":[2,23],"113":[2,23],"121":[2,23],"130":[2,23],"131":[2,23],"133":[2,23],"134":[2,23],"135":[2,23],"136":[2,23],"137":[2,23],"138":[2,23],"139":[2,23],"140":[2,23],"141":[2,23],"142":[2,23],"144":[2,23]},{"1":[2,24],"4":[2,24],"29":[2,24],"30":[2,24],"47":[2,24],"55":[2,24],"59":[2,24],"75":[2,24],"80":[2,24],"90":[2,24],"94":[2,24],"96":[2,24],"105":[2,24],"107":[2,24],"108":[2,24],"109":[2,24],"113":[2,24],"121":[2,24],"130":[2,24],"131":[2,24],"133":[2,24],"134":[2,24],"135":[2,24],"136":[2,24],"137":[2,24],"138":[2,24],"139":[2,24],"140":[2,24],"141":[2,24],"142":[2,24],"144":[2,24]},{"1":[2,25],"4":[2,25],"29":[2,25],"30":[2,25],"47":[2,25],"55":[2,25],"59":[2,25],"75":[2,25],"80":[2,25],"90":[2,25],"94":[2,25],"96":[2,25],"105":[2,25],"107":[2,25],"108":[2,25],"109":[2,25],"113":[2,25],"121":[2,25],"130":[2,25],"131":[2,25],"133":[2,25],"134":[2,25],"135":[2,25],"136":[2,25],"137":[2,25],"138":[2,25],"139":[2,25],"140":[2,25],"141":[2,25],"142":[2,25],"144":[2,25]},{"1":[2,26],"4":[2,26],"29":[2,26],"30":[2,26],"47":[2,26],"55":[2,26],"59":[2,26],"75":[2,26],"80":[2,26],"90":[2,26],"94":[2,26],"96":[2,26],"105":[2,26],"107":[2,26],"108":[2,26],"109":[2,26],"113":[2,26],"121":[2,26],"130":[2,26],"131":[2,26],"133":[2,26],"134":[2,26],"135":[2,26],"136":[2,26],"137":[2,26],"138":[2,26],"139":[2,26],"140":[2,26],"141":[2,26],"142":[2,26],"144":[2,26]},{"1":[2,27],"4":[2,27],"29":[2,27],"30":[2,27],"47":[2,27],"55":[2,27],"59":[2,27],"75":[2,27],"80":[2,27],"90":[2,27],"94":[2,27],"96":[2,27],"105":[2,27],"107":[2,27],"108":[2,27],"109":[2,27],"113":[2,27],"121":[2,27],"130":[2,27],"131":[2,27],"133":[2,27],"134":[2,27],"135":[2,27],"136":[2,27],"137":[2,27],"138":[2,27],"139":[2,27],"140":[2,27],"141":[2,27],"142":[2,27],"144":[2,27]},{"1":[2,28],"4":[2,28],"29":[2,28],"30":[2,28],"47":[2,28],"55":[2,28],"59":[2,28],"75":[2,28],"80":[2,28],"90":[2,28],"94":[2,28],"96":[2,28],"105":[2,28],"107":[2,28],"108":[2,28],"109":[2,28],"113":[2,28],"121":[2,28],"130":[2,28],"131":[2,28],"133":[2,28],"134":[2,28],"135":[2,28],"136":[2,28],"137":[2,28],"138":[2,28],"139":[2,28],"140":[2,28],"141":[2,28],"142":[2,28],"144":[2,28]},{"1":[2,10],"4":[2,10],"30":[2,10],"105":[2,10],"107":[2,10],"109":[2,10],"113":[2,10],"130":[2,10],"131":[2,10]},{"1":[2,11],"4":[2,11],"30":[2,11],"105":[2,11],"107":[2,11],"109":[2,11],"113":[2,11],"130":[2,11],"131":[2,11]},{"1":[2,12],"4":[2,12],"30":[2,12],"105":[2,12],"107":[2,12],"109":[2,12],"113":[2,12],"130":[2,12],"131":[2,12]},{"1":[2,13],"4":[2,13],"30":[2,13],"105":[2,13],"107":[2,13],"109":[2,13],"113":[2,13],"130":[2,13],"131":[2,13]},{"1":[2,14],"4":[2,14],"30":[2,14],"105":[2,14],"107":[2,14],"109":[2,14],"113":[2,14],"130":[2,14],"131":[2,14]},{"1":[2,74],"4":[2,74],"29":[2,74],"30":[2,74],"41":[1,117],"47":[2,74],"55":[2,74],"59":[2,74],"68":[2,74],"69":[2,74],"70":[2,74],"71":[2,74],"74":[2,74],"75":[2,74],"76":[2,74],"77":[2,74],"80":[2,74],"88":[2,74],"89":[2,74],"90":[2,74],"94":[2,74],"96":[2,74],"105":[2,74],"107":[2,74],"108":[2,74],"109":[2,74],"113":[2,74],"121":[2,74],"130":[2,74],"131":[2,74],"133":[2,74],"134":[2,74],"135":[2,74],"136":[2,74],"137":[2,74],"138":[2,74],"139":[2,74],"140":[2,74],"141":[2,74],"142":[2,74],"143":[2,74],"144":[2,74]},{"1":[2,75],"4":[2,75],"29":[2,75],"30":[2,75],"47":[2,75],"55":[2,75],"59":[2,75],"68":[2,75],"69":[2,75],"70":[2,75],"71":[2,75],"74":[2,75],"75":[2,75],"76":[2,75],"77":[2,75],"80":[2,75],"88":[2,75],"89":[2,75],"90":[2,75],"94":[2,75],"96":[2,75],"105":[2,75],"107":[2,75],"108":[2,75],"109":[2,75],"113":[2,75],"121":[2,75],"130":[2,75],"131":[2,75],"133":[2,75],"134":[2,75],"135":[2,75],"136":[2,75],"137":[2,75],"138":[2,75],"139":[2,75],"140":[2,75],"141":[2,75],"142":[2,75],"143":[2,75],"144":[2,75]},{"1":[2,76],"4":[2,76],"29":[2,76],"30":[2,76],"47":[2,76],"55":[2,76],"59":[2,76],"68":[2,76],"69":[2,76],"70":[2,76],"71":[2,76],"74":[2,76],"75":[2,76],"76":[2,76],"77":[2,76],"80":[2,76],"88":[2,76],"89":[2,76],"90":[2,76],"94":[2,76],"96":[2,76],"105":[2,76],"107":[2,76],"108":[2,76],"109":[2,76],"113":[2,76],"121":[2,76],"130":[2,76],"131":[2,76],"133":[2,76],"134":[2,76],"135":[2,76],"136":[2,76],"137":[2,76],"138":[2,76],"139":[2,76],"140":[2,76],"141":[2,76],"142":[2,76],"143":[2,76],"144":[2,76]},{"1":[2,77],"4":[2,77],"29":[2,77],"30":[2,77],"47":[2,77],"55":[2,77],"59":[2,77],"68":[2,77],"69":[2,77],"70":[2,77],"71":[2,77],"74":[2,77],"75":[2,77],"76":[2,77],"77":[2,77],"80":[2,77],"88":[2,77],"89":[2,77],"90":[2,77],"94":[2,77],"96":[2,77],"105":[2,77],"107":[2,77],"108":[2,77],"109":[2,77],"113":[2,77],"121":[2,77],"130":[2,77],"131":[2,77],"133":[2,77],"134":[2,77],"135":[2,77],"136":[2,77],"137":[2,77],"138":[2,77],"139":[2,77],"140":[2,77],"141":[2,77],"142":[2,77],"143":[2,77],"144":[2,77]},{"1":[2,78],"4":[2,78],"29":[2,78],"30":[2,78],"47":[2,78],"55":[2,78],"59":[2,78],"68":[2,78],"69":[2,78],"70":[2,78],"71":[2,78],"74":[2,78],"75":[2,78],"76":[2,78],"77":[2,78],"80":[2,78],"88":[2,78],"89":[2,78],"90":[2,78],"94":[2,78],"96":[2,78],"105":[2,78],"107":[2,78],"108":[2,78],"109":[2,78],"113":[2,78],"121":[2,78],"130":[2,78],"131":[2,78],"133":[2,78],"134":[2,78],"135":[2,78],"136":[2,78],"137":[2,78],"138":[2,78],"139":[2,78],"140":[2,78],"141":[2,78],"142":[2,78],"143":[2,78],"144":[2,78]},{"1":[2,112],"4":[2,112],"29":[2,112],"30":[2,112],"47":[2,112],"55":[2,112],"59":[2,112],"68":[2,112],"69":[2,112],"70":[2,112],"71":[2,112],"74":[2,112],"75":[2,112],"76":[2,112],"77":[2,112],"80":[2,112],"86":118,"88":[2,112],"89":[1,119],"90":[2,112],"94":[2,112],"96":[2,112],"105":[2,112],"107":[2,112],"108":[2,112],"109":[2,112],"113":[2,112],"121":[2,112],"130":[2,112],"131":[2,112],"133":[2,112],"134":[2,112],"135":[2,112],"136":[2,112],"137":[2,112],"138":[2,112],"139":[2,112],"140":[2,112],"141":[2,112],"142":[2,112],"144":[2,112]},{"49":120,"50":[2,59],"55":[2,59],"56":121,"57":[1,122],"58":[1,123]},{"4":[1,125],"6":124,"29":[1,6]},{"8":126,"9":127,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"31":71,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":72,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":47,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,42],"103":[1,51],"104":[1,58],"106":43,"107":[1,66],"109":[1,67],"110":44,"111":[1,68],"112":45,"113":[1,69],"114":70,"122":[1,46],"127":41,"128":[1,64],"129":[1,65],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"8":128,"9":127,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"31":71,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":72,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":47,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,42],"103":[1,51],"104":[1,58],"106":43,"107":[1,66],"109":[1,67],"110":44,"111":[1,68],"112":45,"113":[1,69],"114":70,"122":[1,46],"127":41,"128":[1,64],"129":[1,65],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"8":129,"9":127,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"31":71,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":72,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":47,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,42],"103":[1,51],"104":[1,58],"106":43,"107":[1,66],"109":[1,67],"110":44,"111":[1,68],"112":45,"113":[1,69],"114":70,"122":[1,46],"127":41,"128":[1,64],"129":[1,65],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"8":130,"9":127,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"31":71,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":72,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":47,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,42],"103":[1,51],"104":[1,58],"106":43,"107":[1,66],"109":[1,67],"110":44,"111":[1,68],"112":45,"113":[1,69],"114":70,"122":[1,46],"127":41,"128":[1,64],"129":[1,65],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"8":131,"9":127,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"31":71,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":72,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":47,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,42],"103":[1,51],"104":[1,58],"106":43,"107":[1,66],"109":[1,67],"110":44,"111":[1,68],"112":45,"113":[1,69],"114":70,"122":[1,46],"127":41,"128":[1,64],"129":[1,65],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"1":[2,187],"4":[2,187],"29":[2,187],"30":[2,187],"47":[2,187],"55":[2,187],"59":[2,187],"75":[2,187],"80":[2,187],"90":[2,187],"94":[2,187],"96":[2,187],"105":[2,187],"107":[2,187],"108":[2,187],"109":[2,187],"113":[2,187],"121":[2,187],"124":[1,132],"130":[2,187],"131":[2,187],"133":[2,187],"134":[2,187],"135":[2,187],"136":[2,187],"137":[2,187],"138":[2,187],"139":[2,187],"140":[2,187],"141":[2,187],"142":[2,187],"144":[2,187]},{"4":[1,125],"6":133,"29":[1,6]},{"4":[1,125],"6":134,"29":[1,6]},{"1":[2,153],"4":[2,153],"29":[2,153],"30":[2,153],"47":[2,153],"55":[2,153],"59":[2,153],"75":[2,153],"80":[2,153],"90":[2,153],"94":[2,153],"96":[2,153],"105":[2,153],"107":[2,153],"108":[2,153],"109":[2,153],"113":[2,153],"121":[2,153],"130":[2,153],"131":[2,153],"133":[2,153],"134":[2,153],"135":[2,153],"136":[2,153],"137":[2,153],"138":[2,153],"139":[2,153],"140":[2,153],"141":[2,153],"142":[2,153],"144":[2,153]},{"4":[1,125],"6":135,"29":[1,6]},{"8":136,"9":127,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"29":[1,137],"31":71,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":72,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":47,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,42],"103":[1,51],"104":[1,58],"106":43,"107":[1,66],"109":[1,67],"110":44,"111":[1,68],"112":45,"113":[1,69],"114":70,"122":[1,46],"127":41,"128":[1,64],"129":[1,65],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"1":[2,71],"4":[2,71],"29":[2,71],"30":[2,71],"41":[2,71],"47":[2,71],"55":[2,71],"59":[2,71],"68":[2,71],"69":[2,71],"70":[2,71],"71":[2,71],"74":[2,71],"75":[2,71],"76":[2,71],"77":[2,71],"80":[2,71],"82":[1,138],"88":[2,71],"89":[2,71],"90":[2,71],"94":[2,71],"96":[2,71],"105":[2,71],"107":[2,71],"108":[2,71],"109":[2,71],"113":[2,71],"121":[2,71],"130":[2,71],"131":[2,71],"133":[2,71],"134":[2,71],"135":[2,71],"136":[2,71],"137":[2,71],"138":[2,71],"139":[2,71],"140":[2,71],"141":[2,71],"142":[2,71],"143":[2,71],"144":[2,71]},{"1":[2,99],"4":[2,99],"15":142,"16":143,"29":[1,140],"30":[2,99],"31":71,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":144,"43":72,"47":[2,99],"55":[2,99],"58":[1,61],"59":[2,99],"61":139,"63":52,"64":53,"65":30,"66":31,"67":32,"75":[2,99],"78":[1,73],"80":[2,99],"82":[1,141],"87":[1,33],"90":[2,99],"92":[1,60],"94":[2,99],"95":[1,59],"96":[2,99],"104":[1,58],"105":[2,99],"107":[2,99],"108":[2,99],"109":[2,99],"113":[2,99],"121":[2,99],"130":[2,99],"131":[2,99],"133":[2,99],"134":[2,99],"135":[2,99],"136":[2,99],"137":[2,99],"138":[2,99],"139":[2,99],"140":[2,99],"141":[2,99],"142":[2,99],"144":[2,99]},{"1":[2,51],"4":[2,51],"29":[2,51],"30":[2,51],"47":[2,51],"55":[2,51],"59":[2,51],"75":[2,51],"80":[2,51],"90":[2,51],"94":[2,51],"96":[2,51],"101":[2,51],"102":[2,51],"105":[2,51],"107":[2,51],"108":[2,51],"109":[2,51],"113":[2,51],"121":[2,51],"124":[2,51],"126":[2,51],"130":[2,51],"131":[2,51],"133":[2,51],"134":[2,51],"135":[2,51],"136":[2,51],"137":[2,51],"138":[2,51],"139":[2,51],"140":[2,51],"141":[2,51],"142":[2,51],"144":[2,51]},{"1":[2,50],"4":[2,50],"8":145,"9":127,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"30":[2,50],"31":71,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":72,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":47,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,42],"103":[1,51],"104":[1,58],"105":[2,50],"106":43,"107":[1,66],"109":[1,67],"110":44,"111":[1,68],"112":45,"113":[1,69],"114":70,"122":[1,46],"127":41,"128":[1,64],"129":[1,65],"130":[2,50],"131":[2,50],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"8":146,"9":127,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"31":71,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":72,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":47,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,42],"103":[1,51],"104":[1,58],"106":43,"107":[1,66],"109":[1,67],"110":44,"111":[1,68],"112":45,"113":[1,69],"114":70,"122":[1,46],"127":41,"128":[1,64],"129":[1,65],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"1":[2,72],"4":[2,72],"29":[2,72],"30":[2,72],"41":[2,72],"47":[2,72],"55":[2,72],"59":[2,72],"68":[2,72],"69":[2,72],"70":[2,72],"71":[2,72],"74":[2,72],"75":[2,72],"76":[2,72],"77":[2,72],"80":[2,72],"88":[2,72],"89":[2,72],"90":[2,72],"94":[2,72],"96":[2,72],"105":[2,72],"107":[2,72],"108":[2,72],"109":[2,72],"113":[2,72],"121":[2,72],"130":[2,72],"131":[2,72],"133":[2,72],"134":[2,72],"135":[2,72],"136":[2,72],"137":[2,72],"138":[2,72],"139":[2,72],"140":[2,72],"141":[2,72],"142":[2,72],"143":[2,72],"144":[2,72]},{"1":[2,73],"4":[2,73],"29":[2,73],"30":[2,73],"41":[2,73],"47":[2,73],"55":[2,73],"59":[2,73],"68":[2,73],"69":[2,73],"70":[2,73],"71":[2,73],"74":[2,73],"75":[2,73],"76":[2,73],"77":[2,73],"80":[2,73],"88":[2,73],"89":[2,73],"90":[2,73],"94":[2,73],"96":[2,73],"105":[2,73],"107":[2,73],"108":[2,73],"109":[2,73],"113":[2,73],"121":[2,73],"130":[2,73],"131":[2,73],"133":[2,73],"134":[2,73],"135":[2,73],"136":[2,73],"137":[2,73],"138":[2,73],"139":[2,73],"140":[2,73],"141":[2,73],"142":[2,73],"143":[2,73],"144":[2,73]},{"1":[2,35],"4":[2,35],"29":[2,35],"30":[2,35],"47":[2,35],"55":[2,35],"59":[2,35],"68":[2,35],"69":[2,35],"70":[2,35],"71":[2,35],"74":[2,35],"75":[2,35],"76":[2,35],"77":[2,35],"80":[2,35],"88":[2,35],"89":[2,35],"90":[2,35],"94":[2,35],"96":[2,35],"105":[2,35],"107":[2,35],"108":[2,35],"109":[2,35],"113":[2,35],"121":[2,35],"130":[2,35],"131":[2,35],"133":[2,35],"134":[2,35],"135":[2,35],"136":[2,35],"137":[2,35],"138":[2,35],"139":[2,35],"140":[2,35],"141":[2,35],"142":[2,35],"143":[2,35],"144":[2,35]},{"1":[2,36],"4":[2,36],"29":[2,36],"30":[2,36],"47":[2,36],"55":[2,36],"59":[2,36],"68":[2,36],"69":[2,36],"70":[2,36],"71":[2,36],"74":[2,36],"75":[2,36],"76":[2,36],"77":[2,36],"80":[2,36],"88":[2,36],"89":[2,36],"90":[2,36],"94":[2,36],"96":[2,36],"105":[2,36],"107":[2,36],"108":[2,36],"109":[2,36],"113":[2,36],"121":[2,36],"130":[2,36],"131":[2,36],"133":[2,36],"134":[2,36],"135":[2,36],"136":[2,36],"137":[2,36],"138":[2,36],"139":[2,36],"140":[2,36],"141":[2,36],"142":[2,36],"143":[2,36],"144":[2,36]},{"1":[2,37],"4":[2,37],"29":[2,37],"30":[2,37],"47":[2,37],"55":[2,37],"59":[2,37],"68":[2,37],"69":[2,37],"70":[2,37],"71":[2,37],"74":[2,37],"75":[2,37],"76":[2,37],"77":[2,37],"80":[2,37],"88":[2,37],"89":[2,37],"90":[2,37],"94":[2,37],"96":[2,37],"105":[2,37],"107":[2,37],"108":[2,37],"109":[2,37],"113":[2,37],"121":[2,37],"130":[2,37],"131":[2,37],"133":[2,37],"134":[2,37],"135":[2,37],"136":[2,37],"137":[2,37],"138":[2,37],"139":[2,37],"140":[2,37],"141":[2,37],"142":[2,37],"143":[2,37],"144":[2,37]},{"1":[2,38],"4":[2,38],"29":[2,38],"30":[2,38],"47":[2,38],"55":[2,38],"59":[2,38],"68":[2,38],"69":[2,38],"70":[2,38],"71":[2,38],"74":[2,38],"75":[2,38],"76":[2,38],"77":[2,38],"80":[2,38],"88":[2,38],"89":[2,38],"90":[2,38],"94":[2,38],"96":[2,38],"105":[2,38],"107":[2,38],"108":[2,38],"109":[2,38],"113":[2,38],"121":[2,38],"130":[2,38],"131":[2,38],"133":[2,38],"134":[2,38],"135":[2,38],"136":[2,38],"137":[2,38],"138":[2,38],"139":[2,38],"140":[2,38],"141":[2,38],"142":[2,38],"143":[2,38],"144":[2,38]},{"7":147,"8":7,"9":8,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"31":71,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":72,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":47,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,42],"103":[1,51],"104":[1,58],"105":[1,148],"106":43,"107":[1,66],"109":[1,67],"110":44,"111":[1,68],"112":45,"113":[1,69],"114":70,"122":[1,46],"127":41,"128":[1,64],"129":[1,65],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"8":149,"9":127,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"29":[1,153],"31":71,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":72,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"60":154,"61":47,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"91":151,"92":[1,60],"95":[1,59],"96":[1,150],"97":152,"99":[1,42],"103":[1,51],"104":[1,58],"106":43,"107":[1,66],"109":[1,67],"110":44,"111":[1,68],"112":45,"113":[1,69],"114":70,"122":[1,46],"127":41,"128":[1,64],"129":[1,65],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"1":[2,118],"4":[2,118],"29":[2,118],"30":[2,118],"47":[2,118],"55":[2,118],"59":[2,118],"68":[2,118],"69":[2,118],"70":[2,118],"71":[2,118],"74":[2,118],"75":[2,118],"76":[2,118],"77":[2,118],"80":[2,118],"88":[2,118],"89":[2,118],"90":[2,118],"94":[2,118],"96":[2,118],"105":[2,118],"107":[2,118],"108":[2,118],"109":[2,118],"113":[2,118],"121":[2,118],"130":[2,118],"131":[2,118],"133":[2,118],"134":[2,118],"135":[2,118],"136":[2,118],"137":[2,118],"138":[2,118],"139":[2,118],"140":[2,118],"141":[2,118],"142":[2,118],"143":[2,118],"144":[2,118]},{"1":[2,119],"4":[2,119],"29":[2,119],"30":[2,119],"31":155,"32":[1,76],"47":[2,119],"55":[2,119],"59":[2,119],"68":[2,119],"69":[2,119],"70":[2,119],"71":[2,119],"74":[2,119],"75":[2,119],"76":[2,119],"77":[2,119],"80":[2,119],"88":[2,119],"89":[2,119],"90":[2,119],"94":[2,119],"96":[2,119],"105":[2,119],"107":[2,119],"108":[2,119],"109":[2,119],"113":[2,119],"121":[2,119],"130":[2,119],"131":[2,119],"133":[2,119],"134":[2,119],"135":[2,119],"136":[2,119],"137":[2,119],"138":[2,119],"139":[2,119],"140":[2,119],"141":[2,119],"142":[2,119],"143":[2,119],"144":[2,119]},{"4":[2,55],"29":[2,55]},{"4":[2,56],"29":[2,56]},{"8":156,"9":127,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"31":71,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":72,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":47,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,42],"103":[1,51],"104":[1,58],"106":43,"107":[1,66],"109":[1,67],"110":44,"111":[1,68],"112":45,"113":[1,69],"114":70,"122":[1,46],"127":41,"128":[1,64],"129":[1,65],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"8":157,"9":127,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"31":71,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":72,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":47,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,42],"103":[1,51],"104":[1,58],"106":43,"107":[1,66],"109":[1,67],"110":44,"111":[1,68],"112":45,"113":[1,69],"114":70,"122":[1,46],"127":41,"128":[1,64],"129":[1,65],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"8":158,"9":127,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"31":71,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":72,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":47,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,42],"103":[1,51],"104":[1,58],"106":43,"107":[1,66],"109":[1,67],"110":44,"111":[1,68],"112":45,"113":[1,69],"114":70,"122":[1,46],"127":41,"128":[1,64],"129":[1,65],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"8":159,"9":127,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"31":71,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":72,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":47,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,42],"103":[1,51],"104":[1,58],"106":43,"107":[1,66],"109":[1,67],"110":44,"111":[1,68],"112":45,"113":[1,69],"114":70,"122":[1,46],"127":41,"128":[1,64],"129":[1,65],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"4":[1,125],"6":160,"8":161,"9":127,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"29":[1,6],"31":71,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":72,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":47,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,42],"103":[1,51],"104":[1,58],"106":43,"107":[1,66],"109":[1,67],"110":44,"111":[1,68],"112":45,"113":[1,69],"114":70,"122":[1,46],"127":41,"128":[1,64],"129":[1,65],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"31":166,"32":[1,76],"63":167,"64":168,"66":162,"78":[1,73],"95":[1,59],"116":163,"117":[1,164],"118":165},{"115":169,"119":[1,170],"120":[1,171]},{"1":[2,67],"4":[2,67],"29":[2,67],"30":[2,67],"41":[2,67],"47":[2,67],"55":[2,67],"59":[2,67],"68":[2,67],"69":[2,67],"70":[2,67],"71":[2,67],"74":[2,67],"75":[2,67],"76":[2,67],"77":[2,67],"80":[2,67],"82":[2,67],"88":[2,67],"89":[2,67],"90":[2,67],"94":[2,67],"96":[2,67],"105":[2,67],"107":[2,67],"108":[2,67],"109":[2,67],"113":[2,67],"121":[2,67],"130":[2,67],"131":[2,67],"133":[2,67],"134":[2,67],"135":[2,67],"136":[2,67],"137":[2,67],"138":[2,67],"139":[2,67],"140":[2,67],"141":[2,67],"142":[2,67],"143":[2,67],"144":[2,67]},{"1":[2,70],"4":[2,70],"29":[2,70],"30":[2,70],"41":[2,70],"47":[2,70],"55":[2,70],"59":[2,70],"68":[2,70],"69":[2,70],"70":[2,70],"71":[2,70],"74":[2,70],"75":[2,70],"76":[2,70],"77":[2,70],"80":[2,70],"82":[2,70],"88":[2,70],"89":[2,70],"90":[2,70],"94":[2,70],"96":[2,70],"105":[2,70],"107":[2,70],"108":[2,70],"109":[2,70],"113":[2,70],"121":[2,70],"130":[2,70],"131":[2,70],"133":[2,70],"134":[2,70],"135":[2,70],"136":[2,70],"137":[2,70],"138":[2,70],"139":[2,70],"140":[2,70],"141":[2,70],"142":[2,70],"143":[2,70],"144":[2,70]},{"4":[2,89],"28":177,"29":[2,89],"31":174,"32":[1,76],"33":175,"34":[1,74],"35":[1,75],"42":173,"43":176,"46":[1,49],"55":[2,89],"58":[1,178],"79":172,"80":[2,89]},{"1":[2,33],"4":[2,33],"29":[2,33],"30":[2,33],"44":[2,33],"47":[2,33],"55":[2,33],"59":[2,33],"68":[2,33],"69":[2,33],"70":[2,33],"71":[2,33],"74":[2,33],"75":[2,33],"76":[2,33],"77":[2,33],"80":[2,33],"88":[2,33],"89":[2,33],"90":[2,33],"94":[2,33],"96":[2,33],"105":[2,33],"107":[2,33],"108":[2,33],"109":[2,33],"113":[2,33],"121":[2,33],"130":[2,33],"131":[2,33],"133":[2,33],"134":[2,33],"135":[2,33],"136":[2,33],"137":[2,33],"138":[2,33],"139":[2,33],"140":[2,33],"141":[2,33],"142":[2,33],"143":[2,33],"144":[2,33]},{"1":[2,34],"4":[2,34],"29":[2,34],"30":[2,34],"44":[2,34],"47":[2,34],"55":[2,34],"59":[2,34],"68":[2,34],"69":[2,34],"70":[2,34],"71":[2,34],"74":[2,34],"75":[2,34],"76":[2,34],"77":[2,34],"80":[2,34],"88":[2,34],"89":[2,34],"90":[2,34],"94":[2,34],"96":[2,34],"105":[2,34],"107":[2,34],"108":[2,34],"109":[2,34],"113":[2,34],"121":[2,34],"130":[2,34],"131":[2,34],"133":[2,34],"134":[2,34],"135":[2,34],"136":[2,34],"137":[2,34],"138":[2,34],"139":[2,34],"140":[2,34],"141":[2,34],"142":[2,34],"143":[2,34],"144":[2,34]},{"1":[2,32],"4":[2,32],"29":[2,32],"30":[2,32],"41":[2,32],"44":[2,32],"47":[2,32],"55":[2,32],"59":[2,32],"68":[2,32],"69":[2,32],"70":[2,32],"71":[2,32],"74":[2,32],"75":[2,32],"76":[2,32],"77":[2,32],"80":[2,32],"82":[2,32],"88":[2,32],"89":[2,32],"90":[2,32],"94":[2,32],"96":[2,32],"105":[2,32],"107":[2,32],"108":[2,32],"109":[2,32],"113":[2,32],"119":[2,32],"120":[2,32],"121":[2,32],"130":[2,32],"131":[2,32],"133":[2,32],"134":[2,32],"135":[2,32],"136":[2,32],"137":[2,32],"138":[2,32],"139":[2,32],"140":[2,32],"141":[2,32],"142":[2,32],"143":[2,32],"144":[2,32]},{"1":[2,31],"4":[2,31],"29":[2,31],"30":[2,31],"47":[2,31],"55":[2,31],"59":[2,31],"75":[2,31],"80":[2,31],"90":[2,31],"94":[2,31],"96":[2,31],"101":[2,31],"102":[2,31],"105":[2,31],"107":[2,31],"108":[2,31],"109":[2,31],"113":[2,31],"121":[2,31],"124":[2,31],"126":[2,31],"130":[2,31],"131":[2,31],"133":[2,31],"134":[2,31],"135":[2,31],"136":[2,31],"137":[2,31],"138":[2,31],"139":[2,31],"140":[2,31],"141":[2,31],"142":[2,31],"144":[2,31]},{"1":[2,7],"4":[2,7],"7":179,"8":7,"9":8,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"30":[2,7],"31":71,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":72,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":47,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,42],"103":[1,51],"104":[1,58],"106":43,"107":[1,66],"109":[1,67],"110":44,"111":[1,68],"112":45,"113":[1,69],"114":70,"122":[1,46],"127":41,"128":[1,64],"129":[1,65],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"1":[2,4]},{"4":[1,78],"30":[1,180]},{"1":[2,30],"4":[2,30],"29":[2,30],"30":[2,30],"47":[2,30],"55":[2,30],"59":[2,30],"75":[2,30],"80":[2,30],"90":[2,30],"94":[2,30],"96":[2,30],"101":[2,30],"102":[2,30],"105":[2,30],"107":[2,30],"108":[2,30],"109":[2,30],"113":[2,30],"121":[2,30],"124":[2,30],"126":[2,30],"130":[2,30],"131":[2,30],"133":[2,30],"134":[2,30],"135":[2,30],"136":[2,30],"137":[2,30],"138":[2,30],"139":[2,30],"140":[2,30],"141":[2,30],"142":[2,30],"144":[2,30]},{"1":[2,197],"4":[2,197],"29":[2,197],"30":[2,197],"47":[2,197],"55":[2,197],"59":[2,197],"75":[2,197],"80":[2,197],"90":[2,197],"94":[2,197],"96":[2,197],"105":[2,197],"107":[2,197],"108":[2,197],"109":[2,197],"113":[2,197],"121":[2,197],"130":[2,197],"131":[2,197],"133":[2,197],"134":[2,197],"135":[2,197],"136":[2,197],"137":[2,197],"138":[2,197],"139":[2,197],"140":[2,197],"141":[2,197],"142":[2,197],"144":[2,197]},{"1":[2,198],"4":[2,198],"29":[2,198],"30":[2,198],"47":[2,198],"55":[2,198],"59":[2,198],"75":[2,198],"80":[2,198],"90":[2,198],"94":[2,198],"96":[2,198],"105":[2,198],"107":[2,198],"108":[2,198],"109":[2,198],"113":[2,198],"121":[2,198],"130":[2,198],"131":[2,198],"133":[2,198],"134":[2,198],"135":[2,198],"136":[2,198],"137":[2,198],"138":[2,198],"139":[2,198],"140":[2,198],"141":[2,198],"142":[2,198],"144":[2,198]},{"8":181,"9":127,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"31":71,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":72,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":47,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,42],"103":[1,51],"104":[1,58],"106":43,"107":[1,66],"109":[1,67],"110":44,"111":[1,68],"112":45,"113":[1,69],"114":70,"122":[1,46],"127":41,"128":[1,64],"129":[1,65],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"8":182,"9":127,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"31":71,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":72,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":47,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,42],"103":[1,51],"104":[1,58],"106":43,"107":[1,66],"109":[1,67],"110":44,"111":[1,68],"112":45,"113":[1,69],"114":70,"122":[1,46],"127":41,"128":[1,64],"129":[1,65],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"8":183,"9":127,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"31":71,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":72,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":47,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,42],"103":[1,51],"104":[1,58],"106":43,"107":[1,66],"109":[1,67],"110":44,"111":[1,68],"112":45,"113":[1,69],"114":70,"122":[1,46],"127":41,"128":[1,64],"129":[1,65],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"8":184,"9":127,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"31":71,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":72,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":47,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,42],"103":[1,51],"104":[1,58],"106":43,"107":[1,66],"109":[1,67],"110":44,"111":[1,68],"112":45,"113":[1,69],"114":70,"122":[1,46],"127":41,"128":[1,64],"129":[1,65],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"8":185,"9":127,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"31":71,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":72,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":47,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,42],"103":[1,51],"104":[1,58],"106":43,"107":[1,66],"109":[1,67],"110":44,"111":[1,68],"112":45,"113":[1,69],"114":70,"122":[1,46],"127":41,"128":[1,64],"129":[1,65],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"8":186,"9":127,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"31":71,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":72,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":47,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,42],"103":[1,51],"104":[1,58],"106":43,"107":[1,66],"109":[1,67],"110":44,"111":[1,68],"112":45,"113":[1,69],"114":70,"122":[1,46],"127":41,"128":[1,64],"129":[1,65],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"8":187,"9":127,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"31":71,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":72,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":47,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,42],"103":[1,51],"104":[1,58],"106":43,"107":[1,66],"109":[1,67],"110":44,"111":[1,68],"112":45,"113":[1,69],"114":70,"122":[1,46],"127":41,"128":[1,64],"129":[1,65],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"8":188,"9":127,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"31":71,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":72,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":47,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,42],"103":[1,51],"104":[1,58],"106":43,"107":[1,66],"109":[1,67],"110":44,"111":[1,68],"112":45,"113":[1,69],"114":70,"122":[1,46],"127":41,"128":[1,64],"129":[1,65],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"8":189,"9":127,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"31":71,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":72,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":47,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,42],"103":[1,51],"104":[1,58],"106":43,"107":[1,66],"109":[1,67],"110":44,"111":[1,68],"112":45,"113":[1,69],"114":70,"122":[1,46],"127":41,"128":[1,64],"129":[1,65],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"8":190,"9":127,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"31":71,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":72,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":47,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,42],"103":[1,51],"104":[1,58],"106":43,"107":[1,66],"109":[1,67],"110":44,"111":[1,68],"112":45,"113":[1,69],"114":70,"122":[1,46],"127":41,"128":[1,64],"129":[1,65],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"8":191,"9":127,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"31":71,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":72,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":47,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,42],"103":[1,51],"104":[1,58],"106":43,"107":[1,66],"109":[1,67],"110":44,"111":[1,68],"112":45,"113":[1,69],"114":70,"122":[1,46],"127":41,"128":[1,64],"129":[1,65],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"1":[2,152],"4":[2,152],"29":[2,152],"30":[2,152],"47":[2,152],"55":[2,152],"59":[2,152],"75":[2,152],"80":[2,152],"90":[2,152],"94":[2,152],"96":[2,152],"105":[2,152],"107":[2,152],"108":[2,152],"109":[2,152],"113":[2,152],"121":[2,152],"130":[2,152],"131":[2,152],"133":[2,152],"134":[2,152],"135":[2,152],"136":[2,152],"137":[2,152],"138":[2,152],"139":[2,152],"140":[2,152],"141":[2,152],"142":[2,152],"144":[2,152]},{"1":[2,157],"4":[2,157],"29":[2,157],"30":[2,157],"47":[2,157],"55":[2,157],"59":[2,157],"75":[2,157],"80":[2,157],"90":[2,157],"94":[2,157],"96":[2,157],"105":[2,157],"107":[2,157],"108":[2,157],"109":[2,157],"113":[2,157],"121":[2,157],"130":[2,157],"131":[2,157],"133":[2,157],"134":[2,157],"135":[2,157],"136":[2,157],"137":[2,157],"138":[2,157],"139":[2,157],"140":[2,157],"141":[2,157],"142":[2,157],"144":[2,157]},{"1":[2,52],"4":[2,52],"29":[2,52],"30":[2,52],"47":[2,52],"55":[2,52],"59":[2,52],"75":[2,52],"80":[2,52],"90":[2,52],"94":[2,52],"96":[2,52],"105":[2,52],"107":[2,52],"108":[2,52],"109":[2,52],"113":[2,52],"121":[2,52],"130":[2,52],"131":[2,52],"133":[2,52],"134":[2,52],"135":[2,52],"136":[2,52],"137":[2,52],"138":[2,52],"139":[2,52],"140":[2,52],"141":[2,52],"142":[2,52],"144":[2,52]},{"8":192,"9":127,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"31":71,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":72,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":47,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,42],"103":[1,51],"104":[1,58],"106":43,"107":[1,66],"109":[1,67],"110":44,"111":[1,68],"112":45,"113":[1,69],"114":70,"122":[1,46],"127":41,"128":[1,64],"129":[1,65],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"8":193,"9":127,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"31":71,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":72,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":47,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,42],"103":[1,51],"104":[1,58],"106":43,"107":[1,66],"109":[1,67],"110":44,"111":[1,68],"112":45,"113":[1,69],"114":70,"122":[1,46],"127":41,"128":[1,64],"129":[1,65],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"1":[2,151],"4":[2,151],"29":[2,151],"30":[2,151],"47":[2,151],"55":[2,151],"59":[2,151],"75":[2,151],"80":[2,151],"90":[2,151],"94":[2,151],"96":[2,151],"105":[2,151],"107":[2,151],"108":[2,151],"109":[2,151],"113":[2,151],"121":[2,151],"130":[2,151],"131":[2,151],"133":[2,151],"134":[2,151],"135":[2,151],"136":[2,151],"137":[2,151],"138":[2,151],"139":[2,151],"140":[2,151],"141":[2,151],"142":[2,151],"144":[2,151]},{"1":[2,156],"4":[2,156],"29":[2,156],"30":[2,156],"47":[2,156],"55":[2,156],"59":[2,156],"75":[2,156],"80":[2,156],"90":[2,156],"94":[2,156],"96":[2,156],"105":[2,156],"107":[2,156],"108":[2,156],"109":[2,156],"113":[2,156],"121":[2,156],"130":[2,156],"131":[2,156],"133":[2,156],"134":[2,156],"135":[2,156],"136":[2,156],"137":[2,156],"138":[2,156],"139":[2,156],"140":[2,156],"141":[2,156],"142":[2,156],"144":[2,156]},{"86":194,"89":[1,119]},{"8":195,"9":127,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"29":[1,196],"31":71,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":72,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":47,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,42],"103":[1,51],"104":[1,58],"106":43,"107":[1,66],"109":[1,67],"110":44,"111":[1,68],"112":45,"113":[1,69],"114":70,"122":[1,46],"127":41,"128":[1,64],"129":[1,65],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"1":[2,68],"4":[2,68],"29":[2,68],"30":[2,68],"41":[2,68],"47":[2,68],"55":[2,68],"59":[2,68],"68":[2,68],"69":[2,68],"70":[2,68],"71":[2,68],"74":[2,68],"75":[2,68],"76":[2,68],"77":[2,68],"80":[2,68],"82":[2,68],"88":[2,68],"89":[2,68],"90":[2,68],"94":[2,68],"96":[2,68],"105":[2,68],"107":[2,68],"108":[2,68],"109":[2,68],"113":[2,68],"121":[2,68],"130":[2,68],"131":[2,68],"133":[2,68],"134":[2,68],"135":[2,68],"136":[2,68],"137":[2,68],"138":[2,68],"139":[2,68],"140":[2,68],"141":[2,68],"142":[2,68],"143":[2,68],"144":[2,68]},{"89":[2,115]},{"31":197,"32":[1,76]},{"31":198,"32":[1,76]},{"1":[2,81],"4":[2,81],"29":[2,81],"30":[2,81],"41":[2,81],"47":[2,81],"55":[2,81],"59":[2,81],"68":[2,81],"69":[2,81],"70":[2,81],"71":[2,81],"74":[2,81],"75":[2,81],"76":[2,81],"77":[2,81],"80":[2,81],"82":[2,81],"88":[2,81],"89":[2,81],"90":[2,81],"94":[2,81],"96":[2,81],"105":[2,81],"107":[2,81],"108":[2,81],"109":[2,81],"113":[2,81],"121":[2,81],"130":[2,81],"131":[2,81],"133":[2,81],"134":[2,81],"135":[2,81],"136":[2,81],"137":[2,81],"138":[2,81],"139":[2,81],"140":[2,81],"141":[2,81],"142":[2,81],"143":[2,81],"144":[2,81]},{"31":199,"32":[1,76]},{"1":[2,83],"4":[2,83],"29":[2,83],"30":[2,83],"41":[2,83],"47":[2,83],"55":[2,83],"59":[2,83],"68":[2,83],"69":[2,83],"70":[2,83],"71":[2,83],"74":[2,83],"75":[2,83],"76":[2,83],"77":[2,83],"80":[2,83],"82":[2,83],"88":[2,83],"89":[2,83],"90":[2,83],"94":[2,83],"96":[2,83],"105":[2,83],"107":[2,83],"108":[2,83],"109":[2,83],"113":[2,83],"121":[2,83],"130":[2,83],"131":[2,83],"133":[2,83],"134":[2,83],"135":[2,83],"136":[2,83],"137":[2,83],"138":[2,83],"139":[2,83],"140":[2,83],"141":[2,83],"142":[2,83],"143":[2,83],"144":[2,83]},{"1":[2,84],"4":[2,84],"29":[2,84],"30":[2,84],"41":[2,84],"47":[2,84],"55":[2,84],"59":[2,84],"68":[2,84],"69":[2,84],"70":[2,84],"71":[2,84],"74":[2,84],"75":[2,84],"76":[2,84],"77":[2,84],"80":[2,84],"82":[2,84],"88":[2,84],"89":[2,84],"90":[2,84],"94":[2,84],"96":[2,84],"105":[2,84],"107":[2,84],"108":[2,84],"109":[2,84],"113":[2,84],"121":[2,84],"130":[2,84],"131":[2,84],"133":[2,84],"134":[2,84],"135":[2,84],"136":[2,84],"137":[2,84],"138":[2,84],"139":[2,84],"140":[2,84],"141":[2,84],"142":[2,84],"143":[2,84],"144":[2,84]},{"8":200,"9":127,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"31":71,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":72,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"59":[1,203],"61":47,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"93":201,"94":[1,202],"95":[1,59],"99":[1,42],"103":[1,51],"104":[1,58],"106":43,"107":[1,66],"109":[1,67],"110":44,"111":[1,68],"112":45,"113":[1,69],"114":70,"122":[1,46],"127":41,"128":[1,64],"129":[1,65],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"72":204,"74":[1,205],"76":[1,113],"77":[1,114]},{"72":206,"74":[1,205],"76":[1,113],"77":[1,114]},{"86":207,"89":[1,119]},{"1":[2,69],"4":[2,69],"29":[2,69],"30":[2,69],"41":[2,69],"47":[2,69],"55":[2,69],"59":[2,69],"68":[2,69],"69":[2,69],"70":[2,69],"71":[2,69],"74":[2,69],"75":[2,69],"76":[2,69],"77":[2,69],"80":[2,69],"82":[2,69],"88":[2,69],"89":[2,69],"90":[2,69],"94":[2,69],"96":[2,69],"105":[2,69],"107":[2,69],"108":[2,69],"109":[2,69],"113":[2,69],"121":[2,69],"130":[2,69],"131":[2,69],"133":[2,69],"134":[2,69],"135":[2,69],"136":[2,69],"137":[2,69],"138":[2,69],"139":[2,69],"140":[2,69],"141":[2,69],"142":[2,69],"143":[2,69],"144":[2,69]},{"8":208,"9":127,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"29":[1,209],"31":71,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":72,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":47,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,42],"103":[1,51],"104":[1,58],"106":43,"107":[1,66],"109":[1,67],"110":44,"111":[1,68],"112":45,"113":[1,69],"114":70,"122":[1,46],"127":41,"128":[1,64],"129":[1,65],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"1":[2,113],"4":[2,113],"29":[2,113],"30":[2,113],"47":[2,113],"55":[2,113],"59":[2,113],"68":[2,113],"69":[2,113],"70":[2,113],"71":[2,113],"74":[2,113],"75":[2,113],"76":[2,113],"77":[2,113],"80":[2,113],"88":[2,113],"89":[2,113],"90":[2,113],"94":[2,113],"96":[2,113],"105":[2,113],"107":[2,113],"108":[2,113],"109":[2,113],"113":[2,113],"121":[2,113],"130":[2,113],"131":[2,113],"133":[2,113],"134":[2,113],"135":[2,113],"136":[2,113],"137":[2,113],"138":[2,113],"139":[2,113],"140":[2,113],"141":[2,113],"142":[2,113],"144":[2,113]},{"8":212,"9":127,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"29":[1,153],"31":71,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":72,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"60":154,"61":47,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"90":[1,210],"91":211,"92":[1,60],"95":[1,59],"97":152,"99":[1,42],"103":[1,51],"104":[1,58],"106":43,"107":[1,66],"109":[1,67],"110":44,"111":[1,68],"112":45,"113":[1,69],"114":70,"122":[1,46],"127":41,"128":[1,64],"129":[1,65],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"50":[1,213],"55":[1,214]},{"50":[2,60],"55":[2,60]},{"50":[2,62],"55":[2,62],"59":[1,215]},{"57":[1,216]},{"1":[2,54],"4":[2,54],"29":[2,54],"30":[2,54],"47":[2,54],"55":[2,54],"59":[2,54],"75":[2,54],"80":[2,54],"90":[2,54],"94":[2,54],"96":[2,54],"105":[2,54],"107":[2,54],"108":[2,54],"109":[2,54],"113":[2,54],"121":[2,54],"130":[2,54],"131":[2,54],"133":[2,54],"134":[2,54],"135":[2,54],"136":[2,54],"137":[2,54],"138":[2,54],"139":[2,54],"140":[2,54],"141":[2,54],"142":[2,54],"144":[2,54]},{"28":77,"46":[1,49]},{"1":[2,192],"4":[2,192],"29":[2,192],"30":[2,192],"47":[1,97],"55":[2,192],"59":[2,192],"75":[2,192],"80":[2,192],"90":[2,192],"94":[2,192],"96":[2,192],"105":[2,192],"106":95,"107":[2,192],"108":[2,192],"109":[2,192],"112":96,"113":[2,192],"114":70,"121":[2,192],"130":[2,192],"131":[2,192],"133":[2,192],"134":[2,192],"135":[1,82],"136":[1,83],"137":[2,192],"138":[2,192],"139":[2,192],"140":[2,192],"141":[2,192],"142":[2,192],"144":[2,192]},{"106":100,"107":[1,66],"109":[1,67],"112":101,"113":[1,69],"114":70,"130":[1,98],"131":[1,99]},{"1":[2,193],"4":[2,193],"29":[2,193],"30":[2,193],"47":[1,97],"55":[2,193],"59":[2,193],"75":[2,193],"80":[2,193],"90":[2,193],"94":[2,193],"96":[2,193],"105":[2,193],"106":95,"107":[2,193],"108":[2,193],"109":[2,193],"112":96,"113":[2,193],"114":70,"121":[2,193],"130":[2,193],"131":[2,193],"133":[2,193],"134":[2,193],"135":[1,82],"136":[1,83],"137":[2,193],"138":[2,193],"139":[2,193],"140":[2,193],"141":[2,193],"142":[2,193],"144":[2,193]},{"1":[2,194],"4":[2,194],"29":[2,194],"30":[2,194],"47":[1,97],"55":[2,194],"59":[2,194],"75":[2,194],"80":[2,194],"90":[2,194],"94":[2,194],"96":[2,194],"105":[2,194],"106":95,"107":[2,194],"108":[2,194],"109":[2,194],"112":96,"113":[2,194],"114":70,"121":[2,194],"130":[2,194],"131":[2,194],"133":[2,194],"134":[2,194],"135":[1,82],"136":[1,83],"137":[2,194],"138":[2,194],"139":[2,194],"140":[2,194],"141":[2,194],"142":[2,194],"144":[2,194]},{"1":[2,195],"4":[2,195],"29":[2,195],"30":[2,195],"47":[2,195],"55":[2,195],"59":[2,195],"75":[2,195],"80":[2,195],"90":[2,195],"94":[2,195],"96":[2,195],"105":[2,195],"106":95,"107":[2,195],"108":[2,195],"109":[2,195],"112":96,"113":[2,195],"114":70,"121":[2,195],"130":[2,195],"131":[2,195],"133":[2,195],"134":[2,195],"137":[2,195],"138":[2,195],"139":[2,195],"140":[2,195],"141":[2,195],"142":[2,195],"144":[2,195]},{"1":[2,196],"4":[2,196],"29":[2,196],"30":[2,196],"47":[2,196],"55":[2,196],"59":[2,196],"75":[2,196],"80":[2,196],"90":[2,196],"94":[2,196],"96":[2,196],"105":[2,196],"106":95,"107":[2,196],"108":[2,196],"109":[2,196],"112":96,"113":[2,196],"114":70,"121":[2,196],"130":[2,196],"131":[2,196],"133":[2,196],"134":[2,196],"137":[2,196],"138":[2,196],"139":[2,196],"140":[2,196],"141":[2,196],"142":[2,196],"144":[2,196]},{"4":[1,125],"6":218,"29":[1,6],"128":[1,217]},{"1":[2,138],"4":[2,138],"29":[2,138],"30":[2,138],"47":[2,138],"55":[2,138],"59":[2,138],"75":[2,138],"80":[2,138],"90":[2,138],"94":[2,138],"96":[2,138],"100":219,"101":[1,220],"102":[1,221],"105":[2,138],"107":[2,138],"108":[2,138],"109":[2,138],"113":[2,138],"121":[2,138],"130":[2,138],"131":[2,138],"133":[2,138],"134":[2,138],"135":[2,138],"136":[2,138],"137":[2,138],"138":[2,138],"139":[2,138],"140":[2,138],"141":[2,138],"142":[2,138],"144":[2,138]},{"1":[2,150],"4":[2,150],"29":[2,150],"30":[2,150],"47":[2,150],"55":[2,150],"59":[2,150],"75":[2,150],"80":[2,150],"90":[2,150],"94":[2,150],"96":[2,150],"105":[2,150],"107":[2,150],"108":[2,150],"109":[2,150],"113":[2,150],"121":[2,150],"130":[2,150],"131":[2,150],"133":[2,150],"134":[2,150],"135":[2,150],"136":[2,150],"137":[2,150],"138":[2,150],"139":[2,150],"140":[2,150],"141":[2,150],"142":[2,150],"144":[2,150]},{"1":[2,158],"4":[2,158],"29":[2,158],"30":[2,158],"47":[2,158],"55":[2,158],"59":[2,158],"75":[2,158],"80":[2,158],"90":[2,158],"94":[2,158],"96":[2,158],"105":[2,158],"107":[2,158],"108":[2,158],"109":[2,158],"113":[2,158],"121":[2,158],"130":[2,158],"131":[2,158],"133":[2,158],"134":[2,158],"135":[2,158],"136":[2,158],"137":[2,158],"138":[2,158],"139":[2,158],"140":[2,158],"141":[2,158],"142":[2,158],"144":[2,158]},{"29":[1,222],"47":[1,97],"106":95,"107":[1,66],"109":[1,67],"112":96,"113":[1,69],"114":70,"130":[1,93],"131":[1,94],"133":[1,85],"134":[1,84],"135":[1,82],"136":[1,83],"137":[1,86],"138":[1,87],"139":[1,88],"140":[1,89],"141":[1,90],"142":[1,91],"144":[1,92]},{"123":223,"125":224,"126":[1,225]},{"15":226,"16":143,"31":71,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":144,"43":72,"58":[1,61],"61":227,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"87":[1,33],"92":[1,60],"95":[1,59],"104":[1,58]},{"1":[2,94],"4":[2,94],"29":[1,229],"30":[2,94],"47":[2,94],"55":[2,94],"59":[2,94],"68":[2,71],"69":[2,71],"70":[2,71],"71":[2,71],"74":[2,71],"75":[2,94],"76":[2,71],"77":[2,71],"80":[2,94],"82":[1,228],"88":[2,71],"89":[2,71],"90":[2,94],"94":[2,94],"96":[2,94],"105":[2,94],"107":[2,94],"108":[2,94],"109":[2,94],"113":[2,94],"121":[2,94],"130":[2,94],"131":[2,94],"133":[2,94],"134":[2,94],"135":[2,94],"136":[2,94],"137":[2,94],"138":[2,94],"139":[2,94],"140":[2,94],"141":[2,94],"142":[2,94],"144":[2,94]},{"4":[2,105],"28":177,"30":[2,105],"31":174,"32":[1,76],"33":175,"34":[1,74],"35":[1,75],"42":233,"43":234,"46":[1,49],"58":[1,178],"78":[1,232],"83":230,"84":231},{"15":235,"16":143,"31":71,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":144,"43":72,"58":[1,61],"61":227,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"87":[1,33],"92":[1,60],"95":[1,59],"104":[1,58]},{"62":104,"68":[1,106],"69":[1,107],"70":[1,108],"71":[1,109],"72":110,"73":111,"74":[1,112],"76":[1,113],"77":[1,114],"85":102,"88":[1,105],"89":[2,114]},{"62":116,"68":[1,106],"69":[1,107],"70":[1,108],"71":[1,109],"72":110,"73":111,"74":[1,112],"76":[1,113],"77":[1,114],"85":115,"88":[1,105],"89":[2,114]},{"1":[2,74],"4":[2,74],"29":[2,74],"30":[2,74],"47":[2,74],"55":[2,74],"59":[2,74],"68":[2,74],"69":[2,74],"70":[2,74],"71":[2,74],"74":[2,74],"75":[2,74],"76":[2,74],"77":[2,74],"80":[2,74],"88":[2,74],"89":[2,74],"90":[2,74],"94":[2,74],"96":[2,74],"105":[2,74],"107":[2,74],"108":[2,74],"109":[2,74],"113":[2,74],"121":[2,74],"130":[2,74],"131":[2,74],"133":[2,74],"134":[2,74],"135":[2,74],"136":[2,74],"137":[2,74],"138":[2,74],"139":[2,74],"140":[2,74],"141":[2,74],"142":[2,74],"144":[2,74]},{"1":[2,49],"4":[2,49],"30":[2,49],"47":[1,97],"105":[2,49],"106":95,"107":[1,66],"109":[1,67],"112":96,"113":[1,69],"114":70,"130":[2,49],"131":[2,49],"133":[1,85],"134":[1,84],"135":[1,82],"136":[1,83],"137":[1,86],"138":[1,87],"139":[1,88],"140":[1,89],"141":[1,90],"142":[1,91],"144":[1,92]},{"1":[2,143],"4":[2,143],"30":[2,143],"47":[1,97],"105":[2,143],"106":95,"107":[2,143],"109":[2,143],"112":96,"113":[2,143],"114":70,"130":[2,143],"131":[2,143],"133":[1,85],"134":[1,84],"135":[1,82],"136":[1,83],"137":[1,86],"138":[1,87],"139":[1,88],"140":[1,89],"141":[1,90],"142":[1,91],"144":[1,92]},{"105":[1,236]},{"1":[2,145],"4":[2,145],"29":[2,145],"30":[2,145],"47":[2,145],"55":[2,145],"59":[2,145],"68":[2,145],"69":[2,145],"70":[2,145],"71":[2,145],"74":[2,145],"75":[2,145],"76":[2,145],"77":[2,145],"80":[2,145],"88":[2,145],"89":[2,145],"90":[2,145],"94":[2,145],"96":[2,145],"105":[2,145],"107":[2,145],"108":[2,145],"109":[2,145],"113":[2,145],"121":[2,145],"130":[2,145],"131":[2,145],"133":[2,145],"134":[2,145],"135":[2,145],"136":[2,145],"137":[2,145],"138":[2,145],"139":[2,145],"140":[2,145],"141":[2,145],"142":[2,145],"143":[2,145],"144":[2,145]},{"4":[2,134],"29":[2,134],"47":[1,97],"55":[2,134],"59":[1,238],"93":237,"94":[1,202],"96":[2,134],"106":95,"107":[1,66],"109":[1,67],"112":96,"113":[1,69],"114":70,"130":[1,93],"131":[1,94],"133":[1,85],"134":[1,84],"135":[1,82],"136":[1,83],"137":[1,86],"138":[1,87],"139":[1,88],"140":[1,89],"141":[1,90],"142":[1,91],"144":[1,92]},{"1":[2,127],"4":[2,127],"29":[2,127],"30":[2,127],"41":[2,127],"47":[2,127],"55":[2,127],"59":[2,127],"68":[2,127],"69":[2,127],"70":[2,127],"71":[2,127],"74":[2,127],"75":[2,127],"76":[2,127],"77":[2,127],"80":[2,127],"88":[2,127],"89":[2,127],"90":[2,127],"94":[2,127],"96":[2,127],"105":[2,127],"107":[2,127],"108":[2,127],"109":[2,127],"113":[2,127],"119":[2,127],"120":[2,127],"121":[2,127],"130":[2,127],"131":[2,127],"133":[2,127],"134":[2,127],"135":[2,127],"136":[2,127],"137":[2,127],"138":[2,127],"139":[2,127],"140":[2,127],"141":[2,127],"142":[2,127],"143":[2,127],"144":[2,127]},{"4":[2,57],"29":[2,57],"54":239,"55":[1,240],"96":[2,57]},{"4":[2,129],"29":[2,129],"30":[2,129],"55":[2,129],"90":[2,129],"96":[2,129]},{"8":212,"9":127,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"29":[1,153],"31":71,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":72,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"60":154,"61":47,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"91":241,"92":[1,60],"95":[1,59],"97":152,"99":[1,42],"103":[1,51],"104":[1,58],"106":43,"107":[1,66],"109":[1,67],"110":44,"111":[1,68],"112":45,"113":[1,69],"114":70,"122":[1,46],"127":41,"128":[1,64],"129":[1,65],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"4":[2,135],"29":[2,135],"30":[2,135],"55":[2,135],"90":[2,135],"96":[2,135]},{"1":[2,122],"4":[2,122],"29":[2,122],"30":[2,122],"41":[2,122],"44":[2,122],"47":[2,122],"55":[2,122],"59":[2,122],"68":[2,122],"69":[2,122],"70":[2,122],"71":[2,122],"74":[2,122],"75":[2,122],"76":[2,122],"77":[2,122],"80":[2,122],"82":[2,122],"88":[2,122],"89":[2,122],"90":[2,122],"94":[2,122],"96":[2,122],"105":[2,122],"107":[2,122],"108":[2,122],"109":[2,122],"113":[2,122],"121":[2,122],"130":[2,122],"131":[2,122],"133":[2,122],"134":[2,122],"135":[2,122],"136":[2,122],"137":[2,122],"138":[2,122],"139":[2,122],"140":[2,122],"141":[2,122],"142":[2,122],"143":[2,122],"144":[2,122]},{"4":[1,125],"6":242,"29":[1,6],"47":[1,97],"106":95,"107":[1,66],"109":[1,67],"112":96,"113":[1,69],"114":70,"130":[1,93],"131":[1,94],"133":[1,85],"134":[1,84],"135":[1,82],"136":[1,83],"137":[1,86],"138":[1,87],"139":[1,88],"140":[1,89],"141":[1,90],"142":[1,91],"144":[1,92]},{"4":[1,125],"6":243,"29":[1,6],"47":[1,97],"106":95,"107":[1,66],"109":[1,67],"112":96,"113":[1,69],"114":70,"130":[1,93],"131":[1,94],"133":[1,85],"134":[1,84],"135":[1,82],"136":[1,83],"137":[1,86],"138":[1,87],"139":[1,88],"140":[1,89],"141":[1,90],"142":[1,91],"144":[1,92]},{"1":[2,146],"4":[2,146],"29":[2,146],"30":[2,146],"47":[1,97],"55":[2,146],"59":[2,146],"75":[2,146],"80":[2,146],"90":[2,146],"94":[2,146],"96":[2,146],"105":[2,146],"106":95,"107":[1,66],"108":[1,244],"109":[1,67],"112":96,"113":[1,69],"114":70,"121":[2,146],"130":[2,146],"131":[2,146],"133":[1,85],"134":[1,84],"135":[1,82],"136":[1,83],"137":[1,86],"138":[1,87],"139":[1,88],"140":[1,89],"141":[1,90],"142":[1,91],"144":[1,92]},{"1":[2,148],"4":[2,148],"29":[2,148],"30":[2,148],"47":[1,97],"55":[2,148],"59":[2,148],"75":[2,148],"80":[2,148],"90":[2,148],"94":[2,148],"96":[2,148],"105":[2,148],"106":95,"107":[1,66],"108":[1,245],"109":[1,67],"112":96,"113":[1,69],"114":70,"121":[2,148],"130":[2,148],"131":[2,148],"133":[1,85],"134":[1,84],"135":[1,82],"136":[1,83],"137":[1,86],"138":[1,87],"139":[1,88],"140":[1,89],"141":[1,90],"142":[1,91],"144":[1,92]},{"1":[2,154],"4":[2,154],"29":[2,154],"30":[2,154],"47":[2,154],"55":[2,154],"59":[2,154],"75":[2,154],"80":[2,154],"90":[2,154],"94":[2,154],"96":[2,154],"105":[2,154],"107":[2,154],"108":[2,154],"109":[2,154],"113":[2,154],"121":[2,154],"130":[2,154],"131":[2,154],"133":[2,154],"134":[2,154],"135":[2,154],"136":[2,154],"137":[2,154],"138":[2,154],"139":[2,154],"140":[2,154],"141":[2,154],"142":[2,154],"144":[2,154]},{"1":[2,155],"4":[2,155],"29":[2,155],"30":[2,155],"47":[1,97],"55":[2,155],"59":[2,155],"75":[2,155],"80":[2,155],"90":[2,155],"94":[2,155],"96":[2,155],"105":[2,155],"106":95,"107":[1,66],"108":[2,155],"109":[1,67],"112":96,"113":[1,69],"114":70,"121":[2,155],"130":[2,155],"131":[2,155],"133":[1,85],"134":[1,84],"135":[1,82],"136":[1,83],"137":[1,86],"138":[1,87],"139":[1,88],"140":[1,89],"141":[1,90],"142":[1,91],"144":[1,92]},{"1":[2,159],"4":[2,159],"29":[2,159],"30":[2,159],"47":[2,159],"55":[2,159],"59":[2,159],"75":[2,159],"80":[2,159],"90":[2,159],"94":[2,159],"96":[2,159],"105":[2,159],"107":[2,159],"108":[2,159],"109":[2,159],"113":[2,159],"121":[2,159],"130":[2,159],"131":[2,159],"133":[2,159],"134":[2,159],"135":[2,159],"136":[2,159],"137":[2,159],"138":[2,159],"139":[2,159],"140":[2,159],"141":[2,159],"142":[2,159],"144":[2,159]},{"119":[2,161],"120":[2,161]},{"31":166,"32":[1,76],"63":167,"64":168,"78":[1,73],"95":[1,247],"116":246,"118":165},{"55":[1,248],"119":[2,166],"120":[2,166]},{"55":[2,163],"119":[2,163],"120":[2,163]},{"55":[2,164],"119":[2,164],"120":[2,164]},{"55":[2,165],"119":[2,165],"120":[2,165]},{"1":[2,160],"4":[2,160],"29":[2,160],"30":[2,160],"47":[2,160],"55":[2,160],"59":[2,160],"75":[2,160],"80":[2,160],"90":[2,160],"94":[2,160],"96":[2,160],"105":[2,160],"107":[2,160],"108":[2,160],"109":[2,160],"113":[2,160],"121":[2,160],"130":[2,160],"131":[2,160],"133":[2,160],"134":[2,160],"135":[2,160],"136":[2,160],"137":[2,160],"138":[2,160],"139":[2,160],"140":[2,160],"141":[2,160],"142":[2,160],"144":[2,160]},{"8":249,"9":127,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"31":71,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":72,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":47,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,42],"103":[1,51],"104":[1,58],"106":43,"107":[1,66],"109":[1,67],"110":44,"111":[1,68],"112":45,"113":[1,69],"114":70,"122":[1,46],"127":41,"128":[1,64],"129":[1,65],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"8":250,"9":127,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"31":71,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":72,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":47,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,42],"103":[1,51],"104":[1,58],"106":43,"107":[1,66],"109":[1,67],"110":44,"111":[1,68],"112":45,"113":[1,69],"114":70,"122":[1,46],"127":41,"128":[1,64],"129":[1,65],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"4":[2,57],"29":[2,57],"54":251,"55":[1,252],"80":[2,57]},{"4":[2,90],"29":[2,90],"30":[2,90],"55":[2,90],"80":[2,90]},{"4":[2,41],"29":[2,41],"30":[2,41],"44":[1,253],"55":[2,41],"80":[2,41]},{"4":[2,42],"29":[2,42],"30":[2,42],"44":[1,254],"55":[2,42],"80":[2,42]},{"4":[2,43],"29":[2,43],"30":[2,43],"55":[2,43],"80":[2,43]},{"4":[2,48],"29":[2,48],"30":[2,48],"55":[2,48],"80":[2,48]},{"31":155,"32":[1,76]},{"1":[2,6],"4":[2,6],"30":[2,6]},{"1":[2,29],"4":[2,29],"29":[2,29],"30":[2,29],"47":[2,29],"55":[2,29],"59":[2,29],"75":[2,29],"80":[2,29],"90":[2,29],"94":[2,29],"96":[2,29],"101":[2,29],"102":[2,29],"105":[2,29],"107":[2,29],"108":[2,29],"109":[2,29],"113":[2,29],"121":[2,29],"124":[2,29],"126":[2,29],"130":[2,29],"131":[2,29],"133":[2,29],"134":[2,29],"135":[2,29],"136":[2,29],"137":[2,29],"138":[2,29],"139":[2,29],"140":[2,29],"141":[2,29],"142":[2,29],"144":[2,29]},{"1":[2,199],"4":[2,199],"29":[2,199],"30":[2,199],"47":[1,97],"55":[2,199],"59":[2,199],"75":[2,199],"80":[2,199],"90":[2,199],"94":[2,199],"96":[2,199],"105":[2,199],"106":95,"107":[2,199],"108":[2,199],"109":[2,199],"112":96,"113":[2,199],"114":70,"121":[2,199],"130":[2,199],"131":[2,199],"133":[2,199],"134":[2,199],"135":[1,82],"136":[1,83],"137":[2,199],"138":[2,199],"139":[1,88],"140":[2,199],"141":[2,199],"142":[2,199],"144":[2,199]},{"1":[2,200],"4":[2,200],"29":[2,200],"30":[2,200],"47":[1,97],"55":[2,200],"59":[2,200],"75":[2,200],"80":[2,200],"90":[2,200],"94":[2,200],"96":[2,200],"105":[2,200],"106":95,"107":[2,200],"108":[2,200],"109":[2,200],"112":96,"113":[2,200],"114":70,"121":[2,200],"130":[2,200],"131":[2,200],"133":[2,200],"134":[2,200],"135":[1,82],"136":[1,83],"137":[2,200],"138":[2,200],"139":[1,88],"140":[2,200],"141":[2,200],"142":[2,200],"144":[2,200]},{"1":[2,201],"4":[2,201],"29":[2,201],"30":[2,201],"47":[1,97],"55":[2,201],"59":[2,201],"75":[2,201],"80":[2,201],"90":[2,201],"94":[2,201],"96":[2,201],"105":[2,201],"106":95,"107":[2,201],"108":[2,201],"109":[2,201],"112":96,"113":[2,201],"114":70,"121":[2,201],"130":[2,201],"131":[2,201],"133":[1,85],"134":[1,84],"135":[1,82],"136":[1,83],"137":[2,201],"138":[2,201],"139":[1,88],"140":[1,89],"141":[1,90],"142":[2,201],"144":[1,92]},{"1":[2,202],"4":[2,202],"29":[2,202],"30":[2,202],"47":[1,97],"55":[2,202],"59":[2,202],"75":[2,202],"80":[2,202],"90":[2,202],"94":[2,202],"96":[2,202],"105":[2,202],"106":95,"107":[2,202],"108":[2,202],"109":[2,202],"112":96,"113":[2,202],"114":70,"121":[2,202],"130":[2,202],"131":[2,202],"133":[1,85],"134":[1,84],"135":[1,82],"136":[1,83],"137":[2,202],"138":[2,202],"139":[1,88],"140":[1,89],"141":[1,90],"142":[2,202],"144":[1,92]},{"1":[2,203],"4":[2,203],"29":[2,203],"30":[2,203],"47":[1,97],"55":[2,203],"59":[2,203],"75":[2,203],"80":[2,203],"90":[2,203],"94":[2,203],"96":[2,203],"105":[2,203],"106":95,"107":[2,203],"108":[2,203],"109":[2,203],"112":96,"113":[2,203],"114":70,"121":[2,203],"130":[2,203],"131":[2,203],"133":[2,203],"134":[2,203],"135":[1,82],"136":[1,83],"137":[2,203],"138":[2,203],"139":[2,203],"140":[2,203],"141":[2,203],"142":[2,203],"144":[2,203]},{"1":[2,204],"4":[2,204],"29":[2,204],"30":[2,204],"47":[1,97],"55":[2,204],"59":[2,204],"75":[2,204],"80":[2,204],"90":[2,204],"94":[2,204],"96":[2,204],"105":[2,204],"106":95,"107":[2,204],"108":[2,204],"109":[2,204],"112":96,"113":[2,204],"114":70,"121":[2,204],"130":[2,204],"131":[2,204],"133":[1,85],"134":[1,84],"135":[1,82],"136":[1,83],"137":[2,204],"138":[2,204],"139":[1,88],"140":[2,204],"141":[2,204],"142":[2,204],"144":[2,204]},{"1":[2,205],"4":[2,205],"29":[2,205],"30":[2,205],"47":[1,97],"55":[2,205],"59":[2,205],"75":[2,205],"80":[2,205],"90":[2,205],"94":[2,205],"96":[2,205],"105":[2,205],"106":95,"107":[2,205],"108":[2,205],"109":[2,205],"112":96,"113":[2,205],"114":70,"121":[2,205],"130":[2,205],"131":[2,205],"133":[1,85],"134":[1,84],"135":[1,82],"136":[1,83],"137":[2,205],"138":[2,205],"139":[1,88],"140":[1,89],"141":[2,205],"142":[2,205],"144":[2,205]},{"1":[2,206],"4":[2,206],"29":[2,206],"30":[2,206],"47":[1,97],"55":[2,206],"59":[2,206],"75":[2,206],"80":[2,206],"90":[2,206],"94":[2,206],"96":[2,206],"105":[2,206],"106":95,"107":[2,206],"108":[2,206],"109":[2,206],"112":96,"113":[2,206],"114":70,"121":[2,206],"130":[2,206],"131":[2,206],"133":[1,85],"134":[1,84],"135":[1,82],"136":[1,83],"137":[1,86],"138":[1,87],"139":[1,88],"140":[1,89],"141":[1,90],"142":[2,206],"144":[1,92]},{"1":[2,209],"4":[2,209],"29":[2,209],"30":[2,209],"47":[1,97],"55":[2,209],"59":[2,209],"75":[2,209],"80":[2,209],"90":[2,209],"94":[2,209],"96":[2,209],"105":[2,209],"106":95,"107":[2,209],"108":[2,209],"109":[2,209],"112":96,"113":[2,209],"114":70,"121":[2,209],"130":[2,209],"131":[2,209],"133":[1,85],"134":[1,84],"135":[1,82],"136":[1,83],"137":[2,209],"138":[2,209],"139":[1,88],"140":[1,89],"141":[1,90],"142":[2,209],"144":[2,209]},{"1":[2,189],"4":[2,189],"29":[2,189],"30":[2,189],"47":[1,97],"55":[2,189],"59":[2,189],"75":[2,189],"80":[2,189],"90":[2,189],"94":[2,189],"96":[2,189],"105":[2,189],"106":95,"107":[1,66],"108":[2,189],"109":[1,67],"112":96,"113":[1,69],"114":70,"121":[2,189],"130":[1,93],"131":[1,94],"133":[1,85],"134":[1,84],"135":[1,82],"136":[1,83],"137":[1,86],"138":[1,87],"139":[1,88],"140":[1,89],"141":[1,90],"142":[1,91],"144":[1,92]},{"1":[2,191],"4":[2,191],"29":[2,191],"30":[2,191],"47":[1,97],"55":[2,191],"59":[2,191],"75":[2,191],"80":[2,191],"90":[2,191],"94":[2,191],"96":[2,191],"105":[2,191],"106":95,"107":[1,66],"108":[2,191],"109":[1,67],"112":96,"113":[1,69],"114":70,"121":[2,191],"130":[1,93],"131":[1,94],"133":[1,85],"134":[1,84],"135":[1,82],"136":[1,83],"137":[1,86],"138":[1,87],"139":[1,88],"140":[1,89],"141":[1,90],"142":[1,91],"144":[1,92]},{"1":[2,188],"4":[2,188],"29":[2,188],"30":[2,188],"47":[1,97],"55":[2,188],"59":[2,188],"75":[2,188],"80":[2,188],"90":[2,188],"94":[2,188],"96":[2,188],"105":[2,188],"106":95,"107":[1,66],"108":[2,188],"109":[1,67],"112":96,"113":[1,69],"114":70,"121":[2,188],"130":[1,93],"131":[1,94],"133":[1,85],"134":[1,84],"135":[1,82],"136":[1,83],"137":[1,86],"138":[1,87],"139":[1,88],"140":[1,89],"141":[1,90],"142":[1,91],"144":[1,92]},{"1":[2,190],"4":[2,190],"29":[2,190],"30":[2,190],"47":[1,97],"55":[2,190],"59":[2,190],"75":[2,190],"80":[2,190],"90":[2,190],"94":[2,190],"96":[2,190],"105":[2,190],"106":95,"107":[1,66],"108":[2,190],"109":[1,67],"112":96,"113":[1,69],"114":70,"121":[2,190],"130":[1,93],"131":[1,94],"133":[1,85],"134":[1,84],"135":[1,82],"136":[1,83],"137":[1,86],"138":[1,87],"139":[1,88],"140":[1,89],"141":[1,90],"142":[1,91],"144":[1,92]},{"1":[2,110],"4":[2,110],"29":[2,110],"30":[2,110],"47":[2,110],"55":[2,110],"59":[2,110],"68":[2,110],"69":[2,110],"70":[2,110],"71":[2,110],"74":[2,110],"75":[2,110],"76":[2,110],"77":[2,110],"80":[2,110],"88":[2,110],"89":[2,110],"90":[2,110],"94":[2,110],"96":[2,110],"105":[2,110],"107":[2,110],"108":[2,110],"109":[2,110],"113":[2,110],"121":[2,110],"130":[2,110],"131":[2,110],"133":[2,110],"134":[2,110],"135":[2,110],"136":[2,110],"137":[2,110],"138":[2,110],"139":[2,110],"140":[2,110],"141":[2,110],"142":[2,110],"144":[2,110]},{"1":[2,207],"4":[2,207],"29":[2,207],"30":[2,207],"47":[1,97],"55":[2,207],"59":[2,207],"75":[2,207],"80":[2,207],"90":[2,207],"94":[2,207],"96":[2,207],"105":[2,207],"106":95,"107":[2,207],"108":[2,207],"109":[2,207],"112":96,"113":[2,207],"114":70,"121":[2,207],"130":[2,207],"131":[2,207],"133":[1,85],"134":[1,84],"135":[1,82],"136":[1,83],"137":[1,86],"138":[1,87],"139":[1,88],"140":[1,89],"141":[1,90],"142":[1,91],"144":[1,92]},{"8":255,"9":127,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"31":71,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":72,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":47,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,42],"103":[1,51],"104":[1,58],"106":43,"107":[1,66],"109":[1,67],"110":44,"111":[1,68],"112":45,"113":[1,69],"114":70,"122":[1,46],"127":41,"128":[1,64],"129":[1,65],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"1":[2,79],"4":[2,79],"29":[2,79],"30":[2,79],"41":[2,79],"47":[2,79],"55":[2,79],"59":[2,79],"68":[2,79],"69":[2,79],"70":[2,79],"71":[2,79],"74":[2,79],"75":[2,79],"76":[2,79],"77":[2,79],"80":[2,79],"82":[2,79],"88":[2,79],"89":[2,79],"90":[2,79],"94":[2,79],"96":[2,79],"105":[2,79],"107":[2,79],"108":[2,79],"109":[2,79],"113":[2,79],"121":[2,79],"130":[2,79],"131":[2,79],"133":[2,79],"134":[2,79],"135":[2,79],"136":[2,79],"137":[2,79],"138":[2,79],"139":[2,79],"140":[2,79],"141":[2,79],"142":[2,79],"143":[2,79],"144":[2,79]},{"1":[2,80],"4":[2,80],"29":[2,80],"30":[2,80],"41":[2,80],"47":[2,80],"55":[2,80],"59":[2,80],"68":[2,80],"69":[2,80],"70":[2,80],"71":[2,80],"74":[2,80],"75":[2,80],"76":[2,80],"77":[2,80],"80":[2,80],"82":[2,80],"88":[2,80],"89":[2,80],"90":[2,80],"94":[2,80],"96":[2,80],"105":[2,80],"107":[2,80],"108":[2,80],"109":[2,80],"113":[2,80],"121":[2,80],"130":[2,80],"131":[2,80],"133":[2,80],"134":[2,80],"135":[2,80],"136":[2,80],"137":[2,80],"138":[2,80],"139":[2,80],"140":[2,80],"141":[2,80],"142":[2,80],"143":[2,80],"144":[2,80]},{"1":[2,82],"4":[2,82],"29":[2,82],"30":[2,82],"41":[2,82],"47":[2,82],"55":[2,82],"59":[2,82],"68":[2,82],"69":[2,82],"70":[2,82],"71":[2,82],"74":[2,82],"75":[2,82],"76":[2,82],"77":[2,82],"80":[2,82],"82":[2,82],"88":[2,82],"89":[2,82],"90":[2,82],"94":[2,82],"96":[2,82],"105":[2,82],"107":[2,82],"108":[2,82],"109":[2,82],"113":[2,82],"121":[2,82],"130":[2,82],"131":[2,82],"133":[2,82],"134":[2,82],"135":[2,82],"136":[2,82],"137":[2,82],"138":[2,82],"139":[2,82],"140":[2,82],"141":[2,82],"142":[2,82],"143":[2,82],"144":[2,82]},{"47":[1,97],"59":[1,203],"75":[1,256],"93":257,"94":[1,202],"106":95,"107":[1,66],"109":[1,67],"112":96,"113":[1,69],"114":70,"130":[1,93],"131":[1,94],"133":[1,85],"134":[1,84],"135":[1,82],"136":[1,83],"137":[1,86],"138":[1,87],"139":[1,88],"140":[1,89],"141":[1,90],"142":[1,91],"144":[1,92]},{"8":258,"9":127,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"31":71,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":72,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":47,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,42],"103":[1,51],"104":[1,58],"106":43,"107":[1,66],"109":[1,67],"110":44,"111":[1,68],"112":45,"113":[1,69],"114":70,"122":[1,46],"127":41,"128":[1,64],"129":[1,65],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"12":[2,120],"13":[2,120],"14":[2,120],"32":[2,120],"34":[2,120],"35":[2,120],"37":[2,120],"38":[2,120],"39":[2,120],"45":[2,120],"46":[2,120],"48":[2,120],"52":[2,120],"53":[2,120],"58":[2,120],"75":[2,120],"78":[2,120],"81":[2,120],"87":[2,120],"92":[2,120],"95":[2,120],"99":[2,120],"103":[2,120],"104":[2,120],"107":[2,120],"109":[2,120],"111":[2,120],"113":[2,120],"122":[2,120],"128":[2,120],"129":[2,120],"132":[2,120],"133":[2,120],"134":[2,120],"135":[2,120],"136":[2,120]},{"12":[2,121],"13":[2,121],"14":[2,121],"32":[2,121],"34":[2,121],"35":[2,121],"37":[2,121],"38":[2,121],"39":[2,121],"45":[2,121],"46":[2,121],"48":[2,121],"52":[2,121],"53":[2,121],"58":[2,121],"75":[2,121],"78":[2,121],"81":[2,121],"87":[2,121],"92":[2,121],"95":[2,121],"99":[2,121],"103":[2,121],"104":[2,121],"107":[2,121],"109":[2,121],"111":[2,121],"113":[2,121],"122":[2,121],"128":[2,121],"129":[2,121],"132":[2,121],"133":[2,121],"134":[2,121],"135":[2,121],"136":[2,121]},{"1":[2,86],"4":[2,86],"29":[2,86],"30":[2,86],"41":[2,86],"47":[2,86],"55":[2,86],"59":[2,86],"68":[2,86],"69":[2,86],"70":[2,86],"71":[2,86],"74":[2,86],"75":[2,86],"76":[2,86],"77":[2,86],"80":[2,86],"82":[2,86],"88":[2,86],"89":[2,86],"90":[2,86],"94":[2,86],"96":[2,86],"105":[2,86],"107":[2,86],"108":[2,86],"109":[2,86],"113":[2,86],"121":[2,86],"130":[2,86],"131":[2,86],"133":[2,86],"134":[2,86],"135":[2,86],"136":[2,86],"137":[2,86],"138":[2,86],"139":[2,86],"140":[2,86],"141":[2,86],"142":[2,86],"143":[2,86],"144":[2,86]},{"8":259,"9":127,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"31":71,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":72,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":47,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,42],"103":[1,51],"104":[1,58],"106":43,"107":[1,66],"109":[1,67],"110":44,"111":[1,68],"112":45,"113":[1,69],"114":70,"122":[1,46],"127":41,"128":[1,64],"129":[1,65],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"1":[2,87],"4":[2,87],"29":[2,87],"30":[2,87],"41":[2,87],"47":[2,87],"55":[2,87],"59":[2,87],"68":[2,87],"69":[2,87],"70":[2,87],"71":[2,87],"74":[2,87],"75":[2,87],"76":[2,87],"77":[2,87],"80":[2,87],"82":[2,87],"88":[2,87],"89":[2,87],"90":[2,87],"94":[2,87],"96":[2,87],"105":[2,87],"107":[2,87],"108":[2,87],"109":[2,87],"113":[2,87],"121":[2,87],"130":[2,87],"131":[2,87],"133":[2,87],"134":[2,87],"135":[2,87],"136":[2,87],"137":[2,87],"138":[2,87],"139":[2,87],"140":[2,87],"141":[2,87],"142":[2,87],"143":[2,87],"144":[2,87]},{"1":[2,111],"4":[2,111],"29":[2,111],"30":[2,111],"47":[2,111],"55":[2,111],"59":[2,111],"68":[2,111],"69":[2,111],"70":[2,111],"71":[2,111],"74":[2,111],"75":[2,111],"76":[2,111],"77":[2,111],"80":[2,111],"88":[2,111],"89":[2,111],"90":[2,111],"94":[2,111],"96":[2,111],"105":[2,111],"107":[2,111],"108":[2,111],"109":[2,111],"113":[2,111],"121":[2,111],"130":[2,111],"131":[2,111],"133":[2,111],"134":[2,111],"135":[2,111],"136":[2,111],"137":[2,111],"138":[2,111],"139":[2,111],"140":[2,111],"141":[2,111],"142":[2,111],"144":[2,111]},{"1":[2,39],"4":[2,39],"29":[2,39],"30":[2,39],"47":[1,97],"55":[2,39],"59":[2,39],"75":[2,39],"80":[2,39],"90":[2,39],"94":[2,39],"96":[2,39],"105":[2,39],"106":95,"107":[1,66],"108":[2,39],"109":[1,67],"112":96,"113":[1,69],"114":70,"121":[2,39],"130":[2,39],"131":[2,39],"133":[1,85],"134":[1,84],"135":[1,82],"136":[1,83],"137":[1,86],"138":[1,87],"139":[1,88],"140":[1,89],"141":[1,90],"142":[1,91],"144":[1,92]},{"8":260,"9":127,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"31":71,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":72,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":47,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,42],"103":[1,51],"104":[1,58],"106":43,"107":[1,66],"109":[1,67],"110":44,"111":[1,68],"112":45,"113":[1,69],"114":70,"122":[1,46],"127":41,"128":[1,64],"129":[1,65],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"1":[2,116],"4":[2,116],"29":[2,116],"30":[2,116],"47":[2,116],"55":[2,116],"59":[2,116],"68":[2,116],"69":[2,116],"70":[2,116],"71":[2,116],"74":[2,116],"75":[2,116],"76":[2,116],"77":[2,116],"80":[2,116],"88":[2,116],"89":[2,116],"90":[2,116],"94":[2,116],"96":[2,116],"105":[2,116],"107":[2,116],"108":[2,116],"109":[2,116],"113":[2,116],"121":[2,116],"130":[2,116],"131":[2,116],"133":[2,116],"134":[2,116],"135":[2,116],"136":[2,116],"137":[2,116],"138":[2,116],"139":[2,116],"140":[2,116],"141":[2,116],"142":[2,116],"144":[2,116]},{"4":[2,57],"29":[2,57],"54":261,"55":[1,240],"90":[2,57]},{"4":[2,134],"29":[2,134],"30":[2,134],"47":[1,97],"55":[2,134],"59":[1,262],"90":[2,134],"96":[2,134],"106":95,"107":[1,66],"109":[1,67],"112":96,"113":[1,69],"114":70,"130":[1,93],"131":[1,94],"133":[1,85],"134":[1,84],"135":[1,82],"136":[1,83],"137":[1,86],"138":[1,87],"139":[1,88],"140":[1,89],"141":[1,90],"142":[1,91],"144":[1,92]},{"51":263,"52":[1,62],"53":[1,63]},{"56":264,"57":[1,122],"58":[1,123]},{"50":[2,64],"55":[2,64]},{"50":[2,63],"55":[2,63],"59":[1,265]},{"8":266,"9":127,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"31":71,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":72,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":47,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,42],"103":[1,51],"104":[1,58],"106":43,"107":[1,66],"109":[1,67],"110":44,"111":[1,68],"112":45,"113":[1,69],"114":70,"122":[1,46],"127":41,"128":[1,64],"129":[1,65],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"1":[2,186],"4":[2,186],"29":[2,186],"30":[2,186],"47":[2,186],"55":[2,186],"59":[2,186],"75":[2,186],"80":[2,186],"90":[2,186],"94":[2,186],"96":[2,186],"105":[2,186],"107":[2,186],"108":[2,186],"109":[2,186],"113":[2,186],"121":[2,186],"124":[2,186],"130":[2,186],"131":[2,186],"133":[2,186],"134":[2,186],"135":[2,186],"136":[2,186],"137":[2,186],"138":[2,186],"139":[2,186],"140":[2,186],"141":[2,186],"142":[2,186],"144":[2,186]},{"1":[2,139],"4":[2,139],"29":[2,139],"30":[2,139],"47":[2,139],"55":[2,139],"59":[2,139],"75":[2,139],"80":[2,139],"90":[2,139],"94":[2,139],"96":[2,139],"101":[1,267],"105":[2,139],"107":[2,139],"108":[2,139],"109":[2,139],"113":[2,139],"121":[2,139],"130":[2,139],"131":[2,139],"133":[2,139],"134":[2,139],"135":[2,139],"136":[2,139],"137":[2,139],"138":[2,139],"139":[2,139],"140":[2,139],"141":[2,139],"142":[2,139],"144":[2,139]},{"4":[1,125],"6":268,"29":[1,6]},{"31":269,"32":[1,76]},{"123":270,"125":224,"126":[1,225]},{"30":[1,271],"124":[1,272],"125":273,"126":[1,225]},{"30":[2,179],"124":[2,179],"126":[2,179]},{"8":275,"9":127,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"31":71,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":72,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":47,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"98":274,"99":[1,42],"103":[1,51],"104":[1,58],"106":43,"107":[1,66],"109":[1,67],"110":44,"111":[1,68],"112":45,"113":[1,69],"114":70,"122":[1,46],"127":41,"128":[1,64],"129":[1,65],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"1":[2,109],"4":[2,109],"29":[2,109],"30":[2,109],"47":[2,109],"55":[2,109],"59":[2,109],"62":104,"68":[1,106],"69":[1,107],"70":[1,108],"71":[1,109],"72":110,"73":111,"74":[1,112],"75":[2,109],"76":[1,113],"77":[1,114],"80":[2,109],"85":102,"88":[1,105],"89":[2,114],"90":[2,109],"94":[2,109],"96":[2,109],"105":[2,109],"107":[2,109],"108":[2,109],"109":[2,109],"113":[2,109],"121":[2,109],"130":[2,109],"131":[2,109],"133":[2,109],"134":[2,109],"135":[2,109],"136":[2,109],"137":[2,109],"138":[2,109],"139":[2,109],"140":[2,109],"141":[2,109],"142":[2,109],"144":[2,109]},{"1":[2,71],"4":[2,71],"29":[2,71],"30":[2,71],"47":[2,71],"55":[2,71],"59":[2,71],"68":[2,71],"69":[2,71],"70":[2,71],"71":[2,71],"74":[2,71],"75":[2,71],"76":[2,71],"77":[2,71],"80":[2,71],"88":[2,71],"89":[2,71],"90":[2,71],"94":[2,71],"96":[2,71],"105":[2,71],"107":[2,71],"108":[2,71],"109":[2,71],"113":[2,71],"121":[2,71],"130":[2,71],"131":[2,71],"133":[2,71],"134":[2,71],"135":[2,71],"136":[2,71],"137":[2,71],"138":[2,71],"139":[2,71],"140":[2,71],"141":[2,71],"142":[2,71],"144":[2,71]},{"15":276,"16":143,"31":71,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":144,"43":72,"58":[1,61],"61":227,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"87":[1,33],"92":[1,60],"95":[1,59],"104":[1,58]},{"4":[2,105],"28":177,"30":[2,105],"31":174,"32":[1,76],"33":175,"34":[1,74],"35":[1,75],"42":233,"43":234,"46":[1,49],"58":[1,178],"78":[1,232],"83":277,"84":231},{"4":[1,279],"30":[1,278]},{"4":[2,106],"30":[2,106],"80":[2,106]},{"4":[2,105],"28":177,"31":174,"32":[1,76],"33":175,"34":[1,74],"35":[1,75],"42":233,"43":234,"46":[1,49],"58":[1,178],"78":[1,232],"80":[2,105],"83":280,"84":231},{"4":[2,102],"30":[2,102],"80":[2,102]},{"4":[2,43],"30":[2,43],"44":[1,281],"80":[2,43]},{"1":[2,100],"4":[2,100],"29":[1,282],"30":[2,100],"47":[2,100],"55":[2,100],"59":[2,100],"62":104,"68":[1,106],"69":[1,107],"70":[1,108],"71":[1,109],"72":110,"73":111,"74":[1,112],"75":[2,100],"76":[1,113],"77":[1,114],"80":[2,100],"85":102,"88":[1,105],"89":[2,114],"90":[2,100],"94":[2,100],"96":[2,100],"105":[2,100],"107":[2,100],"108":[2,100],"109":[2,100],"113":[2,100],"121":[2,100],"130":[2,100],"131":[2,100],"133":[2,100],"134":[2,100],"135":[2,100],"136":[2,100],"137":[2,100],"138":[2,100],"139":[2,100],"140":[2,100],"141":[2,100],"142":[2,100],"144":[2,100]},{"1":[2,144],"4":[2,144],"29":[2,144],"30":[2,144],"47":[2,144],"55":[2,144],"59":[2,144],"68":[2,144],"69":[2,144],"70":[2,144],"71":[2,144],"74":[2,144],"75":[2,144],"76":[2,144],"77":[2,144],"80":[2,144],"88":[2,144],"89":[2,144],"90":[2,144],"94":[2,144],"96":[2,144],"105":[2,144],"107":[2,144],"108":[2,144],"109":[2,144],"113":[2,144],"121":[2,144],"130":[2,144],"131":[2,144],"133":[2,144],"134":[2,144],"135":[2,144],"136":[2,144],"137":[2,144],"138":[2,144],"139":[2,144],"140":[2,144],"141":[2,144],"142":[2,144],"143":[2,144],"144":[2,144]},{"8":283,"9":127,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"31":71,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":72,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":47,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,42],"103":[1,51],"104":[1,58],"106":43,"107":[1,66],"109":[1,67],"110":44,"111":[1,68],"112":45,"113":[1,69],"114":70,"122":[1,46],"127":41,"128":[1,64],"129":[1,65],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"4":[2,66],"12":[2,121],"13":[2,121],"14":[2,121],"29":[2,66],"32":[2,121],"34":[2,121],"35":[2,121],"37":[2,121],"38":[2,121],"39":[2,121],"45":[2,121],"46":[2,121],"48":[2,121],"52":[2,121],"53":[2,121],"55":[2,66],"58":[2,121],"78":[2,121],"81":[2,121],"87":[2,121],"92":[2,121],"95":[2,121],"96":[2,66],"99":[2,121],"103":[2,121],"104":[2,121],"107":[2,121],"109":[2,121],"111":[2,121],"113":[2,121],"122":[2,121],"128":[2,121],"129":[2,121],"132":[2,121],"133":[2,121],"134":[2,121],"135":[2,121],"136":[2,121]},{"4":[1,285],"29":[1,286],"96":[1,284]},{"4":[2,58],"8":212,"9":127,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"29":[2,58],"30":[2,58],"31":71,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":72,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"60":154,"61":47,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"90":[2,58],"92":[1,60],"95":[1,59],"96":[2,58],"97":287,"99":[1,42],"103":[1,51],"104":[1,58],"106":43,"107":[1,66],"109":[1,67],"110":44,"111":[1,68],"112":45,"113":[1,69],"114":70,"122":[1,46],"127":41,"128":[1,64],"129":[1,65],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"4":[2,57],"29":[2,57],"30":[2,57],"54":288,"55":[1,240]},{"1":[2,183],"4":[2,183],"29":[2,183],"30":[2,183],"47":[2,183],"55":[2,183],"59":[2,183],"75":[2,183],"80":[2,183],"90":[2,183],"94":[2,183],"96":[2,183],"105":[2,183],"107":[2,183],"108":[2,183],"109":[2,183],"113":[2,183],"121":[2,183],"124":[2,183],"130":[2,183],"131":[2,183],"133":[2,183],"134":[2,183],"135":[2,183],"136":[2,183],"137":[2,183],"138":[2,183],"139":[2,183],"140":[2,183],"141":[2,183],"142":[2,183],"144":[2,183]},{"1":[2,184],"4":[2,184],"29":[2,184],"30":[2,184],"47":[2,184],"55":[2,184],"59":[2,184],"75":[2,184],"80":[2,184],"90":[2,184],"94":[2,184],"96":[2,184],"105":[2,184],"107":[2,184],"108":[2,184],"109":[2,184],"113":[2,184],"121":[2,184],"124":[2,184],"130":[2,184],"131":[2,184],"133":[2,184],"134":[2,184],"135":[2,184],"136":[2,184],"137":[2,184],"138":[2,184],"139":[2,184],"140":[2,184],"141":[2,184],"142":[2,184],"144":[2,184]},{"8":289,"9":127,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"31":71,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":72,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":47,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,42],"103":[1,51],"104":[1,58],"106":43,"107":[1,66],"109":[1,67],"110":44,"111":[1,68],"112":45,"113":[1,69],"114":70,"122":[1,46],"127":41,"128":[1,64],"129":[1,65],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"8":290,"9":127,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"31":71,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":72,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":47,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,42],"103":[1,51],"104":[1,58],"106":43,"107":[1,66],"109":[1,67],"110":44,"111":[1,68],"112":45,"113":[1,69],"114":70,"122":[1,46],"127":41,"128":[1,64],"129":[1,65],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"119":[2,162],"120":[2,162]},{"8":212,"9":127,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"29":[1,153],"31":71,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":72,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"60":154,"61":47,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"91":151,"92":[1,60],"95":[1,59],"96":[1,150],"97":152,"99":[1,42],"103":[1,51],"104":[1,58],"106":43,"107":[1,66],"109":[1,67],"110":44,"111":[1,68],"112":45,"113":[1,69],"114":70,"122":[1,46],"127":41,"128":[1,64],"129":[1,65],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"31":166,"32":[1,76],"63":167,"64":168,"78":[1,73],"95":[1,247],"118":291},{"1":[2,168],"4":[2,168],"29":[2,168],"30":[2,168],"47":[1,97],"55":[2,168],"59":[2,168],"75":[2,168],"80":[2,168],"90":[2,168],"94":[2,168],"96":[2,168],"105":[2,168],"106":95,"107":[2,168],"108":[1,292],"109":[2,168],"112":96,"113":[2,168],"114":70,"121":[1,293],"130":[2,168],"131":[2,168],"133":[1,85],"134":[1,84],"135":[1,82],"136":[1,83],"137":[1,86],"138":[1,87],"139":[1,88],"140":[1,89],"141":[1,90],"142":[1,91],"144":[1,92]},{"1":[2,169],"4":[2,169],"29":[2,169],"30":[2,169],"47":[1,97],"55":[2,169],"59":[2,169],"75":[2,169],"80":[2,169],"90":[2,169],"94":[2,169],"96":[2,169],"105":[2,169],"106":95,"107":[2,169],"108":[1,294],"109":[2,169],"112":96,"113":[2,169],"114":70,"121":[2,169],"130":[2,169],"131":[2,169],"133":[1,85],"134":[1,84],"135":[1,82],"136":[1,83],"137":[1,86],"138":[1,87],"139":[1,88],"140":[1,89],"141":[1,90],"142":[1,91],"144":[1,92]},{"4":[1,296],"29":[1,297],"80":[1,295]},{"4":[2,58],"28":177,"29":[2,58],"30":[2,58],"31":174,"32":[1,76],"33":175,"34":[1,74],"35":[1,75],"42":298,"43":176,"46":[1,49],"58":[1,178],"80":[2,58]},{"8":299,"9":127,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"29":[1,300],"31":71,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":72,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":47,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,42],"103":[1,51],"104":[1,58],"106":43,"107":[1,66],"109":[1,67],"110":44,"111":[1,68],"112":45,"113":[1,69],"114":70,"122":[1,46],"127":41,"128":[1,64],"129":[1,65],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"8":301,"9":127,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"29":[1,302],"31":71,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":72,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":47,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,42],"103":[1,51],"104":[1,58],"106":43,"107":[1,66],"109":[1,67],"110":44,"111":[1,68],"112":45,"113":[1,69],"114":70,"122":[1,46],"127":41,"128":[1,64],"129":[1,65],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"30":[1,303],"47":[1,97],"106":95,"107":[1,66],"109":[1,67],"112":96,"113":[1,69],"114":70,"130":[1,93],"131":[1,94],"133":[1,85],"134":[1,84],"135":[1,82],"136":[1,83],"137":[1,86],"138":[1,87],"139":[1,88],"140":[1,89],"141":[1,90],"142":[1,91],"144":[1,92]},{"1":[2,85],"4":[2,85],"29":[2,85],"30":[2,85],"41":[2,85],"47":[2,85],"55":[2,85],"59":[2,85],"68":[2,85],"69":[2,85],"70":[2,85],"71":[2,85],"74":[2,85],"75":[2,85],"76":[2,85],"77":[2,85],"80":[2,85],"82":[2,85],"88":[2,85],"89":[2,85],"90":[2,85],"94":[2,85],"96":[2,85],"105":[2,85],"107":[2,85],"108":[2,85],"109":[2,85],"113":[2,85],"121":[2,85],"130":[2,85],"131":[2,85],"133":[2,85],"134":[2,85],"135":[2,85],"136":[2,85],"137":[2,85],"138":[2,85],"139":[2,85],"140":[2,85],"141":[2,85],"142":[2,85],"143":[2,85],"144":[2,85]},{"8":304,"9":127,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"31":71,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":72,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":47,"63":52,"64":53,"65":30,"66":31,"67":32,"75":[1,305],"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,42],"103":[1,51],"104":[1,58],"106":43,"107":[1,66],"109":[1,67],"110":44,"111":[1,68],"112":45,"113":[1,69],"114":70,"122":[1,46],"127":41,"128":[1,64],"129":[1,65],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"47":[1,97],"75":[1,306],"106":95,"107":[1,66],"109":[1,67],"112":96,"113":[1,69],"114":70,"130":[1,93],"131":[1,94],"133":[1,85],"134":[1,84],"135":[1,82],"136":[1,83],"137":[1,86],"138":[1,87],"139":[1,88],"140":[1,89],"141":[1,90],"142":[1,91],"144":[1,92]},{"47":[1,97],"75":[1,256],"106":95,"107":[1,66],"109":[1,67],"112":96,"113":[1,69],"114":70,"130":[1,93],"131":[1,94],"133":[1,85],"134":[1,84],"135":[1,82],"136":[1,83],"137":[1,86],"138":[1,87],"139":[1,88],"140":[1,89],"141":[1,90],"142":[1,91],"144":[1,92]},{"30":[1,307],"47":[1,97],"106":95,"107":[1,66],"109":[1,67],"112":96,"113":[1,69],"114":70,"130":[1,93],"131":[1,94],"133":[1,85],"134":[1,84],"135":[1,82],"136":[1,83],"137":[1,86],"138":[1,87],"139":[1,88],"140":[1,89],"141":[1,90],"142":[1,91],"144":[1,92]},{"4":[1,285],"29":[1,286],"90":[1,308]},{"4":[2,66],"29":[2,66],"30":[2,66],"55":[2,66],"90":[2,66],"96":[2,66]},{"4":[1,125],"6":309,"29":[1,6]},{"50":[2,61],"55":[2,61]},{"50":[2,65],"55":[2,65]},{"4":[1,125],"6":310,"29":[1,6],"47":[1,97],"106":95,"107":[1,66],"109":[1,67],"112":96,"113":[1,69],"114":70,"130":[1,93],"131":[1,94],"133":[1,85],"134":[1,84],"135":[1,82],"136":[1,83],"137":[1,86],"138":[1,87],"139":[1,88],"140":[1,89],"141":[1,90],"142":[1,91],"144":[1,92]},{"4":[1,125],"6":311,"29":[1,6]},{"1":[2,140],"4":[2,140],"29":[2,140],"30":[2,140],"47":[2,140],"55":[2,140],"59":[2,140],"75":[2,140],"80":[2,140],"90":[2,140],"94":[2,140],"96":[2,140],"105":[2,140],"107":[2,140],"108":[2,140],"109":[2,140],"113":[2,140],"121":[2,140],"130":[2,140],"131":[2,140],"133":[2,140],"134":[2,140],"135":[2,140],"136":[2,140],"137":[2,140],"138":[2,140],"139":[2,140],"140":[2,140],"141":[2,140],"142":[2,140],"144":[2,140]},{"4":[1,125],"6":312,"29":[1,6]},{"30":[1,313],"124":[1,314],"125":273,"126":[1,225]},{"1":[2,177],"4":[2,177],"29":[2,177],"30":[2,177],"47":[2,177],"55":[2,177],"59":[2,177],"75":[2,177],"80":[2,177],"90":[2,177],"94":[2,177],"96":[2,177],"105":[2,177],"107":[2,177],"108":[2,177],"109":[2,177],"113":[2,177],"121":[2,177],"130":[2,177],"131":[2,177],"133":[2,177],"134":[2,177],"135":[2,177],"136":[2,177],"137":[2,177],"138":[2,177],"139":[2,177],"140":[2,177],"141":[2,177],"142":[2,177],"144":[2,177]},{"4":[1,125],"6":315,"29":[1,6]},{"30":[2,180],"124":[2,180],"126":[2,180]},{"4":[1,125],"6":316,"29":[1,6],"55":[1,317]},{"4":[2,136],"29":[2,136],"47":[1,97],"55":[2,136],"106":95,"107":[1,66],"109":[1,67],"112":96,"113":[1,69],"114":70,"130":[1,93],"131":[1,94],"133":[1,85],"134":[1,84],"135":[1,82],"136":[1,83],"137":[1,86],"138":[1,87],"139":[1,88],"140":[1,89],"141":[1,90],"142":[1,91],"144":[1,92]},{"1":[2,95],"4":[2,95],"29":[1,318],"30":[2,95],"47":[2,95],"55":[2,95],"59":[2,95],"62":104,"68":[1,106],"69":[1,107],"70":[1,108],"71":[1,109],"72":110,"73":111,"74":[1,112],"75":[2,95],"76":[1,113],"77":[1,114],"80":[2,95],"85":102,"88":[1,105],"89":[2,114],"90":[2,95],"94":[2,95],"96":[2,95],"105":[2,95],"107":[2,95],"108":[2,95],"109":[2,95],"113":[2,95],"121":[2,95],"130":[2,95],"131":[2,95],"133":[2,95],"134":[2,95],"135":[2,95],"136":[2,95],"137":[2,95],"138":[2,95],"139":[2,95],"140":[2,95],"141":[2,95],"142":[2,95],"144":[2,95]},{"4":[1,279],"30":[1,319]},{"1":[2,98],"4":[2,98],"29":[2,98],"30":[2,98],"47":[2,98],"55":[2,98],"59":[2,98],"75":[2,98],"80":[2,98],"90":[2,98],"94":[2,98],"96":[2,98],"105":[2,98],"107":[2,98],"108":[2,98],"109":[2,98],"113":[2,98],"121":[2,98],"130":[2,98],"131":[2,98],"133":[2,98],"134":[2,98],"135":[2,98],"136":[2,98],"137":[2,98],"138":[2,98],"139":[2,98],"140":[2,98],"141":[2,98],"142":[2,98],"144":[2,98]},{"28":177,"31":174,"32":[1,76],"33":175,"34":[1,74],"35":[1,75],"42":233,"43":234,"46":[1,49],"58":[1,178],"84":320},{"4":[1,279],"80":[1,321]},{"8":322,"9":127,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"29":[1,323],"31":71,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":72,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":47,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,42],"103":[1,51],"104":[1,58],"106":43,"107":[1,66],"109":[1,67],"110":44,"111":[1,68],"112":45,"113":[1,69],"114":70,"122":[1,46],"127":41,"128":[1,64],"129":[1,65],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"4":[2,105],"28":177,"30":[2,105],"31":174,"32":[1,76],"33":175,"34":[1,74],"35":[1,75],"42":233,"43":234,"46":[1,49],"58":[1,178],"78":[1,232],"83":324,"84":231},{"47":[1,97],"96":[1,325],"106":95,"107":[1,66],"109":[1,67],"112":96,"113":[1,69],"114":70,"130":[1,93],"131":[1,94],"133":[1,85],"134":[1,84],"135":[1,82],"136":[1,83],"137":[1,86],"138":[1,87],"139":[1,88],"140":[1,89],"141":[1,90],"142":[1,91],"144":[1,92]},{"1":[2,128],"4":[2,128],"29":[2,128],"30":[2,128],"41":[2,128],"47":[2,128],"55":[2,128],"59":[2,128],"68":[2,128],"69":[2,128],"70":[2,128],"71":[2,128],"74":[2,128],"75":[2,128],"76":[2,128],"77":[2,128],"80":[2,128],"88":[2,128],"89":[2,128],"90":[2,128],"94":[2,128],"96":[2,128],"105":[2,128],"107":[2,128],"108":[2,128],"109":[2,128],"113":[2,128],"119":[2,128],"120":[2,128],"121":[2,128],"130":[2,128],"131":[2,128],"133":[2,128],"134":[2,128],"135":[2,128],"136":[2,128],"137":[2,128],"138":[2,128],"139":[2,128],"140":[2,128],"141":[2,128],"142":[2,128],"143":[2,128],"144":[2,128]},{"8":212,"9":127,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"31":71,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":72,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"60":154,"61":47,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"97":326,"99":[1,42],"103":[1,51],"104":[1,58],"106":43,"107":[1,66],"109":[1,67],"110":44,"111":[1,68],"112":45,"113":[1,69],"114":70,"122":[1,46],"127":41,"128":[1,64],"129":[1,65],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"8":212,"9":127,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"29":[1,153],"31":71,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":72,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"60":154,"61":47,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"91":327,"92":[1,60],"95":[1,59],"97":152,"99":[1,42],"103":[1,51],"104":[1,58],"106":43,"107":[1,66],"109":[1,67],"110":44,"111":[1,68],"112":45,"113":[1,69],"114":70,"122":[1,46],"127":41,"128":[1,64],"129":[1,65],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"4":[2,130],"29":[2,130],"30":[2,130],"55":[2,130],"90":[2,130],"96":[2,130]},{"4":[1,285],"29":[1,286],"30":[1,328]},{"1":[2,147],"4":[2,147],"29":[2,147],"30":[2,147],"47":[1,97],"55":[2,147],"59":[2,147],"75":[2,147],"80":[2,147],"90":[2,147],"94":[2,147],"96":[2,147],"105":[2,147],"106":95,"107":[1,66],"108":[2,147],"109":[1,67],"112":96,"113":[1,69],"114":70,"121":[2,147],"130":[2,147],"131":[2,147],"133":[1,85],"134":[1,84],"135":[1,82],"136":[1,83],"137":[1,86],"138":[1,87],"139":[1,88],"140":[1,89],"141":[1,90],"142":[1,91],"144":[1,92]},{"1":[2,149],"4":[2,149],"29":[2,149],"30":[2,149],"47":[1,97],"55":[2,149],"59":[2,149],"75":[2,149],"80":[2,149],"90":[2,149],"94":[2,149],"96":[2,149],"105":[2,149],"106":95,"107":[1,66],"108":[2,149],"109":[1,67],"112":96,"113":[1,69],"114":70,"121":[2,149],"130":[2,149],"131":[2,149],"133":[1,85],"134":[1,84],"135":[1,82],"136":[1,83],"137":[1,86],"138":[1,87],"139":[1,88],"140":[1,89],"141":[1,90],"142":[1,91],"144":[1,92]},{"119":[2,167],"120":[2,167]},{"8":329,"9":127,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"31":71,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":72,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":47,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,42],"103":[1,51],"104":[1,58],"106":43,"107":[1,66],"109":[1,67],"110":44,"111":[1,68],"112":45,"113":[1,69],"114":70,"122":[1,46],"127":41,"128":[1,64],"129":[1,65],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"8":330,"9":127,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"31":71,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":72,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":47,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,42],"103":[1,51],"104":[1,58],"106":43,"107":[1,66],"109":[1,67],"110":44,"111":[1,68],"112":45,"113":[1,69],"114":70,"122":[1,46],"127":41,"128":[1,64],"129":[1,65],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"8":331,"9":127,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"31":71,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":72,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":47,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,42],"103":[1,51],"104":[1,58],"106":43,"107":[1,66],"109":[1,67],"110":44,"111":[1,68],"112":45,"113":[1,69],"114":70,"122":[1,46],"127":41,"128":[1,64],"129":[1,65],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"1":[2,88],"4":[2,88],"29":[2,88],"30":[2,88],"41":[2,88],"47":[2,88],"55":[2,88],"59":[2,88],"68":[2,88],"69":[2,88],"70":[2,88],"71":[2,88],"74":[2,88],"75":[2,88],"76":[2,88],"77":[2,88],"80":[2,88],"88":[2,88],"89":[2,88],"90":[2,88],"94":[2,88],"96":[2,88],"105":[2,88],"107":[2,88],"108":[2,88],"109":[2,88],"113":[2,88],"119":[2,88],"120":[2,88],"121":[2,88],"130":[2,88],"131":[2,88],"133":[2,88],"134":[2,88],"135":[2,88],"136":[2,88],"137":[2,88],"138":[2,88],"139":[2,88],"140":[2,88],"141":[2,88],"142":[2,88],"143":[2,88],"144":[2,88]},{"28":177,"31":174,"32":[1,76],"33":175,"34":[1,74],"35":[1,75],"42":332,"43":176,"46":[1,49],"58":[1,178]},{"4":[2,89],"28":177,"29":[2,89],"30":[2,89],"31":174,"32":[1,76],"33":175,"34":[1,74],"35":[1,75],"42":173,"43":176,"46":[1,49],"55":[2,89],"58":[1,178],"79":333},{"4":[2,91],"29":[2,91],"30":[2,91],"55":[2,91],"80":[2,91]},{"4":[2,44],"29":[2,44],"30":[2,44],"47":[1,97],"55":[2,44],"80":[2,44],"106":95,"107":[1,66],"109":[1,67],"112":96,"113":[1,69],"114":70,"130":[1,93],"131":[1,94],"133":[1,85],"134":[1,84],"135":[1,82],"136":[1,83],"137":[1,86],"138":[1,87],"139":[1,88],"140":[1,89],"141":[1,90],"142":[1,91],"144":[1,92]},{"8":334,"9":127,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"31":71,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":72,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":47,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,42],"103":[1,51],"104":[1,58],"106":43,"107":[1,66],"109":[1,67],"110":44,"111":[1,68],"112":45,"113":[1,69],"114":70,"122":[1,46],"127":41,"128":[1,64],"129":[1,65],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"4":[2,45],"29":[2,45],"30":[2,45],"47":[1,97],"55":[2,45],"80":[2,45],"106":95,"107":[1,66],"109":[1,67],"112":96,"113":[1,69],"114":70,"130":[1,93],"131":[1,94],"133":[1,85],"134":[1,84],"135":[1,82],"136":[1,83],"137":[1,86],"138":[1,87],"139":[1,88],"140":[1,89],"141":[1,90],"142":[1,91],"144":[1,92]},{"8":335,"9":127,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"31":71,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":72,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":47,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,42],"103":[1,51],"104":[1,58],"106":43,"107":[1,66],"109":[1,67],"110":44,"111":[1,68],"112":45,"113":[1,69],"114":70,"122":[1,46],"127":41,"128":[1,64],"129":[1,65],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"1":[2,208],"4":[2,208],"29":[2,208],"30":[2,208],"47":[2,208],"55":[2,208],"59":[2,208],"75":[2,208],"80":[2,208],"90":[2,208],"94":[2,208],"96":[2,208],"105":[2,208],"107":[2,208],"108":[2,208],"109":[2,208],"113":[2,208],"121":[2,208],"130":[2,208],"131":[2,208],"133":[2,208],"134":[2,208],"135":[2,208],"136":[2,208],"137":[2,208],"138":[2,208],"139":[2,208],"140":[2,208],"141":[2,208],"142":[2,208],"144":[2,208]},{"47":[1,97],"75":[1,336],"106":95,"107":[1,66],"109":[1,67],"112":96,"113":[1,69],"114":70,"130":[1,93],"131":[1,94],"133":[1,85],"134":[1,84],"135":[1,82],"136":[1,83],"137":[1,86],"138":[1,87],"139":[1,88],"140":[1,89],"141":[1,90],"142":[1,91],"144":[1,92]},{"1":[2,125],"4":[2,125],"29":[2,125],"30":[2,125],"41":[2,125],"47":[2,125],"55":[2,125],"59":[2,125],"68":[2,125],"69":[2,125],"70":[2,125],"71":[2,125],"74":[2,125],"75":[2,125],"76":[2,125],"77":[2,125],"80":[2,125],"82":[2,125],"88":[2,125],"89":[2,125],"90":[2,125],"94":[2,125],"96":[2,125],"105":[2,125],"107":[2,125],"108":[2,125],"109":[2,125],"113":[2,125],"121":[2,125],"130":[2,125],"131":[2,125],"133":[2,125],"134":[2,125],"135":[2,125],"136":[2,125],"137":[2,125],"138":[2,125],"139":[2,125],"140":[2,125],"141":[2,125],"142":[2,125],"143":[2,125],"144":[2,125]},{"1":[2,126],"4":[2,126],"29":[2,126],"30":[2,126],"41":[2,126],"47":[2,126],"55":[2,126],"59":[2,126],"68":[2,126],"69":[2,126],"70":[2,126],"71":[2,126],"74":[2,126],"75":[2,126],"76":[2,126],"77":[2,126],"80":[2,126],"82":[2,126],"88":[2,126],"89":[2,126],"90":[2,126],"94":[2,126],"96":[2,126],"105":[2,126],"107":[2,126],"108":[2,126],"109":[2,126],"113":[2,126],"121":[2,126],"130":[2,126],"131":[2,126],"133":[2,126],"134":[2,126],"135":[2,126],"136":[2,126],"137":[2,126],"138":[2,126],"139":[2,126],"140":[2,126],"141":[2,126],"142":[2,126],"143":[2,126],"144":[2,126]},{"1":[2,40],"4":[2,40],"29":[2,40],"30":[2,40],"47":[2,40],"55":[2,40],"59":[2,40],"75":[2,40],"80":[2,40],"90":[2,40],"94":[2,40],"96":[2,40],"105":[2,40],"107":[2,40],"108":[2,40],"109":[2,40],"113":[2,40],"121":[2,40],"130":[2,40],"131":[2,40],"133":[2,40],"134":[2,40],"135":[2,40],"136":[2,40],"137":[2,40],"138":[2,40],"139":[2,40],"140":[2,40],"141":[2,40],"142":[2,40],"144":[2,40]},{"1":[2,117],"4":[2,117],"29":[2,117],"30":[2,117],"47":[2,117],"55":[2,117],"59":[2,117],"68":[2,117],"69":[2,117],"70":[2,117],"71":[2,117],"74":[2,117],"75":[2,117],"76":[2,117],"77":[2,117],"80":[2,117],"88":[2,117],"89":[2,117],"90":[2,117],"94":[2,117],"96":[2,117],"105":[2,117],"107":[2,117],"108":[2,117],"109":[2,117],"113":[2,117],"121":[2,117],"130":[2,117],"131":[2,117],"133":[2,117],"134":[2,117],"135":[2,117],"136":[2,117],"137":[2,117],"138":[2,117],"139":[2,117],"140":[2,117],"141":[2,117],"142":[2,117],"144":[2,117]},{"1":[2,53],"4":[2,53],"29":[2,53],"30":[2,53],"47":[2,53],"55":[2,53],"59":[2,53],"75":[2,53],"80":[2,53],"90":[2,53],"94":[2,53],"96":[2,53],"105":[2,53],"107":[2,53],"108":[2,53],"109":[2,53],"113":[2,53],"121":[2,53],"130":[2,53],"131":[2,53],"133":[2,53],"134":[2,53],"135":[2,53],"136":[2,53],"137":[2,53],"138":[2,53],"139":[2,53],"140":[2,53],"141":[2,53],"142":[2,53],"144":[2,53]},{"1":[2,185],"4":[2,185],"29":[2,185],"30":[2,185],"47":[2,185],"55":[2,185],"59":[2,185],"75":[2,185],"80":[2,185],"90":[2,185],"94":[2,185],"96":[2,185],"105":[2,185],"107":[2,185],"108":[2,185],"109":[2,185],"113":[2,185],"121":[2,185],"124":[2,185],"130":[2,185],"131":[2,185],"133":[2,185],"134":[2,185],"135":[2,185],"136":[2,185],"137":[2,185],"138":[2,185],"139":[2,185],"140":[2,185],"141":[2,185],"142":[2,185],"144":[2,185]},{"1":[2,141],"4":[2,141],"29":[2,141],"30":[2,141],"47":[2,141],"55":[2,141],"59":[2,141],"75":[2,141],"80":[2,141],"90":[2,141],"94":[2,141],"96":[2,141],"105":[2,141],"107":[2,141],"108":[2,141],"109":[2,141],"113":[2,141],"121":[2,141],"130":[2,141],"131":[2,141],"133":[2,141],"134":[2,141],"135":[2,141],"136":[2,141],"137":[2,141],"138":[2,141],"139":[2,141],"140":[2,141],"141":[2,141],"142":[2,141],"144":[2,141]},{"1":[2,142],"4":[2,142],"29":[2,142],"30":[2,142],"47":[2,142],"55":[2,142],"59":[2,142],"75":[2,142],"80":[2,142],"90":[2,142],"94":[2,142],"96":[2,142],"101":[2,142],"105":[2,142],"107":[2,142],"108":[2,142],"109":[2,142],"113":[2,142],"121":[2,142],"130":[2,142],"131":[2,142],"133":[2,142],"134":[2,142],"135":[2,142],"136":[2,142],"137":[2,142],"138":[2,142],"139":[2,142],"140":[2,142],"141":[2,142],"142":[2,142],"144":[2,142]},{"1":[2,175],"4":[2,175],"29":[2,175],"30":[2,175],"47":[2,175],"55":[2,175],"59":[2,175],"75":[2,175],"80":[2,175],"90":[2,175],"94":[2,175],"96":[2,175],"105":[2,175],"107":[2,175],"108":[2,175],"109":[2,175],"113":[2,175],"121":[2,175],"130":[2,175],"131":[2,175],"133":[2,175],"134":[2,175],"135":[2,175],"136":[2,175],"137":[2,175],"138":[2,175],"139":[2,175],"140":[2,175],"141":[2,175],"142":[2,175],"144":[2,175]},{"4":[1,125],"6":337,"29":[1,6]},{"30":[1,338]},{"4":[1,339],"30":[2,181],"124":[2,181],"126":[2,181]},{"8":340,"9":127,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"31":71,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":72,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":47,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,42],"103":[1,51],"104":[1,58],"106":43,"107":[1,66],"109":[1,67],"110":44,"111":[1,68],"112":45,"113":[1,69],"114":70,"122":[1,46],"127":41,"128":[1,64],"129":[1,65],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"4":[2,105],"28":177,"30":[2,105],"31":174,"32":[1,76],"33":175,"34":[1,74],"35":[1,75],"42":233,"43":234,"46":[1,49],"58":[1,178],"78":[1,232],"83":341,"84":231},{"1":[2,96],"4":[2,96],"29":[2,96],"30":[2,96],"47":[2,96],"55":[2,96],"59":[2,96],"75":[2,96],"80":[2,96],"90":[2,96],"94":[2,96],"96":[2,96],"105":[2,96],"107":[2,96],"108":[2,96],"109":[2,96],"113":[2,96],"121":[2,96],"130":[2,96],"131":[2,96],"133":[2,96],"134":[2,96],"135":[2,96],"136":[2,96],"137":[2,96],"138":[2,96],"139":[2,96],"140":[2,96],"141":[2,96],"142":[2,96],"144":[2,96]},{"4":[2,107],"30":[2,107],"80":[2,107]},{"4":[2,108],"30":[2,108],"80":[2,108]},{"4":[2,103],"30":[2,103],"47":[1,97],"80":[2,103],"106":95,"107":[1,66],"109":[1,67],"112":96,"113":[1,69],"114":70,"130":[1,93],"131":[1,94],"133":[1,85],"134":[1,84],"135":[1,82],"136":[1,83],"137":[1,86],"138":[1,87],"139":[1,88],"140":[1,89],"141":[1,90],"142":[1,91],"144":[1,92]},{"8":342,"9":127,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"31":71,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":72,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":47,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,42],"103":[1,51],"104":[1,58],"106":43,"107":[1,66],"109":[1,67],"110":44,"111":[1,68],"112":45,"113":[1,69],"114":70,"122":[1,46],"127":41,"128":[1,64],"129":[1,65],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"4":[1,279],"30":[1,343]},{"1":[2,123],"4":[2,123],"29":[2,123],"30":[2,123],"47":[2,123],"55":[2,123],"59":[2,123],"68":[2,123],"69":[2,123],"70":[2,123],"71":[2,123],"74":[2,123],"75":[2,123],"76":[2,123],"77":[2,123],"80":[2,123],"88":[2,123],"89":[2,123],"90":[2,123],"94":[2,123],"96":[2,123],"105":[2,123],"107":[2,123],"108":[2,123],"109":[2,123],"113":[2,123],"121":[2,123],"130":[2,123],"131":[2,123],"133":[2,123],"134":[2,123],"135":[2,123],"136":[2,123],"137":[2,123],"138":[2,123],"139":[2,123],"140":[2,123],"141":[2,123],"142":[2,123],"143":[2,123],"144":[2,123]},{"4":[2,131],"29":[2,131],"30":[2,131],"55":[2,131],"90":[2,131],"96":[2,131]},{"4":[2,57],"29":[2,57],"30":[2,57],"54":344,"55":[1,240]},{"4":[2,132],"29":[2,132],"30":[2,132],"55":[2,132],"90":[2,132],"96":[2,132]},{"1":[2,170],"4":[2,170],"29":[2,170],"30":[2,170],"47":[1,97],"55":[2,170],"59":[2,170],"75":[2,170],"80":[2,170],"90":[2,170],"94":[2,170],"96":[2,170],"105":[2,170],"106":95,"107":[2,170],"108":[2,170],"109":[2,170],"112":96,"113":[2,170],"114":70,"121":[1,345],"130":[2,170],"131":[2,170],"133":[1,85],"134":[1,84],"135":[1,82],"136":[1,83],"137":[1,86],"138":[1,87],"139":[1,88],"140":[1,89],"141":[1,90],"142":[1,91],"144":[1,92]},{"1":[2,172],"4":[2,172],"29":[2,172],"30":[2,172],"47":[1,97],"55":[2,172],"59":[2,172],"75":[2,172],"80":[2,172],"90":[2,172],"94":[2,172],"96":[2,172],"105":[2,172],"106":95,"107":[2,172],"108":[1,346],"109":[2,172],"112":96,"113":[2,172],"114":70,"121":[2,172],"130":[2,172],"131":[2,172],"133":[1,85],"134":[1,84],"135":[1,82],"136":[1,83],"137":[1,86],"138":[1,87],"139":[1,88],"140":[1,89],"141":[1,90],"142":[1,91],"144":[1,92]},{"1":[2,171],"4":[2,171],"29":[2,171],"30":[2,171],"47":[1,97],"55":[2,171],"59":[2,171],"75":[2,171],"80":[2,171],"90":[2,171],"94":[2,171],"96":[2,171],"105":[2,171],"106":95,"107":[2,171],"108":[2,171],"109":[2,171],"112":96,"113":[2,171],"114":70,"121":[2,171],"130":[2,171],"131":[2,171],"133":[1,85],"134":[1,84],"135":[1,82],"136":[1,83],"137":[1,86],"138":[1,87],"139":[1,88],"140":[1,89],"141":[1,90],"142":[1,91],"144":[1,92]},{"4":[2,92],"29":[2,92],"30":[2,92],"55":[2,92],"80":[2,92]},{"4":[2,57],"29":[2,57],"30":[2,57],"54":347,"55":[1,252]},{"30":[1,348],"47":[1,97],"106":95,"107":[1,66],"109":[1,67],"112":96,"113":[1,69],"114":70,"130":[1,93],"131":[1,94],"133":[1,85],"134":[1,84],"135":[1,82],"136":[1,83],"137":[1,86],"138":[1,87],"139":[1,88],"140":[1,89],"141":[1,90],"142":[1,91],"144":[1,92]},{"30":[1,349],"47":[1,97],"106":95,"107":[1,66],"109":[1,67],"112":96,"113":[1,69],"114":70,"130":[1,93],"131":[1,94],"133":[1,85],"134":[1,84],"135":[1,82],"136":[1,83],"137":[1,86],"138":[1,87],"139":[1,88],"140":[1,89],"141":[1,90],"142":[1,91],"144":[1,92]},{"1":[2,124],"4":[2,124],"29":[2,124],"30":[2,124],"41":[2,124],"47":[2,124],"55":[2,124],"59":[2,124],"68":[2,124],"69":[2,124],"70":[2,124],"71":[2,124],"74":[2,124],"75":[2,124],"76":[2,124],"77":[2,124],"80":[2,124],"82":[2,124],"88":[2,124],"89":[2,124],"90":[2,124],"94":[2,124],"96":[2,124],"105":[2,124],"107":[2,124],"108":[2,124],"109":[2,124],"113":[2,124],"121":[2,124],"130":[2,124],"131":[2,124],"133":[2,124],"134":[2,124],"135":[2,124],"136":[2,124],"137":[2,124],"138":[2,124],"139":[2,124],"140":[2,124],"141":[2,124],"142":[2,124],"143":[2,124],"144":[2,124]},{"30":[1,350]},{"1":[2,178],"4":[2,178],"29":[2,178],"30":[2,178],"47":[2,178],"55":[2,178],"59":[2,178],"75":[2,178],"80":[2,178],"90":[2,178],"94":[2,178],"96":[2,178],"105":[2,178],"107":[2,178],"108":[2,178],"109":[2,178],"113":[2,178],"121":[2,178],"130":[2,178],"131":[2,178],"133":[2,178],"134":[2,178],"135":[2,178],"136":[2,178],"137":[2,178],"138":[2,178],"139":[2,178],"140":[2,178],"141":[2,178],"142":[2,178],"144":[2,178]},{"30":[2,182],"124":[2,182],"126":[2,182]},{"4":[2,137],"29":[2,137],"47":[1,97],"55":[2,137],"106":95,"107":[1,66],"109":[1,67],"112":96,"113":[1,69],"114":70,"130":[1,93],"131":[1,94],"133":[1,85],"134":[1,84],"135":[1,82],"136":[1,83],"137":[1,86],"138":[1,87],"139":[1,88],"140":[1,89],"141":[1,90],"142":[1,91],"144":[1,92]},{"4":[1,279],"30":[1,351]},{"30":[1,352],"47":[1,97],"106":95,"107":[1,66],"109":[1,67],"112":96,"113":[1,69],"114":70,"130":[1,93],"131":[1,94],"133":[1,85],"134":[1,84],"135":[1,82],"136":[1,83],"137":[1,86],"138":[1,87],"139":[1,88],"140":[1,89],"141":[1,90],"142":[1,91],"144":[1,92]},{"1":[2,101],"4":[2,101],"29":[2,101],"30":[2,101],"47":[2,101],"55":[2,101],"59":[2,101],"75":[2,101],"80":[2,101],"90":[2,101],"94":[2,101],"96":[2,101],"105":[2,101],"107":[2,101],"108":[2,101],"109":[2,101],"113":[2,101],"121":[2,101],"130":[2,101],"131":[2,101],"133":[2,101],"134":[2,101],"135":[2,101],"136":[2,101],"137":[2,101],"138":[2,101],"139":[2,101],"140":[2,101],"141":[2,101],"142":[2,101],"144":[2,101]},{"4":[1,285],"29":[1,286],"30":[1,353]},{"8":354,"9":127,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"31":71,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":72,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":47,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,42],"103":[1,51],"104":[1,58],"106":43,"107":[1,66],"109":[1,67],"110":44,"111":[1,68],"112":45,"113":[1,69],"114":70,"122":[1,46],"127":41,"128":[1,64],"129":[1,65],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"8":355,"9":127,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"31":71,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":72,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":47,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,42],"103":[1,51],"104":[1,58],"106":43,"107":[1,66],"109":[1,67],"110":44,"111":[1,68],"112":45,"113":[1,69],"114":70,"122":[1,46],"127":41,"128":[1,64],"129":[1,65],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"4":[1,296],"29":[1,297],"30":[1,356]},{"4":[2,46],"29":[2,46],"30":[2,46],"55":[2,46],"80":[2,46]},{"4":[2,47],"29":[2,47],"30":[2,47],"55":[2,47],"80":[2,47]},{"1":[2,176],"4":[2,176],"29":[2,176],"30":[2,176],"47":[2,176],"55":[2,176],"59":[2,176],"75":[2,176],"80":[2,176],"90":[2,176],"94":[2,176],"96":[2,176],"105":[2,176],"107":[2,176],"108":[2,176],"109":[2,176],"113":[2,176],"121":[2,176],"130":[2,176],"131":[2,176],"133":[2,176],"134":[2,176],"135":[2,176],"136":[2,176],"137":[2,176],"138":[2,176],"139":[2,176],"140":[2,176],"141":[2,176],"142":[2,176],"144":[2,176]},{"1":[2,97],"4":[2,97],"29":[2,97],"30":[2,97],"47":[2,97],"55":[2,97],"59":[2,97],"75":[2,97],"80":[2,97],"90":[2,97],"94":[2,97],"96":[2,97],"105":[2,97],"107":[2,97],"108":[2,97],"109":[2,97],"113":[2,97],"121":[2,97],"130":[2,97],"131":[2,97],"133":[2,97],"134":[2,97],"135":[2,97],"136":[2,97],"137":[2,97],"138":[2,97],"139":[2,97],"140":[2,97],"141":[2,97],"142":[2,97],"144":[2,97]},{"4":[2,104],"30":[2,104],"80":[2,104]},{"4":[2,133],"29":[2,133],"30":[2,133],"55":[2,133],"90":[2,133],"96":[2,133]},{"1":[2,173],"4":[2,173],"29":[2,173],"30":[2,173],"47":[1,97],"55":[2,173],"59":[2,173],"75":[2,173],"80":[2,173],"90":[2,173],"94":[2,173],"96":[2,173],"105":[2,173],"106":95,"107":[2,173],"108":[2,173],"109":[2,173],"112":96,"113":[2,173],"114":70,"121":[2,173],"130":[2,173],"131":[2,173],"133":[1,85],"134":[1,84],"135":[1,82],"136":[1,83],"137":[1,86],"138":[1,87],"139":[1,88],"140":[1,89],"141":[1,90],"142":[1,91],"144":[1,92]},{"1":[2,174],"4":[2,174],"29":[2,174],"30":[2,174],"47":[1,97],"55":[2,174],"59":[2,174],"75":[2,174],"80":[2,174],"90":[2,174],"94":[2,174],"96":[2,174],"105":[2,174],"106":95,"107":[2,174],"108":[2,174],"109":[2,174],"112":96,"113":[2,174],"114":70,"121":[2,174],"130":[2,174],"131":[2,174],"133":[1,85],"134":[1,84],"135":[1,82],"136":[1,83],"137":[1,86],"138":[1,87],"139":[1,88],"140":[1,89],"141":[1,90],"142":[1,91],"144":[1,92]},{"4":[2,93],"29":[2,93],"30":[2,93],"55":[2,93],"80":[2,93]}],defaultActions:{"79":[2,4],"105":[2,115]},parseError:function parseError(str,hash){throw new Error(str)},parse:function parse(input){var self=this,stack=[0],vstack=[null],table=this.table,yytext="",yylineno=0,yyleng=0,shifts=0,reductions=0,recovering=0,TERROR=2,EOF=1;this.lexer.setInput(input);this.lexer.yy=this.yy;this.yy.lexer=this.lexer;var parseError=this.yy.parseError=typeof this.yy.parseError=="function"?this.yy.parseError:this.parseError;function popStack(n){stack.length=stack.length-2*n;vstack.length=vstack.length-n}function checkRecover(st){for(var p in table[st]){if(p==TERROR){return true}}return false}function lex(){var token;token=self.lexer.lex()||1;if(typeof token!=="number"){token=self.symbols_[token]||token}return token}var symbol,preErrorSymbol,state,action,a,r,yyval={},p,len,newState,expected,recovered=false;while(true){state=stack[stack.length-1];if(this.defaultActions[state]){action=this.defaultActions[state]}else{if(symbol==null){symbol=lex()}action=table[state]&&table[state][symbol]}if(typeof action==="undefined"||!action.length||!action[0]){if(!recovering){expected=[];for(p in table[state]){if(this.terminals_[p]&&p>2){expected.push("'"+this.terminals_[p]+"'")}}if(this.lexer.showPosition){parseError.call(this,"Parse error on line "+(yylineno+1)+":\n"+this.lexer.showPosition()+"\nExpecting "+expected.join(", "),{text:this.lexer.match,token:this.terminals_[symbol]||symbol,line:this.lexer.yylineno,expected:expected})}else{parseError.call(this,"Parse error on line "+(yylineno+1)+": Unexpected '"+(this.terminals_[symbol]||symbol)+"'",{text:this.lexer.match,token:this.terminals_[symbol]||symbol,line:this.lexer.yylineno,expected:expected})}}if(recovering==3){if(symbol==EOF){throw"Parsing halted."}yyleng=this.lexer.yyleng;yytext=this.lexer.yytext;yylineno=this.lexer.yylineno;symbol=lex()}while(1){if(checkRecover(state)){break}if(state==0){throw"Parsing halted."}popStack(1);state=stack[stack.length-1]}preErrorSymbol=symbol;symbol=TERROR;state=stack[stack.length-1];action=table[state]&&table[state][TERROR];recovering=3}if(action[0] instanceof Array&&action.length>1){throw new Error("Parse Error: multiple actions possible at state: "+state+", token: "+symbol)}a=action;switch(a[0]){case 1:shifts++;stack.push(symbol);vstack.push(this.lexer.yytext);stack.push(a[1]);symbol=null;if(!preErrorSymbol){yyleng=this.lexer.yyleng;yytext=this.lexer.yytext;yylineno=this.lexer.yylineno;if(recovering>0){recovering--}}else{symbol=preErrorSymbol;preErrorSymbol=null}break;case 2:reductions++;len=this.productions_[a[1]][1];yyval.$=vstack[vstack.length-len];r=this.performAction.call(yyval,yytext,yyleng,yylineno,this.yy,a[1],vstack);if(typeof r!=="undefined"){return r}if(len){stack=stack.slice(0,-1*len*2);vstack=vstack.slice(0,-1*len)}stack.push(this.productions_[a[1]][0]);vstack.push(yyval.$);newState=table[stack[stack.length-2]][stack[stack.length-1]];stack.push(newState);break;case 3:this.reductionCount=reductions;this.shiftCount=shifts;return true}}return true}};return parser})();if(typeof require!=="undefined"){exports.parser=parser;exports.parse=function(){return parser.parse.apply(parser,arguments)};exports.main=function commonjsMain(args){if(!args[1]){throw new Error("Usage: "+args[0]+" FILE")}if(typeof process!=="undefined"){var source=require("fs").readFileSync(require("path").join(process.cwd(),args[1]),"utf8")}else{var cwd=require("file").path(require("file").cwd());var source=cwd.join(args[1]).read({charset:"utf-8"})}return exports.parser.parse(source)};if(typeof module!=="undefined"&&require.main===module){exports.main(typeof process!=="undefined"?process.argv.slice(1):require("system").args)}}};require["./scope"]=new function(){var exports=this;(function(){var Scope,_ref,extend,last;var __hasProp=Object.prototype.hasOwnProperty;_ref=require("./helpers"),extend=_ref.extend,last=_ref.last;exports.Scope=(function(){Scope=(function(){function Scope(_arg,_arg2,_arg3){this.method=_arg3;this.expressions=_arg2;this.parent=_arg;this.variables={"arguments":"arguments"};if(this.parent){this.garbage=this.parent.garbage}else{this.garbage=[];Scope.root=this}return this}return Scope})();Scope.root=null;Scope.prototype.startLevel=function(){return this.garbage.push([])};Scope.prototype.endLevel=function(){var _i,_len,_ref2,_result,name,vars;vars=this.variables;_result=[];for(_i=0,_len=(_ref2=this.garbage.pop()).length;_i<_len;_i++){name=_ref2[_i];if(vars[name]==="var"){_result.push(vars[name]="reuse")}}return _result};Scope.prototype.find=function(name,options){if(this.check(name,options)){return true}this.variables[name]="var";return false};Scope.prototype.any=function(fn){var _ref2,k,v;for(v in _ref2=this.variables){if(!__hasProp.call(_ref2,v)){continue}k=_ref2[v];if(fn(v,k)){return true}}return false};Scope.prototype.parameter=function(name){return(this.variables[name]="param")};Scope.prototype.check=function(name,options){var _ref2,immediate;immediate=Object.prototype.hasOwnProperty.call(this.variables,name);if(immediate||((options!=null)?options.immediate:undefined)){return immediate}return !!(((_ref2=this.parent)!=null)?_ref2.check(name):undefined)};Scope.prototype.temporary=function(type,index){return type.length>1?"_"+type+(index>1?index:""):"_"+(index+parseInt(type,36)).toString(36).replace(/\d/g,"a")};Scope.prototype.freeVariable=function(type){var index,temp;index=0;while(this.check(temp=this.temporary(type,index))&&this.variables[temp]!=="reuse"){index++}this.variables[temp]="var";if(this.garbage.length){last(this.garbage).push(temp)}return temp};Scope.prototype.assign=function(name,value){return(this.variables[name]={value:value,assigned:true})};Scope.prototype.hasDeclarations=function(body){return body===this.expressions&&this.any(function(k,val){return(val==="var"||val==="reuse")})};Scope.prototype.hasAssignments=function(body){return body===this.expressions&&this.any(function(k,val){return val.assigned})};Scope.prototype.declaredVariables=function(){var _ref2,_result,key,val;return(function(){_result=[];for(key in _ref2=this.variables){if(!__hasProp.call(_ref2,key)){continue}val=_ref2[key];if((val==="var"||val==="reuse")){_result.push(key)}}return _result}).call(this).sort()};Scope.prototype.assignedVariables=function(){var _ref2,_result,key,val;_result=[];for(key in _ref2=this.variables){if(!__hasProp.call(_ref2,key)){continue}val=_ref2[key];if(val.assigned){_result.push(""+key+" = "+(val.value))}}return _result};Scope.prototype.compiledDeclarations=function(){return this.declaredVariables().join(", ")};Scope.prototype.compiledAssignments=function(){return this.assignedVariables().join(", ")};return Scope}).call(this)}).call(this)};require["./nodes"]=new function(){var exports=this;(function(){var Accessor,ArrayLiteral,Assign,Base,Call,Class,Closure,Code,Comment,Existence,Expressions,Extends,For,IDENTIFIER,IS_STRING,If,In,Index,Literal,NO,NUMBER,ObjectLiteral,Op,Param,Parens,Push,Range,Return,SIMPLENUM,Scope,Slice,Splat,Switch,TAB,THIS,TRAILING_WHITESPACE,Throw,Try,UTILITIES,Value,While,YES,_ref,compact,del,ends,flatten,include,last,merge,starts,utility;var __extends=function(child,parent){function ctor(){this.constructor=child}ctor.prototype=parent.prototype;child.prototype=new ctor;if(typeof parent.extended==="function"){parent.extended(child)}child.__super__=parent.prototype};Scope=require("./scope").Scope;_ref=require("./helpers"),compact=_ref.compact,flatten=_ref.flatten,merge=_ref.merge,del=_ref.del,include=_ref.include,starts=_ref.starts,ends=_ref.ends,last=_ref.last;YES=function(){return true};NO=function(){return false};THIS=function(){return this};exports.Base=(function(){Base=(function(){function Base(){this.tags={};return this}return Base})();Base.prototype.compile=function(o){var closure,code,top;this.options=o?merge(o):{};this.tab=o.indent;top=this.topSensitive()?this.options.top:del(this.options,"top");closure=this.isStatement(o)&&!this.isPureStatement()&&!top&&!this.options.asStatement&&!(this instanceof Comment)&&!this.containsPureStatement();code=closure?this.compileClosure(this.options):this.compileNode(this.options);return code};Base.prototype.compileClosure=function(o){o.sharedScope=o.scope;return Closure.wrap(this).compile(o)};Base.prototype.compileReference=function(o,options){var _len,compiled,i,node,pair,reference;pair=(function(){if(!this.isComplex()){return[this,this]}else{reference=new Literal(o.scope.freeVariable("ref"));compiled=new Assign(reference,this);return[compiled,reference]}}).call(this);if(((options!=null)?options.precompile:undefined)){for(i=0,_len=pair.length;i<_len;i++){node=pair[i];(pair[i]=node.compile(o))}}return pair};Base.prototype.idt=function(tabs){var idt,num;idt=this.tab||"";num=(tabs||0)+1;while(num-=1){idt+=TAB}return idt};Base.prototype.makeReturn=function(){return new Return(this)};Base.prototype.contains=function(block){var contains;contains=false;this.traverseChildren(false,function(node){if(block(node)){contains=true;return false}});return contains};Base.prototype.containsType=function(type){return this instanceof type||this.contains(function(node){return node instanceof type})};Base.prototype.containsPureStatement=function(){return this.isPureStatement()||this.contains(function(node){return node.isPureStatement()})};Base.prototype.traverse=function(block){return this.traverseChildren(true,block)};Base.prototype.toString=function(idt,override){var _i,_len,_ref2,_result,child,children,klass;idt||(idt="");children=(function(){_result=[];for(_i=0,_len=(_ref2=this.collectChildren()).length;_i<_len;_i++){child=_ref2[_i];_result.push(child.toString(idt+TAB))}return _result}).call(this).join("");klass=override||this.constructor.name+(this.soakNode||this.exist?"?":"");return"\n"+idt+klass+children};Base.prototype.eachChild=function(func){var _i,_j,_len,_len2,_ref2,_ref3,_result,attr,child;if(!this.children){return}_result=[];for(_i=0,_len=(_ref2=this.children).length;_i<_len;_i++){attr=_ref2[_i];if(this[attr]){for(_j=0,_len2=(_ref3=flatten([this[attr]])).length;_j<_len2;_j++){child=_ref3[_j];if(func(child)===false){return}}}}return _result};Base.prototype.collectChildren=function(){var nodes;nodes=[];this.eachChild(function(node){return nodes.push(node)});return nodes};Base.prototype.traverseChildren=function(crossScope,func){return this.eachChild(function(child){if(func(child)===false){return false}return crossScope||!(child instanceof Code)?child.traverseChildren(crossScope,func):undefined})};Base.prototype.invert=function(){return new Op("!",this)};Base.prototype.children=[];Base.prototype.unwrap=THIS;Base.prototype.isStatement=NO;Base.prototype.isPureStatement=NO;Base.prototype.isComplex=YES;Base.prototype.topSensitive=NO;Base.prototype.assigns=NO;return Base})();exports.Expressions=(function(){Expressions=(function(){function Expressions(nodes){Expressions.__super__.constructor.call(this);this.expressions=compact(flatten(nodes||[]));return this}return Expressions})();__extends(Expressions,Base);Expressions.prototype.children=["expressions"];Expressions.prototype.isStatement=YES;Expressions.prototype.push=function(node){this.expressions.push(node);return this};Expressions.prototype.unshift=function(node){this.expressions.unshift(node);return this};Expressions.prototype.unwrap=function(){return this.expressions.length===1?this.expressions[0]:this};Expressions.prototype.empty=function(){return this.expressions.length===0};Expressions.prototype.makeReturn=function(){var end,idx;end=this.expressions[(idx=this.expressions.length-1)];if(end instanceof Comment){end=this.expressions[idx-=1]}if(end&&!(end instanceof Return)){this.expressions[idx]=end.makeReturn()}return this};Expressions.prototype.compile=function(o){o||(o={});return o.scope?Expressions.__super__.compile.call(this,o):this.compileRoot(o)};Expressions.prototype.compileNode=function(o){var _i,_len,_ref2,_result,node;return(function(){_result=[];for(_i=0,_len=(_ref2=this.expressions).length;_i<_len;_i++){node=_ref2[_i];_result.push(this.compileExpression(node,merge(o)))}return _result}).call(this).join("\n")};Expressions.prototype.compileRoot=function(o){var code;o.indent=(this.tab=o.bare?"":TAB);o.scope=new Scope(null,this,null);code=this.compileWithDeclarations(o);code=code.replace(TRAILING_WHITESPACE,"");return o.bare?code:("(function() {\n"+code+"\n}).call(this);\n")};Expressions.prototype.compileWithDeclarations=function(o){var code;code=this.compileNode(o);if(o.scope.hasAssignments(this)){code=(""+(this.tab)+"var "+(o.scope.compiledAssignments().replace(/\n/g,"$&"+this.tab))+";\n"+code)}if(!o.globals&&o.scope.hasDeclarations(this)){code=(""+(this.tab)+"var "+(o.scope.compiledDeclarations())+";\n"+code)}return code};Expressions.prototype.compileExpression=function(node,o){var compiledNode;this.tab=o.indent;node.tags.front=true;compiledNode=node.compile(merge(o,{top:true}));return node.isStatement(o)?compiledNode:(""+(this.idt())+compiledNode+";")};return Expressions})();Expressions.wrap=function(nodes){if(nodes.length===1&&nodes[0] instanceof Expressions){return nodes[0]}return new Expressions(nodes)};exports.Literal=(function(){Literal=(function(){function Literal(_arg){this.value=_arg;Literal.__super__.constructor.call(this);return this}return Literal})();__extends(Literal,Base);Literal.prototype.makeReturn=function(){return this.isStatement()?this:Literal.__super__.makeReturn.call(this)};Literal.prototype.isStatement=function(){var _ref2;return((_ref2=this.value)==="break"||_ref2==="continue"||_ref2==="debugger")};Literal.prototype.isPureStatement=Literal.prototype.isStatement;Literal.prototype.isComplex=NO;Literal.prototype.isReserved=function(){return !!this.value.reserved};Literal.prototype.assigns=function(name){return name===this.value};Literal.prototype.compileNode=function(o){var end,idt,val;idt=this.isStatement(o)?this.idt():"";end=this.isStatement(o)?";":"";val=this.isReserved()?('"'+(this.value)+'"'):this.value;return idt+val+end};Literal.prototype.toString=function(){return' "'+this.value+'"'};return Literal})();exports.Return=(function(){Return=(function(){function Return(_arg){this.expression=_arg;Return.__super__.constructor.call(this);return this}return Return})();__extends(Return,Base);Return.prototype.isStatement=YES;Return.prototype.isPureStatement=YES;Return.prototype.children=["expression"];Return.prototype.makeReturn=THIS;Return.prototype.compile=function(o){var _ref2,expr;expr=(((_ref2=this.expression)!=null)?_ref2.makeReturn():undefined);if(expr&&(!(expr instanceof Return))){return expr.compile(o)}return Return.__super__.compile.call(this,o)};Return.prototype.compileNode=function(o){var expr;expr="";if(this.expression){if(this.expression.isStatement(o)){o.asStatement=true}expr=" "+this.expression.compile(o)}return""+(this.tab)+"return"+expr+";"};return Return})();exports.Value=(function(){Value=(function(){function Value(_arg,_arg2,tag){this.properties=_arg2;this.base=_arg;Value.__super__.constructor.call(this);this.properties||(this.properties=[]);if(tag){this.tags[tag]=true}return this}return Value})();__extends(Value,Base);Value.prototype.children=["base","properties"];Value.prototype.push=function(prop){this.properties.push(prop);return this};Value.prototype.hasProperties=function(){return !!this.properties.length};Value.prototype.isArray=function(){return this.base instanceof ArrayLiteral&&!this.properties.length};Value.prototype.isObject=function(){return this.base instanceof ObjectLiteral&&!this.properties.length};Value.prototype.isSplice=function(){return last(this.properties) instanceof Slice};Value.prototype.isComplex=function(){return this.base.isComplex()||this.hasProperties()};Value.prototype.assigns=function(name){return !this.properties.length&&this.base.assigns(name)};Value.prototype.makeReturn=function(){return this.properties.length?Value.__super__.makeReturn.call(this):this.base.makeReturn()};Value.prototype.unwrap=function(){return this.properties.length?this:this.base};Value.prototype.isStatement=function(o){return this.base.isStatement(o)&&!this.properties.length};Value.prototype.isSimpleNumber=function(){return this.base instanceof Literal&&SIMPLENUM.test(this.base.value)};Value.prototype.cacheReference=function(o){var base,bref,name,nref;name=last(this.properties);if(!this.base.isComplex()&&this.properties.length<2&&!((name!=null)?name.isComplex():undefined)){return[this,this]}base=new Value(this.base,this.properties.slice(0,-1));if(base.isComplex()){bref=new Literal(o.scope.freeVariable("base"));base=new Value(new Parens(new Assign(bref,base)))}if(!name){return[base,bref]}if(name.isComplex()){nref=new Literal(o.scope.freeVariable("name"));name=new Index(new Assign(nref,name.index));nref=new Index(nref)}return[base.push(name),new Value(bref||base.base,[nref||name])]};Value.prototype.compile=function(o){this.base.tags.front=this.tags.front;return !o.top||this.properties.length?Value.__super__.compile.call(this,o):this.base.compile(o)};Value.prototype.compileNode=function(o){var _i,_len,code,ex,prop,props;if(ex=this.unfoldSoak(o)){return ex.compile(o)}props=this.properties;if(this.parenthetical&&!props.length){this.base.parenthetical=true}code=this.base.compile(o);if(props[0] instanceof Accessor&&this.isSimpleNumber()){code=("("+code+")")}for(_i=0,_len=props.length;_i<_len;_i++){prop=props[_i];(code+=prop.compile(o))}return code};Value.prototype.unfoldSoak=function(o){var _len,_ref2,fst,i,ifn,prop,ref,snd;if(this.base.soakNode){Array.prototype.push.apply(this.base.body.properties,this.properties);return this.base}for(i=0,_len=(_ref2=this.properties).length;i<_len;i++){prop=_ref2[i];if(prop.soakNode){prop.soakNode=false;fst=new Value(this.base,this.properties.slice(0,i));snd=new Value(this.base,this.properties.slice(i));if(fst.isComplex()){ref=new Literal(o.scope.freeVariable("ref"));fst=new Parens(new Assign(ref,fst));snd.base=ref}ifn=new If(new Existence(fst),snd,{operation:true});ifn.soakNode=true;return ifn}}return null};Value.unfoldSoak=function(o,parent,name){var ifnode,node;node=parent[name];if(node instanceof If&&node.soakNode){ifnode=node}else{if(node instanceof Value){ifnode=node.unfoldSoak(o)}}if(!ifnode){return}parent[name]=ifnode.body;ifnode.body=new Value(parent);return ifnode};return Value}).call(this);exports.Comment=(function(){Comment=(function(){function Comment(_arg){this.comment=_arg;Comment.__super__.constructor.call(this);return this}return Comment})();__extends(Comment,Base);Comment.prototype.isStatement=YES;Comment.prototype.makeReturn=THIS;Comment.prototype.compileNode=function(o){return this.tab+"/*"+this.comment.replace(/\n/g,"\n"+this.tab)+"*/"};return Comment})();exports.Call=(function(){Call=(function(){function Call(variable,_arg,_arg2){this.exist=_arg2;this.args=_arg;Call.__super__.constructor.call(this);this.isNew=false;this.isSuper=variable==="super";this.variable=this.isSuper?null:variable;this.args||(this.args=[]);return this}return Call})();__extends(Call,Base);Call.prototype.children=["variable","args"];Call.prototype.compileSplatArguments=function(o){return Splat.compileSplattedArray(this.args,o)};Call.prototype.newInstance=function(){this.isNew=true;return this};Call.prototype.prefix=function(){return this.isNew?"new ":""};Call.prototype.superReference=function(o){var method,name;method=o.scope.method;if(!method){throw Error("cannot call super outside of a function")}name=method.name;if(!name){throw Error("cannot call super on an anonymous function.")}return method.klass?(""+(method.klass)+".__super__."+name):(""+name+".__super__.constructor")};Call.prototype.unfoldSoak=function(o){var _i,_len,_ref2,call,list,node;call=this;list=[];while(true){if(call.variable instanceof Call){list.push(call);call=call.variable;continue}if(!(call.variable instanceof Value)){break}list.push(call);if(!((call=call.variable.base) instanceof Call)){break}}for(_i=0,_len=(_ref2=list.reverse()).length;_i<_len;_i++){call=_ref2[_i];if(node){if(call.variable instanceof Call){call.variable=node}else{call.variable.base=node}}node=Value.unfoldSoak(o,call,"variable")}return node};Call.prototype.compileNode=function(o){var _i,_j,_len,_len2,_ref2,_ref3,_ref4,_ref5,_result,arg,args,left,node,rite,val;if(node=this.unfoldSoak(o)){return node.compile(o)}(((_ref2=this.variable)!=null)?(_ref2.tags.front=this.tags.front):undefined);if(this.exist){if(val=this.variable){if(!(val instanceof Value)){val=new Value(val)}_ref3=val.cacheReference(o),left=_ref3[0],rite=_ref3[1];rite=new Call(rite,this.args)}else{left=new Literal(this.superReference(o));rite=new Call(new Value(left),this.args);rite.isNew=this.isNew}left=("typeof "+(left.compile(o))+' !== "function"');rite=rite.compile(o);return("("+left+" ? undefined : "+rite+")")}for(_i=0,_len=(_ref4=this.args).length;_i<_len;_i++){arg=_ref4[_i];if(arg instanceof Splat){return this.compileSplat(o)}}args=(function(){_result=[];for(_j=0,_len2=(_ref5=this.args).length;_j<_len2;_j++){arg=_ref5[_j];_result.push((arg.parenthetical=true)&&arg.compile(o))}return _result}).call(this).join(", ");return this.isSuper?this.compileSuper(args,o):(""+(this.prefix())+(this.variable.compile(o))+"("+args+")")};Call.prototype.compileSuper=function(args,o){return""+(this.superReference(o))+".call(this"+(args.length?", ":"")+args+")"};Call.prototype.compileSplat=function(o){var base,fun,idt,name,ref,splatargs;splatargs=this.compileSplatArguments(o);if(this.isSuper){return(""+(this.superReference(o))+".apply(this, "+splatargs+")")}if(!this.isNew){if(!((base=this.variable) instanceof Value)){base=new Value(base)}if((name=base.properties.pop())&&base.isComplex()){ref=o.scope.freeVariable("this");fun=("("+ref+" = "+(base.compile(o))+")"+(name.compile(o)))}else{fun=(ref=base.compile(o));if(name){fun+=name.compile(o)}}return(""+fun+".apply("+ref+", "+splatargs+")")}idt=this.idt(1);return"(function(func, args, ctor) {\n"+idt+"ctor.prototype = func.prototype;\n"+idt+"var child = new ctor, result = func.apply(child, args);\n"+idt+'return typeof result === "object" ? result : child;\n'+(this.tab)+"})("+(this.variable.compile(o))+", "+splatargs+", function() {})"};return Call})();exports.Extends=(function(){Extends=(function(){function Extends(_arg,_arg2){this.parent=_arg2;this.child=_arg;Extends.__super__.constructor.call(this);return this}return Extends})();__extends(Extends,Base);Extends.prototype.children=["child","parent"];Extends.prototype.compileNode=function(o){var ref;ref=new Value(new Literal(utility("extends")));return(new Call(ref,[this.child,this.parent])).compile(o)};return Extends})();exports.Accessor=(function(){Accessor=(function(){function Accessor(_arg,tag){this.name=_arg;Accessor.__super__.constructor.call(this);this.prototype=tag==="prototype"?".prototype":"";this.soakNode=tag==="soak";return this}return Accessor})();__extends(Accessor,Base);Accessor.prototype.children=["name"];Accessor.prototype.compileNode=function(o){var name,namePart;name=this.name.compile(o);namePart=name.match(IS_STRING)?("["+name+"]"):("."+name);return this.prototype+namePart};Accessor.prototype.isComplex=NO;return Accessor})();exports.Index=(function(){Index=(function(){function Index(_arg){this.index=_arg;Index.__super__.constructor.call(this);return this}return Index})();__extends(Index,Base);Index.prototype.children=["index"];Index.prototype.compileNode=function(o){var idx,prefix;idx=this.index.compile(o);prefix=this.proto?".prototype":"";return""+prefix+"["+idx+"]"};Index.prototype.isComplex=function(){return this.index.isComplex()};return Index})();exports.Range=(function(){Range=(function(){function Range(_arg,_arg2,tag){this.to=_arg2;this.from=_arg;Range.__super__.constructor.call(this);this.exclusive=tag==="exclusive";this.equals=this.exclusive?"":"=";return this}return Range})();__extends(Range,Base);Range.prototype.children=["from","to"];Range.prototype.compileVariables=function(o){var _ref2,_ref3,_ref4,parts;o=merge(o,{top:true});_ref2=this.from.compileReference(o,{precompile:true}),this.from=_ref2[0],this.fromVar=_ref2[1];_ref3=this.to.compileReference(o,{precompile:true}),this.to=_ref3[0],this.toVar=_ref3[1];_ref4=[this.fromVar.match(SIMPLENUM),this.toVar.match(SIMPLENUM)],this.fromNum=_ref4[0],this.toNum=_ref4[1];parts=[];if(this.from!==this.fromVar){parts.push(this.from)}return this.to!==this.toVar?parts.push(this.to):undefined};Range.prototype.compileNode=function(o){var compare,idx,incr,intro,step,stepPart,vars;this.compileVariables(o);if(!o.index){return this.compileArray(o)}if(this.fromNum&&this.toNum){return this.compileSimple(o)}idx=del(o,"index");step=del(o,"step");vars=(""+idx+" = "+(this.from))+(this.to!==this.toVar?(", "+(this.to)):"");intro=("("+(this.fromVar)+" <= "+(this.toVar)+" ? "+idx);compare=(""+intro+" <"+(this.equals)+" "+(this.toVar)+" : "+idx+" >"+(this.equals)+" "+(this.toVar)+")");stepPart=step?step.compile(o):"1";incr=step?(""+idx+" += "+stepPart):(""+intro+" += "+stepPart+" : "+idx+" -= "+stepPart+")");return""+vars+"; "+compare+"; "+incr};Range.prototype.compileSimple=function(o){var _ref2,from,idx,step,to;_ref2=[+this.fromNum,+this.toNum],from=_ref2[0],to=_ref2[1];idx=del(o,"index");step=del(o,"step");step&&(step=(""+idx+" += "+(step.compile(o))));return from<=to?(""+idx+" = "+from+"; "+idx+" <"+(this.equals)+" "+to+"; "+(step||(""+idx+"++"))):(""+idx+" = "+from+"; "+idx+" >"+(this.equals)+" "+to+"; "+(step||(""+idx+"--")))};Range.prototype.compileArray=function(o){var _i,_ref2,_ref3,_result,body,clause,i,idt,post,pre,range,result,vars;if(this.fromNum&&this.toNum&&(Math.abs(this.fromNum-this.toNum)<=20)){range=(function(){_result=[];for(var _i=_ref2=+this.fromNum,_ref3=+this.toNum;_ref2<=_ref3?_i<=_ref3:_i>=_ref3;_ref2<=_ref3?_i+=1:_i-=1){_result.push(_i)}return _result}).call(this);if(this.exclusive){range.pop()}return("["+(range.join(", "))+"]")}idt=this.idt(1);i=o.scope.freeVariable("i");result=o.scope.freeVariable("result");pre=("\n"+idt+result+" = [];");if(this.fromNum&&this.toNum){o.index=i;body=this.compileSimple(o)}else{vars=(""+i+" = "+(this.from))+(this.to!==this.toVar?(", "+(this.to)):"");clause=(""+(this.fromVar)+" <= "+(this.toVar)+" ?");body=("var "+vars+"; "+clause+" "+i+" <"+(this.equals)+" "+(this.toVar)+" : "+i+" >"+(this.equals)+" "+(this.toVar)+"; "+clause+" "+i+" += 1 : "+i+" -= 1")}post=("{ "+result+".push("+i+"); }\n"+idt+"return "+result+";\n"+(o.indent));return"(function() {"+pre+"\n"+idt+"for ("+body+")"+post+"}).call(this)"};return Range})();exports.Slice=(function(){Slice=(function(){function Slice(_arg){this.range=_arg;Slice.__super__.constructor.call(this);return this}return Slice})();__extends(Slice,Base);Slice.prototype.children=["range"];Slice.prototype.compileNode=function(o){var from,to;from=this.range.from?this.range.from.compile(o):"0";to=this.range.to?this.range.to.compile(o):"";to+=(!to||this.range.exclusive?"":" + 1");if(to){to=", "+to}return".slice("+from+to+")"};return Slice})();exports.ObjectLiteral=(function(){ObjectLiteral=(function(){function ObjectLiteral(props){ObjectLiteral.__super__.constructor.call(this);this.objects=(this.properties=props||[]);return this}return ObjectLiteral})();__extends(ObjectLiteral,Base);ObjectLiteral.prototype.children=["properties"];ObjectLiteral.prototype.compileNode=function(o){var _i,_len,_ref2,_result,i,indent,join,lastNoncom,nonComments,obj,prop,props,top;top=del(o,"top");o.indent=this.idt(1);nonComments=(function(){_result=[];for(_i=0,_len=(_ref2=this.properties).length;_i<_len;_i++){prop=_ref2[_i];if(!(prop instanceof Comment)){_result.push(prop)}}return _result}).call(this);lastNoncom=last(nonComments);props=(function(){_result=[];for(i=0,_len=(_ref2=this.properties).length;i<_len;i++){prop=_ref2[i];_result.push((function(){join=i===this.properties.length-1?"":(prop===lastNoncom||prop instanceof Comment?"\n":",\n");indent=prop instanceof Comment?"":this.idt(1);if(prop instanceof Value&&prop.tags["this"]){prop=new Assign(prop.properties[0].name,prop,"object")}else{if(!(prop instanceof Assign)&&!(prop instanceof Comment)){prop=new Assign(prop,prop,"object")}}return indent+prop.compile(o)+join}).call(this))}return _result}).call(this);props=props.join("");obj=("{"+(props?"\n"+props+"\n"+this.idt():"")+"}");return this.tags.front?("("+obj+")"):obj};ObjectLiteral.prototype.assigns=function(name){var _i,_len,_ref2,prop;for(_i=0,_len=(_ref2=this.properties).length;_i<_len;_i++){prop=_ref2[_i];if(prop.assigns(name)){return true}}return false};return ObjectLiteral})();exports.ArrayLiteral=(function(){ArrayLiteral=(function(){function ArrayLiteral(_arg){this.objects=_arg;ArrayLiteral.__super__.constructor.call(this);this.objects||(this.objects=[]);return this}return ArrayLiteral})();__extends(ArrayLiteral,Base);ArrayLiteral.prototype.children=["objects"];ArrayLiteral.prototype.compileSplatLiteral=function(o){return Splat.compileSplattedArray(this.objects,o)};ArrayLiteral.prototype.compileNode=function(o){var _i,_len,_len2,_ref2,_ref3,code,i,obj,objects;o.indent=this.idt(1);for(_i=0,_len=(_ref2=this.objects).length;_i<_len;_i++){obj=_ref2[_i];if(obj instanceof Splat){return this.compileSplatLiteral(o)}}objects=[];for(i=0,_len2=(_ref3=this.objects).length;i<_len2;i++){obj=_ref3[i];code=obj.compile(o);objects.push(obj instanceof Comment?("\n"+code+"\n"+(o.indent)):(i===this.objects.length-1?code:code+", "))}objects=objects.join("");return 0= "+this.arglength);end=this.trailings.length?(", "+len+" - "+(this.trailings.length)):undefined;for(idx=0,_len=(_ref2=this.trailings).length;idx<_len;idx++){trailing=_ref2[idx];if(trailing.attach){assign=trailing.assign;trailing=new Literal(o.scope.freeVariable("arg"));assign.value=trailing}pos=this.trailings.length-idx;o.scope.assign(trailing.compile(o),"arguments["+variadic+" ? "+len+" - "+pos+" : "+(this.index+idx)+"]")}}return""+name+" = "+(utility("slice"))+".call(arguments, "+(this.index)+end+")"};Splat.prototype.compileValue=function(o,name,index,trailings){var trail;trail=trailings?(", "+name+".length - "+trailings):"";return""+(utility("slice"))+".call("+name+", "+index+trail+")"};Splat.compileSplattedArray=function(list,o){var _len,arg,args,code,end,i,prev;args=[];end=-1;for(i=0,_len=list.length;i<_len;i++){arg=list[i];code=arg.compile(o);prev=args[end];if(!(arg instanceof Splat)){if(prev&&starts(prev,"[")&&ends(prev,"]")){args[end]=(""+(prev.slice(0,-1))+", "+code+"]");continue}if(prev&&starts(prev,".concat([")&&ends(prev,"])")){args[end]=(""+(prev.slice(0,-2))+", "+code+"])");continue}code=("["+code+"]")}args[++end]=i===0?code:(".concat("+code+")")}return args.join("")};return Splat}).call(this);exports.While=(function(){While=(function(){function While(condition,opts){While.__super__.constructor.call(this);this.condition=((opts!=null)?opts.invert:undefined)?condition.invert():condition;this.guard=((opts!=null)?opts.guard:undefined);return this}return While})();__extends(While,Base);While.prototype.children=["condition","guard","body"];While.prototype.isStatement=YES;While.prototype.addBody=function(body){this.body=body;return this};While.prototype.makeReturn=function(){this.returns=true;return this};While.prototype.topSensitive=YES;While.prototype.compileNode=function(o){var cond,post,pre,rvar,set,top;top=del(o,"top")&&!this.returns;o.indent=this.idt(1);this.condition.parenthetical=true;cond=this.condition.compile(o);o.top=true;set="";if(!top){rvar=o.scope.freeVariable("result");set=(""+(this.tab)+rvar+" = [];\n");if(this.body){this.body=Push.wrap(rvar,this.body)}}pre=(""+set+(this.tab)+"while ("+cond+")");if(this.guard){this.body=Expressions.wrap([new If(this.guard,this.body)])}if(this.returns){post="\n"+new Return(new Literal(rvar)).compile(merge(o,{indent:this.idt()}))}else{post=""}return""+pre+" {\n"+(this.body.compile(o))+"\n"+(this.tab)+"}"+post};return While})();exports.Op=(function(){Op=(function(){function Op(op,first,second,flip){if(op==="new"){if(first instanceof Call){return first.newInstance()}if(first instanceof Code&&first.bound){first=new Parens(first)}}Op.__super__.constructor.call(this);this.operator=this.CONVERSIONS[op]||op;(this.first=first).tags.operation=true;if(second){(this.second=second).tags.operation=true}this.flip=!!flip;return this}return Op})();__extends(Op,Base);Op.prototype.CONVERSIONS={"==":"===","!=":"!==",of:"in"};Op.prototype.INVERSIONS={"!==":"===","===":"!=="};Op.prototype.CHAINABLE=["<",">",">=","<=","===","!=="];Op.prototype.ASSIGNMENT=["||=","&&=","?="];Op.prototype.PREFIX_OPERATORS=["new","typeof","delete"];Op.prototype.children=["first","second"];Op.prototype.isUnary=function(){return !this.second};Op.prototype.isComplex=function(){return this.operator!=="!"||this.first.isComplex()};Op.prototype.isMutator=function(){var _ref2;return ends(this.operator,"=")&&!((_ref2=this.operator)==="==="||_ref2==="!==")};Op.prototype.isChainable=function(){return include(this.CHAINABLE,this.operator)};Op.prototype.invert=function(){var _ref2;if(((_ref2=this.operator)==="==="||_ref2==="!==")){this.operator=this.INVERSIONS[this.operator];return this}else{return this.second?new Parens(this).invert():Op.__super__.invert.call(this)}};Op.prototype.toString=function(idt){return Op.__super__.toString.call(this,idt,this.constructor.name+" "+this.operator)};Op.prototype.compileNode=function(o){if(this.second){this.first.tags.front=this.tags.front}if(this.isChainable()&&this.first.unwrap() instanceof Op&&this.first.unwrap().isChainable()){return this.compileChain(o)}if(include(this.ASSIGNMENT,this.operator)){return this.compileAssignment(o)}if(this.isUnary()){return this.compileUnary(o)}if(this.operator==="?"){return this.compileExistence(o)}if(this.first instanceof Op&&this.first.isMutator()){this.first=new Parens(this.first)}if(this.second instanceof Op&&this.second.isMutator()){this.second=new Parens(this.second)}return[this.first.compile(o),this.operator,this.second.compile(o)].join(" ")};Op.prototype.compileChain=function(o){var _ref2,_ref3,first,second,shared;shared=this.first.unwrap().second;_ref2=shared.compileReference(o),this.first.second=_ref2[0],shared=_ref2[1];_ref3=[this.first.compile(o),this.second.compile(o),shared.compile(o)],first=_ref3[0],second=_ref3[1],shared=_ref3[2];return"("+first+") && ("+shared+" "+(this.operator)+" "+second+")"};Op.prototype.compileAssignment=function(o){var _ref2,left,rite;_ref2=this.first.cacheReference(o),left=_ref2[0],rite=_ref2[1];rite=new Assign(rite,this.second);return new Op(this.operator.slice(0,-1),left,rite).compile(o)};Op.prototype.compileExistence=function(o){var fst,ref;if(this.first.isComplex()){ref=o.scope.freeVariable("ref");fst=new Parens(new Assign(new Literal(ref),this.first))}else{fst=this.first;ref=fst.compile(o)}return new Existence(fst).compile(o)+(" ? "+ref+" : "+(this.second.compile(o)))};Op.prototype.compileUnary=function(o){var parts,space;space=include(this.PREFIX_OPERATORS,this.operator)?" ":"";parts=[this.operator,space,this.first.compile(o)];return(this.flip?parts.reverse():parts).join("")};return Op})();exports.In=(function(){In=(function(){function In(_arg,_arg2){this.array=_arg2;this.object=_arg;In.__super__.constructor.call(this);return this}return In})();__extends(In,Base);In.prototype.children=["object","array"];In.prototype.isArray=function(){return this.array instanceof Value&&this.array.isArray()};In.prototype.compileNode=function(o){var _ref2;_ref2=this.object.compileReference(o,{precompile:true}),this.obj1=_ref2[0],this.obj2=_ref2[1];return this.isArray()?this.compileOrTest(o):this.compileLoopTest(o)};In.prototype.compileOrTest=function(o){var _len,_ref2,_result,i,item,tests;tests=(function(){_result=[];for(i=0,_len=(_ref2=this.array.base.objects).length;i<_len;i++){item=_ref2[i];_result.push(""+(i?this.obj2:this.obj1)+" === "+(item.compile(o)))}return _result}).call(this);return"("+(tests.join(" || "))+")"};In.prototype.compileLoopTest=function(o){var _ref2,_ref3,i,l,prefix;_ref2=this.array.compileReference(o,{precompile:true}),this.arr1=_ref2[0],this.arr2=_ref2[1];_ref3=[o.scope.freeVariable("i"),o.scope.freeVariable("len")],i=_ref3[0],l=_ref3[1];prefix=this.obj1!==this.obj2?this.obj1+"; ":"";return"(function(){ "+prefix+"for (var "+i+"=0, "+l+"="+(this.arr1)+".length; "+i+"<"+l+"; "+i+"++) { if ("+(this.arr2)+"["+i+"] === "+(this.obj2)+") return true; } return false; }).call(this)"};return In})();exports.Try=(function(){Try=(function(){function Try(_arg,_arg2,_arg3,_arg4){this.ensure=_arg4;this.recovery=_arg3;this.error=_arg2;this.attempt=_arg;Try.__super__.constructor.call(this);return this}return Try})();__extends(Try,Base);Try.prototype.children=["attempt","recovery","ensure"];Try.prototype.isStatement=YES;Try.prototype.makeReturn=function(){if(this.attempt){this.attempt=this.attempt.makeReturn()}if(this.recovery){this.recovery=this.recovery.makeReturn()}return this};Try.prototype.compileNode=function(o){var attemptPart,catchPart,errorPart,finallyPart;o.indent=this.idt(1);o.top=true;attemptPart=this.attempt.compile(o);errorPart=this.error?(" ("+(this.error.compile(o))+") "):" ";catchPart=this.recovery?(" catch"+errorPart+"{\n"+(this.recovery.compile(o))+"\n"+(this.tab)+"}"):(!(this.ensure||this.recovery)?" catch (_e) {}":"");finallyPart=(this.ensure||"")&&" finally {\n"+this.ensure.compile(merge(o))+("\n"+(this.tab)+"}");return""+(this.tab)+"try {\n"+attemptPart+"\n"+(this.tab)+"}"+catchPart+finallyPart};return Try})();exports.Throw=(function(){Throw=(function(){function Throw(_arg){this.expression=_arg;Throw.__super__.constructor.call(this);return this}return Throw})();__extends(Throw,Base);Throw.prototype.children=["expression"];Throw.prototype.isStatement=YES;Throw.prototype.makeReturn=THIS;Throw.prototype.compileNode=function(o){return""+(this.tab)+"throw "+(this.expression.compile(o))+";"};return Throw})();exports.Existence=(function(){Existence=(function(){function Existence(_arg){this.expression=_arg;Existence.__super__.constructor.call(this);return this}return Existence})();__extends(Existence,Base);Existence.prototype.children=["expression"];Existence.prototype.compileNode=function(o){var code;code=this.expression.compile(o);code=IDENTIFIER.test(code)&&!o.scope.check(code)?("typeof "+code+' !== "undefined" && '+code+" !== null"):(""+code+" != null");return this.parenthetical?code:("("+code+")")};return Existence})();exports.Parens=(function(){Parens=(function(){function Parens(_arg){this.expression=_arg;Parens.__super__.constructor.call(this);return this}return Parens})();__extends(Parens,Base);Parens.prototype.children=["expression"];Parens.prototype.isStatement=function(o){return this.expression.isStatement(o)};Parens.prototype.isComplex=function(){return this.expression.isComplex()};Parens.prototype.topSensitive=YES;Parens.prototype.makeReturn=function(){return this.expression.makeReturn()};Parens.prototype.compileNode=function(o){var code,top;top=del(o,"top");this.expression.parenthetical=true;code=this.expression.compile(o);if(top&&this.expression.isPureStatement(o)){return code}if(this.parenthetical||this.isStatement(o)){return top?this.tab+code+";":code}return"("+code+")"};return Parens})();exports.For=(function(){For=(function(){function For(_arg,source,_arg2,_arg3){var _ref2;this.index=_arg3;this.name=_arg2;this.body=_arg;For.__super__.constructor.call(this);this.source=source.source,this.guard=source.guard,this.step=source.step;this.raw=!!source.raw;this.object=!!source.object;if(this.object){_ref2=[this.index,this.name],this.name=_ref2[0],this.index=_ref2[1]}this.pattern=this.name instanceof Value;if(this.index instanceof Value){throw new Error("index cannot be a pattern matching expression")}this.returns=false;return this}return For})();__extends(For,Base);For.prototype.children=["body","source","guard"];For.prototype.isStatement=YES;For.prototype.topSensitive=YES;For.prototype.makeReturn=function(){this.returns=true;return this};For.prototype.compileReturnValue=function(val,o){if(this.returns){return"\n"+new Return(new Literal(val)).compile(o)}if(val){return"\n"+val}return""};For.prototype.compileNode=function(o){var body,codeInBody,forPart,guardPart,idt1,index,ivar,lvar,name,namePart,range,ref,resultPart,returnResult,rvar,scope,source,sourcePart,stepPart,svar,topLevel,varPart,vars;topLevel=del(o,"top")&&!this.returns;range=this.source instanceof Value&&this.source.base instanceof Range&&!this.source.properties.length;source=range?this.source.base:this.source;codeInBody=this.body.contains(function(node){return node instanceof Code});scope=o.scope;name=this.name&&this.name.compile(o);index=this.index&&this.index.compile(o);if(name&&!this.pattern&&(range||!codeInBody)){scope.find(name,{immediate:true})}if(index){scope.find(index,{immediate:true})}if(!topLevel){rvar=scope.freeVariable("result")}ivar=range?name:index;if(!ivar||codeInBody){ivar=scope.freeVariable("i")}varPart="";guardPart="";body=Expressions.wrap([this.body]);idt1=this.idt(1);if(range){forPart=source.compile(merge(o,{index:ivar,step:this.step}))}else{svar=(sourcePart=this.source.compile(o));if((name||!this.raw)&&!(IDENTIFIER.test(svar)&&scope.check(svar,{immediate:true}))){sourcePart=(""+(ref=scope.freeVariable("ref"))+" = "+svar);if(!this.object){sourcePart=("("+sourcePart+")")}svar=ref}namePart=this.pattern?new Assign(this.name,new Literal(""+svar+"["+ivar+"]")).compile(merge(o,{top:true})):(name?(""+name+" = "+svar+"["+ivar+"]"):undefined);if(!this.object){lvar=scope.freeVariable("len");stepPart=this.step?(""+ivar+" += "+(this.step.compile(o))):(""+ivar+"++");forPart=(""+ivar+" = 0, "+lvar+" = "+sourcePart+".length; "+ivar+" < "+lvar+"; "+stepPart)}}resultPart=rvar?(""+(this.tab)+rvar+" = [];\n"):"";returnResult=this.compileReturnValue(rvar,o);if(!topLevel){body=Push.wrap(rvar,body)}if(this.guard){body=Expressions.wrap([new If(this.guard,body)])}if(codeInBody){if(range){body.unshift(new Literal("var "+name+" = "+ivar))}if(namePart){body.unshift(new Literal("var "+namePart))}if(index){body.unshift(new Literal("var "+index+" = "+ivar))}body=Closure.wrap(body,true)}else{if(namePart){varPart=(""+idt1+namePart+";\n")}}if(this.object){forPart=(""+ivar+" in "+sourcePart);if(!this.raw){guardPart=("\n"+idt1+"if (!"+(utility("hasProp"))+".call("+svar+", "+ivar+")) continue;")}}body=body.compile(merge(o,{indent:idt1,top:true}));vars=range?name:(""+name+", "+ivar);return""+resultPart+(this.tab)+"for ("+forPart+") {"+guardPart+"\n"+varPart+body+"\n"+(this.tab)+"}"+returnResult};return For})();exports.Switch=(function(){Switch=(function(){function Switch(_arg,_arg2,_arg3){this.otherwise=_arg3;this.cases=_arg2;this.subject=_arg;Switch.__super__.constructor.call(this);this.tags.subjectless=!this.subject;this.subject||(this.subject=new Literal("true"));return this}return Switch})();__extends(Switch,Base);Switch.prototype.children=["subject","cases","otherwise"];Switch.prototype.isStatement=YES;Switch.prototype.makeReturn=function(){var _i,_len,_ref2,pair;for(_i=0,_len=(_ref2=this.cases).length;_i<_len;_i++){pair=_ref2[_i];pair[1].makeReturn()}if(this.otherwise){this.otherwise.makeReturn()}return this};Switch.prototype.compileNode=function(o){var _i,_j,_len,_len2,_ref2,_ref3,block,code,condition,conditions,exprs,idt,pair;idt=(o.indent=this.idt(2));o.top=true;code=(""+(this.tab)+"switch ("+(this.subject.compile(o))+") {");for(_i=0,_len=(_ref2=this.cases).length;_i<_len;_i++){pair=_ref2[_i];conditions=pair[0],block=pair[1];exprs=block.expressions;for(_j=0,_len2=(_ref3=flatten([conditions])).length;_j<_len2;_j++){condition=_ref3[_j];if(this.tags.subjectless){condition=new Op("!!",new Parens(condition))}code+=("\n"+(this.idt(1))+"case "+(condition.compile(o))+":")}code+=("\n"+(block.compile(o)));if(!(last(exprs) instanceof Return)){code+=("\n"+idt+"break;")}}if(this.otherwise){code+=("\n"+(this.idt(1))+"default:\n"+(this.otherwise.compile(o)))}code+=("\n"+(this.tab)+"}");return code};return Switch})();exports.If=(function(){If=(function(){function If(condition,_arg,_arg2){this.tags=_arg2;this.body=_arg;this.tags||(this.tags={});this.condition=this.tags.invert?condition.invert():condition;this.elseBody=null;this.isChain=false;return this}return If})();__extends(If,Base);If.prototype.children=["condition","body","elseBody","assigner"];If.prototype.topSensitive=YES;If.prototype.bodyNode=function(){var _ref2;return(((_ref2=this.body)!=null)?_ref2.unwrap():undefined)};If.prototype.elseBodyNode=function(){var _ref2;return(((_ref2=this.elseBody)!=null)?_ref2.unwrap():undefined)};If.prototype.addElse=function(elseBody){if(this.isChain){this.elseBodyNode().addElse(elseBody)}else{this.isChain=elseBody instanceof If;this.elseBody=this.ensureExpressions(elseBody)}return this};If.prototype.isStatement=function(o){var _ref2;return this.statement||(this.statement=((o!=null)?o.top:undefined)||this.bodyNode().isStatement(o)||(((_ref2=this.elseBodyNode())!=null)?_ref2.isStatement(o):undefined))};If.prototype.compileCondition=function(o){this.condition.parenthetical=true;return this.condition.compile(o)};If.prototype.compileNode=function(o){return this.isStatement(o)?this.compileStatement(o):this.compileExpression(o)};If.prototype.makeReturn=function(){if(this.isStatement()){this.body&&(this.body=this.ensureExpressions(this.body.makeReturn()));this.elseBody&&(this.elseBody=this.ensureExpressions(this.elseBody.makeReturn()));return this}else{return new Return(this)}};If.prototype.ensureExpressions=function(node){return node instanceof Expressions?node:new Expressions([node])};If.prototype.compileStatement=function(o){var child,condO,ifPart,top;top=del(o,"top");child=del(o,"chainChild");condO=merge(o);o.indent=this.idt(1);o.top=true;ifPart=("if ("+(this.compileCondition(condO))+") {\n"+(this.body.compile(o))+"\n"+(this.tab)+"}");if(!child){ifPart=this.tab+ifPart}if(!this.elseBody){return ifPart}return ifPart+(this.isChain?" else "+this.elseBodyNode().compile(merge(o,{indent:this.tab,chainChild:true})):(" else {\n"+(this.elseBody.compile(o))+"\n"+(this.tab)+"}"))};If.prototype.compileExpression=function(o){var code,elsePart,ifPart;this.bodyNode().tags.operation=(this.condition.tags.operation=true);if(this.elseBody){this.elseBodyNode().tags.operation=true}ifPart=this.condition.compile(o)+" ? "+this.bodyNode().compile(o);elsePart=this.elseBody?this.elseBodyNode().compile(o):"undefined";code=(""+ifPart+" : "+elsePart);return this.tags.operation?("("+code+")"):code};return If})();Push={wrap:function(name,expressions){if(expressions.empty()||expressions.containsPureStatement()){return expressions}return Expressions.wrap([new Call(new Value(new Literal(name),[new Accessor(new Literal("push"))]),[expressions.unwrap()])])}};Closure={wrap:function(expressions,statement){var args,call,func,mentionsArgs,meth;if(expressions.containsPureStatement()){return expressions}func=new Parens(new Code([],Expressions.wrap([expressions])));args=[];if((mentionsArgs=expressions.contains(this.literalArgs))||(expressions.contains(this.literalThis))){meth=new Literal(mentionsArgs?"apply":"call");args=[new Literal("this")];if(mentionsArgs){args.push(new Literal("arguments"))}func=new Value(func,[new Accessor(meth)])}call=new Call(func,args);return statement?Expressions.wrap([call]):call},literalArgs:function(node){return node instanceof Literal&&node.value==="arguments"},literalThis:function(node){return node instanceof Literal&&node.value==="this"||node instanceof Code&&node.bound}};UTILITIES={"extends":'function(child, parent) {\n function ctor() { this.constructor = child; }\n ctor.prototype = parent.prototype;\n child.prototype = new ctor;\n if (typeof parent.extended === "function") parent.extended(child);\n child.__super__ = parent.prototype;\n}',bind:"function(func, context) {\n return function() { return func.apply(context, arguments); };\n}",hasProp:"Object.prototype.hasOwnProperty",slice:"Array.prototype.slice"};TAB=" ";TRAILING_WHITESPACE=/[ \t]+$/gm;IDENTIFIER=/^[$A-Za-z_][$\w]*$/;NUMBER=/^0x[\da-f]+|^(?:\d+(\.\d+)?|\.\d+)(?:e[+-]?\d+)?$/i;SIMPLENUM=/^[+-]?\d+$/;IS_STRING=/^['"]/;utility=function(name){var ref;ref=("__"+name);Scope.root.assign(ref,UTILITIES[name]);return ref}}).call(this)};require["./coffee-script"]=new function(){var exports=this;(function(){var Lexer,compile,fs,lexer,parser,path;path=require("path");Lexer=require("./lexer").Lexer;parser=require("./parser").parser;if(require.extensions){fs=require("fs");require.extensions[".coffee"]=function(module,filename){var content;content=compile(fs.readFileSync(filename,"utf8"));return module._compile(content,filename)}}else{if(require.registerExtension){require.registerExtension(".coffee",function(content){return compile(content)})}}exports.VERSION="0.9.4";exports.helpers=require("./helpers");exports.compile=(compile=function(code,options){options||(options={});try{return(parser.parse(lexer.tokenize(code))).compile(options)}catch(err){if(options.fileName){err.message=("In "+(options.fileName)+", "+(err.message))}throw err}});exports.tokens=function(code,options){return lexer.tokenize(code,options)};exports.nodes=function(code,options){return parser.parse(lexer.tokenize(code,options))};exports.run=function(code,options){var root;root=module;while(root.parent){root=root.parent}root.filename=options.fileName;if(root.moduleCache){root.moduleCache={}}return path.extname(root.filename)!==".coffee"||require.extensions?root._compile(exports.compile(code,options),root.filename):root._compile(code,root.filename)};exports.eval=function(code,options){var __dirname,__filename;__filename=options.fileName;__dirname=path.dirname(__filename);return eval(exports.compile(code,options))};lexer=new Lexer;parser.lexer={lex:function(){var token;token=this.tokens[this.pos]||[""];this.pos+=1;this.yylineno=token[2];this.yytext=token[1];return token[0]},setInput:function(tokens){this.tokens=tokens;return(this.pos=0)},upcomingInput:function(){return""}};parser.yy=require("./nodes")}).call(this)};require["./browser"]=new function(){var exports=this;(function(){var CoffeeScript,runScripts;CoffeeScript=require("./coffee-script");CoffeeScript.require=require;CoffeeScript.eval=function(code,options){return eval(CoffeeScript.compile(code,options))};CoffeeScript.run=function(code,options){((options!=null)?(options.bare=true):undefined);return Function(CoffeeScript.compile(code,options))()};if(!(typeof window!=="undefined"&&window!==null)){return}CoffeeScript.load=function(url,options){var xhr;xhr=new (window.ActiveXObject||XMLHttpRequest)("Microsoft.XMLHTTP");xhr.open("GET",url,true);if("overrideMimeType" in xhr){xhr.overrideMimeType("text/plain")}xhr.onreadystatechange=function(){return xhr.readyState===4?CoffeeScript.run(xhr.responseText,options):undefined};return xhr.send(null)};runScripts=function(){var _i,_len,_ref;for(_i=0,_len=(_ref=document.getElementsByTagName("script")).length;_i<_len;_i++){(function(){var script=_ref[_i];return script.type==="text/coffeescript"?(script.src?CoffeeScript.load(script.src):setTimeout(function(){return CoffeeScript.run(script.innerHTML)})):undefined})()}return null};if(window.addEventListener){addEventListener("DOMContentLoaded",runScripts,false)}else{attachEvent("onload",runScripts)}}).call(this)};return require["./coffee-script"]}(); \ No newline at end of file diff --git a/node_modules/jade/support/coffee-script/extras/jsl.conf b/node_modules/jade/support/coffee-script/extras/jsl.conf new file mode 100644 index 0000000..fb41a61 --- /dev/null +++ b/node_modules/jade/support/coffee-script/extras/jsl.conf @@ -0,0 +1,44 @@ +# JavaScriptLint configuration file for CoffeeScript. + ++no_return_value # function {0} does not always return a value ++duplicate_formal # duplicate formal argument {0} +-equal_as_assign # test for equality (==) mistyped as assignment (=)?{0} ++var_hides_arg # variable {0} hides argument ++redeclared_var # redeclaration of {0} {1} +-anon_no_return_value # anonymous function does not always return a value ++missing_semicolon # missing semicolon ++meaningless_block # meaningless block; curly braces have no impact +-comma_separated_stmts # multiple statements separated by commas (use semicolons?) ++unreachable_code # unreachable code ++missing_break # missing break statement ++missing_break_for_last_case # missing break statement for last case in switch +-comparison_type_conv # comparisons against null, 0, true, false, or an empty string allowing implicit type conversion (use === or !==) +-inc_dec_within_stmt # increment (++) and decrement (--) operators used as part of greater statement ++useless_void # use of the void type may be unnecessary (void is always undefined) ++multiple_plus_minus # unknown order of operations for successive plus (e.g. x+++y) or minus (e.g. x---y) signs ++use_of_label # use of label +-block_without_braces # block statement without curly braces ++leading_decimal_point # leading decimal point may indicate a number or an object member ++trailing_decimal_point # trailing decimal point may indicate a number or an object member ++octal_number # leading zeros make an octal number ++nested_comment # nested comment ++misplaced_regex # regular expressions should be preceded by a left parenthesis, assignment, colon, or comma ++ambiguous_newline # unexpected end of line; it is ambiguous whether these lines are part of the same statement ++empty_statement # empty statement or extra semicolon +-missing_option_explicit # the "option explicit" control comment is missing ++partial_option_explicit # the "option explicit" control comment, if used, must be in the first script tag ++dup_option_explicit # duplicate "option explicit" control comment ++useless_assign # useless assignment ++ambiguous_nested_stmt # block statements containing block statements should use curly braces to resolve ambiguity ++ambiguous_else_stmt # the else statement could be matched with one of multiple if statements (use curly braces to indicate intent) +-missing_default_case # missing default case in switch statement ++duplicate_case_in_switch # duplicate case in switch statements ++default_not_at_end # the default case is not at the end of the switch statement ++legacy_cc_not_understood # couldn't understand control comment using /*@keyword@*/ syntax ++jsl_cc_not_understood # couldn't understand control comment using /*jsl:keyword*/ syntax ++useless_comparison # useless comparison; comparing identical expressions ++with_statement # with statement hides undeclared variables; use temporary variable instead ++trailing_comma_in_array # extra comma is not recommended in array initializers ++assign_to_function_call # assignment to a function call ++parseint_missing_radix # parseInt missing radix parameter ++lambda_assign_requires_semicolon diff --git a/node_modules/jade/support/coffee-script/index.html b/node_modules/jade/support/coffee-script/index.html new file mode 100644 index 0000000..5b28b8b --- /dev/null +++ b/node_modules/jade/support/coffee-script/index.html @@ -0,0 +1,2225 @@ + + + + + + + + CoffeeScript + + + + + + +
    + + + +
    + + +

    + CoffeeScript is a little language that compiles into JavaScript. Think + of it as JavaScript's less ostentatious kid brother — the same genes, + roughly the same height, but a different sense of style. Apart from a handful of + bonus goodies, statements in CoffeeScript correspond one-to-one with their + equivalent in JavaScript, it's just another way of saying it. +

    + +

    + Disclaimer: + CoffeeScript is just for fun. Until it reaches 1.0, there are no guarantees + that the syntax won't change between versions. That said, + it compiles into clean JavaScript (the good parts) that can use existing + JavaScript libraries seamlessly, and passes through + JSLint without warnings. The compiled + output is pretty-printed and quite readable. +

    + +

    + Latest Version: + 0.9.4 +

    + +

    + + Mini Overview +

    + +

    CoffeeScript on the left, compiled JavaScript output on the right.

    + +
    # Assignment:
    +number   = 42
    +opposite = true
    +
    +# Conditions:
    +number = -42 if opposite
    +
    +# Functions:
    +square = (x) -> x * x
    +
    +# Arrays:
    +list = [1, 2, 3, 4, 5]
    +
    +# Objects:
    +math =
    +  root:   Math.sqrt
    +  square: square
    +  cube:   (x) -> x * square x
    +
    +# Splats:
    +race = (winner, runners...) ->
    +  print winner, runners
    +
    +# Existence:
    +alert "I knew it!" if elvis?
    +
    +# Array comprehensions:
    +cubes = math.cube num for num in list
    +
    var _i, _len, _result, cubes, list, math, num, number, opposite, race, square;
    +var __slice = Array.prototype.slice;
    +number = 42;
    +opposite = true;
    +if (opposite) {
    +  number = -42;
    +}
    +square = function(x) {
    +  return x * x;
    +};
    +list = [1, 2, 3, 4, 5];
    +math = {
    +  root: Math.sqrt,
    +  square: square,
    +  cube: function(x) {
    +    return x * square(x);
    +  }
    +};
    +race = function(winner) {
    +  var runners;
    +  runners = __slice.call(arguments, 1);
    +  return print(winner, runners);
    +};
    +if (typeof elvis !== "undefined" && elvis !== null) {
    +  alert("I knew it!");
    +}
    +cubes = (function() {
    +  _result = [];
    +  for (_i = 0, _len = list.length; _i < _len; _i++) {
    +    num = list[_i];
    +    _result.push(math.cube(num));
    +  }
    +  return _result;
    +})();
    +

    + +

    + For a longer CoffeeScript example, check out + Underscore.coffee, a port + of the Underscore.js + library of helper functions. Underscore.coffee can pass the entire Underscore.js + test suite. The CoffeeScript version is faster than the original for a number + of methods (in general, due to the speed of CoffeeScript's array comprehensions), and + after being minified and gzipped, is only 241 bytes larger than the original + JavaScript version. + Additional examples are included in the source repository, inside the + examples folder. +

    + +

    + + Installation and Usage +

    + +

    + The CoffeeScript compiler is written in pure CoffeeScript, using a + small DSL + on top of the Jison parser generator, and is available + as a Node.js utility. The core compiler however, + does not depend on Node, and can be run in other server-side-JavaScript environments, + or in the browser (see "Try CoffeeScript", above). +

    + +

    + To install, first make sure you have a working copy of the latest tagged version of + Node.js, currently 0.1.102 or higher. + Then clone the CoffeeScript + source repository + from GitHub, or download the latest + release: 0.9.4. + To install the CoffeeScript compiler system-wide + under /usr/local, open the directory and run: +

    + +
    +sudo bin/cake install
    + +

    + Alternatively, if you already have the + Node Package Manager installed, + you can use that to grab the latest CoffeeScript: +

    + +
    +sudo npm install coffee-script
    + +

    + Both of these provide the coffee command, which will execute CoffeeScripts + under Node.js by default, but is also used to compile CoffeeScript + .coffee files into JavaScript, or to run an an interactive REPL. + When compiling to JavaScript, coffee writes the output + as .js files in the same directory by default, but output + can be customized with the following options: +

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    -c, --compile + Compile a .coffee script into a .js JavaScript file + of the same name. +
    -i, --interactive + Launch an interactive CoffeeScript session to try short snippets. + More pleasant if wrapped with + rlwrap. +
    -o, --output [DIR] + Write out all compiled JavaScript files into the specified directory. + Use in conjunction with --compile or --watch. +
    -w, --watch + Watch the modification times of the coffee-scripts, recompiling as + soon as a change occurs. +
    -p, --print + Instead of writing out the JavaScript as a file, print it + directly to stdout. +
    -l, --lint + If the jsl + (JavaScript Lint) + command is installed, use it + to check the compilation of a CoffeeScript file. (Handy in + conjunction with
    --watch) +
    -s, --stdio + Pipe in CoffeeScript to STDIN and get back JavaScript over STDOUT. + Good for use with processes written in other languages. An example:
    + cat src/cake.coffee | coffee -sc +
    -e, --eval + Compile and print a little snippet of CoffeeScript directly from the + command line. For example:
    coffee -e "puts num for num in [10..1]" +
    -r, --require + Load a library before compiling or executing your script. Can be used + to hook in to the compiler (to add Growl notifications, for example). +
    -b, --bare + Compile the JavaScript without the top-level function safety wrapper. + (Used for CoffeeScript as a Node.js module.) +
    -t, --tokens + Instead of parsing the CoffeeScript, just lex it, and print out the + token stream: [IDENTIFIER square] [ASSIGN =] [PARAM_START (] ... +
    -n, --nodes + Instead of compiling the CoffeeScript, just lex and parse it, and print + out the parse tree: +
    +Expressions
    +  Assign
    +    Value "square"
    +    Code "x"
    +      Op *
    +        Value "x"
    +        Value "x"
    +
    + +

    + Examples: +

    + +
    +coffee -c path/to/script.coffee
    +coffee --interactive
    +coffee --watch --lint experimental.coffee
    +coffee --print app/scripts/*.coffee > concatenation.js
    + +

    + + Language Reference +

    + +

    + + This reference is structured so that it can be read from top to bottom, + if you like. Later sections use ideas and syntax previously introduced. + Familiarity with JavaScript is assumed. + In all of the following examples, the source CoffeeScript is provided on + the left, and the direct compilation into JavaScript is on the right. + +

    + +

    + + Many of the examples can be run (where it makes sense) by pressing the "run" + button towards the bottom right. You can also paste examples into + "Try CoffeeScript" in the toolbar, and play with them from there. + +

    + + Significant Whitespace + CoffeeScript uses Python-style significant whitespace: You don't need to + use semicolons ; to terminate expressions, ending + the line will do just as well. Semicolons can still be used to fit + multiple expressions onto a single line. Instead of using curly braces + { } to delimit blocks of code (like functions, + if-statements, + switch, and try/catch), + use indentation. +

    + +

    + You don't need to use parentheses to invoke a function if you're passing + arguments:
    print "coffee". Implicit parentheses wrap forwards + to the end of the line, or block expression. +

    + +

    + You can use newlines to break up your expression into smaller pieces, + as long as CoffeeScript can determine that the line hasn't finished yet, + because it ends with an operator or a dot ... seen most commonly + in jQuery-chaining style JavaScript. +

    + +

    + + Functions and Invocation + Functions are defined by a list of parameters, an arrow, and the + function body. The empty function looks like this: -> +

    +
    square = (x) -> x * x
    +cube   = (x) -> square(x) * x
    +
    var cube, square;
    +square = function(x) {
    +  return x * x;
    +};
    +cube = function(x) {
    +  return square(x) * x;
    +};
    +

    + +

    + + Objects and Arrays + Object and Array literals look very similar to their JavaScript cousins. + When you spread out each property on a separate line, the commas are + optional. Implicit objects may be created with indentation instead of + brackets, winding up looking quite similar to YAML. +

    +
    song = ["do", "re", "mi", "fa", "so"]
    +
    +singers = {Jagger: "Rock", Elvis: "Roll"}
    +
    +matrix = [
    +  1, 0, 1
    +  0, 0, 1
    +  1, 1, 0
    +]
    +
    +kids =
    +  brother:
    +    name: "Max"
    +    age:  11
    +  sister:
    +    name: "Ida"
    +    age:  9
    +
    var kids, matrix, singers, song;
    +song = ["do", "re", "mi", "fa", "so"];
    +singers = {
    +  Jagger: "Rock",
    +  Elvis: "Roll"
    +};
    +matrix = [1, 0, 1, 0, 0, 1, 1, 1, 0];
    +kids = {
    +  brother: {
    +    name: "Max",
    +    age: 11
    +  },
    +  sister: {
    +    name: "Ida",
    +    age: 9
    +  }
    +};
    +

    +

    + In JavaScript, you can't use reserved words, like class, as properties + of an object, without quoting them as strings. CoffeeScript notices and quotes + them for you, so you don't have to worry about it (say, when using jQuery). +

    +
    $('.account').css class: 'active'
    +
    $('.account').css({
    +  "class": 'active'
    +});
    +

    + +

    + + Lexical Scoping and Variable Safety + The CoffeeScript compiler takes care to make sure that all of your variables + are properly declared within lexical scope — you never need to write + var yourself. +

    +
    outer = 1
    +changeNumbers = ->
    +  inner = -1
    +  outer = 10
    +inner = changeNumbers()
    +
    var changeNumbers, inner, outer;
    +outer = 1;
    +changeNumbers = function() {
    +  var inner;
    +  inner = -1;
    +  return (outer = 10);
    +};
    +inner = changeNumbers();
    +

    +

    + Notice how all of the variable declarations have been pushed up to + the top of the closest scope, the first time they appear. + outer is not redeclared within the inner function, because it's + already in scope; inner within the function, on the other hand, + should not be able to change the value of the external variable of the same name, and + therefore has a declaration of its own. +

    +

    + This behavior is effectively identical to Ruby's scope for local variables. + Because you don't have direct access to the var keyword, + it's impossible to shadow an outer variable on purpose, you may only refer + to it. So be careful that you're not reusing the name of an external + variable accidentally, if you're writing a deeply nested function. +

    +

    + Although suppressed within this documentation for clarity, all + CoffeeScript output is wrapped in an anonymous function: + (function(){ ... })(); This safety wrapper, combined with the + automatic generation of the var keyword, make it exceedingly difficult + to pollute the global namespace by accident. +

    +

    + If you'd like to create top-level variables for other scripts to use, + attach them as properties on window, or on the exports + object in CommonJS. The existential operator (covered below), gives you a + reliable way to figure out where to add them, if you're targeting both + CommonJS and the browser: root = exports ? this +

    + +

    + + If, Else, Unless, and Conditional Assignment + If/else statements can be written without the use of parentheses and + curly brackets. As with functions and other block expressions, + multi-line conditionals are delimited by indentation. There's also a handy + postfix form, with the if or unless at the end. +

    +

    + CoffeeScript can compile if statements into JavaScript expressions, + using the ternary operator when possible, and closure wrapping otherwise. There + is no explicit ternary statement in CoffeeScript — you simply use + a regular if statement inline. +

    +
    mood = greatlyImproved if singing
    +
    +if happy and knowsIt
    +  clapsHands()
    +  chaChaCha()
    +else
    +  showIt()
    +
    +date = if friday then sue else jill
    +
    +options or= defaults
    +
    var date, mood, options;
    +if (singing) {
    +  mood = greatlyImproved;
    +}
    +if (happy && knowsIt) {
    +  clapsHands();
    +  chaChaCha();
    +} else {
    +  showIt();
    +}
    +date = friday ? sue : jill;
    +options || (options = defaults);
    +

    + +

    + + Aliases + Because the == operator frequently causes undesirable coercion, + is intransitive, and has a different meaning than in other languages, + CoffeeScript compiles == into ===, and != into + !==. + In addition, is compiles into ===, + and isnt into !==. +

    +

    + You can use not as an alias for !. +

    +

    + For logic, and compiles to &&, and or + into ||. +

    +

    + Instead of a newline or semicolon, then can be used to separate + conditions from expressions, in while, + if/else, and switch/when statements. +

    +

    + As in YAML, on and yes + are the same as boolean true, while off and no are boolean false. +

    +

    + For single-line statements, unless can be used as the inverse of if. +

    +

    + As a shortcut for this.property, you can use @property. +

    +

    + You can use in to test for array presence, and of to + test for JavaScript object-key presence. +

    +
    launch() if ignition is on
    +
    +volume = 10 if band isnt SpinalTap
    +
    +letTheWildRumpusBegin() unless answer is no
    +
    +if car.speed < limit then accelerate()
    +
    +winner = yes if pick in [47, 92, 13]
    +
    +print inspect "My name is " + @name
    +
    var volume, winner;
    +if (ignition === true) {
    +  launch();
    +}
    +if (band !== SpinalTap) {
    +  volume = 10;
    +}
    +if (answer !== false) {
    +  letTheWildRumpusBegin();
    +}
    +if (car.speed < limit) {
    +  accelerate();
    +}
    +if ((47 === pick || 92 === pick || 13 === pick)) {
    +  winner = true;
    +}
    +print(inspect("My name is " + this.name));
    +

    + +

    + + Splats... + The JavaScript arguments object is a useful way to work with + functions that accept variable numbers of arguments. CoffeeScript provides + splats ..., both for function definition as well as invocation, + making variable numbers of arguments a little bit more palatable. +

    +
    gold = silver = rest = "unknown"
    +
    +awardMedals = (first, second, others...) ->
    +  gold   = first
    +  silver = second
    +  rest   = others
    +
    +contenders = [
    +  "Michael Phelps"
    +  "Liu Xiang"
    +  "Yao Ming"
    +  "Allyson Felix"
    +  "Shawn Johnson"
    +  "Roman Sebrle"
    +  "Guo Jingjing"
    +  "Tyson Gay"
    +  "Asafa Powell"
    +  "Usain Bolt"
    +]
    +
    +awardMedals contenders...
    +
    +alert "Gold: " + gold
    +alert "Silver: " + silver
    +alert "The Field: " + rest
    +
    var awardMedals, contenders, gold, rest, silver;
    +var __slice = Array.prototype.slice;
    +gold = (silver = (rest = "unknown"));
    +awardMedals = function(first, second) {
    +  var others;
    +  others = __slice.call(arguments, 2);
    +  gold = first;
    +  silver = second;
    +  return (rest = others);
    +};
    +contenders = ["Michael Phelps", "Liu Xiang", "Yao Ming", "Allyson Felix", "Shawn Johnson", "Roman Sebrle", "Guo Jingjing", "Tyson Gay", "Asafa Powell", "Usain Bolt"];
    +awardMedals.apply(awardMedals, contenders);
    +alert("Gold: " + gold);
    +alert("Silver: " + silver);
    +alert("The Field: " + rest);
    +

    + +

    + + While, Until, and Loop + The only low-level loop that CoffeeScript provides is the while loop. The + main difference from JavaScript is that the while loop can be used + as an expression, returning an array containing the result of each iteration + through the loop. +

    +
    # Econ 101
    +if this.studyingEconomics
    +  buy()  while supply > demand
    +  sell() until supply > demand
    +
    +# Nursery Rhyme
    +num = 6
    +lyrics = while num -= 1
    +  num + " little monkeys, jumping on the bed.
    +    One fell out and bumped his head."
    +
    var _result, lyrics, num;
    +if (this.studyingEconomics) {
    +  while (supply > demand) {
    +    buy();
    +  }
    +  while (!(supply > demand)) {
    +    sell();
    +  }
    +}
    +num = 6;
    +lyrics = (function() {
    +  _result = [];
    +  while (num -= 1) {
    +    _result.push(num + " little monkeys, jumping on the bed.    One fell out and bumped his head.");
    +  }
    +  return _result;
    +})();
    +

    +

    + For readability, the until keyword is equivalent to while not, + and the loop keyword is equivalent to while true. + Other JavaScript loops, such as for loops and do-while loops + can be mimicked by variations on loop, but the hope is that you + won't need to do that with CoffeeScript, either because you're using + each (forEach) style iterators, or... +

    + +

    + + Comprehensions (Arrays, Objects, and Ranges) + For your looping needs, CoffeeScript provides array comprehensions + similar to Python's. They replace (and compile into) for loops, with + optional guard clauses and the value of the current array index. + Unlike for loops, array comprehensions are expressions, and can be returned + and assigned. They should be able to handle most places where you otherwise + would use a loop, each/forEach, map, or select/filter. +

    +
    # Eat lunch.
    +lunch = eat food for food in ['toast', 'cheese', 'wine']
    +
    +# Naive collision detection.
    +for roid, pos in asteroids
    +  for roid2 in asteroids when roid isnt roid2
    +    roid.explode() if roid.overlaps roid2
    +
    var _i, _len, _len2, _ref, _result, food, lunch, pos, roid, roid2;
    +lunch = (function() {
    +  _result = []; _ref = ['toast', 'cheese', 'wine'];
    +  for (_i = 0, _len = _ref.length; _i < _len; _i++) {
    +    food = _ref[_i];
    +    _result.push(eat(food));
    +  }
    +  return _result;
    +})();
    +for (pos = 0, _len = asteroids.length; pos < _len; pos++) {
    +  roid = asteroids[pos];
    +  for (_i = 0, _len2 = asteroids.length; _i < _len2; _i++) {
    +    roid2 = asteroids[_i];
    +    if (roid !== roid2) {
    +      if (roid.overlaps(roid2)) {
    +        roid.explode();
    +      }
    +    }
    +  }
    +}
    +

    +

    + If you know the start and end of your loop, or would like to step through + in fixed-size increments, you can use a range to specify the start and + end of your comprehension. +

    +
    countdown = num for num in [10..1]
    +
    +deliverEggs = ->
    +  for i in [0...eggs.length] by 12
    +    dozen = eggs[i...i+12]
    +    deliver new eggCarton dozen
    +
    var _result, countdown, deliverEggs, num;
    +countdown = (function() {
    +  _result = [];
    +  for (num = 10; num >= 1; num--) {
    +    _result.push(num);
    +  }
    +  return _result;
    +})();
    +deliverEggs = function() {
    +  var _ref, _result2, dozen, i;
    +  _result2 = []; _ref = eggs.length;
    +  for (i = 0; (0 <= _ref ? i < _ref : i > _ref); i += 12) {
    +    _result2.push((function() {
    +      dozen = eggs.slice(i, i + 12);
    +      return deliver(new eggCarton(dozen));
    +    })());
    +  }
    +  return _result2;
    +};
    +

    +

    + Comprehensions can also be used to iterate over the keys and values in + an object. Use of to signal comprehension over the properties of + an object instead of the values in an array. +

    +
    yearsOld = max: 10, ida: 9, tim: 11
    +
    +ages = for child, age of yearsOld
    +  child + " is " + age
    +
    var _result, age, ages, child, yearsOld;
    +var __hasProp = Object.prototype.hasOwnProperty;
    +yearsOld = {
    +  max: 10,
    +  ida: 9,
    +  tim: 11
    +};
    +ages = (function() {
    +  _result = [];
    +  for (child in yearsOld) {
    +    if (!__hasProp.call(yearsOld, child)) continue;
    +    age = yearsOld[child];
    +    _result.push(child + " is " + age);
    +  }
    +  return _result;
    +})();
    +

    +

    + By default, object comprehensions are safe, and use a hasOwnProperty + check to make sure that you're dealing with properties on the current + object. If you'd like the regular JavaScript
    for (key in obj) ... + loop, for speed or for another reason, you can use
    + for all key, value of object in CoffeeScript. +

    + +

    + + Array Slicing and Splicing with Ranges + CoffeeScript borrows Ruby's + range syntax + for extracting slices of arrays. With two dots (3..5), the range + is inclusive: the first argument is the index of the first element in + the slice, and the second is the index of the last one. Three dots signify + a range that excludes the end. +

    +
    numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
    +
    +threeToSix = numbers[3..6]
    +
    +copy = numbers[0...numbers.length]
    +
    +
    var copy, numbers, threeToSix;
    +numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
    +threeToSix = numbers.slice(3, 6 + 1);
    +copy = numbers.slice(0, numbers.length);
    +

    +

    + The same syntax can be used with assignment to replace a segment of an + array with new values (to splice it). +

    +
    numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
    +
    +numbers[3..6] = [-3, -4, -5, -6]
    +
    +
    +
    var _ref, numbers;
    +numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
    +([].splice.apply(numbers, [3, 6 - 3 + 1].concat(_ref = [-3, -4, -5, -6])), _ref);
    +

    + +

    + + Everything is an Expression (at least, as much as possible) + You might have noticed how even though we don't add return statements + to CoffeeScript functions, they nonetheless return their final value. + The CoffeeScript compiler tries to make sure that all statements in the + language can be used as expressions. Watch how the return gets + pushed down into each possible branch of execution, in the function + below. +

    +
    grade = (student) ->
    +  if student.excellentWork
    +    "A+"
    +  else if student.okayStuff
    +    if student.triedHard then "B" else "B-"
    +  else
    +    "C"
    +
    +eldest = if 24 > 21 then "Liz" else "Ike"
    +
    var eldest, grade;
    +grade = function(student) {
    +  return student.excellentWork ? "A+" : (student.okayStuff ? (student.triedHard ? "B" : "B-") : "C");
    +};
    +eldest = 24 > 21 ? "Liz" : "Ike";
    +

    +

    + Even though functions will always return their final value, it's both possible + and encouraged to return early from a function body writing out the explicit + return (return value), when you know that you're done. +

    +

    + Because variable declarations occur at the top of scope, assignment can + be used within expressions, even for variables that haven't been seen before: +

    +
    six = (one = 1) + (two = 2) + (three = 3)
    +
    var one, six, three, two;
    +six = (one = 1) + (two = 2) + (three = 3);
    +

    +

    + Things that would otherwise be statements in JavaScript, when used + as part of an expression in CoffeeScript, are converted into expressions + by wrapping them in a closure. This lets you do useful things, like assign + the result of a comprehension to a variable: +

    +
    # The first ten global properties.
    +
    +globals = (name for name of window)[0...10]
    +
    var _result, globals, name;
    +var __hasProp = Object.prototype.hasOwnProperty;
    +globals = (function() {
    +  _result = [];
    +  for (name in window) {
    +    if (!__hasProp.call(window, name)) continue;
    +    _result.push(name);
    +  }
    +  return _result;
    +})().slice(0, 10);
    +

    +

    + As well as silly things, like passing a try/catch statement directly + into a function call: +

    +
    alert(
    +  try
    +    nonexistent / undefined
    +  catch error
    +    "And the error is ... " + error
    +)
    +
    alert((function() {
    +  try {
    +    return nonexistent / undefined;
    +  } catch (error) {
    +    return "And the error is ... " + error;
    +  }
    +})());
    +

    +

    + There are a handful of statements in JavaScript that can't be meaningfully + converted into expressions, namely break, continue, + and return. If you make use of them within a block of code, + CoffeeScript won't try to perform the conversion. +

    + +

    + + The Existential Operator + It's a little difficult to check for the existence of a variable in + JavaScript. if (variable) ... comes close, but fails for zero, + the empty string, and false. CoffeeScript's existential operator ? returns true unless + a variable is null or undefined, which makes it analogous + to Ruby's nil? +

    +

    + It can also be used for safer conditional assignment than ||= + provides, for cases where you may be handling numbers or strings. +

    +
    solipsism = true if mind? and not world?
    +
    +speed ?= 140
    +
    +
    +
    +
    +
    +
    var solipsism, speed;
    +if ((typeof mind !== "undefined" && mind !== null) && !(typeof world !== "undefined" && world !== null)) {
    +  solipsism = true;
    +}
    +(typeof speed !== "undefined" && speed !== null) ? speed : (speed = 140);
    +

    +

    + The accessor variant of the existential operator ?. can be used to soak + up null references in a chain of properties. Use it instead + of the dot accessor . in cases where the base value may be null + or undefined. If all of the properties exist then you'll get the expected + result, if the chain is broken, undefined is returned instead of + the TypeError that would be raised otherwise. +

    +
    lottery.drawWinner()?.address?.zipcode
    +
    var _ref, _ref2;
    +(((_ref = lottery.drawWinner()) != null) ? (((_ref2 = _ref.address) != null) ? _ref2.zipcode : undefined) : undefined);
    +

    +

    + Soaking up nulls is similar to Ruby's + andand gem, and to the + safe navigation operator + in Groovy. +

    + +

    + + Classes, Inheritance, and Super + JavaScript's prototypal inheritance has always been a bit of a + brain-bender, with a whole family tree of libraries that provide a cleaner + syntax for classical inheritance on top of JavaScript's prototypes: + Base2, + Prototype.js, + JS.Class, etc. + The libraries provide syntactic sugar, but the built-in inheritance would + be completely usable if it weren't for a couple of small exceptions: + it's awkward to call super (the prototype object's + implementation of the current function), and it's awkward to correctly + set the prototype chain. +

    +

    + Instead of repetitively attaching functions to a prototype, CoffeeScript + provides a basic class structure that allows you to name your class, + set the superclass, assign prototypal properties, and define the constructor, + in a single assignable expression. +

    +
    class Animal
    +  constructor: (@name) ->
    +
    +  move: (meters) ->
    +    alert @name + " moved " + meters + "m."
    +
    +class Snake extends Animal
    +  move: ->
    +    alert "Slithering..."
    +    super 5
    +
    +class Horse extends Animal
    +  move: ->
    +    alert "Galloping..."
    +    super 45
    +
    +sam = new Snake "Sammy the Python"
    +tom = new Horse "Tommy the Palomino"
    +
    +sam.move()
    +tom.move()
    +
    +
    +
    +
    +
    var Animal, Horse, Snake, sam, tom;
    +var __extends = function(child, parent) {
    +  var ctor = function() {};
    +  ctor.prototype = parent.prototype;
    +  child.prototype = new ctor();
    +  child.prototype.constructor = child;
    +  if (typeof parent.extended === "function") parent.extended(child);
    +  child.__super__ = parent.prototype;
    +};
    +Animal = (function() {
    +  return function Animal(_arg) {
    +    this.name = _arg;
    +    return this;
    +  };
    +})();
    +Animal.prototype.move = function(meters) {
    +  return alert(this.name + " moved " + meters + "m.");
    +};
    +Snake = (function() {
    +  return function Snake() {
    +    return Animal.apply(this, arguments);
    +  };
    +})();
    +__extends(Snake, Animal);
    +Snake.prototype.move = function() {
    +  alert("Slithering...");
    +  return Snake.__super__.move.call(this, 5);
    +};
    +Horse = (function() {
    +  return function Horse() {
    +    return Animal.apply(this, arguments);
    +  };
    +})();
    +__extends(Horse, Animal);
    +Horse.prototype.move = function() {
    +  alert("Galloping...");
    +  return Horse.__super__.move.call(this, 45);
    +};
    +sam = new Snake("Sammy the Python");
    +tom = new Horse("Tommy the Palomino");
    +sam.move();
    +tom.move();
    +

    +

    + If structuring your prototypes classically isn't your cup of tea, CoffeeScript + provides a couple of lower-level conveniences. The extends operator + helps with proper prototype setup, :: gives you + quick access to an object's prototype, and super() + is converted into a call against the immediate ancestor's method of the same name. +

    +
    String::dasherize = ->
    +  this.replace /_/g, "-"
    +
    String.prototype.dasherize = function() {
    +  return this.replace(/_/g, "-");
    +};
    +

    +

    + Finally, you may assign Class-level (static) properties within a class + definition by using
    @property: value +

    + +

    + + Pattern Matching (Destructuring Assignment) + To make extracting values from complex arrays and objects more convenient, + CoffeeScript implements ECMAScript Harmony's proposed + destructuring assignment + syntax. When you assign an array or object literal to a value, CoffeeScript + breaks up and matches both sides against each other, assigning the values + on the right to the variables on the left. In the simplest case, it can be + used for parallel assignment: +

    +
    theBait   = 1000
    +theSwitch = 0
    +
    +[theBait, theSwitch] = [theSwitch, theBait]
    +
    var _ref, theBait, theSwitch;
    +theBait = 1000;
    +theSwitch = 0;
    +_ref = [theSwitch, theBait], theBait = _ref[0], theSwitch = _ref[1];
    +

    +

    + But it's also helpful for dealing with functions that return multiple + values. +

    +
    weatherReport = (location) ->
    +  # Make an Ajax request to fetch the weather...
    +  [location, 72, "Mostly Sunny"]
    +
    +[city, temp, forecast] = weatherReport "Berkeley, CA"
    +
    var _ref, city, forecast, temp, weatherReport;
    +weatherReport = function(location) {
    +  return [location, 72, "Mostly Sunny"];
    +};
    +_ref = weatherReport("Berkeley, CA"), city = _ref[0], temp = _ref[1], forecast = _ref[2];
    +

    +

    + Pattern matching can be used with any depth of array and object nesting, + to help pull out deeply nested properties. +

    +
    futurists =
    +  sculptor: "Umberto Boccioni"
    +  painter:  "Vladimir Burliuk"
    +  poet:
    +    name:   "F.T. Marinetti"
    +    address: [
    +      "Via Roma 42R"
    +      "Bellagio, Italy 22021"
    +    ]
    +
    +{poet: {name, address: [street, city]}} = futurists
    +
    var _ref, _ref2, city, futurists, name, street;
    +futurists = {
    +  sculptor: "Umberto Boccioni",
    +  painter: "Vladimir Burliuk",
    +  poet: {
    +    name: "F.T. Marinetti",
    +    address: ["Via Roma 42R", "Bellagio, Italy 22021"]
    +  }
    +};
    +_ref = futurists.poet, name = _ref.name, _ref2 = _ref.address, street = _ref2[0], city = _ref2[1];
    +

    +

    + Pattern matching can even be combined with splats. +

    +
    tag = "<impossible>"
    +
    +[open, contents..., close] = tag.split("")
    +
    +
    +
    +
    +
    var _ref, close, contents, open, tag;
    +var __slice = Array.prototype.slice;
    +tag = "<impossible>";
    +_ref = tag.split(""), open = _ref[0], contents = __slice.call(_ref, 1, _ref.length - 1), close = _ref[_ref.length - 1];
    +

    + +

    + + Function binding + In JavaScript, the this keyword is dynamically scoped to mean the + object that the current function is attached to. If you pass a function as + as callback, or attach it to a different object, the original value of this + will be lost. If you're not familiar with this behavior, + this Digital Web article + gives a good overview of the quirks. +

    +

    + The fat arrow => can be used to both define a function, and to bind + it to the current value of this, right on the spot. This is helpful + when using callback-based libraries like Prototype or jQuery, for creating + iterator functions to pass to each, or event-handler functions + to use with bind. Functions created with the fat arrow are able to access + properties of the this where they're defined. +

    +
    Account = (customer, cart) ->
    +  @customer = customer
    +  @cart = cart
    +
    +  $('.shopping_cart').bind 'click', (event) =>
    +    @customer.purchase @cart
    +
    var Account;
    +var __bind = function(func, context) {
    +  return function() { return func.apply(context, arguments); };
    +};
    +Account = function(customer, cart) {
    +  this.customer = customer;
    +  this.cart = cart;
    +  return $('.shopping_cart').bind('click', __bind(function(event) {
    +    return this.customer.purchase(this.cart);
    +  }, this));
    +};
    +

    +

    + If we had used -> in the callback above, @customer would + have referred to the undefined "customer" property of the DOM element, + and trying to call purchase() on it would have raised an exception. +

    + +

    + + Embedded JavaScript + Hopefully, you'll never need to use it, but if you ever need to intersperse + snippets of JavaScript within your CoffeeScript, you can + use backticks to pass it straight through. +

    +
    hi = `function() {
    +  return [document.title, "Hello JavaScript"].join(": ");
    +}`
    +
    +
    +
    var hi;
    +hi = function() {
    +  return [document.title, "Hello JavaScript"].join(": ");
    +};
    +

    + +

    + + Switch/When/Else + Switch statements in JavaScript are a bit awkward. You need to + remember to break at the end of every case statement to + avoid accidentally falling through to the default case. + CoffeeScript prevents accidental fall-through, and can convert the switch + into a returnable, assignable expression. The format is: switch condition, + when clauses, else the default case. +

    +

    + As in Ruby, switch statements in CoffeeScript can take multiple + values for each when clause. If any of the values match, the clause + runs. +

    +
    switch day
    +  when "Mon" then go work
    +  when "Tue" then go relax
    +  when "Thu" then go iceFishing
    +  when "Fri", "Sat"
    +    if day is bingoDay
    +      go bingo
    +      go dancing
    +  when "Sun" then go church
    +  else go work
    +
    switch (day) {
    +  case "Mon":
    +    go(work);
    +    break;
    +  case "Tue":
    +    go(relax);
    +    break;
    +  case "Thu":
    +    go(iceFishing);
    +    break;
    +  case "Fri":
    +  case "Sat":
    +    if (day === bingoDay) {
    +      go(bingo);
    +      go(dancing);
    +    }
    +    break;
    +  case "Sun":
    +    go(church);
    +    break;
    +  default:
    +    go(work);
    +}
    +

    + +

    + + Try/Catch/Finally + Try/catch statements are just about the same as JavaScript (although + they work as expressions). +

    +
    try
    +  allHellBreaksLoose()
    +  catsAndDogsLivingTogether()
    +catch error
    +  print error
    +finally
    +  cleanUp()
    +
    try {
    +  allHellBreaksLoose();
    +  catsAndDogsLivingTogether();
    +} catch (error) {
    +  print(error);
    +} finally {
    +  cleanUp();
    +}
    +

    + +

    + + Chained Comparisons + CoffeeScript borrows + chained comparisons + from Python — making it easy to test if a value falls within a + certain range. +

    +
    cholesterol = 127
    +
    +healthy = 200 > cholesterol > 60
    +
    +
    +
    var cholesterol, healthy;
    +cholesterol = 127;
    +healthy = (200 > cholesterol) && (cholesterol > 60);
    +

    + +

    + + String and RegExp Interpolation + Ruby-style string interpolation is included in CoffeeScript. Double-quoted + strings allow for interpolated values, while single-quoted strings are literal. +

    +
    author = "Wittgenstein"
    +quote  = "A picture is a fact. -- #{author}"
    +
    var author, quote;
    +author = "Wittgenstein";
    +quote = ("A picture is a fact. -- " + author);
    +

    +

    + And arbitrary expressions can be interpolated by using brackets #{ ... }
    + Interpolation works the same way within regular expressions. +

    +
    sentence = "#{ 22 / 7 } is a decent approximation of π"
    +
    +sep   = "[.\\/\\- ]"
    +dates = /\d+#{sep}\d+#{sep}\d+/g
    +
    +
    +
    var dates, sentence, sep;
    +sentence = ("" + (22 / 7) + " is a decent approximation of π");
    +sep = "[.\\/\\- ]";
    +dates = /\d+#{sep}\d+#{sep}\d+/g;
    +

    + +

    + + Multiline Strings, Heredocs, and Block Comments + Multiline strings are allowed in CoffeeScript. +

    +
    mobyDick = "Call me Ishmael. Some years ago --
    + never mind how long precisely -- having little
    + or no money in my purse, and nothing particular
    + to interest me on shore, I thought I would sail
    + about a little and see the watery part of the
    + world..."
    +
    +
    +
    var mobyDick;
    +mobyDick = "Call me Ishmael. Some years ago -- never mind how long precisely -- having little or no money in my purse, and nothing particular to interest me on shore, I thought I would sail about a little and see the watery part of the world...";
    +

    +

    + Heredocs can be used to hold formatted or indentation-sensitive text + (or, if you just don't feel like escaping quotes and apostrophes). The + indentation level that begins the heredoc is maintained throughout, so + you can keep it all aligned with the body of your code. +

    +
    html = '''
    +       <strong>
    +         cup of coffeescript
    +       </strong>
    +       '''
    +
    var html;
    +html = '<strong>\n  cup of coffeescript\n</strong>';
    +

    +

    + Double-quoted heredocs, like double-quoted strings, allow interpolation. +

    +

    + Sometimes you'd like to pass a block comment through to the generated + JavaScript. For example, when you need to embed a licensing header at + the top of a file. Block comments, which mirror the syntax for heredocs, + are preserved in the generated code. +

    +
    ###
    +CoffeeScript Compiler v0.9.4
    +Released under the MIT License
    +###
    +
    /*
    +CoffeeScript Compiler v0.9.4
    +Released under the MIT License
    +*/
    +

    + +

    + + Cake, and Cakefiles +

    + +

    + CoffeeScript includes a simple build system similar to + Make and + Rake. Naturally, + it's called Cake, and is used for the build and test tasks for the CoffeeScript + language itself. Tasks are defined in a file named Cakefile, and + can be invoked by running cake taskname from within the directory. + To print a list of all the tasks and options, just run cake. +

    + +

    + Task definitions are written in CoffeeScript, so you can put arbitrary code + in your Cakefile. Define a task with a name, a long description, and the + function to invoke when the task is run. If your task takes a command-line + option, you can define the option with short and long flags, and it will + be made available in the options object. Here's a task that uses + the Node.js API to rebuild CoffeeScript's parser: +

    +
    fs = require 'fs'
    +
    +option '-o', '--output [DIR]', 'directory for compiled code'
    +
    +task 'build:parser', 'rebuild the Jison parser', (options) ->
    +  require 'jison'
    +  code = require('./lib/grammar').parser.generate()
    +  dir  = options.output or 'lib'
    +  fs.writeFile "#{dir}/parser.js", code
    +
    var fs;
    +fs = require('fs');
    +option('-o', '--output [DIR]', 'directory for compiled code');
    +task('build:parser', 'rebuild the Jison parser', function(options) {
    +  var code, dir;
    +  require('jison');
    +  code = require('./lib/grammar').parser.generate();
    +  dir = options.output || 'lib';
    +  return fs.writeFile("" + dir + "/parser.js", code);
    +});
    +

    +

    + If you need to invoke one task before another — for example, running + build before test, you can use the invoke function: + invoke 'build' +

    + +

    + + "text/coffeescript" Script Tags +

    + +

    + While it's not recommended for serious use, CoffeeScripts may be included + directly within the browser using <script type="text/coffeescript"> + tags. The source includes a compressed and minified version of the compiler + (Download current version here, 43k when gzipped) + as extras/coffee-script.js. Include this file on a page with + inline CoffeeScript tags, and it will compile and evaluate them in order. +

    + +

    + In fact, the little bit of glue script that runs "Try CoffeeScript" above, + as well as jQuery for the menu, is implemented in just this way. + View source and look at the bottom of the page to see the example. + Including the script also gives you access to CoffeeScript.compile() + so you can pop open Firebug and try compiling some strings. +

    + +

    + The usual caveats about CoffeeScript apply — your inline scripts will + run within a closure wrapper, so if you want to expose global variables or + functions, attach them to the window object. +

    + +

    + + Resources +

    + +
      +
    • + Source Code
      + Use bin/coffee to test your changes,
      + bin/cake test to run the test suite,
      + bin/cake build to rebuild the CoffeeScript compiler, and
      + bin/cake build:parser to regenerate the Jison parser if you're + working on the grammar.

      + git checkout lib && bin/cake build:full is a good command to run when you're working + on the core language. It'll refresh the lib directory + (in case you broke something), build your altered compiler, use that to + rebuild itself (a good sanity test) and then run all of the tests. If + they pass, there's a good chance you've made a successful change. +
    • +
    • + CoffeeScript Issues
      + Bugs reports, feature requests, and general discussion all belong here. +
    • +
    • + If you'd like to chat, stop by #coffeescript on Freenode in the + IRC client of your choice, or on + webchat.freenode.net. +
    • +
    • + yeungda's JCoffeeScript + — A Java Library that uses Rhino to compile CoffeeScript, allowing + compilation within Java projects or on systems that Node.js doesn't support. +
    • +
    • + defunkt's CoffeeScript Major Mode + — a Emacs major mode that provides syntax highlighting, indentation + support, and some bonus commands. +
    • +
    • + jashkenas's CoffeeScript TextMate Bundle + — which provides syntax highlighting, snippet expansion, and the + ability to run bits of CoffeeScript from within TextMate itself. +
    • +
    • + kchmck's Vim CoffeeScript + — which adds Vim syntax highlighting and indentation support. +
    • +
    • + wavded's gedit-coffeescript + — a CoffeeScript syntax highlighter for the gedit text editor. +
    • +
    • + yeungda's coffeescript-idea + — a plugin for IntelliJ IDEA and RubyMine providing syntax highlighting. +
    • +
    • + mattly's rack-coffee + — a small Rack middleware for serving CoffeeScript files as + compiled JavaScript on the fly. +
    • +
    • + jnicklas's BistroCar + — a plugin that serves and bundles CoffeeScript from within your + Rails application. +
    • +
    • + dsc's CoffeeCup + — a Python WSGI middleware that compiles CoffeeScript to JavaScript + on-demand during development. +
    • +
    • + sutto's Barista + — a BistroCar alternative that integrates well with + Jammit and Rails 3. +
    • +
    • + inem and gerad's coffee-haml-filter + — a custom filter for rendering CoffeeScript inline within + HAML templates. +
    • +
    • + chrislloyd's Roast + — a CoffeeScript compiler plug-in that allows you to include external + source files. +
    • +
    • + mauricemach's CoffeeKup + — Markup as CoffeeScript. After _why's + Markaby. +
    • +
    • + jashkenas's Docco + — a quick-and-dirty literate-programming-style documentation generator + for CoffeeScript. Used to produce the annotated source. +
    • +
    + +

    + + Web Chat (IRC) +

    + +

    + Quick help and advice can usually be found in the CoffeeScript IRC room. + Join #coffeescript on irc.freenode.net, or click the + button below to open a webchat session on this page. +

    + +

    + +

    + +

    + + Change Log +

    + +

    + 0.9.4 + CoffeeScript now uses appropriately-named temporary variables, and recycles + their references after use. Added require.extensions support for + Node.js 0.3. Loading CoffeeScript in the browser now adds just a + single CoffeeScript object to global scope. + Fixes for implicit object and block comment edge cases. +

    + +

    + 0.9.3 + CoffeeScript switch statements now compile into JS switch + statements — they previously compiled into if/else chains + for JavaScript 1.3 compatibility. + Soaking a function invocation is now supported. Users of the RubyMine + editor should now be able to use --watch mode. +

    + +

    + 0.9.2 + Specifying the start and end of a range literal is now optional, eg. array[3..]. + You can now say a not instanceof b. + Fixed important bugs with nested significant and non-significant indentation (Issue #637). + Added a --require flag that allows you to hook into the coffee command. + Added a custom jsl.conf file for our preferred JavaScriptLint setup. + Sped up Jison grammar compilation time by flattening rules for operations. + Block comments can now be used with JavaScript-minifier-friendly syntax. + Added JavaScript's compound assignment bitwise operators. Bugfixes to + implicit object literals with leading number and string keys, as the subject + of implicit calls, and as part of compound assignment. +

    + +

    + 0.9.1 + Bugfix release for 0.9.1. Greatly improves the handling of mixed + implicit objects, implicit function calls, and implicit indentation. + String and regex interpolation is now strictly #{ ... } (Ruby style). + The compiler now takes a --require flag, which specifies scripts + to run before compilation. +

    + +

    + 0.9.0 + The CoffeeScript 0.9 series is considered to be a release candidate + for 1.0; let's give her a shakedown cruise. 0.9.0 introduces a massive + backwards-incompatible change: Assignment now uses =, and object + literals use :, as in JavaScript. This allows us to have implicit + object literals, and YAML-style object definitions. Half assignments are + removed, in favor of +=, or=, and friends. + Interpolation now uses a hash mark # instead of the dollar sign + $ — because dollar signs may be part of a valid JS identifier. + Downwards range comprehensions are now safe again, and are optimized to + straight for loops when created with integer endpoints. + A fast, unguarded form of object comprehension was added: + for all key, value of object. Mentioning the super keyword + with no arguments now forwards all arguments passed to the function, + as in Ruby. If you extend class B from parent class A, if + A has an extended method defined, it will be called, passing in B — + this enables static inheritance, among other things. Cleaner output for + functions bound with the fat arrow. @variables can now be used + in parameter lists, with the parameter being automatically set as a property + on the object — useful in constructors and setter functions. + Constructor functions can now take splats. +

    + +

    + 0.7.2 + Quick bugfix (right after 0.7.1) for a problem that prevented coffee + command-line options from being parsed in some circumstances. +

    + +

    + 0.7.1 + Block-style comments are now passed through and printed as JavaScript block + comments -- making them useful for licenses and copyright headers. Better + support for running coffee scripts standalone via hashbangs. + Improved syntax errors for tokens that are not in the grammar. +

    + +

    + 0.7.0 + Official CoffeeScript variable style is now camelCase, as in JavaScript. + Reserved words are now allowed as object keys, and will be quoted for you. + Range comprehensions now generate cleaner code, but you have to specify by -1 + if you'd like to iterate downward. Reporting of syntax errors is greatly + improved from the previous release. Running coffee with no arguments + now launches the REPL, with Readline support. The <- bind operator + has been removed from CoffeeScript. The loop keyword was added, + which is equivalent to a while true loop. Comprehensions that contain + closures will now close over their variables, like the semantics of a forEach. + You can now use bound function in class definitions (bound to the instance). + For consistency, a in b is now an array presence check, and a of b + is an object-key check. Comments are no longer passed through to the generated + JavaScript. +

    + +

    + 0.6.2 + The coffee command will now preserve directory structure when + compiling a directory full of scripts. Fixed two omissions that were preventing + the CoffeeScript compiler from running live within Internet Explorer. + There's now a syntax for block comments, similar in spirit to CoffeeScript's heredocs. + ECMA Harmony DRY-style pattern matching is now supported, where the name + of the property is the same as the name of the value: {name, length}: func. + Pattern matching is now allowed within comprehension variables. unless + is now allowed in block form. until loops were added, as the inverse + of while loops. switch statements are now allowed without + switch object clauses. Compatible + with Node.js v0.1.95. +

    + +

    + 0.6.1 + Upgraded CoffeeScript for compatibility with the new Node.js v0.1.90 + series. +

    + +

    + 0.6.0 + Trailing commas are now allowed, a-la Python. Static + properties may be assigned directly within class definitions, + using @property notation. +

    + +

    + 0.5.6 + Interpolation can now be used within regular expressions and heredocs, as well as + strings. Added the <- bind operator. + Allowing assignment to half-expressions instead of special ||=-style + operators. The arguments object is no longer automatically converted into + an array. After requiring coffee-script, Node.js can now directly + load .coffee files, thanks to registerExtension. Multiple + splats can now be used in function calls, arrays, and pattern matching. +

    + +

    + 0.5.5 + String interpolation, contributed by + Stan Angeloff. + Since --run has been the default since 0.5.3, updating + --stdio and --eval to run by default, pass --compile + as well if you'd like to print the result. +

    + +

    + 0.5.4 + Bugfix that corrects the Node.js global constants __filename and + __dirname. Tweaks for more flexible parsing of nested function + literals and improperly-indented comments. Updates for the latest Node.js API. +

    + +

    + 0.5.3 + CoffeeScript now has a syntax for defining classes. Many of the core + components (Nodes, Lexer, Rewriter, Scope, Optparse) are using them. + Cakefiles can use optparse.coffee to define options for tasks. + --run is now the default flag for the coffee command, + use --compile to save JavaScripts. Bugfix for an ambiguity between + RegExp literals and chained divisions. +

    + +

    + 0.5.2 + Added a compressed version of the compiler for inclusion in web pages as +
    extras/coffee-script.js. It'll automatically run any script tags + with type text/coffeescript for you. Added a --stdio option + to the coffee command, for piped-in compiles. +

    + + +

    + 0.5.1 + Improvements to null soaking with the existential operator, including + soaks on indexed properties. Added conditions to while loops, + so you can use them as filters with when, in the same manner as + comprehensions. +

    + +

    + 0.5.0 + CoffeeScript 0.5.0 is a major release, While there are no language changes, + the Ruby compiler has been removed in favor of a self-hosting + compiler written in pure CoffeeScript. +

    + +

    + 0.3.2 + @property is now a shorthand for this.property.
    + Switched the default JavaScript engine from Narwhal to Node.js. Pass + the --narwhal flag if you'd like to continue using it. +

    + +

    + 0.3.0 + CoffeeScript 0.3 includes major syntax changes: +
    + The function symbol was changed to + ->, and the bound function symbol is now =>. +
    + Parameter lists in function definitions must now be wrapped in parentheses. +
    + Added property soaking, with the ?. operator. +
    + Made parentheses optional, when invoking functions with arguments. +
    + Removed the obsolete block literal syntax. +

    + +

    + 0.2.6 + Added Python-style chained comparisons, the conditional existence + operator ?=, and some examples from Beautiful Code. + Bugfixes relating to statement-to-expression conversion, arguments-to-array + conversion, and the TextMate syntax highlighter. +

    + +

    + 0.2.5 + The conditions in switch statements can now take multiple values at once — + If any of them are true, the case will run. Added the long arrow ==>, + which defines and immediately binds a function to this. While loops can + now be used as expressions, in the same way that comprehensions can. Splats + can be used within pattern matches to soak up the rest of an array. +

    + +

    + 0.2.4 + Added ECMAScript Harmony style destructuring assignment, for dealing with + extracting values from nested arrays and objects. Added indentation-sensitive + heredocs for nicely formatted strings or chunks of code. +

    + +

    + 0.2.3 + Axed the unsatisfactory ino keyword, replacing it with of for + object comprehensions. They now look like: for prop, value of object. +

    + +

    + 0.2.2 + When performing a comprehension over an object, use ino, instead + of in, which helps us generate smaller, more efficient code at + compile time. +
    + Added :: as a shorthand for saying .prototype. +
    + The "splat" symbol has been changed from a prefix asterisk *, to + a postfix ellipsis ... +
    + Added JavaScript's in operator, + empty return statements, and empty while loops. +
    + Constructor functions that start with capital letters now include a + safety check to make sure that the new instance of the object is returned. +
    + The extends keyword now functions identically to goog.inherits + in Google's Closure Library. +

    + +

    + 0.2.1 + Arguments objects are now converted into real arrays when referenced. +

    + +

    + 0.2.0 + Major release. Significant whitespace. Better statement-to-expression + conversion. Splats. Splice literals. Object comprehensions. Blocks. + The existential operator. Many thanks to all the folks who posted issues, + with special thanks to + Liam O'Connor-Davis for whitespace + and expression help. +

    + +

    + 0.1.6 + Bugfix for running coffee --interactive and --run + from outside of the CoffeeScript directory. Bugfix for nested + function/if-statements. +

    + +

    + 0.1.5 + Array slice literals and array comprehensions can now both take Ruby-style + ranges to specify the start and end. JavaScript variable declaration is + now pushed up to the top of the scope, making all assignment statements into + expressions. You can use \ to escape newlines. + The coffee-script command is now called coffee. +

    + +

    + 0.1.4 + The official CoffeeScript extension is now .coffee instead of + .cs, which properly belongs to + C#. + Due to popular demand, you can now also use = to assign. Unlike + JavaScript, = can also be used within object literals, interchangeably + with :. Made a grammatical fix for chained function calls + like func(1)(2)(3)(4). Inheritance and super no longer use + __proto__, so they should be IE-compatible now. +

    + +

    + 0.1.3 + The coffee command now includes --interactive, + which launches an interactive CoffeeScript session, and --run, + which directly compiles and executes a script. Both options depend on a + working installation of Narwhal. + The aint keyword has been replaced by isnt, which goes + together a little smoother with is. + Quoted strings are now allowed as identifiers within object literals: eg. + {"5+5": 10}. + All assignment operators now use a colon: +:, -:, + *:, etc. +

    + +

    + 0.1.2 + Fixed a bug with calling super() through more than one level of + inheritance, with the re-addition of the extends keyword. + Added experimental Narwhal + support (as a Tusk package), contributed by + Tom Robinson, including + bin/cs as a CoffeeScript REPL and interpreter. + New --no-wrap option to suppress the safety function + wrapper. +

    + +

    + 0.1.1 + Added instanceof and typeof as operators. +

    + +

    + 0.1.0 + Initial CoffeeScript release. +

    + +
    + + + + + + + + diff --git a/node_modules/jade/support/coffee-script/lib/browser.js b/node_modules/jade/support/coffee-script/lib/browser.js new file mode 100644 index 0000000..c35d5fe --- /dev/null +++ b/node_modules/jade/support/coffee-script/lib/browser.js @@ -0,0 +1,46 @@ +(function() { + var CoffeeScript, runScripts; + CoffeeScript = require('./coffee-script'); + CoffeeScript.require = require; + CoffeeScript.eval = function(code, options) { + return eval(CoffeeScript.compile(code, options)); + }; + CoffeeScript.run = function(code, options) { + ((options != null) ? (options.bare = true) : undefined); + return Function(CoffeeScript.compile(code, options))(); + }; + if (!(typeof window !== "undefined" && window !== null)) { + return; + } + CoffeeScript.load = function(url, options) { + var xhr; + xhr = new (window.ActiveXObject || XMLHttpRequest)('Microsoft.XMLHTTP'); + xhr.open('GET', url, true); + if ('overrideMimeType' in xhr) { + xhr.overrideMimeType('text/plain'); + } + xhr.onreadystatechange = function() { + return xhr.readyState === 4 ? CoffeeScript.run(xhr.responseText, options) : undefined; + }; + return xhr.send(null); + }; + runScripts = function() { + var _i, _j, _len, _ref, script; + for (_i = 0, _len = (_ref = document.getElementsByTagName('script')).length; _i < _len; _i++) { + (function() { + var script = _ref[_i]; + _j = script; + return script.type === 'text/coffeescript' ? (script.src ? CoffeeScript.load(script.src) : setTimeout(function() { + return CoffeeScript.run(script.innerHTML); + })) : undefined; + })(); + script = _j; + } + return null; + }; + if (window.addEventListener) { + addEventListener('DOMContentLoaded', runScripts, false); + } else { + attachEvent('onload', runScripts); + } +}).call(this); diff --git a/node_modules/jade/support/coffee-script/lib/cake.js b/node_modules/jade/support/coffee-script/lib/cake.js new file mode 100755 index 0000000..770a648 --- /dev/null +++ b/node_modules/jade/support/coffee-script/lib/cake.js @@ -0,0 +1,73 @@ +(function() { + var CoffeeScript, fs, helpers, missingTask, oparse, options, optparse, path, printTasks, switches, tasks; + fs = require('fs'); + path = require('path'); + helpers = require('./helpers'); + optparse = require('./optparse'); + CoffeeScript = require('./coffee-script'); + tasks = {}; + options = {}; + switches = []; + oparse = null; + helpers.extend(global, { + task: function(name, description, action) { + var _ref; + if (!action) { + _ref = [description, action], action = _ref[0], description = _ref[1]; + } + return (tasks[name] = { + name: name, + description: description, + action: action + }); + }, + option: function(letter, flag, description) { + return switches.push([letter, flag, description]); + }, + invoke: function(name) { + if (!tasks[name]) { + missingTask(name); + } + return tasks[name].action(options); + } + }); + exports.run = function() { + return path.exists('Cakefile', function(exists) { + var _i, _len, _ref, _result, arg, args; + if (!exists) { + throw new Error("Cakefile not found in " + (process.cwd())); + } + args = process.argv.slice(2); + CoffeeScript.run(fs.readFileSync('Cakefile').toString(), { + fileName: 'Cakefile' + }); + oparse = new optparse.OptionParser(switches); + if (!args.length) { + return printTasks(); + } + options = oparse.parse(args); + _result = []; + for (_i = 0, _len = (_ref = options.arguments).length; _i < _len; _i++) { + arg = _ref[_i]; + _result.push(invoke(arg)); + } + return _result; + }); + }; + printTasks = function() { + var _ref, desc, name, spaces, task; + puts(''); + for (name in _ref = tasks) { + task = _ref[name]; + spaces = 20 - name.length; + spaces = spaces > 0 ? Array(spaces + 1).join(' ') : ''; + desc = task.description ? ("# " + (task.description)) : ''; + puts("cake " + name + spaces + " " + desc); + } + return switches.length ? puts(oparse.help()) : undefined; + }; + missingTask = function(task) { + puts("No such task: \"" + task + "\""); + return process.exit(1); + }; +}).call(this); diff --git a/node_modules/jade/support/coffee-script/lib/coffee-script.js b/node_modules/jade/support/coffee-script/lib/coffee-script.js new file mode 100755 index 0000000..7bd422c --- /dev/null +++ b/node_modules/jade/support/coffee-script/lib/coffee-script.js @@ -0,0 +1,74 @@ +(function() { + var Lexer, compile, fs, lexer, parser, path; + path = require('path'); + Lexer = require('./lexer').Lexer; + parser = require('./parser').parser; + if (require.extensions) { + fs = require('fs'); + require.extensions['.coffee'] = function(module, filename) { + var content; + content = compile(fs.readFileSync(filename, 'utf8')); + return module._compile(content, filename); + }; + } else if (require.registerExtension) { + require.registerExtension('.coffee', function(content) { + return compile(content); + }); + } + exports.VERSION = '0.9.4'; + exports.helpers = require('./helpers'); + exports.compile = (compile = function(code, options) { + options || (options = {}); + try { + return (parser.parse(lexer.tokenize(code))).compile(options); + } catch (err) { + if (options.fileName) { + err.message = ("In " + (options.fileName) + ", " + (err.message)); + } + throw err; + } + }); + exports.tokens = function(code, options) { + return lexer.tokenize(code, options); + }; + exports.nodes = function(code, options) { + return parser.parse(lexer.tokenize(code, options)); + }; + exports.run = function(code, options) { + var root; + root = module; + while (root.parent) { + root = root.parent; + } + root.filename = options.fileName; + if (root.moduleCache) { + root.moduleCache = {}; + } + return path.extname(root.filename) !== '.coffee' || require.extensions ? root._compile(exports.compile(code, options), root.filename) : root._compile(code, root.filename); + }; + exports.eval = function(code, options) { + var __dirname, __filename; + __filename = options.fileName; + __dirname = path.dirname(__filename); + return eval(exports.compile(code, options)); + }; + lexer = new Lexer; + parser.lexer = { + lex: function() { + var token; + token = this.tokens[this.pos] || [""]; + this.pos += 1; + this.yylineno = token[2]; + this.yytext = token[1]; + return token[0]; + }, + setInput: function(tokens) { + this.tokens = tokens; + return (this.pos = 0); + }, + upcomingInput: function() { + return ""; + } + }; + parser.yy = require('./nodes'); +}).call(this); diff --git a/node_modules/jade/support/coffee-script/lib/command.js b/node_modules/jade/support/coffee-script/lib/command.js new file mode 100644 index 0000000..58a2774 --- /dev/null +++ b/node_modules/jade/support/coffee-script/lib/command.js @@ -0,0 +1,227 @@ +(function() { + var BANNER, CoffeeScript, EventEmitter, SWITCHES, _ref, compileOptions, compileScript, compileScripts, compileStdio, exec, fs, helpers, lint, optionParser, optparse, opts, parseOptions, path, printTokens, sources, spawn, usage, version, watch, writeJs; + fs = require('fs'); + path = require('path'); + optparse = require('./optparse'); + CoffeeScript = require('./coffee-script'); + helpers = require('./helpers'); + _ref = require('child_process'), spawn = _ref.spawn, exec = _ref.exec; + EventEmitter = require('events').EventEmitter; + helpers.extend(CoffeeScript, new EventEmitter); + global.CoffeeScript = CoffeeScript; + BANNER = 'coffee compiles CoffeeScript source files into JavaScript.\n\nUsage:\n coffee path/to/script.coffee'; + SWITCHES = [['-c', '--compile', 'compile to JavaScript and save as .js files'], ['-i', '--interactive', 'run an interactive CoffeeScript REPL'], ['-o', '--output [DIR]', 'set the directory for compiled JavaScript'], ['-w', '--watch', 'watch scripts for changes, and recompile'], ['-p', '--print', 'print the compiled JavaScript to stdout'], ['-l', '--lint', 'pipe the compiled JavaScript through JSLint'], ['-s', '--stdio', 'listen for and compile scripts over stdio'], ['-e', '--eval', 'compile a string from the command line'], ['-r', '--require [FILE*]', 'require a library before executing your script'], ['-b', '--bare', 'compile without the top-level function wrapper'], ['-t', '--tokens', 'print the tokens that the lexer produces'], ['-n', '--nodes', 'print the parse tree that Jison produces'], ['-v', '--version', 'display CoffeeScript version'], ['-h', '--help', 'display this help message']]; + opts = {}; + sources = []; + optionParser = null; + exports.run = function() { + var flags, separator; + parseOptions(); + if (opts.help) { + return usage(); + } + if (opts.version) { + return version(); + } + if (opts.interactive) { + return require('./repl'); + } + if (opts.stdio) { + return compileStdio(); + } + if (opts.eval) { + return compileScript('console', sources[0]); + } + if (!sources.length) { + return require('./repl'); + } + separator = sources.indexOf('--'); + flags = []; + if (separator >= 0) { + flags = sources.splice(separator + 1); + sources.pop(); + } + if (opts.run) { + flags = sources.splice(1).concat(flags); + } + process.ARGV = (process.argv = flags); + return compileScripts(); + }; + compileScripts = function() { + var _i, _j, _len, _ref2, _result, base, compile, source; + _result = []; + for (_i = 0, _len = (_ref2 = sources).length; _i < _len; _i++) { + (function() { + var source = _ref2[_i]; + _j = source; + return _result.push((function() { + base = source; + compile = function(source, topLevel) { + return path.exists(source, function(exists) { + if (!exists) { + throw new Error("File not found: " + source); + } + return fs.stat(source, function(err, stats) { + if (stats.isDirectory()) { + return fs.readdir(source, function(err, files) { + var _k, _len2, _result2, file; + _result2 = []; + for (_k = 0, _len2 = files.length; _k < _len2; _k++) { + file = files[_k]; + _result2.push(compile(path.join(source, file))); + } + return _result2; + }); + } else if (topLevel || path.extname(source) === '.coffee') { + fs.readFile(source, function(err, code) { + return compileScript(source, code.toString(), base); + }); + return opts.watch ? watch(source, base) : undefined; + } + }); + }); + }; + return compile(source, true); + })()); + })(); + source = _j; + } + return _result; + }; + compileScript = function(file, input, base) { + var _i, _len, _ref2, o, options, req, t, task; + o = opts; + options = compileOptions(file); + if (o.require) { + for (_i = 0, _len = (_ref2 = o.require).length; _i < _len; _i++) { + req = _ref2[_i]; + require(helpers.starts(req, '.') ? fs.realpathSync(req) : req); + } + } + try { + t = (task = { + file: file, + input: input, + options: options + }); + CoffeeScript.emit('compile', task); + if (o.tokens) { + return printTokens(CoffeeScript.tokens(t.input)); + } else if (o.nodes) { + return puts(CoffeeScript.nodes(t.input).toString().trim()); + } else if (o.run) { + return CoffeeScript.run(t.input, t.options); + } else { + t.output = CoffeeScript.compile(t.input, t.options); + CoffeeScript.emit('success', task); + return o.print ? print(t.output) : (o.compile ? writeJs(t.file, t.output, base) : (o.lint ? lint(t.output) : undefined)); + } + } catch (err) { + CoffeeScript.emit('failure', err, task); + if (CoffeeScript.listeners('failure').length) { + return; + } + if (o.watch) { + return puts(err.message); + } + error(err.stack); + return process.exit(1); + } + }; + compileStdio = function() { + var code, stdin; + code = ''; + stdin = process.openStdin(); + stdin.on('data', function(buffer) { + return buffer ? code += buffer.toString() : undefined; + }); + return stdin.on('end', function() { + return compileScript('stdio', code); + }); + }; + watch = function(source, base) { + return fs.watchFile(source, { + persistent: true, + interval: 500 + }, function(curr, prev) { + if (curr.size === prev.size && curr.mtime.getTime() === prev.mtime.getTime()) { + return; + } + return fs.readFile(source, function(err, code) { + if (err) { + throw err; + } + return compileScript(source, code.toString(), base); + }); + }); + }; + writeJs = function(source, js, base) { + var baseDir, compile, dir, filename, jsPath, srcDir; + filename = path.basename(source, path.extname(source)) + '.js'; + srcDir = path.dirname(source); + baseDir = srcDir.substring(base.length); + dir = opts.output ? path.join(opts.output, baseDir) : srcDir; + jsPath = path.join(dir, filename); + compile = function() { + if (js.length <= 0) { + js = ' '; + } + return fs.writeFile(jsPath, js, function(err) { + return opts.compile && opts.watch ? puts("Compiled " + source) : undefined; + }); + }; + return path.exists(dir, function(exists) { + return exists ? compile() : exec("mkdir -p " + dir, compile); + }); + }; + lint = function(js) { + var conf, jsl, printIt; + printIt = function(buffer) { + return puts(buffer.toString().trim()); + }; + conf = __dirname + '/../extras/jsl.conf'; + jsl = spawn('jsl', ['-nologo', '-stdin', '-conf', conf]); + jsl.stdout.on('data', printIt); + jsl.stderr.on('data', printIt); + jsl.stdin.write(js); + return jsl.stdin.end(); + }; + printTokens = function(tokens) { + var _i, _len, _ref2, _result, strings, tag, token, value; + strings = (function() { + _result = []; + for (_i = 0, _len = tokens.length; _i < _len; _i++) { + token = tokens[_i]; + _result.push((function() { + _ref2 = [token[0], token[1].toString().replace(/\n/, '\\n')], tag = _ref2[0], value = _ref2[1]; + return "[" + tag + " " + value + "]"; + })()); + } + return _result; + })(); + return puts(strings.join(' ')); + }; + parseOptions = function() { + var o; + optionParser = new optparse.OptionParser(SWITCHES, BANNER); + o = (opts = optionParser.parse(process.argv.slice(2))); + o.compile || (o.compile = !!o.output); + o.run = !(o.compile || o.print || o.lint); + o.print = !!(o.print || (o.eval || o.stdio && o.compile)); + return (sources = o.arguments); + }; + compileOptions = function(fileName) { + return { + fileName: fileName, + bare: opts.bare + }; + }; + usage = function() { + puts(optionParser.help()); + return process.exit(0); + }; + version = function() { + puts("CoffeeScript version " + (CoffeeScript.VERSION)); + return process.exit(0); + }; +}).call(this); diff --git a/node_modules/jade/support/coffee-script/lib/grammar.js b/node_modules/jade/support/coffee-script/lib/grammar.js new file mode 100644 index 0000000..e038a74 --- /dev/null +++ b/node_modules/jade/support/coffee-script/lib/grammar.js @@ -0,0 +1,622 @@ +(function() { + var Parser, _i, _j, _len, _len2, _ref, _result, alt, alternatives, grammar, name, o, operators, token, tokens, unwrap; + var __hasProp = Object.prototype.hasOwnProperty; + Parser = require('jison').Parser; + unwrap = /function\s*\(\)\s*\{\s*return\s*([\s\S]*);\s*\}/; + o = function(patternString, action, options) { + var match; + if (!action) { + return [patternString, '$$ = $1;', options]; + } + action = (match = (action + '').match(unwrap)) ? match[1] : ("(" + action + "())"); + action = action.replace(/\bnew (\w+)\b/g, 'new yy.$1').replace(/Expressions\.wrap/g, 'yy.Expressions.wrap'); + return [patternString, ("$$ = " + action + ";"), options]; + }; + grammar = { + Root: [ + o("", function() { + return new Expressions; + }), o("TERMINATOR", function() { + return new Expressions; + }), o("Body"), o("Block TERMINATOR") + ], + Body: [ + o("Line", function() { + return Expressions.wrap([$1]); + }), o("Body TERMINATOR Line", function() { + return $1.push($3); + }), o("Body TERMINATOR") + ], + Line: [o("Expression"), o("Statement")], + Statement: [ + o("Return"), o("Throw"), o("BREAK", function() { + return new Literal($1); + }), o("CONTINUE", function() { + return new Literal($1); + }), o("DEBUGGER", function() { + return new Literal($1); + }) + ], + Expression: [o("Value"), o("Invocation"), o("Code"), o("Operation"), o("Assign"), o("If"), o("Try"), o("While"), o("For"), o("Switch"), o("Extends"), o("Class"), o("Existence"), o("Comment")], + Block: [ + o("INDENT Body OUTDENT", function() { + return $2; + }), o("INDENT OUTDENT", function() { + return new Expressions; + }), o("TERMINATOR Comment", function() { + return Expressions.wrap([$2]); + }) + ], + Identifier: [ + o("IDENTIFIER", function() { + return new Literal($1); + }) + ], + AlphaNumeric: [ + o("NUMBER", function() { + return new Literal($1); + }), o("STRING", function() { + return new Literal($1); + }) + ], + Literal: [ + o("AlphaNumeric"), o("JS", function() { + return new Literal($1); + }), o("REGEX", function() { + return new Literal($1); + }), o("BOOL", function() { + return new Literal($1); + }) + ], + Assign: [ + o("Assignable = Expression", function() { + return new Assign($1, $3); + }), o("Assignable = INDENT Expression OUTDENT", function() { + return new Assign($1, $4); + }) + ], + AssignObj: [ + o("Identifier", function() { + return new Value($1); + }), o("AlphaNumeric"), o("ThisProperty"), o("Identifier : Expression", function() { + return new Assign(new Value($1), $3, 'object'); + }), o("AlphaNumeric : Expression", function() { + return new Assign(new Value($1), $3, 'object'); + }), o("Identifier : INDENT Expression OUTDENT", function() { + return new Assign(new Value($1), $4, 'object'); + }), o("AlphaNumeric : INDENT Expression OUTDENT", function() { + return new Assign(new Value($1), $4, 'object'); + }), o("Comment") + ], + Return: [ + o("RETURN Expression", function() { + return new Return($2); + }), o("RETURN", function() { + return new Return; + }) + ], + Comment: [ + o("HERECOMMENT", function() { + return new Comment($1); + }) + ], + Existence: [ + o("Expression ?", function() { + return new Existence($1); + }) + ], + Code: [ + o("PARAM_START ParamList PARAM_END FuncGlyph Block", function() { + return new Code($2, $5, $4); + }), o("FuncGlyph Block", function() { + return new Code([], $2, $1); + }) + ], + FuncGlyph: [ + o("->", function() { + return 'func'; + }), o("=>", function() { + return 'boundfunc'; + }) + ], + OptComma: [o(''), o(',')], + ParamList: [ + o("", function() { + return []; + }), o("Param", function() { + return [$1]; + }), o("ParamList , Param", function() { + return $1.concat($3); + }) + ], + Param: [ + o("PARAM", function() { + return new Literal($1); + }), o("@ PARAM", function() { + return new Param($2, true); + }), o("PARAM ...", function() { + return new Param($1, false, true); + }), o("@ PARAM ...", function() { + return new Param($2, true, true); + }) + ], + Splat: [ + o("Expression ...", function() { + return new Splat($1); + }) + ], + SimpleAssignable: [ + o("Identifier", function() { + return new Value($1); + }), o("Value Accessor", function() { + return $1.push($2); + }), o("Invocation Accessor", function() { + return new Value($1, [$2]); + }), o("ThisProperty") + ], + Assignable: [ + o("SimpleAssignable"), o("Array", function() { + return new Value($1); + }), o("Object", function() { + return new Value($1); + }) + ], + Value: [ + o("Assignable"), o("Literal", function() { + return new Value($1); + }), o("Parenthetical", function() { + return new Value($1); + }), o("Range", function() { + return new Value($1); + }), o("This") + ], + Accessor: [ + o("PROPERTY_ACCESS Identifier", function() { + return new Accessor($2); + }), o("PROTOTYPE_ACCESS Identifier", function() { + return new Accessor($2, 'prototype'); + }), o("::", function() { + return new Accessor(new Literal('prototype')); + }), o("SOAK_ACCESS Identifier", function() { + return new Accessor($2, 'soak'); + }), o("Index"), o("Slice", function() { + return new Slice($1); + }) + ], + Index: [ + o("INDEX_START Expression INDEX_END", function() { + return new Index($2); + }), o("INDEX_SOAK Index", function() { + $2.soakNode = true; + return $2; + }), o("INDEX_PROTO Index", function() { + $2.proto = true; + return $2; + }) + ], + Object: [ + o("{ AssignList OptComma }", function() { + return new ObjectLiteral($2); + }) + ], + AssignList: [ + o("", function() { + return []; + }), o("AssignObj", function() { + return [$1]; + }), o("AssignList , AssignObj", function() { + return $1.concat($3); + }), o("AssignList OptComma TERMINATOR AssignObj", function() { + return $1.concat($4); + }), o("AssignList OptComma INDENT AssignList OptComma OUTDENT", function() { + return $1.concat($4); + }) + ], + Class: [ + o("CLASS SimpleAssignable", function() { + return new Class($2); + }), o("CLASS SimpleAssignable EXTENDS Value", function() { + return new Class($2, $4); + }), o("CLASS SimpleAssignable INDENT ClassBody OUTDENT", function() { + return new Class($2, null, $4); + }), o("CLASS SimpleAssignable EXTENDS Value INDENT ClassBody OUTDENT", function() { + return new Class($2, $4, $6); + }), o("CLASS INDENT ClassBody OUTDENT", function() { + return new Class('__temp__', null, $3); + }), o("CLASS", function() { + return new Class('__temp__', null, new Expressions); + }), o("CLASS EXTENDS Value", function() { + return new Class('__temp__', $3, new Expressions); + }), o("CLASS EXTENDS Value INDENT ClassBody OUTDENT", function() { + return new Class('__temp__', $3, $5); + }) + ], + ClassAssign: [ + o("AssignObj", function() { + return $1; + }), o("ThisProperty : Expression", function() { + return new Assign(new Value($1), $3, 'this'); + }), o("ThisProperty : INDENT Expression OUTDENT", function() { + return new Assign(new Value($1), $4, 'this'); + }) + ], + ClassBody: [ + o("", function() { + return []; + }), o("ClassAssign", function() { + return [$1]; + }), o("ClassBody TERMINATOR ClassAssign", function() { + return $1.concat($3); + }), o("{ ClassBody }", function() { + return $2; + }) + ], + Extends: [ + o("SimpleAssignable EXTENDS Value", function() { + return new Extends($1, $3); + }) + ], + Invocation: [ + o("Value OptFuncExist Arguments", function() { + return new Call($1, $3, $2); + }), o("Invocation OptFuncExist Arguments", function() { + return new Call($1, $3, $2); + }), o("SUPER", function() { + return new Call('super', [new Splat(new Literal('arguments'))]); + }), o("SUPER Arguments", function() { + return new Call('super', $2); + }) + ], + OptFuncExist: [ + o("", function() { + return false; + }), o("FUNC_EXIST", function() { + return true; + }) + ], + Arguments: [ + o("CALL_START CALL_END", function() { + return []; + }), o("CALL_START ArgList OptComma CALL_END", function() { + return $2; + }) + ], + This: [ + o("THIS", function() { + return new Value(new Literal('this')); + }), o("@", function() { + return new Value(new Literal('this')); + }) + ], + RangeDots: [ + o("..", function() { + return 'inclusive'; + }), o("...", function() { + return 'exclusive'; + }) + ], + ThisProperty: [ + o("@ Identifier", function() { + return new Value(new Literal('this'), [new Accessor($2)], 'this'); + }) + ], + Range: [ + o("[ Expression RangeDots Expression ]", function() { + return new Range($2, $4, $3); + }) + ], + Slice: [ + o("INDEX_START Expression RangeDots Expression INDEX_END", function() { + return new Range($2, $4, $3); + }), o("INDEX_START Expression RangeDots INDEX_END", function() { + return new Range($2, null, $3); + }), o("INDEX_START RangeDots Expression INDEX_END", function() { + return new Range(null, $3, $2); + }) + ], + Array: [ + o("[ ]", function() { + return new ArrayLiteral([]); + }), o("[ ArgList OptComma ]", function() { + return new ArrayLiteral($2); + }) + ], + ArgList: [ + o("Arg", function() { + return [$1]; + }), o("ArgList , Arg", function() { + return $1.concat($3); + }), o("ArgList OptComma TERMINATOR Arg", function() { + return $1.concat($4); + }), o("INDENT ArgList OptComma OUTDENT", function() { + return $2; + }), o("ArgList OptComma INDENT ArgList OptComma OUTDENT", function() { + return $1.concat($4); + }) + ], + Arg: [o("Expression"), o("Splat")], + SimpleArgs: [ + o("Expression"), o("SimpleArgs , Expression", function() { + return [].concat($1, $3); + }) + ], + Try: [ + o("TRY Block", function() { + return new Try($2); + }), o("TRY Block Catch", function() { + return new Try($2, $3[0], $3[1]); + }), o("TRY Block FINALLY Block", function() { + return new Try($2, null, null, $4); + }), o("TRY Block Catch FINALLY Block", function() { + return new Try($2, $3[0], $3[1], $5); + }) + ], + Catch: [ + o("CATCH Identifier Block", function() { + return [$2, $3]; + }) + ], + Throw: [ + o("THROW Expression", function() { + return new Throw($2); + }) + ], + Parenthetical: [ + o("( Expression )", function() { + return new Parens($2); + }), o("( )", function() { + return new Parens(new Literal('')); + }) + ], + WhileSource: [ + o("WHILE Expression", function() { + return new While($2); + }), o("WHILE Expression WHEN Expression", function() { + return new While($2, { + guard: $4 + }); + }), o("UNTIL Expression", function() { + return new While($2, { + invert: true + }); + }), o("UNTIL Expression WHEN Expression", function() { + return new While($2, { + invert: true, + guard: $4 + }); + }) + ], + While: [ + o("WhileSource Block", function() { + return $1.addBody($2); + }), o("Statement WhileSource", function() { + return $2.addBody(Expressions.wrap([$1])); + }), o("Expression WhileSource", function() { + return $2.addBody(Expressions.wrap([$1])); + }), o("Loop", function() { + return $1; + }) + ], + Loop: [ + o("LOOP Block", function() { + return new While(new Literal('true')).addBody($2); + }), o("LOOP Expression", function() { + return new While(new Literal('true')).addBody(Expressions.wrap([$2])); + }) + ], + For: [ + o("Statement ForBody", function() { + return new For($1, $2, $2.vars[0], $2.vars[1]); + }), o("Expression ForBody", function() { + return new For($1, $2, $2.vars[0], $2.vars[1]); + }), o("ForBody Block", function() { + return new For($2, $1, $1.vars[0], $1.vars[1]); + }) + ], + ForBody: [ + o("FOR Range", function() { + return { + source: new Value($2), + vars: [] + }; + }), o("ForStart ForSource", function() { + $2.raw = $1.raw; + $2.vars = $1; + return $2; + }) + ], + ForStart: [ + o("FOR ForVariables", function() { + return $2; + }), o("FOR ALL ForVariables", function() { + $3.raw = true; + return $3; + }) + ], + ForValue: [ + o("Identifier"), o("Array", function() { + return new Value($1); + }), o("Object", function() { + return new Value($1); + }) + ], + ForVariables: [ + o("ForValue", function() { + return [$1]; + }), o("ForValue , ForValue", function() { + return [$1, $3]; + }) + ], + ForSource: [ + o("FORIN Expression", function() { + return { + source: $2 + }; + }), o("FOROF Expression", function() { + return { + source: $2, + object: true + }; + }), o("FORIN Expression WHEN Expression", function() { + return { + source: $2, + guard: $4 + }; + }), o("FOROF Expression WHEN Expression", function() { + return { + source: $2, + guard: $4, + object: true + }; + }), o("FORIN Expression BY Expression", function() { + return { + source: $2, + step: $4 + }; + }), o("FORIN Expression WHEN Expression BY Expression", function() { + return { + source: $2, + guard: $4, + step: $6 + }; + }), o("FORIN Expression BY Expression WHEN Expression", function() { + return { + source: $2, + step: $4, + guard: $6 + }; + }) + ], + Switch: [ + o("SWITCH Expression INDENT Whens OUTDENT", function() { + return new Switch($2, $4); + }), o("SWITCH Expression INDENT Whens ELSE Block OUTDENT", function() { + return new Switch($2, $4, $6); + }), o("SWITCH INDENT Whens OUTDENT", function() { + return new Switch(null, $3); + }), o("SWITCH INDENT Whens ELSE Block OUTDENT", function() { + return new Switch(null, $3, $5); + }) + ], + Whens: [ + o("When"), o("Whens When", function() { + return $1.concat($2); + }) + ], + When: [ + o("LEADING_WHEN SimpleArgs Block", function() { + return [[$2, $3]]; + }), o("LEADING_WHEN SimpleArgs Block TERMINATOR", function() { + return [[$2, $3]]; + }) + ], + IfBlock: [ + o("IF Expression Block", function() { + return new If($2, $3); + }), o("UNLESS Expression Block", function() { + return new If($2, $3, { + invert: true + }); + }), o("IfBlock ELSE IF Expression Block", function() { + return $1.addElse(new If($4, $5)); + }), o("IfBlock ELSE Block", function() { + return $1.addElse($3); + }) + ], + If: [ + o("IfBlock"), o("Statement POST_IF Expression", function() { + return new If($3, Expressions.wrap([$1]), { + statement: true + }); + }), o("Expression POST_IF Expression", function() { + return new If($3, Expressions.wrap([$1]), { + statement: true + }); + }), o("Statement POST_UNLESS Expression", function() { + return new If($3, Expressions.wrap([$1]), { + statement: true, + invert: true + }); + }), o("Expression POST_UNLESS Expression", function() { + return new If($3, Expressions.wrap([$1]), { + statement: true, + invert: true + }); + }) + ], + Operation: [ + o("UNARY Expression", function() { + return new Op($1, $2); + }), o("- Expression", function() { + return new Op('-', $2); + }, { + prec: 'UNARY' + }), o("+ Expression", function() { + return new Op('+', $2); + }, { + prec: 'UNARY' + }), o("-- SimpleAssignable", function() { + return new Op('--', $2); + }), o("++ SimpleAssignable", function() { + return new Op('++', $2); + }), o("SimpleAssignable --", function() { + return new Op('--', $1, null, true); + }), o("SimpleAssignable ++", function() { + return new Op('++', $1, null, true); + }), o("Expression + Expression", function() { + return new Op('+', $1, $3); + }), o("Expression - Expression", function() { + return new Op('-', $1, $3); + }), o("Expression == Expression", function() { + return new Op('==', $1, $3); + }), o("Expression != Expression", function() { + return new Op('!=', $1, $3); + }), o("Expression MATH Expression", function() { + return new Op($2, $1, $3); + }), o("Expression SHIFT Expression", function() { + return new Op($2, $1, $3); + }), o("Expression COMPARE Expression", function() { + return new Op($2, $1, $3); + }), o("Expression LOGIC Expression", function() { + return new Op($2, $1, $3); + }), o("SimpleAssignable COMPOUND_ASSIGN Expression", function() { + return new Op($2, $1, $3); + }), o("SimpleAssignable COMPOUND_ASSIGN INDENT Expression OUTDENT", function() { + return new Op($2, $1, $4); + }), o("Expression RELATION Expression", function() { + return $2.charAt(0) === '!' ? ($2 === '!in' ? new Op('!', new In($1, $3)) : new Op('!', new Parens(new Op($2.slice(1), $1, $3)))) : ($2 === 'in' ? new In($1, $3) : new Op($2, $1, $3)); + }) + ] + }; + operators = [["left", 'CALL_START', 'CALL_END'], ["nonassoc", '++', '--'], ["left", '?'], ["right", 'UNARY'], ["left", 'MATH'], ["left", '+', '-'], ["left", 'SHIFT'], ["left", 'COMPARE'], ["left", 'RELATION'], ["left", '==', '!='], ["left", 'LOGIC'], ["right", 'COMPOUND_ASSIGN'], ["left", '.'], ["nonassoc", 'INDENT', 'OUTDENT'], ["right", 'WHEN', 'LEADING_WHEN', 'FORIN', 'FOROF', 'BY', 'THROW'], ["right", 'IF', 'UNLESS', 'ELSE', 'FOR', 'WHILE', 'UNTIL', 'LOOP', 'SUPER', 'CLASS', 'EXTENDS'], ["right", '=', ':', 'RETURN'], ["right", '->', '=>', 'UNLESS', 'POST_IF', 'POST_UNLESS']]; + tokens = []; + for (name in grammar) { + if (!__hasProp.call(grammar, name)) continue; + alternatives = grammar[name]; + grammar[name] = (function() { + _result = []; + for (_i = 0, _len = alternatives.length; _i < _len; _i++) { + alt = alternatives[_i]; + _result.push((function() { + for (_j = 0, _len2 = (_ref = alt[0].split(' ')).length; _j < _len2; _j++) { + token = _ref[_j]; + if (!grammar[token]) { + tokens.push(token); + } + } + if (name === 'Root') { + alt[1] = ("return " + (alt[1])); + } + return alt; + })()); + } + return _result; + })(); + } + exports.parser = new Parser({ + tokens: tokens.join(' '), + bnf: grammar, + operators: operators.reverse(), + startSymbol: 'Root' + }); +}).call(this); diff --git a/node_modules/jade/support/coffee-script/lib/helpers.js b/node_modules/jade/support/coffee-script/lib/helpers.js new file mode 100644 index 0000000..5983bf6 --- /dev/null +++ b/node_modules/jade/support/coffee-script/lib/helpers.js @@ -0,0 +1,78 @@ +(function() { + var extend, flatten, indexOf; + indexOf = (exports.indexOf = Array.indexOf || (Array.prototype.indexOf ? function(array, item, from) { + return array.indexOf(item, from); + } : function(array, item, from) { + var _len, index, other; + for (index = 0, _len = array.length; index < _len; index++) { + other = array[index]; + if (other === item && (!from || (from <= index))) { + return index; + } + } + return -1; + })); + exports.include = function(list, value) { + return indexOf(list, value) >= 0; + }; + exports.starts = function(string, literal, start) { + return literal === string.substr(start, literal.length); + }; + exports.ends = function(string, literal, back) { + var len; + len = literal.length; + return literal === string.substr(string.length - len - (back || 0), len); + }; + exports.compact = function(array) { + var _i, _len, _result, item; + _result = []; + for (_i = 0, _len = array.length; _i < _len; _i++) { + item = array[_i]; + if (item) { + _result.push(item); + } + } + return _result; + }; + exports.count = function(string, letter) { + var num, pos; + num = (pos = 0); + while (pos = 1 + string.indexOf(letter, pos)) { + num++; + } + return num; + }; + exports.merge = function(options, overrides) { + return extend(extend({}, options), overrides); + }; + extend = (exports.extend = function(object, properties) { + var key, val; + for (key in properties) { + val = properties[key]; + object[key] = val; + } + return object; + }); + exports.flatten = (flatten = function(array) { + var _i, _len, element, flattened; + flattened = []; + for (_i = 0, _len = array.length; _i < _len; _i++) { + element = array[_i]; + if (element instanceof Array) { + flattened = flattened.concat(flatten(element)); + } else { + flattened.push(element); + } + } + return flattened; + }); + exports.del = function(obj, key) { + var val; + val = obj[key]; + delete obj[key]; + return val; + }; + exports.last = function(array, back) { + return array[array.length - (back || 0) - 1]; + }; +}).call(this); diff --git a/node_modules/jade/support/coffee-script/lib/index.js b/node_modules/jade/support/coffee-script/lib/index.js new file mode 100644 index 0000000..dc5ab13 --- /dev/null +++ b/node_modules/jade/support/coffee-script/lib/index.js @@ -0,0 +1,9 @@ +(function() { + var _ref, key, val; + var __hasProp = Object.prototype.hasOwnProperty; + for (key in _ref = require('./coffee-script')) { + if (!__hasProp.call(_ref, key)) continue; + val = _ref[key]; + (exports[key] = val); + } +}).call(this); diff --git a/node_modules/jade/support/coffee-script/lib/lexer.js b/node_modules/jade/support/coffee-script/lib/lexer.js new file mode 100644 index 0000000..ce25616 --- /dev/null +++ b/node_modules/jade/support/coffee-script/lib/lexer.js @@ -0,0 +1,638 @@ +(function() { + var ASSIGNED, BOOL, CALLABLE, CODE, COFFEE_ALIASES, COFFEE_KEYWORDS, COMMENT, COMPARE, COMPOUND_ASSIGN, HEREDOC, HEREDOC_INDENT, HEREGEX, HEREGEX_OMIT, IDENTIFIER, INDEXABLE, JSTOKEN, JS_FORBIDDEN, JS_KEYWORDS, LEADING_SPACES, LINE_BREAK, LOGIC, Lexer, MATH, MULTILINER, MULTI_DENT, NEXT_CHARACTER, NEXT_ELLIPSIS, NOT_REGEX, NO_NEWLINE, NUMBER, OPERATOR, REGEX, RELATION, RESERVED, Rewriter, SHIFT, SIMPLESTR, TRAILING_SPACES, UNARY, WHITESPACE, _ref, compact, count, include, last, op, starts; + Rewriter = require('./rewriter').Rewriter; + _ref = require('./helpers'), include = _ref.include, count = _ref.count, starts = _ref.starts, compact = _ref.compact, last = _ref.last; + exports.Lexer = (function() { + Lexer = (function() { + function Lexer() { + return this; + }; + return Lexer; + })(); + Lexer.prototype.tokenize = function(code, options) { + var o; + code = code.replace(/\r/g, '').replace(TRAILING_SPACES, ''); + o = options || {}; + this.code = code; + this.i = 0; + this.line = o.line || 0; + this.indent = 0; + this.indebt = 0; + this.outdebt = 0; + this.seenFor = false; + this.indents = []; + this.tokens = []; + while (this.chunk = code.slice(this.i)) { + this.identifierToken() || this.commentToken() || this.whitespaceToken() || this.lineToken() || this.heredocToken() || this.stringToken() || this.numberToken() || this.regexToken() || this.jsToken() || this.literalToken(); + } + this.closeIndentation(); + if (o.rewrite === false) { + return this.tokens; + } + return (new Rewriter).rewrite(this.tokens); + }; + Lexer.prototype.identifierToken = function() { + var colon, forcedIdentifier, id, input, match, tag; + if (!(match = IDENTIFIER.exec(this.chunk))) { + return false; + } + input = match[0], id = match[1], colon = match[2]; + this.i += input.length; + if (id === 'all' && this.tag() === 'FOR') { + this.token('ALL', id); + return true; + } + forcedIdentifier = colon || this.tagAccessor(); + tag = 'IDENTIFIER'; + if (include(JS_KEYWORDS, id) || !forcedIdentifier && include(COFFEE_KEYWORDS, id)) { + tag = id.toUpperCase(); + if (tag === 'WHEN' && include(LINE_BREAK, this.tag())) { + tag = 'LEADING_WHEN'; + } else if (tag === 'FOR') { + this.seenFor = true; + } else if (include(UNARY, tag)) { + tag = 'UNARY'; + } else if (include(RELATION, tag)) { + if (tag !== 'INSTANCEOF' && this.seenFor) { + this.seenFor = false; + tag = 'FOR' + tag; + } else { + tag = 'RELATION'; + if (this.value() === '!') { + this.tokens.pop(); + id = '!' + id; + } + } + } + } + if (include(JS_FORBIDDEN, id)) { + if (forcedIdentifier) { + tag = 'IDENTIFIER'; + id = new String(id); + id.reserved = true; + } else if (include(RESERVED, id)) { + this.identifierError(id); + } + } + if (!forcedIdentifier) { + if (COFFEE_ALIASES.hasOwnProperty(id)) { + tag = (id = COFFEE_ALIASES[id]); + } + if (id === '!') { + tag = 'UNARY'; + } else if (include(LOGIC, id)) { + tag = 'LOGIC'; + } else if (include(BOOL, tag)) { + id = tag.toLowerCase(); + tag = 'BOOL'; + } + } + this.token(tag, id); + if (colon) { + this.token(':', ':'); + } + return true; + }; + Lexer.prototype.numberToken = function() { + var match, number; + if (!(match = NUMBER.exec(this.chunk))) { + return false; + } + number = match[0]; + if (this.tag() === '.' && number.charAt(0) === '.') { + return false; + } + this.i += number.length; + this.token('NUMBER', number); + return true; + }; + Lexer.prototype.stringToken = function() { + var match, string; + switch (this.chunk.charAt(0)) { + case "'": + if (!(match = SIMPLESTR.exec(this.chunk))) { + return false; + } + this.token('STRING', (string = match[0]).replace(MULTILINER, '\\\n')); + break; + case '"': + if (!(string = this.balancedString(this.chunk, [['"', '"'], ['#{', '}']]))) { + return false; + } + if (0 < string.indexOf('#{', 1)) { + this.interpolateString(string.slice(1, -1)); + } else { + this.token('STRING', this.escapeLines(string)); + } + break; + default: + return false; + } + this.line += count(string, '\n'); + this.i += string.length; + return true; + }; + Lexer.prototype.heredocToken = function() { + var doc, heredoc, match, quote; + if (!(match = HEREDOC.exec(this.chunk))) { + return false; + } + heredoc = match[0]; + quote = heredoc.charAt(0); + doc = this.sanitizeHeredoc(match[2], { + quote: quote, + indent: null + }); + if (quote === '"' && (0 <= doc.indexOf('#{'))) { + this.interpolateString(doc, { + heredoc: true + }); + } else { + this.token('STRING', this.makeString(doc, quote, true)); + } + this.line += count(heredoc, '\n'); + this.i += heredoc.length; + return true; + }; + Lexer.prototype.commentToken = function() { + var comment, here, match; + if (!(match = this.chunk.match(COMMENT))) { + return false; + } + comment = match[0], here = match[1]; + this.line += count(comment, '\n'); + this.i += comment.length; + if (here) { + this.token('HERECOMMENT', this.sanitizeHeredoc(here, { + herecomment: true, + indent: Array(this.indent + 1).join(' ') + })); + this.token('TERMINATOR', '\n'); + } + return true; + }; + Lexer.prototype.jsToken = function() { + var match, script; + if (!(this.chunk.charAt(0) === '`' && (match = JSTOKEN.exec(this.chunk)))) { + return false; + } + this.token('JS', (script = match[0]).slice(1, -1)); + this.i += script.length; + return true; + }; + Lexer.prototype.regexToken = function() { + var match, regex; + if (this.chunk.charAt(0) !== '/') { + return false; + } + if (match = HEREGEX.exec(this.chunk)) { + return this.heregexToken(match); + } + if (include(NOT_REGEX, this.tag())) { + return false; + } + if (!(match = REGEX.exec(this.chunk))) { + return false; + } + regex = match[0]; + this.token('REGEX', regex === '//' ? '/(?:)/' : regex); + this.i += regex.length; + return true; + }; + Lexer.prototype.heregexToken = function(match) { + var _i, _len, _ref2, _ref3, _ref4, _this, body, flags, heregex, re, tag, tokens, value; + heregex = match[0], body = match[1], flags = match[2]; + this.i += heregex.length; + if (0 > body.indexOf('#{')) { + re = body.replace(HEREGEX_OMIT, '').replace(/\//g, '\\/'); + this.token('REGEX', "/" + (re || '(?:)') + "/" + flags); + return true; + } + this.token('IDENTIFIER', 'RegExp'); + this.tokens.push(['CALL_START', '(']); + tokens = []; + for (_i = 0, _len = (_ref2 = this.interpolateString(body, { + regex: true + })).length; _i < _len; _i++) { + _ref3 = _ref2[_i], tag = _ref3[0], value = _ref3[1]; + if (tag === 'TOKENS') { + tokens.push.apply(tokens, value); + } else { + if (!(value = value.replace(HEREGEX_OMIT, ''))) { + continue; + } + value = value.replace(/\\/g, '\\\\'); + tokens.push(['STRING', this.makeString(value, '"', true)]); + } + tokens.push(['+', '+']); + } + tokens.pop(); + if ((((_ref4 = tokens[0]) != null) ? _ref4[0] : undefined) !== 'STRING') { + this.tokens.push(['STRING', '""'], ['+', '+']); + } + (_this = this.tokens).push.apply(_this, tokens); + if (flags) { + this.tokens.push([',', ','], ['STRING', '"' + flags + '"']); + } + this.token(')', ')'); + return true; + }; + Lexer.prototype.lineToken = function() { + var diff, indent, match, nextCharacter, noNewlines, prev, size; + if (!(match = MULTI_DENT.exec(this.chunk))) { + return false; + } + indent = match[0]; + this.line += count(indent, '\n'); + this.i += indent.length; + prev = last(this.tokens, 1); + size = indent.length - 1 - indent.lastIndexOf('\n'); + nextCharacter = NEXT_CHARACTER.exec(this.chunk)[1]; + noNewlines = ((nextCharacter === '.' || nextCharacter === ',') && !NEXT_ELLIPSIS.test(this.chunk)) || this.unfinished(); + if (size - this.indebt === this.indent) { + if (noNewlines) { + return this.suppressNewlines(); + } + return this.newlineToken(indent); + } else if (size > this.indent) { + if (noNewlines) { + this.indebt = size - this.indent; + return this.suppressNewlines(); + } + diff = size - this.indent + this.outdebt; + this.token('INDENT', diff); + this.indents.push(diff); + this.outdebt = (this.indebt = 0); + } else { + this.indebt = 0; + this.outdentToken(this.indent - size, noNewlines); + } + this.indent = size; + return true; + }; + Lexer.prototype.outdentToken = function(moveOut, noNewlines, close) { + var dent, len; + while (moveOut > 0) { + len = this.indents.length - 1; + if (this.indents[len] === undefined) { + moveOut = 0; + } else if (this.indents[len] === this.outdebt) { + moveOut -= this.outdebt; + this.outdebt = 0; + } else if (this.indents[len] < this.outdebt) { + this.outdebt -= this.indents[len]; + moveOut -= this.indents[len]; + } else { + dent = this.indents.pop() - this.outdebt; + moveOut -= dent; + this.outdebt = 0; + this.token('OUTDENT', dent); + } + } + if (dent) { + this.outdebt -= moveOut; + } + if (!(this.tag() === 'TERMINATOR' || noNewlines)) { + this.token('TERMINATOR', '\n'); + } + return true; + }; + Lexer.prototype.whitespaceToken = function() { + var match, prev; + if (!(match = WHITESPACE.exec(this.chunk))) { + return false; + } + prev = last(this.tokens); + if (prev) { + prev.spaced = true; + } + this.i += match[0].length; + return true; + }; + Lexer.prototype.newlineToken = function(newlines) { + if (this.tag() !== 'TERMINATOR') { + this.token('TERMINATOR', '\n'); + } + return true; + }; + Lexer.prototype.suppressNewlines = function() { + if (this.value() === '\\') { + this.tokens.pop(); + } + return true; + }; + Lexer.prototype.literalToken = function() { + var _ref2, match, prev, tag, value; + if (match = OPERATOR.exec(this.chunk)) { + value = match[0]; + if (CODE.test(value)) { + this.tagParameters(); + } + } else { + value = this.chunk.charAt(0); + } + this.i += value.length; + tag = value; + prev = last(this.tokens); + if (value === '=' && prev) { + if (!prev[1].reserved && include(JS_FORBIDDEN, prev[1])) { + this.assignmentError(); + } + if (((_ref2 = prev[1]) === '||' || _ref2 === '&&')) { + prev[0] = 'COMPOUND_ASSIGN'; + prev[1] += '='; + return true; + } + } + if (';' === value) { + tag = 'TERMINATOR'; + } else if (include(LOGIC, value)) { + tag = 'LOGIC'; + } else if (include(MATH, value)) { + tag = 'MATH'; + } else if (include(COMPARE, value)) { + tag = 'COMPARE'; + } else if (include(COMPOUND_ASSIGN, value)) { + tag = 'COMPOUND_ASSIGN'; + } else if (include(UNARY, value)) { + tag = 'UNARY'; + } else if (include(SHIFT, value)) { + tag = 'SHIFT'; + } else if (value === '?' && ((prev != null) ? prev.spaced : undefined)) { + tag = 'LOGIC'; + } else if (prev && !prev.spaced) { + if (value === '(' && include(CALLABLE, prev[0])) { + if (prev[0] === '?') { + prev[0] = 'FUNC_EXIST'; + } + tag = 'CALL_START'; + } else if (value === '[' && include(INDEXABLE, prev[0])) { + tag = 'INDEX_START'; + switch (prev[0]) { + case '?': + prev[0] = 'INDEX_SOAK'; + break; + case '::': + prev[0] = 'INDEX_PROTO'; + break; + } + } + } + this.token(tag, value); + return true; + }; + Lexer.prototype.tagAccessor = function() { + var prev; + if (!(prev = last(this.tokens)) || prev.spaced) { + return false; + } + if (prev[1] === '::') { + this.tag(0, 'PROTOTYPE_ACCESS'); + } else if (prev[1] === '.' && this.value(1) !== '.') { + if (this.tag(1) === '?') { + this.tag(0, 'SOAK_ACCESS'); + this.tokens.splice(-2, 1); + } else { + this.tag(0, 'PROPERTY_ACCESS'); + } + } else { + return prev[0] === '@'; + } + return true; + }; + Lexer.prototype.sanitizeHeredoc = function(doc, options) { + var _ref2, attempt, herecomment, indent, match; + indent = options.indent, herecomment = options.herecomment; + if (herecomment && 0 > doc.indexOf('\n')) { + return doc; + } + if (!herecomment) { + while (match = HEREDOC_INDENT.exec(doc)) { + attempt = match[1]; + if (indent === null || (0 < (_ref2 = attempt.length)) && (_ref2 < indent.length)) { + indent = attempt; + } + } + } + if (indent) { + doc = doc.replace(RegExp("\\n" + indent, "g"), '\n'); + } + if (!herecomment) { + doc = doc.replace(/^\n/, ''); + } + return doc; + }; + Lexer.prototype.tagParameters = function() { + var i, tok; + if (this.tag() !== ')') { + return; + } + i = this.tokens.length; + while (tok = this.tokens[--i]) { + switch (tok[0]) { + case 'IDENTIFIER': + tok[0] = 'PARAM'; + break; + case ')': + tok[0] = 'PARAM_END'; + break; + case '(': + case 'CALL_START': + tok[0] = 'PARAM_START'; + return true; + } + } + return true; + }; + Lexer.prototype.closeIndentation = function() { + return this.outdentToken(this.indent); + }; + Lexer.prototype.identifierError = function(word) { + throw SyntaxError("Reserved word \"" + word + "\" on line " + (this.line + 1)); + }; + Lexer.prototype.assignmentError = function() { + throw SyntaxError("Reserved word \"" + (this.value()) + "\" on line " + (this.line + 1) + " can't be assigned"); + }; + Lexer.prototype.balancedString = function(str, delimited, options) { + var _i, _len, close, i, levels, open, pair, slen; + options || (options = {}); + levels = []; + i = 0; + slen = str.length; + while (i < slen) { + if (levels.length && str.charAt(i) === '\\') { + i += 1; + } else { + for (_i = 0, _len = delimited.length; _i < _len; _i++) { + pair = delimited[_i]; + open = pair[0], close = pair[1]; + if (levels.length && starts(str, close, i) && last(levels) === pair) { + levels.pop(); + i += close.length - 1; + if (!levels.length) { + i += 1; + } + break; + } + if (starts(str, open, i)) { + levels.push(pair); + i += open.length - 1; + break; + } + } + } + if (!levels.length) { + break; + } + i += 1; + } + if (levels.length) { + throw SyntaxError("Unterminated " + (levels.pop()[0]) + " starting on line " + (this.line + 1)); + } + return !i ? false : str.slice(0, i); + }; + Lexer.prototype.interpolateString = function(str, options) { + var _len, _ref2, _ref3, _this, expr, heredoc, i, inner, interpolated, letter, nested, pi, regex, tag, tokens, value; + _ref2 = options || (options = {}), heredoc = _ref2.heredoc, regex = _ref2.regex; + tokens = []; + pi = 0; + i = -1; + while (letter = str.charAt(i += 1)) { + if (letter === '\\') { + i += 1; + continue; + } + if (!(letter === '#' && str.charAt(i + 1) === '{' && (expr = this.balancedString(str.slice(i + 1), [['{', '}']])))) { + continue; + } + if (pi < i) { + tokens.push(['TO_BE_STRING', str.slice(pi, i)]); + } + inner = expr.slice(1, -1).replace(LEADING_SPACES, '').replace(TRAILING_SPACES, ''); + if (inner.length) { + nested = new Lexer().tokenize(inner, { + line: this.line, + rewrite: false + }); + nested.pop(); + if (nested.length > 1) { + nested.unshift(['(', '(']); + nested.push([')', ')']); + } + tokens.push(['TOKENS', nested]); + } + i += expr.length; + pi = i + 1; + } + if ((i > pi) && (pi < str.length)) { + tokens.push(['TO_BE_STRING', str.slice(pi)]); + } + if (regex) { + return tokens; + } + if (!tokens.length) { + return this.token('STRING', '""'); + } + if (tokens[0][0] !== 'TO_BE_STRING') { + tokens.unshift(['', '']); + } + if (interpolated = tokens.length > 1) { + this.token('(', '('); + } + for (i = 0, _len = tokens.length; i < _len; i++) { + _ref3 = tokens[i], tag = _ref3[0], value = _ref3[1]; + if (i) { + this.token('+', '+'); + } + if (tag === 'TOKENS') { + (_this = this.tokens).push.apply(_this, value); + } else { + this.token('STRING', this.makeString(value, '"', heredoc)); + } + } + if (interpolated) { + this.token(')', ')'); + } + return tokens; + }; + Lexer.prototype.token = function(tag, value) { + return this.tokens.push([tag, value, this.line]); + }; + Lexer.prototype.tag = function(index, tag) { + var tok; + return (tok = last(this.tokens, index)) && ((tag != null) ? (tok[0] = tag) : tok[0]); + }; + Lexer.prototype.value = function(index, val) { + var tok; + return (tok = last(this.tokens, index)) && ((val != null) ? (tok[1] = val) : tok[1]); + }; + Lexer.prototype.unfinished = function() { + var prev, value; + return (prev = last(this.tokens, 1)) && prev[0] !== '.' && (value = this.value()) && !value.reserved && NO_NEWLINE.test(value) && !CODE.test(value) && !ASSIGNED.test(this.chunk); + }; + Lexer.prototype.escapeLines = function(str, heredoc) { + return str.replace(MULTILINER, heredoc ? '\\n' : ''); + }; + Lexer.prototype.makeString = function(body, quote, heredoc) { + if (!body) { + return quote + quote; + } + body = body.replace(/\\([\s\S])/g, function(match, contents) { + return (contents === '\n' || contents === quote) ? contents : match; + }); + body = body.replace(RegExp("" + quote, "g"), '\\$&'); + return quote + this.escapeLines(body, heredoc) + quote; + }; + return Lexer; + })(); + JS_KEYWORDS = ['true', 'false', 'null', 'this', 'new', 'delete', 'typeof', 'in', 'instanceof', 'return', 'throw', 'break', 'continue', 'debugger', 'if', 'else', 'switch', 'for', 'while', 'try', 'catch', 'finally', 'class', 'extends', 'super']; + COFFEE_KEYWORDS = ['then', 'unless', 'until', 'loop', 'of', 'by', 'when']; + for (op in (COFFEE_ALIASES = { + and: '&&', + or: '||', + is: '==', + isnt: '!=', + not: '!', + yes: 'TRUE', + no: 'FALSE', + on: 'TRUE', + off: 'FALSE' + })) { + COFFEE_KEYWORDS.push(op); + } + RESERVED = ['case', 'default', 'do', 'function', 'var', 'void', 'with', 'const', 'let', 'enum', 'export', 'import', 'native', '__hasProp', '__extends', '__slice']; + JS_FORBIDDEN = JS_KEYWORDS.concat(RESERVED); + IDENTIFIER = /^([$A-Za-z_][$\w]*)([^\n\S]*:(?!:))?/; + NUMBER = /^0x[\da-f]+|^(?:\d+(\.\d+)?|\.\d+)(?:e[+-]?\d+)?/i; + HEREDOC = /^("""|''')([\s\S]*?)(?:\n[ \t]*)?\1/; + OPERATOR = /^(?:-[-=>]?|\+[+=]?|\.\.\.?|[*&|\/%=<>^:!?]+)/; + WHITESPACE = /^[ \t]+/; + COMMENT = /^###([^#][\s\S]*?)(?:###[ \t]*\n|(?:###)?$)|^(?:\s*#(?!##[^#]).*)+/; + CODE = /^[-=]>/; + MULTI_DENT = /^(?:\n[ \t]*)+/; + SIMPLESTR = /^'[^\\']*(?:\\.[^\\']*)*'/; + JSTOKEN = /^`[^\\`]*(?:\\.[^\\`]*)*`/; + REGEX = /^\/(?!\s)[^[\/\n\\]*(?:(?:\\[\s\S]|\[[^\]\n\\]*(?:\\[\s\S][^\]\n\\]*)*])[^[\/\n\\]*)*\/[imgy]{0,4}(?![A-Za-z])/; + HEREGEX = /^\/{3}([\s\S]+?)\/{3}([imgy]{0,4})(?![A-Za-z])/; + HEREGEX_OMIT = /\s+(?:#.*)?/g; + MULTILINER = /\n/g; + HEREDOC_INDENT = /\n+([ \t]*)/g; + ASSIGNED = /^\s*@?[$A-Za-z_][$\w]*[ \t]*?[:=][^:=>]/; + NEXT_CHARACTER = /^\s*(\S?)/; + NEXT_ELLIPSIS = /^\s*\.\.\.?/; + LEADING_SPACES = /^\s+/; + TRAILING_SPACES = /\s+$/; + NO_NEWLINE = /^(?:[-+*&|\/%=<>!.\\][<>=&|]*|and|or|is(?:nt)?|n(?:ot|ew)|delete|typeof|instanceof)$/; + COMPOUND_ASSIGN = ['-=', '+=', '/=', '*=', '%=', '||=', '&&=', '?=', '<<=', '>>=', '>>>=', '&=', '^=', '|=']; + UNARY = ['UMINUS', 'UPLUS', '!', '!!', '~', 'NEW', 'TYPEOF', 'DELETE']; + LOGIC = ['&', '|', '^', '&&', '||']; + SHIFT = ['<<', '>>', '>>>']; + COMPARE = ['<=', '<', '>', '>=']; + MATH = ['*', '/', '%']; + RELATION = ['IN', 'OF', 'INSTANCEOF']; + BOOL = ['TRUE', 'FALSE', 'NULL']; + NOT_REGEX = ['NUMBER', 'REGEX', 'BOOL', '++', '--', ']']; + CALLABLE = ['IDENTIFIER', 'STRING', 'REGEX', ')', ']', '}', '?', '::', '@', 'THIS', 'SUPER']; + INDEXABLE = CALLABLE.concat('NUMBER', 'BOOL'); + LINE_BREAK = ['INDENT', 'OUTDENT', 'TERMINATOR']; +}).call(this); diff --git a/node_modules/jade/support/coffee-script/lib/nodes.js b/node_modules/jade/support/coffee-script/lib/nodes.js new file mode 100644 index 0000000..93d8012 --- /dev/null +++ b/node_modules/jade/support/coffee-script/lib/nodes.js @@ -0,0 +1,1981 @@ +(function() { + var Accessor, ArrayLiteral, Assign, Base, Call, Class, Closure, Code, Comment, Existence, Expressions, Extends, For, IDENTIFIER, IS_STRING, If, In, Index, Literal, NO, NUMBER, ObjectLiteral, Op, Param, Parens, Push, Range, Return, SIMPLENUM, Scope, Slice, Splat, Switch, TAB, THIS, TRAILING_WHITESPACE, Throw, Try, UTILITIES, Value, While, YES, _ref, compact, del, ends, flatten, include, last, merge, starts, utility; + var __extends = function(child, parent) { + function ctor() { this.constructor = child; } + ctor.prototype = parent.prototype; + child.prototype = new ctor; + if (typeof parent.extended === "function") parent.extended(child); + child.__super__ = parent.prototype; + }; + Scope = require('./scope').Scope; + _ref = require('./helpers'), compact = _ref.compact, flatten = _ref.flatten, merge = _ref.merge, del = _ref.del, include = _ref.include, starts = _ref.starts, ends = _ref.ends, last = _ref.last; + YES = function() { + return true; + }; + NO = function() { + return false; + }; + THIS = function() { + return this; + }; + exports.Base = (function() { + Base = (function() { + function Base() { + this.tags = {}; + return this; + }; + return Base; + })(); + Base.prototype.compile = function(o) { + var closure, code, top; + this.options = o ? merge(o) : {}; + this.tab = o.indent; + top = this.topSensitive() ? this.options.top : del(this.options, 'top'); + closure = this.isStatement(o) && !this.isPureStatement() && !top && !this.options.asStatement && !(this instanceof Comment); + code = closure ? this.compileClosure(this.options) : this.compileNode(this.options); + return code; + }; + Base.prototype.compileClosure = function(o) { + o.sharedScope = o.scope; + if (this.containsPureStatement()) { + throw new Error('cannot include a pure statement in an expression.'); + } + return Closure.wrap(this).compile(o); + }; + Base.prototype.compileReference = function(o, options) { + var _len, compiled, i, node, pair, reference; + pair = (function() { + if (!this.isComplex()) { + return [this, this]; + } else { + reference = new Literal(o.scope.freeVariable('ref')); + compiled = new Assign(reference, this); + return [compiled, reference]; + } + }).call(this); + if (((options != null) ? options.precompile : undefined)) { + for (i = 0, _len = pair.length; i < _len; i++) { + node = pair[i]; + (pair[i] = node.compile(o)); + } + } + return pair; + }; + Base.prototype.idt = function(tabs) { + var idt, num; + idt = this.tab || ''; + num = (tabs || 0) + 1; + while (num -= 1) { + idt += TAB; + } + return idt; + }; + Base.prototype.makeReturn = function() { + return new Return(this); + }; + Base.prototype.contains = function(block) { + var contains; + contains = false; + this.traverseChildren(false, function(node) { + if (block(node)) { + contains = true; + return false; + } + }); + return contains; + }; + Base.prototype.containsType = function(type) { + return this instanceof type || this.contains(function(node) { + return node instanceof type; + }); + }; + Base.prototype.containsPureStatement = function() { + return this.isPureStatement() || this.contains(function(node) { + return node.isPureStatement(); + }); + }; + Base.prototype.traverse = function(block) { + return this.traverseChildren(true, block); + }; + Base.prototype.toString = function(idt, override) { + var _i, _len, _ref2, _result, child, children, klass; + idt || (idt = ''); + children = (function() { + _result = []; + for (_i = 0, _len = (_ref2 = this.collectChildren()).length; _i < _len; _i++) { + child = _ref2[_i]; + _result.push(child.toString(idt + TAB)); + } + return _result; + }).call(this).join(''); + klass = override || this.constructor.name + (this.soakNode ? '?' : ''); + return '\n' + idt + klass + children; + }; + Base.prototype.eachChild = function(func) { + var _i, _j, _len, _len2, _ref2, _ref3, _result, attr, child; + if (!this.children) { + return; + } + _result = []; + for (_i = 0, _len = (_ref2 = this.children).length; _i < _len; _i++) { + attr = _ref2[_i]; + if (this[attr]) { + for (_j = 0, _len2 = (_ref3 = flatten([this[attr]])).length; _j < _len2; _j++) { + child = _ref3[_j]; + if (func(child) === false) { + return; + } + } + } + } + return _result; + }; + Base.prototype.collectChildren = function() { + var nodes; + nodes = []; + this.eachChild(function(node) { + return nodes.push(node); + }); + return nodes; + }; + Base.prototype.traverseChildren = function(crossScope, func) { + return this.eachChild(function(child) { + if (func(child) === false) { + return false; + } + return crossScope || !(child instanceof Code) ? child.traverseChildren(crossScope, func) : undefined; + }); + }; + Base.prototype.invert = function() { + return new Op('!', this); + }; + Base.prototype.children = []; + Base.prototype.unwrap = THIS; + Base.prototype.isStatement = NO; + Base.prototype.isPureStatement = NO; + Base.prototype.isComplex = YES; + Base.prototype.topSensitive = NO; + Base.prototype.unfoldSoak = NO; + Base.prototype.assigns = NO; + return Base; + })(); + exports.Expressions = (function() { + Expressions = (function() { + function Expressions(nodes) { + Expressions.__super__.constructor.call(this); + this.expressions = compact(flatten(nodes || [])); + return this; + }; + return Expressions; + })(); + __extends(Expressions, Base); + Expressions.prototype.children = ['expressions']; + Expressions.prototype.isStatement = YES; + Expressions.prototype.push = function(node) { + this.expressions.push(node); + return this; + }; + Expressions.prototype.unshift = function(node) { + this.expressions.unshift(node); + return this; + }; + Expressions.prototype.unwrap = function() { + return this.expressions.length === 1 ? this.expressions[0] : this; + }; + Expressions.prototype.empty = function() { + return this.expressions.length === 0; + }; + Expressions.prototype.makeReturn = function() { + var end, idx; + end = this.expressions[(idx = this.expressions.length - 1)]; + if (end instanceof Comment) { + end = this.expressions[idx -= 1]; + } + if (end && !(end instanceof Return)) { + this.expressions[idx] = end.makeReturn(); + } + return this; + }; + Expressions.prototype.compile = function(o) { + o || (o = {}); + return o.scope ? Expressions.__super__.compile.call(this, o) : this.compileRoot(o); + }; + Expressions.prototype.compileNode = function(o) { + var _i, _len, _ref2, _result, node; + return (function() { + _result = []; + for (_i = 0, _len = (_ref2 = this.expressions).length; _i < _len; _i++) { + node = _ref2[_i]; + _result.push(this.compileExpression(node, merge(o))); + } + return _result; + }).call(this).join('\n'); + }; + Expressions.prototype.compileRoot = function(o) { + var code; + o.indent = (this.tab = o.bare ? '' : TAB); + o.scope = new Scope(null, this, null); + code = this.compileWithDeclarations(o); + code = code.replace(TRAILING_WHITESPACE, ''); + return o.bare ? code : ("(function() {\n" + code + "\n}).call(this);\n"); + }; + Expressions.prototype.compileWithDeclarations = function(o) { + var code; + code = this.compileNode(o); + if (o.scope.hasAssignments(this)) { + code = ("" + (this.tab) + "var " + (o.scope.compiledAssignments().replace(/\n/g, '$&' + this.tab)) + ";\n" + code); + } + if (!o.globals && o.scope.hasDeclarations(this)) { + code = ("" + (this.tab) + "var " + (o.scope.compiledDeclarations()) + ";\n" + code); + } + return code; + }; + Expressions.prototype.compileExpression = function(node, o) { + var compiledNode; + this.tab = o.indent; + node.tags.front = true; + compiledNode = node.compile(merge(o, { + top: true + })); + return node.isStatement(o) ? compiledNode : ("" + (this.idt()) + compiledNode + ";"); + }; + return Expressions; + })(); + Expressions.wrap = function(nodes) { + if (nodes.length === 1 && nodes[0] instanceof Expressions) { + return nodes[0]; + } + return new Expressions(nodes); + }; + exports.Literal = (function() { + Literal = (function() { + function Literal(_arg) { + this.value = _arg; + Literal.__super__.constructor.call(this); + return this; + }; + return Literal; + })(); + __extends(Literal, Base); + Literal.prototype.makeReturn = function() { + return this.isStatement() ? this : Literal.__super__.makeReturn.call(this); + }; + Literal.prototype.isStatement = function() { + var _ref2; + return ((_ref2 = this.value) === 'break' || _ref2 === 'continue' || _ref2 === 'debugger'); + }; + Literal.prototype.isPureStatement = Literal.prototype.isStatement; + Literal.prototype.isComplex = NO; + Literal.prototype.isReserved = function() { + return !!this.value.reserved; + }; + Literal.prototype.assigns = function(name) { + return name === this.value; + }; + Literal.prototype.compileNode = function(o) { + var end, idt, val; + idt = this.isStatement(o) ? this.idt() : ''; + end = this.isStatement(o) ? ';' : ''; + val = this.isReserved() ? ("\"" + (this.value) + "\"") : this.value; + return idt + val + end; + }; + Literal.prototype.toString = function() { + return ' "' + this.value + '"'; + }; + return Literal; + })(); + exports.Return = (function() { + Return = (function() { + function Return(_arg) { + this.expression = _arg; + Return.__super__.constructor.call(this); + return this; + }; + return Return; + })(); + __extends(Return, Base); + Return.prototype.isStatement = YES; + Return.prototype.isPureStatement = YES; + Return.prototype.children = ['expression']; + Return.prototype.makeReturn = THIS; + Return.prototype.compile = function(o) { + var _ref2, expr; + expr = (((_ref2 = this.expression) != null) ? _ref2.makeReturn() : undefined); + if (expr && (!(expr instanceof Return))) { + return expr.compile(o); + } + return Return.__super__.compile.call(this, o); + }; + Return.prototype.compileNode = function(o) { + var expr; + expr = ''; + if (this.expression) { + if (this.expression.isStatement(o)) { + o.asStatement = true; + } + expr = ' ' + this.expression.compile(o); + } + return "" + (this.tab) + "return" + expr + ";"; + }; + return Return; + })(); + exports.Value = (function() { + Value = (function() { + function Value(_arg, _arg2, tag) { + this.properties = _arg2; + this.base = _arg; + Value.__super__.constructor.call(this); + this.properties || (this.properties = []); + if (tag) { + this.tags[tag] = true; + } + return this; + }; + return Value; + })(); + __extends(Value, Base); + Value.prototype.children = ['base', 'properties']; + Value.prototype.push = function(prop) { + this.properties.push(prop); + return this; + }; + Value.prototype.hasProperties = function() { + return !!this.properties.length; + }; + Value.prototype.isArray = function() { + return this.base instanceof ArrayLiteral && !this.properties.length; + }; + Value.prototype.isObject = function() { + return this.base instanceof ObjectLiteral && !this.properties.length; + }; + Value.prototype.isSplice = function() { + return last(this.properties) instanceof Slice; + }; + Value.prototype.isComplex = function() { + return this.base.isComplex() || this.hasProperties(); + }; + Value.prototype.assigns = function(name) { + return !this.properties.length && this.base.assigns(name); + }; + Value.prototype.makeReturn = function() { + return this.properties.length ? Value.__super__.makeReturn.call(this) : this.base.makeReturn(); + }; + Value.prototype.unwrap = function() { + return this.properties.length ? this : this.base; + }; + Value.prototype.isStatement = function(o) { + return this.base.isStatement(o) && !this.properties.length; + }; + Value.prototype.isSimpleNumber = function() { + return this.base instanceof Literal && SIMPLENUM.test(this.base.value); + }; + Value.prototype.cacheReference = function(o) { + var base, bref, name, nref; + name = last(this.properties); + if (!this.base.isComplex() && this.properties.length < 2 && !((name != null) ? name.isComplex() : undefined)) { + return [this, this]; + } + base = new Value(this.base, this.properties.slice(0, -1)); + if (base.isComplex()) { + bref = new Literal(o.scope.freeVariable('base')); + base = new Value(new Parens(new Assign(bref, base))); + } + if (!name) { + return [base, bref]; + } + if (name.isComplex()) { + nref = new Literal(o.scope.freeVariable('name')); + name = new Index(new Assign(nref, name.index)); + nref = new Index(nref); + } + return [base.push(name), new Value(bref || base.base, [nref || name])]; + }; + Value.prototype.compile = function(o) { + this.base.tags.front = this.tags.front; + return !o.top || this.properties.length ? Value.__super__.compile.call(this, o) : this.base.compile(o); + }; + Value.prototype.compileNode = function(o) { + var _i, _len, code, ifn, prop, props; + if (ifn = this.unfoldSoak(o)) { + return ifn.compile(o); + } + props = this.properties; + if (this.parenthetical && !props.length) { + this.base.parenthetical = true; + } + code = this.base.compile(o); + if (props[0] instanceof Accessor && this.isSimpleNumber()) { + code = ("(" + code + ")"); + } + for (_i = 0, _len = props.length; _i < _len; _i++) { + prop = props[_i]; + (code += prop.compile(o)); + } + return code; + }; + Value.prototype.unfoldSoak = function(o) { + var _len, _ref2, fst, i, ifn, prop, ref, snd; + if (ifn = this.base.unfoldSoak(o)) { + Array.prototype.push.apply(ifn.body.properties, this.properties); + return ifn; + } + for (i = 0, _len = (_ref2 = this.properties).length; i < _len; i++) { + prop = _ref2[i]; + if (prop.soakNode) { + prop.soakNode = false; + fst = new Value(this.base, this.properties.slice(0, i)); + snd = new Value(this.base, this.properties.slice(i)); + if (fst.isComplex()) { + ref = new Literal(o.scope.freeVariable('ref')); + fst = new Parens(new Assign(ref, fst)); + snd.base = ref; + } + ifn = new If(new Existence(fst), snd, { + soak: true + }); + return ifn; + } + } + return null; + }; + return Value; + })(); + exports.Comment = (function() { + Comment = (function() { + function Comment(_arg) { + this.comment = _arg; + Comment.__super__.constructor.call(this); + return this; + }; + return Comment; + })(); + __extends(Comment, Base); + Comment.prototype.isStatement = YES; + Comment.prototype.makeReturn = THIS; + Comment.prototype.compileNode = function(o) { + return this.tab + '/*' + this.comment.replace(/\n/g, '\n' + this.tab) + '*/'; + }; + return Comment; + })(); + exports.Call = (function() { + Call = (function() { + function Call(variable, _arg, _arg2) { + this.soakNode = _arg2; + this.args = _arg; + Call.__super__.constructor.call(this); + this.isNew = false; + this.isSuper = variable === 'super'; + this.variable = this.isSuper ? null : variable; + this.args || (this.args = []); + return this; + }; + return Call; + })(); + __extends(Call, Base); + Call.prototype.children = ['variable', 'args']; + Call.prototype.compileSplatArguments = function(o) { + return Splat.compileSplattedArray(this.args, o); + }; + Call.prototype.newInstance = function() { + this.isNew = true; + return this; + }; + Call.prototype.prefix = function() { + return this.isNew ? 'new ' : ''; + }; + Call.prototype.superReference = function(o) { + var method, name; + method = o.scope.method; + if (!method) { + throw Error("cannot call super outside of a function."); + } + name = method.name; + if (!name) { + throw Error("cannot call super on an anonymous function."); + } + return method.klass ? ("" + (method.klass) + ".__super__." + name) : ("" + name + ".__super__.constructor"); + }; + Call.prototype.unfoldSoak = function(o) { + var _i, _len, _ref2, _ref3, call, ifn, left, list, rite, val; + if (this.soakNode) { + if (val = this.variable) { + if (!(val instanceof Value)) { + val = new Value(val); + } + _ref2 = val.cacheReference(o), left = _ref2[0], rite = _ref2[1]; + } else { + left = new Literal(this.superReference(o)); + rite = new Value(left); + } + rite = new Call(rite, this.args); + rite.isNew = this.isNew; + left = new Literal("typeof " + (left.compile(o)) + " === \"function\""); + ifn = new If(left, new Value(rite), { + soak: true + }); + return ifn; + } + call = this; + list = []; + while (true) { + if (call.variable instanceof Call) { + list.push(call); + call = call.variable; + continue; + } + if (!(call.variable instanceof Value)) { + break; + } + list.push(call); + if (!((call = call.variable.base) instanceof Call)) { + break; + } + } + for (_i = 0, _len = (_ref3 = list.reverse()).length; _i < _len; _i++) { + call = _ref3[_i]; + if (ifn) { + if (call.variable instanceof Call) { + call.variable = ifn; + } else { + call.variable.base = ifn; + } + } + ifn = If.unfoldSoak(o, call, 'variable'); + } + return ifn; + }; + Call.prototype.compileNode = function(o) { + var _i, _j, _len, _len2, _ref2, _ref3, _ref4, _result, arg, args, ifn; + if (ifn = this.unfoldSoak(o)) { + return ifn.compile(o); + } + (((_ref2 = this.variable) != null) ? (_ref2.tags.front = this.tags.front) : undefined); + for (_i = 0, _len = (_ref3 = this.args).length; _i < _len; _i++) { + arg = _ref3[_i]; + if (arg instanceof Splat) { + return this.compileSplat(o); + } + } + args = (function() { + _result = []; + for (_j = 0, _len2 = (_ref4 = this.args).length; _j < _len2; _j++) { + arg = _ref4[_j]; + _result.push((arg.parenthetical = true) && arg.compile(o)); + } + return _result; + }).call(this).join(', '); + return this.isSuper ? this.compileSuper(args, o) : ("" + (this.prefix()) + (this.variable.compile(o)) + "(" + args + ")"); + }; + Call.prototype.compileSuper = function(args, o) { + return "" + (this.superReference(o)) + ".call(this" + (args.length ? ', ' : '') + args + ")"; + }; + Call.prototype.compileSplat = function(o) { + var base, fun, idt, name, ref, splatargs; + splatargs = this.compileSplatArguments(o); + if (this.isSuper) { + return ("" + (this.superReference(o)) + ".apply(this, " + splatargs + ")"); + } + if (!this.isNew) { + if (!((base = this.variable) instanceof Value)) { + base = new Value(base); + } + if ((name = base.properties.pop()) && base.isComplex()) { + ref = o.scope.freeVariable('this'); + fun = ("(" + ref + " = " + (base.compile(o)) + ")" + (name.compile(o))); + } else { + fun = (ref = base.compile(o)); + if (name) { + fun += name.compile(o); + } + } + return ("" + fun + ".apply(" + ref + ", " + splatargs + ")"); + } + idt = this.idt(1); + return "(function(func, args, ctor) {\n" + idt + "ctor.prototype = func.prototype;\n" + idt + "var child = new ctor, result = func.apply(child, args);\n" + idt + "return typeof result === \"object\" ? result : child;\n" + (this.tab) + "})(" + (this.variable.compile(o)) + ", " + splatargs + ", function() {})"; + }; + return Call; + })(); + exports.Extends = (function() { + Extends = (function() { + function Extends(_arg, _arg2) { + this.parent = _arg2; + this.child = _arg; + Extends.__super__.constructor.call(this); + return this; + }; + return Extends; + })(); + __extends(Extends, Base); + Extends.prototype.children = ['child', 'parent']; + Extends.prototype.compileNode = function(o) { + var ref; + ref = new Value(new Literal(utility('extends'))); + return (new Call(ref, [this.child, this.parent])).compile(o); + }; + return Extends; + })(); + exports.Accessor = (function() { + Accessor = (function() { + function Accessor(_arg, tag) { + this.name = _arg; + Accessor.__super__.constructor.call(this); + this.prototype = tag === 'prototype' ? '.prototype' : ''; + this.soakNode = tag === 'soak'; + return this; + }; + return Accessor; + })(); + __extends(Accessor, Base); + Accessor.prototype.children = ['name']; + Accessor.prototype.compileNode = function(o) { + var name, namePart; + name = this.name.compile(o); + namePart = name.match(IS_STRING) ? ("[" + name + "]") : ("." + name); + return this.prototype + namePart; + }; + Accessor.prototype.isComplex = NO; + return Accessor; + })(); + exports.Index = (function() { + Index = (function() { + function Index(_arg) { + this.index = _arg; + Index.__super__.constructor.call(this); + return this; + }; + return Index; + })(); + __extends(Index, Base); + Index.prototype.children = ['index']; + Index.prototype.compileNode = function(o) { + var idx, prefix; + idx = this.index.compile(o); + prefix = this.proto ? '.prototype' : ''; + return "" + prefix + "[" + idx + "]"; + }; + Index.prototype.isComplex = function() { + return this.index.isComplex(); + }; + return Index; + })(); + exports.Range = (function() { + Range = (function() { + function Range(_arg, _arg2, tag) { + this.to = _arg2; + this.from = _arg; + Range.__super__.constructor.call(this); + this.exclusive = tag === 'exclusive'; + this.equals = this.exclusive ? '' : '='; + return this; + }; + return Range; + })(); + __extends(Range, Base); + Range.prototype.children = ['from', 'to']; + Range.prototype.compileVariables = function(o) { + var _ref2, _ref3, _ref4, parts; + o = merge(o, { + top: true + }); + _ref2 = this.from.compileReference(o, { + precompile: true + }), this.from = _ref2[0], this.fromVar = _ref2[1]; + _ref3 = this.to.compileReference(o, { + precompile: true + }), this.to = _ref3[0], this.toVar = _ref3[1]; + _ref4 = [this.fromVar.match(SIMPLENUM), this.toVar.match(SIMPLENUM)], this.fromNum = _ref4[0], this.toNum = _ref4[1]; + parts = []; + if (this.from !== this.fromVar) { + parts.push(this.from); + } + return this.to !== this.toVar ? parts.push(this.to) : undefined; + }; + Range.prototype.compileNode = function(o) { + var compare, idx, incr, intro, step, stepPart, vars; + this.compileVariables(o); + if (!o.index) { + return this.compileArray(o); + } + if (this.fromNum && this.toNum) { + return this.compileSimple(o); + } + idx = del(o, 'index'); + step = del(o, 'step'); + vars = ("" + idx + " = " + (this.from)) + (this.to !== this.toVar ? (", " + (this.to)) : ''); + intro = ("(" + (this.fromVar) + " <= " + (this.toVar) + " ? " + idx); + compare = ("" + intro + " <" + (this.equals) + " " + (this.toVar) + " : " + idx + " >" + (this.equals) + " " + (this.toVar) + ")"); + stepPart = step ? step.compile(o) : '1'; + incr = step ? ("" + idx + " += " + stepPart) : ("" + intro + " += " + stepPart + " : " + idx + " -= " + stepPart + ")"); + return "" + vars + "; " + compare + "; " + incr; + }; + Range.prototype.compileSimple = function(o) { + var _ref2, from, idx, step, to; + _ref2 = [+this.fromNum, +this.toNum], from = _ref2[0], to = _ref2[1]; + idx = del(o, 'index'); + step = del(o, 'step'); + step && (step = ("" + idx + " += " + (step.compile(o)))); + return from <= to ? ("" + idx + " = " + from + "; " + idx + " <" + (this.equals) + " " + to + "; " + (step || ("" + idx + "++"))) : ("" + idx + " = " + from + "; " + idx + " >" + (this.equals) + " " + to + "; " + (step || ("" + idx + "--"))); + }; + Range.prototype.compileArray = function(o) { + var _i, _ref2, _ref3, _result, body, clause, i, idt, post, pre, range, result, vars; + if (this.fromNum && this.toNum && (Math.abs(this.fromNum - this.toNum) <= 20)) { + range = (function() { + _result = []; + for (var _i = _ref2 = +this.fromNum, _ref3 = +this.toNum; _ref2 <= _ref3 ? _i <= _ref3 : _i >= _ref3; _ref2 <= _ref3 ? _i += 1 : _i -= 1){ _result.push(_i); } + return _result; + }).call(this); + if (this.exclusive) { + range.pop(); + } + return ("[" + (range.join(', ')) + "]"); + } + idt = this.idt(1); + i = o.scope.freeVariable('i'); + result = o.scope.freeVariable('result'); + pre = ("\n" + idt + result + " = [];"); + if (this.fromNum && this.toNum) { + o.index = i; + body = this.compileSimple(o); + } else { + vars = ("" + i + " = " + (this.from)) + (this.to !== this.toVar ? (", " + (this.to)) : ''); + clause = ("" + (this.fromVar) + " <= " + (this.toVar) + " ?"); + body = ("var " + vars + "; " + clause + " " + i + " <" + (this.equals) + " " + (this.toVar) + " : " + i + " >" + (this.equals) + " " + (this.toVar) + "; " + clause + " " + i + " += 1 : " + i + " -= 1"); + } + post = ("{ " + result + ".push(" + i + "); }\n" + idt + "return " + result + ";\n" + (o.indent)); + return "(function() {" + pre + "\n" + idt + "for (" + body + ")" + post + "}).call(this)"; + }; + return Range; + })(); + exports.Slice = (function() { + Slice = (function() { + function Slice(_arg) { + this.range = _arg; + Slice.__super__.constructor.call(this); + return this; + }; + return Slice; + })(); + __extends(Slice, Base); + Slice.prototype.children = ['range']; + Slice.prototype.compileNode = function(o) { + var from, to; + from = this.range.from ? this.range.from.compile(o) : '0'; + to = this.range.to ? this.range.to.compile(o) : ''; + to += (!to || this.range.exclusive ? '' : ' + 1'); + if (to) { + to = ', ' + to; + } + return ".slice(" + from + to + ")"; + }; + return Slice; + })(); + exports.ObjectLiteral = (function() { + ObjectLiteral = (function() { + function ObjectLiteral(props) { + ObjectLiteral.__super__.constructor.call(this); + this.objects = (this.properties = props || []); + return this; + }; + return ObjectLiteral; + })(); + __extends(ObjectLiteral, Base); + ObjectLiteral.prototype.children = ['properties']; + ObjectLiteral.prototype.compileNode = function(o) { + var _i, _len, _ref2, _result, i, indent, join, lastNoncom, nonComments, obj, prop, props, top; + top = del(o, 'top'); + o.indent = this.idt(1); + nonComments = (function() { + _result = []; + for (_i = 0, _len = (_ref2 = this.properties).length; _i < _len; _i++) { + prop = _ref2[_i]; + if (!(prop instanceof Comment)) { + _result.push(prop); + } + } + return _result; + }).call(this); + lastNoncom = last(nonComments); + props = (function() { + _result = []; + for (i = 0, _len = (_ref2 = this.properties).length; i < _len; i++) { + prop = _ref2[i]; + _result.push((function() { + join = i === this.properties.length - 1 ? '' : (prop === lastNoncom || prop instanceof Comment ? '\n' : ',\n'); + indent = prop instanceof Comment ? '' : this.idt(1); + if (prop instanceof Value && prop.tags["this"]) { + prop = new Assign(prop.properties[0].name, prop, 'object'); + } else if (!(prop instanceof Assign) && !(prop instanceof Comment)) { + prop = new Assign(prop, prop, 'object'); + } + return indent + prop.compile(o) + join; + }).call(this)); + } + return _result; + }).call(this); + props = props.join(''); + obj = ("{" + (props ? '\n' + props + '\n' + this.idt() : '') + "}"); + return this.tags.front ? ("(" + obj + ")") : obj; + }; + ObjectLiteral.prototype.assigns = function(name) { + var _i, _len, _ref2, prop; + for (_i = 0, _len = (_ref2 = this.properties).length; _i < _len; _i++) { + prop = _ref2[_i]; + if (prop.assigns(name)) { + return true; + } + } + return false; + }; + return ObjectLiteral; + })(); + exports.ArrayLiteral = (function() { + ArrayLiteral = (function() { + function ArrayLiteral(_arg) { + this.objects = _arg; + ArrayLiteral.__super__.constructor.call(this); + this.objects || (this.objects = []); + return this; + }; + return ArrayLiteral; + })(); + __extends(ArrayLiteral, Base); + ArrayLiteral.prototype.children = ['objects']; + ArrayLiteral.prototype.compileSplatLiteral = function(o) { + return Splat.compileSplattedArray(this.objects, o); + }; + ArrayLiteral.prototype.compileNode = function(o) { + var _i, _len, _len2, _ref2, _ref3, code, i, obj, objects; + o.indent = this.idt(1); + for (_i = 0, _len = (_ref2 = this.objects).length; _i < _len; _i++) { + obj = _ref2[_i]; + if (obj instanceof Splat) { + return this.compileSplatLiteral(o); + } + } + objects = []; + for (i = 0, _len2 = (_ref3 = this.objects).length; i < _len2; i++) { + obj = _ref3[i]; + code = obj.compile(o); + objects.push(obj instanceof Comment ? ("\n" + code + "\n" + (o.indent)) : (i === this.objects.length - 1 ? code : code + ', ')); + } + objects = objects.join(''); + return 0 < objects.indexOf('\n') ? ("[\n" + (o.indent) + objects + "\n" + (this.tab) + "]") : ("[" + objects + "]"); + }; + ArrayLiteral.prototype.assigns = function(name) { + var _i, _len, _ref2, obj; + for (_i = 0, _len = (_ref2 = this.objects).length; _i < _len; _i++) { + obj = _ref2[_i]; + if (obj.assigns(name)) { + return true; + } + } + return false; + }; + return ArrayLiteral; + })(); + exports.Class = (function() { + Class = (function() { + function Class(variable, _arg, _arg2) { + this.properties = _arg2; + this.parent = _arg; + Class.__super__.constructor.call(this); + this.variable = variable === '__temp__' ? new Literal(variable) : variable; + this.properties || (this.properties = []); + this.returns = false; + return this; + }; + return Class; + })(); + __extends(Class, Base); + Class.prototype.children = ['variable', 'parent', 'properties']; + Class.prototype.isStatement = YES; + Class.prototype.makeReturn = function() { + this.returns = true; + return this; + }; + Class.prototype.compileNode = function(o) { + var _i, _len, _ref2, _ref3, _ref4, access, applied, apply, className, constScope, construct, constructor, extension, func, me, pname, prop, props, pvar, ref, returns, val, variable; + variable = this.variable; + if (variable.value === '__temp__') { + variable = new Literal(o.scope.freeVariable('ctor')); + } + extension = this.parent && new Extends(variable, this.parent); + props = new Expressions; + o.top = true; + me = null; + className = variable.compile(o); + constScope = null; + if (this.parent) { + applied = new Value(this.parent, [new Accessor(new Literal('apply'))]); + constructor = new Code([], new Expressions([new Call(applied, [new Literal('this'), new Literal('arguments')])])); + } else { + constructor = new Code([], new Expressions([new Return(new Literal('this'))])); + } + for (_i = 0, _len = (_ref2 = this.properties).length; _i < _len; _i++) { + prop = _ref2[_i]; + _ref3 = [prop.variable, prop.value], pvar = _ref3[0], func = _ref3[1]; + if (pvar && pvar.base.value === 'constructor') { + if (!(func instanceof Code)) { + _ref4 = func.compileReference(o), func = _ref4[0], ref = _ref4[1]; + if (func !== ref) { + props.push(func); + } + apply = new Call(new Value(ref, [new Accessor(new Literal('apply'))]), [new Literal('this'), new Literal('arguments')]); + func = new Code([], new Expressions([apply])); + } + if (func.bound) { + throw new Error("cannot define a constructor as a bound function."); + } + func.name = className; + func.body.push(new Return(new Literal('this'))); + variable = new Value(variable); + variable.namespaced = 0 < className.indexOf('.'); + constructor = func; + if (props.expressions[props.expressions.length - 1] instanceof Comment) { + constructor.comment = props.expressions.pop(); + } + continue; + } + if (func instanceof Code && func.bound) { + if (prop.context === 'this') { + func.context = className; + } else { + func.bound = false; + constScope || (constScope = new Scope(o.scope, constructor.body, constructor)); + me || (me = constScope.freeVariable('this')); + pname = pvar.compile(o); + if (constructor.body.empty()) { + constructor.body.push(new Return(new Literal('this'))); + } + constructor.body.unshift(new Literal("this." + pname + " = function(){ return " + className + ".prototype." + pname + ".apply(" + me + ", arguments); }")); + } + } + if (pvar) { + access = prop.context === 'this' ? pvar.base.properties[0] : new Accessor(pvar, 'prototype'); + val = new Value(variable, [access]); + prop = new Assign(val, func); + } + props.push(prop); + } + constructor.className = className.match(/[\w\d\$_]+$/); + if (me) { + constructor.body.unshift(new Literal("" + me + " = this")); + } + construct = this.idt() + new Assign(variable, constructor).compile(merge(o, { + sharedScope: constScope + })) + ';'; + props = !props.empty() ? '\n' + props.compile(o) : ''; + extension = extension ? '\n' + this.idt() + extension.compile(o) + ';' : ''; + returns = this.returns ? '\n' + new Return(variable).compile(o) : ''; + return construct + extension + props + returns; + }; + return Class; + })(); + exports.Assign = (function() { + Assign = (function() { + function Assign(_arg, _arg2, _arg3) { + this.context = _arg3; + this.value = _arg2; + this.variable = _arg; + Assign.__super__.constructor.call(this); + return this; + }; + return Assign; + })(); + __extends(Assign, Base); + Assign.prototype.METHOD_DEF = /^(?:(\S+)\.prototype\.)?([$A-Za-z_][$\w]*)$/; + Assign.prototype.children = ['variable', 'value']; + Assign.prototype.topSensitive = YES; + Assign.prototype.isValue = function() { + return this.variable instanceof Value; + }; + Assign.prototype.compileNode = function(o) { + var ifn, isValue, match, name, stmt, top, val; + if (isValue = this.isValue()) { + if (this.variable.isArray() || this.variable.isObject()) { + return this.compilePatternMatch(o); + } + if (this.variable.isSplice()) { + return this.compileSplice(o); + } + if (ifn = If.unfoldSoak(o, this, 'variable')) { + delete o.top; + return ifn.compile(o); + } + } + top = del(o, 'top'); + stmt = del(o, 'asStatement'); + name = this.variable.compile(o); + if (this.value instanceof Code && (match = this.METHOD_DEF.exec(name))) { + this.value.name = match[2]; + this.value.klass = match[1]; + } + val = this.value.compile(o); + if (this.context === 'object') { + return ("" + name + ": " + val); + } + if (!(isValue && (this.variable.hasProperties() || this.variable.namespaced))) { + o.scope.find(name); + } + val = ("" + name + " = " + val); + if (stmt) { + return ("" + (this.tab) + val + ";"); + } + return top || this.parenthetical ? val : ("(" + val + ")"); + }; + Assign.prototype.compilePatternMatch = function(o) { + var _len, _ref2, _ref3, accessClass, assigns, code, i, idx, isObject, obj, objects, olength, otop, ref, splat, top, val, valVar, value; + if ((value = this.value).isStatement(o)) { + value = Closure.wrap(value); + } + objects = this.variable.base.objects; + if (!(olength = objects.length)) { + return value.compile(o); + } + isObject = this.variable.isObject(); + if (o.top && olength === 1 && !((obj = objects[0]) instanceof Splat)) { + if (obj instanceof Assign) { + _ref2 = obj, idx = _ref2.variable.base, obj = _ref2.value; + } else { + idx = isObject ? (obj.tags["this"] ? obj.properties[0].name : obj) : new Literal(0); + } + if (!(value instanceof Value)) { + value = new Value(value); + } + accessClass = IDENTIFIER.test(idx.value) ? Accessor : Index; + value.properties.push(new accessClass(idx)); + return new Assign(obj, value).compile(o); + } + top = del(o, 'top'); + otop = merge(o, { + top: true + }); + valVar = value.compile(o); + assigns = []; + splat = false; + if (!IDENTIFIER.test(valVar) || this.variable.assigns(valVar)) { + assigns.push("" + (ref = o.scope.freeVariable('ref')) + " = " + valVar); + valVar = ref; + } + for (i = 0, _len = objects.length; i < _len; i++) { + obj = objects[i]; + idx = i; + if (isObject) { + if (obj instanceof Assign) { + _ref3 = obj, idx = _ref3.variable.base, obj = _ref3.value; + } else { + idx = obj.tags["this"] ? obj.properties[0].name : obj; + } + } + if (!(obj instanceof Value || obj instanceof Splat)) { + throw new Error('pattern matching must use only identifiers on the left-hand side.'); + } + accessClass = isObject && IDENTIFIER.test(idx.value) ? Accessor : Index; + if (!splat && obj instanceof Splat) { + val = new Literal(obj.compileValue(o, valVar, i, olength - i - 1)); + splat = true; + } else { + if (typeof idx !== 'object') { + idx = new Literal(splat ? ("" + valVar + ".length - " + (olength - idx)) : idx); + } + val = new Value(new Literal(valVar), [new accessClass(idx)]); + } + assigns.push(new Assign(obj, val).compile(otop)); + } + if (!top) { + assigns.push(valVar); + } + code = assigns.join(', '); + return top || this.parenthetical ? code : ("(" + code + ")"); + }; + Assign.prototype.compileSplice = function(o) { + var from, name, plus, range, ref, to, val; + range = this.variable.properties.pop().range; + name = this.variable.compile(o); + plus = range.exclusive ? '' : ' + 1'; + from = range.from ? range.from.compile(o) : '0'; + to = range.to ? range.to.compile(o) + ' - ' + from + plus : ("" + name + ".length"); + ref = o.scope.freeVariable('ref'); + val = this.value.compile(o); + return "([].splice.apply(" + name + ", [" + from + ", " + to + "].concat(" + ref + " = " + val + ")), " + ref + ")"; + }; + Assign.prototype.assigns = function(name) { + return this[this.context === 'object' ? 'value' : 'variable'].assigns(name); + }; + return Assign; + })(); + exports.Code = (function() { + Code = (function() { + function Code(_arg, _arg2, tag) { + this.body = _arg2; + this.params = _arg; + Code.__super__.constructor.call(this); + this.params || (this.params = []); + this.body || (this.body = new Expressions); + this.bound = tag === 'boundfunc'; + if (this.bound) { + this.context = 'this'; + } + return this; + }; + return Code; + })(); + __extends(Code, Base); + Code.prototype.children = ['params', 'body']; + Code.prototype.compileNode = function(o) { + var _i, _len, _len2, _ref2, _ref3, _result, close, code, comm, empty, func, i, open, param, params, sharedScope, splat, top, value; + sharedScope = del(o, 'sharedScope'); + top = del(o, 'top'); + o.scope = sharedScope || new Scope(o.scope, this.body, this); + o.top = true; + o.indent = this.idt(1); + empty = this.body.expressions.length === 0; + delete o.bare; + delete o.globals; + splat = undefined; + params = []; + for (i = 0, _len = (_ref2 = this.params).length; i < _len; i++) { + param = _ref2[i]; + if (splat) { + if (param.attach) { + param.assign = new Assign(new Value(new Literal('this'), [new Accessor(param.value)])); + this.body.expressions.splice(splat.index + 1, 0, param.assign); + } + splat.trailings.push(param); + } else { + if (param.attach) { + value = param.value; + _ref3 = [new Literal(o.scope.freeVariable('arg')), param.splat], param = _ref3[0], param.splat = _ref3[1]; + this.body.unshift(new Assign(new Value(new Literal('this'), [new Accessor(value)]), param)); + } + if (param.splat) { + splat = new Splat(param.value); + splat.index = i; + splat.trailings = []; + splat.arglength = this.params.length; + this.body.unshift(splat); + } else { + params.push(param); + } + } + } + o.scope.startLevel(); + params = (function() { + _result = []; + for (_i = 0, _len2 = params.length; _i < _len2; _i++) { + param = params[_i]; + _result.push(param.compile(o)); + } + return _result; + })(); + if (!(empty || this.noReturn)) { + this.body.makeReturn(); + } + for (_i = 0, _len2 = params.length; _i < _len2; _i++) { + param = params[_i]; + (o.scope.parameter(param)); + } + comm = this.comment ? this.comment.compile(o) + '\n' : ''; + if (this.className) { + o.indent = this.idt(2); + } + code = this.body.expressions.length ? ("\n" + (this.body.compileWithDeclarations(o)) + "\n") : ''; + open = this.className ? ("(function() {\n" + comm + (this.idt(1)) + "function " + (this.className) + "(") : "function("; + close = this.className ? ("" + (code && this.idt(1)) + "};\n" + (this.idt(1)) + "return " + (this.className) + ";\n" + (this.tab) + "})()") : ("" + (code && this.tab) + "}"); + func = ("" + open + (params.join(', ')) + ") {" + code + close); + o.scope.endLevel(); + if (this.bound) { + return ("" + (utility('bind')) + "(" + func + ", " + (this.context) + ")"); + } + return this.tags.front ? ("(" + func + ")") : func; + }; + Code.prototype.traverseChildren = function(crossScope, func) { + return crossScope ? Code.__super__.traverseChildren.call(this, crossScope, func) : undefined; + }; + return Code; + })(); + exports.Param = (function() { + Param = (function() { + function Param(_arg, _arg2, _arg3) { + this.splat = _arg3; + this.attach = _arg2; + this.name = _arg; + Param.__super__.constructor.call(this); + this.value = new Literal(this.name); + return this; + }; + return Param; + })(); + __extends(Param, Base); + Param.prototype.children = ['name']; + Param.prototype.compileNode = function(o) { + return this.value.compile(o); + }; + Param.prototype.toString = function() { + var name; + name = this.name; + if (this.attach) { + name = '@' + name; + } + if (this.splat) { + name += '...'; + } + return new Literal(name).toString(); + }; + return Param; + })(); + exports.Splat = (function() { + Splat = (function() { + function Splat(name) { + Splat.__super__.constructor.call(this); + this.name = name.compile ? name : new Literal(name); + return this; + }; + return Splat; + })(); + __extends(Splat, Base); + Splat.prototype.children = ['name']; + Splat.prototype.assigns = function(name) { + return this.name.assigns(name); + }; + Splat.prototype.compileNode = function(o) { + return (this.index != null) ? this.compileParam(o) : this.name.compile(o); + }; + Splat.prototype.compileParam = function(o) { + var _len, _ref2, assign, end, idx, len, name, pos, trailing, variadic; + name = this.name.compile(o); + o.scope.find(name); + end = ''; + if (this.trailings.length) { + len = o.scope.freeVariable('len'); + o.scope.assign(len, "arguments.length"); + variadic = o.scope.freeVariable('result'); + o.scope.assign(variadic, len + ' >= ' + this.arglength); + end = this.trailings.length ? (", " + len + " - " + (this.trailings.length)) : undefined; + for (idx = 0, _len = (_ref2 = this.trailings).length; idx < _len; idx++) { + trailing = _ref2[idx]; + if (trailing.attach) { + assign = trailing.assign; + trailing = new Literal(o.scope.freeVariable('arg')); + assign.value = trailing; + } + pos = this.trailings.length - idx; + o.scope.assign(trailing.compile(o), "arguments[" + variadic + " ? " + len + " - " + pos + " : " + (this.index + idx) + "]"); + } + } + return "" + name + " = " + (utility('slice')) + ".call(arguments, " + (this.index) + end + ")"; + }; + Splat.prototype.compileValue = function(o, name, index, trailings) { + var trail; + trail = trailings ? (", " + name + ".length - " + trailings) : ''; + return "" + (utility('slice')) + ".call(" + name + ", " + index + trail + ")"; + }; + Splat.compileSplattedArray = function(list, o) { + var _len, arg, args, code, end, i, prev; + args = []; + end = -1; + for (i = 0, _len = list.length; i < _len; i++) { + arg = list[i]; + code = arg.compile(o); + prev = args[end]; + if (!(arg instanceof Splat)) { + if (prev && starts(prev, '[') && ends(prev, ']')) { + args[end] = ("" + (prev.slice(0, -1)) + ", " + code + "]"); + continue; + } + if (prev && starts(prev, '.concat([') && ends(prev, '])')) { + args[end] = ("" + (prev.slice(0, -2)) + ", " + code + "])"); + continue; + } + code = ("[" + code + "]"); + } + args[++end] = i === 0 ? code : (".concat(" + code + ")"); + } + return args.join(''); + }; + return Splat; + }).call(this); + exports.While = (function() { + While = (function() { + function While(condition, opts) { + While.__super__.constructor.call(this); + this.condition = ((opts != null) ? opts.invert : undefined) ? condition.invert() : condition; + this.guard = ((opts != null) ? opts.guard : undefined); + return this; + }; + return While; + })(); + __extends(While, Base); + While.prototype.children = ['condition', 'guard', 'body']; + While.prototype.isStatement = YES; + While.prototype.addBody = function(body) { + this.body = body; + return this; + }; + While.prototype.makeReturn = function() { + this.returns = true; + return this; + }; + While.prototype.topSensitive = YES; + While.prototype.compileNode = function(o) { + var cond, post, pre, rvar, set, top; + top = del(o, 'top') && !this.returns; + o.indent = this.idt(1); + this.condition.parenthetical = true; + cond = this.condition.compile(o); + o.top = true; + set = ''; + if (!top) { + rvar = o.scope.freeVariable('result'); + set = ("" + (this.tab) + rvar + " = [];\n"); + if (this.body) { + this.body = Push.wrap(rvar, this.body); + } + } + pre = ("" + set + (this.tab) + "while (" + cond + ")"); + if (this.guard) { + this.body = Expressions.wrap([new If(this.guard, this.body)]); + } + if (this.returns) { + post = '\n' + new Return(new Literal(rvar)).compile(merge(o, { + indent: this.idt() + })); + } else { + post = ''; + } + return "" + pre + " {\n" + (this.body.compile(o)) + "\n" + (this.tab) + "}" + post; + }; + return While; + })(); + exports.Op = (function() { + Op = (function() { + function Op(op, first, second, flip) { + if (op === 'new') { + if (first instanceof Call) { + return first.newInstance(); + } + if (first instanceof Code && first.bound) { + first = new Parens(first); + } + } + Op.__super__.constructor.call(this); + this.operator = this.CONVERSIONS[op] || op; + (this.first = first).tags.operation = true; + if (second) { + (this.second = second).tags.operation = true; + } + this.flip = !!flip; + return this; + }; + return Op; + })(); + __extends(Op, Base); + Op.prototype.CONVERSIONS = { + '==': '===', + '!=': '!==', + of: 'in' + }; + Op.prototype.INVERSIONS = { + '!==': '===', + '===': '!==' + }; + Op.prototype.CHAINABLE = ['<', '>', '>=', '<=', '===', '!==']; + Op.prototype.ASSIGNMENT = ['||=', '&&=', '?=']; + Op.prototype.PREFIX_OPERATORS = ['new', 'typeof', 'delete']; + Op.prototype.children = ['first', 'second']; + Op.prototype.isUnary = function() { + return !this.second; + }; + Op.prototype.isComplex = function() { + return this.operator !== '!' || this.first.isComplex(); + }; + Op.prototype.isMutator = function() { + var _ref2; + return ends(this.operator, '=') && !((_ref2 = this.operator) === '===' || _ref2 === '!=='); + }; + Op.prototype.isChainable = function() { + return include(this.CHAINABLE, this.operator); + }; + Op.prototype.invert = function() { + var _ref2; + if (((_ref2 = this.operator) === '===' || _ref2 === '!==')) { + this.operator = this.INVERSIONS[this.operator]; + return this; + } else return this.second ? new Parens(this).invert() : Op.__super__.invert.call(this); + }; + Op.prototype.toString = function(idt) { + return Op.__super__.toString.call(this, idt, this.constructor.name + ' ' + this.operator); + }; + Op.prototype.compileNode = function(o) { + if (this.second) { + this.first.tags.front = this.tags.front; + } + if (this.isChainable() && this.first.unwrap() instanceof Op && this.first.unwrap().isChainable()) { + return this.compileChain(o); + } + if (include(this.ASSIGNMENT, this.operator)) { + return this.compileAssignment(o); + } + if (this.isUnary()) { + return this.compileUnary(o); + } + if (this.operator === '?') { + return this.compileExistence(o); + } + if (this.first instanceof Op && this.first.isMutator()) { + this.first = new Parens(this.first); + } + if (this.second instanceof Op && this.second.isMutator()) { + this.second = new Parens(this.second); + } + return [this.first.compile(o), this.operator, this.second.compile(o)].join(' '); + }; + Op.prototype.compileChain = function(o) { + var _ref2, _ref3, first, second, shared; + shared = this.first.unwrap().second; + _ref2 = shared.compileReference(o), this.first.second = _ref2[0], shared = _ref2[1]; + _ref3 = [this.first.compile(o), this.second.compile(o), shared.compile(o)], first = _ref3[0], second = _ref3[1], shared = _ref3[2]; + return "(" + first + ") && (" + shared + " " + (this.operator) + " " + second + ")"; + }; + Op.prototype.compileAssignment = function(o) { + var _ref2, left, rite; + _ref2 = this.first.cacheReference(o), left = _ref2[0], rite = _ref2[1]; + rite = new Assign(rite, this.second); + return new Op(this.operator.slice(0, -1), left, rite).compile(o); + }; + Op.prototype.compileExistence = function(o) { + var fst, ref; + if (this.first.isComplex()) { + ref = o.scope.freeVariable('ref'); + fst = new Parens(new Assign(new Literal(ref), this.first)); + } else { + fst = this.first; + ref = fst.compile(o); + } + return new Existence(fst).compile(o) + (" ? " + ref + " : " + (this.second.compile(o))); + }; + Op.prototype.compileUnary = function(o) { + var parts, space; + space = include(this.PREFIX_OPERATORS, this.operator) ? ' ' : ''; + parts = [this.operator, space, this.first.compile(o)]; + return (this.flip ? parts.reverse() : parts).join(''); + }; + return Op; + })(); + exports.In = (function() { + In = (function() { + function In(_arg, _arg2) { + this.array = _arg2; + this.object = _arg; + In.__super__.constructor.call(this); + return this; + }; + return In; + })(); + __extends(In, Base); + In.prototype.children = ['object', 'array']; + In.prototype.isArray = function() { + return this.array instanceof Value && this.array.isArray(); + }; + In.prototype.compileNode = function(o) { + return this.isArray() ? this.compileOrTest(o) : this.compileLoopTest(o); + }; + In.prototype.compileOrTest = function(o) { + var _len, _ref2, _ref3, _result, i, item, obj1, obj2, tests; + _ref2 = this.object.compileReference(o, { + precompile: true + }), obj1 = _ref2[0], obj2 = _ref2[1]; + tests = (function() { + _result = []; + for (i = 0, _len = (_ref3 = this.array.base.objects).length; i < _len; i++) { + item = _ref3[i]; + _result.push("" + (i ? obj2 : obj1) + " === " + (item.compile(o))); + } + return _result; + }).call(this); + return "(" + (tests.join(' || ')) + ")"; + }; + In.prototype.compileLoopTest = function(o) { + return "" + (utility('inArray')) + "(" + (this.object.compile(o)) + ", " + (this.array.compile(o)) + ")"; + }; + return In; + })(); + exports.Try = (function() { + Try = (function() { + function Try(_arg, _arg2, _arg3, _arg4) { + this.ensure = _arg4; + this.recovery = _arg3; + this.error = _arg2; + this.attempt = _arg; + Try.__super__.constructor.call(this); + return this; + }; + return Try; + })(); + __extends(Try, Base); + Try.prototype.children = ['attempt', 'recovery', 'ensure']; + Try.prototype.isStatement = YES; + Try.prototype.makeReturn = function() { + if (this.attempt) { + this.attempt = this.attempt.makeReturn(); + } + if (this.recovery) { + this.recovery = this.recovery.makeReturn(); + } + return this; + }; + Try.prototype.compileNode = function(o) { + var attemptPart, catchPart, errorPart, finallyPart; + o.indent = this.idt(1); + o.top = true; + attemptPart = this.attempt.compile(o); + errorPart = this.error ? (" (" + (this.error.compile(o)) + ") ") : ' '; + catchPart = this.recovery ? (" catch" + errorPart + "{\n" + (this.recovery.compile(o)) + "\n" + (this.tab) + "}") : (!(this.ensure || this.recovery) ? ' catch (_e) {}' : ''); + finallyPart = (this.ensure || '') && ' finally {\n' + this.ensure.compile(merge(o)) + ("\n" + (this.tab) + "}"); + return "" + (this.tab) + "try {\n" + attemptPart + "\n" + (this.tab) + "}" + catchPart + finallyPart; + }; + return Try; + })(); + exports.Throw = (function() { + Throw = (function() { + function Throw(_arg) { + this.expression = _arg; + Throw.__super__.constructor.call(this); + return this; + }; + return Throw; + })(); + __extends(Throw, Base); + Throw.prototype.children = ['expression']; + Throw.prototype.isStatement = YES; + Throw.prototype.makeReturn = THIS; + Throw.prototype.compileNode = function(o) { + return "" + (this.tab) + "throw " + (this.expression.compile(o)) + ";"; + }; + return Throw; + })(); + exports.Existence = (function() { + Existence = (function() { + function Existence(_arg) { + this.expression = _arg; + Existence.__super__.constructor.call(this); + return this; + }; + return Existence; + })(); + __extends(Existence, Base); + Existence.prototype.children = ['expression']; + Existence.prototype.compileNode = function(o) { + var code; + code = this.expression.compile(o); + code = IDENTIFIER.test(code) && !o.scope.check(code) ? ("typeof " + code + " !== \"undefined\" && " + code + " !== null") : ("" + code + " != null"); + return this.parenthetical ? code : ("(" + code + ")"); + }; + return Existence; + })(); + exports.Parens = (function() { + Parens = (function() { + function Parens(_arg) { + this.expression = _arg; + Parens.__super__.constructor.call(this); + return this; + }; + return Parens; + })(); + __extends(Parens, Base); + Parens.prototype.children = ['expression']; + Parens.prototype.isStatement = function(o) { + return this.expression.isStatement(o); + }; + Parens.prototype.isComplex = function() { + return this.expression.isComplex(); + }; + Parens.prototype.topSensitive = YES; + Parens.prototype.makeReturn = function() { + return this.expression.makeReturn(); + }; + Parens.prototype.compileNode = function(o) { + var code, top; + top = del(o, 'top'); + this.expression.parenthetical = true; + code = this.expression.compile(o); + if (top && this.expression.isPureStatement(o)) { + return code; + } + if (this.parenthetical || this.isStatement(o)) { + return top ? this.tab + code + ';' : code; + } + return "(" + code + ")"; + }; + return Parens; + })(); + exports.For = (function() { + For = (function() { + function For(_arg, source, _arg2, _arg3) { + var _ref2; + this.index = _arg3; + this.name = _arg2; + this.body = _arg; + For.__super__.constructor.call(this); + this.source = source.source, this.guard = source.guard, this.step = source.step; + this.raw = !!source.raw; + this.object = !!source.object; + if (this.object) { + _ref2 = [this.index, this.name], this.name = _ref2[0], this.index = _ref2[1]; + } + this.pattern = this.name instanceof Value; + if (this.index instanceof Value) { + throw new Error('index cannot be a pattern matching expression'); + } + this.returns = false; + return this; + }; + return For; + })(); + __extends(For, Base); + For.prototype.children = ['body', 'source', 'guard']; + For.prototype.isStatement = YES; + For.prototype.topSensitive = YES; + For.prototype.makeReturn = function() { + this.returns = true; + return this; + }; + For.prototype.compileReturnValue = function(val, o) { + if (this.returns) { + return '\n' + new Return(new Literal(val)).compile(o); + } + if (val) { + return '\n' + val; + } + return ''; + }; + For.prototype.compileNode = function(o) { + var body, codeInBody, forPart, guardPart, idt1, index, ivar, lastLine, lvar, name, namePart, nvar, range, ref, resultPart, returnResult, rvar, scope, source, sourcePart, stepPart, svar, topLevel, unstepPart, varPart, vars; + topLevel = del(o, 'top') && !this.returns; + range = this.source instanceof Value && this.source.base instanceof Range && !this.source.properties.length; + source = range ? this.source.base : this.source; + codeInBody = !this.body.containsPureStatement() && this.body.contains(function(node) { + return node instanceof Code; + }); + scope = o.scope; + name = this.name && this.name.compile(o); + index = this.index && this.index.compile(o); + if (name && !this.pattern && (range || !codeInBody)) { + scope.find(name, { + immediate: true + }); + } + if (index) { + scope.find(index, { + immediate: true + }); + } + if (!topLevel) { + rvar = scope.freeVariable('result'); + } + ivar = range ? name : index; + if (!ivar || codeInBody) { + ivar = scope.freeVariable('i'); + } + if (name && !range && codeInBody) { + nvar = scope.freeVariable('i'); + } + varPart = ''; + guardPart = ''; + unstepPart = ''; + body = Expressions.wrap([this.body]); + idt1 = this.idt(1); + if (range) { + forPart = source.compile(merge(o, { + index: ivar, + step: this.step + })); + } else { + svar = (sourcePart = this.source.compile(o)); + if ((name || !this.raw) && !(IDENTIFIER.test(svar) && scope.check(svar, { + immediate: true + }))) { + sourcePart = ("" + (ref = scope.freeVariable('ref')) + " = " + svar); + if (!this.object) { + sourcePart = ("(" + sourcePart + ")"); + } + svar = ref; + } + namePart = this.pattern ? new Assign(this.name, new Literal("" + svar + "[" + ivar + "]")).compile(merge(o, { + top: true + })) : (name ? ("" + name + " = " + svar + "[" + ivar + "]") : undefined); + if (!this.object) { + lvar = scope.freeVariable('len'); + stepPart = this.step ? ("" + ivar + " += " + (this.step.compile(o))) : ("" + ivar + "++"); + forPart = ("" + ivar + " = 0, " + lvar + " = " + sourcePart + ".length; " + ivar + " < " + lvar + "; " + stepPart); + } + } + resultPart = rvar ? ("" + (this.tab) + rvar + " = [];\n") : ''; + returnResult = this.compileReturnValue(rvar, o); + if (!topLevel) { + body = Push.wrap(rvar, body); + } + if (this.guard) { + body = Expressions.wrap([new If(this.guard, body)]); + } + if (codeInBody) { + if (range) { + body.unshift(new Literal("var " + name + " = " + ivar)); + } + if (namePart) { + body.unshift(new Literal("var " + namePart)); + } + if (index) { + body.unshift(new Literal("var " + index + " = " + ivar)); + } + lastLine = body.expressions.pop(); + if (index) { + body.push(new Assign(new Literal(ivar), new Literal(index))); + } + if (nvar) { + body.push(new Assign(new Literal(nvar), new Literal(name))); + } + body.push(lastLine); + o.indent = this.idt(1); + body = Expressions.wrap([new Literal(body.compile(o))]); + if (index) { + body.push(new Assign(new Literal(index), new Literal(ivar))); + } + if (name) { + body.push(new Assign(new Literal(name), new Literal(nvar || ivar))); + } + } else { + if (namePart) { + varPart = ("" + idt1 + namePart + ";\n"); + } + if (forPart && name === ivar) { + unstepPart = this.step ? ("" + name + " -= " + (this.step.compile(o)) + ";") : ("" + name + "--;"); + unstepPart = ("\n" + (this.tab)) + unstepPart; + } + } + if (this.object) { + forPart = ("" + ivar + " in " + sourcePart); + if (!this.raw) { + guardPart = ("\n" + idt1 + "if (!" + (utility('hasProp')) + ".call(" + svar + ", " + ivar + ")) continue;"); + } + } + body = body.compile(merge(o, { + indent: idt1, + top: true + })); + vars = range ? name : ("" + name + ", " + ivar); + return "" + resultPart + (this.tab) + "for (" + forPart + ") {" + guardPart + "\n" + varPart + body + "\n" + (this.tab) + "}" + unstepPart + returnResult; + }; + return For; + })(); + exports.Switch = (function() { + Switch = (function() { + function Switch(_arg, _arg2, _arg3) { + this.otherwise = _arg3; + this.cases = _arg2; + this.subject = _arg; + Switch.__super__.constructor.call(this); + this.tags.subjectless = !this.subject; + this.subject || (this.subject = new Literal('true')); + return this; + }; + return Switch; + })(); + __extends(Switch, Base); + Switch.prototype.children = ['subject', 'cases', 'otherwise']; + Switch.prototype.isStatement = YES; + Switch.prototype.makeReturn = function() { + var _i, _len, _ref2, pair; + for (_i = 0, _len = (_ref2 = this.cases).length; _i < _len; _i++) { + pair = _ref2[_i]; + pair[1].makeReturn(); + } + if (this.otherwise) { + this.otherwise.makeReturn(); + } + return this; + }; + Switch.prototype.compileNode = function(o) { + var _i, _j, _len, _len2, _ref2, _ref3, block, code, condition, conditions, exprs, idt, pair; + idt = (o.indent = this.idt(2)); + o.top = true; + code = ("" + (this.tab) + "switch (" + (this.subject.compile(o)) + ") {"); + for (_i = 0, _len = (_ref2 = this.cases).length; _i < _len; _i++) { + pair = _ref2[_i]; + conditions = pair[0], block = pair[1]; + exprs = block.expressions; + for (_j = 0, _len2 = (_ref3 = flatten([conditions])).length; _j < _len2; _j++) { + condition = _ref3[_j]; + if (this.tags.subjectless) { + condition = new Op('!!', new Parens(condition)); + } + code += ("\n" + (this.idt(1)) + "case " + (condition.compile(o)) + ":"); + } + code += ("\n" + (block.compile(o))); + if (!(last(exprs) instanceof Return)) { + code += ("\n" + idt + "break;"); + } + } + if (this.otherwise) { + code += ("\n" + (this.idt(1)) + "default:\n" + (this.otherwise.compile(o))); + } + code += ("\n" + (this.tab) + "}"); + return code; + }; + return Switch; + })(); + exports.If = (function() { + If = (function() { + function If(condition, _arg, tags) { + this.body = _arg; + this.tags = tags || (tags = {}); + this.condition = tags.invert ? condition.invert() : condition; + this.soakNode = tags.soak; + this.elseBody = null; + this.isChain = false; + return this; + }; + return If; + })(); + __extends(If, Base); + If.prototype.children = ['condition', 'body', 'elseBody', 'assigner']; + If.prototype.topSensitive = YES; + If.prototype.bodyNode = function() { + var _ref2; + return (((_ref2 = this.body) != null) ? _ref2.unwrap() : undefined); + }; + If.prototype.elseBodyNode = function() { + var _ref2; + return (((_ref2 = this.elseBody) != null) ? _ref2.unwrap() : undefined); + }; + If.prototype.addElse = function(elseBody) { + if (this.isChain) { + this.elseBodyNode().addElse(elseBody); + } else { + this.isChain = elseBody instanceof If; + this.elseBody = this.ensureExpressions(elseBody); + } + return this; + }; + If.prototype.isStatement = function(o) { + var _ref2; + return this.statement || (this.statement = ((o != null) ? o.top : undefined) || this.bodyNode().isStatement(o) || (((_ref2 = this.elseBodyNode()) != null) ? _ref2.isStatement(o) : undefined)); + }; + If.prototype.compileCondition = function(o) { + this.condition.parenthetical = true; + return this.condition.compile(o); + }; + If.prototype.compileNode = function(o) { + return this.isStatement(o) ? this.compileStatement(o) : this.compileExpression(o); + }; + If.prototype.makeReturn = function() { + if (this.isStatement()) { + this.body && (this.body = this.ensureExpressions(this.body.makeReturn())); + this.elseBody && (this.elseBody = this.ensureExpressions(this.elseBody.makeReturn())); + return this; + } else { + return new Return(this); + } + }; + If.prototype.ensureExpressions = function(node) { + return node instanceof Expressions ? node : new Expressions([node]); + }; + If.prototype.compileStatement = function(o) { + var child, condO, ifPart, top; + top = del(o, 'top'); + child = del(o, 'chainChild'); + condO = merge(o); + o.indent = this.idt(1); + o.top = true; + ifPart = ("if (" + (this.compileCondition(condO)) + ") {\n" + (this.body.compile(o)) + "\n" + (this.tab) + "}"); + if (!child) { + ifPart = this.tab + ifPart; + } + if (!this.elseBody) { + return ifPart; + } + return ifPart + (this.isChain ? ' else ' + this.elseBodyNode().compile(merge(o, { + indent: this.tab, + chainChild: true + })) : (" else {\n" + (this.elseBody.compile(o)) + "\n" + (this.tab) + "}")); + }; + If.prototype.compileExpression = function(o) { + var code, elsePart, ifPart; + this.bodyNode().tags.operation = (this.condition.tags.operation = true); + if (this.elseBody) { + this.elseBodyNode().tags.operation = true; + } + ifPart = this.condition.compile(o) + ' ? ' + this.bodyNode().compile(o); + elsePart = this.elseBody ? this.elseBodyNode().compile(o) : 'undefined'; + code = ("" + ifPart + " : " + elsePart); + return this.tags.operation || this.soakNode ? ("(" + code + ")") : code; + }; + If.prototype.unfoldSoak = function() { + return this.soakNode && this; + }; + If.unfoldSoak = function(o, parent, name) { + var ifn; + if (!(ifn = parent[name].unfoldSoak(o))) { + return; + } + parent[name] = ifn.body; + ifn.body = new Value(parent); + return ifn; + }; + return If; + }).call(this); + Push = { + wrap: function(name, expressions) { + if (expressions.empty() || expressions.containsPureStatement()) { + return expressions; + } + return Expressions.wrap([new Call(new Value(new Literal(name), [new Accessor(new Literal('push'))]), [expressions.unwrap()])]); + } + }; + Closure = { + wrap: function(expressions, statement, noReturn) { + var args, call, func, mentionsArgs, meth; + if (expressions.containsPureStatement()) { + return expressions; + } + func = new Parens(new Code([], Expressions.wrap([expressions]))); + args = []; + if ((mentionsArgs = expressions.contains(this.literalArgs)) || (expressions.contains(this.literalThis))) { + meth = new Literal(mentionsArgs ? 'apply' : 'call'); + args = [new Literal('this')]; + if (mentionsArgs) { + args.push(new Literal('arguments')); + } + func = new Value(func, [new Accessor(meth)]); + func.noReturn = noReturn; + } + call = new Call(func, args); + return statement ? Expressions.wrap([call]) : call; + }, + literalArgs: function(node) { + return node instanceof Literal && node.value === 'arguments'; + }, + literalThis: function(node) { + return node instanceof Literal && node.value === 'this' || node instanceof Code && node.bound; + } + }; + UTILITIES = { + "extends": 'function(child, parent) {\n function ctor() { this.constructor = child; }\n ctor.prototype = parent.prototype;\n child.prototype = new ctor;\n if (typeof parent.extended === "function") parent.extended(child);\n child.__super__ = parent.prototype;\n}', + bind: 'function(func, context) {\n return function() { return func.apply(context, arguments); };\n}', + inArray: '(function() {\n var indexOf = Array.prototype.indexOf || function(item) {\n var i = this.length; while (i--) if (this[i] === item) return i;\n return -1;\n };\n return function(item, array) { return indexOf.call(array, item) > -1; };\n})();', + hasProp: 'Object.prototype.hasOwnProperty', + slice: 'Array.prototype.slice' + }; + TAB = ' '; + TRAILING_WHITESPACE = /[ \t]+$/gm; + IDENTIFIER = /^[$A-Za-z_][$\w]*$/; + NUMBER = /^0x[\da-f]+|^(?:\d+(\.\d+)?|\.\d+)(?:e[+-]?\d+)?$/i; + SIMPLENUM = /^[+-]?\d+$/; + IS_STRING = /^['"]/; + utility = function(name) { + var ref; + ref = ("__" + name); + Scope.root.assign(ref, UTILITIES[name]); + return ref; + }; +}).call(this); diff --git a/node_modules/jade/support/coffee-script/lib/optparse.js b/node_modules/jade/support/coffee-script/lib/optparse.js new file mode 100755 index 0000000..4a9ae28 --- /dev/null +++ b/node_modules/jade/support/coffee-script/lib/optparse.js @@ -0,0 +1,107 @@ +(function() { + var LONG_FLAG, MULTI_FLAG, OPTIONAL, OptionParser, SHORT_FLAG, buildRule, buildRules, normalizeArguments; + exports.OptionParser = (function() { + OptionParser = (function() { + function OptionParser(rules, banner) { + this.banner = banner; + this.rules = buildRules(rules); + return this; + }; + return OptionParser; + })(); + OptionParser.prototype.parse = function(args) { + var _i, _len, _len2, _ref, arg, i, isOption, matchedRule, options, rule, value; + options = { + arguments: [] + }; + args = normalizeArguments(args); + for (i = 0, _len = args.length; i < _len; i++) { + arg = args[i]; + isOption = !!(arg.match(LONG_FLAG) || arg.match(SHORT_FLAG)); + matchedRule = false; + for (_i = 0, _len2 = (_ref = this.rules).length; _i < _len2; _i++) { + rule = _ref[_i]; + if (rule.shortFlag === arg || rule.longFlag === arg) { + value = rule.hasArgument ? args[i += 1] : true; + options[rule.name] = rule.isList ? (options[rule.name] || []).concat(value) : value; + matchedRule = true; + break; + } + } + if (isOption && !matchedRule) { + throw new Error("unrecognized option: " + arg); + } + if (!isOption) { + options.arguments = args.slice(i); + break; + } + } + return options; + }; + OptionParser.prototype.help = function() { + var _i, _len, _ref, letPart, lines, rule, spaces; + lines = ['Available options:']; + if (this.banner) { + lines.unshift("" + (this.banner) + "\n"); + } + for (_i = 0, _len = (_ref = this.rules).length; _i < _len; _i++) { + rule = _ref[_i]; + spaces = 15 - rule.longFlag.length; + spaces = spaces > 0 ? Array(spaces + 1).join(' ') : ''; + letPart = rule.shortFlag ? rule.shortFlag + ', ' : ' '; + lines.push(' ' + letPart + rule.longFlag + spaces + rule.description); + } + return "\n" + (lines.join('\n')) + "\n"; + }; + return OptionParser; + })(); + LONG_FLAG = /^(--\w[\w\-]+)/; + SHORT_FLAG = /^(-\w)/; + MULTI_FLAG = /^-(\w{2,})/; + OPTIONAL = /\[(\w+(\*?))\]/; + buildRules = function(rules) { + var _i, _len, _result, tuple; + _result = []; + for (_i = 0, _len = rules.length; _i < _len; _i++) { + tuple = rules[_i]; + _result.push((function() { + if (tuple.length < 3) { + tuple.unshift(null); + } + return buildRule.apply(buildRule, tuple); + })()); + } + return _result; + }; + buildRule = function(shortFlag, longFlag, description, options) { + var match; + match = longFlag.match(OPTIONAL); + longFlag = longFlag.match(LONG_FLAG)[1]; + options || (options = {}); + return { + name: longFlag.substr(2), + shortFlag: shortFlag, + longFlag: longFlag, + description: description, + hasArgument: !!(match && match[1]), + isList: !!(match && match[2]) + }; + }; + normalizeArguments = function(args) { + var _i, _j, _len, _len2, _ref, arg, l, match, result; + args = args.slice(0); + result = []; + for (_i = 0, _len = args.length; _i < _len; _i++) { + arg = args[_i]; + if (match = arg.match(MULTI_FLAG)) { + for (_j = 0, _len2 = (_ref = match[1].split('')).length; _j < _len2; _j++) { + l = _ref[_j]; + result.push('-' + l); + } + } else { + result.push(arg); + } + } + return result; + }; +}).call(this); diff --git a/node_modules/jade/support/coffee-script/lib/parser.js b/node_modules/jade/support/coffee-script/lib/parser.js new file mode 100755 index 0000000..e77d3bc --- /dev/null +++ b/node_modules/jade/support/coffee-script/lib/parser.js @@ -0,0 +1,687 @@ +/* Jison generated parser */ +var parser = (function(){ +var parser = {trace: function trace() { }, +yy: {}, +symbols_: {"error":2,"Root":3,"TERMINATOR":4,"Body":5,"Block":6,"Line":7,"Expression":8,"Statement":9,"Return":10,"Throw":11,"BREAK":12,"CONTINUE":13,"DEBUGGER":14,"Value":15,"Invocation":16,"Code":17,"Operation":18,"Assign":19,"If":20,"Try":21,"While":22,"For":23,"Switch":24,"Extends":25,"Class":26,"Existence":27,"Comment":28,"INDENT":29,"OUTDENT":30,"Identifier":31,"IDENTIFIER":32,"AlphaNumeric":33,"NUMBER":34,"STRING":35,"Literal":36,"JS":37,"REGEX":38,"BOOL":39,"Assignable":40,"=":41,"AssignObj":42,"ThisProperty":43,":":44,"RETURN":45,"HERECOMMENT":46,"?":47,"PARAM_START":48,"ParamList":49,"PARAM_END":50,"FuncGlyph":51,"->":52,"=>":53,"OptComma":54,",":55,"Param":56,"PARAM":57,"@":58,"...":59,"Splat":60,"SimpleAssignable":61,"Accessor":62,"Array":63,"Object":64,"Parenthetical":65,"Range":66,"This":67,"PROPERTY_ACCESS":68,"PROTOTYPE_ACCESS":69,"::":70,"SOAK_ACCESS":71,"Index":72,"Slice":73,"INDEX_START":74,"INDEX_END":75,"INDEX_SOAK":76,"INDEX_PROTO":77,"{":78,"AssignList":79,"}":80,"CLASS":81,"EXTENDS":82,"ClassBody":83,"ClassAssign":84,"OptFuncExist":85,"Arguments":86,"SUPER":87,"FUNC_EXIST":88,"CALL_START":89,"CALL_END":90,"ArgList":91,"THIS":92,"RangeDots":93,"..":94,"[":95,"]":96,"Arg":97,"SimpleArgs":98,"TRY":99,"Catch":100,"FINALLY":101,"CATCH":102,"THROW":103,"(":104,")":105,"WhileSource":106,"WHILE":107,"WHEN":108,"UNTIL":109,"Loop":110,"LOOP":111,"ForBody":112,"FOR":113,"ForStart":114,"ForSource":115,"ForVariables":116,"ALL":117,"ForValue":118,"FORIN":119,"FOROF":120,"BY":121,"SWITCH":122,"Whens":123,"ELSE":124,"When":125,"LEADING_WHEN":126,"IfBlock":127,"IF":128,"UNLESS":129,"POST_IF":130,"POST_UNLESS":131,"UNARY":132,"-":133,"+":134,"--":135,"++":136,"==":137,"!=":138,"MATH":139,"SHIFT":140,"COMPARE":141,"LOGIC":142,"COMPOUND_ASSIGN":143,"RELATION":144,"$accept":0,"$end":1}, +terminals_: {"2":"error","4":"TERMINATOR","12":"BREAK","13":"CONTINUE","14":"DEBUGGER","29":"INDENT","30":"OUTDENT","32":"IDENTIFIER","34":"NUMBER","35":"STRING","37":"JS","38":"REGEX","39":"BOOL","41":"=","44":":","45":"RETURN","46":"HERECOMMENT","47":"?","48":"PARAM_START","50":"PARAM_END","52":"->","53":"=>","55":",","57":"PARAM","58":"@","59":"...","68":"PROPERTY_ACCESS","69":"PROTOTYPE_ACCESS","70":"::","71":"SOAK_ACCESS","74":"INDEX_START","75":"INDEX_END","76":"INDEX_SOAK","77":"INDEX_PROTO","78":"{","80":"}","81":"CLASS","82":"EXTENDS","87":"SUPER","88":"FUNC_EXIST","89":"CALL_START","90":"CALL_END","92":"THIS","94":"..","95":"[","96":"]","99":"TRY","101":"FINALLY","102":"CATCH","103":"THROW","104":"(","105":")","107":"WHILE","108":"WHEN","109":"UNTIL","111":"LOOP","113":"FOR","117":"ALL","119":"FORIN","120":"FOROF","121":"BY","122":"SWITCH","124":"ELSE","126":"LEADING_WHEN","128":"IF","129":"UNLESS","130":"POST_IF","131":"POST_UNLESS","132":"UNARY","133":"-","134":"+","135":"--","136":"++","137":"==","138":"!=","139":"MATH","140":"SHIFT","141":"COMPARE","142":"LOGIC","143":"COMPOUND_ASSIGN","144":"RELATION"}, +productions_: [0,[3,0],[3,1],[3,1],[3,2],[5,1],[5,3],[5,2],[7,1],[7,1],[9,1],[9,1],[9,1],[9,1],[9,1],[8,1],[8,1],[8,1],[8,1],[8,1],[8,1],[8,1],[8,1],[8,1],[8,1],[8,1],[8,1],[8,1],[8,1],[6,3],[6,2],[6,2],[31,1],[33,1],[33,1],[36,1],[36,1],[36,1],[36,1],[19,3],[19,5],[42,1],[42,1],[42,1],[42,3],[42,3],[42,5],[42,5],[42,1],[10,2],[10,1],[28,1],[27,2],[17,5],[17,2],[51,1],[51,1],[54,0],[54,1],[49,0],[49,1],[49,3],[56,1],[56,2],[56,2],[56,3],[60,2],[61,1],[61,2],[61,2],[61,1],[40,1],[40,1],[40,1],[15,1],[15,1],[15,1],[15,1],[15,1],[62,2],[62,2],[62,1],[62,2],[62,1],[62,1],[72,3],[72,2],[72,2],[64,4],[79,0],[79,1],[79,3],[79,4],[79,6],[26,2],[26,4],[26,5],[26,7],[26,4],[26,1],[26,3],[26,6],[84,1],[84,3],[84,5],[83,0],[83,1],[83,3],[83,3],[25,3],[16,3],[16,3],[16,1],[16,2],[85,0],[85,1],[86,2],[86,4],[67,1],[67,1],[93,1],[93,1],[43,2],[66,5],[73,5],[73,4],[73,4],[63,2],[63,4],[91,1],[91,3],[91,4],[91,4],[91,6],[97,1],[97,1],[98,1],[98,3],[21,2],[21,3],[21,4],[21,5],[100,3],[11,2],[65,3],[65,2],[106,2],[106,4],[106,2],[106,4],[22,2],[22,2],[22,2],[22,1],[110,2],[110,2],[23,2],[23,2],[23,2],[112,2],[112,2],[114,2],[114,3],[118,1],[118,1],[118,1],[116,1],[116,3],[115,2],[115,2],[115,4],[115,4],[115,4],[115,6],[115,6],[24,5],[24,7],[24,4],[24,6],[123,1],[123,2],[125,3],[125,4],[127,3],[127,3],[127,5],[127,3],[20,1],[20,3],[20,3],[20,3],[20,3],[18,2],[18,2],[18,2],[18,2],[18,2],[18,2],[18,2],[18,3],[18,3],[18,3],[18,3],[18,3],[18,3],[18,3],[18,3],[18,3],[18,5],[18,3]], +performAction: function anonymous(yytext,yyleng,yylineno,yy) { + +var $$ = arguments[5],$0=arguments[5].length; +switch(arguments[4]) { +case 1:return this.$ = new yy.Expressions; +break; +case 2:return this.$ = new yy.Expressions; +break; +case 3:return this.$ = $$[$0-1+1-1]; +break; +case 4:return this.$ = $$[$0-2+1-1]; +break; +case 5:this.$ = yy.Expressions.wrap([$$[$0-1+1-1]]); +break; +case 6:this.$ = $$[$0-3+1-1].push($$[$0-3+3-1]); +break; +case 7:this.$ = $$[$0-2+1-1]; +break; +case 8:this.$ = $$[$0-1+1-1]; +break; +case 9:this.$ = $$[$0-1+1-1]; +break; +case 10:this.$ = $$[$0-1+1-1]; +break; +case 11:this.$ = $$[$0-1+1-1]; +break; +case 12:this.$ = new yy.Literal($$[$0-1+1-1]); +break; +case 13:this.$ = new yy.Literal($$[$0-1+1-1]); +break; +case 14:this.$ = new yy.Literal($$[$0-1+1-1]); +break; +case 15:this.$ = $$[$0-1+1-1]; +break; +case 16:this.$ = $$[$0-1+1-1]; +break; +case 17:this.$ = $$[$0-1+1-1]; +break; +case 18:this.$ = $$[$0-1+1-1]; +break; +case 19:this.$ = $$[$0-1+1-1]; +break; +case 20:this.$ = $$[$0-1+1-1]; +break; +case 21:this.$ = $$[$0-1+1-1]; +break; +case 22:this.$ = $$[$0-1+1-1]; +break; +case 23:this.$ = $$[$0-1+1-1]; +break; +case 24:this.$ = $$[$0-1+1-1]; +break; +case 25:this.$ = $$[$0-1+1-1]; +break; +case 26:this.$ = $$[$0-1+1-1]; +break; +case 27:this.$ = $$[$0-1+1-1]; +break; +case 28:this.$ = $$[$0-1+1-1]; +break; +case 29:this.$ = $$[$0-3+2-1]; +break; +case 30:this.$ = new yy.Expressions; +break; +case 31:this.$ = yy.Expressions.wrap([$$[$0-2+2-1]]); +break; +case 32:this.$ = new yy.Literal($$[$0-1+1-1]); +break; +case 33:this.$ = new yy.Literal($$[$0-1+1-1]); +break; +case 34:this.$ = new yy.Literal($$[$0-1+1-1]); +break; +case 35:this.$ = $$[$0-1+1-1]; +break; +case 36:this.$ = new yy.Literal($$[$0-1+1-1]); +break; +case 37:this.$ = new yy.Literal($$[$0-1+1-1]); +break; +case 38:this.$ = new yy.Literal($$[$0-1+1-1]); +break; +case 39:this.$ = new yy.Assign($$[$0-3+1-1], $$[$0-3+3-1]); +break; +case 40:this.$ = new yy.Assign($$[$0-5+1-1], $$[$0-5+4-1]); +break; +case 41:this.$ = new yy.Value($$[$0-1+1-1]); +break; +case 42:this.$ = $$[$0-1+1-1]; +break; +case 43:this.$ = $$[$0-1+1-1]; +break; +case 44:this.$ = new yy.Assign(new yy.Value($$[$0-3+1-1]), $$[$0-3+3-1], 'object'); +break; +case 45:this.$ = new yy.Assign(new yy.Value($$[$0-3+1-1]), $$[$0-3+3-1], 'object'); +break; +case 46:this.$ = new yy.Assign(new yy.Value($$[$0-5+1-1]), $$[$0-5+4-1], 'object'); +break; +case 47:this.$ = new yy.Assign(new yy.Value($$[$0-5+1-1]), $$[$0-5+4-1], 'object'); +break; +case 48:this.$ = $$[$0-1+1-1]; +break; +case 49:this.$ = new yy.Return($$[$0-2+2-1]); +break; +case 50:this.$ = new yy.Return; +break; +case 51:this.$ = new yy.Comment($$[$0-1+1-1]); +break; +case 52:this.$ = new yy.Existence($$[$0-2+1-1]); +break; +case 53:this.$ = new yy.Code($$[$0-5+2-1], $$[$0-5+5-1], $$[$0-5+4-1]); +break; +case 54:this.$ = new yy.Code([], $$[$0-2+2-1], $$[$0-2+1-1]); +break; +case 55:this.$ = 'func'; +break; +case 56:this.$ = 'boundfunc'; +break; +case 57:this.$ = $$[$0-1+1-1]; +break; +case 58:this.$ = $$[$0-1+1-1]; +break; +case 59:this.$ = []; +break; +case 60:this.$ = [$$[$0-1+1-1]]; +break; +case 61:this.$ = $$[$0-3+1-1].concat($$[$0-3+3-1]); +break; +case 62:this.$ = new yy.Literal($$[$0-1+1-1]); +break; +case 63:this.$ = new yy.Param($$[$0-2+2-1], true); +break; +case 64:this.$ = new yy.Param($$[$0-2+1-1], false, true); +break; +case 65:this.$ = new yy.Param($$[$0-3+2-1], true, true); +break; +case 66:this.$ = new yy.Splat($$[$0-2+1-1]); +break; +case 67:this.$ = new yy.Value($$[$0-1+1-1]); +break; +case 68:this.$ = $$[$0-2+1-1].push($$[$0-2+2-1]); +break; +case 69:this.$ = new yy.Value($$[$0-2+1-1], [$$[$0-2+2-1]]); +break; +case 70:this.$ = $$[$0-1+1-1]; +break; +case 71:this.$ = $$[$0-1+1-1]; +break; +case 72:this.$ = new yy.Value($$[$0-1+1-1]); +break; +case 73:this.$ = new yy.Value($$[$0-1+1-1]); +break; +case 74:this.$ = $$[$0-1+1-1]; +break; +case 75:this.$ = new yy.Value($$[$0-1+1-1]); +break; +case 76:this.$ = new yy.Value($$[$0-1+1-1]); +break; +case 77:this.$ = new yy.Value($$[$0-1+1-1]); +break; +case 78:this.$ = $$[$0-1+1-1]; +break; +case 79:this.$ = new yy.Accessor($$[$0-2+2-1]); +break; +case 80:this.$ = new yy.Accessor($$[$0-2+2-1], 'prototype'); +break; +case 81:this.$ = new yy.Accessor(new yy.Literal('prototype')); +break; +case 82:this.$ = new yy.Accessor($$[$0-2+2-1], 'soak'); +break; +case 83:this.$ = $$[$0-1+1-1]; +break; +case 84:this.$ = new yy.Slice($$[$0-1+1-1]); +break; +case 85:this.$ = new yy.Index($$[$0-3+2-1]); +break; +case 86:this.$ = (function () { + $$[$0-2+2-1].soakNode = true; + return $$[$0-2+2-1]; + }()); +break; +case 87:this.$ = (function () { + $$[$0-2+2-1].proto = true; + return $$[$0-2+2-1]; + }()); +break; +case 88:this.$ = new yy.ObjectLiteral($$[$0-4+2-1]); +break; +case 89:this.$ = []; +break; +case 90:this.$ = [$$[$0-1+1-1]]; +break; +case 91:this.$ = $$[$0-3+1-1].concat($$[$0-3+3-1]); +break; +case 92:this.$ = $$[$0-4+1-1].concat($$[$0-4+4-1]); +break; +case 93:this.$ = $$[$0-6+1-1].concat($$[$0-6+4-1]); +break; +case 94:this.$ = new yy.Class($$[$0-2+2-1]); +break; +case 95:this.$ = new yy.Class($$[$0-4+2-1], $$[$0-4+4-1]); +break; +case 96:this.$ = new yy.Class($$[$0-5+2-1], null, $$[$0-5+4-1]); +break; +case 97:this.$ = new yy.Class($$[$0-7+2-1], $$[$0-7+4-1], $$[$0-7+6-1]); +break; +case 98:this.$ = new yy.Class('__temp__', null, $$[$0-4+3-1]); +break; +case 99:this.$ = new yy.Class('__temp__', null, new yy.Expressions); +break; +case 100:this.$ = new yy.Class('__temp__', $$[$0-3+3-1], new yy.Expressions); +break; +case 101:this.$ = new yy.Class('__temp__', $$[$0-6+3-1], $$[$0-6+5-1]); +break; +case 102:this.$ = $$[$0-1+1-1]; +break; +case 103:this.$ = new yy.Assign(new yy.Value($$[$0-3+1-1]), $$[$0-3+3-1], 'this'); +break; +case 104:this.$ = new yy.Assign(new yy.Value($$[$0-5+1-1]), $$[$0-5+4-1], 'this'); +break; +case 105:this.$ = []; +break; +case 106:this.$ = [$$[$0-1+1-1]]; +break; +case 107:this.$ = $$[$0-3+1-1].concat($$[$0-3+3-1]); +break; +case 108:this.$ = $$[$0-3+2-1]; +break; +case 109:this.$ = new yy.Extends($$[$0-3+1-1], $$[$0-3+3-1]); +break; +case 110:this.$ = new yy.Call($$[$0-3+1-1], $$[$0-3+3-1], $$[$0-3+2-1]); +break; +case 111:this.$ = new yy.Call($$[$0-3+1-1], $$[$0-3+3-1], $$[$0-3+2-1]); +break; +case 112:this.$ = new yy.Call('super', [new yy.Splat(new yy.Literal('arguments'))]); +break; +case 113:this.$ = new yy.Call('super', $$[$0-2+2-1]); +break; +case 114:this.$ = false; +break; +case 115:this.$ = true; +break; +case 116:this.$ = []; +break; +case 117:this.$ = $$[$0-4+2-1]; +break; +case 118:this.$ = new yy.Value(new yy.Literal('this')); +break; +case 119:this.$ = new yy.Value(new yy.Literal('this')); +break; +case 120:this.$ = 'inclusive'; +break; +case 121:this.$ = 'exclusive'; +break; +case 122:this.$ = new yy.Value(new yy.Literal('this'), [new yy.Accessor($$[$0-2+2-1])], 'this'); +break; +case 123:this.$ = new yy.Range($$[$0-5+2-1], $$[$0-5+4-1], $$[$0-5+3-1]); +break; +case 124:this.$ = new yy.Range($$[$0-5+2-1], $$[$0-5+4-1], $$[$0-5+3-1]); +break; +case 125:this.$ = new yy.Range($$[$0-4+2-1], null, $$[$0-4+3-1]); +break; +case 126:this.$ = new yy.Range(null, $$[$0-4+3-1], $$[$0-4+2-1]); +break; +case 127:this.$ = new yy.ArrayLiteral([]); +break; +case 128:this.$ = new yy.ArrayLiteral($$[$0-4+2-1]); +break; +case 129:this.$ = [$$[$0-1+1-1]]; +break; +case 130:this.$ = $$[$0-3+1-1].concat($$[$0-3+3-1]); +break; +case 131:this.$ = $$[$0-4+1-1].concat($$[$0-4+4-1]); +break; +case 132:this.$ = $$[$0-4+2-1]; +break; +case 133:this.$ = $$[$0-6+1-1].concat($$[$0-6+4-1]); +break; +case 134:this.$ = $$[$0-1+1-1]; +break; +case 135:this.$ = $$[$0-1+1-1]; +break; +case 136:this.$ = $$[$0-1+1-1]; +break; +case 137:this.$ = [].concat($$[$0-3+1-1], $$[$0-3+3-1]); +break; +case 138:this.$ = new yy.Try($$[$0-2+2-1]); +break; +case 139:this.$ = new yy.Try($$[$0-3+2-1], $$[$0-3+3-1][0], $$[$0-3+3-1][1]); +break; +case 140:this.$ = new yy.Try($$[$0-4+2-1], null, null, $$[$0-4+4-1]); +break; +case 141:this.$ = new yy.Try($$[$0-5+2-1], $$[$0-5+3-1][0], $$[$0-5+3-1][1], $$[$0-5+5-1]); +break; +case 142:this.$ = [$$[$0-3+2-1], $$[$0-3+3-1]]; +break; +case 143:this.$ = new yy.Throw($$[$0-2+2-1]); +break; +case 144:this.$ = new yy.Parens($$[$0-3+2-1]); +break; +case 145:this.$ = new yy.Parens(new yy.Literal('')); +break; +case 146:this.$ = new yy.While($$[$0-2+2-1]); +break; +case 147:this.$ = new yy.While($$[$0-4+2-1], { + guard: $$[$0-4+4-1] + }); +break; +case 148:this.$ = new yy.While($$[$0-2+2-1], { + invert: true + }); +break; +case 149:this.$ = new yy.While($$[$0-4+2-1], { + invert: true, + guard: $$[$0-4+4-1] + }); +break; +case 150:this.$ = $$[$0-2+1-1].addBody($$[$0-2+2-1]); +break; +case 151:this.$ = $$[$0-2+2-1].addBody(yy.Expressions.wrap([$$[$0-2+1-1]])); +break; +case 152:this.$ = $$[$0-2+2-1].addBody(yy.Expressions.wrap([$$[$0-2+1-1]])); +break; +case 153:this.$ = $$[$0-1+1-1]; +break; +case 154:this.$ = new yy.While(new yy.Literal('true')).addBody($$[$0-2+2-1]); +break; +case 155:this.$ = new yy.While(new yy.Literal('true')).addBody(yy.Expressions.wrap([$$[$0-2+2-1]])); +break; +case 156:this.$ = new yy.For($$[$0-2+1-1], $$[$0-2+2-1], $$[$0-2+2-1].vars[0], $$[$0-2+2-1].vars[1]); +break; +case 157:this.$ = new yy.For($$[$0-2+1-1], $$[$0-2+2-1], $$[$0-2+2-1].vars[0], $$[$0-2+2-1].vars[1]); +break; +case 158:this.$ = new yy.For($$[$0-2+2-1], $$[$0-2+1-1], $$[$0-2+1-1].vars[0], $$[$0-2+1-1].vars[1]); +break; +case 159:this.$ = { + source: new yy.Value($$[$0-2+2-1]), + vars: [] + }; +break; +case 160:this.$ = (function () { + $$[$0-2+2-1].raw = $$[$0-2+1-1].raw; + $$[$0-2+2-1].vars = $$[$0-2+1-1]; + return $$[$0-2+2-1]; + }()); +break; +case 161:this.$ = $$[$0-2+2-1]; +break; +case 162:this.$ = (function () { + $$[$0-3+3-1].raw = true; + return $$[$0-3+3-1]; + }()); +break; +case 163:this.$ = $$[$0-1+1-1]; +break; +case 164:this.$ = new yy.Value($$[$0-1+1-1]); +break; +case 165:this.$ = new yy.Value($$[$0-1+1-1]); +break; +case 166:this.$ = [$$[$0-1+1-1]]; +break; +case 167:this.$ = [$$[$0-3+1-1], $$[$0-3+3-1]]; +break; +case 168:this.$ = { + source: $$[$0-2+2-1] + }; +break; +case 169:this.$ = { + source: $$[$0-2+2-1], + object: true + }; +break; +case 170:this.$ = { + source: $$[$0-4+2-1], + guard: $$[$0-4+4-1] + }; +break; +case 171:this.$ = { + source: $$[$0-4+2-1], + guard: $$[$0-4+4-1], + object: true + }; +break; +case 172:this.$ = { + source: $$[$0-4+2-1], + step: $$[$0-4+4-1] + }; +break; +case 173:this.$ = { + source: $$[$0-6+2-1], + guard: $$[$0-6+4-1], + step: $$[$0-6+6-1] + }; +break; +case 174:this.$ = { + source: $$[$0-6+2-1], + step: $$[$0-6+4-1], + guard: $$[$0-6+6-1] + }; +break; +case 175:this.$ = new yy.Switch($$[$0-5+2-1], $$[$0-5+4-1]); +break; +case 176:this.$ = new yy.Switch($$[$0-7+2-1], $$[$0-7+4-1], $$[$0-7+6-1]); +break; +case 177:this.$ = new yy.Switch(null, $$[$0-4+3-1]); +break; +case 178:this.$ = new yy.Switch(null, $$[$0-6+3-1], $$[$0-6+5-1]); +break; +case 179:this.$ = $$[$0-1+1-1]; +break; +case 180:this.$ = $$[$0-2+1-1].concat($$[$0-2+2-1]); +break; +case 181:this.$ = [[$$[$0-3+2-1], $$[$0-3+3-1]]]; +break; +case 182:this.$ = [[$$[$0-4+2-1], $$[$0-4+3-1]]]; +break; +case 183:this.$ = new yy.If($$[$0-3+2-1], $$[$0-3+3-1]); +break; +case 184:this.$ = new yy.If($$[$0-3+2-1], $$[$0-3+3-1], { + invert: true + }); +break; +case 185:this.$ = $$[$0-5+1-1].addElse(new yy.If($$[$0-5+4-1], $$[$0-5+5-1])); +break; +case 186:this.$ = $$[$0-3+1-1].addElse($$[$0-3+3-1]); +break; +case 187:this.$ = $$[$0-1+1-1]; +break; +case 188:this.$ = new yy.If($$[$0-3+3-1], yy.Expressions.wrap([$$[$0-3+1-1]]), { + statement: true + }); +break; +case 189:this.$ = new yy.If($$[$0-3+3-1], yy.Expressions.wrap([$$[$0-3+1-1]]), { + statement: true + }); +break; +case 190:this.$ = new yy.If($$[$0-3+3-1], yy.Expressions.wrap([$$[$0-3+1-1]]), { + statement: true, + invert: true + }); +break; +case 191:this.$ = new yy.If($$[$0-3+3-1], yy.Expressions.wrap([$$[$0-3+1-1]]), { + statement: true, + invert: true + }); +break; +case 192:this.$ = new yy.Op($$[$0-2+1-1], $$[$0-2+2-1]); +break; +case 193:this.$ = new yy.Op('-', $$[$0-2+2-1]); +break; +case 194:this.$ = new yy.Op('+', $$[$0-2+2-1]); +break; +case 195:this.$ = new yy.Op('--', $$[$0-2+2-1]); +break; +case 196:this.$ = new yy.Op('++', $$[$0-2+2-1]); +break; +case 197:this.$ = new yy.Op('--', $$[$0-2+1-1], null, true); +break; +case 198:this.$ = new yy.Op('++', $$[$0-2+1-1], null, true); +break; +case 199:this.$ = new yy.Op('+', $$[$0-3+1-1], $$[$0-3+3-1]); +break; +case 200:this.$ = new yy.Op('-', $$[$0-3+1-1], $$[$0-3+3-1]); +break; +case 201:this.$ = new yy.Op('==', $$[$0-3+1-1], $$[$0-3+3-1]); +break; +case 202:this.$ = new yy.Op('!=', $$[$0-3+1-1], $$[$0-3+3-1]); +break; +case 203:this.$ = new yy.Op($$[$0-3+2-1], $$[$0-3+1-1], $$[$0-3+3-1]); +break; +case 204:this.$ = new yy.Op($$[$0-3+2-1], $$[$0-3+1-1], $$[$0-3+3-1]); +break; +case 205:this.$ = new yy.Op($$[$0-3+2-1], $$[$0-3+1-1], $$[$0-3+3-1]); +break; +case 206:this.$ = new yy.Op($$[$0-3+2-1], $$[$0-3+1-1], $$[$0-3+3-1]); +break; +case 207:this.$ = new yy.Op($$[$0-3+2-1], $$[$0-3+1-1], $$[$0-3+3-1]); +break; +case 208:this.$ = new yy.Op($$[$0-5+2-1], $$[$0-5+1-1], $$[$0-5+4-1]); +break; +case 209:this.$ = $$[$0-3+2-1].charAt(0) === '!' ? ($$[$0-3+2-1] === '!in' ? new yy.Op('!', new yy.In($$[$0-3+1-1], $$[$0-3+3-1])) : new yy.Op('!', new yy.Parens(new yy.Op($$[$0-3+2-1].slice(1), $$[$0-3+1-1], $$[$0-3+3-1])))) : ($$[$0-3+2-1] === 'in' ? new yy.In($$[$0-3+1-1], $$[$0-3+3-1]) : new yy.Op($$[$0-3+2-1], $$[$0-3+1-1], $$[$0-3+3-1])); +break; +} +}, +table: [{"1":[2,1],"3":1,"4":[1,2],"5":3,"6":4,"7":5,"8":7,"9":8,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"29":[1,6],"31":64,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":65,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":41,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,43],"103":[1,51],"104":[1,58],"106":44,"107":[1,68],"109":[1,69],"110":45,"111":[1,70],"112":46,"113":[1,71],"114":72,"122":[1,47],"127":42,"128":[1,66],"129":[1,67],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"1":[3]},{"1":[2,2],"28":77,"46":[1,49]},{"1":[2,3],"4":[1,78]},{"4":[1,79]},{"1":[2,5],"4":[2,5],"30":[2,5]},{"5":80,"7":5,"8":7,"9":8,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"30":[1,81],"31":64,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":65,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":41,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,43],"103":[1,51],"104":[1,58],"106":44,"107":[1,68],"109":[1,69],"110":45,"111":[1,70],"112":46,"113":[1,71],"114":72,"122":[1,47],"127":42,"128":[1,66],"129":[1,67],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"1":[2,8],"4":[2,8],"30":[2,8],"47":[1,95],"106":93,"107":[1,68],"109":[1,69],"112":94,"113":[1,71],"114":72,"130":[1,91],"131":[1,92],"133":[1,83],"134":[1,82],"137":[1,84],"138":[1,85],"139":[1,86],"140":[1,87],"141":[1,88],"142":[1,89],"144":[1,90]},{"1":[2,9],"4":[2,9],"30":[2,9],"106":98,"107":[1,68],"109":[1,69],"112":99,"113":[1,71],"114":72,"130":[1,96],"131":[1,97]},{"1":[2,15],"4":[2,15],"29":[2,15],"30":[2,15],"47":[2,15],"55":[2,15],"59":[2,15],"62":101,"68":[1,103],"69":[1,104],"70":[1,105],"71":[1,106],"72":107,"73":108,"74":[1,109],"75":[2,15],"76":[1,110],"77":[1,111],"80":[2,15],"85":100,"88":[1,102],"89":[2,114],"90":[2,15],"94":[2,15],"96":[2,15],"105":[2,15],"107":[2,15],"108":[2,15],"109":[2,15],"113":[2,15],"121":[2,15],"130":[2,15],"131":[2,15],"133":[2,15],"134":[2,15],"137":[2,15],"138":[2,15],"139":[2,15],"140":[2,15],"141":[2,15],"142":[2,15],"144":[2,15]},{"1":[2,16],"4":[2,16],"29":[2,16],"30":[2,16],"47":[2,16],"55":[2,16],"59":[2,16],"62":113,"68":[1,103],"69":[1,104],"70":[1,105],"71":[1,106],"72":107,"73":108,"74":[1,109],"75":[2,16],"76":[1,110],"77":[1,111],"80":[2,16],"85":112,"88":[1,102],"89":[2,114],"90":[2,16],"94":[2,16],"96":[2,16],"105":[2,16],"107":[2,16],"108":[2,16],"109":[2,16],"113":[2,16],"121":[2,16],"130":[2,16],"131":[2,16],"133":[2,16],"134":[2,16],"137":[2,16],"138":[2,16],"139":[2,16],"140":[2,16],"141":[2,16],"142":[2,16],"144":[2,16]},{"1":[2,17],"4":[2,17],"29":[2,17],"30":[2,17],"47":[2,17],"55":[2,17],"59":[2,17],"75":[2,17],"80":[2,17],"90":[2,17],"94":[2,17],"96":[2,17],"105":[2,17],"107":[2,17],"108":[2,17],"109":[2,17],"113":[2,17],"121":[2,17],"130":[2,17],"131":[2,17],"133":[2,17],"134":[2,17],"137":[2,17],"138":[2,17],"139":[2,17],"140":[2,17],"141":[2,17],"142":[2,17],"144":[2,17]},{"1":[2,18],"4":[2,18],"29":[2,18],"30":[2,18],"47":[2,18],"55":[2,18],"59":[2,18],"75":[2,18],"80":[2,18],"90":[2,18],"94":[2,18],"96":[2,18],"105":[2,18],"107":[2,18],"108":[2,18],"109":[2,18],"113":[2,18],"121":[2,18],"130":[2,18],"131":[2,18],"133":[2,18],"134":[2,18],"137":[2,18],"138":[2,18],"139":[2,18],"140":[2,18],"141":[2,18],"142":[2,18],"144":[2,18]},{"1":[2,19],"4":[2,19],"29":[2,19],"30":[2,19],"47":[2,19],"55":[2,19],"59":[2,19],"75":[2,19],"80":[2,19],"90":[2,19],"94":[2,19],"96":[2,19],"105":[2,19],"107":[2,19],"108":[2,19],"109":[2,19],"113":[2,19],"121":[2,19],"130":[2,19],"131":[2,19],"133":[2,19],"134":[2,19],"137":[2,19],"138":[2,19],"139":[2,19],"140":[2,19],"141":[2,19],"142":[2,19],"144":[2,19]},{"1":[2,20],"4":[2,20],"29":[2,20],"30":[2,20],"47":[2,20],"55":[2,20],"59":[2,20],"75":[2,20],"80":[2,20],"90":[2,20],"94":[2,20],"96":[2,20],"105":[2,20],"107":[2,20],"108":[2,20],"109":[2,20],"113":[2,20],"121":[2,20],"130":[2,20],"131":[2,20],"133":[2,20],"134":[2,20],"137":[2,20],"138":[2,20],"139":[2,20],"140":[2,20],"141":[2,20],"142":[2,20],"144":[2,20]},{"1":[2,21],"4":[2,21],"29":[2,21],"30":[2,21],"47":[2,21],"55":[2,21],"59":[2,21],"75":[2,21],"80":[2,21],"90":[2,21],"94":[2,21],"96":[2,21],"105":[2,21],"107":[2,21],"108":[2,21],"109":[2,21],"113":[2,21],"121":[2,21],"130":[2,21],"131":[2,21],"133":[2,21],"134":[2,21],"137":[2,21],"138":[2,21],"139":[2,21],"140":[2,21],"141":[2,21],"142":[2,21],"144":[2,21]},{"1":[2,22],"4":[2,22],"29":[2,22],"30":[2,22],"47":[2,22],"55":[2,22],"59":[2,22],"75":[2,22],"80":[2,22],"90":[2,22],"94":[2,22],"96":[2,22],"105":[2,22],"107":[2,22],"108":[2,22],"109":[2,22],"113":[2,22],"121":[2,22],"130":[2,22],"131":[2,22],"133":[2,22],"134":[2,22],"137":[2,22],"138":[2,22],"139":[2,22],"140":[2,22],"141":[2,22],"142":[2,22],"144":[2,22]},{"1":[2,23],"4":[2,23],"29":[2,23],"30":[2,23],"47":[2,23],"55":[2,23],"59":[2,23],"75":[2,23],"80":[2,23],"90":[2,23],"94":[2,23],"96":[2,23],"105":[2,23],"107":[2,23],"108":[2,23],"109":[2,23],"113":[2,23],"121":[2,23],"130":[2,23],"131":[2,23],"133":[2,23],"134":[2,23],"137":[2,23],"138":[2,23],"139":[2,23],"140":[2,23],"141":[2,23],"142":[2,23],"144":[2,23]},{"1":[2,24],"4":[2,24],"29":[2,24],"30":[2,24],"47":[2,24],"55":[2,24],"59":[2,24],"75":[2,24],"80":[2,24],"90":[2,24],"94":[2,24],"96":[2,24],"105":[2,24],"107":[2,24],"108":[2,24],"109":[2,24],"113":[2,24],"121":[2,24],"130":[2,24],"131":[2,24],"133":[2,24],"134":[2,24],"137":[2,24],"138":[2,24],"139":[2,24],"140":[2,24],"141":[2,24],"142":[2,24],"144":[2,24]},{"1":[2,25],"4":[2,25],"29":[2,25],"30":[2,25],"47":[2,25],"55":[2,25],"59":[2,25],"75":[2,25],"80":[2,25],"90":[2,25],"94":[2,25],"96":[2,25],"105":[2,25],"107":[2,25],"108":[2,25],"109":[2,25],"113":[2,25],"121":[2,25],"130":[2,25],"131":[2,25],"133":[2,25],"134":[2,25],"137":[2,25],"138":[2,25],"139":[2,25],"140":[2,25],"141":[2,25],"142":[2,25],"144":[2,25]},{"1":[2,26],"4":[2,26],"29":[2,26],"30":[2,26],"47":[2,26],"55":[2,26],"59":[2,26],"75":[2,26],"80":[2,26],"90":[2,26],"94":[2,26],"96":[2,26],"105":[2,26],"107":[2,26],"108":[2,26],"109":[2,26],"113":[2,26],"121":[2,26],"130":[2,26],"131":[2,26],"133":[2,26],"134":[2,26],"137":[2,26],"138":[2,26],"139":[2,26],"140":[2,26],"141":[2,26],"142":[2,26],"144":[2,26]},{"1":[2,27],"4":[2,27],"29":[2,27],"30":[2,27],"47":[2,27],"55":[2,27],"59":[2,27],"75":[2,27],"80":[2,27],"90":[2,27],"94":[2,27],"96":[2,27],"105":[2,27],"107":[2,27],"108":[2,27],"109":[2,27],"113":[2,27],"121":[2,27],"130":[2,27],"131":[2,27],"133":[2,27],"134":[2,27],"137":[2,27],"138":[2,27],"139":[2,27],"140":[2,27],"141":[2,27],"142":[2,27],"144":[2,27]},{"1":[2,28],"4":[2,28],"29":[2,28],"30":[2,28],"47":[2,28],"55":[2,28],"59":[2,28],"75":[2,28],"80":[2,28],"90":[2,28],"94":[2,28],"96":[2,28],"105":[2,28],"107":[2,28],"108":[2,28],"109":[2,28],"113":[2,28],"121":[2,28],"130":[2,28],"131":[2,28],"133":[2,28],"134":[2,28],"137":[2,28],"138":[2,28],"139":[2,28],"140":[2,28],"141":[2,28],"142":[2,28],"144":[2,28]},{"1":[2,10],"4":[2,10],"30":[2,10],"107":[2,10],"109":[2,10],"113":[2,10],"130":[2,10],"131":[2,10]},{"1":[2,11],"4":[2,11],"30":[2,11],"107":[2,11],"109":[2,11],"113":[2,11],"130":[2,11],"131":[2,11]},{"1":[2,12],"4":[2,12],"30":[2,12],"107":[2,12],"109":[2,12],"113":[2,12],"130":[2,12],"131":[2,12]},{"1":[2,13],"4":[2,13],"30":[2,13],"107":[2,13],"109":[2,13],"113":[2,13],"130":[2,13],"131":[2,13]},{"1":[2,14],"4":[2,14],"30":[2,14],"107":[2,14],"109":[2,14],"113":[2,14],"130":[2,14],"131":[2,14]},{"1":[2,74],"4":[2,74],"29":[2,74],"30":[2,74],"41":[1,114],"47":[2,74],"55":[2,74],"59":[2,74],"68":[2,74],"69":[2,74],"70":[2,74],"71":[2,74],"74":[2,74],"75":[2,74],"76":[2,74],"77":[2,74],"80":[2,74],"88":[2,74],"89":[2,74],"90":[2,74],"94":[2,74],"96":[2,74],"105":[2,74],"107":[2,74],"108":[2,74],"109":[2,74],"113":[2,74],"121":[2,74],"130":[2,74],"131":[2,74],"133":[2,74],"134":[2,74],"137":[2,74],"138":[2,74],"139":[2,74],"140":[2,74],"141":[2,74],"142":[2,74],"144":[2,74]},{"1":[2,75],"4":[2,75],"29":[2,75],"30":[2,75],"47":[2,75],"55":[2,75],"59":[2,75],"68":[2,75],"69":[2,75],"70":[2,75],"71":[2,75],"74":[2,75],"75":[2,75],"76":[2,75],"77":[2,75],"80":[2,75],"88":[2,75],"89":[2,75],"90":[2,75],"94":[2,75],"96":[2,75],"105":[2,75],"107":[2,75],"108":[2,75],"109":[2,75],"113":[2,75],"121":[2,75],"130":[2,75],"131":[2,75],"133":[2,75],"134":[2,75],"137":[2,75],"138":[2,75],"139":[2,75],"140":[2,75],"141":[2,75],"142":[2,75],"144":[2,75]},{"1":[2,76],"4":[2,76],"29":[2,76],"30":[2,76],"47":[2,76],"55":[2,76],"59":[2,76],"68":[2,76],"69":[2,76],"70":[2,76],"71":[2,76],"74":[2,76],"75":[2,76],"76":[2,76],"77":[2,76],"80":[2,76],"88":[2,76],"89":[2,76],"90":[2,76],"94":[2,76],"96":[2,76],"105":[2,76],"107":[2,76],"108":[2,76],"109":[2,76],"113":[2,76],"121":[2,76],"130":[2,76],"131":[2,76],"133":[2,76],"134":[2,76],"137":[2,76],"138":[2,76],"139":[2,76],"140":[2,76],"141":[2,76],"142":[2,76],"144":[2,76]},{"1":[2,77],"4":[2,77],"29":[2,77],"30":[2,77],"47":[2,77],"55":[2,77],"59":[2,77],"68":[2,77],"69":[2,77],"70":[2,77],"71":[2,77],"74":[2,77],"75":[2,77],"76":[2,77],"77":[2,77],"80":[2,77],"88":[2,77],"89":[2,77],"90":[2,77],"94":[2,77],"96":[2,77],"105":[2,77],"107":[2,77],"108":[2,77],"109":[2,77],"113":[2,77],"121":[2,77],"130":[2,77],"131":[2,77],"133":[2,77],"134":[2,77],"137":[2,77],"138":[2,77],"139":[2,77],"140":[2,77],"141":[2,77],"142":[2,77],"144":[2,77]},{"1":[2,78],"4":[2,78],"29":[2,78],"30":[2,78],"47":[2,78],"55":[2,78],"59":[2,78],"68":[2,78],"69":[2,78],"70":[2,78],"71":[2,78],"74":[2,78],"75":[2,78],"76":[2,78],"77":[2,78],"80":[2,78],"88":[2,78],"89":[2,78],"90":[2,78],"94":[2,78],"96":[2,78],"105":[2,78],"107":[2,78],"108":[2,78],"109":[2,78],"113":[2,78],"121":[2,78],"130":[2,78],"131":[2,78],"133":[2,78],"134":[2,78],"137":[2,78],"138":[2,78],"139":[2,78],"140":[2,78],"141":[2,78],"142":[2,78],"144":[2,78]},{"1":[2,112],"4":[2,112],"29":[2,112],"30":[2,112],"47":[2,112],"55":[2,112],"59":[2,112],"68":[2,112],"69":[2,112],"70":[2,112],"71":[2,112],"74":[2,112],"75":[2,112],"76":[2,112],"77":[2,112],"80":[2,112],"86":115,"88":[2,112],"89":[1,116],"90":[2,112],"94":[2,112],"96":[2,112],"105":[2,112],"107":[2,112],"108":[2,112],"109":[2,112],"113":[2,112],"121":[2,112],"130":[2,112],"131":[2,112],"133":[2,112],"134":[2,112],"137":[2,112],"138":[2,112],"139":[2,112],"140":[2,112],"141":[2,112],"142":[2,112],"144":[2,112]},{"49":117,"50":[2,59],"55":[2,59],"56":118,"57":[1,119],"58":[1,120]},{"4":[1,122],"6":121,"29":[1,6]},{"8":123,"9":124,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"31":64,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":65,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":41,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,43],"103":[1,51],"104":[1,58],"106":44,"107":[1,68],"109":[1,69],"110":45,"111":[1,70],"112":46,"113":[1,71],"114":72,"122":[1,47],"127":42,"128":[1,66],"129":[1,67],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"8":125,"9":124,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"31":64,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":65,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":41,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,43],"103":[1,51],"104":[1,58],"106":44,"107":[1,68],"109":[1,69],"110":45,"111":[1,70],"112":46,"113":[1,71],"114":72,"122":[1,47],"127":42,"128":[1,66],"129":[1,67],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"8":126,"9":124,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"31":64,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":65,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":41,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,43],"103":[1,51],"104":[1,58],"106":44,"107":[1,68],"109":[1,69],"110":45,"111":[1,70],"112":46,"113":[1,71],"114":72,"122":[1,47],"127":42,"128":[1,66],"129":[1,67],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"15":128,"16":129,"31":64,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":130,"43":65,"58":[1,61],"61":127,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"87":[1,33],"92":[1,60],"95":[1,59],"104":[1,58]},{"15":128,"16":129,"31":64,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":130,"43":65,"58":[1,61],"61":131,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"87":[1,33],"92":[1,60],"95":[1,59],"104":[1,58]},{"1":[2,71],"4":[2,71],"29":[2,71],"30":[2,71],"41":[2,71],"47":[2,71],"55":[2,71],"59":[2,71],"68":[2,71],"69":[2,71],"70":[2,71],"71":[2,71],"74":[2,71],"75":[2,71],"76":[2,71],"77":[2,71],"80":[2,71],"82":[1,135],"88":[2,71],"89":[2,71],"90":[2,71],"94":[2,71],"96":[2,71],"105":[2,71],"107":[2,71],"108":[2,71],"109":[2,71],"113":[2,71],"121":[2,71],"130":[2,71],"131":[2,71],"133":[2,71],"134":[2,71],"135":[1,132],"136":[1,133],"137":[2,71],"138":[2,71],"139":[2,71],"140":[2,71],"141":[2,71],"142":[2,71],"143":[1,134],"144":[2,71]},{"1":[2,187],"4":[2,187],"29":[2,187],"30":[2,187],"47":[2,187],"55":[2,187],"59":[2,187],"75":[2,187],"80":[2,187],"90":[2,187],"94":[2,187],"96":[2,187],"105":[2,187],"107":[2,187],"108":[2,187],"109":[2,187],"113":[2,187],"121":[2,187],"124":[1,136],"130":[2,187],"131":[2,187],"133":[2,187],"134":[2,187],"137":[2,187],"138":[2,187],"139":[2,187],"140":[2,187],"141":[2,187],"142":[2,187],"144":[2,187]},{"4":[1,122],"6":137,"29":[1,6]},{"4":[1,122],"6":138,"29":[1,6]},{"1":[2,153],"4":[2,153],"29":[2,153],"30":[2,153],"47":[2,153],"55":[2,153],"59":[2,153],"75":[2,153],"80":[2,153],"90":[2,153],"94":[2,153],"96":[2,153],"105":[2,153],"107":[2,153],"108":[2,153],"109":[2,153],"113":[2,153],"121":[2,153],"130":[2,153],"131":[2,153],"133":[2,153],"134":[2,153],"137":[2,153],"138":[2,153],"139":[2,153],"140":[2,153],"141":[2,153],"142":[2,153],"144":[2,153]},{"4":[1,122],"6":139,"29":[1,6]},{"8":140,"9":124,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"29":[1,141],"31":64,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":65,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":41,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,43],"103":[1,51],"104":[1,58],"106":44,"107":[1,68],"109":[1,69],"110":45,"111":[1,70],"112":46,"113":[1,71],"114":72,"122":[1,47],"127":42,"128":[1,66],"129":[1,67],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"1":[2,99],"4":[2,99],"15":128,"16":129,"29":[1,143],"30":[2,99],"31":64,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":130,"43":65,"47":[2,99],"55":[2,99],"58":[1,61],"59":[2,99],"61":142,"63":52,"64":53,"65":30,"66":31,"67":32,"75":[2,99],"78":[1,73],"80":[2,99],"82":[1,144],"87":[1,33],"90":[2,99],"92":[1,60],"94":[2,99],"95":[1,59],"96":[2,99],"104":[1,58],"105":[2,99],"107":[2,99],"108":[2,99],"109":[2,99],"113":[2,99],"121":[2,99],"130":[2,99],"131":[2,99],"133":[2,99],"134":[2,99],"137":[2,99],"138":[2,99],"139":[2,99],"140":[2,99],"141":[2,99],"142":[2,99],"144":[2,99]},{"1":[2,51],"4":[2,51],"29":[2,51],"30":[2,51],"47":[2,51],"55":[2,51],"59":[2,51],"75":[2,51],"80":[2,51],"90":[2,51],"94":[2,51],"96":[2,51],"101":[2,51],"102":[2,51],"105":[2,51],"107":[2,51],"108":[2,51],"109":[2,51],"113":[2,51],"121":[2,51],"124":[2,51],"126":[2,51],"130":[2,51],"131":[2,51],"133":[2,51],"134":[2,51],"137":[2,51],"138":[2,51],"139":[2,51],"140":[2,51],"141":[2,51],"142":[2,51],"144":[2,51]},{"1":[2,50],"4":[2,50],"8":145,"9":124,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"30":[2,50],"31":64,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":65,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":41,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,43],"103":[1,51],"104":[1,58],"106":44,"107":[1,68],"109":[1,69],"110":45,"111":[1,70],"112":46,"113":[1,71],"114":72,"122":[1,47],"127":42,"128":[1,66],"129":[1,67],"130":[2,50],"131":[2,50],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"8":146,"9":124,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"31":64,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":65,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":41,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,43],"103":[1,51],"104":[1,58],"106":44,"107":[1,68],"109":[1,69],"110":45,"111":[1,70],"112":46,"113":[1,71],"114":72,"122":[1,47],"127":42,"128":[1,66],"129":[1,67],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"1":[2,72],"4":[2,72],"29":[2,72],"30":[2,72],"41":[2,72],"47":[2,72],"55":[2,72],"59":[2,72],"68":[2,72],"69":[2,72],"70":[2,72],"71":[2,72],"74":[2,72],"75":[2,72],"76":[2,72],"77":[2,72],"80":[2,72],"88":[2,72],"89":[2,72],"90":[2,72],"94":[2,72],"96":[2,72],"105":[2,72],"107":[2,72],"108":[2,72],"109":[2,72],"113":[2,72],"121":[2,72],"130":[2,72],"131":[2,72],"133":[2,72],"134":[2,72],"137":[2,72],"138":[2,72],"139":[2,72],"140":[2,72],"141":[2,72],"142":[2,72],"144":[2,72]},{"1":[2,73],"4":[2,73],"29":[2,73],"30":[2,73],"41":[2,73],"47":[2,73],"55":[2,73],"59":[2,73],"68":[2,73],"69":[2,73],"70":[2,73],"71":[2,73],"74":[2,73],"75":[2,73],"76":[2,73],"77":[2,73],"80":[2,73],"88":[2,73],"89":[2,73],"90":[2,73],"94":[2,73],"96":[2,73],"105":[2,73],"107":[2,73],"108":[2,73],"109":[2,73],"113":[2,73],"121":[2,73],"130":[2,73],"131":[2,73],"133":[2,73],"134":[2,73],"137":[2,73],"138":[2,73],"139":[2,73],"140":[2,73],"141":[2,73],"142":[2,73],"144":[2,73]},{"1":[2,35],"4":[2,35],"29":[2,35],"30":[2,35],"47":[2,35],"55":[2,35],"59":[2,35],"68":[2,35],"69":[2,35],"70":[2,35],"71":[2,35],"74":[2,35],"75":[2,35],"76":[2,35],"77":[2,35],"80":[2,35],"88":[2,35],"89":[2,35],"90":[2,35],"94":[2,35],"96":[2,35],"105":[2,35],"107":[2,35],"108":[2,35],"109":[2,35],"113":[2,35],"121":[2,35],"130":[2,35],"131":[2,35],"133":[2,35],"134":[2,35],"137":[2,35],"138":[2,35],"139":[2,35],"140":[2,35],"141":[2,35],"142":[2,35],"144":[2,35]},{"1":[2,36],"4":[2,36],"29":[2,36],"30":[2,36],"47":[2,36],"55":[2,36],"59":[2,36],"68":[2,36],"69":[2,36],"70":[2,36],"71":[2,36],"74":[2,36],"75":[2,36],"76":[2,36],"77":[2,36],"80":[2,36],"88":[2,36],"89":[2,36],"90":[2,36],"94":[2,36],"96":[2,36],"105":[2,36],"107":[2,36],"108":[2,36],"109":[2,36],"113":[2,36],"121":[2,36],"130":[2,36],"131":[2,36],"133":[2,36],"134":[2,36],"137":[2,36],"138":[2,36],"139":[2,36],"140":[2,36],"141":[2,36],"142":[2,36],"144":[2,36]},{"1":[2,37],"4":[2,37],"29":[2,37],"30":[2,37],"47":[2,37],"55":[2,37],"59":[2,37],"68":[2,37],"69":[2,37],"70":[2,37],"71":[2,37],"74":[2,37],"75":[2,37],"76":[2,37],"77":[2,37],"80":[2,37],"88":[2,37],"89":[2,37],"90":[2,37],"94":[2,37],"96":[2,37],"105":[2,37],"107":[2,37],"108":[2,37],"109":[2,37],"113":[2,37],"121":[2,37],"130":[2,37],"131":[2,37],"133":[2,37],"134":[2,37],"137":[2,37],"138":[2,37],"139":[2,37],"140":[2,37],"141":[2,37],"142":[2,37],"144":[2,37]},{"1":[2,38],"4":[2,38],"29":[2,38],"30":[2,38],"47":[2,38],"55":[2,38],"59":[2,38],"68":[2,38],"69":[2,38],"70":[2,38],"71":[2,38],"74":[2,38],"75":[2,38],"76":[2,38],"77":[2,38],"80":[2,38],"88":[2,38],"89":[2,38],"90":[2,38],"94":[2,38],"96":[2,38],"105":[2,38],"107":[2,38],"108":[2,38],"109":[2,38],"113":[2,38],"121":[2,38],"130":[2,38],"131":[2,38],"133":[2,38],"134":[2,38],"137":[2,38],"138":[2,38],"139":[2,38],"140":[2,38],"141":[2,38],"142":[2,38],"144":[2,38]},{"8":147,"9":124,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"31":64,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":65,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":41,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,43],"103":[1,51],"104":[1,58],"105":[1,148],"106":44,"107":[1,68],"109":[1,69],"110":45,"111":[1,70],"112":46,"113":[1,71],"114":72,"122":[1,47],"127":42,"128":[1,66],"129":[1,67],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"8":149,"9":124,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"29":[1,153],"31":64,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":65,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"60":154,"61":41,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"91":151,"92":[1,60],"95":[1,59],"96":[1,150],"97":152,"99":[1,43],"103":[1,51],"104":[1,58],"106":44,"107":[1,68],"109":[1,69],"110":45,"111":[1,70],"112":46,"113":[1,71],"114":72,"122":[1,47],"127":42,"128":[1,66],"129":[1,67],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"1":[2,118],"4":[2,118],"29":[2,118],"30":[2,118],"47":[2,118],"55":[2,118],"59":[2,118],"68":[2,118],"69":[2,118],"70":[2,118],"71":[2,118],"74":[2,118],"75":[2,118],"76":[2,118],"77":[2,118],"80":[2,118],"88":[2,118],"89":[2,118],"90":[2,118],"94":[2,118],"96":[2,118],"105":[2,118],"107":[2,118],"108":[2,118],"109":[2,118],"113":[2,118],"121":[2,118],"130":[2,118],"131":[2,118],"133":[2,118],"134":[2,118],"137":[2,118],"138":[2,118],"139":[2,118],"140":[2,118],"141":[2,118],"142":[2,118],"144":[2,118]},{"1":[2,119],"4":[2,119],"29":[2,119],"30":[2,119],"31":155,"32":[1,76],"47":[2,119],"55":[2,119],"59":[2,119],"68":[2,119],"69":[2,119],"70":[2,119],"71":[2,119],"74":[2,119],"75":[2,119],"76":[2,119],"77":[2,119],"80":[2,119],"88":[2,119],"89":[2,119],"90":[2,119],"94":[2,119],"96":[2,119],"105":[2,119],"107":[2,119],"108":[2,119],"109":[2,119],"113":[2,119],"121":[2,119],"130":[2,119],"131":[2,119],"133":[2,119],"134":[2,119],"137":[2,119],"138":[2,119],"139":[2,119],"140":[2,119],"141":[2,119],"142":[2,119],"144":[2,119]},{"4":[2,55],"29":[2,55]},{"4":[2,56],"29":[2,56]},{"1":[2,67],"4":[2,67],"29":[2,67],"30":[2,67],"41":[2,67],"47":[2,67],"55":[2,67],"59":[2,67],"68":[2,67],"69":[2,67],"70":[2,67],"71":[2,67],"74":[2,67],"75":[2,67],"76":[2,67],"77":[2,67],"80":[2,67],"82":[2,67],"88":[2,67],"89":[2,67],"90":[2,67],"94":[2,67],"96":[2,67],"105":[2,67],"107":[2,67],"108":[2,67],"109":[2,67],"113":[2,67],"121":[2,67],"130":[2,67],"131":[2,67],"133":[2,67],"134":[2,67],"135":[2,67],"136":[2,67],"137":[2,67],"138":[2,67],"139":[2,67],"140":[2,67],"141":[2,67],"142":[2,67],"143":[2,67],"144":[2,67]},{"1":[2,70],"4":[2,70],"29":[2,70],"30":[2,70],"41":[2,70],"47":[2,70],"55":[2,70],"59":[2,70],"68":[2,70],"69":[2,70],"70":[2,70],"71":[2,70],"74":[2,70],"75":[2,70],"76":[2,70],"77":[2,70],"80":[2,70],"82":[2,70],"88":[2,70],"89":[2,70],"90":[2,70],"94":[2,70],"96":[2,70],"105":[2,70],"107":[2,70],"108":[2,70],"109":[2,70],"113":[2,70],"121":[2,70],"130":[2,70],"131":[2,70],"133":[2,70],"134":[2,70],"135":[2,70],"136":[2,70],"137":[2,70],"138":[2,70],"139":[2,70],"140":[2,70],"141":[2,70],"142":[2,70],"143":[2,70],"144":[2,70]},{"8":156,"9":124,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"31":64,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":65,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":41,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,43],"103":[1,51],"104":[1,58],"106":44,"107":[1,68],"109":[1,69],"110":45,"111":[1,70],"112":46,"113":[1,71],"114":72,"122":[1,47],"127":42,"128":[1,66],"129":[1,67],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"8":157,"9":124,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"31":64,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":65,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":41,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,43],"103":[1,51],"104":[1,58],"106":44,"107":[1,68],"109":[1,69],"110":45,"111":[1,70],"112":46,"113":[1,71],"114":72,"122":[1,47],"127":42,"128":[1,66],"129":[1,67],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"8":158,"9":124,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"31":64,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":65,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":41,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,43],"103":[1,51],"104":[1,58],"106":44,"107":[1,68],"109":[1,69],"110":45,"111":[1,70],"112":46,"113":[1,71],"114":72,"122":[1,47],"127":42,"128":[1,66],"129":[1,67],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"8":159,"9":124,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"31":64,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":65,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":41,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,43],"103":[1,51],"104":[1,58],"106":44,"107":[1,68],"109":[1,69],"110":45,"111":[1,70],"112":46,"113":[1,71],"114":72,"122":[1,47],"127":42,"128":[1,66],"129":[1,67],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"4":[1,122],"6":160,"8":161,"9":124,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"29":[1,6],"31":64,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":65,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":41,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,43],"103":[1,51],"104":[1,58],"106":44,"107":[1,68],"109":[1,69],"110":45,"111":[1,70],"112":46,"113":[1,71],"114":72,"122":[1,47],"127":42,"128":[1,66],"129":[1,67],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"31":166,"32":[1,76],"63":167,"64":168,"66":162,"78":[1,73],"95":[1,59],"116":163,"117":[1,164],"118":165},{"115":169,"119":[1,170],"120":[1,171]},{"4":[2,89],"28":177,"29":[2,89],"31":174,"32":[1,76],"33":175,"34":[1,74],"35":[1,75],"42":173,"43":176,"46":[1,49],"55":[2,89],"58":[1,178],"79":172,"80":[2,89]},{"1":[2,33],"4":[2,33],"29":[2,33],"30":[2,33],"44":[2,33],"47":[2,33],"55":[2,33],"59":[2,33],"68":[2,33],"69":[2,33],"70":[2,33],"71":[2,33],"74":[2,33],"75":[2,33],"76":[2,33],"77":[2,33],"80":[2,33],"88":[2,33],"89":[2,33],"90":[2,33],"94":[2,33],"96":[2,33],"105":[2,33],"107":[2,33],"108":[2,33],"109":[2,33],"113":[2,33],"121":[2,33],"130":[2,33],"131":[2,33],"133":[2,33],"134":[2,33],"137":[2,33],"138":[2,33],"139":[2,33],"140":[2,33],"141":[2,33],"142":[2,33],"144":[2,33]},{"1":[2,34],"4":[2,34],"29":[2,34],"30":[2,34],"44":[2,34],"47":[2,34],"55":[2,34],"59":[2,34],"68":[2,34],"69":[2,34],"70":[2,34],"71":[2,34],"74":[2,34],"75":[2,34],"76":[2,34],"77":[2,34],"80":[2,34],"88":[2,34],"89":[2,34],"90":[2,34],"94":[2,34],"96":[2,34],"105":[2,34],"107":[2,34],"108":[2,34],"109":[2,34],"113":[2,34],"121":[2,34],"130":[2,34],"131":[2,34],"133":[2,34],"134":[2,34],"137":[2,34],"138":[2,34],"139":[2,34],"140":[2,34],"141":[2,34],"142":[2,34],"144":[2,34]},{"1":[2,32],"4":[2,32],"29":[2,32],"30":[2,32],"41":[2,32],"44":[2,32],"47":[2,32],"55":[2,32],"59":[2,32],"68":[2,32],"69":[2,32],"70":[2,32],"71":[2,32],"74":[2,32],"75":[2,32],"76":[2,32],"77":[2,32],"80":[2,32],"82":[2,32],"88":[2,32],"89":[2,32],"90":[2,32],"94":[2,32],"96":[2,32],"105":[2,32],"107":[2,32],"108":[2,32],"109":[2,32],"113":[2,32],"119":[2,32],"120":[2,32],"121":[2,32],"130":[2,32],"131":[2,32],"133":[2,32],"134":[2,32],"135":[2,32],"136":[2,32],"137":[2,32],"138":[2,32],"139":[2,32],"140":[2,32],"141":[2,32],"142":[2,32],"143":[2,32],"144":[2,32]},{"1":[2,31],"4":[2,31],"29":[2,31],"30":[2,31],"47":[2,31],"55":[2,31],"59":[2,31],"75":[2,31],"80":[2,31],"90":[2,31],"94":[2,31],"96":[2,31],"101":[2,31],"102":[2,31],"105":[2,31],"107":[2,31],"108":[2,31],"109":[2,31],"113":[2,31],"121":[2,31],"124":[2,31],"126":[2,31],"130":[2,31],"131":[2,31],"133":[2,31],"134":[2,31],"137":[2,31],"138":[2,31],"139":[2,31],"140":[2,31],"141":[2,31],"142":[2,31],"144":[2,31]},{"1":[2,7],"4":[2,7],"7":179,"8":7,"9":8,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"30":[2,7],"31":64,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":65,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":41,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,43],"103":[1,51],"104":[1,58],"106":44,"107":[1,68],"109":[1,69],"110":45,"111":[1,70],"112":46,"113":[1,71],"114":72,"122":[1,47],"127":42,"128":[1,66],"129":[1,67],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"1":[2,4]},{"4":[1,78],"30":[1,180]},{"1":[2,30],"4":[2,30],"29":[2,30],"30":[2,30],"47":[2,30],"55":[2,30],"59":[2,30],"75":[2,30],"80":[2,30],"90":[2,30],"94":[2,30],"96":[2,30],"101":[2,30],"102":[2,30],"105":[2,30],"107":[2,30],"108":[2,30],"109":[2,30],"113":[2,30],"121":[2,30],"124":[2,30],"126":[2,30],"130":[2,30],"131":[2,30],"133":[2,30],"134":[2,30],"137":[2,30],"138":[2,30],"139":[2,30],"140":[2,30],"141":[2,30],"142":[2,30],"144":[2,30]},{"8":181,"9":124,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"31":64,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":65,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":41,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,43],"103":[1,51],"104":[1,58],"106":44,"107":[1,68],"109":[1,69],"110":45,"111":[1,70],"112":46,"113":[1,71],"114":72,"122":[1,47],"127":42,"128":[1,66],"129":[1,67],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"8":182,"9":124,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"31":64,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":65,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":41,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,43],"103":[1,51],"104":[1,58],"106":44,"107":[1,68],"109":[1,69],"110":45,"111":[1,70],"112":46,"113":[1,71],"114":72,"122":[1,47],"127":42,"128":[1,66],"129":[1,67],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"8":183,"9":124,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"31":64,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":65,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":41,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,43],"103":[1,51],"104":[1,58],"106":44,"107":[1,68],"109":[1,69],"110":45,"111":[1,70],"112":46,"113":[1,71],"114":72,"122":[1,47],"127":42,"128":[1,66],"129":[1,67],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"8":184,"9":124,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"31":64,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":65,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":41,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,43],"103":[1,51],"104":[1,58],"106":44,"107":[1,68],"109":[1,69],"110":45,"111":[1,70],"112":46,"113":[1,71],"114":72,"122":[1,47],"127":42,"128":[1,66],"129":[1,67],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"8":185,"9":124,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"31":64,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":65,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":41,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,43],"103":[1,51],"104":[1,58],"106":44,"107":[1,68],"109":[1,69],"110":45,"111":[1,70],"112":46,"113":[1,71],"114":72,"122":[1,47],"127":42,"128":[1,66],"129":[1,67],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"8":186,"9":124,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"31":64,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":65,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":41,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,43],"103":[1,51],"104":[1,58],"106":44,"107":[1,68],"109":[1,69],"110":45,"111":[1,70],"112":46,"113":[1,71],"114":72,"122":[1,47],"127":42,"128":[1,66],"129":[1,67],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"8":187,"9":124,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"31":64,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":65,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":41,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,43],"103":[1,51],"104":[1,58],"106":44,"107":[1,68],"109":[1,69],"110":45,"111":[1,70],"112":46,"113":[1,71],"114":72,"122":[1,47],"127":42,"128":[1,66],"129":[1,67],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"8":188,"9":124,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"31":64,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":65,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":41,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,43],"103":[1,51],"104":[1,58],"106":44,"107":[1,68],"109":[1,69],"110":45,"111":[1,70],"112":46,"113":[1,71],"114":72,"122":[1,47],"127":42,"128":[1,66],"129":[1,67],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"8":189,"9":124,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"31":64,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":65,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":41,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,43],"103":[1,51],"104":[1,58],"106":44,"107":[1,68],"109":[1,69],"110":45,"111":[1,70],"112":46,"113":[1,71],"114":72,"122":[1,47],"127":42,"128":[1,66],"129":[1,67],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"8":190,"9":124,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"31":64,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":65,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":41,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,43],"103":[1,51],"104":[1,58],"106":44,"107":[1,68],"109":[1,69],"110":45,"111":[1,70],"112":46,"113":[1,71],"114":72,"122":[1,47],"127":42,"128":[1,66],"129":[1,67],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"8":191,"9":124,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"31":64,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":65,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":41,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,43],"103":[1,51],"104":[1,58],"106":44,"107":[1,68],"109":[1,69],"110":45,"111":[1,70],"112":46,"113":[1,71],"114":72,"122":[1,47],"127":42,"128":[1,66],"129":[1,67],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"1":[2,152],"4":[2,152],"29":[2,152],"30":[2,152],"47":[2,152],"55":[2,152],"59":[2,152],"75":[2,152],"80":[2,152],"90":[2,152],"94":[2,152],"96":[2,152],"105":[2,152],"107":[2,152],"108":[2,152],"109":[2,152],"113":[2,152],"121":[2,152],"130":[2,152],"131":[2,152],"133":[2,152],"134":[2,152],"137":[2,152],"138":[2,152],"139":[2,152],"140":[2,152],"141":[2,152],"142":[2,152],"144":[2,152]},{"1":[2,157],"4":[2,157],"29":[2,157],"30":[2,157],"47":[2,157],"55":[2,157],"59":[2,157],"75":[2,157],"80":[2,157],"90":[2,157],"94":[2,157],"96":[2,157],"105":[2,157],"107":[2,157],"108":[2,157],"109":[2,157],"113":[2,157],"121":[2,157],"130":[2,157],"131":[2,157],"133":[2,157],"134":[2,157],"137":[2,157],"138":[2,157],"139":[2,157],"140":[2,157],"141":[2,157],"142":[2,157],"144":[2,157]},{"1":[2,52],"4":[2,52],"29":[2,52],"30":[2,52],"47":[2,52],"55":[2,52],"59":[2,52],"75":[2,52],"80":[2,52],"90":[2,52],"94":[2,52],"96":[2,52],"105":[2,52],"107":[2,52],"108":[2,52],"109":[2,52],"113":[2,52],"121":[2,52],"130":[2,52],"131":[2,52],"133":[2,52],"134":[2,52],"137":[2,52],"138":[2,52],"139":[2,52],"140":[2,52],"141":[2,52],"142":[2,52],"144":[2,52]},{"8":192,"9":124,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"31":64,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":65,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":41,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,43],"103":[1,51],"104":[1,58],"106":44,"107":[1,68],"109":[1,69],"110":45,"111":[1,70],"112":46,"113":[1,71],"114":72,"122":[1,47],"127":42,"128":[1,66],"129":[1,67],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"8":193,"9":124,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"31":64,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":65,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":41,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,43],"103":[1,51],"104":[1,58],"106":44,"107":[1,68],"109":[1,69],"110":45,"111":[1,70],"112":46,"113":[1,71],"114":72,"122":[1,47],"127":42,"128":[1,66],"129":[1,67],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"1":[2,151],"4":[2,151],"29":[2,151],"30":[2,151],"47":[2,151],"55":[2,151],"59":[2,151],"75":[2,151],"80":[2,151],"90":[2,151],"94":[2,151],"96":[2,151],"105":[2,151],"107":[2,151],"108":[2,151],"109":[2,151],"113":[2,151],"121":[2,151],"130":[2,151],"131":[2,151],"133":[2,151],"134":[2,151],"137":[2,151],"138":[2,151],"139":[2,151],"140":[2,151],"141":[2,151],"142":[2,151],"144":[2,151]},{"1":[2,156],"4":[2,156],"29":[2,156],"30":[2,156],"47":[2,156],"55":[2,156],"59":[2,156],"75":[2,156],"80":[2,156],"90":[2,156],"94":[2,156],"96":[2,156],"105":[2,156],"107":[2,156],"108":[2,156],"109":[2,156],"113":[2,156],"121":[2,156],"130":[2,156],"131":[2,156],"133":[2,156],"134":[2,156],"137":[2,156],"138":[2,156],"139":[2,156],"140":[2,156],"141":[2,156],"142":[2,156],"144":[2,156]},{"86":194,"89":[1,116]},{"1":[2,68],"4":[2,68],"29":[2,68],"30":[2,68],"41":[2,68],"47":[2,68],"55":[2,68],"59":[2,68],"68":[2,68],"69":[2,68],"70":[2,68],"71":[2,68],"74":[2,68],"75":[2,68],"76":[2,68],"77":[2,68],"80":[2,68],"82":[2,68],"88":[2,68],"89":[2,68],"90":[2,68],"94":[2,68],"96":[2,68],"105":[2,68],"107":[2,68],"108":[2,68],"109":[2,68],"113":[2,68],"121":[2,68],"130":[2,68],"131":[2,68],"133":[2,68],"134":[2,68],"135":[2,68],"136":[2,68],"137":[2,68],"138":[2,68],"139":[2,68],"140":[2,68],"141":[2,68],"142":[2,68],"143":[2,68],"144":[2,68]},{"89":[2,115]},{"31":195,"32":[1,76]},{"31":196,"32":[1,76]},{"1":[2,81],"4":[2,81],"29":[2,81],"30":[2,81],"41":[2,81],"47":[2,81],"55":[2,81],"59":[2,81],"68":[2,81],"69":[2,81],"70":[2,81],"71":[2,81],"74":[2,81],"75":[2,81],"76":[2,81],"77":[2,81],"80":[2,81],"82":[2,81],"88":[2,81],"89":[2,81],"90":[2,81],"94":[2,81],"96":[2,81],"105":[2,81],"107":[2,81],"108":[2,81],"109":[2,81],"113":[2,81],"121":[2,81],"130":[2,81],"131":[2,81],"133":[2,81],"134":[2,81],"135":[2,81],"136":[2,81],"137":[2,81],"138":[2,81],"139":[2,81],"140":[2,81],"141":[2,81],"142":[2,81],"143":[2,81],"144":[2,81]},{"31":197,"32":[1,76]},{"1":[2,83],"4":[2,83],"29":[2,83],"30":[2,83],"41":[2,83],"47":[2,83],"55":[2,83],"59":[2,83],"68":[2,83],"69":[2,83],"70":[2,83],"71":[2,83],"74":[2,83],"75":[2,83],"76":[2,83],"77":[2,83],"80":[2,83],"82":[2,83],"88":[2,83],"89":[2,83],"90":[2,83],"94":[2,83],"96":[2,83],"105":[2,83],"107":[2,83],"108":[2,83],"109":[2,83],"113":[2,83],"121":[2,83],"130":[2,83],"131":[2,83],"133":[2,83],"134":[2,83],"135":[2,83],"136":[2,83],"137":[2,83],"138":[2,83],"139":[2,83],"140":[2,83],"141":[2,83],"142":[2,83],"143":[2,83],"144":[2,83]},{"1":[2,84],"4":[2,84],"29":[2,84],"30":[2,84],"41":[2,84],"47":[2,84],"55":[2,84],"59":[2,84],"68":[2,84],"69":[2,84],"70":[2,84],"71":[2,84],"74":[2,84],"75":[2,84],"76":[2,84],"77":[2,84],"80":[2,84],"82":[2,84],"88":[2,84],"89":[2,84],"90":[2,84],"94":[2,84],"96":[2,84],"105":[2,84],"107":[2,84],"108":[2,84],"109":[2,84],"113":[2,84],"121":[2,84],"130":[2,84],"131":[2,84],"133":[2,84],"134":[2,84],"135":[2,84],"136":[2,84],"137":[2,84],"138":[2,84],"139":[2,84],"140":[2,84],"141":[2,84],"142":[2,84],"143":[2,84],"144":[2,84]},{"8":198,"9":124,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"31":64,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":65,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"59":[1,201],"61":41,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"93":199,"94":[1,200],"95":[1,59],"99":[1,43],"103":[1,51],"104":[1,58],"106":44,"107":[1,68],"109":[1,69],"110":45,"111":[1,70],"112":46,"113":[1,71],"114":72,"122":[1,47],"127":42,"128":[1,66],"129":[1,67],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"72":202,"74":[1,203],"76":[1,110],"77":[1,111]},{"72":204,"74":[1,203],"76":[1,110],"77":[1,111]},{"86":205,"89":[1,116]},{"1":[2,69],"4":[2,69],"29":[2,69],"30":[2,69],"41":[2,69],"47":[2,69],"55":[2,69],"59":[2,69],"68":[2,69],"69":[2,69],"70":[2,69],"71":[2,69],"74":[2,69],"75":[2,69],"76":[2,69],"77":[2,69],"80":[2,69],"82":[2,69],"88":[2,69],"89":[2,69],"90":[2,69],"94":[2,69],"96":[2,69],"105":[2,69],"107":[2,69],"108":[2,69],"109":[2,69],"113":[2,69],"121":[2,69],"130":[2,69],"131":[2,69],"133":[2,69],"134":[2,69],"135":[2,69],"136":[2,69],"137":[2,69],"138":[2,69],"139":[2,69],"140":[2,69],"141":[2,69],"142":[2,69],"143":[2,69],"144":[2,69]},{"8":206,"9":124,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"29":[1,207],"31":64,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":65,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":41,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,43],"103":[1,51],"104":[1,58],"106":44,"107":[1,68],"109":[1,69],"110":45,"111":[1,70],"112":46,"113":[1,71],"114":72,"122":[1,47],"127":42,"128":[1,66],"129":[1,67],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"1":[2,113],"4":[2,113],"29":[2,113],"30":[2,113],"47":[2,113],"55":[2,113],"59":[2,113],"68":[2,113],"69":[2,113],"70":[2,113],"71":[2,113],"74":[2,113],"75":[2,113],"76":[2,113],"77":[2,113],"80":[2,113],"88":[2,113],"89":[2,113],"90":[2,113],"94":[2,113],"96":[2,113],"105":[2,113],"107":[2,113],"108":[2,113],"109":[2,113],"113":[2,113],"121":[2,113],"130":[2,113],"131":[2,113],"133":[2,113],"134":[2,113],"137":[2,113],"138":[2,113],"139":[2,113],"140":[2,113],"141":[2,113],"142":[2,113],"144":[2,113]},{"8":210,"9":124,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"29":[1,153],"31":64,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":65,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"60":154,"61":41,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"90":[1,208],"91":209,"92":[1,60],"95":[1,59],"97":152,"99":[1,43],"103":[1,51],"104":[1,58],"106":44,"107":[1,68],"109":[1,69],"110":45,"111":[1,70],"112":46,"113":[1,71],"114":72,"122":[1,47],"127":42,"128":[1,66],"129":[1,67],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"50":[1,211],"55":[1,212]},{"50":[2,60],"55":[2,60]},{"50":[2,62],"55":[2,62],"59":[1,213]},{"57":[1,214]},{"1":[2,54],"4":[2,54],"29":[2,54],"30":[2,54],"47":[2,54],"55":[2,54],"59":[2,54],"75":[2,54],"80":[2,54],"90":[2,54],"94":[2,54],"96":[2,54],"105":[2,54],"107":[2,54],"108":[2,54],"109":[2,54],"113":[2,54],"121":[2,54],"130":[2,54],"131":[2,54],"133":[2,54],"134":[2,54],"137":[2,54],"138":[2,54],"139":[2,54],"140":[2,54],"141":[2,54],"142":[2,54],"144":[2,54]},{"28":77,"46":[1,49]},{"1":[2,192],"4":[2,192],"29":[2,192],"30":[2,192],"47":[1,95],"55":[2,192],"59":[2,192],"75":[2,192],"80":[2,192],"90":[2,192],"94":[2,192],"96":[2,192],"105":[2,192],"106":93,"107":[2,192],"108":[2,192],"109":[2,192],"112":94,"113":[2,192],"114":72,"121":[2,192],"130":[2,192],"131":[2,192],"133":[2,192],"134":[2,192],"137":[2,192],"138":[2,192],"139":[2,192],"140":[2,192],"141":[2,192],"142":[2,192],"144":[2,192]},{"106":98,"107":[1,68],"109":[1,69],"112":99,"113":[1,71],"114":72,"130":[1,96],"131":[1,97]},{"1":[2,193],"4":[2,193],"29":[2,193],"30":[2,193],"47":[1,95],"55":[2,193],"59":[2,193],"75":[2,193],"80":[2,193],"90":[2,193],"94":[2,193],"96":[2,193],"105":[2,193],"106":93,"107":[2,193],"108":[2,193],"109":[2,193],"112":94,"113":[2,193],"114":72,"121":[2,193],"130":[2,193],"131":[2,193],"133":[2,193],"134":[2,193],"137":[2,193],"138":[2,193],"139":[2,193],"140":[2,193],"141":[2,193],"142":[2,193],"144":[2,193]},{"1":[2,194],"4":[2,194],"29":[2,194],"30":[2,194],"47":[1,95],"55":[2,194],"59":[2,194],"75":[2,194],"80":[2,194],"90":[2,194],"94":[2,194],"96":[2,194],"105":[2,194],"106":93,"107":[2,194],"108":[2,194],"109":[2,194],"112":94,"113":[2,194],"114":72,"121":[2,194],"130":[2,194],"131":[2,194],"133":[2,194],"134":[2,194],"137":[2,194],"138":[2,194],"139":[2,194],"140":[2,194],"141":[2,194],"142":[2,194],"144":[2,194]},{"1":[2,195],"4":[2,195],"29":[2,195],"30":[2,195],"47":[2,195],"55":[2,195],"59":[2,195],"68":[2,71],"69":[2,71],"70":[2,71],"71":[2,71],"74":[2,71],"75":[2,195],"76":[2,71],"77":[2,71],"80":[2,195],"88":[2,71],"89":[2,71],"90":[2,195],"94":[2,195],"96":[2,195],"105":[2,195],"107":[2,195],"108":[2,195],"109":[2,195],"113":[2,195],"121":[2,195],"130":[2,195],"131":[2,195],"133":[2,195],"134":[2,195],"137":[2,195],"138":[2,195],"139":[2,195],"140":[2,195],"141":[2,195],"142":[2,195],"144":[2,195]},{"62":101,"68":[1,103],"69":[1,104],"70":[1,105],"71":[1,106],"72":107,"73":108,"74":[1,109],"76":[1,110],"77":[1,111],"85":100,"88":[1,102],"89":[2,114]},{"62":113,"68":[1,103],"69":[1,104],"70":[1,105],"71":[1,106],"72":107,"73":108,"74":[1,109],"76":[1,110],"77":[1,111],"85":112,"88":[1,102],"89":[2,114]},{"1":[2,74],"4":[2,74],"29":[2,74],"30":[2,74],"47":[2,74],"55":[2,74],"59":[2,74],"68":[2,74],"69":[2,74],"70":[2,74],"71":[2,74],"74":[2,74],"75":[2,74],"76":[2,74],"77":[2,74],"80":[2,74],"88":[2,74],"89":[2,74],"90":[2,74],"94":[2,74],"96":[2,74],"105":[2,74],"107":[2,74],"108":[2,74],"109":[2,74],"113":[2,74],"121":[2,74],"130":[2,74],"131":[2,74],"133":[2,74],"134":[2,74],"137":[2,74],"138":[2,74],"139":[2,74],"140":[2,74],"141":[2,74],"142":[2,74],"144":[2,74]},{"1":[2,196],"4":[2,196],"29":[2,196],"30":[2,196],"47":[2,196],"55":[2,196],"59":[2,196],"68":[2,71],"69":[2,71],"70":[2,71],"71":[2,71],"74":[2,71],"75":[2,196],"76":[2,71],"77":[2,71],"80":[2,196],"88":[2,71],"89":[2,71],"90":[2,196],"94":[2,196],"96":[2,196],"105":[2,196],"107":[2,196],"108":[2,196],"109":[2,196],"113":[2,196],"121":[2,196],"130":[2,196],"131":[2,196],"133":[2,196],"134":[2,196],"137":[2,196],"138":[2,196],"139":[2,196],"140":[2,196],"141":[2,196],"142":[2,196],"144":[2,196]},{"1":[2,197],"4":[2,197],"29":[2,197],"30":[2,197],"47":[2,197],"55":[2,197],"59":[2,197],"75":[2,197],"80":[2,197],"90":[2,197],"94":[2,197],"96":[2,197],"105":[2,197],"107":[2,197],"108":[2,197],"109":[2,197],"113":[2,197],"121":[2,197],"130":[2,197],"131":[2,197],"133":[2,197],"134":[2,197],"137":[2,197],"138":[2,197],"139":[2,197],"140":[2,197],"141":[2,197],"142":[2,197],"144":[2,197]},{"1":[2,198],"4":[2,198],"29":[2,198],"30":[2,198],"47":[2,198],"55":[2,198],"59":[2,198],"75":[2,198],"80":[2,198],"90":[2,198],"94":[2,198],"96":[2,198],"105":[2,198],"107":[2,198],"108":[2,198],"109":[2,198],"113":[2,198],"121":[2,198],"130":[2,198],"131":[2,198],"133":[2,198],"134":[2,198],"137":[2,198],"138":[2,198],"139":[2,198],"140":[2,198],"141":[2,198],"142":[2,198],"144":[2,198]},{"8":215,"9":124,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"29":[1,216],"31":64,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":65,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":41,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,43],"103":[1,51],"104":[1,58],"106":44,"107":[1,68],"109":[1,69],"110":45,"111":[1,70],"112":46,"113":[1,71],"114":72,"122":[1,47],"127":42,"128":[1,66],"129":[1,67],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"15":217,"16":129,"31":64,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":130,"43":65,"58":[1,61],"61":218,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"87":[1,33],"92":[1,60],"95":[1,59],"104":[1,58]},{"4":[1,122],"6":220,"29":[1,6],"128":[1,219]},{"1":[2,138],"4":[2,138],"29":[2,138],"30":[2,138],"47":[2,138],"55":[2,138],"59":[2,138],"75":[2,138],"80":[2,138],"90":[2,138],"94":[2,138],"96":[2,138],"100":221,"101":[1,222],"102":[1,223],"105":[2,138],"107":[2,138],"108":[2,138],"109":[2,138],"113":[2,138],"121":[2,138],"130":[2,138],"131":[2,138],"133":[2,138],"134":[2,138],"137":[2,138],"138":[2,138],"139":[2,138],"140":[2,138],"141":[2,138],"142":[2,138],"144":[2,138]},{"1":[2,150],"4":[2,150],"29":[2,150],"30":[2,150],"47":[2,150],"55":[2,150],"59":[2,150],"75":[2,150],"80":[2,150],"90":[2,150],"94":[2,150],"96":[2,150],"105":[2,150],"107":[2,150],"108":[2,150],"109":[2,150],"113":[2,150],"121":[2,150],"130":[2,150],"131":[2,150],"133":[2,150],"134":[2,150],"137":[2,150],"138":[2,150],"139":[2,150],"140":[2,150],"141":[2,150],"142":[2,150],"144":[2,150]},{"1":[2,158],"4":[2,158],"29":[2,158],"30":[2,158],"47":[2,158],"55":[2,158],"59":[2,158],"75":[2,158],"80":[2,158],"90":[2,158],"94":[2,158],"96":[2,158],"105":[2,158],"107":[2,158],"108":[2,158],"109":[2,158],"113":[2,158],"121":[2,158],"130":[2,158],"131":[2,158],"133":[2,158],"134":[2,158],"137":[2,158],"138":[2,158],"139":[2,158],"140":[2,158],"141":[2,158],"142":[2,158],"144":[2,158]},{"29":[1,224],"47":[1,95],"106":93,"107":[1,68],"109":[1,69],"112":94,"113":[1,71],"114":72,"130":[1,91],"131":[1,92],"133":[1,83],"134":[1,82],"137":[1,84],"138":[1,85],"139":[1,86],"140":[1,87],"141":[1,88],"142":[1,89],"144":[1,90]},{"123":225,"125":226,"126":[1,227]},{"1":[2,94],"4":[2,94],"29":[1,229],"30":[2,94],"47":[2,94],"55":[2,94],"59":[2,94],"68":[2,71],"69":[2,71],"70":[2,71],"71":[2,71],"74":[2,71],"75":[2,94],"76":[2,71],"77":[2,71],"80":[2,94],"82":[1,228],"88":[2,71],"89":[2,71],"90":[2,94],"94":[2,94],"96":[2,94],"105":[2,94],"107":[2,94],"108":[2,94],"109":[2,94],"113":[2,94],"121":[2,94],"130":[2,94],"131":[2,94],"133":[2,94],"134":[2,94],"137":[2,94],"138":[2,94],"139":[2,94],"140":[2,94],"141":[2,94],"142":[2,94],"144":[2,94]},{"4":[2,105],"28":177,"30":[2,105],"31":174,"32":[1,76],"33":175,"34":[1,74],"35":[1,75],"42":233,"43":234,"46":[1,49],"58":[1,178],"78":[1,232],"83":230,"84":231},{"15":235,"16":129,"31":64,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":130,"43":65,"58":[1,61],"61":218,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"87":[1,33],"92":[1,60],"95":[1,59],"104":[1,58]},{"1":[2,49],"4":[2,49],"30":[2,49],"47":[1,95],"106":93,"107":[1,68],"109":[1,69],"112":94,"113":[1,71],"114":72,"130":[2,49],"131":[2,49],"133":[1,83],"134":[1,82],"137":[1,84],"138":[1,85],"139":[1,86],"140":[1,87],"141":[1,88],"142":[1,89],"144":[1,90]},{"1":[2,143],"4":[2,143],"30":[2,143],"47":[1,95],"106":93,"107":[2,143],"109":[2,143],"112":94,"113":[2,143],"114":72,"130":[2,143],"131":[2,143],"133":[1,83],"134":[1,82],"137":[1,84],"138":[1,85],"139":[1,86],"140":[1,87],"141":[1,88],"142":[1,89],"144":[1,90]},{"47":[1,95],"105":[1,236],"106":93,"107":[1,68],"109":[1,69],"112":94,"113":[1,71],"114":72,"130":[1,91],"131":[1,92],"133":[1,83],"134":[1,82],"137":[1,84],"138":[1,85],"139":[1,86],"140":[1,87],"141":[1,88],"142":[1,89],"144":[1,90]},{"1":[2,145],"4":[2,145],"29":[2,145],"30":[2,145],"47":[2,145],"55":[2,145],"59":[2,145],"68":[2,145],"69":[2,145],"70":[2,145],"71":[2,145],"74":[2,145],"75":[2,145],"76":[2,145],"77":[2,145],"80":[2,145],"88":[2,145],"89":[2,145],"90":[2,145],"94":[2,145],"96":[2,145],"105":[2,145],"107":[2,145],"108":[2,145],"109":[2,145],"113":[2,145],"121":[2,145],"130":[2,145],"131":[2,145],"133":[2,145],"134":[2,145],"137":[2,145],"138":[2,145],"139":[2,145],"140":[2,145],"141":[2,145],"142":[2,145],"144":[2,145]},{"4":[2,134],"29":[2,134],"47":[1,95],"55":[2,134],"59":[1,238],"93":237,"94":[1,200],"96":[2,134],"106":93,"107":[1,68],"109":[1,69],"112":94,"113":[1,71],"114":72,"130":[1,91],"131":[1,92],"133":[1,83],"134":[1,82],"137":[1,84],"138":[1,85],"139":[1,86],"140":[1,87],"141":[1,88],"142":[1,89],"144":[1,90]},{"1":[2,127],"4":[2,127],"29":[2,127],"30":[2,127],"41":[2,127],"47":[2,127],"55":[2,127],"59":[2,127],"68":[2,127],"69":[2,127],"70":[2,127],"71":[2,127],"74":[2,127],"75":[2,127],"76":[2,127],"77":[2,127],"80":[2,127],"88":[2,127],"89":[2,127],"90":[2,127],"94":[2,127],"96":[2,127],"105":[2,127],"107":[2,127],"108":[2,127],"109":[2,127],"113":[2,127],"119":[2,127],"120":[2,127],"121":[2,127],"130":[2,127],"131":[2,127],"133":[2,127],"134":[2,127],"137":[2,127],"138":[2,127],"139":[2,127],"140":[2,127],"141":[2,127],"142":[2,127],"144":[2,127]},{"4":[2,57],"29":[2,57],"54":239,"55":[1,240],"96":[2,57]},{"4":[2,129],"29":[2,129],"30":[2,129],"55":[2,129],"90":[2,129],"96":[2,129]},{"8":210,"9":124,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"29":[1,153],"31":64,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":65,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"60":154,"61":41,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"91":241,"92":[1,60],"95":[1,59],"97":152,"99":[1,43],"103":[1,51],"104":[1,58],"106":44,"107":[1,68],"109":[1,69],"110":45,"111":[1,70],"112":46,"113":[1,71],"114":72,"122":[1,47],"127":42,"128":[1,66],"129":[1,67],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"4":[2,135],"29":[2,135],"30":[2,135],"55":[2,135],"90":[2,135],"96":[2,135]},{"1":[2,122],"4":[2,122],"29":[2,122],"30":[2,122],"41":[2,122],"44":[2,122],"47":[2,122],"55":[2,122],"59":[2,122],"68":[2,122],"69":[2,122],"70":[2,122],"71":[2,122],"74":[2,122],"75":[2,122],"76":[2,122],"77":[2,122],"80":[2,122],"82":[2,122],"88":[2,122],"89":[2,122],"90":[2,122],"94":[2,122],"96":[2,122],"105":[2,122],"107":[2,122],"108":[2,122],"109":[2,122],"113":[2,122],"121":[2,122],"130":[2,122],"131":[2,122],"133":[2,122],"134":[2,122],"135":[2,122],"136":[2,122],"137":[2,122],"138":[2,122],"139":[2,122],"140":[2,122],"141":[2,122],"142":[2,122],"143":[2,122],"144":[2,122]},{"4":[1,122],"6":242,"29":[1,6],"47":[1,95],"106":93,"107":[1,68],"109":[1,69],"112":94,"113":[1,71],"114":72,"130":[1,91],"131":[1,92],"133":[1,83],"134":[1,82],"137":[1,84],"138":[1,85],"139":[1,86],"140":[1,87],"141":[1,88],"142":[1,89],"144":[1,90]},{"4":[1,122],"6":243,"29":[1,6],"47":[1,95],"106":93,"107":[1,68],"109":[1,69],"112":94,"113":[1,71],"114":72,"130":[1,91],"131":[1,92],"133":[1,83],"134":[1,82],"137":[1,84],"138":[1,85],"139":[1,86],"140":[1,87],"141":[1,88],"142":[1,89],"144":[1,90]},{"1":[2,146],"4":[2,146],"29":[2,146],"30":[2,146],"47":[1,95],"55":[2,146],"59":[2,146],"75":[2,146],"80":[2,146],"90":[2,146],"94":[2,146],"96":[2,146],"105":[2,146],"106":93,"107":[1,68],"108":[1,244],"109":[1,69],"112":94,"113":[1,71],"114":72,"121":[2,146],"130":[2,146],"131":[2,146],"133":[1,83],"134":[1,82],"137":[1,84],"138":[1,85],"139":[1,86],"140":[1,87],"141":[1,88],"142":[1,89],"144":[1,90]},{"1":[2,148],"4":[2,148],"29":[2,148],"30":[2,148],"47":[1,95],"55":[2,148],"59":[2,148],"75":[2,148],"80":[2,148],"90":[2,148],"94":[2,148],"96":[2,148],"105":[2,148],"106":93,"107":[1,68],"108":[1,245],"109":[1,69],"112":94,"113":[1,71],"114":72,"121":[2,148],"130":[2,148],"131":[2,148],"133":[1,83],"134":[1,82],"137":[1,84],"138":[1,85],"139":[1,86],"140":[1,87],"141":[1,88],"142":[1,89],"144":[1,90]},{"1":[2,154],"4":[2,154],"29":[2,154],"30":[2,154],"47":[2,154],"55":[2,154],"59":[2,154],"75":[2,154],"80":[2,154],"90":[2,154],"94":[2,154],"96":[2,154],"105":[2,154],"107":[2,154],"108":[2,154],"109":[2,154],"113":[2,154],"121":[2,154],"130":[2,154],"131":[2,154],"133":[2,154],"134":[2,154],"137":[2,154],"138":[2,154],"139":[2,154],"140":[2,154],"141":[2,154],"142":[2,154],"144":[2,154]},{"1":[2,155],"4":[2,155],"29":[2,155],"30":[2,155],"47":[1,95],"55":[2,155],"59":[2,155],"75":[2,155],"80":[2,155],"90":[2,155],"94":[2,155],"96":[2,155],"105":[2,155],"106":93,"107":[1,68],"108":[2,155],"109":[1,69],"112":94,"113":[1,71],"114":72,"121":[2,155],"130":[2,155],"131":[2,155],"133":[1,83],"134":[1,82],"137":[1,84],"138":[1,85],"139":[1,86],"140":[1,87],"141":[1,88],"142":[1,89],"144":[1,90]},{"1":[2,159],"4":[2,159],"29":[2,159],"30":[2,159],"47":[2,159],"55":[2,159],"59":[2,159],"75":[2,159],"80":[2,159],"90":[2,159],"94":[2,159],"96":[2,159],"105":[2,159],"107":[2,159],"108":[2,159],"109":[2,159],"113":[2,159],"121":[2,159],"130":[2,159],"131":[2,159],"133":[2,159],"134":[2,159],"137":[2,159],"138":[2,159],"139":[2,159],"140":[2,159],"141":[2,159],"142":[2,159],"144":[2,159]},{"119":[2,161],"120":[2,161]},{"31":166,"32":[1,76],"63":167,"64":168,"78":[1,73],"95":[1,247],"116":246,"118":165},{"55":[1,248],"119":[2,166],"120":[2,166]},{"55":[2,163],"119":[2,163],"120":[2,163]},{"55":[2,164],"119":[2,164],"120":[2,164]},{"55":[2,165],"119":[2,165],"120":[2,165]},{"1":[2,160],"4":[2,160],"29":[2,160],"30":[2,160],"47":[2,160],"55":[2,160],"59":[2,160],"75":[2,160],"80":[2,160],"90":[2,160],"94":[2,160],"96":[2,160],"105":[2,160],"107":[2,160],"108":[2,160],"109":[2,160],"113":[2,160],"121":[2,160],"130":[2,160],"131":[2,160],"133":[2,160],"134":[2,160],"137":[2,160],"138":[2,160],"139":[2,160],"140":[2,160],"141":[2,160],"142":[2,160],"144":[2,160]},{"8":249,"9":124,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"31":64,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":65,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":41,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,43],"103":[1,51],"104":[1,58],"106":44,"107":[1,68],"109":[1,69],"110":45,"111":[1,70],"112":46,"113":[1,71],"114":72,"122":[1,47],"127":42,"128":[1,66],"129":[1,67],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"8":250,"9":124,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"31":64,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":65,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":41,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,43],"103":[1,51],"104":[1,58],"106":44,"107":[1,68],"109":[1,69],"110":45,"111":[1,70],"112":46,"113":[1,71],"114":72,"122":[1,47],"127":42,"128":[1,66],"129":[1,67],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"4":[2,57],"29":[2,57],"54":251,"55":[1,252],"80":[2,57]},{"4":[2,90],"29":[2,90],"30":[2,90],"55":[2,90],"80":[2,90]},{"4":[2,41],"29":[2,41],"30":[2,41],"44":[1,253],"55":[2,41],"80":[2,41]},{"4":[2,42],"29":[2,42],"30":[2,42],"44":[1,254],"55":[2,42],"80":[2,42]},{"4":[2,43],"29":[2,43],"30":[2,43],"55":[2,43],"80":[2,43]},{"4":[2,48],"29":[2,48],"30":[2,48],"55":[2,48],"80":[2,48]},{"31":155,"32":[1,76]},{"1":[2,6],"4":[2,6],"30":[2,6]},{"1":[2,29],"4":[2,29],"29":[2,29],"30":[2,29],"47":[2,29],"55":[2,29],"59":[2,29],"75":[2,29],"80":[2,29],"90":[2,29],"94":[2,29],"96":[2,29],"101":[2,29],"102":[2,29],"105":[2,29],"107":[2,29],"108":[2,29],"109":[2,29],"113":[2,29],"121":[2,29],"124":[2,29],"126":[2,29],"130":[2,29],"131":[2,29],"133":[2,29],"134":[2,29],"137":[2,29],"138":[2,29],"139":[2,29],"140":[2,29],"141":[2,29],"142":[2,29],"144":[2,29]},{"1":[2,199],"4":[2,199],"29":[2,199],"30":[2,199],"47":[1,95],"55":[2,199],"59":[2,199],"75":[2,199],"80":[2,199],"90":[2,199],"94":[2,199],"96":[2,199],"105":[2,199],"106":93,"107":[2,199],"108":[2,199],"109":[2,199],"112":94,"113":[2,199],"114":72,"121":[2,199],"130":[2,199],"131":[2,199],"133":[2,199],"134":[2,199],"137":[2,199],"138":[2,199],"139":[1,86],"140":[2,199],"141":[2,199],"142":[2,199],"144":[2,199]},{"1":[2,200],"4":[2,200],"29":[2,200],"30":[2,200],"47":[1,95],"55":[2,200],"59":[2,200],"75":[2,200],"80":[2,200],"90":[2,200],"94":[2,200],"96":[2,200],"105":[2,200],"106":93,"107":[2,200],"108":[2,200],"109":[2,200],"112":94,"113":[2,200],"114":72,"121":[2,200],"130":[2,200],"131":[2,200],"133":[2,200],"134":[2,200],"137":[2,200],"138":[2,200],"139":[1,86],"140":[2,200],"141":[2,200],"142":[2,200],"144":[2,200]},{"1":[2,201],"4":[2,201],"29":[2,201],"30":[2,201],"47":[1,95],"55":[2,201],"59":[2,201],"75":[2,201],"80":[2,201],"90":[2,201],"94":[2,201],"96":[2,201],"105":[2,201],"106":93,"107":[2,201],"108":[2,201],"109":[2,201],"112":94,"113":[2,201],"114":72,"121":[2,201],"130":[2,201],"131":[2,201],"133":[1,83],"134":[1,82],"137":[2,201],"138":[2,201],"139":[1,86],"140":[1,87],"141":[1,88],"142":[2,201],"144":[1,90]},{"1":[2,202],"4":[2,202],"29":[2,202],"30":[2,202],"47":[1,95],"55":[2,202],"59":[2,202],"75":[2,202],"80":[2,202],"90":[2,202],"94":[2,202],"96":[2,202],"105":[2,202],"106":93,"107":[2,202],"108":[2,202],"109":[2,202],"112":94,"113":[2,202],"114":72,"121":[2,202],"130":[2,202],"131":[2,202],"133":[1,83],"134":[1,82],"137":[2,202],"138":[2,202],"139":[1,86],"140":[1,87],"141":[1,88],"142":[2,202],"144":[1,90]},{"1":[2,203],"4":[2,203],"29":[2,203],"30":[2,203],"47":[1,95],"55":[2,203],"59":[2,203],"75":[2,203],"80":[2,203],"90":[2,203],"94":[2,203],"96":[2,203],"105":[2,203],"106":93,"107":[2,203],"108":[2,203],"109":[2,203],"112":94,"113":[2,203],"114":72,"121":[2,203],"130":[2,203],"131":[2,203],"133":[2,203],"134":[2,203],"137":[2,203],"138":[2,203],"139":[2,203],"140":[2,203],"141":[2,203],"142":[2,203],"144":[2,203]},{"1":[2,204],"4":[2,204],"29":[2,204],"30":[2,204],"47":[1,95],"55":[2,204],"59":[2,204],"75":[2,204],"80":[2,204],"90":[2,204],"94":[2,204],"96":[2,204],"105":[2,204],"106":93,"107":[2,204],"108":[2,204],"109":[2,204],"112":94,"113":[2,204],"114":72,"121":[2,204],"130":[2,204],"131":[2,204],"133":[1,83],"134":[1,82],"137":[2,204],"138":[2,204],"139":[1,86],"140":[2,204],"141":[2,204],"142":[2,204],"144":[2,204]},{"1":[2,205],"4":[2,205],"29":[2,205],"30":[2,205],"47":[1,95],"55":[2,205],"59":[2,205],"75":[2,205],"80":[2,205],"90":[2,205],"94":[2,205],"96":[2,205],"105":[2,205],"106":93,"107":[2,205],"108":[2,205],"109":[2,205],"112":94,"113":[2,205],"114":72,"121":[2,205],"130":[2,205],"131":[2,205],"133":[1,83],"134":[1,82],"137":[2,205],"138":[2,205],"139":[1,86],"140":[1,87],"141":[2,205],"142":[2,205],"144":[2,205]},{"1":[2,206],"4":[2,206],"29":[2,206],"30":[2,206],"47":[1,95],"55":[2,206],"59":[2,206],"75":[2,206],"80":[2,206],"90":[2,206],"94":[2,206],"96":[2,206],"105":[2,206],"106":93,"107":[2,206],"108":[2,206],"109":[2,206],"112":94,"113":[2,206],"114":72,"121":[2,206],"130":[2,206],"131":[2,206],"133":[1,83],"134":[1,82],"137":[1,84],"138":[1,85],"139":[1,86],"140":[1,87],"141":[1,88],"142":[2,206],"144":[1,90]},{"1":[2,209],"4":[2,209],"29":[2,209],"30":[2,209],"47":[1,95],"55":[2,209],"59":[2,209],"75":[2,209],"80":[2,209],"90":[2,209],"94":[2,209],"96":[2,209],"105":[2,209],"106":93,"107":[2,209],"108":[2,209],"109":[2,209],"112":94,"113":[2,209],"114":72,"121":[2,209],"130":[2,209],"131":[2,209],"133":[1,83],"134":[1,82],"137":[2,209],"138":[2,209],"139":[1,86],"140":[1,87],"141":[1,88],"142":[2,209],"144":[2,209]},{"1":[2,189],"4":[2,189],"29":[2,189],"30":[2,189],"47":[1,95],"55":[2,189],"59":[2,189],"75":[2,189],"80":[2,189],"90":[2,189],"94":[2,189],"96":[2,189],"105":[2,189],"106":93,"107":[1,68],"108":[2,189],"109":[1,69],"112":94,"113":[1,71],"114":72,"121":[2,189],"130":[1,91],"131":[1,92],"133":[1,83],"134":[1,82],"137":[1,84],"138":[1,85],"139":[1,86],"140":[1,87],"141":[1,88],"142":[1,89],"144":[1,90]},{"1":[2,191],"4":[2,191],"29":[2,191],"30":[2,191],"47":[1,95],"55":[2,191],"59":[2,191],"75":[2,191],"80":[2,191],"90":[2,191],"94":[2,191],"96":[2,191],"105":[2,191],"106":93,"107":[1,68],"108":[2,191],"109":[1,69],"112":94,"113":[1,71],"114":72,"121":[2,191],"130":[1,91],"131":[1,92],"133":[1,83],"134":[1,82],"137":[1,84],"138":[1,85],"139":[1,86],"140":[1,87],"141":[1,88],"142":[1,89],"144":[1,90]},{"1":[2,188],"4":[2,188],"29":[2,188],"30":[2,188],"47":[1,95],"55":[2,188],"59":[2,188],"75":[2,188],"80":[2,188],"90":[2,188],"94":[2,188],"96":[2,188],"105":[2,188],"106":93,"107":[1,68],"108":[2,188],"109":[1,69],"112":94,"113":[1,71],"114":72,"121":[2,188],"130":[1,91],"131":[1,92],"133":[1,83],"134":[1,82],"137":[1,84],"138":[1,85],"139":[1,86],"140":[1,87],"141":[1,88],"142":[1,89],"144":[1,90]},{"1":[2,190],"4":[2,190],"29":[2,190],"30":[2,190],"47":[1,95],"55":[2,190],"59":[2,190],"75":[2,190],"80":[2,190],"90":[2,190],"94":[2,190],"96":[2,190],"105":[2,190],"106":93,"107":[1,68],"108":[2,190],"109":[1,69],"112":94,"113":[1,71],"114":72,"121":[2,190],"130":[1,91],"131":[1,92],"133":[1,83],"134":[1,82],"137":[1,84],"138":[1,85],"139":[1,86],"140":[1,87],"141":[1,88],"142":[1,89],"144":[1,90]},{"1":[2,110],"4":[2,110],"29":[2,110],"30":[2,110],"47":[2,110],"55":[2,110],"59":[2,110],"68":[2,110],"69":[2,110],"70":[2,110],"71":[2,110],"74":[2,110],"75":[2,110],"76":[2,110],"77":[2,110],"80":[2,110],"88":[2,110],"89":[2,110],"90":[2,110],"94":[2,110],"96":[2,110],"105":[2,110],"107":[2,110],"108":[2,110],"109":[2,110],"113":[2,110],"121":[2,110],"130":[2,110],"131":[2,110],"133":[2,110],"134":[2,110],"137":[2,110],"138":[2,110],"139":[2,110],"140":[2,110],"141":[2,110],"142":[2,110],"144":[2,110]},{"1":[2,79],"4":[2,79],"29":[2,79],"30":[2,79],"41":[2,79],"47":[2,79],"55":[2,79],"59":[2,79],"68":[2,79],"69":[2,79],"70":[2,79],"71":[2,79],"74":[2,79],"75":[2,79],"76":[2,79],"77":[2,79],"80":[2,79],"82":[2,79],"88":[2,79],"89":[2,79],"90":[2,79],"94":[2,79],"96":[2,79],"105":[2,79],"107":[2,79],"108":[2,79],"109":[2,79],"113":[2,79],"121":[2,79],"130":[2,79],"131":[2,79],"133":[2,79],"134":[2,79],"135":[2,79],"136":[2,79],"137":[2,79],"138":[2,79],"139":[2,79],"140":[2,79],"141":[2,79],"142":[2,79],"143":[2,79],"144":[2,79]},{"1":[2,80],"4":[2,80],"29":[2,80],"30":[2,80],"41":[2,80],"47":[2,80],"55":[2,80],"59":[2,80],"68":[2,80],"69":[2,80],"70":[2,80],"71":[2,80],"74":[2,80],"75":[2,80],"76":[2,80],"77":[2,80],"80":[2,80],"82":[2,80],"88":[2,80],"89":[2,80],"90":[2,80],"94":[2,80],"96":[2,80],"105":[2,80],"107":[2,80],"108":[2,80],"109":[2,80],"113":[2,80],"121":[2,80],"130":[2,80],"131":[2,80],"133":[2,80],"134":[2,80],"135":[2,80],"136":[2,80],"137":[2,80],"138":[2,80],"139":[2,80],"140":[2,80],"141":[2,80],"142":[2,80],"143":[2,80],"144":[2,80]},{"1":[2,82],"4":[2,82],"29":[2,82],"30":[2,82],"41":[2,82],"47":[2,82],"55":[2,82],"59":[2,82],"68":[2,82],"69":[2,82],"70":[2,82],"71":[2,82],"74":[2,82],"75":[2,82],"76":[2,82],"77":[2,82],"80":[2,82],"82":[2,82],"88":[2,82],"89":[2,82],"90":[2,82],"94":[2,82],"96":[2,82],"105":[2,82],"107":[2,82],"108":[2,82],"109":[2,82],"113":[2,82],"121":[2,82],"130":[2,82],"131":[2,82],"133":[2,82],"134":[2,82],"135":[2,82],"136":[2,82],"137":[2,82],"138":[2,82],"139":[2,82],"140":[2,82],"141":[2,82],"142":[2,82],"143":[2,82],"144":[2,82]},{"47":[1,95],"59":[1,201],"75":[1,255],"93":256,"94":[1,200],"106":93,"107":[1,68],"109":[1,69],"112":94,"113":[1,71],"114":72,"130":[1,91],"131":[1,92],"133":[1,83],"134":[1,82],"137":[1,84],"138":[1,85],"139":[1,86],"140":[1,87],"141":[1,88],"142":[1,89],"144":[1,90]},{"8":257,"9":124,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"31":64,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":65,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":41,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,43],"103":[1,51],"104":[1,58],"106":44,"107":[1,68],"109":[1,69],"110":45,"111":[1,70],"112":46,"113":[1,71],"114":72,"122":[1,47],"127":42,"128":[1,66],"129":[1,67],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"12":[2,120],"13":[2,120],"14":[2,120],"32":[2,120],"34":[2,120],"35":[2,120],"37":[2,120],"38":[2,120],"39":[2,120],"45":[2,120],"46":[2,120],"48":[2,120],"52":[2,120],"53":[2,120],"58":[2,120],"75":[2,120],"78":[2,120],"81":[2,120],"87":[2,120],"92":[2,120],"95":[2,120],"99":[2,120],"103":[2,120],"104":[2,120],"107":[2,120],"109":[2,120],"111":[2,120],"113":[2,120],"122":[2,120],"128":[2,120],"129":[2,120],"132":[2,120],"133":[2,120],"134":[2,120],"135":[2,120],"136":[2,120]},{"12":[2,121],"13":[2,121],"14":[2,121],"32":[2,121],"34":[2,121],"35":[2,121],"37":[2,121],"38":[2,121],"39":[2,121],"45":[2,121],"46":[2,121],"48":[2,121],"52":[2,121],"53":[2,121],"58":[2,121],"75":[2,121],"78":[2,121],"81":[2,121],"87":[2,121],"92":[2,121],"95":[2,121],"99":[2,121],"103":[2,121],"104":[2,121],"107":[2,121],"109":[2,121],"111":[2,121],"113":[2,121],"122":[2,121],"128":[2,121],"129":[2,121],"132":[2,121],"133":[2,121],"134":[2,121],"135":[2,121],"136":[2,121]},{"1":[2,86],"4":[2,86],"29":[2,86],"30":[2,86],"41":[2,86],"47":[2,86],"55":[2,86],"59":[2,86],"68":[2,86],"69":[2,86],"70":[2,86],"71":[2,86],"74":[2,86],"75":[2,86],"76":[2,86],"77":[2,86],"80":[2,86],"82":[2,86],"88":[2,86],"89":[2,86],"90":[2,86],"94":[2,86],"96":[2,86],"105":[2,86],"107":[2,86],"108":[2,86],"109":[2,86],"113":[2,86],"121":[2,86],"130":[2,86],"131":[2,86],"133":[2,86],"134":[2,86],"135":[2,86],"136":[2,86],"137":[2,86],"138":[2,86],"139":[2,86],"140":[2,86],"141":[2,86],"142":[2,86],"143":[2,86],"144":[2,86]},{"8":258,"9":124,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"31":64,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":65,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":41,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,43],"103":[1,51],"104":[1,58],"106":44,"107":[1,68],"109":[1,69],"110":45,"111":[1,70],"112":46,"113":[1,71],"114":72,"122":[1,47],"127":42,"128":[1,66],"129":[1,67],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"1":[2,87],"4":[2,87],"29":[2,87],"30":[2,87],"41":[2,87],"47":[2,87],"55":[2,87],"59":[2,87],"68":[2,87],"69":[2,87],"70":[2,87],"71":[2,87],"74":[2,87],"75":[2,87],"76":[2,87],"77":[2,87],"80":[2,87],"82":[2,87],"88":[2,87],"89":[2,87],"90":[2,87],"94":[2,87],"96":[2,87],"105":[2,87],"107":[2,87],"108":[2,87],"109":[2,87],"113":[2,87],"121":[2,87],"130":[2,87],"131":[2,87],"133":[2,87],"134":[2,87],"135":[2,87],"136":[2,87],"137":[2,87],"138":[2,87],"139":[2,87],"140":[2,87],"141":[2,87],"142":[2,87],"143":[2,87],"144":[2,87]},{"1":[2,111],"4":[2,111],"29":[2,111],"30":[2,111],"47":[2,111],"55":[2,111],"59":[2,111],"68":[2,111],"69":[2,111],"70":[2,111],"71":[2,111],"74":[2,111],"75":[2,111],"76":[2,111],"77":[2,111],"80":[2,111],"88":[2,111],"89":[2,111],"90":[2,111],"94":[2,111],"96":[2,111],"105":[2,111],"107":[2,111],"108":[2,111],"109":[2,111],"113":[2,111],"121":[2,111],"130":[2,111],"131":[2,111],"133":[2,111],"134":[2,111],"137":[2,111],"138":[2,111],"139":[2,111],"140":[2,111],"141":[2,111],"142":[2,111],"144":[2,111]},{"1":[2,39],"4":[2,39],"29":[2,39],"30":[2,39],"47":[1,95],"55":[2,39],"59":[2,39],"75":[2,39],"80":[2,39],"90":[2,39],"94":[2,39],"96":[2,39],"105":[2,39],"106":93,"107":[1,68],"108":[2,39],"109":[1,69],"112":94,"113":[1,71],"114":72,"121":[2,39],"130":[2,39],"131":[2,39],"133":[1,83],"134":[1,82],"137":[1,84],"138":[1,85],"139":[1,86],"140":[1,87],"141":[1,88],"142":[1,89],"144":[1,90]},{"8":259,"9":124,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"31":64,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":65,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":41,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,43],"103":[1,51],"104":[1,58],"106":44,"107":[1,68],"109":[1,69],"110":45,"111":[1,70],"112":46,"113":[1,71],"114":72,"122":[1,47],"127":42,"128":[1,66],"129":[1,67],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"1":[2,116],"4":[2,116],"29":[2,116],"30":[2,116],"47":[2,116],"55":[2,116],"59":[2,116],"68":[2,116],"69":[2,116],"70":[2,116],"71":[2,116],"74":[2,116],"75":[2,116],"76":[2,116],"77":[2,116],"80":[2,116],"88":[2,116],"89":[2,116],"90":[2,116],"94":[2,116],"96":[2,116],"105":[2,116],"107":[2,116],"108":[2,116],"109":[2,116],"113":[2,116],"121":[2,116],"130":[2,116],"131":[2,116],"133":[2,116],"134":[2,116],"137":[2,116],"138":[2,116],"139":[2,116],"140":[2,116],"141":[2,116],"142":[2,116],"144":[2,116]},{"4":[2,57],"29":[2,57],"54":260,"55":[1,240],"90":[2,57]},{"4":[2,134],"29":[2,134],"30":[2,134],"47":[1,95],"55":[2,134],"59":[1,261],"90":[2,134],"96":[2,134],"106":93,"107":[1,68],"109":[1,69],"112":94,"113":[1,71],"114":72,"130":[1,91],"131":[1,92],"133":[1,83],"134":[1,82],"137":[1,84],"138":[1,85],"139":[1,86],"140":[1,87],"141":[1,88],"142":[1,89],"144":[1,90]},{"51":262,"52":[1,62],"53":[1,63]},{"56":263,"57":[1,119],"58":[1,120]},{"50":[2,64],"55":[2,64]},{"50":[2,63],"55":[2,63],"59":[1,264]},{"1":[2,207],"4":[2,207],"29":[2,207],"30":[2,207],"47":[1,95],"55":[2,207],"59":[2,207],"75":[2,207],"80":[2,207],"90":[2,207],"94":[2,207],"96":[2,207],"105":[2,207],"106":93,"107":[2,207],"108":[2,207],"109":[2,207],"112":94,"113":[2,207],"114":72,"121":[2,207],"130":[2,207],"131":[2,207],"133":[1,83],"134":[1,82],"137":[1,84],"138":[1,85],"139":[1,86],"140":[1,87],"141":[1,88],"142":[1,89],"144":[1,90]},{"8":265,"9":124,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"31":64,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":65,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":41,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,43],"103":[1,51],"104":[1,58],"106":44,"107":[1,68],"109":[1,69],"110":45,"111":[1,70],"112":46,"113":[1,71],"114":72,"122":[1,47],"127":42,"128":[1,66],"129":[1,67],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"1":[2,109],"4":[2,109],"29":[2,109],"30":[2,109],"47":[2,109],"55":[2,109],"59":[2,109],"62":101,"68":[1,103],"69":[1,104],"70":[1,105],"71":[1,106],"72":107,"73":108,"74":[1,109],"75":[2,109],"76":[1,110],"77":[1,111],"80":[2,109],"85":100,"88":[1,102],"89":[2,114],"90":[2,109],"94":[2,109],"96":[2,109],"105":[2,109],"107":[2,109],"108":[2,109],"109":[2,109],"113":[2,109],"121":[2,109],"130":[2,109],"131":[2,109],"133":[2,109],"134":[2,109],"137":[2,109],"138":[2,109],"139":[2,109],"140":[2,109],"141":[2,109],"142":[2,109],"144":[2,109]},{"1":[2,71],"4":[2,71],"29":[2,71],"30":[2,71],"47":[2,71],"55":[2,71],"59":[2,71],"68":[2,71],"69":[2,71],"70":[2,71],"71":[2,71],"74":[2,71],"75":[2,71],"76":[2,71],"77":[2,71],"80":[2,71],"88":[2,71],"89":[2,71],"90":[2,71],"94":[2,71],"96":[2,71],"105":[2,71],"107":[2,71],"108":[2,71],"109":[2,71],"113":[2,71],"121":[2,71],"130":[2,71],"131":[2,71],"133":[2,71],"134":[2,71],"137":[2,71],"138":[2,71],"139":[2,71],"140":[2,71],"141":[2,71],"142":[2,71],"144":[2,71]},{"8":266,"9":124,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"31":64,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":65,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":41,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,43],"103":[1,51],"104":[1,58],"106":44,"107":[1,68],"109":[1,69],"110":45,"111":[1,70],"112":46,"113":[1,71],"114":72,"122":[1,47],"127":42,"128":[1,66],"129":[1,67],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"1":[2,186],"4":[2,186],"29":[2,186],"30":[2,186],"47":[2,186],"55":[2,186],"59":[2,186],"75":[2,186],"80":[2,186],"90":[2,186],"94":[2,186],"96":[2,186],"105":[2,186],"107":[2,186],"108":[2,186],"109":[2,186],"113":[2,186],"121":[2,186],"124":[2,186],"130":[2,186],"131":[2,186],"133":[2,186],"134":[2,186],"137":[2,186],"138":[2,186],"139":[2,186],"140":[2,186],"141":[2,186],"142":[2,186],"144":[2,186]},{"1":[2,139],"4":[2,139],"29":[2,139],"30":[2,139],"47":[2,139],"55":[2,139],"59":[2,139],"75":[2,139],"80":[2,139],"90":[2,139],"94":[2,139],"96":[2,139],"101":[1,267],"105":[2,139],"107":[2,139],"108":[2,139],"109":[2,139],"113":[2,139],"121":[2,139],"130":[2,139],"131":[2,139],"133":[2,139],"134":[2,139],"137":[2,139],"138":[2,139],"139":[2,139],"140":[2,139],"141":[2,139],"142":[2,139],"144":[2,139]},{"4":[1,122],"6":268,"29":[1,6]},{"31":269,"32":[1,76]},{"123":270,"125":226,"126":[1,227]},{"30":[1,271],"124":[1,272],"125":273,"126":[1,227]},{"30":[2,179],"124":[2,179],"126":[2,179]},{"8":275,"9":124,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"31":64,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":65,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":41,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"98":274,"99":[1,43],"103":[1,51],"104":[1,58],"106":44,"107":[1,68],"109":[1,69],"110":45,"111":[1,70],"112":46,"113":[1,71],"114":72,"122":[1,47],"127":42,"128":[1,66],"129":[1,67],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"15":276,"16":129,"31":64,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":130,"43":65,"58":[1,61],"61":218,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"87":[1,33],"92":[1,60],"95":[1,59],"104":[1,58]},{"4":[2,105],"28":177,"30":[2,105],"31":174,"32":[1,76],"33":175,"34":[1,74],"35":[1,75],"42":233,"43":234,"46":[1,49],"58":[1,178],"78":[1,232],"83":277,"84":231},{"4":[1,279],"30":[1,278]},{"4":[2,106],"30":[2,106],"80":[2,106]},{"4":[2,105],"28":177,"31":174,"32":[1,76],"33":175,"34":[1,74],"35":[1,75],"42":233,"43":234,"46":[1,49],"58":[1,178],"78":[1,232],"80":[2,105],"83":280,"84":231},{"4":[2,102],"30":[2,102],"80":[2,102]},{"4":[2,43],"30":[2,43],"44":[1,281],"80":[2,43]},{"1":[2,100],"4":[2,100],"29":[1,282],"30":[2,100],"47":[2,100],"55":[2,100],"59":[2,100],"62":101,"68":[1,103],"69":[1,104],"70":[1,105],"71":[1,106],"72":107,"73":108,"74":[1,109],"75":[2,100],"76":[1,110],"77":[1,111],"80":[2,100],"85":100,"88":[1,102],"89":[2,114],"90":[2,100],"94":[2,100],"96":[2,100],"105":[2,100],"107":[2,100],"108":[2,100],"109":[2,100],"113":[2,100],"121":[2,100],"130":[2,100],"131":[2,100],"133":[2,100],"134":[2,100],"137":[2,100],"138":[2,100],"139":[2,100],"140":[2,100],"141":[2,100],"142":[2,100],"144":[2,100]},{"1":[2,144],"4":[2,144],"29":[2,144],"30":[2,144],"47":[2,144],"55":[2,144],"59":[2,144],"68":[2,144],"69":[2,144],"70":[2,144],"71":[2,144],"74":[2,144],"75":[2,144],"76":[2,144],"77":[2,144],"80":[2,144],"88":[2,144],"89":[2,144],"90":[2,144],"94":[2,144],"96":[2,144],"105":[2,144],"107":[2,144],"108":[2,144],"109":[2,144],"113":[2,144],"121":[2,144],"130":[2,144],"131":[2,144],"133":[2,144],"134":[2,144],"137":[2,144],"138":[2,144],"139":[2,144],"140":[2,144],"141":[2,144],"142":[2,144],"144":[2,144]},{"8":283,"9":124,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"31":64,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":65,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":41,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,43],"103":[1,51],"104":[1,58],"106":44,"107":[1,68],"109":[1,69],"110":45,"111":[1,70],"112":46,"113":[1,71],"114":72,"122":[1,47],"127":42,"128":[1,66],"129":[1,67],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"4":[2,66],"12":[2,121],"13":[2,121],"14":[2,121],"29":[2,66],"32":[2,121],"34":[2,121],"35":[2,121],"37":[2,121],"38":[2,121],"39":[2,121],"45":[2,121],"46":[2,121],"48":[2,121],"52":[2,121],"53":[2,121],"55":[2,66],"58":[2,121],"78":[2,121],"81":[2,121],"87":[2,121],"92":[2,121],"95":[2,121],"96":[2,66],"99":[2,121],"103":[2,121],"104":[2,121],"107":[2,121],"109":[2,121],"111":[2,121],"113":[2,121],"122":[2,121],"128":[2,121],"129":[2,121],"132":[2,121],"133":[2,121],"134":[2,121],"135":[2,121],"136":[2,121]},{"4":[1,285],"29":[1,286],"96":[1,284]},{"4":[2,58],"8":210,"9":124,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"29":[2,58],"30":[2,58],"31":64,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":65,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"60":154,"61":41,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"90":[2,58],"92":[1,60],"95":[1,59],"96":[2,58],"97":287,"99":[1,43],"103":[1,51],"104":[1,58],"106":44,"107":[1,68],"109":[1,69],"110":45,"111":[1,70],"112":46,"113":[1,71],"114":72,"122":[1,47],"127":42,"128":[1,66],"129":[1,67],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"4":[2,57],"29":[2,57],"30":[2,57],"54":288,"55":[1,240]},{"1":[2,183],"4":[2,183],"29":[2,183],"30":[2,183],"47":[2,183],"55":[2,183],"59":[2,183],"75":[2,183],"80":[2,183],"90":[2,183],"94":[2,183],"96":[2,183],"105":[2,183],"107":[2,183],"108":[2,183],"109":[2,183],"113":[2,183],"121":[2,183],"124":[2,183],"130":[2,183],"131":[2,183],"133":[2,183],"134":[2,183],"137":[2,183],"138":[2,183],"139":[2,183],"140":[2,183],"141":[2,183],"142":[2,183],"144":[2,183]},{"1":[2,184],"4":[2,184],"29":[2,184],"30":[2,184],"47":[2,184],"55":[2,184],"59":[2,184],"75":[2,184],"80":[2,184],"90":[2,184],"94":[2,184],"96":[2,184],"105":[2,184],"107":[2,184],"108":[2,184],"109":[2,184],"113":[2,184],"121":[2,184],"124":[2,184],"130":[2,184],"131":[2,184],"133":[2,184],"134":[2,184],"137":[2,184],"138":[2,184],"139":[2,184],"140":[2,184],"141":[2,184],"142":[2,184],"144":[2,184]},{"8":289,"9":124,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"31":64,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":65,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":41,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,43],"103":[1,51],"104":[1,58],"106":44,"107":[1,68],"109":[1,69],"110":45,"111":[1,70],"112":46,"113":[1,71],"114":72,"122":[1,47],"127":42,"128":[1,66],"129":[1,67],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"8":290,"9":124,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"31":64,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":65,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":41,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,43],"103":[1,51],"104":[1,58],"106":44,"107":[1,68],"109":[1,69],"110":45,"111":[1,70],"112":46,"113":[1,71],"114":72,"122":[1,47],"127":42,"128":[1,66],"129":[1,67],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"119":[2,162],"120":[2,162]},{"8":210,"9":124,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"29":[1,153],"31":64,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":65,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"60":154,"61":41,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"91":151,"92":[1,60],"95":[1,59],"96":[1,150],"97":152,"99":[1,43],"103":[1,51],"104":[1,58],"106":44,"107":[1,68],"109":[1,69],"110":45,"111":[1,70],"112":46,"113":[1,71],"114":72,"122":[1,47],"127":42,"128":[1,66],"129":[1,67],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"31":166,"32":[1,76],"63":167,"64":168,"78":[1,73],"95":[1,247],"118":291},{"1":[2,168],"4":[2,168],"29":[2,168],"30":[2,168],"47":[1,95],"55":[2,168],"59":[2,168],"75":[2,168],"80":[2,168],"90":[2,168],"94":[2,168],"96":[2,168],"105":[2,168],"106":93,"107":[2,168],"108":[1,292],"109":[2,168],"112":94,"113":[2,168],"114":72,"121":[1,293],"130":[2,168],"131":[2,168],"133":[1,83],"134":[1,82],"137":[1,84],"138":[1,85],"139":[1,86],"140":[1,87],"141":[1,88],"142":[1,89],"144":[1,90]},{"1":[2,169],"4":[2,169],"29":[2,169],"30":[2,169],"47":[1,95],"55":[2,169],"59":[2,169],"75":[2,169],"80":[2,169],"90":[2,169],"94":[2,169],"96":[2,169],"105":[2,169],"106":93,"107":[2,169],"108":[1,294],"109":[2,169],"112":94,"113":[2,169],"114":72,"121":[2,169],"130":[2,169],"131":[2,169],"133":[1,83],"134":[1,82],"137":[1,84],"138":[1,85],"139":[1,86],"140":[1,87],"141":[1,88],"142":[1,89],"144":[1,90]},{"4":[1,296],"29":[1,297],"80":[1,295]},{"4":[2,58],"28":177,"29":[2,58],"30":[2,58],"31":174,"32":[1,76],"33":175,"34":[1,74],"35":[1,75],"42":298,"43":176,"46":[1,49],"58":[1,178],"80":[2,58]},{"8":299,"9":124,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"29":[1,300],"31":64,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":65,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":41,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,43],"103":[1,51],"104":[1,58],"106":44,"107":[1,68],"109":[1,69],"110":45,"111":[1,70],"112":46,"113":[1,71],"114":72,"122":[1,47],"127":42,"128":[1,66],"129":[1,67],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"8":301,"9":124,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"29":[1,302],"31":64,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":65,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":41,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,43],"103":[1,51],"104":[1,58],"106":44,"107":[1,68],"109":[1,69],"110":45,"111":[1,70],"112":46,"113":[1,71],"114":72,"122":[1,47],"127":42,"128":[1,66],"129":[1,67],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"1":[2,85],"4":[2,85],"29":[2,85],"30":[2,85],"41":[2,85],"47":[2,85],"55":[2,85],"59":[2,85],"68":[2,85],"69":[2,85],"70":[2,85],"71":[2,85],"74":[2,85],"75":[2,85],"76":[2,85],"77":[2,85],"80":[2,85],"82":[2,85],"88":[2,85],"89":[2,85],"90":[2,85],"94":[2,85],"96":[2,85],"105":[2,85],"107":[2,85],"108":[2,85],"109":[2,85],"113":[2,85],"121":[2,85],"130":[2,85],"131":[2,85],"133":[2,85],"134":[2,85],"135":[2,85],"136":[2,85],"137":[2,85],"138":[2,85],"139":[2,85],"140":[2,85],"141":[2,85],"142":[2,85],"143":[2,85],"144":[2,85]},{"8":303,"9":124,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"31":64,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":65,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":41,"63":52,"64":53,"65":30,"66":31,"67":32,"75":[1,304],"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,43],"103":[1,51],"104":[1,58],"106":44,"107":[1,68],"109":[1,69],"110":45,"111":[1,70],"112":46,"113":[1,71],"114":72,"122":[1,47],"127":42,"128":[1,66],"129":[1,67],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"47":[1,95],"75":[1,305],"106":93,"107":[1,68],"109":[1,69],"112":94,"113":[1,71],"114":72,"130":[1,91],"131":[1,92],"133":[1,83],"134":[1,82],"137":[1,84],"138":[1,85],"139":[1,86],"140":[1,87],"141":[1,88],"142":[1,89],"144":[1,90]},{"47":[1,95],"75":[1,255],"106":93,"107":[1,68],"109":[1,69],"112":94,"113":[1,71],"114":72,"130":[1,91],"131":[1,92],"133":[1,83],"134":[1,82],"137":[1,84],"138":[1,85],"139":[1,86],"140":[1,87],"141":[1,88],"142":[1,89],"144":[1,90]},{"30":[1,306],"47":[1,95],"106":93,"107":[1,68],"109":[1,69],"112":94,"113":[1,71],"114":72,"130":[1,91],"131":[1,92],"133":[1,83],"134":[1,82],"137":[1,84],"138":[1,85],"139":[1,86],"140":[1,87],"141":[1,88],"142":[1,89],"144":[1,90]},{"4":[1,285],"29":[1,286],"90":[1,307]},{"4":[2,66],"29":[2,66],"30":[2,66],"55":[2,66],"90":[2,66],"96":[2,66]},{"4":[1,122],"6":308,"29":[1,6]},{"50":[2,61],"55":[2,61]},{"50":[2,65],"55":[2,65]},{"30":[1,309],"47":[1,95],"106":93,"107":[1,68],"109":[1,69],"112":94,"113":[1,71],"114":72,"130":[1,91],"131":[1,92],"133":[1,83],"134":[1,82],"137":[1,84],"138":[1,85],"139":[1,86],"140":[1,87],"141":[1,88],"142":[1,89],"144":[1,90]},{"4":[1,122],"6":310,"29":[1,6],"47":[1,95],"106":93,"107":[1,68],"109":[1,69],"112":94,"113":[1,71],"114":72,"130":[1,91],"131":[1,92],"133":[1,83],"134":[1,82],"137":[1,84],"138":[1,85],"139":[1,86],"140":[1,87],"141":[1,88],"142":[1,89],"144":[1,90]},{"4":[1,122],"6":311,"29":[1,6]},{"1":[2,140],"4":[2,140],"29":[2,140],"30":[2,140],"47":[2,140],"55":[2,140],"59":[2,140],"75":[2,140],"80":[2,140],"90":[2,140],"94":[2,140],"96":[2,140],"105":[2,140],"107":[2,140],"108":[2,140],"109":[2,140],"113":[2,140],"121":[2,140],"130":[2,140],"131":[2,140],"133":[2,140],"134":[2,140],"137":[2,140],"138":[2,140],"139":[2,140],"140":[2,140],"141":[2,140],"142":[2,140],"144":[2,140]},{"4":[1,122],"6":312,"29":[1,6]},{"30":[1,313],"124":[1,314],"125":273,"126":[1,227]},{"1":[2,177],"4":[2,177],"29":[2,177],"30":[2,177],"47":[2,177],"55":[2,177],"59":[2,177],"75":[2,177],"80":[2,177],"90":[2,177],"94":[2,177],"96":[2,177],"105":[2,177],"107":[2,177],"108":[2,177],"109":[2,177],"113":[2,177],"121":[2,177],"130":[2,177],"131":[2,177],"133":[2,177],"134":[2,177],"137":[2,177],"138":[2,177],"139":[2,177],"140":[2,177],"141":[2,177],"142":[2,177],"144":[2,177]},{"4":[1,122],"6":315,"29":[1,6]},{"30":[2,180],"124":[2,180],"126":[2,180]},{"4":[1,122],"6":316,"29":[1,6],"55":[1,317]},{"4":[2,136],"29":[2,136],"47":[1,95],"55":[2,136],"106":93,"107":[1,68],"109":[1,69],"112":94,"113":[1,71],"114":72,"130":[1,91],"131":[1,92],"133":[1,83],"134":[1,82],"137":[1,84],"138":[1,85],"139":[1,86],"140":[1,87],"141":[1,88],"142":[1,89],"144":[1,90]},{"1":[2,95],"4":[2,95],"29":[1,318],"30":[2,95],"47":[2,95],"55":[2,95],"59":[2,95],"62":101,"68":[1,103],"69":[1,104],"70":[1,105],"71":[1,106],"72":107,"73":108,"74":[1,109],"75":[2,95],"76":[1,110],"77":[1,111],"80":[2,95],"85":100,"88":[1,102],"89":[2,114],"90":[2,95],"94":[2,95],"96":[2,95],"105":[2,95],"107":[2,95],"108":[2,95],"109":[2,95],"113":[2,95],"121":[2,95],"130":[2,95],"131":[2,95],"133":[2,95],"134":[2,95],"137":[2,95],"138":[2,95],"139":[2,95],"140":[2,95],"141":[2,95],"142":[2,95],"144":[2,95]},{"4":[1,279],"30":[1,319]},{"1":[2,98],"4":[2,98],"29":[2,98],"30":[2,98],"47":[2,98],"55":[2,98],"59":[2,98],"75":[2,98],"80":[2,98],"90":[2,98],"94":[2,98],"96":[2,98],"105":[2,98],"107":[2,98],"108":[2,98],"109":[2,98],"113":[2,98],"121":[2,98],"130":[2,98],"131":[2,98],"133":[2,98],"134":[2,98],"137":[2,98],"138":[2,98],"139":[2,98],"140":[2,98],"141":[2,98],"142":[2,98],"144":[2,98]},{"28":177,"31":174,"32":[1,76],"33":175,"34":[1,74],"35":[1,75],"42":233,"43":234,"46":[1,49],"58":[1,178],"84":320},{"4":[1,279],"80":[1,321]},{"8":322,"9":124,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"29":[1,323],"31":64,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":65,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":41,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,43],"103":[1,51],"104":[1,58],"106":44,"107":[1,68],"109":[1,69],"110":45,"111":[1,70],"112":46,"113":[1,71],"114":72,"122":[1,47],"127":42,"128":[1,66],"129":[1,67],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"4":[2,105],"28":177,"30":[2,105],"31":174,"32":[1,76],"33":175,"34":[1,74],"35":[1,75],"42":233,"43":234,"46":[1,49],"58":[1,178],"78":[1,232],"83":324,"84":231},{"47":[1,95],"96":[1,325],"106":93,"107":[1,68],"109":[1,69],"112":94,"113":[1,71],"114":72,"130":[1,91],"131":[1,92],"133":[1,83],"134":[1,82],"137":[1,84],"138":[1,85],"139":[1,86],"140":[1,87],"141":[1,88],"142":[1,89],"144":[1,90]},{"1":[2,128],"4":[2,128],"29":[2,128],"30":[2,128],"41":[2,128],"47":[2,128],"55":[2,128],"59":[2,128],"68":[2,128],"69":[2,128],"70":[2,128],"71":[2,128],"74":[2,128],"75":[2,128],"76":[2,128],"77":[2,128],"80":[2,128],"88":[2,128],"89":[2,128],"90":[2,128],"94":[2,128],"96":[2,128],"105":[2,128],"107":[2,128],"108":[2,128],"109":[2,128],"113":[2,128],"119":[2,128],"120":[2,128],"121":[2,128],"130":[2,128],"131":[2,128],"133":[2,128],"134":[2,128],"137":[2,128],"138":[2,128],"139":[2,128],"140":[2,128],"141":[2,128],"142":[2,128],"144":[2,128]},{"8":210,"9":124,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"31":64,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":65,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"60":154,"61":41,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"97":326,"99":[1,43],"103":[1,51],"104":[1,58],"106":44,"107":[1,68],"109":[1,69],"110":45,"111":[1,70],"112":46,"113":[1,71],"114":72,"122":[1,47],"127":42,"128":[1,66],"129":[1,67],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"8":210,"9":124,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"29":[1,153],"31":64,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":65,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"60":154,"61":41,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"91":327,"92":[1,60],"95":[1,59],"97":152,"99":[1,43],"103":[1,51],"104":[1,58],"106":44,"107":[1,68],"109":[1,69],"110":45,"111":[1,70],"112":46,"113":[1,71],"114":72,"122":[1,47],"127":42,"128":[1,66],"129":[1,67],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"4":[2,130],"29":[2,130],"30":[2,130],"55":[2,130],"90":[2,130],"96":[2,130]},{"4":[1,285],"29":[1,286],"30":[1,328]},{"1":[2,147],"4":[2,147],"29":[2,147],"30":[2,147],"47":[1,95],"55":[2,147],"59":[2,147],"75":[2,147],"80":[2,147],"90":[2,147],"94":[2,147],"96":[2,147],"105":[2,147],"106":93,"107":[1,68],"108":[2,147],"109":[1,69],"112":94,"113":[1,71],"114":72,"121":[2,147],"130":[2,147],"131":[2,147],"133":[1,83],"134":[1,82],"137":[1,84],"138":[1,85],"139":[1,86],"140":[1,87],"141":[1,88],"142":[1,89],"144":[1,90]},{"1":[2,149],"4":[2,149],"29":[2,149],"30":[2,149],"47":[1,95],"55":[2,149],"59":[2,149],"75":[2,149],"80":[2,149],"90":[2,149],"94":[2,149],"96":[2,149],"105":[2,149],"106":93,"107":[1,68],"108":[2,149],"109":[1,69],"112":94,"113":[1,71],"114":72,"121":[2,149],"130":[2,149],"131":[2,149],"133":[1,83],"134":[1,82],"137":[1,84],"138":[1,85],"139":[1,86],"140":[1,87],"141":[1,88],"142":[1,89],"144":[1,90]},{"119":[2,167],"120":[2,167]},{"8":329,"9":124,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"31":64,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":65,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":41,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,43],"103":[1,51],"104":[1,58],"106":44,"107":[1,68],"109":[1,69],"110":45,"111":[1,70],"112":46,"113":[1,71],"114":72,"122":[1,47],"127":42,"128":[1,66],"129":[1,67],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"8":330,"9":124,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"31":64,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":65,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":41,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,43],"103":[1,51],"104":[1,58],"106":44,"107":[1,68],"109":[1,69],"110":45,"111":[1,70],"112":46,"113":[1,71],"114":72,"122":[1,47],"127":42,"128":[1,66],"129":[1,67],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"8":331,"9":124,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"31":64,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":65,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":41,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,43],"103":[1,51],"104":[1,58],"106":44,"107":[1,68],"109":[1,69],"110":45,"111":[1,70],"112":46,"113":[1,71],"114":72,"122":[1,47],"127":42,"128":[1,66],"129":[1,67],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"1":[2,88],"4":[2,88],"29":[2,88],"30":[2,88],"41":[2,88],"47":[2,88],"55":[2,88],"59":[2,88],"68":[2,88],"69":[2,88],"70":[2,88],"71":[2,88],"74":[2,88],"75":[2,88],"76":[2,88],"77":[2,88],"80":[2,88],"88":[2,88],"89":[2,88],"90":[2,88],"94":[2,88],"96":[2,88],"105":[2,88],"107":[2,88],"108":[2,88],"109":[2,88],"113":[2,88],"119":[2,88],"120":[2,88],"121":[2,88],"130":[2,88],"131":[2,88],"133":[2,88],"134":[2,88],"137":[2,88],"138":[2,88],"139":[2,88],"140":[2,88],"141":[2,88],"142":[2,88],"144":[2,88]},{"28":177,"31":174,"32":[1,76],"33":175,"34":[1,74],"35":[1,75],"42":332,"43":176,"46":[1,49],"58":[1,178]},{"4":[2,89],"28":177,"29":[2,89],"30":[2,89],"31":174,"32":[1,76],"33":175,"34":[1,74],"35":[1,75],"42":173,"43":176,"46":[1,49],"55":[2,89],"58":[1,178],"79":333},{"4":[2,91],"29":[2,91],"30":[2,91],"55":[2,91],"80":[2,91]},{"4":[2,44],"29":[2,44],"30":[2,44],"47":[1,95],"55":[2,44],"80":[2,44],"106":93,"107":[1,68],"109":[1,69],"112":94,"113":[1,71],"114":72,"130":[1,91],"131":[1,92],"133":[1,83],"134":[1,82],"137":[1,84],"138":[1,85],"139":[1,86],"140":[1,87],"141":[1,88],"142":[1,89],"144":[1,90]},{"8":334,"9":124,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"31":64,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":65,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":41,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,43],"103":[1,51],"104":[1,58],"106":44,"107":[1,68],"109":[1,69],"110":45,"111":[1,70],"112":46,"113":[1,71],"114":72,"122":[1,47],"127":42,"128":[1,66],"129":[1,67],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"4":[2,45],"29":[2,45],"30":[2,45],"47":[1,95],"55":[2,45],"80":[2,45],"106":93,"107":[1,68],"109":[1,69],"112":94,"113":[1,71],"114":72,"130":[1,91],"131":[1,92],"133":[1,83],"134":[1,82],"137":[1,84],"138":[1,85],"139":[1,86],"140":[1,87],"141":[1,88],"142":[1,89],"144":[1,90]},{"8":335,"9":124,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"31":64,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":65,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":41,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,43],"103":[1,51],"104":[1,58],"106":44,"107":[1,68],"109":[1,69],"110":45,"111":[1,70],"112":46,"113":[1,71],"114":72,"122":[1,47],"127":42,"128":[1,66],"129":[1,67],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"47":[1,95],"75":[1,336],"106":93,"107":[1,68],"109":[1,69],"112":94,"113":[1,71],"114":72,"130":[1,91],"131":[1,92],"133":[1,83],"134":[1,82],"137":[1,84],"138":[1,85],"139":[1,86],"140":[1,87],"141":[1,88],"142":[1,89],"144":[1,90]},{"1":[2,125],"4":[2,125],"29":[2,125],"30":[2,125],"41":[2,125],"47":[2,125],"55":[2,125],"59":[2,125],"68":[2,125],"69":[2,125],"70":[2,125],"71":[2,125],"74":[2,125],"75":[2,125],"76":[2,125],"77":[2,125],"80":[2,125],"82":[2,125],"88":[2,125],"89":[2,125],"90":[2,125],"94":[2,125],"96":[2,125],"105":[2,125],"107":[2,125],"108":[2,125],"109":[2,125],"113":[2,125],"121":[2,125],"130":[2,125],"131":[2,125],"133":[2,125],"134":[2,125],"135":[2,125],"136":[2,125],"137":[2,125],"138":[2,125],"139":[2,125],"140":[2,125],"141":[2,125],"142":[2,125],"143":[2,125],"144":[2,125]},{"1":[2,126],"4":[2,126],"29":[2,126],"30":[2,126],"41":[2,126],"47":[2,126],"55":[2,126],"59":[2,126],"68":[2,126],"69":[2,126],"70":[2,126],"71":[2,126],"74":[2,126],"75":[2,126],"76":[2,126],"77":[2,126],"80":[2,126],"82":[2,126],"88":[2,126],"89":[2,126],"90":[2,126],"94":[2,126],"96":[2,126],"105":[2,126],"107":[2,126],"108":[2,126],"109":[2,126],"113":[2,126],"121":[2,126],"130":[2,126],"131":[2,126],"133":[2,126],"134":[2,126],"135":[2,126],"136":[2,126],"137":[2,126],"138":[2,126],"139":[2,126],"140":[2,126],"141":[2,126],"142":[2,126],"143":[2,126],"144":[2,126]},{"1":[2,40],"4":[2,40],"29":[2,40],"30":[2,40],"47":[2,40],"55":[2,40],"59":[2,40],"75":[2,40],"80":[2,40],"90":[2,40],"94":[2,40],"96":[2,40],"105":[2,40],"107":[2,40],"108":[2,40],"109":[2,40],"113":[2,40],"121":[2,40],"130":[2,40],"131":[2,40],"133":[2,40],"134":[2,40],"137":[2,40],"138":[2,40],"139":[2,40],"140":[2,40],"141":[2,40],"142":[2,40],"144":[2,40]},{"1":[2,117],"4":[2,117],"29":[2,117],"30":[2,117],"47":[2,117],"55":[2,117],"59":[2,117],"68":[2,117],"69":[2,117],"70":[2,117],"71":[2,117],"74":[2,117],"75":[2,117],"76":[2,117],"77":[2,117],"80":[2,117],"88":[2,117],"89":[2,117],"90":[2,117],"94":[2,117],"96":[2,117],"105":[2,117],"107":[2,117],"108":[2,117],"109":[2,117],"113":[2,117],"121":[2,117],"130":[2,117],"131":[2,117],"133":[2,117],"134":[2,117],"137":[2,117],"138":[2,117],"139":[2,117],"140":[2,117],"141":[2,117],"142":[2,117],"144":[2,117]},{"1":[2,53],"4":[2,53],"29":[2,53],"30":[2,53],"47":[2,53],"55":[2,53],"59":[2,53],"75":[2,53],"80":[2,53],"90":[2,53],"94":[2,53],"96":[2,53],"105":[2,53],"107":[2,53],"108":[2,53],"109":[2,53],"113":[2,53],"121":[2,53],"130":[2,53],"131":[2,53],"133":[2,53],"134":[2,53],"137":[2,53],"138":[2,53],"139":[2,53],"140":[2,53],"141":[2,53],"142":[2,53],"144":[2,53]},{"1":[2,208],"4":[2,208],"29":[2,208],"30":[2,208],"47":[2,208],"55":[2,208],"59":[2,208],"75":[2,208],"80":[2,208],"90":[2,208],"94":[2,208],"96":[2,208],"105":[2,208],"107":[2,208],"108":[2,208],"109":[2,208],"113":[2,208],"121":[2,208],"130":[2,208],"131":[2,208],"133":[2,208],"134":[2,208],"137":[2,208],"138":[2,208],"139":[2,208],"140":[2,208],"141":[2,208],"142":[2,208],"144":[2,208]},{"1":[2,185],"4":[2,185],"29":[2,185],"30":[2,185],"47":[2,185],"55":[2,185],"59":[2,185],"75":[2,185],"80":[2,185],"90":[2,185],"94":[2,185],"96":[2,185],"105":[2,185],"107":[2,185],"108":[2,185],"109":[2,185],"113":[2,185],"121":[2,185],"124":[2,185],"130":[2,185],"131":[2,185],"133":[2,185],"134":[2,185],"137":[2,185],"138":[2,185],"139":[2,185],"140":[2,185],"141":[2,185],"142":[2,185],"144":[2,185]},{"1":[2,141],"4":[2,141],"29":[2,141],"30":[2,141],"47":[2,141],"55":[2,141],"59":[2,141],"75":[2,141],"80":[2,141],"90":[2,141],"94":[2,141],"96":[2,141],"105":[2,141],"107":[2,141],"108":[2,141],"109":[2,141],"113":[2,141],"121":[2,141],"130":[2,141],"131":[2,141],"133":[2,141],"134":[2,141],"137":[2,141],"138":[2,141],"139":[2,141],"140":[2,141],"141":[2,141],"142":[2,141],"144":[2,141]},{"1":[2,142],"4":[2,142],"29":[2,142],"30":[2,142],"47":[2,142],"55":[2,142],"59":[2,142],"75":[2,142],"80":[2,142],"90":[2,142],"94":[2,142],"96":[2,142],"101":[2,142],"105":[2,142],"107":[2,142],"108":[2,142],"109":[2,142],"113":[2,142],"121":[2,142],"130":[2,142],"131":[2,142],"133":[2,142],"134":[2,142],"137":[2,142],"138":[2,142],"139":[2,142],"140":[2,142],"141":[2,142],"142":[2,142],"144":[2,142]},{"1":[2,175],"4":[2,175],"29":[2,175],"30":[2,175],"47":[2,175],"55":[2,175],"59":[2,175],"75":[2,175],"80":[2,175],"90":[2,175],"94":[2,175],"96":[2,175],"105":[2,175],"107":[2,175],"108":[2,175],"109":[2,175],"113":[2,175],"121":[2,175],"130":[2,175],"131":[2,175],"133":[2,175],"134":[2,175],"137":[2,175],"138":[2,175],"139":[2,175],"140":[2,175],"141":[2,175],"142":[2,175],"144":[2,175]},{"4":[1,122],"6":337,"29":[1,6]},{"30":[1,338]},{"4":[1,339],"30":[2,181],"124":[2,181],"126":[2,181]},{"8":340,"9":124,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"31":64,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":65,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":41,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,43],"103":[1,51],"104":[1,58],"106":44,"107":[1,68],"109":[1,69],"110":45,"111":[1,70],"112":46,"113":[1,71],"114":72,"122":[1,47],"127":42,"128":[1,66],"129":[1,67],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"4":[2,105],"28":177,"30":[2,105],"31":174,"32":[1,76],"33":175,"34":[1,74],"35":[1,75],"42":233,"43":234,"46":[1,49],"58":[1,178],"78":[1,232],"83":341,"84":231},{"1":[2,96],"4":[2,96],"29":[2,96],"30":[2,96],"47":[2,96],"55":[2,96],"59":[2,96],"75":[2,96],"80":[2,96],"90":[2,96],"94":[2,96],"96":[2,96],"105":[2,96],"107":[2,96],"108":[2,96],"109":[2,96],"113":[2,96],"121":[2,96],"130":[2,96],"131":[2,96],"133":[2,96],"134":[2,96],"137":[2,96],"138":[2,96],"139":[2,96],"140":[2,96],"141":[2,96],"142":[2,96],"144":[2,96]},{"4":[2,107],"30":[2,107],"80":[2,107]},{"4":[2,108],"30":[2,108],"80":[2,108]},{"4":[2,103],"30":[2,103],"47":[1,95],"80":[2,103],"106":93,"107":[1,68],"109":[1,69],"112":94,"113":[1,71],"114":72,"130":[1,91],"131":[1,92],"133":[1,83],"134":[1,82],"137":[1,84],"138":[1,85],"139":[1,86],"140":[1,87],"141":[1,88],"142":[1,89],"144":[1,90]},{"8":342,"9":124,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"31":64,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":65,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":41,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,43],"103":[1,51],"104":[1,58],"106":44,"107":[1,68],"109":[1,69],"110":45,"111":[1,70],"112":46,"113":[1,71],"114":72,"122":[1,47],"127":42,"128":[1,66],"129":[1,67],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"4":[1,279],"30":[1,343]},{"1":[2,123],"4":[2,123],"29":[2,123],"30":[2,123],"47":[2,123],"55":[2,123],"59":[2,123],"68":[2,123],"69":[2,123],"70":[2,123],"71":[2,123],"74":[2,123],"75":[2,123],"76":[2,123],"77":[2,123],"80":[2,123],"88":[2,123],"89":[2,123],"90":[2,123],"94":[2,123],"96":[2,123],"105":[2,123],"107":[2,123],"108":[2,123],"109":[2,123],"113":[2,123],"121":[2,123],"130":[2,123],"131":[2,123],"133":[2,123],"134":[2,123],"137":[2,123],"138":[2,123],"139":[2,123],"140":[2,123],"141":[2,123],"142":[2,123],"144":[2,123]},{"4":[2,131],"29":[2,131],"30":[2,131],"55":[2,131],"90":[2,131],"96":[2,131]},{"4":[2,57],"29":[2,57],"30":[2,57],"54":344,"55":[1,240]},{"4":[2,132],"29":[2,132],"30":[2,132],"55":[2,132],"90":[2,132],"96":[2,132]},{"1":[2,170],"4":[2,170],"29":[2,170],"30":[2,170],"47":[1,95],"55":[2,170],"59":[2,170],"75":[2,170],"80":[2,170],"90":[2,170],"94":[2,170],"96":[2,170],"105":[2,170],"106":93,"107":[2,170],"108":[2,170],"109":[2,170],"112":94,"113":[2,170],"114":72,"121":[1,345],"130":[2,170],"131":[2,170],"133":[1,83],"134":[1,82],"137":[1,84],"138":[1,85],"139":[1,86],"140":[1,87],"141":[1,88],"142":[1,89],"144":[1,90]},{"1":[2,172],"4":[2,172],"29":[2,172],"30":[2,172],"47":[1,95],"55":[2,172],"59":[2,172],"75":[2,172],"80":[2,172],"90":[2,172],"94":[2,172],"96":[2,172],"105":[2,172],"106":93,"107":[2,172],"108":[1,346],"109":[2,172],"112":94,"113":[2,172],"114":72,"121":[2,172],"130":[2,172],"131":[2,172],"133":[1,83],"134":[1,82],"137":[1,84],"138":[1,85],"139":[1,86],"140":[1,87],"141":[1,88],"142":[1,89],"144":[1,90]},{"1":[2,171],"4":[2,171],"29":[2,171],"30":[2,171],"47":[1,95],"55":[2,171],"59":[2,171],"75":[2,171],"80":[2,171],"90":[2,171],"94":[2,171],"96":[2,171],"105":[2,171],"106":93,"107":[2,171],"108":[2,171],"109":[2,171],"112":94,"113":[2,171],"114":72,"121":[2,171],"130":[2,171],"131":[2,171],"133":[1,83],"134":[1,82],"137":[1,84],"138":[1,85],"139":[1,86],"140":[1,87],"141":[1,88],"142":[1,89],"144":[1,90]},{"4":[2,92],"29":[2,92],"30":[2,92],"55":[2,92],"80":[2,92]},{"4":[2,57],"29":[2,57],"30":[2,57],"54":347,"55":[1,252]},{"30":[1,348],"47":[1,95],"106":93,"107":[1,68],"109":[1,69],"112":94,"113":[1,71],"114":72,"130":[1,91],"131":[1,92],"133":[1,83],"134":[1,82],"137":[1,84],"138":[1,85],"139":[1,86],"140":[1,87],"141":[1,88],"142":[1,89],"144":[1,90]},{"30":[1,349],"47":[1,95],"106":93,"107":[1,68],"109":[1,69],"112":94,"113":[1,71],"114":72,"130":[1,91],"131":[1,92],"133":[1,83],"134":[1,82],"137":[1,84],"138":[1,85],"139":[1,86],"140":[1,87],"141":[1,88],"142":[1,89],"144":[1,90]},{"1":[2,124],"4":[2,124],"29":[2,124],"30":[2,124],"41":[2,124],"47":[2,124],"55":[2,124],"59":[2,124],"68":[2,124],"69":[2,124],"70":[2,124],"71":[2,124],"74":[2,124],"75":[2,124],"76":[2,124],"77":[2,124],"80":[2,124],"82":[2,124],"88":[2,124],"89":[2,124],"90":[2,124],"94":[2,124],"96":[2,124],"105":[2,124],"107":[2,124],"108":[2,124],"109":[2,124],"113":[2,124],"121":[2,124],"130":[2,124],"131":[2,124],"133":[2,124],"134":[2,124],"135":[2,124],"136":[2,124],"137":[2,124],"138":[2,124],"139":[2,124],"140":[2,124],"141":[2,124],"142":[2,124],"143":[2,124],"144":[2,124]},{"30":[1,350]},{"1":[2,178],"4":[2,178],"29":[2,178],"30":[2,178],"47":[2,178],"55":[2,178],"59":[2,178],"75":[2,178],"80":[2,178],"90":[2,178],"94":[2,178],"96":[2,178],"105":[2,178],"107":[2,178],"108":[2,178],"109":[2,178],"113":[2,178],"121":[2,178],"130":[2,178],"131":[2,178],"133":[2,178],"134":[2,178],"137":[2,178],"138":[2,178],"139":[2,178],"140":[2,178],"141":[2,178],"142":[2,178],"144":[2,178]},{"30":[2,182],"124":[2,182],"126":[2,182]},{"4":[2,137],"29":[2,137],"47":[1,95],"55":[2,137],"106":93,"107":[1,68],"109":[1,69],"112":94,"113":[1,71],"114":72,"130":[1,91],"131":[1,92],"133":[1,83],"134":[1,82],"137":[1,84],"138":[1,85],"139":[1,86],"140":[1,87],"141":[1,88],"142":[1,89],"144":[1,90]},{"4":[1,279],"30":[1,351]},{"30":[1,352],"47":[1,95],"106":93,"107":[1,68],"109":[1,69],"112":94,"113":[1,71],"114":72,"130":[1,91],"131":[1,92],"133":[1,83],"134":[1,82],"137":[1,84],"138":[1,85],"139":[1,86],"140":[1,87],"141":[1,88],"142":[1,89],"144":[1,90]},{"1":[2,101],"4":[2,101],"29":[2,101],"30":[2,101],"47":[2,101],"55":[2,101],"59":[2,101],"75":[2,101],"80":[2,101],"90":[2,101],"94":[2,101],"96":[2,101],"105":[2,101],"107":[2,101],"108":[2,101],"109":[2,101],"113":[2,101],"121":[2,101],"130":[2,101],"131":[2,101],"133":[2,101],"134":[2,101],"137":[2,101],"138":[2,101],"139":[2,101],"140":[2,101],"141":[2,101],"142":[2,101],"144":[2,101]},{"4":[1,285],"29":[1,286],"30":[1,353]},{"8":354,"9":124,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"31":64,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":65,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":41,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,43],"103":[1,51],"104":[1,58],"106":44,"107":[1,68],"109":[1,69],"110":45,"111":[1,70],"112":46,"113":[1,71],"114":72,"122":[1,47],"127":42,"128":[1,66],"129":[1,67],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"8":355,"9":124,"10":23,"11":24,"12":[1,25],"13":[1,26],"14":[1,27],"15":9,"16":10,"17":11,"18":12,"19":13,"20":14,"21":15,"22":16,"23":17,"24":18,"25":19,"26":20,"27":21,"28":22,"31":64,"32":[1,76],"33":54,"34":[1,74],"35":[1,75],"36":29,"37":[1,55],"38":[1,56],"39":[1,57],"40":28,"43":65,"45":[1,50],"46":[1,49],"48":[1,34],"51":35,"52":[1,62],"53":[1,63],"58":[1,61],"61":41,"63":52,"64":53,"65":30,"66":31,"67":32,"78":[1,73],"81":[1,48],"87":[1,33],"92":[1,60],"95":[1,59],"99":[1,43],"103":[1,51],"104":[1,58],"106":44,"107":[1,68],"109":[1,69],"110":45,"111":[1,70],"112":46,"113":[1,71],"114":72,"122":[1,47],"127":42,"128":[1,66],"129":[1,67],"132":[1,36],"133":[1,37],"134":[1,38],"135":[1,39],"136":[1,40]},{"4":[1,296],"29":[1,297],"30":[1,356]},{"4":[2,46],"29":[2,46],"30":[2,46],"55":[2,46],"80":[2,46]},{"4":[2,47],"29":[2,47],"30":[2,47],"55":[2,47],"80":[2,47]},{"1":[2,176],"4":[2,176],"29":[2,176],"30":[2,176],"47":[2,176],"55":[2,176],"59":[2,176],"75":[2,176],"80":[2,176],"90":[2,176],"94":[2,176],"96":[2,176],"105":[2,176],"107":[2,176],"108":[2,176],"109":[2,176],"113":[2,176],"121":[2,176],"130":[2,176],"131":[2,176],"133":[2,176],"134":[2,176],"137":[2,176],"138":[2,176],"139":[2,176],"140":[2,176],"141":[2,176],"142":[2,176],"144":[2,176]},{"1":[2,97],"4":[2,97],"29":[2,97],"30":[2,97],"47":[2,97],"55":[2,97],"59":[2,97],"75":[2,97],"80":[2,97],"90":[2,97],"94":[2,97],"96":[2,97],"105":[2,97],"107":[2,97],"108":[2,97],"109":[2,97],"113":[2,97],"121":[2,97],"130":[2,97],"131":[2,97],"133":[2,97],"134":[2,97],"137":[2,97],"138":[2,97],"139":[2,97],"140":[2,97],"141":[2,97],"142":[2,97],"144":[2,97]},{"4":[2,104],"30":[2,104],"80":[2,104]},{"4":[2,133],"29":[2,133],"30":[2,133],"55":[2,133],"90":[2,133],"96":[2,133]},{"1":[2,173],"4":[2,173],"29":[2,173],"30":[2,173],"47":[1,95],"55":[2,173],"59":[2,173],"75":[2,173],"80":[2,173],"90":[2,173],"94":[2,173],"96":[2,173],"105":[2,173],"106":93,"107":[2,173],"108":[2,173],"109":[2,173],"112":94,"113":[2,173],"114":72,"121":[2,173],"130":[2,173],"131":[2,173],"133":[1,83],"134":[1,82],"137":[1,84],"138":[1,85],"139":[1,86],"140":[1,87],"141":[1,88],"142":[1,89],"144":[1,90]},{"1":[2,174],"4":[2,174],"29":[2,174],"30":[2,174],"47":[1,95],"55":[2,174],"59":[2,174],"75":[2,174],"80":[2,174],"90":[2,174],"94":[2,174],"96":[2,174],"105":[2,174],"106":93,"107":[2,174],"108":[2,174],"109":[2,174],"112":94,"113":[2,174],"114":72,"121":[2,174],"130":[2,174],"131":[2,174],"133":[1,83],"134":[1,82],"137":[1,84],"138":[1,85],"139":[1,86],"140":[1,87],"141":[1,88],"142":[1,89],"144":[1,90]},{"4":[2,93],"29":[2,93],"30":[2,93],"55":[2,93],"80":[2,93]}], +defaultActions: {"79":[2,4],"102":[2,115]}, +parseError: function parseError(str, hash) { + throw new Error(str); +}, +parse: function parse(input) { + var self = this, + stack = [0], + vstack = [null], // semantic value stack + table = this.table, + yytext = '', + yylineno = 0, + yyleng = 0, + shifts = 0, + reductions = 0, + recovering = 0, + TERROR = 2, + EOF = 1; + + this.lexer.setInput(input); + this.lexer.yy = this.yy; + this.yy.lexer = this.lexer; + + var parseError = this.yy.parseError = typeof this.yy.parseError == 'function' ? this.yy.parseError : this.parseError; + + function popStack (n) { + stack.length = stack.length - 2*n; + vstack.length = vstack.length - n; + } + + function checkRecover (st) { + for (var p in table[st]) if (p == TERROR) { + return true; + } + return false; + } + + function lex() { + var token; + token = self.lexer.lex() || 1; // $end = 1 + // if token isn't its numeric value, convert + if (typeof token !== 'number') { + token = self.symbols_[token] || token; + } + return token; + }; + + var symbol, preErrorSymbol, state, action, a, r, yyval={},p,len,newState, expected, recovered = false; + while (true) { + // retreive state number from top of stack + state = stack[stack.length-1]; + + // use default actions if available + if (this.defaultActions[state]) { + action = this.defaultActions[state]; + } else { + if (symbol == null) + symbol = lex(); + // read action for current state and first input + action = table[state] && table[state][symbol]; + } + + // handle parse error + if (typeof action === 'undefined' || !action.length || !action[0]) { + + if (!recovering) { + // Report error + expected = []; + for (p in table[state]) if (this.terminals_[p] && p > 2) { + expected.push("'"+this.terminals_[p]+"'"); + } + if (this.lexer.showPosition) { + parseError.call(this, 'Parse error on line '+(yylineno+1)+":\n"+this.lexer.showPosition()+'\nExpecting '+expected.join(', '), + {text: this.lexer.match, token: this.terminals_[symbol] || symbol, line: this.lexer.yylineno, expected: expected}); + } else { + parseError.call(this, 'Parse error on line '+(yylineno+1)+": Unexpected '"+(this.terminals_[symbol] || symbol)+"'", + {text: this.lexer.match, token: this.terminals_[symbol] || symbol, line: this.lexer.yylineno, expected: expected}); + } + } + + // just recovered from another error + if (recovering == 3) { + if (symbol == EOF) { + throw 'Parsing halted.' + } + + // discard current lookahead and grab another + yyleng = this.lexer.yyleng; + yytext = this.lexer.yytext; + yylineno = this.lexer.yylineno; + symbol = lex(); + } + + // try to recover from error + while (1) { + // check for error recovery rule in this state + if (checkRecover(state)) { + break; + } + if (state == 0) { + throw 'Parsing halted.' + } + popStack(1); + state = stack[stack.length-1]; + } + + preErrorSymbol = symbol; // save the lookahead token + symbol = TERROR; // insert generic error symbol as new lookahead + state = stack[stack.length-1]; + action = table[state] && table[state][TERROR]; + recovering = 3; // allow 3 real symbols to be shifted before reporting a new error + } + + // this shouldn't happen, unless resolve defaults are off + if (action[0] instanceof Array && action.length > 1) { + throw new Error('Parse Error: multiple actions possible at state: '+state+', token: '+symbol); + } + + a = action; + + switch (a[0]) { + + case 1: // shift + shifts++; + + stack.push(symbol); + vstack.push(this.lexer.yytext); // semantic values or junk only, no terminals + stack.push(a[1]); // push state + symbol = null; + if (!preErrorSymbol) { // normal execution/no error + yyleng = this.lexer.yyleng; + yytext = this.lexer.yytext; + yylineno = this.lexer.yylineno; + if (recovering > 0) + recovering--; + } else { // error just occurred, resume old lookahead f/ before error + symbol = preErrorSymbol; + preErrorSymbol = null; + } + break; + + case 2: // reduce + reductions++; + + len = this.productions_[a[1]][1]; + + // perform semantic action + yyval.$ = vstack[vstack.length-len]; // default to $$ = $1 + r = this.performAction.call(yyval, yytext, yyleng, yylineno, this.yy, a[1], vstack); + + if (typeof r !== 'undefined') { + return r; + } + + // pop off stack + if (len) { + stack = stack.slice(0,-1*len*2); + vstack = vstack.slice(0, -1*len); + } + + stack.push(this.productions_[a[1]][0]); // push nonterminal (reduce) + vstack.push(yyval.$); + // goto new state = table[STATE][NONTERMINAL] + newState = table[stack[stack.length-2]][stack[stack.length-1]]; + stack.push(newState); + break; + + case 3: // accept + + this.reductionCount = reductions; + this.shiftCount = shifts; + return true; + } + + } + + return true; +}}; +return parser; +})(); +if (typeof require !== 'undefined') { +exports.parser = parser; +exports.parse = function () { return parser.parse.apply(parser, arguments); } +exports.main = function commonjsMain(args) { + if (!args[1]) + throw new Error('Usage: '+args[0]+' FILE'); + if (typeof process !== 'undefined') { + var source = require('fs').readFileSync(require('path').join(process.cwd(), args[1]), "utf8"); + } else { + var cwd = require("file").path(require("file").cwd()); + var source = cwd.join(args[1]).read({charset: "utf-8"}); + } + return exports.parser.parse(source); +} +if (typeof module !== 'undefined' && require.main === module) { + exports.main(typeof process !== 'undefined' ? process.argv.slice(1) : require("system").args); +} +} \ No newline at end of file diff --git a/node_modules/jade/support/coffee-script/lib/repl.js b/node_modules/jade/support/coffee-script/lib/repl.js new file mode 100644 index 0000000..d30f756 --- /dev/null +++ b/node_modules/jade/support/coffee-script/lib/repl.js @@ -0,0 +1,38 @@ +(function() { + var CoffeeScript, helpers, readline, repl, run, stdio; + CoffeeScript = require('./coffee-script'); + helpers = require('./helpers'); + readline = require('readline'); + stdio = process.openStdin(); + helpers.extend(global, { + quit: function() { + return process.exit(0); + } + }); + run = function(buffer) { + var val; + try { + val = CoffeeScript.eval(buffer.toString(), { + bare: true, + globals: true, + fileName: 'repl' + }); + if (val !== undefined) { + puts(inspect(val)); + } + } catch (err) { + puts(err.stack || err.toString()); + } + return repl.prompt(); + }; + repl = readline.createInterface(stdio); + repl.setPrompt('coffee> '); + stdio.on('data', function(buffer) { + return repl.write(buffer); + }); + repl.on('close', function() { + return stdio.destroy(); + }); + repl.on('line', run); + repl.prompt(); +}).call(this); diff --git a/node_modules/jade/support/coffee-script/lib/rewriter.js b/node_modules/jade/support/coffee-script/lib/rewriter.js new file mode 100644 index 0000000..6999fc8 --- /dev/null +++ b/node_modules/jade/support/coffee-script/lib/rewriter.js @@ -0,0 +1,378 @@ +(function() { + var BALANCED_PAIRS, EXPRESSION_CLOSE, EXPRESSION_END, EXPRESSION_START, IMPLICIT_BLOCK, IMPLICIT_CALL, IMPLICIT_END, IMPLICIT_FUNC, IMPLICIT_UNSPACED_CALL, INVERSES, LINEBREAKS, SINGLE_CLOSERS, SINGLE_LINERS, _i, _len, _ref, include, left, rite; + include = require('./helpers').include; + exports.Rewriter = (function() { + function Rewriter() { + return this; + }; + return Rewriter; + })(); + exports.Rewriter.prototype.rewrite = function(_arg) { + this.tokens = _arg; + this.adjustComments(); + this.removeLeadingNewlines(); + this.removeMidExpressionNewlines(); + this.closeOpenCalls(); + this.closeOpenIndexes(); + this.addImplicitIndentation(); + this.tagPostfixConditionals(); + this.addImplicitBraces(); + this.addImplicitParentheses(); + this.ensureBalance(BALANCED_PAIRS); + this.rewriteClosingParens(); + return this.tokens; + }; + exports.Rewriter.prototype.scanTokens = function(block) { + var i, token, tokens; + tokens = this.tokens; + i = 0; + while (token = tokens[i]) { + i += block.call(this, token, i, tokens); + } + return true; + }; + exports.Rewriter.prototype.detectEnd = function(i, condition, action) { + var levels, token, tokens; + tokens = this.tokens; + levels = 0; + while (token = tokens[i]) { + if (levels === 0 && condition.call(this, token, i)) { + return action.call(this, token, i); + } + if (!token || levels < 0) { + return action.call(this, token, i - 1); + } + if (include(EXPRESSION_START, token[0])) { + levels += 1; + } else if (include(EXPRESSION_END, token[0])) { + levels -= 1; + } + i += 1; + } + return i - 1; + }; + exports.Rewriter.prototype.adjustComments = function() { + return this.scanTokens(function(token, i, tokens) { + var _ref, after, before, post, prev; + if (token[0] !== 'HERECOMMENT') { + return 1; + } + before = tokens[i - 2]; + prev = tokens[i - 1]; + post = tokens[i + 1]; + after = tokens[i + 2]; + if (((after != null) ? after[0] : undefined) === 'INDENT') { + tokens.splice(i + 2, 1); + if (((before != null) ? before[0] : undefined) === 'OUTDENT' && ((post != null) ? post[0] : undefined) === 'TERMINATOR') { + tokens.splice(i - 2, 1); + } else { + tokens.splice(i, 0, after); + } + } else if (prev && !((_ref = prev[0]) === 'TERMINATOR' || _ref === 'INDENT' || _ref === 'OUTDENT')) { + if (((post != null) ? post[0] : undefined) === 'TERMINATOR' && ((after != null) ? after[0] : undefined) === 'OUTDENT') { + tokens.splice.apply(tokens, [i + 2, 0].concat(tokens.splice(i, 2))); + if (tokens[i + 2][0] !== 'TERMINATOR') { + tokens.splice(i + 2, 0, ['TERMINATOR', '\n', prev[2]]); + } + } else { + tokens.splice(i, 0, ['TERMINATOR', '\n', prev[2]]); + } + return 2; + } + return 1; + }); + }; + exports.Rewriter.prototype.removeLeadingNewlines = function() { + var _len, _ref, i, tag; + for (i = 0, _len = (_ref = this.tokens).length; i < _len; i++) { + tag = _ref[i][0]; + if (tag !== 'TERMINATOR') { + break; + } + } + return i ? this.tokens.splice(0, i) : undefined; + }; + exports.Rewriter.prototype.removeMidExpressionNewlines = function() { + return this.scanTokens(function(token, i, tokens) { + if (!(token[0] === 'TERMINATOR' && include(EXPRESSION_CLOSE, this.tag(i + 1)))) { + return 1; + } + tokens.splice(i, 1); + return 0; + }); + }; + exports.Rewriter.prototype.closeOpenCalls = function() { + var action, condition; + condition = function(token, i) { + var _ref; + return ((_ref = token[0]) === ')' || _ref === 'CALL_END') || token[0] === 'OUTDENT' && this.tag(i - 1) === ')'; + }; + action = function(token, i) { + return (this.tokens[token[0] === 'OUTDENT' ? i - 1 : i][0] = 'CALL_END'); + }; + return this.scanTokens(function(token, i) { + if (token[0] === 'CALL_START') { + this.detectEnd(i + 1, condition, action); + } + return 1; + }); + }; + exports.Rewriter.prototype.closeOpenIndexes = function() { + var action, condition; + condition = function(token, i) { + var _ref; + return ((_ref = token[0]) === ']' || _ref === 'INDEX_END'); + }; + action = function(token, i) { + return (token[0] = 'INDEX_END'); + }; + return this.scanTokens(function(token, i) { + if (token[0] === 'INDEX_START') { + this.detectEnd(i + 1, condition, action); + } + return 1; + }); + }; + exports.Rewriter.prototype.addImplicitBraces = function() { + var action, condition, stack; + stack = []; + condition = function(token, i) { + var _ref, _ref2, one, tag, three, two; + if (('HERECOMMENT' === this.tag(i + 1) || 'HERECOMMENT' === this.tag(i - 1))) { + return false; + } + _ref = this.tokens.slice(i + 1, i + 4), one = _ref[0], two = _ref[1], three = _ref[2]; + tag = token[0]; + return (tag === 'TERMINATOR' || tag === 'OUTDENT') && !(((two != null) ? two[0] : undefined) === ':' || ((one != null) ? one[0] : undefined) === '@' && ((three != null) ? three[0] : undefined) === ':') || tag === ',' && !((_ref2 = ((one != null) ? one[0] : undefined)) === 'IDENTIFIER' || _ref2 === 'NUMBER' || _ref2 === 'STRING' || _ref2 === '@' || _ref2 === 'TERMINATOR' || _ref2 === 'OUTDENT'); + }; + action = function(token, i) { + return this.tokens.splice(i, 0, ['}', '}', token[2]]); + }; + return this.scanTokens(function(token, i, tokens) { + var idx, tag, tok; + if (include(EXPRESSION_START, tag = token[0])) { + stack.push(tag === 'INDENT' && this.tag(i - 1) === '{' ? '{' : tag); + return 1; + } + if (include(EXPRESSION_END, tag)) { + stack.pop(); + return 1; + } + if (!(tag === ':' && stack[stack.length - 1] !== '{')) { + return 1; + } + stack.push('{'); + idx = this.tag(i - 2) === '@' ? i - 2 : i - 1; + if (this.tag(idx - 2) === 'HERECOMMENT') { + idx -= 2; + } + tok = ['{', '{', token[2]]; + tok.generated = true; + tokens.splice(idx, 0, tok); + this.detectEnd(i + 2, condition, action); + return 2; + }); + }; + exports.Rewriter.prototype.addImplicitParentheses = function() { + var action, classLine; + classLine = false; + action = function(token, i) { + var idx; + idx = token[0] === 'OUTDENT' ? i + 1 : i; + return this.tokens.splice(idx, 0, ['CALL_END', ')', token[2]]); + }; + return this.scanTokens(function(token, i, tokens) { + var callObject, next, prev, seenSingle, tag; + tag = token[0]; + if (tag === 'CLASS') { + classLine = true; + } + prev = tokens[i - 1]; + next = tokens[i + 1]; + callObject = !classLine && tag === 'INDENT' && next && next.generated && next[0] === '{' && prev && include(IMPLICIT_FUNC, prev[0]); + seenSingle = false; + if (include(LINEBREAKS, tag)) { + classLine = false; + } + if (prev && !prev.spaced && tag === '?') { + token.call = true; + } + if (!(callObject || ((prev != null) ? prev.spaced : undefined) && (prev.call || include(IMPLICIT_FUNC, prev[0])) && (include(IMPLICIT_CALL, tag) || include(IMPLICIT_UNSPACED_CALL, tag) && !token.spaced))) { + return 1; + } + tokens.splice(i, 0, ['CALL_START', '(', token[2]]); + this.detectEnd(i + (callObject ? 2 : 1), function(token, i) { + var post; + if (!seenSingle && token.fromThen) { + return true; + } + tag = token[0]; + if ((tag === 'IF' || tag === 'ELSE' || tag === 'UNLESS' || tag === '->' || tag === '=>')) { + seenSingle = true; + } + if (tag === 'PROPERTY_ACCESS' && this.tag(i - 1) === 'OUTDENT') { + return true; + } + return !token.generated && this.tag(i - 1) !== ',' && include(IMPLICIT_END, tag) && (tag !== 'INDENT' || (this.tag(i - 2) !== 'CLASS' && !include(IMPLICIT_BLOCK, this.tag(i - 1)) && !((post = this.tokens[i + 1]) && post.generated && post[0] === '{'))); + }, action); + if (prev[0] === '?') { + prev[0] = 'FUNC_EXIST'; + } + return 2; + }); + }; + exports.Rewriter.prototype.addImplicitIndentation = function() { + return this.scanTokens(function(token, i, tokens) { + var _ref, _ref2, action, condition, indent, outdent, starter, tag; + tag = token[0]; + if (tag === 'ELSE' && this.tag(i - 1) !== 'OUTDENT') { + tokens.splice.apply(tokens, [i, 0].concat(this.indentation(token))); + return 2; + } + if (tag === 'CATCH' && ((_ref = this.tag(i + 2)) === 'TERMINATOR' || _ref === 'FINALLY')) { + tokens.splice.apply(tokens, [i + 2, 0].concat(this.indentation(token))); + return 4; + } + if (include(SINGLE_LINERS, tag) && this.tag(i + 1) !== 'INDENT' && !(tag === 'ELSE' && this.tag(i + 1) === 'IF')) { + starter = tag; + _ref2 = this.indentation(token), indent = _ref2[0], outdent = _ref2[1]; + if (starter === 'THEN') { + indent.fromThen = true; + } + indent.generated = (outdent.generated = true); + tokens.splice(i + 1, 0, indent); + condition = function(token, i) { + return token[1] !== ';' && include(SINGLE_CLOSERS, token[0]) && !(token[0] === 'ELSE' && !(starter === 'IF' || starter === 'THEN')); + }; + action = function(token, i) { + return this.tokens.splice(this.tag(i - 1) === ',' ? i - 1 : i, 0, outdent); + }; + this.detectEnd(i + 2, condition, action); + if (tag === 'THEN') { + tokens.splice(i, 1); + } + return 1; + } + return 1; + }); + }; + exports.Rewriter.prototype.tagPostfixConditionals = function() { + var condition; + condition = function(token, i) { + var _ref; + return ((_ref = token[0]) === 'TERMINATOR' || _ref === 'INDENT'); + }; + return this.scanTokens(function(token, i) { + var _ref, original; + if (!((_ref = token[0]) === 'IF' || _ref === 'UNLESS')) { + return 1; + } + original = token; + this.detectEnd(i + 1, condition, function(token, i) { + return token[0] !== 'INDENT' ? (original[0] = 'POST_' + original[0]) : undefined; + }); + return 1; + }); + }; + exports.Rewriter.prototype.ensureBalance = function(pairs) { + var _result, key, levels, open, openLine, unclosed, value; + levels = {}; + openLine = {}; + this.scanTokens(function(token, i) { + var _i, _len, _ref, _ref2, close, open, tag; + tag = token[0]; + for (_i = 0, _len = (_ref = pairs).length; _i < _len; _i++) { + _ref2 = _ref[_i], open = _ref2[0], close = _ref2[1]; + levels[open] |= 0; + if (tag === open) { + if (levels[open] === 0) { + openLine[open] = token[2]; + } + levels[open] += 1; + } else if (tag === close) { + levels[open] -= 1; + } + if (levels[open] < 0) { + throw Error("too many " + (token[1]) + " on line " + (token[2] + 1)); + } + } + return 1; + }); + unclosed = (function() { + _result = []; + for (key in levels) { + value = levels[key]; + if (value > 0) { + _result.push(key); + } + } + return _result; + })(); + if (unclosed.length) { + throw Error("unclosed " + (open = unclosed[0]) + " on line " + (openLine[open] + 1)); + } + }; + exports.Rewriter.prototype.rewriteClosingParens = function() { + var debt, key, stack; + stack = []; + debt = {}; + for (key in INVERSES) { + (debt[key] = 0); + } + return this.scanTokens(function(token, i, tokens) { + var inv, match, mtag, oppos, tag, val; + if (include(EXPRESSION_START, tag = token[0])) { + stack.push(token); + return 1; + } + if (!include(EXPRESSION_END, tag)) { + return 1; + } + if (debt[(inv = INVERSES[tag])] > 0) { + debt[inv] -= 1; + tokens.splice(i, 1); + return 0; + } + match = stack.pop(); + mtag = match[0]; + oppos = INVERSES[mtag]; + if (tag === oppos) { + return 1; + } + debt[mtag] += 1; + val = [oppos, mtag === 'INDENT' ? match[1] : oppos]; + if (this.tag(i + 2) === mtag) { + tokens.splice(i + 3, 0, val); + stack.push(match); + } else { + tokens.splice(i, 0, val); + } + return 1; + }); + }; + exports.Rewriter.prototype.indentation = function(token) { + return [['INDENT', 2, token[2]], ['OUTDENT', 2, token[2]]]; + }; + exports.Rewriter.prototype.tag = function(i) { + var _ref; + return (((_ref = this.tokens[i]) != null) ? _ref[0] : undefined); + }; + BALANCED_PAIRS = [['(', ')'], ['[', ']'], ['{', '}'], ['INDENT', 'OUTDENT'], ['CALL_START', 'CALL_END'], ['PARAM_START', 'PARAM_END'], ['INDEX_START', 'INDEX_END']]; + INVERSES = {}; + EXPRESSION_START = []; + EXPRESSION_END = []; + for (_i = 0, _len = BALANCED_PAIRS.length; _i < _len; _i++) { + _ref = BALANCED_PAIRS[_i], left = _ref[0], rite = _ref[1]; + EXPRESSION_START.push(INVERSES[rite] = left); + EXPRESSION_END.push(INVERSES[left] = rite); + } + EXPRESSION_CLOSE = ['CATCH', 'WHEN', 'ELSE', 'FINALLY'].concat(EXPRESSION_END); + IMPLICIT_FUNC = ['IDENTIFIER', 'SUPER', ')', 'CALL_END', ']', 'INDEX_END', '@', 'THIS']; + IMPLICIT_CALL = ['IDENTIFIER', 'NUMBER', 'STRING', 'JS', 'REGEX', 'NEW', 'PARAM_START', 'CLASS', 'IF', 'UNLESS', 'TRY', 'SWITCH', 'THIS', 'BOOL', 'UNARY', '@', '->', '=>', '[', '(', '{', '--', '++']; + IMPLICIT_UNSPACED_CALL = ['+', '-']; + IMPLICIT_BLOCK = ['->', '=>', '{', '[', ',']; + IMPLICIT_END = ['POST_IF', 'POST_UNLESS', 'FOR', 'WHILE', 'UNTIL', 'LOOP', 'TERMINATOR', 'INDENT']; + SINGLE_LINERS = ['ELSE', '->', '=>', 'TRY', 'FINALLY', 'THEN']; + SINGLE_CLOSERS = ['TERMINATOR', 'CATCH', 'FINALLY', 'ELSE', 'OUTDENT', 'LEADING_WHEN']; + LINEBREAKS = ['TERMINATOR', 'INDENT', 'OUTDENT']; +}).call(this); diff --git a/node_modules/jade/support/coffee-script/lib/scope.js b/node_modules/jade/support/coffee-script/lib/scope.js new file mode 100644 index 0000000..b0f2a64 --- /dev/null +++ b/node_modules/jade/support/coffee-script/lib/scope.js @@ -0,0 +1,134 @@ +(function() { + var Scope, _ref, extend, last; + var __hasProp = Object.prototype.hasOwnProperty; + _ref = require('./helpers'), extend = _ref.extend, last = _ref.last; + exports.Scope = (function() { + Scope = (function() { + function Scope(_arg, _arg2, _arg3) { + this.method = _arg3; + this.expressions = _arg2; + this.parent = _arg; + this.variables = { + 'arguments': 'arguments' + }; + if (this.parent) { + this.garbage = this.parent.garbage; + } else { + this.garbage = []; + Scope.root = this; + } + return this; + }; + return Scope; + })(); + Scope.root = null; + Scope.prototype.startLevel = function() { + return this.garbage.push([]); + }; + Scope.prototype.endLevel = function() { + var _i, _len, _ref2, _result, name, vars; + vars = this.variables; + _result = []; + for (_i = 0, _len = (_ref2 = this.garbage.pop()).length; _i < _len; _i++) { + name = _ref2[_i]; + if (vars[name] === 'var') { + _result.push(vars[name] = 'reuse'); + } + } + return _result; + }; + Scope.prototype.find = function(name, options) { + if (this.check(name, options)) { + return true; + } + this.variables[name] = 'var'; + return false; + }; + Scope.prototype.any = function(fn) { + var _ref2, k, v; + for (v in _ref2 = this.variables) { + if (!__hasProp.call(_ref2, v)) continue; + k = _ref2[v]; + if (fn(v, k)) { + return true; + } + } + return false; + }; + Scope.prototype.parameter = function(name) { + return (this.variables[name] = 'param'); + }; + Scope.prototype.check = function(name, options) { + var _ref2, immediate; + immediate = Object.prototype.hasOwnProperty.call(this.variables, name); + if (immediate || ((options != null) ? options.immediate : undefined)) { + return immediate; + } + return !!(((_ref2 = this.parent) != null) ? _ref2.check(name) : undefined); + }; + Scope.prototype.temporary = function(type, index) { + return type.length > 1 ? '_' + type + (index > 1 ? index : '') : '_' + (index + parseInt(type, 36)).toString(36).replace(/\d/g, 'a'); + }; + Scope.prototype.freeVariable = function(type) { + var index, temp; + index = 0; + while (this.check(temp = this.temporary(type, index)) && this.variables[temp] !== 'reuse') { + index++; + } + this.variables[temp] = 'var'; + if (this.garbage.length) { + last(this.garbage).push(temp); + } + return temp; + }; + Scope.prototype.assign = function(name, value) { + return (this.variables[name] = { + value: value, + assigned: true + }); + }; + Scope.prototype.hasDeclarations = function(body) { + return body === this.expressions && this.any(function(k, val) { + return (val === 'var' || val === 'reuse'); + }); + }; + Scope.prototype.hasAssignments = function(body) { + return body === this.expressions && this.any(function(k, val) { + return val.assigned; + }); + }; + Scope.prototype.declaredVariables = function() { + var _ref2, _result, key, val; + return (function() { + _result = []; + for (key in _ref2 = this.variables) { + if (!__hasProp.call(_ref2, key)) continue; + val = _ref2[key]; + if ((val === 'var' || val === 'reuse')) { + _result.push(key); + } + } + return _result; + }).call(this).sort(); + }; + Scope.prototype.assignedVariables = function() { + var _ref2, _result, key, val; + _result = []; + for (key in _ref2 = this.variables) { + if (!__hasProp.call(_ref2, key)) continue; + val = _ref2[key]; + if (val.assigned) { + _result.push("" + key + " = " + (val.value)); + } + } + return _result; + }; + Scope.prototype.compiledDeclarations = function() { + return this.declaredVariables().join(', '); + }; + Scope.prototype.compiledAssignments = function() { + return this.assignedVariables().join(', '); + }; + return Scope; + }).call(this); +}).call(this); diff --git a/node_modules/jade/support/coffee-script/lib/utilities.js b/node_modules/jade/support/coffee-script/lib/utilities.js new file mode 100644 index 0000000..dacb61d --- /dev/null +++ b/node_modules/jade/support/coffee-script/lib/utilities.js @@ -0,0 +1,12 @@ +(function(){ + if (!((typeof process !== "undefined" && process !== null))) { + this.exports = this; + } + exports.utilities = { + extend: "function(child, parent) {\n var ctor = function(){ };\n ctor.prototype = parent.prototype;\n child.__superClass__ = parent.prototype;\n child.prototype = new ctor();\n child.prototype.constructor = child;\n }", + bind: "function(func, obj, args) {\n return function() {\n return func.apply(obj || {}, args ? args.concat(__slice.call(arguments, 0)) : arguments);\n };\n }", + range: "function(array, from, to, exclusive) {\n return [\n (from < 0 ? from + array.length : from || 0),\n (to < 0 ? to + array.length : to || array.length) + (exclusive ? 0 : 1)\n ];\n }", + hasProp: 'Object.prototype.hasOwnProperty', + slice: 'Array.prototype.slice' + }; +})(); diff --git a/node_modules/jade/support/coffee-script/package.json b/node_modules/jade/support/coffee-script/package.json new file mode 100644 index 0000000..89f7340 --- /dev/null +++ b/node_modules/jade/support/coffee-script/package.json @@ -0,0 +1,22 @@ +{ + "name": "coffee-script", + "description": "Unfancy JavaScript", + "keywords": ["javascript", "language", "coffeescript", "compiler"], + "author": "Jeremy Ashkenas", + "version": "0.9.4", + "licenses": [{ + "type": "MIT", + "url": "http://github.com/jashkenas/coffee-script/raw/master/LICENSE" + }], + "engines": { + "node": ">=0.1.99" + }, + "directories" : { + "lib" : "./lib" + }, + "main" : "./lib/coffee-script", + "bin": { + "coffee": "./bin/coffee", + "cake": "./bin/cake" + } +} diff --git a/node_modules/jade/support/coffee-script/src/browser.coffee b/node_modules/jade/support/coffee-script/src/browser.coffee new file mode 100644 index 0000000..ddb7a0f --- /dev/null +++ b/node_modules/jade/support/coffee-script/src/browser.coffee @@ -0,0 +1,41 @@ +# Override exported methods for non-Node.js engines. + +CoffeeScript = require './coffee-script' +CoffeeScript.require = require + +# Use standard JavaScript `eval` to eval code. +CoffeeScript.eval = (code, options) -> + eval CoffeeScript.compile code, options + +# Running code does not provide access to this scope. +CoffeeScript.run = (code, options) -> + options?.bare = on + Function(CoffeeScript.compile code, options)() + +# If we're not in a browser environment, we're finished with the public API. +return unless window? + +# Load a remote script from the current domain via XHR. +CoffeeScript.load = (url, options) -> + xhr = new (window.ActiveXObject or XMLHttpRequest)('Microsoft.XMLHTTP') + xhr.open 'GET', url, true + xhr.overrideMimeType 'text/plain' if 'overrideMimeType' of xhr + xhr.onreadystatechange = -> + CoffeeScript.run xhr.responseText, options if xhr.readyState is 4 + xhr.send null + +# Activate CoffeeScript in the browser by having it compile and evaluate +# all script tags with a content-type of `text/coffeescript`. +# This happens on page load. +runScripts = -> + for script in document.getElementsByTagName 'script' + if script.type is 'text/coffeescript' + if script.src + CoffeeScript.load script.src + else + setTimeout -> CoffeeScript.run script.innerHTML + null +if window.addEventListener + addEventListener 'DOMContentLoaded', runScripts, no +else + attachEvent 'onload', runScripts diff --git a/node_modules/jade/support/coffee-script/src/cake.coffee b/node_modules/jade/support/coffee-script/src/cake.coffee new file mode 100644 index 0000000..61567bc --- /dev/null +++ b/node_modules/jade/support/coffee-script/src/cake.coffee @@ -0,0 +1,69 @@ +# `cake` is a simplified version of [Make](http://www.gnu.org/software/make/) +# ([Rake](http://rake.rubyforge.org/), [Jake](http://github.com/280north/jake)) +# for CoffeeScript. You define tasks with names and descriptions in a Cakefile, +# and can call them from the command line, or invoke them from other tasks. +# +# Running `cake` with no arguments will print out a list of all the tasks in the +# current directory's Cakefile. + +# External dependencies. +fs = require 'fs' +path = require 'path' +helpers = require './helpers' +optparse = require './optparse' +CoffeeScript = require './coffee-script' + +# Keep track of the list of defined tasks, the accepted options, and so on. +tasks = {} +options = {} +switches = [] +oparse = null + +# Mixin the top-level Cake functions for Cakefiles to use directly. +helpers.extend global, + + # Define a Cake task with a short name, an optional sentence description, + # and the function to run as the action itself. + task: (name, description, action) -> + [action, description] = [description, action] unless action + tasks[name] = {name, description, action} + + # Define an option that the Cakefile accepts. The parsed options hash, + # containing all of the command-line options passed, will be made available + # as the first argument to the action. + option: (letter, flag, description) -> + switches.push [letter, flag, description] + + # Invoke another task in the current Cakefile. + invoke: (name) -> + missingTask name unless tasks[name] + tasks[name].action options + + +# Run `cake`. Executes all of the tasks you pass, in order. Note that Node's +# asynchrony may cause tasks to execute in a different order than you'd expect. +# If no tasks are passed, print the help screen. +exports.run = -> + path.exists 'Cakefile', (exists) -> + throw new Error("Cakefile not found in #{process.cwd()}") unless exists + args = process.argv.slice 2 + CoffeeScript.run fs.readFileSync('Cakefile').toString(), fileName: 'Cakefile' + oparse = new optparse.OptionParser switches + return printTasks() unless args.length + options = oparse.parse(args) + invoke arg for arg in options.arguments + +# Display the list of Cake tasks in a format similar to `rake -T` +printTasks = -> + puts '' + for all name, task of tasks + spaces = 20 - name.length + spaces = if spaces > 0 then Array(spaces + 1).join(' ') else '' + desc = if task.description then "# #{task.description}" else '' + puts "cake #{name}#{spaces} #{desc}" + puts oparse.help() if switches.length + +# Print an error and exit when attempting to all an undefined task. +missingTask = (task) -> + puts "No such task: \"#{task}\"" + process.exit 1 diff --git a/node_modules/jade/support/coffee-script/src/coffee-script.coffee b/node_modules/jade/support/coffee-script/src/coffee-script.coffee new file mode 100755 index 0000000..135788d --- /dev/null +++ b/node_modules/jade/support/coffee-script/src/coffee-script.coffee @@ -0,0 +1,90 @@ +# CoffeeScript can be used both on the server, as a command-line compiler based +# on Node.js/V8, or to run CoffeeScripts directly in the browser. This module +# contains the main entry functions for tokenzing, parsing, and compiling source +# CoffeeScript into JavaScript. +# +# If included on a webpage, it will automatically sniff out, compile, and +# execute all scripts present in `text/coffeescript` tags. + +path = require 'path' +{Lexer} = require './lexer' +{parser} = require './parser' + +# TODO: Remove registerExtension when fully deprecated +if require.extensions + fs = require 'fs' + require.extensions['.coffee'] = (module, filename) -> + content = compile fs.readFileSync filename, 'utf8' + module._compile content, filename +else if require.registerExtension + require.registerExtension '.coffee', (content) -> compile content + +# The current CoffeeScript version number. +exports.VERSION = '0.9.4' + +# Expose helpers for testing. +exports.helpers = require './helpers' + +# Compile a string of CoffeeScript code to JavaScript, using the Coffee/Jison +# compiler. +exports.compile = compile = (code, options) -> + options or= {} + try + (parser.parse lexer.tokenize code).compile options + catch err + err.message = "In #{options.fileName}, #{err.message}" if options.fileName + throw err + +# Tokenize a string of CoffeeScript code, and return the array of tokens. +exports.tokens = (code, options) -> + lexer.tokenize code, options + +# Tokenize and parse a string of CoffeeScript code, and return the AST. You can +# then compile it by calling `.compile()` on the root, or traverse it by using +# `.traverse()` with a callback. +exports.nodes = (code, options) -> + parser.parse lexer.tokenize code, options + +# Compile and execute a string of CoffeeScript (on the server), correctly +# setting `__filename`, `__dirname`, and relative `require()`. +exports.run = (code, options) -> + # We want the root module. + root = module + while root.parent + root = root.parent + # Set the filename + root.filename = options.fileName + # Clear the module cache + root.moduleCache = {} if root.moduleCache + # Compile + if path.extname(root.filename) isnt '.coffee' or require.extensions + root._compile exports.compile(code, options), root.filename + else + root._compile code, root.filename + +# Compile and evaluate a string of CoffeeScript (in a Node.js-like environment). +# The CoffeeScript REPL uses this to run the input. +exports.eval = (code, options) -> + __filename = options.fileName + __dirname = path.dirname __filename + eval exports.compile(code, options) + +# Instantiate a Lexer for our use here. +lexer = new Lexer + +# The real Lexer produces a generic stream of tokens. This object provides a +# thin wrapper around it, compatible with the Jison API. We can then pass it +# directly as a "Jison lexer". +parser.lexer = + lex: -> + token = @tokens[@pos] or [""] + @pos += 1 + this.yylineno = token[2] + this.yytext = token[1] + token[0] + setInput: (tokens) -> + @tokens = tokens + @pos = 0 + upcomingInput: -> "" + +parser.yy = require './nodes' diff --git a/node_modules/jade/support/coffee-script/src/command.coffee b/node_modules/jade/support/coffee-script/src/command.coffee new file mode 100644 index 0000000..59cf5ef --- /dev/null +++ b/node_modules/jade/support/coffee-script/src/command.coffee @@ -0,0 +1,195 @@ +# The `coffee` utility. Handles command-line compilation of CoffeeScript +# into various forms: saved into `.js` files or printed to stdout, piped to +# [JSLint](http://javascriptlint.com/) or recompiled every time the source is +# saved, printed as a token stream or as the syntax tree, or launch an +# interactive REPL. + +# External dependencies. +fs = require 'fs' +path = require 'path' +optparse = require './optparse' +CoffeeScript = require './coffee-script' +helpers = require './helpers' +{spawn, exec} = require 'child_process' +{EventEmitter} = require 'events' + +# Allow CoffeeScript to emit Node.js events, and add it to global scope. +helpers.extend CoffeeScript, new EventEmitter +global.CoffeeScript = CoffeeScript + +# The help banner that is printed when `coffee` is called without arguments. +BANNER = ''' + coffee compiles CoffeeScript source files into JavaScript. + + Usage: + coffee path/to/script.coffee + ''' + +# The list of all the valid option flags that `coffee` knows how to handle. +SWITCHES = [ + ['-c', '--compile', 'compile to JavaScript and save as .js files'] + ['-i', '--interactive', 'run an interactive CoffeeScript REPL'] + ['-o', '--output [DIR]', 'set the directory for compiled JavaScript'] + ['-w', '--watch', 'watch scripts for changes, and recompile'] + ['-p', '--print', 'print the compiled JavaScript to stdout'] + ['-l', '--lint', 'pipe the compiled JavaScript through JSLint'] + ['-s', '--stdio', 'listen for and compile scripts over stdio'] + ['-e', '--eval', 'compile a string from the command line'] + ['-r', '--require [FILE*]', 'require a library before executing your script'] + ['-b', '--bare', 'compile without the top-level function wrapper'] + ['-t', '--tokens', 'print the tokens that the lexer produces'] + ['-n', '--nodes', 'print the parse tree that Jison produces'] + ['-v', '--version', 'display CoffeeScript version'] + ['-h', '--help', 'display this help message'] +] + +# Top-level objects shared by all the functions. +opts = {} +sources = [] +optionParser = null + +# Run `coffee` by parsing passed options and determining what action to take. +# Many flags cause us to divert before compiling anything. Flags passed after +# `--` will be passed verbatim to your script as arguments in `process.argv` +exports.run = -> + parseOptions() + return usage() if opts.help + return version() if opts.version + return require './repl' if opts.interactive + return compileStdio() if opts.stdio + return compileScript 'console', sources[0] if opts.eval + return require './repl' unless sources.length + separator = sources.indexOf '--' + flags = [] + if separator >= 0 + flags = sources.splice separator + 1 + sources.pop() + if opts.run + flags = sources.splice(1).concat flags + process.ARGV = process.argv = flags + compileScripts() + +# Asynchronously read in each CoffeeScript in a list of source files and +# compile them. If a directory is passed, recursively compile all +# '.coffee' extension source files in it and all subdirectories. +compileScripts = -> + for source in sources + base = source + compile = (source, topLevel) -> + path.exists source, (exists) -> + throw new Error "File not found: #{source}" unless exists + fs.stat source, (err, stats) -> + if stats.isDirectory() + fs.readdir source, (err, files) -> + for file in files + compile path.join(source, file) + else if topLevel or path.extname(source) is '.coffee' + fs.readFile source, (err, code) -> compileScript(source, code.toString(), base) + watch source, base if opts.watch + compile source, true + +# Compile a single source script, containing the given code, according to the +# requested options. If evaluating the script directly sets `__filename`, +# `__dirname` and `module.filename` to be correct relative to the script's path. +compileScript = (file, input, base) -> + o = opts + options = compileOptions file + if o.require + require(if helpers.starts(req, '.') then fs.realpathSync(req) else req) for req in o.require + try + t = task = {file, input, options} + CoffeeScript.emit 'compile', task + if o.tokens then printTokens CoffeeScript.tokens t.input + else if o.nodes then puts CoffeeScript.nodes(t.input).toString().trim() + else if o.run then CoffeeScript.run t.input, t.options + else + t.output = CoffeeScript.compile t.input, t.options + CoffeeScript.emit 'success', task + if o.print then print t.output + else if o.compile then writeJs t.file, t.output, base + else if o.lint then lint t.output + catch err + # Avoid using 'error' as it is a special event -- if there is no handler, + # node will print a stack trace and exit the program. + CoffeeScript.emit 'failure', err, task + return if CoffeeScript.listeners('failure').length + return puts err.message if o.watch + error err.stack + process.exit 1 + +# Attach the appropriate listeners to compile scripts incoming over **stdin**, +# and write them back to **stdout**. +compileStdio = -> + code = '' + stdin = process.openStdin() + stdin.on 'data', (buffer) -> + code += buffer.toString() if buffer + stdin.on 'end', -> + compileScript 'stdio', code + +# Watch a source CoffeeScript file using `fs.watchFile`, recompiling it every +# time the file is updated. May be used in combination with other options, +# such as `--lint` or `--print`. +watch = (source, base) -> + fs.watchFile source, {persistent: true, interval: 500}, (curr, prev) -> + return if curr.size is prev.size and curr.mtime.getTime() is prev.mtime.getTime() + fs.readFile source, (err, code) -> + throw err if err + compileScript(source, code.toString(), base) + +# Write out a JavaScript source file with the compiled code. By default, files +# are written out in `cwd` as `.js` files with the same name, but the output +# directory can be customized with `--output`. +writeJs = (source, js, base) -> + filename = path.basename(source, path.extname(source)) + '.js' + srcDir = path.dirname source + baseDir = srcDir.substring base.length + dir = if opts.output then path.join opts.output, baseDir else srcDir + jsPath = path.join dir, filename + compile = -> + js = ' ' if js.length <= 0 + fs.writeFile jsPath, js, (err) -> + puts "Compiled #{source}" if opts.compile and opts.watch + path.exists dir, (exists) -> + if exists then compile() else exec "mkdir -p #{dir}", compile + +# Pipe compiled JS through JSLint (requires a working `jsl` command), printing +# any errors or warnings that arise. +lint = (js) -> + printIt = (buffer) -> puts buffer.toString().trim() + conf = __dirname + '/../extras/jsl.conf' + jsl = spawn 'jsl', ['-nologo', '-stdin', '-conf', conf] + jsl.stdout.on 'data', printIt + jsl.stderr.on 'data', printIt + jsl.stdin.write js + jsl.stdin.end() + +# Pretty-print a stream of tokens. +printTokens = (tokens) -> + strings = for token in tokens + [tag, value] = [token[0], token[1].toString().replace(/\n/, '\\n')] + "[#{tag} #{value}]" + puts strings.join(' ') + +# Use the [OptionParser module](optparse.html) to extract all options from +# `process.argv` that are specified in `SWITCHES`. +parseOptions = -> + optionParser = new optparse.OptionParser SWITCHES, BANNER + o = opts = optionParser.parse process.argv.slice 2 + o.compile or= !!o.output + o.run = not (o.compile or o.print or o.lint) + o.print = !! (o.print or (o.eval or o.stdio and o.compile)) + sources = o.arguments + +# The compile-time options to pass to the CoffeeScript compiler. +compileOptions = (fileName) -> {fileName, bare: opts.bare} + +# Print the `--help` usage message and exit. +usage = -> + puts optionParser.help() + process.exit 0 + +# Print the `--version` message and exit. +version = -> + puts "CoffeeScript version #{CoffeeScript.VERSION}" + process.exit 0 diff --git a/node_modules/jade/support/coffee-script/src/grammar.coffee b/node_modules/jade/support/coffee-script/src/grammar.coffee new file mode 100644 index 0000000..70f5632 --- /dev/null +++ b/node_modules/jade/support/coffee-script/src/grammar.coffee @@ -0,0 +1,613 @@ +# The CoffeeScript parser is generated by [Jison](http://github.com/zaach/jison) +# from this grammar file. Jison is a bottom-up parser generator, similar in +# style to [Bison](http://www.gnu.org/software/bison), implemented in JavaScript. +# It can recognize [LALR(1), LR(0), SLR(1), and LR(1)](http://en.wikipedia.org/wiki/LR_grammar) +# type grammars. To create the Jison parser, we list the pattern to match +# on the left-hand side, and the action to take (usually the creation of syntax +# tree nodes) on the right. As the parser runs, it +# shifts tokens from our token stream, from left to right, and +# [attempts to match](http://en.wikipedia.org/wiki/Bottom-up_parsing) +# the token sequence against the rules below. When a match can be made, it +# reduces into the [nonterminal](http://en.wikipedia.org/wiki/Terminal_and_nonterminal_symbols) +# (the enclosing name at the top), and we proceed from there. +# +# If you run the `cake build:parser` command, Jison constructs a parse table +# from our rules and saves it into `lib/parser.js`. + +# The only dependency is on the **Jison.Parser**. +Parser = require('jison').Parser + +# Jison DSL +# --------- + +# Since we're going to be wrapped in a function by Jison in any case, if our +# action immediately returns a value, we can optimize by removing the function +# wrapper and just returning the value directly. +unwrap = /function\s*\(\)\s*\{\s*return\s*([\s\S]*);\s*\}/ + +# Our handy DSL for Jison grammar generation, thanks to +# [Tim Caswell](http://github.com/creationix). For every rule in the grammar, +# we pass the pattern-defining string, the action to run, and extra options, +# optionally. If no action is specified, we simply pass the value of the +# previous nonterminal. +o = (patternString, action, options) -> + return [patternString, '$$ = $1;', options] unless action + action = if match = (action + '').match(unwrap) then match[1] else "(#{action}())" + action = action.replace(/\bnew (\w+)\b/g, 'new yy.$1').replace(/Expressions\.wrap/g, 'yy.Expressions.wrap'); + [patternString, "$$ = #{action};", options] + +# Grammatical Rules +# ----------------- + +# In all of the rules that follow, you'll see the name of the nonterminal as +# the key to a list of alternative matches. With each match's action, the +# dollar-sign variables are provided by Jison as references to the value of +# their numeric position, so in this rule: +# +# "Expression UNLESS Expression" +# +# `$1` would be the value of the first `Expression`, `$2` would be the token +# for the `UNLESS` terminal, and `$3` would be the value of the second +# `Expression`. +grammar = + + # The **Root** is the top-level node in the syntax tree. Since we parse bottom-up, + # all parsing must end here. + Root: [ + o "", -> new Expressions + o "TERMINATOR", -> new Expressions + o "Body" + o "Block TERMINATOR" + ] + + # Any list of statements and expressions, seperated by line breaks or semicolons. + Body: [ + o "Line", -> Expressions.wrap [$1] + o "Body TERMINATOR Line", -> $1.push $3 + o "Body TERMINATOR" + ] + + # Expressions and statements, which make up a line in a body. + Line: [ + o "Expression" + o "Statement" + ] + + # Pure statements which cannot be expressions. + Statement: [ + o "Return" + o "Throw" + o "BREAK", -> new Literal $1 + o "CONTINUE", -> new Literal $1 + o "DEBUGGER", -> new Literal $1 + ] + + # All the different types of expressions in our language. The basic unit of + # CoffeeScript is the **Expression** -- everything that can be an expression + # is one. Expressions serve as the building blocks of many other rules, making + # them somewhat circular. + Expression: [ + o "Value" + o "Invocation" + o "Code" + o "Operation" + o "Assign" + o "If" + o "Try" + o "While" + o "For" + o "Switch" + o "Extends" + o "Class" + o "Existence" + o "Comment" + ] + + # An indented block of expressions. Note that the [Rewriter](rewriter.html) + # will convert some postfix forms into blocks for us, by adjusting the + # token stream. + Block: [ + o "INDENT Body OUTDENT", -> $2 + o "INDENT OUTDENT", -> new Expressions + o "TERMINATOR Comment", -> Expressions.wrap [$2] + ] + + # A literal identifier, a variable name or property. + Identifier: [ + o "IDENTIFIER", -> new Literal $1 + ] + + # Alphanumerics are separated from the other **Literal** matchers because + # they can also serve as keys in object literals. + AlphaNumeric: [ + o "NUMBER", -> new Literal $1 + o "STRING", -> new Literal $1 + ] + + # All of our immediate values. These can (in general), be passed straight + # through and printed to JavaScript. + Literal: [ + o "AlphaNumeric" + o "JS", -> new Literal $1 + o "REGEX", -> new Literal $1 + o "BOOL", -> new Literal $1 + ] + + # Assignment of a variable, property, or index to a value. + Assign: [ + o "Assignable = Expression", -> new Assign $1, $3 + o "Assignable = INDENT Expression OUTDENT", -> new Assign $1, $4 + ] + + # Assignment when it happens within an object literal. The difference from + # the ordinary **Assign** is that these allow numbers and strings as keys. + AssignObj: [ + o "Identifier", -> new Value $1 + o "AlphaNumeric" + o "ThisProperty" + o "Identifier : Expression", -> new Assign new Value($1), $3, 'object' + o "AlphaNumeric : Expression", -> new Assign new Value($1), $3, 'object' + o "Identifier : INDENT Expression OUTDENT", -> new Assign new Value($1), $4, 'object' + o "AlphaNumeric : INDENT Expression OUTDENT", -> new Assign new Value($1), $4, 'object' + o "Comment" + ] + + # A return statement from a function body. + Return: [ + o "RETURN Expression", -> new Return $2 + o "RETURN", -> new Return + ] + + # A block comment. + Comment: [ + o "HERECOMMENT", -> new Comment $1 + ] + + # [The existential operator](http://jashkenas.github.com/coffee-script/#existence). + Existence: [ + o "Expression ?", -> new Existence $1 + ] + + # The **Code** node is the function literal. It's defined by an indented block + # of **Expressions** preceded by a function arrow, with an optional parameter + # list. + Code: [ + o "PARAM_START ParamList PARAM_END FuncGlyph Block", -> new Code $2, $5, $4 + o "FuncGlyph Block", -> new Code [], $2, $1 + ] + + # CoffeeScript has two different symbols for functions. `->` is for ordinary + # functions, and `=>` is for functions bound to the current value of *this*. + FuncGlyph: [ + o "->", -> 'func' + o "=>", -> 'boundfunc' + ] + + # An optional, trailing comma. + OptComma: [ + o '' + o ',' + ] + + # The list of parameters that a function accepts can be of any length. + ParamList: [ + o "", -> [] + o "Param", -> [$1] + o "ParamList , Param", -> $1.concat $3 + ] + + # A single parameter in a function definition can be ordinary, or a splat + # that hoovers up the remaining arguments. + Param: [ + o "PARAM", -> new Literal $1 + o "@ PARAM", -> new Param $2, true + o "PARAM ...", -> new Param $1, false, true + o "@ PARAM ...", -> new Param $2, true, true + ] + + # A splat that occurs outside of a parameter list. + Splat: [ + o "Expression ...", -> new Splat $1 + ] + + # Variables and properties that can be assigned to. + SimpleAssignable: [ + o "Identifier", -> new Value $1 + o "Value Accessor", -> $1.push $2 + o "Invocation Accessor", -> new Value $1, [$2] + o "ThisProperty" + ] + + # Everything that can be assigned to. + Assignable: [ + o "SimpleAssignable" + o "Array", -> new Value $1 + o "Object", -> new Value $1 + ] + + # The types of things that can be treated as values -- assigned to, invoked + # as functions, indexed into, named as a class, etc. + Value: [ + o "Assignable" + o "Literal", -> new Value $1 + o "Parenthetical", -> new Value $1 + o "Range", -> new Value $1 + o "This" + ] + + # The general group of accessors into an object, by property, by prototype + # or by array index or slice. + Accessor: [ + o "PROPERTY_ACCESS Identifier", -> new Accessor $2 + o "PROTOTYPE_ACCESS Identifier", -> new Accessor $2, 'prototype' + o "::", -> new Accessor(new Literal('prototype')) + o "SOAK_ACCESS Identifier", -> new Accessor $2, 'soak' + o "Index" + o "Slice", -> new Slice $1 + ] + + # Indexing into an object or array using bracket notation. + Index: [ + o "INDEX_START Expression INDEX_END", -> new Index $2 + o "INDEX_SOAK Index", -> $2.soakNode = yes; $2 + o "INDEX_PROTO Index", -> $2.proto = yes; $2 + ] + + # In CoffeeScript, an object literal is simply a list of assignments. + Object: [ + o "{ AssignList OptComma }", -> new ObjectLiteral $2 + ] + + # Assignment of properties within an object literal can be separated by + # comma, as in JavaScript, or simply by newline. + AssignList: [ + o "", -> [] + o "AssignObj", -> [$1] + o "AssignList , AssignObj", -> $1.concat $3 + o "AssignList OptComma TERMINATOR AssignObj", -> $1.concat $4 + o "AssignList OptComma INDENT AssignList OptComma OUTDENT", -> $1.concat $4 + ] + + # Class definitions have optional bodies of prototype property assignments, + # and optional references to the superclass. + Class: [ + o "CLASS SimpleAssignable", -> new Class $2 + o "CLASS SimpleAssignable EXTENDS Value", -> new Class $2, $4 + o "CLASS SimpleAssignable INDENT ClassBody OUTDENT", -> new Class $2, null, $4 + o "CLASS SimpleAssignable EXTENDS Value INDENT ClassBody OUTDENT", -> new Class $2, $4, $6 + o "CLASS INDENT ClassBody OUTDENT", -> new Class '__temp__', null, $3 + o "CLASS", -> new Class '__temp__', null, new Expressions + o "CLASS EXTENDS Value", -> new Class '__temp__', $3, new Expressions + o "CLASS EXTENDS Value INDENT ClassBody OUTDENT", -> new Class '__temp__', $3, $5 + ] + + # Assignments that can happen directly inside a class declaration. + ClassAssign: [ + o "AssignObj", -> $1 + o "ThisProperty : Expression", -> new Assign new Value($1), $3, 'this' + o "ThisProperty : INDENT Expression OUTDENT", -> new Assign new Value($1), $4, 'this' + ] + + # A list of assignments to a class. + ClassBody: [ + o "", -> [] + o "ClassAssign", -> [$1] + o "ClassBody TERMINATOR ClassAssign", -> $1.concat $3 + o "{ ClassBody }", -> $2 + ] + + # Extending an object by setting its prototype chain to reference a parent + # object. + Extends: [ + o "SimpleAssignable EXTENDS Value", -> new Extends $1, $3 + ] + + # Ordinary function invocation, or a chained series of calls. + Invocation: [ + o "Value OptFuncExist Arguments", -> new Call $1, $3, $2 + o "Invocation OptFuncExist Arguments", -> new Call $1, $3, $2 + o "SUPER", -> new Call 'super', [new Splat(new Literal('arguments'))] + o "SUPER Arguments", -> new Call 'super', $2 + ] + + # An optional existence check on a function. + OptFuncExist: [ + o "", -> no + o "FUNC_EXIST", -> yes + ] + + # The list of arguments to a function call. + Arguments: [ + o "CALL_START CALL_END", -> [] + o "CALL_START ArgList OptComma CALL_END", -> $2 + ] + + # A reference to the *this* current object. + This: [ + o "THIS", -> new Value new Literal 'this' + o "@", -> new Value new Literal 'this' + ] + + RangeDots: [ + o "..", -> 'inclusive' + o "...", -> 'exclusive' + ] + + # A reference to a property on *this*. + ThisProperty: [ + o "@ Identifier", -> new Value new Literal('this'), [new Accessor($2)], 'this' + ] + + # The CoffeeScript range literal. + Range: [ + o "[ Expression RangeDots Expression ]", -> new Range $2, $4, $3 + ] + + # The slice literal. + Slice: [ + o "INDEX_START Expression RangeDots Expression INDEX_END", -> new Range $2, $4, $3 + o "INDEX_START Expression RangeDots INDEX_END", -> new Range $2, null, $3 + o "INDEX_START RangeDots Expression INDEX_END", -> new Range null, $3, $2 + ] + + # The array literal. + Array: [ + o "[ ]", -> new ArrayLiteral [] + o "[ ArgList OptComma ]", -> new ArrayLiteral $2 + ] + + # The **ArgList** is both the list of objects passed into a function call, + # as well as the contents of an array literal + # (i.e. comma-separated expressions). Newlines work as well. + ArgList: [ + o "Arg", -> [$1] + o "ArgList , Arg", -> $1.concat $3 + o "ArgList OptComma TERMINATOR Arg", -> $1.concat $4 + o "INDENT ArgList OptComma OUTDENT", -> $2 + o "ArgList OptComma INDENT ArgList OptComma OUTDENT", -> $1.concat $4 + ] + + # Valid arguments are Expressions or Splats. + Arg: [ + o "Expression" + o "Splat" + ] + + # Just simple, comma-separated, required arguments (no fancy syntax). We need + # this to be separate from the **ArgList** for use in **Switch** blocks, where + # having the newlines wouldn't make sense. + SimpleArgs: [ + o "Expression" + o "SimpleArgs , Expression", -> [].concat $1, $3 + ] + + # The variants of *try/catch/finally* exception handling blocks. + Try: [ + o "TRY Block", -> new Try $2 + o "TRY Block Catch", -> new Try $2, $3[0], $3[1] + o "TRY Block FINALLY Block", -> new Try $2, null, null, $4 + o "TRY Block Catch FINALLY Block", -> new Try $2, $3[0], $3[1], $5 + ] + + # A catch clause names its error and runs a block of code. + Catch: [ + o "CATCH Identifier Block", -> [$2, $3] + ] + + # Throw an exception object. + Throw: [ + o "THROW Expression", -> new Throw $2 + ] + + # Parenthetical expressions. Note that the **Parenthetical** is a **Value**, + # not an **Expression**, so if you need to use an expression in a place + # where only values are accepted, wrapping it in parentheses will always do + # the trick. + Parenthetical: [ + o "( Expression )", -> new Parens $2 + o "( )", -> new Parens new Literal '' + ] + + # The condition portion of a while loop. + WhileSource: [ + o "WHILE Expression", -> new While $2 + o "WHILE Expression WHEN Expression", -> new While $2, guard: $4 + o "UNTIL Expression", -> new While $2, invert: true + o "UNTIL Expression WHEN Expression", -> new While $2, invert: true, guard: $4 + ] + + # The while loop can either be normal, with a block of expressions to execute, + # or postfix, with a single expression. There is no do..while. + While: [ + o "WhileSource Block", -> $1.addBody $2 + o "Statement WhileSource", -> $2.addBody Expressions.wrap [$1] + o "Expression WhileSource", -> $2.addBody Expressions.wrap [$1] + o "Loop", -> $1 + ] + + Loop: [ + o "LOOP Block", -> new While(new Literal 'true').addBody $2 + o "LOOP Expression", -> new While(new Literal 'true').addBody Expressions.wrap [$2] + ] + + # Array, object, and range comprehensions, at the most generic level. + # Comprehensions can either be normal, with a block of expressions to execute, + # or postfix, with a single expression. + For: [ + o "Statement ForBody", -> new For $1, $2, $2.vars[0], $2.vars[1] + o "Expression ForBody", -> new For $1, $2, $2.vars[0], $2.vars[1] + o "ForBody Block", -> new For $2, $1, $1.vars[0], $1.vars[1] + ] + + ForBody: [ + o "FOR Range", -> source: new Value($2), vars: [] + o "ForStart ForSource", -> $2.raw = $1.raw; $2.vars = $1; $2 + ] + + ForStart: [ + o "FOR ForVariables", -> $2 + o "FOR ALL ForVariables", -> $3.raw = true; $3 + ] + + # An array of all accepted values for a variable inside the loop. This + # enables support for pattern matching. + ForValue: [ + o "Identifier" + o "Array", -> new Value $1 + o "Object", -> new Value $1 + ] + + # An array or range comprehension has variables for the current element and + # (optional) reference to the current index. Or, *key, value*, in the case + # of object comprehensions. + ForVariables: [ + o "ForValue", -> [$1] + o "ForValue , ForValue", -> [$1, $3] + ] + + # The source of a comprehension is an array or object with an optional guard + # clause. If it's an array comprehension, you can also choose to step through + # in fixed-size increments. + ForSource: [ + o "FORIN Expression", -> source: $2 + o "FOROF Expression", -> source: $2, object: true + o "FORIN Expression WHEN Expression", -> source: $2, guard: $4 + o "FOROF Expression WHEN Expression", -> source: $2, guard: $4, object: true + o "FORIN Expression BY Expression", -> source: $2, step: $4 + o "FORIN Expression WHEN Expression BY Expression", -> source: $2, guard: $4, step: $6 + o "FORIN Expression BY Expression WHEN Expression", -> source: $2, step: $4, guard: $6 + ] + + Switch: [ + o "SWITCH Expression INDENT Whens OUTDENT", -> new Switch $2, $4 + o "SWITCH Expression INDENT Whens ELSE Block OUTDENT", -> new Switch $2, $4, $6 + o "SWITCH INDENT Whens OUTDENT", -> new Switch null, $3 + o "SWITCH INDENT Whens ELSE Block OUTDENT", -> new Switch null, $3, $5 + ] + + Whens: [ + o "When" + o "Whens When", -> $1.concat $2 + ] + + # An individual **When** clause, with action. + When: [ + o "LEADING_WHEN SimpleArgs Block", -> [[$2, $3]] + o "LEADING_WHEN SimpleArgs Block TERMINATOR", -> [[$2, $3]] + ] + + # The most basic form of *if* is a condition and an action. The following + # if-related rules are broken up along these lines in order to avoid + # ambiguity. + IfBlock: [ + o "IF Expression Block", -> new If $2, $3 + o "UNLESS Expression Block", -> new If $2, $3, invert: true + o "IfBlock ELSE IF Expression Block", -> $1.addElse new If $4, $5 + o "IfBlock ELSE Block", -> $1.addElse $3 + ] + + # The full complement of *if* expressions, including postfix one-liner + # *if* and *unless*. + If: [ + o "IfBlock" + o "Statement POST_IF Expression", -> new If $3, Expressions.wrap([$1]), statement: true + o "Expression POST_IF Expression", -> new If $3, Expressions.wrap([$1]), statement: true + o "Statement POST_UNLESS Expression", -> new If $3, Expressions.wrap([$1]), statement: true, invert: true + o "Expression POST_UNLESS Expression", -> new If $3, Expressions.wrap([$1]), statement: true, invert: true + ] + + # Arithmetic and logical operators, working on one or more operands. + # Here they are grouped by order of precedence. The actual precedence rules + # are defined at the bottom of the page. It would be shorter if we could + # combine most of these rules into a single generic *Operand OpSymbol Operand* + # -type rule, but in order to make the precedence binding possible, separate + # rules are necessary. + Operation: [ + o "UNARY Expression", -> new Op $1, $2 + o "- Expression", (-> new Op '-', $2), prec: 'UNARY' + o "+ Expression", (-> new Op '+', $2), prec: 'UNARY' + + o "-- SimpleAssignable", -> new Op '--', $2 + o "++ SimpleAssignable", -> new Op '++', $2 + o "SimpleAssignable --", -> new Op '--', $1, null, true + o "SimpleAssignable ++", -> new Op '++', $1, null, true + + o "Expression + Expression", -> new Op '+', $1, $3 + o "Expression - Expression", -> new Op '-', $1, $3 + o "Expression == Expression", -> new Op '==', $1, $3 + o "Expression != Expression", -> new Op '!=', $1, $3 + + o "Expression MATH Expression", -> new Op $2, $1, $3 + o "Expression SHIFT Expression", -> new Op $2, $1, $3 + o "Expression COMPARE Expression", -> new Op $2, $1, $3 + o "Expression LOGIC Expression", -> new Op $2, $1, $3 + o "SimpleAssignable COMPOUND_ASSIGN Expression", -> new Op $2, $1, $3 + o "SimpleAssignable COMPOUND_ASSIGN INDENT Expression OUTDENT", -> new Op $2, $1, $4 + + o "Expression RELATION Expression", -> + if $2.charAt(0) is '!' + if $2 is '!in' + new Op '!', new In $1, $3 + else + new Op '!', new Parens new Op $2.slice(1), $1, $3 + else + if $2 is 'in' then new In $1, $3 else new Op $2, $1, $3 + ] + + +# Precedence +# ---------- + +# Operators at the top of this list have higher precedence than the ones lower +# down. Following these rules is what makes `2 + 3 * 4` parse as: +# +# 2 + (3 * 4) +# +# And not: +# +# (2 + 3) * 4 +operators = [ + ["left", 'CALL_START', 'CALL_END'] + ["nonassoc", '++', '--'] + ["left", '?'] + ["right", 'UNARY'] + ["left", 'MATH'] + ["left", '+', '-'] + ["left", 'SHIFT'] + ["left", 'COMPARE'] + ["left", 'RELATION'] + ["left", '==', '!='] + ["left", 'LOGIC'] + ["right", 'COMPOUND_ASSIGN'] + ["left", '.'] + ["nonassoc", 'INDENT', 'OUTDENT'] + ["right", 'WHEN', 'LEADING_WHEN', 'FORIN', 'FOROF', 'BY', 'THROW'] + ["right", 'IF', 'UNLESS', 'ELSE', 'FOR', 'WHILE', 'UNTIL', 'LOOP', 'SUPER', 'CLASS', 'EXTENDS'] + ["right", '=', ':', 'RETURN'] + ["right", '->', '=>', 'UNLESS', 'POST_IF', 'POST_UNLESS'] +] + +# Wrapping Up +# ----------- + +# Finally, now what we have our **grammar** and our **operators**, we can create +# our **Jison.Parser**. We do this by processing all of our rules, recording all +# terminals (every symbol which does not appear as the name of a rule above) +# as "tokens". +tokens = [] +for name, alternatives of grammar + grammar[name] = for alt in alternatives + for token in alt[0].split ' ' + tokens.push token unless grammar[token] + alt[1] = "return #{alt[1]}" if name is 'Root' + alt + +# Initialize the **Parser** with our list of terminal **tokens**, our **grammar** +# rules, and the name of the root. Reverse the operators because Jison orders +# precedence from low to high, and we have it high to low +# (as in [Yacc](http://dinosaur.compilertools.net/yacc/index.html)). +exports.parser = new Parser + tokens: tokens.join ' ' + bnf: grammar + operators: operators.reverse() + startSymbol: 'Root' diff --git a/node_modules/jade/support/coffee-script/src/helpers.coffee b/node_modules/jade/support/coffee-script/src/helpers.coffee new file mode 100644 index 0000000..4d201de --- /dev/null +++ b/node_modules/jade/support/coffee-script/src/helpers.coffee @@ -0,0 +1,72 @@ +# This file contains the common helper functions that we'd like to share among +# the **Lexer**, **Rewriter**, and the **Nodes**. Merge objects, flatten +# arrays, count characters, that sort of thing. + +# Cross-engine `indexOf`, so that JScript can join the party. Use SpiderMonkey's +# functional-style `indexOf`, if it's available. +indexOf = exports.indexOf = Array.indexOf or + if Array::indexOf + (array, item, from) -> array.indexOf item, from + else + (array, item, from) -> + for other, index in array + if other is item and (not from or from <= index) + return index + -1 + +# Does a list include a value? +exports.include = (list, value) -> + indexOf(list, value) >= 0 + +# Peek at the beginning of a given string to see if it matches a sequence. +exports.starts = (string, literal, start) -> + literal is string.substr start, literal.length + +# Peek at the end of a given string to see if it matches a sequence. +exports.ends = (string, literal, back) -> + len = literal.length + literal is string.substr string.length - len - (back or 0), len + +# Trim out all falsy values from an array. +exports.compact = (array) -> + item for item in array when item + +# Count the number of occurences of a character in a string. +exports.count = (string, letter) -> + num = pos = 0 + num++ while pos = 1 + string.indexOf letter, pos + num + +# Merge objects, returning a fresh copy with attributes from both sides. +# Used every time `Base#compile` is called, to allow properties in the +# options hash to propagate down the tree without polluting other branches. +exports.merge = (options, overrides) -> + extend (extend {}, options), overrides + +# Extend a source object with the properties of another object (shallow copy). +# We use this to simulate Node's deprecated `process.mixin`. +extend = exports.extend = (object, properties) -> + for all key, val of properties + object[key] = val + object + +# Return a flattened version of an array. +# Handy for getting a list of `children` from the nodes. +exports.flatten = flatten = (array) -> + flattened = [] + for element in array + if element instanceof Array + flattened = flattened.concat flatten element + else + flattened.push element + flattened + +# Delete a key from an object, returning the value. Useful when a node is +# looking for a particular method in an options hash. +exports.del = (obj, key) -> + val = obj[key] + delete obj[key] + val + +# Gets the last item of an array(-like) object. +exports.last = (array, back) -> array[array.length - (back or 0) - 1] diff --git a/node_modules/jade/support/coffee-script/src/index.coffee b/node_modules/jade/support/coffee-script/src/index.coffee new file mode 100644 index 0000000..220f4e2 --- /dev/null +++ b/node_modules/jade/support/coffee-script/src/index.coffee @@ -0,0 +1,2 @@ +# Loader for CoffeeScript as a Node.js library. +(exports[key] = val) for key, val of require './coffee-script' \ No newline at end of file diff --git a/node_modules/jade/support/coffee-script/src/lexer.coffee b/node_modules/jade/support/coffee-script/src/lexer.coffee new file mode 100644 index 0000000..0362eeb --- /dev/null +++ b/node_modules/jade/support/coffee-script/src/lexer.coffee @@ -0,0 +1,635 @@ +# The CoffeeScript Lexer. Uses a series of token-matching regexes to attempt +# matches against the beginning of the source code. When a match is found, +# a token is produced, we consume the match, and start again. Tokens are in the +# form: +# +# [tag, value, lineNumber] +# +# Which is a format that can be fed directly into [Jison](http://github.com/zaach/jison). + +{Rewriter} = require './rewriter' + +# Import the helpers we need. +{include, count, starts, compact, last} = require './helpers' + +# The Lexer Class +# --------------- + +# The Lexer class reads a stream of CoffeeScript and divvys it up into tagged +# tokens. Some potential ambiguity in the grammar has been avoided by +# pushing some extra smarts into the Lexer. +exports.Lexer = class Lexer + + # **tokenize** is the Lexer's main method. Scan by attempting to match tokens + # one at a time, using a regular expression anchored at the start of the + # remaining code, or a custom recursive token-matching method + # (for interpolations). When the next token has been recorded, we move forward + # within the code past the token, and begin again. + # + # Each tokenizing method is responsible for incrementing `@i` by the number of + # characters it has consumed. `@i` can be thought of as our finger on the page + # of source. + # + # Before returning the token stream, run it through the [Rewriter](rewriter.html) + # unless explicitly asked not to. + tokenize: (code, options) -> + code = code.replace(/\r/g, '').replace TRAILING_SPACES, '' + o = options or {} + @code = code # The remainder of the source code. + @i = 0 # Current character position we're parsing. + @line = o.line or 0 # The current line. + @indent = 0 # The current indentation level. + @indebt = 0 # The over-indentation at the current level. + @outdebt = 0 # The under-outdentation at the current level. + @seenFor = no # The flag for distinguishing FORIN/FOROF from IN/OF. + @indents = [] # The stack of all current indentation levels. + @tokens = [] # Stream of parsed tokens in the form ['TYPE', value, line] + # At every position, run through this list of attempted matches, + # short-circuiting if any of them succeed. Their order determines precedence: + # `@literalToken` is the fallback catch-all. + while @chunk = code.slice @i + @identifierToken() or + @commentToken() or + @whitespaceToken() or + @lineToken() or + @heredocToken() or + @stringToken() or + @numberToken() or + @regexToken() or + @jsToken() or + @literalToken() + @closeIndentation() + return @tokens if o.rewrite is off + (new Rewriter).rewrite @tokens + + # Tokenizers + # ---------- + + # Matches identifying literals: variables, keywords, method names, etc. + # Check to ensure that JavaScript reserved words aren't being used as + # identifiers. Because CoffeeScript reserves a handful of keywords that are + # allowed in JavaScript, we're careful not to tag them as keywords when + # referenced as property names here, so you can still do `jQuery.is()` even + # though `is` means `===` otherwise. + identifierToken: -> + return false unless match = IDENTIFIER.exec @chunk + [input, id, colon] = match + @i += input.length + if id is 'all' and @tag() is 'FOR' + @token 'ALL', id + return true + forcedIdentifier = colon or @tagAccessor() + tag = 'IDENTIFIER' + if include(JS_KEYWORDS, id) or + not forcedIdentifier and include(COFFEE_KEYWORDS, id) + tag = id.toUpperCase() + if tag is 'WHEN' and include LINE_BREAK, @tag() + tag = 'LEADING_WHEN' + else if tag is 'FOR' + @seenFor = yes + else if include UNARY, tag + tag = 'UNARY' + else if include RELATION, tag + if tag isnt 'INSTANCEOF' and @seenFor + @seenFor = no + tag = 'FOR' + tag + else + tag = 'RELATION' + if @value() is '!' + @tokens.pop() + id = '!' + id + if include JS_FORBIDDEN, id + if forcedIdentifier + tag = 'IDENTIFIER' + id = new String id + id.reserved = yes + else if include RESERVED, id + @identifierError id + unless forcedIdentifier + tag = id = COFFEE_ALIASES[id] if COFFEE_ALIASES.hasOwnProperty id + if id is '!' + tag = 'UNARY' + else if include LOGIC, id + tag = 'LOGIC' + else if include BOOL, tag + id = tag.toLowerCase() + tag = 'BOOL' + @token tag, id + @token ':', ':' if colon + true + + # Matches numbers, including decimals, hex, and exponential notation. + # Be careful not to interfere with ranges-in-progress. + numberToken: -> + return false unless match = NUMBER.exec @chunk + number = match[0] + return false if @tag() is '.' and number.charAt(0) is '.' + @i += number.length + @token 'NUMBER', number + true + + # Matches strings, including multi-line strings. Ensures that quotation marks + # are balanced within the string's contents, and within nested interpolations. + stringToken: -> + switch @chunk.charAt 0 + when "'" + return false unless match = SIMPLESTR.exec @chunk + @token 'STRING', (string = match[0]).replace MULTILINER, '\\\n' + when '"' + return false unless string = @balancedString @chunk, [['"', '"'], ['#{', '}']] + if 0 < string.indexOf '#{', 1 + @interpolateString string.slice 1, -1 + else + @token 'STRING', @escapeLines string + else + return false + @line += count string, '\n' + @i += string.length + true + + # Matches heredocs, adjusting indentation to the correct level, as heredocs + # preserve whitespace, but ignore indentation to the left. + heredocToken: -> + return false unless match = HEREDOC.exec @chunk + heredoc = match[0] + quote = heredoc.charAt 0 + doc = @sanitizeHeredoc match[2], {quote, indent: null} + if quote is '"' and 0 <= doc.indexOf '#{' + @interpolateString doc, heredoc: yes + else + @token 'STRING', @makeString doc, quote, yes + @line += count heredoc, '\n' + @i += heredoc.length + true + + # Matches and consumes comments. + commentToken: -> + return false unless match = @chunk.match COMMENT + [comment, here] = match + @line += count comment, '\n' + @i += comment.length + if here + @token 'HERECOMMENT', @sanitizeHeredoc here, + herecomment: true, indent: Array(@indent + 1).join(' ') + @token 'TERMINATOR', '\n' + true + + # Matches JavaScript interpolated directly into the source via backticks. + jsToken: -> + return false unless @chunk.charAt(0) is '`' and match = JSTOKEN.exec @chunk + @token 'JS', (script = match[0]).slice 1, -1 + @i += script.length + true + + # Matches regular expression literals. Lexing regular expressions is difficult + # to distinguish from division, so we borrow some basic heuristics from + # JavaScript and Ruby. + regexToken: -> + return false if @chunk.charAt(0) isnt '/' + return @heregexToken match if match = HEREGEX.exec @chunk + return false if include NOT_REGEX, @tag() + return false unless match = REGEX.exec @chunk + [regex] = match + @token 'REGEX', if regex is '//' then '/(?:)/' else regex + @i += regex.length + true + + # Matches experimental, multiline and extended regular expression literals. + heregexToken: (match) -> + [heregex, body, flags] = match + @i += heregex.length + if 0 > body.indexOf '#{' + re = body.replace(HEREGEX_OMIT, '').replace(/\//g, '\\/') + @token 'REGEX', "/#{ re or '(?:)' }/#{flags}" + return true + @token 'IDENTIFIER', 'RegExp' + @tokens.push ['CALL_START', '('] + tokens = [] + for [tag, value] in @interpolateString(body, regex: yes) + if tag is 'TOKENS' + tokens.push value... + else + continue unless value = value.replace HEREGEX_OMIT, '' + value = value.replace /\\/g, '\\\\' + tokens.push ['STRING', @makeString(value, '"', yes)] + tokens.push ['+', '+'] + tokens.pop() + @tokens.push ['STRING', '""'], ['+', '+'] unless tokens[0]?[0] is 'STRING' + @tokens.push tokens... + @tokens.push [',', ','], ['STRING', '"' + flags + '"'] if flags + @token ')', ')' + true + + # Matches newlines, indents, and outdents, and determines which is which. + # If we can detect that the current line is continued onto the the next line, + # then the newline is suppressed: + # + # elements + # .each( ... ) + # .map( ... ) + # + # Keeps track of the level of indentation, because a single outdent token + # can close multiple indents, so we need to know how far in we happen to be. + lineToken: -> + return false unless match = MULTI_DENT.exec @chunk + indent = match[0] + @line += count indent, '\n' + @i += indent.length + prev = last @tokens, 1 + size = indent.length - 1 - indent.lastIndexOf '\n' + nextCharacter = NEXT_CHARACTER.exec(@chunk)[1] + noNewlines = (nextCharacter in ['.', ','] and not NEXT_ELLIPSIS.test(@chunk)) or @unfinished() + if size - @indebt is @indent + return @suppressNewlines() if noNewlines + return @newlineToken indent + else if size > @indent + if noNewlines + @indebt = size - @indent + return @suppressNewlines() + diff = size - @indent + @outdebt + @token 'INDENT', diff + @indents.push diff + @outdebt = @indebt = 0 + else + @indebt = 0 + @outdentToken @indent - size, noNewlines + @indent = size + true + + # Record an outdent token or multiple tokens, if we happen to be moving back + # inwards past several recorded indents. + outdentToken: (moveOut, noNewlines, close) -> + while moveOut > 0 + len = @indents.length - 1 + if @indents[len] is undefined + moveOut = 0 + else if @indents[len] is @outdebt + moveOut -= @outdebt + @outdebt = 0 + else if @indents[len] < @outdebt + @outdebt -= @indents[len] + moveOut -= @indents[len] + else + dent = @indents.pop() - @outdebt + moveOut -= dent + @outdebt = 0 + @token 'OUTDENT', dent + @outdebt -= moveOut if dent + @token 'TERMINATOR', '\n' unless @tag() is 'TERMINATOR' or noNewlines + true + + # Matches and consumes non-meaningful whitespace. Tag the previous token + # as being "spaced", because there are some cases where it makes a difference. + whitespaceToken: -> + return false unless match = WHITESPACE.exec @chunk + prev = last @tokens + prev.spaced = true if prev + @i += match[0].length + true + + # Generate a newline token. Consecutive newlines get merged together. + newlineToken: (newlines) -> + @token 'TERMINATOR', '\n' unless @tag() is 'TERMINATOR' + true + + # Use a `\` at a line-ending to suppress the newline. + # The slash is removed here once its job is done. + suppressNewlines: -> + @tokens.pop() if @value() is '\\' + true + + # We treat all other single characters as a token. Eg.: `( ) , . !` + # Multi-character operators are also literal tokens, so that Jison can assign + # the proper order of operations. There are some symbols that we tag specially + # here. `;` and newlines are both treated as a `TERMINATOR`, we distinguish + # parentheses that indicate a method call from regular parentheses, and so on. + literalToken: -> + if match = OPERATOR.exec @chunk + [value] = match + @tagParameters() if CODE.test value + else + value = @chunk.charAt 0 + @i += value.length + tag = value + prev = last @tokens + if value is '=' and prev + @assignmentError() if not prev[1].reserved and include JS_FORBIDDEN, prev[1] + if prev[1] in ['||', '&&'] + prev[0] = 'COMPOUND_ASSIGN' + prev[1] += '=' + return true + if ';' is value then tag = 'TERMINATOR' + else if include LOGIC , value then tag = 'LOGIC' + else if include MATH , value then tag = 'MATH' + else if include COMPARE , value then tag = 'COMPARE' + else if include COMPOUND_ASSIGN, value then tag = 'COMPOUND_ASSIGN' + else if include UNARY , value then tag = 'UNARY' + else if include SHIFT , value then tag = 'SHIFT' + else if value is '?' and prev?.spaced then tag = 'LOGIC' + else if prev and not prev.spaced + if value is '(' and include CALLABLE, prev[0] + prev[0] = 'FUNC_EXIST' if prev[0] is '?' + tag = 'CALL_START' + else if value is '[' and include INDEXABLE, prev[0] + tag = 'INDEX_START' + switch prev[0] + when '?' then prev[0] = 'INDEX_SOAK' + when '::' then prev[0] = 'INDEX_PROTO' + @token tag, value + true + + # Token Manipulators + # ------------------ + + # As we consume a new `IDENTIFIER`, look at the previous token to determine + # if it's a special kind of accessor. Return `true` if any type of accessor + # is the previous token. + tagAccessor: -> + return false if not (prev = last @tokens) or prev.spaced + if prev[1] is '::' + @tag 0, 'PROTOTYPE_ACCESS' + else if prev[1] is '.' and @value(1) isnt '.' + if @tag(1) is '?' + @tag 0, 'SOAK_ACCESS' + @tokens.splice(-2, 1) + else + @tag 0, 'PROPERTY_ACCESS' + else + return prev[0] is '@' + true + + # Sanitize a heredoc or herecomment by + # erasing all external indentation on the left-hand side. + sanitizeHeredoc: (doc, options) -> + {indent, herecomment} = options + return doc if herecomment and 0 > doc.indexOf '\n' + unless herecomment + while match = HEREDOC_INDENT.exec doc + attempt = match[1] + indent = attempt if indent is null or 0 < attempt.length < indent.length + doc = doc.replace /// \n #{indent} ///g, '\n' if indent + doc = doc.replace /^\n/, '' unless herecomment + doc + + # A source of ambiguity in our grammar used to be parameter lists in function + # definitions versus argument lists in function calls. Walk backwards, tagging + # parameters specially in order to make things easier for the parser. + tagParameters: -> + return if @tag() isnt ')' + i = @tokens.length + while tok = @tokens[--i] + switch tok[0] + when 'IDENTIFIER' then tok[0] = 'PARAM' + when ')' then tok[0] = 'PARAM_END' + when '(', 'CALL_START' then tok[0] = 'PARAM_START'; return true + true + + # Close up all remaining open blocks at the end of the file. + closeIndentation: -> + @outdentToken @indent + + # The error for when you try to use a forbidden word in JavaScript as + # an identifier. + identifierError: (word) -> + throw SyntaxError "Reserved word \"#{word}\" on line #{@line + 1}" + + # The error for when you try to assign to a reserved word in JavaScript, + # like "function" or "default". + assignmentError: -> + throw SyntaxError "Reserved word \"#{@value()}\" on line #{@line + 1} can't be assigned" + + # Matches a balanced group such as a single or double-quoted string. Pass in + # a series of delimiters, all of which must be nested correctly within the + # contents of the string. This method allows us to have strings within + # interpolations within strings, ad infinitum. + balancedString: (str, delimited, options) -> + options or= {} + levels = [] + i = 0 + slen = str.length + while i < slen + if levels.length and str.charAt(i) is '\\' + i += 1 + else + for pair in delimited + [open, close] = pair + if levels.length and starts(str, close, i) and last(levels) is pair + levels.pop() + i += close.length - 1 + i += 1 unless levels.length + break + if starts str, open, i + levels.push(pair) + i += open.length - 1 + break + break if not levels.length + i += 1 + if levels.length + throw SyntaxError "Unterminated #{levels.pop()[0]} starting on line #{@line + 1}" + if not i then false else str[0...i] + + # Expand variables and expressions inside double-quoted strings using + # Ruby-like notation for substitution of arbitrary expressions. + # + # "Hello #{name.capitalize()}." + # + # If it encounters an interpolation, this method will recursively create a + # new Lexer, tokenize the interpolated contents, and merge them into the + # token stream. + interpolateString: (str, options) -> + {heredoc, regex} = options or= {} + tokens = [] + pi = 0 + i = -1 + while letter = str.charAt i += 1 + if letter is '\\' + i += 1 + continue + unless letter is '#' and str.charAt(i+1) is '{' and + (expr = @balancedString str.slice(i+1), [['{', '}']]) + continue + tokens.push ['TO_BE_STRING', str.slice(pi, i)] if pi < i + inner = expr.slice(1, -1).replace(LEADING_SPACES, '').replace(TRAILING_SPACES, '') + if inner.length + nested = new Lexer().tokenize inner, line: @line, rewrite: off + nested.pop() + if nested.length > 1 + nested.unshift ['(', '('] + nested.push [')', ')'] + tokens.push ['TOKENS', nested] + i += expr.length + pi = i + 1 + tokens.push ['TO_BE_STRING', str.slice pi] if i > pi < str.length + return tokens if regex + return @token 'STRING', '""' unless tokens.length + tokens.unshift ['', ''] unless tokens[0][0] is 'TO_BE_STRING' + @token '(', '(' if interpolated = tokens.length > 1 + for [tag, value], i in tokens + @token '+', '+' if i + if tag is 'TOKENS' + @tokens.push value... + else + @token 'STRING', @makeString value, '"', heredoc + @token ')', ')' if interpolated + tokens + + # Helpers + # ------- + + # Add a token to the results, taking note of the line number. + token: (tag, value) -> + @tokens.push [tag, value, @line] + + # Peek at a tag/value in the current token stream. + tag : (index, tag) -> + (tok = last @tokens, index) and if tag? then tok[0] = tag else tok[0] + value: (index, val) -> + (tok = last @tokens, index) and if val? then tok[1] = val else tok[1] + + # Are we in the midst of an unfinished expression? + unfinished: -> + (prev = last @tokens, 1) and prev[0] isnt '.' and + (value = @value()) and not value.reserved and + NO_NEWLINE.test(value) and not CODE.test(value) and not ASSIGNED.test(@chunk) + + # Converts newlines for string literals. + escapeLines: (str, heredoc) -> + str.replace MULTILINER, if heredoc then '\\n' else '' + + # Constructs a string token by escaping quotes and newlines. + makeString: (body, quote, heredoc) -> + return quote + quote unless body + body = body.replace /\\([\s\S])/g, (match, contents) -> + if contents in ['\n', quote] then contents else match + body = body.replace /// #{quote} ///g, '\\$&' + quote + @escapeLines(body, heredoc) + quote + +# Constants +# --------- + +# Keywords that CoffeeScript shares in common with JavaScript. +JS_KEYWORDS = [ + 'true', 'false', 'null', 'this' + 'new', 'delete', 'typeof', 'in', 'instanceof' + 'return', 'throw', 'break', 'continue', 'debugger' + 'if', 'else', 'switch', 'for', 'while', 'try', 'catch', 'finally' + 'class', 'extends', 'super' +] + +# CoffeeScript-only keywords. +COFFEE_KEYWORDS = ['then', 'unless', 'until', 'loop', 'of', 'by', 'when'] +COFFEE_KEYWORDS.push op for all op of COFFEE_ALIASES = + and : '&&' + or : '||' + is : '==' + isnt : '!=' + not : '!' + yes : 'TRUE' + no : 'FALSE' + on : 'TRUE' + off : 'FALSE' + +# The list of keywords that are reserved by JavaScript, but not used, or are +# used by CoffeeScript internally. We throw an error when these are encountered, +# to avoid having a JavaScript error at runtime. +RESERVED = [ + 'case', 'default', 'do', 'function', 'var', 'void', 'with' + 'const', 'let', 'enum', 'export', 'import', 'native' + '__hasProp', '__extends', '__slice' +] + +# The superset of both JavaScript keywords and reserved words, none of which may +# be used as identifiers or properties. +JS_FORBIDDEN = JS_KEYWORDS.concat RESERVED + +# Token matching regexes. +IDENTIFIER = /// ^ + ( [$A-Za-z_][$\w]* ) + ( [^\n\S]* : (?!:) )? # Is this a property name? +/// +NUMBER = /^0x[\da-f]+|^(?:\d+(\.\d+)?|\.\d+)(?:e[+-]?\d+)?/i +HEREDOC = /^("""|''')([\s\S]*?)(?:\n[ \t]*)?\1/ +OPERATOR = /// ^ (?: -[-=>]? | \+[+=]? | \.\.\.? | [*&|/%=<>^:!?]+ ) /// +WHITESPACE = /^[ \t]+/ +COMMENT = /^###([^#][\s\S]*?)(?:###[ \t]*\n|(?:###)?$)|^(?:\s*#(?!##[^#]).*)+/ +CODE = /^[-=]>/ +MULTI_DENT = /^(?:\n[ \t]*)+/ +SIMPLESTR = /^'[^\\']*(?:\\.[^\\']*)*'/ +JSTOKEN = /^`[^\\`]*(?:\\.[^\\`]*)*`/ + +# Regex-matching-regexes. +REGEX = /// ^ + / (?! \s ) # disallow leading whitespace + [^ [ / \n \\ ]* # every other thing + (?: + (?: \\[\s\S] # anything escaped + | \[ # character class + [^ \] \n \\ ]* + (?: \\[\s\S] [^ \] \n \\ ]* )* + ] + ) [^ [ / \n \\ ]* + )* + / [imgy]{0,4} (?![A-Za-z]) +/// +HEREGEX = /^\/{3}([\s\S]+?)\/{3}([imgy]{0,4})(?![A-Za-z])/ +HEREGEX_OMIT = /\s+(?:#.*)?/g + +# Token cleaning regexes. +MULTILINER = /\n/g +HEREDOC_INDENT = /\n+([ \t]*)/g +ASSIGNED = /^\s*@?[$A-Za-z_][$\w]*[ \t]*?[:=][^:=>]/ +NEXT_CHARACTER = /^\s*(\S?)/ +NEXT_ELLIPSIS = /^\s*\.\.\.?/ +LEADING_SPACES = /^\s+/ +TRAILING_SPACES = /\s+$/ +NO_NEWLINE = /// ^ + (?: # non-capturing... + [-+*&|/%=<>!.\\][<>=&|]* | # symbol operators + and | or | is(?:nt)? | n(?:ot|ew) | # word operators + delete | typeof | instanceof + )$ +/// + + +# Compound assignment tokens. +COMPOUND_ASSIGN = ['-=', '+=', '/=', '*=', '%=', '||=', '&&=', '?=', '<<=', '>>=', '>>>=', '&=', '^=', '|='] + +# Unary tokens. +UNARY = ['UMINUS', 'UPLUS', '!', '!!', '~', 'NEW', 'TYPEOF', 'DELETE'] + +# Logical tokens. +LOGIC = ['&', '|', '^', '&&', '||'] + +# Bit-shifting tokens. +SHIFT = ['<<', '>>', '>>>'] + +# Comparison tokens. +COMPARE = ['<=', '<', '>', '>='] + +# Mathmatical tokens. +MATH = ['*', '/', '%'] + +# Relational tokens that are negatable with `not` prefix. +RELATION = ['IN', 'OF', 'INSTANCEOF'] + +# Boolean tokens. +BOOL = ['TRUE', 'FALSE', 'NULL'] + +# Tokens which a regular expression will never immediately follow, but which +# a division operator might. +# +# See: http://www.mozilla.org/js/language/js20-2002-04/rationale/syntax.html#regular-expressions +# +# Our list is shorter, due to sans-parentheses method calls. +NOT_REGEX = ['NUMBER', 'REGEX', 'BOOL', '++', '--', ']'] + +# Tokens which could legitimately be invoked or indexed. A opening +# parentheses or bracket following these tokens will be recorded as the start +# of a function invocation or indexing operation. +CALLABLE = ['IDENTIFIER', 'STRING', 'REGEX', ')', ']', '}', '?', '::', '@', 'THIS', 'SUPER'] +INDEXABLE = CALLABLE.concat 'NUMBER', 'BOOL' + +# Tokens that, when immediately preceding a `WHEN`, indicate that the `WHEN` +# occurs at the start of a line. We disambiguate these from trailing whens to +# avoid an ambiguity in the grammar. +LINE_BREAK = ['INDENT', 'OUTDENT', 'TERMINATOR'] diff --git a/node_modules/jade/support/coffee-script/src/nodes.coffee b/node_modules/jade/support/coffee-script/src/nodes.coffee new file mode 100644 index 0000000..99e372a --- /dev/null +++ b/node_modules/jade/support/coffee-script/src/nodes.coffee @@ -0,0 +1,1710 @@ +# `nodes.coffee` contains all of the node classes for the syntax tree. Most +# nodes are created as the result of actions in the [grammar](grammar.html), +# but some are created by other nodes as a method of code generation. To convert +# the syntax tree into a string of JavaScript code, call `compile()` on the root. + +{Scope} = require './scope' + +# Import the helpers we plan to use. +{compact, flatten, merge, del, include, starts, ends, last} = require './helpers' + +# Constant functions for nodes that don't need customization. +YES = -> yes +NO = -> no +THIS = -> this + +#### Base + +# The **Base** is the abstract base class for all nodes in the syntax tree. +# Each subclass implements the `compileNode` method, which performs the +# code generation for that node. To compile a node to JavaScript, +# call `compile` on it, which wraps `compileNode` in some generic extra smarts, +# to know when the generated code needs to be wrapped up in a closure. +# An options hash is passed and cloned throughout, containing information about +# the environment from higher in the tree (such as if a returned value is +# being requested by the surrounding function), information about the current +# scope, and indentation level. +exports.Base = class Base + + constructor: -> + @tags = {} + + # Common logic for determining whether to wrap this node in a closure before + # compiling it, or to compile directly. We need to wrap if this node is a + # *statement*, and it's not a *pureStatement*, and we're not at + # the top level of a block (which would be unnecessary), and we haven't + # already been asked to return the result (because statements know how to + # return results). + # + # If a Node is *topSensitive*, that means that it needs to compile differently + # depending on whether it's being used as part of a larger expression, or is a + # top-level statement within the function body. + compile: (o) -> + @options = if o then merge o else {} + @tab = o.indent + top = if @topSensitive() then @options.top else del @options, 'top' + closure = @isStatement(o) and not @isPureStatement() and not top and + not @options.asStatement and this not instanceof Comment + code = if closure then @compileClosure(@options) else @compileNode(@options) + code + + # Statements converted into expressions via closure-wrapping share a scope + # object with their parent closure, to preserve the expected lexical scope. + compileClosure: (o) -> + o.sharedScope = o.scope + throw new Error 'cannot include a pure statement in an expression.' if @containsPureStatement() + Closure.wrap(this).compile o + + # If the code generation wishes to use the result of a complex expression + # in multiple places, ensure that the expression is only ever evaluated once, + # by assigning it to a temporary variable. + compileReference: (o, options) -> + pair = unless @isComplex() + [this, this] + else + reference = new Literal o.scope.freeVariable 'ref' + compiled = new Assign reference, this + [compiled, reference] + (pair[i] = node.compile o) for node, i in pair if options?.precompile + pair + + # Convenience method to grab the current indentation level, plus tabbing in. + idt: (tabs) -> + idt = @tab or '' + num = (tabs or 0) + 1 + idt += TAB while num -= 1 + idt + + # Construct a node that returns the current node's result. + # Note that this is overridden for smarter behavior for + # many statement nodes (eg If, For)... + makeReturn: -> + new Return this + + # Does this node, or any of its children, contain a node of a certain kind? + # Recursively traverses down the *children* of the nodes, yielding to a block + # and returning true when the block finds a match. `contains` does not cross + # scope boundaries. + contains: (block) -> + contains = false + @traverseChildren false, (node) -> + if block(node) + contains = true + return false + contains + + # Is this node of a certain type, or does it contain the type? + containsType: (type) -> + this instanceof type or @contains (node) -> node instanceof type + + # Convenience for the most common use of contains. Does the node contain + # a pure statement? + containsPureStatement: -> + @isPureStatement() or @contains (node) -> node.isPureStatement() + + # Perform an in-order traversal of the AST. Crosses scope boundaries. + traverse: (block) -> @traverseChildren true, block + + # `toString` representation of the node, for inspecting the parse tree. + # This is what `coffee --nodes` prints out. + toString: (idt, override) -> + idt or= '' + children = (child.toString idt + TAB for child in @collectChildren()).join('') + klass = override or @constructor.name + if @soakNode then '?' else '' + '\n' + idt + klass + children + + eachChild: (func) -> + return unless @children + for attr in @children when this[attr] + for child in flatten [this[attr]] + return if func(child) is false + + collectChildren: -> + nodes = [] + @eachChild (node) -> nodes.push node + nodes + + traverseChildren: (crossScope, func) -> + @eachChild (child) -> + return false if func(child) is false + if crossScope or child not instanceof Code + child.traverseChildren crossScope, func + + invert: -> new Op '!', this + + # Default implementations of the common node properties and methods. Nodes + # will override these with custom logic, if needed. + children: [] + + unwrap : THIS + isStatement : NO + isPureStatement : NO + isComplex : YES + topSensitive : NO + unfoldSoak : NO + + # Is this node used to assign a certain variable? + assigns: NO + +#### Expressions + +# The expressions body is the list of expressions that forms the body of an +# indented block of code -- the implementation of a function, a clause in an +# `if`, `switch`, or `try`, and so on... +exports.Expressions = class Expressions extends Base + + children: ['expressions'] + isStatement: YES + + constructor: (nodes) -> + super() + @expressions = compact flatten nodes or [] + + # Tack an expression on to the end of this expression list. + push: (node) -> + @expressions.push(node) + this + + # Add an expression at the beginning of this expression list. + unshift: (node) -> + @expressions.unshift(node) + this + + # If this Expressions consists of just a single node, unwrap it by pulling + # it back out. + unwrap: -> + if @expressions.length is 1 then @expressions[0] else this + + # Is this an empty block of code? + empty: -> + @expressions.length is 0 + + # An Expressions node does not return its entire body, rather it + # ensures that the final expression is returned. + makeReturn: -> + end = @expressions[idx = @expressions.length - 1] + end = @expressions[idx -= 1] if end instanceof Comment + if end and end not instanceof Return + @expressions[idx] = end.makeReturn() + this + + # An **Expressions** is the only node that can serve as the root. + compile: (o) -> + o or= {} + if o.scope then super(o) else @compileRoot(o) + + compileNode: (o) -> + (@compileExpression node, merge o for node in @expressions).join '\n' + + # If we happen to be the top-level **Expressions**, wrap everything in + # a safety closure, unless requested not to. + # It would be better not to generate them in the first place, but for now, + # clean up obvious double-parentheses. + compileRoot: (o) -> + o.indent = @tab = if o.bare then '' else TAB + o.scope = new Scope null, this, null + code = @compileWithDeclarations o + code = code.replace TRAILING_WHITESPACE, '' + if o.bare then code else "(function() {\n#{code}\n}).call(this);\n" + + # Compile the expressions body for the contents of a function, with + # declarations of all inner variables pushed up to the top. + compileWithDeclarations: (o) -> + code = @compileNode(o) + if o.scope.hasAssignments this + code = "#{@tab}var #{ o.scope.compiledAssignments().replace /\n/g, '$&' + @tab };\n#{code}" + if not o.globals and o.scope.hasDeclarations this + code = "#{@tab}var #{o.scope.compiledDeclarations()};\n#{code}" + code + + # Compiles a single expression within the expressions body. If we need to + # return the result, and it's an expression, simply return it. If it's a + # statement, ask the statement to do so. + compileExpression: (node, o) -> + @tab = o.indent + node.tags.front = true + compiledNode = node.compile merge o, top: true + if node.isStatement(o) then compiledNode else "#{@idt()}#{compiledNode};" + +# Wrap up the given nodes as an **Expressions**, unless it already happens +# to be one. +Expressions.wrap = (nodes) -> + return nodes[0] if nodes.length is 1 and nodes[0] instanceof Expressions + new Expressions(nodes) + +#### Literal + +# Literals are static values that can be passed through directly into +# JavaScript without translation, such as: strings, numbers, +# `true`, `false`, `null`... +exports.Literal = class Literal extends Base + + constructor: (@value) -> + super() + + makeReturn: -> + if @isStatement() then this else super() + + # Break and continue must be treated as pure statements -- they lose their + # meaning when wrapped in a closure. + isStatement: -> + @value in ['break', 'continue', 'debugger'] + isPureStatement: Literal::isStatement + + isComplex: NO + + isReserved: -> + !!@value.reserved + + assigns: (name) -> name is @value + + compileNode: (o) -> + idt = if @isStatement(o) then @idt() else '' + end = if @isStatement(o) then ';' else '' + val = if @isReserved() then "\"#{@value}\"" else @value + idt + val + end + + toString: -> ' "' + @value + '"' + +#### Return + +# A `return` is a *pureStatement* -- wrapping it in a closure wouldn't +# make sense. +exports.Return = class Return extends Base + + isStatement: YES + isPureStatement: YES + children: ['expression'] + + constructor: (@expression) -> + super() + + makeReturn: THIS + + compile: (o) -> + expr = @expression?.makeReturn() + return expr.compile o if expr and (expr not instanceof Return) + super o + + compileNode: (o) -> + expr = '' + if @expression + o.asStatement = true if @expression.isStatement(o) + expr = ' ' + @expression.compile(o) + "#{@tab}return#{expr};" + +#### Value + +# A value, variable or literal or parenthesized, indexed or dotted into, +# or vanilla. +exports.Value = class Value extends Base + + children: ['base', 'properties'] + + # A **Value** has a base and a list of property accesses. + constructor: (@base, @properties, tag) -> + super() + @properties or= [] + @tags[tag] = yes if tag + + # Add a property access to the list. + push: (prop) -> + @properties.push(prop) + this + + hasProperties: -> + !!@properties.length + + # Some boolean checks for the benefit of other nodes. + + isArray: -> + @base instanceof ArrayLiteral and not @properties.length + + isObject: -> + @base instanceof ObjectLiteral and not @properties.length + + isSplice: -> + last(@properties) instanceof Slice + + isComplex: -> + @base.isComplex() or @hasProperties() + + assigns: (name) -> + not @properties.length and @base.assigns name + + makeReturn: -> + if @properties.length then super() else @base.makeReturn() + + + # The value can be unwrapped as its inner node, if there are no attached + # properties. + unwrap: -> + if @properties.length then this else @base + + # Values are considered to be statements if their base is a statement. + isStatement: (o) -> + @base.isStatement(o) and not @properties.length + + isSimpleNumber: -> + @base instanceof Literal and SIMPLENUM.test @base.value + + # A reference has base part (`this` value) and name part. + # We cache them separately for compiling complex expressions. + # `a()[b()] ?= c` -> `(_base = a())[_name = b()] ? _base[_name] = c` + cacheReference: (o) -> + name = last @properties + if not @base.isComplex() and @properties.length < 2 and + not name?.isComplex() + return [this, this] # `a` `a.b` + base = new Value @base, @properties.slice 0, -1 + if base.isComplex() # `a().b` + bref = new Literal o.scope.freeVariable 'base' + base = new Value new Parens new Assign bref, base + return [base, bref] unless name # `a()` + if name.isComplex() # `a[b()]` + nref = new Literal o.scope.freeVariable 'name' + name = new Index new Assign nref, name.index + nref = new Index nref + [base.push(name), new Value(bref or base.base, [nref or name])] + + # Override compile to unwrap the value when possible. + compile: (o) -> + @base.tags.front = @tags.front + if not o.top or @properties.length then super(o) else @base.compile(o) + + # We compile a value to JavaScript by compiling and joining each property. + # Things get much more insteresting if the chain of properties has *soak* + # operators `?.` interspersed. Then we have to take care not to accidentally + # evaluate a anything twice when building the soak chain. + compileNode: (o) -> + return ifn.compile o if ifn = @unfoldSoak o + props = @properties + @base.parenthetical = yes if @parenthetical and not props.length + code = @base.compile o + code = "(#{code})" if props[0] instanceof Accessor and @isSimpleNumber() + (code += prop.compile o) for prop in props + return code + + # Unfold a soak into an `If`: `a?.b` -> `a.b if a?` + unfoldSoak: (o) -> + if ifn = @base.unfoldSoak o + Array::push.apply ifn.body.properties, @properties + return ifn + for prop, i in @properties when prop.soakNode + prop.soakNode = off + fst = new Value @base, @properties.slice 0, i + snd = new Value @base, @properties.slice i + if fst.isComplex() + ref = new Literal o.scope.freeVariable 'ref' + fst = new Parens new Assign ref, fst + snd.base = ref + ifn = new If new Existence(fst), snd, soak: yes + return ifn + null + +#### Comment + +# CoffeeScript passes through block comments as JavaScript block comments +# at the same position. +exports.Comment = class Comment extends Base + + isStatement: YES + + constructor: (@comment) -> + super() + + makeReturn: THIS + + compileNode: (o) -> + @tab + '/*' + @comment.replace(/\n/g, '\n' + @tab) + '*/' + +#### Call + +# Node for a function invocation. Takes care of converting `super()` calls into +# calls against the prototype's function of the same name. +exports.Call = class Call extends Base + + children: ['variable', 'args'] + + constructor: (variable, @args, @soakNode) -> + super() + @isNew = false + @isSuper = variable is 'super' + @variable = if @isSuper then null else variable + @args or= [] + + compileSplatArguments: (o) -> + Splat.compileSplattedArray @args, o + + # Tag this invocation as creating a new instance. + newInstance: -> + @isNew = true + this + + prefix: -> + if @isNew then 'new ' else '' + + # Grab the reference to the superclass' implementation of the current method. + superReference: (o) -> + {method} = o.scope + throw Error "cannot call super outside of a function." unless method + {name} = method + throw Error "cannot call super on an anonymous function." unless name + if method.klass + "#{method.klass}.__super__.#{name}" + else + "#{name}.__super__.constructor" + + # Soaked chained invocations unfold into if/else ternary structures. + unfoldSoak: (o) -> + if @soakNode + if val = @variable + val = new Value val unless val instanceof Value + [left, rite] = val.cacheReference o + else + left = new Literal @superReference o + rite = new Value left + rite = new Call rite, @args + rite.isNew = @isNew + left = new Literal "typeof #{ left.compile o } === \"function\"" + ifn = new If left, new Value(rite), soak: yes + return ifn + call = this + list = [] + loop + if call.variable instanceof Call + list.push call + call = call.variable + continue + break unless call.variable instanceof Value + list.push call + break unless (call = call.variable.base) instanceof Call + for call in list.reverse() + if ifn + if call.variable instanceof Call + call.variable = ifn + else + call.variable.base = ifn + ifn = If.unfoldSoak o, call, 'variable' + ifn + + # Compile a vanilla function call. + compileNode: (o) -> + return ifn.compile o if ifn = @unfoldSoak o + @variable?.tags.front = @tags.front + for arg in @args when arg instanceof Splat + return @compileSplat o + args = ((arg.parenthetical = on) and arg.compile o for arg in @args).join ', ' + if @isSuper + @compileSuper args, o + else + "#{@prefix()}#{@variable.compile o}(#{args})" + + # `super()` is converted into a call against the superclass's implementation + # of the current function. + compileSuper: (args, o) -> + "#{@superReference(o)}.call(this#{ if args.length then ', ' else '' }#{args})" + + # If you call a function with a splat, it's converted into a JavaScript + # `.apply()` call to allow an array of arguments to be passed. + # If it's a constructor, then things get real tricky. We have to inject an + # inner constructor in order to be able to pass the varargs. + compileSplat: (o) -> + splatargs = @compileSplatArguments o + return "#{ @superReference o }.apply(this, #{splatargs})" if @isSuper + unless @isNew + base = new Value base unless (base = @variable) instanceof Value + if (name = base.properties.pop()) and base.isComplex() + ref = o.scope.freeVariable 'this' + fun = "(#{ref} = #{ base.compile o })#{ name.compile o }" + else + fun = ref = base.compile o + fun += name.compile o if name + return "#{fun}.apply(#{ref}, #{splatargs})" + idt = @idt 1 + """ + (function(func, args, ctor) { + #{idt}ctor.prototype = func.prototype; + #{idt}var child = new ctor, result = func.apply(child, args); + #{idt}return typeof result === "object" ? result : child; + #{@tab}})(#{ @variable.compile o }, #{splatargs}, function() {}) + """ + +#### Extends + +# Node to extend an object's prototype with an ancestor object. +# After `goog.inherits` from the +# [Closure Library](http://closure-library.googlecode.com/svn/docs/closureGoogBase.js.html). +exports.Extends = class Extends extends Base + + children: ['child', 'parent'] + + constructor: (@child, @parent) -> + super() + + # Hooks one constructor into another's prototype chain. + compileNode: (o) -> + ref = new Value new Literal utility 'extends' + (new Call ref, [@child, @parent]).compile o + +#### Accessor + +# A `.` accessor into a property of a value, or the `::` shorthand for +# an accessor into the object's prototype. +exports.Accessor = class Accessor extends Base + + children: ['name'] + + constructor: (@name, tag) -> + super() + @prototype = if tag is 'prototype' then '.prototype' else '' + @soakNode = tag is 'soak' + + compileNode: (o) -> + name = @name.compile o + namePart = if name.match(IS_STRING) then "[#{name}]" else ".#{name}" + @prototype + namePart + + isComplex: NO + +#### Index + +# A `[ ... ]` indexed accessor into an array or object. +exports.Index = class Index extends Base + + children: ['index'] + + constructor: (@index) -> + super() + + compileNode: (o) -> + idx = @index.compile o + prefix = if @proto then '.prototype' else '' + "#{prefix}[#{idx}]" + + isComplex: -> @index.isComplex() + +#### Range + +# A range literal. Ranges can be used to extract portions (slices) of arrays, +# to specify a range for comprehensions, or as a value, to be expanded into the +# corresponding array of integers at runtime. +exports.Range = class Range extends Base + + children: ['from', 'to'] + + constructor: (@from, @to, tag) -> + super() + @exclusive = tag is 'exclusive' + @equals = if @exclusive then '' else '=' + + # Compiles the range's source variables -- where it starts and where it ends. + # But only if they need to be cached to avoid double evaluation. + compileVariables: (o) -> + o = merge(o, top: true) + [@from, @fromVar] = @from.compileReference o, precompile: yes + [@to, @toVar] = @to.compileReference o, precompile: yes + [@fromNum, @toNum] = [@fromVar.match(SIMPLENUM), @toVar.match(SIMPLENUM)] + parts = [] + parts.push @from if @from isnt @fromVar + parts.push @to if @to isnt @toVar + + # When compiled normally, the range returns the contents of the *for loop* + # needed to iterate over the values in the range. Used by comprehensions. + compileNode: (o) -> + @compileVariables o + return @compileArray(o) unless o.index + return @compileSimple(o) if @fromNum and @toNum + idx = del o, 'index' + step = del o, 'step' + vars = "#{idx} = #{@from}" + if @to isnt @toVar then ", #{@to}" else '' + intro = "(#{@fromVar} <= #{@toVar} ? #{idx}" + compare = "#{intro} <#{@equals} #{@toVar} : #{idx} >#{@equals} #{@toVar})" + stepPart = if step then step.compile(o) else '1' + incr = if step then "#{idx} += #{stepPart}" else "#{intro} += #{stepPart} : #{idx} -= #{stepPart})" + "#{vars}; #{compare}; #{incr}" + + # Compile a simple range comprehension, with integers. + compileSimple: (o) -> + [from, to] = [+@fromNum, +@toNum] + idx = del o, 'index' + step = del o, 'step' + step and= "#{idx} += #{step.compile(o)}" + if from <= to + "#{idx} = #{from}; #{idx} <#{@equals} #{to}; #{step or "#{idx}++"}" + else + "#{idx} = #{from}; #{idx} >#{@equals} #{to}; #{step or "#{idx}--"}" + + # When used as a value, expand the range into the equivalent array. + compileArray: (o) -> + if @fromNum and @toNum and Math.abs(@fromNum - @toNum) <= 20 + range = [+@fromNum..+@toNum] + range.pop() if @exclusive + return "[#{ range.join(', ') }]" + idt = @idt 1 + i = o.scope.freeVariable 'i' + result = o.scope.freeVariable 'result' + pre = "\n#{idt}#{result} = [];" + if @fromNum and @toNum + o.index = i + body = @compileSimple o + else + vars = "#{i} = #{@from}" + if @to isnt @toVar then ", #{@to}" else '' + clause = "#{@fromVar} <= #{@toVar} ?" + body = "var #{vars}; #{clause} #{i} <#{@equals} #{@toVar} : #{i} >#{@equals} #{@toVar}; #{clause} #{i} += 1 : #{i} -= 1" + post = "{ #{result}.push(#{i}); }\n#{idt}return #{result};\n#{o.indent}" + "(function() {#{pre}\n#{idt}for (#{body})#{post}}).call(this)" + +#### Slice + +# An array slice literal. Unlike JavaScript's `Array#slice`, the second parameter +# specifies the index of the end of the slice, just as the first parameter +# is the index of the beginning. +exports.Slice = class Slice extends Base + + children: ['range'] + + constructor: (@range) -> + super() + + compileNode: (o) -> + from = if @range.from then @range.from.compile(o) else '0' + to = if @range.to then @range.to.compile(o) else '' + to += if not to or @range.exclusive then '' else ' + 1' + to = ', ' + to if to + ".slice(#{from}#{to})" + +#### ObjectLiteral + +# An object literal, nothing fancy. +exports.ObjectLiteral = class ObjectLiteral extends Base + + children: ['properties'] + + constructor: (props) -> + super() + @objects = @properties = props or [] + + compileNode: (o) -> + top = del o, 'top' + o.indent = @idt 1 + nonComments = prop for prop in @properties when prop not instanceof Comment + lastNoncom = last nonComments + props = for prop, i in @properties + join = if i is @properties.length - 1 + '' + else if prop is lastNoncom or prop instanceof Comment + '\n' + else + ',\n' + indent = if prop instanceof Comment then '' else @idt 1 + if prop instanceof Value and prop.tags.this + prop = new Assign prop.properties[0].name, prop, 'object' + else if prop not instanceof Assign and prop not instanceof Comment + prop = new Assign prop, prop, 'object' + indent + prop.compile(o) + join + props = props.join('') + obj = "{#{ if props then '\n' + props + '\n' + @idt() else '' }}" + if @tags.front then "(#{obj})" else obj + + assigns: (name) -> + for prop in @properties when prop.assigns name then return yes + no + +#### ArrayLiteral + +# An array literal. +exports.ArrayLiteral = class ArrayLiteral extends Base + + children: ['objects'] + + constructor: (@objects) -> + super() + @objects or= [] + + compileSplatLiteral: (o) -> + Splat.compileSplattedArray @objects, o + + compileNode: (o) -> + o.indent = @idt 1 + for obj in @objects when obj instanceof Splat + return @compileSplatLiteral o + objects = [] + for obj, i in @objects + code = obj.compile o + objects.push (if obj instanceof Comment + "\n#{code}\n#{o.indent}" + else if i is @objects.length - 1 + code + else + code + ', ' + ) + objects = objects.join '' + if 0 < objects.indexOf '\n' + "[\n#{o.indent}#{objects}\n#{@tab}]" + else + "[#{objects}]" + + assigns: (name) -> + for obj in @objects when obj.assigns name then return yes + no + +#### Class + +# The CoffeeScript class definition. +exports.Class = class Class extends Base + + children: ['variable', 'parent', 'properties'] + isStatement: YES + + # Initialize a **Class** with its name, an optional superclass, and a + # list of prototype property assignments. + constructor: (variable, @parent, @properties) -> + super() + @variable = if variable is '__temp__' then new Literal variable else variable + @properties or= [] + @returns = false + + makeReturn: -> + @returns = true + this + + # Instead of generating the JavaScript string directly, we build up the + # equivalent syntax tree and compile that, in pieces. You can see the + # constructor, property assignments, and inheritance getting built out below. + compileNode: (o) -> + {variable} = this + variable = new Literal o.scope.freeVariable 'ctor' if variable.value is '__temp__' + extension = @parent and new Extends variable, @parent + props = new Expressions + o.top = true + me = null + className = variable.compile o + constScope = null + + if @parent + applied = new Value @parent, [new Accessor new Literal 'apply'] + constructor = new Code([], new Expressions([ + new Call applied, [new Literal('this'), new Literal('arguments')] + ])) + else + constructor = new Code [], new Expressions [new Return new Literal 'this'] + + for prop in @properties + [pvar, func] = [prop.variable, prop.value] + if pvar and pvar.base.value is 'constructor' + if func not instanceof Code + [func, ref] = func.compileReference o + props.push func if func isnt ref + apply = new Call(new Value(ref, [new Accessor new Literal 'apply']), [new Literal('this'), new Literal('arguments')]) + func = new Code [], new Expressions([apply]) + throw new Error "cannot define a constructor as a bound function." if func.bound + func.name = className + func.body.push new Return new Literal 'this' + variable = new Value variable + variable.namespaced = 0 < className.indexOf '.' + constructor = func + constructor.comment = props.expressions.pop() if props.expressions[props.expressions.length - 1] instanceof Comment + continue + if func instanceof Code and func.bound + if prop.context is 'this' + func.context = className + else + func.bound = false + constScope or= new Scope(o.scope, constructor.body, constructor) + me or= constScope.freeVariable 'this' + pname = pvar.compile(o) + constructor.body.push new Return new Literal 'this' if constructor.body.empty() + constructor.body.unshift new Literal "this.#{pname} = function(){ return #{className}.prototype.#{pname}.apply(#{me}, arguments); }" + if pvar + access = if prop.context is 'this' then pvar.base.properties[0] else new Accessor(pvar, 'prototype') + val = new Value variable, [access] + prop = new Assign(val, func) + props.push prop + + constructor.className = className.match /[\w\d\$_]+$/ + constructor.body.unshift new Literal "#{me} = this" if me + construct = @idt() + new Assign(variable, constructor).compile(merge o, sharedScope: constScope) + ';' + props = if !props.empty() then '\n' + props.compile(o) else '' + extension = if extension then '\n' + @idt() + extension.compile(o) + ';' else '' + returns = if @returns then '\n' + new Return(variable).compile(o) else '' + construct + extension + props + returns + +#### Assign + +# The **Assign** is used to assign a local variable to value, or to set the +# property of an object -- including within object literals. +exports.Assign = class Assign extends Base + + # Matchers for detecting class/method names + METHOD_DEF: /^(?:(\S+)\.prototype\.)?([$A-Za-z_][$\w]*)$/ + + children: ['variable', 'value'] + + constructor: (@variable, @value, @context) -> + super() + + topSensitive: YES + + isValue: -> + @variable instanceof Value + + # Compile an assignment, delegating to `compilePatternMatch` or + # `compileSplice` if appropriate. Keep track of the name of the base object + # we've been assigned to, for correct internal references. If the variable + # has not been seen yet within the current scope, declare it. + compileNode: (o) -> + if isValue = @isValue() + return @compilePatternMatch(o) if @variable.isArray() or @variable.isObject() + return @compileSplice(o) if @variable.isSplice() + if ifn = If.unfoldSoak o, this, 'variable' + delete o.top + return ifn.compile o + top = del o, 'top' + stmt = del o, 'asStatement' + name = @variable.compile(o) + if @value instanceof Code and match = @METHOD_DEF.exec name + @value.name = match[2] + @value.klass = match[1] + val = @value.compile o + return "#{name}: #{val}" if @context is 'object' + o.scope.find name unless isValue and (@variable.hasProperties() or @variable.namespaced) + val = "#{name} = #{val}" + return "#{@tab}#{val};" if stmt + if top or @parenthetical then val else "(#{val})" + + # Brief implementation of recursive pattern matching, when assigning array or + # object literals to a value. Peeks at their properties to assign inner names. + # See the [ECMAScript Harmony Wiki](http://wiki.ecmascript.org/doku.php?id=harmony:destructuring) + # for details. + compilePatternMatch: (o) -> + if (value = @value).isStatement o then value = Closure.wrap value + {objects} = @variable.base + return value.compile o unless olength = objects.length + isObject = @variable.isObject() + if o.top and olength is 1 and (obj = objects[0]) not instanceof Splat + # Unroll simplest cases: `{v} = x` -> `v = x.v` + if obj instanceof Assign + {variable: {base: idx}, value: obj} = obj + else + idx = if isObject + if obj.tags.this then obj.properties[0].name else obj + else new Literal 0 + value = new Value value unless value instanceof Value + accessClass = if IDENTIFIER.test idx.value then Accessor else Index + value.properties.push new accessClass idx + return new Assign(obj, value).compile o + top = del o, 'top' + otop = merge o, top: yes + valVar = value.compile o + assigns = [] + splat = false + if not IDENTIFIER.test(valVar) or @variable.assigns(valVar) + assigns.push "#{ ref = o.scope.freeVariable 'ref' } = #{valVar}" + valVar = ref + for obj, i in objects + # A regular array pattern-match. + idx = i + if isObject + if obj instanceof Assign + # A regular object pattern-match. + {variable: {base: idx}, value: obj} = obj + else + # A shorthand `{a, b, @c} = val` pattern-match. + idx = if obj.tags.this then obj.properties[0].name else obj + unless obj instanceof Value or obj instanceof Splat + throw new Error 'pattern matching must use only identifiers on the left-hand side.' + accessClass = if isObject and IDENTIFIER.test(idx.value) then Accessor else Index + if not splat and obj instanceof Splat + val = new Literal obj.compileValue o, valVar, i, olength - i - 1 + splat = true + else + idx = new Literal(if splat then "#{valVar}.length - #{olength - idx}" else idx) if typeof idx isnt 'object' + val = new Value new Literal(valVar), [new accessClass idx] + assigns.push new Assign(obj, val).compile otop + assigns.push valVar unless top + code = assigns.join ', ' + if top or @parenthetical then code else "(#{code})" + + # Compile the assignment from an array splice literal, using JavaScript's + # `Array#splice` method. + compileSplice: (o) -> + {range} = @variable.properties.pop() + name = @variable.compile o + plus = if range.exclusive then '' else ' + 1' + from = if range.from then range.from.compile(o) else '0' + to = if range.to then range.to.compile(o) + ' - ' + from + plus else "#{name}.length" + ref = o.scope.freeVariable 'ref' + val = @value.compile(o) + "([].splice.apply(#{name}, [#{from}, #{to}].concat(#{ref} = #{val})), #{ref})" + + assigns: (name) -> + @[if @context is 'object' then 'value' else 'variable'].assigns name + +#### Code + +# A function definition. This is the only node that creates a new Scope. +# When for the purposes of walking the contents of a function body, the Code +# has no *children* -- they're within the inner scope. +exports.Code = class Code extends Base + + children: ['params', 'body'] + + constructor: (@params, @body, tag) -> + super() + @params or= [] + @body or= new Expressions + @bound = tag is 'boundfunc' + @context = 'this' if @bound + + # Compilation creates a new scope unless explicitly asked to share with the + # outer scope. Handles splat parameters in the parameter list by peeking at + # the JavaScript `arguments` objects. If the function is bound with the `=>` + # arrow, generates a wrapper that saves the current value of `this` through + # a closure. + compileNode: (o) -> + sharedScope = del o, 'sharedScope' + top = del o, 'top' + o.scope = sharedScope or new Scope(o.scope, @body, this) + o.top = true + o.indent = @idt(1) + empty = @body.expressions.length is 0 + delete o.bare + delete o.globals + splat = undefined + params = [] + for param, i in @params + if splat + if param.attach + param.assign = new Assign new Value new Literal('this'), [new Accessor param.value] + @body.expressions.splice splat.index + 1, 0, param.assign + splat.trailings.push param + else + if param.attach + {value} = param + [param, param.splat] = [new Literal(o.scope.freeVariable 'arg'), param.splat] + @body.unshift new Assign new Value(new Literal('this'), [new Accessor value]), param + if param.splat + splat = new Splat param.value + splat.index = i + splat.trailings = [] + splat.arglength = @params.length + @body.unshift(splat) + else + params.push param + o.scope.startLevel() + params = (param.compile(o) for param in params) + @body.makeReturn() unless empty or @noReturn + (o.scope.parameter(param)) for param in params + comm = if @comment then @comment.compile(o) + '\n' else '' + o.indent = @idt 2 if @className + code = if @body.expressions.length then "\n#{ @body.compileWithDeclarations(o) }\n" else '' + open = if @className then "(function() {\n#{comm}#{@idt(1)}function #{@className}(" else "function(" + close = if @className then "#{code and @idt(1)}};\n#{@idt(1)}return #{@className};\n#{@tab}})()" else "#{code and @tab}}" + func = "#{open}#{ params.join(', ') }) {#{code}#{close}" + o.scope.endLevel() + return "#{utility 'bind'}(#{func}, #{@context})" if @bound + if @tags.front then "(#{func})" else func + + # Short-circuit traverseChildren method to prevent it from crossing scope boundaries + # unless crossScope is true + traverseChildren: (crossScope, func) -> super(crossScope, func) if crossScope + +#### Param + +# A parameter in a function definition. Beyond a typical Javascript parameter, +# these parameters can also attach themselves to the context of the function, +# as well as be a splat, gathering up a group of parameters into an array. +exports.Param = class Param extends Base + + children: ['name'] + + constructor: (@name, @attach, @splat) -> + super() + @value = new Literal @name + + compileNode: (o) -> + @value.compile o + + toString: -> + {name} = @ + name = '@' + name if @attach + name += '...' if @splat + new Literal(name).toString() + +#### Splat + +# A splat, either as a parameter to a function, an argument to a call, +# or as part of a destructuring assignment. +exports.Splat = class Splat extends Base + + children: ['name'] + + constructor: (name) -> + super() + @name = if name.compile then name else new Literal name + + assigns: (name) -> @name.assigns name + + compileNode: (o) -> + if @index? then @compileParam(o) else @name.compile(o) + + # Compiling a parameter splat means recovering the parameters that succeed + # the splat in the parameter list, by slicing the arguments object. + compileParam: (o) -> + name = @name.compile(o) + o.scope.find name + end = '' + if @trailings.length + len = o.scope.freeVariable 'len' + o.scope.assign len, "arguments.length" + variadic = o.scope.freeVariable 'result' + o.scope.assign variadic, len + ' >= ' + @arglength + end = if @trailings.length then ", #{len} - #{@trailings.length}" + for trailing, idx in @trailings + if trailing.attach + assign = trailing.assign + trailing = new Literal o.scope.freeVariable 'arg' + assign.value = trailing + pos = @trailings.length - idx + o.scope.assign(trailing.compile(o), "arguments[#{variadic} ? #{len} - #{pos} : #{@index + idx}]") + "#{name} = #{utility('slice')}.call(arguments, #{@index}#{end})" + + # A compiling a splat as a destructuring assignment means slicing arguments + # from the right-hand-side's corresponding array. + compileValue: (o, name, index, trailings) -> + trail = if trailings then ", #{name}.length - #{trailings}" else '' + "#{utility 'slice'}.call(#{name}, #{index}#{trail})" + + # Utility function that converts arbitrary number of elements, mixed with + # splats, to a proper array + @compileSplattedArray: (list, o) -> + args = [] + end = -1 + for arg, i in list + code = arg.compile o + prev = args[end] + if arg not instanceof Splat + if prev and starts(prev, '[') and ends(prev, ']') + args[end] = "#{prev.slice 0, -1}, #{code}]" + continue + if prev and starts(prev, '.concat([') and ends(prev, '])') + args[end] = "#{prev.slice 0, -2}, #{code}])" + continue + code = "[#{code}]" + args[++end] = if i is 0 then code else ".concat(#{code})" + args.join '' + +#### While + +# A while loop, the only sort of low-level loop exposed by CoffeeScript. From +# it, all other loops can be manufactured. Useful in cases where you need more +# flexibility or more speed than a comprehension can provide. +exports.While = class While extends Base + + children: ['condition', 'guard', 'body'] + isStatement: YES + + constructor: (condition, opts) -> + super() + @condition = if opts?.invert then condition.invert() else condition + @guard = opts?.guard + + addBody: (body) -> + @body = body + this + + makeReturn: -> + @returns = true + this + + topSensitive: YES + + # The main difference from a JavaScript *while* is that the CoffeeScript + # *while* can be used as a part of a larger expression -- while loops may + # return an array containing the computed result of each iteration. + compileNode: (o) -> + top = del(o, 'top') and not @returns + o.indent = @idt 1 + @condition.parenthetical = yes + cond = @condition.compile(o) + o.top = true + set = '' + unless top + rvar = o.scope.freeVariable 'result' + set = "#{@tab}#{rvar} = [];\n" + @body = Push.wrap(rvar, @body) if @body + pre = "#{set}#{@tab}while (#{cond})" + @body = Expressions.wrap([new If(@guard, @body)]) if @guard + if @returns + post = '\n' + new Return(new Literal rvar).compile(merge(o, indent: @idt())) + else + post = '' + "#{pre} {\n#{ @body.compile(o) }\n#{@tab}}#{post}" + +#### Op + +# Simple Arithmetic and logical operations. Performs some conversion from +# CoffeeScript operations into their JavaScript equivalents. +exports.Op = class Op extends Base + + # The map of conversions from CoffeeScript to JavaScript symbols. + CONVERSIONS: + '==': '===' + '!=': '!==' + of: 'in' + + # The map of invertible operators. + INVERSIONS: + '!==': '===' + '===': '!==' + + # The list of operators for which we perform + # [Python-style comparison chaining](http://docs.python.org/reference/expressions.html#notin). + CHAINABLE: ['<', '>', '>=', '<=', '===', '!=='] + + # Our assignment operators that have no JavaScript equivalent. + ASSIGNMENT: ['||=', '&&=', '?='] + + # Operators must come before their operands with a space. + PREFIX_OPERATORS: ['new', 'typeof', 'delete'] + + children: ['first', 'second'] + + constructor: (op, first, second, flip) -> + if op is 'new' + return first.newInstance() if first instanceof Call + first = new Parens first if first instanceof Code and first.bound + super() + @operator = @CONVERSIONS[op] or op + (@first = first ).tags.operation = yes + (@second = second).tags.operation = yes if second + @flip = !!flip + + isUnary: -> + not @second + + isComplex: -> @operator isnt '!' or @first.isComplex() + + isMutator: -> + ends(@operator, '=') and @operator not in ['===', '!=='] + + isChainable: -> + include(@CHAINABLE, @operator) + + invert: -> + if @operator in ['===', '!=='] + @operator = @INVERSIONS[@operator] + this + else if @second + new Parens(this).invert() + else + super() + + toString: (idt) -> + super(idt, @constructor.name + ' ' + @operator) + + compileNode: (o) -> + @first.tags.front = @tags.front if @second + return @compileChain(o) if @isChainable() and @first.unwrap() instanceof Op and @first.unwrap().isChainable() + return @compileAssignment(o) if include @ASSIGNMENT, @operator + return @compileUnary(o) if @isUnary() + return @compileExistence(o) if @operator is '?' + @first = new Parens @first if @first instanceof Op and @first.isMutator() + @second = new Parens @second if @second instanceof Op and @second.isMutator() + [@first.compile(o), @operator, @second.compile(o)].join ' ' + + # Mimic Python's chained comparisons when multiple comparison operators are + # used sequentially. For example: + # + # bin/coffee -e "puts 50 < 65 > 10" + # true + compileChain: (o) -> + shared = @first.unwrap().second + [@first.second, shared] = shared.compileReference o + [first, second, shared] = [@first.compile(o), @second.compile(o), shared.compile(o)] + "(#{first}) && (#{shared} #{@operator} #{second})" + + # When compiling a conditional assignment, take care to ensure that the + # operands are only evaluated once, even though we have to reference them + # more than once. + compileAssignment: (o) -> + [left, rite] = @first.cacheReference o + rite = new Assign rite, @second + return new Op(@operator.slice(0, -1), left, rite).compile o + + compileExistence: (o) -> + if @first.isComplex() + ref = o.scope.freeVariable 'ref' + fst = new Parens new Assign new Literal(ref), @first + else + fst = @first + ref = fst.compile o + new Existence(fst).compile(o) + " ? #{ref} : #{ @second.compile o }" + + # Compile a unary **Op**. + compileUnary: (o) -> + space = if include @PREFIX_OPERATORS, @operator then ' ' else '' + parts = [@operator, space, @first.compile(o)] + (if @flip then parts.reverse() else parts).join '' + +#### In +exports.In = class In extends Base + + children: ['object', 'array'] + + constructor: (@object, @array) -> + super() + + isArray: -> + @array instanceof Value and @array.isArray() + + compileNode: (o) -> + if @isArray() then @compileOrTest(o) else @compileLoopTest(o) + + compileOrTest: (o) -> + [obj1, obj2] = @object.compileReference o, precompile: yes + tests = for item, i in @array.base.objects + "#{if i then obj2 else obj1} === #{item.compile(o)}" + "(#{tests.join(' || ')})" + + compileLoopTest: (o) -> + "#{utility 'inArray'}(#{@object.compile o}, #{@array.compile o})" + +#### Try + +# A classic *try/catch/finally* block. +exports.Try = class Try extends Base + + children: ['attempt', 'recovery', 'ensure'] + isStatement: YES + + constructor: (@attempt, @error, @recovery, @ensure) -> + super() + + makeReturn: -> + @attempt = @attempt.makeReturn() if @attempt + @recovery = @recovery.makeReturn() if @recovery + this + + # Compilation is more or less as you would expect -- the *finally* clause + # is optional, the *catch* is not. + compileNode: (o) -> + o.indent = @idt 1 + o.top = true + attemptPart = @attempt.compile(o) + errorPart = if @error then " (#{ @error.compile(o) }) " else ' ' + catchPart = if @recovery + " catch#{errorPart}{\n#{ @recovery.compile(o) }\n#{@tab}}" + else unless @ensure or @recovery then ' catch (_e) {}' else '' + finallyPart = (@ensure or '') and ' finally {\n' + @ensure.compile(merge(o)) + "\n#{@tab}}" + "#{@tab}try {\n#{attemptPart}\n#{@tab}}#{catchPart}#{finallyPart}" + +#### Throw + +# Simple node to throw an exception. +exports.Throw = class Throw extends Base + + children: ['expression'] + isStatement: YES + + constructor: (@expression) -> + super() + + # A **Throw** is already a return, of sorts... + makeReturn: THIS + + compileNode: (o) -> + "#{@tab}throw #{@expression.compile(o)};" + +#### Existence + +# Checks a variable for existence -- not *null* and not *undefined*. This is +# similar to `.nil?` in Ruby, and avoids having to consult a JavaScript truth +# table. +exports.Existence = class Existence extends Base + + children: ['expression'] + + constructor: (@expression) -> + super() + + compileNode: (o) -> + code = @expression.compile o + code = if IDENTIFIER.test(code) and not o.scope.check code + "typeof #{code} !== \"undefined\" && #{code} !== null" + else + "#{code} != null" + if @parenthetical then code else "(#{code})" + +#### Parens + +# An extra set of parentheses, specified explicitly in the source. At one time +# we tried to clean up the results by detecting and removing redundant +# parentheses, but no longer -- you can put in as many as you please. +# +# Parentheses are a good way to force any statement to become an expression. +exports.Parens = class Parens extends Base + + children: ['expression'] + + constructor: (@expression) -> + super() + + isStatement: (o) -> + @expression.isStatement(o) + isComplex: -> + @expression.isComplex() + + topSensitive: YES + + makeReturn: -> + @expression.makeReturn() + + compileNode: (o) -> + top = del o, 'top' + @expression.parenthetical = true + code = @expression.compile(o) + return code if top and @expression.isPureStatement o + if @parenthetical or @isStatement o + return if top then @tab + code + ';' else code + "(#{code})" + +#### For + +# CoffeeScript's replacement for the *for* loop is our array and object +# comprehensions, that compile into *for* loops here. They also act as an +# expression, able to return the result of each filtered iteration. +# +# Unlike Python array comprehensions, they can be multi-line, and you can pass +# the current index of the loop as a second parameter. Unlike Ruby blocks, +# you can map and filter in a single pass. +exports.For = class For extends Base + + children: ['body', 'source', 'guard'] + isStatement: YES + + constructor: (@body, source, @name, @index) -> + super() + {@source, @guard, @step} = source + @raw = !!source.raw + @object = !!source.object + [@name, @index] = [@index, @name] if @object + @pattern = @name instanceof Value + throw new Error('index cannot be a pattern matching expression') if @index instanceof Value + @returns = false + + topSensitive: YES + + makeReturn: -> + @returns = true + this + + compileReturnValue: (val, o) -> + return '\n' + new Return(new Literal val).compile(o) if @returns + return '\n' + val if val + '' + + # Welcome to the hairiest method in all of CoffeeScript. Handles the inner + # loop, filtering, stepping, and result saving for array, object, and range + # comprehensions. Some of the generated code can be shared in common, and + # some cannot. + compileNode: (o) -> + topLevel = del(o, 'top') and not @returns + range = @source instanceof Value and @source.base instanceof Range and not @source.properties.length + source = if range then @source.base else @source + codeInBody = not @body.containsPureStatement() and @body.contains (node) -> node instanceof Code + scope = o.scope + name = @name and @name.compile o + index = @index and @index.compile o + scope.find(name, immediate: yes) if name and not @pattern and (range or not codeInBody) + scope.find(index, immediate: yes) if index + rvar = scope.freeVariable 'result' unless topLevel + ivar = if range then name else index + ivar = scope.freeVariable 'i' if not ivar or codeInBody + nvar = scope.freeVariable 'i' if name and not range and codeInBody + varPart = '' + guardPart = '' + unstepPart = '' + body = Expressions.wrap([@body]) + idt1 = @idt 1 + if range + forPart = source.compile merge o, {index: ivar, @step} + else + svar = sourcePart = @source.compile o + if (name or not @raw) and + not (IDENTIFIER.test(svar) and scope.check svar, immediate: on) + sourcePart = "#{ref = scope.freeVariable 'ref'} = #{svar}" + sourcePart = "(#{sourcePart})" unless @object + svar = ref + namePart = if @pattern + new Assign(@name, new Literal "#{svar}[#{ivar}]").compile merge o, top: on + else if name + "#{name} = #{svar}[#{ivar}]" + unless @object + lvar = scope.freeVariable 'len' + stepPart = if @step then "#{ivar} += #{ @step.compile(o) }" else "#{ivar}++" + forPart = "#{ivar} = 0, #{lvar} = #{sourcePart}.length; #{ivar} < #{lvar}; #{stepPart}" + resultPart = if rvar then "#{@tab}#{rvar} = [];\n" else '' + returnResult = @compileReturnValue(rvar, o) + body = Push.wrap(rvar, body) unless topLevel + if @guard + body = Expressions.wrap([new If(@guard, body)]) + if codeInBody + body.unshift new Literal "var #{name} = #{ivar}" if range + body.unshift new Literal "var #{namePart}" if namePart + body.unshift new Literal "var #{index} = #{ivar}" if index + lastLine = body.expressions.pop() + body.push new Assign new Literal(ivar), new Literal index if index + body.push new Assign new Literal(nvar), new Literal name if nvar + body.push lastLine + o.indent = @idt 1 + body = Expressions.wrap [new Literal body.compile o] + body.push new Assign new Literal(index), new Literal ivar if index + body.push new Assign new Literal(name), new Literal nvar or ivar if name + else + varPart = "#{idt1}#{namePart};\n" if namePart + if forPart and name is ivar + unstepPart = if @step then "#{name} -= #{ @step.compile(o) };" else "#{name}--;" + unstepPart = "\n#{@tab}" + unstepPart + if @object + forPart = "#{ivar} in #{sourcePart}" + guardPart = "\n#{idt1}if (!#{utility('hasProp')}.call(#{svar}, #{ivar})) continue;" unless @raw + body = body.compile merge o, indent: idt1, top: true + vars = if range then name else "#{name}, #{ivar}" + """ + #{resultPart}#{@tab}for (#{forPart}) {#{guardPart} + #{varPart}#{body} + #{@tab}}#{unstepPart}#{returnResult} + """ + +#### Switch + +# A JavaScript *switch* statement. Converts into a returnable expression on-demand. +exports.Switch = class Switch extends Base + + children: ['subject', 'cases', 'otherwise'] + + isStatement: YES + + constructor: (@subject, @cases, @otherwise) -> + super() + @tags.subjectless = !@subject + @subject or= new Literal 'true' + + makeReturn: -> + pair[1].makeReturn() for pair in @cases + @otherwise.makeReturn() if @otherwise + this + + compileNode: (o) -> + idt = o.indent = @idt 2 + o.top = yes + code = "#{ @tab }switch (#{ @subject.compile o }) {" + for pair in @cases + [conditions, block] = pair + exprs = block.expressions + for condition in flatten [conditions] + condition = new Op '!!', new Parens condition if @tags.subjectless + code += "\n#{ @idt(1) }case #{ condition.compile o }:" + code += "\n#{ block.compile o }" + code += "\n#{ idt }break;" unless last(exprs) instanceof Return + if @otherwise + code += "\n#{ @idt(1) }default:\n#{ @otherwise.compile o }" + code += "\n#{ @tab }}" + code + +#### If + +# *If/else* statements. Acts as an expression by pushing down requested returns +# to the last line of each clause. +# +# Single-expression **Ifs** are compiled into conditional operators if possible, +# because ternaries are already proper expressions, and don't need conversion. +exports.If = class If extends Base + + children: ['condition', 'body', 'elseBody', 'assigner'] + + topSensitive: YES + + constructor: (condition, @body, tags) -> + @tags = tags or= {} + @condition = if tags.invert then condition.invert() else condition + @soakNode = tags.soak + @elseBody = null + @isChain = false + + bodyNode: -> @body?.unwrap() + elseBodyNode: -> @elseBody?.unwrap() + + # Rewrite a chain of **Ifs** to add a default case as the final *else*. + addElse: (elseBody) -> + if @isChain + @elseBodyNode().addElse elseBody + else + @isChain = elseBody instanceof If + @elseBody = @ensureExpressions elseBody + this + + # The **If** only compiles into a statement if either of its bodies needs + # to be a statement. Otherwise a conditional operator is safe. + isStatement: (o) -> + @statement or= o?.top or @bodyNode().isStatement(o) or @elseBodyNode()?.isStatement(o) + + compileCondition: (o) -> + @condition.parenthetical = yes + @condition.compile o + + compileNode: (o) -> + if @isStatement o then @compileStatement o else @compileExpression o + + makeReturn: -> + if @isStatement() + @body and= @ensureExpressions(@body.makeReturn()) + @elseBody and= @ensureExpressions(@elseBody.makeReturn()) + this + else + new Return this + + ensureExpressions: (node) -> + if node instanceof Expressions then node else new Expressions [node] + + # Compile the **If** as a regular *if-else* statement. Flattened chains + # force inner *else* bodies into statement form. + compileStatement: (o) -> + top = del o, 'top' + child = del o, 'chainChild' + condO = merge o + o.indent = @idt 1 + o.top = true + ifPart = "if (#{ @compileCondition condO }) {\n#{ @body.compile o }\n#{@tab}}" + ifPart = @tab + ifPart unless child + return ifPart unless @elseBody + ifPart + if @isChain + ' else ' + @elseBodyNode().compile merge o, indent: @tab, chainChild: true + else + " else {\n#{ @elseBody.compile(o) }\n#{@tab}}" + + # Compile the If as a conditional operator. + compileExpression: (o) -> + @bodyNode().tags.operation = @condition.tags.operation = yes + @elseBodyNode().tags.operation = yes if @elseBody + ifPart = @condition.compile(o) + ' ? ' + @bodyNode().compile(o) + elsePart = if @elseBody then @elseBodyNode().compile(o) else 'undefined' + code = "#{ifPart} : #{elsePart}" + if @tags.operation or @soakNode then "(#{code})" else code + + unfoldSoak: -> @soakNode and this + + # Unfold a node's child if soak, then tuck the node under created `If` + @unfoldSoak: (o, parent, name) -> + return unless ifn = parent[name].unfoldSoak o + parent[name] = ifn.body + ifn.body = new Value parent + ifn + +# Faux-Nodes +# ---------- +# Faux-nodes are never created by the grammar, but are used during code +# generation to generate other combinations of nodes. + +#### Push + +# The **Push** creates the tree for `array.push(value)`, +# which is helpful for recording the result arrays from comprehensions. +Push = + wrap: (name, expressions) -> + return expressions if expressions.empty() or expressions.containsPureStatement() + Expressions.wrap [new Call( + new Value new Literal(name), [new Accessor new Literal 'push'] + [expressions.unwrap()] + )] + +#### Closure + +# A faux-node used to wrap an expressions body in a closure. +Closure = + + # Wrap the expressions body, unless it contains a pure statement, + # in which case, no dice. If the body mentions `this` or `arguments`, + # then make sure that the closure wrapper preserves the original values. + wrap: (expressions, statement, noReturn) -> + return expressions if expressions.containsPureStatement() + func = new Parens new Code [], Expressions.wrap [expressions] + args = [] + if (mentionsArgs = expressions.contains @literalArgs) or + ( expressions.contains @literalThis) + meth = new Literal if mentionsArgs then 'apply' else 'call' + args = [new Literal 'this'] + args.push new Literal 'arguments' if mentionsArgs + func = new Value func, [new Accessor meth] + func.noReturn = noReturn + call = new Call func, args + if statement then Expressions.wrap [call] else call + + literalArgs: (node) -> node instanceof Literal and node.value is 'arguments' + literalThis: (node) -> node instanceof Literal and node.value is 'this' or + node instanceof Code and node.bound + +# Constants +# --------- + +UTILITIES = + + # Correctly set up a prototype chain for inheritance, including a reference + # to the superclass for `super()` calls. See: + # [goog.inherits](http://closure-library.googlecode.com/svn/docs/closureGoogBase.js.source.html#line1206). + extends: ''' + function(child, parent) { + function ctor() { this.constructor = child; } + ctor.prototype = parent.prototype; + child.prototype = new ctor; + if (typeof parent.extended === "function") parent.extended(child); + child.__super__ = parent.prototype; + } + ''' + + # Create a function bound to the current value of "this". + bind: ''' + function(func, context) { + return function() { return func.apply(context, arguments); }; + } + ''' + + # Discover if an item is in an array. + inArray: ''' + (function() { + var indexOf = Array.prototype.indexOf || function(item) { + var i = this.length; while (i--) if (this[i] === item) return i; + return -1; + }; + return function(item, array) { return indexOf.call(array, item) > -1; }; + })(); + ''' + + # Shortcuts to speed up the lookup time for native functions. + hasProp: 'Object.prototype.hasOwnProperty' + slice: 'Array.prototype.slice' + +# Tabs are two spaces for pretty printing. +TAB = ' ' + +# Trim out all trailing whitespace, so that the generated code plays nice +# with Git. +TRAILING_WHITESPACE = /[ \t]+$/gm + +IDENTIFIER = /^[$A-Za-z_][$\w]*$/ +NUMBER = /^0x[\da-f]+|^(?:\d+(\.\d+)?|\.\d+)(?:e[+-]?\d+)?$/i +SIMPLENUM = /^[+-]?\d+$/ + +# Is a literal value a string? +IS_STRING = /^['"]/ + +# Utility Functions +# ----------------- + +# Helper for ensuring that utility functions are assigned at the top level. +utility = (name) -> + ref = "__#{name}" + Scope.root.assign ref, UTILITIES[name] + ref diff --git a/node_modules/jade/support/coffee-script/src/optparse.coffee b/node_modules/jade/support/coffee-script/src/optparse.coffee new file mode 100644 index 0000000..5a6c9ee --- /dev/null +++ b/node_modules/jade/support/coffee-script/src/optparse.coffee @@ -0,0 +1,96 @@ +# A simple **OptionParser** class to parse option flags from the command-line. +# Use it like so: +# +# parser = new OptionParser switches, helpBanner +# options = parser.parse process.argv +# +# The first non-option is considered to be the start of the file (and file +# option) list, and all subsequent arguments are left unparsed. +exports.OptionParser = class OptionParser + + # Initialize with a list of valid options, in the form: + # + # [short-flag, long-flag, description] + # + # Along with an an optional banner for the usage help. + constructor: (rules, banner) -> + @banner = banner + @rules = buildRules rules + + # Parse the list of arguments, populating an `options` object with all of the + # specified options, and returning it. `options.arguments` will be an array + # containing the remaning non-option arguments. This is a simpler API than + # many option parsers that allow you to attach callback actions for every + # flag. Instead, you're responsible for interpreting the options object. + parse: (args) -> + options = arguments: [] + args = normalizeArguments args + for arg, i in args + isOption = !!(arg.match(LONG_FLAG) or arg.match(SHORT_FLAG)) + matchedRule = no + for rule in @rules + if rule.shortFlag is arg or rule.longFlag is arg + value = if rule.hasArgument then args[i += 1] else true + options[rule.name] = if rule.isList then (options[rule.name] or []).concat value else value + matchedRule = yes + break + throw new Error "unrecognized option: #{arg}" if isOption and not matchedRule + if not isOption + options.arguments = args.slice i + break + options + + # Return the help text for this **OptionParser**, listing and describing all + # of the valid options, for `--help` and such. + help: -> + lines = ['Available options:'] + lines.unshift "#{@banner}\n" if @banner + for rule in @rules + spaces = 15 - rule.longFlag.length + spaces = if spaces > 0 then Array(spaces + 1).join(' ') else '' + letPart = if rule.shortFlag then rule.shortFlag + ', ' else ' ' + lines.push ' ' + letPart + rule.longFlag + spaces + rule.description + "\n#{ lines.join('\n') }\n" + +# Helpers +# ------- + +# Regex matchers for option flags. +LONG_FLAG = /^(--\w[\w\-]+)/ +SHORT_FLAG = /^(-\w)/ +MULTI_FLAG = /^-(\w{2,})/ +OPTIONAL = /\[(\w+(\*?))\]/ + +# Build and return the list of option rules. If the optional *short-flag* is +# unspecified, leave it out by padding with `null`. +buildRules = (rules) -> + for tuple in rules + tuple.unshift null if tuple.length < 3 + buildRule tuple... + +# Build a rule from a `-o` short flag, a `--output [DIR]` long flag, and the +# description of what the option does. +buildRule = (shortFlag, longFlag, description, options) -> + match = longFlag.match(OPTIONAL) + longFlag = longFlag.match(LONG_FLAG)[1] + options or= {} + { + name: longFlag.substr 2 + shortFlag: shortFlag + longFlag: longFlag + description: description + hasArgument: !!(match and match[1]) + isList: !!(match and match[2]) + } + +# Normalize arguments by expanding merged flags into multiple flags. This allows +# you to have `-wl` be the same as `--watch --lint`. +normalizeArguments = (args) -> + args = args.slice 0 + result = [] + for arg in args + if match = arg.match MULTI_FLAG + result.push '-' + l for l in match[1].split '' + else + result.push arg + result diff --git a/node_modules/jade/support/coffee-script/src/repl.coffee b/node_modules/jade/support/coffee-script/src/repl.coffee new file mode 100644 index 0000000..294146b --- /dev/null +++ b/node_modules/jade/support/coffee-script/src/repl.coffee @@ -0,0 +1,35 @@ +# A very simple Read-Eval-Print-Loop. Compiles one line at a time to JavaScript +# and evaluates it. Good for simple tests, or poking around the **Node.js** API. +# Using it looks like this: +# +# coffee> puts "#{num} bottles of beer" for num in [99..1] + +# Require the **coffee-script** module to get access to the compiler. +CoffeeScript = require './coffee-script' +helpers = require './helpers' +readline = require 'readline' + +# Start by opening up **stdio**. +stdio = process.openStdin() + +# Quick alias for quitting the REPL. +helpers.extend global, quit: -> process.exit(0) + +# The main REPL function. **run** is called every time a line of code is entered. +# Attempt to evaluate the command. If there's an exception, print it out instead +# of exiting. +run = (buffer) -> + try + val = CoffeeScript.eval buffer.toString(), bare: on, globals: on, fileName: 'repl' + puts inspect val if val isnt undefined + catch err + puts err.stack or err.toString() + repl.prompt() + +# Create the REPL by listening to **stdin**. +repl = readline.createInterface stdio +repl.setPrompt 'coffee> ' +stdio.on 'data', (buffer) -> repl.write buffer +repl.on 'close', -> stdio.destroy() +repl.on 'line', run +repl.prompt() diff --git a/node_modules/jade/support/coffee-script/src/rewriter.coffee b/node_modules/jade/support/coffee-script/src/rewriter.coffee new file mode 100644 index 0000000..5ea0298 --- /dev/null +++ b/node_modules/jade/support/coffee-script/src/rewriter.coffee @@ -0,0 +1,349 @@ +# The CoffeeScript language has a good deal of optional syntax, implicit syntax, +# and shorthand syntax. This can greatly complicate a grammar and bloat +# the resulting parse table. Instead of making the parser handle it all, we take +# a series of passes over the token stream, using this **Rewriter** to convert +# shorthand into the unambiguous long form, add implicit indentation and +# parentheses, balance incorrect nestings, and generally clean things up. + +# Import the helpers we need. +{include} = require './helpers' + +# The **Rewriter** class is used by the [Lexer](lexer.html), directly against +# its internal array of tokens. +class exports.Rewriter + + # Helpful snippet for debugging: + # puts (t[0] + '/' + t[1] for t in @tokens).join ' ' + + # Rewrite the token stream in multiple passes, one logical filter at + # a time. This could certainly be changed into a single pass through the + # stream, with a big ol' efficient switch, but it's much nicer to work with + # like this. The order of these passes matters -- indentation must be + # corrected before implicit parentheses can be wrapped around blocks of code. + rewrite: (@tokens) -> + @adjustComments() + @removeLeadingNewlines() + @removeMidExpressionNewlines() + @closeOpenCalls() + @closeOpenIndexes() + @addImplicitIndentation() + @tagPostfixConditionals() + @addImplicitBraces() + @addImplicitParentheses() + @ensureBalance BALANCED_PAIRS + @rewriteClosingParens() + @tokens + + # Rewrite the token stream, looking one token ahead and behind. + # Allow the return value of the block to tell us how many tokens to move + # forwards (or backwards) in the stream, to make sure we don't miss anything + # as tokens are inserted and removed, and the stream changes length under + # our feet. + scanTokens: (block) -> + {tokens} = this + i = 0 + i += block.call this, token, i, tokens while token = tokens[i] + true + + detectEnd: (i, condition, action) -> + {tokens} = this + levels = 0 + while token = tokens[i] + return action.call this, token, i if levels is 0 and condition.call this, token, i + return action.call this, token, i - 1 if not token or levels < 0 + if include EXPRESSION_START, token[0] + levels += 1 + else if include EXPRESSION_END, token[0] + levels -= 1 + i += 1 + i - 1 + + # Massage newlines and indentations so that comments don't have to be + # correctly indented, or appear on a line of their own. + adjustComments: -> + @scanTokens (token, i, tokens) -> + return 1 unless token[0] is 'HERECOMMENT' + before = tokens[i - 2] + prev = tokens[i - 1] + post = tokens[i + 1] + after = tokens[i + 2] + if after?[0] is 'INDENT' + tokens.splice i + 2, 1 + if before?[0] is 'OUTDENT' and post?[0] is 'TERMINATOR' + tokens.splice i - 2, 1 + else + tokens.splice i, 0, after + else if prev and prev[0] not in ['TERMINATOR', 'INDENT', 'OUTDENT'] + if post?[0] is 'TERMINATOR' and after?[0] is 'OUTDENT' + tokens.splice i + 2, 0, tokens.splice(i, 2)... + if tokens[i + 2][0] isnt 'TERMINATOR' + tokens.splice i + 2, 0, ['TERMINATOR', '\n', prev[2]] + else + tokens.splice i, 0, ['TERMINATOR', '\n', prev[2]] + return 2 + 1 + + # Leading newlines would introduce an ambiguity in the grammar, so we + # dispatch them here. + removeLeadingNewlines: -> + break for [tag], i in @tokens when tag isnt 'TERMINATOR' + @tokens.splice 0, i if i + + # Some blocks occur in the middle of expressions -- when we're expecting + # this, remove their trailing newlines. + removeMidExpressionNewlines: -> + @scanTokens (token, i, tokens) -> + return 1 unless token[0] is 'TERMINATOR' and include EXPRESSION_CLOSE, @tag(i + 1) + tokens.splice i, 1 + 0 + + # The lexer has tagged the opening parenthesis of a method call. Match it with + # its paired close. We have the mis-nested outdent case included here for + # calls that close on the same line, just before their outdent. + closeOpenCalls: -> + condition = (token, i) -> + token[0] in [')', 'CALL_END'] or + token[0] is 'OUTDENT' and @tag(i - 1) is ')' + action = (token, i) -> + @tokens[if token[0] is 'OUTDENT' then i - 1 else i][0] = 'CALL_END' + @scanTokens (token, i) -> + @detectEnd i + 1, condition, action if token[0] is 'CALL_START' + 1 + + # The lexer has tagged the opening parenthesis of an indexing operation call. + # Match it with its paired close. + closeOpenIndexes: -> + condition = (token, i) -> token[0] in [']', 'INDEX_END'] + action = (token, i) -> token[0] = 'INDEX_END' + @scanTokens (token, i) -> + @detectEnd i + 1, condition, action if token[0] is 'INDEX_START' + 1 + + # Object literals may be written with implicit braces, for simple cases. + # Insert the missing braces here, so that the parser doesn't have to. + addImplicitBraces: -> + stack = [] + condition = (token, i) -> + return false if 'HERECOMMENT' in [@tag(i + 1), @tag(i - 1)] + [one, two, three] = @tokens.slice i + 1, i + 4 + [tag] = token + tag in ['TERMINATOR', 'OUTDENT'] and not (two?[0] is ':' or one?[0] is '@' and three?[0] is ':') or + tag is ',' and one?[0] not in ['IDENTIFIER', 'NUMBER', 'STRING', '@', 'TERMINATOR', 'OUTDENT'] + action = (token, i) -> @tokens.splice i, 0, ['}', '}', token[2]] + @scanTokens (token, i, tokens) -> + if include EXPRESSION_START, tag = token[0] + stack.push if tag is 'INDENT' and @tag(i - 1) is '{' then '{' else tag + return 1 + if include EXPRESSION_END, tag + stack.pop() + return 1 + return 1 unless tag is ':' and stack[stack.length - 1] isnt '{' + stack.push '{' + idx = if @tag(i - 2) is '@' then i - 2 else i - 1 + idx -= 2 if @tag(idx - 2) is 'HERECOMMENT' + tok = ['{', '{', token[2]] + tok.generated = yes + tokens.splice idx, 0, tok + @detectEnd i + 2, condition, action + 2 + + # Methods may be optionally called without parentheses, for simple cases. + # Insert the implicit parentheses here, so that the parser doesn't have to + # deal with them. + addImplicitParentheses: -> + classLine = no + action = (token, i) -> + idx = if token[0] is 'OUTDENT' then i + 1 else i + @tokens.splice idx, 0, ['CALL_END', ')', token[2]] + @scanTokens (token, i, tokens) -> + tag = token[0] + classLine = yes if tag is 'CLASS' + prev = tokens[i - 1] + next = tokens[i + 1] + callObject = not classLine and tag is 'INDENT' and + next and next.generated and next[0] is '{' and + prev and include(IMPLICIT_FUNC, prev[0]) + seenSingle = no + classLine = no if include LINEBREAKS, tag + token.call = yes if prev and not prev.spaced and tag is '?' + return 1 unless callObject or + prev?.spaced and (prev.call or include(IMPLICIT_FUNC, prev[0])) and + (include(IMPLICIT_CALL, tag) or include(IMPLICIT_UNSPACED_CALL, tag) and not token.spaced) + tokens.splice i, 0, ['CALL_START', '(', token[2]] + @detectEnd i + (if callObject then 2 else 1), (token, i) -> + return yes if not seenSingle and token.fromThen + [tag] = token + seenSingle = yes if tag in ['IF', 'ELSE', 'UNLESS', '->', '=>'] + return yes if tag is 'PROPERTY_ACCESS' and @tag(i - 1) is 'OUTDENT' + not token.generated and @tag(i - 1) isnt ',' and include(IMPLICIT_END, tag) and + (tag isnt 'INDENT' or + (@tag(i - 2) isnt 'CLASS' and not include(IMPLICIT_BLOCK, @tag(i - 1)) and + not ((post = @tokens[i + 1]) and post.generated and post[0] is '{'))) + , action + prev[0] = 'FUNC_EXIST' if prev[0] is '?' + 2 + + # Because our grammar is LALR(1), it can't handle some single-line + # expressions that lack ending delimiters. The **Rewriter** adds the implicit + # blocks, so it doesn't need to. ')' can close a single-line block, + # but we need to make sure it's balanced. + addImplicitIndentation: -> + @scanTokens (token, i, tokens) -> + [tag] = token + if tag is 'ELSE' and @tag(i - 1) isnt 'OUTDENT' + tokens.splice i, 0, @indentation(token)... + return 2 + if tag is 'CATCH' and @tag(i + 2) in ['TERMINATOR', 'FINALLY'] + tokens.splice i + 2, 0, @indentation(token)... + return 4 + if include(SINGLE_LINERS, tag) and @tag(i + 1) isnt 'INDENT' and + not (tag is 'ELSE' and @tag(i + 1) is 'IF') + starter = tag + [indent, outdent] = @indentation token + indent.fromThen = true if starter is 'THEN' + indent.generated = outdent.generated = true + tokens.splice i + 1, 0, indent + condition = (token, i) -> + token[1] isnt ';' and include(SINGLE_CLOSERS, token[0]) and + not (token[0] is 'ELSE' and starter not in ['IF', 'THEN']) + action = (token, i) -> + @tokens.splice (if @tag(i - 1) is ',' then i - 1 else i), 0, outdent + @detectEnd i + 2, condition, action + tokens.splice i, 1 if tag is 'THEN' + return 1 + return 1 + + # Tag postfix conditionals as such, so that we can parse them with a + # different precedence. + tagPostfixConditionals: -> + condition = (token, i) -> token[0] in ['TERMINATOR', 'INDENT'] + @scanTokens (token, i) -> + return 1 unless token[0] in ['IF', 'UNLESS'] + original = token + @detectEnd i + 1, condition, (token, i) -> + original[0] = 'POST_' + original[0] if token[0] isnt 'INDENT' + 1 + + # Ensure that all listed pairs of tokens are correctly balanced throughout + # the course of the token stream. + ensureBalance: (pairs) -> + levels = {} + openLine = {} + @scanTokens (token, i) -> + [tag] = token + for [open, close] in pairs + levels[open] |= 0 + if tag is open + openLine[open] = token[2] if levels[open] is 0 + levels[open] += 1 + else if tag is close + levels[open] -= 1 + throw Error "too many #{token[1]} on line #{token[2] + 1}" if levels[open] < 0 + 1 + unclosed = key for all key, value of levels when value > 0 + if unclosed.length + throw Error "unclosed #{ open = unclosed[0] } on line #{openLine[open] + 1}" + + # We'd like to support syntax like this: + # + # el.click((event) -> + # el.hide()) + # + # In order to accomplish this, move outdents that follow closing parens + # inwards, safely. The steps to accomplish this are: + # + # 1. Check that all paired tokens are balanced and in order. + # 2. Rewrite the stream with a stack: if you see an `EXPRESSION_START`, add it + # to the stack. If you see an `EXPRESSION_END`, pop the stack and replace + # it with the inverse of what we've just popped. + # 3. Keep track of "debt" for tokens that we manufacture, to make sure we end + # up balanced in the end. + # 4. Be careful not to alter array or parentheses delimiters with overzealous + # rewriting. + rewriteClosingParens: -> + stack = [] + debt = {} + (debt[key] = 0) for all key of INVERSES + @scanTokens (token, i, tokens) -> + if include EXPRESSION_START, tag = token[0] + stack.push token + return 1 + return 1 unless include EXPRESSION_END, tag + if debt[inv = INVERSES[tag]] > 0 + debt[inv] -= 1 + tokens.splice i, 1 + return 0 + match = stack.pop() + mtag = match[0] + oppos = INVERSES[mtag] + return 1 if tag is oppos + debt[mtag] += 1 + val = [oppos, if mtag is 'INDENT' then match[1] else oppos] + if @tag(i + 2) is mtag + tokens.splice i + 3, 0, val + stack.push match + else + tokens.splice i, 0, val + 1 + + # Generate the indentation tokens, based on another token on the same line. + indentation: (token) -> + [['INDENT', 2, token[2]], ['OUTDENT', 2, token[2]]] + + # Look up a tag by token index. + tag: (i) -> @tokens[i]?[0] + +# Constants +# --------- + +# List of the token pairs that must be balanced. +BALANCED_PAIRS = [ + ['(', ')'] + ['[', ']'] + ['{', '}'] + ['INDENT', 'OUTDENT'], + ['CALL_START', 'CALL_END'] + ['PARAM_START', 'PARAM_END'] + ['INDEX_START', 'INDEX_END'] +] + +# The inverse mappings of `BALANCED_PAIRS` we're trying to fix up, so we can +# look things up from either end. +INVERSES = {} + +# The tokens that signal the start/end of a balanced pair. +EXPRESSION_START = [] +EXPRESSION_END = [] + +for [left, rite] in BALANCED_PAIRS + EXPRESSION_START.push INVERSES[rite] = left + EXPRESSION_END .push INVERSES[left] = rite + +# Tokens that indicate the close of a clause of an expression. +EXPRESSION_CLOSE = ['CATCH', 'WHEN', 'ELSE', 'FINALLY'].concat EXPRESSION_END + +# Tokens that, if followed by an `IMPLICIT_CALL`, indicate a function invocation. +IMPLICIT_FUNC = ['IDENTIFIER', 'SUPER', ')', 'CALL_END', ']', 'INDEX_END', '@', 'THIS'] + +# If preceded by an `IMPLICIT_FUNC`, indicates a function invocation. +IMPLICIT_CALL = [ + 'IDENTIFIER', 'NUMBER', 'STRING', 'JS', 'REGEX', 'NEW', 'PARAM_START', 'CLASS' + 'IF', 'UNLESS', 'TRY', 'SWITCH', 'THIS', 'BOOL', 'UNARY', + '@', '->', '=>', '[', '(', '{', '--', '++' +] + +IMPLICIT_UNSPACED_CALL = ['+', '-'] + +# Tokens indicating that the implicit call must enclose a block of expressions. +IMPLICIT_BLOCK = ['->', '=>', '{', '[', ','] + +# Tokens that always mark the end of an implicit call for single-liners. +IMPLICIT_END = ['POST_IF', 'POST_UNLESS', 'FOR', 'WHILE', 'UNTIL', 'LOOP', 'TERMINATOR', 'INDENT'] + +# Single-line flavors of block expressions that have unclosed endings. +# The grammar can't disambiguate them, so we insert the implicit indentation. +SINGLE_LINERS = ['ELSE', '->', '=>', 'TRY', 'FINALLY', 'THEN'] +SINGLE_CLOSERS = ['TERMINATOR', 'CATCH', 'FINALLY', 'ELSE', 'OUTDENT', 'LEADING_WHEN'] + +# Tokens that end a line. +LINEBREAKS = ['TERMINATOR', 'INDENT', 'OUTDENT'] diff --git a/node_modules/jade/support/coffee-script/src/scope.coffee b/node_modules/jade/support/coffee-script/src/scope.coffee new file mode 100644 index 0000000..3a1aad3 --- /dev/null +++ b/node_modules/jade/support/coffee-script/src/scope.coffee @@ -0,0 +1,109 @@ +# The **Scope** class regulates lexical scoping within CoffeeScript. As you +# generate code, you create a tree of scopes in the same shape as the nested +# function bodies. Each scope knows about the variables declared within it, +# and has a reference to its parent enclosing scope. In this way, we know which +# variables are new and need to be declared with `var`, and which are shared +# with the outside. + +# Import the helpers we plan to use. +{extend, last} = require './helpers' + +exports.Scope = class Scope + + # The top-level **Scope** object. + @root: null + + # Initialize a scope with its parent, for lookups up the chain, + # as well as a reference to the **Expressions** node is belongs to, which is + # where it should declare its variables, and a reference to the function that + # it wraps. + constructor: (@parent, @expressions, @method) -> + @variables = {'arguments'} + if @parent + @garbage = @parent.garbage + else + @garbage = [] + Scope.root = this + + # Create a new garbage level + startLevel: -> + @garbage.push [] + + # Return to the previous garbage level and erase referenced temporary + # variables in current level from scope. + endLevel: -> + vars = @variables + (vars[name] = 'reuse') for name in @garbage.pop() when vars[name] is 'var' + + # Look up a variable name in lexical scope, and declare it if it does not + # already exist. + find: (name, options) -> + return true if @check name, options + @variables[name] = 'var' + false + + # Test variables and return true the first time fn(v, k) returns true + any: (fn) -> + for v, k of @variables when fn(v, k) + return true + return false + + # Reserve a variable name as originating from a function parameter for this + # scope. No `var` required for internal references. + parameter: (name) -> + @variables[name] = 'param' + + # Just check to see if a variable has already been declared, without reserving, + # walks up to the root scope. + check: (name, options) -> + immediate = Object::hasOwnProperty.call @variables, name + return immediate if immediate or options?.immediate + !!@parent?.check name + + # Generate a temporary variable name at the given index. + temporary: (type, index) -> + if type.length > 1 + '_' + type + if index > 1 then index else '' + else + '_' + (index + parseInt type, 36).toString(36).replace /\d/g, 'a' + + # If we need to store an intermediate result, find an available name for a + # compiler-generated variable. `_var`, `_var2`, and so on... + freeVariable: (type) -> + index = 0 + index++ while @check(temp = @temporary type, index) and @variables[temp] isnt 'reuse' + @variables[temp] = 'var' + last(@garbage).push temp if @garbage.length + temp + + # Ensure that an assignment is made at the top of this scope + # (or at the top-level scope, if requested). + assign: (name, value) -> + @variables[name] = value: value, assigned: true + + # Does this scope reference any variables that need to be declared in the + # given function body? + hasDeclarations: (body) -> + body is @expressions and @any (k, val) -> val in ['var', 'reuse'] + + # Does this scope reference any assignments that need to be declared at the + # top of the given function body? + hasAssignments: (body) -> + body is @expressions and @any (k, val) -> val.assigned + + # Return the list of variables first declared in this scope. + declaredVariables: -> + (key for key, val of @variables when val in ['var', 'reuse']).sort() + + # Return the list of assignments that are supposed to be made at the top + # of this scope. + assignedVariables: -> + "#{key} = #{val.value}" for key, val of @variables when val.assigned + + # Compile the JavaScript for all of the variable declarations in this scope. + compiledDeclarations: -> + @declaredVariables().join ', ' + + # Compile the JavaScript forall of the variable assignments in this scope. + compiledAssignments: -> + @assignedVariables().join ', ' diff --git a/node_modules/jade/support/coffee-script/test/test.html b/node_modules/jade/support/coffee-script/test/test.html new file mode 100644 index 0000000..fff780c --- /dev/null +++ b/node_modules/jade/support/coffee-script/test/test.html @@ -0,0 +1,95 @@ + + + + + CoffeeScript Test Suite + + + + + +

    CoffeeScript Test Suite

    +
    
    +
    +  
    +
    +
    +
    \ No newline at end of file
    diff --git a/node_modules/jade/support/coffee-script/test/test_arguments.coffee b/node_modules/jade/support/coffee-script/test/test_arguments.coffee
    new file mode 100644
    index 0000000..a45044b
    --- /dev/null
    +++ b/node_modules/jade/support/coffee-script/test/test_arguments.coffee
    @@ -0,0 +1,43 @@
    +area = (x, y, x1, y1) ->
    +  (x - x1) * (x - y1)
    +
    +x  = y  = 10
    +x1 = y1 = 20
    +
    +ok area(x, y, x1, y1) is 100
    +
    +# ok(area(x, y,
    +#            x1, y1) is 100)
    +
    +ok(area(
    +  x
    +  y
    +  x1
    +  y1
    +) is 100)
    +
    +
    +sumOfArgs = ->
    +  sum = 0
    +  sum += val for val in arguments
    +  sum
    +
    +ok sumOfArgs(1, 2, 3, 4, 5) is 15
    +
    +
    +((@arg) ->).call context = {}, 1
    +ok context.arg is 1
    +
    +((splat..., @arg) ->).call context, 1, 2, 3
    +ok context.arg is 3
    +
    +((@arg...) ->).call context, 1, 2, 3
    +ok context.arg.join ' ' is '1 2 3'
    +
    +class Klass
    +  constructor: (@one, @two) ->
    +
    +obj = new Klass 1, 2
    +
    +ok obj.one is 1
    +ok obj.two is 2
    \ No newline at end of file
    diff --git a/node_modules/jade/support/coffee-script/test/test_assignment.coffee b/node_modules/jade/support/coffee-script/test/test_assignment.coffee
    new file mode 100644
    index 0000000..00d3e10
    --- /dev/null
    +++ b/node_modules/jade/support/coffee-script/test/test_assignment.coffee
    @@ -0,0 +1,33 @@
    +# Can assign the result of a try/catch block.
    +result = try
    +  nonexistent * missing
    +catch error
    +  true
    +
    +result2 = try nonexistent * missing catch error then true
    +
    +ok result is true and result2 is true
    +
    +
    +# Can assign a conditional statement.
    +getX = -> 10
    +
    +if x = getX() then 100
    +
    +ok x is 10
    +
    +x = if getX() then 100
    +
    +ok x is 100
    +
    +
    +# This-assignment.
    +tester = ->
    +  @example = -> 'example function'
    +  this
    +
    +ok tester().example() is 'example function'
    +
    +
    +try throw CoffeeScript.tokens 'in = 1'
    +catch e then eq e.message, 'Reserved word "in" on line 1 can\'t be assigned'
    diff --git a/node_modules/jade/support/coffee-script/test/test_break.coffee b/node_modules/jade/support/coffee-script/test/test_break.coffee
    new file mode 100644
    index 0000000..7a6219f
    --- /dev/null
    +++ b/node_modules/jade/support/coffee-script/test/test_break.coffee
    @@ -0,0 +1,28 @@
    +# Test with break at the top level.
    +array = [1,2,3]
    +callWithLambda = (l) -> null
    +for i in array
    +  result = callWithLambda(->)
    +  if i == 2
    +    puts "i = 2"
    +  else
    +    break
    +
    +ok result is null
    +
    +
    +# Test with break *not* at the top level.
    +someFunc = (input) ->
    +  takesLambda = (l) -> null
    +  for i in [1,2]
    +    result = takesLambda(->)
    +    if input == 1
    +      return 1
    +    else
    +      break
    +
    +  return 2
    +
    +ok someFunc(1) is 1
    +ok someFunc(2) is 2
    +
    diff --git a/node_modules/jade/support/coffee-script/test/test_chaining.coffee b/node_modules/jade/support/coffee-script/test/test_chaining.coffee
    new file mode 100644
    index 0000000..7154a83
    --- /dev/null
    +++ b/node_modules/jade/support/coffee-script/test/test_chaining.coffee
    @@ -0,0 +1,56 @@
    +# Basic chained function calls.
    +identityWrap = (x) ->
    +  -> x
    +
    +result = identityWrap(identityWrap(true))()()
    +
    +ok result
    +
    +
    +# Chained accesses split on period/newline, backwards and forwards.
    +str = 'god'
    +
    +result = str.
    +  split('').
    +  reverse().
    +  reverse().
    +  reverse()
    +
    +ok result.join('') is 'dog'
    +
    +result = str
    +  .split('')
    +  .reverse()
    +  .reverse()
    +  .reverse()
    +
    +ok result.join('') is 'dog'
    +
    +
    +# Newline suppression for operators.
    +six =
    +  1 +
    +  2 +
    +  3
    +
    +ok six is 6
    +
    +
    +# Ensure that indented array literals don't trigger whitespace rewriting.
    +func = () ->
    +  ok arguments.length is 1
    +
    +func(
    +  [[[[[],
    +                []],
    +              [[]]]],
    +    []])
    +
    +id = (x) -> x
    +
    +greeting = id(
    +              """
    +              Hello
    +              """)
    +
    +ok greeting is "Hello"
    diff --git a/node_modules/jade/support/coffee-script/test/test_classes.coffee b/node_modules/jade/support/coffee-script/test/test_classes.coffee
    new file mode 100644
    index 0000000..ea1df23
    --- /dev/null
    +++ b/node_modules/jade/support/coffee-script/test/test_classes.coffee
    @@ -0,0 +1,291 @@
    +# Test classes with a four-level inheritance chain.
    +class Base
    +  func: (string) ->
    +    "zero/#{string}"
    +
    +  @static: (string) ->
    +    "static/#{string}"
    +
    +class FirstChild extends Base
    +  func: (string) ->
    +    super('one/') + string
    +
    +SecondChild = class extends FirstChild
    +  func: (string) ->
    +    super('two/') + string
    +
    +thirdCtor = ->
    +  @array = [1, 2, 3]
    +
    +class ThirdChild extends SecondChild
    +  constructor: thirdCtor
    +
    +  # Gratuitous comment for testing.
    +  func: (string) ->
    +    super('three/') + string
    +
    +result = (new ThirdChild).func 'four'
    +
    +ok result is 'zero/one/two/three/four'
    +ok Base.static('word') is 'static/word'
    +
    +FirstChild::func = (string) ->
    +  super('one/').length + string
    +
    +result = (new ThirdChild).func 'four'
    +
    +ok result is '9two/three/four'
    +
    +ok (new ThirdChild).array.join(' ') is '1 2 3'
    +
    +
    +class TopClass
    +  constructor: (arg) ->
    +    @prop = 'top-' + arg
    +
    +class SuperClass extends TopClass
    +  constructor: (arg) ->
    +    super 'super-' + arg
    +
    +class SubClass extends SuperClass
    +  constructor: ->
    +    super 'sub'
    +
    +ok (new SubClass).prop is 'top-super-sub'
    +
    +
    +class OneClass
    +  @new: 'new'
    +  function: 'function'
    +  constructor: (name) -> @name = name
    +
    +class TwoClass extends OneClass
    +
    +Function.prototype.new = -> new this arguments...
    +
    +ok (TwoClass.new('three')).name is 'three'
    +ok (new OneClass).function is 'function'
    +ok OneClass.new is 'new'
    +
    +delete Function.prototype.new
    +
    +
    +# And now the same tests, but written in the manual style:
    +Base = ->
    +Base::func = (string) ->
    +  'zero/' + string
    +Base::['func-func'] = (string) ->
    +  "dynamic-#{string}"
    +
    +FirstChild = ->
    +FirstChild extends Base
    +FirstChild::func = (string) ->
    +  super('one/') + string
    +
    +SecondChild = ->
    +SecondChild extends FirstChild
    +SecondChild::func = (string) ->
    +  super('two/') + string
    +
    +ThirdChild = ->
    +  @array = [1, 2, 3]
    +  this
    +ThirdChild extends SecondChild
    +ThirdChild::func = (string) ->
    +  super('three/') + string
    +
    +result = (new ThirdChild).func 'four'
    +
    +ok result is 'zero/one/two/three/four'
    +
    +ok (new ThirdChild)['func-func']('thing') is 'dynamic-thing'
    +
    +
    +TopClass = (arg) ->
    +  @prop = 'top-' + arg
    +  this
    +
    +SuperClass = (arg) ->
    +  super 'super-' + arg
    +  this
    +
    +SubClass = ->
    +  super 'sub'
    +  this
    +
    +SuperClass extends TopClass
    +SubClass extends SuperClass
    +
    +ok (new SubClass).prop is 'top-super-sub'
    +
    +
    +# '@' referring to the current instance, and not being coerced into a call.
    +class ClassName
    +  amI: ->
    +    @ instanceof ClassName
    +
    +obj = new ClassName
    +ok obj.amI()
    +
    +
    +# super() calls in constructors of classes that are defined as object properties.
    +class Hive
    +  constructor: (name) -> @name = name
    +
    +class Hive.Bee extends Hive
    +  constructor: (name) -> super
    +
    +maya = new Hive.Bee 'Maya'
    +ok maya.name is 'Maya'
    +
    +
    +# Class with JS-keyword properties.
    +class Class
    +  class: 'class'
    +  name: -> @class
    +
    +instance = new Class
    +ok instance.class is 'class'
    +ok instance.name() is 'class'
    +
    +
    +# Classes with methods that are pre-bound to the instance.
    +# ... or statically, to the class.
    +class Dog
    +
    +  constructor: (name) ->
    +    @name = name
    +
    +  bark: =>
    +    "#{@name} woofs!"
    +
    +  @static: =>
    +    new this('Dog')
    +
    +spark = new Dog('Spark')
    +fido  = new Dog('Fido')
    +fido.bark = spark.bark
    +
    +ok fido.bark() is 'Spark woofs!'
    +
    +obj = func: Dog.static
    +
    +ok obj.func().name is 'Dog'
    +
    +
    +# Testing a bound function in a bound function.
    +class Mini
    +  num: 10
    +  generate: =>
    +    for i in [1..3]
    +      =>
    +        @num
    +
    +m = new Mini
    +ok (func() for func in m.generate()).join(' ') is '10 10 10'
    +
    +
    +# Testing a contructor called with varargs.
    +class Connection
    +  constructor: (one, two, three) ->
    +    [@one, @two, @three] = [one, two, three]
    +
    +  out: ->
    +    "#{@one}-#{@two}-#{@three}"
    +
    +list = [3, 2, 1]
    +conn = new Connection list...
    +ok conn instanceof Connection
    +ok conn.out() is '3-2-1'
    +
    +
    +# Test calling super and passing along all arguments.
    +class Parent
    +  method: (args...) -> @args = args
    +
    +class Child extends Parent
    +  method: -> super
    +
    +c = new Child
    +c.method 1, 2, 3, 4
    +ok c.args.join(' ') is '1 2 3 4'
    +
    +
    +# Test `extended` callback.
    +class Base
    +  @extended: (subclass) ->
    +    for key, value of @
    +      subclass[key] = value
    +
    +class Element extends Base
    +  @fromHTML: (html) ->
    +    node = "..."
    +    new @(node)
    +
    +  constructor: (node) ->
    +    @node = node
    +
    +ok Element.extended is Base.extended
    +ok Element.__super__ is Base.prototype
    +
    +class MyElement extends Element
    +
    +ok MyElement.extended is Base.extended
    +ok MyElement.fromHTML is Element.fromHTML
    +ok MyElement.__super__ is Element.prototype
    +
    +
    +# Test classes wrapped in decorators.
    +func = (klass) ->
    +  klass::prop = 'value'
    +  klass
    +
    +func class Test
    +  prop2: 'value2'
    +
    +ok (new Test).prop  is 'value'
    +ok (new Test).prop2 is 'value2'
    +
    +
    +# Test anonymous classes.
    +obj =
    +  klass: class
    +    method: -> 'value'
    +
    +instance = new obj.klass
    +ok instance.method() is 'value'
    +
    +
    +# Implicit objects as static properties.
    +class Static
    +  @static:
    +    one: 1
    +    two: 2
    +
    +ok Static.static.one is 1
    +ok Static.static.two is 2
    +
    +
    +# Nothing classes.
    +c = class
    +ok c instanceof Function
    +
    +
    +# Classes with value'd constructors.
    +counter = 0
    +classMaker = ->
    +  counter += 1
    +  inner = counter
    +  ->
    +    @value = inner
    +
    +class One
    +  constructor: classMaker()
    +
    +class Two
    +  constructor: classMaker()
    +
    +ok (new One).value is 1
    +ok (new Two).value is 2
    +ok (new One).value is 1
    +ok (new Two).value is 2
    diff --git a/node_modules/jade/support/coffee-script/test/test_comments.coffee b/node_modules/jade/support/coffee-script/test/test_comments.coffee
    new file mode 100644
    index 0000000..7743e1b
    --- /dev/null
    +++ b/node_modules/jade/support/coffee-script/test/test_comments.coffee
    @@ -0,0 +1,166 @@
    +# comment before a ...
    +
    +###
    +... block comment.
    +###
    +
    +
    +  # comment
    +func = ->
    +# comment
    +  false
    +  false   # comment
    +  false
    +
    +# comment
    +  true
    +
    +switch 'string'
    +  # comment
    +  when false then something()
    +  # comment
    +  when null
    +    somethingElse()
    +
    +->
    +  code()
    +  # comment
    +
    +ok func()
    +
    +func
    +func
    +# Line3
    +
    +obj = {
    +# comment
    +  # comment
    +    # comment
    +  one: 1
    +# comment
    +  two: 2
    +    # comment
    +}
    +
    +result = if true # comment
    +  false
    +
    +ok not result
    +
    +result = if false
    +  false
    +else # comment
    +  45
    +
    +ok result is 45
    +
    +
    +test =
    +  'test ' +
    +  'test ' + # comment
    +  'test'
    +
    +ok test is 'test test test'
    +
    +###
    +  This is a here-comment.
    +  Kind of like a heredoc.
    +###
    +
    +func = ->
    +  ###
    +  Another block comment.
    +  ###
    +  code
    +
    +func = ->
    +  one = ->
    +    two = ->
    +      three = ->
    +  ###
    +  block.
    +  ###
    +  four = ->
    +
    +fn1 = ->
    +  oneLevel = null
    +###
    +This isn't fine.
    +###
    +
    +ok ok
    +
    +obj = {
    +  a: 'b'
    +  ###
    +  comment
    +  ###
    +  c: 'd'
    +}
    +
    +arr = [
    +  1, 2, 3,
    +  ###
    +  four
    +  ###
    +  5, 6, 7
    +]
    +
    +# Spaced comments in if / elses.
    +result = if false
    +  1
    +
    +# comment
    +else if false
    +  2
    +
    +# comment
    +else
    +  3
    +
    +ok result is 3
    +
    +
    +result = switch 'z'
    +  when 'z' then 7
    +# comment
    +ok result is 7
    +
    +
    +# Trailing-line comment before an outdent.
    +func = ->
    +  if true
    +    true # comment
    +  7
    +
    +ok func() is 7
    +
    +
    +# Trailing herecomment in a function.
    +fn = ->
    +  code
    +  ###
    +  debug code commented
    +  ###
    +
    +fn2 = ->
    +
    +
    +class A
    +  b: ->
    +
    +  ###
    +  Comment
    +  ###
    +  c: ->
    +
    +ok A.prototype.c instanceof Function
    +
    +class A
    +  ###
    +  Comment
    +  ###
    +  b: ->
    +  c: ->
    +
    +ok A.prototype.b instanceof Function
    diff --git a/node_modules/jade/support/coffee-script/test/test_compilation.coffee b/node_modules/jade/support/coffee-script/test/test_compilation.coffee
    new file mode 100644
    index 0000000..ad8c65b
    --- /dev/null
    +++ b/node_modules/jade/support/coffee-script/test/test_compilation.coffee
    @@ -0,0 +1,11 @@
    +# Ensure that carriage returns don't break compilation on Windows.
    +eq CoffeeScript.compile('one\r\ntwo', bare: on), 'one;\ntwo;'
    +
    +# `globals: on` removes `var`s
    +eq CoffeeScript.compile('x = y', bare: on, globals: on), 'x = y;'
    +
    +ok 'passed' is CoffeeScript.eval '"passed"', bare: on, fileName: 'test'
    +
    +#750
    +try ok not CoffeeScript.nodes 'f(->'
    +catch e then eq e.message, 'unclosed CALL_START on line 1'
    diff --git a/node_modules/jade/support/coffee-script/test/test_compound_assignment.coffee b/node_modules/jade/support/coffee-script/test/test_compound_assignment.coffee
    new file mode 100644
    index 0000000..cc2fe58
    --- /dev/null
    +++ b/node_modules/jade/support/coffee-script/test/test_compound_assignment.coffee
    @@ -0,0 +1,26 @@
    +num = 10
    +num -= 5
    +eq num, 5
    +
    +num *= 10
    +eq num, 50
    +
    +num /= 10
    +eq num, 5
    +
    +num %= 3
    +eq num, 2
    +
    +val = false
    +val ||= 'value'
    +val ||= 'eulav'
    +eq val, 'value'
    +
    +val &&= 'rehto'
    +val &&= 'other'
    +eq val, 'other'
    +
    +val = null
    +val ?= 'value'
    +val ?= 'eulav'
    +eq val, 'value'
    diff --git a/node_modules/jade/support/coffee-script/test/test_comprehensions.coffee b/node_modules/jade/support/coffee-script/test/test_comprehensions.coffee
    new file mode 100644
    index 0000000..2aff0bf
    --- /dev/null
    +++ b/node_modules/jade/support/coffee-script/test/test_comprehensions.coffee
    @@ -0,0 +1,172 @@
    +# Basic array comprehensions.
    +nums =    n * n for n in [1, 2, 3] when n % 2 isnt 0
    +results = n * 2 for n in nums
    +
    +ok results.join(',') is '2,18'
    +
    +
    +# Basic object comprehensions.
    +obj   = {one: 1, two: 2, three: 3}
    +names = prop + '!' for prop of obj
    +odds  = prop + '!' for prop, value of obj when value % 2 isnt 0
    +
    +ok names.join(' ') is "one! two! three!"
    +ok odds.join(' ')  is "one! three!"
    +
    +
    +# Basic range comprehensions.
    +nums = i * 3 for i in [1..3]
    +
    +negs = x for x in [-20..-5*2]
    +negs = negs[0..2]
    +
    +result = nums.concat(negs).join(', ')
    +
    +ok result is '3, 6, 9, -20, -19, -18'
    +ok i is 3
    +ok x is -10
    +
    +
    +# With range comprehensions, you can loop in steps.
    +results = x for x in [0...15] by 5
    +ok results.join(' ') is '0 5 10'
    +
    +results = x for x in [0..100] by 10
    +ok results.join(' ') is '0 10 20 30 40 50 60 70 80 90 100'
    +
    +
    +# And can loop downwards, with a negative step.
    +results = x for x in [5..1]
    +
    +ok results.join(' ') is '5 4 3 2 1'
    +ok results.join(' ') is [(10-5)..(-2+3)].join(' ')
    +
    +results = x for x in [10..1]
    +ok results.join(' ') is [10..1].join(' ')
    +
    +results = x for x in [10...0] by -2
    +ok results.join(' ') is [10, 8, 6, 4, 2].join(' ')
    +
    +
    +# Multiline array comprehension with filter.
    +evens = for num in [1, 2, 3, 4, 5, 6] when num % 2 is 0
    +           num *= -1
    +           num -= 2
    +           num * -1
    +
    +ok evens.join(', ') is '4, 6, 8'
    +
    +
    +# The in operator still works, standalone.
    +ok 2 of evens
    +
    +
    +# Ensure that the closure wrapper preserves local variables.
    +obj = {}
    +
    +for method in ['one', 'two', 'three']
    +  obj[method] = ->
    +    "I'm " + method
    +
    +ok obj.one()   is "I'm one"
    +ok obj.two()   is "I'm two"
    +ok obj.three() is "I'm three"
    +
    +i = 0
    +for i in [1..3]
    +  -> 'func'
    +  break if false
    +ok i is 3
    +
    +
    +# Ensure that local variables are closed over for range comprehensions.
    +funcs = for i in [1..3]
    +  -> -i
    +
    +ok (func() for func in funcs).join(' ') is '-1 -2 -3'
    +ok i is 3
    +
    +
    +# Ensure that closing over local variables doesn't break scoping laws.
    +for i in [0]
    +  count = 0
    +  i = 50
    +  ->
    +ok count is 0
    +ok i is 50
    +
    +
    +# Even when referenced in the filter.
    +list = ['one', 'two', 'three']
    +
    +methods = for num, i in list when num isnt 'two' and i isnt 1
    +  -> num + ' ' + i
    +
    +ok methods.length is 2
    +ok methods[0]() is 'one 0'
    +ok methods[1]() is 'three 2'
    +
    +
    +# Naked ranges are expanded into arrays.
    +array = [0..10]
    +ok(num % 2 is 0 for num in array by 2)
    +
    +
    +# Nested comprehensions.
    +multiLiner =
    +  for x in [3..5]
    +    for y in [3..5]
    +      [x, y]
    +
    +singleLiner =
    +  [x, y] for y in [3..5] for x in [3..5]
    +
    +ok multiLiner.length is singleLiner.length
    +ok 5 is multiLiner[2][2][1]
    +ok 5 is singleLiner[2][2][1]
    +
    +
    +# Comprehensions within parentheses.
    +result = null
    +store = (obj) -> result = obj
    +store (x * 2 for x in [3, 2, 1])
    +
    +ok result.join(' ') is '6 4 2'
    +
    +
    +# Closure-wrapped comprehensions that refer to the "arguments" object.
    +expr = ->
    +  result = item * item for item in arguments
    +
    +ok expr(2, 4, 8).join(' ') is '4 16 64'
    +
    +
    +# Fast object comprehensions over all properties, including prototypal ones.
    +class Cat
    +  constructor: -> @name = 'Whiskers'
    +  breed: 'tabby'
    +  hair:  'cream'
    +
    +whiskers = new Cat
    +own = value for key, value of whiskers
    +all = value for all key, value of whiskers
    +
    +ok own.join(' ') is 'Whiskers'
    +ok all.sort().join(' ') is 'Whiskers cream tabby'
    +
    +
    +# Optimized range comprehensions.
    +exxes = 'x' for [0...10]
    +ok exxes.join(' ') is 'x x x x x x x x x x'
    +
    +
    +# Comprehensions safely redeclare parameters if they're not present in closest
    +# scope.
    +rule = (x) -> x
    +
    +learn = ->
    +  rule for rule in [1, 2, 3]
    +
    +ok learn().join(' ') is '1 2 3'
    +
    +ok rule(101) is 101
    \ No newline at end of file
    diff --git a/node_modules/jade/support/coffee-script/test/test_existence.coffee b/node_modules/jade/support/coffee-script/test/test_existence.coffee
    new file mode 100644
    index 0000000..e0687bf
    --- /dev/null
    +++ b/node_modules/jade/support/coffee-script/test/test_existence.coffee
    @@ -0,0 +1,145 @@
    +ok(if mySpecialVariable? then false else true)
    +
    +mySpecialVariable = false
    +
    +ok(if mySpecialVariable? then true else false)
    +
    +
    +# Existential assignment.
    +a = 5
    +a = null
    +a ?= 10
    +b ?= 10
    +
    +ok a is 10 and b is 10
    +
    +
    +# The existential operator.
    +z = null
    +x = z ? "EX"
    +ok z is null and x is "EX"
    +
    +i = 9
    +func = -> i += 1
    +result = func() ? 101
    +ok result is 10
    +
    +# Only evaluate once.
    +counter = 0
    +getNextNode = ->
    +  throw "up" if counter
    +  counter++
    +
    +ok(if getNextNode()? then true else false)
    +
    +
    +# Existence chains, soaking up undefined properties:
    +obj =
    +  prop: "hello"
    +
    +eq obj?.prop, "hello"
    +eq obj?['prop'], "hello"
    +eq obj.prop?.length, 5
    +eq obj?.prop?['length'], 5
    +eq obj?.prop?.non?.existent?.property, undefined
    +
    +
    +# Soaks and caches method calls as well.
    +arr = ["--", "----"]
    +
    +eq arr.pop()?.length, 4
    +eq arr.pop()?.length, 2
    +eq arr.pop()?.length, undefined
    +eq arr.pop()?.length?.non?.existent()?.property, undefined
    +
    +
    +# Soaks method calls safely.
    +value = null
    +eq value?.toString().toLowerCase(), undefined
    +
    +value = 10
    +eq value?.toString().toLowerCase(), '10'
    +
    +eq 0.nothing?.property() or 101, 101
    +
    +counter = 0
    +func = ->
    +  counter += 1
    +  'prop'
    +obj =
    +  prop: -> this
    +  value: 25
    +
    +ok obj[func()]()[func()]()[func()]()?.value is 25
    +ok counter is 3
    +
    +
    +ident = (obj) -> obj
    +eq ident(non?.existent().method()), undefined, 'soaks inner values'
    +
    +
    +# Soaks constructor invocations.
    +a = 0
    +class Foo
    +  constructor: -> a += 1
    +  bar: "bat"
    +
    +ok (new Foo())?.bar is 'bat'
    +ok a is 1
    +
    +
    +ok not value?.property?, 'safely checks existence on soaks'
    +
    +
    +eq nothing?.value, undefined, 'safely calls values off of non-existent variables'
    +eq !nothing?.value and 1, 1,  'corresponding operators work as expected'
    +
    +
    +# Assign to the result of an exsitential operation with a minus.
    +x = null ? - 1
    +ok x is - 1
    +
    +
    +# Things that compile to ternaries should force parentheses, like operators do.
    +duration = if options?.animated then 150 else 0
    +ok duration is 0
    +
    +
    +# Function soaks.
    +plus1 = (x) -> x + 1
    +count = 0
    +obj = {
    +  counter: -> count += 1; this
    +  returnThis: -> this
    +}
    +
    +eq plus1?(41), 42
    +eq (plus1? 41), 42
    +eq plus2?(41), undefined
    +eq (plus2? 41), undefined
    +eq obj.returnThis?(), obj
    +eq obj.returnSelf?(), undefined
    +eq obj.returnThis?().flag = on, on
    +eq obj.returnSelf?().flag = on, undefined
    +eq obj.counter().counter().returnThis?(), obj
    +eq count, 2
    +
    +maybe_close = (f, arg) -> if typeof f is 'function' then () -> f(arg) else -1
    +
    +eq maybe_close(plus1, 41)?(), 42
    +eq (maybe_close plus1, 41)?(), 42
    +eq (maybe_close 'string', 41)?(), undefined
    +
    +eq 2?(3), undefined
    +eq new Number?(42) | 0, 42
    +eq new Bumper?(42) | 0, 0
    +
    +#726
    +eq calendar?[Date()], undefined
    +
    +#733
    +a = b: {c: null}
    +eq a.b?.c?(), undefined
    +a.b?.c or= (it) -> it
    +eq a.b?.c?(1), 1
    +eq a.b?.c?([2, 3]...), 2
    diff --git a/node_modules/jade/support/coffee-script/test/test_expressions.coffee b/node_modules/jade/support/coffee-script/test/test_expressions.coffee
    new file mode 100644
    index 0000000..9572a6c
    --- /dev/null
    +++ b/node_modules/jade/support/coffee-script/test/test_expressions.coffee
    @@ -0,0 +1,40 @@
    +# Ensure that we don't wrap Nodes that are "pureStatement" in a closure.
    +items = [1, 2, 3, "bacon", 4, 5]
    +
    +for item in items
    +  break if item is "bacon"
    +
    +findit = (items) ->
    +  for item in items
    +    return item if item is "bacon"
    +
    +ok findit(items) is "bacon"
    +
    +
    +# When when a closure wrapper is generated for expression conversion, make sure
    +# that references to "this" within the wrapper are safely converted as well.
    +obj = {
    +  num: 5
    +  func: ->
    +    this.result = if false
    +      10
    +    else
    +      "a"
    +      "b"
    +      this.num
    +}
    +
    +ok obj.num is obj.func()
    +ok obj.num is obj.result
    +
    +
    +# Should be able to look at prototypes on keywords.
    +obj =
    +  withAt:   -> @::prop
    +  withThis: -> this::prop
    +  proto:
    +    prop: 100
    +
    +obj.prototype = obj.proto
    +ok obj.withAt() is 100
    +ok obj.withThis() is 100
    \ No newline at end of file
    diff --git a/node_modules/jade/support/coffee-script/test/test_functions.coffee b/node_modules/jade/support/coffee-script/test/test_functions.coffee
    new file mode 100644
    index 0000000..c39e6c0
    --- /dev/null
    +++ b/node_modules/jade/support/coffee-script/test/test_functions.coffee
    @@ -0,0 +1,346 @@
    +x = 1
    +y = {}
    +y.x = -> 3
    +
    +ok x is 1
    +ok typeof(y.x) is 'function'
    +ok y.x instanceof Function
    +ok y.x() is 3
    +
    +
    +# The empty function should not cause a syntax error.
    +->
    +() ->
    +
    +
    +# Multiple nested function declarations mixed with implicit calls should not
    +# cause a syntax error.
    +(one) -> (two) -> three four, (five) -> six seven, eight, (nine) ->
    +
    +
    +obj = {
    +  name: 'Fred'
    +
    +  bound: ->
    +    (=> eq this, obj)()
    +
    +  unbound: ->
    +    (-> ok this isnt obj)()
    +
    +  nested: ->
    +    (=>
    +      (=>
    +        (=>
    +          eq this, obj
    +        )()
    +      )()
    +    )()
    +}
    +
    +obj.unbound()
    +obj.bound()
    +obj.nested()
    +
    +
    +# Python decorator style wrapper that memoizes any function
    +memoize = (fn) ->
    +  cache = {}
    +  self  = this
    +  (args...) ->
    +    key = args.toString()
    +    return cache[key] if cache[key]
    +    cache[key] = fn.apply(self, args)
    +
    +Math = {
    +  Add: (a, b) -> a + b
    +  AnonymousAdd: ((a, b) -> a + b)
    +  FastAdd: memoize (a, b) -> a + b
    +}
    +
    +ok Math.Add(5, 5) is 10
    +ok Math.AnonymousAdd(10, 10) is 20
    +ok Math.FastAdd(20, 20) is 40
    +
    +
    +# Parens are optional on simple function calls.
    +ok 100 > 1 if 1 > 0
    +ok true unless false
    +ok true for i in [1..3]
    +
    +okFunc = (f) -> ok(f())
    +okFunc -> true
    +
    +# Optional parens can be used in a nested fashion.
    +call = (func) -> func()
    +
    +result = call ->
    +  inner = call ->
    +    Math.Add(5, 5)
    +
    +ok result is 10
    +
    +
    +# More fun with optional parens.
    +fn = (arg) -> arg
    +
    +ok fn(fn {prop: 101}).prop is 101
    +
    +
    +# Multi-blocks with optional parens.
    +result = fn( ->
    +  fn ->
    +    "Wrapped"
    +)
    +
    +ok result()() is 'Wrapped'
    +
    +
    +# And even with strange things like this:
    +funcs  = [((x) -> x), ((x) -> x * x)]
    +result = funcs[1] 5
    +
    +ok result is 25
    +
    +result = ("hello".slice) 3
    +
    +ok result is 'lo'
    +
    +
    +# And with multiple single-line functions on the same line.
    +func = (x) -> (x) -> (x) -> x
    +ok func(1)(2)(3) is 3
    +
    +
    +# Ensure that functions with the same name don't clash with helper functions.
    +del = -> 5
    +ok del() is 5
    +
    +# Ensure that functions can have a trailing comma in their argument list
    +mult = (x, mids..., y) ->
    +  x *= n for n in mids
    +  x *= y
    +
    +ok mult(1, 2,) is 2
    +ok mult(1, 2, 3,) is 6
    +ok mult(10,[1..6]...,) is 7200
    +
    +
    +# Test for inline functions with parentheses and implicit calls.
    +combine = (func, num) -> func() * num
    +result  = combine (-> 1 + 2), 3
    +
    +ok result is 9
    +
    +
    +# Test for calls/parens/multiline-chains.
    +f = (x) -> x
    +result = (f 1).toString()
    +  .length
    +
    +ok result is 1
    +
    +
    +# Test implicit calls in functions in parens:
    +result = ((val) ->
    +  [].push val
    +  val
    +)(10)
    +
    +ok result is 10
    +
    +
    +# More paren compilation tests:
    +reverse = (obj) -> obj.reverse()
    +ok reverse([1, 2].concat 3).join(' ') is '3 2 1'
    +
    +# Passing multiple functions without paren-wrapping is legal, and should compile.
    +sum = (one, two) -> one() + two()
    +result = sum ->
    +  7 + 9
    +, ->
    +  1 + 3
    +
    +ok result is 20
    +
    +
    +# Implicit call with a trailing if statement as a param.
    +func = -> arguments[1]
    +result = func 'one', if false then 100 else 13
    +ok result is 13
    +
    +
    +# Test more function passing:
    +result = sum( ->
    +  1 + 2
    +, ->
    +  2 + 1
    +)
    +ok result is 6
    +
    +sum = (a, b) -> a + b
    +result = sum(1
    +, 2)
    +
    +ok result is 3
    +
    +
    +# This is a crazy one.
    +x = (obj, func) -> func obj
    +ident = (x) -> x
    +
    +result = x {one: ident 1}, (obj) ->
    +  inner = ident(obj)
    +  ident inner
    +
    +ok result.one is 1
    +
    +
    +# Assignment to a Object.prototype-named variable should not leak to outer scope.
    +# FIXME: fails on IE
    +(->
    +  constructor = 'word'
    +)()
    +
    +ok constructor isnt 'word'
    +
    +
    +# Trying an implicit object call with a trailing function.
    +a = null
    +meth = (arg, obj, func) -> a = [obj.a, arg, func()].join ' '
    +
    +meth 'apple', b: 1, a: 13, ->
    +  'orange'
    +
    +ok a is '13 apple orange'
    +
    +
    +# Ensure that empty functions don't return mistaken values.
    +obj =
    +  func: (@param, @rest...) ->
    +
    +ok obj.func(101, 102, 103, 104) is undefined
    +ok obj.param is 101
    +ok obj.rest.join(' ') is '102 103 104'
    +
    +
    +# `@` and `this` should both be able to invoke a method.
    +func          = (arg) -> ok arg is true
    +func.withAt   = -> @ true
    +func.withThis = -> this true
    +
    +func.withAt()
    +func.withThis()
    +
    +
    +# Ensure that constructors invoked with splats return a new object.
    +args = [1, 2, 3]
    +Type = (@args) ->
    +type = new Type args
    +
    +ok type and type instanceof Type
    +ok type.args and type.args instanceof Array
    +ok v is args[i] for v, i in type.args
    +
    +Type1 = (@a, @b, @c) ->
    +type1 = new Type1 args...
    +
    +ok type1 instanceof   Type1
    +eq type1.constructor, Type1
    +ok type1.a is args[0] and type1.b is args[1] and type1.c is args[2]
    +
    +
    +# Ensure that constructors invoked with splats cache the function.
    +called = 0
    +get = -> if called++ then false else class Type
    +new get() args...
    +
    +
    +# Chained blocks, with proper indentation levels:
    +counter =
    +  results: []
    +  tick: (func) ->
    +    @results.push func()
    +    this
    +
    +counter
    +  .tick ->
    +    3
    +  .tick ->
    +    2
    +  .tick ->
    +    1
    +
    +eq counter.results.join(' '), '3 2 1'
    +
    +
    +# Make incorrect indentation safe.
    +func = ->
    +  obj = {
    +          key: 10
    +        }
    +  obj.key - 5
    +
    +eq func(), 5
    +
    +
    +# Ensure that chained calls with indented implicit object literals below are
    +# alright.
    +result = null
    +obj =
    +  method: (val)  -> this
    +  second: (hash) -> result = hash.three
    +
    +
    +obj
    +  .method(
    +    101
    +  ).second(
    +    one:
    +      two: 2
    +    three: 3
    +  )
    +
    +eq result, 3
    +
    +
    +# Test newline-supressed call chains with nested functions.
    +obj  =
    +  call: -> this
    +func = ->
    +  obj
    +    .call ->
    +      one two
    +    .call ->
    +      three four
    +  101
    +
    +eq func(), 101
    +
    +
    +# `new` shouldn't add extra parens
    +ok new Date().constructor is Date
    +
    +
    +# `new` works against bare function
    +eq Date, new ->
    +  eq this, new => this
    +  Date
    +
    +
    +# Implicit objects with number arguments.
    +func = (x, y) -> y
    +obj =
    +  prop: func "a", 1
    +
    +ok obj.prop is 1
    +
    +
    +# Non-spaced unary and binary operators should cause a function call.
    +func = (val) -> val + 1
    +ok (func +5) is 6
    +ok (func -5) is -4
    +
    +
    +# Prefix unary assignment operators are allowed in parenless calls.
    +val = 5
    +ok (func --val) is 5
    diff --git a/node_modules/jade/support/coffee-script/test/test_helpers.coffee b/node_modules/jade/support/coffee-script/test/test_helpers.coffee
    new file mode 100644
    index 0000000..56a8017
    --- /dev/null
    +++ b/node_modules/jade/support/coffee-script/test/test_helpers.coffee
    @@ -0,0 +1,49 @@
    +{indexOf, include, starts, ends, compact, count, merge, extend, flatten, del, last} = CoffeeScript.helpers
    +
    +array  = [0..4]
    +string = array.join ''
    +object = {}
    +
    +# Test `indexOf`
    +eq 0, indexOf array, 0
    +eq 2, indexOf array, 2
    +eq 4, indexOf array, 4
    +eq(-1, indexOf array, 6)
    +
    +# Test `include`
    +ok include array, 0
    +ok include array, 2
    +ok include array, 4
    +ok not include array, 6
    +
    +# Test `starts`
    +ok starts string, '012'
    +ok starts string, '34', 3
    +ok not starts string, '42'
    +ok not starts string, '42', 6
    +
    +# Test `ends`
    +ok ends string, '234'
    +ok ends string, '01', 3
    +ok not ends string, '42'
    +ok not ends string, '42', 6
    +
    +# Test `merge`
    +merged = merge object, array
    +ok merged isnt object
    +eq merged[3], 3
    +
    +# Test `extend`
    +ok object is extend object, array
    +eq object[3], 3
    +
    +# Test `flatten`
    +eq "#{ flatten [0, [1, 2], 3, [4]] }", "#{ array }"
    +
    +# Test `del`
    +eq 1, del object, 1
    +ok 1 not of object
    +
    +# Test `last`
    +eq 4, last array
    +eq 2, last array, 2
    diff --git a/node_modules/jade/support/coffee-script/test/test_heredocs.coffee b/node_modules/jade/support/coffee-script/test/test_heredocs.coffee
    new file mode 100644
    index 0000000..330ecdf
    --- /dev/null
    +++ b/node_modules/jade/support/coffee-script/test/test_heredocs.coffee
    @@ -0,0 +1,111 @@
    +a = """
    +    basic heredoc
    +    on two lines
    +    """
    +
    +ok a is "basic heredoc\non two lines"
    +
    +
    +a = '''
    +    a
    +      "b
    +    c
    +    '''
    +
    +ok a is "a\n  \"b\nc"
    +
    +
    +a = """
    +a
    + b
    +  c
    +"""
    +
    +ok a is "a\n b\n  c"
    +
    +
    +a = '''one-liner'''
    +
    +ok a is 'one-liner'
    +
    +
    +a = """
    +      out
    +      here
    +"""
    +
    +ok a is "out\nhere"
    +
    +
    +a = '''
    +       a
    +     b
    +   c
    +    '''
    +
    +ok a is "    a\n  b\nc"
    +
    +
    +a = '''
    +a
    +
    +
    +b c
    +'''
    +
    +ok a is "a\n\n\nb c"
    +
    +
    +a = '''more"than"one"quote'''
    +
    +ok a is 'more"than"one"quote'
    +
    +
    +val = 10
    +
    +a = """
    +    basic heredoc #{val}
    +    on two lines
    +    """
    +
    +b = '''
    +    basic heredoc #{val}
    +    on two lines
    +    '''
    +
    +ok a is "basic heredoc 10\non two lines"
    +ok b is "basic heredoc \#{val}\non two lines"
    +
    +
    +a = '''here's an apostrophe'''
    +ok a is "here's an apostrophe"
    +
    +
    +# The indentation detector ignores blank lines without trailing whitespace
    +a = """
    +    one
    +    two
    +
    +    """
    +ok a is "one\ntwo\n"
    +
    +eq ''' line 0
    +  should not be relevant
    +    to the indent level
    +''', '
    + line 0\n
    +should not be relevant\n
    +  to the indent level
    +'
    +
    +eq ''' '\\\' ''', " '\\' "
    +eq """ "\\\" """, ' "\\" '
    +
    +eq '''  <- keep these spaces ->  ''', '  <- keep these spaces ->  '
    +
    +eq 'multiline nested "interpolations" work', """multiline #{
    +  "nested #{(->
    +    ok yes
    +    "\"interpolations\""
    +  )()}"
    +} work"""
    diff --git a/node_modules/jade/support/coffee-script/test/test_if.coffee b/node_modules/jade/support/coffee-script/test/test_if.coffee
    new file mode 100644
    index 0000000..42ba54b
    --- /dev/null
    +++ b/node_modules/jade/support/coffee-script/test/test_if.coffee
    @@ -0,0 +1,146 @@
    +a = b = d = true
    +c = false
    +
    +result = if a
    +  if b
    +    if c then false else
    +      if d
    +        true
    +
    +ok result
    +
    +
    +first = if false then false else second = if false then false else true
    +
    +ok first
    +ok second
    +
    +
    +result = if false
    +  false
    +else if NaN
    +  false
    +else
    +  true
    +
    +ok result
    +
    +
    +# Testing unless.
    +result = unless true
    +  10
    +else
    +  11
    +
    +ok result is 11
    +
    +
    +# Nested inline if statements.
    +echo = (x) -> x
    +result = if true then echo((if false then 'xxx' else 'y') + 'a')
    +ok result is 'ya'
    +
    +
    +# Testing inline funcs with inline if-elses.
    +func = -> if 1 < 0.5 then 1 else -1
    +ok func() is -1
    +
    +
    +# Testing empty or commented if statements ... should compile:
    +result = if false
    +else if false
    +else
    +
    +ok result is undefined
    +
    +result = if false
    +  # comment
    +else if true
    +  # comment
    +else
    +
    +ok result is undefined
    +
    +
    +# Return an if with no else.
    +func = ->
    +  return if false then callback()
    +
    +ok func() is undefined
    +
    +func = ->
    +  return unless false then 100 else -100
    +
    +ok func() is 100
    +
    +ident = (x) -> x
    +result = ident if false then 300 else 100
    +
    +ok result is 100
    +
    +
    +# If-to-ternary with instanceof requires parentheses (no comment).
    +if {} instanceof Object
    +  ok yes
    +else
    +  ok no
    +
    +try
    +  {} + {}
    +  ok yes
    +catch e
    +  ok no
    +
    +
    +# If-to-ternary as part of a larger operation requires parens.
    +x = 1
    +result = x + if false then 10 else 1
    +ok result is 2
    +
    +
    +# If/else indented within an assignment.
    +func = ->
    +  a =
    +    if false
    +      3
    +    else
    +      5
    +  101
    +  a
    +
    +ok func() is 5
    +
    +
    +# Unmatched 'then' should catch implicit calls.
    +i = 1
    +isTrue = (x) -> x is true
    +
    +if isTrue yes then i += 1
    +
    +ok i is 2
    +
    +# If/else with a suppressed indentation via assignment.
    +result =
    +  if      false then 10
    +  else if no    then 20
    +  else if 0     then 30
    +  else if NaN   then 40
    +  else               50 +
    +       if false then 10
    +       else          20
    +
    +ok result is 70
    +
    +
    +# Issue #738
    +func = if true then -> 1
    +eq func(), 1
    +
    +
    +# Issue #748. Trailing reserved identifiers.
    +obj = delete: true
    +
    +result = if obj.delete
    +  101
    +
    +ok result is 101
    diff --git a/node_modules/jade/support/coffee-script/test/test_importing.coffee b/node_modules/jade/support/coffee-script/test/test_importing.coffee
    new file mode 100644
    index 0000000..e069938
    --- /dev/null
    +++ b/node_modules/jade/support/coffee-script/test/test_importing.coffee
    @@ -0,0 +1,3 @@
    +# Check if we can import and execute a CoffeeScript-only module successfully.
    +if require?.extensions? or require?.registerExtension?
    +  ok require('./test_module').func() is "from over there"
    diff --git a/node_modules/jade/support/coffee-script/test/test_literals.coffee b/node_modules/jade/support/coffee-script/test/test_literals.coffee
    new file mode 100644
    index 0000000..b753b45
    --- /dev/null
    +++ b/node_modules/jade/support/coffee-script/test/test_literals.coffee
    @@ -0,0 +1,247 @@
    +a = [((x) -> x), ((x) -> x * x)]
    +
    +ok a.length is 2
    +
    +
    +neg = (3 -4)
    +
    +ok neg is -1
    +
    +
    +# Decimal number literals.
    +value = .25 + .75
    +ok value is 1
    +value = 0.0 + -.25 - -.75 + 0.0
    +ok value is 0.5
    +
    +# Decimals don't interfere with ranges.
    +ok [0..10].join(' ') is  '0 1 2 3 4 5 6 7 8 9 10'
    +ok [0...10].join(' ') is '0 1 2 3 4 5 6 7 8 9'
    +
    +
    +# Can call methods directly on numbers.
    +4.valueOf() is 4
    +
    +
    +func = ->
    +  return if true
    +
    +ok func() is undefined
    +
    +
    +trailingComma = [1, 2, 3,]
    +ok (trailingComma[0] is 1) and (trailingComma[2] is 3) and (trailingComma.length is 3)
    +
    +trailingComma = [
    +  1, 2, 3,
    +  4, 5, 6
    +  7, 8, 9,
    +]
    +(sum = (sum or 0) + n) for n in trailingComma
    +
    +trailingComma = {k1: "v1", k2: 4, k3: (-> true),}
    +ok trailingComma.k3() and (trailingComma.k2 is 4) and (trailingComma.k1 is "v1")
    +
    +
    +ok {a: (num) -> num is 10 }.a 10
    +
    +
    +moe = {
    +  name:  'Moe'
    +  greet: (salutation) ->
    +    salutation + " " + @name
    +  hello: ->
    +    @['greet'] "Hello"
    +  10: 'number'
    +}
    +
    +ok moe.hello() is "Hello Moe"
    +ok moe[10] is 'number'
    +
    +moe.hello = ->
    +  this['greet'] "Hello"
    +
    +ok moe.hello() is 'Hello Moe'
    +
    +
    +obj = {
    +  is:     -> yes,
    +  'not':  -> no,
    +}
    +
    +ok obj.is()
    +ok not obj.not()
    +
    +
    +# Top-level object literal doesn't break things.
    +obj: 1
    +
    +
    +# Funky indentation within non-comma-seperated arrays.
    +result = [['a']
    + {b: 'c'}]
    +
    +ok result[0][0] is 'a'
    +ok result[1]['b'] is 'c'
    +
    +
    +# Object literals should be able to include keywords.
    +obj = {class: 'höt'}
    +obj.function = 'dog'
    +
    +ok obj.class + obj.function is 'hötdog'
    +
    +
    +# But keyword assignment should be smart enough not to stringify variables.
    +func = ->
    +  this == 'this'
    +
    +ok func() is false
    +
    +
    +# New fancy implicit objects:
    +config =
    +  development:
    +    server: 'localhost'
    +    timeout: 10
    +
    +  production:
    +    server: 'dreamboat'
    +    timeout: 1000
    +
    +ok config.development.server  is 'localhost'
    +ok config.production.server   is 'dreamboat'
    +ok config.development.timeout is 10
    +ok config.production.timeout  is 1000
    +
    +obj =
    +  a: 1
    +  b: 2
    +
    +ok obj.a is 1
    +ok obj.b is 2
    +
    +obj =
    +  a: 1,
    +  b: 2,
    +
    +ok obj.a is 1
    +ok obj.b is 2
    +
    +
    +# Implicit objects nesting.
    +obj =
    +  options:
    +    value: yes
    +
    +  fn: ->
    +    {}
    +    null
    +
    +ok obj.options.value is yes
    +ok obj.fn() is null
    +
    +
    +# Implicit arguments to function calls:
    +func = (obj) -> obj.a
    +
    +result = func
    +  a: 10
    +
    +ok result is 10
    +
    +result = func
    +  "a": 20
    +
    +ok result is 20
    +
    +third = (a, b, c) -> c
    +obj =
    +  one: 'one'
    +  two: third 'one', 'two', 'three'
    +
    +ok obj.one is 'one'
    +ok obj.two is 'three'
    +
    +
    +# Implicit objects with wacky indentation:
    +obj =
    +  'reverse': (obj) ->
    +    Array.prototype.reverse.call obj
    +  abc: ->
    +    @reverse(
    +      @reverse @reverse ['a', 'b', 'c'].reverse()
    +    )
    +  one: [1, 2,
    +    a: 'b'
    +  3, 4]
    +  red:
    +    orange:
    +          yellow:
    +                  green: 'blue'
    +    indigo: 'violet'
    +  misdent: [[],
    +  [],
    +                  [],
    +      []]
    +
    +ok obj.abc().join(' ') is 'a b c'
    +ok obj.one.length is 5
    +ok obj.one[4] is 4
    +ok obj.one[2].a is 'b'
    +ok (key for key of obj.red).length is 2
    +ok obj.red.orange.yellow.green is 'blue'
    +ok obj.red.indigo is 'violet'
    +ok obj.misdent.toString() is ',,,'
    +
    +second = (x, y) -> y
    +obj = then second 'the',
    +  1: 1
    +  two:
    +    three: ->
    +      four five,
    +        six: seven
    +  three: 3
    +
    +ok obj[1] is 1
    +ok obj.three is 3
    +
    +
    +# Implicit objects as part of chained calls.
    +identity = (x) -> x.a
    +
    +b = identity identity identity
    +  a:
    +    a:
    +      a: 100
    +
    +ok b is 100
    +
    +
    +# Inline JS
    +eq '\\`', `
    +  "\\\`"
    +`
    +
    +
    +# Shorthand objects with property references.
    +obj =
    +  one: 1
    +  two: 2
    +  object: -> {@one, @two}
    +  list:   -> [@one, @two]
    +
    +
    +result = obj.object()
    +eq result.one, 1
    +eq result.two, 2
    +eq result.two, obj.list()[1]
    +
    +
    +#542: Objects leading expression statement should be parenthesized.
    +{f: -> ok yes }.f() + 1
    +
    +
    +#764: Boolean/Number should be indexable.
    +ok 42['toString']
    +ok on['toString']
    diff --git a/node_modules/jade/support/coffee-script/test/test_module.coffee b/node_modules/jade/support/coffee-script/test/test_module.coffee
    new file mode 100644
    index 0000000..c6f1f1b
    --- /dev/null
    +++ b/node_modules/jade/support/coffee-script/test/test_module.coffee
    @@ -0,0 +1,4 @@
    +# This file is imported by `testImporting.coffee`
    +if exports?
    +  local = "from over there"
    +  exports.func = -> local
    diff --git a/node_modules/jade/support/coffee-script/test/test_operations.coffee b/node_modules/jade/support/coffee-script/test/test_operations.coffee
    new file mode 100644
    index 0000000..0ba5cd6
    --- /dev/null
    +++ b/node_modules/jade/support/coffee-script/test/test_operations.coffee
    @@ -0,0 +1,154 @@
    +# CoffeeScript's operations should be chainable, like Python's.
    +ok 500 > 50 > 5 > -5
    +
    +ok true is not false is true is not false
    +
    +ok 0 is 0 isnt 50 is 50
    +
    +ok 10 < 20 > 10
    +
    +ok 50 > 10 > 5 is parseInt('5', 10)
    +
    +i = 0
    +ok 1 > i++ < 1, 'chained operations should evaluate each value only once'
    +
    +
    +# `==` and `is` should be interchangeable.
    +a = b = 1
    +
    +ok a is 1 and b is 1
    +ok a == b
    +ok a is b
    +
    +
    +# Allow "if x not in y"
    +obj = {a: true}
    +ok 'a' of obj
    +ok 'b' not of obj
    +
    +# And for "a in b" with array presence.
    +ok 200 in [100, 200, 300]
    +array = [100, 200, 300]
    +ok 200 in array
    +ok 1 not in array
    +ok array[0]++ in [99, 100], 'should cache testee'
    +
    +# And with array presence on an instance variable.
    +obj = {
    +  list: [1, 2, 3, 4, 5]
    +  in_list: (value) -> value in @list
    +}
    +ok obj.in_list 4
    +ok not obj.in_list 0
    +
    +# Non-spaced values still work.
    +x = 10
    +y = -5
    +
    +ok x*-y is 50
    +ok x*+y is -50
    +
    +
    +# Compound operators.
    +one  = 1
    +two  = 0
    +one or= 2
    +two or= 2
    +
    +eq one, 1
    +eq two, 2
    +
    +zero = 0
    +
    +zero and= 'one'
    +one  and= 'one'
    +
    +eq zero, 0
    +eq one , 'one'
    +
    +
    +# Compound assignment should be careful about caching variables.
    +count = 0
    +list = []
    +
    +list[++count] or= 1
    +eq list[1], 1
    +eq count, 1
    +
    +list[++count] ?= 2
    +eq list[2], 2
    +eq count, 2
    +
    +list[count++] and= 'two'
    +eq list[2], 'two'
    +eq count, 3
    +
    +base = -> ++count; base
    +
    +base().four or= 4
    +eq base.four, 4
    +eq count, 4
    +
    +base().five ?= 5
    +eq base.five, 5
    +eq count, 5
    +
    +
    +# Ensure that RHS is treated as a group.
    +a = b = false
    +a and= b or true
    +ok a is false
    +
    +
    +# Bitwise operators:
    +ok (10 &   3) is 2
    +ok (10 |   3) is 11
    +ok (10 ^   3) is 9
    +ok (10 <<  3) is 80
    +ok (10 >>  3) is 1
    +ok (10 >>> 3) is 1
    +
    +num = 10; ok (num <<=  3) is 80
    +num = 10; ok (num >>=  3) is 1
    +num = 10; ok (num >>>= 3) is 1
    +num = 10; ok (num &=   3) is 2
    +num = 10; ok (num ^=   3) is 9
    +num = 10; ok (num |=   3) is 11
    +
    +
    +# Compound assignment with implicit objects.
    +obj = undefined
    +obj ?=
    +  one: 1
    +
    +ok obj.one is 1
    +
    +obj and=
    +  two: 2
    +
    +ok not obj.one
    +ok obj.two is 2
    +
    +
    +# Compound assignment as a sub expression.
    +[a, b, c] = [1, 2, 3]
    +ok (a + b += c) is 6
    +ok a is 1
    +ok b is 5
    +ok c is 3
    +
    +
    +# Instanceof.
    +ok new String instanceof String
    +ok new Number not instanceof String
    +
    +
    +#737: `in` should have higher precedence than logical operators
    +eq 1, 1 in [1] and 1
    +
    +#768: `in` should preserve evaluation order
    +share = 0
    +a = -> share++ if share is 0
    +b = -> share++ if share is 1
    +c = -> share++ if share is 2
    +ok a() not in [b(),c()] and share is 3 
    diff --git a/node_modules/jade/support/coffee-script/test/test_option_parser.coffee b/node_modules/jade/support/coffee-script/test/test_option_parser.coffee
    new file mode 100644
    index 0000000..2f66623
    --- /dev/null
    +++ b/node_modules/jade/support/coffee-script/test/test_option_parser.coffee
    @@ -0,0 +1,27 @@
    +# Ensure that the OptionParser handles arguments correctly.
    +return unless require?
    +{OptionParser} = require './../lib/optparse'
    +
    +opt = new OptionParser [
    +  ['-r', '--required [DIR]',  'desc required']
    +  ['-o', '--optional',        'desc optional']
    +  ['-l', '--list [FILES*]',   'desc list']
    +]
    +
    +result = opt.parse ['one', 'two', 'three', '-r', 'dir']
    +
    +ok result.arguments.length is 5
    +ok result.arguments[3] is '-r'
    +
    +result = opt.parse ['--optional', '-r', 'folder', 'one', 'two']
    +
    +ok result.optional is true
    +ok result.required is 'folder'
    +ok result.arguments.join(' ') is 'one two'
    +
    +result = opt.parse ['-l', 'one.txt', '-l', 'two.txt', 'three']
    +
    +ok result.list instanceof Array
    +ok result.list.join(' ') is 'one.txt two.txt'
    +ok result.arguments.join(' ') is 'three'
    +
    diff --git a/node_modules/jade/support/coffee-script/test/test_pattern_matching.coffee b/node_modules/jade/support/coffee-script/test/test_pattern_matching.coffee
    new file mode 100644
    index 0000000..e323814
    --- /dev/null
    +++ b/node_modules/jade/support/coffee-script/test/test_pattern_matching.coffee
    @@ -0,0 +1,160 @@
    +# Simple variable swapping.
    +a = -1
    +b = -2
    +
    +[a, b] = [b, a]
    +
    +eq a, -2
    +eq b, -1
    +
    +func = ->
    +  [a, b] = [b, a]
    +
    +eq func().join(' '), '-1 -2'
    +eq a, -1
    +eq b, -2
    +
    +#713
    +eq (onetwo = [1, 2]), [a, b] = [c, d] = onetwo
    +ok a is c is 1 and b is d is 2
    +
    +
    +# Array destructuring, including splats.
    +[x,y...,z] = [1,2,3,4,5]
    +
    +ok x is 1
    +ok y.length is 3
    +ok z is 5
    +
    +[x, [y, mids..., last], z..., end] = [1, [10, 20, 30, 40], 2,3,4, 5]
    +
    +ok x is 1
    +ok y is 10
    +ok mids.length is 2 and mids[1] is 30
    +ok last is 40
    +ok z.length is 3 and z[2] is 4
    +ok end is 5
    +
    +
    +# Object destructuring.
    +obj = {x: 10, y: 20, z: 30}
    +
    +{x: a, y: b, z: c} = obj
    +
    +ok a is 10
    +ok b is 20
    +ok c is 30
    +
    +person = {
    +  name: "Moe"
    +  family: {
    +    'elder-brother': {
    +      addresses: [
    +        "first"
    +        {
    +          street: "101 Deercreek Ln."
    +          city:   "Moquasset NY, 10021"
    +        }
    +      ]
    +    }
    +  }
    +}
    +
    +{name: a, family: {'elder-brother': {addresses: [one, {city: b}]}}} = person
    +
    +ok a is "Moe"
    +ok b is "Moquasset NY, 10021"
    +
    +test = {
    +  person: {
    +    address: [
    +      "------"
    +      "Street 101"
    +      "Apt 101"
    +      "City 101"
    +    ]
    +  }
    +}
    +
    +{person: {address: [ignore, addr...]}} = test
    +
    +ok addr.join(', ') is "Street 101, Apt 101, City 101"
    +
    +
    +# Pattern matching against an expression.
    +[a, b] = if true then [2, 1] else [1, 2]
    +
    +ok a is 2
    +ok b is 1
    +
    +
    +# Pattern matching with object shorthand.
    +
    +person = {
    +  name: "Bob"
    +  age:  26
    +  dogs: ["Prince", "Bowie"]
    +}
    +
    +{name, age, dogs: [first, second]} = person
    +
    +ok name   is "Bob"
    +ok age    is 26
    +ok first  is "Prince"
    +ok second is "Bowie"
    +
    +# Pattern matching within for..loops
    +
    +persons = {
    +  George: { name: "Bob" },
    +  Bob: { name: "Alice" }
    +  Christopher: { name: "Stan" }
    +}
    +
    +join1 = "#{key}: #{name}" for key, { name } of persons
    +
    +eq join1.join(' / '), "George: Bob / Bob: Alice / Christopher: Stan"
    +
    +persons = [
    +  { name: "Bob", parent: { name: "George" } },
    +  { name: "Alice", parent: { name: "Bob" } },
    +  { name: "Stan", parent: { name: "Christopher" } }
    +]
    +
    +join2 = "#{parent}: #{name}" for { name, parent: { name: parent } } in persons
    +
    +eq join1.join(' '), join2.join(' ')
    +
    +persons = [['Bob', ['George']], ['Alice', ['Bob']], ['Stan', ['Christopher']]]
    +join3 = "#{parent}: #{name}" for [name, [parent]] in persons
    +
    +eq join2.join(' '), join3.join(' ')
    +
    +
    +# Pattern matching doesn't clash with implicit block objects.
    +obj = a: 101
    +func = -> true
    +
    +if func func
    +  {a} = obj
    +
    +ok a is 101
    +
    +[x] = {0: y} = {'0': z} = [Math.random()]
    +ok x is y is z, 'destructuring in multiple'
    +
    +
    +# Destructuring into an object.
    +obj =
    +  func: (list, object) ->
    +    [@one, @two] = list
    +    {@a, @b} = object
    +    {@a} = object  # must not unroll this
    +    null
    +
    +obj.func [1, 2], a: 'a', b: 'b'
    +
    +eq obj.one, 1
    +eq obj.two, 2
    +eq obj.a, 'a'
    +eq obj.b, 'b'
    diff --git a/node_modules/jade/support/coffee-script/test/test_ranges_slices_and_splices.coffee b/node_modules/jade/support/coffee-script/test/test_ranges_slices_and_splices.coffee
    new file mode 100644
    index 0000000..3e07f8c
    --- /dev/null
    +++ b/node_modules/jade/support/coffee-script/test/test_ranges_slices_and_splices.coffee
    @@ -0,0 +1,75 @@
    +# Slice.
    +array = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
    +
    +a = array[7..9]
    +b = array[2...4]
    +
    +result = a.concat(b).join(' ')
    +
    +ok result is "7 8 9 2 3"
    +
    +a = [0, 1, 2, 3, 4, 5, 6, 7]
    +eq a[2...6].join(' '), '2 3 4 5'
    +
    +
    +# Ranges.
    +countdown = [10..1].join(' ')
    +ok countdown is "10 9 8 7 6 5 4 3 2 1"
    +
    +a = 1
    +b = 5
    +nums = [a...b]
    +ok nums.join(' ') is '1 2 3 4'
    +
    +b = -5
    +nums = [a..b]
    +ok nums.join(' ') is '1 0 -1 -2 -3 -4 -5'
    +
    +
    +# Expression-based range.
    +array = [(1+5)..1+9]
    +ok array.join(' ') is "6 7 8 9 10"
    +
    +array = [5..1]
    +ok array.join(' ') is '5 4 3 2 1'
    +
    +array = [30...0]
    +ok (len = array.length) is 30
    +ok array[len - 1] is 1
    +
    +
    +
    +# String slicing (at least on Node).
    +hello = "Hello World"
    +
    +ok hello[1...1] is ""
    +ok hello[1..1] is "e"
    +ok hello[1...5] is "ello"
    +ok hello[0..4] is "Hello"
    +
    +
    +# Splice literals.
    +array = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    +
    +array[5..10] = [0, 0, 0]
    +
    +ok array.join(' ') is '0 1 2 3 4 0 0 0'
    +
    +
    +# Slices and splices that omit their beginning or end.
    +array = [0..10]
    +
    +ok array[7..].join(' ')  is '7 8 9 10'
    +ok array[-2..].join(' ') is '9 10'
    +
    +ok array[...3].join(' ') is '0 1 2'
    +ok array[..-5].join(' ') is '0 1 2 3 4 5 6'
    +
    +array[3..] = [9, 8, 7]
    +
    +ok array.join(' ') is '0 1 2 9 8 7'
    +
    +array[...3] = [7, 8, 9]
    +
    +ok array.join(' ') is '7 8 9 9 8 7'
    +
    diff --git a/node_modules/jade/support/coffee-script/test/test_regexps.coffee b/node_modules/jade/support/coffee-script/test/test_regexps.coffee
    new file mode 100644
    index 0000000..709709a
    --- /dev/null
    +++ b/node_modules/jade/support/coffee-script/test/test_regexps.coffee
    @@ -0,0 +1,45 @@
    +# Regular expression literals.
    +ok 'x'.match(/x/g)
    +ok 'x'.match /x/g
    +ok 'x'.match(/x/)
    +ok 'x'.match /x/
    +
    +ok 4 / 2 / 1 is 2
    +
    +y = 4
    +x = 2
    +g = 1
    +
    +ok y / x/g is 2
    +
    +obj = {
    +  width:  -> 10
    +  height: -> 20
    +}
    +id = 2
    +
    +ok (obj.width()/id - obj.height()/id) is -5
    +
    +eq /\\/.source, "\\\\"
    +
    +
    +eq /^I'm\s+Heregex?\/\/\//gim + '', ///
    +  ^ I'm \s+ Heregex? / // # or not
    +///gim + ''
    +eq '\\\\#{}\\\\\\\"', ///
    + #{
    +   "#{ '\\' }" # normal comment
    + }
    + # regex comment
    + \#{}
    + \\ \"
    +///.source
    +eq ///  /// + '', '/(?:)/'
    +
    +
    +#584: Unescaped slashes in character classes.
    +ok /:\/[/]goog/.test 'http://google.com'
    +
    +
    +#764: Should be indexable.
    +eq /0/['source'], ///#{0}///['source']
    diff --git a/node_modules/jade/support/coffee-script/test/test_returns.coffee b/node_modules/jade/support/coffee-script/test/test_returns.coffee
    new file mode 100644
    index 0000000..92f5ab0
    --- /dev/null
    +++ b/node_modules/jade/support/coffee-script/test/test_returns.coffee
    @@ -0,0 +1,33 @@
    +# Expression conversion under explicit returns.
    +first = ->
    +  return 'do' for x in [1,2,3]
    +
    +second = ->
    +  return ['re' for x in [1,2,3]]
    +
    +third = ->
    +  return ('mi' for x in [1,2,3])
    +
    +ok first().join(' ')     is 'do do do'
    +ok second()[0].join(' ') is 're re re'
    +ok third().join(' ')     is 'mi mi mi'
    +
    +
    +# Testing returns with multiple branches.
    +func = ->
    +  if false
    +    for a in b
    +      return c if d
    +  else
    +    "word"
    +
    +ok func() is 'word'
    +
    +
    +# And with switches.
    +func = ->
    +  switch 'a'
    +    when 'a' then 42
    +    else return 23
    +
    +ok func() is 42
    \ No newline at end of file
    diff --git a/node_modules/jade/support/coffee-script/test/test_splats.coffee b/node_modules/jade/support/coffee-script/test/test_splats.coffee
    new file mode 100644
    index 0000000..006c80f
    --- /dev/null
    +++ b/node_modules/jade/support/coffee-script/test/test_splats.coffee
    @@ -0,0 +1,125 @@
    +func = (first, second, rest...) ->
    +  rest.join ' '
    +
    +result = func 1, 2, 3, 4, 5
    +
    +ok result is "3 4 5"
    +
    +
    +gold = silver = bronze = theField = last = null
    +
    +medalists = (first, second, third, rest..., unlucky) ->
    +  gold     = first
    +  silver   = second
    +  bronze   = third
    +  theField = rest.concat([last])
    +  last     = unlucky
    +
    +contenders = [
    +  "Michael Phelps"
    +  "Liu Xiang"
    +  "Yao Ming"
    +  "Allyson Felix"
    +  "Shawn Johnson"
    +  "Roman Sebrle"
    +  "Guo Jingjing"
    +  "Tyson Gay"
    +  "Asafa Powell"
    +  "Usain Bolt"
    +]
    +
    +medalists "Mighty Mouse", contenders...
    +
    +ok gold is "Mighty Mouse"
    +ok silver is "Michael Phelps"
    +ok bronze is "Liu Xiang"
    +ok last is "Usain Bolt"
    +ok theField.length is 8
    +
    +contenders.reverse()
    +medalists contenders[0...2]..., "Mighty Mouse", contenders[2...contenders.length]...
    +
    +ok gold is "Usain Bolt"
    +ok silver is "Asafa Powell"
    +ok bronze is "Mighty Mouse"
    +ok last is "Michael Phelps"
    +ok theField.length is 8
    +
    +medalists contenders..., 'Tim', 'Moe', 'Jim'
    +ok last is 'Jim'
    +
    +
    +obj =
    +  name: 'moe'
    +  accessor: (args...) ->
    +    [@name].concat(args).join(' ')
    +  getNames: ->
    +    args = ['jane', 'ted']
    +    @accessor(args...)
    +  index: 0
    +  0: {method: -> this is obj[0]}
    +
    +ok obj.getNames() is 'moe jane ted'
    +ok obj[obj.index++].method([]...), 'should cache base value'
    +
    +crowd = [
    +  contenders...
    +  "Mighty Mouse"
    +]
    +
    +bests = [
    +  "Mighty Mouse"
    +  contenders[0..3]...
    +]
    +
    +ok crowd[0] is contenders[0]
    +ok crowd[10] is "Mighty Mouse"
    +
    +ok bests[1] is contenders[0]
    +ok bests[4] is contenders[3]
    +
    +
    +# Finally, splats with super() within classes.
    +
    +class Parent
    +  meth: (args...) ->
    +    args
    +
    +class Child extends Parent
    +  meth: ->
    +    nums = [3, 2, 1]
    +    super nums...
    +
    +ok (new Child).meth().join(' ') is '3 2 1'
    +
    +
    +# Functions with splats being called with too few arguments.
    +pen = null
    +method = (first, variable..., penultimate, ultimate) ->
    +  pen = penultimate
    +
    +method 1, 2, 3, 4, 5, 6, 7, 8, 9
    +ok pen is 8
    +
    +method 1, 2, 3
    +ok pen is 2
    +
    +method 1, 2
    +ok pen is 2
    +
    +
    +# Array splat expansions with assigns.
    +nums = [1, 2, 3]
    +list = [a = 0, nums..., b = 4]
    +ok a is 0
    +ok b is 4
    +ok list.join(' ') is '0 1 2 3 4'
    +
    +
    +# Splat on a line by itself is invalid.
    +failed = true
    +try
    +  CoffeeScript.compile "x 'a'\n...\n"
    +  failed = false
    +catch err
    +ok failed
    diff --git a/node_modules/jade/support/coffee-script/test/test_strings.coffee b/node_modules/jade/support/coffee-script/test/test_strings.coffee
    new file mode 100644
    index 0000000..51d32dc
    --- /dev/null
    +++ b/node_modules/jade/support/coffee-script/test/test_strings.coffee
    @@ -0,0 +1,101 @@
    +eq '(((dollars)))', '\(\(\(dollars\)\)\)'
    +eq 'one two three', "one
    + two
    + three"
    +eq "four five", 'four
    +
    + five'
    +
    +#647
    +eq "''Hello, World\\''", '''
    +'\'Hello, World\\\''
    +'''
    +eq '""Hello, World\\""', """
    +"\"Hello, World\\\""
    +"""
    +eq 'Hello, World\n', '''
    +Hello, World\
    +
    +'''
    +
    +
    +hello = 'Hello'
    +world = 'World'
    +ok '#{hello} #{world}!' is '#{hello} #{world}!'
    +ok "#{hello} #{world}!" is 'Hello World!'
    +ok "[#{hello}#{world}]" is '[HelloWorld]'
    +ok "#{hello}##{world}" is 'Hello#World'
    +ok "Hello #{ 1 + 2 } World" is 'Hello 3 World'
    +ok "#{hello} #{ 1 + 2 } #{world}" is "Hello 3 World"
    +
    +
    +[s, t, r, i, n, g] = ['s', 't', 'r', 'i', 'n', 'g']
    +ok "#{s}#{t}#{r}#{i}#{n}#{g}" is 'string'
    +ok "\#{s}\#{t}\#{r}\#{i}\#{n}\#{g}" is '#{s}#{t}#{r}#{i}#{n}#{g}'
    +ok "\#{string}" is '#{string}'
    +
    +
    +ok "\#{Escaping} first" is '#{Escaping} first'
    +ok "Escaping \#{in} middle" is 'Escaping #{in} middle'
    +ok "Escaping \#{last}" is 'Escaping #{last}'
    +
    +
    +ok "##" is '##'
    +ok "#{}" is ''
    +ok "#{}A#{} #{} #{}B#{}" is 'A  B'
    +ok "\\\#{}" is '\\#{}'
    +
    +
    +ok "I won ##{20} last night." is 'I won #20 last night.'
    +ok "I won ##{'#20'} last night." is 'I won ##20 last night.'
    +
    +
    +ok "#{hello + world}" is 'HelloWorld'
    +ok "#{hello + ' ' + world + '!'}" is 'Hello World!'
    +
    +
    +list = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
    +ok "values: #{list.join(', ')}, length: #{list.length}." is 'values: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, length: 10.'
    +ok "values: #{list.join ' '}" is 'values: 0 1 2 3 4 5 6 7 8 9'
    +
    +
    +obj = {
    +  name: 'Joe'
    +  hi: -> "Hello #{@name}."
    +  cya: -> "Hello #{@name}.".replace('Hello','Goodbye')
    +}
    +ok obj.hi() is "Hello Joe."
    +ok obj.cya() is "Goodbye Joe."
    +
    +
    +ok "With #{"quotes"}" is 'With quotes'
    +ok 'With #{"quotes"}' is 'With #{"quotes"}'
    +
    +ok "Where is #{obj["name"] + '?'}" is 'Where is Joe?'
    +
    +ok "Where is #{"the nested #{obj["name"]}"}?" is 'Where is the nested Joe?'
    +ok "Hello #{world ? "#{hello}"}" is 'Hello World'
    +
    +ok "Hello #{"#{"#{obj["name"]}" + '!'}"}" is 'Hello Joe!'
    +
    +
    +a = """
    +    Hello #{ "Joe" }
    +    """
    +ok a is "Hello Joe"
    +
    +
    +a = 1
    +b = 2
    +c = 3
    +ok "#{a}#{b}#{c}" is '123'
    +
    +
    +result = null
    +stash = (str) -> result = str
    +stash "a #{ ('aa').replace /a/g, 'b' } c"
    +ok result is 'a bb c'
    +
    +
    +foo = "hello"
    +ok "#{foo.replace("\"", "")}" is 'hello'
    diff --git a/node_modules/jade/support/coffee-script/test/test_switch.coffee b/node_modules/jade/support/coffee-script/test/test_switch.coffee
    new file mode 100644
    index 0000000..f3307d9
    --- /dev/null
    +++ b/node_modules/jade/support/coffee-script/test/test_switch.coffee
    @@ -0,0 +1,98 @@
    +num = 10
    +
    +result = switch num
    +  when 5 then false
    +  when 'a'
    +    true
    +    true
    +    false
    +  when 10 then true
    +
    +
    +  # Mid-switch comment with whitespace
    +  # and multi line
    +  when 11 then false
    +  else false
    +
    +ok result
    +
    +
    +func = (num) ->
    +  switch num
    +    when 2, 4, 6
    +      true
    +    when 1, 3, 5
    +      false
    +    else false
    +
    +ok func(2)
    +ok func(6)
    +ok !func(3)
    +ok !func(8)
    +
    +
    +# Should cache the switch value, if anything fancier than a literal.
    +num = 5
    +result = switch num += 5
    +  when 5 then false
    +  when 15 then false
    +  when 10 then true
    +  else false
    +
    +ok result
    +
    +
    +# Ensure that trailing switch elses don't get rewritten.
    +result = false
    +switch "word"
    +  when "one thing"
    +    doSomething()
    +  else
    +    result = true unless false
    +
    +ok result
    +
    +result = false
    +switch "word"
    +  when "one thing"
    +    doSomething()
    +  when "other thing"
    +    doSomething()
    +  else
    +    result = true unless false
    +
    +ok result
    +
    +
    +# Should be able to handle switches sans-condition.
    +result = switch
    +  when null then 1
    +  when 'truthful string' then 2
    +  else 3
    +
    +ok result is 2
    +
    +
    +# Should be able to use "@properties" within the switch clause.
    +obj = {
    +  num: 101
    +  func: ->
    +    switch @num
    +      when 101 then '101!'
    +      else 'other'
    +}
    +
    +ok obj.func() is '101!'
    +
    +
    +# Should be able to use "@properties" within the switch cases.
    +obj = {
    +  num: 101
    +  func: (yesOrNo) ->
    +    result = switch yesOrNo
    +      when yes then @num
    +      else 'other'
    +    result
    +}
    +
    +ok obj.func(yes) is 101
    diff --git a/node_modules/jade/support/coffee-script/test/test_try_catch.coffee b/node_modules/jade/support/coffee-script/test/test_try_catch.coffee
    new file mode 100644
    index 0000000..e98657b
    --- /dev/null
    +++ b/node_modules/jade/support/coffee-script/test/test_try_catch.coffee
    @@ -0,0 +1,45 @@
    +# Basic exception throwing.
    +block = -> throw 'up'
    +throws block, 'up'
    +
    +
    +# Basic try/catch.
    +result = try
    +  10
    +finally
    +  15
    +
    +ok result is 10
    +
    +result = try
    +  throw 'up'
    +catch err
    +  err.length
    +
    +ok result is 2
    +
    +
    +result = try throw 'error' catch err then err.length
    +
    +ok result is 5
    +
    +try throw 'catch is optional'
    +
    +# try/catch with empty clauses still compiles.
    +try
    +
    +try
    +  # nothing
    +catch err
    +  # nothing
    +
    +try
    +  # nothing
    +finally
    +  # nothing
    +
    +try
    +catch err
    +finally
    +
    +ok yes
    diff --git a/node_modules/jade/support/coffee-script/test/test_while.coffee b/node_modules/jade/support/coffee-script/test/test_while.coffee
    new file mode 100644
    index 0000000..3e3a83f
    --- /dev/null
    +++ b/node_modules/jade/support/coffee-script/test/test_while.coffee
    @@ -0,0 +1,53 @@
    +i = 5
    +list = while i -= 1
    +  i * 2
    +
    +ok list.join(' ') is "8 6 4 2"
    +
    +
    +i = 5
    +list = (i * 3 while i -= 1)
    +
    +ok list.join(' ') is "12 9 6 3"
    +
    +
    +i = 5
    +func   = (num) -> i -= num
    +assert = -> ok i < 5 > 0
    +
    +results = while func 1
    +  assert()
    +  i
    +
    +ok results.join(' ') is '4 3 2 1'
    +
    +
    +i = 10
    +results = while i -= 1 when i % 2 is 0
    +  i * 2
    +
    +ok results.join(' ') is '16 12 8 4'
    +
    +
    +value = false
    +i = 0
    +results = until value
    +  value = true if i is 5
    +  i += 1
    +
    +ok i is 6
    +
    +
    +# And, the loop form of while.
    +i = 5
    +list = []
    +loop
    +  i -= 1
    +  break if i is 0
    +  list.push i * 2
    +
    +ok list.join(' ') is '8 6 4 2'
    +
    +
    +#759: `if` within `while` condition
    +2 while if 1 then 0
    diff --git a/node_modules/jade/support/compile.js b/node_modules/jade/support/compile.js
    new file mode 100644
    index 0000000..4a70058
    --- /dev/null
    +++ b/node_modules/jade/support/compile.js
    @@ -0,0 +1,173 @@
    +
    +/**
    + * Module dependencies.
    + */
    +
    +var fs = require('fs');
    +
    +/**
    + * Arguments.
    + */
    +
    +var args = process.argv.slice(2)
    +  , pending = args.length
    +  , files = {};
    +
    +console.log('');
    +
    +// parse arguments
    +
    +args.forEach(function(file){
    +  var mod = file.replace('lib/', '');
    +  fs.readFile(file, 'utf8', function(err, js){
    +    if (err) throw err;
    +    console.log('  \033[90mcompile : \033[0m\033[36m%s\033[0m', file);
    +    files[file] = parse(js);
    +    --pending || compile();
    +  });
    +});
    +
    +/**
    + * Parse the given `js`.
    + */
    +
    +function parse(js) {
    +  return parseInheritance(parseConditionals(js));
    +}
    +
    +/**
    + * Parse __proto__.
    + */
    +
    +function parseInheritance(js) {
    +  return js
    +    .replace(/^ *(\w+)\.prototype\.__proto__ * = *(\w+)\.prototype *;?/gm, function(_, child, parent){
    +      return child + '.prototype = new ' + parent + ';\n'
    +        + child + '.prototype.constructor = '+ child + ';\n';
    +    });
    +}
    +
    +/**
    + * Parse the given `js`, currently supporting:
    + * 
    + *    'if' ['node' | 'browser']
    + *    'end'
    + * 
    + */
    +
    +function parseConditionals(js) {
    +  var lines = js.split('\n')
    +    , len = lines.length
    +    , buffer = true
    +    , browser = false
    +    , buf = []
    +    , line
    +    , cond;
    +
    +  for (var i = 0; i < len; ++i) {
    +    line = lines[i];
    +    if (/^ *\/\/ *if *(node|browser)/gm.exec(line)) {
    +      cond = RegExp.$1;
    +      buffer = browser = 'browser' == cond;
    +    } else if (/^ *\/\/ *end/.test(line)) {
    +      buffer = true;
    +      browser = false;
    +    } else if (browser) {
    +      buf.push(line.replace(/^( *)\/\//, '$1'));
    +    } else if (buffer) {
    +      buf.push(line);
    +    }
    +  }
    +
    +  return buf.join('\n');
    +}
    +
    +/**
    + * Compile the files.
    + */
    +
    +function compile() {
    +  var buf = '';
    +  buf += '\n// CommonJS require()\n\n';
    +  buf += browser.require + '\n\n';
    +  buf += 'require.modules = {};\n\n';
    +  buf += 'require.resolve = ' + browser.resolve + ';\n\n';
    +  buf += 'require.register = ' + browser.register + ';\n\n';
    +  buf += 'require.relative = ' + browser.relative + ';\n\n';
    +  args.forEach(function(file){
    +    var js = files[file];
    +    file = file.replace('lib/', '');
    +    buf += '\nrequire.register("' + file + '", function(module, exports, require){\n';
    +    buf += js;
    +    buf += '\n}); // module: ' + file + '\n';
    +  });
    +  fs.writeFile('jade.js', buf, function(err){
    +    if (err) throw err;
    +    console.log('  \033[90m create : \033[0m\033[36m%s\033[0m', 'jade.js');
    +    console.log();
    +  });
    +}
    +
    +// refactored version of weepy's
    +// https://github.com/weepy/brequire/blob/master/browser/brequire.js
    +
    +var browser = {
    +  
    +  /**
    +   * Require a module.
    +   */
    +  
    +  require: function require(p){
    +    var path = require.resolve(p)
    +      , mod = require.modules[path];
    +    if (!mod) throw new Error('failed to require "' + p + '"');
    +    if (!mod.exports) {
    +      mod.exports = {};
    +      mod.call(mod.exports, mod, mod.exports, require.relative(path));
    +    }
    +    return mod.exports;
    +  },
    +  
    +  /**
    +   * Resolve module path.
    +   */
    +
    +  resolve: function(path){
    +    var orig = path
    +      , reg = path + '.js'
    +      , index = path + '/index.js';
    +    return require.modules[reg] && reg
    +      || require.modules[index] && index
    +      || orig;
    +  },
    +  
    +  /**
    +   * Return relative require().
    +   */
    +
    +  relative: function(parent) {
    +    return function(p){
    +      if ('.' != p[0]) return require(p);
    +      
    +      var path = parent.split('/')
    +        , segs = p.split('/');
    +      path.pop();
    +      
    +      for (var i = 0; i < segs.length; i++) {
    +        var seg = segs[i];
    +        if ('..' == seg) path.pop();
    +        else if ('.' != seg) path.push(seg);
    +      }
    +
    +      return require(path.join('/'));
    +    };
    +  },
    +  
    +  /**
    +   * Register a module.
    +   */
    +
    +  register: function(path, fn){
    +    require.modules[path] = fn;
    +  }
    +};
    \ No newline at end of file
    diff --git a/node_modules/jade/support/expresso/.gitignore b/node_modules/jade/support/expresso/.gitignore
    new file mode 100644
    index 0000000..432563f
    --- /dev/null
    +++ b/node_modules/jade/support/expresso/.gitignore
    @@ -0,0 +1,3 @@
    +.DS_Store
    +lib-cov
    +*.seed
    \ No newline at end of file
    diff --git a/node_modules/jade/support/expresso/.gitmodules b/node_modules/jade/support/expresso/.gitmodules
    new file mode 100644
    index 0000000..191ddeb
    --- /dev/null
    +++ b/node_modules/jade/support/expresso/.gitmodules
    @@ -0,0 +1,3 @@
    +[submodule "deps/jscoverage"]
    +	path = deps/jscoverage
    +	url = git://github.com/visionmedia/node-jscoverage.git
    diff --git a/node_modules/jade/support/expresso/History.md b/node_modules/jade/support/expresso/History.md
    new file mode 100644
    index 0000000..1989eca
    --- /dev/null
    +++ b/node_modules/jade/support/expresso/History.md
    @@ -0,0 +1,97 @@
    +
    +0.6.2 / 2010-09-17 
    +==================
    +
    +  * Added _node-jsocoverage_ to package.json (aka will respect npm's binroot)
    +  * Added _-t, --timeout_ MS option, defaulting to 2000 ms
    +  * Added _-s, --serial_
    +  * __PREFIX__ clobberable
    +  * Fixed `assert.response()` for latest node
    +  * Fixed cov reporting from exploding on empty files
    +
    +0.6.2 / 2010-08-03
    +==================
    +
    +  * Added `assert.type()`
    +  * Renamed `assert.isNotUndefined()` to `assert.isDefined()`
    +  * Fixed `assert.includes()` param ordering
    +
    +0.6.0 / 2010-07-31
    +==================
    +
    +  * Added _docs/api.html_
    +  * Added -w, --watch
    +  * Added `Array` support to `assert.includes()`
    +  * Added; outputting exceptions immediately. Closes #19
    +  * Fixed `assert.includes()` param ordering
    +  * Fixed `assert.length()` param ordering
    +  * Fixed jscoverage links
    +
    +0.5.0 / 2010-07-16
    +==================
    +
    +  * Added support for async exports
    +  * Added timeout support to `assert.response()`. Closes #3
    +  * Added 4th arg callback support to `assert.response()`
    +  * Added `assert.length()`
    +  * Added `assert.match()`
    +  * Added `assert.isUndefined()`
    +  * Added `assert.isNull()`
    +  * Added `assert.includes()`
    +  * Added growlnotify support via -g, --growl
    +  * Added -o, --only TESTS. Ex: --only "test foo()" --only "test foo(), test bar()"
    +  * Removed profanity
    +
    +0.4.0 / 2010-07-09
    +==================
    +
    +  * Added reporting source coverage (respects --boring for color haters)
    +  * Added callback to assert.response(). Closes #12
    +  * Fixed; putting exceptions to stderr. Closes #13
    +
    +0.3.1 / 2010-06-28
    +==================
    +
    +  * Faster assert.response()
    +
    +0.3.0 / 2010-06-28
    +==================
    +
    +  * Added -p, --port NUM flags
    +  * Added assert.response(). Closes #11
    +
    +0.2.1 / 2010-06-25
    +==================
    +
    +  * Fixed issue with reporting object assertions
    +
    +0.2.0 / 2010-06-21
    +==================
    +
    +  * Added `make uninstall`
    +  * Added better readdir() failure message
    +  * Fixed `make install` for kiwi
    +
    +0.1.0 / 2010-06-15
    +==================
    +
    +  * Added better usage docs via --help
    +  * Added better conditional color support
    +  * Added pre exit assertion support
    +
    +0.0.3 / 2010-06-02
    +==================
    +
    +  * Added more room for filenames in test coverage
    +  * Added boring output support via --boring (suppress colored output)
    +  * Fixed async failure exit status
    +
    +0.0.2 / 2010-05-30
    +==================
    +
    +  * Fixed exit status for CI support
    +
    +0.0.1 / 2010-05-30
    +==================
    +
    +  * Initial release
    \ No newline at end of file
    diff --git a/node_modules/jade/support/expresso/Makefile b/node_modules/jade/support/expresso/Makefile
    new file mode 100644
    index 0000000..8acfe56
    --- /dev/null
    +++ b/node_modules/jade/support/expresso/Makefile
    @@ -0,0 +1,53 @@
    +
    +PREFIX ?= /usr/local
    +BIN = bin/expresso
    +JSCOV = deps/jscoverage/node-jscoverage
    +DOCS = docs/index.md
    +HTMLDOCS = $(DOCS:.md=.html)
    +
    +test: $(BIN)
    +	@./$(BIN) -I lib --growl $(TEST_FLAGS) test/*.test.js
    +
    +test-cov:
    +	@./$(BIN) -I lib --cov $(TEST_FLAGS) test/*.test.js
    +
    +test-serial:
    +	@./$(BIN) --serial -I lib $(TEST_FLAGS) test/serial/*.test.js
    +
    +install: install-jscov install-expresso
    +
    +uninstall:
    +	rm -f $(PREFIX)/bin/expresso
    +	rm -f $(PREFIX)/bin/node-jscoverage
    +
    +install-jscov: $(JSCOV)
    +	install $(JSCOV) $(PREFIX)/bin
    +
    +install-expresso:
    +	install $(BIN) $(PREFIX)/bin
    +
    +$(JSCOV):
    +	cd deps/jscoverage && ./configure && make && mv jscoverage node-jscoverage
    +
    +clean:
    +	@cd deps/jscoverage && git clean -fd
    +
    +docs: docs/api.html $(HTMLDOCS)
    +
    +%.html: %.md
    +	@echo "... $< > $@"
    +	@ronn -5 --pipe --fragment $< \
    +		| cat docs/layout/head.html - docs/layout/foot.html \
    +		> $@
    +
    +docs/api.html: bin/expresso
    +	dox \
    +		--title "Expresso" \
    +		--ribbon "http://github.com/visionmedia/expresso" \
    +		--desc "Insanely fast TDD framework for [node](http://nodejs.org) featuring code coverage reporting." \
    +		$< > $@
    +
    +docclean:
    +	rm -f docs/*.html
    +
    +.PHONY: test test-cov install uninstall install-expresso install-jscov clean docs docclean
    \ No newline at end of file
    diff --git a/node_modules/jade/support/expresso/Readme.md b/node_modules/jade/support/expresso/Readme.md
    new file mode 100644
    index 0000000..dcc1c85
    --- /dev/null
    +++ b/node_modules/jade/support/expresso/Readme.md
    @@ -0,0 +1,39 @@
    +
    +# Expresso
    +
    +  TDD framework for [nodejs](http://nodejs.org).
    +  
    +## Features
    +
    +  - light-weight
    +  - intuitive async support
    +  - intuitive test runner executable
    +  - test coverage support and reporting
    +  - uses the _assert_ module
    +  - `assert.eql()` alias of `assert.deepEqual()`
    +  - `assert.response()` http response utility
    +  - `assert.includes()`
    +  - `assert.type()`
    +  - `assert.isNull()`
    +  - `assert.isUndefined()`
    +  - `assert.isNotNull()`
    +  - `assert.isDefined()`
    +  - `assert.match()`
    +  - `assert.length()`
    +
    +## Installation
    +
    +To install both expresso _and_ node-jscoverage run:
    +
    +    $ make install
    +
    +To install expresso alone (no build required) run:
    +
    +    $ make install-expresso
    +
    +Install via npm:
    +
    +	$ npm install expresso
    +
    +
    +
    diff --git a/node_modules/jade/support/expresso/bin/expresso b/node_modules/jade/support/expresso/bin/expresso
    new file mode 100755
    index 0000000..8366c61
    --- /dev/null
    +++ b/node_modules/jade/support/expresso/bin/expresso
    @@ -0,0 +1,837 @@
    +#!/usr/bin/env node
    +
    +/*!
    + * Expresso
    + * Copyright(c) TJ Holowaychuk 
    + * (MIT Licensed)
    + */
    + 
    +/**
    + * Module dependencies.
    + */
    +
    +var assert = require('assert'),
    +    childProcess = require('child_process'),
    +    http = require('http'),
    +    path = require('path'),
    +    sys = require('sys'),
    +    cwd = process.cwd(),
    +    fs = require('fs'),
    +    defer;
    +
    +/**
    + * Expresso version.
    + */
    +
    +var version = '0.6.2';
    +
    +/**
    + * Failure count.
    + */
    +
    +var failures = 0;
    +
    +
    +/**
    + * Number of tests executed.
    + */
    +
    +var testcount = 0;
    +
    +/**
    + * Whitelist of tests to run.
    + */
    + 
    +var only = [];
    +
    +/**
    + * Boring output.
    + */
    + 
    +var boring = false;
    +
    +/**
    + * Growl notifications.
    + */
    +
    +var growl = false;
    +
    +/**
    + * Server port.
    + */
    +
    +var port = 5555;
    +
    +/**
    + * Watch mode.
    + */
    +
    +var watch = false;
    +
    +/**
    + * Execute serially.
    + */
    +
    +var serial = false;
    +
    +/**
    + * Default timeout.
    + */
    +
    +var timeout = 2000;
    +
    +/**
    + * Usage documentation.
    + */
    +
    +var usage = ''
    +    + '[bold]{Usage}: expresso [options] '
    +    + '\n'
    +    + '\n[bold]{Options}:'
    +    + '\n  -w, --watch          Watch for modifications and re-execute tests'
    +    + '\n  -g, --growl          Enable growl notifications'
    +    + '\n  -c, --coverage       Generate and report test coverage'
    +    + '\n  -t, --timeout MS     Timeout in milliseconds, defaults to 2000'
    +    + '\n  -r, --require PATH   Require the given module path'
    +    + '\n  -o, --only TESTS     Execute only the comma sperated TESTS (can be set several times)'
    +    + '\n  -I, --include PATH   Unshift the given path to require.paths'
    +    + '\n  -p, --port NUM       Port number for test servers, starts at 5555'
    +    + '\n  -s, --serial         Execute tests serially'
    +    + '\n  -b, --boring         Suppress ansi-escape colors'
    +    + '\n  -v, --version        Output version number'
    +    + '\n  -h, --help           Display help information'
    +    + '\n';
    +
    +// Parse arguments
    +
    +var files = [],
    +    args = process.argv.slice(2);
    +
    +while (args.length) {
    +    var arg = args.shift();
    +    switch (arg) {
    +        case '-h':
    +        case '--help':
    +            print(usage + '\n');
    +            process.exit(1);
    +            break;
    +        case '-v':
    +        case '--version':
    +            sys.puts(version);
    +            process.exit(1);
    +            break;
    +        case '-i':
    +        case '-I':
    +        case '--include':
    +            if (arg = args.shift()) {
    +                require.paths.unshift(arg);
    +            } else {
    +                throw new Error('--include requires a path');
    +            }
    +            break;
    +        case '-o':
    +        case '--only':
    +            if (arg = args.shift()) {
    +                only = only.concat(arg.split(/ *, */));
    +            } else {
    +                throw new Error('--only requires comma-separated test names');
    +            }
    +            break;
    +        case '-p':
    +        case '--port':
    +            if (arg = args.shift()) {
    +                port = parseInt(arg, 10);
    +            } else {
    +                throw new Error('--port requires a number');
    +            }
    +            break;
    +        case '-r':
    +        case '--require':
    +            if (arg = args.shift()) {
    +                require(arg);
    +            } else {
    +                throw new Error('--require requires a path');
    +            }
    +            break;
    +        case '-t':
    +        case '--timeout':
    +          if (arg = args.shift()) {
    +            timeout = parseInt(arg, 10);
    +          } else {
    +            throw new Error('--timeout requires an argument');
    +          }
    +          break;
    +        case '-c':
    +        case '--cov':
    +        case '--coverage':
    +            defer = true;
    +            childProcess.exec('rm -fr lib-cov && node-jscoverage lib lib-cov', function(err){
    +                if (err) throw err;
    +                require.paths.unshift('lib-cov');
    +                run(files);
    +            })
    +            break;
    +        case '-b':
    +        case '--boring':
    +        	boring = true;
    +        	break;
    +        case '-w':
    +        case '--watch':
    +            watch = true;
    +            break;
    +        case '-g':
    +        case '--growl':
    +            growl = true;
    +            break;
    +        case '-s':
    +        case '--serial':
    +            serial = true;
    +            break;
    +        default:
    +            if (/\.js$/.test(arg)) {
    +                files.push(arg);
    +            }
    +            break;
    +    }
    +}
    +
    +/**
    + * Colorized sys.error().
    + *
    + * @param {String} str
    + */
    +
    +function print(str){
    +    sys.error(colorize(str));
    +}
    +
    +/**
    + * Colorize the given string using ansi-escape sequences.
    + * Disabled when --boring is set.
    + *
    + * @param {String} str
    + * @return {String}
    + */
    +
    +function colorize(str){
    +    var colors = { bold: 1, red: 31, green: 32, yellow: 33 };
    +    return str.replace(/\[(\w+)\]\{([^]*?)\}/g, function(_, color, str){
    +        return boring
    +            ? str
    +            : '\x1B[' + colors[color] + 'm' + str + '\x1B[0m';
    +    });
    +}
    +
    +// Alias deepEqual as eql for complex equality
    +
    +assert.eql = assert.deepEqual;
    +
    +/**
    + * Assert that `val` is null.
    + *
    + * @param {Mixed} val
    + * @param {String} msg
    + */
    +
    +assert.isNull = function(val, msg) {
    +    assert.strictEqual(null, val, msg);
    +};
    +
    +/**
    + * Assert that `val` is not null.
    + *
    + * @param {Mixed} val
    + * @param {String} msg
    + */
    +
    +assert.isNotNull = function(val, msg) {
    +    assert.notStrictEqual(null, val, msg);
    +};
    +
    +/**
    + * Assert that `val` is undefined.
    + *
    + * @param {Mixed} val
    + * @param {String} msg
    + */
    +
    +assert.isUndefined = function(val, msg) {
    +    assert.strictEqual(undefined, val, msg);
    +};
    +
    +/**
    + * Assert that `val` is not undefined.
    + *
    + * @param {Mixed} val
    + * @param {String} msg
    + */
    +
    +assert.isDefined = function(val, msg) {
    +    assert.notStrictEqual(undefined, val, msg);
    +};
    +
    +/**
    + * Assert that `obj` is `type`.
    + *
    + * @param {Mixed} obj
    + * @param {String} type
    + * @api public
    + */
    +
    +assert.type = function(obj, type, msg){
    +    var real = typeof obj;
    +    msg = msg || 'typeof ' + sys.inspect(obj) + ' is ' + real + ', expected ' + type;
    +    assert.ok(type === real, msg);
    +};
    +
    +/**
    + * Assert that `str` matches `regexp`.
    + *
    + * @param {String} str
    + * @param {RegExp} regexp
    + * @param {String} msg
    + */
    +
    +assert.match = function(str, regexp, msg) {
    +    msg = msg || sys.inspect(str) + ' does not match ' + sys.inspect(regexp);
    +    assert.ok(regexp.test(str), msg);
    +};
    +
    +/**
    + * Assert that `val` is within `obj`.
    + *
    + * Examples:
    + *
    + *    assert.includes('foobar', 'bar');
    + *    assert.includes(['foo', 'bar'], 'foo');
    + *
    + * @param {String|Array} obj
    + * @param {Mixed} val
    + * @param {String} msg
    + */
    +
    +assert.includes = function(obj, val, msg) {
    +    msg = msg || sys.inspect(obj) + ' does not include ' + sys.inspect(val);
    +    assert.ok(obj.indexOf(val) >= 0, msg);
    +};
    +
    +/**
    + * Assert length of `val` is `n`.
    + *
    + * @param {Mixed} val
    + * @param {Number} n
    + * @param {String} msg
    + */
    +
    +assert.length = function(val, n, msg) {
    +    msg = msg || sys.inspect(val) + ' has length of ' + val.length + ', expected ' + n;
    +    assert.equal(n, val.length, msg);
    +};
    +
    +/**
    + * Assert response from `server` with
    + * the given `req` object and `res` assertions object.
    + *
    + * @param {Server} server
    + * @param {Object} req
    + * @param {Object|Function} res
    + * @param {String} msg
    + */
    +
    +assert.response = function(server, req, res, msg){
    +    // Callback as third or fourth arg
    +    var callback = typeof res === 'function'
    +        ? res
    +        : typeof msg === 'function'
    +            ? msg
    +            : function(){};
    +
    +    // Default messate to test title
    +    if (typeof msg === 'function') msg = null;
    +    msg = msg || assert.testTitle;
    +    msg += '. ';
    +
    +    // Pending responses
    +    server.__pending = server.__pending || 0;
    +    server.__pending++;
    +
    +    // Create client
    +    if (!server.fd) {
    +        server.listen(server.__port = port++, '127.0.0.1');
    +        server.client = http.createClient(server.__port);
    +    }
    +
    +    // Issue request
    +    var timer,
    +        client = server.client,
    +        method = req.method || 'GET',
    +        status = res.status || res.statusCode,
    +        data = req.data || req.body,
    +        timeout = req.timeout || 0;
    +
    +    var request = client.request(method, req.url, req.headers);
    +
    +    // Timeout
    +    if (timeout) {
    +        timer = setTimeout(function(){
    +            --server.__pending || server.close();
    +            delete req.timeout;
    +            assert.fail(msg + 'Request timed out after ' + timeout + 'ms.');
    +        }, timeout);
    +    }
    +
    +    if (data) request.write(data);
    +    request.addListener('response', function(response){
    +        response.body = '';
    +        response.setEncoding('utf8');
    +        response.addListener('data', function(chunk){ response.body += chunk; });
    +        response.addListener('end', function(){
    +            --server.__pending || server.close();
    +            if (timer) clearTimeout(timer);
    +
    +            // Assert response body
    +            if (res.body !== undefined) {
    +                var eql = res.body instanceof RegExp
    +                  ? res.body.test(response.body)
    +                  : res.body === response.body;
    +                assert.ok(
    +                    eql,
    +                    msg + 'Invalid response body.\n'
    +                        + '    Expected: ' + sys.inspect(res.body) + '\n'
    +                        + '    Got: ' + sys.inspect(response.body)
    +                );
    +            }
    +
    +            // Assert response status
    +            if (typeof status === 'number') {
    +                assert.equal(
    +                    response.statusCode,
    +                    status,
    +                    msg + colorize('Invalid response status code.\n'
    +                        + '    Expected: [green]{' + status + '}\n'
    +                        + '    Got: [red]{' + response.statusCode + '}')
    +                );
    +            }
    +
    +            // Assert response headers
    +            if (res.headers) {
    +                var keys = Object.keys(res.headers);
    +                for (var i = 0, len = keys.length; i < len; ++i) {
    +                    var name = keys[i],
    +                        actual = response.headers[name.toLowerCase()],
    +                        expected = res.headers[name];
    +                    assert.equal(
    +                        actual,
    +                        expected,
    +                        msg + colorize('Invalid response header [bold]{' + name + '}.\n'
    +                            + '    Expected: [green]{' + expected + '}\n'
    +                            + '    Got: [red]{' + actual + '}')
    +                    );
    +                }
    +            }
    +
    +            // Callback
    +            callback(response);
    +        });
    +    });
    +    request.end();
    +};
    +
    +/**
    + * Pad the given string to the maximum width provided.
    + *
    + * @param  {String} str
    + * @param  {Number} width
    + * @return {String}
    + */
    +
    +function lpad(str, width) {
    +    str = String(str);
    +    var n = width - str.length;
    +    if (n < 1) return str;
    +    while (n--) str = ' ' + str;
    +    return str;
    +}
    +
    +/**
    + * Pad the given string to the maximum width provided.
    + *
    + * @param  {String} str
    + * @param  {Number} width
    + * @return {String}
    + */
    +
    +function rpad(str, width) {
    +    str = String(str);
    +    var n = width - str.length;
    +    if (n < 1) return str;
    +    while (n--) str = str + ' ';
    +    return str;
    +}
    +
    +/**
    + * Report test coverage.
    + *
    + * @param  {Object} cov
    + */
    +
    +function reportCoverage(cov) {
    +    populateCoverage(cov);
    +    // Stats
    +    print('\n   [bold]{Test Coverage}\n');
    +    var sep = '   +------------------------------------------+----------+------+------+--------+',
    +        lastSep = '                                              +----------+------+------+--------+';
    +    sys.puts(sep);
    +    sys.puts('   | filename                                 | coverage | LOC  | SLOC | missed |');
    +    sys.puts(sep);
    +    for (var name in cov) {
    +        var file = cov[name];
    +        if (Array.isArray(file)) {
    +            sys.print('   | ' + rpad(name, 40));
    +            sys.print(' | ' + lpad(file.coverage.toFixed(2), 8));
    +            sys.print(' | ' + lpad(file.LOC, 4));
    +            sys.print(' | ' + lpad(file.SLOC, 4));
    +            sys.print(' | ' + lpad(file.totalMisses, 6));
    +            sys.print(' |\n');
    +        }
    +    }
    +    sys.puts(sep);
    +    sys.print('     ' + rpad('', 40));
    +    sys.print(' | ' + lpad(cov.coverage.toFixed(2), 8));
    +    sys.print(' | ' + lpad(cov.LOC, 4));
    +    sys.print(' | ' + lpad(cov.SLOC, 4));
    +    sys.print(' | ' + lpad(cov.totalMisses, 6));
    +    sys.print(' |\n');
    +    sys.puts(lastSep);
    +    // Source
    +    for (var name in cov) {
    +        if (name.match(/\.js$/)) {
    +            var file = cov[name];
    +            print('\n   [bold]{' + name + '}:');
    +            print(file.source);
    +            sys.print('\n');
    +        }
    +    }
    +}
    +
    +/**
    + * Populate code coverage data.
    + *
    + * @param  {Object} cov
    + */
    +
    +function populateCoverage(cov) {
    +    cov.LOC = 
    +    cov.SLOC =
    +    cov.totalFiles =
    +    cov.totalHits =
    +    cov.totalMisses = 
    +    cov.coverage = 0;
    +    for (var name in cov) {
    +        var file = cov[name];
    +        if (Array.isArray(file)) {
    +            // Stats
    +            ++cov.totalFiles;
    +            cov.totalHits += file.totalHits = coverage(file, true);
    +            cov.totalMisses += file.totalMisses = coverage(file, false);
    +            file.totalLines = file.totalHits + file.totalMisses;
    +            cov.SLOC += file.SLOC = file.totalLines;
    +            if (!file.source) file.source = [];
    +            cov.LOC += file.LOC = file.source.length;
    +            file.coverage = (file.totalHits / file.totalLines) * 100;
    +            // Source
    +            var width = file.source.length.toString().length;
    +            file.source = file.source.map(function(line, i){
    +                ++i;
    +                var hits = file[i] === 0 ? 0 : (file[i] || ' ');
    +                if (!boring) {
    +                    if (hits === 0) {
    +                        hits = '\x1b[31m' + hits + '\x1b[0m';
    +                        line = '\x1b[41m' + line + '\x1b[0m';
    +                    } else {
    +                        hits = '\x1b[32m' + hits + '\x1b[0m';
    +                    }
    +                }
    +                return '\n     ' + lpad(i, width) + ' | ' + hits + ' | ' + line;
    +            }).join('');
    +        }
    +    }
    +    cov.coverage = (cov.totalHits / cov.SLOC) * 100;
    +}
    +
    +/**
    + * Total coverage for the given file data.
    + *
    + * @param  {Array} data
    + * @return {Type}
    + */
    +
    +function coverage(data, val) {
    +    var n = 0;
    +    for (var i = 0, len = data.length; i < len; ++i) {
    +        if (data[i] !== undefined && data[i] == val) ++n;
    +    }
    +    return n;  
    +}
    +
    +/**
    + * Run the given test `files`, or try _test/*_.
    + *
    + * @param  {Array} files
    + */
    +
    +function run(files) {
    +    if (!files.length) {
    +        try {
    +            files = fs.readdirSync('test').map(function(file){
    +                return 'test/' + file;
    +            });
    +        } catch (err) {
    +            print('\n  failed to load tests in [bold]{./test}\n');
    +            ++failures;
    +            process.exit(1);
    +        }
    +    }
    +    if (watch) watchFiles(files);
    +    runFiles(files);
    +}
    +
    +/**
    + * Show the cursor when `show` is true, otherwise hide it.
    + *
    + * @param {Boolean} show
    + */
    +
    +function cursor(show) {
    +    if (show) {
    +        sys.print('\x1b[?25h');
    +    } else {
    +        sys.print('\x1b[?25l');
    +    }
    +}
    +
    +/**
    + * Run the given test `files`.
    + *
    + * @param {Array} files
    + */
    +
    +function runFiles(files) {
    +    files.forEach(runFile);
    +}
    +
    +/**
    + * Run tests for the given `file`.
    + *
    + * @param {String} file
    + */
    +
    +function runFile(file) {
    +    if (file.match(/\.js$/)) {
    +        var title = path.basename(file),
    +            file = path.join(cwd, file),
    +            mod = require(file.replace(/\.js$/, ''));
    +        (function check(){
    +           var len = Object.keys(mod).length;
    +           if (len) {
    +               runSuite(title, mod);
    +           } else {
    +               setTimeout(check, 20);
    +           }
    +        })();
    +    }
    +}
    +
    +/**
    + * Clear the module cache for the given `file`.
    + *
    + * @param {String} file
    + */
    +
    +function clearCache(file) {
    +    var keys = Object.keys(module.moduleCache);
    +    for (var i = 0, len = keys.length; i < len; ++i) {
    +        var key = keys[i];
    +        if (key.indexOf(file) === key.length - file.length) {
    +            delete module.moduleCache[key];
    +        }
    +    }
    +}
    +
    +/**
    + * Watch the given `files` for changes.
    + *
    + * @param {Array} files
    + */
    +
    +function watchFiles(files) {
    +    var p = 0,
    +        c = ['▫   ', '▫▫  ', '▫▫▫ ', ' ▫▫▫',
    +             '  ▫▫', '   ▫', '   ▫', '  ▫▫',
    +             '▫▫▫ ', '▫▫  ', '▫   '],
    +        l = c.length;
    +    cursor(false);
    +    setInterval(function(){
    +        sys.print(colorize('  [green]{' + c[p++ % l] + '} watching\r'));
    +    }, 100);
    +    files.forEach(function(file){
    +        fs.watchFile(file, { interval: 100 }, function(curr, prev){
    +            if (curr.mtime > prev.mtime) {
    +                print('  [yellow]{◦} ' + file);
    +                clearCache(file);
    +                runFile(file);
    +            }
    +        });
    +    });
    +}
    +
    +/**
    + * Report `err` for the given `test` and `suite`.
    + *
    + * @param {String} suite
    + * @param {String} test
    + * @param {Error} err
    + */
    +
    +function error(suite, test, err) {
    +    ++failures;
    +    var name = err.name,
    +        stack = err.stack.replace(err.name, ''),
    +        label = test === 'uncaught'
    +            ? test
    +            : suite + ' ' + test;
    +    print('\n   [bold]{' + label + '}: [red]{' + name + '}' + stack + '\n');
    +    if (watch) notify(label + ' failed');
    +}
    +
    +/**
    + * Run the given tests.
    + *
    + * @param  {String} title
    + * @param  {Object} tests
    + */
    +
    +var dots = 0;
    +function runSuite(title, tests) {
    +    // Keys
    +    var keys = only.length
    +        ? only.slice(0)
    +        : Object.keys(tests);
    +
    +    // Setup
    +    var setup = tests.setup || function(fn){ fn(); };
    +    
    +    // Iterate tests
    +    (function next(){
    +        if (keys.length) {
    +            var key,
    +                test = tests[key = keys.shift()];
    +            // Non-tests
    +            if (key === 'setup') return next();
    +
    +            // Run test
    +            if (test) {
    +                try {
    +                    ++testcount;
    +                    assert.testTitle = key;
    +                    if (serial) {
    +                        if (!watch) {
    +                            sys.print('.');
    +                            if (++dots % 25 === 0) sys.print('\n');
    +                        }
    +                        setup(function(){
    +                            if (test.length < 2) {
    +                                test(assert);
    +                                next();
    +                            } else {
    +                                var id = setTimeout(function(){
    +                                    throw new Error("'" + key + "' timed out");
    +                                }, timeout);
    +                                test(assert, function(){
    +                                    clearTimeout(id);
    +                                    next();
    +                                });
    +                            } 
    +                        });
    +                    } else {
    +                        test(assert, function(fn){
    +                            process.addListener('beforeExit', function(){
    +                                try {
    +                                    fn();
    +                                } catch (err) {
    +                                    error(title, key, err);
    +                                }
    +                            });
    +                        });
    +                    }
    +                } catch (err) {
    +                    error(title, key, err);
    +                }
    +            }
    +            if (!serial) next();
    +        }
    +    })();
    +}
    +
    +/**
    + * Report exceptions.
    + */
    +
    +function report() {
    +    process.emit('beforeExit');
    +    if (failures) {
    +        print('\n   [bold]{Failures}: [red]{' + failures + '}\n\n');
    +        notify('Failures: ' + failures);
    +    } else {
    +        if (serial) print('');
    +        print('\n   [green]{100%} ' + testcount + ' tests\n');
    +        notify('100% ok');
    +    }
    +    if (typeof _$jscoverage === 'object') {
    +        reportCoverage(_$jscoverage);
    +    }
    +}
    +
    +/**
    + * Growl notify the given `msg`.
    + *
    + * @param {String} msg
    + */
    +
    +function notify(msg) {
    +    if (growl) {
    +        childProcess.exec('growlnotify -name Expresso -m "' + msg + '"');
    +    }
    +}
    +
    +// Report uncaught exceptions
    +
    +process.addListener('uncaughtException', function(err){
    +    error('uncaught', 'uncaught', err);
    +});
    +
    +// Show cursor
    +
    +['INT', 'TERM', 'QUIT'].forEach(function(sig){
    +    process.addListener('SIG' + sig, function(){
    +        cursor(true);
    +        process.exit(1);
    +    });
    +});
    +
    +// Report test coverage when available
    +// and emit "beforeExit" event to perform
    +// final assertions
    +
    +var orig = process.emit;
    +process.emit = function(event){
    +    if (event === 'exit') {
    +        report();
    +        process.reallyExit(failures);
    +    }
    +    orig.apply(this, arguments);
    +};
    +
    +// Run test files
    +
    +if (!defer) run(files);
    diff --git a/node_modules/jade/support/expresso/docs/api.html b/node_modules/jade/support/expresso/docs/api.html
    new file mode 100644
    index 0000000..8718732
    --- /dev/null
    +++ b/node_modules/jade/support/expresso/docs/api.html
    @@ -0,0 +1,1048 @@
    +Fork me on GitHub
    +	
    +		Expresso
    +		
    +		
    +		
    +	
    +	
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +

    Expresso

    Insanely fast TDD framework for node featuring code coverage reporting.

    expresso

    bin/expresso
    +

    !/usr/bin/env node

    +
    +
    !
    + * Expresso
    + * Copyright(c) TJ Holowaychuk &lt;tj@vision-media.ca&gt;
    + * (MIT Licensed)
    + 
    +
    +

    Module dependencies. +

    +
    +
    var assert = require('assert'),
    +    childProcess = require('child_process'),
    +    http = require('http'),
    +    path = require('path'),
    +    sys = require('sys'),
    +    cwd = process.cwd(),
    +    fs = require('fs'),
    +    defer;
    +
    +

    Expresso version. +

    +
    +
    var version = '0.6.1';
    +
    +

    Failure count. +

    +
    +
    var failures = 0;
    +
    +

    Number of tests executed. +

    +
    +
    var testcount = 0;
    +
    +

    Whitelist of tests to run. +

    +
    +
    var only = [];
    +
    +

    Boring output. +

    +
    +
    var boring = false;
    +
    +

    Growl notifications. +

    +
    +
    var growl = false;
    +
    +

    Server port. +

    +
    +
    var port = 5555;
    +
    +

    Watch mode. +

    +
    +
    var watch = false;
    +
    +

    Execute serially. +

    +
    +
    var serial = false;
    +
    +

    Usage documentation. +

    +
    +
    var usage = ''
    +    + '[bold]{Usage}: expresso [options] <file ...>'
    +    + '\n'
    +    + '\n[bold]{Options}:'
    +    + '\n  -w, --watch          Watch for modifications and re-execute tests'
    +    + '\n  -g, --growl          Enable growl notifications'
    +    + '\n  -c, --coverage       Generate and report test coverage'
    +    + '\n  -r, --require PATH   Require the given module path'
    +    + '\n  -o, --only TESTS     Execute only the comma sperated TESTS (can be set several times)'
    +    + '\n  -I, --include PATH   Unshift the given path to require.paths'
    +    + '\n  -p, --port NUM       Port number for test servers, starts at 5555'
    +    + '\n  -s, --serial         Execute tests serially'
    +    + '\n  -b, --boring         Suppress ansi-escape colors'
    +    + '\n  -v, --version        Output version number'
    +    + '\n  -h, --help           Display help information'
    +    + '\n';
    +
    +// Parse arguments
    +
    +var files = [],
    +    args = process.argv.slice(2);
    +
    +while (args.length) {
    +    var arg = args.shift();
    +    switch (arg) {
    +        case '-h':
    +        case '--help':
    +            print(usage + '\n');
    +            process.exit(1);
    +            break;
    +        case '-v':
    +        case '--version':
    +            sys.puts(version);
    +            process.exit(1);
    +            break;
    +        case '-i':
    +        case '-I':
    +        case '--include':
    +            if (arg = args.shift()) {
    +                require.paths.unshift(arg);
    +            } else {
    +                throw new Error('--include requires a path');
    +            }
    +            break;
    +        case '-o':
    +        case '--only':
    +            if (arg = args.shift()) {
    +                only = only.concat(arg.split(/ *, */));
    +            } else {
    +                throw new Error('--only requires comma-separated test names');
    +            }
    +            break;
    +        case '-p':
    +        case '--port':
    +            if (arg = args.shift()) {
    +                port = parseInt(arg, 10);
    +            } else {
    +                throw new Error('--port requires a number');
    +            }
    +            break;
    +        case '-r':
    +        case '--require':
    +            if (arg = args.shift()) {
    +                require(arg);
    +            } else {
    +                throw new Error('--require requires a path');
    +            }
    +            break;
    +        case '-c':
    +        case '--cov':
    +        case '--coverage':
    +            defer = true;
    +            childProcess.exec('rm -fr lib-cov && node-jscoverage lib lib-cov', function(err){
    +                if (err) throw err;
    +                require.paths.unshift('lib-cov');
    +                run(files);
    +            })
    +            break;
    +        case '-b':
    +        case '--boring':
    +        	boring = true;
    +        	break;
    +        case '-w':
    +        case '--watch':
    +            watch = true;
    +            break;
    +        case '-g':
    +        case '--growl':
    +            growl = true;
    +            break;
    +        case '-s':
    +        case '--serial':
    +            serial = true;
    +            break;
    +        default:
    +            if (/\.js$/.test(arg)) {
    +                files.push(arg);
    +            }
    +            break;
    +    }
    +}
    +
    +

    Colorized sys.error().

    + +

    + +
    • param: String str

    +
    +
    function print(str){
    +    sys.error(colorize(str));
    +}
    +
    +

    Colorize the given string using ansi-escape sequences. +Disabled when --boring is set.

    + +

    + +
    • param: String str

    • return: String

    +
    +
    function colorize(str){
    +    var colors = { bold: 1, red: 31, green: 32, yellow: 33 };
    +    return str.replace(/\[(\w+)\]\{([^]*?)\}/g, function(_, color, str){
    +        return boring
    +            ? str
    +            : '\x1B[' + colors[color] + 'm' + str + '\x1B[0m';
    +    });
    +}
    +
    +// Alias deepEqual as eql for complex equality
    +
    +assert.eql = assert.deepEqual;
    +
    +

    Assert that val is null.

    + +

    + +
    • param: Mixed val

    • param: String msg

    +
    +
    assert.isNull = function(val, msg) {
    +    assert.strictEqual(null, val, msg);
    +};
    +
    +

    Assert that val is not null.

    + +

    + +
    • param: Mixed val

    • param: String msg

    +
    +
    assert.isNotNull = function(val, msg) {
    +    assert.notStrictEqual(null, val, msg);
    +};
    +
    +

    Assert that val is undefined.

    + +

    + +
    • param: Mixed val

    • param: String msg

    +
    +
    assert.isUndefined = function(val, msg) {
    +    assert.strictEqual(undefined, val, msg);
    +};
    +
    +

    Assert that val is not undefined.

    + +

    + +
    • param: Mixed val

    • param: String msg

    +
    +
    assert.isDefined = function(val, msg) {
    +    assert.notStrictEqual(undefined, val, msg);
    +};
    +
    +

    Assert that obj is type.

    + +

    + +
    • param: Mixed obj

    • param: String type

    • api: public

    +
    +
    assert.type = function(obj, type, msg){
    +    var real = typeof obj;
    +    msg = msg || 'typeof ' + sys.inspect(obj) + ' is ' + real + ', expected ' + type;
    +    assert.ok(type === real, msg);
    +};
    +
    +

    Assert that str matches regexp.

    + +

    + +
    • param: String str

    • param: RegExp regexp

    • param: String msg

    +
    +
    assert.match = function(str, regexp, msg) {
    +    msg = msg || sys.inspect(str) + ' does not match ' + sys.inspect(regexp);
    +    assert.ok(regexp.test(str), msg);
    +};
    +
    +

    Assert that val is within obj.

    + +

    Examples

    + +

    assert.includes('foobar', 'bar'); + assert.includes(['foo', 'bar'], 'foo');

    + +

    + +
    • param: String | Array obj

    • param: Mixed val

    • param: String msg

    +
    +
    assert.includes = function(obj, val, msg) {
    +    msg = msg || sys.inspect(obj) + ' does not include ' + sys.inspect(val);
    +    assert.ok(obj.indexOf(val) &gt;= 0, msg);
    +};
    +
    +

    Assert length of val is n.

    + +

    + +
    • param: Mixed val

    • param: Number n

    • param: String msg

    +
    +
    assert.length = function(val, n, msg) {
    +    msg = msg || sys.inspect(val) + ' has length of ' + val.length + ', expected ' + n;
    +    assert.equal(n, val.length, msg);
    +};
    +
    +

    Assert response from server with +the given req object and res assertions object.

    + +

    + +
    • param: Server server

    • param: Object req

    • param: Object | Function res

    • param: String msg

    +
    +
    assert.response = function(server, req, res, msg){
    +    // Callback as third or fourth arg
    +    var callback = typeof res === 'function'
    +        ? res
    +        : typeof msg === 'function'
    +            ? msg
    +            : function(){};
    +
    +    // Default messate to test title
    +    if (typeof msg === 'function') msg = null;
    +    msg = msg || assert.testTitle;
    +    msg += '. ';
    +
    +    // Pending responses
    +    server.__pending = server.__pending || 0;
    +    server.__pending++;
    +
    +    // Create client
    +    if (!server.fd) {
    +        server.listen(server.__port = port++, '127.0.0.1');
    +        server.client = http.createClient(server.__port);
    +    }
    +
    +    // Issue request
    +    var timer,
    +        client = server.client,
    +        method = req.method || 'GET',
    +        status = res.status || res.statusCode,
    +        data = req.data || req.body,
    +        timeout = req.timeout || 0;
    +
    +    var request = client.request(method, req.url, req.headers);
    +
    +    // Timeout
    +    if (timeout) {
    +        timer = setTimeout(function(){
    +            --server.__pending || server.close();
    +            delete req.timeout;
    +            assert.fail(msg + 'Request timed out after ' + timeout + 'ms.');
    +        }, timeout);
    +    }
    +
    +    if (data) request.write(data);
    +    request.addListener('response', function(response){
    +        response.body = '';
    +        response.setEncoding('utf8');
    +        response.addListener('data', function(chunk){ response.body += chunk; });
    +        response.addListener('end', function(){
    +            --server.__pending || server.close();
    +            if (timer) clearTimeout(timer);
    +
    +            // Assert response body
    +            if (res.body !== undefined) {
    +                assert.equal(
    +                    response.body,
    +                    res.body,
    +                    msg + 'Invalid response body.\n'
    +                        + '    Expected: ' + sys.inspect(res.body) + '\n'
    +                        + '    Got: ' + sys.inspect(response.body)
    +                );
    +            }
    +
    +            // Assert response status
    +            if (typeof status === 'number') {
    +                assert.equal(
    +                    response.statusCode,
    +                    status,
    +                    msg + colorize('Invalid response status code.\n'
    +                        + '    Expected: [green]{' + status + '}\n'
    +                        + '    Got: [red]{' + response.statusCode + '}')
    +                );
    +            }
    +
    +            // Assert response headers
    +            if (res.headers) {
    +                var keys = Object.keys(res.headers);
    +                for (var i = 0, len = keys.length; i &lt; len; ++i) {
    +                    var name = keys[i],
    +                        actual = response.headers[name.toLowerCase()],
    +                        expected = res.headers[name];
    +                    assert.equal(
    +                        actual,
    +                        expected,
    +                        msg + colorize('Invalid response header [bold]{' + name + '}.\n'
    +                            + '    Expected: [green]{' + expected + '}\n'
    +                            + '    Got: [red]{' + actual + '}')
    +                    );
    +                }
    +            }
    +
    +            // Callback
    +            callback(response);
    +        });
    +    });
    +    request.end();
    +};
    +
    +

    Pad the given string to the maximum width provided.

    + +

    + +
    • param: String str

    • param: Number width

    • return: String

    +
    +
    function lpad(str, width) {
    +    str = String(str);
    +    var n = width - str.length;
    +    if (n &lt; 1) return str;
    +    while (n--) str = ' ' + str;
    +    return str;
    +}
    +
    +

    Pad the given string to the maximum width provided.

    + +

    + +
    • param: String str

    • param: Number width

    • return: String

    +
    +
    function rpad(str, width) {
    +    str = String(str);
    +    var n = width - str.length;
    +    if (n &lt; 1) return str;
    +    while (n--) str = str + ' ';
    +    return str;
    +}
    +
    +

    Report test coverage.

    + +

    + +
    • param: Object cov

    +
    +
    function reportCoverage(cov) {
    +    populateCoverage(cov);
    +    // Stats
    +    print('\n   [bold]{Test Coverage}\n');
    +    var sep = '   +------------------------------------------+----------+------+------+--------+',
    +        lastSep = '                                              +----------+------+------+--------+';
    +    sys.puts(sep);
    +    sys.puts('   | filename                                 | coverage | LOC  | SLOC | missed |');
    +    sys.puts(sep);
    +    for (var name in cov) {
    +        var file = cov[name];
    +        if (Array.isArray(file)) {
    +            sys.print('   | ' + rpad(name, 40));
    +            sys.print(' | ' + lpad(file.coverage.toFixed(2), 8));
    +            sys.print(' | ' + lpad(file.LOC, 4));
    +            sys.print(' | ' + lpad(file.SLOC, 4));
    +            sys.print(' | ' + lpad(file.totalMisses, 6));
    +            sys.print(' |\n');
    +        }
    +    }
    +    sys.puts(sep);
    +    sys.print('     ' + rpad('', 40));
    +    sys.print(' | ' + lpad(cov.coverage.toFixed(2), 8));
    +    sys.print(' | ' + lpad(cov.LOC, 4));
    +    sys.print(' | ' + lpad(cov.SLOC, 4));
    +    sys.print(' | ' + lpad(cov.totalMisses, 6));
    +    sys.print(' |\n');
    +    sys.puts(lastSep);
    +    // Source
    +    for (var name in cov) {
    +        if (name.match(/\.js$/)) {
    +            var file = cov[name];
    +            print('\n   [bold]{' + name + '}:');
    +            print(file.source);
    +            sys.print('\n');
    +        }
    +    }
    +}
    +
    +

    Populate code coverage data.

    + +

    + +
    • param: Object cov

    +
    +
    function populateCoverage(cov) {
    +    cov.LOC = 
    +    cov.SLOC =
    +    cov.totalFiles =
    +    cov.totalHits =
    +    cov.totalMisses = 
    +    cov.coverage = 0;
    +    for (var name in cov) {
    +        var file = cov[name];
    +        if (Array.isArray(file)) {
    +            // Stats
    +            ++cov.totalFiles;
    +            cov.totalHits += file.totalHits = coverage(file, true);
    +            cov.totalMisses += file.totalMisses = coverage(file, false);
    +            file.totalLines = file.totalHits + file.totalMisses;
    +            cov.SLOC += file.SLOC = file.totalLines;
    +            if (!file.source) file.source = [];
    +            cov.LOC += file.LOC = file.source.length;
    +            file.coverage = (file.totalHits / file.totalLines) * 100;
    +            // Source
    +            var width = file.source.length.toString().length;
    +            file.source = file.source.map(function(line, i){
    +                ++i;
    +                var hits = file[i] === 0 ? 0 : (file[i] || ' ');
    +                if (!boring) {
    +                    if (hits === 0) {
    +                        hits = '\x1b[31m' + hits + '\x1b[0m';
    +                        line = '\x1b[41m' + line + '\x1b[0m';
    +                    } else {
    +                        hits = '\x1b[32m' + hits + '\x1b[0m';
    +                    }
    +                }
    +                return '\n     ' + lpad(i, width) + ' | ' + hits + ' | ' + line;
    +            }).join('');
    +        }
    +    }
    +    cov.coverage = (cov.totalHits / cov.SLOC) * 100;
    +}
    +
    +

    Total coverage for the given file data.

    + +

    + +
    • param: Array data

    • return: Type

    +
    +
    function coverage(data, val) {
    +    var n = 0;
    +    for (var i = 0, len = data.length; i &lt; len; ++i) {
    +        if (data[i] !== undefined &amp;&amp; data[i] == val) ++n;
    +    }
    +    return n;  
    +}
    +
    +

    Run the given test files, or try test/*.

    + +

    + +
    • param: Array files

    +
    +
    function run(files) {
    +    if (!files.length) {
    +        try {
    +            files = fs.readdirSync('test').map(function(file){
    +                return 'test/' + file;
    +            });
    +        } catch (err) {
    +            print('\n  failed to load tests in [bold]{./test}\n');
    +            ++failures;
    +            process.exit(1);
    +        }
    +    }
    +    if (watch) watchFiles(files);
    +    runFiles(files);
    +}
    +
    +

    Show the cursor when show is true, otherwise hide it.

    + +

    + +
    • param: Boolean show

    +
    +
    function cursor(show) {
    +    if (show) {
    +        sys.print('\x1b[?25h');
    +    } else {
    +        sys.print('\x1b[?25l');
    +    }
    +}
    +
    +

    Run the given test files.

    + +

    + +
    • param: Array files

    +
    +
    function runFiles(files) {
    +    files.forEach(runFile);
    +}
    +
    +

    Run tests for the given file.

    + +

    + +
    • param: String file

    +
    +
    function runFile(file) {
    +    if (file.match(/\.js$/)) {
    +        var title = path.basename(file),
    +            file = path.join(cwd, file),
    +            mod = require(file.replace(/\.js$/, ''));
    +        (function check(){
    +           var len = Object.keys(mod).length;
    +           if (len) {
    +               runSuite(title, mod);
    +           } else {
    +               setTimeout(check, 20);
    +           }
    +        })();
    +    }
    +}
    +
    +

    Clear the module cache for the given file.

    + +

    + +
    • param: String file

    +
    +
    function clearCache(file) {
    +    var keys = Object.keys(module.moduleCache);
    +    for (var i = 0, len = keys.length; i &lt; len; ++i) {
    +        var key = keys[i];
    +        if (key.indexOf(file) === key.length - file.length) {
    +            delete module.moduleCache[key];
    +        }
    +    }
    +}
    +
    +

    Watch the given files for changes.

    + +

    + +
    • param: Array files

    +
    +
    function watchFiles(files) {
    +    var p = 0,
    +        c = ['▫   ', '▫▫  ', '▫▫▫ ', ' ▫▫▫',
    +             '  ▫▫', '   ▫', '   ▫', '  ▫▫',
    +             '▫▫▫ ', '▫▫  ', '▫   '],
    +        l = c.length;
    +    cursor(false);
    +    setInterval(function(){
    +        sys.print(colorize('  [green]{' + c[p++ % l] + '} watching\r'));
    +    }, 100);
    +    files.forEach(function(file){
    +        fs.watchFile(file, { interval: 100 }, function(curr, prev){
    +            if (curr.mtime &gt; prev.mtime) {
    +                print('  [yellow]{◦} ' + file);
    +                clearCache(file);
    +                runFile(file);
    +            }
    +        });
    +    });
    +}
    +
    +

    Report err for the given test and suite.

    + +

    + +
    • param: String suite

    • param: String test

    • param: Error err

    +
    +
    function error(suite, test, err) {
    +    ++failures;
    +    var name = err.name,
    +        stack = err.stack.replace(err.name, ''),
    +        label = test === 'uncaught'
    +            ? test
    +            : suite + ' ' + test;
    +    print('\n   [bold]{' + label + '}: [red]{' + name + '}' + stack + '\n');
    +    if (watch) notify(label + ' failed');
    +}
    +
    +

    Run the given tests.

    + +

    + +
    • param: String title

    • param: Object tests

    +
    +
    var dots = 0;
    +function runSuite(title, tests) {
    +    // Keys
    +    var keys = only.length
    +        ? only.slice(0)
    +        : Object.keys(tests);
    +
    +    // Setup
    +    var setup = tests.setup || function(fn){ fn(); };
    +    
    +    // Iterate tests
    +    (function next(){
    +        if (keys.length) {
    +            var key,
    +                test = tests[key = keys.shift()];
    +            // Non-tests
    +            if (key === 'setup') return next();
    +
    +            // Run test
    +            if (test) {
    +                try {
    +                    ++testcount;
    +                    assert.testTitle = key;
    +                    if (serial) {
    +                        if (!watch) {
    +                            sys.print('.');
    +                            if (++dots % 25 === 0) sys.print('\n');
    +                        }
    +                        setup(function(){
    +                            if (test.length &lt; 2) {
    +                                test(assert);
    +                                next();
    +                            } else {
    +                                var id = setTimeout(function(){
    +                                    throw new Error(&quot;'" + key + "' timed out&quot;);
    +                                }, 2000);
    +                                test(assert, function(){
    +                                    clearTimeout(id);
    +                                    next();
    +                                });
    +                            } 
    +                        });
    +                    } else {
    +                        test(assert, function(fn){
    +                            process.addListener('beforeExit', function(){
    +                                try {
    +                                    fn();
    +                                } catch (err) {
    +                                    error(title, key, err);
    +                                }
    +                            });
    +                        });
    +                    }
    +                } catch (err) {
    +                    error(title, key, err);
    +                }
    +            }
    +            if (!serial) next();
    +        }
    +    })();
    +}
    +
    +

    Report exceptions. +

    +
    +
    function report() {
    +    process.emit('beforeExit');
    +    if (failures) {
    +        print('\n   [bold]{Failures}: [red]{' + failures + '}\n\n');
    +        notify('Failures: ' + failures);
    +    } else {
    +        if (serial) print('');
    +        print('\n   [green]{100%} ' + testcount + ' tests\n');
    +        notify('100% ok');
    +    }
    +    if (typeof _$jscoverage === 'object') {
    +        reportCoverage(_$jscoverage);
    +    }
    +}
    +
    +

    Growl notify the given msg.

    + +

    + +
    • param: String msg

    +
    +
    function notify(msg) {
    +    if (growl) {
    +        childProcess.exec('growlnotify -name Expresso -m "' + msg + '"');
    +    }
    +}
    +
    +// Report uncaught exceptions
    +
    +process.addListener('uncaughtException', function(err){
    +    error('uncaught', 'uncaught', err);
    +});
    +
    +// Show cursor
    +
    +['INT', 'TERM', 'QUIT'].forEach(function(sig){
    +    process.addListener('SIG' + sig, function(){
    +        cursor(true);
    +        process.exit(1);
    +    });
    +});
    +
    +// Report test coverage when available
    +// and emit "beforeExit" event to perform
    +// final assertions
    +
    +var orig = process.emit;
    +process.emit = function(event){
    +    if (event === 'exit') {
    +        report();
    +        process.reallyExit(failures);
    +    }
    +    orig.apply(this, arguments);
    +};
    +
    +// Run test files
    +
    +if (!defer) run(files);
    +
    +
    \ No newline at end of file diff --git a/node_modules/jade/support/expresso/docs/index.html b/node_modules/jade/support/expresso/docs/index.html new file mode 100644 index 0000000..49d8148 --- /dev/null +++ b/node_modules/jade/support/expresso/docs/index.html @@ -0,0 +1,373 @@ + + + Expresso - TDD Framework For Node + + + + + Fork me on GitHub + +
    +

    Expresso

    +
    +

    Expresso is a JavaScript TDD framework written for nodejs. Expresso is extremely fast, and is packed with features such as additional assertion methods, code coverage reporting, CI support, and more.

    + +

    Features

    + +
      +
    • light-weight
    • +
    • intuitive async support
    • +
    • intuitive test runner executable
    • +
    • test coverage support and reporting via node-jscoverage
    • +
    • uses and extends the core assert module
    • +
    • assert.eql() alias of assert.deepEqual()
    • +
    • assert.response() http response utility
    • +
    • assert.includes()
    • +
    • assert.isNull()
    • +
    • assert.isUndefined()
    • +
    • assert.isNotNull()
    • +
    • assert.isDefined()
    • +
    • assert.match()
    • +
    • assert.length()
    • +
    + + +

    Installation

    + +

    To install both expresso and node-jscoverage run +the command below, which will first compile node-jscoverage:

    + +
    $ make install
    +
    + +

    To install expresso alone without coverage reporting run:

    + +
    $ make install-expresso
    +
    + +

    Install via npm:

    + +
    $ npm install expresso
    +
    + +

    Examples

    + +

    To define tests we simply export several functions:

    + +
    exports['test String#length'] = function(assert){
    +    assert.equal(6, 'foobar'.length);
    +};
    +
    + +

    Alternatively for large numbers of tests you may want to +export your own object containing the tests, however this +is essentially the as above:

    + +
    module.exports = {
    +    'test String#length': function(assert){
    +        assert.equal(6, 'foobar'.length);
    +    }
    +};
    +
    + +

    If you prefer not to use quoted keys:

    + +
    exports.testsStringLength = function(assert){
    +    assert.equal(6, 'foobar'.length);
    +};
    +
    + +

    The second argument passed to each callback is beforeExit, +which is typically used to assert that callbacks have been +invoked.

    + +
    exports.testAsync = function(assert, beforeExit){
    +    var n = 0;
    +    setTimeout(function(){
    +        ++n;
    +        assert.ok(true);
    +    }, 200);
    +    setTimeout(function(){
    +        ++n;
    +        assert.ok(true);
    +    }, 200);
    +    beforeExit(function(){
    +        assert.equal(2, n, 'Ensure both timeouts are called');
    +    });
    +};
    +
    + +

    Assert Utilities

    + +

    assert.isNull(val[, msg])

    + +

    Asserts that the given val is null.

    + +
    assert.isNull(null);
    +
    + +

    assert.isNotNull(val[, msg])

    + +

    Asserts that the given val is not null.

    + +
    assert.isNotNull(undefined);
    +assert.isNotNull(false);
    +
    + +

    assert.isUndefined(val[, msg])

    + +

    Asserts that the given val is undefined.

    + +
    assert.isUndefined(undefined);
    +
    + +

    assert.isDefined(val[, msg])

    + +

    Asserts that the given val is not undefined.

    + +
    assert.isDefined(null);
    +assert.isDefined(false);
    +
    + +

    assert.match(str, regexp[, msg])

    + +

    Asserts that the given str matches regexp.

    + +
    assert.match('foobar', /^foo(bar)?/);
    +assert.match('foo', /^foo(bar)?/);
    +
    + +

    assert.length(val, n[, msg])

    + +

    Assert that the given val has a length of n.

    + +
    assert.length([1,2,3], 3);
    +assert.length('foo', 3);
    +
    + +

    assert.type(obj, type[, msg])

    + +

    Assert that the given obj is typeof type.

    + +
    assert.type(3, 'number');
    +
    + +

    assert.eql(a, b[, msg])

    + +

    Assert that object b is equal to object a. This is an +alias for the core assert.deepEqual() method which does complex +comparisons, opposed to assert.equal() which uses ==.

    + +
    assert.eql('foo', 'foo');
    +assert.eql([1,2], [1,2]);
    +assert.eql({ foo: 'bar' }, { foo: 'bar' });
    +
    + +

    assert.includes(obj, val[, msg])

    + +

    Assert that obj is within val. This method supports Array_s +and Strings_s.

    + +
    assert.includes([1,2,3], 3);
    +assert.includes('foobar', 'foo');
    +assert.includes('foobar', 'bar');
    +
    + +

    assert.response(server, req, res|fn[, msg|fn])

    + +

    Performs assertions on the given server, which should not call +listen(), as this is handled internally by expresso and the server +is killed after all responses have completed. This method works with +any http.Server instance, so Connect and Express servers will work +as well.

    + +

    The req object may contain:

    + +
      +
    • url request url
    • +
    • timeout timeout in milliseconds
    • +
    • method HTTP method
    • +
    • data request body
    • +
    • headers headers object
    • +
    + + +

    The res object may be a callback function which +receives the response for assertions, or an object +which is then used to perform several assertions +on the response with the following properties:

    + +
      +
    • body assert response body
    • +
    • status assert response status code
    • +
    • header assert that all given headers match (unspecified are ignored)
    • +
    + + +

    When providing res you may then also pass a callback function +as the fourth argument for additional assertions.

    + +

    Below are some examples:

    + +
    assert.response(server, {
    +    url: '/', timeout: 500
    +}, {
    +    body: 'foobar'
    +});
    +
    +assert.response(server, {
    +    url: '/',
    +    method: 'GET'
    +},{
    +    body: '{"name":"tj"}',
    +    status: 200,
    +    headers: {
    +        'Content-Type': 'application/json; charset=utf8',
    +        'X-Foo': 'bar'
    +    }
    +});
    +
    +assert.response(server, {
    +    url: '/foo',
    +    method: 'POST',
    +    data: 'bar baz'
    +},{
    +    body: '/foo bar baz',
    +    status: 200
    +}, 'Test POST');
    +
    +assert.response(server, {
    +    url: '/foo',
    +    method: 'POST',
    +    data: 'bar baz'
    +},{
    +    body: '/foo bar baz',
    +    status: 200
    +}, function(res){
    +    // All done, do some more tests if needed
    +});
    +
    +assert.response(server, {
    +    url: '/'
    +}, function(res){
    +    assert.ok(res.body.indexOf('tj') >= 0, 'Test assert.response() callback');
    +});
    +
    + +

    expresso(1)

    + +

    To run a single test suite (file) run:

    + +
    $ expresso test/a.test.js
    +
    + +

    To run several suites we may simply append another:

    + +
    $ expresso test/a.test.js test/b.test.js
    +
    + +

    We can also pass a whitelist of tests to run within all suites:

    + +
    $ expresso --only "foo()" --only "bar()"
    +
    + +

    Or several with one call:

    + +
    $ expresso --only "foo(), bar()"
    +
    + +

    Globbing is of course possible as well:

    + +
    $ expresso test/*
    +
    + +

    When expresso is called without any files, test/* is the default, +so the following is equivalent to the command above:

    + +
    $ expresso
    +
    + +

    If you wish to unshift a path to require.paths before +running tests, you may use the -I or --include flag.

    + +
    $ expresso --include lib test/*
    +
    + +

    The previous example is typically what I would recommend, since expresso +supports test coverage via node-jscoverage (bundled with expresso), +so you will need to expose an instrumented version of you library.

    + +

    To instrument your library, simply run node-jscoverage, +passing the src and dest directories:

    + +
    $ node-jscoverage lib lib-cov
    +
    + +

    Now we can run our tests again, using the lib-cov directory that has been +instrumented with coverage statements:

    + +
    $ expresso -I lib-cov test/*
    +
    + +

    The output will look similar to below, depending on your test coverage of course :)

    + +

    node coverage

    + +

    To make this process easier expresso has the -c or --cov which essentially +does the same as the two commands above. The following two commands will +run the same tests, however one will auto-instrument, and unshift lib-cov, +and the other will run tests normally:

    + +
    $ expresso -I lib test/*
    +$ expresso -I lib --cov test/*
    +
    + +

    Currently coverage is bound to the lib directory, however in the +future --cov will most likely accept a path.

    + +

    Async Exports

    + +

    Sometimes it is useful to postpone running of tests until a callback or event has fired, currently the exports.foo = function(){}; syntax is supported for this:

    + +
    setTimeout(function(){
    +    exports['test async exports'] = function(assert){
    +        assert.ok('wahoo');
    +    };
    +}, 100);
    +
    + +
    +
    + + \ No newline at end of file diff --git a/node_modules/jade/support/expresso/docs/index.md b/node_modules/jade/support/expresso/docs/index.md new file mode 100644 index 0000000..5376e59 --- /dev/null +++ b/node_modules/jade/support/expresso/docs/index.md @@ -0,0 +1,290 @@ + +[Expresso](http://github.com/visionmedia/expresso) is a JavaScript [TDD](http://en.wikipedia.org/wiki/Test-driven_development) framework written for [nodejs](http://nodejs.org). Expresso is extremely fast, and is packed with features such as additional assertion methods, code coverage reporting, CI support, and more. + +## Features + + - light-weight + - intuitive async support + - intuitive test runner executable + - test coverage support and reporting via [node-jscoverage](http://github.com/visionmedia/node-jscoverage) + - uses and extends the core _assert_ module + - `assert.eql()` alias of `assert.deepEqual()` + - `assert.response()` http response utility + - `assert.includes()` + - `assert.isNull()` + - `assert.isUndefined()` + - `assert.isNotNull()` + - `assert.isDefined()` + - `assert.match()` + - `assert.length()` + +## Installation + +To install both expresso _and_ node-jscoverage run +the command below, which will first compile node-jscoverage: + + $ make install + +To install expresso alone without coverage reporting run: + + $ make install-expresso + +Install via npm: + + $ npm install expresso + +## Examples + +To define tests we simply export several functions: + + exports['test String#length'] = function(assert){ + assert.equal(6, 'foobar'.length); + }; + +Alternatively for large numbers of tests you may want to +export your own object containing the tests, however this +is essentially the as above: + + module.exports = { + 'test String#length': function(assert){ + assert.equal(6, 'foobar'.length); + } + }; + +If you prefer not to use quoted keys: + + exports.testsStringLength = function(assert){ + assert.equal(6, 'foobar'.length); + }; + +The second argument passed to each callback is _beforeExit_, +which is typically used to assert that callbacks have been +invoked. + + exports.testAsync = function(assert, beforeExit){ + var n = 0; + setTimeout(function(){ + ++n; + assert.ok(true); + }, 200); + setTimeout(function(){ + ++n; + assert.ok(true); + }, 200); + beforeExit(function(){ + assert.equal(2, n, 'Ensure both timeouts are called'); + }); + }; + +## Assert Utilities + +### assert.isNull(val[, msg]) + +Asserts that the given _val_ is _null_. + + assert.isNull(null); + +### assert.isNotNull(val[, msg]) + +Asserts that the given _val_ is not _null_. + + assert.isNotNull(undefined); + assert.isNotNull(false); + +### assert.isUndefined(val[, msg]) + +Asserts that the given _val_ is _undefined_. + + assert.isUndefined(undefined); + +### assert.isDefined(val[, msg]) + +Asserts that the given _val_ is not _undefined_. + + assert.isDefined(null); + assert.isDefined(false); + +### assert.match(str, regexp[, msg]) + +Asserts that the given _str_ matches _regexp_. + + assert.match('foobar', /^foo(bar)?/); + assert.match('foo', /^foo(bar)?/); + +### assert.length(val, n[, msg]) + +Assert that the given _val_ has a length of _n_. + + assert.length([1,2,3], 3); + assert.length('foo', 3); + +### assert.type(obj, type[, msg]) + +Assert that the given _obj_ is typeof _type_. + + assert.type(3, 'number'); + +### assert.eql(a, b[, msg]) + +Assert that object _b_ is equal to object _a_. This is an +alias for the core _assert.deepEqual()_ method which does complex +comparisons, opposed to _assert.equal()_ which uses _==_. + + assert.eql('foo', 'foo'); + assert.eql([1,2], [1,2]); + assert.eql({ foo: 'bar' }, { foo: 'bar' }); + +### assert.includes(obj, val[, msg]) + +Assert that _obj_ is within _val_. This method supports _Array_s +and _Strings_s. + + assert.includes([1,2,3], 3); + assert.includes('foobar', 'foo'); + assert.includes('foobar', 'bar'); + +### assert.response(server, req, res|fn[, msg|fn]) + +Performs assertions on the given _server_, which should _not_ call +listen(), as this is handled internally by expresso and the server +is killed after all responses have completed. This method works with +any _http.Server_ instance, so _Connect_ and _Express_ servers will work +as well. + +The _req_ object may contain: + + - _url_ request url + - _timeout_ timeout in milliseconds + - _method_ HTTP method + - _data_ request body + - _headers_ headers object + +The _res_ object may be a callback function which +receives the response for assertions, or an object +which is then used to perform several assertions +on the response with the following properties: + + - _body_ assert response body + - _status_ assert response status code + - _header_ assert that all given headers match (unspecified are ignored) + +When providing _res_ you may then also pass a callback function +as the fourth argument for additional assertions. + +Below are some examples: + + assert.response(server, { + url: '/', timeout: 500 + }, { + body: 'foobar' + }); + + assert.response(server, { + url: '/', + method: 'GET' + },{ + body: '{"name":"tj"}', + status: 200, + headers: { + 'Content-Type': 'application/json; charset=utf8', + 'X-Foo': 'bar' + } + }); + + assert.response(server, { + url: '/foo', + method: 'POST', + data: 'bar baz' + },{ + body: '/foo bar baz', + status: 200 + }, 'Test POST'); + + assert.response(server, { + url: '/foo', + method: 'POST', + data: 'bar baz' + },{ + body: '/foo bar baz', + status: 200 + }, function(res){ + // All done, do some more tests if needed + }); + + assert.response(server, { + url: '/' + }, function(res){ + assert.ok(res.body.indexOf('tj') >= 0, 'Test assert.response() callback'); + }); + + +## expresso(1) + +To run a single test suite (file) run: + + $ expresso test/a.test.js + +To run several suites we may simply append another: + + $ expresso test/a.test.js test/b.test.js + +We can also pass a whitelist of tests to run within all suites: + + $ expresso --only "foo()" --only "bar()" + +Or several with one call: + + $ expresso --only "foo(), bar()" + +Globbing is of course possible as well: + + $ expresso test/* + +When expresso is called without any files, _test/*_ is the default, +so the following is equivalent to the command above: + + $ expresso + +If you wish to unshift a path to `require.paths` before +running tests, you may use the `-I` or `--include` flag. + + $ expresso --include lib test/* + +The previous example is typically what I would recommend, since expresso +supports test coverage via [node-jscoverage](http://github.com/visionmedia/node-jscoverage) (bundled with expresso), +so you will need to expose an instrumented version of you library. + +To instrument your library, simply run [node-jscoverage](http://github.com/visionmedia/node-jscoverage), +passing the _src_ and _dest_ directories: + + $ node-jscoverage lib lib-cov + +Now we can run our tests again, using the _lib-cov_ directory that has been +instrumented with coverage statements: + + $ expresso -I lib-cov test/* + +The output will look similar to below, depending on your test coverage of course :) + +![node coverage](http://dl.dropbox.com/u/6396913/cov.png) + +To make this process easier expresso has the _-c_ or _--cov_ which essentially +does the same as the two commands above. The following two commands will +run the same tests, however one will auto-instrument, and unshift _lib-cov_, +and the other will run tests normally: + + $ expresso -I lib test/* + $ expresso -I lib --cov test/* + +Currently coverage is bound to the _lib_ directory, however in the +future `--cov` will most likely accept a path. + +## Async Exports + +Sometimes it is useful to postpone running of tests until a callback or event has fired, currently the _exports.foo = function(){};_ syntax is supported for this: + + setTimeout(function(){ + exports['test async exports'] = function(assert){ + assert.ok('wahoo'); + }; + }, 100); diff --git a/node_modules/jade/support/expresso/docs/layout/foot.html b/node_modules/jade/support/expresso/docs/layout/foot.html new file mode 100644 index 0000000..44d85e9 --- /dev/null +++ b/node_modules/jade/support/expresso/docs/layout/foot.html @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/node_modules/jade/support/expresso/docs/layout/head.html b/node_modules/jade/support/expresso/docs/layout/head.html new file mode 100644 index 0000000..567f62e --- /dev/null +++ b/node_modules/jade/support/expresso/docs/layout/head.html @@ -0,0 +1,42 @@ + + + Expresso - TDD Framework For Node + + + + + Fork me on GitHub + +
    +

    Expresso

    diff --git a/node_modules/jade/support/expresso/lib/bar.js b/node_modules/jade/support/expresso/lib/bar.js new file mode 100644 index 0000000..e15aad4 --- /dev/null +++ b/node_modules/jade/support/expresso/lib/bar.js @@ -0,0 +1,4 @@ + +exports.bar = function(msg){ + return msg || 'bar'; +}; \ No newline at end of file diff --git a/node_modules/jade/support/expresso/lib/foo.js b/node_modules/jade/support/expresso/lib/foo.js new file mode 100644 index 0000000..15701a5 --- /dev/null +++ b/node_modules/jade/support/expresso/lib/foo.js @@ -0,0 +1,16 @@ + +exports.foo = function(msg){ + if (msg) { + return msg; + } else { + return generateFoo(); + } +}; + +function generateFoo() { + return 'foo'; +} + +function Foo(msg){ + this.msg = msg || 'foo'; +} diff --git a/node_modules/jade/support/expresso/package.json b/node_modules/jade/support/expresso/package.json new file mode 100644 index 0000000..572935f --- /dev/null +++ b/node_modules/jade/support/expresso/package.json @@ -0,0 +1,12 @@ +{ "name": "expresso", + "version": "0.6.2", + "description": "TDD framework, light-weight, fast, CI-friendly", + "author": "TJ Holowaychuk ", + "bin": { + "expresso": "./bin/expresso", + "node-jscoverage": "./deps/jscoverage/node-jscoverage" + }, + "scripts": { + "preinstall": "make deps/jscoverage/node-jscoverage" + } +} \ No newline at end of file diff --git a/node_modules/jade/support/expresso/test/assert.test.js b/node_modules/jade/support/expresso/test/assert.test.js new file mode 100644 index 0000000..6a5e764 --- /dev/null +++ b/node_modules/jade/support/expresso/test/assert.test.js @@ -0,0 +1,84 @@ +module.exports = { + 'assert.eql()': function(assert){ + assert.equal(assert.deepEqual, assert.eql); + }, + + 'assert.type()': function(assert){ + assert.type('foobar', 'string'); + assert.type(2, 'number'); + assert.throws(function(){ + assert.type([1,2,3], 'string'); + }); + }, + + 'assert.includes()': function(assert){ + assert.includes('some random string', 'dom'); + assert.throws(function(){ + assert.include('some random string', 'foobar'); + }); + + assert.includes(['foo', 'bar'], 'bar'); + assert.includes(['foo', 'bar'], 'foo'); + assert.includes([1,2,3], 3); + assert.includes([1,2,3], 2); + assert.includes([1,2,3], 1); + assert.throws(function(){ + assert.includes(['foo', 'bar'], 'baz'); + }); + + assert.throws(function(){ + assert.includes({ wrong: 'type' }, 'foo'); + }); + }, + + 'assert.isNull()': function(assert){ + assert.isNull(null); + assert.throws(function(){ + assert.isNull(undefined); + }); + assert.throws(function(){ + assert.isNull(false); + }); + }, + + 'assert.isUndefined()': function(assert){ + assert.isUndefined(undefined); + assert.throws(function(){ + assert.isUndefined(null); + }); + assert.throws(function(){ + assert.isUndefined(false); + }); + }, + + 'assert.isNotNull()': function(assert){ + assert.isNotNull(false); + assert.isNotNull(undefined); + assert.throws(function(){ + assert.isNotNull(null); + }); + }, + + 'assert.isDefined()': function(assert){ + assert.isDefined(false); + assert.isDefined(null); + assert.throws(function(){ + assert.isDefined(undefined); + }); + }, + + 'assert.match()': function(assert){ + assert.match('foobar', /foo(bar)?/); + assert.throws(function(){ + assert.match('something', /rawr/); + }); + }, + + 'assert.length()': function(assert){ + assert.length('test', 4); + assert.length([1,2,3,4], 4); + assert.throws(function(){ + assert.length([1,2,3], 4); + }); + } +}; \ No newline at end of file diff --git a/node_modules/jade/support/expresso/test/async.test.js b/node_modules/jade/support/expresso/test/async.test.js new file mode 100644 index 0000000..0dc9016 --- /dev/null +++ b/node_modules/jade/support/expresso/test/async.test.js @@ -0,0 +1,6 @@ + +setTimeout(function(){ + exports['test async exports'] = function(assert){ + assert.ok('wahoo'); + }; +}, 100); \ No newline at end of file diff --git a/node_modules/jade/support/expresso/test/bar.test.js b/node_modules/jade/support/expresso/test/bar.test.js new file mode 100644 index 0000000..68e8d48 --- /dev/null +++ b/node_modules/jade/support/expresso/test/bar.test.js @@ -0,0 +1,12 @@ + +/** + * Module dependencies. + */ + +var bar = require('bar'); + +module.exports = { + 'bar()': function(assert){ + assert.equal('bar', bar.bar()); + } +}; \ No newline at end of file diff --git a/node_modules/jade/support/expresso/test/foo.test.js b/node_modules/jade/support/expresso/test/foo.test.js new file mode 100644 index 0000000..5d9d94e --- /dev/null +++ b/node_modules/jade/support/expresso/test/foo.test.js @@ -0,0 +1,13 @@ + +/** + * Module dependencies. + */ + +var foo = require('foo'); + +module.exports = { + 'foo()': function(assert){ + assert.equal('foo', foo.foo()); + assert.equal('foo', foo.foo()); + } +}; \ No newline at end of file diff --git a/node_modules/jade/support/expresso/test/http.test.js b/node_modules/jade/support/expresso/test/http.test.js new file mode 100644 index 0000000..3a44bec --- /dev/null +++ b/node_modules/jade/support/expresso/test/http.test.js @@ -0,0 +1,82 @@ + +/** + * Module dependencies. + */ + +var http = require('http'); + +var server = http.createServer(function(req, res){ + if (req.method === 'GET') { + if (req.url === '/delay') { + setTimeout(function(){ + res.writeHead(200, {}); + res.end('delayed'); + }, 200); + } else { + var body = JSON.stringify({ name: 'tj' }); + res.writeHead(200, { + 'Content-Type': 'application/json; charset=utf8', + 'Content-Length': body.length + }); + res.end(body); + } + } else { + var body = ''; + req.setEncoding('utf8'); + req.addListener('data', function(chunk){ body += chunk }); + req.addListener('end', function(){ + res.writeHead(200, {}); + res.end(req.url + ' ' + body); + }); + } +}); + +module.exports = { + 'test assert.response()': function(assert, beforeExit){ + var called = 0; + + assert.response(server, { + url: '/', + method: 'GET' + },{ + body: '{"name":"tj"}', + status: 200, + headers: { + 'Content-Type': 'application/json; charset=utf8' + } + }); + + assert.response(server, { + url: '/foo', + method: 'POST', + data: 'bar baz' + },{ + body: '/foo bar baz', + status: 200 + }, function(res){ + ++called; + assert.ok(res); + }); + + assert.response(server, { + url: '/foo' + }, function(res){ + ++called; + assert.ok(res.body.indexOf('tj') >= 0, 'Test assert.response() callback'); + }); + + assert.response(server, + { url: '/delay', timeout: 300 }, + { body: 'delayed' }); + + beforeExit(function(){ + assert.equal(2, called); + }); + }, + + 'test assert.response() regexp': function(assert){ + assert.response(server, + { url: '/foo', method: 'POST', data: 'foobar' }, + { body: /^\/foo foo(bar)?/ }); + } +}; \ No newline at end of file diff --git a/node_modules/jade/support/expresso/test/serial/async.test.js b/node_modules/jade/support/expresso/test/serial/async.test.js new file mode 100644 index 0000000..292f96c --- /dev/null +++ b/node_modules/jade/support/expresso/test/serial/async.test.js @@ -0,0 +1,38 @@ + +var setup = 0, + order = []; + +module.exports = { + setup: function(done){ + ++setup; + done(); + }, + + a: function(assert, done){ + assert.equal(1, setup); + order.push('a'); + setTimeout(function(){ + done(); + }, 500); + }, + + b: function(assert, done){ + assert.equal(2, setup); + order.push('b'); + setTimeout(function(){ + done(); + }, 200); + }, + + c: function(assert, done){ + assert.equal(3, setup); + order.push('c'); + setTimeout(function(){ + done(); + }, 1000); + }, + + d: function(assert){ + assert.eql(order, ['a', 'b', 'c']); + } +}; \ No newline at end of file diff --git a/node_modules/jade/support/expresso/test/serial/http.test.js b/node_modules/jade/support/expresso/test/serial/http.test.js new file mode 100644 index 0000000..3d19557 --- /dev/null +++ b/node_modules/jade/support/expresso/test/serial/http.test.js @@ -0,0 +1,47 @@ + +/** + * Module dependencies. + */ + +var http = require('http'); + +var server = http.createServer(function(req, res){ + if (req.method === 'GET') { + if (req.url === '/delay') { + setTimeout(function(){ + res.writeHead(200, {}); + res.end('delayed'); + }, 200); + } else { + var body = JSON.stringify({ name: 'tj' }); + res.writeHead(200, { + 'Content-Type': 'application/json; charset=utf8', + 'Content-Length': body.length + }); + res.end(body); + } + } else { + var body = ''; + req.setEncoding('utf8'); + req.addListener('data', function(chunk){ body += chunk }); + req.addListener('end', function(){ + res.writeHead(200, {}); + res.end(req.url + ' ' + body); + }); + } +}); + +module.exports = { + 'test assert.response()': function(assert, done){ + assert.response(server, { + url: '/', + method: 'GET' + },{ + body: '{"name":"tj"}', + status: 200, + headers: { + 'Content-Type': 'application/json; charset=utf8' + } + }, done); + } +}; \ No newline at end of file diff --git a/node_modules/jade/support/foot.js b/node_modules/jade/support/foot.js new file mode 100644 index 0000000..92f4251 --- /dev/null +++ b/node_modules/jade/support/foot.js @@ -0,0 +1,4 @@ + + return exports; + +})({}); \ No newline at end of file diff --git a/node_modules/jade/support/head.js b/node_modules/jade/support/head.js new file mode 100644 index 0000000..83775aa --- /dev/null +++ b/node_modules/jade/support/head.js @@ -0,0 +1,2 @@ + +var jade = (function(exports){ \ No newline at end of file diff --git a/node_modules/jade/support/sass/.gitignore b/node_modules/jade/support/sass/.gitignore new file mode 100644 index 0000000..4adf993 --- /dev/null +++ b/node_modules/jade/support/sass/.gitignore @@ -0,0 +1,7 @@ +*.seed +*.cache +*.log +.DS_Store +pkg +build +bin \ No newline at end of file diff --git a/node_modules/jade/support/sass/History.md b/node_modules/jade/support/sass/History.md new file mode 100644 index 0000000..01992cf --- /dev/null +++ b/node_modules/jade/support/sass/History.md @@ -0,0 +1,42 @@ + +0.4.2 / 2010-06-21 +================== + + * Added lib directory to package.json for npm to work + +0.4.1 / 2010-06-21 +================== + + * Addex index.js for npm support + +0.4.0 / 2010-04-02 +================== + + * Added "cache" option + +0.3.0 / 2010-02-22 +================== + + * Added mixin support. Closes #1 + +0.2.0 / 2010-02-05 +================== + + * Added alternate variable syntax back ("var: val") + * Added a method to extract variables. Closes #3 + +0.1.0 / 2010-02-05 +================== + + * Added continuation support. Closes #15 + +0.0.2 / 2010-02-02 +================== + + * Fixed complex selectors + * Removed "var: val" syntax for variables + +0.0.1 / 2010-01-12 +================== + + * Initial release diff --git a/node_modules/jade/support/sass/Makefile b/node_modules/jade/support/sass/Makefile new file mode 100644 index 0000000..f7e6985 --- /dev/null +++ b/node_modules/jade/support/sass/Makefile @@ -0,0 +1,11 @@ + +all: test + +test: spec/node.js + @node spec/node.js + +benchmark: + @node benchmarks/large.js + +.PHONY: test benchmark + \ No newline at end of file diff --git a/node_modules/jade/support/sass/Readme.md b/node_modules/jade/support/sass/Readme.md new file mode 100644 index 0000000..93a5ab6 --- /dev/null +++ b/node_modules/jade/support/sass/Readme.md @@ -0,0 +1,167 @@ + +# Sass.js + + JavaScript implementation of Sass. Great for **node.js** and other + frameworks supporting the CommonJS module system. + +## Installation + + Install the [Kiwi package manager for nodejs](http://github.com/visionmedia/kiwi) + and run: + + $ kiwi install sass + +Or npm: + + $ npm install sass + +## Usage + + var sass = require('sass') + sass.render('... string of sass ...') + // => '... string of css ...' + + sass.collect('... string of sass ...') + // => { selectors: [...], variables: { ... }, mixins: { ... }} + +## Comments + + // foo + body + // bar + a + :color #fff + +compiles to + + body a { + color: #fff;} + +## Variables + + !red = #ff0000 + body + :color !red + +and + + red: #ff0000 + body + :color !red + +compile to + + body { + color: #ff0000;} + +## Selector Continuations + + a + :color #fff + &:hover + :color #000 + &.active + :background #888 + &:hover + :color #fff + +compiles to + + a { + color: #fff;} + + a:hover { + color: #000;} + + a.active { + background: #888;} + + a.active:hover { + color: #fff;} + +## Literal JavaScript + + type: "solid" + size: 1 + input + :border { parseInt(size) + 1 }px {type} #000 + +compiles to + + input { + border: 2px "solid" #000;} + +## Property Expansion + + div + =border-radius 5px + +compiles to + + div { + -webkit-border-radius: 5px; + -moz-border-radius: 5px;} + +## Mixins + + +large + :font-size 15px + +striped + tr + :background #fff + +large + &:odd + :background #000 + table + +striped + :border none + +compiles to + + table { + border: none;} + table tr { + background: #fff;} + table tr { + font-size: 15px;} + table tr:odd { + background: #000;} + + +## Testing + +Update Git submodules and execute: + $ make test +or + $ node spec/node.js +or + $ jspec --node + +## More Information + +* Featured in [Advanced JavaScript e-book](http://www.dev-mag.com/2010/02/18/advanced-javascript/) for only $4 + +## License + +(The MIT License) + +Copyright (c) 2009 TJ Holowaychuk <tj@vision-media.ca> + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/node_modules/jade/support/sass/index.js b/node_modules/jade/support/sass/index.js new file mode 120000 index 0000000..7fb84a5 --- /dev/null +++ b/node_modules/jade/support/sass/index.js @@ -0,0 +1 @@ +lib/sass.js \ No newline at end of file diff --git a/node_modules/jade/support/sass/lib/sass.js b/node_modules/jade/support/sass/lib/sass.js new file mode 100644 index 0000000..a72e49d --- /dev/null +++ b/node_modules/jade/support/sass/lib/sass.js @@ -0,0 +1,299 @@ + +// Sass - Core - Copyright TJ Holowaychuk (MIT Licensed) + +/** + * Library version. + */ + +exports.version = '0.4.3' + +/** + * Compiled sass cache. + */ + +var cache = {} + +/** + * Sass grammar tokens. + */ + +var tokens = [ + ['indent', /^\n +/], + ['space', /^ +/], + ['nl', /^\n/], + ['js', /^{(.*?)}/], + ['comment', /^\/\/(.*)/], + ['string', /^(?:'(.*?)'|"(.*?)")/], + ['variable', /^!([\w\-]+) *= *([^\n]+)/], + ['variable.alternate', /^([\w\-]+): +([^\n]+)/], + ['property.expand', /^=([\w\-]+) *([^\n]+)/], + ['property', /^:([\w\-]+) *([^\n]+)/], + ['continuation', /^&(.+)/], + ['mixin', /^\+([\w\-]+)/], + ['selector', /^(.+)/] +] + +/** + * Vendor-specific expansion prefixes. + */ + +exports.expansions = ['-moz-', '-webkit-'] + +/** + * Tokenize the given _str_. + * + * @param {string} str + * @return {array} + * @api private + */ + +function tokenize(str) { + var token, captures, stack = [] + while (str.length) { + for (var i = 0, len = tokens.length; i < len; ++i) + if (captures = tokens[i][1].exec(str)) { + token = [tokens[i][0], captures], + str = str.replace(tokens[i][1], '') + break + } + if (token) + stack.push(token), + token = null + else + throw new Error("SyntaxError: near `" + str.slice(0, 25).replace('\n', '\\n') + "'") + } + return stack +} + +/** + * Parse the given _tokens_, returning + * and hash containing the properties below: + * + * selectors: array of top-level selectors + * variables: hash of variables defined + * + * @param {array} tokens + * @return {hash} + * @api private + */ + +function parse(tokens) { + var token, selector, + data = { variables: {}, mixins: {}, selectors: [] }, + line = 1, + lastIndents = 0, + indents = 0 + + /** + * Output error _msg_ in context to the current line. + */ + + function error(msg) { + throw new Error('ParseError: on line ' + line + '; ' + msg) + } + + /** + * Reset parents until the indentation levels match. + */ + + function reset() { + if (indents === 0) + return selector = null + while (lastIndents-- > indents) + selector = selector.parent + } + + // Parse tokens + + while (token = tokens.shift()) + switch (token[0]) { + case 'mixin': + if (indents) { + var mixin = data.mixins[token[1][1]] + if (!mixin) error("mixin `" + token[1][1] + "' does not exist") + mixin.parent = selector + selector.children.push(mixin) + } + else + data.mixins[token[1][1]] = selector = new Selector(token[1][1], null, 'mixin') + break + case 'continuation': + reset() + selector = new Selector(token[1][1], selector, 'continuation') + break + case 'selector': + reset() + selector = new Selector(token[1][1], selector) + if (!selector.parent) + data.selectors.push(selector) + break + case 'property': + reset() + if (!selector) error('properties must be nested within a selector') + var val = token[1][2] + .replace(/!([\w\-]+)/g, function(orig, name){ + return data.variables[name] || orig + }) + .replace(/\{(.*?)\}/g, function(_, js){ + with (data.variables){ return eval(js) } + }) + selector.properties.push(new Property(token[1][1], val)) + break + case 'property.expand': + exports.expansions.forEach(function(prefix){ + tokens.unshift(['property', [, prefix + token[1][1], token[1][2]]]) + }) + break + case 'variable': + case 'variable.alternate': + data.variables[token[1][1]] = token[1][2] + break + case 'js': + with (data.variables){ eval(token[1][1]) } + break + case 'nl': + ++line, indents = 0 + break + case 'comment': + break + case 'indent': + ++line + lastIndents = indents, + indents = (token[1][0].length - 1) / 2 + if (indents > lastIndents && + indents - 1 > lastIndents) + error('invalid indentation, to much nesting') + } + return data +} + +/** + * Compile _selectors_ to a string of css. + * + * @param {array} selectors + * @return {string} + * @api private + */ + +function compile(selectors) { + return selectors.join('\n') +} + +/** + * Collect data by parsing _sass_. + * Returns a hash containing the following properties: + * + * selectors: array of top-level selectors + * variables: hash of variables defined + * + * @param {string} sass + * @return {hash} + * @api public + */ + +exports.collect = function(sass) { + return parse(tokenize(sass)) +} + +/** + * Render a string of _sass_. + * + * Options: + * + * - filename Optional filename to aid in error reporting + * - cache Optional caching of compiled content. Requires "filename" option + * + * @param {string} sass + * @param {object} options + * @return {string} + * @api public + */ + +exports.render = function(sass, options) { + options = options || {} + if (options.cache && !options.filename) + throw new Error('filename option must be passed when cache is enabled') + if (options.cache) + return cache[options.filename] + ? cache[options.filename] + : cache[options.filename] = compile(exports.collect(sass).selectors) + return compile(exports.collect(sass).selectors) +} + +// --- Selector + +/** + * Initialize a selector with _string_ and + * optional _parent_. + * + * @param {string} string + * @param {Selector} parent + * @param {string} type + * @api private + */ + +function Selector(string, parent, type) { + this.string = string + this.parent = parent + this.properties = [] + this.children = [] + if (type) this[type] = true + if (parent) parent.children.push(this) +} + +/** + * Return selector string. + * + * @return {string} + * @api private + */ + +Selector.prototype.selector = function() { + var selector = this.string + if (this.parent) + selector = this.continuation + ? this.parent.selector() + selector + : this.mixin + ? this.parent.selector() + : this.parent.selector() + ' ' + selector + return selector +} + +/** + * Return selector and nested selectors as CSS. + * + * @return {string} + * @api private + */ + +Selector.prototype.toString = function() { + return (this.properties.length + ? this.selector() + ' {\n' + this.properties.join('\n') + '}\n' + : '') + this.children.join('') +} + +// --- Property + +/** + * Initialize property with _name_ and _val_. + * + * @param {string} name + * @param {string} val + * @api private + */ + +function Property(name, val) { + this.name = name + this.val = val +} + +/** + * Return CSS string representing a property. + * + * @return {string} + * @api private + */ + +Property.prototype.toString = function() { + return ' ' + this.name + ': ' + this.val + ';' +} diff --git a/node_modules/jade/support/sass/package.json b/node_modules/jade/support/sass/package.json new file mode 100644 index 0000000..250e3bc --- /dev/null +++ b/node_modules/jade/support/sass/package.json @@ -0,0 +1,10 @@ +{ + "name": "sass", + "description": "Syntactically Awesome Stylesheets (compiles to css)", + "version": "0.4.3", + "keywords": ["sass", "template", "css", "view"], + "author": "TJ Holowaychuk ", + "directories": { + "lib": "." + } +} \ No newline at end of file diff --git a/node_modules/jade/support/sass/seed.yml b/node_modules/jade/support/sass/seed.yml new file mode 100644 index 0000000..7f95bf5 --- /dev/null +++ b/node_modules/jade/support/sass/seed.yml @@ -0,0 +1,4 @@ +--- + name: Sass + description: Syntactically Awesome Stylesheets (compiles to css) + version: 0.4.3 diff --git a/node_modules/jade/support/sass/spec/fixtures/collect.sass b/node_modules/jade/support/sass/spec/fixtures/collect.sass new file mode 100644 index 0000000..ad7d202 --- /dev/null +++ b/node_modules/jade/support/sass/spec/fixtures/collect.sass @@ -0,0 +1,3 @@ + +!red = #ff0000 +!black = #000 \ No newline at end of file diff --git a/node_modules/jade/support/sass/spec/fixtures/comment.css b/node_modules/jade/support/sass/spec/fixtures/comment.css new file mode 100644 index 0000000..e81583f --- /dev/null +++ b/node_modules/jade/support/sass/spec/fixtures/comment.css @@ -0,0 +1,2 @@ +body a { + color: #fff;} diff --git a/node_modules/jade/support/sass/spec/fixtures/comment.sass b/node_modules/jade/support/sass/spec/fixtures/comment.sass new file mode 100644 index 0000000..eaad554 --- /dev/null +++ b/node_modules/jade/support/sass/spec/fixtures/comment.sass @@ -0,0 +1,6 @@ + +// foo +body + // bar + a + :color #fff diff --git a/node_modules/jade/support/sass/spec/fixtures/continuation.css b/node_modules/jade/support/sass/spec/fixtures/continuation.css new file mode 100644 index 0000000..6958788 --- /dev/null +++ b/node_modules/jade/support/sass/spec/fixtures/continuation.css @@ -0,0 +1,8 @@ +a { + color: #fff;} +a:hover { + color: #000;} +a.active { + background: #888;} +a.active:hover { + color: #fff;} diff --git a/node_modules/jade/support/sass/spec/fixtures/continuation.sass b/node_modules/jade/support/sass/spec/fixtures/continuation.sass new file mode 100644 index 0000000..d07b101 --- /dev/null +++ b/node_modules/jade/support/sass/spec/fixtures/continuation.sass @@ -0,0 +1,8 @@ +a + :color #fff + &:hover + :color #000 + &.active + :background #888 + &:hover + :color #fff \ No newline at end of file diff --git a/node_modules/jade/support/sass/spec/fixtures/literal.css b/node_modules/jade/support/sass/spec/fixtures/literal.css new file mode 100644 index 0000000..cc4d5a6 --- /dev/null +++ b/node_modules/jade/support/sass/spec/fixtures/literal.css @@ -0,0 +1,2 @@ +input { + border: 2px "solid" #000;} diff --git a/node_modules/jade/support/sass/spec/fixtures/literal.sass b/node_modules/jade/support/sass/spec/fixtures/literal.sass new file mode 100644 index 0000000..c207d37 --- /dev/null +++ b/node_modules/jade/support/sass/spec/fixtures/literal.sass @@ -0,0 +1,4 @@ +!type = "solid" +!size = 1 +input + :border { parseInt(size) + 1 }px {type} #000 \ No newline at end of file diff --git a/node_modules/jade/support/sass/spec/fixtures/mixin.css b/node_modules/jade/support/sass/spec/fixtures/mixin.css new file mode 100644 index 0000000..6ddc778 --- /dev/null +++ b/node_modules/jade/support/sass/spec/fixtures/mixin.css @@ -0,0 +1,8 @@ +table { + border: none;} +table tr { + background: #fff;} +table tr { + font-size: 15px;} +table tr:odd { + background: #000;} diff --git a/node_modules/jade/support/sass/spec/fixtures/mixin.sass b/node_modules/jade/support/sass/spec/fixtures/mixin.sass new file mode 100644 index 0000000..a27a945 --- /dev/null +++ b/node_modules/jade/support/sass/spec/fixtures/mixin.sass @@ -0,0 +1,11 @@ ++large + :font-size 15px ++striped + tr + :background #fff + +large + &:odd + :background #000 +table + +striped + :border none \ No newline at end of file diff --git a/node_modules/jade/support/sass/spec/fixtures/mixin.undefined.sass b/node_modules/jade/support/sass/spec/fixtures/mixin.undefined.sass new file mode 100644 index 0000000..4026d54 --- /dev/null +++ b/node_modules/jade/support/sass/spec/fixtures/mixin.undefined.sass @@ -0,0 +1,2 @@ +body + +large \ No newline at end of file diff --git a/node_modules/jade/support/sass/spec/fixtures/properties.css b/node_modules/jade/support/sass/spec/fixtures/properties.css new file mode 100644 index 0000000..ccc4b21 --- /dev/null +++ b/node_modules/jade/support/sass/spec/fixtures/properties.css @@ -0,0 +1,3 @@ +body { + font-size: 13px; + color: #fff;} diff --git a/node_modules/jade/support/sass/spec/fixtures/properties.expand.css b/node_modules/jade/support/sass/spec/fixtures/properties.expand.css new file mode 100644 index 0000000..b95a347 --- /dev/null +++ b/node_modules/jade/support/sass/spec/fixtures/properties.expand.css @@ -0,0 +1,3 @@ +div { + -webkit-border-radius: 5px; + -moz-border-radius: 5px;} diff --git a/node_modules/jade/support/sass/spec/fixtures/properties.expand.sass b/node_modules/jade/support/sass/spec/fixtures/properties.expand.sass new file mode 100644 index 0000000..9ae954c --- /dev/null +++ b/node_modules/jade/support/sass/spec/fixtures/properties.expand.sass @@ -0,0 +1,2 @@ +div + =border-radius 5px \ No newline at end of file diff --git a/node_modules/jade/support/sass/spec/fixtures/properties.invalid.sass b/node_modules/jade/support/sass/spec/fixtures/properties.invalid.sass new file mode 100644 index 0000000..b724ff6 --- /dev/null +++ b/node_modules/jade/support/sass/spec/fixtures/properties.invalid.sass @@ -0,0 +1,2 @@ +:color #fff +body \ No newline at end of file diff --git a/node_modules/jade/support/sass/spec/fixtures/properties.nested.css b/node_modules/jade/support/sass/spec/fixtures/properties.nested.css new file mode 100644 index 0000000..3542a2a --- /dev/null +++ b/node_modules/jade/support/sass/spec/fixtures/properties.nested.css @@ -0,0 +1,13 @@ +body { + padding: 0;} +body ul { + margin: 0;} +body ul li { + list-style: none;} +body ul li a { + color: #fff;} +body form label { + display: none;} + +a { + color: #cc0000;} diff --git a/node_modules/jade/support/sass/spec/fixtures/properties.nested.invalid.sass b/node_modules/jade/support/sass/spec/fixtures/properties.nested.invalid.sass new file mode 100644 index 0000000..614aee4 --- /dev/null +++ b/node_modules/jade/support/sass/spec/fixtures/properties.nested.invalid.sass @@ -0,0 +1,5 @@ +body + ul + :margin 0 + li + :padding 0 \ No newline at end of file diff --git a/node_modules/jade/support/sass/spec/fixtures/properties.nested.sass b/node_modules/jade/support/sass/spec/fixtures/properties.nested.sass new file mode 100644 index 0000000..aa1a930 --- /dev/null +++ b/node_modules/jade/support/sass/spec/fixtures/properties.nested.sass @@ -0,0 +1,13 @@ +body + ul + :margin 0 + li + a + :color #fff + :list-style none + :padding 0 + form + label + :display none +a + :color #cc0000 \ No newline at end of file diff --git a/node_modules/jade/support/sass/spec/fixtures/properties.sass b/node_modules/jade/support/sass/spec/fixtures/properties.sass new file mode 100644 index 0000000..603653a --- /dev/null +++ b/node_modules/jade/support/sass/spec/fixtures/properties.sass @@ -0,0 +1,3 @@ +body + :font-size 13px + :color #fff \ No newline at end of file diff --git a/node_modules/jade/support/sass/spec/fixtures/selectors.css b/node_modules/jade/support/sass/spec/fixtures/selectors.css new file mode 100644 index 0000000..62532b4 --- /dev/null +++ b/node_modules/jade/support/sass/spec/fixtures/selectors.css @@ -0,0 +1,6 @@ +body input.field#email ~ label { + display: none;} +body form:nth-child(1) legend { + font-size: 15px;} +body ul li:first-child a { + display: none;} diff --git a/node_modules/jade/support/sass/spec/fixtures/selectors.sass b/node_modules/jade/support/sass/spec/fixtures/selectors.sass new file mode 100644 index 0000000..3aa6ca6 --- /dev/null +++ b/node_modules/jade/support/sass/spec/fixtures/selectors.sass @@ -0,0 +1,10 @@ +body + input.field#email ~ label + :display none + form:nth-child(1) + legend + :font-size 15px + ul + li:first-child + a + :display none diff --git a/node_modules/jade/support/sass/spec/fixtures/variables.alternate.css b/node_modules/jade/support/sass/spec/fixtures/variables.alternate.css new file mode 100644 index 0000000..dd2d6bc --- /dev/null +++ b/node_modules/jade/support/sass/spec/fixtures/variables.alternate.css @@ -0,0 +1,2 @@ +body { + background: #ff0000 url('foo.png');} diff --git a/node_modules/jade/support/sass/spec/fixtures/variables.alternate.sass b/node_modules/jade/support/sass/spec/fixtures/variables.alternate.sass new file mode 100644 index 0000000..b022082 --- /dev/null +++ b/node_modules/jade/support/sass/spec/fixtures/variables.alternate.sass @@ -0,0 +1,4 @@ +color: #ff0000 +image: url('foo.png') +body + :background !color !image \ No newline at end of file diff --git a/node_modules/jade/support/sass/spec/fixtures/variables.css b/node_modules/jade/support/sass/spec/fixtures/variables.css new file mode 100644 index 0000000..904bdbc --- /dev/null +++ b/node_modules/jade/support/sass/spec/fixtures/variables.css @@ -0,0 +1,2 @@ +body { + color: #ff0000;} diff --git a/node_modules/jade/support/sass/spec/fixtures/variables.regular.css b/node_modules/jade/support/sass/spec/fixtures/variables.regular.css new file mode 100644 index 0000000..904bdbc --- /dev/null +++ b/node_modules/jade/support/sass/spec/fixtures/variables.regular.css @@ -0,0 +1,2 @@ +body { + color: #ff0000;} diff --git a/node_modules/jade/support/sass/spec/fixtures/variables.regular.sass b/node_modules/jade/support/sass/spec/fixtures/variables.regular.sass new file mode 100644 index 0000000..82ae128 --- /dev/null +++ b/node_modules/jade/support/sass/spec/fixtures/variables.regular.sass @@ -0,0 +1,3 @@ +!red = #ff0000 +body + :color !red \ No newline at end of file diff --git a/node_modules/jade/support/sass/spec/fixtures/variables.sass b/node_modules/jade/support/sass/spec/fixtures/variables.sass new file mode 100644 index 0000000..c9f3388 --- /dev/null +++ b/node_modules/jade/support/sass/spec/fixtures/variables.sass @@ -0,0 +1,5 @@ + +red: #ff0000 + +body + :color !red diff --git a/node_modules/jade/support/sass/spec/lib/images/bg.png b/node_modules/jade/support/sass/spec/lib/images/bg.png new file mode 100644 index 0000000000000000000000000000000000000000..947804ff6acaaf93986a0a11d205df3113656816 GIT binary patch literal 154 zcmeAS@N?(olHy`uVBq!ia0vp^j0_CS3LH#8R&M_M3qVS;#5JNMI6tkVJh3R1!7(L2 zDOJHUH!(dmC^a#qvhZZ84N#Gdr;B4q#jT`Y|Nq+yGczC7kaMcgIDRvs>~})ZZHL{d z3*N|ke!F!0+{6dRCuY6RkTi>G?|T$zbHu=*fssL9)snBgXWIv$ISihzelF{r5}E+; Cx;4N6 literal 0 HcmV?d00001 diff --git a/node_modules/jade/support/sass/spec/lib/images/hr.png b/node_modules/jade/support/sass/spec/lib/images/hr.png new file mode 100644 index 0000000000000000000000000000000000000000..4a94d12fd8405c32b4c20abe777c1a9a7e6a30cb GIT binary patch literal 321 zcmV-H0lxl;P)A5E2-vx}KFiT96$Z17UamL`af0P}@7%Vq>XUIGjN-4D7? ThAmXZ00000NkvXXu0mjfvYCee literal 0 HcmV?d00001 diff --git a/node_modules/jade/support/sass/spec/lib/images/loading.gif b/node_modules/jade/support/sass/spec/lib/images/loading.gif new file mode 100644 index 0000000000000000000000000000000000000000..c69e937232b24ea30f01c68bbd2ebc798dcecfcb GIT binary patch literal 2608 zcmdVcdr(tX9tZGC9yiG~=H_*Q-0%n(kWqP*D#hw{AQu8;1%gl-Hrf&{2?48KX;hHy z3Ze*zEz4t3XdUFyLbNPUYlA`|B}P=N1fqtL1*}S;87#|-W9v<#G;ul(e%d3)N(^9c$d2Dz{7}?ErjNd;{EMKkCsk21~b9Gvg zDo<7L=3Z5HNbVlZUcm1eg#o#CZCJU`3IYHwM->zCd?uYrF3vKFeM}v?f+%s?E>ly|3W25ry9#NNbTx-}0ON58dTrs^ix{_1O0Wh~SVSBlH)Ajn zPn^Gbjz}PCtN@#keR&hK&Dhl-b$kZ8^S)x#dh0{7X=X%CCJk7P1PSO>T&S8I4{#Lg zb5#)o=;!ZP*1nM{cI4@(x7o27*SA()NHmrn67aN@Pmi~(i_SnrjYnwh36aG%!@i0d zqbvfa44f|?OG4ntP|nbjhEl1)Yp6ZN@yjy zy4==QmLy%t;ps3R?~f2KfTTI|2?q8dFd6^z5GF+Xa&Y)sjG)hxit80pPcOP zJ z*LW{SyGHD%hUotV+W%I}fBLAIx!8|7#}$;clKQ+{&FjDqGQ2ZNx(lYM3*%~}ILnao zM`aui55~ZFJlu^!5rdA9Q_7H68H_;##u{x(Yn-vSfIRCb^Nqsg zGRS!Egm>h+o<}LeV4&CLReo9FrDjDvs}8?JwC)#Qs|ie=r?~xUh)&*d`Fx>FG}%X# zNdtDHBKhLPC0wpooFDAQKL%*6T|ULH$=wX!NhcasgD3d;-d$I6yRK3yN+E~C1335_iLOt+*9uvSZ`>*KA}vm}08wRq=>5l|t*Na&jR z-C1&C`nkEk#sB|@yyt-#fXngP04My zm7u$Q%EJbHp`>~`5W&L{W!6`y&}LMS;jfUpgO~7TLVMRZ9IC)IZp0A${`yp0{&wco z#1nx@XMkhqeK%7?RE7JdLr1^nwFfaJ0Q&Lv?WNJ%9}VSJsNY2+UYs2%EU0J~ayFXv zi*?7KCXQHkD)O6!0Q%4N+HTODHxJ{kQSuQX$l-rSwkwh(zMkdfzxyGwl@yHC)C4p< z&n2%8#M?)Q@mgHL1ot8`SFdSEj9ye|jHy+U8#@HoUExG=@AVkRAe_qYm4EpzK6L*& zh`)26?V#f4#_h^P9G^%>h2-H3)$QP zQovu6J9qDvsxqweDdNNa!Lb?L4_UF{tLX_nN7r0U_vF14YKcGR-*Gl} zx3oG)bzf|65dBxD-;2ZCp??K;+TuQ9onnK?==5hzbkb^r_g>z4#D8mcv8(+XdoszA zCx-qhdgxMNMotj}SiL_6V(tLcsK7(M(r(%u<}QrVfOvyK6_;~NOTlPGfX@M7S5YQF z&*$(ylJMHJt^_aQeu{C6NaTE$G3HNN@_SnN8YcaKn%`)F@~L1x+ah7-gEJPpc6w%3 zyX}r+Qk$4RHZzfH){e~F*qJ{d*L8a6n4;U?+{de0-t)mal#TVxe)3F}^UBh+zd T)6_**#cgp_+?JL9(ew3BlNF>u literal 0 HcmV?d00001 diff --git a/node_modules/jade/support/sass/spec/lib/images/sprites.bg.png b/node_modules/jade/support/sass/spec/lib/images/sprites.bg.png new file mode 100644 index 0000000000000000000000000000000000000000..dc8790f338c4fce6611e0c2d2f811882a4136b32 GIT binary patch literal 4876 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 literal 0 HcmV?d00001 diff --git a/node_modules/jade/support/sass/spec/lib/images/sprites.png b/node_modules/jade/support/sass/spec/lib/images/sprites.png new file mode 100644 index 0000000000000000000000000000000000000000..010b98eeef699c0d0f4d0136d7d2d352b2b51d4c GIT binary patch literal 3629 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 NJsl%$+{J5={{f-$rB(m{ literal 0 HcmV?d00001 diff --git a/node_modules/jade/support/sass/spec/lib/images/vr.png b/node_modules/jade/support/sass/spec/lib/images/vr.png new file mode 100644 index 0000000000000000000000000000000000000000..b2e76175d3e8a4b5092757c9cbbfb81802804bc6 GIT binary patch literal 145 zcmeAS@N?(olHy`uVBq!ia0y~yVEzDPGjgy2$;wJseIO-S;u=vBoS#-wo>-L1;Fyx1 zl&avFo0y&&l$w}QS$Hzl2B^r`)5S5Q;?|q%hN29LJggh+4ZdAv`VrpRF7+Vg&V(H& syf&pj3kwA*Y^eWvZr(dP{{}_|Ay#%3&0R090!0}-UHx3vIVCg!0D1l{cmMzZ literal 0 HcmV?d00001 diff --git a/node_modules/jade/support/sass/spec/lib/jspec.css b/node_modules/jade/support/sass/spec/lib/jspec.css new file mode 100644 index 0000000..629d41c --- /dev/null +++ b/node_modules/jade/support/sass/spec/lib/jspec.css @@ -0,0 +1,149 @@ +body.jspec { + margin: 45px 0; + font: 12px "Helvetica Neue Light", "Lucida Grande", "Calibri", "Arial", sans-serif; + background: #efefef url(images/bg.png) top left repeat-x; + text-align: center; +} +#jspec { + margin: 0 auto; + padding-top: 30px; + width: 1008px; + background: url(images/vr.png) top left repeat-y; + text-align: left; +} +#jspec-top { + position: relative; + margin: 0 auto; + width: 1008px; + height: 40px; + background: url(images/sprites.bg.png) top left no-repeat; +} +#jspec-bottom { + margin: 0 auto; + width: 1008px; + height: 15px; + background: url(images/sprites.bg.png) bottom left no-repeat; +} +#jspec .loading { + margin-top: -45px; + width: 1008px; + height: 80px; + background: url(images/loading.gif) 50% 50% no-repeat; +} +#jspec-title { + position: absolute; + top: 15px; + left: 20px; + width: 160px; + font-size: 22px; + font-weight: normal; + background: url(images/sprites.png) 0 -126px no-repeat; + text-align: center; +} +#jspec-title em { + font-size: 10px; + font-style: normal; + color: #BCC8D1; +} +#jspec-report * { + margin: 0; + padding: 0; + background: none; + border: none; +} +#jspec-report { + padding: 15px 40px; + font: 11px "Helvetica Neue Light", "Lucida Grande", "Calibri", "Arial", sans-serif; + color: #7B8D9B; +} +#jspec-report.has-failures { + padding-bottom: 30px; +} +#jspec-report .hidden { + display: none; +} +#jspec-report .heading { + margin-bottom: 15px; +} +#jspec-report .heading span { + padding-right: 10px; +} +#jspec-report .heading .passes em { + color: #0ea0eb; +} +#jspec-report .heading .failures em { + color: #FA1616; +} +#jspec-report table { + font-size: 11px; + border-collapse: collapse; +} +#jspec-report td { + padding: 8px; + text-indent: 30px; + color: #7B8D9B; +} +#jspec-report tr.body { + display: none; +} +#jspec-report tr.body pre { + margin: 0; + padding: 0 0 5px 25px; +} +#jspec-report tr.even:hover + tr.body, +#jspec-report tr.odd:hover + tr.body { + display: block; +} +#jspec-report tr td:first-child em { + display: block; + clear: both; + font-style: normal; + font-weight: normal; + color: #7B8D9B; +} +#jspec-report tr.even:hover, +#jspec-report tr.odd:hover { + text-shadow: 1px 1px 1px #fff; + background: #F2F5F7; +} +#jspec-report td + td { + padding-right: 0; + width: 15px; +} +#jspec-report td.pass { + background: url(images/sprites.png) 3px -7px no-repeat; +} +#jspec-report td.fail { + background: url(images/sprites.png) 3px -158px no-repeat; + font-weight: bold; + color: #FC0D0D; +} +#jspec-report td.requires-implementation { + background: url(images/sprites.png) 3px -333px no-repeat; +} +#jspec-report tr.description td { + margin-top: 25px; + padding-top: 25px; + font-size: 12px; + font-weight: bold; + text-indent: 0; + color: #1a1a1a; +} +#jspec-report tr.description:first-child td { + border-top: none; +} +#jspec-report .assertion { + display: block; + float: left; + margin: 0 0 0 1px; + padding: 0; + width: 1px; + height: 5px; + background: #7B8D9B; +} +#jspec-report .assertion.failed { + background: red; +} +.jspec-sandbox { + display: none; +} \ No newline at end of file diff --git a/node_modules/jade/support/sass/spec/lib/jspec.growl.js b/node_modules/jade/support/sass/spec/lib/jspec.growl.js new file mode 100644 index 0000000..a150257 --- /dev/null +++ b/node_modules/jade/support/sass/spec/lib/jspec.growl.js @@ -0,0 +1,115 @@ + +// JSpec - Growl - Copyright TJ Holowaychuk (MIT Licensed) + +;(function(){ + + Growl = { + + // --- Version + + version: '1.0.0', + + /** + * Execute the given _cmd_, returning an array of lines from stdout. + * + * Examples: + * + * Growl.exec('growlnotify', '-m', msg) + * + * @param {string ...} cmd + * @return {array} + * @api public + */ + + exec: function(cmd) { + var lines = [], line + with (JavaImporter(java.lang, java.io)) { + var proccess = Runtime.getRuntime().exec(Array.prototype.slice.call(arguments)) + var stream = new DataInputStream(proccess.getInputStream()) + while (line = stream.readLine()) + lines.push(line + '') + stream.close() + } + return lines + }, + + /** + * Return the extension of the given _path_ or null. + * + * @param {string} path + * @return {string} + * @api private + */ + + extname: function(path) { + return path.lastIndexOf('.') != -1 ? + path.slice(path.lastIndexOf('.') + 1, path.length) : + null + }, + + /** + * Version of the 'growlnotify' binary. + * + * @return {string} + * @api private + */ + + binVersion: function() { + try { return this.exec('growlnotify', '-v')[0].split(' ')[1] } catch (e) {} + }, + + /** + * Send growl notification _msg_ with _options_. + * + * Options: + * + * - title Notification title + * - sticky Make the notification stick (defaults to false) + * - name Application name (defaults to growlnotify) + * - image + * - path to an icon sets --iconpath + * - path to an image sets --image + * - capitalized word sets --appIcon + * - filename uses extname as --icon + * - otherwise treated as --icon + * + * Examples: + * + * Growl.notify('New email') + * Growl.notify('5 new emails', { title: 'Thunderbird' }) + * + * @param {string} msg + * @param {options} hash + * @api public + */ + + notify: function(msg, options) { + options = options || {} + var args = ['growlnotify', '-m', msg] + if (!this.binVersion()) throw new Error('growlnotify executable is required') + if (image = options.image) { + var flag, ext = this.extname(image) + flag = flag || ext == 'icns' && 'iconpath' + flag = flag || /^[A-Z]/.test(image) && 'appIcon' + flag = flag || /^png|gif|jpe?g$/.test(ext) && 'image' + flag = flag || ext && (image = ext) && 'icon' + flag = flag || 'icon' + args.push('--' + flag, image) + } + if (options.sticky) args.push('--sticky') + if (options.name) args.push('--name', options.name) + if (options.title) args.push(options.title) + this.exec.apply(this, args) + } + } + + JSpec.include({ + name: 'Growl', + reporting: function(options){ + var stats = JSpec.stats + if (stats.failures) Growl.notify('failed ' + stats.failures + ' assertions', { title: 'JSpec'}) + else Growl.notify('passed ' + stats.passes + ' assertions', { title: 'JSpec' }) + } + }) + +})() \ No newline at end of file diff --git a/node_modules/jade/support/sass/spec/lib/jspec.jquery.js b/node_modules/jade/support/sass/spec/lib/jspec.jquery.js new file mode 100644 index 0000000..46422ec --- /dev/null +++ b/node_modules/jade/support/sass/spec/lib/jspec.jquery.js @@ -0,0 +1,79 @@ + +// JSpec - jQuery - Copyright TJ Holowaychuk (MIT Licensed) + +JSpec +.requires('jQuery', 'when using jspec.jquery.js') +.include({ + name: 'jQuery', + + // --- Initialize + + init : function() { + jQuery.ajaxSetup({ async: false }) + }, + + // --- Utilities + + utilities : { + element: jQuery, + elements: jQuery, + sandbox : function() { + return jQuery('
    ') + } + }, + + // --- Matchers + + matchers : { + have_tag : "jQuery(expected, actual).length === 1", + have_one : "alias have_tag", + have_tags : "jQuery(expected, actual).length > 1", + have_many : "alias have_tags", + have_any : "alias have_tags", + have_child : "jQuery(actual).children(expected).length === 1", + have_children : "jQuery(actual).children(expected).length > 1", + have_text : "jQuery(actual).text() === expected", + have_value : "jQuery(actual).val() === expected", + be_enabled : "!jQuery(actual).attr('disabled')", + have_class : "jQuery(actual).hasClass(expected)", + be_animated : "jQuery(actual).queue().length > 0", + + be_visible : function(actual) { + return jQuery(actual).css('display') != 'none' && + jQuery(actual).css('visibility') != 'hidden' && + jQuery(actual).attr('type') != 'hidden' + }, + + be_hidden : function(actual) { + return !JSpec.does(actual, 'be_visible') + }, + + have_classes : function(actual) { + return !JSpec.any(JSpec.toArray(arguments, 1), function(arg){ + return !JSpec.does(actual, 'have_class', arg) + }) + }, + + have_attr : function(actual, attr, value) { + return value ? jQuery(actual).attr(attr) == value: + jQuery(actual).attr(attr) + }, + + have_event_handlers : function(actual, expected) { + return jQuery(actual).data('events') ? + jQuery(actual).data('events').hasOwnProperty(expected) : + false + }, + + 'be disabled selected checked' : function(attr) { + return 'jQuery(actual).attr("' + attr + '")' + }, + + 'have type id title alt href src sel rev name target' : function(attr) { + return function(actual, value) { + return JSpec.does(actual, 'have_attr', attr, value) + } + } + } +}) + diff --git a/node_modules/jade/support/sass/spec/lib/jspec.js b/node_modules/jade/support/sass/spec/lib/jspec.js new file mode 100644 index 0000000..131c745 --- /dev/null +++ b/node_modules/jade/support/sass/spec/lib/jspec.js @@ -0,0 +1,1893 @@ + +// JSpec - Core - Copyright TJ Holowaychuk (MIT Licensed) + +;(function(){ + + JSpec = { + version : '4.3.2', + assert : true, + cache : {}, + suites : [], + modules : [], + allSuites : [], + sharedBehaviors: [], + matchers : {}, + stubbed : [], + options : {}, + request : 'XMLHttpRequest' in this ? XMLHttpRequest : null, + stats : { specs: 0, assertions: 0, failures: 0, passes: 0, specsFinished: 0, suitesFinished: 0 }, + + /** + * Default context in which bodies are evaluated. + * + * Replace context simply by setting JSpec.context + * to your own like below: + * + * JSpec.context = { foo : 'bar' } + * + * Contexts can be changed within any body, this can be useful + * in order to provide specific helper methods to specific suites. + * + * To reset (usually in after hook) simply set to null like below: + * + * JSpec.context = null + * + */ + + defaultContext : { + + /** + * Return an object used for proxy assertions. + * This object is used to indicate that an object + * should be an instance of _object_, not the constructor + * itself. + * + * @param {function} constructor + * @return {hash} + * @api public + */ + + an_instance_of : function(constructor) { + return { an_instance_of : constructor } + }, + + /** + * Load fixture at _path_. + * + * Fixtures are resolved as: + * + * - + * - .html + * + * @param {string} path + * @return {string} + * @api public + */ + + fixture : function(path) { + if (JSpec.cache[path]) return JSpec.cache[path] + return JSpec.cache[path] = + JSpec.tryLoading(JSpec.options.fixturePath + '/' + path) || + JSpec.tryLoading(JSpec.options.fixturePath + '/' + path + '.html') + }, + + /** + * Load json fixture at _path_. + * + * JSON fixtures are resolved as: + * + * - + * - .json + * + * @param {string} path + * @return {object} + * @api public + */ + + json_fixture: function(path) { + if (!JSpec.cache['json:' + path]) + JSpec.cache['json:' + path] = + JSpec.tryLoading(JSpec.options.fixturePath + '/' + path) || + JSpec.tryLoading(JSpec.options.fixturePath + '/' + path + '.json') + try { + return eval('(' + JSpec.cache['json:' + path] + ')') + } catch (e) { + throw 'json_fixture("' + path + '"): ' + e + } + } + }, + + // --- Objects + + reporters : { + + /** + * Report to server. + * + * Options: + * - uri specific uri to report to. + * - verbose weither or not to output messages + * - failuresOnly output failure messages only + * + * @api public + */ + + Server : function(results, options) { + var uri = options.uri || 'http://' + window.location.host + '/results' + JSpec.post(uri, { + stats: JSpec.stats, + options: options, + results: map(results.allSuites, function(suite) { + if (suite.isExecutable()) + return { + description: suite.description, + specs: map(suite.specs, function(spec) { + return { + description: spec.description, + message: !spec.passed() ? spec.failure().message : null, + status: spec.requiresImplementation() ? 'pending' : + spec.passed() ? 'pass' : + 'fail', + assertions: map(spec.assertions, function(assertion){ + return { + passed: assertion.passed + } + }) + } + }) + } + }) + }) + if ('close' in main) main.close() + }, + + /** + * Default reporter, outputting to the DOM. + * + * Options: + * - reportToId id of element to output reports to, defaults to 'jspec' + * - failuresOnly displays only suites with failing specs + * + * @api public + */ + + DOM : function(results, options) { + var id = option('reportToId') || 'jspec', + report = document.getElementById(id), + failuresOnly = option('failuresOnly'), + classes = results.stats.failures ? 'has-failures' : '' + if (!report) throw 'JSpec requires the element #' + id + ' to output its reports' + + function bodyContents(body) { + return JSpec. + escape(JSpec.contentsOf(body)). + replace(/^ */gm, function(a){ return (new Array(Math.round(a.length / 3))).join(' ') }). + replace(/\r\n|\r|\n/gm, '
    ') + } + + report.innerHTML = '
    \ + Passes: ' + results.stats.passes + ' \ + Failures: ' + results.stats.failures + ' \ + Duration: ' + results.duration + ' ms \ +
    ' + map(results.allSuites, function(suite) { + var displaySuite = failuresOnly ? suite.ran && !suite.passed() : suite.ran + if (displaySuite && suite.isExecutable()) + return '' + + map(suite.specs, function(i, spec) { + return '' + + (spec.requiresImplementation() ? + '' : + (spec.passed() && !failuresOnly) ? + '' : + !spec.passed() ? + '' : + '') + + '' + }).join('') + '' + }).join('') + '
    ' + escape(suite.description) + '
    ' + escape(spec.description) + '' + escape(spec.description)+ '' + spec.assertionsGraph() + '' + escape(spec.description) + + map(spec.failures(), function(a){ return '' + escape(a.message) + '' }).join('') + + '' + spec.assertionsGraph() + '
    ' + bodyContents(spec.body) + '
    ' + }, + + /** + * Terminal reporter. + * + * @api public + */ + + Terminal : function(results, options) { + var failuresOnly = option('failuresOnly') + print(color("\n Passes: ", 'bold') + color(results.stats.passes, 'green') + + color(" Failures: ", 'bold') + color(results.stats.failures, 'red') + + color(" Duration: ", 'bold') + color(results.duration, 'green') + " ms \n") + + function indent(string) { + return string.replace(/^(.)/gm, ' $1') + } + + each(results.allSuites, function(suite) { + var displaySuite = failuresOnly ? suite.ran && !suite.passed() : suite.ran + if (displaySuite && suite.isExecutable()) { + print(color(' ' + suite.description, 'bold')) + each(suite.specs, function(spec){ + var assertionsGraph = inject(spec.assertions, '', function(graph, assertion){ + return graph + color('.', assertion.passed ? 'green' : 'red') + }) + if (spec.requiresImplementation()) + print(color(' ' + spec.description, 'blue') + assertionsGraph) + else if (spec.passed() && !failuresOnly) + print(color(' ' + spec.description, 'green') + assertionsGraph) + else if (!spec.passed()) + print(color(' ' + spec.description, 'red') + assertionsGraph + + "\n" + indent(map(spec.failures(), function(a){ return a.message }).join("\n")) + "\n") + }) + print("") + } + }) + + quit(results.stats.failures) + } + }, + + Assertion : function(matcher, actual, expected, negate) { + extend(this, { + message: '', + passed: false, + actual: actual, + negate: negate, + matcher: matcher, + expected: expected, + + // Report assertion results + + report : function() { + if (JSpec.assert) + this.passed ? JSpec.stats.passes++ : JSpec.stats.failures++ + return this + }, + + // Run the assertion + + run : function() { + // TODO: remove unshifting + expected.unshift(actual) + this.result = matcher.match.apply(this, expected) + this.passed = negate ? !this.result : this.result + if (!this.passed) this.message = matcher.message.call(this, actual, expected, negate, matcher.name) + return this + } + }) + }, + + ProxyAssertion : function(object, method, times, negate) { + var self = this, + old = object[method] + + // Proxy + + object[method] = function(){ + var args = toArray(arguments), + result = old.apply(object, args) + self.calls.push({ args : args, result : result }) + return result + } + + // Times + + this.times = { + once : 1, + twice : 2 + }[times] || times || 1 + + extend(this, { + calls: [], + message: '', + defer: true, + passed: false, + negate: negate, + object: object, + method: method, + + // Proxy return value + + and_return : function(result) { + this.expectedResult = result + return this + }, + + // Proxy arguments passed + + with_args : function() { + this.expectedArgs = toArray(arguments) + return this + }, + + // Check if any calls have failing results + + anyResultsFail : function() { + return any(this.calls, function(call){ + return self.expectedResult.an_instance_of ? + call.result.constructor != self.expectedResult.an_instance_of: + !equal(self.expectedResult, call.result) + }) + }, + + // Check if any calls have passing results + + anyResultsPass : function() { + return any(this.calls, function(call){ + return self.expectedResult.an_instance_of ? + call.result.constructor == self.expectedResult.an_instance_of: + equal(self.expectedResult, call.result) + }) + }, + + // Return the passing result + + passingResult : function() { + return this.anyResultsPass().result + }, + + // Return the failing result + + failingResult : function() { + return this.anyResultsFail().result + }, + + // Check if any arguments fail + + anyArgsFail : function() { + return any(this.calls, function(call){ + return any(self.expectedArgs, function(i, arg){ + if (arg == null) return call.args[i] == null + return arg.an_instance_of ? + call.args[i].constructor != arg.an_instance_of: + !equal(arg, call.args[i]) + + }) + }) + }, + + // Check if any arguments pass + + anyArgsPass : function() { + return any(this.calls, function(call){ + return any(self.expectedArgs, function(i, arg){ + return arg.an_instance_of ? + call.args[i].constructor == arg.an_instance_of: + equal(arg, call.args[i]) + + }) + }) + }, + + // Return the passing args + + passingArgs : function() { + return this.anyArgsPass().args + }, + + // Return the failing args + + failingArgs : function() { + return this.anyArgsFail().args + }, + + // Report assertion results + + report : function() { + if (JSpec.assert) + this.passed ? ++JSpec.stats.passes : ++JSpec.stats.failures + return this + }, + + // Run the assertion + + run : function() { + var methodString = 'expected ' + object.toString() + '.' + method + '()' + (negate ? ' not' : '' ) + + function times(n) { + return n > 2 ? n + ' times' : { 1: 'once', 2: 'twice' }[n] + } + + if (this.expectedResult != null && (negate ? this.anyResultsPass() : this.anyResultsFail())) + this.message = methodString + ' to return ' + puts(this.expectedResult) + + ' but ' + (negate ? 'it did' : 'got ' + puts(this.failingResult())) + + if (this.expectedArgs && (negate ? !this.expectedResult && this.anyArgsPass() : this.anyArgsFail())) + this.message = methodString + ' to be called with ' + puts.apply(this, this.expectedArgs) + + ' but was' + (negate ? '' : ' called with ' + puts.apply(this, this.failingArgs())) + + if (negate ? !this.expectedResult && !this.expectedArgs && this.calls.length >= this.times : this.calls.length != this.times) + this.message = methodString + ' to be called ' + times(this.times) + + ', but ' + (this.calls.length == 0 ? ' was not called' : ' was called ' + times(this.calls.length)) + + if (!this.message.length) + this.passed = true + + return this + } + }) + }, + + /** + * Specification Suite block object. + * + * @param {string} description + * @param {function} body + * @api private + */ + + Suite : function(description, body, isShared) { + var self = this + extend(this, { + body: body, + description: description, + suites: [], + sharedBehaviors: [], + specs: [], + ran: false, + shared: isShared, + hooks: { 'before' : [], 'after' : [], + 'before_each' : [], 'after_each' : [], + 'before_nested' : [], 'after_nested' : []}, + + // Add a spec to the suite + + addSpec : function(description, body) { + var spec = new JSpec.Spec(description, body) + this.specs.push(spec) + JSpec.stats.specs++ // TODO: abstract + spec.suite = this + }, + + // Add a before hook to the suite + + addBefore : function(options, body) { + body.options = options || {} + this.befores.push(body) + }, + + // Add an after hook to the suite + + addAfter : function(options, body) { + body.options = options || {} + this.afters.unshift(body) + }, + + // Add a hook to the suite + + addHook : function(hook, body) { + this.hooks[hook].push(body) + }, + + // Add a nested suite + + addSuite : function(description, body, isShared) { + var suite = new JSpec.Suite(description, body, isShared) + JSpec.allSuites.push(suite) + suite.name = suite.description + suite.description = this.description + ' ' + suite.description + this.suites.push(suite) + suite.suite = this + }, + + // Invoke a hook in context to this suite + + hook : function(hook) { + if (hook != 'before' && hook != 'after') + if (this.suite) this.suite.hook(hook) + + each(this.hooks[hook], function(body) { + JSpec.evalBody(body, "Error in hook '" + hook + "', suite '" + self.description + "': ") + }) + }, + + // Check if nested suites are present + + hasSuites : function() { + return this.suites.length + }, + + // Check if this suite has specs + + hasSpecs : function() { + return this.specs.length + }, + + // Check if the entire suite passed + + passed : function() { + return !any(this.specs, function(spec){ + return !spec.passed() + }) + }, + + isShared : function(){ + return this.shared + }, + + isExecutable : function() { + return !this.isShared() && this.hasSpecs() + } + }) + }, + + /** + * Specification block object. + * + * @param {string} description + * @param {function} body + * @api private + */ + + Spec : function(description, body) { + extend(this, { + body: body, + description: description, + assertions: [], + + // Add passing assertion + + pass : function(message) { + this.assertions.push({ passed: true, message: message }) + if (JSpec.assert) ++JSpec.stats.passes + }, + + // Add failing assertion + + fail : function(message) { + this.assertions.push({ passed: false, message: message }) + if (JSpec.assert) ++JSpec.stats.failures + }, + + // Run deferred assertions + + runDeferredAssertions : function() { + each(this.assertions, function(assertion){ + if (assertion.defer) assertion.run().report(), hook('afterAssertion', assertion) + }) + }, + + // Find first failing assertion + + failure : function() { + return find(this.assertions, function(assertion){ + return !assertion.passed + }) + }, + + // Find all failing assertions + + failures : function() { + return select(this.assertions, function(assertion){ + return !assertion.passed + }) + }, + + // Weither or not the spec passed + + passed : function() { + return !this.failure() + }, + + // Weither or not the spec requires implementation (no assertions) + + requiresImplementation : function() { + return this.assertions.length == 0 + }, + + // Sprite based assertions graph + + assertionsGraph : function() { + return map(this.assertions, function(assertion){ + return '' + }).join('') + } + }) + }, + + Module : function(methods) { + extend(this, methods) + }, + + JSON : { + + /** + * Generic sequences. + */ + + meta : { + '\b' : '\\b', + '\t' : '\\t', + '\n' : '\\n', + '\f' : '\\f', + '\r' : '\\r', + '"' : '\\"', + '\\' : '\\\\' + }, + + /** + * Escapable sequences. + */ + + escapable : /[\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, + + /** + * JSON encode _object_. + * + * @param {mixed} object + * @return {string} + * @api private + */ + + encode : function(object) { + var self = this + if (object == undefined || object == null) return 'null' + if (object === true) return 'true' + if (object === false) return 'false' + switch (typeof object) { + case 'number': return object + case 'string': return this.escapable.test(object) ? + '"' + object.replace(this.escapable, function (a) { + return typeof self.meta[a] === 'string' ? self.meta[a] : + '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4) + }) + '"' : + '"' + object + '"' + case 'object': + if (object.constructor == Array) + return '[' + map(object, function(val){ + return self.encode(val) + }).join(', ') + ']' + else if (object) + return '{' + map(object, function(key, val){ + return self.encode(key) + ':' + self.encode(val) + }).join(', ') + '}' + } + return 'null' + } + }, + + // --- DSLs + + DSLs : { + snake : { + expect : function(actual){ + return JSpec.expect(actual) + }, + + describe : function(description, body) { + return JSpec.currentSuite.addSuite(description, body, false) + }, + + it : function(description, body) { + return JSpec.currentSuite.addSpec(description, body) + }, + + before : function(body) { + return JSpec.currentSuite.addHook('before', body) + }, + + after : function(body) { + return JSpec.currentSuite.addHook('after', body) + }, + + before_each : function(body) { + return JSpec.currentSuite.addHook('before_each', body) + }, + + after_each : function(body) { + return JSpec.currentSuite.addHook('after_each', body) + }, + + before_nested : function(body) { + return JSpec.currentSuite.addHook('before_nested', body) + }, + + after_nested : function(body){ + return JSpec.currentSuite.addhook('after_nested', body) + }, + + shared_behaviors_for : function(description, body){ + return JSpec.currentSuite.addSuite(description, body, true) + }, + + should_behave_like : function(description) { + return JSpec.shareBehaviorsOf(description) + } + } + }, + + // --- Methods + + /** + * Check if _value_ is 'stop'. For use as a + * utility callback function. + * + * @param {mixed} value + * @return {bool} + * @api public + */ + + haveStopped : function(value) { + return value === 'stop' + }, + + /** + * Include _object_ which may be a hash or Module instance. + * + * @param {hash, Module} object + * @return {JSpec} + * @api public + */ + + include : function(object) { + var module = object.constructor == JSpec.Module ? object : new JSpec.Module(object) + this.modules.push(module) + if ('init' in module) module.init() + if ('utilities' in module) extend(this.defaultContext, module.utilities) + if ('matchers' in module) this.addMatchers(module.matchers) + if ('reporters' in module) extend(this.reporters, module.reporters) + if ('DSLs' in module) + each(module.DSLs, function(name, methods){ + JSpec.DSLs[name] = JSpec.DSLs[name] || {} + extend(JSpec.DSLs[name], methods) + }) + return this + }, + + /** + * Add a module hook _name_, which is immediately + * called per module with the _args_ given. An array of + * hook return values is returned. + * + * @param {name} string + * @param {...} args + * @return {array} + * @api private + */ + + hook : function(name, args) { + args = toArray(arguments, 1) + return inject(JSpec.modules, [], function(results, module){ + if (typeof module[name] == 'function') + results.push(JSpec.evalHook(module, name, args)) + }) + }, + + /** + * Eval _module_ hook _name_ with _args_. Evaluates in context + * to the module itself, JSpec, and JSpec.context. + * + * @param {Module} module + * @param {string} name + * @param {array} args + * @return {mixed} + * @api private + */ + + evalHook : function(module, name, args) { + hook('evaluatingHookBody', module, name) + return module[name].apply(module, args) + }, + + /** + * Same as hook() however accepts only one _arg_ which is + * considered immutable. This function passes the arg + * to the first module, then passes the return value of the last + * module called, to the following module. + * + * @param {string} name + * @param {mixed} arg + * @return {mixed} + * @api private + */ + + hookImmutable : function(name, arg) { + return inject(JSpec.modules, arg, function(result, module){ + if (typeof module[name] == 'function') + return JSpec.evalHook(module, name, [result]) + }) + }, + + /** + * Find a shared example suite by its description or name. + * First searches parent tree of suites for shared behavior + * before falling back to global scoped nested behaviors. + * + * @param {string} description + * @return {Suite} + * @api private + */ + + findSharedBehavior : function(description) { + var behavior + return (behavior = JSpec.findLocalSharedBehavior(description)) + ? behavior + : JSpec.findGlobalSharedBehavior(description) + }, + + /** + * Find a shared example suite within the current suite's + * parent tree by its description or name. + * + * @param {string} description + * @return {Suite} + * @api private + */ + + findLocalSharedBehavior : function(description) { + var behavior, + currentSuite = JSpec.currentSuite.suite + while (currentSuite) + if (behavior = find(currentSuite.suites, JSpec.suiteDescriptionPredicate(description))) + return behavior + else + currentSuite = currentSuite.suite + }, + + /** + * Find a shared example suite within the global + * scope by its description or name. + * + * @param {string} description + * @return {Suite} + * @api private + */ + + findGlobalSharedBehavior : function(description) { + return find(JSpec.suites, JSpec.suiteDescriptionPredicate(description)) + }, + + /** + * Build a predicate that will match a suite based on name or description + * + * @param {string} description + * @return {function} + * @api private + */ + + suiteDescriptionPredicate : function(description) { + return function(suite){ + return suite.name === description || + suite.description === description + } + }, + + /** + * Share behaviors (specs) of the given suite with + * the current suite. + * + * @param {string} description + * @api public + */ + + shareBehaviorsOf : function(description) { + var suite = JSpec.findSharedBehavior(description) + if (suite) + JSpec.evalBody(suite.body) + else + throw new Error("failed to find shared behaviors named `" + description + "'") + }, + + + /** + * Convert arguments to an array. + * + * @param {object} arguments + * @param {int} offset + * @return {array} + * @api public + */ + + toArray : function(arguments, offset) { + return Array.prototype.slice.call(arguments, offset || 0) + }, + + /** + * Return ANSI-escaped colored string. + * + * @param {string} string + * @param {string} color + * @return {string} + * @api public + */ + + color : function(string, color) { + if (option('disableColors')) { + return string + } else { + return "\u001B[" + { + bold : 1, + black : 30, + red : 31, + green : 32, + yellow : 33, + blue : 34, + magenta : 35, + cyan : 36, + white : 37 + }[color] + 'm' + string + "\u001B[0m" + } + }, + + /** + * Default matcher message callback. + * + * @api private + */ + + defaultMatcherMessage : function(actual, expected, negate, name) { + return 'expected ' + puts(actual) + ' to ' + + (negate ? 'not ' : '') + + name.replace(/_/g, ' ') + + ' ' + (expected.length > 1 ? + puts.apply(this, expected.slice(1)) : + '') + }, + + /** + * Normalize a matcher message. + * + * When no messge callback is present the defaultMatcherMessage + * will be assigned, will suffice for most matchers. + * + * @param {hash} matcher + * @return {hash} + * @api public + */ + + normalizeMatcherMessage : function(matcher) { + if (typeof matcher.message != 'function') + matcher.message = this.defaultMatcherMessage + return matcher + }, + + /** + * Normalize a matcher body + * + * This process allows the following conversions until + * the matcher is in its final normalized hash state. + * + * - '==' becomes 'actual == expected' + * - 'actual == expected' becomes 'return actual == expected' + * - function(actual, expected) { return actual == expected } becomes + * { match : function(actual, expected) { return actual == expected }} + * + * @param {mixed} body + * @return {hash} + * @api public + */ + + normalizeMatcherBody : function(body) { + var captures + switch (body.constructor) { + case String: + if (captures = body.match(/^alias (\w+)/)) return JSpec.matchers[last(captures)] + if (body.length < 4) body = 'actual ' + body + ' expected' + return { match: function(actual, expected) { return eval(body) }} + + case Function: + return { match: body } + + default: + return body + } + }, + + /** + * Get option value. This method first checks if + * the option key has been set via the query string, + * otherwise returning the options hash value. + * + * @param {string} key + * @return {mixed} + * @api public + */ + + option : function(key) { + return (value = query(key)) !== null ? value : + JSpec.options[key] || null + }, + + /** + * Check if object _a_, is equal to object _b_. + * + * @param {object} a + * @param {object} b + * @return {bool} + * @api private + */ + + equal: function(a, b) { + if (typeof a != typeof b) return + if (a === b) return true + if (a instanceof RegExp) + return a.toString() === b.toString() + if (a instanceof Date) + return Number(a) === Number(b) + if (typeof a != 'object') return + if (a.length !== undefined) + if (a.length !== b.length) return + else + for (var i = 0, len = a.length; i < len; ++i) + if (!equal(a[i], b[i])) + return + for (var key in a) + if (!equal(a[key], b[key])) + return + return true + }, + + /** + * Return last element of an array. + * + * @param {array} array + * @return {object} + * @api public + */ + + last : function(array) { + return array[array.length - 1] + }, + + /** + * Convert object(s) to a print-friend string. + * + * @param {...} object + * @return {string} + * @api public + */ + + puts : function(object) { + if (arguments.length > 1) + return map(toArray(arguments), function(arg){ + return puts(arg) + }).join(', ') + if (object === undefined) return 'undefined' + if (object === null) return 'null' + if (object === true) return 'true' + if (object === false) return 'false' + if (object.an_instance_of) return 'an instance of ' + object.an_instance_of.name + if (object.jquery && object.selector.length > 0) return 'selector ' + puts(object.selector) + if (object.jquery) return object.get(0).outerHTML + if (object.nodeName) return object.outerHTML + switch (object.constructor) { + case Function: return object.name || object + case String: + return '"' + object + .replace(/"/g, '\\"') + .replace(/\n/g, '\\n') + .replace(/\t/g, '\\t') + + '"' + case Array: + return inject(object, '[', function(b, v){ + return b + ', ' + puts(v) + }).replace('[,', '[') + ' ]' + case Object: + object.__hit__ = true + return inject(object, '{', function(b, k, v) { + if (k == '__hit__') return b + return b + ', ' + k + ': ' + (v && v.__hit__ ? '' : puts(v)) + }).replace('{,', '{') + ' }' + default: + return object.toString() + } + }, + + /** + * Parse an XML String and return a 'document'. + * + * @param {string} text + * @return {document} + * @api public + */ + + parseXML : function(text) { + var xmlDoc + if (window.DOMParser) + xmlDoc = (new DOMParser()).parseFromString(text, "text/xml") + else { + xmlDoc = new ActiveXObject("Microsoft.XMLDOM") + xmlDoc.async = "false" + xmlDoc.loadXML(text) + } + return xmlDoc + }, + + /** + * Escape HTML. + * + * @param {string} html + * @return {string} + * @api public + */ + + escape : function(html) { + return html.toString() + .replace(/&/gmi, '&') + .replace(/"/gmi, '"') + .replace(/>/gmi, '>') + .replace(/ current) while (++current <= end) values.push(current) + else while (--current >= end) values.push(current) + return '[' + values + ']' + }, + + /** + * Report on the results. + * + * @api public + */ + + report : function() { + this.duration = Number(new Date) - this.start + hook('reporting', JSpec.options) + new (JSpec.options.reporter || JSpec.reporters.DOM)(JSpec, JSpec.options) + }, + + /** + * Run the spec suites. Options are merged + * with JSpec options when present. + * + * @param {hash} options + * @return {JSpec} + * @api public + */ + + run : function(options) { + if (any(hook('running'), haveStopped)) return this + if (options) extend(this.options, options) + this.start = Number(new Date) + each(this.suites, function(suite) { JSpec.runSuite(suite) }) + return this + }, + + /** + * Run a suite. + * + * @param {Suite} suite + * @api public + */ + + runSuite : function(suite) { + if (!suite.isShared()) + { + this.currentSuite = suite + this.evalBody(suite.body) + suite.ran = true + hook('beforeSuite', suite), suite.hook('before'), suite.hook('before_nested') + each(suite.specs, function(spec) { + hook('beforeSpec', spec) + suite.hook('before_each') + JSpec.runSpec(spec) + hook('afterSpec', spec) + suite.hook('after_each') + }) + if (suite.hasSuites()) { + each(suite.suites, function(suite) { + JSpec.runSuite(suite) + }) + } + hook('afterSuite', suite), suite.hook('after_nested'), suite.hook('after') + this.stats.suitesFinished++ + } + }, + + /** + * Report a failure for the current spec. + * + * @param {string} message + * @api public + */ + + fail : function(message) { + JSpec.currentSpec.fail(message) + }, + + /** + * Report a passing assertion for the current spec. + * + * @param {string} message + * @api public + */ + + pass : function(message) { + JSpec.currentSpec.pass(message) + }, + + /** + * Run a spec. + * + * @param {Spec} spec + * @api public + */ + + runSpec : function(spec) { + this.currentSpec = spec + try { this.evalBody(spec.body) } + catch (e) { fail(e) } + spec.runDeferredAssertions() + destub() + this.stats.specsFinished++ + this.stats.assertions += spec.assertions.length + }, + + /** + * Require a dependency, with optional message. + * + * @param {string} dependency + * @param {string} message (optional) + * @return {JSpec} + * @api public + */ + + requires : function(dependency, message) { + hook('requiring', dependency, message) + try { eval(dependency) } + catch (e) { throw 'JSpec depends on ' + dependency + ' ' + message } + return this + }, + + /** + * Query against the current query strings keys + * or the queryString specified. + * + * @param {string} key + * @param {string} queryString + * @return {string, null} + * @api private + */ + + query : function(key, queryString) { + var queryString = (queryString || (main.location ? main.location.search : null) || '').substring(1) + return inject(queryString.split('&'), null, function(value, pair){ + parts = pair.split('=') + return parts[0] == key ? parts[1].replace(/%20|\+/gmi, ' ') : value + }) + }, + + /** + * Ad-hoc POST request for JSpec server usage. + * + * @param {string} uri + * @param {string} data + * @api private + */ + + post : function(uri, data) { + if (any(hook('posting', uri, data), haveStopped)) return + var request = this.xhr() + request.open('POST', uri, false) + request.setRequestHeader('Content-Type', 'application/json') + request.send(JSpec.JSON.encode(data)) + }, + + /** + * Instantiate an XMLHttpRequest. + * + * Here we utilize IE's lame ActiveXObjects first which + * allow IE access serve files via the file: protocol, otherwise + * we then default to XMLHttpRequest. + * + * @return {XMLHttpRequest, ActiveXObject} + * @api private + */ + + xhr : function() { + return this.ieXhr() || new JSpec.request + }, + + /** + * Return Microsoft piece of crap ActiveXObject. + * + * @return {ActiveXObject} + * @api public + */ + + ieXhr : function() { + function object(str) { + try { return new ActiveXObject(str) } catch(e) {} + } + return object('Msxml2.XMLHTTP.6.0') || + object('Msxml2.XMLHTTP.3.0') || + object('Msxml2.XMLHTTP') || + object('Microsoft.XMLHTTP') + }, + + /** + * Check for HTTP request support. + * + * @return {bool} + * @api private + */ + + hasXhr : function() { + return JSpec.request || 'ActiveXObject' in main + }, + + /** + * Try loading _file_ returning the contents + * string or null. Chain to locate / read a file. + * + * @param {string} file + * @return {string} + * @api public + */ + + tryLoading : function(file) { + try { return JSpec.load(file) } catch (e) {} + }, + + /** + * Load a _file_'s contents. + * + * @param {string} file + * @param {function} callback + * @return {string} + * @api public + */ + + load : function(file, callback) { + if (any(hook('loading', file), haveStopped)) return + if ('readFile' in main) + return readFile(file) + else if (this.hasXhr()) { + var request = this.xhr() + request.open('GET', file, false) + request.send(null) + if (request.readyState == 4 && + (request.status == 0 || + request.status.toString().charAt(0) == 2)) + return request.responseText + } + else + throw new Error("failed to load `" + file + "'") + }, + + /** + * Load, pre-process, and evaluate a file. + * + * @param {string} file + * @param {JSpec} + * @api public + */ + + exec : function(file) { + if (any(hook('executing', file), haveStopped)) return this + eval('with (JSpec){' + this.preprocess(this.load(file)) + '}') + return this + } + } + + // --- Node.js support + + if (typeof GLOBAL === 'object' && typeof exports === 'object') { + var fs = require('fs') + quit = process.exit + print = require('sys').puts + readFile = function(file){ + return fs.readFileSync(file).toString('utf8') + } + } + + // --- Utility functions + + var main = this, + find = JSpec.any, + utils = 'haveStopped stub hookImmutable hook destub map any last pass fail range each option inject select \ + error escape extend puts query strip color does addMatchers callIterator toArray equal'.split(/\s+/) + while (utils.length) eval('var ' + utils[0] + ' = JSpec.' + utils.shift()) + if (!main.setTimeout) main.setTimeout = function(callback){ callback() } + + // --- Matchers + + addMatchers({ + equal : "===", + eql : "equal(actual, expected)", + be : "alias equal", + be_greater_than : ">", + be_less_than : "<", + be_at_least : ">=", + be_at_most : "<=", + be_a : "actual.constructor == expected", + be_an : "alias be_a", + be_an_instance_of : "actual instanceof expected", + be_null : "actual == null", + be_true : "actual == true", + be_false : "actual == false", + be_undefined : "typeof actual == 'undefined'", + be_type : "typeof actual == expected", + match : "typeof actual == 'string' ? actual.match(expected) : false", + respond_to : "typeof actual[expected] == 'function'", + have_length : "actual.length == expected", + be_within : "actual >= expected[0] && actual <= last(expected)", + have_length_within : "actual.length >= expected[0] && actual.length <= last(expected)", + + receive : { defer : true, match : function(actual, method, times) { + var proxy = new JSpec.ProxyAssertion(actual, method, times, this.negate) + JSpec.currentSpec.assertions.push(proxy) + return proxy + }}, + + be_empty : function(actual) { + if (actual.constructor == Object && actual.length == undefined) + for (var key in actual) + return false; + return !actual.length + }, + + include : function(actual) { + for (var state = true, i = 1; i < arguments.length; i++) { + var arg = arguments[i] + switch (actual.constructor) { + case String: + case Number: + case RegExp: + case Function: + state = actual.toString().indexOf(arg) !== -1 + break + + case Object: + state = arg in actual + break + + case Array: + state = any(actual, function(value){ return equal(value, arg) }) + break + } + if (!state) return false + } + return true + }, + + throw_error : { match : function(actual, expected, message) { + try { actual() } + catch (e) { + this.e = e + var assert = function(arg) { + switch (arg.constructor) { + case RegExp : return arg.test(e.message || e.toString()) + case String : return arg == (e.message || e.toString()) + case Function : return e instanceof arg || e.name == arg.name + } + } + return message ? assert(expected) && assert(message) : + expected ? assert(expected) : + true + } + }, message : function(actual, expected, negate) { + // TODO: refactor when actual is not in expected [0] + var message_for = function(i) { + if (expected[i] == undefined) return 'exception' + switch (expected[i].constructor) { + case RegExp : return 'exception matching ' + puts(expected[i]) + case String : return 'exception of ' + puts(expected[i]) + case Function : return expected[i].name || 'Error' + } + } + var exception = message_for(1) + (expected[2] ? ' and ' + message_for(2) : '') + return 'expected ' + exception + (negate ? ' not ' : '' ) + + ' to be thrown, but ' + (this.e ? 'got ' + puts(this.e) : 'nothing was') + }}, + + have : function(actual, length, property) { + return actual[property] == null ? false : actual[property].length == length + }, + + have_at_least : function(actual, length, property) { + return actual[property] == null ? (length === 0) : actual[property].length >= length + }, + + have_at_most :function(actual, length, property) { + return actual[property] == null || actual[property].length <= length + }, + + have_within : function(actual, range, property) { + var length = actual[property] == undefined ? 0 : actual[property].length + return length >= range.shift() && length <= range.pop() + }, + + have_prop : function(actual, property, value) { + var actualVal = actual[property], actualType = typeof actualVal + return (actualType == 'function' || actualType == 'undefined') ? false : + typeof value === 'undefined' || + does(actual[property],'eql',value) + }, + + have_property : function(actual, property, value) { + var actualVal = actual[property], actualType = typeof actualVal + return (actualType == 'function' || actualType == 'undefined') ? false : + typeof value === 'undefined' || + value === actualVal + } + }) + +})() diff --git a/node_modules/jade/support/sass/spec/lib/jspec.nodejs.js b/node_modules/jade/support/sass/spec/lib/jspec.nodejs.js new file mode 100644 index 0000000..6765273 --- /dev/null +++ b/node_modules/jade/support/sass/spec/lib/jspec.nodejs.js @@ -0,0 +1,18 @@ + +// JSpec - node - Copyright TJ Holowaychuk (MIT Licensed) + +JSpec +.include({ + name: 'node', + + // --- Matchers + + matchers : { + have_enumerable_property: 'actual.propertyIsEnumerable(expected)', + have_writable_property: 'Object.getOwnPropertyDescriptor(actual, expected).writable === true', + have_configurable_property: 'Object.getOwnPropertyDescriptor(actual, expected).configurable === true', + have_keys: 'does(Object.keys(actual), "eql", expected)', + have_prototype: 'Object.getPrototypeOf(actual) === expected' + } +}) + diff --git a/node_modules/jade/support/sass/spec/lib/jspec.shell.js b/node_modules/jade/support/sass/spec/lib/jspec.shell.js new file mode 100644 index 0000000..cb19c69 --- /dev/null +++ b/node_modules/jade/support/sass/spec/lib/jspec.shell.js @@ -0,0 +1,39 @@ + +// JSpec - Shell - Copyright TJ Holowaychuk (MIT Licensed) + +;(function(){ + + var _quit = quit + + Shell = { + + // --- Global + + main: this, + + // --- Commands + + commands: { + quit: ['Terminate the shell', function(){ _quit() }], + exit: ['Terminate the shell', function(){ _quit() }], + p: ['Inspect an object', function(o){ return o.toSource() }] + }, + + /** + * Start the interactive shell. + * + * @api public + */ + + start : function() { + for (var name in this.commands) + if (this.commands.hasOwnProperty(name)) + this.commands[name][1].length ? + this.main[name] = this.commands[name][1] : + this.main.__defineGetter__(name, this.commands[name][1]) + } + } + + Shell.start() + +})() \ No newline at end of file diff --git a/node_modules/jade/support/sass/spec/lib/jspec.timers.js b/node_modules/jade/support/sass/spec/lib/jspec.timers.js new file mode 100644 index 0000000..c88d10b --- /dev/null +++ b/node_modules/jade/support/sass/spec/lib/jspec.timers.js @@ -0,0 +1,90 @@ + +// JSpec - Mock Timers - Copyright TJ Holowaychuk (MIT Licensed) + +;(function(){ + + /** + * Version. + */ + + mockTimersVersion = '1.0.2' + + /** + * Localized timer stack. + */ + + var timers = [] + + /** + * Set mock timeout with _callback_ and timeout of _ms_. + * + * @param {function} callback + * @param {int} ms + * @return {int} + * @api public + */ + + setTimeout = function(callback, ms) { + var id + return id = setInterval(function(){ + callback() + clearInterval(id) + }, ms) + } + + /** + * Set mock interval with _callback_ and interval of _ms_. + * + * @param {function} callback + * @param {int} ms + * @return {int} + * @api public + */ + + setInterval = function(callback, ms) { + callback.step = ms, callback.current = callback.last = 0 + return timers[timers.length] = callback, timers.length + } + + /** + * Destroy timer with _id_. + * + * @param {int} id + * @return {bool} + * @api public + */ + + clearInterval = clearTimeout = function(id) { + return delete timers[--id] + } + + /** + * Reset timers. + * + * @return {array} + * @api public + */ + + resetTimers = function() { + return timers = [] + } + + /** + * Increment each timers internal clock by _ms_. + * + * @param {int} ms + * @api public + */ + + tick = function(ms) { + for (var i = 0, len = timers.length; i < len; ++i) + if (timers[i] && (timers[i].current += ms)) + if (timers[i].current - timers[i].last >= timers[i].step) { + var times = Math.floor((timers[i].current - timers[i].last) / timers[i].step) + var remainder = (timers[i].current - timers[i].last) % timers[i].step + timers[i].last = timers[i].current - remainder + while (times-- && timers[i]) timers[i]() + } + } + +})() \ No newline at end of file diff --git a/node_modules/jade/support/sass/spec/lib/jspec.xhr.js b/node_modules/jade/support/sass/spec/lib/jspec.xhr.js new file mode 100644 index 0000000..3b96310 --- /dev/null +++ b/node_modules/jade/support/sass/spec/lib/jspec.xhr.js @@ -0,0 +1,210 @@ + +// JSpec - XHR - Copyright TJ Holowaychuk (MIT Licensed) + +(function(){ + + var lastRequest + + // --- Original XMLHttpRequest + + var OriginalXMLHttpRequest = 'XMLHttpRequest' in this ? + XMLHttpRequest : + function(){} + var OriginalActiveXObject = 'ActiveXObject' in this ? + ActiveXObject : + undefined + + // --- MockXMLHttpRequest + + var MockXMLHttpRequest = function() { + this.requestHeaders = {} + } + + MockXMLHttpRequest.prototype = { + status: 0, + async: true, + readyState: 0, + responseXML: null, + responseText: '', + abort: function(){}, + onreadystatechange: function(){}, + + /** + * Return response headers hash. + */ + + getAllResponseHeaders : function(){ + return JSpec.inject(this.responseHeaders, '', function(buf, key, val){ + return buf + key + ': ' + val + '\r\n' + }) + }, + + /** + * Return case-insensitive value for header _name_. + */ + + getResponseHeader : function(name) { + return this.responseHeaders[name.toLowerCase()] + }, + + /** + * Set case-insensitive _value_ for header _name_. + */ + + setRequestHeader : function(name, value) { + this.requestHeaders[name.toLowerCase()] = value + }, + + /** + * Open mock request. + */ + + open : function(method, url, async, user, password) { + this.user = user + this.password = password + this.url = url + this.readyState = 1 + this.method = method.toUpperCase() + if (async != undefined) this.async = async + if (this.async) this.onreadystatechange() + }, + + /** + * Send request _data_. + */ + + send : function(data) { + var self = this + this.data = data + this.readyState = 4 + if (this.method == 'HEAD') this.responseText = null + this.responseHeaders['content-length'] = (this.responseText || '').length + if(this.async) this.onreadystatechange() + this.populateResponseXML() + lastRequest = function(){ + return self + } + }, + + /** + * Parse request body and populate responseXML if response-type is xml + * Based on the standard specification : http://www.w3.org/TR/XMLHttpRequest/ + */ + populateResponseXML: function() { + var type = this.getResponseHeader("content-type") + if (!type || !this.responseText || !type.match(/(text\/xml|application\/xml|\+xml$)/g)) + return + this.responseXML = JSpec.parseXML(this.responseText) + } + } + + // --- Response status codes + + JSpec.statusCodes = { + 100: 'Continue', + 101: 'Switching Protocols', + 200: 'OK', + 201: 'Created', + 202: 'Accepted', + 203: 'Non-Authoritative Information', + 204: 'No Content', + 205: 'Reset Content', + 206: 'Partial Content', + 300: 'Multiple Choice', + 301: 'Moved Permanently', + 302: 'Found', + 303: 'See Other', + 304: 'Not Modified', + 305: 'Use Proxy', + 307: 'Temporary Redirect', + 400: 'Bad Request', + 401: 'Unauthorized', + 402: 'Payment Required', + 403: 'Forbidden', + 404: 'Not Found', + 405: 'Method Not Allowed', + 406: 'Not Acceptable', + 407: 'Proxy Authentication Required', + 408: 'Request Timeout', + 409: 'Conflict', + 410: 'Gone', + 411: 'Length Required', + 412: 'Precondition Failed', + 413: 'Request Entity Too Large', + 414: 'Request-URI Too Long', + 415: 'Unsupported Media Type', + 416: 'Requested Range Not Satisfiable', + 417: 'Expectation Failed', + 422: 'Unprocessable Entity', + 500: 'Internal Server Error', + 501: 'Not Implemented', + 502: 'Bad Gateway', + 503: 'Service Unavailable', + 504: 'Gateway Timeout', + 505: 'HTTP Version Not Supported' + } + + /** + * Mock XMLHttpRequest requests. + * + * mockRequest().and_return('some data', 'text/plain', 200, { 'X-SomeHeader' : 'somevalue' }) + * + * @return {hash} + * @api public + */ + + function mockRequest() { + return { and_return : function(body, type, status, headers) { + XMLHttpRequest = MockXMLHttpRequest + ActiveXObject = false + status = status || 200 + headers = headers || {} + headers['content-type'] = type + JSpec.extend(XMLHttpRequest.prototype, { + responseText: body, + responseHeaders: headers, + status: status, + statusText: JSpec.statusCodes[status] + }) + }} + } + + /** + * Unmock XMLHttpRequest requests. + * + * @api public + */ + + function unmockRequest() { + XMLHttpRequest = OriginalXMLHttpRequest + ActiveXObject = OriginalActiveXObject + } + + JSpec.include({ + name: 'Mock XHR', + + // --- Utilities + + utilities : { + mockRequest: mockRequest, + unmockRequest: unmockRequest + }, + + // --- Hooks + + afterSpec : function() { + unmockRequest() + }, + + // --- DSLs + + DSLs : { + snake : { + mock_request: mockRequest, + unmock_request: unmockRequest, + last_request: function(){ return lastRequest() } + } + } + + }) +})() diff --git a/node_modules/jade/support/sass/spec/node.js b/node_modules/jade/support/sass/spec/node.js new file mode 100644 index 0000000..07d9934 --- /dev/null +++ b/node_modules/jade/support/sass/spec/node.js @@ -0,0 +1,9 @@ + +require.paths.unshift('spec', 'spec/lib', 'lib') +require('jspec') +sass = require('sass') + +JSpec + .exec('spec/spec.core.js') + .run({ reporter: JSpec.reporters.Terminal, fixturePath: 'spec/fixtures', failuresOnly: true }) + .report() diff --git a/node_modules/jade/support/sass/spec/spec.core.js b/node_modules/jade/support/sass/spec/spec.core.js new file mode 100644 index 0000000..5ee3cb7 --- /dev/null +++ b/node_modules/jade/support/sass/spec/spec.core.js @@ -0,0 +1,134 @@ + +describe 'Sass' + before + render = function(path, options) { + return sass.render(fixture(path + '.sass'), options) + } + + expected = function(path) { + return fixture(path + '.css') + } + + assert = function(path, options) { + render(path, options).should.eql expected(path) + } + end + + describe '.version' + it 'should be a triplet' + sass.version.should.match(/^\d+\.\d+\.\d+$/) + end + end + + describe '.render()' + describe 'with "cache" enabled' + describe 'without "filename"' + it 'should throw an error' + -{ assert('selectors', { cache: true }) }.should.throw_error 'filename option must be passed when cache is enabled' + end + end + + describe 'with "filename"' + it 'should still work' + assert('selectors', { cache: true, filename: 'style.sass' }) + end + end + end + + it 'should support complex selectors' + assert('selectors') + end + + describe '// ...' + it 'should be a sass-specific comment' + assert('comment') + end + end + + describe '& ...' + it 'should continue a selector' + assert('continuation') + end + end + + describe '{...}' + it 'should have access to variables' + assert('literal') + end + end + + describe ':key val' + it 'should define a property' + assert('properties') + end + + describe 'when nested' + it 'should traverse correctly' + assert('properties.nested') + end + + describe 'incorrectly' + it 'should throw an error' + try { assert('properties.nested.invalid') } + catch (e) { + e.message.should.eql 'ParseError: on line 3; invalid indentation, to much nesting' + } + end + end + end + + describe 'when at the top level' + it 'should throw an error' + try { assert('properties.invalid') } + catch (e) { + e.message.should.eql 'ParseError: on line 1; properties must be nested within a selector' + } + end + end + end + + describe '=:key val' + it 'should expand to -{moz, webkit}-border-radius' + assert('properties.expand') + end + end + + describe '!key = val' + it 'should define a variable' + assert('variables.regular') + end + end + + describe 'key: val' + it 'should define a variable' + assert('variables.alternate') + end + end + end + + describe '+mixin' + it 'should create a mixin' + assert('mixin') + end + + describe 'when the mixin does not exist' + try { assert('mixin.undefined') } + catch (e) { + e.message.should.eql 'ParseError: on line 2; mixin `large\' does not exist' + } + end + end + + describe '.collect()' + it 'should return variables defined' + var collected = sass.collect(fixture('collect.sass')) + collected.variables.should.eql { red: '#ff0000', black: '#000' } + end + + it 'should return mixins defined' + var collected = sass.collect(fixture('mixin.sass')) + collected.mixins.should.have_property 'large' + collected.mixins.should.have_property 'striped' + end + end +end \ No newline at end of file diff --git a/node_modules/jade/support/stylus/.gitignore b/node_modules/jade/support/stylus/.gitignore new file mode 100644 index 0000000..4be0b32 --- /dev/null +++ b/node_modules/jade/support/stylus/.gitignore @@ -0,0 +1,4 @@ +css +lib-cov +testing +.DS_Store diff --git a/node_modules/jade/support/stylus/.gitmodules b/node_modules/jade/support/stylus/.gitmodules new file mode 100644 index 0000000..01e2298 --- /dev/null +++ b/node_modules/jade/support/stylus/.gitmodules @@ -0,0 +1,3 @@ +[submodule "support/should"] + path = support/should + url = git://github.com/visionmedia/should.js.git diff --git a/node_modules/jade/support/stylus/.npmignore b/node_modules/jade/support/stylus/.npmignore new file mode 100644 index 0000000..2ce29aa --- /dev/null +++ b/node_modules/jade/support/stylus/.npmignore @@ -0,0 +1,5 @@ +test +support +testing +docs +examples diff --git a/node_modules/jade/support/stylus/History.md b/node_modules/jade/support/stylus/History.md new file mode 100644 index 0000000..3c186ae --- /dev/null +++ b/node_modules/jade/support/stylus/History.md @@ -0,0 +1,231 @@ + +0.9.2 / 2011-03-21 +================== + + * Removed a `console.log()` call + +0.9.1 / 2011-03-18 +================== + + * Fixed connect middleware `@import` support. Closes #168 + The middleware is now smart enough to know when imports + change, and will re-compile the target file. + + * Changed middleware `compile` function to return the `Renderer` (API change) + +0.9.0 / 2011-03-18 +================== + + * Added `-i, --interactive` for the Stylus REPL (eval stylus expressions, tab-completion etc) + * Added link to vim syntax + * Changed `p()` built-in to display parens + * Changed `--compress -C` to `-c`, and `-css -c` is now `-C` + * Fixed; preserve rest-arg expressions. Closes #194 + * Fixed `*=` in selector, ex `[class*="foo"]` + * Fixed `--watch` issue with growl, updated to 1.1.0. Closes #188 + * Fixed negative floats when compressed. Closes #193 [reported by ludicco] + +0.8.0 / 2011-03-14 +================== + + * Added postfix `for`-loop support. + Ex: `return n if n % 2 == 0 for n in nums` + * Added support for several postfix operators + Ex: `border-radius: 5px if true unless false;` + * Added `last(expr)` built-in function + * Added `sum(nums)` built-in function + * Added `avg(nums)` built-in function + * Added `join(delim, vals)` built-in function + * Added `Evaluator#{currentScope,currentBlock}` + * Added multi-line function paramter definition support + * Changed; `0` is falsey, `0%`, `0em`, `0px` etc truthy. Closes #160 + * Fixed `for` implicit __return__ value + * Fixed `for` explicit __return__ value + * Fixed mixin property ordering + +0.7.4 / 2011-03-10 +================== + + * Added `RGBA` node + * Added `is a "color"` special-case, true for `HSLA` and `RGBA` nodes. +Closes #180 + * Performance; 2.5x faster compiles due to removing use of getters in `Parser` and `Lexer` (yes, they are really slow). + * Removed `Color` node + * Fixed stylus(1) `--watch` support due to dynamic __@import__ support. Closes #176 + +0.7.3 / 2011-03-09 +================== + + * Fixed; allow semi-colons for non-css syntax for one-liners + +0.7.2 / 2011-03-08 +================== + + * Added `isnt` operator, same as `is not`, and `!=` + * Added support for dynamic `@import` expressions + * Added `@import` index resolution support + * Added `light()` / `dark()` BIFs + * Added `compress` option for connect middleware [disfated] + * Changed; most built-in functions defined in stylus (`./lib/functions/index.styl`) + * Fixed dynamic expressions in `url()`. Closes #105 + +0.7.1 / 2011-03-07 +================== + + * Fixed connect middleware for 0.4.x + +0.7.0 / 2011-03-02 +================== + + * Added `is` and `is not` aliases for `==` and `!=` + * Added __@keyframes__ dynamic name support + * Fixed units in interpolation + * Fixed clamping of HSLA degrees / percentages + +0.6.7 / 2011-03-01 +================== + + * Fixed __RGBA__ -> __HSLA__ conversion due to typo + +0.6.6 / 2011-03-01 +================== + + * Added string -> unit type coercion support aka `5px + "10"` will give `15px` + * Added `warn` option Closes #152 + Currently this only reports on re-definition of functions + * Added '$' as a valid identifier character + * Added `mixin` local variable for function introspection capabilities. Closes #162 + * Fixed typo, `Unit#toBoolean()` is now correct + * Fixed interpolation function calls. Closes #156 + * Fixed mixins within Media node. Closes #153 + * Fixed function call in ret val. Closes #154 + +0.6.5 / 2011-02-24 +================== + + * Fixed parent ref `&` mid-selector bug. Closes #148 [reported by visnu] + +0.6.4 / 2011-02-24 +================== + + * Fixed for within brackets. Closes #146 + +0.6.3 / 2011-02-22 +================== + + * Fixed single-ident selectors. Closes #142 + * Fixed cyclic __@import__ with file of the same name. Closes #143 + +0.6.2 / 2011-02-21 +================== + + * Added stylus(1) growl support when using `--watch` + * Added __@import__ watching support to stylus(1). Closes #134 + * Changed; stylus(1) only throws when `--watch` is not used + * Fixed `darken-by()` BIF + * Fixed __@import__ literal semi-colon. Closes #140 + +0.6.1 / 2011-02-18 +================== + + * Fixed evaluation of nodes after a return. Closes #139 + +0.6.0 / 2011-02-18 +================== + + * Added `stylus(1)` direct css to stylus file conversion [Mario] + For example instead of `$ stylus --css < foo.css > foo.styl` + you may now either `$ stylus --css foo.css` or provide + a destination path `$ stylus --css foo.css /tmp/out.styl`. + + * Added postfix conditionals. Closes #74 + Expressive ruby-ish syntax, ex: `padding 5px if allow-padding`. + +0.5.3 / 2011-02-17 +================== + + * Added `in` operator. `3 in nums`, `padding in props` etc + * Added `Expression#hash`, hashing all of the nodes in order + * Added tests for conditionals with braces. Closes #136 + * Fixed ids that are also valid colors. Closes #137 + +0.5.2 / 2011-02-15 +================== + + * Fixed spaces after "}" with css-style. Closes #131 + * Fixed single-line css-style support. Closes #130 + +0.5.1 / 2011-02-11 +================== + + * Fixed mixin property ordering. Closes #125 + +0.5.0 / 2011-02-09 +================== + + * Added `lighten-by()` BIF + * Added `darken-by()` BIF + +0.4.1 / 2011-02-09 +================== + + * Added support for function definition braces + * Fixed issue with invalid color output. Closes #127 + +0.4.0 / 2011-02-07 +================== + + * Added css-style syntax support + * Fixed support for `*` selector within __@media__ blocks + +0.3.1 / 2011-02-04 +================== + + * Fixed property disambiguation logic. Closes #117 + You no longer need to add a trailing comma when + chaining selectors such as 'td:nth-child(2)\ntd:nth-child(3)' + +0.3.0 / 2011-02-04 +================== + + * Added more assignment operators. Closes #77 + +=, -=, *=, /=, and %= + +0.2.1 / 2011-02-02 +================== + + * Fixed `--compress` when passing files for stylus(1). Closes #115 + * Fixed bug preventing absolute paths from being passed to `@import` + * Fixed `opposite-position()` with nested expressions, unwrapping + * Fixed a couple global var leaks [aheckmann] + +0.2.0 / 2011-02-01 +================== + + * Added; `url()` utilizing general lookup paths. + This means that `{ paths: [] }` is optional now, as lookups + will be relative to the file being rendered by default. + + * Added `-w, --watch` support to stylus(1). Closes #113 + +0.1.0 / 2011-02-01 +================== + + * Added `opposite-position(positions)` built-in function + * Added `image-lookup(path)` built-in function + * Added `-o, --out ` support to stylus(1) + * Added `stylus [file|dir ...]` support + * Added; defaulting paths to `[CWD]` for stylus(1) + * Changed; `unquote()` using `Literal` node + * Changed; utilizing `Literal` in place of some `Ident`s + +0.0.2 / 2011-01-31 +================== + + * Added optional property colon support. Closes #110 + * Added `--version` to stylus(1) + +0.0.1 / 2011-01-31 +================== + + * Initial release \ No newline at end of file diff --git a/node_modules/jade/support/stylus/LICENSE b/node_modules/jade/support/stylus/LICENSE new file mode 100644 index 0000000..a206b68 --- /dev/null +++ b/node_modules/jade/support/stylus/LICENSE @@ -0,0 +1,22 @@ +(The MIT License) + +Copyright (c) 2010 LearnBoost + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/node_modules/jade/support/stylus/Makefile b/node_modules/jade/support/stylus/Makefile new file mode 100644 index 0000000..40a5dc8 --- /dev/null +++ b/node_modules/jade/support/stylus/Makefile @@ -0,0 +1,20 @@ + +SRC = $(shell find lib -name "*.js") +TM_BUNDLE = editors/Stylus.tmbundle +TM_BUNDLE_DEST = ~/Library/Application\ Support/TextMate/Bundles + +test: test-integration + +test-integration: + @node test/run.js + +install-bundle: + cp -fr $(TM_BUNDLE) $(TM_BUNDLE_DEST) + +update-bundle: + cp -fr $(TM_BUNDLE_DEST)/Stylus.tmbundle editors + +benchmark: + @node bm.js + +.PHONY: test test-integration install-bundle update-bundle benchmark \ No newline at end of file diff --git a/node_modules/jade/support/stylus/Readme.md b/node_modules/jade/support/stylus/Readme.md new file mode 100644 index 0000000..d2e57a9 --- /dev/null +++ b/node_modules/jade/support/stylus/Readme.md @@ -0,0 +1,118 @@ + +# Stylus + + Stylus is a revolutionary new language, providing an efficient, dynamic, and expressive way to generate CSS. + +## Installation + + $ npm install stylus + +### Example + + border-radius() + -webkit-border-radius arguments + -moz-border-radius arguments + border-radius arguments + + body a + font 12px/1.4 "Lucida Grande", Arial, sans-serif + background black + color #ccc + + form input + padding 5px + border 1px solid + border-radius 5px + +compiles to: + + body a { + font: 12px/1.4 "Lucida Grande", Arial, sans-serif; + background: #000; + color: #ccc; + } + form input { + padding: 5px; + border: 1px solid; + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + border-radius: 5px; + } + +### Features + + Stylus has _many_ features, click the links below for detailed documentation. + + - [css syntax](stylus/blob/master/docs/css-style.md) support + - [mixins](stylus/blob/master/docs/mixins.md) + - [variables](stylus/blob/master/docs/variables.md) + - [interpolation](stylus/blob/master/docs/interpolation.md) + - arithmetic, logical, and equality [operators](stylus/blob/master/docs/operators.md) + - [importing](stylus/blob/master/docs/import.md) of other stylus sheets + - [introspection api](stylus/blob/master/docs/introspection.md) + - type coercion + - [conditionals](stylus/blob/master/docs/conditionals.md) + - [iteration](stylus/blob/master/docs/iteration.md) + - nested [selectors](stylus/blob/master/docs/selectors.md) + - parent reference + - in-language [functions](stylus/blob/master/docs/functions.md) + - [variable arguments](stylus/blob/master/docs/vargs.md) + - built-in [functions](stylus/blob/master/docs/bifs.md) (over 25) + - optional [image inlining](stylus/blob/master/docs/functions.url.md) + - optional compression + - JavaScript [API](stylus/blob/master/docs/js.md) + - extremely terse syntax + - stylus [executable](stylus/blob/master/docs/executable.md) + - [error reporting](stylus/blob/master/docs/error-reporting.md) + - single-line and multi-line [comments](stylus/blob/master/docs/comments.md) + - css [literal](stylus/blob/master/docs/literal.md) + - character [escaping](stylus/blob/master/docs/escape.md) + - [@keyframes](stylus/blob/master/docs/keyframes.md) support + - [@font-face](stylus/blob/master/docs/font-face.md) support + - [@media](stylus/blob/master/docs/media.md) support + - Connect [Middleware](stylus/blob/master/docs/middleware.md) + - TextMate [bundle](stylus/blob/master/docs/textmates.md) + - VIM [Syntax](https://github.com/wavded/vim-stylus) + +### Framework Support + + - [Connect](stylus/blob/master/docs/middleware.md) + - [Ruby On Rails](https://github.com/lucasmazza/stylus_rails) + +### Screencasts + + - [Stylus Intro](http://screenr.com/bNY) + - [CSS Syntax & Postfix Conditionals](http://screenr.com/A8v) + +### Authors + + - [TJ Holowaychuk (visionmedia)](http://github.com/visionmedia) + +### More Information + + - Language [comparisons](stylus/blob/master/docs/compare.md) + +## License + +(The MIT License) + +Copyright (c) 2010 LearnBoost <dev@learnboost.com> + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/node_modules/jade/support/stylus/bin/stylus b/node_modules/jade/support/stylus/bin/stylus new file mode 100755 index 0000000..f9a5008 --- /dev/null +++ b/node_modules/jade/support/stylus/bin/stylus @@ -0,0 +1,456 @@ +#!/usr/bin/env node + +/** + * Module dependencies. + */ + +var fs = require('fs') + , stylus = require('../') + , basename = require('path').basename + , dirname = require('path').dirname + , join = require('path').join + , growl = require('growl'); + +/** + * Arguments. + */ + +var args = process.argv.slice(2); + +/** + * Compare flag. + */ + +var compare = false; + +/** + * Compress flag. + */ + +var compress = false; + +/** + * CSS conversion flag. + */ + +var convertCSS = false; + +/** + * Files to processes. + */ + +var files = []; + +/** + * Destination directory. + */ + +var dest; + +/** + * Watcher hash. + */ + +var watchers; + +/** + * Enable REPL. + */ + +var interactive; + +/** + * Usage docs. + */ + +var usage = [ + '' + , ' Usage: stylus [options] [command] [< in [> out]]' + , ' [file|dir ...]' + , '' + , ' Commands:' + , '' + , ' help Opens help info for in' + , ' your default browser. (osx only)' + , '' + , ' Options:' + , '' + , ' -i, --interactive Start interactive REPL' + , ' -w, --watch Watch file(s) for changes and re-compile' + , ' -o, --out Output to when passing files' + , ' -C, --css [dest] Convert css input to stylus' + , ' -c, --compress Compress css output' + , ' -d, --compare Display input along with output' + , ' -V, --version Display the version of stylus' + , ' -h, --help Display help information' + , '' +].join('\n'); + +/** + * Handle arguments. + */ + +var arg; +while (args.length) { + arg = args.shift(); + switch (arg) { + case '-h': + case '--help': + console.log(usage); + process.exit(1); + case '-d': + case '--compare': + compare = true; + break; + case '-c': + case '--compress': + compress = true; + break; + case '-C': + case '--css': + convertCSS = true; + break; + case '-V': + case '--version': + console.log(stylus.version); + process.exit(0); + break; + case '-o': + case '--out': + dest = args.shift(); + if (!dest) throw new Error('--out required'); + break; + case 'help': + var name = args.shift(); + if (!name) throw new Error('help required'); + help(name); + break; + case '-i': + case '--repl': + case '--interactive': + interactive = true; + break; + case '-w': + case '--watch': + watchers = {}; + break; + default: + files.push(arg); + } +} + +// if --watch is used, assume we are +// not working with stdio + +if (watchers && !files.length) { + files = fs.readdirSync(process.cwd()) + .filter(function(file){ + return file.match(/\.styl$/); + }); +} + +/** + * Open the default browser to the CSS property `name`. + * + * @param {String} name + */ + +function help(name) { + var url = 'https://developer.mozilla.org/en/CSS/' + name + , exec = require('child_process').exec; + exec('open "' + url + '"', function(){ + process.exit(0); + }); +} + +// Compilation options + +var options = { + filename: 'stdin' + , compress: compress + , paths: [process.cwd()] +}; + +// Buffer stdin + +var str = ''; + +// Convert css to stylus + +if (convertCSS) { + switch (files.length) { + case 2: + compileCSSFile(files[0], files[1]); + break; + case 1: + compileCSSFile(files[0], files[0].replace('.css', '.styl')); + break; + default: + var stdin = process.openStdin(); + stdin.setEncoding('utf8'); + stdin.on('data', function(chunk){ str += chunk; }); + stdin.on('end', function(){ + var out = stylus.convertCSS(str); + console.log(out); + }); + } +} else if (interactive) { + repl(); +} else { + if (files.length) { + compileFiles(files); + } else { + compileStdio(); + } +} + +/** + * Start stylus REPL. + */ + +function repl() { + var options = { filename: 'stdin', imports: [__dirname + '/../lib/functions'] } + , parser = new stylus.Parser('', options) + , evaluator = new stylus.Evaluator(parser.parse(), options) + , rl = require('readline') + , repl = rl.createInterface(process.stdin, process.stdout, true) + , global = evaluator.global.scope; + + // expose BIFs + evaluator.evaluate(); + + // readline + repl.setPrompt('> '); + repl.prompt(); + + // HACK: flat-list auto-complete + repl._tabComplete = function(){ + var out = this.output + , line = this.line + , keys = Object.keys(global.locals) + , len = keys.length + , words = line.split(/\s+/) + , word = words.pop() + , names = [] + , name + , obj + , key; + + // find words that match + for (var i = 0; i < len; ++i) { + key = keys[i]; + if (0 == key.indexOf(word)) { + names.push(key); + } + } + + // several candidates + if (names.length > 1) { + out.write('\r\n\r\n\033[90m'); + names.forEach(function(name){ + var node = global.lookup(name); + switch (node.nodeName) { + case 'function': + out.write(' - ' + node + '\r\n'); + break; + default: + out.write(' - ' + name + '\r\n'); + } + }); + out.write('\r\n\033[0m'); + this._refreshLine(); + // single candidate + } else if (names.length) { + name = names.pop(); + obj = global.lookup(name); + name = name.replace(word, ''); + switch (obj.nodeName) { + case 'function': + this._insertString(name + '()'); + this.cursor--; + break; + default: + this._insertString(name); + } + this._refreshLine(); + } + }; + + repl.on('line', function(line){ + if (!line.trim().length) return repl.prompt(); + parser = new stylus.Parser(line, options); + parser.state.push('expression'); + evaluator.return = true; + try { + var expr = parser.parse(); + var ret = evaluator.visit(expr); + ret = ret.nodes[ret.nodes.length - 1]; + ret = ret.toString(); + if ('(' == ret[0]) ret = ret.replace(/^\(|\)$/g, ''); + console.log('\033[90m=> \033[0m' + highlight(ret)); + repl.prompt(); + } catch (err) { + console.error('\033[31merror: %s\033[0m', err.message || err.stack); + repl.prompt(); + } + }); + + repl.on('SIGINT', function(){ + console.log(); + process.exit(0); + }); +} + +/** + * Highlight the given string of stylus. + */ + +function highlight(str) { + return str + .replace(/(#)?(\d+(\.\d+)?)/g, function($0, $1, $2){ + return $1 ? $0 : '\033[36m' + $2 + '\033[0m'; + }) + .replace(/(#[\da-fA-F]+)/g, '\033[33m$1\033[0m') + .replace(/('.*?'|".*?")/g, '\033[32m$1\033[0m'); +} + +/** + * Convert a CSS file to a Styl file + */ + +function compileCSSFile(file, fileOut) { + fs.lstat(file, function(err, stat){ + if (err) throw err; + if (stat.isFile()) { + fs.readFile(file, 'utf8', function(err, str){ + if (err) throw err; + var styl = stylus.convertCSS(str); + fs.writeFile(fileOut, styl, function(err){ + if (err) throw err; + }); + }); + } + }); +} + +/** + * Compile with stdio. + */ + +function compileStdio() { + var stdin = process.openStdin(); + stdin.setEncoding('utf8'); + stdin.on('data', function(chunk){ str += chunk; }); + stdin.on('end', function(){ + // Compile to css + stylus(str, options).render(function(err, css){ + if (err) throw err; + if (compare) { + console.log('\n\x1b[1mInput:\x1b[0m'); + console.log(str); + console.log('\n\x1b[1mOutput:\x1b[0m'); + } + console.log(css); + if (compare) console.log(); + }); + }); +} + +/** + * Compile the given files. + */ + +function compileFiles(files) { + files.forEach(compileFile); +} + +/** + * Compile the given file. + */ + +function compileFile(file) { + // ensure file exists + fs.lstat(file, function(err, stat){ + if (err) throw err; + // file + if (stat.isFile()) { + fs.readFile(file, 'utf8', function(err, str){ + if (err) throw err; + options.filename = file; + options._imports = []; + stylus(str, options).render(function(err, css){ + watchImports(file, options._imports); + if (err) { + if (watchers) { + console.error(err.stack || err.message); + growl.notify(err.message, { title: 'Stylus error' }); + } else { + throw err; + } + } else { + writeFile(file, css); + } + }); + }); + // directory + } else if (stat.isDirectory()) { + fs.readdir(file, function(err, files){ + if (err) throw err; + files.filter(function(path){ + return path.match(/\.styl$/); + }).map(function(path){ + return file + '/' + path; + }).forEach(compileFile); + }); + } + }); +} + +/** + * Write the given css output. + */ + +function writeFile(file, css) { + // --out support + var path = dest + ? dest + '/' + basename(file, '.styl') + '.css' + : file.replace('.styl', '.css'); + fs.writeFile(path, css, function(err){ + if (err) throw err; + console.log(' \033[90mcompiled\033[0m %s', path); + // --watch support + watch(file, compileFile); + }); +} + +/** + * Watch the given `file` and invoke `fn` when modified. + */ + +function watch(file, fn) { + // not watching + if (!watchers) return; + + // already watched + if (watchers[file]) return; + + // watch the file itself + watchers[file] = true; + console.log(' \033[90mwatching\033[0m %s', file); + fs.watchFile(file, { interval: 50 }, function(curr, prev){ + if (curr.mtime > prev.mtime) fn(file); + }); +} + +/** + * Watch `imports`, re-compiling `file` when they change. + */ + +function watchImports(file, imports) { + imports.forEach(function(import){ + if (!import.path) return; + watch(import.path, function(){ + compileFile(file); + }); + }); +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/bin/stylus-tutorial b/node_modules/jade/support/stylus/bin/stylus-tutorial new file mode 100755 index 0000000..5ab1c61 --- /dev/null +++ b/node_modules/jade/support/stylus/bin/stylus-tutorial @@ -0,0 +1,287 @@ +#!/usr/bin/env node + +/** + * Module dependencies. + */ + +try { + var stylus = require('stylus'); +} catch (err) { + var stylus = require('../lib/stylus'); +} + +/** + * Banner. + */ + +var banner = '\n\ + \n\ + _ _ \n\ + ___| |_ _ _| |_ _ ___ \n\ + / __| __| | | | | | | / __| \n\ + \\__ \\ |_| |_| | | |_| \\__ \\ \n\ + |___/\\__|\\__, |_|\\__,_|___/ \n\ + |___/ \n\ + \n\ +'; + +/** + * Steps. + */ + +var steps = []; + +/** + * Clear the screen and move the cursor up. + */ + +function clear() { + console.log('\x1b[1J\x1b[H'); +} + +/** + * Output "press enter" message. + */ + +function enter() { + process.stdout.write('\x1b[90mpress enter to continue:\x1b[0m '); +} + +/** + * Initialize a `Step` with the given data. + * + * @param {String} title + * @param {String} desc + * @param {String} src + * @param {Function} fn + */ + +function Step(title, desc, src, fn) { + var self = this; + this.n = steps.length; + this.src = src; + desc = desc.replace(/\_([^_]+)\_/g, '\x1b[33m$1\x1b[90m'); + + this.next = function(){ + var step = steps[self.n + 1]; + if (step) { + step.display(); + } else { + console.log(' THE END\n'); + process.exit(0); + } + }; + + this.display = function(retry){ + if (!retry) { + console.log(' %d) \x1b[1m%s\x1b[0m\n', self.n, title); + console.log(' \x1b[90m%s\x1b[0m', desc); + } + console.log('\n%s\n', src); + console.log('\x1b[90m--------------------\x1b[0m \n'); + this.input(); + }; + + this.input = function(){ + stdin.resume(); + var buf = ''; + stdin.on('data', function callback(chunk){ + if (0 == chunk.indexOf('quit')) process.exit(1); + var dot = '.' == chunk[0] && '\n' == chunk[1] + , equal = buf.trim() == self.src.trim(); + if (dot || equal) { + stdin.pause(); + stdin.removeListener('data', callback); + stylus.render(buf, { filename: 'stdin' }, function(err, css){ + if (err) { + console.log('\n\x1b[31mError: ' + err.message + '\x1b[0m\n'); + self.display(true); + return; + } + clear(); + console.log('\x1b[90m-------------------- stylus\x1b[0m \n'); + console.log(buf.replace(/^/gm, ' ')); + console.log('\x1b[90m-------------------- css\x1b[0m \n'); + console.log(css.replace(/^/gm, ' ')); + console.log(); + enter(); + stdin.resume(); + stdin.once('data', function(){ + clear(); + self.next(); + }); + }); + return; + } + buf += chunk; + }); + }; +} + +/** + * Step definitions. + */ + +steps.push(new Step( + 'Selector Properties' + , 'The Stylus grammar has indentation-based blocks,\n' + + ' meaning one does not surround selector properties\n' + + ' using braces _{_ _}_, but uses an indent of two \n' + + ' spaces, or a single tab.\n' + + '\n' + + ' To get started, type the stylus you see below\n' + + ' and then press return a few times or type _"."_ to render.' + , 'body\n color black')); + +steps.push(new Step( + 'Multiple Selectors' + , 'Blocks can be applied to several selectors at once\n' + + ' by separating them via comma, or newline.\n' + + '\n' + + ' Both examples shown below are equivalent.' + + , 'a.button, input[type=button]\n' + + ' border 1px solid #eee\n' + + ' padding 5px\n\n' + + 'a.button\n' + + 'input[type=button]\n' + + ' border 1px solid #eee\n' + + ' padding 5px' + )); + +steps.push(new Step( + 'Nested Selectors' + , 'Selectors may also be nested.\n' + + , 'ul\n' + + ' li\n' + + ' a\n' + + ' color black\n' + )); + +steps.push(new Step( + 'Variables' + , 'Stylus allows you to define variables by utilizing\n' + + ' the _=_ operator, much like you would in any other language.\n' + + '\n' + + ' These variables may be assigned to _numbers_, _strings_, _booleans_,\n' + + ' and virtually everything else you see in css.' + + , 'size = 14px\n\n' + + 'body\n' + + ' font size Arial, sans-serif' + )); + +steps.push(new Step( + 'Conditional Assignment' + , 'The conditional assignment operator _?=_ may be used to\n' + + ' define a variable only when previously undefined.' + + , 'size = 14px\n\n' + + 'body\n' + + ' size ?= 22px\n' + + ' font size Arial, sans-serif' + )); + +steps.push(new Step( + 'Arithmetic' + , 'A variety of binary arithmetic operators are supported\n' + + ' as well as unary operators such as _-_, _+_, and _~_.' + + , 'size = 14px\n' + + 'large-size = size * 2\n' + + '\n' + + 'body\n' + + ' font large-size\n' + + '\n' + + 'p\n' + + ' margin-left -(size - 2)' + )); + +steps.push(new Step( + 'Coercion' + , 'Arithmetic operations coerce the right-hand operand when\n' + + ' applicable, for example converting _2s_ in _1000ms + 2s_\n' + + ' into _2000ms_ before evaluating the expression.\n' + + '\n' + + ' Examples:\n' + + ' _15px_ - _5_\n' + + ' _#000_ + _#eee_\n' + + ' _#fff_ - rgba(_0_,_0_,_0_,_.5_)\n' + + ' _#fff_ / _2_\n' + + ' _5in_ - _3cm_\n' + + , 'duration = 2s\n\n' + + '.fade\n' + + ' -webkit-transition opacity duration - 1500ms linear' + )); + +steps.push(new Step( + 'Functions' + , 'Stylus functions may act as mixins or have a return value.\n' + + 'For example here we use the unit() built-in function to.\n' + + 'forcing both unit\'s type to _px_, and then add them.\n' + + '\n' + + 'Note that we may also use the _return_ keyword, however it\n' + + 'is optional in most cases.' + + , 'add(a, b)\n' + + ' a = unit(a, "px")\n' + + ' b = unit(b, "px")\n' + + ' a + b\n' + + '\n' + + 'body\n' + + ' padding add(5px, 10px)\n' + + ' margin add(5, 10)' + )); + +steps.push(new Step( + 'Mixins' + , 'Mixins are defined in the same manner as functions\n' + + 'with return values, however they "mix in" their properties\n' + + 'and selectors into the caller.\n' + + '\n' + + 'Mixin parens are optional in most cases, so we may apply\n' + + 'the transparently.' + + , 'border-radius(n)\n' + + ' -webkit-border-radius n\n' + + ' -moz-border-radius n\n' + + ' border-radius n\n' + + '\n' + + 'body\n' + + ' border-radius(5px)\n' + + '\n' + + 'form input\n' + + ' border-radius 5px' + )); + +/** + * Start tutorial. + */ + +clear(); +console.log('\x1b[1m' + banner + '\x1b[0m'); +console.log('\n Welcome to the stylus interactive tutorial.\n'); +console.log(' - To quit at any time type \x1b[1mquit\x1b[0m.'); +console.log(' - To force rendering type "." and press enter,'); +console.log(' however source will be automatically rendered'); +console.log(' when it matches the step\'s source.'); +console.log(); +enter(); + +var stdin = process.openStdin(); +stdin.setEncoding('utf8'); + +stdin.once = function(event, fn){ + this.on(event, function callback(chunk){ + stdin.removeListener(event, callback); + fn(chunk); + }); +}; + +stdin.once('data', function(chunk){ + stdin.pause(); + clear(); + steps[0].display(); +}); diff --git a/node_modules/jade/support/stylus/bm.js b/node_modules/jade/support/stylus/bm.js new file mode 100644 index 0000000..ce1acfa --- /dev/null +++ b/node_modules/jade/support/stylus/bm.js @@ -0,0 +1,22 @@ + +/** + * Module dependencies. + */ + +var stylus = require('./'); + +var times = 200 + , n = times + , start = new Date; + +console.log('compiling %d times', times); + +while (n--) { + stylus('body\n color: white;\n background: url(/images/foo.png)\n a\n &:hover\n text-decoration: underline;') + .render(function(err, css){}); +} + +var duration = new Date - start; +console.log(' duration: %dms', duration); +console.log(' average: %dms', duration / times); +console.log(' per second: %d', (times / (duration / 1000)).toFixed(1)); diff --git a/node_modules/jade/support/stylus/docs/bifs.md b/node_modules/jade/support/stylus/docs/bifs.md new file mode 100644 index 0000000..75e599f --- /dev/null +++ b/node_modules/jade/support/stylus/docs/bifs.md @@ -0,0 +1,453 @@ + +## Built-in Functions + +### red(color) + +Return the red component of the given `color`. + + red(#c00) + // => 204 + +### green(color) + +Return the green component of the given `color`. + + green(#0c0) + // => 204 + +### blue(color) + +Return the blue component of the given `color`. + + red(#00c) + // => 204 + +### alpha(color) + +Return the alpha component of the given `color`. + + alpha(#fff) + // => 1 + + alpha(rgba(0,0,0,0.3)) + // => 0.3 + +### dark(color) + +Check if `color` is dark: + + dark(black) + // => true + + dark(#005716) + // => true + + dark(white) + // => false + + +### light(color) + +Check if `color` is light: + + light(black) + // => false + + light(white) + // => true + + light(#00FF40) + // => true + +### hue(color) + +Return the hue of the given `color`. + + hue(hsla(50deg, 100%, 80%)) + // => 50deg + +### saturation(color) + +Return the saturation of the given `color`. + + hue(hsla(50deg, 100%, 80%)) + // => 100% + +### lightness(color) + +Return the lightness of the given `color`. + + hue(hsla(50deg, 100%, 80%)) + // => 80% + +### typeof(node) + +Return type of `node` as a string. + + type(12) + // => 'unit' + + typeof(12) + // => 'unit' + + typeof(#fff) + // => 'rgba' + + type-of(#fff) + // => 'rgba' + +Aliased as `type-of` and `type`. + +### unit(unit[, type]) + +Return a string for the type of `unit` or an empty string, +or assign the given `type` without unit conversion. + + unit(10) + // => '' + + unit(15in) + // => 'in' + + unit(15%, 'px') + // => 15px + + unit(15%, px) + // => 15px + +### match(pattern, string) + +Test if `string` matches the given `pattern`. + + match('^foo(bar)?', foo) + match('^foo(bar)?', foobar) + // => true + + match('^foo(bar)?', 'foo') + match('^foo(bar)?', 'foobar') + // => true + + match('^foo(bar)?', 'bar') + // => false + +### abs(unit) + + abs(-5px) + // => 5px + + abs(5px) + // => 5px + +### ceil(unit) + + ceil(5.5in) + // => 6in + +### floor(unit) + + floor(5.6px) + // => 5px + +### round(unit) + + round(5.5px) + // => 6px + + round(5.4px) + // => 5px + +### min(a, b) + + min(1, 5) + // => 1 + +### max(a, b) + + max(1, 5) + // => 5 + +### even(unit) + + even(6px) + // => true + +### odd(unit) + + odd(5mm) + // => true + +### sum(nums) + + sum(1 2 3) + // => 6 + +### avg(nums) + + avg(1 2 3) + // => 2 + +### join(delim, vals...) + + Join the given `vals` with `delim`. + + join(' ', 1 2 3) + // => "1 2 3" + + join(',', 1 2 3) + // => "1,2,3" + + join(', ', foo bar baz) + // => "foo, bar, baz" + + join(', ', foo, bar, baz) + // => "foo, bar, baz" + +### hsla(color | h[, s, l, a]) + +Convert the given `color` to an `HSLA` node, +or h,s,l,a component values. + + hslaa(10deg, 50%, 30%, 0.5) + // => HSLA + + hslaa(#ffcc00) + // => HSLA + +### hsla(color | h[, s, l]) + +Convert the given `color` to an `HSLA` node, +or h,s,l component values. + + hsla(10, 50, 30) + // => HSLA + + hsla(#ffcc00) + // => HSLA + +### rgba(color | r[, g, b, a]) + +Return `RGBA` from the r,g,b,a channels or provide a `color` to tweak the alpha. + + rgba(255,0,0,0.5) + // => rgba(255,0,0,0.5) + + rgba(255,0,0,1) + // => #ff0000 + + rgba(#ffcc00, 0.5) + // rgba(255,204,0,0.5) + +### rgb(color | r[, g, b]) + +Return a `RGBA` from the r,g,b channels or cast to an `RGBA` node. + + rgb(255,204,0) + // => #ffcc00 + + rgb(#fff) + // => #fff + +### lighten(color, amount) + +Lighten the given `color` by `amount`. + + lighten(black, 50%) + // => #808080 + +### darken(color, amount) + +Darken the given `color` by `amount`. + + darken(white, 50%) + // => #808080 + +### lighten-by(color, amount) + + Lighten by `amount` of the current lightness value. + + lighten-by(black, 50%) + // => #808080 + + lighten-by(lighten-by(black, 50%), 50%) + // => #bfbfbf + + lighten-by(lighten-by(lighten-by(black, 50%), 50%), 50%) + // => #fff + +essentially the same as: + + black + hsla(0,0,50%) + black + hsla(0,0,75%) + black + hsla(0,0,100%) + +### darken-by(color, amount) + + Darken by `amount` of the current lightness value. + + darken-by(white, 50%) + // => #808080 + + darken-by(darken-by(white, 50%), 50%) + // => #404040 + + darken-by(darken-by(darken-by(white, 50%), 50%), 50%) + // => #202020 + +### desaturate(color, amount) + +Desaturate the given `color` by `amount`. + + desaturate(#f00, 40%) + // => #c33 + +### saturate(color, amount) + +Saturate the given `color` by `amount`. + + saturate(#c33, 40%) + // => #f00 + +### unquote(str | ident) + + Unquote the given `str` and returned as a `Literal` node. + + unquote("sans-serif") + // => sans-serif + + unquote(sans-serif) + // => sans-serif + + unquote('1px / 2px') + // => 1px / 2px + +### operate(op, left, right) + + Perform the given `op` on the `left` and `right` operands: + + op = '+' + operate(op, 15, 5) + // => 20 + +### length([expr]) + + Parenthesized expressions may act as tuples, the `length()` function returns the length of such expressions. + + length((1 2 3 4)) + // => 4 + + length((1 2)) + // => 2 + + length((1)) + // => 1 + + length(()) + // => 0 + + length(1 2 3) + // => 3 + + length(1) + // => 1 + + length() + // => 0 + +### warn(msg) + + Warn with the given error `msg`, does not exit. + + warn("oh noes!") + +### error(msg) + + Exits with the given error `msg`. + + add(a, b) + unless a is a 'unit' and b is a 'unit' + error('add() expects units') + a + b + +### last(expr) + + Return the _last_ value in the given `expr`: + + nums = 1 2 3 + last(nums) + last(1 2 3) + // => 3 + + list = (one 1) (two 2) (three 3) + last(list) + // => (three 3) + +### p(expr) + + Inspect the given `expr`: + + fonts = Arial, sans-serif + p('test') + p(123) + p((1 2 3)) + p(fonts) + p(#fff) + p(rgba(0,0,0,0.2)) + + add(a, b) + a + b + + p(add) + +stdout: + + inspect: "test" + inspect: 123 + inspect: 1 2 3 + inspect: Arial, sans-serif + inspect: #fff + inspect: rgba(0,0,0,0.2) + inspect: add(a, b) + +### opposite-position(positions) + + Return the opposites of the given `positions`. + + opposite-position(right) + // => left + + opposite-position(top left) + // => bottom right + + opposite-position('top' 'left') + // => bottom right + +### image-size(path) + + Returns the `width` and `height` of the image found at `path`. Lookups are performed in the same manner as `@import`, altered by the `paths` setting. + + width(img) + return image-size(img)[0] + + height(img) + return image-size(img)[1] + + image-size('tux.png') + // => 405px 250px + + image-size('tux.png')[0] == width('tux.png') + // => true + +### Undefined Functions + + Undefined functions will output as literals, so for example + we may call `rgba-stop(50%, #fff)` within our css, and it will + output as you would expect. We can use this within helpers as well. + + In the example below we simply define the function `stop()` which + returns the literal `rgba-stop()` call. + + stop(pos, rgba) + rgba-stop(pos, rgba) + + stop(50%, orange) + // => rgba-stop(50%, #ffa500) \ No newline at end of file diff --git a/node_modules/jade/support/stylus/docs/comments.md b/node_modules/jade/support/stylus/docs/comments.md new file mode 100644 index 0000000..37e9be2 --- /dev/null +++ b/node_modules/jade/support/stylus/docs/comments.md @@ -0,0 +1,17 @@ + +## Comments + + Stylus supports two kinds of comments, single-line, and multi-line comments, using the same syntax found in JavaScript. + + + // I'm a comment! + body + padding 5px // some awesome padding + + + /* + * Adds the given numbers together. + */ + + add(a, b) + a + b \ No newline at end of file diff --git a/node_modules/jade/support/stylus/docs/compare.md b/node_modules/jade/support/stylus/docs/compare.md new file mode 100644 index 0000000..e823b3d --- /dev/null +++ b/node_modules/jade/support/stylus/docs/compare.md @@ -0,0 +1,81 @@ + +## Implementation Comparisons + +Below we go head to head with other implementations. + +### Variables + +SCSS: + + $main-color: #006; + color: $main-color; + +Less: + + @main-color: #006; + color: @main-color; + +Stylus: + + main-color = #006 + color main-color + +### Mixins + +SCSS: + + @mixin pad($x, $y) { + padding: $y $x; + } + + .msg { + @include pad(5px, 10px); + } + +Less: + + .pad(@x, @y) { + padding: @y @x; + } + + .msg { + .pad(5px, 10px); + } + +Stylus: + + pad(x, y) + padding y x + + .msg + pad(5px, 10px) + +### Larger Example + +Less: + + .box-shadow (@x: 0, @y: 0, @blur: 1px, @alpha) { + @val: @x @y @blur rgba(0, 0, 0, @alpha); + box-shadow: @val; + -webkit-box-shadow: @val; + -moz-box-shadow: @val; + } + .box { + @base: #f938ab; + color: saturate(@base, 5%); + border-color: lighten(@base, 30%); + div { .box-shadow(0, 0, 5px, 0.4) } + } + +Stylus: + box-shadow() + -webkit-box-shadow arguments + -moz-box-shadow arguments + box-shadow arguments + + .box + base = #f938ab + color saturate(base, 5%) + border-color lighten(base, 30%) + div + box-shadow 0 0 5px 0.4 \ No newline at end of file diff --git a/node_modules/jade/support/stylus/docs/conditionals.md b/node_modules/jade/support/stylus/docs/conditionals.md new file mode 100644 index 0000000..8d6d322 --- /dev/null +++ b/node_modules/jade/support/stylus/docs/conditionals.md @@ -0,0 +1,107 @@ + +## Conditionals + + Conditionals provide control flow to a language which is otherwise static, providing conditional imports, mixins, functions, and more. The examples below are simply examples, and not recommended :) + +### if / else if / else + + The `if` conditional works as you would expect, simply accepting an expression, evaluating the following block when `true`. Along with `if` are the typical `else if` and `else` tokens, acting as fallbacks. + + The example below would conditionally overload the `padding` property, swapping it for margin. + + overload-padding = true + + if overload-padding + padding(y, x) + margin y x + + body + padding 5px 10px + +Another example: + + box(x, y, margin = false) + padding y x + if margin + margin y x + + body + box(5px, 10px, true) + +Another `box()` helper: + + box(x, y, margin-only = false) + if margin-only + margin y x + else + padding y x + +### unless + + For users familiar with the ruby programming language, we have the `unless` conditional, which is essentially the opposite of `if`, essentially `if (!(expr))`. + +In the example below, if `disable-padding-override` is undefined or `false` padding will be overridden, displaying `margin` instead. However when `true` padding will remain outputting `padding 5px 10px` as expected. + + disable-padding-override = true + + unless disable-padding-override is defined and disable-padding-override + padding(x, y) + margin y x + + body + padding 5px 10px + +### Postfix Conditionals + + Stylus supports postfix conditionals, meaning the `if` and `unless` act as operators, evaluating the left-hand operand, when the right-hand expression is truthy. + + + For example let's define `negative()`, performing some basic type checking. Below we use block-style conditionals: + + negative(n) + unless n is a 'unit' + error('invalid number') + if n < 0 + yes + else + no + + Next we utilize postfix conditionals to keep our function terse. + + negative(n) + error('invalid number') unless n is a 'unit' + return yes if n < 0 + no + + Of course we could take this further, and utilize `n < 0 ? yes : no`, or simply stick with booleans, and use only `n < 0`. + + Postfix conditionals may be applied to most single-line statements, for example `@import`, `@charset`, mixins, and of course properties as shown below: + + + pad(types = margin padding, n = 5px) + padding unit(n, px) if padding in types + margin unit(n, px) if margin in types + + body + pad() + + body + pad(margin) + + body + apply-mixins = true + pad(padding, 10) if apply-mixins + +yielding: + + body { + padding: 5px; + margin: 5px; + } + body { + margin: 5px; + } + body { + padding: 10px; + } + diff --git a/node_modules/jade/support/stylus/docs/css-style.md b/node_modules/jade/support/stylus/docs/css-style.md new file mode 100644 index 0000000..3d433c4 --- /dev/null +++ b/node_modules/jade/support/stylus/docs/css-style.md @@ -0,0 +1,77 @@ + +## CSS Style + + Stylus transparently supports a regular css-style syntax, meaning you do not need to use an alternative parser, or specify that a certain file is using a specific style. + +### Example + + Below is a small style using the indented approach: + + border-radius() + -webkit-border-radius arguments + -moz-border-radius arguments + border-radius arguments + + body a + font 12px/1.4 "Lucida Grande", Arial, sans-serif + background black + color #ccc + + form input + padding 5px + border 1px solid + border-radius 5px + + Since braces, colons, and semi-colons are optional, we could write this example just as we would with normal css: + + border-radius() { + -webkit-border-radius: arguments; + -moz-border-radius: arguments; + border-radius: arguments; + } + + body a { + font: 12px/1.4 "Lucida Grande", Arial, sans-serif; + background: black; + color: #ccc; + } + + form input { + padding: 5px; + border: 1px solid; + border-radius: 5px; + } + + Since we may mix and match the two variants, the following is valid as well: + + border-radius() + -webkit-border-radius: arguments; + -moz-border-radius: arguments; + border-radius: arguments; + + body a { + font: 12px/1.4 "Lucida Grande", Arial, sans-serif; + background: black; + color: #ccc; + } + + form input + padding: 5px; + border: 1px solid; + border-radius: 5px; + + Variables, functions, mixins, and all of the other features that Stylus provides still work as expected: + + main-color = white + main-hover-color = black + + body a { + color: main-color; + &:hover { color: main-hover-color; } + } + + body a { color: main-color; &:hover { color: main-hover-color; }} + + There are currently a few exceptions to this rule, since the two styles may be mixed and matched some indentation rules still apply. So although not _every_ plain-css stylesheet will work without modification this feature still allows those who prefer css syntax may still utilize the other powerful features provided by Stylus. + + diff --git a/node_modules/jade/support/stylus/docs/error-reporting.md b/node_modules/jade/support/stylus/docs/error-reporting.md new file mode 100644 index 0000000..5b2def2 --- /dev/null +++ b/node_modules/jade/support/stylus/docs/error-reporting.md @@ -0,0 +1,50 @@ + +## Error Reporting + + Stylus has fantastic error reporting built in for syntax, parse, and evaluation errors, complete with stack traces, line numbers, and filenames. + +### Parse Error + +Parse error example: + + body + form input + == padding 5px + +yielding: + + Error: /Users/tj/Projects/stylus/testing/test.styl:4 + 3: ' form input' + 4: ' == padding 5px' + + illegal unary == + +### Evaluation Error + + This "runtime" or evaluation error is caused due to passing a string to `border-radius()` instead of the expected `Unit` by using our helper `ensure(n, 'unit')`. + + ensure(val, type) + unless val is a type + error('expected a ' + type + ', but got ' + typeof(val)) + + border-radius(n) + ensure(n, 'unit') + -webkit-border-radius n + -moz-border-radius n + border-radius n + + body + border-radius '5px' + +yielding: + + Error: /Users/tj/Projects/stylus/examples/error.styl:12 + 11: '' + 12: 'body' + 13: ' border-radius \'5px\'' + 14: '' + + expected a unit, but got string + at ensure() (/Users/tj/Projects/stylus/examples/error.styl:2) + at border-radius() (/Users/tj/Projects/stylus/examples/error.styl:5) + at "body" (/Users/tj/Projects/stylus/examples/error.styl:10) diff --git a/node_modules/jade/support/stylus/docs/escape.md b/node_modules/jade/support/stylus/docs/escape.md new file mode 100644 index 0000000..f2d7348 --- /dev/null +++ b/node_modules/jade/support/stylus/docs/escape.md @@ -0,0 +1,27 @@ + +## Escaping + + Stylus allows you to escape characters, effectively turning them into identifiers, so that they can be rendered as literals. For example: + + body + padding 1 \+ 2 + +will compile to: + + body { + padding: 1 + 2; + } + + +Not that Stylus requires that `/` is parenthesized when used in a property: + + body + font 14px/1.4 + font (14px/1.4) + +yields: + + body { + font: 14px/1.4; + font: 10px; + } \ No newline at end of file diff --git a/node_modules/jade/support/stylus/docs/executable.md b/node_modules/jade/support/stylus/docs/executable.md new file mode 100644 index 0000000..2303a6d --- /dev/null +++ b/node_modules/jade/support/stylus/docs/executable.md @@ -0,0 +1,92 @@ + +## Stylus Executable + +Stylus ships with the `stylus` executable for converting stylus to css. + + Usage: stylus [options] [command] [< in [> out]] + [file|dir ...] + + Commands: + + help Opens help info for in + your default browser. (osx only) + + Options: + + -i, --interactive Start interactive REPL + -w, --watch Watch file(s) for changes and re-compile + -o, --out Output to when passing files + -C, --css [dest] Convert css input to stylus + -c, --compress Compress css output + -d, --compare Display input along with output + -V, --version Display the version of stylus + -h, --help Display help information + +### STDIO Compilation Example + + `stylus` reads from _stdin_ and outputs to _stdout_, so for example: + + $ stylus --compress < some.styl > some.css + +Try stylus some in the terminal, type below and press CTRL-D for __EOF__: + + $ stylus + body + color red + font 14px Arial, sans-serif + +### Compiling Files Example + + `stylus` also accepts files and directories, for example a directory named `css` will compile and output the `.css` files in the same directory. + + $ stylus css + + The following will output to `./public/stylesheets`: + + $ stylus css --out public/stylesheets + + Or a few files: + + $ stylus one.styl two.styl + +### Converting CSS + + If we wish to convert css to the terse Stylus syntax, we can utilize the `--css` flag. + + Via stdio: + + $ stylus --css < test.css > test.styl + + Output a `.styl` file of the same basename: + + $ stylus --css test.css + + Output to a specific destination: + + $ stylus --css test.css /tmp/out.styl + +### CSS Property Help + + On osx `stylus help ` will open your default browser and display help documentation for the given ``. + + $ stylus help box-shadow + +### Interactive Shell + + The Stylus REPL (Read-Eval-Print-Loop) or "interactive shell" allows you to + play around with Stylus expressions directly from your terminal. Note that this works only for expressions, not selectors etc. To use simple add the `-i`, or `--interactive` flag: + + $ stylus -i + > color = white + => #fff + > color - rgb(200,50,0) + => #37cdff + > color + => #fff + > color -= rgb(200,50,0) + => #37cdff + > color + => #37cdff + > rgba(color, 0.5) + => rgba(55,205,255,0.5) + \ No newline at end of file diff --git a/node_modules/jade/support/stylus/docs/font-face.md b/node_modules/jade/support/stylus/docs/font-face.md new file mode 100644 index 0000000..408b491 --- /dev/null +++ b/node_modules/jade/support/stylus/docs/font-face.md @@ -0,0 +1,26 @@ + +## @font-face + + The `@font-face` at-rule expects as you would expect, simply followed by a block of properties: + + + @font-face + font-family Geo + font-style normal + src url(fonts/geo_sans_light/GensansLight.ttf) + + .ingeo + font-family Geo + +yielding: + + + @font-face { + font-family: Geo; + font-style: normal; + src: url("fonts/geo_sans_light/GensansLight.ttf"); + } + .ingeo { + font-family: Geo; + } + diff --git a/node_modules/jade/support/stylus/docs/functions.md b/node_modules/jade/support/stylus/docs/functions.md new file mode 100644 index 0000000..d762104 --- /dev/null +++ b/node_modules/jade/support/stylus/docs/functions.md @@ -0,0 +1,192 @@ + +## Functions + + Stylus features powerful in-language function definition. Function definition appears identical to mixins, however functions may return a value. + +### Return Values + + Let's try a trivial example, creating a function that adds two numbers. + + add(a, b) + a + b + + We may then utilize this function in conditions, as property values, etc. + + body + padding add(10px, 5) + + Rendering + + body { + padding: 15px; + } + +### Argument Defaults + + Optional arguments may default to a given expression. With Stylus we may even default arguments to leading arguments! For example: + + + add(a, b = a) + a + b + + add(10, 5) + // => 15 + + add(10) + // => 20 + +note that since argument defaults are assignments, we can also utilize function calls for defaults: + + add(a, b = unit(a, px)) + a + b + +### Function Bodies + + We can take our simple `add()` function further, by casting all units passed as `px` via the `unit()` built-in. Re-assigning each argument and providing a unit type string (or identifier), which disregards unit conversion. + + add(a, b = a) + a = unit(a, px) + b = unit(b, px) + a + b + + add(15%, 10deg) + // => 25 + +### Multiple Return Values + + Stylus functions can return several values, just as you can assign several values to a variable. For example the following is a valid assignment: + + sizes = 15px 10px + + sizes[0] + // => 15px + +Similarly we may return several values: + + sizes() + 15px 10px + + sizes()[0] + // => 15px + +One slight exception is when return values are identifiers, for example the following looks like a property assignment to Stylus since no operators are present. + + swap(a, b) + b a + +To disambiguate we may either wrap in parens, or utilize the `return` keyword. + + swap(a, b) + (b a) + + swap(a, b) + return b a + +### Conditionals + + Let's say we want to create a function named `stringish()` to see if the value given can be transformed to a string. We check if `val` is a string, or an ident which is string-like. Because undefined identifiers yield themselves as the value, we may compare them to them-selves as shown below, where `yes` and `no` are used in place of `true` and `false`. + + + stringish(val) + if val is a 'string' or val is a 'ident' + yes + else + no + +usage: + + stringish('yay') == yes + // => true + + stringish(yay) == yes + // => true + + stringish(0) == no + // => true + +__note__: `yes` and `no` are not boolean literals, they are simply undefined identifiers in this case. + +Another example: + + + compare(a, b) + if a > b + higher + else if a < b + lower + else + equal + +usage: + + compare(5, 2) + // => higher + + compare(1, 5) + // => lower + + compare(10, 10) + // => equal + +### Aliasing + + To alias a function we can simply assign a function's name to a new identifier. For example our previous `add()` function could be exposed as `plus()` as well, simply by: + + plus = add + + plus(1, 2) + // => 3 + +### Variable Functions + + In the same way that we can "alias" a function, we can pass a function as well, here our `invoke()` function accepts a function, so we can pass it `add()` or `sub()`. + + invoke(a, b, fn) + fn(a, b) + + add(a, b) + a + b + + body + padding invoke(5, 10, add) + padding invoke(5, 10, sub) + +yielding: + + body { + padding: 15; + padding: -5; + } + +### arguments + + The `arguments` local is available to all function bodies, and contains all the arguments passed. For example: + + sum() + n = 0 + for num in arguments + n = n + num + + sum(1,2,3,4,5) + // => 15 + +### Hash Example + + Below we define the `get(hash, key)` function, which will return the + value of `key`, or `null`. We iterate each `pair` in `hash`, returning the pair's second node when the first (the `key`) matches. + + get(hash, key) + return pair[1] if pair[0] == key for pair in hash + +As you can see below, in-language functions paired with robust stylus expressions can provide great flexibility. + + hash = (one 1) (two 2) (three 3) + + get(hash, two) + // => 2 + + get(hash, three) + // => 3 + + get(hash, something) + // => null diff --git a/node_modules/jade/support/stylus/docs/functions.url.md b/node_modules/jade/support/stylus/docs/functions.url.md new file mode 100644 index 0000000..693bbaa --- /dev/null +++ b/node_modules/jade/support/stylus/docs/functions.url.md @@ -0,0 +1,30 @@ +## Data URI Image Inlining + +Stylus is bundled with an optional function named `url()`, which replaces the literal `url()` calls, and conditionally inlines them using base64 [Data URIs](http://en.wikipedia.org/wiki/Data_URI_scheme). + +### Example + +The function itself is available via `require('stylus').url`, and accepts an options object, returning a function that Stylus calls internally when it sees `url()`. + +The `.define(name, callback)` method assigned a JavaScript function that can be called from stylus source. In this case we have our images in `./css/images` then we can ignore the `paths` option, since image lookups are performed relative to the file being rendered (by default), we may alter this with the option. + + stylus(str) + .set('filename', __dirname + '/css/test.styl') + .define('url', stylus.url()) + .render(function(err, css){ + + }); + +For example if our images live in `./public/images` and we wish to use `url(images/tobi.png)`, we can pass `paths` with our public directory, which will become part of the lookup process. Like-wise if we wanted `url(tobi.png)` instead, we would pass `paths: [__dirname + '/public/images']`. + + stylus(str) + .set('filename', __dirname + '/css/test.styl') + .define('url', stylus.url({ paths: [__dirname + '/public'] })) + .render(function(err, css){ + + }); + +### Options + + - `limit` bytesize limit defaulting to 30Kb (30000) + - `paths` image resolution path(s) \ No newline at end of file diff --git a/node_modules/jade/support/stylus/docs/import.md b/node_modules/jade/support/stylus/docs/import.md new file mode 100644 index 0000000..1db388a --- /dev/null +++ b/node_modules/jade/support/stylus/docs/import.md @@ -0,0 +1,73 @@ + +## Import + + Stylus supports both literal __@import__ for CSS, as well as dynamic importing of other Stylus sheets. + +### Literal CSS + + Any filename with the extension `.css` will become a literal, for example: + + @import "reset.css" + +will render to the literal css __@import__ shown below: + + @import "reset.css" + +### Stylus Import + + When using __@import__ without the `.css` extension, it is assumed to be a Stylus sheet, for example `@import "mixins/border-radius"`. + + __@import__ works by iterating an array of directories, and seeing if this file lives in any of them, similar to node's `require.paths`. This array defaults to a single path which is derived from the `filename` option's dirname. So if your filename is `/tmp/testing/stylus/main.styl`, then import will look in `/tmp/testing/stylus/`. + + __@import__ also supports index styles, meaning if you `@import blueprint`, it will resolve either `blueprint.styl` or `blueprint/index.styl`, useful for libraries to expose all of their features, but still allow a subset of the library to be imported. For example a common lib structure might be: + + ./tablet + |-- index.styl + |-- vendor.styl + |-- buttons.styl + |-- images.styl + + In the example below we set the `paths` options to provide additional paths to Stylus. Within `./test.styl` we could then `@import "mixins/border-radius"` or `@import "border-radius"` since `./mixins` is exposed to Stylus. + + /** + * Module dependencies. + */ + + var stylus = require('../') + , str = require('fs').readFileSync(__dirname + '/test.styl', 'utf8'); + + var paths = [ + __dirname + , __dirname + '/mixins' + ]; + + stylus(str) + .set('filename', __dirname + '/test.styl') + .set('paths', paths) + .render(function(err, css){ + if (err) throw err; + console.log(css); + }); + +### JavaScript Import API + + When using the `.import(path)` method, these imports are deferred until evaluation: + + var stylus = require('../') + , str = require('fs').readFileSync(__dirname + '/test.styl', 'utf8'); + + stylus(str) + .set('filename', __dirname + '/test.styl') + .import('mixins/vendor') + .render(function(err, css){ + if (err) throw err; + console.log(css); + }); + + The following are essentially equivalent: + + @import 'mixins/vendor' + +and + .import('mixins/vendor') + \ No newline at end of file diff --git a/node_modules/jade/support/stylus/docs/interpolation.md b/node_modules/jade/support/stylus/docs/interpolation.md new file mode 100644 index 0000000..c59bd9b --- /dev/null +++ b/node_modules/jade/support/stylus/docs/interpolation.md @@ -0,0 +1,43 @@ + +## Interpolation + + Stylus supports interpolation by using the `{}` characters to surround an expression, which then becomes part of the identifier. For example `-webkit-{'border' + '-radius'}` would evaluate to `-webkit-border-radius`. + + A great example use-case for this is expanding properties with vendor prefixes. + + vendor(prop, args) + -webkit-{prop} args + -moz-{prop} args + {prop} args + + border-radius() + vendor('border-radius', arguments) + + box-shadow() + vendor('box-shadow', arguments) + + button + border-radius 1px 2px / 3px 4px + +yielding: + + button { + -webkit-border-radius: 1px 2px / 3px 4px; + -moz-border-radius: 1px 2px / 3px 4px; + border-radius: 1px 2px / 3px 4px; + } + +## Property Hacks + +Interpolation can be used for property hacks as well, since all string values +within the delimiters are transformed to literals. For example: + + body + {'*foo-bar'} baz + +yields: + + body { + *foo-bar: baz; + } + \ No newline at end of file diff --git a/node_modules/jade/support/stylus/docs/introspection.md b/node_modules/jade/support/stylus/docs/introspection.md new file mode 100644 index 0000000..06d7c49 --- /dev/null +++ b/node_modules/jade/support/stylus/docs/introspection.md @@ -0,0 +1,39 @@ + +## Introspection API + + Stylus supports an introspection API, allowing mixins and functions to reflect relative to the caller etc. + + +## mixin + + The `mixin` local variable is automatically assigned within function bodies, + containing the string "root" indicating the function is called at the root + level, or "block" indicating otherwise, and finally `false` if the function + is invoked expecting a return value. + + In the following example we define `reset()` altering its behaviour when mixed in to root, another block, or a return value as used in the `foo` property below. + + reset() + if mixin == 'root' + got + root true + else if mixin + got 'a mixin' + else + 'not a mixin' + + reset() + + body + reset() + foo reset() + +compiles to: + + got { + root: true; + } + body { + foo: "not a mixin"; + got: "a mixin"; + } diff --git a/node_modules/jade/support/stylus/docs/iteration.md b/node_modules/jade/support/stylus/docs/iteration.md new file mode 100644 index 0000000..b309840 --- /dev/null +++ b/node_modules/jade/support/stylus/docs/iteration.md @@ -0,0 +1,100 @@ + +## Iteration + + Stylus allows you to iterate expressions via the `for/in` construct, taking the form of: + + for [, ] in + +For example: + + body + for num in 1 2 3 + foo num + +yields: + + body { + foo: 1; + foo: 2; + foo: 3; + } + +The example below shows how to use the ``: + + body + fonts = Impact Arial sans-serif + for font, i in fonts + foo i font + +yielding: + + body { + foo: 0 Impact; + foo: 1 Arial; + foo: 2 sans-serif; + } + +### Mixins + + We may utilize iteration within mixins to produce powerful functionality, for example we can apply expression pairs as properties using interpolation and iteration. Below we define `apply()`, conditionally utilizing all the `arguments` so that comma-delimited _and_ expression lists are supported: + + apply(props) + props = arguments if length(arguments) > 1 + for prop in props + {prop[0]} prop[1] + + body + apply(one 1, two 2, three 3) + + body + list = (one 1) (two 2) (three 3) + apply(list) + +### Functions + + Stylus functions may also contain for-loops, below are some example use-cases: + +sum: + + sum(nums) + sum = 0 + for n in nums + sum += n + + sum(1 2 3) + // => 6 + +join: + + join(delim, args) + buf = '' + for arg, index in args + if index + buf += delim + arg + else + buf += arg + + join(', ', foo bar baz) + // => "foo, bar, baz" + +### Postfix + + Much like `if` / `unless` may be utilized post-statement, the same can be done with `for`. Below are the same examples as above utilizing the postfix syntax: + + sum(nums) + sum = 0 + sum += n for n in nums + + + join(delim, args) + buf = '' + buf += i ? delim + arg : arg for arg, i in args + + We can also __return__ from within a loop, below is an example returning the + number when `n % 2 == 0` evaluates to __true__. + + first-even(nums) + return n if n % 2 == 0 for n in nums + + first-even(1 3 5 5 6 3 2) + // => 6 \ No newline at end of file diff --git a/node_modules/jade/support/stylus/docs/js.md b/node_modules/jade/support/stylus/docs/js.md new file mode 100644 index 0000000..2bcacaf --- /dev/null +++ b/node_modules/jade/support/stylus/docs/js.md @@ -0,0 +1,108 @@ +## JavaScript API + +Simply require the module, and call `render()` with the given string of stylus code, and (optional) options object. Frameworks utilizing stylus should pass the `filename` option to provide better error reporting. + + var stylus = require('stylus'); + + stylus.render(str, { filename: 'nesting.css' }, function(err, css){ + if (err) throw err; + console.log(css); + }); + +We can also do the same thing in a more progressive manner: + + var stylus = require('stylus'); + + stylus(str) + .set('filename', 'nesting.css') + .render(function(err, css){ + // logic + }); + +### .set(setting, value) + + Apply a setting such as a `filename`, or import `paths`: + + .set('filename', __dirname + '/test.styl') + .set('paths', [__dirname, __dirname + '/mixins']) + +### .import(path) + +Defer importing of the given `path` until evaluation is performed. The example below is essentially the same as doing `@import 'mixins/vendor'` within your Stylus sheet. + + var stylus = require('../') + , str = require('fs').readFileSync(__dirname + '/test.styl', 'utf8'); + + stylus(str) + .set('filename', __dirname + '/test.styl') + .import('mixins/vendor') + .render(function(err, css){ + if (err) throw err; + console.log(css); + }); + +### .define(name, fn) + + This method allows you to provide a JavaScript-defined function to Stylus, think of these as you would JavaScript to C++ bindings. When you have something you cannot do within Stylus, you define it in JavaScript. + +In our example we define four functions `add()`, `sub()`, `image-width()`, and `image-height()`. These functions must return a `Node`, this constructor and the other nodes are available via `stylus.nodes`. + + var stylus = require('../') + , nodes = stylus.nodes + , utils = stylus.utils + , fs = require('fs'); + + function add(a, b) { + return a.operate('+', b); + } + + function sub(a, b) { + return a.operate('-', b); + } + + function imageDimensions(img) { + // assert that the node (img) is a String node, passing + // the param name for error reporting + utils.assertType(img, nodes.String, 'img'); + var path = img.val; + + // Grab bytes necessary to retrieve dimensions. + // if this was real you would do this per format, + // instead of reading the entire image :) + var data = fs.readFileSync(__dirname + '/' + path); + + // GIF + // of course you would support.. more :) + if ('GIF' == data.slice(0, 3).toString()) { + var w = data.slice(6, 8) + , h = data.slice(8, 10); + w = w[1] << 8 | w[0]; + h = h[1] << 8 | h[0]; + } + + return [w, h]; + } + + function imageWidth(img) { + return new nodes.Unit(imageDimensions(img)[0]); + } + + function imageHeight(img) { + return new nodes.Unit(imageDimensions(img)[1]); + } + + stylus(str) + .set('filename', 'js-functions.styl') + .define('add', add) + .define('sub', sub) + .define('image-width', imageWidth) + .define('image-height', imageHeight) + .render(function(err, css){ + if (err) throw err; + console.log(css); + }); + + For further reference until documentation is complete please reference the following files: + + - lib/nodes/* + - lib/utils.js \ No newline at end of file diff --git a/node_modules/jade/support/stylus/docs/keyframes.md b/node_modules/jade/support/stylus/docs/keyframes.md new file mode 100644 index 0000000..48ee6c4 --- /dev/null +++ b/node_modules/jade/support/stylus/docs/keyframes.md @@ -0,0 +1,52 @@ + +## @keyframes + + Stylus supports the `@keyframes` at-rule, which is converted to `@-webkit-keyframes` when compiled: + + + @keyframes pulse + 0% + background-color red + opacity 1.0 + -webkit-transform scale(1.0) rotate(0deg) + 33% + background-color blue + opacity 0.75 + -webkit-transform scale(1.1) rotate(-5deg) + 67% + background-color green + opacity 0.5 + -webkit-transform scale(1.1) rotate(5deg) + 100% + background-color red + opacity 1.0 + -webkit-transform scale(1.0) rotate(0deg) + +yielding: + + @-webkit-keyframes pulse { + 0% { + background-color: red; + opacity: 1; + -webkit-transform: scale(1) rotate(0deg); + } + + 33% { + background-color: blue; + opacity: 0.75; + -webkit-transform: scale(1.1) rotate(-5deg); + } + + 67% { + background-color: green; + opacity: 0.5; + -webkit-transform: scale(1.1) rotate(5deg); + } + + 100% { + background-color: red; + opacity: 1; + -webkit-transform: scale(1) rotate(0deg); + } + + } diff --git a/node_modules/jade/support/stylus/docs/literal.md b/node_modules/jade/support/stylus/docs/literal.md new file mode 100644 index 0000000..52f84c7 --- /dev/null +++ b/node_modules/jade/support/stylus/docs/literal.md @@ -0,0 +1,16 @@ +## Literal CSS + + If for any reason Stylus cannot accommodate a specific need, you can always resort to literal css via `@css`: + + + @css { + body { + font: 14px; + } + } + +compiling to: + + body { + font: 14px; + } \ No newline at end of file diff --git a/node_modules/jade/support/stylus/docs/media.md b/node_modules/jade/support/stylus/docs/media.md new file mode 100644 index 0000000..5603c4f --- /dev/null +++ b/node_modules/jade/support/stylus/docs/media.md @@ -0,0 +1,18 @@ + +## @media + + The `@media` works just as it does within regular css, however with Stylus block notation: + + @media print + #header + #footer + display none + +yielding: + + @media print { + #header, + #footer { + display: none; + } + } diff --git a/node_modules/jade/support/stylus/docs/middleware.md b/node_modules/jade/support/stylus/docs/middleware.md new file mode 100644 index 0000000..1aa414e --- /dev/null +++ b/node_modules/jade/support/stylus/docs/middleware.md @@ -0,0 +1,55 @@ + +## Connect Middleware + + Stylus ships with Connect middleware for auto-compiling Stylus sheets when modified. + +## stylus.middleware(options) + + Return Connect middleware with the given `options`. + +#### Options + + `force` When __true__ styles will always re-compile + `src` Source directory used to find .styl files + `dest` Destination directory used to output .css files + when undefined defaults to `src`. + `compress` Whether the output .css files should be compressed + `compile` Custom compile function, accepting the arguments + `(str, path)` returning the renderer. + +#### Examples + + Here we set up the custom compile function so that we may + alter the renderer by providing additional settings. + + By default the compile function simply sets the `filename` + and renders the CSS. + + function compile(str, path) { + return stylus(str) + .import(__dirname + '/css/mixins/blueprint') + .import(__dirname + '/css/mixins/css3') + .set('filename', path) + .set('warn', true) + .set('compress', true); + } + + Pass the middleware to Connect, grabbing .styl files from this directory + and saving .css files to _./public_. Also supplying our custom `compile` function. + + Following that we have a `staticProvider` layer setup to serve the .css + files generated by Stylus. + + var stylus = require('stylus'); + + var server = connect.createServer( + stylus.middleware({ + src: __dirname + , dest: __dirname + '/public' + , compile: compile + }) + , connect.staticProvider(__dirname + '/public') + ); + + When `force` is used, the styles will be unconditionally re-compiled, however + even without this option the Stylus middleware is smart enough to detect changes in `@import`ed files. \ No newline at end of file diff --git a/node_modules/jade/support/stylus/docs/mixins.md b/node_modules/jade/support/stylus/docs/mixins.md new file mode 100644 index 0000000..5ec7a73 --- /dev/null +++ b/node_modules/jade/support/stylus/docs/mixins.md @@ -0,0 +1,132 @@ + +## Mixins + +Both mixins and functions are defined in the same manor, however they are applied in different ways. For example we have a `border-radius(n)` function defined below, which is invoked as a _mixin_, aka a statement rather than part of an expression. + +When `border-radius()` is invoked within a selector, the properties are expanded and copied into the selector. + + border-radius(n) + -webkit-border-radius n + -moz-border-radius n + border-radius n + + form input[type=button] + border-radius(5px) + +compiles to: + + form input[type=button] { + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + border-radius: 5px; + } + +When utilizing mixins, we can omit the parens all together, providing is with fantastic transparent vendor property support: + + border-radius(n) + -webkit-border-radius n + -moz-border-radius n + border-radius n + + form input[type=button] + border-radius 5px + +Note that the `border-radius` within our mixin is treated as a property, and not a recursive function invocation. To take this further we we may utilize the automatic `arguments` local variable, containing the expression passed, allowing more than one value to be passed: + + border-radius() + -webkit-border-radius arguments + -moz-border-radius arguments + border-radius arguments + +now allowing us to pass values such as `border-radius 1px 2px / 3px 4px`. + +Another great example of this, is adding transparent support for vendor specifics such as `opacity` support for IE: + + support-for-ie ?= true + + opacity(n) + opacity n + if support-for-ie + filter unquote('progid:DXImageTransform.Microsoft.Alpha(Opacity=' + round(n * 100) + ')') + + #logo + &:hover + opacity 0.5 + +rendering: + + #logo:hover { + opacity: 0.5; + filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=50); + } + +### Parent References + + Mixins may utilize the parent reference character `&`, acting on the parent instead of further nesting. For example lets say we wish to create a `stripe(even, odd)` mixin for striping table row, we provide both `even` and `odd` with default color values, and assign the `background-color` property on the row. Nested within the `tr` we use `&` to reference the `tr`, providing the `even` color. + + stripe(even = #fff, odd = #eee) + tr + background-color odd + &.even + &:nth-child(even) + background-color even + +We may then utilize the mixin as shown below: + + table + stripe() + td + padding 4px 10px + + table#users + stripe(#303030, #494848) + td + color white + +Another way to define the `stripe()` mixin without parent reference: + + stripe(even = #fff, odd = #eee) + tr + background-color odd + tr.even + tr:nth-child(even) + background-color even + +If we wished, we could invoke `stripe()` as if it were a property: + + stripe #fff #000 + +### Mixing Mixins in Mixins + + Mixins can of course utilize other mixins, to build up their own selector's and properties. For example, below we create `comma-list()` to inline (via `inline-list()`) and comma-separate an un-ordered list. + + + inline-list() + li + display inline + + comma-list() + inline-list() + li + &:after + content ', ' + &:last-child:after + content '' + + ul + comma-list() + +rendering: + + ul li:after { + content: ", "; + } + ul li:last-child:after { + content: ""; + } + ul li { + display: inline; + } + diff --git a/node_modules/jade/support/stylus/docs/operators.md b/node_modules/jade/support/stylus/docs/operators.md new file mode 100644 index 0000000..b2a22d2 --- /dev/null +++ b/node_modules/jade/support/stylus/docs/operators.md @@ -0,0 +1,418 @@ + +## Operator Precedence + +Below is the operator precedence table, highest to lowest: + + [] + ! ~ + - + is defined + ** * / % + + - + ... .. + <= >= < > + in + == is != is not + is a + && and || or + ?: + = ?= += -= *= /= %= + not + if unless + +## Unary Operators + +The following unary operators are available, `!`, `not`, `-`, `+`, and `~`. + + !0 + // => true + + !!0 + // => false + + !1 + // => false + + !!5px + // => true + + -5px + // => -5px + + --5px + // => 5px + + not true + // => false + + not not true + // => true + +The logical `not` operator has low precedence, therefore the following example could be replaced with + + a = 0 + b = 1 + + !a and !b + // => false + // pased as: (!a) and (!b) + +with: + + not a or b + // => false + // parsed as: not (a or b) + +## Binary Operators + +### Subscript [] + + The subscript operator allows us to grab a value in an expression via index. Parenthesized expressions may act as tuples, so for example `(15px 5px)`, `(1 2 3)`. + + Below is an example where we utilize tuples for error handling, showing the versatility of such a construct. As + + add(a, b) + if a is a 'unit' and b is a 'unit' + a + b + else + (error 'a and b must be units!') + + body + padding add(1,'5') + // => padding: error "a and b must be units"; + + padding add(1,'5')[0] + // => padding: error; + + padding add(1,'5')[0] == error + // => padding: true; + + padding add(1,'5')[1] + // => padding: "a and b must be units"; + + A more complex example, invoking the `error()` built-in function with the error message returned, when the ident (the first value) equals `error`. + + + if (val = add(1,'5'))[0] == error + error(val[1]) + +## Range .. ... + + Both the inclusive (`..`) and exclusive (`...`) range operators are provided, expanding to expressions: + + 1..5 + // => 1 2 3 4 5 + + 1...5 + // => 1 2 3 4 + +### Additive: + - + +multiplicative and additive binary operators work as expected, and type conversion is applied within unit type classes, or default to the literal value. For example if we perform `5s - 2px` we will get `3s`. + + 15px - 5px + // => 10px + + 5 - 2 + // => 3 + + 5in - 50mm + // => 3.031in + + 5s - 1000ms + // => 4s + + 20mm + 4in + // => 121.6mm + + "foo " + "bar" + // => "foo bar" + + "num " + 15 + // => "num 15" + +We can also operator on colors, and values are clamped appropriately. + + #fff - #111 + => #eee + + #111 + #fco + // => #fd1 + + #fff - rgba(255,0,0,0.3) + // => rgba(0,255,255,0.7) + + #fff / 2 + // => #808080 + + #fff / rgb(2,0,4) + // #80ff40 + +### Multiplicative: / * % + + 2000ms + (1s * 2) + // => 4ms + + 5s / 2 + // => 2.5s + + 4 % 2 + // => 0 + +When using `/` within a property value you must wrap with parens. The following for example is taken literally, to support css line-height: + + font: 14px/1.5; + +whereas the following is evaluated, dividing `14px` by `1.5`: + + font: (14px/1.5); + +this exception is _only_ required for the `/` operator. + +### Exponent: ** + +The Exponent operator: + + 2 ** 8 + // => 256 + +### Equality: == != >= <= > < + +Equality operators can be used to equate units, colors, strings, and even identifiers. This is a powerful concept, as even arbitrary identifiers such as as `wahoo` can be utilized as atoms, a function could return `yes` or `no` instead of `true` or `false` (although not advised). + + 5 == 5 + // => true + + 10 < 5 + // => true + + #fff == #fff + // => true + + true == false + // => false + + wahoo == yay + // => false + + wahoo == wahoo + // => true + + "test" == "test" + // => true + + true is true + // => true + + 'hey' is not 'bye' + // => true + + 'hey' isnt 'bye' + // => true + +Only exact values match, for example `0 == false`, and `null == false` are both `false`. + +Aliases: + + == is + != is not + != isnt + +## Truthfulness + + Nearly everything within Stylus resolves to `true`, including units with a suffix, for example even `0%`, `0px`, etc will resolve to `true`, since commonly in Stylus a mixin or function may accept such units as valid, however `0` itself is `false` in terms of arithmetic. + +`true` examples: + + 0% + 0px + 1px + -1 + -1px + hey + 'hey' + +`false` examples: + + 0 + null + false + '' + +### Logical Operators: && || and or + +Logical operators `&&` and `||` are aliased `and` / `or` which apply the same precedence. + + 5 && 3 + // => 3 + + 0 || 5 + // => 5 + + 0 && 5 + // => 0 + + #fff is a 'rgba' and 15 is a 'unit' + // => true + +### Existence Operator: in + + Checks for the existence of the _left-hand_ operand within the _right-hand_ expression. + +Simple examples: + + nums = 1 2 3 + 1 in nums + // => true + + 5 in nums + // => false + +Some undefined identifiers: + + words = foo bar baz + bar in words + // => true + + HEY in words + // => false + +Works with tuples too: + + vals = (error 'one') (error 'two') + error in vals + // => false + + (error 'one') in vals + // => true + + (error 'two') in vals + // => true + + (error 'something') in vals + // => false + +Example usage in mixin: + + pad(types = padding, n = 5px) + if padding in types + padding n + if margin in types + margin n + + body + pad() + + body + pad(margin) + + body + pad(padding margin, 10px) + +yielding: + + body { + padding: 5px; + } + body { + margin: 5px; + } + body { + padding: 10px; + margin: 10px; + } + +### Conditional Assignment: ?= + +The conditional assignment operator `?=` lets us define variables without clobbering old values (when present). This operator expands to an `is defined` binary operation within a ternary, for example the following are equivalent: + + color ?= white + color = color is defined ? color : white + +For example when using `=` we simply re-assign: + + color = white + color = black + + color + // => black + +However when using `?=` our second attempt fails since the variable is already defined: + + color = white + color ?= black + + color + // => white + +### Instance Check: is a + +Stylus provides a binary operator named `is a` used to type check. + + 15 is a 'unit' + // => true + + #fff is a 'rgba' + // => true + + 15 is a 'rgba' + // => false + +Alternatively we could use the `type()` BIF: + + type(#fff) == 'rgba' + // => true + +'color' is the one special-case, evaluating to true when the +left-hand operand is an `RGBA` or `HSLA` node. + +### Variable Definition: is defined + +This pseudo binary operator does not accept a right-hand operator, and does _not_ evaluate the left. This allows us to check if a variable has a value assigned to it. + + foo is defined + // => false + + foo = 15px + foo is defined + // => true + + #fff is defined + // => 'invalid "is defined" check on non-variable #fff' + +Alternatively one can use the `lookup(name)` built-in function to do this, or to perform dynamic lookups: + + name = 'blue' + lookup('light-' + name) + // => null + + light-blue = #80e2e9 + lookup('light-' + name) + // => #80e2e9 + +This operator is essential, as an undefined identifier is still a truthy value. For example: + + body + if ohnoes + padding 5px + +_will_ yield the following css when undefined: + + body { + padding: 5px; + } + +however this will be safe: + + body + if ohnoes is defined + padding 5px + +## Ternary + +The ternary operator works as we would expect in most languages, being the only operator with three operands, the _condition_ expression, the _truth_ expression and the _false_ expression. + + num = 15 + num ? unit(num, 'px') : 20px + // => 15px + + diff --git a/node_modules/jade/support/stylus/docs/selectors.md b/node_modules/jade/support/stylus/docs/selectors.md new file mode 100644 index 0000000..4afb073 --- /dev/null +++ b/node_modules/jade/support/stylus/docs/selectors.md @@ -0,0 +1,132 @@ + +## Selectors + +### Indentation + +Stylus is "pythonic" aka indentation-based. Whitespace is significant, so we substitute { and } with an _indent_, and an _outdent_ as shown below: + + body + color white + +which compiles to: + + body { + color: #fff; + } + +Optionally if preferred we may utilize colons to separate properties and their values: + + body + color: white + +### Rule Sets + +Stylus, just like css allows you to define properties for several selectors at once through comma separation. + + textarea, input + border 1px solid #eee + +The same can be done with a newline: + + textarea + input + border 1px solid #eee + +both compiling to: + + textarea, + input { + border: 1px solid #eee; + } + +The one exception to this rule, are selectors that look like properties, for example `foo bar baz` in the following may be a property, or a selector: + + foo bar baz + > input + border 1px solid + +so for this reason, or if simply preferred we may trail with a comma: + + foo bar baz, + form input, + > a + border 1px solid + +### Parent Reference + +The `&` character references the parent selector(s). In the example below our two selectors `textarea`, and `input` both alter the `color` on the `:hover` pseudo selector. + + textarea + input + color #A7A7A7 + &:hover + color #000 + +compiles to: + + textarea, + input { + color: #a7a7a7; + } + textarea:hover, + input:hover { + color: #000; + } + +below is an example providing a simple `2px` border for internet exploder utilizing the parent reference within a mixin: + + box-shadow() + -webkit-box-shadow arguments + -moz-box-shadow arguments + box-shadow arguments + html.ie8 &, + html.ie7 &, + html.ie6 & + border 2px solid arguments[length(arguments) - 1] + + body + #login + box-shadow 1px 1px 3px #eee + +yielding: + + body #login { + -webkit-box-shadow: 1px 1px 3px #eee; + -moz-box-shadow: 1px 1px 3px #eee; + box-shadow: 1px 1px 3px #eee; + } + html.ie8 body #login, + html.ie7 body #login, + html.ie6 body #login { + border: 1px solid #eee; + } + +### Disambiguation + +Expressions such as `padding - n` could be interpreted both as a subtraction operation, as well as a property with an unary minus. To disambiguate we can wrap the expression with parens: + + pad(n) + padding (- n) + + body + pad(5px) + +compiles to: + + body { + padding: -5px; + } + +however this is only true in functions, since functions act both as mixins, or calls with return values. For example this is fine, and will yield the same results as above: + + body + padding -5px + +Have weird property values that Stylus cannot process? `unquote()` can help you out: + + filter unquote('progid:DXImageTransform.Microsoft.BasicImage(rotation=1)') + +yields: + + filter progid:DXImageTransform.Microsoft.BasicImage(rotation=1) + \ No newline at end of file diff --git a/node_modules/jade/support/stylus/docs/textmate.md b/node_modules/jade/support/stylus/docs/textmate.md new file mode 100644 index 0000000..b29e148 --- /dev/null +++ b/node_modules/jade/support/stylus/docs/textmate.md @@ -0,0 +1,7 @@ + +## TextMate Bundle + + Stylus ships with a TextMate bundle, located within `./editors`. To install simply execute `make install-bundle`, or place `./editors/Stylus.tmbundle` in the appropriate location. + + + ![Stylus TextMate Bundle](http://cl.ly/4CA7) \ No newline at end of file diff --git a/node_modules/jade/support/stylus/docs/vargs.md b/node_modules/jade/support/stylus/docs/vargs.md new file mode 100644 index 0000000..fba09cb --- /dev/null +++ b/node_modules/jade/support/stylus/docs/vargs.md @@ -0,0 +1,84 @@ + +## Rest Parameters + + Stylus supports rest parameters in the form of `name...`. These params consume the remaining arguments passed to a mixin or function. This is useful for example when utilizing the implicit function call support to apply vendor prefixes like `-webkit` or `-moz`. + + +In the example below we consume all the arguments passed and simply apply them to multiple properties. + + box-shadow(args...) + -webkit-box-shadow args + -moz-box-shadow args + box-shadow args + + #login + box-shadow 1px 2px 5px #eee + +yielding: + + #login { + -webkit-box-shadow: 1px 2px 5px #eee; + -moz-box-shadow: 1px 2px 5px #eee; + box-shadow: 1px 2px 5px #eee; + } + +If we wanted to peek at a specific argument, for example the x-offset we could simply use `args[0]`, or for example we may wish to re-define the mixin: + + box-shadow(offset-x, args...) + got-offset-x offset-x + -webkit-box-shadow offset-x args + -moz-box-shadow offset-x args + box-shadow offset-x args + + #login + box-shadow 1px 2px 5px #eee + +yielding: + + #login { + got-offset-x: 1px; + -webkit-box-shadow: 1px 2px 5px #eee; + -moz-box-shadow: 1px 2px 5px #eee; + box-shadow: 1px 2px 5px #eee; + } + +### arguments + + The `arguments` variable is injected into mixin and function bodies, containing the exact expression passed. This is useful for several reasons, primarily for vendor support, as you get the _exact_ expression, commas and all. + + For example, if we use a rest param, the comma is simply consumed since it is an expression delimiter: + + box-shadow(args...) + -webkit-box-shadow args + -moz-box-shadow args + box-shadow args + + #login + box-shadow #ddd 1px 1px, #eee 2px 2px + +yielding slightly unexpected results: + + #login { + -webkit-box-shadow: #ddd 1px 1px #eee 2px 2px; + -moz-box-shadow: #ddd 1px 1px #eee 2px 2px; + box-shadow: #ddd 1px 1px #eee 2px 2px; + } + +Let's redefine the mixin using `arguments`: + + box-shadow() + -webkit-box-shadow arguments + -moz-box-shadow arguments + box-shadow arguments + + body + box-shadow #ddd 1px 1px, #eee 2px 2px + +now yielding the desired result: + + body { + -webkit-box-shadow: #ddd 1px 1px, #eee 2px 2px; + -moz-box-shadow: #ddd 1px 1px, #eee 2px 2px; + box-shadow: #ddd 1px 1px, #eee 2px 2px; + } + diff --git a/node_modules/jade/support/stylus/docs/variables.md b/node_modules/jade/support/stylus/docs/variables.md new file mode 100644 index 0000000..28d595f --- /dev/null +++ b/node_modules/jade/support/stylus/docs/variables.md @@ -0,0 +1,29 @@ + +## Variables + +We may assign expressions to variables and use them throughout our stylesheet: + + font-size = 14px + + body + font font-size Arial, sans-serif + +compiles to: + + body { + font: 14px Arial, sans-serif; + } + +Variables can even consist of an expression list: + + font-size = 14px + font = font-size "Lucida Grande", Arial + + body + font font sans-serif + +compiles to: + + body { + font: 14px "Lucida Grande", Arial sans-serif; + } \ No newline at end of file diff --git a/node_modules/jade/support/stylus/editors/Stylus.tmbundle/Syntaxes/Stylus.tmLanguage b/node_modules/jade/support/stylus/editors/Stylus.tmbundle/Syntaxes/Stylus.tmLanguage new file mode 100644 index 0000000..749ee49 --- /dev/null +++ b/node_modules/jade/support/stylus/editors/Stylus.tmbundle/Syntaxes/Stylus.tmLanguage @@ -0,0 +1,166 @@ + + + + + fileTypes + + styl + stylus + + name + Stylus + patterns + + + match + ^ *(&|) + name + variable.language.stylus + + + match + (arguments) + name + variable.language.stylus + + + match + @([-\w]+) + name + keyword.stylus + + + captures + + 1 + + name + punctuation.definition.entity.stylus + + + match + (\.)[a-zA-Z0-9_-]+ + name + entity.other.attribute-name.class.stylus + + + captures + + 1 + + name + punctuation.definition.entity.stylus + + + match + (:+)\b(after|before|first-child|first-letter|first-line|selection)\b + name + entity.other.attribute-name.pseudo-element.stylus + + + captures + + 1 + + name + punctuation.definition.entity.stylus + + + match + (:)\b(active|hover|link|visited|focus)\b + name + entity.other.attribute-name.pseudo-class.stylus + + + captures + + 1 + + name + punctuation.definition.entity.css + + + match + (#)[a-zA-Z][a-zA-Z0-9_-]* + name + entity.other.attribute-name.id.stylus + + + match + \b(!important|for|in|return|true|false|null|if|else|unless|return)\b + name + keyword.control.stylus + + + begin + " + end + " + name + string.quoted.double.stylus + + + begin + ' + end + ' + name + string.quoted.single.stylus + + + begin + /\* + captures + + 0 + + name + punctuation.definition.comment.js + + + end + \*/ + name + comment.block.js + + + match + (?:\b(\d+))|(#[a-fA-F0-9]+) + name + constant.numeric.stylus + + + captures + + 1 + + name + punctuation.definition.comment.stylus + + + match + (?:^[ \t]+)?(\/\/).*$\n? + name + comment.line.stylus + + + captures + + 1 + + name + entity.name.function.stylus + + + match + ([-a-zA-Z_][-\w]*)?(\() + name + meta.function.stylus + + + scopeName + source.stylus + uuid + 60519324-6A3A-4382-9E0B-546993A3869A + + diff --git a/node_modules/jade/support/stylus/editors/Stylus.tmbundle/info.plist b/node_modules/jade/support/stylus/editors/Stylus.tmbundle/info.plist new file mode 100644 index 0000000..e0e962b --- /dev/null +++ b/node_modules/jade/support/stylus/editors/Stylus.tmbundle/info.plist @@ -0,0 +1,10 @@ + + + + + name + Stylus + uuid + DD7889E4-2ACA-4DF5-838F-FC9D7AEAF3F1 + + diff --git a/node_modules/jade/support/stylus/examples/arithmetic.js b/node_modules/jade/support/stylus/examples/arithmetic.js new file mode 100644 index 0000000..9658fae --- /dev/null +++ b/node_modules/jade/support/stylus/examples/arithmetic.js @@ -0,0 +1,12 @@ + +/** + * Module dependencies. + */ + +var css = require('../') + , str = require('fs').readFileSync(__dirname + '/arithmetic.styl', 'utf8'); + +css.render(str, { filename: 'arithmetic.styl' }, function(err, css){ + if (err) throw err; + console.log(css); +}); \ No newline at end of file diff --git a/node_modules/jade/support/stylus/examples/arithmetic.styl b/node_modules/jade/support/stylus/examples/arithmetic.styl new file mode 100644 index 0000000..4c9cbd1 --- /dev/null +++ b/node_modules/jade/support/stylus/examples/arithmetic.styl @@ -0,0 +1,29 @@ + +font-families = "Lucida Grande", Arial, sans-serif +font-size = 14px +primary-color = #3a3a3a +width = 800px +pad = 20px + +body + font font-size/1.5 font-families + background white + color primary-color + +h1 + font-size font-size * (5 - 3) + color primary-color + #030303 + +h2 + color primary-color - rgba(0,0,0,0.5) + +#wrapper + width width + +.side-bar + padding pad + width (width / 3) - pad + // 6 + height 3 - - - - 3 + // 7 + height 1 + 2 * 3 \ No newline at end of file diff --git a/node_modules/jade/support/stylus/examples/basic.js b/node_modules/jade/support/stylus/examples/basic.js new file mode 100644 index 0000000..a20e5ee --- /dev/null +++ b/node_modules/jade/support/stylus/examples/basic.js @@ -0,0 +1,12 @@ + +/** + * Module dependencies. + */ + +var css = require('../') + , str = require('fs').readFileSync(__dirname + '/basic.styl', 'utf8'); + +css.render(str, { filename: 'basic.styl' }, function(err, css){ + if (err) throw err; + console.log(css); +}); \ No newline at end of file diff --git a/node_modules/jade/support/stylus/examples/basic.styl b/node_modules/jade/support/stylus/examples/basic.styl new file mode 100644 index 0000000..353ef05 --- /dev/null +++ b/node_modules/jade/support/stylus/examples/basic.styl @@ -0,0 +1,8 @@ +body a + font 12px/1.3 "Lucida Grande", Arial, sans-serif + background black + color #ccc + +form input + padding 5px + border 1px solid diff --git a/node_modules/jade/support/stylus/examples/builtins.js b/node_modules/jade/support/stylus/examples/builtins.js new file mode 100644 index 0000000..ba37808 --- /dev/null +++ b/node_modules/jade/support/stylus/examples/builtins.js @@ -0,0 +1,12 @@ + +/** + * Module dependencies. + */ + +var css = require('../') + , str = require('fs').readFileSync(__dirname + '/builtins.styl', 'utf8'); + +css.render(str, { filename: 'builtins.styl' }, function(err, css){ + if (err) throw err; + console.log(css); +}); \ No newline at end of file diff --git a/node_modules/jade/support/stylus/examples/builtins.styl b/node_modules/jade/support/stylus/examples/builtins.styl new file mode 100644 index 0000000..91e043a --- /dev/null +++ b/node_modules/jade/support/stylus/examples/builtins.styl @@ -0,0 +1,56 @@ + + +// color manipulation + +body + color darken(#eee, 50%) + color darken-by(#eee, 50%) + color #eee - rgba(100,0,0,0.5) + color rgba(#eee,.5) + +// expression node access + +body + list = (one 1) (two 2) (three 3) + foo last(list) + +// pseudo hashes + +get(hash, key) + return pair[1] if pair[0] == key for pair in hash + +body + hash = (one 1) (two 2) (three 3) + foo get(hash, two) + foo get(hash, one) + foo get(hash, none) == null + foo length(hash) + +// color components + +body + foo red(#c00) + foo lightness(#c00) + +// units + +body + foo unit(15%) + foo unit(15%, px) + foo unit(15px, '%') + +// math + +body + foo abs(-5) + foo sum(1 2 3 4) + foo avg(1 2 3 4) + +// literals + +body + foo unquote('X::MessedUp::IE.crap(here)') + +// inspection + +p(1 + 5 / 10) \ No newline at end of file diff --git a/node_modules/jade/support/stylus/examples/comments.js b/node_modules/jade/support/stylus/examples/comments.js new file mode 100644 index 0000000..f28270a --- /dev/null +++ b/node_modules/jade/support/stylus/examples/comments.js @@ -0,0 +1,11 @@ + +/** + * Module dependencies. + */ + +var css = require('../') + , str = require('fs').readFileSync(__dirname + '/comments.styl', 'utf8'); + +css.render(str, { filename: 'comments.styl' }, function(err, css){ + console.log(css); +}); \ No newline at end of file diff --git a/node_modules/jade/support/stylus/examples/comments.styl b/node_modules/jade/support/stylus/examples/comments.styl new file mode 100644 index 0000000..9f9ace4 --- /dev/null +++ b/node_modules/jade/support/stylus/examples/comments.styl @@ -0,0 +1,15 @@ + +// This is a comment +body + color white + // You can nest them as you wish + // and have more comments + // and more! + +/* +We can also use multi-line comments +like this, which are native to css +*/ + +form + /* color black */ diff --git a/node_modules/jade/support/stylus/examples/compress.js b/node_modules/jade/support/stylus/examples/compress.js new file mode 100644 index 0000000..e9b570f --- /dev/null +++ b/node_modules/jade/support/stylus/examples/compress.js @@ -0,0 +1,12 @@ + +/** + * Module dependencies. + */ + +var css = require('../') + , str = require('fs').readFileSync(__dirname + '/basic.styl', 'utf8'); + +css.render(str, { filename: 'basic.styl', compress: true }, function(err, css){ + if (err) throw err; + console.log(css); +}); \ No newline at end of file diff --git a/node_modules/jade/support/stylus/examples/conversions.js b/node_modules/jade/support/stylus/examples/conversions.js new file mode 100644 index 0000000..b48e510 --- /dev/null +++ b/node_modules/jade/support/stylus/examples/conversions.js @@ -0,0 +1,12 @@ + +/** + * Module dependencies. + */ + +var css = require('../') + , str = require('fs').readFileSync(__dirname + '/conversions.styl', 'utf8'); + +css.render(str, { filename: 'conversions.styl' }, function(err, css){ + if (err) throw err; + console.log(css); +}); \ No newline at end of file diff --git a/node_modules/jade/support/stylus/examples/conversions.styl b/node_modules/jade/support/stylus/examples/conversions.styl new file mode 100644 index 0000000..ec3488b --- /dev/null +++ b/node_modules/jade/support/stylus/examples/conversions.styl @@ -0,0 +1,34 @@ + +seconds(n) + 0s + n + +body + foo 15px - 5px + foo 15px - 5 + + // 60.8mm + foo 5cm - 2mm + foo 10mm + 2in + + // 3.54cm + foo 1cm + 1in + + // 3in + foo 5in - 5.08cm + + // 0.8s + foo 1s - 200ms + + // 3500ms + foo 1500ms + 2s + + // 3000Hz + foo 1000Hz + 2kHz + + // 1kHz + foo 3kHz - (1000Hz * 2) + + n = 30% + foo unit(n, 'px') + + foo seconds(1500ms) \ No newline at end of file diff --git a/node_modules/jade/support/stylus/examples/functions.js b/node_modules/jade/support/stylus/examples/functions.js new file mode 100644 index 0000000..db4c88a --- /dev/null +++ b/node_modules/jade/support/stylus/examples/functions.js @@ -0,0 +1,12 @@ + +/** + * Module dependencies. + */ + +var css = require('../') + , str = require('fs').readFileSync(__dirname + '/functions.styl', 'utf8'); + +css.render(str, { filename: 'functions.styl' }, function(err, css){ + if (err) throw err; + console.log(css); +}); \ No newline at end of file diff --git a/node_modules/jade/support/stylus/examples/functions.styl b/node_modules/jade/support/stylus/examples/functions.styl new file mode 100644 index 0000000..fa576fa --- /dev/null +++ b/node_modules/jade/support/stylus/examples/functions.styl @@ -0,0 +1,30 @@ + + +// ?= would allow us to define the images global before @importing +// the file if we were to distribute this + +images ?= '/images' + +image(path) + url(join('/', images path)) + +// or + +image(path) + url(images + '/' + path) + +body + background image('foo.png') + +// functions can act as both mixins +// or have a return value + +image(path) + if mixin + background image(path) + else + url(images + '/' + path) + +body + image('something.png') + background image('something.png') \ No newline at end of file diff --git a/node_modules/jade/support/stylus/examples/images.js b/node_modules/jade/support/stylus/examples/images.js new file mode 100644 index 0000000..4f5f9ed --- /dev/null +++ b/node_modules/jade/support/stylus/examples/images.js @@ -0,0 +1,20 @@ + +/** + * Module dependencies. + */ + +var stylus = require('../') + , nodes = stylus.nodes + , path = __dirname + '/images.styl' + , str = require('fs').readFileSync(path, 'utf8'); + +// the paths option is merged with the general options +// so it is completely optional, however this now allows us to use +// url(sprite.gif) instead of url(images/sprite.gif) +stylus(str) + .set('filename', path) + .define('url', stylus.url({ paths: [__dirname + '/images'] })) + .render(function(err, css){ + if (err) throw err; + console.log(css); + }); \ No newline at end of file diff --git a/node_modules/jade/support/stylus/examples/images.styl b/node_modules/jade/support/stylus/examples/images.styl new file mode 100644 index 0000000..b84b699 --- /dev/null +++ b/node_modules/jade/support/stylus/examples/images.styl @@ -0,0 +1,12 @@ + +body + background url("http://foo.com/bar.png") + +#wrapper + background url(/images/gopher.jpg) + +.sprite + // both work due to the additional paths option + // passed to stylus.url() + background url(/images/sprite.gif) + background url(sprite.gif) diff --git a/node_modules/jade/support/stylus/examples/images/gopher.jpg b/node_modules/jade/support/stylus/examples/images/gopher.jpg new file mode 100644 index 0000000000000000000000000000000000000000..9f7f12b4750a6cb0be25611389e591a0a4d5b2b5 GIT binary patch literal 50615 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 literal 0 HcmV?d00001 diff --git a/node_modules/jade/support/stylus/examples/images/sprite.gif b/node_modules/jade/support/stylus/examples/images/sprite.gif new file mode 100644 index 0000000000000000000000000000000000000000..d6b7d396156317206d172c20040ff8554bd2064d GIT binary patch literal 935 zcmV;Y16ce=Nk%w1VITk)0OkMy+q+Bj$}KLDRXU+kNQQ><^Yil1aXza|CRUQDtgKd& zb<^F{#MH*Q#oL>xq)Tj=-r?-;)|N(TrnAMgm8ZpAifQ%s_*HYQth2dSt7Bq)w2GU% z>+JIW{r+r)wjD>4a)`LX$=7M8b=u_HXpW~je0ajk;_veBGmK(*nUwzLsoCW4cZ8)V za(3eC;!$j+DRMWbwb-z|+9-Q!D}ZWaw`+`?$DpaanZ2BOlD6UEY-Qs)%f_;*v)y0z6 z(7wXIo8GuIU!`j8@b~iX`Mkiy>h1TkxX#qPZt}}YKY2#>`1_Bnhn=B`)ZFn4I*vwl zUX`4K=98I9gS6D0l@(VZW%%^4-YIGIWHT71!p={hbsWWYCaicHZMa6 z;0QxKgKY^87&|%zy@C^C0BUa)0zrCB4H`od2u>tggR~?d07XcOED6r+*pXn47dbFs z1o862LJklOmR#tPYETsn1nRWtV#Ej*0(nwYh{&eGmlp+0Y-!^`2^KsH2vu=#XGV?{ zOUg)~fdmSPBNUh@fwQH^lq5|+Y*f$*S{4*X{#-%ejRXY=Q!H@tP(X%+KQ?;&_@Dug zh@6A}TmT_5MQa=lD@^R+Lg9~uEm}4F@sOs&6A}V=Fd)Pr0}&g7KxDnJK}v`+A3Xfg z0K$X>D~@Fu=+a862ST0v|CDApi{n05O3M!%1=i5C_m8K>=pSfW-rY32*=qb`+q>A9PHB zg93QqQ347A9039i8BB1(hlQNL0EDR_fC3P3!Dz?{6ObXm9XPzGBO?p=FhPSuGBN@L Jl1T;v06X@Tu89Bu literal 0 HcmV?d00001 diff --git a/node_modules/jade/support/stylus/examples/implicit-functions.js b/node_modules/jade/support/stylus/examples/implicit-functions.js new file mode 100644 index 0000000..c2df4ea --- /dev/null +++ b/node_modules/jade/support/stylus/examples/implicit-functions.js @@ -0,0 +1,12 @@ + +/** + * Module dependencies. + */ + +var css = require('../') + , str = require('fs').readFileSync(__dirname + '/implicit-functions.styl', 'utf8'); + +css.render(str, { filename: 'implicit-functions.styl' }, function(err, css){ + if (err) throw err; + console.log(css); +}); \ No newline at end of file diff --git a/node_modules/jade/support/stylus/examples/implicit-functions.styl b/node_modules/jade/support/stylus/examples/implicit-functions.styl new file mode 100644 index 0000000..3921052 --- /dev/null +++ b/node_modules/jade/support/stylus/examples/implicit-functions.styl @@ -0,0 +1,23 @@ + +border-radius() + -webkit-border-radius arguments + -moz-border-radius arguments + border-radius arguments + +form + border-radius 5px + +a.button + border-radius 10px + + +support-for-ie ?= true + +opacity(n) + opacity n + if support-for-ie + filter unquote('progid:DXImageTransform.Microsoft.Alpha(Opacity=' + round(n * 100) + ')') + +#logo + &:hover + opacity 0.5 diff --git a/node_modules/jade/support/stylus/examples/import.js b/node_modules/jade/support/stylus/examples/import.js new file mode 100644 index 0000000..a514721 --- /dev/null +++ b/node_modules/jade/support/stylus/examples/import.js @@ -0,0 +1,12 @@ + +/** + * Module dependencies. + */ + +var css = require('../') + , str = require('fs').readFileSync(__dirname + '/import.styl', 'utf8'); + +css.render(str, { filename: __dirname + '/import.styl' }, function(err, css){ + if (err) throw err; + console.log(css); +}); \ No newline at end of file diff --git a/node_modules/jade/support/stylus/examples/import.styl b/node_modules/jade/support/stylus/examples/import.styl new file mode 100644 index 0000000..69b1d8d --- /dev/null +++ b/node_modules/jade/support/stylus/examples/import.styl @@ -0,0 +1,11 @@ + +@import "mixins/box" + +body + pad 10px 5px + +body + pad 5px + +body + pad-x 5px \ No newline at end of file diff --git a/node_modules/jade/support/stylus/examples/js-functions.js b/node_modules/jade/support/stylus/examples/js-functions.js new file mode 100644 index 0000000..9076d30 --- /dev/null +++ b/node_modules/jade/support/stylus/examples/js-functions.js @@ -0,0 +1,55 @@ + +/** + * Module dependencies. + */ + +var css = require('../') + , nodes = css.nodes + , str = require('fs').readFileSync(__dirname + '/js-functions.styl', 'utf8') + , fs = require('fs'); + +function add(a, b) { + return a.operate('+', b); +} + +function sub(a, b) { + return a.operate('-', b); +} + +function imageSize(img) { + // assert that the node (img) is a String node, passing + // the param name for error reporting + css.utils.assertType(img, nodes.String, 'img'); + var path = img.val; + + // Grab bytes necessary to retrieve dimensions. + // if this was real you would do this per format, + // instead of reading the entire image :) + var data = fs.readFileSync(__dirname + '/' + path); + + // GIF + // of course you would support.. more :) + if ('GIF' == data.slice(0, 3).toString()) { + var w = data.slice(6, 8) + , h = data.slice(8, 10); + w = w[1] << 8 | w[0]; + h = h[1] << 8 | h[0]; + } + + // Return (w h) + var expr = new nodes.Expression; + expr.push(new nodes.Unit(w)); + expr.push(new nodes.Unit(h)); + + return expr; +} + +css(str) + .set('filename', 'js-functions.styl') + .define('add', add) + .define('sub', sub) + .define('image-size', imageSize) + .render(function(err, css){ + if (err) throw err; + console.log(css); + }); \ No newline at end of file diff --git a/node_modules/jade/support/stylus/examples/js-functions.styl b/node_modules/jade/support/stylus/examples/js-functions.styl new file mode 100644 index 0000000..8460b3c --- /dev/null +++ b/node_modules/jade/support/stylus/examples/js-functions.styl @@ -0,0 +1,23 @@ + +image-width(path) + return image-size(path)[0] + +image-height(path) + return image-size(path)[1] + +body + font add(5px, 10px) + font sub(5px, 10px) + +#jesus + width image-width('images/jesus.gif') + height image-height('images/jesus.gif') + +#jesus-2 + width image-size('images/jesus.gif')[0] + height image-size('images/jesus.gif')[1] + +#jesus-3 + size = image-size('images/jesus.gif') + width size[0] + height size[1] \ No newline at end of file diff --git a/node_modules/jade/support/stylus/examples/literal.js b/node_modules/jade/support/stylus/examples/literal.js new file mode 100644 index 0000000..5b80b10 --- /dev/null +++ b/node_modules/jade/support/stylus/examples/literal.js @@ -0,0 +1,12 @@ + +/** + * Module dependencies. + */ + +var css = require('../') + , str = require('fs').readFileSync(__dirname + '/literal.styl', 'utf8'); + +css.render(str, { filename: 'literal.styl' }, function(err, css){ + if (err) throw err; + console.log(css); +}); \ No newline at end of file diff --git a/node_modules/jade/support/stylus/examples/literal.styl b/node_modules/jade/support/stylus/examples/literal.styl new file mode 100644 index 0000000..e9a45ee --- /dev/null +++ b/node_modules/jade/support/stylus/examples/literal.styl @@ -0,0 +1,8 @@ + +@css { + body { + font: 14px; + } + + a { text-decoration: none; } +} diff --git a/node_modules/jade/support/stylus/examples/middleware.js b/node_modules/jade/support/stylus/examples/middleware.js new file mode 100644 index 0000000..8a500f9 --- /dev/null +++ b/node_modules/jade/support/stylus/examples/middleware.js @@ -0,0 +1,22 @@ + +/** + * Module dependencies. + */ + +var connect = require('connect') + , stylus = require('../'); + +// Setup server +// $ curl http://localhost:3000/functions.css + +var server = connect.createServer( + stylus.middleware({ + src: __dirname + , dest: __dirname + '/public' + , compress: true + }), + connect.static(__dirname + '/public') +); + +server.listen(3000); +console.log('server listening on port 3000'); \ No newline at end of file diff --git a/node_modules/jade/support/stylus/examples/mixins/box.styl b/node_modules/jade/support/stylus/examples/mixins/box.styl new file mode 100644 index 0000000..6004d86 --- /dev/null +++ b/node_modules/jade/support/stylus/examples/mixins/box.styl @@ -0,0 +1,14 @@ + +pad(x, y = x) + if y == x + padding y + else + padding y x y x + +pad-x(n) + padding-left n + padding-right n + +pad-y(n) + padding-top n + padding-bottom n diff --git a/node_modules/jade/support/stylus/examples/nesting.js b/node_modules/jade/support/stylus/examples/nesting.js new file mode 100644 index 0000000..ef3e968 --- /dev/null +++ b/node_modules/jade/support/stylus/examples/nesting.js @@ -0,0 +1,12 @@ + +/** + * Module dependencies. + */ + +var css = require('../') + , str = require('fs').readFileSync(__dirname + '/nesting.styl', 'utf8'); + +css.render(str, { filename: 'nesting.styl' }, function(err, css){ + if (err) throw err; + console.log(css); +}); \ No newline at end of file diff --git a/node_modules/jade/support/stylus/examples/nesting.styl b/node_modules/jade/support/stylus/examples/nesting.styl new file mode 100644 index 0000000..df0206d --- /dev/null +++ b/node_modules/jade/support/stylus/examples/nesting.styl @@ -0,0 +1,14 @@ + +body + background #ccc + color #000 + +form + .buttons + margin 10px 0 + padding 5px + [type=submit] + padding 5px + border none + input + border 1px solid #ccc diff --git a/node_modules/jade/support/stylus/examples/public/.gitignore b/node_modules/jade/support/stylus/examples/public/.gitignore new file mode 100644 index 0000000..2318862 --- /dev/null +++ b/node_modules/jade/support/stylus/examples/public/.gitignore @@ -0,0 +1 @@ +*.css \ No newline at end of file diff --git a/node_modules/jade/support/stylus/examples/variables.js b/node_modules/jade/support/stylus/examples/variables.js new file mode 100644 index 0000000..cd55b88 --- /dev/null +++ b/node_modules/jade/support/stylus/examples/variables.js @@ -0,0 +1,12 @@ + +/** + * Module dependencies. + */ + +var css = require('../') + , str = require('fs').readFileSync(__dirname + '/variables.styl', 'utf8'); + +css.render(str, { filename: 'variables.styl' }, function(err, css){ + if (err) throw err; + console.log(css); +}); \ No newline at end of file diff --git a/node_modules/jade/support/stylus/examples/variables.styl b/node_modules/jade/support/stylus/examples/variables.styl new file mode 100644 index 0000000..319330c --- /dev/null +++ b/node_modules/jade/support/stylus/examples/variables.styl @@ -0,0 +1,24 @@ + +font-families = "Lucida Grande", Arial +main-width = 80% +main-color = #fff +sidebar-width = main-width / 2 + +// Mixins can use conditionals +// to supply defaults +unless font-families is defined + font-families = 'WAHOO' + +// Alternatively we may use ?= +font-families ?= 'WAHOO' + +body + size = 12px + font size font-families, sans-serif + color main-color + +#wrapper + width main-width + +.sidebar + width sidebar-width \ No newline at end of file diff --git a/node_modules/jade/support/stylus/index.js b/node_modules/jade/support/stylus/index.js new file mode 100644 index 0000000..bd486f6 --- /dev/null +++ b/node_modules/jade/support/stylus/index.js @@ -0,0 +1,2 @@ + +module.exports = require('./lib/stylus'); \ No newline at end of file diff --git a/node_modules/jade/support/stylus/lib/colors.js b/node_modules/jade/support/stylus/lib/colors.js new file mode 100644 index 0000000..9f465a2 --- /dev/null +++ b/node_modules/jade/support/stylus/lib/colors.js @@ -0,0 +1,156 @@ + +/*! + * Stylus - colors + * Copyright(c) 2010 LearnBoost + * MIT Licensed + */ + +module.exports = { + aliceblue: [240, 248, 255] + , antiquewhite: [250, 235, 215] + , aqua: [0, 255, 255] + , aquamarine: [127, 255, 212] + , azure: [240, 255, 255] + , beige: [245, 245, 220] + , bisque: [255, 228, 196] + , black: [0, 0, 0] + , blanchedalmond: [255, 235, 205] + , blue: [0, 0, 255] + , blueviolet: [138, 43, 226] + , brown: [165, 42, 42] + , burlywood: [222, 184, 135] + , cadetblue: [95, 158, 160] + , chartreuse: [127, 255, 0] + , chocolate: [210, 105, 30] + , coral: [255, 127, 80] + , cornflowerblue: [100, 149, 237] + , cornsilk: [255, 248, 220] + , crimson: [220, 20, 60] + , cyan: [0, 255, 255] + , darkblue: [0, 0, 139] + , darkcyan: [0, 139, 139] + , darkgoldenrod: [184, 132, 11] + , darkgray: [169, 169, 169] + , darkgreen: [0, 100, 0] + , darkgrey: [169, 169, 169] + , darkkhaki: [189, 183, 107] + , darkmagenta: [139, 0, 139] + , darkolivegreen: [85, 107, 47] + , darkorange: [255, 140, 0] + , darkorchid: [153, 50, 204] + , darkred: [139, 0, 0] + , darksalmon: [233, 150, 122] + , darkseagreen: [143, 188, 143] + , darkslateblue: [72, 61, 139] + , darkslategray: [47, 79, 79] + , darkslategrey: [47, 79, 79] + , darkturquoise: [0, 206, 209] + , darkviolet: [148, 0, 211] + , deeppink: [255, 20, 147] + , deepskyblue: [0, 191, 255] + , dimgray: [105, 105, 105] + , dimgrey: [105, 105, 105] + , dodgerblue: [30, 144, 255] + , firebrick: [178, 34, 34] + , floralwhite: [255, 255, 240] + , forestgreen: [34, 139, 34] + , fuchsia: [255, 0, 255] + , gainsboro: [220, 220, 220] + , ghostwhite: [248, 248, 255] + , gold: [255, 215, 0] + , goldenrod: [218, 165, 32] + , gray: [128, 128, 128] + , green: [0, 128, 0] + , greenyellow: [173, 255, 47] + , grey: [128, 128, 128] + , honeydew: [240, 255, 240] + , hotpink: [255, 105, 180] + , indianred: [205, 92, 92] + , indigo: [75, 0, 130] + , ivory: [255, 255, 240] + , khaki: [240, 230, 140] + , lavender: [230, 230, 250] + , lavenderblush: [255, 240, 245] + , lawngreen: [124, 252, 0] + , lemonchiffon: [255, 250, 205] + , lightblue: [173, 216, 230] + , lightcoral: [240, 128, 128] + , lightcyan: [224, 255, 255] + , lightgoldenrodyellow: [250, 250, 210] + , lightgray: [211, 211, 211] + , lightgreen: [144, 238, 144] + , lightgrey: [211, 211, 211] + , lightpink: [255, 182, 193] + , lightsalmon: [255, 160, 122] + , lightseagreen: [32, 178, 170] + , lightskyblue: [135, 206, 250] + , lightslategray: [119, 136, 153] + , lightslategrey: [119, 136, 153] + , lightsteelblue: [176, 196, 222] + , lightyellow: [255, 255, 224] + , lime: [0, 255, 0] + , limegreen: [50, 205, 50] + , linen: [250, 240, 230] + , magenta: [255, 0, 255] + , maroon: [128, 0, 0] + , mediumaquamarine: [102, 205, 170] + , mediumblue: [0, 0, 205] + , mediumorchid: [186, 85, 211] + , mediumpurple: [147, 112, 219] + , mediumseagreen: [60, 179, 113] + , mediumslateblue: [123, 104, 238] + , mediumspringgreen: [0, 250, 154] + , mediumturquoise: [72, 209, 204] + , mediumvioletred: [199, 21, 133] + , midnightblue: [25, 25, 112] + , mintcream: [245, 255, 250] + , mistyrose: [255, 228, 225] + , moccasin: [255, 228, 181] + , navajowhite: [255, 222, 173] + , navy: [0, 0, 128] + , oldlace: [253, 245, 230] + , olive: [128, 128, 0] + , olivedrab: [107, 142, 35] + , orange: [255, 165, 0] + , orangered: [255, 69, 0] + , orchid: [218, 112, 214] + , palegoldenrod: [238, 232, 170] + , palegreen: [152, 251, 152] + , paleturquoise: [175, 238, 238] + , palevioletred: [219, 112, 147] + , papayawhip: [255, 239, 213] + , peachpuff: [255, 218, 185] + , peru: [205, 133, 63] + , pink: [255, 192, 203] + , plum: [221, 160, 203] + , powderblue: [176, 224, 230] + , purple: [128, 0, 128] + , red: [255, 0, 0] + , rosybrown: [188, 143, 143] + , royalblue: [65, 105, 225] + , saddlebrown: [139, 69, 19] + , salmon: [250, 128, 114] + , sandybrown: [244, 164, 96] + , seagreen: [46, 139, 87] + , seashell: [255, 245, 238] + , sienna: [160, 82, 45] + , silver: [192, 192, 192] + , skyblue: [135, 206, 235] + , slateblue: [106, 90, 205] + , slategray: [119, 128, 144] + , slategrey: [119, 128, 144] + , snow: [255, 255, 250] + , springgreen: [0, 255, 127] + , steelblue: [70, 130, 180] + , tan: [210, 180, 140] + , teal: [0, 128, 128] + , thistle: [216, 191, 216] + , tomato: [255, 99, 71] + , turquoise: [64, 224, 208] + , violet: [238, 130, 238] + , wheat: [245, 222, 179] + , white: [255, 255, 255] + , whitesmoke: [245, 245, 245] + , yellow: [255, 255, 0] + , yellowgreen: [154, 205, 5] +}; \ No newline at end of file diff --git a/node_modules/jade/support/stylus/lib/convert/css.js b/node_modules/jade/support/stylus/lib/convert/css.js new file mode 100644 index 0000000..a1bb89f --- /dev/null +++ b/node_modules/jade/support/stylus/lib/convert/css.js @@ -0,0 +1,130 @@ + +/*! + * Stylus - css to stylus conversion + * Copyright(c) 2010 LearnBoost + * MIT Licensed + */ + +/** + * Convert the given `css` to stylus source. + * + * @param {String} css + * @return {String} + * @api public + */ + +module.exports = function(css){ + return new Converter(css).stylus(); +}; + +/** + * Initialize a new `Converter` with the given `css`. + * + * @param {String} css + * @api private + */ + +function Converter(css) { + var cssom = require('cssom'); + this.css = css; + this.types = cssom.CSSRule; + this.root = cssom.parse(css); + this.indents = 0; +} + +/** + * Convert to stylus. + * + * @return {String} + * @api private + */ + +Converter.prototype.stylus = function(){ + return this.visitRules(this.root.cssRules); +}; + +/** + * Return indent string. + * + * @return {String} + * @api private + */ + +Converter.prototype.__defineGetter__('indent', function(){ + return Array(this.indents + 1).join(' '); +}); + +/** + * Visit `node`. + * + * @param {CSSRule} node + * @return {String} + * @api private + */ + +Converter.prototype.visit = function(node){ + switch (node.type) { + case this.types.STYLE_RULE: + return this.visitStyle(node); + case this.types.MEDIA_RULE: + return this.visitMedia(node); + } +}; + +/** + * Visit the rules on `node`. + * + * @param {CSSRule} node + * @return {String} + * @api private + */ + +Converter.prototype.visitRules = function(node){ + var buf = ''; + for (var i = 0, len = node.length; i < len; ++i) { + buf += this.visit(node[i]); + } + return buf; +}; + +/** + * Visit CSSMediaRule `node`. + * + * @param {CSSMediaRule} node + * @return {String} + * @api private + */ + +Converter.prototype.visitMedia = function(node){ + var buf = this.indent + '@media '; + for (var i = 0, len = node.media.length; i < len; ++i) { + buf += node.media[i]; + } + buf += '\n'; + ++this.indents; + buf += this.visitRules(node.cssRules); + --this.indents; + return buf; +}; + +/** + * Visit CSSStyleRule `node`.` + * + * @param {CSSStyleRule} node + * @return {String} + * @api private + */ + +Converter.prototype.visitStyle = function(node){ + var buf = this.indent + node.selectorText + '\n'; + ++this.indents; + for (var i = 0, len = node.style.length; i < len; ++i) { + var prop = node.style[i] + , val = node.style[prop]; + if (prop) { + buf += this.indent + prop + ' ' + val + '\n'; + } + } + --this.indents; + return buf + '\n'; +}; \ No newline at end of file diff --git a/node_modules/jade/support/stylus/lib/functions/image.js b/node_modules/jade/support/stylus/lib/functions/image.js new file mode 100644 index 0000000..ba37f1b --- /dev/null +++ b/node_modules/jade/support/stylus/lib/functions/image.js @@ -0,0 +1,120 @@ + + +/*! + * Stylus - plugin - url + * Copyright(c) 2010 LearnBoost + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var utils = require('../utils') + , nodes = require('../nodes') + , fs = require('fs'); + +/** + * Initialize a new `Image` with the given `ctx` and `path. + * + * @param {Evaluator} ctx + * @param {String} path + * @api private + */ + +var Image = module.exports = function Image(ctx, path) { + this.ctx = ctx; + this.path = utils.lookup(path, ctx.paths); + if (!this.path) throw new Error('failed to locate file ' + path); +}; + +/** + * Open the image for reading. + * + * @api private + */ + +Image.prototype.open = function(){ + this.fd = fs.openSync(this.path, 'r'); +}; + +/** + * Close the file. + * + * @api private + */ + +Image.prototype.close = function(){ + if (this.fd) fs.closeSync(this.fd); +}; + +/** + * Return the type of image, supports: + * + * - gif + * - png + * - jpeg + * + * @return {String} + * @api private + */ + +Image.prototype.type = function(){ + var type + , buf = new Buffer(4); + + fs.readSync(this.fd, buf, 0, 4, 0); + + // GIF + if (0x47 == buf[0] && 0x49 == buf[1] && 0x46 == buf[2]) type = 'gif'; + + // PNG + else if (0x50 == buf[1] && 0x4E == buf[2] && 0x47 == buf[3]) type = 'png'; + + // JPEG + else if (0xff == buf[0] && 0xd8 == buf[1]) type = 'jpeg'; + + return type; +}; + +/** + * Return image dimensions `[width, height]`. + * + * @return {Array} + * @api private + */ + +Image.prototype.size = function(){ + var width + , height + , type = this.type(); + + function uint16(b) { return b[1] << 8 | b[0]; } + function uint32(b) { return b[0] << 24 | b[1] << 16 | b[2] << 8 | b[3]; } + + // Determine dimensions + switch (type) { + case 'jpeg': + throw new Error('image-size() jpeg support not yet implemented'); + break; + case 'png': + var buf = new Buffer(8); + // IHDR chunk width / height uint32_t big-endian + fs.readSync(this.fd, buf, 0, 8, 16); + width = uint32(buf); + height = uint32(buf.slice(4, 8)); + break; + case 'gif': + var buf = new Buffer(4); + // width / height uint16_t little-endian + fs.readSync(this.fd, buf, 0, 4, 6); + width = uint16(buf); + height = uint16(buf.slice(2, 4)); + break; + } + + if ('number' != typeof width) throw new Error('failed to find width of "' + this.path + '"'); + if ('number' != typeof height) throw new Error('failed to find height of "' + this.path + '"'); + + return [width, height]; +}; \ No newline at end of file diff --git a/node_modules/jade/support/stylus/lib/functions/index.js b/node_modules/jade/support/stylus/lib/functions/index.js new file mode 100644 index 0000000..cd3f61c --- /dev/null +++ b/node_modules/jade/support/stylus/lib/functions/index.js @@ -0,0 +1,554 @@ + +/*! + * Stylus - Evaluator - built-in functions + * Copyright(c) 2010 LearnBoost + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var nodes = require('../nodes') + , utils = require('../utils') + , Image = require('./image'); + +/** + * Color component name map. + */ + +var componentMap = { + red: 'r' + , green: 'g' + , blue: 'b' + , alpha: 'a' + , hue: 'h' + , saturation: 's' + , lightness: 'l' +}; + +/** + * Color component type map. + */ + +var typeMap = { + hue: 'deg' + , saturation: '%' + , lightness: '%' +}; + +/** + * Convert the given `color` to an `HSLA` node, + * or h,s,l,a component values. + * + * Examples: + * + * hsla(10deg, 50%, 30%, 0.5) + * // => HSLA + * + * hsla(#ffcc00) + * // => HSLA + * + * @param {RGBA|HSLA|Unit} h + * @param {Unit} s + * @param {Unit} l + * @param {Unit} a + * @return {HSLA} + * @api public + */ + +exports.hsla = function(h,s,l,a){ + switch (arguments.length) { + case 1: + utils.assertColor(h); + return h.hsla; + default: + utils.assertType(h, nodes.Unit, 'hue'); + utils.assertType(s, nodes.Unit, 'saturation'); + utils.assertType(l, nodes.Unit, 'lightness'); + utils.assertType(a, nodes.Unit, 'alpha'); + return new nodes.HSLA(h.val,s.val,l.val,a.val); + } +}; + +/** + * Convert the given `color` to an `HSLA` node, + * or h,s,l component values. + * + * Examples: + * + * hsl(10, 50, 30) + * // => HSLA + * + * hsl(#ffcc00) + * // => HSLA + * + * @param {Unit|HSLA|RGBA} h + * @param {Unit} s + * @param {Unit} l + * @return {HSLA} + * @api public + */ + +exports.hsl = function(h,s,l){ + if (arguments.length > 1) { + return exports.hsla(h,s,l,new nodes.Unit(1)); + } + utils.assertColor(h, 'color'); + return h.hsla; +}; + +/** + * Return type of `node`. + * + * Examples: + * + * type(12) + * // => 'unit' + * + * type(#fff) + * // => 'color' + * + * type(type) + * // => 'function' + * + * type(unbound) + * typeof(unbound) + * type-of(unbound) + * // => 'ident' + * + * @param {Node} node + * @return {String} + * @api public + */ + +exports.type = +exports.typeof = +exports['type-of'] = function(node){ + utils.assertPresent(node, 'expression'); + var type = node.nodeName; + return new nodes.String(type); +}; + +/** + * Return component `name` for the given `color`. + * + * @param {RGBA|HSLA} color + * @param {String} na,e + * @return {Unit} + * @api public + */ + +exports.component = function(color, name) { + utils.assertColor(color, 'color'); + utils.assertString(name, 'name'); + var name = name.string + , type = typeMap[name] + , name = componentMap[name]; + if (!name) throw new Error('invalid color component "' + name + '"'); + return new nodes.Unit(color[name], type); +}; + +/** + * Return the red component of the given `color`. + * + * Examples: + * + * red(#c00) + * // => 204 + * + * @param {RGBA|HSLA} color + * @return {Unit} + * @api public + */ + +exports.red = function(color){ + return exports.component(color, new nodes.String('red')); +}; + +/** + * Return the green component of the given `color`. + * + * Examples: + * + * green(#0c0) + * // => 204 + * + * @param {RGBA|HSLA} color + * @return {Unit} + * @api public + */ + +exports.green = function(color){ + return exports.component(color, new nodes.String('green')); +}; + +/** + * Return the blue component of the given `color`. + * + * Examples: + * + * blue(#00c) + * // => 204 + * + * @param {RGBA|HSLA} color + * @return {Unit} + * @api public + */ + +exports.blue = function(color){ + return exports.component(color, new nodes.String('blue')); +}; + +/** + * Return a `RGBA` from the r,g,b,a channels. + * + * Examples: + * + * rgba(255,0,0,0.5) + * // => rgba(255,0,0,0.5) + * + * rgba(255,0,0,1) + * // => #ff0000 + * + * rgba(#ffcc00, 0.5) + * // rgba(255,204,0,0.5) + * + * @param {Unit|RGBA|HSLA} r + * @param {Unit} g + * @param {Unit} b + * @param {Unit} a + * @return {RGBA} + * @api public + */ + +exports.rgba = function(r,g,b,a){ + switch (arguments.length) { + case 1: + utils.assertColor(r); + var color = r.rgba; + return new nodes.RGBA( + color.r + , color.g + , color.b + , color.a); + case 2: + utils.assertColor(r); + var color = r.rgba; + utils.assertType(g, nodes.Unit); + return new nodes.RGBA( + color.r + , color.g + , color.b + , g.val); + default: + utils.assertType(r, nodes.Unit, 'red'); + utils.assertType(g, nodes.Unit, 'green'); + utils.assertType(b, nodes.Unit, 'blue'); + utils.assertType(a, nodes.Unit, 'alpha'); + return new nodes.RGBA( + r.val + , g.val + , b.val + , a.val); + } +}; + +/** + * Return a `RGBA` from the r,g,b channels. + * + * Examples: + * + * rgb(255,204,0) + * // => #ffcc00 + * + * rgb(#fff) + * // => #fff + * + * @param {Unit|RGBA|HSLA} r + * @param {Unit} g + * @param {Unit} b + * @return {RGBA} + * @api public + */ + +exports.rgb = function(r,g,b){ + switch (arguments.length) { + case 1: + utils.assertColor(r); + var color = r.rgba; + return new nodes.RGBA( + color.r + , color.g + , color.b + , 1); + default: + return exports.rgba(r,g,b,new nodes.Unit(1)); + } +}; + +/** + * Unquote the given `str`. + * + * Examples: + * + * unquote("sans-serif") + * // => sans-serif + * + * unquote(sans-serif) + * // => sans-serif + * + * @param {String|Ident} val + * @return {Literal} + * @api public + */ + +exports.unquote = function(val){ + utils.assertString(val, 'string'); + return new nodes.Literal(val.string); +}; + +/** + * Assign `type` to the given `unit` or return `unit`'s type. + * + * @param {Unit} unit + * @param {String|Ident} type + * @return {Unit} + * @api public + */ + +exports.unit = function(unit, type){ + utils.assertType(unit, nodes.Unit, 'unit'); + + // Assign + if (type) { + utils.assertString(type, 'type'); + return new nodes.Unit(unit.val, type.string); + } else { + return new nodes.String(unit.type || ''); + } +}; + +/** + * Lookup variable `name` or return Null. + * + * @param {String} name + * @return {Mixed} + * @api public + */ + +exports.lookup = function(name){ + utils.assertType(name, nodes.String, 'name'); + var node = this.lookup(name.val); + if (!node) return nodes.null; + return this.visit(node); +}; + +/** + * Perform `op` on the `left` and `right` operands. + * + * @param {String} op + * @param {Node} left + * @param {Node} right + * @return {Node} + * @api public + */ + +exports.operate = function(op, left, right){ + utils.assertType(op, nodes.String, 'op'); + utils.assertPresent(left, 'left'); + utils.assertPresent(right, 'right'); + return left.operate(op.val, right); +}; + +/** + * Test if `val` matches the given `pattern`. + * + * Examples: + * + * match('^foo(bar)?', foo) + * match('^foo(bar)?', foobar) + * match('^foo(bar)?', 'foo') + * match('^foo(bar)?', 'foobar') + * // => true + * + * match('^foo(bar)?', 'bar') + * // => false + * + * @param {String} pattern + * @param {String|Ident} val + * @return {Boolean} + * @api public + */ + +exports.match = function(pattern, val){ + utils.assertType(pattern, nodes.String, 'pattern'); + utils.assertString(val, 'val'); + var re = new RegExp(pattern.val); + return nodes.Boolean(re.test(val.string)); +}; + +/** + * Return length of the given `expr`. + * + * @param {Expression} expr + * @return {Unit} + * @api public + */ + +(exports.length = function(expr){ + if (expr) { + if (expr.nodes) { + return new nodes.Unit(utils.unwrap(expr).nodes.length); + } else { + return new nodes.Unit(1); + } + } + return new nodes.Unit(0); +}).raw = true; + +/** + * Inspect the given `expr`. + * + * @param {Expression} expr + * @api public + */ + +(exports.p = function(expr){ + expr = utils.unwrap(expr); + console.log('\033[90minspect:\033[0m %s' + , expr.toString().replace(/^\(|\)$/g, '')); + return nodes.null; +}).raw = true; + +/** + * Throw an error with the given `msg`. + * + * @param {String} msg + * @api public + */ + +exports.error = function(msg){ + utils.assertType(msg, nodes.String, 'msg'); + throw new Error(msg.val); +}; + +/** + * Warn with the given `msg` prefixed by "Warning: ". + * + * @param {String} msg + * @api public + */ + +exports.warn = function(msg){ + utils.assertType(msg, nodes.String, 'msg'); + console.warn('Warning: %s', msg.val); + return nodes.null; +}; + +/** + * Output stack trace. + * + * @api public + */ + +exports.trace = function(){ + console.log(this.stack); + return nodes.null; +}; + +/** + * Return the opposites of the given `positions`. + * + * Examples: + * + * opposite-position(top left) + * // => bottom right + * + * @param {Expression} positions + * @return {Expression} + * @api public + */ + +(exports['opposite-position'] = function(positions){ + var expr = new nodes.Expression; + utils.unwrap(positions).nodes.forEach(function(pos, i){ + utils.assertString(pos, 'position ' + i); + pos = (function(){ switch (pos.string) { + case 'top': return 'bottom'; + case 'bottom': return 'top'; + case 'left': return 'right'; + case 'right': return 'left'; + default: throw new Error('invalid position ' + pos); + }})(); + expr.push(new nodes.Literal(pos)); + }); + return expr; +}).raw = true; + +/** + * Return the width and height of the given `img` path. + * + * Examples: + * + * image-size('foo.png') + * // => 200px 100px + * + * image-size('foo.png')[0] + * // => 200px + * + * image-size('foo.png')[1] + * // => 100px + * + * @param {String} img + * @return {Expression} + * @api public + */ + +exports['image-size'] = function(img) { + utils.assertType(img, nodes.String, 'img'); + var img = new Image(this, img.string); + + // Read size + img.open(); + var size = img.size(); + img.close(); + + // Return (w h) + var expr = new nodes.Expression; + expr.push(new nodes.Unit(size[0], 'px')); + expr.push(new nodes.Unit(size[1], 'px')); + + return expr; +}; + +/** + * Apply Math `fn` to `n` + * + * @param {Unit} n + * @param {String} fn + * @return {Unit} + * @api private + */ + +exports['-math'] = function(n, fn){ + return new nodes.Unit(Math[fn.string](n.val), n.type); +}; + +/** + * Adjust HSL `color` `prop` by `amount`. + * + * @param {RGBA|HSLA} color + * @param {String} prop + * @param {Unit} amount + * @return {HSLA} + * @api private + */ + +exports['-adjust'] = function(color, prop, amount){ + var hsl = color.hsla; + prop = { hue: 'h', saturation: 's', lightness: 'l' }[prop.string]; + if (!prop) throw new Error('invalid adjustment property'); + hsl[prop] = hsl[prop] + amount.val; + return hsl.clone(); +}; \ No newline at end of file diff --git a/node_modules/jade/support/stylus/lib/functions/index.styl b/node_modules/jade/support/stylus/lib/functions/index.styl new file mode 100644 index 0000000..66e656a --- /dev/null +++ b/node_modules/jade/support/stylus/lib/functions/index.styl @@ -0,0 +1,131 @@ + +// stringify the given arg + +-string(arg) + type(arg) + ' ' + arg + +// require a color + +require-color(color) + unless color is a 'color' + error('RGB or HSL value expected, got a ' + -string(color)) + +// require a unit + +require-unit(n) + unless n is a 'unit' + error('unit expected, got a ' + -string(n)) + +// require a string + +require-string(str) + unless str is a 'string' or str is a 'ident' + error('string expected, got a ' + -string(str)) + +// apply js Math function + +math(n, fn) + require-unit(n) + require-string(fn) + -math(n, fn) + +// adjust the given color's property by amount + +adjust(color, prop, amount) + require-color(color) + require-string(prop) + require-unit(amount) + -adjust(color, prop, amount) + +// Math functions + +abs(n) { math(n, 'abs') } +ceil(n) { math(n, 'ceil') } +floor(n) { math(n, 'floor') } +round(n) { math(n, 'round') } +min(a, b) { a < b ? a : b } +max(a, b) { a > b ? a : b } + +// return the sum of the given numbers + +sum(nums) + sum = 0 + sum += n for n in nums + +// return the average of the given numbers + +avg(nums) + sum(nums) / length(nums) + +// color components + +alpha(color) { component(hsl(color), 'alpha') } +hue(color) { component(hsl(color), 'hue') } +saturation(color) { component(hsl(color), 'saturation') } +lightness(color) { component(hsl(color), 'lightness') } + +// check if n is an odd number + +odd(n) + 1 == n % 2 + +// check if n is an even number + +even(n) + 0 == n % 2 + +// check if color is light + +light(color) + lightness(color) >= 50% + +// check if color is dark + +dark(color) + lightness(color) < 50% + +// desaturate color by amount + +desaturate(color, amount) + adjust(color, 'saturation', - amount) + +// saturate color by amount + +saturate(color, amount) + adjust(color, 'saturation', amount) + +// darken by the given amount + +darken(color, amount) + adjust(color, 'lightness', - amount) + +// lighten by the given amount + +lighten(color, amount) + adjust(color, 'lightness', amount) + +// increase the current lightness value by the given amount + +lighten-by(color, amount) + l = lightness(color) + l = 100 if 0 == l + adjust(color, 'lightness', l * amount / 100) + +// decrease the current lightness value by the given amount + +darken-by(color, amount) + l = lightness(color) + adjust(color, 'lightness', - (l * amount / 100)) + +// return the last value in the given expr + +last(expr) + expr[length(expr) - 1] + +// join values with the given delimiter + +join(delim, vals...) + buf = '' + vals = vals[0] if length(vals) == 1 + for val, i in vals + buf += i ? delim + val : val diff --git a/node_modules/jade/support/stylus/lib/functions/url.js b/node_modules/jade/support/stylus/lib/functions/url.js new file mode 100644 index 0000000..66a2832 --- /dev/null +++ b/node_modules/jade/support/stylus/lib/functions/url.js @@ -0,0 +1,97 @@ + +/*! + * Stylus - plugin - url + * Copyright(c) 2010 LearnBoost + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var Compiler = require('../visitor/compiler') + , nodes = require('../nodes') + , parse = require('url').parse + , extname = require('path').extname + , utils = require('../utils') + , fs = require('fs'); + +/** + * Mime table. + */ + +var mimes = { + '.gif': 'image/gif' + , '.png': 'image/png' + , '.jpg': 'image/jpeg' + , '.jpeg': 'image/jpeg' +}; + +/** + * Return a url() function with the given `options`. + * + * Options: + * + * - `limit` bytesize limit defaulting to 30Kb + * - `paths` image resolution path(s), merged with general lookup paths + * + * Examples: + * + * stylus(str) + * .set('filename', __dirname + '/css/test.styl') + * .define('url', stylus.url({ paths: [__dirname + '/public'] })) + * .render(function(err, css){ ... }) + * + * @param {Object} options + * @return {Function} + * @api public + */ + +module.exports = function(options) { + options = options || {}; + + var sizeLimit = options.limit || 30000 + , _paths = options.paths || []; + + function url(url){ + // Compile the url + var compiler = new Compiler(url); + compiler.isURL = true; + var url = url.nodes.map(function(node){ + return compiler.visit(node); + }).join(''); + + // Parse literal + var url = parse(url) + , ext = extname(url.pathname) + , mime = mimes[ext] + , literal = new nodes.Literal('url("' + url.href + '")') + , paths = _paths.concat(this.paths) + , founds + , buf; + + // Not supported + if (!mime) return literal; + + // Absolute + if (url.protocol) return literal; + + // Lookup + found = utils.lookup(url.pathname, paths); + + // Failed to lookup + if (!found) return literal; + + // Read data + buf = fs.readFileSync(found); + + // To large + if (buf.length > sizeLimit) return literal; + + // Encode + return new nodes.Literal('url("data:' + mime + ';base64,' + buf.toString('base64') + '")'); + }; + + url.raw = true; + return url; +}; \ No newline at end of file diff --git a/node_modules/jade/support/stylus/lib/lexer.js b/node_modules/jade/support/stylus/lib/lexer.js new file mode 100644 index 0000000..0ca2e1d --- /dev/null +++ b/node_modules/jade/support/stylus/lib/lexer.js @@ -0,0 +1,672 @@ + +/*! + * Stylus - Lexer + * Copyright(c) 2010 LearnBoost + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var Token = require('./token') + , nodes = require('./nodes'); + +/** + * Operator aliases. + */ + +var alias = { + 'and': '&&' + , 'or': '||' + , 'is': '==' + , 'isnt': '!=' + , 'is not': '!=' +}; + +/** + * Units. + */ + +var units = [ + 'em' + , 'ex' + , 'px' + , 'mm' + , 'cm' + , 'in' + , 'pt' + , 'pc' + , 'deg' + , 'rad' + , 'grad' + , 'ms' + , 's' + , 'Hz' + , 'kHz' + , '%'].join('|'); + +/** + * Unit RegExp. + */ + +var unit = new RegExp('^(-)?(\\d+\\.\\d+|\\d+|\\.\\d+)(' + units + ')? *'); + +/** + * Initialize a new `Lexer` with the given `str` and `options`. + * + * @param {String} str + * @param {Object} options + * @api private + */ + +var Lexer = module.exports = function Lexer(str, options) { + options = options || {}; + this.str = str.replace(/\r\n?/g, '\n'); + this.stash = []; + this.indentStack = []; + this.indentRe = null; + this.lineno = 0; +}; + +/** + * Lexer prototype. + */ + +Lexer.prototype = { + + /** + * Custom inspect. + */ + + inspect: function(){ + var tok + , tmp = this.str + , buf = []; + while ('eos' != (tok = this.next()).type) { + buf.push(tok.inspect()); + } + this.str = tmp; + this.prevIndents = 0; + return buf.concat(tok.inspect()).join('\n'); + }, + + /** + * Lookahead `n` tokens. + * + * @param {Number} n + * @return {Object} + * @api private + */ + + lookahead: function(n){ + var fetch = n - this.stash.length; + while (fetch-- > 0) this.stash.push(this.advance()); + return this.stash[--n]; + }, + + /** + * Consume the given `len`. + * + * @param {Number|Array} len + * @api private + */ + + skip: function(len){ + this.str = this.str.substr(Array.isArray(len) + ? len[0].length + : len); + }, + + /** + * Fetch next token including those stashed by peek. + * + * @return {Token} + * @api private + */ + + next: function() { + var tok = this.stashed() || this.advance(); + switch (tok.type) { + case 'newline': + case 'selector': + case 'indent': + ++this.lineno; + } + tok.lineno = this.lineno; + return tok; + }, + + /** + * Fetch next token. + * + * @return {Token} + * @api private + */ + + advance: function() { + return this.eos() + || this.null() + || this.sep() + || this.keyword() + || this.urlchars() + || this.atrule() + || this.media() + || this.comment() + || this.newline() + || this.escaped() + || this.important() + || this.literal() + || this.function() + || this.brace() + || this.paren() + || this.color() + || this.string() + || this.unit() + || this.namedop() + || this.boolean() + || this.ident() + || this.op() + || this.space() + || this.selector(); + }, + + /** + * Lookahead a single token. + * + * @return {Token} + * @api private + */ + + peek: function() { + return this.lookahead(1); + }, + + /** + * Return the next possibly stashed token. + * + * @return {Token} + * @api private + */ + + stashed: function() { + return this.stash.shift(); + }, + + /** + * EOS | trailing outdents. + */ + + eos: function() { + if (this.str.length) return; + if (this.indentStack.length) { + this.indentStack.shift(); + return new Token('outdent'); + } else { + return new Token('eos'); + } + }, + + /** + * url char + */ + + urlchars: function() { + var captures; + if (!this.isURL) return; + if (captures = /^[\/:@.;?&=*!,<>#%0-9]+/.exec(this.str)) { + this.skip(captures); + return new Token('literal', new nodes.Literal(captures[0])); + } + }, + + /** + * ';' ' '* + */ + + sep: function() { + var captures; + if (captures = /^; */.exec(this.str)) { + this.skip(captures); + return new Token(';'); + } + }, + + /** + * ' '+ + */ + + space: function() { + var captures; + if (captures = /^( +)/.exec(this.str)) { + this.skip(captures); + return new Token('space'); + } + }, + + /** + * '\\' . ' '* + */ + + escaped: function() { + var captures; + if (captures = /^\\(.) */.exec(this.str)) { + var c = captures[1]; + this.skip(captures); + return new Token('ident', new nodes.Literal(c)); + } + }, + + /** + * '@css' ' '* '{' .* '}' ' '* + */ + + literal: function() { + // HACK attack !!! + var captures; + if (captures = /^@css *\{/.exec(this.str)) { + this.skip(captures); + var c + , braces = 1 + , css = ''; + while (c = this.str[0]) { + this.str = this.str.substr(1); + switch (c) { + case '{': ++braces; break; + case '}': --braces; break; + } + css += c; + if (!braces) break; + } + css = css.replace(/\s*}$/, ''); + return new Token('literal', new nodes.Literal(css)); + } + }, + + /** + * '!important' ' '* + */ + + important: function() { + var captures; + if (captures = /^!important */.exec(this.str)) { + this.skip(captures); + return new Token('ident', new nodes.Literal('!important')); + } + }, + + /** + * '{' | '}' + */ + + brace: function() { + var captures; + if (captures = /^([{}])/.exec(this.str)) { + this.skip(1); + var brace = captures[1]; + return new Token(brace, brace); + } + }, + + /** + * '(' | ')' ' '* + */ + + paren: function() { + var captures; + if (captures = /^([()]) */.exec(this.str)) { + var paren = captures[1]; + this.skip(captures); + if (')' == paren) this.isURL = false; + return new Token(paren, paren); + } + }, + + /** + * 'null' + */ + + null: function() { + var captures; + if (captures = /^(null)\b */.exec(this.str)) { + this.skip(captures); + return new Token('null', nodes.null); + } + }, + + /** + * 'if' + * | 'else' + * | 'unless' + * | 'return' + * | 'for' + * | 'in' + */ + + keyword: function() { + var captures; + if (captures = /^(return|if|else|unless|for|in)\b */.exec(this.str)) { + var keyword = captures[1]; + this.skip(captures); + return new Token(keyword, keyword); + } + }, + + /** + * 'not' + * | 'and' + * | 'or' + * | 'is' + * | 'is not' + * | 'isnt' + * | 'is a' + * | 'is defined' + */ + + namedop: function() { + var captures; + if (captures = /^(not|and|or|is a|is defined|isnt|is not|is)\b( *)/.exec(this.str)) { + var op = captures[1]; + this.skip(captures); + op = alias[op] || op; + var tok = new Token(op, op); + tok.space = captures[2]; + return tok; + } + }, + + /** + * ',' + * | '+' + * | '+=' + * | '-' + * | '-=' + * | '*' + * | '*=' + * | '/' + * | '/=' + * | '%' + * | '%=' + * | '**' + * | '!' + * | '&' + * | '&&' + * | '||' + * | '>' + * | '>=' + * | '<' + * | '<=' + * | '=' + * | '==' + * | '!=' + * | '!' + * | '~' + * | '?=' + * | '?' + * | ':' + * | '[' + * | ']' + * | '..' + * | '...' + */ + + op: function() { + var captures; + if (captures = /^([.]{2,3}|&&|\|\||[!<>=?]=|\*\*|[-+*\/%]=?|[,=?:!~<>&\[\]])( *)/.exec(this.str)) { + var op = captures[1]; + this.skip(captures); + op = alias[op] || op; + var tok = new Token(op, op); + tok.space = captures[2]; + return tok; + } + }, + + /** + * '@media' ([^{\n]+) + */ + + media: function() { + var captures; + if (captures = /^@media *([^{\n]+)/.exec(this.str)) { + this.skip(captures); + return new Token('media', captures[1].trim()); + } + }, + + /** + * '@' ('import' | 'keyframes' | 'charset' | 'page') + */ + + atrule: function() { + var captures; + if (captures = /^@(import|keyframes|charset|page) */.exec(this.str)) { + this.skip(captures); + return new Token(captures[1]); + } + }, + + /** + * '//' * + */ + + comment: function() { + // Single line + if ('/' == this.str[0] && '/' == this.str[1]) { + var end = this.str.indexOf('\n'); + if (-1 == end) end = this.str.length; + this.skip(end); + return this.advance(); + } + + // Multi-line + if ('/' == this.str[0] && '*' == this.str[1]) { + var end = this.str.indexOf('*/'); + if (-1 == end) end = this.str.length; + var str = this.str.substr(0, end + 2) + , lines = str.split('\n').length - 1; + this.lineno += lines; + this.skip(end + 2); + return this.allowComments + ? new Token('comment', str) + : this.advance(); + } + }, + + /** + * 'true' | 'false' + */ + + boolean: function() { + var captures; + if (captures = /^(true|false)\b( *)/.exec(this.str)) { + var val = 'true' == captures[1] + ? nodes.true + : nodes.false; + this.skip(captures); + var tok = new Token('boolean', val); + tok.space = captures[2]; + return tok; + } + }, + + /** + * -?[a-zA-Z$] [-\w\d$]* '(' + */ + + function: function() { + var captures; + if (captures = /^(-?[a-zA-Z$][-\w\d$]*)\(( *)/.exec(this.str)) { + var name = captures[1]; + this.skip(captures); + this.isURL = 'url' == name; + var tok = new Token('function', new nodes.Ident(name)); + tok.space = captures[2]; + return tok; + } + }, + + /** + * -?[a-zA-Z$] [-\w\d$]* + */ + + ident: function() { + var captures; + if (captures = /^(-?[a-zA-Z$][-\w\d$]*)/.exec(this.str)) { + var name = captures[1]; + this.skip(captures); + return new Token('ident', new nodes.Ident(name)); + } + }, + + /** + * '\n' ' '+ + */ + + newline: function() { + var captures, re; + + // we have established the indentation regexp + if (this.indentRe){ + captures = this.indentRe.exec(this.str); + // figure out if we are using tabs or spaces + } else { + // try tabs + re = /^\n([\t]*) */; + captures = re.exec(this.str); + + // nope, try spaces + if (captures && !captures[1].length) { + re = /^\n( *)/; + captures = re.exec(this.str); + } + + // established + if (captures && captures[1].length) this.indentRe = re; + } + + + if (captures) { + var tok + , indents = captures[1].length; + + this.skip(captures); + if (this.str[0] === ' ' || this.str[0] === '\t') { + throw new Error('Invalid indentation, you can use tabs or spaces to indent but not both'); + } + + // Reset state + this.isVariable = false; + + // Blank line + if ('\n' == this.str[0]) { + ++this.lineno; + return this.advance(); + } + + // Outdent + if (this.indentStack.length && indents < this.indentStack[0]) { + while (this.indentStack.length && this.indentStack[0] > indents) { + this.stash.push(new Token('outdent')); + this.indentStack.shift(); + } + tok = this.stash.pop(); + // Indent + } else if (indents && indents != this.indentStack[0]) { + this.indentStack.unshift(indents); + tok = new Token('indent'); + // Newline + } else { + tok = new Token('newline'); + } + + return tok; + } + }, + + /** + * '-'? (digit+ | digit* '.' digit+) unit + */ + + unit: function() { + var captures; + if (captures = unit.exec(this.str)) { + this.skip(captures); + var n = parseFloat(captures[2]); + if ('-' == captures[1]) n = -n; + var node = new nodes.Unit(n, captures[3]); + return new Token('unit', node); + } + }, + + /** + * '"' [^"]+ '"' | "'"" [^']+ "'" + */ + + string: function() { + var captures; + if (captures = /^("[^"]*"|'[^']*') */.exec(this.str)) { + var str = captures[1]; + this.skip(captures); + return new Token('string', new nodes.String(str.slice(1,-1))); + } + }, + + /** + * #nnnnnn | #nnn + */ + + color: function() { + return this.hex6() + || this.hex3(); + }, + + /** + * #nnn + */ + + hex3: function() { + var captures; + if (captures = /^#([a-fA-F0-9]{3}) */.exec(this.str)) { + this.skip(captures); + var rgb = captures[1] + , r = parseInt(rgb[0] + rgb[0], 16) + , g = parseInt(rgb[1] + rgb[1], 16) + , b = parseInt(rgb[2] + rgb[2], 16) + , color = new nodes.RGBA(r, g, b, 1); + color.raw = captures[0]; + return new Token('color', color); + } + }, + + /** + * #nnnnnn + */ + + hex6: function() { + var captures; + if (captures = /^#([a-fA-F0-9]{6}) */.exec(this.str)) { + this.skip(captures); + var rgb = captures[1] + , r = parseInt(rgb.substr(0, 2), 16) + , g = parseInt(rgb.substr(2, 2), 16) + , b = parseInt(rgb.substr(4, 2), 16) + , color = new nodes.RGBA(r, g, b, 1); + color.raw = captures[0]; + return new Token('color', color); + } + }, + + /** + * [^\n,;]+ + */ + + selector: function() { + var captures; + if (captures = /^[^{\n,]+/.exec(this.str)) { + var selector = captures[0]; + this.skip(captures); + return new Token('selector', selector); + } + } +}; diff --git a/node_modules/jade/support/stylus/lib/middleware.js b/node_modules/jade/support/stylus/lib/middleware.js new file mode 100644 index 0000000..fdd890d --- /dev/null +++ b/node_modules/jade/support/stylus/lib/middleware.js @@ -0,0 +1,198 @@ +/*! + * Stylus - middleware + * Copyright(c) 2010 LearnBoost + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var stylus = require('./stylus') + , fs = require('fs') + , url = require('url') + , basename = require('path').basename + , join = require('path').join + , ENOENT; + +// COMPAT: + +try { + ENOENT = require('constants').ENOENT; +} catch (err) { + ENOENT = process.ENOENT; +} + +/** + * Import map. + */ + +var imports = {}; + +/** + * Return Connect middleware with the given `options`. + * + * Options: + * + * `force` Always re-compile + * `src` Source directory used to find .styl files + * `dest` Destination directory used to output .css files + * when undefined defaults to `src`. + * `compile` Custom compile function, accepting the arguments + * `(str, path)`. + * `compress` Whether the output .css files should be compressed + * + * Examples: + * + * Here we set up the custom compile function so that we may + * set the `compress` option, or define additional functions. + * + * By default the compile function simply sets the `filename` + * and renders the CSS. + * + * function compile(str, path) { + * return stylus(str) + * .set('filename', path) + * .set('compress', true); + * } + * + * Pass the middleware to Connect, grabbing .styl files from this directory + * and saving .css files to _./public_. Also supplying our custom `compile` function. + * + * Following that we have a `staticProvider` layer setup to serve the .css + * files generated by Stylus. + * + * var server = connect.createServer( + * stylus.middleware({ + * src: __dirname + * , dest: __dirname + '/public' + * , compile: compile + * }) + * , connect.static(__dirname + '/public') + * ); + * + * @param {Object} options + * @return {Function} + * @api public + */ + +module.exports = function(options){ + options = options || {}; + + // Accept src/dest dir + if ('string' == typeof options) { + options = { src: options }; + } + + // Force compilation + var force = options.force; + + // Source dir required + var src = options.src; + if (!src) throw new Error('stylus.middleware() requires "src" directory'); + + // Default dest dir to source + var dest = options.dest + ? options.dest + : src; + + // Default compile callback + options.compile = options.compile || function(str, path){ + return stylus(str) + .set('filename', path) + .set('compress', options.compress); + }; + + // Middleware + return function(req, res, next){ + if ('GET' != req.method && 'HEAD' != req.method) return next(); + var path = url.parse(req.url).pathname; + if (/\.css$/.test(path)) { + var cssPath = join(dest, path) + , stylusPath = join(src, path.replace('.css', '.styl')); + + // Ignore ENOENT to fall through as 404 + function error(err) { + next(ENOENT == err.errno + ? null + : err); + } + + // Force + if (force) return compile(); + + // Compile to cssPath + function compile() { + fs.readFile(stylusPath, 'utf8', function(err, str){ + if (err) return error(err); + var style = options.compile(str, stylusPath); + var paths = style.options._imports = []; + style.render(function(err, css){ + imports[stylusPath] = imports[stylusPath] || paths; + if (err) return next(err); + fs.writeFile(cssPath, css, 'utf8', function(err){ + next(err); + }); + }); + }); + } + + // Compare mtimes + fs.stat(stylusPath, function(err, stylusStats){ + if (err) return error(err); + fs.stat(cssPath, function(err, cssStats){ + // CSS has not been compiled, compile it! + if (err) { + if (ENOENT == err.errno) { + compile(); + } else { + next(err); + } + } else { + // Source has changed, compile it + if (stylusStats.mtime > cssStats.mtime) { + compile(); + // Already compiled, check imports + } else { + checkImports(stylusPath, function(changed){ + changed ? compile() : next(); + }); + } + } + }); + }); + } else { + next(); + } + } +}; + +/** + * Check `path`'s imports to see if they have been altered. + * + * @param {String} path + * @param {Function} fn + * @api private + */ + +function checkImports(path, fn) { + var nodes = imports[path]; + if (!nodes) return fn(); + if (!nodes.length) return fn(); + var pending = nodes.length + , changed = false; + nodes.forEach(function(import){ + fs.stat(import.path, function(err, stat){ + if (err) { + --pending || fn(changed); + } else if (import.mtime) { + changed = changed || stat.mtime > import.mtime; + import.mtime = stat.mtime; + --pending || fn(changed); + } else { + import.mtime = stat.mtime; + --pending || fn(changed = true); + } + }); + }); +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/lib/nodes/binop.js b/node_modules/jade/support/stylus/lib/nodes/binop.js new file mode 100644 index 0000000..3dbe4b2 --- /dev/null +++ b/node_modules/jade/support/stylus/lib/nodes/binop.js @@ -0,0 +1,52 @@ + +/*! + * Stylus - BinOp + * Copyright(c) 2010 LearnBoost + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var Node = require('./node'); + +/** + * Initialize a new `BinOp` with `op`, `left` and `right`. + * + * @param {String} op + * @param {Node} left + * @param {Node} right + * @api public + */ + +var BinOp = module.exports = function BinOp(op, left, right){ + Node.call(this); + this.op = op; + this.left = left; + this.right = right; +}; + +/** + * Inherit from `Node.prototype`. + */ + +BinOp.prototype.__proto__ = Node.prototype; + +/** + * Return a clone of this node. + * + * @return {Node} + * @api public + */ + +BinOp.prototype.clone = function(){ + var clone = new BinOp( + this.op + , this.left.clone() + , this.right ? + this.right.clone() + : null); + clone.lineno = this.lineno; + return clone; +}; \ No newline at end of file diff --git a/node_modules/jade/support/stylus/lib/nodes/block.js b/node_modules/jade/support/stylus/lib/nodes/block.js new file mode 100644 index 0000000..7db0d62 --- /dev/null +++ b/node_modules/jade/support/stylus/lib/nodes/block.js @@ -0,0 +1,98 @@ + +/*! + * Stylus - Block + * Copyright(c) 2010 LearnBoost + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var Node = require('./node'); + +/** + * Initialize a new `Block` node with `parent` Block. + * + * @param {Block} parent + * @api public + */ + +var Block = module.exports = function Block(parent, node){ + Node.call(this); + this.nodes = []; + this.parent = parent; + this.node = node; + this.scope = true; +}; + +/** + * Inherit from `Node.prototype`. + */ + +Block.prototype.__proto__ = Node.prototype; + +/** + * Check if this block has properties.. + * + * @return {Boolean} + * @api public + */ + +Block.prototype.__defineGetter__('hasProperties', function(){ + for (var i = 0, len = this.nodes.length; i < len; ++i) { + if ('property' == this.nodes[i].nodeName) { + return true; + } + } +}); + +/** + * Check if this block is empty. + * + * @return {Boolean} + * @api public + */ + +Block.prototype.__defineGetter__('isEmpty', function(){ + return !this.nodes.length; +}); + +/** + * Return a clone of this node. + * + * @return {Node} + * @api public + */ + +Block.prototype.clone = function(){ + var clone = new Block(this.parent, this.node); + clone.lineno = this.lineno; + clone.scope = this.scope; + this.nodes.forEach(function(node){ + node = node.clone(); + switch (node.nodeName) { + case 'each': + case 'group': + node.block.parent = clone; + break; + case 'ident': + if ('function' == node.val.nodeName) { + node.val.block.parent = clone; + } + } + clone.push(node); + }); + return clone; +}; + +/** + * Push a `node` to this block. + * + * @param {Node} node + * @api public + */ + +Block.prototype.push = function(node){ + this.nodes.push(node); +}; diff --git a/node_modules/jade/support/stylus/lib/nodes/boolean.js b/node_modules/jade/support/stylus/lib/nodes/boolean.js new file mode 100644 index 0000000..a71c327 --- /dev/null +++ b/node_modules/jade/support/stylus/lib/nodes/boolean.js @@ -0,0 +1,83 @@ + +/*! + * Stylus - Boolean + * Copyright(c) 2010 LearnBoost + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var Node = require('./node') + , nodes = require('./'); + +/** + * Initialize a new `Boolean` node with the given `val`. + * + * @param {Boolean} val + * @api public + */ + +var Boolean = module.exports = function Boolean(val){ + Node.call(this); + if (this instanceof Boolean) { + this.val = !!val; + } else { + return val ? nodes.true : nodes.false; + } +}; + +/** + * Inherit from `Node.prototype`. + */ + +Boolean.prototype.__proto__ = Node.prototype; + +/** + * Return `this` node. + * + * @return {Boolean} + * @api public + */ + +Boolean.prototype.toBoolean = function(){ + return this; +}; + +/** + * Negate the value. + * + * @return {Boolean} + * @api public + */ + +Boolean.prototype.negate = function(){ + return this.val + ? nodes.false + : nodes.true; +}; + +/** + * Return 'Boolean'. + * + * @return {String} + * @api public + */ + +Boolean.prototype.inspect = function(){ + return '[Boolean ' + this.val + ']'; +}; + +/** + * Return 'true' or 'false'. + * + * @return {String} + * @api public + */ + +Boolean.prototype.toString = function(){ + return this.val + ? 'true' + : 'false'; +}; \ No newline at end of file diff --git a/node_modules/jade/support/stylus/lib/nodes/call.js b/node_modules/jade/support/stylus/lib/nodes/call.js new file mode 100644 index 0000000..b0d20f5 --- /dev/null +++ b/node_modules/jade/support/stylus/lib/nodes/call.js @@ -0,0 +1,56 @@ + +/*! + * Stylus - Call + * Copyright(c) 2010 LearnBoost + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var Node = require('./node'); + +/** + * Initialize a new `Call` with `name` and `args`. + * + * @param {String} name + * @param {Expression} args + * @api public + */ + +var Call = module.exports = function Call(name, args){ + Node.call(this); + this.name = name; + this.args = args; +}; + +/** + * Inherit from `Node.prototype`. + */ + +Call.prototype.__proto__ = Node.prototype; + +/** + * Return a clone of this node. + * + * @return {Node} + * @api public + */ + +Call.prototype.clone = function(){ + var clone = new Call(this.name, this.args.clone()); + clone.lineno = this.lineno; + return clone; +}; + +/** + * Return (). + * + * @return {String} + * @api public + */ + +Call.prototype.toString = function(){ + return this.name + '()'; +}; diff --git a/node_modules/jade/support/stylus/lib/nodes/charset.js b/node_modules/jade/support/stylus/lib/nodes/charset.js new file mode 100644 index 0000000..2e95c34 --- /dev/null +++ b/node_modules/jade/support/stylus/lib/nodes/charset.js @@ -0,0 +1,42 @@ + +/*! + * Stylus - Charset + * Copyright(c) 2010 LearnBoost + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var Node = require('./node') + , nodes = require('./'); + +/** + * Initialize a new `Charset` with the given `val` + * + * @param {String} val + * @api public + */ + +var Charset = module.exports = function Charset(val){ + Node.call(this); + this.val = val; +}; + +/** + * Inherit from `Node.prototype`. + */ + +Charset.prototype.__proto__ = Node.prototype; + +/** + * Return @charset "val". + * + * @return {String} + * @api public + */ + +Charset.prototype.toString = function(){ + return '@charset ' + this.val; +}; diff --git a/node_modules/jade/support/stylus/lib/nodes/each.js b/node_modules/jade/support/stylus/lib/nodes/each.js new file mode 100644 index 0000000..7268dec --- /dev/null +++ b/node_modules/jade/support/stylus/lib/nodes/each.js @@ -0,0 +1,55 @@ + +/*! + * Stylus - Each + * Copyright(c) 2010 LearnBoost + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var Node = require('./node') + , nodes = require('./'); + +/** + * Initialize a new `Each` node with the given `val` name, + * `key` name, `expr`, and `block`. + * + * @param {String} val + * @param {String} key + * @param {Expression} expr + * @param {Block} block + * @api public + */ + +var Each = module.exports = function Each(val, key, expr, block){ + Node.call(this); + this.val = val; + this.key = key; + this.expr = expr; + this.block = block; +}; + +/** + * Inherit from `Node.prototype`. + */ + +Each.prototype.__proto__ = Node.prototype; + +/** + * Return a clone of this node. + * + * @return {Node} + * @api public + */ + +Each.prototype.clone = function(){ + var clone = new Each( + this.val + , this.key + , this.expr.clone() + , this.block.clone()); + clone.lineno = this.lineno; + return clone; +}; \ No newline at end of file diff --git a/node_modules/jade/support/stylus/lib/nodes/expression.js b/node_modules/jade/support/stylus/lib/nodes/expression.js new file mode 100644 index 0000000..ae7205f --- /dev/null +++ b/node_modules/jade/support/stylus/lib/nodes/expression.js @@ -0,0 +1,143 @@ + +/*! + * Stylus - Expression + * Copyright(c) 2010 LearnBoost + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var Node = require('./node') + , nodes = require('../nodes') + , utils = require('../utils'); + +/** + * Initialize a new `Expression`. + * + * @param {Boolean} isList + * @api public + */ + +var Expression = module.exports = function Expression(isList){ + Node.call(this); + this.nodes = []; + this.isList = isList; +}; + +/** + * Check if the variable has a value. + * + * @return {Boolean} + * @api public + */ + +Expression.prototype.__defineGetter__('isEmpty', function(){ + return !this.nodes.length; +}); + +/** + * Return the first node in this expression. + * + * @return {Node} + * @api public + */ + +Expression.prototype.__defineGetter__('first', function(){ + return this.nodes[0] + ? this.nodes[0].first + : nodes.null; +}); + +/** + * Hash all the nodes in order. + * + * @return {String} + * @api public + */ + +Expression.prototype.__defineGetter__('hash', function(){ + return this.nodes.map(function(node){ + return node.hash; + }).join('::'); +}); + +/** + * Inherit from `Node.prototype`. + */ + +Expression.prototype.__proto__ = Node.prototype; + +/** + * Return a clone of this node. + * + * @return {Node} + * @api public + */ + +Expression.prototype.clone = function(){ + var clone = new Expression(this.isList); + clone.preserve = this.preserve; + clone.lineno = this.lineno; + for (var i = 0; i < this.nodes.length; ++i) { + clone.push(this.nodes[i].clone()); + } + return clone; +}; + +/** + * Push the given `node`. + * + * @param {Node} node + * @api public + */ + +Expression.prototype.push = function(node){ + this.nodes.push(node); +}; + +/** + * Operate on `right` with the given `op`. + * + * @param {String} op + * @param {Node} right + * @return {Node} + * @api public + */ + +Expression.prototype.operate = function(op, right){ + switch (op) { + case '[]': + var expr = new nodes.Expression + , vals = utils.unwrap(this).nodes + , range = utils.unwrap(right).nodes; + range.forEach(function(unit){ + if ('unit' == unit.nodeName) { + var node = vals[unit.val]; + if (node) expr.push(node); + } + }); + return expr.isEmpty + ? nodes.null + : expr; + default: + return Node.prototype.operate.call(this, op, right); + } +}; + +/** + * Return " " or ", , " if + * the expression represents a list. + * + * @return {String} + * @api public + */ + +Expression.prototype.toString = function(){ + return '(' + this.nodes.map(function(node){ + return node.toString(); + }).join(this.isList ? ', ' : ' ') + ')'; +}; + + diff --git a/node_modules/jade/support/stylus/lib/nodes/function.js b/node_modules/jade/support/stylus/lib/nodes/function.js new file mode 100644 index 0000000..ba0c214 --- /dev/null +++ b/node_modules/jade/support/stylus/lib/nodes/function.js @@ -0,0 +1,92 @@ + +/*! + * Stylus - Function + * Copyright(c) 2010 LearnBoost + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var Node = require('./node'); + +/** + * Initialize a new `Function` with `name`, `params`, and `body`. + * + * @param {String} name + * @param {Params|Function} params + * @param {Block} body + * @api public + */ + +var Function = module.exports = function Function(name, params, body){ + Node.call(this); + this.name = name; + this.params = params; + this.block = body; + if ('function' == typeof params) this.fn = params; +}; + +/** + * Check function arity. + * + * @return {Boolean} + * @api public + */ + +Function.prototype.__defineGetter__('arity', function(){ + return this.params.length; +}); + +/** + * Inherit from `Node.prototype`. + */ + +Function.prototype.__proto__ = Node.prototype; + +/** + * Return a clone of this node. + * + * @return {Node} + * @api public + */ + +Function.prototype.clone = function(){ + if (this.fn) { + var clone = new Function( + this.name + , this.fn); + } else { + var clone = new Function( + this.name + , this.params.clone() + , this.block.clone()); + } + clone.lineno = this.lineno; + return clone; +}; + +/** + * Return (param1, param2, ...). + * + * @return {String} + * @api public + */ + +Function.prototype.toString = function(){ + if (this.fn) { + return this.name + + '(' + + this.fn.toString() + .match(/^function *\((.*?)\)/) + .slice(1) + .join(', ') + + ')'; + } else { + return this.name + + '(' + + this.params.nodes.join(', ') + + ')'; + } +}; diff --git a/node_modules/jade/support/stylus/lib/nodes/group.js b/node_modules/jade/support/stylus/lib/nodes/group.js new file mode 100644 index 0000000..1d36b81 --- /dev/null +++ b/node_modules/jade/support/stylus/lib/nodes/group.js @@ -0,0 +1,78 @@ + +/*! + * Stylus - Group + * Copyright(c) 2010 LearnBoost + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var Node = require('./node'); + +/** + * Initialize a new `Group`. + * + * @api public + */ + +var Group = module.exports = function Group(){ + Node.call(this); + this.nodes = []; +}; + +/** + * Inherit from `Node.prototype`. + */ + +Group.prototype.__proto__ = Node.prototype; + +/** + * Push the given `selector` node. + * + * @param {Selector} selector + * @api public + */ + +Group.prototype.push = function(selector){ + this.nodes.push(selector); +}; + +/** + * Return this set's `Block`. + */ + +Group.prototype.__defineGetter__('block', function(){ + return this.nodes[0].block; +}); + +/** + * Assign `block` to each selector in this set. + * + * @param {Block} block + * @api public + */ + +Group.prototype.__defineSetter__('block', function(block){ + for (var i = 0, len = this.nodes.length; i < len; ++i) { + this.nodes[i].block = block; + } +}); + +/** + * Return a clone of this node. + * + * @return {Node} + * @api public + */ + +Group.prototype.clone = function(){ + var clone = new Group; + clone.lineno = this.lineno; + this.nodes.forEach(function(node){ + clone.push(node.clone()); + }); + clone.block = this.block.clone(); + return clone; +}; diff --git a/node_modules/jade/support/stylus/lib/nodes/hsla.js b/node_modules/jade/support/stylus/lib/nodes/hsla.js new file mode 100644 index 0000000..9be887d --- /dev/null +++ b/node_modules/jade/support/stylus/lib/nodes/hsla.js @@ -0,0 +1,230 @@ + +/*! + * Stylus - HSLA + * Copyright(c) 2010 LearnBoost + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var Node = require('./node') + , nodes = require('./'); + +/** + * Initialize a new `HSLA` with the given h,s,l,a component values. + * + * @param {Number} h + * @param {Number} s + * @param {Number} l + * @param {Number} a + * @api public + */ + +var HSLA = exports = module.exports = function HSLA(h,s,l,a){ + Node.call(this); + this.h = clampDegrees(h); + this.s = clampPercentage(s); + this.l = clampPercentage(l); + this.a = clampAlpha(a); + this.hsla = this; +}; + +/** + * Inherit from `Node.prototype`. + */ + +HSLA.prototype.__proto__ = Node.prototype; + +/** + * Return hsla(n,n,n,n). + * + * @return {String} + * @api public + */ + +HSLA.prototype.toString = function(){ + return 'hsla(' + + this.h + ',' + + this.s + ',' + + this.l + ',' + + this.a + ')'; +}; + +/** + * Return a clone of this node. + * + * @return {Node} + * @api public + */ + +HSLA.prototype.clone = function(){ + var clone = new HSLA( + this.h + , this.s + , this.l + , this.a); + clone.lineno = this.lineno; + return clone; +}; + +/** + * Return rgba `RGBA` representation. + * + * @return {RGBA} + * @api public + */ + +HSLA.prototype.__defineGetter__('rgba', function(){ + return nodes.RGBA.fromHSLA(this); +}); + +/** + * Return hash. + * + * @return {String} + * @api public + */ + +HSLA.prototype.__defineGetter__('hash', function(){ + return this.rgba.toString(); +}); + +/** + * Coerce RGBA to HSLA. + * + * @param {Node} other + * @return {Node} + * @api public + */ + +HSLA.prototype.coerce = function(other){ + if (other instanceof nodes.RGBA) { + return other.hsla; + } else { + return Node.prototype.coerce.call(this, other); + } +}; + +/** + * Operate on `right` with the given `op`. + * + * @param {String} op + * @param {Node} right + * @return {Node} + * @api public + */ + +HSLA.prototype.operate = function(op, right){ + switch (op) { + case '+': + return new HSLA( + this.h + right.h + , this.s + right.s + , this.l + right.l + , 1 == right.a ? this.a : (this.a + right.a) + ); + case '-': + return new HSLA( + this.h - right.h + , this.s - right.s + , this.l - right.l + , 1 == right.a ? this.a : (this.a - right.a) + ); + case '*': + return new HSLA( + this.h * right.h + , this.s * right.s + , this.l * right.l + , this.a * right.a + ); + case '/': + return new HSLA( + this.h / right.h + , this.s / right.s + , this.l / right.l + , this.a / right.a + ); + default: + return Node.prototype.operate.call(this, op, right); + } +}; + +/** + * Return `HSLA` representation of the given `color`. + * + * @param {RGBA} color + * @return {HSLA} + * @api public + */ + +exports.fromRGBA = function(rgba){ + var r = rgba.r / 255 + , g = rgba.g / 255 + , b = rgba.b / 255 + , a = rgba.a; + + var min = Math.min(r,g,b) + , max = Math.max(r,g,b) + , l = (max + min) / 2 + , d = max - min + , h, s; + + switch (max) { + case min: h = 0; break; + case r: h = 60 * (g-b) / d; break; + case g: h = 60 * (b-r) / d + 120; break; + case b: h = 60 * (r-g) / d + 240; break; + } + + if (max == min) { + s = 0; + } else if (l < .5) { + s = d / (2 * l); + } else { + s = d / (2 - 2 * l); + } + + h %= 360; + s *= 100; + l *= 100; + + return new HSLA(h,s,l,a); +}; + +/** + * Clamp degree `n` >= 0 and <= 360. + * + * @param {Number} n + * @return {Number} + * @api private + */ + +function clampDegrees(n) { + return Math.max(0, Math.min(n, 360)); +} + +/** + * Clamp percentage `n` >= 0 and <= 100. + * + * @param {Number} n + * @return {Number} + * @api private + */ + +function clampPercentage(n) { + return Math.max(0, Math.min(n, 100)); +} + +/** + * Clamp alpha `n` >= 0 and <= 1. + * + * @param {Number} n + * @return {Number} + * @api private + */ + +function clampAlpha(n) { + return Math.max(0, Math.min(n, 1)); +} diff --git a/node_modules/jade/support/stylus/lib/nodes/ident.js b/node_modules/jade/support/stylus/lib/nodes/ident.js new file mode 100644 index 0000000..e307bc8 --- /dev/null +++ b/node_modules/jade/support/stylus/lib/nodes/ident.js @@ -0,0 +1,97 @@ + +/*! + * Stylus - Ident + * Copyright(c) 2010 LearnBoost + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var Node = require('./node') + , nodes = require('./'); + +/** + * Initialize a new `Ident` by `name` with the given `val` node. + * + * @param {String} name + * @param {Node} val + * @api public + */ + +var Ident = module.exports = function Ident(name, val){ + Node.call(this); + this.name = name; + this.string = name; + this.val = val || nodes.null; +}; + +/** + * Check if the variable has a value. + * + * @return {Boolean} + * @api public + */ + +Ident.prototype.__defineGetter__('isEmpty', function(){ + return undefined == this.val; +}); + +/** + * Return hash. + * + * @return {String} + * @api public + */ + +Ident.prototype.__defineGetter__('hash', function(){ + return this.name; +}); + +/** + * Inherit from `Node.prototype`. + */ + +Ident.prototype.__proto__ = Node.prototype; + +/** + * Return a clone of this node. + * + * @return {Node} + * @api public + */ + +Ident.prototype.clone = function(){ + var clone = new Ident(this.name, this.val.clone()); + clone.lineno = this.lineno; + return clone; +}; + +/** + * Return . + * + * @return {String} + * @api public + */ + +Ident.prototype.toString = function(){ + return this.name; +}; + +/** + * Coerce `other` to an ident. + * + * @param {Node} other + * @return {String} + * @api public + */ + +Ident.prototype.coerce = function(other){ + if (other instanceof nodes.Literal || + other instanceof Ident) { + return other; + } else { + return Node.prototype.coerce.call(this, other); + } +}; diff --git a/node_modules/jade/support/stylus/lib/nodes/if.js b/node_modules/jade/support/stylus/lib/nodes/if.js new file mode 100644 index 0000000..ec7a977 --- /dev/null +++ b/node_modules/jade/support/stylus/lib/nodes/if.js @@ -0,0 +1,54 @@ + +/*! + * Stylus - If + * Copyright(c) 2010 LearnBoost + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var Node = require('./node'); + +/** + * Initialize a new `If` with the given `cond`. + * + * @param {Expression} cond + * @param {Boolean|Block} negate, block + * @api public + */ + +var If = module.exports = function If(cond, negate){ + Node.call(this); + this.cond = cond; + this.elses = []; + if (negate instanceof Node) { + this.block = negate; + } else { + this.negate = negate; + } +}; + +/** + * Inherit from `Node.prototype`. + */ + +If.prototype.__proto__ = Node.prototype; + +/** + * Return a clone of this node. + * + * @return {Node} + * @api public + */ + +If.prototype.clone = function(){ + var cond = this.cond.clone() + , block = this.block.clone(); + var clone = new If(cond, block); + clone.elses = this.elses.map(function(node){ return node.clone(); }); + clone.negate = this.negate; + clone.lineno = this.lineno; + return clone; +}; diff --git a/node_modules/jade/support/stylus/lib/nodes/import.js b/node_modules/jade/support/stylus/lib/nodes/import.js new file mode 100644 index 0000000..9356c30 --- /dev/null +++ b/node_modules/jade/support/stylus/lib/nodes/import.js @@ -0,0 +1,30 @@ + +/*! + * Stylus - Import + * Copyright(c) 2010 LearnBoost + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var Node = require('./node'); + +/** + * Initialize a new `Import` with the given `expr`. + * + * @param {Expression} expr + * @api public + */ + +var Import = module.exports = function Import(expr){ + Node.call(this); + this.path = expr; +}; + +/** + * Inherit from `Node.prototype`. + */ + +Import.prototype.__proto__ = Node.prototype; diff --git a/node_modules/jade/support/stylus/lib/nodes/index.js b/node_modules/jade/support/stylus/lib/nodes/index.js new file mode 100644 index 0000000..671344c --- /dev/null +++ b/node_modules/jade/support/stylus/lib/nodes/index.js @@ -0,0 +1,48 @@ + +/*! + * Stylus - nodes + * Copyright(c) 2010 LearnBoost + * MIT Licensed + */ + +/** + * Constructors + */ + +exports.Node = require('./node'); +exports.Root = require('./root'); +exports.Null = require('./null'); +exports.Each = require('./each'); +exports.If = require('./if'); +exports.Call = require('./call'); +exports.Page = require('./page'); +exports.UnaryOp = require('./unaryop'); +exports.BinOp = require('./binop'); +exports.Ternary = require('./ternary'); +exports.Block = require('./block'); +exports.Unit = require('./unit'); +exports.String = require('./string'); +exports.HSLA = require('./hsla'); +exports.RGBA = require('./rgba'); +exports.Ident = require('./ident'); +exports.Group = require('./group'); +exports.Literal = require('./literal'); +exports.Boolean = require('./boolean'); +exports.Return = require('./return'); +exports.Media = require('./media'); +exports.Params = require('./params'); +exports.Keyframes = require('./keyframes'); +exports.Charset = require('./charset'); +exports.Import = require('./import'); +exports.Function = require('./function'); +exports.Property = require('./property'); +exports.Selector = require('./selector'); +exports.Expression = require('./expression'); + +/** + * Singletons. + */ + +exports.true = new exports.Boolean(true); +exports.false = new exports.Boolean(false); +exports.null = new exports.Null; \ No newline at end of file diff --git a/node_modules/jade/support/stylus/lib/nodes/keyframes.js b/node_modules/jade/support/stylus/lib/nodes/keyframes.js new file mode 100644 index 0000000..cd15604 --- /dev/null +++ b/node_modules/jade/support/stylus/lib/nodes/keyframes.js @@ -0,0 +1,57 @@ + +/*! + * Stylus - Keyframes + * Copyright(c) 2010 LearnBoost + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var Node = require('./node'); + +/** + * Initialize a new `Keyframes` with the given `name`. + * + * @param {String} name + * @api public + */ + +var Keyframes = module.exports = function Keyframes(name){ + Node.call(this); + this.name = name; + this.frames = []; +}; + +/** + * Inherit from `Node.prototype`. + */ + +Keyframes.prototype.__proto__ = Node.prototype; + +/** + * Push the given `block` at `pos`. + * + * @param {Unit} pos + * @param {Block} block + * @api public + */ + +Keyframes.prototype.push = function(pos, block){ + this.frames.push({ + pos: pos + , block: block + }); +}; + +/** + * Return `@keyframes name`. + * + * @return {String} + * @api public + */ + +Keyframes.prototype.toString = function(){ + return '@keyframes ' + this.name; +}; diff --git a/node_modules/jade/support/stylus/lib/nodes/literal.js b/node_modules/jade/support/stylus/lib/nodes/literal.js new file mode 100644 index 0000000..1b94867 --- /dev/null +++ b/node_modules/jade/support/stylus/lib/nodes/literal.js @@ -0,0 +1,70 @@ + +/*! + * Stylus - Literal + * Copyright(c) 2010 LearnBoost + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var Node = require('./node') + , nodes = require('./'); + +/** + * Initialize a new `Literal` with the given `str`. + * + * @param {String} str + * @api public + */ + +var Literal = module.exports = function Literal(str){ + Node.call(this); + this.val = str; +}; + +/** + * Inherit from `Node.prototype`. + */ + +Literal.prototype.__proto__ = Node.prototype; + +/** + * Return hash. + * + * @return {String} + * @api public + */ + +Literal.prototype.__defineGetter__('hash', function(){ + return this.val; +}); + +/** + * Return literal value. + * + * @return {String} + * @api public + */ + +Literal.prototype.toString = function(){ + return this.val; +}; + +/** + * Coerce `other` to a literal. + * + * @param {Node} other + * @return {String} + * @api public + */ + +Literal.prototype.coerce = function(other){ + if (other instanceof Literal || + other instanceof nodes.Ident) { + return other; + } else { + return Node.prototype.coerce.call(this, other); + } +}; diff --git a/node_modules/jade/support/stylus/lib/nodes/media.js b/node_modules/jade/support/stylus/lib/nodes/media.js new file mode 100644 index 0000000..142fb24 --- /dev/null +++ b/node_modules/jade/support/stylus/lib/nodes/media.js @@ -0,0 +1,42 @@ + +/*! + * Stylus - Media + * Copyright(c) 2010 LearnBoost + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var Node = require('./node') + , nodes = require('./'); + +/** + * Initialize a new `Media` with the given `val` + * + * @param {String} val + * @api public + */ + +var Media = module.exports = function Media(val){ + Node.call(this); + this.val = val; +}; + +/** + * Inherit from `Node.prototype`. + */ + +Media.prototype.__proto__ = Node.prototype; + +/** + * Return @media "val". + * + * @return {String} + * @api public + */ + +Media.prototype.toString = function(){ + return '@media ' + this.val; +}; diff --git a/node_modules/jade/support/stylus/lib/nodes/node.js b/node_modules/jade/support/stylus/lib/nodes/node.js new file mode 100644 index 0000000..266c118 --- /dev/null +++ b/node_modules/jade/support/stylus/lib/nodes/node.js @@ -0,0 +1,175 @@ + +/*! + * Stylus - Node + * Copyright(c) 2010 LearnBoost + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var Evaluator = require('../visitor/evaluator') + , utils = require('../utils') + , nodes = require('./'); + +/** + * Node constructor. + * + * @api public + */ + +var Node = module.exports = function Node(){ + this.lineno = nodes.lineno; + Object.defineProperty(this, 'filename', { value: nodes.filename }); + Object.defineProperty(this, 'source', { value: nodes.source }); +}; + +/** + * Return this node. + * + * @return {Node} + * @api public + */ + +Node.prototype.__defineGetter__('first', function(){ + return this; +}); + +/** + * Return hash. + * + * @return {String} + * @api public + */ + +Node.prototype.__defineGetter__('hash', function(){ + return this.val; +}); + +/** + * Return node name. + * + * @return {String} + * @api public + */ + +Node.prototype.__defineGetter__('nodeName', function(){ + return this.constructor.name.toLowerCase(); +}); + +/** + * Return this node. + * + * @return {Node} + * @api public + */ + +Node.prototype.clone = function(){ + return this; +}; + +/** + * Nodes by default evaluate to themselves. + * + * @return {Node} + * @api public + */ + +Node.prototype.eval = function(){ + return new Evaluator(this).evaluate(); +}; + +/** + * Return true. + * + * @return {Boolean} + * @api public + */ + +Node.prototype.toBoolean = function(){ + return nodes.true; +}; + +/** + * Operate on `right` with the given `op`. + * + * @param {String} op + * @param {Node} right + * @return {Node} + * @api public + */ + +Node.prototype.operate = function(op, right){ + switch (op) { + case 'is a': + if ('string' == right.nodeName) { + if ('color' == right.string) { + return nodes.Boolean('rgba' == this.nodeName || 'hsla' == this.nodeName); + } else { + return nodes.Boolean(this.nodeName == right.val); + } + } else { + throw new Error('"is a" expects a string, got ' + right.nodeName); + } + case '==': + return nodes.Boolean(this.hash == right.hash); + case '!=': + return nodes.Boolean(this.hash != right.hash); + case '>=': + return nodes.Boolean(this.hash >= right.hash); + case '<=': + return nodes.Boolean(this.hash <= right.hash); + case '>': + return nodes.Boolean(this.hash > right.hash); + case '<': + return nodes.Boolean(this.hash < right.hash); + case '||': + return nodes.true == this.toBoolean() + ? this + : right; + case 'in': + var vals = utils.unwrap(right).nodes + , hash = this.hash; + if (!vals) throw new Error('"in" given invalid right-hand operand, expecting an expression'); + for (var i = 0, len = vals.length; i < len; ++i) { + if (hash == vals[i].hash) { + return nodes.true; + } + } + return nodes.false; + case '&&': + var a = this.toBoolean() + , b = right.toBoolean(); + return nodes.true == a && nodes.true == b + ? right + : nodes.false == a + ? this + : right; + default: + if ('[]' == op) { + var msg = 'cannot perform ' + + this + + '[' + right + ']'; + } else { + var msg = 'cannot perform' + + ' ' + this + + ' ' + op + + ' ' + right; + } + throw new Error(msg); + } +}; + +/** + * Default coercion throws. + * + * @param {Node} other + * @return {Node} + * @api public + */ + +Node.prototype.coerce = function(other){ + if (other.nodeName == this.nodeName) return other; + throw new Error('cannot coerce ' + other + ' to ' + this.nodeName); +}; diff --git a/node_modules/jade/support/stylus/lib/nodes/null.js b/node_modules/jade/support/stylus/lib/nodes/null.js new file mode 100644 index 0000000..579e4c3 --- /dev/null +++ b/node_modules/jade/support/stylus/lib/nodes/null.js @@ -0,0 +1,61 @@ + +/*! + * Stylus - Null + * Copyright(c) 2010 LearnBoost + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var Node = require('./node') + , nodes = require('./'); + +/** + * Initialize a new `Null` node. + * + * @api public + */ + +var Null = module.exports = function Null(){}; + +/** + * Inherit from `Node.prototype`. + */ + +Null.prototype.__proto__ = Node.prototype; + +/** + * Return 'Null'. + * + * @return {String} + * @api public + */ + +Null.prototype.inspect = +Null.prototype.toString = function(){ + return '[Null]'; +}; + +/** + * Return false. + * + * @return {Boolean} + * @api public + */ + +Null.prototype.toBoolean = function(){ + return nodes.false; +}; + +/** + * Return hash. + * + * @return {String} + * @api public + */ + +Null.prototype.__defineGetter__('hash', function(){ + return null; +}); \ No newline at end of file diff --git a/node_modules/jade/support/stylus/lib/nodes/page.js b/node_modules/jade/support/stylus/lib/nodes/page.js new file mode 100644 index 0000000..e60648e --- /dev/null +++ b/node_modules/jade/support/stylus/lib/nodes/page.js @@ -0,0 +1,43 @@ + +/*! + * Stylus - Page + * Copyright(c) 2010 LearnBoost + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var Node = require('./node'); + +/** + * Initialize a new `Page` with the given `selector` and `block`. + * + * @param {Selector} selector + * @param {Block} block + * @api public + */ + +var Page = module.exports = function Page(selector, block){ + Node.call(this); + this.selector = selector; + this.block = block; +}; + +/** + * Inherit from `Node.prototype`. + */ + +Page.prototype.__proto__ = Node.prototype; + +/** + * Return `@oage name`. + * + * @return {String} + * @api public + */ + +Page.prototype.toString = function(){ + return '@page ' + this.selector; +}; diff --git a/node_modules/jade/support/stylus/lib/nodes/params.js b/node_modules/jade/support/stylus/lib/nodes/params.js new file mode 100644 index 0000000..9bbe9cb --- /dev/null +++ b/node_modules/jade/support/stylus/lib/nodes/params.js @@ -0,0 +1,71 @@ + +/*! + * Stylus - Params + * Copyright(c) 2010 LearnBoost + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var Node = require('./node'); + +/** + * Initialize a new `Params` with `name`, `params`, and `body`. + * + * @param {String} name + * @param {Params} params + * @param {Expression} body + * @api public + */ + +var Params = module.exports = function Params(){ + Node.call(this); + this.nodes = []; +}; + +/** + * Check function arity. + * + * @return {Boolean} + * @api public + */ + +Params.prototype.__defineGetter__('length', function(){ + return this.nodes.length; +}); + +/** + * Inherit from `Node.prototype`. + */ + +Params.prototype.__proto__ = Node.prototype; + +/** + * Push the given `node`. + * + * @param {Node} node + * @api public + */ + +Params.prototype.push = function(node){ + this.nodes.push(node); +}; + +/** + * Return a clone of this node. + * + * @return {Node} + * @api public + */ + +Params.prototype.clone = function(){ + var clone = new Params; + clone.lineno = this.lineno; + this.nodes.forEach(function(node){ + clone.push(node.clone()); + }); + return clone; +}; + diff --git a/node_modules/jade/support/stylus/lib/nodes/property.js b/node_modules/jade/support/stylus/lib/nodes/property.js new file mode 100644 index 0000000..6d3167c --- /dev/null +++ b/node_modules/jade/support/stylus/lib/nodes/property.js @@ -0,0 +1,47 @@ + +/*! + * Stylus - Property + * Copyright(c) 2010 LearnBoost + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var Node = require('./node'); + +/** + * Initialize a new `Property` with the given `segs` and optional `expr`. + * + * @param {Array} segs + * @param {Expression} expr + * @api public + */ + +var Property = module.exports = function Property(segs, expr){ + Node.call(this); + this.segments = segs; + this.expr = expr; +}; + +/** + * Inherit from `Node.prototype`. + */ + +Property.prototype.__proto__ = Node.prototype; + +/** + * Return a clone of this node. + * + * @return {Node} + * @api public + */ + +Property.prototype.clone = function(){ + var clone = new Property(this.segments); + clone.lineno = this.lineno; + this.segments = this.segments.map(function(node){ return node.clone(); }); + if (this.expr) clone.expr = this.expr.clone(); + return clone; +}; diff --git a/node_modules/jade/support/stylus/lib/nodes/return.js b/node_modules/jade/support/stylus/lib/nodes/return.js new file mode 100644 index 0000000..86ca751 --- /dev/null +++ b/node_modules/jade/support/stylus/lib/nodes/return.js @@ -0,0 +1,43 @@ + +/*! + * Stylus - Return + * Copyright(c) 2010 LearnBoost + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var Node = require('./node') + , nodes = require('./'); + +/** + * Initialize a new `Return` node with the given `expr`. + * + * @param {Expression} expr + * @api public + */ + +var Return = module.exports = function Return(expr){ + this.expr = expr || nodes.null; +}; + +/** + * Inherit from `Node.prototype`. + */ + +Return.prototype.__proto__ = Node.prototype; + +/** + * Return a clone of this node. + * + * @return {Node} + * @api public + */ + +Return.prototype.clone = function(){ + var clone = new Return(this.expr.clone()); + clone.lineno = this.lineno; + return clone; +}; \ No newline at end of file diff --git a/node_modules/jade/support/stylus/lib/nodes/rgba.js b/node_modules/jade/support/stylus/lib/nodes/rgba.js new file mode 100644 index 0000000..8648db9 --- /dev/null +++ b/node_modules/jade/support/stylus/lib/nodes/rgba.js @@ -0,0 +1,243 @@ + +/*! + * Stylus - RGBA + * Copyright(c) 2010 LearnBoost + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var Node = require('./node') + , HSLA = require('./hsla') + , nodes = require('./'); + +/** + * Initialize a new `RGBA` with the given r,g,b,a component values. + * + * @param {Number} r + * @param {Number} g + * @param {Number} b + * @param {Number} a + * @api public + */ + +var RGBA = exports = module.exports = function RGBA(r,g,b,a){ + Node.call(this); + this.r = clamp(r); + this.g = clamp(g); + this.b = clamp(b); + this.a = clampAlpha(a); + this.rgba = this; +}; + +/** + * Inherit from `Node.prototype`. + */ + +RGBA.prototype.__proto__ = Node.prototype; + +/** + * Return a clone of this node. + * + * @return {Node} + * @api public + */ + +RGBA.prototype.clone = function(){ + var clone = new RGBA( + this.r + , this.g + , this.b + , this.a); + clone.lineno = this.lineno; + return clone; +}; + +/** + * Return true. + * + * @return {Boolean} + * @api public + */ + +RGBA.prototype.toBoolean = function(){ + return nodes.true; +}; + +/** + * Return `HSLA` representation. + * + * @return {HSLA} + * @api public + */ + +RGBA.prototype.__defineGetter__('hsla', function(){ + return HSLA.fromRGBA(this); +}); + +/** + * Return hash. + * + * @return {String} + * @api public + */ + +RGBA.prototype.__defineGetter__('hash', function(){ + return this.toString(); +}); + +/** + * Coerce HSLA and Unit to RGBA. + * + * @param {Node} other + * @return {Node} + * @api public + */ + +RGBA.prototype.coerce = function(other){ + if (other instanceof nodes.HSLA) { + return other.rgba; + } else if (other instanceof nodes.Unit) { + var n = other.val; + return new RGBA(n,n,n,1); + } else { + return Node.prototype.coerce.call(this, other); + } +}; + +/** + * Operate on `right` with the given `op`. + * + * @param {String} op + * @param {Node} right + * @return {Node} + * @api public + */ + +RGBA.prototype.operate = function(op, right){ + switch (op) { + case '+': + return new RGBA( + this.r + right.r + , this.g + right.g + , this.b + right.b + , 1 == right.a ? this.a : (this.a + right.a) + ); + case '-': + return new RGBA( + this.r - right.r + , this.g - right.g + , this.b - right.b + , 1 == right.a ? this.a : (this.a - right.a) + ); + case '*': + return new RGBA( + this.r * right.r + , this.g * right.g + , this.b * right.b + , this.a * right.a + ); + case '/': + return new RGBA( + this.r / right.r + , this.g / right.g + , this.b / right.b + , this.a / right.a + ); + default: + return Node.prototype.operate.call(this, op, right); + } +}; + +/** + * Return #nnnnnn, #nnn, or rgba(n,n,n,n) string representation of the color. + * + * @return {String} + * @api public + */ + +RGBA.prototype.toString = function(){ + function pad(n) { + return n < 16 + ? '0' + n.toString(16) + : n.toString(16); + } + + if (1 == this.a) { + var r = pad(this.r) + , g = pad(this.g) + , b = pad(this.b); + + // Compress + if (r[0] == r[1] && g[0] == g[1] && b[0] == b[1]) { + return '#' + r[0] + g[0] + b[0]; + } else { + return '#' + r + g + b; + } + } else { + return 'rgba(' + + this.r + ',' + + this.g + ',' + + this.b + ',' + + this.a + ')'; + } +}; + +/** + * Return a `RGBA` from the given `hsla`. + * + * @param {HSLA} hsla + * @return {RGBA} + * @api public + */ + +exports.fromHSLA = function(hsla){ + var h = hsla.h / 360 + , s = hsla.s / 100 + , l = hsla.l / 100 + , a = hsla.a; + + var m2 = l <= .5 ? l * (s + 1) : l + s - l * s + , m1 = l * 2 - m2; + + var r = hue(h + 1/3) * 0xff + , g = hue(h) * 0xff + , b = hue(h - 1/3) * 0xff; + + function hue(h) { + if (h < 0) ++h; + if (h > 1) --h; + if (h * 6 < 1) return m1 + (m2 - m1) * h * 6; + if (h * 2 < 1) return m2; + if (h * 3 < 2) return m1 + (m2 - m1) * (2/3 - h) * 6; + return m1; + } + + return new RGBA(r,g,b,a); +}; + +/** + * Clamp `n` >= 0 and <= 255. + * + * @param {Number} n + * @return {Number} + * @api private + */ + +function clamp(n) { + return Math.max(0, Math.min(n.toFixed(0), 255)); +} + +/** + * Clamp alpha `n` >= 0 and <= 1. + * + * @param {Number} n + * @return {Number} + * @api private + */ + +function clampAlpha(n) { + return Math.max(0, Math.min(n, 1)); +} diff --git a/node_modules/jade/support/stylus/lib/nodes/root.js b/node_modules/jade/support/stylus/lib/nodes/root.js new file mode 100644 index 0000000..d5e14c5 --- /dev/null +++ b/node_modules/jade/support/stylus/lib/nodes/root.js @@ -0,0 +1,50 @@ + +/*! + * Stylus - Root + * Copyright(c) 2010 LearnBoost + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var Node = require('./node'); + +/** + * Initialize a new `Root` node. + * + * @api public + */ + +var Root = module.exports = function Root(){ + this.nodes = []; +}; + +/** + * Inherit from `Node.prototype`. + */ + +Root.prototype.__proto__ = Node.prototype; + +/** + * Push a `node` to this block. + * + * @param {Node} node + * @api public + */ + +Root.prototype.push = function(node){ + this.nodes.push(node); +}; + +/** + * Return "root". + * + * @return {String} + * @api public + */ + +Root.prototype.toString = function(){ + return '[Root]'; +}; diff --git a/node_modules/jade/support/stylus/lib/nodes/selector.js b/node_modules/jade/support/stylus/lib/nodes/selector.js new file mode 100644 index 0000000..c7d308f --- /dev/null +++ b/node_modules/jade/support/stylus/lib/nodes/selector.js @@ -0,0 +1,55 @@ + +/*! + * Stylus - Selector + * Copyright(c) 2010 LearnBoost + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var Block = require('./block') + , Node = require('./node'); + +/** + * Initialize a new `Selector` with the given `val`. + * + * @param {String} val + * @api public + */ + +var Selector = module.exports = function Selector(val){ + Node.call(this); + this.val = val.replace(/ +$/, ''); +}; + +/** + * Inherit from `Node.prototype`. + */ + +Selector.prototype.__proto__ = Node.prototype; + +/** + * Return the selector string. + * + * @return {String} + * @api public + */ + +Selector.prototype.toString = function(){ + return this.val; +}; + +/** + * Return a clone of this node. + * + * @return {Node} + * @api public + */ + +Selector.prototype.clone = function(){ + var clone = new Selector(this.val); + clone.lineno = this.lineno; + return clone; +}; diff --git a/node_modules/jade/support/stylus/lib/nodes/string.js b/node_modules/jade/support/stylus/lib/nodes/string.js new file mode 100644 index 0000000..2e9e6e6 --- /dev/null +++ b/node_modules/jade/support/stylus/lib/nodes/string.js @@ -0,0 +1,101 @@ + +/*! + * Stylus - String + * Copyright(c) 2010 LearnBoost + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var Node = require('./node') + , nodes = require('./'); + +/** + * Initialize a new `String` with the given `val`. + * + * @param {String} val + * @api public + */ + +var String = module.exports = function String(val){ + Node.call(this); + this.val = val; + this.string = val; +}; + +/** + * Inherit from `Node.prototype`. + */ + +String.prototype.__proto__ = Node.prototype; + +/** + * Return quoted string. + * + * @return {String} + * @api public + */ + +String.prototype.toString = function(){ + return '"' + this.val + '"'; +}; + +/** + * Return a clone of this node. + * + * @return {Node} + * @api public + */ + +String.prototype.clone = function(){ + var clone = new String(this.val); + clone.lineno = this.lineno; + return clone; +}; + +/** + * Return Boolean based on the length of this string. + * + * @return {Boolean} + * @api public + */ + +String.prototype.toBoolean = function(){ + return nodes.Boolean(this.val.length); +}; + +/** + * Coerce `other` to a string. + * + * @param {Node} other + * @return {String} + * @api public + */ + +String.prototype.coerce = function(other){ + if (other instanceof String) { + return other; + } else { + return new String(other.toString()); + } +}; + +/** + * Operate on `right` with the given `op`. + * + * @param {String} op + * @param {Node} right + * @return {Node} + * @api public + */ + +String.prototype.operate = function(op, right){ + switch (op) { + case '+': + return new String(this.val + right.val); + default: + return Node.prototype.operate.call(this, op, right); + } +}; diff --git a/node_modules/jade/support/stylus/lib/nodes/ternary.js b/node_modules/jade/support/stylus/lib/nodes/ternary.js new file mode 100644 index 0000000..f82157e --- /dev/null +++ b/node_modules/jade/support/stylus/lib/nodes/ternary.js @@ -0,0 +1,50 @@ + +/*! + * Stylus - Ternary + * Copyright(c) 2010 LearnBoost + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var Node = require('./node'); + +/** + * Initialize a new `Ternary` with `cond`, `trueExpr` and `falseExpr`. + * + * @param {Expression} cond + * @param {Expression} trueExpr + * @param {Expression} falseExpr + * @api public + */ + +var Ternary = module.exports = function Ternary(cond, trueExpr, falseExpr){ + Node.call(this); + this.cond = cond; + this.trueExpr = trueExpr; + this.falseExpr = falseExpr; +}; + +/** + * Inherit from `Node.prototype`. + */ + +Ternary.prototype.__proto__ = Node.prototype; + +/** + * Return a clone of this node. + * + * @return {Node} + * @api public + */ + +Ternary.prototype.clone = function(){ + var clone = new Ternary( + this.cond.clone() + , this.trueExpr.clone() + , this.falseExpr.clone()); + clone.lineno = this.lineno; + return clone; +}; \ No newline at end of file diff --git a/node_modules/jade/support/stylus/lib/nodes/unaryop.js b/node_modules/jade/support/stylus/lib/nodes/unaryop.js new file mode 100644 index 0000000..a409fc6 --- /dev/null +++ b/node_modules/jade/support/stylus/lib/nodes/unaryop.js @@ -0,0 +1,45 @@ + +/*! + * Stylus - UnaryOp + * Copyright(c) 2010 LearnBoost + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var Node = require('./node'); + +/** + * Initialize a new `UnaryOp` with `op`, and `expr`. + * + * @param {String} op + * @param {Node} expr + * @api public + */ + +var UnaryOp = module.exports = function UnaryOp(op, expr){ + Node.call(this); + this.op = op; + this.expr = expr; +}; + +/** + * Inherit from `Node.prototype`. + */ + +UnaryOp.prototype.__proto__ = Node.prototype; + +/** + * Return a clone of this node. + * + * @return {Node} + * @api public + */ + +UnaryOp.prototype.clone = function(){ + var clone = new UnaryOp(this.op, this.expr.clone()); + clone.lineno = this.lineno; + return clone; +}; \ No newline at end of file diff --git a/node_modules/jade/support/stylus/lib/nodes/unit.js b/node_modules/jade/support/stylus/lib/nodes/unit.js new file mode 100644 index 0000000..5e4e342 --- /dev/null +++ b/node_modules/jade/support/stylus/lib/nodes/unit.js @@ -0,0 +1,188 @@ + +/*! + * Stylus - Unit + * Copyright(c) 2010 LearnBoost + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var Node = require('./node') + , nodes = require('./'); + +/** + * Initialize a new `Unit` with the given `val` and unit `type` + * such as "px", "pt", "in", etc. + * + * @param {String} val + * @param {String} type + * @api public + */ + +var Unit = module.exports = function Unit(val, type){ + Node.call(this); + this.val = val; + this.type = type; +}; + +/** + * Inherit from `Node.prototype`. + */ + +Unit.prototype.__proto__ = Node.prototype; + +/** + * Return Boolean based on the unit value. + * + * @return {Boolean} + * @api public + */ + +Unit.prototype.toBoolean = function(){ + return nodes.Boolean(this.type + ? true + : this.val); +}; + +/** + * Return unit string. + * + * @return {String} + * @api public + */ + +Unit.prototype.toString = function(){ + var n = this.val; + if ('px' == this.type) n = n.toFixed(0); + return n + (this.type || ''); +}; + +/** + * Return a clone of this node. + * + * @return {Node} + * @api public + */ + +Unit.prototype.clone = function(){ + var clone = new Unit(this.val, this.type); + clone.lineno = this.lineno; + return clone; +}; + +/** + * Operate on `right` with the given `op`. + * + * @param {String} op + * @param {Node} right + * @return {Node} + * @api public + */ + +Unit.prototype.operate = function(op, right){ + switch (op) { + case '-': + return new Unit(this.val - right.val, this.type); + case '+': + return new Unit(this.val + right.val, this.type); + case '/': + return new Unit(this.val / right.val, this.type); + case '*': + return new Unit(this.val * right.val, this.type); + case '%': + return new Unit(this.val % right.val, this.type); + case '**': + return new Unit(Math.pow(this.val, right.val), this.type); + case '..': + case '...': + var start = this.val + , end = right.val + , expr = new nodes.Expression + , inclusive = '..' == op; + do { + expr.push(new nodes.Unit(start)); + } while (inclusive ? ++start <= end : ++start < end); + return expr; + default: + return Node.prototype.operate.call(this, op, right); + } +}; + +/** + * Coerce `other` unit to the same type as `this` unit. + * + * Supports: + * + * mm -> cm | in + * cm -> mm | in + * in -> mm | cm + * + * ms -> s + * s -> ms + * + * Hz -> kHz + * kHz -> Hz + * + * @param {Unit} other + * @return {Unit} + * @api public + */ + +Unit.prototype.coerce = function(other){ + if (other instanceof Unit) { + var a = this + , b = other; + switch (a.type) { + case 'mm': + switch (b.type) { + case 'cm': + return new nodes.Unit(b.val * 2.54, 'mm'); + case 'in': + return new nodes.Unit(b.val * 25.4, 'mm'); + } + case 'cm': + switch (b.type) { + case 'mm': + return new nodes.Unit(b.val / 10, 'cm'); + case 'in': + return new nodes.Unit(b.val * 2.54, 'cm'); + } + case 'in': + switch (b.type) { + case 'mm': + return new nodes.Unit(b.val / 25.4, 'in'); + case 'cm': + return new nodes.Unit(b.val / 2.54, 'in'); + } + case 'ms': + switch (b.type) { + case 's': + return new nodes.Unit(b.val * 1000, 'ms'); + } + case 's': + switch (b.type) { + case 'ms': + return new nodes.Unit(b.val / 1000, 's'); + } + case 'Hz': + switch (b.type) { + case 'kHz': + return new nodes.Unit(b.val * 1000, 'Hz'); + } + case 'kHz': + switch (b.type) { + case 'Hz': + return new nodes.Unit(b.val / 1000, 'kHz'); + } + } + return new nodes.Unit(b.val, a.type); + } else if (other instanceof nodes.String) { + var val = parseInt(other.val, 10); + if (isNaN(val)) Node.prototype.coerce.call(this, other); + return new nodes.Unit(val); + } else { + return Node.prototype.coerce.call(this, other); + } +}; diff --git a/node_modules/jade/support/stylus/lib/parser.js b/node_modules/jade/support/stylus/lib/parser.js new file mode 100644 index 0000000..73ec075 --- /dev/null +++ b/node_modules/jade/support/stylus/lib/parser.js @@ -0,0 +1,1360 @@ + +/*! + * Stylus - Parser + * Copyright(c) 2010 LearnBoost + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var Lexer = require('./lexer') + , nodes = require('./nodes') + , inspect = require('sys').inspect; + +/** + * Selector composite tokens. + */ + +var selectorTokens = [ + 'ident' + , 'string' + , 'selector' + , 'function' + , 'comment' + , 'space' + , 'color' + , 'unit' + , 'for' + , '[' + , ']' + , '(' + , ')' + , '+' + , '-' + , '*' + , '*=' + , '<' + , '>' + , '=' + , ':' + , '&' + , '~' +]; + +/** + * CSS3 pseudo-selectors. + */ + +var pseudoSelectors = [ + 'root' + , 'nth-child' + , 'nth-last-child' + , 'nth-of-type' + , 'nth-last-of-type' + , 'first-child' + , 'last-child' + , 'first-of-type' + , 'last-of-type' + , 'only-child' + , 'only-of-type' + , 'empty' + , 'link' + , 'visited' + , 'active' + , 'hover' + , 'focus' + , 'target' + , 'lang' + , 'enabled' + , 'disabled' + , 'checked' + , 'not' +]; + +/** + * Initialize a new `Parser` with the given `str` and `options`. + * + * @param {String} str + * @param {Object} options + * @api private + */ + +var Parser = module.exports = function Parser(str, options) { + var self = this; + options = options || {}; + this.str = nodes.source = str; + this.lexer = new Lexer(str, options); + this.root = options.root || new nodes.Root; + this.state = ['root']; + this.state.pop = function(){ + self.prevState = [].pop.call(this); + }; +}; + +/** + * Parser prototype. + */ + +Parser.prototype = { + + /** + * Constructor. + */ + + constructor: Parser, + + /** + * Return current state. + * + * @return {String} + * @api private + */ + + currentState: function() { + return this.state[this.state.length - 1]; + }, + + /** + * Parse the input, then return the root node. + * + * @return {Node} + * @api private + */ + + parse: function(){ + var block = this.parent = this.root; + while ('eos' != this.peek().type) { + if (this.accept('newline')) continue; + var stmt = this.statement(); + this.accept(';'); + if (!stmt) this.error('unexpected token {peek}, not allowed at the root level'); + block.push(stmt); + } + return block; + }, + + /** + * Throw an `Error` with the given `msg`. + * + * @param {String} msg + * @api private + */ + + error: function(msg){ + var type = this.peek().type + , val = undefined == this.peek().val + ? '' + : ' ' + this.peek().toString(); + if (val.trim() == type.trim()) val = ''; + throw new Error(msg.replace('{peek}', type + val)); + }, + + /** + * Accept the given token `type`, and return it, + * otherwise return `undefined`. + * + * @param {String} type + * @return {Token} + * @api private + */ + + accept: function(type){ + if (type == this.peek().type) { + return this.next(); + } + }, + + /** + * Expect token `type` and return it, throw otherwise. + * + * @param {String} type + * @return {Token} + * @api private + */ + + expect: function(type){ + if (type != this.peek().type) { + throw new Error('expected ' + type + ', got ' + this.peek()); + } + return this.next(); + }, + + /** + * Get the next token. + * + * @return {Token} + * @api private + */ + + next: function() { + var tok = this.lexer.next(); + nodes.lineno = tok.lineno; + return tok; + }, + + /** + * Peek with lookahead(1). + * + * @return {Token} + * @api private + */ + + peek: function() { + return this.lexer.peek(); + }, + + /** + * Lookahead `n` tokens. + * + * @param {Number} n + * @return {Token} + * @api private + */ + + lookahead: function(n){ + return this.lexer.lookahead(n); + }, + + /** + * Check if the token at `n` is a valid selector token. + * + * @param {Number} n + * @return {Boolean} + * @api private + */ + + isSelectorToken: function(n) { + var la = this.lookahead(n).type; + switch (la) { + case 'for': + return this.bracketed; + case '[': + this.bracketed = true; + return true; + case ']': + this.bracketed = false; + return true; + default: + return ~selectorTokens.indexOf(la); + } + }, + + /** + * Check if the token at `n` is a pseudo selector. + * + * @param {Number} n + * @return {Boolean} + * @api private + */ + + isPseudoSelector: function(n){ + return ~pseudoSelectors.indexOf(this.lookahead(n).val.name); + }, + + /** + * Valid selector tokens. + */ + + selectorToken: function() { + if (this.isSelectorToken(1)) return this.next(); + }, + + /** + * Consume whitespace. + */ + + skipWhitespace: function() { + while (~['space', 'indent', 'outdent', 'newline'].indexOf(this.peek().type)) + this.next(); + }, + + /** + * Consume spaces. + */ + + skipSpaces: function() { + while ('space' == this.peek().type) + this.next(); + }, + + /** + * Check if the following sequence of tokens + * forms a function definition, ie trailing + * `{` or indentation. + */ + + looksLikeFunctionDefinition: function(i) { + return 'indent' == this.lookahead(i).type + || '{' == this.lookahead(i).type; + }, + + /** + * Check if the following sequence of tokens + * forms a selector. + */ + + looksLikeSelector: function() { + var i = 1; + + // Assume selector when an ident is + // followed by a selector + while ('ident' == this.lookahead(i).type + && 'newline' == this.lookahead(i + 1).type) i += 2; + + // Assume pseudo selectors are NOT properties + // as 'td:th-child(1)' may look like a property + // and function call to the parser otherwise + while (this.isSelectorToken(i)) { + if (':' == this.lookahead(i++).type + && this.isPseudoSelector(i)) + return true; + } + + // Trailing comma + if (',' == this.lookahead(i).type + && 'newline' == this.lookahead(i + 1).type) + return true; + + // Trailing brace + if ('{' == this.lookahead(i).type + && 'newline' == this.lookahead(i + 1).type) + return true; + + // css-style mode, false on ; } + if (this.css) { + if (';' == this.lookahead(i) || + '}' == this.lookahead(i)) + return false; + } + + // Trailing separators + while (!~[ + 'newline' + , 'indent' + , 'outdent' + , 'for' + , 'if' + , ';' + , '}'].indexOf(this.lookahead(i).type)) + ++i; + + if ('indent' == this.lookahead(i).type) + return true; + }, + + /** + * statement + * | statement 'if' expression + * | statement 'unless' expression + */ + + statement: function() { + var stmt = this.stmt() + , state = this.prevState + , block + , op; + + // special-case statements since it + // is not an expression. We could + // implement postfix conditionals at + // the expression level, however they + // would then fail to enclose properties + if (this.allowPostfix) { + delete this.allowPostfix; + state = 'expression'; + } + + switch (state) { + case 'assignment': + case 'expression': + case 'function arguments': + while (op = + this.accept('if') + || this.accept('unless') + || this.accept('for')) { + switch (op.type) { + case 'if': + case 'unless': + stmt = new nodes.If(this.expression(), stmt); + stmt.postfix = true; + stmt.negate = 'unless' == op.type; + this.accept(';'); + break; + case 'for': + var key + , val = this.id().name; + if (this.accept(',')) key = this.id().name; + this.expect('in'); + var each = new nodes.Each(val, key, this.expression()); + block = new nodes.Block; + block.push(stmt); + each.block = block; + stmt = each; + } + } + } + + return stmt; + }, + + /** + * ident + * | selector + * | literal + * | charset + * | import + * | media + * | keyframes + * | page + * | for + * | if + * | unless + * | expression + * | 'return' expression + */ + + stmt: function() { + var type = this.peek().type; + switch (type) { + case 'selector': + case 'literal': + case 'keyframes': + case 'charset': + case 'import': + case 'media': + case 'page': + case 'ident': + case 'unless': + case 'function': + case 'for': + case 'if': + return this[type](); + case 'return': + return this.return(); + case '{': + return this.property(); + default: + // Contextual selectors + switch (this.currentState()) { + case 'root': + case 'selector': + case 'conditional': + case 'keyframe': + case 'function': + case 'media': + case 'for': + switch (type) { + case 'color': + case '~': + case '+': + case '>': + case '<': + case '*': + case ':': + case '&': + case '[': + return this.selector(); + } + } + + // Expression fallback + var expr = this.expression(); + if (expr.isEmpty) this.error('unexpected {peek}'); + return expr; + } + }, + + /** + * indent (!outdent)+ outdent + */ + + block: function(node, scope) { + var delim + , stmt + , _ = this.css + , block = this.parent = new nodes.Block(this.parent, node); + + if (false === scope) block.scope = false; + + // css-style + if (this.css = this.accept('{')) { + delim = '}'; + this.skipWhitespace(); + } else { + delim = 'outdent'; + this.expect('indent'); + } + + while (delim != this.peek().type) { + // css-style + if (this.css) { + if (this.accept('newline')) continue; + stmt = this.statement(); + this.accept(';'); + this.skipWhitespace(); + } else { + if (this.accept('newline')) continue; + stmt = this.statement(); + this.accept(';'); + } + if (!stmt) this.error('unexpected token {peek} in block'); + block.push(stmt); + } + + // css-style + if (this.css) { + this.skipWhitespace(); + this.expect('}'); + this.skipSpaces(); + this.css = _; + } else { + this.expect('outdent'); + } + + this.parent = block.parent; + return block; + }, + + /** + * for val (',' key) in expr + */ + + for: function() { + this.expect('for'); + var key + , val = this.id().name; + if (this.accept(',')) key = this.id().name; + this.expect('in'); + var each = new nodes.Each(val, key, this.expression()); + this.state.push('for'); + each.block = this.block(each, false); + this.state.pop(); + return each; + }, + + /** + * return expression + */ + + return: function() { + this.expect('return'); + var expr = this.expression(); + return expr.isEmpty + ? new nodes.Return + : new nodes.Return(expr); + }, + + /** + * unless expression block + */ + + unless: function() { + this.expect('unless'); + var node = new nodes.If(this.expression(), true); + this.state.push('conditional'); + node.block = this.block(node, false); + this.state.pop(); + return node; + }, + + /** + * if expression block (else block)? + */ + + if: function() { + this.expect('if'); + var node = new nodes.If(this.expression()); + this.state.push('conditional'); + node.block = this.block(node, false); + while (this.accept('else')) { + if (this.accept('if')) { + var cond = this.expression() + , block = this.block(node, false); + node.elses.push(new nodes.If(cond, block)); + } else { + node.elses.push(this.block(node, false)); + break; + } + } + this.state.pop(); + return node; + }, + + /** + * media + */ + + media: function() { + var val = this.expect('media').val + , media = new nodes.Media(val); + this.state.push('media'); + media.block = this.block(media); + this.state.pop(); + return media; + }, + + /** + * import expression + */ + + import: function() { + this.expect('import'); + this.allowPostfix = true; + return new nodes.Import(this.expression()); + }, + + /** + * charset string + */ + + charset: function() { + this.expect('charset'); + var str = this.expect('string').val; + this.allowPostfix = true; + return new nodes.Charset(str); + }, + + /** + * page selector? block + */ + + page: function() { + var selector; + this.expect('page'); + if (this.accept(':')) { + var str = this.expect('ident').val.name; + selector = new nodes.Literal(':' + str); + } + var page = new nodes.Page(selector); + this.state.push('page'); + page.block = this.block(page); + this.state.pop(); + return page; + }, + + /** + * keyframes name ((unit | from | to) block)+ + */ + + keyframes: function() { + this.expect('keyframes'); + var pos + , _ = this.css + , keyframes = new nodes.Keyframes(this.id()); + + // css-sty;e + if (this.css = this.accept('{')) { + this.skipWhitespace(); + } else { + this.expect('indent'); + } + + while (pos = this.accept('unit') || this.accept('ident')) { + // from | to + if ('ident' == pos.type) { + this.accept('space'); + switch (pos.val.name) { + case 'from': + pos = new nodes.Unit(0, '%'); + break; + case 'to': + pos = new nodes.Unit(100, '%'); + break; + default: + throw new Error('invalid ident "' + pos.val.name + '" in selector'); + } + } else { + pos = pos.val; + } + + // block + this.state.push('keyframe'); + var block = this.block(keyframes); + keyframes.push(pos, block); + this.state.pop(); + if (this.css) this.skipWhitespace(); + } + + // css-style + if (this.css) { + this.skipWhitespace(); + this.expect('}'); + this.css = _; + } else { + this.expect('outdent'); + } + + return keyframes; + }, + + /** + * literal + */ + + literal: function() { + return this.expect('literal').val; + }, + + /** + * ident space? + */ + + id: function() { + var tok = this.expect('ident'); + this.accept('space'); + return tok.val; + }, + + /** + * ident + * | assignment + * | property + * | selector + */ + + ident: function() { + var i = 2 + , la = this.lookahead(i).type; + + while ('space' == la) la = this.lookahead(++i).type; + + switch (la) { + // Assignment + case '=': + case '?=': + case '-=': + case '+=': + case '*=': + case '/=': + case '%=': + return this.assignment(); + // Operation + case '-': + case '+': + case '/': + case '*': + case '%': + case '**': + case 'and': + case 'or': + case '&&': + case '||': + case '>': + case '<': + case '>=': + case '<=': + case '!=': + case '==': + case '[': + case '?': + case 'in': + case 'is a': + case 'is defined': + // Prevent cyclic .ident, return literal + if (this._ident == this.peek()) { + return this.id(); + } else { + this._ident = this.peek(); + switch (this.currentState()) { + // unary op or selector in property / for + case 'for': + case 'selector': + return this.property(); + // Part of a selector + case 'root': + return this.selector(); + // Do not disrupt the ident when an operand + default: + return this.operand + ? this.id() + : this.expression(); + } + } + // Selector or property + default: + switch (this.currentState()) { + case 'root': + return this.selector(); + case 'for': + case 'page': + case 'media': + case 'selector': + case 'function': + case 'keyframe': + case 'conditional': + return this.property(); + default: + return this.id(); + } + } + }, + + /** + * (ident | '{' expression '}')+ + */ + + interpolate: function() { + var node + , segs = []; + while (true) { + if (this.accept('{')) { + this.state.push('interpolation'); + segs.push(this.expression()); + this.expect('}'); + this.state.pop(); + } else if (node = this.accept('ident')){ + segs.push(node.val); + } else { + break; + } + } + if (!segs.length) this.expect('ident'); + return segs; + }, + + /** + * property ':'? expression + * | ident + */ + + property: function() { + if (this.looksLikeSelector()) return this.selector(); + + // property + var ident = this.interpolate() + , ret = prop = new nodes.Property(ident); + + // optional ':' + this.accept('space'); + if (this.accept(':')) this.accept('space'); + + this.state.push('property'); + this.inProperty = true; + prop.expr = this.list(); + if (prop.expr.isEmpty) ret = ident[0]; + this.inProperty = false; + this.allowPostfix = true; + this.state.pop(); + + // optional ';' + this.accept(';'); + + return ret; + }, + + /** + * selector ',' selector + * | selector newline selector + * | selector block + */ + + selector: function() { + var tok + , arr + , val + , prev + , parent + , group = new nodes.Group; + + // Allow comments in selectors + // for hacks + this.lexer.allowComments = true; + + do { + val = prev = null; + arr = []; + + // Clobber newline after , + this.accept('newline'); + + // Selector candidates, + // stitched together to + // form a selector. + while (tok = this.selectorToken()) { + // Selector component + switch (tok.type) { + case 'unit': val = tok.val.val; break; + case 'ident': val = tok.val.name; break; + case 'function': val = tok.val.name + '('; break; + case 'string': val = tok.val.toString(); break; + case 'color': val = tok.val.raw; break; + case 'space': val = ' '; break; + default: val = tok.val; + } + + // Whitespace support + if (!prev || prev.space) { + arr.push(val); + } else { + arr[arr.length-1] += val; + } + prev = tok; + } + + // Push the selector + group.push(new nodes.Selector(arr.join(' '), parent)); + } while (this.accept(',') || this.accept('newline')); + + this.lexer.allowComments = false; + this.state.push('selector'); + group.block = this.block(group); + this.state.pop(); + + + return group; + }, + + /** + * ident ('=' | '?=') expression + */ + + assignment: function() { + var op + , node + , name = this.id().name; + + if (op = + this.accept('=') + || this.accept('?=') + || this.accept('+=') + || this.accept('-=') + || this.accept('*=') + || this.accept('/=') + || this.accept('%=')) { + this.state.push('assignment'); + var expr = this.list(); + if (expr.isEmpty) this.error('invalid right-hand side operand in assignment, got {peek}') + node = new nodes.Ident(name, expr); + this.state.pop(); + + switch (op.type) { + case '?=': + var defined = new nodes.BinOp('is defined', node) + , lookup = new nodes.Ident(name); + node = new nodes.Ternary(defined, lookup, node); + break; + case '+=': + case '-=': + case '*=': + case '/=': + case '%=': + node.val = new nodes.BinOp(op.type[0], new nodes.Ident(name), expr); + break; + } + } + + return node; + }, + + /** + * definition + * | call + */ + + function: function() { + var parens = 1 + , i = 2 + , tok; + + // Lookahead and determine if we are dealing + // with a function call or definition. Here + // we pair parens to prevent false negatives + out: + while (tok = this.lookahead(i++)) { + switch (tok.type) { + case 'function': case '(': ++parens; break; + case ')': if (!--parens) break out; + } + } + + // Definition or call + switch (this.currentState()) { + case 'expression': + return this.functionCall(); + default: + return this.looksLikeFunctionDefinition(i) + ? this.functionDefinition() + : this.expression(); + } + }, + + /** + * url '(' (expression | urlchars)+ ')' + */ + + url: function() { + this.expect('function'); + this.state.push('function arguments'); + var args = this.args(); + this.expect(')'); + this.state.pop(); + return new nodes.Call('url', args); + }, + + /** + * ident '(' expression ')' + */ + + functionCall: function() { + if ('url' == this.peek().val.name) return this.url(); + var name = this.expect('function').val.name; + this.state.push('function arguments'); + var args = this.args(); + this.expect(')'); + this.state.pop(); + return new nodes.Call(name, args); + }, + + /** + * ident '(' params ')' block + */ + + functionDefinition: function() { + var name = this.expect('function').val.name; + + // params + this.state.push('function params'); + this.skipWhitespace(); + var params = this.params(); + this.skipWhitespace(); + this.expect(')'); + this.state.pop(); + + // Body + this.state.push('function'); + var fn = new nodes.Function(name, params); + fn.block = this.block(fn); + this.state.pop(); + return new nodes.Ident(name, fn); + }, + + /** + * ident + * | ident '...' + * | ident '=' expression + * | ident ',' ident + */ + + params: function() { + var tok + , node + , params = new nodes.Params; + while (tok = this.accept('ident')) { + this.accept('space'); + params.push(node = tok.val); + if (this.accept('...')) { + node.rest = true; + } else if (this.accept('=')) { + node.val = this.expression(); + } + this.skipWhitespace(); + this.accept(','); + this.skipWhitespace(); + } + return params; + }, + + /** + * expression (',' expression)* + */ + + args: function() { + var args = new nodes.Expression; + do { + args.push(this.expression()); + } while (this.accept(',')); + return args; + }, + + /** + * expression (',' expression)* + */ + + list: function() { + var node = this.expression(); + while (this.accept(',')) { + if (node.isList) { + list.push(this.expression()); + } else { + var list = new nodes.Expression(true); + list.push(node); + list.push(this.expression()); + node = list; + } + } + return node; + }, + + /** + * negation+ + */ + + expression: function() { + var node + , expr = new nodes.Expression; + this.state.push('expression'); + while (node = this.negation()) { + if (!node) this.error('unexpected token {peek} in expression'); + expr.push(node); + } + this.state.pop(); + return expr; + }, + + /** + * 'not' ternary + * | ternary + */ + + negation: function() { + if (this.accept('not')) { + return new nodes.UnaryOp('!', this.negation()); + } + return this.ternary(); + }, + + /** + * logical ('?' expression ':' expression)? + */ + + ternary: function() { + var node = this.logical(); + if (this.accept('?')) { + var trueExpr = this.expression(); + this.expect(':'); + var falseExpr = this.expression(); + node = new nodes.Ternary(node, trueExpr, falseExpr); + } + return node; + }, + + /** + * typecheck (('&&' | '||') typecheck)* + */ + + logical: function() { + var op + , node = this.typecheck(); + while (op = this.accept('&&') || this.accept('||')) { + node = new nodes.BinOp(op.type, node, this.typecheck()); + } + return node; + }, + + /** + * equality ('is a' equality)* + */ + + typecheck: function() { + var op + , node = this.equality(); + while (op = this.accept('is a')) { + this.operand = true; + if (!node) throw new Error('illegal unary ' + op); + node = new nodes.BinOp(op.type, node, this.equality()); + this.operand = false; + } + return node; + }, + + /** + * in (('==' | '!=') in)* + */ + + equality: function() { + var op + , node = this.in(); + while (op = this.accept('==') || this.accept('!=')) { + this.operand = true; + if (!node) throw new Error('illegal unary ' + op); + node = new nodes.BinOp(op.type, node, this.in()); + this.operand = false; + } + return node; + }, + + /** + * relational ('in' relational)* + */ + + in: function() { + var node = this.relational(); + while (this.accept('in')) { + this.operand = true; + if (!node) throw new Error('illegal unary in'); + node = new nodes.BinOp('in', node, this.relational()); + this.operand = false; + } + return node; + }, + + /** + * range (('>=' | '<=' | '>' | '<') range)* + */ + + relational: function() { + var op + , node = this.range(); + while (op = + this.accept('>=') + || this.accept('<=') + || this.accept('<') + || this.accept('>') + ) { + this.operand = true; + if (!node) throw new Error('illegal unary ' + op); + node = new nodes.BinOp(op.type, node, this.range()); + this.operand = false; + } + return node; + }, + + /** + * additive (('..' | '...') additive)* + */ + + range: function() { + var op + , node = this.additive(); + if (op = this.accept('...') || this.accept('..')) { + this.operand = true; + if (!node) throw new Error('illegal unary ' + op); + node = new nodes.BinOp(op.val, node, this.additive()); + this.operand = false; + } + return node; + }, + + /** + * multiplicative (('+' | '-') multiplicative)* + */ + + additive: function() { + var op + , node = this.multiplicative(); + while (op = this.accept('+') || this.accept('-')) { + this.operand = true; + node = new nodes.BinOp(op.type, node, this.multiplicative()); + this.operand = false; + } + return node; + }, + + /** + * defined (('**' | '*' | '/' | '%') defined)* + */ + + multiplicative: function() { + var op + , node = this.defined(); + while (op = + this.accept('**') + || this.accept('*') + || this.accept('/') + || this.accept('%')) { + this.operand = true; + if ('/' == op && this.inProperty && !this.parens) { + var expr = new nodes.Expression; + expr.push(node); + expr.push(new nodes.Literal('/')); + return expr; + } else { + if (!node) throw new Error('illegal unary ' + op); + node = new nodes.BinOp(op.type, node, this.defined()); + this.operand = false; + } + } + return node; + }, + + /** + * unary 'is defined' + * | unary + */ + + defined: function() { + var node = this.unary(); + if (this.accept('is defined')) { + if (!node) throw new Error('illegal use of "is defined"'); + node = new nodes.BinOp('is defined', node); + } + return node; + }, + + /** + * ('!' | '~' | '+' | '-') unary + * | subscript + */ + + unary: function() { + var op + , node; + if (op = + this.accept('!') + || this.accept('~') + || this.accept('+') + || this.accept('-')) { + this.operand = true; + node = new nodes.UnaryOp(op.type, this.unary()); + this.operand = false; + return node; + } + return this.subscript(); + }, + + /** + * primary ('[' expression ']')+ + * | primary + */ + + subscript: function() { + var node = this.primary(); + while (this.accept('[')) { + node = new nodes.BinOp('[]', node, this.expression()); + this.expect(']'); + } + return node; + }, + + /** + * unit + * | null + * | color + * | string + * | ident + * | boolean + * | literal + * | '(' expression ')' + */ + + primary: function() { + var op + , node; + + // Parenthesis + if (this.accept('(')) { + this.parens = true; + var expr = this.expression(); + this.expect(')'); + this.parens = false; + return expr; + } + + // Primitive + switch (this.peek().type) { + case 'null': + case 'unit': + case 'color': + case 'string': + case 'literal': + case 'boolean': + return this.next().val; + case 'ident': + return this.ident(); + case 'function': + return this.functionCall(); + } + } +}; diff --git a/node_modules/jade/support/stylus/lib/renderer.js b/node_modules/jade/support/stylus/lib/renderer.js new file mode 100644 index 0000000..db98bf7 --- /dev/null +++ b/node_modules/jade/support/stylus/lib/renderer.js @@ -0,0 +1,103 @@ + +/*! + * Stylus - Renderer + * Copyright(c) 2010 LearnBoost + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var Parser = require('./parser') + , Compiler = require('./visitor/compiler') + , Evaluator = require('./visitor/evaluator') + , utils = require('./utils') + , nodes = require('./nodes'); + +/** + * Initialize a new `Renderer` with the given `str` and `options`. + * + * @param {String} str + * @param {Object} options + * @api public + */ + +var Renderer = module.exports = function Renderer(str, options) { + options = options || {}; + options.functions = {}; + options.imports = [__dirname + '/functions']; + options.filename = options.filename || 'stylus'; + this.str = str; + this.options = options; + this.parser = new Parser(str, options); +}; + +/** + * Parse and evaluate AST, then callback `fn(err, css)`. + * + * @param {Function} fn + * @api public + */ + +Renderer.prototype.render = function(fn){ + try { + var ast = this.parser.parse() + , expr; + this.evaluator = new Evaluator(ast, this.options); + ast = this.evaluator.evaluate(); + new Compiler(ast, this.options).compile(fn); + } catch (err) { + fn(utils.formatException( + this + , err + , this.options)); + } + nodes.source = null; +}; + +/** + * Set option `key` to `val`. + * + * @param {String} key + * @param {Mixed} val + * @return {Renderer} for chaining + * @api public + */ + +Renderer.prototype.set = function(key, val){ + this.options[key] = val; + return this; +}; + +/** + * Define function with the given `name`. Optionally + * the function may accept full expressions, by setting `raw` + * to `true`. + * + * @param {String} name + * @param {Function} fn + * @return {Renderer} for chaining + * @api public + */ + +Renderer.prototype.define = function(name, fn, raw){ + this.options.functions[name] = fn; + if (undefined != raw) fn.raw = raw; + return this; +}; + +/** + * Import the given `file`. + * + * @param {String} file + * @return {Renderer} for chaining + * @api public + */ + +Renderer.prototype.import = function(file){ + this.options.imports.push(file); + return this; +}; + + diff --git a/node_modules/jade/support/stylus/lib/stack/frame.js b/node_modules/jade/support/stylus/lib/stack/frame.js new file mode 100644 index 0000000..580f9cb --- /dev/null +++ b/node_modules/jade/support/stylus/lib/stack/frame.js @@ -0,0 +1,66 @@ + +/*! + * Stylus - stack - Frame + * Copyright(c) 2010 LearnBoost + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var Scope = require('./scope') + , blocks = require('../nodes'); + +/** + * Initialize a new `Frame` with the given `block`. + * + * @param {Block} block + * @api private + */ + +var Frame = module.exports = function Frame(block) { + this._scope = false === block.scope + ? null + : new Scope; + this.block = block; +}; + +/** + * Return this frame's scope or the parent scope + * for scope-less blocks. + * + * @return {Scope} + * @api public + */ + +Frame.prototype.__defineGetter__('scope', function(){ + return this._scope || this.parent.scope; +}); + +/** + * Lookup the given local variable `name`. + * + * @param {String} name + * @return {Node} + * @api private + */ + +Frame.prototype.lookup = function(name){ + return this.scope.lookup(name) +}; + +/** + * Custom inspect. + * + * @return {String} + * @api public + */ + +Frame.prototype.inspect = function(){ + return '[Frame ' + + (false === this.block.scope + ? 'scope-less' + : this.scope.inspect()) + + ']'; +}; diff --git a/node_modules/jade/support/stylus/lib/stack/index.js b/node_modules/jade/support/stylus/lib/stack/index.js new file mode 100644 index 0000000..fc6fa53 --- /dev/null +++ b/node_modules/jade/support/stylus/lib/stack/index.js @@ -0,0 +1,146 @@ + +/*! + * Stylus - Stack + * Copyright(c) 2010 LearnBoost + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var Frame = require('./frame'); + +/** + * Initialize a new `Stack`. + * + * @api private + */ + +var Stack = module.exports = function Stack() { + Array.apply(this, arguments); +}; + +/** + * Inherit from `Array.prototype`. + */ + +Stack.prototype.__proto__ = Array.prototype; + +/** + * Push the given `frame`. + * + * @param {Frame} frame + * @api public + */ + +Stack.prototype.push = function(frame){ + frame.stack = this; + frame.parent = this.currentFrame; + return [].push.apply(this, arguments); +}; + +/** + * Return the current stack `Frame`. + * + * @return {Frame} + * @api private + */ + +Stack.prototype.__defineGetter__('currentFrame', function(){ + return this[this.length - 1]; +}); + +/** + * Lookup stack frame for the given `block`. + * + * @param {Block} block + * @return {Frame} + * @api private + */ + +Stack.prototype.getBlockFrame = function(block){ + for (var i = 0; i < this.length; ++i) { + if (block == this[i].block) { + return this[i]; + } + } +}; + +/** + * Lookup the given local variable `name`, relative + * to the lexical scope of the current frame's `Block`. + * + * When the result of a lookup is an identifier + * a recursive lookup is performed, defaulting to + * returning the identifier itself. + * + * @param {String} name + * @return {Node} + * @api private + */ + +Stack.prototype.lookup = function(name){ + var block = this.currentFrame.block + , val + , ret; + + do { + var frame = this.getBlockFrame(block); + if (frame && (val = frame.lookup(name))) { + switch (val.first.nodeName) { + case 'ident': + return this.lookup(val.first.name) || val; + default: + return val; + } + } + } while (block = block.parent); +}; + +/** + * Custom inspect. + * + * @return {String} + * @api private + */ + +Stack.prototype.inspect = function(){ + return this.reverse().map(function(frame){ + return frame.inspect(); + }).join('\n'); +}; + +/** + * Return stack string formatted as: + * + * at (:) + * + * @return {String} + * @api private + */ + +Stack.prototype.toString = function(){ + var block + , node + , buf = [] + , location + , len = this.length; + + while (len--) { + block = this[len].block; + if (node = block.node) { + location = '(' + node.filename + ':' + node.lineno + ')'; + switch (node.nodeName) { + case 'function': + buf.push(' at ' + node.name + '() ' + location); + break; + case 'group': + buf.push(' at "' + node.nodes[0].val + '" ' + location); + break; + } + } + } + + return buf.join('\n'); +}; \ No newline at end of file diff --git a/node_modules/jade/support/stylus/lib/stack/scope.js b/node_modules/jade/support/stylus/lib/stack/scope.js new file mode 100644 index 0000000..e2dc4da --- /dev/null +++ b/node_modules/jade/support/stylus/lib/stack/scope.js @@ -0,0 +1,53 @@ + +/*! + * Stylus - stack - Scope + * Copyright(c) 2010 LearnBoost + * MIT Licensed + */ + +/** + * Initialize a new `Scope`. + * + * @api private + */ + +var Scope = module.exports = function Scope() { + this.locals = {}; +}; + +/** + * Add `ident` node to the current scope. + * + * @param {Ident} ident + * @api private + */ + +Scope.prototype.add = function(ident){ + this.locals[ident.name] = ident.val; +}; + +/** + * Lookup the given local variable `name`. + * + * @param {String} name + * @return {Node} + * @api private + */ + +Scope.prototype.lookup = function(name){ + return this.locals[name]; +}; + +/** + * Custom inspect. + * + * @return {String} + * @api public + */ + +Scope.prototype.inspect = function(){ + var keys = Object.keys(this.locals).map(function(key){ return '@' + key; }); + return '[Scope' + + (keys.length ? ' ' + keys.join(', ') : '') + + ']'; +}; diff --git a/node_modules/jade/support/stylus/lib/stylus.js b/node_modules/jade/support/stylus/lib/stylus.js new file mode 100644 index 0000000..8349248 --- /dev/null +++ b/node_modules/jade/support/stylus/lib/stylus.js @@ -0,0 +1,132 @@ + +/*! + * Stylus + * Copyright(c) 2010 LearnBoost + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var Renderer = require('./renderer') + , nodes = require('./nodes') + , utils = require('./utils'); + +/** + * Export render as the module. + */ + +exports = module.exports = render; + +/** + * Library version. + */ + +exports.version = '0.9.2'; + +/** + * Expose nodes. + */ + +exports.nodes = nodes; + +/** + * Expose BIFs. + */ + +exports.functions = require('./functions'); + +/** + * Expose utils. + */ + +exports.utils = require('./utils'); + +/** + * Expose middleware. + */ + +exports.middleware = require('./middleware'); + +/** + * Expose constructors. + */ + +exports.Parser = require('./parser'); +exports.Evaluator = require('./visitor/evaluator'); + +/** + * Convert the given `css` to `stylus` source. + * + * @param {String} css + * @return {String} + * @api public + */ + +exports.convertCSS = require('./convert/css'); + +/** + * Parse the given `str` with `options` and return the AST. + * + * Examples: + * + * css.parse(str); + * // raw ast comprised of nodes + * + * css.parse(str).toObject(); + * // plain object representation + * + * css.parse(str).toJSON(); + * // JSON representation + * + * @param {String} str + * @param {Object} options + * @return {Object} + * @api public + */ + +exports.parse = function(str, options){ + var renderer = new Renderer(str, options); + try { + return renderer.parser.parse(); + } catch (err) { + throw utils.formatException( + renderer + , err + , options); + } +}; + +/** + * Render the given `str` with `options` and callback `fn(err, css)`. + * + * @param {String} str + * @param {Object|Function} options + * @param {Function} fn + * @api public + */ + +exports.render = function(str, options, fn){ + if ('function' == typeof options) fn = options, options = {}; + new Renderer(str, options).render(fn); +}; + +/** + * Return a new `Renderer` for the given `str` and `options`. + * + * @param {String} str + * @param {Object} options + * @return {Renderer} + * @api public + */ + +function render(str, options) { + return new Renderer(str, options); +} + +/** + * Expose optional functions. + */ + +exports.url = require('./functions/url'); diff --git a/node_modules/jade/support/stylus/lib/token.js b/node_modules/jade/support/stylus/lib/token.js new file mode 100644 index 0000000..80f2a34 --- /dev/null +++ b/node_modules/jade/support/stylus/lib/token.js @@ -0,0 +1,53 @@ + +/*! + * Stylus - Token + * Copyright(c) 2010 LearnBoost + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var inspect = require('sys').inspect; + +/** + * Initialize a new `Token` with the given `type` and `val`. + * + * @param {String} type + * @param {Mixed} val + * @api private + */ + +var Token = exports = module.exports = function Token(type, val) { + this.type = type; + this.val = val; +}; + +/** + * Custom inspect. + * + * @return {String} + * @api public + */ + +Token.prototype.inspect = function(){ + var val = ' ' + inspect(this.val); + return '[Token:' + this.lineno + ' ' + + '\x1b[32m' + this.type + '\x1b[0m' + + '\x1b[33m' + (this.val ? val : '') + '\x1b[0m' + + ']'; +}; + +/** + * Return type or val. + * + * @return {String} + * @api public + */ + +Token.prototype.toString = function(){ + return (undefined === this.val + ? this.type + : this.val).toString(); +}; diff --git a/node_modules/jade/support/stylus/lib/utils.js b/node_modules/jade/support/stylus/lib/utils.js new file mode 100644 index 0000000..aa06b31 --- /dev/null +++ b/node_modules/jade/support/stylus/lib/utils.js @@ -0,0 +1,175 @@ + +/*! + * Stylus - utils + * Copyright(c) 2010 LearnBoost + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var nodes = require('./nodes') + , inspect = require('sys').inspect + , fs = require('fs'); + +/** + * Attempt to lookup `path` within `paths` from tail to head. + * Optionally a path to `ignore` may be passed. + * + * @param {String} path + * @param {String} paths + * @param {String} ignore + * @return {String} + * @api private + */ + +exports.lookup = function(path, paths, ignore){ + var lookup + , i = paths.length; + + // Absolute + if ('/' == path[0]) { + try { + fs.statSync(path); + return path; + } catch (err) { + // Ignore, continue on + // to trying relative lookup. + // Needed for url(/images/foo.png) + // for example + } + } + + // Relative + while (i--) { + try { + lookup = paths[i] + '/' + path; + if (ignore == lookup) continue; + fs.statSync(lookup); + return lookup; + } catch (err) { + // Ignore + } + } +}; + +/** + * Format the given `err` in context to `renderer`. + * + * @param {Renderer} renderer + * @param {Error} err + * @param {Object} options + * @return {Error} + * @api private + */ + +exports.formatException = function(renderer, err, options){ + var lineno = renderer.evaluator + ? renderer.evaluator.lineno + : renderer.parser.lexer.lineno + , contextLineno = lineno - 2 + , contextLines = options.context || 8 + , lastWidth = (contextLineno + contextLines).toString().length; + + var src = (err.str || renderer.str).split('\n') + .slice(contextLineno, contextLineno + contextLines) + .map(function(line){ + var n = ++contextLineno + , width = n.toString().length + , pad = Array(lastWidth - width + 1).join(' '); + return ' ' + pad + n + ': ' + inspect(line); + }).join('\n'); + + err.message = renderer.options.filename + + ':' + lineno + + '\n' + src + + '\n\n' + err.message + '\n' + + (err.stylusStack ? err.stylusStack + '\n' : ''); + + return err; +}; + +/** + * Assert that `node` is of the given `type`, or throw. + * + * @param {Node} node + * @param {Function} type + * @param {String} param + * @api public + */ + +exports.assertType = function(node, type, param){ + exports.assertPresent(node, param); + if (node instanceof type) return; + var actual = node.constructor.name + , msg = 'expected ' + type.name + ', but got ' + actual + ':' + node; + throw new Error('TypeError: ' + msg); +}; + +/** + * Assert that `node` is a `String` or `Ident`. + * + * @param {Node} node + * @param {String} param + * @api public + */ + +exports.assertString = function(node, param){ + exports.assertPresent(node, param); + if (node instanceof nodes.String) return; + if (node instanceof nodes.Ident) return; + var actual = node.constructor.name + , msg = 'expected String or Ident, but got ' + actual + ':' + node; + throw new Error('TypeError: ' + msg); +}; + +/** + * Assert that `node` is a `RGBA` or `HSLA`. + * + * @param {Node} node + * @param {String} param + * @api public + */ + +exports.assertColor = function(node, param){ + exports.assertPresent(node, param); + if (node instanceof nodes.RGBA) return; + if (node instanceof nodes.HSLA) return; + var actual = node.constructor.name + , msg = 'expected RGBA or HSLA, but got ' + actual + ':' + node; + throw new Error('TypeError: ' + msg); +}; + +/** + * Assert that param `name` is given, aka the `node` is passed. + * + * @param {Node} node + * @param {String} name + * @api public + */ + +exports.assertPresent = function(node, name){ + if (node) return; + if (name) throw new Error('ArgumentError: argument ' + name + ' required'); + throw new Error('ArgumentError: argument missing'); +}; + +/** + * Unwrap `expr`. + * + * Takes an expressions with length of 1 + * such as `((1 2 3))` and unwraps it to `(1 2 3)`. + * + * @param {Expression} expr + * @return {Node} + * @api public + */ + +exports.unwrap = function(expr){ + if (expr.preserve) return expr; + if ('expression' != expr.nodeName) return expr; + if (1 != expr.nodes.length) return expr; + if ('expression' != expr.nodes[0].nodeName) return expr; + return exports.unwrap(expr.nodes[0]); +}; \ No newline at end of file diff --git a/node_modules/jade/support/stylus/lib/visitor/compiler.js b/node_modules/jade/support/stylus/lib/visitor/compiler.js new file mode 100644 index 0000000..f39ee04 --- /dev/null +++ b/node_modules/jade/support/stylus/lib/visitor/compiler.js @@ -0,0 +1,370 @@ + +/*! + * Stylus - Compiler + * Copyright(c) 2010 LearnBoost + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var Visitor = require('./') + , nodes = require('../nodes'); + +/** + * Initialize a new `Compiler` with the given `root` Node + * and the following `options`. + * + * Options: + * + * - `compress` Compress the css output, defaults to false + * + * @param {Node} root + * @api public + */ + +var Compiler = module.exports = function Compiler(root, options) { + options = options || {}; + this.compress = options.compress; + this.indents = 1; + Visitor.call(this, root); + this.tree = []; +}; + +/** + * Inherit from `Visitor.prototype`. + */ + +Compiler.prototype.__proto__ = Visitor.prototype; + +/** + * Compile to css, and callback `fn(err, css)`. + * + * @param {Function} fn + * @api public + */ + +Compiler.prototype.compile = function(fn){ + this.callback = fn; + this.css = this.visit(this.root); + fn(null, this.css); +}; + +/** + * Return indentation string. + * + * @return {String} + * @api private + */ + +Compiler.prototype.__defineGetter__('indent', function(){ + return this.compress + ? '' + : new Array(this.indents).join(' '); +}); + +/** + * Visit Root. + */ + +Compiler.prototype.visitRoot = function(block){ + this.buf = ''; + for (var i = 0, len = block.nodes.length; i < len; ++i) { + var node = block.nodes[i]; + if (node instanceof nodes.Null + || node instanceof nodes.Expression + || node instanceof nodes.Function + || node instanceof nodes.Unit) continue; + var ret = this.visit(node); + if (ret) this.buf += ret + '\n'; + } + return this.buf; +}; + +/** + * Visit Block. + */ + +Compiler.prototype.visitBlock = function(block){ + if (block.hasProperties) { + var arr = [this.compress ? '{' : ' {']; + ++this.indents; + for (var i = 0, len = block.nodes.length; i < len; ++i) { + this.last = len - 1 == i; + var node = block.nodes[i]; + if (node instanceof nodes.Null + || node instanceof nodes.Expression + || node instanceof nodes.Function + || node instanceof nodes.Group + || node instanceof nodes.Unit) continue; + arr.push(this.visit(node)); + } + --this.indents; + arr.push(this.indent + '}'); + this.buf += arr.join(this.compress ? '' : '\n'); + this.buf += '\n'; + } + + // Nesting + for (var i = 0, len = block.nodes.length; i < len; ++i) { + this.visit(block.nodes[i]); + } +}; + +/** + * Visit Keyframes. + */ + +Compiler.prototype.visitKeyframes = function(node){ + this.buf += '@-webkit-keyframes ' + + this.visit(node.name) + + (this.compress ? '{' : ' {'); + ++this.indents; + node.frames.forEach(function(frame){ + if (!this.compress) this.buf += '\n '; + this.buf += this.visit(frame.pos); + this.visit(frame.block); + }, this); + --this.indents; + this.buf += '}' + (this.compress ? '' : '\n'); +}; + +/** + * Visit Media. + */ + +Compiler.prototype.visitMedia = function(media){ + this.buf += '@media ' + media.val; + this.buf += this.compress ? '{' : ' {\n'; + ++this.indents; + this.visit(media.block); + --this.indents; + this.buf += '}' + (this.compress ? '' : '\n'); +}; + +/** + * Visit Page. + */ + +Compiler.prototype.visitPage = function(page){ + this.buf += this.indent + '@page'; + this.buf += page.selector ? ' ' + page.selector : ''; + this.visit(page.block); +}; + +/** + * Visit Function. + */ + +Compiler.prototype.visitFunction = function(fn){ + return fn.name; +}; + +/** + * Visit Variable. + */ + +Compiler.prototype.visitVariable = function(variable){ + return ''; +}; + +/** + * Visit Charset. + */ + +Compiler.prototype.visitCharset = function(charset){ + return '@charset ' + this.visit(charset.val); +}; + +/** + * Visit Literal. + */ + +Compiler.prototype.visitLiteral = function(lit){ + return lit.val.trim().replace(/^ /gm, ''); +}; + +/** + * Visit Boolean. + */ + +Compiler.prototype.visitBoolean = function(bool){ + return bool.toString(); +}; + +/** + * Visit RGBA. + */ + +Compiler.prototype.visitRGBA = function(rgba){ + return rgba.toString(); +}; + +/** + * Visit HSLA. + */ + +Compiler.prototype.visitHSLA = function(hsla){ + return hsla.rgba.toString(); +}; + +/** + * Visit Unit. + */ + +Compiler.prototype.visitUnit = function(unit){ + var type = unit.type || '' + , n = unit.val + , float = n != (n | 0); + + // Int + if ('px' == type) n = n.toFixed(0); + // Compress + if (this.compress) { + // Zero is always '0' + if (0 == n) return '0'; + // Omit leading '0' on floats + if (float && n < 1 && n > -1) { + return n.toString().replace('0.', '.') + type; + } + } + + return n.toString() + type; +}; + +/** + * Visit Group. + */ + +Compiler.prototype.visitGroup = function(group){ + var self = this + , tree = this.tree + , prev = tree[tree.length - 1] + , curr = []; + + // Construct an array of arrays + // representing the selector hierarchy + group.nodes.forEach(function(node){ + curr.push(node.parent + ? node + : node.val); + }); + + tree.push(curr); + + // Reverse recurse the + // hierarchy array to build + // up the selector permutations. + // When we reach root, we have our + // selector string built + var selectors = [] + , buf = []; + function join(arr, i) { + if (i) { + arr[i].forEach(function(str){ + buf.unshift(str); + join(arr, i - 1); + buf.shift(); + }); + } else { + arr[0].forEach(function(selector){ + var str = selector; + if (buf.length) { + for (var i = 0, len = buf.length; i < len; ++i) { + if (~buf[i].indexOf('&')) { + str = buf[i].replace('&', str); + } else { + str += ' ' + buf[i]; + } + } + } + selectors.push(self.indent + str); + }); + } + } + + // Join selectors + if (group.block.hasProperties) { + join(tree, tree.length - 1); + this.buf += selectors.join(this.compress ? ',' : ',\n'); + } + + // Output blocks + this.visit(group.block); + tree.pop(); +}; + +/** + * Visit Ident. + */ + +Compiler.prototype.visitIdent = function(ident){ + return ident.name; +}; + +/** + * Visit String. + */ + +Compiler.prototype.visitString = function(string){ + return this.isURL + ? string.val + : string.toString(); +}; + +/** + * Visit Null. + */ + +Compiler.prototype.visitNull = function(node){ + return ''; +}; + +/** + * Visit Call. + */ + +Compiler.prototype.visitCall = function(call){ + this.isURL = 'url' == call.name; + var args = call.args.nodes.map(function(arg){ + return this.visit(arg); + }, this).join(this.compress ? ',' : ', '); + if (this.isURL) args = '"' + args + '"'; + delete this.isURL; + return call.name + '(' + args + ')'; +}; + +/** + * Visit Import. + */ + +Compiler.prototype.visitImport = function(import){ + return '@import ' + this.visit(import.path) + ';'; +}; + +/** + * Visit Expression. + */ + +Compiler.prototype.visitExpression = function(expr){ + return expr.nodes.map(function(node){ + return this.visit(node); + }, this).join(expr.isList + ? (this.compress ? ',' : ', ') + : (this.isURL ? '' : ' ')); +}; + +/** + * Visit Property. + */ + +Compiler.prototype.visitProperty = function(prop){ + var self = this + , val = this.visit(prop.expr); + return this.indent + (prop.name || prop.segments.join('')) + + (this.compress ? ':' + val : ': ' + val) + + (this.compress + ? (this.last ? '' : ';') + : ';'); +}; diff --git a/node_modules/jade/support/stylus/lib/visitor/evaluator.js b/node_modules/jade/support/stylus/lib/visitor/evaluator.js new file mode 100644 index 0000000..1b166b4 --- /dev/null +++ b/node_modules/jade/support/stylus/lib/visitor/evaluator.js @@ -0,0 +1,911 @@ + +/*! + * Stylus - Evaluator + * Copyright(c) 2010 LearnBoost + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var Visitor = require('./') + , nodes = require('../nodes') + , Stack = require('../stack') + , Frame = require('../stack/frame') + , Scope = require('../stack/scope') + , utils = require('../utils') + , bifs = require('../functions') + , dirname = require('path').dirname + , colors = require('../colors') + , fs = require('fs'); + +/** + * Initialize a new `Evaluator` with the given `root` Node + * and the following `options`. + * + * Options: + * + * - `compress` Compress the css output, defaults to false + * - `warn` Warn the user of duplicate function definitions etc + * + * @param {Node} root + * @api private + */ + +var Evaluator = module.exports = function Evaluator(root, options) { + options = options || {}; + Visitor.call(this, root); + this.stack = new Stack; + this.imports = options.imports || []; + this.functions = options.functions || {}; + this.paths = options.paths || []; + this.filename = options.filename; + this.paths.push(dirname(options.filename || '.')); + this.stack.push(this.global = new Frame(root)); + this.warnings = options.warn; + this.options = options; + this.calling = []; // TODO: remove, use stack +}; + +/** + * Inherit from `Visitor.prototype`. + */ + +Evaluator.prototype.__proto__ = Visitor.prototype; + +/** + * Proxy visit to expose node line numbers. + * + * @param {Node} node + * @return {Node} + * @api private + */ + +var visit = Visitor.prototype.visit; +Evaluator.prototype.visit = function(node){ + try { + return visit.call(this, node); + } catch (err) { + // TODO: less-lame hack to reference + // the origin node source input + this.lineno = this.lineno || node.lineno; + err.str = err.str || node.source; + err.stylusStack = err.stylusStack || this.stack.toString(); + throw err; + } +}; + +/** + * Perform evaluation setup: + * + * - populate global scope + * - iterate imports + * + * @api private + */ + +Evaluator.prototype.setup = function(){ + this.populateGlobalScope(); + this.imports.forEach(function(file){ + var expr = new nodes.Expression; + expr.push(new nodes.String(file)); + this.visit(new nodes.Import(expr)); + }, this); +}; + +/** + * Populate the global scope with: + * + * - css colors + * + * @api private + */ + +Evaluator.prototype.populateGlobalScope = function(){ + var scope = this.global.scope; + Object.keys(colors).forEach(function(name){ + var rgb = colors[name] + , rgba = new nodes.RGBA(rgb[0], rgb[1], rgb[2], 1) + , node = new nodes.Ident(name, rgba); + scope.add(node); + }); +}; + +/** + * Evaluate the tree. + * + * @return {Node} + * @api private + */ + +Evaluator.prototype.evaluate = function(){ + this.setup(); + return this.visit(this.root); +}; + +/** + * Visit Group. + */ + +Evaluator.prototype.visitGroup = function(group){ + group.block = this.visit(group.block); + return group; +}; + +/** + * Visit Charset. + */ + +Evaluator.prototype.visitCharset = function(charset){ + return charset; +}; + +/** + * Visit Return. + */ + +Evaluator.prototype.visitReturn = function(ret){ + ret.expr = this.visit(ret.expr); + throw ret; +}; + +/** + * Visit Media. + */ + +Evaluator.prototype.visitMedia = function(media){ + media.block = this.visit(media.block); + return media; +}; + +/** + * Visit Keyframes. + */ + +Evaluator.prototype.visitKeyframes = function(keyframes){ + keyframes.name = this.visit(keyframes.name).first.name; + return keyframes; +}; + +/** + * Visit Function. + */ + +Evaluator.prototype.visitFunction = function(fn){ + // check local + var local = this.stack.currentFrame.scope.lookup(fn.name); + if (local) this.warn('local ' + local.nodeName + ' "' + fn.name + '" previously defined in this scope'); + + // user-defined + var user = this.functions[fn.name]; + if (user) this.warn('user-defined function "' + fn.name + '" is already defined'); + + // BIF + var bif = bifs[fn.name]; + if (bif) this.warn('built-in function "' + fn.name + '" is already defined'); + + return fn; +}; + +/** + * Visit Each. + */ + +Evaluator.prototype.visitEach = function(each){ + var expr = utils.unwrap(this.visit(utils.unwrap(each.expr))) + , len = expr.nodes.length + , val = new nodes.Ident(each.val) + , key = new nodes.Ident(each.key || '__index__') + , scope = this.currentScope + , block = this.currentBlock + , vals = [] + , body; + + each.block.scope = false; + for (var i = 0; i < len; ++i) { + val.val = expr.nodes[i]; + key.val = new nodes.Unit(i); + scope.add(val); + scope.add(key); + body = this.visit(each.block.clone()); + vals = vals.concat(body.nodes); + } + + this.mixin(vals, block); + return vals[vals.length - 1] || nodes.null; +}; + +/** + * Visit Call. + */ + +Evaluator.prototype.visitCall = function(call){ + var fn = this.lookup(call.name) + , ret; + + // Variable function + if (fn && 'expression' == fn.nodeName) { + fn = fn.nodes[0]; + } + + // Not a function? try user-defined or built-ins + if (fn && 'function' != fn.nodeName) { + fn = this.lookupFunction(call.name); + } + + // Undefined function, render literal css + if (!fn || fn.nodeName != 'function') return this.literalCall(call); + this.calling.push(call.name); + + // Massive stack + if (this.calling.length > 200) { + throw new RangeError('Maximum call stack size exceeded'); + } + + // First node in expression + if (fn instanceof nodes.Expression) fn = fn.first; + + // Evaluate arguments + var _ = this.return; + this.return = true; + var args = this.visit(call.args); + this.return = _; + + // Built-in + if (fn.fn) { + ret = this.invokeBuiltin(fn.fn, args); + // User-defined + } else if (fn instanceof nodes.Function) { + ret = this.invokeFunction(fn, args); + } + + this.calling.pop(); + return ret; +}; + +/** + * Visit Ident. + */ + +Evaluator.prototype.visitIdent = function(ident){ + // Lookup + if (nodes.null == ident.val) { + var val = this.lookup(ident.name); + return val ? this.visit(val) : ident; + // Assign + } else { + var _ = this.return; + this.return = true; + ident.val = this.visit(ident.val); + this.return = _; + this.currentScope.add(ident); + return ident.val; + } +}; + +/** + * Visit BinOp. + */ + +Evaluator.prototype.visitBinOp = function(binop){ + // Special-case "is defined" pseudo binop + if ('is defined' == binop.op) return this.isDefined(binop.left); + + var _ = this.return; + this.return = true; + // Visit operands + var op = binop.op + , ident = 'ident' == binop.left.nodeName + , left = this.visit(binop.left) + , right = this.visit(binop.right); + this.return = _; + + // First node in expression + if (!~['[]', 'in'].indexOf(op)) { + left = left.first; + right = right.first; + } + + // Coercion + switch (op) { + case '[]': + case 'in': + case '||': + case '&&': + case 'is a': + break; + default: + // Special-case '-' against ident + if ('-' == op + && 'ident' == left.nodeName + && 'unit' == right.nodeName) { + var expr = new nodes.Expression; + right.val = -right.val; + expr.push(left); + expr.push(right); + return expr; + } + + // Attempt coercion + try { + right = left.coerce(right); + } catch (err) { + // Disgregard coercion issues + // and simply return false + if ('==' == op || '!=' == op) { + return nodes.false; + } else { + throw err; + } + } + } + + // Operate + return this.visit(left.operate(op, right)); +}; + +/** + * Visit UnaryOp. + */ + +Evaluator.prototype.visitUnaryOp = function(unary){ + var op = unary.op + , node = this.visit(unary.expr).first; + + if ('!' != op) utils.assertType(node, nodes.Unit); + + switch (op) { + case '-': + node.val = -node.val; + break; + case '+': + node.val = +node.val; + break; + case '~': + node.val = ~node.val; + break; + case '!': + return node.toBoolean().negate(); + } + + return node; +}; + +/** + * Visit TernaryOp. + */ + +Evaluator.prototype.visitTernary = function(ternary){ + var ok = this.visit(ternary.cond).toBoolean(); + return nodes.true == ok + ? this.visit(ternary.trueExpr) + : this.visit(ternary.falseExpr); +}; + +/** + * Visit Expression. + */ + +Evaluator.prototype.visitExpression = function(expr){ + for (var i = 0, len = expr.nodes.length; i < len; ++i) { + expr.nodes[i] = this.visit(expr.nodes[i]); + } + return expr; +}; + +/** + * Visit Property. + */ + +Evaluator.prototype.visitProperty = function(prop){ + var name = this.interpolate(prop) + , fn = this.lookup(name) + , call = fn instanceof nodes.Function + , literal = ~this.calling.indexOf(name); + + // Function of the same name + if (call && !literal && !prop.literal) { + this.calling.push(name); + var ret = this.visit(new nodes.Call(name, prop.expr)); + this.calling.pop(); + return ret; + // Regular property + } else { + var _ = this.return; + this.return = true; + prop.expr = this.visit(prop.expr); + prop.name = name; + prop.literal = true; + this.return = _; + return prop; + } +}; + +/** + * Visit Root. + */ + +Evaluator.prototype.visitRoot = function(block){ + for (var i = 0; i < block.nodes.length; ++i) { + block.index = this.rootIndex = i; + block.nodes[i] = this.visit(block.nodes[i]); + } + return block; +}; + +/** + * Visit Block. + */ + +Evaluator.prototype.visitBlock = function(block){ + this.stack.push(new Frame(block)); + for (var i = 0; i < block.nodes.length; ++i) { + block.index = i; + try { + block.nodes[i] = this.visit(block.nodes[i]); + } catch (err) { + if (err instanceof nodes.Return) { + if (this.return) { + this.stack.pop(); + throw err; + } else { + block.nodes[i] = err; + break; + } + } else { + throw err; + } + } + } + this.stack.pop(); + return block; +}; + +/** + * Visit If. + */ + +Evaluator.prototype.visitIf = function(node){ + var ret + , _ = this.return + , block = this.currentBlock + , negate = node.negate; + + this.return = true; + var ok = this.visit(node.cond).first.toBoolean(); + this.return = _; + + // Evaluate body + if (negate) { + // unless + if (nodes.false == ok) { + ret = this.visit(node.block); + } + } else { + // if + if (nodes.true == ok) { + ret = this.visit(node.block); + // else + } else if (node.elses.length) { + var elses = node.elses + , len = elses.length; + for (var i = 0; i < len; ++i) { + // else if + if (elses[i].cond) { + if (nodes.true == this.visit(elses[i].cond).first.toBoolean()) { + ret = this.visit(elses[i].block); + break; + } + // else + } else { + ret = this.visit(elses[i]); + } + } + } + } + + // mixin conditional statements within a selector group + if (ret && !node.postfix && block.node && 'group' == block.node.nodeName) { + this.mixin(ret.nodes, block); + return nodes.null; + } + + return ret || nodes.null; +}; + +/** + * Visit Import. + */ + +Evaluator.prototype.visitImport = function(import){ + var found + , root = this.root + , i = this.rootIndex + , stylus = require('../stylus') + , path = this.visit(import.path).first + , relative = this.importPath; + + // Enusre string + if (!path.string) throw new Error('@import string expected'); + var name = path = path.string; + + // Literal + if (/\.css$/.test(path)) return import; + path += '.styl'; + + // Lookup + if (relative) this.paths.push(relative); + found = utils.lookup(path, this.paths, this.filename); + found = found || utils.lookup(name + '/index.styl', this.paths, this.filename); + if (relative) this.paths.pop(); + + // Expose imports + import.path = found; + if (this.options._imports) this.options._imports.push(import); + + // Throw if import failed + if (!found) throw new Error('failed to locate @import file ' + path); + this.importPath = dirname(found); + + // Parse the file + var str = fs.readFileSync(found, 'utf8') + , rest = root.nodes.splice(++i, root.nodes.length); + + stylus.parse(str, { + filename: found + , root: root + }); + + rest.forEach(function(node){ + root.push(node); + }); + + return nodes.null; +}; + +/** + * Invoke `fn` with `args`. + * + * @param {Function} fn + * @param {Array} args + * @return {Node} + * @api private + */ + +Evaluator.prototype.invokeFunction = function(fn, args){ + var block = new nodes.Block(fn.block.parent); + fn.block.parent = block; + + // Clone the function body + // to prevent mutation of subsequent calls + // inject argument scope + var body = fn.block.clone(); + + // mixin block + var mixinBlock = this.stack.currentFrame.block; + + // new block scope + this.stack.push(new Frame(block)); + var scope = this.currentScope; + + // arguments local + scope.add(new nodes.Ident('arguments', args)); + + // mixin scope introspection + scope.add(new nodes.Ident('mixin', this.return + ? nodes.false + : new nodes.String(mixinBlock.nodeName))); + + // inject arguments as locals + fn.params.nodes.forEach(function(node, i){ + // rest param support + if (node.rest) { + node.val = new nodes.Expression; + for (var len = args.nodes.length; i < len; ++i) { + node.val.push(args.nodes[i]); + } + node.val.preserve = true; + // argument default support + } else { + var arg = args.nodes[i]; + var val = arg && !arg.isEmpty + ? args.nodes[i] + : node.val; + node = node.clone(); + node.val = val; + // required argument not satisfied + if (node.val instanceof nodes.Null) { + throw new Error('argument ' + node + ' required for ' + fn); + } + } + + scope.add(node); + }); + + // invoke + return this.invoke(body, true); +}; + +/** + * Invoke built-in `fn` with `args`. + * + * @param {Function} fn + * @param {Array} args + * @return {Node} + * @api private + */ + +Evaluator.prototype.invokeBuiltin = function(fn, args){ + // Map arguments to first node + // providing a nicer js api for + // BIFs. Functions may specify that + // they wish to accept full expressions + // via .raw + if (fn.raw) { + args = args.nodes; + } else { + args = args.nodes.map(function(node){ + return node.first; + }); + } + + // Invoke the BIF + var body = fn.apply(this, args); + + // Always wrapping allows js functions + // to return several values with a single + // Expression node + var expr = new nodes.Expression; + expr.push(body); + body = expr; + + // Invoke + return this.invoke(body); +}; + +/** + * Invoke the given function `body`. + * + * @param {Block} body + * @return {Node} + * @api private + */ + +Evaluator.prototype.invoke = function(body, stack){ + var self = this + , ret; + + // Return + if (this.return) { + ret = this.eval(body.nodes); + if (stack) this.stack.pop(); + // Mixin + } else { + body = this.visit(body); + if (stack) this.stack.pop(); + this.mixin(body.nodes, this.currentBlock); + ret = nodes.null; + } + + return ret; +}; + +/** + * Mixin the given `nodes` to the given `block`. + * + * @param {Array} nodes + * @param {Block} block + * @api private + */ + +Evaluator.prototype.mixin = function(nodes, block){ + var len = block.nodes.length + , head = block.nodes.slice(0, block.index) + , tail = block.nodes.slice(block.index + 1, len); + this._mixin(nodes, head); + block.nodes = head.concat(tail); +}; + +/** + * Mixin the given `nodes` to the `dest` array. + * + * @param {Array} nodes + * @param {Array} dest + * @api private + */ + +Evaluator.prototype._mixin = function(nodes, dest){ + var node + , len = nodes.length; + for (var i = 0; i < len; ++i) { + switch ((node = nodes[i]).nodeName) { + case 'return': + return; + case 'block': + this._mixin(node.nodes, dest); + break; + default: + dest.push(node); + } + } +}; + +/** + * Evaluate the given `vals`. + * + * @param {Array} vals + * @return {Node} + * @api private + */ + +Evaluator.prototype.eval = function(vals){ + if (!vals) return nodes.null; + var len = vals.length + , node = nodes.null; + + try { + for (var i = 0; i < len; ++i) { + node = vals[i]; + switch (node.nodeName) { + case 'if': + if ('block' != node.block.nodeName) { + node = this.visit(node); + break; + } + case 'each': + case 'block': + node = this.visit(node); + if (node.nodes) node = this.eval(node.nodes); + break; + default: + node = this.visit(node); + } + } + } catch (err) { + if (err instanceof nodes.Return) { + return err.expr; + } else { + throw err; + } + } + + return node; +}; + +/** + * Literal function `call`. + * + * @param {Call} call + * @return {call} + * @api private + */ + +Evaluator.prototype.literalCall = function(call){ + call.args = this.visit(call.args); + return call; +}; + +/** + * Lookup `name`, with support for JavaScript + * functions, and BIFs. + * + * @param {String} name + * @return {Node} + * @api private + */ + +Evaluator.prototype.lookup = function(name){ + var val; + if (val = this.stack.lookup(name)) { + return utils.unwrap(val); + } else { + return this.lookupFunction(name); + } +}; + +/** + * Map segments in `node` returning a string. + * + * @param {Node} node + * @return {String} + * @api private + */ + +Evaluator.prototype.interpolate = function(node){ + var self = this; + return node.segments.map(function(node){ + function toString(node) { + switch (node.nodeName) { + case 'function': + case 'ident': + return node.name; + case 'literal': + case 'string': + case 'unit': + return node.val; + case 'expression': + var _ = self.return; + self.return = true; + var ret = toString(self.visit(node).first); + self.return = _; + return ret; + } + } + return toString(node); + }).join(''); +}; + +/** + * Lookup JavaScript user-defined or built-in function. + * + * @param {String} name + * @return {Function} + * @api private + */ + +Evaluator.prototype.lookupFunction = function(name){ + var fn = this.functions[name] || bifs[name]; + if (fn) return new nodes.Function(name, fn); +}; + +/** + * Check if the given `node` is an ident, and if it is defined. + * + * @param {Node} node + * @return {Boolean} + * @api private + */ + +Evaluator.prototype.isDefined = function(node){ + if (node instanceof nodes.Ident) { + return nodes.Boolean(this.lookup(node.name)); + } else { + throw new Error('invalid "is defined" check on non-variable ' + node); + } +}; + +/** + * Warn with the given `msg`. + * + * @param {String} msg + * @api private + */ + +Evaluator.prototype.warn = function(msg){ + if (!this.warnings) return; + console.warn('\033[33mWarning:\033[0m ' + msg); +}; + +/** + * Return the current `Block`. + * + * @return {Block} + * @api private + */ + +Evaluator.prototype.__defineGetter__('currentBlock', function(){ + return this.stack.currentFrame.block; +}); + +/** + * Return the current frame `Scope`. + * + * @return {Scope} + * @api private + */ + +Evaluator.prototype.__defineGetter__('currentScope', function(){ + return this.stack.currentFrame.scope; +}); + +/** + * Return the current `Frame`. + * + * @return {Frame} + * @api private + */ + +Evaluator.prototype.__defineGetter__('currentFrame', function(){ + return this.stack.currentFrame; +}); diff --git a/node_modules/jade/support/stylus/lib/visitor/index.js b/node_modules/jade/support/stylus/lib/visitor/index.js new file mode 100644 index 0000000..d7f9207 --- /dev/null +++ b/node_modules/jade/support/stylus/lib/visitor/index.js @@ -0,0 +1,32 @@ + +/*! + * Stylus - Visitor + * Copyright(c) 2010 LearnBoost + * MIT Licensed + */ + +/** + * Initialize a new `Visitor` with the given `root` Node. + * + * @param {Node} root + * @api private + */ + +var Visitor = module.exports = function Visitor(root) { + this.root = root; +}; + +/** + * Visit the given `node`. + * + * @param {Node|Array} node + * @api public + */ + +Visitor.prototype.visit = function(node, fn){ + var method = 'visit' + node.constructor.name + , cons = this.constructor.name; + if (this[method]) return this[method](node); + return node; +}; + diff --git a/node_modules/jade/support/stylus/package.json b/node_modules/jade/support/stylus/package.json new file mode 100644 index 0000000..55f36ed --- /dev/null +++ b/node_modules/jade/support/stylus/package.json @@ -0,0 +1,16 @@ +{ "name": "stylus" + , "description": "Robust, expressive language which compiles to CSS" + , "version": "0.9.2" + , "author": "TJ Holowaychuk " + , "keywords": ["css", "parser", "style", "stylesheets", "jade", "language"] + , "main": "./index.js" + , "engines": { "node": ">= 0.2.4" } + , "bin": { + "stylus": "./bin/stylus" + , "stylus-tutorial": "./bin/stylus-tutorial" + } + , "dependencies": { + "cssom": "0.2.0" + , "growl": "1.1.0" + } +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/arithmetic.color.css b/node_modules/jade/support/stylus/test/cases/arithmetic.color.css new file mode 100644 index 0000000..d6fe9f0 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/arithmetic.color.css @@ -0,0 +1,7 @@ +body { + background: rgba(0,255,255,0.5); + color: #0c0; +} +a { + color: #808080; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/arithmetic.color.styl b/node_modules/jade/support/stylus/test/cases/arithmetic.color.styl new file mode 100644 index 0000000..e27ead0 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/arithmetic.color.styl @@ -0,0 +1,7 @@ + +body + background #fff - (rgba(250,0,0,0.5) + rgba(5,0,0,0)) + color #ffcc00 - #f00 + +a + color (#fff / 2) \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/arithmetic.css b/node_modules/jade/support/stylus/test/cases/arithmetic.css new file mode 100644 index 0000000..9bc514d --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/arithmetic.css @@ -0,0 +1,12 @@ +body { + font-size: 12px; +} +h1 { + font-size: 36px; +} +h2 { + font-size: 24px; + font: 2px; + font: 0px; + font: 16px; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/arithmetic.styl b/node_modules/jade/support/stylus/test/cases/arithmetic.styl new file mode 100644 index 0000000..a4ddbf4 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/arithmetic.styl @@ -0,0 +1,18 @@ + +size = 12px +large = size * (3 - 1) +huge = size * 3 + +body + font-size size + +h1 + font-size huge + +h2 + font-size large + font 5px % 3 + font 5px % 5 + font 2px ** 4 + y = 10 + x = 15 \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/arithmetic.unary.css b/node_modules/jade/support/stylus/test/cases/arithmetic.unary.css new file mode 100644 index 0000000..5766529 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/arithmetic.unary.css @@ -0,0 +1,16 @@ +h1#logo { + margin-top: -15px; + margin-left: 3px; + foo: false; + foo: false; + foo: false; + foo: false; + foo: false; + foo: false; + foo: 0px -2px -3px; + foo: 1px; +} +body { + text-indent: -99999px; + background: #fff url("/some/image.png") no-repeat -29px 1px; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/arithmetic.unary.styl b/node_modules/jade/support/stylus/test/cases/arithmetic.unary.styl new file mode 100644 index 0000000..fc5aa6f --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/arithmetic.unary.styl @@ -0,0 +1,16 @@ + +h1#logo + margin-top - - - 15px + margin-left ~ - 4px + foo !true + foo !!0 + foo !-1 + foo !99 + foo !((99)) + foo not not 0 + foo 0px -2px -3px + foo -2px --3px + +body + text-indent -99999px + background #fff url('/some/image.png') no-repeat -29px 1px diff --git a/node_modules/jade/support/stylus/test/cases/bifs.components.css b/node_modules/jade/support/stylus/test/cases/bifs.components.css new file mode 100644 index 0000000..dc77fa4 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/bifs.components.css @@ -0,0 +1,9 @@ +body { + background: 255; + background: 204; + background: 0; + background: 0.4; + background: 15deg; + background: 100%; + background: 60%; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/bifs.components.styl b/node_modules/jade/support/stylus/test/cases/bifs.components.styl new file mode 100644 index 0000000..dc8b9a6 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/bifs.components.styl @@ -0,0 +1,9 @@ +body + background red(#fc0) + background green(#fc0) + background blue(#fc0) + background alpha(#fff - rgba(0,0,0,.6)) + + background hue(hsl(15deg,100%,60%)) + background saturation(hsl(15deg,100%,60%)) + background lightness(hsl(15deg,100%,60%)) \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/bifs.dark.css b/node_modules/jade/support/stylus/test/cases/bifs.dark.css new file mode 100644 index 0000000..a336a0f --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/bifs.dark.css @@ -0,0 +1,5 @@ +body { + foo: true; + foo: true; + foo: true; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/bifs.dark.styl b/node_modules/jade/support/stylus/test/cases/bifs.dark.styl new file mode 100644 index 0000000..fe9a18e --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/bifs.dark.styl @@ -0,0 +1,4 @@ +body + foo dark(black) == true + foo dark(#005716) == true + foo dark(white) == false diff --git a/node_modules/jade/support/stylus/test/cases/bifs.darken-by.css b/node_modules/jade/support/stylus/test/cases/bifs.darken-by.css new file mode 100644 index 0000000..ef30453 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/bifs.darken-by.css @@ -0,0 +1,5 @@ +body { + background: #808080; + background: #404040; + background: #202020; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/bifs.darken-by.styl b/node_modules/jade/support/stylus/test/cases/bifs.darken-by.styl new file mode 100644 index 0000000..85e5fea --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/bifs.darken-by.styl @@ -0,0 +1,4 @@ +body + background: darken-by(white, 50%) + background: darken-by(darken-by(white, 50%), 50%) + background: darken-by(darken-by(darken-by(white, 50%), 50%), 50%) \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/bifs.image-size.css b/node_modules/jade/support/stylus/test/cases/bifs.image-size.css new file mode 100644 index 0000000..e26d4ac --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/bifs.image-size.css @@ -0,0 +1,9 @@ +body { + foo: 315px 450px; + foo: true; + foo: true; +} +body { + foo: 400px 479px; + foo: 400px 479px; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/bifs.image-size.styl b/node_modules/jade/support/stylus/test/cases/bifs.image-size.styl new file mode 100644 index 0000000..d981a31 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/bifs.image-size.styl @@ -0,0 +1,19 @@ + +width(img) + return image-size(img)[0] + +height(img) + return image-size(img)[1] + +body + foo image-size('gif') + foo image-size('gif')[0] == width('gif') + foo image-size('gif')[1] == height('gif') + +body + foo image-size('tux.png') + foo image-size('tux.png') +/* +body + foo image-size('jpeg') + diff --git a/node_modules/jade/support/stylus/test/cases/bifs.join.css b/node_modules/jade/support/stylus/test/cases/bifs.join.css new file mode 100644 index 0000000..17097cf --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/bifs.join.css @@ -0,0 +1,11 @@ +body { + foo: "1 2 3"; + foo: "1, 2, 3"; + foo: "1,2,3"; + foo: "1"; + foo: true; +} +body { + foo: "1, 2, 3"; + foo: "one, two, three"; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/bifs.join.styl b/node_modules/jade/support/stylus/test/cases/bifs.join.styl new file mode 100644 index 0000000..6599124 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/bifs.join.styl @@ -0,0 +1,11 @@ + +body + foo join(' ', 1 2 3) + foo join(', ', 1 2 3) + foo join(',', 1 2 3) + foo join(',', 1) + foo join(',') == null + +body + foo join(', ', 1, 2, 3) + foo join(', ', one 1, two 2, three 3) \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/bifs.last.css b/node_modules/jade/support/stylus/test/cases/bifs.last.css new file mode 100644 index 0000000..a336a0f --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/bifs.last.css @@ -0,0 +1,5 @@ +body { + foo: true; + foo: true; + foo: true; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/bifs.last.styl b/node_modules/jade/support/stylus/test/cases/bifs.last.styl new file mode 100644 index 0000000..ef13055 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/bifs.last.styl @@ -0,0 +1,6 @@ + +body + nums = 1 2 3 4 + foo last(nums) == 4 + foo last(foo bar baz) == baz + foo last(()) == null \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/bifs.length.css b/node_modules/jade/support/stylus/test/cases/bifs.length.css new file mode 100644 index 0000000..670982d --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/bifs.length.css @@ -0,0 +1,10 @@ +body { + foo: 0; + foo: 1; + foo: 1; + foo: 2; + foo: 3; + foo: 4; + foo: 5; + foo: 6; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/bifs.length.styl b/node_modules/jade/support/stylus/test/cases/bifs.length.styl new file mode 100644 index 0000000..762beb6 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/bifs.length.styl @@ -0,0 +1,18 @@ +args(n = null) + length(n) + +vargs(args...) + length(args) + +arguments() + length(arguments) + +body + foo length() + foo length(args()) + foo length(1) + foo length((1 2) (3 4)) + foo length(1 2 3) + foo vargs(1, 2, 3, 4) + foo args(1 2 3 4 5) + foo arguments(1,2,3,4,5,6) \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/bifs.light.css b/node_modules/jade/support/stylus/test/cases/bifs.light.css new file mode 100644 index 0000000..a336a0f --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/bifs.light.css @@ -0,0 +1,5 @@ +body { + foo: true; + foo: true; + foo: true; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/bifs.light.styl b/node_modules/jade/support/stylus/test/cases/bifs.light.styl new file mode 100644 index 0000000..162cfe7 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/bifs.light.styl @@ -0,0 +1,4 @@ +body + foo light(black) == false + foo light(white) == true + foo light(#00FF40) == true \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/bifs.lighten-by.css b/node_modules/jade/support/stylus/test/cases/bifs.lighten-by.css new file mode 100644 index 0000000..da74b89 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/bifs.lighten-by.css @@ -0,0 +1,6 @@ +body { + background: #808080; + background: #bfbfbf; + background: #fff; + foo: #7fbfee; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/bifs.lighten-by.styl b/node_modules/jade/support/stylus/test/cases/bifs.lighten-by.styl new file mode 100644 index 0000000..8f448e7 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/bifs.lighten-by.styl @@ -0,0 +1,6 @@ +body + background: lighten-by(black, 50%) + background: lighten-by(lighten-by(black, 50%), 50%) + background: lighten-by(lighten-by(lighten-by(black, 50%), 50%), 50%) + foo lighten(#52a8e8, 10%) + // => #7fbfee diff --git a/node_modules/jade/support/stylus/test/cases/bifs.lookup.complex.css b/node_modules/jade/support/stylus/test/cases/bifs.lookup.complex.css new file mode 100644 index 0000000..cbb003b --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/bifs.lookup.complex.css @@ -0,0 +1,4 @@ +body { + color: #80e2e9; + border: 1px solid #f00; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/bifs.lookup.complex.styl b/node_modules/jade/support/stylus/test/cases/bifs.lookup.complex.styl new file mode 100644 index 0000000..cddf1fa --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/bifs.lookup.complex.styl @@ -0,0 +1,11 @@ + +border-type = solid +dark-blue = #006269 +light-blue = dark-blue + hsl(0,0,50%) + +light(color-name) + lookup('light-' + color-name) + +body + color light('blue') + border 1px lookup('border-type') red \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/bifs.lookup.css b/node_modules/jade/support/stylus/test/cases/bifs.lookup.css new file mode 100644 index 0000000..a5209ce --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/bifs.lookup.css @@ -0,0 +1,3 @@ +body { + color: #006269; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/bifs.lookup.styl b/node_modules/jade/support/stylus/test/cases/bifs.lookup.styl new file mode 100644 index 0000000..7f404f0 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/bifs.lookup.styl @@ -0,0 +1,8 @@ + +dark-blue = #006269 + +dark(color-name) + lookup('dark-' + color-name) + +body + color dark('blue') \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/bifs.match.css b/node_modules/jade/support/stylus/test/cases/bifs.match.css new file mode 100644 index 0000000..70483e0 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/bifs.match.css @@ -0,0 +1,4 @@ +body { + margin: 5px; + padding: 5px; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/bifs.match.styl b/node_modules/jade/support/stylus/test/cases/bifs.match.styl new file mode 100644 index 0000000..eb2c7b9 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/bifs.match.styl @@ -0,0 +1,9 @@ +pad(type = padding) + if match('^pad', type) + padding 5px + else + margin 5px + +body + pad(margin) + pad(padding) diff --git a/node_modules/jade/support/stylus/test/cases/bifs.opposite-position.css b/node_modules/jade/support/stylus/test/cases/bifs.opposite-position.css new file mode 100644 index 0000000..dc41fa6 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/bifs.opposite-position.css @@ -0,0 +1,8 @@ +body { + foo: ; + foo: true; + foo: true; + foo: true; + foo: true; + foo: bottom right; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/bifs.opposite-position.styl b/node_modules/jade/support/stylus/test/cases/bifs.opposite-position.styl new file mode 100644 index 0000000..1809da5 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/bifs.opposite-position.styl @@ -0,0 +1,9 @@ + +body + foo opposite-position() + foo opposite-position(top) == bottom + foo opposite-position(left) == right + foo opposite-position(top left)[0] == bottom + foo opposite-position(top left)[1] == right + val = top left + foo opposite-position(val) \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/bifs.rgba.css b/node_modules/jade/support/stylus/test/cases/bifs.rgba.css new file mode 100644 index 0000000..15da40d --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/bifs.rgba.css @@ -0,0 +1,5 @@ +body { + background: #ff0800; + background: rgba(255,255,0,0.2); + background: rgba(255,204,0,0.5); +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/bifs.rgba.styl b/node_modules/jade/support/stylus/test/cases/bifs.rgba.styl new file mode 100644 index 0000000..9c50ca4 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/bifs.rgba.styl @@ -0,0 +1,4 @@ +body + background rgba(255,8,0,1) + background rgba(255,255,0,0.2) + background rgba(#fc0, 0.5) \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/bifs.type.css b/node_modules/jade/support/stylus/test/cases/bifs.type.css new file mode 100644 index 0000000..647b227 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/bifs.type.css @@ -0,0 +1,11 @@ +body { + background: "string"; + background: "unit"; + background: "unit"; + background: "hsla"; + background: "rgba"; + background: "ident"; + background: "unit"; + background: "function"; + background: "ident"; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/bifs.type.styl b/node_modules/jade/support/stylus/test/cases/bifs.type.styl new file mode 100644 index 0000000..e67eec3 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/bifs.type.styl @@ -0,0 +1,12 @@ +body + border-type = solid + size = 15px + background type('test') + background type(12px) + background type(12) + background type(hsl(100deg, 50%, 50%)) + background type(#fff) + background type(something) + background type(size) + background type(type) + background type(border-type) \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/bifs.unit.css b/node_modules/jade/support/stylus/test/cases/bifs.unit.css new file mode 100644 index 0000000..35febfd --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/bifs.unit.css @@ -0,0 +1,6 @@ +body { + foo: 20px; + foo: 20px; + foo: 20px; + foo: 20%; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/bifs.unit.styl b/node_modules/jade/support/stylus/test/cases/bifs.unit.styl new file mode 100644 index 0000000..336dabc --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/bifs.unit.styl @@ -0,0 +1,5 @@ +body + foo unit(20, 'px') + foo unit(20, px) + foo unit(20%, px) + foo unit(20, '%') \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/bifs.unquote.css b/node_modules/jade/support/stylus/test/cases/bifs.unquote.css new file mode 100644 index 0000000..1a3643f --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/bifs.unquote.css @@ -0,0 +1,5 @@ +body { + background: testing; + background: testing; + font: 14px / 1.5; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/bifs.unquote.styl b/node_modules/jade/support/stylus/test/cases/bifs.unquote.styl new file mode 100644 index 0000000..d101806 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/bifs.unquote.styl @@ -0,0 +1,8 @@ + +line-height(n) + unquote('/ ' + n) + +body + background unquote(testing) + background unquote('testing') + font 14px line-height(1.5) diff --git a/node_modules/jade/support/stylus/test/cases/bifs.url.css b/node_modules/jade/support/stylus/test/cases/bifs.url.css new file mode 100644 index 0000000..ab4a9f4 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/bifs.url.css @@ -0,0 +1,11 @@ +body { + background: url("/images/foo.png"); + background: url("/images/foo.png"); + background: url("/images/foo.png"); + background: url("/images/foo.png"); + background: url("/images/foo.png"); + background: url("/images/foo.png"); + background: url("/images/foo.png"); + background: url("/images/foo.png"); + background: url("http://foo.com/images/bar.png"); +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/bifs.url.styl b/node_modules/jade/support/stylus/test/cases/bifs.url.styl new file mode 100644 index 0000000..691d33c --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/bifs.url.styl @@ -0,0 +1,15 @@ +body + background url("/images/foo.png") + background url(/images/foo.png) + + dir = '/images' + img = 'foo.png' + background url(dir/foo.png) + background url(dir/img) + + background url('/images/' + img) + background url(dir'/foo.png') + background url(dir + '/foo.png') + background url(dir + '/' + img) + + background url(http://foo.com/images/bar.png) \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/coercion.css b/node_modules/jade/support/stylus/test/cases/coercion.css new file mode 100644 index 0000000..1c54cd5 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/coercion.css @@ -0,0 +1,6 @@ +body { + foo: 10px; + foo: 6px; + foo: "foo bar"; + foo: "value: 5px"; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/coercion.styl b/node_modules/jade/support/stylus/test/cases/coercion.styl new file mode 100644 index 0000000..8925fc1 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/coercion.styl @@ -0,0 +1,5 @@ +body + foo 5px + '5' + foo 5px + '1 23' + foo 'foo ' + 'bar' + foo 'value: ' + 5px \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/comments.css b/node_modules/jade/support/stylus/test/cases/comments.css new file mode 100644 index 0000000..a11dd7a --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/comments.css @@ -0,0 +1,11 @@ +body { + color: #f00; +} +form { + background: #fff; +} +html>/**/body select, +x:-moz-any-link, +x:default select { + font-weight: bold !important; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/comments.styl b/node_modules/jade/support/stylus/test/cases/comments.styl new file mode 100644 index 0000000..82cb469 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/comments.styl @@ -0,0 +1,28 @@ + +// foo = 'bar' + +body + color red + // lots of stuff + // wahoo + + // super cool + + // background green + +form + background white + +/* + +body + a + color blue + +*/ +// rawr + +html>/**/body select +x:-moz-any-link +x:default select + font-weight bold !important \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/compress.units.css b/node_modules/jade/support/stylus/test/cases/compress.units.css new file mode 100644 index 0000000..d07704f --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/compress.units.css @@ -0,0 +1,2 @@ +body{foo:0;foo:0;foo:15;foo:-15;foo:15px;foo:-15px} +body{foo:.1;foo:-.1;foo:1.1;foo:-1.1;foo:.1;foo:-.1;foo:10.1;foo:-10.1} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/compress.units.styl b/node_modules/jade/support/stylus/test/cases/compress.units.styl new file mode 100644 index 0000000..3f3bf28 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/compress.units.styl @@ -0,0 +1,18 @@ +body + foo 0 + foo 0px + foo 15 + foo -15 + foo 15px + foo -15px + +body + foo 0.1 + foo -0.1 + foo 1.1 + foo -1.1 + foo 0.1 + foo -0.1 + foo 10.1 + foo -10.1 + \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/conditional-assignment.css b/node_modules/jade/support/stylus/test/cases/conditional-assignment.css new file mode 100644 index 0000000..e02b387 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/conditional-assignment.css @@ -0,0 +1,4 @@ +a.button { + font: 14px; + background: #fff; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/conditional-assignment.styl b/node_modules/jade/support/stylus/test/cases/conditional-assignment.styl new file mode 100644 index 0000000..4431b33 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/conditional-assignment.styl @@ -0,0 +1,9 @@ + +color ?= white +color ?= black + +font-size ?= 14px + +a.button + font font-size + background color diff --git a/node_modules/jade/support/stylus/test/cases/css.functions.single-line.css b/node_modules/jade/support/stylus/test/cases/css.functions.single-line.css new file mode 100644 index 0000000..08b9e7c --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/css.functions.single-line.css @@ -0,0 +1,9 @@ +body { + foo: false; + foo: true; +} +body { + foo: false; + foo: true; + foo: ; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/css.functions.single-line.styl b/node_modules/jade/support/stylus/test/cases/css.functions.single-line.styl new file mode 100644 index 0000000..4ac7a65 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/css.functions.single-line.styl @@ -0,0 +1,13 @@ + +large(n){ n > 100 } + +body + foo large(5) + foo large(300) + +large(n){ n > 100 if n is a 'unit' } + +body + foo large(5) + foo large(300) + foo large('test') \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/css.if.css b/node_modules/jade/support/stylus/test/cases/css.if.css new file mode 100644 index 0000000..5ed0353 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/css.if.css @@ -0,0 +1,8 @@ +body { + color: #fff; + color: #fff; +} +body { + padding: 5px; + margin: 5px; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/css.if.styl b/node_modules/jade/support/stylus/test/cases/css.if.styl new file mode 100644 index 0000000..2ff1b4f --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/css.if.styl @@ -0,0 +1,21 @@ + +body + if true { + color: white; + } + unless (false) { + color: white; + } + +mixin(pad, margin) { + if (pad) { + padding: 5px; + } + if (margin) { + margin: 5px; + } +} + +body + mixin(true, true) + diff --git a/node_modules/jade/support/stylus/test/cases/css.keyframes.css b/node_modules/jade/support/stylus/test/cases/css.keyframes.css new file mode 100644 index 0000000..be727ff --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/css.keyframes.css @@ -0,0 +1,48 @@ +@-webkit-keyframes bouce { + 0% { + foo: bar; + } + + 50% { + foo: bar; + } + + 100% { + foo: bar; + } +} +@-webkit-keyframes bouce { + 0% { + foo: bar; + } + + 50% { + foo: bar; + } + + 100% { + foo: bar; + } +} +@-webkit-keyframes bouce { + 0% { + foo: bar; + } + + 50% { + foo: bar; + } + + 100% { + foo: bar; + } +} +@-webkit-keyframes something { + 0% { + color: red; + } + + 100% { + color: blue; + } +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/css.keyframes.styl b/node_modules/jade/support/stylus/test/cases/css.keyframes.styl new file mode 100644 index 0000000..7ce1c3f --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/css.keyframes.styl @@ -0,0 +1,39 @@ + +@keyframes bouce { + from { + foo: bar; + } + + 50% { + foo: bar; + } + + to { + foo: bar; + } +} + +@keyframes bouce { + from { foo: bar; } + 50% { foo: bar; } + to { foo: bar; } +} + + +@keyframes bouce { + from { foo: bar; } + + + 50% { foo: bar; } + + to { foo: bar; } +} + +animate(name) { + @keyframes name { + from { color: red; } + to { color: blue; } + } +} + +animate(something) \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/css.large.css b/node_modules/jade/support/stylus/test/cases/css.large.css new file mode 100644 index 0000000..b63459b --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/css.large.css @@ -0,0 +1,172 @@ +html { + background: #dadada; + background: -moz-linear-gradient(-90deg, #fff, #dadada) fixed; + background: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#dadada)) fixed; +} +body { + padding: 120px 150px; + font: 14px / 1.4 "helvetica neue", helvetica, arial, sans-serif; + color: #484848; +} +h1, +h2, +h3 { + color: #222; +} +h1 a, +h2 a, +h3 a { + color: #222; +} +h1 a:hover, +h2 a:hover, +h3 a:hover { + text-decoration: none; +} +h1 { + margin: 10px 0 15px 0; + font-weight: bold; + font-size: 60px; +} +h2 { + margin: 0; + font-size: 18px; +} +h3 { + font-size: 14px; +} +a { + text-decoration: none; + color: #b90101; +} +a:hover { + text-decoration: underline; +} +strong { + color: #a00; +} +ul { + margin: 0; + padding: 0 25px; +} +ul li { + list-style: square; +} +.tagline { + margin: 0; + padding: 0; +} +.tagline em { + font-style: normal; +} +.tagline em.expressive { + color: #222; +} +.tagline em.dynamic { + color: #555; +} +.tagline em.robust { + color: #888; +} +.tagline em.css { + color: #bbb; +} +#container { + text-align: center; +} +#container #content { + margin: 0 auto; + padding-top: 40px; + width: 300px; + text-align: left; +} +#menu { + position: fixed; + top: -5px; + right: 60px; + margin: 0; + padding: 15px 0 10px 5px; + background: rgba(255,255,255,0.3); + border: 1px solid #ddd; + text-align: left; + -moz-box-shadow: inset rgba(34,34,34,0.1) 0 4px 4px; + -webkit-box-shadow: inset rgba(34,34,34,0.1) 0 4px 4px; + box-shadow: inset rgba(34,34,34,0.1) 0 4px 4px; + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + border-radius: 5px; +} +#menu li { + list-style: none; +} +#menu li a { + display: block; + width: 150px; + padding: 1px 10px; + color: #7b7b7b; + font-size: 13px; +} +#menu li a:hover { + color: #000; + text-decoration: none; +} +.example { + margin-top: 25px; +} +pre { + width: 300px; + padding: 30px; + color: #8d8d8d; + font: 12px / 1.4 monaco, "helvetica neue", helvetica; + overflow-x: auto; + background: #fff; + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + border-radius: 5px; + -moz-box-shadow: rgba(34,34,34,0.1) -1px -1px; + -webkit-box-shadow: rgba(34,34,34,0.1) -1px -1px; + box-shadow: rgba(34,34,34,0.1) -1px -1px; +} +pre.terminal { + width: 340px; + padding: 10px; + background: #2b2b2b; + color: #dadada; + -moz-box-shadow: #fff -1px -1px; + -webkit-box-shadow: #fff -1px -1px; + box-shadow: #fff -1px -1px; +} +p code { + padding: 2px 4px; + color: #626262; + font-size: 85%; + background: #fff; + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + border-radius: 5px; + -moz-box-shadow: rgba(34,34,34,0.1) -1px -1px; + -webkit-box-shadow: rgba(34,34,34,0.1) -1px -1px; + box-shadow: rgba(34,34,34,0.1) -1px -1px; +} +#ribbon { + position: absolute; + top: 2.5em; + left: -3.75em; + background-color: #a00; + padding: 1px 0; + overflow: hidden; + -webkit-transform: rotate(-45deg); + -moz-transform: rotate(-45deg); + -moz-box-shadow: 1px 1px 3px rgba(0,0,0,0.3); + -webkit-box-shadow: 1px 1px 3px rgba(0,0,0,0.3); + box-shadow: 1px 1px 3px rgba(0,0,0,0.3); +} +#ribbon a { + color: #fff; + border: 1px solid #f18585; + display: block; + margin: 0.05em 0; + padding: 0.5em 3.5em; + text-align: center; + text-decoration: none; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/css.large.styl b/node_modules/jade/support/stylus/test/cases/css.large.styl new file mode 100644 index 0000000..ee87684 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/css.large.styl @@ -0,0 +1,172 @@ +html { + background: #dadada; + background: -moz-linear-gradient(-90deg, #fff, #dadada) fixed; + background: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#dadada)) fixed; +} +body { + padding: 120px 150px; + font: 14px / 1.4 "helvetica neue", helvetica, arial, sans-serif; + color: #484848; +} +h1, +h2, +h3 { + color: #222; +} +h1 a, +h2 a, +h3 a { + color: #222; +} +h1 a:hover, +h2 a:hover, +h3 a:hover { + text-decoration: none; +} +h1 { + margin: 10px 0 15px 0; + font-weight: bold; + font-size: 60px; +} +h2 { + margin: 0; + font-size: 18px; +} +h3 { + font-size: 14px; +} +a { + text-decoration: none; + color: #b90101; +} +a:hover { + text-decoration: underline; +} +strong { + color: #a00; +} +ul { + margin: 0; + padding: 0 25px; +} +ul li { + list-style: square; +} +.tagline { + margin: 0; + padding: 0; +} +.tagline em { + font-style: normal; +} +.tagline em.expressive { + color: #222; +} +.tagline em.dynamic { + color: #555; +} +.tagline em.robust { + color: #888; +} +.tagline em.css { + color: #bbb; +} +#container { + text-align: center; +} +#container #content { + margin: 0 auto; + padding-top: 40px; + width: 300px; + text-align: left; +} +#menu { + position: fixed; + top: -5px; + right: 60px; + margin: 0; + padding: 15px 0 10px 5px; + background: rgba(255,255,255,0.3); + border: 1px solid #ddd; + text-align: left; + -moz-box-shadow: inset rgba(34,34,34,0.1) 0 4px 4px; + -webkit-box-shadow: inset rgba(34,34,34,0.1) 0 4px 4px; + box-shadow: inset rgba(34,34,34,0.1) 0 4px 4px; + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + border-radius: 5px; +} +#menu li { + list-style: none; +} +#menu li a { + display: block; + width: 150px; + padding: 1px 10px; + color: #7b7b7b; + font-size: 13px; +} +#menu li a:hover { + color: #000; + text-decoration: none; +} +.example { + margin-top: 25px; +} +pre { + width: 300px; + padding: 30px; + color: #8d8d8d; + font: 12px / 1.4 monaco, "helvetica neue", helvetica; + overflow-x: auto; + background: #fff; + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + border-radius: 5px; + -moz-box-shadow: rgba(34,34,34,0.1) -1px -1px; + -webkit-box-shadow: rgba(34,34,34,0.1) -1px -1px; + box-shadow: rgba(34,34,34,0.1) -1px -1px; +} +pre.terminal { + width: 340px; + padding: 10px; + background: #2b2b2b; + color: #dadada; + -moz-box-shadow: #fff -1px -1px; + -webkit-box-shadow: #fff -1px -1px; + box-shadow: #fff -1px -1px; +} +p code { + padding: 2px 4px; + color: #626262; + font-size: 85%; + background: #fff; + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + border-radius: 5px; + -moz-box-shadow: rgba(34,34,34,0.1) -1px -1px; + -webkit-box-shadow: rgba(34,34,34,0.1) -1px -1px; + box-shadow: rgba(34,34,34,0.1) -1px -1px; +} +#ribbon { + position: absolute; + top: 2.5em; + left: -3.75em; + background-color: #a00; + padding: 1px 0; + overflow: hidden; + -webkit-transform: rotate(-45deg); + -moz-transform: rotate(-45deg); + -moz-box-shadow: 1px 1px 3px rgba(0,0,0,0.3); + -webkit-box-shadow: 1px 1px 3px rgba(0,0,0,0.3); + box-shadow: 1px 1px 3px rgba(0,0,0,0.3); +} +#ribbon a { + color: #fff; + border: 1px solid #f18585; + display: block; + margin: 0.05em 0; + padding: 0.5em 3.5em; + text-align: center; + text-decoration: none; +} diff --git a/node_modules/jade/support/stylus/test/cases/css.media.css b/node_modules/jade/support/stylus/test/cases/css.media.css new file mode 100644 index 0000000..f7ab06b --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/css.media.css @@ -0,0 +1,15 @@ +@media print { + body { + margin: 5px; + padding: 5px; + } +} +@media print { + body { + margin: 5px; + padding: 5px; + } + .no-print { + display: none; + } +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/css.media.styl b/node_modules/jade/support/stylus/test/cases/css.media.styl new file mode 100644 index 0000000..2403566 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/css.media.styl @@ -0,0 +1,17 @@ + +@media print { + body { + margin: 5px; + padding: 5px; + } +} + +@media print { + body { + margin: 5px; + padding: 5px; + } + .no-print { + display: none; + } +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/css.mixins.braces.css b/node_modules/jade/support/stylus/test/cases/css.mixins.braces.css new file mode 100644 index 0000000..7ffe13c --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/css.mixins.braces.css @@ -0,0 +1,31 @@ +button, +a.button { + display: block; + text-decoration: none; + background: #e3e3e3; + border: 1px solid #bdbdbd; + border-radius: 3px; + box-shadow: inset 0 0 1px 1px rgba(255,255,255,0.8); + color: #333; + font-family: "helvetica neue", helvetica, arial, sans-serif; + font-size: 12px; + font-weight: bold; + line-height: 1; + padding: 8px 0 9px; + text-align: center; + text-shadow: 0 1px 0 #fff; + width: 150px; +} +button:hover, +a.button:hover { + background: #dbdbdb; + box-shadow: inset 0 0 1px 1px rgba(255,255,255,0.5); + color: #222; + cursor: pointer; +} +button:active, +a.button:active { + background: #d6d6d6; + box-shadow: inset 0 0 1px 1px rgba(255,255,255,0.2); + color: #000; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/css.mixins.braces.styl b/node_modules/jade/support/stylus/test/cases/css.mixins.braces.styl new file mode 100644 index 0000000..ca8f737 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/css.mixins.braces.styl @@ -0,0 +1,53 @@ + +/* + * Reset button related properties so that + * a, button, and input's are supported. + */ + +-reset() { + display: block; + text-decoration: none; +} + +// just testing stuff + +get-width() { 150px; } + +/* + * Minimalistic flat button with white inset. + */ + +minimal-button(bg = #e3e3e3, intensity = 1) { + -reset(); + background: bg; + border: 1px solid darken(bg, 15% * intensity); + border-radius: 3px; + box-shadow: inset 0 0 1px 1px rgba(white, 0.8 * intensity); + color: #333; + font-family: 'helvetica neue', helvetica, arial, sans-serif; + font-size: 12px; + font-weight: bold; + line-height: 1; + padding: 8px 0 9px; + text-align: center; + text-shadow: 0 1px 0 rgba(white, 1 * intensity); + width: get-width(); + + &:hover { + background: darken(bg, 3%); + box-shadow: inset 0 0 1px 1px rgba(white, 0.5 * intensity); + color: #222; + cursor: pointer; + } + + &:active { + background: darken(bg, 5%); + box-shadow: inset 0 0 1px 1px rgba(white, 0.2 * intensity); + color: #000; + } +} + +button, +a.button { + minimal-button(); +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/css.mixins.css b/node_modules/jade/support/stylus/test/cases/css.mixins.css new file mode 100644 index 0000000..7ffe13c --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/css.mixins.css @@ -0,0 +1,31 @@ +button, +a.button { + display: block; + text-decoration: none; + background: #e3e3e3; + border: 1px solid #bdbdbd; + border-radius: 3px; + box-shadow: inset 0 0 1px 1px rgba(255,255,255,0.8); + color: #333; + font-family: "helvetica neue", helvetica, arial, sans-serif; + font-size: 12px; + font-weight: bold; + line-height: 1; + padding: 8px 0 9px; + text-align: center; + text-shadow: 0 1px 0 #fff; + width: 150px; +} +button:hover, +a.button:hover { + background: #dbdbdb; + box-shadow: inset 0 0 1px 1px rgba(255,255,255,0.5); + color: #222; + cursor: pointer; +} +button:active, +a.button:active { + background: #d6d6d6; + box-shadow: inset 0 0 1px 1px rgba(255,255,255,0.2); + color: #000; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/css.mixins.root.css b/node_modules/jade/support/stylus/test/cases/css.mixins.root.css new file mode 100644 index 0000000..5d9922d --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/css.mixins.root.css @@ -0,0 +1,26 @@ +button, +a.button, +input[type=submit], +input[type=button] { + padding: 5px 10px; +} +button:hover, +a.button:hover, +input[type=submit]:hover, +input[type=button]:hover { + color: #fff; + background: #000; +} +button:hover em, +a.button:hover em, +input[type=submit]:hover em, +input[type=button]:hover em { + color: #808080; +} +button:active, +a.button:active, +input[type=submit]:active, +input[type=button]:active { + color: #000; + background: #fff; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/css.mixins.root.styl b/node_modules/jade/support/stylus/test/cases/css.mixins.root.styl new file mode 100644 index 0000000..b03ff8e --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/css.mixins.root.styl @@ -0,0 +1,25 @@ + +hover() + &:hover { + color: white; + background: black; + em { + color: gray; + } + } + &:active { + color: black; + background: white; + } + + +button(pad) + button, + a.button, + input[type=submit], + input[type=button] { + padding: pad; + hover(); + } + +button(5px 10px); \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/css.mixins.root.wonky.css b/node_modules/jade/support/stylus/test/cases/css.mixins.root.wonky.css new file mode 100644 index 0000000..5d9922d --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/css.mixins.root.wonky.css @@ -0,0 +1,26 @@ +button, +a.button, +input[type=submit], +input[type=button] { + padding: 5px 10px; +} +button:hover, +a.button:hover, +input[type=submit]:hover, +input[type=button]:hover { + color: #fff; + background: #000; +} +button:hover em, +a.button:hover em, +input[type=submit]:hover em, +input[type=button]:hover em { + color: #808080; +} +button:active, +a.button:active, +input[type=submit]:active, +input[type=button]:active { + color: #000; + background: #fff; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/css.mixins.root.wonky.styl b/node_modules/jade/support/stylus/test/cases/css.mixins.root.wonky.styl new file mode 100644 index 0000000..e7bb7e0 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/css.mixins.root.wonky.styl @@ -0,0 +1,17 @@ + +hover() + &:hover { color: white; background: black; + em { + color: gray; + } + } + &:active { color: black; background: white; } + + +button(pad) + button, + a.button, + input[type=submit], + input[type=button] { padding: pad; hover(); } + +button(5px 10px); \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/css.mixins.styl b/node_modules/jade/support/stylus/test/cases/css.mixins.styl new file mode 100644 index 0000000..fd4ceb8 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/css.mixins.styl @@ -0,0 +1,47 @@ + +/* + * Reset button related properties so that + * a, button, and input's are supported. + */ + +-reset() + display: block; + text-decoration: none; + +/* + * Minimalistic flat button with white inset. + */ + +minimal-button(bg = #e3e3e3, intensity = 1) + -reset() + background: bg; + border: 1px solid darken(bg, 15% * intensity); + border-radius: 3px; + box-shadow: inset 0 0 1px 1px rgba(white, 0.8 * intensity); + color: #333; + font-family: 'helvetica neue', helvetica, arial, sans-serif; + font-size: 12px; + font-weight: bold; + line-height: 1; + padding: 8px 0 9px; + text-align: center; + text-shadow: 0 1px 0 rgba(white, 1 * intensity); + width: 150px; + + &:hover { + background: darken(bg, 3%); + box-shadow: inset 0 0 1px 1px rgba(white, 0.5 * intensity); + color: #222; + cursor: pointer; + } + + &:active { + background: darken(bg, 5%); + box-shadow: inset 0 0 1px 1px rgba(white, 0.2 * intensity); + color: #000; + } + +button, +a.button { + minimal-button(); +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/css.selectors.css b/node_modules/jade/support/stylus/test/cases/css.selectors.css new file mode 100644 index 0000000..3ea3a18 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/css.selectors.css @@ -0,0 +1,37 @@ +body { + margin: 0; + padding: 5px; +} +body ul { + margin: 0; +} +body ul li:first-child { + border-top: none; +} +body ul li:last-child { + border-bottom: none; +} +ul li:first-child, +ul li:last-child { + display: none; +} +foo { + border-radius: 5px; +} +foo bar baz { + border-radius: 5px; +} +foo, +bar, +baz { + border-radius: 5px; +} +input[type=button] { + border-radius: 5px; +} +button, +input[type=button], +input[type=submit], +a.button { + border-radius: 5px; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/css.selectors.styl b/node_modules/jade/support/stylus/test/cases/css.selectors.styl new file mode 100644 index 0000000..c42cbc8 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/css.selectors.styl @@ -0,0 +1,53 @@ + +body { + margin: 0; + padding: 5px; + ul { + /* test */ + margin: 0; + li:first-child { + border-top: none; + // test + } + // test + li:last-child { + border-bottom: none; + } + } +} + +ul { + li { + &:first-child, + &:last-child { + display: none; + } + } +} + + +foo { + border-radius: 5px; +} + +foo bar baz { + border-radius: 5px; +} + +foo +bar +baz { + border-radius: 5px; +} + +input[type=button] { + border-radius: 5px; +} + + +button +input[type=button] +input[type=submit] +a.button { + border-radius: 5px; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/css.whitespace.css b/node_modules/jade/support/stylus/test/cases/css.whitespace.css new file mode 100644 index 0000000..146a653 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/css.whitespace.css @@ -0,0 +1,37 @@ +body { + padding: 5px; +} +body { + padding: 5px; +} +body { + padding: 5px; + margin: 0; +} +body { + padding: 5px; + margin: 0; +} +body { + padding: 5px; + margin: 0; +} +body { + padding: 5px; + margin: 0; +} +body { + padding: 5px; +} +ul li { + padding: 5px; +} +body { + padding: 5px; +} +body { + padding: 5px; +} +input { + foo: "bar"; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/css.whitespace.styl b/node_modules/jade/support/stylus/test/cases/css.whitespace.styl new file mode 100644 index 0000000..13ea87a --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/css.whitespace.styl @@ -0,0 +1,36 @@ + +body + padding 5px + +body + padding 5px + +body + padding: 5px; margin: 0; + +body + padding: 5px; + margin: 0; + +body { + padding: 5px; + margin: 0; +} + +body { + padding: 5px; margin: 0; +} + +body { +padding: 5px; +} + +ul { + li { + padding: 5px; +} +} + + +body{padding: 5px;} +body{padding: 5px}input{foo:'bar'} diff --git a/node_modules/jade/support/stylus/test/cases/escape.css b/node_modules/jade/support/stylus/test/cases/escape.css new file mode 100644 index 0000000..1eda758 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/escape.css @@ -0,0 +1,4 @@ +body { + font: 14px + 1.2; + border-radius: 5px 2px ( 5px 1px; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/escape.styl b/node_modules/jade/support/stylus/test/cases/escape.styl new file mode 100644 index 0000000..bbc614f --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/escape.styl @@ -0,0 +1,4 @@ + +body + font 14px \+ 1.2 + border-radius 5px 2px \( 5px 1px diff --git a/node_modules/jade/support/stylus/test/cases/for.complex.css b/node_modules/jade/support/stylus/test/cases/for.complex.css new file mode 100644 index 0000000..e0259a8 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/for.complex.css @@ -0,0 +1,44 @@ +body { + foo: a; + foo: b; + foo: c; + foo: d; + foo: e; + foo: f; + foo: g; +} +body { + foo: a; +} +body { + foo: 0 : b; + foo: 1 : c; + foo: 2 : d; +} +body { + foo: error test "test"; + foo: error test "foo"; +} +body { + foo: 0 a; + foo: 1 a; + foo: 2 a; + foo: 3 a; + foo: 0 b; + foo: 1 b; + foo: 2 b; + foo: 3 b; + foo: 0 c; + foo: 1 c; + foo: 2 c; + foo: 3 c; + foo: 0 d; + foo: 1 d; + foo: 2 d; + foo: 3 d; +} +body { + foo: helvetica; + foo: arial; + foo: sans-serif; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/for.complex.styl b/node_modules/jade/support/stylus/test/cases/for.complex.styl new file mode 100644 index 0000000..d3d442a --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/for.complex.styl @@ -0,0 +1,28 @@ +vals = a b c d e f g + +body + for val in vals + foo val + +body + for val in vals[0] + foo val + +body + for val, i in vals[1..3] + foo i unquote(':') val + +body + for msg in (error 'test') (error 'foo') + foo msg[0] test msg[1] + +body + for char in a b c d + for num in 0 1 2 3 + foo num char + +fonts = helvetica, arial, sans-serif + +body + for font in fonts + foo font diff --git a/node_modules/jade/support/stylus/test/cases/for.css b/node_modules/jade/support/stylus/test/cases/for.css new file mode 100644 index 0000000..f8129ff --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/for.css @@ -0,0 +1,52 @@ +body { + test-args: 1 2 3; + foo: 1; + foo: 2; + foo: 3; + test-args: 1 2 3 4 5; + foo: 1 2; + foo: 3 4; + foo: 5; + test-args: 1 2 3 4; + foo: 1 2; + foo: 3 4; +} +body { + foo: 1 2; + foo: 3 4; +} +body { + foo: 1; + foo: 2; + foo: 3; + foo: 4; + foo: 5; +} +body { + foo: 1; + foo: 2; + foo: 3; +} +body foo { + bar: 1; +} +body foo { + bar: 2; +} +body foo { + bar: 3; +} +body foo bar { + baz: 1; +} +body foo bar { + baz: 2; +} +body foo bar { + baz: 3; +} +body { + foo: 0 foo; + foo: 1 bar; + foo: 2 baz; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/for.function.css b/node_modules/jade/support/stylus/test/cases/for.function.css new file mode 100644 index 0000000..5613a7a --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/for.function.css @@ -0,0 +1,20 @@ +body { + foo: 10; + foo: 20; + foo: 10; +} +body { + foo: "foo bar baz"; + foo: "foo, bar, baz"; + foo: "1 2 3"; + foo: "1, 2, 3"; +} +body { + foo: 0 Impact; + foo: 1 Arial; + foo: 2 sans-serif; +} +body { + foo: 24; + foo: 30; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/for.function.styl b/node_modules/jade/support/stylus/test/cases/for.function.styl new file mode 100644 index 0000000..84a5a21 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/for.function.styl @@ -0,0 +1,51 @@ + +sum(nums...) + sum = 0 + for n in nums + sum += n + +sum2(nums...) + sum = 0 + for n in nums + sum += n + sum * 2 + +sum3(nums...) + sum = 0 + sum += n for n in nums + +body + foo sum(1,2,3,4) + foo sum2(1,2,3,4) + foo sum3(1,2,3,4) + +join(delim, args) + buf = '' + for arg, i in args + buf += i ? delim + arg : arg + +join2(delim, args) + buf = '' + buf += i ? delim + arg : arg for arg, i in args + +body + foo join(' ', foo bar baz) + foo join(', ', foo bar baz) + foo join2(' ', 1 2 3) + foo join2(', ', 1 2 3) + +body + fonts = Impact Arial sans-serif + for font, i in fonts + foo i font + +last-even(nums...) + ret = n if n % 2 == 0 for n in nums + ret + +first-even(nums...) + return n if n % 2 == 0 for n in nums + +body + foo last-even(1,3,30,5,6,12,2,24,3) + foo first-even(1,3,30,5,6,12,2,24,3) \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/for.styl b/node_modules/jade/support/stylus/test/cases/for.styl new file mode 100644 index 0000000..44617e4 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/for.styl @@ -0,0 +1,44 @@ + +test(args...) + test-args args + for arg in args + foo arg + +size(a, b) + return a b + +body + test 1 2 3 + test (1 2) (3 4) 5 + test size(1, 2) size(3, 4) + +body + sizes = size(1, 2) size(3, 4) + for size in sizes + foo size + +body + for n in 1..5 + foo n + +body + for n in 1 2 3 + foo n + +body + for n in 1 2 3 + foo + bar n + +test(args...) + foo + for arg in args + bar + baz arg + +body + test 1 2 3 + +body + for val, index in foo bar baz + foo index val \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/function.arguments.css b/node_modules/jade/support/stylus/test/cases/function.arguments.css new file mode 100644 index 0000000..1a3a83b --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/function.arguments.css @@ -0,0 +1,4 @@ +body { + padding: 15; + padding: 1 2; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/function.arguments.styl b/node_modules/jade/support/stylus/test/cases/function.arguments.styl new file mode 100644 index 0000000..9cb7285 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/function.arguments.styl @@ -0,0 +1,14 @@ + +sum() + n = 0 + for num in arguments + n = n + num + n + +test(a, b) + a = b + (arguments[0] a) + +body + padding sum(1,2,3,4,5) + padding test(1,2) \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/function.literals.css b/node_modules/jade/support/stylus/test/cases/function.literals.css new file mode 100644 index 0000000..30ad857 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/function.literals.css @@ -0,0 +1,6 @@ +body { + foo: bar(1px, baz(5px)); + bar: baz(5px) baz(5px); + foo: recurse; + foo: recurse; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/function.literals.styl b/node_modules/jade/support/stylus/test/cases/function.literals.styl new file mode 100644 index 0000000..d1179b9 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/function.literals.styl @@ -0,0 +1,12 @@ + +something(arg) + bar arg arg + +recurse() + foo recurse + foo recurse + +body + foo bar(1px, baz(5px)) + something(baz(5px)) + recurse() \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/functions.arg-calls.css b/node_modules/jade/support/stylus/test/cases/functions.arg-calls.css new file mode 100644 index 0000000..8e0891f --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/functions.arg-calls.css @@ -0,0 +1,3 @@ +form input { + padding: 10px 5px 10px 5px; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/functions.arg-calls.styl b/node_modules/jade/support/stylus/test/cases/functions.arg-calls.styl new file mode 100644 index 0000000..f2739eb --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/functions.arg-calls.styl @@ -0,0 +1,9 @@ +add(a, b) + a + b + +pad(x, y = x) + padding y x y x + +form input + n = 5 + pad(5px, unit(add(n, n), 'px')) \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/functions.call.css b/node_modules/jade/support/stylus/test/cases/functions.call.css new file mode 100644 index 0000000..9dbadae --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/functions.call.css @@ -0,0 +1,4 @@ +body { + foo: 15; + foo: 7; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/functions.call.styl b/node_modules/jade/support/stylus/test/cases/functions.call.styl new file mode 100644 index 0000000..c85adb1 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/functions.call.styl @@ -0,0 +1,7 @@ + +add(a, b) + a + b + +body + foo add(5, 10) + foo add(5, 2) diff --git a/node_modules/jade/support/stylus/test/cases/functions.css b/node_modules/jade/support/stylus/test/cases/functions.css new file mode 100644 index 0000000..e3c22b2 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/functions.css @@ -0,0 +1,11 @@ +body { + padding: 10px 5px 10px 5px; +} +form .button { + padding-left: 15px; +} +body { + foo: bottom; + foo: right; + foo: bottom right; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/functions.defaults.css b/node_modules/jade/support/stylus/test/cases/functions.defaults.css new file mode 100644 index 0000000..19f7e77 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/functions.defaults.css @@ -0,0 +1,15 @@ +body { + padding: 15px 5px 15px 5px; +} +a.button { + padding: 10px 10px 10px 10px; +} +a.button-2 { + padding: 2px 10px 2px 10px; +} +body { + padding: 10px; +} +.button { + padding: 5px; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/functions.defaults.styl b/node_modules/jade/support/stylus/test/cases/functions.defaults.styl new file mode 100644 index 0000000..2946141 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/functions.defaults.styl @@ -0,0 +1,30 @@ + +size = 15px +small = 5 + +pad-var(x, y = size) + padding y x y x + +pad-arg(x, y = x) + padding y x y x + +body + pad-var(5px) + +a.button + pad-arg(10px) + +a.button-2 + pad-arg(10px, 2px) + +add(a, b) + a + b + +pad-call(n = unit(add(small, small), 'px')) + padding n + +body + pad-call() + +.button + pad-call(5px) \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/functions.multi-line.css b/node_modules/jade/support/stylus/test/cases/functions.multi-line.css new file mode 100644 index 0000000..0818fca --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/functions.multi-line.css @@ -0,0 +1,9 @@ +body { + padding: 2 1; +} +body { + padding: 2 1; +} +body { + padding: 3 2; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/functions.multi-line.styl b/node_modules/jade/support/stylus/test/cases/functions.multi-line.styl new file mode 100644 index 0000000..b17195c --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/functions.multi-line.styl @@ -0,0 +1,25 @@ + +pad( + x = 5 +, y = 10 +) + padding y x + +body + pad 1 2 + +pad( + x = 5 + , y = 10 +) + padding y x + +body + pad 1 2 + +body + pad(x + , y + ) + padding y x + pad 2 3 \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/functions.multiple-calls.css b/node_modules/jade/support/stylus/test/cases/functions.multiple-calls.css new file mode 100644 index 0000000..d860a55 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/functions.multiple-calls.css @@ -0,0 +1,13 @@ +body { + padding: 5px; + padding: 100px; + padding: 10px; + padding: 1px; + padding: 100px; +} +form { + padding-left: 5px; + padding-right: 5px; + padding-top: 10px; + padding-bottom: 10px; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/functions.multiple-calls.styl b/node_modules/jade/support/stylus/test/cases/functions.multiple-calls.styl new file mode 100644 index 0000000..9e7353b --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/functions.multiple-calls.styl @@ -0,0 +1,26 @@ + +pad(y = 100px) + padding unit(y, 'px') + +body + pad(5px) + pad() + pad(10px) + pad(1) + pad() + +pad-x(n) + n = unit(n, 'px') + padding-left n + padding-right n + +pad-y(y) + padding-top n = unit(y, 'px') + padding-bottom n + +pad(x, y) + pad-x(x) + pad-y(y) + +form + pad(5, 10) \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/functions.nested-calls.css b/node_modules/jade/support/stylus/test/cases/functions.nested-calls.css new file mode 100644 index 0000000..104ae05 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/functions.nested-calls.css @@ -0,0 +1,3 @@ +body { + foo: 13; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/functions.nested-calls.styl b/node_modules/jade/support/stylus/test/cases/functions.nested-calls.styl new file mode 100644 index 0000000..eda05a3 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/functions.nested-calls.styl @@ -0,0 +1,9 @@ + +sub(a, b) + a - b + +add(a, b) + a + b + +body + foo add(5, add(5, sub(5, 2))) diff --git a/node_modules/jade/support/stylus/test/cases/functions.nested.css b/node_modules/jade/support/stylus/test/cases/functions.nested.css new file mode 100644 index 0000000..6a3c670 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/functions.nested.css @@ -0,0 +1,10 @@ +body { + padding: 3.5; +} +body { + padding: 3.5; +} +body { + padding: 10; + padding: 0; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/functions.nested.styl b/node_modules/jade/support/stylus/test/cases/functions.nested.styl new file mode 100644 index 0000000..4f9a2f5 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/functions.nested.styl @@ -0,0 +1,37 @@ + +add(a, b) + div(a, b) + a / b + a + div(b, 2) + +body + padding add(1,5) + // => 3.5 + +add(a, b) + half() + b / 2 + a + half() + +body + padding add(1,5) + // => 3.5 + +getFunction(name) + if name == 'add' + add(a, b) + a + b + else + sub(a, b) + a - b + +body + fn = getFunction('add') + padding fn(5, 5) + // => 10 + + fn = getFunction('sub') + fn2 = fn + fn3 = fn2 + padding fn3(5, 5) + // => 0 \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/functions.property.css b/node_modules/jade/support/stylus/test/cases/functions.property.css new file mode 100644 index 0000000..3495051 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/functions.property.css @@ -0,0 +1,10 @@ +form { + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + border-radius: 5px; +} +a.button { + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + border-radius: 5px; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/functions.property.styl b/node_modules/jade/support/stylus/test/cases/functions.property.styl new file mode 100644 index 0000000..cf584ae --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/functions.property.styl @@ -0,0 +1,11 @@ + +border-radius(size) + -webkit-border-radius size + -moz-border-radius size + border-radius size + +form + border-radius 5px + +a.button + border-radius 5px \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/functions.return.css b/node_modules/jade/support/stylus/test/cases/functions.return.css new file mode 100644 index 0000000..37706f0 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/functions.return.css @@ -0,0 +1,15 @@ +body { + foo: no; + foo: yes; + foo: false; + foo: yes; + foo: "a is not a unit"; + foo: 2; +} +body { + foo: five; + foo: something; +} +body { + foo: 3; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/functions.return.each.css b/node_modules/jade/support/stylus/test/cases/functions.return.each.css new file mode 100644 index 0000000..1c38717 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/functions.return.each.css @@ -0,0 +1,10 @@ +body { + foo: "1 2 3"; + foo: "1, 2, 3"; + foo: "1,2,3"; +} +body { + foo: "1 2 3"; + foo: "1, 2, 3"; + foo: "1,2,3"; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/functions.return.each.styl b/node_modules/jade/support/stylus/test/cases/functions.return.each.styl new file mode 100644 index 0000000..0f2f1f8 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/functions.return.each.styl @@ -0,0 +1,23 @@ + +join1(delim, vals) + buf = '' + for val, i in vals + if i + buf += delim + val + else + buf += val + +join2(delim, vals) + buf = '' + for val, i in vals + buf += i ? delim + val : val + +body + foo join1(' ', 1 2 3) + foo join1(', ', 1 2 3) + foo join1(',', 1 2 3) + +body + foo join2(' ', 1 2 3) + foo join2(', ', 1 2 3) + foo join2(',', 1 2 3) \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/functions.return.styl b/node_modules/jade/support/stylus/test/cases/functions.return.styl new file mode 100644 index 0000000..6aab55b --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/functions.return.styl @@ -0,0 +1,86 @@ + +large(n) + unless n is a 'unit' + return false + if n > 100 + yes + else + no + +awesome() + yes + +nested(a = 5) + if a is a 'unit' + b = 10 + if a + c = 100 + c = 100 + c = 100 + c = 100 + awesome() + else + 'b is not a unit' + else + 'a is not a unit' + +set() + 1 + return 2 + 3 + +body + // no + foo large(15) + + // yes + foo large(150) + + // false + foo large('string') + + // yes + foo nested() + + // 'a is not a unit' + foo nested('wahoo') + + // 2 + foo set() + +deep-implicit() + one + if false + two + else + if true + something + three + else + four + five + +deep-explicit() + one + if false + two + else + if true + return something + three + else + four + five + +body + foo deep-implicit() + foo deep-explicit() + +test() + return 1 if false + return 2 if false + return 3 if true + return 4 + +body + foo test() \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/functions.styl b/node_modules/jade/support/stylus/test/cases/functions.styl new file mode 100644 index 0000000..8106c2f --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/functions.styl @@ -0,0 +1,34 @@ + +add(a, b) + a + b + +pad(x, y) + padding y x y x + +body + pad(5px, 10px) + +form .button + padding-left add(10px, 5px) + +-opposite-position(pos) + if pos == top + bottom + else if pos == bottom + top + else if pos == left + right + else if pos == right + left + else + error('Invalid position ' + pos) + +opposite(positions) + for pos in positions + pos = -opposite-position(pos) + ret = ret is defined ? ret pos : pos + +body + foo opposite(top) + foo opposite(left) + foo opposite(top left) diff --git a/node_modules/jade/support/stylus/test/cases/functions.variable.css b/node_modules/jade/support/stylus/test/cases/functions.variable.css new file mode 100644 index 0000000..99fd5ba --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/functions.variable.css @@ -0,0 +1,9 @@ +body { + font: 28px; + padding-left: 5px; + padding-right: 5px; +} +form { + padding-top: 10px; + padding-bottom: 10px; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/functions.variable.ident.css b/node_modules/jade/support/stylus/test/cases/functions.variable.ident.css new file mode 100644 index 0000000..b7cdff3 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/functions.variable.ident.css @@ -0,0 +1,3 @@ +body { + font: 28px; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/functions.variable.ident.styl b/node_modules/jade/support/stylus/test/cases/functions.variable.ident.styl new file mode 100644 index 0000000..abc45ee --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/functions.variable.ident.styl @@ -0,0 +1,11 @@ + +add(a, b) + a + b + +size-function = add + +size(n) + size-function(n, n) + +body + font size(14px) \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/functions.variable.styl b/node_modules/jade/support/stylus/test/cases/functions.variable.styl new file mode 100644 index 0000000..c3d6a66 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/functions.variable.styl @@ -0,0 +1,27 @@ + +add(a, b) + a + b + +size-function = add + +size(n) + size-function(n, n) + +padding-x(n) + padding-left n + padding-right n + +padding-y(n) + padding-top n + padding-bottom n + +mixin(name, n) + name(n) + +body + fn = padding-x + font size(14px) + fn(5px) + +form + mixin(padding-y, 10px) \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/if.css b/node_modules/jade/support/stylus/test/cases/if.css new file mode 100644 index 0000000..41a12f5 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/if.css @@ -0,0 +1,43 @@ +body { + padding: 100; +} +body { + padding: false; +} +body { + padding: 150; +} +body { + padding: 75; +} +body { + padding: -1; +} +body { + padding: 1; +} +body { + foo: yes; + foo: no; + foo: zero; + foo: invalid; +} +body .input { + padding: 5px; + no: margin; +} +body form input { + foo: no; + foo: bar; + bar: baz; +} +body something { + foo: bar; + bar: baz; +} +body .nested { + foo: bar; +} +body .nested .hidden { + display: none; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/if.else.css b/node_modules/jade/support/stylus/test/cases/if.else.css new file mode 100644 index 0000000..5d48da0 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/if.else.css @@ -0,0 +1,6 @@ +body { + foo: string; + foo: unit; + foo: color; + foo: unknown; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/if.else.styl b/node_modules/jade/support/stylus/test/cases/if.else.styl new file mode 100644 index 0000000..bddded5 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/if.else.styl @@ -0,0 +1,16 @@ + +naive-type(val = null) + if val is a 'unit' + unit + else if val is a 'color' + color + else if val is a 'string' + string + else + unknown + +body + foo naive-type('test') + foo naive-type(12) + foo naive-type(#fff) + foo naive-type() diff --git a/node_modules/jade/support/stylus/test/cases/if.mixin.css b/node_modules/jade/support/stylus/test/cases/if.mixin.css new file mode 100644 index 0000000..a83dec6 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/if.mixin.css @@ -0,0 +1,7 @@ +body { + got: above; + got: below; + got: empty; + yup: just lots of empty; + padding: 10px; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/if.mixin.styl b/node_modules/jade/support/stylus/test/cases/if.mixin.styl new file mode 100644 index 0000000..3d36fe3 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/if.mixin.styl @@ -0,0 +1,24 @@ + +test(n) + if n < 0 + got below + else + got above + +test-nested(a, b) + if a > 1 + if unit(-5) == '' + got empty + yup just lots of empty + else + got unit(-5px) + +test-unless(n = 0) + unless n + padding 10px + +body + test(5px) + test(-5px) + test-nested(5px, -5) + test-unless() diff --git a/node_modules/jade/support/stylus/test/cases/if.postfix.css b/node_modules/jade/support/stylus/test/cases/if.postfix.css new file mode 100644 index 0000000..d775ffc --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/if.postfix.css @@ -0,0 +1,61 @@ +body { + foo: 1; + foo: 2; + foo: 3; + foo: 4; + foo: 5; + foo: 6; + foo: 7; +} +body { + foo: 3; +} +body { + foo: true; + foo: true; +} +body { + foo: true; + foo: true; +} +body { + foo: 5; +} +body { + foo: bar; + foo: baz; +} +body { + foo: bar; + foo: baz; +} +@import "foo.css"; +body { + foo: 5; +} +body { + foo: string; + foo: number; + foo: unknown; +} +body { + foo: true; + foo: true; + foo: false; +} +body { + fonts: arial, sans-serif; +} +body { + foo: yes; + foo: yes; + foo: yes; + foo: ; + foo: ; +} +body { + foo: yes; + foo: no; + foo: zero; + foo: invalid; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/if.postfix.styl b/node_modules/jade/support/stylus/test/cases/if.postfix.styl new file mode 100644 index 0000000..9639d4f --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/if.postfix.styl @@ -0,0 +1,110 @@ + +mixin() + if true + foo 6 + foo 7 if true + foo 8 unless true + +body + foo 1 + foo 2 if true + foo 3 unless false + if true + foo 4 + foo 5 + mixin() + +body + foo 1 if false + foo 2 unless true + foo 3 + +above-5(n) + true if n > 5 + +body + foo above-5(2) == null + foo above-5(6) == true + +below-5(n) + return true unless n > 5 + false + +body + foo below-5(3) == true + foo below-5(7) == false + +body + foo 5 unless 5 + 5 == 10 + +body + foo 5 if 5 + 5 == 10 and true + +mixin() + foo bar + foo baz + +body + mixin() if true + mixin() unless true + +body + mixin test if true + + +@import 'foo.css' if true +@charset 'foo' if false + +num = 5 unless num is defined + +body + foo num + +type(arg = null) + return string if arg is a 'string' + return number if arg is a 'unit' + unknown + +body + foo type('test') + foo type(12) + foo type() + +is-a-string(arg = null) + arg is a 'string' unless arg == null + +body + foo is-a-string() == null + foo is-a-string('test') + foo is-a-string(12) if true + +empty(expr) + 0 == length(expr) + +font-list = arial, sans-serif +body + fonts font-list unless empty(font-list) + font-list = () + fonts font-list unless empty(font-list) + +truthy(val) + yes if 1 == val or 'yes' == val or 'y' == val + +body + foo truthy(1) + foo truthy('yes') + foo truthy('y') + foo truthy(0) + foo truthy('no') + +negative(n) + return invalid unless n is a 'unit' + return yes if n < 0 + return no if n > 0 + zero + +body + foo negative(-5) + foo negative(5) + foo negative(0) + foo negative('asdf') \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/if.selectors.css b/node_modules/jade/support/stylus/test/cases/if.selectors.css new file mode 100644 index 0000000..51e1118 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/if.selectors.css @@ -0,0 +1,6 @@ +form input { + border: 1px solid #eee; +} +body { + font: 12px; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/if.selectors.styl b/node_modules/jade/support/stylus/test/cases/if.selectors.styl new file mode 100644 index 0000000..f63848d --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/if.selectors.styl @@ -0,0 +1,12 @@ + +if false + something + with a-prop + +if true + form + input + border 1px solid #eee + if true + body + font 12px \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/if.styl b/node_modules/jade/support/stylus/test/cases/if.styl new file mode 100644 index 0000000..f2f9746 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/if.styl @@ -0,0 +1,99 @@ +n = false + +if !n + n = 100 + +body + padding n + +n = false + +if not not n + n = 50 + +body + padding n + +if not n + n = 150 + +body + padding n + +if n + n = n / 2 +else + n = 10000 + +body + padding n + +if n > 100 + n = n * 2 +else + n = -1 + +body + padding n + +n = 75 + +if n < 50 + n = n +else + if n > 50 and n < 100 + n = 1 + else + n = -1 + +body + padding n + +negative(n) + unless n is a 'unit' + return invalid + if n < 0 + yes + else if n > 0 + no + else + zero + +body + foo negative(-5) + foo negative(5) + foo negative(0) + foo negative('asdf') + +body + .input + pad = true + margin = false + if pad + padding 5px + if margin + margin 5px + else + no unquote('margin') + +mixin() + foo bar + bar baz + +body + form input + if true + foo negative(5) + mixin() + something + mixin() + +body + .nested + if true + if true + if true + foo bar + .hidden + if true + display none \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/import.basic.css b/node_modules/jade/support/stylus/test/cases/import.basic.css new file mode 100644 index 0000000..2f2a6d9 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/import.basic.css @@ -0,0 +1,9 @@ +.a { + color: #f00; +} +.b { + color: #008000; +} +.c { + color: #00f; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/import.basic.styl b/node_modules/jade/support/stylus/test/cases/import.basic.styl new file mode 100644 index 0000000..f8850e3 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/import.basic.styl @@ -0,0 +1,2 @@ + +@import "a" diff --git a/node_modules/jade/support/stylus/test/cases/import.basic/a.styl b/node_modules/jade/support/stylus/test/cases/import.basic/a.styl new file mode 100644 index 0000000..c6aee44 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/import.basic/a.styl @@ -0,0 +1,5 @@ + +.a + color red + +@import "b" \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/import.basic/b.styl b/node_modules/jade/support/stylus/test/cases/import.basic/b.styl new file mode 100644 index 0000000..c514e75 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/import.basic/b.styl @@ -0,0 +1,5 @@ + +.b + color green + +@import "c" \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/import.basic/c.styl b/node_modules/jade/support/stylus/test/cases/import.basic/c.styl new file mode 100644 index 0000000..abc49ca --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/import.basic/c.styl @@ -0,0 +1,3 @@ + +.c + color blue \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/import.complex.css b/node_modules/jade/support/stylus/test/cases/import.complex.css new file mode 100644 index 0000000..3ba73e8 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/import.complex.css @@ -0,0 +1,9 @@ +one { + foo: bar; +} +two { + foo: bar; +} +three { + foo: bar; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/import.complex.styl b/node_modules/jade/support/stylus/test/cases/import.complex.styl new file mode 100644 index 0000000..8d4e813 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/import.complex.styl @@ -0,0 +1 @@ +@import "./import.complex/a" \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/import.complex/a.styl b/node_modules/jade/support/stylus/test/cases/import.complex/a.styl new file mode 100644 index 0000000..4c4e68b --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/import.complex/a.styl @@ -0,0 +1,4 @@ +one + foo bar + +@import "./nested/b" \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/import.complex/c.styl b/node_modules/jade/support/stylus/test/cases/import.complex/c.styl new file mode 100644 index 0000000..c400d08 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/import.complex/c.styl @@ -0,0 +1,2 @@ +three + foo bar \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/import.complex/nested/b.styl b/node_modules/jade/support/stylus/test/cases/import.complex/nested/b.styl new file mode 100644 index 0000000..1316242 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/import.complex/nested/b.styl @@ -0,0 +1,4 @@ +two + foo bar + +@import "../c" \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/import.index.css b/node_modules/jade/support/stylus/test/cases/import.index.css new file mode 100644 index 0000000..f34b6a0 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/import.index.css @@ -0,0 +1,9 @@ +body { + one: 1; +} +body { + two: 2; +} +body { + three: 3; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/import.index.styl b/node_modules/jade/support/stylus/test/cases/import.index.styl new file mode 100644 index 0000000..4ef8282 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/import.index.styl @@ -0,0 +1,2 @@ + +@import 'import.index/vendor' \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/import.index/vendor/a.styl b/node_modules/jade/support/stylus/test/cases/import.index/vendor/a.styl new file mode 100644 index 0000000..a80eaac --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/import.index/vendor/a.styl @@ -0,0 +1,2 @@ +body + one 1 \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/import.index/vendor/b.styl b/node_modules/jade/support/stylus/test/cases/import.index/vendor/b.styl new file mode 100644 index 0000000..ed6a757 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/import.index/vendor/b.styl @@ -0,0 +1,2 @@ +body + two 2 \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/import.index/vendor/c.styl b/node_modules/jade/support/stylus/test/cases/import.index/vendor/c.styl new file mode 100644 index 0000000..0b63b12 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/import.index/vendor/c.styl @@ -0,0 +1,2 @@ +body + three 3 \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/import.index/vendor/index.styl b/node_modules/jade/support/stylus/test/cases/import.index/vendor/index.styl new file mode 100644 index 0000000..fb919a9 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/import.index/vendor/index.styl @@ -0,0 +1,4 @@ + +@import 'a' +@import 'b' +@import 'c' \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/import.literal.css b/node_modules/jade/support/stylus/test/cases/import.literal.css new file mode 100644 index 0000000..54fd5ca --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/import.literal.css @@ -0,0 +1,2 @@ +@import "foo/bar.css"; +@import "bar/baz.css"; \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/import.literal.styl b/node_modules/jade/support/stylus/test/cases/import.literal.styl new file mode 100644 index 0000000..d39dfa3 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/import.literal.styl @@ -0,0 +1,3 @@ + +@import "foo/bar.css" +@import 'bar/baz.css' \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/import.mixins.css b/node_modules/jade/support/stylus/test/cases/import.mixins.css new file mode 100644 index 0000000..b526a7f --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/import.mixins.css @@ -0,0 +1,7 @@ +body { + padding: 10px 5px 10px 5px; +} +form { + padding-left: 5px; + padding-right: 5px; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/import.mixins.styl b/node_modules/jade/support/stylus/test/cases/import.mixins.styl new file mode 100644 index 0000000..8819d7b --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/import.mixins.styl @@ -0,0 +1,9 @@ + +if true + @import "mixins/box" + +body + pad 5px 10px + +form + pad-x 5px \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/import.ordering.css b/node_modules/jade/support/stylus/test/cases/import.ordering.css new file mode 100644 index 0000000..dfae959 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/import.ordering.css @@ -0,0 +1,15 @@ +one { + foo: bar; +} +two { + foo: bar; +} +three { + foo: bar; +} +four { + foo: bar; +} +five { + foo: bar; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/import.ordering.styl b/node_modules/jade/support/stylus/test/cases/import.ordering.styl new file mode 100644 index 0000000..afec87d --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/import.ordering.styl @@ -0,0 +1,12 @@ + +dir = 'import.ordering' + +one + foo bar + +@import dir + "/two" + +three + foo bar + +@import dir + '/four' diff --git a/node_modules/jade/support/stylus/test/cases/import.ordering/five.styl b/node_modules/jade/support/stylus/test/cases/import.ordering/five.styl new file mode 100644 index 0000000..05ee8a9 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/import.ordering/five.styl @@ -0,0 +1,2 @@ +five + foo bar \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/import.ordering/four.styl b/node_modules/jade/support/stylus/test/cases/import.ordering/four.styl new file mode 100644 index 0000000..58392a1 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/import.ordering/four.styl @@ -0,0 +1,4 @@ +four + foo bar + +@import "import.ordering/five" \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/import.ordering/two.styl b/node_modules/jade/support/stylus/test/cases/import.ordering/two.styl new file mode 100644 index 0000000..15f8e04 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/import.ordering/two.styl @@ -0,0 +1,2 @@ +two + foo bar \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/important.css b/node_modules/jade/support/stylus/test/cases/important.css new file mode 100644 index 0000000..a7c144a --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/important.css @@ -0,0 +1,6 @@ +a { + color: #f00 !important; +} +a.button { + color: #00f; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/important.styl b/node_modules/jade/support/stylus/test/cases/important.styl new file mode 100644 index 0000000..8500932 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/important.styl @@ -0,0 +1,6 @@ + +a + color red !important + +a.button + color blue \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/interpolation.properties.css b/node_modules/jade/support/stylus/test/cases/interpolation.properties.css new file mode 100644 index 0000000..801c157 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/interpolation.properties.css @@ -0,0 +1,40 @@ +#login { + -webkit-border-radius: 1px 2px / 3px 4px; + -moz-border-radius: 1px 2px / 3px 4px; + border-radius: 1px 2px / 3px 4px; +} +body { + foo: bar; + foo-something: foo; + foo-something-bar: foo; + something-foo: foo; + something: foo; +} +body { + test-stuff-yup: awesome; + -webkit-border-radius: awesome; + -webkit-box-shadow: awesome; +} +body { + foo: "one"; + foo: "two"; +} +body { + -webkit-something: foo; + something: foo; +} +body form input { + -webkit-something: foo; + something: foo; +} +body form input p { + something: foo; +} +body { + foo-test-baz: bar; + foo-test: bar; + test: bar; + position: absolute; + top: 0; + right: 0; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/interpolation.properties.styl b/node_modules/jade/support/stylus/test/cases/interpolation.properties.styl new file mode 100644 index 0000000..b33dc2b --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/interpolation.properties.styl @@ -0,0 +1,56 @@ + +vendor(prop, args) + -webkit-{prop} args + -moz-{prop} args + {prop} args + +border-radius() + vendor('border-radius', arguments) + +#login + border-radius 1px 2px / 3px 4px + +body + prop = 'something' + foo bar + foo-{prop} foo + foo-{prop}-bar foo + {prop}-foo foo + {prop} foo + +body + {'test' + '-stuff'}-yup awesome + -webkit-{border-radius} awesome + -webkit-{box-shadow} awesome + +testing(var, one, two) + {var} + +body + foo testing('one', 1, 2) + foo testing('two', 1, 2) + +body + nested(prop) + -webkit-{prop} foo + {prop} foo + form input + -webkit-{prop} foo + {prop} foo + p + {prop} foo + nested('something') + +top-right() + position absolute + top 0 + right 0 + +foo(ret) + ret + +body + foo-{foo('test')}-baz bar + foo-{foo('test')} bar + {foo('test')} bar + {foo('top')}-right bar diff --git a/node_modules/jade/support/stylus/test/cases/introspection.css b/node_modules/jade/support/stylus/test/cases/introspection.css new file mode 100644 index 0000000..ce4a1d6 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/introspection.css @@ -0,0 +1,7 @@ +got { + root: true; +} +body { + got: "a mixin"; + foo: "not a mixin"; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/introspection.styl b/node_modules/jade/support/stylus/test/cases/introspection.styl new file mode 100644 index 0000000..8433995 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/introspection.styl @@ -0,0 +1,14 @@ +reset() + if mixin == 'root' + got + root true + else if mixin + got 'a mixin' + else + 'not a mixin' + +reset() + +body + reset() + foo reset() \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/jquery.css b/node_modules/jade/support/stylus/test/cases/jquery.css new file mode 100644 index 0000000..6562ed2 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/jquery.css @@ -0,0 +1,3 @@ +body { + padding: 10px 10px; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/jquery.styl b/node_modules/jade/support/stylus/test/cases/jquery.styl new file mode 100644 index 0000000..36feb65 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/jquery.styl @@ -0,0 +1,5 @@ +pad( x , y = x ) + padding x y + +body + pad( 10px ) \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/list.css b/node_modules/jade/support/stylus/test/cases/list.css new file mode 100644 index 0000000..6c1c179 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/list.css @@ -0,0 +1,3 @@ +body { + font: 12px "Lucida Grande", Arial, sans-serif; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/list.styl b/node_modules/jade/support/stylus/test/cases/list.styl new file mode 100644 index 0000000..08da49c --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/list.styl @@ -0,0 +1,3 @@ + +body + font 12px "Lucida Grande", Arial, sans-serif \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/literal.css b/node_modules/jade/support/stylus/test/cases/literal.css new file mode 100644 index 0000000..ecaf916 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/literal.css @@ -0,0 +1,5 @@ +body { + font: 14px; +} + +a { text-decoration: none; } \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/literal.styl b/node_modules/jade/support/stylus/test/cases/literal.styl new file mode 100644 index 0000000..94b071f --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/literal.styl @@ -0,0 +1,7 @@ +@css { + body { + font: 14px; + } + + a { text-decoration: none; } +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/media.css b/node_modules/jade/support/stylus/test/cases/media.css new file mode 100644 index 0000000..0175743 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/media.css @@ -0,0 +1,14 @@ +@media print and (width: 21cm) and (height: 29cm) { + body { + margin: 3cm; + padding: 0; + } +} +@media print { + @page :left { + margin-left: 5px; + } + @page :right { + margin-right: 5px; + } +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/media.styl b/node_modules/jade/support/stylus/test/cases/media.styl new file mode 100644 index 0000000..da17def --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/media.styl @@ -0,0 +1,11 @@ + +@media print and (width: 21cm) and (height: 29cm) + body + margin 3cm + padding 0 + +@media print + @page :left + margin-left 5px + @page :right + margin-right 5px \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/mixin.conditional.css b/node_modules/jade/support/stylus/test/cases/mixin.conditional.css new file mode 100644 index 0000000..574ff68 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/mixin.conditional.css @@ -0,0 +1,19 @@ +body { + padding: 20px; + padding: 10px; + padding: 3px; +} +form input { + foo: bar; + bar: baz; +} +form input .two { + level: two; +} +form input .two:hover { + level: three; +} +body { + foo: bar; + bar: baz; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/mixin.conditional.styl b/node_modules/jade/support/stylus/test/cases/mixin.conditional.styl new file mode 100644 index 0000000..2ff9cac --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/mixin.conditional.styl @@ -0,0 +1,36 @@ + +pad(size = small) + if large == size + padding 20px + if medium == size + padding 10px + if small == size + padding 3px + +body + pad(large) + pad(medium) + pad() + pad(invalid) + +nested(val) + if val + foo bar + bar baz + .two + level two + &:hover + level three + +form input + nested(true) + nested(false) + +break() + foo bar + bar baz + return + baz raz + +body + break() \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/mixin.order.conditional.css b/node_modules/jade/support/stylus/test/cases/mixin.order.conditional.css new file mode 100644 index 0000000..1bf23eb --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/mixin.order.conditional.css @@ -0,0 +1,11 @@ +body { + one: 1; + two: 2; + three: 3; + four: 4; + five: 5; + six: 6; + seven: 7; + eight: 8; + nine: 9; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/mixin.order.conditional.styl b/node_modules/jade/support/stylus/test/cases/mixin.order.conditional.styl new file mode 100644 index 0000000..cacc666 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/mixin.order.conditional.styl @@ -0,0 +1,20 @@ +mixin2() + four 4 + if true + five 5 + +mixin() + mixin2() + if true + six 6 + if true + seven 7 + eight 8 if true + +body + one 1 + two 2 + three 3 + if true + mixin() + nine 9 \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/mixin.order.css b/node_modules/jade/support/stylus/test/cases/mixin.order.css new file mode 100644 index 0000000..3e4ab4d --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/mixin.order.css @@ -0,0 +1,9 @@ +body { + one: 1; + two: 2; + three: 3; + four: 4; + five: 5; + six: 6; + seven: 7; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/mixin.order.nested.css b/node_modules/jade/support/stylus/test/cases/mixin.order.nested.css new file mode 100644 index 0000000..3e4ab4d --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/mixin.order.nested.css @@ -0,0 +1,9 @@ +body { + one: 1; + two: 2; + three: 3; + four: 4; + five: 5; + six: 6; + seven: 7; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/mixin.order.nested.styl b/node_modules/jade/support/stylus/test/cases/mixin.order.nested.styl new file mode 100644 index 0000000..6a5e9fa --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/mixin.order.nested.styl @@ -0,0 +1,21 @@ + +mixin2() + three 3 + +mixin3() + four 4 + mixin4() + +mixin4() + five 5 + +mixin() + two 2 + mixin2() + mixin3() + six 6 + +body + one 1 + mixin() + seven 7 \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/mixin.order.styl b/node_modules/jade/support/stylus/test/cases/mixin.order.styl new file mode 100644 index 0000000..a873878 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/mixin.order.styl @@ -0,0 +1,20 @@ +mixin2() + three 3 + +mixin3() + four 4 + mixin4() + +mixin4() + five 5 + +mixin() + two 2 + mixin2() + mixin3() + six 6 + +body + one 1 + mixin() + seven 7 \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/mixins.complex.css b/node_modules/jade/support/stylus/test/cases/mixins.complex.css new file mode 100644 index 0000000..134973e --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/mixins.complex.css @@ -0,0 +1,30 @@ +ul li { + list-style-image: none; + list-style-type: none; + margin-left: 0; + display: -moz-inline-box; + -moz-box-orient: vertical; + display: inline-block; + vertical-align: middle; +} +ul li:first-child { + list-style-image: none; + list-style-type: none; + margin-left: 0; + display: -moz-inline-box; + -moz-box-orient: vertical; + display: inline-block; + vertical-align: middle; + padding-left: 5px; + padding-right: 5px; +} +body { + did: nothing; +} +body { + padding: 5px; +} +body { + padding: 5px; + margin: 5px; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/mixins.complex.fix-to.css b/node_modules/jade/support/stylus/test/cases/mixins.complex.fix-to.css new file mode 100644 index 0000000..f104b4d --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/mixins.complex.fix-to.css @@ -0,0 +1,15 @@ +.button { + position: fixed; + bottom: 0; + left: 0; +} +.button { + position: fixed; + bottom: 0; + left: 0; +} +.button { + position: fixed; + bottom: 5px; + left: 5px; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/mixins.complex.fix-to.styl b/node_modules/jade/support/stylus/test/cases/mixins.complex.fix-to.styl new file mode 100644 index 0000000..0609fbc --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/mixins.complex.fix-to.styl @@ -0,0 +1,28 @@ + +fix-to(a, b) + position fixed + {a} 0 + {b} 0 + +.button + fix-to bottom left + + +fix-to(pos...) + position fixed + if length(pos) == 2 + {pos[0]} 0 + {pos[1]} 0 + else if length(pos) == 4 + a = pos[0..1] + b = pos[2..3] + {a[0]} a[1] + {b[0]} b[1] + else + error('invalid arguments. fix-to: [n] [n];') + +.button + fix-to bottom left + +.button + fix-to bottom 5px left 5px \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/mixins.complex.styl b/node_modules/jade/support/stylus/test/cases/mixins.complex.styl new file mode 100644 index 0000000..f92bda4 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/mixins.complex.styl @@ -0,0 +1,41 @@ +no-bullet() + list-style-image none + list-style-type none + margin-left 0 + +inline-block() + display -moz-inline-box + -moz-box-orient vertical + display inline-block + vertical-align middle + +inline-block-list-item(padding = false) + no-bullet() + inline-block() + if padding + padding-left 5px + padding-right 5px + +ul + li + inline-block-list-item() + +ul li:first-child + inline-block-list-item(true) + +pad(pad = false, margin = false) + if pad + padding 5px + if margin + margin 5px + unless pad or margin + did nothing + +body + pad() + +body + pad(true) + +body + pad(true, true) \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/mixins.conditional.css b/node_modules/jade/support/stylus/test/cases/mixins.conditional.css new file mode 100644 index 0000000..f2f733b --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/mixins.conditional.css @@ -0,0 +1,3 @@ +body { + margin: 5px 10px; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/mixins.conditional.styl b/node_modules/jade/support/stylus/test/cases/mixins.conditional.styl new file mode 100644 index 0000000..07275b5 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/mixins.conditional.styl @@ -0,0 +1,8 @@ +overload-padding = true + +if overload-padding + padding(y, x) + margin y x + +body + padding 5px 10px \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/mixins.nested.css b/node_modules/jade/support/stylus/test/cases/mixins.nested.css new file mode 100644 index 0000000..1af8585 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/mixins.nested.css @@ -0,0 +1,7 @@ +body { + one: 1; + two: 1 2; + three: 1 2 3; + -three: 1 2 c; + -two: 1 b c; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/mixins.nested.selectors.css b/node_modules/jade/support/stylus/test/cases/mixins.nested.selectors.css new file mode 100644 index 0000000..ba2f23b --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/mixins.nested.selectors.css @@ -0,0 +1,21 @@ +body { + padding: 5px; + color: "bar"; +} +body .foo { + color: "bar"; +} +body .foo .bar { + color: "bar"; +} +body { + one: 1; + two: 2; + three: 3; +} +body with some nesting { + four: 4; +} +body with some nesting even more { + five: 5; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/mixins.nested.selectors.styl b/node_modules/jade/support/stylus/test/cases/mixins.nested.selectors.styl new file mode 100644 index 0000000..d828786 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/mixins.nested.selectors.styl @@ -0,0 +1,31 @@ + +mixin(n) + padding n + var = 'bar' + color var + .foo + color var + .bar + color var + +body + foo = 'foo' + mixin(5px) + +three(n) + three n + with some nesting + four n = n + 1 + even more + five n + 1 + +two(n) + two n + three(n + 1) + +one(n) + one n + two(n + 1) + +body + one(1) \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/mixins.nested.styl b/node_modules/jade/support/stylus/test/cases/mixins.nested.styl new file mode 100644 index 0000000..045e3a1 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/mixins.nested.styl @@ -0,0 +1,14 @@ + +one(a) + one a + two(b) + two a b + three(c) + three a b c + three(3) + -three a b c + two(2) + -two a b c + +body + one(1) diff --git a/node_modules/jade/support/stylus/test/cases/mixins.order.2.css b/node_modules/jade/support/stylus/test/cases/mixins.order.2.css new file mode 100644 index 0000000..1bf23eb --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/mixins.order.2.css @@ -0,0 +1,11 @@ +body { + one: 1; + two: 2; + three: 3; + four: 4; + five: 5; + six: 6; + seven: 7; + eight: 8; + nine: 9; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/mixins.order.2.styl b/node_modules/jade/support/stylus/test/cases/mixins.order.2.styl new file mode 100644 index 0000000..6cbe4e1 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/mixins.order.2.styl @@ -0,0 +1,16 @@ +test-nested() + two 2 + if true + three 3 + if true + four 4 + if true + five 5 + six 6 + seven 7 + eight 8 + +body + one 1 + test-nested() + nine 9 diff --git a/node_modules/jade/support/stylus/test/cases/mixins.return.css b/node_modules/jade/support/stylus/test/cases/mixins.return.css new file mode 100644 index 0000000..5f2b54e --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/mixins.return.css @@ -0,0 +1,4 @@ +body { + foo: bar; + bar: baz; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/mixins.return.styl b/node_modules/jade/support/stylus/test/cases/mixins.return.styl new file mode 100644 index 0000000..b37c764 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/mixins.return.styl @@ -0,0 +1,8 @@ +another() + foo bar + bar baz + return + baz raz + +body + another() \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/mixins.root.css b/node_modules/jade/support/stylus/test/cases/mixins.root.css new file mode 100644 index 0000000..7f8f806 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/mixins.root.css @@ -0,0 +1,3 @@ +body { + padding: 5px; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/mixins.root.styl b/node_modules/jade/support/stylus/test/cases/mixins.root.styl new file mode 100644 index 0000000..11e1378 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/mixins.root.styl @@ -0,0 +1,5 @@ +foo() + body + padding 5px + +foo() \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/mixins/box.styl b/node_modules/jade/support/stylus/test/cases/mixins/box.styl new file mode 100644 index 0000000..fd9085b --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/mixins/box.styl @@ -0,0 +1,11 @@ + +pad(x, y = x) + padding y x y x + +pad-x(n) + padding-left n + padding-right n + +pad-y(n) + padding-top n + padding-bottom n diff --git a/node_modules/jade/support/stylus/test/cases/operator.range.css b/node_modules/jade/support/stylus/test/cases/operator.range.css new file mode 100644 index 0000000..81f45cb --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/operator.range.css @@ -0,0 +1,15 @@ +body { + foo: 1 2 3 4 5; + foo: 1 2 3 4 5 6 7 8 9 10; + foo: 1; + foo: 1 2 3 4 5; + foo: 5; + foo: 2; + foo: 5; + foo: 6 7 8 9 10; + foo: true; + foo: true; +} +body { + foo: 1 2 3; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/operator.range.styl b/node_modules/jade/support/stylus/test/cases/operator.range.styl new file mode 100644 index 0000000..4b3cdc1 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/operator.range.styl @@ -0,0 +1,23 @@ +body + small = 1..5 + large = (1..5) (6..10) + + foo small + foo large + + foo small[0] + foo large[0] + + foo length(small) + foo length(large) + + foo small[length(small) - 1] + foo large[length(large) - 1] + + foo small[-1] == null + foo small[123123] == null + +body + start = 1 + end = 3 + foo start..end \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/operators.assignment.function.css b/node_modules/jade/support/stylus/test/cases/operators.assignment.function.css new file mode 100644 index 0000000..b4169d6 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/operators.assignment.function.css @@ -0,0 +1,15 @@ +body { + foo: 20; +} +body { + foo: 5; +} +body { + foo: 20; +} +body { + foo: 2.5; +} +body { + foo: 1; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/operators.assignment.function.styl b/node_modules/jade/support/stylus/test/cases/operators.assignment.function.styl new file mode 100644 index 0000000..eda512f --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/operators.assignment.function.styl @@ -0,0 +1,34 @@ + +test(n) + n += 5 + n += 5 + +body + foo test(10) + +test(n) + n -= 2 + n -= 3 + +body + foo test(10) + +test(n) + n *= 2 + n *= 2 + +body + foo test(5) + +test(n) + n /= 2 + n /= 4 + +body + foo test(20) + +test(n) + n %= 2 + +body + foo test(5) \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/operators.assignment.mixin.css b/node_modules/jade/support/stylus/test/cases/operators.assignment.mixin.css new file mode 100644 index 0000000..b4169d6 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/operators.assignment.mixin.css @@ -0,0 +1,15 @@ +body { + foo: 20; +} +body { + foo: 5; +} +body { + foo: 20; +} +body { + foo: 2.5; +} +body { + foo: 1; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/operators.assignment.mixin.styl b/node_modules/jade/support/stylus/test/cases/operators.assignment.mixin.styl new file mode 100644 index 0000000..6cbba10 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/operators.assignment.mixin.styl @@ -0,0 +1,39 @@ + +test(n) + n += 5 + n += 5 + foo n + +body + test(10) + +test(n) + n -= 2 + n -= 3 + foo n + +body + test(10) + +test(n) + n *= 2 + n *= 2 + foo n + +body + test(5) + +test(n) + n /= 2 + n /= 4 + foo n + +body + test(20) + +test(n) + n %= 2 + foo n + +body + test(5) \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/operators.assignment.root.css b/node_modules/jade/support/stylus/test/cases/operators.assignment.root.css new file mode 100644 index 0000000..0bcf506 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/operators.assignment.root.css @@ -0,0 +1,19 @@ +body { + foo: 20; + foo: 21; +} +body { + foo: 20; +} +body { + foo: 5; +} +body { + foo: 20; +} +body { + foo: 2.5; +} +body { + foo: 1; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/operators.assignment.root.styl b/node_modules/jade/support/stylus/test/cases/operators.assignment.root.styl new file mode 100644 index 0000000..63b2e17 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/operators.assignment.root.styl @@ -0,0 +1,43 @@ + + +n = 10 +a = n = n + 10 +a += 1 + +body + foo n + foo a + +n = 10 +n += 5 +n += 5 + +body + foo n + +n = 10 +n -= 2 +n -= 3 + +body + foo n + +n = 5 +n *= 2 +n *= 2 + +body + foo n + +n = 20 +n /= 2 +n /= 4 + +body + foo n + +n = 5 +n %= 2 + +body + foo n \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/operators.complex.css b/node_modules/jade/support/stylus/test/cases/operators.complex.css new file mode 100644 index 0000000..0e3319c --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/operators.complex.css @@ -0,0 +1,9 @@ +body { + foo: yes; + foo: true; + foo: yay; + foo: nah; + foo: nah; + foo: true; + foo: false; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/operators.complex.styl b/node_modules/jade/support/stylus/test/cases/operators.complex.styl new file mode 100644 index 0000000..ffdc6cb --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/operators.complex.styl @@ -0,0 +1,32 @@ + +ensure-unit(n) + foo bar + foo bar + foo bar + n is a 'unit' + +body + a = 15 + b = 15 + + // yes + foo a == b and (b == 15 ? 1 : 0) ? yes : no + + // true + foo a == b and b == a + + // yay + foo 15px is a 'unit' and #fff is a 'color'?yay:nah + + // nah + foo 15px is a 'color' and #fff is a 'color'?yay:nah + + // nah + foo 15px is a 'unit' and #fff is a 'unit'? yay : nah + + // true + foo ensure-unit(15) + + // false + foo ensure-unit(#fff) + diff --git a/node_modules/jade/support/stylus/test/cases/operators.css b/node_modules/jade/support/stylus/test/cases/operators.css new file mode 100644 index 0000000..7e87857 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/operators.css @@ -0,0 +1,32 @@ +body { + foo: 5px; + foo: 0px; + foo: 0px; + foo: false; + foo: true; + foo: 5px; + foo: 1px; + foo: 0; + foo: false; + foo: 10; + foo: #fff; + foo: 1; + foo: true; + foo: true; + foo: false; + foo: true; + foo: true; + foo: true; + foo: false; + foo: wahoo; + foo: nope; + foo: "got 15px"; + foo: 1; + foo: 5; + foo: true; + foo: true; + foo: true; + foo: false; + foo: false; + foo: false; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/operators.equality.css b/node_modules/jade/support/stylus/test/cases/operators.equality.css new file mode 100644 index 0000000..a0c3bb4 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/operators.equality.css @@ -0,0 +1,12 @@ +body { + foo: true; + foo: true; + foo: false; + foo: true; + foo: true; + foo: true; + foo: true; + foo: true; + foo: false; + foo: true; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/operators.equality.styl b/node_modules/jade/support/stylus/test/cases/operators.equality.styl new file mode 100644 index 0000000..452a7ad --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/operators.equality.styl @@ -0,0 +1,31 @@ +body + + // true + foo 1 != 5 + + // true + foo wahoo == wahoo + + // false + foo wahoo == something + + // true + foo wahoo != something + foo wahoo is not something + + // true + foo = yay + foo yes == (foo is defined ? yes : nope) + + // true + rawr = 'asdfasdf' + foo yes == (rawr is defined ? yes : nope) + + // true + foo 1000ms == 1s + + // false + foo 1ms == 1s + + // true + foo 5 < 10 and 10 > 5 \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/operators.in.css b/node_modules/jade/support/stylus/test/cases/operators.in.css new file mode 100644 index 0000000..77a7dcd --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/operators.in.css @@ -0,0 +1,36 @@ +body { + foo: true; + foo: true; + foo: false; +} +body { + foo: true; +} +body { + foo: true; + foo: true; + foo: false; +} +body { + foo: false; + foo: true; + foo: true; + foo: false; +} +body { + foo: false; + foo: false; + foo: true; + foo: false; + foo: true; +} +body { + foo: true; + foo: false; +} +body { + foo: true; + foo: false; + foo: true; + foo: true; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/operators.in.styl b/node_modules/jade/support/stylus/test/cases/operators.in.styl new file mode 100644 index 0000000..3d4e35a --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/operators.in.styl @@ -0,0 +1,50 @@ + + +body + nums = 1 2 3 + foo 1 in nums + foo 3 in nums + foo 5 in nums + +body + nums = 1 + foo 1 in nums == true + +body + words = foo bar baz + foo bar in words + foo baz in words + foo HEY in words + +body + tuples = (error 'one') (error 'two') + foo error in tuples + foo (error 'one') in tuples + foo (error 'two') in tuples + foo (error 'something') in tuples + +fn(args...) + 2 in args + +body + foo fn() + foo fn(1) + foo fn(2) + foo fn(3 2) + foo fn(1,2,3) + +fn(args...) + (3 2) in args + +body + foo fn(3 2) + foo fn(3,2) + +fn() + test in arguments + +body + foo fn(test) + foo fn(a, b, c) + foo fn(a, test, c) + foo fn(a test c) \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/operators.mixins.css b/node_modules/jade/support/stylus/test/cases/operators.mixins.css new file mode 100644 index 0000000..fd2479b --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/operators.mixins.css @@ -0,0 +1,10 @@ +body { + foo: false; + foo: true; + foo: true; + foo: false; + foo: false; + foo: "something"; + foo: "something"; + foo: "12"; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/operators.mixins.styl b/node_modules/jade/support/stylus/test/cases/operators.mixins.styl new file mode 100644 index 0000000..829f696 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/operators.mixins.styl @@ -0,0 +1,25 @@ + +stringish(val = false) + 'string' == type(val) or 'ident' == type(val) + +string(val) + '' + val + +body + // false + foo stringish(12) + + // true + foo stringish('12') + + // true + foo stringish(wahoo) + + // false + num = 12 + foo stringish(num) + foo stringish() + + foo string(something) + foo string('something') + foo string(12) \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/operators.precedence.css b/node_modules/jade/support/stylus/test/cases/operators.precedence.css new file mode 100644 index 0000000..e4959ce --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/operators.precedence.css @@ -0,0 +1,51 @@ +body { + foo: 4; + foo: 4; + foo: -5px; + foo: 2; + foo: 2; +} +body { + foo: true; + foo: true; +} +body { + foo: 5; + foo: 5; +} +body { + foo: true; + foo: true; + foo: true; + foo: true; + foo: 2; +} +body { + foo: true; + foo: true; +} +body { + foo: 2.5; + foo: 2.5; +} +body { + foo: true; + foo: true; + foo: false; + foo: wahoo; + foo: fail; +} +body { + foo: true; + foo: true; +} +body { + foo: true; + foo: 1; +} +body { + foo: true; + foo: true; + foo: false; + foo: true; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/operators.precedence.styl b/node_modules/jade/support/stylus/test/cases/operators.precedence.styl new file mode 100644 index 0000000..c228c58 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/operators.precedence.styl @@ -0,0 +1,82 @@ +body + // 4 + foo (--- 0) or 4 + // 4 + foo --- 0 or 4 + // -5px + foo ---5px + // 2 + foo (!!!5) or 2 + foo !!!5 or 2 + + +body + // true + foo !(! 5) + foo !!5 + +body + // 5 + foo (! false) and (! false) and 5 + foo ! false and ! false and 5 + +body + // true + foo (!!5 == true) or (!!0 == false) + foo !!5 == true or !!0 == false + foo (!!5 == false) or (!!0 == false) + foo !!5 == false or !!0 == false + // 2 + foo 5 < 10 and !!5 and 2 + +body + // true + foo (!!true) and (!!true) + foo !!true and !!true + +body + test() + 5 * 2 - 15 / 2 + // 2.5 + foo test() + foo (5 * 2) - (15 / 2) + +body + // true + foo not 5 < 10 ? 0 : 1 + // true + foo !(5 < 10 ? 0 : 1) + // false + foo !(5 > 10 ? 0 : 1) + // wahoo + foo !! 1 ? wahoo : fail + // fail + foo !1 ? wahoo : fail + +body + foo = 'test' + bar = 'test' + // true + foo (foo is defined) and (bar is defined) + foo foo is defined and bar is defined + +body + // true + foo 5 > 4 is a 'boolean' + + foo = type is a 'unit' ? type : 1 + // 1 + foo foo + +body + padding = false + margin = false + + // true + foo !padding or !margin + foo not padding or margin + + // false + foo not padding or margin == !padding or !margin + // true + foo (not padding or margin) == !padding or !margin diff --git a/node_modules/jade/support/stylus/test/cases/operators.styl b/node_modules/jade/support/stylus/test/cases/operators.styl new file mode 100644 index 0000000..b0fa171 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/operators.styl @@ -0,0 +1,86 @@ +body + // 5px + foo 0 || 5px + + // 0px + foo 0px || 5px + + // 0px + foo 0px || 0px + + // false + foo 0 or false + + // true + foo 0 || 0 || true + + // 5px + foo 1px && 5px + + // 1px + foo 0px && 1px + + // 0 + foo 1px && 0 + + // false + foo 1px and false + + // 10 + foo 5px && 5px && 10 + + // #fff + foo #000 && #fff + + // 1 + foo 8 && (4 && 1) + + // true + type = "color" + foo #fff is a type + foo #fff is a 'color' + + // false + foo 15px is a 'color' + // true + foo 15px is a 'unit' + + // true + foo 15px is a 'unit' and #fff is a 'color' + + // true + foo = 'bar' + + // true + bar = 'baz' + foo foo is defined and bar is defined + + // false + foo baz is defined + + // wahoo + foo bar is defined ? wahoo : nope + + // nope + foo rawr is defined ? yes : nope + + // "got 15px" + foo "got " + 15px + + // 1 + foo true and 1 or 5 + + // 5 + foo !false and !false and 5 + + // true + foo !!5 is true or !!0 is false + foo !!5 == false or !!0 == false + + // true + foo wahoo == wahoo + + // false + foo 0 == true + foo true == 0 + foo #fff == undefined diff --git a/node_modules/jade/support/stylus/test/cases/operators.subscript.css b/node_modules/jade/support/stylus/test/cases/operators.subscript.css new file mode 100644 index 0000000..5d5eac5 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/operators.subscript.css @@ -0,0 +1,59 @@ +body { + foo: true; + foo: 3 4 5; + foo: true; + foo: true; + foo: false; + foo: -5; +} +body { + foo: 1 2 3 4; + foo: 1; + foo: 2 3 4; + foo: 2; + foo: 3 4; + foo: 3; + foo: 4; + foo: ; +} +body { + foo: error; + foo: "message"; +} +body { + foo: 5; + foo: 10; +} +body { + foo: 5; + foo: 10; +} +body { + foo: 1 2; + foo: 3 4; + foo: 4; +} +body { + foo: 100 200; + foo: 100; + foo: 200; + foo: 2; +} +body { + foo: 100 200; + foo: 100; + foo: 200; + foo: 2; +} +body { + foo: 100 200; + foo: 100; + foo: 200; + foo: 2; +} +body { + foo: 100 200; + foo: 100; + foo: 200; + foo: 2; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/operators.subscript.range.css b/node_modules/jade/support/stylus/test/cases/operators.subscript.range.css new file mode 100644 index 0000000..e4c6b28 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/operators.subscript.range.css @@ -0,0 +1,14 @@ +body { + foo: a b; + foo: a b c; + foo: d e f; + foo: c d e; +} +body { + foo: 1 2 3 4; +} +body { + foo: ; + foo: ; + foo: ; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/operators.subscript.range.styl b/node_modules/jade/support/stylus/test/cases/operators.subscript.range.styl new file mode 100644 index 0000000..913a64b --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/operators.subscript.range.styl @@ -0,0 +1,15 @@ +body + vals = a b c d e f g + foo vals[0...2] + foo vals[0..2] + foo vals[3..5] + foo vals[2 3 4] + +body + vals = (1 2) (3 4) + foo vals[0..1] + +body + foo ()[] + foo ()[1] + foo ()[1..3] \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/operators.subscript.styl b/node_modules/jade/support/stylus/test/cases/operators.subscript.styl new file mode 100644 index 0000000..5d69430 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/operators.subscript.styl @@ -0,0 +1,81 @@ +body + foo ()[0] == null + foo (1(2(3 4 5)))[1][1] + foo (1 2 3)['test'] == null + foo !(1 0)[1] + foo !(1 0)[0] + foo - - -(1 2 3 4 5)[4] + +body + foo (1 (2 (3 4))) + foo (1 (2 (3 4)))[0] + foo (1 (2 (3 4)))[1] + foo (1 (2 (3 4)))[1][0] + foo (1 (2 (3 4)))[1][1] + foo (1 (2 (3 4)))[1][1][0] + foo (1 (2 (3 4)))[1][1][1] + foo (1 (2 (3 4)))[1][1][3] + +body + foo (error 'message')[0] + foo (error 'message')[1] + +size(a, b) + return a b + +body + foo size(5, 10)[0] + foo size(5, 10)[1] + +size(a, b) + (a b) + +body + foo size(5, 10)[0] + foo size(5, 10)[1] + +size() + (1 2) (3 4) + +body + foo size()[0] + foo size()[1] + foo size()[1][1] + +image-size(path) + w = 100 + h = 200 + return w h + +body + size = image-size('test.png') + foo size + foo size[0] + foo size[1] + foo length(size) + +image-size(path) + 100 200 + +body + size = image-size('test.png') + foo size + foo size[0] + foo size[1] + foo length(size) + +size = 100 200 + +body + foo size + foo size[0] + foo size[1] + foo length(size) + +size = (100 200) + +body + foo size + foo size[0] + foo size[1] + foo length(size) diff --git a/node_modules/jade/support/stylus/test/cases/page.css b/node_modules/jade/support/stylus/test/cases/page.css new file mode 100644 index 0000000..9adf972 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/page.css @@ -0,0 +1,13 @@ +@page { + margin: 2.5cm; +} +@page :left { + margin-left: 5cm; +} +@page :right { + margin-right: 5cm; +} +@page :first { + margin-top: 8cm; + background: white; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/page.styl b/node_modules/jade/support/stylus/test/cases/page.styl new file mode 100644 index 0000000..d088a29 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/page.styl @@ -0,0 +1,13 @@ + +@page + margin 2.5cm + +@page :left + margin-left 5cm + +@page :right + margin-right 5cm + +@page :first + margin-top 8cm + background white diff --git a/node_modules/jade/support/stylus/test/cases/parent.css b/node_modules/jade/support/stylus/test/cases/parent.css new file mode 100644 index 0000000..ba03b37 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/parent.css @@ -0,0 +1,32 @@ +.button { + padding: 5px; + -webkit-transition: opacity 1s ease-out; +} +.button:hover { + opacity: 2; +} +textarea, +input { + color: #a7a7a7; +} +textarea:hover, +input:hover { + color: #000; +} +.dim { + opacity: 0.2; +} +.dim:hover, +.dim.show { + opacity: 1; +} +body #login { + -webkit-box-shadow: 1px 1px 3px #eee; + -moz-box-shadow: 1px 1px 3px #eee; + box-shadow: 1px 1px 3px #eee; +} +html.ie8 body #login, +html.ie7 body #login foo, +html.ie6 body #login { + border: solid 1px #eee; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/parent.styl b/node_modules/jade/support/stylus/test/cases/parent.styl new file mode 100644 index 0000000..405c79c --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/parent.styl @@ -0,0 +1,33 @@ +dim-on-hover() + -webkit-transition opacity 1s ease-out + &:hover + opacity 2 + +.button + padding 5px + dim-on-hover() + +textarea +input + color #A7A7A7 + &:hover + color #000 + +.dim + opacity .2 + &:hover + &.show + opacity 1 + +box-shadow() + -webkit-box-shadow arguments + -moz-box-shadow arguments + box-shadow arguments + html.ie8 &, + html.ie7 & foo, + html.ie6 & + border solid 1px arguments[length(arguments) - 1] + +body + #login + box-shadow 1px 1px 3px #eee \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/properties.colons.css b/node_modules/jade/support/stylus/test/cases/properties.colons.css new file mode 100644 index 0000000..beb90bb --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/properties.colons.css @@ -0,0 +1,8 @@ +body { + margin: 5px; + padding: 5px; + foo: 5px; +} +body something { + here: whoop; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/properties.colons.styl b/node_modules/jade/support/stylus/test/cases/properties.colons.styl new file mode 100644 index 0000000..d932bc6 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/properties.colons.styl @@ -0,0 +1,10 @@ + +mixin() + foo: 5px + something + here: whoop + +body + margin: 5px + padding: 5px + mixin() \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/properties.css b/node_modules/jade/support/stylus/test/cases/properties.css new file mode 100644 index 0000000..12e1ccb --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/properties.css @@ -0,0 +1,4 @@ +#wrapper { + padding: 5px; + white-space: nowrap; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/properties.one-line.css b/node_modules/jade/support/stylus/test/cases/properties.one-line.css new file mode 100644 index 0000000..f881297 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/properties.one-line.css @@ -0,0 +1,10 @@ +body { + background: #00f; + width: 100px; + height: 50px; +} +body { + background: #00f; + width: 100px; + height: 50px; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/properties.one-line.styl b/node_modules/jade/support/stylus/test/cases/properties.one-line.styl new file mode 100644 index 0000000..834fd93 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/properties.one-line.styl @@ -0,0 +1,11 @@ +bg() + background: blue; + +body { + bg(); width: 100px; + height: 50px; +} + +body + bg(); width 100px; + height 50px \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/properties.styl b/node_modules/jade/support/stylus/test/cases/properties.styl new file mode 100644 index 0000000..944256f --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/properties.styl @@ -0,0 +1,4 @@ + +#wrapper + padding 5px + white-space nowrap \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/regression.107.lookup-failure.css b/node_modules/jade/support/stylus/test/cases/regression.107.lookup-failure.css new file mode 100644 index 0000000..1d81a68 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/regression.107.lookup-failure.css @@ -0,0 +1,12 @@ +button { + background: #e3e3e3; +} +button:hover { + background: #dbdbdb; +} +button:active { + background: #d6d6d6; +} +button nested really-nested with-even-more-nesting { + background: #e3e3e3; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/regression.107.lookup-failure.styl b/node_modules/jade/support/stylus/test/cases/regression.107.lookup-failure.styl new file mode 100644 index 0000000..cd55bc8 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/regression.107.lookup-failure.styl @@ -0,0 +1,13 @@ +minimal-button(bg = #e3e3e3) + background bg + &:hover + background darken(bg, 3%) + &:active + background darken(bg, 5%) + nested + really-nested + with-even-more-nesting + background bg + +button + minimal-button() \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/regression.127.css b/node_modules/jade/support/stylus/test/cases/regression.127.css new file mode 100644 index 0000000..3a27438 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/regression.127.css @@ -0,0 +1,3 @@ +body { + background: #c3210d; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/regression.127.styl b/node_modules/jade/support/stylus/test/cases/regression.127.styl new file mode 100644 index 0000000..f0128c7 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/regression.127.styl @@ -0,0 +1,2 @@ +body + background #c3210d \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/regression.130.css b/node_modules/jade/support/stylus/test/cases/regression.130.css new file mode 100644 index 0000000..42dfaa6 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/regression.130.css @@ -0,0 +1,16 @@ +body { + font: 13px / 1.231; +} +body { + font: 13px / 1.231; +} +body { + font: 13px / 1.231; +} +body { + font: 13px / 1.231; +} +body { + font: 13px / 1.231; + background: #fff; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/regression.130.styl b/node_modules/jade/support/stylus/test/cases/regression.130.styl new file mode 100644 index 0000000..0285947 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/regression.130.styl @@ -0,0 +1,6 @@ + +body { font: 13px / 1.231; } +body {font: 13px / 1.231;} +body {font: 13px / 1.231} +body { font : 13px / 1.231 } +body { font : 13px / 1.231; background: white } \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/regression.131.css b/node_modules/jade/support/stylus/test/cases/regression.131.css new file mode 100644 index 0000000..4a7e264 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/regression.131.css @@ -0,0 +1,6 @@ +body { + font-weight: normal; +} +body { + color: #fff; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/regression.131.styl b/node_modules/jade/support/stylus/test/cases/regression.131.styl new file mode 100644 index 0000000..feb1768 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/regression.131.styl @@ -0,0 +1,2 @@ +body { font-weight: normal; } /* foo */ +body { color: #fff; } // foo \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/regression.137.css b/node_modules/jade/support/stylus/test/cases/regression.137.css new file mode 100644 index 0000000..01f1085 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/regression.137.css @@ -0,0 +1,7 @@ +#fea-ca { + padding: 5px; +} +#ffffff { + padding: 5px; + foo: #fea -ca; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/regression.137.styl b/node_modules/jade/support/stylus/test/cases/regression.137.styl new file mode 100644 index 0000000..5b7e560 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/regression.137.styl @@ -0,0 +1,7 @@ + +#fea-ca + padding 5px + +#ffffff + padding 5px + foo #fea-ca \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/regression.139.css b/node_modules/jade/support/stylus/test/cases/regression.139.css new file mode 100644 index 0000000..0101baf --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/regression.139.css @@ -0,0 +1,5 @@ +body { + foo: bottom; + foo: right; + foo: bottom right; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/regression.139.styl b/node_modules/jade/support/stylus/test/cases/regression.139.styl new file mode 100644 index 0000000..12791e9 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/regression.139.styl @@ -0,0 +1,21 @@ + +opposite-position(pos) { + return bottom if pos == top; + return top if pos == bottom; + return right if pos == left; + return left if pos == right; + error('Invalid position ' + pos) +} + +opposite(positions) { + for pos in positions { + pos = opposite-position(pos); + ret = ret is defined ? ret pos : pos; + } +} + +body { + foo: opposite(top); + foo: opposite(left); + foo: opposite(top left); +} diff --git a/node_modules/jade/support/stylus/test/cases/regression.142.css b/node_modules/jade/support/stylus/test/cases/regression.142.css new file mode 100644 index 0000000..b5a45ee --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/regression.142.css @@ -0,0 +1,39 @@ +foo, +bar, +baz { + display: none; +} +foo, +bar, +baz { + display: none; +} +body :nth-child(2), +body foo bar, +body bar, +body baz { + display: none; +} +body { + foo: bar; +} +body bar, +body baz { + display: none; +} +body foo, +body bar, +body baz { + display: none; +} +body foo, +body :nth-child(2), +body bar { + display: none; +} +body { + foo: bar; +} +body { + foo: 3; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/regression.142.styl b/node_modules/jade/support/stylus/test/cases/regression.142.styl new file mode 100644 index 0000000..f27c86d --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/regression.142.styl @@ -0,0 +1,54 @@ + +foo, bar, baz + display none + +foo +bar +baz + display none + +body + :nth-child(2) + foo bar + bar + baz + display none + +body + foo bar + bar + baz + display none + +body + foo + bar + baz + display none + +body + foo + :nth-child(2) + bar + display none + +fn() + bar if true; + +something() + one + two + fn() + +body + foo something() + +something() + nums = 1 2 3 + one + two + for n in nums + n + +body + foo something() \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/regression.146.css b/node_modules/jade/support/stylus/test/cases/regression.146.css new file mode 100644 index 0000000..b18dfbc --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/regression.146.css @@ -0,0 +1,30 @@ +input[for=name] { + width: 200px; +} +body { + foo: 1; +} +body { + foo: 2; +} +body { + foo: 3; +} +body foo { + bar: 1; + bar: 2; + bar: 3; +} +#login foo, +#login input[for=name] { + foo: bar; +} +#login foo input[for=name] { + bar: 1; +} +#login foo input[for=name] { + bar: 2; +} +#login foo input[for=name] { + bar: 3; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/regression.146.styl b/node_modules/jade/support/stylus/test/cases/regression.146.styl new file mode 100644 index 0000000..b4ecdf6 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/regression.146.styl @@ -0,0 +1,31 @@ +input[for=name] + width 200px + +nums = 1 2 3 +for n in nums + body + foo n + +body + foo + for n in nums + bar n + +something() + nums = 1 2 3 + foo + input[for=name] + foo bar + +#login + something() + +something() + nums = 1 2 3 + foo + for n in nums + input[for=name] + bar n + +#login + something() \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/regression.153.css b/node_modules/jade/support/stylus/test/cases/regression.153.css new file mode 100644 index 0000000..1e76441 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/regression.153.css @@ -0,0 +1,8 @@ +#content { + width: 960px; +} +@media screen { + #content { + width: 640px; + } +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/regression.153.styl b/node_modules/jade/support/stylus/test/cases/regression.153.styl new file mode 100644 index 0000000..1691e85 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/regression.153.styl @@ -0,0 +1,9 @@ +cols(n) + width 160px * n + +#content + cols 6 + +@media screen + #content + cols 4 \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/regression.154.css b/node_modules/jade/support/stylus/test/cases/regression.154.css new file mode 100644 index 0000000..ffa182a --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/regression.154.css @@ -0,0 +1,8 @@ +body { + foo: true; + foo: false; +} +body { + foo: false; + foo: true; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/regression.154.styl b/node_modules/jade/support/stylus/test/cases/regression.154.styl new file mode 100644 index 0000000..40587a5 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/regression.154.styl @@ -0,0 +1,14 @@ + +light(color) + lightness(color) >= 50% + +dark(color) + lightness(color) < 50% + +body + foo light(white) + foo light(black) + +body + foo dark(white) + foo dark(black) \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/regression.156.css b/node_modules/jade/support/stylus/test/cases/regression.156.css new file mode 100644 index 0000000..b418755 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/regression.156.css @@ -0,0 +1,4 @@ +body { + padding-right: 0; + float: right; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/regression.156.styl b/node_modules/jade/support/stylus/test/cases/regression.156.styl new file mode 100644 index 0000000..81de24b --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/regression.156.styl @@ -0,0 +1,6 @@ +body + mixin() + +body + padding-{opposite-position(left)} 0 + float opposite-position(left) \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/rule.charset.css b/node_modules/jade/support/stylus/test/cases/rule.charset.css new file mode 100644 index 0000000..b98ffb5 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/rule.charset.css @@ -0,0 +1 @@ +@charset "utf-8" \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/rule.charset.styl b/node_modules/jade/support/stylus/test/cases/rule.charset.styl new file mode 100644 index 0000000..6cc76dd --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/rule.charset.styl @@ -0,0 +1,2 @@ + +@charset "utf-8" \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/rulset.css b/node_modules/jade/support/stylus/test/cases/rulset.css new file mode 100644 index 0000000..be7adab --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/rulset.css @@ -0,0 +1,4 @@ +textarea, +input { + border: 1px solid #eee; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/rulset.newline.css b/node_modules/jade/support/stylus/test/cases/rulset.newline.css new file mode 100644 index 0000000..4249e51 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/rulset.newline.css @@ -0,0 +1,5 @@ +textarea, +input, +.text { + border: 1px solid #eee; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/rulset.newline.styl b/node_modules/jade/support/stylus/test/cases/rulset.newline.styl new file mode 100644 index 0000000..b4b4a20 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/rulset.newline.styl @@ -0,0 +1,5 @@ + +textarea +input +.text + border 1px solid #eee \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/rulset.styl b/node_modules/jade/support/stylus/test/cases/rulset.styl new file mode 100644 index 0000000..6a2ad9a --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/rulset.styl @@ -0,0 +1,3 @@ + +textarea, input + border 1px solid #eee \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/scope.complex.css b/node_modules/jade/support/stylus/test/cases/scope.complex.css new file mode 100644 index 0000000..e59bd0e --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/scope.complex.css @@ -0,0 +1,10 @@ +body { + margin: 24px; + padding: 12px 5px 12px 5px; + font-size: 50px; +} +form input { + border: 3px solid #000; + margin: 24px; + padding: 2px 1px 2px 1px; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/scope.complex.styl b/node_modules/jade/support/stylus/test/cases/scope.complex.styl new file mode 100644 index 0000000..c743dca --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/scope.complex.styl @@ -0,0 +1,16 @@ + +size = 12px +size-large = size * 2 + +pad(x, y = size) + margin size-large + padding y x y x + +body + size = 50px + pad(5px) + font-size size + +form input + border (size / 4) solid black + pad(1px, 2px) \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/scope.css b/node_modules/jade/support/stylus/test/cases/scope.css new file mode 100644 index 0000000..385c11c --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/scope.css @@ -0,0 +1,5 @@ +body { + margin: 24px; + padding: 12px 5px 12px 5px; + font-size: 50px; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/scope.nested.css b/node_modules/jade/support/stylus/test/cases/scope.nested.css new file mode 100644 index 0000000..68e058a --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/scope.nested.css @@ -0,0 +1,9 @@ +body { + font: 5; +} +body .large { + font: 10; +} +body .other { + font: 15; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/scope.nested.styl b/node_modules/jade/support/stylus/test/cases/scope.nested.styl new file mode 100644 index 0000000..9f4f602 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/scope.nested.styl @@ -0,0 +1,10 @@ + +body + size = 5 + font size + .large + large = size * 2 + font large + .other + large ?= size * 3 + font large \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/scope.styl b/node_modules/jade/support/stylus/test/cases/scope.styl new file mode 100644 index 0000000..9ff2dd3 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/scope.styl @@ -0,0 +1,12 @@ + +size = 12px +size-large = size * 2 + +pad(x, y = size) + margin size-large + padding y x y x + +body + size = 50px + pad(5px) + font-size size diff --git a/node_modules/jade/support/stylus/test/cases/selectors.complex.css b/node_modules/jade/support/stylus/test/cases/selectors.complex.css new file mode 100644 index 0000000..8bd00cb --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/selectors.complex.css @@ -0,0 +1,28 @@ +body form input.hide, +body foo bar, +body .hidden, +body:hover, +body:focus { + display: none; +} +body form input, +body .hidden { + display: none; +} +ul > li { + padding: 5px; + border: 1px solid #eee; +} +ul > li:first-child, +ul > li:last-child { + border: none; +} +ul > li:first-child { + padding-top: 0; +} +ul > li:last-child { + padding-bottom: 0; +} +body form > input:nth-child(2) { + border: 1px solid #eee; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/selectors.complex.styl b/node_modules/jade/support/stylus/test/cases/selectors.complex.styl new file mode 100644 index 0000000..397f5b5 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/selectors.complex.styl @@ -0,0 +1,27 @@ +body + form input.hide, + foo bar, + .hidden + &:hover + &:focus + display none + +body + form input, .hidden + display none + +ul + > li + padding 5px + border 1px solid #eee + &:first-child, + &:last-child + border none + &:first-child + padding-top 0 + &:last-child + padding-bottom 0 + +body + form > input:nth-child(2) + border 1px solid #eee \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/selectors.css b/node_modules/jade/support/stylus/test/cases/selectors.css new file mode 100644 index 0000000..a95cbdf --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/selectors.css @@ -0,0 +1,44 @@ +foo bar baz { + foo: bar; +} +foo > bar { + foo: bar; +} +input[type=text] { + foo: bar; +} +input[type="text"] { + foo: bar; +} +* { + foo: bar; +} +* .foo-bar { + foo: bar; +} +body > #container * { + foo: bar; +} +#foo > #bar + .baz { + foo: bar; +} +#foo>#bar { + foo: bar; +} +p + p ~ p { + foo: bar; +} +ul :odd { + foo: bar; +} +ul > li:last-child { + foo: bar; +} +ul > li:nth-child(2n) { + foo: bar; +} +*, +p + p, +ul > li { + foo: bar; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/selectors.nested.comma.css b/node_modules/jade/support/stylus/test/cases/selectors.nested.comma.css new file mode 100644 index 0000000..e2a4da8 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/selectors.nested.comma.css @@ -0,0 +1,9 @@ +#container .hide, +#footer .hide { + display: none; +} +#foo .hide .stuff, +#bar .hide .stuff, +#baz .hide .stuff { + display: none; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/selectors.nested.comma.styl b/node_modules/jade/support/stylus/test/cases/selectors.nested.comma.styl new file mode 100644 index 0000000..38a1ccf --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/selectors.nested.comma.styl @@ -0,0 +1,8 @@ +#container, #footer + .hide + display none + +#foo, #bar, #baz + .hide + .stuff + display none diff --git a/node_modules/jade/support/stylus/test/cases/selectors.nested.css b/node_modules/jade/support/stylus/test/cases/selectors.nested.css new file mode 100644 index 0000000..54f17f1 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/selectors.nested.css @@ -0,0 +1,34 @@ +form .foo { + color: #000; +} +form .foo .bar { + padding: 5px; + color: #f00; +} +body .foo .bar { + display: none; +} +body .foo .baz, +body .bar .baz, +body .foo .sdf, +body .bar .sdf { + display: none; +} +.foo .baz, +.bar .baz, +.foo .raz, +.bar .raz { + something: "else"; +} +.foo .baz, +.bar .baz, +.foo .raz, +.bar .raz { + background: #f00; +} +.foo .baz .ASDF, +.bar .baz .ASDF, +.foo .raz .ASDF, +.bar .raz .ASDF { + background: #fff; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/selectors.nested.styl b/node_modules/jade/support/stylus/test/cases/selectors.nested.styl new file mode 100644 index 0000000..dbe2170 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/selectors.nested.styl @@ -0,0 +1,33 @@ + +form + .foo + color black + .bar + padding 5px + color red + +body + .foo + .bar + display none + +body + .foo + .bar + .baz + .sdf + display none + +.foo +.bar + .baz + .raz + something 'else' + +.foo +.bar + .baz + .raz + background red + .ASDF + background white \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/selectors.pseudo.css b/node_modules/jade/support/stylus/test/cases/selectors.pseudo.css new file mode 100644 index 0000000..d5ef504 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/selectors.pseudo.css @@ -0,0 +1,27 @@ +ul td:nth-of-type(2), +ul td:nth-of-type(3) { + background: #000; +} +table td:nth-child(2), +table td:nth-child(3), +table td:nth-child(4), +table td:nth-child(5), +table td::first-letter { + background: #000; +} +table td:nth-child(2) li:first-child, +table td:nth-child(3) li:first-child, +table td:nth-child(4) li:first-child, +table td:nth-child(5) li:first-child, +table td::first-letter li:first-child, +table td:nth-child(2) li:last-child, +table td:nth-child(3) li:last-child, +table td:nth-child(4) li:last-child, +table td:nth-child(5) li:last-child, +table td::first-letter li:last-child { + background: #fff; +} +table :nth-child(2), +table :nth-child(3) { + background: #000; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/selectors.pseudo.styl b/node_modules/jade/support/stylus/test/cases/selectors.pseudo.styl new file mode 100644 index 0000000..e235a18 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/selectors.pseudo.styl @@ -0,0 +1,24 @@ + +mixin() + td:nth-of-type(2) + td:nth-of-type(3) + background black + +ul + mixin() + +table + td:nth-child(2) + td:nth-child(3) + td:nth-child(4) + td:nth-child(5) + td::first-letter + background black + li:first-child + li:last-child + background white + +table + :nth-child(2) + :nth-child(3) + background black \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/selectors.styl b/node_modules/jade/support/stylus/test/cases/selectors.styl new file mode 100644 index 0000000..f3a5b32 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/selectors.styl @@ -0,0 +1,41 @@ + +foo bar baz + foo bar + +foo > bar + foo bar + +input[type=text] + foo bar + +input[type="text"] + foo bar + +* + foo bar + +* .foo-bar + foo bar + +body > #container * + foo bar + +#foo > #bar + .baz + foo bar +#foo>#bar + foo bar + +p + p ~ p + foo bar + +ul :odd + foo bar + +ul > li:last-child + foo bar + +ul > li:nth-child(2n) + foo bar + +*, p + p, ul > li + foo bar \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/self-assignment.css b/node_modules/jade/support/stylus/test/cases/self-assignment.css new file mode 100644 index 0000000..deaf803 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/self-assignment.css @@ -0,0 +1,3 @@ +body { + background: #fff; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/self-assignment.styl b/node_modules/jade/support/stylus/test/cases/self-assignment.styl new file mode 100644 index 0000000..86ed143 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/self-assignment.styl @@ -0,0 +1,4 @@ +color = white +color = color is defined ? color : black +body + background color \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/vargs.call.css b/node_modules/jade/support/stylus/test/cases/vargs.call.css new file mode 100644 index 0000000..e9f521e --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/vargs.call.css @@ -0,0 +1,24 @@ +body { + padding: 5px; + padding: 5px 10px; +} +body { + padding: 5px ; + padding: 5px 10px; +} +body { + padding: 5px; + padding: 5px 10px; + padding: 5px 10px 0 2px; +} +body { + test-y: 1px; + test-y: 1px; + padding: 2px 3px; +} +body { + test-y: 1px; + test-x: ; + test-y: 1px; + test-x: 2px; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/vargs.call.styl b/node_modules/jade/support/stylus/test/cases/vargs.call.styl new file mode 100644 index 0000000..bd62e64 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/vargs.call.styl @@ -0,0 +1,40 @@ + +padding(n) + padding n + +body + padding(5px) + padding(5px 10px) + +padding(y, x = null) + padding y x + +body + padding(5px) + padding(5px, 10px) + +padding(args...) + padding args + +body + padding(5px) + padding(5px, 10px) + padding(5px, 10px, 0 2px) + +padding(y, rest...) + test-y y + if rest + padding rest + +body + padding(1px) + padding(1px, 2px, 3px) + +padding(args...) + if args + test-y args[0] + test-x args[1] + +body + padding(1px) + padding(1px, 2px) \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/vargs.css b/node_modules/jade/support/stylus/test/cases/vargs.css new file mode 100644 index 0000000..7db9f11 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/vargs.css @@ -0,0 +1,30 @@ +body { + padding: 5px; + padding: 5px; +} +body { + padding: 5px ; + padding: 5px 10px; +} +body { + padding: 5px; + padding: 5px 10px; + padding: 5px 10px 0 2px; +} +body { + test-y: 1px; + test-y: 1px; + padding: 2px 3px; +} +body { + test-y: 1px; + test-x: ; + test-y: 1px; + test-x: 2px; +} +body { + pad: 1; + pad: 2; + pad: 3 4 5; + len: 3; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/vargs.styl b/node_modules/jade/support/stylus/test/cases/vargs.styl new file mode 100644 index 0000000..297b2b8 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/vargs.styl @@ -0,0 +1,49 @@ + +padding(n) + padding n + +body + padding 5px + padding 5px 10px + +padding(y, x = null) + padding y x + +body + padding 5px + padding 5px 10px + +padding(args...) + padding args + +body + padding 5px + padding 5px 10px + padding 5px 10px 0 2px + +padding(y, rest...) + test-y y + if rest + padding rest + +body + padding 1px + padding 1px 2px 3px + +padding(args...) + if args + test-y args[0] + test-x args[1] + +body + padding 1px + padding 1px 2px + +padding(args...) + pad args[0] + pad args[1] + pad args[2] + len length(args) + +body + padding 1 2 (3 4 5) \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/variable.css b/node_modules/jade/support/stylus/test/cases/variable.css new file mode 100644 index 0000000..1ff59e5 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/variable.css @@ -0,0 +1,3 @@ +body { + font: 12px; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/variable.styl b/node_modules/jade/support/stylus/test/cases/variable.styl new file mode 100644 index 0000000..7b7c990 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/variable.styl @@ -0,0 +1,4 @@ +size = 12px + +body + font size \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/variables.css b/node_modules/jade/support/stylus/test/cases/variables.css new file mode 100644 index 0000000..45f21d7 --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/variables.css @@ -0,0 +1,12 @@ +body { + color: 204; +} +body { + font: 14px "Lucida Grande", Arial, sans-serif; + padding: 5px; + margin: 5px; +} +a { + font: 11px Impact, "Lucida Grande", Arial, sans-serif, serif; + border: 1px solid #fff; +} \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/cases/variables.styl b/node_modules/jade/support/stylus/test/cases/variables.styl new file mode 100644 index 0000000..faf4ced --- /dev/null +++ b/node_modules/jade/support/stylus/test/cases/variables.styl @@ -0,0 +1,17 @@ + +size = 14px +font-family = 'Lucida Grande', Arial, sans-serif +$type = solid +blue = #00c + +body + color blue(blue) + +body + font size font-family + padding pad = 5px + margin pad + +a + font 11px Impact, font-family, serif + border 1px $type #fff \ No newline at end of file diff --git a/node_modules/jade/support/stylus/test/images/gif b/node_modules/jade/support/stylus/test/images/gif new file mode 100644 index 0000000000000000000000000000000000000000..b3989fc3c149e41c80cbaa03d33ee82c97397976 GIT binary patch literal 59920 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

    $4XOE=egZ3471rYlE*#RH*ieLNk^^kd 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 literal 0 HcmV?d00001 diff --git a/node_modules/jade/support/stylus/test/images/squirrel.jpeg b/node_modules/jade/support/stylus/test/images/squirrel.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..030ce1af21e95fdbc78bbf7ce23ccaad80347c9b GIT binary patch literal 21805 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 literal 0 HcmV?d00001 diff --git a/node_modules/jade/support/stylus/test/images/tux.png b/node_modules/jade/support/stylus/test/images/tux.png new file mode 100644 index 0000000000000000000000000000000000000000..df25ec4e45762ec5ffb4d62c1c4ea9a9db3cd225 GIT binary patch literal 41236 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ΝS%2?pd-%iml2 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�Uw`($_+hi3~iInAhSe;JEHXCeMoCQsGlK00Jf(R$B zO@~{nI+U?UJxM?E)4nq$wxjw6WrVhZAZzo-S8{zQX<$nQA3gEJCce~Y1@dj6~uH*2;1 zD2TGY-AB$J+EIr==jK}qPae98I`!c_jp-zli}**|eWnUl%=3v&)aIKFQ!XrX=^fg9 z8-|MNhsH6EEnpjVZTSC*+x!*F^yCK*$Bl-CS>X0J_3)GC z)ZukuzT9(^$q4)_;-*j;$GZ|$h7?pfnLJ&O{C=wjg(9)3$1VYklh%>b@H8#K8jd*0 z5TtDA2}2y$HyYnu^lFcE`K2kIq^S9n-3DICXoT4}MutN2yc4IgpCk68EzGtA(4!Sy z3LncMje_3D7EmWleVo&t%^G^dexN6{*yLR|ckp;hRB%vLVy%%|?12;tY`8Vp0tMyBIzXS&>B!Ds6g_V8xT5WLxg_8n0QOiAvQ-&SL6Z zgVUb)H}E4%mxB2R7!w7DV*LpX-)Co5zjZT))xpuzGnXC$>OHyYdc99bqE)l~)piOB zx_j6DyNp&zlYqJQ@r-ha@Zw7U)TRDFm5T-LMVXGK2HR_Wo$uI}q)3+LGh-2yPH7(# z6VWO(b1O&=ROTU>wKXHvD28(z1MdQVg7U!pq!iVqdzF(KRlH9BF%5K%gW!de6i$rh z^P0PdDi<9&&@H)G0N*|)PZ+MW=6-)52ZM&Ob&tB7l8K z>Y|TEMtJSg7Eu9p`{u6H0rpCImJI;UG%q47nLWR8dJrV#I`! zB`RkYBKpEkl`O>ESh!GOJ?c93%!z0=@DWgdLOjA&DoS^`&=Y&Y=|In<4!J?)`B_#l z_sk9r71W94%%Rkd=1;&nx5?yv5wGvEmfP9Wp1fgeNgSA_U3S%X&)j35gy8@KPzn zu>3TVATq$;gAX+i=pnHjI_u6*lno-&B|B6xa8fPY(Lt?q2zyI&T24GUe=LU5u;w=lD2_MgOL|OLOzBStP1yJy>+4ZC&rchj84erbHT^ zIVEXT83S~gbICW;J$UO{-fLHDV4d%vA8 z{^c(`ih7WT%y$yxzJ&&BMI|LE;~7qf`!0Yx-nsU@R8Uap3HH1qn0q7$5XK2v_~aM) zdF(w)gg6HE7l|;u?61?2s_iX@lbrS5!PpxrQUQonL<>URsVj!5lHIGV&5Eq2zm3oj zHw0)Bv5dBhdNO*1a$zbCrH7>SrP%C47L6!P90FHsvB8+dKjH6|xOevUKum2IUQCao z241Zxg$f@ZXD|<{XyMEGmRlS*Bu5Xc@1iNn{QzNL0U&>Ic3ven3%u!8yX?GOwFZ>h zyV!V+MC(_^L}XQJl$_Dx$pF~DC=5yTvWDr=BjVToCQi05-)r;TO4RE(s!bl~zFv=p z&lrY~@kAdzH@BCzBHd*$BpNS=KyOzXq3C*`B_ zIBDuS{wv!S*I;*{H%OwIeoGbvTqpuMQd!-K zrYBJ{=?9-hasa56(iBntju-g zXtAGjexJ6*Evm1msd&;!%}Nycp+ObslD`#U3yb=xT_*DjfUh9CZB{=0^a^4cV(KM{2|2E(PzkK_g9O5#_5K^x$7Jv+_3+z>-sRRB-TGdfz15xi_ z3kIl_z#tk9p-xoABVp+bKMD`)JUDciyGsVUcaAsgbX%)N<3Z3t>?r8SKRl@*{d!Q# z9#mNRlcl0M8=3qiF*&&pFpBNy)H2|+$+(hFib0!@;_#;O;^6AL9Aq0-RAeVMf}c-YAT5Bh!xIa2j4iQXm{5-ItFV6ne_ zC@r?{7wO&WlMz2$a%I`Gs~1-$3_MI7qS$(`CKE@K7v~7LLjanaR6L+%xZmB8(h!pV z^b{a$v%~hkDjdaaJ+z5NnOBKGK4NwOhKnioxEXBEi7C8vo;qiFwFL)s$`mIPRtYxw zED8pk|H7`;BQF}T&}cbm{NQutD(JQpa`J1e=8C&~jSMd|b#JiAUw4vW#E%`FJE{sw z@wJCF6g6ZO-$qmWuC!L=nZ^S&V6qE|)l;y%=j0?Te}Qw-_a)fr;%wLS5E?nhdUMB> zL-oPwEDG=uUIM6a!-0)}#rFctwWllX`f4?zSS2ZXYXH%6(z&WGUhUTg)rip*BSkL1 z`;X>*(Za2rDPQ!k8NA{%QwHN7lopqB&+ix8)Z1^gjr0h6LgWxi+XW;DKMj<2cyOJ|0GC-l8VsiSaT;sF;O77>HOc~g;E`;ky8yc@TjeXWS-w( zGGo)U3>VHGys0dpG&$FYKI2%hd$Nv-+rKHE6BwDJ_*FiO^S$$G){oRf*s+g zi-PFtn)juES(AoaJR5Bf+pfZ6ZoYD;#cv-b7{>XK8ZcpOglw zOdcBv;Yb}E5SNd-pl=4WJZ8NpR)*sC`%!44J>_Yuh9_4R0(sl!dcSj7$HOdluv*y| zRJP_PP2GwqAlxUVuO%nr<&F#wTTBB&oNYM*W!^)v%1yUBKDM0Ng1U|hEfXrw&(b~o zqR(Qf^$&5klg5`t`){CFhBSd=%Lt|7EIr{yh!;{q^3=~@>aGugumQ`E;Y;dWWG*jn zeRDTc%(#^uNs1$lf%VvRni!}C%>@DM4Z<##%iuC|NmyU_ak&@~N{?>8$l1=S(hWt` zrSHz}?ynqD5zlfNViyj@4{tAqX#v)x{P$|%0|?-ZkE4=M`||L=V}E}ijs%hr3wvTq8BvFoXhf3Pj4COH476Gt zg%&PJUnJs~5v@Yv3Ng-BOVS6bih>vySXcb2)-q|Inmg(!`1qL4=GVN>?GxH^WjI+` zQ&Rrr(-lASFFM=-C{nlmDH_rUEDe4Ap+C&prO&s3e3?#((f#p?K#y-?p*r$Q==X0@ zh@1VG)rI1;$&|jb*$H zrG*6U;PG5q%E2D97dv<@^^Wz0&dALeV)+;P@v}>spzuzk5s`kR>!Ix# zbz?6!M`J?(q;UJSZqa&zbVo3qIJrq4-*?W%O_%=~%Jned z5F&SGXlg1e2>is6xJg%S;Tb3GtLZhKBrNJYf+SMwY^4T!>wddiC8z&1!jA_Dqudd} z%c-x$GB520}NF+~!*3(I79mcdSHX?{81xKxsIWwS$1C zYZ7oi2tlFZRJ48z;N=O3h&ENCuqpYXtF5Nid!KHm?(bVM>a%3YuE;$;shP57D;17) zCi>X1q86pu6dM)Zx!2nvG-m=?Tg&Cmu0Q&+5I~66P=$Q2SG9z1?C&SAz2pUPE46b} zzTHN8FNrmac5w!Se#&g>c|zc`X-!j@|E=S-AD3ghC>uG zJy}v}8jik-3MOEzNR^HPrqiSWN32dDJ2n7t49wLeo;`z%_ep52WT;)&pav zI@Y>3P0JtS@n!d32nmi{)K%RvL1MMGap~_ghkM;}B5aY1;niA&65^j(o@1dZ{nQ&9 zQ1r>(5y%rQ`1H2oo}zNzC+?y#SZQbYBwom8_jdr$+=v$hi~+6t#jzBPXDoPoYw)`h zd8|pW1G?V>19Sq;OEPt4op;WKO|Lb^6{2k@At$7=o~Qc2U@3QmqGgp_q5B!bN`PQ} zn71ZDQ}<4}Wbs^+YLEX1d1ynn%pW%q6fHzgZyD;KB2Xk<&#IC=7pS%jkt)>ZHU9Q- zAP;5t*y8Q3-qcDIfo66N%us}9J>R|Jy|9U@Va=>D0puT}DxG*)Jq5(QBOe%S#@YSU z7^mQ_p{qLrXk)$eYXP)-ib2-*BZTV(W ztKSI_g;0DjeZ+DRwf4cVvN_bs0#gGoUJD%YXIhCc#kYAqs4`e8X0@lxi9W)q6B26g zLCE2GantutPrjURcqO03?%FxTIv^Q#i3nl9kdlYb1X28Pu|_VA(w0ZXQwFQ#t#(+wOl47&tq{RgCAb(lfUwRt-ag`s(D?Z z(#>5edLn7m02{h?JM{szq&!*CYwb5wB{O7W+?qHQ=o>dn4$+L;UOR4~KewE!5W{Sl zAaub{MEp=ha~Xa0FjN`c=epPdbJXj0$r^9gq}6^5rZM#%t9ZC|cy{zf-_rQxY&kJa zb8~fIE?(fn6)p{;n<7on-b5ZSU8H+NEom>`UoBG5>GIp1YN0$e&*ypeIVCQ7l%PKH zzQgu8F{XTk8$S(H469}SsbHx${t|~9KA#3atbEaNGjv*02h7!l5U_vI2lT3)*!>Nv z(7RwNX|{m^oV2PHrDcoe-`<|$?cFE;6l_PTtFy*DG~O1dWJt9LBoAn=p>8LKN4s`j zr;jgsSTq=9ia(pp0gtt2qP$uEwB z+W!L!$P*#`9Ukdd#ZqxL2w0gK7gmG*zRbdbxGiPhsYRYzQhDfFoSU}rM&5zVjWx-u zg1_{deQTlj1}=A+HB>pO*?wn&=Pxae-=achdO8CSDqmU|rAlgB)CZQs_EUj|JBe5z zOmrwLJk2dLC}57DDN7ylwk0*~Hhnd{?la%6^!ZqFGLC*5Hgi!eUv@FV2r3tu4}OcV zn3e%B5DVO!jg_PrI>*~50YWnq=~@xpfG|B07q)eNoGe1pAs7(#wjH_YdqT%Jsb4Z8uBrf-#UjcEVivK`lxHEVv3>gCBwq8H*CMs)uCW zEWDGXsU8s$r21e>H_OAR-l7;Qh3%j@tX-4Wmkjy*{tfTqIfgNIc{qrz7$xNfy$lvs zVgHHgA^HfNJG`f3%z40`Z}Ff1Pu!rF#*D2H8XWbb(W}9Hds}`1fl<5)uj3^oTHLIQ zcEC7J>c9Cn?RqVZwe{&@O!$6^`ysWj@}rvNHwQXMIZb->H?Wc!l0TMZ+&j(ZEpfg- zGSodO*)j(<_d2X{)Kb~C}pLAI)E|zF=oZaU_ftEA{ zt09pYb>@xXRRTEVvLTO^a)Q;@E)qc)96CBW#i0vAr_EnQC#OobLJz6$6#2QJY3>%H zX;XTuIwTz`su%bUssO~z`=B{1rXW=#uVuU>Zaw5Dae2B;A)E5POW@uPgo+5&fH2(P>bhHNpq zn780jo?X4^r>+Uh-Gjx(VkklWpLjJq%#5ByNvEqj%lK*rEYt~2gzlbgt|Hgz4+}&q zc0yl^D#Qo@`G6rmWYgqdC+dC*vEM-GXW0x%$f^+60)|4KjjtN_PXf9xLCw^8d$yAJlcCT5DQh8 z(&E{UKXM^`jJA=XR`Yl`IIPPQ^W|YA7Lof3Xt_fAT(m2#FbYTia}Cl;)h;9T z%}YQbxL5^OYE=X|F_zAyRlik4TC1 zTB$6n?~+e}{azo83hgrDyO39f>=F^8Lco3q2IO%*J?$DtX&U!_# zW`Ebmm3pH%R5$)9)0ANwRY(LoJGh8D6Lnx(+w_`A zUI4F4E*2xo@;zx)8h!Yw0t4>fNRo;KXPWR~yq^d;BndXByYoY=`J8D6?}#Ol30m~4 zgqED?TWA)Zb2d34;^bvL1+GHNtcZzxV+KcZ^Vx`s$2=LbxjXFbJ3k>;UW%GN0aXYu z)Rf0=!sQ!1q82*X6LGWfoJ*%011%Ual_(x6CGI~~&?Yw)%j8G>=QzE78NZ@)lu0xj zYA6W`$<LF#SNzg5q3k(ASMrP2KY$h;vzI#wy$H@a6oF0JYreKW- z&68>13noHrH(}QoyESI0HD@wL-VHBwo59cd+mkqk)8OswU5Rc*iLHu46z_`V24r(O2&=~j4-Xl!A!|Oe)}tBaHe^?)LNu^L4h}L9zKTFq$ z?PG>NLd;GLrll#dWMxVMd%K6=!UVILeNw@h7O0i7z^~y}fLDkQaQp~-ZJN`>zwR}i zKAymN!g#s2!aQHPc!Le@G9OzZ;_)S#&4rHkm5oi2P)xCBb z{Hi{^Nv)RM0nC+k4n956@zTld_lkbxjnGfYc(< zHKcI7BxUGgTyGxrMalC7BQ^!=tD`0b;v2X(zh#rNyAg}IMXf|7DMO}yQ6q(Pa4vpZ zOBwElHMTR}Q@dfuITvUyu}&UXwQxemg+#Yks}2@tiHhv$dR6ut!OXN6G9LFmD7CCJ z$Zh=-d7^_}&r)xGuP3urucL>2F`^6WSQTVU^j=rAyFgv^c0sp(TTt|8{ zCp}2tCL^BgjHa9jBLy``(fT)&U`il|R`q&!{SpSZj}*b}FvSKX?C>h_`{Yo21;|C$ zEll-mxF()!a>7w{SEtXb$GJC3M4Cz!fdR*BxsYpTi<{3$>)rs3MX{xeq;*6TA4f*a zd=6KJy$qT%0^6uSYo`Q%Kc{pxZESLq^z10E`$wws_5JUWV4R)ku_(4sy{q-GvHp7Ol zP1jj|S%B3ccXH)Vlf@2SUch5t_WgVMX8&UTwl&pbX2ra167-8I708=J<0}V5;j$%8 za24IUj#rT4KmZf3I=b;SV~iJv=qZ;Y3ELF1){Hl7v2<(5Kf}*f@5A8*){+JXa1QUZ zE@qpuy5X<9T(w=d+j6G94;!8!Eu&;BD0Fw`tch}hGcexUn~1Giyjc4>oNmE2Ox%4Z z>rUi%o)>;{wsIPj@p$rR;-|Ypfruyg6^9vD##(8xtS!Tk-={FbR9F~#5e-T+{xP`wT?4#c+ybr%%(OI}r; z%yZ(WgU)Rjz)h%PvxeBXyA={V56E;64GGeUvT>@X5)-wIgO<7q>&RUt7QdiI)FTF~ z_%Pp$@rE_%rVwH+Xe4Dm()Z;Ddqab6fPih?`Xbj;6lqE!onvw8w-3g=PD(%NW1FP! zVyUPIrL9tuY_oVLgu;PbX#tQ2&5Pw|D;L6#3RfU6c>KF3^Ds=5!Pd~+XVN!{sQy`( z6!I!R^W~?-Rl+uQ6jV3$i*lRrjZ)y!wEegqwJMw>Sks`b<4_wG}?Zn|4%~N1{{F6 zRaJjo1Z6*m?|=Az)~49~cFK6fu2X?fIh!gqm_MWBuWn(5*O<-?-uV7uVHp$>CG;sr zeg-57$_V3shP%v#j+fJNJyESoP(AIzCx4Fg4fUs<+hKXsKBFh6oqOL_} z(MZ*NXLd4|zp1VWvyYMMp>L{Wc^QX=H&sWy>Ct3ODA;DNO z*ak6vzp^Nw9G6*=(TMTDYd2U{8KzCJ^eqtz@qkPqULK#GP85=hN=K3n&CUgx1SKMb z7-e=vA@Ztx7wW1bY{&au1XD=wabN4wPB$mD4qI|G5r?$gwsZw2T*%OY= z#A%E#*`j#|hhr)CYsv`&m0yIetN2-5E$++5M{c;hngK~??G_L*FtDh5#pTPWOMF_t2>-Hc9WwQ>=%fE;OdmU&W!k$m7c*ZgGgSY@E~T{B zm*h@)%S+kdK3Gk;cR&r6_o+v=Fx4K`H|O3Oar(}n+uqOJmyCJ|+32s<&tHe4q$fCu zDs5BA+&9k8D77uOC{~$n8=Gf9!~47lClI!=VHwhaPDhYk89<1vniK3^8tuJ%{ue7M zG^J={x#QKK;jD+W2M=@f0D>VJYLiS6vauH8N_i&;@|fePPnQk78K2or^hoSkX3~P` zj$ZntR2%&6PeQ0Li;Fv}P!Ci(`jpG5B-Tj6_e+I(m(U>1 zOV464L#-NvTH-Aj#eH7~+5ftx){A9)yq!x!j9F@S3qvF{QbrggkGPVlATVg{D-2+yQD7 zz;dswrA@uG9<2djxzfuc-}pTD{O^CGU^s|r@;h$7oj2ZigZW~8y;TF<2eQw`7A7{O z6YrkwS>##b(0{yCB#;aq(92gNRte;`w6A4FCA@3|G}}p{@Xv`Qzq=rM0!q#Rm#N8K zxU)U9T+EPIyeHjIpEx$FY#v@(;){Xvwr=EC>8~*$z<{yXefB*YpC*4RS z0x*vPDamM{k7L49X>$i&n?DmjMecD(#$6nHwLa6`MEPd1BC8!n>+B@`I!_X`g2^qa?mt5^im_S zh&$8apV!kz90O&V^3{33It;3thCnN1FC$;iX%K6Lco+EAi2eXbGo}q|S=irM*Zx4E z^?UHt!^H7frMlA6aq5>0(A8cEz-22G?!D^4{A3cEY7Z=>yl~~KoP%mo;zj75hDpzSXg{G8(><4vXR`Olm)I)DiS$fA_KD1ut{qKJtzyJLo z^3+s!c<#C9`0QstYcUi!zvU~xKZc^D%u-OwKvQjqz(x{DjREAY2jU=BT($42CWC#z zU%vgH_h~Z-M5GTzgPSD;RIeCDlC_0Xiqi7O z>7KV1#!t*D$tms>%bHGc>~K8*8|wYk?mQ{B%+Sj!D2hUEaM-hF5Bfe@Mz9w+j1CoUx>~64_mvWVLDv<*q`ydsam2m4D2I%gnOgGf|_~u$}-SS)R zx#u1pdgvi+;UErrdf_RCzU2*BJVB5=?&IJUi>u7hDRh)ZynE|2G#24zzDDhPZ4gPNvcyNRIq zpA(1kzX?hhe9MJMERsY15{UH_efIB>10Z=ojn7K16%}JtRE{z@5CY&9T_FFtcaYD2 z{`0I@u|n*{WR1hIW5>jj+#mhuN1Qr!iiOICjPxN(8iA51<_3BwpAB^DcP1x*xuy?? z{*$G&?y4a&;LCLPsDvn6y+{UD3FJB;kXgP07DEED|6H;k#sxDfTDFRU2im zT$Z?$a)_UrwPc%Cbu;uv5KWWtDzYeLed)P&?z-zPYHMq`{PN408YgY&jd4-#d*Ou_ zP*s(Mi+O-B5Qrkn8YYxrMgp<1jXQJP_Fa<59*6!`lQ;w#^hj{6E{`2ppqPgT1!CVT zUoh?@kj#5%5bF~C5!?;nsRg8I1!0{CvPc^mK%S=7jo z<@{uOFUR|$TzTb{V%e#_xgTk8Hais3`07``%HZH2#esQ%FgR8DN^+%B`COaf_Gd&S zkJAImf`R`pj@{La_4_fyK?$zb<iCeS`Dt25KyyXs1O5z#gTZ_6vWyfaSA+3 zK&i;rQe3Nh_63vvR7xQ+IBU@^TYie3?g~;V8CimlTvEgTdbSNs)A;nKKh0y0J;ryw z^BvAT_gqd#dV70${PD-xx^=7QZD^WCvEg<};uOLeS75n=M%vYEl%s5xxMa7}1F=BU zB)Z29N{O zqy)1p>^I@XyK^_8E>g%aXzHxenWCgZ_c0-g(@3 zUL|HYk|B;Hb3`)ASF3@;7_7atjq2sYP6CENFe#x zm{ChX>=dBQS|Y6{YiMn)Nxy}U{`e?|dnTBPn{K*^v(G-83opEoi!Z(ypU+3JaP;WW zv@pcn#=yV;i+$dzC zUz~N;St6lSR#q;EGdK3`-OF2Vy(NbGo_XdOdU|>|U06S90)5I9AeYz}BFxdxOJ3mg zO&_CuCG@qH()m_+%Cw=uganTR4_@~5ecLf%Um)+rAiQ)0*`LL|$UElXe2)YMQ?QX>A_Oqbv9Pk$FBrHP3Nv74>_nZCrvgwbeJ^ey!7 z3=Iv@*ViZJGxU@pKKuLoIZYA6gN+ql(u4xzm~i<3DP6+KW*Kj8f8ON>$yh~rnxLj+ zdQX;#GS%3if4a2MBEk10_`iDE=qC>-dig30oQpw4!zcw{5vQ31#JWKCfjbP67a*&p zzt%Gyc9P1Zdy)jQ8&Zi`3$wm{fcB1RQYl$He$#nX{GaDLutPK&W&i&D;+l6H#P%hU z#LQ=)yF~gZNb)c@^GhK)xY$#OC{1-8sifyvg*dCjEDe$p{1SLbf){jgXyg$ExEhet zMlY`$E4pR1=6ee;*{D&7c7Q7YN(IOYsB_v5-dX}+@ouYB;{g(u=_|9rT30(jM`slP z@7z$%4_@hEAdkvb+nR!uF!Pp zY#jJE3BIaJV~}}50j|IxSTTXylL9Soig;J5;a&nio^})goQ*Lihl)`C|{ZT1{OQ;+881f_p^Lf2`;+yp=lD`$0}&sUqd{q zFb%H&-vxdl4tknr6ks(5q3}eJ4g?lqqdhqasR+m+kxD?aaZK$r_f#AEZb=Gg$yv+M z>q$@*9;Uai9DwW3uH@0}y+ji##e{?T5UEgLVroIi9?(?degVo>re?kjs71e|H<@sW zGF8XnDx*wgA_Dx>SV^^;0-^v-82AEl(B>@>IL~P+q=q3mW*qS3ouT}cO|r;-kkKq6 zmk>x6A{EW_v_MMzF5bPVoTqjUP*gaG<7+De3Tc9Y=~iHQvsi(Z|1y`5h&pCp99rQL zM@LJT)&n)7Np6M~;6V^g@j(g?3a}glZ%M*Q5`~bCmNM$MZg2&~XLb@WB^3KZi;|qR zK!YVwF)uJQ90cIXwPl7t9Ex@SD@oFXK+New0c23sdSZT7YECL5s7aQOk3jb*)AZZof%-wiToYE~kt z4iBdV!Wm0S#B$KlXo}*&VQGbjG=6U!m#kvKW?8R>^?T54iLj!4lr%0` z;(`@HUOF^P@!(KVqF|6-ePvDqk{2{JC#$Oj(xmT9b>HGy$!EI1kiSoicsaOz8RMf~ zCh(Pit7X5|3B=rl&t4=R zcT$u*#v*Y<^f78$0-euXROe2HdrjI3^k+K zo&-q-WRMV`X0bXef07d=EJaC)4Hf~`*7}Q8AWjcNNlu>>R1NFYkX4$n{~n~=m!0gx z$UupZM?C5#gFy*y*TwN1MT(ShBH=l}b3i?2@c5F1D#wLT^iMIhF3Xye8Wx0nB#>l_ zWHG-j3P$CK)2vdT_SG-?g#DyTx1ZBD)e`jipy9ZE+i7F zoS?K~oXWZp(R?q&W{OTfMFTChaDE$NEfGDyG#a!?@aLP21DzJPK&+**%8<#$8eA&DnOK8MQ4N_yDAPZK z<>ScmVibz=Yudhh9f_m@z&Bs)V?Pf_$pIHR{I*`5dEePxHu`bZ!1xX$n5+@JW(0-(vNxTT$s>`Dn;PexS zwNT1{OMuP5+ch{}0v|IY_#ULWt6y_iA80uo4JUK)(0kW;Ph-fi%|jvb>?k zECO#BloA^v$dh!U9e|o&S(xvMe#e0~mowZSn4HJI3VcDAM+yT+Al5?h0p|m62R3VP zi3DX>AW2XXil&7kl8VQZbkaqUJ=fh=$&uCu0OCoFcYo)A_?#mrf!)9^pap2l5XCTy zlMt{<$i#fDBF}u|#uZ%96a=8Yx}WByU1mYJ%RmVhGI5x{YbwOM@+>LyGh-uu4*qEw zu?cskIff;~b|lYWfg=!Wp}345%I0)R0qU`al30SUQ0uEi?%@>1O-h^(2f2;=}*d!%tr8#e%)S7GNvTN47ZlfK8L6at7dM4&3*S z20n0BB>)wrV{B|bVHSbx25%T(;q*aLBaj-;zc?h&G>PMf>gYTfW)hD9f2qqO0^kT_ z{)AGOQS#ahoGDo}92Iwp@=75S{WF5kA9scs3oMtR(E$67G?C`+pB&|2_XN|B0KNcx zJ?H%h2L)I^Nh)UpAuPD{f+{|Fc^v>AcY+Hxy*0H2eAOUHc}^kO3=#GNsl2C;L|oy} zu11Cj17wf_{tl#XZ2tOQ4ZsmdVTB?C*8uMU-T|z`0)I)|kcoa(L~tpoc}@w=b1iL4 z=;^NjpldkJO%ESNV@guM6~HUZ7Y;7q0^nNXItwrv;BCtSeCwtr(p<3dkmyC4MBpw1 zm)nLEawr;2g~UMKOID-9eh%$kMl9+kgFfJ9J$1Zv?<>5ScyrYhe-YNi84Q~GaVUa@2@K3;(SV%Z{fh*GKasPAeOhN_z2KW~iG!DPKXWet< ze&s!YNFRC%nOX!&3CQlkZXKc}Ar;BX`&Ct<<-k&UyUR$UK|+H2ba8we6OKR@gHRfP zs|}f4EkT{tKx28u7**B7LMVzw@5D(UW;%Pr9P6kj&4+*3!pZ&^8N`6QfS=<~3@QIU z;OoXIlcEnYWy+9bPy&TbAE^l-nd|q9lI+3V%NZFe$&|;41lQ{Fcm)Tf)8G$+1e}>s z?%E9aXXu?6G8v&VJc3(EIU6ookVq=*IJi2UKG<<`jC&tHK?Xy>^}z2b794?G0lbXC z`5WKD>rPB95!nMScY&7iszM++-wbiw!-3r^#AgP_LCE7EMT{d5`&06pGlX&$AWbKe zvhoO3;Ss`BBe>nk(=e4-)6%+xo`H(=V|@J4qa5s-z@Xh|)b6F2a0F5c3<5I1$|YSi zRQFF`!*KaPlIA~ssIi>)KB5yIcJEjzmg{D)9r%DQj~*5ojzH|M?z#cE5x4}9nTE>B zQEF<32v?2>xh(#nL2E`LCG2TgNt$2p8{#X!ZpUCh@NS@uV#JZiv%vcR0{$rHtUUrS zeJRW3ndd2V71Vf6-ye^;*|Vcb?B|xjFF>3eIF5rO5R2Z)^@dC~11`+q^(LsR8=$Us zFmI`(@N%(6(}+B@;v<6}8I$E2S>Oo7kx5O4Os)WwshaOqRl_vY_ltAD7hiKc zyT}6w0oMXCiWx^BUZ4XA1EPebm$EEs84}1cAmvvgS_;r|_D)rk*t>Hj zqa%JY_!;nFT^=enaRlQ0LAn$8N1zcighJ!gRu55EJ5Vgce|8Y5V|UBS^w1!Ox+g^M zL)CZ^xD`mS7;q%=9pD}Sx02+7jcoV_!dbg_TWiplc$wbAoP zkV71SI5N2mxW`B*3X>@D$7o#IOI78t=#vzG+AtGKxY>PpC2{=|K-CcP&?T}JxC=zi5$myIwjQc-;uWvhLAS1>l}CyfSgNN|}hk0^P<5r`v_rNAeEyMbyZ z;rGR9Tyl!)un|<6H=wfEa3r!9*pzOjpS|X&NFl{8 zkwj8qpPoD-W4=sz{FgE3G0HsP2*eSI0(?q?zn7qjN%*{R8tVF~tr^56sYRJMG6$;; z9A7TZI#2VTdk6X2Z#uRB9|JTNBaT2m20RR4TGCsb5)oyqJ-b#iKJF!hmx1@qek*nd z8Cy8$F*m7S{~|#x@aG!rCWC0q!?Ba~Y~QhtmSam89V-Ei^p$3&dl}ex&L$HvFS}cs zGvpx-i_-q}rLNBdA6?Y)aM+Sr#yZ(mD}G-WD}w_;-h6#craaK#x4^ZIJe&lw5GLQ> z4}1Z58v=7GX>91FCOm|MmfuujA0dtX$Cjrj&C^@8t6%pi86u(bxJmzjl1|1g8^@M7{|869y%|7@JldFA9l_j+W5U zvP7hgNqiIdp9^`ll_L;GBrA*_!CwG%OhajKoT`dp{WC()A1zqoP&G-+c(nD@kV?s9 z(moh}bZLd>&eL{nypygU1#ZQ_tt8phd_pwW7otQ|Ri?GAn)dc;CNTzlR2Ro%6cLU< zoQC`Lz{kWc!7~V4aixS%N&^wf^v__4=|HTUqG=LCV*v(+OX=4yJ$*2Vm~r;OBb@Fy zzlWa(uFOo*ORD?DnIW>QE(nPv5(*uiRdjV%n*I?4>;gWd%cF%N#u11!>3$t>18^na zW(H(Q!|#pZ_r*l%!0#2Gq86>oCTm$t#5}~}9`QL6DG}mOH3>7MfFA?12l!wOh zE)i9e>FY10r?-OPkpN~;fqw?RwAfc!IRbHH;sVYBE;FvT1J%qQCx9n`U+CiaBQxXR zNMt4OAn=Z9{$V4^u%W;Np^|a2XPhi)cBLVfl@AREgfIq&LsONh&>$tj&kb=L<}}3- zh$EGYfF@u)u+I2g3%IdQ7w{JFTi_X88VAT82S+5Efxpt=dI>ztKqxSd-y1hdvT;iM zQABd~m`)WGVu&XdF*P2Gc^DiCGB^|xL#;Cq1HKJ>O&3Q$nK(ECae!_5yom&717$#^ zafOY~T0jHhKmv#xR}|fL zE{-vZ7Dpfs4i1h?{tUPn{nFs=5|ooeG>A#C4R{%Ndhs4L>j=cb!NC#AYTz0pnXECc q)qsoH5d&T~gz-DzwZcx1JN!Sy^@52rc?8@50000', render(':cdata\n foo')); + assert.equal('', render(':cdata\n foo\n bar')); + assert.equal('

    something else

    ', render(':cdata\n foo\n bar\np something else')); + }, + + // 'test :markdown filter': function(){ + // assert.equal( + // '

    foo

    \n\n
    • bar
    • baz
    ', + // render(':markdown\n #foo\n - bar\n - baz\n')) + // }, + + 'test :stylus filter': function(){ + assert.equal( + '', + render(':stylus\n body\n color #c00')); + }, + + 'test :stylus filter with options': function(){ + assert.equal( + '', + render(':stylus(compress=true)\n body\n color #c00')); + }, + + // 'test :less filter': function(){ + // assert.equal( + // '', + // render(':less\n .class { width: 10px * 2 }\n')); + // }, + + // 'test :coffeescript filter': function(){ + // var coffee, js; + // coffee = [ + // ':coffeescript', + // ' square = (x) ->', + // ' x * x' + // ].join('\n'); + // js = [ + // '' + // ].join('\n'); + // + // assert.equal(js, render(coffee)); + // + // coffee = [ + // ':coffeescript', + // ' $ ->', + // ' $("#flash").fadeIn ->', + // ' console.log("first line")', + // ' console.log("second line")' + // ].join('\n'); + // js = [ + // '' + // ].join('\n'); + // + // assert.equal(js, render(coffee)); + // }, + + 'test parse tree': function(){ + var str = [ + 'conditionals:', + ' if false', + ' | oh noes', + ' or', + ' if null == false', + ' p doh', + ' or', + ' p amazing!' + ].join('\n'); + + var html = [ + '

    amazing!

    ' + ].join(''); + + assert.equal(html, render(str)); + }, + + 'test filter attrs': function(){ + jade.filters.testing = function(str, attrs){ + return str + ' ' + attrs.stuff; + }; + + var str = [ + ':testing(stuff)', + ' foo bar', + ].join('\n'); + + assert.equal('foo bar true', render(str)); + } +}; \ No newline at end of file diff --git a/node_modules/jade/test/fixtures/case-blocks.html b/node_modules/jade/test/fixtures/case-blocks.html new file mode 100644 index 0000000..4b87acb --- /dev/null +++ b/node_modules/jade/test/fixtures/case-blocks.html @@ -0,0 +1 @@ +

    you have a friend

    \ No newline at end of file diff --git a/node_modules/jade/test/fixtures/case-blocks.jade b/node_modules/jade/test/fixtures/case-blocks.jade new file mode 100644 index 0000000..9bf2373 --- /dev/null +++ b/node_modules/jade/test/fixtures/case-blocks.jade @@ -0,0 +1,10 @@ +html + body + friends = 1 + case friends + when 0 + p you have no friends + when 1 + p you have a friend + default + p you have #{friends} friends \ No newline at end of file diff --git a/node_modules/jade/test/fixtures/case.html b/node_modules/jade/test/fixtures/case.html new file mode 100644 index 0000000..37b4f52 --- /dev/null +++ b/node_modules/jade/test/fixtures/case.html @@ -0,0 +1 @@ +

    you have 5 friends

    \ No newline at end of file diff --git a/node_modules/jade/test/fixtures/case.jade b/node_modules/jade/test/fixtures/case.jade new file mode 100644 index 0000000..71533b5 --- /dev/null +++ b/node_modules/jade/test/fixtures/case.jade @@ -0,0 +1,8 @@ +friends = 5 + +html + body + case friends + when 0: p you have no friends + when 1: p you have a friend + default: p you have #{friends} friends diff --git a/node_modules/jade/test/fixtures/conditional-comment.html b/node_modules/jade/test/fixtures/conditional-comment.html new file mode 100644 index 0000000..ca27dc0 --- /dev/null +++ b/node_modules/jade/test/fixtures/conditional-comment.html @@ -0,0 +1,6 @@ + + + + diff --git a/node_modules/jade/test/fixtures/conditional-comment.jade b/node_modules/jade/test/fixtures/conditional-comment.jade new file mode 100644 index 0000000..203a324 --- /dev/null +++ b/node_modules/jade/test/fixtures/conditional-comment.jade @@ -0,0 +1,6 @@ +html + head + //if lte IE 8 + script(src='/ie-sucks.js') + // if lte IE 7 + script(src='/ie-really-sucks.js') \ No newline at end of file diff --git a/node_modules/jade/test/fixtures/invalid.jade b/node_modules/jade/test/fixtures/invalid.jade new file mode 100644 index 0000000..d498bbb --- /dev/null +++ b/node_modules/jade/test/fixtures/invalid.jade @@ -0,0 +1,3 @@ +ul + li= foo + li bar \ No newline at end of file diff --git a/node_modules/jade/test/fixtures/layout.jade b/node_modules/jade/test/fixtures/layout.jade new file mode 100644 index 0000000..a81624a --- /dev/null +++ b/node_modules/jade/test/fixtures/layout.jade @@ -0,0 +1,3 @@ +html + body + h1 Jade \ No newline at end of file diff --git a/node_modules/jade/test/fixtures/mixins.html b/node_modules/jade/test/fixtures/mixins.html new file mode 100644 index 0000000..651c21d --- /dev/null +++ b/node_modules/jade/test/fixtures/mixins.html @@ -0,0 +1,12 @@ +
    +

    Tobi +

    +
    +
    +

    foo +

    +

    bar (baz) +

    +
    +
    +
    diff --git a/node_modules/jade/test/fixtures/mixins.jade b/node_modules/jade/test/fixtures/mixins.jade new file mode 100644 index 0000000..ebb6ff4 --- /dev/null +++ b/node_modules/jade/test/fixtures/mixins.jade @@ -0,0 +1,10 @@ + +mixin comment(title, str) + .comment + h2= title + p.body= str + +#user + h1 Tobi + .comments + mixin comment('foo', 'bar (baz)') \ No newline at end of file diff --git a/node_modules/jade/test/fixtures/pet-page.jade b/node_modules/jade/test/fixtures/pet-page.jade new file mode 100644 index 0000000..017b388 --- /dev/null +++ b/node_modules/jade/test/fixtures/pet-page.jade @@ -0,0 +1,11 @@ + +extends user-layout + +block head + title= name + +block content + if superCool + include super-pet + else + include pet \ No newline at end of file diff --git a/node_modules/jade/test/fixtures/pet.html b/node_modules/jade/test/fixtures/pet.html new file mode 100644 index 0000000..c058114 --- /dev/null +++ b/node_modules/jade/test/fixtures/pet.html @@ -0,0 +1,15 @@ + + + tobi + + + + +
    +

    tobi +

    +

    tobi is a 1 year old ferret +

    +
    + + diff --git a/node_modules/jade/test/fixtures/pet.jade b/node_modules/jade/test/fixtures/pet.jade new file mode 100644 index 0000000..ae190fd --- /dev/null +++ b/node_modules/jade/test/fixtures/pet.jade @@ -0,0 +1,5 @@ +.pet + block name + h1= name + block description + p #{name} is a #{age} year old #{species} \ No newline at end of file diff --git a/node_modules/jade/test/fixtures/scripts.jade b/node_modules/jade/test/fixtures/scripts.jade new file mode 100644 index 0000000..30fabcf --- /dev/null +++ b/node_modules/jade/test/fixtures/scripts.jade @@ -0,0 +1,2 @@ +script(src='/jquery.js') +script(src='/caustic.js') \ No newline at end of file diff --git a/node_modules/jade/test/fixtures/super-pet.html b/node_modules/jade/test/fixtures/super-pet.html new file mode 100644 index 0000000..b19166d --- /dev/null +++ b/node_modules/jade/test/fixtures/super-pet.html @@ -0,0 +1,15 @@ + + + tobi + + + + +
    +

    tobi +

    +

    tobi is a super ferret +

    +
    + + diff --git a/node_modules/jade/test/fixtures/super-pet.jade b/node_modules/jade/test/fixtures/super-pet.jade new file mode 100644 index 0000000..c3e64e9 --- /dev/null +++ b/node_modules/jade/test/fixtures/super-pet.jade @@ -0,0 +1,5 @@ + +extends pet + +block description + p #{name} is a super #{species} diff --git a/node_modules/jade/test/fixtures/test.css b/node_modules/jade/test/fixtures/test.css new file mode 100644 index 0000000..c16c9ef --- /dev/null +++ b/node_modules/jade/test/fixtures/test.css @@ -0,0 +1,3 @@ +body { + color: black; +} \ No newline at end of file diff --git a/node_modules/jade/test/fixtures/user-layout.jade b/node_modules/jade/test/fixtures/user-layout.jade new file mode 100644 index 0000000..a996452 --- /dev/null +++ b/node_modules/jade/test/fixtures/user-layout.jade @@ -0,0 +1,8 @@ +html + head + block head + title My Site + block scripts + script(src='/jquery.js') + body + block content diff --git a/node_modules/jade/test/fixtures/user.jade b/node_modules/jade/test/fixtures/user.jade new file mode 100644 index 0000000..5276f49 --- /dev/null +++ b/node_modules/jade/test/fixtures/user.jade @@ -0,0 +1 @@ +span.name= user diff --git a/node_modules/jade/test/fixtures/users.html b/node_modules/jade/test/fixtures/users.html new file mode 100644 index 0000000..0c4a682 --- /dev/null +++ b/node_modules/jade/test/fixtures/users.html @@ -0,0 +1,17 @@ + + + Viewing 3 users + + + + +
      +
    • tobi +
    • +
    • loki +
    • +
    • jane +
    • +
    + + diff --git a/node_modules/jade/test/fixtures/users.jade b/node_modules/jade/test/fixtures/users.jade new file mode 100644 index 0000000..e66fcf0 --- /dev/null +++ b/node_modules/jade/test/fixtures/users.jade @@ -0,0 +1,11 @@ + +extends user-layout + +block head + title Viewing #{users.length} users + +block content + ul#users + for user, i in users + li(id='user-#{i}') + include user \ No newline at end of file diff --git a/node_modules/jade/test/jade.test.js b/node_modules/jade/test/jade.test.js new file mode 100644 index 0000000..e3adc7b --- /dev/null +++ b/node_modules/jade/test/jade.test.js @@ -0,0 +1,1023 @@ + +/** + * Module dependencies. + */ + +var jade = require('../') + , assert = require('assert') + , fs = require('fs'); + +// Shortcut + +var render = function(str, options){ + var fn = jade.compile(str, options); + return fn(options); +}; + +function fixture(path) { + return fs.readFileSync(__dirname + '/fixtures/' + path, 'utf8'); +} + +assert.render = function(jade, html, options){ + var path = __dirname + '/fixtures/' + jade + , opts = { pretty: true, filename: path }; + jade = fixture(jade); + html = fixture(html).trim(); + for (var key in options) opts[key] = options[key]; + var res = render(jade, opts).trim(); + if (res !== html) { + console.error(); + console.error(path); + console.error('\n\033[31mexpected:\033[m '); + console.error(html); + console.error('\n\033[31mgot:\033[m '); + console.error(res); + process.exit(1); + } +}; + +module.exports = { + 'test .version': function(){ + assert.ok(/^\d+\.\d+\.\d+$/.test(jade.version), "Invalid version format"); + }, + + 'test exports': function(){ + assert.equal('object', typeof jade.selfClosing, 'exports.selfClosing missing'); + assert.equal('object', typeof jade.doctypes, 'exports.doctypes missing'); + assert.equal('object', typeof jade.filters, 'exports.filters missing'); + assert.equal('object', typeof jade.utils, 'exports.utils missing'); + assert.equal('function', typeof jade.Compiler, 'exports.Compiler missing'); + }, + + 'test doctypes': function(){ + assert.equal('', render('!!! xml')); + assert.equal('', render('doctype html')); + assert.equal('', render('doctype foo bar baz')); + assert.equal('', render('!!! 5')); + assert.equal('', render('!!!', { doctype:'html' })); + assert.equal('', render('!!! html', { doctype:'xml' })); + assert.equal('', render('html')); + assert.equal('', render('html', { doctype:'html' })); + }, + + 'test Buffers': function(){ + assert.equal('

    foo

    ', render(new Buffer('p foo'))); + }, + + 'test line endings': function(){ + var str = [ + 'p', + 'div', + 'img' + ].join('\r\n'); + + var html = [ + '

    ', + '
    ', + '' + ].join(''); + + assert.equal(html, render(str)); + + var str = [ + 'p', + 'div', + 'img' + ].join('\r'); + + var html = [ + '

    ', + '
    ', + '' + ].join(''); + + assert.equal(html, render(str)); + + var str = [ + 'p', + 'div', + 'img' + ].join('\r\n'); + + var html = [ + '

    ', + '
    ', + '' + ].join(''); + + assert.equal(html, render(str, { doctype:'html' })); + }, + + 'test single quotes': function(){ + assert.equal("

    'foo'

    ", render("p 'foo'")); + assert.equal("

    'foo'\n

    ", render("p\n | 'foo'")); + assert.equal('
    ', render("- var path = 'foo';\na(href='/' + path)")); + }, + + 'test block-expansion': function(){ + assert.equal("
  • foo
  • bar
  • baz
  • ", render("li: a foo\nli: a bar\nli: a baz")); + assert.equal("
  • foo
  • bar
  • baz
  • ", render("li.first: a foo\nli: a bar\nli: a baz")); + }, + + 'test case statement': function(){ + assert.equal(fixture('case.html'), render(fixture('case.jade'))); + assert.equal(fixture('case-blocks.html'), render(fixture('case-blocks.jade'))); + }, + + 'test tags': function(){ + var str = [ + 'p', + 'div', + 'img' + ].join('\n'); + + var html = [ + '

    ', + '
    ', + '' + ].join(''); + + assert.equal(html, render(str), 'Test basic tags'); + assert.equal('', render('fb:foo-bar'), 'Test hyphens'); + assert.equal('
    ', render('div.something'), 'Test classes'); + assert.equal('
    ', render('div#something'), 'Test ids'); + assert.equal('
    ', render('.something'), 'Test stand-alone classes'); + assert.equal('
    ', render('#something'), 'Test stand-alone ids'); + assert.equal('
    ', render('#foo.bar')); + assert.equal('
    ', render('.bar#foo')); + assert.equal('
    ', render('div#foo(class="bar")')); + assert.equal('
    ', render('div(class="bar")#foo')); + assert.equal('
    ', render('div(id="bar").foo')); + assert.equal('
    ', render('div.foo.bar.baz')); + assert.equal('
    ', render('div(class="foo").bar.baz')); + assert.equal('
    ', render('div.foo(class="bar").baz')); + assert.equal('
    ', render('div.foo.bar(class="baz")')); + assert.equal('
    ', render('div.a-b2')); + assert.equal('
    ', render('div.a_b2')); + assert.equal('', render('fb:user')); + assert.equal('', render('fb:user:role')); + assert.equal('', render('colgroup\n col.test')); + }, + + 'test nested tags': function(){ + var str = [ + 'ul', + ' li a', + ' li b', + ' li', + ' ul', + ' li c', + ' li d', + ' li e', + ].join('\n'); + + var html = [ + '
      ', + '
    • a
    • ', + '
    • b
    • ', + '
      • c
      • d
    • ', + '
    • e
    • ', + '
    ' + ].join(''); + + assert.equal(html, render(str)); + + var str = [ + 'a(href="#")', + ' | foo ', + ' | bar ', + ' | baz' + ].join('\n'); + + assert.equal('foo \nbar \nbaz\n', render(str)); + + var str = [ + 'ul', + ' li one', + ' ul', + ' | two', + ' li three' + ].join('\n'); + + var html = [ + '
      ', + '
    • one
    • ', + '
        two\n', + '
      • three
      • ', + '
      ', + '
    ' + ].join(''); + + assert.equal(html, render(str)); + }, + + 'test variable length newlines': function(){ + var str = [ + 'ul', + ' li a', + ' ', + ' li b', + ' ', + ' ', + ' li', + ' ul', + ' li c', + '', + ' li d', + ' li e', + ].join('\n'); + + var html = [ + '
      ', + '
    • a
    • ', + '
    • b
    • ', + '
      • c
      • d
    • ', + '
    • e
    • ', + '
    ' + ].join(''); + + assert.equal(html, render(str)); + }, + + 'test tab conversion': function(){ + var str = [ + 'ul', + '\tli a', + '\t', + '\tli b', + '\t\t', + '\t\t\t\t\t\t', + '\tli', + '\t\tul', + '\t\t\tli c', + '', + '\t\t\tli d', + '\tli e', + ].join('\n'); + + var html = [ + '
      ', + '
    • a
    • ', + '
    • b
    • ', + '
      • c
      • d
    • ', + '
    • e
    • ', + '
    ' + ].join(''); + + assert.equal(html, render(str)); + }, + + 'test newlines': function(){ + var str = [ + 'ul', + ' li a', + ' ', + ' ', + '', + ' ', + ' li b', + ' li', + ' ', + ' ', + ' ', + ' ul', + ' ', + ' li c', + ' li d', + ' li e', + ].join('\n'); + + var html = [ + '
      ', + '
    • a
    • ', + '
    • b
    • ', + '
      • c
      • d
    • ', + '
    • e
    • ', + '
    ' + ].join(''); + + assert.equal(html, render(str)); + + var str = [ + 'html', + ' ', + ' head', + ' != "test"', + ' ', + ' ', + ' ', + ' body' + ].join('\n'); + + var html = [ + '', + '', + 'test', + '', + '', + '' + ].join(''); + + assert.equal(html, render(str)); + assert.equal('something', render('foo\n= "something"\nbar')); + assert.equal('somethingelse', render('foo\n= "something"\nbar\n= "else"')); + }, + + 'test text': function(){ + assert.equal('foo\nbar\nbaz\n', render('| foo\n| bar\n| baz')); + assert.equal('foo \nbar \nbaz\n', render('| foo \n| bar \n| baz')); + assert.equal('(hey)\n', render('| (hey)')); + assert.equal('some random text\n', render('| some random text')); + assert.equal(' foo\n', render('| foo')); + assert.equal(' foo \n', render('| foo ')); + assert.equal(' foo \n bar \n', render('| foo \n| bar ')); + }, + + 'test pipe-less text': function(){ + assert.equal('
    ', render('pre\n code\n foo\n\n bar')); + assert.equal('

    foo\n\nbar\n

    ', render('p.\n foo\n\n bar')); + assert.equal('

    foo\n\n\n\nbar\n

    ', render('p.\n foo\n\n\n\n bar')); + assert.equal('

    foo\n bar\nfoo\n

    ', render('p.\n foo\n bar\n foo')); + assert.equal('', render('script\n s.parentNode.insertBefore(g,s)\n')); + assert.equal('', render('script\n s.parentNode.insertBefore(g,s)')); + }, + + 'test tag text': function(){ + assert.equal('

    some random text

    ', render('p some random text')); + assert.equal('

    click\nGoogle.\n

    ', render('p\n | click\n a Google\n | .')); + assert.equal('

    (parens)

    ', render('p (parens)')); + assert.equal('

    (parens)

    ', render('p(foo="bar") (parens)')); + assert.equal('', render('option(value="") -- (optional) foo --')); + }, + + 'test tag text block': function(){ + assert.equal('

    foo \nbar \nbaz\n

    ', render('p\n | foo \n | bar \n | baz')); + assert.equal('', render('label\n | Password:\n input')); + assert.equal('', render('label Password:\n input')); + }, + + 'test tag text interpolation': function(){ + assert.equal('yo, jade is cool\n', render('| yo, #{name} is cool\n', { name: 'jade' })); + assert.equal('

    yo, jade is cool

    ', render('p yo, #{name} is cool', { name: 'jade' })); + assert.equal('yo, jade is cool\n', render('| yo, #{name || "jade"} is cool', { name: null })); + assert.equal('yo, \'jade\' is cool\n', render('| yo, #{name || "\'jade\'"} is cool', { name: null })); + assert.equal('foo <script> bar\n', render('| foo #{code} bar', { code: '', + '', + '' + ].join(''); + + assert.equal(html, render(str)); + }, + + 'test comments': function(){ + // Regular + var str = [ + '//foo', + 'p bar' + ].join('\n'); + + var html = [ + '', + '

    bar

    ' + ].join(''); + + assert.equal(html, render(str)); + + // Arbitrary indentation + + var str = [ + ' //foo', + 'p bar' + ].join('\n'); + + var html = [ + '', + '

    bar

    ' + ].join(''); + + assert.equal(html, render(str)); + + // Between tags + + var str = [ + 'p foo', + '// bar ', + 'p baz' + ].join('\n'); + + var html = [ + '

    foo

    ', + '', + '

    baz

    ' + ].join(''); + + assert.equal(html, render(str)); + + // Quotes + + var str = "", + js = "// script(src: '/js/validate.js') "; + assert.equal(str, render(js)); + }, + + 'test unbuffered comments': function(){ + var str = [ + '//- foo', + 'p bar' + ].join('\n'); + + var html = [ + '

    bar

    ' + ].join(''); + + assert.equal(html, render(str)); + + var str = [ + 'p foo', + '//- bar ', + 'p baz' + ].join('\n'); + + var html = [ + '

    foo

    ', + '

    baz

    ' + ].join(''); + + assert.equal(html, render(str)); + }, + + 'test literal html': function(){ + assert.equal('\n', render('')); + }, + + 'test code': function(){ + assert.equal('test', render('!= "test"')); + assert.equal('test', render('= "test"')); + assert.equal('test', render('- var foo = "test"\n=foo')); + assert.equal('foo\ntestbar\n', render('- var foo = "test"\n| foo\nem= foo\n| bar')); + assert.equal('test

    something

    ', render('!= "test"\nh2 something')); + + var str = [ + '- var foo = "' + , render(str, { filename: __dirname + '/jade.test.js' })); + }, + + 'test .render(str, fn)': function(){ + jade.render('p foo bar', function(err, str){ + assert.ok(!err); + assert.equal('

    foo bar

    ', str); + }); + }, + + 'test .render(str, options, fn)': function(){ + jade.render('p #{foo}', { foo: 'bar' }, function(err, str){ + assert.ok(!err); + assert.equal('

    bar

    ', str); + }); + }, + + 'test .render(str, options, fn) cache': function(){ + jade.render('p bar', { cache: true }, function(err, str){ + assert.ok(/the "filename" option is required for caching/.test(err.message)); + }); + + jade.render('p foo bar', { cache: true, filename: 'test' }, function(err, str){ + assert.ok(!err); + assert.equal('

    foo bar

    ', str); + }); + }, + + 'test .compile()': function(){ + var fn = jade.compile('p foo'); + assert.equal('

    foo

    ', fn()); + }, + + 'test .compile() locals': function(){ + var fn = jade.compile('p= foo'); + assert.equal('

    bar

    ', fn({ foo: 'bar' })); + }, + + 'test .compile() no debug': function(){ + var fn = jade.compile('p foo\np #{bar}', {compileDebug: false}); + assert.equal('

    foo

    baz

    ', fn({bar: 'baz'})); + }, + + 'test .compile() no debug and global helpers': function(){ + var fn = jade.compile('p foo\np #{bar}', {compileDebug: false, helpers: 'global'}); + assert.equal('

    foo

    baz

    ', fn({bar: 'baz'})); + }, + + 'test null attrs on tag': function(){ + var tag = new jade.nodes.Tag('a'), + name = 'href', + val = '"/"'; + tag.setAttribute(name, val) + assert.equal(tag.getAttribute(name), val) + tag.removeAttribute(name) + assert.isUndefined(tag.getAttribute(name)) + }, + + 'test assignment': function(){ + assert.equal('
    5
    ', render('a = 5;\ndiv= a')); + assert.equal('
    5
    ', render('a = 5\ndiv= a')); + assert.equal('
    foo bar baz
    ', render('a = "foo bar baz"\ndiv= a')); + assert.equal('
    5
    ', render('a = 5 \ndiv= a')); + assert.equal('
    5
    ', render('a = 5 ; \ndiv= a')); + + var fn = jade.compile('test = local\np=test'); + assert.equal('

    bar

    ', fn({ local: 'bar' })); + } + +}; diff --git a/node_modules/stylus/.gitignore b/node_modules/stylus/.gitignore new file mode 100644 index 0000000..2a39945 --- /dev/null +++ b/node_modules/stylus/.gitignore @@ -0,0 +1,5 @@ +css +lib-cov +testing +.DS_Store +node_modules diff --git a/node_modules/stylus/.gitmodules b/node_modules/stylus/.gitmodules new file mode 100644 index 0000000..e69de29 diff --git a/node_modules/stylus/.npmignore b/node_modules/stylus/.npmignore new file mode 100644 index 0000000..62f5b4a --- /dev/null +++ b/node_modules/stylus/.npmignore @@ -0,0 +1,6 @@ +test +support +testing +docs +examples +node_modules diff --git a/node_modules/stylus/History.md b/node_modules/stylus/History.md new file mode 100644 index 0000000..dbc3e46 --- /dev/null +++ b/node_modules/stylus/History.md @@ -0,0 +1,565 @@ + +0.19.3 / 2011-11-17 +================== + + * Added "include css" setting (need docs) to literally include imported css. Closes #448 + * Added EOL escape. Related to #195 + * Fixed tab support in lexical analysis (trailing colors etc). Closes #460 + +0.19.2 / 2011-11-09 +================== + + * Fixed "in" within selectors. Closes #458 + +0.19.1 / 2011-11-08 +================== + + * Added `spin()` BIF (same as `color + 50deg` etc) + * Removed "sys" require()s for 0.6.x + * Fixed sibling property lookup bug. Closes #452 + * Fixed: retain original quote for strings + +0.19.0 / 2011-10-26 +================== + + * Added property lookup bubbling support. Closes #446 + +0.18.1 / 2011-10-26 +================== + + * Added "indent spaces" compiler setting. Closes #445 + * Allow node > 0.4.x < 0.7.0 + * Fixed: allow function execution within @imports + +0.18.0 / 2011-10-21 +================== + + * Added #n support (#e -> #eeeeee). Closes #430 + * Added #nn support (#ef -> #efefef) + * Added support for rgb percentages. + * Fixed property rendering in blocks. Closes #440 + +0.17.0 / 2011-09-30 +================== + + * Added `@scope ` feature to scope all subsequent selectors + * Added list equality to the `!=` operator + * Added list equality to the `==` operator + * Added mkdir -p support to the middleware + * Changed: `!` coerces expression not the first value + * Fixed Ternary boolean coercion. Closes #420 + * Fixed __@font-face__ __@import__ regression. Closes #418 + +0.16.0 / 2011-09-26 +================== + + * Added `mkdir -p` support to the middleware + * Added `@import url(string)` support. Closes #352 + * Added `fade-in()` and `fade-out()` BIFs + * Adding prefixes for Opera and IE + * Fixed comments trailing __@media__. Closes #415 [guillermo] + * Fixed: Output from --help in stylus executable cut-off half way through + * Changed: treat -/+ operations with percentages as lighten()/darken(). +Closes #401 + +0.15.4 / 2011-09-14 +================== + + * Fixed `String#coerce()` for Expressions + +0.15.3 / 2011-09-14 +================== + + * Added `-U, --inline` to stylus(1) + * Added `rem` support. Closes #395 + * Fixed __@charset__ semi-colon. Closes #400 + * Fixed infinite loop in `Parser#function()`. Closes #393 + +0.15.2 / 2011-09-06 +================== + + * Added alias `:=` of `?=`. Closes #389 + * Removed auto-prefixing of pseudo element selectors. Closes #385 + * Changed: when left-hand operand has no unit assign the right + * Fixed __@keyframes__ with __@import__ regression. Closes #372 + * Fixed css __@import__ within blocks regression. Closes #388 + * Fixed unwrapping of property args expression. Closes #379 + * Fixed __@prop__ access scope issue, use closet block, not current + * Fixed __@font-face__. Closes #375 + +0.15.1 / 2011-08-18 +================== + + * Added pseudo-element vendor expansion support + * Added `@keyframe` expansion support. Closes #293 + * Added support for arbitrary `@-VENDOR-keyframes` support + * Added support for `@property` mixin property access Closes #363 + * Added `/*!` support to comments to disable suppression + * Changed: allow uses to append `.styl` when importing. Closes #366 + * Fixed paren matching issue. Closes #368 + * Fixed windows absolute path checking Added `utils.absolute(path)` + * Fixed `Ident#clone()` with `.property` flag + * Fixed evaluation of expression when using @name. Closes #361 + * Fixed `path.join()` usage in `utils.lookup()`. Closes #356 + * Fixed space after comment regression. Closes #360 + +0.15.0 / 2011-08-15 +================== + + * Adding `Renderer#get(option)` + * Added the ability to reference property values with `@`. Closes #344 + * Changed comment output. css-style multi-line comments are preserved + * Fixed issue with bools in selectors. Closes #280 + +0.14.0 / 2011-08-10 +================== + + * Added firebug original file / line number mapping [parallel] + * Added support for `#rgba` and `#rrggbbaa` color formats + * Changed: fix alpha to a scale of 2 + * Fixing function param check to allow for empty function arguments + +0.13.9 / 2011-08-04 +================== + + * Fixed `lighten()` BIF 'lighten by %' function push color closer to white [cwolves] + * Fixed cli plugin usage absolute paths, don't prepend the CWD [cpojer] + * Renaming 'import' to '_import' because import is a reserved word in node v0.5 + +0.13.8 / 2011-08-01 +================== + + * Added `PI` and `-math-prop(name)` + * Added `cos()` and `sin()` + * Added support for __SVG__ data URIs [mhemesath] + * Rename variable "import" to "imported" [eegg] + +0.13.7 / 2011-07-15 +================== + + * Added `js(str)` BIF + * Fixed reserved keyword `import` with `imported` + +0.13.6 / 2011-07-12 +================== + + * Added `@-webkit-keyframes` support. Closes #307 + * Added gedit language-spec + * Changed: optional `growl` dep for stylus(1) + * Changed: `require("stylus")` instead of `../` for the mac app integration + +0.13.5 / 2011-06-27 +================== + + * Fixed middleware handling of new and removed `@import` s [brandonbloom] + +0.13.4 / 2011-06-22 +================== + + * Added __Compile and Display CSS__ TextMate command (⌘B) [Daniel Gasienica] + * Fixed caching behavior for recompilation of files with changed imports [Brandon Bloom] + +0.13.3 / 2011-06-01 +================== + + * Added padding for error linenos so they line up + * Improved unary op error messages + * Improved invalid `@keyframes` ident error msg + * Fixed HSLA regression for operations resulting in a bool. Closes #274 + * Fixed `arguments` issue with excluding defaults. Closes #272 + +0.13.2 / 2011-05-31 +================== + + * Fixed colors after `url()` call regression. Closes #270 + +0.13.1 / 2011-05-30 +================== + + * Fixed colors in `url()`. Closes #267 + * Fixed selector without trailing comma containing selector token. Closes #260 + +0.13.0 / 2011-05-17 +================== + + * Added `-u, --use PATH` flag for utilizing plugins + * Fixed `hsla.clampDegrees()` with negative values [Bruno Héridet] + +0.12.4 / 2011-05-12 +================== + + * Added support for underscore in identifiers. Closes #247 + * Fixed `@keyframe` block evaluation. Closes #252 + +0.12.3 / 2011-05-08 +================== + + * Fixed `0%` in `@keyframes` from becoming `0` when compressed. Closes #248 + +0.12.2 / 2011-05-03 +================== + + * Fixed issue with `^=` attr selector causing infinite loop. Closes #244 + * Fixed multiple occurrences of `&` in selectors. Closes #243 + +0.12.1 / 2011-04-29 +================== + + * Fixed spaces around line-height shorthand. Closes #228 + * Fixed `-{foo}` interpolation support. Closes #235 + +0.12.0 / 2011-04-29 +================== + + * Added `*prop: val` hack support (blueprint / html boilerplate etc parse fine now) + * Added selector interpolation support + * Fixed "-" within interpolation. Closes #220 + +0.11.12 / 2011-04-27 +================== + + * Added `SyntaxError` and `ParseError` + * Removed `stylus.parse()` + * Fixed error reporting. Closes #44 + +0.11.11 / 2011-04-24 +================== + + * Fixed mutation of units when using unary ops. Closes #233 + +0.11.10 / 2011-04-17 +================== + + * Fixed regression. Closes #229 + +0.11.9 / 2011-04-15 +================== + + * Fixed issue with large selectors spanning several lines + +0.11.8 / 2011-04-15 +================== + + * Added support for `Renderer#define(name, node)` to define a global + +0.11.7 / 2011-04-12 +================== + + * Added `Renderer#use(fn)`. Closes #224 + * Improved `utils.assertType()` error message; include param name + +0.11.6 / 2011-04-12 +================== + + * Fixed: node.source and node.filename are writable + +0.11.5 / 2011-04-12 +================== + + * Added / employed `Null#isNull` + * Added / employed `Boolean#is{True,False}` + * Removed all uses of `instanceof` + * Removed all equality checks between singleton nodes + +0.11.4 / 2011-04-10 +================== + + * Added `Arguments#clone()` + * Added `push()` / `append()` + * Added `unshift()` / `prepend()` BIFs + +0.11.3 / 2011-04-08 +================== + + * Fixed: keyword args previously not evaluated + * Fixed: subpixel support + * Fixed bug preventing combinators (and other ops) in `@media` blocks. Closes #216 [reported by jsteenkamp] + +0.11.2 / 2011-04-06 +================== + + * Added `Renderer#include(path)`. Closes #214 + * Fixed `@import` path resolution bug. Closes #215 + * Fixed optional keyword arg bug. Closes #212 + +0.11.1 / 2011-04-01 +================== + + * Fixed regression preventing commas from outputting + +0.11.0 / 2011-04-01 +================== + + * Added `HSLA#add(h,s,l,a)` + * Added `HSLA#sub(h,s,l,a)` + * Added `RGBA#add(r,g,b,a)` + * Added `RGBA#sub(r,g,b,a)` + * Added `RGBA#multiply(n)` + * Added `RGBA#divide(n)` + * Added `HSLA#adjustHue(deg)` + * Added `HSLA#adjustLightness(percent)` + * Added `HSLA#adjustSaturation(percent)` + * Added `linear-gradient()` example + * Added `s(fmt, ...)` built-in; sprintf-like + * Added `%` sprintf-like string operator, ex: `'%s %s' % (1 2)` + * Added `current-property` local variable + * Added `add-property(name, val)` + * Added the ability for functions to duplicate the property they are invoked within + * Added `[]=` operator support. Ex: `fonts[1] = arial`, `nums[1..3] = 2` + * Added `-I, --include ` to stylus(1). Closes #206 + * Added support for `50 + 25% == 75` + * Added support for `rgba + 25%` to lighten + * Added support for `rgba - 25%` to darken + * Added support for `rgba - 25` to adjust rgb values + * Changed: null now outputs "null" instead of "[Null]" + * Fixed hsl operation support, all operations are equivalent on rgba/hsla nodes + * Fixed degree rotation + +0.10.0 / 2011-03-29 +================== + + * Added keyword argument support + * Added `Arguments` node, acts like `Expression` + * Added `utils.params()` + * Added `debug` option to stylus middleware + * Added support for `hsl + 15deg` etc to adjust hue + * Added special-case for percentage based `RGBA` operations (`#eee - 20%`) + * Changed: right-hand colors in operations are not clamped (`#eee * 0.2`) + * Added support for `unit * color` (swaps operands) + * Fixed color component requests on the opposite node type (ex red on hsla node) + * Fixed `Expression#clone()` to support `Arguments` + * Fixed issue with middleware where imports are improperly mapped + * Fixed mutation of color when adjusting values + * Fixed: coerce string to literal + * Removed {`darken`,`lighten`}`-by()` BIFs + +0.9.2 / 2011-03-21 +================== + + * Removed a `console.log()` call + +0.9.1 / 2011-03-18 +================== + + * Fixed connect middleware `@import` support. Closes #168 + The middleware is now smart enough to know when imports + change, and will re-compile the target file. + + * Changed middleware `compile` function to return the `Renderer` (API change) + +0.9.0 / 2011-03-18 +================== + + * Added `-i, --interactive` for the Stylus REPL (eval stylus expressions, tab-completion etc) + * Added link to vim syntax + * Changed `p()` built-in to display parens + * Changed `--compress -C` to `-c`, and `-css -c` is now `-C` + * Fixed: preserve rest-arg expressions. Closes #194 + * Fixed `*=` in selector, ex `[class*="foo"]` + * Fixed `--watch` issue with growl, updated to 1.1.0. Closes #188 + * Fixed negative floats when compressed. Closes #193 [reported by ludicco] + +0.8.0 / 2011-03-14 +================== + + * Added postfix `for`-loop support. + Ex: `return n if n % 2 == 0 for n in nums` + * Added support for several postfix operators + Ex: `border-radius: 5px if true unless false;` + * Added `last(expr)` built-in function + * Added `sum(nums)` built-in function + * Added `avg(nums)` built-in function + * Added `join(delim, vals)` built-in function + * Added `Evaluator#{currentScope,currentBlock}` + * Added multi-line function paramter definition support + * Changed: `0` is falsey, `0%`, `0em`, `0px` etc truthy. Closes #160 + * Fixed `for` implicit __return__ value + * Fixed `for` explicit __return__ value + * Fixed mixin property ordering + +0.7.4 / 2011-03-10 +================== + + * Added `RGBA` node + * Added `is a "color"` special-case, true for `HSLA` and `RGBA` nodes. +Closes #180 + * Performance; 2.5× faster compiles due to removing use of getters in `Parser` and `Lexer` (yes, they are really slow). + * Removed `Color` node + * Fixed stylus(1) `--watch` support due to dynamic `@import` support. Closes #176 + +0.7.3 / 2011-03-09 +================== + + * Fixed: allow semi-colons for non-css syntax for one-liners + +0.7.2 / 2011-03-08 +================== + + * Added `isnt` operator (same as `is not` and `!=`) + * Added support for dynamic `@import` expressions + * Added `@import` index resolution support + * Added `light()` / `dark()` BIFs + * Added `compress` option for Connect middleware [disfated] + * Changed: most built-in functions defined in stylus (`./lib/functions/index.styl`) + * Fixed dynamic expressions in `url()`. Closes #105 + +0.7.1 / 2011-03-07 +================== + + * Fixed connect middleware for 0.4.x + +0.7.0 / 2011-03-02 +================== + + * Added `is` and `is not` aliases for `==` and `!=` + * Added `@keyframes` dynamic name support + * Fixed units in interpolation + * Fixed clamping of HSLA degrees / percentages + +0.6.7 / 2011-03-01 +================== + + * Fixed __RGBA__ -> __HSLA__ conversion due to typo + +0.6.6 / 2011-03-01 +================== + + * Added string -> unit type coercion support aka `5px + "10"` will give `15px` + * Added `warn` option Closes #152 + Currently this only reports on re-definition of functions + * Added `$` as a valid identifier character + * Added `mixin` local variable for function introspection capabilities. Closes #162 + * Fixed typo: `Unit#toBoolean()` is now correct + * Fixed interpolation function calls. Closes #156 + * Fixed mixins within Media node. Closes #153 + * Fixed function call in ret val. Closes #154 + +0.6.5 / 2011-02-24 +================== + + * Fixed parent ref `&` mid-selector bug. Closes #148 [reported by visnu] + +0.6.4 / 2011-02-24 +================== + + * Fixed `for` within brackets. Closes #146 + +0.6.3 / 2011-02-22 +================== + + * Fixed single-ident selectors. Closes #142 + * Fixed cyclic `@import` with file of the same name. Closes #143 + +0.6.2 / 2011-02-21 +================== + + * Added stylus(1) growl support when using `--watch` + * Added `@import` watching support to stylus(1). Closes #134 + * Changed: stylus(1) only throws when `--watch` is not used + * Fixed `darken-by()` BIF + * Fixed `@import` literal semi-colon. Closes #140 + +0.6.1 / 2011-02-18 +================== + + * Fixed evaluation of nodes after a return. Closes #139 + +0.6.0 / 2011-02-18 +================== + + * Added `stylus(1)` direct css to stylus file conversion [Mario] + For example instead of `$ stylus --css < foo.css > foo.styl` + you may now either `$ stylus --css foo.css` or provide + a destination path `$ stylus --css foo.css /tmp/out.styl`. + + * Added postfix conditionals. Closes #74 + Expressive ruby-ish syntax, ex: `padding 5px if allow-padding`. + +0.5.3 / 2011-02-17 +================== + + * Added `in` operator. `3 in nums`, `padding in props` etc + * Added `Expression#hash`, hashing all of the nodes in order + * Added tests for conditionals with braces. Closes #136 + * Fixed ids that are also valid colors. Closes #137 + +0.5.2 / 2011-02-15 +================== + + * Fixed spaces after `}` with css-style. Closes #131 + * Fixed single-line css-style support. Closes #130 + +0.5.1 / 2011-02-11 +================== + + * Fixed mixin property ordering. Closes #125 + +0.5.0 / 2011-02-09 +================== + + * Added `lighten-by()` BIF + * Added `darken-by()` BIF + +0.4.1 / 2011-02-09 +================== + + * Added support for function definition braces + * Fixed issue with invalid color output. Closes #127 + +0.4.0 / 2011-02-07 +================== + + * Added css-style syntax support + * Fixed support for `*` selector within `@media` blocks + +0.3.1 / 2011-02-04 +================== + + * Fixed property disambiguation logic. Closes #117 + You no longer need to add a trailing comma when + chaining selectors such as `td:nth-child(2)\ntd:nth-child(3)` + +0.3.0 / 2011-02-04 +================== + + * Added more assignment operators. Closes #77 + `+=`, `-=`, `*=`, `/=`, and `%=` + +0.2.1 / 2011-02-02 +================== + + * Fixed `--compress` when passing files for stylus(1). Closes #115 + * Fixed bug preventing absolute paths from being passed to `@import` + * Fixed `opposite-position()` with nested expressions, unwrapping + * Fixed a couple global var leaks [aheckmann] + +0.2.0 / 2011-02-01 +================== + + * Added: `url()` utilizing general lookup paths. + This means that `{ paths: [] }` is optional now, as lookups + will be relative to the file being rendered by default. + + * Added `-w, --watch` support to stylus(1). Closes #113 + +0.1.0 / 2011-02-01 +================== + + * Added `opposite-position(positions)` built-in function + * Added `image-lookup(path)` built-in function + * Added `-o, --out ` support to stylus(1) + * Added `stylus [file|dir ...]` support + * Added: defaulting paths to `[CWD]` for stylus(1) + * Changed: `unquote()` using `Literal` node + * Changed: utilizing `Literal` in place of some `Ident`s + +0.0.2 / 2011-01-31 +================== + + * Added optional property colon support. Closes #110 + * Added `--version` to stylus(1) + +0.0.1 / 2011-01-31 +================== + + * Initial release \ No newline at end of file diff --git a/node_modules/stylus/LICENSE b/node_modules/stylus/LICENSE new file mode 100644 index 0000000..a206b68 --- /dev/null +++ b/node_modules/stylus/LICENSE @@ -0,0 +1,22 @@ +(The MIT License) + +Copyright (c) 2010 LearnBoost + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/node_modules/stylus/Makefile b/node_modules/stylus/Makefile new file mode 100644 index 0000000..40a5dc8 --- /dev/null +++ b/node_modules/stylus/Makefile @@ -0,0 +1,20 @@ + +SRC = $(shell find lib -name "*.js") +TM_BUNDLE = editors/Stylus.tmbundle +TM_BUNDLE_DEST = ~/Library/Application\ Support/TextMate/Bundles + +test: test-integration + +test-integration: + @node test/run.js + +install-bundle: + cp -fr $(TM_BUNDLE) $(TM_BUNDLE_DEST) + +update-bundle: + cp -fr $(TM_BUNDLE_DEST)/Stylus.tmbundle editors + +benchmark: + @node bm.js + +.PHONY: test test-integration install-bundle update-bundle benchmark \ No newline at end of file diff --git a/node_modules/stylus/Readme.md b/node_modules/stylus/Readme.md new file mode 100644 index 0000000..b5e9900 --- /dev/null +++ b/node_modules/stylus/Readme.md @@ -0,0 +1,149 @@ +# Stylus + + Stylus is a revolutionary new language, providing an efficient, dynamic, and expressive way to generate CSS. Supporting both an indented syntax and regular CSS style. + +## Installation + +```bash +$ npm install stylus +``` + +### Example + +``` +border-radius() + -webkit-border-radius: arguments + -moz-border-radius: arguments + border-radius: arguments + +body a + font: 12px/1.4 "Lucida Grande", Arial, sans-serif + background: black + color: #ccc + +form input + padding: 5px + border: 1px solid + border-radius: 5px +``` + +compiles to: + +```css +body a { + font: 12px/1.4 "Lucida Grande", Arial, sans-serif; + background: #000; + color: #ccc; +} +form input { + padding: 5px; + border: 1px solid; + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + border-radius: 5px; +} +``` + +the following is equivalent to the indented version of Stylus source, using the CSS syntax instead: + +``` +border-radius() { + -webkit-border-radius: arguments + -moz-border-radius: arguments + border-radius: arguments +} + +body a { + font: 12px/1.4 "Lucida Grande", Arial, sans-serif; + background: black; + color: #ccc; +} + +form input { + padding: 5px; + border: 1px solid; + border-radius: 5px; +} +``` + +### Features + + Stylus has _many_ features. Detailed documentation links follow: + + - [css syntax](/LearnBoost/stylus/blob/master/docs/css-style.md) support + - [mixins](/LearnBoost/stylus/blob/master/docs/mixins.md) + - [keyword arguments](/LearnBoost/stylus/blob/master/docs/kwargs.md) + - [variables](/LearnBoost/stylus/blob/master/docs/variables.md) + - [interpolation](/LearnBoost/stylus/blob/master/docs/interpolation.md) + - arithmetic, logical, and equality [operators](/LearnBoost/stylus/blob/master/docs/operators.md) + - [importing](/LearnBoost/stylus/blob/master/docs/import.md) of other stylus sheets + - [introspection api](/LearnBoost/stylus/blob/master/docs/introspection.md) + - type coercion + - [conditionals](/LearnBoost/stylus/blob/master/docs/conditionals.md) + - [iteration](/LearnBoost/stylus/blob/master/docs/iteration.md) + - nested [selectors](/LearnBoost/stylus/blob/master/docs/selectors.md) + - parent reference + - in-language [functions](/LearnBoost/stylus/blob/master/docs/functions.md) + - [variable arguments](/LearnBoost/stylus/blob/master/docs/vargs.md) + - built-in [functions](/LearnBoost/stylus/blob/master/docs/bifs.md) (over 25) + - optional [image inlining](/LearnBoost/stylus/blob/master/docs/functions.url.md) + - optional compression + - JavaScript [API](/LearnBoost/stylus/blob/master/docs/js.md) + - extremely terse syntax + - stylus [executable](/LearnBoost/stylus/blob/master/docs/executable.md) + - [error reporting](/LearnBoost/stylus/blob/master/docs/error-reporting.md) + - single-line and multi-line [comments](/LearnBoost/stylus/blob/master/docs/comments.md) + - css [literal](/LearnBoost/stylus/blob/master/docs/literal.md) + - character [escaping](/LearnBoost/stylus/blob/master/docs/escape.md) + - [@keyframes](/LearnBoost/stylus/blob/master/docs/keyframes.md) support & expansion + - [@font-face](/LearnBoost/stylus/blob/master/docs/font-face.md) support + - [@media](/LearnBoost/stylus/blob/master/docs/media.md) support + - Connect [Middleware](/LearnBoost/stylus/blob/master/docs/middleware.md) + - TextMate [bundle](/LearnBoost/stylus/blob/master/docs/textmate.md) + - gedit [language-spec](/LearnBoost/stylus/blob/master/docs/gedit.md) + - VIM [Syntax](https://github.com/wavded/vim-stylus) + - [Firebug extension](/LearnBoost/stylus/blob/master/docs/firebug.md) + - transparent vendor-specific function expansion + +### Framework Support + + - [Connect](/LearnBoost/stylus/blob/master/docs/middleware.md) + - [Ruby On Rails](https://github.com/lucasmazza/stylus_rails) + +### Screencasts + + - [Stylus Intro](http://screenr.com/bNY) + - [CSS Syntax & Postfix Conditionals](http://screenr.com/A8v) + +### Authors + + - [TJ Holowaychuk (visionmedia)](http://github.com/visionmedia) + +### More Information + + - Language [comparisons](/LearnBoost/stylus/blob/master/docs/compare.md) + +## License + +(The MIT License) + +Copyright (c) 2010 LearnBoost <dev@learnboost.com> + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/stylus/bin/stylus b/node_modules/stylus/bin/stylus new file mode 100755 index 0000000..805ebaf --- /dev/null +++ b/node_modules/stylus/bin/stylus @@ -0,0 +1,606 @@ +#!/usr/bin/env node + +/** + * Module dependencies. + */ + +var fs = require('fs') + , stylus = require('../lib/stylus') + , basename = require('path').basename + , dirname = require('path').dirname + , join = require('path').join; + +/** + * Arguments. + */ + +var args = process.argv.slice(2); + +/** + * Compare flag. + */ + +var compare = false; + +/** + * Compress flag. + */ + +var compress = false; + +/** + * CSS conversion flag. + */ + +var convertCSS = false; + +/** + * Line numbers flag. + */ + +var linenos = false; + +/** + * Firebug flag + */ + +var firebug = false; + +/** + * Files to processes. + */ + +var files = []; + +/** + * Import paths. + */ + +var paths = []; + +/** + * Destination directory. + */ + +var dest; + +/** + * Watcher hash. + */ + +var watchers; + +/** + * Enable REPL. + */ + +var interactive; + +/** + * Plugins. + */ + +var plugins = []; + +/** + * Optional url() function. + */ + +var urlFunction = false; + +/** + * Usage docs. + */ + +var usage = [ + '' + , ' Usage: stylus [options] [command] [< in [> out]]' + , ' [file|dir ...]' + , '' + , ' Commands:' + , '' + , ' help [:] Opens help info at MDC for in' + , ' your default browser. Optionally' + , ' searches other resources of :' + , ' safari opera w3c ms caniuse quirksmode' + , '' + , ' Options:' + , '' + , ' -i, --interactive Start interactive REPL' + , ' -u, --use Utilize the stylus plugin at ' + , ' -U, --inline Utilize image inlining via data uri support' + , ' -w, --watch Watch file(s) for changes and re-compile' + , ' -o, --out Output to when passing files' + , ' -C, --css [dest] Convert css input to stylus' + , ' -I, --include Add to lookup paths' + , ' -c, --compress Compress css output' + , ' -d, --compare Display input along with output' + , ' -f, --firebug Emits debug infos in the generated css that' + , ' can be used by the FireStylus Firebug plugin' + , ' -l, --line-numbers Emits comments in the generated css' + , ' indicating the corresponding stylus line' + , ' -V, --version Display the version of stylus' + , ' -h, --help Display help information' + , '' +].join('\n'); + +/** + * Handle arguments. + */ + +var arg; +while (args.length) { + arg = args.shift(); + switch (arg) { + case '-h': + case '--help': + console.error(usage); + process.exit(1); + case '-d': + case '--compare': + compare = true; + break; + case '-c': + case '--compress': + compress = true; + break; + case '-C': + case '--css': + convertCSS = true; + break; + case '-f': + case '--firebug': + firebug = true; + break; + case '-l': + case '--line-numbers': + linenos = true; + break; + case '-V': + case '--version': + console.log(stylus.version); + process.exit(0); + break; + case '-o': + case '--out': + dest = args.shift(); + if (!dest) throw new Error('--out required'); + break; + case 'help': + var name = args.shift() + , browser = name.split(':'); + if (browser.length > 1) { + name = [].slice.call(browser, 1).join(':'); + browser = browser[0]; + } else { + name = browser[0]; + browser = ''; + } + if (!name) throw new Error('help required'); + help(name); + break; + case '-i': + case '--repl': + case '--interactive': + interactive = true; + break; + case '-I': + case '--include': + var path = args.shift(); + if (!path) throw new Error('--include required'); + paths.push(path); + break; + case '-w': + case '--watch': + watchers = {}; + break; + case '-U': + case '--inline': + args.unshift('--use', 'url'); + break; + case '-u': + case '--use': + var options; + var path = args.shift(); + if (!path) throw new Error('--use required'); + + // options + if ('--with' == args[0]) { + args.shift(); + options = args.shift(); + if (!options) throw new Error('--with required'); + options = eval('(' + options + ')'); + } + + // url support + if ('url' == path) { + urlFunction = options || {}; + } else { + paths.push(dirname(path)); + plugins.push({ path: path, options: options }); + } + break; + default: + files.push(arg); + } +} + +// optional growl support + +try { + var growl = require('growl'); +} catch (err) { + // ignore +} + +// if --watch is used, assume we are +// not working with stdio + +if (watchers && !files.length) { + files = fs.readdirSync(process.cwd()) + .filter(function(file){ + return file.match(/\.styl$/); + }); +} + +/** + * Open the default browser to the CSS property `name`. + * + * @param {String} name + */ + +function help(name) { + var url + , exec = require('child_process').exec + , command; + + name = encodeURIComponent(name); + + switch (browser) { + case 'safari': + case 'webkit': + url = 'https://developer.apple.com/library/safari/search/?q=' + name; + break; + case 'opera': + url = 'http://dev.opera.com/search/?term=' + name; + break; + case 'w3c': + url = 'http://www.google.com/search?q=site%3Awww.w3.org%2FTR+' + name; + break; + case 'ms': + url = 'http://social.msdn.microsoft.com/search/en-US/ie?query=' + name + '&refinement=59%2c61'; + break; + case 'caniuse': + url = 'http://caniuse.com/#search=' + name; + break; + case 'quirksmode': + url = 'http://www.google.com/search?q=site%3Awww.quirksmode.org+' + name; + break; + default: + url = 'https://developer.mozilla.org/en/CSS/' + name; + } + + switch (process.platform) { + case 'linux': command = 'x-www-browser'; break; + default: command = 'open'; + } + + exec(command + ' "' + url + '"', function(){ + process.exit(0); + }); +} + +// Compilation options + +var options = { + filename: 'stdin' + , compress: compress + , firebug: firebug + , linenos: linenos + , paths: [process.cwd()].concat(paths) +}; + +// Buffer stdin + +var str = ''; + +// Convert css to stylus + +if (convertCSS) { + switch (files.length) { + case 2: + compileCSSFile(files[0], files[1]); + break; + case 1: + compileCSSFile(files[0], files[0].replace('.css', '.styl')); + break; + default: + var stdin = process.openStdin(); + stdin.setEncoding('utf8'); + stdin.on('data', function(chunk){ str += chunk; }); + stdin.on('end', function(){ + var out = stylus.convertCSS(str); + console.log(out); + }); + } +} else if (interactive) { + repl(); +} else { + if (files.length) { + compileFiles(files); + } else { + compileStdio(); + } +} + +/** + * Start stylus REPL. + */ + +function repl() { + var options = { filename: 'stdin', imports: [join(__dirname, '..', 'lib', 'functions')] } + , parser = new stylus.Parser('', options) + , evaluator = new stylus.Evaluator(parser.parse(), options) + , rl = require('readline') + , repl = rl.createInterface(process.stdin, process.stdout, true) + , global = evaluator.global.scope; + + // expose BIFs + evaluator.evaluate(); + + // readline + repl.setPrompt('> '); + repl.prompt(); + + // HACK: flat-list auto-complete + repl._tabComplete = function(){ + var out = this.output + , line = this.line + , keys = Object.keys(global.locals) + , len = keys.length + , words = line.split(/\s+/) + , word = words.pop() + , names = [] + , name + , obj + , key; + + // find words that match + for (var i = 0; i < len; ++i) { + key = keys[i]; + if (0 == key.indexOf(word)) { + names.push(key); + } + } + + // several candidates + if (names.length > 1) { + out.write('\r\n\r\n\033[90m'); + names.forEach(function(name){ + var node = global.lookup(name); + switch (node.nodeName) { + case 'function': + out.write(' - ' + node + '\r\n'); + break; + default: + out.write(' - ' + name + '\r\n'); + } + }); + out.write('\r\n\033[0m'); + this._refreshLine(); + // single candidate + } else if (names.length) { + name = names.pop(); + obj = global.lookup(name); + name = name.replace(word, ''); + switch (obj.nodeName) { + case 'function': + this._insertString(name + '()'); + this.cursor--; + break; + default: + this._insertString(name); + } + this._refreshLine(); + } + }; + + repl.on('line', function(line){ + if (!line.trim().length) return repl.prompt(); + parser = new stylus.Parser(line, options); + parser.state.push('expression'); + evaluator.return = true; + try { + var expr = parser.parse(); + var ret = evaluator.visit(expr); + ret = ret.nodes[ret.nodes.length - 1]; + ret = ret.toString(); + if ('(' == ret[0]) ret = ret.replace(/^\(|\)$/g, ''); + console.log('\033[90m=> \033[0m' + highlight(ret)); + repl.prompt(); + } catch (err) { + console.error('\033[31merror: %s\033[0m', err.message || err.stack); + repl.prompt(); + } + }); + + repl.on('SIGINT', function(){ + console.log(); + process.exit(0); + }); +} + +/** + * Highlight the given string of stylus. + */ + +function highlight(str) { + return str + .replace(/(#)?(\d+(\.\d+)?)/g, function($0, $1, $2){ + return $1 ? $0 : '\033[36m' + $2 + '\033[0m'; + }) + .replace(/(#[\da-fA-F]+)/g, '\033[33m$1\033[0m') + .replace(/('.*?'|".*?")/g, '\033[32m$1\033[0m'); +} + +/** + * Convert a CSS file to a Styl file + */ + +function compileCSSFile(file, fileOut) { + fs.lstat(file, function(err, stat){ + if (err) throw err; + if (stat.isFile()) { + fs.readFile(file, 'utf8', function(err, str){ + if (err) throw err; + var styl = stylus.convertCSS(str); + fs.writeFile(fileOut, styl, function(err){ + if (err) throw err; + }); + }); + } + }); +} + +/** + * Compile with stdio. + */ + +function compileStdio() { + process.stdin.setEncoding('utf8'); + process.stdin.on('data', function(chunk){ str += chunk; }); + process.stdin.on('end', function(){ + // Compile to css + var style = stylus(str, options); + usePlugins(style); + style.render(function(err, css){ + if (err) throw err; + if (compare) { + console.log('\n\x1b[1mInput:\x1b[0m'); + console.log(str); + console.log('\n\x1b[1mOutput:\x1b[0m'); + } + console.log(css); + if (compare) console.log(); + }); + }).resume(); +} + +/** + * Compile the given files. + */ + +function compileFiles(files) { + files.forEach(compileFile); +} + +/** + * Compile the given file. + */ + +function compileFile(file) { + // ensure file exists + fs.lstat(file, function(err, stat){ + if (err) throw err; + // file + if (stat.isFile()) { + fs.readFile(file, 'utf8', function(err, str){ + if (err) throw err; + options.filename = file; + options._imports = []; + var style = stylus(str, options); + usePlugins(style); + style.render(function(err, css){ + watchImports(file, options._imports); + if (err) { + if (watchers) { + console.error(err.stack || err.message); + growl && growl.notify(err.message, { title: 'Stylus error' }); + } else { + throw err; + } + } else { + writeFile(file, css); + } + }); + }); + // directory + } else if (stat.isDirectory()) { + fs.readdir(file, function(err, files){ + if (err) throw err; + files.filter(function(path){ + return path.match(/\.styl$/); + }).map(function(path){ + return join(file, path); + }).forEach(compileFile); + }); + } + }); +} + +/** + * Write the given css output. + */ + +function writeFile(file, css) { + // --out support + var path = dest + ? join(dest, basename(file, '.styl') + '.css') + : file.replace('.styl', '.css'); + fs.writeFile(path, css, function(err){ + if (err) throw err; + console.log(' \033[90mcompiled\033[0m %s', path); + // --watch support + watch(file, compileFile); + }); +} + +/** + * Watch the given `file` and invoke `fn` when modified. + */ + +function watch(file, fn) { + // not watching + if (!watchers) return; + + // already watched + if (watchers[file]) return; + + // watch the file itself + watchers[file] = true; + console.log(' \033[90mwatching\033[0m %s', file); + fs.watchFile(file, { interval: 50 }, function(curr, prev){ + if (curr.mtime > prev.mtime) fn(file); + }); +} + +/** + * Watch `imports`, re-compiling `file` when they change. + */ + +function watchImports(file, imports) { + imports.forEach(function(imported){ + if (!imported.path) return; + watch(imported.path, function(){ + compileFile(file); + }); + }); +} + +/** + * Utilize plugins. + */ + +function usePlugins(style) { + plugins.forEach(function(plugin){ + var path = plugin.path; + var options = plugin.options; + fn = require(path); + if ('function' != typeof fn) { + throw new Error('plugin ' + path + ' does not export a function'); + } + style.use(fn(options)); + }); + + if (urlFunction) style.define('url', stylus.url(urlFunction)); +} diff --git a/node_modules/stylus/bm.js b/node_modules/stylus/bm.js new file mode 100644 index 0000000..ce1acfa --- /dev/null +++ b/node_modules/stylus/bm.js @@ -0,0 +1,22 @@ + +/** + * Module dependencies. + */ + +var stylus = require('./'); + +var times = 200 + , n = times + , start = new Date; + +console.log('compiling %d times', times); + +while (n--) { + stylus('body\n color: white;\n background: url(/images/foo.png)\n a\n &:hover\n text-decoration: underline;') + .render(function(err, css){}); +} + +var duration = new Date - start; +console.log(' duration: %dms', duration); +console.log(' average: %dms', duration / times); +console.log(' per second: %d', (times / (duration / 1000)).toFixed(1)); diff --git a/node_modules/stylus/docs/bifs.md b/node_modules/stylus/docs/bifs.md new file mode 100644 index 0000000..6ebdbb6 --- /dev/null +++ b/node_modules/stylus/docs/bifs.md @@ -0,0 +1,582 @@ + +## Built-in Functions + +### red(color) + +Return the red component of the given `color`. + + red(#c00) + // => 204 + +### green(color) + +Return the green component of the given `color`. + + green(#0c0) + // => 204 + +### blue(color) + +Return the blue component of the given `color`. + + red(#00c) + // => 204 + +### alpha(color) + +Return the alpha component of the given `color`. + + alpha(#fff) + // => 1 + + alpha(rgba(0,0,0,0.3)) + // => 0.3 + +### dark(color) + +Check if `color` is dark: + + dark(black) + // => true + + dark(#005716) + // => true + + dark(white) + // => false + + +### light(color) + +Check if `color` is light: + + light(black) + // => false + + light(white) + // => true + + light(#00FF40) + // => true + +### hue(color) + +Return the hue of the given `color`. + + hue(hsla(50deg, 100%, 80%)) + // => 50deg + +### saturation(color) + +Return the saturation of the given `color`. + + saturation(hsla(50deg, 100%, 80%)) + // => 100% + +### lightness(color) + +Return the lightness of the given `color`. + + lightness(hsla(50deg, 100%, 80%)) + // => 80% + +### push(expr, args...) + + Push the given `args` to `expr`. + + nums = 1 2 + push(nums, 3, 4, 5) + + nums + // => 1 2 3 4 5 + + Aliased as `append()` + +### unshift(expr, args...) + + Unshift the given `args` to `expr`. + + nums = 4 5 + unshift(nums, 3, 2, 1) + + nums + // => 1 2 3 4 5 + + Aliased as `prepend()` + +### typeof(node) + +Return type of `node` as a string. + + type(12) + // => 'unit' + + typeof(12) + // => 'unit' + + typeof(#fff) + // => 'rgba' + + type-of(#fff) + // => 'rgba' + +Aliased as `type-of` and `type`. + +### unit(unit[, type]) + +Return a string for the type of `unit` or an empty string, +or assign the given `type` without unit conversion. + + unit(10) + // => '' + + unit(15in) + // => 'in' + + unit(15%, 'px') + // => 15px + + unit(15%, px) + // => 15px + +### match(pattern, string) + +Test if `string` matches the given `pattern`. + + match('^foo(bar)?', foo) + match('^foo(bar)?', foobar) + // => true + + match('^foo(bar)?', 'foo') + match('^foo(bar)?', 'foobar') + // => true + + match('^foo(bar)?', 'bar') + // => false + +### abs(unit) + + abs(-5px) + // => 5px + + abs(5px) + // => 5px + +### ceil(unit) + + ceil(5.5in) + // => 6in + +### floor(unit) + + floor(5.6px) + // => 5px + +### round(unit) + + round(5.5px) + // => 6px + + round(5.4px) + // => 5px + +### min(a, b) + + min(1, 5) + // => 1 + +### max(a, b) + + max(1, 5) + // => 5 + +### even(unit) + + even(6px) + // => true + +### odd(unit) + + odd(5mm) + // => true + +### sum(nums) + + sum(1 2 3) + // => 6 + +### avg(nums) + + avg(1 2 3) + // => 2 + +### join(delim, vals...) + + Join the given `vals` with `delim`. + + join(' ', 1 2 3) + // => "1 2 3" + + join(',', 1 2 3) + // => "1,2,3" + + join(', ', foo bar baz) + // => "foo, bar, baz" + + join(', ', foo, bar, baz) + // => "foo, bar, baz" + + join(', ', 1 2, 3 4, 5 6) + // => "1 2, 3 4, 5 6" + +### hsla(color | h,s,l,a) + +Convert the given `color` to an `HSLA` node, +or h,s,l,a component values. + + hslaa(10deg, 50%, 30%, 0.5) + // => HSLA + + hslaa(#ffcc00) + // => HSLA + +### hsla(color | h,s,l) + +Convert the given `color` to an `HSLA` node, +or h,s,l component values. + + hsla(10, 50, 30) + // => HSLA + + hsla(#ffcc00) + // => HSLA + +### rgba(color | r,g,b,a) + +Return `RGBA` from the r,g,b,a channels or provide a `color` to tweak the alpha. + + rgba(255,0,0,0.5) + // => rgba(255,0,0,0.5) + + rgba(255,0,0,1) + // => #ff0000 + + rgba(#ffcc00, 0.5) + // rgba(255,204,0,0.5) + + Alternatively stylus supports the `#rgba` and `#rrggbbaa` notations as well: + + #fc08 + // => rgba(255,204,0,0.5) + + #ffcc00ee + // => rgba(255,204,0,0.9) + +### rgb(color | r,g,b) + +Return a `RGBA` from the r,g,b channels or cast to an `RGBA` node. + + rgb(255,204,0) + // => #ffcc00 + + rgb(#fff) + // => #fff + +### lighten(color, amount) + +Lighten the given `color` by `amount`. This function is +unit-sensitive, for example supporting percentages as shown +below. + + lighten(#2c2c2c, 30) + // => #787878 + + lighten(#2c2c2c, 30%) + // => #393939 + +### darken(color, amount) + +Darken the given `color` by `amount`.This function is +unit-sensitive, for example supporting percentages as shown +below. + + darken(#D62828, 30) + // => #551010 + + darken(#D62828, 30%) + // => #961c1c + +### desaturate(color, amount) + +Desaturate the given `color` by `amount`. + + desaturate(#f00, 40%) + // => #c33 + +### saturate(color, amount) + +Saturate the given `color` by `amount`. + + saturate(#c33, 40%) + // => #f00 + +### unquote(str | ident) + + Unquote the given `str` and returned as a `Literal` node. + + unquote("sans-serif") + // => sans-serif + + unquote(sans-serif) + // => sans-serif + + unquote('1px / 2px') + // => 1px / 2px + +### s(fmt, ...) + + The `s()` function is similar to `unquote()`, in that it returns + a `Literal` node, however it accepts a format string much like C's `sprintf()`. Currently the only specifier is `%s`. + + s('bar()'); + // => bar() + + s('bar(%s)', 'baz'); + // => bar("baz") + + s('bar(%s)', baz); + // => bar(baz) + + s('bar(%s)', 15px); + // => bar(15px) + + s('rgba(%s, %s, %s, 0.5)', 255, 100, 50); + // => rgba(255, 100, 50, 0.5) + + s('bar(%Z)', 15px); + // => bar(%Z) + + s('bar(%s, %s)', 15px); + // => bar(15px, null) + +Check out the `%` string operator for equivalent behaviour. + +### operate(op, left, right) + + Perform the given `op` on the `left` and `right` operands: + + op = '+' + operate(op, 15, 5) + // => 20 + +### length([expr]) + + Parenthesized expressions may act as tuples, the `length()` function returns the length of such expressions. + + length((1 2 3 4)) + // => 4 + + length((1 2)) + // => 2 + + length((1)) + // => 1 + + length(()) + // => 0 + + length(1 2 3) + // => 3 + + length(1) + // => 1 + + length() + // => 0 + +### warn(msg) + + Warn with the given error `msg`, does not exit. + + warn("oh noes!") + +### error(msg) + + Exits with the given error `msg`. + + add(a, b) + unless a is a 'unit' and b is a 'unit' + error('add() expects units') + a + b + +### last(expr) + + Return the _last_ value in the given `expr`: + + nums = 1 2 3 + last(nums) + last(1 2 3) + // => 3 + + list = (one 1) (two 2) (three 3) + last(list) + // => (three 3) + +### p(expr) + + Inspect the given `expr`: + + fonts = Arial, sans-serif + p('test') + p(123) + p((1 2 3)) + p(fonts) + p(#fff) + p(rgba(0,0,0,0.2)) + + add(a, b) + a + b + + p(add) + +stdout: + + inspect: "test" + inspect: 123 + inspect: 1 2 3 + inspect: Arial, sans-serif + inspect: #fff + inspect: rgba(0,0,0,0.2) + inspect: add(a, b) + +### opposite-position(positions) + + Return the opposites of the given `positions`. + + opposite-position(right) + // => left + + opposite-position(top left) + // => bottom right + + opposite-position('top' 'left') + // => bottom right + +### image-size(path) + + Returns the `width` and `height` of the image found at `path`. Lookups are performed in the same manner as `@import`, altered by the `paths` setting. + + width(img) + return image-size(img)[0] + + height(img) + return image-size(img)[1] + + image-size('tux.png') + // => 405px 250px + + image-size('tux.png')[0] == width('tux.png') + // => true + +### add-property(name, expr) + + Adds property `name`, with the given `expr` to the closest block. + + For example: + + something() + add-property('bar', 1 2 3) + s('bar') + + body + foo: something() + +yields: + + body { + bar: 1 2 3; + foo: bar; + } + + Next the "magic" `current-property` local variable comes into play. This variable is automatically available to function bodies, and contains an expression with the current property's name, and value. + + For example if we were to inspect this local variable using `p()`, we + get the following: + + p(current-property) + // => "foo" (foo __CALL__ bar baz) + + p(current-property[0]) + // => "foo" + + p(current-property[1]) + // => foo __CALL__ bar baz + + Using `current-property` we can take our example a bit further, and duplicate the property with new values, and a conditional to ensure the function is only used within a property value. + + something(n) + if current-property + add-property(current-property[0], s('-webkit-something(%s)', n)) + add-property(current-property[0], s('-moz-something(%s)', n)) + s('something(%s)', n) + else + error('something() must be used within a property') + + body { + foo: something(15px) bar; + } + +yields: + + body { + foo: -webkit-something(15px); + foo: -moz-something(15px); + foo: something(15px) bar; + } + + If you noticed in the example above, `bar` is only present for the initial call, since we returned `something(15px)`, it remained in-place within the expression, however the others do not take the rest of the expression into account. + + Our more robust solution below, defines a function named `replace()` which clones the expression to prevent mutation, replaces the string value of an expression with another, and returns the cloned expression. We then move on to replace `__CALL__` within the expressions, which represents the cyclic call to `something()`. + + replace(expr, str, val) + expr = clone(expr) + for e, i in expr + if str == e + expr[i] = val + expr + + something(n) + if current-property + val = current-property[1] + webkit = replace(val, '__CALL__', s('-webkit-something(%s)', n)) + moz = replace(val, '__CALL__', s('-moz-something(%s)', n)) + add-property(current-property[0], webkit) + add-property(current-property[0], moz) + s('something(%s)', n) + else + error('something() must be used within a property') + +yields: + + body { + foo: foo -webkit-something(5px) bar baz; + foo: foo -moz-something(5px) bar baz; + foo: foo something(5px) bar baz; + } + +Our implementation is now fully transparent both in regards to the property it is called within, and the position of the call. This powerful concept aids in transparent vendor support for function calls, such as gradients. + +### Undefined Functions + + Undefined functions will output as literals, so for example + we may call `rgba-stop(50%, #fff)` within our css, and it will + output as you would expect. We can use this within helpers as well. + + In the example below we simply define the function `stop()` which + returns the literal `rgba-stop()` call. + + stop(pos, rgba) + rgba-stop(pos, rgba) + + stop(50%, orange) + // => rgba-stop(50%, #ffa500) \ No newline at end of file diff --git a/node_modules/stylus/docs/comments.md b/node_modules/stylus/docs/comments.md new file mode 100644 index 0000000..6c1b774 --- /dev/null +++ b/node_modules/stylus/docs/comments.md @@ -0,0 +1,35 @@ + +## Comments + + Stylus supports three kinds of comments, single-line, and multi-line comments, and multi-line buffered comments. + +## Single-line + + Single-line comments look like JavaScript comments, and do not output in the resulting CSS: + + // I'm a comment! + body + padding 5px // some awesome padding + +## Multi-line + + Multi-line comments look identical to regular CSS comments, however they only output when the `compress` option is not enabled. + + /* + * Adds the given numbers together. + */ + + add(a, b) + a + b + +## Multi-line buffered + + Multi-line comments which are not suppressed start with `/*!`, signalling Stylus to output the comment regardless of compression. + + /*! + * Adds the given numbers together. + */ + + add(a, b) + a + b + diff --git a/node_modules/stylus/docs/compare.md b/node_modules/stylus/docs/compare.md new file mode 100644 index 0000000..e7da404 --- /dev/null +++ b/node_modules/stylus/docs/compare.md @@ -0,0 +1,81 @@ +## Implementation Comparisons + +Below we go head to head with other implementations. + +### Variables + +SCSS: + + $main-color: #006; + color: $main-color; + +Less: + + @main-color: #006; + color: @main-color; + +Stylus: + + main-color = #006 + color main-color + +### Mixins + +SCSS: + + @mixin pad($x, $y) { + padding: $y $x; + } + + .msg { + @include pad(5px, 10px); + } + +Less: + + .pad(@x, @y) { + padding: @y @x; + } + + .msg { + .pad(5px, 10px); + } + +Stylus: + + pad(x, y) + padding y x + + .msg + pad(5px, 10px) + +### Larger Example + +Less: + + .box-shadow (@x: 0, @y: 0, @blur: 1px, @alpha) { + @val: @x @y @blur rgba(0, 0, 0, @alpha); + box-shadow: @val; + -webkit-box-shadow: @val; + -moz-box-shadow: @val; + } + .box { + @base: #f938ab; + color: saturate(@base, 5%); + border-color: lighten(@base, 30%); + div { .box-shadow(0, 0, 5px, 0.4) } + } + +Stylus: + + box-shadow() + -webkit-box-shadow arguments + -moz-box-shadow arguments + box-shadow arguments + + .box + base = #f938ab + color saturate(base, 5%) + border-color lighten(base, 30%) + div + box-shadow 0 0 5px 0.4 \ No newline at end of file diff --git a/node_modules/stylus/docs/conditionals.md b/node_modules/stylus/docs/conditionals.md new file mode 100644 index 0000000..8d6d322 --- /dev/null +++ b/node_modules/stylus/docs/conditionals.md @@ -0,0 +1,107 @@ + +## Conditionals + + Conditionals provide control flow to a language which is otherwise static, providing conditional imports, mixins, functions, and more. The examples below are simply examples, and not recommended :) + +### if / else if / else + + The `if` conditional works as you would expect, simply accepting an expression, evaluating the following block when `true`. Along with `if` are the typical `else if` and `else` tokens, acting as fallbacks. + + The example below would conditionally overload the `padding` property, swapping it for margin. + + overload-padding = true + + if overload-padding + padding(y, x) + margin y x + + body + padding 5px 10px + +Another example: + + box(x, y, margin = false) + padding y x + if margin + margin y x + + body + box(5px, 10px, true) + +Another `box()` helper: + + box(x, y, margin-only = false) + if margin-only + margin y x + else + padding y x + +### unless + + For users familiar with the ruby programming language, we have the `unless` conditional, which is essentially the opposite of `if`, essentially `if (!(expr))`. + +In the example below, if `disable-padding-override` is undefined or `false` padding will be overridden, displaying `margin` instead. However when `true` padding will remain outputting `padding 5px 10px` as expected. + + disable-padding-override = true + + unless disable-padding-override is defined and disable-padding-override + padding(x, y) + margin y x + + body + padding 5px 10px + +### Postfix Conditionals + + Stylus supports postfix conditionals, meaning the `if` and `unless` act as operators, evaluating the left-hand operand, when the right-hand expression is truthy. + + + For example let's define `negative()`, performing some basic type checking. Below we use block-style conditionals: + + negative(n) + unless n is a 'unit' + error('invalid number') + if n < 0 + yes + else + no + + Next we utilize postfix conditionals to keep our function terse. + + negative(n) + error('invalid number') unless n is a 'unit' + return yes if n < 0 + no + + Of course we could take this further, and utilize `n < 0 ? yes : no`, or simply stick with booleans, and use only `n < 0`. + + Postfix conditionals may be applied to most single-line statements, for example `@import`, `@charset`, mixins, and of course properties as shown below: + + + pad(types = margin padding, n = 5px) + padding unit(n, px) if padding in types + margin unit(n, px) if margin in types + + body + pad() + + body + pad(margin) + + body + apply-mixins = true + pad(padding, 10) if apply-mixins + +yielding: + + body { + padding: 5px; + margin: 5px; + } + body { + margin: 5px; + } + body { + padding: 10px; + } + diff --git a/node_modules/stylus/docs/css-style.md b/node_modules/stylus/docs/css-style.md new file mode 100644 index 0000000..3d433c4 --- /dev/null +++ b/node_modules/stylus/docs/css-style.md @@ -0,0 +1,77 @@ + +## CSS Style + + Stylus transparently supports a regular css-style syntax, meaning you do not need to use an alternative parser, or specify that a certain file is using a specific style. + +### Example + + Below is a small style using the indented approach: + + border-radius() + -webkit-border-radius arguments + -moz-border-radius arguments + border-radius arguments + + body a + font 12px/1.4 "Lucida Grande", Arial, sans-serif + background black + color #ccc + + form input + padding 5px + border 1px solid + border-radius 5px + + Since braces, colons, and semi-colons are optional, we could write this example just as we would with normal css: + + border-radius() { + -webkit-border-radius: arguments; + -moz-border-radius: arguments; + border-radius: arguments; + } + + body a { + font: 12px/1.4 "Lucida Grande", Arial, sans-serif; + background: black; + color: #ccc; + } + + form input { + padding: 5px; + border: 1px solid; + border-radius: 5px; + } + + Since we may mix and match the two variants, the following is valid as well: + + border-radius() + -webkit-border-radius: arguments; + -moz-border-radius: arguments; + border-radius: arguments; + + body a { + font: 12px/1.4 "Lucida Grande", Arial, sans-serif; + background: black; + color: #ccc; + } + + form input + padding: 5px; + border: 1px solid; + border-radius: 5px; + + Variables, functions, mixins, and all of the other features that Stylus provides still work as expected: + + main-color = white + main-hover-color = black + + body a { + color: main-color; + &:hover { color: main-hover-color; } + } + + body a { color: main-color; &:hover { color: main-hover-color; }} + + There are currently a few exceptions to this rule, since the two styles may be mixed and matched some indentation rules still apply. So although not _every_ plain-css stylesheet will work without modification this feature still allows those who prefer css syntax may still utilize the other powerful features provided by Stylus. + + diff --git a/node_modules/stylus/docs/error-reporting.md b/node_modules/stylus/docs/error-reporting.md new file mode 100644 index 0000000..5b2def2 --- /dev/null +++ b/node_modules/stylus/docs/error-reporting.md @@ -0,0 +1,50 @@ + +## Error Reporting + + Stylus has fantastic error reporting built in for syntax, parse, and evaluation errors, complete with stack traces, line numbers, and filenames. + +### Parse Error + +Parse error example: + + body + form input + == padding 5px + +yielding: + + Error: /Users/tj/Projects/stylus/testing/test.styl:4 + 3: ' form input' + 4: ' == padding 5px' + + illegal unary == + +### Evaluation Error + + This "runtime" or evaluation error is caused due to passing a string to `border-radius()` instead of the expected `Unit` by using our helper `ensure(n, 'unit')`. + + ensure(val, type) + unless val is a type + error('expected a ' + type + ', but got ' + typeof(val)) + + border-radius(n) + ensure(n, 'unit') + -webkit-border-radius n + -moz-border-radius n + border-radius n + + body + border-radius '5px' + +yielding: + + Error: /Users/tj/Projects/stylus/examples/error.styl:12 + 11: '' + 12: 'body' + 13: ' border-radius \'5px\'' + 14: '' + + expected a unit, but got string + at ensure() (/Users/tj/Projects/stylus/examples/error.styl:2) + at border-radius() (/Users/tj/Projects/stylus/examples/error.styl:5) + at "body" (/Users/tj/Projects/stylus/examples/error.styl:10) diff --git a/node_modules/stylus/docs/escape.md b/node_modules/stylus/docs/escape.md new file mode 100644 index 0000000..f2d7348 --- /dev/null +++ b/node_modules/stylus/docs/escape.md @@ -0,0 +1,27 @@ + +## Escaping + + Stylus allows you to escape characters, effectively turning them into identifiers, so that they can be rendered as literals. For example: + + body + padding 1 \+ 2 + +will compile to: + + body { + padding: 1 + 2; + } + + +Not that Stylus requires that `/` is parenthesized when used in a property: + + body + font 14px/1.4 + font (14px/1.4) + +yields: + + body { + font: 14px/1.4; + font: 10px; + } \ No newline at end of file diff --git a/node_modules/stylus/docs/executable.md b/node_modules/stylus/docs/executable.md new file mode 100644 index 0000000..5205145 --- /dev/null +++ b/node_modules/stylus/docs/executable.md @@ -0,0 +1,159 @@ + +## Stylus Executable + +Stylus ships with the `stylus` executable for converting stylus to css. + + Usage: stylus [options] [command] [< in [> out]] + [file|dir ...] + + Commands: + + help Opens help info for in + your default browser. (osx only) + + Options: + + -u, --use Utilize the stylus plugin at + -i, --interactive Start interactive REPL + -w, --watch Watch file(s) for changes and re-compile + -o, --out Output to when passing files + -C, --css [dest] Convert css input to stylus + -I, --include Add to lookup paths + -c, --compress Compress css output + -d, --compare Display input along with output + -f, --firebug Emits debug infos in the generated css that + can be used by the FireStylus Firebug plugin + -l, --line-numbers Emits comments in the generated css + indicating the corresponding stylus line + -V, --version Display the version of stylus + -h, --help Display help information + +### STDIO Compilation Example + + `stylus` reads from _stdin_ and outputs to _stdout_, so for example: + + $ stylus --compress < some.styl > some.css + +Try stylus some in the terminal, type below and press CTRL-D for __EOF__: + + $ stylus + body + color red + font 14px Arial, sans-serif + +### Compiling Files Example + + `stylus` also accepts files and directories, for example a directory named `css` will compile and output the `.css` files in the same directory. + + $ stylus css + + The following will output to `./public/stylesheets`: + + $ stylus css --out public/stylesheets + + Or a few files: + + $ stylus one.styl two.styl + + For development purpose, you can enable the `linenos` option to emit comments indicating + the Stylus filename and line number in the generated css: + + $ stylus --line-numbers + + Or the `firebug` option if you want to use + the [FireStylus extension for Firebug](//github.com/LearnBoost/stylus/blob/master/docs/firebug.md): + + $ stylus --firebug + +### Converting CSS + + If we wish to convert css to the terse Stylus syntax, we can utilize the `--css` flag. + + Via stdio: + + $ stylus --css < test.css > test.styl + + Output a `.styl` file of the same basename: + + $ stylus --css test.css + + Output to a specific destination: + + $ stylus --css test.css /tmp/out.styl + +### CSS Property Help + + On osx `stylus help ` will open your default browser and display help documentation for the given ``. + + $ stylus help box-shadow + +### Interactive Shell + + The Stylus REPL (Read-Eval-Print-Loop) or "interactive shell" allows you to + play around with Stylus expressions directly from your terminal. Note that this works only for expressions, not selectors etc. To use simple add the `-i`, or `--interactive` flag: + + $ stylus -i + > color = white + => #fff + > color - rgb(200,50,0) + => #37cdff + > color + => #fff + > color -= rgb(200,50,0) + => #37cdff + > color + => #37cdff + > rgba(color, 0.5) + => rgba(55,205,255,0.5) + +### Utilizing Plugins + + For our examples we will utilize the [nib](https://github.com/visionmedia/nib) Stylus plugin to illustrate it's CLI usage. Suppose we have the following stylus, importing nib and utilize it's `linear-gradient()` function. + + @import 'nib' + + body + background: linear-gradient(20px top, white, black) + + Our first attempt to render using `stylus(1)` via stdio might look like this: + + $ stylus < test.styl + + Which would yield the following error because stylus does not know where to find nib in our machine. + + Error: stdin:3 + 1| + 2| + > 3| @import 'nib' + 4| + 5| body + 6| background: linear-gradient(20px top, white, black) + + For plugins that simply supply stylus APIs we could add the path to the stylus lookup paths by using the `--include` or `-I` flag: + + $ stylus < test.styl --include ../nib/lib + + Now yielding the following output. As you might notice the calls to `gradient-data-uri()` and `create-gradient-image()` output as literals, this is because exposing the library path is not enough when the plugin provides a JavaScript API, though if we wished to only utilize the pure-stylus nib functions we would be fine. + + body { + background: url(gradient-data-uri(create-gradient-image(20px, top))); + background: -webkit-gradient(linear, left top, left bottom, color-stop(0, #fff), color-stop(1, #000)); + background: -webkit-linear-gradient(top, #fff 0%, #000 100%); + background: -moz-linear-gradient(top, #fff 0%, #000 100%); + background: linear-gradient(top, #fff 0%, #000 100%); + } + + So, what we need to do is utilize the `--use`, or `-u` flag which expects a path to a node module, with or without the ".js" extension. This `require()`s the module, expecting a function to be exported as `module.exports`, which then calls `style.use(fn())` to allow the plugin to expose itself, defining js functions etc. + + $ stylus < test.styl --use ../nib/lib/nib + + Yielding the expected result: + + body { + background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAUCAYAAABMDlehAAAABmJLR0QA/wD/AP+gvaeTAAAAI0lEQVQImWP4+fPnf6bPnz8zMH358oUBwkIjKJBgYGNj+w8Aphk4blt0EcMAAAAASUVORK5CYII="); + background: -webkit-gradient(linear, left top, left bottom, color-stop(0, #fff), color-stop(1, #000)); + background: -webkit-linear-gradient(top, #fff 0%, #000 100%); + background: -moz-linear-gradient(top, #fff 0%, #000 100%); + background: linear-gradient(top, #fff 0%, #000 100%); + } + diff --git a/node_modules/stylus/docs/firebug.md b/node_modules/stylus/docs/firebug.md new file mode 100644 index 0000000..fe05962 --- /dev/null +++ b/node_modules/stylus/docs/firebug.md @@ -0,0 +1,60 @@ + +## FireStylus extension for Firebug + +[FireStylus](//github.com/parallel/firestylus) is a Firebug extension +that makes Firebug display the Stylus filename and line numbers of +the Stylus-generated CSS styles rather than those of the generated CSS. + +![Screenshot](//raw.github.com/parallel/firestylus/master/src/chrome/skin/screenshot.png) + +### Usage + +First, you need to install [Firebug](https://addons.mozilla.org/firefox/downloads/latest/1843/addon-1843-latest.xpi?src=addondetail) +and the [FireStylus extension](//github.com/parallel/firestylus) + +Then, you need to enable the Stylus's `firebug` option when generating your CSS. + +Command line + + $ stylus -f + $ stylus --firebug + +Javascript API + + var stylus = require('stylus'); + + stylus(str) + .set('firebug', true) + .render(function(err, css){ + // logic + }); + +Connect / Express + + var stylus = require('stylus'); + + var server = connect.createServer( + stylus.middleware({ + src: __dirname + , dest: __dirname + '/public' + , firebug: true + }) + , connect.static(__dirname + '/public') + ); + +### Compatibility + + FireStylus should work with all versions of Firefox after + and including 3.0, and all Firebug versions after and including 1.4 + + - Firefox 3+ (also works with version 5) + - Firebug 1.4+ + +### Limitations + +FireStylus and FireSass are incompatible. You cannot enable them +simultaneously. + +FireStylus (like FireSass) only works in the html pane of firebug, the others, +such as the css pane won't work due to firebug limitations. + diff --git a/node_modules/stylus/docs/font-face.md b/node_modules/stylus/docs/font-face.md new file mode 100644 index 0000000..408b491 --- /dev/null +++ b/node_modules/stylus/docs/font-face.md @@ -0,0 +1,26 @@ + +## @font-face + + The `@font-face` at-rule expects as you would expect, simply followed by a block of properties: + + + @font-face + font-family Geo + font-style normal + src url(fonts/geo_sans_light/GensansLight.ttf) + + .ingeo + font-family Geo + +yielding: + + + @font-face { + font-family: Geo; + font-style: normal; + src: url("fonts/geo_sans_light/GensansLight.ttf"); + } + .ingeo { + font-family: Geo; + } + diff --git a/node_modules/stylus/docs/functions.md b/node_modules/stylus/docs/functions.md new file mode 100644 index 0000000..d762104 --- /dev/null +++ b/node_modules/stylus/docs/functions.md @@ -0,0 +1,192 @@ + +## Functions + + Stylus features powerful in-language function definition. Function definition appears identical to mixins, however functions may return a value. + +### Return Values + + Let's try a trivial example, creating a function that adds two numbers. + + add(a, b) + a + b + + We may then utilize this function in conditions, as property values, etc. + + body + padding add(10px, 5) + + Rendering + + body { + padding: 15px; + } + +### Argument Defaults + + Optional arguments may default to a given expression. With Stylus we may even default arguments to leading arguments! For example: + + + add(a, b = a) + a + b + + add(10, 5) + // => 15 + + add(10) + // => 20 + +note that since argument defaults are assignments, we can also utilize function calls for defaults: + + add(a, b = unit(a, px)) + a + b + +### Function Bodies + + We can take our simple `add()` function further, by casting all units passed as `px` via the `unit()` built-in. Re-assigning each argument and providing a unit type string (or identifier), which disregards unit conversion. + + add(a, b = a) + a = unit(a, px) + b = unit(b, px) + a + b + + add(15%, 10deg) + // => 25 + +### Multiple Return Values + + Stylus functions can return several values, just as you can assign several values to a variable. For example the following is a valid assignment: + + sizes = 15px 10px + + sizes[0] + // => 15px + +Similarly we may return several values: + + sizes() + 15px 10px + + sizes()[0] + // => 15px + +One slight exception is when return values are identifiers, for example the following looks like a property assignment to Stylus since no operators are present. + + swap(a, b) + b a + +To disambiguate we may either wrap in parens, or utilize the `return` keyword. + + swap(a, b) + (b a) + + swap(a, b) + return b a + +### Conditionals + + Let's say we want to create a function named `stringish()` to see if the value given can be transformed to a string. We check if `val` is a string, or an ident which is string-like. Because undefined identifiers yield themselves as the value, we may compare them to them-selves as shown below, where `yes` and `no` are used in place of `true` and `false`. + + + stringish(val) + if val is a 'string' or val is a 'ident' + yes + else + no + +usage: + + stringish('yay') == yes + // => true + + stringish(yay) == yes + // => true + + stringish(0) == no + // => true + +__note__: `yes` and `no` are not boolean literals, they are simply undefined identifiers in this case. + +Another example: + + + compare(a, b) + if a > b + higher + else if a < b + lower + else + equal + +usage: + + compare(5, 2) + // => higher + + compare(1, 5) + // => lower + + compare(10, 10) + // => equal + +### Aliasing + + To alias a function we can simply assign a function's name to a new identifier. For example our previous `add()` function could be exposed as `plus()` as well, simply by: + + plus = add + + plus(1, 2) + // => 3 + +### Variable Functions + + In the same way that we can "alias" a function, we can pass a function as well, here our `invoke()` function accepts a function, so we can pass it `add()` or `sub()`. + + invoke(a, b, fn) + fn(a, b) + + add(a, b) + a + b + + body + padding invoke(5, 10, add) + padding invoke(5, 10, sub) + +yielding: + + body { + padding: 15; + padding: -5; + } + +### arguments + + The `arguments` local is available to all function bodies, and contains all the arguments passed. For example: + + sum() + n = 0 + for num in arguments + n = n + num + + sum(1,2,3,4,5) + // => 15 + +### Hash Example + + Below we define the `get(hash, key)` function, which will return the + value of `key`, or `null`. We iterate each `pair` in `hash`, returning the pair's second node when the first (the `key`) matches. + + get(hash, key) + return pair[1] if pair[0] == key for pair in hash + +As you can see below, in-language functions paired with robust stylus expressions can provide great flexibility. + + hash = (one 1) (two 2) (three 3) + + get(hash, two) + // => 2 + + get(hash, three) + // => 3 + + get(hash, something) + // => null diff --git a/node_modules/stylus/docs/functions.url.md b/node_modules/stylus/docs/functions.url.md new file mode 100644 index 0000000..693bbaa --- /dev/null +++ b/node_modules/stylus/docs/functions.url.md @@ -0,0 +1,30 @@ +## Data URI Image Inlining + +Stylus is bundled with an optional function named `url()`, which replaces the literal `url()` calls, and conditionally inlines them using base64 [Data URIs](http://en.wikipedia.org/wiki/Data_URI_scheme). + +### Example + +The function itself is available via `require('stylus').url`, and accepts an options object, returning a function that Stylus calls internally when it sees `url()`. + +The `.define(name, callback)` method assigned a JavaScript function that can be called from stylus source. In this case we have our images in `./css/images` then we can ignore the `paths` option, since image lookups are performed relative to the file being rendered (by default), we may alter this with the option. + + stylus(str) + .set('filename', __dirname + '/css/test.styl') + .define('url', stylus.url()) + .render(function(err, css){ + + }); + +For example if our images live in `./public/images` and we wish to use `url(images/tobi.png)`, we can pass `paths` with our public directory, which will become part of the lookup process. Like-wise if we wanted `url(tobi.png)` instead, we would pass `paths: [__dirname + '/public/images']`. + + stylus(str) + .set('filename', __dirname + '/css/test.styl') + .define('url', stylus.url({ paths: [__dirname + '/public'] })) + .render(function(err, css){ + + }); + +### Options + + - `limit` bytesize limit defaulting to 30Kb (30000) + - `paths` image resolution path(s) \ No newline at end of file diff --git a/node_modules/stylus/docs/gedit.md b/node_modules/stylus/docs/gedit.md new file mode 100644 index 0000000..b01d26a --- /dev/null +++ b/node_modules/stylus/docs/gedit.md @@ -0,0 +1,24 @@ +## gedit language-spec + + Stylus ships with a temporary version of `styl.lang` for [GtkSourceView](http://live.gnome.org/GtkSourceView), based off [Yanekk](https://github.com/yanekk)'s [work](https://github.com/gmate/gmate/blob/master/lang-specs/scss.lang) on `scss.lang`. + + ![Stylus Language Specification for GtkSourceView](http://i.imgur.com/uBppL.png)) + + This is a start and provides a basic [language spec](http://live.gnome.org/Gedit/NewLanguage) for GtkSourceView editors such as [gedit](http://projects.gnome.org/gedit/). + + **Installation Steps** + + Download `styl.lang` to your local `language-specs` folder: + + mkdir -p ~/.local/share/gtksourceview-2.0/language-specs/ && wget https://raw.github.com/LearnBoost/stylus/master/editors/gedit/styl.lang -O ~/.local/share/gtksourceview-2.0/language-specs/styl.lang + + Update the mime database and enjoy Stylus syntax in gedit! + + cd ~/.local/share + update-mime-database mime + + This is much more enjoyable than having gedit recognize your `.styl` files as Apache Confs! + + --- + + **Have a sweet tooth?** Add more icing to gedit with gedit-icing: [https://github.com/niftylettuce/gedit-icing](https://github.com/niftylettuce/gedit-icing) diff --git a/node_modules/stylus/docs/import.md b/node_modules/stylus/docs/import.md new file mode 100644 index 0000000..045d083 --- /dev/null +++ b/node_modules/stylus/docs/import.md @@ -0,0 +1,73 @@ +## Import + + Stylus supports both literal __@import__ for CSS, as well as dynamic importing of other Stylus sheets. + +### Literal CSS + + Any filename with the extension `.css` will become a literal, for example: + + @import "reset.css" + +will render to the literal css __@import__ shown below: + + @import "reset.css" + +### Stylus Import + + When using __@import__ without the `.css` extension, it is assumed to be a Stylus sheet, for example `@import "mixins/border-radius"`. + + __@import__ works by iterating an array of directories, and seeing if this file lives in any of them, similar to node's `require.paths`. This array defaults to a single path which is derived from the `filename` option's dirname. So if your filename is `/tmp/testing/stylus/main.styl`, then import will look in `/tmp/testing/stylus/`. + + __@import__ also supports index styles, meaning if you `@import blueprint`, it will resolve either `blueprint.styl` or `blueprint/index.styl`, useful for libraries to expose all of their features, but still allow a subset of the library to be imported. For example a common lib structure might be: + + ./tablet + |-- index.styl + |-- vendor.styl + |-- buttons.styl + |-- images.styl + + In the example below we set the `paths` options to provide additional paths to Stylus. Within `./test.styl` we could then `@import "mixins/border-radius"` or `@import "border-radius"` since `./mixins` is exposed to Stylus. + + /** + * Module dependencies. + */ + + var stylus = require('../') + , str = require('fs').readFileSync(__dirname + '/test.styl', 'utf8'); + + var paths = [ + __dirname + , __dirname + '/mixins' + ]; + + stylus(str) + .set('filename', __dirname + '/test.styl') + .set('paths', paths) + .render(function(err, css){ + if (err) throw err; + console.log(css); + }); + +### JavaScript Import API + + When using the `.import(path)` method, these imports are deferred until evaluation: + + var stylus = require('../') + , str = require('fs').readFileSync(__dirname + '/test.styl', 'utf8'); + + stylus(str) + .set('filename', __dirname + '/test.styl') + .import('mixins/vendor') + .render(function(err, css){ + if (err) throw err; + console.log(css); + }); + + The following are essentially equivalent: + + @import 'mixins/vendor' + +and + + .import('mixins/vendor') + \ No newline at end of file diff --git a/node_modules/stylus/docs/interpolation.md b/node_modules/stylus/docs/interpolation.md new file mode 100644 index 0000000..a9e915e --- /dev/null +++ b/node_modules/stylus/docs/interpolation.md @@ -0,0 +1,55 @@ + +## Interpolation + + Stylus supports interpolation by using the `{}` characters to surround an expression, which then becomes part of the identifier. For example `-webkit-{'border' + '-radius'}` would evaluate to `-webkit-border-radius`. + + A great example use-case for this is expanding properties with vendor prefixes. + + vendor(prop, args) + -webkit-{prop} args + -moz-{prop} args + {prop} args + + border-radius() + vendor('border-radius', arguments) + + box-shadow() + vendor('box-shadow', arguments) + + button + border-radius 1px 2px / 3px 4px + +yielding: + + button { + -webkit-border-radius: 1px 2px / 3px 4px; + -moz-border-radius: 1px 2px / 3px 4px; + border-radius: 1px 2px / 3px 4px; + } + +## Selector Interpolation + + Interpolation works with selectors as well, for example we may iterate while assigning the `height` property for the first 5 rows in a table as shown below. + + table + for row in 1 2 3 4 5 + tr:nth-child({row}) + height: 10px * row + +yielding: + + table tr:nth-child(1) { + height: 10px; + } + table tr:nth-child(2) { + height: 20px; + } + table tr:nth-child(3) { + height: 30px; + } + table tr:nth-child(4) { + height: 40px; + } + table tr:nth-child(5) { + height: 50px; + } \ No newline at end of file diff --git a/node_modules/stylus/docs/introspection.md b/node_modules/stylus/docs/introspection.md new file mode 100644 index 0000000..06d7c49 --- /dev/null +++ b/node_modules/stylus/docs/introspection.md @@ -0,0 +1,39 @@ + +## Introspection API + + Stylus supports an introspection API, allowing mixins and functions to reflect relative to the caller etc. + + +## mixin + + The `mixin` local variable is automatically assigned within function bodies, + containing the string "root" indicating the function is called at the root + level, or "block" indicating otherwise, and finally `false` if the function + is invoked expecting a return value. + + In the following example we define `reset()` altering its behaviour when mixed in to root, another block, or a return value as used in the `foo` property below. + + reset() + if mixin == 'root' + got + root true + else if mixin + got 'a mixin' + else + 'not a mixin' + + reset() + + body + reset() + foo reset() + +compiles to: + + got { + root: true; + } + body { + foo: "not a mixin"; + got: "a mixin"; + } diff --git a/node_modules/stylus/docs/iteration.md b/node_modules/stylus/docs/iteration.md new file mode 100644 index 0000000..b309840 --- /dev/null +++ b/node_modules/stylus/docs/iteration.md @@ -0,0 +1,100 @@ + +## Iteration + + Stylus allows you to iterate expressions via the `for/in` construct, taking the form of: + + for [, ] in + +For example: + + body + for num in 1 2 3 + foo num + +yields: + + body { + foo: 1; + foo: 2; + foo: 3; + } + +The example below shows how to use the ``: + + body + fonts = Impact Arial sans-serif + for font, i in fonts + foo i font + +yielding: + + body { + foo: 0 Impact; + foo: 1 Arial; + foo: 2 sans-serif; + } + +### Mixins + + We may utilize iteration within mixins to produce powerful functionality, for example we can apply expression pairs as properties using interpolation and iteration. Below we define `apply()`, conditionally utilizing all the `arguments` so that comma-delimited _and_ expression lists are supported: + + apply(props) + props = arguments if length(arguments) > 1 + for prop in props + {prop[0]} prop[1] + + body + apply(one 1, two 2, three 3) + + body + list = (one 1) (two 2) (three 3) + apply(list) + +### Functions + + Stylus functions may also contain for-loops, below are some example use-cases: + +sum: + + sum(nums) + sum = 0 + for n in nums + sum += n + + sum(1 2 3) + // => 6 + +join: + + join(delim, args) + buf = '' + for arg, index in args + if index + buf += delim + arg + else + buf += arg + + join(', ', foo bar baz) + // => "foo, bar, baz" + +### Postfix + + Much like `if` / `unless` may be utilized post-statement, the same can be done with `for`. Below are the same examples as above utilizing the postfix syntax: + + sum(nums) + sum = 0 + sum += n for n in nums + + + join(delim, args) + buf = '' + buf += i ? delim + arg : arg for arg, i in args + + We can also __return__ from within a loop, below is an example returning the + number when `n % 2 == 0` evaluates to __true__. + + first-even(nums) + return n if n % 2 == 0 for n in nums + + first-even(1 3 5 5 6 3 2) + // => 6 \ No newline at end of file diff --git a/node_modules/stylus/docs/js.md b/node_modules/stylus/docs/js.md new file mode 100644 index 0000000..0bbba83 --- /dev/null +++ b/node_modules/stylus/docs/js.md @@ -0,0 +1,145 @@ +## JavaScript API + +Simply require the module, and call `render()` with the given string of stylus code, and (optional) options object. Frameworks utilizing stylus should pass the `filename` option to provide better error reporting. + + var stylus = require('stylus'); + + stylus.render(str, { filename: 'nesting.css' }, function(err, css){ + if (err) throw err; + console.log(css); + }); + +We can also do the same thing in a more progressive manner: + + var stylus = require('stylus'); + + stylus(str) + .set('filename', 'nesting.css') + .render(function(err, css){ + // logic + }); + +### .set(setting, value) + + Apply a setting such as a `filename`, or import `paths`: + + .set('filename', __dirname + '/test.styl') + .set('paths', [__dirname, __dirname + '/mixins']) + +### .include(path) + + A progressive alternative to setting `paths` via `.set()`, which is ideal when exposing external stylus libraries which expose a path. + + stylus(str) + .include(require('nib').path) + .include(process.env.HOME + '/mixins') + .render(...) + +### .import(path) + +Defer importing of the given `path` until evaluation is performed. The example below is essentially the same as doing `@import 'mixins/vendor'` within your Stylus sheet. + + var stylus = require('../') + , str = require('fs').readFileSync(__dirname + '/test.styl', 'utf8'); + + stylus(str) + .set('filename', __dirname + '/test.styl') + .import('mixins/vendor') + .render(function(err, css){ + if (err) throw err; + console.log(css); + }); + +### .define(name, node) + + By passing a `Node`, we may define a global variable. This is useful when exposing conditional features within your library depending on the availability of another. For example the "Nib" extensions library conditionally supports node-canvas, providing image generation, however this is not always available, so Nib may define: + + .define('has-canvas', stylus.nodes.false); + .define('some-setting', new stylus.nodes.String('some value')); + + Stylus also casts JavaScript values to their Stylus equivalents when possible, the following are a few examples: + + .define('string', 'some string') + .define('number', 15.5) + .define('some-bool', true) + .define('list', [1,2,3]) + .define('families', ['Helvetica Neue', 'Helvetica', 'sans-serif']) + +### .define(name, fn) + + This method allows you to provide a JavaScript-defined function to Stylus, think of these as you would JavaScript to C++ bindings. When you have something you cannot do within Stylus, you define it in JavaScript. + +In our example we define four functions `add()`, `sub()`, `image-width()`, and `image-height()`. These functions must return a `Node`, this constructor and the other nodes are available via `stylus.nodes`. + + var stylus = require('../') + , nodes = stylus.nodes + , utils = stylus.utils + , fs = require('fs'); + + function add(a, b) { + return a.operate('+', b); + } + + function sub(a, b) { + return a.operate('-', b); + } + + function imageDimensions(img) { + // assert that the node (img) is a String node, passing + // the param name for error reporting + utils.assertType(img, 'string', 'img'); + var path = img.val; + + // Grab bytes necessary to retrieve dimensions. + // if this was real you would do this per format, + // instead of reading the entire image :) + var data = fs.readFileSync(__dirname + '/' + path); + + // GIF + // of course you would support.. more :) + if ('GIF' == data.slice(0, 3).toString()) { + var w = data.slice(6, 8) + , h = data.slice(8, 10); + w = w[1] << 8 | w[0]; + h = h[1] << 8 | h[0]; + } + + return [w, h]; + } + + function imageWidth(img) { + return new nodes.Unit(imageDimensions(img)[0]); + } + + function imageHeight(img) { + return new nodes.Unit(imageDimensions(img)[1]); + } + + stylus(str) + .set('filename', 'js-functions.styl') + .define('add', add) + .define('sub', sub) + .define('image-width', imageWidth) + .define('image-height', imageHeight) + .render(function(err, css){ + if (err) throw err; + console.log(css); + }); + + For further reference until documentation is complete please reference the following files: + + - lib/nodes/* + - lib/utils.js + +### .use(fn) + + When called, the given `fn` is invoked with the renderer, allowing all of the methods above to be used. This allows for plugins to easily expose themselves, defining functions, paths etc. + + var mylib = function(style){ + style.define('add', add); + style.define('sub', sub); + }; + + stylus(str) + .use(mylib) + .render(...) diff --git a/node_modules/stylus/docs/keyframes.md b/node_modules/stylus/docs/keyframes.md new file mode 100644 index 0000000..9486ed9 --- /dev/null +++ b/node_modules/stylus/docs/keyframes.md @@ -0,0 +1,120 @@ + +## @keyframes + + Stylus supports the `@keyframes` at-rule, which is converted to `@-webkit-keyframes` when compiled: + + + @keyframes pulse + 0% + background-color red + opacity 1.0 + -webkit-transform scale(1.0) rotate(0deg) + 33% + background-color blue + opacity 0.75 + -webkit-transform scale(1.1) rotate(-5deg) + 67% + background-color green + opacity 0.5 + -webkit-transform scale(1.1) rotate(5deg) + 100% + background-color red + opacity 1.0 + -webkit-transform scale(1.0) rotate(0deg) + +yielding: + + @-webkit-keyframes pulse { + 0% { + background-color: red; + opacity: 1; + -webkit-transform: scale(1) rotate(0deg); + } + + 33% { + background-color: blue; + opacity: 0.75; + -webkit-transform: scale(1.1) rotate(-5deg); + } + + 67% { + background-color: green; + opacity: 0.5; + -webkit-transform: scale(1.1) rotate(5deg); + } + + 100% { + background-color: red; + opacity: 1; + -webkit-transform: scale(1) rotate(0deg); + } + + } + +## Expansion + + By utilizing `@keyframes` your rules are automatically expanded to the vendor prefixes defined by the `vendors` variable, defaulting to `webkit moz official`. This means we can alter it at any time for the expansion to take effect immediately. For example consider the following + + @keyframes foo { + from { + color: black + } + to { + color: white + } + } + +expands to our two default vendors and the official syntax: + + @-moz-keyframes foo { + 0% { + color: #000; + } + + 100% { + color: #fff; + } + } + @-webkit-keyframes foo { + 0% { + color: #000; + } + + 100% { + color: #fff; + } + } + @keyframes foo { + 0% { + color: #000; + } + + 100% { + color: #fff; + } + } + +if we wanted to limit to the official syntax only, simply alter `vendors`: + + vendors = official + + @keyframes foo { + from { + color: black + } + to { + color: white + } + } + +yielding: + + @keyframes foo { + 0% { + color: #000; + } + + 100% { + color: #fff; + } + } diff --git a/node_modules/stylus/docs/kwargs.md b/node_modules/stylus/docs/kwargs.md new file mode 100644 index 0000000..c9d0afc --- /dev/null +++ b/node_modules/stylus/docs/kwargs.md @@ -0,0 +1,35 @@ + +## Keyword Arguments + + Stylus supports keyword arguments, or "kwargs", allowing you to key + arguments by their associated parameter name. + + The examples shown below are functionally equivalent, however we can + place keyword arguments anywhere within the list. The remaining arguments + that are _not_ keyed will be applied to the parameters that have not + been satisfied. + + body { + color: rgba(255, 200, 100, 0.5); + color: rgba(red: 255, green: 200, blue: 100, alpha: 0.5); + color: rgba(alpha: 0.5, blue: 100, red: 255, 200); + color: rgba(alpha: 0.5, blue: 100, 255, 200); + } + + yielding: + + body { + color: rgba(255,200,100,0.5); + color: rgba(255,200,100,0.5); + color: rgba(255,200,100,0.5); + color: rgba(255,200,100,0.5); + } + + + To see what parameters a function or mixin accept, use the `p()` function: + + p(rgba) + + yielding: + + inspect: rgba(red, green, blue, alpha) diff --git a/node_modules/stylus/docs/literal.md b/node_modules/stylus/docs/literal.md new file mode 100644 index 0000000..52f84c7 --- /dev/null +++ b/node_modules/stylus/docs/literal.md @@ -0,0 +1,16 @@ +## Literal CSS + + If for any reason Stylus cannot accommodate a specific need, you can always resort to literal css via `@css`: + + + @css { + body { + font: 14px; + } + } + +compiling to: + + body { + font: 14px; + } \ No newline at end of file diff --git a/node_modules/stylus/docs/media.md b/node_modules/stylus/docs/media.md new file mode 100644 index 0000000..5603c4f --- /dev/null +++ b/node_modules/stylus/docs/media.md @@ -0,0 +1,18 @@ + +## @media + + The `@media` works just as it does within regular css, however with Stylus block notation: + + @media print + #header + #footer + display none + +yielding: + + @media print { + #header, + #footer { + display: none; + } + } diff --git a/node_modules/stylus/docs/middleware.md b/node_modules/stylus/docs/middleware.md new file mode 100644 index 0000000..b574727 --- /dev/null +++ b/node_modules/stylus/docs/middleware.md @@ -0,0 +1,73 @@ + +## Connect Middleware + + Stylus ships with Connect middleware for auto-compiling Stylus sheets when modified. + +## stylus.middleware(options) + + Return Connect middleware with the given `options`. + +#### Options + + `force` When __true__ styles will always re-compile + `src` Source directory used to find .styl files + `dest` Destination directory used to output .css files + when undefined defaults to `src`. + `compress` Whether the output .css files should be compressed + `compile` Custom compile function, accepting the arguments + `(str, path)` returning the renderer. + `firebug` Emits debug infos in the generated css that can + be used by the FireStylus Firebug plugin + `linenos` Emits comments in the generated css indicating + the corresponding stylus line + +#### Examples + + Here we set up the custom compile function so that we may + alter the renderer by providing additional settings. + + By default the compile function simply sets the `filename` + and renders the CSS. + + function compile(str, path) { + return stylus(str) + .import(__dirname + '/css/mixins/blueprint') + .import(__dirname + '/css/mixins/css3') + .set('filename', path) + .set('warn', true) + .set('compress', true); + } + + Pass the middleware to Connect, grabbing .styl files from this directory + and saving .css files to _./public_. Also supplying our custom `compile` function. + + Following that we have a `staticProvider` layer setup to serve the .css + files generated by Stylus. + + var stylus = require('stylus'); + + var server = connect.createServer( + stylus.middleware({ + src: __dirname + , dest: __dirname + '/public' + , compile: compile + }) + , connect.staticProvider(__dirname + '/public') + ); + + When `force` is used, the styles will be unconditionally re-compiled, however + even without this option the Stylus middleware is smart enough to detect changes in `@import`ed files. + + For development purpose, you can enable the `firebug` option if you want to + use the [FireStylus extension for Firebug](//github.com/LearnBoost/stylus/blob/master/docs/firebug.md) + and/or the `linenos` option to emit debug infos in the generated css. + + function compile(str, path) { + return stylus(str) + .import(__dirname + '/css/mixins/blueprint') + .import(__dirname + '/css/mixins/css3') + .set('filename', path) + .set('warn', true) + .set('firebug', true) + .set('linenos', true); + } diff --git a/node_modules/stylus/docs/mixins.md b/node_modules/stylus/docs/mixins.md new file mode 100644 index 0000000..0280272 --- /dev/null +++ b/node_modules/stylus/docs/mixins.md @@ -0,0 +1,130 @@ + +## Mixins + +Both mixins and functions are defined in the same manor, however they are applied in different ways. For example we have a `border-radius(n)` function defined below, which is invoked as a _mixin_, aka a statement rather than part of an expression. + +When `border-radius()` is invoked within a selector, the properties are expanded and copied into the selector. + + border-radius(n) + -webkit-border-radius n + -moz-border-radius n + border-radius n + + form input[type=button] + border-radius(5px) + +compiles to: + + form input[type=button] { + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + border-radius: 5px; + } + +When utilizing mixins, we can omit the parens all together, providing is with fantastic transparent vendor property support: + + border-radius(n) + -webkit-border-radius n + -moz-border-radius n + border-radius n + + form input[type=button] + border-radius 5px + +Note that the `border-radius` within our mixin is treated as a property, and not a recursive function invocation. To take this further we we may utilize the automatic `arguments` local variable, containing the expression passed, allowing more than one value to be passed: + + border-radius() + -webkit-border-radius arguments + -moz-border-radius arguments + border-radius arguments + +now allowing us to pass values such as `border-radius 1px 2px / 3px 4px`. + +Another great example of this, is adding transparent support for vendor specifics such as `opacity` support for IE: + + support-for-ie ?= true + + opacity(n) + opacity n + if support-for-ie + filter unquote('progid:DXImageTransform.Microsoft.Alpha(Opacity=' + round(n * 100) + ')') + + #logo + &:hover + opacity 0.5 + +rendering: + + #logo:hover { + opacity: 0.5; + filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=50); + } + +### Parent References + + Mixins may utilize the parent reference character `&`, acting on the parent instead of further nesting. For example lets say we wish to create a `stripe(even, odd)` mixin for striping table row, we provide both `even` and `odd` with default color values, and assign the `background-color` property on the row. Nested within the `tr` we use `&` to reference the `tr`, providing the `even` color. + + stripe(even = #fff, odd = #eee) + tr + background-color odd + &.even + &:nth-child(even) + background-color even + +We may then utilize the mixin as shown below: + + table + stripe() + td + padding 4px 10px + + table#users + stripe(#303030, #494848) + td + color white + +Another way to define the `stripe()` mixin without parent reference: + + stripe(even = #fff, odd = #eee) + tr + background-color odd + tr.even + tr:nth-child(even) + background-color even + +If we wished, we could invoke `stripe()` as if it were a property: + + stripe #fff #000 + +### Mixing Mixins in Mixins + + Mixins can of course utilize other mixins, to build up their own selector's and properties. For example, below we create `comma-list()` to inline (via `inline-list()`) and comma-separate an un-ordered list. + + + inline-list() + li + display inline + + comma-list() + inline-list() + li + &:after + content ', ' + &:last-child:after + content '' + + ul + comma-list() + +rendering: + + ul li:after { + content: ", "; + } + ul li:last-child:after { + content: ""; + } + ul li { + display: inline; + } + diff --git a/node_modules/stylus/docs/operators.md b/node_modules/stylus/docs/operators.md new file mode 100644 index 0000000..e99c920 --- /dev/null +++ b/node_modules/stylus/docs/operators.md @@ -0,0 +1,451 @@ + +## Operator Precedence + +Below is the operator precedence table, highest to lowest: + + [] + ! ~ + - + is defined + ** * / % + + - + ... .. + <= >= < > + in + == is != is not isnt + is a + && and || or + ?: + = := ?= += -= *= /= %= + not + if unless + +## Unary Operators + +The following unary operators are available, `!`, `not`, `-`, `+`, and `~`. + + !0 + // => true + + !!0 + // => false + + !1 + // => false + + !!5px + // => true + + -5px + // => -5px + + --5px + // => 5px + + not true + // => false + + not not true + // => true + +The logical `not` operator has low precedence, therefore the following example could be replaced with + + a = 0 + b = 1 + + !a and !b + // => false + // pased as: (!a) and (!b) + +with: + + not a or b + // => false + // parsed as: not (a or b) + +## Binary Operators + +### Subscript [] + + The subscript operator allows us to grab a value in an expression via index. Parenthesized expressions may act as tuples, so for example `(15px 5px)`, `(1 2 3)`. + + Below is an example where we utilize tuples for error handling, showing the versatility of such a construct. As + + add(a, b) + if a is a 'unit' and b is a 'unit' + a + b + else + (error 'a and b must be units!') + + body + padding add(1,'5') + // => padding: error "a and b must be units"; + + padding add(1,'5')[0] + // => padding: error; + + padding add(1,'5')[0] == error + // => padding: true; + + padding add(1,'5')[1] + // => padding: "a and b must be units"; + + A more complex example, invoking the `error()` built-in function with the error message returned, when the ident (the first value) equals `error`. + + + if (val = add(1,'5'))[0] == error + error(val[1]) + +## Range .. ... + + Both the inclusive (`..`) and exclusive (`...`) range operators are provided, expanding to expressions: + + 1..5 + // => 1 2 3 4 5 + + 1...5 + // => 1 2 3 4 + +### Additive: + - + +multiplicative and additive binary operators work as expected, and type conversion is applied within unit type classes, or default to the literal value. For example if we perform `5s - 2px` we will get `3s`. + + 15px - 5px + // => 10px + + 5 - 2 + // => 3 + + 5in - 50mm + // => 3.031in + + 5s - 1000ms + // => 4s + + 20mm + 4in + // => 121.6mm + + "foo " + "bar" + // => "foo bar" + + "num " + 15 + // => "num 15" + +### Multiplicative: / * % + + 2000ms + (1s * 2) + // => 4ms + + 5s / 2 + // => 2.5s + + 4 % 2 + // => 0 + +When using `/` within a property value you must wrap with parens. The following for example is taken literally, to support css line-height: + + font: 14px/1.5; + +whereas the following is evaluated, dividing `14px` by `1.5`: + + font: (14px/1.5); + +this exception is _only_ required for the `/` operator. + +### Exponent: ** + +The Exponent operator: + + 2 ** 8 + // => 256 + +### Equality & Relational: == != >= <= > < + +Equality operators can be used to equate units, colors, strings, and even identifiers. This is a powerful concept, as even arbitrary identifiers such as as `wahoo` can be utilized as atoms, a function could return `yes` or `no` instead of `true` or `false` (although not advised). + + 5 == 5 + // => true + + 10 > 5 + // => true + + #fff == #fff + // => true + + true == false + // => false + + wahoo == yay + // => false + + wahoo == wahoo + // => true + + "test" == "test" + // => true + + true is true + // => true + + 'hey' is not 'bye' + // => true + + 'hey' isnt 'bye' + // => true + + (foo bar) == (foo bar) + // => true + + (1 2 3) == (1 2 3) + // => true + + (1 2 3) == (1 1 3) + // => false + +Only exact values match, for example `0 == false`, and `null == false` are both `false`. + +Aliases: + + == is + != is not + != isnt + +## Truthfulness + + Nearly everything within Stylus resolves to `true`, including units with a suffix, for example even `0%`, `0px`, etc will resolve to `true`, since commonly in Stylus a mixin or function may accept such units as valid, however `0` itself is `false` in terms of arithmetic. + +`true` examples: + + 0% + 0px + 1px + -1 + -1px + hey + 'hey' + (0px 0px 0px) + +`false` examples: + + 0 + null + false + '' + (0 0 0) + +### Logical Operators: && || and or + +Logical operators `&&` and `||` are aliased `and` / `or` which apply the same precedence. + + 5 && 3 + // => 3 + + 0 || 5 + // => 5 + + 0 && 5 + // => 0 + + #fff is a 'rgba' and 15 is a 'unit' + // => true + +### Existence Operator: in + + Checks for the existence of the _left-hand_ operand within the _right-hand_ expression. + +Simple examples: + + nums = 1 2 3 + 1 in nums + // => true + + 5 in nums + // => false + +Some undefined identifiers: + + words = foo bar baz + bar in words + // => true + + HEY in words + // => false + +Works with tuples too: + + vals = (error 'one') (error 'two') + error in vals + // => false + + (error 'one') in vals + // => true + + (error 'two') in vals + // => true + + (error 'something') in vals + // => false + +Example usage in mixin: + + pad(types = padding, n = 5px) + if padding in types + padding n + if margin in types + margin n + + body + pad() + + body + pad(margin) + + body + pad(padding margin, 10px) + +yielding: + + body { + padding: 5px; + } + body { + margin: 5px; + } + body { + padding: 10px; + margin: 10px; + } + +### Conditional Assignment: ?= := + +The conditional assignment operator `?=` (aliased as `:=`) lets us define variables without clobbering old values (when present). This operator expands to an `is defined` binary operation within a ternary, for example the following are equivalent: + + color := white + color ?= white + color = color is defined ? color : white + +For example when using `=` we simply re-assign: + + color = white + color = black + + color + // => black + +However when using `?=` our second attempt fails since the variable is already defined: + + color = white + color ?= black + + color + // => white + +### Instance Check: is a + +Stylus provides a binary operator named `is a` used to type check. + + 15 is a 'unit' + // => true + + #fff is a 'rgba' + // => true + + 15 is a 'rgba' + // => false + +Alternatively we could use the `type()` BIF: + + type(#fff) == 'rgba' + // => true + +'color' is the one special-case, evaluating to true when the +left-hand operand is an `RGBA` or `HSLA` node. + +### Variable Definition: is defined + +This pseudo binary operator does not accept a right-hand operator, and does _not_ evaluate the left. This allows us to check if a variable has a value assigned to it. + + foo is defined + // => false + + foo = 15px + foo is defined + // => true + + #fff is defined + // => 'invalid "is defined" check on non-variable #fff' + +Alternatively one can use the `lookup(name)` built-in function to do this, or to perform dynamic lookups: + + name = 'blue' + lookup('light-' + name) + // => null + + light-blue = #80e2e9 + lookup('light-' + name) + // => #80e2e9 + +This operator is essential, as an undefined identifier is still a truthy value. For example: + + body + if ohnoes + padding 5px + +_will_ yield the following css when undefined: + + body { + padding: 5px; + } + +however this will be safe: + + body + if ohnoes is defined + padding 5px + +## Ternary + +The ternary operator works as we would expect in most languages, being the only operator with three operands, the _condition_ expression, the _truth_ expression and the _false_ expression. + + num = 15 + num ? unit(num, 'px') : 20px + // => 15px + +## Color Operations + + Operations on colors provide a terse, expressive way to alter components. For example we can operate on each RGB: + + #0e0 + #0e0 + // => #0f0 + + Another example is adjust the lightness value by adding or subtracting a percentage. To lighten a color we add, to darken we subtract. + + #888 + 50% + // => #c3c3c3 + + #888 - 50% + // => #444 + + Adjust the hue is also possible by adding or subtracting with degrees, for example adding `50deg` to this red value, resulting in a yellow: + + #f00 + 50deg + // => #ffd500 + + Values clamp appropriately, for example we can "spin" the hue 180 degrees, and if the current value is `320deg`, it will resolve to `140deg`. + + We may also tweak several values at once, including the alpha by using `rgb()`, `rgba()`, `hsl()`, or `hsla()`: + + #f00 - rgba(100,0,0,0.5) + // => rgba(155,0,0,0.5) + +## Sprintf + + The string sprintf-like operator `%` can be used to generate a literal value, internally passing arguments through the `s()` built-in: + + 'X::Microsoft::Crap(%s)' % #fc0 + // => X::Microsoft::Crap(#fc0) + + Multiple values should be parenthesized: + + '-webkit-gradient(%s, %s, %s)' % (linear (0 0) (0 100%)) + // => -webkit-gradient(linear, 0 0, 0 100%) + diff --git a/node_modules/stylus/docs/selectors.md b/node_modules/stylus/docs/selectors.md new file mode 100644 index 0000000..d23310d --- /dev/null +++ b/node_modules/stylus/docs/selectors.md @@ -0,0 +1,131 @@ +## Selectors + +### Indentation + +Stylus is "pythonic" aka indentation-based. Whitespace is significant, so we substitute { and } with an _indent_, and an _outdent_ as shown below: + + body + color white + +which compiles to: + + body { + color: #fff; + } + +Optionally if preferred we may utilize colons to separate properties and their values: + + body + color: white + +### Rule Sets + +Stylus, just like css allows you to define properties for several selectors at once through comma separation. + + textarea, input + border 1px solid #eee + +The same can be done with a newline: + + textarea + input + border 1px solid #eee + +both compiling to: + + textarea, + input { + border: 1px solid #eee; + } + +The one exception to this rule, are selectors that look like properties, for example `foo bar baz` in the following may be a property, or a selector: + + foo bar baz + > input + border 1px solid + +so for this reason, or if simply preferred we may trail with a comma: + + foo bar baz, + form input, + > a + border 1px solid + +### Parent Reference + +The `&` character references the parent selector(s). In the example below our two selectors `textarea`, and `input` both alter the `color` on the `:hover` pseudo selector. + + textarea + input + color #A7A7A7 + &:hover + color #000 + +compiles to: + + textarea, + input { + color: #a7a7a7; + } + textarea:hover, + input:hover { + color: #000; + } + +below is an example providing a simple `2px` border for internet exploder utilizing the parent reference within a mixin: + + box-shadow() + -webkit-box-shadow arguments + -moz-box-shadow arguments + box-shadow arguments + html.ie8 &, + html.ie7 &, + html.ie6 & + border 2px solid arguments[length(arguments) - 1] + + body + #login + box-shadow 1px 1px 3px #eee + +yielding: + + body #login { + -webkit-box-shadow: 1px 1px 3px #eee; + -moz-box-shadow: 1px 1px 3px #eee; + box-shadow: 1px 1px 3px #eee; + } + html.ie8 body #login, + html.ie7 body #login, + html.ie6 body #login { + border: 2px solid #eee; + } + +### Disambiguation + +Expressions such as `padding - n` could be interpreted both as a subtraction operation, as well as a property with an unary minus. To disambiguate we can wrap the expression with parens: + + pad(n) + padding (- n) + + body + pad(5px) + +compiles to: + + body { + padding: -5px; + } + +however this is only true in functions, since functions act both as mixins, or calls with return values. For example this is fine, and will yield the same results as above: + + body + padding -5px + +Have weird property values that Stylus cannot process? `unquote()` can help you out: + + filter unquote('progid:DXImageTransform.Microsoft.BasicImage(rotation=1)') + +yields: + + filter progid:DXImageTransform.Microsoft.BasicImage(rotation=1) + \ No newline at end of file diff --git a/node_modules/stylus/docs/textmate.md b/node_modules/stylus/docs/textmate.md new file mode 100644 index 0000000..6e8b357 --- /dev/null +++ b/node_modules/stylus/docs/textmate.md @@ -0,0 +1,4 @@ + +## TextMate Bundle + + Stylus ships with a TextMate bundle, located within `./editors`. To install simply execute `make install-bundle`, or place `./editors/Stylus.tmbundle` in the appropriate location. \ No newline at end of file diff --git a/node_modules/stylus/docs/vargs.md b/node_modules/stylus/docs/vargs.md new file mode 100644 index 0000000..fba09cb --- /dev/null +++ b/node_modules/stylus/docs/vargs.md @@ -0,0 +1,84 @@ + +## Rest Parameters + + Stylus supports rest parameters in the form of `name...`. These params consume the remaining arguments passed to a mixin or function. This is useful for example when utilizing the implicit function call support to apply vendor prefixes like `-webkit` or `-moz`. + + +In the example below we consume all the arguments passed and simply apply them to multiple properties. + + box-shadow(args...) + -webkit-box-shadow args + -moz-box-shadow args + box-shadow args + + #login + box-shadow 1px 2px 5px #eee + +yielding: + + #login { + -webkit-box-shadow: 1px 2px 5px #eee; + -moz-box-shadow: 1px 2px 5px #eee; + box-shadow: 1px 2px 5px #eee; + } + +If we wanted to peek at a specific argument, for example the x-offset we could simply use `args[0]`, or for example we may wish to re-define the mixin: + + box-shadow(offset-x, args...) + got-offset-x offset-x + -webkit-box-shadow offset-x args + -moz-box-shadow offset-x args + box-shadow offset-x args + + #login + box-shadow 1px 2px 5px #eee + +yielding: + + #login { + got-offset-x: 1px; + -webkit-box-shadow: 1px 2px 5px #eee; + -moz-box-shadow: 1px 2px 5px #eee; + box-shadow: 1px 2px 5px #eee; + } + +### arguments + + The `arguments` variable is injected into mixin and function bodies, containing the exact expression passed. This is useful for several reasons, primarily for vendor support, as you get the _exact_ expression, commas and all. + + For example, if we use a rest param, the comma is simply consumed since it is an expression delimiter: + + box-shadow(args...) + -webkit-box-shadow args + -moz-box-shadow args + box-shadow args + + #login + box-shadow #ddd 1px 1px, #eee 2px 2px + +yielding slightly unexpected results: + + #login { + -webkit-box-shadow: #ddd 1px 1px #eee 2px 2px; + -moz-box-shadow: #ddd 1px 1px #eee 2px 2px; + box-shadow: #ddd 1px 1px #eee 2px 2px; + } + +Let's redefine the mixin using `arguments`: + + box-shadow() + -webkit-box-shadow arguments + -moz-box-shadow arguments + box-shadow arguments + + body + box-shadow #ddd 1px 1px, #eee 2px 2px + +now yielding the desired result: + + body { + -webkit-box-shadow: #ddd 1px 1px, #eee 2px 2px; + -moz-box-shadow: #ddd 1px 1px, #eee 2px 2px; + box-shadow: #ddd 1px 1px, #eee 2px 2px; + } + diff --git a/node_modules/stylus/docs/variables.md b/node_modules/stylus/docs/variables.md new file mode 100644 index 0000000..f71837e --- /dev/null +++ b/node_modules/stylus/docs/variables.md @@ -0,0 +1,85 @@ + +## Variables + +We may assign expressions to variables and use them throughout our stylesheet: + + font-size = 14px + + body + font font-size Arial, sans-serif + +compiles to: + + body { + font: 14px Arial, sans-serif; + } + +Variables can even consist of an expression list: + + font-size = 14px + font = font-size "Lucida Grande", Arial + + body + font font sans-serif + +compiles to: + + body { + font: 14px "Lucida Grande", Arial sans-serif; + } + +identifiers (variable names, functions, etc) may also include the `$` character, for example: + + $font-size = 14px + body { + font: $font sans-serif; + } + +## Property Lookup + + Another cool feature unique to Stylus is the ability to reference + properties defined _without_ assigning their values to variables. A great example of this is the logic required for vertically and horizontally center an element, which is typically done by using percentages and negative margins as shown: + + #logo + position: absolute + top: 50% + left: 50% + width: w = 150px + height: h = 80px + margin-left: -(w / 2) + margin-top: -(h / 2) + + Instead of assigning the variables `w` and `h` we can simply prepend the `@` + character to the property name to access the value: + + #logo + position: absolute + top: 50% + left: 50% + width: 150px + height: 80px + margin-left: -(@width / 2) + margin-top: -(@height / 2) + + Another useful use-case is conditionally defining properties based on the existence of others within mixins. In the following example we apply a default `z-index` of `1`, but _only_ if `z-index` was not previously specified. + + position() + position: arguments + z-index: 1 unless @z-index + + #logo + z-index: 20 + position: absolute + + #logo2 + position: absolute + + Property lookup will "bubble" up the stack until found, or return `null` if the property cannot be resolved. In the following example `@color` will resolve to `blue`. + + body + color: red + ul + li + color: blue + a + background-color: @color \ No newline at end of file diff --git a/node_modules/stylus/editors/Stylus.tmbundle/Commands/Compile and Display CSS.tmCommand b/node_modules/stylus/editors/Stylus.tmbundle/Commands/Compile and Display CSS.tmCommand new file mode 100644 index 0000000..b245ce6 --- /dev/null +++ b/node_modules/stylus/editors/Stylus.tmbundle/Commands/Compile and Display CSS.tmCommand @@ -0,0 +1,33 @@ + + + + + beforeRunningCommand + nop + command + #!/bin/bash + +function highlight { + test `which pygmentize` + if [[ $? -eq 0 ]]; then + pygmentize -Onoclasses,nobackground=True -l css -f html + else + pre + fi +} + +${TM_STYLUS:=stylus} | highlight + input + selection + keyEquivalent + @b + name + Compile and Display CSS + output + showAsHTML + scope + source.stylus + uuid + DD8F8C2B-2B83-4734-82EE-8508EE344638 + + diff --git a/node_modules/stylus/editors/Stylus.tmbundle/Preferences/Comments.tmPreferences b/node_modules/stylus/editors/Stylus.tmbundle/Preferences/Comments.tmPreferences new file mode 100644 index 0000000..d19c68f --- /dev/null +++ b/node_modules/stylus/editors/Stylus.tmbundle/Preferences/Comments.tmPreferences @@ -0,0 +1,36 @@ + + + + + name + Comments + scope + source.stylus + settings + + shellVariables + + + name + TM_COMMENT_START + value + // + + + name + TM_COMMENT_START_2 + value + /* + + + name + TM_COMMENT_END_2 + value + */ + + + + uuid + 7EC85265-178C-4ECC-AAE2-4EEF4AFF8872 + + diff --git a/node_modules/stylus/editors/Stylus.tmbundle/Syntaxes/Stylus.tmLanguage b/node_modules/stylus/editors/Stylus.tmbundle/Syntaxes/Stylus.tmLanguage new file mode 100644 index 0000000..749ee49 --- /dev/null +++ b/node_modules/stylus/editors/Stylus.tmbundle/Syntaxes/Stylus.tmLanguage @@ -0,0 +1,166 @@ + + + + + fileTypes + + styl + stylus + + name + Stylus + patterns + + + match + ^ *(&|) + name + variable.language.stylus + + + match + (arguments) + name + variable.language.stylus + + + match + @([-\w]+) + name + keyword.stylus + + + captures + + 1 + + name + punctuation.definition.entity.stylus + + + match + (\.)[a-zA-Z0-9_-]+ + name + entity.other.attribute-name.class.stylus + + + captures + + 1 + + name + punctuation.definition.entity.stylus + + + match + (:+)\b(after|before|first-child|first-letter|first-line|selection)\b + name + entity.other.attribute-name.pseudo-element.stylus + + + captures + + 1 + + name + punctuation.definition.entity.stylus + + + match + (:)\b(active|hover|link|visited|focus)\b + name + entity.other.attribute-name.pseudo-class.stylus + + + captures + + 1 + + name + punctuation.definition.entity.css + + + match + (#)[a-zA-Z][a-zA-Z0-9_-]* + name + entity.other.attribute-name.id.stylus + + + match + \b(!important|for|in|return|true|false|null|if|else|unless|return)\b + name + keyword.control.stylus + + + begin + " + end + " + name + string.quoted.double.stylus + + + begin + ' + end + ' + name + string.quoted.single.stylus + + + begin + /\* + captures + + 0 + + name + punctuation.definition.comment.js + + + end + \*/ + name + comment.block.js + + + match + (?:\b(\d+))|(#[a-fA-F0-9]+) + name + constant.numeric.stylus + + + captures + + 1 + + name + punctuation.definition.comment.stylus + + + match + (?:^[ \t]+)?(\/\/).*$\n? + name + comment.line.stylus + + + captures + + 1 + + name + entity.name.function.stylus + + + match + ([-a-zA-Z_][-\w]*)?(\() + name + meta.function.stylus + + + scopeName + source.stylus + uuid + 60519324-6A3A-4382-9E0B-546993A3869A + + diff --git a/node_modules/stylus/editors/Stylus.tmbundle/info.plist b/node_modules/stylus/editors/Stylus.tmbundle/info.plist new file mode 100644 index 0000000..e0e962b --- /dev/null +++ b/node_modules/stylus/editors/Stylus.tmbundle/info.plist @@ -0,0 +1,10 @@ + + + + + name + Stylus + uuid + DD7889E4-2ACA-4DF5-838F-FC9D7AEAF3F1 + + diff --git a/node_modules/stylus/editors/gedit/styl.lang b/node_modules/stylus/editors/gedit/styl.lang new file mode 100644 index 0000000..d99ea6c --- /dev/null +++ b/node_modules/stylus/editors/gedit/styl.lang @@ -0,0 +1,475 @@ + + + + + + text/x-styl + *.styl + // + /* + */ + + + +