From 44eae0493f99ac14bf0365f0936793558b86ad06 Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Tue, 3 Sep 2024 01:51:15 +0000 Subject: [PATCH] deploy --- 404.html | 30 + CNAME | 1 + assets/css/0.styles.6b61c7e6.css | 1 + assets/img/search.83621669.svg | 1 + assets/js/10.b593aa85.js | 1 + assets/js/11.e70694b8.js | 1 + assets/js/12.eac7b90f.js | 1 + assets/js/13.a23bc4f4.js | 1 + assets/js/14.38407d5c.js | 1 + assets/js/15.ccfb67c4.js | 1 + assets/js/16.9e12fbb3.js | 1 + assets/js/17.ebe32f37.js | 1 + assets/js/18.e8b2f77f.js | 1 + assets/js/19.70bbb3ef.js | 1 + assets/js/20.10384fec.js | 1 + assets/js/21.0ad30828.js | 1 + assets/js/22.79ff9157.js | 1 + assets/js/23.ed294d2e.js | 1 + assets/js/24.ee2d454f.js | 1 + assets/js/25.9eeadf53.js | 1 + assets/js/26.996ea7bb.js | 1 + assets/js/27.1ab1e33b.js | 1 + assets/js/28.d59826ef.js | 1 + assets/js/29.5e25dc01.js | 1 + assets/js/3.414e7e2a.js | 1 + assets/js/30.c82548b0.js | 1 + assets/js/31.0484fd41.js | 1 + assets/js/32.e1c049c4.js | 1 + assets/js/33.ef922419.js | 1 + assets/js/34.84298453.js | 1 + assets/js/35.6a11bf78.js | 1 + assets/js/36.8804f8bd.js | 1 + assets/js/37.753ca8da.js | 1 + assets/js/38.d5db98ff.js | 1 + assets/js/39.b8a07be0.js | 1 + assets/js/4.bff817ab.js | 1 + assets/js/40.c21571a5.js | 1 + assets/js/41.2d914f09.js | 1 + assets/js/42.5572b290.js | 1 + assets/js/43.588ad31d.js | 1 + assets/js/44.d8860d9e.js | 1 + assets/js/45.dc56303f.js | 1 + assets/js/46.b818906a.js | 1 + assets/js/47.ac22b9de.js | 1 + assets/js/48.6781072d.js | 1 + assets/js/49.9b1307dd.js | 1 + assets/js/5.18699eba.js | 1 + assets/js/50.89840f69.js | 1 + assets/js/51.b8879616.js | 1 + assets/js/52.c9e93d92.js | 1 + assets/js/53.d4b1a91b.js | 1 + assets/js/54.8151b7b4.js | 1 + assets/js/55.1fea72c5.js | 1 + assets/js/6.01d77bdc.js | 1 + assets/js/7.57813f7e.js | 1 + assets/js/8.c2cacdf2.js | 1 + assets/js/9.c701ed4b.js | 1 + assets/js/app.541c131e.js | 21 + assets/js/vendors~docsearch.2967e2f6.js | 3 + avatars/Alon_Zakai.png | Bin 0 -> 8896 bytes avatars/Peter_Salomonsen.png | Bin 0 -> 8169 bytes avatars/Surma.png | Bin 0 -> 5457 bytes basics.html | 43 ++ basics/environment/index.html | 43 ++ basics/exports-and-imports/index.html | 43 ++ basics/loader/index.html | 43 ++ basics/types/index.html | 43 ++ browserconfig.xml | 9 + built-with-assemblyscript.html | 161 +++++ builtins.html | 43 ++ compiler.html | 333 +++++++++ concepts.html | 195 ++++++ contributors.svg | 57 ++ debugging.html | 43 ++ details/compiler/index.html | 43 ++ details/debugging/index.html | 43 ++ details/index.html | 43 ++ details/interoperability/index.html | 43 ++ details/memory/index.html | 43 ++ details/peculiarities/index.html | 43 ++ details/portability/index.html | 43 ++ details/runtime/index.html | 43 ++ details/transforms/index.html | 43 ++ detauls/development/index.html | 43 ++ editor-test.html | 121 ++++ editor.html | 892 ++++++++++++++++++++++++ environment/index.html | 43 ++ examples.html | 81 +++ examples/arrays.html | 193 +++++ examples/game-of-life.html | 273 ++++++++ examples/interference.html | 179 +++++ examples/mandelbrot.html | 224 ++++++ examples/snippets.html | 332 +++++++++ exports-and-imports.html | 43 ++ extended-library/staticarray/index.html | 43 ++ faq/index.html | 43 ++ favicon.ico | Bin 0 -> 15086 bytes favicons/android-chrome-192x192.png | Bin 0 -> 2150 bytes favicons/android-chrome-512x512.png | Bin 0 -> 5642 bytes favicons/apple-touch-icon.png | Bin 0 -> 1976 bytes favicons/favicon-16x16.png | Bin 0 -> 441 bytes favicons/favicon-32x32.png | Bin 0 -> 587 bytes favicons/mstile-150x150.png | Bin 0 -> 1370 bytes favicons/safari-pinned-tab.svg | 1 + frequently-asked-questions.html | 77 ++ garbage-collection.html | 43 ++ getting-started.html | 135 ++++ images/chrome.svg | 1 + images/component-mismatch.svg | 4 + images/firefox.svg | 1 + images/game-of-life-preview.jpg | Bin 0 -> 198063 bytes images/header.svg | 12 + images/icon.png | Bin 0 -> 5962 bytes images/icon.svg | 4 + images/interference-preview.jpg | Bin 0 -> 97587 bytes images/logo.png | Bin 0 -> 17535 bytes images/logo.svg | 4 + images/managedobjectlayout.svg | 3 + images/mandelbrot-preview.jpg | Bin 0 -> 83794 bytes images/nodejs.svg | 1 + images/noimage.png | Bin 0 -> 549 bytes images/reference-hierarchy.svg | 4 + images/safari.svg | 1 + images/wasi-mismatch.svg | 4 + images/wasmer.svg | 5 + index.html | 79 +++ interoperability.html | 43 ++ introduction.html | 103 +++ loader.html | 43 ++ memory.html | 43 ++ portability.html | 43 ++ quick-start.html | 43 ++ robots.txt | 7 + runtime.html | 94 +++ scripts/wat.js | 713 +++++++++++++++++++ site.webmanifest | 19 + sitemap.xml | 1 + sponsors.svg | 55 ++ sponsors/battagline.svg | 1 + sponsors/chainsafeth.svg | 19 + sponsors/fastly.svg | 4 + sponsors/graphprotocol.svg | 10 + sponsors/nearprotocol.svg | 12 + sponsors/nearprotocol1.svg | 1 + sponsors/shopify.svg | 6 + standard-library/array/index.html | 43 ++ standard-library/arraybuffer/index.html | 43 ++ standard-library/dataview/index.html | 43 ++ standard-library/date/index.html | 43 ++ standard-library/error/index.html | 43 ++ standard-library/globals/index.html | 43 ++ standard-library/map/index.html | 43 ++ standard-library/math/index.html | 43 ++ standard-library/number/index.html | 43 ++ standard-library/set/index.html | 43 ++ standard-library/string/index.html | 43 ++ standard-library/typedarray/index.html | 43 ++ standards-objections.html | 80 +++ status.html | 110 +++ stdlib/array.html | 126 ++++ stdlib/arraybuffer.html | 90 +++ stdlib/console.html | 94 +++ stdlib/crypto.html | 86 +++ stdlib/dataview.html | 110 +++ stdlib/date.html | 120 ++++ stdlib/error.html | 90 +++ stdlib/globals.html | 255 +++++++ stdlib/heap.html | 89 +++ stdlib/map.html | 102 +++ stdlib/math.html | 130 ++++ stdlib/number.html | 104 +++ stdlib/process.html | 96 +++ stdlib/set.html | 93 +++ stdlib/staticarray.html | 117 ++++ stdlib/string.html | 128 ++++ stdlib/symbol.html | 89 +++ stdlib/typedarray.html | 114 +++ transforms.html | 43 ++ types.html | 128 ++++ 179 files changed, 8612 insertions(+) create mode 100644 404.html create mode 100644 CNAME create mode 100644 assets/css/0.styles.6b61c7e6.css create mode 100644 assets/img/search.83621669.svg create mode 100644 assets/js/10.b593aa85.js create mode 100644 assets/js/11.e70694b8.js create mode 100644 assets/js/12.eac7b90f.js create mode 100644 assets/js/13.a23bc4f4.js create mode 100644 assets/js/14.38407d5c.js create mode 100644 assets/js/15.ccfb67c4.js create mode 100644 assets/js/16.9e12fbb3.js create mode 100644 assets/js/17.ebe32f37.js create mode 100644 assets/js/18.e8b2f77f.js create mode 100644 assets/js/19.70bbb3ef.js create mode 100644 assets/js/20.10384fec.js create mode 100644 assets/js/21.0ad30828.js create mode 100644 assets/js/22.79ff9157.js create mode 100644 assets/js/23.ed294d2e.js create mode 100644 assets/js/24.ee2d454f.js create mode 100644 assets/js/25.9eeadf53.js create mode 100644 assets/js/26.996ea7bb.js create mode 100644 assets/js/27.1ab1e33b.js create mode 100644 assets/js/28.d59826ef.js create mode 100644 assets/js/29.5e25dc01.js create mode 100644 assets/js/3.414e7e2a.js create mode 100644 assets/js/30.c82548b0.js create mode 100644 assets/js/31.0484fd41.js create mode 100644 assets/js/32.e1c049c4.js create mode 100644 assets/js/33.ef922419.js create mode 100644 assets/js/34.84298453.js create mode 100644 assets/js/35.6a11bf78.js create mode 100644 assets/js/36.8804f8bd.js create mode 100644 assets/js/37.753ca8da.js create mode 100644 assets/js/38.d5db98ff.js create mode 100644 assets/js/39.b8a07be0.js create mode 100644 assets/js/4.bff817ab.js create mode 100644 assets/js/40.c21571a5.js create mode 100644 assets/js/41.2d914f09.js create mode 100644 assets/js/42.5572b290.js create mode 100644 assets/js/43.588ad31d.js create mode 100644 assets/js/44.d8860d9e.js create mode 100644 assets/js/45.dc56303f.js create mode 100644 assets/js/46.b818906a.js create mode 100644 assets/js/47.ac22b9de.js create mode 100644 assets/js/48.6781072d.js create mode 100644 assets/js/49.9b1307dd.js create mode 100644 assets/js/5.18699eba.js create mode 100644 assets/js/50.89840f69.js create mode 100644 assets/js/51.b8879616.js create mode 100644 assets/js/52.c9e93d92.js create mode 100644 assets/js/53.d4b1a91b.js create mode 100644 assets/js/54.8151b7b4.js create mode 100644 assets/js/55.1fea72c5.js create mode 100644 assets/js/6.01d77bdc.js create mode 100644 assets/js/7.57813f7e.js create mode 100644 assets/js/8.c2cacdf2.js create mode 100644 assets/js/9.c701ed4b.js create mode 100644 assets/js/app.541c131e.js create mode 100644 assets/js/vendors~docsearch.2967e2f6.js create mode 100644 avatars/Alon_Zakai.png create mode 100644 avatars/Peter_Salomonsen.png create mode 100644 avatars/Surma.png create mode 100644 basics.html create mode 100644 basics/environment/index.html create mode 100644 basics/exports-and-imports/index.html create mode 100644 basics/loader/index.html create mode 100644 basics/types/index.html create mode 100644 browserconfig.xml create mode 100644 built-with-assemblyscript.html create mode 100644 builtins.html create mode 100644 compiler.html create mode 100644 concepts.html create mode 100644 contributors.svg create mode 100644 debugging.html create mode 100644 details/compiler/index.html create mode 100644 details/debugging/index.html create mode 100644 details/index.html create mode 100644 details/interoperability/index.html create mode 100644 details/memory/index.html create mode 100644 details/peculiarities/index.html create mode 100644 details/portability/index.html create mode 100644 details/runtime/index.html create mode 100644 details/transforms/index.html create mode 100644 detauls/development/index.html create mode 100644 editor-test.html create mode 100644 editor.html create mode 100644 environment/index.html create mode 100644 examples.html create mode 100644 examples/arrays.html create mode 100644 examples/game-of-life.html create mode 100644 examples/interference.html create mode 100644 examples/mandelbrot.html create mode 100644 examples/snippets.html create mode 100644 exports-and-imports.html create mode 100644 extended-library/staticarray/index.html create mode 100644 faq/index.html create mode 100644 favicon.ico create mode 100644 favicons/android-chrome-192x192.png create mode 100644 favicons/android-chrome-512x512.png create mode 100644 favicons/apple-touch-icon.png create mode 100644 favicons/favicon-16x16.png create mode 100644 favicons/favicon-32x32.png create mode 100644 favicons/mstile-150x150.png create mode 100644 favicons/safari-pinned-tab.svg create mode 100644 frequently-asked-questions.html create mode 100644 garbage-collection.html create mode 100644 getting-started.html create mode 100644 images/chrome.svg create mode 100644 images/component-mismatch.svg create mode 100644 images/firefox.svg create mode 100644 images/game-of-life-preview.jpg create mode 100644 images/header.svg create mode 100644 images/icon.png create mode 100644 images/icon.svg create mode 100644 images/interference-preview.jpg create mode 100644 images/logo.png create mode 100644 images/logo.svg create mode 100644 images/managedobjectlayout.svg create mode 100644 images/mandelbrot-preview.jpg create mode 100644 images/nodejs.svg create mode 100644 images/noimage.png create mode 100644 images/reference-hierarchy.svg create mode 100644 images/safari.svg create mode 100644 images/wasi-mismatch.svg create mode 100644 images/wasmer.svg create mode 100644 index.html create mode 100644 interoperability.html create mode 100644 introduction.html create mode 100644 loader.html create mode 100644 memory.html create mode 100644 portability.html create mode 100644 quick-start.html create mode 100644 robots.txt create mode 100644 runtime.html create mode 100644 scripts/wat.js create mode 100644 site.webmanifest create mode 100644 sitemap.xml create mode 100644 sponsors.svg create mode 100644 sponsors/battagline.svg create mode 100644 sponsors/chainsafeth.svg create mode 100644 sponsors/fastly.svg create mode 100644 sponsors/graphprotocol.svg create mode 100644 sponsors/nearprotocol.svg create mode 100644 sponsors/nearprotocol1.svg create mode 100644 sponsors/shopify.svg create mode 100644 standard-library/array/index.html create mode 100644 standard-library/arraybuffer/index.html create mode 100644 standard-library/dataview/index.html create mode 100644 standard-library/date/index.html create mode 100644 standard-library/error/index.html create mode 100644 standard-library/globals/index.html create mode 100644 standard-library/map/index.html create mode 100644 standard-library/math/index.html create mode 100644 standard-library/number/index.html create mode 100644 standard-library/set/index.html create mode 100644 standard-library/string/index.html create mode 100644 standard-library/typedarray/index.html create mode 100644 standards-objections.html create mode 100644 status.html create mode 100644 stdlib/array.html create mode 100644 stdlib/arraybuffer.html create mode 100644 stdlib/console.html create mode 100644 stdlib/crypto.html create mode 100644 stdlib/dataview.html create mode 100644 stdlib/date.html create mode 100644 stdlib/error.html create mode 100644 stdlib/globals.html create mode 100644 stdlib/heap.html create mode 100644 stdlib/map.html create mode 100644 stdlib/math.html create mode 100644 stdlib/number.html create mode 100644 stdlib/process.html create mode 100644 stdlib/set.html create mode 100644 stdlib/staticarray.html create mode 100644 stdlib/string.html create mode 100644 stdlib/symbol.html create mode 100644 stdlib/typedarray.html create mode 100644 transforms.html create mode 100644 types.html diff --git a/404.html b/404.html new file mode 100644 index 000000000..99ced6733 --- /dev/null +++ b/404.html @@ -0,0 +1,30 @@ + + + + + + The AssemblyScript Book + + + + + + + + + + + + + + + + + + +

404

That's a Four-Oh-Four.
+ Take me home. +
+ + + diff --git a/CNAME b/CNAME new file mode 100644 index 000000000..c4945bd0f --- /dev/null +++ b/CNAME @@ -0,0 +1 @@ +www.assemblyscript.org diff --git a/assets/css/0.styles.6b61c7e6.css b/assets/css/0.styles.6b61c7e6.css new file mode 100644 index 000000000..de728ca3e --- /dev/null +++ b/assets/css/0.styles.6b61c7e6.css @@ -0,0 +1 @@ +code[class*=language-],pre[class*=language-]{color:#ccc;background:none;font-family:Consolas,Monaco,Andale Mono,Ubuntu Mono,monospace;font-size:1em;word-wrap:normal;line-height:1.5}:not(pre)>code[class*=language-],pre[class*=language-]{background:#2d2d2d}:not(pre)>code[class*=language-]{padding:.1em;border-radius:.3em;white-space:normal}.token.block-comment,.token.cdata,.token.comment,.token.doctype,.token.prolog{color:#999}.token.punctuation{color:#ccc}.token.attr-name,.token.deleted,.token.namespace,.token.tag{color:#e2777a}.token.function-name{color:#6196cc}.token.boolean,.token.function,.token.number{color:#f08d49}.token.class-name,.token.constant,.token.property,.token.symbol{color:#f8c555}.token.atrule,.token.builtin,.token.important,.token.keyword,.token.selector{color:#cc99cd}.token.attr-value,.token.char,.token.regex,.token.string,.token.variable{color:#7ec699}.token.entity,.token.operator,.token.url{color:#67cdcc}.token.entity{cursor:help}.token.inserted{color:green}code[class*=language-],pre[class*=language-]{color:#393a34;font-family:Consolas,Bitstream Vera Sans Mono,Courier New,Courier,monospace;direction:ltr;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;font-size:.9em;line-height:1.2em;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-ms-hyphens:none;hyphens:none}pre>code[class*=language-]{font-size:1em}code[class*=language-]::-moz-selection,code[class*=language-] ::-moz-selection,pre[class*=language-]::-moz-selection,pre[class*=language-] ::-moz-selection{background:#c1def1}code[class*=language-]::selection,code[class*=language-] ::selection,pre[class*=language-]::selection,pre[class*=language-] ::selection{background:#c1def1}pre[class*=language-]{padding:1em;margin:.5em 0;overflow:auto;border:1px solid #ddd;background-color:#fff}:not(pre)>code[class*=language-]{padding:1px .2em;background:#f8f8f8;border:1px solid #ddd}.token.cdata,.token.comment,.token.doctype,.token.prolog{color:green;font-style:italic}.token.namespace{opacity:.7}.token.string{color:#a31515}.token.operator,.token.punctuation{color:#393a34}.token.boolean,.token.constant,.token.inserted,.token.number,.token.symbol,.token.url,.token.variable{color:#36acaa}.language-autohotkey .token.selector,.language-json .token.boolean,.language-json .token.number,.token.atrule,.token.attr-value,.token.keyword,code[class*=language-css]{color:#00f}.token.function{color:#393a34}.language-autohotkey .token.tag,.token.deleted{color:#9a050f}.language-autohotkey .token.keyword,.token.selector{color:#00009f}.token.important{color:#e90}.token.bold,.token.important{font-weight:700}.token.italic{font-style:italic}.language-json .token.property,.token.class-name{color:#2b91af}.token.selector,.token.tag{color:maroon}.token.attr-name,.token.entity,.token.property,.token.regex{color:red}.token.directive.tag .tag{background:#ff0;color:#393a34}.line-numbers.line-numbers .line-numbers-rows{border-right-color:#a5a5a5}.line-numbers .line-numbers-rows>span:before{color:#2b91af}.line-highlight.line-highlight{background:rgba(193,222,241,.2);background:linear-gradient(90deg,rgba(193,222,241,.2) 70%,rgba(221,222,241,0))}.theme-default-content code{color:#476582;padding:.25rem .5rem;margin:0;font-size:.85em;background-color:rgba(27,31,35,.05);border-radius:3px}.theme-default-content code .token.deleted{color:#ec5975}.theme-default-content code .token.inserted{color:#007acc}.theme-default-content pre,.theme-default-content pre[class*=language-]{line-height:1.4;padding:1.25rem 1.5rem;margin:.85rem 0;background-color:#fff;border-radius:6px;overflow:auto}.theme-default-content pre[class*=language-] code,.theme-default-content pre code{color:#fff;padding:0;background-color:transparent;border-radius:0}div[class*=language-]{position:relative;background-color:#fff;border-radius:6px}div[class*=language-] .highlight-lines{-webkit-user-select:none;user-select:none;padding-top:1.3rem;position:absolute;top:0;left:0;width:100%;line-height:1.4}div[class*=language-] .highlight-lines .highlighted{background-color:rgba(0,0,0,.66)}div[class*=language-] pre,div[class*=language-] pre[class*=language-]{background:transparent;position:relative;z-index:1}div[class*=language-]:before{position:absolute;z-index:3;top:.8em;right:1em;font-size:.75rem;color:hsla(0,0%,100%,.4)}div[class*=language-]:not(.line-numbers-mode) .line-numbers-wrapper{display:none}div[class*=language-].line-numbers-mode .highlight-lines .highlighted{position:relative}div[class*=language-].line-numbers-mode .highlight-lines .highlighted:before{content:" ";position:absolute;z-index:3;left:0;top:0;display:block;width:3.5rem;height:100%;background-color:rgba(0,0,0,.66)}div[class*=language-].line-numbers-mode pre{padding-left:4.5rem;vertical-align:middle}div[class*=language-].line-numbers-mode .line-numbers-wrapper{position:absolute;top:0;width:3.5rem;text-align:center;color:hsla(0,0%,100%,.3);padding:1.25rem 0;line-height:1.4}div[class*=language-].line-numbers-mode .line-numbers-wrapper br{-webkit-user-select:none;user-select:none}div[class*=language-].line-numbers-mode .line-numbers-wrapper .line-number{position:relative;z-index:4;-webkit-user-select:none;user-select:none;font-size:.85em}div[class*=language-].line-numbers-mode:after{content:"";position:absolute;z-index:2;top:0;left:0;width:3.5rem;height:100%;border-radius:6px 0 0 6px;border-right:1px solid rgba(0,0,0,.66);background-color:#fff}div[class~=language-js]:before{content:"js"}div[class~=language-ts]:before{content:"ts"}div[class~=language-html]:before{content:"html"}div[class~=language-md]:before{content:"md"}div[class~=language-vue]:before{content:"vue"}div[class~=language-css]:before{content:"css"}div[class~=language-sass]:before{content:"sass"}div[class~=language-scss]:before{content:"scss"}div[class~=language-less]:before{content:"less"}div[class~=language-stylus]:before{content:"stylus"}div[class~=language-go]:before{content:"go"}div[class~=language-java]:before{content:"java"}div[class~=language-c]:before{content:"c"}div[class~=language-sh]:before{content:"sh"}div[class~=language-yaml]:before{content:"yaml"}div[class~=language-py]:before{content:"py"}div[class~=language-docker]:before{content:"docker"}div[class~=language-dockerfile]:before{content:"dockerfile"}div[class~=language-makefile]:before{content:"makefile"}div[class~=language-javascript]:before{content:"js"}div[class~=language-typescript]:before{content:"ts"}div[class~=language-markup]:before{content:"html"}div[class~=language-markdown]:before{content:"md"}div[class~=language-json]:before{content:"json"}div[class~=language-ruby]:before{content:"rb"}div[class~=language-python]:before{content:"py"}div[class~=language-bash]:before{content:"sh"}div[class~=language-php]:before{content:"php"}.custom-block .custom-block-title{font-weight:600;margin-bottom:-.4rem}.custom-block.danger,.custom-block.tip,.custom-block.warning{padding:.1rem 1.5rem;border-left-width:.5rem;border-left-style:solid;margin:1rem 0}.custom-block.tip{background-color:#f3f5f7;border-color:#42b983}.custom-block.warning{background-color:rgba(255,229,100,.3);border-color:#e7c000;color:#6b5900}.custom-block.warning .custom-block-title{color:#b29400}.custom-block.warning a{color:#2c3e50}.custom-block.danger{background-color:#ffe6e6;border-color:#c00;color:#4d0000}.custom-block.danger .custom-block-title{color:#900}.custom-block.danger a{color:#2c3e50}.custom-block.details{display:block;position:relative;border-radius:2px;margin:1.6em 0;padding:1.6em;background-color:#eee}.custom-block.details h4{margin-top:0}.custom-block.details figure:last-child,.custom-block.details p:last-child{margin-bottom:0;padding-bottom:0}.custom-block.details summary{outline:none;cursor:pointer}.arrow{display:inline-block;width:0;height:0}.arrow.up{border-bottom:6px solid #ccc}.arrow.down,.arrow.up{border-left:4px solid transparent;border-right:4px solid transparent}.arrow.down{border-top:6px solid #ccc}.arrow.right{border-left:6px solid #ccc}.arrow.left,.arrow.right{border-top:4px solid transparent;border-bottom:4px solid transparent}.arrow.left{border-right:6px solid #ccc}.theme-default-content:not(.custom){max-width:960px;margin:0 auto;padding:2rem 2.5rem}@media (max-width:959px){.theme-default-content:not(.custom){padding:2rem}}@media (max-width:419px){.theme-default-content:not(.custom){padding:1.5rem}}.table-of-contents .badge{vertical-align:middle}body,html{padding:0;margin:0;background-color:#fff}body{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-size:16px;color:#2c3e50}.page{padding-left:20rem}.navbar{z-index:20;right:0;height:4.6rem;background-color:#fff;box-sizing:border-box;border-bottom:1px solid #eaecef}.navbar,.sidebar-mask{position:fixed;top:0;left:0}.sidebar-mask{z-index:9;width:100vw;height:100vh;display:none}.sidebar{font-size:16px;background-color:#fff;width:20rem;position:fixed;z-index:10;margin:0;top:4.6rem;left:0;bottom:0;box-sizing:border-box;border-right:1px solid #eaecef;overflow-y:auto}.theme-default-content:not(.custom)>:first-child{margin-top:4.6rem}.theme-default-content:not(.custom) a:hover{text-decoration:underline}.theme-default-content:not(.custom) p.demo{padding:1rem 1.5rem;border:1px solid #ddd;border-radius:4px}.theme-default-content:not(.custom) img{max-width:100%}.theme-default-content.custom{padding:0;margin:0}.theme-default-content.custom img{max-width:100%}a{font-weight:500;text-decoration:none}a,p a code{color:#007acc}p a code{font-weight:400}kbd{background:#eee;border:.15rem solid #ddd;border-bottom:.25rem solid #ddd;border-radius:.15rem;padding:0 .15em}blockquote{font-size:1rem;color:#999;border-left:.2rem solid #dfe2e5;margin:1rem 0;padding:.25rem 0 .25rem 1rem}blockquote>p{margin:0}ol,ul{padding-left:1.2em}strong{font-weight:600}h1,h2,h3,h4,h5,h6{font-weight:600;line-height:1.25}.theme-default-content:not(.custom)>h1,.theme-default-content:not(.custom)>h2,.theme-default-content:not(.custom)>h3,.theme-default-content:not(.custom)>h4,.theme-default-content:not(.custom)>h5,.theme-default-content:not(.custom)>h6{margin-top:-4.1rem;padding-top:5.6rem;margin-bottom:0}.theme-default-content:not(.custom)>h1:first-child,.theme-default-content:not(.custom)>h2:first-child,.theme-default-content:not(.custom)>h3:first-child,.theme-default-content:not(.custom)>h4:first-child,.theme-default-content:not(.custom)>h5:first-child,.theme-default-content:not(.custom)>h6:first-child{margin-top:-1.5rem;margin-bottom:1rem}.theme-default-content:not(.custom)>h1:first-child+.custom-block,.theme-default-content:not(.custom)>h1:first-child+p,.theme-default-content:not(.custom)>h1:first-child+pre,.theme-default-content:not(.custom)>h2:first-child+.custom-block,.theme-default-content:not(.custom)>h2:first-child+p,.theme-default-content:not(.custom)>h2:first-child+pre,.theme-default-content:not(.custom)>h3:first-child+.custom-block,.theme-default-content:not(.custom)>h3:first-child+p,.theme-default-content:not(.custom)>h3:first-child+pre,.theme-default-content:not(.custom)>h4:first-child+.custom-block,.theme-default-content:not(.custom)>h4:first-child+p,.theme-default-content:not(.custom)>h4:first-child+pre,.theme-default-content:not(.custom)>h5:first-child+.custom-block,.theme-default-content:not(.custom)>h5:first-child+p,.theme-default-content:not(.custom)>h5:first-child+pre,.theme-default-content:not(.custom)>h6:first-child+.custom-block,.theme-default-content:not(.custom)>h6:first-child+p,.theme-default-content:not(.custom)>h6:first-child+pre{margin-top:2rem}h1:focus .header-anchor,h1:hover .header-anchor,h2:focus .header-anchor,h2:hover .header-anchor,h3:focus .header-anchor,h3:hover .header-anchor,h4:focus .header-anchor,h4:hover .header-anchor,h5:focus .header-anchor,h5:hover .header-anchor,h6:focus .header-anchor,h6:hover .header-anchor{opacity:1}h1{font-size:2.2rem}h2{font-size:1.65rem;padding-bottom:.3rem;border-bottom:1px solid #eaecef}h3{font-size:1.35rem}a.header-anchor{font-size:.85em;float:left;margin-left:-.87em;padding-right:.23em;margin-top:.125em;opacity:0}a.header-anchor:focus,a.header-anchor:hover{text-decoration:none}.line-number,code,kbd{font-family:source-code-pro,Menlo,Monaco,Consolas,Courier New,monospace}ol,p,ul{line-height:1.7}hr{border:0;border-top:1px solid #eaecef}table{border-collapse:collapse;margin:1rem 0;display:block;overflow-x:auto}tr{border-top:1px solid #dfe2e5}tr:nth-child(2n){background-color:#f6f8fa}td,th{border:1px solid #dfe2e5;padding:.6em 1em}.theme-container.sidebar-open .sidebar-mask{display:block}.theme-container.no-navbar .theme-default-content:not(.custom)>h1,.theme-container.no-navbar h2,.theme-container.no-navbar h3,.theme-container.no-navbar h4,.theme-container.no-navbar h5,.theme-container.no-navbar h6{margin-top:1.5rem;padding-top:0}.theme-container.no-navbar .sidebar{top:0}@media (min-width:720px){.theme-container.no-sidebar .sidebar{display:none}.theme-container.no-sidebar .page{padding-left:0}}@media (max-width:959px){.sidebar{font-size:15px;width:16.4rem}.page{padding-left:16.4rem}}@media (max-width:719px){.sidebar{top:0;padding-top:4.6rem;transform:translateX(-100%);transition:transform .2s ease}.page{padding-left:0}.theme-container.sidebar-open .sidebar{transform:translateX(0)}.theme-container.no-navbar .sidebar{padding-top:0}}@media (max-width:419px){h1{font-size:1.9rem}.theme-default-content div[class*=language-]{margin:.85rem -1.5rem;border-radius:0}}.sidebar::-webkit-scrollbar{width:.3em}.sidebar::-webkit-scrollbar-track{background-color:#eaecef}.sidebar::-webkit-scrollbar-thumb{background-color:#007acc}.sidebar-group:is(.collapsable) .sidebar-heading{opacity:1!important;cursor:pointer!important}.nav-dropdown .dropdown-item h4{margin:.45rem 0 .2rem!important}.token.builtin{color:#36acaa}.token.comment{font-style:normal}.theme-default-content a code{color:#007acc}.theme-default-content pre[class*=language-] code,.theme-default-content pre code{color:#222;color:#476582;font-size:1em}div[class*=language-]:before{color:#fff;background:#bbb;padding:1px 4px 3px 5px}div[class~=language-ts]:before,div[class~=language-typescript]:before{color:#fff;background:#007acc}div[class~=language-javascript]:before,div[class~=language-js]:before{color:#323330;background:#f0db4f}div[class~=language-bash]:before,div[class~=language-sh]:before{color:#fff;background:#000}div[class~=language-wat]:before,div[class~=language-webassembly]:before{color:#fff;background:#654ff0}div[class~=language-html]:before{color:#fff;background:#e44d26}div[class~=language-c]:before{color:#fff;background:#3949ab;padding-right:6px;padding-left:7px}.theme-default-content li div[class*=language-]:first-child pre[class*=language-]{background:#fff;border:0;padding:0;font-size:1.1em}.theme-default-content li div[class*=language-]:first-child:before{display:none}img.engine{position:relative;top:3px}details summary{cursor:pointer}details summary::marker{color:#ccc}details summary:hover{color:#007acc}details table td{font-family:source-code-pro,Menlo,Monaco,Consolas,Courier New,monospace}#nprogress{pointer-events:none}#nprogress .bar{background:#007acc;position:fixed;z-index:1031;top:0;left:0;width:100%;height:2px}#nprogress .peg{display:block;position:absolute;right:0;width:100px;height:100%;box-shadow:0 0 10px #007acc,0 0 5px #007acc;opacity:1;transform:rotate(3deg) translateY(-4px)}#nprogress .spinner{display:block;position:fixed;z-index:1031;top:15px;right:15px}#nprogress .spinner-icon{width:18px;height:18px;box-sizing:border-box;border-color:#007acc transparent transparent #007acc;border-style:solid;border-width:2px;border-radius:50%;-webkit-animation:nprogress-spinner .4s linear infinite;animation:nprogress-spinner .4s linear infinite}.nprogress-custom-parent{overflow:hidden;position:relative}.nprogress-custom-parent #nprogress .bar,.nprogress-custom-parent #nprogress .spinner{position:absolute}@-webkit-keyframes nprogress-spinner{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}@keyframes nprogress-spinner{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}.icon.outbound{color:#aaa;display:inline-block;vertical-align:middle;position:relative;top:-1px}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}.home{padding:4.6rem 2rem 0;max-width:960px;margin:0 auto;display:block}.home .hero{text-align:center}.home .hero img{max-width:100%;max-height:280px;display:block;margin:3rem auto 1.5rem}.home .hero h1{font-size:3rem}.home .hero .action,.home .hero .description,.home .hero h1{margin:1.8rem auto}.home .hero .description{max-width:35rem;font-size:1.6rem;line-height:1.3;color:#6a8bad}.home .hero .action-button{display:inline-block;font-size:1.2rem;color:#fff;background-color:#007acc;padding:.8rem 1.6rem;border-radius:4px;transition:background-color .1s ease;box-sizing:border-box;border-bottom:1px solid #006eb8}.home .hero .action-button:hover{background-color:#008ceb}.home .features{border-top:1px solid #eaecef;padding:1.2rem 0;margin-top:2.5rem;display:flex;flex-wrap:wrap;align-items:flex-start;align-content:stretch;justify-content:space-between}.home .feature{flex-grow:1;flex-basis:30%;max-width:30%}.home .feature h2{font-size:1.4rem;font-weight:500;border-bottom:none;padding-bottom:0;color:#3a5169}.home .feature p{color:#4e6e8e}.home .footer{padding:2.5rem;border-top:1px solid #eaecef;text-align:center;color:#4e6e8e}@media (max-width:719px){.home .features{flex-direction:column}.home .feature{max-width:100%;padding:0 2.5rem}}@media (max-width:419px){.home{padding-left:1.5rem;padding-right:1.5rem}.home .hero img{max-height:210px;margin:2rem auto 1.2rem}.home .hero h1{font-size:2rem}.home .hero .action,.home .hero .description,.home .hero h1{margin:1.2rem auto}.home .hero .description{font-size:1.2rem}.home .hero .action-button{font-size:1rem;padding:.6rem 1.2rem}.home .feature h2{font-size:1.25rem}}.algolia-search-wrapper>span{vertical-align:middle}.algolia-search-wrapper .algolia-autocomplete{line-height:normal}.algolia-search-wrapper .algolia-autocomplete .ds-dropdown-menu{background-color:#fff;border:1px solid #999;border-radius:4px;font-size:16px;margin:6px 0 0;padding:4px;text-align:left}.algolia-search-wrapper .algolia-autocomplete .ds-dropdown-menu:before{border-color:#999}.algolia-search-wrapper .algolia-autocomplete .ds-dropdown-menu [class*=ds-dataset-]{border:none;padding:0}.algolia-search-wrapper .algolia-autocomplete .ds-dropdown-menu .ds-suggestions{margin-top:0}.algolia-search-wrapper .algolia-autocomplete .ds-dropdown-menu .ds-suggestion{border-bottom:1px solid #eaecef}.algolia-search-wrapper .algolia-autocomplete .algolia-docsearch-suggestion--highlight{color:#2c815b}.algolia-search-wrapper .algolia-autocomplete .algolia-docsearch-suggestion{border-color:#eaecef;padding:0}.algolia-search-wrapper .algolia-autocomplete .algolia-docsearch-suggestion .algolia-docsearch-suggestion--category-header{padding:5px 10px;margin-top:0;background:#007acc;color:#fff;font-weight:600}.algolia-search-wrapper .algolia-autocomplete .algolia-docsearch-suggestion .algolia-docsearch-suggestion--category-header .algolia-docsearch-suggestion--highlight{background:hsla(0,0%,100%,.6)}.algolia-search-wrapper .algolia-autocomplete .algolia-docsearch-suggestion .algolia-docsearch-suggestion--wrapper{padding:0}.algolia-search-wrapper .algolia-autocomplete .algolia-docsearch-suggestion .algolia-docsearch-suggestion--title{font-weight:600;margin-bottom:0;color:#2c3e50}.algolia-search-wrapper .algolia-autocomplete .algolia-docsearch-suggestion .algolia-docsearch-suggestion--subcategory-column{vertical-align:top;padding:5px 7px 5px 5px;border-color:#eaecef;background:#f1f3f5}.algolia-search-wrapper .algolia-autocomplete .algolia-docsearch-suggestion .algolia-docsearch-suggestion--subcategory-column:after{display:none}.algolia-search-wrapper .algolia-autocomplete .algolia-docsearch-suggestion .algolia-docsearch-suggestion--subcategory-column-text{color:#555}.algolia-search-wrapper .algolia-autocomplete .algolia-docsearch-footer{border-color:#eaecef}.algolia-search-wrapper .algolia-autocomplete .ds-cursor .algolia-docsearch-suggestion--content{background-color:#e7edf3!important;color:#2c3e50}@media (min-width:719px){.algolia-search-wrapper .algolia-autocomplete .algolia-docsearch-suggestion .algolia-docsearch-suggestion--subcategory-column{float:none;width:150px;min-width:150px;display:table-cell}.algolia-search-wrapper .algolia-autocomplete .algolia-docsearch-suggestion .algolia-docsearch-suggestion--content{float:none;display:table-cell;width:100%;vertical-align:top}.algolia-search-wrapper .algolia-autocomplete .algolia-docsearch-suggestion .ds-dropdown-menu{min-width:515px!important}}@media (max-width:719px){.algolia-search-wrapper .ds-dropdown-menu{min-width:calc(100vw - 4rem)!important;max-width:calc(100vw - 4rem)!important}.algolia-search-wrapper .algolia-docsearch-suggestion--wrapper{padding:5px 7px 5px 5px!important}.algolia-search-wrapper .algolia-docsearch-suggestion--subcategory-column{padding:0!important;background:#fff!important}.algolia-search-wrapper .algolia-docsearch-suggestion--subcategory-column-text:after{content:" > ";font-size:10px;line-height:14.4px;display:inline-block;width:5px;margin:-3px 3px 0;vertical-align:middle}}.search-box{display:inline-block;position:relative;margin-right:1rem}.search-box input{cursor:text;width:10rem;height:2rem;color:#4e6e8e;display:inline-block;border:1px solid #cfd4db;border-radius:2rem;font-size:.9rem;line-height:2rem;padding:0 .5rem 0 2rem;outline:none;transition:all .2s ease;background:#fff url(/assets/img/search.83621669.svg) .6rem .5rem no-repeat;background-size:1rem}.search-box input:focus{cursor:auto;border-color:#007acc}.search-box .suggestions{background:#fff;width:20rem;position:absolute;top:2rem;border:1px solid #cfd4db;border-radius:6px;padding:.4rem;list-style-type:none}.search-box .suggestions.align-right{right:0}.search-box .suggestion{line-height:1.4;padding:.4rem .6rem;border-radius:4px;cursor:pointer}.search-box .suggestion a{white-space:normal;color:#5d82a6}.search-box .suggestion a .page-title{font-weight:600}.search-box .suggestion a .header{font-size:.9em;margin-left:.25em}.search-box .suggestion.focused{background-color:#f3f4f5}.search-box .suggestion.focused a{color:#007acc}@media (max-width:959px){.search-box input{cursor:pointer;width:0;border-color:transparent;position:relative}.search-box input:focus{cursor:text;left:0;width:10rem}}@media (-ms-high-contrast:none){.search-box input{height:2rem}}@media (max-width:959px) and (min-width:719px){.search-box .suggestions{left:0}}@media (max-width:719px){.search-box{margin-right:0}.search-box input{left:1rem}.search-box .suggestions{right:0}}@media (max-width:419px){.search-box .suggestions{width:calc(100vw - 4rem)}.search-box input:focus{width:8rem}}.sidebar-button{cursor:pointer;display:none;width:1.25rem;height:1.25rem;position:absolute;padding:.6rem;top:.6rem;left:1rem}.sidebar-button .icon{display:block;width:1.25rem;height:1.25rem}@media (max-width:719px){.sidebar-button{display:block}}.dropdown-enter,.dropdown-leave-to{height:0!important}.dropdown-wrapper{cursor:pointer}.dropdown-wrapper .dropdown-title,.dropdown-wrapper .mobile-dropdown-title{display:block;font-size:.9rem;font-family:inherit;cursor:inherit;padding:inherit;line-height:1.4rem;background:transparent;border:none;font-weight:500;color:#2c3e50}.dropdown-wrapper .dropdown-title:hover,.dropdown-wrapper .mobile-dropdown-title:hover{border-color:transparent}.dropdown-wrapper .dropdown-title .arrow,.dropdown-wrapper .mobile-dropdown-title .arrow{vertical-align:middle;margin-top:-1px;margin-left:.4rem}.dropdown-wrapper .mobile-dropdown-title{display:none;font-weight:600}.dropdown-wrapper .mobile-dropdown-title font-size inherit:hover{color:#007acc}.dropdown-wrapper .nav-dropdown .dropdown-item{color:inherit;line-height:1.7rem}.dropdown-wrapper .nav-dropdown .dropdown-item h4{margin:.45rem 0 0;border-top:1px solid #eee;padding:1rem 1.5rem .45rem 1.25rem}.dropdown-wrapper .nav-dropdown .dropdown-item .dropdown-subitem-wrapper{padding:0;list-style:none}.dropdown-wrapper .nav-dropdown .dropdown-item .dropdown-subitem-wrapper .dropdown-subitem{font-size:.9em}.dropdown-wrapper .nav-dropdown .dropdown-item a{display:block;line-height:1.7rem;position:relative;border-bottom:none;font-weight:400;margin-bottom:0;padding:0 1.5rem 0 1.25rem}.dropdown-wrapper .nav-dropdown .dropdown-item a.router-link-active,.dropdown-wrapper .nav-dropdown .dropdown-item a:hover{color:#007acc}.dropdown-wrapper .nav-dropdown .dropdown-item a.router-link-active:after{content:"";width:0;height:0;border-left:5px solid #007acc;border-top:3px solid transparent;border-bottom:3px solid transparent;position:absolute;top:calc(50% - 2px);left:9px}.dropdown-wrapper .nav-dropdown .dropdown-item:first-child h4{margin-top:0;padding-top:0;border-top:0}@media (max-width:719px){.dropdown-wrapper.open .dropdown-title{margin-bottom:.5rem}.dropdown-wrapper .dropdown-title{display:none}.dropdown-wrapper .mobile-dropdown-title{display:block}.dropdown-wrapper .nav-dropdown{transition:height .1s ease-out;overflow:hidden}.dropdown-wrapper .nav-dropdown .dropdown-item h4{border-top:0;margin-top:0;padding-top:0}.dropdown-wrapper .nav-dropdown .dropdown-item>a,.dropdown-wrapper .nav-dropdown .dropdown-item h4{font-size:15px;line-height:2rem}.dropdown-wrapper .nav-dropdown .dropdown-item .dropdown-subitem{font-size:14px;padding-left:1rem}}@media (min-width:719px){.dropdown-wrapper{height:1.8rem}.dropdown-wrapper.open .nav-dropdown,.dropdown-wrapper:hover .nav-dropdown{display:block!important}.dropdown-wrapper.open:blur{display:none}.dropdown-wrapper .nav-dropdown{display:none;height:auto!important;box-sizing:border-box;max-height:calc(100vh - 2.7rem);overflow-y:auto;position:absolute;top:100%;right:0;background-color:#fff;padding:.6rem 0;border:1px solid;border-color:#ddd #ddd #ccc;text-align:left;border-radius:.25rem;white-space:nowrap;margin:0}}.nav-links{display:inline-block}.nav-links a{line-height:1.4rem;color:inherit}.nav-links a.router-link-active,.nav-links a:hover{color:#007acc}.nav-links .nav-item{position:relative;display:inline-block;margin-left:1.5rem;line-height:2rem}.nav-links .nav-item:first-child{margin-left:0}.nav-links .repo-link{margin-left:1.5rem}@media (max-width:719px){.nav-links .nav-item,.nav-links .repo-link{margin-left:0}}@media (min-width:719px){.nav-links a.router-link-active,.nav-links a:hover{color:#2c3e50}.nav-item>a:not(.external).router-link-active,.nav-item>a:not(.external):hover{margin-bottom:-2px;border-bottom:2px solid #0089e4}}.navbar{padding:.7rem 1.5rem;line-height:3.2rem}.navbar a,.navbar img,.navbar span{display:inline-block}.navbar .logo{height:3.2rem;min-width:3.2rem;margin-right:.8rem;vertical-align:top}.navbar .site-name{font-size:1.3rem;font-weight:600;color:#2c3e50;position:relative}.navbar .links{padding-left:1.5rem;box-sizing:border-box;background-color:#fff;white-space:nowrap;font-size:.9rem;position:absolute;right:1.5rem;top:.7rem;display:flex}.navbar .links .search-box{flex:0 0 auto;vertical-align:top}@media (max-width:719px){.navbar{padding-left:4rem}.navbar .can-hide{display:none}.navbar .links{padding-left:1.5rem}.navbar .site-name{width:calc(100vw - 9.4rem);overflow:hidden;white-space:nowrap;text-overflow:ellipsis}}.page-edit{max-width:960px;margin:0 auto;padding:2rem 2.5rem}@media (max-width:959px){.page-edit{padding:2rem}}@media (max-width:419px){.page-edit{padding:1.5rem}}.page-edit{padding-top:1rem;padding-bottom:1rem;overflow:auto}.page-edit .edit-link{display:inline-block}.page-edit .edit-link a{color:#4e6e8e;margin-right:.25rem}.page-edit .last-updated{float:right;font-size:.9em}.page-edit .last-updated .prefix{font-weight:500;color:#4e6e8e}.page-edit .last-updated .time{font-weight:400;color:#767676}@media (max-width:719px){.page-edit .edit-link{margin-bottom:.5rem}.page-edit .last-updated{font-size:.8em;float:none;text-align:left}}.page-nav{max-width:960px;margin:0 auto;padding:2rem 2.5rem}@media (max-width:959px){.page-nav{padding:2rem}}@media (max-width:419px){.page-nav{padding:1.5rem}}.page-nav{padding-top:1rem;padding-bottom:0}.page-nav .inner{min-height:2rem;margin-top:0;border-top:1px solid #eaecef;padding-top:1rem;overflow:auto}.page-nav .next{float:right}.page{padding-bottom:2rem;display:block}.page[data-v-bb3fd134]{padding-bottom:0}.editor-wrap{position:relative;-webkit-margin-before:1em;margin-block-start:1em;-webkit-margin-after:1em;margin-block-end:1em}.editor-wrap a.maximize{position:absolute;top:8px;right:12px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;color:#c7c4c7;cursor:pointer;font-size:1.2rem;z-index:1000}.editor-wrap a.maximize:hover{color:#fff;text-decoration:none}.editor-wrap iframe{background:#1e1e1e;width:100%;height:540px;min-height:540px;border:0;resize:vertical}.editor-wrap.maximized{position:fixed;-webkit-margin-before:auto;margin-block-start:auto;-webkit-margin-after:auto;margin-block-end:auto;z-index:9000;margin:0;top:0;left:0;height:100%;width:100%}.editor-wrap.maximized iframe{height:100%!important;resize:none}.sidebar-group .sidebar-group{padding-left:.5em}.sidebar-group:not(.collapsable) .sidebar-heading:not(.clickable){cursor:auto;color:inherit}.sidebar-group.is-sub-group{padding-left:0}.sidebar-group.is-sub-group>.sidebar-heading{font-size:.95em;line-height:1.4;font-weight:400;padding-left:2rem}.sidebar-group.is-sub-group>.sidebar-heading:not(.clickable){opacity:.5}.sidebar-group.is-sub-group>.sidebar-group-items{padding-left:1rem}.sidebar-group.is-sub-group>.sidebar-group-items>li>.sidebar-link{font-size:.95em;border-left:none}.sidebar-group.depth-2>.sidebar-heading{border-left:none}.sidebar-heading{color:#2c3e50;transition:color .15s ease;cursor:pointer;font-size:1.1em;font-weight:700;padding:.35rem 1.5rem .35rem 1.25rem;width:100%;box-sizing:border-box;margin:0;border-left:.25rem solid transparent}.sidebar-heading.open,.sidebar-heading:hover{color:inherit}.sidebar-heading .arrow{position:relative;top:-.12em;left:.5em}.sidebar-heading.clickable.active{font-weight:600;color:#007acc;border-left-color:#007acc}.sidebar-heading.clickable:hover{color:#007acc}.sidebar-group-items{transition:height .1s ease-out;font-size:.95em;overflow:hidden}.sidebar .sidebar-sub-headers{padding-left:1rem;font-size:.95em}a.sidebar-link{font-size:1em;font-weight:400;display:inline-block;color:#2c3e50;border-left:.25rem solid transparent;padding:.35rem 1rem .35rem 1.25rem;line-height:1.4;width:100%;box-sizing:border-box}a.sidebar-link:hover{color:#007acc}a.sidebar-link.active{font-weight:600;color:#007acc;border-left-color:#007acc}.sidebar-group a.sidebar-link{padding-left:2rem}.sidebar-sub-headers a.sidebar-link{padding-top:.25rem;padding-bottom:.25rem;border-left:none}.sidebar-sub-headers a.sidebar-link.active{font-weight:500}.sidebar ul{padding:0;margin:0;list-style-type:none}.sidebar a{display:inline-block}.sidebar .nav-links{display:none;border-bottom:1px solid #eaecef;padding:.5rem 0 .75rem}.sidebar .nav-links a{font-weight:600}.sidebar .nav-links .nav-item,.sidebar .nav-links .repo-link{display:block;line-height:1.25rem;font-size:1.1em;padding:.5rem 0 .5rem 1.5rem}.sidebar>.sidebar-links{padding:1.5rem 0}.sidebar>.sidebar-links>li>a.sidebar-link{font-size:1.1em;line-height:1.7;font-weight:700}.sidebar>.sidebar-links>li:not(:first-child){margin-top:.75rem}@media (max-width:719px){.sidebar .nav-links{display:block}.sidebar .nav-links .dropdown-wrapper .nav-dropdown .dropdown-item a.router-link-active:after{top:calc(1rem - 2px)}.sidebar>.sidebar-links{padding:1rem 0}}.footer[data-v-7c0e63ba]{text-align:center;color:#4e6e8e;padding:0 2rem}.footer .item[data-v-7c0e63ba]{white-space:nowrap}#hero[data-v-0f93345e]{margin-top:2rem;text-align:center;height:400px;background:#007acc}#hero[data-v-0f93345e]:before{content:"";position:absolute;z-index:0;top:0;left:0;width:100%;height:520px;background:#007acc url(/images/header.svg) bottom no-repeat;background-size:1440px}#hero>[data-v-0f93345e]{position:relative}#hero h1[data-v-0f93345e]{color:#fff;margin:1.3rem auto 1.8rem;font-size:2rem;font-weight:200}#logo[data-v-0f93345e]{display:inline-block;width:640px}#logo svg[data-v-0f93345e]{width:100%;height:100%;max-height:240px;fill:#fff}@media only screen and (max-width:740px){#logo[data-v-0f93345e]{width:100%}#logo svg[data-v-0f93345e]{max-height:213px}}#features[data-v-0f93345e]{padding:1.2rem 0 0;margin-top:2.5rem;display:flex;flex-wrap:wrap;align-items:flex-start;align-content:stretch;justify-content:space-between}#features .feature[data-v-0f93345e]{flex-grow:1;flex-basis:30%;max-width:30%}#features h2[data-v-0f93345e]{font-size:1.4rem;border-bottom:none;padding-bottom:0;color:#3a5169}.action[data-v-0f93345e]{text-align:center;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.action a[data-v-0f93345e]{display:inline-block;font-size:1.2rem;color:#fff;background-color:#007acc;padding:.8rem 1.6rem;border-radius:4px;transition:background-color .1s ease;box-sizing:border-box;border-bottom:1px solid #006eb8;text-decoration:none!important;margin:.1rem 0}.action a[data-v-0f93345e]:hover{background-color:#1a8ae7}.action a svg[data-v-0f93345e]{width:2em;position:relative;left:-10px;float:left;height:32px}.action a.docs[data-v-0f93345e]{color:#111;background:#fff;border-bottom-color:#aaa}.action a.docs[data-v-0f93345e]:hover{background:#eee}.action a.github[data-v-0f93345e]{color:#fff;background:#24292e;border-bottom-color:#101214}.action a.github[data-v-0f93345e]:hover{background:#3e464f}.action a.npm[data-v-0f93345e]{color:#fff;background:#cb3837;border-bottom-color:#ba3232}.action a.npm[data-v-0f93345e]:hover{background:#eb3f3f}@media only screen and (max-width:720px){.action a.github svg[data-v-0f93345e]{float:none;left:0;margin-bottom:-.5rem}.action a.github .title[data-v-0f93345e],.action a.npm[data-v-0f93345e]{display:none}#features .feature[data-v-0f93345e]{flex-basis:100%;max-width:100%}}@media only screen and (max-width:640px){#try[data-v-0f93345e]{display:none}}#sponsors[data-v-0f93345e]{margin-bottom:2rem}#community h2 svg[data-v-0f93345e]{display:inline-block;height:25px;position:relative;top:3px}.frontpage .page-edit{display:none}.community .list[data-v-181c7660]{text-align:center}.community .list a[data-v-181c7660]{display:inline-block;box-sizing:border-box;position:relative;top:0;transition:top .1s}.community .list a[data-v-181c7660]:hover{top:-4px}.community .list a[data-v-181c7660]:before{content:"";position:absolute;border-radius:50%;background:#999;bottom:2px;right:2px;width:10px;height:10px;border:2px solid #fff}.community .list a.online[data-v-181c7660]:before{background:#49b684}.community .list a.idle[data-v-181c7660]:before{background:#fff url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMCAxMCI+PHBhdGggZD0iTTUgMGE1IDUgMCAwMC0xLjA1OS4xMkEzLjA5IDMuMDkgMCAwMTYuMTggMy4wODdhMy4wOSAzLjA5IDAgMDEtMy4wOSAzLjA5QTMuMDkgMy4wOSAwIDAxLjEyIDMuOTMgNSA1IDAgMDAwIDVhNSA1IDAgMDA1IDUgNSA1IDAgMDA1LTUgNSA1IDAgMDAtNS01eiIgZmlsbD0iI2Y4YTczNSIvPjwvc3ZnPg==");background-size:10px 10px}.community .list a.dnd[data-v-181c7660]:before{background:#fff url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMCAxMCI+PHBhdGggZD0iTTUgMGE1IDUgMCAwMC01IDUgNSA1IDAgMDA1IDUgNSA1IDAgMDA1LTUgNSA1IDAgMDAtNS01ek0yIDRoNnYySDJWNHoiIGZpbGw9IiNlZDQ3NGEiLz48L3N2Zz4=");background-size:10px 10px}.community .list img[data-v-181c7660]{width:32px;height:32px;overflow:hidden;border-radius:50%;border:1px solid #fff;box-shadow:0 0 0 1px #007acc}.community .list a[data-v-181c7660]{padding:.15rem}.contributors h3[data-v-31cd9d1c]{text-align:center;border:0}.contributors .list[data-v-31cd9d1c]{text-align:center}.contributors .list a[data-v-31cd9d1c]{display:inline-block;box-sizing:border-box;position:relative;top:0;transition:top .1s}.contributors .list a[data-v-31cd9d1c]:hover{top:-4px}.contributors .list img[data-v-31cd9d1c]{width:32px;height:32px;overflow:hidden;border-radius:50%;border:1px solid #fff;box-shadow:0 0 0 1px #007acc}.contributors .list a[data-v-31cd9d1c]{padding:.15rem}.sponsors[data-v-7f9b29e8]{border:1px solid #eaecef;background:#fff;padding:0 .5rem 1.5rem}.sponsors h3[data-v-7f9b29e8]{text-align:center;border:0}.sponsors .list[data-v-7f9b29e8]{text-align:center}.sponsors .list a[data-v-7f9b29e8]{display:inline-block;box-sizing:border-box;position:relative;top:0;transition:top .1s}.sponsors .list img[data-v-7f9b29e8]{overflow:hidden}.sponsors .list a[data-v-7f9b29e8]:hover{top:-4px}.sponsors .platinum .list img[data-v-7f9b29e8]{height:80px}.sponsors .platinum .list a[data-v-7f9b29e8]{padding:.5rem}.sponsors .gold .list img[data-v-7f9b29e8]{height:64px}.sponsors .gold .list a[data-v-7f9b29e8]{padding:.5rem}.sponsors .silver .list img[data-v-7f9b29e8]{height:48px}.sponsors .silver .list a[data-v-7f9b29e8]{padding:.4rem}.sponsors .bronze .list img[data-v-7f9b29e8]{height:36px}.sponsors .bronze .list a[data-v-7f9b29e8]{padding:.3rem}.sponsors .backer .list img[data-v-7f9b29e8]{width:32px;height:32px;border-radius:50%;border:1px solid #fff;box-shadow:0 0 0 1px #007acc}.sponsors .backer .list a[data-v-7f9b29e8]{padding:.15rem}.testimonials[data-v-aebe12ce]{padding-bottom:1rem}.testimonials h3[data-v-aebe12ce]{text-align:center;border:0}.testimonial[data-v-aebe12ce]{display:flex;flex-direction:row;align-items:center;padding:1.5rem 0;margin:0 0 0 30px}.testimonial .logo[data-v-aebe12ce]{border-radius:50%;width:76px;height:76px;border:1px solid #fff;box-shadow:0 0 0 1px #007acc}.testimonial p[data-v-aebe12ce]{margin:0 30px;text-align:justify}@media only screen and (max-width:720px){.testimonial[data-v-aebe12ce]{flex-direction:column;margin:0}.testimonial .logo[data-v-aebe12ce]{width:90px;height:90px}.testimonial p[data-v-aebe12ce]{margin:20px 0 10px}}.badge[data-v-15b7b770]{display:inline-block;font-size:14px;height:18px;line-height:18px;border-radius:3px;padding:0 6px;color:#fff}.badge.green[data-v-15b7b770],.badge.tip[data-v-15b7b770],.badge[data-v-15b7b770]{background-color:#42b983}.badge.error[data-v-15b7b770]{background-color:#da5961}.badge.warn[data-v-15b7b770],.badge.warning[data-v-15b7b770],.badge.yellow[data-v-15b7b770]{background-color:#e7c000}.badge+.badge[data-v-15b7b770]{margin-left:5px}.theme-code-block[data-v-759a7d02]{display:none}.theme-code-block__active[data-v-759a7d02]{display:block}.theme-code-block>pre[data-v-759a7d02]{background-color:orange}.theme-code-group__nav[data-v-deefee04]{margin-bottom:-35px;background-color:#fff;padding-bottom:22px;border-top-left-radius:6px;border-top-right-radius:6px;padding-left:10px;padding-top:10px}.theme-code-group__ul[data-v-deefee04]{margin:auto 0;padding-left:0;display:inline-flex;list-style:none}.theme-code-group__nav-tab[data-v-deefee04]{border:0;padding:5px;cursor:pointer;background-color:transparent;font-size:.85em;line-height:1.4;color:hsla(0,0%,100%,.9);font-weight:600}.theme-code-group__nav-tab-active[data-v-deefee04]{border-bottom:1px solid #42b983}.pre-blank[data-v-deefee04]{color:#42b983}.searchbox{display:inline-block;position:relative;width:200px;height:32px!important;white-space:nowrap;box-sizing:border-box;visibility:visible!important}.searchbox .algolia-autocomplete{display:block;width:100%;height:100%}.searchbox__wrapper{width:100%;height:100%;z-index:999;position:relative}.searchbox__input{display:inline-block;box-sizing:border-box;transition:box-shadow .4s ease,background .4s ease;border:0;border-radius:16px;box-shadow:inset 0 0 0 1px #ccc;background:#fff!important;padding:0 26px 0 32px;width:100%;height:100%;vertical-align:middle;white-space:normal;font-size:12px;-webkit-appearance:none;-moz-appearance:none;appearance:none}.searchbox__input::-webkit-search-cancel-button,.searchbox__input::-webkit-search-decoration,.searchbox__input::-webkit-search-results-button,.searchbox__input::-webkit-search-results-decoration{display:none}.searchbox__input:hover{box-shadow:inset 0 0 0 1px #b3b3b3}.searchbox__input:active,.searchbox__input:focus{outline:0;box-shadow:inset 0 0 0 1px #aaa;background:#fff}.searchbox__input:-ms-input-placeholder{color:#aaa}.searchbox__input::-moz-placeholder{color:#aaa}.searchbox__input::placeholder{color:#aaa}.searchbox__submit{position:absolute;top:0;margin:0;border:0;border-radius:16px 0 0 16px;background-color:rgba(69,142,225,0);padding:0;width:32px;height:100%;vertical-align:middle;text-align:center;font-size:inherit;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;right:inherit;left:0}.searchbox__submit:before{display:inline-block;margin-right:-4px;height:100%;vertical-align:middle;content:""}.searchbox__submit:active,.searchbox__submit:hover{cursor:pointer}.searchbox__submit:focus{outline:0}.searchbox__submit svg{width:14px;height:14px;vertical-align:middle;fill:#6d7e96}.searchbox__reset{display:block;position:absolute;top:8px;right:8px;margin:0;border:0;background:none;cursor:pointer;padding:0;font-size:inherit;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;fill:rgba(0,0,0,.5)}.searchbox__reset.hide{display:none}.searchbox__reset:focus{outline:0}.searchbox__reset svg{display:block;margin:4px;width:8px;height:8px}.searchbox__input:valid~.searchbox__reset{display:block;-webkit-animation-name:sbx-reset-in;animation-name:sbx-reset-in;-webkit-animation-duration:.15s;animation-duration:.15s}@-webkit-keyframes sbx-reset-in{0%{transform:translate3d(-20%,0,0);opacity:0}to{transform:none;opacity:1}}@keyframes sbx-reset-in{0%{transform:translate3d(-20%,0,0);opacity:0}to{transform:none;opacity:1}}.algolia-autocomplete.algolia-autocomplete-right .ds-dropdown-menu{right:0!important;left:inherit!important}.algolia-autocomplete.algolia-autocomplete-right .ds-dropdown-menu:before{right:48px}.algolia-autocomplete.algolia-autocomplete-left .ds-dropdown-menu{left:0!important;right:inherit!important}.algolia-autocomplete.algolia-autocomplete-left .ds-dropdown-menu:before{left:48px}.algolia-autocomplete .ds-dropdown-menu{top:-6px;border-radius:4px;margin:6px 0 0;padding:0;text-align:left;height:auto;position:relative;background:transparent;border:none;z-index:999;max-width:600px;min-width:500px;box-shadow:0 1px 0 0 rgba(0,0,0,.2),0 2px 3px 0 rgba(0,0,0,.1)}.algolia-autocomplete .ds-dropdown-menu:before{display:block;position:absolute;content:"";width:14px;height:14px;background:#fff;z-index:1000;top:-7px;border-top:1px solid #d9d9d9;border-right:1px solid #d9d9d9;transform:rotate(-45deg);border-radius:2px}.algolia-autocomplete .ds-dropdown-menu .ds-suggestions{position:relative;z-index:1000;margin-top:8px}.algolia-autocomplete .ds-dropdown-menu .ds-suggestions a:hover{text-decoration:none}.algolia-autocomplete .ds-dropdown-menu .ds-suggestion{cursor:pointer}.algolia-autocomplete .ds-dropdown-menu .ds-suggestion.ds-cursor .algolia-docsearch-suggestion.suggestion-layout-simple,.algolia-autocomplete .ds-dropdown-menu .ds-suggestion.ds-cursor .algolia-docsearch-suggestion:not(.suggestion-layout-simple) .algolia-docsearch-suggestion--content{background-color:rgba(69,142,225,.05)}.algolia-autocomplete .ds-dropdown-menu [class^=ds-dataset-]{position:relative;border:1px solid #d9d9d9;background:#fff;border-radius:4px;overflow:auto;padding:0 8px 8px}.algolia-autocomplete .ds-dropdown-menu *{box-sizing:border-box}.algolia-autocomplete .algolia-docsearch-suggestion{display:block;position:relative;padding:0 8px;background:#fff;color:#02060c;overflow:hidden}.algolia-autocomplete .algolia-docsearch-suggestion--highlight{color:#174d8c;background:rgba(143,187,237,.1);padding:.1em .05em}.algolia-autocomplete .algolia-docsearch-suggestion--category-header .algolia-docsearch-suggestion--category-header-lvl0 .algolia-docsearch-suggestion--highlight,.algolia-autocomplete .algolia-docsearch-suggestion--category-header .algolia-docsearch-suggestion--category-header-lvl1 .algolia-docsearch-suggestion--highlight,.algolia-autocomplete .algolia-docsearch-suggestion--text .algolia-docsearch-suggestion--highlight{padding:0 0 1px;background:inherit;box-shadow:inset 0 -2px 0 0 rgba(69,142,225,.8);color:inherit}.algolia-autocomplete .algolia-docsearch-suggestion--content{display:block;float:right;width:70%;position:relative;padding:5.33333px 0 5.33333px 10.66667px;cursor:pointer}.algolia-autocomplete .algolia-docsearch-suggestion--content:before{content:"";position:absolute;display:block;top:0;height:100%;width:1px;background:#ddd;left:-1px}.algolia-autocomplete .algolia-docsearch-suggestion--category-header{position:relative;border-bottom:1px solid #ddd;display:none;margin-top:8px;padding:4px 0;font-size:1em;color:#33363d}.algolia-autocomplete .algolia-docsearch-suggestion--wrapper{width:100%;float:left;padding:8px 0 0}.algolia-autocomplete .algolia-docsearch-suggestion--subcategory-column{float:left;width:30%;text-align:right;position:relative;padding:5.33333px 10.66667px;color:#a4a7ae;font-size:.9em;word-wrap:break-word}.algolia-autocomplete .algolia-docsearch-suggestion--subcategory-column:before{content:"";position:absolute;display:block;top:0;height:100%;width:1px;background:#ddd;right:0}.algolia-autocomplete .algolia-docsearch-suggestion--subcategory-inline{display:none}.algolia-autocomplete .algolia-docsearch-suggestion--title{margin-bottom:4px;color:#02060c;font-size:.9em;font-weight:700}.algolia-autocomplete .algolia-docsearch-suggestion--text{display:block;line-height:1.2em;font-size:.85em;color:#63676d}.algolia-autocomplete .algolia-docsearch-suggestion--no-results{width:100%;padding:8px 0;text-align:center;font-size:1.2em}.algolia-autocomplete .algolia-docsearch-suggestion--no-results:before{display:none}.algolia-autocomplete .algolia-docsearch-suggestion code{padding:1px 5px;font-size:90%;border:none;color:#222;background-color:#ebebeb;border-radius:3px;font-family:Menlo,Monaco,Consolas,Courier New,monospace}.algolia-autocomplete .algolia-docsearch-suggestion code .algolia-docsearch-suggestion--highlight{background:none}.algolia-autocomplete .algolia-docsearch-suggestion.algolia-docsearch-suggestion__main .algolia-docsearch-suggestion--category-header,.algolia-autocomplete .algolia-docsearch-suggestion.algolia-docsearch-suggestion__secondary{display:block}@media (min-width:768px){.algolia-autocomplete .algolia-docsearch-suggestion .algolia-docsearch-suggestion--subcategory-column{display:block}}@media (max-width:768px){.algolia-autocomplete .algolia-docsearch-suggestion .algolia-docsearch-suggestion--subcategory-column{display:inline-block;width:auto;float:left;padding:0;color:#02060c;font-size:.9em;font-weight:700;text-align:left;opacity:.5}.algolia-autocomplete .algolia-docsearch-suggestion .algolia-docsearch-suggestion--subcategory-column:before{display:none}.algolia-autocomplete .algolia-docsearch-suggestion .algolia-docsearch-suggestion--subcategory-column:after{content:"|"}.algolia-autocomplete .algolia-docsearch-suggestion .algolia-docsearch-suggestion--content{display:inline-block;width:auto;text-align:left;float:left;padding:0}.algolia-autocomplete .algolia-docsearch-suggestion .algolia-docsearch-suggestion--content:before{display:none}}.algolia-autocomplete .suggestion-layout-simple.algolia-docsearch-suggestion{border-bottom:1px solid #eee;padding:8px;margin:0}.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--content{width:100%;padding:0}.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--content:before{display:none}.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--category-header{margin:0;padding:0;display:block;width:100%;border:none}.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--category-header-lvl0,.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--category-header-lvl1{opacity:.6;font-size:.85em}.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--category-header-lvl1:before{background-image:url('data:image/svg+xml;utf8,');content:"";width:10px;height:10px;display:inline-block}.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--wrapper{width:100%;float:left;margin:0;padding:0}.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--duplicate-content,.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--subcategory-inline{display:none!important}.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--title{margin:0;color:#458ee1;font-size:.9em;font-weight:400}.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--title:before{content:"#";font-weight:700;color:#458ee1;display:inline-block}.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--text{margin:4px 0 0;display:block;line-height:1.4em;padding:5.33333px 8px;background:#f8f8f8;font-size:.85em;opacity:.8}.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--text .algolia-docsearch-suggestion--highlight{color:#3f4145;font-weight:700;box-shadow:none}.algolia-autocomplete .algolia-docsearch-footer{width:134px;height:20px;z-index:2000;margin-top:10.66667px;float:right;font-size:0;line-height:0}.algolia-autocomplete .algolia-docsearch-footer--logo{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width='168' height='24' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='none' fill-rule='evenodd'%3E%3Cpath d='M78.988.938h16.594a2.968 2.968 0 012.966 2.966V20.5a2.967 2.967 0 01-2.966 2.964H78.988a2.967 2.967 0 01-2.966-2.964V3.897A2.961 2.961 0 0178.988.938zm41.937 17.866c-4.386.02-4.386-3.54-4.386-4.106l-.007-13.336 2.675-.424v13.254c0 .322 0 2.358 1.718 2.364v2.248zm-10.846-2.18c.821 0 1.43-.047 1.855-.129v-2.719a6.334 6.334 0 00-1.574-.199 5.7 5.7 0 00-.897.069 2.699 2.699 0 00-.814.24c-.24.116-.439.28-.582.491-.15.212-.219.335-.219.656 0 .628.219.991.616 1.23s.938.362 1.615.362zm-.233-9.7c.883 0 1.629.109 2.231.328.602.218 1.088.525 1.444.915.363.396.609.922.76 1.483.157.56.232 1.175.232 1.85v6.874a32.5 32.5 0 01-1.868.314c-.834.123-1.772.185-2.813.185-.69 0-1.327-.069-1.895-.198a4.001 4.001 0 01-1.471-.636 3.085 3.085 0 01-.951-1.134c-.226-.465-.343-1.12-.343-1.803 0-.656.13-1.073.384-1.525a3.24 3.24 0 011.047-1.106c.445-.287.95-.492 1.532-.615a8.8 8.8 0 011.82-.185 8.404 8.404 0 011.972.24v-.438c0-.307-.035-.6-.11-.874a1.88 1.88 0 00-.384-.73 1.784 1.784 0 00-.724-.493 3.164 3.164 0 00-1.143-.205c-.616 0-1.177.075-1.69.164a7.735 7.735 0 00-1.26.307l-.321-2.192c.335-.117.834-.233 1.478-.349a10.98 10.98 0 012.073-.178zm52.842 9.626c.822 0 1.43-.048 1.854-.13V13.7a6.347 6.347 0 00-1.574-.199c-.294 0-.595.021-.896.069a2.7 2.7 0 00-.814.24 1.46 1.46 0 00-.582.491c-.15.212-.218.335-.218.656 0 .628.218.991.615 1.23.404.245.938.362 1.615.362zm-.226-9.694c.883 0 1.629.108 2.231.327.602.219 1.088.526 1.444.915.355.39.609.923.759 1.483a6.8 6.8 0 01.233 1.852v6.873c-.41.088-1.034.19-1.868.314-.834.123-1.772.184-2.813.184-.69 0-1.327-.068-1.895-.198a4.001 4.001 0 01-1.471-.635 3.085 3.085 0 01-.951-1.134c-.226-.465-.343-1.12-.343-1.804 0-.656.13-1.073.384-1.524.26-.45.608-.82 1.047-1.107.445-.286.95-.491 1.532-.614a8.803 8.803 0 012.751-.13c.329.034.671.096 1.04.185v-.437a3.3 3.3 0 00-.109-.875 1.873 1.873 0 00-.384-.731 1.784 1.784 0 00-.724-.492 3.165 3.165 0 00-1.143-.205c-.616 0-1.177.075-1.69.164a7.75 7.75 0 00-1.26.307l-.321-2.193c.335-.116.834-.232 1.478-.348a11.633 11.633 0 012.073-.177zm-8.034-1.271a1.626 1.626 0 01-1.628-1.62c0-.895.725-1.62 1.628-1.62.904 0 1.63.725 1.63 1.62 0 .895-.733 1.62-1.63 1.62zm1.348 13.22h-2.689V7.27l2.69-.423v11.956zm-4.714 0c-4.386.02-4.386-3.54-4.386-4.107l-.008-13.336 2.676-.424v13.254c0 .322 0 2.358 1.718 2.364v2.248zm-8.698-5.903c0-1.156-.253-2.119-.746-2.788-.493-.677-1.183-1.01-2.067-1.01-.882 0-1.574.333-2.065 1.01-.493.676-.733 1.632-.733 2.788 0 1.168.246 1.953.74 2.63.492.683 1.183 1.018 2.066 1.018.882 0 1.574-.342 2.067-1.019.492-.683.738-1.46.738-2.63zm2.737-.007c0 .902-.13 1.584-.397 2.33a5.52 5.52 0 01-1.128 1.906 4.986 4.986 0 01-1.752 1.223c-.685.286-1.739.45-2.265.45-.528-.006-1.574-.157-2.252-.45a5.096 5.096 0 01-1.744-1.223c-.487-.527-.863-1.162-1.137-1.906a6.345 6.345 0 01-.41-2.33c0-.902.123-1.77.397-2.508a5.554 5.554 0 011.15-1.892 5.133 5.133 0 011.75-1.216c.679-.287 1.425-.423 2.232-.423.808 0 1.553.142 2.237.423a4.88 4.88 0 011.753 1.216 5.644 5.644 0 011.135 1.892c.287.738.431 1.606.431 2.508zm-20.138 0c0 1.12.246 2.363.738 2.882.493.52 1.13.78 1.91.78.424 0 .828-.062 1.204-.178.377-.116.677-.253.917-.417V9.33a10.476 10.476 0 00-1.766-.226c-.971-.028-1.71.37-2.23 1.004-.513.636-.773 1.75-.773 2.788zm7.438 5.274c0 1.824-.466 3.156-1.404 4.004-.936.846-2.367 1.27-4.296 1.27-.705 0-2.17-.137-3.34-.396l.431-2.118c.98.205 2.272.26 2.95.26 1.074 0 1.84-.219 2.299-.656.459-.437.684-1.086.684-1.948v-.437a8.07 8.07 0 01-1.047.397c-.43.13-.93.198-1.492.198-.739 0-1.41-.116-2.018-.349a4.206 4.206 0 01-1.567-1.025c-.431-.45-.774-1.017-1.013-1.694-.24-.677-.363-1.885-.363-2.773 0-.834.13-1.88.384-2.577.26-.696.629-1.298 1.129-1.796.493-.498 1.095-.881 1.8-1.162a6.605 6.605 0 012.428-.457c.87 0 1.67.109 2.45.24.78.129 1.444.265 1.985.415V18.17z' fill='%235468FF'/%3E%3Cpath d='M6.972 6.677v1.627c-.712-.446-1.52-.67-2.425-.67-.585 0-1.045.13-1.38.391a1.24 1.24 0 00-.502 1.03c0 .425.164.765.494 1.02.33.256.835.532 1.516.83.447.192.795.356 1.045.495.25.138.537.332.862.582.324.25.563.548.718.894.154.345.23.741.23 1.188 0 .947-.334 1.691-1.004 2.234-.67.542-1.537.814-2.601.814-1.18 0-2.16-.229-2.936-.686v-1.708c.84.628 1.814.942 2.92.942.585 0 1.048-.136 1.388-.407.34-.271.51-.646.51-1.125 0-.287-.1-.55-.302-.79-.203-.24-.42-.42-.655-.542-.234-.123-.585-.29-1.053-.503a61.27 61.27 0 01-.582-.271 13.67 13.67 0 01-.55-.287 4.275 4.275 0 01-.567-.351 6.92 6.92 0 01-.455-.4c-.18-.17-.31-.34-.39-.51-.08-.17-.155-.37-.224-.598a2.553 2.553 0 01-.104-.742c0-.915.333-1.638.998-2.17.664-.532 1.523-.798 2.576-.798.968 0 1.793.17 2.473.51zm7.468 5.696v-.287c-.022-.607-.187-1.088-.495-1.444-.309-.357-.75-.535-1.324-.535-.532 0-.99.194-1.373.583-.382.388-.622.949-.717 1.683h3.909zm1.005 2.792v1.404c-.596.34-1.383.51-2.362.51-1.255 0-2.255-.377-3-1.132-.744-.755-1.116-1.744-1.116-2.968 0-1.297.34-2.316 1.021-3.055.68-.74 1.548-1.11 2.6-1.11 1.033 0 1.852.323 2.458.966.606.644.91 1.572.91 2.784 0 .33-.033.676-.096 1.038h-5.314c.107.702.405 1.239.894 1.611.49.372 1.106.558 1.85.558.862 0 1.58-.202 2.155-.606zm6.605-1.77h-1.212c-.596 0-1.045.116-1.349.35-.303.234-.454.532-.454.894 0 .372.117.664.35.877.235.213.575.32 1.022.32.51 0 .912-.142 1.204-.424.293-.281.44-.651.44-1.108v-.91zm-4.068-2.554V9.325c.627-.361 1.457-.542 2.489-.542 2.116 0 3.175 1.026 3.175 3.08V17h-1.548v-.957c-.415.68-1.143 1.02-2.186 1.02-.766 0-1.38-.22-1.843-.661-.462-.442-.694-1.003-.694-1.684 0-.776.293-1.38.878-1.81.585-.431 1.404-.647 2.457-.647h1.34V11.8c0-.554-.133-.971-.399-1.253-.266-.282-.707-.423-1.324-.423a4.07 4.07 0 00-2.345.718zm9.333-1.93v1.42c.394-1 1.101-1.5 2.123-1.5.148 0 .313.016.494.048v1.531a1.885 1.885 0 00-.75-.143c-.542 0-.989.24-1.34.718-.351.479-.527 1.048-.527 1.707V17h-1.563V8.91h1.563zm5.01 4.084c.022.82.272 1.492.75 2.019.479.526 1.15.79 2.01.79.639 0 1.235-.176 1.788-.527v1.404c-.521.319-1.186.479-1.995.479-1.265 0-2.276-.4-3.031-1.197-.755-.798-1.133-1.792-1.133-2.984 0-1.16.38-2.151 1.14-2.975.761-.825 1.79-1.237 3.088-1.237.702 0 1.346.149 1.93.447v1.436a3.242 3.242 0 00-1.77-.495c-.84 0-1.513.266-2.019.798-.505.532-.758 1.213-.758 2.042zM40.24 5.72v4.579c.458-1 1.293-1.5 2.505-1.5.787 0 1.42.245 1.899.734.479.49.718 1.17.718 2.042V17h-1.564v-5.106c0-.553-.14-.98-.422-1.284-.282-.303-.652-.455-1.11-.455-.531 0-1.002.202-1.411.606-.41.405-.615 1.022-.615 1.851V17h-1.563V5.72h1.563zm14.966 10.02c.596 0 1.096-.253 1.5-.758.404-.506.606-1.157.606-1.955 0-.915-.202-1.62-.606-2.114-.404-.495-.92-.742-1.548-.742-.553 0-1.05.224-1.491.67-.442.447-.662 1.133-.662 2.058 0 .958.212 1.67.638 2.138.425.469.946.703 1.563.703zM53.004 5.72v4.42c.574-.894 1.388-1.341 2.44-1.341 1.022 0 1.857.383 2.506 1.149.649.766.973 1.781.973 3.047 0 1.138-.309 2.109-.925 2.912-.617.803-1.463 1.205-2.537 1.205-1.075 0-1.894-.447-2.457-1.34V17h-1.58V5.72h1.58zm9.908 11.104l-3.223-7.913h1.739l1.005 2.632 1.26 3.415c.096-.32.48-1.458 1.15-3.415l.909-2.632h1.66l-2.92 7.866c-.777 2.074-1.963 3.11-3.559 3.11a2.92 2.92 0 01-.734-.079v-1.34c.17.042.351.064.543.064 1.032 0 1.755-.57 2.17-1.708z' fill='%235D6494'/%3E%3Cpath d='M89.632 5.967v-.772a.978.978 0 00-.978-.977h-2.28a.978.978 0 00-.978.977v.793c0 .088.082.15.171.13a7.127 7.127 0 011.984-.28c.65 0 1.295.088 1.917.259.082.02.164-.04.164-.13m-6.248 1.01l-.39-.389a.977.977 0 00-1.382 0l-.465.465a.973.973 0 000 1.38l.383.383c.062.061.15.047.205-.014.226-.307.472-.601.746-.874.281-.28.568-.526.883-.751.068-.042.075-.137.02-.2m4.16 2.453v3.341c0 .096.104.165.192.117l2.97-1.537c.068-.034.089-.117.055-.184a3.695 3.695 0 00-3.08-1.866c-.068 0-.136.054-.136.13m0 8.048a4.489 4.489 0 01-4.49-4.482 4.488 4.488 0 014.49-4.482 4.488 4.488 0 014.489 4.482 4.484 4.484 0 01-4.49 4.482m0-10.85a6.363 6.363 0 100 12.729 6.37 6.37 0 006.372-6.368 6.358 6.358 0 00-6.371-6.36' fill='%23FFF'/%3E%3C/g%3E%3C/svg%3E");background-repeat:no-repeat;background-position:50%;background-size:100%;overflow:hidden;text-indent:-9000px;padding:0!important;width:100%;height:100%;display:block} \ No newline at end of file diff --git a/assets/img/search.83621669.svg b/assets/img/search.83621669.svg new file mode 100644 index 000000000..03d83913e --- /dev/null +++ b/assets/img/search.83621669.svg @@ -0,0 +1 @@ + diff --git a/assets/js/10.b593aa85.js b/assets/js/10.b593aa85.js new file mode 100644 index 000000000..ac9fd116a --- /dev/null +++ b/assets/js/10.b593aa85.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[10],{175:function(t,e,a){},208:function(t,e,a){"use strict";a(175)},221:function(t,e,a){"use strict";a.r(e);var s={name:"CodeBlock",props:{title:{type:String,required:!0},active:{type:Boolean,default:!1}},mounted(){this.$parent&&this.$parent.loadTabs&&this.$parent.loadTabs()}},i=(a(208),a(6)),n=Object(i.a)(s,(function(){var t=this.$createElement;return(this._self._c||t)("div",{staticClass:"theme-code-block",class:{"theme-code-block__active":this.active}},[this._t("default")],2)}),[],!1,null,"759a7d02",null);e.default=n.exports}}]); \ No newline at end of file diff --git a/assets/js/11.e70694b8.js b/assets/js/11.e70694b8.js new file mode 100644 index 000000000..035a34309 --- /dev/null +++ b/assets/js/11.e70694b8.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[11],{176:function(e,t,a){},209:function(e,t,a){"use strict";a(176)},222:function(e,t,a){"use strict";a.r(t);var o={name:"CodeGroup",data:()=>({codeTabs:[],activeCodeTabIndex:-1}),watch:{activeCodeTabIndex(e){this.activateCodeTab(e)}},mounted(){this.loadTabs()},methods:{changeCodeTab(e){this.activeCodeTabIndex=e},loadTabs(){this.codeTabs=(this.$slots.default||[]).filter(e=>Boolean(e.componentOptions)).map((e,t)=>(""===e.componentOptions.propsData.active&&(this.activeCodeTabIndex=t),{title:e.componentOptions.propsData.title,elm:e.elm})),-1===this.activeCodeTabIndex&&this.codeTabs.length>0&&(this.activeCodeTabIndex=0),this.activateCodeTab(0)},activateCodeTab(e){this.codeTabs.forEach(e=>{e.elm&&e.elm.classList.remove("theme-code-block__active")}),this.codeTabs[e].elm&&this.codeTabs[e].elm.classList.add("theme-code-block__active")}}},s=(a(209),a(6)),c=Object(s.a)(o,(function(){var e=this,t=e.$createElement,a=e._self._c||t;return a("ClientOnly",[a("div",{staticClass:"theme-code-group"},[a("div",{staticClass:"theme-code-group__nav"},[a("ul",{staticClass:"theme-code-group__ul"},e._l(e.codeTabs,(function(t,o){return a("li",{key:t.title,staticClass:"theme-code-group__li"},[a("button",{staticClass:"theme-code-group__nav-tab",class:{"theme-code-group__nav-tab-active":o===e.activeCodeTabIndex},on:{click:function(t){return e.changeCodeTab(o)}}},[e._v("\n "+e._s(t.title)+"\n ")])])})),0)]),e._v(" "),e._t("default"),e._v(" "),e.codeTabs.length<1?a("pre",{staticClass:"pre-blank"},[e._v("// Make sure to add code blocks to your code group")]):e._e()],2)])}),[],!1,null,"deefee04",null);t.default=c.exports}}]); \ No newline at end of file diff --git a/assets/js/12.eac7b90f.js b/assets/js/12.eac7b90f.js new file mode 100644 index 000000000..69922ea8c --- /dev/null +++ b/assets/js/12.eac7b90f.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[12],{170:function(t,e,s){},199:function(t,e,s){"use strict";s(170)},217:function(t,e,s){"use strict";s.r(e);var n={name:"Community",data(){return{members:this.members||[]}},mounted(){fetch("https://green-sun-f03e.encors.workers.dev/?url="+encodeURIComponent("https://discordapp.com/api/guilds/721472913886281818/widget.json"),{mode:"cors",credentials:"omit"}).then(t=>t.json()).then(({members:t})=>{this.members=t.filter(t=>"string"==typeof t.username&&"string"==typeof t.avatar_url&&t.avatar_url.startsWith("https://cdn.discordapp.com/")&&["online","idle","dnd"].includes(t.status))}).catch(t=>{})}},r=(s(199),s(6)),a=Object(r.a)(n,(function(){var t=this.$createElement,e=this._self._c||t;return this.members.length>0?e("div",{staticClass:"community"},[e("div",{staticClass:"list"},this._l(this.members,(function(t){return e("a",{class:t.status,attrs:{href:"https://discord.gg/assemblyscript",title:t.username,target:"_blank",rel:"noopener"}},[e("img",{attrs:{src:t.avatar_url+"?size=64",alt:t.username,loading:"lazy"}})])})),0)]):this._e()}),[],!1,null,"181c7660",null);e.default=a.exports}}]); \ No newline at end of file diff --git a/assets/js/13.a23bc4f4.js b/assets/js/13.a23bc4f4.js new file mode 100644 index 000000000..8aaf08eac --- /dev/null +++ b/assets/js/13.a23bc4f4.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[13],{215:function(t,e,s){"use strict";s.r(e);const o=["There's nothing here.","How did we get here?","That's a Four-Oh-Four.","Looks like we've got some broken links."];var n={methods:{getMsg:()=>o[Math.floor(Math.random()*o.length)]}},h=s(6),i=Object(h.a)(n,(function(){var t=this.$createElement,e=this._self._c||t;return e("div",{staticClass:"theme-container"},[e("div",{staticClass:"theme-default-content"},[e("h1",[this._v("404")]),this._v(" "),e("blockquote",[this._v(this._s(this.getMsg()))]),this._v(" "),e("RouterLink",{attrs:{to:"/"}},[this._v("\n Take me home.\n ")])],1)])}),[],!1,null,null,null);e.default=i.exports}}]); \ No newline at end of file diff --git a/assets/js/14.38407d5c.js b/assets/js/14.38407d5c.js new file mode 100644 index 000000000..5a0526468 --- /dev/null +++ b/assets/js/14.38407d5c.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[14],{259:function(t,e,s){"use strict";s.r(e);var n=s(6),i=Object(n.a)({},(function(){var t=this.$createElement;return(this._self._c||t)("img",{staticClass:"engine",attrs:{src:"/images/chrome.svg",width:"18",height:"18",title:"Chrome"}})}),[],!1,null,null,null);e.default=i.exports}}]); \ No newline at end of file diff --git a/assets/js/15.ccfb67c4.js b/assets/js/15.ccfb67c4.js new file mode 100644 index 000000000..1d437a08c --- /dev/null +++ b/assets/js/15.ccfb67c4.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[15],{261:function(t,e,i){"use strict";i.r(e);var s=i(6),n=Object(s.a)({},(function(){var t=this.$createElement;return(this._self._c||t)("img",{staticClass:"engine",attrs:{src:"/images/firefox.svg",width:"18",height:"18",title:"Firefox"}})}),[],!1,null,null,null);e.default=n.exports}}]); \ No newline at end of file diff --git a/assets/js/16.9e12fbb3.js b/assets/js/16.9e12fbb3.js new file mode 100644 index 000000000..a6830bc33 --- /dev/null +++ b/assets/js/16.9e12fbb3.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[16],{260:function(t,e,s){"use strict";s.r(e);var n=s(6),i=Object(n.a)({},(function(){var t=this.$createElement;return(this._self._c||t)("img",{staticClass:"engine",attrs:{src:"/images/nodejs.svg",width:"18",height:"18",title:"Node.js"}})}),[],!1,null,null,null);e.default=i.exports}}]); \ No newline at end of file diff --git a/assets/js/17.ebe32f37.js b/assets/js/17.ebe32f37.js new file mode 100644 index 000000000..5758879f9 --- /dev/null +++ b/assets/js/17.ebe32f37.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[17],{262:function(t,e,s){"use strict";s.r(e);var i=s(6),a=Object(i.a)({},(function(){var t=this.$createElement;return(this._self._c||t)("img",{staticClass:"engine",attrs:{src:"/images/safari.svg",width:"18",height:"18",title:"Safari"}})}),[],!1,null,null,null);e.default=a.exports}}]); \ No newline at end of file diff --git a/assets/js/18.e8b2f77f.js b/assets/js/18.e8b2f77f.js new file mode 100644 index 000000000..91ac35eaa --- /dev/null +++ b/assets/js/18.e8b2f77f.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[18],{263:function(t,e,s){"use strict";s.r(e);var n=s(6),i=Object(n.a)({},(function(){var t=this.$createElement;return(this._self._c||t)("img",{staticClass:"engine",attrs:{src:"/images/wasmer.svg",width:"18",height:"18",title:"Wasmer"}})}),[],!1,null,null,null);e.default=i.exports}}]); \ No newline at end of file diff --git a/assets/js/19.70bbb3ef.js b/assets/js/19.70bbb3ef.js new file mode 100644 index 000000000..00abcf750 --- /dev/null +++ b/assets/js/19.70bbb3ef.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[19],{264:function(t,e,n){"use strict";n.r(e);var i=n(6),s=Object(i.a)({},(function(){var t=this.$createElement;return(this._self._c||t)("img",{staticClass:"engine",attrs:{src:"/images/noimage.png",width:"18",height:"18",title:"Wasmtime"}})}),[],!1,null,null,null);e.default=s.exports}}]); \ No newline at end of file diff --git a/assets/js/20.10384fec.js b/assets/js/20.10384fec.js new file mode 100644 index 000000000..1057475b7 --- /dev/null +++ b/assets/js/20.10384fec.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[20],{265:function(t,n,e){"use strict";e.r(n);var i=e(6),l=Object(i.a)({},(function(){var t=this.$createElement;return(this._self._c||t)("span",{staticStyle:{display:"inline-block",width:"18px",height:"18px"}})}),[],!1,null,null,null);n.default=l.exports}}]); \ No newline at end of file diff --git a/assets/js/21.0ad30828.js b/assets/js/21.0ad30828.js new file mode 100644 index 000000000..03c85fefe --- /dev/null +++ b/assets/js/21.0ad30828.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[21],{223:function(r,e,t){"use strict";t.r(e);var a=t(6),n=Object(a.a)({},(function(){var r=this,e=r.$createElement,t=r._self._c||e;return t("ContentSlotsDistributor",{attrs:{"slot-key":r.$parent.slotKey}},[t("h1",{attrs:{id:"built-with-assemblyscript"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#built-with-assemblyscript"}},[r._v("#")]),r._v(" Built with AssemblyScript")]),r._v(" "),t("p",[r._v("A place for all things AssemblyScript. Feel free to add your projects and applications.")]),r._v(" "),t("h2",{attrs:{id:"benchmarks"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#benchmarks"}},[r._v("#")]),r._v(" Benchmarks")]),r._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"https://github.com/jtiscione/webassembly-wave",target:"_blank",rel:"noopener noreferrer"}},[r._v("webassembly-wave"),t("OutboundLink")],1),r._v(" ("),t("a",{attrs:{href:"https://jtiscione.github.io/webassembly-wave/index.html",target:"_blank",rel:"noopener noreferrer"}},[r._v("demo"),t("OutboundLink")],1),r._v(")"),t("br"),r._v("\nJavaScript vs WebAssembly performance comparison - wave equation demo (JS, C++, AssemblyScript).")]),r._v(" "),t("li",[t("a",{attrs:{href:"https://github.com/t-katsumura/webassembly-examples-eratosthenes",target:"_blank",rel:"noopener noreferrer"}},[r._v("Eratosthenes"),t("OutboundLink")],1),t("br"),r._v("\nWebAssembly examples which calculate prime by Sieve of Eratosthenes.")]),r._v(" "),t("li",[t("a",{attrs:{href:"https://wasmboy.app/benchmark/",target:"_blank",rel:"noopener noreferrer"}},[r._v("WasmBoy Benchmark"),t("OutboundLink")],1),t("br"),r._v("\nBenchmarking WasmBoy emulator.")]),r._v(" "),t("li",[t("a",{attrs:{href:"https://github.com/w8r/wasm-n-body",target:"_blank",rel:"noopener noreferrer"}},[r._v("wasm-n-body"),t("OutboundLink")],1),t("br"),r._v("\nWebAssembly N-body simulation benchmark "),t("em",[r._v("(use 1000 bodies compare to original).")])]),r._v(" "),t("li",[t("a",{attrs:{href:"https://github.com/nischayv/as-benchmarks",target:"_blank",rel:"noopener noreferrer"}},[r._v("as-benchmarks"),t("OutboundLink")],1),r._v(" ("),t("a",{attrs:{href:"https://nischayv.github.io/as-benchmarks/index.html",target:"_blank",rel:"noopener noreferrer"}},[r._v("demo"),t("OutboundLink")],1),r._v(")"),t("br"),r._v("\nA set of computational benchmarks (JS, AssemblyScript).")]),r._v(" "),t("li",[t("a",{attrs:{href:"https://github.com/manueldois/WebAssembly/tree/master/Sort%20Colors%20Benchmark/src",target:"_blank",rel:"noopener noreferrer"}},[r._v("Sort Colors Benchmark"),t("OutboundLink")],1),r._v(" ("),t("a",{attrs:{href:"https://manueldois.github.io/WebAssembly/Sort%20Colors%20Benchmark/dist/index.html",target:"_blank",rel:"noopener noreferrer"}},[r._v("demo"),t("OutboundLink")],1),r._v(")"),t("br"),r._v("\nBench of sorting random colors by hue component on 2d canvas.")]),r._v(" "),t("li",[t("a",{attrs:{href:"https://github.com/ColinEberhardt/wasm-mandelbrot",target:"_blank",rel:"noopener noreferrer"}},[r._v("Wasm Mandelbrot"),t("OutboundLink")],1),r._v(" ("),t("a",{attrs:{href:"https://colineberhardt.github.io/wasm-mandelbrot/#AssemblyScript",target:"_blank",rel:"noopener noreferrer"}},[r._v("demo"),t("OutboundLink")],1),r._v(")"),t("br"),r._v("\nA mandelbrot rendered using a variety of WebAssembly tools (emscripten, AssemblyScript, asm.js, etc ...)")])]),r._v(" "),t("h2",{attrs:{id:"blockchain"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#blockchain"}},[r._v("#")]),r._v(" Blockchain")]),r._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"https://github.com/ascontract/subscript",target:"_blank",rel:"noopener noreferrer"}},[r._v("ASContract / subscript"),t("OutboundLink")],1),t("br"),r._v("\nSubstrate smart contract framework written in AssemblyScript.")]),r._v(" "),t("li",[t("a",{attrs:{href:"https://github.com/ewasm/biturbo",target:"_blank",rel:"noopener noreferrer"}},[r._v("eWasm / Biturbo"),t("OutboundLink")],1),t("br"),r._v("\nEth1 EE using Turboproofs.")]),r._v(" "),t("li",[t("a",{attrs:{href:"https://github.com/ewasm/scout.ts",target:"_blank",rel:"noopener noreferrer"}},[r._v("ewasm / scout.ts "),t("OutboundLink")],1),t("br"),r._v("\nScout is a Ethereum 2.0 Phase 2 execution prototyping engine (AssemblyScript Port).")]),r._v(" "),t("li",[t("a",{attrs:{href:"https://github.com/near/near-sdk-as",target:"_blank",rel:"noopener noreferrer"}},[r._v("NearProtocol / near-sdk-as"),t("OutboundLink")],1),t("br"),r._v("\nAssemblyScript tools for writing smart contracts for NearProtocol.")]),r._v(" "),t("li",[t("a",{attrs:{href:"https://github.com/graphprotocol/graph-ts",target:"_blank",rel:"noopener noreferrer"}},[r._v("GraphProtocol / graph-ts"),t("OutboundLink")],1),t("br"),r._v("\nTypeScript/AssemblyScript library for writing mappings for "),t("a",{attrs:{href:"https://thegraph.com",target:"_blank",rel:"noopener noreferrer"}},[r._v("The Graph"),t("OutboundLink")],1),r._v(".")]),r._v(" "),t("li",[t("a",{attrs:{href:"https://github.com/ChainSafe/as-sha256",target:"_blank",rel:"noopener noreferrer"}},[r._v("ChainSafe / as-sha256"),t("OutboundLink")],1),t("br"),r._v("\nAssemblyScript implementation of SHA256 for "),t("a",{attrs:{href:"https://github.com/ChainSafe/lodestar",target:"_blank",rel:"noopener noreferrer"}},[r._v("Lodestar"),t("OutboundLink")],1),r._v(".")]),r._v(" "),t("li",[t("a",{attrs:{href:"https://github.com/paritytech/srml-contracts-waterfall",target:"_blank",rel:"noopener noreferrer"}},[r._v("ParityTech / srml-contracts-waterfall"),t("OutboundLink")],1),t("br"),r._v("\nCollection of simple Substrate smart contract examples written in Rust and AssemblyScript and tests for Substrates SRML Contracts module.")])]),r._v(" "),t("h2",{attrs:{id:"build-tools"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#build-tools"}},[r._v("#")]),r._v(" Build Tools")]),r._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"https://github.com/lastmjs/zwitterion",target:"_blank",rel:"noopener noreferrer"}},[r._v("Zwitterion"),t("OutboundLink")],1),t("br"),r._v("\nA web dev server that lets you import anything*.")]),r._v(" "),t("li",[t("a",{attrs:{href:"https://github.com/surma/rollup-plugin-assemblyscript",target:"_blank",rel:"noopener noreferrer"}},[r._v("rollup-plugin-assemblyscript"),t("OutboundLink")],1),t("br"),r._v("\nA Rollup plugin that allows you to import AssemblyScript files and compiles them on-the-fly.")]),r._v(" "),t("li",[t("a",{attrs:{href:"https://github.com/piotr-oles/as-loader",target:"_blank",rel:"noopener noreferrer"}},[r._v("as-loader"),t("OutboundLink")],1),t("br"),r._v("\nA webpack loader for AssemblyScript")]),r._v(" "),t("li",[t("a",{attrs:{href:"https://github.com/willemneal/visitor-as",target:"_blank",rel:"noopener noreferrer"}},[r._v("visitor-as"),t("OutboundLink")],1),t("br"),r._v("\nTools for creating compiler transformers.")])]),r._v(" "),t("h2",{attrs:{id:"demoscene"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#demoscene"}},[r._v("#")]),r._v(" Demoscene")]),r._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"https://wasm-demo.codument.com",target:"_blank",rel:"noopener noreferrer"}},[r._v("Hoofdkantoor WASM Demo"),t("OutboundLink")],1),t("br"),r._v("\nA demo built with AssemblyScript (also TS and Web Audio API). It's an homage to the old school Demoscene of the early 90s.")])]),r._v(" "),t("h2",{attrs:{id:"editors"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#editors"}},[r._v("#")]),r._v(" Editors")]),r._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"https://wasm.fastlylabs.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("Fastly Terrarium"),t("OutboundLink")],1),t("br"),r._v("\nA compilation toolchain and sandbox to run WebAssembly server-side, with native support for AssemblyScript.")]),r._v(" "),t("li",[t("a",{attrs:{href:"https://examples.near.org/",target:"_blank",rel:"noopener noreferrer"}},[r._v("NEAR Protocol Examples"),t("OutboundLink")],1),t("br"),r._v("\nExamples that use "),t("a",{attrs:{href:"https://gitpod.io/",target:"_blank",rel:"noopener noreferrer"}},[r._v("GitPod"),t("OutboundLink")],1),r._v(" to develop and deploy distributed web apps using NEAR smart contracts authored in AssemblyScript.")]),r._v(" "),t("li",[t("a",{attrs:{href:"https://alpha.iodide.io/notebooks/1234",target:"_blank",rel:"noopener noreferrer"}},[r._v("Iodide Notebook"),t("OutboundLink")],1),t("br"),r._v("\nExperimental tool for scientific communication and exploration on the web ("),t("a",{attrs:{href:"https://hacks.mozilla.org/2019/03/iodide-an-experimental-tool-for-scientific-communicatiodide-for-scientific-communication-exploration-on-the-web",target:"_blank",rel:"noopener noreferrer"}},[r._v("more"),t("OutboundLink")],1),r._v(").")])]),r._v(" "),t("h2",{attrs:{id:"formatter"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#formatter"}},[r._v("#")]),r._v(" Formatter")]),r._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"https://github.com/HerrCai0907/assemblyscript-prettier",target:"_blank",rel:"noopener noreferrer"}},[r._v("assemblyscript-prettier"),t("OutboundLink")],1),t("br"),r._v("\nPrettier plugin for assemblyscript to resolve the incompatible part of ts and as syntax")])]),r._v(" "),t("h2",{attrs:{id:"emulators"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#emulators"}},[r._v("#")]),r._v(" Emulators")]),r._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"https://github.com/torch2424/wasmBoy",target:"_blank",rel:"noopener noreferrer"}},[r._v("wasmBoy"),t("OutboundLink")],1),r._v(" ("),t("a",{attrs:{href:"https://wasmboy.app/",target:"_blank",rel:"noopener noreferrer"}},[r._v("demo"),t("OutboundLink")],1),r._v(")"),t("br"),r._v("\nGame Boy / Game Boy Color Emulator Library, written for WebAssembly using AssemblyScript.")]),r._v(" "),t("li",[t("a",{attrs:{href:"https://github.com/ColinEberhardt/atari2600-wasm",target:"_blank",rel:"noopener noreferrer"}},[r._v("Atari 2600"),t("OutboundLink")],1),t("br"),r._v("\nAn Atari 2600 emulator written in AssemblyScript compiled to WebAssembly.")]),r._v(" "),t("li",[t("a",{attrs:{href:"https://github.com/Dotneteer/as-spectrum-engine",target:"_blank",rel:"noopener noreferrer"}},[r._v("as-spectrum-engine"),t("OutboundLink")],1),t("br"),r._v("\nAssemblyScript implementation of a ZX Spectrum emulator engine.")])]),r._v(" "),t("h2",{attrs:{id:"games"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#games"}},[r._v("#")]),r._v(" Games")]),r._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"https://github.com/mhonert/chess",target:"_blank",rel:"noopener noreferrer"}},[r._v("Chess"),t("OutboundLink")],1),r._v(" ("),t("a",{attrs:{href:"https://mhonert.github.io/chess",target:"_blank",rel:"noopener noreferrer"}},[r._v("play"),t("OutboundLink")],1),r._v(")"),t("br"),r._v("\nA free and open source chess game using AssemblyScript and React.")]),r._v(" "),t("li",[t("a",{attrs:{href:"https://github.com/jolestar/gomoku-wasm",target:"_blank",rel:"noopener noreferrer"}},[r._v("Gomoku WASM"),t("OutboundLink")],1),r._v(" ("),t("a",{attrs:{href:"http://jolestar.com/gomoku-wasm",target:"_blank",rel:"noopener noreferrer"}},[r._v("play"),t("OutboundLink")],1),r._v(")"),t("br"),r._v("\nA Gomoku game implements with WebAssembly using "),t("a",{attrs:{href:"https://github.com/as2d/as2d",target:"_blank",rel:"noopener noreferrer"}},[r._v("as2d"),t("OutboundLink")],1),r._v(".")]),r._v(" "),t("li",[t("a",{attrs:{href:"https://github.com/ttulka/2d-videogame-in-assemblyscript",target:"_blank",rel:"noopener noreferrer"}},[r._v("2d-videogame-in-assemblyscript"),t("OutboundLink")],1),t("br"),r._v("\nDemo 2D videogame in AssemblyScript.")]),r._v(" "),t("li",[t("a",{attrs:{href:"https://github.com/ameliabradley/fiberoptic-game",target:"_blank",rel:"noopener noreferrer"}},[r._v("fiberoptic-game"),t("OutboundLink")],1),t("br"),r._v("\nWeb game produced with AssemblyScript for js13k 2018.")])]),r._v(" "),t("h2",{attrs:{id:"graphics-game-frameworks"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#graphics-game-frameworks"}},[r._v("#")]),r._v(" Graphics / Game Frameworks")]),r._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"https://github.com/as2d/as2d",target:"_blank",rel:"noopener noreferrer"}},[r._v("as2d"),t("OutboundLink")],1),t("br"),r._v("\n["),t("em",[r._v("Deprecated")]),r._v("] Bring the power of the CanvasRenderingContext2D prototype to AssemblyScript.")]),r._v(" "),t("li",[t("a",{attrs:{href:"https://github.com/mrchantey/koora",target:"_blank",rel:"noopener noreferrer"}},[r._v("koora"),t("OutboundLink")],1),t("br"),r._v("\nAssemblyscript 3D Game Framework.")]),r._v(" "),t("li",[t("a",{attrs:{href:"https://github.com/01alchemist/as-smallpt",target:"_blank",rel:"noopener noreferrer"}},[r._v("as-smallpt"),t("OutboundLink")],1),t("br"),r._v("\nPort of C++ smallpt, a path tracing renderer.")]),r._v(" "),t("li",[t("a",{attrs:{href:"https://github.com/ycw/Babylon.Font",target:"_blank",rel:"noopener noreferrer"}},[r._v("Babylon.Font"),t("OutboundLink")],1),t("br"),r._v("\nCreate 3d text in BabylonJS.")]),r._v(" "),t("li",[t("a",{attrs:{href:"https://github.com/Tugcga/Path-Finder/tree/main/assemblyscript",target:"_blank",rel:"noopener noreferrer"}},[r._v("Path-Finder"),t("OutboundLink")],1),t("br"),r._v("\nAssemblyScript NavMesh Path Finder.")]),r._v(" "),t("li",[t("a",{attrs:{href:"https://github.com/alexvictoor/seam-carving-as",target:"_blank",rel:"noopener noreferrer"}},[r._v("seam-carving-as"),t("OutboundLink")],1),t("br"),r._v("\nSeam Carving experiments with AssemblyScript.")]),r._v(" "),t("li",[t("a",{attrs:{href:"https://github.com/battlelinegames/ASWebGLue",target:"_blank",rel:"noopener noreferrer"}},[r._v("ASWebGLue"),t("OutboundLink")],1),t("br"),r._v("\nWebGL bindings for AssemblyScript.")]),r._v(" "),t("li",[t("a",{attrs:{href:"https://github.com/lume/glas",target:"_blank",rel:"noopener noreferrer"}},[r._v("GLAS"),t("OutboundLink")],1),t("br"),r._v("\nWeb"),t("strong",[r._v("GL")]),r._v(" in "),t("strong",[r._v("A")]),r._v("ssembly"),t("strong",[r._v("S")]),r._v("cript, port of "),t("a",{attrs:{href:"https://github.com/mrdoob/three.js/",target:"_blank",rel:"noopener noreferrer"}},[r._v("Three.js"),t("OutboundLink")],1),r._v(" to AssemblyScript.")])]),r._v(" "),t("h2",{attrs:{id:"data-serialization-deserialization"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#data-serialization-deserialization"}},[r._v("#")]),r._v(" Data Serialization / Deserialization")]),r._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"https://github.com/inkeliz/karmem",target:"_blank",rel:"noopener noreferrer"}},[r._v("karmem"),t("OutboundLink")],1),t("br"),r._v("\nKarmem is a fast binary serialization format, faster than Google Flatbuffers and optimized for WebAssembly languages.")]),r._v(" "),t("li",[t("a",{attrs:{href:"https://github.com/piotr-oles/as-proto",target:"_blank",rel:"noopener noreferrer"}},[r._v("as-proto"),t("OutboundLink")],1),t("br"),r._v("\nProtobuf encoder/decoder library.")]),r._v(" "),t("li",[t("a",{attrs:{href:"https://github.com/JairusSW/as-json",target:"_blank",rel:"noopener noreferrer"}},[r._v("as-json"),t("OutboundLink")],1),t("br"),r._v("\nJSON encoder / decoder.")]),r._v(" "),t("li",[t("a",{attrs:{href:"https://github.com/wapc/as-msgpack",target:"_blank",rel:"noopener noreferrer"}},[r._v("as-msgpack"),t("OutboundLink")],1),t("br"),r._v("\nMessagePack package for AssemblyScript.")]),r._v(" "),t("li",[t("a",{attrs:{href:"https://github.com/nearprotocol/assemblyscript-bson",target:"_blank",rel:"noopener noreferrer"}},[r._v("assemblyscript-bson"),t("OutboundLink")],1),t("br"),r._v("\nBSON encoder / decoder.")]),r._v(" "),t("li",[t("a",{attrs:{href:"https://github.com/nearprotocol/assemblyscript-json",target:"_blank",rel:"noopener noreferrer"}},[r._v("assemblyscript-json"),t("OutboundLink")],1),t("br"),r._v("\nJSON encoder / decoder.")]),r._v(" "),t("li",[t("a",{attrs:{href:"https://github.com/01alchemist/AS-LZMA",target:"_blank",rel:"noopener noreferrer"}},[r._v("AS-LZMA"),t("OutboundLink")],1),t("br"),r._v("\nLZMA Decoder written in AssemblyScript.")])]),r._v(" "),t("h2",{attrs:{id:"crypto-non-blockchain"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#crypto-non-blockchain"}},[r._v("#")]),r._v(" Crypto (non-blockchain)")]),r._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"https://github.com/mjethani/superfasthash",target:"_blank",rel:"noopener noreferrer"}},[r._v("superfasthash"),t("OutboundLink")],1),t("br"),r._v("\nAn implementation of the SuperFastHash non-cryptographic hashing algorithm in JavaScript and WebAssembly.")]),r._v(" "),t("li",[t("a",{attrs:{href:"https://github.com/jedisct1/wasm-crypto",target:"_blank",rel:"noopener noreferrer"}},[r._v("WASM-Crypto"),t("OutboundLink")],1),t("br"),r._v("\nAn AssemblyScript set of cryptographic primitives for building authentication and key exchange protocols.")]),r._v(" "),t("li",[t("a",{attrs:{href:"https://github.com/hugomrdias/rabin-wasm",target:"_blank",rel:"noopener noreferrer"}},[r._v("rabin-wasm"),t("OutboundLink")],1),t("br"),r._v("\nRabin fingerprinting implemented in WASM "),t("em",[r._v("(used by js-ipfs)")]),r._v(".")]),r._v(" "),t("li",[t("a",{attrs:{href:"https://github.com/krisselden/xoroshiro128starstar",target:"_blank",rel:"noopener noreferrer"}},[r._v("xoroshiro128starstar"),t("OutboundLink")],1),t("br"),r._v("\nAn AssemblyScript port of xoroshiro128starstar.c")])]),r._v(" "),t("h2",{attrs:{id:"fixed-arbitrary-precision-arithmetics"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#fixed-arbitrary-precision-arithmetics"}},[r._v("#")]),r._v(" Fixed & Arbitrary Precision Arithmetics")]),r._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"https://github.com/MaxGraey/as-bignum",target:"_blank",rel:"noopener noreferrer"}},[r._v("as-bignum"),t("OutboundLink")],1),t("br"),r._v("\nFixed length big numbers like "),t("code",[r._v("u128")]),r._v(", "),t("code",[r._v("i256")]),r._v(", "),t("code",[r._v("fp128")]),r._v(" and etc for AssemblyScript.")]),r._v(" "),t("li",[t("a",{attrs:{href:"https://github.com/ttulka/as-big",target:"_blank",rel:"noopener noreferrer"}},[r._v("as-big"),t("OutboundLink")],1),t("br"),r._v("\nAn AssemblyScript library for arbitrary-precision decimal arithmetic.")]),r._v(" "),t("li",[t("a",{attrs:{href:"https://github.com/polywrap/as-bigint",target:"_blank",rel:"noopener noreferrer"}},[r._v("as-bigint"),t("OutboundLink")],1),t("br"),r._v("\nBigInt is an AssemblyScript class for math with arbitrarily large integers.")]),r._v(" "),t("li",[t("a",{attrs:{href:"https://github.com/polywrap/as-bignumber",target:"_blank",rel:"noopener noreferrer"}},[r._v("as-bignumber"),t("OutboundLink")],1),t("br"),r._v("\nAn AssemblyScript class for math with arbitrary-precision decimal and integer numbers.")])]),r._v(" "),t("h2",{attrs:{id:"language-extensions-and-types"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#language-extensions-and-types"}},[r._v("#")]),r._v(" Language Extensions and Types")]),r._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"https://github.com/yjhmelody/as-container",target:"_blank",rel:"noopener noreferrer"}},[r._v("as-container"),t("OutboundLink")],1),r._v(" "),t("br"),r._v("\nAssemblyScript version of Rust Option and Result etc.")]),r._v(" "),t("li",[t("a",{attrs:{href:"https://github.com/MaxGraey/as-variant",target:"_blank",rel:"noopener noreferrer"}},[r._v("as-variant"),t("OutboundLink")],1),t("br"),r._v("\nVariant (aka Any) data type for AssemblyScript.")])]),r._v(" "),t("h2",{attrs:{id:"bindings"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#bindings"}},[r._v("#")]),r._v(" Bindings")]),r._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"https://github.com/lume/asdom",target:"_blank",rel:"noopener noreferrer"}},[r._v("asdom"),t("OutboundLink")],1),t("br"),r._v("\nDOM bindings for AssemblyScript.")]),r._v(" "),t("li",[t("a",{attrs:{href:"https://github.com/aspkg/ecmassembly",target:"_blank",rel:"noopener noreferrer"}},[r._v("ecmassembly"),t("OutboundLink")],1),t("br"),r._v("\nBindings for common ECMAScript/JavaScript APIs that require host scheduling ("),t("code",[r._v("setTimeout")]),r._v(", "),t("code",[r._v("Promise")]),r._v(", etc).")]),r._v(" "),t("li",[t("a",{attrs:{href:"https://github.com/miracle2k/wasmbind",target:"_blank",rel:"noopener noreferrer"}},[r._v("wasmbind"),t("OutboundLink")],1),t("br"),r._v("\nWork with AssemblyScript memory and classes from Python.")]),r._v(" "),t("li",[t("a",{attrs:{href:"https://github.com/torch2424/as-bind",target:"_blank",rel:"noopener noreferrer"}},[r._v("as-bind"),t("OutboundLink")],1),t("br"),r._v("\n["),t("em",[r._v("Deprecated")]),r._v("] Isomorphic library to handle passing high-level data structures between AssemblyScript and JavaScript, built on top of the AssemblyScript loader.")])]),r._v(" "),t("h2",{attrs:{id:"other-libraries"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#other-libraries"}},[r._v("#")]),r._v(" Other Libraries")]),r._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"https://github.com/samchon/astl",target:"_blank",rel:"noopener noreferrer"}},[r._v("ASTL"),t("OutboundLink")],1),t("br"),r._v("\n["),t("em",[r._v("Deprecated")]),r._v("] Migration project from C++ STL (Standard Template Library) to AssemblyScript. Containers, iterators, algorithms and functors are supported.")]),r._v(" "),t("li",[t("a",{attrs:{href:"https://github.com/kyranet/levenshtein-wasm",target:"_blank",rel:"noopener noreferrer"}},[r._v("Levenshtein Wasm"),t("OutboundLink")],1),t("br"),r._v("\nAn experimental lightning-fast Wasm-compiled levenshtein library.")]),r._v(" "),t("li",[t("a",{attrs:{href:"https://github.com/jedisct1/as-wasi",target:"_blank",rel:"noopener noreferrer"}},[r._v("as-wasi"),t("OutboundLink")],1),t("br"),r._v("\nAn AssemblyScript API layer for WASI system calls.")]),r._v(" "),t("li",[t("a",{attrs:{href:"https://github.com/GuildOfWeavers/galois",target:"_blank",rel:"noopener noreferrer"}},[r._v("galois"),t("OutboundLink")],1),t("br"),r._v("\nArithmetic and polynomial operations in finite fields.")]),r._v(" "),t("li",[t("a",{attrs:{href:"https://github.com/GuildOfWeavers/merkle",target:"_blank",rel:"noopener noreferrer"}},[r._v("merkle"),t("OutboundLink")],1),t("br"),r._v("\nMerkle tree and other data structures.")]),r._v(" "),t("li",[t("a",{attrs:{href:"https://github.com/jamesmilneruk/pixelmatch-asc",target:"_blank",rel:"noopener noreferrer"}},[r._v("pixelmatch-asc"),t("OutboundLink")],1),t("br"),r._v("\nPixel level image comparison library.")]),r._v(" "),t("li",[t("a",{attrs:{href:"https://github.com/onsails/wasmer-as",target:"_blank",rel:"noopener noreferrer"}},[r._v("wasmer-as"),t("OutboundLink")],1),t("br"),r._v("\nHelpers for dealing with assemblyscript memory inside wasmer-runtime.")]),r._v(" "),t("li",[t("a",{attrs:{href:"https://github.com/poria-cat/wasmer3-assemblyscript-example",target:"_blank",rel:"noopener noreferrer"}},[r._v("wasmer3-as"),t("OutboundLink")],1),t("br"),r._v("\nExamples of lift string and lower string in wasmer 3.0")]),r._v(" "),t("li",[t("a",{attrs:{href:"https://github.com/wasmerio/io-devices-lib",target:"_blank",rel:"noopener noreferrer"}},[r._v("io-devices-lib"),t("OutboundLink")],1),t("br"),r._v("\nLibrary for interacting with the Wasmer Experimental IO Devices.")]),r._v(" "),t("li",[t("a",{attrs:{href:"https://github.com/MaxGraey/as-string-sink",target:"_blank",rel:"noopener noreferrer"}},[r._v("as-string-sink"),t("OutboundLink")],1),t("br"),r._v("\nAn efficient dynamically sized string buffer (aka String Builder) for AssemblyScript.")])]),r._v(" "),t("h2",{attrs:{id:"embedded-iot"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#embedded-iot"}},[r._v("#")]),r._v(" Embedded / IoT")]),r._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"https://github.com/wasm3/wasm3-arduino/tree/main/wasm_apps",target:"_blank",rel:"noopener noreferrer"}},[r._v("wasm3-arduino"),t("OutboundLink")],1),t("br"),r._v("\nUsage example with wasm3 which run on Arduino, PlatformIO, Particle.")]),r._v(" "),t("li",[t("a",{attrs:{href:"https://github.com/vshymanskyy/Wasm3_RGB_Lamp",target:"_blank",rel:"noopener noreferrer"}},[r._v("Wasm3_RGB_Lamp"),t("OutboundLink")],1),t("br"),r._v("\nAnimating an RGB lamp, using WebAssembly (AssemblyScript).")]),r._v(" "),t("li",[t("a",{attrs:{href:"https://github.com/alvarowolfx/wasm-arduino-wifi",target:"_blank",rel:"noopener noreferrer"}},[r._v("wasm-arduino-wifi"),t("OutboundLink")],1),t("br"),r._v("\nExample how update WebAssembly via WiFi on arduino.")])]),r._v(" "),t("h2",{attrs:{id:"testing-benchmarking"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#testing-benchmarking"}},[r._v("#")]),r._v(" Testing / Benchmarking")]),r._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"https://github.com/romdotdog/as-tral",target:"_blank",rel:"noopener noreferrer"}},[r._v("as-tral"),t("OutboundLink")],1),t("br"),r._v("\nAssemblyScript benchmarking library inspired by criterion.rs. (Required AssemblyScript >= 0.20)")]),r._v(" "),t("li",[t("a",{attrs:{href:"https://github.com/jtenner/as-pect",target:"_blank",rel:"noopener noreferrer"}},[r._v("as-pect"),t("OutboundLink")],1),t("br"),r._v("\nA test framework inspired by jest. (Required AssemblyScript <= 0.19)")]),r._v(" "),t("li",[t("a",{attrs:{href:"https://github.com/jtenner/envy",target:"_blank",rel:"noopener noreferrer"}},[r._v("envy"),t("OutboundLink")],1),t("br"),r._v("\nA test framework spiritual successor of as-pect. (Required AssemblyScript >= 0.20)")])]),r._v(" "),t("h2",{attrs:{id:"project-templates"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#project-templates"}},[r._v("#")]),r._v(" Project Templates")]),r._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"https://github.com/JamesLMilner/worker-assemblyscript-template",target:"_blank",rel:"noopener noreferrer"}},[r._v("worker-assemblyscript-template"),t("OutboundLink")],1),t("br"),r._v("\nA Cloudflare wrangler template for an AssemblyScript worker.")])]),r._v(" "),t("h2",{attrs:{id:"applications"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#applications"}},[r._v("#")]),r._v(" Applications")]),r._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"https://github.com/torch2424/wasm-matrix",target:"_blank",rel:"noopener noreferrer"}},[r._v("wasm-matrix"),t("OutboundLink")],1),t("br"),r._v("\nA Matrix effect in your terminal using AssemblyScript and WASI, deployed to WAPM.")]),r._v(" "),t("li",[t("a",{attrs:{href:"https://petersalomonsen.com",target:"_blank",rel:"noopener noreferrer"}},[r._v("WebAssembly music experiment"),t("OutboundLink")],1),t("br"),r._v("\nA live coding environment in the browser for sequencing music with javascript and synthesizing instruments in AssemblyScript. Demonstrates compiling AssemblyScript directly in the browser, and live hot-swapping of webassembly modules.")]),r._v(" "),t("li",[t("a",{attrs:{href:"https://github.com/dested/WireWorld",target:"_blank",rel:"noopener noreferrer"}},[r._v("WireWorld"),t("OutboundLink")],1),r._v(" ("),t("a",{attrs:{href:"https://dested.com/projects/wire/",target:"_blank",rel:"noopener noreferrer"}},[r._v("demo"),t("OutboundLink")],1),r._v(")"),t("br"),r._v("\nThe Wireworld Computer in Javascript/Canvas.")])])])}),[],!1,null,null,null);e.default=n.exports}}]); \ No newline at end of file diff --git a/assets/js/22.79ff9157.js b/assets/js/22.79ff9157.js new file mode 100644 index 000000000..0930307b6 --- /dev/null +++ b/assets/js/22.79ff9157.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[22],{225:function(t,s,e){"use strict";e.r(s);var a=e(6),n=Object(a.a)({},(function(){var t=this,s=t.$createElement,e=t._self._c||s;return e("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[e("h1",{attrs:{id:"using-the-compiler"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#using-the-compiler"}},[t._v("#")]),t._v(" Using the compiler")]),t._v(" "),e("p",[t._v("Similar to TypeScript's "),e("code",[t._v("tsc")]),t._v(" transpiling to JavaScript, AssemblyScript's "),e("code",[t._v("asc")]),t._v(" compiles to WebAssembly.")]),t._v(" "),e("h2",{attrs:{id:"compiler-options"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#compiler-options"}},[t._v("#")]),t._v(" Compiler options")]),t._v(" "),e("p",[t._v("The compiler supports various options available on the command line, in a configuration file and programmatically. On the command line, it looks like this:")]),t._v(" "),e("h3",{attrs:{id:"entry-file-s"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#entry-file-s"}},[t._v("#")]),t._v(" Entry file(s)")]),t._v(" "),e("p",[t._v("Non-option arguments are treated as the names of entry files. A single program can have multiple entries, with the exports of each entry becoming the exports of the WebAssembly module. Exports of imported files that are not entry files do not become WebAssembly module exports.")]),t._v(" "),e("div",{staticClass:"language-sh extra-class"},[e("pre",{pre:!0,attrs:{class:"language-sh"}},[e("code",[t._v("asc entryFile.ts\n")])])]),e("h3",{attrs:{id:"general"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#general"}},[t._v("#")]),t._v(" General")]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v("--version, -v Prints just the compiler's version and exits.\n--help, -h Prints this message and exits.\n--config Configuration file to apply. CLI arguments take precedence.\n--target Configuration file target to use. Defaults to 'release'.\n")])])]),e("h3",{attrs:{id:"optimization"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#optimization"}},[t._v("#")]),t._v(" Optimization")]),t._v(" "),e("p",[t._v("The compiler can optimize for both speed ("),e("code",[t._v("-Ospeed")]),t._v(") and size ("),e("code",[t._v("-Osize")]),t._v("), as well as produce a debug build ("),e("code",[t._v("--debug")]),t._v(").")]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v("--optimize, -O Optimizes the module. Typical shorthands are:\n\n Default optimizations -O\n Make a release build -O --noAssert\n Make a debug build --debug\n Optimize for speed -Ospeed\n Optimize for size -Osize\n\n--optimizeLevel How much to focus on optimizing code. [0-3]\n--shrinkLevel How much to focus on shrinking code size. [0-2, s=1, z=2]\n--converge Re-optimizes until no further improvements can be made.\n--noAssert Replaces assertions with just their value without trapping.\n--uncheckedBehavior Changes the behavior of unchecked() expressions.\n Using this option can potentially cause breakage.\n\n default The default behavior: unchecked operations are\n only used inside of unchecked().\n never Unchecked operations are never used, even when,\n inside of unchecked().\n always Unchecked operations are always used if possible,\n whether or not unchecked() is used.\n\n")])])]),e("p",[t._v("Optimization levels can also be tweaked manually: "),e("code",[t._v("--optimizeLevel")]),t._v(" (0-3) indicates how much the compiler focuses on optimizing the code with "),e("code",[t._v("--shrinkLevel")]),t._v(" (0-2, 1=s, 2=z) indicating how much it focuses on keeping the size low during code generation and while optimizing. A shorthand for both is "),e("code",[t._v("-O[optimizeLevel][shrinkLevel]")]),t._v(" , with shrink level indicated by optionally appending the letter "),e("code",[t._v("s")]),t._v(" (1) or "),e("code",[t._v("z")]),t._v(" (2).")]),t._v(" "),e("h3",{attrs:{id:"output"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#output"}},[t._v("#")]),t._v(" Output")]),t._v(" "),e("p",[t._v("Typical output formats are WebAssembly binary (.wasm, "),e("code",[t._v("--outFile")]),t._v(") and/or text format (.wat, "),e("code",[t._v("--textFile")]),t._v("). Often, both are used in tandem to run and also inspect generated code.")]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v("--outFile, -o Specifies the WebAssembly output file (.wasm).\n--textFile, -t Specifies the WebAssembly text output file (.wat).\n--bindings, -b Specifies the bindings to generate (.js + .d.ts).\n\n esm JavaScript bindings & typings for ESM integration.\n raw Like esm, but exports just the instantiate function.\n Useful where modules are meant to be instantiated\n multiple times or non-ESM imports must be provided.\n")])])]),e("h3",{attrs:{id:"debugging"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#debugging"}},[t._v("#")]),t._v(" Debugging")]),t._v(" "),e("p",[t._v("For easier debugging during development, a "),e("a",{attrs:{href:"#source-maps"}},[t._v("source map")]),t._v(" can be emitted alongside the WebAssembly binary, and debug symbols can be embedded:")]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v("--sourceMap Enables source map generation. Optionally takes the URL\n used to reference the source map from the binary file.\n--debug Enables debug information in emitted binaries.\n")])])]),e("h3",{attrs:{id:"features"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#features"}},[t._v("#")]),t._v(" Features")]),t._v(" "),e("p",[t._v("There are several flags that enable or disable specific WebAssembly or compiler features. By default, only the bare minimum is exposed, and fully standardized WebAssembly features will be used.")]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v("--importMemory Imports the memory from 'env.memory'.\n--noExportMemory Does not export the memory as 'memory'.\n--initialMemory Sets the initial memory size in pages.\n--maximumMemory Sets the maximum memory size in pages.\n--sharedMemory Declare memory as shared. Requires maximumMemory.\n--zeroFilledMemory Assume imported memory is zeroed. Requires importMemory.\n--importTable Imports the function table from 'env.table'.\n--exportTable Exports the function table as 'table'.\n--exportStart Exports the start function using the specified name instead\n of calling it implicitly. Useful for WASI or to obtain the\n exported memory before executing any code accessing it.\n--runtime Specifies the runtime variant to include in the program.\n\n incremental TLSF + incremental GC (default)\n minimal TLSF + lightweight GC invoked externally\n stub Minimal runtime stub (never frees)\n ... Path to a custom runtime implementation\n\n--exportRuntime Always exports the runtime helpers (__new, __collect, __pin etc.).\n Automatically determined when generation of --bindings is enabled.\n--stackSize Overrides the stack size. Only relevant for incremental GC\n or when using a custom runtime that requires stack space.\n Defaults to 0 without and to 16384 with incremental GC.\n--enable Enables WebAssembly features being disabled by default.\n\n threads Threading and atomic operations.\n simd SIMD types and operations.\n reference-types Reference types and operations.\n gc Garbage collection (WIP).\n stringref String reference types.\n relaxed-simd Relaxed SIMD operations.\n\n--disable Disables WebAssembly features being enabled by default.\n\n mutable-globals Mutable global imports and exports.\n sign-extension Sign-extension operations\n nontrapping-f2i Non-trapping float to integer ops.\n bulk-memory Bulk memory operations.\n\n--use, -u Aliases a global object under another name, e.g., to switch\n the default 'Math' implementation used: --use Math=JSMath\n Can also be used to introduce an integer constant.\n--lowMemoryLimit Enforces very low (<64k) memory constraints.\n")])])]),e("h3",{attrs:{id:"linking"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#linking"}},[t._v("#")]),t._v(" Linking")]),t._v(" "),e("p",[t._v("Specifying the base offsets of compiler-generated memory respectively the table leaves some space for other data in front. In its current form this is mostly useful to link additional data into an AssemblyScript binary after compilation, be it by populating the binary itself or initializing the data externally upon initialization. One good example is leaving some scratch space for a frame buffer.")]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v("--memoryBase Sets the start offset of emitted memory segments.\n--tableBase Sets the start offset of emitted table elements.\n")])])]),e("h3",{attrs:{id:"api"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#api"}},[t._v("#")]),t._v(" API")]),t._v(" "),e("p",[t._v("To integrate with the compiler, for example to post-process the AST, one or multiple custom "),e("a",{attrs:{href:"#transforms"}},[t._v("transforms")]),t._v(" can be specified.")]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v("--transform Specifies the path to a custom transform to load.\n")])])]),e("h3",{attrs:{id:"other"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#other"}},[t._v("#")]),t._v(" Other")]),t._v(" "),e("p",[t._v("Other options include those forwarded to Binaryen and various flags useful in certain situations.")]),t._v(" "),e("h4",{attrs:{id:"binaryen"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#binaryen"}},[t._v("#")]),t._v(" Binaryen")]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v("--trapMode Sets the trap mode to use.\n\n allow Allow trapping operations. This is the default.\n clamp Replace trapping operations with clamping semantics.\n js Replace trapping operations with JS semantics.\n\n--runPasses Specifies additional Binaryen passes to run after other\n optimizations, if any. See: Binaryen/src/passes/pass.cpp\n--noValidate Skips validating the module using Binaryen.\n")])])]),e("h4",{attrs:{id:"and-the-kitchen-sink"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#and-the-kitchen-sink"}},[t._v("#")]),t._v(" And the kitchen sink")]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v("--baseDir Specifies the base directory of input and output files.\n--noColors Disables terminal colors.\n--noUnsafe Disallows the use of unsafe features in user code.\n Does not affect library files and external modules.\n--disableWarning Disables warnings matching the given diagnostic code.\n If no diagnostic code is given, all warnings are disabled.\n--noEmit Performs compilation as usual but does not emit code.\n--stats Prints statistics on I/O and compile times.\n--pedantic Make yourself sad for no good reason.\n--lib Adds one or multiple paths to custom library components and\n uses exports of all top-level files at this path as globals.\n--path Adds one or multiple paths to package resolution, similar\n to node_modules. Prefers an 'ascMain' entry in a package's\n package.json and falls back to an inner 'assembly/' folder.\n--wasm Uses the specified Wasm binary of the compiler.\n-- ... Specifies node.js options (CLI only). See: node --help\n")])])]),e("h2",{attrs:{id:"configuration-file"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#configuration-file"}},[t._v("#")]),t._v(" Configuration file")]),t._v(" "),e("p",[t._v("Instead of providing the options outlined above on the command line, a configuration file typically named "),e("strong",[t._v("asconfig.json")]),t._v(" can be used. It may look like in the following example, excluding comments:")]),t._v(" "),e("div",{staticClass:"language-json extra-class"},[e("pre",{pre:!0,attrs:{class:"language-json"}},[e("code",[e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token property"}},[t._v('"extends"')]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"./path/to/other/asconfig.json"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// (optional) base config")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token property"}},[t._v('"entries"')]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// (optional) entry files, e.g.")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"./assembly/index.ts"')]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token property"}},[t._v('"options"')]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// common options, e.g.")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token property"}},[t._v('"importTable"')]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token property"}},[t._v('"targets"')]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// (optional) targets")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token property"}},[t._v('"release"')]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v('// additional options for the "release" target, e.g.')]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token property"}},[t._v('"optimize"')]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token property"}},[t._v('"outFile"')]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"myModule.release.wasm"')]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token property"}},[t._v('"debug"')]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v('// additional options for the "debug" target, e.g.')]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token property"}},[t._v('"debug"')]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token property"}},[t._v('"outFile"')]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"myModule.debug.wasm"')]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),e("p",[t._v("Per-target options, e.g. "),e("code",[t._v("targets.release")]),t._v(", add to and override top-level "),e("code",[t._v("options")]),t._v(". Options provided on the command line override any options in the configuration file. Usage is, for example:")]),t._v(" "),e("div",{staticClass:"language-sh extra-class"},[e("pre",{pre:!0,attrs:{class:"language-sh"}},[e("code",[t._v("asc --config asconfig.json --target release\n")])])]),e("h2",{attrs:{id:"programmatic-usage"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#programmatic-usage"}},[t._v("#")]),t._v(" Programmatic usage")]),t._v(" "),e("p",[t._v("The compiler API can also be used programmatically:")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" asc "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"assemblyscript/asc"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" error"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" stdout"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" stderr"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" stats "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" asc"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("main")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Command line options")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"myModule.ts"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"--outFile"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"myModule.wasm"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"--optimize"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"--sourceMap"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"--stats"')]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Additional API options")]),t._v("\n stdout"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("...")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n stderr"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("...")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n readFile"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("...")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n writeFile"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("...")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n listFiles"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("...")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n reportDiagnostic"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("...")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n transforms"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("...")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("error"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n console"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Compilation failed: "')]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" error"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("message"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n console"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("stderr"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("toString")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n console"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("stdout"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("toString")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),e("p",[t._v("The compiler runs in browsers as well. The simplest way to set it up is to include the generated "),e("a",{attrs:{href:"https://cdn.jsdelivr.net/npm/assemblyscript@latest/dist/web.js",target:"_blank",rel:"noopener noreferrer"}},[t._v("web.js"),e("OutboundLink")],1),t._v(" so the compiler can be used with an "),e("code",[t._v("import")]),t._v(" on the Web:")]),t._v(" "),e("div",{staticClass:"language-html extra-class"},[e("pre",{pre:!0,attrs:{class:"language-html"}},[e("code",[e("span",{pre:!0,attrs:{class:"token tag"}},[e("span",{pre:!0,attrs:{class:"token tag"}},[e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("script")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("src")]),e("span",{pre:!0,attrs:{class:"token attr-value"}},[e("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("https://cdn.jsdelivr.net/npm/assemblyscript@x.x.x/dist/web.js"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),e("span",{pre:!0,attrs:{class:"token script"}}),e("span",{pre:!0,attrs:{class:"token tag"}},[e("span",{pre:!0,attrs:{class:"token tag"}},[e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token tag"}},[e("span",{pre:!0,attrs:{class:"token tag"}},[e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("script")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("type")]),e("span",{pre:!0,attrs:{class:"token attr-value"}},[e("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("module"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),e("span",{pre:!0,attrs:{class:"token script"}},[e("span",{pre:!0,attrs:{class:"token language-javascript"}},[t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" asc "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"assemblyscript/asc"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("...")]),t._v("\n")])]),e("span",{pre:!0,attrs:{class:"token tag"}},[e("span",{pre:!0,attrs:{class:"token tag"}},[e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n")])])]),e("p",[t._v("Here, "),e("code",[t._v("x.x.x")]),t._v(" must be replaced with the "),e("a",{attrs:{href:"https://github.com/AssemblyScript/assemblyscript/tags",target:"_blank",rel:"noopener noreferrer"}},[t._v("respective version to use"),e("OutboundLink")],1),t._v(", or "),e("code",[t._v("latest")]),t._v(" to always use the latest version (not recommended in production). By default, the script installs "),e("a",{attrs:{href:"https://cdn.jsdelivr.net/npm/assemblyscript@latest/dist/importmap.json",target:"_blank",rel:"noopener noreferrer"}},[t._v("the necessary import map"),e("OutboundLink")],1),t._v(" and, for browsers that do not yet support import maps, "),e("a",{attrs:{href:"https://github.com/guybedford/es-module-shims",target:"_blank",rel:"noopener noreferrer"}},[t._v("an import map shim"),e("OutboundLink")],1),t._v(". It also accepts the following options in case there is a need to only perform part of the setup:")]),t._v(" "),e("table",[e("thead",[e("tr",[e("th",[t._v("Script URL")]),t._v(" "),e("th",[t._v("Effect")])])]),t._v(" "),e("tbody",[e("tr",[e("td",[e("code",[t._v("web.js?noinstall")])]),t._v(" "),e("td",[t._v("Does not install the import map.")])]),t._v(" "),e("tr",[e("td",[e("code",[t._v("web.js?noshim")])]),t._v(" "),e("td",[t._v("Does not install the import map shim.")])]),t._v(" "),e("tr",[e("td",[e("code",[t._v("web.js?noinstall,noshim")])]),t._v(" "),e("td",[t._v("Does not install the import map or shim.")])])])]),t._v(" "),e("p",[t._v("Regardless of the options used, the script always declares the following global variables:")]),t._v(" "),e("table",[e("thead",[e("tr",[e("th",[t._v("Variable")]),t._v(" "),e("th",[t._v("Description")])])]),t._v(" "),e("tbody",[e("tr",[e("td",[e("code",[t._v("ASSEMBLYSCRIPT_VERSION")])]),t._v(" "),e("td",[t._v("Version string of the compiler release used")])]),t._v(" "),e("tr",[e("td",[e("code",[t._v("ASSEMBLYSCRIPT_IMPORTMAP")])]),t._v(" "),e("td",[t._v("The respective import map of the release as JSON")])])])]),t._v(" "),e("h2",{attrs:{id:"host-bindings"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#host-bindings"}},[t._v("#")]),t._v(" Host bindings")]),t._v(" "),e("p",[t._v("WebAssembly alone cannot yet transfer higher level data types like strings, arrays and objects over module boundaries, so for now some amount of glue code is required to exchange these data structures with the host / JavaScript.")]),t._v(" "),e("p",[t._v("The compiler can generate the necessary bindings using the "),e("code",[t._v("--bindings")]),t._v(" command line option (either as an ES module or a raw instantiate function), enabling exchange of:")]),t._v(" "),e("table",[e("thead",[e("tr",[e("th",[t._v("Type")]),t._v(" "),e("th",[t._v("Strategy")]),t._v(" "),e("th",[t._v("Description")])])]),t._v(" "),e("tbody",[e("tr",[e("td",[t._v("Number")]),t._v(" "),e("td",[t._v("By value")]),t._v(" "),e("td",[t._v("Basic numeric types except 64-bit integers.")])]),t._v(" "),e("tr",[e("td",[t._v("BigInt")]),t._v(" "),e("td",[t._v("By value")]),t._v(" "),e("td",[t._v("64-bit integers via js-bigint-integration.")])]),t._v(" "),e("tr",[e("td",[t._v("Boolean")]),t._v(" "),e("td",[t._v("By value")]),t._v(" "),e("td",[t._v("Coerced to "),e("code",[t._v("true")]),t._v(" or "),e("code",[t._v("false")]),t._v(".")])]),t._v(" "),e("tr",[e("td",[t._v("Externref")]),t._v(" "),e("td",[t._v("By reference")]),t._v(" "),e("td",[t._v("Using reference-types.")])]),t._v(" "),e("tr",[e("td",[e("strong",[t._v("String")])]),t._v(" "),e("td",[t._v("Copy")]),t._v(" "),e("td")]),t._v(" "),e("tr",[e("td",[e("strong",[t._v("ArrayBuffer")])]),t._v(" "),e("td",[t._v("Copy")]),t._v(" "),e("td")]),t._v(" "),e("tr",[e("td",[e("strong",[t._v("TypedArray")])]),t._v(" "),e("td",[t._v("Copy")]),t._v(" "),e("td",[t._v("Any "),e("code",[t._v("Int8Array")]),t._v(", "),e("code",[t._v("Float64Array")]),t._v(" etc.")])]),t._v(" "),e("tr",[e("td",[e("strong",[t._v("Array")])]),t._v(" "),e("td",[t._v("Copy")]),t._v(" "),e("td",[t._v("Any "),e("code",[t._v("Array")])])]),t._v(" "),e("tr",[e("td",[e("strong",[t._v("StaticArray")])]),t._v(" "),e("td",[t._v("Copy")]),t._v(" "),e("td",[t._v("Any "),e("code",[t._v("StaticArray")])])]),t._v(" "),e("tr",[e("td",[e("strong",[t._v("Object")])]),t._v(" "),e("td",[t._v("Copy")]),t._v(" "),e("td",[t._v("If a plain object. That is: Has no constructor or non-public fields.")])]),t._v(" "),e("tr",[e("td",[e("strong",[t._v("Object")])]),t._v(" "),e("td",[t._v("By reference")]),t._v(" "),e("td",[t._v("If not a plain object. Passed as an opaque reference counted pointer.")])])])]),t._v(" "),e("p",[t._v("Note the two different strategies used for "),e("strong",[t._v("Object")]),t._v(": In some situations, say when calling a Web API, it may be preferable to copy the object as a whole, field by field, which is the strategy chosen for plain objects with no constructor or non-public fields:")]),t._v(" "),e("div",{staticClass:"language-ts extra-class"},[e("pre",{pre:!0,attrs:{class:"language-ts"}},[e("code",[e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Copied to a JS object")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("PlainObject")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n field"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("export")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("getObject")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" PlainObject "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n field"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"hello world"')]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),e("p",[t._v("However, copying may not be desirable in every situation, say when individual object properties are meant to be modified externally where serializing/deserializing the object as a whole would result in unnecessary overhead. To support this use case, the compiler can pass just an opaque reference to the object, which can be enforced by providing an empty "),e("code",[t._v("constructor")]),t._v(" (not a plain object anymore):")]),t._v(" "),e("div",{staticClass:"language-ts extra-class"},[e("pre",{pre:!0,attrs:{class:"language-ts"}},[e("code",[e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Not copied to a JS object")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ComplexObject")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("constructor")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// !")]),t._v("\n field"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("null")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("export")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("newObject")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" ComplexObject "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ComplexObject")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("export")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("setObjectField")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("target"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" ComplexObject"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" field"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("null")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n target"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("field "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" field"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("export")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("getObjectField")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("target"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" ComplexObject"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("null")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" target"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("field"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),e("p",[t._v("Also note that exporting an entire "),e("code",[t._v("class")]),t._v(" has no effect at the module boundary (yet), and it is instead recommended to expose only the needed functionality as shown in the example above. Supported elements at the boundary are globals, functions and enums.")]),t._v(" "),e("h3",{attrs:{id:"using-esm-bindings"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#using-esm-bindings"}},[t._v("#")]),t._v(" Using ESM bindings")]),t._v(" "),e("p",[t._v("Bindings generated with "),e("code",[t._v("--bindings esm")]),t._v(" perform all the steps from compilation over instantiation to exporting the final interface. To do so, a few assumptions had to be made:")]),t._v(" "),e("ul",[e("li",[e("p",[t._v("The WebAssembly binary is located next to the JavaScript bindings file using the same name but with a "),e("code",[t._v(".wasm")]),t._v(" extension.")]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v("build/mymodule.js\nbuild/mymodule.wasm\n")])])]),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("as")]),t._v(" myModule "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"./build/mymodule.js"')]),t._v("\n")])])])]),t._v(" "),e("li",[e("p",[t._v("JavaScript globals in "),e("code",[t._v("globalThis")]),t._v(" can be accessed directly via the "),e("code",[t._v("env")]),t._v(" module namespace. For example, "),e("code",[t._v("console.log")]),t._v(" can be manually imported through:")]),t._v(" "),e("div",{staticClass:"language-ts extra-class"},[e("pre",{pre:!0,attrs:{class:"language-ts"}},[e("code",[e("span",{pre:!0,attrs:{class:"token decorator"}},[e("span",{pre:!0,attrs:{class:"token at operator"}},[t._v("@")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("external")])]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"env"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"console.log"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("declare")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("consoleLog")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("s"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v("\n")])])]),e("p",[t._v("Note that this is just an example and "),e("code",[t._v("console.log")]),t._v(" is already provided by the standard library when called from an AssemblyScript file. Other global functions not already provided by the standard library may require an import as of this example, though.")])]),t._v(" "),e("li",[e("p",[t._v("Imports from other namespaces than "),e("code",[t._v("env")]),t._v(", i.e. "),e("code",[t._v('(import "module" "name")')]),t._v(", become an "),e("code",[t._v('import { name } from "module"')]),t._v(" within the binding. Importing a custom function from a JavaScript file next to the bindings file can be achieved through:")]),t._v(" "),e("div",{staticClass:"language-ts extra-class"},[e("pre",{pre:!0,attrs:{class:"language-ts"}},[e("code",[e("span",{pre:!0,attrs:{class:"token decorator"}},[e("span",{pre:!0,attrs:{class:"token at operator"}},[t._v("@")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("external")])]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"./otherfile.js"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"myFunction"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("declare")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("myFunction")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("...")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("...")]),t._v("\n")])])]),e("p",[t._v("Similarly, importing a custom function from, say, a Node.js dependency can be achieved through:")]),t._v(" "),e("div",{staticClass:"language-ts extra-class"},[e("pre",{pre:!0,attrs:{class:"language-ts"}},[e("code",[e("span",{pre:!0,attrs:{class:"token decorator"}},[e("span",{pre:!0,attrs:{class:"token at operator"}},[t._v("@")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("external")])]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"othermodule"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"myFunction"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("declare")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("myFunction")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("...")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("...")]),t._v("\n")])])])])]),t._v(" "),e("p",[t._v("These assumptions cannot be intercepted or customized since, to provide static ESM exports from the bindings file directly, instantiation must start immediately when the bindings file is imported. If customization is required, "),e("code",[t._v("--bindings raw")]),t._v(" can be used instead.")]),t._v(" "),e("h3",{attrs:{id:"using-raw-bindings"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#using-raw-bindings"}},[t._v("#")]),t._v(" Using raw bindings")]),t._v(" "),e("p",[t._v("The signature of the single "),e("code",[t._v("instantiate")]),t._v(" function exported by "),e("code",[t._v("--bindings raw")]),t._v(" is:")]),t._v(" "),e("div",{staticClass:"language-ts extra-class"},[e("pre",{pre:!0,attrs:{class:"language-ts"}},[e("code",[e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("export")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("instantiate")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("module"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" WebAssembly"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("Module"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" imports"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" WebAssembly"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("Imports"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" AdaptedExports\n")])])]),e("p",[t._v("Note that the function does not make any assumptions on how the module is to be compiled, but instead expects a readily compiled "),e("code",[t._v("WebAssembly.Module")]),t._v(" as in this example:")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" instantiate "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"./module.js"')]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" exports "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("instantiate")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" WebAssembly"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("compileStreaming")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("fetch")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"./module.wasm"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* imports */")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),e("p",[t._v("Unlike "),e("code",[t._v("--bindings esm")]),t._v(", raw bindings also do not make any assumptions on how imports are resolved, so these must be provided manually as part of the imports object. For example, to achieve a similar result as with ESM bindings, but now customizable:")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" instantiate "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"./module.js"')]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("as")]),t._v(" other "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"./otherfile.js"')]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("export")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n export1"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n export2"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("...")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("instantiate")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" WebAssembly"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("compileStreaming")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("fetch")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"./module.wasm"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v('"./otherfile.js"')]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" other\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),e("h2",{attrs:{id:"debugging-2"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#debugging-2"}},[t._v("#")]),t._v(" Debugging")]),t._v(" "),e("p",[t._v("The debugging workflow is similar to debugging JavaScript since both Wasm and JS execute in the same engine, and the compiler provides various options to set up additional WebAssembly-specific debug information. Note that any sort of optimization should be disabled in debug builds.")]),t._v(" "),e("h3",{attrs:{id:"debug-symbols"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#debug-symbols"}},[t._v("#")]),t._v(" Debug symbols")]),t._v(" "),e("p",[t._v("When compiling with the "),e("code",[t._v("--debug")]),t._v(" option, the compiler appends a name section to the binary, containing names of functions, globals, locals and so on. These names will show up in stack traces.")]),t._v(" "),e("h3",{attrs:{id:"source-maps"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#source-maps"}},[t._v("#")]),t._v(" Source maps")]),t._v(" "),e("p",[t._v("The compiler can generate a source map alongside a binary using the "),e("code",[t._v("--sourceMap")]),t._v(" option. By default, a relative source map path will be embedded in the binary which browsers can pick up when instantiating a module from a "),e("code",[t._v("fetch")]),t._v(" response. In environments that do not provide "),e("code",[t._v("fetch")]),t._v(" or an equivalent mechanism, like in Node.js, it is alternatively possible to embed an absolute source map path through "),e("code",[t._v("--sourceMap path/to/source/map")]),t._v(".")]),t._v(" "),e("h3",{attrs:{id:"breakpoints"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#breakpoints"}},[t._v("#")]),t._v(" Breakpoints")]),t._v(" "),e("p",[t._v("Some JavaScript engines also support adding break points directly in WebAssembly code. Please consult your engine's documentation: "),e("a",{attrs:{href:"https://developers.google.com/web/tools/chrome-devtools/javascript/breakpoints",target:"_blank",rel:"noopener noreferrer"}},[t._v("Chrome"),e("OutboundLink")],1),t._v(", "),e("a",{attrs:{href:"https://developer.mozilla.org/en-US/docs/Tools/Debugger/How_to/Set_a_breakpoint",target:"_blank",rel:"noopener noreferrer"}},[t._v("Firefox"),e("OutboundLink")],1),t._v(", "),e("a",{attrs:{href:"https://nodejs.org/api/debugger.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("Node.js"),e("OutboundLink")],1),t._v(", "),e("a",{attrs:{href:"https://support.apple.com/de-de/guide/safari-developer/dev5e4caf347/mac",target:"_blank",rel:"noopener noreferrer"}},[t._v("Safari"),e("OutboundLink")],1),t._v(".")]),t._v(" "),e("h2",{attrs:{id:"transforms"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#transforms"}},[t._v("#")]),t._v(" Transforms")]),t._v(" "),e("p",[t._v("AssemblyScript is compiled statically, so code transformation cannot be done at runtime but must instead be performed at compile-time. To enable this, the compiler frontend (asc) provides a mechanism to hook into the compilation process before, while and after the module is being compiled.")]),t._v(" "),e("p",[t._v("Specifying "),e("code",[t._v("--transform ./myTransform.js")]),t._v(" on the command line will load the node module pointed to by "),e("code",[t._v("./myTransform.js")]),t._v(".")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("as")]),t._v(" assemblyscript "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"assemblyscript"')]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" Transform "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"assemblyscript/transform"')]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MyTransform")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Transform")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("...")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("export")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("default")]),t._v(" MyTransform\n")])])]),e("h3",{attrs:{id:"properties"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#properties"}},[t._v("#")]),t._v(" Properties")]),t._v(" "),e("p",[t._v("A transform is an ES6 class/node module with the following inherited properties:")]),t._v(" "),e("ul",[e("li",[e("div",{staticClass:"language-ts extra-class"},[e("pre",{pre:!0,attrs:{class:"language-ts"}},[e("code",[e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("readonly")]),t._v(" program"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Program\n")])])]),e("p",[t._v("Reference to the "),e("code",[t._v("Program")]),t._v(" instance.")])]),t._v(" "),e("li",[e("div",{staticClass:"language-ts extra-class"},[e("pre",{pre:!0,attrs:{class:"language-ts"}},[e("code",[e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("readonly")]),t._v(" baseDir"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),t._v("\n")])])]),e("p",[t._v("Base directory used by the compiler.")])]),t._v(" "),e("li",[e("div",{staticClass:"language-ts extra-class"},[e("pre",{pre:!0,attrs:{class:"language-ts"}},[e("code",[e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("readonly")]),t._v(" stdout"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" OutputStream\n")])])]),e("p",[t._v("Output stream used by the compiler.")])]),t._v(" "),e("li",[e("div",{staticClass:"language-ts extra-class"},[e("pre",{pre:!0,attrs:{class:"language-ts"}},[e("code",[e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("readonly")]),t._v(" stderr"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" OutputStream\n")])])]),e("p",[t._v("Error stream uses by the compiler.")])]),t._v(" "),e("li",[e("div",{staticClass:"language-ts extra-class"},[e("pre",{pre:!0,attrs:{class:"language-ts"}},[e("code",[e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("readonly")]),t._v(" log"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("typeof")]),t._v(" console"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("log\n")])])]),e("p",[t._v("Logs a message to console.")])]),t._v(" "),e("li",[e("div",{staticClass:"language-ts extra-class"},[e("pre",{pre:!0,attrs:{class:"language-ts"}},[e("code",[e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("writeFile")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("filename"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" contents"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Uint8Array")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" baseDir"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("boolean")]),t._v("\n")])])]),e("p",[t._v("Writes a file to disk.")])]),t._v(" "),e("li",[e("div",{staticClass:"language-ts extra-class"},[e("pre",{pre:!0,attrs:{class:"language-ts"}},[e("code",[e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("readFile")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("filename"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" baseDir"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("null")]),t._v("\n")])])]),e("p",[t._v("Reads a file from disk.")])]),t._v(" "),e("li",[e("div",{staticClass:"language-ts extra-class"},[e("pre",{pre:!0,attrs:{class:"language-ts"}},[e("code",[e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("listFiles")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("dirname"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" baseDir"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("null")]),t._v("\n")])])]),e("p",[t._v("Lists all files in a directory.")])])]),t._v(" "),e("h3",{attrs:{id:"hooks"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#hooks"}},[t._v("#")]),t._v(" Hooks")]),t._v(" "),e("p",[t._v("The frontend will call several hooks, if present on the transform, during the compilation process:")]),t._v(" "),e("ul",[e("li",[e("div",{staticClass:"language-ts extra-class"},[e("pre",{pre:!0,attrs:{class:"language-ts"}},[e("code",[e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("afterParse")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("parser"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Parser"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v("\n")])])]),e("p",[t._v("Called when parsing is complete, before a program is initialized from the AST. Note that types are not yet known at this stage and there is no easy way to obtain them.")])]),t._v(" "),e("li",[e("div",{staticClass:"language-ts extra-class"},[e("pre",{pre:!0,attrs:{class:"language-ts"}},[e("code",[e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("afterInitialize")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("program"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Program"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v("\n")])])]),e("p",[t._v("Called once the program is initialized, before it is being compiled. Types are known at this stage, respectively can be resolved where necessary.")])]),t._v(" "),e("li",[e("div",{staticClass:"language-ts extra-class"},[e("pre",{pre:!0,attrs:{class:"language-ts"}},[e("code",[e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("afterCompile")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("module"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Module"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v("\n")])])]),e("p",[t._v("Called with the resulting module before it is being emitted. Useful to modify the IR before writing any output, for example to replace imports with actual functionality or to add custom sections.")])])]),t._v(" "),e("p",[t._v("Transforms are a very powerful feature, but may require profound knowledge of the compiler to utilize them to their full extent, so reading through the compiler sources is a plus.")]),t._v(" "),e("h2",{attrs:{id:"portability"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#portability"}},[t._v("#")]),t._v(" Portability")]),t._v(" "),e("p",[t._v("With AssemblyScript being very similar to TypeScript, there comes the opportunity to compile the same code to JavaScript with "),e("code",[t._v("tsc")]),t._v(" and WebAssembly with "),e("code",[t._v("asc")]),t._v(". The AssemblyScript compiler itself is portable code. Writing portable code is largely a matter of double-checking that the intent translates to the same outcome in both the strictly typed AssemblyScript and the types-stripped-away TypeScript worlds.")]),t._v(" "),e("h3",{attrs:{id:"portable-standard-library"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#portable-standard-library"}},[t._v("#")]),t._v(" Portable standard library")]),t._v(" "),e("p",[t._v("Besides the full standard library, AssemblyScript provides a portable variant of the functionality that is present in both JavaScript and WebAssembly. In addition to that, the portable library lifts some of the functionality that is only available with "),e("code",[t._v("asc")]),t._v(" to JavaScript, like the portable conversions mentioned below.")]),t._v(" "),e("p",[t._v("Also note that some parts of JavaScript's standard library function a little more loosely than how they would when compiling to WebAssembly. While the portable definitions try to take care of this, one example where this can happen is "),e("code",[t._v("Map#get")]),t._v(" returning "),e("code",[t._v("undefined")]),t._v(" when a key cannot be found in JavaScript, while resulting in an abort in WebAssembly, where it is necessary to first check that the key exists using "),e("code",[t._v("Map#has")]),t._v(".")]),t._v(" "),e("p",[t._v("To use the portable library, extend "),e("code",[t._v("assemblyscript/std/portable.json")]),t._v(" instead of "),e("code",[t._v("assemblyscript/std/assembly.json")]),t._v(" within "),e("code",[t._v("tsconfig.json")]),t._v(" and add the following somewhere along your build step so the portable features are present in the environment:")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"assemblyscript/std/portable.js"')]),t._v("\n")])])]),e("p",[t._v("Note that the portable standard library is still a work in progress and so far focuses on functionality useful to make the compiler itself portable, so if you need something specific, feel free to improve "),e("a",{attrs:{href:"https://github.com/AssemblyScript/assemblyscript/tree/main/std/portable",target:"_blank",rel:"noopener noreferrer"}},[t._v("its definitions and feature set"),e("OutboundLink")],1),t._v(".")]),t._v(" "),e("h3",{attrs:{id:"portable-conversions"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#portable-conversions"}},[t._v("#")]),t._v(" Portable conversions")]),t._v(" "),e("p",[t._v("While "),e("code",[t._v("asc")]),t._v(" understands the meaning of")]),t._v(" "),e("div",{staticClass:"language-ts extra-class"},[e("pre",{pre:!0,attrs:{class:"language-ts"}},[e("code",[e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// non-portable")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" someFloat"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("f32")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("1.5")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" someInt"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("i32")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),e("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("i32")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("someFloat\n")])])]),e("p",[t._v("and then inserts the correct conversion steps, "),e("code",[t._v("tsc")]),t._v(" does not because all numeric types are just aliases of "),e("code",[t._v("number")]),t._v(". Hence, when targeting JavaScript with "),e("code",[t._v("tsc")]),t._v(", the above will result in")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" someFloat "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("1.5")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" someInt "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" someFloat\n")])])]),e("p",[t._v("which is obviously wrong. To account for this, portable conversions can be used, resulting in actually portable code. For example")]),t._v(" "),e("div",{staticClass:"language-ts extra-class"},[e("pre",{pre:!0,attrs:{class:"language-ts"}},[e("code",[e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// portable")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" someFloat"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("f32")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("1.5")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" someInt"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("i32")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("i32")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("someFloat"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),e("p",[t._v("will essentially result in")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" someFloat "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("1.5")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" someInt "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" someFloat "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v("\n")])])]),e("p",[t._v("which is correct. The best way of dealing with this is asking yourself the question: What would this code do when compiled to JavaScript?")]),t._v(" "),e("h3",{attrs:{id:"portable-overflows"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#portable-overflows"}},[t._v("#")]),t._v(" Portable overflows")]),t._v(" "),e("p",[t._v("Likewise, again because "),e("code",[t._v("asc")]),t._v(" knows the meaning but "),e("code",[t._v("tsc")]),t._v(" does not, overflows must be handled explicitly:")]),t._v(" "),e("div",{staticClass:"language-ts extra-class"},[e("pre",{pre:!0,attrs:{class:"language-ts"}},[e("code",[e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// non-portable")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" someU8"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("u8")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("255")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" someOtherU8"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("u8")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" someU8 "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),t._v("\n")])])]),e("div",{staticClass:"language-ts extra-class"},[e("pre",{pre:!0,attrs:{class:"language-ts"}},[e("code",[e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// portable")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" someU8"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("u8")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("255")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" someOtherU8"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("u8")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("u8")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("someU8 "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),e("p",[t._v("essentially resulting in")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" someU8 "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("255")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" someOtherU8 "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("someU8 "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("0xff")]),t._v("\n")])])]),e("h3",{attrs:{id:"non-portable-code"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#non-portable-code"}},[t._v("#")]),t._v(" Non-portable code")]),t._v(" "),e("p",[t._v("In JavaScript, all numeric values are IEEE754 doubles that cannot represent the full range of values fitting in a 64-bit integer ("),e("a",{attrs:{href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/MAX_SAFE_INTEGER",target:"_blank",rel:"noopener noreferrer"}},[t._v("max. safe integer"),e("OutboundLink")],1),t._v(" is "),e("code",[t._v("2^53 - 1")]),t._v("). Hence "),e("code",[t._v("i64")]),t._v(" and "),e("code",[t._v("u64")]),t._v(" are not portable and not present in "),e("code",[t._v("std/portable")]),t._v(". There are several ways to deal with this. One is to use an i64 polyfill like "),e("a",{attrs:{href:"https://github.com/AssemblyScript/examples/tree/main/i64",target:"_blank",rel:"noopener noreferrer"}},[t._v("in this example"),e("OutboundLink")],1),t._v(".")]),t._v(" "),e("p",[t._v("Other than that, portable code (JavaScript) does not have a concept of memory, so there are no "),e("code",[t._v("load")]),t._v(" and "),e("code",[t._v("store")]),t._v(" implementations in the portable standard library. Technically this can be polyfilled in various ways, but no default is provided since actual implementations are expected to be relatively specific (for instance: the portable compiler accesses Binaryen's memory).")])])}),[],!1,null,null,null);s.default=n.exports}}]); \ No newline at end of file diff --git a/assets/js/23.ed294d2e.js b/assets/js/23.ed294d2e.js new file mode 100644 index 000000000..7636324d8 --- /dev/null +++ b/assets/js/23.ed294d2e.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[23],{224:function(t,s,a){"use strict";a.r(s);var e=a(6),n=Object(e.a)({},(function(){var t=this,s=t.$createElement,a=t._self._c||s;return a("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[a("h1",{attrs:{id:"concepts"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#concepts"}},[t._v("#")]),t._v(" Concepts")]),t._v(" "),a("p",[t._v("An overview of basic AssemblyScript concepts.")]),t._v(" "),a("h2",{attrs:{id:"typescript-like"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#typescript-like"}},[t._v("#")]),t._v(" TypeScript-like")]),t._v(" "),a("p",[t._v("AssemblyScript is very similar to TypeScript with largely compatible syntax and semantics. As such, many of the concepts known from TypeScript apply to AssemblyScript as well, but not all TypeScript features map well to ahead of time compilation or WebAssembly's so far supported feature set. Some features have been omitted, others not yet implemented, and a few additional concepts needed to be added, technically making AssemblyScript part a subset, part a superset - a variant. As such it is unlikely that existing TypeScript code can be compiled by the AssemblyScript compiler, but likely that sufficiently strict code can be ported with little effort.")]),t._v(" "),a("p",[t._v("A detailed overview of supported TypeScript features is available within "),a("RouterLink",{attrs:{to:"/status.html"}},[t._v("Implementation status")]),t._v(".")],1),t._v(" "),a("h2",{attrs:{id:"strictly-typed"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#strictly-typed"}},[t._v("#")]),t._v(" Strictly typed")]),t._v(" "),a("p",[t._v("While TypeScript has types, its type system is able to describe many of JavaScript's dynamic features. TypeScript is a superset / a type checker on top of JavaScript after all. On the contrary, AssemblyScript is compiled statically ahead of time, making it infeasible to support very dynamic JavaScript features to not enter interpreter territory, respectively requires stricter type checking to guarantee correctness at runtime where TypeScript would not complain.")]),t._v(" "),a("p",[t._v("As a result, there is no "),a("code",[t._v("any")]),t._v(" or "),a("code",[t._v("undefined")]),t._v(":")]),t._v(" "),a("div",{staticClass:"language-ts extra-class"},[a("pre",{pre:!0,attrs:{class:"language-ts"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 😢")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("foo")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("a"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" b "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" a "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" b\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 😊")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("foo")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("a"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("i32")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("i32")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" b "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" a "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" b\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("p",[t._v("There are no union types yet, but a similar effect can be achieved with generics:")]),t._v(" "),a("div",{staticClass:"language-ts extra-class"},[a("pre",{pre:!0,attrs:{class:"language-ts"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 😢")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("foo")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("a"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("i32")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 😊")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token generic-function"}},[a("span",{pre:!0,attrs:{class:"token function"}},[t._v("foo")]),a("span",{pre:!0,attrs:{class:"token generic class-name"}},[a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("T")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")])])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("a"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("T")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("p",[t._v("Objects must be typed, say using a "),a("code",[t._v("Map")]),t._v(" or "),a("code",[t._v("class")]),t._v(":")]),t._v(" "),a("div",{staticClass:"language-ts extra-class"},[a("pre",{pre:!0,attrs:{class:"language-ts"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 😢")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" a "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\na"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("prop "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"hello world"')]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 😊")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" a "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Map"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),a("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\na"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("set")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"prop"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"hello world"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 😊")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("A")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("constructor")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" prop"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" a "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("A")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"hello world"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),a("p",[t._v("And nullability checks are limited to locals to guarantee soundness where TypeScript "),a("a",{attrs:{href:"https://www.typescriptlang.org/play?#code/G4QwTgBAZg9jBcEDOAXMBLAdgcwgHwkwFcAbEiAXggCIRqBuAKEfSggApYYBKCAb0YRkAUxQAxOADlSJdtyZCuAOhLCcKABb0IAeh2EYEYWDAwwjAL7MoRTAGMU6GJhHipMuf0HQ4lQjKYrIA",target:"_blank",rel:"noopener noreferrer"}},[t._v("would not"),a("OutboundLink")],1),t._v(" "),a("a",{attrs:{href:"https://www.typescriptlang.org/play/index.html#code/MYGwhgzhAEBiD29oG8BQ0PQvAtgUwBcALASwDsBzALiwICdyLoAfaMgVxBGgF43OQAblQBfVKgBm7MsAIl4ZaABN4AZVyFSlABQTENBPACUKdJhITouxADps+YoxNpMr5Wo2PKAURAQ81sbCbph68HaeWhQ2IHiUxILQAPRJWETwnErQeHR08HQANNAARuwE7ngQZADkBGYYYmKS0rLyiirqDlG+-oEGiM710GERXYy8-FzCIkA",target:"_blank",rel:"noopener noreferrer"}},[t._v("diagnose"),a("OutboundLink")],1),t._v(" "),a("a",{attrs:{href:"https://www.typescriptlang.org/play/index.html#code/MYGwhgzhAEBiD29oG8BQ0PQPoXgWwFMAXACwEsA7AcwC5oIiAnSq6AH2goFcQRoBeaACISBXvCEBudJirF6+YuWoAKAJR0Gzau048+aTEegh5jeYNJkIAOhyKr1accxXb9wo9aDuvZy+hzIi5GCkDifwwAX1QY1AAzLgpgIjJ4MIATeABlB2UqFXjEOgR4NRQZDDJ46ELEG1xPfPLDAKL4BryWG1NqUkloAHpB+hJ4HgzoAkZGeEYAGmgAIy4iaCyCCAoAciJK6BiYoA",target:"_blank",rel:"noopener noreferrer"}},[t._v("a problem"),a("OutboundLink")],1),t._v(":")]),t._v(" "),a("div",{staticClass:"language-ts extra-class"},[a("pre",{pre:!0,attrs:{class:"language-ts"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("doSomething")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("foo"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Foo"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 😢")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("foo"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("something"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n foo"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("something"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("length "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// fails")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("doSomething")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("foo"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Foo"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 😊")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" something "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" foo"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("something\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("something"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n something"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("length "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// works")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("h2",{attrs:{id:"sandboxed-execution"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#sandboxed-execution"}},[t._v("#")]),t._v(" Sandboxed execution")]),t._v(" "),a("p",[t._v("One of WebAssembly's unique features is that a module cannot access external resources without explicitly importing them, providing strong security guarantees by default. As such, to do anything useful with WebAssembly, it is necessary to wire a module to the host environment, like for example JavaScript and the DOM.")]),t._v(" "),a("h3",{attrs:{id:"module-imports"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#module-imports"}},[t._v("#")]),t._v(" Module imports")]),t._v(" "),a("p",[t._v("In AssemblyScript, host functionality can be imported by utilizing the ambient context, that is using a "),a("code",[t._v("declare")]),t._v(" statement:")]),t._v(" "),a("div",{staticClass:"language-ts extra-class"},[a("pre",{pre:!0,attrs:{class:"language-ts"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// assembly/env.ts")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("export")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("declare")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("logInteger")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("i32")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v("\n")])])]),a("div",{staticClass:"language-ts extra-class"},[a("pre",{pre:!0,attrs:{class:"language-ts"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// assembly/index.ts")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" logInteger "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"./env"')]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("logInteger")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("42")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),a("p",[t._v("Ambient declarations in an AssemblyScript file will yield a WebAssembly module import, using the internal path of the file, without file extension, as the module name (here: "),a("code",[t._v("assembly/env")]),t._v("), and the name of the declared element as the module element (here "),a("code",[t._v("logInteger")]),t._v("). In the example above, the import can be fulfilled by providing the following imports object upon instantiation:")]),t._v(" "),a("div",{staticClass:"language-js extra-class"},[a("pre",{pre:!0,attrs:{class:"language-js"}},[a("code",[t._v("WebAssembly"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("instantiateStreaming")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("fetch")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("...")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v('"assembly/env"')]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("logInteger")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("i")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" console"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"logInteger: "')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" i"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),a("p",[t._v("If necessary, the respective external module and element names can also be overridden using the "),a("code",[t._v("@external")]),t._v(" decorator and modifying the imports object accordingly:")]),t._v(" "),a("div",{staticClass:"language-ts extra-class"},[a("pre",{pre:!0,attrs:{class:"language-ts"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// assembly/index.ts")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token decorator"}},[a("span",{pre:!0,attrs:{class:"token at operator"}},[t._v("@")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("external")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"log"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"integer"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("declare")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("logInteger")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("i32")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v('// { "log": { "integer"(i) { ... } } }')]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("logInteger")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("42")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),a("h3",{attrs:{id:"module-exports"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#module-exports"}},[t._v("#")]),t._v(" Module exports")]),t._v(" "),a("p",[t._v("Similarly, "),a("code",[t._v("export")]),t._v("s from an entry file will yield WebAssembly module exports:")]),t._v(" "),a("div",{staticClass:"language-ts extra-class"},[a("pre",{pre:!0,attrs:{class:"language-ts"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// assembly/index.ts")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("export")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("add")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("a"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("i32")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" b"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("i32")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("i32")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" a "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" b\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("p",[t._v("Module exports can then be called from the host environment:")]),t._v(" "),a("div",{staticClass:"language-js extra-class"},[a("pre",{pre:!0,attrs:{class:"language-js"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("instance")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" exports "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" WebAssembly"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("instantiateStreaming")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("...")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\nconsole"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("exports"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("add")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),a("p",[t._v("See also: "),a("RouterLink",{attrs:{to:"/compiler.html#host-bindings"}},[t._v("Host bindings")]),t._v(" automate much of the wiring.")],1),t._v(" "),a("h3",{attrs:{id:"special-imports"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#special-imports"}},[t._v("#")]),t._v(" Special imports")]),t._v(" "),a("p",[t._v("Some language features need support from the host environment to function, yielding a few special module imports depending on the feature set used within the module. Generated bindings provide these automatically where necessary.")]),t._v(" "),a("ul",[a("li",[a("div",{staticClass:"language-ts extra-class"},[a("pre",{pre:!0,attrs:{class:"language-ts"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" env"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("abort"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("message"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("usize")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" fileName"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("usize")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" line"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("u32")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" column"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("u32")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v("\n")])])]),a("p",[t._v("Called on unrecoverable errors. Typically present if assertions are enabled or errors are thrown.")])]),t._v(" "),a("li",[a("div",{staticClass:"language-ts extra-class"},[a("pre",{pre:!0,attrs:{class:"language-ts"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" env"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("trace"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("message"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("usize")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" n"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("i32")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" a0"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v(".4")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("f64")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v("\n")])])]),a("p",[t._v("Called when "),a("code",[t._v("trace")]),t._v(" is called in user code. Only present if it is.")])]),t._v(" "),a("li",[a("div",{staticClass:"language-ts extra-class"},[a("pre",{pre:!0,attrs:{class:"language-ts"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" env"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("seed"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("f64")]),t._v("\n")])])]),a("p",[t._v("Called when the random number generator needs to be seeded. Only present if it is.")])])]),t._v(" "),a("p",[t._v("The respective implementations of "),a("code",[t._v("abort")]),t._v(", "),a("code",[t._v("trace")]),t._v(" and "),a("code",[t._v("seed")]),t._v(" can be overridden with, for example, "),a("code",[t._v("--use abort=assembly/index/myAbort")]),t._v(", here redirecting calls to "),a("code",[t._v("abort")]),t._v(" to a custom "),a("code",[t._v("myAbort")]),t._v(" function in "),a("code",[t._v("assembly/index.ts")]),t._v(". Useful if an environment does not provide compatible implementations, or when the respective imports are not desired and custom implementations are sufficient.")]),t._v(" "),a("h3",{attrs:{id:"accessing-memory-during-instantiation"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#accessing-memory-during-instantiation"}},[t._v("#")]),t._v(" Accessing memory during instantiation")]),t._v(" "),a("p",[t._v("One important edge case to be aware of is that top-level statements are executed as part of the WebAssembly module's implicit "),a("code",[t._v("(start ...)")]),t._v(" function by default, which leads to a chicken and egg problem when top-level statements already call out to external functionality that needs to access the module's memory instance (say, reading the contents of a logged string). Since instantiation did not yet complete, the module's exports, including exported memory, are not available yet and the access will fail.")]),t._v(" "),a("p",[t._v("A solution is to utilize the "),a("code",[t._v("--exportStart")]),t._v(" command line option to force exporting the start function instead of making it implicit. Then, instantiation first returns before any code is executed. Note, however, that the exported start function must always be called first, before any other exports, or undefined behavior will occur.")]),t._v(" "),a("h2",{attrs:{id:"tree-shaking"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#tree-shaking"}},[t._v("#")]),t._v(" Tree-shaking")]),t._v(" "),a("p",[t._v("AssemblyScript does not compile a module linearly, but starts at the module's exports and only compiles what's reachable from them, often referred to as "),a("a",{attrs:{href:"https://en.wikipedia.org/wiki/Tree_shaking",target:"_blank",rel:"noopener noreferrer"}},[t._v("tree-shaking"),a("OutboundLink")],1),t._v(". As such, dead code is always validated syntactically, but not necessarily checked for semantic correctness. While this mechanism significantly helps to reduce compile times and feels almost natural to those familiar with "),a("em",[t._v("executing")]),t._v(" JavaScript, it may initially feel a little strange not only to those with a background in traditional compilers, for example because emitted diagnostics do not happen linearly, but also to those with a background in TypeScript, because even type annotations remain unchecked as part of dead code. The exception to the rule is top-level code, including top-level variable declarations and their initializers, that must be evaluated as soon as the respective file would first execute.")]),t._v(" "),a("h3",{attrs:{id:"branch-level-tree-shaking"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#branch-level-tree-shaking"}},[t._v("#")]),t._v(" Branch-level tree-shaking")]),t._v(" "),a("p",[t._v("In addition to module-level tree-shaking, the compiler ignores branches that it can prove won't be taken. Works with constants, built-ins that compile to a constant, expressions that can be precomputed to a constant, plus the following globals to detect specific compiler flags or features:")]),t._v(" "),a("ul",[a("li",[a("div",{staticClass:"language-ts extra-class"},[a("pre",{pre:!0,attrs:{class:"language-ts"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("ASC_TARGET")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("i32")]),t._v("\n")])])]),a("p",[t._v("Indicates the compilation target. Possible values are 0 = JS (portable), 1 = WASM32, 2 = WASM64.")])]),t._v(" "),a("li",[a("div",{staticClass:"language-ts extra-class"},[a("pre",{pre:!0,attrs:{class:"language-ts"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("ASC_NO_ASSERT")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("bool")]),t._v("\n")])])]),a("p",[t._v("Whether "),a("code",[t._v("--noAssert")]),t._v(" has been set.")])]),t._v(" "),a("li",[a("div",{staticClass:"language-ts extra-class"},[a("pre",{pre:!0,attrs:{class:"language-ts"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("ASC_MEMORY_BASE")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("usize")]),t._v("\n")])])]),a("p",[t._v("The value of "),a("code",[t._v("--memoryBase")]),t._v(".")])]),t._v(" "),a("li",[a("div",{staticClass:"language-ts extra-class"},[a("pre",{pre:!0,attrs:{class:"language-ts"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("ASC_OPTIMIZE_LEVEL")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("i32")]),t._v("\n")])])]),a("p",[t._v("The value of "),a("code",[t._v("--optimizeLevel")]),t._v(". Possible values are 0, 1, 2 and 3.")])]),t._v(" "),a("li",[a("div",{staticClass:"language-ts extra-class"},[a("pre",{pre:!0,attrs:{class:"language-ts"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("ASC_SHRINK_LEVEL")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("i32")]),t._v("\n")])])]),a("p",[t._v("The value of "),a("code",[t._v("--shrinkLevel")]),t._v(". Possible values are 0, 1 and 2.")])]),t._v(" "),a("li",[a("div",{staticClass:"language-ts extra-class"},[a("pre",{pre:!0,attrs:{class:"language-ts"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("ASC_LOW_MEMORY_LIMIT")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("i32")]),t._v("\n")])])]),a("p",[t._v("The value of "),a("code",[t._v("--lowMemoryLimit")]),t._v(".")])]),t._v(" "),a("li",[a("div",{staticClass:"language-ts extra-class"},[a("pre",{pre:!0,attrs:{class:"language-ts"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("ASC_EXPORT_RUNTIME")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("i32")]),t._v("\n")])])]),a("p",[t._v("Whether "),a("code",[t._v("--exportRuntime")]),t._v(" has been set.")])]),t._v(" "),a("li",[a("div",{staticClass:"language-ts extra-class"},[a("pre",{pre:!0,attrs:{class:"language-ts"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("ASC_FEATURE_SIGN_EXTENSION")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("bool")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("ASC_FEATURE_MUTABLE_GLOBALS")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("bool")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("ASC_FEATURE_NONTRAPPING_F2I")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("bool")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("ASC_FEATURE_BULK_MEMORY")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("bool")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("ASC_FEATURE_SIMD")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("bool")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("ASC_FEATURE_THREADS")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("bool")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("ASC_FEATURE_EXCEPTION_HANDLING")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("bool")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("ASC_FEATURE_TAIL_CALLS")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("bool")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("ASC_FEATURE_REFERENCE_TYPES")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("bool")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("ASC_FEATURE_MULTI_VALUE")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("bool")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("ASC_FEATURE_GC")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("bool")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("ASC_FEATURE_MEMORY64")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("bool")]),t._v("\n")])])]),a("p",[t._v("Whether the respective feature is enabled.")]),t._v(" "),a("p",[t._v("For example, if a library supports SIMD but also wants to provide a fallback when being compiled without SIMD support:")]),t._v(" "),a("div",{staticClass:"language-ts extra-class"},[a("pre",{pre:!0,attrs:{class:"language-ts"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("ASC_FEATURE_SIMD")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// compute with SIMD operations")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// fallback without SIMD operations")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])])])]),t._v(" "),a("h2",{attrs:{id:"code-annotations"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#code-annotations"}},[t._v("#")]),t._v(" Code annotations")]),t._v(" "),a("p",[t._v("Decorators work more like compiler annotations in AssemblyScript and are evaluated at compile time.")]),t._v(" "),a("table",[a("thead",[a("tr",[a("th",{staticStyle:{"text-align":"left"}},[t._v("Annotation")]),t._v(" "),a("th",{staticStyle:{"text-align":"left"}},[t._v("Description")])])]),t._v(" "),a("tbody",[a("tr",[a("td",{staticStyle:{"text-align":"left"}},[a("code",[t._v("@inline")])]),t._v(" "),a("td",{staticStyle:{"text-align":"left"}},[t._v("Requests inlining of a constant or function.")])]),t._v(" "),a("tr",[a("td",{staticStyle:{"text-align":"left"}},[a("code",[t._v("@final")])]),t._v(" "),a("td",{staticStyle:{"text-align":"left"}},[t._v("Annotates a class as final, that is it cannot be subclassed.")])]),t._v(" "),a("tr",[a("td",{staticStyle:{"text-align":"left"}},[a("code",[t._v("@unmanaged")])]),t._v(" "),a("td",{staticStyle:{"text-align":"left"}},[t._v("Annotates a class as not tracked by GC, effectively becoming a C-like struct.")])]),t._v(" "),a("tr",[a("td",{staticStyle:{"text-align":"left"}},[a("code",[t._v("@external")])]),t._v(" "),a("td",{staticStyle:{"text-align":"left"}},[t._v("Changes the external name of an imported element. "),a("code",[t._v("@external(module, name)")]),t._v(" changes both the module and element name, "),a("code",[t._v("@external(name)")]),t._v(" changes the element name only.")])])])]),t._v(" "),a("p",[t._v("Custom decorators are ignored, unless given meaning by using a "),a("RouterLink",{attrs:{to:"/compiler.html#transforms"}},[t._v("transform")]),t._v(".")],1),t._v(" "),a("p",[t._v("There are a few more built-in decorators that are likely going to change significantly over time, or may even be removed entirely. While useful for standard library implementation currently, it is not recommend to utilize them in custom code since tooling does not recognize them.")]),t._v(" "),a("details",[a("summary",[t._v("Show me anyway")]),t._v(" "),a("table",[a("thead",[a("tr",[a("th",{staticStyle:{"text-align":"left"}},[t._v("Annotation")]),t._v(" "),a("th",{staticStyle:{"text-align":"left"}},[t._v("Description")])])]),t._v(" "),a("tbody",[a("tr",[a("td",{staticStyle:{"text-align":"left"}},[a("code",[t._v("@global")])]),t._v(" "),a("td",{staticStyle:{"text-align":"left"}},[t._v("Registers an element to be part of the global scope.")])]),t._v(" "),a("tr",[a("td",{staticStyle:{"text-align":"left"}},[a("code",[t._v("@lazy")])]),t._v(" "),a("td",{staticStyle:{"text-align":"left"}},[t._v("Requests lazy compilation of a variable. Useful to avoid unnecessary globals.")])]),t._v(" "),a("tr",[a("td",{staticStyle:{"text-align":"left"}},[a("code",[t._v("@operator")])]),t._v(" "),a("td",{staticStyle:{"text-align":"left"}},[t._v("Annotates a method as a binary operator overload. See below.")])]),t._v(" "),a("tr",[a("td",{staticStyle:{"text-align":"left"}},[a("code",[t._v("@operator.binary")])]),t._v(" "),a("td",{staticStyle:{"text-align":"left"}},[t._v("Alias of "),a("code",[t._v("@operator")]),t._v(".")])]),t._v(" "),a("tr",[a("td",{staticStyle:{"text-align":"left"}},[a("code",[t._v("@operator.prefix")])]),t._v(" "),a("td",{staticStyle:{"text-align":"left"}},[t._v("Annotates a method as a unary prefix operator overload.")])]),t._v(" "),a("tr",[a("td",{staticStyle:{"text-align":"left"}},[a("code",[t._v("@operator.postfix")])]),t._v(" "),a("td",{staticStyle:{"text-align":"left"}},[t._v("Annotates a method as a unary postfix operator overload.")])])])]),t._v(" "),a("h3",{attrs:{id:"binary-operator-overloads"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#binary-operator-overloads"}},[t._v("#")]),t._v(" Binary operator overloads")]),t._v(" "),a("div",{staticClass:"language-ts extra-class"},[a("pre",{pre:!0,attrs:{class:"language-ts"}},[a("code",[a("span",{pre:!0,attrs:{class:"token decorator"}},[a("span",{pre:!0,attrs:{class:"token at operator"}},[t._v("@")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("operator")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("OP")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("static")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("__op")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("left"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("T")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" right "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("T")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("T")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("...")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token decorator"}},[a("span",{pre:!0,attrs:{class:"token at operator"}},[t._v("@")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("operator")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("OP")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("__op")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("right"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("T")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("T")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("...")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("table",[a("thead",[a("tr",[a("th",{staticStyle:{"text-align":"left"}},[t._v("OP")]),t._v(" "),a("th",{staticStyle:{"text-align":"left"}},[t._v("Description")])])]),t._v(" "),a("tbody",[a("tr",[a("td",{staticStyle:{"text-align":"left"}},[a("code",[t._v('"[]"')])]),t._v(" "),a("td",{staticStyle:{"text-align":"left"}},[t._v("Checked indexed get")])]),t._v(" "),a("tr",[a("td",{staticStyle:{"text-align":"left"}},[a("code",[t._v('"[]="')])]),t._v(" "),a("td",{staticStyle:{"text-align":"left"}},[t._v("Checked indexed set")])]),t._v(" "),a("tr",[a("td",{staticStyle:{"text-align":"left"}},[a("code",[t._v('"{}"')])]),t._v(" "),a("td",{staticStyle:{"text-align":"left"}},[t._v("Unchecked indexed get")])]),t._v(" "),a("tr",[a("td",{staticStyle:{"text-align":"left"}},[a("code",[t._v('"{}="')])]),t._v(" "),a("td",{staticStyle:{"text-align":"left"}},[t._v("Unchecked indexed set")])]),t._v(" "),a("tr",[a("td",{staticStyle:{"text-align":"left"}},[a("code",[t._v('"=="')])]),t._v(" "),a("td",{staticStyle:{"text-align":"left"}},[t._v("Equality (also applies on "),a("code",[t._v("===")]),t._v(")")])]),t._v(" "),a("tr",[a("td",{staticStyle:{"text-align":"left"}},[a("code",[t._v('"!="')])]),t._v(" "),a("td",{staticStyle:{"text-align":"left"}},[t._v("Inequality (also applies on "),a("code",[t._v("!==")]),t._v(")")])]),t._v(" "),a("tr",[a("td",{staticStyle:{"text-align":"left"}},[a("code",[t._v('">"')])]),t._v(" "),a("td",{staticStyle:{"text-align":"left"}},[t._v("Greater than")])]),t._v(" "),a("tr",[a("td",{staticStyle:{"text-align":"left"}},[a("code",[t._v('">="')])]),t._v(" "),a("td",{staticStyle:{"text-align":"left"}},[t._v("Greater than or equal")])]),t._v(" "),a("tr",[a("td",{staticStyle:{"text-align":"left"}},[a("code",[t._v('"<"')])]),t._v(" "),a("td",{staticStyle:{"text-align":"left"}},[t._v("Less than")])]),t._v(" "),a("tr",[a("td",{staticStyle:{"text-align":"left"}},[a("code",[t._v('"<="')])]),t._v(" "),a("td",{staticStyle:{"text-align":"left"}},[t._v("Less than or equal")])]),t._v(" "),a("tr",[a("td",{staticStyle:{"text-align":"left"}},[a("code",[t._v('">>"')])]),t._v(" "),a("td",{staticStyle:{"text-align":"left"}},[t._v("Arithmetic right shift")])]),t._v(" "),a("tr",[a("td",{staticStyle:{"text-align":"left"}},[a("code",[t._v('">>>"')])]),t._v(" "),a("td",{staticStyle:{"text-align":"left"}},[t._v("Logical right shift")])]),t._v(" "),a("tr",[a("td",{staticStyle:{"text-align":"left"}},[a("code",[t._v('"<<"')])]),t._v(" "),a("td",{staticStyle:{"text-align":"left"}},[t._v("Left shift")])]),t._v(" "),a("tr",[a("td",{staticStyle:{"text-align":"left"}},[a("code",[t._v('"&"')])]),t._v(" "),a("td",{staticStyle:{"text-align":"left"}},[t._v("Bitwise AND")])]),t._v(" "),a("tr",[a("td",{staticStyle:{"text-align":"left"}},[a("code",[t._v('"|"')])]),t._v(" "),a("td",{staticStyle:{"text-align":"left"}},[t._v("Bitwise OR")])]),t._v(" "),a("tr",[a("td",{staticStyle:{"text-align":"left"}},[a("code",[t._v('"^"')])]),t._v(" "),a("td",{staticStyle:{"text-align":"left"}},[t._v("Bitwise XOR")])]),t._v(" "),a("tr",[a("td",{staticStyle:{"text-align":"left"}},[a("code",[t._v('"+"')])]),t._v(" "),a("td",{staticStyle:{"text-align":"left"}},[t._v("Addition")])]),t._v(" "),a("tr",[a("td",{staticStyle:{"text-align":"left"}},[a("code",[t._v('"-"')])]),t._v(" "),a("td",{staticStyle:{"text-align":"left"}},[t._v("Subtraction")])]),t._v(" "),a("tr",[a("td",{staticStyle:{"text-align":"left"}},[a("code",[t._v('"*"')])]),t._v(" "),a("td",{staticStyle:{"text-align":"left"}},[t._v("Multiplication")])]),t._v(" "),a("tr",[a("td",{staticStyle:{"text-align":"left"}},[a("code",[t._v('"/"')])]),t._v(" "),a("td",{staticStyle:{"text-align":"left"}},[t._v("Division")])]),t._v(" "),a("tr",[a("td",{staticStyle:{"text-align":"left"}},[a("code",[t._v('"**"')])]),t._v(" "),a("td",{staticStyle:{"text-align":"left"}},[t._v("Exponentiation")])]),t._v(" "),a("tr",[a("td",{staticStyle:{"text-align":"left"}},[a("code",[t._v('"%"')])]),t._v(" "),a("td",{staticStyle:{"text-align":"left"}},[t._v("Remainder")])])])]),t._v(" "),a("h3",{attrs:{id:"unary-operator-overloads"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#unary-operator-overloads"}},[t._v("#")]),t._v(" Unary operator overloads")]),t._v(" "),a("div",{staticClass:"language-ts extra-class"},[a("pre",{pre:!0,attrs:{class:"language-ts"}},[a("code",[a("span",{pre:!0,attrs:{class:"token decorator"}},[a("span",{pre:!0,attrs:{class:"token at operator"}},[t._v("@")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("operator")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("prefix")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("OP")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("static")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("__op")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("self"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("T")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("T")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("...")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token decorator"}},[a("span",{pre:!0,attrs:{class:"token at operator"}},[t._v("@")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("operator")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("prefix")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("OP")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("__op")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("T")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("...")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("table",[a("thead",[a("tr",[a("th",{staticStyle:{"text-align":"left"}},[t._v("OP")]),t._v(" "),a("th",{staticStyle:{"text-align":"left"}},[t._v("Description")]),t._v(" "),a("th",{staticStyle:{"text-align":"left"}},[t._v("Notes")])])]),t._v(" "),a("tbody",[a("tr",[a("td",{staticStyle:{"text-align":"left"}},[a("code",[t._v('"!"')])]),t._v(" "),a("td",{staticStyle:{"text-align":"left"}},[t._v("Logical NOT")]),t._v(" "),a("td",{staticStyle:{"text-align":"left"}})]),t._v(" "),a("tr",[a("td",{staticStyle:{"text-align":"left"}},[a("code",[t._v('"~"')])]),t._v(" "),a("td",{staticStyle:{"text-align":"left"}},[t._v("Bitwise NOT")]),t._v(" "),a("td",{staticStyle:{"text-align":"left"}})]),t._v(" "),a("tr",[a("td",{staticStyle:{"text-align":"left"}},[a("code",[t._v('"+"')])]),t._v(" "),a("td",{staticStyle:{"text-align":"left"}},[t._v("Unary plus")]),t._v(" "),a("td",{staticStyle:{"text-align":"left"}})]),t._v(" "),a("tr",[a("td",{staticStyle:{"text-align":"left"}},[a("code",[t._v('"-"')])]),t._v(" "),a("td",{staticStyle:{"text-align":"left"}},[t._v("Unary negation")]),t._v(" "),a("td",{staticStyle:{"text-align":"left"}})]),t._v(" "),a("tr",[a("td",{staticStyle:{"text-align":"left"}},[a("code",[t._v('"++"')])]),t._v(" "),a("td",{staticStyle:{"text-align":"left"}},[t._v("Prefix increment")]),t._v(" "),a("td",{staticStyle:{"text-align":"left"}},[t._v("Instance overload reassigns")])]),t._v(" "),a("tr",[a("td",{staticStyle:{"text-align":"left"}},[a("code",[t._v('"--"')])]),t._v(" "),a("td",{staticStyle:{"text-align":"left"}},[t._v("Prefix decrement")]),t._v(" "),a("td",{staticStyle:{"text-align":"left"}},[t._v("Instance overload reassigns")])])])]),t._v(" "),a("p",[t._v("Note that increment and decrement overloads can have slightly different semantics. If the overload is declared as an instance method, on "),a("code",[t._v("++a")]),t._v(" the compiler does emit code that reassigns the resulting value to "),a("code",[t._v("a")]),t._v(" while if the overload is declared static, the overload behaves like any other overload, skipping the otherwise implicit assignment.")]),t._v(" "),a("h3",{attrs:{id:"unary-postfix-operations"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#unary-postfix-operations"}},[t._v("#")]),t._v(" Unary postfix operations")]),t._v(" "),a("div",{staticClass:"language-ts extra-class"},[a("pre",{pre:!0,attrs:{class:"language-ts"}},[a("code",[a("span",{pre:!0,attrs:{class:"token decorator"}},[a("span",{pre:!0,attrs:{class:"token at operator"}},[t._v("@")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("operator")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("postfix")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("OP")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("static")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("__op")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("self"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("T")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("T")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("...")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token decorator"}},[a("span",{pre:!0,attrs:{class:"token at operator"}},[t._v("@")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("operator")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("postfix")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("OP")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("__op")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("T")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("...")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("table",[a("thead",[a("tr",[a("th",{staticStyle:{"text-align":"left"}},[t._v("OP")]),t._v(" "),a("th",{staticStyle:{"text-align":"left"}},[t._v("Description")]),t._v(" "),a("th",{staticStyle:{"text-align":"left"}},[t._v("Notes")])])]),t._v(" "),a("tbody",[a("tr",[a("td",{staticStyle:{"text-align":"left"}},[a("code",[t._v('"++"')])]),t._v(" "),a("td",{staticStyle:{"text-align":"left"}},[t._v("Postfix increment")]),t._v(" "),a("td",{staticStyle:{"text-align":"left"}},[t._v("Instance overload reassigns")])]),t._v(" "),a("tr",[a("td",{staticStyle:{"text-align":"left"}},[a("code",[t._v('"--"')])]),t._v(" "),a("td",{staticStyle:{"text-align":"left"}},[t._v("Postfix decrement")]),t._v(" "),a("td",{staticStyle:{"text-align":"left"}},[t._v("Instance overload reassigns")])])])]),t._v(" "),a("p",[t._v("Overloaded postfix operations do not preserve the original value automatically.")])])])}),[],!1,null,null,null);s.default=n.exports}}]); \ No newline at end of file diff --git a/assets/js/24.ee2d454f.js b/assets/js/24.ee2d454f.js new file mode 100644 index 000000000..6a5800ebe --- /dev/null +++ b/assets/js/24.ee2d454f.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[24],{226:function(t,e,n){"use strict";n.r(e);var a=n(6),r=Object(a.a)({},(function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[n("h1",{attrs:{id:"editor-test"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#editor-test"}},[t._v("#")]),t._v(" Editor Test")]),t._v(" "),n("p",[t._v("Text before")]),t._v(" "),n("div",{staticClass:"language-editor extra-class"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[t._v('#!runtime=stub\n// Editor A\n\nexport function add(a: i32, b: i32): i32 {\n return a + b\n}\n\nexport function sub(a: i32, b: i32): i32 {\n return a - b\n}\n\n#!html\n + + \ No newline at end of file diff --git a/basics/environment/index.html b/basics/environment/index.html new file mode 100644 index 000000000..6db2bb3c4 --- /dev/null +++ b/basics/environment/index.html @@ -0,0 +1,43 @@ + + + + + + +

+ Redirect after 3s +

+

+ Powered by vuepress-plugin-redirect +

+ + + \ No newline at end of file diff --git a/basics/exports-and-imports/index.html b/basics/exports-and-imports/index.html new file mode 100644 index 000000000..29f33af77 --- /dev/null +++ b/basics/exports-and-imports/index.html @@ -0,0 +1,43 @@ + + + + + + +

+ Redirect after 3s +

+

+ Powered by vuepress-plugin-redirect +

+ + + \ No newline at end of file diff --git a/basics/loader/index.html b/basics/loader/index.html new file mode 100644 index 000000000..21c3f7290 --- /dev/null +++ b/basics/loader/index.html @@ -0,0 +1,43 @@ + + + + + + +

+ Redirect after 3s +

+

+ Powered by vuepress-plugin-redirect +

+ + + \ No newline at end of file diff --git a/basics/types/index.html b/basics/types/index.html new file mode 100644 index 000000000..c9dfd249d --- /dev/null +++ b/basics/types/index.html @@ -0,0 +1,43 @@ + + + + + + +

+ Redirect after 3s +

+

+ Powered by vuepress-plugin-redirect +

+ + + \ No newline at end of file diff --git a/browserconfig.xml b/browserconfig.xml new file mode 100644 index 000000000..76f82c5ed --- /dev/null +++ b/browserconfig.xml @@ -0,0 +1,9 @@ + + + + + + #ffffff + + + diff --git a/built-with-assemblyscript.html b/built-with-assemblyscript.html new file mode 100644 index 000000000..367802f64 --- /dev/null +++ b/built-with-assemblyscript.html @@ -0,0 +1,161 @@ + + + + + + Built with AssemblyScript | The AssemblyScript Book + + + + + + + + + + + + + + + + + + +

# Built with AssemblyScript

A place for all things AssemblyScript. Feel free to add your projects and applications.

# Benchmarks

# Blockchain

# Build Tools

# Demoscene

# Editors

# Formatter

# Emulators

# Games

# Graphics / Game Frameworks

# Data Serialization / Deserialization

# Crypto (non-blockchain)

# Fixed & Arbitrary Precision Arithmetics

# Language Extensions and Types

# Bindings

# Other Libraries

# Embedded / IoT

# Testing / Benchmarking

# Project Templates

# Applications

+ + + diff --git a/builtins.html b/builtins.html new file mode 100644 index 000000000..36b339b81 --- /dev/null +++ b/builtins.html @@ -0,0 +1,43 @@ + + + + + + +

+ Redirect after 3s +

+

+ Powered by vuepress-plugin-redirect +

+ + + \ No newline at end of file diff --git a/compiler.html b/compiler.html new file mode 100644 index 000000000..86c5b84d3 --- /dev/null +++ b/compiler.html @@ -0,0 +1,333 @@ + + + + + + Using the compiler | The AssemblyScript Book + + + + + + + + + + + + + + + + + + +

# Using the compiler

Similar to TypeScript's tsc transpiling to JavaScript, AssemblyScript's asc compiles to WebAssembly.

# Compiler options

The compiler supports various options available on the command line, in a configuration file and programmatically. On the command line, it looks like this:

# Entry file(s)

Non-option arguments are treated as the names of entry files. A single program can have multiple entries, with the exports of each entry becoming the exports of the WebAssembly module. Exports of imported files that are not entry files do not become WebAssembly module exports.

asc entryFile.ts
+

# General

--version, -v         Prints just the compiler's version and exits.
+--help, -h            Prints this message and exits.
+--config              Configuration file to apply. CLI arguments take precedence.
+--target              Configuration file target to use. Defaults to 'release'.
+

# Optimization

The compiler can optimize for both speed (-Ospeed) and size (-Osize), as well as produce a debug build (--debug).

--optimize, -O        Optimizes the module. Typical shorthands are:
+
+                        Default optimizations   -O
+                        Make a release build    -O --noAssert
+                        Make a debug build      --debug
+                        Optimize for speed      -Ospeed
+                        Optimize for size       -Osize
+
+--optimizeLevel       How much to focus on optimizing code. [0-3]
+--shrinkLevel         How much to focus on shrinking code size. [0-2, s=1, z=2]
+--converge            Re-optimizes until no further improvements can be made.
+--noAssert            Replaces assertions with just their value without trapping.
+--uncheckedBehavior   Changes the behavior of unchecked() expressions.
+                      Using this option can potentially cause breakage.
+
+                        default  The default behavior: unchecked operations are
+                                 only used inside of unchecked().
+                        never    Unchecked operations are never used, even when,
+                                 inside of unchecked().
+                        always   Unchecked operations are always used if possible,
+                                 whether or not unchecked() is used.
+
+

Optimization levels can also be tweaked manually: --optimizeLevel (0-3) indicates how much the compiler focuses on optimizing the code with --shrinkLevel (0-2, 1=s, 2=z) indicating how much it focuses on keeping the size low during code generation and while optimizing. A shorthand for both is -O[optimizeLevel][shrinkLevel] , with shrink level indicated by optionally appending the letter s (1) or z (2).

# Output

Typical output formats are WebAssembly binary (.wasm, --outFile) and/or text format (.wat, --textFile). Often, both are used in tandem to run and also inspect generated code.

--outFile, -o         Specifies the WebAssembly output file (.wasm).
+--textFile, -t        Specifies the WebAssembly text output file (.wat).
+--bindings, -b        Specifies the bindings to generate (.js + .d.ts).
+
+                        esm  JavaScript bindings & typings for ESM integration.
+                        raw  Like esm, but exports just the instantiate function.
+                             Useful where modules are meant to be instantiated
+                             multiple times or non-ESM imports must be provided.
+

# Debugging

For easier debugging during development, a source map can be emitted alongside the WebAssembly binary, and debug symbols can be embedded:

--sourceMap           Enables source map generation. Optionally takes the URL
+                      used to reference the source map from the binary file.
+--debug               Enables debug information in emitted binaries.
+

# Features

There are several flags that enable or disable specific WebAssembly or compiler features. By default, only the bare minimum is exposed, and fully standardized WebAssembly features will be used.

--importMemory        Imports the memory from 'env.memory'.
+--noExportMemory      Does not export the memory as 'memory'.
+--initialMemory       Sets the initial memory size in pages.
+--maximumMemory       Sets the maximum memory size in pages.
+--sharedMemory        Declare memory as shared. Requires maximumMemory.
+--zeroFilledMemory    Assume imported memory is zeroed. Requires importMemory.
+--importTable         Imports the function table from 'env.table'.
+--exportTable         Exports the function table as 'table'.
+--exportStart         Exports the start function using the specified name instead
+                      of calling it implicitly. Useful for WASI or to obtain the
+                      exported memory before executing any code accessing it.
+--runtime             Specifies the runtime variant to include in the program.
+
+                        incremental  TLSF + incremental GC (default)
+                        minimal      TLSF + lightweight GC invoked externally
+                        stub         Minimal runtime stub (never frees)
+                        ...          Path to a custom runtime implementation
+
+--exportRuntime       Always exports the runtime helpers (__new, __collect, __pin etc.).
+                      Automatically determined when generation of --bindings is enabled.
+--stackSize           Overrides the stack size. Only relevant for incremental GC
+                      or when using a custom runtime that requires stack space.
+                      Defaults to 0 without and to 16384 with incremental GC.
+--enable              Enables WebAssembly features being disabled by default.
+
+                        threads             Threading and atomic operations.
+                        simd                SIMD types and operations.
+                        reference-types     Reference types and operations.
+                        gc                  Garbage collection (WIP).
+                        stringref           String reference types.
+                        relaxed-simd        Relaxed SIMD operations.
+
+--disable             Disables WebAssembly features being enabled by default.
+
+                        mutable-globals     Mutable global imports and exports.
+                        sign-extension      Sign-extension operations
+                        nontrapping-f2i     Non-trapping float to integer ops.
+                        bulk-memory         Bulk memory operations.
+
+--use, -u             Aliases a global object under another name, e.g., to switch
+                      the default 'Math' implementation used: --use Math=JSMath
+                      Can also be used to introduce an integer constant.
+--lowMemoryLimit      Enforces very low (<64k) memory constraints.
+

# Linking

Specifying the base offsets of compiler-generated memory respectively the table leaves some space for other data in front. In its current form this is mostly useful to link additional data into an AssemblyScript binary after compilation, be it by populating the binary itself or initializing the data externally upon initialization. One good example is leaving some scratch space for a frame buffer.

--memoryBase          Sets the start offset of emitted memory segments.
+--tableBase           Sets the start offset of emitted table elements.
+

# API

To integrate with the compiler, for example to post-process the AST, one or multiple custom transforms can be specified.

--transform           Specifies the path to a custom transform to load.
+

# Other

Other options include those forwarded to Binaryen and various flags useful in certain situations.

# Binaryen

--trapMode            Sets the trap mode to use.
+
+                       allow  Allow trapping operations. This is the default.
+                       clamp  Replace trapping operations with clamping semantics.
+                       js     Replace trapping operations with JS semantics.
+
+--runPasses           Specifies additional Binaryen passes to run after other
+                      optimizations, if any. See: Binaryen/src/passes/pass.cpp
+--noValidate          Skips validating the module using Binaryen.
+

# And the kitchen sink

--baseDir             Specifies the base directory of input and output files.
+--noColors            Disables terminal colors.
+--noUnsafe            Disallows the use of unsafe features in user code.
+                      Does not affect library files and external modules.
+--disableWarning      Disables warnings matching the given diagnostic code.
+                      If no diagnostic code is given, all warnings are disabled.
+--noEmit              Performs compilation as usual but does not emit code.
+--stats               Prints statistics on I/O and compile times.
+--pedantic            Make yourself sad for no good reason.
+--lib                 Adds one or multiple paths to custom library components and
+                      uses exports of all top-level files at this path as globals.
+--path                Adds one or multiple paths to package resolution, similar
+                      to node_modules. Prefers an 'ascMain' entry in a package's
+                      package.json and falls back to an inner 'assembly/' folder.
+--wasm                Uses the specified Wasm binary of the compiler.
+-- ...                Specifies node.js options (CLI only). See: node --help
+

# Configuration file

Instead of providing the options outlined above on the command line, a configuration file typically named asconfig.json can be used. It may look like in the following example, excluding comments:

{
+  "extends": "./path/to/other/asconfig.json", // (optional) base config
+  "entries": [
+    // (optional) entry files, e.g.
+    "./assembly/index.ts"
+  ],
+  "options": {
+    // common options, e.g.
+    "importTable": true
+  },
+  "targets": {
+    // (optional) targets
+    "release": {
+      // additional options for the "release" target, e.g.
+      "optimize": true,
+      "outFile": "myModule.release.wasm"
+    },
+    "debug": {
+      // additional options for the "debug" target, e.g.
+      "debug": true,
+      "outFile": "myModule.debug.wasm"
+    }
+  }
+}
+

Per-target options, e.g. targets.release, add to and override top-level options. Options provided on the command line override any options in the configuration file. Usage is, for example:

asc --config asconfig.json --target release
+

# Programmatic usage

The compiler API can also be used programmatically:

import asc from "assemblyscript/asc";
+
+const { error, stdout, stderr, stats } = await asc.main([
+  // Command line options
+  "myModule.ts",
+  "--outFile", "myModule.wasm",
+  "--optimize",
+  "--sourceMap",
+  "--stats"
+], {
+  // Additional API options
+  stdout?: ...,
+  stderr?: ...,
+  readFile?: ...,
+  writeFile?: ...,
+  listFiles?: ...,
+  reportDiagnostic?: ...,
+  transforms?: ...
+});
+if (error) {
+  console.log("Compilation failed: " + error.message);
+  console.log(stderr.toString());
+} else {
+  console.log(stdout.toString());
+}
+

The compiler runs in browsers as well. The simplest way to set it up is to include the generated web.js (opens new window) so the compiler can be used with an import on the Web:

<script src="https://cdn.jsdelivr.net/npm/assemblyscript@x.x.x/dist/web.js"></script>
+<script type="module">
+import asc from "assemblyscript/asc";
+...
+</script>
+

Here, x.x.x must be replaced with the respective version to use (opens new window), or latest to always use the latest version (not recommended in production). By default, the script installs the necessary import map (opens new window) and, for browsers that do not yet support import maps, an import map shim (opens new window). It also accepts the following options in case there is a need to only perform part of the setup:

Script URL Effect
web.js?noinstall Does not install the import map.
web.js?noshim Does not install the import map shim.
web.js?noinstall,noshim Does not install the import map or shim.

Regardless of the options used, the script always declares the following global variables:

Variable Description
ASSEMBLYSCRIPT_VERSION Version string of the compiler release used
ASSEMBLYSCRIPT_IMPORTMAP The respective import map of the release as JSON

# Host bindings

WebAssembly alone cannot yet transfer higher level data types like strings, arrays and objects over module boundaries, so for now some amount of glue code is required to exchange these data structures with the host / JavaScript.

The compiler can generate the necessary bindings using the --bindings command line option (either as an ES module or a raw instantiate function), enabling exchange of:

Type Strategy Description
Number By value Basic numeric types except 64-bit integers.
BigInt By value 64-bit integers via js-bigint-integration.
Boolean By value Coerced to true or false.
Externref By reference Using reference-types.
String Copy
ArrayBuffer Copy
TypedArray Copy Any Int8Array, Float64Array etc.
Array Copy Any Array<T>
StaticArray Copy Any StaticArray<T>
Object Copy If a plain object. That is: Has no constructor or non-public fields.
Object By reference If not a plain object. Passed as an opaque reference counted pointer.

Note the two different strategies used for Object: In some situations, say when calling a Web API, it may be preferable to copy the object as a whole, field by field, which is the strategy chosen for plain objects with no constructor or non-public fields:

// Copied to a JS object
+class PlainObject {
+  field: string;
+}
+
+export function getObject(): PlainObject {
+  return {
+    field: "hello world"
+  };
+}
+

However, copying may not be desirable in every situation, say when individual object properties are meant to be modified externally where serializing/deserializing the object as a whole would result in unnecessary overhead. To support this use case, the compiler can pass just an opaque reference to the object, which can be enforced by providing an empty constructor (not a plain object anymore):

// Not copied to a JS object
+class ComplexObject {
+  constructor() {} // !
+  field: string | null;
+}
+
+export function newObject(): ComplexObject {
+  return new ComplexObject();
+}
+
+export function setObjectField(target: ComplexObject, field: string | null): void {
+  target.field = field;
+}
+
+export function getObjectField(target: ComplexObject): string | null {
+  return target.field;
+}
+

Also note that exporting an entire class has no effect at the module boundary (yet), and it is instead recommended to expose only the needed functionality as shown in the example above. Supported elements at the boundary are globals, functions and enums.

# Using ESM bindings

Bindings generated with --bindings esm perform all the steps from compilation over instantiation to exporting the final interface. To do so, a few assumptions had to be made:

  • The WebAssembly binary is located next to the JavaScript bindings file using the same name but with a .wasm extension.

    build/mymodule.js
    +build/mymodule.wasm
    +
    import * as myModule from "./build/mymodule.js"
    +
  • JavaScript globals in globalThis can be accessed directly via the env module namespace. For example, console.log can be manually imported through:

    @external("env", "console.log")
    +declare function consoleLog(s: string): void
    +

    Note that this is just an example and console.log is already provided by the standard library when called from an AssemblyScript file. Other global functions not already provided by the standard library may require an import as of this example, though.

  • Imports from other namespaces than env, i.e. (import "module" "name"), become an import { name } from "module" within the binding. Importing a custom function from a JavaScript file next to the bindings file can be achieved through:

    @external("./otherfile.js", "myFunction")
    +declare function myFunction(...): ...
    +

    Similarly, importing a custom function from, say, a Node.js dependency can be achieved through:

    @external("othermodule", "myFunction")
    +declare function myFunction(...): ...
    +

These assumptions cannot be intercepted or customized since, to provide static ESM exports from the bindings file directly, instantiation must start immediately when the bindings file is imported. If customization is required, --bindings raw can be used instead.

# Using raw bindings

The signature of the single instantiate function exported by --bindings raw is:

export async function instantiate(module: WebAssembly.Module, imports?: WebAssembly.Imports): AdaptedExports
+

Note that the function does not make any assumptions on how the module is to be compiled, but instead expects a readily compiled WebAssembly.Module as in this example:

import { instantiate } from "./module.js"
+const exports = await instantiate(await WebAssembly.compileStreaming(fetch("./module.wasm")), { /* imports */ })
+

Unlike --bindings esm, raw bindings also do not make any assumptions on how imports are resolved, so these must be provided manually as part of the imports object. For example, to achieve a similar result as with ESM bindings, but now customizable:

import { instantiate } from "./module.js"
+import * as other from "./otherfile.js"
+export const {
+  export1,
+  export2,
+  ...
+} = await instantiate(await WebAssembly.compileStreaming(fetch("./module.wasm")), {
+  "./otherfile.js": other
+})
+

# Debugging

The debugging workflow is similar to debugging JavaScript since both Wasm and JS execute in the same engine, and the compiler provides various options to set up additional WebAssembly-specific debug information. Note that any sort of optimization should be disabled in debug builds.

# Debug symbols

When compiling with the --debug option, the compiler appends a name section to the binary, containing names of functions, globals, locals and so on. These names will show up in stack traces.

# Source maps

The compiler can generate a source map alongside a binary using the --sourceMap option. By default, a relative source map path will be embedded in the binary which browsers can pick up when instantiating a module from a fetch response. In environments that do not provide fetch or an equivalent mechanism, like in Node.js, it is alternatively possible to embed an absolute source map path through --sourceMap path/to/source/map.

# Breakpoints

Some JavaScript engines also support adding break points directly in WebAssembly code. Please consult your engine's documentation: Chrome (opens new window), Firefox (opens new window), Node.js (opens new window), Safari (opens new window).

# Transforms

AssemblyScript is compiled statically, so code transformation cannot be done at runtime but must instead be performed at compile-time. To enable this, the compiler frontend (asc) provides a mechanism to hook into the compilation process before, while and after the module is being compiled.

Specifying --transform ./myTransform.js on the command line will load the node module pointed to by ./myTransform.js.

import * as assemblyscript from "assemblyscript"
+import { Transform } from "assemblyscript/transform"
+class MyTransform extends Transform {
+  ...
+}
+export default MyTransform
+

# Properties

A transform is an ES6 class/node module with the following inherited properties:

  • readonly program: Program
    +

    Reference to the Program instance.

  • readonly baseDir: string
    +

    Base directory used by the compiler.

  • readonly stdout: OutputStream
    +

    Output stream used by the compiler.

  • readonly stderr: OutputStream
    +

    Error stream uses by the compiler.

  • readonly log: typeof console.log
    +

    Logs a message to console.

  • function writeFile(filename: string, contents: string | Uint8Array, baseDir: string): boolean
    +

    Writes a file to disk.

  • function readFile(filename: string, baseDir: string): string | null
    +

    Reads a file from disk.

  • function listFiles(dirname: string, baseDir: string): string[] | null
    +

    Lists all files in a directory.

# Hooks

The frontend will call several hooks, if present on the transform, during the compilation process:

  • function afterParse(parser: Parser): void
    +

    Called when parsing is complete, before a program is initialized from the AST. Note that types are not yet known at this stage and there is no easy way to obtain them.

  • function afterInitialize(program: Program): void
    +

    Called once the program is initialized, before it is being compiled. Types are known at this stage, respectively can be resolved where necessary.

  • function afterCompile(module: Module): void
    +

    Called with the resulting module before it is being emitted. Useful to modify the IR before writing any output, for example to replace imports with actual functionality or to add custom sections.

Transforms are a very powerful feature, but may require profound knowledge of the compiler to utilize them to their full extent, so reading through the compiler sources is a plus.

# Portability

With AssemblyScript being very similar to TypeScript, there comes the opportunity to compile the same code to JavaScript with tsc and WebAssembly with asc. The AssemblyScript compiler itself is portable code. Writing portable code is largely a matter of double-checking that the intent translates to the same outcome in both the strictly typed AssemblyScript and the types-stripped-away TypeScript worlds.

# Portable standard library

Besides the full standard library, AssemblyScript provides a portable variant of the functionality that is present in both JavaScript and WebAssembly. In addition to that, the portable library lifts some of the functionality that is only available with asc to JavaScript, like the portable conversions mentioned below.

Also note that some parts of JavaScript's standard library function a little more loosely than how they would when compiling to WebAssembly. While the portable definitions try to take care of this, one example where this can happen is Map#get returning undefined when a key cannot be found in JavaScript, while resulting in an abort in WebAssembly, where it is necessary to first check that the key exists using Map#has.

To use the portable library, extend assemblyscript/std/portable.json instead of assemblyscript/std/assembly.json within tsconfig.json and add the following somewhere along your build step so the portable features are present in the environment:

import "assemblyscript/std/portable.js"
+

Note that the portable standard library is still a work in progress and so far focuses on functionality useful to make the compiler itself portable, so if you need something specific, feel free to improve its definitions and feature set (opens new window).

# Portable conversions

While asc understands the meaning of

// non-portable
+let someFloat: f32 = 1.5
+let someInt: i32 = <i32>someFloat
+

and then inserts the correct conversion steps, tsc does not because all numeric types are just aliases of number. Hence, when targeting JavaScript with tsc, the above will result in

var someFloat = 1.5
+var someInt = someFloat
+

which is obviously wrong. To account for this, portable conversions can be used, resulting in actually portable code. For example

// portable
+let someFloat: f32 = 1.5
+let someInt: i32 = i32(someFloat)
+

will essentially result in

var someFloat = 1.5
+var someInt = someFloat | 0
+

which is correct. The best way of dealing with this is asking yourself the question: What would this code do when compiled to JavaScript?

# Portable overflows

Likewise, again because asc knows the meaning but tsc does not, overflows must be handled explicitly:

// non-portable
+let someU8: u8 = 255
+let someOtherU8: u8 = someU8 + 1
+
// portable
+let someU8: u8 = 255
+let someOtherU8: u8 = u8(someU8 + 1)
+

essentially resulting in

let someU8 = 255
+let someOtherU8 = (someU8 + 1) & 0xff
+

# Non-portable code

In JavaScript, all numeric values are IEEE754 doubles that cannot represent the full range of values fitting in a 64-bit integer (max. safe integer (opens new window) is 2^53 - 1). Hence i64 and u64 are not portable and not present in std/portable. There are several ways to deal with this. One is to use an i64 polyfill like in this example (opens new window).

Other than that, portable code (JavaScript) does not have a concept of memory, so there are no load and store implementations in the portable standard library. Technically this can be polyfilled in various ways, but no default is provided since actual implementations are expected to be relatively specific (for instance: the portable compiler accesses Binaryen's memory).

+ + + diff --git a/concepts.html b/concepts.html new file mode 100644 index 000000000..cf1594676 --- /dev/null +++ b/concepts.html @@ -0,0 +1,195 @@ + + + + + + Concepts | The AssemblyScript Book + + + + + + + + + + + + + + + + + + +

# Concepts

An overview of basic AssemblyScript concepts.

# TypeScript-like

AssemblyScript is very similar to TypeScript with largely compatible syntax and semantics. As such, many of the concepts known from TypeScript apply to AssemblyScript as well, but not all TypeScript features map well to ahead of time compilation or WebAssembly's so far supported feature set. Some features have been omitted, others not yet implemented, and a few additional concepts needed to be added, technically making AssemblyScript part a subset, part a superset - a variant. As such it is unlikely that existing TypeScript code can be compiled by the AssemblyScript compiler, but likely that sufficiently strict code can be ported with little effort.

A detailed overview of supported TypeScript features is available within Implementation status.

# Strictly typed

While TypeScript has types, its type system is able to describe many of JavaScript's dynamic features. TypeScript is a superset / a type checker on top of JavaScript after all. On the contrary, AssemblyScript is compiled statically ahead of time, making it infeasible to support very dynamic JavaScript features to not enter interpreter territory, respectively requires stricter type checking to guarantee correctness at runtime where TypeScript would not complain.

As a result, there is no any or undefined:

// 😢
+function foo(a?) {
+  var b = a + 1
+  return b
+}
+
+// 😊
+function foo(a: i32 = 0): i32 {
+  var b = a + 1
+  return b
+}
+

There are no union types yet, but a similar effect can be achieved with generics:

// 😢
+function foo(a: i32 | string): void {
+}
+
+// 😊
+function foo<T>(a: T): void {
+}
+

Objects must be typed, say using a Map or class:

// 😢
+var a = {}
+a.prop = "hello world"
+
+// 😊
+var a = new Map<string,string>()
+a.set("prop", "hello world")
+
+// 😊
+class A {
+  constructor(public prop: string) {}
+}
+var a = new A("hello world")
+

And nullability checks are limited to locals to guarantee soundness where TypeScript would not (opens new window) diagnose (opens new window) a problem (opens new window):

function doSomething(foo: Foo): void {
+  // 😢
+  if (foo.something) {
+    foo.something.length // fails
+  }
+}
+
+function doSomething(foo: Foo): void {
+  // 😊
+  var something = foo.something
+  if (something) {
+    something.length // works
+  }
+}
+

# Sandboxed execution

One of WebAssembly's unique features is that a module cannot access external resources without explicitly importing them, providing strong security guarantees by default. As such, to do anything useful with WebAssembly, it is necessary to wire a module to the host environment, like for example JavaScript and the DOM.

# Module imports

In AssemblyScript, host functionality can be imported by utilizing the ambient context, that is using a declare statement:

// assembly/env.ts
+export declare function logInteger(i: i32): void
+
// assembly/index.ts
+import { logInteger } from "./env"
+
+logInteger(42)
+

Ambient declarations in an AssemblyScript file will yield a WebAssembly module import, using the internal path of the file, without file extension, as the module name (here: assembly/env), and the name of the declared element as the module element (here logInteger). In the example above, the import can be fulfilled by providing the following imports object upon instantiation:

WebAssembly.instantiateStreaming(fetch(...), {
+  "assembly/env": {
+    logInteger(i) { console.log("logInteger: " + i) }
+  }
+})
+

If necessary, the respective external module and element names can also be overridden using the @external decorator and modifying the imports object accordingly:

// assembly/index.ts
+@external("log", "integer")
+declare function logInteger(i: i32): void // { "log": { "integer"(i) { ... } } }
+
+logInteger(42)
+

# Module exports

Similarly, exports from an entry file will yield WebAssembly module exports:

// assembly/index.ts
+export function add(a: i32, b: i32): i32 {
+  return a + b
+}
+

Module exports can then be called from the host environment:

const { instance: { exports } } = await WebAssembly.instantiateStreaming(...)
+
+console.log(exports.add(1, 2))
+

See also: Host bindings automate much of the wiring.

# Special imports

Some language features need support from the host environment to function, yielding a few special module imports depending on the feature set used within the module. Generated bindings provide these automatically where necessary.

  • function env.abort?(message: usize, fileName: usize, line: u32, column: u32): void
    +

    Called on unrecoverable errors. Typically present if assertions are enabled or errors are thrown.

  • function env.trace?(message: usize, n: i32, a0..4?: f64): void
    +

    Called when trace is called in user code. Only present if it is.

  • function env.seed?(): f64
    +

    Called when the random number generator needs to be seeded. Only present if it is.

The respective implementations of abort, trace and seed can be overridden with, for example, --use abort=assembly/index/myAbort, here redirecting calls to abort to a custom myAbort function in assembly/index.ts. Useful if an environment does not provide compatible implementations, or when the respective imports are not desired and custom implementations are sufficient.

# Accessing memory during instantiation

One important edge case to be aware of is that top-level statements are executed as part of the WebAssembly module's implicit (start ...) function by default, which leads to a chicken and egg problem when top-level statements already call out to external functionality that needs to access the module's memory instance (say, reading the contents of a logged string). Since instantiation did not yet complete, the module's exports, including exported memory, are not available yet and the access will fail.

A solution is to utilize the --exportStart command line option to force exporting the start function instead of making it implicit. Then, instantiation first returns before any code is executed. Note, however, that the exported start function must always be called first, before any other exports, or undefined behavior will occur.

# Tree-shaking

AssemblyScript does not compile a module linearly, but starts at the module's exports and only compiles what's reachable from them, often referred to as tree-shaking (opens new window). As such, dead code is always validated syntactically, but not necessarily checked for semantic correctness. While this mechanism significantly helps to reduce compile times and feels almost natural to those familiar with executing JavaScript, it may initially feel a little strange not only to those with a background in traditional compilers, for example because emitted diagnostics do not happen linearly, but also to those with a background in TypeScript, because even type annotations remain unchecked as part of dead code. The exception to the rule is top-level code, including top-level variable declarations and their initializers, that must be evaluated as soon as the respective file would first execute.

# Branch-level tree-shaking

In addition to module-level tree-shaking, the compiler ignores branches that it can prove won't be taken. Works with constants, built-ins that compile to a constant, expressions that can be precomputed to a constant, plus the following globals to detect specific compiler flags or features:

  • const ASC_TARGET: i32
    +

    Indicates the compilation target. Possible values are 0 = JS (portable), 1 = WASM32, 2 = WASM64.

  • const ASC_NO_ASSERT: bool
    +

    Whether --noAssert has been set.

  • const ASC_MEMORY_BASE: usize
    +

    The value of --memoryBase.

  • const ASC_OPTIMIZE_LEVEL: i32
    +

    The value of --optimizeLevel. Possible values are 0, 1, 2 and 3.

  • const ASC_SHRINK_LEVEL: i32
    +

    The value of --shrinkLevel. Possible values are 0, 1 and 2.

  • const ASC_LOW_MEMORY_LIMIT: i32
    +

    The value of --lowMemoryLimit.

  • const ASC_EXPORT_RUNTIME: i32
    +

    Whether --exportRuntime has been set.

  • const ASC_FEATURE_SIGN_EXTENSION: bool
    +const ASC_FEATURE_MUTABLE_GLOBALS: bool
    +const ASC_FEATURE_NONTRAPPING_F2I: bool
    +const ASC_FEATURE_BULK_MEMORY: bool
    +const ASC_FEATURE_SIMD: bool
    +const ASC_FEATURE_THREADS: bool
    +const ASC_FEATURE_EXCEPTION_HANDLING: bool
    +const ASC_FEATURE_TAIL_CALLS: bool
    +const ASC_FEATURE_REFERENCE_TYPES: bool
    +const ASC_FEATURE_MULTI_VALUE: bool
    +const ASC_FEATURE_GC: bool
    +const ASC_FEATURE_MEMORY64: bool
    +

    Whether the respective feature is enabled.

    For example, if a library supports SIMD but also wants to provide a fallback when being compiled without SIMD support:

    if (ASC_FEATURE_SIMD) {
    +  // compute with SIMD operations
    +} else {
    +  // fallback without SIMD operations
    +}
    +

# Code annotations

Decorators work more like compiler annotations in AssemblyScript and are evaluated at compile time.

Annotation Description
@inline Requests inlining of a constant or function.
@final Annotates a class as final, that is it cannot be subclassed.
@unmanaged Annotates a class as not tracked by GC, effectively becoming a C-like struct.
@external Changes the external name of an imported element. @external(module, name) changes both the module and element name, @external(name) changes the element name only.

Custom decorators are ignored, unless given meaning by using a transform.

There are a few more built-in decorators that are likely going to change significantly over time, or may even be removed entirely. While useful for standard library implementation currently, it is not recommend to utilize them in custom code since tooling does not recognize them.

Show me anyway
Annotation Description
@global Registers an element to be part of the global scope.
@lazy Requests lazy compilation of a variable. Useful to avoid unnecessary globals.
@operator Annotates a method as a binary operator overload. See below.
@operator.binary Alias of @operator.
@operator.prefix Annotates a method as a unary prefix operator overload.
@operator.postfix Annotates a method as a unary postfix operator overload.

# Binary operator overloads

@operator(OP)
+static __op(left: T, right :T): T { ... }
+
+@operator(OP)
+__op(right: T): T  { ... }
+
OP Description
"[]" Checked indexed get
"[]=" Checked indexed set
"{}" Unchecked indexed get
"{}=" Unchecked indexed set
"==" Equality (also applies on ===)
"!=" Inequality (also applies on !==)
">" Greater than
">=" Greater than or equal
"<" Less than
"<=" Less than or equal
">>" Arithmetic right shift
">>>" Logical right shift
"<<" Left shift
"&" Bitwise AND
"|" Bitwise OR
"^" Bitwise XOR
"+" Addition
"-" Subtraction
"*" Multiplication
"/" Division
"**" Exponentiation
"%" Remainder

# Unary operator overloads

@operator.prefix(OP)
+static __op(self: T): T { ... }
+
+@operator.prefix(OP)
+__op(): T { ... }
+
OP Description Notes
"!" Logical NOT
"~" Bitwise NOT
"+" Unary plus
"-" Unary negation
"++" Prefix increment Instance overload reassigns
"--" Prefix decrement Instance overload reassigns

Note that increment and decrement overloads can have slightly different semantics. If the overload is declared as an instance method, on ++a the compiler does emit code that reassigns the resulting value to a while if the overload is declared static, the overload behaves like any other overload, skipping the otherwise implicit assignment.

# Unary postfix operations

@operator.postfix(OP)
+static __op(self: T): T { ... }
+
+@operator.postfix(OP)
+__op(): T { ... }
+
OP Description Notes
"++" Postfix increment Instance overload reassigns
"--" Postfix decrement Instance overload reassigns

Overloaded postfix operations do not preserve the original value automatically.

+ + + diff --git a/contributors.svg b/contributors.svg new file mode 100644 index 000000000..12218fb13 --- /dev/null +++ b/contributors.svg @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/debugging.html b/debugging.html new file mode 100644 index 000000000..599aa201a --- /dev/null +++ b/debugging.html @@ -0,0 +1,43 @@ + + + + + + +

+ Redirect after 3s +

+

+ Powered by vuepress-plugin-redirect +

+ + + \ No newline at end of file diff --git a/details/compiler/index.html b/details/compiler/index.html new file mode 100644 index 000000000..730f0111a --- /dev/null +++ b/details/compiler/index.html @@ -0,0 +1,43 @@ + + + + + + +

+ Redirect after 3s +

+

+ Powered by vuepress-plugin-redirect +

+ + + \ No newline at end of file diff --git a/details/debugging/index.html b/details/debugging/index.html new file mode 100644 index 000000000..5b337b0ee --- /dev/null +++ b/details/debugging/index.html @@ -0,0 +1,43 @@ + + + + + + +

+ Redirect after 3s +

+

+ Powered by vuepress-plugin-redirect +

+ + + \ No newline at end of file diff --git a/details/index.html b/details/index.html new file mode 100644 index 000000000..e5c4e737b --- /dev/null +++ b/details/index.html @@ -0,0 +1,43 @@ + + + + + + +

+ Redirect after 3s +

+

+ Powered by vuepress-plugin-redirect +

+ + + \ No newline at end of file diff --git a/details/interoperability/index.html b/details/interoperability/index.html new file mode 100644 index 000000000..41203d53f --- /dev/null +++ b/details/interoperability/index.html @@ -0,0 +1,43 @@ + + + + + + +

+ Redirect after 3s +

+

+ Powered by vuepress-plugin-redirect +

+ + + \ No newline at end of file diff --git a/details/memory/index.html b/details/memory/index.html new file mode 100644 index 000000000..e5c4e737b --- /dev/null +++ b/details/memory/index.html @@ -0,0 +1,43 @@ + + + + + + +

+ Redirect after 3s +

+

+ Powered by vuepress-plugin-redirect +

+ + + \ No newline at end of file diff --git a/details/peculiarities/index.html b/details/peculiarities/index.html new file mode 100644 index 000000000..f1179081a --- /dev/null +++ b/details/peculiarities/index.html @@ -0,0 +1,43 @@ + + + + + + +

+ Redirect after 3s +

+

+ Powered by vuepress-plugin-redirect +

+ + + \ No newline at end of file diff --git a/details/portability/index.html b/details/portability/index.html new file mode 100644 index 000000000..1c7a675d1 --- /dev/null +++ b/details/portability/index.html @@ -0,0 +1,43 @@ + + + + + + +

+ Redirect after 3s +

+

+ Powered by vuepress-plugin-redirect +

+ + + \ No newline at end of file diff --git a/details/runtime/index.html b/details/runtime/index.html new file mode 100644 index 000000000..465a15a03 --- /dev/null +++ b/details/runtime/index.html @@ -0,0 +1,43 @@ + + + + + + +

+ Redirect after 3s +

+

+ Powered by vuepress-plugin-redirect +

+ + + \ No newline at end of file diff --git a/details/transforms/index.html b/details/transforms/index.html new file mode 100644 index 000000000..079be629e --- /dev/null +++ b/details/transforms/index.html @@ -0,0 +1,43 @@ + + + + + + +

+ Redirect after 3s +

+

+ Powered by vuepress-plugin-redirect +

+ + + \ No newline at end of file diff --git a/detauls/development/index.html b/detauls/development/index.html new file mode 100644 index 000000000..3731b8d46 --- /dev/null +++ b/detauls/development/index.html @@ -0,0 +1,43 @@ + + + + + + +

+ Redirect after 3s +

+

+ Powered by vuepress-plugin-redirect +

+ + + \ No newline at end of file diff --git a/editor-test.html b/editor-test.html new file mode 100644 index 000000000..ca6ad1577 --- /dev/null +++ b/editor-test.html @@ -0,0 +1,121 @@ + + + + + + Editor Test | The AssemblyScript Book + + + + + + + + + + + + + + + + + + +

# Editor Test

Text before

#!runtime=stub
+// Editor A
+
+export function add(a: i32, b: i32): i32 {
+  return a + b
+}
+
+export function sub(a: i32, b: i32): i32 {
+  return a - b
+}
+
+#!html
+<script>
+loader.instantiate(module_wasm, { /* imports */ })
+  .then(({ exports }) => {
+    const output = document.getElementById('output')
+    output.value += `add(1, 2) = ${exports.add(1, 2)}\n`
+    output.value += `sub(1, 2) = ${exports.sub(1, 2)}\n`
+  })
+</script>
+
+<textarea id="output" style="height: 100%; width: 100%" readonly></textarea>
+

Text between

#!runtime=stub
+// Editor B
+
+export function sub(a: i32, b: i32): i32 {
+  return a - b
+}
+
+export function add(a: i32, b: i32): i32 {
+  return a + b
+}
+
+#!html
+<script>
+loader.instantiate(module_wasm, { /* imports */ })
+  .then(({ exports }) => {
+    const output = document.getElementById('output')
+    output.value += `sub(2, 3) = ${exports.sub(2, 3)}\n`
+    output.value += `add(2, 3) = ${exports.add(2, 3)}\n`
+  })
+</script>
+
+<textarea id="output" style="height: 100%; width: 100%" readonly></textarea>
+

Text after

+ + + diff --git a/editor.html b/editor.html new file mode 100644 index 000000000..71a1f31b7 --- /dev/null +++ b/editor.html @@ -0,0 +1,892 @@ + + + + AssemblyScript Editor + + + + + + + + + + + +
+
+ + ⚙️ +
+ + + +
+
+
+
+
+ +
+
+ + + + + + diff --git a/environment/index.html b/environment/index.html new file mode 100644 index 000000000..6db2bb3c4 --- /dev/null +++ b/environment/index.html @@ -0,0 +1,43 @@ + + + + + + +

+ Redirect after 3s +

+

+ Powered by vuepress-plugin-redirect +

+ + + \ No newline at end of file diff --git a/examples.html b/examples.html new file mode 100644 index 000000000..e0363c56e --- /dev/null +++ b/examples.html @@ -0,0 +1,81 @@ + + + + + + Examples | The AssemblyScript Book + + + + + + + + + + + + + + + + + + +

# Examples

A collection of AssemblyScript examples and snippets.

# Starter examples

Small entertaining programs showcasing low-level WebAssembly capabilities. These compile to less than one or just a few kilobytes so their text format is easy to grasp.

# Mandelbrot

Renders the Mandelbrot set to a canvas using 2048 discrete color values computed on the JS side.

easy

Preview image

# Interference

Animates and renders an interference pattern to a canvas while keeping the image buffer in WebAssembly.

easy

Preview image

# Game of Life

Continuously updates a cellular automaton and visualizes its state on a canvas according to user input.

intermediate

Preview image

# Advanced examples

# Arrays

Shows how to exchange and work with arrays using the loader.

intermediate

# Examples repository

Various more advanced examples are available as part of the examples repository (opens new window), including a sophisticated example of using the loader (opens new window), creating (node) libraries (opens new window), utilizing the browser SDK (opens new window) and hooking into the compiler using transforms (opens new window).

# Additional resources

If you are interested in learning more about specific concepts, also make sure to give Wasm By Example (opens new window) a read.

+ + + diff --git a/examples/arrays.html b/examples/arrays.html new file mode 100644 index 000000000..8e55c24f6 --- /dev/null +++ b/examples/arrays.html @@ -0,0 +1,193 @@ + + + + + + Arrays example | The AssemblyScript Book + + + + + + + + + + + + + + + + + + +

# Arrays example

Shows how to exchange and work with arrays either created in WebAssembly or in JavaScript.

# Contents

  • Using the loader and the full runtime to work with managed objects.
  • Creating arrays in WebAssembly and using them in JavaScript.
  • Creating arrays in JavaScript and using them in WebAssembly.
  • Using both copies of and live views on arrays.
  • Performing unchecked accesses where the length of an array is known.
  • Pinning objects externally to prevent premature garbage collection.

# Example

#!optimize=speed&runtime=default&exportRuntime
+/** Creates a new array and returns it to JavaScript. */
+export function createArray(length: i32): Int32Array {
+  return new Int32Array(length)
+}
+
+/** Randomizes the specified array's values. */
+export function randomizeArray(arr: Int32Array): void {
+  for (let i = 0, k = arr.length; i < k; ++i) {
+    let value = i32((Math.random() * 2.0 - 1.0) * i32.MAX_VALUE)
+    unchecked(arr[i] = value)
+  }
+}
+
+/** Computes the sum of an array's values and returns the sum to JavaScript. */
+export function sumArray(arr: Int32Array): i32 {
+  let total = 0
+  for (let i = 0, k = arr.length; i < k; ++i) {
+    total += unchecked(arr[i])
+  }
+  return total
+}
+
+// We'll need the unique Int32Array id when allocating one in JavaScript
+export const Int32Array_ID = idof<Int32Array>()
+
+#!html
+<textarea id="output" style="width: 100%; height: 100%" readonly></textarea>
+<script>
+loader.instantiate(module_wasm).then(({ exports }) => {
+  const output = document.getElementById('output')
+
+  /** Logs a message to the textarea. */
+  function log(message = '') {
+    output.value += `${message}\n`
+  }
+
+  // A simple example using an array created in WebAssembly.
+  function example1() {
+    log('=== Example1 ===')
+
+    // Obtain the necessary runtime helpers
+    const { __pin, __unpin, __getArray } = exports
+
+    // Create a new array in WebAssembly and get a reference to it. Note that
+    // the array is not reachable from within WebAssembly, only externally, so
+    // we should pin it to prevent it from becoming garbage collected too early.
+    let arrayPtr = __pin(exports.createArray(5))
+    log(`Array pointer: ${arrayPtr}`)
+
+    // Log its elements to make sure these are zero
+    log('Initial values: ' + __getArray(arrayPtr).join(', '))
+
+    // Randomize the array in WebAssembly and log it again
+    exports.randomizeArray(arrayPtr)
+    log('Randomized values: ' + __getArray(arrayPtr).join(', '))
+
+    // Compute the array values' sum and log it. This will overflow i32 range.
+    let total = exports.sumArray(arrayPtr)
+    log(`Sum (likely overflown): ${total}`)
+
+    // We are done with the array, so __unpin it so it can become collected.
+    __unpin(arrayPtr)
+
+    log()
+  }
+  example1()
+
+  // A slightly more advanced example allocating the array in JavaScript instead
+  // of WebAssembly, and utilizing a live view to modify it in WebAssembly memory.
+  function example2() {
+    log('=== Example2 ===')
+
+    // Obtain the necessary runtime helpers
+    const { __pin, __unpin, __newArray, __getArray, __getArrayView } = exports
+
+    // Create a new array, but this time in JavaScript. Note that the array is
+    // again not reachable from within WebAssembly, only externally, so we
+    // should pin it to prevent it from becoming garbage collected too early.
+    let arrayPtr = __pin(__newArray(exports.Int32Array_ID, [
+      3, 4, 5, 6, 7, 8, 9
+    ]))
+    log('Array pointer: ' + arrayPtr)
+
+    // Log its elements to make sure these are the provided values
+    log('Initial values: ' + __getArray(arrayPtr).join(', '))
+
+    // Compute the array values' sum and log it
+    let total = exports.sumArray(arrayPtr)
+    log('Sum: ' + total)
+
+    // Instead of copying, let's obtain a live view on the array and modify its
+    // values right in WebAssembly memory.
+    let view = __getArrayView(arrayPtr)
+    view.reverse()
+
+    // Log the array's elements, now reversed
+    log('Reversed values: ' + __getArray(arrayPtr).join(', '))
+
+    // We are done with the array, so __unpin it so it can become collected.
+    __unpin(arrayPtr)
+
+    log()
+  }
+  example2()
+})
+</script>
+

NOTE

This example utilizes the loader to work with managed objects, hence requires --exportRuntime to be set to expose the runtime helpers to JavaScript.

# Resources

Further information on using the loader and the runtime helpers is available as part of the loader's and the garbage collection documentation.

+ + + diff --git a/examples/game-of-life.html b/examples/game-of-life.html new file mode 100644 index 000000000..0d1021937 --- /dev/null +++ b/examples/game-of-life.html @@ -0,0 +1,273 @@ + + + + + + Game of Life example | The AssemblyScript Book + + + + + + + + + + + + + + + + + + +

# Game of Life example

Continuously updates a slightly modified variant of Conway's Game of Life (opens new window) and visualizes its state on a canvas.

# Contents

  • Exporting functions from a WebAssembly module.
  • Calling functions exported from WebAssembly.
  • Importing configuration values from JavaScript.
  • Instantiating the module's memory in JavaScript and import it using --importMemory.
  • Speeding up a program by forcing helper functions in a hot path to always @inline.
  • Utilizing JavaScript's Math instead of native libm to reduce module size via --use Math=JSMath.
  • Reacting to user input by directly modifying an input image buffer.
  • Finding out about WebAssembly's unintuitive byte order.
  • And finally: Continuously updating an input to an output image buffer and rendering the output image buffer.
  • Featuring: Clicking and drawing lots of stuff.

# Example

#!optimize=speed&runtime=stub&importMemory&use=Math=JSMath
+// Configuration imported from JS
+declare const BGR_ALIVE: u32;
+declare const BGR_DEAD: u32;
+declare const BIT_ROT: u32;
+
+var width: i32, height: i32, offset: i32;
+
+/** Gets an input pixel in the range [0, s]. */
+@inline
+function get(x: u32, y: u32): u32 {
+  return load<u32>((y * width + x) << 2);
+}
+
+/** Sets an output pixel in the range [s, 2*s]. */
+@inline
+function set(x: u32, y: u32, v: u32): void {
+  store<u32>((offset + y * width + x) << 2, v);
+}
+
+/** Sets an output pixel in the range [s, 2*s] while fading it out. */
+@inline
+function rot(x: u32, y: u32, v: u32): void {
+  var alpha = max<i32>((v >> 24) - BIT_ROT, 0);
+  set(x, y, (alpha << 24) | (v & 0x00ffffff));
+}
+
+/** Initializes width and height. Called once from JS. */
+export function init(w: i32, h: i32): void {
+  width  = w;
+  height = h;
+  offset = w * h;
+
+  // Start by filling output with random live cells.
+  for (let y = 0; y < h; ++y) {
+    for (let x = 0; x < w; ++x) {
+      let c = Math.random() > 0.1
+        ? BGR_DEAD  & 0x00ffffff
+        : BGR_ALIVE | 0xff000000;
+      set(x, y, c);
+    }
+  }
+}
+
+/** Performs one step. Called about 30 times a second from JS. */
+export function step(): void {
+  var w = width,
+      h = height;
+
+  var hm1 = h - 1, // h - 1
+      wm1 = w - 1; // w - 1
+
+  // The universe of the Game of Life is an infinite two-dimensional orthogonal grid of square
+  // "cells", each of which is in one of two possible states, alive or dead.
+  for (let y = 0; y < h; ++y) {
+    let ym1 = y == 0 ? hm1 : y - 1,
+        yp1 = y == hm1 ? 0 : y + 1;
+    for (let x = 0; x < w; ++x) {
+      let xm1 = x == 0 ? wm1 : x - 1,
+          xp1 = x == wm1 ? 0 : x + 1;
+
+      // Every cell interacts with its eight neighbours, which are the cells that are horizontally,
+      // vertically, or diagonally adjacent. Least significant bit indicates alive or dead.
+      let aliveNeighbors = (
+        (get(xm1, ym1) & 1) + (get(x, ym1) & 1) + (get(xp1, ym1) & 1) +
+        (get(xm1, y  ) & 1)                     + (get(xp1, y  ) & 1) +
+        (get(xm1, yp1) & 1) + (get(x, yp1) & 1) + (get(xp1, yp1) & 1)
+      );
+
+      let self = get(x, y);
+      if (self & 1) {
+        // A live cell with 2 or 3 live neighbors rots on to the next generation.
+        if ((aliveNeighbors & 0b1110) == 0b0010) rot(x, y, self);
+        // A live cell with fewer than 2 or more than 3 live neighbors dies.
+        else set(x, y, BGR_DEAD | 0xff000000);
+      } else {
+        // A dead cell with exactly 3 live neighbors becomes a live cell.
+        if (aliveNeighbors == 3) set(x, y, BGR_ALIVE | 0xff000000);
+        // A dead cell with fewer or more than 3 live neighbors just rots.
+        else rot(x, y, self);
+      }
+    }
+  }
+}
+
+/** Fills the row and column indicated by `x` and `y` with random live cells. */
+export function fill(x: u32, y: u32, p: f64): void {
+  for (let ix = 0; ix < width; ++ix) {
+    if (Math.random() < p) set(ix, y, BGR_ALIVE | 0xff000000);
+  }
+  for (let iy = 0; iy < height; ++iy) {
+    if (Math.random() < p) set(x, iy, BGR_ALIVE | 0xff000000);
+  }
+}
+
+#!html
+<canvas id="canvas" style="width: 100%; height: 100%; background: #000; cursor: crosshair"></canvas>
+<script type="module">
+// Configuration
+const RGB_ALIVE = 0xD392E6;
+const RGB_DEAD  = 0xA61B85;
+const BIT_ROT   = 10;
+
+// Set up the canvas with a 2D rendering context
+const canvas = document.getElementById("canvas");
+const boundingRect = canvas.getBoundingClientRect();
+const ctx = canvas.getContext("2d");
+
+// Compute the size of the universe (2 pixels per cell)
+const width = boundingRect.width >>> 1;
+const height = boundingRect.height >>> 1;
+const size = width * height;
+const byteSize = (size + size) << 2; // input & output (4 bytes per cell)
+
+canvas.width = width;
+canvas.height = height;
+canvas.style.imageRendering = "pixelated";
+ctx.imageSmoothingEnabled = false;
+
+// Compute the size of and instantiate the module's memory
+const memory = new WebAssembly.Memory({ initial: ((byteSize + 0xffff) & ~0xffff) >>> 16 });
+
+// Compile and instantiate the module
+const exports = await instantiate(await compile(), {
+  env: {
+    memory
+  },
+  module: {
+    BGR_ALIVE : rgb2bgr(RGB_ALIVE) | 1, // LSB set indicates alive
+    BGR_DEAD  : rgb2bgr(RGB_DEAD) & ~1, // LSB not set indicates dead
+    BIT_ROT
+  }
+});
+
+// Initialize the module with the universe's width and height
+exports.init(width, height);
+
+var buffer = new Uint32Array(memory.buffer);
+
+// Update about 30 times a second
+(function update() {
+  setTimeout(update, 1000 / 30);
+  buffer.copyWithin(0, size, size + size);   // copy output to input
+  exports.step();                            // perform the next step
+})();
+
+// Keep rendering the output at [size, 2*size]
+var imageData = ctx.createImageData(width, height);
+var argb = new Uint32Array(imageData.data.buffer);
+(function render() {
+  requestAnimationFrame(render);
+  argb.set(buffer.subarray(size, size + size)); // copy output to image buffer
+  ctx.putImageData(imageData, 0, 0);            // apply image buffer
+})();
+
+// When clicked or dragged, fill the current row and column with random live cells
+var down = false;
+[ [canvas, "mousedown"],
+  [canvas, "touchstart"]
+].forEach(eh => eh[0].addEventListener(eh[1], e => down = true));
+[ [document, "mouseup"],
+  [document, "touchend"]
+].forEach(eh => eh[0].addEventListener(eh[1], e => down = false));
+[ [canvas, "mousemove"],
+  [canvas, "touchmove"],
+  [canvas, "mousedown"]
+].forEach(eh => eh[0].addEventListener(eh[1], e => {
+  if (!down) return;
+  var loc;
+  if (e.touches) {
+    if (e.touches.length > 1) return;
+    loc = e.touches[0];
+  } else {
+    loc = e;
+  }
+  const currentBoundingRect = canvas.getBoundingClientRect();
+  exports.fill(
+    ((loc.clientX - currentBoundingRect.left) / currentBoundingRect.width * boundingRect.width) >>> 1,
+    ((loc.clientY - currentBoundingRect.top) / currentBoundingRect.height * boundingRect.height) >>> 1,
+    0.5
+  );
+}));
+
+/** Bitshifts an RGB color to BGR instead (WebAssembly is little endian). */
+function rgb2bgr(rgb) {
+  return ((rgb >>> 16) & 0xff) | (rgb & 0xff00) | (rgb & 0xff) << 16;
+}
+</script>
+

NOTE

The example makes a couple assumptions. For instance, using the entire memory of the program as the image buffer as in this example is only possible because we know that no interferring static memory segments will be created, which is achieved by

  • using JavaScript's Math instead of native libm (usually adds lookup tables),
  • not using a more sophisticated runtime (typically adds bookkeeping) and
  • the rest of the example being relatively simple (i.e. no strings or similar).

As soon as these conditions are no longer met, one would instead either reserve some space by specifying a suitable --memoryBase or export a dynamically instantiated chunk of memory, like an Uint32Array, and utilize it as the input and output image buffers both in WebAssembly and in JavaScript.

# Running locally

Instructions are identical to those of the Mandelbrot example.

+ + + diff --git a/examples/interference.html b/examples/interference.html new file mode 100644 index 000000000..025d0a8ec --- /dev/null +++ b/examples/interference.html @@ -0,0 +1,179 @@ + + + + + + Interference example | The AssemblyScript Book + + + + + + + + + + + + + + + + + + +

# Interference example

Colin Eberhardt's and Ben Smith's WebAssembly interference effect (opens new window), if it was written in AssemblyScript.

# Contents

  • Exporting functions and variables from a WebAssembly module.
  • Calling functions and reading variables exported from WebAssembly.
  • Utilizing 32-bit floating point math to speed up calculations by utilizing Mathf.
  • Keeping an image buffer within the module's memory and copying it to a canvas.
  • Manually growing memory depending on the size of the viewport on the browser side.
  • And finally: Continuously updating and rendering the image buffer.

# Example

EPILEPSY WARNING

A very small percentage of individuals may experience epileptic seizures when exposed to certain light patterns or flashing lights. Exposure to certain patterns or backgrounds on a computer screen may induce an epileptic seizure in these individuals. Certain conditions may induce previously undetected epileptic symptoms even in persons who have no history of prior seizures or epilepsy.

If you experience any of the following symptoms while viewing - dizziness, altered vision, eye or muscle twitches, loss of awareness, disorientation, any involuntary movement, or convulsions - IMMEDIATELY discontinue use and consult your physician.

#!optimize=speed&runtime=stub
+var width  = 320;
+var height = 200;
+
+// Let's utilize the entire heap as our image buffer
+export const offset = __heap_base;
+
+/** Sets a single pixel's color. */
+function set(x: i32, y: i32, v: f32): void {
+  var vi = <i32>v;
+  store<i32>(offset + ((width * y + x) << 2), ~vi << 24 | vi << 8);
+}
+
+/** Computes the distance between two pixels. */
+function distance(x1: i32, y1: i32, x2: f32, y2: f32): f32 {
+  var dx = <f32>x1 - x2;
+  var dy = <f32>y1 - y2;
+  return Mathf.sqrt(dx * dx + dy * dy);
+}
+
+/** Performs one tick. */
+export function update(tick: f32): void {
+  var w = <f32>width;
+  var h = <f32>height;
+  var hw = w * 0.5,
+      hh = h * 0.5;
+  var cx1 = (Mathf.sin(tick * 2) + Mathf.sin(tick      )) * hw * 0.3 + hw,
+      cy1 = (Mathf.cos(tick)                            ) * hh * 0.3 + hh,
+      cx2 = (Mathf.sin(tick * 4) + Mathf.sin(tick + 1.2)) * hw * 0.3 + hw,
+      cy2 = (Mathf.sin(tick * 3) + Mathf.cos(tick + 0.1)) * hh * 0.3 + hh;
+  var res = <f32>48 / Mathf.max(w, h);
+  var y = 0;
+  do {
+    let x = 0;
+    do {
+      set(x, y, Mathf.abs(
+        Mathf.sin(distance(x, y, cx1, cy1) * res) +
+        Mathf.sin(distance(x, y, cx2, cy2) * res)
+      ) * 120);
+    } while (++x != width)
+  } while (++y != height)
+}
+
+/** Recomputes and potentially grows memory on resize of the viewport. */
+export function resize(w: i32, h: i32): void {
+  width = w; height = h;
+  // Pages are 64kb. Rounds up using mask 0xffff before shifting to pages.
+  var needed = <i32>((offset + (w * h * sizeof<i32>() + 0xffff)) & ~0xffff) >>> 16;
+  var actual = memory.size();
+  if (needed > actual) memory.grow(needed - actual);
+}
+
+#!html
+<canvas id="canvas" style="width: 100%; height: 100%; background: #aff"></canvas>
+<script type="module">
+const exports = await instantiate(await compile());
+const canvas = document.getElementById("canvas");
+const context = canvas.getContext("2d");
+const step = 0.012;
+
+// Upscale the image to speed up calculations
+const upscaleFactor = 4;
+
+var width, height, image;
+
+// Inform the module about the viewport's size, incl. on resize
+function onresize() {
+  width = (canvas.offsetWidth / upscaleFactor) | 0;
+  height = (canvas.offsetHeight / upscaleFactor) | 0;
+  canvas.width = width;
+  canvas.height = height;
+  image = context.createImageData(width, height);
+  exports.resize(width, height);
+}
+onresize();
+new ResizeObserver(onresize).observe(canvas);
+
+// Keep updating the image
+var tick = 0.0;
+(function update() {
+  requestAnimationFrame(update);
+  exports.update(tick += step);
+  new Uint32Array(image.data.buffer).set(new Uint32Array(exports.memory.buffer, exports.offset.value, width * height));
+  context.putImageData(image, 0, 0);
+})();
+</script>
+

NOTE

The example makes one important assumption: Since we are not using a sophisticated runtime, we can instead repurpose the entire heap, starting at __heap_base, as our image buffer.

As soon as this condition is no longer met, one would instead either reserve some space by specifying a suitable --memoryBase or export a dynamically instantiated chunk of memory, like an Uint32Array, and utilize it as the image buffer both in WebAssembly and in JavaScript.

# Running locally

Set up a new AssemblyScript project as described in Getting started and copy module.ts to assembly/index.ts and index.html to the project's top-level directory. Edit the build commands in package.json to include

--runtime stub
+

The example can now be compiled with

npm run asbuild
+

To view the example, one can modify the instantiation in index.html from

loader.instantiate(module_wasm).then(({ exports }) => {
+

to

WebAssembly.instantiateStreaming(fetch('./build/optimized.wasm'), {
+  JSMath: Math
+}).then(({ exports }) => {
+

because using the loader is not ultimately necessary here (no managed objects are exchanged). If the loader is used instead, it will automatically provide JSMath.

Some browsers may restrict fetching local resources when just opening index.html now, but one can set up a local server as a workaround:

npm install --save-dev http-server
+http-server . -o -c-1
+
+ + + diff --git a/examples/mandelbrot.html b/examples/mandelbrot.html new file mode 100644 index 000000000..bdcdf7ae3 --- /dev/null +++ b/examples/mandelbrot.html @@ -0,0 +1,224 @@ + + + + + + Mandelbrot example | The AssemblyScript Book + + + + + + + + + + + + + + + + + + +

# Mandelbrot example

Renders the Mandelbrot set (opens new window) to a canvas using 2048 discrete color values computed on the JS side.

# Contents

  • Exporting functions from a WebAssembly module.
  • Calling functions exported from WebAssembly.
  • Instantiating the module's memory in JavaScript and import it using --importMemory.
  • Utilizing JavaScript's Math instead of native libm to reduce module size via --use Math=JSMath.
  • And finally: Reading and translating data from WebAssembly memory to colors rendered to a canvas.

# Example

#!optimize=speed&runtime=stub&importMemory&use=Math=JSMath
+/** Number of discrete color values on the JS side. */
+const NUM_COLORS = 2048;
+
+/** Updates the rectangle `width` x `height`. */
+export function update(width: u32, height: u32, limit: u32): void {
+  var translateX = width  * (1.0 / 1.6);
+  var translateY = height * (1.0 / 2.0);
+  var scale      = 10.0 / min(3 * width, 4 * height);
+  var realOffset = translateX * scale;
+  var invLimit   = 1.0 / limit;
+
+  var minIterations = min(8, limit);
+
+  for (let y: u32 = 0; y < height; ++y) {
+    let imaginary = (y - translateY) * scale;
+    let yOffset   = (y * width) << 1;
+
+    for (let x: u32 = 0; x < width; ++x) {
+      let real = x * scale - realOffset;
+
+      // Iterate until either the escape radius or iteration limit is exceeded
+      let ix = 0.0, iy = 0.0, ixSq: f64, iySq: f64;
+      let iteration: u32 = 0;
+      while ((ixSq = ix * ix) + (iySq = iy * iy) <= 4.0) {
+        iy = 2.0 * ix * iy + imaginary;
+        ix = ixSq - iySq + real;
+        if (iteration >= limit) break;
+        ++iteration;
+      }
+
+      // Do a few extra iterations for quick escapes to reduce error margin
+      while (iteration < minIterations) {
+        let ixNew = ix * ix - iy * iy + real;
+        iy = 2.0 * ix * iy + imaginary;
+        ix = ixNew;
+        ++iteration;
+      }
+
+      // Iteration count is a discrete value in the range [0, limit] here, but we'd like it to be
+      // normalized in the range [0, 2047] so it maps to the gradient computed in JS.
+      // see also: http://linas.org/art-gallery/escape/escape.html
+      let colorIndex = NUM_COLORS - 1;
+      let distanceSq = ix * ix + iy * iy;
+      if (distanceSq > 1.0) {
+        let fraction = Math.log2(0.5 * Math.log(distanceSq));
+        colorIndex = <u32>((NUM_COLORS - 1) * clamp<f64>((iteration + 1 - fraction) * invLimit, 0.0, 1.0));
+      }
+      store<u16>(yOffset + (x << 1), colorIndex);
+    }
+  }
+}
+
+/** Clamps a value between the given minimum and maximum. */
+function clamp<T>(value: T, minValue: T, maxValue: T): T {
+  return min(max(value, minValue), maxValue);
+}
+
+#!html
+<canvas id="canvas" style="width: 100%; height: 100%"></canvas>
+<script type="module">
+
+// Set up the canvas with a 2D rendering context
+const canvas = document.getElementById("canvas");
+const boundingRect = canvas.getBoundingClientRect();
+const ctx = canvas.getContext("2d");
+
+// Compute the size of the viewport
+const ratio  = window.devicePixelRatio || 1;
+const width  = (boundingRect.width  | 0) * ratio;
+const height = (boundingRect.height | 0) * ratio;
+const size = width * height;
+const byteSize = size << 1; // discrete color indices in range [0, 2047] (2 bytes per pixel)
+
+canvas.width  = width;
+canvas.height = height;
+
+ctx.scale(ratio, ratio);
+
+// Compute the size (in pages) of and instantiate the module's memory.
+// Pages are 64kb. Rounds up using mask 0xffff before shifting to pages.
+const memory = new WebAssembly.Memory({ initial: ((byteSize + 0xffff) & ~0xffff) >>> 16 });
+const buffer = new Uint16Array(memory.buffer);
+const imageData = ctx.createImageData(width, height);
+const argb = new Uint32Array(imageData.data.buffer);
+const colors = computeColors();
+
+const exports = await instantiate(await compile(), {
+  env: {
+    memory
+  }
+})
+
+// Update state
+exports.update(width, height, 40);
+
+// Translate 16-bit color indices to colors
+for (let y = 0; y < height; ++y) {
+  const yx = y * width;
+  for (let x = 0; x < width; ++x) {
+    argb[yx + x] = colors[buffer[yx + x]];
+  }
+}
+
+// Render the image buffer.
+ctx.putImageData(imageData, 0, 0);
+
+/** Computes a nice set of colors using a gradient. */
+function computeColors() {
+  const canvas = document.createElement("canvas");
+  canvas.width = 2048;
+  canvas.height = 1;
+  const ctx = canvas.getContext("2d");
+  const grd = ctx.createLinearGradient(0, 0, 2048, 0);
+  grd.addColorStop(0.00, "#000764");
+  grd.addColorStop(0.16, "#2068CB");
+  grd.addColorStop(0.42, "#EDFFFF");
+  grd.addColorStop(0.6425, "#FFAA00");
+  grd.addColorStop(0.8575, "#000200");
+  ctx.fillStyle = grd;
+  ctx.fillRect(0, 0, 2048, 1);
+  return new Uint32Array(ctx.getImageData(0, 0, 2048, 1).data.buffer);
+}
+</script>
+

NOTE

The example makes a couple assumptions. For instance, using the entire memory of the program as the image buffer as in this example is only possible because we know that no interferring static memory segments will be created, which is achieved by

  • using JavaScript's Math instead of native libm (usually adds lookup tables),
  • not using a more sophisticated runtime (typically adds bookkeeping) and
  • the rest of the example being relatively simple (i.e. no strings or similar).

As soon as these conditions are no longer met, one would instead either reserve some space by specifying a suitable --memoryBase or export a dynamically instantiated chunk of memory, like an Uint16Array, and utilize it as the color index buffer both in WebAssembly and in JavaScript.

# Running locally

Set up a new AssemblyScript project as described in Getting started and copy module.ts to assembly/index.ts and index.html to the project's top-level directory. Edit the build commands in package.json to include

--runtime stub --use Math=JSMath --importMemory
+

The example can now be compiled with

npm run asbuild
+

To view the example, one can modify the instantiation in index.html from

loader.instantiate(module_wasm, {
+  env: {
+    memory
+  }
+}).then(({ exports }) => {
+

to

WebAssembly.instantiateStreaming(fetch('./build/optimized.wasm'), {
+  env: {
+    memory
+  },
+  Math
+}).then(({ exports }) => {
+

because using the loader is not ultimately necessary here (no managed objects are exchanged). If the loader is used instead, it will automatically provide JavaScript's Math.

Some browsers may restrict fetching local resources when just opening index.html now, but one can set up a local server as a workaround:

npm install --save-dev http-server
+http-server . -o -c-1
+
+ + + diff --git a/examples/snippets.html b/examples/snippets.html new file mode 100644 index 000000000..ad50b64bd --- /dev/null +++ b/examples/snippets.html @@ -0,0 +1,332 @@ + + + + + + Snippets | The AssemblyScript Book + + + + + + + + + + + + + + + + + + +

# Snippets

Small, copy-pastable AssemblyScript examples using common syntax and patterns.

# Class

An AssemblyScript snippet on using Classes, their instantiation, and their static properties.

#!runtime=stub
+class Animal<T> {
+  static ONE: i32 = 1;
+  static add(a: i32, b: i32): i32 { return a + b + Animal.ONE; }
+
+  two: i16 = 2; // 6
+  instanceSub<T>(a: T, b: T): T { return a - b + <T>Animal.ONE; } // tsc does not allow this
+}
+
+export function staticOne(): i32 {
+  return Animal.ONE;
+}
+
+export function staticAdd(a: i32, b: i32): i32 {
+  return Animal.add(a, b);
+}
+
+export function instanceTwo(): i32 {
+  let animal = new Animal<i32>();
+  return animal.two;
+}
+
+export function instanceSub(a: f32, b: f32): f32 {
+  let animal = new Animal<f32>();
+  return animal.instanceSub<f32>(a, b);
+}
+
+
+#!html
+<script type="module">
+const log = console.log;
+console.log = (...args) => {
+  log(...args);
+  let str = '';
+  args.forEach(arg => {
+    if (typeof arg == 'object') {
+      str += `${JSON.stringify(arg, null, 2)}<br/>`;
+    } else {
+      str += `${arg}<br/>`;
+    }
+  });
+  document.body.innerHTML += `<div>Log: ${str}</div>`;
+}
+
+const exports = await instantiate(await compile(), { /* imports */ });
+
+console.log(exports.staticOne());
+console.log(exports.staticAdd(1, 2));
+console.log(exports.instanceTwo());
+console.log(exports.instanceSub(3.0, 1.0));
+</script>
+

# Extending Classes

Extending classes and general Object Orientated Programming (OOP) in AssemblyScript

#!runtime=stub
+
+class BaseClass {
+  static staticProp: i32 = 24;
+  instanceProp: i32;
+
+  constructor(value: i32) {
+    this.instanceProp = value;
+  }
+
+  add(a: i32, b: i32): i32 {
+    return a + b;
+  }
+}
+
+class ExtendedClass extends BaseClass {
+
+  extendedProp: i32;
+
+  constructor(extendedValue: i32) {
+    super(1);
+
+    this.extendedProp = extendedValue;
+  }
+
+  add(a: i32): i32 {
+    return super.add(a, this.extendedProp + super.instanceProp);
+  }
+}
+
+export function getStaticProp(): i32 {
+  return ExtendedClass.staticProp;
+}
+
+export function overloadAdd(value: i32): i32 {
+  let extendedClass = new ExtendedClass(value);
+  return extendedClass.add(24);
+}
+
+#!html
+<script type="module">
+const log = console.log;
+console.log = (...args) => {
+  log(...args);
+  let str = '';
+  args.forEach(arg => {
+    if (typeof arg === 'object') {
+      str += `${JSON.stringify(arg, null, 2)}<br/>`;
+    } else {
+      str += `${arg}<br/>`;
+    }
+  });
+  document.body.innerHTML += `<div>Log: ${str}</div>`;
+}
+
+const exports = await instantiate(await compile(), { /* imports */ });
+
+console.log(`getStaticProp: ${exports.getStaticProp()}`);
+console.log(`overloadAdd: ${exports.overloadAdd(24)}`);
+</script>
+

# Handling Null

Handling Null as a union type for optional return values and simulating try/catch for errors in AssemblyScript

#!runtime=stub
+class MyValue {
+  value: i32;
+
+  constructor(value: i32) {
+    this.value = value;
+  }
+}
+
+// Using a class type here, as some types are not nullable
+function getMyValue(isAble: boolean): MyValue | null {
+  let myValue = new MyValue(24);
+  if (isAble) {
+    return myValue;
+  } else {
+    return null;
+  }
+}
+
+export function positiveAddWithMyValue(a: i32): i32 {
+  let myValue = getMyValue(a > 0);
+  if (myValue == null) {
+    return -1;
+  } else {
+    return a + myValue.value;
+  }
+}
+
+#!html
+<script type="module">
+const log = console.log;
+console.log = (...args) => {
+  log(...args);
+  let str = '';
+  args.forEach(arg => {
+    if (typeof arg == 'object') {
+      str += `${JSON.stringify(arg, null, 2)}<br/>`;
+    } else {
+      str += `${arg}<br/>`;
+    }
+  });
+  document.body.innerHTML += `<div>Log: ${str}</div>`;
+}
+
+const exports = await instantiate(await compile(), { /* imports */ });
+
+if (exports.positiveAddWithMyValue(24) > -1) {
+  console.log("Add was successful")
+} else {
+  console.log("Could not add 24");
+}
+
+if (exports.positiveAddWithMyValue(-1) > -1) {
+  console.log("Add was successful")
+} else {
+  console.log("Could not add -1");
+}
+</script>
+

# Switch Case

Using switch case statements in AssemblyScript.

NOTE

Currently, the switch conditions (case values) are implicitly converted to u32, i.e. switching over strings or similar is not yet supported.

#!runtime=stub
+export function switchSurprise(a: i32): i32 {
+  let response = -1;
+
+  // Using a mix of braces and not using braces
+  // to show that both syntaxes are supported here.
+  switch (a) {
+    case 1:
+      response = 100;
+      break;
+    case 2: {   // Cases can also use braces
+      response = 200;
+      break;
+    }
+    case 3:
+      // Fall Through to the next case
+    case 4:
+      response = 400;
+      break;
+    default: {
+      response = 0;
+    }
+  }
+
+  return response;
+}
+
+#!html
+<script type="module">
+const log = console.log;
+console.log = (...args) => {
+  log(...args);
+  let str = '';
+  args.forEach(arg => {
+    if (typeof arg == 'object') {
+      str += `${JSON.stringify(arg, null, 2)}<br/>`;
+    } else {
+      str += `${arg}<br/>`;
+    }
+  });
+  document.body.innerHTML += `<div>Log: ${str}</div>`;
+}
+
+const exports = await instantiate(await compile(), { /* imports */ });
+
+console.log(`switchSurprise(1) : ${exports.switchSurprise(1)}`);
+console.log(`switchSurprise(2) : ${exports.switchSurprise(2)}`);
+console.log(`switchSurprise(3) : ${exports.switchSurprise(3)}`);
+console.log(`switchSurprise(4) : ${exports.switchSurprise(4)}`);
+console.log(`switchSurprise(57) : ${exports.switchSurprise(57)}`);
+</script>
+

# Ternary if-else

Using Ternary if-else in AssemblyScript

#!runtime=stub
+export function isTrue(a: i32): i32 {
+  let response = a > 0 ? 1 : 0;
+  return response;
+}
+
+#!html
+<script type="module">
+const log = console.log;
+console.log = (...args) => {
+  log(...args);
+  let str = '';
+  args.forEach(arg => {
+    if (typeof arg == 'object') {
+      str += `${JSON.stringify(arg, null, 2)}<br/>`;
+    } else {
+      str += `${arg}<br/>`;
+    }
+  });
+  document.body.innerHTML += `<div>Log: ${str}</div>`;
+}
+
+const exports = await instantiate(await compile(), { /* imports */ });
+
+console.log(`is 24 greater than 0? ${exports.isTrue(24) > 0 ? true : false}`);
+console.log(`is -3 greater than 0? ${exports.isTrue(-3) > 0 ? true : false}`);
+</script>
+
+ + + diff --git a/exports-and-imports.html b/exports-and-imports.html new file mode 100644 index 000000000..21486244e --- /dev/null +++ b/exports-and-imports.html @@ -0,0 +1,43 @@ + + + + + + +

+ Redirect after 3s +

+

+ Powered by vuepress-plugin-redirect +

+ + + \ No newline at end of file diff --git a/extended-library/staticarray/index.html b/extended-library/staticarray/index.html new file mode 100644 index 000000000..6f6799870 --- /dev/null +++ b/extended-library/staticarray/index.html @@ -0,0 +1,43 @@ + + + + + + +

+ Redirect after 3s +

+

+ Powered by vuepress-plugin-redirect +

+ + + \ No newline at end of file diff --git a/faq/index.html b/faq/index.html new file mode 100644 index 000000000..bbcee9e3c --- /dev/null +++ b/faq/index.html @@ -0,0 +1,43 @@ + + + + + + +

+ Redirect after 3s +

+

+ Powered by vuepress-plugin-redirect +

+ + + \ No newline at end of file diff --git a/favicon.ico b/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..f8c8aae06e6acb51aa6a19c58aca194aae9ff958 GIT binary patch literal 15086 zcmeI3OK4qH6oyZ2p$ej%D2_CULWe~}hdw3_>O==ZM|C1PbW+qpeGCjDq97_r@PR0b zia4;~1ED?!Vw-BMwy`CT(uNXJ(%3dlVp6yJTlcKXy6c{OALrg%l5#ez?z8t(w#1qDPi)Gv;i#}R>O_<5(J1W8 zxUDwXe-G@=LM0Uk(gV*#9#qyzU+jN63&_Fet_g>RZ>kGxa^hW2{T=xj|LEax_VA~5 zIra5Z60e2hhy(OP>V%fO4Nin z#8_FF4LW#ck9V!a+hGrWY~UJv*01`v^M9*LqKCfpR*4+o5f1H8Zr~>+=-9D5evnoNE1Sh@2Mdyg7)%bDV0)}EuM zz-R|O4>oE;e$1R3p9k^vTz7jGr~xs`4mj7?lI+e7%n79VyH z1Fo$2{s1RuL~!MIBDv6$>=&I&bn$5ibt{dZb02fy{;)&u6XK%UR?bpPT_| zS%e$xdj2KPlDLV3Jv|GrIh*AOz27ox;&6vpEcCF& z(&RVqAA43bXRva&F~bYKxSQoO#sKhxjd=F+j{YoY!tLT0)s396_qoB3+@S+F6VyO| zH-InVXdk3<(7F|!9X&&KMvpoV#4~)mUjzrm&3(xGWhtEu4ZTd?E_M-4^ zE$0BfYwh1x*k|6Y;T-6XCf+T6p3#Z27JF&LV@<8sXbpCy@cR9TpL5-pbKref>s}ey z@O;g~=Be6z{d{e{WvOw#XO%U7r!^Gi-YE6I(~5t~<(nXr1lzj%Y-MW6j+@7y28KYU1L);>n7^~t?YhSkNhB9ou( z6u&kfp7FUj^Oxu_E0!|{-VH0~Plrn@7x|AzGB3|fgqfdT4Pa~)mv{IkcYH7wPVEoV z-|cA<;^3dbGx>s})c`{)J}ox!-^yA34xWf@^}!5>a7RpZ7|i6>t|xepPql+fI8@Pn zeEu`GS8{@XVzK5K9~y@}8Idn~LicUH{u!Rsj=12ae)!gXaCv{W#>7D%KDv#ME&NH1 zBW~?O+Z*8U_0-&mOAYF=BLMPX-{+cIlZ)DGEP7FMQB2kz8+4=>^ZrC1uE1k;+dY#D zHVkSG*NTVPa*Z!r8!_Uahyg5M^<1@!uRh_80SDT9;8L#D5B*mkF)kR<1E<$jn@;As z-<;2)Iub+AzjCc{dx?!LJ*Rn-A9y@&xYs)i92%P$`!d{X40{%dfj^&<%^$4ruJ;ma zFr%YByP1ha@6k)#b17Rn8+nb;r4Bk$xKqCTKG^9$a`L&WE;{6?b&%K*2lW8I>Xn_T zal1P5p89a!5aO2Qy(~`nu~ODgW!InIM=BmG9;+VcTMx`eE?-m1~z{gx3 z^D6thY`(|4L1W;%xQ5u^U@yw$_#SbG&D%c5_|&7T{H^_EdFE@3%~LgrUt#b)1z$@H zMX7&J5&vH^KYU*P^M|f=M&CZG{pg-e;l!7Zhsn=(2A+{a!#9TMZ+C~|A3PZT9=T6G zznmF;U-W)^;kpJs@rmxrg_&^f_%|Zwr+$((`^$5a;ljyZWdG8?7sZFi@yE+Iiyn6J zStKk@M+f`{kD*`om*irvoG5g)u@!HziKB{wh-pJyMR^^rI46#rmAu!9Ty zV#gjn*|Tx=nSHR?95pZY;S^DQKZ60j!HJz>CoXxz2l=(~0cP^IzR8RDNGtr-CiU!j uOX*z!`%5tgq=Cy0*FQ$R?YZph&_?4BbGx4P+(#h})#-NTy4kod%l-!d;`gfn literal 0 HcmV?d00001 diff --git a/favicons/android-chrome-192x192.png b/favicons/android-chrome-192x192.png new file mode 100644 index 0000000000000000000000000000000000000000..844437c35a59bc8ad53ac005aa1c3bd6c78bbcce GIT binary patch literal 2150 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 literal 0 HcmV?d00001 diff --git a/favicons/favicon-16x16.png b/favicons/favicon-16x16.png new file mode 100644 index 0000000000000000000000000000000000000000..f55d6900827c5ff686c454b6692c77844af690cc GIT binary patch literal 441 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJOS+@4BLl<6e(pbstUx|vage(c z!@6@aFM*u!0G|+7hU&8nRcC=DW8HZW8;pE13n2{d){A0YmxGqwJM!>z;<|^s?tGei z_U)@Lzx$8A`u6K@-j>I9b8g*u^Zmj5pC_MuS$^rA!L;jJZ+@uX`%M2YM+?vju96_X z;2;10|37rVn<2n0PzP_*6C#W6(Ua&O;jzGefCR_~jOE?t_v?b_+z_RqU|({8Sx z%Tn~?kfMfe&|`z1Rkv5azHYMjtNDdjhQHkFnP0G)FSyfYnQ*W0nBeF>>K0t$<&kcg6?#Bzm#qWrYXoK%I9%7Rpd%z~0+28N0`k3aEn6ozSN zobo??#`9?q1G6%>UNX0^vat7L5oTcpmj;u=Da^{7LljQmxN_pinIkes*iScjEb!7} YcqJ}a^2y0`D$oiBPgg&ebxsLQ0G(jFO#lD@ literal 0 HcmV?d00001 diff --git a/favicons/favicon-32x32.png b/favicons/favicon-32x32.png new file mode 100644 index 0000000000000000000000000000000000000000..0fa8b29855cc487f158aa267a58ab852b16455ea GIT binary patch literal 587 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabR7dyEa{HEjtmSN`?>!lvI6;x#X;^) z4C~IxyaaN>1AIbUeKHFfs?Xv=|NsAIs5~Rvd*#>Pe|l4|vo&3CTX5&qm){?M{H@>n zT%i5Z_FEtGw?2tnb^qF{?+eboop9{c{r5l5JpFp>r@uDP3a*kMzhH*`DgT*fGrkQ; zeCkzu9_R>3PZ!4!i_>o>Wj8e|@U-0B8k_6HFmd{Uzvp)ft`5!q&SJe^>1WU6iOcT3 zyclBpE&c4jhjp`mZ~yJS;PuQOFL(Dl+^+rp_xi$mCcQ8Ge>fFhGYMp^P5E$ZALFT) zPfe$?F?2m-S+Fc~rCXlx0fmniiBWw~(g!PSc~8ozEqJnXWt60XR>-F}ij0n8uUWpv zJZA0SIoEK!i%B&9Bf|pr#oSYV?moo$dP}SBgDV^&tIisJ5%C*a&oh8J{u}LS_xlQK=@^kG7{|<((A^l1%qy zncU}Zw%4c1xaFt#;tn+~OJ0{L$78QJd3{~ALDVXv(4%Ote0FJV;<_)~3!h5mt_iLD z3W}Yokcg6?#Bzm#qWrYXoK%I9%7Rpd%z~0+28N0`k3aEn6ozSNobo??#`9?q1G6%> zUNX0^vat7L5oTcpmj;u=Da^{7LljQmxN_pinIkes*iScjEb!7}cqJ}a^2y0`D$oiB MPgg&ebxsLQ0F-?LYybcN literal 0 HcmV?d00001 diff --git a/favicons/mstile-150x150.png b/favicons/mstile-150x150.png new file mode 100644 index 0000000000000000000000000000000000000000..4498497679dfc6f72edfaacbd2b939cc87cf1269 GIT binary patch literal 1370 zcmeAS@N?(olHy`uVBq!ia0y~yVB`Z~7G|JG*Ze2bfD}u*qpu?a!^VE@KZ&eBK4Wo^ zyA#8@b22Z19IXJK5LchfLWb(IaPAlufF_Vc>b+)&lUT*w~s&i61V0--QMS1 zlGA^Kj4TQA3ufp(>FQML{TRrN_H=O!skrramao6Cqr~y6{s~w37hL35cp)xeKAH7& z;iY4jZl_H)dt0ddsVJK{W5-0L3fGJa%Dop)^iB)U-{Qh^|LEPhH}B4TYgREcUH||6 z&K$Fw@oCR~o;MDDcZU&ZAu>=%Ut@UZ`n_G&?@TKMs%@^_+ckam@$9#2r|+!XbLn2y zl-b9pe7m;!j?I=ut86Ph@Jv99K=USHH$Byt5OQx=G z7n!-?)3*)tY-$WY9yoRXaoGb#{)z+4avvJlZ7`XZl?LjM7fL^vP<7@_+KSx&`*vF1 zF5tAi@$BG<#jj3UzuR1Kmcy2f`(@|Ke@~kpvAaEcSmOOs{khGeAIBGdTJd?&K8G7? z#H&9P%|3Pb*`Ag5k_D~ue7)?qAOG3A&EeI&SAzT;31O_HVT~K4*Ga#;dS3Y^o=ZFnnCtvqO22&DO7vdTf?NWS?DnGk(zq zk8M_B%Q6kuq-^uudf#Z~Lsjk5hm~I2uZrEdep~SC#s0U&uPxppwajJ~-_mv-?$YR~ zrO}B?e3El#=|_+@xXbySBmK1@PnVs#zMx%KZHbha&!sJ^nJ39CIaAs3qULqSIg89&H`V*U-MJvtsi)ZBjfY>w3MEM{Gpv+?Tci;RZPFLspGTwJ8>Yu)Yt$McZnXMw{3U9&@$W`1`) zxA%%z#<|7n(^tl5sQz_Z@%SaXX0lw8GH06e>t1))Uum{kAMLcovtIo=*m-Ju=C#9q zQkUIUWlmR$Z*BLm2$oYi>gB~6?v}Q0=?_Wi{zfA<-MyLD%V$|GmP_K9^{{pA?&W50 z^H$AWFY#62zQrESok2=-M6b!@YD$0g=;Psh$g*K(-chA5FM6w3I*%?3uQ0romBsS; zlGIm@Ln?P3EwVPe{m05TzS*@?H1Fr9TZe6*6@HohX@jxJAFXNq&&`{(v?`7j>(qKn z#oC)ZiT}JjI{N;uXT@`QH`#Q(eIl~;$K0g(!PSYa-j#RG?{F}E9C-f9hv`m{Kjmds;(%yN^ZJXn_ zHZKB7hF66|lmsP~D-;yvr)B1(DwI?fq$*?3oE!Zm>f=FR^A+ \ No newline at end of file diff --git a/frequently-asked-questions.html b/frequently-asked-questions.html new file mode 100644 index 000000000..21cfe0be4 --- /dev/null +++ b/frequently-asked-questions.html @@ -0,0 +1,77 @@ + + + + + + Frequently asked questions | The AssemblyScript Book + + + + + + + + + + + + + + + + + + +

# Frequently asked questions

Questions that may arise before, at or after this point. so if you're wondering about one thing or another, here it is:

# Is WebAssembly faster than JavaScript?

Not always, but it can be. The execution characteristics of ahead-of-time compiled WebAssembly differ from just-in-time compiled JavaScript in that it is more predictable in a way that enables a WebAssembly program to remain on a reasonably fast path over the entire course of execution, while a JavaScript VM tries hard to do all sorts of smart optimizations before and while the code is executing. This implies that a JavaScript VM can make both very smart decisions, especially for well-written code with a clear intent, but might also have to reconsider its strategy to do something more general if its assumptions did not hold. If you are primarily interested in performance, rules of thumb could be:

Scenario Recommendation
Compute-heavy algorithm Use WebAssembly
Mostly interacts with the DOM Mostly use JavaScript
Games Use WebAssembly for CPU-intensive parts
WebGL Depends how much of it is calling APIs. Probably both.
Websites, Blogs, ... JavaScript is your friend

Or: WebAssembly is great for computational tasks, stuff with numbers, but still needs some time to become more convenient and efficient at the same time where sharing numbers between the module and the host is not enough.

# Is AssemblyScript faster than JavaScript?

Not always, but there are use cases especially well-suited for it, like creating a Game Boy emulator by making use of its low-level capabilities, essentially emitting raw WebAssembly using a nicer syntax. But pre-existing TypeScript code doesn't magically become faster just by compiling to WebAssembly, especially when making extensive use of managed objects that require memory management and garbage collection (this has its cost in every language) or talking to the host in structures that WebAssembly isn't currently good at, like strings or more complex objects. Low-level code (just functions, numbers, math and hard work) is always the best choice when all you care about is raw performance.

# Will AssemblyScript support all of TypeScript eventually?

It very likely won't. While TypeScript adds some static typing to JavaScript, its type system also tries to describe any possible dynamic feature of JavaScript. TypeScript is a superset of JavaScript after all. As such there is a point where it becomes infeasible to support JavaScript features that TypeScript can describe without adding an interpreter mode to AssemblyScript, which is a non-goal.

# How can I help?

There are various ways to help. AssemblyScript is an open source project, and everyone is welcome to contribute code (opens new window), documentation (opens new window), or time. We also have an OpenCollective (opens new window) for those preferring to help the project out with a sponsorship.

+ + + diff --git a/garbage-collection.html b/garbage-collection.html new file mode 100644 index 000000000..47c4e7b80 --- /dev/null +++ b/garbage-collection.html @@ -0,0 +1,43 @@ + + + + + + +

+ Redirect after 3s +

+

+ Powered by vuepress-plugin-redirect +

+ + + \ No newline at end of file diff --git a/getting-started.html b/getting-started.html new file mode 100644 index 000000000..d35db34bb --- /dev/null +++ b/getting-started.html @@ -0,0 +1,135 @@ + + + + + + Getting started | The AssemblyScript Book + + + + + + + + + + + + + + + + + + +

# Getting started

Paving the way to your first AssemblyScript module.

# Setting up a new project

Make sure that a recent version of Node.js (opens new window) and its package manager npm (that comes with Node.js) are installed, then switch to a new directory and initialize a new Node.js module as usual:

npm init
+

Install the AssemblyScript compiler. Let's assume that it is not required in production and make it a development dependency:

npm install --save-dev assemblyscript
+

Once installed, the compiler provides a handy scaffolding utility to quickly set up a new project, here in the current directory:

npx asinit .
+

The asinit command automatically creates the recommended directory structure and configuration files:

  ./assembly
+  Directory holding the AssemblyScript sources being compiled to WebAssembly.
+
+  ./assembly/tsconfig.json
+  TypeScript configuration inheriting recommended AssemblyScript settings.
+
+  ./assembly/index.ts
+  Example entry file being compiled to WebAssembly to get you started.
+
+  ./build
+  Build artifact directory where compiled WebAssembly files are stored.
+
+  ./build/.gitignore
+  Git configuration that excludes compiled binaries from source control.
+
+  ./asconfig.json
+  Configuration file defining both a 'debug' and a 'release' target.
+
+  ./package.json
+  Package info containing the necessary commands to compile to WebAssembly.
+
+  ./tests/index.js
+  Starter test to check that the module is functioning.
+
+  ./index.html
+  Starter HTML file that loads the module in a browser.
+

For completeness, asinit supports the following options:

Sets up a new AssemblyScript project or updates an existing one.
+
+SYNTAX
+  asinit directory [options]
+
+EXAMPLES
+  asinit .
+  asinit ./newProject -y
+
+OPTIONS
+  --help, -h            Prints this help message.
+  --yes, -y             Answers all questions with their default option
+                        for non-interactive usage.
+

# Working with your module

The example in assembly/index.ts can now be compiled to WebAssembly by invoking the build command:

npm run asbuild
+

Doing so will emit the compiled binaries, bindings and definition files to the build/ directory.

The generated test case in tests/index.js can be executed with:

npm test
+

Once built, the directory contains all the bits to use the module like any other modern Node.js +ESM module:

import * as myModule from "myModule";
+

The generated index.html shows how the module can be used on the Web. A web server serving +the module directory, defaulting to display index.html, can be started with:

npm start
+

Note that not all of the files may be required depending on the use case, and it is safe +to delete what's not needed. If anything goes wrong, asinit can be executed again, which +would restore the deleted default files while keeping already edited ones.

# The journey ahead

So far, so good! Now it is time to start editing the project of course, which typically involves:

  • Editing and adding source files within the assembly/ directory and updating the tests in tests/.

  • Tweaking compiler options in asconfig.json to fit your project's needs.

  • Realizing that WebAssembly still has a ways to go 🙂

But that's it already for a quick start. Read on to learn more!

+ + + diff --git a/images/chrome.svg b/images/chrome.svg new file mode 100644 index 000000000..79d4a92a5 --- /dev/null +++ b/images/chrome.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/component-mismatch.svg b/images/component-mismatch.svg new file mode 100644 index 000000000..c52fca37a --- /dev/null +++ b/images/component-mismatch.svg @@ -0,0 +1,4 @@ + + + +
Rust-like
Component
Rust-like...
Rust-like
Component
Rust-like...
Java-like
Component
Java-like...
Java-like
Component
Java-like...
Rust-like
Component
Rust-like...
Web platform
Web platform
Web platform
Web platform
Java-like
Component
Java-like...
✔️
✔️
✔️
✔️
✔️ Compatible        ❔ Moot 
✔️ Compatible        ❔ Moot 
CauseEffect
❌ Incompatible
❌ Incompatible
Text is not SVG - cannot display
\ No newline at end of file diff --git a/images/firefox.svg b/images/firefox.svg new file mode 100644 index 000000000..bb05ab914 --- /dev/null +++ b/images/firefox.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/game-of-life-preview.jpg b/images/game-of-life-preview.jpg new file mode 100644 index 0000000000000000000000000000000000000000..46dcada013506d71bdd2475ddd032455bb2083bf GIT binary patch literal 198063 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%0Aw7X9Yf?sjbe^UQeo;pECujJWc^$6!2mn03l! zFt<@hamMaWb)#h-&XmTn#|X19`JrBs_ckhZwDxt4jQ zRX@86BEp1FqKArAp(0|$CZ7w~DVJh)lwQolRJ?9;U6T=Hlt@r+~>)_xs82>>r+e{{W(b zMFjKCmas(fPa}whYD;gj_bW2R_$vm-q>J{_u#*1(x3_u2f{6MO52z#`k5SO- zDOSjA6zj)+8s*+hu)4|MWVE-owwLLWTiJ{&G~rf9L}gbCu^2Nng%AVxtJ7WkZIzdT zV$3`Nt_^L3z5Nh+tKWeKIBM{8H|W*{9C(+B}0M;1bljpK`QzxD^HKhL`6rY zh?H96@2{)$a6IK}RgFtGK~q3FpXAoa*C}KjZ?20h`yx+*b{rR%9wT+n4lY%|*mub5Qtm;yV%W?iB!TJ{gW`3WqQMPhVC=k=Hby$62oBibm})hlX-0^wpBM119mq0E zgXb5rV;3(GIQ+G|Ep%;JS9oWHG<65in)K=O)V|ke8Ic)hER~08(#^VK`=yg|{5#V} zHt|m^;TBfe%iDjb!Q>uf#%1DY*(MOa(j5`mqi_h^t?6G=ts9+!G07`hOZUV~<8l%{D9c|%QPWs$Hy+J` zM=m}KPfy&(Z@7%-7mpCnhj-z@K6zu8W_gRj$-IOeS9ZM-+ zmgPM)A=Eb}&?N^D_&HPkYk&U5a5Ow=W^A#3K;k@kC>|g3pUtd)Kkt55--q)rq}%l$ zO}uw|Tm8HCS8aM%P?2X3lBb4za$R%EtnAZ<@w*-ke_@crGTZ)BZ*3WC{FL`gS-V9d z4$BYRD%%1cgcj+m`L;SEpn^CB_4+sUn1flsj0XW2;gjG`Zc4WD?XFjd;GYM{t$u=R ztO9F!5@>FgSj?=4YeMe7eF*jVYlnY!noK2wu3oRyA^xQ6E+0RuF;qM@^V}9#5V=vg zfcOEbbYf0R<&cD>kagjKLRH4nIuLpq>lJ~+HJFj-kzs*Mk};yjfU^_w0Cm@(5?C){ z42uj(!39YSC|9Ec(w`2x@d#zIJG+=*n%WtiA-UKtB3ETeL~XePs5EV@)K}2!(IU*e zb*o+?U53JCc?H~-7;ARAxQZFBWQ|IKB7qE!)nW(TQ$gy-qSTNzvbyIo(GIs&O_r8~ zOpbU5N$#yKtS+UpzJg0@m>9=ByvWhZ8;@0VU>QjH5v&Lxv08{?#c9`z#kzZ2n_k(t ziKFhW`1cBKQ}G(gQ8CPBwobXhwFZ1b_hpf~#>i#1eTAqVpiqI-1FWHBpj<5JzI7Lg zWt;2yFSdtJp=x@3OH#G|T_-ao?bjPKU0M2X!q|B`hKV^YS-B2FA0pzL1hIp8ip9qp zm?VTNMrC=WV2dMeNdEx+PL!pyrcBvc5|fd`ko;B4qi?4wGJbTCOEm~MX9}iYoURoT>^S+-pT205wyQa_i=^mZ=$YOK|usmTqX$$_Hp( zWVd^*jA4#P1%P(|fOdk^^`Ix=t+i7tBmm;K?RL|?!3c3J;I2Fe>82arA(ZA>j$4Yd zw8g5M$Y!~CE-lMcDKU0j$=qSKFsHB1wE}c>xI!e^KHrM7S4Uj#G<>^(((+G@Wzu_0A0hKUi$Yei`tV~tC@kf^FESf4-u^*X=@TEHZ* z%%^DhhbNjAo-A~%h=yqh0F;bUuHv;&E7YG)j=I0qwVz6n{{Y8sbm}lIg$2 zZkZdouGY;2Hj6y3D1sr>Bw@+gy?qBwMapuPWR_LQ*(v?RmgZ7#PN!HcXwea(AoS~^ zE{EVBrT+lT_$`MmfUuod@eNt^;uuE|lm$tX6mLaA3jj>!=2a#jDhq$sBCJ{0-M#To$JQw3W7e-=*#z% z^k5H7YqF`s?hNaiaFhrV4B`BeTl{8E7SOIz&TBJs5?tF0h@KNH5?5rYybZ|IG-1%| z2}F#-#DX(g7AalhjS-pUr)dBrzV3r)_}Af0c*WUzB1r%YPF?;9Mn@Hr#7x%tJ6SDV zSfwOVptAafZ$tctTP&(|mXINDzin+Y(_~CeSdP!+w?l-!NG)=?J6o$@Le(m^mYoHJh%9)r^~f!7cGu-N<rz>LtFG+B=-xvv<7{|93A3&RRrE{Ze1r9;l#D!{fBzk~;%ILjp z9a_FI@edj1+)pEw&GJRWq_US#b4CeKe7FCdY6Sk~DJCCN*HMHr*>Wtlw z57k(9Jre!Z2G}-i2R6-B>1lN&6Wv7%$px`RxVS`Sjx!-Do7f62;ttyS{51^4omWS2xWCqByH zvANqNwwPsNYr9JrW^0?Dq)%DhZIVS)tw9C1DFZ~%B6Z_jTRY40EsEpTrtak;mf}dmD(!{@FC&t~bX5e+PTy^1($fIv^>3+KvY0#kPSbD$sTFA>+*K-efW(19Po}cAiNiI!bF#Ld zxH#rA9x1w`=dN|Yo$wr2Kgnco$}BD}VTqA0E@6U6V~EJ%5HUbT=4Js`)RRH3ifEmO z0fOt>?Wc5@Wz9eHFAaGUf#IX%JdYM5#>p|YH*HTleS!SUDU6quT5^h zWo;qkFk3fU8+PriGx+w$f`&yLlS+`nhDjt~k;Z_tGcll02U1Bi16)8l;8xZ<^ta_~ zj}u-_VY0Egm)&i~vKNurW#x-_kGLSX*s8Uu_qw$d^z^KxI%V>Ppgg##D!O*!$ZL#A z@+t|-ynW1gBf^}k9Bjnpk||PXE@Cd8sob`bL=ExUO=;GY*A?4)D*MAOYxdUCK(Zz; z%}2G)xs$gMwwCvl;xX_x$!_lL?c$SqN44dZQCKvd!9smor_WtGVD`jwA$RN#{{WK? z4+%03%)aoob^ zVfK92)3?yFHhNe>LlXX{;B?{ie+2mXZxeXyhu}Fqzt!K}cG6K{J=j%gUIcZS-UJdw z+qg0>ZGG$%9qK4sFM1Tx57lZLyC~aYL}ECR>JIpE1h*mFxs#o87v>zZEz6CZHc671 zr)X^=Fxw#kQMM^9Ku=RrO;28@RL#Ww%M5_PubA#gm6DuCq?PA|aDG+fTD=sXqZtf2g(1A@*6r~vDBTIlI@PizbN zhtPx%Pd6Mz_xw>J70R8`%y))zC`-Gy1Lo#LD$q=+6iD%5l=tSUb8 zk`Jgf)l`NozI&2aJ}WDQ$=liHY^TTEH)>^q>KB4T9G>KGvIRR>bqCPv*+j)_jo zsBvB}#dwbQ_~)7Nc3mO#<}j zHPvRDJqIGDr%h6ft3IJF2Z;gOzqlsM&yDk*Im2b_@$)Qr%!Z_U-uAnvb__3WR|BPu<+Bx9v7{8w6WH15T zJ?y63qw*Qr*ENCT>&Go7wGlhSpSDSl7Id=tt40Kxo=g3oJ?{M~MG*ZGTdXmP(+ZtU^FGy`+RJt!K#eyg&huDlz1 zZuP|Dm&2NhroFw!%Y=zB;4v&Se&^%KQ}_P>z?eL5EW+fZg6}pIS>tYOr-pTkXlD%O z7FOEZ)D;x1eGN4kGeCr~58Qr>irMVVQjnN-IUI7qhmYi=*1jm^+lgqq=uWoPe`ShvL{4;vWw_lHUCcUHcACBKSKZyuy>wd&#_&4{x9xAahup49>@Nko z@wYRzw1Us_SC0&^PijLq)V0C{FC&2>+?1~6V6F3APD-t`sv`_@=KlbivP*B%?5+`$ zIelN;?T63pRV*BC(s<>uc)#srj6#EGZK>+5`+xiEh;5=li(t&LhQbmC1bRqsE(JSy z>yBeMo_if>z_SmS<@XlzoYjNEQqJBD8LPb?Hj$M$(8=VT@$+We?MK zm2Iw_dY-^D9Go|VoxAZ;&nEu>7)N7^8T(9CovDU@qc|pk;%K|Sye`nl;E>%qpG`^J zY}4viBP%q?-SE`;x0@#nc0a@%#|LS}?PsvE&P-!WtQT-jBt}SPnrSDWWhGXMBxDKI zI;gD)*O4?y;#v5*=J$5ORz_eE`}H;?fu}sX{5({LmU#2U_|73<`0LXx<*nt8JCNmV z}E^VZ^J-8SwfFxTORCV+f>#m7Hvm6&iR*Ou8K+?xZ@Lg3%FwOoUeuQ`DfVsz`!^3=MoyT>h>Rn}am#8f5rOo__c8fD;;m`#uei?&!QJC+ zh94Pp!OT14aeMS0&GJY#ffDU94*|sTQBDcu zET&F;h1M$yS`3-vH+{p{m?qnyc=!MvPVcQkEr6JHa$YU z)b!UIG{^U5349+;e=HOK0FtxQ@R%(oV|xdY(;#HNxmVrwF-W3Fq>EtKRD(t}>+9*) zTX%Qpjv4nXxBIxpwg5^54Im6$W<0)JR&t(e&TvjkK7S`|ZZLVru&~d;k1ZP{*rglN z7pP@m$8lg8TDx~1r(BkA4RX~ilqLJI9VTwTVJr{a{1n3($oQ|4_|3;Cxxb1mPa?`e z6udR>ZKIF!%L3C$9q)aV4aeOZZu{qN$5IfKFRxeaJU=xpSg&zJSUfZzQ4fj3gX7F{ z#Z+9%--6+Cc$+>0WeuKFC2b|vR?i&I^hm)@2`V4m?$jNYFREj9BW!}(%P^{FbJwFlt zQ>~|bAkmRs!>ZS|F@)F?@g6P14+U}Jd{>6@Wrq;uenPwa$@94on4x8Gj}-Q#7JGSQ zKznYkH&@UrZ0JQb)^_l`2}>^JqWY@cYLg8y4~NM2r~JM%jrgyb-Ev-EhR0(p;6-I*w&x*E7 zVMI1&mS@Gta(mx{DD-zcHxXkkmBqYLMS2P;T9Vrc6=wKT*1sKc32p0+k^>bT8#WYH zVJLzp_;Wqkr#w`CKZBlN;o*6i@%HyDw%3_FMG( zYb-gH$G6;3w%m&=lK?z(&o;;9-mM-{i{$t&GoR!3LfYeuPit|Jxww*o+UC}20?U79 zUYom=Qm#H8nw#8!Yb@GMKOQR2)DGI(1jA@JpA+gY-;40YCc*gQ$DD)2aSS!AXEluv zHPyn*4c*jooy@`}0bU5=Ub_i&ZOlf~QL3$-Mxfsn%STP5Km&{j!dx52pA2yGRp%V> zrwO&>B0g0tml(HJBex?&;6Jq;iUwea#8!Zl>8SD3Y7=5yDCz$IAEpx{Q}Gc_>QH>DepQm(3cZ1;^tYuKCnRK47MbYpE=Heorg{@4YG zr{fGq$J15minIpJRBeve+KUqX+4-vz!aQ>GCz-Iw@%6mRO=G%Sj7^}By8zqXHSLCI z{{XGIN872MnNY%UCk)5nti20uTt~kdvwhAmenfox)R)UVqY;k8KaX-&QpWd^T3lX9 zcosSBZY*AK@g!vKb5SH5;oyXld}RIqI&7Vh0|@MeV5C&RU`d zmw&E2i}q(Bu z@XH^HQOir6J}-}xWY}qCWnnFN%sg8HaB*3tF|2QyC9!8^d*RggT~MC(;U44! ztv2r34RtZK6^MV0o4Hu}L~4v|{{UH;##(&%zsJebXX;wZ!*zo1eY*46z5LD#X&InP zlK?W9_HIt^db`528v4^w8|dwvyK3Xxo2q8w8#kM?V&C1L#n(G=*zix6MZ0G!U;A-5 zRYKh7YIJRdqyh^%weB{Nz9KRQJU$0Az$>$u`1{11XN{P+pA%ed z`p+^&d3_XLRU|OnHLRfTlf6fEEkhpVQ%0tytJ>8ZL;xylrS#}V-*DFuKx{D>jQEU4 zdgpB3GsiqwURiQ1b4x7nPHYm*icFKURwpI8Y+p(rQPWl3-CKG=i5Q=Xt@VAb(`yp| z0Fld^Kg+whI(VbWDaJUY*qaBE3$zyz+hi6&3&-`$i!vR6mRD8U0Y4g!qg#4@<}j$o z=C|}c)iv$RFwNY6{lWZk3e>}|59GW?<37<_WER^WI%YpKy-4mc?-3jBBeo=&5;UgG zmFeq7_UdjnRb(|wE-tM90Paz2M6Ehv{DWb@o)5)y{{Sn_@cvE7>IdHxZ#k zyb(L9PEmr8SvCNy0RRg1uBw*VMV6TW%jcHevcGdFfMN;2D}vw4JZjg1TVV;F?&{Vf zYmUK~qFW0G+!3xPlx=CI?X&hssY?648kwtg7z{i+hw7{wJ{@r`L5SEfo12rqv<4u|gkkT_M2?Ur39((Iq%!ni) zJg7Y%?v1V2`F_npMARNYs%#G0CR2=@KOX$B{8aY?$~rsMdYD}BuhL>WGq zo#9nnrs{~xdv?}`P(4U({lWd*SyTG#cAxGYPWV2S`Qw{;_hh_sem!Z&@Rr8*)+m!8 zh_OPnNjJySws+9gY6(9dhO)Lb#=M!?bX)$vvG#xqVb79*E2QV(owc zECq*jp#+k^R-Hd)q2emnj!Ld0w)YMtzFteCZt;E~kD1}qgu{h+n%*6wA1rg1w(pRy zcC#==oW-!ptW;O;Z99OtQ4OY{?df*&UqUnb$UlC0V3~ZiY2ci8PWDe9 zHL%U@D{*UscDcm_VguFY3KW4_2#cvcq-%oVwTULS)y0$;8%Q~+wQai?O{!nfe;&yaZ-D2 z#@c&1!ngn;Gk@Ke#N*_-pOE6XjvtlZ;xU<4%i^srS{q!Yw0mN>g-9F5`ZvrH1wJcL zL#l-1RBR#14!(9Hw)Ys5rTB9CuQ(X^+hkl_F=%P~zo`nVUEMl@b+Um@ymIedyD05V zr&eF`V6N{NM|B@AwS06?i-2UbWfy-vA$fPp{c^8FM?SBBr+ zm%PItOJ?8k=Zb^e;5hzomtEp~e3Rc>$vTWwJ-HrvL7-Gk%C6OK>j1~)sJPW!=0q`2 z6wy@Ar!kH_vQvAX1w&hWpq}s!)4nn)iTfqkOeEzsq3!jboyX*X~g^of{`5#jkSj35Z*7R z9!KQPs$O%#@VsxBMx2da+R<;tzGLYrA}C1$%R-fva9ud zl@OS>5g8xb;qrgYlwN4K$hyspGrX1yB!bQ706)`jZrNJUllOfcvHVC+}+T zE72V>$$e6wYbLECAP-JO;y9m@tbCK<`%VRuvyYTnt(D~I9F1eRNEs*G!|qpU1x-Qp z)JErJOj<|atNWgxu_8ANiPG5ObHnpcP7{ss<-e1$wj9ppamT);e=?F0S4aq}1u41r z1Jk0D_G%Wo>5c43Wl)VfdiO>klG$aSC3j@;-U)+@$u9_=@=Tz}#ISc_Kz}YE_ZetP zm!&DamFw!GR#?W628DXtL5y^WvkbqxzwuV?YaPcI3Qrfb$D5RlHV9(3+_Af8X(5Sa zi?U~EcYR8U7^HjHFSKj6QLl?X1&pIitdF|R<+bS?JYP>NJXLkdV8z|xcXLQEpHKD0 za?(e0BRX35%R(H&CEF3X+#+Q=o8-eWaY@=(yCp{5lr;vWwa2^_v`vkMN;7vF938^~ zGRyn8Gydmw>x$3gX!wsHxX+s;;t8lMycw<9KM}p7hzOUbRiqC8(=3u&8ikl#pY8lzTpkO?{-3U*ow=NrQgQ&dzfWtO zm7v5MQEsJOq+Xry_3aAOpHWI3N^Ik^{pTM1mu}u2IFYR5^3UOyGCQ3(b4wo|B3Z|7 zmP>4L_N{!D%%;h14SgH#io_xF)Jv7w8$pOU;vy_-x)y}#P|HXkls%$~SR zd|xZ!md9FJ*rmiKR=vNTRWdwLlENEMrl@vQ$j$eN2)^bT+qTgyxEM1m_8Mikh|aMR z8aa2FH({Evc#jU@R+kybt!y#3P~2ke7VD3|@ZUj}nb1XY^EIrJ7=p6*d!DKe>I&?A zDuK}S9_RIDsXrkHywYd>Mt%>;RXU9|Mr2&tvl_V`+!cArlEH4HtyWEoQ4m^fsP(BI z4^2dFL^TCl>LRf*&A2yj1WgwW`eyohZVcU&C>c#m)%OZ|fA3GXUPx`*0$sjoIP7#C zCQqb)?(OB?m*8+13!DaC?=5M6^$QZoh`Nj@i*lcMWUX8ty+_@rU1e6@GJ%l?EE8|A z6M>l$5dqz^@aK+v08KkM@8xBqc@52a?*KQiN&rtve6^{n(Sy3u+h1kDI=j^Chj{Ca z-@=(Yi<5jLK`a*LiyHMHhuc!r=o{p9H?!&V$Z93~mB*!YEv1nbN?P1F96b5=_o+p; z3g?N*E!PUiyJfDGtl~=u%grQrl!4+!6(@4B*L3#cn3D+O+@<#$3bvKXb=Ea^a&h#{ zF-_z(!13It6x}U|z7kvHv2sQU4p7G1_bDT%x2LD=*9DuZ;{yU18j|2EQF`6vO~Pz=ho%rE!d8A_$PpxGAp+#D|G^uBPdExhoP4gp%5AXHwN?n0Qq_5 zth|qS*nUIGa}x7r%*ux(xLG11?%nNs4R6~3H+(Uou~AXgetMbHs-h?AR%lThc9S!X z0xjwdkKz|L`2PSgjPc((ORL;-OOUXZ;@0NQ^-NM*xc%F9%MH=WjZhe_;49OwN{-f5 z)o3kSrsNQ>E> zwy-som=j-LvsUkPvyLn303S@_EKl~}=Z+a;hmvyrL|Ry5c@2jW%o`aj@iq~CIa_qI zjHSdPNf@F#1|dy1RXH4^xMRm%~4w0HktxKbFOkxZ=%n z*ehpwqq)aRe75lm$)9|Z+)C=51N;uv+tRv{)&az_u||p`{z;HXYBBq@=234a%S!0G!f+?Yp08&B?SQZ@ywCSpV z(*OaNe}cl_Yi|!~Py#q&OA+AC@7?69OlE5ao>|Cp?;VE3#~g9VX(*x;Sx(6$RE)4d z!l$>?0n(>j6zKl|Vp6Y?;n`J8w^Nm1Nun9@$F~(X^Cmhbv&LiY?{4xq2cG5eubK-B zJn0m2Go)qNg1iqKDQ~x@O-XMAWB`^R^HZDOYS1HSi=2C~e+);f=Be4!47eG^kz;Bi za}iNf+pkhS1pKS0Neca=rzTa&ia*vmKGrSZy0^!i=F^<^AI3a_E1cD?HVH9y*|d%C z9vET~-r3y9uUJ&DVil^czjf)W7TsU@KH`- zXXKgPIObC=XJaNx-r~y8!##|VT3gPs$w27)Vn&E%(yffQLLtms2j;K*FVXpW*831}jgrdPBTsKV%FTN-TRp-$+r}YA z?U3PXBN`FYrFCd}?{|xqX%IM}%* z{KgDvWQtX3T1c2HRD@DV>Pg;M`WsbW4n+*mNq2RQwFw;d@W#j-C*6U=H@HL< zU29RP@xK<(M84t4T6X*R+d(s*5Meu@mu_@K$(uqP`L=vu4&=gt8FKYEyQ~ zm0+i(D4>sVVqxsQCcPkH`KTNBag|ykF?T1nK0FpU{{WMD{{R)^`5r09^S4%5e5`Us zdybA)?4I#Xa8qH~Cpq#x$v_277`rrSBn zA>z5*=Q_E!c|L?i70!FQ@yin#(d~?z_eQTRO&Lz-L0_Jw?U9W{$+A+r{WWcgU@$J& zGlA;*d{-D-%E_`woQFyf;QNCQx96{(fvfm!d;4<#O18pI%ks}CX4G<-bG1_ zL5A&(AY}%h5)Cz+NYpiCvl4j&CtX$LG|SuY431+NjK)Q6XKfw+FDs1f5VoxSpc%y) zZR@p%b92&-(6QC)b!1~irvfs;eQSBVq8mxuMV_X?@zikOc|Q-qb3PZIa;`g>yU*e8 z1UHw_J-y{)M~Y~q02PuZ1sDRMmZPI6Vbl#$;kvdKdw}|v%pt$N7yI#(PoLH{r3Xz}qt)pr5Jn$0^c}zQswFS-#KbVj zJDxwHq_X)2$>lEcATkSy9z;UbD1@D>QTmrGcIL(=XHO*bgcg3Pk`V&vRy0T zzbW{SC*u1)2jv^vn;ea->1kzgkM2g%+QuY!WGKvGmO|3Jb=nz2RFl(Ij-R}!(kqc- zFjp>*)BvPbB^Z%|AKj~w%y;701y6Y=l-os|zQJ(}ieF%Yc4E5`?P<}6QbW|K9+a-5 zH`}jSg=ON)hpcr%W@@HG+c9F;=a_!%lye=N$mHh7@%+wSYkWkr!wuY}$q?H+qC0i3 zwG?gu^c3{ec)rO22}tQs65nnmSgKPxe0X8<4U+8(4iAf(ZZ*R=;@QQ2K$L!XNt**%G1@!Ucx(@SixT9E* zA^`fhj59tfpK|=$H=MGD(;)lANU;VapJMd`sWcVqL8^V5sm?4{%`NISSzeL==G=T! zhZ@IoTeX7c8;!b>*6q7-T|pD|3P$3)e(+P&&>e5vi_S3xj}_ao{{U=_PzOmZsBl-8 zg7{VCzDFU-W6DR5zT=E!65L7_c<(0mTRhRorjVBC?Mm0-U0AkN2$D&}D}Ktl>z0`v zM4W%+`u$bWEuE$(F^}X-on=^D+q!1aKmx%v1PJc#?(XjH!KH9_cXxLQ?ht}|aH+xz z2o4q8cGo_qZ{PmE{**jx&QIPk=6w>2=l~YC&E_|mODbr_-h_IEZyQT>3VmDwzy*`a zN>uMx&F=UL!%|q-H)*{QmxV(JV>kXC=E2N73`FXcXY{CLB7DMv*(l=-ae}2e-t-$S zFaoJcC1!=FT7y^L1jEgQ>6A;CDZLyl0KYXnq;pas>RD9A5-I z?frxu%EGfoCUDg zO|}uU!|S}2L2u^=L+Yy2lv<=lxV;Lquxm}XaY8E+1R!WhhQ0?deBqZn>5JbFoE&V})YQN{{|46s6Dso$Vl!Q+ z>1P(%?bdL@qdS*+dETZ_y7s9|7t36@$L$;VG&|{n3gEyWu@V%^J0@v1r4o`v-edDI zxkEuQ>(itX@m9s`pxZQxpvI;itTSCsMaHgoE`Bvm`sF2+egT)q+ZfaE{y>SP)s-21 z@XIi<L+`- zm@fa!{9s-DnAT9aL4f=<^p8MHZiGLq$5sPFjz`v?PHYND{>!l`jRJKGn0eP()4dCrZ&yqE2~bgz!&4cLzF<68e3 z8R&mrMHUdj<(qvhJWCp96bz#CaJtBko@oo^LzL&J+%ByMw0Q!UwpJ3zyt=VKbk0PQ zg8Ls}arL|Pwhl0D*xn(5Tu0w$(VX8+p0d^yd zdx>w$QiK0WlE+Bn%adjG^{ z%5jJ~trK>CE{XZ8TY0dGlF1v}s_j3YGnnQu82#jFMmDuyZ0Lml+1V0{vnAqT2;Wtf=^q%i zw+n5fFwcwq5&#ApOnPsg^KPvL%z*Vomy4K#mg5IU_giGcY>oHW{_XlO0M3}W5hh~ zeB-ChLneY@SH42AZkeTDix(9#+6*ejp;ZlZO`f+zR^_J6K*uWow$Z4h;Z9GwtX_a4 zs1u7FPJXI(+>W9Oa;A{orLR~8Xa3G$wJQJq%)8%LP^nw@gRiNkhUN%xUY{O}(93uM z(ldo~qe|6}UF;9kU+rG?kYf4?L8q`R8)!Rlc6GnKSD#MBTeu7=Npkj>60K2DTDe;e z=Mjj3gY_h(V&%`gRI_mrh?=Rce_%I~f6zhi2S0G6oi!55rXETuyXD818)jUdUf!RS z8Jv`7G#u!XV>MIrE?pLX{)6cI`Jy>x8ceEnVbBGv{!Bx%)pbuR9Qi zQpZwvb@%jTi#a-fO71;O4inYOkb-@{tiONp*%D%%b=-u~_Vr4uPg57ByE+WQ-TbpK z=W3ZHa5)T&JWaYW0VTCU9}cvYa{#y9A8nDVXezdyR9?md78r}}TT{4vV z>V=TYd<+k@8m==eFD)5(t}5e&VT}ULom=V-Xyu^hz=;Q(r^7Vjfe(#KeNcxwd7LBnhS^A^ICLP$mv6j3PbbW8gkFD@_nl0#JdrZv^Vt{G4O(Jt&v(}v zE7$f4p9bf72J*3;h3yV15x=SsD)`+QnQ!fB{+MdygX4oZ%fSgRJ*Xs zpAy^!t~fjGjb4ZHqKC%WFm{yb&`c)#$|guem928wEmLt>qn!_ZQY=hI7yvMS38FY^ zOO>sKM_ya?rf`?70HM_bEz@7{AN&W^OF&sk#y985Z9QTSZbE>qkG=2%X*@Y`TilZxz82WGKW%9CXMNWd}#TiP~z-~4E!#D(id21Z20BiZHI)J_ z`f~3*J5^y438_*%Z?`(wmOoG!`MsB23b{-darIW;*%^O!`Hb|q3-cVH^|}9^;DI>& zlEFBGm_bRjr-{#cx9@Cp|K2*IR97MGOX^g3L2*01=!-4aS*BG=inTv>2YwFZoyRO7 z?qH*C#;Q=!abk1RP!3gxp{;>R^BZdkMPrBf*|#t3WUDS6E-!KD{0c564+G z%QJoS>{E0#CAsk+wkq__qbjPE3$9Il z9R+}Osfh94?b*yvh}Cyr8g`bny@L0iA}%^v6B!%|tru*~*Y-;Q>`$1qRj@=n(8Ehpc70Ee)L~)Wkxptbbt6FoYG7AP;IgR?aNu5lo9d zMvKU!n6SdZ-$Oh`DlOspOvtzN8GAHfB(W4wL;sNC`-nuE`YR=d(Ph03922^_#udRk zu0PjZ%}`$v9phulp<7Xy5nX9Jn^qN9#Mul)_&HKGBb|-vJ$vaiCY03g(fqubk75?# zvUX!Egb%yv?&cN{L1T#kMf8p`li#s8v+H2;GrD+TP{jD9^hGazPDvO+56NrwQUaVI zpiS^0tYOHM3%YdL18DpIw4GG0Z`D_16H zgQHlsS18PU8k8b@3Mg?CbdGomIrICHK;+fBK%RM0_S}TWsVDHao28kB{kU+Tw z!A%gSUlXWUc5#3`+{vw>sBJMfKrn9cM7;Wm%_0vyZDc&ap=I{_Z=Uajnkice5`LNd z=V>=|Ym$uH8pKK`f_yAwU8k<`<*=+H1jm?LTcD}3Lwr3@6#2xV4|~QG*e3J-v4zpE zvfG{Ehh}N80=C$as@KPu0<)M=?FU=~qeyNzs_kTbV`E(-2|o(~AjqI++F4Lh>mUW~ z(8>%N&lFoNmSx5ZmR0WS&4DnxryGt#2Mw3%v=;}MlF8C3lD(RYu83+&YgHO&4QoaM z3KKm$p8L}ZGpRXTCGK@Ju|8*6H^S7sZFre{*x&!GJ7h|4I8}|0@i>Rz$&XVib-hq( zBL_@N)X4KEtmu@|40kJB^faD1>qWSI3lPM?`?@O4u;EoJ#BDGWGE>|bfl$xBrZcxR~Xv!5bDIxr+HtLo|-B=P8}zr-)ts%Z@-+V z&=RA1URKX)Xxt|~iej>9MI|6-thU7bQ;w4(9)!pBWp#8 zxr||VQhoR9<3}eIzT8nQOyiCL0bGftGmk7nlP8OZ-Avi9nKGCjo$GZq4wo92D)4Pi zA{KN=#=j;-`xHnHGj#Mc+r_16vWHa8UoXHz*zI$6SB>B+{GLI{zATUG7?1|9V@q{{ z=Y-IHSd&-{?;X)?M+KLOHt178GxhaMqKQdtsFk~3{Kegz22X&nI0T}6x3x9Xz}PCM z)VsBwI;)()AD@0m4(VjG7I#l^OXWDxwHbR$ceeWHLIp~v(8lMB0Dwa*U^(@@bt;L!TL^!P|*$czJ*nhgr zr=-G;);|U58IJ6`CK@X!4VX|x4R#k1x~yKYxY2$39VtzTA%;NA&;iJbvAWy=I3nbN zME$&Q1q95xR`=KT~73P#T0O_8J=+LVLyd=!EmS5(J{> zL@^#8yb|vO4!=56&AOdfjMeMk-=0g+CR%1xBWtRDbatLTtZ6vJ8ZZt9GkEE2DgZbx zMkj1ihID-DnN^Z3t46GL?d|J487Q49R3zkMLzbXwcNtag6?(A6w^6kR0ejjXzs#ba z9uoJ{47Ln6Ik?&qFaflqO7vCB_J)=gDf-ZKyfIb5zs%(!Tm;*=@>iOfA6f2S6J}VF z@KOl0_F^~BB?GxSvk^_F7u(e{Kn(KV|Na=@9{p)O6cAK#83`$pgu(nd3Oo{_JUGrr zLhSC{e^@kT?dgAxUn6TbSn{&X%)+|tY`3Ft`KSp;1>(W@j&7XoyoW-CN&eGZGf1`G zi7CNLK?(2%;tC`@jFhhd^IftX7SWjQ8@icZ|Cac`f9Sd(1wV_}I!z%Pi$j}IW*Tea z?k8qGuF7%$Ado_kz&5>GOP%Z0d*xK5h=vIvO>&a!oDsBuAAgcebJhG9+w~`9Z07ek zdy?CT<=fHlDNk&I{mw;%hBsK7*q|z?fmLQR&}a(HiTQJ_ZjK>PhC(^>Fv-pepk?z> z|AT2UwtOE)2LHh;+d=M0{UAi(*?cA}bhO2kDb*cqN#VrA1L0#wJSbw2Ia$|u{(jC=vC zsxgY`{nEFjn&|0%d?;|D9L)nQXZ|+28Tp}zPO9L8P2}T zOKPu6f9gzV5C35i#%x;{DG}T~)a`-^CPyU7MI@#$a8cGJx(|Njdr2ttq@Tztn zWPe>i4+sv0$h6y#r@{>EY^D8Xa3Tw+$Wy~Ji4P}X6C~EI@AHkYP_!Br$)hd7#d$hQ zacwO4`4j}x#}I4X;KsIYWO|+k53uWzwd(A#%5M8TjuSgX!qLT_>!iOYHh8if(0Ul&^0bX%|eN?{6QT^P}A1Bdr+?F;tTP!)u zQ2fP1I#44=+c@YWULXzZuX-!c8|`uxVWx)~-IIYbo>VmH6j-nXSnf&GOZ%1n26vdl zd`ZjO?(0SPjC=~`1s%+*%Z9)J#?{Q#A2LLoA>~~%;j(X2jOpgOI(FxqcVc8rJ_96Q z)1#Em(w5i+!LuOP7k|*B%Vo?HaJtW?V7J*jEU{3aj;71@QlN(TN1|K&FCtBoEx3g` z`b+vMuLfV+Q-Rtl3^x7ej-v#om}TB;r-$(wdK4{yv~+a880wn1ggucWxjH0!d0>=ds+lPc(f;v(C1uy&gpFc{n}0_LIf^=zHzs#WNgeA@FW6#j zL!u6E;?sBb6dRqytj;E9nO;|m>{p~*vH8B837~*QMs=`YyHkx(wSCx|GR+FAw`-rA(FXgt*YO;i{1nR};ZD<{-vp zTWsDv`KFP}`XS3b(n|};Qgw`ha`DGYbMfg+P=3gNa^VyhhyTG#AV*OF_#x+s3`8+4 zM}$OvujA-3P|6d&jkCKmAc>kXq9Ijw!7{@lW16v)?c#pntmm)dv5}(_r5kvlVJRZr z(UK)3y|;B3)s>Vb#Bg->iK&TV#z-ZxRe^}RP|iGr2Zo0<*xJ18AD9FsVc#mJCOie0 zp|!c5$ZI3+Xxp%H_OhNmHCkwshDB|Xk)85)uMDLF2_Hs=r4<)yxhhmzM`0W~QJ&_8 zQW!J^%??i!GqW=yET*9PnJ0!j9lOri+d+S*t!%(mqvQG~7gvfH$*#0Z7 zF(IM3;pY3%HM2&M=~r>c?d9c($8FO43{}OYGQ?C^`PTMf|-0M_f!)%(#) z*#M!o8ou^$&#$4bs0ELea8g|`;cmWI8E|ElB@aKA>>Of4 zPM2dJs9Ja{XSCA!zGk#XjDoZ==k`b-2SMMz1u_A(om-37D9ItP8)o21x;u=r?#C8?s@~FSO27p>na3XH1rFffP`jUPt>b*g6&)b8U7TF zCxVt}rx=ypj@FM9Tz}deb&zwF!@5s=_~fhB&>#C7O*ovf=IDFOY0EwKstO zRM-kl_BJ(DpPe-p9IbMVtGWV1(@*=^aU=}I68T7nmKD_K8(T{mcy4c)rTU_ttRj~c z3o3G;jltk+HyDVlM0=E2-zG*8U^)sfE`H zV78DEqD@kK_T@aoZ3SzDk)cI3Ib8uWMZYCS;dNX7m?b?MWV9{2WT+?(ZTM?Qsp6m~ z!@&MQRXrsa_?Q_ z5-4TUFP*nN*7NcMsq||&dX?g5ePc`mzppLcV-;9yP_re|(0CqfJ?^Ktp_919BXm3! zN+eBeDqq%^aqHtJ*m#e6(&mV9l76xiDv7}wedOQtgriiZOhvDlkrg&6&9>@Wav%S} zLm)B@?wAChm$rqm&ob3_c&2K5eX6Ele+VyZByb?lz$s5Ws6I)|9Eo3EQ$15#gb7j| zx!#*`8K<7za^8PufwELJ1=}5J061Ae(hGDknr-&_b%b65HI=vP++oJ0Z4Zu;0fR1V z9w&FpLZTnBxXiZZ2j@q13Z-_vI<#Hg8Li^$;(DwVa_*rcQ*`zEUr|-tC7dE;)pI4S zOYgGrywy(KO9(3cs>2V7l3;@rt^4AY|AF0OLhdJb;(9Y}E9P^vPWD^(+F|)wB@S$jmIEK_YEYarzR5n9@>!QRf}kEBERQ~_ z9D-&CR__U~U0m2BVaJH0zH}p3VBl!HY0uUABB9lT+?DJ;q8H#3ruZ{@VV#f+fT)ra zjLXvqKz6c09*Pd0`4E)IbTGP%qV}mJ0aM8Jk`IvT?UuFL36F?#n!_0GI_N~3k=CP7 z+Yk2<-w)Ag`;baW%OF6D&^&OPrqi^Cz7Fc3khBg`X<`XG5E*B_X<$}fTs(ltRa%aL zsS-xq#ztQx`LwEC5}Kop_H=`3hqN^Oh6|FA% zfZ%h+Hx_LjqjVS;r^^lZKt2BF{?cAg7it(8^foB-1ztqs{nGIijkWeQVS>r0AR^Ba zjGrUm>g;U&yWDS+APg}k2lso49E^5*W$8m?-8ZDm-6@(H8GC*Nav|r)LZOjIOC;Qi zL6xtuFUblKKf&kDDW(Qxz6tCG(!tuQW3nrM!k0=@1ND!KWZSRFq_;gSg#I8 zyxsRF&-nI;P)%a>_m6&^0yFo&TtMpEGyLu$wMx!p_an_RM09BNdY0SBRvr`%&jya| zfj2R)eVOj>B4n)(q_4r>Z3sr<`y{Y$HBGs2Nr|;r*ce9+m^tuoboGPvo|~ydR0H-^ z*10-r6H+lz>Kr>W?vZ6UZgn!TM-6cwZRdbciUWnS`|TR5oSWi#VnwQCRC}wlIALdz z*ac3VLCwjnoxe$^Gu7>EmDC0#ts`JJ>#=KZ7>&O4aGhrq;^R={*v5m_0MCcy;4F%Q ze5UfoWw5nWy3dZ(i70uR$Dw>a@+`(I5aq{QbF&lwNE#2}-ldwq`3lGD=KY#+Ylk=! zLo)p*$2=mFccYeK`@*PSros`Z6i+ufsnb}r_+guJBz12q5j`c**uT3{ga zxzc5xy)Ewmosans)D(=P^Ig0Z`c@Xlu?nZy-z0w(j?&beo!VWmN#V#(nq}dVwQkJ2 za>K*sfP0dHA%w5a!w~-|IjbS__4!(_qpjKuCxc_^PYQjYt_)@<}zTdR^SpU}+^*`WoS_XZ<0-mqN z#RA^6Urd9QUa@0izu0?$6(K-QAq@?v_!<@i$m8QJ7m8|Mv4EYs31+ z9?xmbL}`kGmBhAs>^9TO1S#w+Fq=Wn@+9(IHsT^)(GIi=<^pGnwgeV>W*zN1{6 zRxiU(^N=Dgq1%hGzvTP#K6nnto*1GRz6MaMI|bNt;yq}qe9mMcN{J)@XD+0yG#n?g zYJ4A&yNV5-syp56TwCT|L_;Q?{&Ncuibx-8X8JO)J6nbH(ruRI+aQ=V^+@$-Unu14 z2=rrRXEPv+oiivM|2|925>GhZ8Zs0t=QNA5fWBdvCBTXCGWA*nc-e-qr7)^*8{{5;9Tu<|=jf($W3v1O#7CIHqQyKp zQH2W@{!1EsYRlE>&QRYf8P}mu=I@2)^x2(SY8st%L7E*8pSSnqW-S)a-o_TZIkcQ1 zTsy5gC8I@ALM+{7g^e}Nh080Cwe)S&c9j9)X&53{hnQt7HDZ}bG-IBVYiln?c;CZI z>SKsSs8Ze7WBY*6F2NRi4%Bg_2Eg5nqoI^B``?W{(Zp>k3^3s-|ka_(qwj%_63xH}*L1oK-*QmD{y62-0i&nZo||^BPQ=T$r@k6Jgm}XABwc zteK|GHz?ehEyjjaZI&P0Psf7MW7dAeq?q>CwpxbE;PgMhuj?_I;Oi%HTY? zUj5sdSxL~i)ZA(uk`(Ga;=_=CWB7RoZ4CT{(SPwW^#f6kFqU+@Z>_9&4o<*+-TfN> zgZ2tGj0@nvZv`xpU;N|dG?A{eT#CgoZ7Bx;6m>My{$uwu1HJ9x<4VYiMc>8wT_?C zqV-iPo$4_$nFz4gTB~I^{DqIeSaS%b2;;zvjMHOp7X`1kZo};jD`=6d0#2hM&^KdU zor+1al>uD}7{|P9DVE6VIb@t;xYC)-zB7CcH132S$rxxKnFMAYQ6`9z>%bS=nb>{H zW$-xV`Yv*unRee);wR%F+Nw|}_}Yg}nkneI`>K+7cz8byK`l6UZA8K(9-ek(`bGB~ zYz{yy)AOv8U4|ibR4#pZF>3p!vgwT$C||Y8E$}_x>?4e<>1OjV+U%&iacyjJkIJo2 zkd+;C;AFi61i!OLj;gy*uB^KwcKb+ZNRjr~vhhUiaq65{7vAnqDH9De`k-SRqKRs$ zxW2!D`ed$qJuXamt&w-WZz-6S2EHDuy<3hOG}q>}JtS@aD{cC>`mtE6 zjBcz$Umi0i5gFkHJ&uO(R#dFSS}|Gw1Jl!GP^!SDt))e&ri5NK*7M`yxjQ)C3LicR z*ZHL1f8nHqKN8L4EBmDiyU+bjmeJ5?bM|z!BcAB$!xKYQU#e81@o8H#hB|C-o#!OZ ziN1X!v7&)>fiP)p%I4kRy%&upj2D~p`xUbw?);%Kraf4gSZJIa?;^KN^idELDu8^o zn^I62?uD#p79V`gDV0xAy0n@KOlWh8LQ?NIuj`U#h3Oix-r&|ve7}|ty=Ig;COUAx ze%&FDBZ_Lr1nr2<`afkq9oxD+V7qTg_>|Ne}`T3S2g8hOe}c+KQ|W6aQM4+k`*`Mp_67O{Kwf|#_BPziAEYKOqQfszGzi)8P z=+xqsysk&%=Ce*Ir%JD~>HFD=AXS&K44Zt&r?_|bOVuMjpYi%_=pyxUi1&0mF zf^Od*{X(v0=G4i(`r_%hK7v)zZ~HoB3=?#Z8F@smJ>l5-Zw+w-OE)zKA5z0FNS=^^&1|`P~jc7MkBW}lraLEcR*!|Qq^&{N{oT~6A ziVPRU(j9YWYrI97+ioJ<^sy{Y<iO^YbRMdPKpW}Hlr|B5s4 zw}E(6{0o8)gqIsWv~CV>?)h>P)d4v3Mu1q1Q`O}k@+VxBFWAoxnF~qlpDLSGuTl^lPgv*8&ZZ+dfBzMiI@fIm`3LxGl}R_hvdM zNxR;i{0HMFEZkZoEy@qYNas6RxeBD6(FUiT%18wHj z^_MuD)>C5fkV1|;isSJ}w#}0=IA8PJ1m=q)7RX&Nf#hoHGpRPN0RZ==FV`x#`Zup{ zOIx#_rf~?PdfIiXB5e>4?4_7qR=gKBNEd^3*0crap_D>8&ubkODDB9uavH(V(tRWV zSvv{$Igu}S()6*t%`o@%`7Zf=dd*t5BwGR+(%2s(lqYh5tozw)W zOW$y1&=ev#P#)WF4dG9Et+_0`;sJIe+cffZIpl zy7NU1C?u>}NUZ8-Qf7w^$H$MTzqX_nYlnD`KBesZ1!bITOv0l;tp;CN8*F2RnFD<9 zmLu|>Ch&%b|7xt=)j7nl@yqRsa1LcmTXJ|cBu^@A6@)gPs>hZF!!{B*W~8o=ABsD9 zX*)5lnYoqY3#%US2IP zf8r6YpIQ#4AYVOXhxRYCPtiNY5q?qj);(DpOvo4HUDY}%HTg7ciyL$0zQW7NY0bEL zivCuOi5>}b`bo|o!vwm2hM>F+GK%7+5&v6(npVUG<_f#G52RU6|9^qYU<~yTEM1}Y z9luL=?B9RppLL1YC`szZk|Nxqn1@KIs$BfxVq4s$a>sHzKOOyDW$1-4lM)FNc(m*9 z?N#>>=gCJm_IQ=P8DLBz(A_8;s^k6TVjop~HXp-W30Rm^Me~x3ePuTbq)8wEs2z3{tla1fgk$SZHm&+nK|Gs#f7!SpEtdi>L1P(r8I;wHEY7K%6`K7vfRNgm8kdLxV^tRd_=wHnSuMw`%HGXv$l2rz$p8yul4s{v9!@X z78x0E`w^?I@qP97@@gveNGza}-0+x4qL~SrzEvgV-{ZYRFWTC4b)bCpoWvzh!*pls z^7D(1oYd&@?NrmaFOazVVrJBUF*NYKVddThxPeJRHcxX2u`)iT6Z@Zbef@FqwKK%i}#&0kk- zMWy5$_B+9f(C!<=fFUP5JPLl)*wFos!+D%{>ymv54r0l!x}#@gXlTTt$J8OcWtLw4 zu{}Jvm>$?Kd}qsLCZtP{QYCn!J-cR{a3B{3H-C^cjf=4F6T{Z=WB-Z?EL)KGhlSwF zxjvpo@8Kh$%HB14Q6|KI-|2h>)38)Gtz~0E`#hvp9m}SG@ZIfy9LaEdv z&cv_>ASV9Sa)U5Qe}I2S<(H^UH(j7)DHk*n`baJ0&aC;L%M)Ev)LOJi>JNr_2O^r_ zE1n~6wuuGKIG|&j)whBsX`l&!`xUU&5^v=%85TjYRP*4)7D@1T8fMS9(0;cHeLqGd zs;r}b%y1G-d{xcti%>&u=ViQmrdPtcpE2Uu-|CgR8cnpV(hsC8h_}MshK`$d@i43t z!b%UEZqwv7O&E`@EMUXtOrnp>Hysd4>^8?Xu92T@uBk%HoAu+)svqjM1Z=M4z(Qmi z&nzkt_x8R2z{E1Y9is|+KT$JV*~K4xJ)<%ku_!M303(k@Yz2jCt}`3StE4J>ipa$EPuT%c_%wq0lz)S)=ppP zW&N4F^4DN=N7bJJe1aLNN)B*iFVmlGCo+d`OVM^Dh}Y+ji4JvhKCVGF6MNb3`*HPV;%Z$?(2@H;l)Ho0bWNfJ5*{sS&qKRToF>ma=Bw(eo9T!Bou>dsUycvC&Tme5kvIe`Nwy zG2|&pfMQtPOg;p@3$0UXvmdzd_8OZwPcY)?e5Qk2^Z8_GA*T&qE`RdFLDUa3t`Kbk)>B(TLU5NG1hS75aIJs<arIpCnRmvm^^Cf%XmlFvbQH z{AFR7FrjwG4G`vGqt))6+~n)Xu>1%lr$GCip|;#0WcPQuq4!Dtn+*KOyZmU^>6oT; z?GSM=-;R#4>I%c=Kn8U19rJydi}3lkWGE`R#|XmH2L6DFsJrd3cu5`ALbxiV z>$m7j2#DO7x4*vAuPo4i%cG#q{w4T#e6m2+$Ji?c!c0fQc4IAnmUzG$Q+QH;)ZN)h z?l*5=@uMx4n|UD>rply%i>Zq}!}pA-DzwA7)JnU{g6t=J^6X>~^{m@5RZkL~AG6sd zWpD3*S9gC;#&qvA1D^R|tsG4af8|bjfdrPj3IEoM`(^cql93 zXhKhd=)+i*yQRP%Sw}|ZYUzuA zU|gDvc3O&vrL&Vuj}1!=a+m70+YA0{*Nh8@c)O>+M=fOES5WBH(Q9ZdaZ4Q~|58`R zg#7Ipvq|h**R1bH#9zPVC{w?ys6*e1U&!4LY8wKjgkFd`?8VW?!VZ><1cJI{&qcYt zT9&eGc#JxY`kQ|MYB+`DL`ZsmEuHFnNuF8!D|?>!x1i1Ru3c&DzQ=`PJsE7BuoQY< z+$595BO52gOaQ`v8W_%&)P;nxGHx6MmUpBpr@hoLb|3Rw4i2&kd70ZG<8hS`6XaR9 zM3f1N`lSyvwAynI-&$DNb2Qn@ZG%;D_4)7kJFn`}|D>Dyx#=X<0Ltu`24vnvY)Lnt z4n`rG#~)g6oJ@wM6E7?h11>!+N0+sxgvNcfb=uQ&>*3%rO!@JVD!j1Ke>6D@^| z6s1P~@pG(L&fdUJq2z;D@4urAUkhY|M|XVyQ~DMh(jP6l89KPyE*;n-;v*|mV|Df# zCmrK#b6m7Sw^Dw8{}CevAqc4Vc+7|M{PpNO^1z*gG$m`n1d3ht=t<6&l(obvhp&&A z*l6qjY)iX+VFf*5fmtH4V><_aGAl58EpBtKJE6z9i~z4Wan@`m(6>-SA{}IPQqud&8|Gg+c7Iy*6x- zbK}BIWltSYkCzZOSY7k>?4lZoc|t0JP=uMDhV9+yTAW-hpf!My7%#kKU%T{?f1w?e zYg3J+J85;*(n81#-qPM`^VPg<0#;bv@4-S$AFDS!LI*P*~yYwl*ExQ!&) z-4G>|?srrEBC&?NfVRstnb3{a4TJ8&Tp*e^;(}h$5ZGW3t2QP+c$?=-p3 zyoJML0MAm{%=wPk>6cQf@`!38=WYEwPG2Lf=NQUF9|q5*at*};y1pc4Ob68He_&ce zc2ChK1;4+Gbq&jmosV&l-KGU--JREWJi!xN>S1n2hiKw*o~U!p_H5)Smqe1{CTX3t z^r&~qn)3PMew$L;K(9@$ERYhbtosz*mkj;KlSE0XE9-%kZRVJoSM#fwTvMWOF(Rk< z4(;G*VZXy;D+hlD7eX{Iswd~0mi4sU7u2+B6`*sKuk9@klu-fRxGIdATGZ_|)d5tppEK^lWbxWN-WALKPOc=> z&jwvrOf97v&Lm=GTzERI*yj@ez?`&8n*IZ`O!{8B&To9#GZ`L?{xS$x|Ay@+C9S0o zgZ;T7fBaTk*kS@C6XI(3m#>$Wov`jj4E1d~hU705z~>X_b^B4!ZpRy4Z2t3wra`J`ITpI>O_@} z*)>?!{3_Xb!L>rKqZrA~v_D|&+%_(k^6lDf2O&;BGyMPdUX}aYlaXWv!MuDWX+(*Id#&qd_Q`HoZxR9A zCuX)_HhO8GM8INy0KjuymqsDt_C2kq@(t~9cb zZ~)e5s#v9B_Nm%x9!;I4`@0pd+6_9R^6Mx1A_$5xwEg&*4PHSQjqi2btr764wgwny zx;KB!*qjCRKd+veA!LP9;l^HWR@%fejrcmJ{2#X7GAzpP3l|;*B$e)NX&9tSxd!M4E4I7HowfL4^U<4|2Io?`UD7X=Mvr;{pyk7q}BzljZ0?}ggj?J&%{y#^* zbUgMySwFRTjEb!M-v=&EH`*PYLbhL_YTUq~(1l4O&cZGEjRMmk+ zoL3ZKIz^qfVl8*oF}lWXtc$s2Qxyd8z^39~2A27`BBY}ZIa+wHJ4WIQ2m579i`tr| zE0joq>PDjeK89~MG7_u5z;`4_aPzxlp6nrY>wMie@g;*(Lbf%h$WsYB?*)UG8&#G& zYMIFRIr5zNJP+c*v`_&YA?%gjjgsSLnqeziId(%d^OsfJY%dHy;B(_tg&s7z|BYu2_?lPO6i>_VsrLjd@XNEh<4f7xd5$i zdOui5mgKGLc$gv)L7#Z*{fxg5_~dQhyaY@6*3C_4<`YaPXs*~e*B;9_)0PUN`)~t% z3^@}29j|G6i=h_)i=0Pcbq`XGX>z`oSUxXRUwbgf3S&MprG3M}WfaR4g>4*J{_3z? zIxB=E8fkYpkooz_v>Av4%)l7L{j)oWSllhV%+BaJRJ-JmeHRV47W)(5(NfqRBh5+8 z9G=J4Q8r?J^TNq9I>Qm~mXsA5god1V%2M`=-9@R^^$?JFvKK&{sq&QS8n!*Pb9TwA zTb?}*&C1HGq*KfaZ3Z9!haIfKLs>=Y!c$%@-JPyyCtzCI@R;~Lt!iJZ>5QXtGWj&3 zofXOL2ukPB>brq2aoYnFXUOp}7b}LSKy4g|Z%|7_ai1Tivh19r8TL)^BtEIi zUZNST9e{3o^|~)W;C*89k6**!r*%xb8?zh#2p@v^~MldyTq+$gj!$wcMr zE$6z>oFx0u{OdeUzgyxg+qwLrvz3@*en9W_6MmNUY{mB&$IK}*Wam7!hpwk4W7347 zdlc!g3(MW!(_Zsbdc}4(ECTyBh37gFh{cLt6tp3x?(_&JI2aQK&#YLQKPltFpQAC) zb;xv6O4s3*eA_T1oCHNCnBuOdlaN{4#QVm+2eXCw!3yN9H0P>~|D8^c*NeWxIIvZD z-pt!^mT%OwYw?~~{;@*v;kELYo7oPbXDn=LD81dXXRj7lm0F;H**e9V0;8|k{F<`Q zd4VH$LpZHbSz)|Q{ss@efE`G9&T8o~nVSlkBSO)*R)6|f6q#>`(cghQZsB48zaU|a zH>t!M`-hM??6e2ZuO2I}Afz&>N`npS$P%7ioDXfDq)JK>r;35kkzgqEjqq{$zd9nq zl02}lI+12O7^@@(l|K3h;H}>)`p^+BAQfPzbe(@wZym#p%y8cKebr7&qx|#@Qj86F z+u3PvH5C%|O90_Lo!TriLdk5xwxiX&B-!9Knt^X^mpSKdwiTJLnJ{##|Kn2TBBa*J zOpzN0-l5TbFUXO_*_{=qOBblH@89~@P2jZ4Ffx80(KqF6nl@fvS4h%ZmMGjwll_49 z!~T8WP)%Rz0b&~Jz|O@fQu@$&`2wWR2=3)(#bu^PjY$u2(#pg;alzE0!bXwt&4Q+A-j7d|4R#9t_x@H?TUy^vo2_f# zOX!Y@IznS2qva%m1J8^k+sa@)=?UM?KiB55{s+@lS!h}@;^g%vAZ*6jT}iBH03*qL z@^7B%O+LwU{BV0}7q-ZEniLT%KA7mVX6Q%9a5rTcbDd@piuH4ql{}tTJp?j> zbTP}a4k34r(cB3YhTarrx>!}YolM?NV;qvIZ+lOI*Pq zz!EeMBra02cqgr1;T2!0A*JzARsT1vqp|oYqFaP&qr8LL_Ql+XA_`3Nbl>cRMnCkD zbqUG0iznfBT0E+mYXcL6#;6uAm2~v_ho`!K$$yTvMMU0?98IT#!gKKI;o$f`hccxT z{9+|Q!H7wUZ+g)E`{=jauq7OcVGD*Ma_{q1Kg53wEzHObMljx{9joZjNXJp|9p0d+ zAIzG^#C`v1=n4P{!ahH&8hwu)QOMS^7z2ajrHORCRrqKr=8leMb-YbF-Yk|#eYO1} z+o7XqLVyX0Yav;EdwwZ}k2s_J9~C6%>d#q-N1dj)X;^YaLT*z>lb`KIzdJ%VBdE#az>?^AtlO*=nkHde^r*?BZ8clLio_^NJ=XRm@CPavz294+&hURIJX?sHS}y>l4q-9 zTykt53jQq+_dDj>r+}AnwZjVHh8B*jllO5|T=nlEw{?&J-yWZ?KYgX&`5b`YG0p{E zZ|uJSD6_u-#9>G&^2-mPbjz2ca+w)RN}Da$VUq`Md4_1)@9%WE&L=O_+9%&^EmjF7 z_wF9Q;Yixv0Sn~h#6`Q~rY=ET6Pw;^&8MzPRM?A?T20gLmHG}SN31ORCRJnh(~+l+O5QoE_Htzo zoTlHeXZU4;EH=Z9m7U{za#EiG(N;iUJ*g*{NW+dv8p*;^4Ysxgx4MThzK3x)^$-VF zk&4z@-l8aQx!sFVChnyB>TomiDp9`M_HKSXzv{HxP}g>{Y+x{W>YE=&OlQVhvK$N^ zC@ULRxVlCcS>^niSiDytxLeyS?J2Aj>y5?P|1~+`qxn#o0b@dIpM{gF4n*h%{DIr6 zFu~@Q=_iy!cI9BqLsS>av6wX1t4aW_}fR*>jzdh;y~ zX*RF6wRTWl$ z*~)2NSG`xakN&9SW9lOaR3L8}F4|>jKYxSeSr<+1<1)1<&_8mEPIpI~IK&CrW~pNI(jYd^XiQJg&_(GP=gm$0gX@GF8b`v}=q*LIh0cI&U z%ut9Et$|_>O;z77p>eM0WCP2Q-KVkuC8N(kZ!GlUDQA@30N0tW zSv!_XkEWdvN7{}yjLypG*sh>Vt}Hjc`>-m;FGqB~luY*BYUr=79Zy9ErC98Uhylq# z>cm)f$I(6Z`poi*Q*rG5_RLd;M6&`5h!aZ_HBoUdR9WM=VWOA2uk9XwtL(gT7>do9 z?f`@+c@j24OHL}d9`2~o`-#|UH5#A}1R?WL$ z2w>#q##p!g1$gq^K<_6S*gdPIbg8fOo&Z2>QnCO3hE+CMfOWUX}BECkK?3es(356e5W zg+ujFKW?BmBah-OObVplitXyOms4YSO&fXTC#*52CXo815hc~aj@a*{5 z_<7>*ELrX?sW&6TRtldN1ozaxa}4*!vNMi2lev1Ozg#RQ5H_!zIa-D5f6AG3T}0QJ zfk)gBNtif0gOAD<52wVMg}J{B^H~dM+Y326CUmuf_eQ#>hv`v>UXgsPcocNPmWqDF zvo~tW#dR)gTZ)*WFe`t*O+un_#}3h$&-7#lJcQ%=2Foif1~mowUu@94 z27lnqTK>l7chwqSRSWA7_Hi?~$hJDdkFFUV^|TkX0C4p3hqEpIMo)^Um8|OWr*CzYyRdB|83oVHJjmBK>7Ev zO^(msbx$$C7Ovsi$SpK=!vt$7Y#Q(l6EY3`$~?-)9-yUD0(!gj9Xd_(MlW>nzSDN| zY4{6A!Wk#Q&7^aHI)8$+@y}%$N;TK{c(OvXa6(7T5;Gf>HcYk5JT(W^(}$`sN8xnU7=Z)clYN3y_g%}MlcO^9JJ-ltuV*ecW-HS1>936 z6z89;;)2jtp#JVjJmw(-jF1;$Vz)?`DOAyNbv&K%XWf*qa#iuRG*RS0L<$X1b^V<%! zws$2T|A!MmaJael)x3yk^||m@%CgHmZA)$4zK2{OCi~klZ-#1WpWhqz=_GJZ28|`z zR6ZQ*8dyh`zdY+cwp@wo3NA+rWABuoeas0cVT<91?*7mhEp%&z6hSyZtBY%F9Sryr zbe{eJa?Ln!XKaq=Ta6w%LrNaoUAyg=A_*7f6Ry-je=?ISYkr>AS&NID{^n`aplmi2 zK^y5dw;Co`W`vdK=}1sQj5n7<`>MCx)^R1!12mYb9CkRt)Eoi5$Rvte_-eXD&i<^D5;8eS~sNi_XNQx($pUL1x zDCfrc4!A6rU~{mzR${yYs(|vq)1~9^4sizAvq|8fwQils&_B zRcW2{If_?Fk1c*u?LnQioW-I(Bho{(v0NlXap}$6KmuUyy2ej%XhFa@OKE2 zC1|i_eD`HdtKZ#F9rmRU2dV5Ro8vSPz6(zGvS0;w@RrNqrjk5)yu zogpYgJ@pR!xe?ZsdHVwq7V-2RmhvpMLsYyolB!E(!$>(AN^}6a&pPowHR>2n<_W!_ zxs<+9r@NMJj+bw|UQ;PJKF=|oyh{5X-&tJ7-u9Cpg^TFYXcnp)g6J2G;p=sOK1?-E zAEQe7yZlx2ZNjgRtUct*nW9ErgpGzZ68SFu^nd!b|869?EsaH7`CVhih7#Vz1CH>Ki*h%})CiJ3`kD*Gzv{Vz%b(aA-Y&+-r z7PZbp)fl?RgL7=zExI6Dn)h3j9Uj##LxbfCG6Pptr{7k6aNfwGiY>Q!tKk5%W0lV% z*o9R^Iqph|S~TrGz)?(vnicSaz0IGSn{z3exUaxUI|S{*Kv5A-CY3!Y6aap*?JR2w zl3El7x3+b}xr?!hwX4RmfpMU8rmxePQ0O{2#h)&1uh-s@mYQm(Ze9t+>Ja8N8DZ5P zm8%D189xc5twAP4U@u-sNBp#<_D#$C?kAZxZv#^* zG9f0B(+R%8IWqH$^F7RWc4<2?w8I$~uU9vvtkmmfPMMevpur>pVDA^w8J<4%mqI@@AMMzDu(pQc& zTH>Eq9PpX)lWa*<0k3z=epL6lMh>Ij`vz1%Ut~H~iZ60f5!_(~8nV=gB-G<|`>lBO zCgeaY-GJ{g#A4Ax)IPt;Ibv%sL2dhay_g<5J)(2q;HX~k@a@$mbCs9N9o>uJd*lbng!L6w6zNe zMGJ?3iR=e6?JITpN7>044Q*7EG>4Y*!aq%%Nf_N0ZfHLt9W9WYB2ZJaxYP#(=R&5k z>^%#kfHr8MfWSSANto~a+9bvaeMymJ9Kcnkgk@d`20Ha$Di(YeWwW?$fY89c2HE_ zbxn)zJ%5YQgWn`gRxb5QDCVM!k2RYGe>4;MT5Sa0X`q^C1PlP@_jFI3(IfPx$ikEA zz!j?3DXF4AK+0O)1d3`2#pwI~mE&MR9$4aNjoP@|`|F&4!4P_8aQ_2f-8U@RpCnf} z=;0|A;;tDg>DlRwpjrc#J-rxUgExklUqk6*@0RMI5%kO;^T`8$w`20eiPcsEm z$)})kx03#Y_dImLL7EHYbKAxoct^j`6Dc&eajf3AoCgA0L7Rjqp&i7VB6NTk%7g+x zpT7XOBY*}uGabB+dxGw@bq#B;*pq`GJBCN8{mvAEwkN=}BQ&VRKE7{0cz)@yJ?Na) zWKr&>M6lh+gE^s;0R3>kq}TCdGAH!_znk^T@g%IJ>5=X2+`PnzQdV*18q`~xdHnZK zkpGw4g~@%VJXK()s?))QTRM&rucB}=cKa3na@Q;4qHn(~6n1jJX|~1`_Wt(y?k-~y z^lYdKUss-}W;OzOn!t$Je~d`=25{$SBr$|Fi&%PwShohH$mv=c-fv2;(hB*JR4Vh( zpQ2MO3D)HFIhV`#tUuhnFS5q={5mw8(EfgU0RL-W&s6FxFiCcdTx#MC(5!4;QYvZ( z1ef+WHo*H3%$tS#fv8%~7nt)&^JNaU{lA!${}*}V|2U6XZDRCdx6dpPVO#!b%h;c$ z@HmeaDm_`W*Hr{kt)LFdK|hR5IOgm|bgeBh>iL@!7VCRoId(9eewLk_4O%sI^veF@ zgs#08-!oQ|APMt#SI(#s0gvli)OlqI=?=}?2OmrFd!tI>@z6lxAJqzJ6fA?AFB~U!ZB(A%^;#=_F>HiH4tc<`n+CDFZN%jUU295iyOFJ-(ST zWs+Hv)oOQbL-h9@;EobIu{MK$0i~^&l=L$=yFMK+)SRuv4ktjJrY_~&x|Rt3;|p}) z>NvruJuqt5TZ&nnc~9i0LZhQw936&b6!WFm8ZJ&)hYS0JE1lDUuWL?QZI?H!vAZXpJt*;TXfu*mRETk=SFSd7uTe=wA0OwORO^$Qv48RuE>Y+~_|XEu-i2bccy;n)T&&$yJS8)?97#AI(it-k?0iC@jb zPEvqI{(*BT$;FA*=cw9ZX>J&DUoS=nn(VDkCC-2I`z0H#br!WPy&X>iNY%4ldy@CN zVuxiQF1fqA`nt32?o^BP_cqi|(h~a8x#?wQ%!1`h84dfuh9$FIv6ieZ+3AECBl>}X zIjMabD@*F!Yw;w7Oh9=`lNSZqrOH$#88azb0?yIjljh8pT-3NPE$OoIDLc2gjsPw0`6A#(4 znP7IId9I@meMtzYd@lUFY`wy*TlvC@^br@xjKjl5lOCqYqy(aJKS7m!S-SW>>;80F z=5!JHv&mKQ9kq3`WEUc>-sQZL?!=iNR)%oscY{qwzjo0JT2@JBH2to*aah)Yo_`Ailgw7)uope zrEfP4J+*Z`#qCA1xn5w!Nt88P9?jy?tEm)!O}Y}47rt+LqFw@3b$IW`6xgpBqxG0+ z5EmT87;OTCxU#5}a%WHSyj`H#lZi^*;yOzi>a{2el{|A+pn~-UHe5Y=wv}CvNqail z@aa=e9%Ks`zvW!QY5Lq)5d1-T_T&zqAy-V} zg~n*|QLNaoHYB+jiQI@g>yVg@3daW7B&|kY4USP5Z-&}u<~KLR7k$%4#ZxQw_A>ui zR<15D8f^cY9PhUe?1X<>70;V7CALYnJ8IHJH|i^DlVcTJ@RHS(s}SHx`;y(@I{z17 zm-!bkFe&-+7jW`y1bI;q-$G|M=(%T07aBAz>WG-ou5V9}vxr_=)Yko+N(jM#1wST5 zlFP2L78hG9!}SmttvBP|4!pe5Rk5beW9taRCWe&X7&&(XyrV78-(Jmgo9JM}|7V_# zeg-g0xXxEdtB$?%<8^+diBlzZ6K_17b&qjXU3t?*f{bHkw=MiOPBqUm14K**&7UT* zZSOT1Xx(ic>0(*I2Gh}GS#s#iej=KlcXp&-W{$AtFi7`)v=z%jN4{FJ;bOdVWZ2o? z?^k;$tIqj1L!E72gRNsl2V*R!=v_sw5Ad4u@ra)wiN%u}J0nf0Sa>pX^WL&ZREW%N zTYLI_GR-gTOs6U=&-B%~S1%>Ag^wT`%+MOAwvd(ng0aKmZ+cd>=(Y)?dW!bfYSR98 z^q&x*LtSk)BVaU;NweW&rhG7Mhs&80Fe+-aNr9h@@{r{C8`5Wp>OdFA!2<4Q7^BL& z27CONi75D%L({;Z;m7-+a$})^fOS4|-}G)X>#l*NcRT6j&^WKy6rIIW(o%}hwjl?n zB%eM|cV*XI-)4Y-PxJ@cq9&8q%Y`e+fN&G zB^9ZEO+O4~`kA(-6Y9Y=6ltH2h9%p5B#ubHlHigekAop`Sxvy=8K<3W4DC&7u~*ci zlWuL3iyOzY47SFOP~Vj`YQ(>)>WCF(`JHNA=}Mr-@D`yXqR`E8^0X*`-NrwYGzWVH?y?JVdl9Vq{B9~`WN`fgZO^z@7QG_SuA4&aj z&4i3B_wI!}Pw4zV<$*!?P`0-E+G8C%0WayvazheDmY?5K_f>TjTx3K1ngHgI!hoVd zMwsT-uA02QTfvofv24qnk+q)c`!rz#<%gv})d zeDYWLm6(&t(wY9J@|l118)N31Nn5+Tq!FZe%R?kT+Ob^D>&GlI$SC%K6UfsZEC3$Eh3~pBE3H)E@M)7ZcAIeMwy_6c4z+u(A&Vsop681 z^uBL|$Pv?Zbl7VR3?$;=nG}05aHauW z?nfT@P@lN^BVCR0h3;4c#qr|K$=b3@DV01DpDc4^{OkizFlnSWA3<$KPvs4L%!mso zD0+-;x##o$(E|JzB>Nv$qrw~TmBrNdDy{DLQxE6>y?PP#&OVPcdVm$}tUS=uWd>(m zGj9?s%$teg{Nv#$wi~HqY~stw;x`CVvC*#_7V&E73$wenKBtrZ(Js;J1g?7=U5%mhr<~QTJMkbu)oP!Ivt&7v0h2~-LuR7J zNg*xjc7iOpvcBUxV+x#?H?ObVS?}r+zkmshSp%R;|iwmf#s-z@dA_ zW7H@rqo;K0rH$P>NfdoCA)B#g+-*<(W|7V{;=E4l17d4ikt?a7k+IgwV@?PkzPdX~ zfEGJ6Dz&N+ng|tH122R%R2nK#{)u-Wd&4}#4Ik-h zC(@hwyxOL+eSPx=+fz=)oFD=87XZ1s@A5K|Rj%bnImC=S9dZ@$5peSftP!8pnK@o~ zo$!A-u3+cEn>~}QmDC%`G)Zv35l`VUpaCPaqvsBk5?WE*i+`z4lqO?6;e<8EnMjlSM|ey;m=Oq*T-U^)O;a5{j|!7 zMJF1bjgiAy-jvfYnpcR~y+cv=my-`wLc``&=X{sj&Og&of7pHS#{PhFLIvcO*#MrZ z6CwN&%vTY#khqTr&2Ur5_U`sD{A08x&38VY0Ni?+RxI?Tkq6ZUg7Zx6=#2Ne$5p=m z&P^!d{e+C2ONnHA_#qlOa&@p56MVqmZm|8%KC&edAytj1uld$pGQ+DmqLP?fhJtYQZ@Wc?Q4SdjZF{z5Z<~EVxN*H3iIhx8sCc^@I0z6mFCZEW1aTr;yb5{ zhf!B+gO|VSSzc(J>=w-HU^HGAdDxFU z1vW&;@3mUIpP|k;X78TLj50&_tSaydl;Ihi4}i?hPnK)FZGiVsoQMKJpI=%_ayc&< zOu+XHw?hOqS$d2)R>8!ElX4ju%kr9)#wjbBnBo^zEtazkPPYIxEZF?7)z5EsSNMYh zW~;|vKA(5-_K8#j295QMj8}yhE{uMGn8G_=_8zj*z!E#5`_@gl5!Y3L%21pz>NwR~{Tv(Hiag!63Ak;G z9yGKqsChu({#ZjG7YrK_lCp1=QlhT~O~p#S9yvcl`G`+0`tgDEg9CI~#F`^Lv~#9) z>C|3y`^|=n^l!`M7=^&c&~nnQ0lfiB#-|77$)7>C?WA4|kT+UXC3g1^Sx<&NShAoN0I_32hxdvV}c$dUNRGE(5R zV4cG@Q4ZH*Oy^Yw+MYRPOQPttxtTjr7lmrZkTsCtC~d$yzwh0qy<(*5>W31|Q*dh8 z&sVyh&ae;bEzF2x!IfTy%wJcju}l)(@Ag9+WZ7v#_p;kBAPbXSCS%&Q^PB$b74_J)MeQrmz7YRlEF`Vo1_QPw-EAX2kouxO|tOE*q&N~j7fb?N%()n*3%49tFfN5DA{UsIapg&ye!d@ z&8-n;E}Rl$bj}NN@n3#c^f7BS7^#3Ou3MI9;*895Dy#NGrPBnA-ZEFEY9nlPe}g5@ zI^Zf9Q7bJ_a4Cw!lmb8^_RVL#b5UI8f-m(_Kkhz*zIS~*Et zl;=BIL{F0^5773vUy2Mm`>HS!II(i=&hMc9G{{{ogQPTC;|}5L7vy0pJjL@4+Isx3 zqS1x7UQ;XnR^vF++^l)Qq0E9`58(X#e+)&UN8>*4>^#L14^n43?hLO;+Tu-s<;pJk zrRmLd+-Dz{lPeo_s?69Y^qljm-FlF%S*zJKdWE(6pS%MjhRt4EvpHIDS(tH?#aPlN zC9L+2nMIp9tC0+tSQ2`jw$-0{X=;i0&b|qRU3ML0>GKw;4M>u!Mh5SX5}axc#?^>P z5C6%|2bo*8^q?-D(3-8J+@wkb{Za336xA$yh{_3PT!|a%#z&gwt>+t<06aaqIuP>* z{V*X698VXB4U=mA6XNoV`qg(El^G$KDp+_3g59^bT|m$JvTk%wcLT8`$H4Nwb>dc0 z+OC+2Mzr#OPU8PoHrYNi1EBlY>wJN{#uy&D{AQ^qxvs6P++7YR1X(IGr=N96`~qy5 zYL>p#D5fEtYrjjJhO78%Lgk{i5VnlkYgByUGm_?%8va5I7w&S!jUkVDc5 zciVeSTJ`)Y z@D@E7m0n!TFXc{0t6mKoh*m6!NM(r&?U%~TNo)tpsuX~k{v4HT{fK7diT7#$XKOZ> z(wo9dPjE+H6U@6AktX!ooJIumcrY<%EUJZ2dM28v!3rqa&WhbW3;oK3o&~nJ(^5YR zxhZ8j6yCTqdS(m{(L*{wMJ*sTT8tBzgbcpyF@m9cW=dRwrPPFsI#3`bU6&PJRyh}M zcl`=If>B;hmM>jhJ9a5TE4_}P%Ik?iutzVA^~!Nf$MxA~NI*+fL^;%3u$7lQYd_M@ zc0P6Df7LDlQ8-fKN5LFymHX;&;ji0IZxg;G>&as1l+lBiiMLz6%@e=Qpl{LD3#Eg0 zM09q%B?|UuTY?%Q7I3nZjaSwLXA)5`qgU~aw8>r#25-jDcMUb}_U~yAD7xC4;;gO& zO6k;$AYzA?DbU0vK_jL#ZtS+FODaApS-J0id(e?yoFnh>k0Q(r)Q|ejO|-d@7WC7x z6=&NOu5V&%9Fw@OK?yr;Y5l&c?@B)v<+TcTba%OC{E1-fDOrHp>^3!jT=o+S88e|e zpBFvz^pxZjW?v*7H+H;BORA_d_w=M1+21u9`5`vG}p%OHZTU`d)$^o&&$3lDldxhtxK9|ve0-a0yb^&N9NmBP~`?FowTJe~zT1sUlH zdw~fJ5PX#1c=V4;`u}FR|9hYR{~G%s&3=BH;v1Pz0BPJ_BCd2@3IthI{G>_$6jRPr z-B(H#wCe51=bonm6ev~6=}ep7_OR50u*SU zIlukZhQiWM#~SmC;pz6qWlg-uWD*bEt7vY}=c}McbgT-lue)D5VQcqCFGt*pnkbdOSaS0BPsFs$p7?$T}Ex-87tw#8pjOfoa zqKH$FHgSqrW)?9+aAL!Pu3&P1s+i-_bfi1Rn=Vf*S3qY z$t^3o?g-91(Hi{ilh~|-C7h|%7OvF*e?tT))spZYpy~^4W>ZaLrv+0&Z0(yqG+ie~ zkFdb~pXesAvc!m{i6td~58I82WiTqC^Y1_a1$=j!AMAM{N>L+*u&0M1#jl@E;KW_0q6aElv*D|k3vxg;3F?H)wNF4?tdc9ks%RU;+ z$fY%}$uxGh^!!@iRL8|gA2AB?O>V^*rb-YHJt}`KaVyA1dOROLKLWYzzEpdb%%5sa z>GL?EgEO^ly1mGj+>w*+j3yHW(o`dj)(tEy2IXs3mlW#yx?_SBo)-}EsbR%G=SUvn zwTU2g_tK4z?p)rM9WLiCkmn{LyZ><^&I(%@5_e%X-7f%e4csunQb)Z+~$f zr_=@QS&>@I!U_9&E6Xz}89!9E^5m-2y*0*fPW0f0&`IjP9}&xYpKmpWeVYFQ6d#Ap zz0+6FWv8?PyWp&>Q{MGWuDB>lLX%Hxj(J`YEyfn8gEYD?l%ad*PCP?E0gLTBDAQRr zd5&Y{Mtn}eB5_6u!i*ikb1*FRcx?0|V(P{HNhN{5gS;0x>|p)Y@X*IE$}~V1(JVp-Tw!Qu-e25{#$f_zxxoh8L*ya zyuQo+vH!fUA**BP0{erP1Pmt@PwbO4{!#$|o-4a=14`+f=B7Q@F^-;PheE4 z#J>Iuz?*ycG2&`pO(*?zi-x|TTUXz_`X$RWV{%F=Hv^tf*6nIT>wJ} zVCbii3|uzCzFYRttst(UyDad=J>88rLFSPy_>#bFs)FkWPaHAz7u!$vZJm)fcAL$I zbMw=E!*`n(CQ3^lZ@-7|rHtP367z|DYq&4Q+7s&|TPEQ%aXYyUxW@krh`Z&=v^x2tX7bYEbV{QxNOV5-lAU(s zjAZU|fAQOmpOw|hCb)lX==Z3%jixsvoF|)Ql_33gHgtV%e&}jZVp6Gt@#d0DN7{&> z%p03$=pbo;7=lnDMixZoj&?m@?DCz`)<1mMg2S|CE81?#$VB?}GL+RDt3e@}+}egQ zHLV26t0wsm%rHX-!{wE{!Hb~OGiUTw{VlKWYvi30rGjjo;WgQ|)==BWW*r1rVGQT3 zj)>nl^s(yfF2gTJ9HiAmz~AKz`zcb{2u}M7iw=?;eG$9RfOOGpx0{_psJv+UyGX}4Ah zQ$rK{F#k9fIIE46?00R{TPUkmE#s5tGHFrky~NY8eS?gPM)L|sVN5AT{uJR(83m7$ z`60P-egc@>$7w`3fs@IJfulH9q)1iE_B`AC8Xvol&JC*R_pa@iwu;j3lCR~BE+8cu z8$&2G!f&%g;pyUZu4adP_*hA|NPY%L}t?{LcmCoClf$$M=*;;^?i}}##Qr~s4Tl%pu78m3{5D_vja)PS z+K+2|a%s;4Dl%;~Dl9pd>UWeo*~*PCB>Ul;)D5xk{;aI)t>CEp=BErnV&;RVbfACm zMN}#wMh8?fEx}9Gg&wCxti{VkRBr@p99A$ona76RCQgnJ~UG9Di7CYJF+|B*A%PyHS>~<;-+G&l@ z=^8Uq_VqdcA;oPdXEaiBfTUVfqLGx$%v`eu^ z`q_I}f6A`&q>s9nFx|4xUL%?C zKfGAzcS(MhplfPMt79Ik?^Cu|dyDJ5`T<$PVEHeg+apq2rP2soFi^9>TP-RJuZsU@ zT6U^i_VQG?x74Xq=pwxSnP{R~*ZEbeWprw#^ixV;^9JtQry6CqX@dpZ*9A|i#|z|P zxS_FaYAI_>qK*GX@dDE6k{QEmel^Aypqn;3&SEjEGR!WWx-P8V<~~fGigya>6FwP>&m@M;@^aZ1CHDrJ? zEIqxK#FZ$HXGi-k>pY+;tB@QuKJmv&hhSpl8fC1m5lUYTd#iI5XY%XAEPX;a_3jov zT+<;lGj??T+Mb-){ajklf{>-@GLiyR|6YN7apY2DMY4Ff-{WwzU#vl}-vb25zmk?e z0Nmx+>dz+g4FH8z)^Wczv@-18DCzSs&o{q^&XnGT3VylJC`G@iE8FyxqVBL7uOjJH1INpBW_xhb`_vW=F*#!q!fFrp+Uu2ks9z+wf zjBc;n$4U3;b?qbJ&(CkszgM0wyxVpaDumbdkNXbSiaZ2>TC}`^D}X26Q6}8eq(`}K z4gVqy9qt%6dVUlu$3d%C@mSutFN@Ya@V#;>?8we zLS(5V?vtvsKboP`Iq&r$O{xeHfVF0S#vBA4@KQi4X4ug5Li=7( zD}J}h@gTV`Sw^AInL|V8dIqN1V~IG26gB!Fc)zT2S0zTFiv1-ups+AsH&i;O zw{DyVtE&Ntc15QDz7_D>zp)eFE;_lMJq9+1Di2i*^ml*KkZEA|_<#2X3g>#nTmmR= zTvFh6x;naix6{H`#bbW)j%B@uVZmNTLiXdl=m12x{X}v1y`dOQXM4{ckRt{s*pFt9mp>C-K&c&v_%7Ri-H3}; zIr(QGV81jvfRt?gt3{a@^GgA{z#B%6ZeL{5#-TN8e_yvVPdDtU(3|D6!_Cys+#z>2 z-;!92K05nF*=iNuiDBZa!U9#=p2yp1S6;xvHFKM=?kc}IBlUk)_J8@W|Bs&O(D~h_ z&m`XVqAIfsRB^ODj2V|FFxiJN>kty9riqGkZmi6?nT!jI~|w9>1)Ke~E5-P&6FV z@mBU{j>z+-1Is|65?WHGNTMWrky;rMX+xh|ZH{gvqSehXe1gg@U?D@NM zks7pUC?k0ST*c6>*z41TwI}%nlyq?V@v|528IlP}Pgd~1rIz_60T8rdyix#+vB1XP?UbPEL<_qAOPd*Zjt8f-{(QstkvvZBb{=k{7)KS1QKI7(= z06W6Gse(zr-eaA^46)zC$hjU>w;SsXEm5#)&&7tGmToRz5wk=lI^no12I16F!8CI( z-mS|A3F)Zv_xX-y+F>(4--N-PEOrgPe*cnJz4R2FlV7ImS2uJ)#_xl#0oF|uEdYN> z*P4^3ANgQRE2Z&5y`>cSzA<&}W^F{TlH`(12!F105gbkOi(q&Qc@(4o${ zImp3d9x2BKC9PoHAmY{i19}p*&5Aa2gt)k6RyjH$#m~xK5YktjdbN8<#pioi2g1#N zwK1w|Z)4t84=S5Brm?!6T-@LGX#i*(SalOs`GR_LDW2i!xXxsheJ)1JGCd>2qd4!|nhw%Jbi5TBda)A()Q?An+rK?jO5daO)2zyeYo zk^Fyjo#k6w>)P$1SbevXu_d%BcATDR2qca0-sqEWmQQc(l`u4=ig$1$TvC`lt%2+lE6oB9LoSy3z| zX?6|N-E4H|@1^k3U>Inzk83fHy=JCKtljbV|@)h(E>!|U#Lm85NUhoq@ zED8T95{eN9@wBhNYV(jUz!AZ!OPf>tnze3)`X!OCImzV@9L<3%INhKRr=C3>-YkBa zfO;Ct#1M%<=8osu$N~~2%ACjW-0pAo$QnuH%0po(cX8^q#JT41fT8c02hnIC0LCHOo=zoR$WA76Fg_k0LEq($>vYS$95t zCwxgKLwEOS9{tQQNpZfnBvF$pjk#IgLbtlx>-qD%Y` zEXM2^bNkfOR*n@D+bXR}Fyi4X=b36uCpi6+DqPhy;bCelEb`)%1&h37kN$&~hJC;5 zg7xV~8g=hY6s{GfD~FBcB{C;9RAc$)gO-j@Yu>JGFa!}cQR4U=cgLk~6(SDgMpQz! zQ1*sD9SjK;MC|3JD}cj7Et-NROk1#-WID7XcjTL8q-?MWWKHIem7m3>Lc^;2+R8QF zjZy6m1DCZQo*L@E8E@OgvsPuxb*t*M=B%|ZgXIc;cYWdafIEw4{lVu52qUra>61D zHOAvE7k7|VKJ@2ksid&5S`QW4pCocffYjh~idOrr&DM(UvKSL{H&bVP%LWoWcM@h6 z_$b<)Ja3&7#6NHdvwK^7W@JAYc9_iXV%@Gl#;f$ZLH0PUa zy6KSC5L!7k!_Z1L3NezK)#2VJZwl0AzLHE7shEe~fm7KMxY$yd0IoCYqjxZwi~!oD zUk>-%5Ggc+wQ$71=Ty~&ZZ|ip%8NFR`HA`{hIt|u%$txxz&^5UNQE!%(fAeb%V8ys-$F0hxZ@|grIui%T z7Ycc45c{eh&y=xZa@?~~&BFebu&!=#uFPtB9_Sa(6gF_O*h z%)7&E)2Mv`ysB5F`T5xk2z6Lde2kQ10i@qto?|(F3m8Z?{Z?%c!b?h%-s}CM`oZ1C zeF-{UK4mWN%^0EZ!_r*e`4zr*N}^!u+=LNF|DG2s%=4Z!lD;};=JEB_bh8}ARz>+Q zQXX(2Bg2_UtZlcaa^{KPQidvmXgc%NS~lE7vB8iG#z+K9AU zc~L?_q5+rM!wP_qzFsgj}XP+U?OTVi>C?3bTOXq;NDK|MHHvc1-vLsdZmlan9;PbMrV;a8&db zy+>wdbM#YWP4MD@}F9n?Ggvk$9VGV#2gxiM%$e?b_vN_@)K<^dV?(*%e1<#QioA74i(e2CK=$2D zQZV_g`|O$B{g?(ul5GwrjL?uS2fJa$nNl&ScO9ThB!rTM+oJr;EL@vJ!V7qd?cH5g ziltQgBFfkq2s8v{lg&T191D7?$mnHx3uq%Pype@V1=mcdQ<8gziOLMG2^Nk>e!!CY!H$@=tN5x-d1zmJvsh zqH;Is{@cIsU%%5FMOEJPj}$#Mb?|E8jk?n3wle%@|1EVWBO~2Rviwv?P$CbT zUbYWffuUV}r?NQvOx?AbK>0_w{hDs1N9XZPvnG4j^vAP$DZ|6YaD7_=UlW3pa>$_; z^?3P;6v{77n^_gIjs^eO( zgPOI=2a^eXmlz`7GfC$nt8iIUT`Y)2x&=U!nxMPBzOSsyKIep^RDH#Hdc0HVXWd#} zdQLDR!Iz^NZlvaMJd1Hi>*?vmGLB!Tl_VhHrT9r8PYkx<(nUCa?z*;YjyFTmt~+EU zNor{Yb^y=5!=sb628jyT%B$LZ=P%+7l3*wUq})-NXA`5UX%{dy5In4$wLK%$- zWJz6LN~BpX*=gi-vsa|4(kcJI?bUfW)aD|h4zRME@PHI;QhOP$RgEd}#cv`$|ShPQpwG+4VZy=~;!^w5Awz zHU&xmlF+Dm+>l~f`Kc>7Xn3qGhE1uTOk3+F4g6kH6GcM#1J~CkZ!zk2X zGp9-PcE3N)IbOF@F+eAFtzG_+Pu*Alwc26Yu?}3Rn^~vK?#Dh&A!+yXa}3@H`CEa= z@y!U#qN8CT7unS2rttwQYr`VYRj^rT#69C`9>Xt6M0j6MuRy(BQx@n^`mPPDN;yLGzFwxHSDQFqqfa%~w!W%53oz{<1!jbN_n=Ohu=c7(xS`2GcXZ){!-@)|m=;?f${$>6H4|Nli<(*ICPnmtR zFLH~V2S!>`_vs`LxcX>1AKi%`{J4dOWXn3a;-!68lRTDVQ8&-|k+J>!K_2KwyfOyi zw7AcKWH|Y2>%0=1`Q~ph&)b2R1$zy#rl3)05M4U-k0v|i?!`}3~uUj1T2&XTm;iEKZORYM2EhJ+oF}oRWqIteV zBN>Vn%B(kNqx@^P)&c_LyY1KN4mn{oAAe$)q!7R@ayYQ*eJ!3^f26%u*CA@n;b+XU z*{4vbL*}Sm_}ml#_DjI^fECjJ_>WQKFC)W$EwulVZg5|tEa|`uXsMFzId~njy-{!I z=t_3{ZEJ^}^*>fb&x;}kFComIA_YqY5dNpGlEasDCD9x4DEojkWK%*Y?`&opB$#6 z_co&|9wKL7;lNafh^tK4=xx>5oh}TJ+6?!+NOXc%KC+X&do5zHY*HzutBj94LSy;8 zWpFmg`9`R}7x=)x(ARpZnC%b3tCBCV@BgM=sH71s&HkLGtcIz}jp$o%@6 zna)C64xM-t;NoqOf>g6+JRaTBwCpXp6OvHEPvso@j_z=6DzMVtqGb{P4qU)7t$fLi z|CwV4et|5U$-RKzx~>8CbmYb!sWLr%9@S@H$^qvh+eSSRPvF<`e79-b*e>EZ*JUGnD~v8(1>idQ&K=oLDY=j&vj z9Y?c%TTusqLfaCH-Skzb`OPzb4fOUf=MCPRCy0@|J^K*9x!aT&EWtCi5K2tW%Pa9+#{a|ut4k>>FO{Yn+Nv<-bp7-fQmsK_IG}5M=C9H z93MAL7CBZV9>e(xxNNQx_?;avoI^%-U4eY3)^&#=w+l<`-1Bl2oRRg8%!O`WCctP_ z^eR2JRnw1YTqL|{R{eGMm8m7XDHQGk{?g?SO^`|z&IiJ|DdGiXIg5A&DqYid+vZ@F zOJr)$jZQFrh4+hqzc6(|$I@L+uzR>D+j;iGx6AuY=UlT=QZ)2>oRN&R{chYvz>MxF zT_M~;+7GcO%yIqGwqO+MP3iq1WTds*d)n8Zd%D852C3Rx6TgO4g7l+ByAwQ`{Kzk?l5L)jwr8PN*(O?@2_dt*CoT`{v}_|LvxmGMt4t#Kt*RN)YArDJ@E62dQy^W_LMpYi?f`2 z^r+Ex1uLHAcJjuR5x|T(;)A|^Q~{+c!5KUIwtYHp`xt%^t%q@)f3uH(ghNE4Pkr7tGBszt-__r?#}y zpqd_L3{BZcbl?7GUHDPd z((Q?8K)>7Kj(c&<8yYHJ7NNGw^0jY#p%+jU!NqjT2Wl{`H^73;G!(S9@y%vsO1EW9 zSi+m8z@dxBHwr+*hXh&zrt~fB2Jt!XYq}c9Qxj4oIpvE)>=PFdgv=f2AUXQ-Gmoh| z$?K26yDZ(ez)Qkn!_r-q^&FW|Oa~qsvZ-I?zF-sRbtK?k3Iu3_VU#Yr{YB-EBehb7 zgvjB90Q_u|59i8bd5@K#AsFXS?aSf1V z8nVpVT2Rmj`8S1eid(#rmR7FSS-)CUeoXW@7@#t3zwxnc`9iNusVP(1NAeJGw4=jh zlh|kQmy1rD^=oH5**Nh!A0E}X3SIh!f}hfcc>PL7@+6i*8X%0A0a+V;sU}g#owBKm zOOKlTM8?F8p^qci{jCu%qvh!YSnk2Ym3f-ApSwxxizyFp-{n4`DptumS$YBnS@GZR z%iJyVFY!-CyjY92mv-pca)p>S{EQO@pYl|Rzx{zj%{_du0}_qDktU+_WxDUN_`uxO z+U!dSFVw2GSfQkG&Yt#lgpC&IiZ94+fQ=Rt$<2(@<=1-zQzM)&^fo3I0MjhJpqio^ zy&zGMk2NXLq6mZjE^Dh&&Ozj+a1LJzW&`+|n<4El8hz9L(mGt8*H`O9adg-mc-kF_ z7)_m$_EjgMPh12`w`oJ9dyi4~)fL8T_Q!<7QO~7bcRRfMRV3P41cVenwim(?FsRe@ zQ@MpW_`Dp#;;I#Kz9*ekWZ4bz=xt6Cju`r!n-;`q2P9}JSG6QvzEp2N2So2%aC=Jz zo{hG7?k2ccACR&_0Dfr+15%PN`-{dlc()*VV;gkP#Fh!kzukakoE2|wQ7Hrz z)FT}0Fx&}xj>9tv#*~q5T9$n9i(4#QopGH%mK%|~jCfYJsLEIVBf$L}anW9jS4f!H z9HWY-*Y3`xC^7?j)0W}3aUIw9mKArKQ4qf>?Q%FI@}FVObbi0~z*2trYwf-!dgE&P zMFMV;s8T=H6jtrGA1h5jxPx5DJykCoC}W}aW24LA&bj)PO4M|JyX~>RO2euFT$DfH z;yMGR_fmvcNhN zA(fAkytnME{)wM}mF*VW2nC1LaXQQFf1k)P z3lg8AXNm1j`n}T>;1_yjN%%2*rdJd|ahEvbVi|V!Lu=sDWYA`2rWBP^zx}#C1gDF{ z4o5Kpu6Yxqw;5S2iX4U4Nqa85j28v10p1>p}V2^2%K~23Tgdn8WLtx=6mT$V=MD2 zT(iA1AD`@rvMI*CF`VFCkhU%B)atsw=JACUM%s@=)>pl8PGTA-CVB%psaDAVE&2Cj z=-?2T7LdR&-MYWCDZKVYhV|KD%FdlXRbZCm_RFcOLp{tTEU#nLvXJL#>)*FUD7Y%s zw?atP`{XhB$yWU6e-<_0afLof)=^78-S=8k(K*3?z8x|WsWZy7|n4kdUX{h6o zEa(z-VFp%x8#ZGj&#Y-pwv%96`M~q~1P9@jdIpK#UV#k_B*s*$#4bt{64)8Z;#gQd z>6V}1{7X+WVPXdve%3o=sw(O`_~|{~MHj)ZQOILbwzw!g2pyvOJ3{_%ORXAn>F=l` zJaL3PCHv|s`ZL6`@ z|6{ED#t_=AJ^ej41JtJts$KZY)W5;0Dp=~@dh zMY%6j(#TEf@5&D;<~`5nf()>k*Bby$YfFbvn54|-X%z|LfMbUBsZ%FZb(JMpWw^a@x*Pp*f`YIp~4FQ^$ zNC`X>0MNxfi`}ox9}}%@y=mrYN6F!UJdL$lQO)A(jc9+{@+a??kwN&NN#EtJT;NJn z;s7$d*dXQn36})_CnNd<#7q3$j_11Aj_bb1wJiIXYjjGCQdyA?RwWv%F04acKS9tq zwU4lpLeHyW8p;t*V)h5R*sEDrMlg&bCd1_^TzVP}o02sBj_4<*q$d9ckNxE`ACG16 zIE~wuL)tnuP_@nR^9=;_T~$2`1>W!{7EXxXIcX5_$+IQhzYVaV_xANn>huLYWJ4h8 zZ(3wMIp5L4MzB?Qstg8_P1D8SOCliSBf<;Ze@lhM%zq1oQPT;|PcKSIyfd!S&5`A~ ztz{u$VdzQc+FYLskL9zQ(6xzds4@j{P!LJJgek>68N_$xi{Ie_#(xyjWN3ovW5?IdET3>$t>W3(#&=vbZwVt=dT!GTX71#FDiJst;Azz`)ZdJ4-#6X4P&ZU4 zGi*+kyug0@`jL*NM3dwH9!_C@T|x@4>GjXdP58F4hU@vahxGdN@LX83&CQjdCJ$fH zdFtW#wX0FIk0=~Tn2VTGXX6uzOn4KP>3eKIjkc`7kk^=@) zM*_%ctJ8@gf5o~Yybd>lWf@@6fWJwYWH2IX2Fhdp;X5a=BjSO!c5cYr+ubH_fn5P( z&=6Wd1@<_DLu4380$TLLzecVXsMXvNnJao-aUYlVrw(A+&pn1Z8kP}AwU4{eV!Pfs=D-S-gB z(jGYJe@g}lE}IeNd>J0uk>%lKT*|&KFZ0l!Rkk`t+}#G3dl2mgRIOu?SS_ePcT2G% zGkk&{_GsdA@j=HFJyRWco|j{CkKPV)sYM$eKR-*b83kco{Ak)V`axigpLD5aJjv6l zY?_I}K6rt#3;LzHO{QXHF=cm|QJGv8gStR~=h9tuyQHa!u&SodPUb}5r1dQe?ZC6P zk<5q;areOXiFl6MZZrFghoOcerE|RmUNU~TgcFX34Z&6O6sD%iW;`ydQh5SCyHmc(Tf7agoBzxm&43PsLZMwRf{|EPwbFU zNjz@q=xcF-@+^*4-R|BhodF__bATyJK;4QVeFnqT1*t~3!Tl+$yUl82JjuDUY*OBl zmO-hynz?$dy2>+kR_bZbLaYdf(PGV^=0kzg9^@iQ)K7E>JcQVa( zMzD83z}<4KUZJ3;XDkb`Dn8xQT6$3vNlu_WzqqaFw9;_w7SxzDoLuY3AJ!d9H6RcK zN2VCSKvs`K7>A|stP!*W&dI2!obcvj=dH4@*AvJz#}e4A4g?MN7UjO(yRIL8&OY5( zH8`_HM_OzTb7@4UE{8?sA8^=l4J=_m0`e@@U$@Q;D2+YX@8jRKdXP*SC=hBb%)q2- zdXr9ijheV+Z3@^v(Ln{&>CfP+)aqvL-+uExCt~_XAl3SqpFPek$6H$(LgIsNDR0jQ z-w1Z0v|_~ULzy@TwOXlRA@1gLs=%I-%gsBqOty`0M#a2l!6W+|GIGKrHPAoavu`)j2u5IiX**_`Q(<;j*6=1cD<}qtz*D!?K0wG%yFuslnSw5=P2j<2RO+gdzJKBGBPd#I8a zy#3hT)%|K{@PrgO_ZbtHULYa&BnmU6-`#r3_UkzF$plm-H3&@uCO?*Ow6#l6nZwW2 zIAooiH2i4;G3pw4Poh5iHjO;azfTSwamC4icCZ=JsPyqS_Ql zxnk0#he4mzV)Eiv@0x>qgQ%k!IqfuB(Sr zqD(QW4yc4zUD7(w=Or=bTI)Y>J#a(XyTBW9+trQNwgvLl?1d@gB1qTy35|=5X^l_Q zC)n_@61aALG2YJFC@D?6x*gKC_bwe^M1=Q_@p5IpHSX4_$ollqTTXr-><u0Et=rbIhbeA=PT7t)TbxfH9*&%sRU~)-1RK zc2K@saZX7hb}zI3&m0^>#qwQZ6~c9LhxD(k8zIG%z}P93qS}18jJj4@a3w50 z75Z0^8$enT5C2`-!R6fp_-mG6O3fTI{P|eoSdkQ*ECelDcod<*(1LHuVrpudn&Xm1 zd&W|lE?YpcC|S`1aw$eoVSH4v_IhRG3;|U*Z5h}{9=Uc196=J^y`Q0_p59~kbHJyb z=m`!1`(jha*IOi=&{d|ZZ&X!JN`Gc-ds}h$Vay#X$T_>!{WXDxxjAJ# zW|qg`FY=^;&)}hbz)tpx6|h5sI4QY4q6pC@6gKl8_DS%{W3wlk;>G>dWSMurO_31~ zRuWXZ6M#KVd-4S3ewJSMRUnu!irlh{Kj8V?T=wlQw*gqmQ!s0X(^I!kx~GvTlf4V$=oFtdW% zTYS~^<{8Q43&Md5l=PoE>d#9VbFb%6AgPza^qG6=4XXp&3ha#bULS5tKW(=1l<)AT z-K@-xZMdbU8=$TCuj#k8C|>f0&d~U~&@EXIH&ITI!;m;JX9`{ zXN)H}e<4{`HewNb0nE$zs6K;~o!qi!9PD2?#^lax5@&FG5#GVk8!0My%Vy)7Rn3%16S#h{>gE(FzH9_Kwh=jlRs`nIZ!%Fo<@QkIFu!i zoj5@Q^J)LJuTT+$)iju9XmjrD&VY@>!WTO%p_Gm0Xff!_o}4vqcMei;=PY%7RY5zW z+d#*YE{0}yY(#-@l71SYvz@1Ih^yZ2xeJ@In6ERNWdVT$wQY@i9LfHd_n#}QKSEb> z7=)x`Z#7#H^R`2j>$t{La&~t?#5uhbt^i!2P)jx3dfw|VvhI?B`c!CE?W+@W^Dp67E%>=M=_#{vNwfQt{SG}h! zO-yaV#PzcSzZ`N-2IC61X<#x1zN8fkymZS7Ze}f11<%9{xYDkpgS)aisRYE5V5E@e zPXFKzABIZeKFWp|i8K^Nju4XMOongS=?ANB-U6(}3@lJ(q`Xcu73<8+CcGy3;2ZS= zW>Hrjnua3}IZ`f+B`Yf#Sc!re7wp{8hgvLyT6!7B$G zUtb1Lkx%$yQN$0_|Dq;D%R-7CxEW1)V1TT{|{`Hi>1$3IRuqXX2X$TkiXX z5I=!F@pcP-ZkJYh`rrm&kYenO+GxGSR7I`gUvw|F59L_&FE(eh#Q1goSnlsyZ}CHl zKC0riqV-e)_1pOwR8^HSS>%Eiqb94J=0#@y9QaXh*k9|vOvq-EDjiUQyotdZ{}e|D z8_JGUHW_F6!VS!hSEyuY(T{N+I<3wAQ#y`|4xJ$6qph|}QvNkcRDka!wboitw}Cqd z_6p_1^|!8dIkuxXz;-f5a>HZK-L%8rlHPAzX{I~Mn)*U4Hb2~6!6`a0@H=Xmhzm_| zrBCf?4T*U#{QLwhVgp3Cx_Z?DGgz4K=g3-Y?t-f?$TYVf4O#k^Y z&}oQK-%Zj|jjHZk=imzG&?{6Oe4R|9Oq0jTjLnEjx#`o!=-~r7!p8u z`<^|KGDKXO1JMaEebCU7Mc|T!hw02ca8_MOPxyKsuJCPiq2F8;)zUvseWP_wJ_6z? zIao#6UyoD$uhm58K{4~Cv5|r;QfhLGm>r;Q?^u$>X2j1Y&(ewl&JS6^tv*XagSxvtlRskd z-7yPo$JB4@ktxaAS-qZ#LU9^YbgN;En`L{<#7x*r*4XbUAnF7Tnz7v)D*>ntAFUBc%XAUc>it(0*pXFtitha1;mf;! zHYFZsxkP}4z$lwE3nV0-OSDE6|GB3`sbwubk%z!o=%in*qqJpMGiDUFXN*DMOWPo#UCLQZ{g+6AM>t*C}b*VNks}0eBxXbh-b@X!B&*IP}XHfq1f8iOoyU1 zS#7=ViBE}7x(M~QBR7I$v^aC!cX8z&A=DHqN539udR^H!^;M*rDa|L3Kk4PcKPKXibWOl(s}>+69Hr5EfJqx(FY8G)ol@26ZA87B+jjS1dV9_`oLkM@tJdb!9VvBHylK`Iqz(0msIcRQmZBLus?^J}`tnR!t?)P9jU%6P6Ih_iFksd4;(OQTYm8e@%( z0o~PbOSaoOEbuBYHq^M&@m(bd&VE>d{=8*Pg$VBj{T4yu-tp^Cxj#xM*hvkg&7B!p zL3I>rSeblpz>)A|ouy=f2-k*kOQNvKwE?I9UX_TdWjrPceBr~q2t^BaI=r0qj)!^#terE8^;Qlx6 zmKr2>n+SsI_q{CM7j<93b_B^ceH9y_4gZxGMq8CccbP2Ol(KJLYIRUb_Yqk8H>~J3 zeN8eM$_^Fm9{2g$!rA0Wow-muR=QYt;!dhi86wA`4T~iIRRH-P%kcklN<=@^#qx|*d%tu>g>ZRd4GYVKAO%mO7!r9Ow{r|5jKAwTr5%6P2~8hP zH)AtSTI=mSNGCO*zR6c|Jk(^*a-hQI7}=R9SL&|mibjH8hIUoOD8Jd9KItauRr|6e z+02LElIwOg(awOgZxGJ`>j>a>-Y-htzETjdo!0lpO`0Yg5$~}ju-?;5(7p$Vg3&C!cSak3PTcL6Y<<2k)BW|pC#=lNcGq6>AsrXU;o1G zZStZF#aNtcbm?|EyDc2iZ=Cx5bEso`dz_QK8ss53*Y}%n0hg4)n$h~`n>#kS51w$D zhV#`OMiF0xTkET7s4V-w(BU7Z{BL+dx{1>RsYFK0AcWkvW_leLpFGM_0Qct81B@~L z0}f_++eP4e9Xkc*L>DuIvHKp>pJ%6Z=`c5Y*+d_H)x}1Pyx0Sh;NQzpb zO`)PKfeWt%l%!B!vs>BHi=wYl-ytv_&-hmDvoVes)Uo9J@MQFl-2@ zscSeCi?LySs>bU=zI=Pb_`M9smJVBU@Bf^h21XZbEnCjXB~cukkq_oz(01JUc@xfE zJ}orKZJ4&Kwr(R+RxQZ@nb>AUpK#fj^A$GRzOFhjlgH+y+ZS>ok-$303h(`H&TL^# z^F~8a-}Fq`b#XJa0j~>tqKXpvNs{R`#C-_Kf>$`c7VC!VomIQ%aUhajpQi4wGFs7K z5-Rl;S^hl#v7mW__}mvL}(`9!CVjhwW8vV0qgeY za4Y+8yPsj*P<1}?Q{|+DEWC49vmBN9gWF&5>>wSyhzG}nUxERUqm&`ww|2F%9*bqF z5D4G$X=m>=ar7JW3OybrJ#M^Zv_Y!Rc;ESzPcqd|V-OXQ$&aQVowTy|$&a4*4PC&w z>9;`YBnO%-oT3oAiEu2cz7e$Q4?1N?LbA&N8hBs}j)7YX>8>@X=lk4mNfas~)Hv>{ zGu5CaY@8oDPAEl1CybZ;dwe?`up)_9yJkjAYQ?m&d@|(igGytCeM#&o85|o3=M>U$ zn}KGn>@Ap4QV+J)?c#)9%*E@k@tuUay=i)F^iulCrgko3yf}5;rwQhnJH1O|T19OV zOvt#D|!gQ6o=uMgP{L`)||C8RlYL z0_C`u=^MND^b1HQ(wGFLYciWBROda~2(Z-g_r_PYBKfDRA9#B;K>7H%?%bICZKP|X zFhh4W=#|%7fUBm`*2vjU?964r#0yI3*NydjUZ=ZTg& z<_65aXsGY|X|i!t?u?bKQ7WP`Rt2#;M^30*-Hz&F1fzu!RaLXmT)maH@rU^7!u6-9gKEder^fioqI70jEUFx#UD*<(>y@8t+^C1KYmDsdDOjFesRW^5}N;Y@8bYt|t`-lGh5B$$&Ogy=k zM2SGwf^rFKi3Ce%`$}0UZD#GL8Cd7*9iL>`=G_$padjCb&Y4LDj_QY7tHRfvaVL6Q|+5f(V~I^Wn^PzKG@Q1N3{!|H^Hj9N(#UyPRDr zsEChto#a_0=SESbUFkdImKsUENKgTzT-JH(Mw;ttJ?Ys>QqI#vQHncGC5&o*xaaZs zTG8rrKPA{fi2ar-XP$kgRlc>IUUn$@h$tBlr3W4XzcYs7ACBxj`gAF9^3UymC( zf-uJmlFwh*VaqPcU0p$K1fj&vJsoZTn3-9qFyk7jmf^y%>!;m((v78#x)1(c?ce#& zg4jnGk>`hg_@<3u-%Das2@@O7Iu~SK+__xZ0SWdN>gB&p?RDE^9+UcdBz(51Ad zn0)cwIf~WJw5$1(Su0y&5GrjIS#uYZ$c!%J!;Ft}a}%B43djLrl2!6>Z25>SjG;1C zPkk&$6>aGc+%wmYbv?syW3I$wq7YOB)&eKRgoM6$&?yzrEu`DG7B&JcOHb-eJ@VOSWX;*Ec*}{=kue^%W~pgP*+a`uEEPv5)Xv2g4DB@_qU4ALZM5F$98rFeIb#(S<0*!v_p+JKX_ zwn+&|-}LsFYHXy}YR!C#mlpj|I&6VT9tz8MPS9V5Pt}Zh-`Q^zP4It3zCh0cZ0fJR zaq^g4Kd@*dcYNDY!iie~2+izD&7i|LiY`830)Z*z#a(HZ?~s+9=dM(HtsEFYsPA;; zLd|#Dg&CUXTpVYdewilMp*5!A^qNr=Vz#1XV=7mudKwZ)g;YWBxV|xCMU4+i-wYMQ zIBj+`Dp)2a8Nf+h^v(wRuiPAo5iN9SWbXRa*BVe2&)uimjco%6Jfc8-^x0Q2?3k48 z47=wXioYlV?tdKyZp6mIUJnQ2vwz?ikP85d_5vX!+w0JGX)iz}hug9eVr)&k!T_iYUA5Y`@90R~?;H9vko;jdgy zf5{;t&cfFE>Hq8jvS6l#zwLa+V=-C>n?Vnoy2O(Q&WUPXl~;fH;S;BRgh24l6&mZP(v;Cl%iD7^?k*xV9X6TpGxwVFrg` zhzT(AQ5Gb$iBh@LYsmYJ5|=ilWp)0@f(bAZ4*(8P%)Dp%6d<12Y=fRzZx!>^84CmEInK@iSo-pq9(gRiTsi z>KKt0Ne$(X84=MIO$1;AHLin_EJdJG=>_z&sfG1c^*{|F!jn6rWCKIbv z2+hOwMZwP%JD=1qsQ8I@A=roZ2QKYM9vtQ1z*K85Fi1*w&P)hBbgF`aOWLct*8o4< z=@&hgGqZ97k*L4l-UQRf>UT5cK#uy~;4sd#oagP&H&`lIGl3=EaEAS)+g8_Y7>N#; z6?1Ih2BdJKb+33fgN;V;BX`DyVF*oWhkpggDi7d#m>TfiWf-W5sNfcTmbe$Ma8$qC z+QQ0~&1ocp0KbHOY;C0pr{3IKpN=#By>$4Gmh#W>#pk><+^$VCCqs2hCjlNrxGhU& zlfIE*7}Tw^mZj+0mW|4&p9Ji35|at{ z%KeZ;v_HIBd0HRMn#Z~PKKch}o5AjVya~T$XM|v2`HYbqby&I)0Yx|?08NHTpk0!y=C~3uOn>x~xS*HR3|H5rNjpoV!6# zO(8LfK#hhRHWZBycd=uf**0quhD{fPous|svP~H`4 zI$_5o5{zy=>$<@D?g8jv-gg}yOm&^=GunG@hz0%1r;SP9SeSZ*TFn^w^L6yKa`v=G ze;>!r%w{`mb?s2a7A4%<`uY3EkC>MJgF$I`mIlioUtB1lVBsv6XJv-UC61tf&(c3x zUcK%B8w6R{lLCl8j@F1Q)d4ap*V_wO4spuI#8Ii!JhR7vRnHk>m1tkLIc7nZS35XP zZ^>Ne_#6aaIoFRoi!$iSTTx(V!ju!A7Nj~1#^btfrT*T}@e{tN5MmX*j*jjbJ=2{Mkay2ql3W}ySux)dke)0?poY~yR^7NDNc|= zaCa}~NzXag_1@3@j^|Sbe8?C{_TK-s)}He>yRzC{wfYxH9l(q`tSAEKJu2+l&*=^fwQS2RTCpNPt_N5zGHto%%W;Zrv~0AKuO%y@zB{SH{lYF#q%?qJPRLz0_XFL zcBqHHaZK*lAURXuAcC(KLd+7fr}-$cSoujoe$hZ z<(B=jF858vgV>3F!?LXt9T|JQy@qrnbwgn@@)|peYNu58B|6ecWj-0&KG0Qah~%UJ zd%0nEk1T?JZifFor12}0iTez zfxJG_LfLkp^nj%9<-ef98MrO9eU0_LWN&zxssRHef)J+s@Apz1{wHhp{~M5|YM6YIjSe)2Ta<}K{{Bv8h|r~&ASDlI3#HD97&&Jp3Xf>|$07G6sjg80kx8}-$x z54OC=lbDtuU7;+tfl_Fo0M~X(VnM#FiV;2}w9~M(w>x8riSUC>`=@3}Lg!T!cLrU|PK#pYSeOdu8#r+r#6!}l_#{4I!VF}iNsAkoOct(| zR0sq-WZ}bir7qV4JL2~JDkDntivQb+L9_%wF1@FYvpzgwkse*O4%>+u#jPZm-35Fm z9TeOyjp*)=DSHou;m~-ag)UoshrFJTtA1L%R5Y$KZ3zge|=_^DQn>|VMz)S=EJt4M4Z~v};aegbO;W$Ru;%)pu-ODP zCN{hlg$HRIv~nxzC0DoFW=b8%+}QHc8JkoEO$7brGI*z>ZNv0h&rLrD*#0bDX^;+m#bO2>yNU{O~u7FmOvK!nDdB;wS>sM#+9EG{P+;(dNxNiH~z z(H}6X*A5Mp6JW9O(-FaEW?$-Ah==YSn?H#n%cupsR;ss8`GJ+Ih1Yrjo~f~(IRvi> zHwOF2RIv3p0)b==g=bLkqWFFD#hBO~2HDnkv^+AsxwLnT6Q=xJd)C4BsUv;M-i@z} zUE_p)0fs;=>+pxaf8N^%&XJ#>>LjX#>X!10qWlE~KfS5A-_~;?B1WBo?VOH|0$p5T z|FtE81?=$qY$2Xp^W;PUT4mD|*~*GN^)++qIblE7${IszD1o0#%ol(1BqjLr8#UNZ zsX#O7x@SFOnTq}_BG*;6yEQ#*qH!IX0#)*3e6E7l@?}9^b_WnUtu}*YSpF9EH;<{n z7PFEbp#a)>MTo^-kQmdBO-m|D%^0wrsw=36&!KXAH~Du)brG+6*o!!+pr%Hz%2>Z}Zmzzn|W> zg%G_cWpqH~A7-=nZ^DJ+X@#AnWZ-u`bN!(6+4Jl9TXhtC%06&U7@B0XO>@DT%Bdn; ziVVzoRdj>%9zmd<%W>CEL^<{%i7-A1D|^F)Xy&f!U@lXI*mKVJy~m*=+rgbt568-L zFkeO@jvh#-i=%{_x3_qM>LUgry7Rc3JXPw?n5CSN}QOg!QgoM*6=oJ4cQz?F-pcSDoW|+pI%t zq!HUm2mt~Z)P}r1mQeh`uUvg)NP^cYgs_(?o)wE7{ntZCvSM3!_)JS~~Pg<@aM0?|0Kf zAxYwhw-4|L+m#!e&zkR`I@I!YYbFkWGz59OE01DqVPOu0+8R?X_#D}sK&lDHc_>u+ zFy2%`8NrTF*P`Auq7hvlaT~KUxGa$)~w*)2H{*%ey!@gd2@2Blp9S$+S}?(KM8>|Ie7~C3U8e6l30T7~+W}6? z@mn^dvE@XRclTPnzoU9(aj#)sc4ZwFQ&)LDmWoO?O>PO}Dw$Q{=3p(g`m(nxs_j6E>}5rs7%{b8=A2K9iGbKY;v~ z`I3WG`g|Ad^8>R_SmpVfgF5I*w~^h2$i>f9-zwCrDZO1Ig-!b*OBrs=z%!4#Q~2Cr z@nC8YwXrW_3uj=>4{K#a%AGroGQEQBl)hT_`?`;@XvfbRG%Haua_yj%TRGAe=K|4R zPKq3C;4!~%9>tfh2BXM%ldPVEtO`T2f%b`V3u6PiGI}&Tt4HcDv)_Y32DwViK9Sf- zY4QZ|LP3x8S-07XRuM^@Q0--J0#@sOHpPT_Jez1YhxJH=yfsPj#4g(g?00a%U5Q=U zx-4`&$lYtRt|HjBE{JF?tla-Y^YUkJ*N}&_u_`q_P+16l4c_^B2m8d+)_KIg+hy0G zk6S;*TdamR2QRUKt_& z3~1?HO@JvSni+AnWYUu|SK-u=%h#~Y$;53d$fObxnJF*-mGAwvB`{u>HxXvNt{bZ8 z93!Ksh^L{Xg3E=i>3rlv$3?i&2}B*|-_;#=cJ>Xq zPnk^WY?qan9#qh`%95+>UJMQlMxW^AnO&eG)N%_FMc%A6XK4+WPjXdkujp}i0VjGK z05tI@|8wG~zB-P2yh)5pIH!dj(2YLUvUmrhz=RQyef%y|oq;qv?_P({qUK;|Db{7^8x!^!ikzG|eWPI4<6C%h2;ZoFTwZ~Nz6&|FwZpWtGkiy^R_7;- znRpF49b5|>Z!^4l^Npdupnzs8?da7V-hgcGtR(1o8R`U<8*-Q@$k$-Q|GSS3(>y8R zB&c0F!%$WYSSIaD50_tv)Szi9Q5}(X7|oXRwD)4E26v_Gu4igwV6;ooo}y^TMbO zZ^K}WH&%OOrxmkrW1!f~_Pfv7^%yYvr?O2DG%Of2bU9X@|38@qL{y`oVy4mCwoBD9 z4}zI>HRJU`W*q_9>KE9HztN_ z)ujFDVkio2O~p)cZ*>uKJSY<#Z^AY;w|=R2KG;MN(K3*GF?nsYmpyUy^2$@I!;9{kg0GvpX(WJV zz>sY~%eg@K{^U5Oz3RdB{wH%DEy+8!7>KMlYMi+VD?wJXldZsYFmb&5GU<`*=g)`9 z9vkAUzG8K+`oyLh`mSD+2JxvDM$%`z%8FUTdl))*{DT|A=a9sE%F2eIC)Ubq2UERk z%yIt-;bvm?Wb|2veW6CSA zFT-{X&frjT{UWSCcI^qWPT(E8)-!ABS2kxpq0Iw$_5uMtjyxY~7&)irs?@X{(5}cu zbCt%KXZYPN)QD#yr0!HWI0W6JZDL4_k}ifb>1{Z4SD0JR@#)|)mVL10UEN&;3Cd&v zu}Oy;TDP}?r4t`$!m~_yDZ++nmY9ZJ-U^>K=>Q(cLL@D75DdaPLZo9kgDbmx>(>-D zbSwFXz{t-`9Zf&G8g8feyr1bJ1!@YVj?=WYs@f6w6-B2DX-e)$XCLV}$H7#;whX!P zlAHtczMKeG1QH@;!1NOQfSHzl3UHjM>Z~4_i#Y(r&M!T9tx-`)m3nfZ;%)y0RZ~c- z=WZk;CXkazn%Yb7NG6cCj!p0&i!E5mC2YqiI~=7Fr@K~;SBWSeW36A_F{8}z{{HN@ zK6er{1-ls{bcDE=T_r+2s7~6RGWH)F{+~-C$b8v$&|(=-Ztsb~b0RtzjmYMQx)*Xk z-HHUe)a}y%b+KOJ6a5lUh(FnWdt>~raU=GodcvkQ z2kzTBBnY6}X0A9#7MRl>FlDP&AKH3(^A{DM@+BbZ@JPqvY+WqxQMD_Vtw_KBy|eyp zT$prkpN4Av5vY2{tuD!jeyoZgIY-(V_}LUlA73-8G(ltONT_^?B|=s4>aA>((Ll$% z({YKJr|wM7|AGYmd_hO~Tt&|Do5%J#==rE4^T+n%n;NSsQK#XF;)mAOZb@!AN-kjl zf$Ih}aQnA&Edi_VZ8vJEL>Bm0!@8GYL^)5(V?Nu_P$ab|Qo@*?iA6n-qw{?{A1`oD z6_eu3o12^JYhp6#`(qvieg#g5Y#RqYeWsIO3PZ-Mj;P-eBE$ebp?!RSw;U~Bz3q6& zkki+SA(&K&caX-*r-wfF)h**wSS5I$7j_7__<|6Md|nlt|L-=JnXDHrI-e^jj&cld z*!3QL^6cjl*;@K~rTqFL-FgUj@$Dgk!FkiFa$(qE+tbQgT$2;z4S}w410jYJ zTn7luy2&kZGKf-G8IWS+;;bn&x&gs-0 z^Qk-;QeE5<`mq@;Pj5;cbO?oT6^u9U)RjO=uZ+(GhFYU01+hcvPde#>51!xJ4v#Vv zMIJPpy@=Fd@tHa3V#G4xVeSsSiHa7si1*%%W5G5@L{7nJ$q+G;=V|P|oQS+GYs88qr&!6Pk4(nm)Isa=y0#|CmS=)lrJz~>d)rUmHr?;EM; zG4HM@4&@DGCc(@sX=bozqc{^y;1D5NqA58^tcAdN2~{^seV%qL-g4<@Uis#F*oA=q z+}O2a#5;=_rRRFVeD;CBQ6fRnP}pkq{g5w4`-R>l2}Q_3nc-EwYC;*&(L9M&V3urm zuO8Z4bz2UFw~AjL5j#ZC@R}H+nCA-d9O9>LZHjs99LwhT)7Ny#6EqXiLunO?GgPla zETm0}bp}^{>EP=pBl+}3Ur2aRrc*f~As_USaj7@%VX*9={(whal&)fQ$RM( zT6cbu3}R@J9=|c>Gw^3Dd}t{}U#bt6XlHjeP#W>UE+COTABk|7cho7*DuaP-?al+3Y*!Wgf`kpy;+7tPFydEaT@v$OLm&^KS@*1LJzlFfvkeAgqH!uykl zkmc+1kiA9!0tr`FM?9_(k1aX#b^(;q%6U$is6%i%oK+*G3kKF;(R%ph@e`9FR9~C( zPlFN94C$4^x1Sp;H`;G>V|lipuN_rnCmIveTQZNGE22w18Zz`iR{H||I`pI7?-#7Q zD>bA_+4<>Riuw}PW%Qz$A0NMog_S-nh0LaV3U5)5tmP6j19l(qcu}-+9eq74qCnEc zEI67K%37}N>kX6HrtIs+Oio3b&}45UukJKJmQ2qcyp z?p~edp-KK=P>F7QtDvF!CU~}W9$Xzmm=0Q~$JJ#rXVJI!2o{FqpM~wn)1XCv7GDtw z5iCyW^RW5_4>n=O{0nMpSxTG+L!yXOg6!*ItmgMlG+*LC_s_#7()MV9tT#k;*xpW)(zdEKVzX)i~pibjZo7Pwh=6;?bbvTKL<-^(bPeH^iQk zOn0PPwD)PPBqVIEQj;RWE~->?MTBh7#npV%ubgj6=0A42iFil=|iWC0X zb4C?xqG>((2mtGEt+o%=dP;@7Y7`xgfr}6zWGrnZ1v-p2U8|am%Ka{K^yfTNI-WkJ zl(H!7squj2O#ef5i-diCdEV*^<=aoe+Q<&6x{_Be0<`t zNu)v?5tEvZ?%n1WwWp)lTjDUb?C(-rW=GCiJTI|>K$|Yqwn@X!?%s@@v#PlkIl{6w zwcF$45AdM6eSL#Tl{ieCt~T)*GA3+pGHo^wVF4484uzU-8e2y%x;}^R&QBR*hkg$( zFPr3VZenrnDhIJ*`WMN-_vdN(j2{)wtT!LMCZ_WqXu zy@|}-wLWs*m*~dUsYE83u-LMd9Q32dlSq$6Dt{m{9Z*II_WC=`^PiI7zvFS-v*)1Q z0*;np)$m#4&7Dr8)NV62=b;o?7EspoR|Sk@Trc|Jz6W=?^9XvjQ+ z1cB6-_YhH>l(sgsmY4buuZ4HV9{Ht{JUUx59_xxauA|(;K<)3%gl@-k=j*7!>8SI& zvgN(Vb2%sIB<{j=nI3WW16&;2?im^UARnh@;gq@?iI=gDotuk(TN}n-krLHwX4ceO zLgO2tZ2N;X9lynt67`!As}g+jd*WMkx%Nf7k&ShBZCd|uj{FMWa$=n^IgI1-!}PRT z9?nx6Y!|Lhr#V+x-s)P`QBPn_Mk{+4e7~D@=m*0gtao`n?lI$Yxn;_Ip-F$l4KRjK zc(8`*z6pMxFMy|1Xbk+r*%7*qVBFQA3s)&_Y7OT!VK??YGw4=>eoG&Us5y5Z_T0~Ug zAl-RE(dE@It`W%`=#`<9bk}d^3fcve?FiQw2YN!%VUA3JK|#<(wfgVj=u^p7;aYTQ z2pRq`{kl#Il3mJ&{)tRC*1rC|; zVw6jy^cWUxW;mX?G#>~Gz+0-RDu1=%u<@?DH$o4UnC1R`H#L#1N^_sJ&#MrIMd_A?Ao}# zyW^vkIB|7DjQCLs3F(qmq%#9v16=&yCWjSV1+_sAMOLd7nZB|0tpr8$^_Oj-kD-qh zhoI}O`QvH^l?z*MCga{&>(IKo&4m`nU+sY!bM@g(4p6D$jH+KrRc8%!zLHvQs~2Ah zdnnn!5(;Dfg2>TxN2%~~R0jJSB8zWbPwKl}tAm$L>K;B~QpAi_wO_1-(&GVV-8CxlWeQVkF`Vs)DW9VZ7uo`8N_MoVG<@`%(Goj<-R_HG&4x) ziBC8I8uUyU+mfLBxwc{OzBEgbO0rERdp*Le!tqQkOEJK^ zTJ2h(xo@>CBSldn2$_Yr5~lh_VBl_3w{gml-HAcs+WSXRjS5&qg1mtzmW7$BEIAHj znFa%O$Y(RGbpl@dwmq%~DZ6|7Qb{<&1Rv2Rhf&48%2S{QK+}fZ!nh&II3lEhmrKYq zzw~p-q>eDY_bbDd)ew;&%bA&&LdI=coA%%k_!4EXRQktxNdg5yKcvC92lwB7@_i4H zT8({_$_)v8@0!uJSfaL^0@4APw7ZTjyU%)zm@#Bv|3ECKclzdWNC!*K5LGP%$34GK~{pn$rys2ZH@qYl?&jeK~6}T#A!|i9Mru z>nx+Dm>A0(2Q6FRoPjs@lcOOU6dlc;W#+Sz^>BEm(26{X*$dyi%Z{iSs@KPUg5+Tz zO)qmq7!f0^ceF|J52|Vg<#lz!_#ER)|B08c)oJ~29%SszrE2aaiRd8lNGHvMpWIdR zhA|!W20)b=S4)@XR}b8Vqu+LA$3H@>AY`JZ};3nCmhCxN1q0WA16gGeE)-~J=?xa$OA-vGO4WC$4&pVM* z7b=b+G?5Ngvet!?uEwv=vYh_BBw>|2?`j;^F>9M?T;x#f=c~lbes@h!PRu|NLTQig zY$51h$2)Io@=zNY!5o>#hh48t?|2apwSPDSOe`EG=Oiz571|f9d2I{Z1R?C#384W9 zl`k@qI8o%q;H^DaMMgPzuQtIYeQnL1*s`3Pv#1MBmKG_v1sfL7eeg(HNbD8_4pU6= zrdX3lLIFeG4jGm0ezU^D{7UH zP&yTJ!nKEQU(4Us{cRveZfQWXYbB1xr3g|M)Roe~?cvW2f>gYS!6M6eT`7yr{`M>% zRb8nFyCo=}KhdCdE5&Q~Wi=v&;xw5-V^NvF=e0vTZi!1~X552BlMc*hpBCf%Jm>mv zQlWR-{fK8L{N60CFA_oPag|P`zOjfjR>;&@e8PcMT38xo0k^=pSz>_aZHfibL4}9U zgF|gTggolPvNTnk|oIN{S-@I1dh0 z3o$8FYpw+gdM$f*gK8sV@R4NBOFG(mu~XwkjeAsaQ6Mbn{}vc=a4_#hqn4#qQayz0 z_STH8Y@UmgqhUIXizygdpyof|&cTNOFhY zQ61T|#}af2DhfBq6VGfDO5#8}F!He}s}>~6?|f`FeD!s78Y`E=;2@0JzPkENk&TXg zZAzl-?>WwHT40f(S{}#d0;&aqI{*cnhCUi3=g8e(tCM9aMrfQW^w{t(UejF?3ONX6 z}(LK(-nTWq0MFL?F8g~<)#R8dkIuB4+0!YSB( zwI;OoPWL(V85|vWw_?p_3z@1I50Uk3xMqhROS*|}2u6o!3zYGc)7v_vsh<79Hygyd zo%@Er(j*0cd)71z$jCQ)+u<+{9Si;zz)9{;1~iItQ6R01&{8!L;t~Vx*wu@ub<-%b`UGJEML14_7Kr+(-{`qOkaoTuh zK;pze@cbl`JXikA^g>FogFLWP7tK)-3K7Xc6hW^Z=}*Yce^=8#h0*`}Pn^NePlmaV zKZV9RB6S@3IRnKwn&nBU(}o-Xr`D8FcWL1&ktOBbZJ^E{CSqtvverErO94A@-K8X< z+BWq$?sXZBdvshBQ_M2DomrFa+?@9VxaVRu&O%zh3rch>7wni#@g9BIN>%H;o(3qA zNCe^_fXx1nuQB^1TO!ehM#jn3t{_84=@^!W`}A}o>3C=6-qDAE{E^aSHBc`k&xgQ_ zpD{}9xS{I<&o+iUbmM42D3rco0r%xYB0lLr$?VFcfAF|7#l#+K-QI(xS%Jza){-_R z9Hw^~yGubly0MZouXdn%a$L%=%I#aB#A@6SnM8DuRA=PwllzrHr)#QPUV!0fcY7jR zR7x8kd;eXWb1p#th-Jk;Tt|jDvBOy`vUOPn>}y2f9fbhT)4io`vXa|R@e2y-CA$0yrCT5uzmg;Nb7Y2*AZyqOJW@jH~8ElC^e)`J0v;qYcAr!z+ ztd>L+{k_)O=!;Z>Y`bfU^HN#W-vw370iX>vmDWDJIpg~Le5)}s0mnA9)?bZ6ExyHq z5f%fy=!4at8f*X|A{3Bz`*|EzEq84H&#VQakb-lQALHE@zR>s5)X=MKjivX_3r+PCLjS#be-!0fqB3gOadIl9X+qD zNBBKm0^l`LcW;+;!vJ70*bqFS^CkT;a`l1X93yDc&dDy%}wfjqdJA z_$fD>9b;qRATJ_Mb4;J9?IF+V3Bg(XxyHhK52tpAuwWOr-ZUu;;GVHco;gS!x3RpT zxf8riQA|%OwK9Rw-Mn{(iKskBu0XHl_}8wrMEkLg}(J6e<4_yi($i z%X^v?s&@vg>lLh)M$g@cV9+<24)dvP+k~+B!>l}$U6`++XJEgLrc?*rfCI(w{n0J} zmO}gU&F~W}LtdENhon0R;#0H$#NzR*+Y^PH^A{(EmQSaZptFib^Z9r`a_+?eVb`>M z3&RpmJl+BRJ@3Ab8s-$)`Igvp+L)uI@Ux{rl|t*sJu(N`axbBWaJ2#QjRH~ht5*#& z{{hZ7q22i_r`@D!PdJ?in4P)&v%T13xDEi=9*dXSF>&z3*nLZ?D*H<_61IDLJ{NnI z1x}#R$-kbrKdbO)xMNc`^IF)KaOf1@pCM(FftI;Zy0_9QJzcNXPGn}`zLL(6sdkkE zGaK?U^O2gfYjSv#FZ}aW_c?nTa?<#gk%W72Ue>q0rVwLK8V~rKjebLECaL7gnYRmT zpSZq3JBHf6pg<2(nO|h`@PkdPZTri20JX@ zquOIErIPoU;i=VN$tqmc3~DX-Ud)+>c7r*e6M}ovbajrr0qa(Zx}wxs`zp|{o%YI) zr)WZP`s>7xOZN4A%$(!PPU2b^@bBw~5_bi!yC{`ZYUQ7q4_CFDzqEc*YNE^B2H_&? z;^Srd%e&Nm(%VDw`P>$nAAt1gjo6W9%_*Z$*q2A=p2o@0(MZ7{g79@&aNE1>Kgd6} z{~z*iXEuJf-sxB0urkh#+;?Oz*UgWcJ1FUgC7>(8(@03#Oqv{BCgx6={n7pE`|T3?h7CriBdM*(=h z<*xDusbHlbcKM#b=a@qBxXh?)$M*;A1qUb0r5X)G?Er#yM9&_+bN!GTB;4PTHIuSB z{3B)-MKx~{3}bN?B;okOpDvLa_5>;o2>qt`UpF_TOZDH-EQ7pmA=qnT^5 zM9SlIBD%h>!J2t$#~t9^gQMXx_s>@L(a|24I`RL|E2HPIDmhn~oV=H)kRug^mSPoa z+?9bp&R68ir1{7tm%#?8HguF&g)<+q(*CC?vH}MC{PI=-2h-{qT%)MSj2N6Ka15dLqXa9en#Luq)T` zI=sNwR_{x?GwX?Lr0PiFw>pJ#ai%Zi(1g}%sw}s>$m)~)Jx{CE*wwv$k%c4q&K||E zeFw;lAUN$`C_);yF-oFL(_95GVGjP9l<*qH{yu>l)-&kSVuf=jpwrD%_6W3wf>>+C z1!ld#{jgU+d4G6u+c{6J9D<3ISWXow(S%wivmMA4nS02xZPtdi0e?xZ?u?EkMaN%2x&c5wGsFKhr4+G()JxJmIh)IWDC7K-h* zo!mxr{a2SNM#X`rcV|l~GfOg~1|0E9)yDXCP#NBpCy;cNWtDx6HW_hJ>NW?-%9-iu zlqO8kbvGY3VTD8o5s81sRS-1#e+dH8S&JspvhGBU(4`bfUvscNhS`Y(KzjS+9rvuj z-L_%t;wh=|ULb`$29t|5)B|qF^{1VJ*zY_foPebPj#QZ6-68zIxRZFAIaY#Tp>9u$ zZ5~I3|4Fd@XPsoMm~%eK*>sGq$qTE!v$v9_mHB~)`}AX}plbukDeD78627sJA}}V6 zN{;aUU_IGUVfUXeX0*Z>Q$Oos{y=DK&0wZ!Wl-de?BfZ^+Y(o!9 zh?SOsC?ip+OAQM(+6TN+wc_PGbcip`FUsM-mrvOhuMJiOjyAnu6T zEJX0*t_&x~tEyt6yrANbkQl}d*}O@HisqLXPNp7<-QRmqp;4bHk5^@x$qr}Qo@$b4 z3{i&BvGo(hk7pu`5GhA~r4jK2WNRM_MgU9ogobr%6 zZ>m&&Cqo624AaaY+F&sE?mX0}8Zmjk ztqz$fp;i%Exo*Da*jryED~hfVK2zs0b>$0n8_B&s5%Qqw zQ+E6pltBMyLbTuxA4VMt6A3pIaTu}ntpag3a3n*N;Cgf16Vge-fxCtUFynY_i*B?I zTGP#P?Gp?if_+qXM=wd+9u9@0dfUV~MHtBrg6nZ}6}cK4+6X?pR2 zvAGxAamoWpOy%=?F^mTi3!wPw-is+S;%{m(XKV|}edRDQ5T$I316)M?#A!fct=*%^ygwz%u%I~rlIVCu3#0j@pfcZibS z6Mz$~11lp1jR~5jxVcvZ$oVbv41ir(J@96kgCaaRX_n@dna!A_NxYaY&?cASq>g^( z#2tSJ;PFapi6uKoOO*%Ux?5w$aypWME$N%`etvVxlRKt0T9T23Pu8(U29_K3Z$9E;REX zt7+;A3RX>v!pL9dCqsjws<%TWqLqt3&%V+M?)i0 zWXNEjCCBW~Q+Nj6u?x+A^1$#c#YI%2^PBT@#YT2oa{26>HEzi(n6(zFX(E&nix3(4 zPR;9`b^Fz1ye%iY#l4Cgkc>%^p|kL;_o$;BF@apu zq>LA9R+H_%@KsWKJMaimIj~?K>7-iOFGB@Wpc+3~?uZp16jE(Bu82x|S~|MpWU7xH zg`##NTF9rp#L5X`s19nA?lQ&yrW<0*^X7LR8mbaFz#MF+#b1Vr{I^7rW(1R%TNsKO zPMoe>1>bgdz)zg9{)n`W$k53Dp}Quj71X+_E%D{x{{D%zt2#QN^LM9t?wfqG(6DDv z2(sg8dS1p-`y#J16Ez2EOBR#UQFkk&*hIXTO{<}LI2i(M#G;+$_Z@-u(13r~*4DhP zCi^?-!~<%)Yj@@6=@n((hqlAkcy3Qj(ux=#nx8*|DcuTn(T-kZSZ_uCf-+A%77|kj zu@<#w7HJ;I8xf#dd^g$0a7Xqv$>1D5zYw%XiV@6S@|_1Z0vDfb#gE%2&o|cF3ahRZ1HAo z+Dx4gQeuo>DXq918CK(p}{h~|}#>i7<4`I4Tg&A(U z_`|vHgY7NfUm%4(+eqP(_8-fxLX@|qyc|HCmKVROO#l*IC(N(yI1l&PEKQft2?966 z5aQSbWMuE2Lb{N~g!Oh7PZGB?F&G4!Z?4x4iourJgp%L1+e|HZtgRs^y-^S|N9A2(pED|<;M?46|)`rrq2e^p5Yu6^2P^Rj4EyhUy zq||VBDeqd`8g{>fOq^KLmLRJb*awo_1n5PCfUtDkPFn8Bauz9|`|X)j{(&0-Fa>_` z|GuCo*k*xZu*Ei7*B;=KDX1c(2&YDihD07!S8MXS86Fo;nu`0V`1jyZ-H(8i-Bu2i zl#>&f()-d;&S>Iyxg9=ftHU57zS@G$C{UNQu~1IPl0nZv2z~6GH@Z0ar=XV^kpmPQ zTO-HMe}AC=bVt3?IH__}F^WO~^pHWzKf#iEHV_*p@uMS&=hD2t{&}Ncr#Y7-3PwhO zjNkZ|GqF#t(2vK1Ek_C7`kAy|M;kC6{?l8|oyM{S8c zJp~NY#x$BHJss>39BA*$bV|`_BINVI0tAI958Xt(6#9TUrG$JQ~^jnPwwne&t$F)Ky2NwzLwq$ymS4D`YO)Z5Uo7 zw*zs5P4;@$wYDt#Vj36%pKPoXxNmDXzLI)t#Vf_3OcV`Z<$bXrNoRjU8=j=Q4DLvM zEGINl^_m}jvIh{ZboEVdv?bci4uA6wE)zeyhbBVUy0+eUYaSIR-<|ynO7Wd=?!hcP zikDx0ak7FS7O-N0otxrq5Qs(4XawOgQ|x0`;EhP9&lvRk5~hrkn!GZsNkP3F${Nhi z8w(kHIfdFA?U%bfYv^_-7!#K84_%HuV-U_COda-J)^mJ~#AD@b)Q=f4FZ%$mk#U7g z6+9pX9qKDyOO&QwGgM!Vn}UXED%o|+J8FUzA8MEQ(^S?-BBfV=Ibue9q>(s=NM-F) zkuTBDI0@72$AYdRLlIBTecdTv{J^#erx|(qyDA7*#<2FZo)aJ0-V)hJ=`Sb``eD6! zVDlGR&N(!lwW|E4c_?{dm=1nZz=gB>wMvGI2gk^@G3ymo4?SNq{ULoxy-HW>8Sgs` z4-r%C+s)iL0Ioxtfi3Lt)(5ph3WK3*$rM@2u0c?lG&BuSqN=H~lyOBH| z?D}{;;L0)n(jTA!ZyjT-urPKCg(HU6>pk7Rmh1kjq>YrRBWC~kM<_*&>p!5#_>zL7D z8bH6U3@M>p5z!1bJ1gGAX&UlSqpBZr?t5nsBjEED&6K_}T$>M{BFUUFcYOa;vRp;y zi?opKdaz8FBW3*fo!GF~fI7{pK)}Yz)y>6|O|~bYyr(|HwdXJnx`4s3E72&yS`l>d z&sy;sj^k+^5&312)MaW`#{v+_zLj65++Cf6Omr_bJgTV%Jh7tfmPbYl1Wava+g#@?ur_T1yL(zR%Wsa2!7%`oZ1^@sj|CwLwrMvI&H|?ikNE_f^LeDi(wRkD zTf(Mc<&RQS+TA30TU^j$ugRCY@~)BV!?U~T7y&+aOQKt z-kbam!?4ZBnuWo!kk_uiA>`qzo5@?#CRXM1p=RD4cCqg}&sOKLjyK&3a@e^pDE_lI$n!q(4q$&J1%3H~`9110vGN}?gCwQ{j@9esCQVm zCVP%IM>Rg6n(zI!-xG8C&bszDwPC$X+^;NF`PiQK#xAIc0>5Mk<5Tt6koNO1iFa$q7;;eH zir#3lc4rvpDH&(uxPeb8j6wj1L4ae$Ur;QV@1loLkTzURDpu!>lx*H%k*MfB(S!(( zJ+J|vY*S7AcY3?^Id!S(Qt~3#j%10el~t!sSmLAOYugity>9IZoDaNf$*EuB+?+tM zkxz749|8q}6Z++ug90}9Edi~m0d3R!kM!27y&JjKrQ~wsI?sjL1$$o+ z?+48{S5o)S#_01aUMfS|zRmCueAUez(eBJ@gmQJMs2DozF=(fUN}&%%4fZmr{RH(D zhn(f_Ax^KMB1>BD3!fbgE{t4OiCQcfBWEL-RURa59bVl?+`9td_zK6*r`=&M`T62I-AliC5eGS)Z5nlFVk*O5FLRO zKh^^K?0f+%Nk^0gICBGa87BUp^FsB$vxjXDpDj7;-06~gbl0-;eKHgVt**J~n&?~K z@5zt3DsM%0Kjnjs&|OBm6aChEfC2U{R`EGTG+ALx-CI3NGm;Qy&Owqg&= z!B3OI>3i+V1|T_WM^251*wgi5s|=Qf#~vrqY1irv1QJ==Iqfwx%2Ddnn=55crFnK5 zXX(mVT4oJyW`O}Bu`F?X6?6{vqV9;!7 zfS1(#`4x+)-l*A4-+_5HY@|o8wn}`$3O=PIpa$MTl!5~Vx?&{CBr-@x-4;D1)kuEm z!auD&D-F-j?}%Bgi`zVwf`-}UCJ7n6>nBf0u$_?k8L^Q$Mj7wsP&-r}6~}0te^8&p z{1pTa@u(eztW8iGB`}H(u4;ydFeYYeR!n^3z>FU-y)L4 zc>Shb5&G>fC@mRg8V>NJSbae0zIVa)ZURrV+)%BeagF8=)S=^gs=aGd;k+-UawxAj z(|)ddZtLzw!=Bb)rYJ!j?guaaSp}xJ{^4WOao>>W!d>1#wQ;f%R7qoU$F+iFC3Bz5WI7HY z!lwe{*f9d7p?##k0nLy`D_3NMDcRtI{fDNZc%Hh}o|TyFLDO9A^8g8~u=qi%z&O!s zp#<3;IYdNMiEv&5Fer*FXrb0Ae#Z(bI!@T#-ZJ@42o2?+kcVV9+c0Q9lrpQO4bN>; znPv`znl653>T6G(=sRmcwR~QkkOOYA(4cvzem|w40_*b{TJmAT(I6fCD~K)Dg8+GH z+R6#Mr>V$IB|NY`=xS^ABk4n1pvCWTk!1WfS6ev!%O62 z4%NIe>b}&u&1PGPbU_OBt?#Sl{>Q-HXXMJMPZvEfzgZ7Z7J2^UzXSLS$|rwhEukNP zv*7g*ytux>)5SfZ&PfR0hcls;7O8%=`kK#uqVNNN>DtuSJv#AoP2uW6y{JRVSAv^O z`AWW_ivE{+Mz2g07B!7ZP*h6%V2j@g!R3-h^z?}6^gf0%jWQ)*SJnr&juU zU%s`_7LU?vj7?jW@+XV=4?U>*FT1NXee5j>MB8%#7FGA#fV?)7yV0|0+4&z01jWH|`2v%xC(^19P3^gyKieMQx?eK55IYXVePEFx6%{|@2Do(n zOYItmbFyKlJFS(PA0_pLJ#RBZWg9g=E@5JRNvC45m6dXzGl28F)RCG>U+R9ea3cqY zV>%X9*JIr>Pg3Ib=;o&Nbes}TdL717JQVAJ{c7rP;>^3mgd;d86Y8k_48utm*4^v5 zn@ELS$VMFb+{;euPi1Vdj}I1k9l~y`)zr3f&ze&-%2sOEiyOuBvv)u=iVxH}5VOv? zBVpZCU4z!mvWWcYM{l5%{n@-bAoQ(4L@zeQcJQJ@T1P*Bs;#krJKu~Tt*FEY#Rs>t zn`0TyxxRN_^uT=!T$62xy!IoYW2Ic*cS+eszOLipw$qxY!@$-1kxmR#2IoqR zI1+Nh^>;wxmi#si@x@_ZwycdbwLr}vm5YzHKm(QO z8%`jUAV1WkVUenfYAcP|Qc9WxD@$Ir6xDMZ3{kIsXODgRn%(1ZJ#QFL1M3uq{>&2= zmT0~m9h9+dy8utK#)(PBm|RMKi}JIYy?s{9TuC^dCVo+b)}MPumQdl2vdXlsU+wzr zG|&#C{ovb*CKKGi+D{Ib6 zF%D0kPWi_aEOmiLU44*uCZ6k*-Cgq(5tkW|THY~?_O4XNvvHwQqYe6>B;xrRW4?V& zA+pAsAsIdTFV^Kf|5^V;guQa!I7;T1<;n1j-Cvu$26sPQ83zUrMY|k4ex={=PEk_& z$~qw!?Qox4TjohSFF2a9ET>G32Am~ibM0EYTczV=X0CHR7Q*0+zGn`e4N#&*V0Ou{ zK*@;*%(u!E8B?u|#w!!!lfsov64R5SVu6;7*k2c-BJAaeMIpmn+^fT=Q0}pZ1rZ(d zcG-?}FEFRP4 zmhc80&8SAlIkqRuvI~39B$MqMM~4S=6bfUeoEO&XyUuk9^yg)3H?E$my$RUXxbI{X z*}me92*VnRxZP4d+be8~;g)vI_W4hIuJEU~Is8&vbVLQ__;ZSXl^j&>Uv#f*($`}d zK~7`vVfPeNs;z3$5aoIU7S9N_bt<1ROEL%C0q&2>tF4H#BSroWn;ZiE!%c>yqgG$_ z7vcQ_(cTwgK-;cjzFQM}LAh&h?Jd&rs0KloYyRMA^EKa_H8u-e5*d)OY0_!S6Z5>x zn3uPft81mV-i*vnsMyAw;jeYiR60aH;O8mZsMaC@LLZ}5#cn%lhKCX4)0z{S?$%8n z3HH9V3cO+glhQ%?`_}xSB;7&jHg_9C=zwR!m8glO;^g6nfTZ->n`7$SZSQ^YmHHJ= z(pbH^N`{s$q15%?h|Y_(<7RIe*Z!3DjM7!Y)|#v9Xr3+B>tfC;MY%tKj3uvWueN!l zhratHQjRpa8lqtp-`OBOleiGKroH%Yecj)`1|V~E%odv>G8Y_tv3ViJ-=COX(wqP% zY0-6H027M1K|jh9irt{30uRsj00J88p?YxyJNq2x$i#9%hmWW=GuscnR#3H@#gkFn z2^JL@<9zg^a(7o$d>S6z`bmmmf`NY^vJ9HNr3BPyJ^e05m)7cZM14(QCmI`zX_t*= zBtwdu%I2=Rpc`vsO&u;_%9K#9H6u6ZPp@^O62wvv6HC1ow&WMi!(SE}tm zqaBMR4%Sb$Vuszku)OD@^?fUZdOS^jl+Q3yd|pHce_sS44cLy1$J1th5xM)lIR@{% z+W4~JRWs=wdG@|aDJpyDyTA(=Lelxsp+Upr&b$)laW&7g{WiH_WQ6#%-s`OOi+_Al zl5g)F*IwqzKM^2M>bm2ltJCRm@&2_Pn$-`USe;wSY(q%?qqkxB)0Y%ZC7P#-{41RY z@@+sPJ$#`hQN>+mmW@+o=MgKjGE?oYx^yF_=Hrs{^(t(o_=>MZK8I=*yM_+v=RO0m zaSL&llQR?gW5}kO~o>h_J!T2hfOgt8)8%MmX_&R-m`4jW5X@0A%)#4$EX|EflX-uTcE z{YBOM#3qQm_UWwYnZ$&i7AxTk7k^&w6+m*J_~Yu&tWB87y2pnw4Yj|?L0zN`+-)e; zkoG%$9>)CEjozl$gX^&c-d(u0F{1-JWue7i-->wXD5YVVtak0(vl2jN%G%O3p7G7_ z)9hC*|3$=!byi;6dL#kH#dM`?s5FNrp!6|sW1ao!`Af``PkrT1#($TwZx}5$9Zg(l z!D)y~Luu)^wQQ@7X`BW7%XE#65F)IG<0Dl?Ex*OCbU5(eeR1ugOM%5o0}{5Vp=T7` zkBD;j`p4P5(w||k!A`cl1eF_#u1fC7AxpIlcvDqn+CbLw@#~l^h4+m^)&p?Ca;d55 z7D8k1srzBU>$IkrJ_Dk}$0VHCKoP;!R5%OH@5-Z;{E5>cX=!RSWJIp{nwuWo4d^3Y zC&SvR3V&aX1wPx!O-rekF!qma7#_K|!u4%OF>=RE=`Vqu`Mj_!XFnicGB+ z!VHWK65hBhakKVWzrt?;|9{2}S@>8^eJgDYym;{e+-AJ8)f;dl(^vM`W{Dk|uy!Q0 zRd$>$2tdFhg;qL^sf0>&3x8c)Ks-eLM{6dp|gD zk3ZoI|Nipx&nqbdaF2;>;b9-HbDHr9W3I&+-yr;l4S^>>;?5tt`Z{oJK!O)TQ#du& zG*bUP@TFHIhq%2@h8){T@@@2s*CG%y%NaV?It1%oLi@e@(}2tT?Nvav0oyDfLh8JX zz)cHn2QdK6xNI}4OPjO8892{vu87(N`OVsdZ4Opk!Y&c_VjD-8^D58VRiqndm)9uf6eI@rgy)+8+|47vydJ0J0qh_#0g2nobsMoy1n1Rw-Wi z%H#SSC3_8#j)J_rtA(F00d{ECH_}q%uT({Ei48FgO?byB`Hq<>+Yk6S_$FZ!Bzvm{ zukzNKnJC=9Z#XDmZ~M&g@USCV%D`fh-C;eAfPlq#a&ZRml@(CCH6ndLecuXT~ zwH)B^>1<$9&RXeQWBGl}69cia@93DuPexdXS9*w5+P2ikb>CsAQM*n?l$P)xfL8?A z&VRdpK585>Jy0IKbZ{Q8JI*FCJS6(Kk_eT;tF8iuLx7{MNlm;UMo{a>?(Wkd6T4oi zmz+&LMw(7^`AHgnOG-HuM2cL`UdY1qJj{xcEwmt~dSQf{J==#LlJp1;kUCH1$D?cdV<#d1rg24)ET;dBtos3)wE&D>u42SUXJMxFgJaq9vNuXScJ#~Xg-%}?yYUdd3o zdvaHeDH#i4-u)6xqkIYobnh(JVix+mE5lVJHezZ)qi@<;hpx5oW8%Ynq*EMQ+z1xU zXld3keeMH;_i2{EDc|gm#m1reXMMuA1|II0Zh-EpY>i0_MPPNa^d%&neP9s@Kf$yO zq)+uN7Rmf)5;|DrBR8HOz7~cw@A;0%JIk|2v10N@NZ(3&Ug=Bi;4gr7p~*}X1*c7; zB`Im|XXUphHVfIl*?LxXT?C7HBg9+NVEw~NmjYn4G^!uKUq-6JqipTJOw$#A*ifDB zi5C(c>69)v0Cg_v#9WRG(({9f-Ky06mD&E{`I|+#8DS*$txlU@M5bEfIYn1QX%E_c zIhU|$1@8YLLjUPh->0ArBx&6!VZU?=7sLmpBBB_TqZjZ*jXe1RGg`f^NL( z+sRF+_tme1*moG@t6!d>yo6t1(|NTf)OKH2poO2?%PXF2HX^<&oqrx-5jG>iLgbEp z@i_8Qv371WeMQ|gr>%f|)%)@0kmP{j#QP5xL$AfKd;NR@Cx>n`vNtb$+#f$5-7|+3 zJ?&buq?`1r@f1@}_4KT`obF(e24Aw?bkHxpd%JqO-mys5RJbIa##**ELO%k7#OPwR zJ_Vv>zW5_VT>frq{?10TUN!|psSj(pX!qSXYq;{j^*%%M&Bn235`>~vV`jT_tF2Ty zBlSM%M;i!QZ9q~uz&@P4e2=x?t6OF*T~ko+CGo;74V6w;ca{=fad+t-Y+4_)t~2ZB zUL9G~ewynLr1-t5)5~(GXFG_a=haAzT1bB(X(r99gG!!BFK?^lXsda#Za2fPxEpSn z>aroAP-XDmP%%VmB!L`?F(f^=V|_PsNj@t$hvC^kXS>=*JMqp&+|c!Q`;1vk;2See zUlD;hc5+%a@+3-?C2xN%p9b(_8)1LKs~!v#?hq+o^qzP98ffuVo|g24ruRIo!ETA^ zO;0P%R@ACXCO7B`BJ@NamaV=oJ&h|bAAYXdIrl=3*r1tDuF9r| zL~q2LPo>IKM2~B!?$cPI(1`@h=7O)&d6LtkeIp6O1fG>v7%f z(FAQ}JL+O3{T=u4OaX6>BVW%R?Hy~jUhpnP;7Jec` zZ+C5V(hqQL4$&sW9xQh>GBCoE+ZN2uR#lHB5^G~{0ny@BUJLOB$>qA->8Ab zZqMkcw48Un60^ZlbGx}Ks;i7XF6El$J<|jrOmvbl^=n=KO1B~izm%18#-p6PQ!byC zV%ARCYw*^*@U{0&WVPVQd*%ww->mMU{4eX7`zxObPn_?A(eAg>s5F0;B>fWau{tZ6 z9q2W$=_ znDd@Vx#PUfW7kj7N^{qptlQt&UyF3?J^jp5K;uDFW`_TgT4b+{1j89B`ljz{iYpU# zbMR+`)}t2%ODf>;raNcYo%mC|9>cT)MDWRQUyNRw@{v*_!j5in0FW6T6H*>m{xr44 z6d!8ixihQ@w-Jb;RJYx$kD{|GN10v)yt??2@7+uN-U)(tR?7t+1wtv*Z!L*COYjRh~#5(=5r$ibS{aE~i|K@E8l}s?O(&qchNBIuU%X zwB+D7E7c(GB|v`fT3&u>TNI??E;)jA2*vd4G#T0Kc~mYN;y1_Ubq8gT#TipK(?c5+ z{eJ2C57+;vt1564IOIH!{jel|tv=O^dMBwfjyn|#5b5t zKolyalb?3_SqEg`RN0dx%6mMJJ}4CCtJ?ixE)xMvLO>IF-&);dFqG7B$RR#-_=s(r zV3l!jPr@oDZd8u!-2<$&2W<$bg#(G;a}?z0>e5{75U%}>>;1p!uRURvkwJnT9!IJU zt_MC<*F12G4jms^`1OsIoNTTp211&U2 zB$fU>Zw|sGhIvr^m-!OGgSZ~5J$sf}Yn^*3TKJxSfwG{b>Otvgv(B?8F%4=&c14r^ zDz`1O!+|5n9b5Mz_{^l}!_^P>E{rBsBY3@N2&cZ?yK;3h@Q;si?22>EDF_EXcIE)@ z{pT6rJnsT^{Slm(x0mZPF~|wY`Q{8i?H&*oO$lCnwVTuui;g52}}^ zkzaf{`COSsV)yK($v(cn^TR*eD*r%7b-wV0R9=itMfryG*kyB7INNtKJrNc&+X}gx z2PVrEHDz8jai$f+MeR)d%)QqWC+s$AQoT$U-Itmh)89O}plz9+`JRR`=VO%M^-l_> zs|yxV zaW)^F#I&5ZiTUx2SMt+hA8z~LbJoxGDVZ0n_q2IBugAPme<|Ys{^I6$;$pFLnUMTI z>`J*(TcX30lQaT0LJ~_0oGYaoCK@-dCpid6-@5h(_Zhz3Q!ZysQtqgu*-|i@ljvKW zGtcY_o5B}1I)>Q%>0K0!jl7xbYyd*z^m$>kQRZ%sGW@8NJoA|ambZY5>=2(2KSy+r zV9wpZmqNNptZQ@488z-1mY=G;r3Cq(t7NL0Ujk+lKER6jLT(Tb|X~vJqC!wm(g}twpQlX&%3#*&tG6fm6 zzcgVV{8EqMS^aef%G%x!GY-mocC%bCzHJFJV^7?+_Y%yq zr7c@#gL=iZyc4wZB|#zjiIZ6MZh;un3F+ors~itY4#5{scF%-8DVvsawDR`T&2gbF z-b_QKkhX{#IjgG+8VOnsK2M>J0x81Z*ZLlQZjyM)3}oUrHF#r}eB$PYo?og|r1g=9 zPMN8ls8+mMU3v%qm8W^q@^PAYyL(xr*r_fh$k93XQ%r^xqW`Cz_;>DA#pdUFZIPpr zWb5uTma1`61H`voE`_}ht35%RC+sY$_Vtawi<)ywHbeW2);c+4+Jv-EB5Xc2iG1~r z4j4}BpOwA8c5R8{Dli-+kt$M%QZBbMwdZRIHReo9p^*>6+cUo3fjv5-mI82nv!wfP53m`D3^DPg57 zDBO0xH&vjslJ3mkz0gQlNXXB}cjv zE{_ekHW3(`FH%{K9i-uo1*$&QXi4zWCxcx%-lv`qxJ7~#SEoMpe?4*Hpz=%ZG0hz> zS{~64)j6U+l#Q6;0#nY3CGU*S>D~1Pn=OV42nMB1GMnEle6`BW@S|d{9#Unadsc`q z@eAy6OniOxRFtX!ZQ(Zc$NsIw!7|TO`&YfEwiuvH@0=y2;vTl9b)L{jk;mEZtW87g zS4CCFD-qkxoBm--H(^CdOK>-y9~hd&6hzIFC|31vYlH^(hm zcFiZ=aI)M4grD!ksm3Vh(%JhlVyy1gZu)y!bLxl7LPY5YtA=l5b=bvH!s7&mQbZzf{6b=| z@1JA*7y&NImrD(&xo&*{PRBb6txk&qoVGO)zbM8AhT1j1zqp>TPr(X;(9@7Z&S8cm0+`o5H1Ndo36NgDyqkHowEL?6-N_e*TlEVXZ<;JGN zAibICNBeat8^UQ<@(z}vbM%GQ*uJ?PEstwH8~dm3P?ZT1Zr~PhKK$*P(5H?=mXysCQKsCj9Nu z-rYziv1#U6nLErs1F>_wT5~d*Bt+i%h(mxohxXbQGuYmY0{3s0fgBMeZ`MdbgfI)W0pN^Zfa$nd8UP2P;1FDBH^Gy=D%f~dmy!(Le7$dytz~l7lA+K8P zR`fQ-aVBSWZY&Tm;-h$=>b+(U+j@(M3v-|hvZU!=YuXD>sByhBB#^t_PeQJVY*3Q8 zN-bz@+>;~Bpa_*E!_Z!tZC4o=#oC26lRwvROqA{#pe(fF29hA72k)jI)5wwAhFn(z zw%p17K@3A4sAl4fe#TnWv>i<5*{_W`lKWZxaEnFT& z)|=~r9eU2kmd@3J;ndvPW13y=FLgxfvLj)t+86F=21mVVfb)=GeF3q!?I1-9S>3r( zGy)L*VMBKVw2W8N+(EH;YT`-*W8pff*^OZ2;7=%OA_G-jSp_N=o16uS^6kT}?M5!O z>Ods*pT+opY=wXOH~(!LJykuX>9gKPaiCX0At)p~75;V@Q;f;X<%~7hsEC|qZs-zMM z;L}Jjgp$+TPtiN3VIwRxcu;28DU}vGfo2-$MG(+Wr*BMp4EpO;SnU4LF1kIR|Iame z5%v#gT>l?Fm()7Y-z7q2jXj7)4x;0b*}8*~%2tjlyEMr5z!wBfwvC2B8DT_ja1l4N>K& zCxCBPK{Ag>wcH&x*$)5*rBu}71JEryhp0B5=BSCop!K?jz`I(*D%p@jb8EEZKH72H z9Bq6|V+MRU+-E!YMev3|Hb<+w11T{amKYEL(@{u9~_Be=Dj3`XJSy{rfEJGllR9HnCB3;NM6 z(UW8XTtN>(RfjX=b(A%dTNkSY+1ORwzy`Eo!M9&J;%2b3e&p;2@V^6P{N(>I5dOD; zB!TIgctmfweCL#b`57J4 zNRnQ{yK_^5p3J6t;&}C@$^FMPGaJQd$m#}xx(vmRmL1cOb~T@-5Uo{nscJKk_#Xs> z1OsIfp!3Z_kHE(?5x3!Lvqy-Pg`<(xwoG6kO}v~ZduR?o;uS)1Ex8##2mH+xKfw5I zIU#PX88o8E`3}@MQbnDp`6>D54l28UV9SV00_~y`9mC4SQkT%0Z;#%skRWzPhk&b9 z6@kLyj>=7Q+k;6$vWI$SiS8r_nBQrdTRcT!dvRtP`lDaXtN4N2oCoMIR?MQ8jX0ck z6mleUqy}u_9ZJq%09t%*daen9CGHR(=lV?7dM?aVC{^73c@Z~_-?j3rJ6zT`^~TM- z>s(#E{nwc;^SSZ=3)21uJeChX&_@HK;V^-es8!;LX&SUS=DTFtew)s_8`S zxjU3&9kDhYfPu9fp;^pkV3OZKV=&EtBFZ7u-?wVZHPpYJ+pI#)bqq|wS~~xOFYPY> zJ*w&}Lz@l=@0L{N29^4DG7q_1ck$Q_>YCH;Va}KOIYMQ_DB{sb#`M!xt9L;gxrt8g zwe7;6N$^`uM?mMXMa%PtA}|-I1A@O=OmfwhaHBDP}7->o@Q=kRMpA`lM&2055!;&i~( z-o}Fizs<)=p1V?eG9ZFm%l>j7SdR6WrsoQP8su1vtmQEcLy#wOn}@g(l)D;`OPW4x zC621Jwq~}Hn+;PWmvcSaVREk2p2Ur|EN%b@zXSU{V%gyP5DtCNnYagmX?oAC1;u&{ zm6Bhertt)#XC>&|pePnsW;uNQ4K3Zj5oiNiy#_eOGg z=Jav643$Q_(_-cU^X?gm)WrOfyVTII3)oAfciyDQF0p z422!a8tnzhv<-QM7JG1`o?|({mK%7UMdayUyup5Q^ty9@!lF5w$p041QhyC0sJu(L z$s>5Br|2{&5-Lm4^(CzThSlW&Q0d`J#(J?eQd|rh03mj#!gw}*zqV|G?geh`N*_=D E2M=HyHUIzs literal 0 HcmV?d00001 diff --git a/images/header.svg b/images/header.svg new file mode 100644 index 000000000..222c8e3a6 --- /dev/null +++ b/images/header.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/images/icon.png b/images/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..2ffe8dda6a9fc3b0fcc383433159c5a2f3e35a3d GIT binary patch literal 5962 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 literal 0 HcmV?d00001 diff --git a/images/icon.svg b/images/icon.svg new file mode 100644 index 000000000..8277743b5 --- /dev/null +++ b/images/icon.svg @@ -0,0 +1,4 @@ + + + + diff --git a/images/interference-preview.jpg b/images/interference-preview.jpg new file mode 100644 index 0000000000000000000000000000000000000000..1a15f5c6b3d57edc6788e63f464cabe23285ade0 GIT binary patch literal 97587 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 z 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 BWI_M{ literal 0 HcmV?d00001 diff --git a/images/logo.svg b/images/logo.svg new file mode 100644 index 000000000..c225043b6 --- /dev/null +++ b/images/logo.svg @@ -0,0 +1,4 @@ + + + + diff --git a/images/managedobjectlayout.svg b/images/managedobjectlayout.svg new file mode 100644 index 000000000..1c3a5b131 --- /dev/null +++ b/images/managedobjectlayout.svg @@ -0,0 +1,3 @@ + + +
1
1
HEADER- mmInfo: usize- gcInfo: u32- rtId: u32- rtSize: u32StringHEADER- [0]: u16- ...- [n]: u16
Any reference points
right after the header
Any reference points...
+ public # protected - private ~ public unsafe
+ public # protected - private ~ public...
1
1
ArrayBufferViewHEADER+ buffer: ArrayBuffer~ dataStart: usize+ byteLength: i32ArrayBufferHEADER- [0]: u8- ...- [n]: u8Uint8ArrayArrayBufferViewInt16ArrayArrayBufferViewArray<T>HEADER- buffer: ArrayBuffer- dataStart: usize- byteLength: i32+ length: i32
...
...
Viewer does not support full SVG 1.1
\ No newline at end of file diff --git a/images/mandelbrot-preview.jpg b/images/mandelbrot-preview.jpg new file mode 100644 index 0000000000000000000000000000000000000000..dc241bb1eeec2c2704142accb01ffdf2193853d2 GIT binary patch literal 83794 zcmZU*1zc5K&^HQ_O30CrPDu#?>5>+ZE&-*xLrPMRE|G5O2I)o#0qO3LM&ukMrG&dS zKJWW|_ulRA*=xujEz*_$6oc=9rGGDygGkdRElKct&IB$$+|iH#=` zG7>5h5|RR7A&_vzO&yHQkW9Y<4)VWx=|<{ALIN%!g9~_idx4ojo?!rIZrPCVe`H|V|73Vb z$SBAt==U(tQ84bHp`fB5BLN9a6)iS0m`?8`#_4jM z;~pKXaZ8#I-VGq?2%LDTQBD7_^H3_@WE4h;$_=L2z7 zBQz&k{NL|lv#Yq!J0u9kRu9yS>6{4z9(}BqB)XYL!iGkNp}>&Dkj|WQbYqeezh~^X z9FWZ%3rneQ*k2%(kDCJZ`WW-M6BM7iri^=hB04p>Av;RHnrRDh8=Cm%5JpAASL0FN(X?fkzr zYSpq?y>A)10o`({2P3xm61pA<&}jMM76;a%+%3{954sgpFtCT=^x{Tq8u-_okdy(|sQoa};BlFK+y(XfyfrV>TPlu7J5nbpl#iH#GlpiI=}7feHD*M%Qg} zbubuxs1Fze06@#yTc2=uQSgL{{Pg1|1l|R-9Qw0L>oy|?F?K?RwKKp(ea2^ZV!_;X z%6Yd=cTDdaB;wPFdfe6fMQ7Xf>h<`Ik|kix61)IV&~ zxm7Q;L|_Xuf_daDX&mP*p&QLX41(HLSU18Ctq-%xOHcsFq2$U0X$O)EEhJ1uZ1{f=P!j3( zTUm>mKQM_@}A zCs;&HR`V(Gt*(D?T1^h7Rg2)=5`cgRV!kxNyQM=J$Vf{Wc#@tq?^#`y2~#?$gFo=s zWE&%|*9cP2IiRJCQm6@VXPcDBGQ1I=YIq;HgIh_TGKQfMO_PB<#b+Uf*VWHm@-jG6 zH3N%6-R+G6g&u$K8&*lhxiOq#k757aG+>O>ez@c%=zXFo*xN~@dG8F=CfwejK3U4p zsIdn8)Zo1xojRO3V0X!4**};feK$WDNb!K3(JE{(47g#p-AlBSeVy^38%U5R|1m9q z0kU8XactpSF$p5WF30{*T5dPrAW6*OVc+)(FtU0X{r9Y$e72Eon2APY^)AOO0dzui z91=uEBy$uM?-iaz?nUNG&?n2lW0SJghUwh;21dioVJ)U+JDRL(|LNfaJzAY^r8$zf zgyz${4}rCNIVX^ma!9iAG-(4(MJ_|`oOmQ#zee@mi zu#{I?YmT}^seMY%;asTJ=nI=CCCEo;>{{4HkB;W^Ef!BAfImUZrCK`_)m+ESin@go zka>AMjhzg@pwp6-f@qm?ov;Pqf0S+wJ~THyn#iTBZ0TxZXuf(hQ8Qqf*go{Q{S)m0 zN0}9H<}P5iL12yR)w@>!@@goY_V|WMytWo zD#`~C>CaQbS{BmGAaaP%3IId_Jdr!gwmbEJ+R;&v+ZYZfEf{9qMJ`b$9u9x4ufUy? z|K3q2;|?(W39a67E`w+^z?1uv+Ff#;F-eW+7dyxfypG|hAS_8+=f<8jq=`u&>4KO9 zagc2Uf-@XqYfaqWHNNIOJSrAJb7i~;^H6R_D7n(*lwzcBXyBiwhf-fENr^Y4Z#I)Z&k?^DR zP-0zAV4;2(%Y{0fFFiDXO_+D<8Ng~#wQi{5bP6a*i?5Ow($YHpo_D6ET^N><#8PJN z^I!OG)fY+!7a&B{6>y=&WH^dN!Ez9Qp-*`B`TIKv5Qz!InGc4onBusl`8=5JdE_+>Aq zU?MnWe-Z7%h#86_=+OkV$W|BeQsmA_J*hvMd)B%1Ur!UKtJaH&7zNydkq-G!H6{Js zV$ATqLP&lL%YU>*J_*0oyvTseB* z^~YMMwG~vMr|1b<48+yXq}#{#aF{m2Oxo#cz3Aklq>8*Ppi#)eR8E0Yq*{7mYFin( zbC^>lF2I?hNft*T*_!cO`9)knjW>XqurO1Ud+z1R4>e@=hf4r<&W8nviv!jmT+$xE z@_E6UFe@LBhvxAvJ2T~j8*Ti8XI~CCV0x)^I z)(z=9irchE4z(Mq@^b49TufvR0(i_nR%SsbjrRb1^by-zG3g4$l9or84(0E5dYSEPN)?4_|d-L1AMs6LDYBIsS>U&he6iB!2BD1xuY+eDd zPX3_N0*OS~04<-8t(kS10{a7aRYJ2?b}w5UT7K6Fy4Fvf@7ZS$BsqR7{OX{`*D@@mVqO2ax`U=%&mRt0AS}Ps zG2!^YT9%D3)Naa)?KAQ>O9PI&eeSAAqrM);e&LhI(taQB<~G|iF*OHkuiRr#zSNei z0DA-j(-Zl1E!wDn5?S=8clS=aSa}lzzusLnkb`@dFDX&joSA+c4d!zndyU6nKsP503xKxp5_6g)4 zzQw)t!Lsid3HuWSNTKHx+;^ckPcRdEMLiKVVJ-=p=tR4G`cj8s zX~0v2Sw@39f!agxOo&4D!BZj#0*_Ie8R7yogvjr;nT(L;0Fglyt`CB#Rt*G&O3trL z5eGFkf>!w3Sj+s4YYwQtlFn3%2H-&tUxBdr*F|soGMO``Fm#=#i(>*JX3TYjusx57 z2gDx%PgJXK{=GX#e#J!ojVrs)ctDK#Ka4x8d9TatG(U{@X$C~IE{=;|@x43iK)0Yt zEP`Jm5abrM+M0mR^IEjqxK6#jzqO!Bi3mAph}X|M)>Tz^7*zNw^5^YjbW~|WG7GhE z2i}UKxabf62z$)HKh%jwEI6%wI0ZjK6Vn3FQR5#>I8#UClHEZ^U4%WD_-5GWAC3F$ z-Mdy)soG2_^ku_P-nnjcQ}hW(sV9ul-59|?0(9lpG;tiBJhS^z-4QE=_k2SG&vpYd z;BF(ep<)LzMlvlhUV_OO{qAmW@PkWK?w6v=V0a3%6JntqWo^933I!kIt+1E$tG~ggHj(JM z?y)zn?tNSuT9*4q`T4KECb_@ba_^2XM=`7!SL(-241GIK+8pLl#!=#6d+htVnur9+ z;qJ7H2P-+RK%P&w&wZ4|dhY%wy-X>k#fL`PA)X^ zDpmnfH<@SEo54aIb0l{L9J7Bcax={rqEvG;jo;qq3vr7E!)1K}xuPDs&vG%941rb7 z6EhqHo0y|as9hsd9`7O^4a1LIY2HQHbLA&s4{D@M=w2jHo3|(Vz|8O?Turfy3*0&g z@)qwf>DprwWE$qYWB3sv&9MB;|AD>gvoy~;XpHel;izc=NODaCY<#F#cCCiAL9HDG zY{FWoNO6wOa86NGY8SbwiP8d?bY*Fgt&y#mvaK4ashqKx!M@~2=3}iat*zo$lytWA zOHJ^pf~FKIHSZ^uPxE*R5_eeJ@We6cvyo9!uhynSI{FVePhzvC<9WHXR5acql5QJKquXdXn{5acE{3sb( zT2J{hU^bGTQ)ag}7ZlGUmhNgg8_*0^=YWQde=|#|N0(peS>ETxF&_VD{15E)ijpNA z5u~SSN@m-L7UK5M!+=Vp8zkFqs{^YpQS-Z&SInsIMFo>h!!|tFO@dOp-t*(}H`>-5 zecA98}Dj$sNt z9@fD(&N6E=RYRWx?qkyUtWdeP5GQ+IZ}G76mN4A$I7C}<>eAyT8%dF6Rd^uNki|9d zk$4|xTlM=rO0wZxmEw-pUA}wi7=lqOZk2*jkEvaXN|r1HpO#O%6y>?5?~FI-41bce z5M;(l-+c%c3YOc_%vDIWfI*u$HXM%Leeb#Ivk&2F&zQ0; zpVj+&s$fZkqkr|+MceuG{8_=UkgD3K1hO@=9g2Vaow4DPcb^ZKkZB0+VxncMustj) zWiC5U_P9+K2|^7$@FC8Z&)KDzf=tt@g%ebAUegB?ZpNXs3pE57!F&B-R^%xkV0Lq{ z=z#10dnpA^+?{FAf8Kr&)bT-8RD6KtP4lQBPbV|nLKQncb0*A&cuE(_5iaF z6O!Ofr_~UM6D=i|;1ukA!|T%B>kD3O;e6(k`#rfN81O%dPR)hW1T~m51@Kf1YGU(L zAmYVIXWZp!fgf8y2$pIYb6#F!F-P zM7GA0X~3d3Dz8~$3I^&*?;%SW_p<$6mnO3Dz6x11gYO~m%%7vcPR)`a3>T%|t5BlI z@s_~;M|{Sx{i775BP0olXnR6#sh86&7GSXc>AFiW4#}&YFBXk}JmtJ({QL%FtchtF z#^*PWZ56nPH-4PnH{4MOrmrf9R*?Pdg*)0s@m1So*oDQp z{b;jL9Im&1L<^7RlilFjz>aJ6S`IQl;v{!_Gq?vm`)`Nft!aA%MtFn!LD-{$B&=T3 zJp8NoW6#N1bO@?MK8lKU_FC61R*>5qu53~+wS0-DQut$%a8h)6gVgf-a>ZnCv6Z)a z;7i`OHtpfFT z#vjJ)8T7fGo@JypU0u3IF8<;<$T0US9sQ$hHNr0Iwk*c}_M1#rya#J1L+8QLTz5)i zLhM+5;8sx&U)ZX0Dt_p0ZMSjZj7?^bQ?s(`kYCl?qZ_14d*$Z+k+Y=tZZ=CI#uoAw zaWh+Al6oK7Tv24=F8amlc+b0C$Tav;W{TP?`?%jA;dQv{CSek%RP@aD>4h6>JXQLX zm#8I0Mwjg`C`qQ!;Z{+#`snC>>nVrDQhK3#f{s}tCt<>i_3fDW-pZJmc<+%Wm){jb z5s}6YN^!ro@h?OTmP=AgE}E<@aJ@hBH|@KS%RQQxd&Dt)cGklQyC1%olHzz$_1y}3 ziuwiIxNSV#J%0md1&I)3!PsTK-}fl6*k77FpVx_+N7V*FOQ+pj$Xqo;U<;hj)o&qErM63;_wn&4r&*aw4vrq#7h^I+?X zFrO0M2`sVQ>uX%2V-4(_-ZdaKUo4%FO^plY5+jG9asoosRCR0yT9Jy`DM2Eo6ZFv zq|`+LG6Oo`n`qzO*wIRTCq?B{@RCEUA0B3R+hFN3F(?#IV=Fj{0gnx*sMEsq+xJP=9o62U6Y+;}UH z`%pFL#}sOexqYw1j=jBXZWj6L>3zdGwHG~gHHUh8Z#X!-+#YucS9^WOS2Jo)41YO zaSV1>32j~kUN(bund($$YI@Jw5$dPz*Q}2|C)OcO1Ji$qp>H~@whTloPqd}MQ)ikV z_wJYeo_M+QSHZ+Yr2XmMAFWMy*&v^s8>HMB;bAxCBd%^VNxI0y;QA-iza6nqbTRM@ zS}uLbJk}|y@UB|o5?urb+utr1mFVl=kM_7hx-W4lD%_jfx!91hPQaZ+Ce@Z1gs|JB zjE+{>_*GJZ&;y63AVB`>$Buy@1qY@O zhanfzU^Z!t{O zwXEJiEY_WgkyrvA3UJsN+oz$H$gl5DL@7$32eI!YeiU$~{RGtftux=KB{na=3e_c| z^bUP#ofa*n$6mZGt)tX+#OZVi-`G}r3uD=p6g4;ST6X6Ul$8l3U9MLt!7Y6|CxK$Z z?xqr&$X6auP5nPN+FQvT0MZmka{gs@k9u~jE}ojEe4TVoqKGE9Jf0ROsv+d%-_>XH zWxvcY15IS6Rs8*d%_4v~tq#JI)a!Ar4id*Pn(v3Mi`-_Ljn@Gz-3y+w&|{Lqn|`&IjW=J`G$(O~bRZ+1CDBd`aFB5gQITNpiv$39-u=}cnnPbOP0)4}tS6A7f z#0|HrgcS#p%=8oTJTVbGm!SU+2skSH3pxmv#DHyKz$DegAC=*qtt~dStRLW~a?k-jf3J8A%5GH<> zrWkh%;I<(naF?6E2g-)3&NoI&THWa`!dt!`HlN(Qbse+Kzm7(YO$sWX!o0Oce&?w; z+W2W|YJL~3pa*+W{S>=SquDowyBnaJ(yvG|s@CylslGy>--jqoUYF@EIlkL`^SPO5 zR5#z5+e4JTQww;5{H{flXtb@9yIxgOFF|p5Vk&9KcN!cMsmN8veSKNR1Tv3dbxzev zId|TAuL4@Zfic6w*;RPhgse~sHT}n4VP%uLSGqs2!i#mRDA*jQbui#Llr z+dXdJ*MXZYq`y$8``SQ;7jv(qY$=j|?PVFx{rpcAmFG<6pCfe5O?l7?hB=JC9krhz zgrmw+2CV6rWA6PG^sQ81IBU^C$Oy%8J~%LVBHF+=@biecx4~}+`{DIO8fD%&eAw<; z5@}9eA~6;I9P4LZI@6J`yk}!JSP@}Wi&T;8h*#G#TN`jK-Cke(yl*q`u*^)C2}PO< zu`_bT)+hUo6Px|QzG6FPN8b&~2fc_daw$z5+Hi3Q(#CK}0@qxVV~gx56w%1bKFTe? zxHv1_vVZT{Na~CKI4$4Uyp(b}`+Fwqy_%?VdfL6XdG_YuSK(rd@JMOX9QOi=l!-g% z#9!b2sSBES=YN}gz4w>wQ5w^_0=0hBz8Rey(s=xcIGX;^kl>inftYHd)H&?~f$pY? zdJ#S4nq&R3{no+rmvBUnkdqGs!}i3wD5(u;cdMvhovl%oz^bQm-cQP!(_eW_K08Z0 zDZ>6-dG!-U2PFBvt5t10Kdu&BaJ=>1qwJ4J$@g({M%L{U_Us(IDOi6y&Sp}ekjs?) zt^cWCvFx(5YZj4Fn&+?A!Dm<660N?onrvN||K3?)!Fnq!ek_np80Dk>gjSvPYS<&Z zB@U}%wW+EsY~cW<3AOxEl{4dJrBSuiy8FRGd2m$g$#y0X?M#a=ioKl{uSZo&)pnqG z&vj?XfKo-ZC`Dsu{nu$g)T>e#kYfaT2}-6u-r1y0T3g(e@l4I7tRTHq%b)8|88As# z6G6N@HnWj_@M9B{{LBhE)BP}cU69u~AL=q}vkCH{62N3#y$ys|P^PP}flPmv$6X%J zl+R|D4hjns-hdd9O1K^wklvFNoKt-kyttSB3=1-)P_h8Y(8_BL%rMcSK&ASG0!p60 zbq%O?YSRlHWum{s(Lgz4LALR9torhT+;h_1%V0{4`5Apn%RrD7Yn=ti=lZ zffBwtGV$jB?b`TS9q^s!2@HTCQ@2erCS*xb_P7#26?AofzXEFd`ZH#HAQutO7>O z-%WLO^p4u=kw39K{I+DudpAg)8n@V*zZ;5L|3nFjO4I*gUQVmS<>syr%XX{E3g_c) zK|Jx7YHoh5rF@T5C`2bSV$WmK63U{}?3Mbi`awM=Jc*|#EF*l-N zCEoWTx7d3TB`PBK8hFfz^0aY5mZA}@X#(?#7@(+uYuh8+g}Ghy${c}v_j*ndu&Nk)hwO&Br>X2%_M!?DQ`KiF?$vaDaBwh117!NVJFELuS zgHLt4rNDPm9pwQ(UQr)oZ)5snefZZNw}XSMODW&|yMIM=^vygsTd0)D{c%dmQR*ToRETH8r)gH7q1*s&7-gT?x8Dnr7bfikawj zz-enm&>}?Mdiv>jC-(?y*E2XaZSZ{hz%TdNF%#_+pQp4l)OX`A$36qxUV9=KVR&sk zjo9FsR97?7Kyk0r-?6q{H41)Mqc*#%K>nJ$ZtsW7Nu5VK%A8MER88NAKm=lV&E@Yw z`HSn71s_KFD9S%g2ks4yk+jxT)0}^6&QFd)a@Kuc8y=*lrfZcSKmBm$B7FX1pOuMO zy-mBtK*{vHY^^o|ACaYO(|%BLG;!=}LoRxCY3;Cjy)XDF&Y2TFTwKxh4u#ZQMj%PiQU0?VZ5XCve$H%O|!Gc}o-Kdx?&_(Lf4l%?)g z9l2p_>n94B?fiNnsjP~|u-NwQe8!l;hj{EA>(f?Ih@7sorVo3hv7mN}v8AX7e&J=Y zD;A`WT8hGrpQ^4jco06K z7&F2ORA^Ubm_DeL?0KS4ZHuy&T(uKolxNSUg({w;+I0fpMieWDc!BD>tG;>wRb%#i zQ7Xa;z%Qc01(i@zE$e>tj43dUvI^DE=J+$i15h?eLvBlIbJB4ysNLB`zFCk`&MxKG z+cM1YGq49jXW!Oeg3vQKsJO46oq79CgZ%@g$P?7;hicauz=4uoj4rU9s7#6}f${!p zq$lq~US*f`+bO3+1c41o;ChNNXIE~(*H|BUza=T-`A%M419nN6kY2X)*_=e2zpF$Ht?K zA`jI%T73SQo#pChw^%%)gIOW@V6;{@TyWB-*J}u83Bd9=k+njuYrq|+4p<1WLc!4& z!m!f7gM`$EdcZhNIn{f&SZp3QSu2&VU|cC!X|>Sv;JOyNTK}lmvGbZZHb8{er5&RI zU|0~WOWPFEP+q0Tlf+R3kXvn(|GK;oTHVxb44a2nZ(fRja*m=7f-Oirfx0TUG9G^H zIf`0b9$pMPtrsY~vUWiG9fX(#h;?hIE=pIJ+KpIvi;+n3_pr8{EwrdW_FC!9|>1>l-JQs!cF> zUWYe3A&HYSt8=y1=$vwNl@{vYxMPS*l{2zUI5})Fa_C}woH5u<7NSi4L8?a}4{udP z7E_;tk)&VnS_v^Z@l%Y$y?{@go|h~{b$oz7Rp&Ksw)e?{B>C+x2?+1tnFk(n2FWfy zX(lE%0`olu_HSQ}MEp7xxJ*k~U*RM5*tzn%2s_dqF`)BaU1^*Doza5{*UJ_A>pHTKj?ie;MY?<8@B5wPOYbh#i{TV_|IsA)6g5F zv-YF7p{4m@FUHOOr_&cF$%iRd24edwsb0Ufq}kCV+v;*EvfPRmLJSXfk&OLczP1^v z^vYZFn5f5q|aYJ zJ_nQ7M0}Xb0>0~yzhvb%NO4PjD@z?K4(v`BEEn04a=d8G8pITM;njt>lQkX*Kco7Q~w|+dpBXKFzIJK2|#^ zulWOr2T(GKyq!JRei)1i>kQO$RCb&z?MV*_pSBaTi9zwRx5~YJE~qxH@s04yD))K5 zTUCmag5FbA$Ll!1)TSJ>V1lY|Aeg7V7j=K+hhn&{WPwsfw(G*~+DP7-K8B9&%ypyD9Wx4zA-4M%N=?wEg;2i;ZW6+HGR@-^>T zfua?EPr;rdPooyrE%clS8UcB4QRsR8qgO)mMGx31@*Yet3dy4hg8IeMueOpBF-Ljn z_fRlyOk=WXg_EP^Y{~To$rzlYz8#)BvDB5PusCd(%0|KXV)0}&h}xyzM;DL6!Zvaq z#^kzEvpX7u=~6FahZ#T)k4=*x5Zs?5sil!D`wIx_U&6jH(1eJYnvcE<%&O+Ll*0S7 z7da2!uW{=e%GRK;*t@7@!mR-&3B{*<0qY)b%{kfbXqaThHJd6hXZYuKAju`53*KP) z`z}qQ7`#pcjMEc~T%z!Tw`Nv8b6aZSR2-b4+hN8V{yDIQJnOi1L*iDU$neh|_B>uL z#ur0VQWy(16~k9BcF_~BQ=k!iKhDq`{Pyx^&+m9gcxJvQ5x9z7xouc%ymH~(nl3BKErG<3{9=vGg=e%(*&vb+kWMdp)12%QxUE5n zS%4UhoBDR&8shI%kNth@EPI1g(3~=pmdG~yL%G5>Hh7#b(wF$l@k~Yw@r=RD-`8av z-={nqwhE3sIX9(RHd|!S_tDG7R~tDl9lOmd!c#G(+GT_B)rcXE^=eDSt->5}T6yI0M~-E?C{gO}4^?suHSPtH%! zHfJ&u7V^UpEE+XJX1|NJFGR9DjafYtGg>=zTwYpS z?r~}=n)#z0rFdoRfbel|+_zI&CN|>ap$ah_xc$RME z9iC@|3PxZrh05^g5sXRglI;9U#~w_SeCk})?N~QxHTC(U?49#0udU&3qsSqX^wZ_G znV*E}K0Ha4U)TRWA7F|YAa4GB_4bSU(wA%9eVL!?W9NJkswTt?FhylT9txrFiHWft zV_#ors-AU3|L!x%u&+zEIi_0ox_WhRp{GsJW?UUZ73J#?^~WbuM!+4R@#k%KtDi?f zd8%yVctg_fZ{U%9QJsr4={>nY((c*j-dKD5P4&@LjkE0e!@?lX<`g|?4VH4T3Fu+F z9aQoWEa(VX+W{KH#&-CT@k_4om}?5UA6OE-pV zwz}T;CAy5SW{I9rKf@Uvh)#9YCtdMFT^Eud_SKzU$YFoMGo{Qu0nip?kwL#p1FtOR;p1?J;OU#>tcr zHXYjHBHq8oG+_7&baEbk0SU@fD*>fHc*|;kmZX-c4wb_fq(6Ak3aTY+cx{(-yg?8Z zqXk}xx-AL$98e{a&PnWp4 z6~ucYLg_5Vr?Tw}m6rsW5!i1(h#Kpo>^J{{-myY%ARl;cNai#c%FCCP_Nf$u;^Bgm?!B!Zm~HeL&q^29xMS|Aujr4&LpAcP{*EEh}~jy zY_nm+CvZ%S*riX0_$B1vPN&M+5!tjfr8Z1Fkg+6H6U?>kuBpHuEd&wZta)itAubd& zQ#v)Fb1p3<6W6~v+Dn8N+$RiVX^?4-{12Mg6e{11W__n zX3J^Y(hQw{V7rSo#}D?O{fIF8J7txUsG)H{CX)0AmS)i*3%lYnH4h5=PA30~i&1A! zE;b^Nb+agV9GjHe;^+6+)Q6~ufsdTF%)j{;pTWL=6u}C1H*4%jUs|$}E?{<+&2}6< zdL3eqgXOWF^yn?Y#mBa?P{(9DszUbX$E->lb;R{=l7-PnCV=oEuHMH*;}sRd+OsC z*3*yybB8uX*+dUtn)jo%%d&-^oEZmdT#@_D*^_wfJh;M~c2eER^JTI{qwlBf-wE_RfD=F=NO5DCMwkXLfCE$-ouwV{^T4_%Y@DM0sl|X(#mqVGkD?*ZGxtgtBU|#NE?JeM49^Bm?12Hk)0m ztG8q-cOrA-l_35ZB>Tu6pYI1(6$<-kYWzh_z3$a4-W2=qjlQ9KJwN9sHCL;8?aDkZ zlbhBbD-`79q&`uuzKYTfUyM{f(%Y7*D zb?oUCl0i1etg1tej@3UZp{Wey0ij+h;Hl;iRj;QI>e#TmnGpn)HEu~W+t>@ls}a?& zr;sw+unWXvO0o;Y<|G38PGbEqU5Yd_CefQpum3ff8D5Zo=-u5a7B*vW%1l94MEy~*QY$F02==Ho`ovPDh{BV% zO_xyq-Tk0srGXgGHSh~C1E)s|zCim~7~{f;rBo4r zqR$ttAhl1OI;VfZ7`Ss5x9le$|FPHpW78J_wk8YiZ3}7TIzWrGCLb;02dS^gM^%B( z$Ku^}WWf6F5a+_EkShdk2jExv5=W%{3}j)l=T$OJH&8YBaAvr<4avkH?}Ld?rri zFrCUGaDPM3oy#Cl>dS<<)+jPdL#>;RnIh3U*D~jnSq_`p>^ce7y4IW-X!zdPQ0QsX zlw5IUjMMd_Je=gUVN@ks9l{9*`O}l%zbn)JDESJ%ZoeL^o_^ZH?kncoibf)0F@)0|pgwK;> za^N8335N93(YhX)q`~i!3gV=nFsvK-Is8v!HqsWrdx-7nn-oj-3{PT+qmy9y9=}R= zJ+H?a8hX22nrXe>Y9kK8ds1WDgpFDps1-&Ttr*eMzS0*JLdh@Qcx$Z36Qu?|^a|AD z7xNOMHOr)wgR#e9cQO!1zLYlSP*yPDAwSD|Iw41{JNdN2#v<$W9`3C?)RFXqootm0cUBDvvJmcw6Ta`Gr9lO`^QOR^I z?gKeqq?$z4$QQ%0SdlM=WVL^3U%C9n6>mD@xIsz~UR$~#IcP2z(?;Z}S2t%7bXo+< zK3^9LKb7g#E8PRH)Q_&|x@r#}G@LeF9^tz*L}!>Zh`p?+I=C!e*;vndXwTBJeb75$ zKozoeap|?=o|;o2encJOgk>^xVRNFytM_u9)aT2?PWv7g5q+J=RsN%mbZJfUf=q4o zNpw-h@7$ZHi8@;-kh_kym`k@G~aV)3#;@1mC3PD&z4K@=4EsBX|v zZP*>n)x4L%dI<_}-MuBKy~m?cK0X2jIg_y4HcA6;0NOPoR3up!ARHtv;Z@98_Xn;oS(Srl8;Z450H=2gg6>3E`vb<`c z{?WGiD7u18^0c}F)$vSU0f~%DJ||z4IPb}ofTDM5#uQivB&e{V_>y2;6boh*JXt== zk^s#0Q)j^K?TF7IhV|}kGGWri%=N1R4(JD?;-u%Rd$Rf zS6a=hLgI{k4St9hFBu@1QD~)!i@EETk&pKyy3lG~^B+%&pRO1v>Ad853lLKLQxHN+ zi%&ad77k9{+;&fdl*S{=>?_r4;Vjt;rIUcmRh8YQv`||TLi*+B=}JD#5a$L-x&ALx zh^51YPs2~CmrHuN@GtT-UvEiGB0lZEq6^14Z2yUMM^}z79mZ30w$T0Z7kuMqrV?L> zCrMxR{#0|AdTK5~a-DSaXuNTIU#lmj?2)7N)%T|r||kt=dxVZLc_;j(j8GNITds)L!oB?ho5AHDPJt)yhVgU#Ws_AHbh z?{Rao_fz{=yQ^t;BmP!nj4Lw`pC&ddlj(9|8sQqbl&>1lwIrS{FCMzrq~~59gq9VY z^l(pXz-L;9MW_@S8tM{NYZ@Y<-)zYW5(W=eQp;8XLQ2Pi%H=a z_jLqfo6HF|GyJyhjKX}&GfOif<7-L5x9pA}nzHf$cR8i~j6yp-VMbZ*fj|>4h3}T1 z8__P@QC8~t4%0bP8jr${uVW%Nz048AoQbN0qUF&f&8+9a4Qk21BWzQ>{4N6ixC;n+ zT;m-%&ChfkG+aeHU}Sg%|I|iIw6+&5Ma?W>D|BbC6wHjv5&CfdT%Y9p)q7;;l|}az z*822mQ^oXZ&B3(+pM&3`Q`FqdE0eoD4wZTnBry~Yz7nQ1 zxIv;c&`37lbf~9j5jAtD5Fq1}?~<1EA6FAsl?~OH30CiAr&HN#_Qb+13SaOR(HAi= zb98oETD2d(9)^**dJZa85#J!q+&%ZP7+Krys)=hL^W5}Y8NjFX^>jTG;y7o&h&yt3 zyBg_m6#3etv~M_T%A>NHT!F83Rz(`8PC(n9SvK*#cr_&WWpAxepk9W^m$ZiLMX`nd2LzUt#5~#@@mRQ3v@%_Xal;atqA! z!avHDU4=hp9H_4H&VNO%CCAqu*J_;E9!g#>$QZsmRPXFE%|0YcOMGpB8jkaZf zgG4mHve3gfRXc@i~BT?_Sj01s_+Gg@1<+GRVKZhp#B7`7}90IJR5bjQm{=ziSHCYqE90-foAs z4jT`gF9JQ++%Z%nQElI&=o*yb)&&Qb&OJQaME2iYOi-NZH~*Rz%N@M}|G$d_iv6zE zf#tK-$?iv`i;Mc!dy?*hRkHN@#4me^nb%F|kl`LC$mTVqxK$2V;fVdcqk8_?zvPvI zWz8Dk<$l+pDdoItr3$e%1Y*ROCniKccC}C&%ug(Hyv;wT)I8XuE=o9|lUbJ=Sna7U zv#e{Q+HVhvU=rrWTZf;H_` z4NcpGq7UE%*<>MF7R$kbI90O+X-Zg`u|wy&LDyJE*AJtbCa)?&G4I}Tg&$uSeM^OZ zEOQ7QlxY(#U!4D;Eiqy^-^blw1^fHqQ8lT!u2l+}c(`_`NlZ63JDJ4z=7zoPdhdLX zz2oADeEPP*rIg~gL8-y6=^hJr=FrdqY}YV&Op7vR!xC}aZ;Jg+NBGfFebuath$5jc z37c$`^3(Vu9Lwdiy69}j)tV>&4`E*!7X{Pxje(%F(%s$ND6JrhbW2Mtol>IGt#k@V zmvn=&uq!Mju{20`clyqHUC;e{-uwOVewmpQGs^<=KNIJiSuknwvE~->Fz2+gn_td7 zD7U8eIAvxo>wOU@1fQ_S_=6@4;h2q@i&;7>xGmsevP=5=Hu$H7ut|V#)-9a|33eDZ zVo)rl3?PPZd~gj|JQw4eazC3DigZx0T7F$~Ss8(R?eimC0B_b;2L~eX?L@takKwuM zG1HC(HFpUUan}Oh0Hh#nE-HZSl&X6+swix0AAEx%kxS<+ndq!i|G=$uRq6CqfD}j{ znSHnE>nFeV z{O21Jcea+}r_ayZeBrE}FP!LkR-WehwIOv@_FO_(bdm1^pukS<7*^wGUi>wsN}Rlw zTpJ!Ud6co8vGpj!oW#gCYk)Gk(aNt5W`W(-v?Xjn*>6pVN;=BwtLHiVwctb=p(ul| z7^;k_i1bhkg(&aw7Ci3Qdw3Rp@c_g;k?fECg^J6!ubg)cR( zmh3?_20x__!arW8JPUk!$shj`N$lbgp3`HEml6>%=g8J-^_G*b80|a^a%a|)!%=x{ z0*!J)zZmC38plg~bSQ`V!ykPKg?~vA6nR(Asb}Qwy+cde+h{92BTr~uEp6|Zdso%s zBXJ)~Jb!FY`OYJ?81qi3-lT1)9fpWaA?BTk4>hAN?J+)ls2Ra|-QbZLN{ba@Qy7fq z>XG_xoO6LHzc?7pP~y3~a3K%|eo!L2Q!^rW54c+tXTPJI$M(0;NFV4>1ZpU%zei<3Tx-6KR+@x45L7>7DzyV0oY%Fu%ux(@o;Kv)#zUmA@bv8T zTP={6g!$h_9Wkn*&bb{_FH%pPpjZ3;-d_f{+PDE2#YSG277Wq_oD#PK>qXAvY*e1B zjZ?S=q!7n9Jl7V!w^fhgeH=A^4e7hF(ANUYx{P`O6w_L(H!zL!#sb_x=lQTrR1K`i z<*7WgR8Z?n4B)5Ycq9W+v=IEYRek<#-Ox2@N;`)_+*Ws+8X=Q*FX2a`3B(}O@!N*- zaY!}IVbM`}zW0mC>2c_g2zh2g!eC0;BLhdQ$eK>9F!JphgYGw%Iw8FX>F({#`O&%Y zNS~Ywzy3|Ci-0cQ)vVhc^_RV@C8q*7Fr&zUCcdE#`a*lRZF~GQmUPmOsk1-O>SjC| z%NK8amM`(7U8fO}8!JAx0;xM=Y%qqCfsgLT&HhD|JJW{F9lRYYIXlkCCi!#V%LiSk zI9K@oZH}jYz~z+2)zd|l26x6+C_$H*L%yew?RBu;2h}GPQKd+WNEB+ zyzKVYnJiD=O)~je4I_VuZN-mGS8vzm>UzE?kE7(`7^qSo^~>uQ=Lt*8R)^a250xTi ze8$fz&nmsyi)o83I#YV%_^tQ`;wiAB(ZB28n&%i_^${Lpq2!A!aNu2^P~VHrU_j*N z!BI5^Fq!m7IT%{)hQOuO2t z!)(9$Owx5O>pFF9fM?eVyym2LxshBceo-d((0Ws1;}juNQo($xUv~V+0eSkGNb6y< zhw7t&7i^zM)94=Y%~FsmU-SQ7^^p{R_o>A%-49CRlwQvlS+~N`#FF1+BR-e)qIJuX zQg;C8H5R%T9vocxYzNDGga1M9dDFVQ){48dH%41xl_T zYFjhK`l&cfOyG!;quFM#G-31|IJ{Snn1Rib8|ru!u3MBBLKpTHu%k0`o;}T>rghxt zIE!xa&_|AYCC&L*gWo+tw1Ci8B}8JAajLhpT-tWp_^h7%+f5oA18f?nY(HN!TjeE( zZ%A{?eD|EGREUX6bAPFoLjZQBFr`msR=RY+Md%@d^y2m010J42#*WiD{8{lP?>)cS z!o1QX>YR@5UY0zMs#AXt;zXHfe817FZ>)?qX!IRkj`k1O#luM0(pzj6-G;?& zhQ}0^tw23hoK9uDiui)%ngqvZi8NZ{x1md&be+7#VaeauRnfm_RO>!7F+WS&YT$`E z{e$KLO-Ur(UUn8A>x-_eh}1l~Zc;sO`!Ff$ZLjE>t~u)U!bpabi>GCu}f-0|r zPjrv$aa?jao9q@{l}x9Tvz_xj`Ezqu6-v0`n3LV6u0q7lS=P_Sw1j%tI6^dem^&Fh zS8>s19x&;_+frZ8K-QLFz302WY9zeV?CY$wGet}4oifKs?~5IyQ#@n#xIQAte{@@* z`H1(Ty(#D7*cXGJ_aeo^t(98DDggHkiy3m*ca6yaP=cpk2_3gV~`5`dBO$D z`hZpI0(Uvwzz)U&*TP}KS7N!qvBymC)h}Q?!(}OeX(Y_cO{?i5{ED)~Uul7TRbac5 zRx^4#7WB#qdOtsD%chL7z43v4leX{hQQW}WvueZYDnAg`Hifs)j3#Zv@7{ugHi;(g zlS$iR;#)sCZ99ACY~ z?kh2{X`MKdJ-96-Rz-N%*42Xb z{T(qsg*#~d_Cb%-ZzV+r-MW?eE(ddT<>yP@(RO4g!>j$+98%l;Nr5l_H1Fxb_=#TH zTQ1T)o`nm`{#7WpeNEOEn`3K7=Jiuuh!?xXf;Bbyo-xpy?OLRh=fz(62^{=EsV*cH z`5z(h%BKR-k>C9LvBkl+C1A2)Mc<>r$JsiK?~*+z{9DpN&08$k^9%kF|3j3JqvQfb z|C>Vj&x5|jeLb)$4lt5SZD}|ldwa|6osId$w7Io~Su4mWiw(={)lsy=KXl}Dx&qE3 zLjt(E&Tg@Ad1d%7ned*~kt&JaFr!k=Ype0$vbkCC$%$c@odF?9ebtiH7(XeGqh$|M zMf3xosR@_Q{QL{=Gl4?Gilt2kx|G!RR->~j!Wk!zOGqd;s5Pk^yDD*kt{u8=1EJ*F zYIQs8G5m$U{SA}NoOV;-+wqE{YO}7qRDj#Qp}_qgm7Ho#b^5GDY}Vc-*?Eci<@DxU zcE3L=2)9HrihZese)vc{*+w(xc@sjzdAwc#?~pznymS~ForTlXdbRUN7q*qQEF2nm zFdj7by6VGC&qgiwbToz8ZP*LhrZ>F46hb8JqjeNGsO+Z9RYHhbOkyqr>KBuk#Wb>f zPvkW>MVG~UyEaLvAC(;WzhJ1h@^FUNNmMKn3@?@}A0ImseGXb6(p6)58a~*^B=wx~ z*T@rftXigMq^YcYhDw+- zDXfdorJ1>Op8O*Fx1D{0s&)+g(o-*PRsAsijkR)JGQPJ6F{h}_bQU4g**=Q-fLytZ z+*y@TlWfLC!T&U@xl9qxFRs>`Co9Jrl zA+aZh2FE4c3T+H7Xf|UjO2wDLqPcncr?-faxt0@C``{?Ir&~vtFz_+FdzuEcKE! z=nL&OoW2*9Y)r@~^Lq$(s!YnmG{E?|Lub%_-{Yi!4JOp%Q?Pil=k6&|)lbiIX_oy< z)BAcA-FU&w-#}~kx&0ZgkoJ`l$=5_3<&B~x9Nc~C14Dh4TcdRdFP#@OwhN2R(Oaej zqFv_8)Rj~`V31Uir4tSOviQ?+2YJSUxhYfQRqEN0PW(N4&6xnK36Ns$)Gu9@62;#CB}(*Ka2?ij1(uM`meR^5mWdk21ZO%f5Vk!da~`N;X3!U$*aV z{w|Oyii>zpe4yooTcp7U{PKTA@(*B_)N`>*UbtOL<9#}n+Tr1`+wfErgYQH+_%BDcM3Gv7FsjT;H>Xn=k&1xH zW&@%H5O<2KN&5r;5!@+3bw+h~N2Mk!kP|rCVy$qSZ0!Mge6YzTQ1$xx@;1W}I?1a` z$%zMO?qbznsQVV_6!e~#9P&BE__YKdvwV5>eh!s@Q+#tsT=4PZC9#AjHPmt`cWaC` zUeGG!$LI*71m~?x}Z#V^Cu?+Yck>~EE_hbi`wXOGtO80m7hB}wP zi(T2@3wfwPFli`<1~^=b|cC_F(d67U7R_QAVHBWD8A8s$AcIqx%W5 z8hT3Gt@KHve*|=sWI&*WJ2(Th=)PNZgWGa#v_2H^kAzrI0E}3|L5|XsPl&<>Be3_t zg6%0Mi9kLbVO+?As>Ud*AE2M54{6_rG}%(sifCb!*vvBaXYQG`aF9)!;kY?ye6&Jh zg1R}IjdOwZhN8I%#MS<-@vG}VUHwL#%iJtxzPUMD7Aefy1{4Sl^v8409Cp_9i0l3` zh_!s^BTyPvR$6hC>b@+VZk(z;)pX%JA9r?w-~wF2n%`stdOST3%CYke<8YR77`Yja zjApJ%N-{N8mP6fjwMi%<0t&phZnOrcr;lA1Big>#2WSc%y!y$tKrC=j!QkUFIs?V1 z@b-D;bTMv`Uyx9B8`IUD>krzxiBvD5nXK`x55cQ_nX-T!N|L^)A3u2gzIPUha5ZSt zX+@ZE6`zMqX))8f=efmvGE?b|=0->EHT|$G+2?UW*iD|3InGB~dYz2eh`W_n3^nLE zxC$@Yi6tXM&|cZrTEsXgX+ ztVBF^>)sk_^e^pKk58xbm&CBu3pei+(}vPxzW=|A5835&+nb&BEVu_JZHhlSg7 z*AJBLT=cUBrb*=QQUoDcrFExWNjH|*2F z&1P)&WEzWb5P1;y2>6!<`MYcZo6tt1Rv65v;u+L@0q16aWnaZnGYNRFgJ}_kpE$LX z{`0E`n2NvwlB3o`&EnOkna?Q-bX=&(l`z@N!q4WH0T^sxw#D8-4FsC?p)2aLNPq-{ z6V?R1;RgCjpuAgy%aHQ;KC#oC6v6`S0k@UMxMi8^z2Vf|)a$+Pd?dg~PaKIWiimL1 zSoqP!zwEz_)7D75>NM^?o!SJ8R(O%;F)F2`OWKgQ@N<9PYP#hFYxb4y|L8SlmpI_|P zV*PO?>D|MG`5BCudtX%aFdlG#9!2MBzt%GX77S_^kkt`2@GOh8OOet;*HzYdQ_u`k zeCT=_Ui7zQqLj&Mabu5nW|8q)1H*`2!eyB#pAO856Fn3Cj1u+zr3hHJ|5EYaP%;A6 z1vUTu!D98!^y|g!hl#={szlJE`)@zp3DhV8Dh4bv-jhUDiNa3;K>bV~u=@u~9$}@> zwzq6QsOD|`g!Pw!ojm8r;|K7_H06HH{^?A%4rTT4$hhxHkV(QsGOmx&>Qf#;5jaKG ztlRCf>`o?g{vWY1TRi5nAAdiLS&@)^56g7Eg0HD-3r1yM!Qbc+3qjum@LdpUMR~P= znpn$~21(QFACwYQr|Np6yFQF?#_0OrzoYEDc)P)wk&UR&`N?KtsBs zaOu)Pp!#6G4Bj`N|JgWc;b^W{>S)gB`-LN1vg?4jwaW1>&X>{-_H_o*YIe4~Oew1> z2Ev6W4Ah*JIp5uD-(d}%@_0a5JNSAk(@WUS&2kD#2cEe#P~MNM+JUVwsI@xKL{ZEg zTd#88co5Bi+!mELjo z{|84=u!_a@8f13fnfq^jqXnIrSzKA$YRPXZO-go68)psARf2!WHR@86Jq^=%#UEZmk(+0U zRZKlWCHT1tGgS|3DQ?HLMW9y{4QsbG_iP0=>$S5=HPNY9U0%6Z5$V=eb50%5;;txFDeCUlyiSu5eulC9d@h)q|=E-aLnsNWMxSmQvMOw@x zO|M7LTnFVNE-FoENJ!f@R(hx%OR@oc&LfDj5}V9&byq^RuhERO>KV^2Dr-})!1C%Y z)dLaWKN10EYhOKn-q7J`G%CAj5}5XEkXHpNU^Wx#Yp#0(xsbdYYN{*bIeZR@X#q~~ z_^7!Kl8mBIf&LfvUtvy)*ku=SsKsi(ras44fIM%o)6aV%U1V5sxSt+qsVOdQF~ygT>mc3<(+^3UR35y;=0*-%uy1G(wEi|UF} z#J=OlsfkavZbtXcF)uXuR%RkS>AkloS%hphR1d|s&I`{5#Xmwyq0B_~U>rb(fFeBm z14;#@SDFqa^qe>`LtPpgwQ(1^VMUWauQ|1ZbdgGHx0ws<7>-7@(h{O9{1fR7OaD^b zYDlH^V&EoDLFu1bTrI$1K ze{V1;gq*xgbj9GAxH6^EJuA-MUOvaC2b+k(`u>Lb*cX&UxTb>J@q+h_IV<12^LjzQ zFE+iK9pl#7>opcq(g+{F_^d9TMl}7Dw|_G3^d!4F%EE@~J|;ffg5$+I>Pp z^g6xXu1UCuWtS-LOvqzAVk>UrbE}90e4~``({4q`T@ov^jDuGzrh`T)5mE;=-%JN* zP>t3cR$9uGyn=&iRExSuKzSTf5^kh%*?fBZxgSwnpGY{ z+X6k*>7|;E!S%rBo7pcebH9hvET~Z%avv(6XqMdiIMl9p+bdUmwpYzP${ERVK9|s# zRqwdk*dC+=S>G>&;^8I<7@2XK(Ud!z;~FDHAwem35EN87N{{wW2RTZlxi$P@T_G1wQsTmdy| zA3T07q-m$6MsQ(^ig_Qu=2S1!5-UBb1fK6woa#CF11f~CLD-!A>a`IHWrJ_@r2>A{#2`S5MA!)k*HfZN0n%F?GEyIs^DfRfWo2m=~{8I%<03u zEbr--bt-Zlo0es*yVR~p*|#qHjXz@S4h)9UMu676sW8M~VEYE386sxI-V)q(c1|xO zbpo*pYw}N^JuXMIrdLWlva~S^VsG(z=P9j08^ox)9I;c}ZrH(W$E=TlK zxuqzjH=CeC1iAPsk8ELOZaHA}z@i($uudpeY3ZBIbd-D+u)tn-wz=5|I_@HRJHY*E2vvQu zFN3asNwdj}k?(Th+pNU#TE$!8KSF6gpdRrI)tB z71btQ5${i4oMR|k<+NIA#xXut9-9Z7*T3>BziwPgMYXnGN7nO04TXmDbyoM1`X%N+%5FW&-k0h{-w}`ULUY=` zRn*z8zUc76URuVJ$`U>hG#=0uVDGQB23sr>t&FC)DY-O1C_Am5tdit?D5G^C!X=W&E^#p5nwI#R)WAD@R4}08oD_7StkQT>i@ygr_S3a{xI8nCaIoVp_b?QA`3EihX6{tSUxdnklsS0d&}51x!LE_j zKv9|le0YIpwrc1)1`PF6g&}?wTMrLm1)wN}F0r>l_%riI?+7jq0(kuuMhAG5IOTqc zyukUS)HUD7<{FB2A7jZ_ghBMcv#!$bPV-cQUA-&u5B3c`#+bas)Hm$d?$Y;*KL($D z(}n9k!5!sx__n-kl6pCCc6sS74-*hN+4r-q2ceq_W>!M}4t8VP>dU@gxs&{I-nlgss1^Qu=QA_9uG%cx|puV$C|su_M-d-J;4r?A*_>i*Y?)GRkM z%O@ql!Cqao={>7T6vptD$-(YG^RA|^?)^QDd*2b?Q`~1;!2-goFqC_VQ_Ah?CJ!=YO*gj2?AQq|&iZ zlhIhXjGomH?d*c?!LE~v)2&U*cvUS(6vc^bXn`=nQBlUZ0cTG_@j76n#PF2_KgKM z9gJn_wW|?@Atvp6OmshyZ$9a+UJVXi&ta|Yb({KQxrkG4%KiGPskHFJO=IE%PKCg) zHzmz-2Njh+7F27rXbo-{nvJmHx^aA=UVY*avf1 zRGRXn@F-|6fGTKfG|AziRP+ z6~YbP!g*xFHBdmq_JRb3Gx7VEfW;QDA@-IK?YaQP2Vh1Yc&TRm@j*c7@|ybNDM%s! znOlpe0LWf4q%W^ME_eriI?O^P-Q~vx5s}LZxGw-wK9&Ih8vfS&T2=e=ZasM9=ha*G zrjP)29-6jYlX2AB5!Y>5E=965Co6;RLarNY=s@$r@2C2Qn`u<+`gS{r9(TW)d(o(w zJ$4CBF<5_0Q#RJnil5*b0=e9onCqLz?puHb9+yB3Md%k$FZ}Td-uyBMAJ4`EU1TF^ zejrex=+cP8H{c)u_?SX4)ocHb|6?&r7!@lHIj^Bt|M&q#L{p0$zLC$Z1rqT1!dSE~ z*o{kAP@)v3Xjj3Yc~P;h;1E&JX@3BW%4yfN3VJ09q4b~W{?)hoOZ^YiDiJjnc&8!C zYtst!tE`~1NA2`$7t7KPiu<_i;07Yg^7>;DGl1;uIFU5ono9uL=>HM(n|rlRw6mA0 z@RL#aRQqeO>)IE6h2#cZ&-FAMyrIC=F- z?SwCJ#xdCI*?EQYY(`llqR!+dwM&)fDD9+4@0kw zJdSo&PG8LnIqm+)el#HZ85_#$g=Ge{AsvFrE%uCw>xg}kLf)&4W-7ajrW1FiWA0-| zS&dkZJdSE^fL$Qlq>UJMJzIA@9bL>R-P7H6iqkU{LQNyhr{_k9O-lZNnC_QQnfgf+ zibO8W5%Gene(-I!6dlBZ#R~2$cm^CHFH`a&L-E39{-6!Nvfe&Puo{L9Dq&{~Tnlvx zoLs6ntvS85>gIT|&sh)r9`l=gQfy8@e7G?Fke`y@OC3KB2R}uIpx-aY7QCVuX-;aj zv{WAn9cw7-sdFh%T8X9HMI#Q`3;C%(XW=uKcnNQC3F!HQM$Q)sXU$48xNPAW9=f4% z+@9u28NV175O{RyR&nf0wd6SFzjsdX!OY8HXQz$EhD+~=EHw{@hFkl6a>Jiet_U{n_=KTN*f>ir`>DamOlzaXp7+YjUl}Xzs3*Ge zeO0YRWOV+&2gLueJa|qQ#uq7F{wc+$P^#~&QyLNG4JMZ!WMXe{^OJkW&f1vj-VI{a z+PfP5=ECYY<#8PNoH@Oi@7JUSTVdblBL;my{NS9Xvy7)|L|V$h`b^dy0Jc`xK;}q6NE7_z)4}+9*J#$7w(H7uRbff&a}EL~)G&&-{4 zqf~6zoz@uRK0lQV3j8oz|8jiaPART`*}7**arR1$FG&8XQBBNKtyW}RM#yh(+u3U$ zKAC=UoYI8kW|s^Y0#U^VAIH@AI5`N2zV+T32@B@K2%}&pBeR=-jR8$4|K?LSZciI@ zjdx`o2b-Qu7d?ZC&gaLe2RKypNKM)KU@vk_v{W58`u;(SP@A!KY6p=&Yg10=VM!8N z5)eu5zH^<|p>|gBPL}|k5UF%QoVftbO8+@D@o?pKY^UO@qEggif%H|YK* z+6$mBI1>Sou8@<08cLrnU<#xMATinQ%a#o{0VX6$UFEOE5CZ7_KVri64@tm?V4(p2 z4Hn9jJkC2YSwCg3L7#JgJU}zC1lT@E0^Y%T^BAiElnUJK7~Bxdmv$(7Qlgaamw?Jv z+w=#m(&{Z2YatGBtq7Z~0m1&2#b4gdGTwvb(7suI{9Wi4n!)!_@!a7{kXjZpf7JVK zoZxQo7d!G$Vd1&wn3y>7LQ%E1ZWU*jLcsY)A?dw~05jTmb1$~E@QOhxFI-{|0{Q)9 zDm4Z4N92O*hcAgh88JK(>V({Py724Ch8nD2hxWi~TW+#k3M)&kWeTPvOYO)8z;}rt zhq(fk99U&K5SC6N|JES4D}~tM8p_)erCcIhTUnhY9i&%V7L|T}#2{Sxze)DKGJDn4 zfoyGvtC_X5--Bwq2`p6Suta$$_(1%cqLrTd6S8(Ta4O9?&bF}HVpvOYzuFdftFPV@X^L0tp8oVdWHTP(pRjeWn7CSZBOa+0aUQNP}+?J(w)HOM!x7(XLyUw> zH*dQ31|t8xF|{5_Yxma{&FkRdRm1xKg#M}BJMsLJ+Ng?}HaG6A>tkgef+lke0`|HIwM}M8hI3l>t z(%pBWIC=z!)jkma9+syq1DOK(R5U1EheqTL^%!5(NX6X!=0qH;Gi&dYC~@hWNyW@{ zNRj?@s^1w=DqeJzmpwOwD4GdK_9xM_%B$$8^pKy(%Pr4NN#K334!hlL`g;9YR~~+5Wj(nU_f{)~m_8aMhgR{MF}{`^Kx=ah1&naDqU1S!`{S0yTS*o6Vs2y`)q_Eg^1_-Xh1{AzVzIjNhFBo+ggx9 z-qJY2y^&=34_bG<$D)I4)=Z?QaS{Rfal`O%*GVQKcxiPi=IKz&_Sx=n;Bwodx6W!C zxD=T;qY-&RSyo8+{3E}lq^6*9k10#&BAvPN{5K~87{o;CDj==7XMQo$d7aE;r(&l9 z4`vL~LGDk?rJGko>by`2|NrdxLRn~T#szF30 z51u_O4O@|Vz1qN6pexuAXuD?JJC)Ak$Z2J@X~a!`(KTEfL&Mrr9Tp=avvzGbO_Ogz zdzJZRx^=!|FSSm`6n}w#;RE@{`R2~a;=&I$#|2+*mH7!kKN#ZFiT|Rz4R^lu1i@4? z)jqCl+XIG`>r+N7q-jGN?oNkNbJkH}+lvHV>yMCEJ7#S-7^yxJ!bc0kWe@EE}A5|rHM0Gr zi4U0uM(QM90K!!W$G*=R540>1*kbzqz8A!X-@0N20OF#e8j!Bb;)E`;Nwp}1j$-pM z0JzOM4O|UTb#Xcph2Ox%5CzoXrGGI#3ct23Ydj}5_z>)fzH&JhoUnd%)sG_l%l!lc z_Jd6sI1}0ix}yw39$n!V{n^_&iLj~lY{EJrG`c$a_+a2Q2wpS8gk+`?$il`!{)lwe zZ^T&mSZJ+;XpSuT7FfmjQlc~hB>VNquSd2-n!Hz?EnKG=XN^PRTqS#bi#6bxgTv?{ zrsx6*A7x#TMlYl$C?@!A>sJ*5vW=72N`lM^n}=|y@D25tEU_c@v5#`1G+AqF`A1H9 ztCN#B&JF>X3gFQT`1mO6eFUr~BG7Y*Ya6_NkTx~B2J*%9ZEw4QhZP2NYEdtiqL|4Dx7u`u~ zngJK&P}50(K(@Yhqn(YBk4y@9FhPtP!cbv-C{C2`lUNrwR(+oFU|0&Fr?|Oz zV=b#8g-DVA+bTWfv3yjQd*di8AjT6NG^PFrO(fgEYC?T}cQWF<^?`wKZv?L2et<}} zb@M{x8ZUg$sp|@OdWcA%_djc{E&6C$mT7u8IRv87oB@mKDy(=jGL zK(eV8ng>aGb>iSurSf_d_!*kXnREK-7wnSF(|020b*)&qPsY6VU$hAh@(XKeBKy&mJK2k-XFNsu`Uql4 z$=&rug_P!}xeB4v4Azb=`%x}X(SvnSSerE8Y5U9R83Z@yj&+dgI+?i)FzwAN86dg)eg&X49g1|m#~fl7>j86#9nzSeC=B1KxqSb=gs|G_w9og^)t0_zRwW| z38lfI?VK-oC>*cCYMwc`aOdkNrFAT)(kg5LaD#E@01H1HEV&pOsQ z)>s+Kr1%xNGkaoobS#R)>(V4$v9xChG<{g)-{Ao&q+lS98&pe1!bb?Kj6_{zBKC-#9 zN%;ruVO_-}r0Ns-Snq;buAJBV#U+Q`eKA)FqX|WjZ=dR|m-(q140B>?$-dK4U9?x> zXmj=2a{5~D+Q1vK%zgQywN2HLo9#t=t!^3CX$)?D{dHSTDyg}Bf8l#iQj-OZ#M&6U z=jAxx#wptZ0z(+mfQvo{RwN5qQSx@$Uh!C|UF5n>-tfqh;uuZLkw9pAj<3)#{9v8O zcY03xs`gOir!8Kgp+}}Y25woQACVSIkifE#Lou%$jv%LfOv(Uy-93ZSZHO_`g$&*~ zr~SOBi}fnZJ>7hH-P7}{j`2nX3Cu+*(NiF7;<|ch)r5yfhQlpcdvktjra9hVv3bi) z*MX7Iox@qUFJx4Yusmq;=nzIdXA_K2!u(cId9wQ!novuT+&OX)@O60g+%s)%MRQsL13N?F6BXLKR8MqlWL}RL;oNBI#Qfgc z-rAf$YnPN+f_AqTHu;?-^3;Wt}1s_;iVh znao7Pph;A2gX6RwKd$n}JpbdL>#3$ueRjIWWcWUToDO5R*L^zvK#%{|Td!_r{%Lg4JcAx3U)ON79;T7@xIeCVl+5Xk?K=Rejt4OeUbaG0@W zIX?weV)d!b!UIdfrnX#b*5fN`HKzsV2Rf4wH~|cG)1x1`t3rvPJ&VO0p=U0iL7&I16kBSKKf0lamWV1BM)t`r5%f zuGmidMMt}AHv4?wOJ{^xCr5y?ImA6?C~<@(UlTA;1orvBycs>S+-$bB=2}InUy((7@;2jll!3w?Ez&FCxt+(m* zcOQp}_a9-Bip>Vz!u9+jk8iYwkH2aFl6z*X5!@9+9?{bEH}mt;HV@LiUUj*M!=~JQ zTu9fy@CWUOJg;lnnih%ylszouFeC=q<6p17y(@&;)l)s~1Ar+O-2mw)Ds((9{uZ+u0~Bv+)C&;1c?HKpr;^g9W1*tqc-@ zPCz`YZDRtGU#`9?&BaxXC_*HPipmG6_F*XI1vI zYV{ZUX-ca8pf16(1PPYrlM9l&y&^byobHs=-8Uw(zk5u(ab^hJg<~xKpz&n8yCl1G zHI-6}mswr1oEu?fH}Y@u^xDH_do<{zG9%trXn|0rCVR-8Z7 zc|u22LkeYlpILmL6H;0j%*Gh5T#BUbw(BYren>gj8xXsQNYCYp%&j+G%j#*HTbD7} z)_{j5&xEz#4_TVKit>iE8HBBP!A{3~3M+ec-mVmuly^84k}04w*gz@n%&B%W(hb;$ zOnn-Yh|#SGI*~#kq*}fe!7nSCRyophHe@jU0%S{oROrr zz20eC{n2Pp9o`r8N<+IlTuwtta8MH@g;B-h@^yp+{`xe;Id80ZTI+o3x$5aky`H>X zR21I4zVCT*KGgt$k@m?yUmxx2mK;`L9BOHL`qZt0C8!HF^!y}YQ<0BA{r6gLZ(r=E z=U*os*>hY?VDBeWn~LFe&lTl1ft-o0}_eHBw zOqj36=w>~Ld64eF@^nn6wQ|R69-dKJx8Pf_z0A`ro#5Y)rF1mWL}+aLM7@>bSJ-0K zN${2el@^CBJN^4qI>K5ZqW;%++mMr|jRW451+i}>s8?^8Z&qNU)8{*fU|SXr z-OBD|z!;QjBDFnfk#F(zrlM~1)Zy8)_efE(mXHpcWBv9glgsm&e0(x#i-+R~vWm6I z*Q6Ge-4zU}Q@6e)8+^C_%}61NG1)X-c4dBl?9gRvd%!Iqckgtw|Ao-&i@@1Zxn7)| zj{S>`uz*QsQFIMmr24PmWZL4d=CwH7=c3dvsj+xN)&8Vl zV`FN!iyK8UQvyCd4I*`9`vHgzppCirxc82{c_^?%x$5WvnQ_#-i^aqWd*Ju(1 zZ6)D%vDrEs>JXH_{`mc(Rjpni@pnyw#)TKuV@*qhRdwy%zKaIRKgc2pt8K@YkN)X z9lkg&);wd02*2cMIjJv0l$3J;5xY|@eb=R;*r!u>59#T&%W^BDI$#Ysvc<%)+!RJaNb z+_;q(ERIrH%A-5e!R5wun#kgi^alw$aL=FHhTl6$|0#4Fu$B zI?!ok{y|eL94e5yiBi{U+-+_OFGC4zLs#3jdbkJ%0=_8Zhz%S)5R_fj8w|p4oDEbg z%o{ku%;N?U?&{Jt;C3Z3NFU#b1h-+0NH^9mhP#i$UjY;iCkNn(j`aMZE(aj@_9wt5 z@4xh4x}!H{rN9cnk=0IOke0l^KAZ5q=a#t&L5AF zfGdx$XWg32{>e^P39I_ zn3D9Q8izIHo>Xou$c}^UqZb@+X|C#VIrA$|Q+Jqp))b_|5ro%)ckY=>4Cc2pe-4$1 zmpcZb7^UT}BkaMu_j;qQcMYto1dBT-PcZ8SENrw=YJ2SgXNE)dd4;*@SxD6kd!=w| zREYhFL7ujir7Ia;r&Qv)BDYRutgqa-LxP?m?8!c!X_IKoCSz zWic<%HRnRt({Jq?UDf$pjv~ZdU|e0oG|HTH)&cA?y-gF=(rU^uib-to*tiRj?Jgk2 z-L>C0{TKcb7kp+CTee9Q=P|#`L_xG-mFOJX@7F$)j9fO77DAndIw1pdGjIoM%&;uI zq-@w!himkD>f6kvmpcx7>I(wD7WRfle!Js-fv@Ge=^qJkB@6~jb@C6c3d0((C{a1> zR?=yf3A!f{T)qC8y1mnuG9Tx_Gq)9%8R-kWnP% zGq~3p!M%n&Y7AfZqxWqWS*{;l9g~;#QeT*gp-DPQmM<&h)iKjRKGk@+I@BPPS0423 zHu>+(JIAR{?sX0Q_ThH@2~SE~+9Vjtckx>M>#LoNA`hTgM&a1eTC8%-j)CL8*T5Q zD_4(}K{#8mfRF`YT1qoFPAL4zbLG_r*|SN@fl#fQR z_hz$rh+T?0-$%kX-CFeArE!R(U`|B3qSkrqnWPM6X^}5IYi_U-g3~dr(~i8uP@loZ z{fo2h-gM^TjzpFcJ4`%ais#5_?=0C*c?{koGkUdrUJ*Lq(4GRKrsjzf#-kXIkC`cz zNRvl&Mgr-m1rNkU4Gk}aTJtfm>?JwY8c0_ueHlbUQ=|BX7>0zhMt}6ATYGX(mF#aU zllYDP*Gl@oNgC~I&TFhOKRJgPn&h(C7G}-|5%`wW$FGB{lq>c1t&?s_u$?sdDqQuA zD5#}MMEx>}e!-=#ucuEuoJ(`)tCG(H=6Y=U(zosBqkTSqJyS9{IUGIVNu1T&IUV+= zXi0X!XmKAcpycBney|a?wiuj_AmrRz!pBI|ID^zZVZo%!j(UTq!wklcQ$d0}%ZYP3+6m#WjC_WUb&3}~RY-EIPA zCN3k{ZwebzQG0rAK5mt;ZvOChU1s*)!vIY%acvsxR@^9M3VpbSqLsr;pRM`RZPh5*J2Ve?b7Ap!~zkrgoy(MT(P1QShPeuDwV-=Vqgr@Q8Y1 zD~esP3?@}QL9S_}yojPf^b}006#6WR;4fQUSrvd*0^vt^jSCKI9y3bBoyU~uGXa=i zt3xJx36xa;W|F*QLLnkLO7fl!0&p=WkP`@>sc@ZE-@T2(%)GytdCShD8lA8X1+H2n zTqqpY?<@VGa2r4{J7FTk>H+IRK)*cd%HkubJ)8Q;qn8=+!1nQZn3oJiqc@0DD81$3 z{_^pPCWTma;RkDB|BpD<7{vY`<#AT}13!3I=U_c<7JvBqmxtREG^31LXnI{4_>X@t z^aqv_J6p>Or89gGrwxv%E+!Q;%E14Tv$YlsI{r(wQ0o1{MFL@nokEM=FKpzYwHC1u z(CI6+^R6zAAphavu2&oNrdhnOF_Of3O;M+c&%-}RH^ulTtlvK<-%1ZV)P8kM3(o)3 zg27rwwx$z77whhN#HI0wGjtuLVgncBXUL}z17~8^Oj~)NL0lBp9ozGyGAo-cdU@;X zhG!E2cqNpta(3+%!a_+=SYifCfPq<@4ls1n!!4omC{DDCZ5p}ltvA=wr?T@1;RT9m z5p26mjF8ziBg0e5hJ}+1=(N#DmxxPS331YrEt?S2d85VclvsljhCFA-Z^%hXqfYd? zeV&NZ|HIgO$2GNe?V_k#Md^a{BBCI@cL*p=rHS+|MnGx^0YXPadK2k=OOXyzLvMl5 zL+=nufY5ty-o<{;``!2a&Ufy2|6t8A=NxNBA@f;d%`wI^e4P6O4Wp^Pd9Q~i934f< zP}Q|8C|({bCc3(*=X7*=OD~6AGzIl2aMJMxxH5Jm)8ixjCXLf%suj0q%nMDEL*e0K z=KNy`F{k%3{X7ZqHh{x3nA%A}1RvZm?`r}R1?Cndso@sxL^rl`wz>c=vg?v&=O$R! zXmzFZfuNvck=1|2r#gGqtd4i^NMOL7L*9d>7niSPWwUI3x6@&Nb+ORG-vMFxNYof_! z;rvSrqN7XcEZTR`v0X{qU)h*&uPk-+otUhNVgY8gUPsKM_}IDnlxp56&615_XAdsp z1GjBgRjV8?QctnI;3vD%C=SZw?cUVO@Udh(QKZ;U9Zhq0Pf7B@KOm($M`8l&bo26Xmr+RWxjBA@(UnVNDm4(55V%!S;@4UFY6$1SuroL2S6Yt!Q$bXLSy8bsaHb2PDtT%|cnOH#%m~DL$ zNYG00VZl|N6!_tDsDDZ=W%Bq%%i?aZ5(!l$kmVIR738qsq48qNwIRR!Ut^Vv#~JU( z>P<%V^~OV|3WRDR?Y24#gc^WGJJEly+GJEO!CY}=*P+s?gDbbNq2@8Phvx|w)bVzYvIsS*O7&m$vHv{ctAM0!#le8>>PZ5yWWY|HTM^)N=m#Fit|1Z7g(8tZ1nTpevZ zKK^1W)K(K*=D*U{OIt(0f763qamb%-%dIcgZ9XE+h#!rB@Kaen+85ByTy-q zMAn&?qk7;3NuhzEZ3~Jkhh}l{JRP@YyE$qfa%soxHh1TKOnF~VC7#A|=ZL`1R>aV} zAiLv4Z*HOkrdN#soji0oVI!{OO$60h9zc3_I7Iv1Jc}`w!^5L3r1>oyVML+CIWFa_ zNg-KX6r~N@FlE}EM;#N?v|{&{uNP`)JR+#=m(wjYhj1m|R1_{7y@b{;B8VTi_i(W= zZh}juDleVA*&)RHJCw&C*{CsLZ!;;2VTN=CoEDz@aliF$d2~JZT0x^QW72i5DE?(y zDTcn8gXC^|gHbg0Kg>18@LEPFSQ4>(ELbg|H7XHN^P?)_MHVBWiQwz+;>Dni;EFH2 zCii)#e$Or~G?7s~_J$cV{_2qA5^A@P5#4~(Vyg1$=Ge^t>w z0P<}XoHf_<>C1zVE%1OYWj&mJ8@(+e9BPl!{Du;C#t!d~b|H)hA(QvE=Z1z~@DZKt zC%f>Kq&6$3t4Au(1aGzF&lBfM{FZu!!`oFWP?4=g8Cu?#*@M_E!j5rugt)29>E7$zBi zKS+l!dP^z#r~Aamb(M<8+C(xTz_-7W6ly%bkxW*l?iv!aGX zfL52#vYYo~4-oLv$@?(^2=|FXR4Qgr)V}o4vX7}%#EjBr+kZC!u4=#pWo*sjaqcK5 ztbI%4vp=w{2MPX{l&SS<&qK?A-L)aN;{Ae$)_W?y?veNLp;Ms>y!1MivbD%W$}iO> zK#h>r<6Mer*i&BsJ7Ve$Q6m8J+TJ(3dPDP@dLXwP|F*f+P4RA=L0fi=^7=6aL5Bdv zXGYLRPOg9QOu6{i|HFDK227}zL{yftvQ&UI_H}cW2>1ygq7xrr(3!L^c9Opl`R-Us zJozH7=tPvy0~D+Wkkc<;1oqQ{h;q*osP{Zw4v4_*d^RpHfKkmBr_J?`AvX$)mEYKQ zfi{Y0=lAF_gr$U_4eelgs#awTTQh+6 zmNWbR>bI16I~-x2ewRf(z}_YM(f1e`LtUKH+aw)G(}vQVhF*kg2Yxr4xIqCeibnr@Q8TsYu0 zHu0O3o<57*lE z?jn%cY`3uMfqjcjoztnKA#84z;yXdb2G1VZlqRbC`duq|S{Z59t&e<|eYd^)%-eS> z5_lDdxYvO1>j&5)Gj5?`zPc8YOMOk`Af@r&()hB`D-s5ym9&JV|X($ zWfg{i=qF&5qwATz5&P8wxW>&>mMRj9-(KG!I-jDE$nZCJwz-uI096mfh{nL;> zR{Joz*LwYPM)r?;ihIxEUeBKq%oZ*VgJo@OH4`@t55$*CflP}4L9*!xU2n3X3jYb* z=4EM3;4giJnRZY2+LEI5{Mn9!i_Wk|o{!wcOGCQyQ0%Yi-f?_RYi8xEQYQ-cpnXG3 zeEensf^Q;I;czy%U7r4wwKO>I%;v?KH}n{h*^9v{5g@F6oZ3+c5?`vdlF0uZul@)7 zOP#sA0`UD2UlaAhW?%#d58RN5-WiM9okRHO_fwDB0jS4xNQ0wPbWqfjsx5kM_ ziSPGLP4=XBBN+-3ruz|~(nuhWlaY~XVG)PHM2Mh_&($1MSH)#&-_9&AXQ@>*8HB z9S;h%O40B&;HwC*F0--m8=xNf06y#DW1a_A`Fed3yF+!P-^W!@oA6qVE<$!a3=_Cv z2#B(O7G~e?kqua6C=a@F%$i2mqo14qj8w-GgMru zM|;Ou8UEAbKnT}~pKBR1-|Xy+sWQO4%T_G(&*+ECyycFmu*GTE`WH>2L(RGA#BU6= z@{DM}#8N1`k$gYjOpF3>@~YclHf5dtHDIsZ223?W_Rlva+6TleI%7f)Fw}gV6(;|& z%?JqY*6UoYW^>!4ogNx+pTIJLfe-#^nR935>9G%;o7+fQD4}&6P#Kk%1Pd>Ey}G1B zhpq@1#mTFhIQ=D>O6u%3z@X`#ovek)(Dx%s`K-52CpO3>=PJDI(8o{B>;*? zqI&Cc8v|rTfk;hMYPNpjCncIGAdFB;BQ+Z^zYcdFDOIk;S~IuAASPUBo-N%=_5zJ| z4UYDRDl60;3Eb-V4sb3ugo&-2SLe)f6cbAYzMW5#=N*ni$HUe!vY*+uC3No@CD@B( zSN@u*{XIW!@SvW7vm~B_KB|&u!|}4Jou5nbp}XEJ%gjnZWfAaY`EvJ5G|Fk0mo2^@ zNoe6153`Jn(|mVSv_8`?*#S-BZl>!B9Nr1P_o%yeb~^576KKl9HL2{BxgA}>H+7#t zw&Kg^Zi@Pnk*6DtopJASPV6a`dfX-gOV!%KEsZAO;vXPU#4^Cw&8sn=5%Tm6zfQtz#O@6xNq$u+Zlc#f%D z|AUwMO<`G>IQ{fYWrQ}_ffFlHVl_^0_xpzcMNfQ)Vs8UU&mTPQ4RFT`i=yCWf!9m? z4FN*~FBhT9I1^F9L~;Z_`TUNpt%^B0&wf)+l65CX>1yg-LMK$#B2cw#P?J`-p)6i1 zF5nAIp&esC)zi}^+mqFvP>=EhFf?9y$U;hnZ2%@+1;rGyyve_~=KjU(AKo zJo!uwRiRCi2>NNKkprpdXtc9%<+c6trp;OX7Qu>7v_}b}ODS4#tDh+u;5~*=r?ZuA z&T!A=iJ?WqE^Cygv(B3&uXB8s93wpu4AXUAhsU;Y2^D0GaaEo?e?OG4_I-D1o%f6f zj7{TK3>0p~Fgb6r1Y&c1yH1D|>FQ3glBQ{TqgdfAY{|E)J$~L?q=#i7B90Cw{Ri(4 zp8lG|>D655L5Nj$ZqnP}8PjLQyivGtG_)f6IQC?ZjO^W6O=4or)7-dZuBDoPzk2@v z#7TgPe5h%_GU57zmYKKtS@^4~u~~eJko?%w81A#A1%i4D35kaZn`sXSq(p7vL^?Kz zT*7rNA(1sbiPO_bD6r8r|5Z7T0g{73<5-BL;O51qz>=m))29&xwHK)YGA<|gAO4!1 zdHkbC%GLM|eW&5GU*ol{`*tFxy<7xGGPVnLd%J~TEJzUKc&cW}COuQa4iHBrV_zwW zxAoW?b8d*_VLxH_@KfGgshh;EnekLq2ty?Urw_a9Tzf(cLV_aZerb1?ay`h90s&Gy zm-55cktD#rHSc-U{zLFa=z7%QX=$ans0F&|DsIVTigaHlmPs?rtH+S#R9+>Xr)j_$&h8pY}TMqR#OiknFutu%Gku|ecaw| zM$GSBhg^MSSJy$?+5ohW;cX1D(EGUL5j;d-I0XSw{bzk=U`|dqFr2cvVjAUpqiIJ# zw5o43?5*{VTQpxkFUi}21%ibXSpXSFQCISf{aELdET_*u>%0FBIB*{%*A1LK`rFQ= zr0CY@`uX5r#Q!A_^BUYM_nSS+z^A8wO&vi39}AMG$5hDaBilD*1s6=-RfXMapQDrfR?pQv(D6mo{=N;e%;HVB53AQl+ zlyxk0OB*y&b@a)~a|Mg|1$u%TUZ(2O_kiCHem=hETtUu-_Hq*g4b~wAqr0a3d@r5{C~a?%x7ibObH{bu>hvmpzOcQEU}eLlcTFRG zsIMoSA`V31xWXTKb>*^Soj5VM0+HOYrIQ+QDn&861T5K+K+@h|zf_n7q>8TaP9MYU z&$hLKtl4g9z2~0-k+wgVg#4P7gAjgxzD{SL*}9r9KX}rGc9cY~%&~&}rKa{XH%Rag;wdpz5DVPG_x|8Nc(bnI$^q;_jc;l4`~~yo zII{%qe0Ubmr>I18tOQWAs-7iG06bQXp(&hIEVbJpkg=DisaZqMREj06uC9(|n6oj~ z6rQ|ptKK_{u`T{E8$!b^B_Q_pb$QyHcIe?%ll|z|@agKQZH=DIzS2rYbf4-h zh3Qt)ro%My12c*Nd~F_QV-vw6Z75Eq3!4*8A)?7mCBos%z316w4aQ_&Vj3iz0Qu4k9}nm1eFA zT-+`+jvVW2-8yVf)a|TF-c-leA#rB(#{E~&oTFh=2I=Qk2W&3AW%B1b3$GMw3X8KS z`^cW`mg@(8+jA(fOx~1A-6|~Y@R3Yd+aF&&sJ>pVMAU>WBf^#1L!?@pnKU&8Khv>T zI+u3Z@&x*ioqkYi+41Id{kr9IShq+12XE8fW+Ng!I`9wP?`a@HeKZ27G2}$;&8%8q zIRWF_T54ZyyJzPjx4&hsktWKg^ln_%$dJala1`dM^zamjp~BJ^y5!I-;l?bH%86?^ z#R%`1ljAGgM_AL($kzwEB^6SBJ?hyF$FtIXbDgOx$I?Mv4Ueg_s?~e?Rp~zj=hzq) zNq!pHV`$#7`rBap)(&sz6p#Y0#-s^BPzP-l`uxFDn+4f{x4n39HCwhgYD;oKiH)oH z;w15Y8PNCo78K$R!5_Tqo`{#qzMd=0!Hcf33IxoN2GPwn#?S1&1&UQy_K%H>@KzWY z)Xo&&`-Aro^vgqUTfr&0&^b6aVzWsdf3&}2Wy_HbL7(%Wu@t*E#1!e#UwzS1d(gdJ z3-1ry=zg)60CvkP2#%JxB_%+5C(|Rr*%*it3Gbc41mzXhL$6npY7-73se&6i`t6;= zr7qc87y642^8Y{5n*O^O021)I`N0YNI{jocc{uXS;~Qi~Hk2-eFDc2M*E(_kfteM~ zNljFYmp2jF@4@BR0ps%UltJ)DM&e8&Fk{DJK&c>pQ7o1TQqg20D!C5s+Q~N}O4y03 zPF7<*j?%58jym%+xL+CJ5%`sUrTdPakuiDN9aq)RO|P6}|0}6RqfF#^N9OVwP|@@Z zYh>ARWu$gA@P=-QIOk3zQgt-Ax~4SY9;) z71vihhC;8u@9?Y$ECMtGGKU>*Fw*fpCX!RIgy^Hzs1)yJG*EBvV<-A=blFlcSUUA( zD)7{iPE|JuZ_9&;Ne`x)SI6=K*qW)6*S8+FE^M8G$wh~Az$5^|nM!j2XMrCna3pO;~-gGA@ z0j#G$0MCuwzm-VpHWb+DrA#XB+&oA!eCefLQ$#Sq$3p&sxewgtUIK=If06H6#}S!_ zh=*O{5nJZFU)jYsysS6LL!7_QN%QfE4`1M0HA&pb_rjN_Bl#&il@o)LFC7(u0$04K z4ol3JFSb~;?-vo{lW#A7r;%K05Yl=*d@|wn@E(!K;onb~UI8}wE>H;vSmb%a9dGA% zEja@j^upsf`~V`*H;zCeQ5^owZ?Kl7UDx@9rIXH z_)h{gaZ6bvt|7{wNbYQ|e!DovU85+T#&m>(Z@~j%gHbf2 zrGDfIOg_M?6-_H$jqMs#KM=bU&gsWpZ7twzSQpuISH)gH-;62D%9v;?A;E>OUpH?D z!1V`f4x1uB3fdx)BJgMAi&%{N#(fqW#(2}_cP}itez6(-^2wP$tf4z0BU>Onc(b=2 zD0ZE*O#~E2$aOnN{D{i2@g>;_=Rl9J!90|j#EOI|D)`ku39cvV7f;h0ws+UM?eV2# zvWJ`X(M`&0uW`Y#qvR6fGL5sGKSVNUcFf;{H4$Ix_5a|V(PcxID~S}O}p6I+nPRg z6nQF{nWbVbC@AeMXw192dPOoN9^HfFF6v53t8JH;+buek{&X5{PWhNHwl!*K1C$t< z;HuH2+g4cwSo#lcdHc~-qsYWnjh%;0+4|8lXie%36>ACF8O2{5QlPZA`N1QTrp}@%S1=>?=8qpOQWdZMw**%I9Twh< zNpLsMrNDbqH;^ag@O8^yxfx09&&~{j*`LR;z8-I6mU{NO<%xYk=xdQjRQHa@y@j16 zM$S~VukBUqFD!u&?MNA=bx16u$2KBevfMWe?E0JO58jiVzaA$9&#I8DU@0m_+Pq`t zgiPq(-76j0ldcN4AP}P(^^T#Vy3!BZschZu+fHybB8qKeOS`ctWJQ zCiz*N+}o9kfX2_W5GL0b%Yd7`!xZyS{Hb0UKPCbor-~Dt*ipJ02LNKkAv1uB;>9Qj zzJZhL@^oHeq{?=O__T9sf4v-=mz|oS)L$P8dNLu_@cOIzeX6`WhAnNdr^E=-@)2L( zg~g+%v>3?yCw?vM>sowLQYJ+&0`4b|W|KA_xL4!{BK{F~p*Qkn;M5!n- z_hnl@Z|Ca^$qGHNGC)u)_J$N8zn?f28HPYD6!aFn71wlTV4)(kCj|SVZ=*^3M1&^F zC(YwdoQk=ASJv9z6X$G?;E{nj74v2j!Jo9#ySh4xzV#BU0rRsN0aEWgT!1E6GM&Y# zP>l#K0B%d|k7`Q%=wPz)i8{Jkj9AedAdnKJ5gAD+XrU+W?C-4>n08cDOMieedTrxZ zDAjw}lUY-N>tOq3uc~q|g6h;ek$6RY$Ds9%lxeW5XKqk%qC1_SAWw9E2^+`d{A~Et zth?TwMP#W2m%5uZ2lW0+wRKwo9j%A=hvGpGX5Z1v65lHPEsh!(J%!ZUnWLAN>EEW5 z26u2(4q0$KWkbHG8(xq$&APDPgt|P19|k9+fK@*pB_8gMpNmK$mq?<7k_#FS?6+wc z|61SV$yGKEe5pzwQ(Bg!h(1+z4u(ys)2XJUymZ50FD;28gm%nhdKbuI%>^Z}B{-fr za?FV+9BcpdsX$`5&=3$|93!LPt$XHGV`B7@NSdJZYAT7)1hBudY?w@iDtL2Z(#g&@ z$4RW%^0q@=#Vk*OM~&cv*?!4zbaii^i>VWs)>Ra=7l1NVr}u%p$!%QEOK)iQ>AD|% zI1%{$NRA}8d6!ED-&Py&6mofdA_gPVi3Af`J1aBoGMX1Rgk>qG>Q%(ZwlK>9u5G>M z`(vUoK^(Nu>$*gj*l7PW5gfBYi_tdls&8Nl3yipSKKED}{LfQ^M7eKci+tK6!+f<8 zBCh3i+S|99Yz$;CHjTu$vESO%L!;^0UL;1|qg{b!{NKRsUr0#ec&>LIUwm$df?g^U z&PovBiaPSZnOV-RF%l7a%a5vbsJ+T=-O>LNZZn?Vi9NC3+Me;*NX`ol-AyaiWPG%_ zwe6W`w{c*Vv$lKa9WuH=cL2hfIbVOA-)ea*?V_ZSLs6sV% z1PYH;*5C3@y)?zZR<@Ss!mwifVJb%I>P_g1(?&XsR}-TMbW)U@DLu3o8bsewO-Ubq z*>hNw=b83yne!#(1sjV~i5!)QfkCpXS9DaZt^m@QUz9$4C^L@weKfM!qgLl8T`oDo zj+5s#SPE!4L?1G$c8J8%y;}tKWbRZBIfSe)TQOGbW=<%tZ3bqgp|^TrP;abZ}25oT{Q1@v{_aE`xjI&cXQbXi0F|JQ#DnN zz+W;W?U#17M~SQ1dG}YIWB>7y=eO6de-*A7ydRi)M^9nZ&#XN57G6~MmkGDQzYJW7 zaswz2{$??Z8+l0?)tyg$AC^l(a-TLAI77{)Hbe(Kp%d32=0@yseC5W;E@GVI2;4^H z!tI?t^$~Ay1ll9?$-vIFK-%|)b5v~j*ak=U%7$~SLNCt-M_Y**TwljLiY|3bJNOgo z1hbq&kK_<%@`y`;5hg5q?Hpc=LVE?ki6>20my3uI^4 zwV<5I-yPg@X}r{9&iN%&nxP-XES5EiMrVh`asuA0r2X6`PI9w;?u3S6n)^NoSL(f< z|6t?##RUHQLWhpt=pzTjF#r1dmPfiM_v~8Y@D7k_>us|T)qCqe;R#pVgXF~y7J4q2 zNym?IAwRRf^mGRy4lXBrDX^e~_*g_&4`Bv0vD!tC=X7k;)!s5>5O97?({e2l-D?K5 zui%i=NXChvpg?QU{cd{;yI%*>YX?0gk_d7Jc%qoUS}`X*|KOV-Es2MO94_}2{)+jH zI>qjBdsWp}H(Yu$c3(!$Ra5W5E#m{A5gMmHduv0cZd*pZh|<EL0}4W80g_ZLfwd zZ@DQ+483G;&mzM1@|$!;e}2BrUjZ&6UAOq-`7Vq={r8DdLI;k$O-|TCBepl?)pUom zU3q1|5KDK5R*R2PmzO5q4e@FJ@xlqZ*pFZ1uZ9d0v(>v^NzDU!(&A`ueDIu#WNNR&UwZIhnOufQXx9^; zYO}vz<3C~W|8ypDv&G*Wai5sfRhMyv zER8(uFrmo#G8xI<@giZ@JHr0{_(@Wu+oI4rtYM;pYE4}Y*SnoK-nY<)=j#R!akTE@ za!;M2UmuHSqCA-0d>ZmcM8`$)*oAKmv zuTlhp-=`|GWBgp2#rt=_d+q9>H_r}-D$C!aZxO}O7%bwo4fs2H)BtVkrP}M%l)3i4aOsS36lTw?VlnoB}V2#9fhS%ZD7KZUfR{PcwLA zyc&OJ9qMUnmH=g9FSeI&Qj7|1FpfpHg?Gd??oZb*%VK7698a#ZaU8Vx<3Lxj0qBN% zptT6^02+S*x*7Q6c;}zEiWQ<^})&RDxep%5;(o-3&tpNtET9yjodk}GLRZ2uVK;4&0`MbxX zEWdYXg$ClHt)FDlpNyygoR{}KBI@1?#U0MxU zB|?f2$8na_Jo->AZM&w5Y8=<4t{pZ;(eHvexCq zM59!IvW<&bn^;Ctc#oZ2=vaNIMGW0h_r@|J^oKxv=JsEwam+!(Lmg6I#G9otYEt~)i(d_3r z_OJQ*V$3m$W2Y}skBqk-adUG&xu)sF%$*qaK=8xsEf->Xo$?YAHpXlgAVbGh$JOLy zX`14_UW4Ay@tnZLORV2Dzf?!MH=^WW8$94gvI|foBv`aiWXd3Ds*6FBPP%|bSlot= z#l+xVsg&x%>b_5uWof0)TT8L(ZYh=*`D2w~#nzSXbfD>g6`#foYcTpF1lgKS3)Tbg zhUp-P#{|lLxIM8wCept{FYCYsOOpFip|{Aj_}nW3jq@gpPcdwrK_b{A+0A$?Y5z?Z zPm+Bdcpb;jlxxb*4yA_?=H}1X^87rUM(Qg|S}g}y4ukaYpv+@70UMMyl)DC8A|**D z=>VlY_0&}QRiYLuo&lkG=GI_B#VGIxZ!&!=a;(C;bH`+HerJ~UQgGR5b@q)AbIcc! zTt70q?=@rk%$Lv7-MpdQ#|;fdjhkS)$V>1QlX7YQOus~8Qo8QJaQ!Ld0<^z4@iM^O zC#o>-*O_~th9;9AXJVenPndIioJ6Za!LbR*>q2iiYes%;Sa0{xQ|DN^W|>h_8i-a} z{2#ndOvUMYkwIp?`;-Vq`<)NT<>5No@8?}Dq~$ap3w!TYC8(Y|lhND>>-7l#f@gkj znz*Q-XWqOm&3*-aZ9F_Cc_~?o0;Ph8)m#9=XF2-g#Y~{)q*^qn!B{uRur5M#?Dct2 z);Il4#o_$1-;V}p@8jLk@;&CAk^bc(a$Gt+mD@ob6cmXcxN9B@@D!1f&*Kkzj^kh_33lra|17s?;+UHadR}kI5&Dw>=w!qniMgt2 zy-x=KNHzyR7zK6!b2Oap+{~?N-l*RKKuv)c0kHOmP=Wv?x_tpp$$#PDGHulz!U#a$ ztt|lIRt=fly1#h1?4{)X?YtxYP8!tI+urJRynm1odJJMw#{_n%OJl${pa$86~p}fiG#X`Y|xiv*E^1X5dx;=6L|)E zS-S5}KB%)6%jOf+)2nt00Ug~Z@_ei-OSEK!4{B=e`M+yUE0zuV;3}5<{j)qDw5I0v zPh`!%<$M16V(?u+mzdri(AD?=T?aap!YJVW$L3(u-Wk7F0+l7AqE80$-;cevw|Mze z#|rjITE*{G;n2#z`W93InlJ&PhoyWqWyy)(KLb&hy$LhDfQAasrp-GEVnjPz#W-<8cBG{iRk-$)J3{^Dhe zZAZc%bcj`_KY+Wy%aAX6X!6`qWGj?xddIZEf4lt__V11SLi|KJ;`zK~D-s{br(Oj& z#c38chy)nXxx(K!`g!zGT?pH#=%qYnq-%c7unHXx$ zqxs1<_%~M0)$K8u6l}SEr1Etn+Vt!-3PEsJDB-T+x(fFvvXNITA=#Cr zDE<87@^^gkpaCxK&)Cb%3D>#nV^~K&g3zXp5kU@n49CKUvAhE{7Y9;C-o>IZhw1DQ zji#e#xlJ0L?*9t{r6G>>zHRWjo=uWo)^SiINjoCQepd0>2hR#uD_h&dVXaz86X|#Z zl&{U^Z-cdKezcECwU@)?t%m$#b9%~--sd@8YVBkjw>XrIvtUJ)po zHFG!e&<8Z93o_neiwC*ys6DQ~=wLk3eq+dQFMJ?0tfR$uZ@saY173~f{&t`Ln9i+Q z*KkU-s(d2MWp69YDIai6?ImuUNb^|Gpu8qk=cY~B!bl?!`thb6r-fa_w zJ&KDYM_NDeCeSSTgIAGS7B7E#R75oD(c^pPOS00#^&Pt{HH`6K7OJty8n(5Z?xc0e zl+UQ*=F{Y@3ZB@B^LB%%D)NVdC!C4dYDbRvK%NqB)>F<3*5Rf z27pDTJkN^#%byC&0N&jD_MVEd80fJ711_)C1s#d-v)K{>yrIZOp;-aIdHb)iXGe~A zDS!kc;+H=uvXX(-WFP#q3Onl@0EGVaeE>xIvK4%PV(9kI8}%$C&f*-TVhBD0{7WQp%53^rRor%D{S^T}_nJf;h2Yq(aDAPTw6K{RaW&2|j_ptn3 zWm#8w3P&H8ZQ16@*XOUs`gr;H%VVx`@xO+&`T;FN>EAW6nw#*Xu;Hf?`QZ^4 z8tl;w#7PMTf$6j7<`W{G z8O`dsZUR-Vg_rCXB9rR^-X9f;I*WpP4LqL$*%m*e4#!R% zrHc^n8gg`oEgxQD=cJRvyLy_$lY@#Rn{o~}7SEgPPZ+ksJfQjMe*4(#myOYUk$v>Li$d_TU`aR`($q9^#>IgJGUvY?Zp#uZNY}-t&9PkS2X&X= zh8d(-5O31MKuuAIh?ViN;Dl6=NfU!7h$NJbq6C~}L%$;Ezm4~OS~Z0&%F7tpk>_=D zq7PU}6(+WBWF(1_xX?GX5yHZchd(}&J)_=y9FxZ7h}w`h$j0fT7fSz*xXopHXPfb& zb7~1kCw2l3)7HAa7|-&WqZ)!XG}&+$dS{JkijK+Hd3v9OZ7U5%rh?2Ml!5^tsKINy zg}m*ak{v;EnyN1~$u0O%r>W1lqgoX!(N<);0kIp7O;OP53+ipa$t~=PEkwnOF66Y2 zP8=7_&Q2m}f=XzBfY*|xz3`!D8rL)7W3fAyck4M< zT`vY3DkGMhx_S59Bx5bNAp8=_?NLD%}#E#^Jlz+&q2(CHw?zvA#{H!Q$Q8oG(zGlFEzie$nNi6j;Gl zI(`!5&j`u8j5^ox^SJg$Uu~n;Uj{=0c!MM!CUSgUNh(e7um;LG zQ4G)|eDYv{j@X(vJ|8QgODyl1SwSC*FH5>wO-6=|9_0<4ALYQoK47ARsUGUEvg^%8 z;i1b~C&Vn13dYo)DGKxILtReIgtQ#C7`zUJg^Rqfwk%>AR)1Ep{X^&XYqK#z;wQHo zdnR4!Jd2w4MZvgk&yP-dK*Fe$kY`iPe)-hQxt@AYWXuubrw`^7x%3C`UW-E#Db=(R zxjl>e-~mvCwFhw8GnhO79vRx`c*5lsjUtMmq$9w8auD$tw_okyX2vg*Rc9!9hK*5? zVf9(Mv-$_GdyXBBW10)QF38##vT2(HqxWIzF{_jEv*!XuW1MQLhLOnw?7B#8uh6-k9b6raN4p^*Xd#2Fj5eH3OYEEZ7`7n{~EJgICDkQt)6L(^ft$$SK-iuHEeQvN0QoPe- z&}_g?^~ttcqJq5q^6~*(VXSnSk<1>)5}!8r==TOdJA{sv_8z*>?e!6aT3?E&NR%bE zAq6?|SR-;@ow7y@(2vU-etzv*uhxnR(=y&LP}RQyegmP04PhUd_dTL{NJx`@4cmGh^BUp@>eyxEC1nh6!l&xU z-jI%|b6tv**N-5c$@68$*`*!aFb%Z-(65s0)94~2wCv*PcPrp-dle4|t}kZf**$*% z2pm4b?(|Qq#R0Uqhup6aZ+OrS;aZ&k?t+X{7HD%>(pk|C8Es_!(UxKw*7!I8<)01` zEKQ;*48CsMbVf)URZ|uy|IXgmZ%=tqd3PLmj8KM{KA&vme(Aha2i$~Lb7F}PO!!ci z+@GT0cxZG{?yvK=@SKao&v(X_lkLD7_sW5X6WM3sbW2JHe=7YG%ZJ>uHd1?`pk04i z8_?zgMJ@28Qn(E~$T%1i(Ps&TOyTvEp<|XANZOz2Bg$r%YDakt^l>Gcsa9N`LR_98 zCuLGJF);;~oV1t*m%Qhy-sxw(Q+SNBXaMi44&>p2eCclcb>;hBmUpFO8T#L>&I0Ay`cV(73bR6ANQKd!VCb`Io4i17StLZ%4da0@cs&`vg(0IJApbK8Ka&IgnA zCTdWxZb(f-Q9vGSQDn*|j&gy@QdrpfzZ!oXI~x|NFn<~#A=V$bEira8$d1rohgF}f zO(ft|SlMF8T$=zzmHxmhpj#>sGda}C%{b7hd++^-oZCya2Y|dh+Rw%%SKQ)o1s9#7 zp|9VXnN2a<^zf^8jT1rjy?GGzWj(%1oc`|D;WiQyfwN+WAW?2&w{-@lgbB>G!oCWo z+3#@@HOO)0pFPZO&HZGSZ6U0nK^m8&-{oH>Z*Ch-Y*Q_q(ji>TIR5CeZbl{sDk`$y z0sO&g<-r%l^~}dcrshlF6gAfo_e0P06=$|ls?o+p2WHoU{nH3iWEnZ#ghQJbOk?-9;n2CXtNePNAE`-EV`Yb;)~d1=>t$97c(q zi)pibSD{x;iGBUtm$1bC2WM=@9rmW8Z^n<8HFtAY*C7X0VxyH}ZDui^7ztD=Sgka3 z!nD3vx1?NV$Go9vFms~1oh zJr#LWskHM3BzOgOkfws8k?&QDW)QMlb1=H&hM>7NNs=SRJ7@L}c`Mo|_?Qz+hL80~ zEyVjUTD3fkyU;;PxlQNg?g0-!QBkVY8p+v{g8lK0@-+`AyVOL+ObH8|ww8Mf19?;% z!6o4iH;W92V6ZOTFP%DlUHQ$>qAs3Bnpzuf536soQx9`K$PJv> zftJo9X*!tFdAa$AOAfsZ|KQPM^kuqsSj{lDZ~|%`=K8(&5^r69eHzeJqA=(!h>8p^ zmwPw<`t+FvB5>2@mQ|&fZk2;i7pC8Xvzy1m!aDz4Da8s3DoHP7(690tH;I)M z9^R|7H26cY>t(t`tRCQ$a&MErtVJamUGp8grbOl;w_3d+hnI)x5`nopJiO}uZ#Q}I zNe48BBotee-gYPvn(s>}tyefWG@zk4PJmk6etv6n3mkwE4wDgHc7)B&q?9MelNp9; z>!_?*qJu*$A(-MWYwc_+8>@0#64uAl6cIAh3o(&71pk2RXwtVW-FH#i!^ga(2i zc={go9Wq5iFn{nqU~JrUiMbGeFgww7y z&rBs8=M~+|-Q+PE-abde{m5OfaS|yv>FTwxcBNTd!F&@)DjH+TEY+Mpql$g>*6fqx z&>~Ne0+Hsk4^StAlJBGsxKE1a7j8LU70m47Y`s*Rk`q!OdZ%l|IMKj(CRmko(A@YBQp4=*wv%8HUP$zwPZVH%yN4P`ma!HIBZ%owoicI)of;1PuQm89M^!S*L zR!`n@X_34=LcUV;?okR!z(5bTiAWsDu-NaDT zK-3JGW>J5(n|Ea9NjxkILwGOU!$Az^{Ww^#BjZPY#IF!t#d)I#0oh^S9RO!#wQIHR zM%wU>2Yqeh6f{&HCRxPByJeb;NH#Z;YT>f#pVuHN#=1s#GU zd8WPfqmV3ltH9&+h3EplfzkJ0)bTrYIW@R#N3en4K5>X==s7m?(md=F|EO0cdn1Sf z5#LYuzUQgEj^zzZ=f7c93rru&bjceCy|U)ccY68<&md;Bz)1=#A#B}igau;h_#O7b z*56Md6#6$53yT4`*RT!Xfu;f+X*imZjLwfZn!y70$jD%TQ4I$K=b4ghqWxn!)>;8J zvwugIv@HB7YO^V*EmU3`#{S$Ln$&x955$8L9c-8?C51ha~-2p28eC0V> z)uy~p(BKXnyczdx3ZsOMnA2R9*5oP$E*eb;snUV1xtkQ94#&BWZ4+ zZbW4XpveN1k5~cLNHQ7^1s1U|voYbJQ3G^)zZ-816bKRqyyl@fnphFq z;z55X>!L3LpNjCM{Ms1e@nOqGO{Mnc%NTfUy4soFy+>DFt^Hg?Mkz?E^J*<1ox+Q5 zb$1G0MT40$D@+?tC)TT%y%3W#HUp|g00fXEju@n+#Rc}n$6kZhL>gQ&cjD|FzU3kA zaJ)Y=Q#?mPoj8`${<}k}1^N4YUH`@IxiX($fq&<^3)Qf2krTKDmQf{Xut=Oo`4wVn zTzcsfdbro>5F8XP6nx=R++cDKR||ow84s7}1o-u>IZRqH{|t`N(ju~Tig{PF8SrAd zb1XoQs-Sc;*+Y`7GVpcCk<*D6Qo66JpQoIgk)>&5Z@$`|Ncly~K}1fp@I7L?)H)B6SaYoL-Zejj;^&3#Mla zoPsZ#TpQ9#RnItGOh$s=pS=w2@*S%qX3ZfEr6|mf>Codtj4IkF@WTUyFYzwCeyvxH z-xsPHJu^L!+Mk^0SP4Q|>eY68({51lLrv7Ht|i0l?a|SK3{s7M@K)E?Pndcj-0)Zo zc)RfaqYjSDq%?-*g2H6d7)>euh@238DOEizSwKML486oy?8vqBCjA>EL$3vF7|jZj zc0aFa7@u`x7!J^wJ^_-A;TX3pG87#>zXxCI&~E1>s3m*34 zOx7aDi=`1!$ML9rakp)pxTUDTI0?UvRbJ|Af=|KdPigcK9!Zld4jzny1|_-5tByMNN3r4$PgV)J z)``Tnu~0lbN1jOXP(;Uc82|3xUV7-j9Hs}(v*y?jPFU>tIxaM^l6D(^iL;K}zWU#e zsQ)gGhkzv~H;&yhL=+@;M`cLp(b#>4cSdg9tnG>2Pd~D{7s~eIy3V^NSPgRW$heu#3s0V z6T6(=W!!Xxx;Blo_LQ4pj$5EfpgTe?9&8l+ho$)!=cVd-AF!87aoeb@E- zo$H)GoS8eH=aOgcnVq>qYP(htT|G@4e5`xXKof@3#wRho8T{iS{{T-I;-Gt}M3QnH z6cXrd(cz*Jy$SL0<9)G2hfaMRs%g|AHB*nv-s~3+tYqk$_vgTjYFRw0>8}6u$XX># zpy)MAHW46&u-XF~`TYAcU<)%Op8=cv$Qzj8=iebopNQVf12Y=(XdGDMM|CtYt1o@A z;>wBaS3}A>SXTU$m{lcNkA8h`@jGcH5daI<{IzCb7F&L;GDuT($V8bCTh13pReEClzbrQ z%Khzwkguv_*=E=03Xh%~uly$4JF0ls=z;sijlOp|pm`d7{ic^c9exs3yb>M`4juSO z*OiB#3hHJq&b@p&wQ5NPdf)XG6I?>{vRMcd1;&H-05V5Wh^;%ke(dBo10z! zcH({j!Z!9t0xaAm87B^Tezs#%IYE>F&M9exI^=bM%>IK>bZh{fSNa$8m&jf6U3Uu9 zK8Jd=FM*PAfYV1Sx{z*p>2B9DExPNmsYWq4xP4#VT1ro!AH~vI_SCLA{xuhS2v1wa z=lIvHE$rJ=y9I*uTepY%sN(8rVHOO5&Sc)sJ04H!^cA>XV65fV3wv7yVlr+wy|e#S zdn;H2f6+;@RQLzK@Qqb@O0r+wk|8$L;Zq951S%(u_0|}fnoSd=K3CDSkRlpfeEdFc zn2nj*K|;mBPy06)PFF>bW~R*N8=S8qwW%bei{~pmGEftz(EJ4?Y`A@B!RA@m;MVOm zX!&~IJ0_#W)V%K;tEn&99yvi>|z zx0`{tctVTJEwt>AjR0OQUGnTAb+^&5J7~5#xm~M&%fG-r>~2`U0p;4GW3kz(1y3ZN zQ?O@^>9WU+L1GWfZp5Bv^VaP%5)s>&q&ULXx8h6AUzUT(x1an#MsWPns9<+=au-!{ z{?a;M*`Jk1vMV)#8^op^VEbaC8CB6sv>?_$!7qSeMlI)U7kZL5wybP#sY^bSf@dhZ$WMQwqj6+>HE9Y0BUo1s{d=`jan(=)6hxOJ;lau%(z zuyR}^5>y*@wYkjHV78@r%RpiGf4N)!Uw%esAZm%!K+)-Z557XQf75xIaSj8y#|V78 z?SwU{$>J;UXo!tm5fNIJ2`fC~!#L6ID1i`U|C03Z(6tbT^Ru!TWpnI)vzEw+-?ePFDt_@rd(wp+898$q2E(Iwv#?xi z8}&_?Nl_cj@R~$)lXp2E)14nQhWX9x7zk&M{s_&IwU=VheVzVJ7~Z~?`_4P{z9N4A z^`BZFkz3Us$P2T`dXU7Rx<1TQWrS{7jFHhul$Ln=T*OUhKXgWK3>AEtId_uj(>G`O z9_&c0_aj#FWbOf=I>EQ{gP;p#6kBzg-}7ag_oa)zJSZNAzoidmOqZ}3j<6tw>e0>> zRUUt4OMJDenhkABv~+Y8On`-@R46f8+Fxd8N$M%Ea*w<{2|$C0SCU0v2&sOo1f#cR z?^0{`uGoK>%deh5?sCRg=| zR%i5$uWa*o)Bf7rn;O6bulXHv*}H84$EHubS!rRX0fZpYf1KQ(vB@@7q#X zx~8wV@yhE#rHc@uUu715G3#$+YTP>hO9rSkJ34{Qls%FUo&1Wf4_mnv)RR_Y@8EfK z_T?IpGdA@BB|rq07xST0NE1l>Z-cVz-VML#jla zI&g;8iOO;7%1n}BY{JlKc{^;Mq{i%eAwo%HE;bV`yr1*c7SD=eMV-1rh*T zO90g15cU3Laz^pD)ON(;Qc_I{HAl?E;sN4LDSkG)8`4_=K$}Jq`yM4xER~hip6k50^SnFM9>5li z8V$7%zuL7ty>dX=Ks?i@avbA6gGxH@BH2d(XrZ*fauL8Sp9V1y|1}J~4F{2~?;<~{ zEbU+7YZ39+f?E^Dx8-b#wyCQ_I*{ZlpT=`nz-`wL5K}sCemq1Yw1aXH*0}je3oB%SyJOu0h>0vd}o} z>p%0>$AQZWP#t@hb{?(*nG1HEu?U{4RCDnVY3OSdTu$qSgv3wxS28xt z4j<$EhDXo7*ME8WN}~E?k^cjSVC&rH!}>D>%+4X$z6`T3ViC z3R@=KnnKjE7I-N3Ai2Ay3Pg76bQ)Fm9f>-rdI|9Di7EMfV#cJB@+%sDjxPdN0a%uj zii*lf)ls$3mKpiNi0GlK?+KKwT|kG=+R6c<^%geet}hz2D(FV3BPdO#3MEn^(w69( znd%qKW~+!_pJScRe>RD`_ohDBlv+9_ogz_jweeYy^Az8pgi<$gshCMGF`m%VRCH}a zMg$|-fE0EXnIh2 z%^HKdlAv|cV*#F`iasOu!*P_(7qX=>u|=Jyp?ZGsD2ur)A!kBYk`8F(hvTnR%%O5( zEi+114Or_1(&7VC*2Nx$!WyqB(iXrHZgU?RX$-n+C}8cLYrS)@qS<5r9CD5$Ork;+ zbDmun^g#=2F2_jTS||7kXGWErGYOO2j&R^zQL?!P0Ib?Zpur0F*|^ZJsvDjB3Lvtm zq;sFhjcL|qcwJGdQcNMcM{dhQz=OsU9QPO>@t@Z}XDUHXuc;E{A`>%-mHuKZ_>r~( zvQH*@8!)mraIrkT6p4tL=vQ|{5LX!4e?sK29b?9(4(9mN`xiS$D6`B5h#(i*={3n0 zL&(|fgY>&>liLU1=vAUGXQJQ#M1dzrsNCoi^T5bHnWUM8XFh0Y0StL$WJf@ILfrr8 zSkel^Y-Pfvwr&Hsz%u=$z9o}bEyU4)6fpE< z|BHB-3DqNP+oonIQ(3Gi@|!;fN^>W-A@@dcaOU zB6ZO}w4tT(l`>lSw%1GPTV{00 zw+z0t4l<7|a@*Au9fd7xo~bO>chLr@0RO@z!X?_C3Npn={(?~zu>Xn@kMiUmH9lp? z?og`3BbARkI5;tBA{8;Fs?G%qUwNK^jwIL@OR>ta5T-Ho7 z>)y9OCo8JSe7q{a%C`stk*RkAypN+^23g|l5w7T2?RIzXJ4m7uheT@%o4>cFj~0D& zHyn^`A;|VW!Z$4z>mN3^C%NHrHRqx0+og7q1DieTfr$UMP&OqyDw zlgs;iOOjA;lQIEek3ZMEF9u124_8;F#^<4Bu&8#AM&!ca_m)v4a+UPv9{p;Io4q1$ z!bI;p@CHcs;He!bP5-Dx8AqRumy2haNcr6}AV;c@q9w3xa2dKSxLgkMwliYk2(w4J#9NsliFw3Kjraz;R=#`K_P)jQps!<E*8VreniWSvyWSrJsI zj~A`_|Mu9rqd@65WHjc(PyRN4LG8_0I=5I!vC#5Q-Qx!oILxeJFozfI4k=$}$ojM- zWr7Z&tA4AAomK>4H)ipV+KUU(v(q!JI(1b#J4vP~9~XR|&j*An-h8_Y4a^}fxO;Rc zRmYIOSOr0+3WW2hgwBLd#&$1w2u{6gb2+%sFXAy0oK$-(WLY3}qLJ#guE+xq%`=sk z(FmyGA1oxwf?uzlHK^QiIhitM2e^wA)^inB9xA3NI6Vh%BckX zp0xw%pRw%EGlgT$F99-=8vKfYXW~nY{k5xpCAN*zYww2|+JOW=C_M?qC%zx3sj-W5apKH7 zjed8u=*+X}%lVvz&D>|x_s@D_8Q7K!?wP&rA+zZVFwc7hGHZEJJ3GozYv?88J{WXh zNK{RcWOI@q|Ba)X@@`cVE1^}PNFD!+TEl)kS+(p=%?#V>UBg-scF#8gGC7x7h=lg6 zXU6ePgG+C|QM1>*c^g2)OV8O!xrYqhnf$PiY@-bP3K#`>p0_N2^yO(`A1L8l16;<+ ze1$jB51K-OFPb3qM<1yB3E+n#d;p=whQ^}He8CmIx;0dLqs&|GFOQt&2xN1;%#s2H zT+_7ME5L<6NV)|85Z{jlit9sw>smqA$;7$u`}~JpVXaj0&4UlSLiPyWp*5&VDWAof z-DjYJ$oYMwBO_NtlfVA#7gWmaO)$vOv32`)$S%M1`>ZeRC$;p?wSKGf%9V2a@RF3v zm5RJFlhSSC=;$J0jEvkLO5Pww4i!y+$;?901Y(?`U3#Ysy z!>fQ)21XVO;o*EUjo1bI&$v7~x6g)D%Kuo+%`NEjgMB+ydgk=xbeyAy>WB0Cr9ReR z49P~Xe@&xnW_1J+yaE^H#{w zKO1u4}-1KPq|ua~^V2wcdNQ>#xlor+iQ9Sc(V&rbK((37K(-xcLO1ZW)< zHD>IJQPIeQ;`SdlXN~NlEz_bR4#?6*cyaKjAlHv;-|aHnc1EjrWV-`c~-LLDgzIQ4jxMiatxI`|KBvdi$^#6&hD*efoYbSfM0%3~^b2r$2 zWY^Ci(9=Q{64?SR91o>3$j1=K+B&5al$T=lGjP!SH zznq=67r8>TmUzb!jV01nM=+E{O0bPKkSd z`r5K_i|8Zi_tokY;~9wT@jeoh-iOUG0-Gz?fOxj>hD|gm5=Fh+u(`qBn&WN*d}wNw zPk_5jh7wCM<&VBc7Q;edS}EnLE`ymy(gE6amQs{nGDRr~7_xsY83h-WnW449e}^DT z-+!@E#cc4$@k2Ts`9H9^{G7&r1Gcgt;lJZw#cWO>QM(l%up4qY8|-DmBotYFZ0pRx zko+nhrjHb6_sy*pzMdmP#~!OX<>Q-QeS`fonDIWJ&F4!Vn~2=a3G&)S#)4uYk~uj( z?dd9pAcj;~Sb$sc-Z_J6IhUXVsGdmN|MWGg$)oditK>!?gTK%5Be~Bz2Bq)ITokL) zHBS`Frk`v2r*;ka`1_1LlA{HZxSw}YOO@D~NvD+9+)1b2m)$ieRr_8=d;9ni+YIiJ ztgPeF;EBE<9XQ^_;Tr)YpY`HFFQ>1YwICkK+iuzvl z;)@(&ppc=-`{BQkd;|bm0U+mfmtmawt)2a?S_aiB!7q9d0j7`k_R8}CN|B@U;5;H? zZazg1us63iadgVcc?G&U%a$kq`VTdJ`@e{i^1aQZzybK{_QCE_<@jx%knBX`{CCH% zM+Uo#5s)SGlvV8s*GlTOV^)A%R_QIpC{}BmqG3-`4aY&PMsQSd4@+g~Z60ZYwA4cu zP0=5}ApAZdx-y&EM9&Eh&cWLTT7>u+ugY-{Fz4}8N2ak8Olbc_NQGqPj5#ZKZ+mM` z$YL=nHTS_N)ps-bKKzwj{9Bcs>BuxwhcEG51F9DS#vmVlnuV6#fSNlP>%yY=h}eC^ z7=YVsBhzbiQd(7j_39eS7K!vlGHy}K`$hj)8Q+1C331tX$+(#*n$^1j&SQ@m>8yr* z0it`ln^wT`ZfxFmOa2RR`sZR%9C)Feit9f#^d4P;V$cmQ^O+%LaJ06+8L1QC4zJrU zUa$i7b6Q3Zq^@eESdO!Waq*pj%eNq)9e#joREq3tGeV z4o`FuH4uLN{l5R#ri`QnbE_nC#D45viJXsrJVNF0`a!(ZqRgPeA|{4eiCX&5_O_)3 zmlg%n4dG9L2p97Vg5WzbH*gORb@f30Lrno?A7@+}v(OX>_i5S0$|9 z|EjoF%k=tSw~y-4z|ikL@tdWN>_}pK$DuO2bArxanL^O#hMjT(gvH>iHccvt;xdru zZ#p=SG4CXopgtJbOjWFwwc+;R%!)P6m2ZEaIW({t&HQ6kbsbEnDDd-MrL$Buvq~Kc zs%YHe-P?>NL2G@HkH}&M*>k;b`lb}F|L8JKPEe~9RJ1d!q#`G_ba$Tn;Y z_}+0_ML(}%_BnFP1RRDQol;ddakq|T0Ryl&$}!z@jmDXz*XJ7g9n;6i49tjRIdJD1 z=CR|__r+MFW7Pm`3j1dtV1#bsR?4#f6M!8NZ-Wy64&?On%F+a;i&kBn*}uLTFY+=A zvCbN^L8+T>R=?w0PjCCkQL9hStiE*8arW?jg>Rct^MG3VOeF34Fd%xr`rFDqXxE#0 z*%Vw`|I0rC+kW<nTtLl(zhkgz!|DV8R@wWeaPVr9FR+47P4P^? z+rCHtMGZBTOwX>W5m1sXVh-rYxJ7C&?`I}qySp)VW7`0y)k0s}_$!Z$|6g1Oz_Iw@ zg>L`3_L|4?=3knHb19Y>%la1t)%E@|fgkrqKr(o}q%aW6U9etJ7>Jo#RpZkhX@i4m zd42iXV?QqYyv@`?9!#Gn-!IE+_qPGCy!xFMK&P{?ds=%eUK5ZzF~)H@yZx=C@C#=8 zYMrjV61Ne4o)bjz7oC+;@h{$j18Tkv_;T~O>8&CC;E_&dO0mS|N1kry`JvWYzxY$l zjvH&LvaWs&shG)5*borTfEu=4SHBhm9m!zkAZI8BgbFzBHDoSyt3 zyOfel9Q8LEwy!kPc&jZh;$6Yv(Re2f_L8EoOud`UAlyxc)RVx}_4wG3tbO*s-VbTKWsv8Uin70Fe8*fu z=Yu_dc?!D`rK_He^bw_tqGPMMn8$2Js+lcYX<)$m<@G<;!o|N+-Gm{ZHh3yi)KHAb z_@OJtq)13{KlVz7J{^9{Bl+i=Vc*CwM@duPHJxVC7EhWKGfE`Xfs-oBbgwFI@Tje4 zwndTjms^Ss<$laE#XA>iWRcbY^A6V@#^cUvnWyJCODG0n&g{!U$CxBXtbNSaM}xW9 z7PGs@S^npmc-Ub>m^*y<=%kKz7w(Zdw3RX|AY9v5`oFvt2u;sEoZ07{Ma{;+g}q#u zU$~OfQ)}SAgyk8?<*kSv{644C2r;k|q-3|B!)-ZMbm$HuBHQXyiIrXRXfXKrNmPMD z1j!R6DPtgffQUS>J%AtHJ~%&o#o)aE^Tl*mc1CXMgZzA77Jn`aV$ovdm#bTDo}Hn^$lY*TYf%n?ijOf2d=oQ@tVAv zwF3D%52h+8lIPQuhQ=a%82+1|?_jb{C)ZDP{zk_2wp?^}E4-@dNrve&y{B&OWV5^r zW7j_Cwwze=f8IZ*SrS))+ls;3ZK)g^X1jP(#p^L9?ZL$@qK@s3@jJ*OBZFPIp2p(R z9r2|YaM*>w+!0q}FufjNxXYi4_vf0WF+s(B_FlCe+)yx z*4|n7s4k4yoVBiZ6(lV9qEmyXmt83S#m|ktJgzAhT#CqLeRj2kF zD#TeD;39v87Qdh*$u4D6)P6rDmKc46{7spr*(uU;p((NcWGBtCj?qO~_}AoHC!g-M#*qCgcfHO~bx(-FaghIrXN_f%&fxay&gDW# z$80kbls1y~tgnHF=***D|N625rt|Z{V;38S>tC{PV!Da5&^V=ynN=dY)!rt-Q*wLk zm(`$Ta)`d3zm%e70d4K&@b&`t8gDcguw9-`)}8o{zp+;A`C^b^CzS^L?2$ujH^rNI zU=cxTz-U5aI6zr2stSbz`>RwNt?(~m_+J=o_hsOoX&@yn7EP2-A5RTzHpy@d77Moi zGQhTjy*{=BX==M`r|*O9KXxUM{TGN;!U9&A*fkZJ_YVN%d75Q+jj4XQm#xpNQj6S3{v8y{x4=Vc9czA1xVb2U#ed?Akz5KQVr} zg``!iCw}#p=KBS&783vdS4-RYL03Tfb?ol@*Dsl%vbAX9SC=a7gxNE`UT1(sO&!M{ z+PA9;)F4KU_r-2ig<|$hK$>4jDFSl9OSF*M40@2;0n3&Llve&r4l}F4(qHTz0XXlY z?dZSSXdvMIh5;TkWb`4WDy*!RQb?m(u9iY?+<)fSnJo;-`+`{gm>7AYC=Wb zQFBxc4Ah2s|2s(V331YI>doYn^{O~@142%wX&(@#0K?8gFggO5l?VQV(2@1>Q+MY{ zl+{+Hf*{dJ6Kdr-nzTAQeb&rYLu{7$9+YL~atdSGqZ(FJv+*KnB8D(pUGZ+AM()^q z6AePFSLD5?QB};5kK+8A0kY>Pnytg6)kXa6cq8{hT$_{CT4t*??f1>uc)KMsB+0Dd zpix3|M{?pmN0xn9Vk~*=_iZWZ7hP2|6L8@^kTUs!%iTE_QMu-2>#Y^;w8voep;{+s`x|Hcln5$sGEpW4TQIg$tjP zPay|>G3WBE`;mMDiO>ppoBSGu0+%PJO|t#k{<|}Y!&$3i(Q0z2_kyrSVSmU4f)?j= zw_z-G_|LU?k@zajp*a4v1u|CzBH_|jwAYxF!_xs)E zFQp@+Jfc3NbP};%Q9PzcP_Asrw|Oh*8gjPf^OeW4pbb^l)i@J>$s*v7!40JjnzK`XFSG^kQftEdea<+N2=2jf{ENz`j~aNFn7FZHh_0yejtDG^`HQm=sV^*>!YiVY67sfBdsNrb<)hI?g{|Na_E2 zTHZsodO6j)rPfi72X+247nNo8T5u)qcdDuKgv<1^&jrUxa}N9;HkIDBQ z%iVJ)*w*G!ieAa+CACI)ipJcGTV)j)yOc963+{F)A=*$ANu@#LMwtReAz3ty)Q*aowij{?CcCO<9>5 z9=!0b?wb@SOVR2c5<9zzTAHoK+HvnK=OrYMYfoP^MVmssnLM4TuDe(g=kvY=&aLya zwVgx14O5Y2(>+@VuFnEUIihE%kNMc=xEkWnh#A)D#Cb#A#!nKn%R zwlw?O!6MytWQ8iM8}=6p&ml0BdA6Ikf>(=`ef0slt?=fI9ggZ)1HCxfUH8X+*9ymW z15$8UO&$cq4>iQnF1iO>lmz9O%J{A zQYRBnol8kW@k@8!inQqa_z_6PU|VKG_jJJq28TOr_t|J;AOb7h6xpZtJ{aKUWa|VG zmrdtZ!2dz*mR+L@W379m*#P^70QjvbzfPwIbNWg3>#T+;=LkXPti9rtC@Lu zr>wIWk-uHv7=SFP2%X`{;!;dq#F$hkEs2>dKOWGiN`!*t;@HTDn#DX1-Xf3@j8{vZXIxtzJ%~&S9V9{UF`lKeHEu2 ztB-=Dvv3|O_xWsOryOibYDhYN0N5A6=he5h$%CGT~2P=o0tXcL;SFN zp0qSY>}H2llIFz)cy$ShL6=4z((9lQ)VXR((4)2-v%`lwR|21gLPO;=a{Jf9&DkV` zhS;3gmtLb(l2yw=oJk2DG8&hbF!>>>r7Rkkh*p?{j{Xxv98c;X-4kEfneppZo@Cq? zpzeu(XrC&O{*8^5j4`BT$kFsaWmjWshRD4y+1aA{7-Ne!|u9Y(hirdX|R?QZXc%AU%{ z%Si`J%Hw8(ZEa^>gWI~UvPfQ{bBRNo?5UdS?g*N;C6a9c>b7{wy!1dpEBB(f^QV=* zJD;Ip_vY^m?_Qnuq=?h9rJrZNb4+S5U;F;)&$aG}qbu>@Y5$aDGtChCAEk#Emhe@0 z{yhZAiK@m2ox+=0-}0ssT;p$+DA8-`sA*|jcT2_#dC2#*ec4ZPejHIN;Yp4P=sLD} z*9Wdw$uv3(Pd1i{l3mPK#J?%hLqC`481OE6@<*eyQ&MdigIwyu_uP7f^-iY)CqyBU zcrz^T?nJ_T*la?^M60ZMLkK^7-m=@t3ZH0L1IOG|_Kw(801^Giy7v zOAKN74aL=e)ScJc3#7VVL_#FocaM0MSaR2ZTixwlW*EDI?vp6%FiicDT+d&1*mR_N~rG}oHa z@1E8yQ8RTxUTnb-Ef#_&=!)oeJ{pVx(cq;{)f#sGc z{x*NFt<6$()M5P2iKvGstF4>JWb=zK#r6H+ZPB4uYY-{d@M;e|jH8sB^&a$Y=nPA5I5h$f3_aJr7t+@g`vW~QW&<{UP2~;Tm}fHOa1Jd(a5sYs~&nb zv;LM5+TyEsuJ{MAm6$D?(YW)HYBD_&eBM3iBPIT%*SF>6M0xh3dYwXxc}Y-D*v+q% zYc?2+gG5VH-Ij2++IbO&(2cbXgqTrL+w3v>DvGS1EOdN?7dT14s>Bs$Bu`lzMJAW; zVCG5`>nPDWDti7#eBRycyiV#TQA6L$;}+~;-4!l+g@$vMFE0s0Hg#Y~G80#5ursL2 zM2}v8l%BGKQ_88NEa=<#>Qo^YgXq~e4YH?P%hCs~A-8!oqpkIfGn~KW@31hhncHx(eW5^6qGdETgdCHV!feT!Iy4ADRFMhkqB)FYyXo(26 zv0y-2jL~QJ#~iI0C58&*mBHKj&}|SNzwmvfwjX#QhQi-nLMpz0xr_X#$Z}dNkw(4W zc#YPY>G#r(>wZb~tU3r_Ju}# z=sL)tmC-hNSzsr=5T{*3hsR;;_6cD}igE5M2KT}% z1l_j`Vd)75zhQ6jgiAV_m)~H1Hm}^cYY_M68WVaUYHJ%xd}yC~X^)Q4SE0o{aYDe$ zFg?Giw7Va7gt2q-G}mkqv{~JXph&a-un~3!8MIN;($IS6{_a zbwJlK{IzWaM5{td*}r0!#SC=`T5uhVvSk5|i2Lc|@7z}_RcOJ*FV}vW$qooc&4Li{ zk^Dq~YvG*}7i@g0wN&xYijtKm#F0%@LH#vj)S}SKMw9PfPYbzdaDoQ z%?#qN6F8lQ<7mx%zD|HR{rX^KHvWM`vhC|TSoCwJ zMMu5hYKW~1E!(pQQZT>B1PXNe`6uYdJAQ&OHPp3*H$8Z`g z>lI+!$j$J|yA-@Yj$n-3K11fK*8c!H`}BM`#BV*F03`t{LR}{3VWOM{HI2FG=zZPZ z%YHemoMvejbJ11yzB;no(@EWeoNGwl(}^t3q($w;h2Ag=xmB)ZwmHqHlf8*In_OnI zKtzMTp9Hgc9iJnT-#(UKs7LrCa-YoIgEH^loo?yEk@1M(m3~4S#(6&2rF&jsNegn8 zC_B28-|{a1d43p#gNK?D4?8+95-p1L?2Q} z_0R1&`+BdClIj@ykUo`9BPmK0=0xZX?t|m{em59dyV;w-Ki5)&!XsT-jhz~p?A?Bs z5%M&sOVmC7Cv0e&S>#1Y5>n9P(1?rH$Vhxm&+3RP6^BD4VpiE!n(mx1#P$+5H>Mq; zpg9#Q?~S?bHZ{P2zPkN;YP@X>CG=?v4axke3oA_YA8q*8yn?XZ^H{5=)~zE4Gp=bXQ4B}BtK%W6;4+b2b#aAS*}60XXNMkT3f_$ zHQ?EVm&k2aY{T(m)_EfudC}I#7?avq>t0o-xUhS*gEgXbkW<9S!I5?Ql%7nO+WO_mSJlq3A{UcX$>)%afg?=}0Qh97+{JyJ4Z!A`kFWGCVZ zb*(?z?9NWdP6he=4R_jNI7d!27hqb7oA8x2LGPMXWH* zzzis$B0BTxEuAD2SOmz|i4C*&65%nM zM(r(YIkZZUyah9=JA#f31Ev`plIXqxm~={2J{<0#%kfuT0TX&48zQ&=d;lqSysY#F zi^%Iv^)R7ehGBXFWq{R?dWs$Cna#$7(d7;H>!4xgO9ep#Ujmg^&ThTu00u#>0Q2%2 zmgf;}63*+}Bc9)sURF;ToIJVR*U0_+A?9VEvYvPD>PDqAk623tw)aM-sh}>SG z-3pF)5Kv=cXE*8=O^GCJ-O9@ruP*~Rq9aMGzNFf)^t#@^k0#DAqGvpd9w*awf@bk1w*y!hf@HG0n?Q9<=y>D84((m@WOIa zj|d(7O90gV%m?UcXsYZTf(@!OH3>hbP{eaT0^}|h!1))z5@cV%HCG1w?XG~p!%$kF zAusB~_P@aBU*M|xFXb;_hXu$p{0{pNESYSUXDg5>(-^)>SgLHU90iu9Zf{~^>`>CU&Pb@roci#5>hz=9!> zgihwP?_bEWI+lhJ6MXSwplZeT_m5=>u7{p|&Kl;LNn#Y+CN28bAY0U_UZ#B?O^CF7 z2)iqYFI#esZi%4@X+=hng_C&H?lsD;oB3tLFpSQ{h3{%vVbCj{%laPM6pqezovY`a zD-5;~Ix!e7+Ane;+gsG^hHVx((@N~t>?+Kue30^|MNlKRg`EotONo?eYaOv7lxO6= z>m+4~FBx<^8cP1|&o#$hOSIDHpKBan&oL(RyU61BZe~n~<$!3t*`9~krR>P*S|~=E zwjSav^VEY&cH-hjT5%IKJ;)hs_Ay{6*jVyhy^4Uy7C&eOkpc6GGP@FOJ9fXct>ImR z(C8C-CL=pgl>)*V-8(0jnF|}MG}_=gmC*GJvWM#;dOUj}o#?zV`zm02nHIw7?IOwj zcK5y;KCj_k+p|{<3<+nm-n%rE5ZFw0wH4ZTM(|i+@u4l}>71$8ezgU#HLQWcPJ|3u zUF^pX0tXL65iGogC_s}^R|J&we5L|eh9qcmGO^8fB$$O?Q(&MN&G<>E)1yY$zCdNy zK1b!$c~FEm1;Ug3DC=Co=@H=s?3>C_(rTtCQ*gT93@iudQtA<8Kl#Sx(j&os^1eWv zu;3L*X0)i8Ft0Z-0gra=lUCErg!*y}>Q>$p)}^Nb3qdIV=UR1;_xTp6^_AY77t@F> z0g(*c_jrrcE;e5J)~13JqsCOadwEyx{$D6|J%EF;L4WwoI{-�h*gRfIz9Xd;zHY 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μP;-){z;hJ!;9^Y^FfO8SOF@Amk#+vufx8-2%vR=?hSx*p>l z1XD%ne?1kL7jB)(O{#}m$rW2t`D-eW^x$6oIztsNfco8xPu05$%}`Teio8(1gp)F7 z()2G_K`(KcA0hCUFJ0e!2<~x1IrlNNK4`kW2@R*KOXaT(ew4J}q)cr7A_c3z9AJlD zH|%}ypkVW6V=L0~#`_1N~JHce;*7Ji?)T$$TjQVsJO^ z=x^E=xw{T!d7OyL`t{~0 zH{HLA4iY4PNSZhA \ No newline at end of file diff --git a/images/noimage.png b/images/noimage.png new file mode 100644 index 0000000000000000000000000000000000000000..e18d7828388f238a7a67a8408ce223efda0263aa GIT binary patch literal 549 zcmV+=0^0qFP)%!p05DNx&1MtTbzRVs5F|ZBgudEg5)*iyC)9KCx>l=! z-X2OuFSt$hRFdB)=MkA!tA#zQ)hd`lC>h-1sJjpQF;rK}XNuHt>k%2>_mNbkQUSfQ zj66iWN{@STB?t4U(dnB6<-VhKyEn1tZ5KCEC${Zb)G!ReEDw=qhzxLfot0$WUYuC5 zu#N*9#}Q^_8NF!Ark&zuj0|~4WULVw*K@ZYJIgH9k3)K$Au^@&C1o|B3FNqTUbc&Y zVS5>oS*e#$?~g8JmRU0yNhks2P8`{<{9)LMG3z&T_JX>0xQKe!kfa6)QskMa9Lk2L z_E_FAp;F7eCxTbyDMjk|LV1eCvWW_p;OS(jQk%1v33VjoYKUOZsH^n_)PAEg)GL9i zX9cyFnd2d@$mIKTsrMrh;flBZ&6jIdbb8mZ^USCSg1%ti&I3YMLcjjynicxjp`Vf( n_umuSwl($8U&quD`V?RQ3I)Jm^hrSH00000NkvXXu0mjfhD7>* literal 0 HcmV?d00001 diff --git a/images/reference-hierarchy.svg b/images/reference-hierarchy.svg new file mode 100644 index 000000000..11559dab5 --- /dev/null +++ b/images/reference-hierarchy.svg @@ -0,0 +1,4 @@ + + + +Wasm-internal references
any
any
eq
eq
i31
i31
struct
struct
array
array
null
null
(...)
(...)
null
null
(...)
(...)
null
null
string
string
null
null
External references
extern
extern
nullextern
nullextern
Function references
func
func
(...)
(...)
nullfunc
nullfunc
Working draft. The design is still in flux and support is incomplete / preliminary.
Working draft. The design is still in flux and support is incomplete / preliminary.
String references
stringview_wtf8
stringview_wtf8
?
?
stringview_wtf16
stringview_wtf16
?
?
stringview_iter
stringview_iter
?
?
Text is not SVG - cannot display
\ No newline at end of file diff --git a/images/safari.svg b/images/safari.svg new file mode 100644 index 000000000..951a7e52c --- /dev/null +++ b/images/safari.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/wasi-mismatch.svg b/images/wasi-mismatch.svg new file mode 100644 index 000000000..2c8212eb8 --- /dev/null +++ b/images/wasi-mismatch.svg @@ -0,0 +1,4 @@ + + + +Cause



Web platform
Web platform...
WASI polyfill
in JavaScript
WASI polyfill...
WASI host
WASI host
Rust-like
Module
Rust-like...
Rust-like
Module
Rust-like...
Moot
Moot
Effect
Java-like
Module



Java-like...



Web platform
Web platform...
WASI shim
in WebAssembly
WASI shim...
WASI host
WASI host
Conceptional breakage
Conceptional breakage
WASI polyfill
in JavaScript
WASI polyfill...
Bloated & incompatible
Bloated & incompatible
Bloated
Bloated
Java-like
Module



Java-like...
WASI shim
in WebAssembly
WASI shim...
Text is not SVG - cannot display
\ No newline at end of file diff --git a/images/wasmer.svg b/images/wasmer.svg new file mode 100644 index 000000000..b18c1d94c --- /dev/null +++ b/images/wasmer.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/index.html b/index.html new file mode 100644 index 000000000..c87fcfceb --- /dev/null +++ b/index.html @@ -0,0 +1,79 @@ + + + + + + AssemblyScript + + + + + + + + + + + + + + + + + + +

+ + + diff --git a/interoperability.html b/interoperability.html new file mode 100644 index 000000000..47c4e7b80 --- /dev/null +++ b/interoperability.html @@ -0,0 +1,43 @@ + + + + + + +

+ Redirect after 3s +

+

+ Powered by vuepress-plugin-redirect +

+ + + \ No newline at end of file diff --git a/introduction.html b/introduction.html new file mode 100644 index 000000000..d4ece627a --- /dev/null +++ b/introduction.html @@ -0,0 +1,103 @@ + + + + + + Introduction | The AssemblyScript Book + + + + + + + + + + + + + + + + + + +

# Introduction

AssemblyScript compiles a variant of TypeScript (opens new window) (a typed superset of JavaScript) to WebAssembly (opens new window) using Binaryen (opens new window), looking like:

export function fib(n: i32): i32 {
+  var a = 0, b = 1
+  if (n > 0) {
+    while (--n) {
+      let t = a + b
+      a = b
+      b = t
+    }
+    return b
+  }
+  return a
+}
+
asc fib.ts --outFile fib.wasm --optimize
+

It is similiar to TypeScript but with WebAssembly types, has some constraints due to compiling strictly typed code ahead of time, but also some additions originating in WebAssembly's feature set. While not all of TypeScript can be supported, its close relation to JavaScript makes it a familiar choice for developers who are already used to writing code for the Web, and also has the potential to integrate seamlessly with existing Web Platform concepts to produce lean and mean WebAssembly modules.

# From a WebAssembly perspective

AssemblyScript provides WebAssembly and compiler foundations as built-in functions, making it suitable as a thin layer on top of raw WebAssembly. For example, memory can be accessed using built-in functions that compile to WebAssembly instructions directly:

store<i32>(ptr, load<i32>(ptr) + load<i32>(ptr, 4), 8)
+

For comparison, the following C code is roughly equivalent:

*(ptr + 2) = *ptr + *(ptr + 1)
+

Most WebAssembly instructions can also be written directly in AssemblyScript code, with generic variants available as well:

i32.ctz(...)             // ctz<i32>(...)
+f64.reinterpret_i64(...) // reinterpret<f64>(...)
+i64.load32_u(...)        // <i64>load<u32>(...)
+...
+

# From a JavaScript perspective

Implemented on top of its low-level capabilities, AssemblyScript provides a JavaScript-like standard library with many of the classes and namespaces one is used to from JavaScript, including Math (also Mathf for single precision), Array<T>, String, Map<K,V>, the typed arrays and so on.

The load/store example above could look like this when utilizing the standard library:

var view = new Int32Array(12)
+...
+view[2] = view[0] + view[1]
+

Both perspectives can be mixed depending on whether low-level control with WebAssembly instructions or idiomatic concepts with the managed standard library are desirable to accomplish an individual task.

# Frequently asked questions

Does AssemblyScript involve an interpreter, or a "VM in a VM"?

No, AssemblyScript compiles to WebAssembly bytecode directly, statically, ahead-of-time.

What are the differences between AssemblyScript and TypeScript?

TypeScript transpiles down to JavaScript, a dynamic just-in-time compiled language. AssemblyScript, on the other hand, compiles to a static WebAssembly binary. Their compiler implementations are quite different. However, the two languages are so very similar on the surface that they share many concepts. For example, TypeScript tooling can be used to author and refactor AssemblyScript code and, with some effort, the same code base can be transpiled to JavaScript with tsc and compiled to WebAssembly with asc, or code shared. The AssemblyScript compiler itself is portable.

Will AssemblyScript support all of TypeScript eventually?

It likely won't. While TypeScript adds typings to JavaScript, it is a superset after all and can describe many of JavaScript's dynamic features, not all of which are feasible to support in ahead-of-time compilation. Yet, sufficiently strict TypeScript code can often be made compatible with the AssemblyScript compiler with little effort.

What are good use cases for AssemblyScript?

Computation-heavy logic like image manipulation, hot game logic, specialized algorithms, emulators, compilers and the likes are great use cases for WebAssembly, and as such for AssemblyScript as well. In some situations it may also be preferable to ship bytecode instead of minified JS, or just the ability to utilize a TypeScript-like language may open up new opportunities, for example for embedded scripting or plugins.

Can AssemblyScript be used in non-standard ways, say outside of the browser?

Absolutely! AssemblyScript modules are self-contained and run anywhere where WebAssembly is supported. In fact, any arbitrary host interface can be supported. Here is an example of using WASI imports instead of Web APIs (opens new window).

Why the strange name?

AssemblyScript is to Assembly as JavaScript is to Java. Not quite.

But now, let's get started!

+ + + diff --git a/loader.html b/loader.html new file mode 100644 index 000000000..db562f9c3 --- /dev/null +++ b/loader.html @@ -0,0 +1,43 @@ + + + + + + +

+ Redirect after 3s +

+

+ Powered by vuepress-plugin-redirect +

+ + + \ No newline at end of file diff --git a/memory.html b/memory.html new file mode 100644 index 000000000..47c4e7b80 --- /dev/null +++ b/memory.html @@ -0,0 +1,43 @@ + + + + + + +

+ Redirect after 3s +

+

+ Powered by vuepress-plugin-redirect +

+ + + \ No newline at end of file diff --git a/portability.html b/portability.html new file mode 100644 index 000000000..599aa201a --- /dev/null +++ b/portability.html @@ -0,0 +1,43 @@ + + + + + + +

+ Redirect after 3s +

+

+ Powered by vuepress-plugin-redirect +

+ + + \ No newline at end of file diff --git a/quick-start.html b/quick-start.html new file mode 100644 index 000000000..067734fec --- /dev/null +++ b/quick-start.html @@ -0,0 +1,43 @@ + + + + + + +

+ Redirect after 3s +

+

+ Powered by vuepress-plugin-redirect +

+ + + \ No newline at end of file diff --git a/robots.txt b/robots.txt new file mode 100644 index 000000000..c2b997f2d --- /dev/null +++ b/robots.txt @@ -0,0 +1,7 @@ +User-agent: * +Disallow: /404 +Disallow: /404.html +Disallow: /editor +Disallow: /editor.html +Disallow: /editor-test +Disallow: /editor-test.html diff --git a/runtime.html b/runtime.html new file mode 100644 index 000000000..43d3e0e38 --- /dev/null +++ b/runtime.html @@ -0,0 +1,94 @@ + + + + + + Runtime | The AssemblyScript Book + + + + + + + + + + + + + + + + + + +

# Runtime

The AssemblyScript runtime implements the necessary bits for memory management and garbage collection. It is largely invisible to a developer but can become relevant in advanced use cases, for example when integrating AssemblyScript in new environments.

TIP

If not applicable to your use case, i.e. it is not necessary to interact with the runtime directly, you can safely skip this section.

# Variants

The runtime comes in different flavors, each useful in different use cases. The desired runtime can be specified with the --runtime compiler option:

  --runtime             Specifies the runtime variant to include in the program.
+
+                         incremental  TLSF + incremental GC (default)
+                         minimal      TLSF + lightweight GC invoked externally
+                         stub         Minimal runtime stub (never frees)
+                         ...          Path to a custom runtime implementation
+
+  --exportRuntime       Exports the runtime helpers (__new, __collect etc.).
+

The default incremental runtime provides the full package recommended in most use cases. The minimal runtime is a stripped down variant (no shadow stack, no heuristic, simpler algorithm, smaller and more efficient) that is not automated and requires calling __collect externally at appropriate times (when there are no more values on the WebAssembly stack, which would be the case when WebAssembly calls out to the host, directly or indirectly), whereas the stub runtime does not provide a garbage collector at all and never frees (simple bump allocation, extremely small).

For example, the stub runtime can be useful where modules are short-lived and collected as a whole anyhow, while the minimal runtime provides a compromise for use cases where it is sufficient to collect garbage manually, occasionally, say where a module performs a fixed amount of work before being invoked again.

In case of doubt, use incremental, but feel free to experiment with the other potentially more efficient variants where a use case permits.

# Interface

Using the --exportRuntime compiler option, the runtime interface can be exported from the module to the host, so it becomes possible to allocate new managed objects and invoke the garbage collector externally.

It is typically not necessary to invoke the runtime interface manually since generated bindings take care of all the internals. In environments where bindings are not yet available, however, the runtime interface can be utilized to provide the necessary integration.

  • function __new(size: usize, id: u32): usize
    +

    Allocates a new garbage collected instance of the object represented by the specified class id, of at least the specified size. Returns the pointer to the object (pointing at its data, not its internal header).

  • function __pin(ptr: usize): usize
    +

    Pins the object pointed to by ptr externally so it and any object it references do not become garbage collected. Note that the same object cannot be pinned more than once.

    An external object that is not referenced from within WebAssembly must be pinned whenever an allocation might happen in between allocating it and passing it to WebAssembly. If not pinned, the allocation may trigger the garbage collector to step, which would prematurely collect the object and lead to undefined behavior.

  • function __unpin(ptr: usize): void
    +

    Unpins the object pointed to by ptr externally so it can become garbage collected. Note that the respective object must have been pinned before for the unpin operation to succeed.

  • function __collect(): void
    +

    Performs a full garbage collection.

  • const __rtti_base: usize
    +

    Pointer to runtime type information in linear memory. RTTI contains information about the various classes utilized in a binary, mapping class ids to object kinds, their key and value layout, and base classes. Its layout is described in detail in shared/typeinfo (opens new window). Using RTTI, it becomes possible to implement instanceof for example, or to tell strings, arrays etc. apart.

# Memory layout

Overall, AssemblyScript partitions linear memory as follows:

Region Start offset End offset Description
Static data 0 __data_end Contents of static strings, arrays, etc.
Managed stack __data_end __heap_base Present only if the incremental runtime is used.
Heap __heap_base memory.size() << 16 Remaining space is used for dynamic allocations. Can grow.

# Header layout

Any kind of managed object in AssemblyScript utilizes a managed header for the runtime to operate on:

Name Offset Type Description
mmInfo -20 usize Memory manager info
gcInfo -16 usize Garbage collector info
gcInfo2 -12 usize Garbage collector info
rtId -8 u32 Unique id of the concrete class
rtSize -4 u32 Size of the data following the header
0 Payload starts here

References to an object always point at the start of the payload, with the header beginning 20 bytes before. Null references are just the value 0. When working with an AssemblyScript module externally, knowing the memory layout can be helpful to for example obtain an object's class id or size. Invoking __new automatically prepends a managed header and registers the object with the GC, using the provided class id for rtId and the provided size for rtSize.

# Class layout

Class fields are laid out similarly to C structs, sequentially and without packing. Each field is aligned to its type's native alignment, potentially leaving padding in between. If a class has the @unmanaged decorator, it effectively only describes a region of memory as if it were a struct that does not utilize a managed header, is not garbage collected, and can be used with heap.free. Managed classes with a managed header cannot be manually freed, and managed and unmanaged classes cannot be mixed (e.g. extend from each other).

Standard library data types use the following layouts:

Class Description
Object Object, the base class of all managed classes, has a class id of 0.
ArrayBuffer Buffers always use class id 1, with their untyped data as the payload.
String Strings always use class id 2, with their 16-bit char codes (UTF-16 code units, allowing isolated surrogates like JS) as the payload. For example, if rtSize is 8, the string's .length is 4.
TypedArray Typed arrays are objects composed of buffer (the reference to the viewed ArrayBuffer), dataStart (the start pointer into buffer) and byteLength fields, in this order. The respective id is picked sequentially and not predetermined.
Array<T> Normal arrays use the same layout as typed arrays, with an additional mutable length field coming last.
StaticArray<T> Static arrays do not need indirection due to not being resizable, and they have their data right in the payload, aligned according to T. Can be thought of as a typed buffer.
Function Functions are objects composed of their table index and their lexical env (currently always 0).
Map/Set/... Other collection use more complex layouts. Please refer to their respective sources.

It is also possible to build custom data types that integrate with the GC by implementing the __visit interface (that iterates all references contained in an object of this kind). Please refer to the sources of preexisting data types for examples.

# Calling convention

AssemblyScript's calling convention is relatively straight forward, as it does not add additional parameters to functions or other behind-the-scenes magic. Note that generated bindings take care of the calling convention automatically, but other environments may want to adhere to it specifically.

# Basic values

Exported functions wrap basic numeric return values to their respective value ranges. Basic numeric values passed to exported functions are wrapped to their respective value ranges on demand.

# Managed values

Any kind of object is passed as a pointer into memory, and the host is expected to perform the steps necessary to exchange the value between linear memory and the host system. For example, when a string is passed from WebAssembly to the host or vice-versa, it is not its data that is passed but a pointer to the string's data in linear memory. In order to read the data, the managed header before the payload can be evaluated to obtain the string's byte length. Note that host bindings automate this process for common data types.

# Optional arguments

When an exported function allows one or multiple arguments to be omitted, the module must be informed of the number of significant arguments by calling exports.__setArgumentsLength(numArgs) before calling the export, so it can fill in default values. Omitted arguments are not evaluated, i.e. zeroes can be passed. Not calling the helper leads to undefined behavior. If a function has a fixed number of arguments, it is not necessary to call the helper. The helper may not be present if a module only exports functions with a fixed number of arguments.

+ + + diff --git a/scripts/wat.js b/scripts/wat.js new file mode 100644 index 000000000..9f07b5c3c --- /dev/null +++ b/scripts/wat.js @@ -0,0 +1,713 @@ +// 'WebAssembly Text Format' Monarch language + +var WebAssemblyTextLanguage = { + config: { + brackets: [ + ['(', ')'], + ['if', 'end'], + ['loop', 'end'], + ['block', 'end'] + ], + autoClosingPairs: [ + { open: '(', close: ')' }, + { open: 'if', close: 'end' }, + { open: 'loop', close: 'end' }, + { open: 'block', close: 'end' } + ], + surroundingPairs: [ + { open: '(', close: ')' }, + { open: 'if', close: 'end' }, + { open: 'loop', close: 'end' }, + { open: 'block', close: 'end' } + ] + }, + tokens: { + keywords: [ + 'module', + 'import', + 'export', + 'memory', + 'data', + 'table', + 'elem', + 'start', + 'func', + 'tag', + 'type', + 'param', + 'result', + 'global', + 'local', + 'mut', + 'struct', + 'array', + 'field' + ], + types: [ + 'i8', + 'i16', + 'i32', + 'i64', + 'f32', + 'f64', + 'v128', + 'i31ref', + 'eqref', + 'anyref', + 'dataref', + 'externref', + 'funcref', + 'exnref', + 'extern', + 'null', + 'any', + 'eq' + ], + instructions: [ + 'pop', + 'nop', + 'drop', + 'data.drop', + 'elem.drop', + 'local.get', + 'local.set', + 'local.tee', + 'global.get', + 'global.set', + 'tuple.make', + 'tuple.extract', + 'select', + 'v128.const', + 'v128.and', + 'v128.or', + 'v128.xor', + 'v128.not', + 'v128.andnot', + 'v128.bitselect', + 'v128.load', + 'v128.load8x8_s', + 'v128.load8x8_u', + 'v128.load16x4_s', + 'v128.load16x4_u', + 'v128.load32x2_s', + 'v128.load32x2_u', + 'v128.load8_lane', + 'v128.load16_lane', + 'v128.load32_lane', + 'v128.load64_lane', + 'v128.load8_splat', + 'v128.load16_splat', + 'v128.load32_splat', + 'v128.load64_splat', + 'v128.load32_zero', + 'v128.load64_zero', + 'v128.store', + 'v128.store8_lane', + 'v128.store16_lane', + 'v128.store32_lane', + 'v128.store64_lane', + 'v128.any_true', + 'i8x16.shuffle', + 'i8x16.swizzle', + 'i8x16.bitmask', + 'i8x16.splat', + 'i8x16.popcnt', + 'i8x16.replace_lane', + 'i8x16.extract_lane_s', + 'i8x16.extract_lane_u', + 'i8x16.all_true', + 'i8x16.abs', + 'i8x16.add', + 'i8x16.add_sat_s', + 'i8x16.add_sat_u', + 'i8x16.sub', + 'i8x16.sub_sat_s', + 'i8x16.sub_sat_u', + 'i8x16.mul', + 'i8x16.neg', + 'i8x16.shl', + 'i8x16.shr_s', + 'i8x16.shr_u', + 'i8x16.eq', + 'i8x16.ne', + 'i8x16.lt_s', + 'i8x16.lt_u', + 'i8x16.le_s', + 'i8x16.le_u', + 'i8x16.gt_s', + 'i8x16.gt_u', + 'i8x16.ge_s', + 'i8x16.ge_u', + 'i8x16.min_s', + 'i8x16.min_u', + 'i8x16.max_s', + 'i8x16.max_u', + 'i8x16.avgr_u', + 'i8x16.narrow_i16x8_s', + 'i8x16.narrow_i16x8_u', + 'i16x8.bitmask', + 'i16x8.splat', + 'i16x8.load_8x8_s', + 'i16x8.load_8x8_u', + 'i16x8.replace_lane', + 'i16x8.extract_lane_s', + 'i16x8.extract_lane_u', + 'i16x8.extend_low_i8x16_s', + 'i16x8.extend_high_i8x16_s', + 'i16x8.extend_low_i8x16_u', + 'i16x8.extend_high_i8x16_u', + 'i16x8.all_true', + 'i16x8.abs', + 'i16x8.add', + 'i16x8.add_sat_s', + 'i16x8.add_sat_u', + 'i16x8.extadd_pairwise_i8x16_s', + 'i16x8.extadd_pairwise_i8x16_u', + 'i16x8.sub', + 'i16x8.sub_sat_s', + 'i16x8.sub_sat_u', + 'i16x8.q15mulr_sat_s', + 'i16x8.mul', + 'i16x8.extmul_low_i8x16_s', + 'i16x8.extmul_high_i8x16_s', + 'i16x8.extmul_low_i8x16_u', + 'i16x8.extmul_high_i8x16_u', + 'i16x8.neg', + 'i16x8.shl', + 'i16x8.shr_s', + 'i16x8.shr_u', + 'i16x8.eq', + 'i16x8.ne', + 'i16x8.lt_s', + 'i16x8.lt_u', + 'i16x8.le_s', + 'i16x8.le_u', + 'i16x8.gt_s', + 'i16x8.gt_u', + 'i16x8.ge_s', + 'i16x8.ge_u', + 'i16x8.min_s', + 'i16x8.min_u', + 'i16x8.max_s', + 'i16x8.max_u', + 'i16x8.avgr_u', + 'i16x8.narrow_i32x4_s', + 'i16x8.narrow_i32x4_u', + 'i32x4.bitmask', + 'i32x4.splat', + 'i32x4.load_16x4_s', + 'i32x4.load_16x4_u', + 'i32x4.replace_lane', + 'i32x4.extract_lane', + 'i32x4.extend_low_i16x8_s', + 'i32x4.extend_high_i16x8_s', + 'i32x4.extend_low_i16x8_u', + 'i32x4.extend_high_i16x8_u', + 'i32x4.all_true', + 'i32x4.abs', + 'i32x4.add', + 'i32x4.extadd_pairwise_i16x8_s', + 'i32x4.extadd_pairwise_i16x8_u', + 'i32x4.sub', + 'i32x4.mul', + 'i32x4.extmul_low_i16x8_s', + 'i32x4.extmul_high_i16x8_s', + 'i32x4.extmul_low_i16x8_u', + 'i32x4.extmul_high_i16x8_u', + 'i32x4.neg', + 'i32x4.shl', + 'i32x4.shr_s', + 'i32x4.shr_u', + 'i32x4.eq', + 'i32x4.ne', + 'i32x4.lt_s', + 'i32x4.lt_u', + 'i32x4.le_s', + 'i32x4.le_u', + 'i32x4.gt_s', + 'i32x4.gt_u', + 'i32x4.ge_s', + 'i32x4.ge_u', + 'i32x4.min_s', + 'i32x4.min_u', + 'i32x4.max_s', + 'i32x4.max_u', + 'i32x4.trunc_sat_f32x4_s', + 'i32x4.trunc_sat_f32x4_u', + 'i32x4.trunc_sat_f64x2_s_zero', + 'i32x4.trunc_sat_f64x2_u_zero', + 'i32x4.dot_i16x8_s', + 'i64x2.bitmask', + 'i64x2.splat', + 'i64x2.load32x2_s', + 'i64x2.load32x2_u', + 'i64x2.replace_lane', + 'i64x2.extract_lane', + 'i64x2.extend_low_i32x4_s', + 'i64x2.extend_high_i32x4_s', + 'i64x2.extend_low_i32x4_u', + 'i64x2.extend_high_i32x4_u', + 'i64x2.all_true', + 'i64x2.abs', + 'i64x2.add', + 'i64x2.sub', + 'i64x2.mul', + 'i64x2.neg', + 'i64x2.shl', + 'i64x2.shr_s', + 'i64x2.shr_u', + 'f32x4.splat', + 'f32x4.replace_lane', + 'f32x4.extract_lane', + 'f32x4.add', + 'f32x4.sub', + 'f32x4.mul', + 'i64x2.extmul_low_i32x4_s', + 'i64x2.extmul_high_i32x4_s', + 'i64x2.extmul_low_i32x4_u', + 'i64x2.extmul_high_i32x4_u', + 'i64x2.eq', + 'i64x2.ne', + 'i64x2.lt_s', + 'i64x2.le_s', + 'i64x2.gt_s', + 'i64x2.ge_s', + 'f32x4.neg', + 'f32x4.eq', + 'f32x4.ne', + 'f32x4.lt', + 'f32x4.le', + 'f32x4.gt', + 'f32x4.ge', + 'f32x4.abs', + 'f32x4.min', + 'f32x4.pmin', + 'f32x4.max', + 'f32x4.pmax', + 'f32x4.div', + 'f32x4.sqrt', + 'f32x4.ceil', + 'f32x4.floor', + 'f32x4.trunc', + 'f32x4.nearest', + 'f32x4.demote_f64x2_zero', + 'f32x4.convert_i32x4_s', + 'f32x4.convert_i32x4_u', + 'f64x2.splat', + 'f64x2.replace_lane', + 'f64x2.extract_lane', + 'f64x2.add', + 'f64x2.sub', + 'f64x2.mul', + 'f64x2.neg', + 'f64x2.eq', + 'f64x2.ne', + 'f64x2.lt', + 'f64x2.le', + 'f64x2.gt', + 'f64x2.ge', + 'f64x2.abs', + 'f64x2.min', + 'f64x2.max', + 'f64x2.pmin', + 'f64x2.pmax', + 'f64x2.div', + 'f64x2.sqrt', + 'f64x2.ceil', + 'f64x2.floor', + 'f64x2.trunc', + 'f64x2.nearest', + 'f64x2.promote_low_f32x4', + 'f64x2.convert_low_i32x4_s', + 'f64x2.convert_low_i32x4_u', + 'i32.atomic.load', + 'i32.atomic.load8_u', + 'i32.atomic.load16_u', + 'i32.atomic.store', + 'i32.atomic.store8', + 'i32.atomic.store16', + 'i32.atomic.rmw.add', + 'i32.atomic.rmw.sub', + 'i32.atomic.rmw.and', + 'i32.atomic.rmw.or', + 'i32.atomic.rmw.xor', + 'i32.atomic.rmw.xchg', + 'i32.atomic.rmw.cmpxchg', + 'i32.atomic.rmw8.add_u', + 'i32.atomic.rmw8.sub_u', + 'i32.atomic.rmw8.and_u', + 'i32.atomic.rmw8.or_u', + 'i32.atomic.rmw8.xor_u', + 'i32.atomic.rmw8.xchg_u', + 'i32.atomic.rmw8.cmpxchg_u', + 'i32.atomic.rmw16.add_u', + 'i32.atomic.rmw16.sub_u', + 'i32.atomic.rmw16.and_u', + 'i32.atomic.rmw16.or_u', + 'i32.atomic.rmw16.xor_u', + 'i32.atomic.rmw16.xchg_u', + 'i32.atomic.rmw16.cmpxchg_u', + 'i64.atomic.load', + 'i64.atomic.load8_u', + 'i64.atomic.load16_u', + 'i64.atomic.load32_u', + 'i64.atomic.store', + 'i64.atomic.store8', + 'i64.atomic.store16', + 'i64.atomic.store32', + 'i64.atomic.rmw.add', + 'i64.atomic.rmw.sub', + 'i64.atomic.rmw.and', + 'i64.atomic.rmw.or', + 'i64.atomic.rmw.xor', + 'i64.atomic.rmw.xchg', + 'i64.atomic.rmw.cmpxchg', + 'i64.atomic.rmw8.add_u', + 'i64.atomic.rmw8.sub_u', + 'i64.atomic.rmw8.and_u', + 'i64.atomic.rmw8.or_u', + 'i64.atomic.rmw8.xor_u', + 'i64.atomic.rmw8.xchg_u', + 'i64.atomic.rmw8.cmpxchg_u', + 'i64.atomic.rmw16.add_u', + 'i64.atomic.rmw16.sub_u', + 'i64.atomic.rmw16.and_u', + 'i64.atomic.rmw16.or_u', + 'i64.atomic.rmw16.xor_u', + 'i64.atomic.rmw16.xchg_u', + 'i64.atomic.rmw16.cmpxchg_u', + 'i64.atomic.rmw32.add_u', + 'i64.atomic.rmw32.sub_u', + 'i64.atomic.rmw32.and_u', + 'i64.atomic.rmw32.or_u', + 'i64.atomic.rmw32.xor_u', + 'i64.atomic.rmw32.xchg_u', + 'i64.atomic.rmw32.cmpxchg_u', + 'atomic.fence', + 'func.bind', + 'ref', + 'ref.eq', + 'ref.null', + 'ref.is_null', + 'ref.is_func', + 'ref.is_data', + 'ref.is_i31', + 'ref.as_func', + 'ref.as_non_null', + 'ref.as_data', + 'ref.as_i31', + 'ref.func', + 'ref.cast', + 'ref.cast_static', + 'ref.test', + 'ref.test_static', + 'table.get', + 'table.set', + 'table.size', + 'table.grow', + 'table.fill', + 'table.init', + 'table.copy', + 'throw', + 'rethrow', + 'i32.load', + 'i32.load8_s', + 'i32.load8_u', + 'i32.load16_s', + 'i32.load16_u', + 'i32.store', + 'i32.store8', + 'i32.store16', + 'i32.const', + 'i32.eqz', + 'i32.eq', + 'i32.ne', + 'i32.lt_s', + 'i32.lt_u', + 'i32.le_s', + 'i32.le_u', + 'i32.gt_s', + 'i32.gt_u', + 'i32.ge_s', + 'i32.ge_u', + 'i32.clz', + 'i32.ctz', + 'i32.popcnt', + 'i32.add', + 'i32.sub', + 'i32.mul', + 'i32.div_s', + 'i32.div_u', + 'i32.rem_s', + 'i32.rem_u', + 'i32.and', + 'i32.or', + 'i32.xor', + 'i32.shl', + 'i32.shr_s', + 'i32.shr_u', + 'i32.rotl', + 'i32.rotr', + 'i32.wrap_i64', + 'i32.trunc_f32_s', + 'i32.trunc_f32_u', + 'i32.trunc_f64_s', + 'i32.trunc_f64_u', + 'i32.reinterpret_f32', + 'i64.load', + 'i64.load8_s', + 'i64.load8_u', + 'i64.load16_s', + 'i64.load16_u', + 'i64.load32_s', + 'i64.load32_u', + 'i64.store', + 'i64.store8', + 'i64.store16', + 'i64.store32', + 'i64.const', + 'i64.eqz', + 'i64.eq', + 'i64.ne', + 'i64.lt_s', + 'i64.lt_u', + 'i64.le_s', + 'i64.le_u', + 'i64.gt_s', + 'i64.gt_u', + 'i64.ge_s', + 'i64.ge_u', + 'i64.clz', + 'i64.ctz', + 'i64.popcnt', + 'i64.add', + 'i64.sub', + 'i64.mul', + 'i64.div_s', + 'i64.div_u', + 'i64.rem_s', + 'i64.rem_u', + 'i64.and', + 'i64.or', + 'i64.xor', + 'i64.shl', + 'i64.shr_s', + 'i64.shr_u', + 'i64.rotl', + 'i64.rotr', + 'i64.extend_i32_s', + 'i64.extend_i32_u', + 'i64.trunc_f32_s', + 'i64.trunc_f32_u', + 'i64.trunc_f64_s', + 'i64.trunc_f64_u', + 'i64.reinterpret_f64', + 'f32.load', + 'f32.store', + 'f32.const', + 'f32.eq', + 'f32.ne', + 'f32.lt', + 'f32.le', + 'f32.gt', + 'f32.ge', + 'f32.abs', + 'f32.neg', + 'f32.ceil', + 'f32.floor', + 'f32.trunc', + 'f32.nearest', + 'f32.sqrt', + 'f32.add', + 'f32.sub', + 'f32.mul', + 'f32.div', + 'f32.min', + 'f32.max', + 'f32.copysign', + 'f32.convert_i32_s', + 'f32.convert_i32_u', + 'f32.convert_i64_s', + 'f32.convert_i64_u', + 'f32.demote_f64', + 'f32.reinterpret_i32', + 'f64.load', + 'f64.store', + 'f64.const', + 'f64.eq', + 'f64.ne', + 'f64.lt', + 'f64.le', + 'f64.gt', + 'f64.ge', + 'f64.abs', + 'f64.neg', + 'f64.ceil', + 'f64.floor', + 'f64.trunc', + 'f64.nearest', + 'f64.sqrt', + 'f64.add', + 'f64.sub', + 'f64.mul', + 'f64.div', + 'f64.min', + 'f64.max', + 'f64.copysign', + 'f64.convert_i32_s', + 'f64.convert_i32_u', + 'f64.convert_i64_s', + 'f64.convert_i64_u', + 'f64.promote_f32', + 'f64.reinterpret_i64', + 'i32.extend8_s', + 'i32.extend16_s', + 'i64.extend8_s', + 'i64.extend16_s', + 'i64.extend32_s', + 'i32.trunc_sat_f32_s', + 'i32.trunc_sat_f32_u', + 'i32.trunc_sat_f64_s', + 'i32.trunc_sat_f64_u', + 'i64.trunc_sat_f32_s', + 'i64.trunc_sat_f32_u', + 'i64.trunc_sat_f64_s', + 'i64.trunc_sat_f64_u', + 'memory.size', + 'memory.grow', + 'memory.copy', + 'memory.fill', + 'memory.init', + 'memory.atomic.notify', + 'memory.atomic.wait32', + 'memory.atomic.wait64', + 'i31.new', + 'i31.get_u', + 'i31.get_s', + 'array.new', + 'array.new_default', + 'array.init', + 'array.init_static', + 'array.get', + 'array.get_s', + 'array.get_u', + 'array.set', + 'array.len', + 'array.copy', + 'struct.new', + 'struct.new_default', + 'struct.new_with_rtt', + 'struct.new_default_with_rtt', + 'struct.get', + 'struct.get_s', + 'struct.get_u', + 'struct.set', + 'rtt.canon', + 'rtt.sub', + 'rtt.fresh_sub' + ], + controlInstructions: [ + 'block', + 'loop', + 'if', + 'else', + 'then', + 'end', + 'do', + 'let', + 'br', + 'br_if', + 'br_table', + 'br_on_exn', + 'br_on_null', + 'br_on_non_null', + 'br_on_cast', + 'br_on_cast_static', + 'br_on_cast_fail', + 'br_on_cast_static_fail', + 'br_on_func', + 'br_on_non_func', + 'br_on_data', + 'br_on_non_data', + 'br_on_i31', + 'br_on_non_i31', + 'call', + 'call_indirect', + 'call_ref', + 'return', + 'return_call', + 'return_call_indirect', + 'return_call_ref', + 'try', + 'catch', + 'catch_all', + 'delegate', + 'unreachable' + ], + + escapes: /\\(?:[abfnrtv\\"']|x[0-9A-Fa-f]{1,4}|u[0-9A-Fa-f]{4}|U[0-9A-Fa-f]{8})/, + digits: /\d+(_+\d+)*/, + octaldigits: /[0-7]+(_+[0-7]+)*/, + binarydigits: /[0-1]+(_+[0-1]+)*/, + hexdigits: /[[0-9a-fA-F]+(_+[0-9a-fA-F]+)*/, + + tokenizer: { + root: [ + + // whitespace + { include: '@whitespace' }, + + // strings + [/"([^"\\]|\\.)*$/, 'string.invalid'], // non-teminated string + [/"/, 'string', '@string'], + + // numbers (not all of these are generated, but here to be sure) + [/(@digits)[eE]([\-+]?(@digits))?[fFdD]?/, 'number.float'], + [/(@digits)\.(@digits)([eE][\-+]?(@digits))?[fFdD]?/, 'number.float'], + [/0[xX](@hexdigits)[Ll]?/, 'number.hex'], + [/0(@octaldigits)[Ll]?/, 'number.octal'], + [/0[bB](@binarydigits)[Ll]?/, 'number.binary'], + [/(@digits)[fFdD]/, 'number.float'], + [/(@digits)[lL]?/, 'number'], + + // variable names + [/\$[^\s\)]*/, { token: 'identifier' }], + + // instructions and types + [/[a-z0-9_]+(?:\.[a-z0-9_]+)*/, { + cases: { + '@types': { token: 'type.$0' }, + '@keywords': { token: 'keyword.$0' }, + '@controlInstructions': { token: 'controlInstruction.$0' }, + '@instructions': { token: 'instruction.$0' }, + '@default': 'identifier' + } + }] + ], + + string: [ + [/[^\\"]+/, 'string'], + [/@escapes/, 'string.escape'], + [/\\./, 'string.escape.invalid'], + [/"/, 'string', '@pop'] + ], + + whitespace: [ + [/[ \t\r\n]+/, ''], + [/(;; )(ERROR |FAILURE )([^\n]*)/, [ 'comment', 'error', '' ]], + [/(;; )(WARNING )([^\n]*)/, [ 'comment', 'warning', '' ]], + [/(;; )(INFO )([^\n]*)/, [ 'comment', 'info', '' ]], + [/(;; )(PEDANTIC )([^\n]*)/, [ 'comment', 'pedantic', '' ]], + [/(;; +)(~+|\^)$/, ['comment', 'underline']], + [/(;; )([^\n]*)/, ['comment', '']], + [/;;[^\n]*/, 'comment'] + ] + } + } +} + +if (typeof define === 'function' && define.amd) { + define(() => WebAssemblyTextLanguage) +} else if (typeof module === 'object' && module.exports) { + module.exports = WebAssemblyTextLanguage +} diff --git a/site.webmanifest b/site.webmanifest new file mode 100644 index 000000000..43d151574 --- /dev/null +++ b/site.webmanifest @@ -0,0 +1,19 @@ +{ + "name": "AssemblyScript", + "short_name": "AssemblyScript", + "icons": [ + { + "src": "/favicons/android-chrome-192x192.png", + "sizes": "192x192", + "type": "image/png" + }, + { + "src": "/favicons/android-chrome-512x512.png", + "sizes": "512x512", + "type": "image/png" + } + ], + "theme_color": "#ffffff", + "background_color": "#ffffff", + "display": "standalone" +} \ No newline at end of file diff --git a/sitemap.xml b/sitemap.xml new file mode 100644 index 000000000..f42a666ef --- /dev/null +++ b/sitemap.xml @@ -0,0 +1 @@ +https://www.assemblyscript.org/built-with-assemblyscript.htmldailyhttps://www.assemblyscript.org/concepts.htmldailyhttps://www.assemblyscript.org/compiler.htmldailyhttps://www.assemblyscript.org/editor-test.htmldailyhttps://www.assemblyscript.org/examples/game-of-life.htmldailyhttps://www.assemblyscript.org/examples.htmldailyhttps://www.assemblyscript.org/examples/arrays.htmldailyhttps://www.assemblyscript.org/examples/mandelbrot.htmldailyhttps://www.assemblyscript.org/examples/interference.htmldailyhttps://www.assemblyscript.org/examples/snippets.htmldailyhttps://www.assemblyscript.org/frequently-asked-questions.htmldailyhttps://www.assemblyscript.org/getting-started.htmldailyhttps://www.assemblyscript.org/dailyhttps://www.assemblyscript.org/introduction.htmldailyhttps://www.assemblyscript.org/standards-objections.htmldailyhttps://www.assemblyscript.org/runtime.htmldailyhttps://www.assemblyscript.org/status.htmldailyhttps://www.assemblyscript.org/stdlib/array.htmldailyhttps://www.assemblyscript.org/stdlib/arraybuffer.htmldailyhttps://www.assemblyscript.org/stdlib/console.htmldailyhttps://www.assemblyscript.org/stdlib/dataview.htmldailyhttps://www.assemblyscript.org/stdlib/crypto.htmldailyhttps://www.assemblyscript.org/stdlib/date.htmldailyhttps://www.assemblyscript.org/stdlib/globals.htmldailyhttps://www.assemblyscript.org/stdlib/error.htmldailyhttps://www.assemblyscript.org/stdlib/heap.htmldailyhttps://www.assemblyscript.org/stdlib/map.htmldailyhttps://www.assemblyscript.org/stdlib/math.htmldailyhttps://www.assemblyscript.org/stdlib/process.htmldailyhttps://www.assemblyscript.org/stdlib/number.htmldailyhttps://www.assemblyscript.org/stdlib/set.htmldailyhttps://www.assemblyscript.org/stdlib/staticarray.htmldailyhttps://www.assemblyscript.org/stdlib/symbol.htmldailyhttps://www.assemblyscript.org/stdlib/string.htmldailyhttps://www.assemblyscript.org/stdlib/typedarray.htmldailyhttps://www.assemblyscript.org/types.htmldaily \ No newline at end of file diff --git a/sponsors.svg b/sponsors.svg new file mode 100644 index 000000000..ee1504319 --- /dev/null +++ b/sponsors.svg @@ -0,0 +1,55 @@ + + + + +Gold Sponsors + + + +Silver Sponsors + + +Bronze Sponsors + + + + + + +Individual Backers + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/sponsors/battagline.svg b/sponsors/battagline.svg new file mode 100644 index 000000000..8e7c089f5 --- /dev/null +++ b/sponsors/battagline.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/sponsors/chainsafeth.svg b/sponsors/chainsafeth.svg new file mode 100644 index 000000000..11bed9e66 --- /dev/null +++ b/sponsors/chainsafeth.svg @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/sponsors/fastly.svg b/sponsors/fastly.svg new file mode 100644 index 000000000..114ba7204 --- /dev/null +++ b/sponsors/fastly.svg @@ -0,0 +1,4 @@ + + + + diff --git a/sponsors/graphprotocol.svg b/sponsors/graphprotocol.svg new file mode 100644 index 000000000..7d376d38d --- /dev/null +++ b/sponsors/graphprotocol.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/sponsors/nearprotocol.svg b/sponsors/nearprotocol.svg new file mode 100644 index 000000000..abfa156e2 --- /dev/null +++ b/sponsors/nearprotocol.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/sponsors/nearprotocol1.svg b/sponsors/nearprotocol1.svg new file mode 100644 index 000000000..c1d9455c2 --- /dev/null +++ b/sponsors/nearprotocol1.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/sponsors/shopify.svg b/sponsors/shopify.svg new file mode 100644 index 000000000..07bb41a92 --- /dev/null +++ b/sponsors/shopify.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/standard-library/array/index.html b/standard-library/array/index.html new file mode 100644 index 000000000..bb37b3e2a --- /dev/null +++ b/standard-library/array/index.html @@ -0,0 +1,43 @@ + + + + + + +

+ Redirect after 3s +

+

+ Powered by vuepress-plugin-redirect +

+ + + \ No newline at end of file diff --git a/standard-library/arraybuffer/index.html b/standard-library/arraybuffer/index.html new file mode 100644 index 000000000..03106736f --- /dev/null +++ b/standard-library/arraybuffer/index.html @@ -0,0 +1,43 @@ + + + + + + +

+ Redirect after 3s +

+

+ Powered by vuepress-plugin-redirect +

+ + + \ No newline at end of file diff --git a/standard-library/dataview/index.html b/standard-library/dataview/index.html new file mode 100644 index 000000000..9034d71b8 --- /dev/null +++ b/standard-library/dataview/index.html @@ -0,0 +1,43 @@ + + + + + + +

+ Redirect after 3s +

+

+ Powered by vuepress-plugin-redirect +

+ + + \ No newline at end of file diff --git a/standard-library/date/index.html b/standard-library/date/index.html new file mode 100644 index 000000000..b3656f5f8 --- /dev/null +++ b/standard-library/date/index.html @@ -0,0 +1,43 @@ + + + + + + +

+ Redirect after 3s +

+

+ Powered by vuepress-plugin-redirect +

+ + + \ No newline at end of file diff --git a/standard-library/error/index.html b/standard-library/error/index.html new file mode 100644 index 000000000..8e527851d --- /dev/null +++ b/standard-library/error/index.html @@ -0,0 +1,43 @@ + + + + + + +

+ Redirect after 3s +

+

+ Powered by vuepress-plugin-redirect +

+ + + \ No newline at end of file diff --git a/standard-library/globals/index.html b/standard-library/globals/index.html new file mode 100644 index 000000000..0734b8dd9 --- /dev/null +++ b/standard-library/globals/index.html @@ -0,0 +1,43 @@ + + + + + + +

+ Redirect after 3s +

+

+ Powered by vuepress-plugin-redirect +

+ + + \ No newline at end of file diff --git a/standard-library/map/index.html b/standard-library/map/index.html new file mode 100644 index 000000000..44836ebac --- /dev/null +++ b/standard-library/map/index.html @@ -0,0 +1,43 @@ + + + + + + +

+ Redirect after 3s +

+

+ Powered by vuepress-plugin-redirect +

+ + + \ No newline at end of file diff --git a/standard-library/math/index.html b/standard-library/math/index.html new file mode 100644 index 000000000..3eed7f3fe --- /dev/null +++ b/standard-library/math/index.html @@ -0,0 +1,43 @@ + + + + + + +

+ Redirect after 3s +

+

+ Powered by vuepress-plugin-redirect +

+ + + \ No newline at end of file diff --git a/standard-library/number/index.html b/standard-library/number/index.html new file mode 100644 index 000000000..698a50326 --- /dev/null +++ b/standard-library/number/index.html @@ -0,0 +1,43 @@ + + + + + + +

+ Redirect after 3s +

+

+ Powered by vuepress-plugin-redirect +

+ + + \ No newline at end of file diff --git a/standard-library/set/index.html b/standard-library/set/index.html new file mode 100644 index 000000000..0a8c9a319 --- /dev/null +++ b/standard-library/set/index.html @@ -0,0 +1,43 @@ + + + + + + +

+ Redirect after 3s +

+

+ Powered by vuepress-plugin-redirect +

+ + + \ No newline at end of file diff --git a/standard-library/string/index.html b/standard-library/string/index.html new file mode 100644 index 000000000..a0009b14f --- /dev/null +++ b/standard-library/string/index.html @@ -0,0 +1,43 @@ + + + + + + +

+ Redirect after 3s +

+

+ Powered by vuepress-plugin-redirect +

+ + + \ No newline at end of file diff --git a/standard-library/typedarray/index.html b/standard-library/typedarray/index.html new file mode 100644 index 000000000..5a14439d5 --- /dev/null +++ b/standard-library/typedarray/index.html @@ -0,0 +1,43 @@ + + + + + + +

+ Redirect after 3s +

+

+ Powered by vuepress-plugin-redirect +

+ + + \ No newline at end of file diff --git a/standards-objections.html b/standards-objections.html new file mode 100644 index 000000000..7ba942730 --- /dev/null +++ b/standards-objections.html @@ -0,0 +1,80 @@ + + + + + + Standards objections | The AssemblyScript Book + + + + + + + + + + + + + + + + + + +

# Standards objections

In extraordinary circumstances, when collaboration towards eventual resolution is no longer deemed possible, AssemblyScript may object to individual efforts in context of WebAssembly standardization. This page covers our objections and their relevant context.

# W3C WebAssembly Working and Community Group

After thorough consideration, AssemblyScript considers WASI, derived proposals, the W3C's endorsement of its subgroup and the Bytecode Alliance's practices, that not all of their respective members necessarily are aware and/or approve of, harmful to open standards in general and the WebAssembly specification in particular.

# WASI, 2022-09

WASI (opens new window) is a POSIX-like import namespace for non-Web WebAssembly that provides a set of external functions (opens new window) such as fd_write inspired by a low-level layer exposed in systems programming languages such as C++ and Rust, but not on the Web platform. WASI, which is marketed as (opens new window) a standard (opens new window) in close proximity to an official W3C standardization effort, has little overlap with WebAssembly's scope (opens new window) and high-level goals (opens new window), and is governed by a powerful and largely independent-acting W3C subgroup working towards select custom goals (opens new window). Over time, the WASI subgroup has expanded its scope, devising its own proposals (opens new window) that in part compete with established or currently devised Web standards, nowadays promoting fragmentation in tension with the purpose of standards. As part of the disconnect, we have been exposed to a modus operandi of abuse of power when voicing concerns, where our representatives have been systematically discriminated and their concerns silenced, for example by the WASI chair under a pretense with appended derogatory retrospective (opens new window), with the outcome that concerns expressed remain unaddressed.

All in all, WASI and the WASI group make it almost impossible for other participants to pursue (opens new window) efforts (opens new window) aligned with WebAssembly's goals, many of which solely exist on paper today to the broader community's astonishment, while WASI's concepts and ideas continue to diffuse into everything WebAssembly, progressing a premature ecosystem split that is ironically mediated via the standard itself.

Our assessment of WASI's relation to several of WebAssembly's high-level goals (opens new window) and values is as follows:

Communicated technical goal Assessment
Portable
While it can be polyfilled (opens new window), WASI is not a reasonably portable abstraction for high-level languages / the Web.
In violation
Support for languages other than C/C++ (and Rust)
Languages that would naturally fit the Web platform not only are overlooked, but WASI's self-imposed abstinence of Web concepts undermines other languages' interoperability potential with JS and the Web platform specifically.
In violation
Execute within and integrate well with the existing Web platform
WASI does not integrate with the existing Web platform but fundamentally competes with it.
In violation
Maintain the versionless, feature-tested and backwards-compatible evolution story of the Web
WASI's concepts are not backwards-compatible (opens new window) with Web platform concepts.
In violation
Execute in the same semantic universe as JavaScript
WASI's semantics fundamentally differ from JavaScript's, effectively establishing an alternative universe.
In violation
Access browser functionality through the same Web APIs that are accessible to JavaScript
WASI is unconcerned with Web APIs and JavaScript and its group refuses to take their existence into account.
In violation
Promote other compilers and tools targeting WebAssembly
WASI stifles other compilers and breaks other languages through introduction of inefficiency and incompatibility.
In violation
Communicated organizational value Assessment
Charter (opens new window)
WASI's adherence to scope, participation, communication and decision policy is generally questionable. Specifically, WASI's deliverables certainly do not "interoperate gracefully with JavaScript and the Web".
In violation
CEPC (opens new window)
The WASI group systematically abuses the CEPC to "win" losing arguments.
In violation

Summarized, WASI has little overlap with technical goals and organizational values in Web standards in general and the WebAssembly specification in particular. Its subgroup nourishes a discriminatory and exclusionary environment to its own advantage which lopsidedly reinforces its technical bias. It is our impression that the WASI group deliberately applies said practices in order to strongly disadvantage its competitors (opens new window), willingly taking chances that the overall standardization effort is profoundly damaged.

Concrete technical or related concerns we have voiced that remained unaddressed are:

  • For languages that are a natural fit for the Web platform, WASI leads to a shim in Wasm (opens new window) and, lacking alternatives, a polyfill in JS, with conceptional breakage in between, indicating that it is not the right abstraction to support many programming languages well.
  • WASI mandates concepts uncommon on the Web (for e.g. strings) that are fundamentally incompatible with Java-like languages and JavaScript, indicating that it is not a reasonable abstraction when compatibility with the existing Web platform is the goal. +

    Diagram of cause and effect of WASI's choices.

  • WASI introduces redundancy where functionality available on the Web platform is eagerly implemented differently on top of WASI.
  • Overuse of WASI leads to code bloat in WebAssembly on the Web / in browsers, where code size arguably matters the most.
  • WASI promotes fragmentation by introducing the requirement to recompile modules for different environments.
  • WASI promotes fragmentation through eagerly extending its scope and independently devising competing APIs.

Nonetheless, we are open to consider re-engagement with WASI as a custom effort given that the following conditions are met:

  • Relocation of WASI repositories and venues out of the W3C / WebAssembly organization to +
    • a) clearly indicate its not necessarily aligned non-polyglot, non-Web approach and
    • b) end the detrimental effects of endorsement over all other efforts.
  • Clear communication that WASI is unconcerned with many of WebAssembly's overall goals and the existing Web platform.
  • An acknowledgement of wrongdoing and sincere apology to lessen the suffering of those discriminated, discredited and excluded.
  • The presence of well-intention and honesty and the absence of political finesse when addressing the conditions.

We recommend to the WebAssembly CG to ensure that the first condition is fulfilled in any case as we expect that failure to do so will prolong the endorsement's emergent political properties that run counter to rational and constructive technical discourse.

# Component Model, 2022-09

The same considerations as for WASI apply to its Component Model (opens new window), a proposal to define "portable, virtualizable, statically-analyzable, capability-safe, language-agnostic interfaces, especially those being defined by WASI" for all of WebAssembly, that, even though it does not make the connection obvious, is aptly named the "WASI Component Model" by those in the know 1 (opens new window) 2 (opens new window) 3 (opens new window). The Component Model not only cements WASI's preferences as the standard's foundation, but has almost silently replaced long awaited proposals such as JS+DOM (opens new window), WebIDL bindings (opens new window) and Interface Types (opens new window), even though improvements to Wasm/JS interoperability are commonly considered obvious wins yet surprisingly remain absent from the WebAssembly platform. So far we haven't seen any credible evidence that would support the drift away from bindings to the differently scoped Component Model, and suspect strategical reasons.

Our assessment of the Component Model's relation to several of WebAssembly's high-level goals and values is identical to our assessment on WASI above, whereas the Component Model affects all of WebAssembly while violating important properties such as compatibility and security. Our assessment of the Component Model's relation to several of its own goals (opens new window) is as follows:

Communicated technical goal Assessment
Portable, cross-language composition
Works if all languages involved are Rust-like. Breaks in all other cases, incl. when interfacing with JS / Web APIs.
In violation
Language neutrality
The Component Model only supports one family of programming languages — the exact bias it claims to avoid.
In violation
Formal semantics
The Component Model is not defined in the same semantic framework as core Wasm, which is the Web platform.
In violation
Web platform integration
The Component Model undermines Web platform integration for languages that would otherwise be a natural fit.
In violation

Concrete technical or related concerns we have voiced that remained unaddressed are:

  • The Component Model unnecessarily restricts its concepts (for e.g. strings), introducing incompatibility and security issues via target-oriented design choices like its "canonical ABI" or a questionable distinction between "external" and "internal" function calls, where the distinction conveniently does not make a difference for WASI's audience yet "external" calls break Web-, JS- and self-interop for any language that would naturally fit the Web platform. Support for affected use cases is not proposed by the Component Model. +

    Diagram of cause and effect of the Component Model's choices.

  • The Component Model proposes Rust/non-Web concepts exclusively, with Java-like/Web platform concepts nowhere to be found.
  • The Component Model's chosen "canonical ABI" needlessly biases WebAssembly against the Web platform in favor of C++ and Rust.
  • The Component Model states the goals of "language neutrality" and "Web platform integration", which it exactly does not honor.
  • Using the Component Model for ESM-integration will break the Web platform on the fundamental level of function calls, say when JavaScript modules, including transparently in dependencies, are upgraded to or otherwise replaced with WebAssembly modules.

Various process discrepancies respectively violations have been observed over the course of the Component Model being established:

  • In May 2020, the champion of the Component Model proposal (Interface Types at the time) acknowledged (opens new window) that Interface Types' preferred choice of semantics does not match Java-like languages, including JavaScript, and that it would be technically trivial to support Java-like respectively Web platform semantics as well. The group signaled support for the resolution. However, in a later rebase commit that didn't indicate a connection, the exact opposite (opens new window) was committed and justified with nonsensical prose:

    While the canonical representation of all the numeric types are obvious, due to their fixed-power-of-2 sizes, char requires the proposal to choose an arbitrary character encoding. To match the core wasm spec's choice of UTF-8 (opens new window), and the more general trend of "UTF-8 Everywhere" (opens new window), this proposal also chooses UTF-8. By choosing a canonical string encoding happy path while providing a graceful fallback to efficient transcoding, Interface Types provides a gentle pressure to eventually converge without performance cliffs in the meantime.

    First, there is a better than an arbitrary choice: Do what the Web platform does. Second, a file format's choice has little to do with the requirements of API calls. Third, "UTF-8 Everywhere" is an opinion piece by people who publicly state that JavaScript, still WebAssembly's primary interop language, is harmful. Fourth, there is no "happy path", no "graceful fallback" and no "efficient transcoding" for Java-like languages and JavaScript interop. Fifth, it is not any proposal's business to provide pressure against the Web platform. Sixth, eventual convergence is impossible due to hard backwards-compatibility constraints. Seventh, surely there will be performance cliffs, even worse incompatibility, not just in the meantime, but forever if the most fundamental building block, the char type, is already artificially restricted. Unicode code points would instead have been a compatible choice.

  • In May 2021, a series of polls was proposed (opens new window) to the CG's meeting agenda to establish the Component Model. The accompanying presentation (opens new window) contained inaccurate "Proposed next steps" to justify a single "canonical ABI" that would inscribe WASI's semantic choices, calling anything else "just an optimization", which is obviously untrue, while sidestepping "hard design questions", which, also given the prior acknowledgement, is a stretch. A clarifying presentation to inform the group about the implications was proposed (opens new window) by AssemblyScript, which was simply rejected to be given before the polls would take place.

  • AssemblyScript nonetheless hurried to publish an issue with the presentation attached (opens new window) the weekend before the polls would take place. Issue and presentation remained unaddressed until the polls had passed. In the discussion before the polls (opens new window), the concerns were mentioned, but the line of thought harshly interrupted mid-sentence by an Interface Types champion so the concern was not adequately discussed. The polls subsequently passed with the WASI lobby voting in favor. The AssemblyScript representative voted "against" as he was advised by a member of the WebAssembly WG to not vote strongly. It was said doing so would be considered bad practice. During the discussion, an Interface Types champion clarified upon request by another member that the poll would not prescribe specific semantics, which later turned out to be untrue, yet likely convinced more people to vote neutral or in favor.

  • In preparation for their presentation, the AssemblyScript representative requested an ongoing invite to the WASI subgroup's meetings, where Interface Types' and later the Component Model's design choices are first presented. He was first not admitted based on vague conduct accusations by the WASI chair, and after politely agreeing to special rules was only admitted to a single meeting and discouraged from speaking up, with the WASI chair stating that the concerns were uninteresting and nobody would address them anyhow. Meanwhile, one day after proposing the Component Model, the WASI subgroup had declared itself an equal part (opens new window) of the standardization process regardless of the many prior process and organizational discrepancies its endorsement had already fueled. Other chairs ignored the recent incident when the AssemblyScript representative asked for help when suspecting foul play. Eventually, the WASI chair suggested publicly that the male individual might have made her uncomfortable on her personal Twitter account (opens new window), a potentially career-ending move, even though there has never been a personal correspondence.

  • After the polls, in June 2021, a Google employee authored two (opens new window) threads (opens new window) in the W3C Technical Architecture Group that would break JavaScript string semantics and thus compatibility with the Web platform by design principle. Only days later, the existence of the threads was used as part of a list of similarly natured arguments (opens new window) to justify breaking with JavaScript/Web platform semantics.

  • In a discussion slot nonetheless requested in a later meeting in June 2021, an Interface Types champion filibustered (opens new window). When time ran out, a CG chair suggested a follow-up meeting. The follow-up meeting was cancelled shortly after, stating "reluctance". The group was not informed, even though requested. An orderly Interface Types subgroup was not established, even though suggested, so both Interface Types and the Component Model remain specified in the largely independent-acting WASI subgroup until today.

  • For an August 2021 meeting, a summary and hard-to-grasp poll (opens new window) were added to the CG meeting agenda by the Component Model champion. AssemblyScript requested (opens new window) to clarify the poll's text by at least referencing the respective WebIDL concepts so more people would understand what is voted for, which was collectively rejected by WG members and chairs. Our renewed concerns and suggestions (opens new window) were cleverly bypassed (opens new window) during the final decision process (see next item).

  • In the August 2021 meeting, the Component Model champion did not present a summary according to their agenda item (opens new window) but one-sided arguments in favor (opens new window), even though it was clarified beforehand (opens new window) that the champion would summarize. The May 2021 poll, that was said to not prescribe specific semantics, was used as an argument to decide for specific semantics. The polls then passed, with the WASI lobby voting in favor. Two members disagreed strongly this time and were ridiculed by the group for voicing frustration at the end of the meeting. Their strong votes made no difference. Other AssemblyScript contributors later voiced that they didn't understand what was being voted for respectively were surprised by the one-sided presentation.

  • In September 2021, the Component Model repository was created, ironically stating the goals (opens new window) of "language neutrality" and "Web platform integration", both of which are exactly not being honored respectively undermined by the Component Model.

  • Also in September 2021, a big picture discussion (opens new window) in context of WASI and in spirit of this objection was closed and locked under a pretense, the latter of which is untypical, by the WASI chair. An unsolicited retrospective was attached, painting the AssemblyScript representative, who cannot respond, in a bad light. The representative later complained to the W3C ombuds (opens new window) about the action. The ombuds didn't respond, instead the chairs disregarded the complaint, the WASI chair edited and doubled-down on their closing comment, and when finally voicing major frustration regarding the series of process violations and discrepancies the AssemblyScript representative was banned from participating in the WebAssembly organization in all forms by the W3C CEO upon request of the WASI chair. A list of foregoing process and conduct violations similar to this one was provided in response, but was disregarded.

As such, we have reason to believe that the events surrounding the Component Model are politically motivated, whereas technical facts have either been misrepresented or ignored, and people been discouraged, discriminated and excluded with the intent to silence them.

Even though we consider the process and conduct violations in context of the Component Model extraordinarily serious and the amount of technical disinformation and bias unacceptable, we are open to a constructive re-engagement with a revised Component Model proposal given that the following conditions are met:

  • Freezing the Component Model proposal until Wasm/JS interoperability has been significantly improved, mitigating risks of premature standardization ahead of the market respectively in dangerous contradiction to WebAssembly's overall goals.
  • A firmly established commitment to consider compatibility with the Open Web Platform critically important (opens new window).
  • An acknowledgement of wrongdoing and actual adherence to Wasm's and the Component Model's communicated goals.
  • The presence of well-intention and honesty and the absence of political finesse when addressing the conditions.

If not possible or refused, we recommend to the WebAssembly CG to delegitimize the Component Model proposal and to not advance it any further, since standardizing it would prematurely bias WebAssembly against the existing Web platform respectively against exactly those programming languages that would fit the Web platform by design, which is, given the power constellation and consequent experience, almost certainly forever, and as such would set a fatal precedent that politically undermining purpose and goals of W3C standardization efforts with questionable practices is a viable and, even worse, legitimate strategy.

# Notes on the W3C

Even though the W3C is undoubtedly aware, its role in context of the events remains unclear to us. Regardless of our bad experience, we obviously agree that a respectable standardization body should responsibly shepherd the WebAssembly standardization effort, and we are open to extend our engagement with the W3C given that the following conditions are met:

  • Relocation of WASI repositories and venues out of the W3C / WebAssembly organization to end the detrimental endorsement.
  • The appointment of reasonably neutral and responsible chairs to re-establish trust into the W3C's processes and values.
  • Removal of members who have abused the CEPC to discriminate and exclude members for voicing their opinion.
  • A firmly established commitment to consider compatibility with the Open Web Platform critically important (opens new window).
  • An acknowledgement of wrongdoing and sincere apology to lessen the suffering of those systematically mistreated.
  • The presence of well-intention and honesty and the absence of political finesse when addressing the conditions.

If not possible or refused, we recommend to the community to investigate whether Ecma would be a more suitable venue. We recognize that there is no such path if the browser vendors have an interest to leave the situation suboptimal at their discretion.

# Notes on the Bytecode Alliance

We are skeptical of a re-engagement with the Bytecode Alliance, a coalition of several tech giants and select collaborators that is (opens new window) "dedicated to creating … new software foundations, building on standards such as … WASI". Its founding members describe (opens new window) the dawn of WebAssembly as an "opportunity to fix what’s broken" (presumably the Web), "build new foundations for native development" (presumably a non-Web), while taking "deliberate, cross-industry action to ensure this happens in the right way" (likely explaining the political properties). Subsequently, from what we've witnessed, it appears to selectively empower respectively weaken players in the WebAssembly space, applies questionable process values (opens new window) such as "disagree and commit" that are, realistically, suitable to break anything, including its own technical values (opens new window), solely by authoritative claim, and, if our experience with its management-level figures taught us anything, operates well beyond the limits of its purported social values (opens new window) of "collaboration", "inclusiveness" and "openness". Given its not strictly necessary but remarkable concentration of power, and that its members' actions in context of a supposedly open and collaborative standardization effort speak a very clear language, we'd like to caution the public to keep an eye on potential anti-competitive practices that would indicate the need for antitrust legislation to step in. We recognize that not all members of the Bytecode Alliance necessarily are aware and/or approve of its surface-level actions, since several of them have engaged with us in good faith, even though the Bytecode Alliance's representatives have not. All in all we believe that WebAssembly, and in turn the Web, would be better off without it, since realistically, the processes and venues to drive its ideas already exist, but now are at risk to be rendered dysfunctional by the deliberateness of its operation.

# Ecosystem considerations

We believe that the WebAssembly standard, its ecosystem, the Web platform, its stakeholders and the public would benefit immensely from compatibility of WebAssembly with the existing Web platform (opens new window) while putting an emphasis on fostering a truly open and collaborative space where everyone can participate without fear of harassment, so ideas can be exchanged, many more programming languages and use cases become viable and the Web's principles and values are adhered to. We see negative value in an arbitrarily neutered technology that was taken over by politics while ignoring technical concerns, well-established facts and broad public interest. No amount of creative marketing and political finesse will make up for the enormous damage a select few's divisive efforts are doing to the WebAssembly technology that amazed us with the promise to bring many programming languages and use cases not only to the Web but their people closer together. Given that use cases that would fit the Web platform are artificially disadvantaged, while hard to pick up programming languages and often metered use cases with diverging concepts are irrationally advantaged, we thus look with sorrow not only towards the future of the Web platform but also towards the various new endeavors in the WebAssembly space, since, in its current politically constrained form that is stripping Wasm of its true potential while simultaneously introducing portability, compatibility and security problems, the market will likely not grow large enough soon enough to support them all. As such we believe that it is in almost everyone's best interest to ensure that purpose, goals and values of open Web standards are honored, which currently is, frankly, not the case — and sadly, the situation is reinforced by many who put almost religious programming language preference, predatory business practices in support of non-Web use cases or the interplay of both over a once so promising vision.


We hope that we managed to express our objections clearly and in sufficient detail. Thank you for your consideration.

+ + + diff --git a/status.html b/status.html new file mode 100644 index 000000000..822717e48 --- /dev/null +++ b/status.html @@ -0,0 +1,110 @@ + + + + + + Implementation status | The AssemblyScript Book + + + + + + + + + + + + + + + + + + +

# Implementation status

AssemblyScript both aims to be a thin and efficient layer on top of WebAssembly, as well as a language with familiar syntax for developers coming from TypeScript. These two goals are sometimes in conflict, since not all features are equally viable to implement on top of WebAssembly's capabilities right now, respectively applicable in general in ahead-of-time compilation. As such the focus is to implement what's feasible first, and where possible to delay features that are better served by one of the future WebAssembly proposals to avoid otherwise duplicate work. In a sense, the approach is similar to the MVP model used in WebAssembly specification. Some features are critical to make AssemblyScript work right now of course, so there are some exceptions to this rule.

# WebAssembly features

Some language features rely on future WebAssembly functionality (opens new window) to become viable. The following table aims to give an overview from a WebAssembly perspective:

WebAssembly spec Engines AssemblyScript (flag) Perspective
✔️ Finished proposal
Import/export of mutable globals (opens new window) ✔️ good Interop
JS BigInt integration (opens new window)1 ✔️ good Interop
Sign-extension operations (opens new window) ✔️ good Efficiency
Non-trapping float-to-int conversions (opens new window) ✔️ good Efficiency
Bulk memory operations (opens new window) ✔️ good Efficiency
Fixed-width SIMD (opens new window) 🏁 simd good Feature
Reference types (opens new window) 🔨 reference-types good Interop
Multi-value (opens new window) good Feature
🏁 Standardize the feature
Extended constant expressions (opens new window) 🔨 good Efficiency
Tail call (opens new window) good Efficiency
🔨 Implementation phase
Relaxed SIMD (opens new window) 🏁 relaxed-simd good Feature
Exception handling (opens new window) 🔨 exception-handling good Feature
Typed function references (opens new window) 🔨 gc good Feature
Garbage collection (opens new window) 🔨 gc good Efficiency / Interop
Multiple memories (opens new window) 🔨 good Feature
Branch hinting (opens new window) good Efficiency
JS Promise integration (opens new window) uncertain
Threads (opens new window) 🔨 threads uncertain
Memory64 (opens new window) 🔨 uncertain
📖 Spec text available
ECMAScript module integration (opens new window) good Interop
Instrument and tracing (opens new window) good Debugging
💡 Feature proposal
Reference-typed strings (opens new window) 🔨 stringref good Interop
Extended name section (opens new window) 🔨 good Debugging
JS customization for GC (opens new window) good Interop
Type imports (opens new window) good Interop
Flexible vectors (opens new window) good Feature
Constant time (opens new window) good Security
Stack switching (opens new window) uncertain
Call tags (opens new window) uncertain
Memory control (opens new window) uncertain
Profiles (opens new window) uncertain
Component model (opens new window)2 harmful
Quasi proposal
WASI (opens new window)2 harmful

Web:   + Chrome Firefox Safari Node.js   ⁞   +Non-Web:   + Wasmer Wasmtime

1 Supported otherwise by Non-Web hosts.   2 See our detailed standards objections.

Perspective Description
good This specification is conceptually good and worth looking into
uncertain AssemblyScript is uncertain about this specification and not in a hurry to implement it
harmful AssemblyScript considers this specification to be harmful in its current state

# Language features

As such, certain higher-level language features still have their limitations or are not yet available. From a language perspective:

Feature What to expect?
🐤 Functional
Bootstrap The compiler can compile itself to WebAssembly, passing the test suite. Note that the compiler is not technically "self hosted" in WebAssembly yet, as it currently uses a JavaScript frontend for I/O and links to Binaryen (C++ compiled with Emscripten), which again requires some amount of JS glue code.
OOP Largely implemented in linear memory. Access modifiers like private and protected are not currently enforced. There is rudimentary support for interfaces.
Standard library Largely implemented in linear memory. Some APIs function a little different than in JavaScript due to differences introduced by static typing or not yet available future features. There is a separate status document (opens new window) specific to the standard library.
Generics Generics are compiled as monomorphized templates for now and can be specialized with static type checks. Constraining extends XY clauses are not yet enforced.
Garbage collection Implemented in linear memory for the time being, independent of the host GC.
Host integration Enabled by generated host bindings, respectively the runtime interface for integration into non-Web environments.
🐣 Limited
Union types Union types are not supported yet, except for nullable class types. There is no any type. A viable alternative is to use generics specialized with static type checks to achieve a similar effect.
Symbols Symbols are implemented in the standard library, but don't have deep compiler integration yet.
Object literals Object literals can be used in places where the current type is a bare class, then corresponding to an instantiation of the class.
JSON JSON is not strictly typed in nature, so we haven't settled on a standard yet. Solutions developed by the community: assemblyscript-json (opens new window)
RegExp Regular expressions need quite a lot of supporting code with many quirks, and we haven't decided on an implementation yet. Solutions developed by the community: assemblyscript-regex (opens new window)
Date There is initial support for the UTC parts, but WebAssembly lacks access to the system's time zone data. In general the Temporal proposal could be more feasible to adopt. Solutions developed by the community: assemblyscript-temporal (opens new window).
🥚 Not implemented
Closures Captures of local variables are not yet supported and would be best implemented on top of future WebAssembly features, also to avoid inventing a custom ABI. Can be worked around by using a global variable instead (does not need to be captured), or passing an argument with the relevant values.
Iterators Iterators and for..of loops are not supported yet. APIs that would return an iterator return an array of keys or values for now instead.
Rest parameters Rest parameters are not supported yet. Would benefit from a WebAssembly proposal to avoid a custom ABI, but there is none yet. Optional parameters with a default value are supported and can often be used as an alterantive.
Exceptions Exceptions require support from the WebAssembly engine first. Throwing currently aborts the program.
Promises There is no concept of async/await yet due to the lack of an event loop. Future WebAssembly proposals might help with the stack switching parts (pause and resume execution).
BigInt Instead of BigInts, AssemblyScript has opted to utilize WebAssembly's 64-bit integers. It is currently unclear how both concepts could mix.
🕳️ Not supported
Dynamicness AssemblyScript avoids overly dynamic JavaScript features by design and focuses on static compilation.

# On closures

Closures (functions with a captured environment) are not yet supported and we are waiting for the Function References 🦄 and Garbage collection 🦄 (captured environments are GC'ed) proposals to land. However, since this is a crucial language feature, we may end up with a filler implementation using linear memory. Not available yet, though.

In the meantime we recommend to restructure code so closures are not necessary, i.e. instead of writing

function computeSum(arr: i32[]): i32 {
+  var sum = 0
+  arr.forEach(value => {
+    sum += value // fails
+  })
+  return sum
+}
+

restructure to

var sum: i32 // becomes a WebAssembly Global
+function computeSum(arr: i32[]): i32 {
+  sum = 0
+  arr.forEach(value => {
+    sum += value // works
+  })
+  return sum
+}
+

or to

function computeSum(arr: i32[]): i32 {
+  var sum = 0
+  for (let i = 0, k = arr.length; i < k; ++i) {
+    sum += arr[i] // works
+  }
+  return sum
+}
+

# On dynamicness

AssemblyScript intentionally avoids very dynamic JavaScript features that cannot be compiled efficiently, like for example:

  • Assigning any value to any variable.
  • Compare values of incompatible types.
  • Implicitly convert from a non-string to a string without using x.toString().
  • Assign a new property, that has not been statically declared, to a class or object.
  • Assign a class to a variable (e.g. var clazz = MyClass) since classes are static constructs without a runtime representation.
  • Patch class .prototypes since there are none.
  • Access arguments to dynamically obtain function arguments.
  • Dynamically obtain the name of a function at runtime or otherwise use reflection.

Some of these restrictions, like implicit conversion to strings when concatenating with a string, may be lifted in the future, while others, like prototypes, may never be viable in ahead-of-time compilation. For instance, some features would work in an interpreter and may become efficient with a JIT compiler, yet going down that rabbit hole runs counter to WebAssembly's, and by definition AssemblyScript's, goals.

# Tooling features

Feature What to expect?
🐤 Functional
Debugging There is support for debug information and source maps. See also.
Testing Unopinionated with simple assertions. Solutions developed by the community: as-pect (opens new window)
🐣 Limited
Linting AssemblyScript re-uses TypeScript tooling with a // @ts-ignore here or there but would benefit from a dedicated language server eventually. Solutions developed by the community: asls (opens new window)
+ + + diff --git a/stdlib/array.html b/stdlib/array.html new file mode 100644 index 000000000..f2181fa92 --- /dev/null +++ b/stdlib/array.html @@ -0,0 +1,126 @@ + + + + + + Array | The AssemblyScript Book + + + + + + + + + + + + + + + + + + +

# Array

A randomly accessible sequence of values of a generic type.

The Array API is very similar to JavaScript's (MDN (opens new window)), with the notable difference that one must make sure that there are no null values if T is a non-nullable reference type. Example:

var arr = new Array<string>(10)
+// arr[0]; // would error 😢
+for (let i = 0; i < arr.length; ++i) {
+  arr[i] = ""
+}
+arr[0]; // now it works 😊
+

# Constructor

  • new Array<T>(capacity?: i32)
    +
    Constructs a new array.

# Static members

  • function isArray<U>(value: U): bool
    +
    Tests if a value is an array.

# Instance members

# Fields

  • var length: i32
    +
    The length of this array. Setting the length to a value larger than internal capacity will automatically grow the array.

# Methods

  • function concat(other: Array<T>): Array<T>
    +

    Concatenates the values of this and the other array to a new array, in this order.

  • function copyWithin(target: i32, start: i32, end?: i32): this
    +

    Copies a region of an array's values over the respective values starting at the target location.

  • function every(fn: (value: T, index: i32, self: Array<T>) => bool): bool
    +

    Calls the specified function with every value of the array until it finds the first value for which the function returns false. Returns true if all functions returned true or the array is empty, otherwise false.

  • function fill(value: T, start?: i32, end?: i32): this
    +

    Replaces the values of the array from start inclusive to end exclusive in place with the specified value, returning the array.

  • function filter(fn: (value: T, index: i32, self: Array<T>) => bool): Array<T>
    +

    Calls the specified function with every value of the array, returning a new array with all values for which the function returned true.

  • function findIndex(fn: (value: T, index: i32, self: Array<T>) => bool): i32
    +

    Calls the specified function with every value of the array until it finds the first value for which the function returns true, returning its index. Returns -1 if that's never the case.

  • function findLastIndex(fn: (value: T, index: i32, self: Array<T>) => bool): i32;
    +

    Calls the specified function with every value of the array starting at the end until it finds the first value for which the function returns true, returning its index. Returns -1 if that's never the case.

  • function flat(): valueof<T>[]
    +

    Flattens an array of arrays to a one-dimensional array. null entries are ignored.

  • function forEach(fn: (value: T, index: i32, self: Array<T>) => void): void
    +

    Calls the specified function with every value of the array.

  • function includes(value: T, fromIndex?: i32): bool
    +

    Tests if the array includes the specified value, optionally providing a starting index.

  • function indexOf(value: T, fromIndex?: i32): i32
    +

    Gets the first index where the specified value can be found in the array. Returns -1 if not found.

  • function join(separator?: string): string
    +

    Concatenates all values of the array to a string, separated by the specified separator (default: ,).

  • function lastIndexOf(value: T, fromIndex?: i32): i32
    +

    Gets the last index where the specified value can be found in the array. Returns -1 if not found.

  • function map<U>(fn: (value: T, index: i32, self: Array<T>) => U): Array<U>
    +

    Calls the specified function with every value of the array, returning a new array of the function's return values.

  • function pop(): T
    +

    Removes and returns the last value of the array. Modifies Array#length. Throws a RangeError if the array is empty.

  • function push(value: T): i32
    +

    Adds one more value to the end of the array and returns the Array's new length. Modifies Array#length.

  • function reduce<U>(
    +  fn: (accumValue: U, currentValue: T, index: i32, self: Array<T>) => U,
    +  initialValue: U
    +): U
    +

    Calls the specified reducer function with each value of the array, resulting in a single return value. The respective previous reducer function's return value is remembered in accumValue, starting with initialValue, becoming the final return value in the process.

  • function reduceRight<U>(
    +  fn: (accumValue: U, currentValue: T, index: i32, self: Array<T>) => U,
    +  initialValue: U
    +): U
    +

    Calls the specified reducer function with each value of the array, from right to left, resulting in a single return value. See Array#reduce for the reducer function's signature.

  • function reverse(): this
    +

    Reverses an array's values in place, modifying the array before returning it.

  • function shift(): T
    +

    Removes and returns the first value of the array. Modifies Array#length.

  • function slice(start?: i32, end?: i32): Array<T>
    +

    Returns a shallow copy of the array's values from begin inclusive to end exclusive, as a new array. If omitted, end defaults to the end of the array.

  • function some(fn: (value: T, index: i32, self: Array<T>) => bool): bool
    +

    Calls the specified function with every value of the array until it finds the first value for which the function returns true, returning true. Returns false otherwise or if the array is empty.

  • function sort(fn?: (a: T, b: T) => i32): this
    +

    Sorts the values of the array in place, using the specified comparator function, modifying the array before returning it. The comparator returning a negative value means a < b, a positive value means a > b and 0 means that both are equal. Unlike in JavaScript, where an implicit conversion to strings is performed, the comparator defaults to compare two values of type T.

  • function splice(start: i32, deleteCount?: i32): Array<T>
    +

    Removes deleteCount (defaults to all remaining) values from the array, starting at index start, modifying the array in place, returning the removed values.

  • function toString(): string
    +

    Returns the result of Array#join().

  • function unshift(value: T): i32
    +

    Adds one more value to the start of the array and returns the Array's new length. Modifies Array#length.

+ + + diff --git a/stdlib/arraybuffer.html b/stdlib/arraybuffer.html new file mode 100644 index 000000000..1f4c8dedb --- /dev/null +++ b/stdlib/arraybuffer.html @@ -0,0 +1,90 @@ + + + + + + ArrayBuffer | The AssemblyScript Book + + + + + + + + + + + + + + + + + + +

# ArrayBuffer

A fixed-length raw binary buffer.

The ArrayBuffer API is exactly as in JavaScript (MDN (opens new window)).

# Constructor

  • new ArrayBuffer(length: i32)
    +
    Constructs a new buffer of the given length in bytes.

# Static members

  • function isView<T>(value: T): bool
    +
    Returns true if value is one of the buffer views, such as one of the typed arrays or a DataView.

# Instance members

# Fields

  • readonly byteLength: i32
    +
    The buffer's length, in bytes.

# Methods

  • function slice(begin?: i32, end?: i32): ArrayBuffer
    +

    Returns a copy of this buffer from begin, inclusive, up to end, exclusive.

  • function toString(): string
    +

    Returns a string representation of this buffer.

+ + + diff --git a/stdlib/console.html b/stdlib/console.html new file mode 100644 index 000000000..c3896b087 --- /dev/null +++ b/stdlib/console.html @@ -0,0 +1,94 @@ + + + + + + console | The AssemblyScript Book + + + + + + + + + + + + + + + + + + +

# console

An implementation of the console global.

# Static members

  • function assert<T>(assertion: T, message?: string): void
    +

    Logs message to console if assertion is false-ish.

  • function log(message?: string): void
    +

    Outputs message to the console.

  • function debug(message?: string): void
    +function info(message?: string): void
    +function warn(message?: string): void
    +function error(message?: string): void
    +

    Outputs message to the console, prefixed with "Debug:", "Info:", "Warning:" or "Error:" respectively.

  • function time(label?: string): void
    +

    Starts a new timer using the specified label.

  • function timeLog(label?: string): void
    +

    Logs the current value of a timer previously started with console.time.

  • function timeEnd(label?: string): void
    +

    Logs the current value of a timer previously started with console.time and discards the timer.

+ + + diff --git a/stdlib/crypto.html b/stdlib/crypto.html new file mode 100644 index 000000000..25ae8584f --- /dev/null +++ b/stdlib/crypto.html @@ -0,0 +1,86 @@ + + + + + + crypto | The AssemblyScript Book + + + + + + + + + + + + + + + + + + +

# crypto

An implementation of the crypto global.

# Static members

  • function getRandomValues(array: Uint8Array): void
    +
    Fills array with cryptographically strong random values.
+ + + diff --git a/stdlib/dataview.html b/stdlib/dataview.html new file mode 100644 index 000000000..e06fe4ee2 --- /dev/null +++ b/stdlib/dataview.html @@ -0,0 +1,110 @@ + + + + + + DataView | The AssemblyScript Book + + + + + + + + + + + + + + + + + + +

# DataView

An interface for working with a raw binary buffer.

The DataView API is exactly as in JavaScript (MDN (opens new window)).

# Constructor

  • new DataView(buffer: ArrayBuffer, byteOffset?: i32, byteLength?: i32)
    +
    Constructs a new DataView on the specified buffer and region.

# Instance members

# Fields

  • readonly buffer: ArrayBuffer
    +

    The backing buffer.

  • readonly byteLength: i32
    +

    The length of this view from the start of its buffer.

  • readonly byteOffset: i32
    +

    The offset of this view from the start of its buffer.

# Methods

  • function getFloat32(byteOffset: i32, littleEndian?: bool): f32
    +

    Gets the 32-bit float value at the specified offset from the start of the view.

  • function getFloat64(byteOffset: i32, littleEndian?: bool): f64
    +

    Gets the 64-bit float value at the specified offset from the start of the view.

  • function getInt8(byteOffset: i32): i8
    +

    Gets the signed 8-bit integer value at the specified offset from the start of the view.

  • function getInt16(byteOffset: i32, littleEndian?: bool): i16
    +

    Gets the signed 16-bit integer value at the specified offset from the start of the view.

  • function getInt32(byteOffset: i32, littleEndian?: bool): i32
    +

    Gets the signed 32-bit integer value at the specified offset from the start of the view.

  • function getInt64(byteOffset: i32, littleEndian?: bool): i64
    +

    Gets the signed 64-bit integer value at the specified offset from the start of the view.

  • function getUint8(byteOffset: i32, littleEndian?: bool): u8
    +

    Gets the unsigned 8-bit integer value at the specified offset from the start of the view.

  • function getUint16(byteOffset: i32, littleEndian?: bool): u16
    +

    Gets the unsigned 16-bit integer value at the specified offset from the start of the view.

  • function getUint32(byteOffset: i32, littleEndian?: bool): u32
    +

    Gets the unsigned 32-bit integer value at the specified offset from the start of the view.

  • function getUint64(byteOffset: i32, littleEndian?: bool): u64
    +

    Gets the unsigned 64-bit integer value at the specified offset from the start of the view.

  • function setFloat32(byteOffset: i32, value: f32, littleEndian?: bool): void
    +

    Sets the 32-bit float value at the specified offset from the start of the view.

  • function setFloat64(byteOffset: i32, value: f64, littleEndian?: bool): void
    +

    Sets the 64-bit float value at the specified offset from the start of the view.

  • function setInt8(byteOffset: i32, value: i8): void
    +

    Sets the signed 8-bit integer value at the specified offset from the start of the view.

  • function setInt16(byteOffset: i32, value: i16, littleEndian?: bool): void
    +

    Sets the signed 16-bit integer value at the specified offset from the start of the view.

  • function setInt32(byteOffset: i32, value: i32, littleEndian?: bool): void
    +

    Sets the signed 32-bit integer value at the specified offset from the start of the view.

  • function setInt64(byteOffset: i32, value: i64, littleEndian?: bool): void
    +

    Sets the signed 64-bit integer value at the specified offset from the start of the view.

  • function setUint8(byteOffset: i32, value: u8, littleEndian?: bool): void
    +

    Sets the unsigned 8-bit integer value at the specified offset from the start of the view.

  • function setUint16(byteOffset: i32, value: u16, littleEndian?: bool): void
    +

    Sets the unsigned 16-bit integer value at the specified offset from the start of the view.

  • function setUint32(byteOffset: i32, value: u32, littleEndian?: bool): void
    +

    Sets the unsigned 32-bit integer value at the specified offset from the start of the view.

  • function setUint64(byteOffset: i32, value: u64, littleEndian?: bool): void
    +

    Sets the unsigned 64-bit integer value at the specified offset from the start of the view.

  • function toString(): string
    +

    Returns a string representation of this object.

Endianness defaults to littleEndian = false.

+ + + diff --git a/stdlib/date.html b/stdlib/date.html new file mode 100644 index 000000000..1ec7b006e --- /dev/null +++ b/stdlib/date.html @@ -0,0 +1,120 @@ + + + + + + Date | The AssemblyScript Book + + + + + + + + + + + + + + + + + + +

# Date

Represents timestamps.

The Date API is still preliminary with only a subset of properties and methods implemented. Note that getting the current date, via Date.now, requires importing the Date object from the host (as Date).

WARNING

Date does not currently support timezones other than UTC. Therefore, methods such as toString and toTimeString can only be partially implemented.

# Constructor

  • new Date(value: i64)
    +
    Constructs a new date object from an UTC timestamp in milliseconds.

# Static members

  • function now(): i64
    +

    Returns the current UTC timestamp in milliseconds. To use this function you must import the Date object from the host (as Date).

  • function UTC(
    +  year: i32,
    +  month?: i32,
    +  day?: i32,
    +  hour?: i32,
    +  minute?: i32,
    +  second?: i32,
    +  millisecond?: i64
    +): i64
    +

    Returns the UTC timestamp in milliseconds of the specified date.

  • function parse(dateString: string): Date
    +

    Parses a Date object from a string (ISO 8601 format only).

  • function fromString(dateTimeString: string): Date
    +

    Creates a Date object from an ISO 8601 formatted string.

# Instance members

  • function getTime(): i64
    +

    Gets the UTC timestamp of this date in milliseconds.

  • function setTime(value: i64): i64
    +

    Sets the UTC timestamp of this date in milliseconds and returns the timestamp.

  • function getUTCFullYear(): i32
    +

    Gets the full year according to universal time.

  • function setUTCFullYear(value: i32): i32
    +

    Sets the full year according to universal time.

  • function getUTCMonth(): i32
    +

    Gets the (zero indexed) month according to universal time.

  • function setUTCMonth(value: i32): i32
    +

    Sets the (zero indexed) month according to universal time.

  • function getUTCDate(): i32
    +

    Gets the day of the month according to universal time.

  • function setUTCDate(value: i32): i32
    +

    Sets the day of the month according to universal time.

  • function getUTCDay(): i32
    +

    Gets the day of the week in the specified date according to universal time, where 0 represents Sunday.

  • function getUTCHours(): i32
    +

    Gets the hour according to universal time.

  • function setUTCHours(value: i32): i32
    +

    Sets the hour according to universal time.

  • function getUTCMinutes(): i32
    +

    Gets the minute according to universal time.

  • function setUTCMinutes(value: i32): i32
    +

    Sets the minute according to universal time.

  • function getUTCSeconds(): i32
    +

    Gets the second according to universal time.

  • function setUTCSeconds(value: i32): i32
    +

    Sets the second according to universal time.

  • function getUTCMilliseconds(): i32
    +

    Gets the millisecond according to universal time.

  • function setUTCMilliseconds(value: i32): i32
    +

    Sets the millisecond according to universal time.

  • function toISOString(): string
    +

    Returns the a string in simplified extended ISO 8601 format.

  • function toUTCString(): string
    +

    Returns the a string in RFC-1123 format and the UTC time zone.

  • function toDateString(): string
    +

    Returns the a date string in human readable form in English WWW MMM DD YYYY format.

  • function toTimeString(): string
    +

    Returns the a time string in HH:MM:SS format.

WARNING

At the moment toTimeString doesn't output time zone and doesn't use local time zone offset!

  • function toString(): string
    +
    Returns the a time string in human readable form in English WWW MMM DD YYYY HH:MM:SS format.

WARNING

At the moment toString doesn't output time zone and doesn't use local time zone offset!

+ + + diff --git a/stdlib/error.html b/stdlib/error.html new file mode 100644 index 000000000..aaea24217 --- /dev/null +++ b/stdlib/error.html @@ -0,0 +1,90 @@ + + + + + + Error | The AssemblyScript Book + + + + + + + + + + + + + + + + + + +

# Error

Represents a runtime error.

The Error API is very similar to JavaScript's (MDN (opens new window)), with some properties not being implemented yet.

# Variants

Variant Description
Error Represents a general error.
RangeError Represents an error where a value is not in the range of allowed values.
TypeError Represents an error where a value is not of the expected type.
SyntaxError Represents an error where the syntax of the input in invalid.

The Errorclass can also be sub-classed by forwarding message and setting the name property in the overloaded constructor.

# Constructor

  • new Error(message?: string)
    +
    Constructs a new error object.

# Instance members

# Fields

  • var message: string
    +

    The message of this error.

  • var name: string
    +

    The name of this error. In case of Error, this is "Error".

  • var stack: string
    +

    The stack trace of this error. Not supported yet, hence an empty string.

# Methods

  • function toString(): string
    +
    Returns a string representation of this error in the form name: message.
+ + + diff --git a/stdlib/globals.html b/stdlib/globals.html new file mode 100644 index 000000000..d563700f2 --- /dev/null +++ b/stdlib/globals.html @@ -0,0 +1,255 @@ + + + + + + Globals | The AssemblyScript Book + + + + + + + + + + + + + + + + + + +

# Globals

The following global constants and functions are present alongside the standard library's classes.

# Constants

  • const NaN: auto // f32 or f64
    +

    Not a number as a 32-bit or 64-bit float depending on context. Compiles to a constant.

  • const Infinity: auto // f32 or f64
    +

    Positive infinity as a 32-bit or 64-bit float depending on context. Compiles to a constant.

# Functions

  • function isNaN<T>(value: T): bool
    +

    Tests if a 32-bit or 64-bit float is NaN.

  • function isFinite<T>(value: T): bool
    +

    Tests if a 32-bit or 64-bit float is finite, that is not NaN or +/-Infinity.

  • function parseInt(str: string, radix?: i32): f64
    +

    Parses a string representing an integer to an f64 number Returns NaN on invalid inputs.

    Type-specific variants of parseInt are available separately:

    • F32.parseInt to parse to a 32-bit float.
    • I8.parseInt to parse to a signed 8-bit integer, respectively U8.parseInt if unsigned.
    • I16.parseInt to parse to a signed 16-bit integer, respectively U16.parseInt if unsigned.
    • I32.parseInt to parse to a signed 32-bit integer, respectively U32.parseInt if unsigned.
    • I64.parseInt to parse to a signed 64-bit integer, respectively U64.parseInt if unsigned.
  • function parseFloat(str: string): f64
    +

    Parses a string to a 64-bit float. Returns NaN on invalid inputs.

# Builtins

The following builtins provide direct access to WebAssembly and compiler features. They form the low-level foundation of the standard library, while also being available for everyone to utilize where directly tapping into WebAssembly or the compiler is desired.

# Static type checks

By making use of the following special type checks, especially in generic contexts, untaken branches can be eliminated statically, leading to concrete WebAssembly functions that handle one type specificially.

  • function isInteger<T>(value?: T): bool
    +

    Tests if the specified type or expression is of an integer type and not a reference. Compiles to a constant.

  • function isSigned<T>(value?: T): bool
    +

    Tests if the specified type or expression can represent negative numbers. Compiles to a constant.

  • function isFloat<T>(value?: T): bool
    +

    Tests if the specified type or expression is of a float type. Compiles to a constant.

  • function isVector<T>(value?: T): bool
    +

    Tests if the specified type or expression is of a SIMD vector type. Compiles to a constant.

  • function isReference<T>(value?: T): bool
    +

    Tests if the specified type or expression is of a reference type. Compiles to a constant.

  • function isString<T>(value?: T): bool
    +

    Tests if the specified type or expression can be used as a string. Compiles to a constant.

  • function isArray<T>(value?: T): bool
    +

    Tests if the specified type or expression can be used as an array. Compiles to a constant.

  • function isFunction<T>(value?: T): bool
    +

    Tests if the specified type or expression is of a function type. Compiles to a constant.

  • function isNullable<T>(value?: T): bool
    +

    Tests if the specified type or expression is of a nullable reference type. Compiles to a constant.

  • function isDefined(expression: auto): bool
    +

    Tests if the specified expression resolves to a defined element. Compiles to a constant.

  • function isConstant(expression: auto): bool
    +

    Tests if the specified expression evaluates to a constant value. Compiles to a constant.

  • function isManaged<T>(expression: auto): bool
    +

    Tests if the specified type or expression is of a managed type. Compiles to a constant. Usually only relevant when implementing custom collection-like classes.

# Example of static type checking

function add<T>(a: T, b: T): T {
+  return a + b // addition if numeric, string concatenation if a string
+}
+
+function add<T>(a: T, b: T): T {
+  if (isString<T>()) { // eliminated if T is not a string
+    return parseInt(a) + parseInt(b)
+  } else { // eliminated if T is a string
+    return a + b
+  }
+}
+

TIP

If you are not going to use low-level WebAssembly in the foreseeable future, feel free to come back to the following paragraphs at a later time.

# Utilities

  • function bswap<T>(value: T): T
    +

    Reverses the byte order of the specified integer.

  • function sizeof<T>(): usize
    +

    Determines the byte size of the respective basic type. Means: If T is a class type, the size of usize, the pointer type, is returned. To obtain the size of a class in memory, use offsetof<T>() instead. Compiles to a constant.

  • function offsetof<T>(fieldName?: string): usize
    +

    Determines the offset of the specified field within the given class type. If fieldName is omitted, this returns what could be interpreted as either the size of the class, or the offset where the next field would be located, before alignment. Compiles to a constant. The fieldName argument must be a compile-time constant string because there is no information about field names anymore at runtime. Therefore, the field's name must be known at the time the returned constant is computed.

  • function alignof<T>(): usize
    +

    Determines the alignment (log2) of the specified underlying basic type; i.e. If T is a class type, the alignment of usize is returned. Compiles to a constant.

  • function assert<T>(isTrueish: T, message?: string): T
    +

    Traps if the specified value is not true-ish, otherwise returns the non-nullable value. Like assertions in C, aborting the entire program if the expectation fails. Where desired, the --noAssert compiler option can be used to disable assertions in production.

  • function trace(message: string, n?: i32, a0?: f64, a1?: f64, a2?: f64, a3?: f64, a4?: f64): void
    +

    Simple trace function which prints message and 5 optional f64 arguments to a console. n is count of used arguments.

    # Usage examples

    trace("foo");
    +trace("one arg:", 1, 5.0);
    +trace("three args:", 3, 1.0, <f64>2, 3);
    +
  • function instantiate<T>(...args: auto[]): T
    +

    Instantiates a new instance of T using the specified constructor arguments.

  • function changetype<T>(value: auto): T
    +

    Changes the type of a value to another one. Useful for casting class instances to their pointer values and vice-versa.

  • function idof<T>(): u32
    +

    Obtains the computed unique id of a class type. Usually only relevant when allocating objects or dealing with RTTI externally.

  • function nameof<T>(value?: T): string
    +

    Returns the name of a given type.

# WebAssembly

# Math

The following generic built-ins compile to WebAssembly instructions directly.

  • function clz<T>(value: T): T
    +
    Performs the sign-agnostic count leading zero bits operation on a 32-bit or 64-bit integer. All zero bits are considered leading if the value is zero.
    T Instruction
    i8, u8, i16, u16, i32, u32, bool i32.clz
    i64, u64 i64.clz
  • function ctz<T>(value: T): T
    +
    Performs the sign-agnostic count trailing zero bits operation on a 32-bit or 64-bit integer. All zero bits are considered trailing if the value is zero.
    T Instruction
    i8, u8, i16, u16, i32, u32, bool i32.ctz
    i64, u64 i64.ctz
  • function popcnt<T>(value: T): T
    +
    Performs the sign-agnostic count number of one bits operation on a 32-bit or 64-bit integer.
    T Instruction
    i8, u8, i16, u16, i32, u32 i32.popcnt
    i64, u64 i64.popcnt
    bool none
  • function rotl<T>(value: T, shift: T): T
    +
    Performs the sign-agnostic rotate left operation on a 32-bit or 64-bit integer.
    T Instruction
    i32, u32 i32.rotl
    i64, u64 i64.rotl
    i8, u8, i16, u16 emulated
    bool none
  • function rotr<T>(value: T, shift: T): T
    +
    Performs the sign-agnostic rotate right operation on a 32-bit or 64-bit integer.
    T Instruction
    i32, u32 i32.rotr
    i64, u64 i64.rotr
    i8, u8, i16, u16 emulated
    bool none
  • function abs<T>(value: T): T
    +
    Computes the absolute value of an integer or float.
    T Instruction
    f32 f32.abs
    f64 f64.abs
    i8, i16, i32, i64 emulated
    u8, u16, u32, u64, bool none
  • function max<T>(left: T, right: T): T
    +
    Determines the maximum of two integers or floats. If either operand is NaN, returns NaN.
    T Instruction
    f32 f32.max
    f64 f64.max
    i8, u8, i16, u16, i32, u32, i64, u64, bool emulated
  • function min<T>(left: T, right: T): T
    +
    Determines the minimum of two integers or floats. If either operand is NaN, returns NaN.
    T Instruction
    f32 f32.min
    f64 f64.min
    i8, u8, i16, u16, i32, u32, i64, u64, bool emulated
  • function ceil<T>(value: T): T
    +
    Performs the ceiling operation on a 32-bit or 64-bit float.
    T Instruction
    f32 f32.ceil
    f64 f64.ceil
    i8, u8, i16, u16, i32, u32, i64, u64, bool none
  • function floor<T>(value: T): T
    +
    Performs the floor operation on a 32-bit or 64-bit float.
    T Instruction
    f32 f32.floor
    f64 f64.floor
    i8, u8, i16, u16, i32, u32, i64, u64, bool none
  • function copysign<T>(x: T , y: T): T
    +
    Composes a 32-bit or 64-bit float from the magnitude of x and the sign of y.
    T Instruction
    f32 f32.copysign
    f64 f64.copysign
  • function nearest<T>(value: T): T
    +
    Rounds to the nearest integer half to even of a 32-bit or 64-bit float.
    T Instruction
    f32 f32.nearest
    f64 f64.nearest
    i8, u8, i16, u16, i32, u32, i64, u64, bool none
  • function reinterpret<TTo>(value: auto): TTo
    +
    Reinterprets the bits of the specified value as type T.
    TTo Instruction
    i32, u32 i32.reinterpret_f32
    i64, u64 i64.reinterpret_f64
    f32 f32.reinterpret_i32
    f64 f64.reinterpret_i64
  • function sqrt<T>(value: T): T
    +
    Calculates the square root of a 32-bit or 64-bit float.
    T Instruction
    f32 f32.sqrt
    f64 f64.sqrt
  • function trunc<T>(value: T): T
    +
    Rounds to the nearest integer towards zero of a 32-bit or 64-bit float.
    T Instruction
    f32 f32.trunc
    f64 f64.trunc
    i8, u8, i16, u16, i32, u32, i64, u64, bool none

# Memory

Similarly, the following built-ins emit WebAssembly instructions accessing or otherwise modifying memory.

NOTE

The immOffset and immAlign arguments, if provided, must be compile time constant values. See more details in rationale (opens new window).

  • function load<T>(ptr: usize, immOffset?: usize, immAlign?: usize): T
    +
    Loads a value of the specified type from memory. Equivalent to dereferencing a pointer in other languages.
    T Instruction If contextual type is i64
    i8 i32.load8_s i64.load8_s
    u8 i32.load8_u i64.load8_u
    i16 i32.load16_s i64.load16_s
    u16 i32.load16_u i64.load16_u
    i32 i32.load i64.load32_s
    u32 i32.load i64.load32_u
    i64, u64 i64.load n/a
    f32 f32.load n/a
    f64 f64.load n/a
    <ref> i32/i64.load n/a
  • function store<T>(ptr: usize, value: auto, immOffset?: usize, immAlign?: usize): void
    +
    Stores a value of the specified type to memory. Equivalent to dereferencing a pointer in other languages and assigning a value.
    T Instruction If value is i64
    i8, u8 i32.store8 i64.store8
    i16, u16 i32.store16 i64.store16
    i32, u32 i32.store i64.store32
    i64, u64 i64.store n/a
    f32 f32.store n/a
    f64 f64.store n/a
    <ref> i32/i64.store n/a
  • function memory.size(): i32
    +

    Returns the current size of the memory in units of pages. One page is 64kb.

  • function memory.grow(value: i32): i32
    +

    Grows linear memory by a given unsigned delta of pages. One page is 64kb. Returns the previous size of the memory in units of pages or -1 on failure.

    WARNING

    Calling memory.grow where a memory manager is present might break it.

  • function memory.copy(dst: usize, src: usize, n: usize): void
    +

    Copies n bytes from src to dst . Regions may overlap. Emits the respective instruction if bulk-memory is enabled, otherwise ships a polyfill.

  • function memory.fill(dst: usize, value: u8, n: usize): void
    +

    Fills n bytes at dst with the given byte value. Emits the respective instruction if bulk-memory is enabled, otherwise ships a polyfill.

  • function memory.repeat(dst: usize, src: usize, srcLength: usize, count: usize): void
    +

    Repeats a sequence of bytes given as src with srcLength count times into destination dst.

  • function memory.compare(lhs: usize, rhs: usize, n: usize): i32
    +

    Compares the first n bytes of left and right and returns a value that indicates their relationship:

    • Negative value if the first differing byte in lhs is less than the corresponding byte in rhs.
    • Positive value if the first differing byte in lhs is greater than the corresponding byte in rhs.
    • Zero​ if all n bytes of lhs and rhs are equal.
  • function memory.data(size: i32, align?: i32): usize
    +

    Gets a pointer to a zeroed static chunk of memory of the given size. Alignment defaults to 16. Arguments must be compile-time constants.

  • function memory.data<T>(values: T[], align?: i32): usize
    +

    Gets a pointer to a pre-initialized static chunk of memory. Alignment defaults to the size of T. Arguments must be compile-time constants.

# Control flow

  • function select<T>(ifTrue: T, ifFalse: T, condition: bool): T
    +

    Selects one of two pre-evaluated values depending on the condition. Differs from an if/else in that both arms are always executed and the final value is picked based on the condition afterwards. Performs better than an if/else only if the condition is random (means: branch prediction is not going to perform well) and both alternatives are cheap. It is also worth to note that Binaryen will do relevant optimizations like switching to a select automatically, so simply using a ternary ? : may be preferable.

  • function unreachable(): auto
    +

    Emits an unreachable instruction that results in a runtime error (trap) when executed. Both a statement and an expression of any type. Beware that trapping in managed code will most likely lead to memory leaks or even break the program because it ends execution prematurely.

# Atomics 🦄

The following instructions represent the WebAssembly threads and atomics (opens new window) specification. Must be enabled with --enable threads.

  • function atomic.load<T>(ptr: usize, immOffset?: usize): T
    +

    Atomically loads an integer value from memory and returns it.

  • function atomic.store<T>(ptr: usize, value: auto, immOffset?: usize): void
    +

    Atomically stores an integer value to memory.

  • function atomic.add<T>(ptr: usize, value: T, immOffset?: usize): T
    +

    Atomically adds an integer value in memory.

  • function atomic.sub<T>(ptr: usize, value: T, immOffset?: usize): T
    +

    Atomically subtracts an integer value in memory.

  • function atomic.and<T>(ptr: usize, value: T, immOffset?: usize): T
    +

    Atomically performs a bitwise AND operation on an integer value in memory.

  • function atomic.or<T>(ptr: usize, value: T, immOffset?: usize): T
    +

    Atomically performs a bitwise OR operation on an integer value in memory.

  • function atomic.xor<T>(ptr: usize, value: T, immOffset?: usize): T
    +

    Atomically performs a bitwise XOR operation on an integer value in memory.

  • function atomic.xchg<T>(ptr: usize, value: T, immOffset?: usize): T
    +

    Atomically exchanges an integer value in memory.

  • function atomic.cmpxchg<T>(ptr: usize, expected: T, replacement: T, immOffset?: usize): T
    +

    Atomically compares and exchanges an integer value in memory if the condition is met.

  • function atomic.wait<T>(ptr: usize, expected: T, timeout: i64): AtomicWaitResult
    +

    Performs a wait operation on an address in memory, suspending this agent if the integer condition is met. Return values are

    Value Description
    0 OK - Woken by another agent.
    1 NOT_EQUAL - Loaded value did not match the expected value.
    2 TIMED_OUT - Not woken before the timeout expired.
  • function atomic.notify(ptr: usize, count: i32): i32
    +

    Performs a notify operation on an address in memory waking up suspended agents.

  • function atomic.fence(): void
    +

    Performs a fence operation, preserving synchronization guarantees of higher level languages.

# SIMD 🦄

Likewise, these represent the WebAssembly SIMD (opens new window) specification. Must be enabled with --enable simd.

  • function v128(a: i8, ... , p: i8): v128
    +

    Initializes a 128-bit vector from sixteen 8-bit integer values. Arguments must be compile-time constants.

    See Constructing constant vectors for additional type-specific options.

  • function v128.splat<T>(x: T): v128
    +
    Creates a vector with identical lanes.
    T Instruction
    i8, u8 i8x16.splat
    i16, u16 i16x8.splat
    i32, u32 i32x4.splat
    i64, u64 i64x2.splat
    f32 f32x4.splat
    f64 f64x2.splat
  • function v128.extract_lane<T>(x: v128, idx: u8): T
    +
    Extracts one lane as a scalar.
    T Instruction
    i8 i8x16.extract_lane_s
    u8 i8x16.extract_lane_u
    i16 i16x8.extract_lane_s
    u16 i16x8.extract_lane_u
    i32, u32 i32x4.extract_lane
    i64, u64 i64x2.extract_lane
    f32 f32x4.extract_lane
    f64 f64x2.extract_lane
  • function v128.replace_lane<T>(x: v128, idx: u8, value: T): v128
    +
    Replaces one lane.
    T Instruction
    i8, u8 i8x16.replace_lane
    i16, u16 i16x8.replace_lane
    i32, u32 i32x4.replace_lane
    i64, u64 i64x2.replace_lane
    f32 f32x4.replace_lane
    f64 f64x2.replace_lane
  • function v128.shuffle<T>(a: v128, b: v128, ...lanes: u8[]): v128
    +
    Selects lanes from either vector according to the specified lane indexes.
    T Instruction
    i8, u8 i8x16.shuffle
    i16, u16 i8x16.shuffle emulating i16x8.shuffle
    i32, u32 i8x16.shuffle emulating i32x4.shuffle
    i64, u64 i8x16.shuffle emulating i64x2.shuffle
    f32 i8x16.shuffle emulating f32x4.shuffle
    f64 i8x16.shuffle emulating f64x2.shuffle
  • function v128.swizzle(a: v128, s: v128): v128
    +

    Selects 8-bit lanes from the first vector according to the indexes [0-15] specified by the 8-bit lanes of the second vector.

  • function v128.load(ptr: usize, immOffset?: usize, immAlign?: usize): v128
    +

    Loads a vector from memory.

  • function v128.load_ext<TFrom>(ptr: usize, immOffset?: usize, immAlign?: usize): v128
    +
    Creates a vector by loading the lanes of the specified integer type and extending each to the next larger type.
    TFrom Instruction
    i8 v128.load8x8_s
    u8 v128.load8x8_u
    i16 v128.load16x4_s
    u16 v128.load16x4_u
    i32 v128.load32x2_s
    u32 v128.load32x2_u
  • function v128.load_zero<TFrom>(ptr: usize, immOffset?: usize, immAlign?: usize): v128
    +
    Creates a vector by loading a value of the specified type into the lowest bits and initializing all other bits of the vector to zero.
    TFrom Instruction
    i32, u32, f32 v128.load32_zero
    i64, u64, f64 v128.load64_zero
  • function v128.load_lane<T>(
    +  ptr: usize, vec: v128, idx: u8, immOffset?: usize, immAlign?: usize
    +): v128
    +
    Loads a single lane from memory into the specified lane of the given vector. Other lanes are bypassed as is.
    T Instruction
    i8, u8 v128.load8_lane
    i16, u16 v128.load16_lane
    i32, u32, f32 v128.load32_lane
    i64, u64, f64 v128.load64_lane
  • function v128.store_lane<T>(
    +  ptr: usize, vec: v128, idx: u8, immOffset?: usize, immAlign?: usize
    +): v128
    +
    Stores the single lane at the specified index of the given vector to memory.
    T Instruction
    i8, u8 v128.store8_lane
    i16, u16 v128.store16_lane
    i32, u32, f32 v128.store32_lane
    i64, u64, f64 v128.store64_lane
  • function v128.load_splat<T>(ptr: usize, immOffset?: usize, immAlign?: usize): v128
    +
    Creates a vector with identical lanes by loading the splatted value.
    T Instruction
    i8, u8 v128.load8_splat
    i16, u16 v128.load16_splat
    i32, u32, f32 v128.load32_splat
    i64, u64, f64 v128.load64_splat
  • function v128.store(ptr: usize, value: v128, immOffset?: usize, immAlign?: usize): void
    +

    Stores a vector to memory.

  • function v128.add<T>(a: v128, b: v128): v128
    +
    Adds each lane.
    T Instruction
    i8, u8 i8x16.add
    i16, u16 i16x8.add
    i32, u32 i32x4.add
    i64, u64 i64x2.add
    f32 f32x4.add
    f64 f64x2.add
  • function v128.sub<T>(a: v128, b: v128): v128
    +
    Subtracts each lane.
    T Instruction
    i8, u8 i8x16.sub
    i16, u16 i16x8.sub
    i32, u32 i32x4.sub
    i64, u64 i64x2.sub
    f32 f32x4.sub
    f64 f64x2.sub
  • function v128.mul<T>(a: v128, b: v128): v128
    +
    Multiplies each lane.
    T Instruction
    i16, u16 i16x8.mul
    i32, u32 i32x4.mul
    i64, u64 i64x2.mul
    f32 f32x4.mul
    f64 f64x2.mul
  • function v128.div<T>(a: v128, b: v128): v128
    +
    Divides each floating point lane.
    T Instruction
    f32 f32x4.div
    f64 f64x2.div
  • function v128.neg<T>(a: v128): v128
    +
    Negates each lane.
    T Instruction
    i8, u8 i8x16.neg
    i16, u16 i16x8.neg
    i32, u32 i32x4.neg
    i64, u64 i64x2.neg
    f32 f32x4.neg
    f64 f64x2.neg
  • function v128.add_sat<T>(a: v128, b: v128): v128
    +
    Adds each signed small integer lane using saturation.
    T Instruction
    i8 i8x16.add_sat_s
    u8 i8x16.add_sat_u
    i16 i16x8.add_sat_s
    u16 i16x8.add_sat_u
  • function v128.sub_sat<T>(a: v128, b: v128): v128
    +
    Subtracts each signed small integer lane using saturation.
    T Instruction
    i8 i8x16.sub_sat_s
    u8 i8x16.sub_sat_u
    i16 i16x8.sub_sat_s
    u16 i16x8.sub_sat_u
  • function v128.shl<T>(a: v128, b: i32): v128
    +
    Performs a bitwise left shift by a scalar on each integer lane.
    T Instruction
    i8, u8 i8x16.shl
    i16, u16 i16x8.shl
    i32, u32 i32x4.shl
    i64, u64 i64x2.shl
  • function v128.shr<T>(a: v128, b: i32): v128
    +
    Performs a bitwise right shift by a scalar on each integer lane.
    T Instruction
    i8 i8x16.shr_s
    u8 i8x16.shr_u
    i16 i16x8.shr_s
    u16 i16x8.shr_u
    i32 i32x4.shr_s
    u32 i32x4.shr_u
    i64 i64x2.shr_s
    u64 i64x2.shr_u
  • function v128.and(a: v128, b: v128): v128
    +

    Performs the bitwise a & b operation on each lane.

  • function v128.or(a: v128, b: v128): v128
    +

    Performs the bitwise a | b operation on each lane.

  • function v128.xor(a: v128, b: v128): v128
    +

    Performs the bitwise a ^ b operation on each lane.

  • function v128.andnot(a: v128, b: v128): v128
    +

    Performs the bitwise a & !b operation on each lane.

  • function v128.not(a: v128): v128
    +

    Performs the bitwise !a operation on each lane.

  • function v128.bitselect(v1: v128, v2: v128, mask: v128): v128
    +

    Selects bits of either vector according to the specified mask. Selects from v1 if the bit in mask is 1, otherwise from v2.

  • function v128.any_true(a: v128): bool
    +

    Reduces a vector to a scalar indicating whether any lane is considered true.

  • function v128.all_true<T>(a: v128): bool
    +
    Reduces a vector to a scalar indicating whether all lanes are considered true.
    T Instruction
    i8, u8 i8x16.all_true
    i16, u16 i16x8.all_true
    i32, u32 i32x4.all_true
    i64, u64 i64x2.all_true
  • function v128.bitmask<T>(a: v128): bool
    +
    Extracts the high bit of each integer lane (except 64-bit) and produces a scalar mask with all bits concatenated.
    T Instruction
    i8, u8 i8x16.bitmask
    i16, u16 i16x8.bitmask
    i32, u32 i32x4.bitmask
    i64, u64 i64x2.bitmask
  • function v128.popcnt<T>(a: v128): v128
    +
    Counts the number of bits set to one within each lane.
    T Instruction
    i8, u8 i8x16.popcnt
  • function v128.min<T>(a: v128, b: v128): v128
    +
    Computes the minimum of each lane.
    T Instruction
    i8 i8x16.min_s
    u8 i8x16.min_u
    i16 i16x8.min_s
    u16 i16x8.min_u
    i32 i32x4.min_s
    u32 i32x4.min_u
    f32 f32x4.min
    f64 f64x2.min
  • function v128.max<T>(a: v128, b: v128): v128
    +
    Computes the maximum of each lane.
    T Instruction
    i8 i8x16.max_s
    u8 i8x16.max_u
    i16 i16x8.max_s
    u16 i16x8.max_u
    i32 i32x4.max_s
    u32 i32x4.max_u
    f32 f32x4.max
    f64 f64x2.max
  • function v128.pmin<T>(a: v128, b: v128): v128
    +
    Computes the psuedo-minimum of each lane.
    T Instruction
    f32 f32x4.pmin
    f64 f64x2.pmin
  • function v128.pmax<T>(a: v128, b: v128): v128
    +
    Computes the pseudo-maximum of each lane.
    T Instruction
    f32 f32x4.pmax
    f64 f64x2.pmax
  • function v128.dot<T>(a: v128, b: v128): v128
    +
    Computes the dot product of two 16-bit integer lanes each, yielding lanes one size wider than the input.
    T Instruction
    i16 i32x4.dot_i16x8_s
  • function v128.avgr<T>(a: v128, b: v128): v128)
    +
    Computes the rounding average of each unsigned small integer lane.
    T Instruction
    u8 i8x16.avgr_u
    u16 i16x8.avgr_u
  • function v128.abs<T>(a: v128): v128
    +
    Computes the absolute value of each lane (except 64-bit integers).
    T Instruction
    i8, u8 i8x16.abs
    i16, u16 i16x8.abs
    i32, u32 i32x4.abs
    i64, u64 i64x2.abs
    f32 f32x4.abs
    f64 f64x2.abs
  • function v128.sqrt<T>(a: v128): v128
    +
    Computes the square root of each floating point lane.
    T Instruction
    f32 f32x4.sqrt
    f64 f64x2.sqrt
  • function v128.ceil<T>(a: v128): v128
    +
    Performs the ceiling operation on each lane.
    T Instruction
    f32 f32x4.ceil
    f64 f64x2.ceil
  • function v128.floor<T>(a: v128): v128
    +
    Performs the floor operation on each lane.
    T Instruction
    f32 f32x4.floor
    f64 f64x2.floor
  • function v128.trunc<T>(a: v128): v128
    +
    Rounds to the nearest integer towards zero of each lane.
    T Instruction
    f32 f32x4.trunc
    f64 f64x2.trunc
  • function v128.nearest<T>(a: v128): v128
    +
    Rounds to the nearest integer half to even of each lane.
    T Instruction
    f32 f32x4.nearest
    f64 f64x2.nearest
  • function v128.eq<T>(a: v128, b: v128): v128
    +
    Computes which lanes are equal.
    T Instruction
    i8, u8 i8x16.eq
    i16, u16 i16x8.eq
    i32, u32 i32x4.eq
    i64, u64 i64x2.eq
    f32 f32x4.eq
    f64 f64x2.eq
  • function v128.ne<T>(a: v128, b: v128): v128
    +
    Computes which lanes are not equal.
    T Instruction
    i8, u8 i8x16.ne
    i16, u16 i16x8.ne
    i32, u32 i32x4.ne
    i64, u64 i64x2.ne
    f32 f32x4.ne
    f64 f64x2.ne
  • function v128.lt<T>(a: v128, b: v128): v128
    +
    Computes which lanes of the first vector are less than those of the second.
    T Instruction
    i8 i8x16.lt_s
    u8 i8x16.lt_u
    i16 i16x8.lt_s
    u16 i16x8.lt_u
    i32 i32x4.lt_s
    u32 i32x4.lt_u
    i64 i64x2.lt_s
    f32 f32x4.lt
    f64 f64x2.lt
  • function v128.le<T>(a: v128, b: v128): v128
    +
    Computes which lanes of the first vector are less than or equal those of the second.
    T Instruction
    i8 i8x16.le_s
    u8 i8x16.le_u
    i16 i16x8.le_s
    u16 i16x8.le_u
    i32 i32x4.le_s
    u32 i32x4.le_u
    i64 i64x2.le_s
    f32 f32x4.le
    f64 f64x2.le
  • function v128.gt<T>(a: v128, b: v128): v128
    +
    Computes which lanes of the first vector are greater than those of the second.
    T Instruction
    i8 i8x16.gt_s
    u8 i8x16.gt_u
    i16 i16x8.gt_s
    u16 i16x8.gt_u
    i32 i32x4.gt_s
    u32 i32x4.gt_u
    i64 i64x2.gt_s
    f32 f32x4.gt
    f64 f64x2.gt
  • function v128.ge<T>(a: v128, b: v128): v128
    +
    Computes which lanes of the first vector are greater than or equal those of the second.
    T Instruction
    i8 i8x16.ge_s
    u8 i8x16.ge_u
    i16 i16x8.ge_s
    u16 i16x8.ge_u
    i32 i32x4.ge_s
    u32 i32x4.ge_u
    i64 i64x2.ge_s
    f32 f32x4.ge
    f64 f64x2.ge
  • function v128.convert<TFrom>(a: v128): v128
    +
    Converts each lane of a vector from integer to single-precision floating point.
    TFrom Instruction
    i32 f32x4.convert_i32x4_s
    u32 f32x4.convert_i32x4_u
  • function v128.convert_low<TFrom>(a: v128): v128
    +
    Converts the low lanes of a vector from integer to double-precision floating point.
    TFrom Instruction
    i32 f64x2.convert_low_i32x4_s
    u32 f64x2.convert_low_i32x4_u
  • function v128.trunc_sat<TTo>(a: v128): v128
    +
    Truncates each lane of a vector from single-precision floating point to integer with saturation. Takes the target type.
    TTo Instruction
    i32 i32x4.trunc_sat_f32x4_s
    u32 i32x4.trunc_sat_f32x4_u
  • function v128.trunc_sat_zero<TTo>(a: v128): v128
    +
    Truncates each lane of a vector from double-precision floating point to integer with saturation. Takes the target type.
    TTo Instruction
    i32 i32x4.trunc_sat_f64x2_s_zero
    u32 i32x4.trunc_sat_f64x2_u_zero
  • function v128.narrow<TFrom>(a: v128, b: v128): v128
    +
    Narrows wider integer lanes to their respective narrower lanes.
    TFrom Instruction
    i16 i8x16.narrow_i16x8_s
    u16 i8x16.narrow_i16x8_u
    i32 i16x8.narrow_i32x4_s
    u32 i16x8.narrow_i32x4_u
  • function v128.extend_low<TFrom>(a: v128): v128
    +
    Extends the low half of narrower integer lanes to their respective wider lanes.
    TFrom Instruction
    i8 i16x8.extend_low_i8x16_s
    u8 i16x8.extend_low_i8x16_u
    i16 i32x4.extend_low_i16x8_s
    u16 i32x4.extend_low_i16x8_u
    i32 i64x2.extend_low_i32x4_s
    u32 i64x2.extend_low_i32x4_u
  • function v128.extend_high<TFrom>(a: v128): v128
    +
    Extends the high half of narrower integer lanes to their respective wider lanes.
    TFrom Instruction
    i8 i16x8.extend_high_i8x16_s
    u8 i16x8.extend_high_i8x16_u
    i16 i32x4.extend_high_i16x8_s
    u16 i32x4.extend_high_i16x8_u
    i32 i64x2.extend_high_i32x4_s
    u32 i64x2.extend_high_i32x4_u
  • function v128.extadd_pairwise<TFrom>(a: v128): v128
    +
    Adds lanes pairwise producing twice wider extended results.
    TFrom Instruction
    i16 i16x8.extadd_pairwise_i8x16_s
    u16 i16x8.extadd_pairwise_i8x16_u
    i32 i32x4.extadd_pairwise_i16x8_s
    u32 i32x4.extadd_pairwise_i16x8_u
  • function v128.demote_zero<T>(a: v128): v128
    +
    Demotes each float lane to lower precision. The higher lanes of the result are initialized to zero.
    T Instruction
    f64 f32x4.demote_f64x2_zero
  • function v128.promote_low<T>(a: v128): v128
    +
    Promotes the lower float lanes to higher precision.
    T Instruction
    f32 f64x2.promote_low_f32x4
  • function v128.q15mulr_sat<T>(a: v128, b: v128): v128
    +
    Performs the line-wise saturating rounding multiplication in Q15 format ((a[i] * b[i] + (1 << (Q - 1))) >> Q where Q=15).
    T Instruction
    i16 i16x8.q15mulr_sat_s
  • function v128.extmul_low<T>(a: v128, b: v128): v128
    +
    Performs the lane-wise integer extended multiplication of the lower lanes producing a twice wider result than the inputs.
    T Instruction
    i8 i16x8.extmul_low_i8x16_s
    u8 i16x8.extmul_low_i8x16_u
    i16 i32x4.extmul_low_i16x8_s
    u16 i32x4.extmul_low_i16x8_u
    i32 i64x2.extmul_low_i32x4_s
    u32 i64x2.extmul_low_i32x4_u
  • function v128.extmul_high<T>(a: v128, b: v128): v128
    +
    Performs the lane-wise integer extended multiplication of the higher lanes producing a twice wider result than the inputs.
    T Instruction
    i8 i16x8.extmul_high_i8x16_s
    u8 i16x8.extmul_high_i8x16_u
    i16 i32x4.extmul_high_i16x8_s
    u16 i32x4.extmul_high_i16x8_u
    i32 i64x2.extmul_high_i32x4_s
    u32 i64x2.extmul_high_i32x4_u

# Constructing constant vectors

  • function i8x16(a: i8, ... , p: i8): v128
    +

    Initializes a 128-bit vector from sixteen 8-bit integer values.

  • function i16x8(a: i16, ..., h: i16): v128
    +

    Initializes a 128-bit vector from eight 16-bit integer values.

  • function i32x4(a: i32, b: i32, c: i32, d: i32): v128
    +

    Initializes a 128-bit vector from four 32-bit integer values.

  • function i64x2(a: i64, b: i64): v128
    +

    Initializes a 128-bit vector from two 64-bit integer values.

  • function f32x4(a: f32, b: f32, c: f32, d: f32): v128
    +

    Initializes a 128-bit vector from four 32-bit float values.

  • function f64x2(a: f64, b: f64): v128
    +

    Initializes a 128-bit vector from two 64-bit float values.

# Relaxed SIMD 🦄

The following instructions represent the WebAssembly Relaxed SIMD (opens new window) specification. Must be enabled with --enable relaxed-simd.

  • function v128.relaxed_swizzle(a: v128, s: v128): v128
    +

    Selects 8-bit lanes from a using indices in s. Indices in the range [0-15] select the i-th element of a.

    Unlike v128.swizzle, the result of an out of bounds index is implementation-defined, depending on hardware capabilities: Either 0 or a[s[i]%16].

  • function v128.relaxed_trunc<T>(a: v128): v128
    +
    Truncates each lane of a vector from 32-bit floating point to a 32-bit signed or unsigned integer as indicated by T.
    T Instruction
    i32 i32x4.relaxed_trunc_f32x4_s
    u32 i32x4.relaxed_trunc_f32x4_u

    Unlike v128.trunc_sat, the result of lanes out of bounds of the target type is implementation defined, depending on hardware capabilities:

    • If the input lane contains NaN, the result is either 0 or the respective maximum integer value.
    • If the input lane contains a value otherwise out of bounds of the target type, the result is either the saturatated result or maximum integer value.
  • function v128.relaxed_trunc_zero<T>(a: v128): v128
    +
    Truncates each lane of a vector from 64-bit floating point to a 32-bit signed or unsigned integer as indicated by T. Unused higher integer lanes of the result are initialized to zero.
    T Instruction
    i32 i32x4.relaxed_trunc_f64x2_s_zero
    u32 i32x4.relaxed_trunc_f64x2_u_zero

    Unlike v128.trunc_sat_zero, the result of lanes out of bounds of the target type is implementation defined, depending on hardware capabilities:

    • If the input lane contains NaN, the result is either 0 or the respective maximum integer value.
    • If the input lane contains a value otherwise out of bounds of the target type, the result is either the saturatated result or maximum integer value.
  • function v128.relaxed_madd<T>(a: v128, b: v128, c: v128): v128
    +
    Performs the fused multiply-add operation (a * b + c) on 32- or 64-bit floating point lanes as indicated by T.
    T Instruction
    f32 f32x4.relaxed_madd
    f64 f64x2.relaxed_madd

    The result is implementation defined, depending on hardware capabilities:

    • Either a * b is rounded once and the final result rounded again, or
    • The expression is evaluated with higher precision and only rounded once
  • function v128.relaxed_nmadd<T>(a: v128, b: v128, c: v128): v128
    +
    Performs the fused negative multiply-add operation (-(a * b) + c) on 32- or 64-bit floating point lanes as indicated by T.
    T Instruction
    f32 f32x4.relaxed_nmadd
    f64 f64x2.relaxed_nmadd

    The result is implementation defined, depending on hardware capabilities:

    • Either a * b is rounded once and the final result rounded again, or
    • The expression is evaluated with higher precision and only rounded once
  • function v128.relaxed_laneselect<T>(a: v128, b: v128, m: v128): v128
    +
    Selects 8-, 16-, 32- or 64-bit integer lanes as indicated by T from a or b based on masks in m.
    T Instruction
    i8, u8 i8x16.relaxed_laneselect
    i16, u16 i16x8.relaxed_laneselect
    i32, u32 i32x4.relaxed_laneselect
    i64, u64 i64x2.relaxed_laneselect

    Behaves like v128.bitselect if masks in m do have all bits either set (result is a[i]) or unset (result is b[i]). Otherwise the result is implementation-defined, depending on hardware capabilities: If the most significant bit of m is set, the result is either bitselect(a[i], b[i], mask) or a[i], otherwise the result is b[i].

  • function v128.relaxed_min<T>(a: v128, b: v128): v128
    +
    Computes the minimum of each 32- or 64-bit floating point lane as indicated by T.
    T Instruction
    f32 f32x4.relaxed_min
    f64 f64x2.relaxed_min

    Unlike v128.min, the result is implementation-defined if either value is NaN or both are -0.0 and +0.0, depending on hardware capabilities: Either a[i] or b[i].

  • function v128.relaxed_max<T>(a: v128, b: v128): v128
    +
    Computes the maximum of each 32- or 64-bit floating point lane as indicated by T.
    T Instruction
    f32 f32x4.relaxed_max
    f64 f64x2.relaxed_max

    Unlike v128.max, the result is implementation-defined if either value is NaN or both are -0.0 and +0.0, depending on hardware capabilities: Either a[i] or b[i].

  • function v128.relaxed_q15mulr<T>(a: v128, b: v128): v128
    +
    Performs the lane-wise rounding multiplication in Q15 format ((a[i] * b[i] + (1 << (Q - 1))) >> Q where Q=15).
    T Instruction
    i16 i16x8.relaxed_q15mulr_s

    Unlike v128.q15mulr_sat, the result is implementation-defined if both inputs are the minimum signed value: Either the minimum or maximum signed value.

  • function v128.relaxed_dot<T>(a: v128, b: v128): v128
    +
    Computes the dot product of two 8-bit integer lanes each, yielding lanes one size wider than the input.
    T Instruction
    i16 i16x8.relaxed_dot_i8x16_i7x16_s

    Unlike v128.dot, if the most significant bit of b[i] is set, whether b[i] is interpreted as signed or unsigned by the intermediate multiplication is implementation-defined.

  • function v128.relaxed_dot_add<T>(a: v128, b: v128, c: v128): v128
    +
    Computes the dot product of two 8-bit integer lanes each, yielding lanes two sizes wider than the input with the lanes of c accumulated into the result.
    T Instruction
    i32 i32x4.relaxed_dot_i8x16_i7x16_add_s

    Unlike v128.dot, if the most significant bit of b[i] is set, whether b[i] is interpreted as signed or unsigned by the intermediate multiplication is implementation-defined.

# Inline instructions

In addition to using the generic builtins above, most WebAssembly instructions can be written directly in AssemblyScript code. For example, the following is equivalent:

// generic builtin
+v128.splat<i32>(42);
+
+// inline instruction
+i32x4.splat(42);
+
+ + + diff --git a/stdlib/heap.html b/stdlib/heap.html new file mode 100644 index 000000000..de80cb20a --- /dev/null +++ b/stdlib/heap.html @@ -0,0 +1,89 @@ + + + + + + heap | The AssemblyScript Book + + + + + + + + + + + + + + + + + + +

# heap

An unsafe interface to use the dynamic memory manager directly, resembling malloc, realloc and free. Manual memory management can be used in parallel to garbage collection, which can be quite handy, but manually managed blocks cannot be mixed with garbage collected objects (i.e. trying to heap.free a GC object or casting a block to a managed object respectively would break since one has a GC header and the other does not).

# Static members

  • function heap.alloc(size: usize): usize
    +

    Allocates a chunk of memory of at least the specified size.

  • function heap.realloc(ptr: usize, size: usize): usize
    +

    Reallocates a chunk of memory to have at least the specified size.

  • function heap.free(ptr: usize): void
    +

    Frees a chunk of memory.

  • function heap.reset(): void
    +

    Dangerously resets the entire heap. Specific to the "stub" runtime.

+ + + diff --git a/stdlib/map.html b/stdlib/map.html new file mode 100644 index 000000000..ccaa355b1 --- /dev/null +++ b/stdlib/map.html @@ -0,0 +1,102 @@ + + + + + + Map | The AssemblyScript Book + + + + + + + + + + + + + + + + + + +

# Map

A mapping of generic keys to generic values.

The Map API is very similar to JavaScript's (MDN (opens new window)), with the notable difference that a .get with a key that does not exist results in an error, because undefined cannot be represented. Example:

var map = new Map<i32,string>()
+
+// Because `undefined` cannot be represented if a key is not found, this will error:
+var str = map.get(1) // ERROR
+
+// The error can be avoided by first making sure that the key exists, so this works:
+var str: string | null = map.has(1) ? map.get(1) : null // OK
+

# Constructor

  • new Map<K,V>()
    +
    Constructs a new map mapping keys of type K to values of type V.

# Instance members

# Fields

  • readonly size: i32
    +
    The current number of key-value pairs in this map.

# Methods

  • function clear(): void
    +

    Clears the map, deleting all key-value pairs.

  • function delete(key: K): bool
    +

    Deletes the key-value pair for the corresponding key. Returns true if the key did exist, otherwise false.

  • function get(key: K): V
    +

    Gets the value corresponding to the specified key. Traps if the key does not exist because "not found" cannot be represented in all cases (use Map#has to check).

  • function has(key: K): bool
    +

    Tests if the specified key exists.

  • function keys(): Array<K>
    +

    Gets the keys contained in this map as an array, in insertion order. This is preliminary while iterators are not supported.

  • function set(key: K, value: V): this
    +

    Sets the value for the specified key. Creates a new key-value pair if the key did not exist.

  • function values(): Array<V>
    +

    Gets the values contained in this map as an array, in insertion order. This is preliminary while iterators are not supported.

  • function toString(): string
    +

    Returns a string representation of this map.

+ + + diff --git a/stdlib/math.html b/stdlib/math.html new file mode 100644 index 000000000..e2664d9af --- /dev/null +++ b/stdlib/math.html @@ -0,0 +1,130 @@ + + + + + + Math | The AssemblyScript Book + + + + + + + + + + + + + + + + + + +

# Math

Mathematical operations as known from JavaScript.

The Math API is very much like JavaScript's (MDN (opens new window)), with the notable exceptions stated above and rest parameters not being supported yet.

# Variants

Math in AssemblyScript is available in multiple variants.

Variant Description
NativeMath WebAssembly implementation for f64
NativeMathf WebAssembly implementation for f32
JSMath JavaScript implementation for f64 (imported from the host)

By default, the global Math object is an alias of NativeMath and Mathf is an alias of NativeMathf .

# Using JSMath

By default, the compiler utilizes NativeMath which is implemented in WebAssembly directly, but where small module size is more important than performance, one can opt to override the default by adding --use Math=JSMath on the command line, essentially aliasing Math with JSMath instead, which maps to an import of the browser's math implementation. Naturally, this option requires importing the browser's Math object as a whole, but does not require seeding / is not seedable. Generated bindings automatically take care of importing the browser's math in this scenario.

# Static members

The type T below substitutes either f32 or f64 depending on the implementation used. Note that Math is not actually generic, but concrete implementations like Math and Mathf have an identical interface that only differs in the implementation's floating-point precision denoted by T.

# Constants

  • const E: T
    +

    The base of natural logarithms, e, approximately 2.718.

  • const LN2: T
    +

    The natural logarithm of 2, approximately 0.693.

  • const LN10: T
    +

    The natural logarithm of 10, approximately 2.302.

  • const LOG2E: T
    +

    The base 2 logarithm of e, approximately 1.442.

  • const LOG10E: T
    +

    The base 10 logarithm of e, approximately 0.434.

  • const PI: T
    +

    The ratio of the circumference of a circle to its diameter, approximately 3.14159.

  • const SQRT1_2: T
    +

    The square root of 1/2, approximately 0.707.

  • const SQRT2: T
    +

    The square root of 2, approximately 1.414.

# Functions

  • function abs(x: T): T
    +

    Returns the absolute value of x.

  • function acos(x: T): T
    +

    Returns the arccosine (in radians) of x.

  • function acosh(x: T): T
    +

    Returns the hyperbolic arc-cosine of x.

  • function asin(x: T): T
    +

    Returns the arcsine (in radians) of x.

  • function asinh(x: T): T
    +

    Returns the hyperbolic arcsine of x.

  • function atan(x: T): T
    +

    Returns the arctangent (in radians) of x.

  • function atan2(y: T, x: T): T
    +

    Returns the arctangent of the quotient of its arguments.

  • function atanh(x: T): T
    +

    Returns the hyperbolic arctangent of x.

  • function cbrt(x: T): T
    +

    Returns the cube root of x.

  • function ceil(x: T): T
    +

    Returns the smallest integer greater than or equal to x.

  • function clz32(x: T): T
    +

    Returns the number of leading zero bits in the 32-bit binary representation of x.

  • function cos(x: T): T
    +

    Returns the cosine (in radians) of x.

  • function cosh(x: T): T
    +

    Returns the hyperbolic cosine of x.

  • function exp(x: T): T
    +

    Returns e to the power of x.

  • function expm1(x: T): T
    +

    Returns e to the power of x, minus 1.

  • function floor(x: T): T
    +

    Returns the largest integer less than or equal to x.

  • function fround(x: T): T
    +

    Returns the nearest 32-bit single precision float representation of x.

  • function hypot(value1: T, value2: T): T
    +

    Returns the square root of the sum of squares of its arguments.

  • function imul(a: T, b: T): T
    +

    Returns the result of the C-like 32-bit multiplication of a and b.

  • function log(x: T): T
    +

    Returns the natural logarithm (base e) of x.

  • function log10(x: T): T
    +

    Returns the base 10 logarithm of x.

  • function log1p(x: T): T
    +

    Returns the natural logarithm (base e) of 1 + x.

  • function log2(x: T): T
    +

    Returns the base 2 logarithm of x.

  • function max(value1: T, value2: T): T
    +

    Returns the largest-valued number of its arguments.

  • function min(value1: T, value2: T): T
    +

    Returns the lowest-valued number of its arguments.

  • function pow(base: T, exponent: T): T
    +

    Returns base to the power of exponent.

  • function random(): T
    +

    Returns a pseudo-random number in the range from 0.0 inclusive up to but not including 1.0.

    Note that Math.random needs a way to seed the random number generator, which is achieved with a special import env.seed returning the seed as an f64 value. Generated bindings and WASI take care of it automatically.

  • function round(x: T): T
    +

    Returns the value of x rounded to the nearest integer.

  • function seedRandom(value: i64): void
    +

    Seeds the random function. Called internally by random if the seed hasn't been set.

  • function sign(x: T): T
    +

    Returns the sign of x, indicating whether the number is positive, negative or zero.

  • function signbit(x: T): bool
    +

    Returns whether the sign bit of x is set.

  • function sin(x: T): T
    +

    Returns the sine of x.

  • function sinh(x: T): T
    +

    Returns the hyperbolic sine of x.

  • function sqrt(x: T): T
    +

    Returns the square root of x.

  • function tan(x: T): T
    +

    Returns the tangent of x.

  • function tanh(x: T): T
    +

    Returns the hyperbolic tangent of x.

  • function trunc(x: T): T
    +

    Returns the integer part of x by removing any fractional digits.

# Considerations

The Math implementations are meant as a drop-in replacement for JavaScript's Math with all its quirks. For example, Math.round always rounds towards +Infinity and Math.imul and similar functions operate on number, which is f64 in AssemblyScript. Hence, using WebAssembly's math instructions directly where possible is often more efficient.

+ + + diff --git a/stdlib/number.html b/stdlib/number.html new file mode 100644 index 000000000..6368e7d25 --- /dev/null +++ b/stdlib/number.html @@ -0,0 +1,104 @@ + + + + + + Number | The AssemblyScript Book + + + + + + + + + + + + + + + + + + +

# Number

Wrappers for basic numerical values.

The Number object has been split into one class per basic WebAssembly type as well. Unlike in JavaScript, these classes cannot have actual instances, hence it works a bit different than JavaScript's (MDN (opens new window)).

# Integers

The name Number below stands for one of the wrappers I8, I16, I32, I64, U8, U16, U32 or U64 representing their respective basic integer type T.

# Static members

  • const MIN_VALUE: T
    +

    The smallest representable value of the respective basic type. Differs from floating point values where it is the smallest representable positive value.

  • const MAX_VALUE: T
    +

    The largest representable value of the respective basic type.

  • function parseInt(value: string, radix?: i32): T
    +

    Parses a string to a value of the respective basic type.

# Instance members

  • function toString(radix?: i32): string
    +
    Returns the respective basic value converted to a string.

# Floats

The name Number below stands for one of the wrappers F32 or F64 representing their respective basic floating point type T.

# Static members

  • const EPSILON: T
    +

    The difference between 1.0 and the smallest number larger than 1.0.

  • const MAX_VALUE: T
    +

    The largest representable positive value by the respective basic type.

  • const MIN_VALUE: T
    +

    The smallest representable positive value by the respective basic type.

  • const MAX_SAFE_INTEGER: T
    +

    The largest safe integer representable by the respective basic type.

  • const MIN_SAFE_INTEGER: T
    +

    The smallest safe integer representable by the respective basic type.

  • const POSITIVE_INFINITY: T
    +

    Positive infinity of the respective basic type.

  • const NEGATIVE_INFINITY: T
    +

    Negative infinity of the respective basic type.

  • const NaN: T
    +

    NaN (Not A Number) of the respective basic type.

  • function isNaN(value: T): bool
    +

    Tests if the value is NaN.

  • function isFinite(value: T): bool
    +

    Tests if the value is finite, that is not NaN , POSITIVE_INFINITY or NEGATIVE_INFINITY.

  • function isInteger(value: T): bool
    +

    Tests if the value is an integer.

  • function isSafeInteger(value: T): bool
    +

    Tests if the value is a safe integer.

  • function parseInt(value: string, radix?: i32): T
    +

    Parses a string to an integer value of the respective basic type.

  • function parseFloat(value: string): T
    +

    Parses a string to a float value of the respective basic type.

# Instance members

  • function toString(radix?: i32): string
    +
    Returns the respective basic value converted to a string. The radix parameter is currently ignored here.
+ + + diff --git a/stdlib/process.html b/stdlib/process.html new file mode 100644 index 000000000..57571fa06 --- /dev/null +++ b/stdlib/process.html @@ -0,0 +1,96 @@ + + + + + + process | The AssemblyScript Book + + + + + + + + + + + + + + + + + + +

# process

An implementation of a Node.js-like process global.

# Static members

  • const arch: string
    +

    String representing the CPU architecture for which the binary was compiled. Either wasm32 or wasm64.

  • const platform: string
    +

    String representing the operating system platform for which the binary was compiled. Always wasm.

  • const argv: string[]
    +

    Array of command line arguments passed to the binary upon instantiation.

  • const env: Map<string,string>
    +

    Map of variables in the binary's user environment.

  • var exitCode: i32
    +

    Process exit code to use when the process exits gracefully. Defaults to 0.

  • function exit(code?: i32): void
    +

    Terminates the process with either the given exit code, or process.exitCode if omitted.

  • const stdin: ReadableStream
    +const stdout: WritableStream
    +const stderr: WritableStream
    +

    Streams connected to stdin (fd 0), stdout (fd 1) and stderr (fd 2) respectively.

  • function time(): i64
    +

    Obtains the system's current time of day, in milliseconds since Unix epoch.

  • function hrtime(): u64
    +

    Obtains the system's monotonic high resolution time, in nanoseconds since an arbitrary time in the past.

+ + + diff --git a/stdlib/set.html b/stdlib/set.html new file mode 100644 index 000000000..0ebcd159c --- /dev/null +++ b/stdlib/set.html @@ -0,0 +1,93 @@ + + + + + + Set | The AssemblyScript Book + + + + + + + + + + + + + + + + + + +

# Set

A set of unique generic values.

The Set API is very similar to JavaScript's (MDN (opens new window)), but iterators are not implemented yet.

# Constructor

  • new Set<T>()
    +
    Constructs a new set of unique value of type T.

# Instance members

# Fields

  • readonly size: i32
    +
    The current number of unique values in the set.

# Methods

  • function add(value: T): void
    +

    Adds the specified value to the set. Does nothing if the value already exists.

  • function delete(value: T): bool
    +

    Deletes the specified value. Returns true if the value was found, otherwise false.

  • function clear(): void
    +

    Clears the set, deleting all values.

  • function has(value: T): bool
    +

    Tests if the specified value exists in the set.

  • function values(): Array<T>
    +

    Gets the values contained in this set as an array, in insertion order. This is preliminary while iterators are not supported.

  • function toString(): string
    +

    Returns a string representation of this set.

+ + + diff --git a/stdlib/staticarray.html b/stdlib/staticarray.html new file mode 100644 index 000000000..7e2b8a7f3 --- /dev/null +++ b/stdlib/staticarray.html @@ -0,0 +1,117 @@ + + + + + + StaticArray | The AssemblyScript Book + + + + + + + + + + + + + + + + + + +

# StaticArray

A randomly accessible sequence of values of a generic type with a fixed length.

The StaticArray API is similar to the Array API, with the important difference that it has a fixed length that cannot change. Unlike a normal Array, a StaticArray does not have a separate backing buffer, so no level of indirection, and as such can have minimal overhead and performance characteristics very similar to arrays in C.

# Constructor

  • new StaticArray<T>(length: i32)
    +
    Constructs a new static array.

# Static members

  • function fromArray<T>(source: Array<T>): StaticArray<T>
    +

    Creates a static array from a normal array.

  • function concat<T>(source: StaticArray<T>, other: StaticArray<T>): StaticArray<T>
    +

    Deprecated! Like the instance member concat, but taking and returning a StaticArray.

    Instead of StaticArray.concat better to use parametric concat instance method.

  • function slice<T>(source: StaticArray<T>, start?: i32, end?: i32): StaticArray<T>
    +

    Deprecated! Like the instance member slice, but returning a StaticArray.

    Instead of StaticArray.slice better to use parametric slice instance method.

# Instance members

# Fields

  • readonly length: i32
    +
    The fixed length of this static array.

# Methods

  • function at(pos: i32): T
    +

    Gets the element at the specified position. This method allows for positive and negative integers. Negative integers count back from the last element.

  • function concat<U extends ArrayLike<T> = Array<T>>(other: U): U
    +

    Concatenates the values of this static and the other normal array to a new normal array, in this order. Patameter U accepts Array<T> or StaticArray<T> types.

  • function copyWithin(target: i32, start: i32, end?: i32): this
    +

    Copies a region of an array's values over the respective values starting at the target location.

  • function every(fn: (value: T, index: i32, self: StaticArray<T>) => bool): bool
    +

    Calls the specified function with every value of the array until it finds the first value for which the function returns false. Returns true if all functions returned true or the array is empty, otherwise false.

  • function fill(value: T, start?: i32, end?: i32): this
    +

    Replaces the values of the array from start inclusive to end exclusive in place with the specified value, returning the array.

  • function filter(fn: (value: T, index: i32, self: StaticArray<T>) => bool): Array<T>
    +

    Calls the specified function with every value of the array, returning a new array with all values for which the function returned true.

  • function findIndex(fn: (value: T, index: i32, self: StaticArray<T>) => bool): i32
    +

    Calls the specified function with every value of the array until it finds the first value for which the function returns true, returning its index. Returns -1 if that's never the case.

  • function findLastIndex(fn: (value: T, index: i32, self: StaticArray<T>) => bool): i32;
    +

    Calls the specified function with every value of the array starting at the end until it finds the first value for which the function returns true, returning its index. Returns -1 if that's never the case.

  • function forEach(fn: (value: T, index: i32, self: StaticArray<T>) => void): void
    +

    Calls the specified function with every value of the array.

  • function includes(value: T, fromIndex?: i32): bool
    +

    Tests if the array includes the specified value, optionally providing a starting index.

  • function indexOf(value: T, fromIndex?: i32): i32
    +

    Gets the first index where the specified value can be found in the array. Returns -1 if not found.

  • function join(separator?: string): string
    +

    Concatenates all values of the array to a string, separated by the specified separator (default: ,).

  • function lastIndexOf(value: T, fromIndex?: i32): i32
    +

    Gets the last index where the specified value can be found in the array. Returns -1 if not found.

  • function map<U>(fn: (value: T, index: i32, self: StaticArray<T>) => U): Array<U>
    +

    Calls the specified function with every value of the array, returning a new array of the function's return values.

  • function slice<U extends ArrayLike<T> = Array<T>>(start?: i32, end?: i32): U
    +

    Returns a shallow copy of this static array's values from begin inclusive to end exclusive, as a new normal array. If omitted, end defaults to the end of the array. Patameter U accepts Array<T> or StaticArray<T> types.

  • function some(fn: (value: T, index: i32, self: StaticArray<T>) => bool): bool
    +

    Calls the specified function with every value of the array until it finds the first value for which the function returns true, returning true. Returns false otherwise or if the array is empty.

  • function sort(fn?: (a: T, b: T) => i32): this
    +

    Sorts the values of the array in place, using the specified comparator function, modifying the array before returning it. The comparator returning a negative value means a < b, a positive value means a > b and 0 means that both are equal. Unlike in JavaScript, where an implicit conversion to strings is performed, the comparator defaults to compare two values of type T.

  • function reduce<U>(
    +  fn: (accumValue: U, currentValue: T, index: i32, self: StaticArray<T>) => U,
    +  initialValue: U
    +): U
    +

    Calls the specified reducer function with each value of the array, resulting in a single return value. The respective previous reducer function's return value is remembered in accumValue, starting with initialValue, becoming the final return value in the process.

  • function reduceRight<U>(
    +  fn: (accumValue: U, currentValue: T, index: i32, self: StaticArray<T>) => U,
    +  initialValue: U
    +): U
    +

    Calls the specified reducer function with each value of the array, from right to left, resulting in a single return value. See Array#reduce for the reducer function's signature.

  • function reverse(): this
    +

    Reverses an array's values in place, modifying the array before returning it.

  • function toString(): string
    +

    Returns the result of join().

+ + + diff --git a/stdlib/string.html b/stdlib/string.html new file mode 100644 index 000000000..c76d118a5 --- /dev/null +++ b/stdlib/string.html @@ -0,0 +1,128 @@ + + + + + + String | The AssemblyScript Book + + + + + + + + + + + + + + + + + + +

# String

A fixed-length sequence of UTF-16 code units.

The String API works very much like JavaScript's (MDN (opens new window)), with the notable difference that the string type is an actual alias of String.

# Static members

  • function fromCharCode(unit: i32, surr?: i32): string
    +

    Creates a one character long string from the specified UTF-16 code units.

  • function fromCharCodes(units: u16[]): string
    +

    Creates a string from a sequence of UTF-16 code units.

  • function fromCodePoint(code: i32): string
    +

    Creates a one character long string from the specified Unicode code point.

  • function fromCodePoints(codes: i32[]): string
    +

    Creates a string from a sequence of Unicode code points.

# Instance members

# Fields

  • readonly length: i32
    +
    The length of the string in UTF-16 code units.

# Methods

  • function at(pos: i32): string
    +

    Gets the UTF-16 code unit at the specified position as a single character string. This method allows for positive and negative integers. Negative integers count back from the last string character.

  • function charAt(pos: i32): string
    +

    Gets the UTF-16 code unit at the specified position as a single character string. Returns "" (empty string) if out of bounds.

  • function charCodeAt(pos: i32): i32
    +

    Gets the UTF-16 code unit at the specified position as a number. Returns -1 if out of bounds.

  • function codePointAt(pos: i32): i32
    +

    Gets the Unicode code point at the specified (UTF-16 code unit) position as a number, possibly combining multiple successive UTF-16 code units. Returns -1 if out of bounds.

  • function concat(other: string): string
    +

    Concatenates this string with another string, in this order, and returns the resulting string.

  • function endsWith(search: string, end?: i32): bool
    +

    Tests if the strings ends with the specified string. If specified, end indicates the position at which to stop searching, acting as if it is the length of the string.

  • function includes(search: string, start?: i32): bool
    +

    Tests if the string includes the search string. If specified, start indicates the position at which to begin searching.

  • function indexOf(search: string, start?: i32): i32
    +

    Gets the first index of the specified search string within the string, or -1 if not found. If specified, start indicates the position at which to begin searching.

  • function lastIndexOf(search: string, start?: i32): i32
    +

    Gets the last index of the specified search string within the string, or -1 if not found. If specified, start indicates the position at which to begin searching from right to left.

  • function padStart(length: i32, pad: string): string
    +

    Pads the string with the contents of another string, possibly multiple times, until the resulting string reaches the specified length, returning the resulting string.

  • function padEnd(length: i32, pad: string): string
    +

    Pads the string with the contents of another string, possibly multiple times, until the resulting string reaches the specified length, returning the resulting string.

  • function repeat(count?: i32): string
    +

    Repeats the string count times and returns the concatenated result.

  • function replace(search: string, replacement: string): string
    +

    Replaces the first occurrence of search with replacement.

  • function replaceAll(search: string, replacement: string): string
    +

    Replaces all occurrences of search with replacement.

  • function slice(start: i32, end?: i32): string
    +

    Returns the region of the string from start inclusive to end exclusive, as a new string. If omitted, end defaults to the end of the string.

  • function split(separator?: string, limit?: i32): string[]
    +

    Splits the string at each occurrence of separator and returns the result as a new array of strings that has a maximum of limit values. If limit is omitted, no limit is assumed. If separator is omitted or not present in the string, the string becomes the sole element of the array. If separator is an empty string, the split is performed between code units (not code points), potentially destroying surrogate pairs.

  • function startsWith(search: string, start?: i32): bool
    +

    Tests if the string starts with the specified string. If specified, start indicates the position at which to begin searching, acting as the start of the string.

  • function substring(start: i32, end?: i32): string
    +

    Gets the part of the string in between start inclusive and end exclusive as a new string.

  • function toString(): this
    +

    Returns the string.

  • function trim(): string
    +

    Removes white space characters from both the start and the end of the string, returning the resulting string.

  • function trimStart(): string
    +function trimLeft(): string
    +

    Removes white space characters from the start of the string, returning the resulting string.

  • function trimEnd(): string
    +function trimRight(): string
    +

    Removes white space characters from the end of the string, returning the resulting string.

# Encoding API

# UTF8

When integrating with an environment that uses UTF-8, the following helpers can be used to quickly re-encode String data.

  • function String.UTF8.byteLength(str: string, nullTerminated?: bool): i32
    +

    Calculates the byte length of the specified string when encoded as UTF-8, optionally null terminated.

  • function String.UTF8.encode(str: string, nullTerminated?: bool): ArrayBuffer
    +

    Encodes the specified string to UTF-8 bytes, optionally null terminated.

  • function String.UTF8.encodeUnsafe(str: usize, len: i32, buf: usize, nullTerminated?: bool): usize
    +

    Encodes the specified raw string to UTF-8 bytes, opionally null terminated. Returns the number of bytes written.

  • function String.UTF8.decode(buf: ArrayBuffer, nullTerminated?: bool): string
    +

    Decodes the specified buffer from UTF-8 bytes to a string, optionally null terminated.

  • function String.UTF8.decodeUnsafe(
    +  buf: usize,
    +  len: usize,
    +  nullTerminated?: bool
    +): string
    +

    Decodes raw UTF-8 bytes to a string, optionally null terminated.

TIP

Note that any ArrayBuffer return value is a pointer to the buffer's data internally and thus can be passed to let's say a C-function directly. However, if the pointer is meant to live longer than the immediate external function call, the lifetime of the buffer must be tracked so it doesn't become collected prematurely with the data becoming invalid.

# UTF16

The following mostly exist to have a safe way to copy between Strings and ArrayBuffers, but doesn't involve a re-encoding step.

  • function String.UTF16.byteLength(str: string): i32
    +

    Calculates the byte length of the specified string when encoded as UTF-16.

  • function String.UTF16.encode(str: string): ArrayBuffer
    +

    Encodes the specified string to UTF-16 bytes.

  • function String.UTF16.encodeUnsafe(str: usize, len: i32, buf: usize): usize
    +

    Encodes the specified raw string to UTF-16 bytes. Returns the number of bytes written.

  • function String.UTF16.decode(buf: ArrayBuffer): string
    +

    Decodes the specified buffer from UTF-16 bytes to a string.

  • function String.UTF16.decodeUnsafe(buf: usize, len: usize): string
    +

    Decodes raw UTF-16 bytes to a string.

# Considerations

TL;DR: AssemblyScript does strings like JavaScript, but...

AssemblyScript strings purposely share their semantics with JavaScript strings, including that isolated surrogates can occur and are not eagerly sanitized. This is done for two reasons. First, as the Unicode Standard, Version 13.0 (opens new window) states in §2.7 Unicode Strings:

Depending on the programming environment, a Unicode string may or may not be required to be in the corresponding Unicode encoding form. For example, strings in Java, C#, or ECMAScript are Unicode 16-bit strings, but are not necessarily well-formed UTF-16 sequences. In normal processing, it can be far more efficient to allow such strings to contain code unit sequences that are not well-formed UTF-16—that is, isolated surrogates. Because strings are such a fundamental component of every program, checking for isolated surrogates in every operation that modifies strings can create significant overhead, especially because supplementary characters are extremely rare as a percentage of overall text in programs worldwide.

Second, sanitization is also not desirable in between AssemblyScript and JavaScript, or between two AssemblyScript modules, where it can be critical to maintain equality, inequality and hash integrity of idiomatic strings when function calls traverse JS<->AS or AS<->AS boundaries. It is common, for example, that an application is composed of both AssemblyScript and JavaScript code, or that an AssemblyScript module replaces a JavaScript module, and it is expected that two AssemblyScript modules can exchange strings, where sanitizing (mutating) strings eagerly would be unnecessary and dangerous. Also, ESM-integration aims to make JavaScript and WebAssembly modules interchangeable more broadly, which can only be achieved safely when maintaining compatibility.

Note that this stance differs from what the majority within the WebAssembly CG has decided (opens new window) for Interface Types and the Component Model, including its Web integration, regardless of our concerns (1 (opens new window), 2 (opens new window)), yet we believe that sanitization should only be performed where unavoidable, ideally as late as possible, matching what Web APIs do today (say right when calling an HTTP API but no earlier) to not impose unresolvable problems on the many popular languages already matching what JavaScript and the Web do. As such, we'd prefer if Interface Types and similar or related proposals revised their approach to follow WebIDL's precedent, where DOMString (opens new window) represents the concept and USVString (opens new window) is the special case. As WebIDL states:

When in doubt, use DOMString.

Of course we agree that USVString should be supported in some capacity to match what Rust and C++ do, but making it the only supported concept will not only break the other half of the ecosystem on a fundamental level, but also the Web platform as a whole, which is unnecessary and avoidable given that sanitization can easily be performed by an interface adapter only when needed.

+ + + diff --git a/stdlib/symbol.html b/stdlib/symbol.html new file mode 100644 index 000000000..7c0581fff --- /dev/null +++ b/stdlib/symbol.html @@ -0,0 +1,89 @@ + + + + + + Symbol | The AssemblyScript Book + + + + + + + + + + + + + + + + + + +

# Symbol

A primitive data type representing a unique global symbol.

The symbol type is very similar to JavaScript's (MDN (opens new window)), but is not deeply integrated with the compiler yet.

# Construction

  • function Symbol(description?: string): symbol
    +
    Creates a new unique symbol. Note that this is not a constructor (symbols are primitive data types) so cannot be invoked with new.

# Static members

  • function for(key: string): symbol
    +

    Obtains the existing unique symbol for the specified global key or creates a new unique symbol if the key does not exist.

  • function keyFor(sym: symbol): string | null
    +

    Obtains the global key of the specified unique symbol, if any.

# Instance members

  • function toString(): string
    +
    Returns a string representation of the symbol of the form "Symbol(key?)".
+ + + diff --git a/stdlib/typedarray.html b/stdlib/typedarray.html new file mode 100644 index 000000000..40badc2ee --- /dev/null +++ b/stdlib/typedarray.html @@ -0,0 +1,114 @@ + + + + + + TypedArray | The AssemblyScript Book + + + + + + + + + + + + + + + + + + +

# TypedArray

An Array-like view on a raw binary buffer.

The TypedArray API works very much like JavaScript's (MDN (opens new window)). The name TypedArray below represents one of the variants of element type T and is not an actual class. Note that typed arrays are not actually generic, but concrete implementations like Uint8Array and Float64Array have an identical interface that only differs in the implementation's element type denoted as T.

# Variants

Variant Element type Description
Int8Array i8 A view on 8-bit signed integer values.
Int16Array i16 A view on 16-bit signed integer values.
Int32Array i32 A view on 32-bit signed integer values.
Int64Array i64 A view on 64-bit signed integer values.
Uint8Array u8 A view on 8-bit unsigned integer values.
Uint8ClampedArray u8 A view on 8-bit unsigned integer values,
with set values clamped between 0 and 255 inclusive.
Uint16Array u16 A view on 16-bit unsigned integer values.
Uint32Array u32 A view on 32-bit unsigned integer values.
Uint64Array u64 A view on 64-bit unsigned integer values.
Float32Array f32 A view on 32-bit float values.
Float64Array f64 A view on 64-bit float values.

# Constructor

  • new TypedArray(length: i32)
    +
    Constructs a new typed array view with a new backing buffer and all values initialized to zero. See wrap below for wrapping a raw buffer.

# Static members

  • const BYTES_PER_ELEMENT: usize
    +

    Number of bytes per element.

  • function wrap(buffer: ArrayBuffer, byteOffset?: i32, length?: i32): TypedArray
    +

    Wraps a raw buffer to be viewed as a sequence of values of the typed array's value type. This is equivalent to the respective alternative constructor signature in JS but exists because there is no function overloading (yet).

# Instance members

# Fields

  • readonly buffer: ArrayBuffer
    +

    The backing array buffer of this view.

  • readonly byteOffset: i32
    +

    The offset in bytes from the start of the backing buffer.

  • readonly byteLength: i32
    +

    The length in bytes from the start of the backing buffer.

  • readonly length: i32
    +

    The length in elements.

# Methods

  • function every(fn: (value: T, index: i32, self: TypedArray) => bool): bool
    +

    Calls the specified function with every value of the array until it finds the first value for which the function returns false. Returns true if all functions returned true or the array is empty, otherwise false.

  • function fill(value: T, start?: i32, end?: i32): this
    +

    Replaces the values of the array from start inclusive to end exclusive in place with the specified value, returning the array.

  • function findIndex(fn: (value: T, index: i32, self: TypedArray) => bool): i32
    +

    Calls the specified function with every value of the array until it finds the first value for which the function returns true, returning its index. Returns -1 if that's never the case.

  • function findLastIndex(fn: (value: T, index: i32, self: TypedArray) => bool): i32
    +

    Calls the specified function with every value of the array starting at the end until it finds the first value for which the function returns true, returning its index. Returns -1 if that's never the case.

  • function forEach(fn: (value: T, index: i32, self: TypedArray) => void): void
    +

    Calls the specified function with every value of the array.

  • function includes(value: T, fromIndex?: i32): bool
    +

    Tests if the array includes the specified value, optionally providing a starting index.

  • function indexOf(value: T, fromIndex?: i32): i32
    +

    Gets the first index where the specified value can be found in the array. Returns -1 if not found.

  • function lastIndexOf(value: T, fromIndex?: i32): i32
    +

    Gets the last index where the specified value can be found in the array. Returns -1 if not found.

  • function map(fn: (value: T, index: i32, self: TypedArray) => T): TypedArray
    +

    Calls the specified function with every value of the array, returning a new array of the function's return values.

  • function reduce<U>(
    +  fn: (accumValue: U, currentValue T, index: i32, self: TypedArray) => U,
    +  initialValue: U
    +): U
    +

    Calls the specified reducer function with each value of the array, resulting in a single return value. The respective previous reducer function's return value is remembered in accumValue, starting with initialValue, becoming the final return value in the process.

  • function reduceRight<U>(
    +  fn: (accumValue: U, currentValue: T, index: i32, self: TypedArray) => U,
    +  initialValue: U
    +): U
    +

    Calls the specified reducer function with each value of the array, from right to left, resulting in a single return value.

  • function reverse(): this
    +

    Reverses an array's values in place, modifying the array before returning it.

  • function set(source: ArrayLike<number>, offset?: i32): void
    +

    Sets the typed array values (starting at offset, or 0), reading input values from a specified source array.

  • function some(fn: (value: T, index: i32, self: TypedArray) => bool): bool
    +

    Calls the specified function with every value of the array until it finds the first value for which the function returns true, returning true. Returns false otherwise or if the array is empty.

  • function sort(fn: (a: T, b: T) => i32): this
    +

    Sorts the values of the array in place, using the specified comparator function, modifying the array before returning it. The comparator returning a negative value means a < b, a positive value means a > b and 0 means that both are equal. Unlike in JavaScript, where an implicit conversion to strings is performed, the comparator defaults to compare two values of type T.

  • function subarray(start?: i32, end?: i32): TypedArray
    +

    Returns a new view on the array's backing buffer from begin inclusive to end exclusive relative to this array. If omitted, end defaults to the end of the array. Does not copy.

+ + + diff --git a/transforms.html b/transforms.html new file mode 100644 index 000000000..599aa201a --- /dev/null +++ b/transforms.html @@ -0,0 +1,43 @@ + + + + + + +

+ Redirect after 3s +

+

+ Powered by vuepress-plugin-redirect +

+ + + \ No newline at end of file diff --git a/types.html b/types.html new file mode 100644 index 000000000..4a718f0cb --- /dev/null +++ b/types.html @@ -0,0 +1,128 @@ + + + + + + Types | The AssemblyScript Book + + + + + + + + + + + + + + + + + + +

# Types

AssemblyScript inherits WebAssembly's more specific integer, floating point and reference types:

AssemblyScript Type WebAssembly type TypeScript type Description
Integer types
i32 i32 number A 32-bit signed integer.
u32 i32 number A 32-bit unsigned integer.
i64 i64 bigint A 64-bit signed integer.
u64 i64 bigint A 64-bit unsigned integer.
isize i32 or i64 number or bigint A 32-bit signed integer in WASM32.
A 64-bit signed integer in WASM64 🦄.
usize i32 or i64 number or bigint A 32-bit unsigned integer in WASM32.
A 64-bit unsigned integer in WASM64 🦄.
Floating point types
f32 f32 number A 32-bit float.
f64 f64 number A 64-bit float.
Small integer types
i8 i32 number An 8-bit signed integer.
u8 i32 number An 8-bit unsigned integer.
i16 i32 number A 16-bit signed integer.
u16 i32 number A 16-bit unsigned integer.
bool i32 boolean A 1-bit unsigned integer.
Vector types
v128 v128 - A 128-bit vector.
Reference / GC types
ref_extern (ref extern) Object An external reference.
ref_func (ref func) Function A function reference.
ref_any (ref any) Object An internal reference. 🦄
ref_eq (ref eq) Object An equatable reference. 🦄
ref_struct (ref struct) Object A data reference. 🦄
ref_array (ref array) Array An array reference. 🦄
ref_string (ref string) string A string reference. 🦄
ref_stringview_wtf8 (ref stringview_wtf8) - A WTF-8 string view reference. 🦄
ref_stringview_wtf16 (ref stringview_wtf16) string A WTF-16 string view reference. 🦄
ref_stringview_iter (ref stringview_iter) - A string iterator reference. 🦄
Special types
void - void Indicates no return value.

Note

The base reference types above are non-nullable. Canonical aliases, as per the spec, are available as well and refer to the respective nullable type, e.g. type externref = ref_extern | null mapping to externref == (ref null extern) in Wasm. The ref_ prefix avoids naming collisions for the time being and might be dropped in the future.

Just like in TypeScript, types are annotated after variable, function argument or class member names, separated by :, like so:

function add(a: i32, b: i32): i32 {
+  let sum: i32 = a + b; // type can be inferred, annotation can be omitted
+  return sum;
+}
+

# Type rules

The compiler will complain when it sees an implicit conversion that might not actually be intended, quite similar to what a C compiler would do.

# Casting

In AssemblyScript, the type assertions <T>expression and expression as T known from TypeScript become explicit type conversions, essentially telling the compiler that the conversion is intended. In addition, each of the type names mentioned above, except aliases, also act as portable conversion built-ins that can be used just like i32(expression). Using portable conversions is especially useful where the exact same code is meant to be compiled to JavaScript with the TypeScript compiler (see), that otherwise would require the insertion of asm.js-style type coercions like expression | 0.

# Inference

Compared to TypeScript, type inference in AssemblyScript is limited because the type of each expression must be known in advance. This means that variable and parameter declarations must either have their type annotated or have an initializer. Without a type annotation and only an initializer, AssemblyScript will assume i32 at first and only reconsider another type if the value doesn't fit (becomes i64), is a float (becomes f64) or irrefutably has another type than these, like the type of a variable, the return type of a function or a class type. Furthermore, functions must be annotated with a return type to help the compiler make the correct decisions, for example where a literal is returned or multiple return statements are present.

# Nullability

Basic types cannot be nullable, but class and function types can. Appending | null declares a nullable type.

# Assignability

Assigning a value of one type to a target of another type can be performed without explicit casts where the full range of possible values can be represented in the target type, regardless of interpretation/signedness:

bool i8/u8 i16/u16 i32/u32 i64/u64 f32 f64
bool
i8/u8
i16/u16
i32/u32
i64/u64
f32
f64

Note that isize and usize are aliases of either i32 and u32 in WASM32 respectively i64 and u64 in WASM64 🦄.

var  i8val: i8  = -128  // 0x80
+var  u8val: u8  = i8val // becomes 128 (0x80)
+var i16val: i16 = i8val // becomes -128 through sign-extension (0xFF80)
+var u16val: u16 = i8val // becomes 65408 through masking (0xFF80)
+var f32val: f32 = i8val // becomes -128.0
+

Wasm reference and GC types are anticipated to adhere to the following hierarchy 🦄:

Diagram of anticipated reference types hierarchy.

Dashed elements are not exposed and/or unclear. (...)-placeholders indicate the concrete subtypes, e.g. an array of a specific element type, a struct with specific field types and potentially a supertype, or a function with specific parameter and return types. For details, see Wasm GC's subtyping rules (opens new window).

# Comparability

Comparing two values of different types can be performed without an explicit cast under the same rules as outlined in assignability above

  1. if the comparison is absolute (== or ===, != or !==)
  2. if the comparison is relative (>, <, >=, <=) and both types have the same signedness

because WebAssembly has distinct operations for signed and unsigned comparisons. The comparison uses the larger type and returns bool.

Note that == and === respectively != and !== are the same in AssemblyScript because comparing two values of different types is invalid under its strict typing rules anyhow.

# Bit shifts

The result of a bit shift (<<, >>) is the left type, with the right type implicitly converted to the left type, performing an arithmetic shift if the left type is signed and a logical shift if the left type is unsigned.

The result of an unsigned right shift (>>>) is the left type (signedness is retained), with the right type implicitly converted to the left type, but always performing a logical shift.

Note that only the log2(sizeof<T>()) least significant bits of the shift affect the result:

Type Significant bits Example
i8 / u8 3 x << yx << (y & 7)
i16 / u16 4 x << yx << (y & 15)
i32 / u32 5 x << yx << (y & 31)
i64 / u64 6 x << yx << (y & 63)

If the left type is a float, an error is emitted.

# Macro types

The following macro types provide access to related types that would otherwise be impossible to obtain.

Macro type Description
native<T> Obtains the underlying native type of T, e.g. u32 if T is a class (in WASM32).
indexof<T> Obtains the index type of a collection based on the indexed access overload.
valueof<T> Obtains the value type of a collection based on the indexed access overload.
returnof<T> Obtains the return type of a function type.

# Range limits

Various range limits specific to the WebAssembly types are present as global constants for convenience:

  • const i8.MIN_VALUE: i8 = -128
    +const i8.MAX_VALUE: i8 = 127
    +
  • const i16.MIN_VALUE: i16 = -32768
    +const i16.MAX_VALUE: i16 = 32767
    +
  • const i32.MIN_VALUE: i32 = -2147483648
    +const i32.MAX_VALUE: i32 = 2147483647
    +
  • const i64.MIN_VALUE: i64 = -9223372036854775808
    +const i64.MAX_VALUE: i64 = 9223372036854775807
    +
  • const isize.MIN_VALUE: isize // WASM32: i32.MIN_VALUE, WASM64: i64.MIN_VALUE
    +const isize.MAX_VALUE: isize // WASM32: i32.MAX_VALUE, WASM64: i64.MAX_VALUE
    +
  • const u8.MIN_VALUE: u8 = 0
    +const u8.MAX_VALUE: u8 = 255
    +
  • const u16.MIN_VALUE: u16 = 0
    +const u16.MAX_VALUE: u16 = 65535
    +
  • const u32.MIN_VALUE: u32 = 0
    +const u32.MAX_VALUE: u32 = 4294967295
    +
  • const u64.MIN_VALUE: u64 = 0
    +const u64.MAX_VALUE: u64 = 18446744073709551615
    +
  • const usize.MIN_VALUE: usize = 0
    +const usize.MAX_VALUE: usize // WASM32: u32.MAX_VALUE, WASM64: u64.MAX_VALUE
    +
  • const bool.MIN_VALUE: bool = 0
    +const bool.MAX_VALUE: bool = 1
    +
  • const f32.MIN_VALUE: f32 = -3.40282347e+38
    +const f32.MAX_VALUE: f32 = 3.40282347e+38
    +const f32.MIN_NORMAL_VALUE: f32 = 1.17549435e-38
    +const f32.MIN_SAFE_INTEGER: f32 = -16777215
    +const f32.MAX_SAFE_INTEGER: f32 = 16777215
    +const f32.EPSILON: f32 = 1.19209290e-07
    +
  • const f64.MIN_VALUE: f64 = -1.7976931348623157e+308
    +const f64.MAX_VALUE: f64 = 1.7976931348623157e+308
    +const f64.MIN_NORMAL_VALUE: f64 = 2.2250738585072014e-308
    +const f64.MIN_SAFE_INTEGER: f64 = -9007199254740991
    +const f64.MAX_SAFE_INTEGER: f64 = 9007199254740991
    +const f64.EPSILON: f64 = 2.2204460492503131e-16
    +
+ + +

A TypeScript-like language for WebAssembly.

+ Get Started + GitHub npm

Designed for WebAssembly

AssemblyScript targets WebAssembly's feature set specifically, giving developers low-level control over their code.

Familiar TypeScript syntax

Its similarity with TypeScript makes it easy to compile to WebAssembly without learning a new language.

Right at your fingertips

Integrates with the existing Web ecosystem - no heavy toolchains to set up. Simply npm install it!

#!runtime=stub
+/** Calculates the n-th Fibonacci number. */
+export function fib(n: i32): i32 {
+  var a = 0, b = 1
+  if (n > 0) {
+    while (--n) {
+      let t = a + b
+      a = b
+      b = t
+    }
+    return b
+  }
+  return a
+}
+
+#!html
+<textarea id="output" style="height: 100%; width: 100%" readonly></textarea>
+<script type="module">
+const exports = await instantiate(await compile(), { /* imports */ })
+const output = document.getElementById('output')
+for (let i = 0; i <= 10; ++i) {
+  output.value += `fib(${i}) = ${exports.fib(i)}\n`
+}
+</script>
+

AssemblyScript is free and open source software released under the Apache License, Version 2.0, builds upon Binaryen and is based on the WebAssembly specification. It is brought to you by the following awesome people:

Contributors

dcodeIOMaxGraeyHerrCai0907jtennerCountBleckJesseCodeBonesyjhmelodyromdotdogtorch2424technohippysaulecabreraLiaoPengalangpierceColinEberhardtDuncanUszkay1nidinsurmawillemnealLinusUFGasperghalimiandy-hansonforcepusherkazuponjayphelpsgzuidhofmattjohnsonpintFloorLampPinkaminaDianePiepiotr-olessidx1024ApsarasXJairusSWadurosphamannfatjonnyccouzenstrusktrmaxlkatcwellsErnestoBorioTyriardawsbotRehkitzDevsunfishcodeprogrammerjakemmathysporia-catpvoronanischayvWscatsrottencandycoder0107git

Why AssemblyScript?

“You are now able to write WebAssembly without learning a new language, and harness all these benefits WebAssembly might offer you. I think that is kind of powerful. AssemblyScript is absolutely usable, and very enjoyable!” – Surma, WebAssembly for Web Developers (Google I/O ’19)

“AssemblyScript is designed with WebAssembly and code size in mind. It's not an existing language that we are using for a new purpose but it's a language designed for WebAssembly. It has great wasm-opt integration, in fact it's built with it, and it's very easy to get good code size.” – Alon Zakai, Shipping Tiny WebAssembly Builds (WebAssembly Summit)

“I chose AssemblyScript because it has high-level readability and low-level control. It's like a high-level language but you get that low-level feeling and you can even directly write WebAssembly intrinsics if you want to.” – Peter Salomonsen, WebAssembly Music (WebAssembly Summit)

Thanks to our sponsors!

Most of the maintainers and contributors do this open source work in their free time. If you use AssemblyScript for a serious task or plan to do so, and you'd like us to invest more time on it, please donate to our OpenCollective. By sponsoring this project, your logo will show up below. Thank you so much for your support!

Gold Sponsors

NEAR FoundationShopifyThe GraphChainSafe Systems

Silver Sponsors

STOICFunrize™ Social CasinoWasmBook.com

Bronze Sponsors

Ryan ZurrerAlon ZakaiІгрові автоматиTriplebyteRoute4Me Route PlannerNoLimitCoinsFlint

Individual Backers

Riversweeps Sweepstakes SoftwareWebScraping.AI777 казиноTom BallingerОнлайн Казино Украины#1 Sweepstakes Software for Internet CafesОнлайн казино slotoking УкраїнаHoofdkantoorJordan TimmermanІгрові автоматиForrest MoretJacob RichardsCharlie ArnoldІгрові автоматиОнлайн казино УкраїниТоп казиноTaylor ClarkHarry SolovayFunz Citytakanori sugawaraJonathan BeriJack ArringtonJeff Wainwrightemmanuelm41Agung Sidharta SoStrapisri sai swaroopEzra SavardincognitoJulius ShapiroRubenD777Open Source CollectiveRobinMaryGuest

Join our Discord

If you have questions only a human can answer, would like to show others what you are working on or just want to hang out with other AssemblyScript folks, make sure to join our Discord server! There you'll find channels for #announcements, #help, and more.