diff options
Diffstat (limited to 'deps/v8/tools/turbolizer')
45 files changed, 4863 insertions, 2249 deletions
diff --git a/deps/v8/tools/turbolizer/README.md b/deps/v8/tools/turbolizer/README.md index 293f4a20a6..c5ee729d64 100644 --- a/deps/v8/tools/turbolizer/README.md +++ b/deps/v8/tools/turbolizer/README.md @@ -10,15 +10,20 @@ the '--trace-turbo' command-line flag. Turbolizer is build using npm: + cd tools/turbolizer npm i npm run-script build Afterwards, turbolizer can be hosted locally by starting a web server that serve the contents of the turbolizer directory, e.g.: - cd src/tools/turbolizer python -m SimpleHTTPServer 8000 +To deploy to a directory that can be hosted the script `deploy` can be used. The +following command will deploy to the directory /www/turbolizer: + + npm run deploy -- /www/turbolizer + Optionally, profiling data generated by the perf tools in linux can be merged with the .json files using the turbolizer-perf.py file included. The following command is an example of using the perf script: diff --git a/deps/v8/tools/turbolizer/deploy.sh b/deps/v8/tools/turbolizer/deploy.sh index db76dca490..ae069762d9 100755 --- a/deps/v8/tools/turbolizer/deploy.sh +++ b/deps/v8/tools/turbolizer/deploy.sh @@ -7,12 +7,18 @@ if [ ! -d "$DEST" ]; then exit 1 fi -echo "Deploying..." +function copy() { + echo -n "." + cp "$@" +} -cp *.jpg $DEST/ -cp *.png $DEST/ -cp *.css $DEST/ -cp index.html $DEST/ -cp -R build $DEST/ +echo -n "Deploying..." +copy *.jpg $DEST/ +copy *.png $DEST/ +copy *.css $DEST/ +copy index.html $DEST/ +copy info-view.html $DEST/ +copy -R build $DEST/ +echo "done!" echo "Deployed to $DEST/." diff --git a/deps/v8/tools/turbolizer/expand-all.jpg b/deps/v8/tools/turbolizer/expand-all.jpg Binary files differdeleted file mode 100644 index df64a2c4aa..0000000000 --- a/deps/v8/tools/turbolizer/expand-all.jpg +++ /dev/null diff --git a/deps/v8/tools/turbolizer/hide-selected.png b/deps/v8/tools/turbolizer/img/hide-selected-icon.png Binary files differindex 207cdbb89a..207cdbb89a 100644 --- a/deps/v8/tools/turbolizer/hide-selected.png +++ b/deps/v8/tools/turbolizer/img/hide-selected-icon.png diff --git a/deps/v8/tools/turbolizer/hide-unselected.png b/deps/v8/tools/turbolizer/img/hide-unselected-icon.png Binary files differindex 15617b0939..15617b0939 100644 --- a/deps/v8/tools/turbolizer/hide-unselected.png +++ b/deps/v8/tools/turbolizer/img/hide-unselected-icon.png diff --git a/deps/v8/tools/turbolizer/layout-icon.png b/deps/v8/tools/turbolizer/img/layout-icon.png Binary files differindex 95a517afa6..95a517afa6 100644 --- a/deps/v8/tools/turbolizer/layout-icon.png +++ b/deps/v8/tools/turbolizer/img/layout-icon.png diff --git a/deps/v8/tools/turbolizer/img/show-all-icon.png b/deps/v8/tools/turbolizer/img/show-all-icon.png Binary files differnew file mode 100644 index 0000000000..50fc845f01 --- /dev/null +++ b/deps/v8/tools/turbolizer/img/show-all-icon.png diff --git a/deps/v8/tools/turbolizer/img/show-control-icon.png b/deps/v8/tools/turbolizer/img/show-control-icon.png Binary files differnew file mode 100644 index 0000000000..4238bee9cc --- /dev/null +++ b/deps/v8/tools/turbolizer/img/show-control-icon.png diff --git a/deps/v8/tools/turbolizer/live.png b/deps/v8/tools/turbolizer/img/toggle-hide-dead-icon.png Binary files differindex ac72bb93e8..ac72bb93e8 100644 --- a/deps/v8/tools/turbolizer/live.png +++ b/deps/v8/tools/turbolizer/img/toggle-hide-dead-icon.png diff --git a/deps/v8/tools/turbolizer/types.png b/deps/v8/tools/turbolizer/img/toggle-types-icon.png Binary files differindex 8fead8f079..8fead8f079 100644 --- a/deps/v8/tools/turbolizer/types.png +++ b/deps/v8/tools/turbolizer/img/toggle-types-icon.png diff --git a/deps/v8/tools/turbolizer/search.png b/deps/v8/tools/turbolizer/img/zoom-selection-icon.png Binary files differindex 12dc3e3469..12dc3e3469 100644 --- a/deps/v8/tools/turbolizer/search.png +++ b/deps/v8/tools/turbolizer/img/zoom-selection-icon.png diff --git a/deps/v8/tools/turbolizer/index.html b/deps/v8/tools/turbolizer/index.html index ea89a61261..f970a6df04 100644 --- a/deps/v8/tools/turbolizer/index.html +++ b/deps/v8/tools/turbolizer/index.html @@ -1,63 +1,46 @@ -<!DOCTYPE HTML> +<!DOCTYPE html> <html> - <head> - <title>Turbolizer</title> - <link rel="stylesheet" href="turbo-visualizer.css" /> - <link rel="stylesheet" href="prettify.css" /> - <link rel="icon" type="image/png" href="turbolizer.png"> - </head> - <body> - <div id="left" class="viewpane scrollable"></div> - <div class="resizer-left"></div> - <div id="middle" class="viewpane"> - <div id="graph-toolbox-anchor"> - <span id="graph-toolbox"> - <input id="layout" type="image" title="layout graph" src="layout-icon.png" - alt="layout graph" class="button-input"> - <input id="show-all" type="image" title="show all nodes" src="expand-all.jpg" - alt="show all nodes" class="button-input"> - <input id="toggle-hide-dead" type="image" title="show only live nodes" src="live.png" - alt="only live nodes" class="button-input"> - <input id="hide-unselected" type="image" title="hide unselected nodes" - src="hide-unselected.png" alt="hide unselected nodes" class="button-input"> - <input id="hide-selected" type="image" title="hide selected nodes" - src="hide-selected.png" alt="hide selected nodes" class="button-input"> - <input id="zoom-selection" type="image" title="zoom to selection" - src="search.png" alt="zoom to selection" class="button-input"> - <input id="toggle-types" type="image" title="show/hide types" - src="types.png" alt="show/hide types" class="button-input"> - <input id="search-input" type="text" title="search nodes for regex" - alt="search node for regex" class="search-input" - placeholder="find with regexp…"> - <select id="display-selector"> - <option disabled selected>(please open a file)</option> - </select> - </span> - </div> - <div id="load-file"> - <input id="upload-helper" type="file"> - <input id="upload" type="image" title="load graph" class="button-input" - src="upload-icon.png" alt="upload graph"> - </div> - <div id='text-placeholder' width="0px" height="0px" style="position: absolute; top:100000px;" ><svg><text text-anchor="right"> - <tspan white-space="inherit" id="text-measure"/> - </text></svg></div> +<!-- +Copyright 2019 the V8 project authors. All rights reserved. Use of this source +code is governed by a BSD-style license that can be found in the LICENSE file. +--> +<head> + <meta charset="utf-8"> + <title>V8 Turbolizer</title> + <link rel="stylesheet" href="turbo-visualizer.css"> + <link rel="stylesheet" href="tabs.css"> + <link rel="stylesheet" href="prettify.css"> + <link rel="icon" type="image/png" href="turbolizer.png"> +</head> + +<body> + <div id="left" class="content"></div> + <div id="resizer-left" class="resizer"></div> + <div id="middle"> + + <div id="load-file"> + <input id="upload-helper" type="file"> + <input id="upload" type="image" title="load graph" class="button-input" src="upload-icon.png" alt="upload graph"> </div> - <div class="resizer-right"></div> - <div id="right" class="viewpane scrollable"></div> - <div id="source-collapse" class="collapse-pane"> - <input id="source-expand" type="image" title="show source" - src="right-arrow.png" class="button-input invisible"> - <input id="source-shrink" type="image" title="hide source" - src="left-arrow.png" class="button-input"> - </div> - <div id="disassembly-collapse" class="collapse-pane"> - <input id="disassembly-expand" type="image" title="show disassembly" - src="left-arrow.png" class="button-input invisible"> - <input id="disassembly-shrink" type="image" title="hide disassembly" - src="right-arrow.png" class="button-input"> - </div> - <script src="https://cdn.rawgit.com/google/code-prettify/master/loader/run_prettify.js"></script> - <script src="build/turbolizer.js"></script> - </body> + </div> + <div id="resizer-right" class="resizer"></div> + <div id="right" class="content"></div> + <div id="source-collapse" class="collapse-pane"> + <input id="source-expand" type="image" title="show source" src="right-arrow.png" class="button-input invisible"> + <input id="source-shrink" type="image" title="hide source" src="left-arrow.png" class="button-input"> + </div> + <div id="disassembly-collapse" class="collapse-pane"> + <input id="disassembly-expand" type="image" title="show disassembly" src="left-arrow.png" class="button-input invisible"> + <input id="disassembly-shrink" type="image" title="hide disassembly" src="right-arrow.png" class="button-input"> + </div> + <div id="text-placeholder" width="0" height="0" style="position: absolute; top:100000px;"> + <svg> + <text text-anchor="right"> + <tspan white-space="inherit" id="text-measure"> + </text> + </svg> + </div> + <script src="https://cdn.rawgit.com/google/code-prettify/master/loader/run_prettify.js"></script> + <script src="build/turbolizer.js"></script> +</body> </html> diff --git a/deps/v8/tools/turbolizer/info-view.html b/deps/v8/tools/turbolizer/info-view.html new file mode 100644 index 0000000000..7c714c3f9f --- /dev/null +++ b/deps/v8/tools/turbolizer/info-view.html @@ -0,0 +1,119 @@ +<div>This is view contains hints about available keyboard shortcuts.</div> +<div class="info-topic" id="info-global"> + <div class="info-topic-header">Global shortcuts</div> + <div class="info-topic-content"> + <table> + <tr> + <td>CTRL+L</td> + <td>Open load file dialog.</td> + </tr> + <tr> + <td>CTRL+R</td> + <td>Reload turbolizer (Chrome shortcut)</td> + </tr> + </table> + </div> +</div> +<div class="info-topic" id="info-graph-view"> + <div class="info-topic-header">Graph view</div> + <div class="info-topic-content"> + <table> + <tr> + <td>r</td> + <td>Relayout graph</td> + </tr> + <tr> + <td>a</td> + <td>Select all nodes</td> + </tr> + <tr> + <td>/</td> + <td>Select search box</td> + </tr> + </table> + </div> +</div> +<div class="info-topic" id="info-graph-nodes"> + <div class="info-topic-header">TurboFan graph nodes</div> + <div class="info-topic-content"> + <div>The following commands transform node selections, i.e. each operation will be applied + to each node in the current selection and the union of the resulting nodes will become the + new selection.</div> + <table> + <tr> + <td>UP</td> + <td>Select all input nodes</td> + </tr> + <tr> + <td>DOWN</td> + <td>Select all output nodes</td> + </tr> + <tr> + <td>1-9</td> + <td>Select input node 1-9</td> + </tr> + <tr> + <td>CTRL+1-9</td> + <td>Toggle input edge 1-9</td> + </tr> + <tr> + <td>c</td> + <td>Select control output node</td> + </tr> + <tr> + <td>e</td> + <td>Select effect output node</td> + </tr> + <tr> + <td>o</td> + <td>Reveal node's input nodes</td> + </tr> + <tr> + <td>i</td> + <td>Reveal node's output nodes</td> + </tr> + <tr> + <td>s</td> + <td>Select node's origin node</td> + </tr> + <tr> + <td>/</td> + <td>Select search box</td> + </tr> + </table> + </div> +</div> +<div class="info-topic" id="info-graph-search"> + <div class="info-topic-header">Graph search</div> + <div class="info-topic-content"> + <table> + <tr> + <td>ENTER</td> + <td>Select nodes according to regular expression. Invisible nodes are included depending on the state of the + checkbox "only visible".</td> + </tr> + <tr> + <td>CTRL+ENTER</td> + <td>Select nodes according to regular expression, always including invisible nodes regardless of checkbox.</td> + </tr> + </table> + <div style="font-weight: bold"> + Useful patterns + </div> + <table> + <tr> + <td>IfTrue</td> + <td>Select nodes which have 'IfTrue' in title or description.</td> + </tr> + <tr> + <td>^42:</td> + <td>Select exactly the node with id 14.</td> + </tr> + <tr> + <td>Origin: #42 </td> + <td>Select nodes which were created while node with id 42 was reduced. This is inaccurate if the node was + changed in-place.</td> + </tr> + </table> + </div> +</div> diff --git a/deps/v8/tools/turbolizer/package-lock.json b/deps/v8/tools/turbolizer/package-lock.json index fc9557f76d..34dea91004 100644 --- a/deps/v8/tools/turbolizer/package-lock.json +++ b/deps/v8/tools/turbolizer/package-lock.json @@ -4,19 +4,16 @@ "lockfileVersion": 1, "requires": true, "dependencies": { - "@types/commander": { - "version": "2.12.2", - "resolved": "https://registry.npmjs.org/@types/commander/-/commander-2.12.2.tgz", - "integrity": "sha512-0QEFiR8ljcHp9bAbWxecjVRuAMr16ivPiGOw6KFQBVrVd0RQIcM3xKdRisH2EDWgVWujiYtHwhSkSUoAAGzH7Q==", - "dev": true, - "requires": { - "commander": "*" - } + "@koa/cors": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/@koa/cors/-/cors-2.2.2.tgz", + "integrity": "sha512-Ollvsy3wB8+7R9w6hPVzlj3wekF6nK+IHpHj7faSPVXCkahqCwNEPp9+0C4b51RDkdpHjevLEGLOKuVjqtXgSQ==", + "dev": true }, "@types/d3": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@types/d3/-/d3-5.0.0.tgz", - "integrity": "sha512-BVfPw7ha+UgsG24v6ymerMY4+pJgQ/6p+hJA4loCeaaqV9snGS/G6ReVaQEn8Himn67dWn/Je9WhRbnDO7MzLw==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@types/d3/-/d3-5.5.0.tgz", + "integrity": "sha512-Bz9EAhWnaO93jLYSAT13blgzwP5Z0grO5THBOXSMeWHIIFHA7ntJSLpHSCr1kDtQunEZKCYT9OfE+4lYY/PwlA==", "requires": { "@types/d3-array": "*", "@types/d3-axis": "*", @@ -52,30 +49,30 @@ } }, "@types/d3-array": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-1.2.1.tgz", - "integrity": "sha512-YBaAfimGdWE4nDuoGVKsH89/dkz2hWZ0i8qC+xxqmqi+XJ/aXiRF0jPtzXmN7VdkpVjy1xuDmM5/m1FNuB6VWA==" + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-1.2.4.tgz", + "integrity": "sha512-3r1fOAAb+SGfcOGXty/LGvoP0ovMec4UtGNUyHOSzYyvSGpmt+eNMxLowol/3HryusevznSfcHZebEShXMwsZA==" }, "@types/d3-axis": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/@types/d3-axis/-/d3-axis-1.0.10.tgz", - "integrity": "sha512-5YF0wfdQMPKw01VAAupLIlg/T4pn5M3/vL9u0KZjiemnVnnKBEWE24na4X1iW+TfZiYJ8j+BgK2KFYnAAT54Ug==", + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@types/d3-axis/-/d3-axis-1.0.11.tgz", + "integrity": "sha512-cuigApCyCwYJxaQPghj+BqaxzbdRdT/lpZBMtF7EuEIJ61NMQ8yvGnqFvHCIgJEmUu2Wb2wiZqy9kiHi3Ddftg==", "requires": { "@types/d3-selection": "*" } }, "@types/d3-brush": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@types/d3-brush/-/d3-brush-1.0.8.tgz", - "integrity": "sha512-9Thv09jvolu9T1BE3fHmIeYSgbwSpdxtF6/A5HZEDjSTfgtA0mtaXRk5AiWOo0KjuLsI+/7ggD3ZGN5Ye8KXPQ==", + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@types/d3-brush/-/d3-brush-1.0.9.tgz", + "integrity": "sha512-mAx8IVc0luUHfk51pl0UN1vzybnAzLMUsvIwLt3fbsqqPkSXr+Pu1AxOPPeyNc27LhHJnfH/LCV7Jlv+Yzqu1A==", "requires": { "@types/d3-selection": "*" } }, "@types/d3-chord": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/@types/d3-chord/-/d3-chord-1.0.7.tgz", - "integrity": "sha512-WbCN7SxhZMpQQw46oSjAovAmvl3IdjhLuQ4r7AXCzNKyxtXXBWuihSPZ4bVwFQF3+S2z37i9d4hfUBatcSJpog==" + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/d3-chord/-/d3-chord-1.0.8.tgz", + "integrity": "sha512-F0ftYOo7FenAIxsRjXLt8vbij0NLDuVcL+xaGY7R9jUmF2Mrpj1T5XukBI9Cad+Ei7YSxEWREIO+CYcaKCl2qQ==" }, "@types/d3-collection": { "version": "1.0.7", @@ -88,9 +85,9 @@ "integrity": "sha512-xwb1tqvYNWllbHuhMFhiXk63Imf+QNq/dJdmbXmr2wQVnwGenCuj3/0IWJ9hdIFQIqzvhT7T37cvx93jtAsDbQ==" }, "@types/d3-contour": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@types/d3-contour/-/d3-contour-1.2.1.tgz", - "integrity": "sha512-p8iC4KeVFyT3qRTGQRj0Jf5QDdPsDUevBEnma7gEsY1yDolVSLanG2eFAiLV+xj8/5DK7oU7Ey8z0drs3pbsug==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@types/d3-contour/-/d3-contour-1.3.0.tgz", + "integrity": "sha512-AUCUIjEnC5lCGBM9hS+MryRaFLIrPls4Rbv6ktqbd+TK/RXZPwOy9rtBWmGpbeXcSOYCJTUDwNJuEnmYPJRxHQ==", "requires": { "@types/d3-array": "*", "@types/geojson": "*" @@ -102,17 +99,17 @@ "integrity": "sha512-xyWJQMr832vqhu6fD/YqX+MSFBWnkxasNhcStvlhqygXxj0cKqPft0wuGoH5TIq5ADXgP83qeNVa4R7bEYN3uA==" }, "@types/d3-drag": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@types/d3-drag/-/d3-drag-1.2.1.tgz", - "integrity": "sha512-J9liJ4NNeV0oN40MzPiqwWjqNi3YHCRtHNfNMZ1d3uL9yh1+vDuo346LBEr8yyBm30WHvrHssAkExVZrGCswtA==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@types/d3-drag/-/d3-drag-1.2.2.tgz", + "integrity": "sha512-+UKFeaMVTfSQvMO0PTzOyLXSr7OZbF2Rx1iNVwo2XsyiOsd4MSuLyJKUwRmGn67044QpbNzr+VD6/8iBBLExWw==", "requires": { "@types/d3-selection": "*" } }, "@types/d3-dsv": { - "version": "1.0.33", - "resolved": "https://registry.npmjs.org/@types/d3-dsv/-/d3-dsv-1.0.33.tgz", - "integrity": "sha512-jx5YvaVC3Wfh6LobaiWTeU1NkvL2wPmmpmajk618bD+xVz98yNWzmZMvmlPHGK0HXbMeHmW/6oVX48V9AH1bRQ==" + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/@types/d3-dsv/-/d3-dsv-1.0.34.tgz", + "integrity": "sha512-/grhPLPFJ17GxH18EB8OSOlqcsLahz1xlKb08cVUu3OP83wBPxfoX2otVvLJDTL6BEP0kyTNsA2SdGrRhWwSBQ==" }, "@types/d3-ease": { "version": "1.0.7", @@ -120,9 +117,9 @@ "integrity": "sha1-k6MBhovp4VBh89RDQ7GrP4rLbwk=" }, "@types/d3-fetch": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@types/d3-fetch/-/d3-fetch-1.1.2.tgz", - "integrity": "sha512-w6ANZv/mUh+6IV3drT22zgPWMRobzuGXhzOZC8JPD+ygce0/Vx6vTci3m3dizkocnQQCOwNbrWWWPYqpWiKzRQ==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@types/d3-fetch/-/d3-fetch-1.1.4.tgz", + "integrity": "sha512-POR6AHGEjUk8VjHhU2HfcKxVKnZUIhhHjU65greJs34NlfmWfaDxE+6+ABeMsRCAWa/DRTRNe+1ExuMPBwb7/Q==", "requires": { "@types/d3-dsv": "*" } @@ -146,14 +143,14 @@ } }, "@types/d3-hierarchy": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@types/d3-hierarchy/-/d3-hierarchy-1.1.2.tgz", - "integrity": "sha512-L+Ht4doqlCIH8jYN2AC1mYIOj13OxlRhdWNWXv2pc3o5A9i3YmQ0kz6A7w8c+Ujylfusi/FO+zVlVnQoOHc2Qw==" + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@types/d3-hierarchy/-/d3-hierarchy-1.1.5.tgz", + "integrity": "sha512-DKhqURrURt2c7MsF9sHiF2wrWf2+yZR4Q9oIG026t/ZY4VWoM0Yd7UonaR+rygyReWcFSEjKC/+5A27TgD8R8g==" }, "@types/d3-interpolate": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-1.2.0.tgz", - "integrity": "sha512-qM9KlUrqbwIhBRtw9OtAEbkis1AxsOJEun2uxaX/vEsBp3vyNBmhPz9boXXEqic9ZRi7fCpUNRwyZvxa0PioIw==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-1.3.0.tgz", + "integrity": "sha512-Ng4ds7kPSvP/c3W3J5PPUQlgewif1tGBqCeh5lgY+UG82Y7H9zQ8c2gILsEFDLg7wRGOwnuKZ940Q/LSN14w9w==", "requires": { "@types/d3-color": "*" } @@ -169,9 +166,9 @@ "integrity": "sha512-E6Kyodn9JThgLq20nxSbEce9ow5/ePgm9PX2EO6W1INIL4DayM7cFaiG10DStuamjYAd0X4rntW2q+GRjiIktw==" }, "@types/d3-quadtree": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/d3-quadtree/-/d3-quadtree-1.0.5.tgz", - "integrity": "sha1-HOHmWerkUw3wyxJ/KX8XQaNnqC4=" + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/d3-quadtree/-/d3-quadtree-1.0.6.tgz", + "integrity": "sha512-sphVuDdiSIaxLt9kQgebJW98pTktQ/xuN7Ysd8X68Rnjeg/q8+c36/ShlqU52qoKg9nob/JEHH1uQMdxURZidQ==" }, "@types/d3-random": { "version": "1.1.1", @@ -179,35 +176,35 @@ "integrity": "sha512-jUPeBq1XKK9/5XasTvy5QAUwFeMsjma2yt/nP02yC2Tijovx7i/W5776U/HZugxc5SSmtpx4Z3g9KFVon0QrjQ==" }, "@types/d3-scale": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-2.0.1.tgz", - "integrity": "sha512-D5ZWv8ToLvqacE7XkdMNHMiiVDULdDxT7FMMGU0YJC3/nVzBmApjyTyxracUWOQyY3KK7YhZ05on8pOcNi0dfQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-2.1.0.tgz", + "integrity": "sha512-vLzRDF5lRxZdCLUOvmw90pkiuSsZdgroBQaat0Ov7Z7OnO9iJsPSm/TZw3wW6m2z/NhIn1E4N0RLNfEi1k4kAA==", "requires": { "@types/d3-time": "*" } }, "@types/d3-scale-chromatic": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@types/d3-scale-chromatic/-/d3-scale-chromatic-1.2.0.tgz", - "integrity": "sha512-bhS2SVzUzRtrxp1REhGCfHmj8pyDv9oDmsonYiPvBl8KCxPJTxnfXBF39PzAJrYnRKM41TR0kQzsJvL+NmcDtg==" + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@types/d3-scale-chromatic/-/d3-scale-chromatic-1.3.0.tgz", + "integrity": "sha512-JqQH5uu1kmdQEa6XSu7NYzQM71lL1YreBPS5o8SnmEDcBRKL6ooykXa8iFPPOEUiTah25ydi+cTrbsogBSMNSQ==" }, "@types/d3-selection": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@types/d3-selection/-/d3-selection-1.3.1.tgz", - "integrity": "sha512-G+eO+2G1iW3GNrROxhoU+ar+bIJbQq1QkxcfhwjQ19xA20n3T31j5pSJqAOWvPSoFTz4Ets/DQgYhmgT4jepDg==" + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/@types/d3-selection/-/d3-selection-1.3.4.tgz", + "integrity": "sha512-WQ6Ivy7VuUlZ/Grqc8493ZxC+y/fpvZLy5+8ELvmCr2hll8eJPUqC05l6fgRRA7kjqlpbH7lbmvY6pRKf6yzxw==" }, "@types/d3-shape": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-1.2.3.tgz", - "integrity": "sha512-iP9TcX0EVi+LlX+jK9ceS+yhEz5abTitF+JaO2ugpRE/J+bccaYLe/0/3LETMmdaEkYarIyboZW8OF67Mpnj1w==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-1.2.7.tgz", + "integrity": "sha512-b2jpGcddOseeNxchaR1SNLqA5xZAbgKix3cXiFeuGeYIEAEUu91UbtelCxOHIUTbNURFnjcbkf4plRbejNzVaQ==", "requires": { "@types/d3-path": "*" } }, "@types/d3-time": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-1.0.8.tgz", - "integrity": "sha512-/UCphyyw97YAq4zKsuXH33R3UNB4jDSza0fLvMubWr/ONh9IePi1NbgFP222blhiCe724ebJs8U87+aDuAq/jA==" + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-1.0.9.tgz", + "integrity": "sha512-m+D4NbQdDlTVaO7QgXAnatR3IDxQYDMBtRhgSCi5rs9R1LPq1y7/2aqa1FJ2IWjFm1mOV63swDxonnCDlHgHMA==" }, "@types/d3-time-format": { "version": "2.1.0", @@ -215,27 +212,27 @@ "integrity": "sha512-/myT3I7EwlukNOX2xVdMzb8FRgNzRMpsZddwst9Ld/VFe6LyJyRp0s32l/V9XoUzk+Gqu56F/oGk6507+8BxrA==" }, "@types/d3-timer": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/@types/d3-timer/-/d3-timer-1.0.7.tgz", - "integrity": "sha512-830pT+aYZrgbA91AuynP3KldfB1A1s60d0gKiV+L7JcSKSJapUzUffAm8VZod7RQOxF5SzoItV6cvrTzjbmrJQ==" + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/d3-timer/-/d3-timer-1.0.8.tgz", + "integrity": "sha512-AKUgQ/nljUFcUO2P3gK24weVI5XwUTdJvjoh8gJ0yxT4aJ+d7t2Or3TB+k9dEYl14BAjoj32D0ky+YzQSVszfg==" }, "@types/d3-transition": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@types/d3-transition/-/d3-transition-1.1.1.tgz", - "integrity": "sha512-GHTghl0YYB8gGgbyKxVLHyAp9Na0HqsX2U7M0u0lGw4IdfEaslooykweZ8fDHW13T+KZeZAuzhbmqBZVFO+6kg==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@types/d3-transition/-/d3-transition-1.1.3.tgz", + "integrity": "sha512-1EukXNuVu/z2G1GZpZagzFJnie9C5zze17ox/vhTgGXNy46rYAm4UkhLLlUeeZ1ndq88k95SOeC8898RpKMLOQ==", "requires": { "@types/d3-selection": "*" } }, "@types/d3-voronoi": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/@types/d3-voronoi/-/d3-voronoi-1.1.7.tgz", - "integrity": "sha512-/dHFLK5jhXTb/W4XEQcFydVk8qlIAo85G3r7+N2fkBFw190l0R1GQ8C1VPeXBb2GfSU5GbT2hjlnE7i7UY5Gvg==" + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/@types/d3-voronoi/-/d3-voronoi-1.1.8.tgz", + "integrity": "sha512-zqNhW7QsYQGlfOdrwPNPG3Wk64zUa4epKRurkJ/dVc6oeXrB+iTDt8sRZ0KZKOOXvvfa1dcdB0e45TZeLBiodQ==" }, "@types/d3-zoom": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/@types/d3-zoom/-/d3-zoom-1.7.1.tgz", - "integrity": "sha512-Ofjwz6Pt53tRef9TAwwayN+JThNVYC/vFOepa/H4KtwjhsqkmEseHvc2jpJM7vye5PQ5XHtTSOpdY4Y/6xZWEg==", + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/@types/d3-zoom/-/d3-zoom-1.7.3.tgz", + "integrity": "sha512-Tz7+z4+Id0MxERw/ozinC5QHJmGLARs9Mpi/7VVfiR+9AHcFGe9q+fjQa30/oPNY8WPuCh5p5uuXmBYAJ3y91Q==", "requires": { "@types/d3-interpolate": "*", "@types/d3-selection": "*" @@ -247,21 +244,91 @@ "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==" }, "@types/geojson": { - "version": "7946.0.3", - "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.3.tgz", - "integrity": "sha512-BYHiG1vQJ7T93uswzuXZ0OBPWqj5tsAPtaMDQADV8sn2InllXarwg9llr6uaW22q1QCwBZ81gVajOpYWzjesug==" + "version": "7946.0.4", + "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.4.tgz", + "integrity": "sha512-MHmwBtCb7OCv1DSivz2UNJXPGU/1btAWRKlqJ2saEhVJkpkvqHMMaOpKg0v4sAbDWSQekHGvPVMM8nQ+Jen03Q==" + }, + "@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", + "dev": true, + "optional": true }, "@types/node": { - "version": "10.5.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.5.2.tgz", - "integrity": "sha512-m9zXmifkZsMHZBOyxZWilMwmTlpC8x5Ty360JKTiXvlXZfBWYpsg9ZZvP/Ye+iZUh+Q+MxDLjItVTWIsfwz+8Q==" + "version": "10.12.18", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.18.tgz", + "integrity": "sha512-fh+pAqt4xRzPfqA6eh3Z2y6fyZavRIumvjhaCL753+TVkGKGhpPeyrJG2JftD0T9q4GF00KjefsQ+PQNDdWQaQ==" + }, + "JSONStream": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", + "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", + "dev": true, + "requires": { + "jsonparse": "^1.2.0", + "through": ">=2.2.7 <3" + } }, - "@types/semver": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-5.5.0.tgz", - "integrity": "sha512-41qEJgBH/TWgo5NFSvBCJ1qkoi3Q6ONSF2avrHq1LVEZfYpdHmj0y9SuTK+u9ZhG1sYQKBL1AWXKyLWP4RaUoQ==", + "accepts": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.5.tgz", + "integrity": "sha1-63d99gEXI6OxTopywIBcjoZ0a9I=", + "dev": true, + "requires": { + "mime-types": "~2.1.18", + "negotiator": "0.6.1" + } + }, + "ansi-escape-sequences": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/ansi-escape-sequences/-/ansi-escape-sequences-4.0.0.tgz", + "integrity": "sha512-v+0wW9Wezwsyb0uF4aBVCjmSqit3Ru7PZFziGF0o2KwTvN2zWfTi3BRLq9EkJFdg3eBbyERXGTntVpBxH1J68Q==", + "dev": true, + "requires": { + "array-back": "^2.0.0" + } + }, + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8=", "dev": true }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "argv-tools": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/argv-tools/-/argv-tools-0.1.1.tgz", + "integrity": "sha512-Cc0dBvx4dvrjjKpyDA6w8RlNAw8Su30NvZbWl/Tv9ZALEVlLVkWQiHMi84Q0xNfpVuSaiQbYkdmWK8g1PLGhKw==", + "dev": true, + "requires": { + "array-back": "^2.0.0", + "find-replace": "^2.0.1" + } + }, "arr-diff": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", @@ -275,11 +342,112 @@ "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==" }, + "array-back": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-2.0.0.tgz", + "integrity": "sha512-eJv4pLLufP3g5kcZry0j6WXpIbzYw9GUB4mVJZno9wfwiBxbizTnHCw3VJb07cBihbFX48Y7oSrW9y+gt4glyw==", + "dev": true, + "requires": { + "typical": "^2.6.1" + }, + "dependencies": { + "typical": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/typical/-/typical-2.6.1.tgz", + "integrity": "sha1-XAgOXWYcu+OCWdLnCjxyU+hziB0=", + "dev": true + } + } + }, "array-unique": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=" }, + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", + "dev": true + }, + "assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true + }, + "async-limiter": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz", + "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==", + "dev": true + }, + "babel-code-frame": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", + "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", + "dev": true, + "requires": { + "chalk": "^1.1.3", + "esutils": "^2.0.2", + "js-tokens": "^3.0.2" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + } + } + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "basic-auth": { + "version": "1.1.0", + "resolved": "http://registry.npmjs.org/basic-auth/-/basic-auth-1.1.0.tgz", + "integrity": "sha1-RSIe5Cn37h5QNb4/UVM/HN/SmIQ=", + "dev": true + }, + "batch": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", + "integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=", + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, "braces": { "version": "1.8.5", "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", @@ -290,26 +458,233 @@ "repeat-element": "^1.1.2" } }, + "browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true + }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "dev": true + }, "builtin-modules": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-2.0.0.tgz", - "integrity": "sha512-3U5kUA5VPsRUA3nofm/BXX7GVHKfxz0hOBAPxXrIvHzlDRkQVqEn6yi8QJegxl4LzOHLdvb7XF5dVawa/VVYBg==" + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.0.0.tgz", + "integrity": "sha512-hMIeU4K2ilbXV6Uv93ZZ0Avg/M91RaKXucQ+4me2Do1txxBDyDZWCBa5bJSLqoNTRpXTLwEzIk1KmloenDDjhg==" + }, + "byte-size": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/byte-size/-/byte-size-4.0.4.tgz", + "integrity": "sha512-82RPeneC6nqCdSwCX2hZUz3JPOvN5at/nTEw/CMf05Smu3Hrpo9Psb7LjN+k+XndNArG1EY8L4+BM3aTM4BCvw==", + "dev": true + }, + "bytes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=", + "dev": true + }, + "cache-content-type": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-content-type/-/cache-content-type-1.0.1.tgz", + "integrity": "sha512-IKufZ1o4Ut42YUrZSo8+qnMTrFuKkvyoLXUywKz9GJ5BrhOFGhLdkx9sG4KAnVvbY6kEcSFjLQul+DVmBm2bgA==", + "dev": true, + "requires": { + "mime-types": "^2.1.18", + "ylru": "^1.2.0" + } + }, + "chai": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz", + "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==", + "dev": true, + "requires": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.2", + "deep-eql": "^3.0.1", + "get-func-name": "^2.0.0", + "pathval": "^1.1.0", + "type-detect": "^4.0.5" + } + }, + "chalk": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", + "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "check-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", + "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", + "dev": true + }, + "cli-commands": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/cli-commands/-/cli-commands-0.4.0.tgz", + "integrity": "sha512-zAvJlR7roeMgpUIhMDYATYL90vz+9ffuyPr0+qq4LzcZ0Jq+gM+H1KdYKxerc6U2nhitiDEx79YiJlXdrooEOA==", + "dev": true, + "requires": { + "command-line-args": "^5.0.2", + "command-line-commands": "^2.0.1" + } + }, + "co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", + "dev": true + }, + "co-body": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/co-body/-/co-body-6.0.0.tgz", + "integrity": "sha512-9ZIcixguuuKIptnY8yemEOuhb71L/lLf+Rl5JfJEUiDNJk0e02MBt7BPxR2GEh5mw8dPthQYR4jPI/BnS1MQgw==", + "dev": true, + "requires": { + "inflation": "^2.0.0", + "qs": "^6.5.2", + "raw-body": "^2.3.3", + "type-is": "^1.6.16" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "command-line-args": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/command-line-args/-/command-line-args-5.0.2.tgz", + "integrity": "sha512-/qPcbL8zpqg53x4rAaqMFlRV4opN3pbla7I7k9x8kyOBMQoGT6WltjN6sXZuxOXw6DgdK7Ad+ijYS5gjcr7vlA==", + "dev": true, + "requires": { + "argv-tools": "^0.1.1", + "array-back": "^2.0.0", + "find-replace": "^2.0.1", + "lodash.camelcase": "^4.3.0", + "typical": "^2.6.1" + }, + "dependencies": { + "typical": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/typical/-/typical-2.6.1.tgz", + "integrity": "sha1-XAgOXWYcu+OCWdLnCjxyU+hziB0=", + "dev": true + } + } + }, + "command-line-commands": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/command-line-commands/-/command-line-commands-2.0.1.tgz", + "integrity": "sha512-m8c2p1DrNd2ruIAggxd/y6DgygQayf6r8RHwchhXryaLF8I6koYjoYroVP+emeROE9DXN5b9sP1Gh+WtvTTdtQ==", + "dev": true, + "requires": { + "array-back": "^2.0.0" + } + }, + "command-line-usage": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/command-line-usage/-/command-line-usage-5.0.5.tgz", + "integrity": "sha512-d8NrGylA5oCXSbGoKz05FkehDAzSmIm4K03S5VDh4d5lZAtTWfc3D1RuETtuQCn8129nYfJfDdF7P/lwcz1BlA==", + "dev": true, + "requires": { + "array-back": "^2.0.0", + "chalk": "^2.4.1", + "table-layout": "^0.4.3", + "typical": "^2.6.1" + }, + "dependencies": { + "typical": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/typical/-/typical-2.6.1.tgz", + "integrity": "sha1-XAgOXWYcu+OCWdLnCjxyU+hziB0=", + "dev": true + } + } }, "commander": { "version": "2.15.1", "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==" }, - "commandpost": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/commandpost/-/commandpost-1.3.0.tgz", - "integrity": "sha512-T62tyrmYTkaRDbV2z1k2yXTyxk0cFptXYwo1cUbnfHtp7ThLgQ9/90jG1Ym5WLZgFhvOTaHA5VSARWJ9URpLDw==", + "common-log-format": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/common-log-format/-/common-log-format-0.1.4.tgz", + "integrity": "sha512-BXcgq+wzr2htmBmnT7cL7YHzPAWketWbr4kozjoM9kWe4sk3+zMgjcH0HO+EddjDlEw2LZysqLpVRwbF318tDw==", + "dev": true + }, + "compressible": { + "version": "2.0.15", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.15.tgz", + "integrity": "sha512-4aE67DL33dSW9gw4CI2H/yTxqHLNcxp0yS6jB+4h+wr3e43+1z7vm0HU9qXOH8j+qjKuL8+UtkOxYQSMq60Ylw==", + "dev": true, + "requires": { + "mime-db": ">= 1.36.0 < 2" + } + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "content-disposition": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", + "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ=", + "dev": true + }, + "content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", + "dev": true + }, + "cookies": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/cookies/-/cookies-0.7.2.tgz", + "integrity": "sha512-J2JjH9T3PUNKPHknprxgCrCaZshIfxW2j49gq1E1CP5Micj1LppWAR2y9EHSQAzEiX84zOsScWNwUZ0b/ChlMw==", + "dev": true, + "requires": { + "depd": "~1.1.2", + "keygrip": "~1.0.2" + } + }, + "copy-to": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/copy-to/-/copy-to-2.0.1.tgz", + "integrity": "sha1-JoD7uAaKSNCGVrYJgJK9r8kG9KU=", + "dev": true + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", "dev": true }, "d3": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/d3/-/d3-5.5.0.tgz", - "integrity": "sha512-HRDSYvT3n7kMvJH7Avp7iR0Xsz97bkCFka9aOg04EdyXyiAP8yQzUpLH3712y9R7ffVo1g94t1OYFHBB0yI9vQ==", + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/d3/-/d3-5.7.0.tgz", + "integrity": "sha512-8KEIfx+dFm8PlbJN9PI0suazrZ41QcaAufsKE9PRcqYPWLngHIyWJZX96n6IQKePGgeSu0l7rtlueSSNq8Zc3g==", "requires": { "d3-array": "1", "d3-axis": "1", @@ -345,19 +720,19 @@ } }, "d3-array": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-1.2.1.tgz", - "integrity": "sha512-CyINJQ0SOUHojDdFDH4JEM0552vCR1utGyLHegJHyYH0JyCpSeTPxi4OBqHMA2jJZq4NH782LtaJWBImqI/HBw==" + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-1.2.4.tgz", + "integrity": "sha512-KHW6M86R+FUPYGb3R5XiYjXPq7VzwxZ22buHhAEVG5ztoEcZZMLov530mmccaqA1GghZArjQV46fuc8kUqhhHw==" }, "d3-axis": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/d3-axis/-/d3-axis-1.0.8.tgz", - "integrity": "sha1-MacFoLU15ldZ3hQXOjGTMTfxjvo=" + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/d3-axis/-/d3-axis-1.0.12.tgz", + "integrity": "sha512-ejINPfPSNdGFKEOAtnBtdkpr24c4d4jsei6Lg98mxf424ivoDP2956/5HDpIAtmHo85lqT4pruy+zEgvRUBqaQ==" }, "d3-brush": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/d3-brush/-/d3-brush-1.0.4.tgz", - "integrity": "sha1-AMLyOAGfJPbAoZSibUGhUw/+e8Q=", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/d3-brush/-/d3-brush-1.0.6.tgz", + "integrity": "sha512-lGSiF5SoSqO5/mYGD5FAeGKKS62JdA1EV7HPrU2b5rTX4qEJJtpjaGLJngjnkewQy7UnGstnFd3168wpf5z76w==", "requires": { "d3-dispatch": "1", "d3-drag": "1", @@ -367,50 +742,50 @@ } }, "d3-chord": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/d3-chord/-/d3-chord-1.0.4.tgz", - "integrity": "sha1-fexPC6iG9xP+ERxF92NBT290yiw=", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/d3-chord/-/d3-chord-1.0.6.tgz", + "integrity": "sha512-JXA2Dro1Fxw9rJe33Uv+Ckr5IrAa74TlfDEhE/jfLOaXegMQFQTAgAw9WnZL8+HxVBRXaRGCkrNU7pJeylRIuA==", "requires": { "d3-array": "1", "d3-path": "1" } }, "d3-collection": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/d3-collection/-/d3-collection-1.0.4.tgz", - "integrity": "sha1-NC39EoN8kJdPM/HMCnha6lcNzcI=" + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/d3-collection/-/d3-collection-1.0.7.tgz", + "integrity": "sha512-ii0/r5f4sjKNTfh84Di+DpztYwqKhEyUlKoPrzUFfeSkWxjW49xU2QzO9qrPrNkpdI0XJkfzvmTu8V2Zylln6A==" }, "d3-color": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-1.2.0.tgz", - "integrity": "sha512-dmL9Zr/v39aSSMnLOTd58in2RbregCg4UtGyUArvEKTTN6S3HKEy+ziBWVYo9PTzRyVW+pUBHUtRKz0HYX+SQg==" + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-1.2.3.tgz", + "integrity": "sha512-x37qq3ChOTLd26hnps36lexMRhNXEtVxZ4B25rL0DVdDsGQIJGB18S7y9XDwlDD6MD/ZBzITCf4JjGMM10TZkw==" }, "d3-contour": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/d3-contour/-/d3-contour-1.3.0.tgz", - "integrity": "sha512-6zccxidQRtcydx0lWqHawdW1UcBzKZTxv0cW90Dlx98pY/L7GjQJmftH1tWopYFDaLCoXU0ECg9x/z2EuFT8tg==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/d3-contour/-/d3-contour-1.3.2.tgz", + "integrity": "sha512-hoPp4K/rJCu0ladiH6zmJUEz6+u3lgR+GSm/QdM2BBvDraU39Vr7YdDCicJcxP1z8i9B/2dJLgDC1NcvlF8WCg==", "requires": { "d3-array": "^1.1.1" } }, "d3-dispatch": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-1.0.3.tgz", - "integrity": "sha1-RuFJHqqbWMNY/OW+TovtYm54cfg=" + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-1.0.5.tgz", + "integrity": "sha512-vwKx+lAqB1UuCeklr6Jh1bvC4SZgbSqbkGBLClItFBIYH4vqDJCA7qfoy14lXmJdnBOdxndAMxjCbImJYW7e6g==" }, "d3-drag": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-1.2.1.tgz", - "integrity": "sha512-Cg8/K2rTtzxzrb0fmnYOUeZHvwa4PHzwXOLZZPwtEs2SKLLKLXeYwZKBB+DlOxUvFmarOnmt//cU4+3US2lyyQ==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-1.2.3.tgz", + "integrity": "sha512-8S3HWCAg+ilzjJsNtWW1Mutl74Nmzhb9yU6igspilaJzeZVFktmY6oO9xOh5TDk+BM2KrNFjttZNoJJmDnkjkg==", "requires": { "d3-dispatch": "1", "d3-selection": "1" } }, "d3-dsv": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/d3-dsv/-/d3-dsv-1.0.8.tgz", - "integrity": "sha512-IVCJpQ+YGe3qu6odkPQI0KPqfxkhbP/oM1XhhE/DFiYmcXKfCRub4KXyiuehV1d4drjWVXHUWx4gHqhdZb6n/A==", + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/d3-dsv/-/d3-dsv-1.0.10.tgz", + "integrity": "sha512-vqklfpxmtO2ZER3fq/B33R/BIz3A1PV0FaZRuFM8w6jLo7sUX1BZDh73fPlr0s327rzq4H6EN1q9U+eCBCSN8g==", "requires": { "commander": "2", "iconv-lite": "0.4", @@ -418,22 +793,22 @@ } }, "d3-ease": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-1.0.3.tgz", - "integrity": "sha1-aL+8NJM4o4DETYrMT7wzBKotjA4=" + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-1.0.5.tgz", + "integrity": "sha512-Ct1O//ly5y5lFM9YTdu+ygq7LleSgSE4oj7vUt9tPLHUi8VCV7QoizGpdWRWAwCO9LdYzIrQDg97+hGVdsSGPQ==" }, "d3-fetch": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/d3-fetch/-/d3-fetch-1.1.0.tgz", - "integrity": "sha512-j+V4vtT6dceQbcKYLtpTueB8Zvc+wb9I93WaFtEQIYNADXl0c1ZJMN3qQo0CssiTsAqK8pePwc7f4qiW+b0WOg==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/d3-fetch/-/d3-fetch-1.1.2.tgz", + "integrity": "sha512-S2loaQCV/ZeyTyIF2oP8D1K9Z4QizUzW7cWeAOAS4U88qOt3Ucf6GsmgthuYSdyB2HyEm4CeGvkQxWsmInsIVA==", "requires": { "d3-dsv": "1" } }, "d3-force": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/d3-force/-/d3-force-1.1.0.tgz", - "integrity": "sha512-2HVQz3/VCQs0QeRNZTYb7GxoUCeb6bOzMp/cGcLa87awY9ZsPvXOGeZm0iaGBjXic6I1ysKwMn+g+5jSAdzwcg==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/d3-force/-/d3-force-1.1.2.tgz", + "integrity": "sha512-p1vcHAUF1qH7yR+e8ip7Bs61AHjLeKkIn8Z2gzwU2lwEf2wkSpWdjXG0axudTHsVFnYGlMkFaEsVy2l8tAg1Gw==", "requires": { "d3-collection": "1", "d3-dispatch": "1", @@ -442,55 +817,55 @@ } }, "d3-format": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-1.3.0.tgz", - "integrity": "sha512-ycfLEIzHVZC3rOvuBOKVyQXSiUyCDjeAPIj9n/wugrr+s5AcTQC2Bz6aKkubG7rQaQF0SGW/OV4UEJB9nfioFg==" + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-1.3.2.tgz", + "integrity": "sha512-Z18Dprj96ExragQ0DeGi+SYPQ7pPfRMtUXtsg/ChVIKNBCzjO8XYJvRTC1usblx52lqge56V5ect+frYTQc8WQ==" }, "d3-geo": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-1.10.0.tgz", - "integrity": "sha512-VK/buVGgexthTTqGRNXQ/LSo3EbOFu4p2Pjud5drSIaEnOaF2moc8A3P7WEljEO1JEBEwbpAJjFWMuJiUtoBcw==", + "version": "1.11.3", + "resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-1.11.3.tgz", + "integrity": "sha512-n30yN9qSKREvV2fxcrhmHUdXP9TNH7ZZj3C/qnaoU0cVf/Ea85+yT7HY7i8ySPwkwjCNYtmKqQFTvLFngfkItQ==", "requires": { "d3-array": "1" } }, "d3-hierarchy": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-1.1.6.tgz", - "integrity": "sha512-nn4bhBnwWnMSoZgkBXD7vRyZ0xVUsNMQRKytWYHhP1I4qHw+qzApCTgSQTZqMdf4XXZbTMqA59hFusga+THA/g==" + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-1.1.8.tgz", + "integrity": "sha512-L+GHMSZNwTpiq4rt9GEsNcpLa4M96lXMR8M/nMG9p5hBE0jy6C+3hWtyZMenPQdwla249iJy7Nx0uKt3n+u9+w==" }, "d3-interpolate": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-1.2.0.tgz", - "integrity": "sha512-zLvTk8CREPFfc/2XglPQriAsXkzoRDAyBzndtKJWrZmHw7kmOWHNS11e40kPTd/oGk8P5mFJW5uBbcFQ+ybxyA==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-1.3.2.tgz", + "integrity": "sha512-NlNKGopqaz9qM1PXh9gBF1KSCVh+jSFErrSlD/4hybwoNX/gt1d8CDbDW+3i+5UOHhjC6s6nMvRxcuoMVNgL2w==", "requires": { "d3-color": "1" } }, "d3-path": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-1.0.5.tgz", - "integrity": "sha1-JB6xhJvZ6egCHA0KeZ+KDo5EF2Q=" + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-1.0.7.tgz", + "integrity": "sha512-q0cW1RpvA5c5ma2rch62mX8AYaiLX0+bdaSM2wxSU9tXjU4DNvkx9qiUvjkuWCj3p22UO/hlPivujqMiR9PDzA==" }, "d3-polygon": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/d3-polygon/-/d3-polygon-1.0.3.tgz", - "integrity": "sha1-FoiOkCZGCTPysXllKtN4Ik04LGI=" + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/d3-polygon/-/d3-polygon-1.0.5.tgz", + "integrity": "sha512-RHhh1ZUJZfhgoqzWWuRhzQJvO7LavchhitSTHGu9oj6uuLFzYZVeBzaWTQ2qSO6bz2w55RMoOCf0MsLCDB6e0w==" }, "d3-quadtree": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-1.0.3.tgz", - "integrity": "sha1-rHmH4+I/6AWpkPKOG1DTj8uCJDg=" + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-1.0.5.tgz", + "integrity": "sha512-U2tjwDFbZ75JRAg8A+cqMvqPg1G3BE7UTJn3h8DHjY/pnsAfWdbJKgyfcy7zKjqGtLAmI0q8aDSeG1TVIKRaHQ==" }, "d3-random": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/d3-random/-/d3-random-1.1.0.tgz", - "integrity": "sha1-ZkLlBsb6OmSFldKyRpeIqNElKdM=" + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/d3-random/-/d3-random-1.1.2.tgz", + "integrity": "sha512-6AK5BNpIFqP+cx/sreKzNjWbwZQCSUatxq+pPRmFIQaWuoD+NrbVWw7YWpHiXpCQ/NanKdtGDuB+VQcZDaEmYQ==" }, "d3-scale": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-2.1.0.tgz", - "integrity": "sha512-Bb2N3ZgzPdKVEoWGkt8lPV6R7YdpSBWI70Xf26NQHOVjs77a6gLUmBOOPt9d9nB8JiQhwXY1RHCa+eSyWCJZIQ==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-2.1.2.tgz", + "integrity": "sha512-bESpd64ylaKzCDzvULcmHKZTlzA/6DGSVwx7QSDj/EnX9cpSevsdiwdHFYI9ouo9tNBbV3v5xztHS2uFeOzh8Q==", "requires": { "d3-array": "^1.2.0", "d3-collection": "1", @@ -501,49 +876,49 @@ } }, "d3-scale-chromatic": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-1.3.0.tgz", - "integrity": "sha512-YwMbiaW2bStWvQFByK8hA6hk7ToWflspIo2TRukCqERd8isiafEMBXmwfh8c7/0Z94mVvIzIveRLVC6RAjhgeA==", + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-1.3.3.tgz", + "integrity": "sha512-BWTipif1CimXcYfT02LKjAyItX5gKiwxuPRgr4xM58JwlLocWbjPLI7aMEjkcoOQXMkYsmNsvv3d2yl/OKuHHw==", "requires": { "d3-color": "1", "d3-interpolate": "1" } }, "d3-selection": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-1.3.0.tgz", - "integrity": "sha512-qgpUOg9tl5CirdqESUAu0t9MU/t3O9klYfGfyKsXEmhyxyzLpzpeh08gaxBUTQw1uXIOkr/30Ut2YRjSSxlmHA==" + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-1.3.2.tgz", + "integrity": "sha512-OoXdv1nZ7h2aKMVg3kaUFbLLK5jXUFAMLD/Tu5JA96mjf8f2a9ZUESGY+C36t8R1WFeWk/e55hy54Ml2I62CRQ==" }, "d3-shape": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-1.2.0.tgz", - "integrity": "sha1-RdAVOPBkuv0F6j1tLLdI/YxB93c=", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-1.2.2.tgz", + "integrity": "sha512-hUGEozlKecFZ2bOSNt7ENex+4Tk9uc/m0TtTEHBvitCBxUNjhzm5hS2GrrVRD/ae4IylSmxGeqX5tWC2rASMlQ==", "requires": { "d3-path": "1" } }, "d3-time": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-1.0.8.tgz", - "integrity": "sha512-YRZkNhphZh3KcnBfitvF3c6E0JOFGikHZ4YqD+Lzv83ZHn1/u6yGenRU1m+KAk9J1GnZMnKcrtfvSktlA1DXNQ==" + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-1.0.10.tgz", + "integrity": "sha512-hF+NTLCaJHF/JqHN5hE8HVGAXPStEq6/omumPE/SxyHVrR7/qQxusFDo0t0c/44+sCGHthC7yNGFZIEgju0P8g==" }, "d3-time-format": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-2.1.1.tgz", - "integrity": "sha512-8kAkymq2WMfzW7e+s/IUNAtN/y3gZXGRrdGfo6R8NKPAA85UBTxZg5E61bR6nLwjPjj4d3zywSQe1CkYLPFyrw==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-2.1.3.tgz", + "integrity": "sha512-6k0a2rZryzGm5Ihx+aFMuO1GgelgIz+7HhB4PH4OEndD5q2zGn1mDfRdNrulspOfR6JXkb2sThhDK41CSK85QA==", "requires": { "d3-time": "1" } }, "d3-timer": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-1.0.7.tgz", - "integrity": "sha512-vMZXR88XujmG/L5oB96NNKH5lCWwiLM/S2HyyAQLcjWJCloK5shxta4CwOFYLZoY3AWX73v8Lgv4cCAdWtRmOA==" + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-1.0.9.tgz", + "integrity": "sha512-rT34J5HnQUHhcLvhSB9GjCkN0Ddd5Y8nCwDBG2u6wQEeYxT/Lf51fTFFkldeib/sE/J0clIe0pnCfs6g/lRbyg==" }, "d3-transition": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-1.1.1.tgz", - "integrity": "sha512-xeg8oggyQ+y5eb4J13iDgKIjUcEfIOZs2BqV/eEmXm2twx80wTzJ4tB4vaZ5BKfz7XsI/DFmQL5me6O27/5ykQ==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-1.1.3.tgz", + "integrity": "sha512-tEvo3qOXL6pZ1EzcXxFcPNxC/Ygivu5NoBY6mbzidATAeML86da+JfVIUzon3dNM6UX6zjDx+xbYDmMVtTSjuA==", "requires": { "d3-color": "1", "d3-dispatch": "1", @@ -554,14 +929,14 @@ } }, "d3-voronoi": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/d3-voronoi/-/d3-voronoi-1.1.2.tgz", - "integrity": "sha1-Fodmfo8TotFYyAwUgMWinLDYlzw=" + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/d3-voronoi/-/d3-voronoi-1.1.4.tgz", + "integrity": "sha512-dArJ32hchFsrQ8uMiTBLq256MpnZjeuBtdHpaDlYuQyjU0CVzCJl/BVW+SkszaAeH95D/8gxqAhgx0ouAWAfRg==" }, "d3-zoom": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-1.7.1.tgz", - "integrity": "sha512-sZHQ55DGq5BZBFGnRshUT8tm2sfhPHFnOlmPbbwTkAoPeVdRTkB4Xsf9GCY0TSHrTD8PeJPZGmP/TpGicwJDJQ==", + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-1.7.3.tgz", + "integrity": "sha512-xEBSwFx5Z9T3/VrwDkMt+mr0HCzv7XjpGURJ8lWmIC8wxe32L39eWHIasEe/e7Ox8MPU4p1hvH8PKN2olLzIBg==", "requires": { "d3-dispatch": "1", "d3-drag": "1", @@ -570,25 +945,120 @@ "d3-transition": "1" } }, - "editorconfig": { - "version": "0.15.0", - "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-0.15.0.tgz", - "integrity": "sha512-j7JBoj/bpNzvoTQylfRZSc85MlLNKWQiq5y6gwKhmqD2h1eZ+tH4AXbkhEJD468gjDna/XMx2YtSkCxBRX9OGg==", + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", "dev": true, "requires": { - "@types/commander": "^2.11.0", - "@types/semver": "^5.4.0", - "commander": "^2.11.0", - "lru-cache": "^4.1.1", - "semver": "^5.4.1", - "sigmund": "^1.0.1" + "ms": "2.0.0" } }, + "deep-eql": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", + "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", + "dev": true, + "requires": { + "type-detect": "^4.0.0" + } + }, + "deep-equal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz", + "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=", + "dev": true + }, + "deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "dev": true + }, + "deepmerge": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-2.2.1.tgz", + "integrity": "sha512-R9hc1Xa/NOBi9WRVUWg19rl1UB7Tt4kuPd+thNJgFZoxXsTz7ncaPaeIm+40oSGuP33DfMb4sZt1QIGiJzC4EA==", + "dev": true, + "optional": true + }, + "defer-promise": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/defer-promise/-/defer-promise-1.0.1.tgz", + "integrity": "sha1-HKb/7dvO8XFd16riXHYW+a4iky8=", + "dev": true + }, + "delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", + "dev": true + }, + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", + "dev": true + }, + "destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=", + "dev": true + }, + "diff": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", + "dev": true + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", + "dev": true + }, + "error-inject": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/error-inject/-/error-inject-1.0.0.tgz", + "integrity": "sha1-4rPZG1Su1nLzCdlQ0VSFD6EdTzc=", + "dev": true + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, "estree-walker": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.5.2.tgz", "integrity": "sha512-XpCnW/AE10ws/kDAs37cngSkvgIR8aN3G0MS85m7dUpuK2EREo9VJ00uvw6Dg/hXEpfsE1I1TvJOJr+Z+TL+ig==" }, + "esutils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", + "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", + "dev": true + }, + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", + "dev": true + }, "expand-brackets": { "version": "0.1.5", "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", @@ -630,6 +1100,16 @@ "repeat-string": "^1.5.2" } }, + "find-replace": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-2.0.1.tgz", + "integrity": "sha512-LzDo3Fpa30FLIBsh6DCDnMN1KW2g4QKkqKmejlImgWY67dDFPX/x9Kh/op/GK522DchQXEvDi/wD48HKW49XOQ==", + "dev": true, + "requires": { + "array-back": "^2.0.0", + "test-value": "^3.0.0" + } + }, "for-in": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", @@ -643,16 +1123,48 @@ "for-in": "^1.0.1" } }, + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", + "dev": true + }, "fs-extra": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-5.0.0.tgz", - "integrity": "sha512-66Pm4RYbjzdyeuqudYqhFiNBbCIuI9kgRqLPSHIlXHidW8NIQtVdkM1yeZ4lXwuhbTETv3EUGMNHAAw6hiundQ==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.0.tgz", + "integrity": "sha512-EglNDLRpmaTWiD/qraZn6HREAEAHJcJOmxNEYwq6xeMKnVMAy3GUcFB+wXt2C6k4CNvB/mP1y/U3dzvKKj5OtQ==", "requires": { "graceful-fs": "^4.1.2", "jsonfile": "^4.0.0", "universalify": "^0.1.0" } }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "get-func-name": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", + "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", + "dev": true + }, + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, "glob-base": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", @@ -671,9 +1183,59 @@ } }, "graceful-fs": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", - "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=" + "version": "4.1.15", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", + "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==" + }, + "growl": { + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", + "dev": true + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "he": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", + "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", + "dev": true + }, + "http-assert": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/http-assert/-/http-assert-1.4.0.tgz", + "integrity": "sha512-tPVv62a6l3BbQoM/N5qo969l0OFxqpnQzNUPeYfTP6Spo4zkgWeDBD1D5thI7sDLg7jCCihXTLB0X8UtdyAy8A==", + "dev": true, + "requires": { + "deep-equal": "~1.0.1", + "http-errors": "~1.7.1" + } + }, + "http-errors": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.1.tgz", + "integrity": "sha512-jWEUgtZWGSMba9I1N3gc1HmvpBUaNC9vDdA46yScAdp+C5rdEuKWUBLWTQpW9FwSWSbYYs++b6SDCxf9UEJzfw==", + "dev": true, + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + } }, "iconv-lite": { "version": "0.4.23", @@ -683,6 +1245,28 @@ "safer-buffer": ">= 2.1.2 < 3" } }, + "inflation": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/inflation/-/inflation-2.0.0.tgz", + "integrity": "sha1-i0F+R8KPklpFEz2RTKH9OJEH8w8=", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, "is-buffer": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", @@ -711,6 +1295,12 @@ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=" }, + "is-generator-function": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.7.tgz", + "integrity": "sha512-YZc5EwyO4f2kWCax7oegfuSr9mFz1ZvieNYBEjmukLxgXfBUbxAWGVF7GZf0zidYtoBl3WvC07YK0wT76a+Rtw==", + "dev": true + }, "is-glob": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", @@ -742,6 +1332,12 @@ "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=" }, + "is-wsl": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", + "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=", + "dev": true + }, "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", @@ -755,6 +1351,38 @@ "isarray": "1.0.0" } }, + "js-tokens": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", + "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", + "dev": true + }, + "js-yaml": { + "version": "3.12.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.1.tgz", + "integrity": "sha512-um46hB9wNOKlwkHgiuyEVAybXBjwFUV0Z/RaHJblRd9DXltue9FTYvzCr9ErQrK9Adz5MU4gHWVaNUfdmrC8qA==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "dev": true + }, + "json5": { + "version": "1.0.1", + "resolved": "http://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "optional": true, + "requires": { + "minimist": "^1.2.0" + } + }, "jsonfile": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", @@ -763,6 +1391,18 @@ "graceful-fs": "^4.1.6" } }, + "jsonparse": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=", + "dev": true + }, + "keygrip": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/keygrip/-/keygrip-1.0.3.tgz", + "integrity": "sha512-/PpesirAIfaklxUzp4Yb7xBper9MwP6hNRA6BGGUFCgbJ+BM5CKBtsoxinNXkLHAr+GXS1/lSlF2rP7cv5Fl+g==", + "dev": true + }, "kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", @@ -771,21 +1411,554 @@ "is-buffer": "^1.1.5" } }, - "lru-cache": { + "koa": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/koa/-/koa-2.6.1.tgz", + "integrity": "sha512-n9R5Eex4y0drUeqFTeCIeXyz8wjr2AxBo2Cq8LvmiXbJl4yDA5KIrecMPkhnmgACZnPXMRyCLbJoyLmpM9aFAw==", + "dev": true, + "requires": { + "accepts": "^1.3.5", + "cache-content-type": "^1.0.0", + "content-disposition": "~0.5.2", + "content-type": "^1.0.4", + "cookies": "~0.7.1", + "debug": "~3.1.0", + "delegates": "^1.0.0", + "depd": "^1.1.2", + "destroy": "^1.0.4", + "error-inject": "^1.0.0", + "escape-html": "^1.0.3", + "fresh": "~0.5.2", + "http-assert": "^1.3.0", + "http-errors": "^1.6.3", + "is-generator-function": "^1.0.7", + "koa-compose": "^4.1.0", + "koa-convert": "^1.2.0", + "koa-is-json": "^1.0.0", + "on-finished": "^2.3.0", + "only": "~0.0.2", + "parseurl": "^1.3.2", + "statuses": "^1.5.0", + "type-is": "^1.6.16", + "vary": "^1.1.2" + } + }, + "koa-bodyparser": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/koa-bodyparser/-/koa-bodyparser-4.2.1.tgz", + "integrity": "sha512-UIjPAlMZfNYDDe+4zBaOAUKYqkwAGcIU6r2ARf1UOXPAlfennQys5IiShaVeNf7KkVBlf88f2LeLvBFvKylttw==", + "dev": true, + "requires": { + "co-body": "^6.0.0", + "copy-to": "^2.0.1" + } + }, + "koa-compose": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/koa-compose/-/koa-compose-4.1.0.tgz", + "integrity": "sha512-8ODW8TrDuMYvXRwra/Kh7/rJo9BtOfPc6qO8eAfC80CnCvSjSl0bkRM24X6/XBBEyj0v1nRUQ1LyOy3dbqOWXw==", + "dev": true + }, + "koa-compress": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/koa-compress/-/koa-compress-2.0.0.tgz", + "integrity": "sha1-e36ykhuEd0a14SK6n1zYpnHo6jo=", + "dev": true, + "requires": { + "bytes": "^2.3.0", + "compressible": "^2.0.0", + "koa-is-json": "^1.0.0", + "statuses": "^1.0.0" + }, + "dependencies": { + "bytes": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-2.5.0.tgz", + "integrity": "sha1-TJQj6i0lLCcMQbK97+/5u2tiwGo=", + "dev": true + } + } + }, + "koa-conditional-get": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/koa-conditional-get/-/koa-conditional-get-2.0.0.tgz", + "integrity": "sha1-pD83I8HQFLcwo07Oit8wuTyCM/I=", + "dev": true + }, + "koa-convert": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/koa-convert/-/koa-convert-1.2.0.tgz", + "integrity": "sha1-2kCHXfSd4FOQmNFwC1CCDOvNIdA=", + "dev": true, + "requires": { + "co": "^4.6.0", + "koa-compose": "^3.0.0" + }, + "dependencies": { + "koa-compose": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/koa-compose/-/koa-compose-3.2.1.tgz", + "integrity": "sha1-qFzLQLfZhtjlo0Wzoazo6rz1Tec=", + "dev": true, + "requires": { + "any-promise": "^1.1.0" + } + } + } + }, + "koa-etag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/koa-etag/-/koa-etag-3.0.0.tgz", + "integrity": "sha1-nvc4Ld1agqsN6xU0FckVg293HT8=", + "dev": true, + "requires": { + "etag": "^1.3.0", + "mz": "^2.1.0" + } + }, + "koa-is-json": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/koa-is-json/-/koa-is-json-1.0.0.tgz", + "integrity": "sha1-JzwH7c3Ljfaiwat9We52SRRR7BQ=", + "dev": true + }, + "koa-json": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/koa-json/-/koa-json-2.0.2.tgz", + "integrity": "sha1-Nq8U5uofXWRtfESihXAcb4Wk/eQ=", + "dev": true, + "requires": { + "koa-is-json": "1", + "streaming-json-stringify": "3" + } + }, + "koa-mock-response": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/koa-mock-response/-/koa-mock-response-0.2.0.tgz", + "integrity": "sha512-HmybRN1a3WqcSFvf7tycu2YhBIEHeqzm8bwcsShNWGsTgP86coZOpdI8aqYm/1DFsAQMctnpdWrva4rDr1Pibg==", + "dev": true, + "requires": { + "array-back": "^2.0.0", + "path-to-regexp": "^1.7.0", + "typical": "^2.6.1" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "path-to-regexp": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz", + "integrity": "sha1-Wf3g9DW62suhA6hOnTvGTpa5k30=", + "dev": true, + "requires": { + "isarray": "0.0.1" + } + }, + "typical": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/typical/-/typical-2.6.1.tgz", + "integrity": "sha1-XAgOXWYcu+OCWdLnCjxyU+hziB0=", + "dev": true + } + } + }, + "koa-morgan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/koa-morgan/-/koa-morgan-1.0.1.tgz", + "integrity": "sha1-CAUuDODYOdPEMXi5CluzQkvvH5k=", + "dev": true, + "requires": { + "morgan": "^1.6.1" + } + }, + "koa-range": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/koa-range/-/koa-range-0.3.0.tgz", + "integrity": "sha1-NYjjSWRzqDmhvSZNKkKx2FvX/qw=", + "dev": true, + "requires": { + "stream-slice": "^0.1.2" + } + }, + "koa-rewrite-75lb": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/koa-rewrite-75lb/-/koa-rewrite-75lb-2.1.1.tgz", + "integrity": "sha512-i9ofDKLs0xNCb2PW7wKGFzBFX6+Ce3aKoZzNKPh0fkejeUOTWkkDqnjXrgqrJEP2ifX6WWsHp6VtGuXzSYLSWQ==", + "dev": true, + "requires": { + "path-to-regexp": "1.7.0" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "path-to-regexp": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz", + "integrity": "sha1-Wf3g9DW62suhA6hOnTvGTpa5k30=", + "dev": true, + "requires": { + "isarray": "0.0.1" + } + } + } + }, + "koa-route": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/koa-route/-/koa-route-3.2.0.tgz", + "integrity": "sha1-dimLmaa8+p44yrb+XHmocz51i84=", + "dev": true, + "requires": { + "debug": "*", + "methods": "~1.1.0", + "path-to-regexp": "^1.2.0" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "path-to-regexp": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz", + "integrity": "sha1-Wf3g9DW62suhA6hOnTvGTpa5k30=", + "dev": true, + "requires": { + "isarray": "0.0.1" + } + } + } + }, + "koa-send": { "version": "4.1.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.3.tgz", - "integrity": "sha512-fFEhvcgzuIoJVUF8fYr5KR0YqxD238zgObTps31YdADwPPAp82a4M8TrckkWyx7ekNlf9aBcVn81cFwwXngrJA==", + "resolved": "http://registry.npmjs.org/koa-send/-/koa-send-4.1.3.tgz", + "integrity": "sha512-3UetMBdaXSiw24qM2Mx5mKmxLKw5ZTPRjACjfhK6Haca55RKm9hr/uHDrkrxhSl5/S1CKI/RivZVIopiatZuTA==", + "dev": true, + "requires": { + "debug": "^2.6.3", + "http-errors": "^1.6.1", + "mz": "^2.6.0", + "resolve-path": "^1.4.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } + } + }, + "koa-static": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/koa-static/-/koa-static-4.0.3.tgz", + "integrity": "sha512-JGmxTuPWy4bH7bt6gD/OMWkhprawvRmzJSr8TWKmTL4N7+IMv3s0SedeQi5S4ilxM9Bo6ptkCyXj/7wf+VS5tg==", + "dev": true, + "requires": { + "debug": "^3.1.0", + "koa-send": "^4.1.3" + } + }, + "load-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/load-module/-/load-module-1.0.0.tgz", + "integrity": "sha512-FmoAJI/RM4vmvIRk65g/SFCnGQC9BbALY3zy38Z0cMllNnra1+iCdxAf051LVymzE60/FweOo9or9XJiGgFshg==", + "dev": true, + "requires": { + "array-back": "^2.0.0" + } + }, + "local-web-server": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/local-web-server/-/local-web-server-2.6.0.tgz", + "integrity": "sha512-m7Z5zlzZFxMyiK1W8xR5TJMh00Fy9z7Po8vilSQCpeU4LG2VMK667xCkASBUepFR9fPj6heUMBHu9P/TrwDqFw==", + "dev": true, + "requires": { + "lws": "^1.3.0", + "lws-basic-auth": "^0.1.1", + "lws-blacklist": "^0.3.0", + "lws-body-parser": "^0.2.4", + "lws-compress": "^0.2.1", + "lws-conditional-get": "^0.3.4", + "lws-cors": "^1.0.0", + "lws-index": "^0.4.0", + "lws-json": "^0.3.2", + "lws-log": "^0.3.2", + "lws-mime": "^0.2.2", + "lws-mock-response": "^0.5.1", + "lws-range": "^1.1.0", + "lws-request-monitor": "^0.1.5", + "lws-rewrite": "^0.4.1", + "lws-spa": "^0.3.0", + "lws-static": "^0.5.0", + "node-version-matches": "^1.0.0" + } + }, + "lodash.assignwith": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.assignwith/-/lodash.assignwith-4.2.0.tgz", + "integrity": "sha1-EnqX8CrcQXUalU0ksN4X4QDgOOs=", + "dev": true + }, + "lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=", + "dev": true + }, + "lodash.padend": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/lodash.padend/-/lodash.padend-4.6.1.tgz", + "integrity": "sha1-U8y6BH0G4VjTEfRdpiX05J5vFm4=", + "dev": true + }, + "lodash.pick": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.pick/-/lodash.pick-4.4.0.tgz", + "integrity": "sha1-UvBWEP/53tQiYRRB7R/BI6AwAbM=", + "dev": true + }, + "lodash.throttle": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz", + "integrity": "sha1-wj6RtxAkKscMN/HhzaknTMOb8vQ=", + "dev": true + }, + "lws": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/lws/-/lws-1.3.0.tgz", + "integrity": "sha512-2gOJzVtgjg4mA1cyWnzkICR/NLuMD24sbRSwQeVZeVkadp0VOKTlpmnjvA1tQpkb1TGrcOS+N+3vKMJST8tt2w==", + "dev": true, + "requires": { + "ansi-escape-sequences": "^4.0.0", + "array-back": "^2.0.0", + "byte-size": "^4.0.3", + "cli-commands": "^0.4.0", + "command-line-args": "^5.0.2", + "command-line-usage": "^5.0.5", + "koa": "^2.5.2", + "load-module": "^1.0.0", + "lodash.assignwith": "^4.2.0", + "node-version-matches": "^1.0.0", + "opn": "^5.3.0", + "reduce-flatten": "^2.0.0", + "typical": "^3.0.0", + "walk-back": "^3.0.0", + "ws": "^5.2.1" + } + }, + "lws-basic-auth": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/lws-basic-auth/-/lws-basic-auth-0.1.1.tgz", + "integrity": "sha512-npPpqkOFzJzB9yJ2pGXmiYOswH+0n86ro75WhromeGuNo0GfE18ZLI/VCOVWmBbeXp2pcnPIMUAdkNSgukpAww==", + "dev": true, + "requires": { + "basic-auth": "^1.1.0" + } + }, + "lws-blacklist": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/lws-blacklist/-/lws-blacklist-0.3.0.tgz", + "integrity": "sha512-ZA8dujYaZwRNMBhgP+oGsZi9tum44Ba6VHsA3JrV1JVrjZ8c65kLaO/41rLBqQDKP3SDPu7dLity4YLwe1FuNQ==", + "dev": true, + "requires": { + "array-back": "^2.0.0", + "path-to-regexp": "^2.2.0" + } + }, + "lws-body-parser": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/lws-body-parser/-/lws-body-parser-0.2.4.tgz", + "integrity": "sha512-XKJzbzK97TUsewIPA5J2RpEk7kRoJcL+/Du6JlwzqIq84tWuXMfiT2a4Ncj12+tRWrdY2avV6d8uLhqlHLz1yg==", + "dev": true, + "requires": { + "koa-bodyparser": "^4.2.0" + } + }, + "lws-compress": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/lws-compress/-/lws-compress-0.2.1.tgz", + "integrity": "sha512-14++1o6U8upi3DLx9J2O2sFELsijEJF9utoFxSH4Stoo9SdU2Cxw6BtqQTrb9SEA6O6IsApzstdMYnq8floLSg==", + "dev": true, + "requires": { + "koa-compress": "^2.0.0" + } + }, + "lws-conditional-get": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/lws-conditional-get/-/lws-conditional-get-0.3.4.tgz", + "integrity": "sha512-6asZSfM747snhdz4xexRllm09pebz8pjYeg2d5khLR53D/OJznZWHsIqW0JGiScJObri2D7+H4z7yRLBjokT7g==", + "dev": true, + "requires": { + "koa-conditional-get": "^2.0.0", + "koa-etag": "^3.0.0" + } + }, + "lws-cors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lws-cors/-/lws-cors-1.0.0.tgz", + "integrity": "sha512-4C0m4lvYdAnpAa03tr9AqziB4d8SRPh4beQBuzPiefv7N9/tpVdrl9kgXrUe1hLHhISnVJ5MoOZuZ6wFeMiU4g==", + "dev": true, + "requires": { + "@koa/cors": "^2.2.1" + } + }, + "lws-index": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/lws-index/-/lws-index-0.4.0.tgz", + "integrity": "sha512-k+mkqgMSzx1ipzVpaxsAJU4Qe7R1kp1B/u+qC+d1Y3l+auBz+bLcIxL4dYKfaxLqiz0IFwg1dZwGzVm/dd7FFw==", + "dev": true, + "requires": { + "serve-index-75lb": "^2.0.0" + } + }, + "lws-json": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/lws-json/-/lws-json-0.3.2.tgz", + "integrity": "sha512-ElmCA8hi3GPMfxbtiI015PDHuJovhhcbXX/qTTTifXhopedAzIBzn/rF5dHZHE4k7HQDYfbiaPgPMbmpv9dMvQ==", + "dev": true, + "requires": { + "koa-json": "^2.0.2" + } + }, + "lws-log": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/lws-log/-/lws-log-0.3.2.tgz", + "integrity": "sha512-DRp4bFl4a7hjwR/RjARjhFLEXs8pIeqKbUvojaAl1hhfRBuW2JsDxRSKC+ViQN06CW4Qypg3ZsztMMR8dRO8dA==", + "dev": true, + "requires": { + "koa-morgan": "^1.0.1", + "stream-log-stats": "^2.0.2" + } + }, + "lws-mime": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/lws-mime/-/lws-mime-0.2.2.tgz", + "integrity": "sha512-cWBj9CuuSvvaqdYMPiXRid0QhzJmr+5gWAA96pEDOiW8tMCMoxl7CIgTpHXZwhJzCqdI84RZDVm+FswByATS5w==", + "dev": true + }, + "lws-mock-response": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/lws-mock-response/-/lws-mock-response-0.5.1.tgz", + "integrity": "sha512-4R5Q1RmRglC0pqEwywrS5g62aKaLQsteMnShGmWU9aQ/737Bq0/3qbQ3mb8VbMk3lLzo3ZaNZ1DUsPgVvZaXNQ==", "dev": true, "requires": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" + "array-back": "^2.0.0", + "koa-mock-response": "0.2.0", + "load-module": "^1.0.0", + "reduce-flatten": "^2.0.0" } }, + "lws-range": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/lws-range/-/lws-range-1.1.0.tgz", + "integrity": "sha512-Mpx6FdO58Z4l6DAXlATsC2zm10QvyGYElQvFd7P1xqUSTPoYG0wAxfjlpqI+Qdb2O7W4Ah21yESVnPEwae3SIw==", + "dev": true, + "requires": { + "koa-range": "^0.3.0" + } + }, + "lws-request-monitor": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/lws-request-monitor/-/lws-request-monitor-0.1.5.tgz", + "integrity": "sha512-u9eczHPowH17ftUjQ8ysutGDADNZdDD6k8wgFMzOB7/rRq1Is12lTYA4u8pfKZ8C2oyoy+HYsDSrOzTwespTlA==", + "dev": true, + "requires": { + "byte-size": "^4.0.2" + } + }, + "lws-rewrite": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/lws-rewrite/-/lws-rewrite-0.4.1.tgz", + "integrity": "sha512-EHUdbqfdwc4Baa7iXOdG2y815WC040Cing1GwhM9VsBL7lHtZ7zl3EHzjWFv3styoO3qNqZ4W0xCey4hoo/aYg==", + "dev": true, + "requires": { + "array-back": "^2.0.0", + "koa-rewrite-75lb": "^2.1.1", + "koa-route": "^3.2.0", + "path-to-regexp": "^1.7.0", + "req-then": "^0.6.4", + "stream-read-all": "^0.1.2", + "typical": "^2.6.1" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "path-to-regexp": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz", + "integrity": "sha1-Wf3g9DW62suhA6hOnTvGTpa5k30=", + "dev": true, + "requires": { + "isarray": "0.0.1" + } + }, + "typical": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/typical/-/typical-2.6.1.tgz", + "integrity": "sha1-XAgOXWYcu+OCWdLnCjxyU+hziB0=", + "dev": true + } + } + }, + "lws-spa": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/lws-spa/-/lws-spa-0.3.0.tgz", + "integrity": "sha512-8wxZl5dOI/CQsJ6oOG8Y7B4khjlQXfB7GlVkjYFPuOYM+JIw/QzMvezKjKweG0qGePmHJVHWa38+CyololV4aw==", + "dev": true, + "requires": { + "koa-route": "^3.2.0", + "koa-send": "^4.1.3" + } + }, + "lws-static": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/lws-static/-/lws-static-0.5.0.tgz", + "integrity": "sha512-r3QIeJfBox/hSJLSL7TPhNSZsTKE0r4mWYHbGZ+DwrBcKbLt1ljsh5NAtmJpsqCcjYpyOuD/DlsZ0yQY9VI8bA==", + "dev": true, + "requires": { + "koa-static": "^4.0.2" + } + }, + "make-error": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.5.tgz", + "integrity": "sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g==", + "dev": true + }, "math-random": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.1.tgz", "integrity": "sha1-izqsWIuKZuSXXjzepn97sylgH6w=" }, + "media-typer": { + "version": "0.3.0", + "resolved": "http://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", + "dev": true + }, + "methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", + "dev": true + }, "micromatch": { "version": "2.3.11", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", @@ -806,6 +1979,137 @@ "regex-cache": "^0.4.2" } }, + "mime-db": { + "version": "1.37.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.37.0.tgz", + "integrity": "sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg==", + "dev": true + }, + "mime-types": { + "version": "2.1.21", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.21.tgz", + "integrity": "sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg==", + "dev": true, + "requires": { + "mime-db": "~1.37.0" + } + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "dev": true, + "requires": { + "minimist": "0.0.8" + }, + "dependencies": { + "minimist": { + "version": "0.0.8", + "resolved": "http://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + } + } + }, + "mocha": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.2.0.tgz", + "integrity": "sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ==", + "dev": true, + "requires": { + "browser-stdout": "1.3.1", + "commander": "2.15.1", + "debug": "3.1.0", + "diff": "3.5.0", + "escape-string-regexp": "1.0.5", + "glob": "7.1.2", + "growl": "1.10.5", + "he": "1.1.1", + "minimatch": "3.0.4", + "mkdirp": "0.5.1", + "supports-color": "5.4.0" + } + }, + "morgan": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.9.1.tgz", + "integrity": "sha512-HQStPIV4y3afTiCYVxirakhlCfGkI161c76kKFca7Fk1JusM//Qeo1ej2XaMniiNeaZklMVrh3vTtIzpzwbpmA==", + "dev": true, + "requires": { + "basic-auth": "~2.0.0", + "debug": "2.6.9", + "depd": "~1.1.2", + "on-finished": "~2.3.0", + "on-headers": "~1.0.1" + }, + "dependencies": { + "basic-auth": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", + "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==", + "dev": true, + "requires": { + "safe-buffer": "5.1.2" + } + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "mz": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "dev": true, + "requires": { + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" + } + }, + "negotiator": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", + "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=", + "dev": true + }, + "node-version-matches": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-version-matches/-/node-version-matches-1.0.0.tgz", + "integrity": "sha512-E1OQnAUB+BvEyNTXTWpUUMAWXYCa7yjiS64djOuTJEkm20yaQfNmWTfx/kvN6nC7fc0GQS182IaefOPxQvpxXg==", + "dev": true, + "requires": { + "semver": "^5.5.0" + } + }, "normalize-path": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", @@ -814,6 +2118,12 @@ "remove-trailing-separator": "^1.0.1" } }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true + }, "object.omit": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", @@ -823,6 +2133,45 @@ "is-extendable": "^0.1.1" } }, + "on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "dev": true, + "requires": { + "ee-first": "1.1.1" + } + }, + "on-headers": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.1.tgz", + "integrity": "sha1-ko9dD0cNSTQmUepnlLCFfBAGk/c=", + "dev": true + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "only": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/only/-/only-0.0.2.tgz", + "integrity": "sha1-Kv3oTQPlC5qO3EROMGEKcCle37Q=", + "dev": true + }, + "opn": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/opn/-/opn-5.4.0.tgz", + "integrity": "sha512-YF9MNdVy/0qvJvDtunAOzFw9iasOQHpVthTCvGzxt61Il64AYSGdK+rYwld7NAfk9qJ7dt+hymBNSc9LNYS+Sw==", + "dev": true, + "requires": { + "is-wsl": "^1.1.0" + } + }, "parse-glob": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", @@ -834,31 +2183,56 @@ "is-glob": "^2.0.0" } }, + "parseurl": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz", + "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, "path-parse": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz", "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=" }, - "pegjs": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/pegjs/-/pegjs-0.10.0.tgz", - "integrity": "sha1-z4uvrm7d/0tafvsYUmnqr0YQ3b0=" + "path-to-regexp": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-2.4.0.tgz", + "integrity": "sha512-G6zHoVqC6GGTQkZwF4lkuEyMbVOjoBKAEybQUypI1WTkqinCOrq2x6U2+phkJ1XsEMTy4LjtwPI7HW+NVrRR2w==", + "dev": true + }, + "pathval": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", + "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", + "dev": true }, "preserve": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=" }, - "pseudomap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", + "process-nextick-args": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", + "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", + "dev": true + }, + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", "dev": true }, "randomatic": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.0.0.tgz", - "integrity": "sha512-VdxFOIEY3mNO5PtSRkkle/hPJDHvQhK21oa73K4yAc9qmp6N429gAyF1gZMOTMeS0/AYzaV/2Trcef+NaIonSA==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.1.1.tgz", + "integrity": "sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw==", "requires": { "is-number": "^4.0.0", "kind-of": "^6.0.0", @@ -877,6 +2251,53 @@ } } }, + "raw-body": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.3.tgz", + "integrity": "sha512-9esiElv1BrZoI3rCDuOuKCBRbuApGGaDPQfjSflGxdy4oyzqghxu6klEkkVIvBje+FF0BX9coEv8KqW6X/7njw==", + "dev": true, + "requires": { + "bytes": "3.0.0", + "http-errors": "1.6.3", + "iconv-lite": "0.4.23", + "unpipe": "1.0.0" + }, + "dependencies": { + "http-errors": { + "version": "1.6.3", + "resolved": "http://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", + "dev": true, + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + } + } + } + }, + "readable-stream": { + "version": "2.3.6", + "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "reduce-flatten": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/reduce-flatten/-/reduce-flatten-2.0.0.tgz", + "integrity": "sha512-EJ4UNY/U1t2P/2k6oqotuX2Cc3T6nxJwsM0N0asT7dhrtH1ltUxDn4NalSYmPE2rCkVpcf/X6R0wDwcFpzhd4w==", + "dev": true + }, "regex-cache": { "version": "0.4.4", "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", @@ -891,15 +2312,36 @@ "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=" }, "repeat-element": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz", - "integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo=" + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", + "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==" }, "repeat-string": { "version": "1.6.1", "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=" }, + "req-then": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/req-then/-/req-then-0.6.4.tgz", + "integrity": "sha512-Uf7xsK1qPqPUetESHemNQ7nGtgOxngSFtlcAOOkx0lDAo+XRZpEA9QDrGBdyOfGq4b+a0z/D5gR2VJ+pp/dzBA==", + "dev": true, + "requires": { + "array-back": "^2.0.0", + "defer-promise": "^1.0.1", + "lodash.pick": "^4.4.0", + "stream-read-all": "^0.1.0", + "typical": "^2.6.1" + }, + "dependencies": { + "typical": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/typical/-/typical-2.6.1.tgz", + "integrity": "sha1-XAgOXWYcu+OCWdLnCjxyU+hziB0=", + "dev": true + } + } + }, "resolve": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.8.1.tgz", @@ -908,40 +2350,64 @@ "path-parse": "^1.0.5" } }, + "resolve-path": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/resolve-path/-/resolve-path-1.4.0.tgz", + "integrity": "sha1-xL2p9e+y/OZSR4c6s2u02DT+Fvc=", + "dev": true, + "requires": { + "http-errors": "~1.6.2", + "path-is-absolute": "1.0.1" + }, + "dependencies": { + "http-errors": { + "version": "1.6.3", + "resolved": "http://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", + "dev": true, + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + } + } + } + }, "rollup": { - "version": "0.62.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-0.62.0.tgz", - "integrity": "sha512-mZS0aIGfYzuJySJD78znu9/hCJsNfBzg4lDuZGMj0hFVcYHt2evNRHv8aqiu9/w6z6Qn8AQoVl4iyEjDmisGeA==", + "version": "0.68.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-0.68.2.tgz", + "integrity": "sha512-WgjNCXYv7ZbtStIap1+tz4pd2zwz0XYN//OILwEY6dINIFLVizK1iWdu+ZtUURL/OKnp8Lv2w8FBds8YihzX7Q==", "requires": { "@types/estree": "0.0.39", "@types/node": "*" } }, "rollup-plugin-node-resolve": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/rollup-plugin-node-resolve/-/rollup-plugin-node-resolve-3.3.0.tgz", - "integrity": "sha512-9zHGr3oUJq6G+X0oRMYlzid9fXicBdiydhwGChdyeNRGPcN/majtegApRKHLR5drboUvEWU+QeUmGTyEZQs3WA==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/rollup-plugin-node-resolve/-/rollup-plugin-node-resolve-4.0.0.tgz", + "integrity": "sha512-7Ni+/M5RPSUBfUaP9alwYQiIKnKeXCOHiqBpKUl9kwp3jX5ZJtgXAait1cne6pGEVUUztPD6skIKH9Kq9sNtfw==", "requires": { - "builtin-modules": "^2.0.0", + "builtin-modules": "^3.0.0", "is-module": "^1.0.0", - "resolve": "^1.1.6" + "resolve": "^1.8.1" } }, "rollup-plugin-typescript2": { - "version": "0.15.1", - "resolved": "https://registry.npmjs.org/rollup-plugin-typescript2/-/rollup-plugin-typescript2-0.15.1.tgz", - "integrity": "sha512-lJ/yfIj1fmp0KyfgPmd2QFeRpLgXlc58fS3Ha9Loc7/p3qByDL7CRndcI9MflE/pUSrfUdDjZMR0mHSKvqrZ+g==", + "version": "0.18.1", + "resolved": "https://registry.npmjs.org/rollup-plugin-typescript2/-/rollup-plugin-typescript2-0.18.1.tgz", + "integrity": "sha512-aR2m5NCCAUV/KpcKgCWX6Giy8rTko9z92b5t0NX9eZyjOftCvcdDFa1C9Ze/9yp590hnRymr5hG0O9SAXi1oUg==", "requires": { - "fs-extra": "^5.0.0", - "resolve": "^1.7.1", - "rollup-pluginutils": "^2.0.1", - "tslib": "1.9.2" + "fs-extra": "7.0.0", + "resolve": "1.8.1", + "rollup-pluginutils": "2.3.3", + "tslib": "1.9.3" } }, "rollup-pluginutils": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-2.3.0.tgz", - "integrity": "sha512-xB6hsRsjdJdIYWEyYUJy/3ki5g69wrf0luHPGNK3ZSocV6HLNfio59l3dZ3TL4xUwEKgROhFi9jOCt6c5gfUWw==", + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-2.3.3.tgz", + "integrity": "sha512-2XZwja7b6P5q4RZ5FhyX1+f46xi1Z3qBKigLRZ6VTZjwbN0K1IFGMlwm06Uu0Emcre2Z63l77nq/pzn+KxIEoA==", "requires": { "estree-walker": "^0.5.2", "micromatch": "^2.3.11" @@ -952,6 +2418,12 @@ "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz", "integrity": "sha1-P4Yt+pGrdmsUiF700BEkv9oHT7Q=" }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, "safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", @@ -963,42 +2435,444 @@ "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==", "dev": true }, - "sigmund": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", - "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=", + "serve-index-75lb": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/serve-index-75lb/-/serve-index-75lb-2.0.1.tgz", + "integrity": "sha512-/d9r8bqJlFQcwy0a0nb1KnWAA+Mno+V+VaoKocdkbW5aXKRQd/+4bfnRhQRQr6uEoYwTRJ4xgztOyCJvWcpBpQ==", + "dev": true, + "requires": { + "accepts": "~1.3.4", + "batch": "0.6.1", + "debug": "2.6.9", + "escape-html": "~1.0.3", + "http-errors": "~1.6.2", + "mime-types": "~2.1.18", + "parseurl": "~1.3.2" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "http-errors": { + "version": "1.6.3", + "resolved": "http://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", + "dev": true, + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + } + } + } + }, + "setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "source-map-support": { + "version": "0.5.9", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.9.tgz", + "integrity": "sha512-gR6Rw4MvUlYy83vP0vxoVNzM6t8MUXqNuRsuBmBHQDu1Fh6X015FrLdgoDKcNdkwGubozq0P4N0Q37UyFVr1EA==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", + "dev": true + }, + "stream-log-stats": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stream-log-stats/-/stream-log-stats-2.0.2.tgz", + "integrity": "sha512-b1LccxXhMlOQQrzSqapQHyZ3UI00QTAv+8VecFgsJz//sGB5LFl/+mkFeWBVVI2/E4DlCT4sGgvLExB/VTVFfA==", + "dev": true, + "requires": { + "JSONStream": "^1.3.1", + "ansi-escape-sequences": "^3.0.0", + "byte-size": "^3.0.0", + "common-log-format": "~0.1.3", + "lodash.throttle": "^4.1.1", + "stream-via": "^1.0.3", + "table-layout": "~0.4.0" + }, + "dependencies": { + "ansi-escape-sequences": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-escape-sequences/-/ansi-escape-sequences-3.0.0.tgz", + "integrity": "sha1-HBg5S2r5t2/5pjUJ+kl2af0s5T4=", + "dev": true, + "requires": { + "array-back": "^1.0.3" + } + }, + "array-back": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-1.0.4.tgz", + "integrity": "sha1-ZEun8JX3/898Q7Xw3DnTwfA8Bjs=", + "dev": true, + "requires": { + "typical": "^2.6.0" + } + }, + "byte-size": { + "version": "3.0.0", + "resolved": "http://registry.npmjs.org/byte-size/-/byte-size-3.0.0.tgz", + "integrity": "sha1-QG+eI2aqXav2NnLrKR17sJSV2nU=", + "dev": true + }, + "typical": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/typical/-/typical-2.6.1.tgz", + "integrity": "sha1-XAgOXWYcu+OCWdLnCjxyU+hziB0=", + "dev": true + } + } + }, + "stream-read-all": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/stream-read-all/-/stream-read-all-0.1.2.tgz", + "integrity": "sha512-KX42xBg853m+KnwRtwCKT95ShopAbY/MNKs2dBQ0WkNeuJdqgQYRtGRbTlxdx0L6t979h3z/wMq2eMSAu7Tygw==", + "dev": true + }, + "stream-slice": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/stream-slice/-/stream-slice-0.1.2.tgz", + "integrity": "sha1-LcT04bk2+xPz6zmi3vGTJ5jQeks=", + "dev": true + }, + "stream-via": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/stream-via/-/stream-via-1.0.4.tgz", + "integrity": "sha512-DBp0lSvX5G9KGRDTkR/R+a29H+Wk2xItOF+MpZLLNDWbEV9tGPnqLPxHEYjmiz8xGtJHRIqmI+hCjmNzqoA4nQ==", + "dev": true + }, + "streaming-json-stringify": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/streaming-json-stringify/-/streaming-json-stringify-3.1.0.tgz", + "integrity": "sha1-gCAEN6mTzDnE/gAmO3s7kDrIevU=", + "dev": true, + "requires": { + "json-stringify-safe": "5", + "readable-stream": "2" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true, + "optional": true + }, + "supports-color": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", + "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "table-layout": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/table-layout/-/table-layout-0.4.4.tgz", + "integrity": "sha512-uNaR3SRMJwfdp9OUr36eyEi6LLsbcTqTO/hfTsNviKsNeyMBPICJCC7QXRF3+07bAP6FRwA8rczJPBqXDc0CkQ==", + "dev": true, + "requires": { + "array-back": "^2.0.0", + "deep-extend": "~0.6.0", + "lodash.padend": "^4.6.1", + "typical": "^2.6.1", + "wordwrapjs": "^3.0.0" + }, + "dependencies": { + "typical": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/typical/-/typical-2.6.1.tgz", + "integrity": "sha1-XAgOXWYcu+OCWdLnCjxyU+hziB0=", + "dev": true + } + } + }, + "test-value": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/test-value/-/test-value-3.0.0.tgz", + "integrity": "sha512-sVACdAWcZkSU9x7AOmJo5TqE+GyNJknHaHsMrR6ZnhjVlVN9Yx6FjHrsKZ3BjIpPCT68zYesPWkakrNupwfOTQ==", + "dev": true, + "requires": { + "array-back": "^2.0.0", + "typical": "^2.6.1" + }, + "dependencies": { + "typical": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/typical/-/typical-2.6.1.tgz", + "integrity": "sha1-XAgOXWYcu+OCWdLnCjxyU+hziB0=", + "dev": true + } + } + }, + "thenify": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.0.tgz", + "integrity": "sha1-5p44obq+lpsBCCB5eLn2K4hgSDk=", + "dev": true, + "requires": { + "any-promise": "^1.0.0" + } + }, + "thenify-all": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", + "integrity": "sha1-GhkY1ALY/D+Y+/I02wvMjMEOlyY=", + "dev": true, + "requires": { + "thenify": ">= 3.1.0 < 4" + } + }, + "through": { + "version": "2.3.8", + "resolved": "http://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, + "toidentifier": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", + "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", "dev": true }, + "ts-mocha": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ts-mocha/-/ts-mocha-2.0.0.tgz", + "integrity": "sha512-Rj6+vvwKtOTs5GsNO1jLl4DIXUGnyAg5HFt2Yb4SHIRN45clTJkHWpNdTxCSL0u+1oeavSYJah6d1PZ++Ju5pw==", + "dev": true, + "requires": { + "ts-node": "7.0.0", + "tsconfig-paths": "^3.5.0" + } + }, + "ts-node": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-7.0.0.tgz", + "integrity": "sha512-klJsfswHP0FuOLsvBZ/zzCfUvakOSSxds78mVeK7I+qP76YWtxf16hEZsp3U+b0kIo82R5UatGFeblYMqabb2Q==", + "dev": true, + "requires": { + "arrify": "^1.0.0", + "buffer-from": "^1.1.0", + "diff": "^3.1.0", + "make-error": "^1.1.1", + "minimist": "^1.2.0", + "mkdirp": "^0.5.1", + "source-map-support": "^0.5.6", + "yn": "^2.0.0" + } + }, + "tsconfig-paths": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.6.0.tgz", + "integrity": "sha512-mrqQIP2F4e03aMTCiPdedCIT300//+q0ET53o5WqqtQjmEICxP9yfz/sHTpPqXpssuJEzODsEzJaLRaf5J2X1g==", + "dev": true, + "optional": true, + "requires": { + "@types/json5": "^0.0.29", + "deepmerge": "^2.0.1", + "json5": "^1.0.1", + "minimist": "^1.2.0", + "strip-bom": "^3.0.0" + } + }, "tslib": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.2.tgz", - "integrity": "sha512-AVP5Xol3WivEr7hnssHDsaM+lVrVXWUvd1cfXTRkTj80b//6g2wIFEH6hZG0muGZRnHGrfttpdzRk3YlBkWjKw==" + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz", + "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==" + }, + "tslint": { + "version": "5.12.0", + "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.12.0.tgz", + "integrity": "sha512-CKEcH1MHUBhoV43SA/Jmy1l24HJJgI0eyLbBNSRyFlsQvb9v6Zdq+Nz2vEOH00nC5SUx4SneJ59PZUS/ARcokQ==", + "dev": true, + "requires": { + "babel-code-frame": "^6.22.0", + "builtin-modules": "^1.1.1", + "chalk": "^2.3.0", + "commander": "^2.12.1", + "diff": "^3.2.0", + "glob": "^7.1.1", + "js-yaml": "^3.7.0", + "minimatch": "^3.0.4", + "resolve": "^1.3.2", + "semver": "^5.3.0", + "tslib": "^1.8.0", + "tsutils": "^2.27.2" + }, + "dependencies": { + "builtin-modules": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", + "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", + "dev": true + } + } }, - "typescript": { - "version": "2.9.1", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.9.1.tgz", - "integrity": "sha512-h6pM2f/GDchCFlldnriOhs1QHuwbnmj6/v7499eMHqPeW4V2G0elua2eIc2nu8v2NdHV0Gm+tzX83Hr6nUFjQA==", + "tsutils": { + "version": "2.29.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", + "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", + "dev": true, + "requires": { + "tslib": "^1.8.1" + } + }, + "type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", "dev": true }, - "typescript-formatter": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/typescript-formatter/-/typescript-formatter-7.2.2.tgz", - "integrity": "sha512-V7vfI9XArVhriOTYHPzMU2WUnm5IMdu9X/CPxs8mIMGxmTBFpDABlbkBka64PZJ9/xgQeRpK8KzzAG4MPzxBDQ==", + "type-is": { + "version": "1.6.16", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.16.tgz", + "integrity": "sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q==", "dev": true, "requires": { - "commandpost": "^1.0.0", - "editorconfig": "^0.15.0" + "media-typer": "0.3.0", + "mime-types": "~2.1.18" } }, + "typescript": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.2.2.tgz", + "integrity": "sha512-VCj5UiSyHBjwfYacmDuc/NOk4QQixbE+Wn7MFJuS0nRuPQbof132Pw4u53dm264O8LPc2MVsc7RJNml5szurkg==", + "dev": true + }, + "typical": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/typical/-/typical-3.0.0.tgz", + "integrity": "sha512-2/pGDQD/q1iJWlrj357aEKGIlRvHirm81x04lsg51hreiohy2snAXoFc9dIHFWEx9LsfOVA5K7lUGM9rcUqwlQ==", + "dev": true + }, "universalify": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" }, - "yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", + "dev": true + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", + "dev": true + }, + "walk-back": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/walk-back/-/walk-back-3.0.0.tgz", + "integrity": "sha1-I1h4ejXakQMtrV6S+AsSNw2HlcU=", + "dev": true + }, + "wordwrapjs": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/wordwrapjs/-/wordwrapjs-3.0.0.tgz", + "integrity": "sha512-mO8XtqyPvykVCsrwj5MlOVWvSnCdT+C+QVbm6blradR7JExAhbkZ7hZ9A+9NUtwzSqrlUo9a67ws0EiILrvRpw==", + "dev": true, + "requires": { + "reduce-flatten": "^1.0.1", + "typical": "^2.6.1" + }, + "dependencies": { + "reduce-flatten": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/reduce-flatten/-/reduce-flatten-1.0.1.tgz", + "integrity": "sha1-JYx479FT3fk8tWEjf2EYTzaW4yc=", + "dev": true + }, + "typical": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/typical/-/typical-2.6.1.tgz", + "integrity": "sha1-XAgOXWYcu+OCWdLnCjxyU+hziB0=", + "dev": true + } + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "ws": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-5.2.2.tgz", + "integrity": "sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA==", + "dev": true, + "requires": { + "async-limiter": "~1.0.0" + } + }, + "ylru": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ylru/-/ylru-1.2.1.tgz", + "integrity": "sha512-faQrqNMzcPCHGVC2aaOINk13K+aaBDUPjGWl0teOXywElLjyVAB6Oe2jj62jHYtwsU49jXhScYbvPENK+6zAvQ==", + "dev": true + }, + "yn": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yn/-/yn-2.0.0.tgz", + "integrity": "sha1-5a2ryKz0CPY4X8dklWhMiOavaJo=", "dev": true } } diff --git a/deps/v8/tools/turbolizer/package.json b/deps/v8/tools/turbolizer/package.json index 1d8efc5286..ae354ba393 100644 --- a/deps/v8/tools/turbolizer/package.json +++ b/deps/v8/tools/turbolizer/package.json @@ -4,26 +4,31 @@ "description": "Visualization tool for V8 TurboFan IR graphs", "scripts": { "build": "rollup -c", - "watch": "tsc --watch", + "watch": "rollup -c -w", "deploy": "./deploy.sh", - "format": "tsfmt -r" + "test": "ts-mocha -p tsconfig.test.json test/**/*-test.ts", + "dev-server": "ws", + "presubmit": "tslint --project ./tslint.json --fix" }, "author": "The V8 team", "license": "MIT", "dependencies": { - "@types/d3": "^5.0.0", - "d3": "^5.5.0", - "pegjs": "^0.10.0", - "rollup": "^0.62.0", - "rollup-plugin-node-resolve": "^3.3.0", - "rollup-plugin-typescript2": "^0.15.1" + "@types/d3": "^5.5.0", + "d3": "^5.7.0", + "rollup": "^0.68.2", + "rollup-plugin-node-resolve": "^4.0.0", + "rollup-plugin-typescript2": "^0.18.1" }, "repository": { "type": "git", "url": "https://github.com/v8/v8.git" }, "devDependencies": { - "typescript": "^2.9.1", - "typescript-formatter": "^7.2.2" + "chai": "^4.2.0", + "local-web-server": "^2.6.0", + "mocha": "^5.2.0", + "ts-mocha": "^2.0.0", + "typescript": "^3.2.2", + "tslint": "^5.12.0" } } diff --git a/deps/v8/tools/turbolizer/rollup.config.js b/deps/v8/tools/turbolizer/rollup.config.js index bb34555a7d..05b69b8515 100644 --- a/deps/v8/tools/turbolizer/rollup.config.js +++ b/deps/v8/tools/turbolizer/rollup.config.js @@ -5,8 +5,28 @@ import typescript from 'rollup-plugin-typescript2'; import node from 'rollup-plugin-node-resolve'; +import path from 'path' + +const onwarn = warning => { + // Silence circular dependency warning for moment package + const node_modules = path.normalize('node_modules/'); + if (warning.code === 'CIRCULAR_DEPENDENCY' && + !warning.importer.indexOf(node_modules)) { + return + } + + console.warn(`(!) ${warning.message}`) +} + export default { input: "src/turbo-visualizer.ts", - plugins: [node(), typescript({abortOnError:false})], - output: {file: "build/turbolizer.js", format: "iife", sourcemap: true} + plugins: [node(), typescript({ + abortOnError: false + })], + output: { + file: "build/turbolizer.js", + format: "iife", + sourcemap: true + }, + onwarn: onwarn }; diff --git a/deps/v8/tools/turbolizer/src/code-view.ts b/deps/v8/tools/turbolizer/src/code-view.ts index 5975ff7a60..298f08b01d 100644 --- a/deps/v8/tools/turbolizer/src/code-view.ts +++ b/deps/v8/tools/turbolizer/src/code-view.ts @@ -2,16 +2,17 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import {Source,SourceResolver,sourcePositionToStringKey} from "./source-resolver.js" -import {SelectionBroker} from "./selection-broker.js" -import {View} from "./view.js" -import {MySelection} from "./selection.js" -import {anyToString,ViewElements} from "./util.js" +import { Source, SourceResolver, sourcePositionToStringKey } from "../src/source-resolver"; +import { SelectionBroker } from "../src/selection-broker"; +import { View } from "../src/view"; +import { MySelection } from "../src/selection"; +import { ViewElements } from "../src/util"; +import { SelectionHandler } from "./selection-handler"; export enum CodeMode { MAIN_SOURCE = "main function", INLINED_SOURCE = "inlined function" -}; +} export class CodeView extends View { broker: SelectionBroker; @@ -29,11 +30,10 @@ export class CodeView extends View { return sourceContainer; } - constructor(parentId, broker, sourceResolver, sourceFunction, codeMode: CodeMode) { - super(parentId); - let view = this; + constructor(parent: HTMLElement, broker: SelectionBroker, sourceResolver: SourceResolver, sourceFunction: Source, codeMode: CodeMode) { + super(parent); + const view = this; view.broker = broker; - view.source = null; view.sourceResolver = sourceResolver; view.source = sourceFunction; view.codeMode = codeMode; @@ -44,11 +44,11 @@ export class CodeView extends View { clear: function () { view.selection.clear(); view.updateSelection(); - broker.broadcastClear(this) + broker.broadcastClear(this); }, select: function (sourcePositions, selected) { const locations = []; - for (var sourcePosition of sourcePositions) { + for (const sourcePosition of sourcePositions) { locations.push(sourcePosition); sourceResolver.addInliningPositions(sourcePosition, locations); } @@ -62,7 +62,7 @@ export class CodeView extends View { for (const location of locations) { const translated = sourceResolver.translateToSourceId(view.source.sourceId, location); if (!translated) continue; - view.selection.select(translated, selected); + view.selection.select([translated], selected); } view.updateSelection(firstSelect); }, @@ -100,9 +100,6 @@ export class CodeView extends View { mkVisible.apply(scrollIntoView); } - initializeContent(data, rememberedSelection) { - } - getCodeHtmlElementName() { return `source-pre-${this.source.sourceId}`; } @@ -117,7 +114,6 @@ export class CodeView extends View { } onSelectLine(lineNumber: number, doClear: boolean) { - const key = anyToString(lineNumber); if (doClear) { this.selectionHandler.clear(); } @@ -127,7 +123,7 @@ export class CodeView extends View { } } - onSelectSourcePosition(sourcePosition, doClear) { + onSelectSourcePosition(sourcePosition, doClear: boolean) { if (doClear) { this.selectionHandler.clear(); } @@ -135,7 +131,7 @@ export class CodeView extends View { } initializeCode() { - var view = this; + const view = this; const source = this.source; const sourceText = source.sourceText; if (!sourceText) return; @@ -145,14 +141,14 @@ export class CodeView extends View { } else { sourceContainer.classList.add("inlined-source"); } - var codeHeader = document.createElement("div"); + const codeHeader = document.createElement("div"); codeHeader.setAttribute("id", this.getCodeHeaderHtmlElementName()); codeHeader.classList.add("code-header"); - var codeFileFunction = document.createElement("div"); + const codeFileFunction = document.createElement("div"); codeFileFunction.classList.add("code-file-function"); codeFileFunction.innerHTML = `${source.sourceName}:${source.functionName}`; codeHeader.appendChild(codeFileFunction); - var codeModeDiv = document.createElement("div"); + const codeModeDiv = document.createElement("div"); codeModeDiv.classList.add("code-mode"); codeModeDiv.innerHTML = `${this.codeMode}`; codeHeader.appendChild(codeModeDiv); @@ -160,7 +156,7 @@ export class CodeView extends View { clearDiv.style.clear = "both"; codeHeader.appendChild(clearDiv); sourceContainer.appendChild(codeHeader); - var codePre = document.createElement("pre"); + const codePre = document.createElement("pre"); codePre.setAttribute("id", this.getCodeHtmlElementName()); codePre.classList.add("prettyprint"); sourceContainer.appendChild(codePre); @@ -171,7 +167,7 @@ export class CodeView extends View { } else { codePre.style.display = "none"; } - } + }; if (sourceText != "") { codePre.classList.add("linenums"); codePre.textContent = sourceText; @@ -182,9 +178,17 @@ export class CodeView extends View { console.log(e); } - view.divNode.onclick = function (e) { - view.selectionHandler.clear(); - } + view.divNode.onclick = function (e: MouseEvent) { + if (e.target instanceof Element && e.target.tagName == "DIV") { + const targetDiv = e.target as HTMLDivElement; + if (targetDiv.classList.contains("line-number")) { + e.stopPropagation(); + view.onSelectLine(Number(targetDiv.dataset.lineNumber), !e.shiftKey); + } + } else { + view.selectionHandler.clear(); + } + }; const base: number = source.startPosition; let current = 0; @@ -197,13 +201,14 @@ export class CodeView extends View { currentLineElement.id = "li" + i; currentLineElement.dataset.lineNumber = "" + lineNumber; const spans = currentLineElement.childNodes; - for (let j = 0; j < spans.length; ++j) { - const currentSpan = spans[j]; - const pos = base + current; - const end = pos + currentSpan.textContent.length; - current += currentSpan.textContent.length; - this.insertSourcePositions(currentSpan, lineNumber, pos, end, newlineAdjust); - newlineAdjust = 0; + for (const currentSpan of spans) { + if (currentSpan instanceof HTMLSpanElement) { + const pos = base + current; + const end = pos + currentSpan.textContent.length; + current += currentSpan.textContent.length; + this.insertSourcePositions(currentSpan, lineNumber, pos, end, newlineAdjust); + newlineAdjust = 0; + } } this.insertLineNumber(currentLineElement, lineNumber); @@ -220,44 +225,44 @@ export class CodeView extends View { insertSourcePositions(currentSpan, lineNumber, pos, end, adjust) { const view = this; const sps = this.sourceResolver.sourcePositionsInRange(this.source.sourceId, pos - adjust, end); + let offset = 0; for (const sourcePosition of sps) { this.sourceResolver.addAnyPositionToLine(lineNumber, sourcePosition); - const textnode = currentSpan.tagName == 'SPAN' ? currentSpan.firstChild : currentSpan; - const replacementNode = textnode.splitText(Math.max(0, sourcePosition.scriptOffset - pos)); + const textnode = currentSpan.tagName == 'SPAN' ? currentSpan.lastChild : currentSpan; + if (!(textnode instanceof Text)) continue; + const splitLength = Math.max(0, sourcePosition.scriptOffset - pos - offset); + offset += splitLength; + const replacementNode = textnode.splitText(splitLength); const span = document.createElement('span'); span.setAttribute("scriptOffset", sourcePosition.scriptOffset); - span.classList.add("source-position") + span.classList.add("source-position"); const marker = document.createElement('span'); - marker.classList.add("marker") + marker.classList.add("marker"); span.appendChild(marker); const inlining = this.sourceResolver.getInliningForPosition(sourcePosition); if (inlining != undefined && view.showAdditionalInliningPosition) { const sourceName = this.sourceResolver.getSourceName(inlining.sourceId); const inliningMarker = document.createElement('span'); - inliningMarker.classList.add("inlining-marker") - inliningMarker.setAttribute("data-descr", `${sourceName} was inlined here`) + inliningMarker.classList.add("inlining-marker"); + inliningMarker.setAttribute("data-descr", `${sourceName} was inlined here`); span.appendChild(inliningMarker); } span.onclick = function (e) { e.stopPropagation(); - view.onSelectSourcePosition(sourcePosition, !e.shiftKey) + view.onSelectSourcePosition(sourcePosition, !e.shiftKey); }; view.addHtmlElementToSourcePosition(sourcePosition, span); textnode.parentNode.insertBefore(span, replacementNode); } } - insertLineNumber(lineElement, lineNumber) { + insertLineNumber(lineElement: HTMLElement, lineNumber: number) { const view = this; const lineNumberElement = document.createElement("div"); lineNumberElement.classList.add("line-number"); - lineNumberElement.dataset.lineNumber = lineNumber; - lineNumberElement.innerText = lineNumber; - lineNumberElement.onclick = function (e) { - e.stopPropagation(); - view.onSelectLine(lineNumber, !e.shiftKey); - } - lineElement.insertBefore(lineNumberElement, lineElement.firstChild) + lineNumberElement.dataset.lineNumber = `${lineNumber}`; + lineNumberElement.innerText = `${lineNumber}`; + lineElement.insertBefore(lineNumberElement, lineElement.firstChild); // Don't add lines to source positions of not in backwardsCompatibility mode. if (this.source.backwardsCompatibility === true) { for (const sourcePosition of this.sourceResolver.linetoSourcePositions(lineNumber - 1)) { @@ -266,6 +271,4 @@ export class CodeView extends View { } } - deleteContent() { } - detachSelection() { return null; } } diff --git a/deps/v8/tools/turbolizer/src/disassembly-view.ts b/deps/v8/tools/turbolizer/src/disassembly-view.ts index 8142b2aa0d..4b8fc6ea2d 100644 --- a/deps/v8/tools/turbolizer/src/disassembly-view.ts +++ b/deps/v8/tools/turbolizer/src/disassembly-view.ts @@ -2,16 +2,30 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import {PROF_COLS, UNICODE_BLOCK} from "./constants.js" -import {SelectionBroker} from "./selection-broker.js" -import {TextView} from "./text-view.js" +import { PROF_COLS, UNICODE_BLOCK } from "../src/constants"; +import { SelectionBroker } from "../src/selection-broker"; +import { TextView } from "../src/text-view"; +import { MySelection } from "./selection"; +import { anyToString, interpolate } from "./util"; +import { InstructionSelectionHandler } from "./selection-handler"; + +const toolboxHTML = `<div id="disassembly-toolbox"> +<form> + <label><input id="show-instruction-address" type="checkbox" name="instruction-address">Show addresses</label> + <label><input id="show-instruction-binary" type="checkbox" name="instruction-binary">Show binary literal</label> +</form> +</div>`; export class DisassemblyView extends TextView { SOURCE_POSITION_HEADER_REGEX: any; - addr_event_counts: any; - total_event_counts: any; - max_event_counts: any; - pos_lines: Array<any>; + addrEventCounts: any; + totalEventCounts: any; + maxEventCounts: any; + posLines: Array<any>; + instructionSelectionHandler: InstructionSelectionHandler; + offsetSelection: MySelection; + showInstructionAddressHandler: () => void; + showInstructionBinaryHandler: () => void; createViewElement() { const pane = document.createElement('div'); @@ -21,222 +35,310 @@ export class DisassemblyView extends TextView { <ul id='disassembly-list' class='nolinenums noindent'> </ul> </pre>`; + return pane; } constructor(parentId, broker: SelectionBroker) { - super(parentId, broker, null); - let view = this; - const sourceResolver = broker.sourceResolver; - let ADDRESS_STYLE = { - css: 'tag', - linkHandler: function (text, fragment) { - const matches = text.match(/0x[0-9a-f]{8,16}\s*(?<offset>[0-9a-f]+)/); + super(parentId, broker); + const view = this; + const ADDRESS_STYLE = { + associateData: (text, fragment: HTMLElement) => { + const matches = text.match(/(?<address>0?x?[0-9a-fA-F]{8,16})(?<addressSpace>\s+)(?<offset>[0-9a-f]+)(?<offsetSpace>\s*)/); const offset = Number.parseInt(matches.groups["offset"], 16); + const addressElement = document.createElement("SPAN"); + addressElement.className = "instruction-address"; + addressElement.innerText = matches.groups["address"]; + const offsetElement = document.createElement("SPAN"); + offsetElement.innerText = matches.groups["offset"]; + fragment.appendChild(addressElement); + fragment.appendChild(document.createTextNode(matches.groups["addressSpace"])); + fragment.appendChild(offsetElement); + fragment.appendChild(document.createTextNode(matches.groups["offsetSpace"])); + fragment.classList.add('tag'); + if (!Number.isNaN(offset)) { - const [nodes, blockId] = sourceResolver.nodesForPCOffset(offset) - console.log("nodes for", offset, offset.toString(16), " are ", nodes); - if (nodes.length > 0) { - for (const nodeId of nodes) { - view.addHtmlElementForNodeId(nodeId, fragment); - } - return (e) => { - console.log(offset, nodes); - e.stopPropagation(); - if (!e.shiftKey) { - view.selectionHandler.clear(); - } - view.selectionHandler.select(nodes, true); - }; - } + const pcOffset = view.sourceResolver.getKeyPcOffset(offset); + fragment.dataset.pcOffset = `${pcOffset}`; + addressElement.classList.add('linkable-text'); + offsetElement.classList.add('linkable-text'); } - return undefined; } }; - let ADDRESS_LINK_STYLE = { - css: 'tag' - }; - let UNCLASSIFIED_STYLE = { + const UNCLASSIFIED_STYLE = { css: 'com' }; - let NUMBER_STYLE = { - css: 'lit' + const NUMBER_STYLE = { + css: ['instruction-binary', 'lit'] }; - let COMMENT_STYLE = { + const COMMENT_STYLE = { css: 'com' }; - let POSITION_STYLE = { - css: 'com', + const OPCODE_ARGS = { + associateData: function (text, fragment) { + fragment.innerHTML = text; + const replacer = (match, hexOffset) => { + const offset = Number.parseInt(hexOffset, 16); + const keyOffset = view.sourceResolver.getKeyPcOffset(offset); + return `<span class="tag linkable-text" data-pc-offset="${keyOffset}">${match}</span>`; + }; + const html = text.replace(/<.0?x?([0-9a-fA-F]+)>/g, replacer); + fragment.innerHTML = html; + } }; - let OPCODE_STYLE = { - css: 'kwd', + const OPCODE_STYLE = { + css: 'kwd' }; const BLOCK_HEADER_STYLE = { - css: ['com', 'block'], - block_id: null, - blockId: function (text) { - let matches = /\d+/.exec(text); - if (!matches) return undefined; - BLOCK_HEADER_STYLE.block_id = Number(matches[0]); - return BLOCK_HEADER_STYLE.block_id; - }, - linkHandler: function (text) { - let matches = /\d+/.exec(text); - if (!matches) return undefined; + associateData: function (text, fragment) { + const matches = /\d+/.exec(text); + if (!matches) return; const blockId = matches[0]; - return function (e) { - e.stopPropagation(); - if (!e.shiftKey) { - view.selectionHandler.clear(); - } - view.blockSelectionHandler.select([blockId], true); - }; + fragment.dataset.blockId = blockId; + fragment.innerHTML = text; + fragment.className = "com block"; } }; const SOURCE_POSITION_HEADER_STYLE = { css: 'com' }; view.SOURCE_POSITION_HEADER_REGEX = /^\s*--[^<]*<.*(not inlined|inlined\((\d+)\)):(\d+)>\s*--/; - let patterns = [ + const patterns = [ [ - [/^0x[0-9a-f]{8,16}\s*[0-9a-f]+\ /, ADDRESS_STYLE, 1], + [/^0?x?[0-9a-fA-F]{8,16}\s+[0-9a-f]+\s+/, ADDRESS_STYLE, 1], [view.SOURCE_POSITION_HEADER_REGEX, SOURCE_POSITION_HEADER_STYLE, -1], [/^\s+-- B\d+ start.*/, BLOCK_HEADER_STYLE, -1], [/^.*/, UNCLASSIFIED_STYLE, -1] ], [ - [/^\s+[0-9a-f]+\s+/, NUMBER_STYLE, 2], - [/^\s+[0-9a-f]+\s+[0-9a-f]+\s+/, NUMBER_STYLE, 2], + [/^\s*[0-9a-f]+\s+/, NUMBER_STYLE, 2], + [/^\s*[0-9a-f]+\s+[0-9a-f]+\s+/, NUMBER_STYLE, 2], [/^.*/, null, -1] ], [ + [/^REX.W \S+\s+/, OPCODE_STYLE, 3], [/^\S+\s+/, OPCODE_STYLE, 3], [/^\S+$/, OPCODE_STYLE, -1], [/^.*/, null, -1] ], [ [/^\s+/, null], - [/^[^\(;]+$/, null, -1], - [/^[^\(;]+/, null], - [/^\(/, null, 4], + [/^[^;]+$/, OPCODE_ARGS, -1], + [/^[^;]+/, OPCODE_ARGS, 4], [/^;/, COMMENT_STYLE, 5] ], [ - [/^0x[0-9a-f]{8,16}/, ADDRESS_LINK_STYLE], - [/^[^\)]/, null], - [/^\)$/, null, -1], - [/^\)/, null, 3] - ], - [ - [/^; debug\: position /, COMMENT_STYLE, 6], [/^.+$/, COMMENT_STYLE, -1] - ], - [ - [/^\d+$/, POSITION_STYLE, -1], ] ]; view.setPatterns(patterns); + + const linkHandler = (e: MouseEvent) => { + if (!(e.target instanceof HTMLElement)) return; + const offsetAsString = e.target.dataset.pcOffset ? e.target.dataset.pcOffset : e.target.parentElement.dataset.pcOffset; + const offset = Number.parseInt(offsetAsString, 10); + if ((typeof offsetAsString) != "undefined" && !Number.isNaN(offset)) { + view.offsetSelection.select([offset], true); + const nodes = view.sourceResolver.nodesForPCOffset(offset)[0]; + if (nodes.length > 0) { + e.stopPropagation(); + if (!e.shiftKey) { + view.selectionHandler.clear(); + } + view.selectionHandler.select(nodes, true); + } else { + view.updateSelection(); + } + } + return undefined; + }; + view.divNode.addEventListener('click', linkHandler); + + const linkHandlerBlock = e => { + const blockId = e.target.dataset.blockId; + if (typeof blockId != "undefined" && !Number.isNaN(blockId)) { + e.stopPropagation(); + if (!e.shiftKey) { + view.selectionHandler.clear(); + } + view.blockSelectionHandler.select([blockId], true); + } + }; + view.divNode.addEventListener('click', linkHandlerBlock); + + this.offsetSelection = new MySelection(anyToString); + const instructionSelectionHandler = { + clear: function () { + view.offsetSelection.clear(); + view.updateSelection(); + broker.broadcastClear(instructionSelectionHandler); + }, + select: function (instructionIds, selected) { + view.offsetSelection.select(instructionIds, selected); + view.updateSelection(); + broker.broadcastBlockSelect(instructionSelectionHandler, instructionIds, selected); + }, + brokeredInstructionSelect: function (instructionIds, selected) { + const firstSelect = view.offsetSelection.isEmpty(); + const keyPcOffsets = view.sourceResolver.instructionsToKeyPcOffsets(instructionIds); + view.offsetSelection.select(keyPcOffsets, selected); + view.updateSelection(firstSelect); + }, + brokeredClear: function () { + view.offsetSelection.clear(); + view.updateSelection(); + } + }; + this.instructionSelectionHandler = instructionSelectionHandler; + broker.addInstructionHandler(instructionSelectionHandler); + + const toolbox = document.createElement("div"); + toolbox.id = "toolbox-anchor"; + toolbox.innerHTML = toolboxHTML; + view.divNode.insertBefore(toolbox, view.divNode.firstChild); + const instructionAddressInput: HTMLInputElement = view.divNode.querySelector("#show-instruction-address"); + const lastShowInstructionAddress = window.sessionStorage.getItem("show-instruction-address"); + instructionAddressInput.checked = lastShowInstructionAddress == 'true'; + const showInstructionAddressHandler = () => { + window.sessionStorage.setItem("show-instruction-address", `${instructionAddressInput.checked}`); + for (const el of view.divNode.querySelectorAll(".instruction-address")) { + el.classList.toggle("invisible", !instructionAddressInput.checked); + } + }; + instructionAddressInput.addEventListener("change", showInstructionAddressHandler); + this.showInstructionAddressHandler = showInstructionAddressHandler; + + const instructionBinaryInput: HTMLInputElement = view.divNode.querySelector("#show-instruction-binary"); + const lastShowInstructionBinary = window.sessionStorage.getItem("show-instruction-binary"); + instructionBinaryInput.checked = lastShowInstructionBinary == 'true'; + const showInstructionBinaryHandler = () => { + window.sessionStorage.setItem("show-instruction-binary", `${instructionBinaryInput.checked}`); + for (const el of view.divNode.querySelectorAll(".instruction-binary")) { + el.classList.toggle("invisible", !instructionBinaryInput.checked); + } + }; + instructionBinaryInput.addEventListener("change", showInstructionBinaryHandler); + this.showInstructionBinaryHandler = showInstructionBinaryHandler; + } + + updateSelection(scrollIntoView: boolean = false) { + super.updateSelection(scrollIntoView); + const keyPcOffsets = this.sourceResolver.nodesToKeyPcOffsets(this.selection.selectedKeys()); + if (this.offsetSelection) { + for (const key of this.offsetSelection.selectedKeys()) { + keyPcOffsets.push(Number(key)); + } + } + for (const keyPcOffset of keyPcOffsets) { + const elementsToSelect = this.divNode.querySelectorAll(`[data-pc-offset='${keyPcOffset}']`); + for (const el of elementsToSelect) { + el.classList.toggle("selected", true); + } + } } - initializeCode(sourceText, sourcePosition) { - let view = this; - view.addr_event_counts = null; - view.total_event_counts = null; - view.max_event_counts = null; - view.pos_lines = new Array(); + initializeCode(sourceText, sourcePosition: number = 0) { + const view = this; + view.addrEventCounts = null; + view.totalEventCounts = null; + view.maxEventCounts = null; + view.posLines = new Array(); // Comment lines for line 0 include sourcePosition already, only need to // add sourcePosition for lines > 0. - view.pos_lines[0] = sourcePosition; + view.posLines[0] = sourcePosition; if (sourceText && sourceText != "") { - let base = sourcePosition; + const base = sourcePosition; let current = 0; - let source_lines = sourceText.split("\n"); - for (let i = 1; i < source_lines.length; i++) { + const sourceLines = sourceText.split("\n"); + for (let i = 1; i < sourceLines.length; i++) { // Add 1 for newline character that is split off. - current += source_lines[i - 1].length + 1; - view.pos_lines[i] = base + current; + current += sourceLines[i - 1].length + 1; + view.posLines[i] = base + current; } } } initializePerfProfile(eventCounts) { - let view = this; + const view = this; if (eventCounts !== undefined) { - view.addr_event_counts = eventCounts; - - view.total_event_counts = {}; - view.max_event_counts = {}; - for (let ev_name in view.addr_event_counts) { - let keys = Object.keys(view.addr_event_counts[ev_name]); - let values = keys.map(key => view.addr_event_counts[ev_name][key]); - view.total_event_counts[ev_name] = values.reduce((a, b) => a + b); - view.max_event_counts[ev_name] = values.reduce((a, b) => Math.max(a, b)); + view.addrEventCounts = eventCounts; + + view.totalEventCounts = {}; + view.maxEventCounts = {}; + for (const evName in view.addrEventCounts) { + if (view.addrEventCounts.hasOwnProperty(evName)) { + const keys = Object.keys(view.addrEventCounts[evName]); + const values = keys.map(key => view.addrEventCounts[evName][key]); + view.totalEventCounts[evName] = values.reduce((a, b) => a + b); + view.maxEventCounts[evName] = values.reduce((a, b) => Math.max(a, b)); + } } - } - else { - view.addr_event_counts = null; - view.total_event_counts = null; - view.max_event_counts = null; + } else { + view.addrEventCounts = null; + view.totalEventCounts = null; + view.maxEventCounts = null; } } + showContent(data): void { + console.time("disassembly-view"); + super.initializeContent(data, null); + this.showInstructionAddressHandler(); + this.showInstructionBinaryHandler(); + console.timeEnd("disassembly-view"); + } + // Shorten decimals and remove trailing zeroes for readability. humanize(num) { return num.toFixed(3).replace(/\.?0+$/, "") + "%"; } - // Interpolate between the given start and end values by a fraction of val/max. - interpolate(val, max, start, end) { - return start + (end - start) * (val / max); - } - processLine(line) { - let view = this; + const view = this; let fragments = super.processLine(line); // Add profiling data per instruction if available. - if (view.total_event_counts) { - let matches = /^(0x[0-9a-fA-F]+)\s+\d+\s+[0-9a-fA-F]+/.exec(line); + if (view.totalEventCounts) { + const matches = /^(0x[0-9a-fA-F]+)\s+\d+\s+[0-9a-fA-F]+/.exec(line); if (matches) { - let newFragments = []; - for (let event in view.addr_event_counts) { - let count = view.addr_event_counts[event][matches[1]]; + const newFragments = []; + for (const event in view.addrEventCounts) { + if (!view.addrEventCounts.hasOwnProperty(event)) continue; + const count = view.addrEventCounts[event][matches[1]]; let str = " "; - let css_cls = "prof"; + const cssCls = "prof"; if (count !== undefined) { - let perc = count / view.total_event_counts[event] * 100; + const perc = count / view.totalEventCounts[event] * 100; let col = { r: 255, g: 255, b: 255 }; for (let i = 0; i < PROF_COLS.length; i++) { if (perc === PROF_COLS[i].perc) { col = PROF_COLS[i].col; break; - } - else if (perc > PROF_COLS[i].perc && perc < PROF_COLS[i + 1].perc) { - let col1 = PROF_COLS[i].col; - let col2 = PROF_COLS[i + 1].col; + } else if (perc > PROF_COLS[i].perc && perc < PROF_COLS[i + 1].perc) { + const col1 = PROF_COLS[i].col; + const col2 = PROF_COLS[i + 1].col; - let val = perc - PROF_COLS[i].perc; - let max = PROF_COLS[i + 1].perc - PROF_COLS[i].perc; + const val = perc - PROF_COLS[i].perc; + const max = PROF_COLS[i + 1].perc - PROF_COLS[i].perc; - col.r = Math.round(view.interpolate(val, max, col1.r, col2.r)); - col.g = Math.round(view.interpolate(val, max, col1.g, col2.g)); - col.b = Math.round(view.interpolate(val, max, col1.b, col2.b)); + col.r = Math.round(interpolate(val, max, col1.r, col2.r)); + col.g = Math.round(interpolate(val, max, col1.g, col2.g)); + col.b = Math.round(interpolate(val, max, col1.b, col2.b)); break; } } str = UNICODE_BLOCK; - let fragment = view.createFragment(str, css_cls); + const fragment = view.createFragment(str, cssCls); fragment.title = event + ": " + view.humanize(perc) + " (" + count + ")"; fragment.style.color = "rgb(" + col.r + ", " + col.g + ", " + col.b + ")"; newFragments.push(fragment); + } else { + newFragments.push(view.createFragment(str, cssCls)); } - else - newFragments.push(view.createFragment(str, css_cls)); - } fragments = newFragments.concat(fragments); } @@ -245,4 +347,8 @@ export class DisassemblyView extends TextView { } detachSelection() { return null; } + + public searchInputAction(searchInput: HTMLInputElement, e: Event, onlyVisible: boolean): void { + throw new Error("Method not implemented."); + } } diff --git a/deps/v8/tools/turbolizer/src/edge.ts b/deps/v8/tools/turbolizer/src/edge.ts index 7ca6d9dba0..30d265c561 100644 --- a/deps/v8/tools/turbolizer/src/edge.ts +++ b/deps/v8/tools/turbolizer/src/edge.ts @@ -2,19 +2,16 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import {GNode, DEFAULT_NODE_BUBBLE_RADIUS} from "./node.js" +import { GNode, DEFAULT_NODE_BUBBLE_RADIUS } from "../src/node"; +import { Graph } from "./graph"; export const MINIMUM_EDGE_SEPARATION = 20; -export function isEdgeInitiallyVisible(target, index, source, type) { - return type == "control" && (target.cfg || source.cfg); -} - export class Edge { target: GNode; source: GNode; index: number; - type: String; + type: string; backEdgeNumber: number; visible: boolean; @@ -24,55 +21,54 @@ export class Edge { this.index = index; this.type = type; this.backEdgeNumber = 0; - this.visible = isEdgeInitiallyVisible(target, index, source, type); + this.visible = false; } - stringID() { return this.source.id + "," + this.index + "," + this.target.id; - }; + } isVisible() { return this.visible && this.source.visible && this.target.visible; - }; + } - getInputHorizontalPosition(graph) { + getInputHorizontalPosition(graph: Graph, showTypes: boolean) { if (this.backEdgeNumber > 0) { return graph.maxGraphNodeX + this.backEdgeNumber * MINIMUM_EDGE_SEPARATION; } - var source = this.source; - var target = this.target; - var index = this.index; - var input_x = target.x + target.getInputX(index); - var inputApproach = target.getInputApproach(this.index); - var outputApproach = source.getOutputApproach(graph); + const source = this.source; + const target = this.target; + const index = this.index; + const inputX = target.x + target.getInputX(index); + const inputApproach = target.getInputApproach(this.index); + const outputApproach = source.getOutputApproach(showTypes); if (inputApproach > outputApproach) { - return input_x; + return inputX; } else { - var inputOffset = MINIMUM_EDGE_SEPARATION * (index + 1); + const inputOffset = MINIMUM_EDGE_SEPARATION * (index + 1); return (target.x < source.x) ? (target.x + target.getTotalNodeWidth() + inputOffset) - : (target.x - inputOffset) + : (target.x - inputOffset); } } - generatePath(graph) { - var target = this.target; - var source = this.source; - var input_x = target.x + target.getInputX(this.index); - var arrowheadHeight = 7; - var input_y = target.y - 2 * DEFAULT_NODE_BUBBLE_RADIUS - arrowheadHeight; - var output_x = source.x + source.getOutputX(); - var output_y = source.y + graph.getNodeHeight(source) + DEFAULT_NODE_BUBBLE_RADIUS; - var inputApproach = target.getInputApproach(this.index); - var outputApproach = source.getOutputApproach(graph); - var horizontalPos = this.getInputHorizontalPosition(graph); - - var result = "M" + output_x + "," + output_y + - "L" + output_x + "," + outputApproach + + generatePath(graph: Graph, showTypes: boolean) { + const target = this.target; + const source = this.source; + const inputX = target.x + target.getInputX(this.index); + const arrowheadHeight = 7; + const inputY = target.y - 2 * DEFAULT_NODE_BUBBLE_RADIUS - arrowheadHeight; + const outputX = source.x + source.getOutputX(); + const outputY = source.y + source.getNodeHeight(showTypes) + DEFAULT_NODE_BUBBLE_RADIUS; + let inputApproach = target.getInputApproach(this.index); + const outputApproach = source.getOutputApproach(showTypes); + const horizontalPos = this.getInputHorizontalPosition(graph, showTypes); + + let result = "M" + outputX + "," + outputY + + "L" + outputX + "," + outputApproach + "L" + horizontalPos + "," + outputApproach; - if (horizontalPos != input_x) { + if (horizontalPos != inputX) { result += "L" + horizontalPos + "," + inputApproach; } else { if (inputApproach < outputApproach) { @@ -80,8 +76,8 @@ export class Edge { } } - result += "L" + input_x + "," + inputApproach + - "L" + input_x + "," + input_y; + result += "L" + inputX + "," + inputApproach + + "L" + inputX + "," + inputY; return result; } diff --git a/deps/v8/tools/turbolizer/src/graph-layout.ts b/deps/v8/tools/turbolizer/src/graph-layout.ts index 302a98aacc..3687c28c86 100644 --- a/deps/v8/tools/turbolizer/src/graph-layout.ts +++ b/deps/v8/tools/turbolizer/src/graph-layout.ts @@ -2,23 +2,21 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import { MAX_RANK_SENTINEL } from "../src/constants"; +import { MINIMUM_EDGE_SEPARATION, Edge } from "../src/edge"; +import { NODE_INPUT_WIDTH, MINIMUM_NODE_OUTPUT_APPROACH, DEFAULT_NODE_BUBBLE_RADIUS, GNode } from "../src/node"; +import { Graph } from "./graph"; -import {MAX_RANK_SENTINEL} from "./constants.js" -import {MINIMUM_EDGE_SEPARATION} from "./edge.js" -import {NODE_INPUT_WIDTH, MINIMUM_NODE_OUTPUT_APPROACH, DEFAULT_NODE_BUBBLE_RADIUS} from "./node.js" +const DEFAULT_NODE_ROW_SEPARATION = 130; +const traceLayout = false; +function newGraphOccupation(graph: Graph) { + const isSlotFilled = []; + let maxSlot = 0; + let minSlot = 0; + let nodeOccupation: Array<[number, number]> = []; -const DEFAULT_NODE_ROW_SEPARATION = 130 - -var traceLayout = false; - -function newGraphOccupation(graph) { - var isSlotFilled = []; - var maxSlot = 0; - var minSlot = 0; - var nodeOccupation = []; - - function slotToIndex(slot) { + function slotToIndex(slot: number) { if (slot >= 0) { return slot * 2; } else { @@ -26,42 +24,30 @@ function newGraphOccupation(graph) { } } - function indexToSlot(index) { - if ((index % 0) == 0) { - return index / 2; - } else { - return -((index - 1) / 2); - } - } - - function positionToSlot(pos) { + function positionToSlot(pos: number) { return Math.floor(pos / NODE_INPUT_WIDTH); } - function slotToLeftPosition(slot) { - return slot * NODE_INPUT_WIDTH - } - - function slotToRightPosition(slot) { - return (slot + 1) * NODE_INPUT_WIDTH + function slotToLeftPosition(slot: number) { + return slot * NODE_INPUT_WIDTH; } - function findSpace(pos, width, direction) { - var widthSlots = Math.floor((width + NODE_INPUT_WIDTH - 1) / + function findSpace(pos: number, width: number, direction: number) { + const widthSlots = Math.floor((width + NODE_INPUT_WIDTH - 1) / NODE_INPUT_WIDTH); - var currentSlot = positionToSlot(pos + width / 2); - var currentScanSlot = currentSlot; - var widthSlotsRemainingLeft = widthSlots; - var widthSlotsRemainingRight = widthSlots; - var slotsChecked = 0; + const currentSlot = positionToSlot(pos + width / 2); + let currentScanSlot = currentSlot; + let widthSlotsRemainingLeft = widthSlots; + let widthSlotsRemainingRight = widthSlots; + let slotsChecked = 0; while (true) { - var mod = slotsChecked++ % 2; + const mod = slotsChecked++ % 2; currentScanSlot = currentSlot + (mod ? -1 : 1) * (slotsChecked >> 1); if (!isSlotFilled[slotToIndex(currentScanSlot)]) { if (mod) { - if (direction <= 0)--widthSlotsRemainingLeft + if (direction <= 0) --widthSlotsRemainingLeft; } else { - if (direction >= 0)--widthSlotsRemainingRight + if (direction >= 0) --widthSlotsRemainingRight; } if (widthSlotsRemainingLeft == 0 || widthSlotsRemainingRight == 0 || @@ -83,7 +69,7 @@ function newGraphOccupation(graph) { } } - function setIndexRange(from, to, value) { + function setIndexRange(from: number, to: number, value: boolean) { if (to < from) { throw ("illegal slot range"); } @@ -98,48 +84,47 @@ function newGraphOccupation(graph) { } } - function occupySlotRange(from, to) { + function occupySlotRange(from: number, to: number) { if (traceLayout) { console.log("Occupied [" + slotToLeftPosition(from) + " " + slotToLeftPosition(to + 1) + ")"); } setIndexRange(from, to, true); } - function clearSlotRange(from, to) { + function clearSlotRange(from: number, to: number) { if (traceLayout) { console.log("Cleared [" + slotToLeftPosition(from) + " " + slotToLeftPosition(to + 1) + ")"); } setIndexRange(from, to, false); } - function occupyPositionRange(from, to) { + function occupyPositionRange(from: number, to: number) { occupySlotRange(positionToSlot(from), positionToSlot(to - 1)); } - function clearPositionRange(from, to) { + function clearPositionRange(from: number, to: number) { clearSlotRange(positionToSlot(from), positionToSlot(to - 1)); } - function occupyPositionRangeWithMargin(from, to, margin) { - var fromMargin = from - Math.floor(margin); - var toMargin = to + Math.floor(margin); + function occupyPositionRangeWithMargin(from: number, to: number, margin: number) { + const fromMargin = from - Math.floor(margin); + const toMargin = to + Math.floor(margin); occupyPositionRange(fromMargin, toMargin); } - function clearPositionRangeWithMargin(from, to, margin) { - var fromMargin = from - Math.floor(margin); - var toMargin = to + Math.floor(margin); + function clearPositionRangeWithMargin(from: number, to: number, margin: number) { + const fromMargin = from - Math.floor(margin); + const toMargin = to + Math.floor(margin); clearPositionRange(fromMargin, toMargin); } - var occupation = { - occupyNodeInputs: function (node) { - for (var i = 0; i < node.inputs.length; ++i) { + const occupation = { + occupyNodeInputs: function (node: GNode, showTypes: boolean) { + for (let i = 0; i < node.inputs.length; ++i) { if (node.inputs[i].isVisible()) { - var edge = node.inputs[i]; + const edge = node.inputs[i]; if (!edge.isBackEdge()) { - var source = edge.source; - var horizontalPos = edge.getInputHorizontalPosition(graph); + const horizontalPos = edge.getInputHorizontalPosition(graph, showTypes); if (traceLayout) { console.log("Occupying input " + i + " of " + node.id + " at " + horizontalPos); } @@ -150,19 +135,18 @@ function newGraphOccupation(graph) { } } }, - occupyNode: function (node) { - var getPlacementHint = function (n) { - var pos = 0; - var direction = -1; - var outputEdges = 0; - var inputEdges = 0; - for (var k = 0; k < n.outputs.length; ++k) { - var outputEdge = n.outputs[k]; + occupyNode: function (node: GNode) { + const getPlacementHint = function (n: GNode) { + let pos = 0; + let direction = -1; + let outputEdges = 0; + let inputEdges = 0; + for (const outputEdge of n.outputs) { if (outputEdge.isVisible()) { - var output = n.outputs[k].target; - for (var l = 0; l < output.inputs.length; ++l) { + const output = outputEdge.target; + for (let l = 0; l < output.inputs.length; ++l) { if (output.rank > n.rank) { - var inputEdge = output.inputs[l]; + const inputEdge = output.inputs[l]; if (inputEdge.isVisible()) { ++inputEdges; } @@ -184,19 +168,19 @@ function newGraphOccupation(graph) { direction = 0; } return [direction, pos]; - } - var width = node.getTotalNodeWidth(); - var margin = MINIMUM_EDGE_SEPARATION; - var paddedWidth = width + 2 * margin; - var placementHint = getPlacementHint(node); - var x = placementHint[1] - paddedWidth + margin; + }; + const width = node.getTotalNodeWidth(); + const margin = MINIMUM_EDGE_SEPARATION; + const paddedWidth = width + 2 * margin; + const placementHint = getPlacementHint(node); + const x = placementHint[1] - paddedWidth + margin; if (traceLayout) { console.log("Node " + node.id + " placement hint [" + x + ", " + (x + paddedWidth) + ")"); } - var placement = findSpace(x, paddedWidth, placementHint[0]); - var firstSlot = placement[0]; - var slotWidth = placement[1]; - var endSlotExclusive = firstSlot + slotWidth - 1; + const placement = findSpace(x, paddedWidth, placementHint[0]); + const firstSlot = placement[0]; + const slotWidth = placement[1]; + const endSlotExclusive = firstSlot + slotWidth - 1; occupySlotRange(firstSlot, endSlotExclusive); nodeOccupation.push([firstSlot, endSlotExclusive]); if (placementHint[0] < 0) { @@ -208,18 +192,18 @@ function newGraphOccupation(graph) { } }, clearOccupiedNodes: function () { - nodeOccupation.forEach(function (o) { - clearSlotRange(o[0], o[1]); + nodeOccupation.forEach(([firstSlot, endSlotExclusive]) => { + clearSlotRange(firstSlot, endSlotExclusive); }); nodeOccupation = []; }, - clearNodeOutputs: function (source) { + clearNodeOutputs: function (source: GNode, showTypes: boolean) { source.outputs.forEach(function (edge) { if (edge.isVisible()) { - var target = edge.target; - for (var i = 0; i < target.inputs.length; ++i) { - if (target.inputs[i].source === source) { - var horizontalPos = edge.getInputHorizontalPosition(graph); + const target = edge.target; + for (const inputEdge of target.inputs) { + if (inputEdge.source === source) { + const horizontalPos = edge.getInputHorizontalPosition(graph, showTypes); clearPositionRangeWithMargin(horizontalPos, horizontalPos, NODE_INPUT_WIDTH / 2); @@ -229,8 +213,8 @@ function newGraphOccupation(graph) { }); }, print: function () { - var s = ""; - for (var currentSlot = -40; currentSlot < 40; ++currentSlot) { + let s = ""; + for (let currentSlot = -40; currentSlot < 40; ++currentSlot) { if (currentSlot != 0) { s += " "; } else { @@ -239,7 +223,7 @@ function newGraphOccupation(graph) { } console.log(s); s = ""; - for (var currentSlot2 = -40; currentSlot2 < 40; ++currentSlot2) { + for (let currentSlot2 = -40; currentSlot2 < 40; ++currentSlot2) { if (isSlotFilled[slotToIndex(currentSlot2)]) { s += "*"; } else { @@ -248,30 +232,33 @@ function newGraphOccupation(graph) { } console.log(s); } - } + }; return occupation; } -export function layoutNodeGraph(graph) { +export function layoutNodeGraph(graph: Graph, showTypes: boolean): void { // First determine the set of nodes that have no outputs. Those are the // basis for bottom-up DFS to determine rank and node placement. - var endNodesHasNoOutputs = []; - var startNodesHasNoInputs = []; - graph.nodes.forEach(function (n, i) { + + const start = performance.now(); + + const endNodesHasNoOutputs = []; + const startNodesHasNoInputs = []; + for (const n of graph.nodes()) { endNodesHasNoOutputs[n.id] = true; startNodesHasNoInputs[n.id] = true; - }); - graph.edges.forEach(function (e, i) { + } + graph.forEachEdge((e: Edge) => { endNodesHasNoOutputs[e.source.id] = false; startNodesHasNoInputs[e.target.id] = false; }); // Finialize the list of start and end nodes. - var endNodes = []; - var startNodes = []; - var visited = []; - var rank = []; - graph.nodes.forEach(function (n, i) { + const endNodes: Array<GNode> = []; + const startNodes: Array<GNode> = []; + let visited: Array<boolean> = []; + const rank: Array<number> = []; + for (const n of graph.nodes()) { if (endNodesHasNoOutputs[n.id]) { endNodes.push(n); } @@ -283,40 +270,44 @@ export function layoutNodeGraph(graph) { n.rank = 0; n.visitOrderWithinRank = 0; n.outputApproach = MINIMUM_NODE_OUTPUT_APPROACH; - }); + } + if (traceLayout) { + console.log(`layoutGraph init ${performance.now() - start}`); + } - var maxRank = 0; - var visited = []; - var dfsStack = []; - var visitOrderWithinRank = 0; + let maxRank = 0; + visited = []; + let visitOrderWithinRank = 0; - var worklist = startNodes.slice(); + const worklist: Array<GNode> = startNodes.slice(); while (worklist.length != 0) { - var n = worklist.pop(); - var changed = false; + const n: GNode = worklist.pop(); + let changed = false; if (n.rank == MAX_RANK_SENTINEL) { n.rank = 1; changed = true; } - var begin = 0; - var end = n.inputs.length; - if (n.opcode == 'Phi' || n.opcode == 'EffectPhi') { + let begin = 0; + let end = n.inputs.length; + if (n.nodeLabel.opcode == 'Phi' || + n.nodeLabel.opcode == 'EffectPhi' || + n.nodeLabel.opcode == 'InductionVariablePhi') { // Keep with merge or loop node begin = n.inputs.length - 1; } else if (n.hasBackEdges()) { end = 1; } - for (var l = begin; l < end; ++l) { - var input = n.inputs[l].source; + for (let l = begin; l < end; ++l) { + const input = n.inputs[l].source; if (input.visible && input.rank >= n.rank) { n.rank = input.rank + 1; changed = true; } } if (changed) { - var hasBackEdges = n.hasBackEdges(); - for (var l = n.outputs.length - 1; l >= 0; --l) { + const hasBackEdges = n.hasBackEdges(); + for (let l = n.outputs.length - 1; l >= 0; --l) { if (hasBackEdges && (l != 0)) { worklist.unshift(n.outputs[l].target); } else { @@ -329,24 +320,28 @@ export function layoutNodeGraph(graph) { } } + if (traceLayout) { + console.log(`layoutGraph worklist ${performance.now() - start}`); + } + visited = []; - function dfsFindRankLate(n) { + function dfsFindRankLate(n: GNode) { if (visited[n.id]) return; visited[n.id] = true; - var originalRank = n.rank; - var newRank = n.rank; - var firstInput = true; - for (var l = 0; l < n.outputs.length; ++l) { - var output = n.outputs[l].target; + const originalRank = n.rank; + let newRank = n.rank; + let isFirstInput = true; + for (const outputEdge of n.outputs) { + const output = outputEdge.target; dfsFindRankLate(output); - var outputRank = output.rank; - if (output.visible && (firstInput || outputRank <= newRank) && + const outputRank = output.rank; + if (output.visible && (isFirstInput || outputRank <= newRank) && (outputRank > originalRank)) { newRank = outputRank - 1; } - firstInput = false; + isFirstInput = false; } - if (n.opcode != "Start" && n.opcode != "Phi" && n.opcode != "EffectPhi") { + if (n.nodeLabel.opcode != "Start" && n.nodeLabel.opcode != "Phi" && n.nodeLabel.opcode != "EffectPhi" && n.nodeLabel.opcode != "InductionVariablePhi") { n.rank = newRank; } } @@ -354,13 +349,12 @@ export function layoutNodeGraph(graph) { startNodes.forEach(dfsFindRankLate); visited = []; - function dfsRankOrder(n) { + function dfsRankOrder(n: GNode) { if (visited[n.id]) return; visited[n.id] = true; - for (var l = 0; l < n.outputs.length; ++l) { - var edge = n.outputs[l]; - if (edge.isVisible()) { - var output = edge.target; + for (const outputEdge of n.outputs) { + if (outputEdge.isVisible()) { + const output = outputEdge.target; dfsRankOrder(output); } } @@ -374,10 +368,10 @@ export function layoutNodeGraph(graph) { n.rank = maxRank + 1; }); - var rankSets = []; + const rankSets: Array<Array<GNode>> = []; // Collect sets for each rank. - graph.nodes.forEach(function (n, i) { - n.y = n.rank * (DEFAULT_NODE_ROW_SEPARATION + graph.getNodeHeight(n) + + for (const n of graph.nodes()) { + n.y = n.rank * (DEFAULT_NODE_ROW_SEPARATION + n.getNodeHeight(showTypes) + 2 * DEFAULT_NODE_BUBBLE_RADIUS); if (n.visible) { if (rankSets[n.rank] === undefined) { @@ -386,18 +380,17 @@ export function layoutNodeGraph(graph) { rankSets[n.rank].push(n); } } - }); + } // Iterate backwards from highest to lowest rank, placing nodes so that they // spread out from the "center" as much as possible while still being // compact and not overlapping live input lines. - var occupation = newGraphOccupation(graph); - var rankCount = 0; + const occupation = newGraphOccupation(graph); - rankSets.reverse().forEach(function (rankSet) { + rankSets.reverse().forEach(function (rankSet: Array<GNode>) { - for (var i = 0; i < rankSet.length; ++i) { - occupation.clearNodeOutputs(rankSet[i]); + for (const node of rankSet) { + occupation.clearNodeOutputs(node, showTypes); } if (traceLayout) { @@ -405,19 +398,25 @@ export function layoutNodeGraph(graph) { occupation.print(); } - var placedCount = 0; - rankSet = rankSet.sort(function (a, b) { - return a.visitOrderWithinRank < b.visitOrderWithinRank; + let placedCount = 0; + rankSet = rankSet.sort((a: GNode, b: GNode) => { + if (a.visitOrderWithinRank < b.visitOrderWithinRank) { + return -1; + } else if (a.visitOrderWithinRank == b.visitOrderWithinRank) { + return 0; + } else { + return 1; + } }); - for (var i = 0; i < rankSet.length; ++i) { - var nodeToPlace = rankSet[i]; + + for (const nodeToPlace of rankSet) { if (nodeToPlace.visible) { nodeToPlace.x = occupation.occupyNode(nodeToPlace); if (traceLayout) { console.log("Node " + nodeToPlace.id + " is placed between [" + nodeToPlace.x + ", " + (nodeToPlace.x + nodeToPlace.getTotalNodeWidth()) + ")"); } - var staggeredFlooredI = Math.floor(placedCount++ % 3); - var delta = MINIMUM_EDGE_SEPARATION * staggeredFlooredI + const staggeredFlooredI = Math.floor(placedCount++ % 3); + const delta = MINIMUM_EDGE_SEPARATION * staggeredFlooredI; nodeToPlace.outputApproach += delta; } else { nodeToPlace.x = 0; @@ -436,9 +435,8 @@ export function layoutNodeGraph(graph) { occupation.print(); } - for (var i = 0; i < rankSet.length; ++i) { - var node = rankSet[i]; - occupation.occupyNodeInputs(node); + for (const node of rankSet) { + occupation.occupyNodeInputs(node, showTypes); } if (traceLayout) { @@ -453,57 +451,11 @@ export function layoutNodeGraph(graph) { }); graph.maxBackEdgeNumber = 0; - graph.visibleEdges.selectAll("path").each(function (e) { + graph.forEachEdge((e: Edge) => { if (e.isBackEdge()) { e.backEdgeNumber = ++graph.maxBackEdgeNumber; } else { e.backEdgeNumber = 0; } }); - - redetermineGraphBoundingBox(graph); -} - -function redetermineGraphBoundingBox(graph) { - graph.minGraphX = 0; - graph.maxGraphNodeX = 1; - graph.maxGraphX = undefined; // see below - graph.minGraphY = 0; - graph.maxGraphY = 1; - - for (var i = 0; i < graph.nodes.length; ++i) { - var node = graph.nodes[i]; - - if (!node.visible) { - continue; - } - - if (node.x < graph.minGraphX) { - graph.minGraphX = node.x; - } - if ((node.x + node.getTotalNodeWidth()) > graph.maxGraphNodeX) { - graph.maxGraphNodeX = node.x + node.getTotalNodeWidth(); - } - if ((node.y - 50) < graph.minGraphY) { - graph.minGraphY = node.y - 50; - } - if ((node.y + graph.getNodeHeight(node) + 50) > graph.maxGraphY) { - graph.maxGraphY = node.y + graph.getNodeHeight(node) + 50; - } - } - - graph.maxGraphX = graph.maxGraphNodeX + - graph.maxBackEdgeNumber * MINIMUM_EDGE_SEPARATION; - - const width = (graph.maxGraphX - graph.minGraphX); - const height = graph.maxGraphY - graph.minGraphY; - graph.width = width; - graph.height = height; - - const extent = [ - [graph.minGraphX - width / 2, graph.minGraphY - height / 2], - [graph.maxGraphX + width / 2, graph.maxGraphY + height / 2] - ]; - graph.panZoom.translateExtent(extent); - graph.minScale(); } diff --git a/deps/v8/tools/turbolizer/src/graph-view.ts b/deps/v8/tools/turbolizer/src/graph-view.ts index 9e136f8225..c46413c400 100644 --- a/deps/v8/tools/turbolizer/src/graph-view.ts +++ b/deps/v8/tools/turbolizer/src/graph-view.ts @@ -2,18 +2,20 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import * as d3 from "d3" -import {layoutNodeGraph} from "./graph-layout.js" -import {MAX_RANK_SENTINEL} from "./constants.js" -import {GNode, nodeToStr, isNodeInitiallyVisible} from "./node.js" -import {NODE_INPUT_WIDTH, MINIMUM_NODE_OUTPUT_APPROACH} from "./node.js" -import {DEFAULT_NODE_BUBBLE_RADIUS} from "./node.js" -import {Edge, edgeToStr} from "./edge.js" -import {View, PhaseView} from "./view.js" -import {MySelection} from "./selection.js" -import {partial, alignUp} from "./util.js" - -function nodeToStringKey(n) { +import * as d3 from "d3"; +import { layoutNodeGraph } from "../src/graph-layout"; +import { GNode, nodeToStr } from "../src/node"; +import { NODE_INPUT_WIDTH } from "../src/node"; +import { DEFAULT_NODE_BUBBLE_RADIUS } from "../src/node"; +import { Edge, edgeToStr } from "../src/edge"; +import { PhaseView } from "../src/view"; +import { MySelection } from "../src/selection"; +import { partial } from "../src/util"; +import { NodeSelectionHandler, ClearableHandler } from "./selection-handler"; +import { Graph } from "./graph"; +import { SelectionBroker } from "./selection-broker"; + +function nodeToStringKey(n: GNode) { return "" + n.id; } @@ -21,35 +23,28 @@ interface GraphState { showTypes: boolean; selection: MySelection; mouseDownNode: any; - justDragged: boolean, - justScaleTransGraph: boolean, - lastKeyDown: number, - hideDead: boolean + justDragged: boolean; + justScaleTransGraph: boolean; + hideDead: boolean; } -export class GraphView extends View implements PhaseView { +export class GraphView extends PhaseView { divElement: d3.Selection<any, any, any, any>; svg: d3.Selection<any, any, any, any>; - showPhaseByName: (string) => void; + showPhaseByName: (p: string, s: Set<any>) => void; state: GraphState; - nodes: Array<GNode>; - edges: Array<any>; - selectionHandler: NodeSelectionHandler; + selectionHandler: NodeSelectionHandler & ClearableHandler; graphElement: d3.Selection<any, any, any, any>; visibleNodes: d3.Selection<any, GNode, any, any>; visibleEdges: d3.Selection<any, Edge, any, any>; - minGraphX: number; - maxGraphX: number; - minGraphY: number; - maxGraphY: number; - width: number; - height: number; - maxGraphNodeX: number; drag: d3.DragBehavior<any, GNode, GNode>; panZoom: d3.ZoomBehavior<SVGElement, any>; - nodeMap: Array<any>; visibleBubbles: d3.Selection<any, any, any, any>; transitionTimout: number; + graph: Graph; + broker: SelectionBroker; + phaseName: string; + toolbox: HTMLElement; createViewElement() { const pane = document.createElement('div'); @@ -57,82 +52,88 @@ export class GraphView extends View implements PhaseView { return pane; } - constructor(id, broker, showPhaseByName: (string) => void) { - super(id); - var graph = this; + constructor(idOrContainer: string | HTMLElement, broker: SelectionBroker, + showPhaseByName: (s: string) => void, toolbox: HTMLElement) { + super(idOrContainer); + const view = this; + this.broker = broker; this.showPhaseByName = showPhaseByName; this.divElement = d3.select(this.divNode); - const svg = this.divElement.append("svg").attr('version', '1.1') + this.phaseName = ""; + this.toolbox = toolbox; + const svg = this.divElement.append("svg") + .attr('version', '2.0') .attr("width", "100%") .attr("height", "100%"); svg.on("click", function (d) { - graph.selectionHandler.clear(); + view.selectionHandler.clear(); }); - graph.svg = svg; + // Listen for key events. Note that the focus handler seems + // to be important even if it does nothing. + svg + .attr("focusable", false) + .on("focus", e => { }) + .on("keydown", e => { view.svgKeyDown(); }); - graph.nodes = []; - graph.edges = []; + view.svg = svg; - graph.minGraphX = 0; - graph.maxGraphX = 1; - graph.minGraphY = 0; - graph.maxGraphY = 1; - - graph.state = { + this.state = { selection: null, mouseDownNode: null, justDragged: false, justScaleTransGraph: false, - lastKeyDown: -1, showTypes: false, hideDead: false }; this.selectionHandler = { clear: function () { - graph.state.selection.clear(); + view.state.selection.clear(); broker.broadcastClear(this); - graph.updateGraphVisibility(); + view.updateGraphVisibility(); }, - select: function (nodes, selected) { - let locations = []; + select: function (nodes: Array<GNode>, selected: boolean) { + const locations = []; for (const node of nodes) { - if (node.sourcePosition) { - locations.push(node.sourcePosition); + if (node.nodeLabel.sourcePosition) { + locations.push(node.nodeLabel.sourcePosition); } - if (node.origin && node.origin.bytecodePosition) { - locations.push({ bytecodePosition: node.origin.bytecodePosition }); + if (node.nodeLabel.origin && node.nodeLabel.origin.bytecodePosition) { + locations.push({ bytecodePosition: node.nodeLabel.origin.bytecodePosition }); } } - graph.state.selection.select(nodes, selected); + view.state.selection.select(nodes, selected); broker.broadcastSourcePositionSelect(this, locations, selected); - graph.updateGraphVisibility(); + view.updateGraphVisibility(); }, - brokeredNodeSelect: function (locations, selected) { - let selection = graph.nodes - .filter(function (n) { - return locations.has(nodeToStringKey(n)) - && (!graph.state.hideDead || n.isLive()); - }); - graph.state.selection.select(selection, selected); - // Update edge visibility based on selection. - graph.nodes.forEach((n) => { - if (graph.state.selection.isSelected(n)) n.visible = true; + brokeredNodeSelect: function (locations, selected: boolean) { + if (!view.graph) return; + const selection = view.graph.nodes(n => { + return locations.has(nodeToStringKey(n)) + && (!view.state.hideDead || n.isLive()); }); - graph.edges.forEach(function (e) { - e.visible = e.visible || - (graph.state.selection.isSelected(e.source) && graph.state.selection.isSelected(e.target)); - }); - graph.updateGraphVisibility(); + view.state.selection.select(selection, selected); + // Update edge visibility based on selection. + for (const n of view.graph.nodes()) { + if (view.state.selection.isSelected(n)) { + n.visible = true; + n.inputs.forEach(e => { + e.visible = e.visible || view.state.selection.isSelected(e.source); + }); + n.outputs.forEach(e => { + e.visible = e.visible || view.state.selection.isSelected(e.target); + }); + } + } + view.updateGraphVisibility(); }, brokeredClear: function () { - graph.state.selection.clear(); - graph.updateGraphVisibility(); + view.state.selection.clear(); + view.updateGraphVisibility(); } }; - broker.addNodeHandler(this.selectionHandler); - graph.state.selection = new MySelection(nodeToStringKey); + view.state.selection = new MySelection(nodeToStringKey); const defs = svg.append('svg:defs'); defs.append('svg:marker') @@ -146,35 +147,20 @@ export class GraphView extends View implements PhaseView { .attr('d', 'M0,-4L8,0L0,4'); this.graphElement = svg.append("g"); - graph.visibleEdges = this.graphElement.append("g"); - graph.visibleNodes = this.graphElement.append("g"); + view.visibleEdges = this.graphElement.append("g"); + view.visibleNodes = this.graphElement.append("g"); - graph.drag = d3.drag<any, GNode, GNode>() + view.drag = d3.drag<any, GNode, GNode>() .on("drag", function (d) { d.x += d3.event.dx; d.y += d3.event.dy; - graph.updateGraphVisibility(); + view.updateGraphVisibility(); }); - - d3.select("#layout").on("click", partial(this.layoutAction, graph)); - d3.select("#show-all").on("click", partial(this.showAllAction, graph)); - d3.select("#toggle-hide-dead").on("click", partial(this.toggleHideDead, graph)); - d3.select("#hide-unselected").on("click", partial(this.hideUnselectedAction, graph)); - d3.select("#hide-selected").on("click", partial(this.hideSelectedAction, graph)); - d3.select("#zoom-selection").on("click", partial(this.zoomSelectionAction, graph)); - d3.select("#toggle-types").on("click", partial(this.toggleTypesAction, graph)); - - // listen for key events - d3.select(window).on("keydown", function (e) { - graph.svgKeyDown.call(graph); - }).on("keyup", function () { - graph.svgKeyUp.call(graph); - }); - function zoomed() { if (d3.event.shiftKey) return false; - graph.graphElement.attr("transform", d3.event.transform); + view.graphElement.attr("transform", d3.event.transform); + return true; } const zoomSvg = d3.zoom<SVGElement, any>() @@ -190,38 +176,17 @@ export class GraphView extends View implements PhaseView { svg.call(zoomSvg).on("dblclick.zoom", null); - graph.panZoom = zoomSvg; - - } - - - static get selectedClass() { - return "selected"; - } - static get rectClass() { - return "nodeStyle"; - } - static get activeEditId() { - return "active-editing"; - } - static get nodeRadius() { - return 50; - } + view.panZoom = zoomSvg; - getNodeHeight(d): number { - if (this.state.showTypes) { - return d.normalheight + d.labelbbox.height; - } else { - return d.normalheight; - } } - getEdgeFrontier(nodes, inEdges, edgeFilter) { - let frontier = new Set(); + getEdgeFrontier(nodes: Iterable<GNode>, inEdges: boolean, + edgeFilter: (e: Edge, i: number) => boolean) { + const frontier: Set<Edge> = new Set(); for (const n of nodes) { - var edges = inEdges ? n.inputs : n.outputs; - var edgeNumber = 0; - edges.forEach(function (edge) { + const edges = inEdges ? n.inputs : n.outputs; + let edgeNumber = 0; + edges.forEach((edge: Edge) => { if (edgeFilter == undefined || edgeFilter(edge, edgeNumber)) { frontier.add(edge); } @@ -231,28 +196,29 @@ export class GraphView extends View implements PhaseView { return frontier; } - getNodeFrontier(nodes, inEdges, edgeFilter) { - let graph = this; - var frontier = new Set(); - var newState = true; - var edgeFrontier = graph.getEdgeFrontier(nodes, inEdges, edgeFilter); + getNodeFrontier(nodes: Iterable<GNode>, inEdges: boolean, + edgeFilter: (e: Edge, i: number) => boolean) { + const view = this; + const frontier: Set<GNode> = new Set(); + let newState = true; + const edgeFrontier = view.getEdgeFrontier(nodes, inEdges, edgeFilter); // Control key toggles edges rather than just turning them on if (d3.event.ctrlKey) { - edgeFrontier.forEach(function (edge) { + edgeFrontier.forEach(function (edge: Edge) { if (edge.visible) { newState = false; } }); } - edgeFrontier.forEach(function (edge) { + edgeFrontier.forEach(function (edge: Edge) { edge.visible = newState; if (newState) { - var node = inEdges ? edge.source : edge.target; + const node = inEdges ? edge.source : edge.target; node.visible = true; frontier.add(node); } }); - graph.updateGraphVisibility(); + view.updateGraphVisibility(); if (newState) { return frontier; } else { @@ -261,8 +227,39 @@ export class GraphView extends View implements PhaseView { } initializeContent(data, rememberedSelection) { - this.createGraph(data, rememberedSelection); - if (rememberedSelection != null) { + this.show(); + function createImgInput(id: string, title: string, onClick): HTMLElement { + const input = document.createElement("input"); + input.setAttribute("id", id); + input.setAttribute("type", "image"); + input.setAttribute("title", title); + input.setAttribute("src", `img/${id}-icon.png`); + input.className = "button-input graph-toolbox-item"; + input.addEventListener("click", onClick); + return input; + } + this.toolbox.appendChild(createImgInput("layout", "layout graph", + partial(this.layoutAction, this))); + this.toolbox.appendChild(createImgInput("show-all", "show all nodes", + partial(this.showAllAction, this))); + this.toolbox.appendChild(createImgInput("show-control", "show all nodes", + partial(this.showControlAction, this))); + this.toolbox.appendChild(createImgInput("toggle-hide-dead", "show only live nodes", + partial(this.toggleHideDead, this))); + this.toolbox.appendChild(createImgInput("hide-unselected", "show only live nodes", + partial(this.hideUnselectedAction, this))); + this.toolbox.appendChild(createImgInput("hide-selected", "show only live nodes", + partial(this.hideSelectedAction, this))); + this.toolbox.appendChild(createImgInput("zoom-selection", "show only live nodes", + partial(this.zoomSelectionAction, this))); + this.toolbox.appendChild(createImgInput("toggle-types", "show only live nodes", + partial(this.toggleTypesAction, this))); + + this.phaseName = data.name; + this.createGraph(data.data, rememberedSelection); + this.broker.addNodeHandler(this.selectionHandler); + + if (rememberedSelection != null && rememberedSelection.size > 0) { this.attachSelection(rememberedSelection); this.connectVisibleSelectedNodes(); this.viewSelection(); @@ -272,88 +269,50 @@ export class GraphView extends View implements PhaseView { } deleteContent() { - if (this.visibleNodes) { - this.nodes = []; - this.edges = []; - this.nodeMap = []; - this.updateGraphVisibility(); + for (const item of this.toolbox.querySelectorAll(".graph-toolbox-item")) { + item.parentElement.removeChild(item); } - }; - - measureText(text) { - const textMeasure = document.getElementById('text-measure') as SVGTSpanElement; - textMeasure.textContent = text; - return { - width: textMeasure.getBBox().width, - height: textMeasure.getBBox().height, - }; - } - createGraph(data, rememberedSelection) { - var g = this; - g.nodes = []; - g.nodeMap = []; - data.nodes.forEach(function (n, i) { - n.__proto__ = GNode.prototype; + for (const n of this.graph.nodes()) { n.visible = false; - n.x = 0; - n.y = 0; - if (typeof n.pos === "number") { - // Backwards compatibility. - n.sourcePosition = { scriptOffset: n.pos, inliningId: -1 }; - } - n.rank = MAX_RANK_SENTINEL; - n.inputs = []; - n.outputs = []; - n.rpo = -1; - n.outputApproach = MINIMUM_NODE_OUTPUT_APPROACH; - n.cfg = n.control; - g.nodeMap[n.id] = n; - n.displayLabel = n.getDisplayLabel(); - n.labelbbox = g.measureText(n.displayLabel); - n.typebbox = g.measureText(n.getDisplayType()); - var innerwidth = Math.max(n.labelbbox.width, n.typebbox.width); - n.width = alignUp(innerwidth + NODE_INPUT_WIDTH * 2, - NODE_INPUT_WIDTH); - var innerheight = Math.max(n.labelbbox.height, n.typebbox.height); - n.normalheight = innerheight + 20; - g.nodes.push(n); - }); - g.edges = []; - data.edges.forEach(function (e, i) { - var t = g.nodeMap[e.target]; - var s = g.nodeMap[e.source]; - var newEdge = new Edge(t, e.index, s, e.type); - t.inputs.push(newEdge); - s.outputs.push(newEdge); - g.edges.push(newEdge); - if (e.type == 'control') { - s.cfg = true; - } + } + this.graph.forEachEdge((e: Edge) => { + e.visible = false; }); - g.nodes.forEach(function (n, i) { - n.visible = isNodeInitiallyVisible(n) && (!g.state.hideDead || n.isLive()); - if (rememberedSelection != undefined) { - if (rememberedSelection.has(nodeToStringKey(n))) { - n.visible = true; - } + this.updateGraphVisibility(); + } + + public hide(): void { + super.hide(); + this.deleteContent(); + } + + createGraph(data, rememberedSelection) { + this.graph = new Graph(data); + + this.showControlAction(this); + + if (rememberedSelection != undefined) { + for (const n of this.graph.nodes()) { + n.visible = n.visible || rememberedSelection.has(nodeToStringKey(n)); } - }); - g.updateGraphVisibility(); - g.layoutGraph(); - g.updateGraphVisibility(); - g.viewWholeGraph(); + } + + this.graph.forEachEdge(e => e.visible = e.source.visible && e.target.visible); + + this.layoutGraph(); + this.updateGraphVisibility(); } connectVisibleSelectedNodes() { - var graph = this; - for (const n of graph.state.selection) { - n.inputs.forEach(function (edge) { + const view = this; + for (const n of view.state.selection) { + n.inputs.forEach(function (edge: Edge) { if (edge.source.visible && edge.target.visible) { edge.visible = true; } }); - n.outputs.forEach(function (edge) { + n.outputs.forEach(function (edge: Edge) { if (edge.source.visible && edge.target.visible) { edge.visible = true; } @@ -362,52 +321,51 @@ export class GraphView extends View implements PhaseView { } updateInputAndOutputBubbles() { - var g = this; - var s = g.visibleBubbles; + const view = this; + const g = this.graph; + const s = this.visibleBubbles; s.classed("filledBubbleStyle", function (c) { - var components = this.id.split(','); + const components = this.id.split(','); if (components[0] == "ib") { - var edge = g.nodeMap[components[3]].inputs[components[2]]; + const edge = g.nodeMap[components[3]].inputs[components[2]]; return edge.isVisible(); } else { return g.nodeMap[components[1]].areAnyOutputsVisible() == 2; } }).classed("halfFilledBubbleStyle", function (c) { - var components = this.id.split(','); + const components = this.id.split(','); if (components[0] == "ib") { - var edge = g.nodeMap[components[3]].inputs[components[2]]; return false; } else { return g.nodeMap[components[1]].areAnyOutputsVisible() == 1; } }).classed("bubbleStyle", function (c) { - var components = this.id.split(','); + const components = this.id.split(','); if (components[0] == "ib") { - var edge = g.nodeMap[components[3]].inputs[components[2]]; + const edge = g.nodeMap[components[3]].inputs[components[2]]; return !edge.isVisible(); } else { return g.nodeMap[components[1]].areAnyOutputsVisible() == 0; } }); s.each(function (c) { - var components = this.id.split(','); + const components = this.id.split(','); if (components[0] == "ob") { - var from = g.nodeMap[components[1]]; - var x = from.getOutputX(); - var y = g.getNodeHeight(from) + DEFAULT_NODE_BUBBLE_RADIUS; - var transform = "translate(" + x + "," + y + ")"; + const from = g.nodeMap[components[1]]; + const x = from.getOutputX(); + const y = from.getNodeHeight(view.state.showTypes) + DEFAULT_NODE_BUBBLE_RADIUS; + const transform = "translate(" + x + "," + y + ")"; this.setAttribute('transform', transform); } }); } attachSelection(s) { - const graph = this; if (!(s instanceof Set)) return; - graph.selectionHandler.clear(); - const selected = graph.nodes.filter((n) => - s.has(graph.state.selection.stringKey(n)) && (!graph.state.hideDead || n.isLive())); - graph.selectionHandler.select(selected, true); + this.selectionHandler.clear(); + const selected = [...this.graph.nodes(n => + s.has(this.state.selection.stringKey(n)) && (!this.state.hideDead || n.isLive()))]; + this.selectionHandler.select(selected, true); } detachSelection() { @@ -415,134 +373,135 @@ export class GraphView extends View implements PhaseView { } selectAllNodes() { - var graph = this; if (!d3.event.shiftKey) { - graph.state.selection.clear(); + this.state.selection.clear(); } - const allVisibleNodes = graph.nodes.filter((n) => n.visible); - graph.state.selection.select(allVisibleNodes, true); - graph.updateGraphVisibility(); + const allVisibleNodes = [...this.graph.nodes(n => n.visible)]; + this.state.selection.select(allVisibleNodes, true); + this.updateGraphVisibility(); } - layoutAction(graph) { - graph.updateGraphVisibility(); + layoutAction(graph: GraphView) { graph.layoutGraph(); graph.updateGraphVisibility(); graph.viewWholeGraph(); } - showAllAction(graph) { - graph.nodes.forEach(function (n) { - n.visible = !graph.state.hideDead || n.isLive(); + showAllAction(view: GraphView) { + for (const n of view.graph.nodes()) { + n.visible = !view.state.hideDead || n.isLive(); + } + view.graph.forEachEdge((e: Edge) => { + e.visible = e.source.visible || e.target.visible; }); - graph.edges.forEach(function (e) { - e.visible = !graph.state.hideDead || (e.source.isLive() && e.target.isLive()); + view.updateGraphVisibility(); + view.viewWholeGraph(); + } + + showControlAction(view: GraphView) { + for (const n of view.graph.nodes()) { + n.visible = n.cfg && (!view.state.hideDead || n.isLive()); + } + view.graph.forEachEdge((e: Edge) => { + e.visible = e.type == 'control' && e.source.visible && e.target.visible; }); - graph.updateGraphVisibility(); - graph.viewWholeGraph(); + view.updateGraphVisibility(); + view.viewWholeGraph(); } - toggleHideDead(graph) { - graph.state.hideDead = !graph.state.hideDead; - if (graph.state.hideDead) graph.hideDead(); - var element = document.getElementById('toggle-hide-dead'); - element.classList.toggle('button-input-toggled', graph.state.hideDead); + toggleHideDead(view: GraphView) { + view.state.hideDead = !view.state.hideDead; + if (view.state.hideDead) view.hideDead(); + const element = document.getElementById('toggle-hide-dead'); + element.classList.toggle('button-input-toggled', view.state.hideDead); } hideDead() { - const graph = this; - graph.nodes.filter(function (n) { + for (const n of this.graph.nodes()) { if (!n.isLive()) { n.visible = false; - graph.state.selection.select([n], false); + this.state.selection.select([n], false); } - }) - graph.updateGraphVisibility(); + } + this.updateGraphVisibility(); } - hideUnselectedAction(graph) { - graph.nodes.forEach(function (n) { - if (!graph.state.selection.isSelected(n)) { + hideUnselectedAction(view: GraphView) { + for (const n of view.graph.nodes()) { + if (!view.state.selection.isSelected(n)) { n.visible = false; } - }); - graph.updateGraphVisibility(); + } + view.updateGraphVisibility(); } - hideSelectedAction(graph) { - graph.nodes.forEach(function (n) { - if (graph.state.selection.isSelected(n)) { + hideSelectedAction(view: GraphView) { + for (const n of view.graph.nodes()) { + if (view.state.selection.isSelected(n)) { n.visible = false; } - }); - graph.selectionHandler.clear(); + } + view.selectionHandler.clear(); } - zoomSelectionAction(graph) { - graph.viewSelection(); + zoomSelectionAction(view: GraphView) { + view.viewSelection(); } - toggleTypesAction(graph) { - graph.toggleTypes(); + toggleTypesAction(view: GraphView) { + view.toggleTypes(); } - searchInputAction(searchBar, e: KeyboardEvent) { - const graph = this; + searchInputAction(searchBar: HTMLInputElement, e: KeyboardEvent, onlyVisible: boolean) { if (e.keyCode == 13) { - graph.selectionHandler.clear(); - var query = searchBar.value; + this.selectionHandler.clear(); + const query = searchBar.value; window.sessionStorage.setItem("lastSearch", query); if (query.length == 0) return; - var reg = new RegExp(query); - var filterFunction = function (n) { + const reg = new RegExp(query); + const filterFunction = (n: GNode) => { return (reg.exec(n.getDisplayLabel()) != null || - (graph.state.showTypes && reg.exec(n.getDisplayType())) || + (this.state.showTypes && reg.exec(n.getDisplayType())) || (reg.exec(n.getTitle())) || - reg.exec(n.opcode) != null); + reg.exec(n.nodeLabel.opcode) != null); }; - const selection = graph.nodes.filter( - function (n, i) { - if ((e.ctrlKey || n.visible) && filterFunction(n)) { - if (e.ctrlKey) n.visible = true; - return true; - } - return false; - }); + const selection = [...this.graph.nodes(n => { + if ((e.ctrlKey || n.visible || !onlyVisible) && filterFunction(n)) { + if (e.ctrlKey || !onlyVisible) n.visible = true; + return true; + } + return false; + })]; - graph.selectionHandler.select(selection, true); - graph.connectVisibleSelectedNodes(); - graph.updateGraphVisibility(); + this.selectionHandler.select(selection, true); + this.connectVisibleSelectedNodes(); + this.updateGraphVisibility(); searchBar.blur(); - graph.viewSelection(); + this.viewSelection(); } e.stopPropagation(); } svgKeyDown() { - var state = this.state; - var graph = this; - - // Don't handle key press repetition - if (state.lastKeyDown !== -1) return; + const view = this; + const state = this.state; - var showSelectionFrontierNodes = function (inEdges, filter, select) { - var frontier = graph.getNodeFrontier(state.selection, inEdges, filter); + const showSelectionFrontierNodes = (inEdges: boolean, filter: (e: Edge, i: number) => boolean, doSelect: boolean) => { + const frontier = view.getNodeFrontier(state.selection, inEdges, filter); if (frontier != undefined && frontier.size) { - if (select) { + if (doSelect) { if (!d3.event.shiftKey) { state.selection.clear(); } - state.selection.select(frontier, true); + state.selection.select([...frontier], true); } - graph.updateGraphVisibility(); + view.updateGraphVisibility(); } - allowRepetition = false; - } + }; - var allowRepetition = true; - var eventHandled = true; // unless the below switch defaults + let eventHandled = true; // unless the below switch defaults switch (d3.event.keyCode) { case 49: case 50: @@ -555,8 +514,8 @@ export class GraphView extends View implements PhaseView { case 57: // '1'-'9' showSelectionFrontierNodes(true, - (edge, index) => { return index == (d3.event.keyCode - 49); }, - false); + (edge: Edge, index: number) => index == (d3.event.keyCode - 49), + !d3.event.ctrlKey); break; case 97: case 98: @@ -569,19 +528,19 @@ export class GraphView extends View implements PhaseView { case 105: // 'numpad 1'-'numpad 9' showSelectionFrontierNodes(true, - (edge, index) => { return index == (d3.event.keyCode - 97); }, - false); + (edge, index) => index == (d3.event.keyCode - 97), + !d3.event.ctrlKey); break; case 67: // 'c' showSelectionFrontierNodes(d3.event.altKey, - (edge, index) => { return edge.type == 'control'; }, + (edge, index) => edge.type == 'control', true); break; case 69: // 'e' showSelectionFrontierNodes(d3.event.altKey, - (edge, index) => { return edge.type == 'effect'; }, + (edge, index) => edge.type == 'effect', true); break; case 79: @@ -590,21 +549,26 @@ export class GraphView extends View implements PhaseView { break; case 73: // 'i' - showSelectionFrontierNodes(true, undefined, false); + if (!d3.event.ctrlKey && !d3.event.shiftKey) { + showSelectionFrontierNodes(true, undefined, false); + } else { + eventHandled = false; + } break; case 65: // 'a' - graph.selectAllNodes(); - allowRepetition = false; + view.selectAllNodes(); break; case 38: + // UP case 40: { + // DOWN showSelectionFrontierNodes(d3.event.keyCode == 38, undefined, true); break; } case 82: // 'r' - if (!d3.event.ctrlKey) { + if (!d3.event.ctrlKey && !d3.event.shiftKey) { this.layoutAction(this); } else { eventHandled = false; @@ -612,11 +576,7 @@ export class GraphView extends View implements PhaseView { break; case 83: // 's' - graph.selectOrigins(); - break; - case 191: - // '/' - document.getElementById("search-input").focus(); + view.selectOrigins(); break; default: eventHandled = false; @@ -625,93 +585,100 @@ export class GraphView extends View implements PhaseView { if (eventHandled) { d3.event.preventDefault(); } - if (!allowRepetition) { - state.lastKeyDown = d3.event.keyCode; - } } - svgKeyUp() { - this.state.lastKeyDown = -1 - }; - layoutGraph() { - layoutNodeGraph(this); + console.time("layoutGraph"); + layoutNodeGraph(this.graph, this.state.showTypes); + const extent = this.graph.redetermineGraphBoundingBox(this.state.showTypes); + this.panZoom.translateExtent(extent); + this.minScale(); + console.timeEnd("layoutGraph"); } selectOrigins() { const state = this.state; const origins = []; - let phase = null; + let phase = this.phaseName; + const selection = new Set<any>(); for (const n of state.selection) { - if (n.origin) { - const node = this.nodeMap[n.origin.nodeId]; - origins.push(node); - phase = n.origin.phase; + const origin = n.nodeLabel.origin; + if (origin) { + phase = origin.phase; + const node = this.graph.nodeMap[origin.nodeId]; + if (phase === this.phaseName && node) { + origins.push(node); + } else { + selection.add(`${origin.nodeId}`); + } } } - if (origins.length) { - state.selection.clear(); - state.selection.select(origins, true); - if (phase) { - this.showPhaseByName(phase); - } + // Only go through phase reselection if we actually need + // to display another phase. + if (selection.size > 0 && phase !== this.phaseName) { + this.showPhaseByName(phase, selection); + } else if (origins.length > 0) { + this.selectionHandler.clear(); + this.selectionHandler.select(origins, true); } } // call to propagate changes to graph updateGraphVisibility() { - let graph = this; - let state = graph.state; + const view = this; + const graph = this.graph; + const state = this.state; + if (!graph) return; - var filteredEdges = graph.edges.filter(function (e) { - return e.isVisible(); - }); - const selEdges = graph.visibleEdges.selectAll<SVGPathElement, Edge>("path").data(filteredEdges, edgeToStr); + const filteredEdges = [...graph.filteredEdges(function (e) { + return e.source.visible && e.target.visible; + })]; + const selEdges = view.visibleEdges.selectAll<SVGPathElement, Edge>("path").data(filteredEdges, edgeToStr); // remove old links selEdges.exit().remove(); // add new paths - selEdges.enter() - .append('path') - .style('marker-end', 'url(#end-arrow)') - .classed('hidden', function (e) { - return !e.isVisible(); - }) + const newEdges = selEdges.enter() + .append('path'); + + newEdges.style('marker-end', 'url(#end-arrow)') .attr("id", function (edge) { return "e," + edge.stringID(); }) .on("click", function (edge) { d3.event.stopPropagation(); if (!d3.event.shiftKey) { - graph.selectionHandler.clear(); + view.selectionHandler.clear(); } - graph.selectionHandler.select([edge.source, edge.target], true); + view.selectionHandler.select([edge.source, edge.target], true); }) - .attr("adjacentToHover", "false"); - - // Set the correct styles on all of the paths - selEdges.classed('value', function (e) { - return e.type == 'value' || e.type == 'context'; - }).classed('control', function (e) { - return e.type == 'control'; - }).classed('effect', function (e) { - return e.type == 'effect'; - }).classed('frame-state', function (e) { - return e.type == 'frame-state'; - }).attr('stroke-dasharray', function (e) { - if (e.type == 'frame-state') return "10,10"; - return (e.type == 'effect') ? "5,5" : ""; - }); + .attr("adjacentToHover", "false") + .classed('value', function (e) { + return e.type == 'value' || e.type == 'context'; + }).classed('control', function (e) { + return e.type == 'control'; + }).classed('effect', function (e) { + return e.type == 'effect'; + }).classed('frame-state', function (e) { + return e.type == 'frame-state'; + }).attr('stroke-dasharray', function (e) { + if (e.type == 'frame-state') return "10,10"; + return (e.type == 'effect') ? "5,5" : ""; + }); + + const newAndOldEdges = newEdges.merge(selEdges); + + newAndOldEdges.classed('hidden', e => !e.isVisible()); // select existing nodes - const filteredNodes = graph.nodes.filter(n => n.visible); - const allNodes = graph.visibleNodes.selectAll<SVGGElement, GNode>("g"); + const filteredNodes = [...graph.nodes(n => n.visible)]; + const allNodes = view.visibleNodes.selectAll<SVGGElement, GNode>("g"); const selNodes = allNodes.data(filteredNodes, nodeToStr); // remove old nodes selNodes.exit().remove(); // add new nodes - var newGs = selNodes.enter() + const newGs = selNodes.enter() .append("g"); newGs.classed("turbonode", function (n) { return true; }) @@ -723,36 +690,33 @@ export class GraphView extends View implements PhaseView { .classed("simplified", function (n) { return n.isSimplified(); }) .classed("machine", function (n) { return n.isMachine(); }) .on('mouseenter', function (node) { - const visibleEdges = graph.visibleEdges.selectAll<SVGPathElement, Edge>('path'); - const adjInputEdges = visibleEdges.filter(e => { return e.target === node; }); - const adjOutputEdges = visibleEdges.filter(e => { return e.source === node; }); + const visibleEdges = view.visibleEdges.selectAll<SVGPathElement, Edge>('path'); + const adjInputEdges = visibleEdges.filter(e => e.target === node); + const adjOutputEdges = visibleEdges.filter(e => e.source === node); adjInputEdges.attr('relToHover', "input"); adjOutputEdges.attr('relToHover', "output"); const adjInputNodes = adjInputEdges.data().map(e => e.source); - const visibleNodes = graph.visibleNodes.selectAll<SVGGElement, GNode>("g"); - const input = visibleNodes.data<GNode>(adjInputNodes, nodeToStr) - .attr('relToHover', "input"); + const visibleNodes = view.visibleNodes.selectAll<SVGGElement, GNode>("g"); + visibleNodes.data<GNode>(adjInputNodes, nodeToStr).attr('relToHover', "input"); const adjOutputNodes = adjOutputEdges.data().map(e => e.target); - const output = visibleNodes.data<GNode>(adjOutputNodes, nodeToStr) - .attr('relToHover', "output"); - graph.updateGraphVisibility(); + visibleNodes.data<GNode>(adjOutputNodes, nodeToStr).attr('relToHover', "output"); + view.updateGraphVisibility(); }) .on('mouseleave', function (node) { - const visibleEdges = graph.visibleEdges.selectAll<SVGPathElement, Edge>('path'); - const adjEdges = visibleEdges.filter(e => { return e.target === node || e.source === node; }); + const visibleEdges = view.visibleEdges.selectAll<SVGPathElement, Edge>('path'); + const adjEdges = visibleEdges.filter(e => e.target === node || e.source === node); adjEdges.attr('relToHover', "none"); const adjNodes = adjEdges.data().map(e => e.target).concat(adjEdges.data().map(e => e.source)); - const visibleNodes = graph.visibleNodes.selectAll<SVGPathElement, GNode>("g"); - const nodes = visibleNodes.data(adjNodes, nodeToStr) - .attr('relToHover', "none"); - graph.updateGraphVisibility(); + const visibleNodes = view.visibleNodes.selectAll<SVGPathElement, GNode>("g"); + visibleNodes.data(adjNodes, nodeToStr).attr('relToHover', "none"); + view.updateGraphVisibility(); }) - .on("click", (d) => { - if (!d3.event.shiftKey) graph.selectionHandler.clear(); - graph.selectionHandler.select([d], undefined); + .on("click", d => { + if (!d3.event.shiftKey) view.selectionHandler.clear(); + view.selectionHandler.select([d], undefined); d3.event.stopPropagation(); }) - .call(graph.drag) + .call(view.drag); newGs.append("rect") .attr("rx", 10) @@ -761,14 +725,14 @@ export class GraphView extends View implements PhaseView { return d.getTotalNodeWidth(); }) .attr('height', function (d) { - return graph.getNodeHeight(d); - }) + return d.getNodeHeight(view.state.showTypes); + }); function appendInputAndOutputBubbles(g, d) { - for (var i = 0; i < d.inputs.length; ++i) { - var x = d.getInputX(i); - var y = -DEFAULT_NODE_BUBBLE_RADIUS; - var s = g.append('circle') + for (let i = 0; i < d.inputs.length; ++i) { + const x = d.getInputX(i); + const y = -DEFAULT_NODE_BUBBLE_RADIUS; + g.append('circle') .classed("filledBubbleStyle", function (c) { return d.inputs[i].isVisible(); }) @@ -780,20 +744,20 @@ export class GraphView extends View implements PhaseView { .attr("transform", function (d) { return "translate(" + x + "," + y + ")"; }) - .on("click", function (d) { - var components = this.id.split(','); - var node = graph.nodeMap[components[3]]; - var edge = node.inputs[components[2]]; - var visible = !edge.isVisible(); + .on("click", function (this: SVGCircleElement, d) { + const components = this.id.split(','); + const node = graph.nodeMap[components[3]]; + const edge = node.inputs[components[2]]; + const visible = !edge.isVisible(); node.setInputVisibility(components[2], visible); d3.event.stopPropagation(); - graph.updateGraphVisibility(); + view.updateGraphVisibility(); }); } if (d.outputs.length != 0) { - var x = d.getOutputX(); - var y = graph.getNodeHeight(d) + DEFAULT_NODE_BUBBLE_RADIUS; - var s = g.append('circle') + const x = d.getOutputX(); + const y = d.getNodeHeight(view.state.showTypes) + DEFAULT_NODE_BUBBLE_RADIUS; + g.append('circle') .classed("filledBubbleStyle", function (c) { return d.areAnyOutputsVisible() == 2; }) @@ -811,7 +775,7 @@ export class GraphView extends View implements PhaseView { .on("click", function (d) { d.setOutputVisibility(d.areAnyOutputsVisible() == 0); d3.event.stopPropagation(); - graph.updateGraphVisibility(); + view.updateGraphVisibility(); }); } } @@ -833,8 +797,8 @@ export class GraphView extends View implements PhaseView { .append("title") .text(function (l) { return d.getTitle(); - }) - if (d.type != undefined) { + }); + if (d.nodeLabel.type != undefined) { d3.select(this).append("text") .classed("label", true) .classed("type", true) @@ -848,14 +812,14 @@ export class GraphView extends View implements PhaseView { .append("title") .text(function (l) { return d.getType(); - }) + }); } }); const newAndOldNodes = newGs.merge(selNodes); newAndOldNodes.select<SVGTextElement>('.type').each(function (d) { - this.setAttribute('visibility', graph.state.showTypes ? 'visible' : 'hidden'); + this.setAttribute('visibility', view.state.showTypes ? 'visible' : 'hidden'); }); newAndOldNodes @@ -865,15 +829,15 @@ export class GraphView extends View implements PhaseView { }) .attr("transform", function (d) { return "translate(" + d.x + "," + d.y + ")"; }) .select('rect') - .attr('height', function (d) { return graph.getNodeHeight(d); }); + .attr('height', function (d) { return d.getNodeHeight(view.state.showTypes); }); - graph.visibleBubbles = d3.selectAll('circle'); + view.visibleBubbles = d3.selectAll('circle'); - graph.updateInputAndOutputBubbles(); + view.updateInputAndOutputBubbles(); graph.maxGraphX = graph.maxGraphNodeX; - selEdges.attr("d", function (edge) { - return edge.generatePath(graph); + newAndOldEdges.attr("d", function (edge) { + return edge.generatePath(graph, view.state.showTypes); }); } @@ -886,10 +850,9 @@ export class GraphView extends View implements PhaseView { } minScale() { - const graph = this; const dimensions = this.getSvgViewDimensions(); - const minXScale = dimensions[0] / (2 * graph.width); - const minYScale = dimensions[1] / (2 * graph.height); + const minXScale = dimensions[0] / (2 * this.graph.width); + const minYScale = dimensions[1] / (2 * this.graph.height); const minScale = Math.min(minXScale, minYScale); this.panZoom.scaleExtent([minScale, 40]); return minScale; @@ -897,48 +860,49 @@ export class GraphView extends View implements PhaseView { onresize() { const trans = d3.zoomTransform(this.svg.node()); - const ctrans = this.panZoom.constrain()(trans, this.getSvgExtent(), this.panZoom.translateExtent()) - this.panZoom.transform(this.svg, ctrans) + const ctrans = this.panZoom.constrain()(trans, this.getSvgExtent(), this.panZoom.translateExtent()); + this.panZoom.transform(this.svg, ctrans); } toggleTypes() { - var graph = this; - graph.state.showTypes = !graph.state.showTypes; - var element = document.getElementById('toggle-types'); - element.classList.toggle('button-input-toggled', graph.state.showTypes); - graph.updateGraphVisibility(); + const view = this; + view.state.showTypes = !view.state.showTypes; + const element = document.getElementById('toggle-types'); + element.classList.toggle('button-input-toggled', view.state.showTypes); + view.updateGraphVisibility(); } viewSelection() { - var graph = this; - var minX, maxX, minY, maxY; - var hasSelection = false; - graph.visibleNodes.selectAll<SVGGElement, GNode>("g").each(function (n) { - if (graph.state.selection.isSelected(n)) { + const view = this; + let minX; + let maxX; + let minY; + let maxY; + let hasSelection = false; + view.visibleNodes.selectAll<SVGGElement, GNode>("g").each(function (n) { + if (view.state.selection.isSelected(n)) { hasSelection = true; minX = minX ? Math.min(minX, n.x) : n.x; maxX = maxX ? Math.max(maxX, n.x + n.getTotalNodeWidth()) : n.x + n.getTotalNodeWidth(); minY = minY ? Math.min(minY, n.y) : n.y; - maxY = maxY ? Math.max(maxY, n.y + graph.getNodeHeight(n)) : - n.y + graph.getNodeHeight(n); + maxY = maxY ? Math.max(maxY, n.y + n.getNodeHeight(view.state.showTypes)) : + n.y + n.getNodeHeight(view.state.showTypes); } }); if (hasSelection) { - graph.viewGraphRegion(minX - NODE_INPUT_WIDTH, minY - 60, - maxX + NODE_INPUT_WIDTH, maxY + 60, - true); + view.viewGraphRegion(minX - NODE_INPUT_WIDTH, minY - 60, + maxX + NODE_INPUT_WIDTH, maxY + 60); } } - viewGraphRegion(minX, minY, maxX, maxY, transition) { + viewGraphRegion(minX, minY, maxX, maxY) { const [width, height] = this.getSvgViewDimensions(); const dx = maxX - minX; const dy = maxY - minY; const x = (minX + maxX) / 2; const y = (minY + maxY) / 2; const scale = Math.min(width / (1.1 * dx), height / (1.1 * dy)); - const transform = d3.zoomIdentity.translate(1500, 100).scale(0.75); this.svg .transition().duration(300).call(this.panZoom.translateTo, x, y) .transition().duration(300).call(this.panZoom.scaleTo, scale) @@ -947,6 +911,8 @@ export class GraphView extends View implements PhaseView { viewWholeGraph() { this.panZoom.scaleTo(this.svg, 0); - this.panZoom.translateTo(this.svg, this.minGraphX + this.width / 2, this.minGraphY + this.height / 2) + this.panZoom.translateTo(this.svg, + this.graph.minGraphX + this.graph.width / 2, + this.graph.minGraphY + this.graph.height / 2); } } diff --git a/deps/v8/tools/turbolizer/src/graph.ts b/deps/v8/tools/turbolizer/src/graph.ts new file mode 100644 index 0000000000..0eb2e3e1e6 --- /dev/null +++ b/deps/v8/tools/turbolizer/src/graph.ts @@ -0,0 +1,107 @@ +import { GNode } from "./node"; +import { Edge, MINIMUM_EDGE_SEPARATION } from "./edge"; + +export class Graph { + nodeMap: Array<GNode>; + minGraphX: number; + maxGraphX: number; + minGraphY: number; + maxGraphY: number; + maxGraphNodeX: number; + maxBackEdgeNumber: number; + width: number; + height: number; + + constructor(data: any) { + this.nodeMap = []; + + this.minGraphX = 0; + this.maxGraphX = 1; + this.minGraphY = 0; + this.maxGraphY = 1; + this.width = 1; + this.height = 1; + + data.nodes.forEach((jsonNode: any) => { + this.nodeMap[jsonNode.id] = new GNode(jsonNode.nodeLabel); + }); + + data.edges.forEach((e: any) => { + const t = this.nodeMap[e.target]; + const s = this.nodeMap[e.source]; + const newEdge = new Edge(t, e.index, s, e.type); + t.inputs.push(newEdge); + s.outputs.push(newEdge); + if (e.type == 'control') { + // Every source of a control edge is a CFG node. + s.cfg = true; + } + }); + + } + + *nodes(p = (n: GNode) => true) { + for (const node of this.nodeMap) { + if (!node || !p(node)) continue; + yield node; + } + } + + *filteredEdges(p: (e: Edge) => boolean) { + for (const node of this.nodes()) { + for (const edge of node.inputs) { + if (p(edge)) yield edge; + } + } + } + + forEachEdge(p: (e: Edge) => void) { + for (const node of this.nodeMap) { + if (!node) continue; + for (const edge of node.inputs) { + p(edge); + } + } + } + + redetermineGraphBoundingBox(showTypes: boolean): [[number, number], [number, number]] { + this.minGraphX = 0; + this.maxGraphNodeX = 1; + this.maxGraphX = undefined; // see below + this.minGraphY = 0; + this.maxGraphY = 1; + + for (const node of this.nodes()) { + if (!node.visible) { + continue; + } + + if (node.x < this.minGraphX) { + this.minGraphX = node.x; + } + if ((node.x + node.getTotalNodeWidth()) > this.maxGraphNodeX) { + this.maxGraphNodeX = node.x + node.getTotalNodeWidth(); + } + if ((node.y - 50) < this.minGraphY) { + this.minGraphY = node.y - 50; + } + if ((node.y + node.getNodeHeight(showTypes) + 50) > this.maxGraphY) { + this.maxGraphY = node.y + node.getNodeHeight(showTypes) + 50; + } + } + + this.maxGraphX = this.maxGraphNodeX + + this.maxBackEdgeNumber * MINIMUM_EDGE_SEPARATION; + + this.width = this.maxGraphX - this.minGraphX; + this.height = this.maxGraphY - this.minGraphY; + + const extent: [[number, number], [number, number]] = [ + [this.minGraphX - this.width / 2, this.minGraphY - this.height / 2], + [this.maxGraphX + this.width / 2, this.maxGraphY + this.height / 2] + ]; + + return extent; + } + +} diff --git a/deps/v8/tools/turbolizer/src/graphmultiview.ts b/deps/v8/tools/turbolizer/src/graphmultiview.ts index f9e7efb58c..43ec418ee0 100644 --- a/deps/v8/tools/turbolizer/src/graphmultiview.ts +++ b/deps/v8/tools/turbolizer/src/graphmultiview.ts @@ -2,12 +2,24 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import {GraphView} from "./graph-view.js" -import {ScheduleView} from "./schedule-view.js" -import {SequenceView} from "./sequence-view.js" -import {SourceResolver} from "./source-resolver.js" -import {SelectionBroker} from "./selection-broker.js" -import {View, PhaseView} from "./view.js" +import { GraphView } from "../src/graph-view"; +import { ScheduleView } from "../src/schedule-view"; +import { SequenceView } from "../src/sequence-view"; +import { SourceResolver } from "../src/source-resolver"; +import { SelectionBroker } from "../src/selection-broker"; +import { View, PhaseView } from "../src/view"; + +const multiviewID = "multiview"; + +const toolboxHTML = ` +<div class="graph-toolbox"> + <select id="phase-select"> + <option disabled selected>(please open a file)</option> + </select> + <input id="search-input" type="text" title="search nodes for regex" alt="search node for regex" class="search-input" + placeholder="find with regexp…"> + <label><input id="search-only-visible" type="checkbox" name="instruction-address" alt="Apply search to visible nodes only">only visible</label> +</div>`; export class GraphMultiView extends View { sourceResolver: SourceResolver; @@ -16,11 +28,12 @@ export class GraphMultiView extends View { schedule: ScheduleView; sequence: SequenceView; selectMenu: HTMLSelectElement; - currentPhaseView: View & PhaseView; + currentPhaseView: PhaseView; createViewElement() { - const pane = document.createElement('div'); - pane.setAttribute('id', "multiview"); + const pane = document.createElement("div"); + pane.setAttribute("id", multiviewID); + pane.className = "viewpane"; return pane; } @@ -29,35 +42,50 @@ export class GraphMultiView extends View { const view = this; view.sourceResolver = sourceResolver; view.selectionBroker = selectionBroker; - const searchInput = document.getElementById("search-input") as HTMLInputElement; + const toolbox = document.createElement("div"); + toolbox.className = "toolbox-anchor"; + toolbox.innerHTML = toolboxHTML; + view.divNode.appendChild(toolbox); + const searchInput = toolbox.querySelector("#search-input") as HTMLInputElement; + const onlyVisibleCheckbox = toolbox.querySelector("#search-only-visible") as HTMLInputElement; searchInput.addEventListener("keyup", e => { if (!view.currentPhaseView) return; - view.currentPhaseView.searchInputAction(searchInput, e) + view.currentPhaseView.searchInputAction(searchInput, e, onlyVisibleCheckbox.checked); + }); + view.divNode.addEventListener("keyup", (e: KeyboardEvent) => { + if (e.keyCode == 191) { // keyCode == '/' + searchInput.focus(); + } }); searchInput.setAttribute("value", window.sessionStorage.getItem("lastSearch") || ""); - this.graph = new GraphView(id, selectionBroker, - (phaseName) => view.displayPhaseByName(phaseName)); - this.schedule = new ScheduleView(id, selectionBroker); - this.sequence = new SequenceView(id, selectionBroker); - this.selectMenu = (<HTMLSelectElement>document.getElementById('display-selector')); + this.graph = new GraphView(this.divNode, selectionBroker, view.displayPhaseByName.bind(this), + toolbox.querySelector(".graph-toolbox")); + this.schedule = new ScheduleView(this.divNode, selectionBroker); + this.sequence = new SequenceView(this.divNode, selectionBroker); + this.selectMenu = toolbox.querySelector("#phase-select") as HTMLSelectElement; } initializeSelect() { const view = this; - view.selectMenu.innerHTML = ''; - view.sourceResolver.forEachPhase((phase) => { + view.selectMenu.innerHTML = ""; + view.sourceResolver.forEachPhase(phase => { const optionElement = document.createElement("option"); - optionElement.text = phase.name; + let maxNodeId = ""; + if (phase.type == "graph" && phase.highestNodeId != 0) { + maxNodeId = ` ${phase.highestNodeId}`; + } + optionElement.text = `${phase.name}${maxNodeId}`; view.selectMenu.add(optionElement); }); this.selectMenu.onchange = function (this: HTMLSelectElement) { - window.sessionStorage.setItem("lastSelectedPhase", this.selectedIndex.toString()); - view.displayPhase(view.sourceResolver.getPhase(this.selectedIndex)); - } + const phaseIndex = this.selectedIndex; + window.sessionStorage.setItem("lastSelectedPhase", phaseIndex.toString()); + view.displayPhase(view.sourceResolver.getPhase(phaseIndex)); + }; } - show(data, rememberedSelection) { - super.show(data, rememberedSelection); + show() { + super.show(); this.initializeSelect(); const lastPhaseIndex = +window.sessionStorage.getItem("lastSelectedPhase"); const initialPhaseIndex = this.sourceResolver.repairPhaseId(lastPhaseIndex); @@ -65,29 +93,27 @@ export class GraphMultiView extends View { this.displayPhase(this.sourceResolver.getPhase(initialPhaseIndex)); } - initializeContent() { } - - displayPhase(phase) { - if (phase.type == 'graph') { - this.displayPhaseView(this.graph, phase.data); - } else if (phase.type == 'schedule') { - this.displayPhaseView(this.schedule, phase); - } else if (phase.type == 'sequence') { - this.displayPhaseView(this.sequence, phase); + displayPhase(phase, selection?: Set<any>) { + if (phase.type == "graph") { + this.displayPhaseView(this.graph, phase, selection); + } else if (phase.type == "schedule") { + this.displayPhaseView(this.schedule, phase, selection); + } else if (phase.type == "sequence") { + this.displayPhaseView(this.sequence, phase, selection); } } - displayPhaseView(view, data) { - const rememberedSelection = this.hideCurrentPhase(); - view.show(data, rememberedSelection); - document.getElementById("middle").classList.toggle("scrollable", view.isScrollable()); + displayPhaseView(view: PhaseView, data, selection?: Set<any>) { + const rememberedSelection = selection ? selection : this.hideCurrentPhase(); + view.initializeContent(data, rememberedSelection); + this.divNode.classList.toggle("scrollable", view.isScrollable()); this.currentPhaseView = view; } - displayPhaseByName(phaseName) { + displayPhaseByName(phaseName, selection?: Set<any>) { const phaseId = this.sourceResolver.getPhaseIdByName(phaseName); - this.selectMenu.selectedIndex = phaseId - 1; - this.displayPhase(this.sourceResolver.getPhase(phaseId)); + this.selectMenu.selectedIndex = phaseId; + this.displayPhase(this.sourceResolver.getPhase(phaseId), selection); } hideCurrentPhase() { @@ -104,10 +130,6 @@ export class GraphMultiView extends View { if (this.currentPhaseView) this.currentPhaseView.onresize(); } - deleteContent() { - this.hideCurrentPhase(); - } - detachSelection() { return null; } diff --git a/deps/v8/tools/turbolizer/src/info-view.ts b/deps/v8/tools/turbolizer/src/info-view.ts new file mode 100644 index 0000000000..38585365ff --- /dev/null +++ b/deps/v8/tools/turbolizer/src/info-view.ts @@ -0,0 +1,17 @@ +import { View } from "./view"; + +export class InfoView extends View { + + constructor(idOrContainer: HTMLElement | string) { + super(idOrContainer); + fetch("info-view.html") + .then(response => response.text()) + .then(htmlText => this.divNode.innerHTML = htmlText); + } + + createViewElement(): HTMLElement { + const infoContainer = document.createElement("div"); + infoContainer.classList.add("info-container"); + return infoContainer; + } +} diff --git a/deps/v8/tools/turbolizer/src/lang-disassembly.ts b/deps/v8/tools/turbolizer/src/lang-disassembly.ts deleted file mode 100644 index 9312627abd..0000000000 --- a/deps/v8/tools/turbolizer/src/lang-disassembly.ts +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright 2015 the V8 project authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -PR.registerLangHandler( - PR.createSimpleLexer( - [ - [PR.PR_STRING, /^(?:\'(?:[^\\\'\r\n]|\\.)*(?:\'|$))/, null, '\''], - [PR.PR_PLAIN, /^\s+/, null, ' \r\n\t\xA0'] - ], - [ // fallthroughStylePatterns - [PR.PR_COMMENT, /;; debug: position \d+/, null], - ]), - ['disassembly']); diff --git a/deps/v8/tools/turbolizer/src/node-label.ts b/deps/v8/tools/turbolizer/src/node-label.ts new file mode 100644 index 0000000000..6e7d41d899 --- /dev/null +++ b/deps/v8/tools/turbolizer/src/node-label.ts @@ -0,0 +1,86 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +function formatOrigin(origin) { + if (origin.nodeId) { + return `#${origin.nodeId} in phase ${origin.phase}/${origin.reducer}`; + } + if (origin.bytecodePosition) { + return `Bytecode line ${origin.bytecodePosition} in phase ${origin.phase}/${origin.reducer}`; + } + return "unknown origin"; +} + +export class NodeLabel { + id: number; + label: string; + title: string; + live: boolean; + properties: string; + sourcePosition: any; + origin: any; + opcode: string; + control: boolean; + opinfo: string; + type: string; + inplaceUpdatePhase: string; + + constructor(id: number, label: string, title: string, live: boolean, properties: string, sourcePosition: any, origin: any, opcode: string, control: boolean, opinfo: string, type: string) { + this.id = id; + this.label = label; + this.title = title; + this.live = live; + this.properties = properties; + this.sourcePosition = sourcePosition; + this.origin = origin; + this.opcode = opcode; + this.control = control; + this.opinfo = opinfo; + this.type = type; + this.inplaceUpdatePhase = null; + } + + equals(that?: NodeLabel) { + if (!that) return false; + if (this.id != that.id) return false; + if (this.label != that.label) return false; + if (this.title != that.title) return false; + if (this.live != that.live) return false; + if (this.properties != that.properties) return false; + if (this.opcode != that.opcode) return false; + if (this.control != that.control) return false; + if (this.opinfo != that.opinfo) return false; + if (this.type != that.type) return false; + return true; + } + + getTitle() { + let propsString = ""; + if (this.properties === "") { + propsString = "no properties"; + } else { + propsString = "[" + this.properties + "]"; + } + let title = this.title + "\n" + propsString + "\n" + this.opinfo; + if (this.origin) { + title += `\nOrigin: ${formatOrigin(this.origin)}`; + } + if (this.inplaceUpdatePhase) { + title += `\nInplace update in phase: ${this.inplaceUpdatePhase}`; + } + return title; + } + + getDisplayLabel() { + const result = `${this.id}: ${this.label}`; + if (result.length > 40) { + return `${this.id}: ${this.opcode}`; + } + return result; + } + + setInplaceUpdatePhase(name: string): any { + this.inplaceUpdatePhase = name; + } +} diff --git a/deps/v8/tools/turbolizer/src/node.ts b/deps/v8/tools/turbolizer/src/node.ts index 95c47cab20..02906d1204 100644 --- a/deps/v8/tools/turbolizer/src/node.ts +++ b/deps/v8/tools/turbolizer/src/node.ts @@ -2,120 +2,111 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import {NodeOrigin} from "./source-resolver.js" -import {MINIMUM_EDGE_SEPARATION} from "./edge.js" +import { MINIMUM_EDGE_SEPARATION, Edge } from "../src/edge"; +import { NodeLabel } from "./node-label"; +import { MAX_RANK_SENTINEL } from "./constants"; +import { alignUp, measureText } from "./util"; export const DEFAULT_NODE_BUBBLE_RADIUS = 12; export const NODE_INPUT_WIDTH = 50; export const MINIMUM_NODE_OUTPUT_APPROACH = 15; const MINIMUM_NODE_INPUT_APPROACH = 15 + 2 * DEFAULT_NODE_BUBBLE_RADIUS; -export function isNodeInitiallyVisible(node) { - return node.cfg; -} - -function formatOrigin(origin) { - if (origin.nodeId) { - return `#${origin.nodeId} in phase ${origin.phase}/${origin.reducer}`; - } - if (origin.bytecodePosition) { - return `Bytecode line ${origin.bytecodePosition} in phase ${origin.phase}/${origin.reducer}`; - } - return "unknown origin"; -} - export class GNode { - control: boolean; - opcode: string; - live: boolean; - inputs: Array<any>; - width: number; - properties: string; - title: string; - label: string; - origin: NodeOrigin; - outputs: Array<any>; - outputApproach: number; - type: string; id: number; + nodeLabel: NodeLabel; + displayLabel: string; + inputs: Array<Edge>; + outputs: Array<Edge>; + visible: boolean; x: number; y: number; - visible: boolean; rank: number; - opinfo: string; + outputApproach: number; + cfg: boolean; labelbbox: { width: number, height: number }; + width: number; + normalheight: number; + visitOrderWithinRank: number; + + constructor(nodeLabel: NodeLabel) { + this.id = nodeLabel.id; + this.nodeLabel = nodeLabel; + this.displayLabel = nodeLabel.getDisplayLabel(); + this.inputs = []; + this.outputs = []; + this.visible = false; + this.x = 0; + this.y = 0; + this.rank = MAX_RANK_SENTINEL; + this.outputApproach = MINIMUM_NODE_OUTPUT_APPROACH; + // Every control node is a CFG node. + this.cfg = nodeLabel.control; + this.labelbbox = measureText(this.displayLabel); + const typebbox = measureText(this.getDisplayType()); + const innerwidth = Math.max(this.labelbbox.width, typebbox.width); + this.width = alignUp(innerwidth + NODE_INPUT_WIDTH * 2, + NODE_INPUT_WIDTH); + const innerheight = Math.max(this.labelbbox.height, typebbox.height); + this.normalheight = innerheight + 20; + this.visitOrderWithinRank = 0; + } isControl() { - return this.control; + return this.nodeLabel.control; } isInput() { - return this.opcode == 'Parameter' || this.opcode.endsWith('Constant'); + return this.nodeLabel.opcode == 'Parameter' || this.nodeLabel.opcode.endsWith('Constant'); } isLive() { - return this.live !== false; + return this.nodeLabel.live !== false; } isJavaScript() { - return this.opcode.startsWith('JS'); + return this.nodeLabel.opcode.startsWith('JS'); } isSimplified() { if (this.isJavaScript()) return false; - return this.opcode.endsWith('Phi') || - this.opcode.startsWith('Boolean') || - this.opcode.startsWith('Number') || - this.opcode.startsWith('String') || - this.opcode.startsWith('Change') || - this.opcode.startsWith('Object') || - this.opcode.startsWith('Reference') || - this.opcode.startsWith('Any') || - this.opcode.endsWith('ToNumber') || - (this.opcode == 'AnyToBoolean') || - (this.opcode.startsWith('Load') && this.opcode.length > 4) || - (this.opcode.startsWith('Store') && this.opcode.length > 5); + const opcode = this.nodeLabel.opcode; + return opcode.endsWith('Phi') || + opcode.startsWith('Boolean') || + opcode.startsWith('Number') || + opcode.startsWith('String') || + opcode.startsWith('Change') || + opcode.startsWith('Object') || + opcode.startsWith('Reference') || + opcode.startsWith('Any') || + opcode.endsWith('ToNumber') || + (opcode == 'AnyToBoolean') || + (opcode.startsWith('Load') && opcode.length > 4) || + (opcode.startsWith('Store') && opcode.length > 5); } isMachine() { return !(this.isControl() || this.isInput() || this.isJavaScript() || this.isSimplified()); } getTotalNodeWidth() { - var inputWidth = this.inputs.length * NODE_INPUT_WIDTH; + const inputWidth = this.inputs.length * NODE_INPUT_WIDTH; return Math.max(inputWidth, this.width); } getTitle() { - var propsString; - if (this.properties === undefined) { - propsString = ""; - } else if (this.properties === "") { - propsString = "no properties"; - } else { - propsString = "[" + this.properties + "]"; - } - let title = this.title + "\n" + propsString + "\n" + this.opinfo; - if (this.origin) { - title += `\nOrigin: ${formatOrigin(this.origin)}`; - } - return title; + return this.nodeLabel.getTitle(); } getDisplayLabel() { - var result = this.id + ":" + this.label; - if (result.length > 40) { - return this.id + ":" + this.opcode; - } else { - return result; - } + return this.nodeLabel.getDisplayLabel(); } getType() { - return this.type; + return this.nodeLabel.type; } getDisplayType() { - var type_string = this.type; - if (type_string == undefined) return ""; - if (type_string.length > 24) { - type_string = type_string.substr(0, 25) + "..."; + let typeString = this.nodeLabel.type; + if (typeString == undefined) return ""; + if (typeString.length > 24) { + typeString = typeString.substr(0, 25) + "..."; } - return type_string; + return typeString; } deepestInputRank() { - var deepestRank = 0; + let deepestRank = 0; this.inputs.forEach(function (e) { if (e.isVisible() && !e.isBackEdge()) { if (e.source.rank > deepestRank) { @@ -126,14 +117,14 @@ export class GNode { return deepestRank; } areAnyOutputsVisible() { - var visibleCount = 0; + let visibleCount = 0; this.outputs.forEach(function (e) { if (e.isVisible())++visibleCount; }); if (this.outputs.length == visibleCount) return 2; if (visibleCount != 0) return 1; return 0; } setOutputVisibility(v) { - var result = false; + let result = false; this.outputs.forEach(function (e) { e.visible = v; if (v) { @@ -146,7 +137,7 @@ export class GNode { return result; } setInputVisibility(i, v) { - var edge = this.inputs[i]; + const edge = this.inputs[i]; edge.visible = v; if (v) { if (!edge.source.visible) { @@ -158,14 +149,21 @@ export class GNode { } getInputApproach(index) { return this.y - MINIMUM_NODE_INPUT_APPROACH - - (index % 4) * MINIMUM_EDGE_SEPARATION - DEFAULT_NODE_BUBBLE_RADIUS + (index % 4) * MINIMUM_EDGE_SEPARATION - DEFAULT_NODE_BUBBLE_RADIUS; } - getOutputApproach(graph) { - return this.y + this.outputApproach + graph.getNodeHeight(this) + + getNodeHeight(showTypes: boolean): number { + if (showTypes) { + return this.normalheight + this.labelbbox.height; + } else { + return this.normalheight; + } + } + getOutputApproach(showTypes: boolean) { + return this.y + this.outputApproach + this.getNodeHeight(showTypes) + + DEFAULT_NODE_BUBBLE_RADIUS; } getInputX(index) { - var result = this.getTotalNodeWidth() - (NODE_INPUT_WIDTH / 2) + + const result = this.getTotalNodeWidth() - (NODE_INPUT_WIDTH / 2) + (index - this.inputs.length + 1) * NODE_INPUT_WIDTH; return result; } @@ -173,10 +171,10 @@ export class GNode { return this.getTotalNodeWidth() - (NODE_INPUT_WIDTH / 2); } hasBackEdges() { - return (this.opcode == "Loop") || - ((this.opcode == "Phi" || this.opcode == "EffectPhi") && - this.inputs[this.inputs.length - 1].source.opcode == "Loop"); + return (this.nodeLabel.opcode == "Loop") || + ((this.nodeLabel.opcode == "Phi" || this.nodeLabel.opcode == "EffectPhi" || this.nodeLabel.opcode == "InductionVariablePhi") && + this.inputs[this.inputs.length - 1].source.nodeLabel.opcode == "Loop"); } -}; +} export const nodeToStr = (n: GNode) => "N" + n.id; diff --git a/deps/v8/tools/turbolizer/src/resizer.ts b/deps/v8/tools/turbolizer/src/resizer.ts new file mode 100644 index 0000000000..ec2d68c0e2 --- /dev/null +++ b/deps/v8/tools/turbolizer/src/resizer.ts @@ -0,0 +1,199 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import * as d3 from "d3"; +import * as C from "../src/constants"; + +class Snapper { + resizer: Resizer; + sourceExpand: HTMLElement; + sourceCollapse: HTMLElement; + disassemblyExpand: HTMLElement; + disassemblyCollapse: HTMLElement; + + constructor(resizer: Resizer) { + this.resizer = resizer; + this.sourceExpand = document.getElementById(C.SOURCE_EXPAND_ID); + this.sourceCollapse = document.getElementById(C.SOURCE_COLLAPSE_ID); + this.disassemblyExpand = document.getElementById(C.DISASSEMBLY_EXPAND_ID); + this.disassemblyCollapse = document.getElementById(C.DISASSEMBLY_COLLAPSE_ID); + + document.getElementById("source-collapse").addEventListener("click", () => { + this.setSourceExpanded(!this.sourceExpand.classList.contains("invisible")); + this.resizer.updatePanes(); + }); + document.getElementById("disassembly-collapse").addEventListener("click", () => { + this.setDisassemblyExpanded(!this.disassemblyExpand.classList.contains("invisible")); + this.resizer.updatePanes(); + }); + } + + restoreExpandedState(): void { + this.setSourceExpanded(this.getLastExpandedState("source", true)); + this.setDisassemblyExpanded(this.getLastExpandedState("disassembly", false)); + } + + getLastExpandedState(type: string, defaultState: boolean): boolean { + const state = window.sessionStorage.getItem("expandedState-" + type); + if (state === null) return defaultState; + return state === 'true'; + } + + sourceExpandUpdate(newState: boolean): void { + window.sessionStorage.setItem("expandedState-source", `${newState}`); + this.sourceExpand.classList.toggle("invisible", newState); + this.sourceCollapse.classList.toggle("invisible", !newState); + } + + setSourceExpanded(newState: boolean): void { + if (this.sourceExpand.classList.contains("invisible") === newState) return; + const resizer = this.resizer; + this.sourceExpandUpdate(newState); + if (newState) { + resizer.sepLeft = resizer.sepLeftSnap; + resizer.sepLeftSnap = 0; + } else { + resizer.sepLeftSnap = resizer.sepLeft; + resizer.sepLeft = 0; + } + } + + disassemblyExpandUpdate(newState: boolean): void { + window.sessionStorage.setItem("expandedState-disassembly", `${newState}`); + this.disassemblyExpand.classList.toggle("invisible", newState); + this.disassemblyCollapse.classList.toggle("invisible", !newState); + } + + setDisassemblyExpanded(newState: boolean): void { + if (this.disassemblyExpand.classList.contains("invisible") === newState) return; + const resizer = this.resizer; + this.disassemblyExpandUpdate(newState); + if (newState) { + resizer.sepRight = resizer.sepRightSnap; + resizer.sepRightSnap = resizer.clientWidth; + } else { + resizer.sepRightSnap = resizer.sepRight; + resizer.sepRight = resizer.clientWidth; + } + } + + panesUpdated(): void { + this.sourceExpandUpdate(this.resizer.sepLeft > this.resizer.deadWidth); + this.disassemblyExpandUpdate(this.resizer.sepRight < + (this.resizer.clientWidth - this.resizer.deadWidth)); + } +} + +export class Resizer { + snapper: Snapper; + deadWidth: number; + clientWidth: number; + left: HTMLElement; + right: HTMLElement; + middle: HTMLElement; + sepLeft: number; + sepRight: number; + sepLeftSnap: number; + sepRightSnap: number; + sepWidthOffset: number; + panesUpdatedCallback: () => void; + resizerRight: d3.Selection<HTMLDivElement, any, any, any>; + resizerLeft: d3.Selection<HTMLDivElement, any, any, any>; + + constructor(panesUpdatedCallback: () => void, deadWidth: number) { + const resizer = this; + resizer.panesUpdatedCallback = panesUpdatedCallback; + resizer.deadWidth = deadWidth; + resizer.left = document.getElementById(C.SOURCE_PANE_ID); + resizer.middle = document.getElementById(C.INTERMEDIATE_PANE_ID); + resizer.right = document.getElementById(C.GENERATED_PANE_ID); + resizer.resizerLeft = d3.select('#resizer-left'); + resizer.resizerRight = d3.select('#resizer-right'); + resizer.sepLeftSnap = 0; + resizer.sepRightSnap = 0; + // Offset to prevent resizers from sliding slightly over one another. + resizer.sepWidthOffset = 7; + this.updateWidths(); + + const dragResizeLeft = d3.drag() + .on('drag', function () { + const x = d3.mouse(this.parentElement)[0]; + resizer.sepLeft = Math.min(Math.max(0, x), resizer.sepRight - resizer.sepWidthOffset); + resizer.updatePanes(); + }) + .on('start', function () { + resizer.resizerLeft.classed("dragged", true); + const x = d3.mouse(this.parentElement)[0]; + if (x > deadWidth) { + resizer.sepLeftSnap = resizer.sepLeft; + } + }) + .on('end', function () { + if (!resizer.isRightSnapped()) { + window.sessionStorage.setItem("source-pane-width", `${resizer.sepLeft / resizer.clientWidth}`); + } + resizer.resizerLeft.classed("dragged", false); + }); + resizer.resizerLeft.call(dragResizeLeft); + + const dragResizeRight = d3.drag() + .on('drag', function () { + const x = d3.mouse(this.parentElement)[0]; + resizer.sepRight = Math.max(resizer.sepLeft + resizer.sepWidthOffset, Math.min(x, resizer.clientWidth)); + resizer.updatePanes(); + }) + .on('start', function () { + resizer.resizerRight.classed("dragged", true); + const x = d3.mouse(this.parentElement)[0]; + if (x < (resizer.clientWidth - deadWidth)) { + resizer.sepRightSnap = resizer.sepRight; + } + }) + .on('end', function () { + if (!resizer.isRightSnapped()) { + console.log(`disassembly-pane-width ${resizer.sepRight}`); + window.sessionStorage.setItem("disassembly-pane-width", `${resizer.sepRight / resizer.clientWidth}`); + } + resizer.resizerRight.classed("dragged", false); + }); + resizer.resizerRight.call(dragResizeRight); + window.onresize = function () { + resizer.updateWidths(); + resizer.updatePanes(); + }; + resizer.snapper = new Snapper(resizer); + resizer.snapper.restoreExpandedState(); + } + + isLeftSnapped() { + return this.sepLeft === 0; + } + + isRightSnapped() { + return this.sepRight >= this.clientWidth - 1; + } + + updatePanes() { + const leftSnapped = this.isLeftSnapped(); + const rightSnapped = this.isRightSnapped(); + this.resizerLeft.classed("snapped", leftSnapped); + this.resizerRight.classed("snapped", rightSnapped); + this.left.style.width = this.sepLeft + 'px'; + this.middle.style.width = (this.sepRight - this.sepLeft) + 'px'; + this.right.style.width = (this.clientWidth - this.sepRight) + 'px'; + this.resizerLeft.style('left', this.sepLeft + 'px'); + this.resizerRight.style('right', (this.clientWidth - this.sepRight - 1) + 'px'); + + this.snapper.panesUpdated(); + this.panesUpdatedCallback(); + } + + updateWidths() { + this.clientWidth = document.body.getBoundingClientRect().width; + const sepLeft = window.sessionStorage.getItem("source-pane-width"); + this.sepLeft = this.clientWidth * (sepLeft ? Number.parseFloat(sepLeft) : (1 / 3)); + const sepRight = window.sessionStorage.getItem("disassembly-pane-width"); + this.sepRight = this.clientWidth * (sepRight ? Number.parseFloat(sepRight) : (2 / 3)); + } +} diff --git a/deps/v8/tools/turbolizer/src/schedule-view.ts b/deps/v8/tools/turbolizer/src/schedule-view.ts index f62aba0c86..ed36d126fd 100644 --- a/deps/v8/tools/turbolizer/src/schedule-view.ts +++ b/deps/v8/tools/turbolizer/src/schedule-view.ts @@ -2,12 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import {Schedule,SourceResolver} from "./source-resolver.js" -import {isIterable} from "./util.js" -import {PhaseView} from "./view.js" -import {TextView} from "./text-view.js" +import { Schedule, SourceResolver } from "../src/source-resolver"; +import { TextView } from "../src/text-view"; -export class ScheduleView extends TextView implements PhaseView { +export class ScheduleView extends TextView { schedule: Schedule; sourceResolver: SourceResolver; @@ -18,7 +16,7 @@ export class ScheduleView extends TextView implements PhaseView { } constructor(parentId, broker) { - super(parentId, broker, null); + super(parentId, broker); this.sourceResolver = broker.sourceResolver; } @@ -39,26 +37,23 @@ export class ScheduleView extends TextView implements PhaseView { initializeContent(data, rememberedSelection) { this.divNode.innerHTML = ''; - this.schedule = data.schedule + this.schedule = data.schedule; this.addBlocks(data.schedule.blocks); this.attachSelection(rememberedSelection); + this.show(); } createElementFromString(htmlString) { - var div = document.createElement('div'); + const div = document.createElement('div'); div.innerHTML = htmlString.trim(); return div.firstChild; } elementForBlock(block) { const view = this; - function createElement(tag: string, cls: string | Array<string>, content?: string) { + function createElement(tag: string, cls: string, content?: string) { const el = document.createElement(tag); - if (isIterable(cls)) { - for (const c of cls) el.classList.add(c); - } else { - el.classList.add(cls); - } + el.className = cls; if (content != undefined) el.innerHTML = content; return el; } @@ -76,15 +71,15 @@ export class ScheduleView extends TextView implements PhaseView { function getMarker(start, end) { if (start != end) { return ["⊙", `This node generated instructions in range [${start},${end}). ` + - `This is currently unreliable for constants.`]; + `This is currently unreliable for constants.`]; } if (start != -1) { return ["·", `The instruction selector did not generate instructions ` + - `for this node, but processed the node at instruction ${start}. ` + - `This usually means that this node was folded into another node; ` + - `the highlighted machine code is a guess.`]; + `for this node, but processed the node at instruction ${start}. ` + + `This usually means that this node was folded into another node; ` + + `the highlighted machine code is a guess.`]; } - return ["", `This not is not in the final schedule.`] + return ["", `This not is not in the final schedule.`]; } function createElementForNode(node) { @@ -92,27 +87,26 @@ export class ScheduleView extends TextView implements PhaseView { const [start, end] = view.sourceResolver.getInstruction(node.id); const [marker, tooltip] = getMarker(start, end); - const instrMarker = createElement("div", ["instr-marker", "com"], marker); + const instrMarker = createElement("div", "instr-marker com", marker); instrMarker.setAttribute("title", tooltip); instrMarker.onclick = mkNodeLinkHandler(node.id); nodeEl.appendChild(instrMarker); - - const node_id = createElement("div", ["node-id", "tag", "clickable"], node.id); - node_id.onclick = mkNodeLinkHandler(node.id); - view.addHtmlElementForNodeId(node.id, node_id); - nodeEl.appendChild(node_id); - const node_label = createElement("div", "node-label", node.label); - nodeEl.appendChild(node_label); + const nodeId = createElement("div", "node-id tag clickable", node.id); + nodeId.onclick = mkNodeLinkHandler(node.id); + view.addHtmlElementForNodeId(node.id, nodeId); + nodeEl.appendChild(nodeId); + const nodeLabel = createElement("div", "node-label", node.label); + nodeEl.appendChild(nodeLabel); if (node.inputs.length > 0) { - const node_parameters = createElement("div", ["parameter-list", "comma-sep-list"]); + const nodeParameters = createElement("div", "parameter-list comma-sep-list"); for (const param of node.inputs) { - const paramEl = createElement("div", ["parameter", "tag", "clickable"], param); - node_parameters.appendChild(paramEl); + const paramEl = createElement("div", "parameter tag clickable", param); + nodeParameters.appendChild(paramEl); paramEl.onclick = mkNodeLinkHandler(param); view.addHtmlElementForNodeId(param, paramEl); } - nodeEl.appendChild(node_parameters); + nodeEl.appendChild(nodeParameters); } return nodeEl; @@ -128,38 +122,38 @@ export class ScheduleView extends TextView implements PhaseView { }; } - const schedule_block = createElement("div", "schedule-block"); + const scheduleBlock = createElement("div", "schedule-block"); const [start, end] = view.sourceResolver.getInstructionRangeForBlock(block.id); - const instrMarker = createElement("div", ["instr-marker", "com"], "⊙"); - instrMarker.setAttribute("title", `Instructions range for this block is [${start}, ${end})`) + const instrMarker = createElement("div", "instr-marker com", "⊙"); + instrMarker.setAttribute("title", `Instructions range for this block is [${start}, ${end})`); instrMarker.onclick = mkBlockLinkHandler(block.id); - schedule_block.appendChild(instrMarker); + scheduleBlock.appendChild(instrMarker); - const block_id = createElement("div", ["block-id", "com", "clickable"], block.id); - block_id.onclick = mkBlockLinkHandler(block.id); - schedule_block.appendChild(block_id); - const block_pred = createElement("div", ["predecessor-list", "block-list", "comma-sep-list"]); + const blockId = createElement("div", "block-id com clickable", block.id); + blockId.onclick = mkBlockLinkHandler(block.id); + scheduleBlock.appendChild(blockId); + const blockPred = createElement("div", "predecessor-list block-list comma-sep-list"); for (const pred of block.pred) { - const predEl = createElement("div", ["block-id", "com", "clickable"], pred); + const predEl = createElement("div", "block-id com clickable", pred); predEl.onclick = mkBlockLinkHandler(pred); - block_pred.appendChild(predEl); + blockPred.appendChild(predEl); } - if (block.pred.length) schedule_block.appendChild(block_pred); + if (block.pred.length) scheduleBlock.appendChild(blockPred); const nodes = createElement("div", "nodes"); for (const node of block.nodes) { nodes.appendChild(createElementForNode(node)); } - schedule_block.appendChild(nodes); - const block_succ = createElement("div", ["successor-list", "block-list", "comma-sep-list"]); + scheduleBlock.appendChild(nodes); + const blockSucc = createElement("div", "successor-list block-list comma-sep-list"); for (const succ of block.succ) { - const succEl = createElement("div", ["block-id", "com", "clickable"], succ); + const succEl = createElement("div", "block-id com clickable", succ); succEl.onclick = mkBlockLinkHandler(succ); - block_succ.appendChild(succEl); + blockSucc.appendChild(succEl); } - if (block.succ.length) schedule_block.appendChild(block_succ); - this.addHtmlElementForBlockId(block.id, schedule_block); - return schedule_block; + if (block.succ.length) scheduleBlock.appendChild(blockSucc); + this.addHtmlElementForBlockId(block.id, scheduleBlock); + return scheduleBlock; } addBlocks(blocks) { @@ -170,10 +164,10 @@ export class ScheduleView extends TextView implements PhaseView { } lineString(node) { - return `${node.id}: ${node.label}(${node.inputs.join(", ")})` + return `${node.id}: ${node.label}(${node.inputs.join(", ")})`; } - searchInputAction(searchBar, e) { + searchInputAction(searchBar, e, onlyVisible) { e.stopPropagation(); this.selectionHandler.clear(); const query = searchBar.value; @@ -184,11 +178,9 @@ export class ScheduleView extends TextView implements PhaseView { for (const node of this.schedule.nodes) { if (node === undefined) continue; if (reg.exec(this.lineString(node)) != null) { - select.push(node.id) + select.push(node.id); } } this.selectionHandler.select(select, true); } - - onresize() { } } diff --git a/deps/v8/tools/turbolizer/src/selection-broker.ts b/deps/v8/tools/turbolizer/src/selection-broker.ts index e20fd977d2..7e0c0ddee0 100644 --- a/deps/v8/tools/turbolizer/src/selection-broker.ts +++ b/deps/v8/tools/turbolizer/src/selection-broker.ts @@ -2,36 +2,54 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import {SourceResolver, sourcePositionValid} from "./source-resolver.js" +import { SourceResolver, sourcePositionValid } from "../src/source-resolver"; +import { ClearableHandler, SelectionHandler, NodeSelectionHandler, BlockSelectionHandler, InstructionSelectionHandler } from "../src/selection-handler"; export class SelectionBroker { sourceResolver: SourceResolver; + allHandlers: Array<ClearableHandler>; sourcePositionHandlers: Array<SelectionHandler>; nodeHandlers: Array<NodeSelectionHandler>; blockHandlers: Array<BlockSelectionHandler>; + instructionHandlers: Array<InstructionSelectionHandler>; constructor(sourceResolver) { + this.allHandlers = []; this.sourcePositionHandlers = []; this.nodeHandlers = []; this.blockHandlers = []; + this.instructionHandlers = []; this.sourceResolver = sourceResolver; - }; + } - addSourcePositionHandler(handler) { + addSourcePositionHandler(handler: SelectionHandler & ClearableHandler) { + this.allHandlers.push(handler); this.sourcePositionHandlers.push(handler); } - addNodeHandler(handler) { + addNodeHandler(handler: NodeSelectionHandler & ClearableHandler) { + this.allHandlers.push(handler); this.nodeHandlers.push(handler); } - addBlockHandler(handler) { + addBlockHandler(handler: BlockSelectionHandler & ClearableHandler) { + this.allHandlers.push(handler); this.blockHandlers.push(handler); } + addInstructionHandler(handler: InstructionSelectionHandler & ClearableHandler) { + this.allHandlers.push(handler); + this.instructionHandlers.push(handler); + } + + broadcastInstructionSelect(from, instructionOffsets, selected) { + for (const b of this.instructionHandlers) { + if (b != from) b.brokeredInstructionSelect(instructionOffsets, selected); + } + } + broadcastSourcePositionSelect(from, sourcePositions, selected) { - let broker = this; - sourcePositions = sourcePositions.filter((l) => { + sourcePositions = sourcePositions.filter(l => { if (!sourcePositionValid(l)) { console.log("Warning: invalid source position"); return false; @@ -48,7 +66,6 @@ export class SelectionBroker { } broadcastNodeSelect(from, nodes, selected) { - let broker = this; for (const b of this.nodeHandlers) { if (b != from) b.brokeredNodeSelect(nodes, selected); } @@ -59,20 +76,13 @@ export class SelectionBroker { } broadcastBlockSelect(from, blocks, selected) { - let broker = this; - for (var b of this.blockHandlers) { + for (const b of this.blockHandlers) { if (b != from) b.brokeredBlockSelect(blocks, selected); } } broadcastClear(from) { - this.sourcePositionHandlers.forEach(function (b) { - if (b != from) b.brokeredClear(); - }); - this.nodeHandlers.forEach(function (b) { - if (b != from) b.brokeredClear(); - }); - this.blockHandlers.forEach(function (b) { + this.allHandlers.forEach(function (b) { if (b != from) b.brokeredClear(); }); } diff --git a/deps/v8/tools/turbolizer/src/selection-handler.ts b/deps/v8/tools/turbolizer/src/selection-handler.ts index bf0719c8a6..a605149238 100644 --- a/deps/v8/tools/turbolizer/src/selection-handler.ts +++ b/deps/v8/tools/turbolizer/src/selection-handler.ts @@ -2,23 +2,30 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -interface SelectionHandler { +export interface ClearableHandler { + brokeredClear(): void; +} + +export interface SelectionHandler { clear(): void; select(nodeIds: any, selected: any): void; - brokeredClear(): void; brokeredSourcePositionSelect(sourcePositions: any, selected: any): void; -}; +} -interface NodeSelectionHandler { +export interface NodeSelectionHandler { clear(): void; select(nodeIds: any, selected: any): void; - brokeredClear(): void; brokeredNodeSelect(nodeIds: any, selected: any): void; -}; +} -interface BlockSelectionHandler { +export interface BlockSelectionHandler { clear(): void; select(nodeIds: any, selected: any): void; - brokeredClear(): void; brokeredBlockSelect(blockIds: any, selected: any): void; -}; +} + +export interface InstructionSelectionHandler { + clear(): void; + select(instructionIds: any, selected: any): void; + brokeredInstructionSelect(instructionIds: any, selected: any): void; +} diff --git a/deps/v8/tools/turbolizer/src/selection.ts b/deps/v8/tools/turbolizer/src/selection.ts index b02a3e9cbb..90fe3bd4bc 100644 --- a/deps/v8/tools/turbolizer/src/selection.ts +++ b/deps/v8/tools/turbolizer/src/selection.ts @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import {isIterable} from "./util.js" - export class MySelection { selection: any; stringKey: (o: any) => string; @@ -21,8 +19,7 @@ export class MySelection { this.selection = new Map(); } - select(s, isSelected) { - if (!isIterable(s)) { s = [s]; } + select(s: Iterable<any>, isSelected?: boolean) { for (const i of s) { if (!i) continue; if (isSelected == undefined) { @@ -36,7 +33,7 @@ export class MySelection { } } - isSelected(i): boolean { + isSelected(i: any): boolean { return this.selection.has(this.stringKey(i)); } @@ -45,21 +42,18 @@ export class MySelection { } selectedKeys() { - var result = new Set(); - for (var i of this.selection.keys()) { + const result = new Set(); + for (const i of this.selection.keys()) { result.add(i); } return result; } detachSelection() { - var result = new Set(); - for (var i of this.selection.keys()) { - result.add(i); - } + const result = this.selectedKeys(); this.clear(); return result; } - [Symbol.iterator]() { return this.selection.values() } + [Symbol.iterator]() { return this.selection.values(); } } diff --git a/deps/v8/tools/turbolizer/src/sequence-view.ts b/deps/v8/tools/turbolizer/src/sequence-view.ts index afddb56649..a796707c74 100644 --- a/deps/v8/tools/turbolizer/src/sequence-view.ts +++ b/deps/v8/tools/turbolizer/src/sequence-view.ts @@ -2,14 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import {Sequence} from "./source-resolver.js" -import {isIterable} from "./util.js" -import {PhaseView} from "./view.js" -import {TextView} from "./text-view.js" +import { Sequence } from "../src/source-resolver"; +import { isIterable } from "../src/util"; +import { TextView } from "../src/text-view"; -export class SequenceView extends TextView implements PhaseView { +export class SequenceView extends TextView { sequence: Sequence; - search_info: Array<any>; + searchInfo: Array<any>; createViewElement() { const pane = document.createElement('div'); @@ -18,7 +17,7 @@ export class SequenceView extends TextView implements PhaseView { } constructor(parentId, broker) { - super(parentId, broker, null); + super(parentId, broker); } attachSelection(s) { @@ -39,9 +38,17 @@ export class SequenceView extends TextView implements PhaseView { initializeContent(data, rememberedSelection) { this.divNode.innerHTML = ''; this.sequence = data.sequence; - this.search_info = []; + this.searchInfo = []; + this.divNode.addEventListener('click', (e: MouseEvent) => { + if (!(e.target instanceof HTMLElement)) return; + const instructionId = Number.parseInt(e.target.dataset.instructionId, 10); + if (!instructionId) return; + if (!e.shiftKey) this.broker.broadcastClear(null); + this.broker.broadcastInstructionSelect(null, [instructionId], true); + }); this.addBlocks(this.sequence.blocks); this.attachSelection(rememberedSelection); + this.show(); } elementForBlock(block) { @@ -75,23 +82,25 @@ export class SequenceView extends TextView implements PhaseView { return mkLinkHandler(text, view.selectionHandler); } - function elementForOperand(operand, search_info) { - var text = operand.text; + function elementForOperand(operand, searchInfo) { + const text = operand.text; const operandEl = createElement("div", ["parameter", "tag", "clickable", operand.type], text); if (operand.tooltip) { operandEl.setAttribute("title", operand.tooltip); } operandEl.onclick = mkOperandLinkHandler(text); - search_info.push(text); + searchInfo.push(text); view.addHtmlElementForNodeId(text, operandEl); return operandEl; } - function elementForInstruction(instruction, search_info) { + function elementForInstruction(instruction, searchInfo) { const instNodeEl = createElement("div", "instruction-node"); - const inst_id = createElement("div", "instruction-id", instruction.id); - instNodeEl.appendChild(inst_id); + const instId = createElement("div", "instruction-id", instruction.id); + instId.classList.add("clickable"); + instId.dataset.instructionId = instruction.id; + instNodeEl.appendChild(instId); const instContentsEl = createElement("div", "instruction-contents"); instNodeEl.appendChild(instContentsEl); @@ -103,11 +112,11 @@ export class SequenceView extends TextView implements PhaseView { const moves = createElement("div", ["comma-sep-list", "gap-move"]); for (const move of gap) { const moveEl = createElement("div", "move"); - const destinationEl = elementForOperand(move[0], search_info); + const destinationEl = elementForOperand(move[0], searchInfo); moveEl.appendChild(destinationEl); const assignEl = createElement("div", "assign", "="); moveEl.appendChild(assignEl); - const sourceEl = elementForOperand(move[1], search_info); + const sourceEl = elementForOperand(move[1], searchInfo); moveEl.appendChild(sourceEl); moves.appendChild(moveEl); } @@ -120,7 +129,7 @@ export class SequenceView extends TextView implements PhaseView { if (instruction.outputs.length > 0) { const outputs = createElement("div", ["comma-sep-list", "input-output-list"]); for (const output of instruction.outputs) { - const outputEl = elementForOperand(output, search_info); + const outputEl = elementForOperand(output, searchInfo); outputs.appendChild(outputEl); } instEl.appendChild(outputs); @@ -128,16 +137,16 @@ export class SequenceView extends TextView implements PhaseView { instEl.appendChild(assignEl); } - var text = instruction.opcode + instruction.flags; - const inst_label = createElement("div", "node-label", text); - search_info.push(text); - view.addHtmlElementForNodeId(text, inst_label); - instEl.appendChild(inst_label); + const text = instruction.opcode + instruction.flags; + const instLabel = createElement("div", "node-label", text); + searchInfo.push(text); + view.addHtmlElementForNodeId(text, instLabel); + instEl.appendChild(instLabel); if (instruction.inputs.length > 0) { const inputs = createElement("div", ["comma-sep-list", "input-output-list"]); for (const input of instruction.inputs) { - const inputEl = elementForOperand(input, search_info); + const inputEl = elementForOperand(input, searchInfo); inputs.appendChild(inputEl); } instEl.appendChild(inputs); @@ -146,7 +155,7 @@ export class SequenceView extends TextView implements PhaseView { if (instruction.temps.length > 0) { const temps = createElement("div", ["comma-sep-list", "input-output-list", "temps"]); for (const temp of instruction.temps) { - const tempEl = elementForOperand(temp, search_info); + const tempEl = elementForOperand(temp, searchInfo); temps.appendChild(tempEl); } instEl.appendChild(temps); @@ -155,20 +164,20 @@ export class SequenceView extends TextView implements PhaseView { return instNodeEl; } - const sequence_block = createElement("div", "schedule-block"); + const sequenceBlock = createElement("div", "schedule-block"); - const block_id = createElement("div", ["block-id", "com", "clickable"], block.id); - block_id.onclick = mkBlockLinkHandler(block.id); - sequence_block.appendChild(block_id); - const block_pred = createElement("div", ["predecessor-list", "block-list", "comma-sep-list"]); + const blockId = createElement("div", ["block-id", "com", "clickable"], block.id); + blockId.onclick = mkBlockLinkHandler(block.id); + sequenceBlock.appendChild(blockId); + const blockPred = createElement("div", ["predecessor-list", "block-list", "comma-sep-list"]); for (const pred of block.predecessors) { const predEl = createElement("div", ["block-id", "com", "clickable"], pred); predEl.onclick = mkBlockLinkHandler(pred); - block_pred.appendChild(predEl); + blockPred.appendChild(predEl); } - if (block.predecessors.length > 0) sequence_block.appendChild(block_pred); + if (block.predecessors.length > 0) sequenceBlock.appendChild(blockPred); const phis = createElement("div", "phis"); - sequence_block.appendChild(phis); + sequenceBlock.appendChild(phis); const phiLabel = createElement("div", "phi-label", "phi:"); phis.appendChild(phiLabel); @@ -180,7 +189,7 @@ export class SequenceView extends TextView implements PhaseView { const phiEl = createElement("div", "phi"); phiContents.appendChild(phiEl); - const outputEl = elementForOperand(phi.output, this.search_info); + const outputEl = elementForOperand(phi.output, this.searchInfo); phiEl.appendChild(outputEl); const assignEl = createElement("div", "assign", "="); @@ -194,18 +203,18 @@ export class SequenceView extends TextView implements PhaseView { const instructions = createElement("div", "instructions"); for (const instruction of block.instructions) { - instructions.appendChild(elementForInstruction(instruction, this.search_info)); + instructions.appendChild(elementForInstruction(instruction, this.searchInfo)); } - sequence_block.appendChild(instructions); - const block_succ = createElement("div", ["successor-list", "block-list", "comma-sep-list"]); + sequenceBlock.appendChild(instructions); + const blockSucc = createElement("div", ["successor-list", "block-list", "comma-sep-list"]); for (const succ of block.successors) { const succEl = createElement("div", ["block-id", "com", "clickable"], succ); succEl.onclick = mkBlockLinkHandler(succ); - block_succ.appendChild(succEl); + blockSucc.appendChild(succEl); } - if (block.successors.length > 0) sequence_block.appendChild(block_succ); - this.addHtmlElementForBlockId(block.id, sequence_block); - return sequence_block; + if (block.successors.length > 0) sequenceBlock.appendChild(blockSucc); + this.addHtmlElementForBlockId(block.id, sequenceBlock); + return sequenceBlock; } addBlocks(blocks) { @@ -223,13 +232,11 @@ export class SequenceView extends TextView implements PhaseView { const select = []; window.sessionStorage.setItem("lastSearch", query); const reg = new RegExp(query); - for (const item of this.search_info) { + for (const item of this.searchInfo) { if (reg.exec(item) != null) { select.push(item); } } this.selectionHandler.select(select, true); } - - onresize() { } } diff --git a/deps/v8/tools/turbolizer/src/source-resolver.ts b/deps/v8/tools/turbolizer/src/source-resolver.ts index 20f1f5070a..67f9c088a2 100644 --- a/deps/v8/tools/turbolizer/src/source-resolver.ts +++ b/deps/v8/tools/turbolizer/src/source-resolver.ts @@ -2,7 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import {sortUnique, anyToString} from "./util.js" +import { sortUnique, anyToString } from "../src/util"; +import { NodeLabel } from "./node-label"; function sourcePositionLe(a, b) { if (a.inliningId == b.inliningId) { @@ -16,12 +17,14 @@ function sourcePositionEq(a, b) { a.scriptOffset == b.scriptOffset; } -export function sourcePositionToStringKey(sourcePosition): string { +export function sourcePositionToStringKey(sourcePosition: AnyPosition): string { if (!sourcePosition) return "undefined"; - if (sourcePosition.inliningId && sourcePosition.scriptOffset) + if ('inliningId' in sourcePosition && 'scriptOffset' in sourcePosition) { return "SP:" + sourcePosition.inliningId + ":" + sourcePosition.scriptOffset; - if (sourcePosition.bytecodePosition) + } + if (sourcePosition.bytecodePosition) { return "BCP:" + sourcePosition.bytecodePosition; + } return "undefined"; } @@ -48,9 +51,9 @@ interface BytecodePosition { bytecodePosition: number; } -type Origin = NodeOrigin | BytecodePosition; -type TurboFanNodeOrigin = NodeOrigin & TurboFanOrigin; -type TurboFanBytecodeOrigin = BytecodePosition & TurboFanOrigin; +export type Origin = NodeOrigin | BytecodePosition; +export type TurboFanNodeOrigin = NodeOrigin & TurboFanOrigin; +export type TurboFanBytecodeOrigin = BytecodePosition & TurboFanOrigin; type AnyPosition = SourcePosition | BytecodePosition; @@ -61,17 +64,37 @@ export interface Source { sourceText: string; sourceId: number; startPosition?: number; + backwardsCompatibility: boolean; } interface Inlining { inliningPosition: SourcePosition; sourceId: number; } -interface Phase { - type: string; +interface OtherPhase { + type: "disassembly" | "sequence" | "schedule"; + name: string; + data: any; +} + +interface InstructionsPhase { + type: "instructions"; + name: string; + data: any; + instructionOffsetToPCOffset?: any; + blockIdtoInstructionRange?: any; + nodeIdToInstructionRange?: any; +} + +interface GraphPhase { + type: "graph"; name: string; data: any; + highestNodeId: number; + nodeLabelMap: Array<NodeLabel>; } +type Phase = GraphPhase | InstructionsPhase | OtherPhase; + export interface Schedule { nodes: Array<any>; } @@ -94,7 +117,7 @@ export class SourceResolver { blockIdToInstructionRange: Array<[number, number]>; instructionToPCOffset: Array<number>; pcOffsetToInstructions: Map<number, Array<number>>; - + pcOffsets: Array<number>; constructor() { // Maps node ids to source positions. @@ -123,11 +146,12 @@ export class SourceResolver { this.instructionToPCOffset = []; // Maps PC offsets to instructions. this.pcOffsetToInstructions = new Map(); + this.pcOffsets = []; } setSources(sources, mainBackup) { if (sources) { - for (let [sourceId, source] of Object.entries(sources)) { + for (const [sourceId, source] of Object.entries(sources)) { this.sources[sourceId] = source; this.sources[sourceId].sourcePositions = []; } @@ -159,7 +183,7 @@ export class SourceResolver { alternativeMap[nodeId] = { scriptOffset: scriptOffset, inliningId: -1 }; } map = alternativeMap; - }; + } for (const [nodeId, sourcePosition] of Object.entries<SourcePosition>(map)) { if (sourcePosition == undefined) { @@ -172,13 +196,13 @@ export class SourceResolver { this.sources[sourceId].sourcePositions.push(sourcePosition); } this.nodePositionMap[nodeId] = sourcePosition; - let key = sourcePositionToStringKey(sourcePosition); + const key = sourcePositionToStringKey(sourcePosition); if (!this.positionToNodes.has(key)) { this.positionToNodes.set(key, []); } this.positionToNodes.get(key).push(nodeId); } - for (const [sourceId, source] of Object.entries(this.sources)) { + for (const [, source] of Object.entries(this.sources)) { source.sourcePositions = sortUnique(source.sourcePositions, sourcePositionLe, sourcePositionEq); } @@ -187,8 +211,8 @@ export class SourceResolver { sourcePositionsToNodeIds(sourcePositions) { const nodeIds = new Set(); for (const sp of sourcePositions) { - let key = sourcePositionToStringKey(sp); - let nodeIdsForPosition = this.positionToNodes.get(key); + const key = sourcePositionToStringKey(sp); + const nodeIdsForPosition = this.positionToNodes.get(key); if (!nodeIdsForPosition) continue; for (const nodeId of nodeIdsForPosition) { nodeIds.add(nodeId); @@ -200,8 +224,8 @@ export class SourceResolver { nodeIdsToSourcePositions(nodeIds): Array<AnyPosition> { const sourcePositions = new Map(); for (const nodeId of nodeIds) { - let sp = this.nodePositionMap[nodeId]; - let key = sourcePositionToStringKey(sp); + const sp = this.nodePositionMap[nodeId]; + const key = sourcePositionToStringKey(sp); sourcePositions.set(key, sp); } const sourcePositionArray = []; @@ -211,13 +235,13 @@ export class SourceResolver { return sourcePositionArray; } - forEachSource(f) { + forEachSource(f: (value: Source, index: number, array: Array<Source>) => void) { this.sources.forEach(f); } - translateToSourceId(sourceId, location) { + translateToSourceId(sourceId: number, location?: SourcePosition) { for (const position of this.getInlineStack(location)) { - let inlining = this.inlinings[position.inliningId]; + const inlining = this.inlinings[position.inliningId]; if (!inlining) continue; if (inlining.sourceId == sourceId) { return position; @@ -226,10 +250,10 @@ export class SourceResolver { return location; } - addInliningPositions(sourcePosition, locations) { - let inlining = this.inliningsMap.get(sourcePositionToStringKey(sourcePosition)); + addInliningPositions(sourcePosition: AnyPosition, locations: Array<SourcePosition>) { + const inlining = this.inliningsMap.get(sourcePositionToStringKey(sourcePosition)); if (!inlining) return; - let sourceId = inlining.sourceId + const sourceId = inlining.sourceId; const source = this.sources[sourceId]; for (const sp of source.sourcePositions) { locations.push(sp); @@ -237,26 +261,26 @@ export class SourceResolver { } } - getInliningForPosition(sourcePosition) { + getInliningForPosition(sourcePosition: AnyPosition) { return this.inliningsMap.get(sourcePositionToStringKey(sourcePosition)); } - getSource(sourceId) { + getSource(sourceId: number) { return this.sources[sourceId]; } - getSourceName(sourceId) { + getSourceName(sourceId: number) { const source = this.sources[sourceId]; return `${source.sourceName}:${source.functionName}`; } - sourcePositionFor(sourceId, scriptOffset) { + sourcePositionFor(sourceId: number, scriptOffset: number) { if (!this.sources[sourceId]) { return null; } const list = this.sources[sourceId].sourcePositions; for (let i = 0; i < list.length; i++) { - const sourcePosition = list[i] + const sourcePosition = list[i]; const position = sourcePosition.scriptOffset; const nextPosition = list[Math.min(i + 1, list.length - 1)].scriptOffset; if ((position <= scriptOffset && scriptOffset < nextPosition)) { @@ -266,12 +290,11 @@ export class SourceResolver { return null; } - sourcePositionsInRange(sourceId, start, end) { + sourcePositionsInRange(sourceId: number, start: number, end: number) { if (!this.sources[sourceId]) return []; const res = []; const list = this.sources[sourceId].sourcePositions; - for (let i = 0; i < list.length; i++) { - const sourcePosition = list[i] + for (const sourcePosition of list) { if (start <= sourcePosition.scriptOffset && sourcePosition.scriptOffset < end) { res.push(sourcePosition); } @@ -279,15 +302,14 @@ export class SourceResolver { return res; } - getInlineStack(sourcePosition) { - if (!sourcePosition) { - return []; - } - let inliningStack = []; + getInlineStack(sourcePosition?: SourcePosition) { + if (!sourcePosition) return []; + + const inliningStack = []; let cur = sourcePosition; while (cur && cur.inliningId != -1) { inliningStack.push(cur); - let inlining = this.inlinings[cur.inliningId]; + const inlining = this.inlinings[cur.inliningId]; if (!inlining) { break; } @@ -299,19 +321,25 @@ export class SourceResolver { return inliningStack; } - recordOrigins(phase) { + recordOrigins(phase: GraphPhase) { if (phase.type != "graph") return; for (const node of phase.data.nodes) { + phase.highestNodeId = Math.max(phase.highestNodeId, node.id); if (node.origin != undefined && node.origin.bytecodePosition != undefined) { const position = { bytecodePosition: node.origin.bytecodePosition }; this.nodePositionMap[node.id] = position; - let key = sourcePositionToStringKey(position); + const key = sourcePositionToStringKey(position); if (!this.positionToNodes.has(key)) { this.positionToNodes.set(key, []); } const A = this.positionToNodes.get(key); - if (!A.includes(node.id)) A.push("" + node.id); + if (!A.includes(node.id)) A.push(`${node.id}`); + } + + // Backwards compatibility. + if (typeof node.pos === "number") { + node.sourcePosition = { scriptOffset: node.pos, inliningId: -1 }; } } } @@ -328,13 +356,13 @@ export class SourceResolver { } } - getInstruction(nodeId):[number, number] { + getInstruction(nodeId: number): [number, number] { const X = this.nodeIdToInstructionRange[nodeId]; if (X === undefined) return [-1, -1]; return X; } - getInstructionRangeForBlock(blockId):[number, number] { + getInstructionRangeForBlock(blockId: number): [number, number] { const X = this.blockIdToInstructionRange[blockId]; if (X === undefined) return [-1, -1]; return X; @@ -346,20 +374,51 @@ export class SourceResolver { if (!this.pcOffsetToInstructions.has(offset)) { this.pcOffsetToInstructions.set(offset, []); } - this.pcOffsetToInstructions.get(offset).push(instruction); + this.pcOffsetToInstructions.get(offset).push(Number(instruction)); } - console.log(this.pcOffsetToInstructions); + this.pcOffsets = Array.from(this.pcOffsetToInstructions.keys()).sort((a, b) => b - a); } hasPCOffsets() { return this.pcOffsetToInstructions.size > 0; } + getKeyPcOffset(offset: number): number { + if (this.pcOffsets.length === 0) return -1; + for (const key of this.pcOffsets) { + if (key <= offset) { + return key; + } + } + return -1; + } + + instructionRangeToKeyPcOffsets([start, end]: [number, number]) { + if (start == end) return [this.instructionToPCOffset[start]]; + return this.instructionToPCOffset.slice(start, end); + } + + instructionsToKeyPcOffsets(instructionIds: Iterable<number>) { + const keyPcOffsets = []; + for (const instructionId of instructionIds) { + keyPcOffsets.push(this.instructionToPCOffset[instructionId]); + } + return keyPcOffsets; + } + + nodesToKeyPcOffsets(nodes) { + let offsets = []; + for (const node of nodes) { + const range = this.nodeIdToInstructionRange[node]; + if (!range) continue; + offsets = offsets.concat(this.instructionRangeToKeyPcOffsets(range)); + } + return offsets; + } - nodesForPCOffset(offset): [Array<String>, Array<String>] { - const keys = Array.from(this.pcOffsetToInstructions.keys()).sort((a, b) => b - a); - if (keys.length === 0) return [[],[]]; - for (const key of keys) { + nodesForPCOffset(offset: number): [Array<string>, Array<string>] { + if (this.pcOffsets.length === 0) return [[], []]; + for (const key of this.pcOffsets) { if (key <= offset) { const instrs = this.pcOffsetToInstructions.get(key); const nodes = []; @@ -379,54 +438,82 @@ export class SourceResolver { return [nodes, blocks]; } } - return [[],[]]; + return [[], []]; } parsePhases(phases) { - for (const [phaseId, phase] of Object.entries<Phase>(phases)) { - if (phase.type == 'disassembly') { - this.disassemblyPhase = phase; - } else if (phase.type == 'schedule') { - this.phases.push(this.parseSchedule(phase)); - this.phaseNames.set(phase.name, this.phases.length); - } else if (phase.type == 'sequence') { - this.phases.push(this.parseSequence(phase)); - this.phaseNames.set(phase.name, this.phases.length); - } else if (phase.type == 'instructions') { - if (phase.nodeIdToInstructionRange) { - this.readNodeIdToInstructionRange(phase.nodeIdToInstructionRange); - } - if (phase.blockIdtoInstructionRange) { - this.readBlockIdToInstructionRange(phase.blockIdtoInstructionRange); - } - if (phase.instructionOffsetToPCOffset) { - this.readInstructionOffsetToPCOffset(phase.instructionOffsetToPCOffset); + const nodeLabelMap = []; + for (const [, phase] of Object.entries<Phase>(phases)) { + switch (phase.type) { + case 'disassembly': + this.disassemblyPhase = phase; + break; + case 'schedule': + this.phaseNames.set(phase.name, this.phases.length); + this.phases.push(this.parseSchedule(phase)); + break; + case 'sequence': + this.phaseNames.set(phase.name, this.phases.length); + this.phases.push(this.parseSequence(phase)); + break; + case 'instructions': + if (phase.nodeIdToInstructionRange) { + this.readNodeIdToInstructionRange(phase.nodeIdToInstructionRange); + } + if (phase.blockIdtoInstructionRange) { + this.readBlockIdToInstructionRange(phase.blockIdtoInstructionRange); + } + if (phase.instructionOffsetToPCOffset) { + this.readInstructionOffsetToPCOffset(phase.instructionOffsetToPCOffset); + } + break; + case 'graph': + const graphPhase: GraphPhase = Object.assign(phase, { highestNodeId: 0 }); + this.phaseNames.set(graphPhase.name, this.phases.length); + this.phases.push(graphPhase); + this.recordOrigins(graphPhase); + this.internNodeLabels(graphPhase, nodeLabelMap); + graphPhase.nodeLabelMap = nodeLabelMap.slice(); + break; + default: + throw "Unsupported phase type"; + } + } + } + + internNodeLabels(phase: GraphPhase, nodeLabelMap: Array<NodeLabel>) { + for (const n of phase.data.nodes) { + const label = new NodeLabel(n.id, n.label, n.title, n.live, + n.properties, n.sourcePosition, n.origin, n.opcode, n.control, + n.opinfo, n.type); + const previous = nodeLabelMap[label.id]; + if (!label.equals(previous)) { + if (previous != undefined) { + label.setInplaceUpdatePhase(phase.name); } - } else { - this.phases.push(phase); - this.recordOrigins(phase); - this.phaseNames.set(phase.name, this.phases.length); + nodeLabelMap[label.id] = label; } + n.nodeLabel = nodeLabelMap[label.id]; } } repairPhaseId(anyPhaseId) { - return Math.max(0, Math.min(anyPhaseId, this.phases.length - 1)) + return Math.max(0, Math.min(anyPhaseId | 0, this.phases.length - 1)); } - getPhase(phaseId) { + getPhase(phaseId: number) { return this.phases[phaseId]; } - getPhaseIdByName(phaseName) { + getPhaseIdByName(phaseName: string) { return this.phaseNames.get(phaseName); } - forEachPhase(f) { + forEachPhase(f: (value: Phase, index: number, array: Array<Phase>) => void) { this.phases.forEach(f); } - addAnyPositionToLine(lineNumber: number | String, sourcePosition: AnyPosition) { + addAnyPositionToLine(lineNumber: number | string, sourcePosition: AnyPosition) { const lineNumberString = anyToString(lineNumber); if (!this.lineToSourcePositions.has(lineNumberString)) { this.lineToSourcePositions.set(lineNumberString, []); @@ -442,19 +529,19 @@ export class SourceResolver { }); } - linetoSourcePositions(lineNumber: number | String) { + linetoSourcePositions(lineNumber: number | string) { const positions = this.lineToSourcePositions.get(anyToString(lineNumber)); if (positions === undefined) return []; return positions; } parseSchedule(phase) { - function createNode(state, match) { + function createNode(state: any, match) { let inputs = []; if (match.groups.args) { const nodeIdsString = match.groups.args.replace(/\s/g, ''); const nodeIdStrings = nodeIdsString.split(','); - inputs = nodeIdStrings.map((n) => Number.parseInt(n, 10)); + inputs = nodeIdStrings.map(n => Number.parseInt(n, 10)); } const node = { id: Number.parseInt(match.groups.id, 10), @@ -464,7 +551,7 @@ export class SourceResolver { if (match.groups.blocks) { const nodeIdsString = match.groups.blocks.replace(/\s/g, '').replace(/B/g, ''); const nodeIdStrings = nodeIdsString.split(','); - const successors = nodeIdStrings.map((n) => Number.parseInt(n, 10)); + const successors = nodeIdStrings.map(n => Number.parseInt(n, 10)); state.currentBlock.succ = successors; } state.nodes[node.id] = node; @@ -475,7 +562,7 @@ export class SourceResolver { if (match.groups.in) { const blockIdsString = match.groups.in.replace(/\s/g, '').replace(/B/g, ''); const blockIdStrings = blockIdsString.split(','); - predecessors = blockIdStrings.map((n) => Number.parseInt(n, 10)); + predecessors = blockIdStrings.map(n => Number.parseInt(n, 10)); } const block = { id: Number.parseInt(match.groups.id, 10), diff --git a/deps/v8/tools/turbolizer/src/tabs.ts b/deps/v8/tools/turbolizer/src/tabs.ts new file mode 100644 index 0000000000..0416b9ed9d --- /dev/null +++ b/deps/v8/tools/turbolizer/src/tabs.ts @@ -0,0 +1,114 @@ + +export class Tabs { + private container: HTMLElement; + private tabBar: HTMLElement; + private nextTabId: number; + + private mkTabBar(container: HTMLElement) { + container.classList.add("nav-tabs-container"); + this.tabBar = document.createElement("ul"); + this.tabBar.id = `tab-bar-${container.id}`; + this.tabBar.className = "nav-tabs"; + this.tabBar.ondrop = this.tabBarOnDrop.bind(this); + this.tabBar.ondragover = this.tabBarOnDragover.bind(this); + this.tabBar.onclick = this.tabBarOnClick.bind(this); + + const defaultDiv = document.createElement("div"); + defaultDiv.className = "tab-content tab-default"; + defaultDiv.id = `tab-content-${container.id}-default`; + container.insertBefore(defaultDiv, container.firstChild); + container.insertBefore(this.tabBar, container.firstChild); + } + + constructor(container: HTMLElement) { + this.container = container; + this.nextTabId = 0; + this.mkTabBar(container); + } + + activateTab(tab: HTMLLIElement) { + if (typeof tab.dataset.divid !== "string") return; + for (const li of this.tabBar.querySelectorAll<HTMLLIElement>("li.active")) { + li.classList.remove("active"); + this.showTab(li, false); + } + tab.classList.add("active"); + this.showTab(tab, true); + } + + clearTabsAndContent() { + for (const tab of this.tabBar.querySelectorAll(".nav-tabs > li")) { + if (!(tab instanceof HTMLLIElement)) continue; + if (tab.classList.contains("persistent-tab")) continue; + const tabDiv = document.getElementById(tab.dataset.divid); + tabDiv.parentNode.removeChild(tabDiv); + tab.parentNode.removeChild(tab); + } + } + + private showTab(li: HTMLElement, show: boolean = true) { + const tabDiv = document.getElementById(li.dataset.divid); + tabDiv.style.display = show ? "block" : "none"; + } + + public addTab(caption: string): HTMLLIElement { + const newTab = document.createElement("li"); + newTab.innerHTML = caption; + newTab.id = `tab-header-${this.container.id}-${this.nextTabId++}`; + const lastTab = this.tabBar.querySelector("li.last-tab"); + this.tabBar.insertBefore(newTab, lastTab); + return newTab; + } + + public addTabAndContent(caption: string): [HTMLLIElement, HTMLDivElement] { + const contentDiv = document.createElement("div"); + contentDiv.className = "tab-content tab-default"; + contentDiv.id = `tab-content-${this.container.id}-${this.nextTabId++}`; + contentDiv.style.display = "none"; + this.container.appendChild(contentDiv); + + const newTab = this.addTab(caption); + newTab.dataset.divid = contentDiv.id; + newTab.draggable = true; + newTab.ondragstart = this.tabOnDragStart.bind(this); + const lastTab = this.tabBar.querySelector("li.last-tab"); + this.tabBar.insertBefore(newTab, lastTab); + return [newTab, contentDiv]; + } + + private moveTabDiv(tab: HTMLLIElement) { + const tabDiv = document.getElementById(tab.dataset.divid); + tabDiv.style.display = "none"; + tab.classList.remove("active"); + this.tabBar.parentNode.appendChild(tabDiv); + } + + private tabBarOnDrop(e: DragEvent) { + if (!(e.target instanceof HTMLElement)) return; + e.preventDefault(); + const tabId = e.dataTransfer.getData("text"); + const tab = document.getElementById(tabId) as HTMLLIElement; + if (tab.parentNode != this.tabBar) { + this.moveTabDiv(tab); + } + const dropTab = + e.target.parentNode == this.tabBar + ? e.target : this.tabBar.querySelector("li.last-tab"); + this.tabBar.insertBefore(tab, dropTab); + this.activateTab(tab); + } + + private tabBarOnDragover(e) { + e.preventDefault(); + } + + private tabOnDragStart(e: DragEvent) { + if (!(e.target instanceof HTMLElement)) return; + e.dataTransfer.setData("text", e.target.id); + } + + private tabBarOnClick(e: MouseEvent) { + const li = e.target as HTMLLIElement; + this.activateTab(li); + } +} diff --git a/deps/v8/tools/turbolizer/src/text-view.ts b/deps/v8/tools/turbolizer/src/text-view.ts index a88d31d194..41a06eae77 100644 --- a/deps/v8/tools/turbolizer/src/text-view.ts +++ b/deps/v8/tools/turbolizer/src/text-view.ts @@ -2,14 +2,16 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import {View} from "./view.js" -import {anyToString, ViewElements, isIterable} from "./util.js" -import {MySelection} from "./selection.js" - -export abstract class TextView extends View { +import { PhaseView } from "../src/view"; +import { anyToString, ViewElements, isIterable } from "../src/util"; +import { MySelection } from "../src/selection"; +import { SourceResolver } from "./source-resolver"; +import { SelectionBroker } from "./selection-broker"; +import { NodeSelectionHandler, BlockSelectionHandler } from "./selection-handler"; + +export abstract class TextView extends PhaseView { selectionHandler: NodeSelectionHandler; blockSelectionHandler: BlockSelectionHandler; - nodeSelectionHandler: NodeSelectionHandler; selection: MySelection; blockSelection: MySelection; textListNode: HTMLUListElement; @@ -18,18 +20,22 @@ export abstract class TextView extends View { blockIdtoNodeIds: Map<string, Array<string>>; nodeIdToBlockId: Array<string>; patterns: any; + sourceResolver: SourceResolver; + broker: SelectionBroker; - constructor(id, broker, patterns) { + constructor(id, broker) { super(id); - let view = this; + const view = this; view.textListNode = view.divNode.getElementsByTagName('ul')[0]; - view.patterns = patterns; + view.patterns = null; view.nodeIdToHtmlElementsMap = new Map(); view.blockIdToHtmlElementsMap = new Map(); view.blockIdtoNodeIds = new Map(); view.nodeIdToBlockId = []; view.selection = new MySelection(anyToString); view.blockSelection = new MySelection(anyToString); + view.broker = broker; + view.sourceResolver = broker.sourceResolver; const selectionHandler = { clear: function () { view.selection.clear(); @@ -53,11 +59,12 @@ export abstract class TextView extends View { }; this.selectionHandler = selectionHandler; broker.addNodeHandler(selectionHandler); - view.divNode.onmouseup = function (e) { + view.divNode.addEventListener('click', e => { if (!e.shiftKey) { view.selectionHandler.clear(); } - } + e.stopPropagation(); + }); const blockSelectionHandler = { clear: function () { view.blockSelection.clear(); @@ -129,6 +136,10 @@ export abstract class TextView extends View { element.classList.toggle("selected", isSelected); } } + const elementsToSelect = view.divNode.querySelectorAll(`[data-pc-offset]`); + for (const el of elementsToSelect) { + el.classList.toggle("selected", false); + } for (const key of this.nodeIdToHtmlElementsMap.keys()) { for (const element of this.nodeIdToHtmlElementsMap.get(key)) { element.classList.toggle("selected", false); @@ -146,82 +157,47 @@ export abstract class TextView extends View { } setPatterns(patterns) { - let view = this; - view.patterns = patterns; + this.patterns = patterns; } clearText() { - let view = this; - while (view.textListNode.firstChild) { - view.textListNode.removeChild(view.textListNode.firstChild); + while (this.textListNode.firstChild) { + this.textListNode.removeChild(this.textListNode.firstChild); } } createFragment(text, style) { - let view = this; - let fragment = document.createElement("SPAN"); - - if (style.blockId != undefined) { - const blockId = style.blockId(text); - if (blockId != undefined) { - fragment.blockId = blockId; - this.addHtmlElementForBlockId(blockId, fragment); - } - } - - if (typeof style.link == 'function') { - fragment.classList.add('linkable-text'); - fragment.onmouseup = function (e) { - e.stopPropagation(); - style.link(text) - }; - } - - if (typeof style.nodeId == 'function') { - const nodeId = style.nodeId(text); - if (nodeId != undefined) { - fragment.nodeId = nodeId; - this.addHtmlElementForNodeId(nodeId, fragment); - } - } - - if (typeof style.assignBlockId === 'function') { - fragment.blockId = style.assignBlockId(); - this.addNodeIdToBlockId(fragment.nodeId, fragment.blockId); - } - - if (typeof style.linkHandler == 'function') { - const handler = style.linkHandler(text, fragment) - if (handler !== undefined) { - fragment.classList.add('linkable-text'); - fragment.onmouseup = handler; + const fragment = document.createElement("SPAN"); + + if (typeof style.associateData == 'function') { + style.associateData(text, fragment); + } else { + if (style.css != undefined) { + const css = isIterable(style.css) ? style.css : [style.css]; + for (const cls of css) { + fragment.classList.add(cls); + } } + fragment.innerText = text; } - if (style.css != undefined) { - const css = isIterable(style.css) ? style.css : [style.css]; - for (const cls of css) { - fragment.classList.add(cls); - } - } - fragment.innerHTML = text; return fragment; } processLine(line) { - let view = this; - let result = []; + const view = this; + const result = []; let patternSet = 0; while (true) { - let beforeLine = line; - for (let pattern of view.patterns[patternSet]) { - let matches = line.match(pattern[0]); + const beforeLine = line; + for (const pattern of view.patterns[patternSet]) { + const matches = line.match(pattern[0]); if (matches != null) { if (matches[0] != '') { - let style = pattern[1] != null ? pattern[1] : {}; - let text = matches[0]; + const style = pattern[1] != null ? pattern[1] : {}; + const text = matches[0]; if (text != '') { - let fragment = view.createFragment(matches[0], style); + const fragment = view.createFragment(matches[0], style); result.push(fragment); } line = line.substr(matches[0].length); @@ -247,15 +223,15 @@ export abstract class TextView extends View { } processText(text) { - let view = this; - let textLines = text.split(/[\n]/); + const view = this; + const textLines = text.split(/[\n]/); let lineNo = 0; - for (let line of textLines) { - let li = document.createElement("LI"); + for (const line of textLines) { + const li = document.createElement("LI"); li.className = "nolinenums"; li.dataset.lineNo = "" + lineNo++; - let fragments = view.processLine(line); - for (let fragment of fragments) { + const fragments = view.processLine(line); + for (const fragment of fragments) { li.appendChild(fragment); } view.textListNode.appendChild(li); @@ -263,13 +239,12 @@ export abstract class TextView extends View { } initializeContent(data, rememberedSelection) { - let view = this; - view.clearText(); - view.processText(data); + this.clearText(); + this.processText(data); + this.show(); } - deleteContent() { - } + public onresize(): void {} isScrollable() { return true; diff --git a/deps/v8/tools/turbolizer/src/turbo-visualizer.ts b/deps/v8/tools/turbolizer/src/turbo-visualizer.ts index 4cab92a197..87924b7b96 100644 --- a/deps/v8/tools/turbolizer/src/turbo-visualizer.ts +++ b/deps/v8/tools/turbolizer/src/turbo-visualizer.ts @@ -2,220 +2,50 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import * as C from "./constants.js" -import {SourceResolver} from "./source-resolver.js" -import {SelectionBroker} from "./selection-broker.js" -import {DisassemblyView} from "./disassembly-view.js" -import {GraphMultiView} from "./graphmultiview.js" -import {CodeMode, CodeView} from "./code-view.js" -import * as d3 from "d3" - -class Snapper { - resizer: Resizer; - sourceExpand: HTMLElement; - sourceCollapse: HTMLElement; - disassemblyExpand: HTMLElement; - disassemblyCollapse: HTMLElement; - - constructor(resizer: Resizer) { - const snapper = this; - snapper.resizer = resizer; - snapper.sourceExpand = document.getElementById(C.SOURCE_EXPAND_ID); - snapper.sourceCollapse = document.getElementById(C.SOURCE_COLLAPSE_ID); - snapper.disassemblyExpand = document.getElementById(C.DISASSEMBLY_EXPAND_ID); - snapper.disassemblyCollapse = document.getElementById(C.DISASSEMBLY_COLLAPSE_ID); - - document.getElementById("source-collapse").addEventListener("click", function () { - resizer.snapper.toggleSourceExpanded(); - }); - document.getElementById("disassembly-collapse").addEventListener("click", function () { - resizer.snapper.toggleDisassemblyExpanded(); - }); - } - - getLastExpandedState(type, default_state) { - var state = window.sessionStorage.getItem("expandedState-" + type); - if (state === null) return default_state; - return state === 'true'; - } - - setLastExpandedState(type, state) { - window.sessionStorage.setItem("expandedState-" + type, state); - } - - toggleSourceExpanded(): void { - this.setSourceExpanded(!this.sourceExpand.classList.contains("invisible")); - } - - sourceExpandUpdate(newState: boolean) { - this.setLastExpandedState("source", newState); - this.sourceExpand.classList.toggle("invisible", newState); - this.sourceCollapse.classList.toggle("invisible", !newState); - } - - setSourceExpanded(newState) { - if (this.sourceExpand.classList.contains("invisible") === newState) return; - this.sourceExpandUpdate(newState); - let resizer = this.resizer; - if (newState) { - resizer.sep_left = resizer.sep_left_snap; - resizer.sep_left_snap = 0; - } else { - resizer.sep_left_snap = resizer.sep_left; - resizer.sep_left = 0; - } - resizer.updatePanes(); - } - - toggleDisassemblyExpanded() { - this.setDisassemblyExpanded(!this.disassemblyExpand.classList.contains("invisible")); - } - - disassemblyExpandUpdate(newState) { - this.setLastExpandedState("disassembly", newState); - this.disassemblyExpand.classList.toggle("invisible", newState); - this.disassemblyCollapse.classList.toggle("invisible", !newState); - } - - setDisassemblyExpanded(newState) { - if (this.disassemblyExpand.classList.contains("invisible") === newState) return; - this.disassemblyExpandUpdate(newState); - let resizer = this.resizer; - if (newState) { - resizer.sep_right = resizer.sep_right_snap; - resizer.sep_right_snap = resizer.client_width; - } else { - resizer.sep_right_snap = resizer.sep_right; - resizer.sep_right = resizer.client_width; - } - resizer.updatePanes(); - } - - panesUpated() { - this.sourceExpandUpdate(this.resizer.sep_left > this.resizer.dead_width); - this.disassemblyExpandUpdate(this.resizer.sep_right < - (this.resizer.client_width - this.resizer.dead_width)); - } -} - -class Resizer { - snapper: Snapper; - dead_width: number; - client_width: number; - left: HTMLElement; - right: HTMLElement; - middle: HTMLElement; - sep_left: number; - sep_right: number; - sep_left_snap: number; - sep_right_snap: number; - sep_width_offset: number; - panes_updated_callback: () => void; - resizer_right: d3.Selection<HTMLDivElement, any, any, any>; - resizer_left: d3.Selection<HTMLDivElement, any, any, any>; - - constructor(panes_updated_callback: () => void, dead_width: number) { - let resizer = this; - resizer.snapper = new Snapper(resizer) - resizer.panes_updated_callback = panes_updated_callback; - resizer.dead_width = dead_width - resizer.client_width = document.body.getBoundingClientRect().width; - resizer.left = document.getElementById(C.SOURCE_PANE_ID); - resizer.middle = document.getElementById(C.INTERMEDIATE_PANE_ID); - resizer.right = document.getElementById(C.GENERATED_PANE_ID); - resizer.resizer_left = d3.select('.resizer-left'); - resizer.resizer_right = d3.select('.resizer-right'); - resizer.sep_left = resizer.client_width / 3; - resizer.sep_right = resizer.client_width / 3 * 2; - resizer.sep_left_snap = 0; - resizer.sep_right_snap = 0; - // Offset to prevent resizers from sliding slightly over one another. - resizer.sep_width_offset = 7; - - let dragResizeLeft = d3.drag() - .on('drag', function () { - let x = d3.mouse(this.parentElement)[0]; - resizer.sep_left = Math.min(Math.max(0, x), resizer.sep_right - resizer.sep_width_offset); - resizer.updatePanes(); - }) - .on('start', function () { - resizer.resizer_left.classed("dragged", true); - let x = d3.mouse(this.parentElement)[0]; - if (x > dead_width) { - resizer.sep_left_snap = resizer.sep_left; - } - }) - .on('end', function () { - resizer.resizer_left.classed("dragged", false); - }); - resizer.resizer_left.call(dragResizeLeft); - - let dragResizeRight = d3.drag() - .on('drag', function () { - let x = d3.mouse(this.parentElement)[0]; - resizer.sep_right = Math.max(resizer.sep_left + resizer.sep_width_offset, Math.min(x, resizer.client_width)); - resizer.updatePanes(); - }) - .on('start', function () { - resizer.resizer_right.classed("dragged", true); - let x = d3.mouse(this.parentElement)[0]; - if (x < (resizer.client_width - dead_width)) { - resizer.sep_right_snap = resizer.sep_right; - } - }) - .on('end', function () { - resizer.resizer_right.classed("dragged", false); - });; - resizer.resizer_right.call(dragResizeRight); - window.onresize = function () { - resizer.updateWidths(); - resizer.updatePanes(); - }; - } - - updatePanes() { - let left_snapped = this.sep_left === 0; - let right_snapped = this.sep_right >= this.client_width - 1; - this.resizer_left.classed("snapped", left_snapped); - this.resizer_right.classed("snapped", right_snapped); - this.left.style.width = this.sep_left + 'px'; - this.middle.style.width = (this.sep_right - this.sep_left) + 'px'; - this.right.style.width = (this.client_width - this.sep_right) + 'px'; - this.resizer_left.style('left', this.sep_left + 'px'); - this.resizer_right.style('right', (this.client_width - this.sep_right - 1) + 'px'); - - this.snapper.panesUpated(); - this.panes_updated_callback(); - } - - updateWidths() { - this.client_width = document.body.getBoundingClientRect().width; - this.sep_right = Math.min(this.sep_right, this.client_width); - this.sep_left = Math.min(Math.max(0, this.sep_left), this.sep_right); - } -} +import { SourceResolver } from "../src/source-resolver"; +import { SelectionBroker } from "../src/selection-broker"; +import { DisassemblyView } from "../src/disassembly-view"; +import { GraphMultiView } from "../src/graphmultiview"; +import { CodeMode, CodeView } from "../src/code-view"; +import { Tabs } from "../src/tabs"; +import { Resizer } from "../src/resizer"; +import * as C from "../src/constants"; +import { InfoView } from "./info-view"; window.onload = function () { - var svg = null; - var multiview = null; - var disassemblyView = null; - var sourceViews = []; - var selectionBroker = null; - var sourceResolver = null; - let resizer = new Resizer(panesUpdatedCallback, 100); + let multiview: GraphMultiView = null; + let disassemblyView: DisassemblyView = null; + let sourceViews: Array<CodeView> = []; + let selectionBroker: SelectionBroker = null; + let sourceResolver: SourceResolver = null; + const resizer = new Resizer(panesUpdatedCallback, 100); + const sourceTabsContainer = document.getElementById(C.SOURCE_PANE_ID); + const sourceTabs = new Tabs(sourceTabsContainer); + sourceTabs.addTab("+").classList.add("last-tab", "persistent-tab"); + const disassemblyTabsContainer = document.getElementById(C.GENERATED_PANE_ID); + const disassemblyTabs = new Tabs(disassemblyTabsContainer); + disassemblyTabs.addTab("+").classList.add("last-tab", "persistent-tab"); + const [infoTab, infoContainer] = sourceTabs.addTabAndContent("Info"); + infoTab.classList.add("persistent-tab"); + infoContainer.classList.add("viewpane", "scrollable"); + const infoView = new InfoView(infoContainer); + infoView.show(); + sourceTabs.activateTab(infoTab); function panesUpdatedCallback() { if (multiview) multiview.onresize(); } - function loadFile(txtRes) { + function loadFile(txtRes: string) { + sourceTabs.clearTabsAndContent(); + disassemblyTabs.clearTabsAndContent(); // If the JSON isn't properly terminated, assume compiler crashed and // add best-guess empty termination if (txtRes[txtRes.length - 2] == ',') { txtRes += '{"name":"disassembly","type":"disassembly","data":""}]}'; } try { - sourceViews.forEach((sv) => sv.hide()); + sourceViews.forEach(sv => sv.hide()); if (multiview) multiview.hide(); multiview = null; if (disassemblyView) disassemblyView.hide(); @@ -225,9 +55,9 @@ window.onload = function () { const jsonObj = JSON.parse(txtRes); - let fnc = jsonObj.function; + let fnc = null; // Backwards compatibility. - if (typeof fnc == 'string') { + if (typeof jsonObj.function == 'string') { fnc = { functionName: fnc, sourceId: -1, @@ -236,33 +66,42 @@ window.onload = function () { sourceText: jsonObj.source, backwardsCompatibility: true }; + } else { + fnc = Object.assign(jsonObj.function, { backwardsCompatibility: false }); } sourceResolver.setInlinings(jsonObj.inlinings); sourceResolver.setSourceLineToBytecodePosition(jsonObj.sourceLineToBytecodePosition); - sourceResolver.setSources(jsonObj.sources, fnc) + sourceResolver.setSources(jsonObj.sources, fnc); sourceResolver.setNodePositionMap(jsonObj.nodePositions); sourceResolver.parsePhases(jsonObj.phases); - let sourceView = new CodeView(C.SOURCE_PANE_ID, selectionBroker, sourceResolver, fnc, CodeMode.MAIN_SOURCE); - sourceView.show(null, null); + const [sourceTab, sourceContainer] = sourceTabs.addTabAndContent("Source"); + sourceContainer.classList.add("viewpane", "scrollable"); + sourceTabs.activateTab(sourceTab); + const sourceView = new CodeView(sourceContainer, selectionBroker, sourceResolver, fnc, CodeMode.MAIN_SOURCE); + sourceView.show(); sourceViews.push(sourceView); - sourceResolver.forEachSource((source) => { - let sourceView = new CodeView(C.SOURCE_PANE_ID, selectionBroker, sourceResolver, source, CodeMode.INLINED_SOURCE); - sourceView.show(null, null); + sourceResolver.forEachSource(source => { + const sourceView = new CodeView(sourceContainer, selectionBroker, sourceResolver, source, CodeMode.INLINED_SOURCE); + sourceView.show(); sourceViews.push(sourceView); }); - disassemblyView = new DisassemblyView(C.GENERATED_PANE_ID, selectionBroker); + const [disassemblyTab, disassemblyContainer] = disassemblyTabs.addTabAndContent("Disassembly"); + disassemblyContainer.classList.add("viewpane", "scrollable"); + disassemblyTabs.activateTab(disassemblyTab); + disassemblyView = new DisassemblyView(disassemblyContainer, selectionBroker); disassemblyView.initializeCode(fnc.sourceText); if (sourceResolver.disassemblyPhase) { disassemblyView.initializePerfProfile(jsonObj.eventCounts); - disassemblyView.show(sourceResolver.disassemblyPhase.data, null); + disassemblyView.showContent(sourceResolver.disassemblyPhase.data); + disassemblyView.show(); } multiview = new GraphMultiView(C.INTERMEDIATE_PANE_ID, selectionBroker, sourceResolver); - multiview.show(jsonObj); + multiview.show(); } catch (err) { if (window.confirm("Error: Exception during load of TurboFan JSON file:\n" + "error: " + err.message + "\nDo you want to clear session storage?")) { @@ -276,26 +115,34 @@ window.onload = function () { // The <input> form #upload-helper with type file can't be a picture. // We hence keep it hidden, and forward the click from the picture // button #upload. - d3.select("#upload").on("click", - () => document.getElementById("upload-helper").click()); - d3.select("#upload-helper").on("change", function (this: HTMLInputElement) { - var uploadFile = this.files && this.files[0]; - var filereader = new FileReader(); - filereader.onload = function (e) { - var txtRes = e.target.result; - loadFile(txtRes); - }; - if (uploadFile) - filereader.readAsText(uploadFile); + document.getElementById("upload").addEventListener("click", e => { + document.getElementById("upload-helper").click(); + e.stopPropagation(); + }); + document.getElementById("upload-helper").addEventListener("change", + function (this: HTMLInputElement) { + const uploadFile = this.files && this.files[0]; + if (uploadFile) { + const filereader = new FileReader(); + filereader.onload = () => { + const txtRes = filereader.result; + if (typeof txtRes == 'string') { + loadFile(txtRes); + } + }; + filereader.readAsText(uploadFile); + } + } + ); + window.addEventListener("keydown", (e: KeyboardEvent) => { + if (e.keyCode == 76 && e.ctrlKey) { // CTRL + L + document.getElementById("upload-helper").click(); + e.stopPropagation(); + e.preventDefault(); + } }); } initializeUploadHandlers(); - - - resizer.snapper.setSourceExpanded(resizer.snapper.getLastExpandedState("source", true)); - resizer.snapper.setDisassemblyExpanded(resizer.snapper.getLastExpandedState("disassembly", false)); - resizer.updatePanes(); - }; diff --git a/deps/v8/tools/turbolizer/src/util.ts b/deps/v8/tools/turbolizer/src/util.ts index ef877e508c..d9c8dcdce0 100644 --- a/deps/v8/tools/turbolizer/src/util.ts +++ b/deps/v8/tools/turbolizer/src/util.ts @@ -32,7 +32,7 @@ export class ViewElements { if (!doConsider) return; const newScrollTop = computeScrollTop(this.container, element); if (isNaN(newScrollTop)) { - console.log("NOO") + console.log("NOO"); } if (this.scrollTop === undefined) { this.scrollTop = newScrollTop; @@ -47,50 +47,11 @@ export class ViewElements { } } - -function lowerBound(a, value, compare, lookup) { - let first = 0; - let count = a.length; - while (count > 0) { - let step = Math.floor(count / 2); - let middle = first + step; - let middle_value = (lookup === undefined) ? a[middle] : lookup(a, middle); - let result = (compare === undefined) ? (middle_value < value) : compare(middle_value, value); - if (result) { - first = middle + 1; - count -= step + 1; - } else { - count = step; - } - } - return first; -} - - -function upperBound(a, value, compare, lookup) { - let first = 0; - let count = a.length; - while (count > 0) { - let step = Math.floor(count / 2); - let middle = first + step; - let middle_value = (lookup === undefined) ? a[middle] : lookup(a, middle); - let result = (compare === undefined) ? (value < middle_value) : compare(value, middle_value); - if (!result) { - first = middle + 1; - count -= step + 1; - } else { - count = step; - } - } - return first; -} - - export function sortUnique<T>(arr: Array<T>, f: (a: T, b: T) => number, equal: (a: T, b: T) => boolean) { if (arr.length == 0) return arr; arr = arr.sort(f); - let ret = [arr[0]]; - for (var i = 1; i < arr.length; i++) { + const ret = [arr[0]]; + for (let i = 1; i < arr.length; i++) { if (!equal(arr[i - 1], arr[i])) { ret.push(arr[i]); } @@ -99,11 +60,10 @@ export function sortUnique<T>(arr: Array<T>, f: (a: T, b: T) => number, equal: ( } // Partial application without binding the receiver -export function partial(f, ...arguments1) { - return function (...arguments2) { - var arguments2 = Array.from(arguments); +export function partial(f: any, ...arguments1: Array<any>) { + return function (this: any, ...arguments2: Array<any>) { f.apply(this, [...arguments1, ...arguments2]); - } + }; } export function isIterable(obj: any): obj is Iterable<any> { @@ -111,6 +71,23 @@ export function isIterable(obj: any): obj is Iterable<any> { && typeof obj != 'string' && typeof obj[Symbol.iterator] === 'function'; } -export function alignUp(raw:number, multiple:number):number { +export function alignUp(raw: number, multiple: number): number { return Math.floor((raw + multiple - 1) / multiple) * multiple; } + +export function measureText(text: string) { + const textMeasure = document.getElementById('text-measure'); + if (textMeasure instanceof SVGTSpanElement) { + textMeasure.textContent = text; + return { + width: textMeasure.getBBox().width, + height: textMeasure.getBBox().height, + }; + } + return { width: 0, height: 0 }; +} + +// Interpolate between the given start and end values by a fraction of val/max. +export function interpolate(val: number, max: number, start: number, end: number) { + return start + (end - start) * (val / max); +} diff --git a/deps/v8/tools/turbolizer/src/view.ts b/deps/v8/tools/turbolizer/src/view.ts index dbb8514fe2..a8bb125fc4 100644 --- a/deps/v8/tools/turbolizer/src/view.ts +++ b/deps/v8/tools/turbolizer/src/view.ts @@ -3,34 +3,35 @@ // found in the LICENSE file. export abstract class View { - container: HTMLElement; - divNode: HTMLElement; - abstract initializeContent(data: any, rememberedSelection: Selection): void; - abstract createViewElement(): HTMLElement; - abstract deleteContent(): void; - abstract detachSelection(): Set<string>; + protected container: HTMLElement; + protected divNode: HTMLElement; + protected abstract createViewElement(): HTMLElement; - constructor(id) { - this.container = document.getElementById(id); + constructor(idOrContainer: string | HTMLElement) { + this.container = typeof idOrContainer == "string" ? document.getElementById(idOrContainer) : idOrContainer; this.divNode = this.createViewElement(); } - isScrollable(): boolean { - return false; - } - - show(data, rememberedSelection): void { + public show(): void { this.container.appendChild(this.divNode); - this.initializeContent(data, rememberedSelection); } - hide(): void { - this.deleteContent(); + public hide(): void { this.container.removeChild(this.divNode); } } -export interface PhaseView { - onresize(); - searchInputAction(searchInput: HTMLInputElement, e: Event); +export abstract class PhaseView extends View { + public abstract initializeContent(data: any, rememberedSelection: Set<any>): void; + public abstract detachSelection(): Set<string>; + public abstract onresize(): void; + public abstract searchInputAction(searchInput: HTMLInputElement, e: Event, onlyVisible: boolean): void; + + constructor(idOrContainer: string | HTMLElement) { + super(idOrContainer); + } + + public isScrollable(): boolean { + return false; + } } diff --git a/deps/v8/tools/turbolizer/tabs.css b/deps/v8/tools/turbolizer/tabs.css new file mode 100644 index 0000000000..54dba72b70 --- /dev/null +++ b/deps/v8/tools/turbolizer/tabs.css @@ -0,0 +1,55 @@ +.content { + display: grid; + grid-template-areas: "tabs" "window"; + grid-template-columns: 1fr; + grid-template-rows: auto 1fr; + min-height: calc(100vh); +} + +.nav-tabs-container { + grid-area: tabs; + padding: 0px; + background-color: #999999; + border-bottom: 4px solid #CCCCCC; +} + +.tab-content { + grid-area: window; + background-color: white; + padding: 0px; + display:none; +} + +.tab-content.tab-default { + display: block; +} + +ul.nav-tabs { + padding: 0px; + margin: 0px; + overflow: auto; + display: table-row; + min-height: 2ex; +} + +.nav-tabs li { + display: inline-block; + padding-left: 10px; + padding-right: 10px; + padding-top: 4px; + padding-bottom: 4px; + min-width: 20px; + text-decoration: none; + color: black; + text-align: center; + user-select: none; + cursor: pointer; +} + +.nav-tabs li:hover { + background-color: #EEEEEE; +} + +.nav-tabs li.active { + background-color: #CCCCCC; +}
\ No newline at end of file diff --git a/deps/v8/tools/turbolizer/test/source-resolver-test.ts b/deps/v8/tools/turbolizer/test/source-resolver-test.ts new file mode 100644 index 0000000000..38d674510f --- /dev/null +++ b/deps/v8/tools/turbolizer/test/source-resolver-test.ts @@ -0,0 +1,10 @@ +import { SourceResolver } from '../src/source-resolver'; +import { expect } from 'chai'; +import { describe, it } from 'mocha'; + +describe('SourceResolver', () => { + it('should be constructible', () => { + const a: SourceResolver = new SourceResolver(); + expect(a.sources.length).to.equal(0); + }); +}); diff --git a/deps/v8/tools/turbolizer/tsconfig.json b/deps/v8/tools/turbolizer/tsconfig.json index c54157280f..cd036ac3ab 100644 --- a/deps/v8/tools/turbolizer/tsconfig.json +++ b/deps/v8/tools/turbolizer/tsconfig.json @@ -1,32 +1,39 @@ { - "compilerOptions": { - "outDir": "build/", - "allowJs": false, - "target": "es2017", - "module": "es2015", - "sourceMap": true, - "experimentalDecorators": true, - "emitDecoratorMetadata": true, - "moduleResolution": "node" - }, - "files": [ - "src/util.ts", - "src/lang-disassembly.ts", - "src/node.ts", - "src/edge.ts", - "src/source-resolver.ts", - "src/selection.ts", - "src/selection-broker.ts", - "src/selection-handler.ts", - "src/constants.ts", - "src/view.ts", - "src/text-view.ts", - "src/code-view.ts", - "src/graph-layout.ts", - "src/graph-view.ts", - "src/schedule-view.ts", - "src/disassembly-view.ts", - "src/graphmultiview.ts", - "src/turbo-visualizer.ts" - ] + "compilerOptions": { + "outDir": "build/", + "allowJs": false, + "target": "es2018", + "module": "es2015", + "sourceMap": true, + "experimentalDecorators": true, + "emitDecoratorMetadata": true, + "moduleResolution": "node", + "noUnusedLocals": true, + "noImplicitReturns": true, + "noImplicitThis": true, + "lib": ["dom", "es6", "dom.iterable", "scripthost", "es2018"] + }, + "files": [ + "src/util.ts", + "src/node.ts", + "src/edge.ts", + "src/graph.ts", + "src/node-label.ts", + "src/source-resolver.ts", + "src/selection.ts", + "src/selection-broker.ts", + "src/selection-handler.ts", + "src/constants.ts", + "src/view.ts", + "src/text-view.ts", + "src/code-view.ts", + "src/graph-layout.ts", + "src/graph-view.ts", + "src/schedule-view.ts", + "src/disassembly-view.ts", + "src/graphmultiview.ts", + "src/turbo-visualizer.ts", + "src/resizer.ts", + "src/info-view.ts" + ] } diff --git a/deps/v8/tools/turbolizer/tsconfig.test.json b/deps/v8/tools/turbolizer/tsconfig.test.json new file mode 100644 index 0000000000..1b7a59159d --- /dev/null +++ b/deps/v8/tools/turbolizer/tsconfig.test.json @@ -0,0 +1,6 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "module": "commonjs" + } +} diff --git a/deps/v8/tools/turbolizer/tslint.json b/deps/v8/tools/turbolizer/tslint.json new file mode 100644 index 0000000000..e07e057a62 --- /dev/null +++ b/deps/v8/tools/turbolizer/tslint.json @@ -0,0 +1,45 @@ +{ + "defaultSeverity": "error", + "extends": "tslint:recommended", + "jsRules": {}, + "rules": { + "curly": [true, "ignore-same-line"], + "quotemark": [false, "double", "avoid-escape", "avoid-template"], + "only-arrow-functions": [false], + "no-var-keyword": true, + "prefer-const": [true], + "max-line-length": [false, { + "limit": 80 + }], + "ordered-imports": false, + "array-type": [true, "generic"], + "semicolon": true, + "member-access": false, + "object-literal-shorthand": false, + "object-literal-key-quotes": [true, "as-needed"], + "object-literal-sort-keys": false, + "space-before-function-paren": [true, { + "anonymous": "always" + }], + "triple-equals": false, + "no-string-throw": false, + "no-empty": [true, "allow-empty-catch", "allow-empty-functions"], + "trailing-comma": false, + "member-ordering": false, + "no-string-literal": false, + "arrow-parens": [true, "ban-single-arg-parens"], + "no-console": false, + "interface-name": false, + "no-bitwise": false, + "no-shadowed-variable": false, + "prefer-for-of": true, + "align": true, + "arrow-return-shorthand": true, + "max-classes-per-file": false, + "variable-name": true, + "forin": false, + "one-variable-per-declaration": true, + "no-consecutive-blank-lines": true + }, + "rulesDirectory": [] +} diff --git a/deps/v8/tools/turbolizer/turbo-visualizer.css b/deps/v8/tools/turbolizer/turbo-visualizer.css index c7d45a7ee2..b37dcc498b 100644 --- a/deps/v8/tools/turbolizer/turbo-visualizer.css +++ b/deps/v8/tools/turbolizer/turbo-visualizer.css @@ -1,58 +1,69 @@ .visible-transition { - transition-delay: 0s; - transition-duration: 1s; - transition-property: all; - transition-timing-function: ease; + transition-delay: 0s; + transition-duration: 1s; + transition-property: all; + transition-timing-function: ease; } .collapse-pane { - background: #A0A0A0; - bottom: 0; - position: absolute; - margin-bottom: 0.5em; - margin-right: 0.5em; - margin-left: 0.5em; - border-radius: 5px; - padding: 0.5em; - z-index: 5; - opacity: 0.7; - cursor: pointer; + background: #A0A0A0; + bottom: 0; + position: absolute; + margin-bottom: 0.5em; + margin-right: 0.5em; + margin-left: 0.5em; + border-radius: 5px; + padding: 0.5em; + z-index: 20; + opacity: 0.7; + cursor: pointer; } .search-input { - vertical-align: middle; - width: 145px; - opacity: 1; + vertical-align: middle; + width: 145px; + opacity: 1; + box-sizing: border-box; + height: 1.5em; +} + +#phase-select { + box-sizing: border-box; + height: 1.5em; +} + +#search-only-visible { + vertical-align: middle; } .button-input { - vertical-align: middle; - width: 24px; - opacity: 0.4; - cursor: pointer; + vertical-align: middle; + width: 24px; + opacity: 0.4; + cursor: pointer; } .button-input-toggled { - border-radius: 5px; - background-color: #505050; + border-radius: 5px; + background-color: #505050; } .button-input:focus { - outline: none; + outline: none; } .invisible { - display: none; + display: none; } .selected { - background-color: #FFFF33; + background-color: #FFFF33; } .selected.block, .selected.block-id, .selected.schedule-block { - background-color: #AAFFAA; + background-color: #AAFFAA; } ol.linenums { @@ -60,120 +71,142 @@ ol.linenums { } .line-number { - display:inline-block; - min-width: 3ex; - text-align: right; - color: #444444; - margin-right: 0.5ex; - padding-right: 0.5ex; - background: #EEEEEE; - /* font-size: 80%; */ - user-select: none; - height: 120%; + display: inline-block; + min-width: 3ex; + text-align: right; + color: #444444; + margin-right: 0.5ex; + padding-right: 0.5ex; + background: #EEEEEE; + /* font-size: 80%; */ + user-select: none; + height: 120%; } .line-number:hover { - background-color: #CCCCCC; + background-color: #CCCCCC; } -.prettyprint ol.linenums > li.selected { - background-color: #FFFF33 !important; +.prettyprint ol.linenums>li.selected { + background-color: #FFFF33 !important; } li.selected .line-number { - background-color: #FFFF33; + background-color: #FFFF33; } -.prettyprint ol.linenums > li { - list-style-type: decimal; - display: block; +.prettyprint ol.linenums>li { + list-style-type: decimal; + display: block; } .source-container { - border-bottom: 2px solid #AAAAAA; + border-bottom: 2px solid #AAAAAA; } .code-header { - background-color: #CCCCCC; - padding-left: 1em; - padding-right: 1em; - padding-top: 1ex; - padding-bottom: 1ex; - font-family: monospace; - user-select: none; + background-color: #CCCCCC; + padding-left: 1em; + padding-right: 1em; + padding-top: 1ex; + padding-bottom: 1ex; + font-family: monospace; + user-select: none; } .main-source .code-header { - border-top: 2px solid #AAAAAA; - font-weight: bold; + border-top: 2px solid #AAAAAA; + font-weight: bold; } .code-header .code-file-function { - font-family: monospace; - float: left; - user-select: text; + font-family: monospace; + float: left; + user-select: text; } .code-header .code-mode { - float: right; - font-family: sans-serif; - font-size: small; + float: right; + font-family: sans-serif; + font-size: small; +} + +.info-container { + font-family: sans-serif; + font-size: small; +} + +.info-topic { + border: 1px solid lightgray; + margin: 2px; } -html, body { - margin: 0; - padding: 0; - /*height: 99vh; +.info-topic-header { + background-color: lightgray; + padding: 1px; +} + +.info-topic-content { + padding: 2px; +} + + +html, +body { + margin: 0; + padding: 0; + /*height: 99vh; width: 99vw;*/ - overflow: hidden; + overflow: hidden; } p { - text-align: center; - overflow: overlay; - position: relative; + text-align: center; + overflow: overlay; + position: relative; } marker { - fill: #080808; + fill: #080808; } g rect { - fill: #F0F0F0; - stroke: #080808; - stroke-width: 2px; + fill: #F0F0F0; + stroke: #080808; + stroke-width: 2px; } g.dead { - opacity: .5; + opacity: .5; } g.unsorted rect { - opacity: 0.5; + opacity: 0.5; } div.scrollable { - overflow-y: auto; overflow-x: hidden; + overflow-y: auto; + overflow-x: hidden; } g.turbonode[relToHover="input"] rect { - stroke: #67e62c; - stroke-width: 16px; + stroke: #67e62c; + stroke-width: 16px; } g.turbonode[relToHover="output"] rect { - stroke: #d23b14; - stroke-width: 16px; + stroke: #d23b14; + stroke-width: 16px; } path[relToHover="input"] { - stroke: #67e62c; - stroke-width: 16px; + stroke: #67e62c; + stroke-width: 16px; } path[relToHover="output"] { - stroke: #d23b14; - stroke-width: 16px; + stroke: #d23b14; + stroke-width: 16px; } @@ -183,82 +216,82 @@ g.turbonode:hover rect { } g.control rect { - fill: #EFCC00; - stroke: #080808; - stroke-width: 5px; + fill: #EFCC00; + stroke: #080808; + stroke-width: 5px; } g.javascript rect { - fill: #DD7E6B; + fill: #DD7E6B; } g.simplified rect { - fill: #3C78D8; + fill: #3C78D8; } g.machine rect { - fill: #6AA84F; + fill: #6AA84F; } g.input rect { - fill: #CFE2F3; + fill: #CFE2F3; } g.selected rect { - fill: #FFFF33; + fill: #FFFF33; } circle.bubbleStyle { - fill: #080808; - fill-opacity: 0.0; - stroke: #080808; - stroke-width: 2px; + fill: #080808; + fill-opacity: 0.0; + stroke: #080808; + stroke-width: 2px; } circle.bubbleStyle:hover { - stroke-width: 3px; + stroke-width: 3px; } circle.filledBubbleStyle { - fill: #080808; - stroke: #080808; - stroke-width: 2px; + fill: #080808; + stroke: #080808; + stroke-width: 2px; } circle.filledBubbleStyle:hover { - fill: #080808; - stroke-width: 3px; + fill: #080808; + stroke-width: 3px; } circle.halfFilledBubbleStyle { - fill: #808080; - stroke: #101010; - stroke-width: 2px; + fill: #808080; + stroke: #101010; + stroke-width: 2px; } circle.halfFilledBubbleStyle:hover { - fill: #808080; - stroke-width: 3px; + fill: #808080; + stroke-width: 3px; } path { - fill: none; - stroke: #080808; - stroke-width: 4px; - cursor: default; + fill: none; + stroke: #080808; + stroke-width: 4px; + cursor: default; } path:hover { - stroke-width: 6px; + stroke-width: 6px; } path.hidden { - fill: none; - stroke-width: 0; + fill: none; + stroke-width: 0; } path.link.selected { - stroke: #FFFF33; + stroke: #FFFF33; } pre.prettyprint { @@ -271,11 +304,11 @@ li.L3, li.L5, li.L7, li.L9 { - background: none !important + background: none !important } li.nolinenums { - list-style-type:none; + list-style-type: none; } ul.noindent { @@ -284,151 +317,142 @@ ul.noindent { -webkit-margin-after: 0px; } -input:hover, .collapse-pane:hover input { - opacity: 1; - cursor: pointer; +input:hover, +.collapse-pane:hover input { + opacity: 1; + cursor: pointer; } -span.linkable-text { - text-decoration: underline; +.linkable-text { + text-decoration: underline; } -span.linkable-text:hover { - cursor: pointer; - font-weight: bold; +.linkable-text:hover { + cursor: pointer; + font-weight: bold; } #left { - float: left; - user-select: none; + float: left; + user-select: none; } #middle { - float:left; - background-color: #F8F8F8; - user-select: none; + float: left; + background-color: #F8F8F8; + user-select: none; } #right { - float: right; + float: right; } .viewpane { - height: 100vh; - background-color: #FFFFFF; + height: 100vh; + background-color: #FFFFFF; +} + +.multiview { + width: 100%; } #disassembly-collapse { - right: 0; + right: 0; } #source-collapse { - left: 0; + left: 0; } #graph { - width: 100%; - height: 100%; + width: 100%; + height: 100%; } -#graph-toolbox-anchor { - height: 0px; +.toolbox-anchor { + height: 0px; } -#graph-toolbox { - position: relative; - top: 1em; - left: 25px; - border: 2px solid #eee8d5; - border-radius: 5px; - padding: 0.7em; - z-index: 5; - background: rgba(100%, 100%, 100%, 0.7); +.graph-toolbox { + position: relative; + border-bottom: 2px solid #eee8d5; + z-index: 5; + background: rgba(100%, 100%, 100%, 0.7); + box-sizing: border-box; + padding: 3px; + margin-left: 4px; + margin-right: 4px; } -#disassembly-toolbox { - position: relative; - top: 1em; - left: 0.7em; - border: 2px solid #eee8d5; - border-radius: 5px; - padding: 0.7em; - z-index: 5; +.disassembly-toolbox { + position: relative; + padding-bottom: 3px; + z-index: 5; + background: rgba(100%, 100%, 100%, 0.7); + padding-top: 3px; + box-sizing: border-box; + margin-left: 4px; + margin-right: 4px; } #load-file { - position: absolute; - top: 0; - right: 0; - margin-top: 0.5em; - margin-right: 0.5em; - z-index: 5; - opacity: 0.7; + position: absolute; + top: 0; + right: 0; + margin-top: 0.5em; + margin-right: 0.5em; + z-index: 20; + opacity: 0.7; } #load-file input { - background: #A0A0A0; - border-radius: 5px; - padding: 0.5em; + background: #A0A0A0; + border-radius: 5px; + padding: 0.5em; } #upload-helper { - display: none; + display: none; } .prof { - cursor: default; + cursor: default; } tspan { - font-size: 500%; - font-family: sans-serif; + font-size: 500%; + font-family: sans-serif; } text { - dominant-baseline: text-before-edge; -} - -.resizer-left { - position:absolute; - width: 4px; - height:100%; - background: #a0a0a0; - cursor: pointer; + dominant-baseline: text-before-edge; } -.resizer-left.snapped { - width: 12px; +.resizer { + position: absolute; + z-index: 10; + width: 4px; + height: 100%; + background: #a0a0a0; + cursor: pointer; } -.resizer-left:hover { - background: orange; +.resizer.snapped { + width: 12px; } -.resizer-left.dragged { - background: orange; +.resizer.snapped:hover { + width: 12px; + margin-left: 0px; } -.resizer-right { - position:absolute; - width: 4px; - height:100%; - background: #a0a0a0; - cursor: pointer; -} - -.resizer-right.snapped { - width: 12px; -} - -.resizer-right:hover { - background: orange; -} - -.resizer-right.dragged { - background: orange; +.resizer:hover, +.resizer.dragged { + width: 10px; + margin-left: -4px; + background: orange; } .source-position { @@ -438,227 +462,233 @@ text { } .source-position .inlining-marker { - content: ""; - position: relative; - display: inline-block; - top: -0.5ex; - margin-left: -4px; - margin-right: -4px; - border-width: 5px; - border-style: solid; - border-color: #555 transparent transparent transparent; + content: ""; + position: relative; + display: inline-block; + top: -0.5ex; + margin-left: -4px; + margin-right: -4px; + border-width: 5px; + border-style: solid; + border-color: #555 transparent transparent transparent; } .source-position .marker { - content: ""; - display: inline-block; - position: relative; - bottom: -1ex; - width: 0px; - margin-left: -4px; - margin-right: -4px; - border-width: 5px; - border-style: solid; - border-color: transparent transparent #555 transparent; + content: ""; + display: inline-block; + bottom: -1ex; + width: 0px; + margin-left: -4px; + margin-right: -4px; + margin-bottom: -1ex; + border-width: 5px; + border-style: solid; + border-color: transparent transparent #555 transparent; } .source-position.selected .marker { - border-color: transparent transparent #F00 transparent; + border-color: transparent transparent #F00 transparent; } .source-position .inlining-marker:hover { - border-color: transparent transparent #AA5 transparent; + border-color: transparent transparent #AA5 transparent; } .source-position .inlining-marker[data-descr]:hover::after { - content: attr(data-descr); - position: absolute; - font-size: 10px; - z-index: 1; - background-color: #555; - color: #fff; - text-align: center; - border-radius: 6px; - padding: 6px; - top: 6px; - left: 50%; - margin-left: -80px; + content: attr(data-descr); + position: absolute; + font-size: 10px; + z-index: 1; + background-color: #555; + color: #fff; + text-align: center; + border-radius: 6px; + padding: 6px; + top: 6px; + left: 50%; + margin-left: -80px; } #sequence { - font-family: monospace; - margin-top: 50px; + font-family: monospace; + margin-top: 50px; } #schedule { - font-family: monospace; - margin-top: 50px; + font-family: monospace; + margin-top: 50px; } .schedule-block { - margin: 5px; - background-color: white; - padding-left: 5px; + margin: 5px; + background-color: white; + padding-left: 5px; } .schedule-block .block-id { - display: inline-block; - font-size:large; - text-decoration: underline; - padding-left: 1ex; + display: inline-block; + font-size: large; + text-decoration: underline; + padding-left: 1ex; } .schedule-block .block-id:hover { - font-weight: bold; + font-weight: bold; } -.schedule-block > .block-id::before { - content: "Block B"; +.schedule-block>.block-id::before { + content: "Block B"; } .schedule-block .block-list { - display: inline-block; + display: inline-block; } .schedule-block .block-list * { - display: inline-block; + display: inline-block; } .schedule-block .block-list .block-id { - padding-left: 1ex; + padding-left: 1ex; } .schedule-block .block-list .block-id:before { - content: "B"; + content: "B"; } .schedule-block .predecessor-list::before { - display: inline-block; - content: " \2B05 "; - padding-left: 1ex; - padding-right: 1ex; + display: inline-block; + content: " \2B05 "; + padding-left: 1ex; + padding-right: 1ex; } .schedule-block .successor-list::before { - display: inline-block; - content: " \2B95 "; - padding-left: 1ex; - padding-right: 1ex; + display: inline-block; + content: " \2B95 "; + padding-left: 1ex; + padding-right: 1ex; } .schedule-block .nodes .node * { - display:inline-block; + display: inline-block; } .schedule-block .nodes .node .node-id { - padding-right: 1ex; - min-width: 5ex; - text-align: right; + padding-right: 1ex; + min-width: 5ex; + text-align: right; } .schedule-block .nodes .node .node-id:after { - content: ":"; + content: ":"; } .schedule-block .nodes .node .node-label { - user-select: text; + user-select: text; } .schedule-block .nodes .node .parameter-list:before { - content: "("; + content: "("; } .schedule-block .nodes .node .parameter-list:after { - content: ")"; + content: ")"; } .schedule-block .instr-marker { - padding-right: .5ex; - padding-left: .5ex; - min-width: 1ex; - background: #EEEEEE; - /* display: none; */ + padding-right: .5ex; + padding-left: .5ex; + min-width: 1em; + background: #EEEEEE; + /* display: none; */ } -.schedule-block > .instr-marker { - display: inline; +.schedule-block>.instr-marker { + display: inline; } .instruction * { - padding-right: .5ex; + padding-right: .5ex; } -.phi-label, .instruction-id { - display: inline-block; - padding-right: .5ex; - padding-left: .5ex; - min-width: 1ex; - vertical-align: top; +.phi-label, +.instruction-id { + display: inline-block; + padding-right: .5ex; + padding-left: .5ex; + min-width: 1ex; + vertical-align: top; } .instruction-id:after { - content: ":"; + content: ":"; } -.instruction-node, .gap, .instruction { - display: block; +.instruction-node, +.gap, +.instruction { + display: block; } -.phi-contents, .instruction-contents, .gap *, .instruction * { - display: inline-block; +.phi-contents, +.instruction-contents, +.gap *, +.instruction * { + display: inline-block; } .phi * { - padding-right: 1ex; - display: inline-block; + padding-right: 1ex; + display: inline-block; } .gap .gap-move { - padding-left: .5ex; - padding-right: .5ex; + padding-left: .5ex; + padding-right: .5ex; } -.gap > *:before { - content: "("; +.gap>*:before { + content: "("; } -.gap > *:after { - content: ")"; +.gap>*:after { + content: ")"; } .parameter.constant { - outline: 1px dotted red; + outline: 1px dotted red; } .clickable:hover { - text-decoration: underline; + text-decoration: underline; } .clickable:hover { - font-weight: bold; + font-weight: bold; } -.comma-sep-list > * { - padding-right: 1ex; +.comma-sep-list>* { + padding-right: 1ex; } -.comma-sep-list > *:after { - content: ","; +.comma-sep-list>*:after { + content: ","; } -.comma-sep-list > *:last-child:after { - content: ""; +.comma-sep-list>*:last-child:after { + content: ""; } -.comma-sep-list > *:last-child { - padding-right: 0ex; +.comma-sep-list>*:last-child { + padding-right: 0ex; } .temps:before { - content: "temps: "; + content: "temps: "; } .temps { - padding-left: .5ex; - outline: 1px dotted grey; + padding-left: .5ex; + outline: 1px dotted grey; } |