@elizaos/capacitor-screencapture 1.0.0

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.
@@ -0,0 +1,346 @@
1
+ 'use strict';
2
+
3
+ var core = require('@capacitor/core');
4
+
5
+ const loadWeb = () => Promise.resolve().then(function () { return web; }).then((m) => new m.ScreenCaptureWeb());
6
+ const ScreenCapture = core.registerPlugin("ScreenCapture", {
7
+ web: loadWeb,
8
+ });
9
+
10
+ const VIDEO_MIME_TYPES = [
11
+ "video/webm;codecs=vp9,opus",
12
+ "video/webm;codecs=vp8,opus",
13
+ "video/webm",
14
+ "video/mp4",
15
+ ];
16
+ const getSupportedMimeType = () => VIDEO_MIME_TYPES.find((m) => MediaRecorder.isTypeSupported(m)) ?? null;
17
+ const hasDisplayMedia = () => !!navigator.mediaDevices.getDisplayMedia;
18
+ const getDisplayMedia = (opts) => navigator.mediaDevices.getDisplayMedia(opts);
19
+ class ScreenCaptureWeb extends core.WebPlugin {
20
+ constructor() {
21
+ super(...arguments);
22
+ this.mediaStream = null;
23
+ this.mediaRecorder = null;
24
+ this.recordedChunks = [];
25
+ this.isRecording = false;
26
+ this.isPaused = false;
27
+ this.recordingStartTime = 0;
28
+ this.pausedDuration = 0;
29
+ this.pauseStartTime = 0;
30
+ this.recordingStateInterval = null;
31
+ this.pluginListeners = [];
32
+ }
33
+ async isSupported() {
34
+ const supported = hasDisplayMedia();
35
+ const features = [];
36
+ if (supported)
37
+ features.push("screenshot", "recording");
38
+ if (typeof MediaRecorder !== "undefined")
39
+ features.push("video_encoding");
40
+ if (typeof AudioContext !== "undefined")
41
+ features.push("system_audio");
42
+ return { supported, features };
43
+ }
44
+ async captureScreenshot(options) {
45
+ const format = options?.format || "png";
46
+ const quality = (options?.quality || 100) / 100;
47
+ const scale = options?.scale || 1;
48
+ const stream = await getDisplayMedia({
49
+ video: { displaySurface: "monitor" },
50
+ audio: false,
51
+ });
52
+ const track = stream.getVideoTracks()[0];
53
+ const settings = track.getSettings();
54
+ const width = (settings.width || 1920) * scale;
55
+ const height = (settings.height || 1080) * scale;
56
+ const imageCapture = new ImageCapture(track);
57
+ const bitmap = await imageCapture.grabFrame();
58
+ stream.getTracks().forEach((t) => {
59
+ t.stop();
60
+ });
61
+ const canvas = document.createElement("canvas");
62
+ canvas.width = width;
63
+ canvas.height = height;
64
+ const ctx = canvas.getContext("2d");
65
+ if (!ctx) {
66
+ throw new Error("Failed to get canvas context");
67
+ }
68
+ ctx.drawImage(bitmap, 0, 0, width, height);
69
+ bitmap.close();
70
+ const mimeType = format === "png"
71
+ ? "image/png"
72
+ : format === "webp"
73
+ ? "image/webp"
74
+ : "image/jpeg";
75
+ const dataUrl = canvas.toDataURL(mimeType, quality);
76
+ const base64 = dataUrl.split(",")[1];
77
+ return {
78
+ base64,
79
+ format,
80
+ width,
81
+ height,
82
+ timestamp: Date.now(),
83
+ };
84
+ }
85
+ async startRecording(options) {
86
+ if (this.isRecording)
87
+ throw new Error("Recording already in progress");
88
+ const videoConstraints = {
89
+ displaySurface: "monitor",
90
+ };
91
+ if (options?.fps)
92
+ videoConstraints.frameRate = { ideal: options.fps };
93
+ this.mediaStream = await getDisplayMedia({
94
+ video: videoConstraints,
95
+ audio: options?.captureSystemAudio !== false,
96
+ });
97
+ if (options?.captureMicrophone) {
98
+ const micStream = await navigator.mediaDevices.getUserMedia({
99
+ audio: true,
100
+ });
101
+ micStream.getAudioTracks().forEach((t) => {
102
+ this.mediaStream?.addTrack(t);
103
+ });
104
+ }
105
+ const mimeType = getSupportedMimeType();
106
+ if (!mimeType) {
107
+ this.mediaStream.getTracks().forEach((t) => {
108
+ t.stop();
109
+ });
110
+ throw new Error("No supported video mime type found");
111
+ }
112
+ const recorderOptions = { mimeType };
113
+ if (options?.bitrate)
114
+ recorderOptions.videoBitsPerSecond = options.bitrate;
115
+ this.recordedChunks = [];
116
+ this.mediaRecorder = new MediaRecorder(this.mediaStream, recorderOptions);
117
+ this.mediaRecorder.ondataavailable = (event) => {
118
+ if (event.data.size > 0) {
119
+ this.recordedChunks.push(event.data);
120
+ }
121
+ };
122
+ this.mediaRecorder.onerror = (event) => {
123
+ this.notifyListeners("error", {
124
+ code: "RECORDING_ERROR",
125
+ message: `Recording error: ${event.message || "Unknown error"}`,
126
+ });
127
+ };
128
+ this.mediaStream.getVideoTracks()[0].addEventListener("ended", () => {
129
+ if (this.isRecording) {
130
+ this.stopRecording().catch((err) => {
131
+ console.error("[ScreenCapture] Auto-stop on track end failed:", err);
132
+ });
133
+ }
134
+ });
135
+ this.recordingStartTime = Date.now();
136
+ this.pausedDuration = 0;
137
+ this.isRecording = true;
138
+ this.isPaused = false;
139
+ this.mediaRecorder.start(1000);
140
+ this.notifyListeners("recordingState", {
141
+ isRecording: true,
142
+ duration: 0,
143
+ fileSize: 0,
144
+ });
145
+ let autoStopping = false;
146
+ this.recordingStateInterval = setInterval(() => {
147
+ if (!this.isRecording || this.isPaused || autoStopping)
148
+ return;
149
+ const duration = (Date.now() - this.recordingStartTime - this.pausedDuration) / 1000;
150
+ const fileSize = this.recordedChunks.reduce((acc, chunk) => acc + chunk.size, 0);
151
+ this.notifyListeners("recordingState", {
152
+ isRecording: true,
153
+ duration,
154
+ fileSize,
155
+ });
156
+ const overLimit = (options?.maxDuration && duration >= options.maxDuration) ||
157
+ (options?.maxFileSize && fileSize >= options.maxFileSize);
158
+ if (overLimit) {
159
+ autoStopping = true;
160
+ this.stopRecording().catch((err) => {
161
+ console.error("[ScreenCapture] Auto-stop recording failed:", err);
162
+ });
163
+ }
164
+ }, 500);
165
+ }
166
+ async stopRecording() {
167
+ if (!this.isRecording || !this.mediaRecorder) {
168
+ throw new Error("Not recording");
169
+ }
170
+ return new Promise((resolve, reject) => {
171
+ if (!this.mediaRecorder) {
172
+ reject(new Error("MediaRecorder not initialized"));
173
+ return;
174
+ }
175
+ const duration = (Date.now() - this.recordingStartTime - this.pausedDuration) / 1000;
176
+ this.mediaRecorder.onstop = () => {
177
+ if (this.recordingStateInterval) {
178
+ clearInterval(this.recordingStateInterval);
179
+ this.recordingStateInterval = null;
180
+ }
181
+ this.isRecording = false;
182
+ this.isPaused = false;
183
+ if (this.mediaStream) {
184
+ this.mediaStream.getTracks().forEach((track) => {
185
+ track.stop();
186
+ });
187
+ this.mediaStream = null;
188
+ }
189
+ const blob = new Blob(this.recordedChunks, {
190
+ type: this.mediaRecorder?.mimeType || "video/webm",
191
+ });
192
+ const url = URL.createObjectURL(blob);
193
+ const video = document.createElement("video");
194
+ video.src = url;
195
+ video.onloadedmetadata = () => {
196
+ resolve({
197
+ path: url,
198
+ duration,
199
+ width: video.videoWidth,
200
+ height: video.videoHeight,
201
+ fileSize: blob.size,
202
+ mimeType: this.mediaRecorder?.mimeType || "video/webm",
203
+ });
204
+ };
205
+ video.onerror = () => {
206
+ resolve({
207
+ path: url,
208
+ duration,
209
+ width: 0,
210
+ height: 0,
211
+ fileSize: blob.size,
212
+ mimeType: this.mediaRecorder?.mimeType || "video/webm",
213
+ });
214
+ };
215
+ this.notifyListeners("recordingState", {
216
+ isRecording: false,
217
+ duration,
218
+ fileSize: blob.size,
219
+ });
220
+ };
221
+ this.mediaRecorder.stop();
222
+ });
223
+ }
224
+ async pauseRecording() {
225
+ if (!this.isRecording || !this.mediaRecorder) {
226
+ throw new Error("Not recording");
227
+ }
228
+ if (this.isPaused) {
229
+ return;
230
+ }
231
+ this.mediaRecorder.pause();
232
+ this.isPaused = true;
233
+ this.pauseStartTime = Date.now();
234
+ const duration = (Date.now() - this.recordingStartTime - this.pausedDuration) / 1000;
235
+ const fileSize = this.recordedChunks.reduce((acc, chunk) => acc + chunk.size, 0);
236
+ this.notifyListeners("recordingState", {
237
+ isRecording: true,
238
+ duration,
239
+ fileSize,
240
+ });
241
+ }
242
+ async resumeRecording() {
243
+ if (!this.isRecording || !this.mediaRecorder) {
244
+ throw new Error("Not recording");
245
+ }
246
+ if (!this.isPaused) {
247
+ return;
248
+ }
249
+ this.pausedDuration += Date.now() - this.pauseStartTime;
250
+ this.mediaRecorder.resume();
251
+ this.isPaused = false;
252
+ }
253
+ async getRecordingState() {
254
+ const duration = this.isRecording
255
+ ? (Date.now() - this.recordingStartTime - this.pausedDuration) / 1000
256
+ : 0;
257
+ const fileSize = this.recordedChunks.reduce((acc, chunk) => acc + chunk.size, 0);
258
+ return {
259
+ isRecording: this.isRecording,
260
+ duration,
261
+ fileSize,
262
+ };
263
+ }
264
+ /**
265
+ * Check screen capture permissions.
266
+ *
267
+ * LIMITATION: The Screen Capture API (getDisplayMedia) does not support permission queries.
268
+ * Unlike camera/microphone, there's no way to check if permission was previously granted.
269
+ * Each call to getDisplayMedia always prompts the user.
270
+ *
271
+ * `screenCapture` will be:
272
+ * - "not_supported": getDisplayMedia API not available
273
+ * - "prompt": API available, but actual permission state is unknown (always requires prompt)
274
+ */
275
+ async checkPermissions() {
276
+ let microphone = "prompt";
277
+ try {
278
+ const result = await navigator.permissions.query({
279
+ name: "microphone",
280
+ });
281
+ microphone = result.state;
282
+ }
283
+ catch {
284
+ // Permissions API may not support microphone query in this browser
285
+ }
286
+ // Screen capture permission cannot be queried - getDisplayMedia always prompts
287
+ const screenCaptureStatus = hasDisplayMedia() ? "prompt" : "not_supported";
288
+ return { screenCapture: screenCaptureStatus, microphone };
289
+ }
290
+ /**
291
+ * Request screen capture permissions.
292
+ *
293
+ * LIMITATION: Screen capture (getDisplayMedia) cannot be pre-requested.
294
+ * The user is prompted only when an actual capture is initiated.
295
+ * This method only requests microphone permission for audio capture during recording.
296
+ *
297
+ * `screenCapture` will be:
298
+ * - "not_supported": getDisplayMedia API not available
299
+ * - "prompt": API available (permission prompt happens during actual capture)
300
+ */
301
+ async requestPermissions() {
302
+ let microphone = "denied";
303
+ try {
304
+ const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
305
+ stream.getTracks().forEach((t) => {
306
+ t.stop();
307
+ });
308
+ microphone = "granted";
309
+ }
310
+ catch {
311
+ microphone = "denied";
312
+ }
313
+ // Cannot pre-request screen capture permission - it requires user gesture + actual capture
314
+ const screenCaptureStatus = hasDisplayMedia() ? "prompt" : "not_supported";
315
+ return { screenCapture: screenCaptureStatus, microphone };
316
+ }
317
+ async addListener(eventName, listenerFunc) {
318
+ const entry = { eventName, callback: listenerFunc };
319
+ this.pluginListeners.push(entry);
320
+ return {
321
+ remove: async () => {
322
+ const i = this.pluginListeners.indexOf(entry);
323
+ if (i >= 0)
324
+ this.pluginListeners.splice(i, 1);
325
+ },
326
+ };
327
+ }
328
+ async removeAllListeners() {
329
+ this.pluginListeners = [];
330
+ }
331
+ notifyListeners(eventName, data) {
332
+ this.pluginListeners
333
+ .filter((l) => l.eventName === eventName)
334
+ .forEach((l) => {
335
+ l.callback(data);
336
+ });
337
+ }
338
+ }
339
+
340
+ var web = /*#__PURE__*/Object.freeze({
341
+ __proto__: null,
342
+ ScreenCaptureWeb: ScreenCaptureWeb
343
+ });
344
+
345
+ exports.ScreenCapture = ScreenCapture;
346
+ //# sourceMappingURL=plugin.cjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin.cjs.js","sources":["esm/index.js","esm/web.js"],"sourcesContent":["import { registerPlugin } from \"@capacitor/core\";\nexport * from \"./definitions\";\nconst loadWeb = () => import(\"./web\").then((m) => new m.ScreenCaptureWeb());\nexport const ScreenCapture = registerPlugin(\"ScreenCapture\", {\n web: loadWeb,\n});\n","import { WebPlugin } from \"@capacitor/core\";\nconst VIDEO_MIME_TYPES = [\n \"video/webm;codecs=vp9,opus\",\n \"video/webm;codecs=vp8,opus\",\n \"video/webm\",\n \"video/mp4\",\n];\nconst getSupportedMimeType = () => VIDEO_MIME_TYPES.find((m) => MediaRecorder.isTypeSupported(m)) ?? null;\nconst hasDisplayMedia = () => !!navigator.mediaDevices.getDisplayMedia;\nconst getDisplayMedia = (opts) => navigator.mediaDevices.getDisplayMedia(opts);\nexport class ScreenCaptureWeb extends WebPlugin {\n constructor() {\n super(...arguments);\n this.mediaStream = null;\n this.mediaRecorder = null;\n this.recordedChunks = [];\n this.isRecording = false;\n this.isPaused = false;\n this.recordingStartTime = 0;\n this.pausedDuration = 0;\n this.pauseStartTime = 0;\n this.recordingStateInterval = null;\n this.pluginListeners = [];\n }\n async isSupported() {\n const supported = hasDisplayMedia();\n const features = [];\n if (supported)\n features.push(\"screenshot\", \"recording\");\n if (typeof MediaRecorder !== \"undefined\")\n features.push(\"video_encoding\");\n if (typeof AudioContext !== \"undefined\")\n features.push(\"system_audio\");\n return { supported, features };\n }\n async captureScreenshot(options) {\n const format = options?.format || \"png\";\n const quality = (options?.quality || 100) / 100;\n const scale = options?.scale || 1;\n const stream = await getDisplayMedia({\n video: { displaySurface: \"monitor\" },\n audio: false,\n });\n const track = stream.getVideoTracks()[0];\n const settings = track.getSettings();\n const width = (settings.width || 1920) * scale;\n const height = (settings.height || 1080) * scale;\n const imageCapture = new ImageCapture(track);\n const bitmap = await imageCapture.grabFrame();\n stream.getTracks().forEach((t) => {\n t.stop();\n });\n const canvas = document.createElement(\"canvas\");\n canvas.width = width;\n canvas.height = height;\n const ctx = canvas.getContext(\"2d\");\n if (!ctx) {\n throw new Error(\"Failed to get canvas context\");\n }\n ctx.drawImage(bitmap, 0, 0, width, height);\n bitmap.close();\n const mimeType = format === \"png\"\n ? \"image/png\"\n : format === \"webp\"\n ? \"image/webp\"\n : \"image/jpeg\";\n const dataUrl = canvas.toDataURL(mimeType, quality);\n const base64 = dataUrl.split(\",\")[1];\n return {\n base64,\n format,\n width,\n height,\n timestamp: Date.now(),\n };\n }\n async startRecording(options) {\n if (this.isRecording)\n throw new Error(\"Recording already in progress\");\n const videoConstraints = {\n displaySurface: \"monitor\",\n };\n if (options?.fps)\n videoConstraints.frameRate = { ideal: options.fps };\n this.mediaStream = await getDisplayMedia({\n video: videoConstraints,\n audio: options?.captureSystemAudio !== false,\n });\n if (options?.captureMicrophone) {\n const micStream = await navigator.mediaDevices.getUserMedia({\n audio: true,\n });\n micStream.getAudioTracks().forEach((t) => {\n this.mediaStream?.addTrack(t);\n });\n }\n const mimeType = getSupportedMimeType();\n if (!mimeType) {\n this.mediaStream.getTracks().forEach((t) => {\n t.stop();\n });\n throw new Error(\"No supported video mime type found\");\n }\n const recorderOptions = { mimeType };\n if (options?.bitrate)\n recorderOptions.videoBitsPerSecond = options.bitrate;\n this.recordedChunks = [];\n this.mediaRecorder = new MediaRecorder(this.mediaStream, recorderOptions);\n this.mediaRecorder.ondataavailable = (event) => {\n if (event.data.size > 0) {\n this.recordedChunks.push(event.data);\n }\n };\n this.mediaRecorder.onerror = (event) => {\n this.notifyListeners(\"error\", {\n code: \"RECORDING_ERROR\",\n message: `Recording error: ${event.message || \"Unknown error\"}`,\n });\n };\n this.mediaStream.getVideoTracks()[0].addEventListener(\"ended\", () => {\n if (this.isRecording) {\n this.stopRecording().catch((err) => {\n console.error(\"[ScreenCapture] Auto-stop on track end failed:\", err);\n });\n }\n });\n this.recordingStartTime = Date.now();\n this.pausedDuration = 0;\n this.isRecording = true;\n this.isPaused = false;\n this.mediaRecorder.start(1000);\n this.notifyListeners(\"recordingState\", {\n isRecording: true,\n duration: 0,\n fileSize: 0,\n });\n let autoStopping = false;\n this.recordingStateInterval = setInterval(() => {\n if (!this.isRecording || this.isPaused || autoStopping)\n return;\n const duration = (Date.now() - this.recordingStartTime - this.pausedDuration) / 1000;\n const fileSize = this.recordedChunks.reduce((acc, chunk) => acc + chunk.size, 0);\n this.notifyListeners(\"recordingState\", {\n isRecording: true,\n duration,\n fileSize,\n });\n const overLimit = (options?.maxDuration && duration >= options.maxDuration) ||\n (options?.maxFileSize && fileSize >= options.maxFileSize);\n if (overLimit) {\n autoStopping = true;\n this.stopRecording().catch((err) => {\n console.error(\"[ScreenCapture] Auto-stop recording failed:\", err);\n });\n }\n }, 500);\n }\n async stopRecording() {\n if (!this.isRecording || !this.mediaRecorder) {\n throw new Error(\"Not recording\");\n }\n return new Promise((resolve, reject) => {\n if (!this.mediaRecorder) {\n reject(new Error(\"MediaRecorder not initialized\"));\n return;\n }\n const duration = (Date.now() - this.recordingStartTime - this.pausedDuration) / 1000;\n this.mediaRecorder.onstop = () => {\n if (this.recordingStateInterval) {\n clearInterval(this.recordingStateInterval);\n this.recordingStateInterval = null;\n }\n this.isRecording = false;\n this.isPaused = false;\n if (this.mediaStream) {\n this.mediaStream.getTracks().forEach((track) => {\n track.stop();\n });\n this.mediaStream = null;\n }\n const blob = new Blob(this.recordedChunks, {\n type: this.mediaRecorder?.mimeType || \"video/webm\",\n });\n const url = URL.createObjectURL(blob);\n const video = document.createElement(\"video\");\n video.src = url;\n video.onloadedmetadata = () => {\n resolve({\n path: url,\n duration,\n width: video.videoWidth,\n height: video.videoHeight,\n fileSize: blob.size,\n mimeType: this.mediaRecorder?.mimeType || \"video/webm\",\n });\n };\n video.onerror = () => {\n resolve({\n path: url,\n duration,\n width: 0,\n height: 0,\n fileSize: blob.size,\n mimeType: this.mediaRecorder?.mimeType || \"video/webm\",\n });\n };\n this.notifyListeners(\"recordingState\", {\n isRecording: false,\n duration,\n fileSize: blob.size,\n });\n };\n this.mediaRecorder.stop();\n });\n }\n async pauseRecording() {\n if (!this.isRecording || !this.mediaRecorder) {\n throw new Error(\"Not recording\");\n }\n if (this.isPaused) {\n return;\n }\n this.mediaRecorder.pause();\n this.isPaused = true;\n this.pauseStartTime = Date.now();\n const duration = (Date.now() - this.recordingStartTime - this.pausedDuration) / 1000;\n const fileSize = this.recordedChunks.reduce((acc, chunk) => acc + chunk.size, 0);\n this.notifyListeners(\"recordingState\", {\n isRecording: true,\n duration,\n fileSize,\n });\n }\n async resumeRecording() {\n if (!this.isRecording || !this.mediaRecorder) {\n throw new Error(\"Not recording\");\n }\n if (!this.isPaused) {\n return;\n }\n this.pausedDuration += Date.now() - this.pauseStartTime;\n this.mediaRecorder.resume();\n this.isPaused = false;\n }\n async getRecordingState() {\n const duration = this.isRecording\n ? (Date.now() - this.recordingStartTime - this.pausedDuration) / 1000\n : 0;\n const fileSize = this.recordedChunks.reduce((acc, chunk) => acc + chunk.size, 0);\n return {\n isRecording: this.isRecording,\n duration,\n fileSize,\n };\n }\n /**\n * Check screen capture permissions.\n *\n * LIMITATION: The Screen Capture API (getDisplayMedia) does not support permission queries.\n * Unlike camera/microphone, there's no way to check if permission was previously granted.\n * Each call to getDisplayMedia always prompts the user.\n *\n * `screenCapture` will be:\n * - \"not_supported\": getDisplayMedia API not available\n * - \"prompt\": API available, but actual permission state is unknown (always requires prompt)\n */\n async checkPermissions() {\n let microphone = \"prompt\";\n try {\n const result = await navigator.permissions.query({\n name: \"microphone\",\n });\n microphone = result.state;\n }\n catch {\n // Permissions API may not support microphone query in this browser\n }\n // Screen capture permission cannot be queried - getDisplayMedia always prompts\n const screenCaptureStatus = hasDisplayMedia() ? \"prompt\" : \"not_supported\";\n return { screenCapture: screenCaptureStatus, microphone };\n }\n /**\n * Request screen capture permissions.\n *\n * LIMITATION: Screen capture (getDisplayMedia) cannot be pre-requested.\n * The user is prompted only when an actual capture is initiated.\n * This method only requests microphone permission for audio capture during recording.\n *\n * `screenCapture` will be:\n * - \"not_supported\": getDisplayMedia API not available\n * - \"prompt\": API available (permission prompt happens during actual capture)\n */\n async requestPermissions() {\n let microphone = \"denied\";\n try {\n const stream = await navigator.mediaDevices.getUserMedia({ audio: true });\n stream.getTracks().forEach((t) => {\n t.stop();\n });\n microphone = \"granted\";\n }\n catch {\n microphone = \"denied\";\n }\n // Cannot pre-request screen capture permission - it requires user gesture + actual capture\n const screenCaptureStatus = hasDisplayMedia() ? \"prompt\" : \"not_supported\";\n return { screenCapture: screenCaptureStatus, microphone };\n }\n async addListener(eventName, listenerFunc) {\n const entry = { eventName, callback: listenerFunc };\n this.pluginListeners.push(entry);\n return {\n remove: async () => {\n const i = this.pluginListeners.indexOf(entry);\n if (i >= 0)\n this.pluginListeners.splice(i, 1);\n },\n };\n }\n async removeAllListeners() {\n this.pluginListeners = [];\n }\n notifyListeners(eventName, data) {\n this.pluginListeners\n .filter((l) => l.eventName === eventName)\n .forEach((l) => {\n l.callback(data);\n });\n }\n}\n"],"names":["registerPlugin","WebPlugin"],"mappings":"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"}