formal (empty) → 0.1.0
raw patch · 86 files changed
+19206/−0 lines, 86 filesdep +HTTPdep +MissingHdep +ansi-terminalsetup-changed
Dependencies added: HTTP, MissingH, ansi-terminal, base, bytestring, containers, directory, file-embed, indents, interpolatedstring-perl6, jmacro, mtl, network, pandoc, parsec, process, text, transformers, urlencoded, wl-pprint-text
Files
- LICENSE +30/−0
- Setup.hs +2/−0
- formal.cabal +129/−0
- lib/base.css +266/−0
- lib/default.css +83/−0
- lib/jasmine-node/LICENSE +22/−0
- lib/jasmine-node/README.md +83/−0
- lib/jasmine-node/bin/jasmine-node +7/−0
- lib/jasmine-node/lib/jasmine-node/async-callback.js +54/−0
- lib/jasmine-node/lib/jasmine-node/autotest.js +90/−0
- lib/jasmine-node/lib/jasmine-node/cli.js +176/−0
- lib/jasmine-node/lib/jasmine-node/index.js +148/−0
- lib/jasmine-node/lib/jasmine-node/jasmine-2.0.0.rc1.js +2479/−0
- lib/jasmine-node/lib/jasmine-node/reporter.js +275/−0
- lib/jasmine-node/lib/jasmine-node/requirejs-runner.js +80/−0
- lib/jasmine-node/lib/jasmine-node/requirejs-spec-loader.js +48/−0
- lib/jasmine-node/lib/jasmine-node/requirejs-wrapper-template.js +65/−0
- lib/jasmine-node/lib/jasmine-node/spec-collection.js +35/−0
- lib/jasmine-node/package.json +29/−0
- lib/jasmine-node/scripts/specs +37/−0
- lib/jasmine-node/spec-requirejs/requirejs.spec.js +8/−0
- lib/jasmine-node/spec-requirejs/requirejs.sut.js +8/−0
- lib/jasmine-node/spec/AsyncSpec.coffee +7/−0
- lib/jasmine-node/spec/CoffeeSpec.coffee +4/−0
- lib/jasmine-node/spec/GrammarHelper.coffee +22/−0
- lib/jasmine-node/spec/HelperSpec.coffee +6/−0
- lib/jasmine-node/spec/SampleSpecs.js +25/−0
- lib/jasmine-node/spec/TestSpec.js +5/−0
- lib/jasmine-node/spec/async-callback_spec.js +150/−0
- lib/jasmine-node/spec/helper_spec.js +7/−0
- lib/jasmine-node/spec/nested.js/NestedSpec.js +5/−0
- lib/jasmine-node/spec/nested/NestedSpec.js +5/−0
- lib/jasmine-node/spec/nested/uber-nested/UberNestedSpec.js +11/−0
- lib/jasmine-node/spec/reporter_spec.js +432/−0
- lib/jasmine-node/spec/sample_helper.js +19/−0
- lib/jasmine-node/specs.sh +24/−0
- lib/js/coda.css +25/−0
- lib/js/console.js +179/−0
- lib/js/jasmine-1.0.1/MIT.LICENSE +20/−0
- lib/js/jasmine-1.0.1/jasmine-html.js +10/−0
- lib/js/jasmine-1.0.1/jasmine.css +171/−0
- lib/js/jasmine-1.0.1/jasmine.js +77/−0
- lib/js/jquery.js +16/−0
- lib/js/lang-hs.js +102/−0
- lib/js/prettify.css +1/−0
- lib/js/prettify.js +28/−0
- lib/js/underscore.js +26/−0
- lib/js/zepto.js +1/−0
- lib/layout.css +58/−0
- lib/skeleton.css +242/−0
- src/formal/bug.formal +13/−0
- src/formal/bugb.formal +19/−0
- src/formal/formalz.formal +88/−0
- src/formal/parsec.formal +172/−0
- src/formal/prelude.formal +802/−0
- src/formal/prelude.html +4474/−0
- src/formal/prelude.js +1166/−0
- src/formal/prelude.spec.js +2095/−0
- src/formal/temp.js +0/−0
- src/formal/tests.formal +145/−0
- src/formal/underscore.formal +29/−0
- src/hs/Formal/CLI.hs +111/−0
- src/hs/Formal/Closure.hs +68/−0
- src/hs/Formal/Javascript.hs +91/−0
- src/hs/Formal/Javascript/Backend.hs +61/−0
- src/hs/Formal/Javascript/Utils.hs +99/−0
- src/hs/Formal/Optimize.hs +330/−0
- src/hs/Formal/Parser.hs +114/−0
- src/hs/Formal/Parser/Utils.hs +210/−0
- src/hs/Formal/TypeCheck.hs +570/−0
- src/hs/Formal/TypeCheck/Types.hs +671/−0
- src/hs/Formal/Types/Axiom.hs +98/−0
- src/hs/Formal/Types/Definition.hs +153/−0
- src/hs/Formal/Types/Expression.hs +531/−0
- src/hs/Formal/Types/Literal.hs +37/−0
- src/hs/Formal/Types/Namespace.hs +54/−0
- src/hs/Formal/Types/Pattern.hs +256/−0
- src/hs/Formal/Types/Statement.hs +301/−0
- src/hs/Formal/Types/Symbol.hs +35/−0
- src/hs/Formal/Types/Type.hs +171/−0
- src/hs/Formal/Types/TypeDefinition.hs +37/−0
- src/hs/Main.hs +200/−0
- src/html/footer.html +7/−0
- src/html/header.html +55/−0
- src/js/FormalReporter.js +79/−0
- src/js/table_of_contents.js +32/−0
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright (c)2011, Andrew Stein++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++ * Redistributions of source code must retain the above copyright+ notice, this list of conditions and the following disclaimer.++ * Redistributions in binary form must reproduce the above+ copyright notice, this list of conditions and the following+ disclaimer in the documentation and/or other materials provided+ with the distribution.++ * Neither the name of Andrew Stein nor the names of other+ contributors may be used to endorse or promote products derived+ from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ formal.cabal view
@@ -0,0 +1,129 @@+Name: formal+Version: 0.1.0+Synopsis: A statically typed, functional programming language +License: MIT+Author: Andrew Stein+Maintainer: steinlink@gmail.com+Stability: Experimental+Category: Compiler+Build-type: Simple+Cabal-version: >=1.4+data-files: + lib/jasmine-node/bin/jasmine-node, + lib/jasmine-node/lib/jasmine-node/async-callback.js, + lib/jasmine-node/lib/jasmine-node/autotest.js, + lib/jasmine-node/lib/jasmine-node/cli.js, + lib/jasmine-node/lib/jasmine-node/index.js, + lib/jasmine-node/lib/jasmine-node/jasmine-2.0.0.rc1.js, + lib/jasmine-node/lib/jasmine-node/reporter.js, + lib/jasmine-node/lib/jasmine-node/requirejs-runner.js, + lib/jasmine-node/lib/jasmine-node/requirejs-spec-loader.js, + lib/jasmine-node/lib/jasmine-node/requirejs-wrapper-template.js, + lib/jasmine-node/lib/jasmine-node/spec-collection.js, + lib/jasmine-node/scripts/specs, + lib/jasmine-node/spec/nested/uber-nested/UberNestedSpec.js, + lib/jasmine-node/spec/nested/NestedSpec.js, + lib/jasmine-node/spec/nested.js/NestedSpec.js, + lib/jasmine-node/spec/async-callback_spec.js, + lib/jasmine-node/spec/AsyncSpec.coffee, + lib/jasmine-node/spec/CoffeeSpec.coffee, + lib/jasmine-node/spec/GrammarHelper.coffee, + lib/jasmine-node/spec/helper_spec.js, + lib/jasmine-node/spec/HelperSpec.coffee, + lib/jasmine-node/spec/reporter_spec.js, + lib/jasmine-node/spec/sample_helper.js, + lib/jasmine-node/spec/SampleSpecs.js, + lib/jasmine-node/spec/TestSpec.js, + lib/jasmine-node/spec-requirejs/requirejs.spec.js, + lib/jasmine-node/spec-requirejs/requirejs.sut.js, + lib/jasmine-node/LICENSE, + lib/jasmine-node/package.json, + lib/jasmine-node/README.md, + lib/jasmine-node/specs.sh, + lib/js/jasmine-1.0.1/jasmine-html.js, + lib/js/jasmine-1.0.1/jasmine.css, + lib/js/jasmine-1.0.1/jasmine.js, + lib/js/jasmine-1.0.1/MIT.LICENSE, + lib/js/coda.css, + lib/js/console.js, + lib/js/jquery.js, + lib/js/lang-hs.js, + lib/js/prettify.css, + lib/js/prettify.js, + lib/js/underscore.js, + lib/js/zepto.js, + lib/base.css, + lib/default.css, + lib/layout.css, + lib/skeleton.css, + src/formal/bug.formal, + src/formal/bugb.formal, + src/formal/formalz.formal, + src/formal/parsec.formal, + src/formal/prelude.formal, + src/formal/prelude.html, + src/formal/prelude.js, + src/formal/prelude.spec.js, + src/formal/temp.js, + src/formal/tests.formal, + src/formal/underscore.formal, + src/html/footer.html, + src/html/header.html, + src/js/FormalReporter.js, + src/js/table_of_contents.js, + LICENSE++Executable formal+ hs-source-dirs: src/hs+ main-is: Main.hs++ Build-depends:+ base >= 4 && <= 5, + bytestring >= 0.9.1 && <0.10,+ parsec,+ indents,+ containers,+ pandoc,+ jmacro,+ MissingH,+ interpolatedstring-perl6,+ transformers,+ mtl,+ text,+ wl-pprint-text,+ ansi-terminal,+ HTTP,+ network,+ urlencoded,+ file-embed,+ process,+ directory+ + if impl(ghc >= 6.12.0)+ ghc-options: -Wall -fwarn-tabs -funbox-strict-fields -O2+ -fno-warn-unused-do-bind -threaded+ -funfolding-use-threshold=16 -fexcess-precision+ -optc-O3 -optc-ffast-math+ else+ ghc-options: -Wall -fwarn-tabs -funbox-strict-fields -O2+ other-modules: + Formal.Javascript,+ Formal.Javascript.Backend,+ Formal.Javascript.Utils,+ Formal.Optimize,+ Formal.Parser,+ Formal.Parser.Utils,+ Formal.TypeCheck,+ Formal.TypeCheck.Types,+ Formal.Types.Axiom,+ Formal.Types.Definition,+ Formal.Types.Expression,+ Formal.Types.Literal,+ Formal.Types.Namespace,+ Formal.Types.Pattern,+ Formal.Types.Statement,+ Formal.Types.Symbol,+ Formal.Types.Type,+ Formal.Types.TypeDefinition,+ Formal.Closure,+ Formal.CLI
+ lib/base.css view
@@ -0,0 +1,266 @@+/*+* Skeleton V1.2+* Copyright 2011, Dave Gamache+* www.getskeleton.com+* Free to use under the MIT license.+* http://www.opensource.org/licenses/mit-license.php+* 6/20/2012+*/+++/* Table of Content+==================================================+ #Reset & Basics+ #Basic Styles+ #Site Styles+ #Typography+ #Links+ #Lists+ #Images+ #Buttons+ #Forms+ #Misc */+++/* #Reset & Basics (Inspired by E. Meyers)+================================================== */+ html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, canvas, details, embed, figure, figcaption, footer, header, hgroup, menu, nav, output, ruby, section, summary, time, mark, audio, video {+ margin: 0;+ padding: 0;+ border: 0;+ font-size: 100%;+ font: inherit;+ vertical-align: baseline; }+ article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section {+ display: block; }+ body {+ line-height: 1; }+ blockquote, q {+ quotes: none; }+ blockquote:before, blockquote:after,+ q:before, q:after {+ content: '';+ content: none; }+ table {+ border-collapse: collapse;+ border-spacing: 0; }+++/* #Basic Styles+================================================== */+ body {+ background: #fff;+ font: 14px/21px "HelveticaNeue", "Helvetica Neue", Helvetica, Arial, sans-serif;+ color: #444;+ -webkit-font-smoothing: antialiased; /* Fix for webkit rendering */+ -webkit-text-size-adjust: 100%;+ }+++/* #Typography+================================================== */+ h1, h2, h3, h4, h5, h6 {+ color: #181818;+ font-family: "Georgia", "Times New Roman", serif;+ font-weight: normal; }+ h1 a, h2 a, h3 a, h4 a, h5 a, h6 a { font-weight: inherit; }+ h1 { font-size: 46px; line-height: 50px; margin-bottom: 14px;}+ h2 { font-size: 35px; line-height: 40px; margin-bottom: 10px; }+ h3 { font-size: 28px; line-height: 34px; margin-bottom: 8px; }+ h4 { font-size: 21px; line-height: 30px; margin-bottom: 4px; }+ h5 { font-size: 17px; line-height: 24px; }+ h6 { font-size: 14px; line-height: 21px; }+ .subheader { color: #777; }++ p { margin: 0 0 20px 0; }+ p img { margin: 0; }+ p.lead { font-size: 21px; line-height: 27px; color: #777; }++ em { font-style: italic; }+ strong { font-weight: bold; color: #333; }+ small { font-size: 80%; }++/* Blockquotes */+ blockquote, blockquote p { font-size: 17px; line-height: 24px; color: #777; font-style: italic; }+ blockquote { margin: 0 0 20px; padding: 9px 20px 0 19px; border-left: 1px solid #ddd; }+ blockquote cite { display: block; font-size: 12px; color: #555; }+ blockquote cite:before { content: "\2014 \0020"; }+ blockquote cite a, blockquote cite a:visited, blockquote cite a:visited { color: #555; }++ hr { border: solid #ddd; border-width: 1px 0 0; clear: both; margin: 10px 0 30px; height: 0; }+++/* #Links+================================================== */+ a, a:visited { color: #333; text-decoration: underline; outline: 0; }+ a:hover, a:focus { color: #000; }+ p a, p a:visited { line-height: inherit; }+++/* #Lists+================================================== */+ ul, ol { margin-bottom: 20px; }+ ol { list-style: decimal; }+ ol, ul.square, ul.circle, ul.disc { margin-left: 30px; }+ ul.square { list-style: square outside; }+ ul.circle { list-style: circle outside; }+ ul.disc { list-style: disc outside; }+ ul ul, ul ol,+ ol ol, ol ul { margin: 4px 0 5px 30px; font-size: 90%; }+ ul ul li, ul ol li,+ ol ol li, ol ul li { margin-bottom: 6px; }+ li { line-height: 18px; margin-bottom: 12px; }+ ul.large li { line-height: 21px; }+ li p { line-height: 21px; }++/* #Images+================================================== */++ img.scale-with-grid {+ max-width: 100%;+ height: auto; }+++/* #Buttons+================================================== */++ .button,+ button,+ input[type="submit"],+ input[type="reset"],+ input[type="button"] {+ background: #eee; /* Old browsers */+ background: #eee -moz-linear-gradient(top, rgba(255,255,255,.2) 0%, rgba(0,0,0,.2) 100%); /* FF3.6+ */+ background: #eee -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(255,255,255,.2)), color-stop(100%,rgba(0,0,0,.2))); /* Chrome,Safari4+ */+ background: #eee -webkit-linear-gradient(top, rgba(255,255,255,.2) 0%,rgba(0,0,0,.2) 100%); /* Chrome10+,Safari5.1+ */+ background: #eee -o-linear-gradient(top, rgba(255,255,255,.2) 0%,rgba(0,0,0,.2) 100%); /* Opera11.10+ */+ background: #eee -ms-linear-gradient(top, rgba(255,255,255,.2) 0%,rgba(0,0,0,.2) 100%); /* IE10+ */+ background: #eee linear-gradient(top, rgba(255,255,255,.2) 0%,rgba(0,0,0,.2) 100%); /* W3C */+ border: 1px solid #aaa;+ border-top: 1px solid #ccc;+ border-left: 1px solid #ccc;+ -moz-border-radius: 3px;+ -webkit-border-radius: 3px;+ border-radius: 3px;+ color: #444;+ display: inline-block;+ font-size: 11px;+ font-weight: bold;+ text-decoration: none;+ text-shadow: 0 1px rgba(255, 255, 255, .75);+ cursor: pointer;+ margin-bottom: 20px;+ line-height: normal;+ padding: 8px 10px;+ font-family: "HelveticaNeue", "Helvetica Neue", Helvetica, Arial, sans-serif; }++ .button:hover,+ button:hover,+ input[type="submit"]:hover,+ input[type="reset"]:hover,+ input[type="button"]:hover {+ color: #222;+ background: #ddd; /* Old browsers */+ background: #ddd -moz-linear-gradient(top, rgba(255,255,255,.3) 0%, rgba(0,0,0,.3) 100%); /* FF3.6+ */+ background: #ddd -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(255,255,255,.3)), color-stop(100%,rgba(0,0,0,.3))); /* Chrome,Safari4+ */+ background: #ddd -webkit-linear-gradient(top, rgba(255,255,255,.3) 0%,rgba(0,0,0,.3) 100%); /* Chrome10+,Safari5.1+ */+ background: #ddd -o-linear-gradient(top, rgba(255,255,255,.3) 0%,rgba(0,0,0,.3) 100%); /* Opera11.10+ */+ background: #ddd -ms-linear-gradient(top, rgba(255,255,255,.3) 0%,rgba(0,0,0,.3) 100%); /* IE10+ */+ background: #ddd linear-gradient(top, rgba(255,255,255,.3) 0%,rgba(0,0,0,.3) 100%); /* W3C */+ border: 1px solid #888;+ border-top: 1px solid #aaa;+ border-left: 1px solid #aaa; }++ .button:active,+ button:active,+ input[type="submit"]:active,+ input[type="reset"]:active,+ input[type="button"]:active {+ border: 1px solid #666;+ background: #ccc; /* Old browsers */+ background: #ccc -moz-linear-gradient(top, rgba(255,255,255,.35) 0%, rgba(10,10,10,.4) 100%); /* FF3.6+ */+ background: #ccc -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(255,255,255,.35)), color-stop(100%,rgba(10,10,10,.4))); /* Chrome,Safari4+ */+ background: #ccc -webkit-linear-gradient(top, rgba(255,255,255,.35) 0%,rgba(10,10,10,.4) 100%); /* Chrome10+,Safari5.1+ */+ background: #ccc -o-linear-gradient(top, rgba(255,255,255,.35) 0%,rgba(10,10,10,.4) 100%); /* Opera11.10+ */+ background: #ccc -ms-linear-gradient(top, rgba(255,255,255,.35) 0%,rgba(10,10,10,.4) 100%); /* IE10+ */+ background: #ccc linear-gradient(top, rgba(255,255,255,.35) 0%,rgba(10,10,10,.4) 100%); /* W3C */ }++ .button.full-width,+ button.full-width,+ input[type="submit"].full-width,+ input[type="reset"].full-width,+ input[type="button"].full-width {+ width: 100%;+ padding-left: 0 !important;+ padding-right: 0 !important;+ text-align: center; }++ /* Fix for odd Mozilla border & padding issues */+ button::-moz-focus-inner,+ input::-moz-focus-inner {+ border: 0;+ padding: 0;+ }+++/* #Forms+================================================== */++ form {+ margin-bottom: 20px; }+ fieldset {+ margin-bottom: 20px; }+ input[type="text"],+ input[type="password"],+ input[type="email"],+ textarea,+ select {+ border: 1px solid #ccc;+ padding: 6px 4px;+ outline: none;+ -moz-border-radius: 2px;+ -webkit-border-radius: 2px;+ border-radius: 2px;+ font: 13px "HelveticaNeue", "Helvetica Neue", Helvetica, Arial, sans-serif;+ color: #777;+ margin: 0;+ width: 210px;+ max-width: 100%;+ display: block;+ margin-bottom: 20px;+ background: #fff; }+ select {+ padding: 0; }+ input[type="text"]:focus,+ input[type="password"]:focus,+ input[type="email"]:focus,+ textarea:focus {+ border: 1px solid #aaa;+ color: #444;+ -moz-box-shadow: 0 0 3px rgba(0,0,0,.2);+ -webkit-box-shadow: 0 0 3px rgba(0,0,0,.2);+ box-shadow: 0 0 3px rgba(0,0,0,.2); }+ textarea {+ min-height: 60px; }+ label,+ legend {+ display: block;+ font-weight: bold;+ font-size: 13px; }+ select {+ width: 220px; }+ input[type="checkbox"] {+ display: inline; }+ label span,+ legend span {+ font-weight: normal;+ font-size: 13px;+ color: #444; }++/* #Misc+================================================== */+ .remove-bottom { margin-bottom: 0 !important; }+ .half-bottom { margin-bottom: 10px !important; }+ .add-bottom { margin-bottom: 20px !important; }++
+ lib/default.css view
@@ -0,0 +1,83 @@+body {+ text-align: center; + margin: 5em 0 0 0; + vertical-align: middle;+ font-family: "Times New Roman", Times;+ font-size: 14px;+ line-height: 19px;+ color: #333;+} ++h1, h2, h3, h4 {+ display: block;+ text-align: center;+ padding: 20px 0px 10px 0;+ font-size: 14px;+ letter-spacing: 1px;+ font-variant: small-caps;+}++@media only screen and (max-width: 767px) {+ nav ul {+ display: none;+ }+}++@media only screen and (min-width: 767px) {+ nav { position: fixed; }++}+n+nav { text-align: left; }+h1 { font-size: 21px; }++nav h1 { text-align: left; }++.sidebar {+ height: 200px;+}+h2 + p:first-line {+}++p {+ hyphens: auto;+ text-align: justify;+}+++h2 + p:first-letter, body > div > :nth-child(2):first-letter {+ font-size: 24px;+ margin-top: -4px;+ margin-right: 2px;+ float: left;+}+body > div { + width: 760px; + text-align: left; + margin: 0 auto;+ }++pre { + padding: 15px 0 15px 25px;+ border-radius: 4px;+ border: 1px solid #ccc;+ white-space: pre-wrap;+ overflow: auto;+ line-height: 14px;+}+code {+ font-family: "Courier New";+ font-size: 12px;+}+p { margin-top: 20px; }++.jasmine_reporter label {+ display: inline;+ font-weight: normal;+}++a, a:visited {+ color: #333;+ color: #BA1820;+ text-decoration: none;+}
+ lib/jasmine-node/LICENSE view
@@ -0,0 +1,22 @@+The MIT License++Copyright (c) 2010 Adam Abrons and Misko Hevery http://getangular.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.+
+ lib/jasmine-node/README.md view
@@ -0,0 +1,83 @@+jasmine-node+======++[](http://travis-ci.org/spaghetticode/jasmine-node)++This node.js module makes the wonderful Pivotal Lab's jasmine+(http://github.com/pivotal/jasmine) spec framework available in+node.js.++install+------+ npm install jasmine-node -g++usage+------++Write the specifications for your code in *.js and *.coffee files in the+spec/ directory (note: your specification files must end with either+.spec.js or .spec.coffee; otherwise jasmine-node won't find them!). You+can use sub-directories to better organise your specs.++If you have installed the npm package, you can run it with:++ jasmine-node++If you aren't using npm, you should add `pwd`/lib to the $NODE_PATH+environment variable, then run:++ node lib/jasmine-node/cli.js+++You can supply the following arguments:++ * <code>--autotest</code>, provides automatic execution of specs after+ each changes+ * <code>--coffee</code>, allow execution of .coffee specs+ * <code>--color</code>, indicates spec output should uses color to+indicates passing (green) or failing (red) specs+ * <code>--noColor</code>, do not use color in the output+ * <code>--verbose</code>, verbose output as the specs are run+ * <code>--junitreport</code>, export tests results as junitreport xml format'++Checkout spec/SampleSpecs.js to see how to use it.++async tests+-----------++jasmine-node includes an alternate syntax for writing asynchronous tests. Accepting+a done callback in the specification will trigger jasmine-node to run the test+asynchronously waiting until the done() callback is called.++```javascript+ it("should respond with hello world", function(done) {+ request("http://localhost:3000/hello", function(error, response, body){+ expect(body).toEqual("hello world");+ done();+ });+ });+```++An asynchronous test will fail after 5000 ms if done() is not called. This timeout+can be changed by setting jasmine.DEFAULT_TIMEOUT_INTERVAL or by passing a timeout+interval in the specification.++ it("should respond with hello world", function(done) {+ request("http://localhost:3000/hello", function(error, response, body){+ done();+ }, 250); // timeout after 250 ms+ });++development+-----------+Install the dependent packages by running:++ npm install++Run the specs before you send your pull request:++ scripts/specs++or++ scripts/specs --verbose
+ lib/jasmine-node/bin/jasmine-node view
@@ -0,0 +1,7 @@+#!/usr/bin/env node++if( !process.env.NODE_ENV ) process.env.NODE_ENV = 'test';++var path = require('path');+var fs = require('fs');+require(path.join(__dirname,'../lib/jasmine-node/cli.js'));
+ lib/jasmine-node/lib/jasmine-node/async-callback.js view
@@ -0,0 +1,54 @@+(function() {+ var withoutAsync = {};++ ["it", "beforeEach", "afterEach"].forEach(function(jasmineFunction) {+ withoutAsync[jasmineFunction] = jasmine.Env.prototype[jasmineFunction];+ return jasmine.Env.prototype[jasmineFunction] = function() {+ var args = Array.prototype.slice.call(arguments, 0);+ var timeout = null;+ if (isLastArgumentATimeout(args)) {+ timeout = args.pop();+ }+ if (isLastArgumentAnAsyncSpecFunction(args))+ {+ var specFunction = args.pop();+ args.push(function() {+ return asyncSpec(specFunction, this, timeout);+ });+ }+ return withoutAsync[jasmineFunction].apply(this, args);+ };+ });++ function isLastArgumentATimeout(args)+ {+ return args.length > 0 && (typeof args[args.length-1]) === "number";+ }++ function isLastArgumentAnAsyncSpecFunction(args)+ {+ return args.length > 0 && (typeof args[args.length-1]) === "function" && args[args.length-1].length > 0;+ }++ function asyncSpec(specFunction, spec, timeout) {+ if (timeout == null) timeout = jasmine.DEFAULT_TIMEOUT_INTERVAL || 1000;+ var done = false;+ spec.runs(function() {+ try {+ return specFunction(function(error) {+ done = true;+ if (error != null) return spec.fail(error);+ });+ } catch (e) {+ done = true;+ throw e;+ }+ });+ return spec.waitsFor(function() {+ if (done === true) {+ return true;+ }+ }, "spec to complete", timeout);+ };++}).call(this);
+ lib/jasmine-node/lib/jasmine-node/autotest.js view
@@ -0,0 +1,90 @@+var walkdir = require('walkdir');+var collection = require('./spec-collection');+var path = require('path');+var fs = require('fs');+var child_process = require('child_process');++var baseArgv = [];++for(var i = 0; i < process.argv.length; i++) {+ if(process.argv[i] !== '--autotest') {+ baseArgv.push(process.argv[i]);+ }+}++var run_external = function(command, args, callback) {+ var child = child_process.spawn(command, args);+ child.stdout.on('data', function(data) {+ process.stdout.write(data);+ });+ child.stderr.on('data', function(data) {+ process.stderr.write(data);+ });+ if(typeof callback == 'function') {+ child.on('exit', callback);+ }+}++var run_everything = function() {+ // run the suite when it starts+ var argv = [].concat(baseArgv);+ run_external(argv.shift(), argv, function() { console.log(arguments) });+}++var last_run_succesful = true;++var watchFile = function(file, stat) {++ var file = path.normalize(file)++ var prevStats = stat;+ + var watcher = fs.watch(file, function(ev) {++ if(!path.existsSync(file)) {+ watcher.close();+ return;+ }++ var currStats = fs.statSync( file );+ + if(prevStats.mtime.getTime() != currStats.mtime.getTime()) {+ prevStats = currStats;++ // narrow down a pattern to reduce the specs runned+ var match = path.basename(file, path.extname(file)) + ".*";+ match = match.replace(new RegExp("spec", "i"), "");++ // so we need to rerun the jasmine suite+ var argv = [].concat(baseArgv, ["--match", match]);+ run_external(argv.shift(), argv, function(code) {+ // run everything if we fixed some bugs+ if(code == 0) {+ if(!last_run_succesful) {+ run_everything();+ }+ last_run_succesful = true;+ } else {+ last_run_succesful = false;+ }+ });+ }+ });+}+++exports.start = function(loadpath, pattern) {++ var finder = walkdir.find(loadpath);++ finder.on('file', function(file, stat) { + var basename = path.basename(file);++ if(pattern.test(basename)) {+ watchFile(file,stat);+ }++ });++ run_everything();+}
+ lib/jasmine-node/lib/jasmine-node/cli.js view
@@ -0,0 +1,176 @@+var jasmine = require('./index');+var util,+ Path= require('path');+try {+ util = require('util')+} catch(e) {+ util = require('sys')+}++var helperCollection = require('./spec-collection');++var specFolder = null;++for (var key in jasmine)+ global[key] = jasmine[key];++var isVerbose = false;+var showColors = true;+var teamcity = process.env.TEAMCITY_PROJECT_NAME || false;+var useRequireJs = false;+var extentions = "js";+var match = '.';+var matchall = false;+var autotest = false;+var useHelpers = true;+var forceExit = false;++var junitreport = {+ report: false,+ savePath : "./reports/",+ useDotNotation: true,+ consolidate: true+}++var args = process.argv.slice(2);++while(args.length) {+ var arg = args.shift();++ switch(arg)+ {+ case '--color':+ showColors = true;+ break;+ case '--noColor':+ case '--nocolor':+ showColors = false;+ break;+ case '--verbose':+ isVerbose = true;+ break;+ case '--coffee':+ require('coffee-script');+ extentions = "js|coffee";+ break;+ case '-m':+ case '--match':+ match = args.shift();+ break;+ case '--matchall':+ matchall = true;+ break;+ case '--junitreport':+ junitreport.report = true;+ break;+ case '--output':+ junitreport.savePath = args.shift();+ break;+ case '--teamcity':+ teamcity = true;+ break;+ case '--runWithRequireJs':+ useRequireJs = true;+ break;+ case '--nohelpers':+ useHelpers = false;+ break;+ case '--test-dir':+ var dir = args.shift();++ if(!Path.existsSync(dir))+ throw new Error("Test root path '" + dir + "' doesn't exist!");++ specFolder = dir; // NOTE: Does not look from current working directory.+ break;+ case '--autotest':+ autotest = true;+ break;+ case '--forceexit':+ forceExit = true;+ break;+ case '-h':+ help();+ default:+ if (arg.match(/^--/)) help();+ if (arg.match(/^\/.*/)) {+ specFolder = arg;+ } else {+ specFolder = Path.join(process.cwd(), arg);+ }+ break;+ }+}++if (!specFolder) {+ help();+}++if (autotest) {+ require('./autotest').start(specFolder,+ new RegExp(".+\\.(" + extentions + ")$", "i"));+ return;+}++var exitCode = 0;++process.on("exit", onExit);++function onExit() {+ process.removeListener("exit", onExit);+ process.exit(exitCode);+}++var onComplete = function(runner, log) {+ util.print('\n');+ if (runner.results().failedCount == 0) {+ exitCode = 0;+ } else {+ exitCode = 1;+ }+ if (forceExit) {+ process.exit(exitCode);+ }+};++if(useHelpers){+ jasmine.loadHelpersInFolder(specFolder,+ new RegExp("helpers?\\.(" + extentions + ")$", 'i'));+}++var regExpSpec = new RegExp(match + (matchall ? "" : "spec\\.") + "(" + extentions + ")$", 'i')++jasmine.executeSpecsInFolder(specFolder,+ onComplete,+ isVerbose,+ showColors,+ teamcity,+ useRequireJs,+ regExpSpec,+ junitreport);++function help(){+ util.print([+ 'USAGE: jasmine-node [--color|--noColor] [--verbose] [--coffee] directory'+ , ''+ , 'Options:'+ , ' --autotest - rerun automatically the specs when a file changes'+ , ' --color - use color coding for output'+ , ' --noColor - do not use color coding for output'+ , ' -m, --match REGEXP - load only specs containing "REGEXPspec"'+ , ' --matchall - relax requirement of "spec" in spec file names'+ , ' --verbose - print extra information per each test run'+ , ' --coffee - load coffee-script which allows execution .coffee files'+ , ' --junitreport - export tests results as junitreport xml format'+ , ' --output - defines the output folder for junitreport files'+ , ' --teamcity - converts all console output to teamcity custom test runner commands. (Normally auto detected.)'+ , ' --runWithRequireJs - loads all specs using requirejs instead of node\'s native require method'+ , ' --test-dir - the absolute root directory path where tests are located'+ , ' --nohelpers - does not load helpers.'+ , ' --forceexit - force exit once tests complete.'+ , ' -h, --help - display this help and exit'+ , ''+ ].join("\n"));++ process.exit(-1);+}
+ lib/jasmine-node/lib/jasmine-node/index.js view
@@ -0,0 +1,148 @@+var fs = require('fs');+var util;+try {+ util = require('util')+} catch(e) {+ util = require('sys')+}++var path = require('path');++var filename = __dirname + '/jasmine-2.0.0.rc1.js';+global.window = {+ setTimeout: setTimeout,+ clearTimeout: clearTimeout,+ setInterval: setInterval,+ clearInterval: clearInterval+};++var src = fs.readFileSync(filename);+var jasmine;+var minorVersion = process.version.match(/\d\.(\d)\.\d/)[1];+switch (minorVersion) {+ case "1":+ case "2":+ jasmine = process.compile(src + '\njasmine;', filename);+ break;+ default:+ jasmine = require('vm').runInThisContext(src + "\njasmine;", filename);+}++delete global.window;+require("./async-callback");+require("jasmine-reporters");++var jasmineNode = require('./reporter').jasmineNode;++jasmine.loadHelpersInFolder=function(folder, matcher)+{+ var helpers = [],+ helperCollection = require('./spec-collection');++ helperCollection.load(folder, matcher);+ helpers = helperCollection.getSpecs();++ for (var i = 0, len = helpers.length; i < len; ++i)+ {+ var file = helpers[i].path();+ var helper= require(file.replace(/\.*$/, ""));+ for (var key in helper)+ global[key]= helper[key];+ }+};++function removeJasmineFrames(text) {+ var lines = [];+ text.split(/\n/).forEach(function(line){+ if (line.indexOf(filename) == -1) {+ lines.push(line);+ }+ });+ return lines.join('\n');+}++jasmine.executeSpecsInFolder = function(folder,+ done,+ isVerbose,+ showColors,+ teamcity,+ useRequireJs,+ matcher,+ junitreport){+ var fileMatcher = matcher || new RegExp(".(js)$", "i"),+ colors = showColors || false,+ specs = require('./spec-collection'),+ jasmineEnv = jasmine.getEnv();++ specs.load(folder, fileMatcher);++ if(junitreport && junitreport.report) {+ if(!path.existsSync(junitreport.savePath)) {+ util.puts('creating junit xml report save path: ' + junitreport.savePath);+ fs.mkdirSync(junitreport.savePath, "0755");+ }+ jasmineEnv.addReporter(new jasmine.JUnitXmlReporter(junitreport.savePath,+ junitreport.consolidate,+ junitreport.useDotNotation));+ }++ if(teamcity){+ jasmineEnv.addReporter(new jasmineNode.TerminalReporter({print: util.print,+ color: false,+ onComplete: done,+ stackFilter: removeJasmineFrames}));+ } else if(isVerbose) {+ jasmineEnv.addReporter(new jasmineNode.TerminalVerboseReporter({ print: util.print,+ color: showColors,+ onComplete: done,+ stackFilter: removeJasmineFrames}));+ } else {+ jasmineEnv.addReporter(new jasmineNode.TerminalReporter({print: util.print,+ color: showColors,+ onComplete: done,+ stackFilter: removeJasmineFrames}));+ }++ if (useRequireJs) {+ require('./requirejs-runner').executeJsRunner(specs, done, jasmineEnv);+ } else {+ var specsList = specs.getSpecs();++ for (var i = 0, len = specsList.length; i < len; ++i) {+ var filename = specsList[i];+ require(filename.path().replace(/\.\w+$/, ""));+ }++ jasmineEnv.execute();+ }+};++function now(){+ return new Date().getTime();+}++jasmine.asyncSpecWait = function(){+ var wait = jasmine.asyncSpecWait;+ wait.start = now();+ wait.done = false;+ (function innerWait(){+ waits(10);+ runs(function() {+ if (wait.start + wait.timeout < now()) {+ expect('timeout waiting for spec').toBeNull();+ } else if (wait.done) {+ wait.done = false;+ } else {+ innerWait();+ }+ });+ })();+};+jasmine.asyncSpecWait.timeout = 4 * 1000;+jasmine.asyncSpecDone = function(){+ jasmine.asyncSpecWait.done = true;+};++for ( var key in jasmine) {+ exports[key] = jasmine[key];+}
+ lib/jasmine-node/lib/jasmine-node/jasmine-2.0.0.rc1.js view
@@ -0,0 +1,2479 @@+var isCommonJS = typeof window == "undefined";++/**+ * Top level namespace for Jasmine, a lightweight JavaScript BDD/spec/testing framework.+ *+ * @namespace+ */+var jasmine = {};+if (isCommonJS) exports.jasmine = jasmine;+/**+ * @private+ */+jasmine.unimplementedMethod_ = function() {+ throw new Error("unimplemented method");+};++/**+ * Use <code>jasmine.undefined</code> instead of <code>undefined</code>, since <code>undefined</code> is just+ * a plain old variable and may be redefined by somebody else.+ *+ * @private+ */+jasmine.undefined = jasmine.___undefined___;++/**+ * Show diagnostic messages in the console if set to true+ *+ */+jasmine.VERBOSE = false;++/**+ * Default interval in milliseconds for event loop yields (e.g. to allow network activity or to refresh the screen with the HTML-based runner). Small values here may result in slow test running. Zero means no updates until all tests have completed.+ *+ */+jasmine.DEFAULT_UPDATE_INTERVAL = 250;++/**+ * Default timeout interval in milliseconds for waitsFor() blocks.+ */+jasmine.DEFAULT_TIMEOUT_INTERVAL = 5000;++jasmine.getGlobal = function() {+ function getGlobal() {+ return this;+ }++ return getGlobal();+};++/**+ * Allows for bound functions to be compared. Internal use only.+ *+ * @ignore+ * @private+ * @param base {Object} bound 'this' for the function+ * @param name {Function} function to find+ */+jasmine.bindOriginal_ = function(base, name) {+ var original = base[name];+ if (original.apply) {+ return function() {+ return original.apply(base, arguments);+ };+ } else {+ // IE support+ return jasmine.getGlobal()[name];+ }+};++jasmine.setTimeout = jasmine.bindOriginal_(jasmine.getGlobal(), 'setTimeout');+jasmine.clearTimeout = jasmine.bindOriginal_(jasmine.getGlobal(), 'clearTimeout');+jasmine.setInterval = jasmine.bindOriginal_(jasmine.getGlobal(), 'setInterval');+jasmine.clearInterval = jasmine.bindOriginal_(jasmine.getGlobal(), 'clearInterval');++jasmine.MessageResult = function(values) {+ this.type = 'log';+ this.values = values;+ this.trace = new Error(); // todo: test better+};++jasmine.MessageResult.prototype.toString = function() {+ var text = "";+ for (var i = 0; i < this.values.length; i++) {+ if (i > 0) text += " ";+ if (jasmine.isString_(this.values[i])) {+ text += this.values[i];+ } else {+ text += jasmine.pp(this.values[i]);+ }+ }+ return text;+};++jasmine.ExpectationResult = function(params) {+ this.type = 'expect';+ this.matcherName = params.matcherName;+ this.passed_ = params.passed;+ this.expected = params.expected;+ this.actual = params.actual;+ this.message = this.passed_ ? 'Passed.' : params.message;++ var trace = (params.trace || new Error(this.message));+ this.trace = this.passed_ ? '' : trace;+};++jasmine.ExpectationResult.prototype.toString = function () {+ return this.message;+};++jasmine.ExpectationResult.prototype.passed = function () {+ return this.passed_;+};++/**+ * Getter for the Jasmine environment. Ensures one gets created+ */+jasmine.getEnv = function() {+ var env = jasmine.currentEnv_ = jasmine.currentEnv_ || new jasmine.Env();+ return env;+};++/**+ * @ignore+ * @private+ * @param value+ * @returns {Boolean}+ */+jasmine.isArray_ = function(value) {+ return jasmine.isA_("Array", value);+};++/**+ * @ignore+ * @private+ * @param value+ * @returns {Boolean}+ */+jasmine.isString_ = function(value) {+ return jasmine.isA_("String", value);+};++/**+ * @ignore+ * @private+ * @param value+ * @returns {Boolean}+ */+jasmine.isNumber_ = function(value) {+ return jasmine.isA_("Number", value);+};++/**+ * @ignore+ * @private+ * @param {String} typeName+ * @param value+ * @returns {Boolean}+ */+jasmine.isA_ = function(typeName, value) {+ return Object.prototype.toString.apply(value) === '[object ' + typeName + ']';+};++/**+ * Pretty printer for expecations. Takes any object and turns it into a human-readable string.+ *+ * @param value {Object} an object to be outputted+ * @returns {String}+ */+jasmine.pp = function(value) {+ var stringPrettyPrinter = new jasmine.StringPrettyPrinter();+ stringPrettyPrinter.format(value);+ return stringPrettyPrinter.string;+};++/**+ * Returns true if the object is a DOM Node.+ *+ * @param {Object} obj object to check+ * @returns {Boolean}+ */+jasmine.isDomNode = function(obj) {+ return obj.nodeType > 0;+};++/**+ * Returns a matchable 'generic' object of the class type. For use in expecations of type when values don't matter.+ *+ * @example+ * // don't care about which function is passed in, as long as it's a function+ * expect(mySpy).toHaveBeenCalledWith(jasmine.any(Function));+ *+ * @param {Class} clazz+ * @returns matchable object of the type clazz+ */+jasmine.any = function(clazz) {+ return new jasmine.Matchers.Any(clazz);+};++/**+ * Jasmine Spies are test doubles that can act as stubs, spies, fakes or when used in an expecation, mocks.+ *+ * Spies should be created in test setup, before expectations. They can then be checked, using the standard Jasmine+ * expectation syntax. Spies can be checked if they were called or not and what the calling params were.+ *+ * A Spy has the following fields: wasCalled, callCount, mostRecentCall, and argsForCall (see docs).+ *+ * Spies are torn down at the end of every spec.+ *+ * Note: Do <b>not</b> call new jasmine.Spy() directly - a spy must be created using spyOn, jasmine.createSpy or jasmine.createSpyObj.+ *+ * @example+ * // a stub+ * var myStub = jasmine.createSpy('myStub'); // can be used anywhere+ *+ * // spy example+ * var foo = {+ * not: function(bool) { return !bool; }+ * }+ *+ * // actual foo.not will not be called, execution stops+ * spyOn(foo, 'not');++ // foo.not spied upon, execution will continue to implementation+ * spyOn(foo, 'not').andCallThrough();+ *+ * // fake example+ * var foo = {+ * not: function(bool) { return !bool; }+ * }+ *+ * // foo.not(val) will return val+ * spyOn(foo, 'not').andCallFake(function(value) {return value;});+ *+ * // mock example+ * foo.not(7 == 7);+ * expect(foo.not).toHaveBeenCalled();+ * expect(foo.not).toHaveBeenCalledWith(true);+ *+ * @constructor+ * @see spyOn, jasmine.createSpy, jasmine.createSpyObj+ * @param {String} name+ */+jasmine.Spy = function(name) {+ /**+ * The name of the spy, if provided.+ */+ this.identity = name || 'unknown';+ /**+ * Is this Object a spy?+ */+ this.isSpy = true;+ /**+ * The actual function this spy stubs.+ */+ this.plan = function() {+ };+ /**+ * Tracking of the most recent call to the spy.+ * @example+ * var mySpy = jasmine.createSpy('foo');+ * mySpy(1, 2);+ * mySpy.mostRecentCall.args = [1, 2];+ */+ this.mostRecentCall = {};++ /**+ * Holds arguments for each call to the spy, indexed by call count+ * @example+ * var mySpy = jasmine.createSpy('foo');+ * mySpy(1, 2);+ * mySpy(7, 8);+ * mySpy.mostRecentCall.args = [7, 8];+ * mySpy.argsForCall[0] = [1, 2];+ * mySpy.argsForCall[1] = [7, 8];+ */+ this.argsForCall = [];+ this.calls = [];+};++/**+ * Tells a spy to call through to the actual implemenatation.+ *+ * @example+ * var foo = {+ * bar: function() { // do some stuff }+ * }+ *+ * // defining a spy on an existing property: foo.bar+ * spyOn(foo, 'bar').andCallThrough();+ */+jasmine.Spy.prototype.andCallThrough = function() {+ this.plan = this.originalValue;+ return this;+};++/**+ * For setting the return value of a spy.+ *+ * @example+ * // defining a spy from scratch: foo() returns 'baz'+ * var foo = jasmine.createSpy('spy on foo').andReturn('baz');+ *+ * // defining a spy on an existing property: foo.bar() returns 'baz'+ * spyOn(foo, 'bar').andReturn('baz');+ *+ * @param {Object} value+ */+jasmine.Spy.prototype.andReturn = function(value) {+ this.plan = function() {+ return value;+ };+ return this;+};++/**+ * For throwing an exception when a spy is called.+ *+ * @example+ * // defining a spy from scratch: foo() throws an exception w/ message 'ouch'+ * var foo = jasmine.createSpy('spy on foo').andThrow('baz');+ *+ * // defining a spy on an existing property: foo.bar() throws an exception w/ message 'ouch'+ * spyOn(foo, 'bar').andThrow('baz');+ *+ * @param {String} exceptionMsg+ */+jasmine.Spy.prototype.andThrow = function(exceptionMsg) {+ this.plan = function() {+ throw exceptionMsg;+ };+ return this;+};++/**+ * Calls an alternate implementation when a spy is called.+ *+ * @example+ * var baz = function() {+ * // do some stuff, return something+ * }+ * // defining a spy from scratch: foo() calls the function baz+ * var foo = jasmine.createSpy('spy on foo').andCall(baz);+ *+ * // defining a spy on an existing property: foo.bar() calls an anonymnous function+ * spyOn(foo, 'bar').andCall(function() { return 'baz';} );+ *+ * @param {Function} fakeFunc+ */+jasmine.Spy.prototype.andCallFake = function(fakeFunc) {+ this.plan = fakeFunc;+ return this;+};++/**+ * Resets all of a spy's the tracking variables so that it can be used again.+ *+ * @example+ * spyOn(foo, 'bar');+ *+ * foo.bar();+ *+ * expect(foo.bar.callCount).toEqual(1);+ *+ * foo.bar.reset();+ *+ * expect(foo.bar.callCount).toEqual(0);+ */+jasmine.Spy.prototype.reset = function() {+ this.wasCalled = false;+ this.callCount = 0;+ this.argsForCall = [];+ this.calls = [];+ this.mostRecentCall = {};+};++jasmine.createSpy = function(name) {++ var spyObj = function() {+ spyObj.wasCalled = true;+ spyObj.callCount++;+ var args = jasmine.util.argsToArray(arguments);+ spyObj.mostRecentCall.object = this;+ spyObj.mostRecentCall.args = args;+ spyObj.argsForCall.push(args);+ spyObj.calls.push({object: this, args: args});+ return spyObj.plan.apply(this, arguments);+ };++ var spy = new jasmine.Spy(name);++ for (var prop in spy) {+ spyObj[prop] = spy[prop];+ }++ spyObj.reset();++ return spyObj;+};++/**+ * Determines whether an object is a spy.+ *+ * @param {jasmine.Spy|Object} putativeSpy+ * @returns {Boolean}+ */+jasmine.isSpy = function(putativeSpy) {+ return putativeSpy && putativeSpy.isSpy;+};++/**+ * Creates a more complicated spy: an Object that has every property a function that is a spy. Used for stubbing something+ * large in one call.+ *+ * @param {String} baseName name of spy class+ * @param {Array} methodNames array of names of methods to make spies+ */+jasmine.createSpyObj = function(baseName, methodNames) {+ if (!jasmine.isArray_(methodNames) || methodNames.length === 0) {+ throw new Error('createSpyObj requires a non-empty array of method names to create spies for');+ }+ var obj = {};+ for (var i = 0; i < methodNames.length; i++) {+ obj[methodNames[i]] = jasmine.createSpy(baseName + '.' + methodNames[i]);+ }+ return obj;+};++/**+ * All parameters are pretty-printed and concatenated together, then written to the current spec's output.+ *+ * Be careful not to leave calls to <code>jasmine.log</code> in production code.+ */+jasmine.log = function() {+ var spec = jasmine.getEnv().currentSpec;+ spec.log.apply(spec, arguments);+};++/**+ * Function that installs a spy on an existing object's method name. Used within a Spec to create a spy.+ *+ * @example+ * // spy example+ * var foo = {+ * not: function(bool) { return !bool; }+ * }+ * spyOn(foo, 'not'); // actual foo.not will not be called, execution stops+ *+ * @see jasmine.createSpy+ * @param obj+ * @param methodName+ * @returns a Jasmine spy that can be chained with all spy methods+ */+var spyOn = function(obj, methodName) {+ return jasmine.getEnv().currentSpec.spyOn(obj, methodName);+};+if (isCommonJS) exports.spyOn = spyOn;++/**+ * Creates a Jasmine spec that will be added to the current suite.+ *+ * // TODO: pending tests+ *+ * @example+ * it('should be true', function() {+ * expect(true).toEqual(true);+ * });+ *+ * @param {String} desc description of this specification+ * @param {Function} func defines the preconditions and expectations of the spec+ */+var it = function(desc, func) {+ return jasmine.getEnv().it(desc, func);+};+if (isCommonJS) exports.it = it;++/**+ * Creates a <em>disabled</em> Jasmine spec.+ *+ * A convenience method that allows existing specs to be disabled temporarily during development.+ *+ * @param {String} desc description of this specification+ * @param {Function} func defines the preconditions and expectations of the spec+ */+var xit = function(desc, func) {+ return jasmine.getEnv().xit(desc, func);+};+if (isCommonJS) exports.xit = xit;++/**+ * Starts a chain for a Jasmine expectation.+ *+ * It is passed an Object that is the actual value and should chain to one of the many+ * jasmine.Matchers functions.+ *+ * @param {Object} actual Actual value to test against and expected value+ */+var expect = function(actual) {+ return jasmine.getEnv().currentSpec.expect(actual);+};+if (isCommonJS) exports.expect = expect;++/**+ * Defines part of a jasmine spec. Used in cominbination with waits or waitsFor in asynchrnous specs.+ *+ * @param {Function} func Function that defines part of a jasmine spec.+ */+var runs = function(func) {+ jasmine.getEnv().currentSpec.runs(func);+};+if (isCommonJS) exports.runs = runs;++/**+ * Waits a fixed time period before moving to the next block.+ *+ * @deprecated Use waitsFor() instead+ * @param {Number} timeout milliseconds to wait+ */+var waits = function(timeout) {+ jasmine.getEnv().currentSpec.waits(timeout);+};+if (isCommonJS) exports.waits = waits;++/**+ * Waits for the latchFunction to return true before proceeding to the next block.+ *+ * @param {Function} latchFunction+ * @param {String} optional_timeoutMessage+ * @param {Number} optional_timeout+ */+var waitsFor = function(latchFunction, optional_timeoutMessage, optional_timeout) {+ jasmine.getEnv().currentSpec.waitsFor.apply(jasmine.getEnv().currentSpec, arguments);+};+if (isCommonJS) exports.waitsFor = waitsFor;++/**+ * A function that is called before each spec in a suite.+ *+ * Used for spec setup, including validating assumptions.+ *+ * @param {Function} beforeEachFunction+ */+var beforeEach = function(beforeEachFunction) {+ jasmine.getEnv().beforeEach(beforeEachFunction);+};+if (isCommonJS) exports.beforeEach = beforeEach;++/**+ * A function that is called after each spec in a suite.+ *+ * Used for restoring any state that is hijacked during spec execution.+ *+ * @param {Function} afterEachFunction+ */+var afterEach = function(afterEachFunction) {+ jasmine.getEnv().afterEach(afterEachFunction);+};+if (isCommonJS) exports.afterEach = afterEach;++/**+ * Defines a suite of specifications.+ *+ * Stores the description and all defined specs in the Jasmine environment as one suite of specs. Variables declared+ * are accessible by calls to beforeEach, it, and afterEach. Describe blocks can be nested, allowing for specialization+ * of setup in some tests.+ *+ * @example+ * // TODO: a simple suite+ *+ * // TODO: a simple suite with a nested describe block+ *+ * @param {String} description A string, usually the class under test.+ * @param {Function} specDefinitions function that defines several specs.+ */+var describe = function(description, specDefinitions) {+ return jasmine.getEnv().describe(description, specDefinitions);+};+if (isCommonJS) exports.describe = describe;++/**+ * Disables a suite of specifications. Used to disable some suites in a file, or files, temporarily during development.+ *+ * @param {String} description A string, usually the class under test.+ * @param {Function} specDefinitions function that defines several specs.+ */+var xdescribe = function(description, specDefinitions) {+ return jasmine.getEnv().xdescribe(description, specDefinitions);+};+if (isCommonJS) exports.xdescribe = xdescribe;+++// Provide the XMLHttpRequest class for IE 5.x-6.x:+jasmine.XmlHttpRequest = (typeof XMLHttpRequest == "undefined") ? function() {+ function tryIt(f) {+ try {+ return f();+ } catch(e) {+ }+ return null;+ }++ var xhr = tryIt(function() {+ return new ActiveXObject("Msxml2.XMLHTTP.6.0");+ }) ||+ tryIt(function() {+ return new ActiveXObject("Msxml2.XMLHTTP.3.0");+ }) ||+ tryIt(function() {+ return new ActiveXObject("Msxml2.XMLHTTP");+ }) ||+ tryIt(function() {+ return new ActiveXObject("Microsoft.XMLHTTP");+ });++ if (!xhr) throw new Error("This browser does not support XMLHttpRequest.");++ return xhr;+} : XMLHttpRequest;+/**+ * @namespace+ */+jasmine.util = {};++/**+ * Declare that a child class inherit it's prototype from the parent class.+ *+ * @private+ * @param {Function} childClass+ * @param {Function} parentClass+ */+jasmine.util.inherit = function(childClass, parentClass) {+ /**+ * @private+ */+ var subclass = function() {+ };+ subclass.prototype = parentClass.prototype;+ childClass.prototype = new subclass();+};++jasmine.util.formatException = function(e) {+ var lineNumber;+ if (e.line) {+ lineNumber = e.line;+ }+ else if (e.lineNumber) {+ lineNumber = e.lineNumber;+ }++ var file;++ if (e.sourceURL) {+ file = e.sourceURL;+ }+ else if (e.fileName) {+ file = e.fileName;+ }++ var message = (e.name && e.message) ? (e.name + ': ' + e.message) : e.toString();++ if (file && lineNumber) {+ message += ' in ' + file + ' (line ' + lineNumber + ')';+ }++ return message;+};++jasmine.util.htmlEscape = function(str) {+ if (!str) return str;+ return str.replace(/&/g, '&')+ .replace(/</g, '<')+ .replace(/>/g, '>');+};++jasmine.util.argsToArray = function(args) {+ var arrayOfArgs = [];+ for (var i = 0; i < args.length; i++) arrayOfArgs.push(args[i]);+ return arrayOfArgs;+};++jasmine.util.extend = function(destination, source) {+ for (var property in source) destination[property] = source[property];+ return destination;+};++/**+ * Environment for Jasmine+ *+ * @constructor+ */+jasmine.Env = function() {+ this.currentSpec = null;+ this.currentSuite = null;+ this.currentRunner_ = new jasmine.Runner(this);++ this.reporter = new jasmine.MultiReporter();++ this.updateInterval = jasmine.DEFAULT_UPDATE_INTERVAL;+ this.defaultTimeoutInterval = jasmine.DEFAULT_TIMEOUT_INTERVAL;+ this.lastUpdate = 0;+ this.specFilter = function() {+ return true;+ };++ this.nextSpecId_ = 0;+ this.nextSuiteId_ = 0;+ this.equalityTesters_ = [];++ // wrap matchers+ this.matchersClass = function() {+ jasmine.Matchers.apply(this, arguments);+ };+ jasmine.util.inherit(this.matchersClass, jasmine.Matchers);++ jasmine.Matchers.wrapInto_(jasmine.Matchers.prototype, this.matchersClass);+};+++jasmine.Env.prototype.setTimeout = jasmine.setTimeout;+jasmine.Env.prototype.clearTimeout = jasmine.clearTimeout;+jasmine.Env.prototype.setInterval = jasmine.setInterval;+jasmine.Env.prototype.clearInterval = jasmine.clearInterval;++/**+ * @returns an object containing jasmine version build info, if set.+ */+jasmine.Env.prototype.version = function () {+ if (jasmine.version_) {+ return jasmine.version_;+ } else {+ throw new Error('Version not set');+ }+};++/**+ * @returns string containing jasmine version build info, if set.+ */+jasmine.Env.prototype.versionString = function() {+ if (jasmine.version_) {+ var version = this.version();+ var versionString = version.major + "." + version.minor + "." + version.build;+ if (version.release_candidate) {+ versionString += ".rc" + version.release_candidate+ }+ versionString += " revision " + version.revision+ return versionString;+ } else {+ return "version unknown";+ }+};++/**+ * @returns a sequential integer starting at 0+ */+jasmine.Env.prototype.nextSpecId = function () {+ return this.nextSpecId_++;+};++/**+ * @returns a sequential integer starting at 0+ */+jasmine.Env.prototype.nextSuiteId = function () {+ return this.nextSuiteId_++;+};++/**+ * Register a reporter to receive status updates from Jasmine.+ * @param {jasmine.Reporter} reporter An object which will receive status updates.+ */+jasmine.Env.prototype.addReporter = function(reporter) {+ this.reporter.addReporter(reporter);+};++jasmine.Env.prototype.execute = function() {+ this.currentRunner_.execute();+};++jasmine.Env.prototype.describe = function(description, specDefinitions) {+ var suite = new jasmine.Suite(this, description, specDefinitions, this.currentSuite);++ var parentSuite = this.currentSuite;+ if (parentSuite) {+ parentSuite.add(suite);+ } else {+ this.currentRunner_.add(suite);+ }++ this.currentSuite = suite;++ var declarationError = null;+ try {+ specDefinitions.call(suite);+ } catch(e) {+ declarationError = e;+ }++ if (declarationError) {+ this.it("encountered a declaration exception", function() {+ throw declarationError;+ });+ }++ this.currentSuite = parentSuite;++ return suite;+};++jasmine.Env.prototype.beforeEach = function(beforeEachFunction) {+ if (this.currentSuite) {+ this.currentSuite.beforeEach(beforeEachFunction);+ } else {+ this.currentRunner_.beforeEach(beforeEachFunction);+ }+};++jasmine.Env.prototype.currentRunner = function () {+ return this.currentRunner_;+};++jasmine.Env.prototype.afterEach = function(afterEachFunction) {+ if (this.currentSuite) {+ this.currentSuite.afterEach(afterEachFunction);+ } else {+ this.currentRunner_.afterEach(afterEachFunction);+ }++};++jasmine.Env.prototype.xdescribe = function(desc, specDefinitions) {+ return {+ execute: function() {+ }+ };+};++jasmine.Env.prototype.it = function(description, func) {+ var spec = new jasmine.Spec(this, this.currentSuite, description);+ this.currentSuite.add(spec);+ this.currentSpec = spec;++ if (func) {+ spec.runs(func);+ }++ return spec;+};++jasmine.Env.prototype.xit = function(desc, func) {+ return {+ id: this.nextSpecId(),+ runs: function() {+ }+ };+};++jasmine.Env.prototype.compareObjects_ = function(a, b, mismatchKeys, mismatchValues) {+ if (a.__Jasmine_been_here_before__ === b && b.__Jasmine_been_here_before__ === a) {+ return true;+ }++ a.__Jasmine_been_here_before__ = b;+ b.__Jasmine_been_here_before__ = a;++ var hasKey = function(obj, keyName) {+ return obj !== null && obj[keyName] !== jasmine.undefined;+ };++ for (var property in b) {+ if (!hasKey(a, property) && hasKey(b, property)) {+ mismatchKeys.push("expected has key '" + property + "', but missing from actual.");+ }+ }+ for (property in a) {+ if (!hasKey(b, property) && hasKey(a, property)) {+ mismatchKeys.push("expected missing key '" + property + "', but present in actual.");+ }+ }+ for (property in b) {+ if (property == '__Jasmine_been_here_before__') continue;+ if (!this.equals_(a[property], b[property], mismatchKeys, mismatchValues)) {+ mismatchValues.push("'" + property + "' was '" + (b[property] ? jasmine.util.htmlEscape(b[property].toString()) : b[property]) + "' in expected, but was '" + (a[property] ? jasmine.util.htmlEscape(a[property].toString()) : a[property]) + "' in actual.");+ }+ }++ if (jasmine.isArray_(a) && jasmine.isArray_(b) && a.length != b.length) {+ mismatchValues.push("arrays were not the same length");+ }++ delete a.__Jasmine_been_here_before__;+ delete b.__Jasmine_been_here_before__;+ return (mismatchKeys.length === 0 && mismatchValues.length === 0);+};++jasmine.Env.prototype.equals_ = function(a, b, mismatchKeys, mismatchValues) {+ mismatchKeys = mismatchKeys || [];+ mismatchValues = mismatchValues || [];++ for (var i = 0; i < this.equalityTesters_.length; i++) {+ var equalityTester = this.equalityTesters_[i];+ var result = equalityTester(a, b, this, mismatchKeys, mismatchValues);+ if (result !== jasmine.undefined) return result;+ }++ if (a === b) return true;++ if (a === jasmine.undefined || a === null || b === jasmine.undefined || b === null) {+ return (a == jasmine.undefined && b == jasmine.undefined);+ }++ if (jasmine.isDomNode(a) && jasmine.isDomNode(b)) {+ return a === b;+ }++ if (a instanceof Date && b instanceof Date) {+ return a.getTime() == b.getTime();+ }++ if (a instanceof jasmine.Matchers.Any) {+ return a.matches(b);+ }++ if (b instanceof jasmine.Matchers.Any) {+ return b.matches(a);+ }++ if (jasmine.isString_(a) && jasmine.isString_(b)) {+ return (a == b);+ }++ if (jasmine.isNumber_(a) && jasmine.isNumber_(b)) {+ return (a == b);+ }++ if (typeof a === "object" && typeof b === "object") {+ return this.compareObjects_(a, b, mismatchKeys, mismatchValues);+ }++ //Straight check+ return (a === b);+};++jasmine.Env.prototype.contains_ = function(haystack, needle) {+ if (jasmine.isArray_(haystack)) {+ for (var i = 0; i < haystack.length; i++) {+ if (this.equals_(haystack[i], needle)) return true;+ }+ return false;+ }+ return haystack.indexOf(needle) >= 0;+};++jasmine.Env.prototype.addEqualityTester = function(equalityTester) {+ this.equalityTesters_.push(equalityTester);+};+/** No-op base class for Jasmine reporters.+ *+ * @constructor+ */+jasmine.Reporter = function() {+};++//noinspection JSUnusedLocalSymbols+jasmine.Reporter.prototype.reportRunnerStarting = function(runner) {+};++//noinspection JSUnusedLocalSymbols+jasmine.Reporter.prototype.reportRunnerResults = function(runner) {+};++//noinspection JSUnusedLocalSymbols+jasmine.Reporter.prototype.reportSuiteResults = function(suite) {+};++//noinspection JSUnusedLocalSymbols+jasmine.Reporter.prototype.reportSpecStarting = function(spec) {+};++//noinspection JSUnusedLocalSymbols+jasmine.Reporter.prototype.reportSpecResults = function(spec) {+};++//noinspection JSUnusedLocalSymbols+jasmine.Reporter.prototype.log = function(str) {+};++/**+ * Blocks are functions with executable code that make up a spec.+ *+ * @constructor+ * @param {jasmine.Env} env+ * @param {Function} func+ * @param {jasmine.Spec} spec+ */+jasmine.Block = function(env, func, spec) {+ this.env = env;+ this.func = func;+ this.spec = spec;+};++jasmine.Block.prototype.execute = function(onComplete) { + try {+ this.func.apply(this.spec);+ } catch (e) {+ this.spec.fail(e);+ }+ onComplete();+};+/** JavaScript API reporter.+ *+ * @constructor+ */+jasmine.JsApiReporter = function() {+ this.started = false;+ this.finished = false;+ this.suites_ = [];+ this.results_ = {};+};++jasmine.JsApiReporter.prototype.reportRunnerStarting = function(runner) {+ this.started = true;+ var suites = runner.topLevelSuites();+ for (var i = 0; i < suites.length; i++) {+ var suite = suites[i];+ this.suites_.push(this.summarize_(suite));+ }+};++jasmine.JsApiReporter.prototype.suites = function() {+ return this.suites_;+};++jasmine.JsApiReporter.prototype.summarize_ = function(suiteOrSpec) {+ var isSuite = suiteOrSpec instanceof jasmine.Suite;+ var summary = {+ id: suiteOrSpec.id,+ name: suiteOrSpec.description,+ type: isSuite ? 'suite' : 'spec',+ children: []+ };+ + if (isSuite) {+ var children = suiteOrSpec.children();+ for (var i = 0; i < children.length; i++) {+ summary.children.push(this.summarize_(children[i]));+ }+ }+ return summary;+};++jasmine.JsApiReporter.prototype.results = function() {+ return this.results_;+};++jasmine.JsApiReporter.prototype.resultsForSpec = function(specId) {+ return this.results_[specId];+};++//noinspection JSUnusedLocalSymbols+jasmine.JsApiReporter.prototype.reportRunnerResults = function(runner) {+ this.finished = true;+};++//noinspection JSUnusedLocalSymbols+jasmine.JsApiReporter.prototype.reportSuiteResults = function(suite) {+};++//noinspection JSUnusedLocalSymbols+jasmine.JsApiReporter.prototype.reportSpecResults = function(spec) {+ this.results_[spec.id] = {+ messages: spec.results().getItems(),+ result: spec.results().failedCount > 0 ? "failed" : "passed"+ };+};++//noinspection JSUnusedLocalSymbols+jasmine.JsApiReporter.prototype.log = function(str) {+};++jasmine.JsApiReporter.prototype.resultsForSpecs = function(specIds){+ var results = {};+ for (var i = 0; i < specIds.length; i++) {+ var specId = specIds[i];+ results[specId] = this.summarizeResult_(this.results_[specId]);+ }+ return results;+};++jasmine.JsApiReporter.prototype.summarizeResult_ = function(result){+ var summaryMessages = [];+ var messagesLength = result.messages.length;+ for (var messageIndex = 0; messageIndex < messagesLength; messageIndex++) {+ var resultMessage = result.messages[messageIndex];+ summaryMessages.push({+ text: resultMessage.type == 'log' ? resultMessage.toString() : jasmine.undefined,+ passed: resultMessage.passed ? resultMessage.passed() : true,+ type: resultMessage.type,+ message: resultMessage.message,+ trace: {+ stack: resultMessage.passed && !resultMessage.passed() ? resultMessage.trace.stack : jasmine.undefined+ }+ });+ }++ return {+ result : result.result,+ messages : summaryMessages+ };+};++/**+ * @constructor+ * @param {jasmine.Env} env+ * @param actual+ * @param {jasmine.Spec} spec+ */+jasmine.Matchers = function(env, actual, spec, opt_isNot) {+ this.env = env;+ this.actual = actual;+ this.spec = spec;+ this.isNot = opt_isNot || false;+ this.reportWasCalled_ = false;+};++// todo: @deprecated as of Jasmine 0.11, remove soon [xw]+jasmine.Matchers.pp = function(str) {+ throw new Error("jasmine.Matchers.pp() is no longer supported, please use jasmine.pp() instead!");+};++// todo: @deprecated Deprecated as of Jasmine 0.10. Rewrite your custom matchers to return true or false. [xw]+jasmine.Matchers.prototype.report = function(result, failing_message, details) {+ throw new Error("As of jasmine 0.11, custom matchers must be implemented differently -- please see jasmine docs");+};++jasmine.Matchers.wrapInto_ = function(prototype, matchersClass) {+ for (var methodName in prototype) {+ if (methodName == 'report') continue;+ var orig = prototype[methodName];+ matchersClass.prototype[methodName] = jasmine.Matchers.matcherFn_(methodName, orig);+ }+};++jasmine.Matchers.matcherFn_ = function(matcherName, matcherFunction) {+ return function() {+ var matcherArgs = jasmine.util.argsToArray(arguments);+ var result = matcherFunction.apply(this, arguments);++ if (this.isNot) {+ result = !result;+ }++ if (this.reportWasCalled_) return result;++ var message;+ if (!result) {+ if (this.message) {+ message = this.message.apply(this, arguments);+ if (jasmine.isArray_(message)) {+ message = message[this.isNot ? 1 : 0];+ }+ } else {+ var englishyPredicate = matcherName.replace(/[A-Z]/g, function(s) { return ' ' + s.toLowerCase(); });+ message = "Expected " + jasmine.pp(this.actual) + (this.isNot ? " not " : " ") + englishyPredicate;+ if (matcherArgs.length > 0) {+ for (var i = 0; i < matcherArgs.length; i++) {+ if (i > 0) message += ",";+ message += " " + jasmine.pp(matcherArgs[i]);+ }+ }+ message += ".";+ }+ }+ var expectationResult = new jasmine.ExpectationResult({+ matcherName: matcherName,+ passed: result,+ expected: matcherArgs.length > 1 ? matcherArgs : matcherArgs[0],+ actual: this.actual,+ message: message+ });+ this.spec.addMatcherResult(expectationResult);+ return jasmine.undefined;+ };+};+++++/**+ * toBe: compares the actual to the expected using ===+ * @param expected+ */+jasmine.Matchers.prototype.toBe = function(expected) {+ return this.actual === expected;+};++/**+ * toNotBe: compares the actual to the expected using !==+ * @param expected+ * @deprecated as of 1.0. Use not.toBe() instead.+ */+jasmine.Matchers.prototype.toNotBe = function(expected) {+ return this.actual !== expected;+};++/**+ * toEqual: compares the actual to the expected using common sense equality. Handles Objects, Arrays, etc.+ *+ * @param expected+ */+jasmine.Matchers.prototype.toEqual = function(expected) {+ return this.env.equals_(this.actual, expected);+};++/**+ * toNotEqual: compares the actual to the expected using the ! of jasmine.Matchers.toEqual+ * @param expected+ * @deprecated as of 1.0. Use not.toNotEqual() instead.+ */+jasmine.Matchers.prototype.toNotEqual = function(expected) {+ return !this.env.equals_(this.actual, expected);+};++/**+ * Matcher that compares the actual to the expected using a regular expression. Constructs a RegExp, so takes+ * a pattern or a String.+ *+ * @param expected+ */+jasmine.Matchers.prototype.toMatch = function(expected) {+ return new RegExp(expected).test(this.actual);+};++/**+ * Matcher that compares the actual to the expected using the boolean inverse of jasmine.Matchers.toMatch+ * @param expected+ * @deprecated as of 1.0. Use not.toMatch() instead.+ */+jasmine.Matchers.prototype.toNotMatch = function(expected) {+ return !(new RegExp(expected).test(this.actual));+};++/**+ * Matcher that compares the actual to jasmine.undefined.+ */+jasmine.Matchers.prototype.toBeDefined = function() {+ return (this.actual !== jasmine.undefined);+};++/**+ * Matcher that compares the actual to jasmine.undefined.+ */+jasmine.Matchers.prototype.toBeUndefined = function() {+ return (this.actual === jasmine.undefined);+};++/**+ * Matcher that compares the actual to null.+ */+jasmine.Matchers.prototype.toBeNull = function() {+ return (this.actual === null);+};++/**+ * Matcher that boolean not-nots the actual.+ */+jasmine.Matchers.prototype.toBeTruthy = function() {+ return !!this.actual;+};+++/**+ * Matcher that boolean nots the actual.+ */+jasmine.Matchers.prototype.toBeFalsy = function() {+ return !this.actual;+};+++/**+ * Matcher that checks to see if the actual, a Jasmine spy, was called.+ */+jasmine.Matchers.prototype.toHaveBeenCalled = function() {+ if (arguments.length > 0) {+ throw new Error('toHaveBeenCalled does not take arguments, use toHaveBeenCalledWith');+ }++ if (!jasmine.isSpy(this.actual)) {+ throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.');+ }++ this.message = function() {+ return [+ "Expected spy " + this.actual.identity + " to have been called.",+ "Expected spy " + this.actual.identity + " not to have been called."+ ];+ };++ return this.actual.wasCalled;+};++/** @deprecated Use expect(xxx).toHaveBeenCalled() instead */+jasmine.Matchers.prototype.wasCalled = jasmine.Matchers.prototype.toHaveBeenCalled;++/**+ * Matcher that checks to see if the actual, a Jasmine spy, was not called.+ *+ * @deprecated Use expect(xxx).not.toHaveBeenCalled() instead+ */+jasmine.Matchers.prototype.wasNotCalled = function() {+ if (arguments.length > 0) {+ throw new Error('wasNotCalled does not take arguments');+ }++ if (!jasmine.isSpy(this.actual)) {+ throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.');+ }++ this.message = function() {+ return [+ "Expected spy " + this.actual.identity + " to not have been called.",+ "Expected spy " + this.actual.identity + " to have been called."+ ];+ };++ return !this.actual.wasCalled;+};++/**+ * Matcher that checks to see if the actual, a Jasmine spy, was called with a set of parameters.+ *+ * @example+ *+ */+jasmine.Matchers.prototype.toHaveBeenCalledWith = function() {+ var expectedArgs = jasmine.util.argsToArray(arguments);+ if (!jasmine.isSpy(this.actual)) {+ throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.');+ }+ this.message = function() {+ if (this.actual.callCount === 0) {+ // todo: what should the failure message for .not.toHaveBeenCalledWith() be? is this right? test better. [xw]+ return [+ "Expected spy " + this.actual.identity + " to have been called with " + jasmine.pp(expectedArgs) + " but it was never called.",+ "Expected spy " + this.actual.identity + " not to have been called with " + jasmine.pp(expectedArgs) + " but it was."+ ];+ } else {+ return [+ "Expected spy " + this.actual.identity + " to have been called with " + jasmine.pp(expectedArgs) + " but was called with " + jasmine.pp(this.actual.argsForCall),+ "Expected spy " + this.actual.identity + " not to have been called with " + jasmine.pp(expectedArgs) + " but was called with " + jasmine.pp(this.actual.argsForCall)+ ];+ }+ };++ return this.env.contains_(this.actual.argsForCall, expectedArgs);+};++/** @deprecated Use expect(xxx).toHaveBeenCalledWith() instead */+jasmine.Matchers.prototype.wasCalledWith = jasmine.Matchers.prototype.toHaveBeenCalledWith;++/** @deprecated Use expect(xxx).not.toHaveBeenCalledWith() instead */+jasmine.Matchers.prototype.wasNotCalledWith = function() {+ var expectedArgs = jasmine.util.argsToArray(arguments);+ if (!jasmine.isSpy(this.actual)) {+ throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.');+ }++ this.message = function() {+ return [+ "Expected spy not to have been called with " + jasmine.pp(expectedArgs) + " but it was",+ "Expected spy to have been called with " + jasmine.pp(expectedArgs) + " but it was"+ ];+ };++ return !this.env.contains_(this.actual.argsForCall, expectedArgs);+};++/**+ * Matcher that checks that the expected item is an element in the actual Array.+ *+ * @param {Object} expected+ */+jasmine.Matchers.prototype.toContain = function(expected) {+ return this.env.contains_(this.actual, expected);+};++/**+ * Matcher that checks that the expected item is NOT an element in the actual Array.+ *+ * @param {Object} expected+ * @deprecated as of 1.0. Use not.toNotContain() instead.+ */+jasmine.Matchers.prototype.toNotContain = function(expected) {+ return !this.env.contains_(this.actual, expected);+};++jasmine.Matchers.prototype.toBeLessThan = function(expected) {+ return this.actual < expected;+};++jasmine.Matchers.prototype.toBeGreaterThan = function(expected) {+ return this.actual > expected;+};++/**+ * Matcher that checks that the expected item is equal to the actual item+ * up to a given level of decimal precision (default 2).+ *+ * @param {Number} expected+ * @param {Number} precision+ */+jasmine.Matchers.prototype.toBeCloseTo = function(expected, precision) {+ if (!(precision === 0)) {+ precision = precision || 2;+ }+ var multiplier = Math.pow(10, precision);+ var actual = Math.round(this.actual * multiplier);+ expected = Math.round(expected * multiplier);+ return expected == actual;+};++/**+ * Matcher that checks that the expected exception was thrown by the actual.+ *+ * @param {String} expected+ */+jasmine.Matchers.prototype.toThrow = function(expected) {+ var result = false;+ var exception;+ if (typeof this.actual != 'function') {+ throw new Error('Actual is not a function');+ }+ try {+ this.actual();+ } catch (e) {+ exception = e;+ }+ if (exception) {+ result = (expected === jasmine.undefined || this.env.equals_(exception.message || exception, expected.message || expected));+ }++ var not = this.isNot ? "not " : "";++ this.message = function() {+ if (exception && (expected === jasmine.undefined || !this.env.equals_(exception.message || exception, expected.message || expected))) {+ return ["Expected function " + not + "to throw", expected ? expected.message || expected : "an exception", ", but it threw", exception.message || exception].join(' ');+ } else {+ return "Expected function to throw an exception.";+ }+ };++ return result;+};++jasmine.Matchers.Any = function(expectedClass) {+ this.expectedClass = expectedClass;+};++jasmine.Matchers.Any.prototype.matches = function(other) {+ if (this.expectedClass == String) {+ return typeof other == 'string' || other instanceof String;+ }++ if (this.expectedClass == Number) {+ return typeof other == 'number' || other instanceof Number;+ }++ if (this.expectedClass == Function) {+ return typeof other == 'function' || other instanceof Function;+ }++ if (this.expectedClass == Object) {+ return typeof other == 'object';+ }++ return other instanceof this.expectedClass;+};++jasmine.Matchers.Any.prototype.toString = function() {+ return '<jasmine.any(' + this.expectedClass + ')>';+};++/**+ * @constructor+ */+jasmine.MultiReporter = function() {+ this.subReporters_ = [];+};+jasmine.util.inherit(jasmine.MultiReporter, jasmine.Reporter);++jasmine.MultiReporter.prototype.addReporter = function(reporter) {+ this.subReporters_.push(reporter);+};++(function() {+ var functionNames = [+ "reportRunnerStarting",+ "reportRunnerResults",+ "reportSuiteResults",+ "reportSpecStarting",+ "reportSpecResults",+ "log"+ ];+ for (var i = 0; i < functionNames.length; i++) {+ var functionName = functionNames[i];+ jasmine.MultiReporter.prototype[functionName] = (function(functionName) {+ return function() {+ for (var j = 0; j < this.subReporters_.length; j++) {+ var subReporter = this.subReporters_[j];+ if (subReporter[functionName]) {+ subReporter[functionName].apply(subReporter, arguments);+ }+ }+ };+ })(functionName);+ }+})();+/**+ * Holds results for a set of Jasmine spec. Allows for the results array to hold another jasmine.NestedResults+ *+ * @constructor+ */+jasmine.NestedResults = function() {+ /**+ * The total count of results+ */+ this.totalCount = 0;+ /**+ * Number of passed results+ */+ this.passedCount = 0;+ /**+ * Number of failed results+ */+ this.failedCount = 0;+ /**+ * Was this suite/spec skipped?+ */+ this.skipped = false;+ /**+ * @ignore+ */+ this.items_ = [];+};++/**+ * Roll up the result counts.+ *+ * @param result+ */+jasmine.NestedResults.prototype.rollupCounts = function(result) {+ this.totalCount += result.totalCount;+ this.passedCount += result.passedCount;+ this.failedCount += result.failedCount;+};++/**+ * Adds a log message.+ * @param values Array of message parts which will be concatenated later.+ */+jasmine.NestedResults.prototype.log = function(values) {+ this.items_.push(new jasmine.MessageResult(values));+};++/**+ * Getter for the results: message & results.+ */+jasmine.NestedResults.prototype.getItems = function() {+ return this.items_;+};++/**+ * Adds a result, tracking counts (total, passed, & failed)+ * @param {jasmine.ExpectationResult|jasmine.NestedResults} result+ */+jasmine.NestedResults.prototype.addResult = function(result) {+ if (result.type != 'log') {+ if (result.items_) {+ this.rollupCounts(result);+ } else {+ this.totalCount++;+ if (result.passed()) {+ this.passedCount++;+ } else {+ this.failedCount++;+ }+ }+ }+ this.items_.push(result);+};++/**+ * @returns {Boolean} True if <b>everything</b> below passed+ */+jasmine.NestedResults.prototype.passed = function() {+ return this.passedCount === this.totalCount;+};+/**+ * Base class for pretty printing for expectation results.+ */+jasmine.PrettyPrinter = function() {+ this.ppNestLevel_ = 0;+};++/**+ * Formats a value in a nice, human-readable string.+ *+ * @param value+ */+jasmine.PrettyPrinter.prototype.format = function(value) {+ if (this.ppNestLevel_ > 40) {+ throw new Error('jasmine.PrettyPrinter: format() nested too deeply!');+ }++ this.ppNestLevel_++;+ try {+ if (value === jasmine.undefined) {+ this.emitScalar('undefined');+ } else if (value === null) {+ this.emitScalar('null');+ } else if (value === jasmine.getGlobal()) {+ this.emitScalar('<global>');+ } else if (value instanceof jasmine.Matchers.Any) {+ this.emitScalar(value.toString());+ } else if (typeof value === 'string') {+ this.emitString(value);+ } else if (jasmine.isSpy(value)) {+ this.emitScalar("spy on " + value.identity);+ } else if (value instanceof RegExp) {+ this.emitScalar(value.toString());+ } else if (typeof value === 'function') {+ this.emitScalar('Function');+ } else if (typeof value.nodeType === 'number') {+ this.emitScalar('HTMLNode');+ } else if (value instanceof Date) {+ this.emitScalar('Date(' + value + ')');+ } else if (value.__Jasmine_been_here_before__) {+ this.emitScalar('<circular reference: ' + (jasmine.isArray_(value) ? 'Array' : 'Object') + '>');+ } else if (jasmine.isArray_(value) || typeof value == 'object') {+ value.__Jasmine_been_here_before__ = true;+ if (jasmine.isArray_(value)) {+ this.emitArray(value);+ } else {+ this.emitObject(value);+ }+ delete value.__Jasmine_been_here_before__;+ } else {+ this.emitScalar(value.toString());+ }+ } finally {+ this.ppNestLevel_--;+ }+};++jasmine.PrettyPrinter.prototype.iterateObject = function(obj, fn) {+ for (var property in obj) {+ if (property == '__Jasmine_been_here_before__') continue;+ fn(property, obj.__lookupGetter__ ? (obj.__lookupGetter__(property) !== jasmine.undefined && + obj.__lookupGetter__(property) !== null) : false);+ }+};++jasmine.PrettyPrinter.prototype.emitArray = jasmine.unimplementedMethod_;+jasmine.PrettyPrinter.prototype.emitObject = jasmine.unimplementedMethod_;+jasmine.PrettyPrinter.prototype.emitScalar = jasmine.unimplementedMethod_;+jasmine.PrettyPrinter.prototype.emitString = jasmine.unimplementedMethod_;++jasmine.StringPrettyPrinter = function() {+ jasmine.PrettyPrinter.call(this);++ this.string = '';+};+jasmine.util.inherit(jasmine.StringPrettyPrinter, jasmine.PrettyPrinter);++jasmine.StringPrettyPrinter.prototype.emitScalar = function(value) {+ this.append(value);+};++jasmine.StringPrettyPrinter.prototype.emitString = function(value) {+ this.append("'" + value + "'");+};++jasmine.StringPrettyPrinter.prototype.emitArray = function(array) {+ this.append('[ ');+ for (var i = 0; i < array.length; i++) {+ if (i > 0) {+ this.append(', ');+ }+ this.format(array[i]);+ }+ this.append(' ]');+};++jasmine.StringPrettyPrinter.prototype.emitObject = function(obj) {+ var self = this;+ this.append('{ ');+ var first = true;++ this.iterateObject(obj, function(property, isGetter) {+ if (first) {+ first = false;+ } else {+ self.append(', ');+ }++ self.append(property);+ self.append(' : ');+ if (isGetter) {+ self.append('<getter>');+ } else {+ self.format(obj[property]);+ }+ });++ this.append(' }');+};++jasmine.StringPrettyPrinter.prototype.append = function(value) {+ this.string += value;+};+jasmine.Queue = function(env) {+ this.env = env;+ this.blocks = [];+ this.running = false;+ this.index = 0;+ this.offset = 0;+ this.abort = false;+};++jasmine.Queue.prototype.addBefore = function(block) {+ this.blocks.unshift(block);+};++jasmine.Queue.prototype.add = function(block) {+ this.blocks.push(block);+};++jasmine.Queue.prototype.insertNext = function(block) {+ this.blocks.splice((this.index + this.offset + 1), 0, block);+ this.offset++;+};++jasmine.Queue.prototype.start = function(onComplete) {+ this.running = true;+ this.onComplete = onComplete;+ this.next_();+};++jasmine.Queue.prototype.isRunning = function() {+ return this.running;+};++jasmine.Queue.LOOP_DONT_RECURSE = true;++jasmine.Queue.prototype.next_ = function() {+ var self = this;+ var goAgain = true;++ while (goAgain) {+ goAgain = false;++ if (self.index < self.blocks.length && !this.abort) {+ var calledSynchronously = true;+ var completedSynchronously = false;++ var onComplete = function () {+ if (jasmine.Queue.LOOP_DONT_RECURSE && calledSynchronously) {+ completedSynchronously = true;+ return;+ }++ if (self.blocks[self.index] && self.blocks[self.index].abort) {+ self.abort = true;+ }++ self.offset = 0;+ self.index++;++ var now = new Date().getTime();+ if (self.env.updateInterval && now - self.env.lastUpdate > self.env.updateInterval) {+ self.env.lastUpdate = now;+ self.env.setTimeout(function() {+ self.next_();+ }, 0);+ } else {+ if (jasmine.Queue.LOOP_DONT_RECURSE && completedSynchronously) {+ goAgain = true;+ } else {+ self.next_();+ }+ }+ };+ self.blocks[self.index].execute(onComplete);++ calledSynchronously = false;+ if (completedSynchronously) {+ onComplete();+ }++ } else {+ self.running = false;+ if (self.onComplete) {+ self.onComplete();+ }+ }+ }+};++jasmine.Queue.prototype.results = function() {+ var results = new jasmine.NestedResults();+ for (var i = 0; i < this.blocks.length; i++) {+ if (this.blocks[i].results) {+ results.addResult(this.blocks[i].results());+ }+ }+ return results;+};+++/**+ * Runner+ *+ * @constructor+ * @param {jasmine.Env} env+ */+jasmine.Runner = function(env) {+ var self = this;+ self.env = env;+ self.queue = new jasmine.Queue(env);+ self.before_ = [];+ self.after_ = [];+ self.suites_ = [];+};++jasmine.Runner.prototype.execute = function() {+ var self = this;+ if (self.env.reporter.reportRunnerStarting) {+ self.env.reporter.reportRunnerStarting(this);+ }+ self.queue.start(function () {+ self.finishCallback();+ });+};++jasmine.Runner.prototype.beforeEach = function(beforeEachFunction) {+ beforeEachFunction.typeName = 'beforeEach';+ this.before_.splice(0,0,beforeEachFunction);+};++jasmine.Runner.prototype.afterEach = function(afterEachFunction) {+ afterEachFunction.typeName = 'afterEach';+ this.after_.splice(0,0,afterEachFunction);+};+++jasmine.Runner.prototype.finishCallback = function() {+ this.env.reporter.reportRunnerResults(this);+};++jasmine.Runner.prototype.addSuite = function(suite) {+ this.suites_.push(suite);+};++jasmine.Runner.prototype.add = function(block) {+ if (block instanceof jasmine.Suite) {+ this.addSuite(block);+ }+ this.queue.add(block);+};++jasmine.Runner.prototype.specs = function () {+ var suites = this.suites();+ var specs = [];+ for (var i = 0; i < suites.length; i++) {+ specs = specs.concat(suites[i].specs());+ }+ return specs;+};++jasmine.Runner.prototype.suites = function() {+ return this.suites_;+};++jasmine.Runner.prototype.topLevelSuites = function() {+ var topLevelSuites = [];+ for (var i = 0; i < this.suites_.length; i++) {+ if (!this.suites_[i].parentSuite) {+ topLevelSuites.push(this.suites_[i]);+ }+ }+ return topLevelSuites;+};++jasmine.Runner.prototype.results = function() {+ return this.queue.results();+};+/**+ * Internal representation of a Jasmine specification, or test.+ *+ * @constructor+ * @param {jasmine.Env} env+ * @param {jasmine.Suite} suite+ * @param {String} description+ */+jasmine.Spec = function(env, suite, description) {+ if (!env) {+ throw new Error('jasmine.Env() required');+ }+ if (!suite) {+ throw new Error('jasmine.Suite() required');+ }+ var spec = this;+ spec.id = env.nextSpecId ? env.nextSpecId() : null;+ spec.env = env;+ spec.suite = suite;+ spec.description = description;+ spec.queue = new jasmine.Queue(env);++ spec.afterCallbacks = [];+ spec.spies_ = [];++ spec.results_ = new jasmine.NestedResults();+ spec.results_.description = description;+ spec.matchersClass = null;+};++jasmine.Spec.prototype.getFullName = function() {+ return this.suite.getFullName() + ' ' + this.description + '.';+};+++jasmine.Spec.prototype.results = function() {+ return this.results_;+};++/**+ * All parameters are pretty-printed and concatenated together, then written to the spec's output.+ *+ * Be careful not to leave calls to <code>jasmine.log</code> in production code.+ */+jasmine.Spec.prototype.log = function() {+ return this.results_.log(arguments);+};++jasmine.Spec.prototype.runs = function (func) {+ var block = new jasmine.Block(this.env, func, this);+ this.addToQueue(block);+ return this;+};++jasmine.Spec.prototype.addToQueue = function (block) {+ if (this.queue.isRunning()) {+ this.queue.insertNext(block);+ } else {+ this.queue.add(block);+ }+};++/**+ * @param {jasmine.ExpectationResult} result+ */+jasmine.Spec.prototype.addMatcherResult = function(result) {+ this.results_.addResult(result);+};++jasmine.Spec.prototype.expect = function(actual) {+ var positive = new (this.getMatchersClass_())(this.env, actual, this);+ positive.not = new (this.getMatchersClass_())(this.env, actual, this, true);+ return positive;+};++/**+ * Waits a fixed time period before moving to the next block.+ *+ * @deprecated Use waitsFor() instead+ * @param {Number} timeout milliseconds to wait+ */+jasmine.Spec.prototype.waits = function(timeout) {+ var waitsFunc = new jasmine.WaitsBlock(this.env, timeout, this);+ this.addToQueue(waitsFunc);+ return this;+};++/**+ * Waits for the latchFunction to return true before proceeding to the next block.+ *+ * @param {Function} latchFunction+ * @param {String} optional_timeoutMessage+ * @param {Number} optional_timeout+ */+jasmine.Spec.prototype.waitsFor = function(latchFunction, optional_timeoutMessage, optional_timeout) {+ var latchFunction_ = null;+ var optional_timeoutMessage_ = null;+ var optional_timeout_ = null;++ for (var i = 0; i < arguments.length; i++) {+ var arg = arguments[i];+ switch (typeof arg) {+ case 'function':+ latchFunction_ = arg;+ break;+ case 'string':+ optional_timeoutMessage_ = arg;+ break;+ case 'number':+ optional_timeout_ = arg;+ break;+ }+ }++ var waitsForFunc = new jasmine.WaitsForBlock(this.env, optional_timeout_, latchFunction_, optional_timeoutMessage_, this);+ this.addToQueue(waitsForFunc);+ return this;+};++jasmine.Spec.prototype.fail = function (e) {+ var expectationResult = new jasmine.ExpectationResult({+ passed: false,+ message: e ? jasmine.util.formatException(e) : 'Exception',+ trace: { stack: e.stack }+ });+ this.results_.addResult(expectationResult);+};++jasmine.Spec.prototype.getMatchersClass_ = function() {+ return this.matchersClass || this.env.matchersClass;+};++jasmine.Spec.prototype.addMatchers = function(matchersPrototype) {+ var parent = this.getMatchersClass_();+ var newMatchersClass = function() {+ parent.apply(this, arguments);+ };+ jasmine.util.inherit(newMatchersClass, parent);+ jasmine.Matchers.wrapInto_(matchersPrototype, newMatchersClass);+ this.matchersClass = newMatchersClass;+};++jasmine.Spec.prototype.finishCallback = function() {+ this.env.reporter.reportSpecResults(this);+};++jasmine.Spec.prototype.finish = function(onComplete) {+ this.removeAllSpies();+ this.finishCallback();+ if (onComplete) {+ onComplete();+ }+};++jasmine.Spec.prototype.after = function(doAfter) {+ if (this.queue.isRunning()) {+ this.queue.add(new jasmine.Block(this.env, doAfter, this));+ } else {+ this.afterCallbacks.unshift(doAfter);+ }+};++jasmine.Spec.prototype.execute = function(onComplete) {+ var spec = this;+ if (!spec.env.specFilter(spec)) {+ spec.results_.skipped = true;+ spec.finish(onComplete);+ return;+ }++ this.env.reporter.reportSpecStarting(this);++ spec.env.currentSpec = spec;++ spec.addBeforesAndAftersToQueue();++ spec.queue.start(function () {+ spec.finish(onComplete);+ });+};++jasmine.Spec.prototype.addBeforesAndAftersToQueue = function() {+ var runner = this.env.currentRunner();+ var i;++ for (var suite = this.suite; suite; suite = suite.parentSuite) {+ for (i = 0; i < suite.before_.length; i++) {+ this.queue.addBefore(new jasmine.Block(this.env, suite.before_[i], this));+ }+ }+ for (i = 0; i < runner.before_.length; i++) {+ this.queue.addBefore(new jasmine.Block(this.env, runner.before_[i], this));+ }+ for (i = 0; i < this.afterCallbacks.length; i++) {+ this.queue.add(new jasmine.Block(this.env, this.afterCallbacks[i], this));+ }+ for (suite = this.suite; suite; suite = suite.parentSuite) {+ for (i = 0; i < suite.after_.length; i++) {+ this.queue.add(new jasmine.Block(this.env, suite.after_[i], this));+ }+ }+ for (i = 0; i < runner.after_.length; i++) {+ this.queue.add(new jasmine.Block(this.env, runner.after_[i], this));+ }+};++jasmine.Spec.prototype.explodes = function() {+ throw 'explodes function should not have been called';+};++jasmine.Spec.prototype.spyOn = function(obj, methodName, ignoreMethodDoesntExist) {+ if (obj == jasmine.undefined) {+ throw "spyOn could not find an object to spy upon for " + methodName + "()";+ }++ if (!ignoreMethodDoesntExist && obj[methodName] === jasmine.undefined) {+ throw methodName + '() method does not exist';+ }++ if (!ignoreMethodDoesntExist && obj[methodName] && obj[methodName].isSpy) {+ throw new Error(methodName + ' has already been spied upon');+ }++ var spyObj = jasmine.createSpy(methodName);++ this.spies_.push(spyObj);+ spyObj.baseObj = obj;+ spyObj.methodName = methodName;+ spyObj.originalValue = obj[methodName];++ obj[methodName] = spyObj;++ return spyObj;+};++jasmine.Spec.prototype.removeAllSpies = function() {+ for (var i = 0; i < this.spies_.length; i++) {+ var spy = this.spies_[i];+ spy.baseObj[spy.methodName] = spy.originalValue;+ }+ this.spies_ = [];+};++/**+ * Internal representation of a Jasmine suite.+ *+ * @constructor+ * @param {jasmine.Env} env+ * @param {String} description+ * @param {Function} specDefinitions+ * @param {jasmine.Suite} parentSuite+ */+jasmine.Suite = function(env, description, specDefinitions, parentSuite) {+ var self = this;+ self.id = env.nextSuiteId ? env.nextSuiteId() : null;+ self.description = description;+ self.queue = new jasmine.Queue(env);+ self.parentSuite = parentSuite;+ self.env = env;+ self.before_ = [];+ self.after_ = [];+ self.children_ = [];+ self.suites_ = [];+ self.specs_ = [];+};++jasmine.Suite.prototype.getFullName = function() {+ var fullName = this.description;+ for (var parentSuite = this.parentSuite; parentSuite; parentSuite = parentSuite.parentSuite) {+ fullName = parentSuite.description + ' ' + fullName;+ }+ return fullName;+};++jasmine.Suite.prototype.finish = function(onComplete) {+ this.env.reporter.reportSuiteResults(this);+ this.finished = true;+ if (typeof(onComplete) == 'function') {+ onComplete();+ }+};++jasmine.Suite.prototype.beforeEach = function(beforeEachFunction) {+ beforeEachFunction.typeName = 'beforeEach';+ this.before_.unshift(beforeEachFunction);+};++jasmine.Suite.prototype.afterEach = function(afterEachFunction) {+ afterEachFunction.typeName = 'afterEach';+ this.after_.unshift(afterEachFunction);+};++jasmine.Suite.prototype.results = function() {+ return this.queue.results();+};++jasmine.Suite.prototype.add = function(suiteOrSpec) {+ this.children_.push(suiteOrSpec);+ if (suiteOrSpec instanceof jasmine.Suite) {+ this.suites_.push(suiteOrSpec);+ this.env.currentRunner().addSuite(suiteOrSpec);+ } else {+ this.specs_.push(suiteOrSpec);+ }+ this.queue.add(suiteOrSpec);+};++jasmine.Suite.prototype.specs = function() {+ return this.specs_;+};++jasmine.Suite.prototype.suites = function() {+ return this.suites_;+};++jasmine.Suite.prototype.children = function() {+ return this.children_;+};++jasmine.Suite.prototype.execute = function(onComplete) {+ var self = this;+ this.queue.start(function () {+ self.finish(onComplete);+ });+};+jasmine.WaitsBlock = function(env, timeout, spec) {+ this.timeout = timeout;+ jasmine.Block.call(this, env, null, spec);+};++jasmine.util.inherit(jasmine.WaitsBlock, jasmine.Block);++jasmine.WaitsBlock.prototype.execute = function (onComplete) {+ if (jasmine.VERBOSE) {+ this.env.reporter.log('>> Jasmine waiting for ' + this.timeout + ' ms...');+ }+ this.env.setTimeout(function () {+ onComplete();+ }, this.timeout);+};+/**+ * A block which waits for some condition to become true, with timeout.+ *+ * @constructor+ * @extends jasmine.Block+ * @param {jasmine.Env} env The Jasmine environment.+ * @param {Number} timeout The maximum time in milliseconds to wait for the condition to become true.+ * @param {Function} latchFunction A function which returns true when the desired condition has been met.+ * @param {String} message The message to display if the desired condition hasn't been met within the given time period.+ * @param {jasmine.Spec} spec The Jasmine spec.+ */+jasmine.WaitsForBlock = function(env, timeout, latchFunction, message, spec) {+ this.timeout = timeout || env.defaultTimeoutInterval;+ this.latchFunction = latchFunction;+ this.message = message;+ this.totalTimeSpentWaitingForLatch = 0;+ jasmine.Block.call(this, env, null, spec);+};+jasmine.util.inherit(jasmine.WaitsForBlock, jasmine.Block);++jasmine.WaitsForBlock.TIMEOUT_INCREMENT = 10;++jasmine.WaitsForBlock.prototype.execute = function(onComplete) {+ if (jasmine.VERBOSE) {+ this.env.reporter.log('>> Jasmine waiting for ' + (this.message || 'something to happen'));+ }+ var latchFunctionResult;+ try {+ latchFunctionResult = this.latchFunction.apply(this.spec);+ } catch (e) {+ this.spec.fail(e);+ onComplete();+ return;+ }++ if (latchFunctionResult) {+ onComplete();+ } else if (this.totalTimeSpentWaitingForLatch >= this.timeout) {+ var message = 'timed out after ' + this.timeout + ' msec waiting for ' + (this.message || 'something to happen');+ this.spec.fail({+ name: 'timeout',+ message: message+ });++ this.abort = true;+ onComplete();+ } else {+ this.totalTimeSpentWaitingForLatch += jasmine.WaitsForBlock.TIMEOUT_INCREMENT;+ var self = this;+ this.env.setTimeout(function() {+ self.execute(onComplete);+ }, jasmine.WaitsForBlock.TIMEOUT_INCREMENT);+ }+};+// Mock setTimeout, clearTimeout+// Contributed by Pivotal Computer Systems, www.pivotalsf.com++jasmine.FakeTimer = function() {+ this.reset();++ var self = this;+ self.setTimeout = function(funcToCall, millis) {+ self.timeoutsMade++;+ self.scheduleFunction(self.timeoutsMade, funcToCall, millis, false);+ return self.timeoutsMade;+ };++ self.setInterval = function(funcToCall, millis) {+ self.timeoutsMade++;+ self.scheduleFunction(self.timeoutsMade, funcToCall, millis, true);+ return self.timeoutsMade;+ };++ self.clearTimeout = function(timeoutKey) {+ self.scheduledFunctions[timeoutKey] = jasmine.undefined;+ };++ self.clearInterval = function(timeoutKey) {+ self.scheduledFunctions[timeoutKey] = jasmine.undefined;+ };++};++jasmine.FakeTimer.prototype.reset = function() {+ this.timeoutsMade = 0;+ this.scheduledFunctions = {};+ this.nowMillis = 0;+};++jasmine.FakeTimer.prototype.tick = function(millis) {+ var oldMillis = this.nowMillis;+ var newMillis = oldMillis + millis;+ this.runFunctionsWithinRange(oldMillis, newMillis);+ this.nowMillis = newMillis;+};++jasmine.FakeTimer.prototype.runFunctionsWithinRange = function(oldMillis, nowMillis) {+ var scheduledFunc;+ var funcsToRun = [];+ for (var timeoutKey in this.scheduledFunctions) {+ scheduledFunc = this.scheduledFunctions[timeoutKey];+ if (scheduledFunc != jasmine.undefined &&+ scheduledFunc.runAtMillis >= oldMillis &&+ scheduledFunc.runAtMillis <= nowMillis) {+ funcsToRun.push(scheduledFunc);+ this.scheduledFunctions[timeoutKey] = jasmine.undefined;+ }+ }++ if (funcsToRun.length > 0) {+ funcsToRun.sort(function(a, b) {+ return a.runAtMillis - b.runAtMillis;+ });+ for (var i = 0; i < funcsToRun.length; ++i) {+ try {+ var funcToRun = funcsToRun[i];+ this.nowMillis = funcToRun.runAtMillis;+ funcToRun.funcToCall();+ if (funcToRun.recurring) {+ this.scheduleFunction(funcToRun.timeoutKey,+ funcToRun.funcToCall,+ funcToRun.millis,+ true);+ }+ } catch(e) {+ }+ }+ this.runFunctionsWithinRange(oldMillis, nowMillis);+ }+};++jasmine.FakeTimer.prototype.scheduleFunction = function(timeoutKey, funcToCall, millis, recurring) {+ this.scheduledFunctions[timeoutKey] = {+ runAtMillis: this.nowMillis + millis,+ funcToCall: funcToCall,+ recurring: recurring,+ timeoutKey: timeoutKey,+ millis: millis+ };+};++/**+ * @namespace+ */+jasmine.Clock = {+ defaultFakeTimer: new jasmine.FakeTimer(),++ reset: function() {+ jasmine.Clock.assertInstalled();+ jasmine.Clock.defaultFakeTimer.reset();+ },++ tick: function(millis) {+ jasmine.Clock.assertInstalled();+ jasmine.Clock.defaultFakeTimer.tick(millis);+ },++ runFunctionsWithinRange: function(oldMillis, nowMillis) {+ jasmine.Clock.defaultFakeTimer.runFunctionsWithinRange(oldMillis, nowMillis);+ },++ scheduleFunction: function(timeoutKey, funcToCall, millis, recurring) {+ jasmine.Clock.defaultFakeTimer.scheduleFunction(timeoutKey, funcToCall, millis, recurring);+ },++ useMock: function() {+ if (!jasmine.Clock.isInstalled()) {+ var spec = jasmine.getEnv().currentSpec;+ spec.after(jasmine.Clock.uninstallMock);++ jasmine.Clock.installMock();+ }+ },++ installMock: function() {+ jasmine.Clock.installed = jasmine.Clock.defaultFakeTimer;+ },++ uninstallMock: function() {+ jasmine.Clock.assertInstalled();+ jasmine.Clock.installed = jasmine.Clock.real;+ },++ real: {+ setTimeout: jasmine.getGlobal().setTimeout,+ clearTimeout: jasmine.getGlobal().clearTimeout,+ setInterval: jasmine.getGlobal().setInterval,+ clearInterval: jasmine.getGlobal().clearInterval+ },++ assertInstalled: function() {+ if (!jasmine.Clock.isInstalled()) {+ throw new Error("Mock clock is not installed, use jasmine.Clock.useMock()");+ }+ },++ isInstalled: function() {+ return jasmine.Clock.installed == jasmine.Clock.defaultFakeTimer;+ },++ installed: null+};+jasmine.Clock.installed = jasmine.Clock.real;++//else for IE support+jasmine.getGlobal().setTimeout = function(funcToCall, millis) {+ if (jasmine.Clock.installed.setTimeout.apply) {+ return jasmine.Clock.installed.setTimeout.apply(this, arguments);+ } else {+ return jasmine.Clock.installed.setTimeout(funcToCall, millis);+ }+};++jasmine.getGlobal().setInterval = function(funcToCall, millis) {+ if (jasmine.Clock.installed.setInterval.apply) {+ return jasmine.Clock.installed.setInterval.apply(this, arguments);+ } else {+ return jasmine.Clock.installed.setInterval(funcToCall, millis);+ }+};++jasmine.getGlobal().clearTimeout = function(timeoutKey) {+ if (jasmine.Clock.installed.clearTimeout.apply) {+ return jasmine.Clock.installed.clearTimeout.apply(this, arguments);+ } else {+ return jasmine.Clock.installed.clearTimeout(timeoutKey);+ }+};++jasmine.getGlobal().clearInterval = function(timeoutKey) {+ if (jasmine.Clock.installed.clearTimeout.apply) {+ return jasmine.Clock.installed.clearInterval.apply(this, arguments);+ } else {+ return jasmine.Clock.installed.clearInterval(timeoutKey);+ }+};+++jasmine.version_= {+ "major": 2,+ "minor": 0,+ "build": 0,+ "revision": 1315499111,+ "release_candidate": 1+};+
+ lib/jasmine-node/lib/jasmine-node/reporter.js view
@@ -0,0 +1,275 @@+(function() {+ //+ // Imports+ //+ var util;+ try {+ util = require('util')+ } catch(e) {+ util = require('sys')+ }++ if (! jasmineNode) {+ var jasmineNode = {};+ }++ //+ // Helpers+ //+ function noop() {}++ jasmineNode.ANSIColors = {+ pass: function() { return '\033[32m'; }, // Green+ fail: function() { return '\033[31m'; }, // Red+ neutral: function() { return '\033[0m'; } // Normal+ };++ jasmineNode.NoColors = {+ pass: function() { return ''; },+ fail: function() { return ''; },+ neutral: function() { return ''; }+ };++ jasmineNode.TerminalReporter = function(config) {+ this.print_ = config.print || util.print;+ this.color_ = config.color ? jasmineNode.ANSIColors : jasmineNode.NoColors;++ this.started_ = false;+ this.finished_ = false;++ this.callback_ = config.onComplete || false++ this.suites_ = [];+ this.specResults_ = {};+ this.failures_ = [];+ }++ jasmineNode.TerminalReporter.prototype = {+ reportRunnerStarting: function(runner) {+ this.started_ = true;+ this.startedAt = new Date();+ var suites = runner.topLevelSuites();+ for (var i = 0; i < suites.length; i++) {+ var suite = suites[i];+ this.suites_.push(this.summarize_(suite));+ }+ },++ summarize_: function(suiteOrSpec) {+ var isSuite = suiteOrSpec instanceof jasmine.Suite;++ // We could use a separate object for suite and spec+ var summary = {+ id: suiteOrSpec.id,+ name: suiteOrSpec.description,+ type: isSuite? 'suite' : 'spec',+ suiteNestingLevel: 0,+ children: []+ };++ if (isSuite) {+ var calculateNestingLevel = function(examinedSuite) {+ var nestingLevel = 0;+ while (examinedSuite.parentSuite !== null) {+ nestingLevel += 1;+ examinedSuite = examinedSuite.parentSuite;+ }+ return nestingLevel;+ };++ summary.suiteNestingLevel = calculateNestingLevel(suiteOrSpec);++ var children = suiteOrSpec.children();+ for (var i = 0; i < children.length; i++) {+ summary.children.push(this.summarize_(children[i]));+ }+ }++ return summary;+ },++ // This is heavily influenced by Jasmine's Html/Trivial Reporter+ reportRunnerResults: function(runner) {+ this.reportFailures_();++ var results = runner.results();+ var resultColor = (results.failedCount > 0) ? this.color_.fail() : this.color_.pass();++ var specs = runner.specs();+ var specCount = specs.length;++ var message = "\n\nFinished in " + ((new Date().getTime() - this.startedAt.getTime()) / 1000) + " seconds";+ this.printLine_(message);++ // This is what jasmine-html.js has+ //message = "" + specCount + " spec" + ( specCount === 1 ? "" : "s" ) + ", " + results.failedCount + " failure" + ((results.failedCount === 1) ? "" : "s");++ this.printLine_(this.stringWithColor_(this.printRunnerResults_(runner), resultColor));++ this.finished_ = true;+ if(this.callback_) { this.callback_(runner); }+ },++ reportFailures_: function() {+ if (this.failures_.length === 0) {+ return;+ }++ var indent = ' ', failure;+ this.printLine_('\n');++ this.print_('Failures:');++ for (var i = 0; i < this.failures_.length; i++) {+ failure = this.failures_[i];+ this.printLine_('\n');+ this.printLine_(' ' + (i + 1) + ') ' + failure.spec);+ this.printLine_(' Message:');+ this.printLine_(' ' + this.stringWithColor_(failure.message, this.color_.fail()));+ this.printLine_(' Stacktrace:');+ this.print_(' ' + failure.stackTrace);+ }+ },++ reportSuiteResults: function(suite) {+ // Not used in this context+ },++ reportSpecResults: function(spec) {+ var result = spec.results();+ var msg = '';+ if (result.passed()) {+ msg = this.stringWithColor_('.', this.color_.pass());+ // } else if (result.skipped) { TODO: Research why "result.skipped" returns false when "xit" is called on a spec?+ // msg = (colors) ? (ansi.yellow + '*' + ansi.none) : '*';+ } else {+ msg = this.stringWithColor_('F', this.color_.fail());+ this.addFailureToFailures_(spec);+ }+ this.spec_results += msg;+ this.print_(msg);+ },++ addFailureToFailures_: function(spec) {+ var result = spec.results();+ var failureItem = null;++ var items_length = result.items_.length;+ for (var i = 0; i < items_length; i++) {+ if (result.items_[i].passed_ === false) {+ failureItem = result.items_[i];+ var failure = {+ spec: spec.description,+ message: failureItem.message,+ stackTrace: failureItem.trace.stack+ }++ this.failures_.push(failure);+ }+ }+ },++ printRunnerResults_: function(runner){+ var results = runner.results();+ var specs = runner.specs();+ var msg = '';+ msg += specs.length + ' test' + ((specs.length === 1) ? '' : 's') + ', ';+ msg += results.totalCount + ' assertion' + ((results.totalCount === 1) ? '' : 's') + ', ';+ msg += results.failedCount + ' failure' + ((results.failedCount === 1) ? '' : 's') + '\n';+ return msg;+ },++ // Helper Methods //+ stringWithColor_: function(stringValue, color) {+ return (color || this.color_.neutral()) + stringValue + this.color_.neutral();+ },++ printLine_: function(stringValue) {+ this.print_(stringValue);+ this.print_('\n');+ }+ };++ // ***************************************************************+ // TerminalVerboseReporter uses the TerminalReporter's constructor+ // ***************************************************************+ jasmineNode.TerminalVerboseReporter = function(config) {+ jasmineNode.TerminalReporter.call(this, config);+ // The extra field in this object+ this.indent_ = 0;+ }+++ jasmineNode.TerminalVerboseReporter.prototype = {+ reportSpecResults: function(spec) {+ if (spec.results().failedCount > 0) {+ this.addFailureToFailures_(spec);+ }++ this.specResults_[spec.id] = {+ messages: spec.results().getItems(),+ result: spec.results().failedCount > 0 ? 'failed' : 'passed'+ };+ },++ reportRunnerResults: function(runner) {+ var messages = new Array();+ this.buildMessagesFromResults_(messages, this.suites_);++ var messages_length = messages.length;+ for (var i = 0; i < messages_length-1; i++) {+ this.printLine_(messages[i]);+ }++ this.print_(messages[messages_length-1]);++ // Call the parent object's method+ jasmineNode.TerminalReporter.prototype.reportRunnerResults.call(this, runner);+ },++ buildMessagesFromResults_: function(messages, results) {+ var element, specResult, specIndentSpaces, msg = '';++ var results_length = results.length;+ for (var i = 0; i < results_length; i++) {+ element = results[i];++ if (element.type === 'spec') {+ specResult = this.specResults_[element.id.toString()];++ specIndentSpaces = this.indent_ + 2;+ if (specResult.result === 'passed') {+ msg = this.stringWithColor_(this.indentMessage_(element.name, specIndentSpaces), this.color_.pass());+ } else {+ msg = this.stringWithColor_(this.indentMessage_(element.name, specIndentSpaces), this.color_.fail());+ }++ messages.push(msg);+ } else {+ this.indent_ = element.suiteNestingLevel * 2;++ messages.push('');+ messages.push(this.indentMessage_(element.name, this.indent_));+ }++ this.buildMessagesFromResults_(messages, element.children);+ }+ },++ indentMessage_: function(message, indentCount) {+ var _indent = '';+ for (var i = 0; i < indentCount; i++) {+ _indent += ' ';+ }+ return (_indent + message);+ }+ };++ // Inherit from TerminalReporter+ jasmineNode.TerminalVerboseReporter.prototype.__proto__ = jasmineNode.TerminalReporter.prototype;++ //+ // Exports+ //+ exports.jasmineNode = jasmineNode;+})();
+ lib/jasmine-node/lib/jasmine-node/requirejs-runner.js view
@@ -0,0 +1,80 @@+exports.executeJsRunner = function(specCollection, done, jasmineEnv) {+ var specs,+ specLoader = require('./requirejs-spec-loader'),+ requirejs = require('requirejs'),+ vm = require('vm'),+ fs = require('fs'),+ template = fs.readFileSync(__dirname + '/requirejs-wrapper-template.js', 'utf8'),+ buildNewContext = function(spec){+ var context = {+ describe: describe,+ it: it,+ xdescribe: xdescribe,+ xit: xit,+ beforeEach: beforeEach,+ spyOn: spyOn,+ waitsFor: waitsFor,+ runs: runs,+ jasmine: jasmine,+ expect: expect,+ require: require,+ console: console,+ process: process,+ module: module,+ specLoader: specLoader,+ __dirname: spec.directory(),+ __filename: spec.path()+ };++ context.global = context;++ return context;+ },+ buildRelativeDirName = function(dir){+ var retVal = "",+ thisDir = process.cwd(),+ toDir = dir.split('/'),+ index = 0,+ colonMatches = __dirname.match(/^.:/);++ for(var i = 0; i < (colonMatches && colonMatches.length) || 0; i++){+ thisDir = thisDir.replace(colonMatches[i], '\\' + colonMatches[i].substring(0,1));+ }++ thisDir = thisDir.replace(/\\/g, '/').split('/');++ for(; index < thisDir.length || index < toDir.length; index++) {+ if(thisDir[index] != toDir[index]){+ for(var i = index; i < thisDir.length-1; i++){+ retVal += '../';+ }++ for(var i = index; i < toDir.length; i++){+ retVal += toDir[i] + '/';+ }++ break;+ }+ }++ return retVal.trim('/');+ };++ specCollection.getSpecs().forEach(function(s){+ var script = fs.readFileSync(s.path(), 'utf8'),+ dir = s.directory(),+ colonMatches = dir.match(/.:/),+ wrappedScript;++ for(var i = 0; i < (colonMatches && colonMatches.length) || 0; i++){+ dir = dir.replace(colonMatches[i], '/' + colonMatches[i].substring(0,1));+ }++ wrappedScript = template.replace(/#REPLACE URL#/, buildRelativeDirName(dir))+ .replace(/#REPLACE TEST SCRIPT#/, script);++ vm.runInNewContext(wrappedScript, buildNewContext(s), s.path());+ });++ specLoader.executeWhenAllSpecsAreComplete(jasmineEnv);+};
+ lib/jasmine-node/lib/jasmine-node/requirejs-spec-loader.js view
@@ -0,0 +1,48 @@+var _ = require('underscore'),+ registry = {},+ timeout = 120000,+ now = function() {+ return new Date().getTime();+ },+ loader = {+ register: function(name) {+ registry[name] = false;+ },+ completed: function(name){+ registry[name] = true;+ }+ },+ specLoader = {+ defineLoader: function(requirejs) {+ requirejs.define('jasmine-spec-loader', function() {+ return loader;+ });+ },+ executeWhenAllSpecsAreComplete: function(jasmineEnv) {+ var allComplete = false,+ wait = now(),+ timeoutCallback = function() {+ allComplete = _.all(registry, function(value) {+ return value;+ });++ if(!allComplete && wait + timeout > now()) {+ setTimeout(timeoutCallback, 100);+ } else if (!allComplete) {+ console.log('Failed to load all specs within timeout window.');+ process.exit(-1);+ } else {+ jasmineEnv.execute();+ }+ };++ setTimeout(timeoutCallback, 100);+ },+ setTimeoutInterval: function(value) {+ timeout = value;+ },+ };++for(var key in specLoader) {+ exports[key] = specLoader[key];+}
+ lib/jasmine-node/lib/jasmine-node/requirejs-wrapper-template.js view
@@ -0,0 +1,65 @@+var test = function(require, define, undefined) { #REPLACE TEST SCRIPT# +};++var requirejsOrig = require('requirejs'),+ ostring = Object.prototype.toString,+ path = require('path'),+ baseUrl = '#REPLACE URL#',+ isArray = function(it){+ return ostring.call(it) === '[object Array]';+ },+ isFunction = function(it){+ return ostring.call(it) === '[object Function]';+ },+ requirejs = function(deps, callback){+ var retVal;++ if(!isArray(deps) && typeof deps !== 'string'){+ if(isArray(callback)){+ retVal = requirejsOrig(deps, callback, arguments[2]);+ } else {+ retVal = requirejsOrig(deps, [], callback);+ }+ } else {+ retVal = requirejsOrig(deps, callback);+ }++ return retVal;+ };++requirejsOrig.config({+ baseUrl: baseUrl,+ nodeRequire: require+});++for(var key in requirejsOrig) {+ requirejs[key] = requirejsOrig[key];+}++requirejs.config = function(config){+ var alteredConfig = {};++ for(var key in config) {+ alteredConfig[key] = config[key];+ }++ if(alteredConfig.baseUrl){+ var base = baseUrl.replace(/\\/g, '/'),+ splitUrl = alteredConfig.baseUrl.replace(/\\/g, '/').split('/'),+ index = 0;++ for(; index < splitUrl.length; index++){+ if(splitUrl[index] === '..'){+ base = path.dirname(base);+ } else {+ base += '/' + splitUrl[index];+ }+ }++ alteredConfig.baseUrl = base;+ }++ return requirejsOrig.config(alteredConfig);+};++test(requirejs, requirejs.define);
+ lib/jasmine-node/lib/jasmine-node/spec-collection.js view
@@ -0,0 +1,35 @@+var walkdir = require('walkdir');+var path = require('path');+var fs = require('fs');+var specs = [];++var createSpecObj = function(path, root) {+ return {+ path: function() { return path; },+ relativePath: function() { return path.replace(root, '').replace(/^[\/\\]/, '').replace(/\\/g, '/'); },+ directory: function() { return path.replace(/[\/\\][\s\w\.-]*$/, "").replace(/\\/g, '/'); },+ relativeDirectory: function() { return relativePath().replace(/[\/\\][\s\w\.-]*$/, "").replace(/\\/g, '/'); },+ filename: function() { return path.replace(/^.*[\\\/]/, ''); }+ };+};++exports.load = function(loadpath, matcher) {+ var wannaBeSpecs = walkdir.sync(loadpath)++ for (var i = 0; i < wannaBeSpecs.length; i++) {+ var file = wannaBeSpecs[i];+ try {+ if (fs.statSync(file).isFile()) {+ if (!/.*node_modules.*/.test(file) && matcher.test(path.basename(file))) {+ specs.push(createSpecObj(file));+ }+ }+ } catch(e) {+ // nothing to do here+ }+ }+};++exports.getSpecs = function() {+ return specs;+};
+ lib/jasmine-node/package.json view
@@ -0,0 +1,29 @@+{+ "name" : "jasmine-node"+, "version" : "1.0.26"+, "description" : "DOM-less simple JavaScript BDD testing framework for Node"+, "homepage" : [ "http://pivotal.github.com/jasmine"+ , "https://github.com/mhevery/jasmine-node"]+, "repository" : { "type" : "git"+ , "url" : "https://github.com/mhevery/jasmine-node.git"+ }+, "keywords" : ["testing", "bdd"]+, "author" : "Misko Hevery <misko@hevery.com>"+, "contributors" : [ "Rajan Agaskar <rajan@pivotallabs.com"+ , "Christian Williams <xian@pivotallabs.com"+ , "Davis W. Frank <dwfrank@pivotallabs.com>"+ , "Matteo Collina <matteo.collina@gmail.com>"+ ]+, "maintainers" : "Martin Häger <martin.haeger@gmail.com>"+, "contributors" : [ "Mike Swift <theycallmeswift@gmail.com> (http://theycallmeswift.com)" ]+, "licenses" : ["MIT"]+, "dependencies" : { "coffee-script" : ">=1.0.1"+ , "jasmine-reporters" : ">=0.2.0"+ , "requirejs" : ">=0.27.1"+ , "walkdir" : ">= 0.0.1"+ , "underscore" : ">= 1.3.1"+ }+, "bin" : "bin/jasmine-node"+, "main" : "lib/jasmine-node"+, "scripts" : { "test" : "node lib/jasmine-node/cli.js spec" }+}
+ lib/jasmine-node/scripts/specs view
@@ -0,0 +1,37 @@+#!/bin/bash++entry="node lib/jasmine-node/cli.js "++if [ $# -ne 0 ]; then+ command=$entry"$1 spec"+ echo $command+ $command+else+ echo "Running all tests located in the spec directory"+ command=$entry"spec"+ echo $command+ time $command #/nested/uber-nested+ echo -e "\033[1;35m--- Should have 40 tests and 71 assertions and 1 Failure. ---\033[0m"+ echo ""++ echo "Running all tests located in the spec directory with coffee option"+ command=$entry"--coffee spec"+ echo $command+ time $command #/nested/uber-nested+ echo -e "\033[1;35m--- Should have 40 tests and 71 assertions and 1 Failure. ---\033[0m"+ echo ""++ echo "Running all tests located in the spec directory with requirejs option"+ #command=$entry"--nohelpers --runWithRequireJs spec-requirejs"+ command=$entry"--runWithRequireJs spec"+ echo $command+ time $command+ echo -e "\033[1;35m--- Should have 40 tests and 71 assertions and 1 Failure. ---\033[0m"++ echo "Running all tests located in the spec-requirejs directory with requirejs"+ #command=$entry"--nohelpers --runWithRequireJs spec-requirejs"+ command=$entry"--runWithRequireJs spec-requirejs"+ echo $command+ time $command+ echo -e "\033[1;35m--- Should have 1 test and 2 assertions and 0 Failures. ---\033[0m"+fi
+ lib/jasmine-node/spec-requirejs/requirejs.spec.js view
@@ -0,0 +1,8 @@+require(['requirejs.sut'], function(sut){+ describe('RequireJs basic tests', function(){+ it('should load sut', function(){+ expect(sut.name).toBe('Subject To Test');+ expect(sut.method(2)).toBe(3);+ });+ });+});
+ lib/jasmine-node/spec-requirejs/requirejs.sut.js view
@@ -0,0 +1,8 @@+define(function(){+ return {+ name: 'Subject To Test',+ method: function(input){+ return 1+input;+ }+ };+});
+ lib/jasmine-node/spec/AsyncSpec.coffee view
@@ -0,0 +1,7 @@+#=============================================================================+# Async spec, that will be time outed+#=============================================================================+describe 'async', ->+ it 'should be timed out', ->+ waitsFor (-> false), 'MIRACLE', 500+
+ lib/jasmine-node/spec/CoffeeSpec.coffee view
@@ -0,0 +1,4 @@+describe 'jasmine-node', ->++ it 'should pass', ->+ expect(1+2).toEqual(3)
+ lib/jasmine-node/spec/GrammarHelper.coffee view
@@ -0,0 +1,22 @@+global.testClass = (description, specDefinitions) ->+ suite = jasmine.getEnv().describe('Class: ' + description, specDefinitions)+ suite.tags = ['class']+ suite.isIntermediate = true;+ suite++global.feature = (description, specDefinitions) ->+ suite = jasmine.getEnv().describe('Feature: ' + description, specDefinitions)+ suite.tags = ['feature']+ suite.isIntermediate = true;+ suite++global.scenario = (desc, func) ->+ suite = jasmine.getEnv().describe('Scenario: ' + desc, func)+ suite.tags = ['scenario']+ suite.isIntermediate = true;+ suite++global.should = (description, specDefinitions) ->+ suite = jasmine.getEnv().it('It should ' + description, specDefinitions)+ suite.tags = ['should']+ suite
+ lib/jasmine-node/spec/HelperSpec.coffee view
@@ -0,0 +1,6 @@++testClass 'HelperLoader', ->+ feature 'Loading order', ->+ should 'load the helpers before the specs.', ->+ expect(true).toBeTruthy()+ # will fail to parse the spec if the helper was not loaded first
+ lib/jasmine-node/spec/SampleSpecs.js view
@@ -0,0 +1,25 @@+describe('jasmine-node', function(){++ it('should pass', function(){+ expect(1+2).toEqual(3);+ });++ it('shows asynchronous test', function(){+ setTimeout(function(){+ expect('second').toEqual('second');+ asyncSpecDone();+ }, 1);+ expect('first').toEqual('first');+ asyncSpecWait();+ });++ it('shows asynchronous test node-style', function(done){+ setTimeout(function(){+ expect('second').toEqual('second');+ // If you call done() with an argument, it will fail the spec + // so you can use it as a handler for many async node calls+ done();+ }, 1);+ expect('first').toEqual('first');+ });+});
+ lib/jasmine-node/spec/TestSpec.js view
@@ -0,0 +1,5 @@+describe('jasmine-node-flat', function(){+ it('should pass', function(){+ expect(1+2).toEqual(3);+ });+});
+ lib/jasmine-node/spec/async-callback_spec.js view
@@ -0,0 +1,150 @@+describe('async-callback', function() {+ var env;+ beforeEach(function() {+ env = new jasmine.Env();+ });++ describe('it', function() {++ it("should time out if callback is not called", function() {+ env.describe("it", function() {+ env.it("doesn't wait", function(done) {+ expect(1+2).toEqual(3);+ });+ });++ env.currentRunner().execute();++ waitsFor(function() {+ return env.currentRunner().results().totalCount > 0;+ }, 6000);++ runs(function() {+ expect(env.currentRunner().results().failedCount).toEqual(1);+ expect(firstResult(env.currentRunner()).message).toMatch(/timeout/);;+ });+ });++ it("should accept timeout for individual spec", function() {+ env.describe("it", function() {+ env.it("doesn't wait", function(done) {+ expect(1+2).toEqual(3);+ }, 250);+ });++ env.currentRunner().execute();++ waitsFor(function() {+ return env.currentRunner().results().totalCount > 0;+ }, 500);++ runs(function() {+ expect(env.currentRunner().results().failedCount).toEqual(1);+ expect(firstResult(env.currentRunner()).message).toMatch(/timeout/);;+ });+ });++ it("should fail if callback is passed error", function() {+ env.describe("it", function() {+ env.it("doesn't wait", function(done) {+ process.nextTick(function() {+ done("Failed asynchronously");+ });+ });+ });++ env.currentRunner().execute();++ waitsFor(function() {+ return env.currentRunner().results().totalCount > 0;+ });++ runs(function() {+ expect(env.currentRunner().results().failedCount).toEqual(1);+ expect(firstResult(env.currentRunner()).message).toEqual("Failed asynchronously");+ });+ });+ ++ it("should finish after callback is called", function() {+ env.describe("it", function() {+ env.it("waits", function(done) {+ process.nextTick(function() {+ env.currentSpec.expect(1+2).toEqual(3);+ done();+ });+ });+ });++ env.currentRunner().execute();++ waitsFor(function() {+ return env.currentRunner().results().totalCount > 0;+ }, 2000);++ runs(function() {+ expect(env.currentRunner().results().passedCount).toEqual(1);+ });+ });++ });++ describe("beforeEach", function() {+ it("should wait for callback", function() {+ env.describe("beforeEach", function() {+ var waited = false;+ env.beforeEach(function(done) {+ process.nextTick(function() {+ waited = true;+ done();+ });+ });+ env.it("waited", function() {+ env.currentSpec.expect(waited).toBeTruthy();+ });+ });++ env.currentRunner().execute();++ waitsFor(function() {+ return env.currentRunner().results().totalCount > 0;+ });++ runs(function() {+ expect(env.currentRunner().results().passedCount).toEqual(1);+ });+ });+ });++ describe("afterEach", function() {+ it("should be passed async callback", function() {+ var completed = false;+ env.describe("afterEach", function() {+ env.afterEach(function(done) {+ process.nextTick(function() {+ done('Failed in afterEach');+ completed = true;+ });+ });+ env.it("should pass", function() {+ this.expect(1+2).toEqual(3);+ });+ });++ env.currentRunner().execute();++ waitsFor(function() {+ return completed === true;+ });++ runs(function() {+ expect(env.currentRunner().results().passedCount).toEqual(1);+ expect(env.currentRunner().results().failedCount).toEqual(1);+ });+ });+ });+});++function firstResult(runner) {+ return runner.results().getItems()[0].getItems()[0].getItems()[0];+}
+ lib/jasmine-node/spec/helper_spec.js view
@@ -0,0 +1,7 @@+describe("helper", function() {+ it("should load the helpers", function() {+ var expectation= expect(true);+ + expect(typeof(expectation.toHaveProperty)).toBe('function');+ });+});
+ lib/jasmine-node/spec/nested.js/NestedSpec.js view
@@ -0,0 +1,5 @@+describe('jasmine-node-nested.js', function(){+ it('should pass', function(){+ expect(1+2).toEqual(3);+ });+});
+ lib/jasmine-node/spec/nested/NestedSpec.js view
@@ -0,0 +1,5 @@+describe('jasmine-node-nested', function(){+ it('should pass', function(){+ expect(1+2).toEqual(3);+ });+});
+ lib/jasmine-node/spec/nested/uber-nested/UberNestedSpec.js view
@@ -0,0 +1,11 @@+describe('jasmine-node-uber-nested', function(){+ it('should pass', function(){+ expect(1+2).toEqual(3);+ });++ describe('failure', function(){+ it('should report failure (THIS IS EXPECTED)', function(){+ expect(true).toBeFalsy();+ });+ });+});
+ lib/jasmine-node/spec/reporter_spec.js view
@@ -0,0 +1,432 @@+var jasmineNode = require(__dirname + "/../lib/jasmine-node/reporter").jasmineNode;++describe('TerminalReporter', function() {+ beforeEach(function() {+ var config = {}+ this.reporter = new jasmineNode.TerminalReporter(config);+ });++ describe("initialize", function() {+ it('initializes print_ from config', function() {+ var config = { print: true };+ this.reporter = new jasmineNode.TerminalReporter(config);+ expect(this.reporter.print_).toBeTruthy();+ });++ it('initializes color_ from config', function() {+ var config = { color: true }+ this.reporter = new jasmineNode.TerminalReporter(config);+ expect(this.reporter.color_).toEqual(jasmineNode.ANSIColors);+ });++ it('sets the started_ flag to false', function() {+ var config = {}+ this.reporter = new jasmineNode.TerminalReporter(config);+ expect(this.reporter.started_).toBeFalsy();+ });++ it('sets the finished_ flag to false', function() {+ var config = {}+ this.reporter = new jasmineNode.TerminalReporter(config);+ expect(this.reporter.finished_).toBeFalsy();+ });++ it('initializes the suites_ array', function() {+ var config = {}+ this.reporter = new jasmineNode.TerminalReporter(config);+ expect(this.reporter.suites_.length).toEqual(0);+ });++ it('initializes the specResults_ to an Object', function() {+ var config = {}+ this.reporter = new jasmineNode.TerminalReporter(config);+ expect(this.reporter.specResults_).toBeDefined();+ });++ it('initializes the failures_ array', function() {+ var config = {}+ this.reporter = new jasmineNode.TerminalReporter(config);+ expect(this.reporter.failures_.length).toEqual(0);+ });++ it('sets the callback_ property to false by default', function() {+ var config = {}+ this.reporter = new jasmineNode.TerminalReporter(config);+ expect(this.reporter.callback_).toEqual(false)+ });++ it('sets the callback_ property to onComplete if supplied', function() {+ var foo = function() { }+ var config = { onComplete: foo }+ this.reporter = new jasmineNode.TerminalReporter(config);+ expect(this.reporter.callback_).toBe(foo)+ });+ });++ describe('when the report runner starts', function() {+ beforeEach(function() {+ this.spy = spyOn(this.reporter, 'printLine_');++ var runner = {+ topLevelSuites: function() {+ var suites = [];+ var suite = { id: 25 };+ suites.push(suite);+ return suites;+ }+ };+ this.reporter.reportRunnerStarting(runner);+ });++ it('sets the started_ field to true', function() {+ expect(this.reporter.started_).toBeTruthy();+ });++ it('sets the startedAt field', function() {+ expect(this.reporter.startedAt instanceof Date).toBeTruthy();+ });++ it('buildes the suites_ collection', function() {+ expect(this.reporter.suites_.length).toEqual(1);+ expect(this.reporter.suites_[0].id).toEqual(25);+ });+ });++ describe('the summarize_ creates suite and spec tree', function() {+ beforeEach(function() {+ this.spec = {+ id: 1,+ description: 'the spec',+ isSuite: false+ }+ });++ it('creates a summary object from spec', function() {+ var result = this.reporter.summarize_(this.spec);++ expect(result.id).toEqual(1);+ expect(result.name).toEqual('the spec');+ expect(result.type).toEqual('spec');+ expect(result.children.length).toEqual(0);+ });++ it('creates a summary object from suite with 1 spec', function() {+ var env = { nextSuiteId: false }+ var suite = new jasmine.Suite(env, 'suite name', undefined, undefined);+ suite.description = 'the suite';+ suite.parentSuite = null;+ suite.children_.push(this.spec);++ var result = this.reporter.summarize_(suite);+ expect(result.name).toEqual('the suite');+ expect(result.type).toEqual('suite');+ expect(result.children.length).toEqual(1);++ var suiteChildSpec = result.children[0];+ expect(suiteChildSpec.id).toEqual(1);+ });+ });++ describe('reportRunnerResults', function() {+ beforeEach(function() {+ this.printLineSpy = spyOn(this.reporter, 'printLine_');+ });++ it('generates the report', function() {+ var failuresSpy = spyOn(this.reporter, 'reportFailures_');+ var printRunnerResultsSpy = spyOn(this.reporter, 'printRunnerResults_').+ andReturn('this is the runner result');++ var callbackSpy = spyOn(this.reporter, 'callback_');++ var runner = {+ results: function() {+ var result = { failedCount: 0 };+ return result;+ },+ specs: function() { return []; }+ };+ this.reporter.startedAt = new Date();++ this.reporter.reportRunnerResults(runner);++ expect(failuresSpy).toHaveBeenCalled();+ expect(this.printLineSpy).toHaveBeenCalled();+ expect(callbackSpy).toHaveBeenCalled();+ });+ });++ describe('reportSpecResults', function() {+ beforeEach(function() {+ this.printSpy = spyOn(this.reporter, 'print_');+ this.spec = {+ id: 1,+ description: 'the spec',+ isSuite: false,+ results: function() {+ var result = {+ passed: function() { return true; }+ }+ return result;+ }+ }+ });++ it('prints a \'.\' for pass', function() {+ this.reporter.reportSpecResults(this.spec);+ expect(this.printSpy).toHaveBeenCalledWith('.');+ });++ it('prints an \'F\' for failure', function() {+ var addFailureToFailuresSpy = spyOn(this.reporter, 'addFailureToFailures_');+ var results = function() {+ var result = {+ passed: function() { return false; }+ }+ return result;+ }+ this.spec.results = results;++ this.reporter.reportSpecResults(this.spec);++ expect(this.printSpy).toHaveBeenCalledWith('F');+ expect(addFailureToFailuresSpy).toHaveBeenCalled();+ });+ });++ describe('addFailureToFailures', function() {+ it('adds message and stackTrace to failures_', function() {+ var spec = {+ description: 'the spec',+ results: function() {+ var result = {+ items_: function() {+ var theItems = new Array();+ var item = {+ passed_: false,+ message: 'the message',+ trace: {+ stack: 'the stack'+ }+ }+ theItems.push(item);+ return theItems;+ }.call()+ };+ return result;+ }+ };++ this.reporter.addFailureToFailures_(spec);++ var failures = this.reporter.failures_;+ expect(failures.length).toEqual(1);+ var failure = failures[0];+ expect(failure.spec).toEqual('the spec');+ expect(failure.message).toEqual('the message');+ expect(failure.stackTrace).toEqual('the stack');+ });+ });++ describe('prints the runner results', function() {+ beforeEach(function() {+ this.runner = {+ results: function() {+ var _results = {+ totalCount: 23,+ failedCount: 52+ };+ return _results;+ },+ specs: function() {+ var _specs = new Array();+ _specs.push(1);+ return _specs;+ }+ };+ });++ it('uses the specs\'s length, totalCount and failedCount', function() {+ var message = this.reporter.printRunnerResults_(this.runner);+ expect(message).toEqual('1 test, 23 assertions, 52 failures\n');+ });+ });++ describe('reports failures', function() {+ beforeEach(function() {+ this.printSpy = spyOn(this.reporter, 'print_');+ this.printLineSpy = spyOn(this.reporter, 'printLine_');+ });++ it('does not report anything when there are no failures', function() {+ this.reporter.failures_ = new Array();++ this.reporter.reportFailures_();++ expect(this.printLineSpy).not.toHaveBeenCalled();+ });++ it('prints the failures', function() {+ var failure = {+ spec: 'the spec',+ message: 'the message',+ stackTrace: 'the stackTrace'+ }++ this.reporter.failures_ = new Array();+ this.reporter.failures_.push(failure);++ this.reporter.reportFailures_();++ var generatedOutput =+ [ [ '\n' ],+ [ '\n' ],+ [ ' 1) the spec' ],+ [ ' Message:' ],+ [ ' the message' ],+ [ ' Stacktrace:' ] ];++ expect(this.printLineSpy).toHaveBeenCalled();+ expect(this.printLineSpy.argsForCall).toEqual(generatedOutput);++ expect(this.printSpy).toHaveBeenCalled();+ expect(this.printSpy.argsForCall[0]).toEqual(['Failures:']);+ expect(this.printSpy.argsForCall[1]).toEqual([' the stackTrace']);+ });+ });+});++describe('TerminalVerboseReporter', function() {+ beforeEach(function() {+ var config = {}+ this.verboseReporter = new jasmineNode.TerminalVerboseReporter(config);+ this.addFailureToFailuresSpy = spyOn(this.verboseReporter, 'addFailureToFailures_');+ this.spec = {+ id: 23,+ results: function() {+ return {+ failedCount: 1,+ getItems: function() {+ return ["this is the message"];+ }+ }+ }+ };+ });++ describe('#reportSpecResults', function() {+ it('adds the spec to the failures_', function() {+ this.verboseReporter.reportSpecResults(this.spec);++ expect(this.addFailureToFailuresSpy).toHaveBeenCalledWith(this.spec);+ });++ it('adds a new object to the specResults_', function() {+ this.verboseReporter.reportSpecResults(this.spec);++ expect(this.verboseReporter.specResults_[23].messages).toEqual(['this is the message']);+ expect(this.verboseReporter.specResults_[23].result).toEqual('failed');+ });+ });++ describe('#buildMessagesFromResults_', function() {+ beforeEach(function() {+ this.suite = {+ type: 'suite',+ name: 'a describe block',+ suiteNestingLevel: 0,+ children: []+ };++ this.spec = {+ id: 23,+ type: 'spec',+ name: 'a spec block',+ children: []+ };++ this.verboseReporter.specResults_['23'] = {+ result: 'passed'+ };++ });++ it('does not build anything when the results collection is empty', function() {+ var results = [],+ messages = [];++ this.verboseReporter.buildMessagesFromResults_(messages, results);++ expect(messages.length).toEqual(0);+ });++ it('adds a single suite to the messages', function() {+ var results = [],+ messages = [];++ results.push(this.suite);++ this.verboseReporter.buildMessagesFromResults_(messages, results);++ expect(messages.length).toEqual(2);+ expect(messages[0]).toEqual('');+ expect(messages[1]).toEqual('a describe block');+ });++ it('adds a single spec with success to the messages', function() {+ var results = [],+ messages = [];++ this.passSpy = spyOn(this.verboseReporter.color_, 'pass');++ results.push(this.spec);++ this.verboseReporter.buildMessagesFromResults_(messages, results);++ expect(this.passSpy).toHaveBeenCalled();+ expect(messages.length).toEqual(1);+ expect(messages[0]).toEqual(' a spec block');+ });++ it('adds a single spec with failure to the messages', function() {+ var results = [],+ messages = [];++ this.verboseReporter.specResults_['23'].result = 'failed';++ this.passSpy = spyOn(this.verboseReporter.color_, 'pass');+ this.failSpy = spyOn(this.verboseReporter.color_, 'fail');++ results.push(this.spec);++ this.verboseReporter.buildMessagesFromResults_(messages, results);++ expect(this.failSpy).toHaveBeenCalled();+ expect(this.passSpy).not.toHaveBeenCalled();+ });++ it('adds a suite, a suite and a single spec with success to the messages', function() {+ var results = [],+ messages = [];++ var subSuite = new Object();+ subSuite.type = 'suite';+ subSuite.name = 'a sub describe block';+ subSuite.suiteNestingLevel = 1;+ subSuite.children = [];+ subSuite.children.push(this.spec);++ this.suite.children.push(subSuite);+ results.push(this.suite);++ this.verboseReporter.buildMessagesFromResults_(messages, results);++ expect(messages.length).toEqual(5);+ expect(messages[0]).toEqual('');+ expect(messages[1]).toEqual('a describe block');+ expect(messages[2]).toEqual('');+ expect(messages[3]).toEqual(' a sub describe block');+ expect(messages[4]).toEqual(' a spec block');+ });+ });+});
+ lib/jasmine-node/spec/sample_helper.js view
@@ -0,0 +1,19 @@+(function(){++ var objectToString = Object.prototype.toString;+ var PRIMITIVE_TYPES = [String, Number, RegExp, Boolean, Date];++ beforeEach(function(){+ this.addMatchers({+ toHaveProperty: function(prop) {+ try {+ return prop in this.actual;+ }+ catch (e) {+ return false;+ }+ }+ });+ });++})();
+ lib/jasmine-node/specs.sh view
@@ -0,0 +1,24 @@+#!/usr/bin/env bash++entry="node lib/jasmine-node/cli.js "++echo "Running all tests located in the spec directory"+command=$entry"spec"+echo $command+time $command #/nested/uber-nested+echo -e "\033[1;35m--- Should have 40 tests and 74 assertions and 1 Failure. ---\033[0m"+echo ""++echo "Running all tests located in the spec directory with coffee option"+command=$entry"--coffee spec"+echo $command+time $command #/nested/uber-nested+echo -e "\033[1;35m--- Should have 43 tests and 77 assertions and 2 Failures. ---\033[0m"+echo ""++echo "Running all tests located in the spec directory with requirejs option"+#command=$entry"--nohelpers --runWithRequireJs spec-requirejs"+command=$entry"--runWithRequireJs ./"+echo $command+time $command+echo -e "\033[1;35m--- Should have 41 tests and 76 assertions and 1 Failure. ---\033[0m"
+ lib/js/coda.css view
@@ -0,0 +1,25 @@+/* Coda scheme ported from TextMate to google prettify */++pre.prettyprint { padding: 5px; border-left: 5px solid #939393; +border-width: 0 0 0 5px !important;}+pre .nocode { background-color: none; color: #000 }+pre .str { color: #731318; } /* string */+pre .kwd { color: #8C1751;} /* keyword */+pre .com { color: #256D24; } /* comment */+pre .typ { color: #000; } /* type */+pre .lit { color: #000;} /* literal */+pre .pun { color: #000 } /* punctuation */+pre .pln { color: #000 } /* plaintext */+pre .tag { color: #861681;} /* html/xml tag */+pre .atn { color: #C5680C;} /* attribute name */+pre .atv { color: #221AA6;} /* attribute value */+pre .dec { color: #1F00FF; } /* decimal */++/* Specify class=linenums on a pre to get line numbering */+ol.linenums { margin-top: 0; margin-bottom: 0; +color: #333; } +/* IE indents via margin-left */+li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8 {+ list-style-type: none }+/* Alternate shading for lines */+li.L1,li.L3,li.L5,li.L7,li.L9 {background: #eee;}
+ lib/js/console.js view
@@ -0,0 +1,179 @@++// (function() {+// if (! jasmine) {+// throw new Exception("jasmine library does not exist in global namespace!");+// }++// var console = { log: global.console.log }+// var messages = []++// global.console.log = function() {}++// /**+// * Basic reporter that outputs spec results to the browser console.+// * Useful if you need to test an html page and don't want the TrivialReporter+// * markup mucking things up.+// *+// * Usage:+// *+// * jasmine.getEnv().addReporter(new jasmine.ConsoleReporter());+// * jasmine.getEnv().execute();+// */+// var ConsoleReporter = function() {+// this.started = false;+// this.finished = false;+// };++// ConsoleReporter.prototype = {+// reportRunnerResults: function(runner) {+// if (this.hasGroupedConsole()) {+// var suites = runner.suites();+// startGroup(runner.results(), 'tests');+// for (var i in suites) {+// if (!suites[i].parentSuite) {+// suiteResults(suites[i]);+// }+// }+// console.groupEnd();+// }+// else {+// var dur = (new Date()).getTime() - this.start_time;+// var failed = this.executed_specs - this.passed_specs;+// var spec_str = this.executed_specs + (this.executed_specs === 1 ? " spec, " : " specs, ");+// var fail_str = failed + (failed === 1 ? " failure in " : " failures in ");+// var red = (failed > 0) ? "\033[31m" : "\033[32m"+// this.log(red);+// this.log(spec_str + fail_str + (dur/1000) + "s.\033[0m");+// if (failed > 0) {+// process.stdout.write("\r[\033[31mX\033[0m] Running Tests\n\n")+// for (msg in messages) { process.stdout.write(messages[msg]) }+// process.exit(1)+// } else {+// process.stdout.write("\r[\033[32m*\033[0m] Running Tests\n")+// }++// }+// this.finished = true;+// },++// hasGroupedConsole: function() {+// var console = jasmine.getGlobal().console;+// return console && console.info && console.warn && console.group && console.groupEnd && console.groupCollapsed;+// },++// reportRunnerStarting: function(runner) {+// this.started = true;+// if (!this.hasGroupedConsole()) {+// this.start_time = (new Date()).getTime();+// this.executed_specs = 0;+// this.passed_specs = 0;+// process.stdout.write("[ ] Running Tests");+// }+// },++// reportSpecResults: function(spec) {+// if (!this.hasGroupedConsole()) {+// var resultText = "\033[31mFailure\033[0m";+// var x = spec.results()+// if (x.passed()) {+// this.passed_specs++;+// } else {+// messages.push("Test failed: " + spec.description.split("::")[1] + "\n" +// + " at line " +// + (parseInt(spec.description.split("::")[0].split("_")[0]) + 1)+// + "\n\n"+// + " Expected " + JSON.stringify(spec.results_.items_[0].expected)+// + "\n Actual " + JSON.stringify(spec.results_.items_[0].actual) + "\n\n");+// this.log(resultText + " in " + spec.suite.description + "\n" + spec.description);+// this.log(x.items_[0].message)+// }+// }+// },++// reportSpecStarting: function(spec) {+// if (!this.hasGroupedConsole()) {+// this.executed_specs++;+// //this.log(spec.suite.description + ' : ' + spec.description + ' ... ');+// }+// },++// reportSuiteResults: function(suite) {+// if (!this.hasGroupedConsole()) {+// var results = suite.results();+// var red = (results.passedCount < results.totalCount) ? "\033[31m" : "\033[32m"+ +// this.log(red + suite.description + ": " + results.passedCount + " of " + results.totalCount + " passed.\033[0m");+// }+// },++// log: function(str) {+// var console = jasmine.getGlobal().console;+// if (console && console.log) {+// console.log(str);+// }+// }+// };++// function suiteResults(suite) {+// var results = suite.results();+// startGroup(results, suite.description);+// var specs = suite.specs();+// for (var i in specs) {+// if (specs.hasOwnProperty(i)) {+// specResults(specs[i]);+// }+// }+// var suites = suite.suites();+// for (var j in suites) {+// if (suites.hasOwnProperty(j)) {+// suiteResults(suites[j]);+// }+// }+// console.groupEnd();+// }++// function specResults(spec) {+// var results = spec.results();+// startGroup(results, spec.description);+// var items = results.getItems();+// for (var k in items) {+// if (items.hasOwnProperty(k)) {+// itemResults(items[k]);+// }+// }+// console.groupEnd();+// }++// function itemResults(item) {+// if (item.passed && !item.passed()) {+// console.warn({actual:item.actual,expected: item.expected});+// item.trace.message = item.matcherName;+// console.error(item.trace);+// } else {+// console.info('Passed');+// }+// }++// function startGroup(results, description) {+// var consoleFunc = (results.passed() && console.groupCollapsed) ? 'groupCollapsed' : 'group';+// red = (results.failedCount > 0) ? "\033[31m" : ""+// console[consoleFunc](red + description + ' (' + results.passedCount + '/' + results.totalCount + ' passed, ' + results.failedCount + ' failures)\033[0m');++// }++// // export public+// jasmine.ConsoleReporter = ConsoleReporter;+// })();++var page = new WebPage()++page.open("file:///Users/astein/work/formal/prelude.html", function () {+ var result = page.evaluate(function () {+ console.log("Test");+ return $(".description").html()+ });+ console.log(result)+ window.setTimeout(function () {+ phantom.exit();+ }, 3000);+});
+ lib/js/jasmine-1.0.1/MIT.LICENSE view
@@ -0,0 +1,20 @@+Copyright (c) 2008-2010 Pivotal Labs++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.
+ lib/js/jasmine-1.0.1/jasmine-html.js view
@@ -0,0 +1,10 @@+jasmine.TrivialReporter=function(a){this.document=a||document;this.suiteDivs={};this.logRunningSpecs=!1};jasmine.TrivialReporter.prototype.createDom=function(a,b,c){for(var d=document.createElement(a),e=2;e<arguments.length;e++){var f=arguments[e];"string"===typeof f?d.appendChild(document.createTextNode(f)):f&&d.appendChild(f)}for(var g in b)"className"==g?d[g]=b[g]:d.setAttribute(g,b[g]);return d};+jasmine.TrivialReporter.prototype.reportRunnerStarting=function(a){var b,c;this.outerDiv=this.createDom("div",{className:"jasmine_reporter"},this.createDom("div",{className:"banner"},this.createDom("div",{className:"logo"},this.createDom("a",{href:"http://pivotal.github.com/jasmine/",target:"_blank"},"Jasmine"),this.createDom("span",{className:"version"},a.env.versionString())),this.createDom("div",{className:"options"},"Show ",b=this.createDom("input",{id:"__jasmine_TrivialReporter_showPassed__",+type:"checkbox"}),this.createDom("label",{"for":"__jasmine_TrivialReporter_showPassed__"}," passed "),c=this.createDom("input",{id:"__jasmine_TrivialReporter_showSkipped__",type:"checkbox"}),this.createDom("label",{"for":"__jasmine_TrivialReporter_showSkipped__"}," skipped"))),this.runnerDiv=this.createDom("div",{className:"runner running"},this.createDom("a",{className:"run_spec",href:"?"},"run all"),this.runnerMessageSpan=this.createDom("span",{},"Running..."),this.finishedAtSpan=this.createDom("span",+{className:"finished-at"},"")));this.document.body.appendChild(this.outerDiv);for(var a=a.suites(),d=0;d<a.length;d++){var e=a[d],f=this.createDom("div",{className:"suite"},this.createDom("a",{className:"run_spec",href:"?spec="+encodeURIComponent(e.getFullName())},"run"),this.createDom("a",{className:"description",href:"?spec="+encodeURIComponent(e.getFullName())},e.description));this.suiteDivs[e.id]=f;var g=this.outerDiv;e.parentSuite&&(g=this.suiteDivs[e.parentSuite.id]);g.appendChild(f)}this.startedAt=+new Date;var h=this;b.onclick=function(){h.outerDiv.className=b.checked?h.outerDiv.className+" show-passed":h.outerDiv.className.replace(/ show-passed/,"")};c.onclick=function(){h.outerDiv.className=c.checked?h.outerDiv.className+" show-skipped":h.outerDiv.className.replace(/ show-skipped/,"")}};+jasmine.TrivialReporter.prototype.reportRunnerResults=function(a){var b=a.results(),c=0<b.failedCount?"runner failed":"runner passed";this.runnerDiv.setAttribute("class",c);this.runnerDiv.setAttribute("className",c);for(var a=a.specs(),d=c=0;d<a.length;d++)this.specFilter(a[d])&&c++;b=""+c+" spec"+(1==c?"":"s")+", "+b.failedCount+" failure"+(1==b.failedCount?"":"s");b+=" in "+((new Date).getTime()-this.startedAt.getTime())/1E3+"s";this.runnerMessageSpan.replaceChild(this.createDom("a",{className:"description",+href:"?"},b),this.runnerMessageSpan.firstChild);this.finishedAtSpan.appendChild(document.createTextNode("Finished at "+(new Date).toString()))};jasmine.TrivialReporter.prototype.reportSuiteResults=function(a){var b=a.results(),c=b.passed()?"passed":"failed";0==b.totalCount&&(c="skipped");this.suiteDivs[a.id].className+=" "+c};jasmine.TrivialReporter.prototype.reportSpecStarting=function(a){this.logRunningSpecs&&this.log(">> Jasmine Running "+a.suite.description+" "+a.description+"...")};+jasmine.TrivialReporter.prototype.reportSpecResults=function(a){var b=a.results(),c=b.passed()?"passed":"failed";b.skipped&&(c="skipped");for(var c=this.createDom("div",{className:"spec "+c},this.createDom("a",{className:"run_spec",href:"?spec="+encodeURIComponent(a.getFullName())},"run"),this.createDom("a",{className:"description",href:"?spec="+encodeURIComponent(a.getFullName()),title:a.getFullName()},a.description.split("__::__")[1])),b=b.getItems(),d=this.createDom("div",{className:"messages"}),+e=0;e<b.length;e++){var f=b[e];"log"==f.type?d.appendChild(this.createDom("div",{className:"resultMessage log"},f.toString())):"expect"==f.type&&f.passed&&!f.passed()&&(d.appendChild(this.createDom("div",{className:"resultMessage fail"},f.message)),f.trace.stack&&d.appendChild(this.createDom("div",{className:"stackTrace"},f.trace.stack)))}0<d.childNodes.length&&c.appendChild(d);this.suiteDivs[a.suite.id].appendChild(c)};+jasmine.TrivialReporter.prototype.log=function(){var a=jasmine.getGlobal().console;a&&a.log&&(a.log.apply?a.log.apply(a,arguments):a.log(arguments))};jasmine.TrivialReporter.prototype.getLocation=function(){return this.document.location};jasmine.TrivialReporter.prototype.specFilter=function(a){for(var b={},c=this.getLocation().search.substring(1).split("&"),d=0;d<c.length;d++){var e=c[d].split("=");b[decodeURIComponent(e[0])]=decodeURIComponent(e[1])}return!b.spec?!0:0==a.getFullName().indexOf(b.spec)};
+ lib/js/jasmine-1.0.1/jasmine.css view
@@ -0,0 +1,171 @@++.jasmine_reporter a:visited, .jasmine_reporter a {+ color: #303; +}++.jasmine_reporter a:hover, .jasmine_reporter a:active {+ color: blue; +}++.run_spec {+ float:right;+ padding-right: 5px;+ font-size: .8em;+ text-decoration: none;+}++.jasmine_reporter {+ margin: 0px 0px 40px 0px;+}++.banner {+ color: #303;+ padding: 5px;+}++.runner.failed {+ background-color: #fdd;+}++.runner.passed {+ background-color: #dfd;+}+++.logo {+ float: left;+ font-size: 1.1em;+ padding-left: 5px;+}++.logo .version {+ font-size: .6em;+ padding-left: 1em;+}++.runner.running {+ background-color: yellow;+}+++.options {+ text-align: right;+ font-size: .8em;+}+++++.suite {+ margin: 5px 0px 5px 5px;+ padding-left: 1em;+ padding-top: 2px;+ padding-bottom: 2px;+}++.suite .suite {+ margin: 5px 0px 5px 5px; +}++.suite.passed {+ background-color: #dfd;+}++.suite.failed {+ background-color: #fdd;+}++.spec {+ margin: 5px 0px 5px 5px;+ padding-left: 1em;+ clear: both;+}++.spec.failed, .spec.passed, .spec.skipped {+ padding-bottom: 5px;+}++.spec.failed {+ background-color: #fbb;+ border-color: red;+}++.spec.passed {+ background-color: #bfb;+ border-color: green;+}++.spec.skipped {+ background-color: #bbb;+}++.messages {+ border-left: 1px dashed gray;+ padding-left: 1em;+ padding-right: 1em;+}++.passed {+ /* background-color: #cfc; */+ display: none;+}++/*+.failed {+ background-color: #fbb;+}+*/+.skipped {+ color: #777;+ background-color: #eee;+ display: none;+}+++/*.resultMessage {*/+ /*white-space: pre;*/+/*}*/++.resultMessage span.result {+ display: block;+ line-height: 2em;+ color: black;+}++.resultMessage .mismatch {+ color: black;+}++.stackTrace {+ white-space: pre;+ font-size: .8em;+ margin-left: 10px;+ max-height: 5em;+ overflow: auto;+ border: 1px inset red;+ padding: 1em;+ background: #eef;+}++.finished-at {+ padding-left: 1em;+ font-size: .6em;+}++.show-passed .passed,+.show-skipped .skipped {+ display: block;+}+++#jasmine_content {+ position:fixed;+ right: 100%;+}++.runner {+ display: block;+ margin: 5px 0px -5px 5px;+ padding: 2px 0 2px 10px;+}+
+ lib/js/jasmine-1.0.1/jasmine.js view
@@ -0,0 +1,77 @@+var jasmine={unimplementedMethod_:function(){throw Error("unimplemented method");}};jasmine.undefined=jasmine.___undefined___;jasmine.DEFAULT_UPDATE_INTERVAL=250;jasmine.DEFAULT_TIMEOUT_INTERVAL=5E3;jasmine.getGlobal=function(){return function(){return this}()};jasmine.bindOriginal_=function(a,b){var c=a[b];return c.apply?function(){return c.apply(a,arguments)}:jasmine.getGlobal()[b]};jasmine.setTimeout=jasmine.bindOriginal_(jasmine.getGlobal(),"setTimeout");+jasmine.clearTimeout=jasmine.bindOriginal_(jasmine.getGlobal(),"clearTimeout");jasmine.setInterval=jasmine.bindOriginal_(jasmine.getGlobal(),"setInterval");jasmine.clearInterval=jasmine.bindOriginal_(jasmine.getGlobal(),"clearInterval");jasmine.MessageResult=function(a){this.type="log";this.values=a;this.trace=Error()};+jasmine.MessageResult.prototype.toString=function(){for(var a="",b=0;b<this.values.length;b++)0<b&&(a+=" "),a=jasmine.isString_(this.values[b])?a+this.values[b]:a+jasmine.pp(this.values[b]);return a};jasmine.ExpectationResult=function(a){this.type="expect";this.matcherName=a.matcherName;this.passed_=a.passed;this.expected=a.expected;this.actual=a.actual;this.message=this.passed_?"Passed.":a.message;this.trace=this.passed_?"":Error(this.message)};jasmine.ExpectationResult.prototype.toString=function(){return this.message};+jasmine.ExpectationResult.prototype.passed=function(){return this.passed_};jasmine.getEnv=function(){return jasmine.currentEnv_=jasmine.currentEnv_||new jasmine.Env};jasmine.isArray_=function(a){return jasmine.isA_("Array",a)};jasmine.isString_=function(a){return jasmine.isA_("String",a)};jasmine.isNumber_=function(a){return jasmine.isA_("Number",a)};jasmine.isA_=function(a,b){return Object.prototype.toString.apply(b)==="[object "+a+"]"};+jasmine.pp=function(a){var b=new jasmine.StringPrettyPrinter;b.format(a);return b.string};jasmine.isDomNode=function(a){return 0<a.nodeType};jasmine.any=function(a){return new jasmine.Matchers.Any(a)};jasmine.Spy=function(a){this.identity=a||"unknown";this.isSpy=!0;this.plan=function(){};this.mostRecentCall={};this.argsForCall=[];this.calls=[]};jasmine.Spy.prototype.andCallThrough=function(){this.plan=this.originalValue;return this};+jasmine.Spy.prototype.andReturn=function(a){this.plan=function(){return a};return this};jasmine.Spy.prototype.andThrow=function(a){this.plan=function(){throw a;};return this};jasmine.Spy.prototype.andCallFake=function(a){this.plan=a;return this};jasmine.Spy.prototype.reset=function(){this.wasCalled=!1;this.callCount=0;this.argsForCall=[];this.calls=[];this.mostRecentCall={}};+jasmine.createSpy=function(a){var b=function(){b.wasCalled=!0;b.callCount++;var a=jasmine.util.argsToArray(arguments);b.mostRecentCall.object=this;b.mostRecentCall.args=a;b.argsForCall.push(a);b.calls.push({object:this,args:a});return b.plan.apply(this,arguments)},a=new jasmine.Spy(a),c;for(c in a)b[c]=a[c];b.reset();return b};jasmine.isSpy=function(a){return a&&a.isSpy};+jasmine.createSpyObj=function(a,b){if(!jasmine.isArray_(b)||0==b.length)throw Error("createSpyObj requires a non-empty array of method names to create spies for");for(var c={},d=0;d<b.length;d++)c[b[d]]=jasmine.createSpy(a+"."+b[d]);return c};jasmine.log=function(){var a=jasmine.getEnv().currentSpec;a.log.apply(a,arguments)};+var spyOn=function(a,b){return jasmine.getEnv().currentSpec.spyOn(a,b)},it=function(a,b){return jasmine.getEnv().it(a,b)},xit=function(a,b){return jasmine.getEnv().xit(a,b)},expect=function(a){return jasmine.getEnv().currentSpec.expect(a)},runs=function(a){jasmine.getEnv().currentSpec.runs(a)},waits=function(a){jasmine.getEnv().currentSpec.waits(a)},waitsFor=function(a,b,c){jasmine.getEnv().currentSpec.waitsFor.apply(jasmine.getEnv().currentSpec,arguments)},beforeEach=function(a){jasmine.getEnv().beforeEach(a)},+afterEach=function(a){jasmine.getEnv().afterEach(a)},describe=function(a,b){return jasmine.getEnv().describe(a,b)},xdescribe=function(a,b){return jasmine.getEnv().xdescribe(a,b)};+jasmine.XmlHttpRequest="undefined"==typeof XMLHttpRequest?function(){try{return new ActiveXObject("Msxml2.XMLHTTP.6.0")}catch(a){}try{return new ActiveXObject("Msxml2.XMLHTTP.3.0")}catch(b){}try{return new ActiveXObject("Msxml2.XMLHTTP")}catch(c){}try{return new ActiveXObject("Microsoft.XMLHTTP")}catch(d){}throw Error("This browser does not support XMLHttpRequest.");}:XMLHttpRequest;jasmine.util={};jasmine.util.inherit=function(a,b){var c=function(){};c.prototype=b.prototype;a.prototype=new c};+jasmine.util.formatException=function(a){var b;a.line?b=a.line:a.lineNumber&&(b=a.lineNumber);var c;a.sourceURL?c=a.sourceURL:a.fileName&&(c=a.fileName);a=a.name&&a.message?a.name+": "+a.message:a.toString();c&&b&&(a+=" in "+c+" (line "+b+")");return a};jasmine.util.htmlEscape=function(a){return!a?a:a.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">")};jasmine.util.argsToArray=function(a){for(var b=[],c=0;c<a.length;c++)b.push(a[c]);return b};+jasmine.util.extend=function(a,b){for(var c in b)a[c]=b[c];return a};+jasmine.Env=function(){this.currentSuite=this.currentSpec=null;this.currentRunner_=new jasmine.Runner(this);this.reporter=new jasmine.MultiReporter;this.updateInterval=jasmine.DEFAULT_UPDATE_INTERVAL;this.defaultTimeoutInterval=jasmine.DEFAULT_TIMEOUT_INTERVAL;this.lastUpdate=0;this.specFilter=function(){return!0};this.nextSuiteId_=this.nextSpecId_=0;this.equalityTesters_=[];this.matchersClass=function(){jasmine.Matchers.apply(this,arguments)};jasmine.util.inherit(this.matchersClass,jasmine.Matchers);+jasmine.Matchers.wrapInto_(jasmine.Matchers.prototype,this.matchersClass)};jasmine.Env.prototype.setTimeout=jasmine.setTimeout;jasmine.Env.prototype.clearTimeout=jasmine.clearTimeout;jasmine.Env.prototype.setInterval=jasmine.setInterval;jasmine.Env.prototype.clearInterval=jasmine.clearInterval;jasmine.Env.prototype.version=function(){if(jasmine.version_)return jasmine.version_;throw Error("Version not set");};+jasmine.Env.prototype.versionString=function(){if(jasmine.version_){var a=this.version();return a.major+"."+a.minor+"."+a.build+" revision "+a.revision}return"version unknown"};jasmine.Env.prototype.nextSpecId=function(){return this.nextSpecId_++};jasmine.Env.prototype.nextSuiteId=function(){return this.nextSuiteId_++};jasmine.Env.prototype.addReporter=function(a){this.reporter.addReporter(a)};jasmine.Env.prototype.execute=function(){this.currentRunner_.execute()};+jasmine.Env.prototype.describe=function(a,b){var c=new jasmine.Suite(this,a,b,this.currentSuite),d=this.currentSuite;d?d.add(c):this.currentRunner_.add(c);this.currentSuite=c;var e=null;try{b.call(c)}catch(f){e=f}this.currentSuite=d;e&&this.it("encountered a declaration exception",function(){throw e;});return c};jasmine.Env.prototype.beforeEach=function(a){this.currentSuite?this.currentSuite.beforeEach(a):this.currentRunner_.beforeEach(a)};jasmine.Env.prototype.currentRunner=function(){return this.currentRunner_};+jasmine.Env.prototype.afterEach=function(a){this.currentSuite?this.currentSuite.afterEach(a):this.currentRunner_.afterEach(a)};jasmine.Env.prototype.xdescribe=function(){return{execute:function(){}}};jasmine.Env.prototype.it=function(a,b){var c=new jasmine.Spec(this,this.currentSuite,a);this.currentSuite.add(c);this.currentSpec=c;b&&c.runs(b);return c};jasmine.Env.prototype.xit=function(){return{id:this.nextSpecId(),runs:function(){}}};+jasmine.Env.prototype.compareObjects_=function(a,b,c,d){if(a.__Jasmine_been_here_before__===b&&b.__Jasmine_been_here_before__===a)return!0;a.__Jasmine_been_here_before__=b;b.__Jasmine_been_here_before__=a;var e=function(a,b){return null!=a&&a[b]!==jasmine.undefined},f;for(f in b)!e(a,f)&&e(b,f)&&c.push("expected has key '"+f+"', but missing from actual.");for(f in a)!e(b,f)&&e(a,f)&&c.push("expected missing key '"+f+"', but present in actual.");for(f in b)"__Jasmine_been_here_before__"!=f&&(this.equals_(a[f],+b[f],c,d)||d.push("'"+f+"' was '"+(b[f]?jasmine.util.htmlEscape(b[f].toString()):b[f])+"' in expected, but was '"+(a[f]?jasmine.util.htmlEscape(a[f].toString()):a[f])+"' in actual."));jasmine.isArray_(a)&&(jasmine.isArray_(b)&&a.length!=b.length)&&d.push("arrays were not the same length");delete a.__Jasmine_been_here_before__;delete b.__Jasmine_been_here_before__;return 0==c.length&&0==d.length};+jasmine.Env.prototype.equals_=function(a,b,c,d){for(var c=c||[],d=d||[],e=0;e<this.equalityTesters_.length;e++){var f=(0,this.equalityTesters_[e])(a,b,this,c,d);if(f!==jasmine.undefined)return f}return a===b?!0:a===jasmine.undefined||null===a||b===jasmine.undefined||null===b?a==jasmine.undefined&&b==jasmine.undefined:jasmine.isDomNode(a)&&jasmine.isDomNode(b)?a===b:a instanceof Date&&b instanceof Date?a.getTime()==b.getTime():a instanceof jasmine.Matchers.Any?a.matches(b):b instanceof jasmine.Matchers.Any?+b.matches(a):jasmine.isString_(a)&&jasmine.isString_(b)||jasmine.isNumber_(a)&&jasmine.isNumber_(b)?a==b:"object"===typeof a&&"object"===typeof b?this.compareObjects_(a,b,c,d):a===b};jasmine.Env.prototype.contains_=function(a,b){if(jasmine.isArray_(a)){for(var c=0;c<a.length;c++)if(this.equals_(a[c],b))return!0;return!1}return 0<=a.indexOf(b)};jasmine.Env.prototype.addEqualityTester=function(a){this.equalityTesters_.push(a)};jasmine.Reporter=function(){};+jasmine.Reporter.prototype.reportRunnerStarting=function(){};jasmine.Reporter.prototype.reportRunnerResults=function(){};jasmine.Reporter.prototype.reportSuiteResults=function(){};jasmine.Reporter.prototype.reportSpecStarting=function(){};jasmine.Reporter.prototype.reportSpecResults=function(){};jasmine.Reporter.prototype.log=function(){};jasmine.Block=function(a,b,c){this.env=a;this.func=b;this.spec=c};jasmine.Block.prototype.execute=function(a){try{this.func.apply(this.spec)}catch(b){this.spec.fail(b)}a()};+jasmine.JsApiReporter=function(){this.finished=this.started=!1;this.suites_=[];this.results_={}};jasmine.JsApiReporter.prototype.reportRunnerStarting=function(a){this.started=!0;for(var a=a.topLevelSuites(),b=0;b<a.length;b++)this.suites_.push(this.summarize_(a[b]))};jasmine.JsApiReporter.prototype.suites=function(){return this.suites_};+jasmine.JsApiReporter.prototype.summarize_=function(a){var b=a instanceof jasmine.Suite,c={id:a.id,name:a.description,type:b?"suite":"spec",children:[]};if(b){a=a.children();for(b=0;b<a.length;b++)c.children.push(this.summarize_(a[b]))}return c};jasmine.JsApiReporter.prototype.results=function(){return this.results_};jasmine.JsApiReporter.prototype.resultsForSpec=function(a){return this.results_[a]};jasmine.JsApiReporter.prototype.reportRunnerResults=function(){this.finished=!0};+jasmine.JsApiReporter.prototype.reportSuiteResults=function(){};jasmine.JsApiReporter.prototype.reportSpecResults=function(a){this.results_[a.id]={messages:a.results().getItems(),result:0<a.results().failedCount?"failed":"passed"}};jasmine.JsApiReporter.prototype.log=function(){};jasmine.JsApiReporter.prototype.resultsForSpecs=function(a){for(var b={},c=0;c<a.length;c++){var d=a[c];b[d]=this.summarizeResult_(this.results_[d])}return b};+jasmine.JsApiReporter.prototype.summarizeResult_=function(a){for(var b=[],c=a.messages.length,d=0;d<c;d++){var e=a.messages[d];b.push({text:"log"==e.type?e.toString():jasmine.undefined,passed:e.passed?e.passed():!0,type:e.type,message:e.message,trace:{stack:e.passed&&!e.passed()?e.trace.stack:jasmine.undefined}})}return{result:a.result,messages:b}};jasmine.Matchers=function(a,b,c,d){this.env=a;this.actual=b;this.spec=c;this.isNot=d||!1;this.reportWasCalled_=!1};+jasmine.Matchers.pp=function(){throw Error("jasmine.Matchers.pp() is no longer supported, please use jasmine.pp() instead!");};jasmine.Matchers.prototype.report=function(){throw Error("As of jasmine 0.11, custom matchers must be implemented differently -- please see jasmine docs");};jasmine.Matchers.wrapInto_=function(a,b){for(var c in a)"report"!=c&&(b.prototype[c]=jasmine.Matchers.matcherFn_(c,a[c]))};+jasmine.Matchers.matcherFn_=function(a,b){return function(){var c=jasmine.util.argsToArray(arguments),d=b.apply(this,arguments);this.isNot&&(d=!d);if(this.reportWasCalled_)return d;var e;if(!d)if(this.message)e=this.message.apply(this,arguments),jasmine.isArray_(e)&&(e=e[this.isNot?1:0]);else{e=a.replace(/[A-Z]/g,function(a){return" "+a.toLowerCase()});e="Expected "+jasmine.pp(this.actual)+(this.isNot?" not ":" ")+e;if(0<c.length)for(var f=0;f<c.length;f++)0<f&&(e+=","),e+=" "+jasmine.pp(c[f]);e+=+"."}this.spec.addMatcherResult(new jasmine.ExpectationResult({matcherName:a,passed:d,expected:1<c.length?c:c[0],actual:this.actual,message:e}));return jasmine.undefined}};jasmine.Matchers.prototype.toBe=function(a){return this.actual===a};jasmine.Matchers.prototype.toNotBe=function(a){return this.actual!==a};jasmine.Matchers.prototype.toEqual=function(a){return this.env.equals_(this.actual,a)};jasmine.Matchers.prototype.toNotEqual=function(a){return!this.env.equals_(this.actual,a)};+jasmine.Matchers.prototype.toMatch=function(a){return RegExp(a).test(this.actual)};jasmine.Matchers.prototype.toNotMatch=function(a){return!RegExp(a).test(this.actual)};jasmine.Matchers.prototype.toBeDefined=function(){return this.actual!==jasmine.undefined};jasmine.Matchers.prototype.toBeUndefined=function(){return this.actual===jasmine.undefined};jasmine.Matchers.prototype.toBeNull=function(){return null===this.actual};jasmine.Matchers.prototype.toBeTruthy=function(){return!!this.actual};+jasmine.Matchers.prototype.toBeFalsy=function(){return!this.actual};jasmine.Matchers.prototype.toHaveBeenCalled=function(){if(0<arguments.length)throw Error("toHaveBeenCalled does not take arguments, use toHaveBeenCalledWith");if(!jasmine.isSpy(this.actual))throw Error("Expected a spy, but got "+jasmine.pp(this.actual)+".");this.message=function(){return["Expected spy "+this.actual.identity+" to have been called.","Expected spy "+this.actual.identity+" not to have been called."]};return this.actual.wasCalled};+jasmine.Matchers.prototype.wasCalled=jasmine.Matchers.prototype.toHaveBeenCalled;jasmine.Matchers.prototype.wasNotCalled=function(){if(0<arguments.length)throw Error("wasNotCalled does not take arguments");if(!jasmine.isSpy(this.actual))throw Error("Expected a spy, but got "+jasmine.pp(this.actual)+".");this.message=function(){return["Expected spy "+this.actual.identity+" to not have been called.","Expected spy "+this.actual.identity+" to have been called."]};return!this.actual.wasCalled};+jasmine.Matchers.prototype.toHaveBeenCalledWith=function(){var a=jasmine.util.argsToArray(arguments);if(!jasmine.isSpy(this.actual))throw Error("Expected a spy, but got "+jasmine.pp(this.actual)+".");this.message=function(){return 0==this.actual.callCount?["Expected spy to have been called with "+jasmine.pp(a)+" but it was never called.","Expected spy not to have been called with "+jasmine.pp(a)+" but it was."]:["Expected spy to have been called with "+jasmine.pp(a)+" but was called with "+jasmine.pp(this.actual.argsForCall),+"Expected spy not to have been called with "+jasmine.pp(a)+" but was called with "+jasmine.pp(this.actual.argsForCall)]};return this.env.contains_(this.actual.argsForCall,a)};jasmine.Matchers.prototype.wasCalledWith=jasmine.Matchers.prototype.toHaveBeenCalledWith;+jasmine.Matchers.prototype.wasNotCalledWith=function(){var a=jasmine.util.argsToArray(arguments);if(!jasmine.isSpy(this.actual))throw Error("Expected a spy, but got "+jasmine.pp(this.actual)+".");this.message=function(){return["Expected spy not to have been called with "+jasmine.pp(a)+" but it was","Expected spy to have been called with "+jasmine.pp(a)+" but it was"]};return!this.env.contains_(this.actual.argsForCall,a)};+jasmine.Matchers.prototype.toContain=function(a){return this.env.contains_(this.actual,a)};jasmine.Matchers.prototype.toNotContain=function(a){return!this.env.contains_(this.actual,a)};jasmine.Matchers.prototype.toBeLessThan=function(a){return this.actual<a};jasmine.Matchers.prototype.toBeGreaterThan=function(a){return this.actual>a};+jasmine.Matchers.prototype.toThrow=function(a){var b=!1,c;if("function"!=typeof this.actual)throw Error("Actual is not a function");try{this.actual()}catch(d){c=d}c&&(b=a===jasmine.undefined||this.env.equals_(c.message||c,a.message||a));var e=this.isNot?"not ":"";this.message=function(){return c&&(a===jasmine.undefined||!this.env.equals_(c.message||c,a.message||a))?["Expected function "+e+"to throw",a?a.message||a:" an exception",", but it threw",c.message||c].join(" "):"Expected function to throw an exception."};+return b};jasmine.Matchers.Any=function(a){this.expectedClass=a};jasmine.Matchers.Any.prototype.matches=function(a){return this.expectedClass==String?"string"==typeof a||a instanceof String:this.expectedClass==Number?"number"==typeof a||a instanceof Number:this.expectedClass==Function?"function"==typeof a||a instanceof Function:this.expectedClass==Object?"object"==typeof a:a instanceof this.expectedClass};+jasmine.Matchers.Any.prototype.toString=function(){return"<jasmine.any("+this.expectedClass+")>"};jasmine.MultiReporter=function(){this.subReporters_=[]};jasmine.util.inherit(jasmine.MultiReporter,jasmine.Reporter);jasmine.MultiReporter.prototype.addReporter=function(a){this.subReporters_.push(a)};+(function(){for(var a="reportRunnerStarting reportRunnerResults reportSuiteResults reportSpecStarting reportSpecResults log".split(" "),b=0;b<a.length;b++){var c=a[b];jasmine.MultiReporter.prototype[c]=function(a){return function(){for(var b=0;b<this.subReporters_.length;b++){var c=this.subReporters_[b];c[a]&&c[a].apply(c,arguments)}}}(c)}})();jasmine.NestedResults=function(){this.failedCount=this.passedCount=this.totalCount=0;this.skipped=!1;this.items_=[]};+jasmine.NestedResults.prototype.rollupCounts=function(a){this.totalCount+=a.totalCount;this.passedCount+=a.passedCount;this.failedCount+=a.failedCount};jasmine.NestedResults.prototype.log=function(a){this.items_.push(new jasmine.MessageResult(a))};jasmine.NestedResults.prototype.getItems=function(){return this.items_};jasmine.NestedResults.prototype.addResult=function(a){"log"!=a.type&&(a.items_?this.rollupCounts(a):(this.totalCount++,a.passed()?this.passedCount++:this.failedCount++));this.items_.push(a)};+jasmine.NestedResults.prototype.passed=function(){return this.passedCount===this.totalCount};jasmine.PrettyPrinter=function(){this.ppNestLevel_=0};+jasmine.PrettyPrinter.prototype.format=function(a){if(40<this.ppNestLevel_)throw Error("jasmine.PrettyPrinter: format() nested too deeply!");this.ppNestLevel_++;try{a===jasmine.undefined?this.emitScalar("undefined"):null===a?this.emitScalar("null"):a===jasmine.getGlobal()?this.emitScalar("<global>"):a instanceof jasmine.Matchers.Any?this.emitScalar(a.toString()):"string"===typeof a?this.emitString(a):jasmine.isSpy(a)?this.emitScalar("spy on "+a.identity):a instanceof RegExp?this.emitScalar(a.toString()):+"function"===typeof a?this.emitScalar("Function"):"number"===typeof a.nodeType?this.emitScalar("HTMLNode"):a instanceof Date?this.emitScalar("Date("+a+")"):a.__Jasmine_been_here_before__?this.emitScalar("<circular reference: "+(jasmine.isArray_(a)?"Array":"Object")+">"):jasmine.isArray_(a)||"object"==typeof a?(a.__Jasmine_been_here_before__=!0,jasmine.isArray_(a)?this.emitArray(a):this.emitObject(a),delete a.__Jasmine_been_here_before__):this.emitScalar(a.toString())}finally{this.ppNestLevel_--}};+jasmine.PrettyPrinter.prototype.iterateObject=function(a,b){for(var c in a)"__Jasmine_been_here_before__"!=c&&b(c,a.__lookupGetter__?null!=a.__lookupGetter__(c):!1)};jasmine.PrettyPrinter.prototype.emitArray=jasmine.unimplementedMethod_;jasmine.PrettyPrinter.prototype.emitObject=jasmine.unimplementedMethod_;jasmine.PrettyPrinter.prototype.emitScalar=jasmine.unimplementedMethod_;jasmine.PrettyPrinter.prototype.emitString=jasmine.unimplementedMethod_;+jasmine.StringPrettyPrinter=function(){jasmine.PrettyPrinter.call(this);this.string=""};jasmine.util.inherit(jasmine.StringPrettyPrinter,jasmine.PrettyPrinter);jasmine.StringPrettyPrinter.prototype.emitScalar=function(a){this.append(a)};jasmine.StringPrettyPrinter.prototype.emitString=function(a){this.append("'"+a+"'")};jasmine.StringPrettyPrinter.prototype.emitArray=function(a){this.append("[ ");for(var b=0;b<a.length;b++)0<b&&this.append(", "),this.format(a[b]);this.append(" ]")};+jasmine.StringPrettyPrinter.prototype.emitObject=function(a){var b=this;this.append("{ ");var c=!0;this.iterateObject(a,function(d,e){c?c=!1:b.append(", ");b.append(d);b.append(" : ");e?b.append("<getter>"):b.format(a[d])});this.append(" }")};jasmine.StringPrettyPrinter.prototype.append=function(a){this.string+=a};jasmine.Queue=function(a){this.env=a;this.blocks=[];this.running=!1;this.offset=this.index=0;this.abort=!1};jasmine.Queue.prototype.addBefore=function(a){this.blocks.unshift(a)};+jasmine.Queue.prototype.add=function(a){this.blocks.push(a)};jasmine.Queue.prototype.insertNext=function(a){this.blocks.splice(this.index+this.offset+1,0,a);this.offset++};jasmine.Queue.prototype.start=function(a){this.running=!0;this.onComplete=a;this.next_()};jasmine.Queue.prototype.isRunning=function(){return this.running};jasmine.Queue.LOOP_DONT_RECURSE=!0;+jasmine.Queue.prototype.next_=function(){for(var a=this,b=!0;b;)if(b=!1,a.index<a.blocks.length&&!this.abort){var c=!0,d=!1,e=function(){if(jasmine.Queue.LOOP_DONT_RECURSE&&c)d=!0;else{a.blocks[a.index].abort&&(a.abort=!0);a.offset=0;a.index++;var e=(new Date).getTime();a.env.updateInterval&&e-a.env.lastUpdate>a.env.updateInterval?(a.env.lastUpdate=e,a.env.setTimeout(function(){a.next_()},0)):jasmine.Queue.LOOP_DONT_RECURSE&&d?b=!0:a.next_()}};a.blocks[a.index].execute(e);c=!1;d&&e()}else if(a.running=+!1,a.onComplete)a.onComplete()};jasmine.Queue.prototype.results=function(){for(var a=new jasmine.NestedResults,b=0;b<this.blocks.length;b++)this.blocks[b].results&&a.addResult(this.blocks[b].results());return a};jasmine.Runner=function(a){this.env=a;this.queue=new jasmine.Queue(a);this.before_=[];this.after_=[];this.suites_=[]};jasmine.Runner.prototype.execute=function(){var a=this;a.env.reporter.reportRunnerStarting&&a.env.reporter.reportRunnerStarting(this);a.queue.start(function(){a.finishCallback()})};+jasmine.Runner.prototype.beforeEach=function(a){a.typeName="beforeEach";this.before_.splice(0,0,a)};jasmine.Runner.prototype.afterEach=function(a){a.typeName="afterEach";this.after_.splice(0,0,a)};jasmine.Runner.prototype.finishCallback=function(){this.env.reporter.reportRunnerResults(this)};jasmine.Runner.prototype.addSuite=function(a){this.suites_.push(a)};jasmine.Runner.prototype.add=function(a){a instanceof jasmine.Suite&&this.addSuite(a);this.queue.add(a)};+jasmine.Runner.prototype.specs=function(){for(var a=this.suites(),b=[],c=0;c<a.length;c++)b=b.concat(a[c].specs());return b};jasmine.Runner.prototype.suites=function(){return this.suites_};jasmine.Runner.prototype.topLevelSuites=function(){for(var a=[],b=0;b<this.suites_.length;b++)this.suites_[b].parentSuite||a.push(this.suites_[b]);return a};jasmine.Runner.prototype.results=function(){return this.queue.results()};+jasmine.Spec=function(a,b,c){if(!a)throw Error("jasmine.Env() required");if(!b)throw Error("jasmine.Suite() required");this.id=a.nextSpecId?a.nextSpecId():null;this.env=a;this.suite=b;this.description=c;this.queue=new jasmine.Queue(a);this.afterCallbacks=[];this.spies_=[];this.results_=new jasmine.NestedResults;this.results_.description=c;this.matchersClass=null};jasmine.Spec.prototype.getFullName=function(){return this.suite.getFullName()+" "+this.description+"."};+jasmine.Spec.prototype.results=function(){return this.results_};jasmine.Spec.prototype.log=function(){return this.results_.log(arguments)};jasmine.Spec.prototype.runs=function(a){this.addToQueue(new jasmine.Block(this.env,a,this));return this};jasmine.Spec.prototype.addToQueue=function(a){this.queue.isRunning()?this.queue.insertNext(a):this.queue.add(a)};jasmine.Spec.prototype.addMatcherResult=function(a){this.results_.addResult(a)};+jasmine.Spec.prototype.expect=function(a){var b=new (this.getMatchersClass_())(this.env,a,this);b.not=new (this.getMatchersClass_())(this.env,a,this,!0);return b};jasmine.Spec.prototype.waits=function(a){this.addToQueue(new jasmine.WaitsBlock(this.env,a,this));return this};+jasmine.Spec.prototype.waitsFor=function(a,b,c){for(var d=null,e=null,f=null,g=0;g<arguments.length;g++){var h=arguments[g];switch(typeof h){case "function":d=h;break;case "string":e=h;break;case "number":f=h}}this.addToQueue(new jasmine.WaitsForBlock(this.env,f,d,e,this));return this};jasmine.Spec.prototype.fail=function(a){this.results_.addResult(new jasmine.ExpectationResult({passed:!1,message:a?jasmine.util.formatException(a):"Exception"}))};+jasmine.Spec.prototype.getMatchersClass_=function(){return this.matchersClass||this.env.matchersClass};jasmine.Spec.prototype.addMatchers=function(a){var b=this.getMatchersClass_(),c=function(){b.apply(this,arguments)};jasmine.util.inherit(c,b);jasmine.Matchers.wrapInto_(a,c);this.matchersClass=c};jasmine.Spec.prototype.finishCallback=function(){this.env.reporter.reportSpecResults(this)};jasmine.Spec.prototype.finish=function(a){this.removeAllSpies();this.finishCallback();a&&a()};+jasmine.Spec.prototype.after=function(a){this.queue.isRunning()?this.queue.add(new jasmine.Block(this.env,a,this)):this.afterCallbacks.unshift(a)};jasmine.Spec.prototype.execute=function(a){var b=this;b.env.specFilter(b)?(this.env.reporter.reportSpecStarting(this),b.env.currentSpec=b,b.addBeforesAndAftersToQueue(),b.queue.start(function(){b.finish(a)})):(b.results_.skipped=!0,b.finish(a))};+jasmine.Spec.prototype.addBeforesAndAftersToQueue=function(){for(var a=this.env.currentRunner(),b,c=this.suite;c;c=c.parentSuite)for(b=0;b<c.before_.length;b++)this.queue.addBefore(new jasmine.Block(this.env,c.before_[b],this));for(b=0;b<a.before_.length;b++)this.queue.addBefore(new jasmine.Block(this.env,a.before_[b],this));for(b=0;b<this.afterCallbacks.length;b++)this.queue.add(new jasmine.Block(this.env,this.afterCallbacks[b],this));for(c=this.suite;c;c=c.parentSuite)for(b=0;b<c.after_.length;b++)this.queue.add(new jasmine.Block(this.env,+c.after_[b],this));for(b=0;b<a.after_.length;b++)this.queue.add(new jasmine.Block(this.env,a.after_[b],this))};jasmine.Spec.prototype.explodes=function(){throw"explodes function should not have been called";};+jasmine.Spec.prototype.spyOn=function(a,b,c){if(a==jasmine.undefined)throw"spyOn could not find an object to spy upon for "+b+"()";if(!c&&a[b]===jasmine.undefined)throw b+"() method does not exist";if(!c&&a[b]&&a[b].isSpy)throw Error(b+" has already been spied upon");c=jasmine.createSpy(b);this.spies_.push(c);c.baseObj=a;c.methodName=b;c.originalValue=a[b];return a[b]=c};+jasmine.Spec.prototype.removeAllSpies=function(){for(var a=0;a<this.spies_.length;a++){var b=this.spies_[a];b.baseObj[b.methodName]=b.originalValue}this.spies_=[]};jasmine.Suite=function(a,b,c,d){this.id=a.nextSuiteId?a.nextSuiteId():null;this.description=b;this.queue=new jasmine.Queue(a);this.parentSuite=d;this.env=a;this.before_=[];this.after_=[];this.children_=[];this.suites_=[];this.specs_=[]};+jasmine.Suite.prototype.getFullName=function(){for(var a=this.description,b=this.parentSuite;b;b=b.parentSuite)a=b.description+" "+a;return a};jasmine.Suite.prototype.finish=function(a){this.env.reporter.reportSuiteResults(this);this.finished=!0;"function"==typeof a&&a()};jasmine.Suite.prototype.beforeEach=function(a){a.typeName="beforeEach";this.before_.unshift(a)};jasmine.Suite.prototype.afterEach=function(a){a.typeName="afterEach";this.after_.unshift(a)};jasmine.Suite.prototype.results=function(){return this.queue.results()};+jasmine.Suite.prototype.add=function(a){this.children_.push(a);a instanceof jasmine.Suite?(this.suites_.push(a),this.env.currentRunner().addSuite(a)):this.specs_.push(a);this.queue.add(a)};jasmine.Suite.prototype.specs=function(){return this.specs_};jasmine.Suite.prototype.suites=function(){return this.suites_};jasmine.Suite.prototype.children=function(){return this.children_};jasmine.Suite.prototype.execute=function(a){var b=this;this.queue.start(function(){b.finish(a)})};+jasmine.WaitsBlock=function(a,b,c){this.timeout=b;jasmine.Block.call(this,a,null,c)};jasmine.util.inherit(jasmine.WaitsBlock,jasmine.Block);jasmine.WaitsBlock.prototype.execute=function(a){this.env.reporter.log(">> Jasmine waiting for "+this.timeout+" ms...");this.env.setTimeout(function(){a()},this.timeout)};jasmine.WaitsForBlock=function(a,b,c,d,e){this.timeout=b||a.defaultTimeoutInterval;this.latchFunction=c;this.message=d;this.totalTimeSpentWaitingForLatch=0;jasmine.Block.call(this,a,null,e)};+jasmine.util.inherit(jasmine.WaitsForBlock,jasmine.Block);jasmine.WaitsForBlock.TIMEOUT_INCREMENT=10;+jasmine.WaitsForBlock.prototype.execute=function(a){this.env.reporter.log(">> Jasmine waiting for "+(this.message||"something to happen"));var b;try{b=this.latchFunction.apply(this.spec)}catch(c){this.spec.fail(c);a();return}if(b)a();else if(this.totalTimeSpentWaitingForLatch>=this.timeout)this.spec.fail({name:"timeout",message:"timed out after "+this.timeout+" msec waiting for "+(this.message||"something to happen")}),this.abort=!0,a();else{this.totalTimeSpentWaitingForLatch+=jasmine.WaitsForBlock.TIMEOUT_INCREMENT;+var d=this;this.env.setTimeout(function(){d.execute(a)},jasmine.WaitsForBlock.TIMEOUT_INCREMENT)}};jasmine.FakeTimer=function(){this.reset();var a=this;a.setTimeout=function(b,c){a.timeoutsMade++;a.scheduleFunction(a.timeoutsMade,b,c,!1);return a.timeoutsMade};a.setInterval=function(b,c){a.timeoutsMade++;a.scheduleFunction(a.timeoutsMade,b,c,!0);return a.timeoutsMade};a.clearTimeout=function(b){a.scheduledFunctions[b]=jasmine.undefined};a.clearInterval=function(b){a.scheduledFunctions[b]=jasmine.undefined}};+jasmine.FakeTimer.prototype.reset=function(){this.timeoutsMade=0;this.scheduledFunctions={};this.nowMillis=0};jasmine.FakeTimer.prototype.tick=function(a){var b=this.nowMillis,a=b+a;this.runFunctionsWithinRange(b,a);this.nowMillis=a};+jasmine.FakeTimer.prototype.runFunctionsWithinRange=function(a,b){var c,d=[],e;for(e in this.scheduledFunctions)c=this.scheduledFunctions[e],c!=jasmine.undefined&&(c.runAtMillis>=a&&c.runAtMillis<=b)&&(d.push(c),this.scheduledFunctions[e]=jasmine.undefined);if(0<d.length){d.sort(function(a,b){return a.runAtMillis-b.runAtMillis});for(c=0;c<d.length;++c)try{var f=d[c];this.nowMillis=f.runAtMillis;f.funcToCall();f.recurring&&this.scheduleFunction(f.timeoutKey,f.funcToCall,f.millis,!0)}catch(g){}this.runFunctionsWithinRange(a,+b)}};jasmine.FakeTimer.prototype.scheduleFunction=function(a,b,c,d){this.scheduledFunctions[a]={runAtMillis:this.nowMillis+c,funcToCall:b,recurring:d,timeoutKey:a,millis:c}};+jasmine.Clock={defaultFakeTimer:new jasmine.FakeTimer,reset:function(){jasmine.Clock.assertInstalled();jasmine.Clock.defaultFakeTimer.reset()},tick:function(a){jasmine.Clock.assertInstalled();jasmine.Clock.defaultFakeTimer.tick(a)},runFunctionsWithinRange:function(a,b){jasmine.Clock.defaultFakeTimer.runFunctionsWithinRange(a,b)},scheduleFunction:function(a,b,c,d){jasmine.Clock.defaultFakeTimer.scheduleFunction(a,b,c,d)},useMock:function(){jasmine.Clock.isInstalled()||(jasmine.getEnv().currentSpec.after(jasmine.Clock.uninstallMock),+jasmine.Clock.installMock())},installMock:function(){jasmine.Clock.installed=jasmine.Clock.defaultFakeTimer},uninstallMock:function(){jasmine.Clock.assertInstalled();jasmine.Clock.installed=jasmine.Clock.real},real:{setTimeout:jasmine.getGlobal().setTimeout,clearTimeout:jasmine.getGlobal().clearTimeout,setInterval:jasmine.getGlobal().setInterval,clearInterval:jasmine.getGlobal().clearInterval},assertInstalled:function(){if(!jasmine.Clock.isInstalled())throw Error("Mock clock is not installed, use jasmine.Clock.useMock()");+},isInstalled:function(){return jasmine.Clock.installed==jasmine.Clock.defaultFakeTimer},installed:null};jasmine.Clock.installed=jasmine.Clock.real;jasmine.getGlobal().setTimeout=function(a,b){return jasmine.Clock.installed.setTimeout.apply?jasmine.Clock.installed.setTimeout.apply(this,arguments):jasmine.Clock.installed.setTimeout(a,b)};+jasmine.getGlobal().setInterval=function(a,b){return jasmine.Clock.installed.setInterval.apply?jasmine.Clock.installed.setInterval.apply(this,arguments):jasmine.Clock.installed.setInterval(a,b)};jasmine.getGlobal().clearTimeout=function(a){return jasmine.Clock.installed.clearTimeout.apply?jasmine.Clock.installed.clearTimeout.apply(this,arguments):jasmine.Clock.installed.clearTimeout(a)};+jasmine.getGlobal().clearInterval=function(a){return jasmine.Clock.installed.clearTimeout.apply?jasmine.Clock.installed.clearInterval.apply(this,arguments):jasmine.Clock.installed.clearInterval(a)};jasmine.version_={major:1,minor:0,build:1,revision:1286311016};
+ lib/js/jquery.js view
@@ -0,0 +1,16 @@+/*!+ * jQuery JavaScript Library v1.5.2+ * http://jquery.com/+ *+ * Copyright 2011, John Resig+ * Dual licensed under the MIT or GPL Version 2 licenses.+ * http://jquery.org/license+ *+ * Includes Sizzle.js+ * http://sizzlejs.com/+ * Copyright 2011, The Dojo Foundation+ * Released under the MIT, BSD, and GPL Licenses.+ *+ * Date: Thu Mar 31 15:28:23 2011 -0400+ */+(function(a,b){function ci(a){return d.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}function cf(a){if(!b_[a]){var b=d("<"+a+">").appendTo("body"),c=b.css("display");b.remove();if(c==="none"||c==="")c="block";b_[a]=c}return b_[a]}function ce(a,b){var c={};d.each(cd.concat.apply([],cd.slice(0,b)),function(){c[this]=a});return c}function b$(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function bZ(){try{return new a.XMLHttpRequest}catch(b){}}function bY(){d(a).unload(function(){for(var a in bW)bW[a](0,1)})}function bS(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var e=a.dataTypes,f={},g,h,i=e.length,j,k=e[0],l,m,n,o,p;for(g=1;g<i;g++){if(g===1)for(h in a.converters)typeof h==="string"&&(f[h.toLowerCase()]=a.converters[h]);l=k,k=e[g];if(k==="*")k=l;else if(l!=="*"&&l!==k){m=l+" "+k,n=f[m]||f["* "+k];if(!n){p=b;for(o in f){j=o.split(" ");if(j[0]===l||j[0]==="*"){p=f[j[1]+" "+k];if(p){o=f[o],o===!0?n=p:p===!0&&(n=o);break}}}}!n&&!p&&d.error("No conversion from "+m.replace(" "," to ")),n!==!0&&(c=n?n(c):p(o(c)))}}return c}function bR(a,c,d){var e=a.contents,f=a.dataTypes,g=a.responseFields,h,i,j,k;for(i in g)i in d&&(c[g[i]]=d[i]);while(f[0]==="*")f.shift(),h===b&&(h=a.mimeType||c.getResponseHeader("content-type"));if(h)for(i in e)if(e[i]&&e[i].test(h)){f.unshift(i);break}if(f[0]in d)j=f[0];else{for(i in d){if(!f[0]||a.converters[i+" "+f[0]]){j=i;break}k||(k=i)}j=j||k}if(j){j!==f[0]&&f.unshift(j);return d[j]}}function bQ(a,b,c,e){if(d.isArray(b)&&b.length)d.each(b,function(b,f){c||bs.test(a)?e(a,f):bQ(a+"["+(typeof f==="object"||d.isArray(f)?b:"")+"]",f,c,e)});else if(c||b==null||typeof b!=="object")e(a,b);else if(d.isArray(b)||d.isEmptyObject(b))e(a,"");else for(var f in b)bQ(a+"["+f+"]",b[f],c,e)}function bP(a,c,d,e,f,g){f=f||c.dataTypes[0],g=g||{},g[f]=!0;var h=a[f],i=0,j=h?h.length:0,k=a===bJ,l;for(;i<j&&(k||!l);i++)l=h[i](c,d,e),typeof l==="string"&&(!k||g[l]?l=b:(c.dataTypes.unshift(l),l=bP(a,c,d,e,l,g)));(k||!l)&&!g["*"]&&(l=bP(a,c,d,e,"*",g));return l}function bO(a){return function(b,c){typeof b!=="string"&&(c=b,b="*");if(d.isFunction(c)){var e=b.toLowerCase().split(bD),f=0,g=e.length,h,i,j;for(;f<g;f++)h=e[f],j=/^\+/.test(h),j&&(h=h.substr(1)||"*"),i=a[h]=a[h]||[],i[j?"unshift":"push"](c)}}}function bq(a,b,c){var e=b==="width"?bk:bl,f=b==="width"?a.offsetWidth:a.offsetHeight;if(c==="border")return f;d.each(e,function(){c||(f-=parseFloat(d.css(a,"padding"+this))||0),c==="margin"?f+=parseFloat(d.css(a,"margin"+this))||0:f-=parseFloat(d.css(a,"border"+this+"Width"))||0});return f}function bc(a,b){b.src?d.ajax({url:b.src,async:!1,dataType:"script"}):d.globalEval(b.text||b.textContent||b.innerHTML||""),b.parentNode&&b.parentNode.removeChild(b)}function bb(a){return"getElementsByTagName"in a?a.getElementsByTagName("*"):"querySelectorAll"in a?a.querySelectorAll("*"):[]}function ba(a,b){if(b.nodeType===1){var c=b.nodeName.toLowerCase();b.clearAttributes(),b.mergeAttributes(a);if(c==="object")b.outerHTML=a.outerHTML;else if(c!=="input"||a.type!=="checkbox"&&a.type!=="radio"){if(c==="option")b.selected=a.defaultSelected;else if(c==="input"||c==="textarea")b.defaultValue=a.defaultValue}else a.checked&&(b.defaultChecked=b.checked=a.checked),b.value!==a.value&&(b.value=a.value);b.removeAttribute(d.expando)}}function _(a,b){if(b.nodeType===1&&d.hasData(a)){var c=d.expando,e=d.data(a),f=d.data(b,e);if(e=e[c]){var g=e.events;f=f[c]=d.extend({},e);if(g){delete f.handle,f.events={};for(var h in g)for(var i=0,j=g[h].length;i<j;i++)d.event.add(b,h+(g[h][i].namespace?".":"")+g[h][i].namespace,g[h][i],g[h][i].data)}}}}function $(a,b){return d.nodeName(a,"table")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function Q(a,b,c){if(d.isFunction(b))return d.grep(a,function(a,d){var e=!!b.call(a,d,a);return e===c});if(b.nodeType)return d.grep(a,function(a,d){return a===b===c});if(typeof b==="string"){var e=d.grep(a,function(a){return a.nodeType===1});if(L.test(b))return d.filter(b,e,!c);b=d.filter(b,e)}return d.grep(a,function(a,e){return d.inArray(a,b)>=0===c})}function P(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function H(a,b){return(a&&a!=="*"?a+".":"")+b.replace(t,"`").replace(u,"&")}function G(a){var b,c,e,f,g,h,i,j,k,l,m,n,o,p=[],q=[],s=d._data(this,"events");if(a.liveFired!==this&&s&&s.live&&!a.target.disabled&&(!a.button||a.type!=="click")){a.namespace&&(n=new RegExp("(^|\\.)"+a.namespace.split(".").join("\\.(?:.*\\.)?")+"(\\.|$)")),a.liveFired=this;var t=s.live.slice(0);for(i=0;i<t.length;i++)g=t[i],g.origType.replace(r,"")===a.type?q.push(g.selector):t.splice(i--,1);f=d(a.target).closest(q,a.currentTarget);for(j=0,k=f.length;j<k;j++){m=f[j];for(i=0;i<t.length;i++){g=t[i];if(m.selector===g.selector&&(!n||n.test(g.namespace))&&!m.elem.disabled){h=m.elem,e=null;if(g.preType==="mouseenter"||g.preType==="mouseleave")a.type=g.preType,e=d(a.relatedTarget).closest(g.selector)[0];(!e||e!==h)&&p.push({elem:h,handleObj:g,level:m.level})}}}for(j=0,k=p.length;j<k;j++){f=p[j];if(c&&f.level>c)break;a.currentTarget=f.elem,a.data=f.handleObj.data,a.handleObj=f.handleObj,o=f.handleObj.origHandler.apply(f.elem,arguments);if(o===!1||a.isPropagationStopped()){c=f.level,o===!1&&(b=!1);if(a.isImmediatePropagationStopped())break}}return b}}function E(a,c,e){var f=d.extend({},e[0]);f.type=a,f.originalEvent={},f.liveFired=b,d.event.handle.call(c,f),f.isDefaultPrevented()&&e[0].preventDefault()}function y(){return!0}function x(){return!1}function i(a){for(var b in a)if(b!=="toJSON")return!1;return!0}function h(a,c,e){if(e===b&&a.nodeType===1){e=a.getAttribute("data-"+c);if(typeof e==="string"){try{e=e==="true"?!0:e==="false"?!1:e==="null"?null:d.isNaN(e)?g.test(e)?d.parseJSON(e):e:parseFloat(e)}catch(f){}d.data(a,c,e)}else e=b}return e}var c=a.document,d=function(){function G(){if(!d.isReady){try{c.documentElement.doScroll("left")}catch(a){setTimeout(G,1);return}d.ready()}}var d=function(a,b){return new d.fn.init(a,b,g)},e=a.jQuery,f=a.$,g,h=/^(?:[^<]*(<[\w\W]+>)[^>]*$|#([\w\-]+)$)/,i=/\S/,j=/^\s+/,k=/\s+$/,l=/\d/,m=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,n=/^[\],:{}\s]*$/,o=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,p=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,q=/(?:^|:|,)(?:\s*\[)+/g,r=/(webkit)[ \/]([\w.]+)/,s=/(opera)(?:.*version)?[ \/]([\w.]+)/,t=/(msie) ([\w.]+)/,u=/(mozilla)(?:.*? rv:([\w.]+))?/,v=navigator.userAgent,w,x,y,z=Object.prototype.toString,A=Object.prototype.hasOwnProperty,B=Array.prototype.push,C=Array.prototype.slice,D=String.prototype.trim,E=Array.prototype.indexOf,F={};d.fn=d.prototype={constructor:d,init:function(a,e,f){var g,i,j,k;if(!a)return this;if(a.nodeType){this.context=this[0]=a,this.length=1;return this}if(a==="body"&&!e&&c.body){this.context=c,this[0]=c.body,this.selector="body",this.length=1;return this}if(typeof a==="string"){g=h.exec(a);if(!g||!g[1]&&e)return!e||e.jquery?(e||f).find(a):this.constructor(e).find(a);if(g[1]){e=e instanceof d?e[0]:e,k=e?e.ownerDocument||e:c,j=m.exec(a),j?d.isPlainObject(e)?(a=[c.createElement(j[1])],d.fn.attr.call(a,e,!0)):a=[k.createElement(j[1])]:(j=d.buildFragment([g[1]],[k]),a=(j.cacheable?d.clone(j.fragment):j.fragment).childNodes);return d.merge(this,a)}i=c.getElementById(g[2]);if(i&&i.parentNode){if(i.id!==g[2])return f.find(a);this.length=1,this[0]=i}this.context=c,this.selector=a;return this}if(d.isFunction(a))return f.ready(a);a.selector!==b&&(this.selector=a.selector,this.context=a.context);return d.makeArray(a,this)},selector:"",jquery:"1.5.2",length:0,size:function(){return this.length},toArray:function(){return C.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var e=this.constructor();d.isArray(a)?B.apply(e,a):d.merge(e,a),e.prevObject=this,e.context=this.context,b==="find"?e.selector=this.selector+(this.selector?" ":"")+c:b&&(e.selector=this.selector+"."+b+"("+c+")");return e},each:function(a,b){return d.each(this,a,b)},ready:function(a){d.bindReady(),x.done(a);return this},eq:function(a){return a===-1?this.slice(a):this.slice(a,+a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(C.apply(this,arguments),"slice",C.call(arguments).join(","))},map:function(a){return this.pushStack(d.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:B,sort:[].sort,splice:[].splice},d.fn.init.prototype=d.fn,d.extend=d.fn.extend=function(){var a,c,e,f,g,h,i=arguments[0]||{},j=1,k=arguments.length,l=!1;typeof i==="boolean"&&(l=i,i=arguments[1]||{},j=2),typeof i!=="object"&&!d.isFunction(i)&&(i={}),k===j&&(i=this,--j);for(;j<k;j++)if((a=arguments[j])!=null)for(c in a){e=i[c],f=a[c];if(i===f)continue;l&&f&&(d.isPlainObject(f)||(g=d.isArray(f)))?(g?(g=!1,h=e&&d.isArray(e)?e:[]):h=e&&d.isPlainObject(e)?e:{},i[c]=d.extend(l,h,f)):f!==b&&(i[c]=f)}return i},d.extend({noConflict:function(b){a.$=f,b&&(a.jQuery=e);return d},isReady:!1,readyWait:1,ready:function(a){a===!0&&d.readyWait--;if(!d.readyWait||a!==!0&&!d.isReady){if(!c.body)return setTimeout(d.ready,1);d.isReady=!0;if(a!==!0&&--d.readyWait>0)return;x.resolveWith(c,[d]),d.fn.trigger&&d(c).trigger("ready").unbind("ready")}},bindReady:function(){if(!x){x=d._Deferred();if(c.readyState==="complete")return setTimeout(d.ready,1);if(c.addEventListener)c.addEventListener("DOMContentLoaded",y,!1),a.addEventListener("load",d.ready,!1);else if(c.attachEvent){c.attachEvent("onreadystatechange",y),a.attachEvent("onload",d.ready);var b=!1;try{b=a.frameElement==null}catch(e){}c.documentElement.doScroll&&b&&G()}}},isFunction:function(a){return d.type(a)==="function"},isArray:Array.isArray||function(a){return d.type(a)==="array"},isWindow:function(a){return a&&typeof a==="object"&&"setInterval"in a},isNaN:function(a){return a==null||!l.test(a)||isNaN(a)},type:function(a){return a==null?String(a):F[z.call(a)]||"object"},isPlainObject:function(a){if(!a||d.type(a)!=="object"||a.nodeType||d.isWindow(a))return!1;if(a.constructor&&!A.call(a,"constructor")&&!A.call(a.constructor.prototype,"isPrototypeOf"))return!1;var c;for(c in a){}return c===b||A.call(a,c)},isEmptyObject:function(a){for(var b in a)return!1;return!0},error:function(a){throw a},parseJSON:function(b){if(typeof b!=="string"||!b)return null;b=d.trim(b);if(n.test(b.replace(o,"@").replace(p,"]").replace(q,"")))return a.JSON&&a.JSON.parse?a.JSON.parse(b):(new Function("return "+b))();d.error("Invalid JSON: "+b)},parseXML:function(b,c,e){a.DOMParser?(e=new DOMParser,c=e.parseFromString(b,"text/xml")):(c=new ActiveXObject("Microsoft.XMLDOM"),c.async="false",c.loadXML(b)),e=c.documentElement,(!e||!e.nodeName||e.nodeName==="parsererror")&&d.error("Invalid XML: "+b);return c},noop:function(){},globalEval:function(a){if(a&&i.test(a)){var b=c.head||c.getElementsByTagName("head")[0]||c.documentElement,e=c.createElement("script");d.support.scriptEval()?e.appendChild(c.createTextNode(a)):e.text=a,b.insertBefore(e,b.firstChild),b.removeChild(e)}},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,e){var f,g=0,h=a.length,i=h===b||d.isFunction(a);if(e){if(i){for(f in a)if(c.apply(a[f],e)===!1)break}else for(;g<h;)if(c.apply(a[g++],e)===!1)break}else if(i){for(f in a)if(c.call(a[f],f,a[f])===!1)break}else for(var j=a[0];g<h&&c.call(j,g,j)!==!1;j=a[++g]){}return a},trim:D?function(a){return a==null?"":D.call(a)}:function(a){return a==null?"":(a+"").replace(j,"").replace(k,"")},makeArray:function(a,b){var c=b||[];if(a!=null){var e=d.type(a);a.length==null||e==="string"||e==="function"||e==="regexp"||d.isWindow(a)?B.call(c,a):d.merge(c,a)}return c},inArray:function(a,b){if(b.indexOf)return b.indexOf(a);for(var c=0,d=b.length;c<d;c++)if(b[c]===a)return c;return-1},merge:function(a,c){var d=a.length,e=0;if(typeof c.length==="number")for(var f=c.length;e<f;e++)a[d++]=c[e];else while(c[e]!==b)a[d++]=c[e++];a.length=d;return a},grep:function(a,b,c){var d=[],e;c=!!c;for(var f=0,g=a.length;f<g;f++)e=!!b(a[f],f),c!==e&&d.push(a[f]);return d},map:function(a,b,c){var d=[],e;for(var f=0,g=a.length;f<g;f++)e=b(a[f],f,c),e!=null&&(d[d.length]=e);return d.concat.apply([],d)},guid:1,proxy:function(a,c,e){arguments.length===2&&(typeof c==="string"?(e=a,a=e[c],c=b):c&&!d.isFunction(c)&&(e=c,c=b)),!c&&a&&(c=function(){return a.apply(e||this,arguments)}),a&&(c.guid=a.guid=a.guid||c.guid||d.guid++);return c},access:function(a,c,e,f,g,h){var i=a.length;if(typeof c==="object"){for(var j in c)d.access(a,j,c[j],f,g,e);return a}if(e!==b){f=!h&&f&&d.isFunction(e);for(var k=0;k<i;k++)g(a[k],c,f?e.call(a[k],k,g(a[k],c)):e,h);return a}return i?g(a[0],c):b},now:function(){return(new Date).getTime()},uaMatch:function(a){a=a.toLowerCase();var b=r.exec(a)||s.exec(a)||t.exec(a)||a.indexOf("compatible")<0&&u.exec(a)||[];return{browser:b[1]||"",version:b[2]||"0"}},sub:function(){function a(b,c){return new a.fn.init(b,c)}d.extend(!0,a,this),a.superclass=this,a.fn=a.prototype=this(),a.fn.constructor=a,a.subclass=this.subclass,a.fn.init=function b(b,c){c&&c instanceof d&&!(c instanceof a)&&(c=a(c));return d.fn.init.call(this,b,c,e)},a.fn.init.prototype=a.fn;var e=a(c);return a},browser:{}}),d.each("Boolean Number String Function Array Date RegExp Object".split(" "),function(a,b){F["[object "+b+"]"]=b.toLowerCase()}),w=d.uaMatch(v),w.browser&&(d.browser[w.browser]=!0,d.browser.version=w.version),d.browser.webkit&&(d.browser.safari=!0),E&&(d.inArray=function(a,b){return E.call(b,a)}),i.test(" ")&&(j=/^[\s\xA0]+/,k=/[\s\xA0]+$/),g=d(c),c.addEventListener?y=function(){c.removeEventListener("DOMContentLoaded",y,!1),d.ready()}:c.attachEvent&&(y=function(){c.readyState==="complete"&&(c.detachEvent("onreadystatechange",y),d.ready())});return d}(),e="then done fail isResolved isRejected promise".split(" "),f=[].slice;d.extend({_Deferred:function(){var a=[],b,c,e,f={done:function(){if(!e){var c=arguments,g,h,i,j,k;b&&(k=b,b=0);for(g=0,h=c.length;g<h;g++)i=c[g],j=d.type(i),j==="array"?f.done.apply(f,i):j==="function"&&a.push(i);k&&f.resolveWith(k[0],k[1])}return this},resolveWith:function(d,f){if(!e&&!b&&!c){f=f||[],c=1;try{while(a[0])a.shift().apply(d,f)}finally{b=[d,f],c=0}}return this},resolve:function(){f.resolveWith(this,arguments);return this},isResolved:function(){return c||b},cancel:function(){e=1,a=[];return this}};return f},Deferred:function(a){var b=d._Deferred(),c=d._Deferred(),f;d.extend(b,{then:function(a,c){b.done(a).fail(c);return this},fail:c.done,rejectWith:c.resolveWith,reject:c.resolve,isRejected:c.isResolved,promise:function(a){if(a==null){if(f)return f;f=a={}}var c=e.length;while(c--)a[e[c]]=b[e[c]];return a}}),b.done(c.cancel).fail(b.cancel),delete b.cancel,a&&a.call(b,b);return b},when:function(a){function i(a){return function(c){b[a]=arguments.length>1?f.call(arguments,0):c,--g||h.resolveWith(h,f.call(b,0))}}var b=arguments,c=0,e=b.length,g=e,h=e<=1&&a&&d.isFunction(a.promise)?a:d.Deferred();if(e>1){for(;c<e;c++)b[c]&&d.isFunction(b[c].promise)?b[c].promise().then(i(c),h.reject):--g;g||h.resolveWith(h,b)}else h!==a&&h.resolveWith(h,e?[a]:[]);return h.promise()}}),function(){d.support={};var b=c.createElement("div");b.style.display="none",b.innerHTML=" <link/><table></table><a href='/a' style='color:red;float:left;opacity:.55;'>a</a><input type='checkbox'/>";var e=b.getElementsByTagName("*"),f=b.getElementsByTagName("a")[0],g=c.createElement("select"),h=g.appendChild(c.createElement("option")),i=b.getElementsByTagName("input")[0];if(e&&e.length&&f){d.support={leadingWhitespace:b.firstChild.nodeType===3,tbody:!b.getElementsByTagName("tbody").length,htmlSerialize:!!b.getElementsByTagName("link").length,style:/red/.test(f.getAttribute("style")),hrefNormalized:f.getAttribute("href")==="/a",opacity:/^0.55$/.test(f.style.opacity),cssFloat:!!f.style.cssFloat,checkOn:i.value==="on",optSelected:h.selected,deleteExpando:!0,optDisabled:!1,checkClone:!1,noCloneEvent:!0,noCloneChecked:!0,boxModel:null,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableHiddenOffsets:!0,reliableMarginRight:!0},i.checked=!0,d.support.noCloneChecked=i.cloneNode(!0).checked,g.disabled=!0,d.support.optDisabled=!h.disabled;var j=null;d.support.scriptEval=function(){if(j===null){var b=c.documentElement,e=c.createElement("script"),f="script"+d.now();try{e.appendChild(c.createTextNode("window."+f+"=1;"))}catch(g){}b.insertBefore(e,b.firstChild),a[f]?(j=!0,delete a[f]):j=!1,b.removeChild(e)}return j};try{delete b.test}catch(k){d.support.deleteExpando=!1}!b.addEventListener&&b.attachEvent&&b.fireEvent&&(b.attachEvent("onclick",function l(){d.support.noCloneEvent=!1,b.detachEvent("onclick",l)}),b.cloneNode(!0).fireEvent("onclick")),b=c.createElement("div"),b.innerHTML="<input type='radio' name='radiotest' checked='checked'/>";var m=c.createDocumentFragment();m.appendChild(b.firstChild),d.support.checkClone=m.cloneNode(!0).cloneNode(!0).lastChild.checked,d(function(){var a=c.createElement("div"),b=c.getElementsByTagName("body")[0];if(b){a.style.width=a.style.paddingLeft="1px",b.appendChild(a),d.boxModel=d.support.boxModel=a.offsetWidth===2,"zoom"in a.style&&(a.style.display="inline",a.style.zoom=1,d.support.inlineBlockNeedsLayout=a.offsetWidth===2,a.style.display="",a.innerHTML="<div style='width:4px;'></div>",d.support.shrinkWrapBlocks=a.offsetWidth!==2),a.innerHTML="<table><tr><td style='padding:0;border:0;display:none'></td><td>t</td></tr></table>";var e=a.getElementsByTagName("td");d.support.reliableHiddenOffsets=e[0].offsetHeight===0,e[0].style.display="",e[1].style.display="none",d.support.reliableHiddenOffsets=d.support.reliableHiddenOffsets&&e[0].offsetHeight===0,a.innerHTML="",c.defaultView&&c.defaultView.getComputedStyle&&(a.style.width="1px",a.style.marginRight="0",d.support.reliableMarginRight=(parseInt(c.defaultView.getComputedStyle(a,null).marginRight,10)||0)===0),b.removeChild(a).style.display="none",a=e=null}});var n=function(a){var b=c.createElement("div");a="on"+a;if(!b.attachEvent)return!0;var d=a in b;d||(b.setAttribute(a,"return;"),d=typeof b[a]==="function");return d};d.support.submitBubbles=n("submit"),d.support.changeBubbles=n("change"),b=e=f=null}}();var g=/^(?:\{.*\}|\[.*\])$/;d.extend({cache:{},uuid:0,expando:"jQuery"+(d.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){a=a.nodeType?d.cache[a[d.expando]]:a[d.expando];return!!a&&!i(a)},data:function(a,c,e,f){if(d.acceptData(a)){var g=d.expando,h=typeof c==="string",i,j=a.nodeType,k=j?d.cache:a,l=j?a[d.expando]:a[d.expando]&&d.expando;if((!l||f&&l&&!k[l][g])&&h&&e===b)return;l||(j?a[d.expando]=l=++d.uuid:l=d.expando),k[l]||(k[l]={},j||(k[l].toJSON=d.noop));if(typeof c==="object"||typeof c==="function")f?k[l][g]=d.extend(k[l][g],c):k[l]=d.extend(k[l],c);i=k[l],f&&(i[g]||(i[g]={}),i=i[g]),e!==b&&(i[c]=e);if(c==="events"&&!i[c])return i[g]&&i[g].events;return h?i[c]:i}},removeData:function(b,c,e){if(d.acceptData(b)){var f=d.expando,g=b.nodeType,h=g?d.cache:b,j=g?b[d.expando]:d.expando;if(!h[j])return;if(c){var k=e?h[j][f]:h[j];if(k){delete k[c];if(!i(k))return}}if(e){delete h[j][f];if(!i(h[j]))return}var l=h[j][f];d.support.deleteExpando||h!=a?delete h[j]:h[j]=null,l?(h[j]={},g||(h[j].toJSON=d.noop),h[j][f]=l):g&&(d.support.deleteExpando?delete b[d.expando]:b.removeAttribute?b.removeAttribute(d.expando):b[d.expando]=null)}},_data:function(a,b,c){return d.data(a,b,c,!0)},acceptData:function(a){if(a.nodeName){var b=d.noData[a.nodeName.toLowerCase()];if(b)return b!==!0&&a.getAttribute("classid")===b}return!0}}),d.fn.extend({data:function(a,c){var e=null;if(typeof a==="undefined"){if(this.length){e=d.data(this[0]);if(this[0].nodeType===1){var f=this[0].attributes,g;for(var i=0,j=f.length;i<j;i++)g=f[i].name,g.indexOf("data-")===0&&(g=g.substr(5),h(this[0],g,e[g]))}}return e}if(typeof a==="object")return this.each(function(){d.data(this,a)});var k=a.split(".");k[1]=k[1]?"."+k[1]:"";if(c===b){e=this.triggerHandler("getData"+k[1]+"!",[k[0]]),e===b&&this.length&&(e=d.data(this[0],a),e=h(this[0],a,e));return e===b&&k[1]?this.data(k[0]):e}return this.each(function(){var b=d(this),e=[k[0],c];b.triggerHandler("setData"+k[1]+"!",e),d.data(this,a,c),b.triggerHandler("changeData"+k[1]+"!",e)})},removeData:function(a){return this.each(function(){d.removeData(this,a)})}}),d.extend({queue:function(a,b,c){if(a){b=(b||"fx")+"queue";var e=d._data(a,b);if(!c)return e||[];!e||d.isArray(c)?e=d._data(a,b,d.makeArray(c)):e.push(c);return e}},dequeue:function(a,b){b=b||"fx";var c=d.queue(a,b),e=c.shift();e==="inprogress"&&(e=c.shift()),e&&(b==="fx"&&c.unshift("inprogress"),e.call(a,function(){d.dequeue(a,b)})),c.length||d.removeData(a,b+"queue",!0)}}),d.fn.extend({queue:function(a,c){typeof a!=="string"&&(c=a,a="fx");if(c===b)return d.queue(this[0],a);return this.each(function(b){var e=d.queue(this,a,c);a==="fx"&&e[0]!=="inprogress"&&d.dequeue(this,a)})},dequeue:function(a){return this.each(function(){d.dequeue(this,a)})},delay:function(a,b){a=d.fx?d.fx.speeds[a]||a:a,b=b||"fx";return this.queue(b,function(){var c=this;setTimeout(function(){d.dequeue(c,b)},a)})},clearQueue:function(a){return this.queue(a||"fx",[])}});var j=/[\n\t\r]/g,k=/\s+/,l=/\r/g,m=/^(?:href|src|style)$/,n=/^(?:button|input)$/i,o=/^(?:button|input|object|select|textarea)$/i,p=/^a(?:rea)?$/i,q=/^(?:radio|checkbox)$/i;d.props={"for":"htmlFor","class":"className",readonly:"readOnly",maxlength:"maxLength",cellspacing:"cellSpacing",rowspan:"rowSpan",colspan:"colSpan",tabindex:"tabIndex",usemap:"useMap",frameborder:"frameBorder"},d.fn.extend({attr:function(a,b){return d.access(this,a,b,!0,d.attr)},removeAttr:function(a,b){return this.each(function(){d.attr(this,a,""),this.nodeType===1&&this.removeAttribute(a)})},addClass:function(a){if(d.isFunction(a))return this.each(function(b){var c=d(this);c.addClass(a.call(this,b,c.attr("class")))});if(a&&typeof a==="string"){var b=(a||"").split(k);for(var c=0,e=this.length;c<e;c++){var f=this[c];if(f.nodeType===1)if(f.className){var g=" "+f.className+" ",h=f.className;for(var i=0,j=b.length;i<j;i++)g.indexOf(" "+b[i]+" ")<0&&(h+=" "+b[i]);f.className=d.trim(h)}else f.className=a}}return this},removeClass:function(a){if(d.isFunction(a))return this.each(function(b){var c=d(this);c.removeClass(a.call(this,b,c.attr("class")))});if(a&&typeof a==="string"||a===b){var c=(a||"").split(k);for(var e=0,f=this.length;e<f;e++){var g=this[e];if(g.nodeType===1&&g.className)if(a){var h=(" "+g.className+" ").replace(j," ");for(var i=0,l=c.length;i<l;i++)h=h.replace(" "+c[i]+" "," ");g.className=d.trim(h)}else g.className=""}}return this},toggleClass:function(a,b){var c=typeof a,e=typeof b==="boolean";if(d.isFunction(a))return this.each(function(c){var e=d(this);e.toggleClass(a.call(this,c,e.attr("class"),b),b)});return this.each(function(){if(c==="string"){var f,g=0,h=d(this),i=b,j=a.split(k);while(f=j[g++])i=e?i:!h.hasClass(f),h[i?"addClass":"removeClass"](f)}else if(c==="undefined"||c==="boolean")this.className&&d._data(this,"__className__",this.className),this.className=this.className||a===!1?"":d._data(this,"__className__")||""})},hasClass:function(a){var b=" "+a+" ";for(var c=0,d=this.length;c<d;c++)if((" "+this[c].className+" ").replace(j," ").indexOf(b)>-1)return!0;return!1},val:function(a){if(!arguments.length){var c=this[0];if(c){if(d.nodeName(c,"option")){var e=c.attributes.value;return!e||e.specified?c.value:c.text}if(d.nodeName(c,"select")){var f=c.selectedIndex,g=[],h=c.options,i=c.type==="select-one";if(f<0)return null;for(var j=i?f:0,k=i?f+1:h.length;j<k;j++){var m=h[j];if(m.selected&&(d.support.optDisabled?!m.disabled:m.getAttribute("disabled")===null)&&(!m.parentNode.disabled||!d.nodeName(m.parentNode,"optgroup"))){a=d(m).val();if(i)return a;g.push(a)}}if(i&&!g.length&&h.length)return d(h[f]).val();return g}if(q.test(c.type)&&!d.support.checkOn)return c.getAttribute("value")===null?"on":c.value;return(c.value||"").replace(l,"")}return b}var n=d.isFunction(a);return this.each(function(b){var c=d(this),e=a;if(this.nodeType===1){n&&(e=a.call(this,b,c.val())),e==null?e="":typeof e==="number"?e+="":d.isArray(e)&&(e=d.map(e,function(a){return a==null?"":a+""}));if(d.isArray(e)&&q.test(this.type))this.checked=d.inArray(c.val(),e)>=0;else if(d.nodeName(this,"select")){var f=d.makeArray(e);d("option",this).each(function(){this.selected=d.inArray(d(this).val(),f)>=0}),f.length||(this.selectedIndex=-1)}else this.value=e}})}}),d.extend({attrFn:{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0},attr:function(a,c,e,f){if(!a||a.nodeType===3||a.nodeType===8||a.nodeType===2)return b;if(f&&c in d.attrFn)return d(a)[c](e);var g=a.nodeType!==1||!d.isXMLDoc(a),h=e!==b;c=g&&d.props[c]||c;if(a.nodeType===1){var i=m.test(c);if(c==="selected"&&!d.support.optSelected){var j=a.parentNode;j&&(j.selectedIndex,j.parentNode&&j.parentNode.selectedIndex)}if((c in a||a[c]!==b)&&g&&!i){h&&(c==="type"&&n.test(a.nodeName)&&a.parentNode&&d.error("type property can't be changed"),e===null?a.nodeType===1&&a.removeAttribute(c):a[c]=e);if(d.nodeName(a,"form")&&a.getAttributeNode(c))return a.getAttributeNode(c).nodeValue;if(c==="tabIndex"){var k=a.getAttributeNode("tabIndex");return k&&k.specified?k.value:o.test(a.nodeName)||p.test(a.nodeName)&&a.href?0:b}return a[c]}if(!d.support.style&&g&&c==="style"){h&&(a.style.cssText=""+e);return a.style.cssText}h&&a.setAttribute(c,""+e);if(!a.attributes[c]&&(a.hasAttribute&&!a.hasAttribute(c)))return b;var l=!d.support.hrefNormalized&&g&&i?a.getAttribute(c,2):a.getAttribute(c);return l===null?b:l}h&&(a[c]=e);return a[c]}});var r=/\.(.*)$/,s=/^(?:textarea|input|select)$/i,t=/\./g,u=/ /g,v=/[^\w\s.|`]/g,w=function(a){return a.replace(v,"\\$&")};d.event={add:function(c,e,f,g){if(c.nodeType!==3&&c.nodeType!==8){try{d.isWindow(c)&&(c!==a&&!c.frameElement)&&(c=a)}catch(h){}if(f===!1)f=x;else if(!f)return;var i,j;f.handler&&(i=f,f=i.handler),f.guid||(f.guid=d.guid++);var k=d._data(c);if(!k)return;var l=k.events,m=k.handle;l||(k.events=l={}),m||(k.handle=m=function(a){return typeof d!=="undefined"&&d.event.triggered!==a.type?d.event.handle.apply(m.elem,arguments):b}),m.elem=c,e=e.split(" ");var n,o=0,p;while(n=e[o++]){j=i?d.extend({},i):{handler:f,data:g},n.indexOf(".")>-1?(p=n.split("."),n=p.shift(),j.namespace=p.slice(0).sort().join(".")):(p=[],j.namespace=""),j.type=n,j.guid||(j.guid=f.guid);var q=l[n],r=d.event.special[n]||{};if(!q){q=l[n]=[];if(!r.setup||r.setup.call(c,g,p,m)===!1)c.addEventListener?c.addEventListener(n,m,!1):c.attachEvent&&c.attachEvent("on"+n,m)}r.add&&(r.add.call(c,j),j.handler.guid||(j.handler.guid=f.guid)),q.push(j),d.event.global[n]=!0}c=null}},global:{},remove:function(a,c,e,f){if(a.nodeType!==3&&a.nodeType!==8){e===!1&&(e=x);var g,h,i,j,k=0,l,m,n,o,p,q,r,s=d.hasData(a)&&d._data(a),t=s&&s.events;if(!s||!t)return;c&&c.type&&(e=c.handler,c=c.type);if(!c||typeof c==="string"&&c.charAt(0)==="."){c=c||"";for(h in t)d.event.remove(a,h+c);return}c=c.split(" ");while(h=c[k++]){r=h,q=null,l=h.indexOf(".")<0,m=[],l||(m=h.split("."),h=m.shift(),n=new RegExp("(^|\\.)"+d.map(m.slice(0).sort(),w).join("\\.(?:.*\\.)?")+"(\\.|$)")),p=t[h];if(!p)continue;if(!e){for(j=0;j<p.length;j++){q=p[j];if(l||n.test(q.namespace))d.event.remove(a,r,q.handler,j),p.splice(j--,1)}continue}o=d.event.special[h]||{};for(j=f||0;j<p.length;j++){q=p[j];if(e.guid===q.guid){if(l||n.test(q.namespace))f==null&&p.splice(j--,1),o.remove&&o.remove.call(a,q);if(f!=null)break}}if(p.length===0||f!=null&&p.length===1)(!o.teardown||o.teardown.call(a,m)===!1)&&d.removeEvent(a,h,s.handle),g=null,delete t[h]}if(d.isEmptyObject(t)){var u=s.handle;u&&(u.elem=null),delete s.events,delete s.handle,d.isEmptyObject(s)&&d.removeData(a,b,!0)}}},trigger:function(a,c,e){var f=a.type||a,g=arguments[3];if(!g){a=typeof a==="object"?a[d.expando]?a:d.extend(d.Event(f),a):d.Event(f),f.indexOf("!")>=0&&(a.type=f=f.slice(0,-1),a.exclusive=!0),e||(a.stopPropagation(),d.event.global[f]&&d.each(d.cache,function(){var b=d.expando,e=this[b];e&&e.events&&e.events[f]&&d.event.trigger(a,c,e.handle.elem)}));if(!e||e.nodeType===3||e.nodeType===8)return b;a.result=b,a.target=e,c=d.makeArray(c),c.unshift(a)}a.currentTarget=e;var h=d._data(e,"handle");h&&h.apply(e,c);var i=e.parentNode||e.ownerDocument;try{e&&e.nodeName&&d.noData[e.nodeName.toLowerCase()]||e["on"+f]&&e["on"+f].apply(e,c)===!1&&(a.result=!1,a.preventDefault())}catch(j){}if(!a.isPropagationStopped()&&i)d.event.trigger(a,c,i,!0);else if(!a.isDefaultPrevented()){var k,l=a.target,m=f.replace(r,""),n=d.nodeName(l,"a")&&m==="click",o=d.event.special[m]||{};if((!o._default||o._default.call(e,a)===!1)&&!n&&!(l&&l.nodeName&&d.noData[l.nodeName.toLowerCase()])){try{l[m]&&(k=l["on"+m],k&&(l["on"+m]=null),d.event.triggered=a.type,l[m]())}catch(p){}k&&(l["on"+m]=k),d.event.triggered=b}}},handle:function(c){var e,f,g,h,i,j=[],k=d.makeArray(arguments);c=k[0]=d.event.fix(c||a.event),c.currentTarget=this,e=c.type.indexOf(".")<0&&!c.exclusive,e||(g=c.type.split("."),c.type=g.shift(),j=g.slice(0).sort(),h=new RegExp("(^|\\.)"+j.join("\\.(?:.*\\.)?")+"(\\.|$)")),c.namespace=c.namespace||j.join("."),i=d._data(this,"events"),f=(i||{})[c.type];if(i&&f){f=f.slice(0);for(var l=0,m=f.length;l<m;l++){var n=f[l];if(e||h.test(n.namespace)){c.handler=n.handler,c.data=n.data,c.handleObj=n;var o=n.handler.apply(this,k);o!==b&&(c.result=o,o===!1&&(c.preventDefault(),c.stopPropagation()));if(c.isImmediatePropagationStopped())break}}}return c.result},props:"altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),fix:function(a){if(a[d.expando])return a;var e=a;a=d.Event(e);for(var f=this.props.length,g;f;)g=this.props[--f],a[g]=e[g];a.target||(a.target=a.srcElement||c),a.target.nodeType===3&&(a.target=a.target.parentNode),!a.relatedTarget&&a.fromElement&&(a.relatedTarget=a.fromElement===a.target?a.toElement:a.fromElement);if(a.pageX==null&&a.clientX!=null){var h=c.documentElement,i=c.body;a.pageX=a.clientX+(h&&h.scrollLeft||i&&i.scrollLeft||0)-(h&&h.clientLeft||i&&i.clientLeft||0),a.pageY=a.clientY+(h&&h.scrollTop||i&&i.scrollTop||0)-(h&&h.clientTop||i&&i.clientTop||0)}a.which==null&&(a.charCode!=null||a.keyCode!=null)&&(a.which=a.charCode!=null?a.charCode:a.keyCode),!a.metaKey&&a.ctrlKey&&(a.metaKey=a.ctrlKey),!a.which&&a.button!==b&&(a.which=a.button&1?1:a.button&2?3:a.button&4?2:0);return a},guid:1e8,proxy:d.proxy,special:{ready:{setup:d.bindReady,teardown:d.noop},live:{add:function(a){d.event.add(this,H(a.origType,a.selector),d.extend({},a,{handler:G,guid:a.handler.guid}))},remove:function(a){d.event.remove(this,H(a.origType,a.selector),a)}},beforeunload:{setup:function(a,b,c){d.isWindow(this)&&(this.onbeforeunload=c)},teardown:function(a,b){this.onbeforeunload===b&&(this.onbeforeunload=null)}}}},d.removeEvent=c.removeEventListener?function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c,!1)}:function(a,b,c){a.detachEvent&&a.detachEvent("on"+b,c)},d.Event=function(a){if(!this.preventDefault)return new d.Event(a);a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||a.returnValue===!1||a.getPreventDefault&&a.getPreventDefault()?y:x):this.type=a,this.timeStamp=d.now(),this[d.expando]=!0},d.Event.prototype={preventDefault:function(){this.isDefaultPrevented=y;var a=this.originalEvent;a&&(a.preventDefault?a.preventDefault():a.returnValue=!1)},stopPropagation:function(){this.isPropagationStopped=y;var a=this.originalEvent;a&&(a.stopPropagation&&a.stopPropagation(),a.cancelBubble=!0)},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=y,this.stopPropagation()},isDefaultPrevented:x,isPropagationStopped:x,isImmediatePropagationStopped:x};var z=function(a){var b=a.relatedTarget;try{if(b&&b!==c&&!b.parentNode)return;while(b&&b!==this)b=b.parentNode;b!==this&&(a.type=a.data,d.event.handle.apply(this,arguments))}catch(e){}},A=function(a){a.type=a.data,d.event.handle.apply(this,arguments)};d.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){d.event.special[a]={setup:function(c){d.event.add(this,b,c&&c.selector?A:z,a)},teardown:function(a){d.event.remove(this,b,a&&a.selector?A:z)}}}),d.support.submitBubbles||(d.event.special.submit={setup:function(a,b){if(this.nodeName&&this.nodeName.toLowerCase()!=="form")d.event.add(this,"click.specialSubmit",function(a){var b=a.target,c=b.type;(c==="submit"||c==="image")&&d(b).closest("form").length&&E("submit",this,arguments)}),d.event.add(this,"keypress.specialSubmit",function(a){var b=a.target,c=b.type;(c==="text"||c==="password")&&d(b).closest("form").length&&a.keyCode===13&&E("submit",this,arguments)});else return!1},teardown:function(a){d.event.remove(this,".specialSubmit")}});if(!d.support.changeBubbles){var B,C=function(a){var b=a.type,c=a.value;b==="radio"||b==="checkbox"?c=a.checked:b==="select-multiple"?c=a.selectedIndex>-1?d.map(a.options,function(a){return a.selected}).join("-"):"":a.nodeName.toLowerCase()==="select"&&(c=a.selectedIndex);return c},D=function D(a){var c=a.target,e,f;if(s.test(c.nodeName)&&!c.readOnly){e=d._data(c,"_change_data"),f=C(c),(a.type!=="focusout"||c.type!=="radio")&&d._data(c,"_change_data",f);if(e===b||f===e)return;if(e!=null||f)a.type="change",a.liveFired=b,d.event.trigger(a,arguments[1],c)}};d.event.special.change={filters:{focusout:D,beforedeactivate:D,click:function(a){var b=a.target,c=b.type;(c==="radio"||c==="checkbox"||b.nodeName.toLowerCase()==="select")&&D.call(this,a)},keydown:function(a){var b=a.target,c=b.type;(a.keyCode===13&&b.nodeName.toLowerCase()!=="textarea"||a.keyCode===32&&(c==="checkbox"||c==="radio")||c==="select-multiple")&&D.call(this,a)},beforeactivate:function(a){var b=a.target;d._data(b,"_change_data",C(b))}},setup:function(a,b){if(this.type==="file")return!1;for(var c in B)d.event.add(this,c+".specialChange",B[c]);return s.test(this.nodeName)},teardown:function(a){d.event.remove(this,".specialChange");return s.test(this.nodeName)}},B=d.event.special.change.filters,B.focus=B.beforeactivate}c.addEventListener&&d.each({focus:"focusin",blur:"focusout"},function(a,b){function f(a){var c=d.event.fix(a);c.type=b,c.originalEvent={},d.event.trigger(c,null,c.target),c.isDefaultPrevented()&&a.preventDefault()}var e=0;d.event.special[b]={setup:function(){e++===0&&c.addEventListener(a,f,!0)},teardown:function(){--e===0&&c.removeEventListener(a,f,!0)}}}),d.each(["bind","one"],function(a,c){d.fn[c]=function(a,e,f){if(typeof a==="object"){for(var g in a)this[c](g,e,a[g],f);return this}if(d.isFunction(e)||e===!1)f=e,e=b;var h=c==="one"?d.proxy(f,function(a){d(this).unbind(a,h);return f.apply(this,arguments)}):f;if(a==="unload"&&c!=="one")this.one(a,e,f);else for(var i=0,j=this.length;i<j;i++)d.event.add(this[i],a,h,e);return this}}),d.fn.extend({unbind:function(a,b){if(typeof a!=="object"||a.preventDefault)for(var e=0,f=this.length;e<f;e++)d.event.remove(this[e],a,b);else for(var c in a)this.unbind(c,a[c]);return this},delegate:function(a,b,c,d){return this.live(b,c,d,a)},undelegate:function(a,b,c){return arguments.length===0?this.unbind("live"):this.die(b,null,c,a)},trigger:function(a,b){return this.each(function(){d.event.trigger(a,b,this)})},triggerHandler:function(a,b){if(this[0]){var c=d.Event(a);c.preventDefault(),c.stopPropagation(),d.event.trigger(c,b,this[0]);return c.result}},toggle:function(a){var b=arguments,c=1;while(c<b.length)d.proxy(a,b[c++]);return this.click(d.proxy(a,function(e){var f=(d._data(this,"lastToggle"+a.guid)||0)%c;d._data(this,"lastToggle"+a.guid,f+1),e.preventDefault();return b[f].apply(this,arguments)||!1}))},hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}});var F={focus:"focusin",blur:"focusout",mouseenter:"mouseover",mouseleave:"mouseout"};d.each(["live","die"],function(a,c){d.fn[c]=function(a,e,f,g){var h,i=0,j,k,l,m=g||this.selector,n=g?this:d(this.context);if(typeof a==="object"&&!a.preventDefault){for(var o in a)n[c](o,e,a[o],m);return this}d.isFunction(e)&&(f=e,e=b),a=(a||"").split(" ");while((h=a[i++])!=null){j=r.exec(h),k="",j&&(k=j[0],h=h.replace(r,""));if(h==="hover"){a.push("mouseenter"+k,"mouseleave"+k);continue}l=h,h==="focus"||h==="blur"?(a.push(F[h]+k),h=h+k):h=(F[h]||h)+k;if(c==="live")for(var p=0,q=n.length;p<q;p++)d.event.add(n[p],"live."+H(h,m),{data:e,selector:m,handler:f,origType:h,origHandler:f,preType:l});else n.unbind("live."+H(h,m),f)}return this}}),d.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error".split(" "),function(a,b){d.fn[b]=function(a,c){c==null&&(c=a,a=null);return arguments.length>0?this.bind(b,a,c):this.trigger(b)},d.attrFn&&(d.attrFn[b]=!0)}),function(){function u(a,b,c,d,e,f){for(var g=0,h=d.length;g<h;g++){var i=d[g];if(i){var j=!1;i=i[a];while(i){if(i.sizcache===c){j=d[i.sizset];break}if(i.nodeType===1){f||(i.sizcache=c,i.sizset=g);if(typeof b!=="string"){if(i===b){j=!0;break}}else if(k.filter(b,[i]).length>0){j=i;break}}i=i[a]}d[g]=j}}}function t(a,b,c,d,e,f){for(var g=0,h=d.length;g<h;g++){var i=d[g];if(i){var j=!1;i=i[a];while(i){if(i.sizcache===c){j=d[i.sizset];break}i.nodeType===1&&!f&&(i.sizcache=c,i.sizset=g);if(i.nodeName.toLowerCase()===b){j=i;break}i=i[a]}d[g]=j}}}var a=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,e=0,f=Object.prototype.toString,g=!1,h=!0,i=/\\/g,j=/\W/;[0,0].sort(function(){h=!1;return 0});var k=function(b,d,e,g){e=e||[],d=d||c;var h=d;if(d.nodeType!==1&&d.nodeType!==9)return[];if(!b||typeof b!=="string")return e;var i,j,n,o,q,r,s,t,u=!0,w=k.isXML(d),x=[],y=b;do{a.exec(""),i=a.exec(y);if(i){y=i[3],x.push(i[1]);if(i[2]){o=i[3];break}}}while(i);if(x.length>1&&m.exec(b))if(x.length===2&&l.relative[x[0]])j=v(x[0]+x[1],d);else{j=l.relative[x[0]]?[d]:k(x.shift(),d);while(x.length)b=x.shift(),l.relative[b]&&(b+=x.shift()),j=v(b,j)}else{!g&&x.length>1&&d.nodeType===9&&!w&&l.match.ID.test(x[0])&&!l.match.ID.test(x[x.length-1])&&(q=k.find(x.shift(),d,w),d=q.expr?k.filter(q.expr,q.set)[0]:q.set[0]);if(d){q=g?{expr:x.pop(),set:p(g)}:k.find(x.pop(),x.length===1&&(x[0]==="~"||x[0]==="+")&&d.parentNode?d.parentNode:d,w),j=q.expr?k.filter(q.expr,q.set):q.set,x.length>0?n=p(j):u=!1;while(x.length)r=x.pop(),s=r,l.relative[r]?s=x.pop():r="",s==null&&(s=d),l.relative[r](n,s,w)}else n=x=[]}n||(n=j),n||k.error(r||b);if(f.call(n)==="[object Array]")if(u)if(d&&d.nodeType===1)for(t=0;n[t]!=null;t++)n[t]&&(n[t]===!0||n[t].nodeType===1&&k.contains(d,n[t]))&&e.push(j[t]);else for(t=0;n[t]!=null;t++)n[t]&&n[t].nodeType===1&&e.push(j[t]);else e.push.apply(e,n);else p(n,e);o&&(k(o,h,e,g),k.uniqueSort(e));return e};k.uniqueSort=function(a){if(r){g=h,a.sort(r);if(g)for(var b=1;b<a.length;b++)a[b]===a[b-1]&&a.splice(b--,1)}return a},k.matches=function(a,b){return k(a,null,null,b)},k.matchesSelector=function(a,b){return k(b,null,null,[a]).length>0},k.find=function(a,b,c){var d;if(!a)return[];for(var e=0,f=l.order.length;e<f;e++){var g,h=l.order[e];if(g=l.leftMatch[h].exec(a)){var j=g[1];g.splice(1,1);if(j.substr(j.length-1)!=="\\"){g[1]=(g[1]||"").replace(i,""),d=l.find[h](g,b,c);if(d!=null){a=a.replace(l.match[h],"");break}}}}d||(d=typeof b.getElementsByTagName!=="undefined"?b.getElementsByTagName("*"):[]);return{set:d,expr:a}},k.filter=function(a,c,d,e){var f,g,h=a,i=[],j=c,m=c&&c[0]&&k.isXML(c[0]);while(a&&c.length){for(var n in l.filter)if((f=l.leftMatch[n].exec(a))!=null&&f[2]){var o,p,q=l.filter[n],r=f[1];g=!1,f.splice(1,1);if(r.substr(r.length-1)==="\\")continue;j===i&&(i=[]);if(l.preFilter[n]){f=l.preFilter[n](f,j,d,i,e,m);if(f){if(f===!0)continue}else g=o=!0}if(f)for(var s=0;(p=j[s])!=null;s++)if(p){o=q(p,f,s,j);var t=e^!!o;d&&o!=null?t?g=!0:j[s]=!1:t&&(i.push(p),g=!0)}if(o!==b){d||(j=i),a=a.replace(l.match[n],"");if(!g)return[];break}}if(a===h)if(g==null)k.error(a);else break;h=a}return j},k.error=function(a){throw"Syntax error, unrecognized expression: "+a};var l=k.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,CLASS:/\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/},leftMatch:{},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(a){return a.getAttribute("href")},type:function(a){return a.getAttribute("type")}},relative:{"+":function(a,b){var c=typeof b==="string",d=c&&!j.test(b),e=c&&!d;d&&(b=b.toLowerCase());for(var f=0,g=a.length,h;f<g;f++)if(h=a[f]){while((h=h.previousSibling)&&h.nodeType!==1){}a[f]=e||h&&h.nodeName.toLowerCase()===b?h||!1:h===b}e&&k.filter(b,a,!0)},">":function(a,b){var c,d=typeof b==="string",e=0,f=a.length;if(d&&!j.test(b)){b=b.toLowerCase();for(;e<f;e++){c=a[e];if(c){var g=c.parentNode;a[e]=g.nodeName.toLowerCase()===b?g:!1}}}else{for(;e<f;e++)c=a[e],c&&(a[e]=d?c.parentNode:c.parentNode===b);d&&k.filter(b,a,!0)}},"":function(a,b,c){var d,f=e++,g=u;typeof b==="string"&&!j.test(b)&&(b=b.toLowerCase(),d=b,g=t),g("parentNode",b,f,a,d,c)},"~":function(a,b,c){var d,f=e++,g=u;typeof b==="string"&&!j.test(b)&&(b=b.toLowerCase(),d=b,g=t),g("previousSibling",b,f,a,d,c)}},find:{ID:function(a,b,c){if(typeof b.getElementById!=="undefined"&&!c){var d=b.getElementById(a[1]);return d&&d.parentNode?[d]:[]}},NAME:function(a,b){if(typeof b.getElementsByName!=="undefined"){var c=[],d=b.getElementsByName(a[1]);for(var e=0,f=d.length;e<f;e++)d[e].getAttribute("name")===a[1]&&c.push(d[e]);return c.length===0?null:c}},TAG:function(a,b){if(typeof b.getElementsByTagName!=="undefined")return b.getElementsByTagName(a[1])}},preFilter:{CLASS:function(a,b,c,d,e,f){a=" "+a[1].replace(i,"")+" ";if(f)return a;for(var g=0,h;(h=b[g])!=null;g++)h&&(e^(h.className&&(" "+h.className+" ").replace(/[\t\n\r]/g," ").indexOf(a)>=0)?c||d.push(h):c&&(b[g]=!1));return!1},ID:function(a){return a[1].replace(i,"")},TAG:function(a,b){return a[1].replace(i,"").toLowerCase()},CHILD:function(a){if(a[1]==="nth"){a[2]||k.error(a[0]),a[2]=a[2].replace(/^\+|\s*/g,"");var b=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(a[2]==="even"&&"2n"||a[2]==="odd"&&"2n+1"||!/\D/.test(a[2])&&"0n+"+a[2]||a[2]);a[2]=b[1]+(b[2]||1)-0,a[3]=b[3]-0}else a[2]&&k.error(a[0]);a[0]=e++;return a},ATTR:function(a,b,c,d,e,f){var g=a[1]=a[1].replace(i,"");!f&&l.attrMap[g]&&(a[1]=l.attrMap[g]),a[4]=(a[4]||a[5]||"").replace(i,""),a[2]==="~="&&(a[4]=" "+a[4]+" ");return a},PSEUDO:function(b,c,d,e,f){if(b[1]==="not")if((a.exec(b[3])||"").length>1||/^\w/.test(b[3]))b[3]=k(b[3],null,null,c);else{var g=k.filter(b[3],c,d,!0^f);d||e.push.apply(e,g);return!1}else if(l.match.POS.test(b[0])||l.match.CHILD.test(b[0]))return!0;return b},POS:function(a){a.unshift(!0);return a}},filters:{enabled:function(a){return a.disabled===!1&&a.type!=="hidden"},disabled:function(a){return a.disabled===!0},checked:function(a){return a.checked===!0},selected:function(a){a.parentNode&&a.parentNode.selectedIndex;return a.selected===!0},parent:function(a){return!!a.firstChild},empty:function(a){return!a.firstChild},has:function(a,b,c){return!!k(c[3],a).length},header:function(a){return/h\d/i.test(a.nodeName)},text:function(a){var b=a.getAttribute("type"),c=a.type;return"text"===c&&(b===c||b===null)},radio:function(a){return"radio"===a.type},checkbox:function(a){return"checkbox"===a.type},file:function(a){return"file"===a.type},password:function(a){return"password"===a.type},submit:function(a){return"submit"===a.type},image:function(a){return"image"===a.type},reset:function(a){return"reset"===a.type},button:function(a){return"button"===a.type||a.nodeName.toLowerCase()==="button"},input:function(a){return/input|select|textarea|button/i.test(a.nodeName)}},setFilters:{first:function(a,b){return b===0},last:function(a,b,c,d){return b===d.length-1},even:function(a,b){return b%2===0},odd:function(a,b){return b%2===1},lt:function(a,b,c){return b<c[3]-0},gt:function(a,b,c){return b>c[3]-0},nth:function(a,b,c){return c[3]-0===b},eq:function(a,b,c){return c[3]-0===b}},filter:{PSEUDO:function(a,b,c,d){var e=b[1],f=l.filters[e];if(f)return f(a,c,b,d);if(e==="contains")return(a.textContent||a.innerText||k.getText([a])||"").indexOf(b[3])>=0;if(e==="not"){var g=b[3];for(var h=0,i=g.length;h<i;h++)if(g[h]===a)return!1;return!0}k.error(e)},CHILD:function(a,b){var c=b[1],d=a;switch(c){case"only":case"first":while(d=d.previousSibling)if(d.nodeType===1)return!1;if(c==="first")return!0;d=a;case"last":while(d=d.nextSibling)if(d.nodeType===1)return!1;return!0;case"nth":var e=b[2],f=b[3];if(e===1&&f===0)return!0;var g=b[0],h=a.parentNode;if(h&&(h.sizcache!==g||!a.nodeIndex)){var i=0;for(d=h.firstChild;d;d=d.nextSibling)d.nodeType===1&&(d.nodeIndex=++i);h.sizcache=g}var j=a.nodeIndex-f;return e===0?j===0:j%e===0&&j/e>=0}},ID:function(a,b){return a.nodeType===1&&a.getAttribute("id")===b},TAG:function(a,b){return b==="*"&&a.nodeType===1||a.nodeName.toLowerCase()===b},CLASS:function(a,b){return(" "+(a.className||a.getAttribute("class"))+" ").indexOf(b)>-1},ATTR:function(a,b){var c=b[1],d=l.attrHandle[c]?l.attrHandle[c](a):a[c]!=null?a[c]:a.getAttribute(c),e=d+"",f=b[2],g=b[4];return d==null?f==="!=":f==="="?e===g:f==="*="?e.indexOf(g)>=0:f==="~="?(" "+e+" ").indexOf(g)>=0:g?f==="!="?e!==g:f==="^="?e.indexOf(g)===0:f==="$="?e.substr(e.length-g.length)===g:f==="|="?e===g||e.substr(0,g.length+1)===g+"-":!1:e&&d!==!1},POS:function(a,b,c,d){var e=b[2],f=l.setFilters[e];if(f)return f(a,c,b,d)}}},m=l.match.POS,n=function(a,b){return"\\"+(b-0+1)};for(var o in l.match)l.match[o]=new RegExp(l.match[o].source+/(?![^\[]*\])(?![^\(]*\))/.source),l.leftMatch[o]=new RegExp(/(^(?:.|\r|\n)*?)/.source+l.match[o].source.replace(/\\(\d+)/g,n));var p=function(a,b){a=Array.prototype.slice.call(a,0);if(b){b.push.apply(b,a);return b}return a};try{Array.prototype.slice.call(c.documentElement.childNodes,0)[0].nodeType}catch(q){p=function(a,b){var c=0,d=b||[];if(f.call(a)==="[object Array]")Array.prototype.push.apply(d,a);else if(typeof a.length==="number")for(var e=a.length;c<e;c++)d.push(a[c]);else for(;a[c];c++)d.push(a[c]);return d}}var r,s;c.documentElement.compareDocumentPosition?r=function(a,b){if(a===b){g=!0;return 0}if(!a.compareDocumentPosition||!b.compareDocumentPosition)return a.compareDocumentPosition?-1:1;return a.compareDocumentPosition(b)&4?-1:1}:(r=function(a,b){var c,d,e=[],f=[],h=a.parentNode,i=b.parentNode,j=h;if(a===b){g=!0;return 0}if(h===i)return s(a,b);if(!h)return-1;if(!i)return 1;while(j)e.unshift(j),j=j.parentNode;j=i;while(j)f.unshift(j),j=j.parentNode;c=e.length,d=f.length;for(var k=0;k<c&&k<d;k++)if(e[k]!==f[k])return s(e[k],f[k]);return k===c?s(a,f[k],-1):s(e[k],b,1)},s=function(a,b,c){if(a===b)return c;var d=a.nextSibling;while(d){if(d===b)return-1;d=d.nextSibling}return 1}),k.getText=function(a){var b="",c;for(var d=0;a[d];d++)c=a[d],c.nodeType===3||c.nodeType===4?b+=c.nodeValue:c.nodeType!==8&&(b+=k.getText(c.childNodes));return b},function(){var a=c.createElement("div"),d="script"+(new Date).getTime(),e=c.documentElement;a.innerHTML="<a name='"+d+"'/>",e.insertBefore(a,e.firstChild),c.getElementById(d)&&(l.find.ID=function(a,c,d){if(typeof c.getElementById!=="undefined"&&!d){var e=c.getElementById(a[1]);return e?e.id===a[1]||typeof e.getAttributeNode!=="undefined"&&e.getAttributeNode("id").nodeValue===a[1]?[e]:b:[]}},l.filter.ID=function(a,b){var c=typeof a.getAttributeNode!=="undefined"&&a.getAttributeNode("id");return a.nodeType===1&&c&&c.nodeValue===b}),e.removeChild(a),e=a=null}(),function(){var a=c.createElement("div");a.appendChild(c.createComment("")),a.getElementsByTagName("*").length>0&&(l.find.TAG=function(a,b){var c=b.getElementsByTagName(a[1]);if(a[1]==="*"){var d=[];for(var e=0;c[e];e++)c[e].nodeType===1&&d.push(c[e]);c=d}return c}),a.innerHTML="<a href='#'></a>",a.firstChild&&typeof a.firstChild.getAttribute!=="undefined"&&a.firstChild.getAttribute("href")!=="#"&&(l.attrHandle.href=function(a){return a.getAttribute("href",2)}),a=null}(),c.querySelectorAll&&function(){var a=k,b=c.createElement("div"),d="__sizzle__";b.innerHTML="<p class='TEST'></p>";if(!b.querySelectorAll||b.querySelectorAll(".TEST").length!==0){k=function(b,e,f,g){e=e||c;if(!g&&!k.isXML(e)){var h=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b);if(h&&(e.nodeType===1||e.nodeType===9)){if(h[1])return p(e.getElementsByTagName(b),f);if(h[2]&&l.find.CLASS&&e.getElementsByClassName)return p(e.getElementsByClassName(h[2]),f)}if(e.nodeType===9){if(b==="body"&&e.body)return p([e.body],f);if(h&&h[3]){var i=e.getElementById(h[3]);if(!i||!i.parentNode)return p([],f);if(i.id===h[3])return p([i],f)}try{return p(e.querySelectorAll(b),f)}catch(j){}}else if(e.nodeType===1&&e.nodeName.toLowerCase()!=="object"){var m=e,n=e.getAttribute("id"),o=n||d,q=e.parentNode,r=/^\s*[+~]/.test(b);n?o=o.replace(/'/g,"\\$&"):e.setAttribute("id",o),r&&q&&(e=e.parentNode);try{if(!r||q)return p(e.querySelectorAll("[id='"+o+"'] "+b),f)}catch(s){}finally{n||m.removeAttribute("id")}}}return a(b,e,f,g)};for(var e in a)k[e]=a[e];b=null}}(),function(){var a=c.documentElement,b=a.matchesSelector||a.mozMatchesSelector||a.webkitMatchesSelector||a.msMatchesSelector;if(b){var d=!b.call(c.createElement("div"),"div"),e=!1;try{b.call(c.documentElement,"[test!='']:sizzle")}catch(f){e=!0}k.matchesSelector=function(a,c){c=c.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!k.isXML(a))try{if(e||!l.match.PSEUDO.test(c)&&!/!=/.test(c)){var f=b.call(a,c);if(f||!d||a.document&&a.document.nodeType!==11)return f}}catch(g){}return k(c,null,null,[a]).length>0}}}(),function(){var a=c.createElement("div");a.innerHTML="<div class='test e'></div><div class='test'></div>";if(a.getElementsByClassName&&a.getElementsByClassName("e").length!==0){a.lastChild.className="e";if(a.getElementsByClassName("e").length===1)return;l.order.splice(1,0,"CLASS"),l.find.CLASS=function(a,b,c){if(typeof b.getElementsByClassName!=="undefined"&&!c)return b.getElementsByClassName(a[1])},a=null}}(),c.documentElement.contains?k.contains=function(a,b){return a!==b&&(a.contains?a.contains(b):!0)}:c.documentElement.compareDocumentPosition?k.contains=function(a,b){return!!(a.compareDocumentPosition(b)&16)}:k.contains=function(){return!1},k.isXML=function(a){var b=(a?a.ownerDocument||a:0).documentElement;return b?b.nodeName!=="HTML":!1};var v=function(a,b){var c,d=[],e="",f=b.nodeType?[b]:b;while(c=l.match.PSEUDO.exec(a))e+=c[0],a=a.replace(l.match.PSEUDO,"");a=l.relative[a]?a+"*":a;for(var g=0,h=f.length;g<h;g++)k(a,f[g],d);return k.filter(e,d)};d.find=k,d.expr=k.selectors,d.expr[":"]=d.expr.filters,d.unique=k.uniqueSort,d.text=k.getText,d.isXMLDoc=k.isXML,d.contains=k.contains}();var I=/Until$/,J=/^(?:parents|prevUntil|prevAll)/,K=/,/,L=/^.[^:#\[\.,]*$/,M=Array.prototype.slice,N=d.expr.match.POS,O={children:!0,contents:!0,next:!0,prev:!0};d.fn.extend({find:function(a){var b=this.pushStack("","find",a),c=0;for(var e=0,f=this.length;e<f;e++){c=b.length,d.find(a,this[e],b);if(e>0)for(var g=c;g<b.length;g++)for(var h=0;h<c;h++)if(b[h]===b[g]){b.splice(g--,1);break}}return b},has:function(a){var b=d(a);return this.filter(function(){for(var a=0,c=b.length;a<c;a++)if(d.contains(this,b[a]))return!0})},not:function(a){return this.pushStack(Q(this,a,!1),"not",a)},filter:function(a){return this.pushStack(Q(this,a,!0),"filter",a)},is:function(a){return!!a&&d.filter(a,this).length>0},closest:function(a,b){var c=[],e,f,g=this[0];if(d.isArray(a)){var h,i,j={},k=1;if(g&&a.length){for(e=0,f=a.length;e<f;e++)i=a[e],j[i]||(j[i]=d.expr.match.POS.test(i)?d(i,b||this.context):i);while(g&&g.ownerDocument&&g!==b){for(i in j)h=j[i],(h.jquery?h.index(g)>-1:d(g).is(h))&&c.push({selector:i,elem:g,level:k});g=g.parentNode,k++}}return c}var l=N.test(a)?d(a,b||this.context):null;for(e=0,f=this.length;e<f;e++){g=this[e];while(g){if(l?l.index(g)>-1:d.find.matchesSelector(g,a)){c.push(g);break}g=g.parentNode;if(!g||!g.ownerDocument||g===b)break}}c=c.length>1?d.unique(c):c;return this.pushStack(c,"closest",a)},index:function(a){if(!a||typeof a==="string")return d.inArray(this[0],a?d(a):this.parent().children());return d.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var c=typeof a==="string"?d(a,b):d.makeArray(a),e=d.merge(this.get(),c);return this.pushStack(P(c[0])||P(e[0])?e:d.unique(e))},andSelf:function(){return this.add(this.prevObject)}}),d.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return d.dir(a,"parentNode")},parentsUntil:function(a,b,c){return d.dir(a,"parentNode",c)},next:function(a){return d.nth(a,2,"nextSibling")},prev:function(a){return d.nth(a,2,"previousSibling")},nextAll:function(a){return d.dir(a,"nextSibling")},prevAll:function(a){return d.dir(a,"previousSibling")},nextUntil:function(a,b,c){return d.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return d.dir(a,"previousSibling",c)},siblings:function(a){return d.sibling(a.parentNode.firstChild,a)},children:function(a){return d.sibling(a.firstChild)},contents:function(a){return d.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:d.makeArray(a.childNodes)}},function(a,b){d.fn[a]=function(c,e){var f=d.map(this,b,c),g=M.call(arguments);I.test(a)||(e=c),e&&typeof e==="string"&&(f=d.filter(e,f)),f=this.length>1&&!O[a]?d.unique(f):f,(this.length>1||K.test(e))&&J.test(a)&&(f=f.reverse());return this.pushStack(f,a,g.join(","))}}),d.extend({filter:function(a,b,c){c&&(a=":not("+a+")");return b.length===1?d.find.matchesSelector(b[0],a)?[b[0]]:[]:d.find.matches(a,b)},dir:function(a,c,e){var f=[],g=a[c];while(g&&g.nodeType!==9&&(e===b||g.nodeType!==1||!d(g).is(e)))g.nodeType===1&&f.push(g),g=g[c];return f},nth:function(a,b,c,d){b=b||1;var e=0;for(;a;a=a[c])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var R=/ jQuery\d+="(?:\d+|null)"/g,S=/^\s+/,T=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,U=/<([\w:]+)/,V=/<tbody/i,W=/<|&#?\w+;/,X=/<(?:script|object|embed|option|style)/i,Y=/checked\s*(?:[^=]|=\s*.checked.)/i,Z={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]};Z.optgroup=Z.option,Z.tbody=Z.tfoot=Z.colgroup=Z.caption=Z.thead,Z.th=Z.td,d.support.htmlSerialize||(Z._default=[1,"div<div>","</div>"]),d.fn.extend({text:function(a){if(d.isFunction(a))return this.each(function(b){var c=d(this);c.text(a.call(this,b,c.text()))});if(typeof a!=="object"&&a!==b)return this.empty().append((this[0]&&this[0].ownerDocument||c).createTextNode(a));return d.text(this)},wrapAll:function(a){if(d.isFunction(a))return this.each(function(b){d(this).wrapAll(a.call(this,b))});if(this[0]){var b=d(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){if(d.isFunction(a))return this.each(function(b){d(this).wrapInner(a.call(this,b))});return this.each(function(){var b=d(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){d(this).wrapAll(a)})},unwrap:function(){return this.parent().each(function(){d.nodeName(this,"body")||d(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=d(arguments[0]);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,d(arguments[0]).toArray());return a}},remove:function(a,b){for(var c=0,e;(e=this[c])!=null;c++)if(!a||d.filter(a,[e]).length)!b&&e.nodeType===1&&(d.cleanData(e.getElementsByTagName("*")),d.cleanData([e])),e.parentNode&&e.parentNode.removeChild(e);return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++){b.nodeType===1&&d.cleanData(b.getElementsByTagName("*"));while(b.firstChild)b.removeChild(b.firstChild)}return this},clone:function(a,b){a=a==null?!1:a,b=b==null?a:b;return this.map(function(){return d.clone(this,a,b)})},html:function(a){if(a===b)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(R,""):null;if(typeof a!=="string"||X.test(a)||!d.support.leadingWhitespace&&S.test(a)||Z[(U.exec(a)||["",""])[1].toLowerCase()])d.isFunction(a)?this.each(function(b){var c=d(this);c.html(a.call(this,b,c.html()))}):this.empty().append(a);else{a=a.replace(T,"<$1></$2>");try{for(var c=0,e=this.length;c<e;c++)this[c].nodeType===1&&(d.cleanData(this[c].getElementsByTagName("*")),this[c].innerHTML=a)}catch(f){this.empty().append(a)}}return this},replaceWith:function(a){if(this[0]&&this[0].parentNode){if(d.isFunction(a))return this.each(function(b){var c=d(this),e=c.html();c.replaceWith(a.call(this,b,e))});typeof a!=="string"&&(a=d(a).detach());return this.each(function(){var b=this.nextSibling,c=this.parentNode;d(this).remove(),b?d(b).before(a):d(c).append(a)})}return this.length?this.pushStack(d(d.isFunction(a)?a():a),"replaceWith",a):this},detach:function(a){return this.remove(a,!0)},domManip:function(a,c,e){var f,g,h,i,j=a[0],k=[];if(!d.support.checkClone&&arguments.length===3&&typeof j==="string"&&Y.test(j))return this.each(function(){d(this).domManip(a,c,e,!0)});if(d.isFunction(j))return this.each(function(f){var g=d(this);a[0]=j.call(this,f,c?g.html():b),g.domManip(a,c,e)});if(this[0]){i=j&&j.parentNode,d.support.parentNode&&i&&i.nodeType===11&&i.childNodes.length===this.length?f={fragment:i}:f=d.buildFragment(a,this,k),h=f.fragment,h.childNodes.length===1?g=h=h.firstChild:g=h.firstChild;if(g){c=c&&d.nodeName(g,"tr");for(var l=0,m=this.length,n=m-1;l<m;l++)e.call(c?$(this[l],g):this[l],f.cacheable||m>1&&l<n?d.clone(h,!0,!0):h)}k.length&&d.each(k,bc)}return this}}),d.buildFragment=function(a,b,e){var f,g,h,i=b&&b[0]?b[0].ownerDocument||b[0]:c;a.length===1&&typeof a[0]==="string"&&a[0].length<512&&i===c&&a[0].charAt(0)==="<"&&!X.test(a[0])&&(d.support.checkClone||!Y.test(a[0]))&&(g=!0,h=d.fragments[a[0]],h&&(h!==1&&(f=h))),f||(f=i.createDocumentFragment(),d.clean(a,i,f,e)),g&&(d.fragments[a[0]]=h?f:1);return{fragment:f,cacheable:g}},d.fragments={},d.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){d.fn[a]=function(c){var e=[],f=d(c),g=this.length===1&&this[0].parentNode;if(g&&g.nodeType===11&&g.childNodes.length===1&&f.length===1){f[b](this[0]);return this}for(var h=0,i=f.length;h<i;h++){var j=(h>0?this.clone(!0):this).get();d(f[h])[b](j),e=e.concat(j)}return this.pushStack(e,a,f.selector)}}),d.extend({clone:function(a,b,c){var e=a.cloneNode(!0),f,g,h;if((!d.support.noCloneEvent||!d.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!d.isXMLDoc(a)){ba(a,e),f=bb(a),g=bb(e);for(h=0;f[h];++h)ba(f[h],g[h])}if(b){_(a,e);if(c){f=bb(a),g=bb(e);for(h=0;f[h];++h)_(f[h],g[h])}}return e},clean:function(a,b,e,f){b=b||c,typeof b.createElement==="undefined"&&(b=b.ownerDocument||b[0]&&b[0].ownerDocument||c);var g=[];for(var h=0,i;(i=a[h])!=null;h++){typeof i==="number"&&(i+="");if(!i)continue;if(typeof i!=="string"||W.test(i)){if(typeof i==="string"){i=i.replace(T,"<$1></$2>");var j=(U.exec(i)||["",""])[1].toLowerCase(),k=Z[j]||Z._default,l=k[0],m=b.createElement("div");m.innerHTML=k[1]+i+k[2];while(l--)m=m.lastChild;if(!d.support.tbody){var n=V.test(i),o=j==="table"&&!n?m.firstChild&&m.firstChild.childNodes:k[1]==="<table>"&&!n?m.childNodes:[];for(var p=o.length-1;p>=0;--p)d.nodeName(o[p],"tbody")&&!o[p].childNodes.length&&o[p].parentNode.removeChild(o[p])}!d.support.leadingWhitespace&&S.test(i)&&m.insertBefore(b.createTextNode(S.exec(i)[0]),m.firstChild),i=m.childNodes}}else i=b.createTextNode(i);i.nodeType?g.push(i):g=d.merge(g,i)}if(e)for(h=0;g[h];h++)!f||!d.nodeName(g[h],"script")||g[h].type&&g[h].type.toLowerCase()!=="text/javascript"?(g[h].nodeType===1&&g.splice.apply(g,[h+1,0].concat(d.makeArray(g[h].getElementsByTagName("script")))),e.appendChild(g[h])):f.push(g[h].parentNode?g[h].parentNode.removeChild(g[h]):g[h]);return g},cleanData:function(a){var b,c,e=d.cache,f=d.expando,g=d.event.special,h=d.support.deleteExpando;for(var i=0,j;(j=a[i])!=null;i++){if(j.nodeName&&d.noData[j.nodeName.toLowerCase()])continue;c=j[d.expando];if(c){b=e[c]&&e[c][f];if(b&&b.events){for(var k in b.events)g[k]?d.event.remove(j,k):d.removeEvent(j,k,b.handle);b.handle&&(b.handle.elem=null)}h?delete j[d.expando]:j.removeAttribute&&j.removeAttribute(d.expando),delete e[c]}}}});var bd=/alpha\([^)]*\)/i,be=/opacity=([^)]*)/,bf=/-([a-z])/ig,bg=/([A-Z]|^ms)/g,bh=/^-?\d+(?:px)?$/i,bi=/^-?\d/,bj={position:"absolute",visibility:"hidden",display:"block"},bk=["Left","Right"],bl=["Top","Bottom"],bm,bn,bo,bp=function(a,b){return b.toUpperCase()};d.fn.css=function(a,c){if(arguments.length===2&&c===b)return this;return d.access(this,a,c,!0,function(a,c,e){return e!==b?d.style(a,c,e):d.css(a,c)})},d.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=bm(a,"opacity","opacity");return c===""?"1":c}return a.style.opacity}}},cssNumber:{zIndex:!0,fontWeight:!0,opacity:!0,zoom:!0,lineHeight:!0},cssProps:{"float":d.support.cssFloat?"cssFloat":"styleFloat"},style:function(a,c,e,f){if(a&&a.nodeType!==3&&a.nodeType!==8&&a.style){var g,h=d.camelCase(c),i=a.style,j=d.cssHooks[h];c=d.cssProps[h]||h;if(e===b){if(j&&"get"in j&&(g=j.get(a,!1,f))!==b)return g;return i[c]}if(typeof e==="number"&&isNaN(e)||e==null)return;typeof e==="number"&&!d.cssNumber[h]&&(e+="px");if(!j||!("set"in j)||(e=j.set(a,e))!==b)try{i[c]=e}catch(k){}}},css:function(a,c,e){var f,g=d.camelCase(c),h=d.cssHooks[g];c=d.cssProps[g]||g;if(h&&"get"in h&&(f=h.get(a,!0,e))!==b)return f;if(bm)return bm(a,c,g)},swap:function(a,b,c){var d={};for(var e in b)d[e]=a.style[e],a.style[e]=b[e];c.call(a);for(e in b)a.style[e]=d[e]},camelCase:function(a){return a.replace(bf,bp)}}),d.curCSS=d.css,d.each(["height","width"],function(a,b){d.cssHooks[b]={get:function(a,c,e){var f;if(c){a.offsetWidth!==0?f=bq(a,b,e):d.swap(a,bj,function(){f=bq(a,b,e)});if(f<=0){f=bm(a,b,b),f==="0px"&&bo&&(f=bo(a,b,b));if(f!=null)return f===""||f==="auto"?"0px":f}if(f<0||f==null){f=a.style[b];return f===""||f==="auto"?"0px":f}return typeof f==="string"?f:f+"px"}},set:function(a,b){if(!bh.test(b))return b;b=parseFloat(b);if(b>=0)return b+"px"}}}),d.support.opacity||(d.cssHooks.opacity={get:function(a,b){return be.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"":b?"1":""},set:function(a,b){var c=a.style;c.zoom=1;var e=d.isNaN(b)?"":"alpha(opacity="+b*100+")",f=c.filter||"";c.filter=bd.test(f)?f.replace(bd,e):c.filter+" "+e}}),d(function(){d.support.reliableMarginRight||(d.cssHooks.marginRight={get:function(a,b){var c;d.swap(a,{display:"inline-block"},function(){b?c=bm(a,"margin-right","marginRight"):c=a.style.marginRight});return c}})}),c.defaultView&&c.defaultView.getComputedStyle&&(bn=function(a,c,e){var f,g,h;e=e.replace(bg,"-$1").toLowerCase();if(!(g=a.ownerDocument.defaultView))return b;if(h=g.getComputedStyle(a,null))f=h.getPropertyValue(e),f===""&&!d.contains(a.ownerDocument.documentElement,a)&&(f=d.style(a,e));return f}),c.documentElement.currentStyle&&(bo=function(a,b){var c,d=a.currentStyle&&a.currentStyle[b],e=a.runtimeStyle&&a.runtimeStyle[b],f=a.style;!bh.test(d)&&bi.test(d)&&(c=f.left,e&&(a.runtimeStyle.left=a.currentStyle.left),f.left=b==="fontSize"?"1em":d||0,d=f.pixelLeft+"px",f.left=c,e&&(a.runtimeStyle.left=e));return d===""?"auto":d}),bm=bn||bo,d.expr&&d.expr.filters&&(d.expr.filters.hidden=function(a){var b=a.offsetWidth,c=a.offsetHeight;return b===0&&c===0||!d.support.reliableHiddenOffsets&&(a.style.display||d.css(a,"display"))==="none"},d.expr.filters.visible=function(a){return!d.expr.filters.hidden(a)});var br=/%20/g,bs=/\[\]$/,bt=/\r?\n/g,bu=/#.*$/,bv=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,bw=/^(?:color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,bx=/^(?:about|app|app\-storage|.+\-extension|file|widget):$/,by=/^(?:GET|HEAD)$/,bz=/^\/\//,bA=/\?/,bB=/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,bC=/^(?:select|textarea)/i,bD=/\s+/,bE=/([?&])_=[^&]*/,bF=/(^|\-)([a-z])/g,bG=function(a,b,c){return b+c.toUpperCase()},bH=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,bI=d.fn.load,bJ={},bK={},bL,bM;try{bL=c.location.href}catch(bN){bL=c.createElement("a"),bL.href="",bL=bL.href}bM=bH.exec(bL.toLowerCase())||[],d.fn.extend({load:function(a,c,e){if(typeof a!=="string"&&bI)return bI.apply(this,arguments);if(!this.length)return this;var f=a.indexOf(" ");if(f>=0){var g=a.slice(f,a.length);a=a.slice(0,f)}var h="GET";c&&(d.isFunction(c)?(e=c,c=b):typeof c==="object"&&(c=d.param(c,d.ajaxSettings.traditional),h="POST"));var i=this;d.ajax({url:a,type:h,dataType:"html",data:c,complete:function(a,b,c){c=a.responseText,a.isResolved()&&(a.done(function(a){c=a}),i.html(g?d("<div>").append(c.replace(bB,"")).find(g):c)),e&&i.each(e,[c,b,a])}});return this},serialize:function(){return d.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?d.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||bC.test(this.nodeName)||bw.test(this.type))}).map(function(a,b){var c=d(this).val();return c==null?null:d.isArray(c)?d.map(c,function(a,c){return{name:b.name,value:a.replace(bt,"\r\n")}}):{name:b.name,value:c.replace(bt,"\r\n")}}).get()}}),d.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){d.fn[b]=function(a){return this.bind(b,a)}}),d.each(["get","post"],function(a,c){d[c]=function(a,e,f,g){d.isFunction(e)&&(g=g||f,f=e,e=b);return d.ajax({type:c,url:a,data:e,success:f,dataType:g})}}),d.extend({getScript:function(a,c){return d.get(a,b,c,"script")},getJSON:function(a,b,c){return d.get(a,b,c,"json")},ajaxSetup:function(a,b){b?d.extend(!0,a,d.ajaxSettings,b):(b=a,a=d.extend(!0,d.ajaxSettings,b));for(var c in {context:1,url:1})c in b?a[c]=b[c]:c in d.ajaxSettings&&(a[c]=d.ajaxSettings[c]);return a},ajaxSettings:{url:bL,isLocal:bx.test(bM[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":"*/*"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String,"text html":!0,"text json":d.parseJSON,"text xml":d.parseXML}},ajaxPrefilter:bO(bJ),ajaxTransport:bO(bK),ajax:function(a,c){function v(a,c,l,n){if(r!==2){r=2,p&&clearTimeout(p),o=b,m=n||"",u.readyState=a?4:0;var q,t,v,w=l?bR(e,u,l):b,x,y;if(a>=200&&a<300||a===304){if(e.ifModified){if(x=u.getResponseHeader("Last-Modified"))d.lastModified[k]=x;if(y=u.getResponseHeader("Etag"))d.etag[k]=y}if(a===304)c="notmodified",q=!0;else try{t=bS(e,w),c="success",q=!0}catch(z){c="parsererror",v=z}}else{v=c;if(!c||a)c="error",a<0&&(a=0)}u.status=a,u.statusText=c,q?h.resolveWith(f,[t,c,u]):h.rejectWith(f,[u,c,v]),u.statusCode(j),j=b,s&&g.trigger("ajax"+(q?"Success":"Error"),[u,e,q?t:v]),i.resolveWith(f,[u,c]),s&&(g.trigger("ajaxComplete",[u,e]),--d.active||d.event.trigger("ajaxStop"))}}typeof a==="object"&&(c=a,a=b),c=c||{};var e=d.ajaxSetup({},c),f=e.context||e,g=f!==e&&(f.nodeType||f instanceof d)?d(f):d.event,h=d.Deferred(),i=d._Deferred(),j=e.statusCode||{},k,l={},m,n,o,p,q,r=0,s,t,u={readyState:0,setRequestHeader:function(a,b){r||(l[a.toLowerCase().replace(bF,bG)]=b);return this},getAllResponseHeaders:function(){return r===2?m:null},getResponseHeader:function(a){var c;if(r===2){if(!n){n={};while(c=bv.exec(m))n[c[1].toLowerCase()]=c[2]}c=n[a.toLowerCase()]}return c===b?null:c},overrideMimeType:function(a){r||(e.mimeType=a);return this},abort:function(a){a=a||"abort",o&&o.abort(a),v(0,a);return this}};h.promise(u),u.success=u.done,u.error=u.fail,u.complete=i.done,u.statusCode=function(a){if(a){var b;if(r<2)for(b in a)j[b]=[j[b],a[b]];else b=a[u.status],u.then(b,b)}return this},e.url=((a||e.url)+"").replace(bu,"").replace(bz,bM[1]+"//"),e.dataTypes=d.trim(e.dataType||"*").toLowerCase().split(bD),e.crossDomain==null&&(q=bH.exec(e.url.toLowerCase()),e.crossDomain=q&&(q[1]!=bM[1]||q[2]!=bM[2]||(q[3]||(q[1]==="http:"?80:443))!=(bM[3]||(bM[1]==="http:"?80:443)))),e.data&&e.processData&&typeof e.data!=="string"&&(e.data=d.param(e.data,e.traditional)),bP(bJ,e,c,u);if(r===2)return!1;s=e.global,e.type=e.type.toUpperCase(),e.hasContent=!by.test(e.type),s&&d.active++===0&&d.event.trigger("ajaxStart");if(!e.hasContent){e.data&&(e.url+=(bA.test(e.url)?"&":"?")+e.data),k=e.url;if(e.cache===!1){var w=d.now(),x=e.url.replace(bE,"$1_="+w);e.url=x+(x===e.url?(bA.test(e.url)?"&":"?")+"_="+w:"")}}if(e.data&&e.hasContent&&e.contentType!==!1||c.contentType)l["Content-Type"]=e.contentType;e.ifModified&&(k=k||e.url,d.lastModified[k]&&(l["If-Modified-Since"]=d.lastModified[k]),d.etag[k]&&(l["If-None-Match"]=d.etag[k])),l.Accept=e.dataTypes[0]&&e.accepts[e.dataTypes[0]]?e.accepts[e.dataTypes[0]]+(e.dataTypes[0]!=="*"?", */*; q=0.01":""):e.accepts["*"];for(t in e.headers)u.setRequestHeader(t,e.headers[t]);if(e.beforeSend&&(e.beforeSend.call(f,u,e)===!1||r===2)){u.abort();return!1}for(t in {success:1,error:1,complete:1})u[t](e[t]);o=bP(bK,e,c,u);if(o){u.readyState=1,s&&g.trigger("ajaxSend",[u,e]),e.async&&e.timeout>0&&(p=setTimeout(function(){u.abort("timeout")},e.timeout));try{r=1,o.send(l,v)}catch(y){status<2?v(-1,y):d.error(y)}}else v(-1,"No Transport");return u},param:function(a,c){var e=[],f=function(a,b){b=d.isFunction(b)?b():b,e[e.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};c===b&&(c=d.ajaxSettings.traditional);if(d.isArray(a)||a.jquery&&!d.isPlainObject(a))d.each(a,function(){f(this.name,this.value)});else for(var g in a)bQ(g,a[g],c,f);return e.join("&").replace(br,"+")}}),d.extend({active:0,lastModified:{},etag:{}});var bT=d.now(),bU=/(\=)\?(&|$)|\?\?/i;d.ajaxSetup({jsonp:"callback",jsonpCallback:function(){return d.expando+"_"+bT++}}),d.ajaxPrefilter("json jsonp",function(b,c,e){var f=typeof b.data==="string";if(b.dataTypes[0]==="jsonp"||c.jsonpCallback||c.jsonp!=null||b.jsonp!==!1&&(bU.test(b.url)||f&&bU.test(b.data))){var g,h=b.jsonpCallback=d.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,i=a[h],j=b.url,k=b.data,l="$1"+h+"$2",m=function(){a[h]=i,g&&d.isFunction(i)&&a[h](g[0])};b.jsonp!==!1&&(j=j.replace(bU,l),b.url===j&&(f&&(k=k.replace(bU,l)),b.data===k&&(j+=(/\?/.test(j)?"&":"?")+b.jsonp+"="+h))),b.url=j,b.data=k,a[h]=function(a){g=[a]},e.then(m,m),b.converters["script json"]=function(){g||d.error(h+" was not called");return g[0]},b.dataTypes[0]="json";return"script"}}),d.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){d.globalEval(a);return a}}}),d.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),d.ajaxTransport("script",function(a){if(a.crossDomain){var d,e=c.head||c.getElementsByTagName("head")[0]||c.documentElement;return{send:function(f,g){d=c.createElement("script"),d.async="async",a.scriptCharset&&(d.charset=a.scriptCharset),d.src=a.url,d.onload=d.onreadystatechange=function(a,c){if(!d.readyState||/loaded|complete/.test(d.readyState))d.onload=d.onreadystatechange=null,e&&d.parentNode&&e.removeChild(d),d=b,c||g(200,"success")},e.insertBefore(d,e.firstChild)},abort:function(){d&&d.onload(0,1)}}}});var bV=d.now(),bW,bX;d.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&bZ()||b$()}:bZ,bX=d.ajaxSettings.xhr(),d.support.ajax=!!bX,d.support.cors=bX&&"withCredentials"in bX,bX=b,d.support.ajax&&d.ajaxTransport(function(a){if(!a.crossDomain||d.support.cors){var c;return{send:function(e,f){var g=a.xhr(),h,i;a.username?g.open(a.type,a.url,a.async,a.username,a.password):g.open(a.type,a.url,a.async);if(a.xhrFields)for(i in a.xhrFields)g[i]=a.xhrFields[i];a.mimeType&&g.overrideMimeType&&g.overrideMimeType(a.mimeType),!a.crossDomain&&!e["X-Requested-With"]&&(e["X-Requested-With"]="XMLHttpRequest");try{for(i in e)g.setRequestHeader(i,e[i])}catch(j){}g.send(a.hasContent&&a.data||null),c=function(e,i){var j,k,l,m,n;try{if(c&&(i||g.readyState===4)){c=b,h&&(g.onreadystatechange=d.noop,delete bW[h]);if(i)g.readyState!==4&&g.abort();else{j=g.status,l=g.getAllResponseHeaders(),m={},n=g.responseXML,n&&n.documentElement&&(m.xml=n),m.text=g.responseText;try{k=g.statusText}catch(o){k=""}j||!a.isLocal||a.crossDomain?j===1223&&(j=204):j=m.text?200:404}}}catch(p){i||f(-1,p)}m&&f(j,k,m,l)},a.async&&g.readyState!==4?(bW||(bW={},bY()),h=bV++,g.onreadystatechange=bW[h]=c):c()},abort:function(){c&&c(0,1)}}}});var b_={},ca=/^(?:toggle|show|hide)$/,cb=/^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,cc,cd=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];d.fn.extend({show:function(a,b,c){var e,f;if(a||a===0)return this.animate(ce("show",3),a,b,c);for(var g=0,h=this.length;g<h;g++)e=this[g],f=e.style.display,!d._data(e,"olddisplay")&&f==="none"&&(f=e.style.display=""),f===""&&d.css(e,"display")==="none"&&d._data(e,"olddisplay",cf(e.nodeName));for(g=0;g<h;g++){e=this[g],f=e.style.display;if(f===""||f==="none")e.style.display=d._data(e,"olddisplay")||""}return this},hide:function(a,b,c){if(a||a===0)return this.animate(ce("hide",3),a,b,c);for(var e=0,f=this.length;e<f;e++){var g=d.css(this[e],"display");g!=="none"&&!d._data(this[e],"olddisplay")&&d._data(this[e],"olddisplay",g)}for(e=0;e<f;e++)this[e].style.display="none";return this},_toggle:d.fn.toggle,toggle:function(a,b,c){var e=typeof a==="boolean";d.isFunction(a)&&d.isFunction(b)?this._toggle.apply(this,arguments):a==null||e?this.each(function(){var b=e?a:d(this).is(":hidden");d(this)[b?"show":"hide"]()}):this.animate(ce("toggle",3),a,b,c);return this},fadeTo:function(a,b,c,d){return this.filter(":hidden").css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,e){var f=d.speed(b,c,e);if(d.isEmptyObject(a))return this.each(f.complete);return this[f.queue===!1?"each":"queue"](function(){var b=d.extend({},f),c,e=this.nodeType===1,g=e&&d(this).is(":hidden"),h=this;for(c in a){var i=d.camelCase(c);c!==i&&(a[i]=a[c],delete a[c],c=i);if(a[c]==="hide"&&g||a[c]==="show"&&!g)return b.complete.call(this);if(e&&(c==="height"||c==="width")){b.overflow=[this.style.overflow,this.style.overflowX,this.style.overflowY];if(d.css(this,"display")==="inline"&&d.css(this,"float")==="none")if(d.support.inlineBlockNeedsLayout){var j=cf(this.nodeName);j==="inline"?this.style.display="inline-block":(this.style.display="inline",this.style.zoom=1)}else this.style.display="inline-block"}d.isArray(a[c])&&((b.specialEasing=b.specialEasing||{})[c]=a[c][1],a[c]=a[c][0])}b.overflow!=null&&(this.style.overflow="hidden"),b.curAnim=d.extend({},a),d.each(a,function(c,e){var f=new d.fx(h,b,c);if(ca.test(e))f[e==="toggle"?g?"show":"hide":e](a);else{var i=cb.exec(e),j=f.cur();if(i){var k=parseFloat(i[2]),l=i[3]||(d.cssNumber[c]?"":"px");l!=="px"&&(d.style(h,c,(k||1)+l),j=(k||1)/f.cur()*j,d.style(h,c,j+l)),i[1]&&(k=(i[1]==="-="?-1:1)*k+j),f.custom(j,k,l)}else f.custom(j,e,"")}});return!0})},stop:function(a,b){var c=d.timers;a&&this.queue([]),this.each(function(){for(var a=c.length-1;a>=0;a--)c[a].elem===this&&(b&&c[a](!0),c.splice(a,1))}),b||this.dequeue();return this}}),d.each({slideDown:ce("show",1),slideUp:ce("hide",1),slideToggle:ce("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){d.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),d.extend({speed:function(a,b,c){var e=a&&typeof a==="object"?d.extend({},a):{complete:c||!c&&b||d.isFunction(a)&&a,duration:a,easing:c&&b||b&&!d.isFunction(b)&&b};e.duration=d.fx.off?0:typeof e.duration==="number"?e.duration:e.duration in d.fx.speeds?d.fx.speeds[e.duration]:d.fx.speeds._default,e.old=e.complete,e.complete=function(){e.queue!==!1&&d(this).dequeue(),d.isFunction(e.old)&&e.old.call(this)};return e},easing:{linear:function(a,b,c,d){return c+d*a},swing:function(a,b,c,d){return(-Math.cos(a*Math.PI)/2+.5)*d+c}},timers:[],fx:function(a,b,c){this.options=b,this.elem=a,this.prop=c,b.orig||(b.orig={})}}),d.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this),(d.fx.step[this.prop]||d.fx.step._default)(this)},cur:function(){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null))return this.elem[this.prop];var a,b=d.css(this.elem,this.prop);return isNaN(a=parseFloat(b))?!b||b==="auto"?0:b:a},custom:function(a,b,c){function g(a){return e.step(a)}var e=this,f=d.fx;this.startTime=d.now(),this.start=a,this.end=b,this.unit=c||this.unit||(d.cssNumber[this.prop]?"":"px"),this.now=this.start,this.pos=this.state=0,g.elem=this.elem,g()&&d.timers.push(g)&&!cc&&(cc=setInterval(f.tick,f.interval))},show:function(){this.options.orig[this.prop]=d.style(this.elem,this.prop),this.options.show=!0,this.custom(this.prop==="width"||this.prop==="height"?1:0,this.cur()),d(this.elem).show()},hide:function(){this.options.orig[this.prop]=d.style(this.elem,this.prop),this.options.hide=!0,this.custom(this.cur(),0)},step:function(a){var b=d.now(),c=!0;if(a||b>=this.options.duration+this.startTime){this.now=this.end,this.pos=this.state=1,this.update(),this.options.curAnim[this.prop]=!0;for(var e in this.options.curAnim)this.options.curAnim[e]!==!0&&(c=!1);if(c){if(this.options.overflow!=null&&!d.support.shrinkWrapBlocks){var f=this.elem,g=this.options;d.each(["","X","Y"],function(a,b){f.style["overflow"+b]=g.overflow[a]})}this.options.hide&&d(this.elem).hide();if(this.options.hide||this.options.show)for(var h in this.options.curAnim)d.style(this.elem,h,this.options.orig[h]);this.options.complete.call(this.elem)}return!1}var i=b-this.startTime;this.state=i/this.options.duration;var j=this.options.specialEasing&&this.options.specialEasing[this.prop],k=this.options.easing||(d.easing.swing?"swing":"linear");this.pos=d.easing[j||k](this.state,i,0,1,this.options.duration),this.now=this.start+(this.end-this.start)*this.pos,this.update();return!0}},d.extend(d.fx,{tick:function(){var a=d.timers;for(var b=0;b<a.length;b++)a[b]()||a.splice(b--,1);a.length||d.fx.stop()},interval:13,stop:function(){clearInterval(cc),cc=null},speeds:{slow:600,fast:200,_default:400},step:{opacity:function(a){d.style(a.elem,"opacity",a.now)},_default:function(a){a.elem.style&&a.elem.style[a.prop]!=null?a.elem.style[a.prop]=(a.prop==="width"||a.prop==="height"?Math.max(0,a.now):a.now)+a.unit:a.elem[a.prop]=a.now}}}),d.expr&&d.expr.filters&&(d.expr.filters.animated=function(a){return d.grep(d.timers,function(b){return a===b.elem}).length});var cg=/^t(?:able|d|h)$/i,ch=/^(?:body|html)$/i;"getBoundingClientRect"in c.documentElement?d.fn.offset=function(a){var b=this[0],c;if(a)return this.each(function(b){d.offset.setOffset(this,a,b)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return d.offset.bodyOffset(b);try{c=b.getBoundingClientRect()}catch(e){}var f=b.ownerDocument,g=f.documentElement;if(!c||!d.contains(g,b))return c?{top:c.top,left:c.left}:{top:0,left:0};var h=f.body,i=ci(f),j=g.clientTop||h.clientTop||0,k=g.clientLeft||h.clientLeft||0,l=i.pageYOffset||d.support.boxModel&&g.scrollTop||h.scrollTop,m=i.pageXOffset||d.support.boxModel&&g.scrollLeft||h.scrollLeft,n=c.top+l-j,o=c.left+m-k;return{top:n,left:o}}:d.fn.offset=function(a){var b=this[0];if(a)return this.each(function(b){d.offset.setOffset(this,a,b)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return d.offset.bodyOffset(b);d.offset.initialize();var c,e=b.offsetParent,f=b,g=b.ownerDocument,h=g.documentElement,i=g.body,j=g.defaultView,k=j?j.getComputedStyle(b,null):b.currentStyle,l=b.offsetTop,m=b.offsetLeft;while((b=b.parentNode)&&b!==i&&b!==h){if(d.offset.supportsFixedPosition&&k.position==="fixed")break;c=j?j.getComputedStyle(b,null):b.currentStyle,l-=b.scrollTop,m-=b.scrollLeft,b===e&&(l+=b.offsetTop,m+=b.offsetLeft,d.offset.doesNotAddBorder&&(!d.offset.doesAddBorderForTableAndCells||!cg.test(b.nodeName))&&(l+=parseFloat(c.borderTopWidth)||0,m+=parseFloat(c.borderLeftWidth)||0),f=e,e=b.offsetParent),d.offset.subtractsBorderForOverflowNotVisible&&c.overflow!=="visible"&&(l+=parseFloat(c.borderTopWidth)||0,m+=parseFloat(c.borderLeftWidth)||0),k=c}if(k.position==="relative"||k.position==="static")l+=i.offsetTop,m+=i.offsetLeft;d.offset.supportsFixedPosition&&k.position==="fixed"&&(l+=Math.max(h.scrollTop,i.scrollTop),m+=Math.max(h.scrollLeft,i.scrollLeft));return{top:l,left:m}},d.offset={initialize:function(){var a=c.body,b=c.createElement("div"),e,f,g,h,i=parseFloat(d.css(a,"marginTop"))||0,j="<div style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;'><div></div></div><table style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;' cellpadding='0' cellspacing='0'><tr><td></td></tr></table>";d.extend(b.style,{position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"}),b.innerHTML=j,a.insertBefore(b,a.firstChild),e=b.firstChild,f=e.firstChild,h=e.nextSibling.firstChild.firstChild,this.doesNotAddBorder=f.offsetTop!==5,this.doesAddBorderForTableAndCells=h.offsetTop===5,f.style.position="fixed",f.style.top="20px",this.supportsFixedPosition=f.offsetTop===20||f.offsetTop===15,f.style.position=f.style.top="",e.style.overflow="hidden",e.style.position="relative",this.subtractsBorderForOverflowNotVisible=f.offsetTop===-5,this.doesNotIncludeMarginInBodyOffset=a.offsetTop!==i,a.removeChild(b),d.offset.initialize=d.noop},bodyOffset:function(a){var b=a.offsetTop,c=a.offsetLeft;d.offset.initialize(),d.offset.doesNotIncludeMarginInBodyOffset&&(b+=parseFloat(d.css(a,"marginTop"))||0,c+=parseFloat(d.css(a,"marginLeft"))||0);return{top:b,left:c}},setOffset:function(a,b,c){var e=d.css(a,"position");e==="static"&&(a.style.position="relative");var f=d(a),g=f.offset(),h=d.css(a,"top"),i=d.css(a,"left"),j=(e==="absolute"||e==="fixed")&&d.inArray("auto",[h,i])>-1,k={},l={},m,n;j&&(l=f.position()),m=j?l.top:parseInt(h,10)||0,n=j?l.left:parseInt(i,10)||0,d.isFunction(b)&&(b=b.call(a,c,g)),b.top!=null&&(k.top=b.top-g.top+m),b.left!=null&&(k.left=b.left-g.left+n),"using"in b?b.using.call(a,k):f.css(k)}},d.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),c=this.offset(),e=ch.test(b[0].nodeName)?{top:0,left:0}:b.offset();c.top-=parseFloat(d.css(a,"marginTop"))||0,c.left-=parseFloat(d.css(a,"marginLeft"))||0,e.top+=parseFloat(d.css(b[0],"borderTopWidth"))||0,e.left+=parseFloat(d.css(b[0],"borderLeftWidth"))||0;return{top:c.top-e.top,left:c.left-e.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||c.body;while(a&&(!ch.test(a.nodeName)&&d.css(a,"position")==="static"))a=a.offsetParent;return a})}}),d.each(["Left","Top"],function(a,c){var e="scroll"+c;d.fn[e]=function(c){var f=this[0],g;if(!f)return null;if(c!==b)return this.each(function(){g=ci(this),g?g.scrollTo(a?d(g).scrollLeft():c,a?c:d(g).scrollTop()):this[e]=c});g=ci(f);return g?"pageXOffset"in g?g[a?"pageYOffset":"pageXOffset"]:d.support.boxModel&&g.document.documentElement[e]||g.document.body[e]:f[e]}}),d.each(["Height","Width"],function(a,c){var e=c.toLowerCase();d.fn["inner"+c]=function(){return this[0]?parseFloat(d.css(this[0],e,"padding")):null},d.fn["outer"+c]=function(a){return this[0]?parseFloat(d.css(this[0],e,a?"margin":"border")):null},d.fn[e]=function(a){var f=this[0];if(!f)return a==null?null:this;if(d.isFunction(a))return this.each(function(b){var c=d(this);c[e](a.call(this,b,c[e]()))});if(d.isWindow(f)){var g=f.document.documentElement["client"+c];return f.document.compatMode==="CSS1Compat"&&g||f.document.body["client"+c]||g}if(f.nodeType===9)return Math.max(f.documentElement["client"+c],f.body["scroll"+c],f.documentElement["scroll"+c],f.body["offset"+c],f.documentElement["offset"+c]);if(a===b){var h=d.css(f,e),i=parseFloat(h);return d.isNaN(i)?h:i}return this.css(e,typeof a==="string"?a:a+"px")}}),a.jQuery=a.$=d})(window);
+ lib/js/lang-hs.js view
@@ -0,0 +1,102 @@+// Copyright (C) 2009 Google Inc.+//+// Licensed under the Apache License, Version 2.0 (the "License");+// you may not use this file except in compliance with the License.+// You may obtain a copy of the License at+//+// http://www.apache.org/licenses/LICENSE-2.0+//+// Unless required by applicable law or agreed to in writing, software+// distributed under the License is distributed on an "AS IS" BASIS,+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.+// See the License for the specific language governing permissions and+// limitations under the License.++++/**+ * @fileoverview+ * Registers a language handler for Haskell.+ *+ *+ * To use, include prettify.js and this file in your HTML page.+ * Then put your code in an HTML tag like+ * <pre class="prettyprint lang-hs">(my lisp code)</pre>+ * The lang-cl class identifies the language as common lisp.+ * This file supports the following language extensions:+ * lang-cl - Common Lisp+ * lang-el - Emacs Lisp+ * lang-lisp - Lisp+ * lang-scm - Scheme+ *+ *+ * I used http://www.informatik.uni-freiburg.de/~thiemann/haskell/haskell98-report-html/syntax-iso.html+ * as the basis, but ignore the way the ncomment production nests since this+ * makes the lexical grammar irregular. It might be possible to support+ * ncomments using the lookbehind filter.+ *+ *+ * @author mikesamuel@gmail.com+ */++PR['registerLangHandler'](+ PR['createSimpleLexer'](+ [+ // Whitespace+ // whitechar -> newline | vertab | space | tab | uniWhite+ // newline -> return linefeed | return | linefeed | formfeed+ [PR['PR_PLAIN'], /^[\t\n\x0B\x0C\r ]+/, null, '\t\n\x0B\x0C\r '],+ // Single line double and single-quoted strings.+ // char -> ' (graphic<' | \> | space | escape<\&>) '+ // string -> " {graphic<" | \> | space | escape | gap}"+ // escape -> \ ( charesc | ascii | decimal | o octal+ // | x hexadecimal )+ // charesc -> a | b | f | n | r | t | v | \ | " | ' | &+ [PR['PR_STRING'], /^\"(?:[^\"\\\n\x0C\r]|\\[\s\S])*(?:\"|$)/,+ null, '"'],+ [PR['PR_STRING'], /^\'(?:[^\'\\\n\x0C\r]|\\[^&])\'?/,+ null, "'"],+ // decimal -> digit{digit}+ // octal -> octit{octit}+ // hexadecimal -> hexit{hexit}+ // integer -> decimal+ // | 0o octal | 0O octal+ // | 0x hexadecimal | 0X hexadecimal+ // float -> decimal . decimal [exponent]+ // | decimal exponent+ // exponent -> (e | E) [+ | -] decimal+ [PR['PR_LITERAL'],+ /^(?:0o[0-7]+|0x[\da-f]+|\d+(?:\.\d+)?(?:e[+\-]?\d+)?)/i,+ null, '0123456789']+ ],+ [+ // Haskell does not have a regular lexical grammar due to the nested+ // ncomment.+ // comment -> dashes [ any<symbol> {any}] newline+ // ncomment -> opencom ANYseq {ncomment ANYseq}closecom+ // dashes -> '--' {'-'}+ // opencom -> '{-'+ // closecom -> '-}'+// [PR['PR_LITERAL'], /^(?:[a-zA-Z]+?\:)/, null],+ [PR['PR_COMMENT'], /^(?:(?:--+(?:[^\r\n\x0C]*)?)|(?:\{-(?:[^-]|-+[^-\}])*-\}))/],+ // reservedid -> case | class | data | default | deriving | do+ // | else | if | import | in | infix | infixl | infixr+ // | instance | let | module | newtype | of | then+ // | type | where | _+ [PR['PR_KEYWORD'], /^(?:yield|lazy|inline|private|open|class|data|default|deriving|do|else|if|import|in|infix|infixl|infixr|instance|let|module|newtype|of|then|when|with|type|where|_)(?=[^a-zA-Z0-9\']|$)/, null],+ // qvarid -> [ modid . ] varid+ // qconid -> [ modid . ] conid+ // varid -> (small {small | large | digit | ' })<reservedid>+ // conid -> large {small | large | digit | ' }+ // modid -> conid+ // small -> ascSmall | uniSmall | _+ // ascSmall -> a | b | ... | z+ // uniSmall -> any Unicode lowercase letter+ // large -> ascLarge | uniLarge+ // ascLarge -> A | B | ... | Z+ // uniLarge -> any uppercase or titlecase Unicode letter+ [PR['PR_PLAIN'], /^(?:[A-Z][\w\']*\.)*[a-zA-Z][\w\']*/],+ // matches the symbol production+ [PR['PR_PUNCTUATION'], /^[^\t\n\x0B\x0C\r a-zA-Z0-9\'\"]+/]+ ]),+ ['hs']);
+ lib/js/prettify.css view
@@ -0,0 +1,1 @@+.pln{color:#000}@media screen{.str{color:#080}.kwd{color:#008}.com{color:#800}.typ{color:#606}.lit{color:#066}.pun,.opn,.clo{color:#660}.tag{color:#008}.atn{color:#606}.atv{color:#080}.dec,.var{color:#606}.fun{color:red}}@media print,projection{.str{color:#060}.kwd{color:#006;font-weight:bold}.com{color:#600;font-style:italic}.typ{color:#404;font-weight:bold}.lit{color:#044}.pun,.opn,.clo{color:#440}.tag{color:#006;font-weight:bold}.atn{color:#404}.atv{color:#060}}pre.prettyprint{padding:2px;border:1px solid #888}ol.linenums{margin-top:0;margin-bottom:0}li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8{list-style-type:none}li.L1,li.L3,li.L5,li.L7,li.L9{background:#eee}
+ lib/js/prettify.js view
@@ -0,0 +1,28 @@+var q=null;window.PR_SHOULD_USE_CONTINUATION=!0;+(function(){function L(a){function m(a){var f=a.charCodeAt(0);if(f!==92)return f;var b=a.charAt(1);return(f=r[b])?f:"0"<=b&&b<="7"?parseInt(a.substring(1),8):b==="u"||b==="x"?parseInt(a.substring(2),16):a.charCodeAt(1)}function e(a){if(a<32)return(a<16?"\\x0":"\\x")+a.toString(16);a=String.fromCharCode(a);if(a==="\\"||a==="-"||a==="["||a==="]")a="\\"+a;return a}function h(a){for(var f=a.substring(1,a.length-1).match(/\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\[0-3][0-7]{0,2}|\\[0-7]{1,2}|\\[\S\s]|[^\\]/g),a=+[],b=[],o=f[0]==="^",c=o?1:0,i=f.length;c<i;++c){var j=f[c];if(/\\[bdsw]/i.test(j))a.push(j);else{var j=m(j),d;c+2<i&&"-"===f[c+1]?(d=m(f[c+2]),c+=2):d=j;b.push([j,d]);d<65||j>122||(d<65||j>90||b.push([Math.max(65,j)|32,Math.min(d,90)|32]),d<97||j>122||b.push([Math.max(97,j)&-33,Math.min(d,122)&-33]))}}b.sort(function(a,f){return a[0]-f[0]||f[1]-a[1]});f=[];j=[NaN,NaN];for(c=0;c<b.length;++c)i=b[c],i[0]<=j[1]+1?j[1]=Math.max(j[1],i[1]):f.push(j=i);b=["["];o&&b.push("^");b.push.apply(b,a);for(c=0;c<+f.length;++c)i=f[c],b.push(e(i[0])),i[1]>i[0]&&(i[1]+1>i[0]&&b.push("-"),b.push(e(i[1])));b.push("]");return b.join("")}function y(a){for(var f=a.source.match(/\[(?:[^\\\]]|\\[\S\s])*]|\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\\d+|\\[^\dux]|\(\?[!:=]|[()^]|[^()[\\^]+/g),b=f.length,d=[],c=0,i=0;c<b;++c){var j=f[c];j==="("?++i:"\\"===j.charAt(0)&&(j=+j.substring(1))&&j<=i&&(d[j]=-1)}for(c=1;c<d.length;++c)-1===d[c]&&(d[c]=++t);for(i=c=0;c<b;++c)j=f[c],j==="("?(++i,d[i]===void 0&&(f[c]="(?:")):"\\"===j.charAt(0)&&+(j=+j.substring(1))&&j<=i&&(f[c]="\\"+d[i]);for(i=c=0;c<b;++c)"^"===f[c]&&"^"!==f[c+1]&&(f[c]="");if(a.ignoreCase&&s)for(c=0;c<b;++c)j=f[c],a=j.charAt(0),j.length>=2&&a==="["?f[c]=h(j):a!=="\\"&&(f[c]=j.replace(/[A-Za-z]/g,function(a){a=a.charCodeAt(0);return"["+String.fromCharCode(a&-33,a|32)+"]"}));return f.join("")}for(var t=0,s=!1,l=!1,p=0,d=a.length;p<d;++p){var g=a[p];if(g.ignoreCase)l=!0;else if(/[a-z]/i.test(g.source.replace(/\\u[\da-f]{4}|\\x[\da-f]{2}|\\[^UXux]/gi,""))){s=!0;l=!1;break}}for(var r=+{b:8,t:9,n:10,v:11,f:12,r:13},n=[],p=0,d=a.length;p<d;++p){g=a[p];if(g.global||g.multiline)throw Error(""+g);n.push("(?:"+y(g)+")")}return RegExp(n.join("|"),l?"gi":"g")}function M(a){function m(a){switch(a.nodeType){case 1:if(e.test(a.className))break;for(var g=a.firstChild;g;g=g.nextSibling)m(g);g=a.nodeName;if("BR"===g||"LI"===g)h[s]="\n",t[s<<1]=y++,t[s++<<1|1]=a;break;case 3:case 4:g=a.nodeValue,g.length&&(g=p?g.replace(/\r\n?/g,"\n"):g.replace(/[\t\n\r ]+/g," "),h[s]=g,t[s<<1]=y,y+=g.length,+t[s++<<1|1]=a)}}var e=/(?:^|\s)nocode(?:\s|$)/,h=[],y=0,t=[],s=0,l;a.currentStyle?l=a.currentStyle.whiteSpace:window.getComputedStyle&&(l=document.defaultView.getComputedStyle(a,q).getPropertyValue("white-space"));var p=l&&"pre"===l.substring(0,3);m(a);return{a:h.join("").replace(/\n$/,""),c:t}}function B(a,m,e,h){m&&(a={a:m,d:a},e(a),h.push.apply(h,a.e))}function x(a,m){function e(a){for(var l=a.d,p=[l,"pln"],d=0,g=a.a.match(y)||[],r={},n=0,z=g.length;n<z;++n){var f=g[n],b=r[f],o=void 0,c;if(typeof b===+"string")c=!1;else{var i=h[f.charAt(0)];if(i)o=f.match(i[1]),b=i[0];else{for(c=0;c<t;++c)if(i=m[c],o=f.match(i[1])){b=i[0];break}o||(b="pln")}if((c=b.length>=5&&"lang-"===b.substring(0,5))&&!(o&&typeof o[1]==="string"))c=!1,b="src";c||(r[f]=b)}i=d;d+=f.length;if(c){c=o[1];var j=f.indexOf(c),k=j+c.length;o[2]&&(k=f.length-o[2].length,j=k-c.length);b=b.substring(5);B(l+i,f.substring(0,j),e,p);B(l+i+j,c,C(b,c),p);B(l+i+k,f.substring(k),e,p)}else p.push(l+i,b)}a.e=p}var h={},y;(function(){for(var e=a.concat(m),+l=[],p={},d=0,g=e.length;d<g;++d){var r=e[d],n=r[3];if(n)for(var k=n.length;--k>=0;)h[n.charAt(k)]=r;r=r[1];n=""+r;p.hasOwnProperty(n)||(l.push(r),p[n]=q)}l.push(/[\S\s]/);y=L(l)})();var t=m.length;return e}function u(a){var m=[],e=[];a.tripleQuotedStrings?m.push(["str",/^(?:'''(?:[^'\\]|\\[\S\s]|''?(?=[^']))*(?:'''|$)|"""(?:[^"\\]|\\[\S\s]|""?(?=[^"]))*(?:"""|$)|'(?:[^'\\]|\\[\S\s])*(?:'|$)|"(?:[^"\\]|\\[\S\s])*(?:"|$))/,q,"'\""]):a.multiLineStrings?m.push(["str",/^(?:'(?:[^'\\]|\\[\S\s])*(?:'|$)|"(?:[^"\\]|\\[\S\s])*(?:"|$)|`(?:[^\\`]|\\[\S\s])*(?:`|$))/,+q,"'\"`"]):m.push(["str",/^(?:'(?:[^\n\r'\\]|\\.)*(?:'|$)|"(?:[^\n\r"\\]|\\.)*(?:"|$))/,q,"\"'"]);a.verbatimStrings&&e.push(["str",/^@"(?:[^"]|"")*(?:"|$)/,q]);var h=a.hashComments;h&&(a.cStyleComments?(h>1?m.push(["com",/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,q,"#"]):m.push(["com",/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\n\r]*)/,q,"#"]),e.push(["str",/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,q])):m.push(["com",/^#[^\n\r]*/,+q,"#"]));a.cStyleComments&&(e.push(["com",/^\/\/[^\n\r]*/,q]),e.push(["com",/^\/\*[\S\s]*?(?:\*\/|$)/,q]));a.regexLiterals&&e.push(["lang-regex",/^(?:^^\.?|[!+-]|!=|!==|#|%|%=|&|&&|&&=|&=|\(|\*|\*=|\+=|,|-=|->|\/|\/=|:|::|;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|[?@[^]|\^=|\^\^|\^\^=|{|\||\|=|\|\||\|\|=|~|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\s*(\/(?=[^*/])(?:[^/[\\]|\\[\S\s]|\[(?:[^\\\]]|\\[\S\s])*(?:]|$))+\/)/]);(h=a.types)&&e.push(["typ",h]);a=(""+a.keywords).replace(/^ | $/g,+"");a.length&&e.push(["kwd",RegExp("^(?:"+a.replace(/[\s,]+/g,"|")+")\\b"),q]);m.push(["pln",/^\s+/,q," \r\n\t\xa0"]);e.push(["lit",/^@[$_a-z][\w$@]*/i,q],["typ",/^(?:[@_]?[A-Z]+[a-z][\w$@]*|\w+_t\b)/,q],["pln",/^[$_a-z][\w$@]*/i,q],["lit",/^(?:0x[\da-f]+|(?:\d(?:_\d+)*\d*(?:\.\d*)?|\.\d\+)(?:e[+-]?\d+)?)[a-z]*/i,q,"0123456789"],["pln",/^\\[\S\s]?/,q],["pun",/^.[^\s\w"-$'./@\\`]*/,q]);return x(m,e)}function D(a,m){function e(a){switch(a.nodeType){case 1:if(k.test(a.className))break;if("BR"===a.nodeName)h(a),+a.parentNode&&a.parentNode.removeChild(a);else for(a=a.firstChild;a;a=a.nextSibling)e(a);break;case 3:case 4:if(p){var b=a.nodeValue,d=b.match(t);if(d){var c=b.substring(0,d.index);a.nodeValue=c;(b=b.substring(d.index+d[0].length))&&a.parentNode.insertBefore(s.createTextNode(b),a.nextSibling);h(a);c||a.parentNode.removeChild(a)}}}}function h(a){function b(a,d){var e=d?a.cloneNode(!1):a,f=a.parentNode;if(f){var f=b(f,1),g=a.nextSibling;f.appendChild(e);for(var h=g;h;h=g)g=h.nextSibling,f.appendChild(h)}return e}+for(;!a.nextSibling;)if(a=a.parentNode,!a)return;for(var a=b(a.nextSibling,0),e;(e=a.parentNode)&&e.nodeType===1;)a=e;d.push(a)}var k=/(?:^|\s)nocode(?:\s|$)/,t=/\r\n?|\n/,s=a.ownerDocument,l;a.currentStyle?l=a.currentStyle.whiteSpace:window.getComputedStyle&&(l=s.defaultView.getComputedStyle(a,q).getPropertyValue("white-space"));var p=l&&"pre"===l.substring(0,3);for(l=s.createElement("LI");a.firstChild;)l.appendChild(a.firstChild);for(var d=[l],g=0;g<d.length;++g)e(d[g]);m===(m|0)&&d[0].setAttribute("value",+m);var r=s.createElement("OL");r.className="linenums";for(var n=Math.max(0,m-1|0)||0,g=0,z=d.length;g<z;++g)l=d[g],l.className="L"+(g+n)%10,l.firstChild||l.appendChild(s.createTextNode("\xa0")),r.appendChild(l);a.appendChild(r)}function k(a,m){for(var e=m.length;--e>=0;){var h=m[e];A.hasOwnProperty(h)?window.console&&console.warn("cannot override language handler %s",h):A[h]=a}}function C(a,m){if(!a||!A.hasOwnProperty(a))a=/^\s*</.test(m)?"default-markup":"default-code";return A[a]}function E(a){var m=+a.g;try{var e=M(a.h),h=e.a;a.a=h;a.c=e.c;a.d=0;C(m,h)(a);var k=/\bMSIE\b/.test(navigator.userAgent),m=/\n/g,t=a.a,s=t.length,e=0,l=a.c,p=l.length,h=0,d=a.e,g=d.length,a=0;d[g]=s;var r,n;for(n=r=0;n<g;)d[n]!==d[n+2]?(d[r++]=d[n++],d[r++]=d[n++]):n+=2;g=r;for(n=r=0;n<g;){for(var z=d[n],f=d[n+1],b=n+2;b+2<=g&&d[b+1]===f;)b+=2;d[r++]=z;d[r++]=f;n=b}for(d.length=r;h<p;){var o=l[h+2]||s,c=d[a+2]||s,b=Math.min(o,c),i=l[h+1],j;if(i.nodeType!==1&&(j=t.substring(e,b))){k&&(j=j.replace(m,"\r"));i.nodeValue=+j;var u=i.ownerDocument,v=u.createElement("SPAN");v.className=d[a+1];var x=i.parentNode;x.replaceChild(v,i);v.appendChild(i);e<o&&(l[h+1]=i=u.createTextNode(t.substring(b,o)),x.insertBefore(i,v.nextSibling))}e=b;e>=o&&(h+=2);e>=c&&(a+=2)}}catch(w){"console"in window&&console.log(w&&w.stack?w.stack:w)}}var v=["break,continue,do,else,for,if,return,while"],w=[[v,"auto,case,char,const,default,double,enum,extern,float,goto,int,long,register,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"],+"catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"],F=[w,"alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,dynamic_cast,explicit,export,friend,inline,late_check,mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"],G=[w,"abstract,boolean,byte,extends,final,finally,implements,import,instanceof,null,native,package,strictfp,super,synchronized,throws,transient"],+H=[G,"as,base,by,checked,decimal,delegate,descending,dynamic,event,fixed,foreach,from,group,implicit,in,interface,internal,into,is,lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var"],w=[w,"debugger,eval,export,function,get,null,set,undefined,var,with,Infinity,NaN"],I=[v,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"],+J=[v,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"],v=[v,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"],K=/^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)/,N=/\S/,O=u({keywords:[F,H,w,"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END"++I,J,v],hashComments:!0,cStyleComments:!0,multiLineStrings:!0,regexLiterals:!0}),A={};k(O,["default-code"]);k(x([],[["pln",/^[^<?]+/],["dec",/^<!\w[^>]*(?:>|$)/],["com",/^<\!--[\S\s]*?(?:--\>|$)/],["lang-",/^<\?([\S\s]+?)(?:\?>|$)/],["lang-",/^<%([\S\s]+?)(?:%>|$)/],["pun",/^(?:<[%?]|[%?]>)/],["lang-",/^<xmp\b[^>]*>([\S\s]+?)<\/xmp\b[^>]*>/i],["lang-js",/^<script\b[^>]*>([\S\s]*?)(<\/script\b[^>]*>)/i],["lang-css",/^<style\b[^>]*>([\S\s]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]),+["default-markup","htm","html","mxml","xhtml","xml","xsl"]);k(x([["pln",/^\s+/,q," \t\r\n"],["atv",/^(?:"[^"]*"?|'[^']*'?)/,q,"\"'"]],[["tag",/^^<\/?[a-z](?:[\w-.:]*\w)?|\/?>$/i],["atn",/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^\s"'>]*(?:[^\s"'/>]|\/(?=\s)))/],["pun",/^[/<->]+/],["lang-js",/^on\w+\s*=\s*"([^"]+)"/i],["lang-js",/^on\w+\s*=\s*'([^']+)'/i],["lang-js",/^on\w+\s*=\s*([^\s"'>]+)/i],["lang-css",/^style\s*=\s*"([^"]+)"/i],["lang-css",/^style\s*=\s*'([^']+)'/i],["lang-css",+/^style\s*=\s*([^\s"'>]+)/i]]),["in.tag"]);k(x([],[["atv",/^[\S\s]+/]]),["uq.val"]);k(u({keywords:F,hashComments:!0,cStyleComments:!0,types:K}),["c","cc","cpp","cxx","cyc","m"]);k(u({keywords:"null,true,false"}),["json"]);k(u({keywords:H,hashComments:!0,cStyleComments:!0,verbatimStrings:!0,types:K}),["cs"]);k(u({keywords:G,cStyleComments:!0}),["java"]);k(u({keywords:v,hashComments:!0,multiLineStrings:!0}),["bsh","csh","sh"]);k(u({keywords:I,hashComments:!0,multiLineStrings:!0,tripleQuotedStrings:!0}),+["cv","py"]);k(u({keywords:"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END",hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["perl","pl","pm"]);k(u({keywords:J,hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["rb"]);k(u({keywords:w,cStyleComments:!0,regexLiterals:!0}),["js"]);k(u({keywords:"all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,true,try,unless,until,when,while,yes",+hashComments:3,cStyleComments:!0,multilineStrings:!0,tripleQuotedStrings:!0,regexLiterals:!0}),["coffee"]);k(x([],[["str",/^[\S\s]+/]]),["regex"]);window.prettyPrintOne=function(a,m,e){var h=document.createElement("PRE");h.innerHTML=a;e&&D(h,e);E({g:m,i:e,h:h});return h.innerHTML};window.prettyPrint=function(a){function m(){for(var e=window.PR_SHOULD_USE_CONTINUATION?l.now()+250:Infinity;p<h.length&&l.now()<e;p++){var n=h[p],k=n.className;if(k.indexOf("prettyprint")>=0){var k=k.match(g),f,b;if(b=+!k){b=n;for(var o=void 0,c=b.firstChild;c;c=c.nextSibling)var i=c.nodeType,o=i===1?o?b:c:i===3?N.test(c.nodeValue)?b:o:o;b=(f=o===b?void 0:o)&&"CODE"===f.tagName}b&&(k=f.className.match(g));k&&(k=k[1]);b=!1;for(o=n.parentNode;o;o=o.parentNode)if((o.tagName==="pre"||o.tagName==="code"||o.tagName==="xmp")&&o.className&&o.className.indexOf("prettyprint")>=0){b=!0;break}b||((b=(b=n.className.match(/\blinenums\b(?::(\d+))?/))?b[1]&&b[1].length?+b[1]:!0:!1)&&D(n,b),d={g:k,h:n,i:b},E(d))}}p<h.length?setTimeout(m,+250):a&&a()}for(var e=[document.getElementsByTagName("pre"),document.getElementsByTagName("code"),document.getElementsByTagName("xmp")],h=[],k=0;k<e.length;++k)for(var t=0,s=e[k].length;t<s;++t)h.push(e[k][t]);var e=q,l=Date;l.now||(l={now:function(){return+new Date}});var p=0,d,g=/\blang(?:uage)?-([\w.]+)(?!\S)/;m()};window.PR={createSimpleLexer:x,registerLangHandler:k,sourceDecorator:u,PR_ATTRIB_NAME:"atn",PR_ATTRIB_VALUE:"atv",PR_COMMENT:"com",PR_DECLARATION:"dec",PR_KEYWORD:"kwd",PR_LITERAL:"lit",+PR_NOCODE:"nocode",PR_PLAIN:"pln",PR_PUNCTUATION:"pun",PR_SOURCE:"src",PR_STRING:"str",PR_TAG:"tag",PR_TYPE:"typ"}})();
+ lib/js/underscore.js view
@@ -0,0 +1,26 @@+// Underscore.js 1.1.5+// (c) 2011 Jeremy Ashkenas, DocumentCloud Inc.+// Underscore is freely distributable under the MIT license.+// Portions of Underscore are inspired or borrowed from Prototype,+// Oliver Steele's Functional, and John Resig's Micro-Templating.+// For all details and documentation:+// http://documentcloud.github.com/underscore+(function(){var q=this,D=q._,n={},k=Array.prototype,o=Object.prototype,i=k.slice,E=k.unshift,F=o.toString,m=o.hasOwnProperty,s=k.forEach,t=k.map,u=k.reduce,v=k.reduceRight,w=k.filter,x=k.every,y=k.some,p=k.indexOf,z=k.lastIndexOf;o=Array.isArray;var G=Object.keys,A=Function.prototype.bind,c=function(a){return new l(a)};if(typeof module!=="undefined"&&module.exports){module.exports=c;c._=c}else q._=c;c.VERSION="1.1.5";var j=c.each=c.forEach=function(a,b,d){if(a!=null)if(s&&a.forEach===s)a.forEach(b,+d);else if(c.isNumber(a.length))for(var e=0,f=a.length;e<f;e++){if(b.call(d,a[e],e,a)===n)break}else for(e in a)if(m.call(a,e))if(b.call(d,a[e],e,a)===n)break};c.map=function(a,b,d){var e=[];if(a==null)return e;if(t&&a.map===t)return a.map(b,d);j(a,function(f,g,h){e[e.length]=b.call(d,f,g,h)});return e};c.reduce=c.foldl=c.inject=function(a,b,d,e){var f=d!==void 0;if(a==null)a=[];if(u&&a.reduce===u){if(e)b=c.bind(b,e);return f?a.reduce(b,d):a.reduce(b)}j(a,function(g,h,H){if(!f&&h===0){d=g;f=true}else d=+b.call(e,d,g,h,H)});if(!f)throw new TypeError("Reduce of empty array with no initial value");return d};c.reduceRight=c.foldr=function(a,b,d,e){if(a==null)a=[];if(v&&a.reduceRight===v){if(e)b=c.bind(b,e);return d!==void 0?a.reduceRight(b,d):a.reduceRight(b)}a=(c.isArray(a)?a.slice():c.toArray(a)).reverse();return c.reduce(a,b,d,e)};c.find=c.detect=function(a,b,d){var e;B(a,function(f,g,h){if(b.call(d,f,g,h)){e=f;return true}});return e};c.filter=c.select=function(a,b,d){var e=[];if(a==null)return e;+if(w&&a.filter===w)return a.filter(b,d);j(a,function(f,g,h){if(b.call(d,f,g,h))e[e.length]=f});return e};c.reject=function(a,b,d){var e=[];if(a==null)return e;j(a,function(f,g,h){b.call(d,f,g,h)||(e[e.length]=f)});return e};c.every=c.all=function(a,b,d){b=b||c.identity;var e=true;if(a==null)return e;if(x&&a.every===x)return a.every(b,d);j(a,function(f,g,h){if(!(e=e&&b.call(d,f,g,h)))return n});return e};var B=c.some=c.any=function(a,b,d){b=b||c.identity;var e=false;if(a==null)return e;if(y&&a.some===+y)return a.some(b,d);j(a,function(f,g,h){if(e=b.call(d,f,g,h))return n});return e};c.include=c.contains=function(a,b){var d=false;if(a==null)return d;if(p&&a.indexOf===p)return a.indexOf(b)!=-1;B(a,function(e){if(d=e===b)return true});return d};c.invoke=function(a,b){var d=i.call(arguments,2);return c.map(a,function(e){return(b?e[b]:e).apply(e,d)})};c.pluck=function(a,b){return c.map(a,function(d){return d[b]})};c.max=function(a,b,d){if(!b&&c.isArray(a))return Math.max.apply(Math,a);var e={computed:-Infinity};+j(a,function(f,g,h){g=b?b.call(d,f,g,h):f;g>=e.computed&&(e={value:f,computed:g})});return e.value};c.min=function(a,b,d){if(!b&&c.isArray(a))return Math.min.apply(Math,a);var e={computed:Infinity};j(a,function(f,g,h){g=b?b.call(d,f,g,h):f;g<e.computed&&(e={value:f,computed:g})});return e.value};c.sortBy=function(a,b,d){return c.pluck(c.map(a,function(e,f,g){return{value:e,criteria:b.call(d,e,f,g)}}).sort(function(e,f){var g=e.criteria,h=f.criteria;return g<h?-1:g>h?1:0}),"value")};c.sortedIndex=+function(a,b,d){d=d||c.identity;for(var e=0,f=a.length;e<f;){var g=e+f>>1;d(a[g])<d(b)?e=g+1:f=g}return e};c.toArray=function(a){if(!a)return[];if(a.toArray)return a.toArray();if(c.isArray(a))return a;if(c.isArguments(a))return i.call(a);return c.values(a)};c.size=function(a){return c.toArray(a).length};c.first=c.head=function(a,b,d){return b!=null&&!d?i.call(a,0,b):a[0]};c.rest=c.tail=function(a,b,d){return i.call(a,b==null||d?1:b)};c.last=function(a){return a[a.length-1]};c.compact=function(a){return c.filter(a,+function(b){return!!b})};c.flatten=function(a){return c.reduce(a,function(b,d){if(c.isArray(d))return b.concat(c.flatten(d));b[b.length]=d;return b},[])};c.without=function(a){var b=i.call(arguments,1);return c.filter(a,function(d){return!c.include(b,d)})};c.uniq=c.unique=function(a,b){return c.reduce(a,function(d,e,f){if(0==f||(b===true?c.last(d)!=e:!c.include(d,e)))d[d.length]=e;return d},[])};c.intersect=function(a){var b=i.call(arguments,1);return c.filter(c.uniq(a),function(d){return c.every(b,+function(e){return c.indexOf(e,d)>=0})})};c.zip=function(){for(var a=i.call(arguments),b=c.max(c.pluck(a,"length")),d=Array(b),e=0;e<b;e++)d[e]=c.pluck(a,""+e);return d};c.indexOf=function(a,b,d){if(a==null)return-1;var e;if(d){d=c.sortedIndex(a,b);return a[d]===b?d:-1}if(p&&a.indexOf===p)return a.indexOf(b);d=0;for(e=a.length;d<e;d++)if(a[d]===b)return d;return-1};c.lastIndexOf=function(a,b){if(a==null)return-1;if(z&&a.lastIndexOf===z)return a.lastIndexOf(b);for(var d=a.length;d--;)if(a[d]===b)return d;+return-1};c.range=function(a,b,d){if(arguments.length<=1){b=a||0;a=0}d=arguments[2]||1;for(var e=Math.max(Math.ceil((b-a)/d),0),f=0,g=Array(e);f<e;){g[f++]=a;a+=d}return g};c.bind=function(a,b){if(A&&a.bind===A)return a.bind.apply(a,i.call(arguments,1));var d=i.call(arguments,2);return function(){return a.apply(b,d.concat(i.call(arguments)))}};c.bindAll=function(a){var b=i.call(arguments,1);if(b.length==0)b=c.functions(a);j(b,function(d){a[d]=c.bind(a[d],a)});return a};c.memoize=function(a,b){var d=+{};b=b||c.identity;return function(){var e=b.apply(this,arguments);return m.call(d,e)?d[e]:d[e]=a.apply(this,arguments)}};c.delay=function(a,b){var d=i.call(arguments,2);return setTimeout(function(){return a.apply(a,d)},b)};c.defer=function(a){return c.delay.apply(c,[a,1].concat(i.call(arguments,1)))};var C=function(a,b,d){var e;return function(){var f=this,g=arguments,h=function(){e=null;a.apply(f,g)};d&&clearTimeout(e);if(d||!e)e=setTimeout(h,b)}};c.throttle=function(a,b){return C(a,b,false)};c.debounce=+function(a,b){return C(a,b,true)};c.once=function(a){var b=false,d;return function(){if(b)return d;b=true;return d=a.apply(this,arguments)}};c.wrap=function(a,b){return function(){var d=[a].concat(i.call(arguments));return b.apply(this,d)}};c.compose=function(){var a=i.call(arguments);return function(){for(var b=i.call(arguments),d=a.length-1;d>=0;d--)b=[a[d].apply(this,b)];return b[0]}};c.keys=G||function(a){if(a!==Object(a))throw new TypeError("Invalid object");var b=[],d;for(d in a)if(m.call(a,+d))b[b.length]=d;return b};c.values=function(a){return c.map(a,c.identity)};c.functions=c.methods=function(a){return c.filter(c.keys(a),function(b){return c.isFunction(a[b])}).sort()};c.extend=function(a){j(i.call(arguments,1),function(b){for(var d in b)a[d]=b[d]});return a};c.defaults=function(a){j(i.call(arguments,1),function(b){for(var d in b)if(a[d]==null)a[d]=b[d]});return a};c.clone=function(a){return c.isArray(a)?a.slice():c.extend({},a)};c.tap=function(a,b){b(a);return a};c.isEqual=function(a,+b){if(a===b)return true;var d=typeof a;if(d!=typeof b)return false;if(a==b)return true;if(!a&&b||a&&!b)return false;if(a._chain)a=a._wrapped;if(b._chain)b=b._wrapped;if(a.isEqual)return a.isEqual(b);if(c.isDate(a)&&c.isDate(b))return a.getTime()===b.getTime();if(c.isNaN(a)&&c.isNaN(b))return false;if(c.isRegExp(a)&&c.isRegExp(b))return a.source===b.source&&a.global===b.global&&a.ignoreCase===b.ignoreCase&&a.multiline===b.multiline;if(d!=="object")return false;if(a.length&&a.length!==b.length)return false;+d=c.keys(a);var e=c.keys(b);if(d.length!=e.length)return false;for(var f in a)if(!(f in b)||!c.isEqual(a[f],b[f]))return false;return true};c.isEmpty=function(a){if(c.isArray(a)||c.isString(a))return a.length===0;for(var b in a)if(m.call(a,b))return false;return true};c.isElement=function(a){return!!(a&&a.nodeType==1)};c.isArray=o||function(a){return F.call(a)==="[object Array]"};c.isArguments=function(a){return!!(a&&m.call(a,"callee"))};c.isFunction=function(a){return!!(a&&a.constructor&&a.call&&+a.apply)};c.isString=function(a){return!!(a===""||a&&a.charCodeAt&&a.substr)};c.isNumber=function(a){return!!(a===0||a&&a.toExponential&&a.toFixed)};c.isNaN=function(a){return a!==a};c.isBoolean=function(a){return a===true||a===false};c.isDate=function(a){return!!(a&&a.getTimezoneOffset&&a.setUTCFullYear)};c.isRegExp=function(a){return!!(a&&a.test&&a.exec&&(a.ignoreCase||a.ignoreCase===false))};c.isNull=function(a){return a===null};c.isUndefined=function(a){return a===void 0};c.noConflict=function(){q._=+D;return this};c.identity=function(a){return a};c.times=function(a,b,d){for(var e=0;e<a;e++)b.call(d,e)};c.mixin=function(a){j(c.functions(a),function(b){I(b,c[b]=a[b])})};var J=0;c.uniqueId=function(a){var b=J++;return a?a+b:b};c.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g};c.template=function(a,b){var d=c.templateSettings;d="var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('"+a.replace(/\\/g,"\\\\").replace(/'/g,"\\'").replace(d.interpolate,+function(e,f){return"',"+f.replace(/\\'/g,"'")+",'"}).replace(d.evaluate||null,function(e,f){return"');"+f.replace(/\\'/g,"'").replace(/[\r\n\t]/g," ")+"__p.push('"}).replace(/\r/g,"\\r").replace(/\n/g,"\\n").replace(/\t/g,"\\t")+"');}return __p.join('');";d=new Function("obj",d);return b?d(b):d};var l=function(a){this._wrapped=a};c.prototype=l.prototype;var r=function(a,b){return b?c(a).chain():a},I=function(a,b){l.prototype[a]=function(){var d=i.call(arguments);E.call(d,this._wrapped);return r(b.apply(c,+d),this._chain)}};c.mixin(c);j(["pop","push","reverse","shift","sort","splice","unshift"],function(a){var b=k[a];l.prototype[a]=function(){b.apply(this._wrapped,arguments);return r(this._wrapped,this._chain)}});j(["concat","join","slice"],function(a){var b=k[a];l.prototype[a]=function(){return r(b.apply(this._wrapped,arguments),this._chain)}});l.prototype.chain=function(){this._chain=true;return this};l.prototype.value=function(){return this._wrapped}})();
+ lib/js/zepto.js view
@@ -0,0 +1,1 @@+String.prototype.trim===undefined&&(String.prototype.trim=function(){return this.replace(/^\s+/,"").replace(/\s+$/,"")}),Array.prototype.reduce===undefined&&(Array.prototype.reduce=function(a){if(this===void 0||this===null)throw new TypeError;var b=Object(this),c=b.length>>>0,d=0,e;if(typeof a!=="function")throw new TypeError;if(c==0&&arguments.length==1)throw new TypeError;if(arguments.length<2){do{if(d in b){e=b[d++];break}if(++d>=c)throw new TypeError}while(!0)}else e=arguments[1];while(d<c)d in b&&(e=a.call(undefined,e,b[d],d,b)),d++;return e});var Zepto=function(){function r(a,b){return b===h?q(a):q(a).filter(b)}function q(a,b){if(a==g)return p();if(b!==h)return q(b).find(a);if(typeof a==="function")return q(g).ready(a);if(a instanceof p)return a;var c;a instanceof Array?c=k(a):a instanceof Element||a===window?c=[a]:e.test(a)?c=o(a):c=d(g,a);return p(c,a)}function p(a,b){a=a||[],a.__proto__=p.prototype,a.selector=b||"";return a}function o(b){f.innerHTML=(""+b).trim();var c=a.call(f.childNodes);f.innerHTML="";return c}function n(a){var b=[];for(var c=0,d=a.length;c<d;c++)b.indexOf(a[c])<0&&b.push(a[c]);return b}function m(a){return a.replace(/-+(.)?/g,function(a,b){return b?b.toUpperCase():""})}function l(a){return a.reduce(function(a,b){return a.concat(b)},[])}function k(a){return a.filter(function(a){return a!==h&&a!==null})}function j(a){return new RegExp("(^|\\s)"+a+"(\\s|$)")}var a=[].slice,b,c,d,e,f,g=window.document,h,i=g.defaultView.getComputedStyle;e=/^\s*<.+>/,f=g.createElement("div"),q.extend=function(a,c){for(b in c)a[b]=c[b];return a},q.qsa=d=function(b,c){return a.call(b.querySelectorAll(c))},q.fn={forEach:[].forEach,map:[].map,reduce:[].reduce,push:[].push,indexOf:[].indexOf,concat:[].concat,ready:function(a){g.addEventListener("DOMContentLoaded",a,!1);return this},get:function(a){return a===h?this:this[a]},size:function(){return this.length},remove:function(){return this.each(function(){this.parentNode.removeChild(this)})},each:function(a){this.forEach(function(b,c){a.call(b,c,b)});return this},filter:function(a){return q([].filter.call(this,function(b){return d(b.parentNode,a).indexOf(b)>=0}))},is:function(a){return this.length>0&&q(this[0]).filter(a).length>0},not:function(b){var c=[];if(typeof b=="function"&&b.call!==h)this.each(function(a){b.call(this,a)||c.push(this)});else{var d=a.call(typeof b==="string"?this.filter(b):b instanceof NodeList?b:q(b));a.call(this).forEach(function(a){d.indexOf(a)<0&&c.push(a)})}return q(c)},eq:function(a){return q(this[a])},first:function(){return q(this[0])},last:function(){return q(this[this.length-1])},find:function(a){var b;this.length==1?b=d(this[0],a):b=l(this.map(function(b){return d(b,a)}));return q(b)},closest:function(a,b){var c=this[0],e=d(b!==h?b:g,a);e.length===0&&(c=null);while(c&&c!==g&&e.indexOf(c)<0)c=c.parentNode;return q(c)},parents:function(a){var b=[],c=this;while(c.length>0)c=k(c.map(function(a){if((a=a.parentNode)&&a!==g&&b.indexOf(a)<0){b.push(a);return a}}));return r(b,a)},parent:function(a){return r(n(k(this.pluck("parentNode"))),a)},children:function(b){return r(l(this.map(function(b){return a.call(b.children)})),b)},siblings:function(b){return r(l(this.map(function(b){return a.call(b.parentNode.children).filter(function(a){return a!==b})})),b)},pluck:function(a){return this.map(function(b){return b[a]})},show:function(){return this.css("display","block")},hide:function(){return this.css("display","none")},prev:function(){return q(this.pluck("previousElementSibling"))},next:function(){return q(this.pluck("nextElementSibling"))},html:function(a){return a===h?this.length>0?this[0].innerHTML:null:this.each(function(b){this.innerHTML=typeof a=="function"?a.call(this,b,this.innerHTML):a})},text:function(a){return a===h?this.length>0?this[0].innerText:null:this.each(function(){this.innerText=a})},attr:function(a,c){return typeof a=="string"&&c===h?this.length>0&&this[0].nodeName==="INPUT"&&this[0].type==="text"&&a==="value"?this.val():this.length>0?this[0].getAttribute(a)||(a in this[0]?this[0][a]:h):null:this.each(function(d){if(typeof a=="object")for(b in a)this.setAttribute(b,a[b]);else this.setAttribute(a,typeof c=="function"?c.call(this,d,this.getAttribute(a)):c)})},removeAttr:function(a){return this.each(function(){this.removeAttribute(a)})},data:function(a,b){return this.attr("data-"+a,b)},val:function(a){return a===h?this.length>0?this[0].value:null:this.each(function(){this.value=a})},offset:function(){var a=this[0].getBoundingClientRect();return{left:a.left+g.body.scrollLeft,top:a.top+g.body.scrollTop,width:a.width,height:a.height}},css:function(a,d){if(d===h&&typeof a=="string")return this[0].style[m(a)]||i(this[0],"").getPropertyValue(a);c="";for(b in a)c+=b+":"+a[b]+";";typeof a=="string"&&(c=a+":"+d);return this.each(function(){this.style.cssText+=";"+c})},index:function(a){return this.indexOf(q(a)[0])},hasClass:function(a){return j(a).test(this[0].className)},addClass:function(a){return this.each(function(){!q(this).hasClass(a)&&(this.className+=(this.className?" ":"")+a)})},removeClass:function(a){return this.each(function(){this.className=this.className.replace(j(a)," ").trim()})},toggleClass:function(a,b){return this.each(function(){b!==h&&!b||q(this).hasClass(a)?q(this).removeClass(a):q(this).addClass(a)})}},["width","height"].forEach(function(a){q.fn[a]=function(){return this.offset()[a]}});var s={append:"beforeEnd",prepend:"afterBegin",before:"beforeBegin",after:"afterEnd"};for(b in s)q.fn[b]=function(a){return function(b){return this.each(function(c,d){if(b instanceof p){dom=b;if(a=="afterBegin"||a=="afterEnd")for(var e=0;e<dom.length;e++)d.insertAdjacentElement(a,dom[dom.length-e-1]);else for(var e=0;e<dom.length;e++)d.insertAdjacentElement(a,dom[e])}else d["insertAdjacent"+(b instanceof Element?"Element":"HTML")](a,b)})}}(s[b]);p.prototype=q.fn;return q}();"$"in window||(window.$=Zepto),function(a){function l(b){var c=a.extend({originalEvent:b},b);k.forEach(function(a){c[a]=function(){return b[a].apply(b,arguments)}});return c}function j(a,b,d,g){var h=e(a);(b||"").split(/\s/).forEach(function(b){f(a,b,d,g).forEach(function(b){delete c[h][b.i],a.removeEventListener(b.e,b.del||b.fn,!1)})})}function i(b,d,f,h,i){var j=e(b),k=c[j]||(c[j]=[]);d.split(/\s/).forEach(function(c){var d=a.extend(g(c),{fn:f,sel:h,del:i,i:k.length});k.push(d),b.addEventListener(d.e,i||f,!1)})}function h(a){return new RegExp("(?:^| )"+a.replace(" "," .* ?")+"(?: |$)")}function g(a){var b=(""+a).split(".");return{e:b[0],ns:b.slice(1).sort().join(" ")}}function f(a,b,d,f){b=g(b);if(b.ns)var i=h(b.ns);return(c[e(a)]||[]).filter(function(a){return a&&(!b.e||a.e==b.e)&&(!b.ns||i.test(a.ns))&&(!d||a.fn==d)&&(!f||a.sel==f)})}function e(a){return a._zid||(a._zid=d++)}var b=a.qsa,c={},d=1;a.event={add:function(a,b,c){i(a,b,c)},remove:function(a,b,c){j(a,b,c)}},a.fn.bind=function(a,b){return this.each(function(){i(this,a,b)})},a.fn.unbind=function(a,b){return this.each(function(){j(this,a,b)})},a.fn.one=function(a,b){return this.each(function(){var c=this;i(this,a,function d(){b(),j(c,a,arguments.callee)})})};var k=["preventDefault","stopImmediatePropagation","stopPropagation"];a.fn.delegate=function(c,d,e){return this.each(function(f,g){i(g,d,e,c,function(d){var f=d.target,h=b(g,c);while(f&&h.indexOf(f)<0)f=f.parentNode;f&&f!==g&&f!==document&&e.call(f,a.extend(l(d),{currentTarget:f,liveFired:g}))})})},a.fn.undelegate=function(a,b,c){return this.each(function(){j(this,b,c,a)})},a.fn.live=function(b,c){a(document.body).delegate(this.selector,b,c);return this},a.fn.die=function(b,c){a(document.body).undelegate(this.selector,b,c);return this},a.fn.trigger=function(a){return this.each(function(){var b=document.createEvent("Events");this.dispatchEvent(b,b.initEvent(a,!0,!0))})}}(Zepto),function(a){function b(a){var a=a,b={},c=a.match(/(Android)\s+([\d.]+)/),d=a.match(/(iPhone\sOS)\s([\d_]+)/),e=a.match(/(iPad).*OS\s([\d_]+)/),f=a.match(/(webOS)\/([\d.]+)/),g=a.match(/(BlackBerry).*Version\/([\d.]+)/);c&&(b.android=!0,b.version=c[2]),d&&(b.ios=!0,b.version=d[2].replace(/_/g,"."),b.iphone=!0),e&&(b.ios=!0,b.version=e[2].replace(/_/g,"."),b.ipad=!0),f&&(b.webos=!0,b.version=f[2]),g&&(b.blackberry=!0,b.version=g[2]);return b}a.os=b(navigator.userAgent),a.__detect=b;var c=navigator.userAgent.match(/WebKit\/([\d.]+)/);a.browser=c?{webkit:!0,version:c[1]}:{webkit:!1}}(Zepto),function(a){a.fn.anim=function(a,b,c,d){var e=[],f,g;for(g in a)g==="opacity"?f=a[g]:e.push(g+"("+a[g]+")");typeof d=="function"&&this.one("webkitTransitionEnd",d);return this.css({"-webkit-transition":"all "+(b!==undefined?b:.5)+"s "+(c||""),"-webkit-transform":e.join(" "),opacity:f})}}(Zepto),function(a){function d(a){return"tagName"in a?a:a.parentNode}var b={},c;a(document).ready(function(){a(document.body).bind("touchstart",function(a){var e=Date.now(),f=e-(b.last||e);b.target=d(a.touches[0].target),c&&clearTimeout(c),b.x1=a.touches[0].pageX,f>0&&f<=250&&(b.isDoubleTap=!0),b.last=e}).bind("touchmove",function(a){b.x2=a.touches[0].pageX}).bind("touchend",function(d){b.isDoubleTap?(a(b.target).trigger("doubleTap"),b={}):b.x2>0?(Math.abs(b.x1-b.x2)>30&&a(b.target).trigger("swipe")&&a(b.target).trigger("swipe"+(b.x1-b.x2>0?"Left":"Right")),b.x1=b.x2=b.last=0):"last"in b&&(c=setTimeout(function(){c=null,a(b.target).trigger("tap"),b={}},250))}).bind("touchcancel",function(){b={}})}),["swipe","swipeLeft","swipeRight","doubleTap","tap"].forEach(function(b){a.fn[b]=function(a){return this.bind(b,a)}})}(Zepto),function(a){function c(){}var b=0;a.ajaxJSONP=function(c){var d="jsonp"+ ++b,e=document.createElement("script");window[d]=function(a){c.success(a),delete window.jsonpString},e.src=c.url.replace(/=\?/,"="+d),a("head").append(e)},a.ajax=function(b){b=b||{};if(b.url&&/=\?/.test(b.url))return a.ajaxJSONP(b);var e=b.data,f=b.success||c,g=b.error||c,h=d[b.dataType],i=b.type||"GET",j=b.contentType||(i==="POST"?"application/x-www-form-urlencoded":""),k=new XMLHttpRequest;k.onreadystatechange=function(){if(k.readyState==4)if(k.status>=200&&k.status<300||k.status==0)if(h=="application/json"){var a,b=!1;try{a=JSON.parse(k.responseText)}catch(c){b=c}b?g(k,"parsererror",b):f(a,"success",k)}else f(k.responseText,"success",k);else g(k,"error")},k.open(i,b.url||window.location,!0),h&&k.setRequestHeader("Accept",h),e instanceof Object&&(e=a.param(e)),j&&k.setRequestHeader("Content-Type",j),k.setRequestHeader("X-Requested-With","XMLHttpRequest"),k.send(e)};var d=a.ajax.mimeTypes={json:"application/json",xml:"application/xml",html:"text/html",text:"text/plain"};a.get=function(b,c){a.ajax({url:b,success:c})},a.post=function(b,c,d,e){c instanceof Function&&(e=e||d,d=c,c=null),a.ajax({type:"POST",url:b,data:c,success:d,dataType:e})},a.getJSON=function(b,c){a.ajax({url:b,success:c,dataType:"json"})},a.fn.load=function(b,c){if(!this.length)return this;var d=this,e=b.split(/\s/),f;e.length>1&&(b=e[0],f=e[1]),a.get(b,function(b){d.html(f?a(document.createElement("div")).html(b).find(f).html():b),c&&c()});return this},a.param=function(b,c){var d=[],e="",f=function(a,b){c?d[d.length]=encodeURIComponent(c+"["+a+"]")+"="+encodeURIComponent(b):d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};for(var g in b)b[g]instanceof Array||b[g]instanceof Object?e+=(d.length+e.length>0?"&":"")+a.param(b[g],c?c+"["+g+"]":g):f(b instanceof Array?"":g,b[g]);return d.join("&").replace(/%20/g,"+")+e}}(Zepto),function(a){var b=[],c;a.fn.remove=function(){return this.each(function(){this.tagName=="IMG"&&(b.push(this),this.src="data:image/gif;base64,R0lGODlhAQABAAAAADs=",c&&clearTimeout(c),c=setTimeout(function(){b=[]},6e4)),this.parentNode.removeChild(this)})}}(Zepto)
+ lib/layout.css view
@@ -0,0 +1,58 @@+/*+* Skeleton V1.2+* Copyright 2011, Dave Gamache+* www.getskeleton.com+* Free to use under the MIT license.+* http://www.opensource.org/licenses/mit-license.php+* 6/20/2012+*/++/* Table of Content+==================================================+ #Site Styles+ #Page Styles+ #Media Queries+ #Font-Face */++/* #Site Styles+================================================== */++/* #Page Styles+================================================== */++/* #Media Queries+================================================== */++ /* Smaller than standard 960 (devices and browsers) */+ @media only screen and (max-width: 959px) {}++ /* Tablet Portrait size to standard 960 (devices and browsers) */+ @media only screen and (min-width: 768px) and (max-width: 959px) {}++ /* All Mobile Sizes (devices and browser) */+ @media only screen and (max-width: 767px) {}++ /* Mobile Landscape Size to Tablet Portrait (devices and browsers) */+ @media only screen and (min-width: 480px) and (max-width: 767px) {}++ /* Mobile Portrait Size to Mobile Landscape Size (devices and browsers) */+ @media only screen and (max-width: 479px) {}+++/* #Font-Face+================================================== */+/* This is the proper syntax for an @font-face file+ Just create a "fonts" folder at the root,+ copy your FontName into code below and remove+ comment brackets */++/* @font-face {+ font-family: 'FontName';+ src: url('../fonts/FontName.eot');+ src: url('../fonts/FontName.eot?iefix') format('eot'),+ url('../fonts/FontName.woff') format('woff'),+ url('../fonts/FontName.ttf') format('truetype'),+ url('../fonts/FontName.svg#webfontZam02nTh') format('svg');+ font-weight: normal;+ font-style: normal; }+*/
+ lib/skeleton.css view
@@ -0,0 +1,242 @@+/*+* Skeleton V1.2+* Copyright 2011, Dave Gamache+* www.getskeleton.com+* Free to use under the MIT license.+* http://www.opensource.org/licenses/mit-license.php+* 6/20/2012+*/+++/* Table of Contents+==================================================+ #Base 960 Grid+ #Tablet (Portrait)+ #Mobile (Portrait)+ #Mobile (Landscape)+ #Clearing */++++/* #Base 960 Grid+================================================== */++ .container { position: relative; width: 960px; margin: 0 auto; padding: 0; }+ .container .column,+ .container .columns { float: left; display: inline; margin-left: 10px; margin-right: 10px; }+ .row { margin-bottom: 20px; }++ /* Nested Column Classes */+ .column.alpha, .columns.alpha { margin-left: 0; }+ .column.omega, .columns.omega { margin-right: 0; }++ /* Base Grid */+ .container .one.column,+ .container .one.columns { width: 40px; }+ .container .two.columns { width: 100px; }+ .container .three.columns { width: 160px; }+ .container .four.columns { width: 220px; }+ .container .five.columns { width: 280px; }+ .container .six.columns { width: 340px; }+ .container .seven.columns { width: 400px; }+ .container .eight.columns { width: 460px; }+ .container .nine.columns { width: 520px; }+ .container .ten.columns { width: 580px; }+ .container .eleven.columns { width: 640px; }+ .container .twelve.columns { width: 700px; }+ .container .thirteen.columns { width: 760px; }+ .container .fourteen.columns { width: 820px; }+ .container .fifteen.columns { width: 880px; }+ .container .sixteen.columns { width: 940px; }++ .container .one-third.column { width: 300px; }+ .container .two-thirds.column { width: 620px; }++ /* Offsets */+ .container .offset-by-one { padding-left: 60px; }+ .container .offset-by-two { padding-left: 120px; }+ .container .offset-by-three { padding-left: 180px; }+ .container .offset-by-four { padding-left: 240px; }+ .container .offset-by-five { padding-left: 300px; }+ .container .offset-by-six { padding-left: 360px; }+ .container .offset-by-seven { padding-left: 420px; }+ .container .offset-by-eight { padding-left: 480px; }+ .container .offset-by-nine { padding-left: 540px; }+ .container .offset-by-ten { padding-left: 600px; }+ .container .offset-by-eleven { padding-left: 660px; }+ .container .offset-by-twelve { padding-left: 720px; }+ .container .offset-by-thirteen { padding-left: 780px; }+ .container .offset-by-fourteen { padding-left: 840px; }+ .container .offset-by-fifteen { padding-left: 900px; }++++/* #Tablet (Portrait)+================================================== */++ /* Note: Design for a width of 768px */++ @media only screen and (min-width: 768px) and (max-width: 959px) {+ .container { width: 768px; }+ .container .column,+ .container .columns { margin-left: 10px; margin-right: 10px; }+ .column.alpha, .columns.alpha { margin-left: 0; margin-right: 10px; }+ .column.omega, .columns.omega { margin-right: 0; margin-left: 10px; }+ .alpha.omega { margin-left: 0; margin-right: 0; }++ .container .one.column,+ .container .one.columns { width: 28px; }+ .container .two.columns { width: 76px; }+ .container .three.columns { width: 124px; }+ .container .four.columns { width: 172px; }+ .container .five.columns { width: 220px; }+ .container .six.columns { width: 268px; }+ .container .seven.columns { width: 316px; }+ .container .eight.columns { width: 364px; }+ .container .nine.columns { width: 412px; }+ .container .ten.columns { width: 460px; }+ .container .eleven.columns { width: 508px; }+ .container .twelve.columns { width: 556px; }+ .container .thirteen.columns { width: 604px; }+ .container .fourteen.columns { width: 652px; }+ .container .fifteen.columns { width: 700px; }+ .container .sixteen.columns { width: 748px; }++ .container .one-third.column { width: 236px; }+ .container .two-thirds.column { width: 492px; }++ /* Offsets */+ .container .offset-by-one { padding-left: 48px; }+ .container .offset-by-two { padding-left: 96px; }+ .container .offset-by-three { padding-left: 144px; }+ .container .offset-by-four { padding-left: 192px; }+ .container .offset-by-five { padding-left: 240px; }+ .container .offset-by-six { padding-left: 288px; }+ .container .offset-by-seven { padding-left: 336px; }+ .container .offset-by-eight { padding-left: 384px; }+ .container .offset-by-nine { padding-left: 432px; }+ .container .offset-by-ten { padding-left: 480px; }+ .container .offset-by-eleven { padding-left: 528px; }+ .container .offset-by-twelve { padding-left: 576px; }+ .container .offset-by-thirteen { padding-left: 624px; }+ .container .offset-by-fourteen { padding-left: 672px; }+ .container .offset-by-fifteen { padding-left: 720px; }+ }+++/* #Mobile (Portrait)+================================================== */++ /* Note: Design for a width of 320px */++ @media only screen and (max-width: 767px) {+ .container { width: 300px; }+ .container .columns,+ .container .column { margin: 0; }++ .container .one.column,+ .container .one.columns,+ .container .two.columns,+ .container .three.columns,+ .container .four.columns,+ .container .five.columns,+ .container .six.columns,+ .container .seven.columns,+ .container .eight.columns,+ .container .nine.columns,+ .container .ten.columns,+ .container .eleven.columns,+ .container .twelve.columns,+ .container .thirteen.columns,+ .container .fourteen.columns,+ .container .fifteen.columns,+ .container .sixteen.columns,+ .container .one-third.column,+ .container .two-thirds.column { width: 300px; }++ /* Offsets */+ .container .offset-by-one,+ .container .offset-by-two,+ .container .offset-by-three,+ .container .offset-by-four,+ .container .offset-by-five,+ .container .offset-by-six,+ .container .offset-by-seven,+ .container .offset-by-eight,+ .container .offset-by-nine,+ .container .offset-by-ten,+ .container .offset-by-eleven,+ .container .offset-by-twelve,+ .container .offset-by-thirteen,+ .container .offset-by-fourteen,+ .container .offset-by-fifteen { padding-left: 0; }++ }+++/* #Mobile (Landscape)+================================================== */++ /* Note: Design for a width of 480px */++ @media only screen and (min-width: 480px) and (max-width: 767px) {+ .container { width: 420px; }+ .container .columns,+ .container .column { margin: 0; }++ .container .one.column,+ .container .one.columns,+ .container .two.columns,+ .container .three.columns,+ .container .four.columns,+ .container .five.columns,+ .container .six.columns,+ .container .seven.columns,+ .container .eight.columns,+ .container .nine.columns,+ .container .ten.columns,+ .container .eleven.columns,+ .container .twelve.columns,+ .container .thirteen.columns,+ .container .fourteen.columns,+ .container .fifteen.columns,+ .container .sixteen.columns,+ .container .one-third.column,+ .container .two-thirds.column { width: 420px; }+ }+++/* #Clearing+================================================== */++ /* Self Clearing Goodness */+ .container:after { content: "\0020"; display: block; height: 0; clear: both; visibility: hidden; }++ /* Use clearfix class on parent to clear nested columns,+ or wrap each row of columns in a <div class="row"> */+ .clearfix:before,+ .clearfix:after,+ .row:before,+ .row:after {+ content: '\0020';+ display: block;+ overflow: hidden;+ visibility: hidden;+ width: 0;+ height: 0; }+ .row:after,+ .clearfix:after {+ clear: both; }+ .row,+ .clearfix {+ zoom: 1; }++ /* You can also use a <br class="clear" /> to clear columns */+ .clear {+ clear: both;+ display: block;+ overflow: hidden;+ visibility: hidden;+ width: 0;+ height: 0;+ }
+ src/formal/bug.formal view
@@ -0,0 +1,13 @@+++module tests++ module testb+ Option a = {some: a} | {none}+ + + option {none} x = x+ option {some: x} _ = x+ + +
+ src/formal/bugb.formal view
@@ -0,0 +1,19 @@++ + +module other++ open tests.testb++ (<*>): Parser (a -> b) -> Parser a -> Parser b+ (<*>) {parser = fp} {parser = p} =++ { parser s = ++ var pick _ {none} = {none}+ pick f {some: {rest: ss, parsed: x}} =+ {some: {rest: ss, parsed: f x}}++ -- var {some: y} = pick id <| fp s ++ {none}}
+ src/formal/formalz.formal view
@@ -0,0 +1,88 @@++ -- FormalZ+ -- -------+ -- Demonstration of some classic FP data structures.++ module formalz++ -- TODO interface should declare a partially implemented module,+ -- parameterized by a single type varialbe of any kind.++ -- TODO `=` syntax allows for same line, single def intreface++ interface functor f = map: f a -> (a -> b) -> f b ++ -- TODO parameterized implementations must share the exact+ -- namespace of the interface - eg, in another module, this would+ -- would be `module formalz.functor List`++ module functor List = map = list.map++ interface monad m++ (>>=): m a -> (a -> m b) -> m b+ return: a -> m a++ interface monad.run m++ -- TODO interfaces can open modules also, which act in the type system+ -- as constraints. The constraints themselves are not expressable in a+ -- type signature - the fact that mond.extras only works on `m` when + -- there is a `module monad m` somewhere in existence. Error + -- messages will need to show the dependency stack. I have a+ -- philosophical justification for this.++ -- TODO `import` should work like `open`, but also create aliases.++ open monad m++ run: m a -> a+ + module monad List++ (>>=) x g = concat_map g x+ return x = [:x]++ (1..3 >>= λx = [: x, x + 1, x + 2 ]) == [:1,2,3,2,3,4,3,4,5]++ -- TODO allow joining of interface definitions with `&` for clarity++ module monad JS & monad.extras JS++ -- TODO inline definitions - maybe should have decorator+ -- syntax for this?+ + inline (>>=) x f = x >>= f+ return x = return x++ run f = `undefined` -- Note: beacuse `do!` is implemented in terms of run,+ -- there is no way to actually write this function.++++ -- TODO allow invisible modules like this maybe?++ module _++ -- *TODO* allow local module open `let open monad List`, or force sig++ -- TODO allow private modules++ private module utils+ + open formalz.monad List++ [:1,2,3,2,3,4,3,4,5] ==++ do x <- [:1, 2, 3]+ [:x, x + 1, x + 2]++ -- TODO private definitions (only needs to be implemented in type checker)++ private zzz = 1++ -- TODO tail call elimination++ -- TODO `in` keyword for same line let expressions?++ let f x = if x > 0 then f (x - 1) else true in f 50000
+ src/formal/parsec.formal view
@@ -0,0 +1,172 @@+++module parsec++ open prelude+ open prelude.option+ open prelude.string+ open prelude.html++ ++ Parser a = {parser: String -> {rest: String, parsed: Option a}}++++ inline run_parser:+ -- Runs a parser over a text argument and throws away the leftover text.+ + Parser p -> String -> Option p + | {parser = p} x = p x |> λ {parsed = {some = y}, _} = {some = y} + | _ = {none}+ + + + inline (<$>):+ -- Applies a function to the parse result, only if the parse was+ -- successful.+ + (a -> b) -> Parser a -> Parser b+ f <$> {parser = z} =++ { parser s =+ z s |> λ {parsed = {some: x}, rest = ss} =+ {parsed = {some = f x}, rest = ss}+ | {parsed = {none}, rest = x} =+ {parsed = {none}, rest = x} }++++ inline (<*>):+ -- Allows functions that take multiple arguments to be applied+ -- sequentially to a sequence of parsed values.+ + Parser (a -> b) -> Parser a -> Parser b+ {parser = fp} <*> {parser = p} =++ { parser s = + fp s |> λ {parsed = {some: f}, rest = rr} =+ p rr |> λ {parsed = {some = x}, rest = z} =+ {parsed = {some = f x}, rest = z}+ | {parsed = {none}, rest = x} =+ {parsed = {none}, rest = x}+ | {parsed: {none}, rest: x} =+ {parsed: {none}, rest: x} }++++++ private inline lift(g, {parser: f}) =+ { parser text =+ let f' = f text+ in g { text: text+ f: f+ parsed: f'.parsed+ rest: f'.rest+ f': f' }}++ inline (*>):+ -- Applies two parsers in sequence, throwing out the result+ -- of the first.+ + Parser a -> Parser b -> Parser b+ {parser = f} *> {parser = g} =++ { parser s =+ f s |> λ {parsed = {some = x}, rest = zz} = g zz+ | {parsed = {none}, rest = x} =+ {parsed = {none}, rest = x} }+ +++ inline (<|>):+ -- Alternative will try the first parser, and applies the second only if+ -- the first fails *and* consumes no input from the text.+ + Parser a -> Parser a -> Parser a+ {parser = f} <|> {parser = g} =++ let h text {parsed = {none}, rest = textt} when text == textt =+ g text+ | _ x = x++ in {parser text = h text (f text)}++++ inline try':+ -- Tries to apply a parser, but restores the parser state in the case+ -- of a failure. This is useful with combinators that check the+ -- state of the consumed text, like `<|>`++ Parser a -> Parser a+ = lift λ (x & {_, parsed: {none}}) =+ {parsed: {none}, rest: x.text}+ | x = x.f'++++ inline string:+ -- A parser that matches a string. Unlike Haskell's Parsec library,+ -- parsec.formal will not consume any input if the entire string+ -- doesn't match. This is for efficiency reasons currently, but+ -- may change in the future.+ + String -> Parser String + | x = { parser y = + let sub = do! `y.substring(0, x.length)`+ if (sub == x) + { rest = do! `y.substring(x.length)`+ parsed = {some = x} }+ else {rest = y, parsed = {none}} }+ + + + inline push! : x -> Array x -> Array x+ | x xs = do! `xs.unshift(x); xs`++ many:+ -- Applies a parser repeatedly, until parsing fails. ++ Parser a -> Parser (Array a)+ = lift λ (x & {_, parsed: {none}}) =+ {parsed: {some: []}, rest = x.rest}+ | (y & {_, parsed: {some: x}}) =+ (push! x <$> many {parser: y.f}).parser y.rest+ + ++ module "Testing"++ {some = "ten"} == run_parser (string "ten") "tens"+ {some = "tenten"} == run_parser ((λx = x +++ x) <$> string "ten") "tenfingers"++ {parsed = {some = "tenten"}, rest = "fingers"} + == ((λx = x +++ x) <$> string "ten").parser "tenfingers"++ var result = run_parser ((λx y = y +++ x) <$> string "ten" <*> string "fingers") "tenfingers"+ result == {some: "fingersten"}+ + var result = run_parser (string "ten" <|> string "eleven") "eleven"+ result == {some: "eleven"}++ var result = run_parser (string "ten" *> string "fingers") "tenfingers"+ result == {some: "fingers"}++ var parser = (string "ten" *> string "fingers") <|> string "tentoes"+ result = run_parser parser "tentoes"+ result == {none}++ var parser = try' (string "ten" *> string "fingers") <|> string "tentoes"+ result = run_parser parser "tentoes"+ result == {some: "tentoes"}+ + var parser = many (string "ten")+ result = run_parser parser "tententententen"+ result == {some: ["ten", "ten", "ten", "ten", "ten"]}++ + + +
+ src/formal/prelude.formal view
@@ -0,0 +1,802 @@++-- If you are familiar with Haskell or ML, the prelude may serve as a +-- good introduction to formal.+-- Formal's syntax is quite liberal; to illustrate, the prelude will +-- maintain an intentionally inconsistent style throughout.++-- First, we need to create a namespace with the `module` keyword.++module prelude+++ JS a = {} -> a++ inline object? x = do! `typeof x === "object"`+ inline array? = do! `is_array`+ inline string? x = do! `typeof x === "string"`++ inline+ num? x = do! `typeof x == "number"`+++ inline type? x = do! `typeof x`++ inline+ not: Bool -> Bool + not x = do! `!x`+ not false+ ++ object? {}+ array? []+ not (array? {})+ not (object? 0)++++ -- Side effects can only happen in Javascript, so we use a monadic container to+ -- compose these bits.++ inline + (>>=): JS a -> (a -> JS b) -> JS b+ (>>=) x y = y (run x)++ inline + (>>): JS a -> JS b -> JS b+ (>>) x y = `run x; return (run y)`++ inline return:++ a -> JS a+ return x = `x`++ + do! x <- `1 + 4`+ y <- `2 + 3`+ ans <- `x + y`+ return (10 == ans)++ 5 == do! return 5+ 10 == do! `5 + 5`++++ inline log: a -> JS {} + | x = `console.log(x)`++ -- Testing to verify that escaping Javascript & utilizing escaped+ -- Javascript with `do` sugar and composition in general works as+ -- expected.++ var x = 0+ y = do z <- `x = 1`+ return z+ x == 0+++ -- Numbers+ -- -------+ -- Some basic aliases to native javascript infix functions. These are type+ -- annotated to constrain inferrence - otherwise, these functions would all be+ -- inferred as `a -> b -> c`.++ inline (&&): Bool -> Bool -> Bool | x y = do! `x && y`+ inline (||): Bool -> Bool -> Bool | x y = do! `x || y`+ inline (*): Num -> Num -> Num | x y = do! `x * y`+ inline (/): Num -> Num -> Num | x y = do! `x / y`+ inline (%): Num -> Num -> Num | x y = do! `x % y`+ inline (+): Num -> Num -> Num | x y = do! `x + y`+ inline (-): Num -> Num -> Num | x y = do! `x - y`+ inline (<=): Num -> Num -> Bool | x y = do! `x <= y`+ inline (>=): Num -> Num -> Bool | x y = do! `x >= y`+ inline (<): Num -> Num -> Bool | x y = do! `x < y`+ inline (>): Num -> Num -> Bool | x y = do! `x > y`++ -- Equality is overloaded to match records and arrays. By constraining the type of+ -- this operator, we need only dispatch on the type of the first element,+ -- constraining ++ inline x != y = not (x is y)++ inline x /= y = not (x == y)++ (==): a -> a -> Bool+ | x y when do! `x === y` = true+ | x y when object? x =+ do! `var result = true;+ for (key in x) {+ result = result && y.hasOwnProperty(key) && _eq_eq(x[key])(y[key]);+ };++ var z = Object.keys(x).length + === Object.keys(y).length;++ result && z`+ + | x y when array? x =+ do! `var result = true;+ for (z in x) {+ result = result && _eq_eq(x[z])(y[z]);+ };++ result && x.length == y.length`++ | x y = false++ -- And a few simple tests to verify the correctness of these+ -- implementations. This is not meant to be exhaustive, only a smoke+ -- test against regressions.++ (3 * 4) + 5 * 4 == 64 / 2+ 4 - 1 != 5 - 10+ (10 >= 5 + 5) != (4 + 5 <= 10 - 2)+ ({test: 1} == {test: 1}) == true+ ({test: 1} != {test: 1}) == false++ -- Fibonacci function++ fib 0 = 0 | 1 = 1 | n = fib(n - 1) + fib(n - 2)++ -- Speed+ -- -----++ -- Due to the nested recursion, `fib` is an excellent function for testing the+ -- runtime speed versus raw javascript. `fast_fib` is a trivial javascript+ -- implementation of the same function, recursed itself to remove any potential+ -- overhead from formal's dispatch mechanism.++ module speedtest++ private inline get_time = `new Date().getTime()`++ time js =++ do start <- get_time+ js+ stop <- get_time+ return (stop - start)++ private inline+ fast_fib =++ do! `var f = function(n) {+ return 0 === n ? 0 : 1 === n ? 1 : f(n - 1) + f(n - 2)+ }; f`+ + fast_fib 7 == fib 7+ + -- With this, we can set up a simple canary to let us know if the prelude is+ -- suddenly dramatically slower than it previously was; in this case, we fail a test+ -- if the formal version isn't at least 90% as fast as the native javascript+ -- version.++ floor: Num -> Num = do! `Math.floor`++ do! fast_time <- time yield fast_fib 30+ slow_time <- time yield fib 30+ return (floor (fast_time / slow_time * 100) >= 80)++ -- Function Combinators+ -- --------------------+ -- Simple left & right pipes, ala F#. ++ inline x <| y = x y+ inline x |> y = y x+ + 3 |> (λy = y + 1) |> λy = y + 1 == 5+ (λy x z = x + y + z + 1) 1 <| 3 <| 4 == 9+ + -- Alternatively, there is a right associative version of `<|`, ala+ -- haskell. All operators which end with a `:` are right associative.++ inline x <: y = x y+ + (λx = x - 3) <: (λx = x - 3) <: 5 + 5 == 4+ + -- Function composition++ inline x .: y = λz = x y(z)+ inline id x = x+ inline flip(f) x y = f(y, x)++ inline x ' y = y x++ + ((λx = x + 1) .: (λx = x * 2) .: λx = x - 3) 4 == 3+ id [1, 2, 3] == [1, 2, 3]+ flip (λx y = x - y) 3 5 == 2++++ -- Strings+ -- -------++ module string+ + inline + lstrip: String -> String+ lstrip x = do! `x.replace(/^\s+/, '')` + + inline rstrip: String -> String | x = do! `x.replace(/\s+$/, '')` + inline strip: String -> String | = lstrip .: rstrip++ length: String -> Num | n = do! `n.length`++ inline + (+++): a -> b -> String+ x +++ y = do! `"" + x + y`++ strip " test " is "test"++ -- interpolated strings++ let x = "test"+ in "hello `x`" is "hello test"++ open string++ -- Tests+ -- -----+ -- By invoking javascript, we can listen for exceptions.+ + err x = do! `try {+ x();+ return false;+ } catch (e) {+ return e;+ }`++ -- Option+ -- ------++ module option+ + Option a = {some: a} | {none}+ + option b {none} = b+ | _ {some: x} = x+ + option 3 {some: 2} == 2++ module html++ HTML = { element: a+ inner: JS String+ on_click: JS {} -> JS {}+ set: b -> JS {}+ add_class: String -> JS {}+ add_style: String -> String -> JS {} }++ get:+ String -> JS HTML+ | x = do el <- `$(x).get(0)`++ return { element = el+ inner = `el.innerHTML`+ on_click y = `el.onclick = y`+ set y = `el.innerHTML = y`++ add_class y =+ `el.setAttribute("class", el.getAttribute("class") + " " + y)`++ add_style y z = `el.style[y] = z` }++ inline ($=):++ String -> a -> JS {}+ x $= y =++ `if (typeof $ != "undefined") {+ var xx = $(x).get(0);+ if (typeof xx != "undefined") {+ xx.innerHTML = y;+ }+ }`++ inline ($|): ++ String -> String -> String -> JS {}+ selector $| rule value = `$(selector).css(rule, value)`++ inline + ($.): String -> String -> JS {}+ ($.) x y = `$(x).addClass(y)`++ inline ($+): String -> String -> JS {}+ | x y = `$(x).append(y)`++ div: String -> JS String+ | x = yield "<div id='`x`'/>"++ move: HTML -> HTML -> JS a+ | x y = `$(y.element).append($(x.element).detach())`+ + on_load: JS {} -> JS {}+ | x = `window.addEventListener("load", x, false)`++ inline stringify: a -> String | x = do! `JSON.stringify(x)`++ inline (!!): Array a -> Num -> a | x y = do! `x[y]`++ with_page: JS<a> -> JS<a>+ | x = do old <- `$("body").clone()`+ xx <- x+ `$("body").replaceWith(old)`+ return xx++ -- do! with_page do "body" $= "Test"+ -- text <- get "body"+ -- text <- text.inner+ -- return (text == "Test")++ do! d <- div "test1"++ "body" $+ d+ "#test1" $= "I am a test!"++ text <- get "#test1"+ text <- text.inner++ "#test1" $= ""++ return (text == "I am a test!")++ inline split: String -> String -> Array String | y x = do! `x.split(y)`+++ -- This is the initializer for prelude's console test suite. ++ console_runner: JS {} =++ var is_error = 0++ var get_line x = x |> split "__::__"+ |> \x = x !! 0+ |> split "_" + |> \x = x !! 0+ |> \x = do! `parseInt x`+ |> \x = x + 1+ |> stringify++ var report_failed spec results =++ let items = spec.results_.items_+ desc = spec.description.split "__::__" !! 1+ exp = stringify (items !! 0).expected+ act = stringify (items !! 0).actual+ line = get_line spec.description+ + do if is_error == 0+ then log "\r " + else return {}++ `is_error = 1`++ log "Test failed at line `line`++ `desc`+ + Expected `exp`+ Actual `act`"++ log ""++ var report spec = ++ do! results <- `spec.results()`+ passed <- `results.passed()`++ if passed + then return {}+ else report_failed spec results++ var reporter = { reportSpecResults: report + reportRunnerResults: `phantom.exit(is_error)` }++ do env <- `jasmine.getEnv()`++ `env.addReporter(reporter)`+ `env.execute()`+++ push : a -> Array a -> JS (Array a)+ push xs x = `xs.push(x)` ++ private console_reporter = {++ total = 0+ failed = 0++ messages = []++ reportSpecResults spec =++ do! results <- `spec.results()`+ passed <- `results.passed()`+ `console_reporter.total++`++ if not passed then do+ `console_reporter.failed++`+ push console_reporter.messages spec.description+ return {}+ else return {}++ reportRunnerResults =++ do if console_reporter.failed > 0+ log console_reporter.messages+ else + return {}+ + log "`console_reporter.total - console_reporter.failed`/`console_reporter.total` tests passed"+ }++ -- This is the initializer for prelude's HTML test suite. ++ table_of_contents =++ do "code" $. "prettyprint"+ "code" $. "lang-hs"++ ".test" $| "position" <| "relative"+ ".test" $| "left" <| "50px"++ `prettyPrint()`++ trivial <- `new jasmine.TrivialReporter()`+ formal <- `new jasmine.FormalReporter()`+ env <- `jasmine.getEnv()`++ `env.addReporter trivial`+ `env.addReporter formal`+ `env.addReporter console_reporter`++ `env.execute()`++ reporter <- get ".jasmine_reporter"+ body <- get "#test_suite"++ move reporter body+++ + -- Lists+ -- -----+ -- A simple implementation of a library for manipulating linked lists.++ module list+ + List a = { head: a, tail: List a } + | { nil }+ + -- This complex type can be hidden behind a constructor function which+ -- works more like a traditional cons.++ inline + x :: y = { head = x, tail = y }++ -- The compiler itself also supports the list sugar `[: 1, 2, 3 ]` (or+ -- `[: 1, 2, 3 :]`, if you prefer symmetry). All of these lists are+ -- synonyms.++ var xs = [:++ [:1,2,3]++ [:1,2,3:]++ (1::2::3::{nil})++ { head = 1+ tail = { head = 2+ tail = { head = 3+ tail = {nil} }}}+ ]++ all? (λy = [:1,2,3] == y) xs + ++ -- Simple implementations of list accessors, which illustrate+ -- incomplete definition.++ empty? { nil } = true | _ = false++ head { head: x, tail: _ } = x+ | { nil } = error "Head called on empty list"+ + tail { head: _, tail: x } = x + | { nil } = error "Tail called on empty list"++ last { head: x, tail: { nil } } = x+ last { head: _, tail: x } = last x+ last { nil } = error "Last called on empty list"++ take 0 x = { nil } | n x = head x :: take (n - 1) (tail x)+ drop 0 x = x | n x = drop (n - 1) (tail x)++ x .. y = + let f xx z when xx >= x = f (xx - 1) (xx :: z)+ f _ z = z ++ f y {nil}+ + 1 .. 5 == [:1,2,3,4,5]++ -- Project Euler problem 1, modified to protect the innocent:++ 288045 == 1 .. 1111 |> filter (λx = x % 3 == 0 || x % 5 == 0) |> sum+++ take_while f { nil } = { nil }+ | f x when f (head x) = head x :: filter f (tail x)+ | _ _ = { nil }++ drop_while f { nil } = { nil }+ | f x when f (head x) = drop_while f (tail x)+ | _ x = x++ not (empty? (1 :: {nil}))+ empty? [:]+ + head [: 1, 2 ] is 1+ tail [: 1, 2 ] is [:2]+ last [: 1, 2 ] is 2++ err (lazy head {nil}) is "Head called on empty list"+ err (lazy tail {nil}) is "Tail called on empty list"+ err (lazy last {nil}) is "Last called on empty list"++ take(2, [: 1, 2, 3 ]) == [: 1, 2 ]+ drop(2, [: 1, 2, 3 ]) == [: 3 ]++ take_while (λx = x < 0) [:] == [:]+ take_while (λx = x > 0) [: 2, 1, 0 ] == [: 2, 1 ]++ drop_while (λx = x < 0) {nil} == {nil}+ drop_while (λx = x > 0) [: 2, 1, 0 ] == [: 0 ]++ -- Cardinality+ + length ++ | {nil} = 0+ | {head: _, tail: x} = 1 + length x+ + length [: 1, 2, 3, 4 ] == 4++ -- Generators++ init 0 _ = {nil}+ | n x = x :: init (n - 1) x+ + length (init 30 0) == 30+ tail (init 3 0) == init 2 0++ -- List concatenation++ (++)++ | {nil} y = y+ | {head: y, tail: ys} xs = y :: (ys ++ xs)++ {nil} ++ (1 :: 2 :: {nil}) == 1 :: 2 :: {nil}+ [: 1, 2 ] ++ [: 3, 4 ] == [: 1, 2, 3, 4 ]+ + -- Filter.++ filter: (a -> Bool) -> List a -> List a+ | f {nil} = {nil}+ | f x when f (head x) = head x :: filter f (tail x)+ | f x = filter f <| tail x+ + [: 1, 2, 3, 4 ] 'filter (λx = x > 2) == [: 3, 4 ]++ -- Map+ + map(f, {nil}) = {nil}+ map(f, x) = f(head(x)) :: map(f, tail(x))+ + [: 2, 3, 4 ] == [: 1, 2, 3 ] |> map λx = x + 1+ + -- Reverse++ reverse y = + let r rest [:] = rest+ r rest { head: x, tail: xs } = + r (x :: rest) xs++ in r {nil} y++ reverse [: 1, 2, 3, 4 ] == [: 4, 3, 2, 1 ]++ var test_x = [: 1, 2, 3, 4 ]+ test_x == reverse <| reverse test_x++ take' x y =+ let t(0, _, acc) = acc+ t(n, x, acc) = t(n - 1, tail x, head x :: acc)++ in reverse t(x, y, {nil})++ var x = [: 1, 2, 3, 4, 5, 6, 7, 8 ]+ take 5 x == take' 5 x++ -- Folds++ foldl f x xs =+ var g y {nil} = y+ | y { head: z, tail: zs } = g (f y z) zs+ g x xs++ foldl1 _ {nil} = error "Foldl1 called on empty list"+ | f x = foldl f (head x) (tail x)+ + foldr f x =+ var g {nil} = x+ g { head: y, tail: ys } = f y (g ys)+ g++ foldr1 _ {nil} = error "Foldr1 called on empty list"+ | f x = foldr f (head x) (tail x)+ + all? f = foldl1 (λx y = x && y) .: map f+ any? f = foldl1 (λx y = x || y) .: map f++ sum = foldl1 λ(x, y) = x + y+ product = foldl1 λ(x, y) = x * y+ + concat = foldl1 λx y = x ++ y+ concat_map f xs = concat (map f xs)+ + maximum = foldl1 λ(x, y) when x > y = x+ |(_, y) = y++ minimum = foldl1 λx y = if x > y then y else x++ foldl (λx y = x + y) 0 [: 1, 2, 3, 4 ] == 10+ foldr (λx y = x + y) 0 [: 1, 2, 3, 4 ] == 10+ all? id [:true,true]+ not (all? id [:true,false])+ any? id [:true,false]+ not (any? id [:false,false])+ sum [:1,2,3] == 6+ product [:1,2,4] == 8++ let x = [:1,2], y = [:3,4]+ concat [:x,y] == [:1,2,3,4]++ concat_map (λx = [:x,x+1]) [:1,2] == [:1,2,2,3]+ + minimum [: 1, 2, 3 ] == 1+ maximum [: 1, 2, 3 ] == 3+ ++ -- Sequences+ -- ---------+ -- Sequences are an abstract data type which resembles a list, except that elements+ -- Sequences may be infinite, as long as you never try to read every element.+ -- However, the current implementation is stack-consuming and thus limited by the+ -- underlying javascript runtime [TODO]. ++ module seq++ open list+ open speedtest+ open html+ + Seq a = { seq: JS { elem: a, next: Seq a}}+ | { end }++ inline seq x = {seq: x}+ + iterate f x = seq yield { elem: x, next: iterate f (f x) }++ from_list {nil} = {end}+ | { head: x, tail: xs } =+ { seq: yield { elem: x, next: from_list xs }}+ + to_list { end } = {nil}+ | { seq: x } = do! { elem: y, next: ys } <- x+ return (y :: to_list ys)++ take _ {end} = {end}+ | 0 _ = {end}+ | x { seq: y } = seq do { elem: z, next: zs } <- y+ return { elem: z, next: take (x - 1) zs }++ to_list (from_list [:1,2]) == [:1,2]+ iterate (λx = x + 1) 0 |> take 100 |> to_list |> length == 100++ zip_with:+ + (a -> b -> c) -> Seq a -> Seq b -> Seq c+ | _ {end} _____ = {end}+ | _ _____ {end} = {end}+ | f {seq: a} {seq: b} = seq do++ { elem: xx, next: xs } <- a+ { elem: yy, next: ys } <- b++ return { elem: f xx yy, next: zip_with f xs ys }+ + inline x ::: y = seq yield { elem: x, next: do! y }+ + tail:+ Seq a -> Seq a+ | {end} = error "tail called on empty seq"+ | {seq: t} = do! t >>= λx = return x.next+ + to_lazy+ | {end} = {end}+ | {seq: y} = seq lazy do!+ {elem: x, next: xs} <- y+ return {elem: x, next: to_lazy xs}+ + -- Infinite sequence example+ + fibs = to_lazy <: 1 ::: return <: 1 ::: yield zip_with (λx y = x + y) fibs <: tail fibs+ + -- Since the `lazy` keyword memoizes it's argument, this fibonacci implementation+ -- is ridiculously faster than the recursive version. For example, the runtime+ -- speed of this fib implementation compared to the native recursive one is <span+ -- id="speedtest">__________</span>%.++ do! fast_time <- time yield fast_fib 30+ slow_time <- time yield fibs |> take 30 |> to_list |> last+ let ratio = floor (fast_time / slow_time * 100)+ "#speedtest" $= ratio+ return (ratio >= 2)++ fibs |> take 5 |> to_list == [:1,1,2,3,5]++ fast_fib 15 == fibs |> take 15+ |> to_list+ |> last+++ -- FormalZ+ -- -------+ -- Demonstration of some classic FP data structures. This form of polymorphism can+ -- be simulated in Formal the same way they are implemented in Haskell - as a function+ -- dictionary, the only difference being that you must explicitly bind the dictionary+ -- instance to a symbol (as opposed to it being referenced by the type variable's+ -- instantiation).++ module "Formal Z"++ open list++ Functor f =++ { map: (a -> b) -> f a -> f b }++ Monad m =++ { (>>=): m a -> (a -> m b) -> m b+ ret: a -> m a }++ map z x f = z.map f x++ bind { ret: f, _ } x = f x++ list_functor =++ { map _ {nil} = {nil} + | f { head: x, tail: xs } =+ { head: f x+ tail: list_functor.map f xs }}++ list_monad =++ { (>>=) x g = concat_map g x+ return x = [:x] }++ js_monad =++ { (>>=) x f = x >>= f+ return x = return x }++ let (>>>=) x g = concat_map g x+ z = 1 .. 3 >>>= λx = [:x, x + 1, x + 2]++ z == [:1,2,3,2,3,4,3,4,5]
+ src/formal/prelude.html view
@@ -0,0 +1,4474 @@+<!DOCTYPE html>+<!--[if lt IE 7 ]><html class="ie ie6" lang="en"> <![endif]-->+<!--[if IE 7 ]><html class="ie ie7" lang="en"> <![endif]-->+<!--[if IE 8 ]><html class="ie ie8" lang="en"> <![endif]-->+<!--[if (gte IE 9)|!(IE)]><!--><html lang="en"> <!--<![endif]-->+ <head>++ <!-- Basic Page Needs+ ================================================== -->+ <meta charset="utf-8">+ <meta name="description" content="">+ <meta name="author" content="">++ <!-- Mobile Specific Metas+ ================================================== -->+ <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">++ <!-- CSS+ ================================================== -->+ <link rel="stylesheet" href="lib/base.css">+ <link rel="stylesheet" href="lib/skeleton.css">+ <link rel="stylesheet" href="lib/layout.css">++ <link href='lib/js/prettify.css' type='text/css' rel='stylesheet' />+ <link href='lib/default.css' type='text/css' rel='stylesheet' />+ <link href='lib/js/jasmine-1.0.1/jasmine.css' type='text/css' rel='stylesheet' />++ <script type='text/javascript' src='lib/js/prettify.js'></script>+ <script type='text/javascript' src='lib/js/lang-hs.js'></script>+ <script type='text/javascript' src='lib/js/jquery.js'></script>+++ <!--[if lt IE 9]>+ <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>+ <![endif]-->++ <!-- Favicons+ ================================================== -->+ <link rel="shortcut icon" href="images/favicon.ico">+ <link rel="apple-touch-icon" href="images/apple-touch-icon.png">+ <link rel="apple-touch-icon" sizes="72x72" href="images/apple-touch-icon-72x72.png">+ <link rel="apple-touch-icon" sizes="114x114" href="images/apple-touch-icon-114x114.png">++ </head>+ <body>+ <div class="container">+ <div class="three columns sidebar">+ <nav>+ <h1>Formal</h1>+ A Programming Language+ </nav>+ + </div>+ <div class="twelve columns offset-by-one content">+<script>var jasmine={unimplementedMethod_:function(){throw Error("unimplemented method");}};jasmine.undefined=jasmine.___undefined___;jasmine.DEFAULT_UPDATE_INTERVAL=250;jasmine.DEFAULT_TIMEOUT_INTERVAL=5E3;jasmine.getGlobal=function(){return function(){return this}()};jasmine.bindOriginal_=function(a,b){var c=a[b];return c.apply?function(){return c.apply(a,arguments)}:jasmine.getGlobal()[b]};jasmine.setTimeout=jasmine.bindOriginal_(jasmine.getGlobal(),"setTimeout");+jasmine.clearTimeout=jasmine.bindOriginal_(jasmine.getGlobal(),"clearTimeout");jasmine.setInterval=jasmine.bindOriginal_(jasmine.getGlobal(),"setInterval");jasmine.clearInterval=jasmine.bindOriginal_(jasmine.getGlobal(),"clearInterval");jasmine.MessageResult=function(a){this.type="log";this.values=a;this.trace=Error()};+jasmine.MessageResult.prototype.toString=function(){for(var a="",b=0;b<this.values.length;b++)0<b&&(a+=" "),a=jasmine.isString_(this.values[b])?a+this.values[b]:a+jasmine.pp(this.values[b]);return a};jasmine.ExpectationResult=function(a){this.type="expect";this.matcherName=a.matcherName;this.passed_=a.passed;this.expected=a.expected;this.actual=a.actual;this.message=this.passed_?"Passed.":a.message;this.trace=this.passed_?"":Error(this.message)};jasmine.ExpectationResult.prototype.toString=function(){return this.message};+jasmine.ExpectationResult.prototype.passed=function(){return this.passed_};jasmine.getEnv=function(){return jasmine.currentEnv_=jasmine.currentEnv_||new jasmine.Env};jasmine.isArray_=function(a){return jasmine.isA_("Array",a)};jasmine.isString_=function(a){return jasmine.isA_("String",a)};jasmine.isNumber_=function(a){return jasmine.isA_("Number",a)};jasmine.isA_=function(a,b){return Object.prototype.toString.apply(b)==="[object "+a+"]"};+jasmine.pp=function(a){var b=new jasmine.StringPrettyPrinter;b.format(a);return b.string};jasmine.isDomNode=function(a){return 0<a.nodeType};jasmine.any=function(a){return new jasmine.Matchers.Any(a)};jasmine.Spy=function(a){this.identity=a||"unknown";this.isSpy=!0;this.plan=function(){};this.mostRecentCall={};this.argsForCall=[];this.calls=[]};jasmine.Spy.prototype.andCallThrough=function(){this.plan=this.originalValue;return this};+jasmine.Spy.prototype.andReturn=function(a){this.plan=function(){return a};return this};jasmine.Spy.prototype.andThrow=function(a){this.plan=function(){throw a;};return this};jasmine.Spy.prototype.andCallFake=function(a){this.plan=a;return this};jasmine.Spy.prototype.reset=function(){this.wasCalled=!1;this.callCount=0;this.argsForCall=[];this.calls=[];this.mostRecentCall={}};+jasmine.createSpy=function(a){var b=function(){b.wasCalled=!0;b.callCount++;var a=jasmine.util.argsToArray(arguments);b.mostRecentCall.object=this;b.mostRecentCall.args=a;b.argsForCall.push(a);b.calls.push({object:this,args:a});return b.plan.apply(this,arguments)},a=new jasmine.Spy(a),c;for(c in a)b[c]=a[c];b.reset();return b};jasmine.isSpy=function(a){return a&&a.isSpy};+jasmine.createSpyObj=function(a,b){if(!jasmine.isArray_(b)||0==b.length)throw Error("createSpyObj requires a non-empty array of method names to create spies for");for(var c={},d=0;d<b.length;d++)c[b[d]]=jasmine.createSpy(a+"."+b[d]);return c};jasmine.log=function(){var a=jasmine.getEnv().currentSpec;a.log.apply(a,arguments)};+var spyOn=function(a,b){return jasmine.getEnv().currentSpec.spyOn(a,b)},it=function(a,b){return jasmine.getEnv().it(a,b)},xit=function(a,b){return jasmine.getEnv().xit(a,b)},expect=function(a){return jasmine.getEnv().currentSpec.expect(a)},runs=function(a){jasmine.getEnv().currentSpec.runs(a)},waits=function(a){jasmine.getEnv().currentSpec.waits(a)},waitsFor=function(a,b,c){jasmine.getEnv().currentSpec.waitsFor.apply(jasmine.getEnv().currentSpec,arguments)},beforeEach=function(a){jasmine.getEnv().beforeEach(a)},+afterEach=function(a){jasmine.getEnv().afterEach(a)},describe=function(a,b){return jasmine.getEnv().describe(a,b)},xdescribe=function(a,b){return jasmine.getEnv().xdescribe(a,b)};+jasmine.XmlHttpRequest="undefined"==typeof XMLHttpRequest?function(){try{return new ActiveXObject("Msxml2.XMLHTTP.6.0")}catch(a){}try{return new ActiveXObject("Msxml2.XMLHTTP.3.0")}catch(b){}try{return new ActiveXObject("Msxml2.XMLHTTP")}catch(c){}try{return new ActiveXObject("Microsoft.XMLHTTP")}catch(d){}throw Error("This browser does not support XMLHttpRequest.");}:XMLHttpRequest;jasmine.util={};jasmine.util.inherit=function(a,b){var c=function(){};c.prototype=b.prototype;a.prototype=new c};+jasmine.util.formatException=function(a){var b;a.line?b=a.line:a.lineNumber&&(b=a.lineNumber);var c;a.sourceURL?c=a.sourceURL:a.fileName&&(c=a.fileName);a=a.name&&a.message?a.name+": "+a.message:a.toString();c&&b&&(a+=" in "+c+" (line "+b+")");return a};jasmine.util.htmlEscape=function(a){return!a?a:a.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">")};jasmine.util.argsToArray=function(a){for(var b=[],c=0;c<a.length;c++)b.push(a[c]);return b};+jasmine.util.extend=function(a,b){for(var c in b)a[c]=b[c];return a};+jasmine.Env=function(){this.currentSuite=this.currentSpec=null;this.currentRunner_=new jasmine.Runner(this);this.reporter=new jasmine.MultiReporter;this.updateInterval=jasmine.DEFAULT_UPDATE_INTERVAL;this.defaultTimeoutInterval=jasmine.DEFAULT_TIMEOUT_INTERVAL;this.lastUpdate=0;this.specFilter=function(){return!0};this.nextSuiteId_=this.nextSpecId_=0;this.equalityTesters_=[];this.matchersClass=function(){jasmine.Matchers.apply(this,arguments)};jasmine.util.inherit(this.matchersClass,jasmine.Matchers);+jasmine.Matchers.wrapInto_(jasmine.Matchers.prototype,this.matchersClass)};jasmine.Env.prototype.setTimeout=jasmine.setTimeout;jasmine.Env.prototype.clearTimeout=jasmine.clearTimeout;jasmine.Env.prototype.setInterval=jasmine.setInterval;jasmine.Env.prototype.clearInterval=jasmine.clearInterval;jasmine.Env.prototype.version=function(){if(jasmine.version_)return jasmine.version_;throw Error("Version not set");};+jasmine.Env.prototype.versionString=function(){if(jasmine.version_){var a=this.version();return a.major+"."+a.minor+"."+a.build+" revision "+a.revision}return"version unknown"};jasmine.Env.prototype.nextSpecId=function(){return this.nextSpecId_++};jasmine.Env.prototype.nextSuiteId=function(){return this.nextSuiteId_++};jasmine.Env.prototype.addReporter=function(a){this.reporter.addReporter(a)};jasmine.Env.prototype.execute=function(){this.currentRunner_.execute()};+jasmine.Env.prototype.describe=function(a,b){var c=new jasmine.Suite(this,a,b,this.currentSuite),d=this.currentSuite;d?d.add(c):this.currentRunner_.add(c);this.currentSuite=c;var e=null;try{b.call(c)}catch(f){e=f}this.currentSuite=d;e&&this.it("encountered a declaration exception",function(){throw e;});return c};jasmine.Env.prototype.beforeEach=function(a){this.currentSuite?this.currentSuite.beforeEach(a):this.currentRunner_.beforeEach(a)};jasmine.Env.prototype.currentRunner=function(){return this.currentRunner_};+jasmine.Env.prototype.afterEach=function(a){this.currentSuite?this.currentSuite.afterEach(a):this.currentRunner_.afterEach(a)};jasmine.Env.prototype.xdescribe=function(){return{execute:function(){}}};jasmine.Env.prototype.it=function(a,b){var c=new jasmine.Spec(this,this.currentSuite,a);this.currentSuite.add(c);this.currentSpec=c;b&&c.runs(b);return c};jasmine.Env.prototype.xit=function(){return{id:this.nextSpecId(),runs:function(){}}};+jasmine.Env.prototype.compareObjects_=function(a,b,c,d){if(a.__Jasmine_been_here_before__===b&&b.__Jasmine_been_here_before__===a)return!0;a.__Jasmine_been_here_before__=b;b.__Jasmine_been_here_before__=a;var e=function(a,b){return null!=a&&a[b]!==jasmine.undefined},f;for(f in b)!e(a,f)&&e(b,f)&&c.push("expected has key '"+f+"', but missing from actual.");for(f in a)!e(b,f)&&e(a,f)&&c.push("expected missing key '"+f+"', but present in actual.");for(f in b)"__Jasmine_been_here_before__"!=f&&(this.equals_(a[f],+b[f],c,d)||d.push("'"+f+"' was '"+(b[f]?jasmine.util.htmlEscape(b[f].toString()):b[f])+"' in expected, but was '"+(a[f]?jasmine.util.htmlEscape(a[f].toString()):a[f])+"' in actual."));jasmine.isArray_(a)&&(jasmine.isArray_(b)&&a.length!=b.length)&&d.push("arrays were not the same length");delete a.__Jasmine_been_here_before__;delete b.__Jasmine_been_here_before__;return 0==c.length&&0==d.length};+jasmine.Env.prototype.equals_=function(a,b,c,d){for(var c=c||[],d=d||[],e=0;e<this.equalityTesters_.length;e++){var f=(0,this.equalityTesters_[e])(a,b,this,c,d);if(f!==jasmine.undefined)return f}return a===b?!0:a===jasmine.undefined||null===a||b===jasmine.undefined||null===b?a==jasmine.undefined&&b==jasmine.undefined:jasmine.isDomNode(a)&&jasmine.isDomNode(b)?a===b:a instanceof Date&&b instanceof Date?a.getTime()==b.getTime():a instanceof jasmine.Matchers.Any?a.matches(b):b instanceof jasmine.Matchers.Any?+b.matches(a):jasmine.isString_(a)&&jasmine.isString_(b)||jasmine.isNumber_(a)&&jasmine.isNumber_(b)?a==b:"object"===typeof a&&"object"===typeof b?this.compareObjects_(a,b,c,d):a===b};jasmine.Env.prototype.contains_=function(a,b){if(jasmine.isArray_(a)){for(var c=0;c<a.length;c++)if(this.equals_(a[c],b))return!0;return!1}return 0<=a.indexOf(b)};jasmine.Env.prototype.addEqualityTester=function(a){this.equalityTesters_.push(a)};jasmine.Reporter=function(){};+jasmine.Reporter.prototype.reportRunnerStarting=function(){};jasmine.Reporter.prototype.reportRunnerResults=function(){};jasmine.Reporter.prototype.reportSuiteResults=function(){};jasmine.Reporter.prototype.reportSpecStarting=function(){};jasmine.Reporter.prototype.reportSpecResults=function(){};jasmine.Reporter.prototype.log=function(){};jasmine.Block=function(a,b,c){this.env=a;this.func=b;this.spec=c};jasmine.Block.prototype.execute=function(a){try{this.func.apply(this.spec)}catch(b){this.spec.fail(b)}a()};+jasmine.JsApiReporter=function(){this.finished=this.started=!1;this.suites_=[];this.results_={}};jasmine.JsApiReporter.prototype.reportRunnerStarting=function(a){this.started=!0;for(var a=a.topLevelSuites(),b=0;b<a.length;b++)this.suites_.push(this.summarize_(a[b]))};jasmine.JsApiReporter.prototype.suites=function(){return this.suites_};+jasmine.JsApiReporter.prototype.summarize_=function(a){var b=a instanceof jasmine.Suite,c={id:a.id,name:a.description,type:b?"suite":"spec",children:[]};if(b){a=a.children();for(b=0;b<a.length;b++)c.children.push(this.summarize_(a[b]))}return c};jasmine.JsApiReporter.prototype.results=function(){return this.results_};jasmine.JsApiReporter.prototype.resultsForSpec=function(a){return this.results_[a]};jasmine.JsApiReporter.prototype.reportRunnerResults=function(){this.finished=!0};+jasmine.JsApiReporter.prototype.reportSuiteResults=function(){};jasmine.JsApiReporter.prototype.reportSpecResults=function(a){this.results_[a.id]={messages:a.results().getItems(),result:0<a.results().failedCount?"failed":"passed"}};jasmine.JsApiReporter.prototype.log=function(){};jasmine.JsApiReporter.prototype.resultsForSpecs=function(a){for(var b={},c=0;c<a.length;c++){var d=a[c];b[d]=this.summarizeResult_(this.results_[d])}return b};+jasmine.JsApiReporter.prototype.summarizeResult_=function(a){for(var b=[],c=a.messages.length,d=0;d<c;d++){var e=a.messages[d];b.push({text:"log"==e.type?e.toString():jasmine.undefined,passed:e.passed?e.passed():!0,type:e.type,message:e.message,trace:{stack:e.passed&&!e.passed()?e.trace.stack:jasmine.undefined}})}return{result:a.result,messages:b}};jasmine.Matchers=function(a,b,c,d){this.env=a;this.actual=b;this.spec=c;this.isNot=d||!1;this.reportWasCalled_=!1};+jasmine.Matchers.pp=function(){throw Error("jasmine.Matchers.pp() is no longer supported, please use jasmine.pp() instead!");};jasmine.Matchers.prototype.report=function(){throw Error("As of jasmine 0.11, custom matchers must be implemented differently -- please see jasmine docs");};jasmine.Matchers.wrapInto_=function(a,b){for(var c in a)"report"!=c&&(b.prototype[c]=jasmine.Matchers.matcherFn_(c,a[c]))};+jasmine.Matchers.matcherFn_=function(a,b){return function(){var c=jasmine.util.argsToArray(arguments),d=b.apply(this,arguments);this.isNot&&(d=!d);if(this.reportWasCalled_)return d;var e;if(!d)if(this.message)e=this.message.apply(this,arguments),jasmine.isArray_(e)&&(e=e[this.isNot?1:0]);else{e=a.replace(/[A-Z]/g,function(a){return" "+a.toLowerCase()});e="Expected "+jasmine.pp(this.actual)+(this.isNot?" not ":" ")+e;if(0<c.length)for(var f=0;f<c.length;f++)0<f&&(e+=","),e+=" "+jasmine.pp(c[f]);e+=+"."}this.spec.addMatcherResult(new jasmine.ExpectationResult({matcherName:a,passed:d,expected:1<c.length?c:c[0],actual:this.actual,message:e}));return jasmine.undefined}};jasmine.Matchers.prototype.toBe=function(a){return this.actual===a};jasmine.Matchers.prototype.toNotBe=function(a){return this.actual!==a};jasmine.Matchers.prototype.toEqual=function(a){return this.env.equals_(this.actual,a)};jasmine.Matchers.prototype.toNotEqual=function(a){return!this.env.equals_(this.actual,a)};+jasmine.Matchers.prototype.toMatch=function(a){return RegExp(a).test(this.actual)};jasmine.Matchers.prototype.toNotMatch=function(a){return!RegExp(a).test(this.actual)};jasmine.Matchers.prototype.toBeDefined=function(){return this.actual!==jasmine.undefined};jasmine.Matchers.prototype.toBeUndefined=function(){return this.actual===jasmine.undefined};jasmine.Matchers.prototype.toBeNull=function(){return null===this.actual};jasmine.Matchers.prototype.toBeTruthy=function(){return!!this.actual};+jasmine.Matchers.prototype.toBeFalsy=function(){return!this.actual};jasmine.Matchers.prototype.toHaveBeenCalled=function(){if(0<arguments.length)throw Error("toHaveBeenCalled does not take arguments, use toHaveBeenCalledWith");if(!jasmine.isSpy(this.actual))throw Error("Expected a spy, but got "+jasmine.pp(this.actual)+".");this.message=function(){return["Expected spy "+this.actual.identity+" to have been called.","Expected spy "+this.actual.identity+" not to have been called."]};return this.actual.wasCalled};+jasmine.Matchers.prototype.wasCalled=jasmine.Matchers.prototype.toHaveBeenCalled;jasmine.Matchers.prototype.wasNotCalled=function(){if(0<arguments.length)throw Error("wasNotCalled does not take arguments");if(!jasmine.isSpy(this.actual))throw Error("Expected a spy, but got "+jasmine.pp(this.actual)+".");this.message=function(){return["Expected spy "+this.actual.identity+" to not have been called.","Expected spy "+this.actual.identity+" to have been called."]};return!this.actual.wasCalled};+jasmine.Matchers.prototype.toHaveBeenCalledWith=function(){var a=jasmine.util.argsToArray(arguments);if(!jasmine.isSpy(this.actual))throw Error("Expected a spy, but got "+jasmine.pp(this.actual)+".");this.message=function(){return 0==this.actual.callCount?["Expected spy to have been called with "+jasmine.pp(a)+" but it was never called.","Expected spy not to have been called with "+jasmine.pp(a)+" but it was."]:["Expected spy to have been called with "+jasmine.pp(a)+" but was called with "+jasmine.pp(this.actual.argsForCall),+"Expected spy not to have been called with "+jasmine.pp(a)+" but was called with "+jasmine.pp(this.actual.argsForCall)]};return this.env.contains_(this.actual.argsForCall,a)};jasmine.Matchers.prototype.wasCalledWith=jasmine.Matchers.prototype.toHaveBeenCalledWith;+jasmine.Matchers.prototype.wasNotCalledWith=function(){var a=jasmine.util.argsToArray(arguments);if(!jasmine.isSpy(this.actual))throw Error("Expected a spy, but got "+jasmine.pp(this.actual)+".");this.message=function(){return["Expected spy not to have been called with "+jasmine.pp(a)+" but it was","Expected spy to have been called with "+jasmine.pp(a)+" but it was"]};return!this.env.contains_(this.actual.argsForCall,a)};+jasmine.Matchers.prototype.toContain=function(a){return this.env.contains_(this.actual,a)};jasmine.Matchers.prototype.toNotContain=function(a){return!this.env.contains_(this.actual,a)};jasmine.Matchers.prototype.toBeLessThan=function(a){return this.actual<a};jasmine.Matchers.prototype.toBeGreaterThan=function(a){return this.actual>a};+jasmine.Matchers.prototype.toThrow=function(a){var b=!1,c;if("function"!=typeof this.actual)throw Error("Actual is not a function");try{this.actual()}catch(d){c=d}c&&(b=a===jasmine.undefined||this.env.equals_(c.message||c,a.message||a));var e=this.isNot?"not ":"";this.message=function(){return c&&(a===jasmine.undefined||!this.env.equals_(c.message||c,a.message||a))?["Expected function "+e+"to throw",a?a.message||a:" an exception",", but it threw",c.message||c].join(" "):"Expected function to throw an exception."};+return b};jasmine.Matchers.Any=function(a){this.expectedClass=a};jasmine.Matchers.Any.prototype.matches=function(a){return this.expectedClass==String?"string"==typeof a||a instanceof String:this.expectedClass==Number?"number"==typeof a||a instanceof Number:this.expectedClass==Function?"function"==typeof a||a instanceof Function:this.expectedClass==Object?"object"==typeof a:a instanceof this.expectedClass};+jasmine.Matchers.Any.prototype.toString=function(){return"<jasmine.any("+this.expectedClass+")>"};jasmine.MultiReporter=function(){this.subReporters_=[]};jasmine.util.inherit(jasmine.MultiReporter,jasmine.Reporter);jasmine.MultiReporter.prototype.addReporter=function(a){this.subReporters_.push(a)};+(function(){for(var a="reportRunnerStarting reportRunnerResults reportSuiteResults reportSpecStarting reportSpecResults log".split(" "),b=0;b<a.length;b++){var c=a[b];jasmine.MultiReporter.prototype[c]=function(a){return function(){for(var b=0;b<this.subReporters_.length;b++){var c=this.subReporters_[b];c[a]&&c[a].apply(c,arguments)}}}(c)}})();jasmine.NestedResults=function(){this.failedCount=this.passedCount=this.totalCount=0;this.skipped=!1;this.items_=[]};+jasmine.NestedResults.prototype.rollupCounts=function(a){this.totalCount+=a.totalCount;this.passedCount+=a.passedCount;this.failedCount+=a.failedCount};jasmine.NestedResults.prototype.log=function(a){this.items_.push(new jasmine.MessageResult(a))};jasmine.NestedResults.prototype.getItems=function(){return this.items_};jasmine.NestedResults.prototype.addResult=function(a){"log"!=a.type&&(a.items_?this.rollupCounts(a):(this.totalCount++,a.passed()?this.passedCount++:this.failedCount++));this.items_.push(a)};+jasmine.NestedResults.prototype.passed=function(){return this.passedCount===this.totalCount};jasmine.PrettyPrinter=function(){this.ppNestLevel_=0};+jasmine.PrettyPrinter.prototype.format=function(a){if(40<this.ppNestLevel_)throw Error("jasmine.PrettyPrinter: format() nested too deeply!");this.ppNestLevel_++;try{a===jasmine.undefined?this.emitScalar("undefined"):null===a?this.emitScalar("null"):a===jasmine.getGlobal()?this.emitScalar("<global>"):a instanceof jasmine.Matchers.Any?this.emitScalar(a.toString()):"string"===typeof a?this.emitString(a):jasmine.isSpy(a)?this.emitScalar("spy on "+a.identity):a instanceof RegExp?this.emitScalar(a.toString()):+"function"===typeof a?this.emitScalar("Function"):"number"===typeof a.nodeType?this.emitScalar("HTMLNode"):a instanceof Date?this.emitScalar("Date("+a+")"):a.__Jasmine_been_here_before__?this.emitScalar("<circular reference: "+(jasmine.isArray_(a)?"Array":"Object")+">"):jasmine.isArray_(a)||"object"==typeof a?(a.__Jasmine_been_here_before__=!0,jasmine.isArray_(a)?this.emitArray(a):this.emitObject(a),delete a.__Jasmine_been_here_before__):this.emitScalar(a.toString())}finally{this.ppNestLevel_--}};+jasmine.PrettyPrinter.prototype.iterateObject=function(a,b){for(var c in a)"__Jasmine_been_here_before__"!=c&&b(c,a.__lookupGetter__?null!=a.__lookupGetter__(c):!1)};jasmine.PrettyPrinter.prototype.emitArray=jasmine.unimplementedMethod_;jasmine.PrettyPrinter.prototype.emitObject=jasmine.unimplementedMethod_;jasmine.PrettyPrinter.prototype.emitScalar=jasmine.unimplementedMethod_;jasmine.PrettyPrinter.prototype.emitString=jasmine.unimplementedMethod_;+jasmine.StringPrettyPrinter=function(){jasmine.PrettyPrinter.call(this);this.string=""};jasmine.util.inherit(jasmine.StringPrettyPrinter,jasmine.PrettyPrinter);jasmine.StringPrettyPrinter.prototype.emitScalar=function(a){this.append(a)};jasmine.StringPrettyPrinter.prototype.emitString=function(a){this.append("'"+a+"'")};jasmine.StringPrettyPrinter.prototype.emitArray=function(a){this.append("[ ");for(var b=0;b<a.length;b++)0<b&&this.append(", "),this.format(a[b]);this.append(" ]")};+jasmine.StringPrettyPrinter.prototype.emitObject=function(a){var b=this;this.append("{ ");var c=!0;this.iterateObject(a,function(d,e){c?c=!1:b.append(", ");b.append(d);b.append(" : ");e?b.append("<getter>"):b.format(a[d])});this.append(" }")};jasmine.StringPrettyPrinter.prototype.append=function(a){this.string+=a};jasmine.Queue=function(a){this.env=a;this.blocks=[];this.running=!1;this.offset=this.index=0;this.abort=!1};jasmine.Queue.prototype.addBefore=function(a){this.blocks.unshift(a)};+jasmine.Queue.prototype.add=function(a){this.blocks.push(a)};jasmine.Queue.prototype.insertNext=function(a){this.blocks.splice(this.index+this.offset+1,0,a);this.offset++};jasmine.Queue.prototype.start=function(a){this.running=!0;this.onComplete=a;this.next_()};jasmine.Queue.prototype.isRunning=function(){return this.running};jasmine.Queue.LOOP_DONT_RECURSE=!0;+jasmine.Queue.prototype.next_=function(){for(var a=this,b=!0;b;)if(b=!1,a.index<a.blocks.length&&!this.abort){var c=!0,d=!1,e=function(){if(jasmine.Queue.LOOP_DONT_RECURSE&&c)d=!0;else{a.blocks[a.index].abort&&(a.abort=!0);a.offset=0;a.index++;var e=(new Date).getTime();a.env.updateInterval&&e-a.env.lastUpdate>a.env.updateInterval?(a.env.lastUpdate=e,a.env.setTimeout(function(){a.next_()},0)):jasmine.Queue.LOOP_DONT_RECURSE&&d?b=!0:a.next_()}};a.blocks[a.index].execute(e);c=!1;d&&e()}else if(a.running=+!1,a.onComplete)a.onComplete()};jasmine.Queue.prototype.results=function(){for(var a=new jasmine.NestedResults,b=0;b<this.blocks.length;b++)this.blocks[b].results&&a.addResult(this.blocks[b].results());return a};jasmine.Runner=function(a){this.env=a;this.queue=new jasmine.Queue(a);this.before_=[];this.after_=[];this.suites_=[]};jasmine.Runner.prototype.execute=function(){var a=this;a.env.reporter.reportRunnerStarting&&a.env.reporter.reportRunnerStarting(this);a.queue.start(function(){a.finishCallback()})};+jasmine.Runner.prototype.beforeEach=function(a){a.typeName="beforeEach";this.before_.splice(0,0,a)};jasmine.Runner.prototype.afterEach=function(a){a.typeName="afterEach";this.after_.splice(0,0,a)};jasmine.Runner.prototype.finishCallback=function(){this.env.reporter.reportRunnerResults(this)};jasmine.Runner.prototype.addSuite=function(a){this.suites_.push(a)};jasmine.Runner.prototype.add=function(a){a instanceof jasmine.Suite&&this.addSuite(a);this.queue.add(a)};+jasmine.Runner.prototype.specs=function(){for(var a=this.suites(),b=[],c=0;c<a.length;c++)b=b.concat(a[c].specs());return b};jasmine.Runner.prototype.suites=function(){return this.suites_};jasmine.Runner.prototype.topLevelSuites=function(){for(var a=[],b=0;b<this.suites_.length;b++)this.suites_[b].parentSuite||a.push(this.suites_[b]);return a};jasmine.Runner.prototype.results=function(){return this.queue.results()};+jasmine.Spec=function(a,b,c){if(!a)throw Error("jasmine.Env() required");if(!b)throw Error("jasmine.Suite() required");this.id=a.nextSpecId?a.nextSpecId():null;this.env=a;this.suite=b;this.description=c;this.queue=new jasmine.Queue(a);this.afterCallbacks=[];this.spies_=[];this.results_=new jasmine.NestedResults;this.results_.description=c;this.matchersClass=null};jasmine.Spec.prototype.getFullName=function(){return this.suite.getFullName()+" "+this.description+"."};+jasmine.Spec.prototype.results=function(){return this.results_};jasmine.Spec.prototype.log=function(){return this.results_.log(arguments)};jasmine.Spec.prototype.runs=function(a){this.addToQueue(new jasmine.Block(this.env,a,this));return this};jasmine.Spec.prototype.addToQueue=function(a){this.queue.isRunning()?this.queue.insertNext(a):this.queue.add(a)};jasmine.Spec.prototype.addMatcherResult=function(a){this.results_.addResult(a)};+jasmine.Spec.prototype.expect=function(a){var b=new (this.getMatchersClass_())(this.env,a,this);b.not=new (this.getMatchersClass_())(this.env,a,this,!0);return b};jasmine.Spec.prototype.waits=function(a){this.addToQueue(new jasmine.WaitsBlock(this.env,a,this));return this};+jasmine.Spec.prototype.waitsFor=function(a,b,c){for(var d=null,e=null,f=null,g=0;g<arguments.length;g++){var h=arguments[g];switch(typeof h){case "function":d=h;break;case "string":e=h;break;case "number":f=h}}this.addToQueue(new jasmine.WaitsForBlock(this.env,f,d,e,this));return this};jasmine.Spec.prototype.fail=function(a){this.results_.addResult(new jasmine.ExpectationResult({passed:!1,message:a?jasmine.util.formatException(a):"Exception"}))};+jasmine.Spec.prototype.getMatchersClass_=function(){return this.matchersClass||this.env.matchersClass};jasmine.Spec.prototype.addMatchers=function(a){var b=this.getMatchersClass_(),c=function(){b.apply(this,arguments)};jasmine.util.inherit(c,b);jasmine.Matchers.wrapInto_(a,c);this.matchersClass=c};jasmine.Spec.prototype.finishCallback=function(){this.env.reporter.reportSpecResults(this)};jasmine.Spec.prototype.finish=function(a){this.removeAllSpies();this.finishCallback();a&&a()};+jasmine.Spec.prototype.after=function(a){this.queue.isRunning()?this.queue.add(new jasmine.Block(this.env,a,this)):this.afterCallbacks.unshift(a)};jasmine.Spec.prototype.execute=function(a){var b=this;b.env.specFilter(b)?(this.env.reporter.reportSpecStarting(this),b.env.currentSpec=b,b.addBeforesAndAftersToQueue(),b.queue.start(function(){b.finish(a)})):(b.results_.skipped=!0,b.finish(a))};+jasmine.Spec.prototype.addBeforesAndAftersToQueue=function(){for(var a=this.env.currentRunner(),b,c=this.suite;c;c=c.parentSuite)for(b=0;b<c.before_.length;b++)this.queue.addBefore(new jasmine.Block(this.env,c.before_[b],this));for(b=0;b<a.before_.length;b++)this.queue.addBefore(new jasmine.Block(this.env,a.before_[b],this));for(b=0;b<this.afterCallbacks.length;b++)this.queue.add(new jasmine.Block(this.env,this.afterCallbacks[b],this));for(c=this.suite;c;c=c.parentSuite)for(b=0;b<c.after_.length;b++)this.queue.add(new jasmine.Block(this.env,+c.after_[b],this));for(b=0;b<a.after_.length;b++)this.queue.add(new jasmine.Block(this.env,a.after_[b],this))};jasmine.Spec.prototype.explodes=function(){throw"explodes function should not have been called";};+jasmine.Spec.prototype.spyOn=function(a,b,c){if(a==jasmine.undefined)throw"spyOn could not find an object to spy upon for "+b+"()";if(!c&&a[b]===jasmine.undefined)throw b+"() method does not exist";if(!c&&a[b]&&a[b].isSpy)throw Error(b+" has already been spied upon");c=jasmine.createSpy(b);this.spies_.push(c);c.baseObj=a;c.methodName=b;c.originalValue=a[b];return a[b]=c};+jasmine.Spec.prototype.removeAllSpies=function(){for(var a=0;a<this.spies_.length;a++){var b=this.spies_[a];b.baseObj[b.methodName]=b.originalValue}this.spies_=[]};jasmine.Suite=function(a,b,c,d){this.id=a.nextSuiteId?a.nextSuiteId():null;this.description=b;this.queue=new jasmine.Queue(a);this.parentSuite=d;this.env=a;this.before_=[];this.after_=[];this.children_=[];this.suites_=[];this.specs_=[]};+jasmine.Suite.prototype.getFullName=function(){for(var a=this.description,b=this.parentSuite;b;b=b.parentSuite)a=b.description+" "+a;return a};jasmine.Suite.prototype.finish=function(a){this.env.reporter.reportSuiteResults(this);this.finished=!0;"function"==typeof a&&a()};jasmine.Suite.prototype.beforeEach=function(a){a.typeName="beforeEach";this.before_.unshift(a)};jasmine.Suite.prototype.afterEach=function(a){a.typeName="afterEach";this.after_.unshift(a)};jasmine.Suite.prototype.results=function(){return this.queue.results()};+jasmine.Suite.prototype.add=function(a){this.children_.push(a);a instanceof jasmine.Suite?(this.suites_.push(a),this.env.currentRunner().addSuite(a)):this.specs_.push(a);this.queue.add(a)};jasmine.Suite.prototype.specs=function(){return this.specs_};jasmine.Suite.prototype.suites=function(){return this.suites_};jasmine.Suite.prototype.children=function(){return this.children_};jasmine.Suite.prototype.execute=function(a){var b=this;this.queue.start(function(){b.finish(a)})};+jasmine.WaitsBlock=function(a,b,c){this.timeout=b;jasmine.Block.call(this,a,null,c)};jasmine.util.inherit(jasmine.WaitsBlock,jasmine.Block);jasmine.WaitsBlock.prototype.execute=function(a){this.env.reporter.log(">> Jasmine waiting for "+this.timeout+" ms...");this.env.setTimeout(function(){a()},this.timeout)};jasmine.WaitsForBlock=function(a,b,c,d,e){this.timeout=b||a.defaultTimeoutInterval;this.latchFunction=c;this.message=d;this.totalTimeSpentWaitingForLatch=0;jasmine.Block.call(this,a,null,e)};+jasmine.util.inherit(jasmine.WaitsForBlock,jasmine.Block);jasmine.WaitsForBlock.TIMEOUT_INCREMENT=10;+jasmine.WaitsForBlock.prototype.execute=function(a){this.env.reporter.log(">> Jasmine waiting for "+(this.message||"something to happen"));var b;try{b=this.latchFunction.apply(this.spec)}catch(c){this.spec.fail(c);a();return}if(b)a();else if(this.totalTimeSpentWaitingForLatch>=this.timeout)this.spec.fail({name:"timeout",message:"timed out after "+this.timeout+" msec waiting for "+(this.message||"something to happen")}),this.abort=!0,a();else{this.totalTimeSpentWaitingForLatch+=jasmine.WaitsForBlock.TIMEOUT_INCREMENT;+var d=this;this.env.setTimeout(function(){d.execute(a)},jasmine.WaitsForBlock.TIMEOUT_INCREMENT)}};jasmine.FakeTimer=function(){this.reset();var a=this;a.setTimeout=function(b,c){a.timeoutsMade++;a.scheduleFunction(a.timeoutsMade,b,c,!1);return a.timeoutsMade};a.setInterval=function(b,c){a.timeoutsMade++;a.scheduleFunction(a.timeoutsMade,b,c,!0);return a.timeoutsMade};a.clearTimeout=function(b){a.scheduledFunctions[b]=jasmine.undefined};a.clearInterval=function(b){a.scheduledFunctions[b]=jasmine.undefined}};+jasmine.FakeTimer.prototype.reset=function(){this.timeoutsMade=0;this.scheduledFunctions={};this.nowMillis=0};jasmine.FakeTimer.prototype.tick=function(a){var b=this.nowMillis,a=b+a;this.runFunctionsWithinRange(b,a);this.nowMillis=a};+jasmine.FakeTimer.prototype.runFunctionsWithinRange=function(a,b){var c,d=[],e;for(e in this.scheduledFunctions)c=this.scheduledFunctions[e],c!=jasmine.undefined&&(c.runAtMillis>=a&&c.runAtMillis<=b)&&(d.push(c),this.scheduledFunctions[e]=jasmine.undefined);if(0<d.length){d.sort(function(a,b){return a.runAtMillis-b.runAtMillis});for(c=0;c<d.length;++c)try{var f=d[c];this.nowMillis=f.runAtMillis;f.funcToCall();f.recurring&&this.scheduleFunction(f.timeoutKey,f.funcToCall,f.millis,!0)}catch(g){}this.runFunctionsWithinRange(a,+b)}};jasmine.FakeTimer.prototype.scheduleFunction=function(a,b,c,d){this.scheduledFunctions[a]={runAtMillis:this.nowMillis+c,funcToCall:b,recurring:d,timeoutKey:a,millis:c}};+jasmine.Clock={defaultFakeTimer:new jasmine.FakeTimer,reset:function(){jasmine.Clock.assertInstalled();jasmine.Clock.defaultFakeTimer.reset()},tick:function(a){jasmine.Clock.assertInstalled();jasmine.Clock.defaultFakeTimer.tick(a)},runFunctionsWithinRange:function(a,b){jasmine.Clock.defaultFakeTimer.runFunctionsWithinRange(a,b)},scheduleFunction:function(a,b,c,d){jasmine.Clock.defaultFakeTimer.scheduleFunction(a,b,c,d)},useMock:function(){jasmine.Clock.isInstalled()||(jasmine.getEnv().currentSpec.after(jasmine.Clock.uninstallMock),+jasmine.Clock.installMock())},installMock:function(){jasmine.Clock.installed=jasmine.Clock.defaultFakeTimer},uninstallMock:function(){jasmine.Clock.assertInstalled();jasmine.Clock.installed=jasmine.Clock.real},real:{setTimeout:jasmine.getGlobal().setTimeout,clearTimeout:jasmine.getGlobal().clearTimeout,setInterval:jasmine.getGlobal().setInterval,clearInterval:jasmine.getGlobal().clearInterval},assertInstalled:function(){if(!jasmine.Clock.isInstalled())throw Error("Mock clock is not installed, use jasmine.Clock.useMock()");+},isInstalled:function(){return jasmine.Clock.installed==jasmine.Clock.defaultFakeTimer},installed:null};jasmine.Clock.installed=jasmine.Clock.real;jasmine.getGlobal().setTimeout=function(a,b){return jasmine.Clock.installed.setTimeout.apply?jasmine.Clock.installed.setTimeout.apply(this,arguments):jasmine.Clock.installed.setTimeout(a,b)};+jasmine.getGlobal().setInterval=function(a,b){return jasmine.Clock.installed.setInterval.apply?jasmine.Clock.installed.setInterval.apply(this,arguments):jasmine.Clock.installed.setInterval(a,b)};jasmine.getGlobal().clearTimeout=function(a){return jasmine.Clock.installed.clearTimeout.apply?jasmine.Clock.installed.clearTimeout.apply(this,arguments):jasmine.Clock.installed.clearTimeout(a)};+jasmine.getGlobal().clearInterval=function(a){return jasmine.Clock.installed.clearTimeout.apply?jasmine.Clock.installed.clearInterval.apply(this,arguments):jasmine.Clock.installed.clearInterval(a)};jasmine.version_={major:1,minor:0,build:1,revision:1286311016};+jasmine.TrivialReporter=function(a){this.document=a||document;this.suiteDivs={};this.logRunningSpecs=!1};jasmine.TrivialReporter.prototype.createDom=function(a,b,c){for(var d=document.createElement(a),e=2;e<arguments.length;e++){var f=arguments[e];"string"===typeof f?d.appendChild(document.createTextNode(f)):f&&d.appendChild(f)}for(var g in b)"className"==g?d[g]=b[g]:d.setAttribute(g,b[g]);return d};+jasmine.TrivialReporter.prototype.reportRunnerStarting=function(a){var b,c;this.outerDiv=this.createDom("div",{className:"jasmine_reporter"},this.createDom("div",{className:"banner"},this.createDom("div",{className:"logo"},this.createDom("a",{href:"http://pivotal.github.com/jasmine/",target:"_blank"},"Jasmine"),this.createDom("span",{className:"version"},a.env.versionString())),this.createDom("div",{className:"options"},"Show ",b=this.createDom("input",{id:"__jasmine_TrivialReporter_showPassed__",+type:"checkbox"}),this.createDom("label",{"for":"__jasmine_TrivialReporter_showPassed__"}," passed "),c=this.createDom("input",{id:"__jasmine_TrivialReporter_showSkipped__",type:"checkbox"}),this.createDom("label",{"for":"__jasmine_TrivialReporter_showSkipped__"}," skipped"))),this.runnerDiv=this.createDom("div",{className:"runner running"},this.createDom("a",{className:"run_spec",href:"?"},"run all"),this.runnerMessageSpan=this.createDom("span",{},"Running..."),this.finishedAtSpan=this.createDom("span",+{className:"finished-at"},"")));this.document.body.appendChild(this.outerDiv);for(var a=a.suites(),d=0;d<a.length;d++){var e=a[d],f=this.createDom("div",{className:"suite"},this.createDom("a",{className:"run_spec",href:"?spec="+encodeURIComponent(e.getFullName())},"run"),this.createDom("a",{className:"description",href:"?spec="+encodeURIComponent(e.getFullName())},e.description));this.suiteDivs[e.id]=f;var g=this.outerDiv;e.parentSuite&&(g=this.suiteDivs[e.parentSuite.id]);g.appendChild(f)}this.startedAt=+new Date;var h=this;b.onclick=function(){h.outerDiv.className=b.checked?h.outerDiv.className+" show-passed":h.outerDiv.className.replace(/ show-passed/,"")};c.onclick=function(){h.outerDiv.className=c.checked?h.outerDiv.className+" show-skipped":h.outerDiv.className.replace(/ show-skipped/,"")}};+jasmine.TrivialReporter.prototype.reportRunnerResults=function(a){var b=a.results(),c=0<b.failedCount?"runner failed":"runner passed";this.runnerDiv.setAttribute("class",c);this.runnerDiv.setAttribute("className",c);for(var a=a.specs(),d=c=0;d<a.length;d++)this.specFilter(a[d])&&c++;b=""+c+" spec"+(1==c?"":"s")+", "+b.failedCount+" failure"+(1==b.failedCount?"":"s");b+=" in "+((new Date).getTime()-this.startedAt.getTime())/1E3+"s";this.runnerMessageSpan.replaceChild(this.createDom("a",{className:"description",+href:"?"},b),this.runnerMessageSpan.firstChild);this.finishedAtSpan.appendChild(document.createTextNode("Finished at "+(new Date).toString()))};jasmine.TrivialReporter.prototype.reportSuiteResults=function(a){var b=a.results(),c=b.passed()?"passed":"failed";0==b.totalCount&&(c="skipped");this.suiteDivs[a.id].className+=" "+c};jasmine.TrivialReporter.prototype.reportSpecStarting=function(a){this.logRunningSpecs&&this.log(">> Jasmine Running "+a.suite.description+" "+a.description+"...")};+jasmine.TrivialReporter.prototype.reportSpecResults=function(a){var b=a.results(),c=b.passed()?"passed":"failed";b.skipped&&(c="skipped");for(var c=this.createDom("div",{className:"spec "+c},this.createDom("a",{className:"run_spec",href:"?spec="+encodeURIComponent(a.getFullName())},"run"),this.createDom("a",{className:"description",href:"?spec="+encodeURIComponent(a.getFullName()),title:a.getFullName()},a.description.split("__::__")[1])),b=b.getItems(),d=this.createDom("div",{className:"messages"}),+e=0;e<b.length;e++){var f=b[e];"log"==f.type?d.appendChild(this.createDom("div",{className:"resultMessage log"},f.toString())):"expect"==f.type&&f.passed&&!f.passed()&&(d.appendChild(this.createDom("div",{className:"resultMessage fail"},f.message)),f.trace.stack&&d.appendChild(this.createDom("div",{className:"stackTrace"},f.trace.stack)))}0<d.childNodes.length&&c.appendChild(d);this.suiteDivs[a.suite.id].appendChild(c)};+jasmine.TrivialReporter.prototype.log=function(){var a=jasmine.getGlobal().console;a&&a.log&&(a.log.apply?a.log.apply(a,arguments):a.log(arguments))};jasmine.TrivialReporter.prototype.getLocation=function(){return this.document.location};jasmine.TrivialReporter.prototype.specFilter=function(a){for(var b={},c=this.getLocation().search.substring(1).split("&"),d=0;d<c.length;d++){var e=c[d].split("=");b[decodeURIComponent(e[0])]=decodeURIComponent(e[1])}return!b.spec?!0:0==a.getFullName().indexOf(b.spec)};+(function() {+jasmine.FormalReporter = function(doc) {+ this.document = doc || document;+ this.suiteDivs = {};+ this.logRunningSpecs = false;+ };+ + jasmine.FormalReporter.prototype.createDom = function(type, attrs, childrenVarArgs) {+ };+ + jasmine.FormalReporter.prototype.reportRunnerStarting = function(runner) {+ var showPassed, showSkipped;+ + var suites = runner.suites();+ for (var i = 0; i < suites.length; i++) {+ var suite = suites[i];+ }+ + this.startedAt = new Date();+ + var self = this;+ };+ + jasmine.FormalReporter.prototype.reportRunnerResults = function(runner) {+ };+ + jasmine.FormalReporter.prototype.reportSuiteResults = function(suite) {+ };+ + jasmine.FormalReporter.prototype.reportSpecStarting = function(spec) {+ };+ + jasmine.FormalReporter.prototype.reportSpecResults = function(spec) {+ var results = spec.results();+ var status = results.passed() ? 'passed' : 'failed';+ + var k = "#test_" + spec.description.split("__::__")[0]+ var el = $(k)++ spec.description = spec.description.split("__::__")[1]++ if (status == "passed") {+ if (k.indexOf("multi") >= 0) {+ $(k).before("<span style='border-radius:3;margin-right:-50px;background-color:rgba(32,186,24,0.5)' title='" + JSON.stringify(spec.results_.items_[0].actual)+ "'> <span style='color:rgb(255,255,255);font-weight:bold'>PASS</span> </span> ")+ } else {+ $(k).before("<span style='border-radius:3;margin-right:-50px;background-color:rgba(32,186,24,0.5)' title='" + spec.results_.items_[0].actual+ "'> <span style='color:rgb(255,255,255);font-weight:bold'>PASS</span> </span> ")+ }+ } else {+ if (k.indexOf("multi") >= 0) {+ $(k).before("<span style='border-radius:3;margin-right:-50px;background-color:rgba(182,24,32,0.5)' title='" + JSON.stringify(spec.results_.items_[0].actual)+ "'> <span style='color:rgb(255,255,255);font-weight:bold'>FAIL</span> </span> ")+ } else {+ $(k).before("<span style='border-radius:3;margin-right:-50px;background-color:rgba(182,24,32,0.5)' title='" + JSON.stringify(spec.results_.items_[0].actual)+ "'> <span style='color:rgb(255,255,255);font-weight:bold'>FAIL</span> </span> ")+ }+ }+ };+ + jasmine.FormalReporter.prototype.log = function() {+ };+ + jasmine.FormalReporter.prototype.getLocation = function() {+ return this.document.location;+ };+ + jasmine.FormalReporter.prototype.specFilter = function(spec) {+ var paramMap = {};+ var params = this.getLocation().search.substring(1).split('&');+ for (var i = 0; i < params.length; i++) {+ var p = params[i].split('=');+ paramMap[decodeURIComponent(p[0])] = decodeURIComponent(p[1]);+ }+ + if (!paramMap.spec) {+ return true;+ }+ return spec.getFullName().indexOf(paramMap.spec) === 0;+ };+ +})();// Input 0+var i = void 0, j = !0;+function k(p) {+ return p instanceof Array+}+function s() {+ throw"Pattern Match Exhausted";+}+var v = new function() {+ function p(a) {+ var b;+ 0 === a ? b = 0 : 1 === a ? b = 1 : (b = p(a - 1), a = p(a - 2), b += a);+ return b+ }+ function h(a) {+ return function(b) {+ var e = a, f;+ if(e === b) {+ return j+ }+ e = a;+ f = b;+ if("object" === typeof e) {+ var c = j, d;+ for(d in e) {+ c = c && f.hasOwnProperty(d) && h(e[d])(f[d])+ }+ e = Object.keys(e).length === Object.keys(f).length;+ return c && e+ }+ e = a;+ f = b;+ if(k(e)) {+ d = j;+ for(c in e) {+ d = d && h(e[c])(f[c])+ }+ return d && e.length == f.length+ }+ return!1+ }+ }+ function m(a) {+ return function() {+ return a+ }+ }+ this.object_ = function(a) {+ return"object" === typeof a+ };+ this.array_ = k;+ this.string_ = function(a) {+ return"string" === typeof a+ };+ this.type_ = function(a) {+ return typeof a+ };+ this.not = function(a) {+ return!a+ };+ this._grea_grea_eq = function(a) {+ return function(b) {+ return b(a())+ }+ };+ this._grea_grea = function(a) {+ return function(b) {+ return function() {+ a();+ return b()+ }+ }+ };+ this._return_ = m;+ this.log = function(a) {+ return function() {+ return console.log(a)+ }+ };+ this._and_and = function(a) {+ return function(b) {+ return a && b+ }+ };+ this._or_or = function(a) {+ return function(b) {+ return a || b+ }+ };+ this._star = function(a) {+ return function(b) {+ return a * b+ }+ };+ this._forw = function(a) {+ return function(b) {+ return a / b+ }+ };+ this._perc = function(a) {+ return function(b) {+ return a % b+ }+ };+ this._plus = function(a) {+ return function(b) {+ return a + b+ }+ };+ this._minu = function(a) {+ return function(b) {+ return a - b+ }+ };+ this._less_eq = function(a) {+ return function(b) {+ return a <= b+ }+ };+ this._grea_eq = function(a) {+ return function(b) {+ return a >= b+ }+ };+ this._less = function(a) {+ return function(b) {+ return a < b+ }+ };+ this._grea = function(a) {+ return function(b) {+ return a > b+ }+ };+ this._bang_eq = function(a) {+ return function(b) {+ return!h(a)(b)+ }+ };+ this._forw_eq = function(a) {+ return function(b) {+ return!h(a)(b)+ }+ };+ this._eq_eq = h;+ this.fib = p;+ this.speedtest = new function() {+ function a(b) {+ return 0 === b ? 0 : 1 === b ? 1 : a(b - 1) + a(b - 2)+ }+ function b() {+ return(new Date).getTime()+ }+ this.get_time = b;+ this.time = function(a) {+ return function() {+ var f = b();+ a();+ return b() - f+ }+ };+ this.fast_fib = a;+ this.floor = Math.floor+ };+ this._less_or = function(a) {+ return function(b) {+ return a(b)+ }+ };+ this._or_grea = function(a) {+ return function(b) {+ return b(a)+ }+ };+ this._less_col = function(a) {+ return function(b) {+ return a(b)+ }+ };+ this._comp_col = function(a) {+ return function(b) {+ return function(e) {+ return a(b(e))+ }+ }+ };+ this.id = function(a) {+ return a+ };+ this.flip = function(a) {+ return function(b) {+ return function(e) {+ return a(e)(b)+ }+ }+ };+ this._apos = function(a) {+ return function(b) {+ return b(a)+ }+ };+ this.string = new function() {+ function a(a) {+ return a.replace(/\s+$/, "")+ }+ function b(a) {+ return a.replace(/^\s+/, "")+ }+ this.lstrip = b;+ this.rstrip = a;+ this.strip = function(e) {+ return b(a(e))+ };+ this._plus_plus_plus = function(a) {+ return function(b) {+ return"" + a + b+ }+ }+ };+ this.err = function(a) {+ var b;+ try {+ a(), b = !1+ }catch(e) {+ b = e+ }+ return b+ };+ this.option = new function() {+ this.option = function(a) {+ return function(b) {+ if(b.hasOwnProperty("none")) {+ return a+ }+ var e = b.some;+ if(b.hasOwnProperty("some")) {+ return e+ }+ s()+ }+ }+ };+ this.html = new function() {+ function a(a) {+ return function(b) {+ return function() {+ return a.push(b)+ }+ }+ }+ function b(a) {+ return function(b) {+ return b.split(a)+ }+ }+ function e(a) {+ return JSON.stringify(a)+ }+ function f(a) {+ return function() {+ return window.addEventListener("load", a, !1)+ }+ }+ function c(a) {+ return function(b) {+ return function() {+ return $(b.element).append($(a.element).detach())+ }+ }+ }+ function d(a) {+ return function() {+ var b = $(a).get(0);+ return{add_class:function(a) {+ return function() {+ return b.setAttribute("class", b.getAttribute("class") + " " + a)+ }+ }, add_style:function(a) {+ return function(t) {+ return function() {+ b.style[a] = t+ }+ }+ }, element:b, inner:function() {+ return b.innerHTML+ }, on_click:function(a) {+ return function() {+ b.onclick = a+ }+ }, set:function(a) {+ return function() {+ b.innerHTML = a+ }+ }}+ }+ }+ this.get = d;+ this.$_eq = function(a) {+ return function(b) {+ return function() {+ if("undefined" != typeof $) {+ var c = $(a).get(0);+ "undefined" != typeof c && (c.innerHTML = b)+ }+ }+ }+ };+ var g;+ this.$_or = g = function(a) {+ return function(b) {+ return function(c) {+ return function() {+ return $(a).css(b, c)+ }+ }+ }+ };+ this.$_comp = function(a) {+ return function(b) {+ return function() {+ return $(a).addClass(b)+ }+ }+ };+ this.$_plus = function(a) {+ return function(b) {+ return function() {+ return $(a).append(b)+ }+ }+ };+ this.div = function(a) {+ return function() {+ return"<div id='" + a + "'/>"+ }+ };+ this.move = c;+ this.on_load = f;+ this.stringify = e;+ this._bang_bang = function(a) {+ return function(b) {+ return a[b]+ }+ };+ this.with_page = function(a) {+ return function() {+ var b = $("body").clone(), c = a();+ $("body").replaceWith(b);+ return c+ }+ };+ this.split = b;+ var u = 0, l = {reportRunnerResults:function() {+ return phantom.exit(u)+ }, reportSpecResults:function(a) {+ if(a.results().passed()) {+ var c = {}, a = function() {+ return c+ }+ }else {+ var d = a.results_.items_, t;+ t = a.description.split("__::__")[1];+ var x;+ x = JSON.stringify(d[0].expected);+ var y;+ y = JSON.stringify(d[0].actual);+ var a = b("__::__")(a.description), a = b("_")(a[0])[0], z = e(parseInt(a) + 1), a = function() {+ var a;+ if(h(u)(0)) {+ a = function() {+ return console.log("\r ")+ }+ }else {+ var b = {};+ a = function() {+ return b+ }+ }+ a();+ u = 1;+ console.log("Test failed at line " + z + ("\n\n" + t + ("\n\n Expected " + x + ("\n Actual " + y + ""))));+ return console.log("")+ }+ }+ return a()+ }};+ this.console_runner = function() {+ var a = jasmine.getEnv();+ a.addReporter(l);+ return a.execute()+ };+ this.push = a;+ var n = {failed:0, messages:[], reportRunnerResults:function() {+ var a;+ if(0 < n.failed) {+ var b = n.messages;+ a = function() {+ return console.log(b)+ }+ }else {+ var c = {};+ a = function() {+ return c+ }+ }+ a();+ return console.log("" + (n.total - n.failed) + ("/" + n.total + " tests passed"))+ }, reportSpecResults:function(b) {+ var c = b.results().passed();+ n.total++;+ if(c) {+ var d = {}, c = function() {+ return d+ }+ }else {+ c = function() {+ n.failed++;+ a(n.messages)(b.description)();+ return{}+ }+ }+ return c()+ }, total:0};+ this.console_reporter = n;+ this.table_of_contents = f(function() {+ $("code").addClass("prettyprint");+ $("code").addClass("lang-hs");+ g(".test")("position")("relative")();+ g(".test")("left")("50px")();+ prettyPrint();+ var a = new jasmine.TrivialReporter, b = new jasmine.FormalReporter, f = jasmine.getEnv();+ f.addReporter(a);+ f.addReporter(b);+ f.addReporter(n);+ f.execute();+ a = d(".jasmine_reporter")();+ b = d("#test_suite")();+ return c(a)(b)()+ })+ };+ var l = new function() {+ function a(a) {+ return function(b) {+ function c(d) {+ if(d.hasOwnProperty("nil")) {+ return b+ }+ var f = d.head, g = d.tail;+ if(d.hasOwnProperty("head") && d.hasOwnProperty("tail")) {+ return a(f)(c(g))+ }+ s()+ }+ return c+ }+ }+ function b(a) {+ return function(b) {+ if(b.hasOwnProperty("nil")) {+ throw"Foldl1 called on empty list";+ }+ return e(a)(r(b))(q(b))+ }+ }+ function e(a) {+ return function(b) {+ return function(c) {+ for(var d = i, f = b;"undefined" == typeof d;) {+ var g = f;+ if(c.hasOwnProperty("nil")) {+ d = g+ }else {+ var g = f, e = c.head, q = c.tail;+ c.hasOwnProperty("head") && c.hasOwnProperty("tail") ? (f = a(g)(e), c = q, d = i) : s()+ }+ }+ return d+ }+ }+ }+ function f(a) {+ for(var b = i, c = {nil:j};"undefined" == typeof b;) {+ var d = c;+ if(a.hasOwnProperty("nil")) {+ b = d+ }else {+ var d = c, f = a.head, g = a.tail;+ a.hasOwnProperty("head") && a.hasOwnProperty("tail") ? (c = {head:f, tail:d}, a = g, b = i) : s()+ }+ }+ return b+ }+ function c(a) {+ return function(b) {+ var d = a;+ if(b.hasOwnProperty("nil")) {+ return{nil:j}+ }+ var d = a, f = d(r(b)), b = c(d)(q(b));+ return{head:f, tail:b}+ }+ }+ function d(a) {+ return function(b) {+ var c = a;+ if(b.hasOwnProperty("nil")) {+ return{nil:j}+ }+ var c = a, f = b;+ if(c(r(f))) {+ return b = r(f), c = d(c)(q(f)), {head:b, tail:c}+ }+ c = a;+ c = d(c);+ b = q(b);+ return c(b)+ }+ }+ function g(a) {+ return function(b) {+ var c = b;+ if(a.hasOwnProperty("nil")) {+ return c+ }+ var c = a.head, d = a.tail;+ if(a.hasOwnProperty("head") && a.hasOwnProperty("tail")) {+ return b = g(d)(b), {head:c, tail:b}+ }+ s()+ }+ }+ function h(a) {+ return function(b) {+ if(0 === a) {+ b = {nil:j}+ }else {+ var c = h(a - 1)(b), b = {head:b, tail:c}+ }+ return b+ }+ }+ function l(a) {+ if(a.hasOwnProperty("nil")) {+ return 0+ }+ var b = a.tail;+ if(a.hasOwnProperty("head") && a.hasOwnProperty("tail")) {+ return 1 + l(b)+ }+ s()+ }+ function n(a) {+ return function(b) {+ var c = b;+ if(0 === a) {+ return{nil:j}+ }+ c = b;+ b = r(c);+ c = n(a - 1)(q(c));+ return{head:b, tail:c}+ }+ }+ function q(a) {+ var b = a.tail;+ if(a.hasOwnProperty("head") && a.hasOwnProperty("tail")) {+ return b+ }+ if(a.hasOwnProperty("nil")) {+ throw"Tail called on empty list";+ }+ s()+ }+ function r(a) {+ var b = a.head;+ if(a.hasOwnProperty("head") && a.hasOwnProperty("tail")) {+ return b+ }+ if(a.hasOwnProperty("nil")) {+ throw"Head called on empty list";+ }+ s()+ }+ this._col_col = function(a) {+ return function(b) {+ return{head:a, tail:b}+ }+ };+ this.empty_ = function(a) {+ return a.hasOwnProperty("nil") ? j : !1+ };+ this.head = r;+ this.tail = q;+ this.last = function(a) {+ for(var b = i;"undefined" == typeof b;) {+ var c = a.head;+ if(a.hasOwnProperty("head") && a.hasOwnProperty("tail") && a.tail.hasOwnProperty("nil")) {+ b = c+ }else {+ if(c = a.tail, a.hasOwnProperty("head") && a.hasOwnProperty("tail")) {+ a = c, b = i+ }else {+ if(a.hasOwnProperty("nil")) {+ throw"Last called on empty list";+ }+ s()+ }+ }+ }+ return b+ };+ this.take = n;+ this.drop = function(a) {+ return function(b) {+ for(var c = i, d = a;"undefined" == typeof c;) {+ c = b, 0 !== d && (c = b, d -= 1, b = q(c), c = i)+ }+ return c+ }+ };+ this._comp_comp = function(a) {+ return function(b) {+ for(var c = i, d = {nil:j};"undefined" == typeof c;) {+ var c = b, f = d;+ c >= a ? (b = c - 1, d = {head:c, tail:f}, c = i) : c = f = d+ }+ return c+ }+ };+ this.take_while = function(a) {+ return function(b) {+ var c = a;+ if(b.hasOwnProperty("nil")) {+ return{nil:j}+ }+ var c = a, f;+ c(r(b)) ? (f = r(b), b = d(c)(q(b)), f = {head:f, tail:b}) : f = {nil:j};+ return f+ }+ };+ this.drop_while = function(a) {+ return function(b) {+ for(var c = i, d = a;"undefined" == typeof c;) {+ if(c = d, b.hasOwnProperty("nil")) {+ c = {nil:j}+ }else {+ var c = d, f = b;+ c(r(f)) ? (d = c, b = q(f), c = i) : c = f = b+ }+ }+ return c+ }+ };+ this.length = l;+ this.init = h;+ this._plus_plus = g;+ this.filter = d;+ this.map = c;+ this.reverse = f;+ this.take_apos = function(a) {+ return function(b) {+ for(var c = i, d = a, g = {nil:j};"undefined" == typeof c;) {+ if(c = g, 0 !== d) {+ var e = b, c = g, d = d - 1, b = q(e), g = {head:r(e), tail:c}, c = i+ }+ }+ return f(c)+ }+ };+ this.foldl = e;+ this.foldl1 = b;+ this.foldr = a;+ this.foldr1 = function(b) {+ return function(c) {+ if(c.hasOwnProperty("nil")) {+ throw"Foldr1 called on empty list";+ }+ return a(b)(r(c))(q(c))+ }+ };+ this.all_ = function(a) {+ var d = b(function(a) {+ return function(b) {+ return a && b+ }+ }), f = c(a);+ return function(a) {+ return d(f(a))+ }+ };+ this.any_ = function(a) {+ var d = b(function(a) {+ return function(b) {+ return a || b+ }+ }), f = c(a);+ return function(a) {+ return d(f(a))+ }+ };+ this.sum = b(function(a) {+ return function(b) {+ return a + b+ }+ });+ this.product = b(function(a) {+ return function(b) {+ return a * b+ }+ });+ var w = b(function(a) {+ return function(b) {+ return g(a)(b)+ }+ });+ this.concat = w;+ this.concat_map = function(a) {+ return function(b) {+ return w(c(a)(b))+ }+ };+ this.maximum = b(function(a) {+ return function(b) {+ return a > b ? a : b+ }+ });+ this.minimum = b(function(a) {+ return function(b) {+ return a > b ? b : a+ }+ })+ };+ this.list = l;+ this.seq = new function() {+ function a(b) {+ if(b.hasOwnProperty("end")) {+ return{end:j}+ }+ var c = b.seq;+ if(b.hasOwnProperty("seq")) {+ var d = i;+ return{seq:function() {+ if(!d) {+ var b;+ b = c();+ var f = b.elem, g = b.next;+ if(b.hasOwnProperty("elem") && b.hasOwnProperty("next")) {+ var e = {elem:f, next:a(g)};+ b = function() {+ return e+ }+ }else {+ s(), b = i+ }+ d = b()+ }+ return d+ }}+ }+ s()+ }+ function b(a) {+ return function(c) {+ return function(d) {+ if(c.hasOwnProperty("end") || d.hasOwnProperty("end")) {+ return{end:j}+ }+ var f = c.seq, g = d.seq;+ if(c.hasOwnProperty("seq") && d.hasOwnProperty("seq")) {+ return{seq:function() {+ var c;+ var d = f();+ c = d.elem;+ var e = d.next;+ if(d.hasOwnProperty("elem") && d.hasOwnProperty("next")) {+ var d = g(), r = d.elem, h = d.next;+ if(d.hasOwnProperty("elem") && d.hasOwnProperty("next")) {+ var l = {elem:a(c)(r), next:b(a)(e)(h)};+ c = function() {+ return l+ }+ }else {+ s(), c = i+ }+ }else {+ s(), c = i+ }+ return c()+ }}+ }+ s()+ }+ }+ }+ function e(a) {+ if(a.hasOwnProperty("end")) {+ return{nil:j}+ }+ var b = a.seq;+ if(a.hasOwnProperty("seq")) {+ var b = b(), a = b.elem, c = b.next;+ if(b.hasOwnProperty("elem") && b.hasOwnProperty("next")) {+ var d, b = e(c);+ d = {head:a, tail:b};+ a = function() {+ return d+ }+ }else {+ s(), a = i+ }+ return a()+ }+ s()+ }+ function f(a) {+ if(a.hasOwnProperty("nil")) {+ return{end:j}+ }+ var b = a.head, c = a.tail;+ if(a.hasOwnProperty("head") && a.hasOwnProperty("tail")) {+ return{seq:function() {+ return{elem:b, next:f(c)}+ }}+ }+ s()+ }+ function c(a) {+ return function(b) {+ return{seq:function() {+ return{elem:b, next:c(a)(a(b))}+ }}+ }+ }+ var d = l.tail || window.tail, g = l.take || window.take;+ this.seq = function(a) {+ return{seq:a}+ };+ this.iterate = c;+ this.from_list = f;+ this.to_list = e;+ this.take = g = function(a) {+ return function(b) {+ if(b.hasOwnProperty("end") || 0 === a) {+ return{end:j}+ }+ var c = b.seq;+ if(b.hasOwnProperty("seq")) {+ return{seq:function() {+ var b;+ b = c();+ var d = b.elem, f = b.next;+ if(b.hasOwnProperty("elem") && b.hasOwnProperty("next")) {+ var e = {elem:d, next:g(a - 1)(f)};+ b = function() {+ return e+ }+ }else {+ s(), b = i+ }+ return b()+ }}+ }+ s()+ }+ };+ this.zip_with = b;+ this._col_col_col = function(a) {+ return function(b) {+ return{seq:function() {+ return{elem:a, next:b()}+ }}+ }+ };+ this.tail = d = function(a) {+ if(a.hasOwnProperty("end")) {+ throw"tail called on empty seq";+ }+ var b = a.seq;+ if(a.hasOwnProperty("seq")) {+ return b().next+ }+ s()+ };+ var h = this.to_lazy = a, p = m({seq:function() {+ var a = b(function(a) {+ return function(b) {+ return a + b+ }+ })(n), c = d(n);+ return{elem:1, next:a(c)}+ }}), n;+ this.fibs = n = h({seq:function() {+ return{elem:1, next:p()}+ }})+ };+ this.Formal_Z = new function() {+ var a = l.map || window.map, b = l.concat_map || window.concat_map;+ this.map = a = function(a) {+ return function(b) {+ return function(d) {+ return a.map(d)(b)+ }+ }+ };+ this.bind = function(a) {+ return function(b) {+ var d = a.ret;+ if(a.hasOwnProperty("ret")) {+ return d(b)+ }+ s()+ }+ };+ var e = {map:function(a) {+ return function(b) {+ if(b.hasOwnProperty("nil")) {+ return{nil:j}+ }+ var d = b.head, g = b.tail;+ if(b.hasOwnProperty("head") && b.hasOwnProperty("tail")) {+ return{head:a(d), tail:e.map(a)(g)}+ }+ s()+ }+ }};+ this.list_functor = e;+ this.list_monad = {_grea_grea_eq:function(a) {+ return function(c) {+ return b(c)(a)+ }+ }, _return_:function(a) {+ return{head:a, tail:{nil:j}}+ }};+ this.js_monad = {_grea_grea_eq:function(a) {+ return function(b) {+ return b(a())+ }+ }, _return_:function(a) {+ return function() {+ return a+ }+ }}+ }+};+("undefined" == typeof global ? window : global).prelude = v;+("undefined" == typeof global ? window : global).parsec = new function() {+ function p(a) {+ return function(b) {+ b.unshift(a);+ return b+ }+ }+ function h(a) {+ return function(b) {+ var e = b.parser;+ if(b.hasOwnProperty("parser")) {+ return{parser:function(b) {+ var c = e(b);+ return a({f:e, f_apos:c, parsed:c.parsed, rest:c.rest, text:b})+ }}+ }+ s()+ }+ }+ var m = v._eq_eq || window._eq_eq;+ this.run_parser = function(a) {+ return function(b) {+ var e = a.parser;+ if(a.hasOwnProperty("parser")) {+ return b = e(b), e = b.parsed.some, b.hasOwnProperty("parsed") && b.parsed.hasOwnProperty("some") ? {some:e} : {none:j}+ }+ s()+ }+ };+ this._less$_grea = function(a) {+ return function(b) {+ var e = b.parser;+ if(b.hasOwnProperty("parser")) {+ return{parser:function(b) {+ var b = e(b), c = b.parsed.some, d = b.rest;+ b.hasOwnProperty("parsed") && b.hasOwnProperty("rest") && b.parsed.hasOwnProperty("some") ? b = {parsed:{some:a(c)}, rest:d} : (c = b.rest, b.hasOwnProperty("parsed") && b.hasOwnProperty("rest") && b.parsed.hasOwnProperty("none") ? b = {parsed:{none:j}, rest:c} : (s(), b = i));+ return b+ }}+ }+ s()+ }+ };+ this._less_star_grea = function(a) {+ return function(b) {+ var e = a.parser, f = b.parser;+ if(a.hasOwnProperty("parser") && b.hasOwnProperty("parser")) {+ return{parser:function(a) {+ var b = e(a), a = b.parsed.some, g = b.rest;+ if(b.hasOwnProperty("parsed") && b.hasOwnProperty("rest") && b.parsed.hasOwnProperty("some")) {+ var b = f(g), g = b.parsed.some, h = b.rest;+ b.hasOwnProperty("parsed") && b.hasOwnProperty("rest") && b.parsed.hasOwnProperty("some") ? a = {parsed:{some:a(g)}, rest:h} : (g = b.rest, b.hasOwnProperty("parsed") && b.hasOwnProperty("rest") && b.parsed.hasOwnProperty("none") ? a = {parsed:{none:j}, rest:g} : (s(), a = i))+ }else {+ a = b.rest, b.hasOwnProperty("parsed") && b.hasOwnProperty("rest") && b.parsed.hasOwnProperty("none") ? a = {parsed:{none:j}, rest:a} : (s(), a = i)+ }+ return a+ }}+ }+ s()+ }+ };+ this.lift = h;+ this._star_grea = function(a) {+ return function(b) {+ var e = a.parser, f = b.parser;+ if(a.hasOwnProperty("parser") && b.hasOwnProperty("parser")) {+ return{parser:function(a) {+ var a = e(a), b = a.parsed.some, b = a.rest;+ a.hasOwnProperty("parsed") && a.hasOwnProperty("rest") && a.parsed.hasOwnProperty("some") ? a = f(b) : (b = a.rest, a.hasOwnProperty("parsed") && a.hasOwnProperty("rest") && a.parsed.hasOwnProperty("none") ? a = {parsed:{none:j}, rest:b} : (s(), a = i));+ return a+ }}+ }+ s()+ }+ };+ this._less_or_grea = function(a) {+ return function(b) {+ var e = a.parser, f = b.parser;+ if(a.hasOwnProperty("parser") && b.hasOwnProperty("parser")) {+ return{parser:function(a) {+ var b = e(a), g = b.rest;+ return b.hasOwnProperty("parsed") && b.hasOwnProperty("rest") && b.parsed.hasOwnProperty("none") && m(a)(g) ? f(a) : b+ }}+ }+ s()+ }+ };+ this.try_apos = h(function(a) {+ return a.hasOwnProperty("parsed") && a.parsed.hasOwnProperty("none") ? {parsed:{none:j}, rest:a.text} : a.f_apos+ });+ this.string = function(a) {+ return{parser:function(b) {+ var e = b.substring(0, a.length);+ return m(e)(a) ? {parsed:{some:a}, rest:b.substring(a.length)} : {parsed:{none:j}, rest:b}+ }}+ };+ this.push_excl = p;+ var l = h(function(a) {+ var b = a;+ if(a.hasOwnProperty("parsed") && a.parsed.hasOwnProperty("none")) {+ return{parsed:{some:[]}, rest:b.rest}+ }+ b = a.parsed.some;+ if(a.hasOwnProperty("parsed") && a.parsed.hasOwnProperty("some")) {+ var e = p(b);+ var b = l({parser:a.f}), f = b.parser;+ b.hasOwnProperty("parser") ? b = {parser:function(a) {+ var a = f(a), b = a.parsed.some, g = a.rest;+ a.hasOwnProperty("parsed") && a.hasOwnProperty("rest") && a.parsed.hasOwnProperty("some") ? a = {parsed:{some:e(b)}, rest:g} : (b = a.rest, a.hasOwnProperty("parsed") && a.hasOwnProperty("rest") && a.parsed.hasOwnProperty("none") ? a = {parsed:{none:j}, rest:b} : (s(), a = i));+ return a+ }} : (s(), b = i);+ return b.parser(a.rest)+ }+ s()+ });+ this.many = l;+ this.Testing = new function() {+ }+};+("undefined" == typeof global ? window : global).Benchmarks_for_the_prelude = new function() {+ function p(b) {+ for(var d = i;"undefined" == typeof d;) {+ if(d = b, 3 > d) {+ d = 0+ }else {+ var d = b, g = i, g = a(d % 3)(0), e = a(d % 5)(0);+ g || e ? g = 1 + p(d - 1) : (b = d - 1, g = i);+ d = g+ }+ }+ return d+ }+ this.title = function(a) {+ return function() {+ return h(l("\r "))(function() {+ return h(l(a))(function() {+ return m(j)+ })+ })()+ }+ };+ var h = v._grea_grea_eq || window._grea_grea_eq, m = v._return_ || window._return_, l = v.log || window.log, a = v._eq_eq || window._eq_eq, b = v._comp_comp || window._comp_comp, e = v.filter || window.filter, f = v.sum || window.sum, b = v.list._comp_comp || window._comp_comp, e = v.list.filter || window.filter, f = v.list.sum || window.sum;+ this.euler_1 = function(a) {+ return function() {+ for(var b = 0, g = 1;g < a;) {+ if(0 == g % 3 || 0 == g % 5) {+ b += g+ }+ g+++ }+ return b+ }+ };+ this.euler_2 = function(b) {+ return function(d) {+ for(var g = i, e = b;"undefined" == typeof g;) {+ var g = e, f = d;+ if(3 > g) {+ g = f+ }else {+ var g = e, f = d, h = a(g % 3)(0), l = a(g % 5)(0);+ h || l ? (e = g - 1, d = f + 1) : (g = e, f = d, e = g - 1, d = f);+ g = i+ }+ }+ return g+ }+ };+ this.euler_3 = p;+ this.euler_4 = function(c) {+ return function() {+ var d = b(1)(c), d = e(function(b) {+ var c = a(b % 3)(0), b = a(b % 5)(0);+ return c || b+ })(d);+ return f(d)+ }+ };+ this.euler_5 = function(a) {+ return function(b) {+ for(var e = i, f = a;"undefined" == typeof e;) {+ var e = f, h = b;+ 3 > e ? e = h : (e = f, h = b, 0 == e % 3 || 0 == e % 5 ? (f = e - 1, b = h + 1) : (e = f, h = b, f = e - 1, b = h), e = i)+ }+ return e+ }+ }+};+("undefined" == typeof global ? window : global).Tests_for_partial_records = new function() {+};+var A = new function() {+ this.rev_1 = function(h) {+ for(var m = i, l = {nil:j};"undefined" == typeof m;) {+ var a = l;+ if(h.hasOwnProperty("nil")) {+ m = a+ }else {+ var a = l, b = h.head, e = h.tail;+ h.hasOwnProperty("head") && h.hasOwnProperty("tail") ? (l = {head:b, tail:a}, h = e, m = i) : s()+ }+ }+ return m+ };+ var p = {nil:j};+ this.rev_2 = function(h) {+ for(var m = i, l = p;"undefined" == typeof m;) {+ var a = l;+ if(h.hasOwnProperty("nil")) {+ m = a+ }else {+ var a = l, b = h.head, e = h.tail;+ h.hasOwnProperty("head") && h.hasOwnProperty("tail") ? (l = {head:b, tail:a}, h = e, m = i) : s()+ }+ }+ return m+ };+ this.test_x = {head:1, tail:{head:2, tail:{head:3, tail:{head:4, tail:{head:5, tail:{head:6, tail:{head:7, tail:{nil:j}}}}}}}}+};+("undefined" == typeof global ? window : global).Tests_for_TCO_bugs = A;+("undefined" == typeof global ? window : global).Tests_for_parser_bugs = new function() {+};++// Input 0+var is_array;+is_array = function(i) {+ return i instanceof Array+};+var __undefined__;+__undefined__ = "undefined";+var run;+run = function(i) {+ return i()+};+var error;+error = function(i) {+ throw i;+};+var exhaust;+exhaust = function() {+ error("Pattern Match Exhausted")+};+var __check;+__check = function(i, g) {+ return i.hasOwnProperty(g)+};+describe("", function() {+ describe("prelude", function() {+ var i;+ i = prelude.array_;+ var g;+ g = prelude._eq_eq;+ var e;+ e = prelude.fib;+ var a;+ a = prelude.speedtest;+ var c;+ c = prelude.id;+ var d;+ d = prelude.err;+ var f;+ f = prelude.list;+ i = prelude.array_;+ g = prelude._eq_eq;+ e = prelude.fib;+ a = prelude.speedtest;+ c = prelude.id;+ d = prelude.err;+ f = prelude.list;+ new function() {+ it("122_122__::__ not false", function() {+ expect(function() {+ try {+ var b;+ b = run(function() {+ return run(function() {+ return!0+ })+ });+ return b+ }catch(n) {+ return{error:n}+ }+ }()).toEqual(!0)+ });+ it("125_125__::__ object? {}", function() {+ expect(function() {+ try {+ var b;+ var n = {};+ b = run(function() {+ return run(function() {+ return"object" === typeof n+ })+ });+ return b+ }catch(a) {+ return{error:a}+ }+ }()).toEqual(!0)+ });+ it("126_126__::__ array? []", function() {+ expect(function() {+ try {+ return i([])+ }catch(b) {+ return{error:b}+ }+ }()).toEqual(!0)+ });+ it("127_127__::__ not (array? {})", function() {+ expect(function() {+ try {+ var b;+ var n = i({});+ b = run(function() {+ return run(function() {+ return!n+ })+ });+ return b+ }catch(a) {+ return{error:a}+ }+ }()).toEqual(!0)+ });+ it("128_128__::__ not (object? 0)", function() {+ expect(function() {+ try {+ var b;+ b = run(function() {+ return run(function() {+ return!1+ })+ });+ var n;+ n = run(function() {+ return run(function() {+ return!b+ })+ });+ return n+ }catch(a) {+ return{error:a}+ }+ }()).toEqual(!0)+ });+ it("149_152multi__::__ do! x <- `1 + 4`\n y <- `2 + 3`\n ans <- `x + y`\n return (10 == ans)", function() {+ expect(function() {+ try {+ return run(function() {+ var b = run, a = run(function() {+ return 5+ }), c = run(function() {+ return 5+ }), h = run(function() {+ return a + c+ }), f = g(10)(h);+ return b(function() {+ return f+ })+ })+ }catch(b) {+ return{error:b}+ }+ }()).toEqual(!0)+ });+ it("154_154__::__ 5 == do! return 5", function() {+ expect(5).toEqual(run(function() {+ return run(function() {+ return 5+ })+ }))+ });+ it("155_155__::__ 10 == do! `5 + 5`", function() {+ expect(10).toEqual(run(function() {+ return run(function() {+ return 10+ })+ }))+ });+ it("166_169multi__::__ var x = 0\n y = do z <- `x = 1`\n return z\n x == 0", function() {+ expect(function() {+ try {+ return g(0)(0)+ }catch(b) {+ return{error:b}+ }+ }()).toEqual(!0)+ });+ it("226_226__::__ (3 * 4) + 5 * 4 == 64 / 2", function() {+ expect(function(b) {+ return function(a) {+ return run(function() {+ return run(function() {+ return b + a+ })+ })+ }+ }(function(b) {+ return function(a) {+ return run(function() {+ return run(function() {+ return b * a+ })+ })+ }+ }(3)(4))(function(b) {+ return function(a) {+ return run(function() {+ return run(function() {+ return b * a+ })+ })+ }+ }(5)(4))).toEqual(function(b) {+ return function(a) {+ return run(function() {+ return run(function() {+ return b / a+ })+ })+ }+ }(64)(2))+ });+ it("227_227__::__ 4 - 1 != 5 - 10", function() {+ expect(function() {+ try {+ var b;+ b = run(function() {+ return run(function() {+ return 3+ })+ });+ var a = run(function() {+ return run(function() {+ return-5+ })+ }), c = g(b)(a);+ return run(function() {+ return run(function() {+ return!c+ })+ })+ }catch(f) {+ return{error:f}+ }+ }()).toEqual(!0)+ });+ it("228_228__::__ (10 >= 5 + 5) != (4 + 5 <= 10 - 2)", function() {+ expect(function() {+ try {+ var b, a = run(function() {+ return run(function() {+ return 10+ })+ });+ b = run(function() {+ return run(function() {+ return 10 >= a+ })+ });+ var c;+ c = run(function() {+ return run(function() {+ return 9+ })+ });+ var f = run(function() {+ return run(function() {+ return 8+ })+ }), h = run(function() {+ return run(function() {+ return c <= f+ })+ }), d = g(b)(h);+ return run(function() {+ return run(function() {+ return!d+ })+ })+ }catch(e) {+ return{error:e}+ }+ }()).toEqual(!0)+ });+ it("229_229__::__ ({test: 1} == {test: 1}) == true", function() {+ expect(g({test:1})({test:1})).toEqual(!0)+ });+ it("230_230__::__ ({test: 1} != {test: 1}) == false", function() {+ expect(function(b) {+ return function(a) {+ var c = g(b)(a);+ return run(function() {+ return run(function() {+ return!c+ })+ })+ }+ }({test:1})({test:1})).toEqual(!1)+ });+ describe("speedtest", function() {+ var b;+ b = prelude.speedtest.time;+ var a;+ a = prelude.speedtest.fast_fib;+ var c;+ c = prelude.speedtest.floor;+ b = prelude.speedtest.time;+ a = prelude.speedtest.fast_fib;+ c = prelude.speedtest.floor;+ new function() {+ it("262_262__::__ fast_fib 7 == fib 7", function() {+ expect(a(7)).toEqual(e(7))+ });+ it("271_273multi__::__ do! fast_time <- time yield fast_fib 30\n slow_time <- time yield fib 30\n return (floor (fast_time / slow_time * 100) >= 80)", function() {+ expect(function() {+ try {+ return run(function() {+ var f = run, d = b(function() {+ return a(30)+ }), g = run(d), d = b(function() {+ return e(30)+ }), j = run(d), d = c, m;+ m = run(function() {+ return run(function() {+ return g / j+ })+ });+ var k;+ k = run(function() {+ return run(function() {+ return 100 * m+ })+ });+ var p = d(k), s;+ s = run(function() {+ return run(function() {+ return 80 <= p+ })+ });+ return f(function() {+ return s+ })+ })+ }catch(f) {+ return{error:f}+ }+ }()).toEqual(!0)+ })+ }+ });+ it("282_282__::__ 3 |> (\u03bby = y + 1) |> \u03bby = y + 1 == 5", function() {+ expect(function() {+ try {+ var b;+ b = run(function() {+ return run(function() {+ return 4+ })+ });+ var a = g, c;+ c = run(function() {+ return run(function() {+ return b + 1+ })+ });+ return a(c)(5)+ }catch(f) {+ return{error:f}+ }+ }()).toEqual(!0)+ });+ it("283_283__::__ (\u03bby x z = x + y + z + 1) 1 <| 3 <| 4 == 9", function() {+ expect(function(b) {+ return function(a) {+ return b(a)+ }+ }(function(b) {+ return function(a) {+ return b(a)+ }+ }(function(b) {+ return function(a) {+ return function(c) {+ var f;+ f = run(function() {+ return run(function() {+ return a + b+ })+ });+ var h;+ h = run(function() {+ return run(function() {+ return f + c+ })+ });+ return run(function() {+ return run(function() {+ return h + 1+ })+ })+ }+ }+ }(1))(3))(4)).toEqual(9)+ });+ it("290_290__::__ (\u03bbx = x - 3) <: (\u03bbx = x - 3) <: 5 + 5 == 4", function() {+ expect(function(b) {+ return function(a) {+ return b(a)+ }+ }(function(b) {+ return run(function() {+ return run(function() {+ return b - 3+ })+ })+ })(function(b) {+ return function(a) {+ return b(a)+ }+ }(function(b) {+ return run(function() {+ return run(function() {+ return b - 3+ })+ })+ })(function(b) {+ return function(a) {+ return run(function() {+ return run(function() {+ return b + a+ })+ })+ }+ }(5)(5)))).toEqual(4)+ });+ it("301_301__::__ ((\u03bbx = x + 1) .: (\u03bbx = x * 2) .: \u03bbx = x - 3) 4 == 3", function() {+ expect(function(b) {+ return function(a) {+ return function(c) {+ return b(a(c))+ }+ }+ }(function(b) {+ return run(function() {+ return run(function() {+ return b + 1+ })+ })+ })(function(b) {+ return function(a) {+ return function(c) {+ return b(a(c))+ }+ }+ }(function(b) {+ return run(function() {+ return run(function() {+ return 2 * b+ })+ })+ })(function(b) {+ return run(function() {+ return run(function() {+ return b - 3+ })+ })+ }))(4)).toEqual(3)+ });+ it("302_302__::__ id [1, 2, 3] == [1, 2, 3]", function() {+ expect([1, 2, 3]).toEqual([1, 2, 3])+ });+ it("303_303__::__ flip (\u03bbx y = x - y) 3 5 == 2", function() {+ expect(function(b) {+ return function(a) {+ return function(c) {+ return b(c)(a)+ }+ }+ }(function(b) {+ return function(a) {+ return run(function() {+ return run(function() {+ return b - a+ })+ })+ }+ })(3)(5)).toEqual(2)+ });+ describe("string", function() {+ var b;+ b = b = prelude.string.strip;+ new function() {+ it('323_323__::__ strip " test " is "test"', function() {+ expect(b(" test ")).toEqual("test")+ });+ it('327_328multi__::__ let x = "test"\n in "hello `x`" is "hello test"', function() {+ expect(function() {+ try {+ var b = g, a;+ a = run(function() {+ return run(function() {+ return"hello test"+ })+ });+ var c;+ c = run(function() {+ return run(function() {+ return"" + a + ""+ })+ });+ return b(c)("hello test")+ }catch(f) {+ return{error:f}+ }+ }()).toEqual(!0)+ })+ }+ });+ describe("option", function() {+ var b;+ b = b = prelude.option.option;+ new function() {+ it("353_353__::__ option 3 {some: 2} == 2", function() {+ expect(b(3)({some:2})).toEqual(2)+ })+ }+ });+ describe("html", function() {+ var b;+ b = prelude.html.get;+ var a;+ a = prelude.html.div;+ b = prelude.html.get;+ a = prelude.html.div;+ new function() {+ it('426_436multi__::__ do! d <- div "test1"\n \n "body" $+ d\n "#test1" $= "I am a test!"\n \n text <- get "#test1"\n text <- text.inner\n \n "#test1" $= ""\n \n return (text == "I am a test!")', function() {+ expect(function() {+ try {+ return run(function() {+ var c = run, f = a("test1"), d = run(f);+ run(function() {+ return $("body").append(d)+ });+ run(function() {+ if("undefined" != typeof $) {+ var a;+ a = $("#test1").get(0);+ "undefined" != typeof a && (a.innerHTML = "I am a test!")+ }+ });+ f = b("#test1");+ f = run(f).inner;+ f = run(f);+ run(function() {+ if("undefined" != typeof $) {+ var a;+ a = $("#test1").get(0);+ "undefined" != typeof a && (a.innerHTML = "")+ }+ });+ var e = g(f)("I am a test!");+ return c(function() {+ return e+ })+ })+ }catch(c) {+ return{error:c}+ }+ }()).toEqual(!0)+ })+ }+ });+ describe("list", function() {+ var a;+ a = prelude.list.empty_;+ var f;+ f = prelude.list.head;+ var e;+ e = prelude.list.tail;+ var k;+ k = prelude.list.last;+ var h;+ h = prelude.list.take;+ var i;+ i = prelude.list.drop;+ var l;+ l = prelude.list._comp_comp;+ var j;+ j = prelude.list.take_while;+ var m;+ m = prelude.list.drop_while;+ var r;+ r = prelude.list.length;+ var p;+ p = prelude.list.init;+ var s;+ s = prelude.list._plus_plus;+ var w;+ w = prelude.list.filter;+ var x;+ x = prelude.list.map;+ var t;+ t = prelude.list.reverse;+ var B;+ B = prelude.list.take_apos;+ var y;+ y = prelude.list.foldl;+ var C;+ C = prelude.list.foldr;+ var u;+ u = prelude.list.all_;+ var v;+ v = prelude.list.any_;+ var z;+ z = prelude.list.sum;+ var D;+ D = prelude.list.product;+ var A;+ A = prelude.list.concat;+ var H;+ H = prelude.list.concat_map;+ var F;+ F = prelude.list.maximum;+ var G;+ G = prelude.list.minimum;+ a = prelude.list.empty_;+ f = prelude.list.head;+ e = prelude.list.tail;+ k = prelude.list.last;+ h = prelude.list.take;+ i = prelude.list.drop;+ l = prelude.list._comp_comp;+ j = prelude.list.take_while;+ m = prelude.list.drop_while;+ r = prelude.list.length;+ p = prelude.list.init;+ s = prelude.list._plus_plus;+ w = prelude.list.filter;+ x = prelude.list.map;+ t = prelude.list.reverse;+ B = prelude.list.take_apos;+ y = prelude.list.foldl;+ C = prelude.list.foldr;+ u = prelude.list.all_;+ v = prelude.list.any_;+ z = prelude.list.sum;+ D = prelude.list.product;+ A = prelude.list.concat;+ H = prelude.list.concat_map;+ F = prelude.list.maximum;+ G = prelude.list.minimum;+ new function() {+ it("573_587multi__::__ var xs = [:\n \n [:1,2,3]\n \n [:1,2,3:]\n \n (1::2::3::{nil})\n \n { head = 1\n tail = { head = 2\n tail = { head = 3\n tail = {nil} }}}\n ]\n \n all? (\u03bby = [:1,2,3] == y) xs", function() {+ expect(function() {+ try {+ return u(function(a) {+ return g({head:1, tail:{head:2, tail:{head:3, tail:{nil:!0}}}})(a)+ })({head:{head:1, tail:{head:2, tail:{head:3, tail:{nil:!0}}}}, tail:{head:{head:1, tail:{head:2, tail:{head:3, tail:{nil:!0}}}}, tail:{head:{head:1, tail:{head:2, tail:{head:3, tail:{nil:!0}}}}, tail:{head:{head:1, tail:{head:2, tail:{head:3, tail:{nil:!0}}}}, tail:{nil:!0}}}}})+ }catch(a) {+ return{error:a}+ }+ }()).toEqual(!0)+ });+ it("614_614__::__ 1 .. 5 == [:1,2,3,4,5]", function() {+ expect(l(1)(5)).toEqual({head:1, tail:{head:2, tail:{head:3, tail:{head:4, tail:{head:5, tail:{nil:!0}}}}}})+ });+ it("618_618__::__ 288045 == 1 .. 1111 |> filter (\u03bbx = x % 3 == 0 || x % 5 == 0) |> sum", function() {+ expect(288045).toEqual(function(a) {+ return function(b) {+ return b(a)+ }+ }(function(a) {+ return function(b) {+ return b(a)+ }+ }(l(1)(1111))(w(function(a) {+ var b = g, c;+ c = run(function() {+ return run(function() {+ return a % 3+ })+ });+ var f = b(c)(0), b = g;+ c = run(function() {+ return run(function() {+ return a % 5+ })+ });+ var j = b(c)(0);+ return run(function() {+ return run(function() {+ return f || j+ })+ })+ })))(z))+ });+ it("629_629__::__ not (empty? (1 :: {nil}))", function() {+ expect(function() {+ try {+ var c;+ var f = a({head:1, tail:{nil:!0}});+ c = run(function() {+ return run(function() {+ return!f+ })+ });+ return c+ }catch(j) {+ return{error:j}+ }+ }()).toEqual(!0)+ });+ it("630_630__::__ empty? [:]", function() {+ expect(function() {+ try {+ return a({nil:!0})+ }catch(c) {+ return{error:c}+ }+ }()).toEqual(!0)+ });+ it("632_632__::__ head [: 1, 2 ] is 1", function() {+ expect(f({head:1, tail:{head:2, tail:{nil:!0}}})).toEqual(1)+ });+ it("633_633__::__ tail [: 1, 2 ] is [:2]", function() {+ expect(e({head:1, tail:{head:2, tail:{nil:!0}}})).toEqual({head:2, tail:{nil:!0}})+ });+ it("634_634__::__ last [: 1, 2 ] is 2", function() {+ expect(k({head:1, tail:{head:2, tail:{nil:!0}}})).toEqual(2)+ });+ it('636_636__::__ err (lazy head {nil}) is "Head called on empty list"', function() {+ expect(d(function() {+ var a;+ a = void 0;+ return function() {+ a || (a = f({nil:!0}));+ return a+ }+ }())).toEqual("Head called on empty list")+ });+ it('637_637__::__ err (lazy tail {nil}) is "Tail called on empty list"', function() {+ expect(d(function() {+ var a;+ a = void 0;+ return function() {+ a || (a = e({nil:!0}));+ return a+ }+ }())).toEqual("Tail called on empty list")+ });+ it('638_638__::__ err (lazy last {nil}) is "Last called on empty list"', function() {+ expect(d(function() {+ var a;+ a = void 0;+ return function() {+ a || (a = k({nil:!0}));+ return a+ }+ }())).toEqual("Last called on empty list")+ });+ it("640_640__::__ take(2, [: 1, 2, 3 ]) == [: 1, 2 ]", function() {+ expect(h(2)({head:1, tail:{head:2, tail:{head:3, tail:{nil:!0}}}})).toEqual({head:1, tail:{head:2, tail:{nil:!0}}})+ });+ it("641_641__::__ drop(2, [: 1, 2, 3 ]) == [: 3 ]", function() {+ expect(i(2)({head:1, tail:{head:2, tail:{head:3, tail:{nil:!0}}}})).toEqual({head:3, tail:{nil:!0}})+ });+ it("643_643__::__ take_while (\u03bbx = x < 0) [:] == [:]", function() {+ expect(j(function(a) {+ return run(function() {+ return run(function() {+ return 0 > a+ })+ })+ })({nil:!0})).toEqual({nil:!0})+ });+ it("644_644__::__ take_while (\u03bbx = x > 0) [: 2, 1, 0 ] == [: 2, 1 ]", function() {+ expect(j(function(a) {+ return run(function() {+ return run(function() {+ return 0 < a+ })+ })+ })({head:2, tail:{head:1, tail:{head:0, tail:{nil:!0}}}})).toEqual({head:2, tail:{head:1, tail:{nil:!0}}})+ });+ it("646_646__::__ drop_while (\u03bbx = x < 0) {nil} == {nil}", function() {+ expect(m(function(a) {+ return run(function() {+ return run(function() {+ return 0 > a+ })+ })+ })({nil:!0})).toEqual({nil:!0})+ });+ it("647_647__::__ drop_while (\u03bbx = x > 0) [: 2, 1, 0 ] == [: 0 ]", function() {+ expect(m(function(a) {+ return run(function() {+ return run(function() {+ return 0 < a+ })+ })+ })({head:2, tail:{head:1, tail:{head:0, tail:{nil:!0}}}})).toEqual({head:0, tail:{nil:!0}})+ });+ it("656_656__::__ length [: 1, 2, 3, 4 ] == 4", function() {+ expect(r({head:1, tail:{head:2, tail:{head:3, tail:{head:4, tail:{nil:!0}}}}})).toEqual(4)+ });+ it("663_663__::__ length (init 30 0) == 30", function() {+ expect(r(p(30)(0))).toEqual(30)+ });+ it("664_664__::__ tail (init 3 0) == init 2 0", function() {+ expect(e(p(3)(0))).toEqual(p(2)(0))+ });+ it("673_673__::__ {nil} ++ (1 :: 2 :: {nil}) == 1 :: 2 :: {nil}", function() {+ expect(s({nil:!0})(function(a) {+ return function(b) {+ return{head:a, tail:b}+ }+ }(1)(function(a) {+ return function(b) {+ return{head:a, tail:b}+ }+ }(2)({nil:!0})))).toEqual(function(a) {+ return function(b) {+ return{head:a, tail:b}+ }+ }(1)(function(a) {+ return function(b) {+ return{head:a, tail:b}+ }+ }(2)({nil:!0})))+ });+ it("674_674__::__ [: 1, 2 ] ++ [: 3, 4 ] == [: 1, 2, 3, 4 ]", function() {+ expect(s({head:1, tail:{head:2, tail:{nil:!0}}})({head:3, tail:{head:4, tail:{nil:!0}}})).toEqual({head:1, tail:{head:2, tail:{head:3, tail:{head:4, tail:{nil:!0}}}}})+ });+ it("683_683__::__ [: 1, 2, 3, 4 ] 'filter (\u03bbx = x > 2) == [: 3, 4 ]", function() {+ expect(function(a) {+ return function(b) {+ return b(a)+ }+ }({head:1, tail:{head:2, tail:{head:3, tail:{head:4, tail:{nil:!0}}}}})(w(function(a) {+ return run(function() {+ return run(function() {+ return 2 < a+ })+ })+ }))).toEqual({head:3, tail:{head:4, tail:{nil:!0}}})+ });+ it("690_690__::__ [: 2, 3, 4 ] == [: 1, 2, 3 ] |> map \u03bbx = x + 1", function() {+ expect({head:2, tail:{head:3, tail:{head:4, tail:{nil:!0}}}}).toEqual(function(a) {+ return function(b) {+ return b(a)+ }+ }({head:1, tail:{head:2, tail:{head:3, tail:{nil:!0}}}})(x(function(a) {+ return run(function() {+ return run(function() {+ return a + 1+ })+ })+ })))+ });+ it("701_701__::__ reverse [: 1, 2, 3, 4 ] == [: 4, 3, 2, 1 ]", function() {+ expect(t({head:1, tail:{head:2, tail:{head:3, tail:{head:4, tail:{nil:!0}}}}})).toEqual({head:4, tail:{head:3, tail:{head:2, tail:{head:1, tail:{nil:!0}}}}})+ });+ it("703_704multi__::__ var test_x = [: 1, 2, 3, 4 ]\n test_x == reverse <| reverse test_x", function() {+ expect(function() {+ try {+ var a;+ a = {head:1, tail:{head:2, tail:{head:3, tail:{head:4, tail:{nil:!0}}}}};+ var b = g(a), c = t, f, j = t(a);+ f = c(j);+ return b(f)+ }catch(d) {+ return{error:d}+ }+ }()).toEqual(!0)+ });+ it("712_713multi__::__ var x = [: 1, 2, 3, 4, 5, 6, 7, 8 ]\n take 5 x == take' 5 x", function() {+ expect(function() {+ try {+ var a;+ a = {head:1, tail:{head:2, tail:{head:3, tail:{head:4, tail:{head:5, tail:{head:6, tail:{head:7, tail:{head:8, tail:{nil:!0}}}}}}}}};+ return g(h(5)(a))(B(5)(a))+ }catch(b) {+ return{error:b}+ }+ }()).toEqual(!0)+ });+ it("747_747__::__ foldl (\u03bbx y = x + y) 0 [: 1, 2, 3, 4 ] == 10", function() {+ expect(y(function(a) {+ return function(b) {+ return run(function() {+ return run(function() {+ return a + b+ })+ })+ }+ })(0)({head:1, tail:{head:2, tail:{head:3, tail:{head:4, tail:{nil:!0}}}}})).toEqual(10)+ });+ it("748_748__::__ foldr (\u03bbx y = x + y) 0 [: 1, 2, 3, 4 ] == 10", function() {+ expect(C(function(a) {+ return function(b) {+ return run(function() {+ return run(function() {+ return a + b+ })+ })+ }+ })(0)({head:1, tail:{head:2, tail:{head:3, tail:{head:4, tail:{nil:!0}}}}})).toEqual(10)+ });+ it("749_749__::__ all? id [:true,true]", function() {+ expect(function() {+ try {+ return u(c)({head:!0, tail:{head:!0, tail:{nil:!0}}})+ }catch(a) {+ return{error:a}+ }+ }()).toEqual(!0)+ });+ it("750_750__::__ not (all? id [:true,false])", function() {+ expect(function() {+ try {+ var a;+ var b = u(c)({head:!0, tail:{head:!1, tail:{nil:!0}}});+ a = run(function() {+ return run(function() {+ return!b+ })+ });+ return a+ }catch(f) {+ return{error:f}+ }+ }()).toEqual(!0)+ });+ it("751_751__::__ any? id [:true,false]", function() {+ expect(function() {+ try {+ return v(c)({head:!0, tail:{head:!1, tail:{nil:!0}}})+ }catch(a) {+ return{error:a}+ }+ }()).toEqual(!0)+ });+ it("752_752__::__ not (any? id [:false,false])", function() {+ expect(function() {+ try {+ var a;+ var b = v(c)({head:!1, tail:{head:!1, tail:{nil:!0}}});+ a = run(function() {+ return run(function() {+ return!b+ })+ });+ return a+ }catch(f) {+ return{error:f}+ }+ }()).toEqual(!0)+ });+ it("753_753__::__ sum [:1,2,3] == 6", function() {+ expect(z({head:1, tail:{head:2, tail:{head:3, tail:{nil:!0}}}})).toEqual(6)+ });+ it("754_754__::__ product [:1,2,4] == 8", function() {+ expect(D({head:1, tail:{head:2, tail:{head:4, tail:{nil:!0}}}})).toEqual(8)+ });+ it("756_757multi__::__ let x = [:1,2], y = [:3,4]\n concat [:x,y] == [:1,2,3,4]", function() {+ expect(function() {+ try {+ return g(A({head:{head:1, tail:{head:2, tail:{nil:!0}}}, tail:{head:{head:3, tail:{head:4, tail:{nil:!0}}}, tail:{nil:!0}}}))({head:1, tail:{head:2, tail:{head:3, tail:{head:4, tail:{nil:!0}}}}})+ }catch(a) {+ return{error:a}+ }+ }()).toEqual(!0)+ });+ it("759_759__::__ concat_map (\u03bbx = [:x,x+1]) [:1,2] == [:1,2,2,3]", function() {+ expect(H(function(a) {+ var b;+ b = run(function() {+ return run(function() {+ return a + 1+ })+ });+ return{head:a, tail:{head:b, tail:{nil:!0}}}+ })({head:1, tail:{head:2, tail:{nil:!0}}})).toEqual({head:1, tail:{head:2, tail:{head:2, tail:{head:3, tail:{nil:!0}}}}})+ });+ it("761_761__::__ minimum [: 1, 2, 3 ] == 1", function() {+ expect(G({head:1, tail:{head:2, tail:{head:3, tail:{nil:!0}}}})).toEqual(1)+ });+ it("762_762__::__ maximum [: 1, 2, 3 ] == 3", function() {+ expect(F({head:1, tail:{head:2, tail:{head:3, tail:{nil:!0}}}})).toEqual(3)+ })+ }+ });+ describe("seq", function() {+ var b;+ b = prelude.seq.iterate;+ var c;+ c = prelude.seq.from_list;+ var d;+ d = prelude.seq.to_list;+ var e;+ e = prelude.seq.take;+ var h;+ h = prelude.seq.fibs;+ var g;+ g = f.last || window.last;+ e = f.take || window.take;+ var l;+ l = f.length || window.length;+ var j;+ j = a.time || window.time;+ var m;+ m = a.fast_fib || window.fast_fib;+ var i;+ i = a.floor || window.floor;+ b = prelude.seq.iterate;+ c = prelude.seq.from_list;+ d = prelude.seq.to_list;+ e = prelude.seq.take;+ h = prelude.seq.fibs;+ new function() {+ it("798_798__::__ to_list (from_list [:1,2]) == [:1,2]", function() {+ expect(d(c({head:1, tail:{head:2, tail:{nil:!0}}}))).toEqual({head:1, tail:{head:2, tail:{nil:!0}}})+ });+ it("799_799__::__ iterate (\u03bbx = x + 1) 0 |> take 100 |> to_list |> length == 100", function() {+ expect(function(a) {+ return function(b) {+ return b(a)+ }+ }(function(a) {+ return function(b) {+ return b(a)+ }+ }(function(a) {+ return function(b) {+ return b(a)+ }+ }(b(function(a) {+ return run(function() {+ return run(function() {+ return a + 1+ })+ })+ })(0))(e(100)))(d))(l)).toEqual(100)+ });+ it('835_839multi__::__ do! fast_time <- time yield fast_fib 30\n slow_time <- time yield fibs |> take 30 |> to_list |> last\n let ratio = floor (fast_time / slow_time * 100)\n "#speedtest" $= ratio\n return (ratio >= 2)', function() {+ expect(function() {+ try {+ return run(function() {+ var a = run, b = j(function() {+ return m(30)+ }), c = run(b), b = j(function() {+ var a = h, a = e(30)(a), a = d(a);+ return g(a)+ }), f, p, l = run(b);+ p = run(function() {+ return run(function() {+ return c / l+ })+ });+ b = run(function() {+ return run(function() {+ return 100 * p+ })+ });+ f = i(b);+ run(function() {+ if("undefined" != typeof $) {+ var a;+ a = $("#speedtest").get(0);+ "undefined" != typeof a && (a.innerHTML = f)+ }+ });+ var n;+ n = run(function() {+ return run(function() {+ return 2 <= f+ })+ });+ return a(function() {+ return n+ })+ })+ }catch(a) {+ return{error:a}+ }+ }()).toEqual(!0)+ });+ it("841_841__::__ fibs |> take 5 |> to_list == [:1,1,2,3,5]", function() {+ expect(function(a) {+ return function(b) {+ return b(a)+ }+ }(function(a) {+ return function(b) {+ return b(a)+ }+ }(h)(e(5)))(d)).toEqual({head:1, tail:{head:1, tail:{head:2, tail:{head:3, tail:{head:5, tail:{nil:!0}}}}}})+ });+ it("843_845multi__::__ fast_fib 15 == fibs |> take 15\n |> to_list\n |> last", function() {+ expect(m(15)).toEqual(function(a) {+ return function(b) {+ return b(a)+ }+ }(function(a) {+ return function(b) {+ return b(a)+ }+ }(function(a) {+ return function(b) {+ return b(a)+ }+ }(h)(e(15)))(d))(g))+ })+ }+ });+ describe("Formal Z", function() {+ var a;+ a = f._comp_comp || window._comp_comp;+ var c;+ c = f.concat_map || window.concat_map;+ new function() {+ it("890_893multi__::__ let (>>>=) x g = concat_map g x\n z = 1..3 >>>= \u03bbx = [:x,x+1,x+2]\n \n z == [:1,2,3,2,3,4,3,4,5]", function() {+ expect(function() {+ try {+ var f, d = a(1)(3);+ f = c(function(a) {+ var b = run(function() {+ return run(function() {+ return a + 1+ })+ }), c;+ c = run(function() {+ return run(function() {+ return a + 2+ })+ });+ return{head:a, tail:{head:b, tail:{head:c, tail:{nil:!0}}}}+ })(d);+ return g(f)({head:1, tail:{head:2, tail:{head:3, tail:{head:2, tail:{head:3, tail:{head:4, tail:{head:3, tail:{head:4, tail:{head:5, tail:{nil:!0}}}}}}}}}})+ }catch(e) {+ return{error:e}+ }+ }()).toEqual(!0)+ })+ }+ })+ }+ })+});+describe("", function() {+ describe("parsec", function() {+ var i;+ i = parsec.try_apos;+ var g;+ g = parsec.many;+ var e;+ e = prelude._eq_eq || window._eq_eq;+ i = parsec.try_apos;+ g = parsec.many;+ new function() {+ describe("Testing", function() {+ new function() {+ it('141_141__::__ {some = "ten"} == run_parser (string "ten") "tens"', function() {+ expect({some:"ten"}).toEqual(function(a) {+ return function(c) {+ var d;+ d = a.parser;+ if(__check(a, "parser")) {+ return c = d(c), d = c.parsed.some, __check(c, "parsed") && __check(c.parsed, "some") ? {some:d} : {none:!0}+ }+ exhaust()+ }+ }(function(a) {+ return{parser:function(c) {+ var d;+ d = run(function() {+ return run(function() {+ return c.substring(0, a.length)+ })+ });+ return e(d)(a) ? {parsed:{some:a}, rest:run(function() {+ return run(function() {+ return c.substring(a.length)+ })+ })} : {parsed:{none:!0}, rest:c}+ }}+ }("ten"))("tens"))+ });+ it('142_142__::__ {some = "tenten"} == run_parser ((\u03bbx = x +++ x) <$> string "ten") "tenfingers"', function() {+ expect({some:"tenten"}).toEqual(function(a) {+ return function(c) {+ var d;+ d = a.parser;+ if(__check(a, "parser")) {+ return c = d(c), d = c.parsed.some, __check(c, "parsed") && __check(c.parsed, "some") ? {some:d} : {none:!0}+ }+ exhaust()+ }+ }(function(a) {+ return function(c) {+ var d;+ d = c.parser;+ if(__check(c, "parser")) {+ return{parser:function(c) {+ var c = d(c), b;+ b = c.parsed.some;+ var e;+ e = c.rest;+ __check(c, "parsed") && __check(c, "rest") && __check(c.parsed, "some") ? c = {parsed:{some:a(b)}, rest:e} : (b = c.rest, __check(c, "parsed") && __check(c, "rest") && __check(c.parsed, "none") ? c = {parsed:{none:!0}, rest:b} : (exhaust(), c = void 0));+ return c+ }}+ }+ exhaust()+ }+ }(function(a) {+ return run(function() {+ return run(function() {+ return"" + a + a+ })+ })+ })(function(a) {+ return{parser:function(c) {+ var d;+ d = run(function() {+ return run(function() {+ return c.substring(0, a.length)+ })+ });+ return e(d)(a) ? {parsed:{some:a}, rest:run(function() {+ return run(function() {+ return c.substring(a.length)+ })+ })} : {parsed:{none:!0}, rest:c}+ }}+ }("ten")))("tenfingers"))+ });+ it('144_145multi__::__ {parsed = {some = "tenten"}, rest = "fingers"} \n == ((\u03bbx = x +++ x) <$> string "ten").parser "tenfingers"', function() {+ expect({parsed:{some:"tenten"}, rest:"fingers"}).toEqual(function(a) {+ return function(c) {+ var d;+ d = c.parser;+ if(__check(c, "parser")) {+ return{parser:function(c) {+ var c = d(c), b;+ b = c.parsed.some;+ var e;+ e = c.rest;+ __check(c, "parsed") && __check(c, "rest") && __check(c.parsed, "some") ? c = {parsed:{some:a(b)}, rest:e} : (b = c.rest, __check(c, "parsed") && __check(c, "rest") && __check(c.parsed, "none") ? c = {parsed:{none:!0}, rest:b} : (exhaust(), c = void 0));+ return c+ }}+ }+ exhaust()+ }+ }(function(a) {+ return run(function() {+ return run(function() {+ return"" + a + a+ })+ })+ })(function(a) {+ return{parser:function(c) {+ var d;+ d = run(function() {+ return run(function() {+ return c.substring(0, a.length)+ })+ });+ return e(d)(a) ? {parsed:{some:a}, rest:run(function() {+ return run(function() {+ return c.substring(a.length)+ })+ })} : {parsed:{none:!0}, rest:c}+ }}+ }("ten")).parser("tenfingers"))+ });+ it('147_148multi__::__ var result = run_parser ((\u03bbx y = y +++ x) <$> string "ten" <*> string "fingers") "tenfingers"\n result == {some: "fingersten"}', function() {+ expect(function() {+ try {+ var a, c;+ var d = {parser:function(a) {+ var b;+ b = run(function() {+ return run(function() {+ return a.substring(0, 3)+ })+ });+ return e(b)("ten") ? {parsed:{some:"ten"}, rest:run(function() {+ return run(function() {+ return a.substring(3)+ })+ })} : {parsed:{none:!0}, rest:a}+ }}, f;+ f = d.parser;+ __check(d, "parser") ? c = {parser:function(a) {+ var a = f(a), b;+ b = a.parsed.some;+ var c;+ c = a.rest;+ if(__check(a, "parsed") && __check(a, "rest") && __check(a.parsed, "some")) {+ var d = b, a = {parsed:{some:function(a) {+ return run(function() {+ return run(function() {+ return"" + a + d+ })+ })+ }}, rest:c}+ }else {+ b = a.rest, __check(a, "parsed") && __check(a, "rest") && __check(a.parsed, "none") ? a = {parsed:{none:!0}, rest:b} : (exhaust(), a = void 0)+ }+ return a+ }} : (exhaust(), c = void 0);+ var b;+ var d = {parser:function(a) {+ var b;+ b = run(function() {+ return run(function() {+ return a.substring(0, 7)+ })+ });+ return e(b)("fingers") ? {parsed:{some:"fingers"}, rest:run(function() {+ return run(function() {+ return a.substring(7)+ })+ })} : {parsed:{none:!0}, rest:a}+ }}, g;+ g = c.parser;+ var i;+ i = d.parser;+ __check(c, "parser") && __check(d, "parser") ? b = {parser:function(a) {+ var b = g(a), a = b.parsed.some, c;+ c = b.rest;+ if(__check(b, "parsed") && __check(b, "rest") && __check(b.parsed, "some")) {+ b = i(c);+ c = b.parsed.some;+ var d;+ d = b.rest;+ __check(b, "parsed") && __check(b, "rest") && __check(b.parsed, "some") ? a = {parsed:{some:a(c)}, rest:d} : (c = b.rest, __check(b, "parsed") && __check(b, "rest") && __check(b.parsed, "none") ? a = {parsed:{none:!0}, rest:c} : (exhaust(), a = void 0))+ }else {+ a = b.rest, __check(b, "parsed") && __check(b, "rest") && __check(b.parsed, "none") ? a = {parsed:{none:!0}, rest:a} : (exhaust(), a = void 0)+ }+ return a+ }} : (exhaust(), b = void 0);+ var k;+ k = b.parser;+ if(__check(b, "parser")) {+ var h = k("tenfingers"), q;+ q = h.parsed.some;+ a = __check(h, "parsed") && __check(h.parsed, "some") ? {some:q} : {none:!0}+ }else {+ exhaust(), a = void 0+ }+ return e(a)({some:"fingersten"})+ }catch(l) {+ return{error:l}+ }+ }()).toEqual(!0)+ });+ it('150_151multi__::__ var result = run_parser (string "ten" <|> string "eleven") "eleven"\n result == {some: "eleven"}', function() {+ expect(function() {+ try {+ var a, c = {parser:function(a) {+ var b;+ b = run(function() {+ return run(function() {+ return a.substring(0, 3)+ })+ });+ return e(b)("ten") ? {parsed:{some:"ten"}, rest:run(function() {+ return run(function() {+ return a.substring(3)+ })+ })} : {parsed:{none:!0}, rest:a}+ }}, d;+ var f = {parser:function(a) {+ var b;+ b = run(function() {+ return run(function() {+ return a.substring(0, 6)+ })+ });+ return e(b)("eleven") ? {parsed:{some:"eleven"}, rest:run(function() {+ return run(function() {+ return a.substring(6)+ })+ })} : {parsed:{none:!0}, rest:a}+ }}, b;+ b = c.parser;+ var g;+ g = f.parser;+ if(__check(c, "parser") && __check(f, "parser")) {+ var i;+ i = function(a) {+ return function(b) {+ var c;+ c = b.rest;+ return __check(b, "parsed") && __check(b, "rest") && __check(b.parsed, "none") && e(a)(c) ? g(a) : b+ }+ };+ d = {parser:function(a) {+ return i(a)(b(a))+ }}+ }else {+ exhaust(), d = void 0+ }+ var k;+ k = d.parser;+ if(__check(d, "parser")) {+ var h = k("eleven"), q;+ q = h.parsed.some;+ a = __check(h, "parsed") && __check(h.parsed, "some") ? {some:q} : {none:!0}+ }else {+ exhaust(), a = void 0+ }+ return e(a)({some:"eleven"})+ }catch(l) {+ return{error:l}+ }+ }()).toEqual(!0)+ });+ it('153_154multi__::__ var result = run_parser (string "ten" *> string "fingers") "tenfingers"\n result == {some: "fingers"}', function() {+ expect(function() {+ try {+ var a, c = {parser:function(a) {+ var b;+ b = run(function() {+ return run(function() {+ return a.substring(0, 3)+ })+ });+ return e(b)("ten") ? {parsed:{some:"ten"}, rest:run(function() {+ return run(function() {+ return a.substring(3)+ })+ })} : {parsed:{none:!0}, rest:a}+ }}, d;+ var f = {parser:function(a) {+ var b;+ b = run(function() {+ return run(function() {+ return a.substring(0, 7)+ })+ });+ return e(b)("fingers") ? {parsed:{some:"fingers"}, rest:run(function() {+ return run(function() {+ return a.substring(7)+ })+ })} : {parsed:{none:!0}, rest:a}+ }}, b;+ b = c.parser;+ var g;+ g = f.parser;+ __check(c, "parser") && __check(f, "parser") ? d = {parser:function(a) {+ var a = b(a), c;+ c = a.rest;+ __check(a, "parsed") && __check(a, "rest") && __check(a.parsed, "some") ? a = g(c) : (c = a.rest, __check(a, "parsed") && __check(a, "rest") && __check(a.parsed, "none") ? a = {parsed:{none:!0}, rest:c} : (exhaust(), a = void 0));+ return a+ }} : (exhaust(), d = void 0);+ var i;+ i = d.parser;+ if(__check(d, "parser")) {+ var k = i("tenfingers"), h;+ h = k.parsed.some;+ a = __check(k, "parsed") && __check(k.parsed, "some") ? {some:h} : {none:!0}+ }else {+ exhaust(), a = void 0+ }+ return e(a)({some:"fingers"})+ }catch(q) {+ return{error:q}+ }+ }()).toEqual(!0)+ });+ it('156_158multi__::__ var parser = (string "ten" *> string "fingers") <|> string "tentoes"\n result = run_parser parser "tentoes"\n result == {none}', function() {+ expect(function() {+ try {+ var a, c = {parser:function(a) {+ var b;+ b = run(function() {+ return run(function() {+ return a.substring(0, 3)+ })+ });+ return e(b)("ten") ? {parsed:{some:"ten"}, rest:run(function() {+ return run(function() {+ return a.substring(3)+ })+ })} : {parsed:{none:!0}, rest:a}+ }}, d;+ var f = {parser:function(a) {+ var b;+ b = run(function() {+ return run(function() {+ return a.substring(0, 7)+ })+ });+ return e(b)("fingers") ? {parsed:{some:"fingers"}, rest:run(function() {+ return run(function() {+ return a.substring(7)+ })+ })} : {parsed:{none:!0}, rest:a}+ }}, b;+ b = c.parser;+ var g;+ g = f.parser;+ __check(c, "parser") && __check(f, "parser") ? d = {parser:function(a) {+ var a = b(a), c;+ c = a.rest;+ __check(a, "parsed") && __check(a, "rest") && __check(a.parsed, "some") ? a = g(c) : (c = a.rest, __check(a, "parsed") && __check(a, "rest") && __check(a.parsed, "none") ? a = {parsed:{none:!0}, rest:c} : (exhaust(), a = void 0));+ return a+ }} : (exhaust(), d = void 0);+ var i;+ var c = {parser:function(a) {+ var b;+ b = run(function() {+ return run(function() {+ return a.substring(0, 7)+ })+ });+ return e(b)("tentoes") ? {parsed:{some:"tentoes"}, rest:run(function() {+ return run(function() {+ return a.substring(7)+ })+ })} : {parsed:{none:!0}, rest:a}+ }}, k;+ k = d.parser;+ var h;+ h = c.parser;+ if(__check(d, "parser") && __check(c, "parser")) {+ var q;+ q = function(a) {+ return function(b) {+ var c;+ c = b.rest;+ return __check(b, "parsed") && __check(b, "rest") && __check(b.parsed, "none") && e(a)(c) ? h(a) : b+ }+ };+ i = {parser:function(a) {+ return q(a)(k(a))+ }}+ }else {+ exhaust(), i = void 0+ }+ var l;+ l = i.parser;+ if(__check(i, "parser")) {+ var j = l("tentoes"), m;+ m = j.parsed.some;+ a = __check(j, "parsed") && __check(j.parsed, "some") ? {some:m} : {none:!0}+ }else {+ exhaust(), a = void 0+ }+ return e(a)({none:!0})+ }catch(r) {+ return{error:r}+ }+ }()).toEqual(!0)+ });+ it('160_162multi__::__ var parser = try\' (string "ten" *> string "fingers") <|> string "tentoes"\n result = run_parser parser "tentoes"\n result == {some: "tentoes"}', function() {+ expect(function() {+ try {+ var a, c = i, d = {parser:function(a) {+ var b;+ b = run(function() {+ return run(function() {+ return a.substring(0, 3)+ })+ });+ return e(b)("ten") ? {parsed:{some:"ten"}, rest:run(function() {+ return run(function() {+ return a.substring(3)+ })+ })} : {parsed:{none:!0}, rest:a}+ }}, f;+ var b = {parser:function(a) {+ var b;+ b = run(function() {+ return run(function() {+ return a.substring(0, 7)+ })+ });+ return e(b)("fingers") ? {parsed:{some:"fingers"}, rest:run(function() {+ return run(function() {+ return a.substring(7)+ })+ })} : {parsed:{none:!0}, rest:a}+ }}, g;+ g = d.parser;+ var E;+ E = b.parser;+ __check(d, "parser") && __check(b, "parser") ? f = {parser:function(a) {+ var a = g(a), b;+ b = a.rest;+ __check(a, "parsed") && __check(a, "rest") && __check(a.parsed, "some") ? a = E(b) : (b = a.rest, __check(a, "parsed") && __check(a, "rest") && __check(a.parsed, "none") ? a = {parsed:{none:!0}, rest:b} : (exhaust(), a = void 0));+ return a+ }} : (exhaust(), f = void 0);+ var k = c(f), h;+ var c = {parser:function(a) {+ var b;+ b = run(function() {+ return run(function() {+ return a.substring(0, 7)+ })+ });+ return e(b)("tentoes") ? {parsed:{some:"tentoes"}, rest:run(function() {+ return run(function() {+ return a.substring(7)+ })+ })} : {parsed:{none:!0}, rest:a}+ }}, q;+ q = k.parser;+ var l;+ l = c.parser;+ if(__check(k, "parser") && __check(c, "parser")) {+ var j;+ j = function(a) {+ return function(b) {+ var c;+ c = b.rest;+ return __check(b, "parsed") && __check(b, "rest") && __check(b.parsed, "none") && e(a)(c) ? l(a) : b+ }+ };+ h = {parser:function(a) {+ return j(a)(q(a))+ }}+ }else {+ exhaust(), h = void 0+ }+ var m;+ m = h.parser;+ if(__check(h, "parser")) {+ var r = m("tentoes"), p;+ p = r.parsed.some;+ a = __check(r, "parsed") && __check(r.parsed, "some") ? {some:p} : {none:!0}+ }else {+ exhaust(), a = void 0+ }+ return e(a)({some:"tentoes"})+ }catch(s) {+ return{error:s}+ }+ }()).toEqual(!0)+ });+ it('164_166multi__::__ var parser = many (string "ten")\n result = run_parser parser "tententententen"\n result == {some: ["ten", "ten", "ten", "ten", "ten"]}', function() {+ expect(function() {+ try {+ var a, c = g({parser:function(a) {+ var b;+ b = run(function() {+ return run(function() {+ return a.substring(0, 3)+ })+ });+ return e(b)("ten") ? {parsed:{some:"ten"}, rest:run(function() {+ return run(function() {+ return a.substring(3)+ })+ })} : {parsed:{none:!0}, rest:a}+ }});+ var d;+ d = c.parser;+ if(__check(c, "parser")) {+ var f = d("tententententen"), b;+ b = f.parsed.some;+ a = __check(f, "parsed") && __check(f.parsed, "some") ? {some:b} : {none:!0}+ }else {+ exhaust(), a = void 0+ }+ return e(a)({some:["ten", "ten", "ten", "ten", "ten"]})+ }catch(i) {+ return{error:i}+ }+ }()).toEqual(!0)+ })+ }+ })+ }+ })+});+describe("", function() {+ describe("Benchmarks for the prelude", function() {+ var i;+ i = Benchmarks_for_the_prelude.title;+ var g;+ g = Benchmarks_for_the_prelude.euler_1;+ var e;+ e = Benchmarks_for_the_prelude.euler_2;+ var a;+ a = Benchmarks_for_the_prelude.euler_3;+ var c;+ c = Benchmarks_for_the_prelude.euler_4;+ var d;+ d = Benchmarks_for_the_prelude.euler_5;+ var f;+ f = prelude._return_ || window._return_;+ var b;+ b = prelude.time || window.time;+ var n;+ n = prelude.err || window.err;+ b = prelude.speedtest.time || window.time;+ i = Benchmarks_for_the_prelude.title;+ g = Benchmarks_for_the_prelude.euler_1;+ e = Benchmarks_for_the_prelude.euler_2;+ a = Benchmarks_for_the_prelude.euler_3;+ c = Benchmarks_for_the_prelude.euler_4;+ d = Benchmarks_for_the_prelude.euler_5;+ new function() {+ it('56_70multi__::__ do! title "Relative Speeds (10k)"\n \n w <- time (euler_1 10000)\n x <- time yield euler_2 10000 0\n y <- time yield euler_3 10000\n z <- time (euler_4 10000)\n q <- time yield euler_5 10000 0\n \n log " Native JS: `w / 1000`s"\n log " Formal TCO Unboxed: `q / 1000`s"\n log " Formal TCO: `x / 1000`s"\n log " Formal Recursive: `y / 1000`s"\n log " Formal list: `z / 1000`s"\n \n return <| (x <= y && y < z)', + function() {+ expect(function() {+ try {+ return run(function() {+ var k = run, h = i("Relative Speeds (10k)");+ run(h);+ var h = b(g(1E4)), n = run(h), h = b(function() {+ return e(1E4)(0)+ }), l = run(h), h = b(function() {+ return a(1E4)+ }), j = run(h), h = b(c(1E4)), m = run(h), h = b(function() {+ return d(1E4)(0)+ }), r = run(h), p, s = run(function() {+ return run(function() {+ return n / 1E3+ })+ });+ p = run(function() {+ return run(function() {+ return" Native JS: " + s+ })+ });+ var w;+ w = run(function() {+ return run(function() {+ return"" + p + "s"+ })+ });+ run(function() {+ return console.log(w)+ });+ var x, t = run(function() {+ return run(function() {+ return r / 1E3+ })+ });+ x = run(function() {+ return run(function() {+ return" Formal TCO Unboxed: " + t+ })+ });+ var B;+ B = run(function() {+ return run(function() {+ return"" + x + "s"+ })+ });+ run(function() {+ return console.log(B)+ });+ var y, C = run(function() {+ return run(function() {+ return l / 1E3+ })+ });+ y = run(function() {+ return run(function() {+ return" Formal TCO: " + C+ })+ });+ var u;+ u = run(function() {+ return run(function() {+ return"" + y + "s"+ })+ });+ run(function() {+ return console.log(u)+ });+ var v, z = run(function() {+ return run(function() {+ return j / 1E3+ })+ });+ v = run(function() {+ return run(function() {+ return" Formal Recursive: " + z+ })+ });+ var D;+ D = run(function() {+ return run(function() {+ return"" + v + "s"+ })+ });+ run(function() {+ return console.log(D)+ });+ var A, E = run(function() {+ return run(function() {+ return m / 1E3+ })+ });+ A = run(function() {+ return run(function() {+ return" Formal list: " + E+ })+ });+ var F;+ F = run(function() {+ return run(function() {+ return"" + A + "s"+ })+ });+ run(function() {+ return console.log(F)+ });+ var G;+ G = run(function() {+ return run(function() {+ return l <= j+ })+ });+ var I = run(function() {+ return run(function() {+ return j < m+ })+ }), h = run(function() {+ return run(function() {+ return G && I+ })+ }), h = f(h);+ return k(h)+ })+ }catch(n) {+ return{error:n}+ }+ }()).toEqual(!0)+ });+ it("72_72__::__ string? (err yield euler_3(250000)).message", function() {+ expect(function() {+ try {+ var b;+ var c = n(function() {+ return a(25E4)+ }).message;+ b = run(function() {+ return run(function() {+ return"string" === typeof c+ })+ });+ return b+ }catch(d) {+ return{error:d}+ }+ }()).toEqual(!0)+ });+ it('74_88multi__::__ do! title "Relative Speeds (2.5M)"\n \n w <- time (euler_1 2500000)\n x <- time yield euler_2 2500000 0\n y <- time yield euler_5 2500000 0\n \n log " Native JS: `w / 1000`s"\n log " Formal TCO Unboxed: `y / 1000`s"\n log " Formal TCO: `x / 1000`s"\n log " Formal Recursive: `err yield euler_3(250000)`"\n log " Formal list: `err (euler_4 250000)`"\n \n log ""\n \n return <| (w < x)', + function() {+ expect(function() {+ try {+ return run(function() {+ var k = run, h = i("Relative Speeds (2.5M)");+ run(h);+ var h = b(g(25E5)), q = run(h), h = b(function() {+ return e(25E5)(0)+ }), l = run(h), h = b(function() {+ return d(25E5)(0)+ }), j = run(h), m, r = run(function() {+ return run(function() {+ return q / 1E3+ })+ });+ m = run(function() {+ return run(function() {+ return" Native JS: " + r+ })+ });+ var p;+ p = run(function() {+ return run(function() {+ return"" + m + "s"+ })+ });+ run(function() {+ return console.log(p)+ });+ var s, w = run(function() {+ return run(function() {+ return j / 1E3+ })+ });+ s = run(function() {+ return run(function() {+ return" Formal TCO Unboxed: " + w+ })+ });+ var x;+ x = run(function() {+ return run(function() {+ return"" + s + "s"+ })+ });+ run(function() {+ return console.log(x)+ });+ var t, B = run(function() {+ return run(function() {+ return l / 1E3+ })+ });+ t = run(function() {+ return run(function() {+ return" Formal TCO: " + B+ })+ });+ var y;+ y = run(function() {+ return run(function() {+ return"" + t + "s"+ })+ });+ run(function() {+ return console.log(y)+ });+ var C, u = n(function() {+ return a(25E4)+ });+ C = run(function() {+ return run(function() {+ return" Formal Recursive: " + u+ })+ });+ var v;+ v = run(function() {+ return run(function() {+ return"" + C + ""+ })+ });+ run(function() {+ return console.log(v)+ });+ var z, D = n(c(25E4));+ z = run(function() {+ return run(function() {+ return" Formal list: " + D+ })+ });+ var A;+ A = run(function() {+ return run(function() {+ return"" + z + ""+ })+ });+ run(function() {+ return console.log(A)+ });+ run(function() {+ return console.log("")+ });+ h = run(function() {+ return run(function() {+ return q < l+ })+ });+ h = f(h);+ return k(h)+ })+ }catch(E) {+ return{error:E}+ }+ }()).toEqual(!0)+ })+ }+ });+ describe("Tests for partial records", function() {+ var i;+ i = prelude._eq_eq || window._eq_eq;+ new function() {+ it("95_96multi__::__ var f {a: x, b: y, _ } = x + y\n f { a: 5, b: 5, c: 5 } == f { a: 5, b: 5, d: 5 }", function() {+ expect(function() {+ try {+ var g;+ g = function(a) {+ var c;+ c = a.a;+ var d;+ d = a.b;+ if(__check(a, "a") && __check(a, "b")) {+ return run(function() {+ return run(function() {+ return c + d+ })+ })+ }+ exhaust()+ };+ return i(g({a:5, b:5, c:5}))(g({a:5, b:5, d:5}))+ }catch(e) {+ return{error:e}+ }+ }()).toEqual(!0)+ });+ it("98_100multi__::__ var f {a: 1, b: 1, _ } = 2\n f {b: 2, c: 2, _ } = 2\n f {a:1,b:1,c:3,d:5} + f {a:1,b:2,c:2,e:5} == 4", function() {+ expect(function() {+ try {+ var g;+ g = function(a) {+ if(__check(a, "a") && __check(a, "b") && 1 === a.a && 1 === a.b || __check(a, "b") && __check(a, "c") && 2 === a.b && 2 === a.c) {+ return 2+ }+ exhaust()+ };+ var e = g({a:1, b:1, c:3, d:5}), a, c = g({a:1, b:2, c:2, e:5});+ a = run(function() {+ return run(function() {+ return e + c+ })+ });+ return i(a)(4)+ }catch(d) {+ return{error:d}+ }+ }()).toEqual(!0)+ });+ it("102_105multi__::__ var f { a = 1, b = 2, _ } = 1\n g { b = 2, c = 3, _ } = 2\n x = { a = 1, b = 2, c = 3, d = 4 }\n f x + 1 == g x", function() {+ expect(function() {+ try {+ var g;+ g = {a:1, b:2, c:3, d:4};+ var e;+ __check(g, "a") && __check(g, "b") && 1 === g.a && 2 === g.b ? e = 1 : (exhaust(), e = void 0);+ var a = e, c;+ c = run(function() {+ return run(function() {+ return a + 1+ })+ });+ var d = i(c), f;+ __check(g, "b") && __check(g, "c") && 2 === g.b && 3 === g.c ? f = 2 : (exhaust(), f = void 0);+ return d(f)+ }catch(b) {+ return{error:b}+ }+ }()).toEqual(!0)+ })+ }+ });+ describe("Tests for TCO bugs", function() {+ var i;+ i = Tests_for_TCO_bugs.rev_1;+ var g;+ g = Tests_for_TCO_bugs.rev_2;+ var e;+ e = Tests_for_TCO_bugs.test_x;+ var a;+ a = prelude.length || window.length;+ var c;+ c = prelude.reverse || window.reverse;+ a = prelude.list.length || window.length;+ c = prelude.list.reverse || window.reverse;+ i = Tests_for_TCO_bugs.rev_1;+ g = Tests_for_TCO_bugs.rev_2;+ e = Tests_for_TCO_bugs.test_x;+ new function() {+ it("126_126__::__ rev_2 [: 1, 2, 3, 4 ] == [: 4, 3, 2, 1 ]", function() {+ expect(g({head:1, tail:{head:2, tail:{head:3, tail:{head:4, tail:{nil:!0}}}}})).toEqual({head:4, tail:{head:3, tail:{head:2, tail:{head:1, tail:{nil:!0}}}}})+ });+ it("130_130__::__ rev_2 test_x == rev_1 test_x", function() {+ expect(g(e)).toEqual(i(e))+ });+ it("131_131__::__ rev_1 test_x == reverse test_x", function() {+ expect(i(e)).toEqual(c(e))+ });+ it("132_132__::__ length (rev_2 test_x) == length (rev_1 test_x)", function() {+ expect(a(g(e))).toEqual(a(i(e)))+ });+ it("133_133__::__ length (rev_2 test_x) == length test_x", function() {+ expect(a(g(e))).toEqual(a(e))+ });+ it("134_134__::__ length (rev_1 test_x) == length (reverse test_x)", function() {+ expect(a(i(e))).toEqual(a(c(e)))+ })+ }+ });+ describe("Tests for parser bugs", function() {+ var i;+ i = prelude._eq_eq || window._eq_eq;+ new function() {+ it('143_144multi__::__ var x = do! `[ { x: 1}, {x: 2}, {x: 3} ]`\n stringify (x !! 0).x == "1"', function() {+ expect(function() {+ try {+ var g;+ g = run(function() {+ return run(function() {+ return[{x:1}, {x:2}, {x:3}]+ })+ });+ var e, a = run(function() {+ return run(function() {+ return g[0]+ })+ }).x;+ e = run(function() {+ return run(function() {+ return JSON.stringify(a)+ })+ });+ return i(e)("1")+ }catch(c) {+ return{error:c}+ }+ }()).toEqual(!0)+ })+ }+ })+});++</script><p>Formal is an opinionative programming language for the discriminating modern programmer. More importantly, formal is my vanity project, an attempt to learn ML by writing one.</p>+<p>What opinions, you may ask? Several:</p>+<ul>+<li><p>Buzzwords: functional, strict, pure(ish), static(y), inferred, fast, fun. Strong like a gorilla, yet soft and yielding like a Nerf ball.</p></li>+<li><p>Targets Javascript. Please regard this as an implementation detail - formal is not intended as an answer to "the Javascript problem."</p></li>+<li><p>Testing is first class.</p></li>+<li>Heavily inspired by</li>+<li><a href="http://www.haskell.org/haskellwiki/Haskell">Haskell</a></li>+<li><a href="http://msdn.microsoft.com/en-us/vstudio/hh388569.aspx">F#</a></li>+<li><a href="http://coffeescript.org/">Coffeescript</a>.</li>+<li>(<a href="http://en.wikipedia.org/wiki/Category:ML_programming_language_family">_</a>)(<a href="http://www.smlnj.org/">S</a>)(<a href="http://caml.inria.fr/">OCA</a>)ML</li>+<li><a href="http://clojure.org/">Clojure</a></li>+<li><a href="http://www.haskell.org/haskellwiki/Jmacro">JMacro</a></li>+<li><a href="http://www.ruby-lang.org/en/">Ruby</a></li>+<li><p><a href="http://en.wikipedia.org/wiki/Absinthe">absinthe</a></p></li>+</ul>+<p>Detriments:</p>+<ul>+<li><p>Unreadable Javascript. As a vanity project, this was simply not a priority. Long term, source maps seem a much better solution to this issue than targetting</p></li>+<li><p>Buggy. But you can help - by reporting bugs!</p></li>+<li><p>Designed for readability and</p></li>+<li><p>Hybrid type system - complete polymorphic type system w/ stuctural records, plus a dynamic type for unrestricted Javascript.</p></li>+<li><p>First class testing - types and tests are equal first class citizens of the language.</p></li>+<li><p>Inline Javascript - For bootstrapping, quickly importing a Javascript library, accessing un-formalized APIs or simply writing fast mutation algorithms "natively."</p></li>+<li><p>Simple data types - The basic data types in Formal are the exact same basic data types of Javascript: Num, String, Array, Object, Function.</p></li>+<li><p>Advanced pattern matching - Traditional pattern matching goodness with a few extras: match on record partials & define your own matches with view patterns.</p></li>+<li><p>Pure by default - Like Haskell, any function which has a side effect returns the polymorphic type <code>JS a</code> by default, including any inline Javascript, and these types can be composed without evaluation via <code>do</code>, <code>yield</code>, <code>lazy</code> or simple combinators. Unlike Haskell, <code>JS a</code> types can be trivially unwrapped anywhere via <code>do!</code></p></li>+<li><p>Targets Closure advanced mode - Formal does not aim to emit readable Javascript, instead opting to produce the most efficient output possible.</p></li>+</ul>+<p>This document is a both the compiler's README, and the Formal language's standard library as literate code, which serves as a simple language feature spec/tutorial</p>+<h2 id="installation">Installation</h2>+<p>Mac OSX (tested on Snow Leopard & Lion)</p>+<p>Install the <a href="http://hackage.haskell.org/platform/index.html">Haskell Platform</a>, then</p>+<pre><code>--$ cabal install formal</pre>+</code>+<p>To compile some formal files:</p>+<pre><code>--$ formal -o app test.formal test2.formal</pre>+</code>+<p>will create an app.js, app.spec.js and app.html file with the compiled code, test suite and annotated documentation respectively. To compile literate formal (eg, Formal code embedded in Markdown, ala this file):</p>+<pre><code>--$ formal test.lformal</pre>+</code>+<p>To see the inferred types:</p>+<pre><code>--$ formal -t test.formal</pre>+</code>+<p>To turn off optimizing (eg, Closure) or testing:</p>+<pre><code>--$ formal -no-test -no-opt test.formal</pre>+</code>+<p>Formal is a literate language embedded in <a href="http://daringfireball.net/projects/markdown/syntax">Markdown</a>, so any line not indented at least 4 spaces is considered a comment. The primary unit of code organization is the <code>module</code>, a named collection of functions and values.</p>+<pre><code>module prelude</code></pre>+<h2 id="bootstrap">Bootstrap</h2>+<p>Some simple reflection by lifting from Javascript. The definitions of <code>object?</code> and <code>array?</code> must use Javascript's <code>===</code> operator directly here, as the "==" operator defined in <a href="#numbers">Numbers</a> is defined in terms of them.</p>+<pre><code> type+ JS a = {} -> a++ inline object? x = do! `typeof x === "object"`+ inline array? = do! `is_array`+ inline string? x = do! `typeof x === "string"`+ inline type? x = do! `typeof x`++ inline+ not: Bool -> Bool + not x = do! `!x`+ <span class='test' id='test_122_122'>not false</span>+++ <span class='test' id='test_125_125'>object? {}</span>+ <span class='test' id='test_126_126'>array? []</span>+ <span class='test' id='test_127_127'>not (array? {})</span>+ <span class='test' id='test_128_128'>not (object? 0)</span></code></pre>+<p>Side effects can only happen in Javascript, so we use a monadic container to compose these bits.</p>+<pre><code> inline + (>>=): JS a -> (a -> JS b) -> JS b+ (>>=) x y = y (run x)++ inline + (>>): JS a -> JS b -> JS b+ (>>) x y = `run x; return (run y)`++ inline return:++ a -> JS a+ return x = `x`+++ <span class='test' id='test_149_152multi'>do! x <- `1 + 4`+ y <- `2 + 3`+ ans <- `x + y`+ return (10 == ans)</span>++ <span class='test' id='test_154_154'>5 == do! return 5</span>+ <span class='test' id='test_155_155'>10 == do! `5 + 5`</span>++++ inline log: a -> JS {} + | x = `console.log(x)`</code></pre>+<p>Testing to verify that escaping Javascript & utilizing escaped Javascript with <code>do</code> sugar and composition in general works as expected.</p>+<pre><code> <span class='test' id='test_166_169multi'>var x = 0+ y = do z <- `x = 1`+ return z+ x == 0</span></code></pre>+<h2 id="numbers">Numbers</h2>+<p>Some basic aliases to native javascript infix functions. These are type annotated to constrain inferrence - otherwise, these functions would all be inferred as <code>a -> b -> c</code>.</p>+<pre><code> inline (&&): Bool -> Bool -> Bool | x y = do! `x && y`+ inline (||): Bool -> Bool -> Bool | x y = do! `x || y`+ inline (*): Num -> Num -> Num | x y = do! `x * y`+ inline (/): Num -> Num -> Num | x y = do! `x / y`+ inline (%): Num -> Num -> Num | x y = do! `x % y`+ inline (+): Num -> Num -> Num | x y = do! `x + y`+ inline (-): Num -> Num -> Num | x y = do! `x - y`+ inline (<=): Num -> Num -> Bool | x y = do! `x <= y`+ inline (>=): Num -> Num -> Bool | x y = do! `x >= y`+ inline (<): Num -> Num -> Bool | x y = do! `x < y`+ inline (>): Num -> Num -> Bool | x y = do! `x > y`</code></pre>+<p>Equality is overloaded to match records and arrays. By constraining the type of this operator, we need only dispatch on the type of the first element, constraining</p>+<pre><code> inline x != y = not (x is y)++ inline x /= y = not (x == y)++ (==): a -> a -> Bool+ | x y when do! `x === y` = true++ | x y when object? x =+ do! `var result = true;+ for (key in x) {+ result = result && y.hasOwnProperty(key) && _eq_eq(x[key])(y[key]);+ };++ var z = Object.keys(x).length + === Object.keys(y).length;++ result && z`++ | x y when array? x =+ do! `var result = true;+ for (z in x) {+ result = result && _eq_eq(x[z])(y[z]);+ };++ result && x.length == y.length`++ | x y = false</code></pre>+<p>And a few simple tests to verify the correctness of these implementations. This is not meant to be exhaustive, only a smoke test against regressions.</p>+<pre><code> <span class='test' id='test_226_226'>(3 * 4) + 5 * 4 == 64 / 2</span>+ <span class='test' id='test_227_227'>4 - 1 != 5 - 10</span>+ <span class='test' id='test_228_228'>(10 >= 5 + 5) != (4 + 5 <= 10 - 2)</span>+ <span class='test' id='test_229_229'>({test: 1} == {test: 1}) == true</span>+ <span class='test' id='test_230_230'>({test: 1} != {test: 1}) == false</span></code></pre>+<p>Fibonacci function</p>+<pre><code> fib 0 = 0 | 1 = 1 | n = fib(n - 1) + fib(n - 2)</code></pre>+<h2 id="speed">Speed</h2>+<p>Due to the nested recursion, <code>fib</code> is an excellent function for testing the runtime speed versus raw javascript. <code>fast_fib</code> is a trivial javascript implementation of the same function, recursed itself to remove any potential overhead from formal's dispatch mechanism.</p>+<pre><code> module speedtest++ private inline get_time = `new Date().getTime()`++ time js =++ do start <- get_time+ js+ stop <- get_time+ return (stop - start)++ private inline+ fast_fib =++ do! `var f = function(n) {+ return 0 === n ? 0 : 1 === n ? 1 : f(n - 1) + f(n - 2)+ }; f`++ <span class='test' id='test_262_262'>fast_fib 7 == fib 7</span></code></pre>+<p>With this, we can set up a simple canary to let us know if the prelude is suddenly dramatically slower than it previously was; in this case, we fail a test if the formal version isn't at least 90% as fast as the native javascript version.</p>+<pre><code> floor: Num -> Num = do! `Math.floor`++ <span class='test' id='test_271_273multi'>do! fast_time <- time yield fast_fib 30+ slow_time <- time yield fib 30+ return (floor (fast_time / slow_time * 100) >= 80)</span></code></pre>+<h2 id="function-combinators">Function Combinators</h2>+<p>Simple left & right pipes, ala F#.</p>+<pre><code> inline x <| y = x y+ inline x |> y = y x++ <span class='test' id='test_282_282'>3 |> (λy = y + 1) |> λy = y + 1 == 5</span>+ <span class='test' id='test_283_283'>(λy x z = x + y + z + 1) 1 <| 3 <| 4 == 9</span></code></pre>+<p>Alternatively, there is a right associative version of <code><|</code>, ala haskell. All operators which end with a <code>:</code> are right associative.</p>+<pre><code> inline x <: y = x y++ <span class='test' id='test_290_290'>(λx = x - 3) <: (λx = x - 3) <: 5 + 5 == 4</span></code></pre>+<p>Function composition</p>+<pre><code> inline x .: y = λz = x y(z)+ inline id x = x+ inline flip(f) x y = f(y, x)++ inline x ' y = y x+++ <span class='test' id='test_301_301'>((λx = x + 1) .: (λx = x * 2) .: λx = x - 3) 4 == 3</span>+ <span class='test' id='test_302_302'>id [1, 2, 3] == [1, 2, 3]</span>+ <span class='test' id='test_303_303'>flip (λx y = x - y) 3 5 == 2</span></code></pre>+<h2 id="strings">Strings</h2>+<pre><code> module string++ inline + lstrip: String -> String+ lstrip x = do! `x.replace(/^\s+/, '')` ++ inline rstrip: String -> String | x = do! `x.replace(/\s+$/, '')` + inline strip: String -> String | = lstrip .: rstrip++ inline + (+++): a -> b -> String+ x +++ y = do! `"" + x + y`++ <span class='test' id='test_323_323'>strip " test " is "test"</span></code></pre>+<p>interpolated strings</p>+<pre><code> <span class='test' id='test_327_328multi'>let x = "test"+ in "hello `x`" is "hello test"</span>++ open string</code></pre>+<h2 id="tests">Tests</h2>+<p>By invoking javascript, we can listen for exceptions.</p>+<pre><code> err x = do! `try {+ x();+ return false;+ } catch (e) {+ return e;+ }`</code></pre>+<h2 id="option">Option</h2>+<pre><code> module option++ Option a = {some: a} | {none}++ option b {none} = b+ | _ {some: x} = x++ <span class='test' id='test_353_353'>option 3 {some: 2} == 2</span>++ module html++ HTML = { element: a+ inner: JS String+ on_click: JS {} -> JS {}+ set: b -> JS {}+ add_class: String -> JS {}+ add_style: String -> String -> JS {} }++ get:+ String -> JS HTML+ | x = do el <- `$(x).get(0)`++ return { element = el+ inner = `el.innerHTML`+ on_click y = `el.onclick = y`+ set y = `el.innerHTML = y`++ add_class y =+ `el.setAttribute("class", el.getAttribute("class") + " " + y)`++ add_style y z = `el.style[y] = z` }++ inline ($=):++ String -> a -> JS {}+ x $= y =++ `if (typeof $ != "undefined") {+ var xx = $(x).get(0);+ if (typeof xx != "undefined") {+ xx.innerHTML = y;+ }+ }`++ inline ($|): ++ String -> String -> String -> JS {}+ selector $| rule value = `$(selector).css(rule, value)`++ inline + ($.): String -> String -> JS {}+ ($.) x y = `$(x).addClass(y)`++ inline ($+): String -> String -> JS {}+ | x y = `$(x).append(y)`++ div: String -> JS String+ | x = yield "<div id='`x`'/>"++ move: HTML -> HTML -> JS a+ | x y = `$(y.element).append($(x.element).detach())`++ on_load: JS {} -> JS {}+ | x = `window.addEventListener("load", x, false)`++ inline stringify: a -> String | x = do! `JSON.stringify(x)`++ inline (!!): Array a -> Num -> a | x y = do! `x[y]`++ with_page: JS a -> JS a+ | x = do old <- `$("body").clone()`+ xx <- x+ `$("body").replaceWith(old)`+ return xx</code></pre>+<p>do! with_page do "body" $= "Test" text <- get "body" text <- text.inner return (text == "Test")</p>+<pre><code> <span class='test' id='test_426_436multi'>do! d <- div "test1"++ "body" $+ d+ "#test1" $= "I am a test!"++ text <- get "#test1"+ text <- text.inner++ "#test1" $= ""++ return (text == "I am a test!")</span>++ inline split: String -> String -> Array String | y x = do! `x.split(y)`</code></pre>+<p>This is the initializer for prelude's console test suite.</p>+<pre><code> console_runner: JS {} =++ var is_error = 0++ var report spec = ++ do! results <- `spec.results()`+ passed <- `results.passed()`++ if passed + then return {}++ else let items = spec.results_.items_+ desc = spec.description.split "__::__" !! 1+ exp = stringify (items !! 0).expected+ act = stringify (items !! 0).actual++ let line = spec.description+ |> split "__::__"+ |> \x = x !! 0+ |> split "_" + |> \x = x !! 0+ |> \x = do! `parseInt x`+ |> \x = x + 1+ |> stringify++ do if is_error == 0+ then log "\r " + else return {}++ `is_error = 1`++ log "Test failed at line `line`++ `desc`++ Expected `exp`+ Actual `act`"++ log ""++ var reporter = { reportSpecResults: report + reportRunnerResults: `phantom.exit(is_error)` }++ do env <- `jasmine.getEnv()`++ `env.addReporter(reporter)`+ `env.execute()`+++ push : a -> Array a -> JS (Array a)+ push xs x = `xs.push(x)` ++ private console_reporter = {++ total = 0+ failed = 0++ messages = []++ reportSpecResults spec =++ do! results <- `spec.results()`+ passed <- `results.passed()`+ `console_reporter.total++`++ if not passed then do+ `console_reporter.failed++`+ push console_reporter.messages spec.description+ return {}+ else return {}++ reportRunnerResults =++ do if console_reporter.failed > 0+ log console_reporter.messages+ else + return {}++ log "`console_reporter.total - console_reporter.failed`/`console_reporter.total` tests passed"+ }</code></pre>+<p>This is the initializer for prelude's HTML test suite.</p>+<pre><code> table_of_contents =++ on_load do "code" $. "prettyprint"+ "code" $. "lang-hs"++ ".test" $| "position" <| "relative"+ ".test" $| "left" <| "50px"++ `prettyPrint()`++ trivial <- `new jasmine.TrivialReporter()`+ formal <- `new jasmine.FormalReporter()`+ env <- `jasmine.getEnv()`++ `env.addReporter trivial`+ `env.addReporter formal`+ `env.addReporter console_reporter`++ `env.execute()`++ reporter <- get ".jasmine_reporter"+ body <- get "#test_suite"++ move reporter body</code></pre>+<h2 id="lists">Lists</h2>+<p>A simple implementation of a library for manipulating linked lists.</p>+<pre><code> module list++ List a = { head: a, tail: List a } + | { nil }</code></pre>+<p>This complex type can be hidden behind a constructor function which works more like a traditional cons.</p>+<pre><code> inline + x :: y = { head = x, tail = y }</code></pre>+<p>The compiler itself also supports the list sugar <code>[: 1, 2, 3 ]</code> (or <code>[: 1, 2, 3 :]</code>, if you prefer symmetry). All of these lists are synonyms.</p>+<pre><code> <span class='test' id='test_573_587multi'>var xs = [:++ [:1,2,3]++ [:1,2,3:]++ (1::2::3::{nil})++ { head = 1+ tail = { head = 2+ tail = { head = 3+ tail = {nil} }}}+ ]++ all? (λy = [:1,2,3] == y) xs </span></code></pre>+<p>Simple implementations of list accessors, which illustrate incomplete definition.</p>+<pre><code> empty? { nil } = true | _ = false++ head { head: x, tail: _ } = x+ | { nil } = error "Head called on empty list"++ tail { head: _, tail: x } = x + | { nil } = error "Tail called on empty list"++ last { head: x, tail: { nil } } = x+ last { head: _, tail: x } = last x+ last { nil } = error "Last called on empty list"++ take 0 x = { nil } | n x = head x :: take (n - 1) (tail x)+ drop 0 x = x | n x = drop (n - 1) (tail x)++ x .. y = + let f xx z when xx >= x = f (xx - 1) (xx :: z)+ f _ z = z ++ f y {nil}++ <span class='test' id='test_614_614'>1 .. 5 == [:1,2,3,4,5]</span></code></pre>+<p>Project Euler problem 1, modified to protect the innocent:</p>+<pre><code> <span class='test' id='test_618_618'>288045 == 1 .. 1111 |> filter (λx = x % 3 == 0 || x % 5 == 0) |> sum</span>+++ take_while f { nil } = { nil }+ | f x when f (head x) = head x :: filter f (tail x)+ | _ _ = { nil }++ drop_while f { nil } = { nil }+ | f x when f (head x) = drop_while f (tail x)+ | _ x = x++ <span class='test' id='test_629_629'>not (empty? (1 :: {nil}))</span>+ <span class='test' id='test_630_630'>empty? [:]</span>++ <span class='test' id='test_632_632'>head [: 1, 2 ] is 1</span>+ <span class='test' id='test_633_633'>tail [: 1, 2 ] is [:2]</span>+ <span class='test' id='test_634_634'>last [: 1, 2 ] is 2</span>++ <span class='test' id='test_636_636'>err (lazy head {nil}) is "Head called on empty list"</span>+ <span class='test' id='test_637_637'>err (lazy tail {nil}) is "Tail called on empty list"</span>+ <span class='test' id='test_638_638'>err (lazy last {nil}) is "Last called on empty list"</span>++ <span class='test' id='test_640_640'>take(2, [: 1, 2, 3 ]) == [: 1, 2 ]</span>+ <span class='test' id='test_641_641'>drop(2, [: 1, 2, 3 ]) == [: 3 ]</span>++ <span class='test' id='test_643_643'>take_while (λx = x < 0) [:] == [:]</span>+ <span class='test' id='test_644_644'>take_while (λx = x > 0) [: 2, 1, 0 ] == [: 2, 1 ]</span>++ <span class='test' id='test_646_646'>drop_while (λx = x < 0) {nil} == {nil}</span>+ <span class='test' id='test_647_647'>drop_while (λx = x > 0) [: 2, 1, 0 ] == [: 0 ]</span></code></pre>+<p>Cardinality</p>+<pre><code> length ++ | {nil} = 0+ | {head: _, tail: x} = 1 + length x++ <span class='test' id='test_656_656'>length [: 1, 2, 3, 4 ] == 4</span></code></pre>+<p>Generators</p>+<pre><code> init 0 _ = {nil}+ | n x = x :: init (n - 1) x++ <span class='test' id='test_663_663'>length (init 30 0) == 30</span>+ <span class='test' id='test_664_664'>tail (init 3 0) == init 2 0</span></code></pre>+<p>List concatenation</p>+<pre><code> (++)++ | {nil} y = y+ | {head: y, tail: ys} xs = y :: (ys ++ xs)++ <span class='test' id='test_673_673'>{nil} ++ (1 :: 2 :: {nil}) == 1 :: 2 :: {nil}</span>+ <span class='test' id='test_674_674'>[: 1, 2 ] ++ [: 3, 4 ] == [: 1, 2, 3, 4 ]</span></code></pre>+<p>Filter.</p>+<pre><code> filter: (a -> Bool) -> List a -> List a+ | f {nil} = {nil}+ | f x when f (head x) = head x :: filter f (tail x)+ | f x = filter f <| tail x++ <span class='test' id='test_683_683'>[: 1, 2, 3, 4 ] 'filter (λx = x > 2) == [: 3, 4 ]</span></code></pre>+<p>Map</p>+<pre><code> map(f, {nil}) = {nil}+ map(f, x) = f(head(x)) :: map(f, tail(x))++ <span class='test' id='test_690_690'>[: 2, 3, 4 ] == [: 1, 2, 3 ] |> map λx = x + 1</span></code></pre>+<p>Reverse</p>+<pre><code> reverse y = + let r rest [:] = rest+ r rest { head: x, tail: xs } = + r (x :: rest) xs++ in r {nil} y++ <span class='test' id='test_701_701'>reverse [: 1, 2, 3, 4 ] == [: 4, 3, 2, 1 ]</span>++ <span class='test' id='test_703_704multi'>var test_x = [: 1, 2, 3, 4 ]+ test_x == reverse <| reverse test_x</span>++ take' x y =+ let t(0, _, acc) = acc+ t(n, x, acc) = t(n - 1, tail x, head x :: acc)++ in reverse t(x, y, {nil})++ <span class='test' id='test_712_713multi'>var x = [: 1, 2, 3, 4, 5, 6, 7, 8 ]+ take 5 x == take' 5 x</span></code></pre>+<p>Folds</p>+<pre><code> foldl f x xs =+ var g y {nil} = y+ | y { head: z, tail: zs } = g (f y z) zs+ g x xs++ foldl1 _ {nil} = error "Foldl1 called on empty list"+ | f x = foldl f (head x) (tail x)++ foldr f x =+ var g {nil} = x+ g { head: y, tail: ys } = f y (g ys)+ g++ foldr1 _ {nil} = error "Foldr1 called on empty list"+ | f x = foldr f (head x) (tail x)++ all? f = foldl1 (λx y = x && y) .: map f+ any? f = foldl1 (λx y = x || y) .: map f++ sum = foldl1 λ(x, y) = x + y+ product = foldl1 λ(x, y) = x * y++ concat = foldl1 λx y = x ++ y+ concat_map f xs = concat (map f xs)++ maximum = foldl1 λ(x, y) when x > y = x+ |(_, y) = y++ minimum = foldl1 λx y = if x > y then y else x++ <span class='test' id='test_747_747'>foldl (λx y = x + y) 0 [: 1, 2, 3, 4 ] == 10</span>+ <span class='test' id='test_748_748'>foldr (λx y = x + y) 0 [: 1, 2, 3, 4 ] == 10</span>+ <span class='test' id='test_749_749'>all? id [:true,true]</span>+ <span class='test' id='test_750_750'>not (all? id [:true,false])</span>+ <span class='test' id='test_751_751'>any? id [:true,false]</span>+ <span class='test' id='test_752_752'>not (any? id [:false,false])</span>+ <span class='test' id='test_753_753'>sum [:1,2,3] == 6</span>+ <span class='test' id='test_754_754'>product [:1,2,4] == 8</span>++ <span class='test' id='test_756_757multi'>let x = [:1,2], y = [:3,4]+ concat [:x,y] == [:1,2,3,4]</span>++ <span class='test' id='test_759_759'>concat_map (λx = [:x,x+1]) [:1,2] == [:1,2,2,3]</span>++ <span class='test' id='test_761_761'>minimum [: 1, 2, 3 ] == 1</span>+ <span class='test' id='test_762_762'>maximum [: 1, 2, 3 ] == 3</span></code></pre>+<h2 id="sequences">Sequences</h2>+<p>Sequences are an abstract data type which resembles a list, except that elements Sequences may be infinite, as long as you never try to read every element. However, the current implementation is stack-consuming and thus limited by the underlying javascript runtime [TODO].</p>+<pre><code> module seq++ open list+ open speedtest+ open html++ Seq a = { seq: JS { elem: a, next: Seq a}}+ | { end }++ inline seq x = {seq: x}++ iterate f x = seq yield { elem: x, next: iterate f (f x) }++ from_list {nil} = {end}+ | { head: x, tail: xs } =+ { seq: yield { elem: x, next: from_list xs }}++ to_list { end } = {nil}+ | { seq: x } = do! { elem: y, next: ys } <- x+ return (y :: to_list ys)++ take _ {end} = {end}+ | 0 _ = {end}+ | x { seq: y } = seq do { elem: z, next: zs } <- y+ return { elem: z, next: take (x - 1) zs }++ <span class='test' id='test_798_798'>to_list (from_list [:1,2]) == [:1,2]</span>+ <span class='test' id='test_799_799'>iterate (λx = x + 1) 0 |> take 100 |> to_list |> length == 100</span>++ zip_with:++ (a -> b -> c) -> Seq a -> Seq b -> Seq c+ | _ {end} _____ = {end}+ | _ _____ {end} = {end}+ | f {seq: a} {seq: b} = seq do++ { elem: xx, next: xs } <- a+ { elem: yy, next: ys } <- b++ return { elem: f xx yy, next: zip_with f xs ys }++ inline x ::: y = seq yield { elem: x, next: do! y }++ tail:+ Seq a -> Seq a+ | {end} = error "tail called on empty seq"+ | {seq: t} = do! t >>= λx = return x.next++ to_lazy+ | {end} = {end}+ | {seq: y} = seq lazy do!+ {elem: x, next: xs} <- y+ return {elem: x, next: to_lazy xs}</code></pre>+<p>Infinite sequence example</p>+<pre><code> fibs = to_lazy <: 1 ::: return <: 1 ::: yield zip_with (λx y = x + y) fibs <: tail fibs</code></pre>+<p>Since the <code>lazy</code> keyword memoizes it's argument, this fibonacci implementation is ridiculously faster than the recursive version. For example, the runtime speed of this fib implementation compared to the native recursive one is <span+id="speedtest">__________</span>%.</p>+<pre><code> <span class='test' id='test_835_839multi'>do! fast_time <- time yield fast_fib 30+ slow_time <- time yield fibs |> take 30 |> to_list |> last+ let ratio = floor (fast_time / slow_time * 100)+ "#speedtest" $= ratio+ return (ratio >= 2)</span>++ <span class='test' id='test_841_841'>fibs |> take 5 |> to_list == [:1,1,2,3,5]</span>++ <span class='test' id='test_843_845multi'>fast_fib 15 == fibs |> take 15+ |> to_list+ |> last</span></code></pre>+<h2 id="formalz">FormalZ</h2>+<p>Demonstration of some classic FP data structures. This form of polymorphism can be simulated in Formal the same way they are implemented in Haskell - as a function dictionary, the only difference being that you must explicitly bind the dictionary instance to a symbol (as opposed to it being referenced by the type variable's instantiation).</p>+<pre><code> module "Formal Z"++ open list++ Functor f =++ { map: (a -> b) -> f a -> f b }++ Monad m =++ { (>>=): m a -> (a -> m b) -> m b+ ret: a -> m a }++ map z x f = z.map f x++ bind { ret: f, _ } x = f x++ list_functor =++ { map _ {nil} = {nil} + | f { head: x, tail: xs } =+ { head: f x+ tail: list_functor.map f xs }}++ list_monad =++ { (>>=) x g = concat_map g x+ return x = [:x] }++ js_monad =++ { (>>=) x f = x >>= f+ return x = return x }++ <span class='test' id='test_890_893multi'>let (>>>=) x g = concat_map g x+ z = 1..3 >>>= λx = [:x,x+1,x+2]++ z == [:1,2,3,2,3,4,3,4,5]</span></code></pre><pre><code>module parsec++ open prelude+ open prelude.option+ open prelude.string+ open prelude.html++++ Parser a = {parser: String -> {rest: String, parsed: Option a}}++++ inline run_parser:</code></pre>+<p>Runs a parser over a text argument and throws away the leftover text.</p>+<pre><code> Parser p -> String -> Option p + | {parser = p} x = p x |> λ {parsed = {some = y}, _} = {some = y} + | _ = {none}++++ inline (<$>):</code></pre>+<p>Applies a function to the parse result, only if the parse was successful.</p>+<pre><code> (a -> b) -> Parser a -> Parser b+ f <$> {parser = z} =++ { parser s =+ z s |> λ {parsed = {some: x}, rest = ss} =+ {parsed = {some = f x}, rest = ss}+ | {parsed = {none}, rest = x} =+ {parsed = {none}, rest = x} }++++ inline (<*>):</code></pre>+<p>Allows functions that take multiple arguments to be applied sequentially to a sequence of parsed values.</p>+<pre><code> Parser (a -> b) -> Parser a -> Parser b+ {parser = fp} <*> {parser = p} =++ { parser s = + fp s |> λ {parsed = {some: f}, rest = rr} =+ p rr |> λ {parsed = {some = x}, rest = z} =+ {parsed = {some = f x}, rest = z}+ | {parsed = {none}, rest = x} =+ {parsed = {none}, rest = x}+ | {parsed: {none}, rest: x} =+ {parsed: {none}, rest: x} }++++++ private inline lift(g, {parser: f}) =+ { parser text =+ let f' = f text+ in g { text: text+ f: f+ parsed: f'.parsed+ rest: f'.rest+ f': f' }}++ inline (*>):</code></pre>+<p>Applies two parsers in sequence, throwing out the result of the first.</p>+<pre><code> Parser a -> Parser b -> Parser b+ {parser = f} *> {parser = g} =++ { parser s =+ f s |> λ {parsed = {some = x}, rest = zz} = g zz+ | {parsed = {none}, rest = x} =+ {parsed = {none}, rest = x} }++++ inline (<|>):</code></pre>+<p>Alternative will try the first parser, and applies the second only if the first fails <em>and</em> consumes no input from the text.</p>+<pre><code> Parser a -> Parser a -> Parser a+ {parser = f} <|> {parser = g} =++ let h text {parsed = {none}, rest = textt} when text == textt =+ g text+ | _ x = x++ in {parser text = h text (f text)}++++ inline try':</code></pre>+<p>Tries to apply a parser, but restores the parser state in the case of a failure. This is useful with combinators that check the state of the consumed text, like <code><|></code></p>+<pre><code> Parser a -> Parser a+ = lift λ (x & {_, parsed: {none}}) =+ {parsed: {none}, rest: x.text}+ | x = x.f'++++ inline string:</code></pre>+<p>A parser that matches a string. Unlike Haskell's Parsec library, parsec.formal will not consume any input if the entire string doesn't match. This is for efficiency reasons currently, but may change in the future.</p>+<pre><code> String -> Parser String + | x = { parser y = + let sub = do! `y.substring(0, x.length)`+ if (sub == x) + { rest = do! `y.substring(x.length)`+ parsed = {some = x} }+ else {rest = y, parsed = {none}} }++++ inline push! : x -> Array x -> Array x+ | x xs = do! `xs.unshift(x); xs`++ many:</code></pre>+<p>Applies a parser repeatedly, until parsing fails.</p>+<pre><code> Parser a -> Parser (Array a)+ = lift λ (x & {_, parsed: {none}}) =+ {parsed: {some: []}, rest = x.rest}+ | (y & {_, parsed: {some: x}}) =+ (push! x <$> many {parser: y.f}).parser y.rest++++ module "Testing"++ <span class='test' id='test_141_141'>{some = "ten"} == run_parser (string "ten") "tens"</span>+ <span class='test' id='test_142_142'>{some = "tenten"} == run_parser ((λx = x +++ x) <$> string "ten") "tenfingers"</span>++ <span class='test' id='test_144_145multi'>{parsed = {some = "tenten"}, rest = "fingers"} + == ((λx = x +++ x) <$> string "ten").parser "tenfingers"</span>++ <span class='test' id='test_147_148multi'>var result = run_parser ((λx y = y +++ x) <$> string "ten" <*> string "fingers") "tenfingers"+ result == {some: "fingersten"}</span>++ <span class='test' id='test_150_151multi'>var result = run_parser (string "ten" <|> string "eleven") "eleven"+ result == {some: "eleven"}</span>++ <span class='test' id='test_153_154multi'>var result = run_parser (string "ten" *> string "fingers") "tenfingers"+ result == {some: "fingers"}</span>++ <span class='test' id='test_156_158multi'>var parser = (string "ten" *> string "fingers") <|> string "tentoes"+ result = run_parser parser "tentoes"+ result == {none}</span>++ <span class='test' id='test_160_162multi'>var parser = try' (string "ten" *> string "fingers") <|> string "tentoes"+ result = run_parser parser "tentoes"+ result == {some: "tentoes"}</span>++ <span class='test' id='test_164_166multi'>var parser = many (string "ten")+ result = run_parser parser "tententententen"+ result == {some: ["ten", "ten", "ten", "ten", "ten"]}</span></code></pre><h2 id="tests">Tests</h2>+<p>A collection of tests for compiler bugs, benchmarking, etc.</p>+<h2 id="benchmarks">Benchmarks</h2>+<p>A collection of simple benchmarks. You can view the results by opening your browser's terminal.</p>+<pre><code>module "Benchmarks for the prelude"++ title x = + do log "\r "+ log x+ return true++ open prelude+ open prelude.speedtest+ open prelude.list+ open prelude.string</code></pre>+<p>Here we have 5 implementations of (Project Euler problem #1)[http://projecteuler.net/problem=1]. The first is simply a native JS implementation.</p>+<pre><code> euler_1 x = `var sum = 0;+ for (var i = 1; i < x; i++) {+ if (i % 3 == 0 || i % 5 == 0) sum += i;+ };+ return sum;`</code></pre>+<p>The second is a tail recursive. The formal compiler will optimize simple functions which are tail recursive into javascript <code>for</code> loops automatically, making them much faster.</p>+<pre><code> euler_2 x y when x < 3 = y+ | x y when x % 3 == 0 || x % 5 == 0 =+ euler_2 (x - 1) (y + 1)+ | x y = euler_2 (x - 1) y++ euler_3 x when x < 3 = 0+ euler_3 x = if x % 3 == 0 || x % 5 == 0+ then 1 + euler_3 (x - 1)+ else euler_3 (x - 1)++ euler_4 z = yield 1 .. z + |> filter (λx = x % 3 == 0 || x % 5 == 0)+ |> sum++ euler_5 x y when x < 3 = y+ | x y when do! `x % 3 == 0 || x % 5 == 0` =+ euler_5 (x - 1) (y + 1)+ | x y = euler_5 (x - 1) y++ <span class='test' id='test_56_70multi'>do! title "Relative Speeds (10k)"++ w <- time (euler_1 10000)+ x <- time yield euler_2 10000 0+ y <- time yield euler_3 10000+ z <- time (euler_4 10000)+ q <- time yield euler_5 10000 0++ log " Native JS: `w / 1000`s"+ log " Formal TCO Unboxed: `q / 1000`s"+ log " Formal TCO: `x / 1000`s"+ log " Formal Recursive: `y / 1000`s"+ log " Formal list: `z / 1000`s"++ return <| (x <= y && y < z)</span>++ <span class='test' id='test_72_72'>string? (err yield euler_3(250000)).message</span>++ <span class='test' id='test_74_88multi'>do! title "Relative Speeds (2.5M)"++ w <- time (euler_1 2500000)+ x <- time yield euler_2 2500000 0+ y <- time yield euler_5 2500000 0++ log " Native JS: `w / 1000`s"+ log " Formal TCO Unboxed: `y / 1000`s"+ log " Formal TCO: `x / 1000`s"+ log " Formal Recursive: `err yield euler_3(250000)`"+ log " Formal list: `err (euler_4 250000)`"++ log ""++ return <| (w < x)</span>+++module "Tests for partial records"++ open prelude++ <span class='test' id='test_95_96multi'>var f {a: x, b: y, _ } = x + y+ f { a: 5, b: 5, c: 5 } == f { a: 5, b: 5, d: 5 }</span>++ <span class='test' id='test_98_100multi'>var f {a: 1, b: 1, _ } = 2+ f {b: 2, c: 2, _ } = 2+ f {a:1,b:1,c:3,d:5} + f {a:1,b:2,c:2,e:5} == 4</span>++ <span class='test' id='test_102_105multi'>var f { a = 1, b = 2, _ } = 1+ g { b = 2, c = 3, _ } = 2+ x = { a = 1, b = 2, c = 3, d = 4 }+ f x + 1 == g x</span>++module "Tests for TCO bugs"++ open prelude+ open prelude.list++ rev_1 y = + var r rest [:] = rest+ | rest { head: x, tail: xs } = + r (x :: rest) xs++ r {nil} y++ rev_2 = + var rrr rest [:] = rest+ rrr rest { head: x, tail: xs } = + rrr (x :: rest) xs++ rrr {nil}++ <span class='test' id='test_126_126'>rev_2 [: 1, 2, 3, 4 ] == [: 4, 3, 2, 1 ]</span>++ test_x = [: 1, 2, 3, 4, 5, 6, 7 ]++ <span class='test' id='test_130_130'>rev_2 test_x == rev_1 test_x</span>+ <span class='test' id='test_131_131'>rev_1 test_x == reverse test_x</span>+ <span class='test' id='test_132_132'>length (rev_2 test_x) == length (rev_1 test_x)</span>+ <span class='test' id='test_133_133'>length (rev_2 test_x) == length test_x</span>+ <span class='test' id='test_134_134'>length (rev_1 test_x) == length (reverse test_x)</span>+++module "Tests for parser bugs"++ open prelude+ open prelude.string+ open prelude.html++ <span class='test' id='test_143_144multi'>var x = do! `[ { x: 1}, {x: 2}, {x: 3} ]`+ stringify (x !! 0).x == "1"</span></code></pre><script>prelude.html.table_of_contents()</script><div id="test_suite">+</div>++</div>+</div>+</body>+ </html>
+ src/formal/prelude.js view
@@ -0,0 +1,1166 @@+// Input 0+var i = void 0, j = !0;+function k(p) {+ return p instanceof Array+}+function s() {+ throw"Pattern Match Exhausted";+}+var v = new function() {+ function p(a) {+ var b;+ 0 === a ? b = 0 : 1 === a ? b = 1 : (b = p(a - 1), a = p(a - 2), b += a);+ return b+ }+ function h(a) {+ return function(b) {+ var e = a, f;+ if(e === b) {+ return j+ }+ e = a;+ f = b;+ if("object" === typeof e) {+ var c = j, d;+ for(d in e) {+ c = c && f.hasOwnProperty(d) && h(e[d])(f[d])+ }+ e = Object.keys(e).length === Object.keys(f).length;+ return c && e+ }+ e = a;+ f = b;+ if(k(e)) {+ d = j;+ for(c in e) {+ d = d && h(e[c])(f[c])+ }+ return d && e.length == f.length+ }+ return!1+ }+ }+ function m(a) {+ return function() {+ return a+ }+ }+ this.object_ = function(a) {+ return"object" === typeof a+ };+ this.array_ = k;+ this.string_ = function(a) {+ return"string" === typeof a+ };+ this.type_ = function(a) {+ return typeof a+ };+ this.not = function(a) {+ return!a+ };+ this._grea_grea_eq = function(a) {+ return function(b) {+ return b(a())+ }+ };+ this._grea_grea = function(a) {+ return function(b) {+ return function() {+ a();+ return b()+ }+ }+ };+ this._return_ = m;+ this.log = function(a) {+ return function() {+ return console.log(a)+ }+ };+ this._and_and = function(a) {+ return function(b) {+ return a && b+ }+ };+ this._or_or = function(a) {+ return function(b) {+ return a || b+ }+ };+ this._star = function(a) {+ return function(b) {+ return a * b+ }+ };+ this._forw = function(a) {+ return function(b) {+ return a / b+ }+ };+ this._perc = function(a) {+ return function(b) {+ return a % b+ }+ };+ this._plus = function(a) {+ return function(b) {+ return a + b+ }+ };+ this._minu = function(a) {+ return function(b) {+ return a - b+ }+ };+ this._less_eq = function(a) {+ return function(b) {+ return a <= b+ }+ };+ this._grea_eq = function(a) {+ return function(b) {+ return a >= b+ }+ };+ this._less = function(a) {+ return function(b) {+ return a < b+ }+ };+ this._grea = function(a) {+ return function(b) {+ return a > b+ }+ };+ this._bang_eq = function(a) {+ return function(b) {+ return!h(a)(b)+ }+ };+ this._forw_eq = function(a) {+ return function(b) {+ return!h(a)(b)+ }+ };+ this._eq_eq = h;+ this.fib = p;+ this.speedtest = new function() {+ function a(b) {+ return 0 === b ? 0 : 1 === b ? 1 : a(b - 1) + a(b - 2)+ }+ function b() {+ return(new Date).getTime()+ }+ this.get_time = b;+ this.time = function(a) {+ return function() {+ var f = b();+ a();+ return b() - f+ }+ };+ this.fast_fib = a;+ this.floor = Math.floor+ };+ this._less_or = function(a) {+ return function(b) {+ return a(b)+ }+ };+ this._or_grea = function(a) {+ return function(b) {+ return b(a)+ }+ };+ this._less_col = function(a) {+ return function(b) {+ return a(b)+ }+ };+ this._comp_col = function(a) {+ return function(b) {+ return function(e) {+ return a(b(e))+ }+ }+ };+ this.id = function(a) {+ return a+ };+ this.flip = function(a) {+ return function(b) {+ return function(e) {+ return a(e)(b)+ }+ }+ };+ this._apos = function(a) {+ return function(b) {+ return b(a)+ }+ };+ this.string = new function() {+ function a(a) {+ return a.replace(/\s+$/, "")+ }+ function b(a) {+ return a.replace(/^\s+/, "")+ }+ this.lstrip = b;+ this.rstrip = a;+ this.strip = function(e) {+ return b(a(e))+ };+ this._plus_plus_plus = function(a) {+ return function(b) {+ return"" + a + b+ }+ }+ };+ this.err = function(a) {+ var b;+ try {+ a(), b = !1+ }catch(e) {+ b = e+ }+ return b+ };+ this.option = new function() {+ this.option = function(a) {+ return function(b) {+ if(b.hasOwnProperty("none")) {+ return a+ }+ var e = b.some;+ if(b.hasOwnProperty("some")) {+ return e+ }+ s()+ }+ }+ };+ this.html = new function() {+ function a(a) {+ return function(b) {+ return function() {+ return a.push(b)+ }+ }+ }+ function b(a) {+ return function(b) {+ return b.split(a)+ }+ }+ function e(a) {+ return JSON.stringify(a)+ }+ function f(a) {+ return function() {+ return window.addEventListener("load", a, !1)+ }+ }+ function c(a) {+ return function(b) {+ return function() {+ return $(b.element).append($(a.element).detach())+ }+ }+ }+ function d(a) {+ return function() {+ var b = $(a).get(0);+ return{add_class:function(a) {+ return function() {+ return b.setAttribute("class", b.getAttribute("class") + " " + a)+ }+ }, add_style:function(a) {+ return function(t) {+ return function() {+ b.style[a] = t+ }+ }+ }, element:b, inner:function() {+ return b.innerHTML+ }, on_click:function(a) {+ return function() {+ b.onclick = a+ }+ }, set:function(a) {+ return function() {+ b.innerHTML = a+ }+ }}+ }+ }+ this.get = d;+ this.$_eq = function(a) {+ return function(b) {+ return function() {+ if("undefined" != typeof $) {+ var c = $(a).get(0);+ "undefined" != typeof c && (c.innerHTML = b)+ }+ }+ }+ };+ var g;+ this.$_or = g = function(a) {+ return function(b) {+ return function(c) {+ return function() {+ return $(a).css(b, c)+ }+ }+ }+ };+ this.$_comp = function(a) {+ return function(b) {+ return function() {+ return $(a).addClass(b)+ }+ }+ };+ this.$_plus = function(a) {+ return function(b) {+ return function() {+ return $(a).append(b)+ }+ }+ };+ this.div = function(a) {+ return function() {+ return"<div id='" + a + "'/>"+ }+ };+ this.move = c;+ this.on_load = f;+ this.stringify = e;+ this._bang_bang = function(a) {+ return function(b) {+ return a[b]+ }+ };+ this.with_page = function(a) {+ return function() {+ var b = $("body").clone(), c = a();+ $("body").replaceWith(b);+ return c+ }+ };+ this.split = b;+ var u = 0, l = {reportRunnerResults:function() {+ return phantom.exit(u)+ }, reportSpecResults:function(a) {+ if(a.results().passed()) {+ var c = {}, a = function() {+ return c+ }+ }else {+ var d = a.results_.items_, t;+ t = a.description.split("__::__")[1];+ var x;+ x = JSON.stringify(d[0].expected);+ var y;+ y = JSON.stringify(d[0].actual);+ var a = b("__::__")(a.description), a = b("_")(a[0])[0], z = e(parseInt(a) + 1), a = function() {+ var a;+ if(h(u)(0)) {+ a = function() {+ return console.log("\r ")+ }+ }else {+ var b = {};+ a = function() {+ return b+ }+ }+ a();+ u = 1;+ console.log("Test failed at line " + z + ("\n\n" + t + ("\n\n Expected " + x + ("\n Actual " + y + ""))));+ return console.log("")+ }+ }+ return a()+ }};+ this.console_runner = function() {+ var a = jasmine.getEnv();+ a.addReporter(l);+ return a.execute()+ };+ this.push = a;+ var n = {failed:0, messages:[], reportRunnerResults:function() {+ var a;+ if(0 < n.failed) {+ var b = n.messages;+ a = function() {+ return console.log(b)+ }+ }else {+ var c = {};+ a = function() {+ return c+ }+ }+ a();+ return console.log("" + (n.total - n.failed) + ("/" + n.total + " tests passed"))+ }, reportSpecResults:function(b) {+ var c = b.results().passed();+ n.total++;+ if(c) {+ var d = {}, c = function() {+ return d+ }+ }else {+ c = function() {+ n.failed++;+ a(n.messages)(b.description)();+ return{}+ }+ }+ return c()+ }, total:0};+ this.console_reporter = n;+ this.table_of_contents = f(function() {+ $("code").addClass("prettyprint");+ $("code").addClass("lang-hs");+ g(".test")("position")("relative")();+ g(".test")("left")("50px")();+ prettyPrint();+ var a = new jasmine.TrivialReporter, b = new jasmine.FormalReporter, f = jasmine.getEnv();+ f.addReporter(a);+ f.addReporter(b);+ f.addReporter(n);+ f.execute();+ a = d(".jasmine_reporter")();+ b = d("#test_suite")();+ return c(a)(b)()+ })+ };+ var l = new function() {+ function a(a) {+ return function(b) {+ function c(d) {+ if(d.hasOwnProperty("nil")) {+ return b+ }+ var f = d.head, g = d.tail;+ if(d.hasOwnProperty("head") && d.hasOwnProperty("tail")) {+ return a(f)(c(g))+ }+ s()+ }+ return c+ }+ }+ function b(a) {+ return function(b) {+ if(b.hasOwnProperty("nil")) {+ throw"Foldl1 called on empty list";+ }+ return e(a)(r(b))(q(b))+ }+ }+ function e(a) {+ return function(b) {+ return function(c) {+ for(var d = i, f = b;"undefined" == typeof d;) {+ var g = f;+ if(c.hasOwnProperty("nil")) {+ d = g+ }else {+ var g = f, e = c.head, q = c.tail;+ c.hasOwnProperty("head") && c.hasOwnProperty("tail") ? (f = a(g)(e), c = q, d = i) : s()+ }+ }+ return d+ }+ }+ }+ function f(a) {+ for(var b = i, c = {nil:j};"undefined" == typeof b;) {+ var d = c;+ if(a.hasOwnProperty("nil")) {+ b = d+ }else {+ var d = c, f = a.head, g = a.tail;+ a.hasOwnProperty("head") && a.hasOwnProperty("tail") ? (c = {head:f, tail:d}, a = g, b = i) : s()+ }+ }+ return b+ }+ function c(a) {+ return function(b) {+ var d = a;+ if(b.hasOwnProperty("nil")) {+ return{nil:j}+ }+ var d = a, f = d(r(b)), b = c(d)(q(b));+ return{head:f, tail:b}+ }+ }+ function d(a) {+ return function(b) {+ var c = a;+ if(b.hasOwnProperty("nil")) {+ return{nil:j}+ }+ var c = a, f = b;+ if(c(r(f))) {+ return b = r(f), c = d(c)(q(f)), {head:b, tail:c}+ }+ c = a;+ c = d(c);+ b = q(b);+ return c(b)+ }+ }+ function g(a) {+ return function(b) {+ var c = b;+ if(a.hasOwnProperty("nil")) {+ return c+ }+ var c = a.head, d = a.tail;+ if(a.hasOwnProperty("head") && a.hasOwnProperty("tail")) {+ return b = g(d)(b), {head:c, tail:b}+ }+ s()+ }+ }+ function h(a) {+ return function(b) {+ if(0 === a) {+ b = {nil:j}+ }else {+ var c = h(a - 1)(b), b = {head:b, tail:c}+ }+ return b+ }+ }+ function l(a) {+ if(a.hasOwnProperty("nil")) {+ return 0+ }+ var b = a.tail;+ if(a.hasOwnProperty("head") && a.hasOwnProperty("tail")) {+ return 1 + l(b)+ }+ s()+ }+ function n(a) {+ return function(b) {+ var c = b;+ if(0 === a) {+ return{nil:j}+ }+ c = b;+ b = r(c);+ c = n(a - 1)(q(c));+ return{head:b, tail:c}+ }+ }+ function q(a) {+ var b = a.tail;+ if(a.hasOwnProperty("head") && a.hasOwnProperty("tail")) {+ return b+ }+ if(a.hasOwnProperty("nil")) {+ throw"Tail called on empty list";+ }+ s()+ }+ function r(a) {+ var b = a.head;+ if(a.hasOwnProperty("head") && a.hasOwnProperty("tail")) {+ return b+ }+ if(a.hasOwnProperty("nil")) {+ throw"Head called on empty list";+ }+ s()+ }+ this._col_col = function(a) {+ return function(b) {+ return{head:a, tail:b}+ }+ };+ this.empty_ = function(a) {+ return a.hasOwnProperty("nil") ? j : !1+ };+ this.head = r;+ this.tail = q;+ this.last = function(a) {+ for(var b = i;"undefined" == typeof b;) {+ var c = a.head;+ if(a.hasOwnProperty("head") && a.hasOwnProperty("tail") && a.tail.hasOwnProperty("nil")) {+ b = c+ }else {+ if(c = a.tail, a.hasOwnProperty("head") && a.hasOwnProperty("tail")) {+ a = c, b = i+ }else {+ if(a.hasOwnProperty("nil")) {+ throw"Last called on empty list";+ }+ s()+ }+ }+ }+ return b+ };+ this.take = n;+ this.drop = function(a) {+ return function(b) {+ for(var c = i, d = a;"undefined" == typeof c;) {+ c = b, 0 !== d && (c = b, d -= 1, b = q(c), c = i)+ }+ return c+ }+ };+ this._comp_comp = function(a) {+ return function(b) {+ for(var c = i, d = {nil:j};"undefined" == typeof c;) {+ var c = b, f = d;+ c >= a ? (b = c - 1, d = {head:c, tail:f}, c = i) : c = f = d+ }+ return c+ }+ };+ this.take_while = function(a) {+ return function(b) {+ var c = a;+ if(b.hasOwnProperty("nil")) {+ return{nil:j}+ }+ var c = a, f;+ c(r(b)) ? (f = r(b), b = d(c)(q(b)), f = {head:f, tail:b}) : f = {nil:j};+ return f+ }+ };+ this.drop_while = function(a) {+ return function(b) {+ for(var c = i, d = a;"undefined" == typeof c;) {+ if(c = d, b.hasOwnProperty("nil")) {+ c = {nil:j}+ }else {+ var c = d, f = b;+ c(r(f)) ? (d = c, b = q(f), c = i) : c = f = b+ }+ }+ return c+ }+ };+ this.length = l;+ this.init = h;+ this._plus_plus = g;+ this.filter = d;+ this.map = c;+ this.reverse = f;+ this.take_apos = function(a) {+ return function(b) {+ for(var c = i, d = a, g = {nil:j};"undefined" == typeof c;) {+ if(c = g, 0 !== d) {+ var e = b, c = g, d = d - 1, b = q(e), g = {head:r(e), tail:c}, c = i+ }+ }+ return f(c)+ }+ };+ this.foldl = e;+ this.foldl1 = b;+ this.foldr = a;+ this.foldr1 = function(b) {+ return function(c) {+ if(c.hasOwnProperty("nil")) {+ throw"Foldr1 called on empty list";+ }+ return a(b)(r(c))(q(c))+ }+ };+ this.all_ = function(a) {+ var d = b(function(a) {+ return function(b) {+ return a && b+ }+ }), f = c(a);+ return function(a) {+ return d(f(a))+ }+ };+ this.any_ = function(a) {+ var d = b(function(a) {+ return function(b) {+ return a || b+ }+ }), f = c(a);+ return function(a) {+ return d(f(a))+ }+ };+ this.sum = b(function(a) {+ return function(b) {+ return a + b+ }+ });+ this.product = b(function(a) {+ return function(b) {+ return a * b+ }+ });+ var w = b(function(a) {+ return function(b) {+ return g(a)(b)+ }+ });+ this.concat = w;+ this.concat_map = function(a) {+ return function(b) {+ return w(c(a)(b))+ }+ };+ this.maximum = b(function(a) {+ return function(b) {+ return a > b ? a : b+ }+ });+ this.minimum = b(function(a) {+ return function(b) {+ return a > b ? b : a+ }+ })+ };+ this.list = l;+ this.seq = new function() {+ function a(b) {+ if(b.hasOwnProperty("end")) {+ return{end:j}+ }+ var c = b.seq;+ if(b.hasOwnProperty("seq")) {+ var d = i;+ return{seq:function() {+ if(!d) {+ var b;+ b = c();+ var f = b.elem, g = b.next;+ if(b.hasOwnProperty("elem") && b.hasOwnProperty("next")) {+ var e = {elem:f, next:a(g)};+ b = function() {+ return e+ }+ }else {+ s(), b = i+ }+ d = b()+ }+ return d+ }}+ }+ s()+ }+ function b(a) {+ return function(c) {+ return function(d) {+ if(c.hasOwnProperty("end") || d.hasOwnProperty("end")) {+ return{end:j}+ }+ var f = c.seq, g = d.seq;+ if(c.hasOwnProperty("seq") && d.hasOwnProperty("seq")) {+ return{seq:function() {+ var c;+ var d = f();+ c = d.elem;+ var e = d.next;+ if(d.hasOwnProperty("elem") && d.hasOwnProperty("next")) {+ var d = g(), r = d.elem, h = d.next;+ if(d.hasOwnProperty("elem") && d.hasOwnProperty("next")) {+ var l = {elem:a(c)(r), next:b(a)(e)(h)};+ c = function() {+ return l+ }+ }else {+ s(), c = i+ }+ }else {+ s(), c = i+ }+ return c()+ }}+ }+ s()+ }+ }+ }+ function e(a) {+ if(a.hasOwnProperty("end")) {+ return{nil:j}+ }+ var b = a.seq;+ if(a.hasOwnProperty("seq")) {+ var b = b(), a = b.elem, c = b.next;+ if(b.hasOwnProperty("elem") && b.hasOwnProperty("next")) {+ var d, b = e(c);+ d = {head:a, tail:b};+ a = function() {+ return d+ }+ }else {+ s(), a = i+ }+ return a()+ }+ s()+ }+ function f(a) {+ if(a.hasOwnProperty("nil")) {+ return{end:j}+ }+ var b = a.head, c = a.tail;+ if(a.hasOwnProperty("head") && a.hasOwnProperty("tail")) {+ return{seq:function() {+ return{elem:b, next:f(c)}+ }}+ }+ s()+ }+ function c(a) {+ return function(b) {+ return{seq:function() {+ return{elem:b, next:c(a)(a(b))}+ }}+ }+ }+ var d = l.tail || window.tail, g = l.take || window.take;+ this.seq = function(a) {+ return{seq:a}+ };+ this.iterate = c;+ this.from_list = f;+ this.to_list = e;+ this.take = g = function(a) {+ return function(b) {+ if(b.hasOwnProperty("end") || 0 === a) {+ return{end:j}+ }+ var c = b.seq;+ if(b.hasOwnProperty("seq")) {+ return{seq:function() {+ var b;+ b = c();+ var d = b.elem, f = b.next;+ if(b.hasOwnProperty("elem") && b.hasOwnProperty("next")) {+ var e = {elem:d, next:g(a - 1)(f)};+ b = function() {+ return e+ }+ }else {+ s(), b = i+ }+ return b()+ }}+ }+ s()+ }+ };+ this.zip_with = b;+ this._col_col_col = function(a) {+ return function(b) {+ return{seq:function() {+ return{elem:a, next:b()}+ }}+ }+ };+ this.tail = d = function(a) {+ if(a.hasOwnProperty("end")) {+ throw"tail called on empty seq";+ }+ var b = a.seq;+ if(a.hasOwnProperty("seq")) {+ return b().next+ }+ s()+ };+ var h = this.to_lazy = a, p = m({seq:function() {+ var a = b(function(a) {+ return function(b) {+ return a + b+ }+ })(n), c = d(n);+ return{elem:1, next:a(c)}+ }}), n;+ this.fibs = n = h({seq:function() {+ return{elem:1, next:p()}+ }})+ };+ this.Formal_Z = new function() {+ var a = l.map || window.map, b = l.concat_map || window.concat_map;+ this.map = a = function(a) {+ return function(b) {+ return function(d) {+ return a.map(d)(b)+ }+ }+ };+ this.bind = function(a) {+ return function(b) {+ var d = a.ret;+ if(a.hasOwnProperty("ret")) {+ return d(b)+ }+ s()+ }+ };+ var e = {map:function(a) {+ return function(b) {+ if(b.hasOwnProperty("nil")) {+ return{nil:j}+ }+ var d = b.head, g = b.tail;+ if(b.hasOwnProperty("head") && b.hasOwnProperty("tail")) {+ return{head:a(d), tail:e.map(a)(g)}+ }+ s()+ }+ }};+ this.list_functor = e;+ this.list_monad = {_grea_grea_eq:function(a) {+ return function(c) {+ return b(c)(a)+ }+ }, _return_:function(a) {+ return{head:a, tail:{nil:j}}+ }};+ this.js_monad = {_grea_grea_eq:function(a) {+ return function(b) {+ return b(a())+ }+ }, _return_:function(a) {+ return function() {+ return a+ }+ }}+ }+};+("undefined" == typeof global ? window : global).prelude = v;+("undefined" == typeof global ? window : global).parsec = new function() {+ function p(a) {+ return function(b) {+ b.unshift(a);+ return b+ }+ }+ function h(a) {+ return function(b) {+ var e = b.parser;+ if(b.hasOwnProperty("parser")) {+ return{parser:function(b) {+ var c = e(b);+ return a({f:e, f_apos:c, parsed:c.parsed, rest:c.rest, text:b})+ }}+ }+ s()+ }+ }+ var m = v._eq_eq || window._eq_eq;+ this.run_parser = function(a) {+ return function(b) {+ var e = a.parser;+ if(a.hasOwnProperty("parser")) {+ return b = e(b), e = b.parsed.some, b.hasOwnProperty("parsed") && b.parsed.hasOwnProperty("some") ? {some:e} : {none:j}+ }+ s()+ }+ };+ this._less$_grea = function(a) {+ return function(b) {+ var e = b.parser;+ if(b.hasOwnProperty("parser")) {+ return{parser:function(b) {+ var b = e(b), c = b.parsed.some, d = b.rest;+ b.hasOwnProperty("parsed") && b.hasOwnProperty("rest") && b.parsed.hasOwnProperty("some") ? b = {parsed:{some:a(c)}, rest:d} : (c = b.rest, b.hasOwnProperty("parsed") && b.hasOwnProperty("rest") && b.parsed.hasOwnProperty("none") ? b = {parsed:{none:j}, rest:c} : (s(), b = i));+ return b+ }}+ }+ s()+ }+ };+ this._less_star_grea = function(a) {+ return function(b) {+ var e = a.parser, f = b.parser;+ if(a.hasOwnProperty("parser") && b.hasOwnProperty("parser")) {+ return{parser:function(a) {+ var b = e(a), a = b.parsed.some, g = b.rest;+ if(b.hasOwnProperty("parsed") && b.hasOwnProperty("rest") && b.parsed.hasOwnProperty("some")) {+ var b = f(g), g = b.parsed.some, h = b.rest;+ b.hasOwnProperty("parsed") && b.hasOwnProperty("rest") && b.parsed.hasOwnProperty("some") ? a = {parsed:{some:a(g)}, rest:h} : (g = b.rest, b.hasOwnProperty("parsed") && b.hasOwnProperty("rest") && b.parsed.hasOwnProperty("none") ? a = {parsed:{none:j}, rest:g} : (s(), a = i))+ }else {+ a = b.rest, b.hasOwnProperty("parsed") && b.hasOwnProperty("rest") && b.parsed.hasOwnProperty("none") ? a = {parsed:{none:j}, rest:a} : (s(), a = i)+ }+ return a+ }}+ }+ s()+ }+ };+ this.lift = h;+ this._star_grea = function(a) {+ return function(b) {+ var e = a.parser, f = b.parser;+ if(a.hasOwnProperty("parser") && b.hasOwnProperty("parser")) {+ return{parser:function(a) {+ var a = e(a), b = a.parsed.some, b = a.rest;+ a.hasOwnProperty("parsed") && a.hasOwnProperty("rest") && a.parsed.hasOwnProperty("some") ? a = f(b) : (b = a.rest, a.hasOwnProperty("parsed") && a.hasOwnProperty("rest") && a.parsed.hasOwnProperty("none") ? a = {parsed:{none:j}, rest:b} : (s(), a = i));+ return a+ }}+ }+ s()+ }+ };+ this._less_or_grea = function(a) {+ return function(b) {+ var e = a.parser, f = b.parser;+ if(a.hasOwnProperty("parser") && b.hasOwnProperty("parser")) {+ return{parser:function(a) {+ var b = e(a), g = b.rest;+ return b.hasOwnProperty("parsed") && b.hasOwnProperty("rest") && b.parsed.hasOwnProperty("none") && m(a)(g) ? f(a) : b+ }}+ }+ s()+ }+ };+ this.try_apos = h(function(a) {+ return a.hasOwnProperty("parsed") && a.parsed.hasOwnProperty("none") ? {parsed:{none:j}, rest:a.text} : a.f_apos+ });+ this.string = function(a) {+ return{parser:function(b) {+ var e = b.substring(0, a.length);+ return m(e)(a) ? {parsed:{some:a}, rest:b.substring(a.length)} : {parsed:{none:j}, rest:b}+ }}+ };+ this.push_excl = p;+ var l = h(function(a) {+ var b = a;+ if(a.hasOwnProperty("parsed") && a.parsed.hasOwnProperty("none")) {+ return{parsed:{some:[]}, rest:b.rest}+ }+ b = a.parsed.some;+ if(a.hasOwnProperty("parsed") && a.parsed.hasOwnProperty("some")) {+ var e = p(b);+ var b = l({parser:a.f}), f = b.parser;+ b.hasOwnProperty("parser") ? b = {parser:function(a) {+ var a = f(a), b = a.parsed.some, g = a.rest;+ a.hasOwnProperty("parsed") && a.hasOwnProperty("rest") && a.parsed.hasOwnProperty("some") ? a = {parsed:{some:e(b)}, rest:g} : (b = a.rest, a.hasOwnProperty("parsed") && a.hasOwnProperty("rest") && a.parsed.hasOwnProperty("none") ? a = {parsed:{none:j}, rest:b} : (s(), a = i));+ return a+ }} : (s(), b = i);+ return b.parser(a.rest)+ }+ s()+ });+ this.many = l;+ this.Testing = new function() {+ }+};+("undefined" == typeof global ? window : global).Benchmarks_for_the_prelude = new function() {+ function p(b) {+ for(var d = i;"undefined" == typeof d;) {+ if(d = b, 3 > d) {+ d = 0+ }else {+ var d = b, g = i, g = a(d % 3)(0), e = a(d % 5)(0);+ g || e ? g = 1 + p(d - 1) : (b = d - 1, g = i);+ d = g+ }+ }+ return d+ }+ this.title = function(a) {+ return function() {+ return h(l("\r "))(function() {+ return h(l(a))(function() {+ return m(j)+ })+ })()+ }+ };+ var h = v._grea_grea_eq || window._grea_grea_eq, m = v._return_ || window._return_, l = v.log || window.log, a = v._eq_eq || window._eq_eq, b = v._comp_comp || window._comp_comp, e = v.filter || window.filter, f = v.sum || window.sum, b = v.list._comp_comp || window._comp_comp, e = v.list.filter || window.filter, f = v.list.sum || window.sum;+ this.euler_1 = function(a) {+ return function() {+ for(var b = 0, g = 1;g < a;) {+ if(0 == g % 3 || 0 == g % 5) {+ b += g+ }+ g+++ }+ return b+ }+ };+ this.euler_2 = function(b) {+ return function(d) {+ for(var g = i, e = b;"undefined" == typeof g;) {+ var g = e, f = d;+ if(3 > g) {+ g = f+ }else {+ var g = e, f = d, h = a(g % 3)(0), l = a(g % 5)(0);+ h || l ? (e = g - 1, d = f + 1) : (g = e, f = d, e = g - 1, d = f);+ g = i+ }+ }+ return g+ }+ };+ this.euler_3 = p;+ this.euler_4 = function(c) {+ return function() {+ var d = b(1)(c), d = e(function(b) {+ var c = a(b % 3)(0), b = a(b % 5)(0);+ return c || b+ })(d);+ return f(d)+ }+ };+ this.euler_5 = function(a) {+ return function(b) {+ for(var e = i, f = a;"undefined" == typeof e;) {+ var e = f, h = b;+ 3 > e ? e = h : (e = f, h = b, 0 == e % 3 || 0 == e % 5 ? (f = e - 1, b = h + 1) : (e = f, h = b, f = e - 1, b = h), e = i)+ }+ return e+ }+ }+};+("undefined" == typeof global ? window : global).Tests_for_partial_records = new function() {+};+var A = new function() {+ this.rev_1 = function(h) {+ for(var m = i, l = {nil:j};"undefined" == typeof m;) {+ var a = l;+ if(h.hasOwnProperty("nil")) {+ m = a+ }else {+ var a = l, b = h.head, e = h.tail;+ h.hasOwnProperty("head") && h.hasOwnProperty("tail") ? (l = {head:b, tail:a}, h = e, m = i) : s()+ }+ }+ return m+ };+ var p = {nil:j};+ this.rev_2 = function(h) {+ for(var m = i, l = p;"undefined" == typeof m;) {+ var a = l;+ if(h.hasOwnProperty("nil")) {+ m = a+ }else {+ var a = l, b = h.head, e = h.tail;+ h.hasOwnProperty("head") && h.hasOwnProperty("tail") ? (l = {head:b, tail:a}, h = e, m = i) : s()+ }+ }+ return m+ };+ this.test_x = {head:1, tail:{head:2, tail:{head:3, tail:{head:4, tail:{head:5, tail:{head:6, tail:{head:7, tail:{nil:j}}}}}}}}+};+("undefined" == typeof global ? window : global).Tests_for_TCO_bugs = A;+("undefined" == typeof global ? window : global).Tests_for_parser_bugs = new function() {+};+
+ src/formal/prelude.spec.js view
@@ -0,0 +1,2095 @@+// Input 0+var is_array;+is_array = function(i) {+ return i instanceof Array+};+var __undefined__;+__undefined__ = "undefined";+var run;+run = function(i) {+ return i()+};+var error;+error = function(i) {+ throw i;+};+var exhaust;+exhaust = function() {+ error("Pattern Match Exhausted")+};+var __check;+__check = function(i, g) {+ return i.hasOwnProperty(g)+};+describe("", function() {+ describe("prelude", function() {+ var i;+ i = prelude.array_;+ var g;+ g = prelude._eq_eq;+ var e;+ e = prelude.fib;+ var a;+ a = prelude.speedtest;+ var c;+ c = prelude.id;+ var d;+ d = prelude.err;+ var f;+ f = prelude.list;+ i = prelude.array_;+ g = prelude._eq_eq;+ e = prelude.fib;+ a = prelude.speedtest;+ c = prelude.id;+ d = prelude.err;+ f = prelude.list;+ new function() {+ it("122_122__::__ not false", function() {+ expect(function() {+ try {+ var b;+ b = run(function() {+ return run(function() {+ return!0+ })+ });+ return b+ }catch(n) {+ return{error:n}+ }+ }()).toEqual(!0)+ });+ it("125_125__::__ object? {}", function() {+ expect(function() {+ try {+ var b;+ var n = {};+ b = run(function() {+ return run(function() {+ return"object" === typeof n+ })+ });+ return b+ }catch(a) {+ return{error:a}+ }+ }()).toEqual(!0)+ });+ it("126_126__::__ array? []", function() {+ expect(function() {+ try {+ return i([])+ }catch(b) {+ return{error:b}+ }+ }()).toEqual(!0)+ });+ it("127_127__::__ not (array? {})", function() {+ expect(function() {+ try {+ var b;+ var n = i({});+ b = run(function() {+ return run(function() {+ return!n+ })+ });+ return b+ }catch(a) {+ return{error:a}+ }+ }()).toEqual(!0)+ });+ it("128_128__::__ not (object? 0)", function() {+ expect(function() {+ try {+ var b;+ b = run(function() {+ return run(function() {+ return!1+ })+ });+ var n;+ n = run(function() {+ return run(function() {+ return!b+ })+ });+ return n+ }catch(a) {+ return{error:a}+ }+ }()).toEqual(!0)+ });+ it("149_152multi__::__ do! x <- `1 + 4`\n y <- `2 + 3`\n ans <- `x + y`\n return (10 == ans)", function() {+ expect(function() {+ try {+ return run(function() {+ var b = run, a = run(function() {+ return 5+ }), c = run(function() {+ return 5+ }), h = run(function() {+ return a + c+ }), f = g(10)(h);+ return b(function() {+ return f+ })+ })+ }catch(b) {+ return{error:b}+ }+ }()).toEqual(!0)+ });+ it("154_154__::__ 5 == do! return 5", function() {+ expect(5).toEqual(run(function() {+ return run(function() {+ return 5+ })+ }))+ });+ it("155_155__::__ 10 == do! `5 + 5`", function() {+ expect(10).toEqual(run(function() {+ return run(function() {+ return 10+ })+ }))+ });+ it("166_169multi__::__ var x = 0\n y = do z <- `x = 1`\n return z\n x == 0", function() {+ expect(function() {+ try {+ return g(0)(0)+ }catch(b) {+ return{error:b}+ }+ }()).toEqual(!0)+ });+ it("226_226__::__ (3 * 4) + 5 * 4 == 64 / 2", function() {+ expect(function(b) {+ return function(a) {+ return run(function() {+ return run(function() {+ return b + a+ })+ })+ }+ }(function(b) {+ return function(a) {+ return run(function() {+ return run(function() {+ return b * a+ })+ })+ }+ }(3)(4))(function(b) {+ return function(a) {+ return run(function() {+ return run(function() {+ return b * a+ })+ })+ }+ }(5)(4))).toEqual(function(b) {+ return function(a) {+ return run(function() {+ return run(function() {+ return b / a+ })+ })+ }+ }(64)(2))+ });+ it("227_227__::__ 4 - 1 != 5 - 10", function() {+ expect(function() {+ try {+ var b;+ b = run(function() {+ return run(function() {+ return 3+ })+ });+ var a = run(function() {+ return run(function() {+ return-5+ })+ }), c = g(b)(a);+ return run(function() {+ return run(function() {+ return!c+ })+ })+ }catch(f) {+ return{error:f}+ }+ }()).toEqual(!0)+ });+ it("228_228__::__ (10 >= 5 + 5) != (4 + 5 <= 10 - 2)", function() {+ expect(function() {+ try {+ var b, a = run(function() {+ return run(function() {+ return 10+ })+ });+ b = run(function() {+ return run(function() {+ return 10 >= a+ })+ });+ var c;+ c = run(function() {+ return run(function() {+ return 9+ })+ });+ var f = run(function() {+ return run(function() {+ return 8+ })+ }), h = run(function() {+ return run(function() {+ return c <= f+ })+ }), d = g(b)(h);+ return run(function() {+ return run(function() {+ return!d+ })+ })+ }catch(e) {+ return{error:e}+ }+ }()).toEqual(!0)+ });+ it("229_229__::__ ({test: 1} == {test: 1}) == true", function() {+ expect(g({test:1})({test:1})).toEqual(!0)+ });+ it("230_230__::__ ({test: 1} != {test: 1}) == false", function() {+ expect(function(b) {+ return function(a) {+ var c = g(b)(a);+ return run(function() {+ return run(function() {+ return!c+ })+ })+ }+ }({test:1})({test:1})).toEqual(!1)+ });+ describe("speedtest", function() {+ var b;+ b = prelude.speedtest.time;+ var a;+ a = prelude.speedtest.fast_fib;+ var c;+ c = prelude.speedtest.floor;+ b = prelude.speedtest.time;+ a = prelude.speedtest.fast_fib;+ c = prelude.speedtest.floor;+ new function() {+ it("262_262__::__ fast_fib 7 == fib 7", function() {+ expect(a(7)).toEqual(e(7))+ });+ it("271_273multi__::__ do! fast_time <- time yield fast_fib 30\n slow_time <- time yield fib 30\n return (floor (fast_time / slow_time * 100) >= 80)", function() {+ expect(function() {+ try {+ return run(function() {+ var f = run, d = b(function() {+ return a(30)+ }), g = run(d), d = b(function() {+ return e(30)+ }), j = run(d), d = c, m;+ m = run(function() {+ return run(function() {+ return g / j+ })+ });+ var k;+ k = run(function() {+ return run(function() {+ return 100 * m+ })+ });+ var p = d(k), s;+ s = run(function() {+ return run(function() {+ return 80 <= p+ })+ });+ return f(function() {+ return s+ })+ })+ }catch(f) {+ return{error:f}+ }+ }()).toEqual(!0)+ })+ }+ });+ it("282_282__::__ 3 |> (\u03bby = y + 1) |> \u03bby = y + 1 == 5", function() {+ expect(function() {+ try {+ var b;+ b = run(function() {+ return run(function() {+ return 4+ })+ });+ var a = g, c;+ c = run(function() {+ return run(function() {+ return b + 1+ })+ });+ return a(c)(5)+ }catch(f) {+ return{error:f}+ }+ }()).toEqual(!0)+ });+ it("283_283__::__ (\u03bby x z = x + y + z + 1) 1 <| 3 <| 4 == 9", function() {+ expect(function(b) {+ return function(a) {+ return b(a)+ }+ }(function(b) {+ return function(a) {+ return b(a)+ }+ }(function(b) {+ return function(a) {+ return function(c) {+ var f;+ f = run(function() {+ return run(function() {+ return a + b+ })+ });+ var h;+ h = run(function() {+ return run(function() {+ return f + c+ })+ });+ return run(function() {+ return run(function() {+ return h + 1+ })+ })+ }+ }+ }(1))(3))(4)).toEqual(9)+ });+ it("290_290__::__ (\u03bbx = x - 3) <: (\u03bbx = x - 3) <: 5 + 5 == 4", function() {+ expect(function(b) {+ return function(a) {+ return b(a)+ }+ }(function(b) {+ return run(function() {+ return run(function() {+ return b - 3+ })+ })+ })(function(b) {+ return function(a) {+ return b(a)+ }+ }(function(b) {+ return run(function() {+ return run(function() {+ return b - 3+ })+ })+ })(function(b) {+ return function(a) {+ return run(function() {+ return run(function() {+ return b + a+ })+ })+ }+ }(5)(5)))).toEqual(4)+ });+ it("301_301__::__ ((\u03bbx = x + 1) .: (\u03bbx = x * 2) .: \u03bbx = x - 3) 4 == 3", function() {+ expect(function(b) {+ return function(a) {+ return function(c) {+ return b(a(c))+ }+ }+ }(function(b) {+ return run(function() {+ return run(function() {+ return b + 1+ })+ })+ })(function(b) {+ return function(a) {+ return function(c) {+ return b(a(c))+ }+ }+ }(function(b) {+ return run(function() {+ return run(function() {+ return 2 * b+ })+ })+ })(function(b) {+ return run(function() {+ return run(function() {+ return b - 3+ })+ })+ }))(4)).toEqual(3)+ });+ it("302_302__::__ id [1, 2, 3] == [1, 2, 3]", function() {+ expect([1, 2, 3]).toEqual([1, 2, 3])+ });+ it("303_303__::__ flip (\u03bbx y = x - y) 3 5 == 2", function() {+ expect(function(b) {+ return function(a) {+ return function(c) {+ return b(c)(a)+ }+ }+ }(function(b) {+ return function(a) {+ return run(function() {+ return run(function() {+ return b - a+ })+ })+ }+ })(3)(5)).toEqual(2)+ });+ describe("string", function() {+ var b;+ b = b = prelude.string.strip;+ new function() {+ it('323_323__::__ strip " test " is "test"', function() {+ expect(b(" test ")).toEqual("test")+ });+ it('327_328multi__::__ let x = "test"\n in "hello `x`" is "hello test"', function() {+ expect(function() {+ try {+ var b = g, a;+ a = run(function() {+ return run(function() {+ return"hello test"+ })+ });+ var c;+ c = run(function() {+ return run(function() {+ return"" + a + ""+ })+ });+ return b(c)("hello test")+ }catch(f) {+ return{error:f}+ }+ }()).toEqual(!0)+ })+ }+ });+ describe("option", function() {+ var b;+ b = b = prelude.option.option;+ new function() {+ it("353_353__::__ option 3 {some: 2} == 2", function() {+ expect(b(3)({some:2})).toEqual(2)+ })+ }+ });+ describe("html", function() {+ var b;+ b = prelude.html.get;+ var a;+ a = prelude.html.div;+ b = prelude.html.get;+ a = prelude.html.div;+ new function() {+ it('426_436multi__::__ do! d <- div "test1"\n \n "body" $+ d\n "#test1" $= "I am a test!"\n \n text <- get "#test1"\n text <- text.inner\n \n "#test1" $= ""\n \n return (text == "I am a test!")', function() {+ expect(function() {+ try {+ return run(function() {+ var c = run, f = a("test1"), d = run(f);+ run(function() {+ return $("body").append(d)+ });+ run(function() {+ if("undefined" != typeof $) {+ var a;+ a = $("#test1").get(0);+ "undefined" != typeof a && (a.innerHTML = "I am a test!")+ }+ });+ f = b("#test1");+ f = run(f).inner;+ f = run(f);+ run(function() {+ if("undefined" != typeof $) {+ var a;+ a = $("#test1").get(0);+ "undefined" != typeof a && (a.innerHTML = "")+ }+ });+ var e = g(f)("I am a test!");+ return c(function() {+ return e+ })+ })+ }catch(c) {+ return{error:c}+ }+ }()).toEqual(!0)+ })+ }+ });+ describe("list", function() {+ var a;+ a = prelude.list.empty_;+ var f;+ f = prelude.list.head;+ var e;+ e = prelude.list.tail;+ var k;+ k = prelude.list.last;+ var h;+ h = prelude.list.take;+ var i;+ i = prelude.list.drop;+ var l;+ l = prelude.list._comp_comp;+ var j;+ j = prelude.list.take_while;+ var m;+ m = prelude.list.drop_while;+ var r;+ r = prelude.list.length;+ var p;+ p = prelude.list.init;+ var s;+ s = prelude.list._plus_plus;+ var w;+ w = prelude.list.filter;+ var x;+ x = prelude.list.map;+ var t;+ t = prelude.list.reverse;+ var B;+ B = prelude.list.take_apos;+ var y;+ y = prelude.list.foldl;+ var C;+ C = prelude.list.foldr;+ var u;+ u = prelude.list.all_;+ var v;+ v = prelude.list.any_;+ var z;+ z = prelude.list.sum;+ var D;+ D = prelude.list.product;+ var A;+ A = prelude.list.concat;+ var H;+ H = prelude.list.concat_map;+ var F;+ F = prelude.list.maximum;+ var G;+ G = prelude.list.minimum;+ a = prelude.list.empty_;+ f = prelude.list.head;+ e = prelude.list.tail;+ k = prelude.list.last;+ h = prelude.list.take;+ i = prelude.list.drop;+ l = prelude.list._comp_comp;+ j = prelude.list.take_while;+ m = prelude.list.drop_while;+ r = prelude.list.length;+ p = prelude.list.init;+ s = prelude.list._plus_plus;+ w = prelude.list.filter;+ x = prelude.list.map;+ t = prelude.list.reverse;+ B = prelude.list.take_apos;+ y = prelude.list.foldl;+ C = prelude.list.foldr;+ u = prelude.list.all_;+ v = prelude.list.any_;+ z = prelude.list.sum;+ D = prelude.list.product;+ A = prelude.list.concat;+ H = prelude.list.concat_map;+ F = prelude.list.maximum;+ G = prelude.list.minimum;+ new function() {+ it("573_587multi__::__ var xs = [:\n \n [:1,2,3]\n \n [:1,2,3:]\n \n (1::2::3::{nil})\n \n { head = 1\n tail = { head = 2\n tail = { head = 3\n tail = {nil} }}}\n ]\n \n all? (\u03bby = [:1,2,3] == y) xs", function() {+ expect(function() {+ try {+ return u(function(a) {+ return g({head:1, tail:{head:2, tail:{head:3, tail:{nil:!0}}}})(a)+ })({head:{head:1, tail:{head:2, tail:{head:3, tail:{nil:!0}}}}, tail:{head:{head:1, tail:{head:2, tail:{head:3, tail:{nil:!0}}}}, tail:{head:{head:1, tail:{head:2, tail:{head:3, tail:{nil:!0}}}}, tail:{head:{head:1, tail:{head:2, tail:{head:3, tail:{nil:!0}}}}, tail:{nil:!0}}}}})+ }catch(a) {+ return{error:a}+ }+ }()).toEqual(!0)+ });+ it("614_614__::__ 1 .. 5 == [:1,2,3,4,5]", function() {+ expect(l(1)(5)).toEqual({head:1, tail:{head:2, tail:{head:3, tail:{head:4, tail:{head:5, tail:{nil:!0}}}}}})+ });+ it("618_618__::__ 288045 == 1 .. 1111 |> filter (\u03bbx = x % 3 == 0 || x % 5 == 0) |> sum", function() {+ expect(288045).toEqual(function(a) {+ return function(b) {+ return b(a)+ }+ }(function(a) {+ return function(b) {+ return b(a)+ }+ }(l(1)(1111))(w(function(a) {+ var b = g, c;+ c = run(function() {+ return run(function() {+ return a % 3+ })+ });+ var f = b(c)(0), b = g;+ c = run(function() {+ return run(function() {+ return a % 5+ })+ });+ var j = b(c)(0);+ return run(function() {+ return run(function() {+ return f || j+ })+ })+ })))(z))+ });+ it("629_629__::__ not (empty? (1 :: {nil}))", function() {+ expect(function() {+ try {+ var c;+ var f = a({head:1, tail:{nil:!0}});+ c = run(function() {+ return run(function() {+ return!f+ })+ });+ return c+ }catch(j) {+ return{error:j}+ }+ }()).toEqual(!0)+ });+ it("630_630__::__ empty? [:]", function() {+ expect(function() {+ try {+ return a({nil:!0})+ }catch(c) {+ return{error:c}+ }+ }()).toEqual(!0)+ });+ it("632_632__::__ head [: 1, 2 ] is 1", function() {+ expect(f({head:1, tail:{head:2, tail:{nil:!0}}})).toEqual(1)+ });+ it("633_633__::__ tail [: 1, 2 ] is [:2]", function() {+ expect(e({head:1, tail:{head:2, tail:{nil:!0}}})).toEqual({head:2, tail:{nil:!0}})+ });+ it("634_634__::__ last [: 1, 2 ] is 2", function() {+ expect(k({head:1, tail:{head:2, tail:{nil:!0}}})).toEqual(2)+ });+ it('636_636__::__ err (lazy head {nil}) is "Head called on empty list"', function() {+ expect(d(function() {+ var a;+ a = void 0;+ return function() {+ a || (a = f({nil:!0}));+ return a+ }+ }())).toEqual("Head called on empty list")+ });+ it('637_637__::__ err (lazy tail {nil}) is "Tail called on empty list"', function() {+ expect(d(function() {+ var a;+ a = void 0;+ return function() {+ a || (a = e({nil:!0}));+ return a+ }+ }())).toEqual("Tail called on empty list")+ });+ it('638_638__::__ err (lazy last {nil}) is "Last called on empty list"', function() {+ expect(d(function() {+ var a;+ a = void 0;+ return function() {+ a || (a = k({nil:!0}));+ return a+ }+ }())).toEqual("Last called on empty list")+ });+ it("640_640__::__ take(2, [: 1, 2, 3 ]) == [: 1, 2 ]", function() {+ expect(h(2)({head:1, tail:{head:2, tail:{head:3, tail:{nil:!0}}}})).toEqual({head:1, tail:{head:2, tail:{nil:!0}}})+ });+ it("641_641__::__ drop(2, [: 1, 2, 3 ]) == [: 3 ]", function() {+ expect(i(2)({head:1, tail:{head:2, tail:{head:3, tail:{nil:!0}}}})).toEqual({head:3, tail:{nil:!0}})+ });+ it("643_643__::__ take_while (\u03bbx = x < 0) [:] == [:]", function() {+ expect(j(function(a) {+ return run(function() {+ return run(function() {+ return 0 > a+ })+ })+ })({nil:!0})).toEqual({nil:!0})+ });+ it("644_644__::__ take_while (\u03bbx = x > 0) [: 2, 1, 0 ] == [: 2, 1 ]", function() {+ expect(j(function(a) {+ return run(function() {+ return run(function() {+ return 0 < a+ })+ })+ })({head:2, tail:{head:1, tail:{head:0, tail:{nil:!0}}}})).toEqual({head:2, tail:{head:1, tail:{nil:!0}}})+ });+ it("646_646__::__ drop_while (\u03bbx = x < 0) {nil} == {nil}", function() {+ expect(m(function(a) {+ return run(function() {+ return run(function() {+ return 0 > a+ })+ })+ })({nil:!0})).toEqual({nil:!0})+ });+ it("647_647__::__ drop_while (\u03bbx = x > 0) [: 2, 1, 0 ] == [: 0 ]", function() {+ expect(m(function(a) {+ return run(function() {+ return run(function() {+ return 0 < a+ })+ })+ })({head:2, tail:{head:1, tail:{head:0, tail:{nil:!0}}}})).toEqual({head:0, tail:{nil:!0}})+ });+ it("656_656__::__ length [: 1, 2, 3, 4 ] == 4", function() {+ expect(r({head:1, tail:{head:2, tail:{head:3, tail:{head:4, tail:{nil:!0}}}}})).toEqual(4)+ });+ it("663_663__::__ length (init 30 0) == 30", function() {+ expect(r(p(30)(0))).toEqual(30)+ });+ it("664_664__::__ tail (init 3 0) == init 2 0", function() {+ expect(e(p(3)(0))).toEqual(p(2)(0))+ });+ it("673_673__::__ {nil} ++ (1 :: 2 :: {nil}) == 1 :: 2 :: {nil}", function() {+ expect(s({nil:!0})(function(a) {+ return function(b) {+ return{head:a, tail:b}+ }+ }(1)(function(a) {+ return function(b) {+ return{head:a, tail:b}+ }+ }(2)({nil:!0})))).toEqual(function(a) {+ return function(b) {+ return{head:a, tail:b}+ }+ }(1)(function(a) {+ return function(b) {+ return{head:a, tail:b}+ }+ }(2)({nil:!0})))+ });+ it("674_674__::__ [: 1, 2 ] ++ [: 3, 4 ] == [: 1, 2, 3, 4 ]", function() {+ expect(s({head:1, tail:{head:2, tail:{nil:!0}}})({head:3, tail:{head:4, tail:{nil:!0}}})).toEqual({head:1, tail:{head:2, tail:{head:3, tail:{head:4, tail:{nil:!0}}}}})+ });+ it("683_683__::__ [: 1, 2, 3, 4 ] 'filter (\u03bbx = x > 2) == [: 3, 4 ]", function() {+ expect(function(a) {+ return function(b) {+ return b(a)+ }+ }({head:1, tail:{head:2, tail:{head:3, tail:{head:4, tail:{nil:!0}}}}})(w(function(a) {+ return run(function() {+ return run(function() {+ return 2 < a+ })+ })+ }))).toEqual({head:3, tail:{head:4, tail:{nil:!0}}})+ });+ it("690_690__::__ [: 2, 3, 4 ] == [: 1, 2, 3 ] |> map \u03bbx = x + 1", function() {+ expect({head:2, tail:{head:3, tail:{head:4, tail:{nil:!0}}}}).toEqual(function(a) {+ return function(b) {+ return b(a)+ }+ }({head:1, tail:{head:2, tail:{head:3, tail:{nil:!0}}}})(x(function(a) {+ return run(function() {+ return run(function() {+ return a + 1+ })+ })+ })))+ });+ it("701_701__::__ reverse [: 1, 2, 3, 4 ] == [: 4, 3, 2, 1 ]", function() {+ expect(t({head:1, tail:{head:2, tail:{head:3, tail:{head:4, tail:{nil:!0}}}}})).toEqual({head:4, tail:{head:3, tail:{head:2, tail:{head:1, tail:{nil:!0}}}}})+ });+ it("703_704multi__::__ var test_x = [: 1, 2, 3, 4 ]\n test_x == reverse <| reverse test_x", function() {+ expect(function() {+ try {+ var a;+ a = {head:1, tail:{head:2, tail:{head:3, tail:{head:4, tail:{nil:!0}}}}};+ var b = g(a), c = t, f, j = t(a);+ f = c(j);+ return b(f)+ }catch(d) {+ return{error:d}+ }+ }()).toEqual(!0)+ });+ it("712_713multi__::__ var x = [: 1, 2, 3, 4, 5, 6, 7, 8 ]\n take 5 x == take' 5 x", function() {+ expect(function() {+ try {+ var a;+ a = {head:1, tail:{head:2, tail:{head:3, tail:{head:4, tail:{head:5, tail:{head:6, tail:{head:7, tail:{head:8, tail:{nil:!0}}}}}}}}};+ return g(h(5)(a))(B(5)(a))+ }catch(b) {+ return{error:b}+ }+ }()).toEqual(!0)+ });+ it("747_747__::__ foldl (\u03bbx y = x + y) 0 [: 1, 2, 3, 4 ] == 10", function() {+ expect(y(function(a) {+ return function(b) {+ return run(function() {+ return run(function() {+ return a + b+ })+ })+ }+ })(0)({head:1, tail:{head:2, tail:{head:3, tail:{head:4, tail:{nil:!0}}}}})).toEqual(10)+ });+ it("748_748__::__ foldr (\u03bbx y = x + y) 0 [: 1, 2, 3, 4 ] == 10", function() {+ expect(C(function(a) {+ return function(b) {+ return run(function() {+ return run(function() {+ return a + b+ })+ })+ }+ })(0)({head:1, tail:{head:2, tail:{head:3, tail:{head:4, tail:{nil:!0}}}}})).toEqual(10)+ });+ it("749_749__::__ all? id [:true,true]", function() {+ expect(function() {+ try {+ return u(c)({head:!0, tail:{head:!0, tail:{nil:!0}}})+ }catch(a) {+ return{error:a}+ }+ }()).toEqual(!0)+ });+ it("750_750__::__ not (all? id [:true,false])", function() {+ expect(function() {+ try {+ var a;+ var b = u(c)({head:!0, tail:{head:!1, tail:{nil:!0}}});+ a = run(function() {+ return run(function() {+ return!b+ })+ });+ return a+ }catch(f) {+ return{error:f}+ }+ }()).toEqual(!0)+ });+ it("751_751__::__ any? id [:true,false]", function() {+ expect(function() {+ try {+ return v(c)({head:!0, tail:{head:!1, tail:{nil:!0}}})+ }catch(a) {+ return{error:a}+ }+ }()).toEqual(!0)+ });+ it("752_752__::__ not (any? id [:false,false])", function() {+ expect(function() {+ try {+ var a;+ var b = v(c)({head:!1, tail:{head:!1, tail:{nil:!0}}});+ a = run(function() {+ return run(function() {+ return!b+ })+ });+ return a+ }catch(f) {+ return{error:f}+ }+ }()).toEqual(!0)+ });+ it("753_753__::__ sum [:1,2,3] == 6", function() {+ expect(z({head:1, tail:{head:2, tail:{head:3, tail:{nil:!0}}}})).toEqual(6)+ });+ it("754_754__::__ product [:1,2,4] == 8", function() {+ expect(D({head:1, tail:{head:2, tail:{head:4, tail:{nil:!0}}}})).toEqual(8)+ });+ it("756_757multi__::__ let x = [:1,2], y = [:3,4]\n concat [:x,y] == [:1,2,3,4]", function() {+ expect(function() {+ try {+ return g(A({head:{head:1, tail:{head:2, tail:{nil:!0}}}, tail:{head:{head:3, tail:{head:4, tail:{nil:!0}}}, tail:{nil:!0}}}))({head:1, tail:{head:2, tail:{head:3, tail:{head:4, tail:{nil:!0}}}}})+ }catch(a) {+ return{error:a}+ }+ }()).toEqual(!0)+ });+ it("759_759__::__ concat_map (\u03bbx = [:x,x+1]) [:1,2] == [:1,2,2,3]", function() {+ expect(H(function(a) {+ var b;+ b = run(function() {+ return run(function() {+ return a + 1+ })+ });+ return{head:a, tail:{head:b, tail:{nil:!0}}}+ })({head:1, tail:{head:2, tail:{nil:!0}}})).toEqual({head:1, tail:{head:2, tail:{head:2, tail:{head:3, tail:{nil:!0}}}}})+ });+ it("761_761__::__ minimum [: 1, 2, 3 ] == 1", function() {+ expect(G({head:1, tail:{head:2, tail:{head:3, tail:{nil:!0}}}})).toEqual(1)+ });+ it("762_762__::__ maximum [: 1, 2, 3 ] == 3", function() {+ expect(F({head:1, tail:{head:2, tail:{head:3, tail:{nil:!0}}}})).toEqual(3)+ })+ }+ });+ describe("seq", function() {+ var b;+ b = prelude.seq.iterate;+ var c;+ c = prelude.seq.from_list;+ var d;+ d = prelude.seq.to_list;+ var e;+ e = prelude.seq.take;+ var h;+ h = prelude.seq.fibs;+ var g;+ g = f.last || window.last;+ e = f.take || window.take;+ var l;+ l = f.length || window.length;+ var j;+ j = a.time || window.time;+ var m;+ m = a.fast_fib || window.fast_fib;+ var i;+ i = a.floor || window.floor;+ b = prelude.seq.iterate;+ c = prelude.seq.from_list;+ d = prelude.seq.to_list;+ e = prelude.seq.take;+ h = prelude.seq.fibs;+ new function() {+ it("798_798__::__ to_list (from_list [:1,2]) == [:1,2]", function() {+ expect(d(c({head:1, tail:{head:2, tail:{nil:!0}}}))).toEqual({head:1, tail:{head:2, tail:{nil:!0}}})+ });+ it("799_799__::__ iterate (\u03bbx = x + 1) 0 |> take 100 |> to_list |> length == 100", function() {+ expect(function(a) {+ return function(b) {+ return b(a)+ }+ }(function(a) {+ return function(b) {+ return b(a)+ }+ }(function(a) {+ return function(b) {+ return b(a)+ }+ }(b(function(a) {+ return run(function() {+ return run(function() {+ return a + 1+ })+ })+ })(0))(e(100)))(d))(l)).toEqual(100)+ });+ it('835_839multi__::__ do! fast_time <- time yield fast_fib 30\n slow_time <- time yield fibs |> take 30 |> to_list |> last\n let ratio = floor (fast_time / slow_time * 100)\n "#speedtest" $= ratio\n return (ratio >= 2)', function() {+ expect(function() {+ try {+ return run(function() {+ var a = run, b = j(function() {+ return m(30)+ }), c = run(b), b = j(function() {+ var a = h, a = e(30)(a), a = d(a);+ return g(a)+ }), f, p, l = run(b);+ p = run(function() {+ return run(function() {+ return c / l+ })+ });+ b = run(function() {+ return run(function() {+ return 100 * p+ })+ });+ f = i(b);+ run(function() {+ if("undefined" != typeof $) {+ var a;+ a = $("#speedtest").get(0);+ "undefined" != typeof a && (a.innerHTML = f)+ }+ });+ var n;+ n = run(function() {+ return run(function() {+ return 2 <= f+ })+ });+ return a(function() {+ return n+ })+ })+ }catch(a) {+ return{error:a}+ }+ }()).toEqual(!0)+ });+ it("841_841__::__ fibs |> take 5 |> to_list == [:1,1,2,3,5]", function() {+ expect(function(a) {+ return function(b) {+ return b(a)+ }+ }(function(a) {+ return function(b) {+ return b(a)+ }+ }(h)(e(5)))(d)).toEqual({head:1, tail:{head:1, tail:{head:2, tail:{head:3, tail:{head:5, tail:{nil:!0}}}}}})+ });+ it("843_845multi__::__ fast_fib 15 == fibs |> take 15\n |> to_list\n |> last", function() {+ expect(m(15)).toEqual(function(a) {+ return function(b) {+ return b(a)+ }+ }(function(a) {+ return function(b) {+ return b(a)+ }+ }(function(a) {+ return function(b) {+ return b(a)+ }+ }(h)(e(15)))(d))(g))+ })+ }+ });+ describe("Formal Z", function() {+ var a;+ a = f._comp_comp || window._comp_comp;+ var c;+ c = f.concat_map || window.concat_map;+ new function() {+ it("890_893multi__::__ let (>>>=) x g = concat_map g x\n z = 1..3 >>>= \u03bbx = [:x,x+1,x+2]\n \n z == [:1,2,3,2,3,4,3,4,5]", function() {+ expect(function() {+ try {+ var f, d = a(1)(3);+ f = c(function(a) {+ var b = run(function() {+ return run(function() {+ return a + 1+ })+ }), c;+ c = run(function() {+ return run(function() {+ return a + 2+ })+ });+ return{head:a, tail:{head:b, tail:{head:c, tail:{nil:!0}}}}+ })(d);+ return g(f)({head:1, tail:{head:2, tail:{head:3, tail:{head:2, tail:{head:3, tail:{head:4, tail:{head:3, tail:{head:4, tail:{head:5, tail:{nil:!0}}}}}}}}}})+ }catch(e) {+ return{error:e}+ }+ }()).toEqual(!0)+ })+ }+ })+ }+ })+});+describe("", function() {+ describe("parsec", function() {+ var i;+ i = parsec.try_apos;+ var g;+ g = parsec.many;+ var e;+ e = prelude._eq_eq || window._eq_eq;+ i = parsec.try_apos;+ g = parsec.many;+ new function() {+ describe("Testing", function() {+ new function() {+ it('141_141__::__ {some = "ten"} == run_parser (string "ten") "tens"', function() {+ expect({some:"ten"}).toEqual(function(a) {+ return function(c) {+ var d;+ d = a.parser;+ if(__check(a, "parser")) {+ return c = d(c), d = c.parsed.some, __check(c, "parsed") && __check(c.parsed, "some") ? {some:d} : {none:!0}+ }+ exhaust()+ }+ }(function(a) {+ return{parser:function(c) {+ var d;+ d = run(function() {+ return run(function() {+ return c.substring(0, a.length)+ })+ });+ return e(d)(a) ? {parsed:{some:a}, rest:run(function() {+ return run(function() {+ return c.substring(a.length)+ })+ })} : {parsed:{none:!0}, rest:c}+ }}+ }("ten"))("tens"))+ });+ it('142_142__::__ {some = "tenten"} == run_parser ((\u03bbx = x +++ x) <$> string "ten") "tenfingers"', function() {+ expect({some:"tenten"}).toEqual(function(a) {+ return function(c) {+ var d;+ d = a.parser;+ if(__check(a, "parser")) {+ return c = d(c), d = c.parsed.some, __check(c, "parsed") && __check(c.parsed, "some") ? {some:d} : {none:!0}+ }+ exhaust()+ }+ }(function(a) {+ return function(c) {+ var d;+ d = c.parser;+ if(__check(c, "parser")) {+ return{parser:function(c) {+ var c = d(c), b;+ b = c.parsed.some;+ var e;+ e = c.rest;+ __check(c, "parsed") && __check(c, "rest") && __check(c.parsed, "some") ? c = {parsed:{some:a(b)}, rest:e} : (b = c.rest, __check(c, "parsed") && __check(c, "rest") && __check(c.parsed, "none") ? c = {parsed:{none:!0}, rest:b} : (exhaust(), c = void 0));+ return c+ }}+ }+ exhaust()+ }+ }(function(a) {+ return run(function() {+ return run(function() {+ return"" + a + a+ })+ })+ })(function(a) {+ return{parser:function(c) {+ var d;+ d = run(function() {+ return run(function() {+ return c.substring(0, a.length)+ })+ });+ return e(d)(a) ? {parsed:{some:a}, rest:run(function() {+ return run(function() {+ return c.substring(a.length)+ })+ })} : {parsed:{none:!0}, rest:c}+ }}+ }("ten")))("tenfingers"))+ });+ it('144_145multi__::__ {parsed = {some = "tenten"}, rest = "fingers"} \n == ((\u03bbx = x +++ x) <$> string "ten").parser "tenfingers"', function() {+ expect({parsed:{some:"tenten"}, rest:"fingers"}).toEqual(function(a) {+ return function(c) {+ var d;+ d = c.parser;+ if(__check(c, "parser")) {+ return{parser:function(c) {+ var c = d(c), b;+ b = c.parsed.some;+ var e;+ e = c.rest;+ __check(c, "parsed") && __check(c, "rest") && __check(c.parsed, "some") ? c = {parsed:{some:a(b)}, rest:e} : (b = c.rest, __check(c, "parsed") && __check(c, "rest") && __check(c.parsed, "none") ? c = {parsed:{none:!0}, rest:b} : (exhaust(), c = void 0));+ return c+ }}+ }+ exhaust()+ }+ }(function(a) {+ return run(function() {+ return run(function() {+ return"" + a + a+ })+ })+ })(function(a) {+ return{parser:function(c) {+ var d;+ d = run(function() {+ return run(function() {+ return c.substring(0, a.length)+ })+ });+ return e(d)(a) ? {parsed:{some:a}, rest:run(function() {+ return run(function() {+ return c.substring(a.length)+ })+ })} : {parsed:{none:!0}, rest:c}+ }}+ }("ten")).parser("tenfingers"))+ });+ it('147_148multi__::__ var result = run_parser ((\u03bbx y = y +++ x) <$> string "ten" <*> string "fingers") "tenfingers"\n result == {some: "fingersten"}', function() {+ expect(function() {+ try {+ var a, c;+ var d = {parser:function(a) {+ var b;+ b = run(function() {+ return run(function() {+ return a.substring(0, 3)+ })+ });+ return e(b)("ten") ? {parsed:{some:"ten"}, rest:run(function() {+ return run(function() {+ return a.substring(3)+ })+ })} : {parsed:{none:!0}, rest:a}+ }}, f;+ f = d.parser;+ __check(d, "parser") ? c = {parser:function(a) {+ var a = f(a), b;+ b = a.parsed.some;+ var c;+ c = a.rest;+ if(__check(a, "parsed") && __check(a, "rest") && __check(a.parsed, "some")) {+ var d = b, a = {parsed:{some:function(a) {+ return run(function() {+ return run(function() {+ return"" + a + d+ })+ })+ }}, rest:c}+ }else {+ b = a.rest, __check(a, "parsed") && __check(a, "rest") && __check(a.parsed, "none") ? a = {parsed:{none:!0}, rest:b} : (exhaust(), a = void 0)+ }+ return a+ }} : (exhaust(), c = void 0);+ var b;+ var d = {parser:function(a) {+ var b;+ b = run(function() {+ return run(function() {+ return a.substring(0, 7)+ })+ });+ return e(b)("fingers") ? {parsed:{some:"fingers"}, rest:run(function() {+ return run(function() {+ return a.substring(7)+ })+ })} : {parsed:{none:!0}, rest:a}+ }}, g;+ g = c.parser;+ var i;+ i = d.parser;+ __check(c, "parser") && __check(d, "parser") ? b = {parser:function(a) {+ var b = g(a), a = b.parsed.some, c;+ c = b.rest;+ if(__check(b, "parsed") && __check(b, "rest") && __check(b.parsed, "some")) {+ b = i(c);+ c = b.parsed.some;+ var d;+ d = b.rest;+ __check(b, "parsed") && __check(b, "rest") && __check(b.parsed, "some") ? a = {parsed:{some:a(c)}, rest:d} : (c = b.rest, __check(b, "parsed") && __check(b, "rest") && __check(b.parsed, "none") ? a = {parsed:{none:!0}, rest:c} : (exhaust(), a = void 0))+ }else {+ a = b.rest, __check(b, "parsed") && __check(b, "rest") && __check(b.parsed, "none") ? a = {parsed:{none:!0}, rest:a} : (exhaust(), a = void 0)+ }+ return a+ }} : (exhaust(), b = void 0);+ var k;+ k = b.parser;+ if(__check(b, "parser")) {+ var h = k("tenfingers"), q;+ q = h.parsed.some;+ a = __check(h, "parsed") && __check(h.parsed, "some") ? {some:q} : {none:!0}+ }else {+ exhaust(), a = void 0+ }+ return e(a)({some:"fingersten"})+ }catch(l) {+ return{error:l}+ }+ }()).toEqual(!0)+ });+ it('150_151multi__::__ var result = run_parser (string "ten" <|> string "eleven") "eleven"\n result == {some: "eleven"}', function() {+ expect(function() {+ try {+ var a, c = {parser:function(a) {+ var b;+ b = run(function() {+ return run(function() {+ return a.substring(0, 3)+ })+ });+ return e(b)("ten") ? {parsed:{some:"ten"}, rest:run(function() {+ return run(function() {+ return a.substring(3)+ })+ })} : {parsed:{none:!0}, rest:a}+ }}, d;+ var f = {parser:function(a) {+ var b;+ b = run(function() {+ return run(function() {+ return a.substring(0, 6)+ })+ });+ return e(b)("eleven") ? {parsed:{some:"eleven"}, rest:run(function() {+ return run(function() {+ return a.substring(6)+ })+ })} : {parsed:{none:!0}, rest:a}+ }}, b;+ b = c.parser;+ var g;+ g = f.parser;+ if(__check(c, "parser") && __check(f, "parser")) {+ var i;+ i = function(a) {+ return function(b) {+ var c;+ c = b.rest;+ return __check(b, "parsed") && __check(b, "rest") && __check(b.parsed, "none") && e(a)(c) ? g(a) : b+ }+ };+ d = {parser:function(a) {+ return i(a)(b(a))+ }}+ }else {+ exhaust(), d = void 0+ }+ var k;+ k = d.parser;+ if(__check(d, "parser")) {+ var h = k("eleven"), q;+ q = h.parsed.some;+ a = __check(h, "parsed") && __check(h.parsed, "some") ? {some:q} : {none:!0}+ }else {+ exhaust(), a = void 0+ }+ return e(a)({some:"eleven"})+ }catch(l) {+ return{error:l}+ }+ }()).toEqual(!0)+ });+ it('153_154multi__::__ var result = run_parser (string "ten" *> string "fingers") "tenfingers"\n result == {some: "fingers"}', function() {+ expect(function() {+ try {+ var a, c = {parser:function(a) {+ var b;+ b = run(function() {+ return run(function() {+ return a.substring(0, 3)+ })+ });+ return e(b)("ten") ? {parsed:{some:"ten"}, rest:run(function() {+ return run(function() {+ return a.substring(3)+ })+ })} : {parsed:{none:!0}, rest:a}+ }}, d;+ var f = {parser:function(a) {+ var b;+ b = run(function() {+ return run(function() {+ return a.substring(0, 7)+ })+ });+ return e(b)("fingers") ? {parsed:{some:"fingers"}, rest:run(function() {+ return run(function() {+ return a.substring(7)+ })+ })} : {parsed:{none:!0}, rest:a}+ }}, b;+ b = c.parser;+ var g;+ g = f.parser;+ __check(c, "parser") && __check(f, "parser") ? d = {parser:function(a) {+ var a = b(a), c;+ c = a.rest;+ __check(a, "parsed") && __check(a, "rest") && __check(a.parsed, "some") ? a = g(c) : (c = a.rest, __check(a, "parsed") && __check(a, "rest") && __check(a.parsed, "none") ? a = {parsed:{none:!0}, rest:c} : (exhaust(), a = void 0));+ return a+ }} : (exhaust(), d = void 0);+ var i;+ i = d.parser;+ if(__check(d, "parser")) {+ var k = i("tenfingers"), h;+ h = k.parsed.some;+ a = __check(k, "parsed") && __check(k.parsed, "some") ? {some:h} : {none:!0}+ }else {+ exhaust(), a = void 0+ }+ return e(a)({some:"fingers"})+ }catch(q) {+ return{error:q}+ }+ }()).toEqual(!0)+ });+ it('156_158multi__::__ var parser = (string "ten" *> string "fingers") <|> string "tentoes"\n result = run_parser parser "tentoes"\n result == {none}', function() {+ expect(function() {+ try {+ var a, c = {parser:function(a) {+ var b;+ b = run(function() {+ return run(function() {+ return a.substring(0, 3)+ })+ });+ return e(b)("ten") ? {parsed:{some:"ten"}, rest:run(function() {+ return run(function() {+ return a.substring(3)+ })+ })} : {parsed:{none:!0}, rest:a}+ }}, d;+ var f = {parser:function(a) {+ var b;+ b = run(function() {+ return run(function() {+ return a.substring(0, 7)+ })+ });+ return e(b)("fingers") ? {parsed:{some:"fingers"}, rest:run(function() {+ return run(function() {+ return a.substring(7)+ })+ })} : {parsed:{none:!0}, rest:a}+ }}, b;+ b = c.parser;+ var g;+ g = f.parser;+ __check(c, "parser") && __check(f, "parser") ? d = {parser:function(a) {+ var a = b(a), c;+ c = a.rest;+ __check(a, "parsed") && __check(a, "rest") && __check(a.parsed, "some") ? a = g(c) : (c = a.rest, __check(a, "parsed") && __check(a, "rest") && __check(a.parsed, "none") ? a = {parsed:{none:!0}, rest:c} : (exhaust(), a = void 0));+ return a+ }} : (exhaust(), d = void 0);+ var i;+ var c = {parser:function(a) {+ var b;+ b = run(function() {+ return run(function() {+ return a.substring(0, 7)+ })+ });+ return e(b)("tentoes") ? {parsed:{some:"tentoes"}, rest:run(function() {+ return run(function() {+ return a.substring(7)+ })+ })} : {parsed:{none:!0}, rest:a}+ }}, k;+ k = d.parser;+ var h;+ h = c.parser;+ if(__check(d, "parser") && __check(c, "parser")) {+ var q;+ q = function(a) {+ return function(b) {+ var c;+ c = b.rest;+ return __check(b, "parsed") && __check(b, "rest") && __check(b.parsed, "none") && e(a)(c) ? h(a) : b+ }+ };+ i = {parser:function(a) {+ return q(a)(k(a))+ }}+ }else {+ exhaust(), i = void 0+ }+ var l;+ l = i.parser;+ if(__check(i, "parser")) {+ var j = l("tentoes"), m;+ m = j.parsed.some;+ a = __check(j, "parsed") && __check(j.parsed, "some") ? {some:m} : {none:!0}+ }else {+ exhaust(), a = void 0+ }+ return e(a)({none:!0})+ }catch(r) {+ return{error:r}+ }+ }()).toEqual(!0)+ });+ it('160_162multi__::__ var parser = try\' (string "ten" *> string "fingers") <|> string "tentoes"\n result = run_parser parser "tentoes"\n result == {some: "tentoes"}', function() {+ expect(function() {+ try {+ var a, c = i, d = {parser:function(a) {+ var b;+ b = run(function() {+ return run(function() {+ return a.substring(0, 3)+ })+ });+ return e(b)("ten") ? {parsed:{some:"ten"}, rest:run(function() {+ return run(function() {+ return a.substring(3)+ })+ })} : {parsed:{none:!0}, rest:a}+ }}, f;+ var b = {parser:function(a) {+ var b;+ b = run(function() {+ return run(function() {+ return a.substring(0, 7)+ })+ });+ return e(b)("fingers") ? {parsed:{some:"fingers"}, rest:run(function() {+ return run(function() {+ return a.substring(7)+ })+ })} : {parsed:{none:!0}, rest:a}+ }}, g;+ g = d.parser;+ var E;+ E = b.parser;+ __check(d, "parser") && __check(b, "parser") ? f = {parser:function(a) {+ var a = g(a), b;+ b = a.rest;+ __check(a, "parsed") && __check(a, "rest") && __check(a.parsed, "some") ? a = E(b) : (b = a.rest, __check(a, "parsed") && __check(a, "rest") && __check(a.parsed, "none") ? a = {parsed:{none:!0}, rest:b} : (exhaust(), a = void 0));+ return a+ }} : (exhaust(), f = void 0);+ var k = c(f), h;+ var c = {parser:function(a) {+ var b;+ b = run(function() {+ return run(function() {+ return a.substring(0, 7)+ })+ });+ return e(b)("tentoes") ? {parsed:{some:"tentoes"}, rest:run(function() {+ return run(function() {+ return a.substring(7)+ })+ })} : {parsed:{none:!0}, rest:a}+ }}, q;+ q = k.parser;+ var l;+ l = c.parser;+ if(__check(k, "parser") && __check(c, "parser")) {+ var j;+ j = function(a) {+ return function(b) {+ var c;+ c = b.rest;+ return __check(b, "parsed") && __check(b, "rest") && __check(b.parsed, "none") && e(a)(c) ? l(a) : b+ }+ };+ h = {parser:function(a) {+ return j(a)(q(a))+ }}+ }else {+ exhaust(), h = void 0+ }+ var m;+ m = h.parser;+ if(__check(h, "parser")) {+ var r = m("tentoes"), p;+ p = r.parsed.some;+ a = __check(r, "parsed") && __check(r.parsed, "some") ? {some:p} : {none:!0}+ }else {+ exhaust(), a = void 0+ }+ return e(a)({some:"tentoes"})+ }catch(s) {+ return{error:s}+ }+ }()).toEqual(!0)+ });+ it('164_166multi__::__ var parser = many (string "ten")\n result = run_parser parser "tententententen"\n result == {some: ["ten", "ten", "ten", "ten", "ten"]}', function() {+ expect(function() {+ try {+ var a, c = g({parser:function(a) {+ var b;+ b = run(function() {+ return run(function() {+ return a.substring(0, 3)+ })+ });+ return e(b)("ten") ? {parsed:{some:"ten"}, rest:run(function() {+ return run(function() {+ return a.substring(3)+ })+ })} : {parsed:{none:!0}, rest:a}+ }});+ var d;+ d = c.parser;+ if(__check(c, "parser")) {+ var f = d("tententententen"), b;+ b = f.parsed.some;+ a = __check(f, "parsed") && __check(f.parsed, "some") ? {some:b} : {none:!0}+ }else {+ exhaust(), a = void 0+ }+ return e(a)({some:["ten", "ten", "ten", "ten", "ten"]})+ }catch(i) {+ return{error:i}+ }+ }()).toEqual(!0)+ })+ }+ })+ }+ })+});+describe("", function() {+ describe("Benchmarks for the prelude", function() {+ var i;+ i = Benchmarks_for_the_prelude.title;+ var g;+ g = Benchmarks_for_the_prelude.euler_1;+ var e;+ e = Benchmarks_for_the_prelude.euler_2;+ var a;+ a = Benchmarks_for_the_prelude.euler_3;+ var c;+ c = Benchmarks_for_the_prelude.euler_4;+ var d;+ d = Benchmarks_for_the_prelude.euler_5;+ var f;+ f = prelude._return_ || window._return_;+ var b;+ b = prelude.time || window.time;+ var n;+ n = prelude.err || window.err;+ b = prelude.speedtest.time || window.time;+ i = Benchmarks_for_the_prelude.title;+ g = Benchmarks_for_the_prelude.euler_1;+ e = Benchmarks_for_the_prelude.euler_2;+ a = Benchmarks_for_the_prelude.euler_3;+ c = Benchmarks_for_the_prelude.euler_4;+ d = Benchmarks_for_the_prelude.euler_5;+ new function() {+ it('56_70multi__::__ do! title "Relative Speeds (10k)"\n \n w <- time (euler_1 10000)\n x <- time yield euler_2 10000 0\n y <- time yield euler_3 10000\n z <- time (euler_4 10000)\n q <- time yield euler_5 10000 0\n \n log " Native JS: `w / 1000`s"\n log " Formal TCO Unboxed: `q / 1000`s"\n log " Formal TCO: `x / 1000`s"\n log " Formal Recursive: `y / 1000`s"\n log " Formal list: `z / 1000`s"\n \n return <| (x <= y && y < z)', + function() {+ expect(function() {+ try {+ return run(function() {+ var k = run, h = i("Relative Speeds (10k)");+ run(h);+ var h = b(g(1E4)), n = run(h), h = b(function() {+ return e(1E4)(0)+ }), l = run(h), h = b(function() {+ return a(1E4)+ }), j = run(h), h = b(c(1E4)), m = run(h), h = b(function() {+ return d(1E4)(0)+ }), r = run(h), p, s = run(function() {+ return run(function() {+ return n / 1E3+ })+ });+ p = run(function() {+ return run(function() {+ return" Native JS: " + s+ })+ });+ var w;+ w = run(function() {+ return run(function() {+ return"" + p + "s"+ })+ });+ run(function() {+ return console.log(w)+ });+ var x, t = run(function() {+ return run(function() {+ return r / 1E3+ })+ });+ x = run(function() {+ return run(function() {+ return" Formal TCO Unboxed: " + t+ })+ });+ var B;+ B = run(function() {+ return run(function() {+ return"" + x + "s"+ })+ });+ run(function() {+ return console.log(B)+ });+ var y, C = run(function() {+ return run(function() {+ return l / 1E3+ })+ });+ y = run(function() {+ return run(function() {+ return" Formal TCO: " + C+ })+ });+ var u;+ u = run(function() {+ return run(function() {+ return"" + y + "s"+ })+ });+ run(function() {+ return console.log(u)+ });+ var v, z = run(function() {+ return run(function() {+ return j / 1E3+ })+ });+ v = run(function() {+ return run(function() {+ return" Formal Recursive: " + z+ })+ });+ var D;+ D = run(function() {+ return run(function() {+ return"" + v + "s"+ })+ });+ run(function() {+ return console.log(D)+ });+ var A, E = run(function() {+ return run(function() {+ return m / 1E3+ })+ });+ A = run(function() {+ return run(function() {+ return" Formal list: " + E+ })+ });+ var F;+ F = run(function() {+ return run(function() {+ return"" + A + "s"+ })+ });+ run(function() {+ return console.log(F)+ });+ var G;+ G = run(function() {+ return run(function() {+ return l <= j+ })+ });+ var I = run(function() {+ return run(function() {+ return j < m+ })+ }), h = run(function() {+ return run(function() {+ return G && I+ })+ }), h = f(h);+ return k(h)+ })+ }catch(n) {+ return{error:n}+ }+ }()).toEqual(!0)+ });+ it("72_72__::__ string? (err yield euler_3(250000)).message", function() {+ expect(function() {+ try {+ var b;+ var c = n(function() {+ return a(25E4)+ }).message;+ b = run(function() {+ return run(function() {+ return"string" === typeof c+ })+ });+ return b+ }catch(d) {+ return{error:d}+ }+ }()).toEqual(!0)+ });+ it('74_88multi__::__ do! title "Relative Speeds (2.5M)"\n \n w <- time (euler_1 2500000)\n x <- time yield euler_2 2500000 0\n y <- time yield euler_5 2500000 0\n \n log " Native JS: `w / 1000`s"\n log " Formal TCO Unboxed: `y / 1000`s"\n log " Formal TCO: `x / 1000`s"\n log " Formal Recursive: `err yield euler_3(250000)`"\n log " Formal list: `err (euler_4 250000)`"\n \n log ""\n \n return <| (w < x)', + function() {+ expect(function() {+ try {+ return run(function() {+ var k = run, h = i("Relative Speeds (2.5M)");+ run(h);+ var h = b(g(25E5)), q = run(h), h = b(function() {+ return e(25E5)(0)+ }), l = run(h), h = b(function() {+ return d(25E5)(0)+ }), j = run(h), m, r = run(function() {+ return run(function() {+ return q / 1E3+ })+ });+ m = run(function() {+ return run(function() {+ return" Native JS: " + r+ })+ });+ var p;+ p = run(function() {+ return run(function() {+ return"" + m + "s"+ })+ });+ run(function() {+ return console.log(p)+ });+ var s, w = run(function() {+ return run(function() {+ return j / 1E3+ })+ });+ s = run(function() {+ return run(function() {+ return" Formal TCO Unboxed: " + w+ })+ });+ var x;+ x = run(function() {+ return run(function() {+ return"" + s + "s"+ })+ });+ run(function() {+ return console.log(x)+ });+ var t, B = run(function() {+ return run(function() {+ return l / 1E3+ })+ });+ t = run(function() {+ return run(function() {+ return" Formal TCO: " + B+ })+ });+ var y;+ y = run(function() {+ return run(function() {+ return"" + t + "s"+ })+ });+ run(function() {+ return console.log(y)+ });+ var C, u = n(function() {+ return a(25E4)+ });+ C = run(function() {+ return run(function() {+ return" Formal Recursive: " + u+ })+ });+ var v;+ v = run(function() {+ return run(function() {+ return"" + C + ""+ })+ });+ run(function() {+ return console.log(v)+ });+ var z, D = n(c(25E4));+ z = run(function() {+ return run(function() {+ return" Formal list: " + D+ })+ });+ var A;+ A = run(function() {+ return run(function() {+ return"" + z + ""+ })+ });+ run(function() {+ return console.log(A)+ });+ run(function() {+ return console.log("")+ });+ h = run(function() {+ return run(function() {+ return q < l+ })+ });+ h = f(h);+ return k(h)+ })+ }catch(E) {+ return{error:E}+ }+ }()).toEqual(!0)+ })+ }+ });+ describe("Tests for partial records", function() {+ var i;+ i = prelude._eq_eq || window._eq_eq;+ new function() {+ it("95_96multi__::__ var f {a: x, b: y, _ } = x + y\n f { a: 5, b: 5, c: 5 } == f { a: 5, b: 5, d: 5 }", function() {+ expect(function() {+ try {+ var g;+ g = function(a) {+ var c;+ c = a.a;+ var d;+ d = a.b;+ if(__check(a, "a") && __check(a, "b")) {+ return run(function() {+ return run(function() {+ return c + d+ })+ })+ }+ exhaust()+ };+ return i(g({a:5, b:5, c:5}))(g({a:5, b:5, d:5}))+ }catch(e) {+ return{error:e}+ }+ }()).toEqual(!0)+ });+ it("98_100multi__::__ var f {a: 1, b: 1, _ } = 2\n f {b: 2, c: 2, _ } = 2\n f {a:1,b:1,c:3,d:5} + f {a:1,b:2,c:2,e:5} == 4", function() {+ expect(function() {+ try {+ var g;+ g = function(a) {+ if(__check(a, "a") && __check(a, "b") && 1 === a.a && 1 === a.b || __check(a, "b") && __check(a, "c") && 2 === a.b && 2 === a.c) {+ return 2+ }+ exhaust()+ };+ var e = g({a:1, b:1, c:3, d:5}), a, c = g({a:1, b:2, c:2, e:5});+ a = run(function() {+ return run(function() {+ return e + c+ })+ });+ return i(a)(4)+ }catch(d) {+ return{error:d}+ }+ }()).toEqual(!0)+ });+ it("102_105multi__::__ var f { a = 1, b = 2, _ } = 1\n g { b = 2, c = 3, _ } = 2\n x = { a = 1, b = 2, c = 3, d = 4 }\n f x + 1 == g x", function() {+ expect(function() {+ try {+ var g;+ g = {a:1, b:2, c:3, d:4};+ var e;+ __check(g, "a") && __check(g, "b") && 1 === g.a && 2 === g.b ? e = 1 : (exhaust(), e = void 0);+ var a = e, c;+ c = run(function() {+ return run(function() {+ return a + 1+ })+ });+ var d = i(c), f;+ __check(g, "b") && __check(g, "c") && 2 === g.b && 3 === g.c ? f = 2 : (exhaust(), f = void 0);+ return d(f)+ }catch(b) {+ return{error:b}+ }+ }()).toEqual(!0)+ })+ }+ });+ describe("Tests for TCO bugs", function() {+ var i;+ i = Tests_for_TCO_bugs.rev_1;+ var g;+ g = Tests_for_TCO_bugs.rev_2;+ var e;+ e = Tests_for_TCO_bugs.test_x;+ var a;+ a = prelude.length || window.length;+ var c;+ c = prelude.reverse || window.reverse;+ a = prelude.list.length || window.length;+ c = prelude.list.reverse || window.reverse;+ i = Tests_for_TCO_bugs.rev_1;+ g = Tests_for_TCO_bugs.rev_2;+ e = Tests_for_TCO_bugs.test_x;+ new function() {+ it("126_126__::__ rev_2 [: 1, 2, 3, 4 ] == [: 4, 3, 2, 1 ]", function() {+ expect(g({head:1, tail:{head:2, tail:{head:3, tail:{head:4, tail:{nil:!0}}}}})).toEqual({head:4, tail:{head:3, tail:{head:2, tail:{head:1, tail:{nil:!0}}}}})+ });+ it("130_130__::__ rev_2 test_x == rev_1 test_x", function() {+ expect(g(e)).toEqual(i(e))+ });+ it("131_131__::__ rev_1 test_x == reverse test_x", function() {+ expect(i(e)).toEqual(c(e))+ });+ it("132_132__::__ length (rev_2 test_x) == length (rev_1 test_x)", function() {+ expect(a(g(e))).toEqual(a(i(e)))+ });+ it("133_133__::__ length (rev_2 test_x) == length test_x", function() {+ expect(a(g(e))).toEqual(a(e))+ });+ it("134_134__::__ length (rev_1 test_x) == length (reverse test_x)", function() {+ expect(a(i(e))).toEqual(a(c(e)))+ })+ }+ });+ describe("Tests for parser bugs", function() {+ var i;+ i = prelude._eq_eq || window._eq_eq;+ new function() {+ it('143_144multi__::__ var x = do! `[ { x: 1}, {x: 2}, {x: 3} ]`\n stringify (x !! 0).x == "1"', function() {+ expect(function() {+ try {+ var g;+ g = run(function() {+ return run(function() {+ return[{x:1}, {x:2}, {x:3}]+ })+ });+ var e, a = run(function() {+ return run(function() {+ return g[0]+ })+ }).x;+ e = run(function() {+ return run(function() {+ return JSON.stringify(a)+ })+ });+ return i(e)("1")+ }catch(c) {+ return{error:c}+ }+ }()).toEqual(!0)+ })+ }+ })+});+
+ src/formal/temp.js view
+ src/formal/tests.formal view
@@ -0,0 +1,145 @@++-- Tests+-- -----+-- A collection of tests for compiler bugs, benchmarking, etc.++-- Benchmarks+-- ----------+-- A collection of simple benchmarks. You can view the results+-- by opening your browser's terminal.++module "Benchmarks for the prelude"+ + title x = + do log "\r "+ log x+ return true++ open prelude+ open prelude.speedtest+ open prelude.list+ open prelude.string++ -- Here we have 5 implementations of + -- (Project Euler problem #1)[http://projecteuler.net/problem=1].+ -- The first is simply a native JS implementation.++ euler_1 x = `var sum = 0;+ for (var i = 1; i < x; i++) {+ if (i % 3 == 0 || i % 5 == 0) sum += i;+ };+ return sum;`++ -- The second is a tail recursive. The formal compiler will + -- optimize simple functions which are tail recursive into + -- javascript `for` loops automatically, making them+ -- much faster.++ euler_2 x y when x < 3 = y+ | x y when x % 3 == 0 || x % 5 == 0 =+ euler_2 (x - 1) (y + 1)+ | x y = euler_2 (x - 1) y++ euler_3 x when x < 3 = 0+ euler_3 x = if x % 3 == 0 || x % 5 == 0+ then 1 + euler_3 (x - 1)+ else euler_3 (x - 1)++ euler_4 z = yield 1 .. z + |> filter (λx = x % 3 == 0 || x % 5 == 0)+ |> sum++ euler_5 x y when x < 3 = y+ | x y when do! `x % 3 == 0 || x % 5 == 0` =+ euler_5 (x - 1) (y + 1)+ | x y = euler_5 (x - 1) y++ do! title "Relative Speeds (10k)"++ w <- time (euler_1 10000)+ x <- time yield euler_2 10000 0+ y <- time yield euler_3 10000+ z <- time (euler_4 10000)+ q <- time yield euler_5 10000 0++ log " Native JS: `w / 1000`s"+ log " Formal TCO Unboxed: `q / 1000`s"+ log " Formal TCO: `x / 1000`s"+ log " Formal Recursive: `y / 1000`s"+ log " Formal list: `z / 1000`s"+ + return <| (x <= y && y < z)++ string? (err yield euler_3(250000)).message++ do! title "Relative Speeds (2.5M)"++ w <- time (euler_1 2500000)+ x <- time yield euler_2 2500000 0+ y <- time yield euler_5 2500000 0+ + log " Native JS: `w / 1000`s"+ log " Formal TCO Unboxed: `y / 1000`s"+ log " Formal TCO: `x / 1000`s"+ log " Formal Recursive: `err yield euler_3(250000)`"+ log " Formal list: `err (euler_4 250000)`"++ log ""+ + return <| (w < x)+++module "Tests for partial records"++ open prelude++ var f {a: x, b: y, _ } = x + y+ f { a: 5, b: 5, c: 5 } == f { a: 5, b: 5, d: 5 }++ var f {a: 1, b: 1, _ } = 2+ f {b: 2, c: 2, _ } = 2+ f {a:1,b:1,c:3,d:5} + f {a:1,b:2,c:2,e:5} == 4+ + var f { a = 1, b = 2, _ } = 1+ g { b = 2, c = 3, _ } = 2+ x = { a = 1, b = 2, c = 3, d = 4 }+ f x + 1 == g x++module "Tests for TCO bugs"+ + open prelude+ open prelude.list++ rev_1 y = + var r rest [:] = rest+ | rest { head: x, tail: xs } = + r (x :: rest) xs++ r {nil} y++ rev_2 = + var rrr rest [:] = rest+ rrr rest { head: x, tail: xs } = + rrr (x :: rest) xs++ rrr {nil}+ + rev_2 [: 1, 2, 3, 4 ] == [: 4, 3, 2, 1 ]++ test_x = [: 1, 2, 3, 4, 5, 6, 7 ]++ rev_2 test_x == rev_1 test_x+ rev_1 test_x == reverse test_x+ length (rev_2 test_x) == length (rev_1 test_x)+ length (rev_2 test_x) == length test_x+ length (rev_1 test_x) == length (reverse test_x)+++module "Tests for parser bugs"++ open prelude+ open prelude.string+ open prelude.html++ var x = do! `[ {x: 1}, {x: 2}, {x: 3} ]`+ stringify (x !! 0).x == "1"
+ src/formal/underscore.formal view
@@ -0,0 +1,29 @@++++++ ++module underscore++ open prelude+ open prelude.list++ array_prototype = do! `Array.prototype.forEach`++ each:+ -- The cornerstone, an **each** implementation.+ -- Handles objects implementing **forEach**, arrays, and raw objects.++ a -> (b -> c) -> d -> e+ each(obj, iterator, context) =++ var fe = array_prototype.forEach+ do! \ when object? fe && do! `obj.forEach === fe` =+ obj.forEach iterator+ | when number? obj.length =+ var f i = yield iterator.call context (get obj i) i obj+ for [0 .. obj.length] \i = f i+ | = iterator.call +
+ src/hs/Formal/CLI.hs view
@@ -0,0 +1,111 @@++module Formal.CLI where+++import Control.Monad.State hiding (lift)++import System.Console.ANSI+import System.Exit+import System.IO+import System.Process++import Data.String.Utils++++data TestMode = NoTest | Node | Phantom++data RunConfig = RunConfig { inputs :: [String]+ , output :: String+ , show_types :: Bool+ , optimize :: Bool+ , run_tests :: TestMode+ , write_docs :: Bool+ , watch :: Bool }+++parseArgs :: [String] -> RunConfig+parseArgs = fst . runState argsParser++ where argsParser = do args <- get+ case args of+ [] -> return $ RunConfig [] "default" False True Phantom False False+ (x':xs) -> do put xs+ case x' of+ "-w" -> do x <- argsParser+ return $ x { watch = True }+ "-docs" -> do x <- argsParser+ return $ x { write_docs = True }+ "-t" -> do x <- argsParser+ return $ x { show_types = True }+ "-no-opt" -> do x <- argsParser+ return $ x { optimize = False }+ "-no-test" -> do x <- argsParser+ return $ x { run_tests = NoTest }+ "-node-test" -> do x <- argsParser+ return $ x { run_tests = Node }+ "-o" -> do (name:ys) <- get+ put ys+ RunConfig a _ c d e f g <- argsParser+ return $ RunConfig (x':a) name c d e f g+ ('-':_) -> error "Could not parse options"+ z -> do RunConfig a _ c d e f g <- argsParser+ let b = last $ split "/" $ head $ split "." z++ return $ RunConfig (x':a) b c d e f g++++warn :: String -> a -> IO a+warn x js = colors ((putStr $ "[-] " ++ x) >> return js) $+ do putStr "\r["+ setSGR [SetColor Foreground Dull Yellow]+ putStr "-"+ setSGR []+ putStrLn$ "] " ++ x+ return js++colors :: IO a -> IO a -> IO a+colors failure success =++ do (_, Just std_out', _, p) <-+ createProcess (shell "tput colors 2> /dev/null") { std_out = CreatePipe }+ waitForProcess p+ c <- hGetContents std_out'+ case reads (strip c) of+ [(x, "")] | x > (2 :: Integer) -> success+ _ -> failure++++monitor :: String -> IO (Either [String] a) -> IO a+monitor x d = do colors (return ()) $ putStr $ "[ ] " ++ x+ hFlush stdout+ d' <- d+ case d' of+ Right y -> colors ((putStrLn $ "[*] " ++ x) >> return y) $+ do putStr "\r["+ setSGR [SetColor Foreground Dull Green]+ putStr "*"+ setSGR []+ putStrLn$ "] " ++ x+ return y+ Left y -> colors (errors y) $+ do putStr "\r["+ setSGR [SetColor Foreground Dull Red]+ putStr "X"+ setSGR []+ putStrLn$ "] " ++ x+ putStrLn ""+ if length y <= 5+ then mapM putStrLn y >> return ()+ else mapM putStrLn (take 5 y) >> putStrLn ("\n" ++ show (length y - 5) ++ " additional errors")+ exitFailure++ where errors y =+ do putStrLn ("[X] " ++ x)+ if length y <= 5+ then mapM putStrLn y >> return ()+ else mapM putStrLn (take 5 y) >> putStrLn ("\n" ++ show (length y - 5) ++ " additional errors")+ exitFailure+
+ src/hs/Formal/Closure.hs view
@@ -0,0 +1,68 @@+{-# LANGUAGE QuasiQuotes #-}+{-# LANGUAGE NamedFieldPuns #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE ViewPatterns #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE QuasiQuotes #-}+{-# LANGUAGE OverlappingInstances #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE TupleSections #-}++module Formal.Closure where++import Control.Applicative++import System.IO+import System.Environment+import System.Directory+import System.Process++import Network.HTTP+import Network.URI++import Data.List as L+import Data.URLEncoded+import Data.Maybe (fromMaybe)++++closure_local :: String -> String -> IO (Either a String)+closure_local x y =++ do env' <- L.lookup "CLOSURE" <$> getEnvironment+ case env' of+ Just env ->+ do exists' <- doesFileExist env+ if exists' + then do putStr " local]"+ hFlush stdout+ writeFile "temp.js" x+ system$ "java -jar $CLOSURE --compilation_level "+ ++ y + ++ " --formatting=pretty_print --formatting=print_input_delimiter "+ ++ " --js temp.js --warning_level QUIET > temp.compiled.js"+ js <- readFile "temp.compiled.js"+ system "rm temp.js"+ system "rm temp.compiled.js"+ return $ Right js+ else putStr " remote]" >> hFlush stdout >> closure x y+ Nothing -> putStr " remote]" >> hFlush stdout >> closure x y++++closure :: String -> String -> IO (Either a String)+closure x z = do let uri = fromMaybe undefined $ parseURI "http://closure-compiler.appspot.com/compile" ++ y = export$ importList [ ("output_format", "text")+ , ("output_info", "compiled_code")+ , ("compilation_level", z)+ , ("js_code", x) ]++ args = [ mkHeader HdrContentLength (show$ length y)+ , mkHeader HdrContentType "application/x-www-form-urlencoded" ]++ rsp <- simpleHTTP (Request uri POST args y)+ txt <- getResponseBody rsp++ return$ Right txt
+ src/hs/Formal/Javascript.hs view
@@ -0,0 +1,91 @@+{-# LANGUAGE FlexibleContexts, FlexibleInstances, FunctionalDependencies,+ MultiParamTypeClasses, NamedFieldPuns, OverlappingInstances,+ QuasiQuotes, RankNTypes, RecordWildCards, TypeSynonymInstances,+ UndecidableInstances #-}++module Formal.Javascript (render, render_spec) where++import Language.Javascript.JMacro+import Prelude hiding (curry, (++))++import Formal.Types.Statement++import qualified Data.Map as M++import Formal.Javascript.Backend+import Formal.Parser++++class Compress a where+ comp :: a -> a++instance (Compress a, Compress b) => Compress (a, b) where+ comp (a, b) = (comp a, comp b)++instance (Compress a) => Compress [a] where+ comp x = map comp x++instance (Functor m, Compress a) => Compress (m a) where+ comp x = fmap comp x++instance Compress JStat where+ comp (ReturnStat x) = ReturnStat (comp x)+ comp (IfStat a b c) = IfStat (comp a) (comp b) (comp c)+ comp (WhileStat a b) = WhileStat (comp a) (comp b)+ comp (ForInStat a b c d) = ForInStat a b (comp c) (comp d)+ comp (SwitchStat a b c) = SwitchStat (comp a) (comp b) (comp c)+ comp (TryStat a b c d) = TryStat (comp a) b (comp c) (comp d)+ comp (BlockStat xs) = BlockStat (comp xs)+ comp (ApplStat a b) = ApplStat (comp a) (comp b)+ comp (PPostStat a b c) = PPostStat a b (comp c)+ comp (AssignStat a b) = AssignStat (comp a) (comp b)+ comp (UnsatBlock a) = UnsatBlock (comp a)++ comp x = x++ -- comp (DeclStat Ident (Maybe JLocalType)+ -- comp (UnsatBlock (IdentSupply JStat)+ -- comp (AntiStat String+ -- comp (ForeignStat Ident JLocalType+ -- comp (BreakStat++instance Compress JVal where+ comp (JList xs) = JList (comp xs)+ comp (JHash m) = JHash (M.map comp m)+ comp (JFunc xs x) = JFunc xs (comp x)+ comp (UnsatVal x) = UnsatVal (comp x)++ comp x = x++ -- comp x@(JVar _) = x+ -- comp x@(JDouble _) = x+ -- comp x@(JInt _) = x+ -- comp x@(JStr _) = x+ -- comp x@(JRegEx _) = x++instance Compress JExpr where+ comp (SelExpr e (StrI i)) = IdxExpr (comp e) (ValExpr (JStr i)) -- Closure fix - advanced mode nukes these+ comp (IdxExpr a b) = IdxExpr (comp a) (comp b)+ comp (InfixExpr a b c) = InfixExpr a (comp b) (comp c)+ comp (PPostExpr a b c) = PPostExpr a b (comp c)+ comp (IfExpr a b c) = IfExpr (comp a) (comp b) (comp c)+ comp (NewExpr a) = NewExpr (comp a)++ -- comp (ApplExpr (ValExpr (UnsatVal (JFunc [z] y))) [x])++ comp (ApplExpr a b) = ApplExpr (comp a) (map comp b)+ comp (TypeExpr a b c) = TypeExpr a (comp b) c+ comp (ValExpr a) = ValExpr (comp a)+ comp (UnsatExpr a) = UnsatExpr (comp a)+ comp _ = error "Compression"++render :: Program -> String -> Program -> String+render (Program ys) src (Program xs) = show . renderJs $ (comp . runJS src . toJS . map (empty_meta Library ys) $ xs)++render_spec :: Program -> String -> Program -> String+render_spec (Program ys) src (Program xs) = show . renderJs . wrap . runJS src . toJS . map (empty_meta Test ys) $ xs+ where wrap x = [jmacro| describe("", function() { `(x)`; }); |]+++
+ src/hs/Formal/Javascript/Backend.hs view
@@ -0,0 +1,61 @@+{-# LANGUAGE QuasiQuotes #-}+{-# LANGUAGE NamedFieldPuns #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE ViewPatterns #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE QuasiQuotes #-}+{-# LANGUAGE OverlappingInstances #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE FunctionalDependencies #-}+{-# LANGUAGE TypeSynonymInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE UndecidableInstances, KindSignatures #-}++module Formal.Javascript.Backend where+ + import Formal.Types.Namespace+ import Formal.TypeCheck.Types+ import Formal.Parser.Utils + + import Data.Monoid + import Data.String.Utils+ import Text.Parsec (sourceLine)+ + type TypeSystem = [(Namespace, [Assumption])]+ + data JSState = JSState { src :: String+ , assumptions :: TypeSystem }+ + newtype JS a = JS (JSState -> (JSState, a))+ + instance Monad JS where+ fail x = JS (\_ -> error$ x) + return x = JS (\y -> (y, x))+ JS f >>= g = JS (\x -> case f x of+ (y, x') -> let JS gx = g x'+ in gx y)+ + instance Functor JS where+ fmap f y = y >>= (\x -> JS (\x' -> (x', f x)))+ + class Javascript e t | e -> t where toJS :: e -> JS t+ + runJS :: String -> JS t -> t+ runJS src (JS f) = snd . f $ JSState src []+ + instance (Javascript a b, Monoid b) => Javascript [a] b where+ + toJS [] = return mempty+ toJS (x:xs) = do x' <- toJS x+ xs' <- toJS xs+ return $ mappend x' xs'+ + get_error :: Addr a -> String -> String+ get_error (Addr (sourceLine -> x) (sourceLine -> y) _) =+ + rstrip . unlines . lines . rstrip . unlines . take ((y - x) + 1) . drop (x - 1) . lines+
+ src/hs/Formal/Javascript/Utils.hs view
@@ -0,0 +1,99 @@+{-# LANGUAGE TypeSynonymInstances #-}+{-# LANGUAGE QuasiQuotes #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE FunctionalDependencies #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE OverlappingInstances #-}++{-# LANGUAGE ViewPatterns #-}+{-# LANGUAGE NamedFieldPuns #-}+{-# LANGUAGE RecordWildCards #-}++module Formal.Javascript.Utils where+++import Text.InterpolatedString.Perl6+import Language.Javascript.JMacro+import Data.Monoid+import Data.String.Utils++import Prelude hiding (curry, (++), error)+++prelude :: String+prelude = show $ renderJs + [jmacro| function !is_array(x) { + return `(InfixExpr "instanceof" x (ref "Array"))`;+ }++ var !__undefined__ = "undefined";++ function !run(x) { return x(); }++ function !error(x) { throw x; }++ function !exhaust() { error("Pattern Match Exhausted"); }++ function !__check(x, y) {+ return x.hasOwnProperty(y);+ } |]++instance (ToStat a) => ToStat [a] where+ toStat [] = mempty+ toStat x = foldl1 mappend . map toStat $ x++--------------------------------------------------------------------------------+----+---- Metadata+++--------------------------------------------------------------------------------+----+---- Utilities++(++) :: Monoid a => a -> a -> a+(++) = mappend++end :: forall a. [a] -> [a]+end (reverse -> x : xs) = x : reverse xs+end _ = fail "End is not defined for empty lists"++ref :: String -> JExpr+ref name = ValExpr (JVar (StrI name))++func :: String -> JStat -> JStat+func var ex = ReturnStat (ValExpr (JFunc [StrI var] (BlockStat [ex])))++declare_this :: forall a. ToJExpr a => [Char] -> a -> JStat+declare_this name expr =++ [jmacro| `(declare (replace " " "_" name) expr)`;+ this[`(replace " " "_" name)`] = `(ref (replace " " "_" name))`; |]++declare_window :: forall a. ToJExpr a => [Char] -> a -> JStat+declare_window name expr =++ [jmacro| `(declare (replace " " "_" name) expr)`;+ (typeof global == "undefined" ? window : global)[`((replace " " "_" name))`] = `(ref (replace " " "_" name))`; |]+declare :: forall a. ToJExpr a => [Char] -> a -> JStat++declare name expr = + [jmacro| `(DeclStat (StrI (replace " " "_" name)) Nothing)`;+ `(ref (replace " " "_" name))` = `(expr)`; |]+ +declare_scope :: String -> JExpr -> JStat -> JStat+declare_scope name expr stat =++ BlockStat [ReturnStat (ApplExpr (ValExpr (JFunc [StrI name] stat)) [expr])]++curry :: Int -> (String -> String) -> JStat -> JStat+curry 0 _ jexpr = jexpr+curry n f jexpr = func (f $ local_pool $ n - 1) (curry (n - 1) f jexpr)++local_pool :: Int -> String+local_pool n = [qq|__{ "abcdefghijklmnopqrstuvqxyz" !! n }__|]++scope :: forall a. ToStat a => a -> JExpr+scope x = [jmacroE| (function() { `(x)`; })() |]
+ src/hs/Formal/Optimize.hs view
@@ -0,0 +1,330 @@++{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE FunctionalDependencies #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE NamedFieldPuns #-}+{-# LANGUAGE OverlappingInstances #-}+{-# LANGUAGE QuasiQuotes #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE TypeSynonymInstances #-}+{-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE ViewPatterns #-}++module Formal.Optimize where+import System.IO.Unsafe ()++import Language.Javascript.JMacro++import qualified Data.Map as M++import Control.Applicative+import Control.Monad+import Data.Char+import Data.Monoid++import Formal.Types.Axiom+import Formal.Types.Definition+import Formal.Types.Expression+import Formal.Types.Namespace hiding (Module)+import Formal.Types.Pattern+import Formal.Types.Statement hiding (Test, find, modules, namespace)+import Formal.Types.Symbol++import Formal.TypeCheck.Types hiding (get_namespace)++import Formal.Parser+import Formal.Parser.Utils++import qualified Formal.Javascript.Utils as J++import Prelude hiding (curry)+++++type Inlines = [((Namespace, Symbol), (Match (Expression Definition), Expression Definition))]+type Inline = [(Symbol, (Match (Expression Definition), Expression Definition))]++data OptimizeState = OptimizeState { ns :: Namespace+ , assumptions :: [(Namespace, [Assumption])]+ , inlines :: Inlines+ , tco :: [String]+ , env :: Inline }++data Optimizer a = Optimizer (OptimizeState -> (OptimizeState, a))++instance Monad Optimizer where++ fail x = Optimizer (\y -> error x)+ return x = Optimizer (\y -> (y, x))++ Optimizer f >>= g =+ Optimizer (\x -> case f x of (y, x) -> let Optimizer gx = g x in gx y)++instance Functor Optimizer where++ fmap f (Optimizer g) = Optimizer (\x -> case g x of (y, x) -> (y, f x))++instance Applicative Optimizer where++ pure = return+ x <*> y = do f <- x+ f <$> y++class Optimize a where++ optimize :: a -> Optimizer a++set_namespace :: Namespace -> Optimizer ()+set_namespace ns' = Optimizer (\x -> (x { ns = ns' }, ()))++get_namespace :: Optimizer Namespace+get_namespace = Optimizer (\x -> (x, ns x))++set_inline :: Inlines -> Optimizer ()+set_inline ns' = Optimizer (\x -> (x { inlines = ns' }, ()))++get_inline :: Optimizer Inlines+get_inline = Optimizer (\x -> (x, inlines x))++set_env :: Inline -> Optimizer ()+set_env ns' = Optimizer (\x -> (x { env = ns' }, ()))++get_env :: Optimizer Inline+get_env = Optimizer (\x -> (x, env x))++add_tco :: String -> Optimizer ()+add_tco x = Optimizer (\y -> (y { tco = x : tco y }, ()))++with_env :: forall b. Optimizer b -> Optimizer b+with_env xs =++ do e <- get_env+ xs' <- xs+ set_env e+ return xs'++get_addr :: Addr a -> a+get_addr (Addr _ _ x) = x++instance (Optimize a) => Optimize (Addr a) where++ optimize (Addr s e a) = Addr s e <$> optimize a++instance Optimize (Expression Definition) where++ optimize (ApplyExpression f' @ (SymbolExpression f) args) =++ do is <- get_env+ case f `lookup` is of+ Just (m @ (Match pss _), ex) | length pss == length args ->++ do args' <- mapM optimize args+ ex' <- optimize ex+ m' <- optimize m+ return $ ApplyExpression (FunctionExpression [EqualityAxiom m' (Addr undefined undefined ex')]) args'++ _ -> ApplyExpression <$> optimize f' <*> mapM optimize args++++ optimize (ApplyExpression f args) = ApplyExpression <$> optimize f <*> mapM optimize args+ optimize (IfExpression a b c) = IfExpression <$> optimize a <*> optimize b <*> optimize c+ optimize (LazyExpression x l) = flip LazyExpression l <$> optimize x+ optimize (FunctionExpression xs) = FunctionExpression <$> mapM optimize xs+ optimize (AccessorExpression x xs) = flip AccessorExpression xs <$> optimize x+ optimize (ListExpression ex) = ListExpression <$> mapM optimize ex++ optimize (LetExpression ds ex) =++ do ds' <- mapM optimize ds+ LetExpression ds' <$> optimize ex++ optimize (RecordExpression (M.toList -> xs)) =++ let (keys, vals) = unzip xs+ in RecordExpression . M.fromList . zip keys <$> mapM optimize vals++ optimize x = return x+++-- TODO wrong+instance Optimize (Match (Expression Definition)) where++ optimize (Match ms (Just ex)) = Match ms . Just <$> optimize ex+ optimize x = return x++instance Optimize (Axiom (Expression Definition)) where++ optimize t @ (TypeAxiom _) = return t+ optimize (EqualityAxiom m ex) =++ do m' <- optimize m+ ex' <- optimize ex+ return (EqualityAxiom m' ex')++instance Optimize Definition where++ optimize (Definition a True name [eq @ (EqualityAxiom _ _)]) =++ do (EqualityAxiom m ex) <- optimize eq+ is <- get_inline+ e <- get_env+ ns <- get_namespace+ set_inline (((ns, name), (m, get_addr ex)) : is)+ set_env ((name, (m, get_addr ex)) : e)+ return (Definition a True name [EqualityAxiom m ex])++ optimize (Definition a True c (TypeAxiom _ : x)) = optimize (Definition a True c x)+ optimize (Definition _ True name _) = fail$ "Illegal inline definition '" ++ show name ++ "'"++ optimize (Definition a b name xs) | is_recursive xs =++ do xs' <- mapM optimize xs+ add_tco $ show name+ return $ Definition a b name (axioms xs')++ where is_recursive (TypeAxiom _: xs') = is_recursive xs'+ is_recursive (EqualityAxiom _ x: xs') = is_recursive' (get_addr x) || is_recursive xs'+ is_recursive [] = False++ is_recursive' (ApplyExpression (SymbolExpression x) _) | name == x = True+ is_recursive' (LetExpression _ e) = is_recursive' e+ is_recursive' (IfExpression _ a b) = is_recursive' a || is_recursive' b+ is_recursive' _ = False++ axioms (t @ (TypeAxiom _): xs) = t : axioms xs+ axioms xs' =+ [EqualityAxiom (Match [] Nothing) (Addr undefined undefined (JSExpression (to_trampoline xs')))]++ to_trampoline xs @ (EqualityAxiom (Match ps _) _ : _) =+ J.scope . J.curry (length ps) ("_V"++) . to_trampoline' ps $ xs++ to_trampoline' ps xs =++ [jmacro| var __result = undefined;+ `(def_local (reverse . take (length ps) . map J.local_pool $ [0 .. 26]) local_var_names)`;+ while (typeof __result == "undefined") {+ (function() {+ `(to_trampoline'' xs __result)`;+ })();+ }+ return __result; |]++ where to_trampoline'' [] _ = [jmacro| exhaust(); |]+ to_trampoline'' (EqualityAxiom (Match pss cond) (Addr _ _ ex) : xss) result =++ [jmacro| `(declare_bindings var_names pss)`;+ if (`(pss)` && `(cond)`) {+ `(result)` = `(replace pss ex)`;+ } else `(to_trampoline'' xss result)`; |]++ var_names = map J.ref . reverse . take (length ps) . map J.local_pool $ [0 .. 26]++ --to_expr ps = toJExpr$ zipWith PM (reverse . take (length ps) . map ("r"++) . map J.local_pool $ [0 .. 26]) ps++ local_var_names = map J.ref . map ("_V"++) . reverse . take (length ps) . map J.local_pool $ [0 .. 26]++ declare_bindings (name : names) (VarPattern x : zs) =++ [jmacro| `(J.declare x name)`; |] `mappend` declare_bindings names zs++ declare_bindings (name : names) (RecordPattern x _: zs) =+ let (ns, z) = unzip . M.toList $ x+ in declare_bindings (map (acc name) ns) z `mappend` declare_bindings names zs++ declare_bindings (_ : names) (_ : zs) = declare_bindings names zs+ declare_bindings _ _ = mempty++ acc n ns = [jmacroE| `(n)`[`(ns)`] |]++ replace _ (ApplyExpression (SymbolExpression x) args) | name == x =++ JSExpression [jmacroE| (function() {+ `(bind_local (reverse . take (length ps) . map J.local_pool $ [0 .. 26]) args)`;+ return undefined;+ })() |]++ replace pss (LetExpression x e) = LetExpression x (replace pss e)+ replace pss (IfExpression x a b) = IfExpression x (replace pss a) (replace pss b)+ replace _ x = x++ bind_local :: ToJExpr a => [String] -> [a] -> JStat+ bind_local (x:xs) (y:ys) = [jmacro| `(J.ref x)` = `(y)`; |] `mappend` bind_local xs ys+ bind_local _ _ = mempty++ def_local :: [String] -> [JExpr] -> JStat+ def_local (x:xs) (y:ys) = [jmacro| `(J.declare x y)`; |] `mappend` def_local xs ys+ def_local _ _ = mempty+++ optimize (Definition a b c xs) = Definition a b c <$> mapM optimize xs++instance Optimize Statement where++ optimize (DefinitionStatement d) = DefinitionStatement <$> optimize d+ optimize (ExpressionStatement (Addr s e x)) = ExpressionStatement . Addr s e <$> optimize x+ optimize (ModuleStatement x xs) =++ do ns <- get_namespace+ set_namespace$ ns `mappend` x+ xs' <- with_env$ optimize xs+ set_namespace ns+ return$ ModuleStatement x xs'++ optimize ss @ (ImportStatement (Namespace x)) =++ do is <- get_inline+ e <- get_env+ n <- get_namespace+ rfind n is e++ where rfind (Namespace n) is e =++ case lookup' (Namespace x) is of+ [] ->++ if length n > 0 && head n /= head x+ then do optimize (ImportStatement (Namespace (head n : x)))+ return ss+ else return ss++ zs ->++ do set_env $ cc zs ++ e+ return ss++ cc (((_, s), ex): zs) = (s, ex) : cc zs+ cc [] = []++ lookup' x (((y, z), w):ys) | x == y = (((y, z), w) : lookup' x ys)+ | otherwise = lookup' x ys+ lookup' _ [] = []++ optimize x = return x++instance Optimize [Statement] where++ optimize [] = return []+ optimize (x:xs) =++ do x <- optimize x+ xs <- optimize xs+ return (x:xs)++instance Optimize Program where++ optimize (Program xs) = Program <$> optimize xs++run_optimizer :: [Program] -> [(Namespace, [Assumption])] -> [Program]+run_optimizer ps as = g ps as gen_state++ where g ps @ (optimize . head -> Optimizer f) as st = case f st of (st', p) -> p : g (tail ps) as st'++ gen_state = OptimizeState (Namespace []) as [] [] []+
+ src/hs/Formal/Parser.hs view
@@ -0,0 +1,114 @@+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE NamedFieldPuns #-}+{-# LANGUAGE OverlappingInstances #-}+{-# LANGUAGE QuasiQuotes #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE TemplateHaskell #-}++module Formal.Parser where++import Control.Applicative+import Data.String.Utils+import Formal.Parser.Utils hiding (spaces)+import Text.Parsec hiding (State, label, many, parse, (<|>))++import Formal.Types.Statement++-- Parsing+-- -----------------------------------------------------------------------------+-- A Sonnet program is represented by a set of statements++parseFormal :: String -> String -> Either ParseError Program+parseFormal name src = case parse ((comment <|> return "\n") `manyTill` eof) "Cleaning comments" src of+ Right x -> parse syntax name (concat x)+ Left y -> error $ show y+++compress :: String -> String+compress = run var . run nul . run fun++ where run x src' = case parse ((try x <|> ((:[]) <$> anyChar)) `manyTill` eof) "Compressing" src' of+ Right z -> concat z+ Left z -> error $ show z++ var = do string "var"+ spaces+ name <- many1 (alphaNum <|> char '_')+ string ";"+ spaces+ string name+ return $ "var " ++ name++ nul = do string "var"+ spaces+ name <- many1 (alphaNum <|> char '_')+ string ";"+ spaces+ string name+ spaces+ string "="+ spaces+ string "null"+ return $ "var " ++ name++ pairs = do string "{"+ inner <- (try pairs <|> try fun <|> try var <|> try nul <|> ((:[]) <$> anyChar)) `manyTill` string "}"+ return $ "{" ++ concat inner ++ "}"++ fun = do string "(function()"+ spaces+ string "{"+ spaces+ string "return"+ spaces++ string "(function("+ name <- many1 (alphaNum <|> char '_')+ string ")"+ spaces+ content <- pairs+ spaces+ string ");"+ spaces+ string "})()"+ return $ "(function(" ++ name ++ ")" ++ content ++ ")"++get_tests :: [Statement] -> [(SourcePos, SourcePos)]+get_tests [] = []+get_tests (ExpressionStatement (Addr x y _): xs) = (x,y) : get_tests xs+get_tests (ModuleStatement _ x: xs) = get_tests x ++ get_tests xs+get_tests (_: xs) = get_tests xs++annotate_tests :: String -> Program -> String+annotate_tests zz (Program xs) = annotate_tests' zz (get_tests xs)+ where annotate_tests' x [] = x+ annotate_tests' x' ((a, b):ys) =+ annotate_tests' marked ys+ where marked = mark (mark x' (serial a b ++ "--") row' col') ("--" ++ serial a b) row col++ mark str tk x y =+ let str' = lines str+ in unlines $ take x str'+ ++ [take y (str' !! x) ++ tk ++ drop y (str' !! x)]+ ++ drop (x + 1) str'++ row = sourceLine a - 1+ col = sourceColumn a - 1++ row' = sourceLine b - 1+ col' = sourceColumn b +1+++highlight :: [(SourcePos, SourcePos)] -> String -> String+highlight [] x = x+highlight ((a, b):xs) y = highlight xs (replace ("--" ++ serial a b) ("<span class='test' id='test_" ++ serial a b ++ "'>") (replace (serial a b ++ "--") "</span>" y))+++newtype Program = Program [Statement]++instance Show Program where+ show (Program ss) = sep_with "\n\n" ss++instance Syntax Program where+ syntax = Program <$> many (many (string "\n") >> syntax) <* eof
+ src/hs/Formal/Parser/Utils.hs view
@@ -0,0 +1,210 @@+{-# LANGUAGE QuasiQuotes #-}+{-# LANGUAGE NamedFieldPuns #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE ViewPatterns #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE QuasiQuotes #-}+{-# LANGUAGE OverlappingInstances #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses #-}+{-# OPTIONS_GHC -fno-warn-orphans #-}+{-# LANGUAGE TypeSynonymInstances #-}+++module Formal.Parser.Utils where++import Control.Applicative+import Control.Monad.Identity+import Control.Monad.State hiding (lift)++import Text.Parsec hiding ((<|>), State, many, spaces, parse, label)+import qualified Text.Parsec as P+import Text.Parsec.Indent hiding (same)++import qualified Data.Map as M+import qualified Data.List as L++import Data.String.Utils+++import Text.Parsec.Prim hiding ((<|>), State, many, parse, label)+import qualified Data.Text as T+import System.IO.Unsafe (unsafePerformIO)+++++data Addr a = Addr SourcePos SourcePos a++instance Functor Addr where++ fmap f (Addr s e a) = Addr s e $ f a++addr :: Parser a -> Parser (Addr a)+addr p = do x <- getPosition+ y <- p+ z <- getPosition+ return$ Addr x z y+++instance (Show a) => Show (Addr a) where+ show (Addr _ _ x) = show x++instance (Monad m) => Stream T.Text m Char where+ uncons = return . T.uncons++type Parser a = ParsecT T.Text () (StateT SourcePos Identity) a++class Syntax a where+ syntax :: Parser a++instance Syntax Double where+ syntax = read <$> do x <- many1 digit+ string "."+ y <- many1 digit+ return $ x ++ "." ++ y++instance Syntax Int where+ syntax = read <$> many1 digit++instance Syntax String where+ syntax = do char '"'+ (escaped_char <|> anyChar) `manyTill` char '"'++ where escaped_char = do char '\\'+ x <- oneOf "tnr"+ case x of+ 'r' -> return '\r'+ 'n' -> return '\n'+ 't' -> return '\t'+ _ -> error "Unimplemented"+++parse :: Parser a -> SourceName -> String -> Either ParseError a+parse parser sname input = runIndent sname $ runParserT parser () sname (T.pack input)++whitespace :: Parser String+whitespace = many $ oneOf "\t "++whitespace1 :: Parser String+whitespace1 = space >> whitespace++same :: Parser ()+same = spaces >> do pos <- getPosition+ s <- get+ if (sourceColumn pos) /= (sourceColumn s)+ then parserFail $ "not indented to exactly " ++ show (sourceColumn s)+ else do put $ setSourceLine s (sourceLine pos)+ return ()++set_indentation :: (Int -> Int) -> Parser ()+set_indentation f = do s <- get+ put$ setSourceColumn s (f (sourceColumn s))++spaces :: Parser ()+spaces = try emptyline `manyTill` try line_start >> return ()++ where emptyline = whitespace >> newline+ line_start = whitespace >> notFollowedBy newline >> in_block++ in_block = do pos <- getPosition+ s <- get+ if (sourceColumn pos) < (sourceColumn s)+ then parserFail $ "not indented to at least " ++ show (sourceColumn s)+ else do put $ setSourceLine s (sourceLine pos)+ return ()+++comment :: Parser String+comment = try empty_line <|> try commented_code <|> try code <|> markdown_comment++ where markdown_comment = anyChar `manyTill` newline *> return "\n"+ empty_line = whitespace *> newline *> return "\n"+ code = (\x y -> x ++ rstrip y ++ "\n") <$> string " " <*> (anyChar `manyTill` newline)+ commented_code = do string " "+ x <- noneOf "\n" `manyTill` try (string "--")+ anyChar `manyTill` newline+ return $ if length (strip x) > 0+ then " " ++ rstrip x ++ "\n"+ else "\n"++sep_with :: Show a => String -> [a] -> String+sep_with x = concat . L.intersperse x . fmap show++unsep_with :: forall a b. (Show a, Show b) => String -> (M.Map b a) -> String+unsep_with z = concat . L.intersperse ", " . fmap (\(x, y) -> concat [show x, z, show y]) . M.toAscList++(<:>) :: Parser a -> Parser [a] -> Parser [a]+(<:>) x y = (:) <$> x <*> y++operator_dict :: M.Map Char String+operator_dict = M.fromList [ ('!', "_bang"),+ ('@', "_at"),+ ('#', "_hash"),+ ('$', "$"),+ ('%', "_perc"),+ ('^', "_exp"),+ ('&', "_and"),+ ('|', "_or"),+ ('<', "_less"),+ ('>', "_grea"),+ ('?', "_ques"),+ ('/', "_forw"),+ ('=', "_eq"),+ (':', "_col"),+ ('\\', "_back"),+ ('~', "_tild"),+ ('+', "_plus"),+ ('-', "_minu"),+ ('\'', "_tick"),+ ('*', "_star"),+ (',', "_comm"),+ ('\'', "_apos"),+ ('.', "_comp") ]++operator :: Parser Char+operator = oneOf (fst . unzip . M.toList $ operator_dict)++not_reserved :: Parser String -> Parser String+not_reserved x = do y <- x+ if y `elem` reserved_words+ then parserFail "non-reserved word"+ else return y++ where reserved_words = [ "if", "then", "else", "let", "when", "with", "and", "or", "do", "var",+ "module", "open", "yield", "lazy", "inline", "in", "is", "isnt",+ "|", "\\", "=", ":", ",", "->", "<-" ]++not_system :: Parser String -> Parser String+not_system x = not_reserved$ do y <- x+ if y `elem` reserved_words+ then parserFail "non-reserved word"+ else return y++ where reserved_words = [ "==", "<=", ">=", "!=", "<", ">", "||", "&&", ".", "," ]+++type_sep :: Parser Char+indentPairs :: String -> Parser a -> String -> Parser a+not_comma :: Parser ()+comma :: Parser ()++type_sep = try (spaces *> char '|' <* whitespace)+not_comma = whitespace >> newline >> spaces >> notFollowedBy (string "}")+comma = spaces *> string "," *> spaces+optional_sep = try (try comma <|> not_comma)++indentPairs a p b = string a *> P.spaces *> withPosTemp (withPos p) <* P.spaces <* string b++indentAsymmetricPairs :: String -> Parser a -> Parser b -> Parser a+indentAsymmetricPairs a p b = string a *> P.spaces *> withPos p <* P.spaces <* b++withPosTemp p = do x <- get+ try p <|> (put x >> parserFail ("expression continuation indented to " ++ show x))+++db :: Show a => a -> a+db x = unsafePerformIO $ do putStrLn$ "-- " ++ (show x)+ return x+
+ src/hs/Formal/TypeCheck.hs view
@@ -0,0 +1,570 @@++{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE FunctionalDependencies #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE KindSignatures #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE NamedFieldPuns #-}+{-# LANGUAGE OverlappingInstances #-}+{-# LANGUAGE QuasiQuotes #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE TypeSynonymInstances #-}+{-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE ViewPatterns #-}++module Formal.TypeCheck where++import Data.List (intersect, partition,+ union, (\\))++import qualified Data.List as L+import qualified Data.Map as M+import qualified Data.Set as S++import Text.ParserCombinators.Parsec++import Formal.Types.Axiom+import Formal.Types.Definition+import Formal.Types.Expression+import Formal.Types.Namespace hiding (Module)+import Formal.Types.Pattern+import Formal.Types.Statement hiding (Test, find, modules,+ namespace)+import Formal.Types.Symbol++import Formal.Types.Type+import Formal.Types.TypeDefinition++import Formal.Parser+import Formal.Parser.Utils++import Formal.TypeCheck.Types+++-- Type Inference+-- --------------------------------------------------------------------------------+++instance Infer (Expression Definition) Type where+ infer (ApplyExpression _ []) = fail "This should not be"+ infer (ApplyExpression e (x:[])) =++ do te <- infer e+ tx <- infer x+ t <- newTVar Star+ unify (tx `fn` t) te+ return t++ infer (ApplyExpression e (x:xs)) = infer (ApplyExpression (ApplyExpression e (x:[])) xs)++ infer (IfExpression a b c) =++ do ta <- infer a+ tb <- infer b+ tc <- infer c+ t <- newTVar Star+ unify ta bool_type+ unify t tb+ unify t tc+ return t++ infer (LiteralExpression s) = infer s++ infer (SymbolExpression i) =++ do sc <- find (show i)+ (ps :=> t) <- freshInst sc+ predicate ps+ return t++ infer (JSExpression _) =++ do t <- newTVar Star+ return (TypeApplication (Type (TypeConst "JS" (KindFunction Star Star))) t)++ infer (LazyExpression x _) =++ do t <- newTVar Star+ t' <- infer x+ unify t t'+ return (TypeApplication (Type (TypeConst "JS" (KindFunction Star Star))) t)+++ -- TODO this may be removeable at no perf cost?+ infer (FunctionExpression rs) =++ do t <- newTVar Star+ as <- get_assumptions+ [_ :>: q] <- with_scope$ ims as+ (_ :=> t') <- freshInst q+ unify t t'+ return t++ where ims as =++ do infer [Definition Public False (Symbol "") rs]+ as'' <- get_assumptions+ return$ as'' \\ as++ infer (AccessorExpression (Addr s f x) y) = infer (acc y)++ where acc :: [Symbol] -> Expression Definition+ acc [] = x+ acc (y:ys) = --Addr undefined undefined $+ ApplyExpression+ (FunctionExpression+ [ EqualityAxiom+ (Match [RecordPattern (M.fromList [(y, VarPattern "__x__")]) Partial] Nothing)+ (Addr s f (SymbolExpression (Symbol "__x__"))) ] )+ [acc ys]++ infer (RecordExpression (unzip . M.toList -> (names, xs))) =++ do ts <- mapM infer xs+ let r = TypeRecord (TRecord (M.fromList (zip (map f names) ts)) TComplete Star)+ t' <- newTVar Star+ sc <- find $ quantify (tv r) ([] :=> r)+ case sc of+ Nothing ->+ do unify t' r+ return t'+ Just (Forall _ scr, sct) ->+ do (_ :=> t'') <- freshInst sct+ (qs :=> t''') <- return$ inst (map TypeVar$ tv t'') (scr)+ (_ :=> t) <- freshInst (quantify (tv t''' \\ tv t'') (qs :=> t'''))+ unify t r+ unify t' t''+ s <- get_substitution+ let t''' = apply s t+ r''' = apply s r+ qt = quantify (tv t''') $ [] :=> t'''+ rt = quantify (tv r''') $ [] :=> r'''+ sct' = apply s t''+ if qt /= rt+ then do add_error$ "Record does not match expected signature for " ++ show sct' ++ "\n"+ ++ " Expected: " ++ show qt ++ "\n"+ ++ " Actual: " ++ show rt+ return t'+ else return t'++ where f (Symbol x) = x+ f (Operator x) = x++ infer (LetExpression xs x) =++ with_scope$ do infer' defs+ infer x++ where defs = to_group (map DefinitionStatement xs)++ infer' [] = return []+ infer' (x:xs) =++ do a <- infer x+ assume a+ as <- infer' xs+ return$ a ++ as++ infer (ListExpression x) =++ do t <- newTVar Star+ ts <- mapM infer x+ mapM (unify t) ts+ t' <- newTVar Star+ unify t' (TypeApplication (Type (TypeConst "Array" (KindFunction Star Star))) t)+ return t'+ + infer x = error $ "Unimplemented: " ++ show x++-- Axioms++instance (Infer a t) => Infer (Addr a) t where++ infer (Addr s _ x) = do m <- get_msg+ set_msg new_msg+ z <- infer x+ set_msg m+ return z++ where new_msg = " at line " ++ show (sourceLine s) ++ ", column " ++ show (sourceColumn s) ++ "\n"++instance Infer (Axiom (Expression Definition)) Type where++ infer (EqualityAxiom (Match y z) x) =++ do ts <- mapM infer y+ case z of+ (Just q) -> infer q >>= (flip unify) bool_type+ _ -> return ()+ t <- infer x+ return (foldr fn t ts)++ infer _ = newTVar Star++++++-- Generalization++split :: Monad m => ClassEnv -> [TypeVar] -> [TypeVar] -> [Pred] -> m ([Pred], [Pred])+split ce fs _ ps =++ do ps' <- reduce ce ps+ let (ds, rs) = partition (all (`elem` fs) . tv) ps'+ return (ds, rs) -- \\ rs')++instance Infer [Definition] () where+ infer bs =++ do def_types <- mapM (\_ -> newTVar Star) bs++ let is = map get_name bs+ scs = map toScheme def_types+ altss = map get_axioms bs++ axiom_types <- with_scope$+ do assume $ zipWith (:>:) is scs+ mapM (mapM (with_scope . infer)) altss++ let f _ [] = return ()+ f g (x:xs) = do s <- get_substitution+ g x+ g (apply s x)+ f g xs++ mapM (\(t, as) -> f (unify t) as) (zip def_types axiom_types)++ ps <- get_predicates+ as <- get_assumptions+ ps' <- substitute ps+ ss <- get_substitution+ fs' <- substitute as++ let ts' = apply ss def_types+ fs = tv fs'+ vss = map tv ts'+ gs = foldr1 union vss \\ fs++ ce <- get_classenv+ (ds, rs) <- split ce fs (foldr1 intersect vss) ps'++ if restricted then+ let gs' = gs \\ tv rs+ scs' = map (quantify gs' . ([]:=>)) ts'+ in do predicate (ds ++ rs)+ assume (zipWith (:>:) is scs')+ return ()+ else+ let scs' = map (quantify gs . (rs:=>)) ts'+ in do predicate ds+ assume (zipWith (:>:) is scs')+ return ()++ where get_name (Definition _ _ (Symbol x) _) = x+ get_name (Definition _ _ (Operator x) _) = x+ get_axioms (Definition _ _ _ x) = x++ restricted = any simple bs+ simple (Definition _ _ _ axs) = any (null . f) axs++ f (EqualityAxiom (Match p _) _) = p+ f _ = error "Fatal error occurred while reticulating splines"+++data BindGroup = Scope [Namespace] [Statement] [Definition] [[Definition]] [Addr (Expression Definition)]+ | Module String [BindGroup]+ deriving (Show)++instance Infer Definition () where++ infer (Definition _ _ name axs) =++ do sc <- find$ f name+ (qs :=> t) <- freshInst sc+ axiom_types <- with_scope$ mapM (with_scope . infer) axs++ s <- get_substitution+ mapM (flip unify t) axiom_types -- TODO apply sub to axiom_types?++ as <- get_assumptions+ ce <- get_classenv+ ps <- get_predicates++ let qs' = apply s qs+ t' = apply s t+ fs = tv (apply s as)+ gs = tv t' \\ fs+ sc' = quantify gs (qs' :=> t')+ ps' = filter (not . entail ce qs') (apply s ps)++ (_, rs) <- split ce fs gs ps'++ if sc /= sc' then+ add_error$ "Signature too general\n\n Expected: " ++ show sc ++ "\n Actual: " ++ show sc'+ else if not (null rs) then+ add_error$ "Context too weak\n\n Expected: " ++ show sc ++ "\n Actual: " ++ show sc'+ else+ assume (f name :>: sc)++ return ()++ where f (Symbol x) = x+ f (Operator x) = x++instance Infer Test () where++ infer (Test ex) = do t <- newTVar Star+ x <- infer ex+ unify t x+ unify t bool_type++newtype Test = Test (Addr (Expression Definition))++instance Infer BindGroup [Assumption] where+ infer (Scope imps tts es iss ts) =++ do --as <- get_assumptions+ mapM import' imps+ as' <- get_assumptions+ infer tts+ mapM assume$ sigs es+ mapM infer iss+ with_scope$ mapM infer es+ mapM infer (map Test ts)+ as'' <- get_assumptions+ set_assumptions as'+ return (as'' \\ as')++ where f (TypeAxiom t) = True+ f _ = False++ g name (TypeAxiom t) = [ name :>: to_scheme' t' | t' <- enumerate_types t ]++ to_scheme' :: Type -> Scheme+ to_scheme' t = quantify (tv t) ([] :=> t)++ sigs :: [Definition] -> [Assumption]+ sigs [] = []+ sigs (Definition _ _ name as:xs) =+ case L.find f as of+ Nothing -> sigs xs+ Just x -> g (h name) x ++ sigs xs++ import' (Namespace ns) =++ do z <- get_modules+ a <- get_assumptions+ (Namespace ns') <- get_namespace+ case Namespace ns `lookup` z of+ Just z' -> assume$ a ++ z'+ Nothing -> if length ns' > 0 && head ns' /= head ns+ then import' (Namespace (head ns' : ns))+ else add_error$ "Unknown namespace " ++ show (Namespace ns)++ h (Symbol x) = x+ h (Operator x) = x++ infer (Module name bgs) =++ do as <- get_assumptions+ with_module name$ infer' bgs+ set_assumptions as+ return []++ where infer' [] = return []+ infer' (x:xs) =++ do a <- infer x+ assume a+ as' <- infer' xs+ return$ a ++ as'++++to_scheme :: TypeDefinition -> UnionType -> [Assumption]+to_scheme (TypeDefinition n vs) t = [ quantify (vars y) ([]:=> y) :>>: def_type y+ | y <- enumerate_types t ]++ where vars y = map (\x -> TVar x (infer_kind x y)) vs++ def_type y = quantify (vars y) ([] :=> foldl app poly_type (map TypeVar (vars y)))++ poly_type = Type (TypeConst n (to_kind (length vs)))++ to_kind 0 = Star+ to_kind n = KindFunction Star (to_kind$ n - 1)++ app :: Type -> Type -> Type+ app y x = TypeApplication y x++ -- TODO this is still wrong - have to check for all enumerated types++ infer_kind x y = let ks = infer_kinds x y+ in if ks == []+ then Star+ else if all (\x -> x == head ks) ks+ then head ks+ else error "Kind mismatch in scheme"++ infer_kinds x (TypeApplication a b) = infer_kinds x a ++ infer_kinds x b+ infer_kinds x (TypeVar (TVar y k)) | x == y = [k]+ infer_kinds x (TypeRecord (TRecord m _ _)) = concat$ map (infer_kinds x) (M.elems m)+ infer_kinds _ _ = []++-- | Computes all possible types from a type signature AST.++enumerate_types :: UnionType -> [Type]+enumerate_types (UnionType types) = to_unit . concat . map enumerate_type . S.toList $ types++ where term_type (VariableType x) = [ TypeVar (TVar x Star) ]+ term_type (SymbolType x) = [ Type (TypeConst (show x) Star) ]+ term_type (PolymorphicType a b) = [ foldl TypeApplication a' b'+ | b' <- map enumerate_types b+ , a' <- to_kind' (length b')$ term_type a ]++ to_kind 0 = Star+ to_kind n = KindFunction Star (to_kind$ n - 1)++ to_unit [] = [TypeRecord (TRecord M.empty TComplete Star)]+ to_unit x = x++ to_kind' _ [] = []+ to_kind' n (TypeVar (TVar x _) : xs) = TypeVar (TVar x (to_kind n)) : to_kind' n xs+ to_kind' n (Type (TypeConst x _) : xs) = Type (TypeConst x (to_kind n)) : to_kind' n xs++ enumerate_type (SimpleType x) = term_type x++ enumerate_type (FunctionType a b) =+ [ a' `fn` b' | a' <- enumerate_types a, b' <- enumerate_types b ]++ enumerate_type (RecordType (unzip . M.toList -> (names, types'))) =++ map f permutations++ where f = TypeRecord . (\x -> TRecord x TComplete Star) . M.fromList . zip (map show names)+ permutations = permutations' . map enumerate_types $ types'++ where permutations' [] = []+ permutations' (x:[]) = [ x ]+ permutations' (x:xs) = [ x' : xs' | x' <- x, xs' <- permutations' xs ]++++++instance Infer [Statement] () where++ infer [] = return ()+ infer (TypeStatement t c : xs) =++ do assume $ to_scheme t c+ infer xs++ infer (_ : xs) = infer xs++sort_dep :: [[Definition]] -> [[Definition]]+sort_dep [] = []+sort_dep xs = case map (:[])$ concat$ map snd$ filter fst free of+ [] -> error$ "Unresolvable dependency ordering in " ++ show (get_names xs)+ xs -> xs ++ sort_dep (map snd$ filter (not . fst) free)+++ where as = get_needed (get_names xs) (zip (get_names xs) (get_expressions xs))++ free = get_free as `zip` xs++ get_free [] = []+ get_free ([]:xs) = True : get_free xs+ get_free (_:xs) = False : get_free xs++ get_names [] = []+ get_names ([Definition _ _ n _]:xs) = show n : get_names xs++ get_needed _ [] = []+ get_needed names ((n,x):xs) =+ ((names \\ [n]) `L.intersect` (concat$ map get_symbols x)) : get_needed names xs++ get_expressions :: [[Definition]] -> [[Expression Definition]]+ get_expressions [] = []+ get_expressions ([Definition _ _ _ as]:xs) = get_expressions' as : get_expressions xs++ get_expressions' [] = []+ get_expressions' (TypeAxiom _: xs) = get_expressions' xs+ get_expressions' (EqualityAxiom (Match _ (Just y)) (Addr _ _ x): xs) = y : x : get_expressions' xs+ get_expressions' (EqualityAxiom _ (Addr _ _ x): xs) = x : get_expressions' xs++ get_symbols (RecordExpression (unzip . M.toList -> (_, xs))) = concat (map get_symbols xs)+ get_symbols (AccessorExpression (Addr _ _ x) _) = get_symbols x+ get_symbols (ApplyExpression a b) = get_symbols a ++ concat (map get_symbols b)+ get_symbols (IfExpression a b c) = get_symbols a ++ get_symbols b ++ get_symbols c+ get_symbols (LiteralExpression _) = []+ get_symbols (SymbolExpression x) = [show x]+ get_symbols (JSExpression _) = []+ get_symbols (LazyExpression (Addr _ _ x) _) = get_symbols x+ get_symbols (FunctionExpression as) = concat$ map get_symbols$ get_expressions' as+ get_symbols (LetExpression _ x) = get_symbols x+ get_symbols (ListExpression x) = concat (map get_symbols x)+js_type :: Type++js_type = Type (TypeConst "JS" (KindFunction Star Star))++tiProgram :: Program -> [(Namespace, [Assumption])] -> ([(Namespace, [Assumption])], [String])+tiProgram (Program bgs) env =++ runTI $ do TI (\x -> (x { modules = env }, ()))+ assume$ "true" :>: (Forall [] ([] :=> Type (TypeConst "Bool" Star)))+ assume$ "false" :>: (Forall [] ([] :=> Type (TypeConst "Bool" Star)))+ assume$ "error" :>: (Forall [Star] ([] :=> TypeGen 0))+ assume$ "run" :>: (Forall [Star] ([] :=> (TypeApplication js_type (TypeGen 0) -:> TypeGen 0)))+ infer'$ to_group bgs+ s <- get_substitution+ ce <- get_classenv+ ps <- get_predicates+ ms <- TI (\y -> (y, modules y))+ rs <- reduce ce (apply s ps)+ e <- get_errors+ return ((apply s ms), S.toList . S.fromList $ e)++ where infer' [] = return ()+ infer' (x:xs) =++ do a <- infer x+ assume a+ infer' xs+++++to_group :: [Statement] -> [BindGroup]+to_group [] = []+to_group xs = case takeWhile not_module xs of+ [] -> to_group' xs+ yx -> sort_deps (foldl f (Scope [] [] [] [] []) yx)+ : to_group' (dropWhile not_module xs)++ where to_group' [] = []+ to_group' (ModuleStatement x y:xs) = Module (show x) (to_group y) : to_group xs+ to_group' _ = error "Unexpected"++ sort_deps (Scope i t a b c) = Scope i t a (sort_dep b) c++ not_module (ModuleStatement _ _) = False+ not_module _ = True++ f (Scope i t a b c) (DefinitionStatement x @ (Definition _ _ _ (EqualityAxiom _ _:_))) =+ Scope i t a (b ++ [[x]]) c+ f (Scope i t a b c) (DefinitionStatement x @ (Definition _ _ _ (TypeAxiom _:_))) =+ Scope i t (a ++ [x]) b c+ f (Scope i t a b c) (ExpressionStatement x) =+ Scope i t a b (c ++ [x])+ f (Scope i t a b c) (ImportStatement ns) =+ Scope (i ++ [ns]) t a b c+ f (Scope i t a b c) x @ (TypeStatement _ _) =+ Scope i (t ++ [x]) a b c+ f x _ = x+
+ src/hs/Formal/TypeCheck/Types.hs view
@@ -0,0 +1,671 @@+{-# LANGUAGE QuasiQuotes #-}+{-# LANGUAGE NamedFieldPuns #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE ViewPatterns #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE QuasiQuotes #-}+{-# LANGUAGE OverlappingInstances #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE FunctionalDependencies #-}+{-# LANGUAGE TypeSynonymInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE UndecidableInstances, KindSignatures #-}++module Formal.TypeCheck.Types where++import Data.List (nub, intersect, union)+import System.IO.Unsafe++import Text.InterpolatedString.Perl6++import Data.List (nub, (\\), intersect, union, partition)++import qualified Data.Map as M+import qualified Data.List as L+import qualified Data.Set as S++import Control.Monad+import Data.Monoid++import Formal.Types.Namespace hiding (Module)++type Id = String++enumId :: Int -> Id+enumId n = "v" ++ show n++data Kind = Star | KindFunction Kind Kind deriving (Show, Eq, Ord)++type Key = String++data Type = TypeVar TypeVar+ | Type TypeConst+ | TypeApplication Type Type+ | TypeRecord TypeRecord+ | TypeGen Int+ deriving Eq++data TPartial = TComplete | TPartial Type deriving (Eq, Show)++data TypeRecord = TRecord (M.Map Key Type) TPartial Kind+ deriving (Show, Eq)++data TypeVar = TVar Id Kind+ deriving (Show, Eq, Ord)++data TypeConst = TypeConst Id Kind -- (?)+ deriving (Show, Eq, Ord)++instance Show Type where+ show (TypeVar (TVar i _)) = i+ show (Type (TypeConst i _)) = i+ show (TypeApplication (TypeApplication (Type (TypeConst "->" _)) + u @ (TypeApplication (TypeApplication (Type (TypeConst "->" _)) _) _)) v) = + "(" ++ show u ++ ") → " ++ show v+ show (TypeApplication (TypeApplication (Type (TypeConst "->" _)) u) v) = + show u ++ " → " ++ show v+ show (TypeApplication t u) = show t ++ " " ++ show u+ show (TypeGen x) = (map (:[])$ concat$ repeat "abcdefghijklmnopqrstuvwxyz") !! x+ show (TypeRecord (TRecord m TComplete _)) =+ "{" ++ (concat$ L.intersperse ", "$ map (\(x, y) -> x ++ " = " ++ show y) . M.toList $ m) ++ "}"+ show (TypeRecord (TRecord m (TPartial _) _)) =+ "{" ++ (concat$ L.intersperse ", "$ map (\(x, y) -> x ++ " = " ++ show y) . M.toList $ m) ++ ", _ }"+++num_type :: Type+fun_type :: Type+num_type = Type (TypeConst "Num" Star)+fun_type = Type (TypeConst "->" (KindFunction Star (KindFunction Star Star)))++infixr 4 -:>+(-:>) :: Type -> Type -> Type+a -:> b = TypeApplication (TypeApplication fun_type a) b++class HasKind t where kind :: t -> Kind++instance HasKind TypeVar where kind (TVar _ k) = k+instance HasKind TypeConst where kind (TypeConst _ k) = k+instance HasKind TypeRecord where kind (TRecord _ _ k) = k+instance HasKind Type where+ kind (Type x) = kind x+ kind (TypeVar x) = kind x+ kind (TypeRecord x) = kind x+ kind (TypeApplication (kind -> KindFunction _ k) _) = k+ kind t = error$ "Could not determine kind of " ++ show t++type Substitution = [(TypeVar, Type)]++(+->) :: TypeVar -> Type -> Substitution+x +-> y = [(x, y)]++class Types t where+ apply :: Substitution -> t -> t+ tv :: t -> [TypeVar]++instance Types Type where+ apply s (TypeVar u) = case lookup u s of + Just x -> x+ Nothing -> TypeVar u+ apply s (TypeApplication l r) = TypeApplication (apply s l) (apply s r)+ apply s (TypeRecord (TRecord xs TComplete k)) = TypeRecord (TRecord (fmap (apply s) xs) TComplete k)+ apply s (TypeRecord (TRecord xs (TPartial p) k)) =+ case apply s p of+ p' | p' == p -> TypeRecord (TRecord (fmap (apply s) xs) (TPartial p) k)+ TypeRecord (TRecord ys p' _) -> TypeRecord (TRecord (fmap (apply s) (xs `M.union` ys)) p' k)+ x -> TypeRecord (TRecord (fmap (apply s) xs) (TPartial x) k)+ apply _ t = t++ tv (TypeVar u) = [u]+ tv (TypeApplication l r) = tv l `union` tv r+ tv (TypeRecord (TRecord xs TComplete _)) = nub $ M.elems xs >>= tv+ tv (TypeRecord (TRecord xs (TPartial t) _)) = (nub $ M.elems xs >>= tv) ++ tv t+ tv _ = []++instance Types a => Types [a] where+ apply s = map (apply s)+ tv = nub . concat . map tv++infixr 4 @@+(@@) :: Substitution -> Substitution -> Substitution+s1 @@ s2 = ([(u, apply s1 t) | (u, t) <- s2] ++ s1)++merge :: Monad m => Substitution -> Substitution -> m Substitution+merge s1 s2 = if agree then return (s1 ++ s2) else fail $ "merge fails " ++ show s1 ++ show s2+ where agree = all f (map fst s1 `intersect` map fst s2)+ f (TypeVar -> v) = apply s1 v == apply s2 v++++++++-- Unification+-- --------------------------------------------------------------------------------++instance Monoid TypeVar where+ mappend (TVar x k) (TVar y k') | k == k' = TVar (x ++ y) k+ mempty = TVar "" Star++var_bind :: Monad m => TypeVar -> Type -> m Substitution+match :: Monad m => Type -> Type -> m Substitution++class Unify a where+ (|=|) :: Monad m => a -> a -> m Substitution++instance Unify TypeRecord where++ TRecord t TComplete _ |=| TRecord u TComplete _+ | M.keysSet t == M.keysSet u = ++ f (M.elems t) (M.elems u) []++ where f [] _ s = return s+ f (x:xs) (y:ys) s = do s' <- apply s x |=| apply s y+ f xs ys (s @@ s')++ TRecord t (TPartial (TypeVar p)) k |=| TRecord u (TPartial (TypeVar p')) k' =++ do a <- TRecord t' TComplete k |=| TRecord u' TComplete k'+ b <- f (u M.\\ t) p (p `mappend` p') k+ c <- f (t M.\\ u) p' (p `mappend` p') k+ return$ a @@ b @@ c++ where t' = u M.\\ (u M.\\ t)+ u' = t M.\\ (t M.\\ u)+ + f x p p' k | M.size x > 0 = var_bind p (TypeRecord (TRecord x (TPartial (TypeVar p')) k))+ | otherwise = return []++ t' @ (TRecord t (TPartial (TypeVar p)) k) |=| u' @ (TRecord u TComplete k')+ | M.keysSet t `S.intersection` M.keysSet u == M.keysSet t =++ do a <- TRecord t TComplete k |=| TRecord (u M.\\ (u M.\\ t)) TComplete k'+ b <- if M.size u >= M.size t+ then var_bind p$ TypeRecord$ TRecord (u M.\\ t) TComplete Star+ else return []+ return$ a @@ b++ | otherwise = fail [qq|Records do not unify: found {TypeRecord t'}, expecting {TypeRecord u'}|]+ + t |=| u @ (TRecord _ (TPartial _) _) = u |=| t++ t |=| u = fail [qq|Illegal record unification: {TypeRecord t} and {TypeRecord u}|]++instance Unify Type where++ TypeApplication l1 r1 |=| TypeApplication l2 r2 =++ do s1 <- l1 |=| l2+ s2 <- apply s1 r1 |=| apply s1 r2+ return$ s1 @@ s2++ TypeVar u |=| t = var_bind u t+ t |=| TypeVar u = var_bind u t+ TypeRecord a |=| TypeRecord b = a |=| b+ Type t |=| Type u | t == u = return []+ t |=| u = fail$ "Types do not unify: found " ++ show t ++ ", expecting " ++ show u++data Z a = Z a | Error String++instance Monad Z where+ return x = Z x+ (Z x) >>= f = f x+ (Error x) >>= _ = Error x+ fail x = Error x++mgu :: Type -> Type -> TI Substitution+mgu x y = do z <- mgu' x y+ case z of+ Left e -> add_error e >> return []+ Right e -> return e++mgu' :: Type -> Type -> TI (Either String Substitution)+mgu' x y = case x |=| y of+ Z z -> return $ Right z+ Error e -> second_chance e x y++ where second_chance e x@ (TypeRecord (TRecord _ (TPartial _) _)) y =+ + do as <- get_assumptions+ g <- find''' as x++ case g of+ Nothing -> return $ Left e --add_error e >> return []+ Just (x, sct) ->+ do (qs' :=> t'') <- freshInst sct+ return $ Right x++ second_chance e y x @ (TypeRecord (TRecord _ (TPartial _) _)) = second_chance e x y+ second_chance e (TypeApplication a b) (TypeApplication c d) =+ do xss <- second_chance e a c+ yss <- second_chance e b d+ case (xss, yss) of+ (Right xss', Right yss') -> return$ Right$ xss' @@ yss'+ (Left e', _) -> return $ Left e'+ (_, Left e') -> return $ Left e'+ ++ second_chance e x y = case x |=| y of+ Error _ -> return $ Left e --add_error e >> return []+ Z x -> return $ Right x+ + find''' [] _ = return Nothing+ find''' (_:>:_:xs) t = find''' xs t+ find''' ((Forall _ x :>>: y):xs) t =++ do (_ :=> t') <- return$ inst (map TypeVar$ tv t) x+ case t' |=| t of+ Error _ -> find''' xs t++ -- TODO Only allow this shorthand if the match is unique - true?+ Z x -> do zz' <- find''' xs t+ case zz' of+ Nothing -> return$ Just (x, y)+ Just _ -> return$ Nothing++var_bind u t | t == TypeVar u = return []+ | u `elem` tv t = fail $ "occurs check fails: " ++ show u ++ show t+ | kind u /= kind t = fail "kinds do not match"+ | otherwise = return (u +-> t)++match (TypeApplication l1 r1) (TypeApplication l2 r2) =+ do s1 <- match l1 l2+ s2 <- match r1 r2+ merge s1 s2++match (TypeVar u) t + | kind u == kind t = return (u +-> t)+match (TypeRecord t) (TypeRecord u) + | t == u = return []+match (Type t) (Type u)+ | t == u = return []+match _ _ = fail "Types do not match"++++-- Type Classes+-- --------------------------------------------------------------------------------++data Qual t = [Pred] :=> t deriving Eq+data Pred = IsIn Id Type deriving (Show, Eq)++instance (Show t) => Show (Qual t) where+ show (_ :=> t) = show t++instance Types t => Types (Qual t) where+ apply s (ps :=> t) = apply s ps :=> apply s t+ tv (ps :=> t) = tv ps `union` tv t++instance Types Pred where+ apply s (IsIn i t) = IsIn i (apply s t)+ tv (IsIn _ t) = tv t++mguPred, matchPred :: Pred -> Pred -> Maybe Substitution+mguPred = lift (|=|)+lift :: forall (m :: * -> *) a.+ Monad m =>+ (Type -> Type -> m a) -> Pred -> Pred -> m a+matchPred = lift match++lift m (IsIn i t) (IsIn i' t')+ | i == i' = m t t'+ | otherwise = fail "classes differ"++type Class = ([Id], [Inst])+type Inst = Qual Pred++++-- Class Environments+-- --------------------------------------------------------------------------------++data ClassEnv = ClassEnv { classes :: Id -> Maybe Class,+ defaults :: [Type] }++super :: ClassEnv -> Id -> [Id]+super ce i = case classes ce i of Just (is, _) -> is++insts :: ClassEnv -> Id -> [Inst]+insts ce i = case classes ce i of Just (_, its) -> its++defined :: Maybe a -> Bool+defined (Just x) = True+defined Nothing = False++modify :: ClassEnv -> Id -> Class -> ClassEnv+modify ce i c = ce{classes = \j -> if i==j then Just c+ else classes ce j}++initialEnv :: ClassEnv+initialEnv = ClassEnv { classes = \_ -> fail "class not defined",+ defaults = [num_type] }++type EnvTransformer = ClassEnv -> Maybe ClassEnv++infixr 5 <::>+(<::>) :: EnvTransformer -> EnvTransformer -> EnvTransformer+(f <::> g) ce = do ce' <- f ce+ g ce'++addClass :: Id -> [Id] -> EnvTransformer+addClass i is ce+ | defined (classes ce i) = fail "class already defined"+ | any (not . defined . classes ce) is = fail "superclass not defined"+ | otherwise = return (modify ce i (is, []))++addPreludeClasses :: EnvTransformer+addPreludeClasses = addCoreClasses <::> addNumClasses++addCoreClasses :: EnvTransformer+addCoreClasses = addClass "Eq" []+ <::> addClass "Ord" ["Eq"]+ <::> addClass "Show" []+ <::> addClass "Read" []+ <::> addClass "Bounded" []+ <::> addClass "Enum" []+ <::> addClass "Functor" []+ <::> addClass "Monad" []++addNumClasses :: EnvTransformer+addNumClasses = addClass "Num" ["Eq", "Show"]+ <::> addClass "Real" ["Num", "Ord"]+ <::> addClass "Fractional" ["Num"]+ <::> addClass "Integral" ["Real", "Enum"]+ <::> addClass "RealFrac" ["Real", "Fractional"]+ <::> addClass "Floating" ["Fractional"]+ <::> addClass "RealFloat" ["RealFrac", "Floating"]++++-- Entailment+-- --------------------------------------------------------------------------------++bySuper :: ClassEnv -> Pred -> [Pred]+bySuper ce p@(IsIn i t) =+ p : concat [ bySuper ce (IsIn i' t) | i' <- super ce i ]++byInst :: ClassEnv -> Pred -> Maybe [Pred]+byInst ce p@(IsIn i t) = msum [ tryInst it | it <- insts ce i ]+ where tryInst (ps :=> h) = do u <- matchPred h p+ Just (map (apply u) ps)++entail :: ClassEnv -> [Pred] -> Pred -> Bool+entail ce ps p = any (p `elem`) (map (bySuper ce) ps) ||+ case byInst ce p of+ Nothing -> False+ Just qs -> all (entail ce ps) qs++inHnf :: Pred -> Bool+inHnf (IsIn _ t) = hnf t+ where hnf (TypeVar v) = True+ hnf (Type tc) = False+ hnf (TypeApplication t _) = hnf t++toHnfs :: Monad m => ClassEnv -> [Pred] -> m [Pred]+toHnfs ce ps = do pss <- mapM (toHnf ce) ps+ return (concat pss)++toHnf :: Monad m => ClassEnv -> Pred -> m [Pred]+toHnf ce p | inHnf p = return [p]+ | otherwise = case byInst ce p of+ Nothing -> fail "context reduction"+ Just ps -> toHnfs ce ps++simplify :: ClassEnv -> [Pred] -> [Pred]+simplify ce = loop []+ where loop rs [] = rs+ loop rs (p:ps) | entail ce (rs++ps) p = loop rs ps+ | otherwise = loop (p:rs) ps++reduce :: Monad m => ClassEnv -> [Pred] -> m [Pred]+reduce ce ps = do qs <- toHnfs ce ps+ return (simplify ce qs)++scEntail :: ClassEnv -> [Pred] -> Pred -> Bool+scEntail ce ps p = any (p `elem`) (map (bySuper ce) ps)++++-- Type Schemes+-- --------------------------------------------------------------------------------++data Scheme = Forall [Kind] (Qual Type) deriving Eq++instance Show Scheme where+ show (Forall [] t) = show t+ show (Forall xs t) = show t --"∀" ++ vars ++ " ⇒ " ++ show t+ where vars = concat . L.intersperse " " . map (\x -> (map (:[]) "abcdefghijklmnopqrstuvwxyz") !! x) . take (length xs) $ [0..]++instance Types Scheme where+ apply s (Forall ks qt) = Forall ks (apply s qt)+ tv (Forall _ qt) = tv qt++quantify :: [TypeVar] -> Qual Type -> Scheme+quantify vs qt = Forall ks (apply s qt)+ where vs' = [ v | v <- tv qt, v `elem` vs ]+ ks = map kind vs'+ s = zip vs' (map TypeGen [0..])++toScheme :: Type -> Scheme+toScheme t = Forall [] ([] :=> t)++++-- Assumptions+-- --------------------------------------------------------------------------------++data Assumption = Id :>: Scheme | Scheme :>>: Scheme deriving (Eq)++newtype A = A [Assumption]++instance Show Assumption where+ show (i :>: s) = i ++ ": " ++ show s+ show (i :>>: s) = show i ++ ": " ++ show s++instance Types Assumption where+ apply s (i :>: sc) = i :>: (apply s sc)+ apply s (sc :>>: sd) = apply s sc :>>: apply s sd++ tv (_ :>: sc) = tv sc+ tv (sc :>>: _) = tv sc++class Find a b | a -> b where+ find :: a -> TI b++instance Find Id Scheme where++ find i = do (reverse -> x) <- get_assumptions+ find' x ++ where find' ((i':>:sc):as) = if i == i' then return sc else find' as+ find' (_:as) = find' as+ find' [] = do add_error ("Unbound identifier " ++ show i)+ return$ toScheme$ TypeVar (TVar "a" Star)+ ++instance Find Scheme (Maybe (Scheme, Scheme)) where++ find i = do (reverse -> x) <- get_assumptions+ find' x ++ where find' [] = return Nothing+ find' ((i':>>:sc):as) = do (_ :=> i'') <- freshInst i+ (_ :=> i''') <- freshInst i'+ x <- i'' `can_unify` i'''+ if x then return $ Just (i', sc) else find' as+ find' (_:as) = find' as++++-- Type Inference Monad+-- --------------------------------------------------------------------------------++data TIState = TIState { substitution :: Substitution+ , seed :: Int+ , class_env :: ClassEnv+ , msg :: String+ , warnings :: [String]+ , errors :: [String]+ , modules :: [(Namespace, [Assumption])]+ , namespace :: Namespace+ , assumptions :: [Assumption]+ , predicates :: [Pred] }++newtype TI a = TI (TIState -> (TIState, a))++instance Monad TI where+ fail x = TI (\y -> error$ x ++ "\n" ++ msg y) + return x = TI (\y -> (y, x))+ TI f >>= g = TI (\x -> case f x of+ (y, x) -> let TI gx = g x+ in gx y)++instance Functor TI where+ fmap f y = y >>= (\x -> TI (\x' -> (x', f x)))++instance Types [(Namespace, [Assumption])] where+ apply s v = map (\(x, y) -> (x, apply s y)) v+ tv = concat . map (\(_, y) -> tv y)+++runTI :: TI a -> a+runTI (TI f) = x where (t,x) = f (TIState [] 0 initialEnv "" [] [] [] (Namespace []) [] [])++get_assumptions :: TI [Assumption]+get_msg :: TI String+set_msg :: String -> TI ()+get_predicates :: TI [Pred]+set_predicates :: [Pred] -> TI ()+get_substitution :: TI Substitution+get_classenv :: TI ClassEnv+add_error :: String -> TI ()++get_assumptions = TI (\x -> (x, assumptions x))+get_msg = TI (\x -> (x, msg x))+set_msg x = TI (\y -> (y { msg = x }, ()))+get_predicates = TI (\x -> (x, predicates x))+set_predicates x = TI (\y -> (y { predicates = x }, ()))+get_substitution = TI (\x -> (x, substitution x))+get_classenv = TI (\x -> (x, class_env x))+add_error y = TI (\x -> (x { errors = errors x ++ [y ++ "\n" ++ msg x] }, ()))+set_assumptions :: [Assumption] -> TI ()+get_errors :: TI [String]+get_errors = TI (\x -> (x, errors x))+get_modules :: TI [(Namespace, [Assumption])]+get_modules = TI (\x -> (x, modules x))+set_assumptions x = TI (\y -> (y { assumptions = x }, ()))+get_namespace :: TI Namespace+get_namespace = TI (\y -> (y, namespace y))+ +class Assume a where+ assume :: a -> TI ()++instance Assume Assumption where+ assume x = TI (\y -> (y { assumptions = assumptions y ++ (x:[]) }, ()))++instance Assume [Assumption] where+ assume x = TI (\y -> (y { assumptions = assumptions y ++ x}, ()))++class Predicated a where+ predicate :: a -> TI ()++instance Predicated Pred where+ predicate x = TI (\y -> (y { predicates = predicates y ++ (x:[]) }, ()))++instance Predicated [Pred] where+ predicate x = TI (\y -> (y { predicates = predicates y ++ x}, ()))+++with_scope :: TI a -> TI a+with_scope x = do as <- get_assumptions+ ps <- get_predicates+ y <- x+ set_assumptions as+ set_predicates ps+ return y++with_module :: String -> TI [Assumption] -> TI ()+with_module name x = do --as <- get_assumptions+ ns <- get_namespace+ set_namespace (ns `mappend` Namespace [name])+ as' <- x+ --as' <- get_assumptions+ --set_assumptions as+ add_module (ns `mappend` Namespace [name], as')+ set_namespace ns++ where add_module x = TI (\y -> (y { modules = modules y ++ [x] }, ()))++ set_namespace x = TI (\y -> (y { namespace = x }, ()))+++substitute :: Types a => a -> TI a+substitute x = do y <- get_substitution+ return $ apply y x++unify :: Type -> Type -> TI ()+unify t1 t2 = do s <- get_substitution+ u <- apply s t1 `mgu` apply s t2+ extSubst $ u @@ s++ where extSubst :: Substitution -> TI ()+ extSubst s' = TI (\x -> (x { substitution = s' }, ()))++can_unify :: Type -> Type -> TI Bool+can_unify t1 t2 = with_scope $ + do s <- get_substitution+ u <- apply s t1 `mgu'` apply s t2+ case u of+ Left x -> return False+ Right x -> return True++newTVar :: Kind -> TI Type+newTVar k = TI (\x -> let v = TVar (enumId (seed x)) k+ in (x { seed = seed x + 1}, TypeVar v))++freshInst :: Scheme -> TI (Qual Type)+freshInst (Forall ks qt) = do ts <- mapM newTVar ks+ return (inst ts qt)++class Instantiate t where+ inst :: [Type] -> t -> t++instance Instantiate Type where+ inst ts (TypeApplication l r) = TypeApplication (inst ts l) (inst ts r)+ inst ts (TypeGen n) = ts !! n+ inst ts (TypeRecord (TRecord m TComplete k)) =+ TypeRecord (TRecord (M.map (inst ts) m) TComplete k)+ inst ts (TypeRecord (TRecord m (TPartial p) k)) =+ TypeRecord (TRecord (M.map (inst ts) m) (TPartial (inst ts p)) k)+ inst _ t = t++instance Instantiate a => Instantiate [a] where+ inst ts = map (inst ts)++instance Instantiate t => Instantiate (Qual t) where+ inst ts (ps :=> t) = inst ts ps :=> inst ts t++instance Instantiate Pred where+ inst ts (IsIn c t) = IsIn c (inst ts t)++class Infer e t | e -> t where infer :: e -> TI t+++list_scheme :: Scheme+list_scheme = Forall [Star] qual_list+ where qual_list = [] :=> TypeApplication (Type (TypeConst "List" (KindFunction Star Star))) (TypeGen 0)++bool_type :: Type+bool_type = Type (TypeConst "Bool" Star)++-- Expressions+++infixr 4 `fn`+fn :: Type -> Type -> Type+a `fn` b = TypeApplication (TypeApplication fun_type a) b
+ src/hs/Formal/Types/Axiom.hs view
@@ -0,0 +1,98 @@+{-# LANGUAGE QuasiQuotes #-}+{-# LANGUAGE NamedFieldPuns #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE ViewPatterns #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE QuasiQuotes #-}+{-# LANGUAGE OverlappingInstances #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE ScopedTypeVariables #-}++module Formal.Types.Axiom where++import Text.InterpolatedString.Perl6+import Language.Javascript.JMacro++import qualified Data.Map as M++import Formal.Parser.Utils+import Formal.Javascript.Utils++import Formal.Types.Type+import Formal.Types.Pattern+++import Data.Monoid++import Prelude hiding (curry, (++))+++-- Axiom+-- --------------------------------------------------------------------------------++data Axiom a = TypeAxiom UnionType+ | EqualityAxiom (Match a) (Addr a)++instance (Show a) => Show (Axiom a) where+ show (TypeAxiom x) = ": " ++ show x+ show (EqualityAxiom ps ex) = [qq|$ps = $ex|]++instance (Show a, ToJExpr a) => ToJExpr [Axiom a] where+ toJExpr [] = toJExpr . scope $ (Curried [] :: Curried a)+ toJExpr (TypeAxiom _:xs) = toJExpr xs+ toJExpr xs @ (EqualityAxiom (Match ps _) _ : _) = scope . curry (length ps) id . toStat . Curried $ xs++newtype Curried a = Curried [Axiom a]++instance (Show a, ToJExpr a) => ToStat (Curried a) where++ toStat (Curried []) = [jmacro| exhaust(); |]++ toStat (Curried (EqualityAxiom (Match [] Nothing) (Addr _ _ ex) : xss)) = ++ [jmacro| return `(ex)`; |]++ toStat (Curried (EqualityAxiom (Match pss Nothing) (Addr _ _ ex) : xss)) = ++ [jmacro| `(declare_bindings (var_names pss) pss)`;+ if (`(pss)`) return `(ex)`;+ `(Curried xss)`; |]+ + toStat (Curried (EqualityAxiom (Match [] cond) (Addr _ _ ex) : xss)) = ++ [jmacro| if (`(cond)`) return `(ex)`; |]+ ++ toStat (Curried (EqualityAxiom (Match pss cond) (Addr _ _ ex) : xss)) = ++ [jmacro| `(declare_bindings (var_names pss) pss)`;+ if (`(pss)` && `(cond)`) return `(ex)`;+ `(Curried xss)`; |]+++declare_bindings (name : names) (AliasPattern x : zs) =++ declare_bindings (take (length x) (repeat name)) x ++ declare_bindings names zs++declare_bindings (name : names) (VarPattern x : zs) =+ + [jmacro| `(declare x name)`; |] ++ declare_bindings names zs++declare_bindings (name : names) (RecordPattern x _: zs) = + let (ns, z) = unzip . M.toList $ x+ in declare_bindings (map (acc name) ns) z ++ declare_bindings names zs++declare_bindings (_ : names) (_ : zs) = declare_bindings names zs+declare_bindings [] [] = mempty++var_names :: forall a. [a] -> [JExpr]+var_names pss = map ref . reverse . take (length pss) . map local_pool $ [0 .. 26]++acc n ns = [jmacroE| `(n)`[`(ns)`] |]+++instance (ToJExpr a) => ToJExpr (Maybe a) where+ toJExpr = maybe (toJExpr True) toJExpr
+ src/hs/Formal/Types/Definition.hs view
@@ -0,0 +1,153 @@+{-# LANGUAGE QuasiQuotes #-}+{-# LANGUAGE NamedFieldPuns #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE ViewPatterns #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE QuasiQuotes #-}+{-# LANGUAGE OverlappingInstances #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE ScopedTypeVariables, MultiParamTypeClasses #-}++module Formal.Types.Definition where++import Text.InterpolatedString.Perl6+import Language.Javascript.JMacro++import Control.Applicative+import Control.Monad+import Data.Monoid++import Text.Parsec hiding ((<|>), State, many, spaces, parse, label)+import qualified Text.Parsec as P+import Text.Parsec.Indent hiding (same)++import Formal.Parser.Utils+import Formal.Javascript.Utils+import Formal.Javascript.Backend++import Formal.Types.Type+import Formal.Types.Symbol+import Formal.Types.Pattern+import Formal.Types.Axiom+import Formal.Types.Expression++import Prelude hiding (curry, (++))++++-- Definition+-- --------------------------------------------------------------------------------++data Visibility = Public | Private+++data Definition = Definition Visibility Bool Symbol [Axiom (Expression Definition)]++instance Show Definition where+ show (Definition Public _ name ax) =[qq|$name {sep_with "\\n" ax}|]+ show (Definition Private _ name ax) =[qq|private $name {sep_with "\\n" ax}|]++instance Syntax Definition where++ syntax = do whitespace+ vis <- option Public (try (string "private" >> spaces >> return Private))+ inl <- option False (try (string "inline" >> spaces >> return True))+ (x, y) <- try prefix <|> try infix''+ return $ Definition vis inl x y++ where infix'' =++ do whitespace+ first_arg <- try syntax+ whitespace+ op <- not_reserved $ many1 operator+ whitespace+ Match pss cond <- syntax+ ax <- no_args_eq_axiom $ Match (first_arg:pss) cond+ axs <- try (prefix' $ Operator op) <|> return []+ return (Operator op, ax:axs)++ where no_args_eq_axiom patterns =++ do whitespace *> string "=" *> spaces *> indented+ ex <- withPos (addr syntax)+ return $ EqualityAxiom patterns ex++ prefix = ++ do name <- try syntax <|> (Symbol <$> many1 (char '_'))+ y <- prefix' name+ return (name, y)+ + prefix' name =++ do sig <- first+ eqs <- (try $ spaces *> (withPos . many . try $ try infix_axiom <|> eq_axiom)) <|> return []+ whitespace+ if length sig == 0 && length eqs == 0 + then parserFail "Definition Axioms"+ else return (sig ++ eqs)++ where first = try type_or_first+ <|> ((:[]) <$> try naked_eq_axiom)+ <|> ((:[]) <$> (whitespace *> infix_axiom))+ <|> return []++ type_or_first = (:) <$> type_axiom <*> second++ second = option [] ((:[]) <$> try (no_args_eq_axiom (Match [] Nothing)))++ eq_axiom =++ do try (spaces >> same) <|> (whitespace >> return ())+ string "|" <|> try (string name' <* notFollowedBy (digit <|> letter)) + naked_eq_axiom++ where name' = case name of+ (Symbol name'') -> name''+ (Operator name'') -> "(" ++ name'' ++ ")"++ naked_eq_axiom =++ do whitespace+ patterns <- syntax+ no_args_eq_axiom patterns++ no_args_eq_axiom patterns =++ do P.spaces *> string "=" *> spaces *> indented+ ex <- withPos (addr syntax)+ return $ EqualityAxiom patterns ex++ infix_axiom =+ + case name of+ (Symbol _) -> parserFail "Infix Definition"+ (Operator name'') -> do first_arg <- syntax+ whitespace+ string name''+ whitespace+ Match pss cond <- syntax+ no_args_eq_axiom $ Match (first_arg:pss) cond ++ type_axiom =++ do spaces+ indented+ string ":"+ spaces+ indented+ TypeAxiom <$> withPos type_axiom_signature++-- TODO Visibility should be more than skin deep?++instance Javascript Definition JStat where+ toJS (Definition _ _ _ (TypeAxiom _: [])) = return mempty+ toJS (Definition _ _ name as) = return [jmacro| `(declare_this (to_name name) $ toJExpr as)`; |]++instance ToLocalStat Definition where+ toLocal (Definition _ _ _ (TypeAxiom _: [])) = mempty+ toLocal (Definition _ _ name as) = [jmacro| `(declare (to_name name) $ toJExpr as)`; |]
+ src/hs/Formal/Types/Expression.hs view
@@ -0,0 +1,531 @@+{-# LANGUAGE QuasiQuotes #-}+{-# LANGUAGE NamedFieldPuns #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE ViewPatterns #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE QuasiQuotes #-}+{-# LANGUAGE OverlappingInstances #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE ScopedTypeVariables #-}++module Formal.Types.Expression where++import Text.InterpolatedString.Perl6+import Language.Javascript.JMacro++import Control.Applicative+import Control.Monad+import Control.Monad.State hiding (lift)++import Text.Parsec hiding ((<|>), State, many, spaces, parse, label)+import Text.Parsec.Indent hiding (same)+import Text.Parsec.Expr++import qualified Text.Parsec as P+import qualified Data.Map as M+import qualified Data.List as L++import Formal.Parser.Utils+import Formal.Javascript.Utils++import Formal.Types.Literal+import Formal.Types.Type+import Formal.Types.Symbol+import Formal.Types.Pattern+import Formal.Types.Axiom++import Data.String.Utils hiding (join)+import Data.Monoid++import Prelude hiding (curry, (++))++++-- Expression+-- --------------------------------------------------------------------------------++class ToLocalStat a where+ toLocal :: a -> JStat++data Lazy = Once | Every++data Expression d = ApplyExpression (Expression d) [Expression d]+ | IfExpression (Expression d) (Expression d) (Expression d)+ | LiteralExpression Literal+ | SymbolExpression Symbol+ | JSExpression JExpr+ | LazyExpression (Addr (Expression d)) Lazy+ | FunctionExpression [Axiom (Expression d)]+ | RecordExpression (M.Map Symbol (Expression d))+ | InheritExpression (Expression d) (M.Map Symbol (Expression d))+ | LetExpression [d] (Expression d)+ | ListExpression [Expression d]+ | AccessorExpression (Addr (Expression d)) [Symbol]++instance (Show d) => Show (Expression d) where++ show (ApplyExpression x @ (SymbolExpression (show -> f : _)) y) + | f `elem` "abcdefghijklmnopqrstuvwxyz" = [qq|$x {sep_with " " y}|]+ | length y == 2 = [qq|{y !! 0} $x {y !! 1}|]++ show (ApplyExpression x y) = [qq|$x {sep_with " " y}|]+ show (IfExpression a b c) = [qq|if $a then $b else $c|]+ show (LiteralExpression x) = show x+ show (SymbolExpression x) = show x+ show (ListExpression x) = [qq|[ {sep_with ", " x} ]|]+ show (FunctionExpression as) = replace "\n |" "\n |" $ [qq|(λ{sep_with "| " as})|]+ show (JSExpression x) = "`" ++ show (renderJs x) ++ "`"+ show (LazyExpression x Once) = "lazy " ++ show x+ show (LazyExpression x Every) = "do " ++ show x+ show (LetExpression ax e) = replace "\n |" "\n |" $ [qq|let {sep_with "\\n| " ax} in ($e)|]+ show (RecordExpression m) = [qq|\{ {unsep_with " = " m} \}|] + show (InheritExpression x m) = [qq|\{ $x with {unsep_with " = " m} \}|] + show (AccessorExpression x m) = [qq|$x.{sep_with "." m}|] +++instance (Syntax d, Show d) => Syntax (Expression d) where++ syntax = try if' <|> try infix' <|> other++ where other = try let'+ <|> try do'+ <|> try yield+ <|> try lazy+ <|> other_next++ other_next =++ try apply+ <|> function+ <|> try accessor+ <|> inner++ inner = try accessor <|> inner_no_accessor+ + inner_no_accessor =+ indentPairs "(" syntax ")" + <|> js + <|> try record + <|> named_key+ <|> literal+ <|> symbol+ <|> try array+ <|> list++ let' = withPosTemp $ do string "var" <|> string "let"+ whitespace1+ defs <- withPos def+ spaces+ try (do string "in"+ spaces+ LetExpression <$> return defs <*> syntax)+ <|> do same+ LetExpression <$> return defs <*> syntax++ where def = try syntax `sepBy1` (try comma <|> try (spaces *> same))++ do' = do s <- getPosition+ string "do"+ i <- try (string "!") <|> return ""+ P.spaces+ l <- withPos line+ if i == "!" + then return$ ApplyExpression (SymbolExpression (Symbol "run")) [wrap s l]+ else return$ wrap s l++ where line = try bind <|> try let_bind <|> try return'++ wrap s x = LazyExpression (Addr s s (ApplyExpression (SymbolExpression (Symbol "run")) [x])) Every++ bind = do p <- syntax+ whitespace <* (string "<-" <|> string "←") <* whitespace + ex <- withPos syntax + spaces *> same+ f ex p <$> addr line++ let_bind = withPosTemp $ do string "let"+ whitespace1+ defs <- withPos def+ spaces+ same+ LetExpression <$> return defs <*> line++ where def = try syntax `sepBy1` try (spaces *> same)++ return' = do v <- syntax+ option v $ try $ unit_bind v++ unit_bind v = do spaces *> same+ f v AnyPattern <$> addr line++ f ex pat zx = ApplyExpression + (SymbolExpression (Operator ">>="))+ [ ex, (FunctionExpression + [ EqualityAxiom + (Match [pat] Nothing)+ zx ]) ]++ lazy = do string "lazy"+ whitespace1+ LazyExpression <$> withPos (addr$ try syntax) <*> return Once++ yield = do string "yield"+ whitespace1+ LazyExpression <$> withPos (addr$ try syntax) <*> return Every++ if' = withPos $ do string "if"+ whitespace1+ e <- withPos$ try infix' <|> other+ spaces+ try (jStyle e) <|> hStyle e++ where jStyle e = do indented+ cont e++ hStyle e = do string "then" + whitespace1+ cont e++ cont e = do t <- withPos$ try infix' <|> other+ P.spaces+ string "else"+ whitespace1+ IfExpression e t <$> withPos (try infix' <|> other) ++ infix' = buildExpressionParser table term ++ where table = [ [ix "^"]+ , [ix "*", ix "/"]+ , [px "-", px "!" ]+ , [ix "+", ix "-"]+ , [ Infix user_op_right AssocRight, Infix user_op_left AssocLeft ]+ , [ix "<", ix "<=", ix ">=", ix ">", ix "==", ix "!=", ix "is", ix "isnt"]+ , [ix "&&", ix "||", ix "and", ix "or" ] ]++ ix s = Infix (try . op $ (unwind <$> string s) <* notFollowedBy operator) AssocLeft+ + unwind "and" = Operator "&&"+ unwind "or" = Operator "||"+ unwind "is" = Operator "=="+ unwind "isnt" = Operator "!="+ unwind x = Operator x++ px s = Prefix (try neg)+ where neg = do spaces+ op <- SymbolExpression . Operator <$> string s+ spaces+ return (\x -> ApplyExpression op [x])+ + term = try other+ + user_op_left = try $ do spaces+ op' <- not_system (many1 operator) + spaces+ return $ f op'++ user_op_right = try $ do spaces+ op' @ (end -> x : _) <- g operator+ spaces+ if x == ':'+ then return $ f op'+ else parserFail "Operator"++ f op' x y = ApplyExpression (SymbolExpression (Operator op')) [x, y]++ g = not_system . many1++ op p = do spaces+ op' <- SymbolExpression <$> p+ spaces+ + return (\x y -> ApplyExpression op' [x, y])++ named_key = do x <- indentPairs "{" syntax "}"+ return $ RecordExpression (M.fromList [(x, SymbolExpression (Symbol "true"))]) ++ accessor = do s <- getPosition+ x <- indentPairs "(" syntax ")"+ <|> js + <|> record + <|> literal+ <|> try java_apply+ <|> try symbol+ <|> list+ + f <- getPosition+ string "."+ z <- syntax `sepBy1` string "."+ return $ acc_exp (Addr s f) x z++ acc_exp f x z = AccessorExpression (f x) z++ java_apply = ApplyExpression <$> inner_no_accessor <*> try java++ where java = indentPairs "(" java_args ")"+ where java_args = do x <- syntax `sepEndBy1` comma+ option x ((x ++) <$> try java)++ apply = ApplyExpression <$> inner <*> arguments++ where arguments = try java <|> try cont <|> halt++ where cont = do x <- whitespace *> (try (ApplyExpression <$> inner <*> java) <|> inner)+ option [x] ((x:) <$> try (whitespace *> (try cont <|> halt)))++ halt = (:[]) <$> (whitespace *> (try let'+ <|> try do'+ <|> try lazy+ <|> try yield+ <|> function))++ java = indentPairs "(" java_args ")"+ where java_args = do x <- syntax `sepEndBy1` comma+ option x ((x ++) <$> try arguments)++ -- No idea why this is necessary?+ withPosTemp :: Parser a -> Parser a+ withPosTemp p = do x <- get+ z <- try (Just <$> p) <|> return Nothing+ put x+ case z of+ Just z -> return z+ Nothing -> parserFail ("expression continuation indented to " ++ show x)++ function = withPosTemp$ withPos $ do try (char '\\') <|> char 'λ'+ whitespace+ pat_fun++ where pat_fun = do t <- option [] ( ((:[]) <$> type_axiom <* spaces))+ eqs <- try eq_axiom `sepBy1` try (spaces *> string "|" <* whitespace)+ return $ FunctionExpression (t ++ eqs)++ type_axiom = do string ":"+ spaces+ indented+ TypeAxiom <$> withPos type_axiom_signature++ eq_axiom = do patterns <- syntax+ string "="+ spaces+ indented+ ex <- withPosTemp $ withPos (addr syntax)+ return $ EqualityAxiom patterns ex++ js = g <$> indentPairs "`" (many $ noneOf "`") "`"+ where p (parseJM . wrap -> Right (BlockStat [AssignStat _ x])) =+ [jmacroE| (function() { return `(x)`; }) |]+ p (parseJM . (++";") -> Right z) = [jmacroE| (function() { `(z)`; }) |]+ p (parseJM . concat . L.intersperse ";" . h . split ";" -> Right x) = + [jmacroE| (function() { `(x)`; }) |]+ p _ = error "\n\nJavascript parsing failed"+ + g x | last x == '!' = ApplyExpression (SymbolExpression (Symbol "run"))+ [JSExpression (p (take (length x - 1) x))]+ | otherwise = JSExpression$ p x++ h [] = []+ h (x:[]) = ["return " ++ x]+ h (x:xs) = x : h xs+ + wrap x = "__ans__ = " ++ x ++ ";"++ record = indentPairs "{" (try inherit <|> (RecordExpression . M.fromList <$> pairs')) "}"+ + where pairs' = withPos $ (try key_eq_val <|> try function') + `sepBy` optional_sep++ function' = do n <- syntax + whitespace+ eqs <- try eq_axiom `sepBy1` try (spaces *> string "|" <* whitespace)+ return $ (n, FunctionExpression eqs)++ eq_axiom = do patterns <- syntax+ string "="+ spaces+ indented+ ex <- withPos (addr syntax)+ return $ EqualityAxiom patterns ex++ inherit = do ex <- syntax+ spaces *> indented+ string "with"+ spaces *> indented+ ps <- pairs'+ return $ InheritExpression ex (M.fromList ps)++ key_eq_val = do key <- syntax+ whitespace+ string "=" <|> string ":"+ spaces+ value <- withPos syntax+ return (key, value)++ literal = do (sourceColumn -> x) <- getPosition+ undo x <$> syntax++ strip_indent x y = let splitted = split "\n" y+ r x' | strip (take x x') == "" = drop x x'+ | otherwise = error$ "Badly formatted string \"" ++ show splitted ++ "\""+ in if length splitted > 1 + then head splitted ++ "\n" ++ (concat . L.intersperse "\n" . fmap r . tail $ splitted)+ else y++ undo z (StringLiteral x) = to_escaped . split "`" . strip_indent z $ x+ undo _ l = LiteralExpression l++ to_escaped (x:s:xs) =+ ApplyExpression (SymbolExpression$ Operator "+++") + [ ApplyExpression (SymbolExpression$ Operator "+++") + [LiteralExpression $ StringLiteral x+ , p s ]+ , to_escaped xs ]+ to_escaped (l:[]) = LiteralExpression $ StringLiteral l+ to_escaped [] = LiteralExpression $ StringLiteral ""++ p s = case parse syntax "Escaped String" s of+ Left x -> error$ show x+ Right x -> x++ symbol = SymbolExpression <$> syntax++ list = ListExpression <$> indentPairs "[" v "]"+ where v = do whitespace+ withPos (syntax `sepBy` optional_sep)++ array = f <$> indentAsymmetricPairs "[:" v (try (string ":]") <|> string "]")++ where v = do whitespace+ withPos (syntax `sepBy` optional_sep)++ f [] = RecordExpression (M.fromList [(Symbol "nil", SymbolExpression (Symbol "true"))])+ f (x:xs) = RecordExpression (M.fromList [(Symbol "head", x), (Symbol "tail", f xs)])++class Opt a where+ opt :: a -> a++instance (Opt a, Opt b) => Opt (a, b) where+ opt (a, b) = (opt a, opt b)++instance (Opt a) => Opt [a] where+ opt x = map opt x++instance (Functor m, Opt a) => Opt (m a) where+ opt x = fmap opt x++instance Opt JStat where+ opt (ReturnStat x) = ReturnStat (opt x)+ opt (IfStat a b c) = IfStat (opt a) (opt b) (opt c)+ opt (WhileStat a b) = WhileStat (opt a) (opt b)+ opt (ForInStat a b c d) = ForInStat a b (opt c) (opt d)+ opt (SwitchStat a b c) = SwitchStat (opt a) (opt b) (opt c)+ opt (TryStat a b c d) = TryStat (opt a) b (opt c) (opt d)+ opt (BlockStat xs) = BlockStat (opt xs)+ opt (ApplStat a b) = ApplStat (opt a) (opt b)+ opt (PPostStat a b c) = PPostStat a b (opt c)+ opt (AssignStat a b) = AssignStat (opt a) (opt b)+ opt (UnsatBlock a) = UnsatBlock (opt a)++ opt x = x++ -- opt (DeclStat Ident (Maybe JLocalType)+ -- opt (UnsatBlock (IdentSupply JStat)+ -- opt (AntiStat String+ -- opt (ForeignStat Ident JLocalType+ -- opt (BreakStat+++instance Opt JVal where+ opt (JList xs) = JList (opt xs)+ opt (JHash m) = JHash (M.map opt m)+ opt (JFunc xs x) = JFunc xs (opt x)+ opt (UnsatVal x) = UnsatVal (opt x)++ opt x = x++ -- opt x@(JVar _) = x+ -- opt x@(JDouble _) = x+ -- opt x@(JInt _) = x+ -- opt x@(JStr _) = x+ -- opt x@(JRegEx _) = x++instance Opt JExpr where+ opt (SelExpr e (StrI i)) = IdxExpr (opt e) (ValExpr (JStr i)) -- Closure fix - advanced mode nukes these+ opt (IdxExpr a b) = IdxExpr (opt a) (opt b)+ opt (InfixExpr a b c) = InfixExpr a (opt b) (opt c)+ opt (PPostExpr a b c) = PPostExpr a b (opt c)+ opt (IfExpr a b c) = IfExpr (opt a) (opt b) (opt c)+ opt (NewExpr a) = NewExpr (opt a)+ opt (ApplExpr a b) = ApplExpr (opt a) (map opt b)+ opt (TypeExpr a b c) = TypeExpr a (opt b) c+ opt (ValExpr a) = ValExpr (opt a)+ opt (UnsatExpr a) = UnsatExpr (opt a)++instance (Show d, ToLocalStat d) => ToJExpr (Expression d) where++-- toJExpr (ApplyExpression (SymbolExpression (Symbol "run")) [x]) = [jmacroE| `(x)`() |]++ toJExpr (ApplyExpression (SymbolExpression f @ (Operator _)) [x, y]) = + toJExpr (ApplyExpression (SymbolExpression (Symbol (to_name f))) [x,y])++ toJExpr (ApplyExpression (SymbolExpression (Operator _)) x) =+ error $ "Operator with " ++ show (length x) ++ " params"++ toJExpr (ApplyExpression (SymbolExpression f) []) = ref (to_name f)+ toJExpr (ApplyExpression f []) = [jmacroE| `(f)` |]+ toJExpr (ApplyExpression f (end -> x : xs)) = [jmacroE| `(ApplyExpression f xs)`(`(x)`) |]++ toJExpr (AccessorExpression (Addr _ _ x) []) =++ toJExpr x++ toJExpr (AccessorExpression x (reverse -> y:ys)) =++ [jmacroE| `(AccessorExpression x (reverse ys))`[`(to_name y)`] |]++ toJExpr (ListExpression x) = toJExpr x+ toJExpr (LiteralExpression l) = toJExpr l+ toJExpr (SymbolExpression x) = ref (to_name x)+ toJExpr (FunctionExpression x) = toJExpr x+ toJExpr (LazyExpression x Every) =++ toJExpr (FunctionExpression + [ EqualityAxiom + (Match [AnyPattern] Nothing)+ x ])++ toJExpr (LazyExpression (Addr _ _ x) Once) =++ [jmacroE| (function() {+ var y = undefined;+ return function() {+ if (y) {+ return y;+ } else {+ y = `(x)`;+ return y;+ }+ }+ })() |]++ toJExpr (RecordExpression m) = toJExpr (M.mapKeys to_name m)+ toJExpr (JSExpression s) = opt s+ toJExpr (LetExpression bs ex) =++ [jmacroE| (function() { `(foldl1 mappend $ map toLocal bs)`; return `(ex)` })() |]++ toJExpr (IfExpression x y z) =++ [jmacroE| (function(){ + if (`(x)`) { + return `(y)`;+ } else { + return `(z)` + }+ })() |] ++ toJExpr x = error $ "Unimplemented " ++ show x++
+ src/hs/Formal/Types/Literal.hs view
@@ -0,0 +1,37 @@+{-# LANGUAGE MultiParamTypeClasses #-}++module Formal.Types.Literal where++import Language.Javascript.JMacro++import Control.Applicative+import Text.Parsec hiding ((<|>), State, many, spaces, parse, label)++import Formal.Parser.Utils+import Formal.TypeCheck.Types++data Literal = StringLiteral String | IntLiteral Int | DoubleLiteral Double++instance Show Literal where+ show (StringLiteral x) = show x+ show (IntLiteral x) = show x+ show (DoubleLiteral x) = show x++instance Syntax Literal where++ syntax = try flt <|> try num <|> try str++ where flt = DoubleLiteral <$> syntax + num = IntLiteral <$> syntax+ str = StringLiteral <$> syntax++instance ToJExpr Literal where+ toJExpr (StringLiteral s) = toJExpr s+ toJExpr (IntLiteral s) = toJExpr s+ toJExpr (DoubleLiteral s) = toJExpr s++instance Infer Literal Type where+ infer (StringLiteral _) = return (Type (TypeConst "String" Star))+ infer (IntLiteral _) = return (Type (TypeConst "Num" Star))+ infer (DoubleLiteral _) = return (Type (TypeConst "Double" Star))+
+ src/hs/Formal/Types/Namespace.hs view
@@ -0,0 +1,54 @@+{-# LANGUAGE QuasiQuotes #-}+{-# LANGUAGE NamedFieldPuns #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE ViewPatterns #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE QuasiQuotes #-}+{-# LANGUAGE OverlappingInstances #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE TypeSynonymInstances #-}+{-# LANGUAGE FlexibleInstances #-}++module Formal.Types.Namespace where++import Language.Javascript.JMacro++import Control.Applicative++import Text.Parsec hiding ((<|>), State, many, spaces, parse, label)+import Data.Monoid+import qualified Data.List as L++import Formal.Parser.Utils+import Formal.Javascript.Utils++import Prelude hiding (curry, (++))++newtype Namespace = Namespace [String] deriving (Eq)++instance Monoid Namespace where+ mempty = Namespace []+ mappend (Namespace x) (Namespace y) = Namespace (x ++ y)++instance Show Namespace where+ show (Namespace []) = "global"+ show (Namespace x) = concat $ L.intersperse "." x++instance Syntax Namespace where+ syntax = Namespace <$> (many1 lower `sepBy1` char '.')++instance ToJExpr Namespace where+ toJExpr (Namespace []) = ref "this"+ toJExpr (Namespace (end -> x : xs)) = [jmacroE| `(Namespace xs)`[`(x)`] |]+++++data Module = Module Namespace [Module]+ | Var String++instance Show Module where+ show (Module (Namespace (reverse -> (x:_))) _) = x+ show (Var s) = s+
+ src/hs/Formal/Types/Pattern.hs view
@@ -0,0 +1,256 @@+{-# LANGUAGE QuasiQuotes #-}+{-# LANGUAGE NamedFieldPuns #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE ViewPatterns #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE QuasiQuotes #-}+{-# LANGUAGE OverlappingInstances #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE ScopedTypeVariables, MultiParamTypeClasses #-}++module Formal.Types.Pattern where++import Text.InterpolatedString.Perl6+import Data.Maybe+import Language.Javascript.JMacro++import Control.Applicative+import Control.Monad++import Text.Parsec hiding ((<|>), State, many, spaces, parse, label)+import qualified Text.Parsec as P+import qualified Data.List as L+import Text.Parsec.Indent hiding (same)++import qualified Data.Map as M++import Formal.Parser.Utils+import Formal.Javascript.Utils++import Formal.Types.Literal+import Formal.Types.Type+import Formal.Types.Symbol+import Formal.TypeCheck.Types++import Prelude hiding (curry, (++))+import System.IO.Unsafe (unsafePerformIO)+import Data.Monoid (mappend)++++++-- Pattern+-- --------------------------------------------------------------------------------++data Match a = Match [Pattern a] (Maybe a)+data Pattern a = VarPattern String+ | AnyPattern+ | LiteralPattern Literal+ | RecordPattern (M.Map Symbol (Pattern a)) Partial+ | ListPattern [Pattern a]+ | ViewPattern a (Pattern a)+ | AliasPattern [Pattern a]+++instance (Show a) => Show (Match a) where+ show (Match p Nothing) = sep_with " " p+ show (Match p (Just x)) = [qq|{sep_with " " p} when $x|]++instance (Syntax a, Show a) => Syntax (Match a) where++ syntax = try conditional <|> ((\x -> Match x Nothing) <$> (try jStyle <|> hStyle))++ where ++ jStyle = do x <- indentPairs "(" (syntax `sepBy1` comma) ")"+ spaces+ if length x > 1 then return x else fail "Java-style arguments"++ hStyle = syntax `sepEndBy` whitespace1++ conditional = do x <- try jStyle <|> try hStyle+ string "when"+ spaces+ indented+ ex <- withPos syntax+ spaces+ indented+ return $ Match x (Just ex)++newtype Condition = Condition JExpr++instance ToJExpr [Condition] where+ toJExpr [] = toJExpr True+ toJExpr (Condition x : []) = [jmacroE| `(x)` |]+ toJExpr (Condition x : xs) = [jmacroE| `(x)` && `(xs)` |]++data PatternMatch a = PM String (Pattern a)++instance (Show a) => ToJExpr [PatternMatch a] where+ toJExpr [] = toJExpr True+ toJExpr (x:[]) = [jmacroE| `(x)` |]+ toJExpr (x:xs) = [jmacroE| `(x)` && `(xs)` |]++instance (Show a) => ToJExpr (PatternMatch a) where++ toJExpr (PM n (AliasPattern xs)) = toJExpr $ filter fil $ map (PM n) xs++ toJExpr (PM n (LiteralPattern x)) =++ [jmacroE| `(ref n)` === `(x)` |]++ toJExpr (PM n (RecordPattern (M.toList -> xs) _)) =++ [jmacroE| `(map g xs)` && `(filter fil $ map f xs)` |]+ where f (key, val) = PM (n ++ "[\"" ++ to_name key ++ "\"]") val+ g (key, _) = Condition [jmacroE| __check(`(ref n)`, `(to_name key)`) |]++ toJExpr (PM n (ListPattern [])) =+ [jmacroE| equals(`(n)`)([]) |]+ toJExpr (PM n (ListPattern xs)) = + let x = toJExpr (map f (zip [(0 :: Int) ..] xs))+ f (index, val) = toJExpr (PM (n ++ "[" ++ show index ++ "]") val)+ in [jmacroE| `(x)` && `(ref n)`.length == `(length xs)` |]+ toJExpr (PM _ x) = error $ "Unimplemented " ++ show x++data Partial = Partial | Complete deriving (Eq, Show)++instance (Show a) => Show (Pattern a) where+ show (VarPattern x) = x+ show AnyPattern = "_"+ show (LiteralPattern x) = show x+ show (ListPattern x) = [qq|[ {sep_with ", " x} ]|]+ show (ViewPattern x y) = [qq|($x -> $y)|]+ show (RecordPattern m Complete) = [qq|\{ {unsep_with " = " m} \}|] + show (RecordPattern m Partial) = [qq|\{ {unsep_with " = " m}, _ \}|]+ show (AliasPattern a) = sep_with " & " a++instance (Show a, ToJExpr a) => ToJExpr [Pattern a] where++ toJExpr ps = toJExpr$ filter fil $ zipWith PM (reverse . take (length ps) . map local_pool $ [0 .. 26]) ps+ +fil (PM _ (VarPattern _)) = False+fil (PM _ AnyPattern) = False+fil (PM _ (RecordPattern (M.toList -> []) Complete)) = False+fil _ = True++instance (Syntax a, Show a) => Syntax (Pattern a) where+ + syntax = try literal+ <|> try var+ <|> any'+ <|> try record+ <|> naked_apply+ <|> array+ <|> list+ <|> indentPairs "(" (try alias <|> syntax) ")"+ + where alias = let sep = P.spaces <* string "&" <* P.spaces+ in AliasPattern <$> ((:) <$> syntax <* sep <*> sepBy1 syntax sep) ++ var = VarPattern <$> type_var+ literal = LiteralPattern <$> syntax+ any' = many1 (string "_") *> return AnyPattern+ naked_apply =++ do x <- indentPairs "{" (many1 letter) "}"+ return $ RecordPattern (M.fromList [(Symbol x, AnyPattern )]) Complete++ record = indentPairs "{" any_record "}"+ ++ where pairs = (try key_eq_val <|> (many1 (char '_') >> return Nothing)) `sepEndBy` optional_sep++ any_record =+ + do ps <- pairs+ let ps' = catMaybes ps+ return $+ case (length ps, (not . isJust) `filter` ps) of+ (0, _) -> RecordPattern M.empty Complete+ (_, (Nothing:_)) -> RecordPattern (M.fromList ps') Partial+ _ -> RecordPattern (M.fromList ps') Complete++ key_eq_val = do key <- syntax+ spaces+ string "=" <|> string ":"+ spaces+ value <- syntax+ return$ Just (key, value)++ list = ListPattern <$> indentPairs "[" (syntax `sepBy` optional_sep) "]"++ array = f <$> indentAsymmetricPairs "[:" v (try (string ":]") <|> string "]")++ where v = do whitespace+ withPos (syntax `sepBy` optional_sep)++ f [] = RecordPattern (M.fromList [(Symbol "nil", AnyPattern)]) Complete+ f (x:xs) = RecordPattern (M.fromList [(Symbol "head", x), (Symbol "tail", f xs)]) Complete++++instance (Show b) => Infer (Pattern b) Type where++ infer (AliasPattern (x:[])) = infer x+ + infer (AliasPattern (x:xs)) = + do z <- infer x+ z' <- infer (AliasPattern xs)+ unify z z'+ return z'++ infer (VarPattern i) = do v <- newTVar Star+ assume (i :>: toScheme v)+ return v++ infer AnyPattern = newTVar Star++ infer (LiteralPattern x) = infer x++ infer (ListPattern xs) = do ts <- mapM infer xs+ t' <- newTVar Star+ (qs :=> t) <- freshInst list_scheme+ mapM_ (unify t') ts+ predicate qs+ return t++ infer (RecordPattern (unzip . M.toList -> (names, patterns)) p) =+ + do ts <- mapM infer patterns+ p' <- case p of+ Complete -> return TComplete+ Partial -> do t <- newTVar Star+ return$ TPartial t++ let r = TypeRecord (TRecord (M.fromList (zip (map f names) ts)) p' Star)+ t' <- newTVar Star+ sc <- find $ quantify (tv r) ([] :=> r)+ case sc of+ Nothing ->+ do unify t' r+ return t'+ Just (Forall _ scr, sct) ->+ do (_ :=> t'') <- freshInst sct+ (qs :=> t''') <- return$ inst (map TypeVar$ tv t'') scr+ (_ :=> t) <- freshInst (quantify (tv t''' L.\\ tv t'') (qs :=> t'''))+ unify t r+ unify t' t''+ s <- get_substitution+ let t''' = apply s t+ r''' = apply s r+ qt = quantify (tv t''') $ [] :=> t'''+ rt = quantify (tv r''') $ [] :=> r'''+ if qt /= rt+ then do add_error$ "Object constructor does not match signature\n" + ++ " Expected: " ++ show qt ++ "\n" + ++ " Actual: " ++ show rt+ return t'+ else return t'++ where f (Symbol x) = x+ f (Operator x) = x
+ src/hs/Formal/Types/Statement.hs view
@@ -0,0 +1,301 @@+{-# LANGUAGE QuasiQuotes #-}+{-# LANGUAGE NamedFieldPuns #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE ViewPatterns #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE QuasiQuotes #-}+{-# LANGUAGE OverlappingInstances #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE FunctionalDependencies #-}+{-# LANGUAGE TypeSynonymInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE UndecidableInstances, KindSignatures #-}++module Formal.Types.Statement where++import Text.InterpolatedString.Perl6++import Language.Javascript.JMacro++import Control.Applicative++import Text.Parsec hiding ((<|>), State, many, spaces, parse, label)+import Text.Parsec.Indent hiding (same)++import Data.String.Utils+import Data.Monoid+import qualified Data.List as L++import Formal.Parser.Utils++import Formal.Types.Type+import Formal.Types.Axiom+import Formal.Types.TypeDefinition+import Formal.Types.Symbol+import Formal.Types.Definition+import Formal.Types.Expression+import Formal.Types.Namespace++import Formal.Javascript.Utils+import Formal.Javascript.Backend++import Prelude hiding (curry, (++))+import System.IO.Unsafe (unsafePerformIO)++++--------------------------------------------------------------------------------+----+---- Statement++data Statement = TypeStatement TypeDefinition UnionType+ | DefinitionStatement Definition+ | ExpressionStatement (Addr (Expression Definition))+ | ImportStatement Namespace+ | ModuleStatement Namespace [Statement]++instance Show Statement where+ show (TypeStatement t c) = [qq|type $t = $c|]+ show (DefinitionStatement d) = show d+ show (ExpressionStatement (Addr _ _ x)) = show x+ show (ImportStatement x) = [qq|import $x|]+ show (ModuleStatement x xs) = replace "\n |" "\n |" + $ replace "\n\n" "\n\n " + $ "module " + ++ show x ++ "\n\n" ++ sep_with "\n\n" xs++instance Syntax Statement where++ syntax = whitespace >> withPos statement_types <* many newline++ where statement_types =++ (type_statement <?> "Type Definition")+ <|> (try import_statement <?> "Import Statement")+ <|> (module_statement <?> "Module Declaration")+ <|> (try def_statement <?> "Symbol Definition")+ <|> (expression_statement <?> "Assertion")++ def_statement = DefinitionStatement <$> syntax++ import_statement = do string "open"+ whitespace+ ImportStatement <$> syntax++ module_statement = do try (string "module")+ whitespace1+ name <- try syntax <|> (char '"' *> (Namespace . (:[]) <$> (anyChar `manyTill` char '"')))+ whitespace *> newline+ spaces *> (indented <|> same)+ ModuleStatement name <$> withPos (many1 ((spaces >> same >> syntax)))++ type_statement = do try (string "type" >> spaces) <|> return ()+ def <- syntax+ set_indentation (+1)+ whitespace+ sig <- try (string "=" >> spaces >> (string "|" >> type_definition_signature))+ <|> (string "=" >> spaces >> type_definition_signature)+ whitespace+ set_indentation (+(-1))+ return $ TypeStatement def sig++ expression_statement = do try (string "test" >> spaces) <|> return ()+ whitespace+ x <- getPosition + y <- withPos$ addr syntax+ z <- getPosition+ return $ ExpressionStatement y+ ++++--------------------------------------------------------------------------------+----+---- Meta++data Meta = Meta { target :: Target,+ namespace :: Namespace,+ modules :: [Module],+ expr :: Statement } deriving (Show)++data Target = Test | Library+ deriving (Show)++serial :: SourcePos -> SourcePos -> String+serial a b = show (sourceLine a - 1) ++ "_" ++ show (sourceLine b - 1) ++ (if sourceLine a /= sourceLine b then "multi" else "")++get_code :: forall a. Addr a -> JS String+get_code a = do src <- JS (\s @ JSState {src = src} -> (s, src))+ return $ get_error a src++instance Javascript Meta JStat where++ -- Expressions are ignored for Libraries, and rendered as tests for Test+ toJS (Meta { target = Library, expr = ExpressionStatement _ }) = return mempty+ toJS (Meta { target = Test, expr = ExpressionStatement a' @ (Addr a b e) }) = ++ do message <- get_code a'+ return [jmacro| it(`(serial a b ++ "__::__" ++ message)`, function() {+ `(Jasmine e)`;+ }); |]++ -- Imports work identically for both targets+ toJS (Meta { modules, + namespace = Namespace [], + expr = ImportStatement target_namespace @ (find modules -> Nothing) }) = ++ fail [qq| Could not resolve namespace $target_namespace |] ++ toJS (Meta { modules, + expr = ImportStatement target_namespace, + namespace = (find modules . (++ target_namespace) -> Just y) }) =++ return $ open target_namespace y++ toJS meta @ (Meta { expr = ImportStatement _, .. }) = ++ let slice (Namespace ns) = Namespace . take (length ns - 1) $ ns+ in toJS (meta { namespace = slice namespace })++++ -- Modules in test mode must open the contents of the Library++ toJS meta @ (Meta { target = Library, namespace = Namespace [], expr = ModuleStatement ns xs, .. }) =+ + do xs' <- toJS $ fmap (\z -> meta { namespace = ns, expr = z }) xs+ return $ declare_window (show ns)+ [jmacroE| new (function() { + `(xs')`;+ }) |]++ toJS meta @ (Meta { target = Library, expr = ModuleStatement ns xs, .. }) =+ + do xs' <- toJS $ fmap (\z -> meta { namespace = namespace ++ ns, expr = z }) xs+ return $ declare_this (show ns)+ [jmacroE| new (function() { + `(xs')`;+ }) |]+++ toJS meta @ (Meta { target = Test, expr = ModuleStatement ns xs, .. }) =++ let (imports, rest) = L.partition f xs+ f (ImportStatement _) = True+ f _ = False in++ do imports' <- toJS $ map (\z -> meta { namespace = namespace ++ ns, expr = z }) imports+ rest' <- toJS $ map (\z -> meta { namespace = namespace ++ ns, expr = z }) rest++ return [jmacro| describe(`(show ns)`, function() {+ `(open (namespace ++ ns) xs)`;+ `(imports')`; + `(open (namespace ++ ns) xs)`;+ + var x = new (function {+ `(rest')`; + }());+ }); |]++++ -- Definitions are ignored for the Test target++ toJS (Meta { target = Library, expr = DefinitionStatement d }) = toJS d+ toJS (Meta { target = Test, expr = DefinitionStatement _ }) = return mempty++ toJS (Meta { expr = TypeStatement _ _ }) = return mempty+ -- toJS x = fail $ "Unimplemented " ++ show x++++empty_meta :: Target -> [Statement] -> Statement -> Meta+empty_meta x = Meta x (Namespace []) . build_modules++ where build_modules (ModuleStatement n ns : xs) = Module n (build_modules ns) : build_modules xs+ build_modules (DefinitionStatement (Definition _ _ n _): xs) = Var (to_name n) : build_modules xs+ build_modules (_ : xs) = build_modules xs+ build_modules [] = []++find :: [Module] -> Namespace -> Maybe [String]+find (Var s : ss) n @ (Namespace []) = Just [s] ++ find ss n+find (Var _: xs) ns = find xs ns+find [] (Namespace []) = Just []+find [] _ = Nothing++find (Module _ xs : ms) n @ (Namespace []) = Just (map show xs) ++ find ms n+find (Module (Namespace ys) x : zs) n @ (Namespace xs)+ | length xs >= length ys && take (length ys) xs == ys = + find x (Namespace $ drop (length ys) xs)+ | otherwise = find zs n++++--------------------------------------------------------------------------------+----+---- Open++class Open a where open :: Namespace -> [a] -> JStat++instance Open Statement where+ open _ [] = mempty+ open ns (DefinitionStatement (Definition _ _ _ (TypeAxiom _: [])) : xs) = open ns xs+ open ns (DefinitionStatement (Definition _ _ n _) : xs) =++ let f = ref . replace " " "_" . show+ x = [jmacroE| `(f ns)`[`(n)`] |] in++ [jmacro| `(declare (replace " " "_" $ to_name n) x)`;+ `(open ns xs)`; |]++ open nss (ModuleStatement ns @ (Namespace (n:_)) _:xs) =++ [jmacro| `(declare n (ref . replace " " "_" . show $ nss ++ ns))`;+ `(open nss xs)`; |]++ open ns (_ : xs) = open ns xs++instance Open String where+ open _ [] = mempty+ open (Namespace (map (replace " " "_") -> ns)) (x:xs) =++ let print' [] = error "Empty Namespace"+ print' (y:[]) = [jmacroE| `(ref y)` |]+ print' (y:ys) = [jmacroE| `(print' ys)`[`(y)`] |]++ in declare x [jmacroE| `(print' $ reverse ns)`[`(x)`] || window[`(x)`] |] ++ open (Namespace ns) xs+++++--------------------------------------------------------------------------------+----+---- Jasmine++newtype Jasmine = Jasmine (Expression Definition)++instance ToStat Jasmine where++ toStat (Jasmine (ApplyExpression (SymbolExpression (Operator "==")) [x, y])) =++ [jmacro| expect(`(x)`).toEqual(`(y)`); |]++ toStat (Jasmine (ApplyExpression (SymbolExpression (Operator "!=")) [x, y])) =++ [jmacro| expect(`(x)`).toNotEqual(`(y)`); |]+ + toStat (Jasmine e) = ++ [jmacro| expect((function() {+ try {+ return `(e)`;+ } catch (ex) {+ return { error: ex };+ }+ })()).toEqual(true); |]++
+ src/hs/Formal/Types/Symbol.hs view
@@ -0,0 +1,35 @@++module Formal.Types.Symbol where++import Language.Javascript.JMacro++import Control.Applicative+import Text.Parsec hiding ((<|>), State, many, spaces, parse, label)+import qualified Data.Map as M+import Formal.Parser.Utils+import Data.String.Utils++data Symbol = Symbol String+ | Operator String+ deriving (Ord, Eq)++instance Show Symbol where+ show (Symbol s) = s+ show (Operator x) = x++instance Syntax Symbol where+ syntax = (Symbol <$> not_reserved (oneOf "abscdefghijklmnopqrstuvwxyz" <:> many (alphaNum <|> oneOf "_'!$" <|> (string "?" >> return '_'))))+ <|> (Operator <$> not_reserved imp_infix)+ where imp_infix = string "(" *> many1 operator <* option "" (try (string ":")) <* string ")"++instance ToJExpr Symbol where+ toJExpr = toJExpr . to_name++to_name :: Symbol -> String+to_name (Symbol "return") = "_return_"+to_name (Symbol "new") = "_new_"+++to_name (Symbol x) = replace "!" "_excl" $ replace " " "_" $ replace "'" "_apos" x+to_name (Operator op) = concat . map (\x -> M.findWithDefault "_" x operator_dict) $ op+
+ src/hs/Formal/Types/Type.hs view
@@ -0,0 +1,171 @@+{-# LANGUAGE FlexibleContexts, NamedFieldPuns, OverlappingInstances,+ QuasiQuotes, RankNTypes, RecordWildCards, TemplateHaskell,+ ViewPatterns #-}++module Formal.Types.Type where++import Control.Applicative+import Text.InterpolatedString.Perl6++import Text.Parsec hiding (State, label, many, parse, spaces, (<|>))+import Text.Parsec.Indent hiding (same)++import qualified Data.Map as M+import qualified Data.Set as S++import Formal.Parser.Utils++import Formal.Types.Symbol+++data UnionType = UnionType (S.Set ComplexType)+ deriving (Ord, Eq)++data ComplexType = RecordType (M.Map Symbol UnionType)+ | InheritType SimpleType (M.Map Symbol UnionType)+ | FunctionType UnionType UnionType+ | SimpleType SimpleType+ deriving (Eq, Ord)++data SimpleType = PolymorphicType SimpleType [UnionType]+ | SymbolType Symbol+ | VariableType String+ deriving (Ord, Eq)++instance Show UnionType where+ show (UnionType xs) = [qq|{sep_with " | " $ S.toList xs}|]++instance Show ComplexType where+ show (SimpleType y) = [qq|$y|]+ show (InheritType n m) = [qq|\{ $n with {unsep_with ": " m} \}|]+ show (RecordType m) = [qq|\{ {unsep_with ": " m} \}|]++ show (FunctionType g @ (UnionType (S.toList -> ((FunctionType _ _):[]))) h) =+ [qq|($g -> $h)|]++ show (FunctionType g h) = [qq|$g -> $h|]++instance Show SimpleType where+ show (PolymorphicType x y) = [qq|($x {sep_with " " y})|]+ show (SymbolType x) = show x+ show (VariableType x) = x++++-- Type Signatures+-- -----------------------------------------------------------------------------+-- TODO ! (IO type)+-- TODO type axioms need nominative types?+-- ? TODO List, Map, Set shorthand?++-- The type algebra of Sonnet is broken into 3 types to preserve the+-- associativity of UnionTypes: (x | y) | z == x | y | z++++-- Where a type signature may be used in Sonnet had two slightly different parsers+-- in order to allow for somewhat overloaded surrounding characters (eg "|" - when+-- declaring the type of an axiom, one must be careful to disambiguate UnionTypes+-- and sets of EqualityAxioms). However, these types are otherwise equivalent,+-- and any type that may be declared in a TypeDefinition may also be the explicit+-- type of a Definition (Note, however, that in the case of NamedTypes, the+-- names introduced into scope will be inaccessible in the case of a Definition).+++type_axiom_signature :: Parser UnionType+type_definition_signature :: Parser UnionType++type_axiom_signature = do option "" (string "|" <* whitespace)+ t <- (u $ try function_type) <|> try nested_union_type <|> u inner_type+ whitespace+ return t++ where u = (<$>) $ UnionType . S.fromList . (:[])++type_definition_signature = UnionType . S.fromList <$> types <* whitespace+ where types = (try function_type <|> inner_type) `sepBy1` type_sep+++-- Through various complexities of the recursive structure of these types, we will+-- need a few mutually recursive parsers to express these slightly different+-- signature parsers.++inner_type :: Parser ComplexType+nested_function :: Parser ComplexType+nested_union_type :: Parser UnionType++inner_type = nested_function+ <|> try record_type+ <|> try named_type+ <|> try poly_type+ <|> var_type+ <|> symbol_type++nested_function = indentPairs "(" (try function_type <|> inner_type) ")"+nested_union_type = indentPairs "(" type_definition_signature ")"+++-- Now that we've expressed the possible parses of a UnionType, we can move on to+-- parsing the ComplexType and SimpleType layers. While these are also mutually+-- recursive, the recursion is uniform, as the various allowable combinations+-- have already been defined above.++function_type :: Parser ComplexType+poly_type :: Parser ComplexType+record_type :: Parser ComplexType+named_type :: Parser ComplexType+symbol_type :: Parser ComplexType+var_type :: Parser ComplexType++function_type = do x <- try nested_union_type <|> unionize inner_type+ spaces+ string "->" <|> string "→"+ spaces+ y <- (unionize $ try function_type) <|> try nested_union_type <|> unionize inner_type+ return $ FunctionType x y++poly_type = do name <- (SymbolType <$> type_name) <|> (VariableType <$> try type_var)+ whitespace+ SimpleType . PolymorphicType name <$> (j_style <|> h_style)++ where rvs = record_type <|> var_type <|> symbol_type+ h_style = (try nested_union_type <|> unionize (try rvs)) `sepEndBy1` whitespace+ j_style = indentPairs "<" ((try nested_union_type <|> unionize (try rvs)) `sepBy1` optional_sep) ">"++record_type = let key_value = (,) <$> syntax <* div' <*> type_definition_signature+ div' = spaces <* string ":" <* spaces+ pairs = key_value `sepEndBy` optional_sep+ inner = RecordType . M.fromList <$> pairs+ inherit = do SimpleType n <- try poly_type <|> try symbol_type <|> var_type+ spaces+ indented+ string "with"+ spaces *> indented+ InheritType n . M.fromList <$> pairs++ in indentPairs "{" (try inherit <|> inner) "}"++named_type = do x <- indentPairs "{" name "}"++-- named_type = do x <- name+-- y <- option bool (try nested_union_type <|> unionize inner_type)++ return $ RecordType (M.fromList [(Symbol x, bool)])++ where name = type_var+ bool = UnionType (S.fromList [(SimpleType (SymbolType (Symbol "Bool")))])++symbol_type = SimpleType . SymbolType <$> type_name+var_type = SimpleType . VariableType <$> type_var++unionize :: Parser ComplexType -> Parser UnionType+unionize = fmap $ UnionType . S.fromList . (:[])+++type_name :: Parser Symbol+type_var :: Parser String++type_name = Symbol <$> not_reserved (upper <:> many (alphaNum <|> oneOf "_'"))+type_var = not_reserved (oneOf "abscdefghijklmnopqrstuvwxyz" <:> many (alphaNum <|> oneOf "_'"))++
+ src/hs/Formal/Types/TypeDefinition.hs view
@@ -0,0 +1,37 @@+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE NamedFieldPuns #-}+{-# LANGUAGE OverlappingInstances #-}+{-# LANGUAGE QuasiQuotes #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE TemplateHaskell #-}++module Formal.Types.TypeDefinition where++++import Control.Applicative++import qualified Data.List as L+import Text.Parsec hiding (State, label, many, parse, spaces,+ (<|>))++import Formal.Parser.Utils+++data TypeDefinition = TypeDefinition String [String]+++instance Show TypeDefinition where+ show (TypeDefinition name vars) = concat . L.intersperse " " $ name : vars+++instance Syntax TypeDefinition where++ syntax = do name <- (:) <$> upper <*> many alphaNum+ vars <- try vars' <|> return []+ return $ TypeDefinition name vars++ where vars' = do many1 $ oneOf "\t "+ let var = (:) <$> lower <*> many alphaNum+ var `sepEndBy` whitespace
+ src/hs/Main.hs view
@@ -0,0 +1,200 @@+{-# LANGUAGE FlexibleContexts, NamedFieldPuns, OverlappingInstances,+ QuasiQuotes, RankNTypes, RecordWildCards, TemplateHaskell,+ TupleSections, ViewPatterns #-}+++module Main(main) where++import Text.InterpolatedString.Perl6++import Control.Applicative+import Control.Monad.State hiding (lift)++import System.Directory+import System.Environment+import System.Exit+import System.IO+import System.Process++import Control.Concurrent++import Text.Pandoc++import Data.Char (isAscii, ord)+import Data.List as L+import Data.Monoid+import Data.String.Utils++import Formal.Closure+import Formal.Javascript+import Formal.Javascript.Backend+import Formal.Javascript.Utils (prelude)+import Formal.Parser+import Formal.TypeCheck hiding (split)+import Formal.Types.Statement+import Formal.CLI++import qualified Formal.Optimize as O++import qualified Data.ByteString.Char8 as B+import Data.FileEmbed++++toEntities :: String -> String+toEntities [] = ""+toEntities (c:cs) | isAscii c = c : toEntities cs+ | otherwise = [qq|&#{ord c};{toEntities cs}|]++toHTML :: String -> String+toHTML = toEntities . writeHtmlString defaultWriterOptions . readMarkdown defaultParserState+++to_literate :: String -> String -> String+to_literate filename+ | (head . tail . split "." $ filename) == "formal" = unlines . map l . lines+ | otherwise = id++ where l (lstrip -> '-':'-':xs) = lstrip xs+ l x = " " ++ x++to_parsed :: String -> String -> TypeSystem -> Either [String] (TypeSystem, (Program, String))+to_parsed name src env = case parseFormal name src of+ Left x -> Left [show x]+ Right x -> case tiProgram x env of+ (as, []) -> Right (as, (x, src))+ (_, y) -> Left y++parse_formal :: [String] -> IO ([String], TypeSystem, [(Program, String)])+parse_formal xs = foldM parse' (xs, [], []) xs++ where parse' :: ([String], TypeSystem, [(Program, String)]) -> String -> IO ([String], TypeSystem, [(Program, String)])+ parse' (zs, ts, as) filename = do hFile <- openFile filename ReadMode+ src <- hGetContents hFile+ let src' = to_literate filename . (++ "\n") $ src+ (ts', as') <- monitor [qq|Loading $filename|] $ return$ to_parsed (head zs) src' ts+ return (tail zs, ts ++ ts', as ++ [as'])++gen_js :: [String] -> [Program] -> (String, [(String, String)])+gen_js src p = (compress (read' prelude ++ "\n" ++ (unlines $ map read' $ zipWith (render (Program $ get_program p)) src p)), [("", read' prelude ++ "\n" ++ (unlines $ map read' $ zipWith (render_spec (Program $ get_program p)) src p))])++read' :: [Char] -> [Char]+read' xs @ ('"':_) = read xs+read' x = x++get_program :: [Program] -> [Statement]+get_program (Program ss: ps) = ss ++ get_program ps+get_program [] = []++main :: IO ()+main = do args <- getArgs+ main' args++main' :: [String] -> IO ()+main' (parseArgs -> rc') =+ if watch rc'+ then watch' rc'+ else compile rc'++ where f (x, y) = show x ++ "\n " ++ concat (L.intersperse "\n " (map show y)) ++ "\n\n "++ jquery = $(embedFile "lib/js/jquery.js")+ header = $(embedFile "src/html/header.html")+ footer = $(embedFile "src/html/footer.html")+ jasmine = $(embedFile "lib/js/jasmine-1.0.1/jasmine.js")+ `mappend` $(embedFile "lib/js/jasmine-1.0.1/jasmine-html.js")++ console = "prelude.html.console_runner()"+ report = $(embedFile "src/js/FormalReporter.js")+ htmljs = "$('#run_tests').click(prelude.html.table_of_contents)"++ watch' rc =++ do x <- mapM getModificationTime . inputs $ rc+ compile rc+ putStr "Waiting ..."+ hFlush stdout+ wait rc x++ wait rc x =++ do threadDelay 1000+ x' <- mapM getModificationTime . inputs $ rc+ if x /= x' then do putStr "\r"+ watch' rc+ else wait rc x++ compile rc =++ do (_, as, src') <- parse_formal$ inputs rc+ let src'' = O.run_optimizer (fmap fst src') as+ let (js', ((_, tests'):_)) = gen_js (fmap snd src') src''++ js <- if optimize rc+ then (monitor "Closure [libs"$ closure_local (js') "ADVANCED_OPTIMIZATIONS")+ else do warn "Closure [libs]" js'++ tests <- case rc of+ RunConfig { optimize = True, run_tests = Phantom } ->+ monitor "Closure [tests"$ closure_local (tests') "SIMPLE_OPTIMIZATIONS"+ _ -> warn "Closure [tests]" tests'++ writeFile (output rc ++ ".js") js+ writeFile (output rc ++ ".spec.js") tests++ monitor "Docs" $+ if write_docs rc+ then let xxx = map fst src'+ yyy = map snd src'+ html' xxx' yyy' = highlight (case xxx' of (Program xs) -> get_tests xs)$ toHTML (annotate_tests yyy' xxx')+ html = concat $ zipWith html' xxx yyy+ prelude' = "<script>" ++ B.unpack jasmine ++ B.unpack report ++ js ++ tests ++ "</script>"+ hook = "<script>" ++ htmljs ++ "</script>"++ in do writeFile ((output rc) ++ ".html") (B.unpack header ++ prelude' ++ html ++ hook ++ B.unpack footer)+ return $ Right ()+ else return $ Right ()++ case run_tests rc of+ Node ->+ monitor "Testing [Node.js]"$+ do (Just std_in, Just std_out, _, p) <-+ createProcess (proc "node" []) { std_in = CreatePipe, std_out = CreatePipe }+ forkIO $ do errors <- hGetContents std_out+ putStr errors+ hFlush stdout+ hPutStrLn std_in$ B.unpack jasmine+ hPutStrLn std_in$ js ++ "\n\n"+ hPutStrLn std_in$ tests+ hPutStrLn std_in$ console+ z <- waitForProcess p++ case z of+ ExitFailure _ -> return$ Left []+ ExitSuccess -> if (show_types rc)+ then Right <$> putStrLn ("\nTypes\n\n " ++ concat (map f as))+ else return$ Right ()++ Phantom ->+ monitor "Testing [Phantom.js]"$+ do writeFile (output rc ++ ".phantom.js")+ (B.unpack jquery ++ B.unpack jasmine ++ js ++ tests ++ console)++ (Just std_in, Just std_out, _, p) <-+ createProcess (proc "phantomjs" [output rc ++ ".phantom.js"]) { std_in = CreatePipe, std_out = CreatePipe }+ forkIO $ do errors <- hGetContents std_out+ putStr errors+ hFlush stdout+ z <- waitForProcess p+ system$ "rm " ++ output rc ++ ".phantom.js"++ case z of+ ExitFailure _ -> return$ Left []+ ExitSuccess -> if (show_types rc)+ then Right <$> putStrLn ("\nTypes\n\n " ++ concat (map f as))+ else return$ Right ()+ NoTest ->+ do warn "Testing" ()+ if (show_types rc)+ then putStrLn$ "\nTypes\n\n " ++ concat (map f as)+ else return ()
@@ -0,0 +1,7 @@+<div id="test_suite">+</div>++</div>+</div>+</body>+ </html>
+ src/html/header.html view
@@ -0,0 +1,55 @@+<!DOCTYPE html>+<!--[if lt IE 7 ]><html class="ie ie6" lang="en"> <![endif]-->+<!--[if IE 7 ]><html class="ie ie7" lang="en"> <![endif]-->+<!--[if IE 8 ]><html class="ie ie8" lang="en"> <![endif]-->+<!--[if (gte IE 9)|!(IE)]><!--><html lang="en"> <!--<![endif]-->+ <head>++ <!-- Basic Page Needs+ ================================================== -->+ <meta charset="utf-8">+ <meta name="description" content="">+ <meta name="author" content="">++ <!-- Mobile Specific Metas+ ================================================== -->+ <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">++ <!-- CSS+ ================================================== -->+ <link rel="stylesheet" href="lib/base.css">+ <link rel="stylesheet" href="lib/skeleton.css">+ <link rel="stylesheet" href="lib/layout.css">++ <link href='lib/js/prettify.css' type='text/css' rel='stylesheet' />+ <link href='lib/default.css' type='text/css' rel='stylesheet' />+ <link href='lib/js/jasmine-1.0.1/jasmine.css' type='text/css' rel='stylesheet' />++ <script type='text/javascript' src='lib/js/prettify.js'></script>+ <script type='text/javascript' src='lib/js/lang-hs.js'></script>+ <script type='text/javascript' src='lib/js/jquery.js'></script>+++ <!--[if lt IE 9]>+ <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>+ <![endif]-->++ <!-- Favicons+ ================================================== -->+ <link rel="shortcut icon" href="images/favicon.ico">+ <link rel="apple-touch-icon" href="images/apple-touch-icon.png">+ <link rel="apple-touch-icon" sizes="72x72" href="images/apple-touch-icon-72x72.png">+ <link rel="apple-touch-icon" sizes="114x114" href="images/apple-touch-icon-114x114.png">++ </head>+ <body>+ <div class="container">+ <div class="three columns sidebar">+ <nav>+ <h1 id="title">Formal</h1>+ <div>A Programming Language</div>+ <br/>+ <div id="run_tests">Test</div>+ </nav>+ </div>+ <div class="twelve columns offset-by-one content">
+ src/js/FormalReporter.js view
@@ -0,0 +1,79 @@++(function() {+jasmine.FormalReporter = function(doc) {+ this.document = doc || document;+ this.suiteDivs = {};+ this.logRunningSpecs = false;+ };+ + jasmine.FormalReporter.prototype.createDom = function(type, attrs, childrenVarArgs) {+ };+ + jasmine.FormalReporter.prototype.reportRunnerStarting = function(runner) {+ var showPassed, showSkipped;+ + var suites = runner.suites();+ for (var i = 0; i < suites.length; i++) {+ var suite = suites[i];+ }+ + this.startedAt = new Date();+ + var self = this;+ };+ + jasmine.FormalReporter.prototype.reportRunnerResults = function(runner) {+ };+ + jasmine.FormalReporter.prototype.reportSuiteResults = function(suite) {+ };+ + jasmine.FormalReporter.prototype.reportSpecStarting = function(spec) {+ };+ + jasmine.FormalReporter.prototype.reportSpecResults = function(spec) {+ var results = spec.results();+ var status = results.passed() ? 'passed' : 'failed';+ + var k = "#test_" + spec.description.split("__::__")[0]+ var el = $(k)++ spec.description = spec.description.split("__::__")[1]++ if (status == "passed") {+ if (k.indexOf("multi") >= 0) {+ $(k).before("<span style='border-radius:3;margin-right:-50px;background-color:rgba(32,186,24,0.5)' title='" + JSON.stringify(spec.results_.items_[0].actual)+ "'> <span style='color:rgb(255,255,255);font-weight:bold'>PASS</span> </span> ")+ } else {+ $(k).before("<span style='border-radius:3;margin-right:-50px;background-color:rgba(32,186,24,0.5)' title='" + spec.results_.items_[0].actual+ "'> <span style='color:rgb(255,255,255);font-weight:bold'>PASS</span> </span> ")+ }+ } else {+ if (k.indexOf("multi") >= 0) {+ $(k).before("<span style='border-radius:3;margin-right:-50px;background-color:rgba(182,24,32,0.5)' title='" + JSON.stringify(spec.results_.items_[0].actual)+ "'> <span style='color:rgb(255,255,255);font-weight:bold'>FAIL</span> </span> ")+ } else {+ $(k).before("<span style='border-radius:3;margin-right:-50px;background-color:rgba(182,24,32,0.5)' title='" + JSON.stringify(spec.results_.items_[0].actual)+ "'> <span style='color:rgb(255,255,255);font-weight:bold'>FAIL</span> </span> ")+ }+ }+ };+ + jasmine.FormalReporter.prototype.log = function() {+ };+ + jasmine.FormalReporter.prototype.getLocation = function() {+ return this.document.location;+ };+ + jasmine.FormalReporter.prototype.specFilter = function(spec) {+ var paramMap = {};+ var params = this.getLocation().search.substring(1).split('&');+ for (var i = 0; i < params.length; i++) {+ var p = params[i].split('=');+ paramMap[decodeURIComponent(p[0])] = decodeURIComponent(p[1]);+ }+ + if (!paramMap.spec) {+ return true;+ }+ return spec.getFullName().indexOf(paramMap.spec) === 0;+ };+ +})();
+ src/js/table_of_contents.js view
@@ -0,0 +1,32 @@+++$(function() {+ // var headers = $("h2,h3,h4,h5,h6")++ // var text = ""++ // headers.map(function(y,x) {+ // text += "<a href=\"#" + x.innerHTML.toLowerCase().replace(/\s/g, "-") + "\">" + x.innerHTML + "</a></br>"+ // });++ // $('#contents').html(text);+ // $('body').css('font-family','Arial');+ // $('code').css('font-family', 'Menlo, Consolas, Monospace');+ /// / $('p, ul, ol').css('text-align','justify')+ // $('code').addClass('prettyprint lang-hs');+ // // $('body').css('margin', '0 0');+ // // $('pre').css('margin', '0 0 23px 0');+ // $(".test").css("position", "relative").css("left", "50px")+ // prettyPrint();++ // jasmine.getEnv().addReporter(new jasmine.TrivialReporter());+ // jasmine.getEnv().addReporter(new jasmine.FormalReporter());+ // jasmine.getEnv().execute();++ // var reporter = $(".jasmine_reporter").detach();++ // $("body div").append(reporter)++});++prelude.html.table_of_contents()