UNPKG

@react-native/debugger-frontend

Version:
2 lines (1 loc) • 22.8 kB
import*as e from"../../../core/common/common.js";import*as t from"../../../core/i18n/i18n.js";import*as r from"../../../third_party/puppeteer-replay/puppeteer-replay.js";import{AssertedEventType as s,StepType as n,SelectorType as i}from"../../../third_party/puppeteer-replay/puppeteer-replay.js";import*as a from"../../../ui/legacy/legacy.js";import*as o from"../../../core/sdk/sdk.js";import*as c from"../../../services/puppeteer/puppeteer.js";import*as d from"../../../core/platform/platform.js";import*as l from"../util/util.js";var g=Object.freeze({__proto__:null}),p=Object.freeze({__proto__:null,AssertedEventType:s,StepType:n,SelectorType:i});const h={defaultRecordingName:"Recording {DATE} at {TIME}"},u=t.i18n.registerUIStrings("panels/recorder/models/RecorderSettings.ts",h),m=t.i18n.getLocalizedString.bind(void 0,u);var f=Object.freeze({__proto__:null,RecorderSettings:class{#e=e.Settings.Settings.instance().createSetting("recorder-selector-attribute","");#t=e.Settings.Settings.instance().createSetting("recorder-panel-replay-speed","normal");#r=e.Settings.Settings.instance().createSetting("recorder-panel-replay-extension","");#s=new Map;#n=e.Settings.Settings.instance().createSetting("recorder-preferred-copy-format","json");constructor(){for(const t of Object.values(i))this.#s.set(t,e.Settings.Settings.instance().createSetting(`recorder-${t}-selector-enabled`,!0))}get selectorAttribute(){return this.#e.get()}set selectorAttribute(e){this.#e.set(e)}get speed(){return this.#t.get()}set speed(e){this.#t.set(e)}get replayExtension(){return this.#r.get()}set replayExtension(e){this.#r.set(e)}get defaultTitle(){const e=new Date;return m(h.defaultRecordingName,{DATE:e.toLocaleDateString(),TIME:e.toLocaleTimeString()})}get defaultSelectors(){return Object.values(i).filter((e=>this.getSelectorByType(e)))}getSelectorByType(e){return this.#s.get(e)?.get()}setSelectorByType(e,t){this.#s.get(e)?.set(t)}get preferredCopyFormat(){return this.#n.get()}set preferredCopyFormat(e){this.#n.set(e)}}});var y=Object.freeze({__proto__:null,RecorderShortcutHelper:class{#i;#a=null;#o;constructor(e=200){this.#o=e,this.#i=new AbortController}#c(){this.#i.abort(),this.#a&&clearTimeout(this.#a),this.#i=new AbortController}#d(e){this.#c(),e()}handleShortcut(e){this.#c(),document.addEventListener("keyup",(t=>{a.KeyboardShortcut.KeyboardShortcut.eventHasCtrlEquivalentKey(t)&&this.#d(e)}),{signal:this.#i.signal}),this.#a=setTimeout((()=>this.#d(e)),this.#o)}}});const w={normal:0,slow:500,very_slow:1e3,extremely_slow:2e3};function v(t){return e.ParsedURL.schemeIs(t.url,"devtools:")||"page"===t.type||"background_page"===t.type||"webview"===t.type}class S extends e.ObjectWrapper.ObjectWrapper{#l;#g;userFlow;speed;timeout;breakpointIndexes;steppingOver=!1;aborted=!1;abortPromise;#p;#h;constructor(e,{speed:t,breakpointIndexes:r=new Set}){super(),this.userFlow=e,this.speed=t,this.timeout=e.timeout||5e3,this.breakpointIndexes=r,this.#l=new Promise((e=>{this.#g=e})),this.abortPromise=new Promise((e=>{this.#p=e}))}#u(){this.#g?.(),this.#l=new Promise((e=>{this.#g=e}))}static async connectPuppeteer(){const e=o.TargetManager.TargetManager.instance().rootTarget();if(!e)throw new Error("Could not find the root target");const t=o.TargetManager.TargetManager.instance().primaryPageTarget();if(!t)throw new Error("Could not find the primary page target");const r=t.model(o.ChildTargetManager.ChildTargetManager);if(!r)throw new Error("Could not get childTargetManager");const s=t.model(o.ResourceTreeModel.ResourceTreeModel);if(!s)throw new Error("Could not get resource tree model");if(!s.mainFrame)throw new Error("Could not find main frame");const n=e.model(o.ChildTargetManager.ChildTargetManager);if(!n)throw new Error("Could not find the child target manager class for the root target");const i=(await n.createParallelConnection((()=>{}))).connection,a=await r.getParentTargetId(),d=await n.getParentTargetId(),{page:l,browser:g,puppeteerConnection:p}=await c.PuppeteerConnection.PuppeteerConnectionHelper.connectPuppeteerToConnectionViaTab({connection:i,rootTargetId:d,isPageTargetCallback:v});if(!l)throw new Error("could not find main page!");return g.on("targetdiscovered",(e=>{"page"===e.type&&e.targetId!==a&&e.openerId===a&&p._createSession(e,!0)})),{page:l,browser:g}}static async disconnectPuppeteer(e){try{const t=await e.pages();for(const e of t){const t=e._client();await t.send("Network.disable"),await t.send("Page.disable"),await t.send("Log.disable"),await t.send("Performance.disable"),await t.send("Runtime.disable"),await t.send("Emulation.clearDeviceMetricsOverride"),await t.send("Emulation.setAutomationOverride",{enabled:!1});for(const t of e.frames()){const e=t.client;await e.send("Network.disable"),await e.send("Page.disable"),await e.send("Log.disable"),await e.send("Performance.disable"),await e.send("Runtime.disable"),await e.send("Emulation.setAutomationOverride",{enabled:!1})}}await e.disconnect()}catch(e){console.error("Error disconnecting Puppeteer",e.message)}}async stop(){await Promise.race([this.#l,this.abortPromise])}abort(){this.aborted=!0,this.#p?.(),this.#h?.abort()}disposeForTesting(){this.#g?.(),this.#p?.()}continue(){this.steppingOver=!1,this.#u()}stepOver(){this.steppingOver=!0,this.#u()}updateBreakpointIndexes(e){this.breakpointIndexes=e}async play(){const{page:t,browser:s}=await S.connectPuppeteer();this.aborted=!1;const n=this;class i extends r.PuppeteerRunnerExtension{#t;constructor(e,t,{timeout:r,speed:s}){super(e,t,{timeout:r}),this.#t=s}async beforeEachStep(e,t){let r=()=>{};const s=new Promise((e=>{r=e}));n.dispatchEventToListeners("Step",{step:e,resolve:r}),await s;const i=t.steps.indexOf(e),a=n.steppingOver||n.breakpointIndexes.has(i),o="setViewport"!==e.type&&"navigate"!==e.type&&!n.aborted;a?(n.dispatchEventToListeners("Stop"),await n.stop(),n.dispatchEventToListeners("Continue")):o&&await Promise.race([new Promise((e=>setTimeout(e,w[this.#t]))),n.abortPromise])}async runStep(r,s){(!e.ParsedURL.schemeIs(t?.url(),"devtools:")||"setViewport"!==r.type&&"navigate"!==r.type)&&(await this.page.bringToFront(),await super.runStep(r,s))}}const a=new i(s,t,{timeout:this.timeout,speed:this.speed});let o;this.#h=await r.createRunner(this.userFlow,a);try{await this.#h.run()}catch(e){o=e,console.error("Replay error",e.message)}finally{await S.disconnectPuppeteer(s)}this.aborted?this.dispatchEventToListeners("Abort"):o?this.dispatchEventToListeners("Error",o):this.dispatchEventToListeners("Done")}}var T=Object.freeze({__proto__:null,defaultTimeout:5e3,RecordingPlayer:S});function b(e){return{type:n.SetViewport,width:e.clientWidth,height:e.clientHeight,deviceScaleFactor:1,isMobile:!1,hasTouch:!1,isLandscape:!1}}function C(e){return{type:n.EmulateNetworkConditions,...e}}function E(e,t){return"selectors"in e&&"selectors"in t?JSON.stringify(e.selectors)===JSON.stringify(t.selectors):!("selectors"in e)&&!("selectors"in t)}const R=r.parse,M=r.parseStep;var k=Object.freeze({__proto__:null,createViewportStep:b,createEmulateNetworkConditionsStep:C,areSelectorsEqual:E,minTimeout:1,maxTimeout:3e4,parse:R,parseStep:M});function _(e){return o.TargetManager.TargetManager.instance().primaryPageTarget()===e||"main"===e.id()?"main":e.inspectedURL()}function A(e,t){const r=[];for(;t;){const e=t.sameTargetParentFrame();if(!e)break;const s=e.childFrames.indexOf(t);r.unshift(s),t=e}return{target:_(e),frame:r}}async function N(e,t,r){const s=t.model(o.RuntimeModel.RuntimeModel).executionContexts(),n=t.model(o.ResourceTreeModel.ResourceTreeModel);for(const i of n.frames()){if(!s.find((e=>e.frameId===i.id)))continue;const{executionContextId:n}=await t.pageAgent().invoke_createIsolatedWorld({frameId:i.id,worldName:e});await t.runtimeAgent().invoke_evaluate({expression:r,includeCommandLineAPI:!0,contextId:n})}}var I=Object.freeze({__proto__:null,getTargetName:_,getTargetFrameContext:A,evaluateInAllFrames:N,findTargetByExecutionContext:function(e,t){for(const r of e){const e=r.model(o.RuntimeModel.RuntimeModel);if(e)for(const s of e.executionContexts())if(s.id===t)return r}},findFrameIdByExecutionContext:function(e,t){for(const r of e){const e=r.model(o.RuntimeModel.RuntimeModel);if(e)for(const r of e.executionContexts())if(r.id===t&&void 0!==r.frameId)return r.frameId}},isFrameTargetInfo:e=>"page"===e.type||"iframe"===e.type});const P=d.StringUtilities.formatAsJSLiteral,x=new Set(["typed","address_bar","auto_bookmark","auto_subframe","generated","auto_toplevel","reload","keyword","keyword_generated"]),O=Object.freeze({addStep:"addStep",stopShortcut:"stopShortcut"});class F extends e.ObjectWrapper.ObjectWrapper{#m;#f;#y;#w;#v;#S=new Map;#T=new Map;#b=new Map;#C=new Map;#E=new Map;#R=new Map;#M=new e.Mutex.Mutex;#k;#_=new Map;#A=!1;#N=[];constructor(e,t){super(),this.#m=e,this.#f=e.pageAgent(),this.#y=e.targetAgent(),this.#w=o.NetworkManager.MultitargetNetworkManager.instance();const r=e.model(o.ResourceTreeModel.ResourceTreeModel);if(!r)throw new Error("ResourceTreeModel is missing for the target: "+e.id());this.#v=r,this.#m=e,this.#k={title:t.title,selectorAttribute:t.selectorAttribute,steps:[]},this.#N=t.selectorTypesToRecord}cloneUserFlow(){return structuredClone(this.#k)}overwriteUserFlow(e){this.#k=structuredClone(e)}async start(){if(this.#A)throw new Error("The session has started");this.#A=!0,this.#w.addEventListener("ConditionsChanged",this.#I,this),await this.#P(),await this.#f.invoke_bringToFront(),await this.#x(this.#m)}async stop(){await this.#O(),this.#M.acquire(),await Promise.all([...this.#S.values()].map(this.#F)),this.#w.removeEventListener("ConditionsChanged",this.#I,this)}async#P(){const e=this.#v.mainFrame;if(!e)throw new Error("Could not find mainFrame.");this.#w.networkConditions()!==o.NetworkManager.NoThrottlingConditions&&this.#I();const{cssLayoutViewport:t}=await this.#m.pageAgent().invoke_getLayoutMetrics();this.#L(b(t));const r=await this.#v.navigationHistory();if(r){const e=r.entries[r.currentIndex];this.#T.set(this.#m.id(),e.id),this.#b.set(this.#m.id(),r.entries.map((e=>e.id))),this.#k.steps.push({type:n.Navigate,url:e.url,assertedEvents:[{type:s.Navigation,url:e.url,title:e.title}]})}else this.#k.steps.push({type:n.Navigate,url:e.url,assertedEvents:[{type:s.Navigation,url:e.url,title:await this.#D(this.#m)}]});this.#O()}async#D(e){const t=await e.runtimeAgent().invoke_evaluate({expression:"document.title"});return t.result?.value||""}#I(){const e=this.#w.networkConditions();this.#L(C(e))}#B;#j=[];#O(){return this.#B&&clearTimeout(this.#B),this.#B=setTimeout((()=>{this.dispatchEventToListeners("recordingupdated",structuredClone(this.#k)),this.#B=void 0;for(const e of this.#j)e();this.#j.length=0}),100),new Promise((e=>{this.#j.push(e)}))}get#U(){return this.#k.steps.slice(-1)[0]}#z=new Set;#L(e){switch(e.type){case"doubleClick":for(let t=this.#k.steps.length-1;t>0;t--){const r=this.#k.steps[t];if("click"===r.type){e.selectors=r.selectors,this.#k.steps.splice(t,1);break}}break;case"change":{const t=this.#U;if(!t)break;switch(t.type){case"change":if(!E(e,t))break;return this.#k.steps[this.#k.steps.length-1]=e,void this.#O();case"keyDown":return this.#z.add(t.key),this.#k.steps.pop(),void this.#L(e)}break}case"keyDown":if(this.#z.has(e.key))return;break;case"keyUp":if(this.#z.has(e.key))return void this.#z.delete(e.key)}this.#k.steps.push(e),this.#O()}#W(e,t){const r=this.#k.steps[this.#k.steps.length-1];if(r&&!r.assertedEvents?.find((e=>e.type===s.Navigation))){const n=e.target||"main",i=(e.frame||[]).join(","),a=r.target||"main",o=(("frame"in r?r.frame:[])||[]).join(",");n===a&&i===o&&(r.assertedEvents=[{type:s.Navigation}],this.#_.set(t.id(),r),this.#O())}}#K(e,t){const r=this.#_.get(e.id());if(!r)return;const n=r;if(!n.assertedEvents)return;const i=n.assertedEvents.find((e=>e.type===s.Navigation));i&&!i.url&&(i.url=t.url,i.title=t.title,this.#O())}#H(e){const t=Number(e.data.payload);for(let e=0;e<t-1;e++)this.#k.steps.pop();this.dispatchEventToListeners("recordingstopped",structuredClone(this.#k))}#$(e,t){switch(t.data.name){case O.stopShortcut:return void this.#H(t);case O.addStep:return void this.#V(e,t);default:return}}#V(e,t){const r=t.data.executionContextId;let s;const n=e.model(o.RuntimeModel.RuntimeModel);if(n)for(const e of n.executionContexts())if(e.id===r){s=e.frameId;break}if(!s)throw new Error("No execution context found for the binding call + "+JSON.stringify(t.data));const i=JSON.parse(t.data.payload),a=e.model(o.ResourceTreeModel.ResourceTreeModel).frameForId(s);if(!a)throw new Error("Could not find frame.");const c=A(e,a);if("beforeUnload"!==i.type)switch(i.type){case"change":this.#L({type:"change",value:i.value,selectors:i.selectors,frame:c.frame.length?c.frame:void 0,target:c.target});break;case"doubleClick":this.#L({type:"doubleClick",target:c.target,selectors:i.selectors,offsetY:i.offsetY,offsetX:i.offsetX,frame:c.frame.length?c.frame:void 0,deviceType:i.deviceType,button:i.button});break;case"click":this.#L({type:"click",target:c.target,selectors:i.selectors,offsetY:i.offsetY,offsetX:i.offsetX,frame:c.frame.length?c.frame:void 0,duration:i.duration,deviceType:i.deviceType,button:i.button});break;case"keyUp":this.#L({type:"keyUp",key:i.key,frame:c.frame.length?c.frame:void 0,target:c.target});break;case"keyDown":this.#L({type:"keyDown",frame:c.frame.length?c.frame:void 0,target:c.target,key:i.key});break;default:throw new Error("Unhandled client event")}else this.#W(c,e)}#G(){return(e=>{const t=[];for(const r of e)for(const e of r){const r={meta:!1,ctrl:!1,shift:!1,alt:!1,keyCode:-1},{keyCode:s,modifiers:n}=a.KeyboardShortcut.KeyboardShortcut.keyCodeAndModifiersFromKey(e);r.keyCode=s;const i=a.KeyboardShortcut.Modifiers;r.ctrl=Boolean(n&i.Ctrl),r.meta=Boolean(n&i.Meta),r.shift=Boolean(n&i.Shift),r.shift=Boolean(n&i.Alt),-1!==r.keyCode&&t.push(r)}return t})(a.ShortcutRegistry.ShortcutRegistry.instance().shortcutsForAction("chrome-recorder.start-recording").map((e=>e.descriptors.map((e=>e.key)))))}static get#J(){try{return e.Settings.Settings.instance().settingForTest("untrusted-recorder-events"),!0}catch{}return!1}#x=async e=>{if(e.type()!==o.Target.Type.Frame)return;this.#S.set(e.id(),e);const t=e.model(o.AccessibilityModel.AccessibilityModel);d.assertNotNullOrUndefined(t),await t.resumeModel(),await this.#q(e),await this.#X(e);const r=e.model(o.ChildTargetManager.ChildTargetManager);d.assertNotNullOrUndefined(r),this.#R.set(e,[r.addEventListener("TargetCreated",this.#Y.bind(this,e)),r.addEventListener("TargetDestroyed",this.#Q.bind(this,e)),r.addEventListener("TargetInfoChanged",this.#Z.bind(this,e))]),await Promise.all(r.childTargets().map(this.#x))};#F=async t=>{const r=this.#R.get(t);r&&e.EventTarget.removeEventListeners(r),await this.#ee(t),await this.#te(t)};async#q(e){const t=e.model(o.RuntimeModel.RuntimeModel);d.assertNotNullOrUndefined(t),this.#E.set(e,[t.addEventListener(o.RuntimeModel.Events.BindingCalled,this.#$.bind(this,e))]),await Promise.all(Object.values(O).map((e=>t.addBinding({name:e,executionContextName:l.DEVTOOLS_RECORDER_WORLD_NAME}))))}async#te(t){await Promise.all(Object.values(O).map((e=>t.runtimeAgent().invoke_removeBinding({name:e}))));const r=this.#E.get(t);r&&e.EventTarget.removeEventListeners(r)}async#X(e){const t=`\n ${await l.InjectedScript.get()};DevToolsRecorder.startRecording({getAccessibleName, getAccessibleRole}, {\n debug: ${l.isDebugBuild},\n allowUntrustedEvents: ${F.#J},\n selectorTypesToRecord: ${JSON.stringify(this.#N)},\n selectorAttribute: ${this.#k.selectorAttribute?P(this.#k.selectorAttribute):void 0},\n stopShortcuts: ${JSON.stringify(this.#G())},\n });\n `,[{identifier:r}]=await Promise.all([e.pageAgent().invoke_addScriptToEvaluateOnNewDocument({source:t,worldName:l.DEVTOOLS_RECORDER_WORLD_NAME,includeCommandLineAPI:!0}),N(l.DEVTOOLS_RECORDER_WORLD_NAME,e,t)]);this.#C.set(e.id(),r)}async#ee(e){const t=this.#C.get(e.id());t&&(await e.pageAgent().invoke_removeScriptToEvaluateOnNewDocument({identifier:t}),await(async(e,t,r)=>{await Promise.all(t.map((t=>N(e,t,r))))})(l.DEVTOOLS_RECORDER_WORLD_NAME,[...this.#S.values()],"DevToolsRecorder.stopRecording()"))}#Y(e,t){this.#re({type:"targetCreated",event:t,target:e})}#Q(e,t){const r=this.#S.get(t.data);r&&this.#re({type:"targetClosed",event:t,target:r})}#Z(e,t){const r=this.#S.get(t.data.targetId)||e;this.#re({type:"targetInfoChanged",event:t,target:r})}#re(e){return this.#M.run((async()=>{try{switch(l.isDebugBuild&&console.time(`Processing ${JSON.stringify(e)}`),e.type){case"targetClosed":await this.#se(e);break;case"targetCreated":await this.#ne(e);break;case"targetInfoChanged":await this.#ie(e)}l.isDebugBuild&&console.timeEnd(`Processing ${JSON.stringify(e)}`)}catch(e){console.error("Error happened while processing recording events: ",e.message,e.stack)}}))}async#ne(e){if("page"!==e.event.data.type&&"iframe"!==e.event.data.type)return;await this.#y.invoke_attachToTarget({targetId:e.event.data.targetId,flatten:!0});const t=o.TargetManager.TargetManager.instance().targets().find((t=>t.id()===e.event.data.targetId));if(!t)throw new Error("Could not find target.");await this.#x(t),window.dispatchEvent(new Event("recorderAttachedToTarget"))}async#se(e){const t=this.#_.get(e.target.id());t&&(delete t.assertedEvents,this.#_.delete(e.target.id()))}async#ae(e,t){const r=await e.navigationHistory();if(!r)return!1;const i=r.entries[r.currentIndex];if(this.#T.get(t.id())===i.id)return!0;this.#T.set(t.id(),i.id);const a=this.#b.get(t.id())||[];if(this.#b.set(t.id(),r.entries.map((e=>e.id))),x.has(i.transitionType)||a.includes(i.id)){const e=this.#_.get(t.id());e&&(delete e.assertedEvents,this.#_.delete(t.id())),this.#L({type:n.Navigate,url:i.url,assertedEvents:[{type:s.Navigation,url:i.url,title:i.title}]})}else this.#K(t,{type:s.Navigation,url:i.url,title:i.title});return!0}async#ie(e){if("page"!==e.event.data.type&&"iframe"!==e.event.data.type)return;const t=e.target,r=t.model(o.ResourceTreeModel.ResourceTreeModel);if(!r)throw new Error("ResourceTreeModel is missing in handleNavigation");if("iframe"===e.event.data.type)this.#K(t,{type:s.Navigation,url:e.event.data.url,title:await this.#D(t)});else if("page"===e.event.data.type){if(await this.#ae(r,t))return;await this.#oe(r,500),this.#K(t,{type:s.Navigation,url:e.event.data.url,title:await this.#D(t)})}}async#oe(e,t){let r=()=>Promise.resolve();const s=new Promise((e=>{r=e})),n=()=>{e.removeEventListener(o.ResourceTreeModel.Events.DOMContentLoaded,n),r()};e.addEventListener(o.ResourceTreeModel.Events.DOMContentLoaded,n),await Promise.any([s,new Promise((r=>setTimeout((()=>{e.removeEventListener(o.ResourceTreeModel.Events.DOMContentLoaded,n),r()}),t)))])}}var L=Object.freeze({__proto__:null,RecordingSession:F}),D=Object.freeze({__proto__:null});let B=null;class j{next(){return crypto.randomUUID()}}class U{#ce;#M=new e.Mutex.Mutex;#de=new j;constructor(){this.#ce=e.Settings.Settings.instance().createSetting("recorder-recordings-ng",[])}clearForTest(){this.#ce.set([]),this.#de=new j}setIdGeneratorForTest(e){this.#de=e}async saveRecording(e){const t=await this.#M.acquire();try{const t=await this.#ce.forceGet(),r={storageName:this.#de.next(),flow:e};return t.push(r),this.#ce.set(t),r}finally{t()}}async updateRecording(e,t){const r=await this.#M.acquire();try{const r=await this.#ce.forceGet(),s=r.find((t=>t.storageName===e));if(!s)throw new Error("No recording is found during updateRecording");return s.flow=t,this.#ce.set(r),s}finally{r()}}async deleteRecording(e){const t=await this.#M.acquire();try{const t=await this.#ce.forceGet();this.#ce.set(t.filter((t=>t.storageName!==e)))}finally{t()}}getRecording(e){return this.#ce.get().find((t=>t.storageName===e))}getRecordings(){return this.#ce.get()}static instance(){return B||(B=new U),B}}var z=Object.freeze({__proto__:null,RecordingStorage:U});let W=null;const K=52428800;class H{#le;#ge;#pe;constructor(t=52428800){this.#le=e.Settings.Settings.instance().createSetting("recorder-screenshots",[]),this.#ge=this.#he(),this.#pe=t}clear(){this.#le.set([]),this.#ge=new Map}getScreenshotForSection(e,t){const r=this.#ge.get(this.#ue(e,t));return r?(this.#me(r),r.data):null}storeScreenshotForSection(e,t,r){const s={recordingName:e,index:t,data:r};this.#ge.set(this.#ue(e,t),s),this.#me(s)}deleteScreenshotsForRecording(e){for(const[t,r]of this.#ge)r.recordingName===e&&this.#ge.delete(t);this.#me()}#ue(e,t){return`${e}:${t}`}#he(){const e=new Map,t=this.#le.get();for(const r of t)e.set(this.#ue(r.recordingName,r.index),r);return e}#me(e){if(e){const t=this.#ue(e.recordingName,e.index);this.#ge.delete(t),this.#ge.set(t,e)}const t=[];let r=0;for(const[e,s]of Array.from(this.#ge.entries()).reverse())r<this.#pe?(r+=s.data.length,t.push(s)):this.#ge.delete(e);this.#le.set(t.reverse())}static instance(e={forceNew:null,maxStorageSize:K}){const{forceNew:t,maxStorageSize:r}=e;return W&&!t||(W=new H(r)),W}}var $=Object.freeze({__proto__:null,ScreenshotStorage:H});const V=160,G=240;async function J(e){const t=new Image,r=new Promise((e=>{t.onload=e}));t.src=e,await r;const s=document.createElement("canvas"),n=s.getContext("2d");if(!n)throw new Error("Could not create context.");const i=t.width/t.height;s.width=V,s.height=Math.min(G,V/i);const a=await createImageBitmap(t,{resizeWidth:V,resizeQuality:"high"});return n.drawImage(a,0,0),s.toDataURL("image/png")}var q=Object.freeze({__proto__:null,resizeScreenshot:J,takeScreenshot:async function(){const e=await async function(){const e=o.TargetManager.TargetManager.instance().primaryPageTarget();if(!e)throw new Error("Could not find main target");const{data:t}=await e.pageAgent().invoke_captureScreenshot({});return t?"data:image/png;base64,"+t:"data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"}();return await J(e)}});function X(e){const t=e.assertedEvents?.find((e=>"navigation"===e.type));return"navigate"===e.type?{title:t?.title||"",url:e.url,steps:[],causingStep:e}:t?{title:t.title||"",url:t.url||"",steps:[]}:null}var Y=Object.freeze({__proto__:null,buildSections:function(e){let t=null;const r=[];for(const s of e){if(t)t.steps.push(s);else{if("navigate"===s.type){t=X(s);continue}t={title:"Current page",url:"",steps:[s]}}const e=X(s);e&&(t&&r.push(t),t=e)}return!t||r.length&&!t.steps.length||r.push(t),r}});var Q=Object.freeze({__proto__:null,getTooltipForActions:function(e,t){let r=e;const s=a.ShortcutRegistry.ShortcutRegistry.instance().shortcutsForAction(t);for(const e of s)r+=` - ${e.title()}`;return r}});export{g as ConverterIds,f as RecorderSettings,y as RecorderShortcutHelper,T as RecordingPlayer,L as RecordingSession,D as RecordingSettings,z as RecordingStorage,I as SDKUtils,p as Schema,k as SchemaUtils,$ as ScreenshotStorage,q as ScreenshotUtils,Y as Section,Q as Tooltip};