UNPKG

@esotericsoftware/spine-player

Version:
129 lines (127 loc) 16.1 kB
/****************************************************************************** * Spine Runtimes License Agreement * Last updated April 5, 2025. Replaces all prior versions. * * Copyright (c) 2013-2025, Esoteric Software LLC * * Integration of the Spine Runtimes into software or otherwise creating * derivative works of the Spine Runtimes is permitted under the terms and * conditions of Section 2 of the Spine Editor License Agreement: * http://esotericsoftware.com/spine-editor-license * * Otherwise, it is permitted to integrate the Spine Runtimes into software * or otherwise create derivative works of the Spine Runtimes (collectively, * "Products"), provided that each user of the Products must obtain their own * Spine Editor license and redistribution of the Products in any form must * include this license and copyright notice. * * THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, * BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *****************************************************************************/ function loadScript(url) { return new Promise((resolve, reject) => { const script = document.createElement('script'); script.src = url; script.onload = () => resolve(); script.onerror = () => reject(new Error(`Script load error for ${url}`)); document.head.appendChild(script); }); } function loadCss(url) { return new Promise((resolve, reject) => { const link = document.createElement('link'); link.href = url; link.rel = 'stylesheet'; link.onload = () => resolve(); link.onerror = () => reject(new Error(`CSS load error for ${url}`)); document.head.appendChild(link); }); } export class SpinePlayerEditor { parent; static DEFAULT_CODE = ` <script src="https://esotericsoftware.com/files/spine-player/4.1/spine-player.js"></script> <link rel="stylesheet" href="https://esotericsoftware.com/files/spine-player/4.1/spine-player.css"> <div id="player-container" style="width: 100vw; height: 100vh;"></div> <script> new spine.SpinePlayer("player-container", { jsonUrl: "https://esotericsoftware.com/files/examples/4.1/spineboy/export/spineboy-pro.json", atlasUrl: "https://esotericsoftware.com/files/examples/4.1/spineboy/export/spineboy-pma.atlas" }); </script> `.trim(); prefix = `<html> <head> <style> body { margin: 0px; } </style> </head> <body>`.trim(); postfix = `</body>`; code; player; constructor(parent) { this.parent = parent; this.load(); } async load() { await Promise.all([loadScript("https://www.unpkg.com/codemirror@5.51.0/lib/codemirror.js"), loadCss("https://www.unpkg.com/codemirror@5.51.0/lib/codemirror.css")]); this.render(this.parent); } render(parent) { const dom = /*html*/ ` <div style="display: flex; flex-direction: column; width: 100%; height: 100%;"> <div style="width: 100%; height: 50%"></div> <iframe style="width: 100%; height: 50%; outline: none; border: none;"></iframe> </div> `; parent.innerHTML = dom; const codeElement = parent.children[0].children[0]; this.player = parent.children[0].children[1]; requestAnimationFrame(() => { this.code = CodeMirror(codeElement, { lineNumbers: true, tabSize: 3, indentUnit: 3, indentWithTabs: true, scrollBarStyle: "native", mode: "htmlmixed", theme: "monokai" }); this.code.on("change", () => { this.startPlayer(); }); codeElement.children[0].style.height = "100%"; this.setCode(SpinePlayerEditor.DEFAULT_CODE); }); } setPreAndPostfix(prefix, postfix) { this.prefix = prefix; this.postfix = postfix; this.startPlayer(); } setCode(code) { this.code.setValue(code); this.startPlayer(); } timerId = 0; startPlayer() { clearTimeout(this.timerId); this.timerId = setTimeout(() => { let code = this.code.getDoc().getValue(); code = this.prefix + code + this.postfix; code = window.btoa(code); this.player.src = ""; this.player.src = "data:text/html;base64," + code; }, 500); } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUGxheWVyRWRpdG9yLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL1BsYXllckVkaXRvci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OytFQTJCK0U7QUFJL0UsU0FBUyxVQUFVLENBQUUsR0FBVztJQUMvQixPQUFPLElBQUksT0FBTyxDQUFDLENBQUMsT0FBTyxFQUFFLE1BQU0sRUFBRSxFQUFFO1FBQ3RDLE1BQU0sTUFBTSxHQUFHLFFBQVEsQ0FBQyxhQUFhLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDaEQsTUFBTSxDQUFDLEdBQUcsR0FBRyxHQUFHLENBQUM7UUFDakIsTUFBTSxDQUFDLE1BQU0sR0FBRyxHQUFHLEVBQUUsQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUNoQyxNQUFNLENBQUMsT0FBTyxHQUFHLEdBQUcsRUFBRSxDQUFDLE1BQU0sQ0FBQyxJQUFJLEtBQUssQ0FBQyx5QkFBeUIsR0FBRyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQ3pFLFFBQVEsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQ25DLENBQUMsQ0FBQyxDQUFDO0FBQ0osQ0FBQztBQUVELFNBQVMsT0FBTyxDQUFFLEdBQVc7SUFDNUIsT0FBTyxJQUFJLE9BQU8sQ0FBQyxDQUFDLE9BQU8sRUFBRSxNQUFNLEVBQUUsRUFBRTtRQUN0QyxNQUFNLElBQUksR0FBRyxRQUFRLENBQUMsYUFBYSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQzVDLElBQUksQ0FBQyxJQUFJLEdBQUcsR0FBRyxDQUFDO1FBQ2hCLElBQUksQ0FBQyxHQUFHLEdBQUcsWUFBWSxDQUFDO1FBQ3hCLElBQUksQ0FBQyxNQUFNLEdBQUcsR0FBRyxFQUFFLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDOUIsSUFBSSxDQUFDLE9BQU8sR0FBRyxHQUFHLEVBQUUsQ0FBQyxNQUFNLENBQUMsSUFBSSxLQUFLLENBQUMsc0JBQXNC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QyxJQUFJLEdBQUcsSUFBSSxDQUFDLE1BQU0sR0FBRyxJQUFJLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQztZQUN6QyxJQUFJLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUN6QixJQUFJLENBQUMsTUFBTyxDQUFDLEdBQUcsR0FBRyxFQUFFLENBQUM7WUFDdEIsSUFBSSxDQUFDLE1BQU8sQ0FBQyxHQUFHLEdBQUcsd0JBQXdCLEdBQUcsSUFBSSxDQUFDO1FBQ3BELENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQztJQUNULENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXG4gKiBTcGluZSBSdW50aW1lcyBMaWNlbnNlIEFncmVlbWVudFxuICogTGFzdCB1cGRhdGVkIEFwcmlsIDUsIDIwMjUuIFJlcGxhY2VzIGFsbCBwcmlvciB2ZXJzaW9ucy5cbiAqXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTMtMjAyNSwgRXNvdGVyaWMgU29mdHdhcmUgTExDXG4gKlxuICogSW50ZWdyYXRpb24gb2YgdGhlIFNwaW5lIFJ1bnRpbWVzIGludG8gc29mdHdhcmUgb3Igb3RoZXJ3aXNlIGNyZWF0aW5nXG4gKiBkZXJpdmF0aXZlIHdvcmtzIG9mIHRoZSBTcGluZSBSdW50aW1lcyBpcyBwZXJtaXR0ZWQgdW5kZXIgdGhlIHRlcm1zIGFuZFxuICogY29uZGl0aW9ucyBvZiBTZWN0aW9uIDIgb2YgdGhlIFNwaW5lIEVkaXRvciBMaWNlbnNlIEFncmVlbWVudDpcbiAqIGh0dHA6Ly9lc290ZXJpY3NvZnR3YXJlLmNvbS9zcGluZS1lZGl0b3ItbGljZW5zZVxuICpcbiAqIE90aGVyd2lzZSwgaXQgaXMgcGVybWl0dGVkIHRvIGludGVncmF0ZSB0aGUgU3BpbmUgUnVudGltZXMgaW50byBzb2Z0d2FyZVxuICogb3Igb3RoZXJ3aXNlIGNyZWF0ZSBkZXJpdmF0aXZlIHdvcmtzIG9mIHRoZSBTcGluZSBSdW50aW1lcyAoY29sbGVjdGl2ZWx5LFxuICogXCJQcm9kdWN0c1wiKSwgcHJvdmlkZWQgdGhhdCBlYWNoIHVzZXIgb2YgdGhlIFByb2R1Y3RzIG11c3Qgb2J0YWluIHRoZWlyIG93blxuICogU3BpbmUgRWRpdG9yIGxpY2Vuc2UgYW5kIHJlZGlzdHJpYnV0aW9uIG9mIHRoZSBQcm9kdWN0cyBpbiBhbnkgZm9ybSBtdXN0XG4gKiBpbmNsdWRlIHRoaXMgbGljZW5zZSBhbmQgY29weXJpZ2h0IG5vdGljZS5cbiAqXG4gKiBUSEUgU1BJTkUgUlVOVElNRVMgQVJFIFBST1ZJREVEIEJZIEVTT1RFUklDIFNPRlRXQVJFIExMQyBcIkFTIElTXCIgQU5EIEFOWVxuICogRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRFxuICogV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRVxuICogRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgRVNPVEVSSUMgU09GVFdBUkUgTExDIEJFIExJQUJMRSBGT1IgQU5ZXG4gKiBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFU1xuICogKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTLFxuICogQlVTSU5FU1MgSU5URVJSVVBUSU9OLCBPUiBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUykgSE9XRVZFUiBDQVVTRUQgQU5EXG4gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVFxuICogKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GXG4gKiBUSEUgU1BJTkUgUlVOVElNRVMsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4gKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXG5cbmRlY2xhcmUgZnVuY3Rpb24gQ29kZU1pcnJvciAoZWw6IEVsZW1lbnQsIGNvbmZpZzogYW55KTogdm9pZDtcblxuZnVuY3Rpb24gbG9hZFNjcmlwdCAodXJsOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcblx0cmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcblx0XHRjb25zdCBzY3JpcHQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzY3JpcHQnKTtcblx0XHRzY3JpcHQuc3JjID0gdXJsO1xuXHRcdHNjcmlwdC5vbmxvYWQgPSAoKSA9PiByZXNvbHZlKCk7XG5cdFx0c2NyaXB0Lm9uZXJyb3IgPSAoKSA9PiByZWplY3QobmV3IEVycm9yKGBTY3JpcHQgbG9hZCBlcnJvciBmb3IgJHt1cmx9YCkpO1xuXHRcdGRvY3VtZW50LmhlYWQuYXBwZW5kQ2hpbGQoc2NyaXB0KTtcblx0fSk7XG59XG5cbmZ1bmN0aW9uIGxvYWRDc3MgKHVybDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG5cdHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG5cdFx0Y29uc3QgbGluayA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2xpbmsnKTtcblx0XHRsaW5rLmhyZWYgPSB1cmw7XG5cdFx0bGluay5yZWwgPSAnc3R5bGVzaGVldCc7XG5cdFx0bGluay5vbmxvYWQgPSAoKSA9PiByZXNvbHZlKCk7XG5cdFx0bGluay5vbmVycm9yID0gKCkgPT4gcmVqZWN0KG5ldyBFcnJvcihgQ1NTIGxvYWQgZXJyb3IgZm9yICR7dXJsfWApKTtcblx0XHRkb2N1bWVudC5oZWFkLmFwcGVuZENoaWxkKGxpbmspO1xuXHR9KTtcbn1cblxuZXhwb3J0IGNsYXNzIFNwaW5lUGxheWVyRWRpdG9yIHtcblx0cHJpdmF0ZSBzdGF0aWMgREVGQVVMVF9DT0RFID1cblx0XHRgXG48c2NyaXB0IHNyYz1cImh0dHBzOi8vZXNvdGVyaWNzb2Z0d2FyZS5jb20vZmlsZXMvc3BpbmUtcGxheWVyLzQuMS9zcGluZS1wbGF5ZXIuanNcIj48L3NjcmlwdD5cbjxsaW5rIHJlbD1cInN0eWxlc2hlZXRcIiBocmVmPVwiaHR0cHM6Ly9lc290ZXJpY3NvZnR3YXJlLmNvbS9maWxlcy9zcGluZS1wbGF5ZXIvNC4xL3NwaW5lLXBsYXllci5jc3NcIj5cblxuPGRpdiBpZD1cInBsYXllci1jb250YWluZXJcIiBzdHlsZT1cIndpZHRoOiAxMDB2dzsgaGVpZ2h0OiAxMDB2aDtcIj48L2Rpdj5cblxuPHNjcmlwdD5cbm5ldyBzcGluZS5TcGluZVBsYXllcihcInBsYXllci1jb250YWluZXJcIiwge1xuXHRqc29uVXJsOiBcImh0dHBzOi8vZXNvdGVyaWNzb2Z0d2FyZS5jb20vZmlsZXMvZXhhbXBsZXMvNC4xL3NwaW5lYm95L2V4cG9ydC9zcGluZWJveS1wcm8uanNvblwiLFxuXHRhdGxhc1VybDogXCJodHRwczovL2Vzb3Rlcmljc29mdHdhcmUuY29tL2ZpbGVzL2V4YW1wbGVzLzQuMS9zcGluZWJveS9leHBvcnQvc3BpbmVib3ktcG1hLmF0bGFzXCJcbn0pO1xuPC9zY3JpcHQ+XG5cdFx0YC50cmltKCk7XG5cblx0cHJpdmF0ZSBwcmVmaXg6IHN0cmluZyA9XG5cdFx0YDxodG1sPlxuPGhlYWQ+XG48c3R5bGU+XG5ib2R5IHsgbWFyZ2luOiAwcHg7IH1cbjwvc3R5bGU+XG48L2hlYWQ+XG48Ym9keT5gLnRyaW0oKVxuXHRwcml2YXRlIHBvc3RmaXg6IHN0cmluZyA9IGA8L2JvZHk+YDtcblx0cHJpdmF0ZSBjb2RlOiBhbnk7XG5cdHByaXZhdGUgcGxheWVyPzogSFRNTElGcmFtZUVsZW1lbnQ7XG5cblx0Y29uc3RydWN0b3IgKHByaXZhdGUgcmVhZG9ubHkgcGFyZW50OiBIVE1MRWxlbWVudCkge1xuXHRcdHRoaXMubG9hZCgpO1xuXHR9XG5cblx0cHJpdmF0ZSBhc3luYyBsb2FkICgpIHtcblx0XHRhd2FpdCBQcm9taXNlLmFsbChbbG9hZFNjcmlwdChcImh0dHBzOi8vd3d3LnVucGtnLmNvbS9jb2RlbWlycm9yQDUuNTEuMC9saWIvY29kZW1pcnJvci5qc1wiKSwgbG9hZENzcyhcImh0dHBzOi8vd3d3LnVucGtnLmNvbS9jb2RlbWlycm9yQDUuNTEuMC9saWIvY29kZW1pcnJvci5jc3NcIildKTtcblx0XHR0aGlzLnJlbmRlcih0aGlzLnBhcmVudCk7XG5cdH1cblxuXHRwcml2YXRlIHJlbmRlciAocGFyZW50OiBIVE1MRWxlbWVudCkge1xuXHRcdGNvbnN0IGRvbSA9IC8qaHRtbCovYFxuXHRcdFx0XHQ8ZGl2IHN0eWxlPVwiZGlzcGxheTogZmxleDsgZmxleC1kaXJlY3Rpb246IGNvbHVtbjsgd2lkdGg6IDEwMCU7IGhlaWdodDogMTAwJTtcIj5cblx0XHRcdFx0XHQ8ZGl2IHN0eWxlPVwid2lkdGg6IDEwMCU7IGhlaWdodDogNTAlXCI+PC9kaXY+XG5cdFx0XHRcdFx0PGlmcmFtZSBzdHlsZT1cIndpZHRoOiAxMDAlOyBoZWlnaHQ6IDUwJTsgb3V0bGluZTogbm9uZTsgYm9yZGVyOiBub25lO1wiPjwvaWZyYW1lPlxuXHRcdFx0XHQ8L2Rpdj5cblx0XHRcdGA7XG5cdFx0cGFyZW50LmlubmVySFRNTCA9IGRvbTtcblx0XHRjb25zdCBjb2RlRWxlbWVudCA9IHBhcmVudC5jaGlsZHJlblswXS5jaGlsZHJlblswXTtcblx0XHR0aGlzLnBsYXllciA9IHBhcmVudC5jaGlsZHJlblswXS5jaGlsZHJlblsxXSBhcyBIVE1MSUZyYW1lRWxlbWVudDtcblxuXHRcdHJlcXVlc3RBbmltYXRpb25GcmFtZSgoKSA9PiB7XG5cdFx0XHR0aGlzLmNvZGUgPSBDb2RlTWlycm9yKGNvZGVFbGVtZW50LCB7XG5cdFx0XHRcdGxpbmVOdW1iZXJzOiB0cnVlLFxuXHRcdFx0XHR0YWJTaXplOiAzLFxuXHRcdFx0XHRpbmRlbnRVbml0OiAzLFxuXHRcdFx0XHRpbmRlbnRXaXRoVGFiczogdHJ1ZSxcblx0XHRcdFx0c2Nyb2xsQmFyU3R5bGU6IFwibmF0aXZlXCIsXG5cdFx0XHRcdG1vZGU6IFwiaHRtbG1peGVkXCIsXG5cdFx0XHRcdHRoZW1lOiBcIm1vbm9rYWlcIlxuXHRcdFx0fSk7XG5cdFx0XHR0aGlzLmNvZGUub24oXCJjaGFuZ2VcIiwgKCkgPT4ge1xuXHRcdFx0XHR0aGlzLnN0YXJ0UGxheWVyKCk7XG5cdFx0XHR9KTtcblxuXHRcdFx0KGNvZGVFbGVtZW50LmNoaWxkcmVuWzBdIGFzIEhUTUxFbGVtZW50KS5zdHlsZS5oZWlnaHQgPSBcIjEwMCVcIjtcblx0XHRcdHRoaXMuc2V0Q29kZShTcGluZVBsYXllckVkaXRvci5ERUZBVUxUX0NPREUpO1xuXHRcdH0pXG5cdH1cblxuXHRzZXRQcmVBbmRQb3N0Zml4IChwcmVmaXg6IHN0cmluZywgcG9zdGZpeDogc3RyaW5nKSB7XG5cdFx0dGhpcy5wcmVmaXggPSBwcmVmaXg7XG5cdFx0dGhpcy5wb3N0Zml4ID0gcG9zdGZpeDtcblx0XHR0aGlzLnN0YXJ0UGxheWVyKClcblx0fVxuXG5cdHNldENvZGUgKGNvZGU6IHN0cmluZykge1xuXHRcdHRoaXMuY29kZS5zZXRWYWx1ZShjb2RlKTtcblx0XHR0aGlzLnN0YXJ0UGxheWVyKCk7XG5cdH1cblxuXHRwcml2YXRlIHRpbWVySWQ6IGFueSA9IDA7XG5cdHN0YXJ0UGxheWVyICgpIHtcblx0XHRjbGVhclRpbWVvdXQodGhpcy50aW1lcklkKTtcblx0XHR0aGlzLnRpbWVySWQgPSBzZXRUaW1lb3V0KCgpID0+IHtcblx0XHRcdGxldCBjb2RlID0gdGhpcy5jb2RlLmdldERvYygpLmdldFZhbHVlKCk7XG5cdFx0XHRjb2RlID0gdGhpcy5wcmVmaXggKyBjb2RlICsgdGhpcy5wb3N0Zml4O1xuXHRcdFx0Y29kZSA9IHdpbmRvdy5idG9hKGNvZGUpO1xuXHRcdFx0dGhpcy5wbGF5ZXIhLnNyYyA9IFwiXCI7XG5cdFx0XHR0aGlzLnBsYXllciEuc3JjID0gXCJkYXRhOnRleHQvaHRtbDtiYXNlNjQsXCIgKyBjb2RlO1xuXHRcdH0sIDUwMCk7XG5cdH1cbn1cbiJdfQ==