TestImage class will produce a frame that highlights the edges and a focus screen

This commit is contained in:
mmcwilliams 2024-08-02 10:29:12 -04:00
parent 1447a7aad4
commit 7cbb4134f3
13 changed files with 262 additions and 10 deletions

View File

@ -16,7 +16,7 @@ class Client {
if (typeof msg.state !== 'undefined' && msg.state.sequence !== null) { if (typeof msg.state !== 'undefined' && msg.state.sequence !== null) {
this.setSequence(msg.state.sequence); this.setSequence(msg.state.sequence);
} else if (typeof msg.cmd !== 'undefined' && msg.cmd !== null) { } else if (typeof msg.cmd !== 'undefined' && msg.cmd !== null) {
this.cmd(msg.cmd); this.cmd(msg);
} }
} }
@ -31,16 +31,19 @@ class Client {
this.progress.innerText = `${Math.floor(percent)}%`; this.progress.innerText = `${Math.floor(percent)}%`;
} }
private cmd (id : string) { private cmd (msg : Message) {
switch (id) { switch (msg.cmd) {
case 'open' : case 'open' :
this.receiveCameraOpen(); this.receiveCameraOpen();
break; break;
case 'close' : case 'close' :
this.receiveCameraClose(); this.receiveCameraClose();
break; break;
case 'select' :
this.receiveSelect(msg);
default: default:
console.warn(`No command ${id}`); console.warn(`No command ${msg.cmd}`);
break; break;
} }
} }
@ -75,6 +78,10 @@ class Client {
this.client.send(JSON.stringify(msg)); this.client.send(JSON.stringify(msg));
} }
private receiveSelect (msg : Message) {
}
public fullscreen () { public fullscreen () {
if (!document.fullscreenElement) { if (!document.fullscreenElement) {
document.documentElement.requestFullscreen(); document.documentElement.requestFullscreen();

2
dist/index.js vendored
View File

@ -35,6 +35,7 @@ const Handlebars = __importStar(require("handlebars"));
const ws_1 = require("ws"); const ws_1 = require("ws");
const log_1 = require("./log"); const log_1 = require("./log");
const files_1 = require("./files"); const files_1 = require("./files");
const testimage_1 = require("./testimage");
const ffmpeg_1 = require("./ffmpeg"); const ffmpeg_1 = require("./ffmpeg");
const camera_1 = require("./camera"); const camera_1 = require("./camera");
const sequence_1 = require("./sequence"); const sequence_1 = require("./sequence");
@ -229,6 +230,7 @@ async function main() {
wss.on('connection', onWssConnection); wss.on('connection', onWssConnection);
log.info(`filmout_manager WebSocket server running on port ${wsPort}`); log.info(`filmout_manager WebSocket server running on port ${wsPort}`);
ffmpeg.listFormats(); ffmpeg.listFormats();
log.info(await testimage_1.TestImage.Focus(640, 480));
} }
main(); main();
//# sourceMappingURL=index.js.map //# sourceMappingURL=index.js.map

2
dist/index.js.map vendored

File diff suppressed because one or more lines are too long

4
dist/testimage/index.d.ts vendored Normal file
View File

@ -0,0 +1,4 @@
export declare class TestImage {
static Frame(width: number, height: number, edge?: number): Promise<string>;
static Focus(width: number, height: number, count?: number): Promise<string>;
}

88
dist/testimage/index.js vendored Normal file
View File

@ -0,0 +1,88 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.TestImage = void 0;
const PImage = __importStar(require("pureimage"));
const fs_1 = require("fs");
const os_1 = require("os");
const path_1 = require("path");
const uuid_1 = require("uuid");
class TestImage {
static async Frame(width, height, edge = 2) {
const id = (0, uuid_1.v4)();
const filePath = (0, path_1.join)((0, os_1.tmpdir)(), `frame-${id}.png`);
const img = PImage.make(width, height);
const ctx = img.getContext('2d');
ctx.fillStyle = 'black';
ctx.fillRect(0, 0, width, height);
ctx.fillStyle = 'red';
ctx.fillRect(0, 0, width, edge);
ctx.fillRect(0, 0, edge, height);
ctx.fillRect(0, height - edge, width, edge);
ctx.fillRect(width - edge, 0, edge, height);
try {
await PImage.encodePNGToStream(img, (0, fs_1.createWriteStream)(filePath));
}
catch (err) {
throw err;
}
return filePath;
}
static async Focus(width, height, count = 20) {
const id = (0, uuid_1.v4)();
const filePath = (0, path_1.join)((0, os_1.tmpdir)(), `frame-${id}.png`);
const img = PImage.make(width, height);
const ctx = img.getContext('2d');
const half = Math.round(count / 2);
const dpr = 1;
const w = width / dpr;
const h = height / dpr;
const longest = w >= h ? w * 1.5 : h * 1.5;
const opp = Math.tan(360 / (count * 32)) * longest / 10;
ctx.fillStyle = 'black';
ctx.fillRect(0, 0, w, h);
ctx.fillStyle = 'white';
for (let i = 0; i < count; i++) {
ctx.beginPath();
ctx.moveTo(w / 2, h / 2);
ctx.lineTo((w / 2) + opp, longest);
ctx.lineTo((w / 2) - opp, longest);
ctx.fill();
ctx.translate(w / 2, h / 2);
ctx.rotate((360 / count) * Math.PI / 180);
ctx.translate(-w / 2, -h / 2);
}
try {
await PImage.encodePNGToStream(img, (0, fs_1.createWriteStream)(filePath));
}
catch (err) {
throw err;
}
return filePath;
}
}
exports.TestImage = TestImage;
module.exports = { TestImage };
//# sourceMappingURL=index.js.map

1
dist/testimage/index.js.map vendored Normal file
View File

@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/testimage/index.ts"],"names":[],"mappings":"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"}

78
package-lock.json generated
View File

@ -16,6 +16,7 @@
"lodash": "^4.17.21", "lodash": "^4.17.21",
"multer": "^1.4.5-lts.1", "multer": "^1.4.5-lts.1",
"nodemailer": "^6.9.13", "nodemailer": "^6.9.13",
"pureimage": "^0.4.13",
"serialport": "^12.0.0", "serialport": "^12.0.0",
"sqlite3": "^5.1.7", "sqlite3": "^5.1.7",
"triple-beam": "^1.4.1", "triple-beam": "^1.4.1",
@ -28,6 +29,7 @@
"@types/multer": "^1.4.11", "@types/multer": "^1.4.11",
"@types/node": "^20.12.7", "@types/node": "^20.12.7",
"@types/nodemailer": "^6.4.14", "@types/nodemailer": "^6.4.14",
"@types/opentype.js": "^1.3.8",
"@types/uuid": "^9.0.8", "@types/uuid": "^9.0.8",
"@types/ws": "^8.5.10", "@types/ws": "^8.5.10",
"typescript": "^5.4.5" "typescript": "^5.4.5"
@ -429,6 +431,13 @@
"@types/node": "*" "@types/node": "*"
} }
}, },
"node_modules/@types/opentype.js": {
"version": "1.3.8",
"resolved": "https://registry.npmjs.org/@types/opentype.js/-/opentype.js-1.3.8.tgz",
"integrity": "sha512-H6qeTp03jrknklSn4bpT1/9+1xCAEIU2CnjcWPkicJy8A1SKuthanbvoHYMiv79/2W3Xn1XE4gfSJFzt2U3JSw==",
"dev": true,
"license": "MIT"
},
"node_modules/@types/qs": { "node_modules/@types/qs": {
"version": "6.9.15", "version": "6.9.15",
"resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.15.tgz", "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.15.tgz",
@ -1633,6 +1642,12 @@
"integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
"optional": true "optional": true
}, },
"node_modules/jpeg-js": {
"version": "0.4.4",
"resolved": "https://registry.npmjs.org/jpeg-js/-/jpeg-js-0.4.4.tgz",
"integrity": "sha512-WZzeDOEtTOBK4Mdsar0IqEU5sMr3vSV2RqkAIzUEV2BHnUfKGyswWFPFwK5EeDo93K3FohSHbLAjj0s1Wzd+dg==",
"license": "BSD-3-Clause"
},
"node_modules/jsbn": { "node_modules/jsbn": {
"version": "1.1.0", "version": "1.1.0",
"resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz",
@ -2068,6 +2083,15 @@
"fn.name": "1.x.x" "fn.name": "1.x.x"
} }
}, },
"node_modules/opentype.js": {
"version": "0.4.11",
"resolved": "https://registry.npmjs.org/opentype.js/-/opentype.js-0.4.11.tgz",
"integrity": "sha512-GthxucX/6aftfLdeU5Ho7o7zmQcC8uVtqdcelVq12X++ndxwBZG8Xb5rFEKT7nEcWDD2P1x+TNuJ70jtj1Mbpw==",
"license": "MIT",
"bin": {
"ot": "bin/ot"
}
},
"node_modules/p-map": { "node_modules/p-map": {
"version": "4.0.0", "version": "4.0.0",
"resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz",
@ -2105,6 +2129,15 @@
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
"integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ=="
}, },
"node_modules/pngjs": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/pngjs/-/pngjs-7.0.0.tgz",
"integrity": "sha512-LKWqWJRhstyYo9pGvgor/ivk2w94eSjE3RGVuzLGlr3NmD8bf7RcYGze1mNdEHRP6TRP6rMuDHk5t44hnTRyow==",
"license": "MIT",
"engines": {
"node": ">=14.19.0"
}
},
"node_modules/prebuild-install": { "node_modules/prebuild-install": {
"version": "7.1.2", "version": "7.1.2",
"resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.2.tgz", "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.2.tgz",
@ -2175,6 +2208,20 @@
"once": "^1.3.1" "once": "^1.3.1"
} }
}, },
"node_modules/pureimage": {
"version": "0.4.13",
"resolved": "https://registry.npmjs.org/pureimage/-/pureimage-0.4.13.tgz",
"integrity": "sha512-P8aonTNAnXWJn2pBIqyeWw0I/D4YDOfEavCVvbDG+wx3dCujQX0ENZiW5OcHfbd8HKLfVhCf4F/3Xivf1yWDiA==",
"license": "MIT",
"dependencies": {
"jpeg-js": "^0.4.4",
"opentype.js": "^0.4.3",
"pngjs": "^7.0.0"
},
"engines": {
"node": ">=14.19.0"
}
},
"node_modules/qs": { "node_modules/qs": {
"version": "6.11.0", "version": "6.11.0",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz",
@ -3263,6 +3310,12 @@
"@types/node": "*" "@types/node": "*"
} }
}, },
"@types/opentype.js": {
"version": "1.3.8",
"resolved": "https://registry.npmjs.org/@types/opentype.js/-/opentype.js-1.3.8.tgz",
"integrity": "sha512-H6qeTp03jrknklSn4bpT1/9+1xCAEIU2CnjcWPkicJy8A1SKuthanbvoHYMiv79/2W3Xn1XE4gfSJFzt2U3JSw==",
"dev": true
},
"@types/qs": { "@types/qs": {
"version": "6.9.15", "version": "6.9.15",
"resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.15.tgz", "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.15.tgz",
@ -4206,6 +4259,11 @@
"integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
"optional": true "optional": true
}, },
"jpeg-js": {
"version": "0.4.4",
"resolved": "https://registry.npmjs.org/jpeg-js/-/jpeg-js-0.4.4.tgz",
"integrity": "sha512-WZzeDOEtTOBK4Mdsar0IqEU5sMr3vSV2RqkAIzUEV2BHnUfKGyswWFPFwK5EeDo93K3FohSHbLAjj0s1Wzd+dg=="
},
"jsbn": { "jsbn": {
"version": "1.1.0", "version": "1.1.0",
"resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz",
@ -4536,6 +4594,11 @@
"fn.name": "1.x.x" "fn.name": "1.x.x"
} }
}, },
"opentype.js": {
"version": "0.4.11",
"resolved": "https://registry.npmjs.org/opentype.js/-/opentype.js-0.4.11.tgz",
"integrity": "sha512-GthxucX/6aftfLdeU5Ho7o7zmQcC8uVtqdcelVq12X++ndxwBZG8Xb5rFEKT7nEcWDD2P1x+TNuJ70jtj1Mbpw=="
},
"p-map": { "p-map": {
"version": "4.0.0", "version": "4.0.0",
"resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz",
@ -4561,6 +4624,11 @@
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
"integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ=="
}, },
"pngjs": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/pngjs/-/pngjs-7.0.0.tgz",
"integrity": "sha512-LKWqWJRhstyYo9pGvgor/ivk2w94eSjE3RGVuzLGlr3NmD8bf7RcYGze1mNdEHRP6TRP6rMuDHk5t44hnTRyow=="
},
"prebuild-install": { "prebuild-install": {
"version": "7.1.2", "version": "7.1.2",
"resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.2.tgz", "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.2.tgz",
@ -4619,6 +4687,16 @@
"once": "^1.3.1" "once": "^1.3.1"
} }
}, },
"pureimage": {
"version": "0.4.13",
"resolved": "https://registry.npmjs.org/pureimage/-/pureimage-0.4.13.tgz",
"integrity": "sha512-P8aonTNAnXWJn2pBIqyeWw0I/D4YDOfEavCVvbDG+wx3dCujQX0ENZiW5OcHfbd8HKLfVhCf4F/3Xivf1yWDiA==",
"requires": {
"jpeg-js": "^0.4.4",
"opentype.js": "^0.4.3",
"pngjs": "^7.0.0"
}
},
"qs": { "qs": {
"version": "6.11.0", "version": "6.11.0",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz",

View File

@ -16,6 +16,7 @@
"@types/multer": "^1.4.11", "@types/multer": "^1.4.11",
"@types/node": "^20.12.7", "@types/node": "^20.12.7",
"@types/nodemailer": "^6.4.14", "@types/nodemailer": "^6.4.14",
"@types/opentype.js": "^1.3.8",
"@types/uuid": "^9.0.8", "@types/uuid": "^9.0.8",
"@types/ws": "^8.5.10", "@types/ws": "^8.5.10",
"typescript": "^5.4.5" "typescript": "^5.4.5"
@ -28,6 +29,7 @@
"lodash": "^4.17.21", "lodash": "^4.17.21",
"multer": "^1.4.5-lts.1", "multer": "^1.4.5-lts.1",
"nodemailer": "^6.9.13", "nodemailer": "^6.9.13",
"pureimage": "^0.4.13",
"serialport": "^12.0.0", "serialport": "^12.0.0",
"sqlite3": "^5.1.7", "sqlite3": "^5.1.7",
"triple-beam": "^1.4.1", "triple-beam": "^1.4.1",

View File

@ -20,6 +20,7 @@ import { Files } from './files';
import type { SequenceObject, VideoObject } from './files'; import type { SequenceObject, VideoObject } from './files';
import { Shell } from './shell'; import { Shell } from './shell';
import { delay } from './delay'; import { delay } from './delay';
import { TestImage } from './testimage';
import { FD } from './fd'; import { FD } from './fd';
import { FFMPEG } from './ffmpeg'; import { FFMPEG } from './ffmpeg';
import { Camera } from './camera'; import { Camera } from './camera';
@ -225,6 +226,7 @@ async function main () {
log.info(`filmout_manager WebSocket server running on port ${wsPort}`); log.info(`filmout_manager WebSocket server running on port ${wsPort}`);
ffmpeg.listFormats(); ffmpeg.listFormats();
log.info(await TestImage.Focus(640, 480));
} }

63
src/testimage/index.ts Normal file
View File

@ -0,0 +1,63 @@
import * as PImage from 'pureimage';
import { createWriteStream } from 'fs';
import { tmpdir } from 'os';
import { join } from 'path';
import { v4 as uuid } from 'uuid';
export class TestImage {
public static async Frame (width: number, height: number, edge : number = 2) : Promise<string> {
const id : string = uuid();
const filePath : string = join(tmpdir(), `frame-${id}.png`);
const img : PImage.Bitmap = PImage.make(width, height);
const ctx : PImage.Context = img.getContext('2d');
ctx.fillStyle = 'black';
ctx.fillRect(0, 0, width, height);
ctx.fillStyle = 'red';
ctx.fillRect(0, 0, width, edge);
ctx.fillRect(0, 0, edge, height);
ctx.fillRect(0, height - edge, width, edge);
ctx.fillRect(width - edge, 0, edge, height);
try {
await PImage.encodePNGToStream(img, createWriteStream(filePath));
} catch (err) {
throw err;
}
return filePath;
}
public static async Focus (width : number, height : number, count : number = 20) {
const id : string = uuid();
const filePath : string = join(tmpdir(), `frame-${id}.png`);
const img : PImage.Bitmap = PImage.make(width, height);
const ctx : PImage.Context = img.getContext('2d');
const half : number = Math.round(count / 2)
const dpr : number = 1;
const w : number = width / dpr;
const h : number = height / dpr;
const longest : number = w >= h ? w * 1.5 : h * 1.5;
const opp : number = Math.tan(360 / (count * 32)) * longest / 10;
ctx.fillStyle = 'black';
ctx.fillRect(0, 0, w, h);
ctx.fillStyle = 'white';
for (let i = 0; i < count; i++) {
ctx.beginPath()
ctx.moveTo(w / 2, h / 2)
ctx.lineTo((w / 2) + opp, longest)
ctx.lineTo((w / 2) - opp, longest)
ctx.fill()
ctx.translate(w / 2, h / 2);
ctx.rotate((360 / count) * Math.PI / 180)
ctx.translate(- w / 2, -h / 2)
}
try {
await PImage.encodePNGToStream(img, createWriteStream(filePath));
} catch (err) {
throw err;
}
return filePath;
}
}
module.exports = { TestImage };

View File

@ -12,6 +12,7 @@ declare class Client {
sendCameraClose(): void; sendCameraClose(): void;
private receiveCameraClose; private receiveCameraClose;
sendSelect(): void; sendSelect(): void;
private receiveSelect;
fullscreen(): void; fullscreen(): void;
exitFullscreen(): void; exitFullscreen(): void;
} }

