Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
ES6 Deep Dive
Search
dherman
August 30, 2012
Programming
14
4.1k
ES6 Deep Dive
A deep dive into three features of ECMAScript Edition 6: symbols, structs, and generators.
dherman
August 30, 2012
Tweet
Share
More Decks by dherman
See All by dherman
Rust + Node = Neon
dherman
1
330
Evolving the World's Most Popular Programming Language
dherman
0
660
Closing iterators
dherman
0
780
A better future for comprehensions
dherman
0
2k
Evolution is Awesome
dherman
0
580
Status Report: ES6 Modules
dherman
16
4k
Discussion with TC39 about the semantics of symbols
dherman
1
410
September 2013 Modules Status Update
dherman
2
1.2k
Rust: low-level programming without the segfaults
dherman
13
9k
Other Decks in Programming
See All in Programming
新メンバーも今日から大活躍!SREが支えるスケールし続ける組織のオンボーディング
honmarkhunt
5
8.7k
型で語るカタ
irof
0
700
たった 1 枚の PHP ファイルで実装する MCP サーバ / MCP Server with Vanilla PHP
okashoi
1
300
脱Riverpod?fqueryで考える、TanStack Queryライクなアーキテクチャの可能性
ostk0069
0
500
Quand Symfony, ApiPlatform, OpenAI et LangChain s'allient pour exploiter vos PDF : de la théorie à la production…
ahmedbhs123
0
220
可変変数との向き合い方 $$変数名が踊り出す$$ / php conference Variable variables
gunji
0
180
AWS Summit Japan 2024と2025の比較/はじめてのKiro、今あなたは岐路に立つ
satoshi256kbyte
0
120
テストから始めるAgentic Coding 〜Claude Codeと共に行うTDD〜 / Agentic Coding starts with testing
rkaga
15
5.6k
AI時代の『改訂新版 良いコード/悪いコードで学ぶ設計入門』 / ai-good-code-bad-code
minodriven
23
9.6k
dbt民主化とLLMによる開発ブースト ~ AI Readyな分析サイクルを目指して ~
yoshyum
3
1.1k
レベル1の開発生産性向上に取り組む − 日々の作業の効率化・自動化を通じた改善活動
kesoji
0
300
Agentic Coding: The Future of Software Development with Agents
mitsuhiko
0
130
Featured
See All Featured
The Language of Interfaces
destraynor
158
25k
Product Roadmaps are Hard
iamctodd
PRO
54
11k
Bash Introduction
62gerente
613
210k
Fashionably flexible responsive web design (full day workshop)
malarkey
407
66k
How to Ace a Technical Interview
jacobian
278
23k
YesSQL, Process and Tooling at Scale
rocio
173
14k
Writing Fast Ruby
sferik
628
62k
How STYLIGHT went responsive
nonsquared
100
5.6k
Testing 201, or: Great Expectations
jmmastey
43
7.6k
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
656
60k
What’s in a name? Adding method to the madness
productmarketing
PRO
23
3.5k
Code Review Best Practice
trishagee
69
19k
Transcript
Dave Herman ES6 Deep Dive Symbols, Structs, Generators
None
About me • @littlecalculist • http://calculist.org • http://github.com/dherman • Mozilla
Research • TC39 • Also…
In print this December http://effectivejs.com
Symbols
JS property names are strings var obj = { foo:
42 }; obj["foo"]; // 42
The all-powerful _ character function Dict() { this._entries = {};
} Don’t touch me, I’m private!
When you mean business… __proto__ private SO PRIVATE REALLY GUYS
SOOO TOTALLY PRIVATE private!
Conventions are no guarantee function SuperClass() { this._data = "superclass
private data"; } function SubClass() { SuperClass.call(this); this._data = "subclass private data"; // collision! } SubClass.prototype = Object.create(SuperClass.prototype);
Closures for information hiding function SuperClass() { var data =
"private data"; this.method = function() { /* ... */ data /* ... */ }; } no sharing: one method per instance!
Introducing symbols
Introducing symbols var sym = new Symbol("data");
Introducing symbols var sym = new Symbol("data"); function SuperClass() {
this[sym] = "private data"; }
Introducing symbols var sym = new Symbol("data"); function SuperClass() {
this[sym] = "private data"; } SuperClass.prototype.method = function() { /* ... */ this[sym] /* ... */ };
Introducing symbols var obj = new SuperClass(); "data" in obj;
// false "_data" in obj; // false sym in obj; // true
Performance • Engines already do string interning • Convertible to
a fixed offset with inline caches
Proposal: scoped symbols private @sym; function SuperClass() { this.@sym =
"private data"; } SuperClass.prototype.method = function() { /* ... */ this.@sym /* ... */ };
Structured binary data
Typed arrays var a = new Uint32Array(1024); a[17] = 42;
Typed arrays var vertices = new Float32Array([ -1.0, -1.0, 0.0,
// vertex 1 0.0, 1.0, 0.0, // vertex 2 1.0, -1.0, 0.0 // vertex 3 ]); -1.0 -1.0 0.0 0.0 1.0 0.0 1.0 -1.0 0.0 0 4 8 12 16 20 24 28 32
Structs var Point = struct({ x: float32, y: float32, z:
float32 }); var origin = new Point(0.0, 0.0, 0.0); origin.x; // 0.0 origin.y; // 0.0
Arrays of structs var vertices = new Point.array([ { x:
-1.0, y: -1.0, z: 0.0 }, { x: 0.0, y: 1.0, z: 0.0 }, { x: 1.0, y: -1.0, z: 0.0 } ]); -1.0 -1.0 0.0 0.0 1.0 0.0 1.0 -1.0 0.0 0 4 8 12 16 20 24 28 32
JIT compilers — types
Applications of structs • WebGL data • File and network
I/O • Compiling other languages to JS
Generators
Lies, lies, lies “JS doesn’t have concurrency.” “JS is single-threaded
so it can’t have race conditions.” “Event-based programming is easy.”
Download three files load("foo", function(foo) { load("bar", function(bar) { //
why wait? load("baz", function(baz) { use([foo, bar, baz]); }); }); });
Download three files load("foo", function(foo) { load("bar", function(bar) { //
why wait? load("baz", function(baz) { use([foo, bar, baz]); }); }); });
Download three files var files = []; ["foo", "bar", "baz"].forEach(function(url,
i) { load(url, function(file) { files.push(file); // no! if (i === 3) // no! use(files); }); });
Download three files var files = []; ["foo", "bar", "baz"].forEach(function(url,
i) { load(url, function(file) { files[i] = file; if (files.length === 3) // still no! use(files); }); });
Download three files var files = [], count = 0;
["foo", "bar", "baz"].forEach(function(url, i) { load(url, function(file) { files[i] = file; if (++count === 3) use(files); }); });
JavaScript is concurrent Cooperative concurrency: easier, but not easy! Handlers
run sequentially but start concurrently. Shared state 㱺 race conditions 㱺 pain and suffering
task.js: Beautiful concurrency spawn(function*() { var files = yield join(load("foo"),
load("bar"), load("baz")); use(files); }); http://taskjs.org
task.js: Beautiful concurrency spawn(function*() { var files = yield join(load("foo"),
load("bar"), load("baz")); use(files); }); create a task that can be paused pause! http://taskjs.org
Generator functions function* evenNumbers() { for (var next = 0;
true; next += 2) { yield next; } }
Generator functions function* evenNumbers() { for (var next = 0;
true; next += 2) { yield next; } }
Generator functions function* evenNumbers() { for (var next = 0;
true; next += 2) { yield next; } } evenNumbers(); ✗
Generator functions function* evenNumbers() { for (var next = 0;
true; next += 2) { yield next; } } evenNumbers(); ✗
Generators function* f() { }
Generators function* f() { } .next: var g = f();
⋮
Generators function* evenNumbers() { /* ... */ } var g
= evenNumbers(); g.next(); // 0 g.next(); // 2 g.next(); // 4 starts out paused
Lazy iteration Dict.prototype.keys = function*() { for (var key in
this._entries) yield key; };
Iterators work with for-of var dict = new Dict(); //
... for (var key of dict.keys()) { console.log(key + ": " + dict.get(key)); }
Pausing is powerful load("config.json", function(config) { db.lookup(JSON.parse(config).table, username, function(user) {
load(user.id + ".png", function(avatar) { // ... }); }); });
Pausing is powerful load("config.json", function(config) { db.lookup(JSON.parse(config).table, username, function(user) {
load(user.id + ".png", function(avatar) { // ... }); }); }); later later later
Pausing is powerful load("config.json", function(config) { db.lookup(JSON.parse(config).table, username, function(user) {
load(user.id + ".png", function(avatar) { // ... }); }); }); later later later
Pausing with promises load("config.json") .then(function(config) { return db.lookup(JSON.parse(config).table); }) .then(function(user)
{ return load(user.id + ".png"); }) .then(function(avatar) { /* ... */ });
Pausing with promises load("config.json") .then(function(config) { return db.lookup(JSON.parse(config).table); }) .then(function(user)
{ return load(user.id + ".png"); }) .then(function(avatar) { /* ... */ });
Pausing with promises load("config.json") .then(function(config) { return db.lookup(JSON.parse(config).table); }) .then(function(user)
{ return load(user.id + ".png"); }) .then(function(avatar) { /* ... */ });
Pausing with promises load("config.json") .then(function(config) { return db.lookup(JSON.parse(config).table); }) .then(function(user)
{ return load(user.id + ".png"); }) .then(function(avatar) { /* ... */ });
Pausing with promises load("config.json") .then(function(config) { return db.lookup(JSON.parse(config).table); }) .then(function(user)
{ return load(user.id + ".png"); }) .then(function(avatar) { /* ... */ });
Pausing with promises load("config.json") .then(function(config) { return db.lookup(JSON.parse(config).table); }) .then(function(user)
{ return load(user.id + ".png"); }) .then(function(avatar) { /* ... */ });
Tasks yield promises spawn(function*() { var config = JSON.parse(yield load("config.json"));
var user = yield db.lookup(config.table, username); var avatar = yield load(user.id + ".png"); // ... });
Tasks yield promises spawn(function*() { var config = JSON.parse(yield load("config.json"));
var user = yield db.lookup(config.table, username); var avatar = yield load(user.id + ".png"); // ... });
Tasks yield promises spawn(function*() { var config = JSON.parse(yield load("config.json"));
var user = yield db.lookup(config.table, username); var avatar = yield load(user.id + ".png"); // ... }); looks like a synchronous API!
What about errors? load("foo", function(foo) { load("bar", function(bar) { load("baz",
function(baz) { use([foo, bar, baz]); }, function(err) { /* ... */ }); }, function(err) { /* ... */ }); }, function(err) { /* ... */ });
What about errors? load("foo", function(err, foo) { if (err) return
onError(err); load("bar", function(err, bar) { if (err) return onError(err); load("baz", function(err, baz) { if (err) return onError(err); use([foo, bar, baz]); }); }); });
Error handling with promises var p = load("config.json") .then(function(config) {
/* ... */ } .then(function(user) { /* ... */ }) .then(function(avatar) { /* ... */ }); when(p, function(result) { /* ... */ }, function(err) { /* ... */ });
Error handling with tasks spawn(function*() { try { var config
= JSON.parse(yield load("config.json")); var user = yield db.lookup(config.table, username); var avatar = yield load(user.id + ".png"); // ... } catch (e) { /* ... */ } });
Wait for multiple events spawn(function*() { var [foo, bar, baz]
= yield join(load("foo"), load("bar"), load("baz")); // ... });
Purposefully race events spawn(function*() { try { var foo =
yield select(load("foo"), timeout(3000)); // ... } catch (e) { /* timed out */ } });
Generators • Interruptible computations 㱺 custom iterators • Pausing with
yield 㱺 concurrency minus the callbacks
Something completely different
({}+[])[!![]+!![]+!![]]+(![]+[])[!![]+!![]+!![]]
({}+[])[!![]+!![]+!![]]+(![]+[])[!![]+!![]+!![]]
({}+[])[!![]+!![]+!![]]+(![]+[])[!![]+!![]+!![]] "[object Object]"
({}+[])[!![]+!![]+!![]]+(![]+[])[!![]+!![]+!![]] "[object Object]"
({}+[])[!![]+!![]+!![]]+(![]+[])[!![]+!![]+!![]] "[object Object]" true true true
({}+[])[!![]+!![]+!![]]+(![]+[])[!![]+!![]+!![]] "[object Object]" 3
({}+[])[!![]+!![]+!![]]+(![]+[])[!![]+!![]+!![]] "j"
({}+[])[!![]+!![]+!![]]+(![]+[])[!![]+!![]+!![]] "false" "j"
({}+[])[!![]+!![]+!![]]+(![]+[])[!![]+!![]+!![]] "false" 3 "j"
({}+[])[!![]+!![]+!![]]+(![]+[])[!![]+!![]+!![]] "j" "s"
! + { } [ ] ( ) \n ===
JavaScript
Um. So… why?
• No reason. Um. So… why?
• Yosuke Hasegawa: JSF*ck • Patricio Palladino: Hieroglyphy • Me:
pure JS, no browser API’s Not the first deranged weirdo
> String+[] "function String() { [native code] }" "S"
> "".constructor+[] "function String() { [native code] }" "S"
> ""["constructor"]+[] "function String() { [native code] }" "S"
> [].slice.call(""["constructor"]+[]) ["f","u","n","c","t","i","o","n"," ","S","t","r", /* ... */] "S"
> [].slice.call(""["constructor"]+[]) [" ","f","u","n","c","t","i","o","n"," ","S","t","r", /* ... */] "S"
> function nonWhitespace(s) { return !/^\s*$/.test(s) } > [].slice.call(""["constructor"]+[]).filter(nonWhitespace) ["f","u","n","c","t","i","o","n","S","t","r",
/* ... */] "S"
> Number("f") NaN > Number(" ") 0 > isNaN("f") true
> isNaN(" ") false "S"
> [].slice.call(""["constructor"]+[]).filter(isNaN) ["f","u","n","c","t","i","o","n","S","t","r", /* ... */] "S"
> [].slice.call(""["constructor"]+[]) .filter(Function("return isNaN")()) ["f","u","n","c","t","i","o","n","S","t","r", /* ... */] "S"
> [].slice.call(""["constructor"]+[]) .filter(Array.constructor("return isNaN")()) ["f","u","n","c","t","i","o","n","S","t","r", /* ... */] "S"
> [].slice.call(""["constructor"]+[]) .filter([].constructor.constructor("return isNaN")()) ["f","u","n","c","t","i","o","n","S","t","r", /* ... */] "S"
> [].slice.call(""["constructor"]+[]) .filter([].constructor.constructor("return isNaN")())[8] "S" "S"
> (9).toString() "9" > (15).toString(16) "f" > (16).toString(17) "g" "p"
> (25).toString(26) "p" "p"
> (25)["toString"](26) "p" "p"
> escape(" ") "%20" "%"
> Function("return escape")()(" ") "%20" "%"
> Function("return escape")()(" ")[0] "%" "%"
> Function("return unescape")()("%3b") ";" Any ASCII character
> (({}+[])[!![]+!![]+!![]]+[]+(![]+[])[+!![]]+(+(!![]+!![]+!![]+[]+ (+!![])))[(!![]+[])[+![]]+[]+({}+[])[+!![]]+[][(![]+[])[!![]+!![] +!![]]+[]+(![]+[])[!![]+!![]]+([][![]]+[])[!![]+!![]+!![]+!![]+!! []]+({}+[])[!![]+!![]+!![]+!![]+!![]]+(!![]+[])[!![]+!![]+!![]]] [({}+[])[!![]+!![]+!![]+!![]+!![]]+[]+(![]+[])[+!![]]+(![]+[])[!![] +!![]]+(![]+[])[!![]+!![]]](+[![]]+[]+(!![]+[])[({}+[])[!![]+!![] +!![]+!![]+!![]]+[]+({}+[])[+!![]]+([][![]]+[])[+!![]]+(![]+[])[!! []+!![]+!![]]+(!![]+[])[+![]]+(!![]+[])[+!![]]+([][![]]+[])[+![]]+ ({}+[])[!![]+!![]+!![]+!![]+!![]]+(!![]+[])[+![]]+({}+[])[+!![]]+
(!![]+[])[+!![]]])[(![]+[])[+![]]+[]+([][![]]+[])[!![]+!![]+!![]+!! []+!![]]+(![]+[])[!![]+!![]]+(!![]+[])[+![]]+(!![]+[])[!![]+!![]+!! []]+(!![]+[])[+!![]]]([][({}+[])[!![]+!![]+!![]+!![]+!![]]+[]+({}+ [])[+!![]]+([][![]]+[])[+!![]]+(![]+[])[!![]+!![]+!![]]+(!![]+[]) [+![]]+(!![]+[])[+!![]]+([][![]]+[])[+![]]+({}+[])[!![]+!![]+!![] +!![]+!![]]+(!![]+[])[+![]]+({}+[])[+!![]]+(!![]+[])[+!![]]][({}+ [])[!![]+!![]+!![]+!![]+!![]]+[]+({}+[])[+!![]]+([][![]]+[])[+!![]] +(![]+[])[!![]+!![]+!![]]+(!![]+[])[+![]]+(!![]+[])[+!![]]+([][![]] +[])[+![]]+({}+[])[!![]+!![]+!![]+!![]+!![]]+(!![]+[])[+![]]+({}+ [])[+!![]]+(!![]+[])[+!![]]]((!![]+[])[+!![]]+[]+(!![]+[])[!![]+!! []+!![]]+(!![]+[])[+![]]+([][![]]+[])[+![]]+(!![]+[])[+!![]]+([][!
[]]+[])[+!![]]+({}+[])[!![]+!![]+!![]+!![]+!![]+!![]+!![]]+([][![]] +[])[!![]+!![]+!![]+!![]+!![]]+(![]+[])[!![]+!![]+!![]]+(+[![]])) ())[+(+!![]+[]+(+!![]))]+(!![]+[])[+![]]+(!![]+[])[+!![]]+([][![]]+ [])[!![]+!![]+!![]+!![]+!![]]+([][![]]+[])[+!![]]+[][(![]+[])[!![] +!![]+!![]]+[]+(![]+[])[!![]+!![]]+([][![]]+[])[!![]+!![]+!![]+!![] +!![]]+({}+[])[!![]+!![]+!![]+!![]+!![]]+(!![]+[])[!![]+!![]+!![]]] [({}+[])[!![]+!![]+!![]+!![]+!![]]+[]+(![]+[])[+!![]]+(![]+[])[!![] +!![]]+(![]+[])[!![]+!![]]]((!![]+[])[({}+[])[!![]+!![]+!![]+!![] +!![]]+[]+({}+[])[+!![]]+([][![]]+[])[+!![]]+(![]+[])[!![]+!![]+!! []]+(!![]+[])[+![]]+(!![]+[])[+!![]]+([][![]]+[])[+![]]+({}+[])[!!
[]+!![]+!![]+!![]+!![]]+(!![]+[])[+![]]+({}+[])[+!![]]+(!![]+[]) [+!![]]]+[])[(![]+[])[+![]]+[]+([][![]]+[])[!![]+!![]+!![]+!![]+!! []]+(![]+[])[!![]+!![]]+(!![]+[])[+![]]+(!![]+[])[!![]+!![]+!![]]+ (!![]+[])[+!![]]]([][({}+[])[!![]+!![]+!![]+!![]+!![]]+[]+({}+[]) [+!![]]+([][![]]+[])[+!![]]+(![]+[])[!![]+!![]+!![]]+(!![]+[])[+! []]+(!![]+[])[+!![]]+([][![]]+[])[+![]]+({}+[])[!![]+!![]+!![]+!![] +!![]]+(!![]+[])[+![]]+({}+[])[+!![]]+(!![]+[])[+!![]]][({}+[])[!! []+!![]+!![]+!![]+!![]]+[]+({}+[])[+!![]]+([][![]]+[])[+!![]]+(![]+ [])[!![]+!![]+!![]]+(!![]+[])[+![]]+(!![]+[])[+!![]]+([][![]]+[]) [+![]]+({}+[])[!![]+!![]+!![]+!![]+!![]]+(!![]+[])[+![]]+({}+[]) [+!![]]+(!![]+[])[+!![]]]((!![]+[])[+!![]]+[]+(!![]+[])[!![]+!![
]+!![]]+(!![]+[])[+![]]+([][![]]+[])[+![]]+(!![]+[])[+!![]]+([][! []]+[])[+!![]]+({}+[])[!![]+!![]+!![]+!![]+!![]+!![]+!![]]+([][![]] +[])[!![]+!![]+!![]+!![]+!![]]+(![]+[])[!![]+!![]+!![]]+(+[![]])) ())[+(+!![]+[]+(!![]+!![]+!![]))]](+(!![]+!![]+!![]+[]+(!![]+!! [])))+(![]+[])[+!![]]+(![]+[])[!![]+!![]+!![]]+({}+[])[!![]+!![]+!! []+!![]+!![]]+(!![]+[])[+!![]]+([][![]]+[])[!![]+!![]+!![]+!![]+!! []]+(+(!![]+!![]+[]+(!![]+!![]+!![]+!![]+!![])))[(!![]+[])[+![]]+[] +({}+[])[+!![]]+[][(![]+[])[!![]+!![]+!![]]+[]+(![]+[])[!![]+!![]]+ ([][![]]+[])[!![]+!![]+!![]+!![]+!![]]+({}+[])[!![]+!![]+!![]+!![] +!![]]+(!![]+[])[!![]+!![]+!![]]][({}+[])[!![]+!![]+!![]+!![]+!![]]
+[]+(![]+[])[+!![]]+(![]+[])[!![]+!![]]+(![]+[])[!![]+!![]]](+[![]] +[]+(!![]+[])[({}+[])[!![]+!![]+!![]+!![]+!![]]+[]+({}+[])[+!![]]+ ([][![]]+[])[+!![]]+(![]+[])[!![]+!![]+!![]]+(!![]+[])[+![]]+(!![]+ [])[+!![]]+([][![]]+[])[+![]]+({}+[])[!![]+!![]+!![]+!![]+!![]]+(!! []+[])[+![]]+({}+[])[+!![]]+(!![]+[])[+!![]]])[(![]+[])[+![]]+[]+ ([][![]]+[])[!![]+!![]+!![]+!![]+!![]]+(![]+[])[!![]+!![]]+(!![]+ [])[+![]]+(!![]+[])[!![]+!![]+!![]]+(!![]+[])[+!![]]]([][({}+[])[!! []+!![]+!![]+!![]+!![]]+[]+({}+[])[+!![]]+([][![]]+[])[+!![]]+(![]+ [])[!![]+!![]+!![]]+(!![]+[])[+![]]+(!![]+[])[+!![]]+([][![]]+[]) [+![]]+({}+[])[!![]+!![]+!![]+!![]+!![]]+(!![]+[])[+![]]+({}+[]) [+!![]]+(!![]+[])[+!![]]][({}+[])[!![]+!![]+!![]+!![]+!![]]+[]+({}+
[])[+!![]]+([][![]]+[])[+!![]]+(![]+[])[!![]+!![]+!![]]+(!![]+[]) [+![]]+(!![]+[])[+!![]]+([][![]]+[])[+![]]+({}+[])[!![]+!![]+!![] +!![]+!![]]+(!![]+[])[+![]]+({}+[])[+!![]]+(!![]+[])[+!![]]]((!![]+ [])[+!![]]+[]+(!![]+[])[!![]+!![]+!![]]+(!![]+[])[+![]]+([][![]]+ [])[+![]]+(!![]+[])[+!![]]+([][![]]+[])[+!![]]+({}+[])[!![]+!![]+!! []+!![]+!![]+!![]+!![]]+([][![]]+[])[!![]+!![]+!![]+!![]+!![]]+(![] +[])[!![]+!![]+!![]]+(+[![]]))())[+(+!![]+[]+(+!![]))]+(!![]+[])[+! []]+(!![]+[])[+!![]]+([][![]]+[])[!![]+!![]+!![]+!![]+!![]]+([][! []]+[])[+!![]]+[][(![]+[])[!![]+!![]+!![]]+[]+(![]+[])[!![]+!![]]+ ([][![]]+[])[!![]+!![]+!![]+!![]+!![]]+({}+[])[!![]+!![]+!![]+!![]
+!![]]+(!![]+[])[!![]+!![]+!![]]][({}+[])[!![]+!![]+!![]+!![]+!![]] +[]+(![]+[])[+!![]]+(![]+[])[!![]+!![]]+(![]+[])[!![]+!![]]]((!![]+ [])[({}+[])[!![]+!![]+!![]+!![]+!![]]+[]+({}+[])[+!![]]+([][![]]+ [])[+!![]]+(![]+[])[!![]+!![]+!![]]+(!![]+[])[+![]]+(!![]+[])[+!! []]+([][![]]+[])[+![]]+({}+[])[!![]+!![]+!![]+!![]+!![]]+(!![]+[]) [+![]]+({}+[])[+!![]]+(!![]+[])[+!![]]]+[])[(![]+[])[+![]]+[]+([][! []]+[])[!![]+!![]+!![]+!![]+!![]]+(![]+[])[!![]+!![]]+(!![]+[])[+! []]+(!![]+[])[!![]+!![]+!![]]+(!![]+[])[+!![]]]([][({}+[])[!![]+!! []+!![]+!![]+!![]]+[]+({}+[])[+!![]]+([][![]]+[])[+!![]]+(![]+[]) [!![]+!![]+!![]]+(!![]+[])[+![]]+(!![]+[])[+!![]]+([][![]]+[])[+! []]+({}+[])[!![]+!![]+!![]+!![]+!![]]+(!![]+[])[+![]]+({}+[])[+!!
[]]+(!![]+[])[+!![]]][({}+[])[!![]+!![]+!![]+!![]+!![]]+[]+({}+[]) [+!![]]+([][![]]+[])[+!![]]+(![]+[])[!![]+!![]+!![]]+(!![]+[])[+! []]+(!![]+[])[+!![]]+([][![]]+[])[+![]]+({}+[])[!![]+!![]+!![]+!![] +!![]]+(!![]+[])[+![]]+({}+[])[+!![]]+(!![]+[])[+!![]]]((!![]+[]) [+!![]]+[]+(!![]+[])[!![]+!![]+!![]]+(!![]+[])[+![]]+([][![]]+[]) [+![]]+(!![]+[])[+!![]]+([][![]]+[])[+!![]]+({}+[])[!![]+!![]+!![] +!![]+!![]+!![]+!![]]+([][![]]+[])[!![]+!![]+!![]+!![]+!![]]+(![]+ [])[!![]+!![]+!![]]+(+[![]]))())[+(+!![]+[]+(!![]+!![]+!![]))]](+ (!![]+!![]+!![]+[]+(+![])))+(!![]+[])[+![]]) "javascript"
(({}+[])[!![]+!![]+!![]]+[]+(![]+[])[+!![]]+(+(!![]+!![]+!![]+[]+(+!![])))[(!![]+[])[+![]]+[]+({}+[])[+!![]]+[][(![]+[])[!![]+!![]+!![]]+[]+(![]+ [])[!![]+!![]]+([][![]]+[])[!![]+!![]+!![]+!![]+!![]]+({}+[])[!![]+!![]+!![]+!![]+!![]]+(!![]+[])[!![]+!![]+!![]]][({}+[])[!![]+!![]+!![]+!![]+!! []]+[]+(![]+[])[+!![]]+(![]+[])[!![]+!![]]+(![]+[])[!![]+!![]]](+[![]]+[]+(!![]+[])[({}+[])[!![]+!![]+!![]+!![]+!![]]+[]+({}+[])[+!![]]+([][![]]+ [])[+!![]]+(![]+[])[!![]+!![]+!![]]+(!![]+[])[+![]]+(!![]+[])[+!![]]+([][![]]+[])[+![]]+({}+[])[!![]+!![]+!![]+!![]+!![]]+(!![]+[])[+![]]+({}+[]) [+!![]]+(!![]+[])[+!![]]])[(![]+[])[+![]]+[]+([][![]]+[])[!![]+!![]+!![]+!![]+!![]]+(![]+[])[!![]+!![]]+(!![]+[])[+![]]+(!![]+[])[!![]+!![]+!![]]+ (!![]+[])[+!![]]]([][({}+[])[!![]+!![]+!![]+!![]+!![]]+[]+({}+[])[+!![]]+([][![]]+[])[+!![]]+(![]+[])[!![]+!![]+!![]]+(!![]+[])[+![]]+(!![]+[])[+!! []]+([][![]]+[])[+![]]+({}+[])[!![]+!![]+!![]+!![]+!![]]+(!![]+[])[+![]]+({}+[])[+!![]]+(!![]+[])[+!![]]][({}+[])[!![]+!![]+!![]+!![]+!![]]+[]+({}+ [])[+!![]]+([][![]]+[])[+!![]]+(![]+[])[!![]+!![]+!![]]+(!![]+[])[+![]]+(!![]+[])[+!![]]+([][![]]+[])[+![]]+({}+[])[!![]+!![]+!![]+!![]+!![]]+(!![] +[])[+![]]+({}+[])[+!![]]+(!![]+[])[+!![]]]((!![]+[])[+!![]]+[]+(!![]+[])[!![]+!![]+!![]]+(!![]+[])[+![]]+([][![]]+[])[+![]]+(!![]+[])[+!![]]+([][! []]+[])[+!![]]+({}+[])[!![]+!![]+!![]+!![]+!![]+!![]+!![]]+([][![]]+[])[!![]+!![]+!![]+!![]+!![]]+(![]+[])[!![]+!![]+!![]]+(+[![]]))())[+(+!![]+[]+
(+!![]))]+(!![]+[])[+![]]+(!![]+[])[+!![]]+([][![]]+[])[!![]+!![]+!![]+!![]+!![]]+([][![]]+[])[+!![]]+[][(![]+[])[!![]+!![]+!![]]+[]+(![]+[])[!![] +!![]]+([][![]]+[])[!![]+!![]+!![]+!![]+!![]]+({}+[])[!![]+!![]+!![]+!![]+!![]]+(!![]+[])[!![]+!![]+!![]]][({}+[])[!![]+!![]+!![]+!![]+!![]]+[]+(! []+[])[+!![]]+(![]+[])[!![]+!![]]+(![]+[])[!![]+!![]]]((!![]+[])[({}+[])[!![]+!![]+!![]+!![]+!![]]+[]+({}+[])[+!![]]+([][![]]+[])[+!![]]+(![]+[]) [!![]+!![]+!![]]+(!![]+[])[+![]]+(!![]+[])[+!![]]+([][![]]+[])[+![]]+({}+[])[!![]+!![]+!![]+!![]+!![]]+(!![]+[])[+![]]+({}+[])[+!![]]+(!![]+[])[+!! []]]+[])[(![]+[])[+![]]+[]+([][![]]+[])[!![]+!![]+!![]+!![]+!![]]+(![]+[])[!![]+!![]]+(!![]+[])[+![]]+(!![]+[])[!![]+!![]+!![]]+(!![]+[])[+!![]]] ([][({}+[])[!![]+!![]+!![]+!![]+!![]]+[]+({}+[])[+!![]]+([][![]]+[])[+!![]]+(![]+[])[!![]+!![]+!![]]+(!![]+[])[+![]]+(!![]+[])[+!![]]+([][![]]+[]) [+![]]+({}+[])[!![]+!![]+!![]+!![]+!![]]+(!![]+[])[+![]]+({}+[])[+!![]]+(!![]+[])[+!![]]][({}+[])[!![]+!![]+!![]+!![]+!![]]+[]+({}+[])[+!![]]+([][! []]+[])[+!![]]+(![]+[])[!![]+!![]+!![]]+(!![]+[])[+![]]+(!![]+[])[+!![]]+([][![]]+[])[+![]]+({}+[])[!![]+!![]+!![]+!![]+!![]]+(!![]+[])[+![]]+({}+ [])[+!![]]+(!![]+[])[+!![]]]((!![]+[])[+!![]]+[]+(!![]+[])[!![]+!![]+!![]]+(!![]+[])[+![]]+([][![]]+[])[+![]]+(!![]+[])[+!![]]+([][![]]+[])[+!![]]+ ({}+[])[!![]+!![]+!![]+!![]+!![]+!![]+!![]]+([][![]]+[])[!![]+!![]+!![]+!![]+!![]]+(![]+[])[!![]+!![]+!![]]+(+[![]]))())[+(+!![]+[]+(!![]+!![]+!! []))]](+(!![]+!![]+!![]+[]+(!![]+!![])))+(![]+[])[+!![]]+(![]+[])[!![]+!![]+!![]]+({}+[])[!![]+!![]+!![]+!![]+!![]]+(!![]+[])[+!![]]+([][![]]+[]) [!![]+!![]+!![]+!![]+!![]]+(+(!![]+!![]+[]+(!![]+!![]+!![]+!![]+!![])))[(!![]+[])[+![]]+[]+({}+[])[+!![]]+[][(![]+[])[!![]+!![]+!![]]+[]+(![]+[]) [!![]+!![]]+([][![]]+[])[!![]+!![]+!![]+!![]+!![]]+({}+[])[!![]+!![]+!![]+!![]+!![]]+(!![]+[])[!![]+!![]+!![]]][({}+[])[!![]+!![]+!![]+!![]+!![]]+ []+(![]+[])[+!![]]+(![]+[])[!![]+!![]]+(![]+[])[!![]+!![]]](+[![]]+[]+(!![]+[])[({}+[])[!![]+!![]+!![]+!![]+!![]]+[]+({}+[])[+!![]]+([][![]]+[]) [+!![]]+(![]+[])[!![]+!![]+!![]]+(!![]+[])[+![]]+(!![]+[])[+!![]]+([][![]]+[])[+![]]+({}+[])[!![]+!![]+!![]+!![]+!![]]+(!![]+[])[+![]]+({}+[])[+!! []]+(!![]+[])[+!![]]])[(![]+[])[+![]]+[]+([][![]]+[])[!![]+!![]+!![]+!![]+!![]]+(![]+[])[!![]+!![]]+(!![]+[])[+![]]+(!![]+[])[!![]+!![]+!![]]+(!![] +[])[+!![]]]([][({}+[])[!![]+!![]+!![]+!![]+!![]]+[]+({}+[])[+!![]]+([][![]]+[])[+!![]]+(![]+[])[!![]+!![]+!![]]+(!![]+[])[+![]]+(!![]+[])[+!![]]+ ([][![]]+[])[+![]]+({}+[])[!![]+!![]+!![]+!![]+!![]]+(!![]+[])[+![]]+({}+[])[+!![]]+(!![]+[])[+!![]]][({}+[])[!![]+!![]+!![]+!![]+!![]]+[]+({}+[]) [+!![]]+([][![]]+[])[+!![]]+(![]+[])[!![]+!![]+!![]]+(!![]+[])[+![]]+(!![]+[])[+!![]]+([][![]]+[])[+![]]+({}+[])[!![]+!![]+!![]+!![]+!![]]+(!![]+ [])[+![]]+({}+[])[+!![]]+(!![]+[])[+!![]]]((!![]+[])[+!![]]+[]+(!![]+[])[!![]+!![]+!![]]+(!![]+[])[+![]]+([][![]]+[])[+![]]+(!![]+[])[+!![]]+([][! []]+[])[+!![]]+({}+[])[!![]+!![]+!![]+!![]+!![]+!![]+!![]]+([][![]]+[])[!![]+!![]+!![]+!![]+!![]]+(![]+[])[!![]+!![]+!![]]+(+[![]]))())[+(+!![]+[]+ (+!![]))]+(!![]+[])[+![]]+(!![]+[])[+!![]]+([][![]]+[])[!![]+!![]+!![]+!![]+!![]]+([][![]]+[])[+!![]]+[][(![]+[])[!![]+!![]+!![]]+[]+(![]+[])[!![] +!![]]+([][![]]+[])[!![]+!![]+!![]+!![]+!![]]+({}+[])[!![]+!![]+!![]+!![]+!![]]+(!![]+[])[!![]+!![]+!![]]][({}+[])[!![]+!![]+!![]+!![]+!![]]+[]+(! []+[])[+!![]]+(![]+[])[!![]+!![]]+(![]+[])[!![]+!![]]]((!![]+[])[({}+[])[!![]+!![]+!![]+!![]+!![]]+[]+({}+[])[+!![]]+([][![]]+[])[+!![]]+(![]+[]) [!![]+!![]+!![]]+(!![]+[])[+![]]+(!![]+[])[+!![]]+([][![]]+[])[+![]]+({}+[])[!![]+!![]+!![]+!![]+!![]]+(!![]+[])[+![]]+({}+[])[+!![]]+(!![]+[])[+!! []]]+[])[(![]+[])[+![]]+[]+([][![]]+[])[!![]+!![]+!![]+!![]+!![]]+(![]+[])[!![]+!![]]+(!![]+[])[+![]]+(!![]+[])[!![]+!![]+!![]]+(!![]+[])[+!![]]] ([][({}+[])[!![]+!![]+!![]+!![]+!![]]+[]+({}+[])[+!![]]+([][![]]+[])[+!![]]+(![]+[])[!![]+!![]+!![]]+(!![]+[])[+![]]+(!![]+[])[+!![]]+([][![]]+[]) [+![]]+({}+[])[!![]+!![]+!![]+!![]+!![]]+(!![]+[])[+![]]+({}+[])[+!![]]+(!![]+[])[+!![]]][({}+[])[!![]+!![]+!![]+!![]+!![]]+[]+({}+[])[+!![]]+([][! []]+[])[+!![]]+(![]+[])[!![]+!![]+!![]]+(!![]+[])[+![]]+(!![]+[])[+!![]]+([][![]]+[])[+![]]+({}+[])[!![]+!![]+!![]+!![]+!![]]+(!![]+[])[+![]]+({}+ [])[+!![]]+(!![]+[])[+!![]]]((!![]+[])[+!![]]+[]+(!![]+[])[!![]+!![]+!![]]+(!![]+[])[+![]]+([][![]]+[])[+![]]+(!![]+[])[+!![]]+([][![]]+[])[+!![]]+ ({}+[])[!![]+!![]+!![]+!![]+!![]+!![]+!![]]+([][![]]+[])[!![]+!![]+!![]+!![]+!![]]+(![]+[])[!![]+!![]+!![]]+(+[![]]))())[+(+!![]+[]+(!![]+!![]+!! []))]](+(!![]+!![]+!![]+[]+(+![])))+(!![]+[])[+![]])
None