From 81fed51b9fa003713a9841d436f0426c382deca4 Mon Sep 17 00:00:00 2001 From: Black-Hole <158blackhole@gmail.com> Date: Sat, 14 Mar 2020 20:03:43 +0800 Subject: [PATCH] feat(api): add rebirth.init api 1. If the init function is not called within 5 minutes, the task is considered to have failed --- .gitignore | 1 + README-zh.md | 15 +++----------- README.md | 18 +++------------- package.json | 23 +++++++++++++++++++++ src/chrome-extension/background.ts | 13 +++++++++++- src/chrome-extension/injected.ts | 2 +- src/chrome-extension/lib/recording.ts | 2 +- src/chrome-extension/lib/tabs.ts | 14 +++++++++++++ src/chrome-extension/typing/background.d.ts | 1 + src/chrome-extension/typing/rebirth.d.ts | 2 +- src/extensions_dist/background.js | 2 +- src/extensions_dist/injected.js | 2 +- 12 files changed, 62 insertions(+), 33 deletions(-) create mode 100644 package.json diff --git a/.gitignore b/.gitignore index 19adbb2..f59f6a9 100644 --- a/.gitignore +++ b/.gitignore @@ -93,3 +93,4 @@ typings/ .idea /examples/*/rebirth_data/* !/examples/*/rebirth_data/.gitkeep +.DS_Store \ No newline at end of file diff --git a/README-zh.md b/README-zh.md index e532ed2..b3b0742 100644 --- a/README-zh.md +++ b/README-zh.md @@ -56,6 +56,9 @@ docker run -dit -P --name rebirth_alo7 -v `pwd`/rebirth_alo7/logs:/etc/www/logs 在网页加载完毕后,将会注入一些api,供网页使用 ```javascript +// 初始化API (5分钟内如果没有调用,则认为任务失败),确保网页可以正常打开。 +rebirth.init(); + // 开始进行录制 rebirth.start(); @@ -109,18 +112,6 @@ module.exports = { }; ``` -### 业务运用 - -> 以下是我们公司的运用场景 - -我们是一个在线教育的公司。在实际业务场景中有一个需求是把上课过程录制下来,并进行 `AI` 分析,生成本节课的精彩视频,供学生及老师查看。 - -因为我们的应用是 `Electron` 开发的,所以一开始我们使用的是在老师端启动一个屏幕录制,把上课过程录制下来,但是这样做有一个缺点,就是严重依赖了老师的电脑设备及网络带宽,导致我们公司在招聘老师的过程中,电脑性能也是一个非常重要的考察目标。 - -为了招聘到更多优秀的老师,避免因为非老师自身问题导致的没有招聘,所带来的影响。从而我们研发出 `Rebirth` 项目。 - -我们的做法是把上课页面完整的复制一份(这里称作 `replay`),同时在上课过程中,记录下学生和老师的动作行为(鼠标移动、鼠标点击、键盘打字、课件翻页、老师及学生摄像头的画面等),再根据这些动作行为数据,在 `replay` 里进行一次复现,在复现过程中由 `Rebirth` 进行录制。从而达到降低老师设备及网络带宽的要求,而且我们一节课可以为公司节省 **6~8** 元人民币的开销,因为之前屏幕录制使用的是第三方服务。 - ### 贡献者 感谢这些了不起的人: diff --git a/README.md b/README.md index 9fc58ce..d633983 100644 --- a/README.md +++ b/README.md @@ -56,6 +56,9 @@ docker run -dit -P --name rebirth_alo7 -v `pwd`/rebirth_alo7/logs:/etc/www/logs After the webpage is loaded, some api will be injected for the webpage to use. ```javascript +// Initialize the API (if not called within 5 minutes, the task is considered to have failed) to ensure that the web page can be opened normally. +rebirth.init(); + // start record rebirth.start(); @@ -109,21 +112,6 @@ module.exports = { }; ``` -### Use of business - -> The following are the business scenarios of our company - -ALO7 is an online education company that provides an Intelligent EFL Ecosystem. - -One of ALO7 important product is ALO7 Online Tutoring-One-stop online tutoring solutions for schools and institutions. -During the online classes, we need to record the video of the class and analyze the quality of the class, meanwhile providing feedback for students and teachers. - -Our platform is implemented by `Electron`, and the video is recorded from the tutor’s portal,which requires tutors’ high-performance PC and good internet service, plenty of experienced tutors can’t make it teach the class on our platform due to this issue. - -This is how we optimized : - -record all tutors’ control during the class (e.g., move the cursor, type, video, etc), then generate a video based on the data we collected, that’s why this project is named `Rebirth`. It not only makes more tutors to teach classes but save **6~8** CNY for each class (recording the class is based on the third-party service). - ### Contributors Thanks goes to these wonderful people: diff --git a/package.json b/package.json new file mode 100644 index 0000000..2979a45 --- /dev/null +++ b/package.json @@ -0,0 +1,23 @@ +{ + "name": "rebirth", + "version": "1.0.0", + "description": "Record a web page on the server", + "main": "src/index.js", + "directories": { + "example": "examples" + }, + "devDependencies": {}, + "scripts": { + "changelog": "conventional-changelog -p angular -i CHANGELOG.md -s" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/alo7/rebirth.git" + }, + "author": "", + "license": "MIT", + "bugs": { + "url": "https://github.com/alo7/rebirth/issues" + }, + "homepage": "https://github.com/alo7/rebirth#readme" +} diff --git a/src/chrome-extension/background.ts b/src/chrome-extension/background.ts index 0ca44b2..9ca566c 100644 --- a/src/chrome-extension/background.ts +++ b/src/chrome-extension/background.ts @@ -17,6 +17,13 @@ const getRecordTasksAndStartTab = () => { sendLog('open url', { recordInfo: data }); + + // If the init function is not called within 5 minutes, the task is considered to have failed + const initTimeoutId = setTimeout(() => { + sendLog('initTimeout'); + actions.fail(id); + }, 1000 * 60 * 5); + tabs.setInitTimeoutId(id, initTimeoutId); }); }) .catch(e => { @@ -38,7 +45,7 @@ chrome.runtime.onConnect.addListener(port => { const params = [ currentTabId, tabs.getMediaRecorder(currentTabId) ]; if ([ 'pause', 'resume', 'fail' ].includes(data.action)) { - return actions[data.action](...params); + return actions[data.action as 'pause' | 'resume' | 'fail'](...params); } if (data.action === 'start') { @@ -58,5 +65,9 @@ chrome.runtime.onConnect.addListener(port => { type: 'ready' }); } + + if (data.action === 'init') { + clearTimeout(tabs.getInitTimeoutId(currentTabId)); + } }); }); diff --git a/src/chrome-extension/injected.ts b/src/chrome-extension/injected.ts index 67b9979..e8e8090 100644 --- a/src/chrome-extension/injected.ts +++ b/src/chrome-extension/injected.ts @@ -16,7 +16,7 @@ interface MyWindow extends Window { (window as MyWindow & typeof globalThis).rebirth = {} as rebirth; -[ 'pause', 'resume', 'fail' ].forEach((m) => { +[ 'init', 'pause', 'resume', 'fail' ].forEach(m => { (window as MyWindow & typeof globalThis).rebirth[m] = () => { const msg = { 'action': m, diff --git a/src/chrome-extension/lib/recording.ts b/src/chrome-extension/lib/recording.ts index bfabf79..5115d5f 100644 --- a/src/chrome-extension/lib/recording.ts +++ b/src/chrome-extension/lib/recording.ts @@ -126,7 +126,7 @@ const fail = (id: number): void => { recordFail(id); }; -const actions: { [keys: string]: Function } = { +const actions: { [keys in 'start' | 'pause' | 'resume' | 'stop' | 'fail']: Function } = { start, pause, resume, diff --git a/src/chrome-extension/lib/tabs.ts b/src/chrome-extension/lib/tabs.ts index f6d0e97..826766c 100644 --- a/src/chrome-extension/lib/tabs.ts +++ b/src/chrome-extension/lib/tabs.ts @@ -26,6 +26,10 @@ class Tabs { return (this.getTab(id) && this.getTab(id).fileName) ? this.getTab(id).fileName : 'fileName_is_null'; } + getInitTimeoutId (id: number) { + return (this.getTab(id) && this.getTab(id).initTimeoutId) ? this.getTab(id).initTimeoutId : 0; + } + createTab (id: number) { this.tabs[id] = Object.create(null); } @@ -67,6 +71,16 @@ class Tabs { this.tabs[id].fileName = makeID(8) + fileName; } } + + setInitTimeoutId (id: number, timeoutId: number) { + if (this.getTab(id) === null) { + this.createTab(id); + } + if (timeoutId !== this.tabs[id].initTimeoutId) { + this.tabs[id].initTimeoutId = timeoutId; + } + + } } const tabs = new Tabs(); diff --git a/src/chrome-extension/typing/background.d.ts b/src/chrome-extension/typing/background.d.ts index fff4f44..01c4c73 100644 --- a/src/chrome-extension/typing/background.d.ts +++ b/src/chrome-extension/typing/background.d.ts @@ -8,6 +8,7 @@ export type ITabs = { mediaRecorder: MediaRecorder; // MediaRecorder Object extraInfo: IRecursive; // Additional information to carry fileName: string; // Record saved file name + initTimeoutId: number; // init timeout id } } diff --git a/src/chrome-extension/typing/rebirth.d.ts b/src/chrome-extension/typing/rebirth.d.ts index 20876c7..8cf696f 100644 --- a/src/chrome-extension/typing/rebirth.d.ts +++ b/src/chrome-extension/typing/rebirth.d.ts @@ -1,3 +1,3 @@ -export type IAction = 'waiting' | 'start' | 'pause' | 'resume' | 'stop' | 'fail'; +export type IAction = 'init' | 'waiting' | 'start' | 'pause' | 'resume' | 'stop' | 'fail'; export type IActionHelper = 'setExtraInfo' | 'ready'; diff --git a/src/extensions_dist/background.js b/src/extensions_dist/background.js index 3b10850..efcd02a 100644 --- a/src/extensions_dist/background.js +++ b/src/extensions_dist/background.js @@ -1 +1 @@ -!function(e){var t={};function a(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,a),o.l=!0,o.exports}a.m=e,a.c=t,a.d=function(e,t,r){a.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},a.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},a.t=function(e,t){if(1&t&&(e=a(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(a.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)a.d(r,o,function(t){return e[t]}.bind(null,o));return r},a.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return a.d(t,"a",t),t},a.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},a.p="",a(a.s=2)}({2:function(e,t,a){"use strict";a.r(t);var r=function(e,t,a,r){return new(a||(a=Promise))((function(o,n){function i(e){try{c(r.next(e))}catch(e){n(e)}}function s(e){try{c(r.throw(e))}catch(e){n(e)}}function c(e){var t;e.done?o(e.value):(t=e.value,t instanceof a?t:new a((function(e){e(t)}))).then(i,s)}c((r=r.apply(e,t||[])).next())}))};const o=(e,t,a="info")=>{i("http://127.0.0.1/logHandle",{name:e,payload:t,level:a}).catch(e=>{console.error(e)})},n=e=>{let t="";const a="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",r=a.length;for(let o=0;ofetch(e,{body:JSON.stringify(t),method:"POST",cache:"no-cache",headers:{"content-type":"application/json"},mode:"cors",credentials:"include"});var s=new class{constructor(){this.tabs=Object.create(null)}getTab(e){return this.tabs[e]||null}getMediaRecorder(e){return this.getTab(e)&&this.getTab(e).mediaRecorder?this.getTab(e).mediaRecorder:null}getExtraInfo(e){return this.getTab(e)&&this.getTab(e).extraInfo?this.getTab(e).extraInfo:{}}getFileName(e){return this.getTab(e)&&this.getTab(e).fileName?this.getTab(e).fileName:"fileName_is_null"}createTab(e){this.tabs[e]=Object.create(null)}setAction(e,t){null===this.getTab(e)&&this.createTab(e),t!==this.tabs[e].action&&(this.tabs[e].action=t),o(`set action to ${t}`)}setMediaRecorder(e,t){null===this.getTab(e)&&this.createTab(e),this.tabs[e].mediaRecorder=t}setExtraInfo(e,t){null===this.getTab(e)&&this.createTab(e),this.tabs[e].extraInfo=Object.assign(Object.assign({},this.tabs[e].extraInfo),t)}setFileName(e,t){null===this.getTab(e)&&this.createTab(e),t!==this.tabs[e].fileName&&(this.tabs[e].fileName=n(8)+t)}};const c={audioBitsPerSecond:128e3,videoBitsPerSecond:25e5,mimeType:"video/webm;codecs=vp9"},l={type:"video/webm"};var d={start:(e,t,a)=>{s.setAction(e,"start"),chrome.tabs.update(e,{active:!0}),chrome.tabCapture.capture(((e,t)=>({video:!0,audio:!0,videoConstraints:{mandatory:{minWidth:e,minHeight:t,maxWidth:e,maxHeight:t,maxFrameRate:30,minFrameRate:30}}}))(t,a),t=>{if(null===t)return chrome.tabs.sendMessage(e,{error:chrome.runtime.lastError}),o("capture fail",{captureError:chrome.runtime.lastError},"error"),!1;const a=[],r=new MediaRecorder(t,c);r.ondataavailable=e=>{e.data&&e.data.size>0&&a.push(e.data)},r.onstop=()=>{const t=s.getFileName(e),r=new Blob(a,l),n=document.createElement("a");n.href=URL.createObjectURL(r),n.setAttribute("download",`${t}.webm`),n.click(),(e=>(o("checkFileDownload",{filenameRegex:e}),new Promise(t=>{const a=setTimeout(()=>{o("file download timeout",{filenameRegex:e},"warn"),t()},3e4),r=e=>{chrome.downloads.search({filenameRegex:e},n=>{0!==n.length&&"complete"===n[0].state?(clearTimeout(a),setTimeout(()=>{o("the file has been downloaded",{filenameRegex:e,downloadInfo:n[0]}),t()},3e3)):r(e)})};r(e)})))(t).then(()=>{((e,t)=>{i("http://127.0.0.1/completeRecord",{extraInfo:s.getExtraInfo(t),fileName:e}).catch(e=>{o("complete record task request send fail",{completeRecordTaskError:e.message},"error")})})(t,e)}).catch(e=>{o("file download fail",{fileName:t,fileDownloadFailMessage:e.message},"error")}),setTimeout(()=>{chrome.tabs.remove(e)},2e3)},s.setMediaRecorder(e,r),r.start()})},pause:(e,t)=>{s.setAction(e,"pause"),t.pause()},resume:(e,t)=>{s.setAction(e,"resume"),t.resume()},stop:(e,t,a)=>{s.setAction(e,"stop"),s.setFileName(e,a),t.stop(),t.stream.getTracks().forEach(e=>{e.stop()})},fail:e=>{(e=>{i("http://127.0.0.1/recordFail",{extraInfo:s.getExtraInfo(e)}).catch(e=>{o("record fail request send fail",{recordFail:e.message},"error")})})(e)}};const u=()=>{(()=>new Promise((e,t)=>{i("http://127.0.0.1/getRecord",{}).then(a=>r(void 0,void 0,void 0,(function*(){const r=yield a.json();return a.ok?e(r):t(r)}))).catch(e=>t(e))}))().then(e=>{chrome.tabs.create({url:e.material_url},t=>{const a=t.id;s.setAction(a,"waiting"),o("open url",{recordInfo:e})})}).catch(e=>{o("get record tasks fail",{getRecordTasksFail:e},"error")})};setTimeout(()=>{u()},3e3),chrome.runtime.onConnect.addListener(e=>{e.onMessage.addListener(t=>{const a=e.sender.tab.id,r=[a,s.getMediaRecorder(a)];return["pause","resume","fail"].includes(t.action)?d[t.action](...r):"start"===t.action?d.start(a,t.pageWidth,t.pageHeight):"stop"===t.action?d.stop(...r,t.fileName):"setExtraInfo"===t.action?s.setExtraInfo(a,t.extraInfo):void("ready"===t.action&&e.postMessage({type:"ready"}))})})}}); \ No newline at end of file +!function(e){var t={};function a(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,a),o.l=!0,o.exports}a.m=e,a.c=t,a.d=function(e,t,r){a.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},a.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},a.t=function(e,t){if(1&t&&(e=a(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(a.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)a.d(r,o,function(t){return e[t]}.bind(null,o));return r},a.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return a.d(t,"a",t),t},a.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},a.p="",a(a.s=2)}({2:function(e,t,a){"use strict";a.r(t);var r=function(e,t,a,r){return new(a||(a=Promise))((function(o,i){function n(e){try{c(r.next(e))}catch(e){i(e)}}function s(e){try{c(r.throw(e))}catch(e){i(e)}}function c(e){var t;e.done?o(e.value):(t=e.value,t instanceof a?t:new a((function(e){e(t)}))).then(n,s)}c((r=r.apply(e,t||[])).next())}))};const o=(e,t,a="info")=>{n("http://127.0.0.1/logHandle",{name:e,payload:t,level:a}).catch(e=>{console.error(e)})},i=e=>{let t="";const a="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",r=a.length;for(let o=0;ofetch(e,{body:JSON.stringify(t),method:"POST",cache:"no-cache",headers:{"content-type":"application/json"},mode:"cors",credentials:"include"});var s=new class{constructor(){this.tabs=Object.create(null)}getTab(e){return this.tabs[e]||null}getMediaRecorder(e){return this.getTab(e)&&this.getTab(e).mediaRecorder?this.getTab(e).mediaRecorder:null}getExtraInfo(e){return this.getTab(e)&&this.getTab(e).extraInfo?this.getTab(e).extraInfo:{}}getFileName(e){return this.getTab(e)&&this.getTab(e).fileName?this.getTab(e).fileName:"fileName_is_null"}getInitTimeoutId(e){return this.getTab(e)&&this.getTab(e).initTimeoutId?this.getTab(e).initTimeoutId:0}createTab(e){this.tabs[e]=Object.create(null)}setAction(e,t){null===this.getTab(e)&&this.createTab(e),t!==this.tabs[e].action&&(this.tabs[e].action=t),o(`set action to ${t}`)}setMediaRecorder(e,t){null===this.getTab(e)&&this.createTab(e),this.tabs[e].mediaRecorder=t}setExtraInfo(e,t){null===this.getTab(e)&&this.createTab(e),this.tabs[e].extraInfo=Object.assign(Object.assign({},this.tabs[e].extraInfo),t)}setFileName(e,t){null===this.getTab(e)&&this.createTab(e),t!==this.tabs[e].fileName&&(this.tabs[e].fileName=i(8)+t)}setInitTimeoutId(e,t){null===this.getTab(e)&&this.createTab(e),t!==this.tabs[e].initTimeoutId&&(this.tabs[e].initTimeoutId=t)}};const c={audioBitsPerSecond:128e3,videoBitsPerSecond:25e5,mimeType:"video/webm;codecs=vp9"},l={type:"video/webm"};var d={start:(e,t,a)=>{s.setAction(e,"start"),chrome.tabs.update(e,{active:!0}),chrome.tabCapture.capture(((e,t)=>({video:!0,audio:!0,videoConstraints:{mandatory:{minWidth:e,minHeight:t,maxWidth:e,maxHeight:t,maxFrameRate:30,minFrameRate:30}}}))(t,a),t=>{if(null===t)return chrome.tabs.sendMessage(e,{error:chrome.runtime.lastError}),o("capture fail",{captureError:chrome.runtime.lastError},"error"),!1;const a=[],r=new MediaRecorder(t,c);r.ondataavailable=e=>{e.data&&e.data.size>0&&a.push(e.data)},r.onstop=()=>{const t=s.getFileName(e),r=new Blob(a,l),i=document.createElement("a");i.href=URL.createObjectURL(r),i.setAttribute("download",`${t}.webm`),i.click(),(e=>(o("checkFileDownload",{filenameRegex:e}),new Promise(t=>{const a=setTimeout(()=>{o("file download timeout",{filenameRegex:e},"warn"),t()},3e4),r=e=>{chrome.downloads.search({filenameRegex:e},i=>{0!==i.length&&"complete"===i[0].state?(clearTimeout(a),setTimeout(()=>{o("the file has been downloaded",{filenameRegex:e,downloadInfo:i[0]}),t()},3e3)):r(e)})};r(e)})))(t).then(()=>{((e,t)=>{n("http://127.0.0.1/completeRecord",{extraInfo:s.getExtraInfo(t),fileName:e}).catch(e=>{o("complete record task request send fail",{completeRecordTaskError:e.message},"error")})})(t,e)}).catch(e=>{o("file download fail",{fileName:t,fileDownloadFailMessage:e.message},"error")}),setTimeout(()=>{chrome.tabs.remove(e)},2e3)},s.setMediaRecorder(e,r),r.start()})},pause:(e,t)=>{s.setAction(e,"pause"),t.pause()},resume:(e,t)=>{s.setAction(e,"resume"),t.resume()},stop:(e,t,a)=>{s.setAction(e,"stop"),s.setFileName(e,a),t.stop(),t.stream.getTracks().forEach(e=>{e.stop()})},fail:e=>{(e=>{n("http://127.0.0.1/recordFail",{extraInfo:s.getExtraInfo(e)}).catch(e=>{o("record fail request send fail",{recordFail:e.message},"error")})})(e)}};const u=()=>{(()=>new Promise((e,t)=>{n("http://127.0.0.1/getRecord",{}).then(a=>r(void 0,void 0,void 0,(function*(){const r=yield a.json();return a.ok?e(r):t(r)}))).catch(e=>t(e))}))().then(e=>{chrome.tabs.create({url:e.material_url},t=>{const a=t.id;s.setAction(a,"waiting"),o("open url",{recordInfo:e});const r=setTimeout(()=>{o("initTimeout"),d.fail(a)},3e5);s.setInitTimeoutId(a,r)})}).catch(e=>{o("get record tasks fail",{getRecordTasksFail:e},"error")})};setTimeout(()=>{u()},3e3),chrome.runtime.onConnect.addListener(e=>{e.onMessage.addListener(t=>{const a=e.sender.tab.id,r=[a,s.getMediaRecorder(a)];return["pause","resume","fail"].includes(t.action)?d[t.action](...r):"start"===t.action?d.start(a,t.pageWidth,t.pageHeight):"stop"===t.action?d.stop(...r,t.fileName):"setExtraInfo"===t.action?s.setExtraInfo(a,t.extraInfo):("ready"===t.action&&e.postMessage({type:"ready"}),void("init"===t.action&&clearTimeout(s.getInitTimeoutId(a))))})})}}); \ No newline at end of file diff --git a/src/extensions_dist/injected.js b/src/extensions_dist/injected.js index 4dcbddc..7d9f007 100644 --- a/src/extensions_dist/injected.js +++ b/src/extensions_dist/injected.js @@ -1 +1 @@ -!function(e){var t={};function n(o){if(t[o])return t[o].exports;var r=t[o]={i:o,l:!1,exports:{}};return e[o].call(r.exports,r,r.exports,n),r.l=!0,r.exports}n.m=e,n.c=t,n.d=function(e,t,o){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:o})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var o=Object.create(null);if(n.r(o),Object.defineProperty(o,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var r in e)n.d(o,r,function(t){return e[t]}.bind(null,r));return o},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=1)}([,function(e,t){window.rebirth={},["pause","resume","fail"].forEach(e=>{window.rebirth[e]=()=>{const t={action:e};window.postMessage(t,"*")}}),window.rebirth.start=()=>{window.postMessage({action:"start",pageWidth:document.documentElement.clientWidth,pageHeight:document.documentElement.clientHeight},"*")},window.rebirth.stop=e=>{window.postMessage({action:"stop",fileName:e},"*")},window.rebirth.setExtraInfo=e=>{window.postMessage({action:"setExtraInfo",extraInfo:e},"*")}}]); \ No newline at end of file +!function(e){var t={};function n(o){if(t[o])return t[o].exports;var r=t[o]={i:o,l:!1,exports:{}};return e[o].call(r.exports,r,r.exports,n),r.l=!0,r.exports}n.m=e,n.c=t,n.d=function(e,t,o){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:o})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var o=Object.create(null);if(n.r(o),Object.defineProperty(o,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var r in e)n.d(o,r,function(t){return e[t]}.bind(null,r));return o},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=1)}([,function(e,t){window.rebirth={},["init","pause","resume","fail"].forEach(e=>{window.rebirth[e]=()=>{const t={action:e};window.postMessage(t,"*")}}),window.rebirth.start=()=>{window.postMessage({action:"start",pageWidth:document.documentElement.clientWidth,pageHeight:document.documentElement.clientHeight},"*")},window.rebirth.stop=e=>{window.postMessage({action:"stop",fileName:e},"*")},window.rebirth.setExtraInfo=e=>{window.postMessage({action:"setExtraInfo",extraInfo:e},"*")}}]); \ No newline at end of file