├── .gitignore ├── .istanbul.yml ├── .travis.yml ├── LICENSE ├── README.markdown ├── favicon.ico ├── index.html ├── package.json ├── tests.js ├── thermite.js └── thermite.min.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | coverage 3 | bundle.js 4 | .zuulrc 5 | -------------------------------------------------------------------------------- /.istanbul.yml: -------------------------------------------------------------------------------- 1 | instrumentation: 2 | excludes: [tests.js] 3 | check: 4 | global: 5 | statements: 100 6 | lines: 100 7 | branches: 100 8 | functions: 100 9 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - stable 4 | after_script: 5 | - npm run-script cover 6 | - npm run-script coveralls 7 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 omphalos 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /README.markdown: -------------------------------------------------------------------------------- 1 | Thermite 2 | ======== 3 | 4 | [![Build Status](https://secure.travis-ci.org/omphalos/thermite.png) 5 | ](http://travis-ci.org/omphalos/thermite) 6 | [![Coverage](https://coveralls.io/repos/omphalos/thermite/badge.svg) 7 | ](https://coveralls.io/github/omphalos/thermite) 8 | 9 | Thermite gives you an API for programmatically live reloading code. 10 | 11 | Its main purpose is to act like a library used by 12 | development and (experimentally) deployment tools. 13 | 14 | Comparison with native browser live code reloading 15 | -------------------------------------------------- 16 | 17 | I love native browser live code reloading and use it in normal development. 18 | Nevertheless there are advantages to doing live code reloading with a library. 19 | 20 | * Most runtimes currently do not support live code reloading, 21 | so on many browsers, 22 | if you want this feature, 23 | you're out of luck. 24 | * Browsers that do support this 25 | don't offer direct access to this feature 26 | from inside your program. 27 | 28 | Thermite doesn't have these restrictions. 29 | 30 | I'm not complaining about native browser reloading - I think it's great. 31 | But I think there's utility 32 | in having a library that gives you 33 | direct programmatic access to hot code swapping cross browser. 34 | 35 | Demo 36 | ---- 37 | 38 | The demo is [here](https://omphalos.github.io/thermite). 39 | 40 | Check it out! 41 | 42 | Set Up 43 | ------ 44 | 45 | If you are using Node, first, `npm install thermite`, 46 | then `var thermite = require('thermite')` 47 | 48 | If you are using the browser, use thermite.min.js. 49 | `thermite` is exposed as a global variable. 50 | Or just use browserify. 51 | 52 | Basic usage 53 | ----------- 54 | 55 | var hotSwappableCode = thermite.eval('(' + function() { 56 | document.addEventListener("mousemove", function(evt) { 57 | console.log(evt.clientX * evt.clientY) 58 | }) 59 | } + ')()') 60 | 61 | hotSwappableCode.hotSwap('(' + function() { 62 | document.addEventListener("mousemove", function(evt) { 63 | console.log(evt.clientX + evt.clientY) 64 | }) 65 | } + ')()') 66 | 67 | Calling `hotSwap` here doesn't add a second event listener to the DOM. 68 | It effectively replaces the reference to the event listener stored in the DOM 69 | with a new one. 70 | 71 | How it works 72 | ------------ 73 | 74 | Thermite works by rewriting code 75 | and proxying each function. 76 | 77 | Additionally it stores the initial version of your code in a map. 78 | 79 | When you call `hotSwap`, 80 | thermite runs a diff to identify how functions change. 81 | It uses this diff to update the map. 82 | 83 | Whenever a function runs, it checks its version. 84 | When a function finds that its version is lower than the one in the map, 85 | it `evals` the new function (creating it in the proper scope). 86 | 87 | License 88 | ------- 89 | 90 | MIT 91 | -------------------------------------------------------------------------------- /favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omphalos/thermite/b1d7a4f100c6b2122adb8211a18c049e7af5d116/favicon.ico -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 43 | 44 | 45 | 46 | 69 |
Hot Swap
70 | GitHub 72 |
73 | 83 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "thermite", 3 | "version": "0.0.8", 4 | "description": "JavaScript live code reloading utility for Node and browsers", 5 | "main": "thermite.js", 6 | "repository": { 7 | "type": "git", 8 | "url": "https://github.com/omphalos/thermite" 9 | }, 10 | "keywords": [ 11 | "JavaScript", 12 | "hot-swap", 13 | "hot-load", 14 | "hot-reload", 15 | "live-reload", 16 | "live-edit", 17 | "instrumentation", 18 | "ast", 19 | "abstract-syntax-tree", 20 | "swap", 21 | "swapping", 22 | "hot-swapping", 23 | "livereload", 24 | "reload", 25 | "live" 26 | ], 27 | "author": "omphalos", 28 | "license": "MIT", 29 | "bugs": { 30 | "url": "https://github.com/omphalos/thermite/issues" 31 | }, 32 | "homepage": "https://github.com/omphalos/thermite", 33 | "dependencies": { 34 | "falafel": "1.2.0", 35 | "googlediff": "0.1.0", 36 | "survivor": "^0.0.3" 37 | }, 38 | "devDependencies": { 39 | "browserify": "13.1.1", 40 | "bumpt": "0.0.4", 41 | "coveralls": "2.11.4", 42 | "istanbul": "0.3.19", 43 | "minilint": "0.0.12", 44 | "mocha": "3.1.2", 45 | "nodemon": "1.4.1", 46 | "uglifyjs": "2.4.10" 47 | }, 48 | "scripts": { 49 | "test": "npm run lint && npm run mocha && npm run cover-and-check", 50 | "mocha": "mocha ./tests.js", 51 | "watch": "nodemon -x 'mocha ./tests.js'", 52 | "check-coverage": "istanbul check-coverage coverage/coverage.json", 53 | "cover-and-check": "npm run cover && npm run check-coverage", 54 | "cover": "istanbul cover _mocha -- ./tests.js", 55 | "coveralls": "cat ./coverage/lcov.info | coveralls", 56 | "lint": "minilint", 57 | "bundle": "browserify thermite.js -s thermite > bundle.js", 58 | "minify": "cat bundle.js | uglifyjs > thermite.min.js", 59 | "count": "gzip -c thermite.min.js | wc -c", 60 | "build": "npm run bundle; npm run minify; npm run count; rm bundle.js", 61 | "release": "npm run build; npm run test; bumpt" 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /tests.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | 'use strict' 4 | 5 | var assert = require('assert') 6 | var thermite = require('./thermite.js') 7 | 8 | it('should should eval raw JavaScript', function() { 9 | assert.equal(thermite.eval('123').result, 123) 10 | }) 11 | 12 | it('should eval an anonymous function', function() { 13 | var fn = thermite.eval('(function() { return 123 })').result 14 | assert.equal(fn(), 123) 15 | }) 16 | 17 | it('should eval a named function', function() { 18 | var fn = thermite.eval('(function x() { return 123 })').result 19 | assert.equal(fn(), 123) 20 | assert.equal(fn.name, 'x') 21 | }) 22 | 23 | it('should eval in scope', function() { 24 | var x = 123 25 | thermite.eval('x = 5', { 26 | eval: function(code) { return eval(code) } 27 | }) 28 | assert.equal(x, 5) 29 | }) 30 | 31 | it('should replace functions', function() { 32 | var target = thermite.eval('(function noop() {})') 33 | target.hotSwap('(function add(x, y) { return x + y })') 34 | assert.equal(target.result(2, 3), 5) 35 | }) 36 | 37 | it('should replace multiline functions', function() { 38 | var target = thermite.eval('(function noop() {})') 39 | target.hotSwap('(function add(x, y) { return x + y })') 40 | assert.equal(target.result(2, 3), 5) 41 | }) 42 | 43 | it('should hotSwap function references', function() { 44 | var target = thermite.eval('(function() {})') 45 | var savedReference = target.result 46 | target.hotSwap('(function add(x, y) { return x + y })') 47 | assert.equal(savedReference(2, 3), 5) 48 | }) 49 | 50 | it('should hotSwap recursive-style function references', function() { 51 | var target = thermite.eval('(function length(x) {\n' 52 | + ' return x ? rec(x.tail) + 1 : 0\n' 53 | + '})') 54 | var savedReference = target.result 55 | target.hotSwap('(function length(x) {\n' 56 | + ' return x ? length(x.tail) + 1 : 100\n' 57 | + '})') 58 | assert.equal(savedReference({ tail: { tail: {} } }), 103) 59 | }) 60 | 61 | it('should hot swap nested functions', function() { 62 | var target = thermite.eval('(function outer() {\n' 63 | + ' return "outer-" + inner()\n' 64 | + ' function inner() { return "inner" }\n' 65 | + '})') 66 | var savedReference = target.result 67 | target.hotSwap('(function outer() {\n' 68 | + ' return "outerChanged-" + inner()\n' 69 | + ' function inner() { return "innerChanged" }\n' 70 | + '})') 71 | assert.equal(savedReference(), 'outerChanged-innerChanged') 72 | }) 73 | 74 | it('should hot swap nested function twice', function() { 75 | var target = thermite.eval('(' + function outer() { 76 | return function inner() {} 77 | } + ')') 78 | 79 | target.hotSwap('(' + function outer() { 80 | return function inner() { return 'a' } 81 | } + ')') 82 | var callback = target.result() 83 | 84 | target.hotSwap('(' + function outer() { 85 | return function inner() { return 'b' } 86 | } + ')') 87 | 88 | assert.equal(callback(), 'b') 89 | }) 90 | 91 | it('should hot swap callbacks twice', function() { 92 | var state = {} 93 | var callback = null 94 | function setCallback(f) { callback = f } 95 | 96 | var target = thermite.eval('(' + function outer(state) { 97 | return 0 98 | } + ')') 99 | 100 | target.hotSwap('(' + function outer(state, setCallback) { 101 | setCallback(function inner() { 102 | state.value = 1 103 | }) 104 | } + ')') 105 | target.result(state, setCallback) 106 | callback() 107 | 108 | target.hotSwap('(' + function outer(state, setCallback) { 109 | setCallback(function inner() { 110 | state.value = 2 111 | }) 112 | } + ')') 113 | callback() 114 | 115 | assert.equal(state.value, 2) 116 | }) 117 | 118 | it('should add functions', function() { 119 | var target = thermite.eval('(function outer() {\n' 120 | + ' return function inner() {}\n' 121 | + '})') 122 | var outer = target.result 123 | target.hotSwap('(function outer() {\n' 124 | + ' return function inner1() {\n' 125 | + ' return function inner2() { return "inner2Result" }\n' 126 | + ' }\n' 127 | + '})') 128 | var inner1 = outer() 129 | var inner2 = inner1() 130 | var inner2Result = inner2() 131 | assert.equal(inner2Result, 'inner2Result') 132 | }) 133 | 134 | it('should hotSwap added functions', function() { 135 | var target = thermite.eval('(function outer() {\n' 136 | + ' return function inner() {}\n' 137 | + '})') 138 | var outer = target.result 139 | target.hotSwap('(function outer() {\n' 140 | + ' return function inner1() {\n' 141 | + ' return function inner2() { return "inner2Result" }\n' 142 | + ' }\n' 143 | + '})') 144 | target.hotSwap('(function outer() {\n' 145 | + ' return function inner1() {\n' 146 | + ' return function inner2() { return "inner2ResultChanged" }\n' 147 | + ' }\n' 148 | + '})') 149 | var inner1 = outer() 150 | var inner2 = inner1() 151 | var inner2Result = inner2() 152 | assert.equal(inner2Result, 'inner2ResultChanged') 153 | }) 154 | 155 | it('should hotSwap added functions 10 times', function() { 156 | var target = thermite.eval('(function outer() {\n' 157 | + ' return function inner() {}\n' 158 | + '})') 159 | var outer = target.result 160 | for(var i = 0; i < 10; i++) 161 | target.hotSwap('(function outer() {\n' 162 | + ' return function inner1() {\n' 163 | + ' return function inner2() { return ' + i + ' }\n' 164 | + ' }\n' 165 | + '})') 166 | var inner1 = outer() 167 | var inner2 = inner1() 168 | var inner2Result = inner2() 169 | assert.equal(inner2Result, 9) 170 | }) 171 | 172 | it('should hotSwap function twice', function() { 173 | var target = thermite.eval('(function outer() {\n' 174 | + ' return function inner() {}\n' 175 | + '})') 176 | var outer = target.result 177 | target.hotSwap('(function outer() {\n' 178 | + ' return function inner() { return 1 }\n' 179 | + '})') 180 | target.hotSwap('(function outer() {\n' 181 | + ' return function inner() { return 2 }\n' 182 | + '})') 183 | var inner = outer() 184 | assert.equal(inner(), 2) 185 | }) 186 | 187 | it('should hotSwap 10 times', function() { 188 | var target = thermite.eval('(function outer() {\n' 189 | + ' return function inner() {}\n' 190 | + '})') 191 | var outer = target.result 192 | for(var i = 0; i < 10; i++) 193 | target.hotSwap('(function outer() {\n' 194 | + ' return function inner() { return ' + i + ' }\n' 195 | + '})') 196 | var inner = outer() 197 | assert.equal(inner(), 9) // The last value of `i` is 9. 198 | }) 199 | 200 | it('should hotSwap member functions', function() { 201 | var target = thermite.eval('(function() {\n' 202 | + ' return { fn: function() {} }\n' 203 | + '})') 204 | var fn = target.result().fn 205 | target.hotSwap('(function() {\n' 206 | + ' return { fn: function() { return "hotSwapped" } }\n' 207 | + '})') 208 | assert.equal(fn(), 'hotSwapped') 209 | }) 210 | 211 | it('should hotSwap all copies of a function', function() { 212 | var target = thermite.eval('(function() {\n' 213 | + ' return function() {}\n' 214 | + '})') 215 | var fn1 = target.result() 216 | var fn2 = target.result() 217 | target.hotSwap('(function() {\n' 218 | + ' return function() { return "hotSwapped" }\n' 219 | + '})') 220 | assert.equal(fn1(), 'hotSwapped') 221 | assert.equal(fn2(), 'hotSwapped') 222 | }) 223 | 224 | it('should hotSwap recursive function references', function() { 225 | var recursiveReference 226 | 227 | var target = thermite.eval('(function rec(x) {\n' 228 | + ' return x ? rec(x.tail) + 1 : 0\n' 229 | + '})') 230 | 231 | // Call the function so that recursiveReference gets set 232 | var recursiveReference = target.result 233 | 234 | // Replace this with a new calculation 235 | target.hotSwap('(function rec(x) {\n' 236 | + ' return x ? rec(x.tail) + 1 : 100\n' 237 | + '})') 238 | 239 | assert.equal(recursiveReference({ tail: { tail: {} } }), 103) 240 | }) 241 | 242 | it('should propagate parse error', function() { 243 | var originalLog = console.log 244 | var logs = [] 245 | console.log = logs.push.bind(logs) 246 | try { 247 | try { 248 | thermite.eval('1.1.1') 249 | } finally { 250 | console.log = originalLog 251 | } 252 | } catch(err) { 253 | assert.equal(logs[0], 'Error parsing source:') 254 | assert.equal(logs[1], '1.1.1') 255 | return 256 | } 257 | assert.fail('failed to propagate error') 258 | }) 259 | 260 | it('should propagate parse error during hotSwap', function() { 261 | var target = thermite.eval('1.1') 262 | var originalLog = console.log 263 | var logs = [] 264 | console.log = logs.push.bind(logs) 265 | try { 266 | try { 267 | target.hotSwap('1.1.1') 268 | } finally { 269 | console.log = originalLog 270 | } 271 | } catch(err) { 272 | assert.equal(logs[0], 'Error parsing source:') 273 | assert.equal(logs[1], '1.1.1') 274 | return 275 | } 276 | assert.fail('failed to propagate error') 277 | }) 278 | 279 | it('should propagate runtime error', function() { 280 | var originalLog = console.log 281 | var logs = [] 282 | console.log = logs.push.bind(logs) 283 | try { 284 | try { 285 | thermite.eval('a.b.c') 286 | } finally { 287 | console.log = originalLog 288 | } 289 | } catch(err) { 290 | assert.equal(logs[0], 'Error evaling code:') 291 | assert.equal(logs[1], 'a.b.c') 292 | return 293 | } 294 | assert.fail('failed to propagate error') 295 | }) 296 | 297 | it('should handle changing declaration to expression', function() { 298 | var target = thermite.eval('(function() {\n' 299 | + ' function fn(a, b) {\n' 300 | + ' return a + b\n' 301 | + ' }\n' 302 | + ' return fn\n' 303 | + '})()') 304 | var fn = target.result 305 | target.hotSwap('(function() {\n' 306 | + ' var fn = function(a, b) {\n' 307 | + ' return a * b\n' 308 | + ' }\n' 309 | + ' return fn\n' 310 | + '})()') 311 | assert.equal(fn(2, 3), 6) 312 | }) 313 | 314 | it('should handle changing expression to declaration', function() { 315 | var target = thermite.eval('(function() {\n' 316 | + ' var fn = function(a, b) {\n' 317 | + ' return a * b\n' 318 | + ' }\n' 319 | + ' return fn\n' 320 | + '})()') 321 | var fn = target.result 322 | target.hotSwap('(function() {\n' 323 | + ' function fn(a, b) {\n' 324 | + ' return a + b\n' 325 | + ' }\n' 326 | + ' return fn\n' 327 | + '})()') 328 | assert.equal(fn(2, 3), 5) 329 | }) 330 | 331 | it('should preserve deleted functions', function() { 332 | var target = thermite.eval('(function() {\n' 333 | + ' return function() { return "hello" }\n' 334 | + '})()') 335 | var fn = target.result 336 | target.hotSwap('(function() {\n' 337 | + ' return\n' 338 | + '})()') 339 | assert.equal(fn(), 'hello') 340 | }) 341 | 342 | it('should update multiple expressions', function() { 343 | var target = thermite.eval('(function() {\n' 344 | + ' var a = function() { return "a" }\n' 345 | + ' var b = function() { return "b" }\n' 346 | + ' return { a: a, b: b }\n' 347 | + '})()') 348 | var fns = target.result 349 | target.hotSwap('(function() {\n' 350 | + ' var a = function() { return "a1" }\n' 351 | + ' var b = function() { return "b1" }\n' 352 | + ' return { a: a, b: b }\n' 353 | + '})()') 354 | assert.equal(fns.a(), 'a1') 355 | assert.equal(fns.b(), 'b1') 356 | }) 357 | 358 | it('should update multiple declarations', function() { 359 | var target = thermite.eval('(function() {\n' 360 | + ' return { a: a, b: b }\n' 361 | + ' function a() { return "a" }\n' 362 | + ' function b() { return "b" }\n' 363 | + '})()') 364 | var fns = target.result 365 | target.hotSwap('(function() {\n' 366 | + ' return { a: a, b: b }\n' 367 | + ' function a() { return "a1" }\n' 368 | + ' function b() { return "b1" }\n' 369 | + '})()') 370 | assert.equal(fns.a(), 'a1') 371 | assert.equal(fns.b(), 'b1') 372 | }) 373 | 374 | it('should cache function expressions', function() { 375 | var target = thermite.eval('(function() { return 1 })') 376 | shouldCache(assert, target, null, 1) 377 | }) 378 | 379 | it('should cache function declarations', function() { 380 | var target = thermite.eval('(function() {\n' 381 | + ' return x\n' 382 | + ' function x() { return 1 }\n' 383 | + '})()') 384 | shouldCache(assert, target, null, 1) 385 | }) 386 | 387 | it('should cache recursive function expressions', function() { 388 | var target = thermite.eval('(function factorial(n) {\n' 389 | + ' return n <= 1 ? 1 : factorial(n - 1) * n\n' 390 | + '})') 391 | shouldCache(assert, target, 3, 6) 392 | }) 393 | 394 | it('should cache recursive function declarations', function() { 395 | var target = thermite.eval('(function() {\n' 396 | + ' return factorial\n' 397 | + ' function factorial(n) {\n' 398 | + ' return n <= 1 ? 1 : factorial(n - 1) * n\n' 399 | + ' }\n' 400 | + '})()') 401 | shouldCache(assert, target, 3, 6) 402 | }) 403 | 404 | it('should not swap deleted functions', function() { 405 | var target = thermite.eval('(function() {\n' 406 | + ' return function() { return 1 }\n' 407 | + '})') 408 | var fn1 = target.result() 409 | target.hotSwap('(function() {\n' 410 | + ' return\n' 411 | + '})') 412 | target.hotSwap('(function() {\n' 413 | + ' return function() { return 2 }\n' 414 | + '})') 415 | var fn2 = target.result() 416 | assert.equal(fn1(), 1) 417 | assert.equal(fn2(), 2) 418 | }) 419 | 420 | it('should swap classes', function() { 421 | var target = thermite.eval('(function() {\n' 422 | + ' function X() { this.a = 1 }\n' 423 | + ' X.prototype.b = function() { return 3 }\n' 424 | + ' return X\n' 425 | + '})()') 426 | var X = target.result 427 | target.hotSwap('(function() {\n' 428 | + ' function X() { this.a = 2 }\n' 429 | + ' X.prototype.b = function() { return 4 }\n' 430 | + ' return X\n' 431 | + '})()') 432 | var instance = new X 433 | assert.equal(instance.a, 2) 434 | assert.equal(instance.b(), 4) 435 | }) 436 | 437 | it('should swap base classes', function() { 438 | var target = thermite.eval('(function() {\n' 439 | + ' function Parent() { this.x = 1 }\n' 440 | + ' Parent.prototype.a = function() { return 2 }\n' 441 | + ' function Child() {\n' 442 | + ' Parent.call(this)\n' 443 | + ' this.y = 3\n' 444 | + ' }\n' 445 | + ' Child.prototype = Object.create(Parent.prototype)\n' 446 | + ' return Child\n' 447 | + '})()') 448 | var Child = target.result 449 | target.hotSwap('(function() {\n' 450 | + ' function Parent() { this.x = 10 }\n' 451 | + ' Parent.prototype.a = function() { return 20 }\n' 452 | + ' function Child() {\n' 453 | + ' Parent.call(this)\n' 454 | + ' this.y = 30\n' 455 | + ' }\n' 456 | + ' Child.prototype = Object.create(Parent.prototype)\n' 457 | + ' return Child\n' 458 | + '})()') 459 | var instance = new Child 460 | assert.equal(instance.x, 10) 461 | assert.equal(instance.a(), 20) 462 | assert.equal(instance.y, 30) 463 | }) 464 | 465 | it('should preserve bizarre constructor semantics of JavaScript', function() { 466 | var target1 = thermite.eval('(function X() {\n' 467 | + ' this.a = 1\n' 468 | + ' return "string"\n' 469 | + '})') 470 | var X = target1.result 471 | assert.equal(new X() instanceof X, true) 472 | var target2 = thermite.eval('(function Y() {\n' 473 | + ' this.a = 1\n' 474 | + ' return { b: 2 }\n' 475 | + '})') 476 | var Y = target2.result 477 | assert.equal(new Y() instanceof Y, false) 478 | }) 479 | 480 | function shouldCache(assert, target, arg, expected) { 481 | assert.equal(target.result(arg), expected) 482 | var originalEval = global.eval 483 | try { 484 | global.eval = assert.fail 485 | assert.equal(target.result(arg), expected) 486 | } finally { 487 | global.eval = originalEval 488 | } 489 | } 490 | -------------------------------------------------------------------------------- /thermite.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | var falafel = require('falafel') 4 | var DiffMatchPatch = require('googlediff') 5 | var survivor = require('survivor') 6 | var functionNodeTypes = ['FunctionExpression', 'FunctionDeclaration'] 7 | var blockIDCounter = new Counter('f') 8 | var contextIDCounter = new Counter('c') 9 | 10 | var template = ['function $thermiteTemplate() {', 11 | '', 12 | 'if(__thermiteMap.$thermiteContextID.$thermiteBlockID.codeVersion >', 13 | ' (__thermiteFunctionVersion_$thermiteBlockID || -1)) {', 14 | '', 15 | ' __thermiteFunction_$thermiteBlockID =', 16 | ' eval(__thermiteMap.$thermiteContextID.$thermiteBlockID.code)', 17 | '', 18 | ' __thermiteFunctionVersion_$thermiteBlockID =', 19 | ' __thermiteMap.$thermiteContextID.$thermiteBlockID.codeVersion', 20 | '}', 21 | '', 22 | 'return __thermiteFunction_$thermiteBlockID.apply(this, arguments)', 23 | '', 24 | '}'].join('\n') 25 | 26 | global.__thermiteMap = {} 27 | 28 | function Counter(label) { 29 | this.label = label 30 | this.value = 0 31 | } 32 | 33 | Counter.prototype.getNextID = function() { 34 | return this.label + (this.value++) 35 | } 36 | 37 | function thermiteEval(source, options) { 38 | 39 | options = options || {} 40 | var fnTree = {} 41 | var state = { 42 | contextID: contextIDCounter.getNextID(), 43 | lastSource: source, 44 | doLineDiff: options.lineDiff || false, 45 | version: 1 46 | } 47 | 48 | var rewritten = forEachNode(source, function(node) { 49 | if(functionNodeTypes.indexOf(node.type) < 0) return 50 | var blockID = blockIDCounter.getNextID() 51 | rewriteNode(state.contextID, blockID, state.version, node) 52 | }).toString() 53 | 54 | return { 55 | hotSwap: function(source) { return hotSwap(state, source) }, 56 | result: invokeEval(options.eval || eval, rewritten) 57 | } 58 | } 59 | 60 | function hotSwap(state, source) { 61 | 62 | state.version++ 63 | 64 | var version = state.version 65 | var contextID = state.contextID 66 | var dmp = new DiffMatchPatch() 67 | var diffs = dmp.diff_main(state.lastSource, source, state.doLineDiff) 68 | var lookup = survivor(diffs, true) 69 | var entries = getEntriesForContext(contextID) 70 | var entriesByRangeString = {} 71 | var persistedBlockIDs = {} 72 | 73 | for(var blockID in entries) { 74 | var entry = entries[blockID] 75 | if(entry.deleted) continue 76 | var rangeString = rangeToString(entry.node.range) 77 | entriesByRangeString[rangeString] = entry 78 | } 79 | 80 | forEachNode(source, function(node) { 81 | if(functionNodeTypes.indexOf(node.type) < 0) return 82 | var startSurvived = lookup(node.range[0]) 83 | var endSurvived = lookup(node.range[1]) 84 | var existingEntry = startSurvived 85 | && endSurvived 86 | && entriesByRangeString[rangeToString([startSurvived, endSurvived])] 87 | var blockID = existingEntry 88 | ? existingEntry.blockID 89 | : blockIDCounter.getNextID() 90 | rewriteNode(contextID, blockID, version, node) 91 | persistedBlockIDs[blockID] = true 92 | }) 93 | 94 | for(var blockID in entries) 95 | if(!(blockID in persistedBlockIDs)) 96 | entries[blockID].deleted = true 97 | 98 | state.lastSource = source 99 | } 100 | 101 | function getEntriesForContext(contextID) { 102 | return __thermiteMap[contextID] = __thermiteMap[contextID] || {} 103 | } 104 | 105 | function invokeEval(evaler, code) { 106 | try { 107 | return evaler(code) 108 | } catch(err) { 109 | console.log('Error evaling code:') 110 | console.log(code) 111 | throw err 112 | } 113 | } 114 | 115 | function forEachNode(source, visitor) { 116 | try { 117 | return falafel(source, { ranges: true }, visitor) 118 | } catch(err) { 119 | console.log('Error parsing source:') 120 | console.log(source) 121 | throw err 122 | } 123 | } 124 | 125 | function rewriteNode(contextID, blockID, version, node) { 126 | var code = node.source() 127 | var name = '' 128 | // Strip out the name (to handle recursive references) 129 | if(node.id && node.id.name) { 130 | name = node.id.name 131 | code = code.replace(name, '') 132 | node.update(code) 133 | } 134 | var addVersionTo = { 135 | FunctionDeclaration: addVersionToDeclaration, 136 | FunctionExpression: addVersionToExpression 137 | } 138 | var boundTemplate = addVersionTo[node.type](template, name) 139 | .replace(/\$thermiteTemplate/g, name) 140 | .replace(/\$thermiteBlockID/g, blockID) 141 | .replace(/\$thermiteContextID/g, contextID) 142 | node.update(boundTemplate) 143 | var rewritten = '(' + code + ')' 144 | var entries = getEntriesForContext(contextID) 145 | entries[blockID] = { 146 | blockID: blockID, 147 | node: node, 148 | codeVersion: version, 149 | code: rewritten 150 | } 151 | } 152 | 153 | function addVersionToDeclaration(template, name) { 154 | return '; ' 155 | + 'var __thermiteFunctionVersion_$thermiteBlockID; ' 156 | + 'var __thermiteFunction_$thermiteBlockID; ' 157 | + template 158 | } 159 | 160 | function addVersionToExpression(template, name) { 161 | return '(function ' + name + '() { ' 162 | + 'var __thermiteFunctionVersion_$thermiteBlockID; ' 163 | + 'var __thermiteFunction_$thermiteBlockID; ' 164 | + 'return (' + template + ');' 165 | + '})()' 166 | } 167 | 168 | function rangeToString(range) { 169 | return 'from' + range[0] + 'to' + range[1] 170 | } 171 | 172 | exports.eval = thermiteEval 173 | 174 | -------------------------------------------------------------------------------- /thermite.min.js: -------------------------------------------------------------------------------- 1 | (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.thermite=f()}})(function(){var define,module,exports;return function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o=len)return x;switch(x){case"%s":return String(args[i++]);case"%d":return Number(args[i++]);case"%j":try{return JSON.stringify(args[i++])}catch(_){return"[Circular]"}default:return x}});for(var x=args[i];i=3)ctx.depth=arguments[2];if(arguments.length>=4)ctx.colors=arguments[3];if(isBoolean(opts)){ctx.showHidden=opts}else if(opts){exports._extend(ctx,opts)}if(isUndefined(ctx.showHidden))ctx.showHidden=false;if(isUndefined(ctx.depth))ctx.depth=2;if(isUndefined(ctx.colors))ctx.colors=false;if(isUndefined(ctx.customInspect))ctx.customInspect=true;if(ctx.colors)ctx.stylize=stylizeWithColor;return formatValue(ctx,obj,ctx.depth)}exports.inspect=inspect;inspect.colors={bold:[1,22],italic:[3,23],underline:[4,24],inverse:[7,27],white:[37,39],grey:[90,39],black:[30,39],blue:[34,39],cyan:[36,39],green:[32,39],magenta:[35,39],red:[31,39],yellow:[33,39]};inspect.styles={special:"cyan",number:"yellow","boolean":"yellow",undefined:"grey","null":"bold",string:"green",date:"magenta",regexp:"red"};function stylizeWithColor(str,styleType){var style=inspect.styles[styleType];if(style){return"["+inspect.colors[style][0]+"m"+str+"["+inspect.colors[style][1]+"m"}else{return str}}function stylizeNoColor(str,styleType){return str}function arrayToHash(array){var hash={};array.forEach(function(val,idx){hash[val]=true});return hash}function formatValue(ctx,value,recurseTimes){if(ctx.customInspect&&value&&isFunction(value.inspect)&&value.inspect!==exports.inspect&&!(value.constructor&&value.constructor.prototype===value)){var ret=value.inspect(recurseTimes,ctx);if(!isString(ret)){ret=formatValue(ctx,ret,recurseTimes)}return ret}var primitive=formatPrimitive(ctx,value);if(primitive){return primitive}var keys=Object.keys(value);var visibleKeys=arrayToHash(keys);if(ctx.showHidden){keys=Object.getOwnPropertyNames(value)}if(isError(value)&&(keys.indexOf("message")>=0||keys.indexOf("description")>=0)){return formatError(value)}if(keys.length===0){if(isFunction(value)){var name=value.name?": "+value.name:"";return ctx.stylize("[Function"+name+"]","special")}if(isRegExp(value)){return ctx.stylize(RegExp.prototype.toString.call(value),"regexp")}if(isDate(value)){return ctx.stylize(Date.prototype.toString.call(value),"date")}if(isError(value)){return formatError(value)}}var base="",array=false,braces=["{","}"];if(isArray(value)){array=true;braces=["[","]"]}if(isFunction(value)){var n=value.name?": "+value.name:"";base=" [Function"+n+"]"}if(isRegExp(value)){base=" "+RegExp.prototype.toString.call(value)}if(isDate(value)){base=" "+Date.prototype.toUTCString.call(value)}if(isError(value)){base=" "+formatError(value)}if(keys.length===0&&(!array||value.length==0)){return braces[0]+base+braces[1]}if(recurseTimes<0){if(isRegExp(value)){return ctx.stylize(RegExp.prototype.toString.call(value),"regexp")}else{return ctx.stylize("[Object]","special")}}ctx.seen.push(value);var output;if(array){output=formatArray(ctx,value,recurseTimes,visibleKeys,keys)}else{output=keys.map(function(key){return formatProperty(ctx,value,recurseTimes,visibleKeys,key,array)})}ctx.seen.pop();return reduceToSingleString(output,base,braces)}function formatPrimitive(ctx,value){if(isUndefined(value))return ctx.stylize("undefined","undefined");if(isString(value)){var simple="'"+JSON.stringify(value).replace(/^"|"$/g,"").replace(/'/g,"\\'").replace(/\\"/g,'"')+"'";return ctx.stylize(simple,"string")}if(isNumber(value))return ctx.stylize(""+value,"number");if(isBoolean(value))return ctx.stylize(""+value,"boolean");if(isNull(value))return ctx.stylize("null","null")}function formatError(value){return"["+Error.prototype.toString.call(value)+"]"}function formatArray(ctx,value,recurseTimes,visibleKeys,keys){var output=[];for(var i=0,l=value.length;i-1){if(array){str=str.split("\n").map(function(line){return" "+line}).join("\n").substr(2)}else{str="\n"+str.split("\n").map(function(line){return" "+line}).join("\n")}}}else{str=ctx.stylize("[Circular]","special")}}if(isUndefined(name)){if(array&&key.match(/^\d+$/)){return str}name=JSON.stringify(""+key);if(name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)){name=name.substr(1,name.length-2);name=ctx.stylize(name,"name")}else{name=name.replace(/'/g,"\\'").replace(/\\"/g,'"').replace(/(^"|"$)/g,"'");name=ctx.stylize(name,"string")}}return name+": "+str}function reduceToSingleString(output,base,braces){var numLinesEst=0;var length=output.reduce(function(prev,cur){numLinesEst++;if(cur.indexOf("\n")>=0)numLinesEst++;return prev+cur.replace(/\u001b\[\d\d?m/g,"").length+1},0);if(length>60){return braces[0]+(base===""?"":base+"\n ")+" "+output.join(",\n ")+" "+braces[1]}return braces[0]+base+" "+output.join(", ")+" "+braces[1]}function isArray(ar){return Array.isArray(ar)}exports.isArray=isArray;function isBoolean(arg){return typeof arg==="boolean"}exports.isBoolean=isBoolean;function isNull(arg){return arg===null}exports.isNull=isNull;function isNullOrUndefined(arg){return arg==null}exports.isNullOrUndefined=isNullOrUndefined;function isNumber(arg){return typeof arg==="number"}exports.isNumber=isNumber;function isString(arg){return typeof arg==="string"}exports.isString=isString;function isSymbol(arg){return typeof arg==="symbol"}exports.isSymbol=isSymbol;function isUndefined(arg){return arg===void 0}exports.isUndefined=isUndefined;function isRegExp(re){return isObject(re)&&objectToString(re)==="[object RegExp]"}exports.isRegExp=isRegExp;function isObject(arg){return typeof arg==="object"&&arg!==null}exports.isObject=isObject;function isDate(d){return isObject(d)&&objectToString(d)==="[object Date]"}exports.isDate=isDate;function isError(e){return isObject(e)&&(objectToString(e)==="[object Error]"||e instanceof Error)}exports.isError=isError;function isFunction(arg){return typeof arg==="function"}exports.isFunction=isFunction;function isPrimitive(arg){return arg===null||typeof arg==="boolean"||typeof arg==="number"||typeof arg==="string"||typeof arg==="symbol"||typeof arg==="undefined"}exports.isPrimitive=isPrimitive;exports.isBuffer=_dereq_("./support/isBuffer");function objectToString(o){return Object.prototype.toString.call(o)}function pad(n){return n<10?"0"+n.toString(10):n.toString(10)}var months=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];function timestamp(){var d=new Date;var time=[pad(d.getHours()),pad(d.getMinutes()),pad(d.getSeconds())].join(":");return[d.getDate(),months[d.getMonth()],time].join(" ")}exports.log=function(){console.log("%s - %s",timestamp(),exports.format.apply(exports,arguments))};exports.inherits=_dereq_("inherits");exports._extend=function(origin,add){if(!add||!isObject(add))return origin;var keys=Object.keys(add);var i=keys.length;while(i--){origin[keys[i]]=add[keys[i]]}return origin};function hasOwnProperty(obj,prop){return Object.prototype.hasOwnProperty.call(obj,prop)}}).call(this,_dereq_("_process"),typeof global!=="undefined"?global:typeof self!=="undefined"?self:typeof window!=="undefined"?window:{})},{"./support/isBuffer":4,_process:3,inherits:2}],6:[function(_dereq_,module,exports){"use strict";var tt=_dereq_("./tokentype").types;var Parser=_dereq_("./state").Parser;var reservedWords=_dereq_("./identifier").reservedWords;var has=_dereq_("./util").has;var pp=Parser.prototype;pp.checkPropClash=function(prop,propHash){if(this.options.ecmaVersion>=6)return;var key=prop.key,name=undefined;switch(key.type){case"Identifier":name=key.name;break;case"Literal":name=String(key.value);break;default:return}var kind=prop.kind||"init",other=undefined;if(has(propHash,name)){other=propHash[name];var isGetSet=kind!=="init";if((this.strict||isGetSet)&&other[kind]||!(isGetSet^other.init))this.raise(key.start,"Redefinition of property")}else{other=propHash[name]={init:false,get:false,set:false}}other[kind]=true};pp.parseExpression=function(noIn,refShorthandDefaultPos){var startPos=this.start,startLoc=this.startLoc;var expr=this.parseMaybeAssign(noIn,refShorthandDefaultPos);if(this.type===tt.comma){var node=this.startNodeAt(startPos,startLoc);node.expressions=[expr];while(this.eat(tt.comma))node.expressions.push(this.parseMaybeAssign(noIn,refShorthandDefaultPos));return this.finishNode(node,"SequenceExpression")}return expr};pp.parseMaybeAssign=function(noIn,refShorthandDefaultPos,afterLeftParse){if(this.type==tt._yield&&this.inGenerator)return this.parseYield();var failOnShorthandAssign=undefined;if(!refShorthandDefaultPos){refShorthandDefaultPos={start:0};failOnShorthandAssign=true}else{failOnShorthandAssign=false}var startPos=this.start,startLoc=this.startLoc;if(this.type==tt.parenL||this.type==tt.name)this.potentialArrowAt=this.start;var left=this.parseMaybeConditional(noIn,refShorthandDefaultPos);if(afterLeftParse)left=afterLeftParse.call(this,left,startPos,startLoc);if(this.type.isAssign){var node=this.startNodeAt(startPos,startLoc);node.operator=this.value;node.left=this.type===tt.eq?this.toAssignable(left):left;refShorthandDefaultPos.start=0;this.checkLVal(left);this.next();node.right=this.parseMaybeAssign(noIn);return this.finishNode(node,"AssignmentExpression")}else if(failOnShorthandAssign&&refShorthandDefaultPos.start){this.unexpected(refShorthandDefaultPos.start)}return left};pp.parseMaybeConditional=function(noIn,refShorthandDefaultPos){var startPos=this.start,startLoc=this.startLoc;var expr=this.parseExprOps(noIn,refShorthandDefaultPos);if(refShorthandDefaultPos&&refShorthandDefaultPos.start)return expr;if(this.eat(tt.question)){var node=this.startNodeAt(startPos,startLoc);node.test=expr;node.consequent=this.parseMaybeAssign();this.expect(tt.colon);node.alternate=this.parseMaybeAssign(noIn);return this.finishNode(node,"ConditionalExpression")}return expr};pp.parseExprOps=function(noIn,refShorthandDefaultPos){var startPos=this.start,startLoc=this.startLoc;var expr=this.parseMaybeUnary(refShorthandDefaultPos);if(refShorthandDefaultPos&&refShorthandDefaultPos.start)return expr;return this.parseExprOp(expr,startPos,startLoc,-1,noIn)};pp.parseExprOp=function(left,leftStartPos,leftStartLoc,minPrec,noIn){var prec=this.type.binop;if(Array.isArray(leftStartPos)){if(this.options.locations&&noIn===undefined){noIn=minPrec;minPrec=leftStartLoc;leftStartLoc=leftStartPos[1];leftStartPos=leftStartPos[0]}}if(prec!=null&&(!noIn||this.type!==tt._in)){if(prec>minPrec){var node=this.startNodeAt(leftStartPos,leftStartLoc);node.left=left;node.operator=this.value;var op=this.type;this.next();var startPos=this.start,startLoc=this.startLoc;node.right=this.parseExprOp(this.parseMaybeUnary(),startPos,startLoc,prec,noIn);this.finishNode(node,op===tt.logicalOR||op===tt.logicalAND?"LogicalExpression":"BinaryExpression");return this.parseExprOp(node,leftStartPos,leftStartLoc,minPrec,noIn)}}return left};pp.parseMaybeUnary=function(refShorthandDefaultPos){if(this.type.prefix){var node=this.startNode(),update=this.type===tt.incDec;node.operator=this.value;node.prefix=true;this.next();node.argument=this.parseMaybeUnary();if(refShorthandDefaultPos&&refShorthandDefaultPos.start)this.unexpected(refShorthandDefaultPos.start);if(update)this.checkLVal(node.argument);else if(this.strict&&node.operator==="delete"&&node.argument.type==="Identifier")this.raise(node.start,"Deleting local variable in strict mode");return this.finishNode(node,update?"UpdateExpression":"UnaryExpression")}var startPos=this.start,startLoc=this.startLoc;var expr=this.parseExprSubscripts(refShorthandDefaultPos);if(refShorthandDefaultPos&&refShorthandDefaultPos.start)return expr;while(this.type.postfix&&!this.canInsertSemicolon()){var node=this.startNodeAt(startPos,startLoc);node.operator=this.value;node.prefix=false;node.argument=expr;this.checkLVal(expr);this.next();expr=this.finishNode(node,"UpdateExpression")}return expr};pp.parseExprSubscripts=function(refShorthandDefaultPos){var startPos=this.start,startLoc=this.startLoc;var expr=this.parseExprAtom(refShorthandDefaultPos);if(refShorthandDefaultPos&&refShorthandDefaultPos.start)return expr;return this.parseSubscripts(expr,startPos,startLoc)};pp.parseSubscripts=function(base,startPos,startLoc,noCalls){if(Array.isArray(startPos)){if(this.options.locations&&noCalls===undefined){noCalls=startLoc;startLoc=startPos[1];startPos=startPos[0]}}for(;;){if(this.eat(tt.dot)){var node=this.startNodeAt(startPos,startLoc);node.object=base;node.property=this.parseIdent(true);node.computed=false;base=this.finishNode(node,"MemberExpression")}else if(this.eat(tt.bracketL)){var node=this.startNodeAt(startPos,startLoc);node.object=base;node.property=this.parseExpression();node.computed=true;this.expect(tt.bracketR);base=this.finishNode(node,"MemberExpression")}else if(!noCalls&&this.eat(tt.parenL)){var node=this.startNodeAt(startPos,startLoc);node.callee=base;node.arguments=this.parseExprList(tt.parenR,false);base=this.finishNode(node,"CallExpression")}else if(this.type===tt.backQuote){var node=this.startNodeAt(startPos,startLoc);node.tag=base;node.quasi=this.parseTemplate();base=this.finishNode(node,"TaggedTemplateExpression")}else{return base}}};pp.parseExprAtom=function(refShorthandDefaultPos){var node=undefined,canBeArrow=this.potentialArrowAt==this.start;switch(this.type){case tt._this:case tt._super:var type=this.type===tt._this?"ThisExpression":"Super";node=this.startNode();this.next();return this.finishNode(node,type);case tt._yield:if(this.inGenerator)this.unexpected();case tt.name:var startPos=this.start,startLoc=this.startLoc;var id=this.parseIdent(this.type!==tt.name);if(canBeArrow&&!this.canInsertSemicolon()&&this.eat(tt.arrow))return this.parseArrowExpression(this.startNodeAt(startPos,startLoc),[id]);return id;case tt.regexp:var value=this.value;node=this.parseLiteral(value.value);node.regex={pattern:value.pattern,flags:value.flags};return node;case tt.num:case tt.string:return this.parseLiteral(this.value);case tt._null:case tt._true:case tt._false:node=this.startNode();node.value=this.type===tt._null?null:this.type===tt._true;node.raw=this.type.keyword;this.next();return this.finishNode(node,"Literal");case tt.parenL:return this.parseParenAndDistinguishExpression(canBeArrow);case tt.bracketL:node=this.startNode();this.next();if(this.options.ecmaVersion>=7&&this.type===tt._for){return this.parseComprehension(node,false)}node.elements=this.parseExprList(tt.bracketR,true,true,refShorthandDefaultPos);return this.finishNode(node,"ArrayExpression");case tt.braceL:return this.parseObj(false,refShorthandDefaultPos);case tt._function:node=this.startNode();this.next();return this.parseFunction(node,false);case tt._class:return this.parseClass(this.startNode(),false);case tt._new:return this.parseNew();case tt.backQuote:return this.parseTemplate();default:this.unexpected()}};pp.parseLiteral=function(value){var node=this.startNode();node.value=value;node.raw=this.input.slice(this.start,this.end);this.next();return this.finishNode(node,"Literal")};pp.parseParenExpression=function(){this.expect(tt.parenL);var val=this.parseExpression();this.expect(tt.parenR);return val};pp.parseParenAndDistinguishExpression=function(canBeArrow){var startPos=this.start,startLoc=this.startLoc,val=undefined;if(this.options.ecmaVersion>=6){this.next();if(this.options.ecmaVersion>=7&&this.type===tt._for){return this.parseComprehension(this.startNodeAt(startPos,startLoc),true)}var innerStartPos=this.start,innerStartLoc=this.startLoc;var exprList=[],first=true;var refShorthandDefaultPos={start:0},spreadStart=undefined,innerParenStart=undefined;while(this.type!==tt.parenR){first?first=false:this.expect(tt.comma);if(this.type===tt.ellipsis){spreadStart=this.start;exprList.push(this.parseParenItem(this.parseRest()));break}else{if(this.type===tt.parenL&&!innerParenStart){innerParenStart=this.start}exprList.push(this.parseMaybeAssign(false,refShorthandDefaultPos,this.parseParenItem))}}var innerEndPos=this.start,innerEndLoc=this.startLoc;this.expect(tt.parenR);if(canBeArrow&&!this.canInsertSemicolon()&&this.eat(tt.arrow)){if(innerParenStart)this.unexpected(innerParenStart);return this.parseParenArrowList(startPos,startLoc,exprList)}if(!exprList.length)this.unexpected(this.lastTokStart);if(spreadStart)this.unexpected(spreadStart);if(refShorthandDefaultPos.start)this.unexpected(refShorthandDefaultPos.start);if(exprList.length>1){val=this.startNodeAt(innerStartPos,innerStartLoc);val.expressions=exprList;this.finishNodeAt(val,"SequenceExpression",innerEndPos,innerEndLoc)}else{val=exprList[0]}}else{val=this.parseParenExpression()}if(this.options.preserveParens){var par=this.startNodeAt(startPos,startLoc);par.expression=val;return this.finishNode(par,"ParenthesizedExpression")}else{return val}};pp.parseParenItem=function(item){return item};pp.parseParenArrowList=function(startPos,startLoc,exprList){return this.parseArrowExpression(this.startNodeAt(startPos,startLoc),exprList)};var empty=[];pp.parseNew=function(){var node=this.startNode();var meta=this.parseIdent(true);if(this.options.ecmaVersion>=6&&this.eat(tt.dot)){node.meta=meta;node.property=this.parseIdent(true);if(node.property.name!=="target")this.raise(node.property.start,"The only valid meta property for new is new.target");return this.finishNode(node,"MetaProperty")}var startPos=this.start,startLoc=this.startLoc;node.callee=this.parseSubscripts(this.parseExprAtom(),startPos,startLoc,true);if(this.eat(tt.parenL))node.arguments=this.parseExprList(tt.parenR,false);else node.arguments=empty;return this.finishNode(node,"NewExpression")};pp.parseTemplateElement=function(){var elem=this.startNode();elem.value={raw:this.input.slice(this.start,this.end),cooked:this.value};this.next();elem.tail=this.type===tt.backQuote;return this.finishNode(elem,"TemplateElement")};pp.parseTemplate=function(){var node=this.startNode();this.next();node.expressions=[];var curElt=this.parseTemplateElement();node.quasis=[curElt];while(!curElt.tail){this.expect(tt.dollarBraceL);node.expressions.push(this.parseExpression());this.expect(tt.braceR);node.quasis.push(curElt=this.parseTemplateElement())}this.next();return this.finishNode(node,"TemplateLiteral")};pp.parseObj=function(isPattern,refShorthandDefaultPos){var node=this.startNode(),first=true,propHash={};node.properties=[];this.next();while(!this.eat(tt.braceR)){if(!first){this.expect(tt.comma);if(this.afterTrailingComma(tt.braceR))break}else first=false;var prop=this.startNode(),isGenerator=undefined,startPos=undefined,startLoc=undefined;if(this.options.ecmaVersion>=6){prop.method=false;prop.shorthand=false;if(isPattern||refShorthandDefaultPos){startPos=this.start;startLoc=this.startLoc}if(!isPattern)isGenerator=this.eat(tt.star)}this.parsePropertyName(prop);this.parsePropertyValue(prop,isPattern,isGenerator,startPos,startLoc,refShorthandDefaultPos);this.checkPropClash(prop,propHash);node.properties.push(this.finishNode(prop,"Property"))}return this.finishNode(node,isPattern?"ObjectPattern":"ObjectExpression")};pp.parsePropertyValue=function(prop,isPattern,isGenerator,startPos,startLoc,refShorthandDefaultPos){if(this.eat(tt.colon)){prop.value=isPattern?this.parseMaybeDefault(this.start,this.startLoc):this.parseMaybeAssign(false,refShorthandDefaultPos);prop.kind="init"}else if(this.options.ecmaVersion>=6&&this.type===tt.parenL){if(isPattern)this.unexpected();prop.kind="init";prop.method=true;prop.value=this.parseMethod(isGenerator)}else if(this.options.ecmaVersion>=5&&!prop.computed&&prop.key.type==="Identifier"&&(prop.key.name==="get"||prop.key.name==="set")&&(this.type!=tt.comma&&this.type!=tt.braceR)){if(isGenerator||isPattern)this.unexpected();prop.kind=prop.key.name;this.parsePropertyName(prop);prop.value=this.parseMethod(false)}else if(this.options.ecmaVersion>=6&&!prop.computed&&prop.key.type==="Identifier"){prop.kind="init";if(isPattern){if(this.isKeyword(prop.key.name)||this.strict&&(reservedWords.strictBind(prop.key.name)||reservedWords.strict(prop.key.name))||!this.options.allowReserved&&this.isReservedWord(prop.key.name))this.raise(prop.key.start,"Binding "+prop.key.name);prop.value=this.parseMaybeDefault(startPos,startLoc,prop.key)}else if(this.type===tt.eq&&refShorthandDefaultPos){if(!refShorthandDefaultPos.start)refShorthandDefaultPos.start=this.start;prop.value=this.parseMaybeDefault(startPos,startLoc,prop.key)}else{prop.value=prop.key}prop.shorthand=true}else this.unexpected()};pp.parsePropertyName=function(prop){if(this.options.ecmaVersion>=6){if(this.eat(tt.bracketL)){prop.computed=true;prop.key=this.parseMaybeAssign();this.expect(tt.bracketR);return prop.key}else{prop.computed=false}}return prop.key=this.type===tt.num||this.type===tt.string?this.parseExprAtom():this.parseIdent(true)};pp.initFunction=function(node){node.id=null;if(this.options.ecmaVersion>=6){node.generator=false;node.expression=false}};pp.parseMethod=function(isGenerator){var node=this.startNode();this.initFunction(node);this.expect(tt.parenL);node.params=this.parseBindingList(tt.parenR,false,false);var allowExpressionBody=undefined;if(this.options.ecmaVersion>=6){node.generator=isGenerator;allowExpressionBody=true}else{allowExpressionBody=false}this.parseFunctionBody(node,allowExpressionBody);return this.finishNode(node,"FunctionExpression")};pp.parseArrowExpression=function(node,params){this.initFunction(node);node.params=this.toAssignableList(params,true);this.parseFunctionBody(node,true);return this.finishNode(node,"ArrowFunctionExpression")};pp.parseFunctionBody=function(node,allowExpression){var isExpression=allowExpression&&this.type!==tt.braceL;if(isExpression){node.body=this.parseMaybeAssign();node.expression=true}else{var oldInFunc=this.inFunction,oldInGen=this.inGenerator,oldLabels=this.labels;this.inFunction=true;this.inGenerator=node.generator;this.labels=[];node.body=this.parseBlock(true);node.expression=false;this.inFunction=oldInFunc;this.inGenerator=oldInGen;this.labels=oldLabels}if(this.strict||!isExpression&&node.body.body.length&&this.isUseStrict(node.body.body[0])){var nameHash={},oldStrict=this.strict;this.strict=true;if(node.id)this.checkLVal(node.id,true);for(var i=0;i=6||this.input.slice(this.start,this.end).indexOf("\\")==-1)))this.raise(this.start,"The keyword '"+this.value+"' is reserved");node.name=this.value}else if(liberal&&this.type.keyword){node.name=this.type.keyword}else{this.unexpected()}this.next(); 2 | 3 | return this.finishNode(node,"Identifier")};pp.parseYield=function(){var node=this.startNode();this.next();if(this.type==tt.semi||this.canInsertSemicolon()||this.type!=tt.star&&!this.type.startsExpr){node.delegate=false;node.argument=null}else{node.delegate=this.eat(tt.star);node.argument=this.parseMaybeAssign()}return this.finishNode(node,"YieldExpression")};pp.parseComprehension=function(node,isGenerator){node.blocks=[];while(this.type===tt._for){var block=this.startNode();this.next();this.expect(tt.parenL);block.left=this.parseBindingAtom();this.checkLVal(block.left,true);this.expectContextual("of");block.right=this.parseExpression();this.expect(tt.parenR);node.blocks.push(this.finishNode(block,"ComprehensionBlock"))}node.filter=this.eat(tt._if)?this.parseParenExpression():null;node.body=this.parseExpression();this.expect(isGenerator?tt.parenR:tt.bracketR);node.generator=isGenerator;return this.finishNode(node,"ComprehensionExpression")}},{"./identifier":7,"./state":13,"./tokentype":17,"./util":18}],7:[function(_dereq_,module,exports){"use strict";exports.isIdentifierStart=isIdentifierStart;exports.isIdentifierChar=isIdentifierChar;exports.__esModule=true;function makePredicate(words){words=words.split(" ");var f="",cats=[];out:for(var i=0;i3){cats.sort(function(a,b){return b.length-a.length});f+="switch(str.length){";for(var i=0;icode){return false}pos+=set[i+1];if(pos>=code){return true}}}function isIdentifierStart(code,astral){if(code<65){return code===36}if(code<91){return true}if(code<97){return code===95}if(code<123){return true}if(code<=65535){return code>=170&&nonASCIIidentifierStart.test(String.fromCharCode(code))}if(astral===false){return false}return isInAstralSet(code,astralIdentifierStartCodes)}function isIdentifierChar(code,astral){if(code<48){return code===36}if(code<58){return true}if(code<65){return false}if(code<91){return true}if(code<97){return code===95}if(code<123){return true}if(code<=65535){return code>=170&&nonASCIIidentifier.test(String.fromCharCode(code))}if(astral===false){return false}return isInAstralSet(code,astralIdentifierStartCodes)||isInAstralSet(code,astralIdentifierCodes)}},{}],8:[function(_dereq_,module,exports){"use strict";var _classCallCheck=function(instance,Constructor){if(!(instance instanceof Constructor)){throw new TypeError("Cannot call a class as a function")}};exports.getLineInfo=getLineInfo;exports.__esModule=true;var Parser=_dereq_("./state").Parser;var lineBreakG=_dereq_("./whitespace").lineBreakG;var deprecate=_dereq_("util").deprecate;var Position=exports.Position=function(){function Position(line,col){_classCallCheck(this,Position);this.line=line;this.column=col}Position.prototype.offset=function offset(n){return new Position(this.line,this.column+n)};return Position}();var SourceLocation=exports.SourceLocation=function SourceLocation(p,start,end){_classCallCheck(this,SourceLocation);this.start=start;this.end=end;if(p.sourceFile!==null)this.source=p.sourceFile};function getLineInfo(input,offset){for(var line=1,cur=0;;){lineBreakG.lastIndex=cur;var match=lineBreakG.exec(input);if(match&&match.index=6&&node){switch(node.type){case"Identifier":case"ObjectPattern":case"ArrayPattern":case"AssignmentPattern":break;case"ObjectExpression":node.type="ObjectPattern";for(var i=0;i=6){node.sourceType=this.options.sourceType}return this.finishNode(node,"Program")};var loopLabel={kind:"loop"},switchLabel={kind:"switch"};pp.parseStatement=function(declaration,topLevel){var starttype=this.type,node=this.startNode();switch(starttype){case tt._break:case tt._continue:return this.parseBreakContinueStatement(node,starttype.keyword);case tt._debugger:return this.parseDebuggerStatement(node);case tt._do:return this.parseDoStatement(node);case tt._for:return this.parseForStatement(node);case tt._function:if(!declaration&&this.options.ecmaVersion>=6)this.unexpected();return this.parseFunctionStatement(node);case tt._class:if(!declaration)this.unexpected();return this.parseClass(node,true);case tt._if:return this.parseIfStatement(node);case tt._return:return this.parseReturnStatement(node);case tt._switch:return this.parseSwitchStatement(node);case tt._throw:return this.parseThrowStatement(node);case tt._try:return this.parseTryStatement(node);case tt._let:case tt._const:if(!declaration)this.unexpected();case tt._var:return this.parseVarStatement(node,starttype);case tt._while:return this.parseWhileStatement(node);case tt._with:return this.parseWithStatement(node);case tt.braceL:return this.parseBlock();case tt.semi:return this.parseEmptyStatement(node);case tt._export:case tt._import:if(!this.options.allowImportExportEverywhere){if(!topLevel)this.raise(this.start,"'import' and 'export' may only appear at the top level");if(!this.inModule)this.raise(this.start,"'import' and 'export' may appear only with 'sourceType: module'")}return starttype===tt._import?this.parseImport(node):this.parseExport(node);default:var maybeName=this.value,expr=this.parseExpression();if(starttype===tt.name&&expr.type==="Identifier"&&this.eat(tt.colon))return this.parseLabeledStatement(node,maybeName,expr);else return this.parseExpressionStatement(node,expr)}};pp.parseBreakContinueStatement=function(node,keyword){var isBreak=keyword=="break";this.next();if(this.eat(tt.semi)||this.insertSemicolon())node.label=null;else if(this.type!==tt.name)this.unexpected();else{node.label=this.parseIdent();this.semicolon()}for(var i=0;i=6)this.eat(tt.semi);else this.semicolon();return this.finishNode(node,"DoWhileStatement")};pp.parseForStatement=function(node){this.next();this.labels.push(loopLabel);this.expect(tt.parenL);if(this.type===tt.semi)return this.parseFor(node,null);if(this.type===tt._var||this.type===tt._let||this.type===tt._const){var _init=this.startNode(),varKind=this.type;this.next();this.parseVar(_init,true,varKind);this.finishNode(_init,"VariableDeclaration");if((this.type===tt._in||this.options.ecmaVersion>=6&&this.isContextual("of"))&&_init.declarations.length===1&&!(varKind!==tt._var&&_init.declarations[0].init))return this.parseForIn(node,_init);return this.parseFor(node,_init)}var refShorthandDefaultPos={start:0};var init=this.parseExpression(true,refShorthandDefaultPos);if(this.type===tt._in||this.options.ecmaVersion>=6&&this.isContextual("of")){this.toAssignable(init);this.checkLVal(init);return this.parseForIn(node,init)}else if(refShorthandDefaultPos.start){this.unexpected(refShorthandDefaultPos.start)}return this.parseFor(node,init)};pp.parseFunctionStatement=function(node){this.next();return this.parseFunction(node,true)};pp.parseIfStatement=function(node){this.next();node.test=this.parseParenExpression();node.consequent=this.parseStatement(false);node.alternate=this.eat(tt._else)?this.parseStatement(false):null;return this.finishNode(node,"IfStatement")};pp.parseReturnStatement=function(node){if(!this.inFunction&&!this.options.allowReturnOutsideFunction)this.raise(this.start,"'return' outside of function");this.next();if(this.eat(tt.semi)||this.insertSemicolon())node.argument=null;else{node.argument=this.parseExpression();this.semicolon()}return this.finishNode(node,"ReturnStatement")};pp.parseSwitchStatement=function(node){this.next();node.discriminant=this.parseParenExpression();node.cases=[];this.expect(tt.braceL);this.labels.push(switchLabel);for(var cur,sawDefault;this.type!=tt.braceR;){if(this.type===tt._case||this.type===tt._default){var isCase=this.type===tt._case;if(cur)this.finishNode(cur,"SwitchCase");node.cases.push(cur=this.startNode());cur.consequent=[];this.next();if(isCase){cur.test=this.parseExpression()}else{if(sawDefault)this.raise(this.lastTokStart,"Multiple default clauses");sawDefault=true;cur.test=null}this.expect(tt.colon)}else{if(!cur)this.unexpected();cur.consequent.push(this.parseStatement(true))}}if(cur)this.finishNode(cur,"SwitchCase");this.next();this.labels.pop();return this.finishNode(node,"SwitchStatement")};pp.parseThrowStatement=function(node){this.next();if(lineBreak.test(this.input.slice(this.lastTokEnd,this.start)))this.raise(this.lastTokEnd,"Illegal newline after throw");node.argument=this.parseExpression();this.semicolon();return this.finishNode(node,"ThrowStatement")};var empty=[];pp.parseTryStatement=function(node){this.next();node.block=this.parseBlock();node.handler=null;if(this.type===tt._catch){var clause=this.startNode();this.next();this.expect(tt.parenL);clause.param=this.parseBindingAtom();this.checkLVal(clause.param,true);this.expect(tt.parenR);clause.guard=null;clause.body=this.parseBlock();node.handler=this.finishNode(clause,"CatchClause")}node.guardedHandlers=empty;node.finalizer=this.eat(tt._finally)?this.parseBlock():null;if(!node.handler&&!node.finalizer)this.raise(node.start,"Missing catch or finally clause");return this.finishNode(node,"TryStatement")};pp.parseVarStatement=function(node,kind){this.next();this.parseVar(node,false,kind);this.semicolon();return this.finishNode(node,"VariableDeclaration")};pp.parseWhileStatement=function(node){this.next();node.test=this.parseParenExpression();this.labels.push(loopLabel);node.body=this.parseStatement(false);this.labels.pop();return this.finishNode(node,"WhileStatement")};pp.parseWithStatement=function(node){if(this.strict)this.raise(this.start,"'with' in strict mode");this.next();node.object=this.parseParenExpression();node.body=this.parseStatement(false);return this.finishNode(node,"WithStatement")};pp.parseEmptyStatement=function(node){this.next();return this.finishNode(node,"EmptyStatement")};pp.parseLabeledStatement=function(node,maybeName,expr){for(var i=0;i=6&&this.isContextual("of"))){this.unexpected()}else if(decl.id.type!="Identifier"&&!(isFor&&(this.type===tt._in||this.isContextual("of")))){this.raise(this.lastTokEnd,"Complex binding patterns require an initialization value")}else{decl.init=null}node.declarations.push(this.finishNode(decl,"VariableDeclarator"));if(!this.eat(tt.comma))break}return node};pp.parseVarId=function(decl){decl.id=this.parseBindingAtom();this.checkLVal(decl.id,true)};pp.parseFunction=function(node,isStatement,allowExpressionBody){this.initFunction(node);if(this.options.ecmaVersion>=6)node.generator=this.eat(tt.star);if(isStatement||this.type===tt.name)node.id=this.parseIdent();this.parseFunctionParams(node);this.parseFunctionBody(node,allowExpressionBody);return this.finishNode(node,isStatement?"FunctionDeclaration":"FunctionExpression")};pp.parseFunctionParams=function(node){this.expect(tt.parenL);node.params=this.parseBindingList(tt.parenR,false,false)};pp.parseClass=function(node,isStatement){this.next();this.parseClassId(node,isStatement);this.parseClassSuper(node);var classBody=this.startNode();var hadConstructor=false;classBody.body=[];this.expect(tt.braceL);while(!this.eat(tt.braceR)){if(this.eat(tt.semi))continue;var method=this.startNode();var isGenerator=this.eat(tt.star);var isMaybeStatic=this.type===tt.name&&this.value==="static";this.parsePropertyName(method);method["static"]=isMaybeStatic&&this.type!==tt.parenL;if(method["static"]){if(isGenerator)this.unexpected();isGenerator=this.eat(tt.star);this.parsePropertyName(method)}method.kind="method";if(!method.computed){var key=method.key;var isGetSet=false;if(!isGenerator&&key.type==="Identifier"&&this.type!==tt.parenL&&(key.name==="get"||key.name==="set")){isGetSet=true;method.kind=key.name;key=this.parsePropertyName(method)}if(!method["static"]&&(key.type==="Identifier"&&key.name==="constructor"||key.type==="Literal"&&key.value==="constructor")){if(hadConstructor)this.raise(key.start,"Duplicate constructor in the same class");if(isGetSet)this.raise(key.start,"Constructor can't have get/set modifier");if(isGenerator)this.raise(key.start,"Constructor can't be a generator");method.kind="constructor";hadConstructor=true}}this.parseClassMethod(classBody,method,isGenerator)}node.body=this.finishNode(classBody,"ClassBody");return this.finishNode(node,isStatement?"ClassDeclaration":"ClassExpression")};pp.parseClassMethod=function(classBody,method,isGenerator){method.value=this.parseMethod(isGenerator);classBody.body.push(this.finishNode(method,"MethodDefinition"))};pp.parseClassId=function(node,isStatement){node.id=this.type===tt.name?this.parseIdent():isStatement?this.unexpected():null};pp.parseClassSuper=function(node){node.superClass=this.eat(tt._extends)?this.parseExprSubscripts():null};pp.parseExport=function(node){this.next();if(this.eat(tt.star)){this.expectContextual("from");node.source=this.type===tt.string?this.parseExprAtom():this.unexpected();this.semicolon();return this.finishNode(node,"ExportAllDeclaration")}if(this.eat(tt._default)){var expr=this.parseMaybeAssign();var needsSemi=true;if(expr.type=="FunctionExpression"||expr.type=="ClassExpression"){needsSemi=false;if(expr.id){expr.type=expr.type=="FunctionExpression"?"FunctionDeclaration":"ClassDeclaration"}}node.declaration=expr;if(needsSemi)this.semicolon();return this.finishNode(node,"ExportDefaultDeclaration")}if(this.shouldParseExportStatement()){node.declaration=this.parseStatement(true);node.specifiers=[];node.source=null}else{node.declaration=null;node.specifiers=this.parseExportSpecifiers();if(this.eatContextual("from")){node.source=this.type===tt.string?this.parseExprAtom():this.unexpected()}else{node.source=null}this.semicolon()}return this.finishNode(node,"ExportNamedDeclaration")};pp.shouldParseExportStatement=function(){return this.type.keyword};pp.parseExportSpecifiers=function(){var nodes=[],first=true;this.expect(tt.braceL);while(!this.eat(tt.braceR)){if(!first){this.expect(tt.comma);if(this.afterTrailingComma(tt.braceR))break}else first=false;var node=this.startNode(); 4 | 5 | node.local=this.parseIdent(this.type===tt._default);node.exported=this.eatContextual("as")?this.parseIdent(true):node.local;nodes.push(this.finishNode(node,"ExportSpecifier"))}return nodes};pp.parseImport=function(node){this.next();if(this.type===tt.string){node.specifiers=empty;node.source=this.parseExprAtom();node.kind=""}else{node.specifiers=this.parseImportSpecifiers();this.expectContextual("from");node.source=this.type===tt.string?this.parseExprAtom():this.unexpected()}this.semicolon();return this.finishNode(node,"ImportDeclaration")};pp.parseImportSpecifiers=function(){var nodes=[],first=true;if(this.type===tt.name){var node=this.startNode();node.local=this.parseIdent();this.checkLVal(node.local,true);nodes.push(this.finishNode(node,"ImportDefaultSpecifier"));if(!this.eat(tt.comma))return nodes}if(this.type===tt.star){var node=this.startNode();this.next();this.expectContextual("as");node.local=this.parseIdent();this.checkLVal(node.local,true);nodes.push(this.finishNode(node,"ImportNamespaceSpecifier"));return nodes}this.expect(tt.braceL);while(!this.eat(tt.braceR)){if(!first){this.expect(tt.comma);if(this.afterTrailingComma(tt.braceR))break}else first=false;var node=this.startNode();node.imported=this.parseIdent(true);node.local=this.eatContextual("as")?this.parseIdent():node.imported;this.checkLVal(node.local,true);nodes.push(this.finishNode(node,"ImportSpecifier"))}return nodes}},{"./state":13,"./tokentype":17,"./whitespace":19}],15:[function(_dereq_,module,exports){"use strict";var _classCallCheck=function(instance,Constructor){if(!(instance instanceof Constructor)){throw new TypeError("Cannot call a class as a function")}};exports.__esModule=true;var Parser=_dereq_("./state").Parser;var tt=_dereq_("./tokentype").types;var lineBreak=_dereq_("./whitespace").lineBreak;var TokContext=exports.TokContext=function TokContext(token,isExpr,preserveSpace,override){_classCallCheck(this,TokContext);this.token=token;this.isExpr=isExpr;this.preserveSpace=preserveSpace;this.override=override};var types={b_stat:new TokContext("{",false),b_expr:new TokContext("{",true),b_tmpl:new TokContext("${",true),p_stat:new TokContext("(",false),p_expr:new TokContext("(",true),q_tmpl:new TokContext("`",true,true,function(p){return p.readTmplToken()}),f_expr:new TokContext("function",true)};exports.types=types;var pp=Parser.prototype;pp.initialContext=function(){return[types.b_stat]};pp.braceIsBlock=function(prevType){var parent=undefined;if(prevType===tt.colon&&(parent=this.curContext()).token=="{")return!parent.isExpr;if(prevType===tt._return)return lineBreak.test(this.input.slice(this.lastTokEnd,this.start));if(prevType===tt._else||prevType===tt.semi||prevType===tt.eof)return true;if(prevType==tt.braceL)return this.curContext()===types.b_stat;return!this.exprAllowed};pp.updateContext=function(prevType){var update=undefined,type=this.type;if(type.keyword&&prevType==tt.dot)this.exprAllowed=false;else if(update=type.updateContext)update.call(this,prevType);else this.exprAllowed=type.beforeExpr};tt.parenR.updateContext=tt.braceR.updateContext=function(){if(this.context.length==1){this.exprAllowed=true;return}var out=this.context.pop();if(out===types.b_stat&&this.curContext()===types.f_expr){this.context.pop();this.exprAllowed=false}else if(out===types.b_tmpl){this.exprAllowed=true}else{this.exprAllowed=!out.isExpr}};tt.braceL.updateContext=function(prevType){this.context.push(this.braceIsBlock(prevType)?types.b_stat:types.b_expr);this.exprAllowed=true};tt.dollarBraceL.updateContext=function(){this.context.push(types.b_tmpl);this.exprAllowed=true};tt.parenL.updateContext=function(prevType){var statementParens=prevType===tt._if||prevType===tt._for||prevType===tt._with||prevType===tt._while;this.context.push(statementParens?types.p_stat:types.p_expr);this.exprAllowed=true};tt.incDec.updateContext=function(){};tt._function.updateContext=function(){if(this.curContext()!==types.b_stat)this.context.push(types.f_expr);this.exprAllowed=false};tt.backQuote.updateContext=function(){if(this.curContext()===types.q_tmpl)this.context.pop();else this.context.push(types.q_tmpl);this.exprAllowed=false}},{"./state":13,"./tokentype":17,"./whitespace":19}],16:[function(_dereq_,module,exports){"use strict";var _classCallCheck=function(instance,Constructor){if(!(instance instanceof Constructor)){throw new TypeError("Cannot call a class as a function")}};exports.__esModule=true;var _identifier=_dereq_("./identifier");var isIdentifierStart=_identifier.isIdentifierStart;var isIdentifierChar=_identifier.isIdentifierChar;var _tokentype=_dereq_("./tokentype");var tt=_tokentype.types;var keywordTypes=_tokentype.keywords;var Parser=_dereq_("./state").Parser;var SourceLocation=_dereq_("./location").SourceLocation;var _whitespace=_dereq_("./whitespace");var lineBreak=_whitespace.lineBreak;var lineBreakG=_whitespace.lineBreakG;var isNewLine=_whitespace.isNewLine;var nonASCIIwhitespace=_whitespace.nonASCIIwhitespace;var Token=exports.Token=function Token(p){_classCallCheck(this,Token);this.type=p.type;this.value=p.value;this.start=p.start;this.end=p.end;if(p.options.locations)this.loc=new SourceLocation(p,p.startLoc,p.endLoc);if(p.options.ranges)this.range=[p.start,p.end]};var pp=Parser.prototype;var isRhino=typeof Packages!=="undefined";pp.next=function(){if(this.options.onToken)this.options.onToken(new Token(this));this.lastTokEnd=this.end;this.lastTokStart=this.start;this.lastTokEndLoc=this.endLoc;this.lastTokStartLoc=this.startLoc;this.nextToken()};pp.getToken=function(){this.next();return new Token(this)};if(typeof Symbol!=="undefined")pp[Symbol.iterator]=function(){var self=this;return{next:function next(){var token=self.getToken();return{done:token.type===tt.eof,value:token}}}};pp.setStrict=function(strict){this.strict=strict;if(this.type!==tt.num&&this.type!==tt.string)return;this.pos=this.start;if(this.options.locations){while(this.pos=this.input.length)return this.finishToken(tt.eof);if(curContext.override)return curContext.override(this);else this.readToken(this.fullCharCodeAtPos())};pp.readToken=function(code){if(isIdentifierStart(code,this.options.ecmaVersion>=6)||code===92)return this.readWord();return this.getTokenFromCode(code)};pp.fullCharCodeAtPos=function(){var code=this.input.charCodeAt(this.pos);if(code<=55295||code>=57344)return code;var next=this.input.charCodeAt(this.pos+1);return(code<<10)+next-56613888};pp.skipBlockComment=function(){var startLoc=this.options.onComment&&this.options.locations&&this.curPosition();var start=this.pos,end=this.input.indexOf("*/",this.pos+=2);if(end===-1)this.raise(this.pos-2,"Unterminated comment");this.pos=end+2;if(this.options.locations){lineBreakG.lastIndex=start;var match=undefined;while((match=lineBreakG.exec(this.input))&&match.index8&&ch<14){++this.pos}else if(ch===47){var next=this.input.charCodeAt(this.pos+1);if(next===42){this.skipBlockComment()}else if(next===47){this.skipLineComment(2)}else break}else if(ch===160){++this.pos}else if(ch>=5760&&nonASCIIwhitespace.test(String.fromCharCode(ch))){++this.pos}else{break}}};pp.finishToken=function(type,val){this.end=this.pos;if(this.options.locations)this.endLoc=this.curPosition();var prevType=this.type;this.type=type;this.value=val;this.updateContext(prevType)};pp.readToken_dot=function(){var next=this.input.charCodeAt(this.pos+1);if(next>=48&&next<=57)return this.readNumber(true);var next2=this.input.charCodeAt(this.pos+2);if(this.options.ecmaVersion>=6&&next===46&&next2===46){this.pos+=3;return this.finishToken(tt.ellipsis)}else{++this.pos;return this.finishToken(tt.dot)}};pp.readToken_slash=function(){var next=this.input.charCodeAt(this.pos+1);if(this.exprAllowed){++this.pos;return this.readRegexp()}if(next===61)return this.finishOp(tt.assign,2);return this.finishOp(tt.slash,1)};pp.readToken_mult_modulo=function(code){var next=this.input.charCodeAt(this.pos+1);if(next===61)return this.finishOp(tt.assign,2);return this.finishOp(code===42?tt.star:tt.modulo,1)};pp.readToken_pipe_amp=function(code){var next=this.input.charCodeAt(this.pos+1);if(next===code)return this.finishOp(code===124?tt.logicalOR:tt.logicalAND,2);if(next===61)return this.finishOp(tt.assign,2);return this.finishOp(code===124?tt.bitwiseOR:tt.bitwiseAND,1)};pp.readToken_caret=function(){var next=this.input.charCodeAt(this.pos+1);if(next===61)return this.finishOp(tt.assign,2);return this.finishOp(tt.bitwiseXOR,1)};pp.readToken_plus_min=function(code){var next=this.input.charCodeAt(this.pos+1);if(next===code){if(next==45&&this.input.charCodeAt(this.pos+2)==62&&lineBreak.test(this.input.slice(this.lastTokEnd,this.pos))){this.skipLineComment(3);this.skipSpace();return this.nextToken()}return this.finishOp(tt.incDec,2)}if(next===61)return this.finishOp(tt.assign,2);return this.finishOp(tt.plusMin,1)};pp.readToken_lt_gt=function(code){var next=this.input.charCodeAt(this.pos+1);var size=1;if(next===code){size=code===62&&this.input.charCodeAt(this.pos+2)===62?3:2;if(this.input.charCodeAt(this.pos+size)===61)return this.finishOp(tt.assign,size+1);return this.finishOp(tt.bitShift,size)}if(next==33&&code==60&&this.input.charCodeAt(this.pos+2)==45&&this.input.charCodeAt(this.pos+3)==45){if(this.inModule)this.unexpected();this.skipLineComment(4);this.skipSpace();return this.nextToken()}if(next===61)size=this.input.charCodeAt(this.pos+2)===61?3:2;return this.finishOp(tt.relational,size)};pp.readToken_eq_excl=function(code){var next=this.input.charCodeAt(this.pos+1);if(next===61)return this.finishOp(tt.equality,this.input.charCodeAt(this.pos+2)===61?3:2);if(code===61&&next===62&&this.options.ecmaVersion>=6){this.pos+=2;return this.finishToken(tt.arrow)}return this.finishOp(code===61?tt.eq:tt.prefix,1)};pp.getTokenFromCode=function(code){switch(code){case 46:return this.readToken_dot();case 40:++this.pos;return this.finishToken(tt.parenL);case 41:++this.pos;return this.finishToken(tt.parenR);case 59:++this.pos;return this.finishToken(tt.semi);case 44:++this.pos;return this.finishToken(tt.comma);case 91:++this.pos;return this.finishToken(tt.bracketL);case 93:++this.pos;return this.finishToken(tt.bracketR);case 123:++this.pos;return this.finishToken(tt.braceL);case 125:++this.pos;return this.finishToken(tt.braceR);case 58:++this.pos;return this.finishToken(tt.colon);case 63:++this.pos;return this.finishToken(tt.question);case 96:if(this.options.ecmaVersion<6)break;++this.pos;return this.finishToken(tt.backQuote);case 48:var next=this.input.charCodeAt(this.pos+1);if(next===120||next===88)return this.readRadixNumber(16);if(this.options.ecmaVersion>=6){if(next===111||next===79)return this.readRadixNumber(8);if(next===98||next===66)return this.readRadixNumber(2)}case 49:case 50:case 51:case 52:case 53:case 54:case 55:case 56:case 57:return this.readNumber(false);case 34:case 39:return this.readString(code);case 47:return this.readToken_slash();case 37:case 42:return this.readToken_mult_modulo(code);case 124:case 38:return this.readToken_pipe_amp(code);case 94:return this.readToken_caret();case 43:case 45:return this.readToken_plus_min(code);case 60:case 62:return this.readToken_lt_gt(code);case 61:case 33:return this.readToken_eq_excl(code);case 126:return this.finishOp(tt.prefix,1)}this.raise(this.pos,"Unexpected character '"+codePointToString(code)+"'")};pp.finishOp=function(type,size){var str=this.input.slice(this.pos,this.pos+size);this.pos+=size;return this.finishToken(type,str)};var regexpUnicodeSupport=false;try{new RegExp("￿","u");regexpUnicodeSupport=true}catch(e){}pp.readRegexp=function(){var escaped=undefined,inClass=undefined,start=this.pos;for(;;){if(this.pos>=this.input.length)this.raise(start,"Unterminated regular expression");var ch=this.input.charAt(this.pos);if(lineBreak.test(ch))this.raise(start,"Unterminated regular expression");if(!escaped){if(ch==="[")inClass=true;else if(ch==="]"&&inClass)inClass=false;else if(ch==="/"&&!inClass)break;escaped=ch==="\\"}else escaped=false;++this.pos}var content=this.input.slice(start,this.pos);++this.pos;var mods=this.readWord1();var tmp=content;if(mods){var validFlags=/^[gmsiy]*$/;if(this.options.ecmaVersion>=6)validFlags=/^[gmsiyu]*$/;if(!validFlags.test(mods))this.raise(start,"Invalid regular expression flag");if(mods.indexOf("u")>=0&&!regexpUnicodeSupport){tmp=tmp.replace(/\\u([a-fA-F0-9]{4})|\\u\{([0-9a-fA-F]+)\}|[\uD800-\uDBFF][\uDC00-\uDFFF]/g,"x")}}var value=null;if(!isRhino){try{new RegExp(tmp)}catch(e){if(e instanceof SyntaxError)this.raise(start,"Error parsing regular expression: "+e.message);this.raise(e)}try{value=new RegExp(content,mods)}catch(err){}}return this.finishToken(tt.regexp,{pattern:content,flags:mods,value:value})};pp.readInt=function(radix,len){var start=this.pos,total=0;for(var i=0,e=len==null?Infinity:len;i=97)val=code-97+10;else if(code>=65)val=code-65+10;else if(code>=48&&code<=57)val=code-48;else val=Infinity;if(val>=radix)break;++this.pos;total=total*radix+val}if(this.pos===start||len!=null&&this.pos-start!==len)return null;return total};pp.readRadixNumber=function(radix){this.pos+=2;var val=this.readInt(radix);if(val==null)this.raise(this.start+2,"Expected number in radix "+radix);if(isIdentifierStart(this.fullCharCodeAtPos()))this.raise(this.pos,"Identifier directly after number");return this.finishToken(tt.num,val)};pp.readNumber=function(startsWithDot){var start=this.pos,isFloat=false,octal=this.input.charCodeAt(this.pos)===48;if(!startsWithDot&&this.readInt(10)===null)this.raise(start,"Invalid number");if(this.input.charCodeAt(this.pos)===46){++this.pos;this.readInt(10);isFloat=true}var next=this.input.charCodeAt(this.pos);if(next===69||next===101){next=this.input.charCodeAt(++this.pos);if(next===43||next===45)++this.pos;if(this.readInt(10)===null)this.raise(start,"Invalid number");isFloat=true}if(isIdentifierStart(this.fullCharCodeAtPos()))this.raise(this.pos,"Identifier directly after number");var str=this.input.slice(start,this.pos),val=undefined;if(isFloat)val=parseFloat(str);else if(!octal||str.length===1)val=parseInt(str,10);else if(/[89]/.test(str)||this.strict)this.raise(start,"Invalid number");else val=parseInt(str,8);return this.finishToken(tt.num,val)};pp.readCodePoint=function(){var ch=this.input.charCodeAt(this.pos),code=undefined;if(ch===123){if(this.options.ecmaVersion<6)this.unexpected();++this.pos;code=this.readHexChar(this.input.indexOf("}",this.pos)-this.pos);++this.pos;if(code>1114111)this.unexpected()}else{code=this.readHexChar(4)}return code};function codePointToString(code){if(code<=65535){return String.fromCharCode(code)}return String.fromCharCode((code-65536>>10)+55296,(code-65536&1023)+56320)}pp.readString=function(quote){var out="",chunkStart=++this.pos;for(;;){if(this.pos>=this.input.length)this.raise(this.start,"Unterminated string constant");var ch=this.input.charCodeAt(this.pos);if(ch===quote)break;if(ch===92){out+=this.input.slice(chunkStart,this.pos);out+=this.readEscapedChar();chunkStart=this.pos}else{if(isNewLine(ch))this.raise(this.start,"Unterminated string constant");++this.pos}}out+=this.input.slice(chunkStart,this.pos++);return this.finishToken(tt.string,out)};pp.readTmplToken=function(){var out="",chunkStart=this.pos;for(;;){if(this.pos>=this.input.length)this.raise(this.start,"Unterminated template");var ch=this.input.charCodeAt(this.pos);if(ch===96||ch===36&&this.input.charCodeAt(this.pos+1)===123){if(this.pos===this.start&&this.type===tt.template){if(ch===36){this.pos+=2;return this.finishToken(tt.dollarBraceL)}else{++this.pos;return this.finishToken(tt.backQuote)}}out+=this.input.slice(chunkStart,this.pos);return this.finishToken(tt.template,out)}if(ch===92){out+=this.input.slice(chunkStart,this.pos);out+=this.readEscapedChar();chunkStart=this.pos}else if(isNewLine(ch)){out+=this.input.slice(chunkStart,this.pos);++this.pos;if(ch===13&&this.input.charCodeAt(this.pos)===10){++this.pos;out+="\n"}else{out+=String.fromCharCode(ch)}if(this.options.locations){++this.curLine;this.lineStart=this.pos}chunkStart=this.pos}else{++this.pos}}};pp.readEscapedChar=function(){var ch=this.input.charCodeAt(++this.pos);var octal=/^[0-7]+/.exec(this.input.slice(this.pos,this.pos+3));if(octal)octal=octal[0];while(octal&&parseInt(octal,8)>255)octal=octal.slice(0,-1);if(octal==="0")octal=null;++this.pos;if(octal){if(this.strict)this.raise(this.pos-2,"Octal literal in strict mode");this.pos+=octal.length-1;return String.fromCharCode(parseInt(octal,8))}else{switch(ch){case 110:return"\n";case 114:return"\r";case 120:return String.fromCharCode(this.readHexChar(2));case 117:return codePointToString(this.readCodePoint());case 116:return" ";case 98:return"\b";case 118:return" ";case 102:return"\f";case 48:return"\x00";case 13:if(this.input.charCodeAt(this.pos)===10)++this.pos;case 10:if(this.options.locations){this.lineStart=this.pos;++this.curLine}return"";default:return String.fromCharCode(ch)}}};pp.readHexChar=function(len){var n=this.readInt(16,len);if(n===null)this.raise(this.start,"Bad character escape sequence");return n};var containsEsc;pp.readWord1=function(){containsEsc=false;var word="",first=true,chunkStart=this.pos;var astral=this.options.ecmaVersion>=6;while(this.pos=6||!containsEsc)&&this.isKeyword(word))type=keywordTypes[word];return this.finishToken(type,word)}},{"./identifier":7,"./location":8,"./state":13,"./tokentype":17,"./whitespace":19}],17:[function(_dereq_,module,exports){"use strict";var _classCallCheck=function(instance,Constructor){if(!(instance instanceof Constructor)){throw new TypeError("Cannot call a class as a function")}};exports.__esModule=true;var TokenType=exports.TokenType=function TokenType(label){var conf=arguments[1]===undefined?{}:arguments[1];_classCallCheck(this,TokenType);this.label=label;this.keyword=conf.keyword;this.beforeExpr=!!conf.beforeExpr;this.startsExpr=!!conf.startsExpr;this.isLoop=!!conf.isLoop;this.isAssign=!!conf.isAssign;this.prefix=!!conf.prefix;this.postfix=!!conf.postfix;this.binop=conf.binop||null;this.updateContext=null};function binop(name,prec){return new TokenType(name,{beforeExpr:true,binop:prec})}var beforeExpr={beforeExpr:true},startsExpr={startsExpr:true};var types={num:new TokenType("num",startsExpr),regexp:new TokenType("regexp",startsExpr),string:new TokenType("string",startsExpr),name:new TokenType("name",startsExpr),eof:new TokenType("eof"),bracketL:new TokenType("[",{beforeExpr:true,startsExpr:true}),bracketR:new TokenType("]"),braceL:new TokenType("{",{beforeExpr:true,startsExpr:true}),braceR:new TokenType("}"),parenL:new TokenType("(",{beforeExpr:true,startsExpr:true}),parenR:new TokenType(")"),comma:new TokenType(",",beforeExpr),semi:new TokenType(";",beforeExpr),colon:new TokenType(":",beforeExpr),dot:new TokenType("."),question:new TokenType("?",beforeExpr),arrow:new TokenType("=>",beforeExpr),template:new TokenType("template"),ellipsis:new TokenType("...",beforeExpr),backQuote:new TokenType("`",startsExpr),dollarBraceL:new TokenType("${",{beforeExpr:true,startsExpr:true}),eq:new TokenType("=",{beforeExpr:true,isAssign:true}),assign:new TokenType("_=",{beforeExpr:true,isAssign:true}),incDec:new TokenType("++/--",{prefix:true,postfix:true,startsExpr:true}),prefix:new TokenType("prefix",{beforeExpr:true,prefix:true,startsExpr:true}),logicalOR:binop("||",1),logicalAND:binop("&&",2),bitwiseOR:binop("|",3),bitwiseXOR:binop("^",4),bitwiseAND:binop("&",5),equality:binop("==/!=",6),relational:binop("",7),bitShift:binop("<>",8),plusMin:new TokenType("+/-",{beforeExpr:true,binop:9,prefix:true,startsExpr:true}),modulo:binop("%",10),star:binop("*",10),slash:binop("/",10)};exports.types=types;var keywords={};exports.keywords=keywords;function kw(name){var options=arguments[1]===undefined?{}:arguments[1];options.keyword=name;keywords[name]=types["_"+name]=new TokenType(name,options)}kw("break");kw("case",beforeExpr);kw("catch");kw("continue");kw("debugger");kw("default");kw("do",{isLoop:true});kw("else",beforeExpr);kw("finally");kw("for",{isLoop:true});kw("function",startsExpr);kw("if");kw("return",beforeExpr);kw("switch");kw("throw",beforeExpr);kw("try");kw("var");kw("let");kw("const");kw("while",{isLoop:true});kw("with");kw("new",{beforeExpr:true,startsExpr:true});kw("this",startsExpr);kw("super",startsExpr);kw("class");kw("extends",beforeExpr);kw("export");kw("import");kw("yield",{beforeExpr:true,startsExpr:true});kw("null",startsExpr);kw("true",startsExpr);kw("false",startsExpr);kw("in",{beforeExpr:true,binop:7});kw("instanceof",{beforeExpr:true,binop:7});kw("typeof",{beforeExpr:true,prefix:true,startsExpr:true});kw("void",{beforeExpr:true,prefix:true,startsExpr:true});kw("delete",{beforeExpr:true,prefix:true,startsExpr:true})},{}],18:[function(_dereq_,module,exports){"use strict";exports.isArray=isArray;exports.has=has;exports.__esModule=true;function isArray(obj){return Object.prototype.toString.call(obj)==="[object Array]"}function has(obj,propName){return Object.prototype.hasOwnProperty.call(obj,propName)}},{}],19:[function(_dereq_,module,exports){"use strict";exports.isNewLine=isNewLine;exports.__esModule=true;var lineBreak=/\r\n?|\n|\u2028|\u2029/;exports.lineBreak=lineBreak;var lineBreakG=new RegExp(lineBreak.source,"g");exports.lineBreakG=lineBreakG;function isNewLine(code){return code===10||code===13||code===8232||code==8233}var nonASCIIwhitespace=/[\u1680\u180e\u2000-\u200a\u202f\u205f\u3000\ufeff]/;exports.nonASCIIwhitespace=nonASCIIwhitespace},{}]},{},[1])(1)})}).call(this,typeof global!=="undefined"?global:typeof self!=="undefined"?self:typeof window!=="undefined"?window:{})},{}],3:[function(require,module,exports){var hasOwn=Object.prototype.hasOwnProperty;var toString=Object.prototype.toString;module.exports=function forEach(obj,fn,ctx){if(toString.call(fn)!=="[object Function]"){throw new TypeError("iterator must be a function")}var l=obj.length;if(l===+l){for(var i=0;i0&&!has.call(object,0)){for(var i=0;i0){for(var j=0;j=0&&toStr.call(value.callee)==="[object Function]"}return isArgs}},{}],7:[function(require,module,exports){module.exports=require("./javascript/diff_match_patch_uncompressed.js").diff_match_patch},{"./javascript/diff_match_patch_uncompressed.js":8}],8:[function(require,module,exports){function diff_match_patch(){this.Diff_Timeout=1;this.Diff_EditCost=4;this.Match_Threshold=.5;this.Match_Distance=1e3;this.Patch_DeleteThreshold=.5;this.Patch_Margin=4;this.Match_MaxBits=32}var DIFF_DELETE=-1;var DIFF_INSERT=1;var DIFF_EQUAL=0;diff_match_patch.Diff;diff_match_patch.prototype.diff_main=function(text1,text2,opt_checklines,opt_deadline){if(typeof opt_deadline=="undefined"){if(this.Diff_Timeout<=0){opt_deadline=Number.MAX_VALUE}else{opt_deadline=(new Date).getTime()+this.Diff_Timeout*1e3}}var deadline=opt_deadline;if(text1==null||text2==null){throw new Error("Null input. (diff_main)")}if(text1==text2){if(text1){return[[DIFF_EQUAL,text1]]}return[]}if(typeof opt_checklines=="undefined"){opt_checklines=true}var checklines=opt_checklines;var commonlength=this.diff_commonPrefix(text1,text2);var commonprefix=text1.substring(0,commonlength);text1=text1.substring(commonlength);text2=text2.substring(commonlength);commonlength=this.diff_commonSuffix(text1,text2);var commonsuffix=text1.substring(text1.length-commonlength);text1=text1.substring(0,text1.length-commonlength);text2=text2.substring(0,text2.length-commonlength);var diffs=this.diff_compute_(text1,text2,checklines,deadline);if(commonprefix){diffs.unshift([DIFF_EQUAL,commonprefix])}if(commonsuffix){diffs.push([DIFF_EQUAL,commonsuffix])}this.diff_cleanupMerge(diffs);return diffs};diff_match_patch.prototype.diff_compute_=function(text1,text2,checklines,deadline){var diffs;if(!text1){return[[DIFF_INSERT,text2]]}if(!text2){return[[DIFF_DELETE,text1]]}var longtext=text1.length>text2.length?text1:text2;var shorttext=text1.length>text2.length?text2:text1;var i=longtext.indexOf(shorttext);if(i!=-1){diffs=[[DIFF_INSERT,longtext.substring(0,i)],[DIFF_EQUAL,shorttext],[DIFF_INSERT,longtext.substring(i+shorttext.length)]];if(text1.length>text2.length){diffs[0][0]=diffs[2][0]=DIFF_DELETE}return diffs}if(shorttext.length==1){return[[DIFF_DELETE,text1],[DIFF_INSERT,text2]]}var hm=this.diff_halfMatch_(text1,text2);if(hm){var text1_a=hm[0];var text1_b=hm[1];var text2_a=hm[2];var text2_b=hm[3];var mid_common=hm[4];var diffs_a=this.diff_main(text1_a,text2_a,checklines,deadline);var diffs_b=this.diff_main(text1_b,text2_b,checklines,deadline);return diffs_a.concat([[DIFF_EQUAL,mid_common]],diffs_b)}if(checklines&&text1.length>100&&text2.length>100){return this.diff_lineMode_(text1,text2,deadline)}return this.diff_bisect_(text1,text2,deadline)};diff_match_patch.prototype.diff_lineMode_=function(text1,text2,deadline){var a=this.diff_linesToChars_(text1,text2);text1=a.chars1;text2=a.chars2;var linearray=a.lineArray;var diffs=this.diff_main(text1,text2,false,deadline);this.diff_charsToLines_(diffs,linearray);this.diff_cleanupSemantic(diffs);diffs.push([DIFF_EQUAL,""]);var pointer=0;var count_delete=0;var count_insert=0;var text_delete="";var text_insert="";while(pointer=1&&count_insert>=1){diffs.splice(pointer-count_delete-count_insert,count_delete+count_insert);pointer=pointer-count_delete-count_insert;var a=this.diff_main(text_delete,text_insert,false,deadline);for(var j=a.length-1;j>=0;j--){diffs.splice(pointer,0,a[j])}pointer=pointer+a.length}count_insert=0;count_delete=0;text_delete="";text_insert="";break}pointer++}diffs.pop();return diffs};diff_match_patch.prototype.diff_bisect_=function(text1,text2,deadline){var text1_length=text1.length;var text2_length=text2.length;var max_d=Math.ceil((text1_length+text2_length)/2);var v_offset=max_d;var v_length=2*max_d;var v1=new Array(v_length);var v2=new Array(v_length);for(var x=0;xdeadline){break}for(var k1=-d+k1start;k1<=d-k1end;k1+=2){var k1_offset=v_offset+k1;var x1;if(k1==-d||k1!=d&&v1[k1_offset-1]text1_length){k1end+=2}else if(y1>text2_length){k1start+=2}else if(front){var k2_offset=v_offset+delta-k1;if(k2_offset>=0&&k2_offset=x2){return this.diff_bisectSplit_(text1,text2,x1,y1,deadline); 6 | 7 | }}}}for(var k2=-d+k2start;k2<=d-k2end;k2+=2){var k2_offset=v_offset+k2;var x2;if(k2==-d||k2!=d&&v2[k2_offset-1]text1_length){k2end+=2}else if(y2>text2_length){k2start+=2}else if(!front){var k1_offset=v_offset+delta-k2;if(k1_offset>=0&&k1_offset=x2){return this.diff_bisectSplit_(text1,text2,x1,y1,deadline)}}}}}return[[DIFF_DELETE,text1],[DIFF_INSERT,text2]]};diff_match_patch.prototype.diff_bisectSplit_=function(text1,text2,x,y,deadline){var text1a=text1.substring(0,x);var text2a=text2.substring(0,y);var text1b=text1.substring(x);var text2b=text2.substring(y);var diffs=this.diff_main(text1a,text2a,false,deadline);var diffsb=this.diff_main(text1b,text2b,false,deadline);return diffs.concat(diffsb)};diff_match_patch.prototype.diff_linesToChars_=function(text1,text2){var lineArray=[];var lineHash={};lineArray[0]="";function diff_linesToCharsMunge_(text){var chars="";var lineStart=0;var lineEnd=-1;var lineArrayLength=lineArray.length;while(lineEndtext2_length){text1=text1.substring(text1_length-text2_length)}else if(text1_lengthtext2.length?text1:text2;var shorttext=text1.length>text2.length?text2:text1;if(longtext.length<4||shorttext.length*2=longtext.length){return[best_longtext_a,best_longtext_b,best_shorttext_a,best_shorttext_b,best_common]}else{return null}}var hm1=diff_halfMatchI_(longtext,shorttext,Math.ceil(longtext.length/4));var hm2=diff_halfMatchI_(longtext,shorttext,Math.ceil(longtext.length/2));var hm;if(!hm1&&!hm2){return null}else if(!hm2){hm=hm1}else if(!hm1){hm=hm2}else{hm=hm1[4].length>hm2[4].length?hm1:hm2}var text1_a,text1_b,text2_a,text2_b;if(text1.length>text2.length){text1_a=hm[0];text1_b=hm[1];text2_a=hm[2];text2_b=hm[3]}else{text2_a=hm[0];text2_b=hm[1];text1_a=hm[2];text1_b=hm[3]}var mid_common=hm[4];return[text1_a,text1_b,text2_a,text2_b,mid_common]};diff_match_patch.prototype.diff_cleanupSemantic=function(diffs){var changes=false;var equalities=[];var equalitiesLength=0;var lastequality=null;var pointer=0;var length_insertions1=0;var length_deletions1=0;var length_insertions2=0;var length_deletions2=0;while(pointer0?equalities[equalitiesLength-1]:-1;length_insertions1=0;length_deletions1=0;length_insertions2=0;length_deletions2=0;lastequality=null;changes=true}}pointer++}if(changes){this.diff_cleanupMerge(diffs)}this.diff_cleanupSemanticLossless(diffs);pointer=1;while(pointer=overlap_length2){if(overlap_length1>=deletion.length/2||overlap_length1>=insertion.length/2){diffs.splice(pointer,0,[DIFF_EQUAL,insertion.substring(0,overlap_length1)]);diffs[pointer-1][1]=deletion.substring(0,deletion.length-overlap_length1);diffs[pointer+1][1]=insertion.substring(overlap_length1);pointer++}}else{if(overlap_length2>=deletion.length/2||overlap_length2>=insertion.length/2){diffs.splice(pointer,0,[DIFF_EQUAL,deletion.substring(0,overlap_length2)]);diffs[pointer-1][0]=DIFF_INSERT;diffs[pointer-1][1]=insertion.substring(0,insertion.length-overlap_length2);diffs[pointer+1][0]=DIFF_DELETE;diffs[pointer+1][1]=deletion.substring(overlap_length2);pointer++}}pointer++}pointer++}};diff_match_patch.prototype.diff_cleanupSemanticLossless=function(diffs){function diff_cleanupSemanticScore_(one,two){if(!one||!two){return 6}var char1=one.charAt(one.length-1);var char2=two.charAt(0);var nonAlphaNumeric1=char1.match(diff_match_patch.nonAlphaNumericRegex_);var nonAlphaNumeric2=char2.match(diff_match_patch.nonAlphaNumericRegex_);var whitespace1=nonAlphaNumeric1&&char1.match(diff_match_patch.whitespaceRegex_);var whitespace2=nonAlphaNumeric2&&char2.match(diff_match_patch.whitespaceRegex_);var lineBreak1=whitespace1&&char1.match(diff_match_patch.linebreakRegex_);var lineBreak2=whitespace2&&char2.match(diff_match_patch.linebreakRegex_);var blankLine1=lineBreak1&&one.match(diff_match_patch.blanklineEndRegex_);var blankLine2=lineBreak2&&two.match(diff_match_patch.blanklineStartRegex_);if(blankLine1||blankLine2){return 5}else if(lineBreak1||lineBreak2){return 4}else if(nonAlphaNumeric1&&!whitespace1&&whitespace2){return 3}else if(whitespace1||whitespace2){return 2}else if(nonAlphaNumeric1||nonAlphaNumeric2){return 1}return 0}var pointer=1;while(pointer=bestScore){bestScore=score;bestEquality1=equality1;bestEdit=edit;bestEquality2=equality2}}if(diffs[pointer-1][1]!=bestEquality1){if(bestEquality1){diffs[pointer-1][1]=bestEquality1}else{diffs.splice(pointer-1,1);pointer--}diffs[pointer][1]=bestEdit;if(bestEquality2){diffs[pointer+1][1]=bestEquality2}else{diffs.splice(pointer+1,1);pointer--}}}pointer++}};diff_match_patch.nonAlphaNumericRegex_=/[^a-zA-Z0-9]/;diff_match_patch.whitespaceRegex_=/\s/;diff_match_patch.linebreakRegex_=/[\r\n]/;diff_match_patch.blanklineEndRegex_=/\n\r?\n$/;diff_match_patch.blanklineStartRegex_=/^\r?\n\r?\n/;diff_match_patch.prototype.diff_cleanupEfficiency=function(diffs){var changes=false;var equalities=[];var equalitiesLength=0;var lastequality=null;var pointer=0;var pre_ins=false;var pre_del=false;var post_ins=false;var post_del=false;while(pointer0?equalities[equalitiesLength-1]:-1;post_ins=post_del=false}changes=true}}pointer++}if(changes){this.diff_cleanupMerge(diffs)}};diff_match_patch.prototype.diff_cleanupMerge=function(diffs){diffs.push([DIFF_EQUAL,""]);var pointer=0;var count_delete=0;var count_insert=0;var text_delete="";var text_insert="";var commonlength;while(pointer1){if(count_delete!==0&&count_insert!==0){commonlength=this.diff_commonPrefix(text_insert,text_delete);if(commonlength!==0){if(pointer-count_delete-count_insert>0&&diffs[pointer-count_delete-count_insert-1][0]==DIFF_EQUAL){diffs[pointer-count_delete-count_insert-1][1]+=text_insert.substring(0,commonlength)}else{diffs.splice(0,0,[DIFF_EQUAL,text_insert.substring(0,commonlength)]);pointer++}text_insert=text_insert.substring(commonlength);text_delete=text_delete.substring(commonlength)}commonlength=this.diff_commonSuffix(text_insert,text_delete);if(commonlength!==0){diffs[pointer][1]=text_insert.substring(text_insert.length-commonlength)+diffs[pointer][1];text_insert=text_insert.substring(0,text_insert.length-commonlength);text_delete=text_delete.substring(0,text_delete.length-commonlength)}}if(count_delete===0){diffs.splice(pointer-count_insert,count_delete+count_insert,[DIFF_INSERT,text_insert])}else if(count_insert===0){diffs.splice(pointer-count_delete,count_delete+count_insert,[DIFF_DELETE,text_delete])}else{diffs.splice(pointer-count_delete-count_insert,count_delete+count_insert,[DIFF_DELETE,text_delete],[DIFF_INSERT,text_insert])}pointer=pointer-count_delete-count_insert+(count_delete?1:0)+(count_insert?1:0)+1}else if(pointer!==0&&diffs[pointer-1][0]==DIFF_EQUAL){diffs[pointer-1][1]+=diffs[pointer][1];diffs.splice(pointer,1)}else{pointer++}count_insert=0;count_delete=0;text_delete="";text_insert="";break}}if(diffs[diffs.length-1][1]===""){diffs.pop()}var changes=false;pointer=1;while(pointerloc){break}last_chars1=chars1;last_chars2=chars2}if(diffs.length!=x&&diffs[x][0]===DIFF_DELETE){return last_chars2}return last_chars2+(loc-last_chars1)};diff_match_patch.prototype.diff_prettyHtml=function(diffs){var html=[];var pattern_amp=/&/g;var pattern_lt=//g;var pattern_para=/\n/g;for(var x=0;x");switch(op){case DIFF_INSERT:html[x]=''+text+"";break;case DIFF_DELETE:html[x]=''+text+"";break;case DIFF_EQUAL:html[x]=""+text+"";break}}return html.join("")};diff_match_patch.prototype.diff_text1=function(diffs){var text=[];for(var x=0;xthis.Match_MaxBits){throw new Error("Pattern too long for this browser.")}var s=this.match_alphabet_(pattern);var dmp=this;function match_bitapScore_(e,x){var accuracy=e/pattern.length;var proximity=Math.abs(loc-x);if(!dmp.Match_Distance){return proximity?1:accuracy}return accuracy+proximity/dmp.Match_Distance}var score_threshold=this.Match_Threshold;var best_loc=text.indexOf(pattern,loc);if(best_loc!=-1){score_threshold=Math.min(match_bitapScore_(0,best_loc),score_threshold);best_loc=text.lastIndexOf(pattern,loc+pattern.length);if(best_loc!=-1){score_threshold=Math.min(match_bitapScore_(0,best_loc),score_threshold)}}var matchmask=1<=start;j--){var charMatch=s[text.charAt(j-1)];if(d===0){rd[j]=(rd[j+1]<<1|1)&charMatch}else{rd[j]=(rd[j+1]<<1|1)&charMatch|((last_rd[j+1]|last_rd[j])<<1|1)|last_rd[j+1]}if(rd[j]&matchmask){var score=match_bitapScore_(d,j-1);if(score<=score_threshold){score_threshold=score;best_loc=j-1;if(best_loc>loc){start=Math.max(1,2*loc-best_loc)}else{break}}}}if(match_bitapScore_(d+1,loc)>score_threshold){break}last_rd=rd}return best_loc};diff_match_patch.prototype.match_alphabet_=function(pattern){var s={};for(var i=0;i2){this.diff_cleanupSemantic(diffs);this.diff_cleanupEfficiency(diffs)}}else if(a&&typeof a=="object"&&typeof opt_b=="undefined"&&typeof opt_c=="undefined"){diffs=a;text1=this.diff_text1(diffs)}else if(typeof a=="string"&&opt_b&&typeof opt_b=="object"&&typeof opt_c=="undefined"){text1=a;diffs=opt_b}else if(typeof a=="string"&&typeof opt_b=="string"&&opt_c&&typeof opt_c=="object"){text1=a;diffs=opt_c}else{throw new Error("Unknown call format to patch_make.")}if(diffs.length===0){return[]}var patches=[];var patch=new diff_match_patch.patch_obj;var patchDiffLength=0;var char_count1=0;var char_count2=0;var prepatch_text=text1;var postpatch_text=text1;for(var x=0;x=2*this.Patch_Margin){if(patchDiffLength){this.patch_addContext_(patch,prepatch_text);patches.push(patch);patch=new diff_match_patch.patch_obj;patchDiffLength=0;prepatch_text=postpatch_text;char_count1=char_count2}}break}if(diff_type!==DIFF_INSERT){char_count1+=diff_text.length}if(diff_type!==DIFF_DELETE){char_count2+=diff_text.length}}if(patchDiffLength){this.patch_addContext_(patch,prepatch_text);patches.push(patch)}return patches};diff_match_patch.prototype.patch_deepCopy=function(patches){var patchesCopy=[];for(var x=0;xthis.Match_MaxBits){start_loc=this.match_main(text,text1.substring(0,this.Match_MaxBits),expected_loc);if(start_loc!=-1){end_loc=this.match_main(text,text1.substring(text1.length-this.Match_MaxBits),expected_loc+text1.length-this.Match_MaxBits);if(end_loc==-1||start_loc>=end_loc){start_loc=-1}}}else{start_loc=this.match_main(text,text1,expected_loc)}if(start_loc==-1){results[x]=false;delta-=patches[x].length2-patches[x].length1}else{results[x]=true;delta=start_loc-expected_loc;var text2;if(end_loc==-1){text2=text.substring(start_loc,start_loc+text1.length)}else{text2=text.substring(start_loc,end_loc+this.Match_MaxBits)}if(text1==text2){text=text.substring(0,start_loc)+this.diff_text2(patches[x].diffs)+text.substring(start_loc+text1.length)}else{var diffs=this.diff_main(text1,text2,false);if(text1.length>this.Match_MaxBits&&this.diff_levenshtein(diffs)/text1.length>this.Patch_DeleteThreshold){results[x]=false}else{this.diff_cleanupSemanticLossless(diffs);var index1=0;var index2;for(var y=0;ydiffs[0][1].length){var extraLength=paddingLength-diffs[0][1].length;diffs[0][1]=nullPadding.substring(diffs[0][1].length)+diffs[0][1];patch.start1-=extraLength;patch.start2-=extraLength;patch.length1+=extraLength;patch.length2+=extraLength}patch=patches[patches.length-1];diffs=patch.diffs;if(diffs.length==0||diffs[diffs.length-1][0]!=DIFF_EQUAL){diffs.push([DIFF_EQUAL,nullPadding]);patch.length1+=paddingLength;patch.length2+=paddingLength}else if(paddingLength>diffs[diffs.length-1][1].length){var extraLength=paddingLength-diffs[diffs.length-1][1].length;diffs[diffs.length-1][1]+=nullPadding.substring(0,extraLength);patch.length1+=extraLength;patch.length2+=extraLength}return nullPadding};diff_match_patch.prototype.patch_splitMax=function(patches){var patch_size=this.Match_MaxBits;for(var x=0;x2*patch_size){patch.length1+=diff_text.length;start1+=diff_text.length;empty=false;patch.diffs.push([diff_type,diff_text]);bigpatch.diffs.shift()}else{diff_text=diff_text.substring(0,patch_size-patch.length1-this.Patch_Margin);patch.length1+=diff_text.length;start1+=diff_text.length;if(diff_type===DIFF_EQUAL){patch.length2+=diff_text.length;start2+=diff_text.length}else{empty=false}patch.diffs.push([diff_type,diff_text]);if(diff_text==bigpatch.diffs[0][1]){bigpatch.diffs.shift()}else{bigpatch.diffs[0][1]=bigpatch.diffs[0][1].substring(diff_text.length)}}}precontext=this.diff_text2(patch.diffs);precontext=precontext.substring(precontext.length-this.Patch_Margin);var postcontext=this.diff_text1(bigpatch.diffs).substring(0,this.Patch_Margin);if(postcontext!==""){patch.length1+=postcontext.length;patch.length2+=postcontext.length;if(patch.diffs.length!==0&&patch.diffs[patch.diffs.length-1][0]===DIFF_EQUAL){patch.diffs[patch.diffs.length-1][1]+=postcontext}else{patch.diffs.push([DIFF_EQUAL,postcontext])}}if(!empty){patches.splice(++x,0,patch)}}}};diff_match_patch.prototype.patch_toText=function(patches){var text=[];for(var x=0;x"," (__thermiteFunctionVersion_$thermiteBlockID || -1)) {",""," __thermiteFunction_$thermiteBlockID ="," eval(__thermiteMap.$thermiteContextID.$thermiteBlockID.code)",""," __thermiteFunctionVersion_$thermiteBlockID ="," __thermiteMap.$thermiteContextID.$thermiteBlockID.codeVersion","}","","return __thermiteFunction_$thermiteBlockID.apply(this, arguments)","","}"].join("\n"); 8 | 9 | global.__thermiteMap={};function Counter(label){this.label=label;this.value=0}Counter.prototype.getNextID=function(){return this.label+this.value++};function thermiteEval(source,options){options=options||{};var fnTree={};var state={contextID:contextIDCounter.getNextID(),lastSource:source,doLineDiff:options.lineDiff||false,version:1};var rewritten=forEachNode(source,function(node){if(functionNodeTypes.indexOf(node.type)<0)return;var blockID=blockIDCounter.getNextID();rewriteNode(state.contextID,blockID,state.version,node)}).toString();return{hotSwap:function(source){return hotSwap(state,source)},result:invokeEval(options.eval||eval,rewritten)}}function hotSwap(state,source){state.version++;var version=state.version;var contextID=state.contextID;var dmp=new DiffMatchPatch;var diffs=dmp.diff_main(state.lastSource,source,state.doLineDiff);var lookup=survivor(diffs,true);var entries=getEntriesForContext(contextID);var entriesByRangeString={};var persistedBlockIDs={};for(var blockID in entries){var entry=entries[blockID];if(entry.deleted)continue;var rangeString=rangeToString(entry.node.range);entriesByRangeString[rangeString]=entry}forEachNode(source,function(node){if(functionNodeTypes.indexOf(node.type)<0)return;var startSurvived=lookup(node.range[0]);var endSurvived=lookup(node.range[1]);var existingEntry=startSurvived&&endSurvived&&entriesByRangeString[rangeToString([startSurvived,endSurvived])];var blockID=existingEntry?existingEntry.blockID:blockIDCounter.getNextID();rewriteNode(contextID,blockID,version,node);persistedBlockIDs[blockID]=true});for(var blockID in entries)if(!(blockID in persistedBlockIDs))entries[blockID].deleted=true;state.lastSource=source}function getEntriesForContext(contextID){return __thermiteMap[contextID]=__thermiteMap[contextID]||{}}function invokeEval(evaler,code){try{return evaler(code)}catch(err){console.log("Error evaling code:");console.log(code);throw err}}function forEachNode(source,visitor){try{return falafel(source,{ranges:true},visitor)}catch(err){console.log("Error parsing source:");console.log(source);throw err}}function rewriteNode(contextID,blockID,version,node){var code=node.source();var name="";if(node.id&&node.id.name){name=node.id.name;code=code.replace(name,"");node.update(code)}var addVersionTo={FunctionDeclaration:addVersionToDeclaration,FunctionExpression:addVersionToExpression};var boundTemplate=addVersionTo[node.type](template,name).replace(/\$thermiteTemplate/g,name).replace(/\$thermiteBlockID/g,blockID).replace(/\$thermiteContextID/g,contextID);node.update(boundTemplate);var rewritten="("+code+")";var entries=getEntriesForContext(contextID);entries[blockID]={blockID:blockID,node:node,codeVersion:version,code:rewritten}}function addVersionToDeclaration(template,name){return"; "+"var __thermiteFunctionVersion_$thermiteBlockID; "+"var __thermiteFunction_$thermiteBlockID; "+template}function addVersionToExpression(template,name){return"(function "+name+"() { "+"var __thermiteFunctionVersion_$thermiteBlockID; "+"var __thermiteFunction_$thermiteBlockID; "+"return ("+template+");"+"})()"}function rangeToString(range){return"from"+range[0]+"to"+range[1]}exports.eval=thermiteEval}).call(this,typeof global!=="undefined"?global:typeof self!=="undefined"?self:typeof window!=="undefined"?window:{})},{falafel:1,googlediff:7,survivor:9}]},{},[10])(10)}); --------------------------------------------------------------------------------