@appsurify-testmap/rrweb-playwright-plugin 2.1.1-alpha.7 → 2.1.2-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +105 -27
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +105 -27
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
package/dist/index.cjs
CHANGED
|
@@ -871,10 +871,13 @@ function inspectInlineEventHandlers$1() {
|
|
|
871
871
|
});
|
|
872
872
|
});
|
|
873
873
|
}
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
874
|
+
try {
|
|
875
|
+
if (document.readyState === "complete" || document.readyState === "interactive") {
|
|
876
|
+
inspectInlineEventHandlers$1();
|
|
877
|
+
} else {
|
|
878
|
+
document.addEventListener("DOMContentLoaded", inspectInlineEventHandlers$1);
|
|
879
|
+
}
|
|
880
|
+
} catch (error) {
|
|
878
881
|
}
|
|
879
882
|
let _id = 1;
|
|
880
883
|
const tagNameRegex = new RegExp("[^a-z0-9-_:]");
|
|
@@ -5581,10 +5584,13 @@ function inspectInlineEventHandlers() {
|
|
|
5581
5584
|
});
|
|
5582
5585
|
});
|
|
5583
5586
|
}
|
|
5584
|
-
|
|
5585
|
-
|
|
5586
|
-
|
|
5587
|
-
|
|
5587
|
+
try {
|
|
5588
|
+
if (document.readyState === "complete" || document.readyState === "interactive") {
|
|
5589
|
+
inspectInlineEventHandlers();
|
|
5590
|
+
} else {
|
|
5591
|
+
document.addEventListener("DOMContentLoaded", inspectInlineEventHandlers);
|
|
5592
|
+
}
|
|
5593
|
+
} catch (error) {
|
|
5588
5594
|
}
|
|
5589
5595
|
function getDefaultExportFromCjs(x2) {
|
|
5590
5596
|
return x2 && x2.__esModule && Object.prototype.hasOwnProperty.call(x2, "default") ? x2["default"] : x2;
|
|
@@ -10859,6 +10865,8 @@ function initViewportResizeObserver({ viewportResizeCb }, { win }) {
|
|
|
10859
10865
|
}
|
|
10860
10866
|
const INPUT_TAGS = ["INPUT", "TEXTAREA", "SELECT"];
|
|
10861
10867
|
const lastInputValueMap = /* @__PURE__ */ new WeakMap();
|
|
10868
|
+
const FINALIZING_KEYS = ["Enter", "Tab", "Escape", "ArrowDown", "ArrowUp", "Delete"];
|
|
10869
|
+
const lastKeyInputValueMap = /* @__PURE__ */ new WeakMap();
|
|
10862
10870
|
function initInputObserver({
|
|
10863
10871
|
inputCb,
|
|
10864
10872
|
doc,
|
|
@@ -10931,6 +10939,22 @@ function initInputObserver({
|
|
|
10931
10939
|
const isPhantomCheckbox = el.type === "checkbox" && !v2.userTriggered && !v2.isChecked && !lastInputValue;
|
|
10932
10940
|
const isPhantomRadio = el.type === "radio" && !v2.userTriggered && !v2.isChecked && !lastInputValue;
|
|
10933
10941
|
if (isLikelyPhantom || isRenderDrivenTextInput || isValueFromDefault || isPhantomCheckbox || isPhantomRadio) {
|
|
10942
|
+
console.debug(
|
|
10943
|
+
\`[\${nowTimestamp()}] [rrweb:record/observer] \\u26D4 phantom input ignored\`,
|
|
10944
|
+
{
|
|
10945
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-call
|
|
10946
|
+
node: index.describeNode(el),
|
|
10947
|
+
tag: el.tagName,
|
|
10948
|
+
nodeType: el.nodeType,
|
|
10949
|
+
attribute: el.attributes,
|
|
10950
|
+
value: el.value,
|
|
10951
|
+
isLikelyPhantom,
|
|
10952
|
+
isRenderDrivenTextInput,
|
|
10953
|
+
isValueFromDefault,
|
|
10954
|
+
isPhantomCheckbox,
|
|
10955
|
+
isPhantomRadio
|
|
10956
|
+
}
|
|
10957
|
+
);
|
|
10934
10958
|
return;
|
|
10935
10959
|
}
|
|
10936
10960
|
if (!lastInputValue || lastInputValue.text !== v2.text || lastInputValue.isChecked !== v2.isChecked) {
|
|
@@ -10945,6 +10969,62 @@ function initInputObserver({
|
|
|
10945
10969
|
const handlers = events.map(
|
|
10946
10970
|
(eventName) => on(eventName, callbackWrapper(eventHandler), doc)
|
|
10947
10971
|
);
|
|
10972
|
+
const keyboardHandler = (event) => {
|
|
10973
|
+
const target = getEventTarget(event);
|
|
10974
|
+
if (!target || !target.tagName)
|
|
10975
|
+
return;
|
|
10976
|
+
if (sampling.input === "all") {
|
|
10977
|
+
eventHandler(event);
|
|
10978
|
+
return;
|
|
10979
|
+
}
|
|
10980
|
+
const tag = target.tagName;
|
|
10981
|
+
const key = event.key;
|
|
10982
|
+
const isFinalizingKey = FINALIZING_KEYS.includes(key);
|
|
10983
|
+
const isTextarea = tag === "TEXTAREA";
|
|
10984
|
+
const isFocused = doc.activeElement === target;
|
|
10985
|
+
const valueNow = target.value;
|
|
10986
|
+
const valueBefore = lastKeyInputValueMap.get(target);
|
|
10987
|
+
lastKeyInputValueMap.set(target, valueNow);
|
|
10988
|
+
if (!isFocused) {
|
|
10989
|
+
eventHandler(event);
|
|
10990
|
+
return;
|
|
10991
|
+
}
|
|
10992
|
+
if (isFinalizingKey) {
|
|
10993
|
+
if (!isTextarea) {
|
|
10994
|
+
eventHandler(event);
|
|
10995
|
+
return;
|
|
10996
|
+
}
|
|
10997
|
+
let lastValue = valueBefore != null ? valueBefore : "";
|
|
10998
|
+
let unchangedCount = 0;
|
|
10999
|
+
const REQUIRED_STABLE_FRAMES = 2;
|
|
11000
|
+
const checkFinal = () => {
|
|
11001
|
+
const currentValue = target.value;
|
|
11002
|
+
const stillFocused = doc.activeElement === target;
|
|
11003
|
+
const changed = currentValue !== lastValue;
|
|
11004
|
+
if (!stillFocused) {
|
|
11005
|
+
eventHandler(event);
|
|
11006
|
+
return;
|
|
11007
|
+
}
|
|
11008
|
+
if (!changed) {
|
|
11009
|
+
unchangedCount++;
|
|
11010
|
+
if (unchangedCount >= REQUIRED_STABLE_FRAMES) {
|
|
11011
|
+
eventHandler(event);
|
|
11012
|
+
return;
|
|
11013
|
+
}
|
|
11014
|
+
} else {
|
|
11015
|
+
unchangedCount = 0;
|
|
11016
|
+
lastValue = currentValue;
|
|
11017
|
+
}
|
|
11018
|
+
requestAnimationFrame(checkFinal);
|
|
11019
|
+
};
|
|
11020
|
+
requestAnimationFrame(checkFinal);
|
|
11021
|
+
return;
|
|
11022
|
+
}
|
|
11023
|
+
};
|
|
11024
|
+
handlers.push(
|
|
11025
|
+
on("keydown", callbackWrapper(keyboardHandler), doc)
|
|
11026
|
+
// on('keypress', callbackWrapper(keyboardHandler), doc),
|
|
11027
|
+
);
|
|
10948
11028
|
const currentWindow = doc.defaultView;
|
|
10949
11029
|
if (!currentWindow) {
|
|
10950
11030
|
return () => {
|
|
@@ -12932,13 +13012,14 @@ class VisibilityManager {
|
|
|
12932
13012
|
cancelAnimationFrame(this.rafId);
|
|
12933
13013
|
}
|
|
12934
13014
|
}
|
|
13015
|
+
const version$1 = "2.1.2-alpha.2";
|
|
12935
13016
|
let wrappedEmit;
|
|
12936
13017
|
let takeFullSnapshot$1;
|
|
12937
13018
|
let canvasManager;
|
|
12938
13019
|
let visibilityManager;
|
|
12939
13020
|
let recording = false;
|
|
12940
13021
|
const customEventQueue = [];
|
|
12941
|
-
let flushCustomEventQueue;
|
|
13022
|
+
let flushCustomEventQueue$1;
|
|
12942
13023
|
function waitForDOMStabilization(win) {
|
|
12943
13024
|
const maxWaitMs = 5e3;
|
|
12944
13025
|
return new Promise((resolve2) => {
|
|
@@ -13303,7 +13384,7 @@ function record(options = {}) {
|
|
|
13303
13384
|
mirror.getId(document)
|
|
13304
13385
|
);
|
|
13305
13386
|
};
|
|
13306
|
-
flushCustomEventQueue = () => {
|
|
13387
|
+
flushCustomEventQueue$1 = () => {
|
|
13307
13388
|
for (const e2 of customEventQueue) {
|
|
13308
13389
|
wrappedEmit(e2);
|
|
13309
13390
|
}
|
|
@@ -13437,37 +13518,34 @@ function record(options = {}) {
|
|
|
13437
13518
|
});
|
|
13438
13519
|
const init = () => {
|
|
13439
13520
|
if (flushCustomEvent === "before") {
|
|
13440
|
-
flushCustomEventQueue();
|
|
13521
|
+
flushCustomEventQueue$1();
|
|
13441
13522
|
}
|
|
13442
13523
|
takeFullSnapshot$1();
|
|
13443
13524
|
handlers.push(observe(document));
|
|
13444
13525
|
recording = true;
|
|
13445
13526
|
if (flushCustomEvent === "after") {
|
|
13446
|
-
flushCustomEventQueue();
|
|
13527
|
+
flushCustomEventQueue$1();
|
|
13447
13528
|
}
|
|
13448
13529
|
};
|
|
13449
13530
|
const runInit = async () => {
|
|
13450
13531
|
if (flushCustomEvent === "before") {
|
|
13451
|
-
flushCustomEventQueue();
|
|
13532
|
+
flushCustomEventQueue$1();
|
|
13452
13533
|
}
|
|
13453
13534
|
if (recordAfter === "DOMContentStabilized") {
|
|
13454
|
-
console.
|
|
13535
|
+
console.debug(\`[\${nowTimestamp()}] [rrweb:record] \\u{1F7E2} Waiting for DOM stabilization...\`);
|
|
13455
13536
|
await waitForDOMStabilization(window);
|
|
13456
|
-
console.
|
|
13537
|
+
console.debug(\`[\${nowTimestamp()}] [rrweb:record] \\u2705 DOM stabilized, starting recording\`);
|
|
13457
13538
|
}
|
|
13539
|
+
console.debug(\`[\${nowTimestamp()}] [rrweb:record] \\u2705 Init dom and takeFullSnapshot \`);
|
|
13458
13540
|
takeFullSnapshot$1();
|
|
13459
13541
|
handlers.push(observe(document));
|
|
13460
13542
|
recording = true;
|
|
13461
13543
|
if (flushCustomEvent === "after") {
|
|
13462
|
-
flushCustomEventQueue();
|
|
13544
|
+
flushCustomEventQueue$1();
|
|
13463
13545
|
}
|
|
13464
13546
|
};
|
|
13465
13547
|
if (document.readyState === "interactive" || document.readyState === "complete") {
|
|
13466
|
-
|
|
13467
|
-
void runInit();
|
|
13468
|
-
} else {
|
|
13469
|
-
init();
|
|
13470
|
-
}
|
|
13548
|
+
init();
|
|
13471
13549
|
} else {
|
|
13472
13550
|
handlers.push(
|
|
13473
13551
|
on("DOMContentLoaded", () => {
|
|
@@ -13475,9 +13553,8 @@ function record(options = {}) {
|
|
|
13475
13553
|
type: EventType.DomContentLoaded,
|
|
13476
13554
|
data: {}
|
|
13477
13555
|
});
|
|
13478
|
-
if (recordAfter === "DOMContentLoaded"
|
|
13479
|
-
|
|
13480
|
-
}
|
|
13556
|
+
if (recordAfter === "DOMContentLoaded")
|
|
13557
|
+
init();
|
|
13481
13558
|
})
|
|
13482
13559
|
);
|
|
13483
13560
|
handlers.push(
|
|
@@ -13489,14 +13566,14 @@ function record(options = {}) {
|
|
|
13489
13566
|
data: {}
|
|
13490
13567
|
});
|
|
13491
13568
|
if (recordAfter === "load")
|
|
13492
|
-
|
|
13569
|
+
init();
|
|
13493
13570
|
},
|
|
13494
13571
|
window
|
|
13495
13572
|
)
|
|
13496
13573
|
);
|
|
13497
13574
|
}
|
|
13498
13575
|
return () => {
|
|
13499
|
-
flushCustomEventQueue();
|
|
13576
|
+
flushCustomEventQueue$1();
|
|
13500
13577
|
handlers.forEach((h) => h());
|
|
13501
13578
|
processedNodeManager.destroy();
|
|
13502
13579
|
recording = false;
|
|
@@ -13506,10 +13583,11 @@ function record(options = {}) {
|
|
|
13506
13583
|
console.warn(error);
|
|
13507
13584
|
}
|
|
13508
13585
|
}
|
|
13586
|
+
record.getVersion = () => version$1;
|
|
13509
13587
|
record.isRecording = () => recording;
|
|
13510
13588
|
record.flushCustomEventQueue = () => {
|
|
13511
13589
|
console.warn(\`[rrweb] CustomEvent flushing: \${customEventQueue.length} events\`);
|
|
13512
|
-
flushCustomEventQueue();
|
|
13590
|
+
flushCustomEventQueue$1();
|
|
13513
13591
|
};
|
|
13514
13592
|
record.addCustomEvent = (tag, payload) => {
|
|
13515
13593
|
const customEvent = {
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/recorder/RRWebRecorder.ts","../src/recorder/index.ts"],"sourcesContent":["import { test as base, expect } from '@playwright/test';\nimport type { Browser, BrowserContext, Page, Frame, ConsoleMessage } from '@playwright/test';\nimport { parseSerializedValue } from './serializers';\nimport RRWebRecorder from './recorder';\n\nclass PlaywrightRRWebAdapter {\n private recorder: RRWebRecorder;\n private page: Page;\n private buffer: any[] = [];\n\n constructor(recorder: RRWebRecorder, page: Page) {\n this.recorder = recorder;\n this.page = page;\n }\n\n public async setup() {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n const srcCode = this.recorder.getScriptCode();\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument,@typescript-eslint/no-unsafe-assignment\n await this.page.addInitScript({content: srcCode});\n }\n\n}\n\nconst test = base.extend<{\n browser: Browser;\n context: BrowserContext;\n page: Page;\n}>({\n browser: async ({ browser }: { browser: Browser }, use) => {\n\n // const originalOnMessage = browser._connection.onmessage.bind(browser._connection);\n //\n // browser._connection.onmessage = (message: any) => {\n // originalOnMessage(message);\n // };\n\n await use(browser);\n },\n\n context: async ({ browser }: { browser: Browser }, use) => {\n const context = await browser.newContext();\n\n // const originalOnMessage = context._connection.onmessage.bind(context._connection);\n //\n // context._connection.onmessage = (message: any) => {\n // originalOnMessage(message);\n // };\n\n await use(context);\n await context.close();\n },\n\n page: async ({ page }: { page: Page }, use) => {\n // eslint-disable-next-line @typescript-eslint/no-empty-function,@typescript-eslint/ban-ts-comment\n // @ts-ignore\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n page.on('console', async (consoleMessage: ConsoleMessage) => {});\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n page.on('load', async (page: Page) => {});\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n page.on('domcontentloaded', async (page: Page) => {});\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n page.on('framenavigated', async (frame: Frame) => {});\n // const originalOnMessage = page._connection.onmessage.bind(page._connection);\n // page._connection.onmessage = (message: any) => {\n // // const curGuid = message.guid;\n // // const curObject = page._objects?.get?.(curGuid);\n // // const curInit = curObject?._initializer;\n // // if (curInit?.name === '_captureEvent') {\n // // const curInitArgs = curInit.args;\n // // const event = parseSerializedValue(curInitArgs[0], undefined);\n // // console.log(`[onmessage][captureEvent]`, event.timestamp, event.type);\n // // }\n // console.log(`[onmessage]`, message.method);\n // originalOnMessage(message);\n // };\n const recorder = new RRWebRecorder();\n const adapter = new PlaywrightRRWebAdapter(recorder, page);\n\n\n await use(page);\n },\n});\n\n// eslint-disable-next-line no-empty-pattern,@typescript-eslint/require-await\ntest.beforeEach(async ({}, testInfo) => {\n console.log(`[🟢 TEST START] ${testInfo.title}`);\n});\n\n// eslint-disable-next-line no-empty-pattern,@typescript-eslint/require-await\ntest.afterEach(async ({}, testInfo) => {\n console.log(`[🔴 TEST END] ${testInfo.title}`);\n});\n\nexport { test, expect };\n\n","import type { record } from '@appsurify-testmap/rrweb';\nimport type { Mirror } from '@appsurify-testmap/rrweb-snapshot';\nimport { getRecordSequentialIdPlugin } from '@appsurify-testmap/rrweb-plugin-sequential-id-record';\n\n// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n// @ts-ignore\nimport rrSrc from './releases/rrweb-record.umd.cjs.src';\n\nimport type { RecorderContext, Recorder, RecorderEvent } from './types';\n\ninterface WindowWithRRWeb extends Window {\n rrweb?: {\n record: typeof record | null;\n };\n}\n\nexport class RRWebRecorder implements Recorder {\n private recordFn: typeof record | null = null;\n private stopFn: (() => void) | undefined | null = null;\n private targetWindow: Window | null = null;\n private context: RecorderContext;\n private eventCounter = 0;\n private events: RecorderEvent[] = [];\n\n private pendingEvents: {\n tag: string;\n payload: Record<string, unknown>;\n }[] = [];\n\n constructor() {\n this.context = {\n pushEvent: (event) => this.events.push(event),\n };\n }\n\n private handleEmit(event: RecorderEvent) {\n if (event.type === 0 || event.type === 1) {\n return;\n }\n const rrEvent: RecorderEvent = {\n ...event,\n };\n this.context.pushEvent(rrEvent);\n }\n\n public inject(win: Window) {\n const w = win as WindowWithRRWeb;\n\n this.targetWindow = win;\n\n if (w.rrweb) {\n this.recordFn = w.rrweb.record ?? null;\n return;\n }\n\n const script = win.document.createElement('script');\n script.type = 'text/javascript';\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n script.innerHTML = rrSrc;\n win.document.head.appendChild(script);\n\n const recheck = (win as WindowWithRRWeb).rrweb;\n if (!recheck || !recheck.record) {\n console.error(`🟡 [rrweb] Failed to load rrweb.record`);\n return;\n }\n\n this.recordFn = recheck.record;\n }\n\n public start() {\n if (!this.targetWindow || !this.recordFn) {\n console.warn(`🟡 [rrweb] Not ready to start`);\n return;\n }\n\n if (this.stopFn) {\n console.warn(`🟡 [rrweb] Already recording`);\n return;\n }\n\n this.stopFn = this.recordFn({\n emit: (event: RecorderEvent) => this.handleEmit(event),\n checkoutEveryNvm: 10,\n plugins: [\n getRecordSequentialIdPlugin({\n key: 'id',\n getId: () => ++this.eventCounter,\n }),\n ],\n // includeAttribute: /data-(cy|test(id)?|cypress|highlight-el|cypress-el)/i,\n maskInputOptions: { password: true },\n slimDOMOptions: 'all',\n inlineStylesheet: true,\n sampling: {\n mousemove: false,\n mouseInteraction: {\n MouseUp: false,\n MouseDown: false,\n Click: true,\n ContextMenu: true,\n DblClick: true,\n Focus: true,\n Blur: true,\n TouchStart: false,\n TouchEnd: false,\n },\n scroll: 100,\n media: 100,\n input: 'last',\n canvas: 'all',\n visibility: {\n mode: 'debounce',\n debounce: 50,\n threshold: 0.5,\n sensitivity: 0.05,\n rafThrottle: 50\n }\n },\n recordDOM: true,\n recordCanvas: true,\n collectFonts: true,\n inlineImages: true,\n flushCustomEvent: 'after',\n // recordAfter: 'DOMContentStabilized',\n recordAfter: 'DOMContentLoaded',\n });\n\n this.flush();\n }\n\n public stop() {\n this.flush();\n this.stopFn?.();\n this.stopFn = null;\n }\n\n public reset() {\n this.eventCounter = 0;\n this.events = [];\n this.stop();\n this.context = {\n pushEvent: (event) => this.events.push(event),\n };\n }\n\n public flush() {\n if (!this.recordFn) return;\n\n const stillPending: typeof this.pendingEvents = [];\n\n for (const evt of this.pendingEvents) {\n try {\n this.recordFn.addCustomEvent(evt.tag, evt.payload);\n } catch (err) {\n console.warn(`[rrweb] flush failed for custom event: ${evt.tag}`);\n stillPending.push(evt);\n }\n }\n\n this.pendingEvents = stillPending;\n }\n\n public addCustomEvent(tag: string, payload: Record<string, unknown>) {\n const event = { tag, payload };\n\n if (!this.recordFn || !this.stopFn) {\n console.warn(`[rrweb] queued custom event (recorder not ready): ${tag}`);\n this.pendingEvents.push(event);\n return;\n }\n\n try {\n this.recordFn.addCustomEvent(tag, payload);\n } catch (error) {\n console.warn(`[rrweb] error adding custom event: ${tag}`, error);\n this.pendingEvents.push(event);\n }\n }\n\n public isRecordingReady(): boolean {\n return !!this.recordFn && !!this.stopFn;\n }\n\n public getEvents(): readonly RecorderEvent[] {\n return this.events;\n }\n\n public getMirror(): Mirror | undefined {\n return (this.recordFn as unknown as { mirror?: Mirror })?.mirror;\n }\n\n public bind(ctx: RecorderContext) {\n this.context = ctx;\n }\n\n public setEventCounter(value: number) {\n this.eventCounter = value;\n }\n\n public getScriptCode() {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return\n return rrSrc;\n }\n}\n","import { RRWebRecorder } from './RRWebRecorder';\n\n\nexport default RRWebRecorder;\n"],"mappings":"yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,8BAAAE,IAAA,eAAAC,EAAAH,GAAA,IAAAI,EAAqC,4BCErC,IAAAC,EAA4C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAcrC,IAAMC,EAAN,KAAwC,CACrC,SAAiC,KACjC,OAA0C,KAC1C,aAA8B,KAC9B,QACA,aAAe,EACf,OAA0B,CAAC,EAE3B,cAGF,CAAC,EAEP,aAAc,CACZ,KAAK,QAAU,CACb,UAAYC,GAAU,KAAK,OAAO,KAAKA,CAAK,CAC9C,CACF,CAEQ,WAAWA,EAAsB,CACvC,GAAIA,EAAM,OAAS,GAAKA,EAAM,OAAS,EACrC,OAEF,IAAMC,EAAyB,CAC7B,GAAGD,CACL,EACA,KAAK,QAAQ,UAAUC,CAAO,CAChC,CAEO,OAAOC,EAAa,CACzB,IAAMC,EAAID,EAIV,GAFA,KAAK,aAAeA,EAEhBC,EAAE,MAAO,CACX,KAAK,SAAWA,EAAE,MAAM,QAAU,KAClC,OAGF,IAAMC,EAASF,EAAI,SAAS,cAAc,QAAQ,EAClDE,EAAO,KAAO,kBAEdA,EAAO,UAAYC,EACnBH,EAAI,SAAS,KAAK,YAAYE,CAAM,EAEpC,IAAME,EAAWJ,EAAwB,MACzC,GAAI,CAACI,GAAW,CAACA,EAAQ,OAAQ,CAC/B,QAAQ,MAAM,+CAAwC,EACtD,OAGF,KAAK,SAAWA,EAAQ,MAC1B,CAEO,OAAQ,CACb,GAAI,CAAC,KAAK,cAAgB,CAAC,KAAK,SAAU,CACxC,QAAQ,KAAK,sCAA+B,EAC5C,OAGF,GAAI,KAAK,OAAQ,CACf,QAAQ,KAAK,qCAA8B,EAC3C,OAGF,KAAK,OAAS,KAAK,SAAS,CAC1B,KAAON,GAAyB,KAAK,WAAWA,CAAK,EACrD,iBAAkB,GAClB,QAAS,IACP,+BAA4B,CAC1B,IAAK,KACL,MAAO,IAAM,EAAE,KAAK,YACtB,CAAC,CACH,EAEA,iBAAkB,CAAE,SAAU,EAAK,EACnC,eAAgB,MAChB,iBAAkB,GAClB,SAAU,CACR,UAAW,GACX,iBAAkB,CAChB,QAAS,GACT,UAAW,GACX,MAAO,GACP,YAAa,GACb,SAAU,GACV,MAAO,GACP,KAAM,GACN,WAAY,GACZ,SAAU,EACZ,EACA,OAAQ,IACR,MAAO,IACP,MAAO,OACP,OAAQ,MACR,WAAY,CACV,KAAM,WACN,SAAU,GACV,UAAW,GACX,YAAa,IACb,YAAa,EACf,CACF,EACA,UAAW,GACX,aAAc,GACd,aAAc,GACd,aAAc,GACd,iBAAkB,QAElB,YAAa,kBACf,CAAC,EAED,KAAK,MAAM,CACb,CAEO,MAAO,CACZ,KAAK,MAAM,EACX,KAAK,SAAS,EACd,KAAK,OAAS,IAChB,CAEO,OAAQ,CACb,KAAK,aAAe,EACpB,KAAK,OAAS,CAAC,EACf,KAAK,KAAK,EACV,KAAK,QAAU,CACb,UAAYA,GAAU,KAAK,OAAO,KAAKA,CAAK,CAC9C,CACF,CAEO,OAAQ,CACb,GAAI,CAAC,KAAK,SAAU,OAEpB,IAAMO,EAA0C,CAAC,EAEjD,QAAWC,KAAO,KAAK,cACrB,GAAI,CACF,KAAK,SAAS,eAAeA,EAAI,IAAKA,EAAI,OAAO,CACnD,MAAE,CACA,QAAQ,KAAK,0CAA0CA,EAAI,KAAK,EAChED,EAAa,KAAKC,CAAG,CACvB,CAGF,KAAK,cAAgBD,CACvB,CAEO,eAAeE,EAAaC,EAAkC,CACnE,IAAMV,EAAQ,CAAE,IAAAS,EAAK,QAAAC,CAAQ,EAE7B,GAAI,CAAC,KAAK,UAAY,CAAC,KAAK,OAAQ,CAClC,QAAQ,KAAK,qDAAqDD,GAAK,EACvE,KAAK,cAAc,KAAKT,CAAK,EAC7B,OAGF,GAAI,CACF,KAAK,SAAS,eAAeS,EAAKC,CAAO,CAC3C,OAASC,EAAP,CACA,QAAQ,KAAK,sCAAsCF,IAAOE,CAAK,EAC/D,KAAK,cAAc,KAAKX,CAAK,CAC/B,CACF,CAEO,kBAA4B,CACjC,MAAO,CAAC,CAAC,KAAK,UAAY,CAAC,CAAC,KAAK,MACnC,CAEO,WAAsC,CAC3C,OAAO,KAAK,MACd,CAEO,WAAgC,CACrC,OAAQ,KAAK,UAA6C,MAC5D,CAEO,KAAKY,EAAsB,CAChC,KAAK,QAAUA,CACjB,CAEO,gBAAgBC,EAAe,CACpC,KAAK,aAAeA,CACtB,CAEO,eAAgB,CAErB,OAAOR,CACT,CACF,ECzMA,IAAOS,EAAQC,EFEf,IAAMC,EAAN,KAA6B,CACnB,SACA,KACA,OAAgB,CAAC,EAEzB,YAAYC,EAAyBC,EAAY,CAC/C,KAAK,SAAWD,EAChB,KAAK,KAAOC,CACd,CAEA,MAAa,OAAQ,CAEjB,IAAMC,EAAU,KAAK,SAAS,cAAc,EAE5C,MAAM,KAAK,KAAK,cAAc,CAAC,QAASA,CAAO,CAAC,CACpD,CAEF,EAEMC,EAAO,EAAAC,KAAK,OAIf,CACD,QAAS,MAAO,CAAE,QAAAC,CAAQ,EAAyBC,IAAQ,CAQzD,MAAMA,EAAID,CAAO,CACnB,EAEA,QAAS,MAAO,CAAE,QAAAA,CAAQ,EAAyBC,IAAQ,CACzD,IAAMC,EAAU,MAAMF,EAAQ,WAAW,EAQzC,MAAMC,EAAIC,CAAO,EACjB,MAAMA,EAAQ,MAAM,CACtB,EAEA,KAAM,MAAO,CAAE,KAAAN,CAAK,EAAmBK,IAAQ,CAI7CL,EAAK,GAAG,UAAW,MAAOO,GAAmC,CAAC,CAAC,EAE/DP,EAAK,GAAG,OAAQ,MAAOA,GAAe,CAAC,CAAC,EAExCA,EAAK,GAAG,mBAAoB,MAAOA,GAAe,CAAC,CAAC,EAEpDA,EAAK,GAAG,iBAAkB,MAAOQ,GAAiB,CAAC,CAAC,EAcpD,IAAMT,EAAW,IAAIU,EACfC,EAAU,IAAIZ,EAAuBC,EAAUC,CAAI,EAGzD,MAAMK,EAAIL,CAAI,CAChB,CACF,CAAC,EAGDE,EAAK,WAAW,MAAO,CAAC,EAAGS,IAAa,CACtC,QAAQ,IAAI,0BAAmBA,EAAS,OAAO,CACjD,CAAC,EAGDT,EAAK,UAAU,MAAO,CAAC,EAAGS,IAAa,CACrC,QAAQ,IAAI,wBAAiBA,EAAS,OAAO,CAC/C,CAAC","names":["src_exports","__export","test","__toCommonJS","import_test","import_rrweb_plugin_sequential_id_record","RRWebRecorder","event","rrEvent","win","w","script","rrweb_record_umd_cjs_default","recheck","stillPending","evt","tag","payload","error","ctx","value","recorder_default","RRWebRecorder","PlaywrightRRWebAdapter","recorder","page","srcCode","test","base","browser","use","context","consoleMessage","frame","recorder_default","adapter","testInfo"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/recorder/RRWebRecorder.ts","../src/recorder/index.ts"],"sourcesContent":["import { test as base, expect } from '@playwright/test';\nimport type { Browser, BrowserContext, Page, Frame, ConsoleMessage } from '@playwright/test';\nimport { parseSerializedValue } from './serializers';\nimport RRWebRecorder from './recorder';\n\nclass PlaywrightRRWebAdapter {\n private recorder: RRWebRecorder;\n private page: Page;\n private buffer: any[] = [];\n\n constructor(recorder: RRWebRecorder, page: Page) {\n this.recorder = recorder;\n this.page = page;\n }\n\n public async setup() {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n const srcCode = this.recorder.getScriptCode();\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument,@typescript-eslint/no-unsafe-assignment\n await this.page.addInitScript({content: srcCode});\n }\n\n}\n\nconst test = base.extend<{\n browser: Browser;\n context: BrowserContext;\n page: Page;\n}>({\n browser: async ({ browser }: { browser: Browser }, use) => {\n\n // const originalOnMessage = browser._connection.onmessage.bind(browser._connection);\n //\n // browser._connection.onmessage = (message: any) => {\n // originalOnMessage(message);\n // };\n\n await use(browser);\n },\n\n context: async ({ browser }: { browser: Browser }, use) => {\n const context = await browser.newContext();\n\n // const originalOnMessage = context._connection.onmessage.bind(context._connection);\n //\n // context._connection.onmessage = (message: any) => {\n // originalOnMessage(message);\n // };\n\n await use(context);\n await context.close();\n },\n\n page: async ({ page }: { page: Page }, use) => {\n // eslint-disable-next-line @typescript-eslint/no-empty-function,@typescript-eslint/ban-ts-comment\n // @ts-ignore\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n page.on('console', async (consoleMessage: ConsoleMessage) => {});\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n page.on('load', async (page: Page) => {});\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n page.on('domcontentloaded', async (page: Page) => {});\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n page.on('framenavigated', async (frame: Frame) => {});\n // const originalOnMessage = page._connection.onmessage.bind(page._connection);\n // page._connection.onmessage = (message: any) => {\n // // const curGuid = message.guid;\n // // const curObject = page._objects?.get?.(curGuid);\n // // const curInit = curObject?._initializer;\n // // if (curInit?.name === '_captureEvent') {\n // // const curInitArgs = curInit.args;\n // // const event = parseSerializedValue(curInitArgs[0], undefined);\n // // console.log(`[onmessage][captureEvent]`, event.timestamp, event.type);\n // // }\n // console.log(`[onmessage]`, message.method);\n // originalOnMessage(message);\n // };\n const recorder = new RRWebRecorder();\n const adapter = new PlaywrightRRWebAdapter(recorder, page);\n\n\n await use(page);\n },\n});\n\n// eslint-disable-next-line no-empty-pattern,@typescript-eslint/require-await\ntest.beforeEach(async ({}, testInfo) => {\n console.log(`[🟢 TEST START] ${testInfo.title}`);\n});\n\n// eslint-disable-next-line no-empty-pattern,@typescript-eslint/require-await\ntest.afterEach(async ({}, testInfo) => {\n console.log(`[🔴 TEST END] ${testInfo.title}`);\n});\n\nexport { test, expect };\n\n","import type { record } from '@appsurify-testmap/rrweb';\nimport type { Mirror } from '@appsurify-testmap/rrweb-snapshot';\nimport { getRecordSequentialIdPlugin } from '@appsurify-testmap/rrweb-plugin-sequential-id-record';\n\n// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n// @ts-ignore\nimport rrSrc from './releases/rrweb-record.umd.cjs.src';\n\nimport type { RecorderContext, Recorder, RecorderEvent } from './types';\n\ninterface WindowWithRRWeb extends Window {\n rrweb?: {\n record: typeof record | null;\n };\n}\n\nexport class RRWebRecorder implements Recorder {\n private recordFn: typeof record | null = null;\n private stopFn: (() => void) | undefined | null = null;\n private targetWindow: Window | null = null;\n private context: RecorderContext;\n private eventCounter = 0;\n private events: RecorderEvent[] = [];\n\n private pendingEvents: {\n tag: string;\n payload: Record<string, unknown>;\n }[] = [];\n\n constructor() {\n this.context = {\n pushEvent: (event) => this.events.push(event),\n };\n }\n\n private handleEmit(event: RecorderEvent) {\n if (event.type === 0 || event.type === 1) {\n return;\n }\n const rrEvent: RecorderEvent = {\n ...event,\n };\n this.context.pushEvent(rrEvent);\n }\n\n public inject(win: Window) {\n const w = win as WindowWithRRWeb;\n\n this.targetWindow = win;\n\n if (w.rrweb) {\n this.recordFn = w.rrweb.record ?? null;\n return;\n }\n\n const script = win.document.createElement('script');\n script.type = 'text/javascript';\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n script.innerHTML = rrSrc;\n win.document.head.appendChild(script);\n\n const recheck = (win as WindowWithRRWeb).rrweb;\n if (!recheck || !recheck.record) {\n console.error(`🟡 [rrweb] Failed to load rrweb.record`);\n return;\n }\n\n this.recordFn = recheck.record;\n }\n\n public start() {\n if (!this.targetWindow || !this.recordFn) {\n console.warn(`🟡 [rrweb] Not ready to start`);\n return;\n }\n\n if (this.stopFn) {\n console.warn(`🟡 [rrweb] Already recording`);\n return;\n }\n\n this.stopFn = this.recordFn({\n emit: (event: RecorderEvent) => this.handleEmit(event),\n checkoutEveryNvm: 10,\n plugins: [\n getRecordSequentialIdPlugin({\n key: 'id',\n getId: () => ++this.eventCounter,\n }),\n ],\n // includeAttribute: /data-(cy|test(id)?|cypress|highlight-el|cypress-el)/i,\n maskInputOptions: { password: true },\n slimDOMOptions: 'all',\n inlineStylesheet: true,\n sampling: {\n mousemove: false,\n mouseInteraction: {\n MouseUp: false,\n MouseDown: false,\n Click: true,\n ContextMenu: true,\n DblClick: true,\n Focus: true,\n Blur: true,\n TouchStart: false,\n TouchEnd: false,\n },\n scroll: 100,\n media: 100,\n input: 'last',\n canvas: 'all',\n visibility: {\n mode: 'debounce',\n debounce: 50,\n threshold: 0.5,\n sensitivity: 0.05,\n rafThrottle: 50\n }\n },\n recordDOM: true,\n recordCanvas: true,\n collectFonts: true,\n inlineImages: true,\n flushCustomEvent: 'after',\n // recordAfter: 'DOMContentStabilized',\n recordAfter: 'DOMContentLoaded',\n });\n\n this.flush();\n }\n\n public stop() {\n this.flush();\n this.stopFn?.();\n this.stopFn = null;\n }\n\n public reset() {\n this.eventCounter = 0;\n this.events = [];\n this.stop();\n this.context = {\n pushEvent: (event) => this.events.push(event),\n };\n }\n\n public flush() {\n if (!this.recordFn) return;\n\n const stillPending: typeof this.pendingEvents = [];\n\n for (const evt of this.pendingEvents) {\n try {\n this.recordFn.addCustomEvent(evt.tag, evt.payload);\n } catch (err) {\n console.warn(`[rrweb] flush failed for custom event: ${evt.tag}`);\n stillPending.push(evt);\n }\n }\n\n this.pendingEvents = stillPending;\n }\n\n public addCustomEvent(tag: string, payload: Record<string, unknown>) {\n const event = { tag, payload };\n\n if (!this.recordFn || !this.stopFn) {\n console.warn(`[rrweb] queued custom event (recorder not ready): ${tag}`);\n this.pendingEvents.push(event);\n return;\n }\n\n try {\n this.recordFn.addCustomEvent(tag, payload);\n } catch (error) {\n console.warn(`[rrweb] error adding custom event: ${tag}`, error);\n this.pendingEvents.push(event);\n }\n }\n\n public isRecordingReady(): boolean {\n return !!this.recordFn && !!this.stopFn;\n }\n\n public getEvents(): readonly RecorderEvent[] {\n return this.events;\n }\n\n public getMirror(): Mirror | undefined {\n return (this.recordFn as unknown as { mirror?: Mirror })?.mirror;\n }\n\n public bind(ctx: RecorderContext) {\n this.context = ctx;\n }\n\n public setEventCounter(value: number) {\n this.eventCounter = value;\n }\n\n public getScriptCode() {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return\n return rrSrc;\n }\n}\n","import { RRWebRecorder } from './RRWebRecorder';\n\n\nexport default RRWebRecorder;\n"],"mappings":"yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,8BAAAE,IAAA,eAAAC,EAAAH,GAAA,IAAAI,EAAqC,4BCErC,IAAAC,EAA4C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;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","names":["src_exports","__export","test","__toCommonJS","import_test","import_rrweb_plugin_sequential_id_record","RRWebRecorder","event","rrEvent","win","w","script","rrweb_record_umd_cjs_default","recheck","stillPending","evt","tag","payload","error","ctx","value","recorder_default","RRWebRecorder","PlaywrightRRWebAdapter","recorder","page","srcCode","test","base","browser","use","context","consoleMessage","frame","recorder_default","adapter","testInfo"]}
|
package/dist/index.js
CHANGED
|
@@ -871,10 +871,13 @@ function inspectInlineEventHandlers$1() {
|
|
|
871
871
|
});
|
|
872
872
|
});
|
|
873
873
|
}
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
874
|
+
try {
|
|
875
|
+
if (document.readyState === "complete" || document.readyState === "interactive") {
|
|
876
|
+
inspectInlineEventHandlers$1();
|
|
877
|
+
} else {
|
|
878
|
+
document.addEventListener("DOMContentLoaded", inspectInlineEventHandlers$1);
|
|
879
|
+
}
|
|
880
|
+
} catch (error) {
|
|
878
881
|
}
|
|
879
882
|
let _id = 1;
|
|
880
883
|
const tagNameRegex = new RegExp("[^a-z0-9-_:]");
|
|
@@ -5581,10 +5584,13 @@ function inspectInlineEventHandlers() {
|
|
|
5581
5584
|
});
|
|
5582
5585
|
});
|
|
5583
5586
|
}
|
|
5584
|
-
|
|
5585
|
-
|
|
5586
|
-
|
|
5587
|
-
|
|
5587
|
+
try {
|
|
5588
|
+
if (document.readyState === "complete" || document.readyState === "interactive") {
|
|
5589
|
+
inspectInlineEventHandlers();
|
|
5590
|
+
} else {
|
|
5591
|
+
document.addEventListener("DOMContentLoaded", inspectInlineEventHandlers);
|
|
5592
|
+
}
|
|
5593
|
+
} catch (error) {
|
|
5588
5594
|
}
|
|
5589
5595
|
function getDefaultExportFromCjs(x2) {
|
|
5590
5596
|
return x2 && x2.__esModule && Object.prototype.hasOwnProperty.call(x2, "default") ? x2["default"] : x2;
|
|
@@ -10859,6 +10865,8 @@ function initViewportResizeObserver({ viewportResizeCb }, { win }) {
|
|
|
10859
10865
|
}
|
|
10860
10866
|
const INPUT_TAGS = ["INPUT", "TEXTAREA", "SELECT"];
|
|
10861
10867
|
const lastInputValueMap = /* @__PURE__ */ new WeakMap();
|
|
10868
|
+
const FINALIZING_KEYS = ["Enter", "Tab", "Escape", "ArrowDown", "ArrowUp", "Delete"];
|
|
10869
|
+
const lastKeyInputValueMap = /* @__PURE__ */ new WeakMap();
|
|
10862
10870
|
function initInputObserver({
|
|
10863
10871
|
inputCb,
|
|
10864
10872
|
doc,
|
|
@@ -10931,6 +10939,22 @@ function initInputObserver({
|
|
|
10931
10939
|
const isPhantomCheckbox = el.type === "checkbox" && !v2.userTriggered && !v2.isChecked && !lastInputValue;
|
|
10932
10940
|
const isPhantomRadio = el.type === "radio" && !v2.userTriggered && !v2.isChecked && !lastInputValue;
|
|
10933
10941
|
if (isLikelyPhantom || isRenderDrivenTextInput || isValueFromDefault || isPhantomCheckbox || isPhantomRadio) {
|
|
10942
|
+
console.debug(
|
|
10943
|
+
\`[\${nowTimestamp()}] [rrweb:record/observer] \\u26D4 phantom input ignored\`,
|
|
10944
|
+
{
|
|
10945
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-call
|
|
10946
|
+
node: index.describeNode(el),
|
|
10947
|
+
tag: el.tagName,
|
|
10948
|
+
nodeType: el.nodeType,
|
|
10949
|
+
attribute: el.attributes,
|
|
10950
|
+
value: el.value,
|
|
10951
|
+
isLikelyPhantom,
|
|
10952
|
+
isRenderDrivenTextInput,
|
|
10953
|
+
isValueFromDefault,
|
|
10954
|
+
isPhantomCheckbox,
|
|
10955
|
+
isPhantomRadio
|
|
10956
|
+
}
|
|
10957
|
+
);
|
|
10934
10958
|
return;
|
|
10935
10959
|
}
|
|
10936
10960
|
if (!lastInputValue || lastInputValue.text !== v2.text || lastInputValue.isChecked !== v2.isChecked) {
|
|
@@ -10945,6 +10969,62 @@ function initInputObserver({
|
|
|
10945
10969
|
const handlers = events.map(
|
|
10946
10970
|
(eventName) => on(eventName, callbackWrapper(eventHandler), doc)
|
|
10947
10971
|
);
|
|
10972
|
+
const keyboardHandler = (event) => {
|
|
10973
|
+
const target = getEventTarget(event);
|
|
10974
|
+
if (!target || !target.tagName)
|
|
10975
|
+
return;
|
|
10976
|
+
if (sampling.input === "all") {
|
|
10977
|
+
eventHandler(event);
|
|
10978
|
+
return;
|
|
10979
|
+
}
|
|
10980
|
+
const tag = target.tagName;
|
|
10981
|
+
const key = event.key;
|
|
10982
|
+
const isFinalizingKey = FINALIZING_KEYS.includes(key);
|
|
10983
|
+
const isTextarea = tag === "TEXTAREA";
|
|
10984
|
+
const isFocused = doc.activeElement === target;
|
|
10985
|
+
const valueNow = target.value;
|
|
10986
|
+
const valueBefore = lastKeyInputValueMap.get(target);
|
|
10987
|
+
lastKeyInputValueMap.set(target, valueNow);
|
|
10988
|
+
if (!isFocused) {
|
|
10989
|
+
eventHandler(event);
|
|
10990
|
+
return;
|
|
10991
|
+
}
|
|
10992
|
+
if (isFinalizingKey) {
|
|
10993
|
+
if (!isTextarea) {
|
|
10994
|
+
eventHandler(event);
|
|
10995
|
+
return;
|
|
10996
|
+
}
|
|
10997
|
+
let lastValue = valueBefore != null ? valueBefore : "";
|
|
10998
|
+
let unchangedCount = 0;
|
|
10999
|
+
const REQUIRED_STABLE_FRAMES = 2;
|
|
11000
|
+
const checkFinal = () => {
|
|
11001
|
+
const currentValue = target.value;
|
|
11002
|
+
const stillFocused = doc.activeElement === target;
|
|
11003
|
+
const changed = currentValue !== lastValue;
|
|
11004
|
+
if (!stillFocused) {
|
|
11005
|
+
eventHandler(event);
|
|
11006
|
+
return;
|
|
11007
|
+
}
|
|
11008
|
+
if (!changed) {
|
|
11009
|
+
unchangedCount++;
|
|
11010
|
+
if (unchangedCount >= REQUIRED_STABLE_FRAMES) {
|
|
11011
|
+
eventHandler(event);
|
|
11012
|
+
return;
|
|
11013
|
+
}
|
|
11014
|
+
} else {
|
|
11015
|
+
unchangedCount = 0;
|
|
11016
|
+
lastValue = currentValue;
|
|
11017
|
+
}
|
|
11018
|
+
requestAnimationFrame(checkFinal);
|
|
11019
|
+
};
|
|
11020
|
+
requestAnimationFrame(checkFinal);
|
|
11021
|
+
return;
|
|
11022
|
+
}
|
|
11023
|
+
};
|
|
11024
|
+
handlers.push(
|
|
11025
|
+
on("keydown", callbackWrapper(keyboardHandler), doc)
|
|
11026
|
+
// on('keypress', callbackWrapper(keyboardHandler), doc),
|
|
11027
|
+
);
|
|
10948
11028
|
const currentWindow = doc.defaultView;
|
|
10949
11029
|
if (!currentWindow) {
|
|
10950
11030
|
return () => {
|
|
@@ -12932,13 +13012,14 @@ class VisibilityManager {
|
|
|
12932
13012
|
cancelAnimationFrame(this.rafId);
|
|
12933
13013
|
}
|
|
12934
13014
|
}
|
|
13015
|
+
const version$1 = "2.1.2-alpha.2";
|
|
12935
13016
|
let wrappedEmit;
|
|
12936
13017
|
let takeFullSnapshot$1;
|
|
12937
13018
|
let canvasManager;
|
|
12938
13019
|
let visibilityManager;
|
|
12939
13020
|
let recording = false;
|
|
12940
13021
|
const customEventQueue = [];
|
|
12941
|
-
let flushCustomEventQueue;
|
|
13022
|
+
let flushCustomEventQueue$1;
|
|
12942
13023
|
function waitForDOMStabilization(win) {
|
|
12943
13024
|
const maxWaitMs = 5e3;
|
|
12944
13025
|
return new Promise((resolve2) => {
|
|
@@ -13303,7 +13384,7 @@ function record(options = {}) {
|
|
|
13303
13384
|
mirror.getId(document)
|
|
13304
13385
|
);
|
|
13305
13386
|
};
|
|
13306
|
-
flushCustomEventQueue = () => {
|
|
13387
|
+
flushCustomEventQueue$1 = () => {
|
|
13307
13388
|
for (const e2 of customEventQueue) {
|
|
13308
13389
|
wrappedEmit(e2);
|
|
13309
13390
|
}
|
|
@@ -13437,37 +13518,34 @@ function record(options = {}) {
|
|
|
13437
13518
|
});
|
|
13438
13519
|
const init = () => {
|
|
13439
13520
|
if (flushCustomEvent === "before") {
|
|
13440
|
-
flushCustomEventQueue();
|
|
13521
|
+
flushCustomEventQueue$1();
|
|
13441
13522
|
}
|
|
13442
13523
|
takeFullSnapshot$1();
|
|
13443
13524
|
handlers.push(observe(document));
|
|
13444
13525
|
recording = true;
|
|
13445
13526
|
if (flushCustomEvent === "after") {
|
|
13446
|
-
flushCustomEventQueue();
|
|
13527
|
+
flushCustomEventQueue$1();
|
|
13447
13528
|
}
|
|
13448
13529
|
};
|
|
13449
13530
|
const runInit = async () => {
|
|
13450
13531
|
if (flushCustomEvent === "before") {
|
|
13451
|
-
flushCustomEventQueue();
|
|
13532
|
+
flushCustomEventQueue$1();
|
|
13452
13533
|
}
|
|
13453
13534
|
if (recordAfter === "DOMContentStabilized") {
|
|
13454
|
-
console.
|
|
13535
|
+
console.debug(\`[\${nowTimestamp()}] [rrweb:record] \\u{1F7E2} Waiting for DOM stabilization...\`);
|
|
13455
13536
|
await waitForDOMStabilization(window);
|
|
13456
|
-
console.
|
|
13537
|
+
console.debug(\`[\${nowTimestamp()}] [rrweb:record] \\u2705 DOM stabilized, starting recording\`);
|
|
13457
13538
|
}
|
|
13539
|
+
console.debug(\`[\${nowTimestamp()}] [rrweb:record] \\u2705 Init dom and takeFullSnapshot \`);
|
|
13458
13540
|
takeFullSnapshot$1();
|
|
13459
13541
|
handlers.push(observe(document));
|
|
13460
13542
|
recording = true;
|
|
13461
13543
|
if (flushCustomEvent === "after") {
|
|
13462
|
-
flushCustomEventQueue();
|
|
13544
|
+
flushCustomEventQueue$1();
|
|
13463
13545
|
}
|
|
13464
13546
|
};
|
|
13465
13547
|
if (document.readyState === "interactive" || document.readyState === "complete") {
|
|
13466
|
-
|
|
13467
|
-
void runInit();
|
|
13468
|
-
} else {
|
|
13469
|
-
init();
|
|
13470
|
-
}
|
|
13548
|
+
init();
|
|
13471
13549
|
} else {
|
|
13472
13550
|
handlers.push(
|
|
13473
13551
|
on("DOMContentLoaded", () => {
|
|
@@ -13475,9 +13553,8 @@ function record(options = {}) {
|
|
|
13475
13553
|
type: EventType.DomContentLoaded,
|
|
13476
13554
|
data: {}
|
|
13477
13555
|
});
|
|
13478
|
-
if (recordAfter === "DOMContentLoaded"
|
|
13479
|
-
|
|
13480
|
-
}
|
|
13556
|
+
if (recordAfter === "DOMContentLoaded")
|
|
13557
|
+
init();
|
|
13481
13558
|
})
|
|
13482
13559
|
);
|
|
13483
13560
|
handlers.push(
|
|
@@ -13489,14 +13566,14 @@ function record(options = {}) {
|
|
|
13489
13566
|
data: {}
|
|
13490
13567
|
});
|
|
13491
13568
|
if (recordAfter === "load")
|
|
13492
|
-
|
|
13569
|
+
init();
|
|
13493
13570
|
},
|
|
13494
13571
|
window
|
|
13495
13572
|
)
|
|
13496
13573
|
);
|
|
13497
13574
|
}
|
|
13498
13575
|
return () => {
|
|
13499
|
-
flushCustomEventQueue();
|
|
13576
|
+
flushCustomEventQueue$1();
|
|
13500
13577
|
handlers.forEach((h) => h());
|
|
13501
13578
|
processedNodeManager.destroy();
|
|
13502
13579
|
recording = false;
|
|
@@ -13506,10 +13583,11 @@ function record(options = {}) {
|
|
|
13506
13583
|
console.warn(error);
|
|
13507
13584
|
}
|
|
13508
13585
|
}
|
|
13586
|
+
record.getVersion = () => version$1;
|
|
13509
13587
|
record.isRecording = () => recording;
|
|
13510
13588
|
record.flushCustomEventQueue = () => {
|
|
13511
13589
|
console.warn(\`[rrweb] CustomEvent flushing: \${customEventQueue.length} events\`);
|
|
13512
|
-
flushCustomEventQueue();
|
|
13590
|
+
flushCustomEventQueue$1();
|
|
13513
13591
|
};
|
|
13514
13592
|
record.addCustomEvent = (tag, payload) => {
|
|
13515
13593
|
const customEvent = {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/recorder/RRWebRecorder.ts","../src/recorder/index.ts"],"sourcesContent":["import { test as base, expect } from '@playwright/test';\nimport type { Browser, BrowserContext, Page, Frame, ConsoleMessage } from '@playwright/test';\nimport { parseSerializedValue } from './serializers';\nimport RRWebRecorder from './recorder';\n\nclass PlaywrightRRWebAdapter {\n private recorder: RRWebRecorder;\n private page: Page;\n private buffer: any[] = [];\n\n constructor(recorder: RRWebRecorder, page: Page) {\n this.recorder = recorder;\n this.page = page;\n }\n\n public async setup() {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n const srcCode = this.recorder.getScriptCode();\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument,@typescript-eslint/no-unsafe-assignment\n await this.page.addInitScript({content: srcCode});\n }\n\n}\n\nconst test = base.extend<{\n browser: Browser;\n context: BrowserContext;\n page: Page;\n}>({\n browser: async ({ browser }: { browser: Browser }, use) => {\n\n // const originalOnMessage = browser._connection.onmessage.bind(browser._connection);\n //\n // browser._connection.onmessage = (message: any) => {\n // originalOnMessage(message);\n // };\n\n await use(browser);\n },\n\n context: async ({ browser }: { browser: Browser }, use) => {\n const context = await browser.newContext();\n\n // const originalOnMessage = context._connection.onmessage.bind(context._connection);\n //\n // context._connection.onmessage = (message: any) => {\n // originalOnMessage(message);\n // };\n\n await use(context);\n await context.close();\n },\n\n page: async ({ page }: { page: Page }, use) => {\n // eslint-disable-next-line @typescript-eslint/no-empty-function,@typescript-eslint/ban-ts-comment\n // @ts-ignore\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n page.on('console', async (consoleMessage: ConsoleMessage) => {});\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n page.on('load', async (page: Page) => {});\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n page.on('domcontentloaded', async (page: Page) => {});\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n page.on('framenavigated', async (frame: Frame) => {});\n // const originalOnMessage = page._connection.onmessage.bind(page._connection);\n // page._connection.onmessage = (message: any) => {\n // // const curGuid = message.guid;\n // // const curObject = page._objects?.get?.(curGuid);\n // // const curInit = curObject?._initializer;\n // // if (curInit?.name === '_captureEvent') {\n // // const curInitArgs = curInit.args;\n // // const event = parseSerializedValue(curInitArgs[0], undefined);\n // // console.log(`[onmessage][captureEvent]`, event.timestamp, event.type);\n // // }\n // console.log(`[onmessage]`, message.method);\n // originalOnMessage(message);\n // };\n const recorder = new RRWebRecorder();\n const adapter = new PlaywrightRRWebAdapter(recorder, page);\n\n\n await use(page);\n },\n});\n\n// eslint-disable-next-line no-empty-pattern,@typescript-eslint/require-await\ntest.beforeEach(async ({}, testInfo) => {\n console.log(`[🟢 TEST START] ${testInfo.title}`);\n});\n\n// eslint-disable-next-line no-empty-pattern,@typescript-eslint/require-await\ntest.afterEach(async ({}, testInfo) => {\n console.log(`[🔴 TEST END] ${testInfo.title}`);\n});\n\nexport { test, expect };\n\n","import type { record } from '@appsurify-testmap/rrweb';\nimport type { Mirror } from '@appsurify-testmap/rrweb-snapshot';\nimport { getRecordSequentialIdPlugin } from '@appsurify-testmap/rrweb-plugin-sequential-id-record';\n\n// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n// @ts-ignore\nimport rrSrc from './releases/rrweb-record.umd.cjs.src';\n\nimport type { RecorderContext, Recorder, RecorderEvent } from './types';\n\ninterface WindowWithRRWeb extends Window {\n rrweb?: {\n record: typeof record | null;\n };\n}\n\nexport class RRWebRecorder implements Recorder {\n private recordFn: typeof record | null = null;\n private stopFn: (() => void) | undefined | null = null;\n private targetWindow: Window | null = null;\n private context: RecorderContext;\n private eventCounter = 0;\n private events: RecorderEvent[] = [];\n\n private pendingEvents: {\n tag: string;\n payload: Record<string, unknown>;\n }[] = [];\n\n constructor() {\n this.context = {\n pushEvent: (event) => this.events.push(event),\n };\n }\n\n private handleEmit(event: RecorderEvent) {\n if (event.type === 0 || event.type === 1) {\n return;\n }\n const rrEvent: RecorderEvent = {\n ...event,\n };\n this.context.pushEvent(rrEvent);\n }\n\n public inject(win: Window) {\n const w = win as WindowWithRRWeb;\n\n this.targetWindow = win;\n\n if (w.rrweb) {\n this.recordFn = w.rrweb.record ?? null;\n return;\n }\n\n const script = win.document.createElement('script');\n script.type = 'text/javascript';\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n script.innerHTML = rrSrc;\n win.document.head.appendChild(script);\n\n const recheck = (win as WindowWithRRWeb).rrweb;\n if (!recheck || !recheck.record) {\n console.error(`🟡 [rrweb] Failed to load rrweb.record`);\n return;\n }\n\n this.recordFn = recheck.record;\n }\n\n public start() {\n if (!this.targetWindow || !this.recordFn) {\n console.warn(`🟡 [rrweb] Not ready to start`);\n return;\n }\n\n if (this.stopFn) {\n console.warn(`🟡 [rrweb] Already recording`);\n return;\n }\n\n this.stopFn = this.recordFn({\n emit: (event: RecorderEvent) => this.handleEmit(event),\n checkoutEveryNvm: 10,\n plugins: [\n getRecordSequentialIdPlugin({\n key: 'id',\n getId: () => ++this.eventCounter,\n }),\n ],\n // includeAttribute: /data-(cy|test(id)?|cypress|highlight-el|cypress-el)/i,\n maskInputOptions: { password: true },\n slimDOMOptions: 'all',\n inlineStylesheet: true,\n sampling: {\n mousemove: false,\n mouseInteraction: {\n MouseUp: false,\n MouseDown: false,\n Click: true,\n ContextMenu: true,\n DblClick: true,\n Focus: true,\n Blur: true,\n TouchStart: false,\n TouchEnd: false,\n },\n scroll: 100,\n media: 100,\n input: 'last',\n canvas: 'all',\n visibility: {\n mode: 'debounce',\n debounce: 50,\n threshold: 0.5,\n sensitivity: 0.05,\n rafThrottle: 50\n }\n },\n recordDOM: true,\n recordCanvas: true,\n collectFonts: true,\n inlineImages: true,\n flushCustomEvent: 'after',\n // recordAfter: 'DOMContentStabilized',\n recordAfter: 'DOMContentLoaded',\n });\n\n this.flush();\n }\n\n public stop() {\n this.flush();\n this.stopFn?.();\n this.stopFn = null;\n }\n\n public reset() {\n this.eventCounter = 0;\n this.events = [];\n this.stop();\n this.context = {\n pushEvent: (event) => this.events.push(event),\n };\n }\n\n public flush() {\n if (!this.recordFn) return;\n\n const stillPending: typeof this.pendingEvents = [];\n\n for (const evt of this.pendingEvents) {\n try {\n this.recordFn.addCustomEvent(evt.tag, evt.payload);\n } catch (err) {\n console.warn(`[rrweb] flush failed for custom event: ${evt.tag}`);\n stillPending.push(evt);\n }\n }\n\n this.pendingEvents = stillPending;\n }\n\n public addCustomEvent(tag: string, payload: Record<string, unknown>) {\n const event = { tag, payload };\n\n if (!this.recordFn || !this.stopFn) {\n console.warn(`[rrweb] queued custom event (recorder not ready): ${tag}`);\n this.pendingEvents.push(event);\n return;\n }\n\n try {\n this.recordFn.addCustomEvent(tag, payload);\n } catch (error) {\n console.warn(`[rrweb] error adding custom event: ${tag}`, error);\n this.pendingEvents.push(event);\n }\n }\n\n public isRecordingReady(): boolean {\n return !!this.recordFn && !!this.stopFn;\n }\n\n public getEvents(): readonly RecorderEvent[] {\n return this.events;\n }\n\n public getMirror(): Mirror | undefined {\n return (this.recordFn as unknown as { mirror?: Mirror })?.mirror;\n }\n\n public bind(ctx: RecorderContext) {\n this.context = ctx;\n }\n\n public setEventCounter(value: number) {\n this.eventCounter = value;\n }\n\n public getScriptCode() {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return\n return rrSrc;\n }\n}\n","import { RRWebRecorder } from './RRWebRecorder';\n\n\nexport default RRWebRecorder;\n"],"mappings":"AAAA,OAAS,QAAQA,EAAM,UAAAC,MAAc,mBCErC,OAAS,+BAAAC,MAAmC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;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","names":["base","expect","getRecordSequentialIdPlugin","RRWebRecorder","event","rrEvent","win","w","script","rrweb_record_umd_cjs_default","recheck","getRecordSequentialIdPlugin","stillPending","evt","tag","payload","error","ctx","value","recorder_default","RRWebRecorder","PlaywrightRRWebAdapter","recorder","page","srcCode","test","base","browser","use","context","consoleMessage","frame","recorder_default","adapter","testInfo"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/recorder/RRWebRecorder.ts","../src/recorder/index.ts"],"sourcesContent":["import { test as base, expect } from '@playwright/test';\nimport type { Browser, BrowserContext, Page, Frame, ConsoleMessage } from '@playwright/test';\nimport { parseSerializedValue } from './serializers';\nimport RRWebRecorder from './recorder';\n\nclass PlaywrightRRWebAdapter {\n private recorder: RRWebRecorder;\n private page: Page;\n private buffer: any[] = [];\n\n constructor(recorder: RRWebRecorder, page: Page) {\n this.recorder = recorder;\n this.page = page;\n }\n\n public async setup() {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n const srcCode = this.recorder.getScriptCode();\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument,@typescript-eslint/no-unsafe-assignment\n await this.page.addInitScript({content: srcCode});\n }\n\n}\n\nconst test = base.extend<{\n browser: Browser;\n context: BrowserContext;\n page: Page;\n}>({\n browser: async ({ browser }: { browser: Browser }, use) => {\n\n // const originalOnMessage = browser._connection.onmessage.bind(browser._connection);\n //\n // browser._connection.onmessage = (message: any) => {\n // originalOnMessage(message);\n // };\n\n await use(browser);\n },\n\n context: async ({ browser }: { browser: Browser }, use) => {\n const context = await browser.newContext();\n\n // const originalOnMessage = context._connection.onmessage.bind(context._connection);\n //\n // context._connection.onmessage = (message: any) => {\n // originalOnMessage(message);\n // };\n\n await use(context);\n await context.close();\n },\n\n page: async ({ page }: { page: Page }, use) => {\n // eslint-disable-next-line @typescript-eslint/no-empty-function,@typescript-eslint/ban-ts-comment\n // @ts-ignore\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n page.on('console', async (consoleMessage: ConsoleMessage) => {});\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n page.on('load', async (page: Page) => {});\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n page.on('domcontentloaded', async (page: Page) => {});\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n page.on('framenavigated', async (frame: Frame) => {});\n // const originalOnMessage = page._connection.onmessage.bind(page._connection);\n // page._connection.onmessage = (message: any) => {\n // // const curGuid = message.guid;\n // // const curObject = page._objects?.get?.(curGuid);\n // // const curInit = curObject?._initializer;\n // // if (curInit?.name === '_captureEvent') {\n // // const curInitArgs = curInit.args;\n // // const event = parseSerializedValue(curInitArgs[0], undefined);\n // // console.log(`[onmessage][captureEvent]`, event.timestamp, event.type);\n // // }\n // console.log(`[onmessage]`, message.method);\n // originalOnMessage(message);\n // };\n const recorder = new RRWebRecorder();\n const adapter = new PlaywrightRRWebAdapter(recorder, page);\n\n\n await use(page);\n },\n});\n\n// eslint-disable-next-line no-empty-pattern,@typescript-eslint/require-await\ntest.beforeEach(async ({}, testInfo) => {\n console.log(`[🟢 TEST START] ${testInfo.title}`);\n});\n\n// eslint-disable-next-line no-empty-pattern,@typescript-eslint/require-await\ntest.afterEach(async ({}, testInfo) => {\n console.log(`[🔴 TEST END] ${testInfo.title}`);\n});\n\nexport { test, expect };\n\n","import type { record } from '@appsurify-testmap/rrweb';\nimport type { Mirror } from '@appsurify-testmap/rrweb-snapshot';\nimport { getRecordSequentialIdPlugin } from '@appsurify-testmap/rrweb-plugin-sequential-id-record';\n\n// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n// @ts-ignore\nimport rrSrc from './releases/rrweb-record.umd.cjs.src';\n\nimport type { RecorderContext, Recorder, RecorderEvent } from './types';\n\ninterface WindowWithRRWeb extends Window {\n rrweb?: {\n record: typeof record | null;\n };\n}\n\nexport class RRWebRecorder implements Recorder {\n private recordFn: typeof record | null = null;\n private stopFn: (() => void) | undefined | null = null;\n private targetWindow: Window | null = null;\n private context: RecorderContext;\n private eventCounter = 0;\n private events: RecorderEvent[] = [];\n\n private pendingEvents: {\n tag: string;\n payload: Record<string, unknown>;\n }[] = [];\n\n constructor() {\n this.context = {\n pushEvent: (event) => this.events.push(event),\n };\n }\n\n private handleEmit(event: RecorderEvent) {\n if (event.type === 0 || event.type === 1) {\n return;\n }\n const rrEvent: RecorderEvent = {\n ...event,\n };\n this.context.pushEvent(rrEvent);\n }\n\n public inject(win: Window) {\n const w = win as WindowWithRRWeb;\n\n this.targetWindow = win;\n\n if (w.rrweb) {\n this.recordFn = w.rrweb.record ?? null;\n return;\n }\n\n const script = win.document.createElement('script');\n script.type = 'text/javascript';\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n script.innerHTML = rrSrc;\n win.document.head.appendChild(script);\n\n const recheck = (win as WindowWithRRWeb).rrweb;\n if (!recheck || !recheck.record) {\n console.error(`🟡 [rrweb] Failed to load rrweb.record`);\n return;\n }\n\n this.recordFn = recheck.record;\n }\n\n public start() {\n if (!this.targetWindow || !this.recordFn) {\n console.warn(`🟡 [rrweb] Not ready to start`);\n return;\n }\n\n if (this.stopFn) {\n console.warn(`🟡 [rrweb] Already recording`);\n return;\n }\n\n this.stopFn = this.recordFn({\n emit: (event: RecorderEvent) => this.handleEmit(event),\n checkoutEveryNvm: 10,\n plugins: [\n getRecordSequentialIdPlugin({\n key: 'id',\n getId: () => ++this.eventCounter,\n }),\n ],\n // includeAttribute: /data-(cy|test(id)?|cypress|highlight-el|cypress-el)/i,\n maskInputOptions: { password: true },\n slimDOMOptions: 'all',\n inlineStylesheet: true,\n sampling: {\n mousemove: false,\n mouseInteraction: {\n MouseUp: false,\n MouseDown: false,\n Click: true,\n ContextMenu: true,\n DblClick: true,\n Focus: true,\n Blur: true,\n TouchStart: false,\n TouchEnd: false,\n },\n scroll: 100,\n media: 100,\n input: 'last',\n canvas: 'all',\n visibility: {\n mode: 'debounce',\n debounce: 50,\n threshold: 0.5,\n sensitivity: 0.05,\n rafThrottle: 50\n }\n },\n recordDOM: true,\n recordCanvas: true,\n collectFonts: true,\n inlineImages: true,\n flushCustomEvent: 'after',\n // recordAfter: 'DOMContentStabilized',\n recordAfter: 'DOMContentLoaded',\n });\n\n this.flush();\n }\n\n public stop() {\n this.flush();\n this.stopFn?.();\n this.stopFn = null;\n }\n\n public reset() {\n this.eventCounter = 0;\n this.events = [];\n this.stop();\n this.context = {\n pushEvent: (event) => this.events.push(event),\n };\n }\n\n public flush() {\n if (!this.recordFn) return;\n\n const stillPending: typeof this.pendingEvents = [];\n\n for (const evt of this.pendingEvents) {\n try {\n this.recordFn.addCustomEvent(evt.tag, evt.payload);\n } catch (err) {\n console.warn(`[rrweb] flush failed for custom event: ${evt.tag}`);\n stillPending.push(evt);\n }\n }\n\n this.pendingEvents = stillPending;\n }\n\n public addCustomEvent(tag: string, payload: Record<string, unknown>) {\n const event = { tag, payload };\n\n if (!this.recordFn || !this.stopFn) {\n console.warn(`[rrweb] queued custom event (recorder not ready): ${tag}`);\n this.pendingEvents.push(event);\n return;\n }\n\n try {\n this.recordFn.addCustomEvent(tag, payload);\n } catch (error) {\n console.warn(`[rrweb] error adding custom event: ${tag}`, error);\n this.pendingEvents.push(event);\n }\n }\n\n public isRecordingReady(): boolean {\n return !!this.recordFn && !!this.stopFn;\n }\n\n public getEvents(): readonly RecorderEvent[] {\n return this.events;\n }\n\n public getMirror(): Mirror | undefined {\n return (this.recordFn as unknown as { mirror?: Mirror })?.mirror;\n }\n\n public bind(ctx: RecorderContext) {\n this.context = ctx;\n }\n\n public setEventCounter(value: number) {\n this.eventCounter = value;\n }\n\n public getScriptCode() {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return\n return rrSrc;\n }\n}\n","import { RRWebRecorder } from './RRWebRecorder';\n\n\nexport default RRWebRecorder;\n"],"mappings":"AAAA,OAAS,QAAQA,EAAM,UAAAC,MAAc,mBCErC,OAAS,+BAAAC,MAAmC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;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","names":["base","expect","getRecordSequentialIdPlugin","RRWebRecorder","event","rrEvent","win","w","script","rrweb_record_umd_cjs_default","recheck","getRecordSequentialIdPlugin","stillPending","evt","tag","payload","error","ctx","value","recorder_default","RRWebRecorder","PlaywrightRRWebAdapter","recorder","page","srcCode","test","base","browser","use","context","consoleMessage","frame","recorder_default","adapter","testInfo"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@appsurify-testmap/rrweb-playwright-plugin",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.2-alpha.2",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -49,10 +49,10 @@
|
|
|
49
49
|
"typescript": "^5.8.3"
|
|
50
50
|
},
|
|
51
51
|
"dependencies": {
|
|
52
|
-
"@appsurify-testmap/rrweb": "^2.1.
|
|
53
|
-
"@appsurify-testmap/rrweb-plugin-sequential-id-record": "^2.1.
|
|
54
|
-
"@appsurify-testmap/rrweb-snapshot": "^2.1.
|
|
55
|
-
"@appsurify-testmap/rrweb-types": "^2.1.
|
|
52
|
+
"@appsurify-testmap/rrweb": "^2.1.2-alpha.2",
|
|
53
|
+
"@appsurify-testmap/rrweb-plugin-sequential-id-record": "^2.1.2-alpha.2",
|
|
54
|
+
"@appsurify-testmap/rrweb-snapshot": "^2.1.2-alpha.2",
|
|
55
|
+
"@appsurify-testmap/rrweb-types": "^2.1.2-alpha.2",
|
|
56
56
|
"@appsurify-testmap/rrweb-ui-report": "file:/Users/whenessel/Development/WebstormProjects/appsurify-rrweb/packages/rrweb-ui-report"
|
|
57
57
|
}
|
|
58
58
|
}
|