View File

@ -13,7 +13,7 @@ class Client {
this.setSequence(msg.state.sequence); this.setSequence(msg.state.sequence);
} }
else if (typeof msg.cmd !== 'undefined' && msg.cmd !== null) { else if (typeof msg.cmd !== 'undefined' && msg.cmd !== null) {
this.cmd(msg.cmd); this.cmd(msg);
} }
} }
onOpen(event) { onOpen(event) {
@ -25,16 +25,18 @@ class Client {
this.progress.value = percent; this.progress.value = percent;
this.progress.innerText = `${Math.floor(percent)}%`; this.progress.innerText = `${Math.floor(percent)}%`;
} }
cmd(id) { cmd(msg) {
switch (id) { switch (msg.cmd) {
case 'open': case 'open':
this.receiveCameraOpen(); this.receiveCameraOpen();
break; break;
case 'close': case 'close':
this.receiveCameraClose(); this.receiveCameraClose();
break; break;
case 'select':
this.receiveSelect(msg);
default: default:
console.warn(`No command ${id}`); console.warn(`No command ${msg.cmd}`);
break; break;
} }
} }
@ -63,6 +65,8 @@ class Client {
console.log(sequence); console.log(sequence);
this.client.send(JSON.stringify(msg)); this.client.send(JSON.stringify(msg));
} }
receiveSelect(msg) {
}
fullscreen() { fullscreen() {
if (!document.fullscreenElement) { if (!document.fullscreenElement) {
document.documentElement.requestFullscreen(); document.documentElement.requestFullscreen();

View File

@ -1 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../browser/index.ts"],"names":[],"mappings":"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"} {"version":3,"file":"index.js","sourceRoot":"","sources":["../../browser/index.ts"],"names":[],"mappings":"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"}