diff --git "a/js/addon-entry-debugger.js" "b/js/addon-entry-debugger.js" new file mode 100644--- /dev/null +++ "b/js/addon-entry-debugger.js" @@ -0,0 +1,2293 @@ +(window["webpackJsonpGUI"] = window["webpackJsonpGUI"] || []).push([["addon-entry-debugger"],{ + +/***/ "./node_modules/css-loader/index.js!./src/addons/addons/debugger/style.css": +/*!************************************************************************!*\ + !*** ./node_modules/css-loader!./src/addons/addons/debugger/style.css ***! + \************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +var escape = __webpack_require__(/*! ../../../../node_modules/css-loader/lib/url/escape.js */ "./node_modules/css-loader/lib/url/escape.js"); +exports = module.exports = __webpack_require__(/*! ../../../../node_modules/css-loader/lib/css-base.js */ "./node_modules/css-loader/lib/css-base.js")(false); +// imports +exports.i(__webpack_require__(/*! -!../../../../node_modules/css-loader!../editor-theme3/compatibility.css */ "./node_modules/css-loader/index.js!./src/addons/addons/editor-theme3/compatibility.css"), ""); + +// module +exports.push([module.i, "[dir=\"ltr\"] .sa-debugger-container {\n margin-right: 0.2rem;\n}\n\n[dir=\"rtl\"] .sa-debugger-container {\n margin-left: 0.2rem;\n}\n\n.sa-debugger-small .sa-debugger-container {\n display: none !important;\n}\n\n.sa-debugger-container [class*=\"button_content_\"] {\n position: relative;\n}\n\n.sa-debugger-unread::after {\n content: \"\";\n position: absolute;\n top: 1px;\n right: 0;\n display: block;\n width: 6px;\n height: 6px;\n background-color: var(--editorDarkMode-highlightText, #4d97ff);\n border-radius: 50%;\n}\n\n.sa-debugger-interface {\n display: none;\n position: absolute;\n z-index: 492;\n background-color: white;\n width: 565px;\n height: 25rem;\n}\n[theme=\"dark\"] .sa-debugger-interface {\n background: var(--ui-primary);\n}\n\n.sa-debugger-interface [class*=\"card_header-buttons_\"] {\n background-color: #29beb8;\n border-color: #3aa8a4;\n}\n\n.sa-debugger-interface h1 {\n padding: 10px;\n z-index: 10;\n width: calc(100% - 20px);\n font-size: 20px;\n}\n\n.sa-debugger-tabs {\n margin: 0;\n display: flex;\n align-items: center;\n padding: 0 15px;\n font-size: 0.75rem;\n}\n.sa-debugger-tabs li {\n margin: 0;\n display: flex;\n align-items: center;\n padding: 0.5em 1em;\n background-color: rgba(0, 0, 0, 0.1);\n border: 1px solid rgba(0, 0, 0, 0.15);\n border-radius: 1rem;\n color: white;\n cursor: pointer;\n}\n.sa-debugger-tabs li + li {\n margin-inline-start: 10px;\n}\n.sa-debugger-tabs li:hover {\n background-color: rgba(0, 0, 0, 0.15);\n}\n.sa-debugger-tabs li.sa-debugger-tab-selected {\n background-color: white;\n background-clip: padding-box;\n border-color: rgba(0, 0, 0, 0.25);\n color: #4d97ff;\n}\n.sa-debugger-tabs li img {\n margin: 0;\n margin-right: 0.25rem;\n width: 1rem;\n filter: brightness(0) invert(1);\n}\n.sa-debugger-tabs li.sa-debugger-tab-selected img {\n filter: none;\n}\n\n.sa-debugger-header-buttons img {\n width: 20px;\n height: 20px;\n}\n\n.sa-debugger-unpause {\n animation: saDebuggerUnpause 2s infinite alternate;\n}\n\n@keyframes saDebuggerUnpause {\n 0% {\n background-color: rgba(0, 0, 0, 0.15);\n }\n 100% {\n background-color: rgba(0, 0, 0, 0);\n }\n}\n\n.sa-debugger-tab-content {\n width: 100%;\n height: 100%;\n overflow: auto;\n cursor: auto;\n}\n\n.sa-debugger-chart {\n width: 100%;\n height: 100%;\n}\n\n.sa-performance-tab-content {\n padding: 15px;\n}\n\n.sa-debugger-log-outer {\n height: 100%;\n}\n\n.sa-debugger-log-inner {\n position: relative;\n overflow-y: auto;\n font-size: 12px;\n line-height: 1.2;\n height: 100%;\n contain: strict;\n}\n\n.sa-debugger-log-empty {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 100%;\n height: 100%;\n font-size: 20px;\n font-style: italic;\n}\n\n.sa-debugger-log-end {\n position: absolute;\n top: 0;\n left: 0;\n width: 1px;\n height: 1px;\n}\n\n.sa-debugger-log {\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 20px;\n box-sizing: border-box;\n display: flex;\n align-items: center;\n border-bottom: 1px solid rgba(0, 0, 0, 0.15);\n padding-left: 4px;\n font-family: monospace;\n color: #000;\n}\n[theme=\"dark\"] .sa-debugger-log {\n color: var(--text-primary);\n border-color: rgba(255, 255, 255, 0.15);\n}\n.sa-debugger-log[data-type=\"warn\"] {\n border-color: hsl(50deg, 100%, 75%);\n color: hsl(39deg 100% 18%);\n background-color: hsl(50deg 100% 95%);\n}\n.sa-debugger-log[data-type=\"error\"] {\n border-color: hsl(0deg 100% 92%);\n color: red;\n background-color: hsl(0deg 100% 95%);\n}\n[theme=\"dark\"] .sa-debugger-log[data-type=\"warn\"] {\n border-color: hsl(50deg, 100%, 15%);\n color: hsl(39deg 100% 90%);\n background-color: hsl(50deg 100% 10%);\n}\n[theme=\"dark\"] .sa-debugger-log[data-type=\"error\"] {\n border-color: hsl(0deg 100% 15%);\n color: hsl(0deg 100% 77%);\n background-color: hsl(0deg 100% 10%);\n}\n\n.sa-debugger-log-repeats {\n background-color: hsla(163, 85%, 40%, 1);\n color: white;\n border-radius: 100px;\n padding: 1px 6px;\n margin-right: 4px;\n}\n[theme=\"dark\"] .sa-debugger-log-repeats {\n color: var(--ui-primary);\n}\n\n.sa-debugger-log-icon {\n width: 16px;\n height: 16px;\n margin-right: 4px;\n}\n[data-type=\"warn\"] .sa-debugger-log-icon {\n background-image: url(" + escape(__webpack_require__(/*! ./icons/warning.svg */ "./src/addons/addons/debugger/icons/warning.svg")) + ");\n}\n[data-type=\"error\"] .sa-debugger-log-icon {\n background-image: url(" + escape(__webpack_require__(/*! ./icons/error.svg */ "./src/addons/addons/debugger/icons/error.svg")) + ");\n}\n.sa-debugger-threads .sa-debugger-log-icon {\n background-image: url(" + escape(__webpack_require__(/*! ./icons/subthread.svg */ "./src/addons/addons/debugger/icons/subthread.svg")) + ");\n}\n\n.sa-debugger-log-link {\n color: inherit;\n cursor: pointer;\n opacity: 0.5;\n text-decoration: underline;\n float: right;\n text-align: right;\n max-width: 100%;\n padding-left: 4px;\n margin-right: 4px;\n margin-left: auto;\n}\n[theme=\"dark\"] .sa-debugger-log-link {\n color: inherit;\n}\n.sa-debugger-log-link:hover {\n text-decoration: underline;\n color: #4d97ff;\n opacity: 1;\n}\n.sa-debugger-log-link-unknown {\n pointer-events: none;\n}\n\n.sa-debugger-log-text {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: pre;\n}\n.sa-debugger-log-text-empty {\n font-style: italic;\n}\n.sa-debugger-log-internal .sa-debugger-log-text {\n font-style: italic;\n}\n\n.sa-debugger-thread-indent {\n width: calc(16px * var(--level));\n margin-right: 4px;\n}\n.sa-debugger-thread-title .sa-debugger-thread-indent {\n margin: 0;\n}\n.sa-debugger-thread-target-name {\n font-weight: bold;\n margin-right: 8px;\n}\n.sa-debugger-thread-running {\n background-color: rgba(255, 187, 0, 0.233);\n font-weight: bold;\n}\n\n.sa-debugger-block-preview {\n padding: 1px 6px;\n margin-right: 4px;\n background-color: var(--sa-block-colored-background);\n color: var(--sa-block-text);\n}\n.sa-debugger-block-preview[data-shape=\"round\"] {\n border-radius: 100px;\n}\n.sa-debugger-block-preview[data-shape=\"stacked\"] {\n border-radius: 3px;\n}\n\n.sa-debugger-thread-compiled {\n font-style: italic;\n}\n\n.sa-debugger-compiler-warning {\n position: relative;\n display: block;\n text-align: center;\n height: 24px;\n color: #2121bf;\n}\n.sa-debugger-compiler-warning[hidden] {\n display: none;\n}\n[theme=\"dark\"] .sa-debugger-compiler-warning {\n color: #bdbdf9;\n}\n", ""]); + +// exports + + +/***/ }), + +/***/ "./node_modules/css-loader/index.js!./src/addons/addons/editor-theme3/compatibility.css": +/*!*************************************************************************************!*\ + !*** ./node_modules/css-loader!./src/addons/addons/editor-theme3/compatibility.css ***! + \*************************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +exports = module.exports = __webpack_require__(/*! ../../../../node_modules/css-loader/lib/css-base.js */ "./node_modules/css-loader/lib/css-base.js")(false); +// imports + + +// module +exports.push([module.i, "/* Imported by other addons */\n\n.sa-block-color {\n --sa-block-colored-background: var(--sa-block-background-primary);\n --sa-block-colored-background-secondary: var(--sa-block-field-background);\n --sa-block-bright-background: var(--sa-block-background-primary);\n --sa-block-text: white;\n --sa-block-gray-text: white;\n --sa-block-colored-text: var(--sa-block-background-primary);\n --sa-block-text-on-bright-background: white;\n}\n\n.sa-block-color-motion {\n --sa-block-background-primary: var(--editorTheme3-motion-primary, #4c97ff);\n --sa-block-background-secondary: var(--editorTheme3-motion-secondary, #4280d7);\n --sa-block-background-tertiary: var(--editorTheme3-motion-tertiary, #3373cc);\n --sa-block-field-background: var(--editorTheme3-motion-field, #3373cc);\n}\n\n.sa-block-color-looks {\n --sa-block-background-primary: var(--editorTheme3-looks-primary, #9966ff);\n --sa-block-background-secondary: var(--editorTheme3-looks-secondary, #855cd6);\n --sa-block-background-tertiary: var(--editorTheme3-looks-tertiary, #774dcb);\n --sa-block-field-background: var(--editorTheme3-looks-field, #774dcb);\n}\n\n.sa-block-color-sounds {\n --sa-block-background-primary: var(--editorTheme3-sounds-primary, #cf63cf);\n --sa-block-background-secondary: var(--editorTheme3-sounds-secondary, #c94fc9);\n --sa-block-background-tertiary: var(--editorTheme3-sounds-tertiary, #bd42bd);\n --sa-block-field-background: var(--editorTheme3-sounds-field, #bd42bd);\n}\n\n.sa-block-color-events {\n --sa-block-background-primary: var(--editorTheme3-event-primary, #ffbf00);\n --sa-block-background-secondary: var(--editorTheme3-event-secondary, #e6ac00);\n --sa-block-background-tertiary: var(--editorTheme3-event-tertiary, #cc9900);\n --sa-block-field-background: var(--editorTheme3-event-field, #cc9900);\n}\n\n.sa-block-color-control {\n --sa-block-background-primary: var(--editorTheme3-control-primary, #ffab19);\n --sa-block-background-secondary: var(--editorTheme3-control-secondary, #ec9c13);\n --sa-block-background-tertiary: var(--editorTheme3-control-tertiary, #cf8b17);\n --sa-block-field-background: var(--editorTheme3-control-field, #cf8b17);\n}\n\n.sa-block-color-sensing {\n --sa-block-background-primary: var(--editorTheme3-sensing-primary, #5cb1d6);\n --sa-block-background-secondary: var(--editorTheme3-sensing-secondary, #47a8d1);\n --sa-block-background-tertiary: var(--editorTheme3-sensing-tertiary, #2e8eb8);\n --sa-block-field-background: var(--editorTheme3-sensing-field, #2e8eb8);\n}\n\n.sa-block-color-operators {\n --sa-block-background-primary: var(--editorTheme3-operators-primary, #59c059);\n --sa-block-background-secondary: var(--editorTheme3-operators-secondary, #46b946);\n --sa-block-background-tertiary: var(--editorTheme3-operators-tertiary, #389438);\n --sa-block-field-background: var(--editorTheme3-operators-field, #389438);\n}\n\n.sa-block-color-data {\n --sa-block-background-primary: var(--editorTheme3-data-primary, #ff8c1a);\n --sa-block-background-secondary: var(--editorTheme3-data-secondary, #ff8000);\n --sa-block-background-tertiary: var(--editorTheme3-data-tertiary, #db6e00);\n --sa-block-field-background: var(--editorTheme3-data-field, #db6e00);\n}\n\n.sa-block-color-data-lists,\n.sa-block-color-list {\n --sa-block-background-primary: var(--editorTheme3-data_lists-primary, #ff661a);\n --sa-block-background-secondary: var(--editorTheme3-data_lists-secondary, #ff5500);\n --sa-block-background-tertiary: var(--editorTheme3-data_lists-tertiary, #e64d00);\n --sa-block-field-background: var(--editorTheme3-data_lists-field, #e64d00);\n}\n\n.sa-block-color-more,\n.sa-block-color-null {\n --sa-block-background-primary: var(--editorTheme3-more-primary, #ff6680);\n --sa-block-background-secondary: var(--editorTheme3-more-secondary, #ff4d6a);\n --sa-block-background-tertiary: var(--editorTheme3-more-tertiary, #ff3355);\n --sa-block-field-background: var(--editorTheme3-more-field, #ff3355);\n}\n\n.sa-block-color-pen {\n --sa-block-background-primary: var(--editorTheme3-pen-primary, #0fbd8c);\n --sa-block-background-secondary: var(--editorTheme3-pen-secondary, #0da57a);\n --sa-block-background-tertiary: var(--editorTheme3-pen-tertiary, #0b8e69);\n --sa-block-field-background: var(--editorTheme3-pen-field, #0b8e69);\n}\n\n.sa-block-color-addon-custom-block {\n --sa-block-background-primary: var(--editorTheme3-sa-primary, #29beb8);\n --sa-block-background-secondary: var(--editorTheme3-sa-secondary, #3aa8a4);\n --sa-block-background-tertiary: var(--editorTheme3-sa-tertiary, #3aa8a4);\n --sa-block-field-background: var(--editorTheme3-sa-field, #3aa8a4);\n}\n\n.sa-block-color-TurboWarp {\n --sa-block-background-primary: var(--editorTheme3-tw-primary, #ff4c4c);\n --sa-block-background-secondary: var(--editorTheme3-tw-secondary, #e64444);\n --sa-block-background-tertiary: var(--editorTheme3-tw-tertiary, #e64444);\n --sa-block-field-background: var(--editorTheme3-tw-field, #e64444);\n}\n", ""]); + +// exports + + +/***/ }), + +/***/ "./node_modules/url-loader/dist/cjs.js!./src/addons/addons/debugger/icons/close.svg": +/*!******************************************************************************************!*\ + !*** ./node_modules/url-loader/dist/cjs.js!./src/addons/addons/debugger/icons/close.svg ***! + \******************************************************************************************/ +/*! exports provided: default */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony default export */ __webpack_exports__["default"] = ("data:image/svg+xml;base64,PHN2ZyBkYXRhLW5hbWU9IkxheWVyIDEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmlld0JveD0iMCAwIDcuNDggNy40OCIgc3R5bGU9InRyYW5zZm9ybTpyb3RhdGUoNDVkZWcpIj48cGF0aCBkPSJNMy43NCA2LjQ4VjFNMSAzLjc0aDUuNDgiIHN0eWxlPSJmaWxsOm5vbmU7c3Ryb2tlOiNmZmY7c3Ryb2tlLWxpbmVjYXA6cm91bmQ7c3Ryb2tlLWxpbmVqb2luOnJvdW5kO3N0cm9rZS13aWR0aDoycHgiLz48L3N2Zz4="); + +/***/ }), + +/***/ "./node_modules/url-loader/dist/cjs.js!./src/addons/addons/debugger/icons/debug.svg": +/*!******************************************************************************************!*\ + !*** ./node_modules/url-loader/dist/cjs.js!./src/addons/addons/debugger/icons/debug.svg ***! + \******************************************************************************************/ +/*! exports provided: default */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony default export */ __webpack_exports__["default"] = ("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAiIGhlaWdodD0iMjAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGcgc3Ryb2tlPSIjNEM5N0ZGIiBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCI+PHBhdGggc3R5bGU9ImZpbGw6IzU3NWU3NTtmaWxsLW9wYWNpdHk6MTtzdHJva2U6bm9uZTtzdHJva2Utd2lkdGg6MTtzdHJva2UtbGluZWNhcDpyb3VuZDtzdHJva2UtbGluZWpvaW46cm91bmQ7c3Ryb2tlLW1pdGVybGltaXQ6NDtzdHJva2UtZGFzaGFycmF5Om5vbmU7c3Ryb2tlLW9wYWNpdHk6MTtwYWludC1vcmRlcjptYXJrZXJzIHN0cm9rZSBmaWxsIiBkPSJNNCAzLjVjLS44MzEgMC0xLjUuNjY5LTEuNSAxLjV2MTBjMCAuODMxLjY2OSAxLjUgMS41IDEuNWgxMmMuODMxIDAgMS41LS42NjkgMS41LTEuNVY1YzAtLjgzMS0uNjY5LTEuNS0xLjUtMS41Wm0wIDFoMTJjLjI3NyAwIC41LjIyMy41LjV2MTBjMCAuMjc3LS4yMjMuNS0uNS41SDRhLjQ5OS40OTkgMCAwIDEtLjUtLjVWNWMwLS4yNzcuMjIzLS41LjUtLjVaIiBzdHJva2U9Im5vbmUiLz48cGF0aCBkPSJtNS40MTcgNy41IDMuNzUgMi41LTMuNzUgMi41bTUgMGg0LjE2NiIgc3R5bGU9ImZpbGw6bm9uZTtzdHJva2U6IzhmOGY4ZjtzdHJva2Utd2lkdGg6MTtzdHJva2UtbWl0ZXJsaW1pdDo0O3N0cm9rZS1kYXNoYXJyYXk6bm9uZTtzdHJva2Utb3BhY2l0eToxIi8+PC9nPjwvc3ZnPg=="); + +/***/ }), + +/***/ "./node_modules/url-loader/dist/cjs.js!./src/addons/addons/debugger/icons/delete.svg": +/*!*******************************************************************************************!*\ + !*** ./node_modules/url-loader/dist/cjs.js!./src/addons/addons/debugger/icons/delete.svg ***! + \*******************************************************************************************/ +/*! exports provided: default */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony default export */ __webpack_exports__["default"] = ("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAiIGhlaWdodD0iMjAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPjxkZWZzPjxwYXRoIGQ9Ik00LjU0OCA3aDEwLjkwNGEuNS41IDAgMCAxIC40OTguNTQ1bC0uNzg1IDguNjM1QTIgMiAwIDAgMSAxMy4xNzQgMThINi44MjdhMiAyIDAgMCAxLTEuOTkyLTEuODJMNC4wNSA3LjU0NkEuNS41IDAgMCAxIDQuNTQ4IDd6bTIuNzg1LTMgLjU1My0xLjY1OEEuNS41IDAgMCAxIDguMzYgMmgzLjI4YS41LjUgMCAwIDEgLjQ3NC4zNDJMMTIuNjY3IDRIMTYuNWEuNS41IDAgMCAxIC41LjV2MWEuNS41IDAgMCAxLS41LjVoLTEzYS41LjUgMCAwIDEtLjUtLjV2LTFhLjUuNSAwIDAgMSAuNS0uNWgzLjgzM3ptMS4wNTQgMGgzLjIyNmwtLjMzNC0xSDguNzIxbC0uMzM0IDF6TTEwIDExLjcybDEuNTk1LTEuNTk1YS41LjUgMCAwIDEgLjcwNyAwbC4wNzMuMDczYS41LjUgMCAwIDEgMCAuNzA3TDEwLjc4IDEyLjVsMS41OTUgMS41OTVhLjUuNSAwIDAgMSAwIC43MDdsLS4wNzMuMDczYS41LjUgMCAwIDEtLjcwNyAwTDEwIDEzLjI4bC0xLjU5NSAxLjU5NWEuNS41IDAgMCAxLS43MDcgMGwtLjA3My0uMDczYS41LjUgMCAwIDEgMC0uNzA3TDkuMjIgMTIuNWwtMS41OTUtMS41OTVhLjUuNSAwIDAgMSAwLS43MDdsLjA3My0uMDczYS41LjUgMCAwIDEgLjcwNyAwTDEwIDExLjcyeiIgaWQ9ImEiLz48L2RlZnM+PGcgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIj48bWFzayBpZD0iYiIgZmlsbD0iI2ZmZiI+PHVzZSB4bGluazpocmVmPSIjYSIvPjwvbWFzaz48ZyBtYXNrPSJ1cmwoI2IpIiBmaWxsPSIjRkZGIj48cGF0aCBkPSJNMCAwaDIwdjIwSDB6Ii8+PC9nPjwvZz48L3N2Zz4="); + +/***/ }), + +/***/ "./node_modules/url-loader/dist/cjs.js!./src/addons/addons/debugger/icons/download-white.svg": +/*!***************************************************************************************************!*\ + !*** ./node_modules/url-loader/dist/cjs.js!./src/addons/addons/debugger/icons/download-white.svg ***! + \***************************************************************************************************/ +/*! exports provided: default */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony default export */ __webpack_exports__["default"] = ("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAiIGhlaWdodD0iMjAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0ibTE0LjczIDguNzc5LTQuMjUzIDQuMjY0YS42MTkuNjE5IDAgMCAxLS44OSAwTDUuMzM2IDguNzc5QS42My42MyAwIDAgMSA1Ljc4OCA3LjdoMi4xMTdsMS4yNjMtNS4wMTZhLjkxMi45MTIgMCAwIDEgMS4xMDYtLjY1Ni44OS44OSAwIDAgMSAuNjY4LjY1NkwxMi4yMDYgNy43aDIuMDcyYy41NTkgMCAuODU2LjY3LjQ1MSAxLjA3OHpNMTggMTEuODEydjIuNTc5QzE4IDE2LjM3NSAxNi4zOTUgMTggMTQuNDE3IDE4SDUuNkEzLjYwNyAzLjYwNyAwIDAgMSAyIDE0LjM5di0yLjU3OGExLjE3IDEuMTcgMCAxIDEgMi4zMzcgMHYyLjU3OUExLjI3IDEuMjcgMCAwIDAgNS42IDE1LjY1Nmg4LjgxN2MuNjg2IDAgMS4yNDYtLjU3OCAxLjI0Ni0xLjI2NXYtMi41NzljMC0uNjU2LjUzLTEuMTcyIDEuMTY5LTEuMTcyLjY1NCAwIDEuMTY4LjUxNiAxLjE2OCAxLjE3MnoiIGZpbGw9IiNGRkYiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvc3ZnPg=="); + +/***/ }), + +/***/ "./node_modules/url-loader/dist/cjs.js!./src/addons/addons/debugger/icons/error.svg": +/*!******************************************************************************************!*\ + !*** ./node_modules/url-loader/dist/cjs.js!./src/addons/addons/debugger/icons/error.svg ***! + \******************************************************************************************/ +/*! exports provided: default */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony default export */ __webpack_exports__["default"] = ("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxZW0iIGhlaWdodD0iMWVtIiB2aWV3Qm94PSIwIDAgMjQgMjQiIHN0eWxlPSItbXMtdHJhbnNmb3JtOnJvdGF0ZSgzNjBkZWcpOy13ZWJraXQtdHJhbnNmb3JtOnJvdGF0ZSgzNjBkZWcpO3RyYW5zZm9ybTpyb3RhdGUoMzYwZGVnKSI+PHBhdGggZD0iTTEyIDE0YTEuMjUgMS4yNSAwIDEgMCAxLjI1IDEuMjVBMS4yNSAxLjI1IDAgMCAwIDEyIDE0em0wLTEuNWExIDEgMCAwIDAgMS0xdi0zYTEgMSAwIDAgMC0yIDB2M2ExIDEgMCAwIDAgMSAxek0xMiAyYTEwIDEwIDAgMSAwIDEwIDEwQTEwLjAxMSAxMC4wMTEgMCAwIDAgMTIgMnptMCAxOGE4IDggMCAxIDEgOC04IDguMDEgOC4wMSAwIDAgMS04IDh6IiBmaWxsPSJyZWQiLz48L3N2Zz4="); + +/***/ }), + +/***/ "./node_modules/url-loader/dist/cjs.js!./src/addons/addons/debugger/icons/logs.svg": +/*!*****************************************************************************************!*\ + !*** ./node_modules/url-loader/dist/cjs.js!./src/addons/addons/debugger/icons/logs.svg ***! + \*****************************************************************************************/ +/*! exports provided: default */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony default export */ __webpack_exports__["default"] = ("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxZW0iIGhlaWdodD0iMWVtIiB2aWV3Qm94PSIwIDAgMjQgMjQiIHN0eWxlPSItbXMtdHJhbnNmb3JtOnJvdGF0ZSgzNjBkZWcpOy13ZWJraXQtdHJhbnNmb3JtOnJvdGF0ZSgzNjBkZWcpO3RyYW5zZm9ybTpyb3RhdGUoMzYwZGVnKSI+PHBhdGggZD0iTTMgN2gxOGExIDEgMCAwIDAgMC0ySDNhMSAxIDAgMCAwIDAgMnptMCA0aDE0YTEgMSAwIDAgMCAwLTJIM2ExIDEgMCAwIDAgMCAyem0xOCAySDNhMSAxIDAgMCAwIDAgMmgxOGExIDEgMCAwIDAgMC0yem0tNCA0SDNhMSAxIDAgMCAwIDAgMmgxNGExIDEgMCAwIDAgMC0yeiIgZmlsbD0iIzUxMDBmZiIvPjwvc3ZnPg=="); + +/***/ }), + +/***/ "./node_modules/url-loader/dist/cjs.js!./src/addons/addons/debugger/icons/performance.svg": +/*!************************************************************************************************!*\ + !*** ./node_modules/url-loader/dist/cjs.js!./src/addons/addons/debugger/icons/performance.svg ***! + \************************************************************************************************/ +/*! exports provided: default */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony default export */ __webpack_exports__["default"] = ("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGZpbGw9Im5vbmUiIHZpZXdCb3g9IjAgMCAyNCAyNCIgc3Ryb2tlPSJjdXJyZW50Q29sb3IiPjxwYXRoIHN0cm9rZT0iIzRjOTdmZiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBzdHJva2Utd2lkdGg9IjIiIGQ9Ik05IDE5di02YTIgMiAwIDAgMC0yLTJINWEyIDIgMCAwIDAtMiAydjZhMiAyIDAgMCAwIDIgMmgyYTIgMiAwIDAgMCAyLTJ6bTAgMFY5YTIgMiAwIDAgMSAyLTJoMmEyIDIgMCAwIDEgMiAydjEwbS02IDBhMiAyIDAgMCAwIDIgMmgyYTIgMiAwIDAgMCAyLTJtMCAwVjVhMiAyIDAgMCAxIDItMmgyYTIgMiAwIDAgMSAyIDJ2MTRhMiAyIDAgMCAxLTIgMmgtMmEyIDIgMCAwIDEtMi0yeiIvPjwvc3ZnPg=="); + +/***/ }), + +/***/ "./node_modules/url-loader/dist/cjs.js!./src/addons/addons/debugger/icons/play.svg": +/*!*****************************************************************************************!*\ + !*** ./node_modules/url-loader/dist/cjs.js!./src/addons/addons/debugger/icons/play.svg ***! + \*****************************************************************************************/ +/*! exports provided: default */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony default export */ __webpack_exports__["default"] = ("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNDkiIGhlaWdodD0iNTIiIHZpZXdCb3g9Ii01IDAgNDkgNDgiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPjxkZWZzPjxwYXRoIGQ9Ik0xNy4yMjEgOC4zNDVjMi41NTYtNC4yNTkgNi43MDItNC4yNTIgOS4yNTQgMGwxMy42NzcgMjIuNzk2YzIuNTU1IDQuMjU4LjU5NyA3LjcxLTQuMzggNy43MUg3LjkyNGMtNC45NzMgMC02LjkzLTMuNDU4LTQuMzgtNy43MUwxNy4yMjIgOC4zNDV6IiBpZD0iYSIvPjwvZGVmcz48dXNlIHN0cm9rZT0iI0ZGRiIgZmlsbD0iI0ZGRiIgeGxpbms6aHJlZj0iI2EiIHRyYW5zZm9ybT0icm90YXRlKDkwIDIwLjg1IDIzLjAwMykiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvc3ZnPg=="); + +/***/ }), + +/***/ "./node_modules/url-loader/dist/cjs.js!./src/addons/addons/debugger/icons/step.svg": +/*!*****************************************************************************************!*\ + !*** ./node_modules/url-loader/dist/cjs.js!./src/addons/addons/debugger/icons/step.svg ***! + \*****************************************************************************************/ +/*! exports provided: default */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony default export */ __webpack_exports__["default"] = ("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTkiIGhlaWdodD0iMTkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmlld0JveD0iMCAwIDI0IDI0Ij48cGF0aCBkPSJNMjIuNjggMTIuMmExLjYgMS42IDAgMCAxLTEuMjcuNjNoLTcuNjlhMS41OSAxLjU5IDAgMCAxLTEuMTYtMi41OGwxLjEyLTEuNDFhNC44MiA0LjgyIDAgMCAwLTMuMTQtLjc3IDQuMzEgNC4zMSAwIDAgMC0yIC44QTQuMjUgNC4yNSAwIDAgMCA3LjIgMTAuNmE1LjA2IDUuMDYgMCAwIDAgLjU0IDQuNjJBNS41OCA1LjU4IDAgMCAwIDEyIDE3Ljc0YTIuMjYgMi4yNiAwIDAgMS0uMTYgNC41MkExMC4yNSAxMC4yNSAwIDAgMSAzLjc0IDE4YTEwLjE0IDEwLjE0IDAgMCAxLTEuNDktOS4yMiA5LjcgOS43IDAgMCAxIDIuODMtNC4xNEE5LjkyIDkuOTIgMCAwIDEgOS42NiAyLjVhMTAuNjYgMTAuNjYgMCAwIDEgNy43MiAxLjY4bDEuMDgtMS4zNWExLjU3IDEuNTcgMCAwIDEgMS4yNC0uNiAxLjYgMS42IDAgMCAxIDEuNTQgMS4yMWwxLjcgNy4zN2ExLjU3IDEuNTcgMCAwIDEtLjI2IDEuMzlaIiBzdHlsZT0iZmlsbDojZmZmIi8+PHBhdGggZD0iTTIxLjM4IDExLjgzaC03LjYxYS41OS41OSAwIDAgMS0uNDMtMWwxLjc1LTIuMTlhNS45IDUuOSAwIDAgMC00LjctMS41OCA1LjA3IDUuMDcgMCAwIDAtNC4xMSAzLjE3QTYgNiAwIDAgMCA3IDE1Ljc3YTYuNTEgNi41MSAwIDAgMCA1IDIuOTIgMS4zMSAxLjMxIDAgMCAxLS4wOCAyLjYyIDkuMyA5LjMgMCAwIDEtNy4zNS0zLjgyIDkuMTYgOS4xNiAwIDAgMS0xLjQtOC4zN0E4LjUxIDguNTEgMCAwIDEgNS43MSA1LjRhOC43NiA4Ljc2IDAgMCAxIDQuMTEtMS45MiA5LjcxIDkuNzEgMCAwIDEgNy43NSAyLjA3bDEuNjctMi4xYS41OS41OSAwIDAgMSAxIC4yMUwyMiAxMS4wOGEuNTkuNTkgMCAwIDEtLjYyLjc1WiIgc3R5bGU9ImZpbGw6I2ZmZiIvPjwvc3ZnPg=="); + +/***/ }), + +/***/ "./node_modules/url-loader/dist/cjs.js!./src/addons/addons/debugger/icons/subthread.svg": +/*!**********************************************************************************************!*\ + !*** ./node_modules/url-loader/dist/cjs.js!./src/addons/addons/debugger/icons/subthread.svg ***! + \**********************************************************************************************/ +/*! exports provided: default */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony default export */ __webpack_exports__["default"] = ("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxZW0iIGhlaWdodD0iMWVtIiB2aWV3Qm94PSIwIDAgMjQgMjQiIHN0eWxlPSItbXMtdHJhbnNmb3JtOnJvdGF0ZSgzNjBkZWcpOy13ZWJraXQtdHJhbnNmb3JtOnJvdGF0ZSgzNjBkZWcpO3RyYW5zZm9ybTpyb3RhdGUoMzYwZGVnKSI+PHBhdGggZD0iTTIwLjkyIDEyLjYyYTEgMSAwIDAgMC0uMjEtLjMzbC0zLTNhMSAxIDAgMCAwLTEuNDIgMS40MmwxLjMgMS4yOUg4YTEgMSAwIDAgMS0xLTFWN2ExIDEgMCAwIDAtMiAwdjRhMyAzIDAgMCAwIDMgM2g5LjU5bC0xLjMgMS4yOWExIDEgMCAwIDAgMCAxLjQyIDEgMSAwIDAgMCAxLjQyIDBsMy0zYTEgMSAwIDAgMCAuMjEtLjMzIDEgMSAwIDAgMCAwLS43NnoiIGZpbGw9ImdyYXkiLz48L3N2Zz4="); + +/***/ }), + +/***/ "./node_modules/url-loader/dist/cjs.js!./src/addons/addons/debugger/icons/threads.svg": +/*!********************************************************************************************!*\ + !*** ./node_modules/url-loader/dist/cjs.js!./src/addons/addons/debugger/icons/threads.svg ***! + \********************************************************************************************/ +/*! exports provided: default */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony default export */ __webpack_exports__["default"] = ("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxZW0iIGhlaWdodD0iMWVtIiB2aWV3Qm94PSIwIDAgMjQgMjQiIHN0eWxlPSItbXMtdHJhbnNmb3JtOnJvdGF0ZSgzNjBkZWcpOy13ZWJraXQtdHJhbnNmb3JtOnJvdGF0ZSgzNjBkZWcpO3RyYW5zZm9ybTpyb3RhdGUoMzYwZGVnKSI+PHBhdGggZD0iTTE5IDJIOWEzIDMgMCAwIDAtMyAzdjFINWEzIDMgMCAwIDAtMyAzdjEwYTMgMyAwIDAgMCAzIDNoMTBhMyAzIDAgMCAwIDMtM3YtMWgxYTMgMyAwIDAgMCAzLTNWNWEzIDMgMCAwIDAtMy0zem0tMyAxN2ExIDEgMCAwIDEtMSAxSDVhMSAxIDAgMCAxLTEtMXYtN2gxMnptMC05SDRWOWExIDEgMCAwIDEgMS0xaDEwYTEgMSAwIDAgMSAxIDF6bTQgNWExIDEgMCAwIDEtMSAxaC0xVjlhMyAzIDAgMCAwLS4xOC0xSDIwem0wLTlIOFY1YTEgMSAwIDAgMSAxLTFoMTBhMSAxIDAgMCAxIDEgMXoiIGZpbGw9IiM0Yzk3ZmYiLz48L3N2Zz4="); + +/***/ }), + +/***/ "./node_modules/url-loader/dist/cjs.js!./src/addons/addons/debugger/icons/warning.svg": +/*!********************************************************************************************!*\ + !*** ./node_modules/url-loader/dist/cjs.js!./src/addons/addons/debugger/icons/warning.svg ***! + \********************************************************************************************/ +/*! exports provided: default */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony default export */ __webpack_exports__["default"] = ("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxZW0iIGhlaWdodD0iMWVtIiB2aWV3Qm94PSIwIDAgMjQgMjQiIHN0eWxlPSItbXMtdHJhbnNmb3JtOnJvdGF0ZSgzNjBkZWcpOy13ZWJraXQtdHJhbnNmb3JtOnJvdGF0ZSgzNjBkZWcpO3RyYW5zZm9ybTpyb3RhdGUoMzYwZGVnKSI+PHBhdGggZD0iTTEyIDE2YTEgMSAwIDEgMCAxIDEgMSAxIDAgMCAwLTEtMXptMTAuNjcgMS40Ny04LjA1LTE0YTMgMyAwIDAgMC01LjI0IDBsLTggMTRBMyAzIDAgMCAwIDMuOTQgMjJoMTYuMTJhMyAzIDAgMCAwIDIuNjEtNC41M3ptLTEuNzMgMmExIDEgMCAwIDEtLjg4LjUxSDMuOTRhMSAxIDAgMCAxLS44OC0uNTEgMSAxIDAgMCAxIDAtMWw4LTE0YTEgMSAwIDAgMSAxLjc4IDBsOC4wNSAxNGExIDEgMCAwIDEgLjA1IDEuMDJ6TTEyIDhhMSAxIDAgMCAwLTEgMXY0YTEgMSAwIDAgMCAyIDBWOWExIDEgMCAwIDAtMS0xeiIgZmlsbD0iI2UwYmIwMCIvPjwvc3ZnPg=="); + +/***/ }), + +/***/ "./src/addons/addons/debugger/_runtime_entry.js": +/*!******************************************************!*\ + !*** ./src/addons/addons/debugger/_runtime_entry.js ***! + \******************************************************/ +/*! exports provided: resources */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "resources", function() { return resources; }); +/* harmony import */ var _userscript_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./userscript.js */ "./src/addons/addons/debugger/userscript.js"); +/* harmony import */ var _css_loader_style_css__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! css-loader!./style.css */ "./node_modules/css-loader/index.js!./src/addons/addons/debugger/style.css"); +/* harmony import */ var _css_loader_style_css__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_css_loader_style_css__WEBPACK_IMPORTED_MODULE_1__); +/* harmony import */ var _url_loader_icons_close_svg__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! url-loader!./icons/close.svg */ "./node_modules/url-loader/dist/cjs.js!./src/addons/addons/debugger/icons/close.svg"); +/* harmony import */ var _url_loader_icons_debug_svg__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! url-loader!./icons/debug.svg */ "./node_modules/url-loader/dist/cjs.js!./src/addons/addons/debugger/icons/debug.svg"); +/* harmony import */ var _url_loader_icons_delete_svg__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! url-loader!./icons/delete.svg */ "./node_modules/url-loader/dist/cjs.js!./src/addons/addons/debugger/icons/delete.svg"); +/* harmony import */ var _url_loader_icons_download_white_svg__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! url-loader!./icons/download-white.svg */ "./node_modules/url-loader/dist/cjs.js!./src/addons/addons/debugger/icons/download-white.svg"); +/* harmony import */ var _url_loader_icons_error_svg__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! url-loader!./icons/error.svg */ "./node_modules/url-loader/dist/cjs.js!./src/addons/addons/debugger/icons/error.svg"); +/* harmony import */ var _url_loader_icons_logs_svg__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! url-loader!./icons/logs.svg */ "./node_modules/url-loader/dist/cjs.js!./src/addons/addons/debugger/icons/logs.svg"); +/* harmony import */ var _url_loader_icons_performance_svg__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! url-loader!./icons/performance.svg */ "./node_modules/url-loader/dist/cjs.js!./src/addons/addons/debugger/icons/performance.svg"); +/* harmony import */ var _url_loader_icons_play_svg__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! url-loader!./icons/play.svg */ "./node_modules/url-loader/dist/cjs.js!./src/addons/addons/debugger/icons/play.svg"); +/* harmony import */ var _url_loader_icons_step_svg__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! url-loader!./icons/step.svg */ "./node_modules/url-loader/dist/cjs.js!./src/addons/addons/debugger/icons/step.svg"); +/* harmony import */ var _url_loader_icons_subthread_svg__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! url-loader!./icons/subthread.svg */ "./node_modules/url-loader/dist/cjs.js!./src/addons/addons/debugger/icons/subthread.svg"); +/* harmony import */ var _url_loader_icons_threads_svg__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! url-loader!./icons/threads.svg */ "./node_modules/url-loader/dist/cjs.js!./src/addons/addons/debugger/icons/threads.svg"); +/* harmony import */ var _url_loader_icons_warning_svg__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! url-loader!./icons/warning.svg */ "./node_modules/url-loader/dist/cjs.js!./src/addons/addons/debugger/icons/warning.svg"); +/* generated by pull.js */ + + + + + + + + + + + + + + +const resources = { + "userscript.js": _userscript_js__WEBPACK_IMPORTED_MODULE_0__["default"], + "style.css": _css_loader_style_css__WEBPACK_IMPORTED_MODULE_1___default.a, + "icons/close.svg": _url_loader_icons_close_svg__WEBPACK_IMPORTED_MODULE_2__["default"], + "icons/debug.svg": _url_loader_icons_debug_svg__WEBPACK_IMPORTED_MODULE_3__["default"], + "icons/delete.svg": _url_loader_icons_delete_svg__WEBPACK_IMPORTED_MODULE_4__["default"], + "icons/download-white.svg": _url_loader_icons_download_white_svg__WEBPACK_IMPORTED_MODULE_5__["default"], + "icons/error.svg": _url_loader_icons_error_svg__WEBPACK_IMPORTED_MODULE_6__["default"], + "icons/logs.svg": _url_loader_icons_logs_svg__WEBPACK_IMPORTED_MODULE_7__["default"], + "icons/performance.svg": _url_loader_icons_performance_svg__WEBPACK_IMPORTED_MODULE_8__["default"], + "icons/play.svg": _url_loader_icons_play_svg__WEBPACK_IMPORTED_MODULE_9__["default"], + "icons/step.svg": _url_loader_icons_step_svg__WEBPACK_IMPORTED_MODULE_10__["default"], + "icons/subthread.svg": _url_loader_icons_subthread_svg__WEBPACK_IMPORTED_MODULE_11__["default"], + "icons/threads.svg": _url_loader_icons_threads_svg__WEBPACK_IMPORTED_MODULE_12__["default"], + "icons/warning.svg": _url_loader_icons_warning_svg__WEBPACK_IMPORTED_MODULE_13__["default"] +}; + +/***/ }), + +/***/ "./src/addons/addons/debugger/icons/error.svg": +/*!****************************************************!*\ + !*** ./src/addons/addons/debugger/icons/error.svg ***! + \****************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +module.exports = __webpack_require__.p + "static/assets/76b6cb627b95d79705c0b41664064f0e.svg"; + +/***/ }), + +/***/ "./src/addons/addons/debugger/icons/subthread.svg": +/*!********************************************************!*\ + !*** ./src/addons/addons/debugger/icons/subthread.svg ***! + \********************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +module.exports = __webpack_require__.p + "static/assets/c846a442121113b1d04f6b9d50912038.svg"; + +/***/ }), + +/***/ "./src/addons/addons/debugger/icons/warning.svg": +/*!******************************************************!*\ + !*** ./src/addons/addons/debugger/icons/warning.svg ***! + \******************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +module.exports = __webpack_require__.p + "static/assets/0e009d6e684951615b31a267baa37636.svg"; + +/***/ }), + +/***/ "./src/addons/addons/debugger/log-view.js": +/*!************************************************!*\ + !*** ./src/addons/addons/debugger/log-view.js ***! + \************************************************/ +/*! exports provided: default */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +const clamp = (i, min, max) => Math.max(min, Math.min(max, i)); +const appendSortedElement = (parent, newChild) => { + const newChildIndex = +newChild.dataset.index; + let foundSpot = false; + for (const existingChild of parent.children) { + const existingChildIndex = +existingChild.dataset.index; + if (existingChildIndex > newChildIndex) { + foundSpot = true; + parent.insertBefore(newChild, existingChild); + break; + } + } + if (!foundSpot) { + parent.appendChild(newChild); + } +}; + +/** + * LogView: A virtualized row viewer. + * It efficiently manages row rendering and scrolling. + * + * 1. .logs is the place where all the rows live. This is an array of any arbitrary object. + * 2. Implement generateRow(row). This takes a row from .logs as an argument. This should return + * an object with a bunch of DOM elements on it. The "root" property must be set, nothing else + * is required. This is called when a row becomes visible. It can be called any number of times. + * This is where you should setup elements that are immutable for a given row. LogView will + * move the root element to the right spot for you. + * 3. Implement renderRow(elements, row). This will be called with the result returned by + * generateRow() and the row in .logs any time a row is changed, including the first render. + * It can be called any number of times. This is where you should update any dynamic elements. + * 4. Whenever you update .logs without using the helper methods such as append(), call + * queueUpdateContent(). + */ +class LogView { + constructor() { + this.rows = []; + this.canAutoScrollToEnd = true; + this.rowHeight = 20; + this.outerElement = document.createElement("div"); + this.outerElement.className = "sa-debugger-log-outer"; + this.innerElement = document.createElement("div"); + this.innerElement.className = "sa-debugger-log-inner"; + this.outerElement.appendChild(this.innerElement); + this.innerElement.addEventListener("scroll", this._handleScroll.bind(this), { + passive: true + }); + this.innerElement.addEventListener("wheel", this._handleWheel.bind(this), { + passive: true + }); + this.endElement = document.createElement("div"); + this.endElement.className = "sa-debugger-log-end"; + this.endElement.dataset.index = "-1"; + this.innerElement.appendChild(this.endElement); + this.placeholderElement = document.createElement("div"); + this.placeholderElement.className = "sa-debugger-log-empty"; + this.visible = false; + this.isScrolledToEnd = true; + this.scrollTopWhenHidden = "end"; + this.scrollTop = 0; + this.updateContentQueued = false; + this.scrollToEndQueued = false; + this.oldLength = -1; + this.rowToMetadata = new Map(); + } + append(log) { + this.queueUpdateContent(); + this._queueScrollToEnd(); + this.rows.push(log); + const MAX_LOGS = 200000; + while (this.rows.length > MAX_LOGS) { + this.rows.shift(); + } + } + clear() { + this.rows.length = 0; + this.scrollTop = 0; + this.isScrolledToEnd = true; + this.queueUpdateContent(); + } + show() { + this.visible = true; + this.height = this.innerElement.offsetHeight; + this.queueUpdateContent(); + if (this.scrollTopWhenHidden === "end") { + this._queueScrollToEnd(); + } else { + this.innerElement.scrollTop = this.scrollTopWhenHidden; + } + } + hide() { + this.visible = false; + this.scrollTopWhenHidden = this.isScrolledToEnd ? "end" : this.scrollTop; + } + _handleScroll(e) { + this.scrollTop = e.target.scrollTop; + this.isScrolledToEnd = e.target.scrollTop + 5 >= e.target.scrollHeight - e.target.clientHeight; + this.queueUpdateContent(); + } + _handleWheel(e) { + if (e.deltaY < 0) { + this.isScrolledToEnd = false; + } + } + scrollIntoView(index) { + const distanceFromTop = index * this.rowHeight; + const viewportStart = this.scrollTop; + const viewportEnd = this.scrollTop + this.height; + const isInView = distanceFromTop > viewportStart && distanceFromTop < viewportEnd; + if (!isInView) { + this.scrollTop = distanceFromTop; + this.innerElement.scrollTop = distanceFromTop; + } + } + _queueScrollToEnd() { + if (this.visible && this.canAutoScrollToEnd && this.isScrolledToEnd && !this.scrollToEndQueued) { + this.scrollToEndQueued = true; + queueMicrotask(() => { + this.scrollToEndQueued = false; + if (this.isScrolledToEnd) { + const scrollEnd = this.innerElement.scrollHeight - this.innerElement.offsetHeight; + this.innerElement.scrollTop = scrollEnd; + this.scrollTop = scrollEnd; + } + }); + } + } + queueUpdateContent() { + if (this.visible && !this.updateContentQueued) { + this.updateContentQueued = true; + queueMicrotask(() => { + this.updateContentQueued = false; + this.updateContent(); + }); + } + } + generateRow(row) { + // to be implemented by users + } + renderRow(elements, row) { + // to be implemented by users + } + updateContent() { + if (this.rows.length !== this.oldLength) { + this.oldLength = this.rows.length; + const totalHeight = this.rows.length * this.rowHeight; + this.endElement.style.transform = "translateY(".concat(totalHeight, "px)"); + if (this.rows.length) { + this.placeholderElement.remove(); + } else { + this.innerElement.appendChild(this.placeholderElement); + for (const metadata of this.rowToMetadata.values()) { + metadata.elements.root.remove(); + } + this.rowToMetadata.clear(); + } + } + if (this.rows.length === 0) { + return; + } + + // For better compatibility with asynchronous scrolling, we'll render a few extra rows in either direction. + const EXTRA_ROWS_ABOVE = 5; + const EXTRA_ROWS_BELOW = 5; + const scrollStartIndex = Math.floor(this.scrollTop / this.rowHeight); + const rowsVisible = Math.ceil(this.height / this.rowHeight); + const startIndex = clamp(scrollStartIndex - EXTRA_ROWS_BELOW, 0, this.rows.length); + const endIndex = clamp(scrollStartIndex + rowsVisible + EXTRA_ROWS_ABOVE, 0, this.rows.length); + const allVisibleRows = new Set(); + const newElements = []; + for (let i = startIndex; i < endIndex; i++) { + const row = this.rows[i]; + allVisibleRows.add(row); + let metadata = this.rowToMetadata.get(row); + if (!metadata) { + const elements = this.generateRow(row); + newElements.push(elements.root); + metadata = { + stringify: null, + elements + }; + this.rowToMetadata.set(row, metadata); + } + const currentStringify = JSON.stringify(row); + if (currentStringify !== metadata.stringify) { + metadata.stringify = currentStringify; + this.renderRow(metadata.elements, row); + } + const root = metadata.elements.root; + root.style.transform = "translateY(".concat(i * this.rowHeight, "px)"); + root.dataset.index = i; + } + for (const [row, metadata] of this.rowToMetadata.entries()) { + if (!allVisibleRows.has(row)) { + metadata.elements.root.remove(); + this.rowToMetadata.delete(row); + } + } + for (const root of newElements) { + appendSortedElement(this.innerElement, root); + } + } +} +/* harmony default export */ __webpack_exports__["default"] = (LogView); + +/***/ }), + +/***/ "./src/addons/addons/debugger/logs.js": +/*!********************************************!*\ + !*** ./src/addons/addons/debugger/logs.js ***! + \********************************************/ +/*! exports provided: default */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return createLogsTab; }); +/* harmony import */ var _libraries_common_cs_download_blob_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../libraries/common/cs/download-blob.js */ "./src/addons/libraries/common/cs/download-blob.js"); +/* harmony import */ var _log_view_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./log-view.js */ "./src/addons/addons/debugger/log-view.js"); + + +async function createLogsTab(_ref) { + let { + debug, + addon, + console, + msg + } = _ref; + const vm = addon.tab.traps.vm; + const tab = debug.createHeaderTab({ + text: msg("tab-logs"), + icon: addon.self.getResource("/icons/logs.svg") /* rewritten by pull.js */ + }); + const logView = new _log_view_js__WEBPACK_IMPORTED_MODULE_1__["default"](); + logView.placeholderElement.textContent = msg("no-logs"); + const getInputOfBlock = (targetId, blockId) => { + var _Object$values$; + const target = vm.runtime.getTargetById(targetId); + if (!target) { + return null; + } + const block = debug.getBlock(target, blockId); + if (!block) { + return null; + } + return (_Object$values$ = Object.values(block.inputs)[0]) === null || _Object$values$ === void 0 ? void 0 : _Object$values$.block; + }; + logView.generateRow = row => { + const root = document.createElement("div"); + root.className = "sa-debugger-log"; + if (row.internal) { + root.classList.add("sa-debugger-log-internal"); + } + root.dataset.type = row.type; + const icon = document.createElement("div"); + icon.className = "sa-debugger-log-icon"; + if (row.type === "warn" || row.type === "error") { + icon.title = msg("icon-" + row.type); + } + root.appendChild(icon); + const repeats = document.createElement("div"); + repeats.className = "sa-debugger-log-repeats"; + repeats.style.display = "none"; + root.appendChild(repeats); + if (row.preview && row.blockId && row.targetInfo) { + const originalId = row.targetInfo.originalId; + const inputBlock = getInputOfBlock(originalId, row.blockId); + if (inputBlock) { + const preview = debug.createBlockPreview(originalId, inputBlock); + if (preview) { + root.appendChild(preview); + } + } + } + const text = document.createElement("div"); + text.className = "sa-debugger-log-text"; + if (row.text.length === 0) { + text.classList.add("sa-debugger-log-text-empty"); + text.textContent = msg("empty-string"); + } else { + text.textContent = row.text; + text.title = row.text; + } + root.appendChild(text); + if (row.targetInfo && row.blockId) { + root.appendChild(debug.createBlockLink(row.targetInfo, row.blockId)); + } + return { + root, + repeats + }; + }; + logView.renderRow = (elements, row) => { + const { + repeats + } = elements; + if (row.count > 1) { + repeats.style.display = ""; + repeats.textContent = row.count; + } + }; + const exportButton = debug.createHeaderButton({ + text: msg("export"), + icon: addon.self.getResource("/icons/download-white.svg") /* rewritten by pull.js */, + description: msg("export-desc") + }); + const downloadText = (filename, text) => { + Object(_libraries_common_cs_download_blob_js__WEBPACK_IMPORTED_MODULE_0__["default"])(filename, new Blob([text], { + type: "text/plain" + })); + }; + exportButton.element.addEventListener("click", async e => { + const defaultFormat = "{sprite}: {content} ({type})"; + const exportFormat = e.shiftKey ? await addon.tab.prompt(msg("export"), msg("enter-format"), defaultFormat, { + useEditorClasses: true + }) : defaultFormat; + if (!exportFormat) return; + const file = logView.rows.map(_ref2 => { + let { + text, + targetInfo, + type, + count + } = _ref2; + return (exportFormat.replace(/\{(sprite|type|content)\}/g, (_, match) => ({ + sprite: targetInfo ? targetInfo.name : msg("unknown-sprite"), + type, + content: text + })[match]) + "\n").repeat(count); + }).join(""); + downloadText("logs.txt", file); + }); + const trashButton = debug.createHeaderButton({ + text: msg("clear"), + icon: addon.self.getResource("/icons/delete.svg") /* rewritten by pull.js */ + }); + trashButton.element.addEventListener("click", () => { + clearLogs(); + }); + const areLogsEqual = (a, b) => a.text === b.text && a.type === b.type && a.internal === b.internal && a.blockId === b.blockId && a.targetId === b.targetId; + const addLog = (text, thread, type) => { + const log = { + text, + type, + count: 1, + preview: true + }; + if (thread) { + log.blockId = thread.peekStack ? thread.peekStack() : thread.thread.peekStack(); + const targetId = thread.target.id; + log.targetId = targetId; + log.targetInfo = debug.getTargetInfoById(targetId); + } + if (type === "internal") { + log.internal = true; + log.preview = false; + log.type = "log"; + } + if (type === "internal-warn") { + log.internal = true; + log.type = "warn"; + } + const previousLog = logView.rows[logView.rows.length - 1]; + if (previousLog && areLogsEqual(log, previousLog)) { + previousLog.count++; + logView.queueUpdateContent(); + } else { + logView.append(log); + } + if (!logView.visible && !log.internal) { + debug.setHasUnreadMessage(true); + } + }; + const clearLogs = () => { + logView.clear(); + }; + const show = () => { + logView.show(); + debug.setHasUnreadMessage(false); + }; + const hide = () => { + logView.hide(); + }; + return { + tab, + content: logView.outerElement, + buttons: [exportButton, trashButton], + show, + hide, + addLog, + clearLogs + }; +} + +/***/ }), + +/***/ "./src/addons/addons/debugger/module.js": +/*!**********************************************!*\ + !*** ./src/addons/addons/debugger/module.js ***! + \**********************************************/ +/*! exports provided: isPaused, setPaused, onPauseChanged, onSingleStep, getRunningThread, singleStep, setup */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isPaused", function() { return isPaused; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "setPaused", function() { return setPaused; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "onPauseChanged", function() { return onPauseChanged; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "onSingleStep", function() { return onSingleStep; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getRunningThread", function() { return getRunningThread; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "singleStep", function() { return singleStep; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "setup", function() { return setup; }); +/* harmony import */ var _event_target_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../event-target.js */ "./src/addons/event-target.js"); + /* inserted by pull.js */ + +// https://github.com/LLK/scratch-vm/blob/bb352913b57991713a5ccf0b611fda91056e14ec/src/engine/thread.js#L198 +const STATUS_RUNNING = 0; +const STATUS_PROMISE_WAIT = 1; +const STATUS_YIELD = 2; +const STATUS_YIELD_TICK = 3; +const STATUS_DONE = 4; +let vm; +let paused = false; +let pausedThreadState = new WeakMap(); +let pauseNewThreads = false; +let steppingThread = null; +const eventTarget = new _event_target_js__WEBPACK_IMPORTED_MODULE_0__["default"](); +let audioContextStateChange = Promise.resolve(); +const isPaused = () => paused; +const pauseThread = thread => { + if (thread.updateMonitor || pausedThreadState.has(thread)) { + // Thread is already paused or shouldn't be paused. + return; + } + const pauseState = { + time: vm.runtime.currentMSecs, + status: thread.status + }; + pausedThreadState.set(thread, pauseState); + + // Pausing a thread now works by just setting its status to STATUS_PROMISE_WAIT. + // At the start of each frame, we make sure each paused thread is still paused. + // This is really the best way to implement this. + // Converting thread.status into a getter/setter causes Scratch's sequencer to permanently + // perform significantly slower in some projects. I think this is because it causes some + // very hot functions to be deoptimized. + // Trapping sequencer.stepThread to no-op for a paused thread causes Scratch's sequencer + // to waste 24ms of CPU time every frame because it thinks a thread is running. + thread.status = STATUS_PROMISE_WAIT; +}; +const ensurePausedThreadIsStillPaused = thread => { + if (thread.status === STATUS_DONE) { + // If a paused thread is finished by single stepping, let it keep being done. + return; + } + const pauseState = pausedThreadState.get(thread); + if (pauseState) { + if (thread.status !== STATUS_PROMISE_WAIT) { + // We'll record the change so we can properly resume the thread, but the thread must still be paused for now. + pauseState.status = thread.status; + thread.status = STATUS_PROMISE_WAIT; + } + } +}; +const setSteppingThread = thread => { + steppingThread = thread; +}; +const compensateForTimePassedWhilePaused = (thread, pauseState) => { + // TW: Compiled threads store their timer in a different place. + if (thread.timer) { + thread.timer.startTime += vm.runtime.currentMSecs - pauseState.time; + } + const stackFrame = thread.peekStackFrame(); + if (stackFrame && stackFrame.executionContext && stackFrame.executionContext.timer) { + stackFrame.executionContext.timer.startTime += vm.runtime.currentMSecs - pauseState.time; + } +}; +const stepUnsteppedThreads = lastSteppedThread => { + // If we paused in the middle of a tick, we need to make sure to step the scripts that didn't get + // stepped in that tick to avoid affecting project behavior. + const threads = vm.runtime.threads; + const startingIndex = getThreadIndex(lastSteppedThread); + if (startingIndex !== -1) { + for (let i = startingIndex; i < threads.length; i++) { + const thread = threads[i]; + const status = thread.status; + if (status === STATUS_RUNNING || status === STATUS_YIELD || status === STATUS_YIELD_TICK) { + vm.runtime.sequencer.activeThread = thread; + vm.runtime.sequencer.stepThread(thread); + } + } + } +}; +const setPaused = _paused => { + const didChange = paused !== _paused; + if (didChange) { + paused = _paused; + eventTarget.dispatchEvent(new CustomEvent("change")); + } + + // Don't check didChange as new threads could've started that we need to pause. + if (paused) { + audioContextStateChange = audioContextStateChange.then(() => { + return vm.runtime.audioEngine.audioContext.suspend(); + }); + if (!vm.runtime.ioDevices.clock._paused) { + vm.runtime.ioDevices.clock.pause(); + } + vm.runtime.threads.forEach(pauseThread); + const activeThread = vm.runtime.sequencer.activeThread; + if (activeThread) { + setSteppingThread(activeThread); + eventTarget.dispatchEvent(new CustomEvent("step")); + } + } + + // Only run unpausing logic when pause state changed to avoid unnecessary work + if (!paused && didChange) { + audioContextStateChange = audioContextStateChange.then(() => { + return vm.runtime.audioEngine.audioContext.resume(); + }); + vm.runtime.ioDevices.clock.resume(); + for (const thread of vm.runtime.threads) { + const pauseState = pausedThreadState.get(thread); + if (pauseState) { + compensateForTimePassedWhilePaused(thread, pauseState); + thread.status = pauseState.status; + } + } + pausedThreadState = new WeakMap(); + const lastSteppedThread = steppingThread; + // This must happen after the "change" event is fired to fix https://github.com/ScratchAddons/ScratchAddons/issues/4281 + stepUnsteppedThreads(lastSteppedThread); + steppingThread = null; + } +}; +const onPauseChanged = listener => { + eventTarget.addEventListener("change", () => listener(paused)); +}; +const onSingleStep = listener => { + eventTarget.addEventListener("step", listener); +}; +const getRunningThread = () => steppingThread; + +// A modified version of this function +// https://github.com/LLK/scratch-vm/blob/0e86a78a00db41af114df64255e2cd7dd881329f/src/engine/sequencer.js#L179 +// Returns if we should continue executing this thread. +const singleStepThread = thread => { + if (thread.status === STATUS_DONE) { + return false; + } + // TW: Can't single-step compiled threads + if (thread.isCompiled) { + return false; + } + const currentBlockId = thread.peekStack(); + if (!currentBlockId) { + thread.popStack(); + if (thread.stack.length === 0) { + thread.status = STATUS_DONE; + return false; + } + } + pauseNewThreads = true; + vm.runtime.sequencer.activeThread = thread; + + /* + We need to call execute(this, thread) like the original sequencer. We don't + have access to that method, so we need to force the original stepThread to run + execute for us then exit before it tries to run more blocks. + So, we make `thread.blockGlowInFrame = ...` throw an exception, so this line: + https://github.com/LLK/scratch-vm/blob/bb352913b57991713a5ccf0b611fda91056e14ec/src/engine/sequencer.js#L214 + will end the function early. We then have to set it back to normal afterward. + Why are we here just to suffer? + */ + const specialError = ["special error used by Scratch Addons for implementing single-stepping"]; + Object.defineProperty(thread, "blockGlowInFrame", { + set(_block) { + throw specialError; + } + }); + try { + thread.status = STATUS_RUNNING; + + // Restart the warp timer on each step. + // If we don't do this, Scratch will think a lot of time has passed and may yield this thread. + if (thread.warpTimer) { + thread.warpTimer.start(); + } + try { + vm.runtime.sequencer.stepThread(thread); + } catch (err) { + if (err !== specialError) throw err; + } + if (thread.status !== STATUS_RUNNING) { + return false; + } + if (thread.peekStack() === currentBlockId) { + thread.goToNextBlock(); + } + while (!thread.peekStack()) { + thread.popStack(); + if (thread.stack.length === 0) { + thread.status = STATUS_DONE; + return false; + } + const stackFrame = thread.peekStackFrame(); + if (stackFrame.isLoop) { + if (thread.peekStackFrame().warpMode) { + continue; + } else { + return false; + } + } else if (stackFrame.waitingReporter) { + return false; + } + thread.goToNextBlock(); + } + return true; + } finally { + pauseNewThreads = false; + vm.runtime.sequencer.activeThread = null; + Object.defineProperty(thread, "blockGlowInFrame", { + value: currentBlockId, + configurable: true, + enumerable: true, + writable: true + }); + + // Strictly this doesn't seem to be necessary, but let's make sure the thread is still paused after we step it. + if (thread.status !== STATUS_DONE) { + thread.status = STATUS_PROMISE_WAIT; + } + } +}; +const getRealStatus = thread => { + const pauseState = pausedThreadState.get(thread); + if (pauseState) { + return pauseState.status; + } + return thread.status; +}; +const getThreadIndex = thread => { + // We can't use vm.runtime.threads.indexOf(thread) because threads can be restarted. + // This can happens when, for example, a "when I receive message1" script broadcasts message1. + // The object in runtime.threads is replaced when this happens. + if (!thread) return -1; + return vm.runtime.threads.findIndex(otherThread => otherThread.target === thread.target && otherThread.topBlock === thread.topBlock && otherThread.stackClick === thread.stackClick && otherThread.updateMonitor === thread.updateMonitor); +}; +const findNewSteppingThread = startingIndex => { + const threads = vm.runtime.threads; + for (let i = startingIndex; i < threads.length; i++) { + const possibleNewThread = threads[i]; + if (possibleNewThread.updateMonitor) { + // Never single-step monitor update threads. + continue; + } + // TW: Can't single-step compiled threads + if (possibleNewThread.isCompiled) { + continue; + } + const status = getRealStatus(possibleNewThread); + if (status === STATUS_RUNNING || status === STATUS_YIELD || status === STATUS_YIELD_TICK) { + // Thread must not be running for single stepping to work. + pauseThread(possibleNewThread); + return possibleNewThread; + } + } + return null; +}; +const singleStep = () => { + if (steppingThread) { + const pauseState = pausedThreadState.get(steppingThread); + // We can assume pauseState is defined as any single stepping threads must already be paused. + + // Make it look like no time has passed + compensateForTimePassedWhilePaused(steppingThread, pauseState); + pauseState.time = vm.runtime.currentMSecs; + + // Execute the block + const continueExecuting = singleStepThread(steppingThread); + if (!continueExecuting) { + // Try to move onto the next thread + steppingThread = findNewSteppingThread(getThreadIndex(steppingThread) + 1); + } + } + + // If we don't have a thread, than we are between VM steps and should search for a new thread + if (!steppingThread) { + setSteppingThread(findNewSteppingThread(0)); + + // End of VM step, emulate one frame of time passing. + vm.runtime.ioDevices.clock._pausedTime += vm.runtime.currentStepTime; + // Skip all sounds forward by vm.runtime.currentStepTime milliseconds so it's as + // if they where playing for one frame. + const audioContext = vm.runtime.audioEngine.audioContext; + for (const target of vm.runtime.targets) { + for (const soundId of Object.keys(target.sprite.soundBank.soundPlayers)) { + const soundPlayer = target.sprite.soundBank.soundPlayers[soundId]; + if (soundPlayer.outputNode) { + soundPlayer.outputNode.stop(audioContext.currentTime); + soundPlayer._createSource(); + soundPlayer.outputNode.start(audioContext.currentTime, audioContext.currentTime - soundPlayer.startingUntil + vm.runtime.currentStepTime / 1000); + soundPlayer.startingUntil -= vm.runtime.currentStepTime / 1000; + } + } + } + // Move all threads forward one frame in time. For blocks like `wait () seconds` + for (const thread of vm.runtime.threads) { + if (pausedThreadState.has(thread)) { + pausedThreadState.get(thread).time += vm.runtime.currentStepTime; + } + } + + // Try to run edge activated hats + pauseNewThreads = true; + const hats = vm.runtime._hats; + for (const hatType in hats) { + if (!Object.prototype.hasOwnProperty.call(hats, hatType)) continue; + const hat = hats[hatType]; + if (hat.edgeActivated) { + vm.runtime.startHats(hatType); + } + } + pauseNewThreads = false; + } + eventTarget.dispatchEvent(new CustomEvent("step")); +}; +const setup = _vm => { + if (vm) { + return; + } + vm = _vm; + const originalStepThreads = vm.runtime.sequencer.stepThreads; + vm.runtime.sequencer.stepThreads = function () { + if (isPaused()) { + for (const thread of this.runtime.threads) { + ensurePausedThreadIsStillPaused(thread); + } + } + return originalStepThreads.call(this); + }; + + // Unpause when green flag + const originalGreenFlag = vm.runtime.greenFlag; + vm.runtime.greenFlag = function () { + setPaused(false); + return originalGreenFlag.call(this); + }; + + // Disable edge-activated hats and hats like "when key pressed" while paused. + const originalStartHats = vm.runtime.startHats; + vm.runtime.startHats = function () { + for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { + args[_key] = arguments[_key]; + } + const hat = args[0]; + // These hats can be manually started by the user when paused or while single stepping. + const isUserInitiated = hat === "event_whenbroadcastreceived" || hat === "control_start_as_clone"; + if (pauseNewThreads) { + if (!isUserInitiated && !this.getIsEdgeActivatedHat(hat)) { + return []; + } + const newThreads = originalStartHats.apply(this, args); + for (const thread of newThreads) { + pauseThread(thread); + } + return newThreads; + } else if (paused && !isUserInitiated) { + return []; + } + return originalStartHats.apply(this, args); + }; + + // Paused threads should not be counted as running when updating GUI state. + const originalGetMonitorThreadCount = vm.runtime._getMonitorThreadCount; + vm.runtime._getMonitorThreadCount = function (threads) { + let count = originalGetMonitorThreadCount.call(this, threads); + if (paused) { + for (const thread of threads) { + if (pausedThreadState.has(thread)) { + count++; + } + } + } + return count; + }; +}; + +/***/ }), + +/***/ "./src/addons/addons/debugger/performance.js": +/*!***************************************************!*\ + !*** ./src/addons/addons/debugger/performance.js ***! + \***************************************************/ +/*! exports provided: default */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return createPerformanceTab; }); +/* harmony import */ var _module_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./module.js */ "./src/addons/addons/debugger/module.js"); + +async function createPerformanceTab(_ref) { + let { + debug, + addon, + console, + msg + } = _ref; + const vm = addon.tab.traps.vm; + await addon.tab.loadScript(addon.self.getResource("/thirdparty/cs/chart.min.js")) /* rewritten by pull.js */; + const tab = debug.createHeaderTab({ + text: msg("tab-performance"), + icon: addon.self.getResource("/icons/performance.svg") /* rewritten by pull.js */ + }); + const content = Object.assign(document.createElement("div"), { + className: "sa-performance-tab-content" + }); + const createChart = _ref2 => { + let { + title + } = _ref2; + const titleElement = Object.assign(document.createElement("h2"), { + textContent: title + }); + const canvas = Object.assign(document.createElement("canvas"), { + className: "sa-debugger-chart" + }); + return { + title: titleElement, + canvas + }; + }; + const now = () => performance.now(); + const getMaxFps = () => Math.round(1000 / vm.runtime.currentStepTime); + const NUMBER_OF_POINTS = 20; + // An array like [9, 8, 7, 6, 5, 4, 3, 2, 1, 0] + const labels = Array.from(Array(NUMBER_OF_POINTS).keys()).reverse(); + const fpsElements = createChart({ + title: msg("performance-framerate-title") + }); + const fpsChart = new Chart(fpsElements.canvas.getContext("2d"), { + type: "line", + data: { + labels, + datasets: [{ + data: Array(NUMBER_OF_POINTS).fill(-1), + borderWidth: 1, + fill: true, + backgroundColor: "#29beb8" + }] + }, + options: { + scales: { + y: { + max: getMaxFps(), + min: 0 + } + }, + plugins: { + legend: { + display: false + }, + tooltip: { + callbacks: { + label: context => msg("performance-framerate-graph-tooltip", { + fps: context.parsed.y + }) + } + } + } + } + }); + const clonesElements = createChart({ + title: msg("performance-clonecount-title") + }); + const performanceClonesChart = new Chart(clonesElements.canvas.getContext("2d"), { + type: "line", + data: { + labels, + datasets: [{ + data: Array(NUMBER_OF_POINTS).fill(-1), + borderWidth: 1, + fill: true, + backgroundColor: "#29beb8" + }] + }, + options: { + scales: { + y: { + max: 300, + min: 0 + } + }, + plugins: { + legend: { + display: false + }, + tooltip: { + callbacks: { + label: context => msg("performance-clonecount-graph-tooltip", { + clones: context.parsed.y + }) + } + } + } + } + }); + + // Holds the times of each frame drawn in the last second. + // The length of this list is effectively the FPS. + const renderTimes = []; + + // The last time we pushed a new datapoint to the graph + let lastFpsTime = now() + 3000; + debug.addAfterStepCallback(() => { + if (Object(_module_js__WEBPACK_IMPORTED_MODULE_0__["isPaused"])()) { + return; + } + const time = now(); + + // Remove all frame times older than 1 second in renderTimes + while (renderTimes.length > 0 && renderTimes[0] <= time - 1000) renderTimes.shift(); + renderTimes.push(time); + if (time - lastFpsTime > 1000) { + lastFpsTime = time; + const maxFps = getMaxFps(); + const fpsData = fpsChart.data.datasets[0].data; + fpsData.shift(); + fpsData.push(Math.min(renderTimes.length, maxFps)); + // Incase we switch between 30FPS and 60FPS, update the max height of the chart. + fpsChart.options.scales.y.max = maxFps; + const clonesData = performanceClonesChart.data.datasets[0].data; + clonesData.shift(); + clonesData.push(vm.runtime._cloneCounter); + if (isVisible) { + fpsChart.update(); + performanceClonesChart.update(); + } + } + }); + content.appendChild(fpsElements.title); + content.appendChild(fpsElements.canvas); + content.appendChild(clonesElements.title); + content.appendChild(clonesElements.canvas); + let pauseTime = 0; + Object(_module_js__WEBPACK_IMPORTED_MODULE_0__["onPauseChanged"])(paused => { + if (paused) { + pauseTime = now(); + } else { + const dt = now() - pauseTime; + lastFpsTime += dt; + for (var i = 0; i < renderTimes.length; i++) { + renderTimes[i] += dt; + } + } + }); + let isVisible = false; + const show = () => { + isVisible = true; + }; + const hide = () => { + isVisible = false; + }; + return { + tab, + content, + buttons: [], + show, + hide + }; +} + +/***/ }), + +/***/ "./src/addons/addons/debugger/threads.js": +/*!***********************************************!*\ + !*** ./src/addons/addons/debugger/threads.js ***! + \***********************************************/ +/*! exports provided: default */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return createThreadsTab; }); +/* harmony import */ var _module_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./module.js */ "./src/addons/addons/debugger/module.js"); +/* harmony import */ var _log_view_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./log-view.js */ "./src/addons/addons/debugger/log-view.js"); +/* harmony import */ var _editor_stepping_highlighter_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../editor-stepping/highlighter.js */ "./src/addons/addons/editor-stepping/highlighter.js"); + + + +const concatInPlace = (copyInto, copyFrom) => { + for (const i of copyFrom) { + copyInto.push(i); + } +}; +async function createThreadsTab(_ref) { + let { + debug, + addon, + console, + msg + } = _ref; + const vm = addon.tab.traps.vm; + const tab = debug.createHeaderTab({ + text: msg("tab-threads"), + icon: addon.self.getResource("/icons/threads.svg") /* rewritten by pull.js */ + }); + const logView = new _log_view_js__WEBPACK_IMPORTED_MODULE_1__["default"](); + logView.canAutoScrollToEnd = false; + logView.outerElement.classList.add("sa-debugger-threads"); + logView.placeholderElement.textContent = msg("no-threads-running"); + const highlighter = new _editor_stepping_highlighter_js__WEBPACK_IMPORTED_MODULE_2__["default"](10, "#ff0000"); + logView.generateRow = row => { + const root = document.createElement("div"); + root.className = "sa-debugger-log"; + const isHeader = row.type === "thread-header"; + const indenter = document.createElement("div"); + indenter.className = "sa-debugger-thread-indent"; + indenter.style.setProperty("--level", isHeader ? row.depth : row.depth + 1); + root.appendChild(indenter); + if (isHeader) { + root.classList.add("sa-debugger-thread-title"); + if (row.depth > 0) { + const icon = document.createElement("div"); + icon.className = "sa-debugger-log-icon"; + root.appendChild(icon); + } + const name = document.createElement("div"); + name.textContent = row.targetName; + name.className = "sa-debugger-thread-target-name"; + root.appendChild(name); + const id = document.createElement("div"); + id.className = "sa-debugger-thread-id"; + id.textContent = msg("thread", { + id: row.id + }); + root.appendChild(id); + } + if (row.type === "thread-stack") { + const preview = debug.createBlockPreview(row.targetId, row.blockId); + if (preview) { + root.appendChild(preview); + } + } + + // pm: this isnt very useful if every thread will be compiled + // if (row.type === "compiled") { + // const el = document.createElement('div'); + // el.className = "sa-debugger-thread-compiled"; + // el.textContent = "Compiled threads can't be stepped and have no stack information."; + // root.appendChild(el); + // } + + if (row.targetId && row.blockId) { + root.appendChild(debug.createBlockLink(debug.getTargetInfoById(row.targetId), row.blockId)); + } + return { + root + }; + }; + logView.renderRow = (elements, row) => { + const { + root + } = elements; + root.classList.toggle("sa-debugger-thread-running", !!row.running); + }; + let threadInfoCache = new WeakMap(); + const allThreadIds = new WeakMap(); + let nextThreadId = 1; + const getThreadId = thread => { + if (!allThreadIds.has(thread)) { + allThreadIds.set(thread, nextThreadId++); + } + return allThreadIds.get(thread); + }; + const updateContent = () => { + if (!logView.visible) { + return; + } + const newRows = []; + const threads = vm.runtime.threads; + const visitedThreads = new Set(); + const createThreadInfo = (thread, depth) => { + if (visitedThreads.has(thread)) { + return []; + } + visitedThreads.add(thread); + const id = getThreadId(thread); + const target = thread.target; + if (!threadInfoCache.has(thread)) { + threadInfoCache.set(thread, { + headerItem: { + type: "thread-header", + depth, + targetName: target.getName(), + id + }, + compiledItem: thread.isCompiled ? { + type: "compiled", + depth: 1 + } : null, + blockCache: new WeakMap() + }); + } + const cacheInfo = threadInfoCache.get(thread); + const runningThread = Object(_module_js__WEBPACK_IMPORTED_MODULE_0__["getRunningThread"])(); + const createBlockInfo = (block, stackFrameIdx) => { + const blockId = block.id; + if (!block) return; + const stackFrame = thread.stackFrames[stackFrameIdx]; + if (!cacheInfo.blockCache.has(block)) { + cacheInfo.blockCache.set(block, {}); + } + const blockInfoMap = cacheInfo.blockCache.get(block); + let blockInfo = blockInfoMap[stackFrameIdx]; + if (!blockInfo) { + blockInfo = blockInfoMap[stackFrameIdx] = { + type: "thread-stack", + depth, + targetId: target.id, + blockId + }; + } + blockInfo.running = thread === runningThread && (thread.isCompiled || blockId === runningThread.peekStack() && stackFrameIdx === runningThread.stackFrames.length - 1); + const result = [blockInfo]; + if (stackFrame && stackFrame.executionContext && stackFrame.executionContext.startedThreads) { + for (const thread of stackFrame.executionContext.startedThreads) { + concatInPlace(result, createThreadInfo(thread, depth + 1)); + } + } + return result; + }; + const topBlock = debug.getBlock(thread.target, thread.topBlock); + const result = [cacheInfo.headerItem]; + if (topBlock) { + concatInPlace(result, createBlockInfo(topBlock, 0)); + for (let i = 0; i < thread.stack.length; i++) { + const blockId = thread.stack[i]; + if (blockId === topBlock.id) continue; + const block = debug.getBlock(thread.target, blockId); + if (block) { + concatInPlace(result, createBlockInfo(block, i)); + } + } + } + if (cacheInfo.compiledItem) { + result.push(cacheInfo.compiledItem); + } + return result; + }; + for (let i = 0; i < threads.length; i++) { + const thread = threads[i]; + // Do not display threads used to update variable and list monitors. + if (thread.updateMonitor) { + continue; + } + concatInPlace(newRows, createThreadInfo(thread, 0)); + } + logView.rows = newRows; + logView.queueUpdateContent(); + }; + debug.addAfterStepCallback(() => { + updateContent(); + const runningThread = Object(_module_js__WEBPACK_IMPORTED_MODULE_0__["getRunningThread"])(); + if (runningThread) { + highlighter.setGlowingThreads([runningThread]); + } else { + highlighter.setGlowingThreads([]); + } + }); + const stepButton = debug.createHeaderButton({ + text: msg("step"), + icon: addon.self.getResource("/icons/step.svg") /* rewritten by pull.js */, + description: msg("step-desc") + }); + stepButton.element.addEventListener("click", () => { + Object(_module_js__WEBPACK_IMPORTED_MODULE_0__["singleStep"])(); + }); + const handlePauseChanged = paused => { + stepButton.element.style.display = paused ? "" : "none"; + updateContent(); + }; + handlePauseChanged(Object(_module_js__WEBPACK_IMPORTED_MODULE_0__["isPaused"])()); + Object(_module_js__WEBPACK_IMPORTED_MODULE_0__["onPauseChanged"])(handlePauseChanged); + Object(_module_js__WEBPACK_IMPORTED_MODULE_0__["onSingleStep"])(updateContent); + const show = () => { + logView.show(); + updateContent(); + }; + const hide = () => { + logView.hide(); + }; + return { + tab, + content: logView.outerElement, + buttons: [stepButton], + show, + hide + }; +} + +/***/ }), + +/***/ "./src/addons/addons/debugger/userscript.js": +/*!**************************************************!*\ + !*** ./src/addons/addons/debugger/userscript.js ***! + \**************************************************/ +/*! exports provided: default */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony import */ var _module_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./module.js */ "./src/addons/addons/debugger/module.js"); +/* harmony import */ var _logs_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./logs.js */ "./src/addons/addons/debugger/logs.js"); +/* harmony import */ var _threads_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./threads.js */ "./src/addons/addons/debugger/threads.js"); +/* harmony import */ var _performance_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./performance.js */ "./src/addons/addons/debugger/performance.js"); +/* harmony import */ var _find_bar_blockly_Utils_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../find-bar/blockly/Utils.js */ "./src/addons/addons/find-bar/blockly/Utils.js"); + + + + + +const removeAllChildren = element => { + while (element.firstChild) { + element.removeChild(element.firstChild); + } +}; +/* harmony default export */ __webpack_exports__["default"] = (async function (_ref) { + let { + addon, + console, + msg + } = _ref; + Object(_module_js__WEBPACK_IMPORTED_MODULE_0__["setup"])(addon.tab.traps.vm); + let logsTab; + const messagesLoggedBeforeLogsTabLoaded = []; + const logMessage = function logMessage() { + for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { + args[_key] = arguments[_key]; + } + if (logsTab) { + logsTab.addLog(...args); + } else { + messagesLoggedBeforeLogsTabLoaded.push(args); + } + }; + let hasLoggedPauseError = false; + const pause = (_, thread) => { + if (addon.tab.redux.state.scratchGui.mode.isPlayerOnly) { + if (!hasLoggedPauseError) { + logMessage(msg("cannot-pause-player"), thread, "error"); + hasLoggedPauseError = true; + } + return; + } + Object(_module_js__WEBPACK_IMPORTED_MODULE_0__["setPaused"])(true); + setInterfaceVisible(true); + }; + addon.tab.addBlock("\u200B\u200Bbreakpoint\u200B\u200B", { + args: [], + displayName: msg("block-breakpoint"), + callback: pause + }); + addon.tab.addBlock("\u200B\u200Blog\u200B\u200B %s", { + args: ["content"], + displayName: msg("block-log"), + callback: (_ref2, thread) => { + let { + content + } = _ref2; + logMessage(content, thread, "log"); + } + }); + addon.tab.addBlock("\u200B\u200Bwarn\u200B\u200B %s", { + args: ["content"], + displayName: msg("block-warn"), + callback: (_ref3, thread) => { + let { + content + } = _ref3; + logMessage(content, thread, "warn"); + } + }); + addon.tab.addBlock("\u200B\u200Berror\u200B\u200B %s", { + args: ["content"], + displayName: msg("block-error"), + callback: (_ref4, thread) => { + let { + content + } = _ref4; + logMessage(content, thread, "error"); + } + }); + const vm = addon.tab.traps.vm; + await new Promise((resolve, reject) => { + if (vm.editingTarget) return resolve(); + vm.runtime.once("PROJECT_LOADED", resolve); + }); + const ScratchBlocks = await addon.tab.traps.getBlockly(); + const debuggerButtonOuter = document.createElement("div"); + debuggerButtonOuter.className = "sa-debugger-container"; + const debuggerButton = document.createElement("div"); + debuggerButton.className = addon.tab.scratchClass("button_outlined-button", "stage-header_stage-button"); + const debuggerButtonContent = document.createElement("div"); + debuggerButtonContent.className = addon.tab.scratchClass("button_content"); + const debuggerButtonImage = document.createElement("img"); + debuggerButtonImage.className = addon.tab.scratchClass("stage-header_stage-button-icon"); + debuggerButtonImage.draggable = false; + debuggerButtonImage.src = addon.self.getResource("/icons/debug.svg") /* rewritten by pull.js */; + debuggerButtonContent.appendChild(debuggerButtonImage); + debuggerButton.appendChild(debuggerButtonContent); + debuggerButtonOuter.appendChild(debuggerButton); + debuggerButton.addEventListener("click", () => setInterfaceVisible(true)); + const setHasUnreadMessage = unreadMessage => { + debuggerButtonContent.classList.toggle("sa-debugger-unread", unreadMessage); + }; + const interfaceContainer = Object.assign(document.createElement("div"), { + className: addon.tab.scratchClass("card_card", { + others: "sa-debugger-interface" + }) + }); + const interfaceHeader = Object.assign(document.createElement("div"), { + className: addon.tab.scratchClass("card_header-buttons") + }); + const tabListElement = Object.assign(document.createElement("ul"), { + className: "sa-debugger-tabs" + }); + const buttonContainerElement = Object.assign(document.createElement("div"), { + className: addon.tab.scratchClass("card_header-buttons-right", { + others: "sa-debugger-header-buttons" + }) + }); + const tabContentContainer = Object.assign(document.createElement("div"), { + className: "sa-debugger-tab-content" + }); + const compilerWarning = document.createElement("a"); + compilerWarning.addEventListener("click", () => { + addon.tab.redux.dispatch({ + type: "scratch-gui/modals/OPEN_MODAL", + modal: "settingsModal" + }); + }); + compilerWarning.className = "sa-debugger-log sa-debugger-compiler-warning"; + compilerWarning.textContent = "The debugger works best when the compiler is disabled."; + const updateCompilerWarningVisibility = () => { + // compilerWarning.hidden = !vm.runtime.compilerOptions.enabled; + compilerWarning.hidden = true; + }; + vm.on("COMPILER_OPTIONS_CHANGED", updateCompilerWarningVisibility); + updateCompilerWarningVisibility(); + let isInterfaceVisible = false; + const setInterfaceVisible = _isVisible => { + isInterfaceVisible = _isVisible; + interfaceContainer.style.display = isInterfaceVisible ? "flex" : ""; + if (isInterfaceVisible) { + activeTab.show(); + } else { + activeTab.hide(); + } + }; + let mouseOffsetX = 0; + let mouseOffsetY = 0; + let lastX = 0; + let lastY = 0; + const handleStartDrag = e => { + e.preventDefault(); + mouseOffsetX = e.clientX - interfaceContainer.offsetLeft; + mouseOffsetY = e.clientY - interfaceContainer.offsetTop; + lastX = e.clientX; + lastY = e.clientY; + document.addEventListener("mouseup", handleStopDrag); + document.addEventListener("mousemove", handleDragInterface); + }; + const handleStopDrag = () => { + document.removeEventListener("mouseup", handleStopDrag); + document.removeEventListener("mousemove", handleDragInterface); + }; + const moveInterface = (x, y) => { + lastX = x; + lastY = y; + const width = (document.documentElement.clientWidth || document.body.clientWidth) - 1; + const height = (document.documentElement.clientHeight || document.body.clientHeight) - 1; + const clampedX = Math.max(0, Math.min(x - mouseOffsetX, width - interfaceContainer.offsetWidth)); + const clampedY = Math.max(0, Math.min(y - mouseOffsetY, height - interfaceContainer.offsetHeight)); + interfaceContainer.style.left = clampedX + "px"; + interfaceContainer.style.top = clampedY + "px"; + }; + const handleDragInterface = e => { + e.preventDefault(); + moveInterface(e.clientX, e.clientY); + }; + window.addEventListener("resize", () => { + moveInterface(lastX, lastY); + }); + interfaceHeader.addEventListener("mousedown", handleStartDrag); + interfaceHeader.append(tabListElement, buttonContainerElement); + interfaceContainer.append(interfaceHeader, compilerWarning, tabContentContainer); + document.body.append(interfaceContainer); + const createHeaderButton = _ref5 => { + let { + text, + icon, + description + } = _ref5; + const button = Object.assign(document.createElement("div"), { + className: addon.tab.scratchClass("card_shrink-expand-button"), + draggable: false + }); + if (description) { + button.title = description; + } + const imageElement = Object.assign(document.createElement("img"), { + src: icon, + draggable: false + }); + const textElement = Object.assign(document.createElement("span"), { + textContent: text + }); + button.appendChild(imageElement); + button.appendChild(textElement); + return { + element: button, + image: imageElement, + text: textElement + }; + }; + const createHeaderTab = _ref6 => { + let { + text, + icon + } = _ref6; + const tab = document.createElement("li"); + const imageElement = Object.assign(document.createElement("img"), { + src: icon, + draggable: false + }); + const textElement = Object.assign(document.createElement("span"), { + textContent: text + }); + tab.appendChild(imageElement); + tab.appendChild(textElement); + return { + element: tab, + image: imageElement, + text: textElement + }; + }; + const unpauseButton = createHeaderButton({ + text: msg("unpause"), + icon: addon.self.getResource("/icons/play.svg") /* rewritten by pull.js */ + }); + unpauseButton.element.classList.add("sa-debugger-unpause"); + unpauseButton.element.addEventListener("click", () => Object(_module_js__WEBPACK_IMPORTED_MODULE_0__["setPaused"])(false)); + const updateUnpauseVisibility = paused => { + unpauseButton.element.style.display = paused ? "" : "none"; + }; + updateUnpauseVisibility(Object(_module_js__WEBPACK_IMPORTED_MODULE_0__["isPaused"])()); + Object(_module_js__WEBPACK_IMPORTED_MODULE_0__["onPauseChanged"])(updateUnpauseVisibility); + const closeButton = createHeaderButton({ + text: msg("close"), + icon: addon.self.getResource("/icons/close.svg") /* rewritten by pull.js */ + }); + closeButton.element.addEventListener("click", () => setInterfaceVisible(false)); + const originalStep = vm.runtime._step; + const afterStepCallbacks = []; + vm.runtime._step = function () { + for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { + args[_key2] = arguments[_key2]; + } + const ret = originalStep.call(this, ...args); + for (const cb of afterStepCallbacks) { + cb(); + } + return ret; + }; + const addAfterStepCallback = cb => { + afterStepCallbacks.push(cb); + }; + const getBlock = (target, id) => target.blocks.getBlock(id) || vm.runtime.flyoutBlocks.getBlock(id); + const getTargetInfoById = id => { + const target = vm.runtime.getTargetById(id); + if (target) { + let name = target.getName(); + let original = target; + if (!target.isOriginal) { + name = msg("clone-of", { + sprite: name + }); + original = target.sprite.clones[0]; + } + return { + exists: true, + originalId: original.id, + name + }; + } + return { + exists: false, + original: null, + name: msg("unknown-sprite") + }; + }; + const createBlockLink = (targetInfo, blockId) => { + const link = document.createElement("a"); + link.className = "sa-debugger-log-link"; + const { + exists, + name, + originalId + } = targetInfo; + link.textContent = name; + if (exists) { + // We use mousedown instead of click so that you can still go to blocks when logs are rapidly scrolling + link.addEventListener("mousedown", () => { + switchToSprite(originalId); + activateCodeTab(); + goToBlock(blockId); + }); + } else { + link.classList.add("sa-debugger-log-link-unknown"); + } + return link; + }; + const switchToSprite = targetId => { + if (targetId !== vm.editingTarget.id) { + if (vm.runtime.getTargetById(targetId)) { + vm.setEditingTarget(targetId); + } + } + }; + const activateCodeTab = () => { + const redux = addon.tab.redux; + if (redux.state.scratchGui.editorTab.activeTabIndex !== 0) { + redux.dispatch({ + type: "scratch-gui/navigation/ACTIVATE_TAB", + activeTabIndex: 0 + }); + } + }; + const goToBlock = blockId => { + const workspace = Blockly.getMainWorkspace(); + const block = workspace.getBlockById(blockId); + if (!block) return; + + // Don't scroll to blocks in the flyout + if (block.workspace.isFlyout) return; + new _find_bar_blockly_Utils_js__WEBPACK_IMPORTED_MODULE_4__["default"](addon).scrollBlockIntoView(blockId); + }; + + /** + * @param {string} procedureCode + * @returns {string} + */ + const formatProcedureCode = procedureCode => { + const customBlock = addon.tab.getCustomBlock(procedureCode); + if (customBlock) { + procedureCode = customBlock.displayName; + } + // May be slightly incorrect in some edge cases. + return procedureCode.replace(/%[nbs]/g, "()"); + }; + + // May be slightly incorrect in some edge cases. + const formatBlocklyBlockData = jsonData => { + // For sample jsonData, see: + // https://github.com/LLK/scratch-blocks/blob/0bd1a17e66a779ec5d11f4a00c43784e3ac7a7b8/blocks_vertical/motion.js + // https://github.com/LLK/scratch-blocks/blob/0bd1a17e66a779ec5d11f4a00c43784e3ac7a7b8/blocks_vertical/control.js + + const processSegment = index => { + const message = jsonData["message".concat(index)]; + const args = jsonData["args".concat(index)]; + if (!message) { + return null; + } + const parts = message.split(/%\d+/g); + let formattedMessage = ""; + for (let i = 0; i < parts.length; i++) { + formattedMessage += parts[i]; + const argInfo = args && args[i]; + if (argInfo) { + const type = argInfo.type; + if (type === "field_vertical_separator") { + // no-op + } else if (type === "field_image") { + const src = argInfo.src; + if (src.endsWith("rotate-left.svg")) { + formattedMessage += "↩"; + } else if (src.endsWith("rotate-right.svg")) { + formattedMessage += "↪"; + } + } else { + formattedMessage += "()"; + } + } + } + return formattedMessage; + }; + const parts = []; + let i = 0; + // The jsonData doesn't directly tell us how many segments it has, so we have to + // just keep looping until one doesn't exist. + while (true) { + const nextSegment = processSegment(i); + if (nextSegment) { + parts.push(nextSegment); + } else { + break; + } + i++; + } + return parts.join(" "); + }; + const createBlockPreview = (targetId, blockId) => { + const target = vm.runtime.getTargetById(targetId); + if (!target) { + return null; + } + const block = getBlock(target, blockId); + if (!block || block.opcode === "text") { + return null; + } + let text; + let category; + let shape; + if (block.opcode === "data_variable" || block.opcode === "data_listcontents" || block.opcode === "argument_reporter_string_number" || block.opcode === "argument_reporter_boolean") { + text = Object.values(block.fields)[0].value; + if (block.opcode === "data_variable") { + category = "data"; + } else if (block.opcode === "data_listcontents") { + category = "list"; + } else { + category = "more"; + } + shape = "round"; + } else if (block.opcode === "procedures_call") { + const proccode = block.mutation.proccode; + text = formatProcedureCode(proccode); + const customBlock = addon.tab.getCustomBlock(proccode); + if (customBlock) { + category = "addon-custom-block"; + } else { + category = "more"; + } + } else if (block.opcode === "procedures_definition" || block.opcode === "procedures_definition_return") { + const prototypeBlockId = block.inputs.custom_block.block; + const prototypeBlock = getBlock(target, prototypeBlockId); + const proccode = prototypeBlock.mutation.proccode; + text = ScratchBlocks.ScratchMsgs.translate("PROCEDURES_DEFINITION", "define %1").replace("%1", formatProcedureCode(proccode)); + category = "more"; + } else { + var _jsonData$extensions; + // Try to call things like https://github.com/LLK/scratch-blocks/blob/0bd1a17e66a779ec5d11f4a00c43784e3ac7a7b8/blocks_vertical/operators.js#L36 + var jsonData; + const fakeBlock = { + jsonInit(data) { + jsonData = data; + } + }; + const blockConstructor = ScratchBlocks.Blocks[block.opcode]; + if (blockConstructor) { + try { + blockConstructor.init.call(fakeBlock); + } catch (e) { + // ignore + } + } + if (!jsonData) { + return null; + } + text = formatBlocklyBlockData(jsonData); + if (!text) { + return null; + } + // jsonData.extensions is not guaranteed to exist + category = (_jsonData$extensions = jsonData.extensions) !== null && _jsonData$extensions !== void 0 && _jsonData$extensions.includes("scratch_extension") ? "pen" : jsonData.category; + const isStatement = jsonData.extensions && (jsonData.extensions.includes("shape_statement") || jsonData.extensions.includes("shape_hat") || jsonData.extensions.includes("shape_end")) || "previousStatement" in jsonData || "nextStatement" in jsonData; + shape = isStatement ? "stacked" : "round"; + } + if (!text || !category) { + return null; + } + const element = document.createElement("span"); + element.className = "sa-debugger-block-preview sa-block-color"; + element.textContent = text; + element.dataset.shape = shape; + element.classList.add("sa-block-color-".concat(category)); + return element; + }; + const api = { + debug: { + createHeaderButton, + createHeaderTab, + setHasUnreadMessage, + addAfterStepCallback, + getBlock, + getTargetInfoById, + createBlockLink, + createBlockPreview + }, + addon, + msg, + console + }; + logsTab = await Object(_logs_js__WEBPACK_IMPORTED_MODULE_1__["default"])(api); + const threadsTab = await Object(_threads_js__WEBPACK_IMPORTED_MODULE_2__["default"])(api); + const allTabs = [logsTab, threadsTab]; + for (const message of messagesLoggedBeforeLogsTabLoaded) { + logsTab.addLog(...message); + } + messagesLoggedBeforeLogsTabLoaded.length = 0; + let activeTab; + const setActiveTab = tab => { + if (tab === activeTab) return; + const selectedClass = "sa-debugger-tab-selected"; + if (activeTab) { + activeTab.hide(); + activeTab.tab.element.classList.remove(selectedClass); + } + tab.tab.element.classList.add(selectedClass); + activeTab = tab; + removeAllChildren(tabContentContainer); + tabContentContainer.appendChild(tab.content); + removeAllChildren(buttonContainerElement); + buttonContainerElement.appendChild(unpauseButton.element); + for (const button of tab.buttons) { + buttonContainerElement.appendChild(button.element); + } + buttonContainerElement.appendChild(closeButton.element); + if (isInterfaceVisible) { + activeTab.show(); + } + }; + for (const tab of allTabs) { + tab.tab.element.addEventListener("click", () => { + setActiveTab(tab); + }); + tabListElement.appendChild(tab.tab.element); + } + setActiveTab(allTabs[0]); + if (addon.tab.redux.state && addon.tab.redux.state.scratchGui.stageSize.stageSize === "small") { + document.body.classList.add("sa-debugger-small"); + } + document.addEventListener("click", e => { + if (e.target.closest("[class*='stage-header_stage-button-first']:not(.sa-hide-stage-button)")) { + document.body.classList.add("sa-debugger-small"); + } else if (e.target.closest("[class*='stage-header_stage-button-last']") || e.target.closest(".sa-hide-stage-button")) { + document.body.classList.remove("sa-debugger-small"); + } + }, { + capture: true + }); + const ogGreenFlag = vm.runtime.greenFlag; + vm.runtime.greenFlag = function () { + if (addon.settings.get("log_clear_greenflag")) { + logsTab.clearLogs(); + } + if (addon.settings.get("log_greenflag")) { + logsTab.addLog(msg("log-msg-flag-clicked"), null, "internal"); + } + for (var _len3 = arguments.length, args = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) { + args[_key3] = arguments[_key3]; + } + return ogGreenFlag.call(this, ...args); + }; + const ogMakeClone = vm.runtime.targets[0].constructor.prototype.makeClone; + vm.runtime.targets[0].constructor.prototype.makeClone = function () { + if (addon.settings.get("log_failed_clone_creation") && !vm.runtime.clonesAvailable()) { + logsTab.addLog(msg("log-msg-clone-cap", { + sprite: this.getName() + }), vm.runtime.sequencer.activeThread, "internal-warn"); + } + for (var _len4 = arguments.length, args = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) { + args[_key4] = arguments[_key4]; + } + var clone = ogMakeClone.call(this, ...args); + if (addon.settings.get("log_clone_create") && clone) { + logsTab.addLog(msg("log-msg-clone-created", { + sprite: this.getName() + }), vm.runtime.sequencer.activeThread, "internal"); + } + return clone; + }; + const ogStartHats = vm.runtime.startHats; + vm.runtime.startHats = function (hat, optMatchFields) { + if (addon.settings.get("log_broadcasts") && hat === "event_whenbroadcastreceived") { + logsTab.addLog(msg("log-msg-broadcasted", { + broadcast: optMatchFields.BROADCAST_OPTION + }), vm.runtime.sequencer.activeThread, "internal"); + } + for (var _len5 = arguments.length, args = new Array(_len5 > 2 ? _len5 - 2 : 0), _key5 = 2; _key5 < _len5; _key5++) { + args[_key5 - 2] = arguments[_key5]; + } + return ogStartHats.call(this, hat, optMatchFields, ...args); + }; + while (true) { + await addon.tab.waitForElement('[class*="stage-header_stage-size-row"]', { + markAsSeen: true, + reduxEvents: ["scratch-gui/mode/SET_PLAYER", "scratch-gui/mode/SET_FULL_SCREEN", "fontsLoaded/SET_FONTS_LOADED", "scratch-gui/locales/SELECT_LOCALE"] + }); + if (addon.tab.editorMode === "editor") { + addon.tab.appendToSharedSpace({ + space: "stageHeader", + element: debuggerButtonOuter, + order: 0 + }); + } else { + setInterfaceVisible(false); + } + } +}); + +/***/ }), + +/***/ "./src/addons/addons/editor-stepping/highlighter.js": +/*!**********************************************************!*\ + !*** ./src/addons/addons/editor-stepping/highlighter.js ***! + \**********************************************************/ +/*! exports provided: default */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +const SVG_NS = "http://www.w3.org/2000/svg"; +const containerSvg = document.createElementNS(SVG_NS, "svg"); +// unfortunately we can't use display: none on this as that breaks filters +containerSvg.style.position = "fixed"; +containerSvg.style.top = "-999999px"; +containerSvg.style.width = "0"; +containerSvg.style.height = "0"; +document.body.appendChild(containerSvg); +let nextGlowerId = 0; +const highlightsPerElement = new WeakMap(); +const getHighlightersForElement = element => { + if (!highlightsPerElement.get(element)) { + highlightsPerElement.set(element, new Set()); + } + return highlightsPerElement.get(element); +}; +const updateHighlight = (element, highlighters) => { + let result; + for (const i of highlighters) { + if (!result || i.priority > result.priority) { + result = i; + } + } + if (result) { + element.style.filter = result.filter; + } else { + element.style.filter = ""; + } +}; +const addHighlight = (element, highlighter) => { + const highlighters = getHighlightersForElement(element); + highlighters.add(highlighter); + updateHighlight(element, highlighters); +}; +const removeHighlight = (element, highlighter) => { + const highlighters = getHighlightersForElement(element); + highlighters.delete(highlighter); + updateHighlight(element, highlighters); +}; +class Highlighter { + constructor(priority, color) { + this.priority = priority; + const id = "sa_glower_filter".concat(nextGlowerId++); + this.filter = "url(\"#".concat(id, "\")"); + this.previousElements = new Set(); + const filterElement = document.createElementNS(SVG_NS, "filter"); + filterElement.id = id; + filterElement.setAttribute("width", "180%"); + filterElement.setAttribute("height", "160%"); + filterElement.setAttribute("x", "-40%"); + filterElement.setAttribute("y", "-30%"); + const filterBlur = document.createElementNS(SVG_NS, "feGaussianBlur"); + filterBlur.setAttribute("in", "SourceGraphic"); + filterBlur.setAttribute("stdDeviation", "4"); + filterElement.appendChild(filterBlur); + const filterTransfer = document.createElementNS(SVG_NS, "feComponentTransfer"); + filterTransfer.setAttribute("result", "outBlur"); + filterElement.appendChild(filterTransfer); + const filterTransferTable = document.createElementNS(SVG_NS, "feFuncA"); + filterTransferTable.setAttribute("type", "table"); + filterTransferTable.setAttribute("tableValues", "0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1"); + filterTransfer.appendChild(filterTransferTable); + const filterFlood = document.createElementNS(SVG_NS, "feFlood"); + filterFlood.setAttribute("flood-opacity", "1"); + filterFlood.setAttribute("result", "outColor"); + filterElement.appendChild(filterFlood); + this.filterFlood = filterFlood; + const filterComposite = document.createElementNS(SVG_NS, "feComposite"); + filterComposite.setAttribute("in", "outColor"); + filterComposite.setAttribute("in2", "outBlur"); + filterComposite.setAttribute("operator", "in"); + filterComposite.setAttribute("result", "outGlow"); + filterElement.appendChild(filterComposite); + const filterFinalComposite = document.createElementNS(SVG_NS, "feComposite"); + filterFinalComposite.setAttribute("in", "SourceGraphic"); + filterFinalComposite.setAttribute("in2", "outGlow"); + filterFinalComposite.setAttribute("operator", "over"); + filterElement.appendChild(filterFinalComposite); + containerSvg.appendChild(filterElement); + this.setColor(color); + } + setColor(color) { + this.filterFlood.setAttribute("flood-color", color); + } + setGlowingThreads(threads) { + const elementsToHighlight = new Set(); + const workspace = Blockly.getMainWorkspace(); + if (workspace) { + for (const thread of threads) { + thread.stack.forEach(blockId => { + const block = workspace.getBlockById(blockId); + if (!block) { + return; + } + const childblock = thread.stack.find(i => { + let b = block; + while (b.childBlocks_.length) { + b = b.childBlocks_[b.childBlocks_.length - 1]; + if (i === b.id) return true; + } + return false; + }); + if (!childblock && block.svgPath_) { + const svgPath = block.svgPath_; + elementsToHighlight.add(svgPath); + } + }); + } + } + for (const element of this.previousElements) { + if (!elementsToHighlight.has(element)) { + removeHighlight(element, this); + } + } + for (const element of elementsToHighlight) { + if (!this.previousElements.has(element)) { + addHighlight(element, this); + } + } + this.previousElements = elementsToHighlight; + } +} +/* harmony default export */ __webpack_exports__["default"] = (Highlighter); + +/***/ }), + +/***/ "./src/addons/libraries/common/cs/download-blob.js": +/*!*********************************************************!*\ + !*** ./src/addons/libraries/common/cs/download-blob.js ***! + \*********************************************************/ +/*! exports provided: default */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +// From https://github.com/LLK/scratch-gui/blob/develop/src/lib/download-blob.js +/* harmony default export */ __webpack_exports__["default"] = ((filename, blob) => { + const downloadLink = document.createElement("a"); + document.body.appendChild(downloadLink); + + // Use special ms version if available to get it working on Edge. + if (navigator.msSaveOrOpenBlob) { + navigator.msSaveOrOpenBlob(blob, filename); + return; + } + if ("download" in HTMLAnchorElement.prototype) { + const url = window.URL.createObjectURL(blob); + downloadLink.href = url; + downloadLink.download = filename; + downloadLink.type = blob.type; + downloadLink.click(); + // remove the link after a timeout to prevent a crash on iOS 13 Safari + window.setTimeout(() => { + document.body.removeChild(downloadLink); + window.URL.revokeObjectURL(url); + }, 1000); + } else { + // iOS 12 Safari, open a new page and set href to data-uri + let popup = window.open("", "_blank"); + const reader = new FileReader(); + reader.onloadend = function () { + popup.location.href = reader.result; + popup = null; + }; + reader.readAsDataURL(blob); + } +}); + +/***/ }) + +}]); +//# sourceMappingURL=addon-entry-debugger.js.map \ No newline at end of file