summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--demo/custom.css160
-rw-r--r--demo/index.html12
-rw-r--r--demo/primer.css6
-rw-r--r--demo/third_party/codemirror/javascript.js847
-rw-r--r--demo/third_party/split/horizontal.pngbin0 -> 104 bytes
-rw-r--r--demo/third_party/split/split.min.js5
-rw-r--r--demo/third_party/split/vertical.pngbin0 -> 91 bytes
-rw-r--r--demo/wasm2wat/index.html46
-rw-r--r--demo/wat2wasm/demo.js110
-rw-r--r--demo/wat2wasm/examples.js93
-rw-r--r--demo/wat2wasm/index.html45
11 files changed, 1195 insertions, 129 deletions
diff --git a/demo/custom.css b/demo/custom.css
index 86d3c7d4..88fc0a2b 100644
--- a/demo/custom.css
+++ b/demo/custom.css
@@ -1,19 +1,161 @@
-.CodeMirror {
- height: 600px;
+html {
+ font-size: 80%;
+ line-height: 1.3;
}
-.two-fifths {
- width:40%;
+* {
+ box-sizing: border-box;
}
-.three-fifths {
- width:60%;
+body {
+ font-family: sans-serif;
+ font-size: 1rem;
+ line-height: 1.3125rem;
+ margin: 0;
}
-.container {
- width: 1200px;
+h1 {
+ font-size: 2.375rem;
+ line-height: 2.625rem;
+ margin-top: 1.3125rem;
+ margin-bottom: 1.3125rem;
+}
+
+h2 {
+ font-size: 1.75rem;
+ line-height: 2.625rem;
+ margin-top: 1.3125rem;
+ margin-bottom: 1.3125rem;
+}
+
+h3 {
+ font-size: 1.3125rem;
+ line-height: 1.3125rem;
+ margin-top: 1.3125rem;
+ margin-bottom: 0rem;
+}
+
+h4 {
+ font-size: 1rem;
+ line-height: 1.3125rem;
+ margin-top: 1.3125rem;
+ margin-bottom: 0rem;
+}
+
+h5 {
+ font-size: 1rem;
+ line-height: 1.3125rem;
+ margin-top: 1.3125rem;
+ margin-bottom: 0rem;
+}
+
+p, ul {
+ padding-left: 0;
+ margin-top: 0rem;
+ margin-bottom: 1.3125rem;
+}
+
+ul ul, ol ol, ul ol, ol ul {
+ margin-top: 0rem;
+ margin-bottom: 0rem;
+}
+
+pre {
+ margin: 0;
+}
+
+.right {
+ float: right;
+ white-space: nowrap;
}
.hidden {
- visibility: hidden;
+ display: none;
+}
+
+#split-grid {
+ position: absolute;
+ height: 100%;
+ left: 0;
+ right: 0;
+ top: 0;
+}
+
+.CodeMirror, .output {
+ position: absolute;
+ height: calc(100% - 2.625rem);
+ top: 2.625rem;
+ left: 0;
+ right: 0;
+}
+
+.output {
+ padding: 0.3125rem;
+ overflow: auto;
+}
+
+.toolbar {
+ position: absolute;
+ top: 0;
+ right: 0;
+ left: 0;
+ color: #555;
+ background-color: #eee;
+ z-index: 9;
+ height: 2.625rem;
+ line-height: 2rem;
+ padding: 0.3125rem 0.3125rem 0;
+ box-shadow: 0 2px 2px rgba(0, 0, 0, 0.3);
+}
+
+.split-horizontal, .gutter-horizontal {
+ height: 100%;
+ float: left;
+}
+
+.gutter-horizontal {
+ cursor: ew-resize;
+ background-image: url('third_party/split/vertical.png');
+}
+
+.gutter-vertical {
+ cursor: ns-resize;
+ background-image: url('third_party/split/horizontal.png');
+}
+
+.gutter {
+ touch-action: none;
+ user-select: none;
+ background-color: #ddd;
+ background-repeat: no-repeat;
+ background-position: 50%;
+ z-index: 0;
+}
+
+.split {
+ position: relative;
+ overflow: hidden;
+}
+
+
+body {
+ display: flex;
+ min-height: 100vh;
+ flex-direction: column;
+}
+
+main {
+ flex: 1;
+ position: relative;
+}
+
+header {
+ padding: 0 1em;
+ z-index: 10;
+ box-shadow: 0 2px 2px rgba(0, 0, 0, 0.3);
+}
+
+ul {
+ margin: 1em;
+ list-style: none;
}
diff --git a/demo/index.html b/demo/index.html
index 912c1c9e..fea01a2c 100644
--- a/demo/index.html
+++ b/demo/index.html
@@ -19,27 +19,27 @@
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>wabt demos</title>
- <link href="primer.css" rel="stylesheet">
<link href="custom.css" rel="stylesheet">
</head>
<body>
- <div class="container">
+ <header>
<h1>wabt demos</h1>
- <hr>
+ </header>
+ <main>
<ul>
<li>
- <a href="wat2wasm/">wat2wasm demo</a>
+ <a href="wat2wasm/index.html">wat2wasm demo</a>
<p>
Example showing converting text to binary.
</p>
</li>
<li>
- <a href="wasm2wat/">wasm2wat demo</a>
+ <a href="wasm2wat/index.html">wasm2wat demo</a>
<p>
Example showing converting binary to text.
</p>
</li>
</ul>
- </div>
+ </main>
</body>
</html>
diff --git a/demo/primer.css b/demo/primer.css
deleted file mode 100644
index c9d09316..00000000
--- a/demo/primer.css
+++ /dev/null
@@ -1,6 +0,0 @@
-/*!
- * Primer
- * http://primercss.io
- *
- * Released under MIT license. Copyright 2015 GitHub, Inc.
- *//*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%;text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}dfn{font-style:italic}h1{font-size:2em;margin:0.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace, monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0}input[type="number"]::-webkit-inner-spin-button,input[type="number"]::-webkit-outer-spin-button{height:auto}input[type="search"]{-webkit-appearance:textfield;box-sizing:content-box}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid #c0c0c0;margin:0 2px;padding:0.35em 0.625em 0.75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:bold}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}*{box-sizing:border-box}input,select,textarea,button{font:13px/1.4 Helvetica,arial,nimbussansl,liberationsans,freesans,clean,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol"}body{font:13px/1.4 Helvetica,arial,nimbussansl,liberationsans,freesans,clean,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";color:#333;background-color:#fff}a{color:#4078c0;text-decoration:none}a:hover,a:active{text-decoration:underline}hr,.rule{height:0;margin:15px 0;overflow:hidden;background:transparent;border:0;border-bottom:1px solid #ddd}hr::before,.rule::before{display:table;content:""}hr::after,.rule::after{display:table;clear:both;content:""}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:0;line-height:1.5}h1{font-size:30px}h2{font-size:21px}h3{font-size:16px}h4{font-size:14px}h5{font-size:12px}h6{font-size:11px}p{margin-top:0;margin-bottom:10px}small{font-size:90%}blockquote{margin:0}.lead{margin-bottom:30px;font-size:20px;font-weight:300;color:#555}.text-emphasized{font-weight:bold;color:#333}ul,ol{padding-left:0;margin-top:0;margin-bottom:0}ol ol,ul ol{list-style-type:lower-roman}ul ul ol,ul ol ol,ol ul ol,ol ol ol{list-style-type:lower-alpha}dd{margin-left:0}tt,code{font-family:Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:12px}pre{margin-top:0;margin-bottom:0;font:12px Consolas,"Liberation Mono",Menlo,Courier,monospace}.container{width:980px;margin-right:auto;margin-left:auto}.container::before{display:table;content:""}.container::after{display:table;clear:both;content:""}.columns{margin-right:-10px;margin-left:-10px}.columns::before{display:table;content:""}.columns::after{display:table;clear:both;content:""}.column{float:left;padding-right:10px;padding-left:10px}.one-third{width:33.333333%}.two-thirds{width:66.666667%}.one-fourth{width:25%}.one-half{width:50%}.three-fourths{width:75%}.one-fifth{width:20%}.four-fifths{width:80%}.single-column{padding-right:10px;padding-left:10px}.table-column{display:table-cell;width:1%;padding-right:10px;padding-left:10px;vertical-align:top}.centered{display:block;float:none;margin-right:auto;margin-left:auto}.border{border:1px #e5e5e5 solid !important}.border-top{border-top:1px #e5e5e5 solid !important}.border-right{border-right:1px #e5e5e5 solid !important}.border-bottom{border-bottom:1px #e5e5e5 solid !important}.border-left{border-left:1px #e5e5e5 solid !important}.border-y{border-top:1px #e5e5e5 solid !important;border-bottom:1px #e5e5e5 solid !important}.border-blue{border-color:#c5d5dd !important}.border-gray-light{border-color:#eee !important}.border-gray-dark{border-color:#ddd !important}.border-0{border:0 !important}.border-top-0{border-top:0 !important}.border-right-0{border-right:0 !important}.border-bottom-0{border-bottom:0 !important}.border-left-0{border-left:0 !important}.rounded-0{border-radius:0 !important}.rounded-1{border-radius:3px !important}.rounded-2{border-radius:6px !important}.bg-white{background-color:#fff !important}.bg-blue{background-color:#4078c0 !important}.bg-blue-light{background-color:#f2f8fa !important}.bg-gray-dark{background-color:#333 !important}.bg-gray{background-color:#f5f5f5 !important}.bg-gray-light{background-color:#fafafa !important}.bg-green{background-color:#6cc644 !important}.bg-red{background-color:#bd2c00 !important}.text-blue{color:#4078c0 !important}.danger,.text-closed,.text-danger,.text-diff-deleted,.text-error,.text-failure,.text-reverted,.text-red{color:#bd2c00 !important}.text-gray-light{color:#999 !important}.text-muted,.text-gray{color:#767676 !important}.mute,.text-gray-dark{color:#333 !important}.text-diff-added,.text-success,.text-open,.text-green{color:#55a532 !important}.text-orange{color:#c9510c !important}.text-merged,.text-purple{color:#6e5494 !important}.text-white{color:#fff !important}.text-inherit{color:inherit !important}.link-blue{color:#4078c0 !important}.link-gray-dark{color:#333 !important}.link-gray{color:#767676 !important}.text-renamed{color:#fffa5d !important}.text-pending{color:#cea61b !important}.muted-link{color:#767676 !important}.muted-link:hover{color:#4078c0 !important;text-decoration:none}.position-static{position:static !important}.position-relative{position:relative !important}.position-absolute{position:absolute !important}.position-fixed{position:fixed !important}.top-0{top:0 !important}.right-0{right:0 !important}.bottom-0{bottom:0 !important}.left-0{left:0 !important}.d-block{display:block !important}.d-inline{display:inline !important}.d-inline-block{display:inline-block !important}.hidden,.d-none{display:none !important}.clearfix::before{display:table;content:""}.clearfix::after{display:table;clear:both;content:""}.right,.float-right{float:right !important}.left,.float-left{float:left !important}.m-0{margin:0 !important}.mt-0{margin-top:0 !important}.mr-0{margin-right:0 !important}.mb-0{margin-bottom:0 !important}.ml-0{margin-left:0 !important}.mx-0{margin-right:0 !important;margin-left:0 !important}.my-0{margin-top:0 !important;margin-bottom:0 !important}.m-1{margin:3px !important}.mt-1{margin-top:3px !important}.mr-1{margin-right:3px !important}.mb-1{margin-bottom:3px !important}.ml-1{margin-left:3px !important}.mx-1{margin-right:3px !important;margin-left:3px !important}.my-1{margin-top:3px !important;margin-bottom:3px !important}.m-2{margin:6px !important}.mt-2{margin-top:6px !important}.mr-2{margin-right:6px !important}.mb-2{margin-bottom:6px !important}.ml-2{margin-left:6px !important}.mx-2{margin-right:6px !important;margin-left:6px !important}.my-2{margin-top:6px !important;margin-bottom:6px !important}.m-3{margin:12px !important}.mt-3{margin-top:12px !important}.mr-3{margin-right:12px !important}.mb-3{margin-bottom:12px !important}.ml-3{margin-left:12px !important}.mx-3{margin-right:12px !important;margin-left:12px !important}.my-3{margin-top:12px !important;margin-bottom:12px !important}.m-4{margin:24px !important}.mt-4{margin-top:24px !important}.mr-4{margin-right:24px !important}.mb-4{margin-bottom:24px !important}.ml-4{margin-left:24px !important}.mx-4{margin-right:24px !important;margin-left:24px !important}.my-4{margin-top:24px !important;margin-bottom:24px !important}.m-5{margin:36px !important}.mt-5{margin-top:36px !important}.mr-5{margin-right:36px !important}.mb-5{margin-bottom:36px !important}.ml-5{margin-left:36px !important}.mx-5{margin-right:36px !important;margin-left:36px !important}.my-5{margin-top:36px !important;margin-bottom:36px !important}.m-6{margin:48px !important}.mt-6{margin-top:48px !important}.mr-6{margin-right:48px !important}.mb-6{margin-bottom:48px !important}.ml-6{margin-left:48px !important}.mx-6{margin-right:48px !important;margin-left:48px !important}.my-6{margin-top:48px !important;margin-bottom:48px !important}.m-auto{margin-right:auto !important;margin-left:auto !important}.p-0{padding:0 !important}.pt-0{padding-top:0 !important}.pr-0{padding-right:0 !important}.pb-0{padding-bottom:0 !important}.pl-0{padding-left:0 !important}.px-0{padding-right:0 !important;padding-left:0 !important}.py-0{padding-top:0 !important;padding-bottom:0 !important}.p-1{padding:3px !important}.pt-1{padding-top:3px !important}.pr-1{padding-right:3px !important}.pb-1{padding-bottom:3px !important}.pl-1{padding-left:3px !important}.px-1{padding-right:3px !important;padding-left:3px !important}.py-1{padding-top:3px !important;padding-bottom:3px !important}.p-2{padding:6px !important}.pt-2{padding-top:6px !important}.pr-2{padding-right:6px !important}.pb-2{padding-bottom:6px !important}.pl-2{padding-left:6px !important}.px-2{padding-right:6px !important;padding-left:6px !important}.py-2{padding-top:6px !important;padding-bottom:6px !important}.p-3{padding:12px !important}.pt-3{padding-top:12px !important}.pr-3{padding-right:12px !important}.pb-3{padding-bottom:12px !important}.pl-3{padding-left:12px !important}.px-3{padding-right:12px !important;padding-left:12px !important}.py-3{padding-top:12px !important;padding-bottom:12px !important}.p-4{padding:24px !important}.pt-4{padding-top:24px !important}.pr-4{padding-right:24px !important}.pb-4{padding-bottom:24px !important}.pl-4{padding-left:24px !important}.px-4{padding-right:24px !important;padding-left:24px !important}.py-4{padding-top:24px !important;padding-bottom:24px !important}.p-5{padding:36px !important}.pt-5{padding-top:36px !important}.pr-5{padding-right:36px !important}.pb-5{padding-bottom:36px !important}.pl-5{padding-left:36px !important}.px-5{padding-right:36px !important;padding-left:36px !important}.py-5{padding-top:36px !important;padding-bottom:36px !important}.p-6{padding:48px !important}.pt-6{padding-top:48px !important}.pr-6{padding-right:48px !important}.pb-6{padding-bottom:48px !important}.pl-6{padding-left:48px !important}.px-6{padding-right:48px !important;padding-left:48px !important}.py-6{padding-top:48px !important;padding-bottom:48px !important}.text-right{text-align:right !important}.text-left{text-align:left !important}.text-center{text-align:center !important}.text-normal{font-weight:normal !important}.no-underline{text-decoration:none !important}.no-wrap{white-space:nowrap !important}.vertical-middle{vertical-align:middle !important}.text-small{font-size:12px !important}fieldset{padding:0;margin:0;border:0}label{font-size:13px;font-weight:bold}.form-control,.form-select{min-height:34px;padding:7px 8px;font-size:13px;color:#333;vertical-align:middle;background-color:#fff;background-repeat:no-repeat;background-position:right 8px center;border:1px solid #ddd;border-radius:3px;outline:none;box-shadow:inset 0 1px 2px rgba(0,0,0,0.075)}.form-control.focus,.form-control:focus,.form-select.focus,.form-select:focus{border-color:#51a7e8;outline:none;box-shadow:inset 0 1px 2px rgba(0,0,0,0.075),0 0 5px rgba(81,167,232,0.5)}.input-contrast{background-color:#fafafa}.input-contrast:focus{background-color:#fff}::-webkit-input-placeholder{color:#999}::-moz-placeholder{color:#999}:-ms-input-placeholder{color:#999}::placeholder{color:#999}.input-sm{min-height:26px;padding-top:4px;padding-bottom:4px;font-size:12px}.input-lg{padding:6px 10px;font-size:16px}.input-block{display:block;width:100%}.input-monospace{font-family:Consolas,"Liberation Mono",Menlo,Courier,monospace}.form-checkbox{padding-left:20px;margin:15px 0;vertical-align:middle}.form-checkbox label em.highlight{position:relative;left:-4px;padding:2px 4px;font-style:normal;background:#fffbdc;border-radius:3px}.form-checkbox input[type=checkbox],.form-checkbox input[type=radio]{float:left;margin:2px 0 0 -20px;vertical-align:middle}.form-checkbox .note{display:block;margin:0;font-size:12px;font-weight:normal;color:#666}.hfields{margin:15px 0}.hfields::before{display:table;content:""}.hfields::after{display:table;clear:both;content:""}.hfields .form-group{float:left;margin:0 30px 0 0}.hfields .form-group dt label{display:inline-block;margin:5px 0 0;color:#666}.hfields .form-group dt img{position:relative;top:-2px}.hfields .btn{float:left;margin:28px 25px 0 -20px}.hfields .form-select{margin-top:5px}input::-webkit-outer-spin-button,input::-webkit-inner-spin-button{margin:0;-webkit-appearance:none}.form-actions::before{display:table;content:""}.form-actions::after{display:table;clear:both;content:""}.form-actions .btn{float:right}.form-actions .btn+.btn{margin-right:5px}.form-warning{padding:8px 10px;margin:10px 0;font-size:14px;color:#4c4a42;background:#fff9ea;border:1px solid #dfd8c2;border-radius:3px}.form-warning p{margin:0;line-height:1.5}.form-warning a{font-weight:bold}.form-select{display:inline-block;max-width:100%;padding-right:24px;padding-right:8px \9;background:#fff url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAUCAMAAACzvE1FAAAADFBMVEUzMzMzMzMzMzMzMzMKAG/3AAAAA3RSTlMAf4C/aSLHAAAAPElEQVR42q3NMQ4AIAgEQTn//2cLdRKppSGzBYwzVXvznNWs8C58CiussPJj8h6NwgorrKRdTvuV9v16Afn0AYFOB7aYAAAAAElFTkSuQmCC) no-repeat right 8px center;background-image:none \9;background-size:8px 10px;-webkit-appearance:none;-moz-appearance:none;appearance:none}.form-select::-ms-expand{opacity:0}.form-select:not([multiple]){height:34px}.select-sm{padding-top:3px;padding-bottom:3px;font-size:12px}.select-sm:not([multiple]){height:26px;min-height:26px}.form-group{margin:15px 0}.form-group .form-control{width:440px;max-width:100%;margin-right:5px;background-color:#fafafa}.form-group .form-control:focus{background-color:#fff}.form-group .form-control.shorter{width:130px}.form-group .form-control.short{width:250px}.form-group .form-control.long{width:100%}.form-group textarea.form-control{width:100%;height:200px;min-height:200px}.form-group textarea.form-control.short{height:50px;min-height:50px}.form-group dt{margin:0 0 6px}.form-group label{position:relative}.form-group.flattened dt{float:left;margin:0;line-height:32px}.form-group.flattened dd{line-height:32px}.form-group dd h4{margin:4px 0 0}.form-group dd h4.is-error{color:#bd2c00}.form-group dd h4.is-success{color:#55a532}.form-group dd h4+.note{margin-top:0}.form-group.required dt label::after{padding-left:5px;color:#bd2c00;content:"*"}.form-group .success,.form-group .error,.form-group .indicator{display:none;font-size:12px;font-weight:bold}.form-group.loading{opacity:0.5}.form-group.loading .indicator{display:inline}.form-group.loading .spinner{display:inline-block;vertical-align:middle}.form-group.successful .success{display:inline;color:#55a532}.form-group.warn .warning,.form-group.warn .error,.form-group.errored .warning,.form-group.errored .error{position:absolute;z-index:10;display:inline-block;max-width:450px;padding:5px 8px;margin:3px 0 0;font-size:13px;font-weight:normal;border-style:solid;border-width:1px;border-radius:3px}.form-group.warn .warning::after,.form-group.warn .warning::before,.form-group.warn .error::after,.form-group.warn .error::before,.form-group.errored .warning::after,.form-group.errored .warning::before,.form-group.errored .error::after,.form-group.errored .error::before{position:absolute;bottom:100%;left:10px;z-index:15;width:0;height:0;pointer-events:none;content:" ";border:solid transparent}.form-group.warn .warning::after,.form-group.warn .error::after,.form-group.errored .warning::after,.form-group.errored .error::after{border-width:5px}.form-group.warn .warning::before,.form-group.warn .error::before,.form-group.errored .warning::before,.form-group.errored .error::before{margin-left:-1px;border-width:6px}.form-group.warn .warning{color:#4c4a42;background-color:#fff9ea;border-color:#dfd8c2}.form-group.warn .warning::after{border-bottom-color:#fff9ea}.form-group.warn .warning::before{border-bottom-color:#dfd8c2}.form-group.errored label{color:#bd2c00}.form-group.errored .error{color:#911;background-color:#fcdede;border-color:#d2b2b2}.form-group.errored .error::after{border-bottom-color:#fcdede}.form-group.errored .error::before{border-bottom-color:#d2b2b2}.note{min-height:17px;margin:4px 0 2px;font-size:12px;color:#767676}.note .spinner{margin-right:3px;vertical-align:middle}.btn{position:relative;display:inline-block;padding:6px 12px;font-size:13px;font-weight:bold;line-height:20px;color:#333;white-space:nowrap;vertical-align:middle;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:#eee;background-image:linear-gradient(#fcfcfc, #eee);border:1px solid #d5d5d5;border-radius:3px;-webkit-appearance:none}.btn i{font-style:normal;font-weight:500;opacity:0.6}.btn .octicon{vertical-align:text-top}.btn .counter{text-shadow:none;background-color:#e5e5e5}.btn:focus{text-decoration:none;border-color:#51a7e8;outline:none;box-shadow:0 0 5px rgba(81,167,232,0.5)}.btn:focus:hover,.btn.selected:focus{border-color:#51a7e8}.btn:hover,.btn:active,.btn.zeroclipboard-is-hover,.btn.zeroclipboard-is-active{text-decoration:none;background-color:#ddd;background-image:linear-gradient(#eee, #ddd);border-color:#ccc}.btn:active,.btn.selected,.btn.zeroclipboard-is-active{background-color:#dcdcdc;background-image:none;border-color:#b5b5b5;box-shadow:inset 0 2px 4px rgba(0,0,0,0.15)}.btn.selected:hover{background-color:#cfcfcf}.btn:disabled,.btn:disabled:hover,.btn.disabled,.btn.disabled:hover{color:rgba(102,102,102,0.5);cursor:default;background-color:rgba(229,229,229,0.5);background-image:none;border-color:rgba(197,197,197,0.5);box-shadow:none}.btn-primary{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.15);background-color:#60b044;background-image:linear-gradient(#8add6d, #60b044);border-color:#5ca941}.btn-primary .counter{color:#60b044;background-color:#fff}.btn-primary:hover{color:#fff;background-color:#569e3d;background-image:linear-gradient(#79d858, #569e3d);border-color:#4a993e}.btn-primary:active,.btn-primary.selected{text-shadow:0 1px 0 rgba(0,0,0,0.15);background-color:#569e3d;background-image:none;border-color:#418737}.btn-primary.selected:hover{background-color:#4c8b36}.btn-primary:disabled,.btn-primary:disabled:hover,.btn-primary.disabled,.btn-primary.disabled:hover{color:#fefefe;background-color:#add39f;background-image:linear-gradient(#c3ecb4, #add39f);border-color:#b9dcac #b9dcac #a7c89b}.btn-danger{color:#900}.btn-danger:hover{color:#fff;background-color:#b33630;background-image:linear-gradient(#dc5f59, #b33630);border-color:#cd504a}.btn-danger:active,.btn-danger.selected{color:#fff;background-color:#b33630;background-image:none;border-color:#9f312c}.btn-danger.selected:hover{background-color:#9f302b}.btn-danger:disabled,.btn-danger:disabled:hover,.btn-danger.disabled,.btn-danger.disabled:hover{color:#cb7f7f;background-color:#efefef;background-image:linear-gradient(#fefefe, #efefef);border-color:#e1e1e1}.btn-danger:hover .counter,.btn-danger:active .counter,.btn-danger.selected .counter{color:#b33630;background-color:#fff}.btn-outline{color:#4078c0;background-color:#fff;background-image:none;border:1px solid #e5e5e5}.btn-outline .counter{background-color:#eee}.btn-outline:hover,.btn-outline:active,.btn-outline.selected,.btn-outline.zeroclipboard-is-hover,.btn-outline.zeroclipboard-is-active{color:#fff;background-color:#4078c0;background-image:none;border-color:#4078c0}.btn-outline:hover .counter,.btn-outline:active .counter,.btn-outline.selected .counter,.btn-outline.zeroclipboard-is-hover .counter,.btn-outline.zeroclipboard-is-active .counter{color:#4078c0;background-color:#fff}.btn-outline.selected:hover{background-color:#396cad}.btn-outline:disabled,.btn-outline:disabled:hover,.btn-outline.disabled,.btn-outline.disabled:hover{color:#767676;background-color:#fff;background-image:none;border-color:#e5e5e5}.btn-with-count{float:left;border-top-right-radius:0;border-bottom-right-radius:0}.btn-sm{padding:2px 10px}.hidden-text-expander{display:block}.hidden-text-expander.inline{position:relative;top:-1px;display:inline-block;margin-left:5px;line-height:0}.hidden-text-expander a,.ellipsis-expander{display:inline-block;height:12px;padding:0 5px 5px;font-size:12px;font-weight:bold;line-height:6px;color:#555;text-decoration:none;vertical-align:middle;background:#ddd;border-radius:1px;border:0}.hidden-text-expander a:hover,.ellipsis-expander:hover{text-decoration:none;background-color:#ccc}.hidden-text-expander a:active,.ellipsis-expander:active{color:#fff;background-color:#4183c4}.social-count{float:left;padding:2px 7px;font-size:11px;font-weight:bold;line-height:20px;color:#333;vertical-align:middle;background-color:#fff;border:1px solid #ddd;border-left:0;border-top-right-radius:3px;border-bottom-right-radius:3px}.social-count:hover,.social-count:active{text-decoration:none}.social-count:hover{color:#4078c0;cursor:pointer}.btn-block{display:block;width:100%;text-align:center}.btn-link{display:inline-block;padding:0;font-size:inherit;color:#4078c0;white-space:nowrap;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:transparent;border:0;-webkit-appearance:none}.btn-link:hover,.btn-link:focus{text-decoration:underline}.btn-link:focus{outline:none}.input-group{display:table}.input-group .form-control{position:relative;width:100%}.input-group .form-control:focus{z-index:2}.input-group .form-control+.btn{margin-left:0}.input-group.inline{display:inline-table}.input-group .form-control,.input-group-button{display:table-cell}.input-group-button{width:1%;vertical-align:middle}.input-group .form-control:first-child,.input-group-button:first-child .btn{border-top-right-radius:0;border-bottom-right-radius:0}.input-group-button:first-child .btn{margin-right:-1px}.input-group .form-control:last-child,.input-group-button:last-child .btn{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-button:last-child .btn{margin-left:-1px}.btn-group{display:inline-block;vertical-align:middle}.btn-group::before{display:table;content:""}.btn-group::after{display:table;clear:both;content:""}.btn-group .btn{position:relative;float:left}.btn-group .btn:not(:first-child):not(:last-child){border-radius:0}.btn-group .btn:first-child:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group .btn:last-child:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.btn-group .btn:hover,.btn-group .btn:active,.btn-group .btn.selected{z-index:2}.btn-group .btn:focus{z-index:3}.btn-group .btn+.btn{margin-left:-1px}.btn-group .btn+.btn-group-form,.btn-group .btn-group-form+.btn,.btn-group .btn-group-form+.btn-group-form{margin-left:-1px}.btn-group .btn-group-form{float:left}.btn-group .btn-group-form .btn{border-radius:0}.btn-group .btn-group-form:first-child .btn{border-top-left-radius:3px;border-bottom-left-radius:3px}.btn-group .btn-group-form:last-child .btn{border-top-right-radius:3px;border-bottom-right-radius:3px}.btn-group+.btn-group,.btn-group+.btn{margin-left:5px}.flash{position:relative;padding:15px;font-size:14px;line-height:1.5;color:#246;background-color:#e2eef9;border:1px solid #bac6d3;border-radius:3px}.flash p:last-child{margin-bottom:0}.flash-messages{margin-bottom:20px}.flash-close{float:right;width:34px;height:44px;margin:-11px;line-height:40px;color:inherit;text-align:center;cursor:pointer;background:none;border:0;-webkit-appearance:none;opacity:0.6}.flash-close:hover{opacity:1}.flash-action{float:right;margin-top:-4px;margin-left:20px}.flash-warn{color:#4c4a42;background-color:#fff9ea;border-color:#dfd8c2}.flash-error{color:#911;background-color:#fcdede;border-color:#d2b2b2}.flash-full{margin-top:-1px;border-width:1px 0;border-radius:0}.flash-with-icon .container{padding-left:40px}.flash-with-icon .flash-icon{float:left;margin-top:3px;margin-left:-25px}.flash-content{margin-top:0;margin-bottom:0;line-height:1.5}.warning{padding:0.5em;margin-bottom:0.8em;font-weight:bold;background-color:#fffccc}.avatar{display:inline-block;overflow:hidden;line-height:1;vertical-align:middle;border-radius:3px}.avatar-small{border-radius:2px}.avatar-link{float:left;line-height:1}.avatar-group-item{display:inline-block;margin-bottom:3px}.avatar-parent-child{position:relative}.avatar-child{position:absolute;right:-15%;bottom:-9%;background-color:#fff;border-radius:2px;box-shadow:-2px -2px 0 rgba(255,255,255,0.8)}.blankslate{position:relative;padding:30px;text-align:center;background-color:#fafafa;border:1px solid #e5e5e5;border-radius:3px;box-shadow:inset 0 0 10px rgba(0,0,0,0.05)}.blankslate code{padding:2px 5px 3px;font-size:14px;background:#fff;border:1px solid #eee;border-radius:3px}.blankslate-icon{margin-right:5px;margin-bottom:10px;margin-left:5px;color:#aaa}.blankslate-capped{border-radius:0 0 3px 3px}.blankslate-spacious{padding:100px 60px 120px}.blankslate-narrow{width:485px;margin:0 auto}.blankslate-large h3{margin:0.75em 0;font-size:20px}.blankslate-large p{font-size:16px}.blankslate-large p.has-fixed-width{width:540px;margin:0 auto;text-align:left}.blankslate-clean-background{background:none;border:0;box-shadow:none}.counter{display:inline-block;padding:2px 5px;font-size:11px;font-weight:bold;line-height:1;color:#666;background-color:#eee;border-radius:20px}.menu{margin-bottom:15px;list-style:none;background-color:#fff;border:1px solid #d8d8d8;border-radius:3px}.menu-item{position:relative;display:block;padding:8px 10px;text-shadow:0 1px 0 #fff;border-bottom:1px solid #eee}.menu-item:first-child{border-top:0;border-top-left-radius:2px;border-top-right-radius:2px}.menu-item:first-child::before{border-top-left-radius:2px}.menu-item:last-child{border-bottom:0;border-bottom-right-radius:2px;border-bottom-left-radius:2px}.menu-item:last-child::before{border-bottom-left-radius:2px}.menu-item:hover{text-decoration:none;background-color:#f9f9f9}.menu-item.selected{font-weight:bold;color:#222;cursor:default;background-color:#fff}.menu-item.selected::before{position:absolute;top:0;bottom:0;left:0;width:2px;content:"";background-color:#d26911}.menu-item .octicon{width:16px;margin-right:5px;color:#333;text-align:center}.menu-item .counter{float:right;margin-left:5px}.menu-item .menu-warning{float:right;color:#d26911}.menu-item .avatar{float:left;margin-right:5px}.menu-item.alert .counter{color:#bd2c00}.menu-heading{display:block;padding:8px 10px;margin-top:0;margin-bottom:0;font-size:13px;font-weight:bold;line-height:20px;color:#555;background-color:#f7f7f7;border-bottom:1px solid #eee}.menu-heading:hover{text-decoration:none}.menu-heading:first-child{border-top-left-radius:2px;border-top-right-radius:2px}.menu-heading:last-child{border-bottom:0;border-bottom-right-radius:2px;border-bottom-left-radius:2px}.tabnav{margin-top:0;margin-bottom:15px;border-bottom:1px solid #ddd}.tabnav .counter{margin-left:5px}.tabnav-tabs{margin-bottom:-1px}.tabnav-tab{display:inline-block;padding:8px 12px;font-size:14px;line-height:20px;color:#666;text-decoration:none;background-color:transparent;border:1px solid transparent;border-bottom:0}.tabnav-tab.selected{color:#333;background-color:#fff;border-color:#ddd;border-radius:3px 3px 0 0}.tabnav-tab:hover,.tabnav-tab:focus{text-decoration:none}.tabnav-extra{display:inline-block;padding-top:10px;margin-left:10px;font-size:12px;color:#666}.tabnav-extra>.octicon{margin-right:2px}a.tabnav-extra:hover{color:#4078c0;text-decoration:none}.tabnav-btn{margin-left:10px}.filter-list{list-style-type:none}.filter-list.small .filter-item{padding:4px 10px;margin:0 0 2px;font-size:12px}.filter-list.pjax-active .filter-item{color:#767676;background-color:transparent}.filter-list.pjax-active .filter-item.pjax-active{color:#fff;background-color:#4078c0}.filter-item{position:relative;display:block;padding:8px 10px;margin-bottom:5px;overflow:hidden;font-size:14px;color:#767676;text-decoration:none;text-overflow:ellipsis;white-space:nowrap;cursor:pointer;border-radius:3px}.filter-item:hover{text-decoration:none;background-color:#eee}.filter-item.selected{color:#fff;background-color:#4078c0}.filter-item.selected .octicon-remove-close{float:right;opacity:0.8}.filter-item .count{float:right;font-weight:bold}.filter-item .bar{position:absolute;top:2px;right:0;bottom:2px;z-index:-1;display:inline-block;background-color:#f1f1f1}.state{display:inline-block;padding:4px 8px;font-weight:bold;line-height:20px;color:#fff;text-align:center;background-color:#999;border-radius:3px}.state-open,.state-proposed,.state-reopened{background-color:#6cc644}.state-merged{background-color:#6e5494}.state-closed{background-color:#bd2c00}.state-renamed{background-color:#fffa5d}.tooltipped{position:relative}.tooltipped::after{position:absolute;z-index:1000000;display:none;padding:5px 8px;font:normal normal 11px/1.5 Helvetica,arial,nimbussansl,liberationsans,freesans,clean,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";color:#fff;text-align:center;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-wrap:break-word;white-space:pre;pointer-events:none;content:attr(aria-label);background:rgba(0,0,0,0.8);border-radius:3px;-webkit-font-smoothing:subpixel-antialiased;opacity:0}.tooltipped::before{position:absolute;z-index:1000001;display:none;width:0;height:0;color:rgba(0,0,0,0.8);pointer-events:none;content:"";border:5px solid transparent;opacity:0}@-webkit-keyframes tooltip-appear{from{opacity:0}to{opacity:1}}@keyframes tooltip-appear{from{opacity:0}to{opacity:1}}.tooltipped:hover::before,.tooltipped:hover::after,.tooltipped:active::before,.tooltipped:active::after,.tooltipped:focus::before,.tooltipped:focus::after{display:inline-block;text-decoration:none;-webkit-animation-name:tooltip-appear;animation-name:tooltip-appear;-webkit-animation-duration:0.1s;animation-duration:0.1s;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards;-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in;-webkit-animation-delay:0.4s;animation-delay:0.4s}.tooltipped-no-delay:hover::before,.tooltipped-no-delay:hover::after,.tooltipped-no-delay:active::before,.tooltipped-no-delay:active::after,.tooltipped-no-delay:focus::before,.tooltipped-no-delay:focus::after{opacity:1;-webkit-animation:none;animation:none}.tooltipped-multiline:hover::after,.tooltipped-multiline:active::after,.tooltipped-multiline:focus::after{display:table-cell}.tooltipped-s::after,.tooltipped-se::after,.tooltipped-sw::after{top:100%;right:50%;margin-top:5px}.tooltipped-s::before,.tooltipped-se::before,.tooltipped-sw::before{top:auto;right:50%;bottom:-5px;margin-right:-5px;border-bottom-color:rgba(0,0,0,0.8)}.tooltipped-se::after{right:auto;left:50%;margin-left:-15px}.tooltipped-sw::after{margin-right:-15px}.tooltipped-n::after,.tooltipped-ne::after,.tooltipped-nw::after{right:50%;bottom:100%;margin-bottom:5px}.tooltipped-n::before,.tooltipped-ne::before,.tooltipped-nw::before{top:-5px;right:50%;bottom:auto;margin-right:-5px;border-top-color:rgba(0,0,0,0.8)}.tooltipped-ne::after{right:auto;left:50%;margin-left:-15px}.tooltipped-nw::after{margin-right:-15px}.tooltipped-s::after,.tooltipped-n::after{-webkit-transform:translateX(50%);-ms-transform:translateX(50%);transform:translateX(50%)}.tooltipped-w::after{right:100%;bottom:50%;margin-right:5px;-webkit-transform:translateY(50%);-ms-transform:translateY(50%);transform:translateY(50%)}.tooltipped-w::before{top:50%;bottom:50%;left:-5px;margin-top:-5px;border-left-color:rgba(0,0,0,0.8)}.tooltipped-e::after{bottom:50%;left:100%;margin-left:5px;-webkit-transform:translateY(50%);-ms-transform:translateY(50%);transform:translateY(50%)}.tooltipped-e::before{top:50%;right:-5px;bottom:50%;margin-top:-5px;border-right-color:rgba(0,0,0,0.8)}.tooltipped-multiline::after{width:-webkit-max-content;width:-moz-max-content;width:max-content;max-width:250px;word-break:break-word;word-wrap:normal;white-space:pre-line;border-collapse:separate}.tooltipped-multiline.tooltipped-s::after,.tooltipped-multiline.tooltipped-n::after{right:auto;left:50%;-webkit-transform:translateX(-50%);-ms-transform:translateX(-50%);transform:translateX(-50%)}.tooltipped-multiline.tooltipped-w::after,.tooltipped-multiline.tooltipped-e::after{right:100%}@media screen and (min-width: 0 \0){.tooltipped-multiline::after{width:250px}}.tooltipped-sticky::before,.tooltipped-sticky::after{display:inline-block}.tooltipped-sticky.tooltipped-multiline::after{display:table-cell}.flex-table{display:table}.flex-table-item{display:table-cell;width:1%;white-space:nowrap;vertical-align:middle}.flex-table-item-primary{width:99%}.css-truncate.css-truncate-target,.css-truncate .css-truncate-target{display:inline-block;max-width:125px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;vertical-align:top}.css-truncate.expandable.zeroclipboard-is-hover .css-truncate-target,.css-truncate.expandable.zeroclipboard-is-hover.css-truncate-target,.css-truncate.expandable:hover .css-truncate-target,.css-truncate.expandable:hover.css-truncate-target{max-width:10000px !important}
diff --git a/demo/third_party/codemirror/javascript.js b/demo/third_party/codemirror/javascript.js
new file mode 100644
index 00000000..0a46dc77
--- /dev/null
+++ b/demo/third_party/codemirror/javascript.js
@@ -0,0 +1,847 @@
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
+// Distributed under an MIT license: http://codemirror.net/LICENSE
+
+(function(mod) {
+ if (typeof exports == "object" && typeof module == "object") // CommonJS
+ mod(require("../../lib/codemirror"));
+ else if (typeof define == "function" && define.amd) // AMD
+ define(["../../lib/codemirror"], mod);
+ else // Plain browser env
+ mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.defineMode("javascript", function(config, parserConfig) {
+ var indentUnit = config.indentUnit;
+ var statementIndent = parserConfig.statementIndent;
+ var jsonldMode = parserConfig.jsonld;
+ var jsonMode = parserConfig.json || jsonldMode;
+ var isTS = parserConfig.typescript;
+ var wordRE = parserConfig.wordCharacters || /[\w$\xa1-\uffff]/;
+
+ // Tokenizer
+
+ var keywords = function(){
+ function kw(type) {return {type: type, style: "keyword"};}
+ var A = kw("keyword a"), B = kw("keyword b"), C = kw("keyword c");
+ var operator = kw("operator"), atom = {type: "atom", style: "atom"};
+
+ var jsKeywords = {
+ "if": kw("if"), "while": A, "with": A, "else": B, "do": B, "try": B, "finally": B,
+ "return": C, "break": C, "continue": C, "new": kw("new"), "delete": C, "void": C, "throw": C, "debugger": C,
+ "var": kw("var"), "const": kw("var"), "let": kw("var"),
+ "function": kw("function"), "catch": kw("catch"),
+ "for": kw("for"), "switch": kw("switch"), "case": kw("case"), "default": kw("default"),
+ "in": operator, "typeof": operator, "instanceof": operator,
+ "true": atom, "false": atom, "null": atom, "undefined": atom, "NaN": atom, "Infinity": atom,
+ "this": kw("this"), "class": kw("class"), "super": kw("atom"),
+ "yield": C, "export": kw("export"), "import": kw("import"), "extends": C,
+ "await": C
+ };
+
+ // Extend the 'normal' keywords with the TypeScript language extensions
+ if (isTS) {
+ var type = {type: "variable", style: "type"};
+ var tsKeywords = {
+ // object-like things
+ "interface": kw("class"),
+ "implements": C,
+ "namespace": C,
+ "module": kw("module"),
+ "enum": kw("module"),
+
+ // scope modifiers
+ "public": kw("modifier"),
+ "private": kw("modifier"),
+ "protected": kw("modifier"),
+ "abstract": kw("modifier"),
+ "readonly": kw("modifier"),
+
+ // types
+ "string": type, "number": type, "boolean": type, "any": type
+ };
+
+ for (var attr in tsKeywords) {
+ jsKeywords[attr] = tsKeywords[attr];
+ }
+ }
+
+ return jsKeywords;
+ }();
+
+ var isOperatorChar = /[+\-*&%=<>!?|~^@]/;
+ var isJsonldKeyword = /^@(context|id|value|language|type|container|list|set|reverse|index|base|vocab|graph)"/;
+
+ function readRegexp(stream) {
+ var escaped = false, next, inSet = false;
+ while ((next = stream.next()) != null) {
+ if (!escaped) {
+ if (next == "/" && !inSet) return;
+ if (next == "[") inSet = true;
+ else if (inSet && next == "]") inSet = false;
+ }
+ escaped = !escaped && next == "\\";
+ }
+ }
+
+ // Used as scratch variables to communicate multiple values without
+ // consing up tons of objects.
+ var type, content;
+ function ret(tp, style, cont) {
+ type = tp; content = cont;
+ return style;
+ }
+ function tokenBase(stream, state) {
+ var ch = stream.next();
+ if (ch == '"' || ch == "'") {
+ state.tokenize = tokenString(ch);
+ return state.tokenize(stream, state);
+ } else if (ch == "." && stream.match(/^\d+(?:[eE][+\-]?\d+)?/)) {
+ return ret("number", "number");
+ } else if (ch == "." && stream.match("..")) {
+ return ret("spread", "meta");
+ } else if (/[\[\]{}\(\),;\:\.]/.test(ch)) {
+ return ret(ch);
+ } else if (ch == "=" && stream.eat(">")) {
+ return ret("=>", "operator");
+ } else if (ch == "0" && stream.eat(/x/i)) {
+ stream.eatWhile(/[\da-f]/i);
+ return ret("number", "number");
+ } else if (ch == "0" && stream.eat(/o/i)) {
+ stream.eatWhile(/[0-7]/i);
+ return ret("number", "number");
+ } else if (ch == "0" && stream.eat(/b/i)) {
+ stream.eatWhile(/[01]/i);
+ return ret("number", "number");
+ } else if (/\d/.test(ch)) {
+ stream.match(/^\d*(?:\.\d*)?(?:[eE][+\-]?\d+)?/);
+ return ret("number", "number");
+ } else if (ch == "/") {
+ if (stream.eat("*")) {
+ state.tokenize = tokenComment;
+ return tokenComment(stream, state);
+ } else if (stream.eat("/")) {
+ stream.skipToEnd();
+ return ret("comment", "comment");
+ } else if (expressionAllowed(stream, state, 1)) {
+ readRegexp(stream);
+ stream.match(/^\b(([gimyu])(?![gimyu]*\2))+\b/);
+ return ret("regexp", "string-2");
+ } else {
+ stream.eatWhile(isOperatorChar);
+ return ret("operator", "operator", stream.current());
+ }
+ } else if (ch == "`") {
+ state.tokenize = tokenQuasi;
+ return tokenQuasi(stream, state);
+ } else if (ch == "#") {
+ stream.skipToEnd();
+ return ret("error", "error");
+ } else if (isOperatorChar.test(ch)) {
+ if (ch != ">" || !state.lexical || state.lexical.type != ">")
+ stream.eatWhile(isOperatorChar);
+ return ret("operator", "operator", stream.current());
+ } else if (wordRE.test(ch)) {
+ stream.eatWhile(wordRE);
+ var word = stream.current()
+ if (state.lastType != ".") {
+ if (keywords.propertyIsEnumerable(word)) {
+ var kw = keywords[word]
+ return ret(kw.type, kw.style, word)
+ }
+ if (word == "async" && stream.match(/^\s*[\(\w]/, false))
+ return ret("async", "keyword", word)
+ }
+ return ret("variable", "variable", word)
+ }
+ }
+
+ function tokenString(quote) {
+ return function(stream, state) {
+ var escaped = false, next;
+ if (jsonldMode && stream.peek() == "@" && stream.match(isJsonldKeyword)){
+ state.tokenize = tokenBase;
+ return ret("jsonld-keyword", "meta");
+ }
+ while ((next = stream.next()) != null) {
+ if (next == quote && !escaped) break;
+ escaped = !escaped && next == "\\";
+ }
+ if (!escaped) state.tokenize = tokenBase;
+ return ret("string", "string");
+ };
+ }
+
+ function tokenComment(stream, state) {
+ var maybeEnd = false, ch;
+ while (ch = stream.next()) {
+ if (ch == "/" && maybeEnd) {
+ state.tokenize = tokenBase;
+ break;
+ }
+ maybeEnd = (ch == "*");
+ }
+ return ret("comment", "comment");
+ }
+
+ function tokenQuasi(stream, state) {
+ var escaped = false, next;
+ while ((next = stream.next()) != null) {
+ if (!escaped && (next == "`" || next == "$" && stream.eat("{"))) {
+ state.tokenize = tokenBase;
+ break;
+ }
+ escaped = !escaped && next == "\\";
+ }
+ return ret("quasi", "string-2", stream.current());
+ }
+
+ var brackets = "([{}])";
+ // This is a crude lookahead trick to try and notice that we're
+ // parsing the argument patterns for a fat-arrow function before we
+ // actually hit the arrow token. It only works if the arrow is on
+ // the same line as the arguments and there's no strange noise
+ // (comments) in between. Fallback is to only notice when we hit the
+ // arrow, and not declare the arguments as locals for the arrow
+ // body.
+ function findFatArrow(stream, state) {
+ if (state.fatArrowAt) state.fatArrowAt = null;
+ var arrow = stream.string.indexOf("=>", stream.start);
+ if (arrow < 0) return;
+
+ if (isTS) { // Try to skip TypeScript return type declarations after the arguments
+ var m = /:\s*(?:\w+(?:<[^>]*>|\[\])?|\{[^}]*\})\s*$/.exec(stream.string.slice(stream.start, arrow))
+ if (m) arrow = m.index
+ }
+
+ var depth = 0, sawSomething = false;
+ for (var pos = arrow - 1; pos >= 0; --pos) {
+ var ch = stream.string.charAt(pos);
+ var bracket = brackets.indexOf(ch);
+ if (bracket >= 0 && bracket < 3) {
+ if (!depth) { ++pos; break; }
+ if (--depth == 0) { if (ch == "(") sawSomething = true; break; }
+ } else if (bracket >= 3 && bracket < 6) {
+ ++depth;
+ } else if (wordRE.test(ch)) {
+ sawSomething = true;
+ } else if (/["'\/]/.test(ch)) {
+ return;
+ } else if (sawSomething && !depth) {
+ ++pos;
+ break;
+ }
+ }
+ if (sawSomething && !depth) state.fatArrowAt = pos;
+ }
+
+ // Parser
+
+ var atomicTypes = {"atom": true, "number": true, "variable": true, "string": true, "regexp": true, "this": true, "jsonld-keyword": true};
+
+ function JSLexical(indented, column, type, align, prev, info) {
+ this.indented = indented;
+ this.column = column;
+ this.type = type;
+ this.prev = prev;
+ this.info = info;
+ if (align != null) this.align = align;
+ }
+
+ function inScope(state, varname) {
+ for (var v = state.localVars; v; v = v.next)
+ if (v.name == varname) return true;
+ for (var cx = state.context; cx; cx = cx.prev) {
+ for (var v = cx.vars; v; v = v.next)
+ if (v.name == varname) return true;
+ }
+ }
+
+ function parseJS(state, style, type, content, stream) {
+ var cc = state.cc;
+ // Communicate our context to the combinators.
+ // (Less wasteful than consing up a hundred closures on every call.)
+ cx.state = state; cx.stream = stream; cx.marked = null, cx.cc = cc; cx.style = style;
+
+ if (!state.lexical.hasOwnProperty("align"))
+ state.lexical.align = true;
+
+ while(true) {
+ var combinator = cc.length ? cc.pop() : jsonMode ? expression : statement;
+ if (combinator(type, content)) {
+ while(cc.length && cc[cc.length - 1].lex)
+ cc.pop()();
+ if (cx.marked) return cx.marked;
+ if (type == "variable" && inScope(state, content)) return "variable-2";
+ return style;
+ }
+ }
+ }
+
+ // Combinator utils
+
+ var cx = {state: null, column: null, marked: null, cc: null};
+ function pass() {
+ for (var i = arguments.length - 1; i >= 0; i--) cx.cc.push(arguments[i]);
+ }
+ function cont() {
+ pass.apply(null, arguments);
+ return true;
+ }
+ function register(varname) {
+ function inList(list) {
+ for (var v = list; v; v = v.next)
+ if (v.name == varname) return true;
+ return false;
+ }
+ var state = cx.state;
+ cx.marked = "def";
+ if (state.context) {
+ if (inList(state.localVars)) return;
+ state.localVars = {name: varname, next: state.localVars};
+ } else {
+ if (inList(state.globalVars)) return;
+ if (parserConfig.globalVars)
+ state.globalVars = {name: varname, next: state.globalVars};
+ }
+ }
+
+ // Combinators
+
+ var defaultVars = {name: "this", next: {name: "arguments"}};
+ function pushcontext() {
+ cx.state.context = {prev: cx.state.context, vars: cx.state.localVars};
+ cx.state.localVars = defaultVars;
+ }
+ function popcontext() {
+ cx.state.localVars = cx.state.context.vars;
+ cx.state.context = cx.state.context.prev;
+ }
+ function pushlex(type, info) {
+ var result = function() {
+ var state = cx.state, indent = state.indented;
+ if (state.lexical.type == "stat") indent = state.lexical.indented;
+ else for (var outer = state.lexical; outer && outer.type == ")" && outer.align; outer = outer.prev)
+ indent = outer.indented;
+ state.lexical = new JSLexical(indent, cx.stream.column(), type, null, state.lexical, info);
+ };
+ result.lex = true;
+ return result;
+ }
+ function poplex() {
+ var state = cx.state;
+ if (state.lexical.prev) {
+ if (state.lexical.type == ")")
+ state.indented = state.lexical.indented;
+ state.lexical = state.lexical.prev;
+ }
+ }
+ poplex.lex = true;
+
+ function expect(wanted) {
+ function exp(type) {
+ if (type == wanted) return cont();
+ else if (wanted == ";") return pass();
+ else return cont(exp);
+ };
+ return exp;
+ }
+
+ function statement(type, value) {
+ if (type == "var") return cont(pushlex("vardef", value.length), vardef, expect(";"), poplex);
+ if (type == "keyword a") return cont(pushlex("form"), parenExpr, statement, poplex);
+ if (type == "keyword b") return cont(pushlex("form"), statement, poplex);
+ if (type == "{") return cont(pushlex("}"), block, poplex);
+ if (type == ";") return cont();
+ if (type == "if") {
+ if (cx.state.lexical.info == "else" && cx.state.cc[cx.state.cc.length - 1] == poplex)
+ cx.state.cc.pop()();
+ return cont(pushlex("form"), parenExpr, statement, poplex, maybeelse);
+ }
+ if (type == "function") return cont(functiondef);
+ if (type == "for") return cont(pushlex("form"), forspec, statement, poplex);
+ if (type == "variable") {
+ if (isTS && value == "type") {
+ cx.marked = "keyword"
+ return cont(typeexpr, expect("operator"), typeexpr, expect(";"));
+ } if (isTS && value == "declare") {
+ cx.marked = "keyword"
+ return cont(statement)
+ } else {
+ return cont(pushlex("stat"), maybelabel);
+ }
+ }
+ if (type == "switch") return cont(pushlex("form"), parenExpr, expect("{"), pushlex("}", "switch"),
+ block, poplex, poplex);
+ if (type == "case") return cont(expression, expect(":"));
+ if (type == "default") return cont(expect(":"));
+ if (type == "catch") return cont(pushlex("form"), pushcontext, expect("("), funarg, expect(")"),
+ statement, poplex, popcontext);
+ if (type == "class") return cont(pushlex("form"), className, poplex);
+ if (type == "export") return cont(pushlex("stat"), afterExport, poplex);
+ if (type == "import") return cont(pushlex("stat"), afterImport, poplex);
+ if (type == "module") return cont(pushlex("form"), pattern, expect("{"), pushlex("}"), block, poplex, poplex)
+ if (type == "async") return cont(statement)
+ if (value == "@") return cont(expression, statement)
+ return pass(pushlex("stat"), expression, expect(";"), poplex);
+ }
+ function expression(type) {
+ return expressionInner(type, false);
+ }
+ function expressionNoComma(type) {
+ return expressionInner(type, true);
+ }
+ function parenExpr(type) {
+ if (type != "(") return pass()
+ return cont(pushlex(")"), expression, expect(")"), poplex)
+ }
+ function expressionInner(type, noComma) {
+ if (cx.state.fatArrowAt == cx.stream.start) {
+ var body = noComma ? arrowBodyNoComma : arrowBody;
+ if (type == "(") return cont(pushcontext, pushlex(")"), commasep(funarg, ")"), poplex, expect("=>"), body, popcontext);
+ else if (type == "variable") return pass(pushcontext, pattern, expect("=>"), body, popcontext);
+ }
+
+ var maybeop = noComma ? maybeoperatorNoComma : maybeoperatorComma;
+ if (atomicTypes.hasOwnProperty(type)) return cont(maybeop);
+ if (type == "function") return cont(functiondef, maybeop);
+ if (type == "class") return cont(pushlex("form"), classExpression, poplex);
+ if (type == "keyword c" || type == "async") return cont(noComma ? maybeexpressionNoComma : maybeexpression);
+ if (type == "(") return cont(pushlex(")"), maybeexpression, expect(")"), poplex, maybeop);
+ if (type == "operator" || type == "spread") return cont(noComma ? expressionNoComma : expression);
+ if (type == "[") return cont(pushlex("]"), arrayLiteral, poplex, maybeop);
+ if (type == "{") return contCommasep(objprop, "}", null, maybeop);
+ if (type == "quasi") return pass(quasi, maybeop);
+ if (type == "new") return cont(maybeTarget(noComma));
+ return cont();
+ }
+ function maybeexpression(type) {
+ if (type.match(/[;\}\)\],]/)) return pass();
+ return pass(expression);
+ }
+ function maybeexpressionNoComma(type) {
+ if (type.match(/[;\}\)\],]/)) return pass();
+ return pass(expressionNoComma);
+ }
+
+ function maybeoperatorComma(type, value) {
+ if (type == ",") return cont(expression);
+ return maybeoperatorNoComma(type, value, false);
+ }
+ function maybeoperatorNoComma(type, value, noComma) {
+ var me = noComma == false ? maybeoperatorComma : maybeoperatorNoComma;
+ var expr = noComma == false ? expression : expressionNoComma;
+ if (type == "=>") return cont(pushcontext, noComma ? arrowBodyNoComma : arrowBody, popcontext);
+ if (type == "operator") {
+ if (/\+\+|--/.test(value) || isTS && value == "!") return cont(me);
+ if (value == "?") return cont(expression, expect(":"), expr);
+ return cont(expr);
+ }
+ if (type == "quasi") { return pass(quasi, me); }
+ if (type == ";") return;
+ if (type == "(") return contCommasep(expressionNoComma, ")", "call", me);
+ if (type == ".") return cont(property, me);
+ if (type == "[") return cont(pushlex("]"), maybeexpression, expect("]"), poplex, me);
+ if (isTS && value == "as") { cx.marked = "keyword"; return cont(typeexpr, me) }
+ if (type == "regexp") {
+ cx.state.lastType = cx.marked = "operator"
+ cx.stream.backUp(cx.stream.pos - cx.stream.start - 1)
+ return cont(expr)
+ }
+ }
+ function quasi(type, value) {
+ if (type != "quasi") return pass();
+ if (value.slice(value.length - 2) != "${") return cont(quasi);
+ return cont(expression, continueQuasi);
+ }
+ function continueQuasi(type) {
+ if (type == "}") {
+ cx.marked = "string-2";
+ cx.state.tokenize = tokenQuasi;
+ return cont(quasi);
+ }
+ }
+ function arrowBody(type) {
+ findFatArrow(cx.stream, cx.state);
+ return pass(type == "{" ? statement : expression);
+ }
+ function arrowBodyNoComma(type) {
+ findFatArrow(cx.stream, cx.state);
+ return pass(type == "{" ? statement : expressionNoComma);
+ }
+ function maybeTarget(noComma) {
+ return function(type) {
+ if (type == ".") return cont(noComma ? targetNoComma : target);
+ else if (type == "variable" && isTS) return cont(maybeTypeArgs, noComma ? maybeoperatorNoComma : maybeoperatorComma)
+ else return pass(noComma ? expressionNoComma : expression);
+ };
+ }
+ function target(_, value) {
+ if (value == "target") { cx.marked = "keyword"; return cont(maybeoperatorComma); }
+ }
+ function targetNoComma(_, value) {
+ if (value == "target") { cx.marked = "keyword"; return cont(maybeoperatorNoComma); }
+ }
+ function maybelabel(type) {
+ if (type == ":") return cont(poplex, statement);
+ return pass(maybeoperatorComma, expect(";"), poplex);
+ }
+ function property(type) {
+ if (type == "variable") {cx.marked = "property"; return cont();}
+ }
+ function objprop(type, value) {
+ if (type == "async") {
+ cx.marked = "property";
+ return cont(objprop);
+ } else if (type == "variable" || cx.style == "keyword") {
+ cx.marked = "property";
+ if (value == "get" || value == "set") return cont(getterSetter);
+ var m // Work around fat-arrow-detection complication for detecting typescript typed arrow params
+ if (isTS && cx.state.fatArrowAt == cx.stream.start && (m = cx.stream.match(/^\s*:\s*/, false)))
+ cx.state.fatArrowAt = cx.stream.pos + m[0].length
+ return cont(afterprop);
+ } else if (type == "number" || type == "string") {
+ cx.marked = jsonldMode ? "property" : (cx.style + " property");
+ return cont(afterprop);
+ } else if (type == "jsonld-keyword") {
+ return cont(afterprop);
+ } else if (type == "modifier") {
+ return cont(objprop)
+ } else if (type == "[") {
+ return cont(expression, expect("]"), afterprop);
+ } else if (type == "spread") {
+ return cont(expression, afterprop);
+ } else if (type == ":") {
+ return pass(afterprop)
+ }
+ }
+ function getterSetter(type) {
+ if (type != "variable") return pass(afterprop);
+ cx.marked = "property";
+ return cont(functiondef);
+ }
+ function afterprop(type) {
+ if (type == ":") return cont(expressionNoComma);
+ if (type == "(") return pass(functiondef);
+ }
+ function commasep(what, end, sep) {
+ function proceed(type, value) {
+ if (sep ? sep.indexOf(type) > -1 : type == ",") {
+ var lex = cx.state.lexical;
+ if (lex.info == "call") lex.pos = (lex.pos || 0) + 1;
+ return cont(function(type, value) {
+ if (type == end || value == end) return pass()
+ return pass(what)
+ }, proceed);
+ }
+ if (type == end || value == end) return cont();
+ return cont(expect(end));
+ }
+ return function(type, value) {
+ if (type == end || value == end) return cont();
+ return pass(what, proceed);
+ };
+ }
+ function contCommasep(what, end, info) {
+ for (var i = 3; i < arguments.length; i++)
+ cx.cc.push(arguments[i]);
+ return cont(pushlex(end, info), commasep(what, end), poplex);
+ }
+ function block(type) {
+ if (type == "}") return cont();
+ return pass(statement, block);
+ }
+ function maybetype(type, value) {
+ if (isTS) {
+ if (type == ":") return cont(typeexpr);
+ if (value == "?") return cont(maybetype);
+ }
+ }
+ function typeexpr(type, value) {
+ if (type == "variable") {
+ if (value == "keyof") {
+ cx.marked = "keyword"
+ return cont(typeexpr)
+ } else {
+ cx.marked = "type"
+ return cont(afterType)
+ }
+ }
+ if (type == "string" || type == "number" || type == "atom") return cont(afterType);
+ if (type == "[") return cont(pushlex("]"), commasep(typeexpr, "]", ","), poplex, afterType)
+ if (type == "{") return cont(pushlex("}"), commasep(typeprop, "}", ",;"), poplex, afterType)
+ if (type == "(") return cont(commasep(typearg, ")"), maybeReturnType)
+ }
+ function maybeReturnType(type) {
+ if (type == "=>") return cont(typeexpr)
+ }
+ function typeprop(type, value) {
+ if (type == "variable" || cx.style == "keyword") {
+ cx.marked = "property"
+ return cont(typeprop)
+ } else if (value == "?") {
+ return cont(typeprop)
+ } else if (type == ":") {
+ return cont(typeexpr)
+ } else if (type == "[") {
+ return cont(expression, maybetype, expect("]"), typeprop)
+ }
+ }
+ function typearg(type) {
+ if (type == "variable") return cont(typearg)
+ else if (type == ":") return cont(typeexpr)
+ }
+ function afterType(type, value) {
+ if (value == "<") return cont(pushlex(">"), commasep(typeexpr, ">"), poplex, afterType)
+ if (value == "|" || type == ".") return cont(typeexpr)
+ if (type == "[") return cont(expect("]"), afterType)
+ if (value == "extends") return cont(typeexpr)
+ }
+ function maybeTypeArgs(_, value) {
+ if (value == "<") return cont(pushlex(">"), commasep(typeexpr, ">"), poplex, afterType)
+ }
+ function vardef() {
+ return pass(pattern, maybetype, maybeAssign, vardefCont);
+ }
+ function pattern(type, value) {
+ if (type == "modifier") return cont(pattern)
+ if (type == "variable") { register(value); return cont(); }
+ if (type == "spread") return cont(pattern);
+ if (type == "[") return contCommasep(pattern, "]");
+ if (type == "{") return contCommasep(proppattern, "}");
+ }
+ function proppattern(type, value) {
+ if (type == "variable" && !cx.stream.match(/^\s*:/, false)) {
+ register(value);
+ return cont(maybeAssign);
+ }
+ if (type == "variable") cx.marked = "property";
+ if (type == "spread") return cont(pattern);
+ if (type == "}") return pass();
+ return cont(expect(":"), pattern, maybeAssign);
+ }
+ function maybeAssign(_type, value) {
+ if (value == "=") return cont(expressionNoComma);
+ }
+ function vardefCont(type) {
+ if (type == ",") return cont(vardef);
+ }
+ function maybeelse(type, value) {
+ if (type == "keyword b" && value == "else") return cont(pushlex("form", "else"), statement, poplex);
+ }
+ function forspec(type) {
+ if (type == "(") return cont(pushlex(")"), forspec1, expect(")"), poplex);
+ }
+ function forspec1(type) {
+ if (type == "var") return cont(vardef, expect(";"), forspec2);
+ if (type == ";") return cont(forspec2);
+ if (type == "variable") return cont(formaybeinof);
+ return pass(expression, expect(";"), forspec2);
+ }
+ function formaybeinof(_type, value) {
+ if (value == "in" || value == "of") { cx.marked = "keyword"; return cont(expression); }
+ return cont(maybeoperatorComma, forspec2);
+ }
+ function forspec2(type, value) {
+ if (type == ";") return cont(forspec3);
+ if (value == "in" || value == "of") { cx.marked = "keyword"; return cont(expression); }
+ return pass(expression, expect(";"), forspec3);
+ }
+ function forspec3(type) {
+ if (type != ")") cont(expression);
+ }
+ function functiondef(type, value) {
+ if (value == "*") {cx.marked = "keyword"; return cont(functiondef);}
+ if (type == "variable") {register(value); return cont(functiondef);}
+ if (type == "(") return cont(pushcontext, pushlex(")"), commasep(funarg, ")"), poplex, maybetype, statement, popcontext);
+ if (isTS && value == "<") return cont(pushlex(">"), commasep(typeexpr, ">"), poplex, functiondef)
+ }
+ function funarg(type, value) {
+ if (value == "@") cont(expression, funarg)
+ if (type == "spread" || type == "modifier") return cont(funarg);
+ return pass(pattern, maybetype, maybeAssign);
+ }
+ function classExpression(type, value) {
+ // Class expressions may have an optional name.
+ if (type == "variable") return className(type, value);
+ return classNameAfter(type, value);
+ }
+ function className(type, value) {
+ if (type == "variable") {register(value); return cont(classNameAfter);}
+ }
+ function classNameAfter(type, value) {
+ if (value == "<") return cont(pushlex(">"), commasep(typeexpr, ">"), poplex, classNameAfter)
+ if (value == "extends" || value == "implements" || (isTS && type == ","))
+ return cont(isTS ? typeexpr : expression, classNameAfter);
+ if (type == "{") return cont(pushlex("}"), classBody, poplex);
+ }
+ function classBody(type, value) {
+ if (type == "modifier" || type == "async" ||
+ (type == "variable" &&
+ (value == "static" || value == "get" || value == "set") &&
+ cx.stream.match(/^\s+[\w$\xa1-\uffff]/, false))) {
+ cx.marked = "keyword";
+ return cont(classBody);
+ }
+ if (type == "variable" || cx.style == "keyword") {
+ cx.marked = "property";
+ return cont(isTS ? classfield : functiondef, classBody);
+ }
+ if (type == "[")
+ return cont(expression, expect("]"), isTS ? classfield : functiondef, classBody)
+ if (value == "*") {
+ cx.marked = "keyword";
+ return cont(classBody);
+ }
+ if (type == ";") return cont(classBody);
+ if (type == "}") return cont();
+ if (value == "@") return cont(expression, classBody)
+ }
+ function classfield(type, value) {
+ if (value == "?") return cont(classfield)
+ if (type == ":") return cont(typeexpr, maybeAssign)
+ if (value == "=") return cont(expressionNoComma)
+ return pass(functiondef)
+ }
+ function afterExport(type, value) {
+ if (value == "*") { cx.marked = "keyword"; return cont(maybeFrom, expect(";")); }
+ if (value == "default") { cx.marked = "keyword"; return cont(expression, expect(";")); }
+ if (type == "{") return cont(commasep(exportField, "}"), maybeFrom, expect(";"));
+ return pass(statement);
+ }
+ function exportField(type, value) {
+ if (value == "as") { cx.marked = "keyword"; return cont(expect("variable")); }
+ if (type == "variable") return pass(expressionNoComma, exportField);
+ }
+ function afterImport(type) {
+ if (type == "string") return cont();
+ return pass(importSpec, maybeMoreImports, maybeFrom);
+ }
+ function importSpec(type, value) {
+ if (type == "{") return contCommasep(importSpec, "}");
+ if (type == "variable") register(value);
+ if (value == "*") cx.marked = "keyword";
+ return cont(maybeAs);
+ }
+ function maybeMoreImports(type) {
+ if (type == ",") return cont(importSpec, maybeMoreImports)
+ }
+ function maybeAs(_type, value) {
+ if (value == "as") { cx.marked = "keyword"; return cont(importSpec); }
+ }
+ function maybeFrom(_type, value) {
+ if (value == "from") { cx.marked = "keyword"; return cont(expression); }
+ }
+ function arrayLiteral(type) {
+ if (type == "]") return cont();
+ return pass(commasep(expressionNoComma, "]"));
+ }
+
+ function isContinuedStatement(state, textAfter) {
+ return state.lastType == "operator" || state.lastType == "," ||
+ isOperatorChar.test(textAfter.charAt(0)) ||
+ /[,.]/.test(textAfter.charAt(0));
+ }
+
+ function expressionAllowed(stream, state, backUp) {
+ return state.tokenize == tokenBase &&
+ /^(?:operator|sof|keyword [bc]|case|new|export|default|spread|[\[{}\(,;:]|=>)$/.test(state.lastType) ||
+ (state.lastType == "quasi" && /\{\s*$/.test(stream.string.slice(0, stream.pos - (backUp || 0))))
+ }
+
+ // Interface
+
+ return {
+ startState: function(basecolumn) {
+ var state = {
+ tokenize: tokenBase,
+ lastType: "sof",
+ cc: [],
+ lexical: new JSLexical((basecolumn || 0) - indentUnit, 0, "block", false),
+ localVars: parserConfig.localVars,
+ context: parserConfig.localVars && {vars: parserConfig.localVars},
+ indented: basecolumn || 0
+ };
+ if (parserConfig.globalVars && typeof parserConfig.globalVars == "object")
+ state.globalVars = parserConfig.globalVars;
+ return state;
+ },
+
+ token: function(stream, state) {
+ if (stream.sol()) {
+ if (!state.lexical.hasOwnProperty("align"))
+ state.lexical.align = false;
+ state.indented = stream.indentation();
+ findFatArrow(stream, state);
+ }
+ if (state.tokenize != tokenComment && stream.eatSpace()) return null;
+ var style = state.tokenize(stream, state);
+ if (type == "comment") return style;
+ state.lastType = type == "operator" && (content == "++" || content == "--") ? "incdec" : type;
+ return parseJS(state, style, type, content, stream);
+ },
+
+ indent: function(state, textAfter) {
+ if (state.tokenize == tokenComment) return CodeMirror.Pass;
+ if (state.tokenize != tokenBase) return 0;
+ var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical, top
+ // Kludge to prevent 'maybelse' from blocking lexical scope pops
+ if (!/^\s*else\b/.test(textAfter)) for (var i = state.cc.length - 1; i >= 0; --i) {
+ var c = state.cc[i];
+ if (c == poplex) lexical = lexical.prev;
+ else if (c != maybeelse) break;
+ }
+ while ((lexical.type == "stat" || lexical.type == "form") &&
+ (firstChar == "}" || ((top = state.cc[state.cc.length - 1]) &&
+ (top == maybeoperatorComma || top == maybeoperatorNoComma) &&
+ !/^[,\.=+\-*:?[\(]/.test(textAfter))))
+ lexical = lexical.prev;
+ if (statementIndent && lexical.type == ")" && lexical.prev.type == "stat")
+ lexical = lexical.prev;
+ var type = lexical.type, closing = firstChar == type;
+
+ if (type == "vardef") return lexical.indented + (state.lastType == "operator" || state.lastType == "," ? lexical.info + 1 : 0);
+ else if (type == "form" && firstChar == "{") return lexical.indented;
+ else if (type == "form") return lexical.indented + indentUnit;
+ else if (type == "stat")
+ return lexical.indented + (isContinuedStatement(state, textAfter) ? statementIndent || indentUnit : 0);
+ else if (lexical.info == "switch" && !closing && parserConfig.doubleIndentSwitch != false)
+ return lexical.indented + (/^(?:case|default)\b/.test(textAfter) ? indentUnit : 2 * indentUnit);
+ else if (lexical.align) return lexical.column + (closing ? 0 : 1);
+ else return lexical.indented + (closing ? 0 : indentUnit);
+ },
+
+ electricInput: /^\s*(?:case .*?:|default:|\{|\})$/,
+ blockCommentStart: jsonMode ? null : "/*",
+ blockCommentEnd: jsonMode ? null : "*/",
+ lineComment: jsonMode ? null : "//",
+ fold: "brace",
+ closeBrackets: "()[]{}''\"\"``",
+
+ helperType: jsonMode ? "json" : "javascript",
+ jsonldMode: jsonldMode,
+ jsonMode: jsonMode,
+
+ expressionAllowed: expressionAllowed,
+
+ skipExpression: function(state) {
+ var top = state.cc[state.cc.length - 1]
+ if (top == expression || top == expressionNoComma) state.cc.pop()
+ }
+ };
+});
+
+CodeMirror.registerHelper("wordChars", "javascript", /[\w$]/);
+
+CodeMirror.defineMIME("text/javascript", "javascript");
+CodeMirror.defineMIME("text/ecmascript", "javascript");
+CodeMirror.defineMIME("application/javascript", "javascript");
+CodeMirror.defineMIME("application/x-javascript", "javascript");
+CodeMirror.defineMIME("application/ecmascript", "javascript");
+CodeMirror.defineMIME("application/json", {name: "javascript", json: true});
+CodeMirror.defineMIME("application/x-json", {name: "javascript", json: true});
+CodeMirror.defineMIME("application/ld+json", {name: "javascript", jsonld: true});
+CodeMirror.defineMIME("text/typescript", { name: "javascript", typescript: true });
+CodeMirror.defineMIME("application/typescript", { name: "javascript", typescript: true });
+
+});
diff --git a/demo/third_party/split/horizontal.png b/demo/third_party/split/horizontal.png
new file mode 100644
index 00000000..cbe7da77
--- /dev/null
+++ b/demo/third_party/split/horizontal.png
Binary files differ
diff --git a/demo/third_party/split/split.min.js b/demo/third_party/split/split.min.js
new file mode 100644
index 00000000..022f808d
--- /dev/null
+++ b/demo/third_party/split/split.min.js
@@ -0,0 +1,5 @@
+/*! Split.js - v1.3.5
+ * Copyright (c) 2017 Nathan Cahill
+ * MIT https://github.com/nathancahill/Split.js/blob/master/LICENSE.txt
+ */
+!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.Split=t()}(this,function(){"use strict";var e=window,t=e.document,n="addEventListener",i="removeEventListener",r="getBoundingClientRect",s=function(){return!1},o=e.attachEvent&&!e[n],a=["","-webkit-","-moz-","-o-"].filter(function(e){var n=t.createElement("div");return n.style.cssText="width:"+e+"calc(9px)",!!n.style.length}).shift()+"calc",l=function(e){return"string"==typeof e||e instanceof String?t.querySelector(e):e};return function(u,c){function z(e,t,n){var i=A(y,t,n);Object.keys(i).forEach(function(t){return e.style[t]=i[t]})}function h(e,t){var n=B(y,t);Object.keys(n).forEach(function(t){return e.style[t]=n[t]})}function f(e){var t=E[this.a],n=E[this.b],i=t.size+n.size;t.size=e/this.size*i,n.size=i-e/this.size*i,z(t.element,t.size,this.aGutterSize),z(n.element,n.size,this.bGutterSize)}function m(e){var t;this.dragging&&((t="touches"in e?e.touches[0][b]-this.start:e[b]-this.start)<=E[this.a].minSize+M+this.aGutterSize?t=E[this.a].minSize+this.aGutterSize:t>=this.size-(E[this.b].minSize+M+this.bGutterSize)&&(t=this.size-(E[this.b].minSize+this.bGutterSize)),f.call(this,t),c.onDrag&&c.onDrag())}function g(){var e=E[this.a].element,t=E[this.b].element;this.size=e[r]()[y]+t[r]()[y]+this.aGutterSize+this.bGutterSize,this.start=e[r]()[G]}function d(){var t=this,n=E[t.a].element,r=E[t.b].element;t.dragging&&c.onDragEnd&&c.onDragEnd(),t.dragging=!1,e[i]("mouseup",t.stop),e[i]("touchend",t.stop),e[i]("touchcancel",t.stop),t.parent[i]("mousemove",t.move),t.parent[i]("touchmove",t.move),delete t.stop,delete t.move,n[i]("selectstart",s),n[i]("dragstart",s),r[i]("selectstart",s),r[i]("dragstart",s),n.style.userSelect="",n.style.webkitUserSelect="",n.style.MozUserSelect="",n.style.pointerEvents="",r.style.userSelect="",r.style.webkitUserSelect="",r.style.MozUserSelect="",r.style.pointerEvents="",t.gutter.style.cursor="",t.parent.style.cursor=""}function S(t){var i=this,r=E[i.a].element,o=E[i.b].element;!i.dragging&&c.onDragStart&&c.onDragStart(),t.preventDefault(),i.dragging=!0,i.move=m.bind(i),i.stop=d.bind(i),e[n]("mouseup",i.stop),e[n]("touchend",i.stop),e[n]("touchcancel",i.stop),i.parent[n]("mousemove",i.move),i.parent[n]("touchmove",i.move),r[n]("selectstart",s),r[n]("dragstart",s),o[n]("selectstart",s),o[n]("dragstart",s),r.style.userSelect="none",r.style.webkitUserSelect="none",r.style.MozUserSelect="none",r.style.pointerEvents="none",o.style.userSelect="none",o.style.webkitUserSelect="none",o.style.MozUserSelect="none",o.style.pointerEvents="none",i.gutter.style.cursor=j,i.parent.style.cursor=j,g.call(i)}function v(e){e.forEach(function(t,n){if(n>0){var i=F[n-1],r=E[i.a],s=E[i.b];r.size=e[n-1],s.size=t,z(r.element,r.size,i.aGutterSize),z(s.element,s.size,i.bGutterSize)}})}function p(){F.forEach(function(e){e.parent.removeChild(e.gutter),E[e.a].element.style[y]="",E[e.b].element.style[y]=""})}void 0===c&&(c={});var y,b,G,E,w=l(u[0]).parentNode,D=e.getComputedStyle(w).flexDirection,U=c.sizes||u.map(function(){return 100/u.length}),k=void 0!==c.minSize?c.minSize:100,x=Array.isArray(k)?k:u.map(function(){return k}),L=void 0!==c.gutterSize?c.gutterSize:10,M=void 0!==c.snapOffset?c.snapOffset:30,O=c.direction||"horizontal",j=c.cursor||("horizontal"===O?"ew-resize":"ns-resize"),C=c.gutter||function(e,n){var i=t.createElement("div");return i.className="gutter gutter-"+n,i},A=c.elementStyle||function(e,t,n){var i={};return"string"==typeof t||t instanceof String?i[e]=t:i[e]=o?t+"%":a+"("+t+"% - "+n+"px)",i},B=c.gutterStyle||function(e,t){return n={},n[e]=t+"px",n;var n};"horizontal"===O?(y="width","clientWidth",b="clientX",G="left","paddingLeft"):"vertical"===O&&(y="height","clientHeight",b="clientY",G="top","paddingTop");var F=[];return E=u.map(function(e,t){var i,s={element:l(e),size:U[t],minSize:x[t]};if(t>0&&(i={a:t-1,b:t,dragging:!1,isFirst:1===t,isLast:t===u.length-1,direction:O,parent:w},i.aGutterSize=L,i.bGutterSize=L,i.isFirst&&(i.aGutterSize=L/2),i.isLast&&(i.bGutterSize=L/2),"row-reverse"===D||"column-reverse"===D)){var a=i.a;i.a=i.b,i.b=a}if(!o&&t>0){var c=C(t,O);h(c,L),c[n]("mousedown",S.bind(i)),c[n]("touchstart",S.bind(i)),w.insertBefore(c,s.element),i.gutter=c}0===t||t===u.length-1?z(s.element,s.size,L/2):z(s.element,s.size,L);var f=s.element[r]()[y];return f<s.minSize&&(s.minSize=f),t>0&&F.push(i),s}),o?{setSizes:v,destroy:p}:{setSizes:v,getSizes:function(){return E.map(function(e){return e.size})},collapse:function(e){if(e===F.length){var t=F[e-1];g.call(t),o||f.call(t,t.size-t.bGutterSize)}else{var n=F[e];g.call(n),o||f.call(n,n.aGutterSize)}},destroy:p}}});
diff --git a/demo/third_party/split/vertical.png b/demo/third_party/split/vertical.png
new file mode 100644
index 00000000..0ac8fa1e
--- /dev/null
+++ b/demo/third_party/split/vertical.png
Binary files differ
diff --git a/demo/wasm2wat/index.html b/demo/wasm2wat/index.html
index d2de0eee..abc3b017 100644
--- a/demo/wasm2wat/index.html
+++ b/demo/wasm2wat/index.html
@@ -20,13 +20,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>wasm2wat demo</title>
<link href="../third_party/codemirror/codemirror.css" rel="stylesheet">
- <link href="../primer.css" rel="stylesheet">
<link href="../custom.css" rel="stylesheet">
</head>
<body>
- <div class="container">
+ <header>
<h1>wasm2wat demo</h1>
- <hr>
<p>WebAssembly has a
<a href="http://webassembly.github.io/spec/text/index.html">text format</a>
and a
@@ -37,34 +35,34 @@
Upload a WebAssembly binary file, and the text format will be displayed.
</p>
<div>
- <label>example:</label>
- <select id="select" class="form-select"></select>
- <button class="btn" type="button" id="upload">Upload</button>
- <input type="file" id="uploadInput" class="hidden"></a>
- <div>
- <input type="checkbox" id="generateNames" checked>
- <label for="generateNames">Generate Names</label>
- </div>
- <div>
- <input type="checkbox" id="foldExprs" checked>
- <label for="foldExprs">Fold Expressions</label>
- </div>
+ <p>
+ </p>
+ </div>
+ </header>
+ <main>
+ <div class="toolbar">
+ <input type="checkbox" id="generateNames" checked>
+ <label for="generateNames">Generate Names</label>
- <div>
- <input type="checkbox" id="inlineExport" checked>
- <label for="inlineExport">Inline Export</label>
- </div>
+ <input type="checkbox" id="foldExprs" checked>
+ <label for="foldExprs">Fold Expressions</label>
+
+ <input type="checkbox" id="inlineExport" checked>
+ <label for="inlineExport">Inline Export</label>
- <div>
- <input type="checkbox" id="readDebugNames" checked>
- <label for="readDebugNames">Read Debug Names</label>
+ <input type="checkbox" id="readDebugNames" checked>
+ <label for="readDebugNames">Read Debug Names</label>
+ <div class="right">
+ <input type="file" id="uploadInput" class="hidden"></a>
+ <label>example:</label>
+ <select id="select" class="form-select"></select>
+ <button class="btn" type="button" id="upload">Upload</button>
</div>
</div>
-
<textarea class="editor" autofocus autocomplete="off" autocorrect="off"
autocapitalize="off" spellcheck="false" hidden></textarea>
- </div>
+ </main>
<script src="../third_party/codemirror/codemirror.js"></script>
<script src="../third_party/codemirror/simple-mode.js"></script>
<script src="../wast-mode.js"></script>
diff --git a/demo/wat2wasm/demo.js b/demo/wat2wasm/demo.js
index 98cb3850..3b39ee3a 100644
--- a/demo/wat2wasm/demo.js
+++ b/demo/wat2wasm/demo.js
@@ -13,11 +13,19 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+Split(["#top-left", "#top-right"]);
+Split(["#bottom-left", "#bottom-right"]);
+
+Split(["#top-row", "#bottom-row"], {
+ direction: 'vertical'
+});
+
+wabt.ready.then(function () {
var kCompileMinMS = 100;
-var editorEl = document.querySelector('.editor');
var outputEl = document.getElementById('output');
+var jsLogEl = document.getElementById('js_log');
var selectEl = document.getElementById('select');
var downloadEl = document.getElementById('download');
var downloadLink = document.getElementById('downloadLink');
@@ -26,8 +34,27 @@ var binaryBlobUrl = null;
var wasmInstance = null;
-var options = {mode: 'wast', lineNumbers: true};
-var editor = CodeMirror.fromTextArea(editorEl, options);
+var wrappedConsole = Object.create(console);
+
+wrappedConsole.log = (...args) => {
+ let line = args.map(String).join('') + '\n';
+ jsLogEl.textContent += line;
+ console.log(...args);
+}
+
+var watEditor = CodeMirror((elt) => {
+ document.getElementById('top-left').appendChild(elt);
+}, {
+ mode: 'wast',
+ lineNumbers: true,
+});
+
+var jsEditor = CodeMirror((elt) => {
+ document.getElementById('bottom-left').appendChild(elt);
+}, {
+ mode: 'javascript',
+ lineNumbers: true,
+});
function debounce(f, wait) {
var lastTime = 0;
@@ -48,43 +75,53 @@ function debounce(f, wait) {
return wrapped;
}
-function compile(text) {
- wabt.ready.then(function() {
- outputEl.textContent = '';
- try {
- var module = wabt.parseWat('test.wast', text);
- module.resolveNames();
- module.validate();
- var binaryOutput = module.toBinary({log: true});
- outputEl.textContent = binaryOutput.log;
- binaryBuffer = binaryOutput.buffer;
- var blob = new Blob([binaryOutput.buffer]);
- if (binaryBlobUrl) {
- URL.revokeObjectURL(binaryBlobUrl);
- }
- binaryBlobUrl = URL.createObjectURL(blob);
- downloadLink.setAttribute('href', binaryBlobUrl);
- downloadEl.classList.remove('disabled');
- } catch (e) {
- outputEl.textContent += e.toString();
- downloadEl.classList.add('disabled');
- } finally {
- if (module) module.destroy();
+function compile() {
+ outputEl.textContent = '';
+ var binaryOutput;
+ try {
+ var module = wabt.parseWat('test.wast', watEditor.getValue());
+ module.resolveNames();
+ module.validate();
+ var binaryOutput = module.toBinary({log: true});
+ outputEl.textContent = binaryOutput.log;
+ binaryBuffer = binaryOutput.buffer;
+ var blob = new Blob([binaryOutput.buffer]);
+ if (binaryBlobUrl) {
+ URL.revokeObjectURL(binaryBlobUrl);
}
- });
+ binaryBlobUrl = URL.createObjectURL(blob);
+ downloadLink.setAttribute('href', binaryBlobUrl);
+ downloadEl.classList.remove('disabled');
+ } catch (e) {
+ outputEl.textContent += e.toString();
+ downloadEl.classList.add('disabled');
+ } finally {
+ if (module) module.destroy();
+ }
}
-var compileInput =
- debounce(function() { compile(editor.getValue()); }, kCompileMinMS);
-
-function onEditorChange(e) {
- compileInput();
+function run() {
+ jsLogEl.textContent = '';
+ if (binaryBuffer === null) return;
+ try {
+ let wasm = new WebAssembly.Module(binaryBuffer);
+ let js = jsEditor.getValue();
+ let fn = new Function('wasmModule', 'console', js + '//# sourceURL=demo.js');
+ fn(wasm, wrappedConsole);
+ } catch (e) {
+ jsLogEl.textContent += String(e);
+ }
}
+var onWatChange = debounce(compile, kCompileMinMS);
+var onJsChange = debounce(run, kCompileMinMS);
+
function setExample(index) {
- var contents = examples[index].contents;
- editor.setValue(contents);
- compileInput();
+ var example = examples[index];
+ watEditor.setValue(example.contents);
+ onWatChange();
+ jsEditor.setValue(example.js);
+ onJsChange();
}
function onSelectChanged(e) {
@@ -101,7 +138,8 @@ function onDownloadClicked(e) {
downloadLink.dispatchEvent(event);
}
-editor.on('change', onEditorChange);
+watEditor.on('change', onWatChange);
+jsEditor.on('change', onJsChange);
selectEl.addEventListener('change', onSelectChanged);
downloadEl.addEventListener('click', onDownloadClicked);
@@ -113,3 +151,5 @@ for (var i = 0; i < examples.length; ++i) {
}
selectEl.selectedIndex = 1;
setExample(selectEl.selectedIndex);
+
+});
diff --git a/demo/wat2wasm/examples.js b/demo/wat2wasm/examples.js
index 05f07571..901b5da8 100644
--- a/demo/wat2wasm/examples.js
+++ b/demo/wat2wasm/examples.js
@@ -17,54 +17,79 @@
var examples = [
{
name: 'empty',
- contents: '(module)'
+ contents: '(module)',
+ js: '',
},
{
name: 'simple',
contents:
- '(module\n' +
- ' (func $addTwo (param i32 i32) (result i32)\n' +
- ' get_local 0\n' +
- ' get_local 1\n' +
- ' i32.add)\n' +
- ' (export "addTwo" (func $addTwo)))\n'
+`(module
+ (func $addTwo (param i32 i32) (result i32)
+ get_local 0
+ get_local 1
+ i32.add)
+ (export "addTwo" (func $addTwo)))
+`,
+ js:
+`const wasmInstance =
+ new WebAssembly.Instance(wasmModule, {});
+const { addTwo } = wasmInstance.exports;
+for (let i = 0; i < 10; i++) {
+ console.log(addTwo(i, i));
+}
+`,
},
{
name: 'factorial',
contents:
- '(module\n' +
- ' (func $fac (param i64) (result i64)\n' +
- ' get_local 0\n' +
- ' i64.const 1\n' +
- ' i64.lt_s\n' +
- ' if (result i64)\n' +
- ' i64.const 1\n' +
- ' else\n' +
- ' get_local 0\n' +
- ' get_local 0\n' +
- ' i64.const 1\n' +
- ' i64.sub\n' +
- ' call $fac\n' +
- ' i64.mul\n' +
- ' end)\n' +
- ' (export "fac" (func $fac)))\n'
+`(module
+ (func $fac (param f64) (result f64)
+ get_local 0
+ f64.const 1
+ f64.lt
+ if (result f64)
+ f64.const 1
+ else
+ get_local 0
+ get_local 0
+ f64.const 1
+ f64.sub
+ call $fac
+ f64.mul
+ end)
+ (export "fac" (func $fac)))
+`,
+ js: `const wasmInstance =
+ new WebAssembly.Instance(wasmModule, {});
+const { fac } = wasmInstance.exports;
+for (let i = 1; i <= 15; i++) {
+ console.log(fac(i));
+}
+`,
},
{
name: 'stuff',
contents:
- '(module\n' +
- ' (import "foo" "bar" (func (param f32)))\n' +
- ' (memory (data "hi"))\n' +
- ' (type (func (param i32) (result i32)))\n' +
- ' (start 1)\n' +
- ' (table 0 1 anyfunc)\n' +
- ' (func)\n' +
- ' (func (type 1)\n' +
- ' i32.const 42\n' +
- ' drop)\n' +
- ' (export "e" (func 1)))\n'
+`(module
+ (import "foo" "bar" (func (param f32)))
+ (memory (data "hi"))
+ (type (func (param i32) (result i32)))
+ (start 1)
+ (table 0 1 anyfunc)
+ (func)
+ (func (type 1)
+ i32.const 42
+ drop)
+ (export "e" (func 1)))
+`,
+ js: `var wasmInstance = new WebAssembly.Instance(wasmModule, {
+ foo: {
+ bar() {}
+ },
+});
+`,
}
];
diff --git a/demo/wat2wasm/index.html b/demo/wat2wasm/index.html
index aca2405c..71946e89 100644
--- a/demo/wat2wasm/index.html
+++ b/demo/wat2wasm/index.html
@@ -20,13 +20,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>wat2wasm demo</title>
<link href="../third_party/codemirror/codemirror.css" rel="stylesheet">
- <link href="../primer.css" rel="stylesheet">
<link href="../custom.css" rel="stylesheet">
</head>
<body>
- <div class="container">
+ <header>
<h1>wat2wasm demo</h1>
- <hr>
<p>WebAssembly has a
<a href="http://webassembly.github.io/spec/text/index.html">text format</a>
and a
@@ -38,24 +36,41 @@
either show an error, or will show a log with a description of the
generated binary file.
</p>
- <div class="columns">
- <div class="two-fifths column">
- <textarea class="editor" autofocus autocomplete="off" autocorrect="off"
- autocapitalize="off" spellcheck="false" hidden></textarea>
- <div class="right">
- <label>example:</label>
- <select id="select" class="form-select"></select>
- <button class="btn disabled" type="button" id="download">Download</button>
- <a id="downloadLink" download="test.wasm" class="hidden"></a>
+ </header>
+ <main>
+ <div id="split-grid" class="split-grid">
+ <div id="top-row" class="split-vertical">
+ <div id="top-left" class="split split-horizontal">
+ <div class="toolbar">
+ WAT
+ <div class="right">
+ <label>example:</label>
+ <select id="select" class="form-select"></select>
+ <button class="btn disabled" type="button" id="download">Download</button>
+ <a id="downloadLink" download="test.wasm" class="hidden"></a>
+ </div>
+ </div>
+ </div>
+ <div id="top-right" class="split split-horizontal">
+ <pre id="output" class="output"></pre>
+ <div class="toolbar">BUILD LOG</div>
</div>
</div>
- <div class="three-fifths column">
- <pre id="output"></pre>
+ <div id="bottom-row" class="split-vertical">
+ <div id="bottom-left" class="split split-horizontal">
+ <div class="toolbar">JS</div>
+ </div>
+ <div id="bottom-right" class="split split-horizontal">
+ <pre id="js_log" class="output"></pre>
+ <div class="toolbar">JS LOG</div>
+ </div>
</div>
</div>
- </div>
+ </main>
+ <script src="../third_party/split/split.min.js"></script>
<script src="../third_party/codemirror/codemirror.js"></script>
<script src="../third_party/codemirror/simple-mode.js"></script>
+ <script src="../third_party/codemirror/javascript.js"></script>
<script src="../wast-mode.js"></script>
<script src="../libwabt.js"></script>
<script src="examples.js"></script>