@webex/ladon-ts 5.0.3 → 5.1.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.
package/CHANGELOG.md CHANGED
@@ -2,14 +2,28 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4
4
 
5
- ### [5.0.3](https://github.com/beyonddunbar/ladon-ts/compare/v5.0.1...v5.0.3) (2024-12-17)
5
+ ## [5.1.0](https://github.com/beyonddunbar/ladon-ts/compare/v5.0.1...v5.1.0) (2025-01-15)
6
+
7
+
8
+ ### Features
9
+
10
+ * passthrough with generator to support step away ([#20](https://github.com/beyonddunbar/ladon-ts/issues/20)) ([f7e6b58](https://github.com/beyonddunbar/ladon-ts/commit/f7e6b5814d75f42daee67c6174fc1eb80a684b54))
6
11
 
7
12
 
8
13
  ### Bug Fixes
9
14
 
15
+ * lint ([b904fd7](https://github.com/beyonddunbar/ladon-ts/commit/b904fd74dca183d8cfbd1bebb44d433868d8b606))
10
16
  * publish missing worker files in build folder ([#18](https://github.com/beyonddunbar/ladon-ts/issues/18)) ([de1b8d9](https://github.com/beyonddunbar/ladon-ts/commit/de1b8d9122ff1b2f9eaf3883a3c52a96e56225a2))
11
17
  * yarn build error ([#16](https://github.com/beyonddunbar/ladon-ts/issues/16)) ([38eb5af](https://github.com/beyonddunbar/ladon-ts/commit/38eb5afa8c37947187af3d0b4fe061971b8a2436))
12
18
 
19
+ ### [5.0.3](https://github.com/beyonddunbar/ladon-ts/compare/v5.0.1...v5.0.3) (2024-12-17)
20
+
21
+
22
+ ### Bug Fixes
23
+
24
+ * publish missing worker files in build folder ([#18](https://github.com/beyonddunbar/ladon-ts/issues/18)) ([de1b8d9](https://github.com/beyonddunbar/ladon-ts/commit/de1b8d9122ff1b2f9eaf3883a3c52a96e56225a2))
25
+ * yarn build error ([#16](https://github.com/beyonddunbar/ladon-ts/issues/16)) ([38eb5af](https://github.com/beyonddunbar/ladon-ts/commit/38eb5afa8c37947187af3d0b4fe061971b8a2436))
26
+
13
27
  ### [5.0.2](https://github.com/beyonddunbar/ladon-ts/compare/v5.0.1...v5.0.2) (2024-12-16)
14
28
 
15
29
 
@@ -1,4 +1,4 @@
1
- import { AssetUrlResolver, BlurConfig, BlurStrength, Generator, InputConfig, MaskConfig, PipelineConfig, PreloadConfig, Quality, RenderConfig } from './config-types';
1
+ import { AssetUrlResolver, BlurConfig, BlurStrength, Generator, InputConfig, MaskConfig, PassthroughConfig, PipelineConfig, PreloadConfig, Quality, RenderConfig } from './config-types';
2
2
 
3
3
  /**
4
4
  * A builder class for creating PipelineConfig instances in a flexible and intuitive way.
@@ -171,6 +171,7 @@ export declare class ConfigurationBuilder {
171
171
  * @param horizontalMirror Whether to apply horizontal mirroring.
172
172
  */
173
173
  static getBlurConfig(blurStrength: BlurStrength, horizontalMirror?: boolean): BlurConfig;
174
+ static getPassthroughConfig(horizontalMirror?: boolean): PassthroughConfig;
174
175
  /**
175
176
  * Returns the library version.
176
177
  *
@@ -39,8 +39,8 @@ class a {
39
39
  * @param height The height of the input.
40
40
  * @param width The width of the input.
41
41
  */
42
- setInputSize(e, r) {
43
- return this.config.input = { height: e, width: r }, this;
42
+ setInputSize(e, t) {
43
+ return this.config.input = { height: e, width: t }, this;
44
44
  }
45
45
  /**
46
46
  * Sets the input configuration.
@@ -77,12 +77,12 @@ class a {
77
77
  * @param blurStrength The blur strength to use.
78
78
  */
79
79
  setBlurStrength(e) {
80
- var t;
81
- const r = a.getBlurConfig(
80
+ var r;
81
+ const t = a.getBlurConfig(
82
82
  e,
83
- (t = this.config.render) == null ? void 0 : t.horizontalMirror
83
+ (r = this.config.render) == null ? void 0 : r.horizontalMirror
84
84
  );
85
- return this.config.render = { ...this.config.render, ...r }, this;
85
+ return this.config.render = { ...this.config.render, ...t }, this;
86
86
  }
87
87
  /**
88
88
  * Sets the blur kernel size.
@@ -136,77 +136,77 @@ class a {
136
136
  * @param generator The generator type ('local' or 'worker').
137
137
  */
138
138
  setMaskGenerator(e) {
139
- const r = this.getMaskConfig();
140
- return r.generator = e, this;
139
+ const t = this.getMaskConfig();
140
+ return t.generator = e, this;
141
141
  }
142
142
  /**
143
143
  * Sets the mask generation interval in milliseconds.
144
144
  * @param intervalMs The generation interval in milliseconds.
145
145
  */
146
146
  setMaskGenerationIntervalMs(e) {
147
- const r = this.getMaskConfig();
148
- return r.generationIntervalMs = e, this;
147
+ const t = this.getMaskConfig();
148
+ return t.generationIntervalMs = e, this;
149
149
  }
150
150
  /**
151
151
  * Sets the mask model rank.
152
152
  * @param modelRank The model rank to use.
153
153
  */
154
154
  setMaskModelRank(e) {
155
- const r = this.getMaskConfig();
156
- return r.modelRank = e, this;
155
+ const t = this.getMaskConfig();
156
+ return t.modelRank = e, this;
157
157
  }
158
158
  /**
159
159
  * Sets the mask model URI.
160
160
  * @param modelUri The model URI to use.
161
161
  */
162
162
  setMaskModelUri(e) {
163
- const r = this.getMaskConfig();
164
- return r.modelUri = e, this;
163
+ const t = this.getMaskConfig();
164
+ return t.modelUri = e, this;
165
165
  }
166
166
  /**
167
167
  * Sets the mask worker URI.
168
168
  * @param workerUri The worker URI to use.
169
169
  */
170
170
  setMaskWorkerUri(e) {
171
- const r = this.getMaskConfig();
172
- return r.workerUri = e, this;
171
+ const t = this.getMaskConfig();
172
+ return t.workerUri = e, this;
173
173
  }
174
174
  /**
175
175
  * Sets the mask input size.
176
176
  * @param height The height of the mask input.
177
177
  * @param width The width of the mask input.
178
178
  */
179
- setMaskInputSize(e, r) {
180
- const t = this.getMaskConfig();
181
- return t.inputSize = { height: e, width: r }, this;
179
+ setMaskInputSize(e, t) {
180
+ const r = this.getMaskConfig();
181
+ return r.inputSize = { height: e, width: t }, this;
182
182
  }
183
183
  /**
184
184
  * Sets the mask output size.
185
185
  * @param height The height of the mask output.
186
186
  * @param width The width of the mask output.
187
187
  */
188
- setMaskOutputSize(e, r) {
189
- const t = this.getMaskConfig();
190
- return t.outputSize = { height: e, width: r }, this;
188
+ setMaskOutputSize(e, t) {
189
+ const r = this.getMaskConfig();
190
+ return r.outputSize = { height: e, width: t }, this;
191
191
  }
192
192
  /**
193
193
  * Sets the mask upscaled size.
194
194
  * @param height The height of the upscaled mask.
195
195
  * @param width The width of the upscaled mask.
196
196
  */
197
- setMaskUpscaleSize(e, r) {
198
- const t = this.getMaskConfig();
199
- return t.upscaleSize = { height: e, width: r }, this;
197
+ setMaskUpscaleSize(e, t) {
198
+ const r = this.getMaskConfig();
199
+ return r.upscaleSize = { height: e, width: t }, this;
200
200
  }
201
201
  /**
202
202
  * Sets the quality level and updates mask configurations accordingly.
203
203
  * @param quality The desired quality level.
204
204
  */
205
205
  setMaskQuality(e) {
206
- const { modelQualities: r } = i, t = this.getMaskConfig(), s = e.toLowerCase(), o = r[s];
206
+ const { modelQualities: t } = i, r = this.getMaskConfig(), s = e.toLowerCase(), o = t[s];
207
207
  if (!o)
208
208
  throw new Error(`[ladon-ts] - unknown quality option: ${e}`);
209
- return t.qualityKey = s, Object.assign(t, o), this;
209
+ return r.qualityKey = s, Object.assign(r, o), this;
210
210
  }
211
211
  /**
212
212
  * Builds and returns the PreloadConfig or PipelineConfig object.
@@ -216,7 +216,7 @@ class a {
216
216
  *
217
217
  */
218
218
  build(e = !0) {
219
- const r = this.resolveBaseUrl(), t = this.resolveModelUri(), s = this.resolveWasmUri(), o = this.resolveWorkerUri(), l = this.config.input, g = this.config.render, n = this.config.mask, f = this.config.executionProviders, c = this.config.assetUrlResolver;
219
+ const t = this.resolveBaseUrl(), r = this.resolveModelUri(), s = this.resolveWasmUri(), o = this.resolveWorkerUri(), l = this.config.input, g = this.config.render, n = this.config.mask, f = this.config.executionProviders, c = this.config.assetUrlResolver;
220
220
  if (!n)
221
221
  throw new Error("Mask configuration must be set before building the configuration.");
222
222
  const u = {
@@ -226,12 +226,12 @@ class a {
226
226
  inputSize: n.inputSize,
227
227
  outputSize: n.outputSize,
228
228
  upscaleSize: n.upscaleSize,
229
- modelUri: t,
229
+ modelUri: r,
230
230
  workerUri: o
231
231
  }, h = {
232
232
  assetUrlResolver: c,
233
233
  executionProviders: f,
234
- baseUrl: r,
234
+ baseUrl: t,
235
235
  wasmUri: s,
236
236
  mask: u
237
237
  };
@@ -266,8 +266,8 @@ class a {
266
266
  * @returns The base URL for the configuration.
267
267
  */
268
268
  resolveModelUri() {
269
- var r;
270
- if ((r = this.config.mask) != null && r.modelUri)
269
+ var t;
270
+ if ((t = this.config.mask) != null && t.modelUri)
271
271
  return this.config.mask.modelUri;
272
272
  const e = this.getMaskConfig();
273
273
  if (!e.qualityKey)
@@ -299,11 +299,11 @@ class a {
299
299
  * @param values The values to use for resolution.
300
300
  * @returns The resolved template string.
301
301
  */
302
- resolveTemplate(e, r) {
303
- return e.replace(/\$\{([A-Z_]+)\}/g, (t, s) => {
304
- if (!r[s])
302
+ resolveTemplate(e, t) {
303
+ return e.replace(/\$\{([A-Z_]+)\}/g, (r, s) => {
304
+ if (!t[s])
305
305
  throw new Error(`Missing value for template variable: ${s}`);
306
- return r[s];
306
+ return t[s];
307
307
  });
308
308
  }
309
309
  /**
@@ -311,16 +311,22 @@ class a {
311
311
  * @param blurStrength The desired blur strength.
312
312
  * @param horizontalMirror Whether to apply horizontal mirroring.
313
313
  */
314
- static getBlurConfig(e, r) {
315
- const t = e.toLowerCase(), s = i.blurStrengths[t];
314
+ static getBlurConfig(e, t) {
315
+ const r = e.toLowerCase(), s = i.blurStrengths[r];
316
316
  if (!s)
317
317
  throw new Error(`[ladon-ts] Unknown blur strength: ${e}`);
318
318
  return {
319
319
  type: "blur",
320
- horizontalMirror: r,
320
+ horizontalMirror: t,
321
321
  ...s
322
322
  };
323
323
  }
324
+ static getPassthroughConfig(e) {
325
+ return {
326
+ type: "passthrough",
327
+ horizontalMirror: e
328
+ };
329
+ }
324
330
  /**
325
331
  * Returns the library version.
326
332
  *
@@ -1 +1 @@
1
- {"version":3,"file":"config-builder.js","sources":["../../../src/lib/config-builder.ts"],"sourcesContent":["import rawConfig from '../config.json';\n\nimport {\n AssetUrlResolver,\n BlurConfig,\n BlurStrength,\n Generator,\n InputConfig,\n MaskConfig,\n PipelineConfig,\n PreloadConfig,\n Quality,\n RawConfig,\n RenderConfig,\n} from './config-types';\nimport { LIB_VERSION } from './version';\n\n/**\n * Internal mutable versions of the configurations used within the builder.\n */\ninterface MutableSizeConfig {\n height: number;\n width: number;\n}\n\ninterface MutableRenderConfig {\n type: 'blur' | 'passthrough' | 'replacement';\n horizontalMirror?: boolean;\n}\n\ninterface MutableBlurConfig extends MutableRenderConfig {\n type: 'blur';\n kernelSize: number;\n sigma: number;\n}\n\ninterface MutableReplacementConfig extends MutableRenderConfig {\n type: 'replacement';\n background: HTMLCanvasElement;\n static: boolean;\n // TODO: add reposition args for presentation mode\n}\n\ninterface MutableBaseMaskConfig {\n generator: Generator;\n generationIntervalMs: number;\n modelRank: number;\n modelUri: string;\n workerUri: string;\n inputSize?: MutableSizeConfig;\n outputSize?: MutableSizeConfig;\n upscaleSize?: MutableSizeConfig;\n}\n\ninterface MutableMaskConfig extends MutableBaseMaskConfig {\n inputSize: MutableSizeConfig;\n outputSize: MutableSizeConfig;\n upscaleSize: MutableSizeConfig;\n qualityKey?: keyof RawConfig['modelQualities'];\n}\n\ninterface MutablePipelineConfig {\n baseUrl?: string;\n wasmUri?: string;\n executionProviders?: string[];\n render?: MutableBlurConfig | MutableRenderConfig | MutableReplacementConfig;\n input?: MutableSizeConfig;\n mask?: MutableMaskConfig;\n assetUrlResolver?: AssetUrlResolver;\n}\n\n/**\n * A builder class for creating PipelineConfig instances in a flexible and intuitive way.\n */\nexport class ConfigurationBuilder {\n private config: MutablePipelineConfig = {};\n\n constructor(private env: 'int' | 'prod' = 'prod') {}\n\n /**\n * Sets the base URL for the configuration.\n * @param baseUrl The base URL to use.\n */\n public setBaseUrl(baseUrl: string): ConfigurationBuilder {\n // Remove trailing slashes from the base URL\n this.config.baseUrl = baseUrl.replace(/\\/+$/, '');\n return this;\n }\n\n /**\n * Sets the WASM URI for the configuration.\n * @param wasmUri The WASM URI to use.\n */\n public setWasmUri(wasmUri: string): ConfigurationBuilder {\n this.config.wasmUri = wasmUri;\n return this;\n }\n\n /**\n * Sets the asset URL resolver.\n * @param assetUrlResolver The asset URL resolver to use\n * @returns The current ConfigurationBuilder instance.\n */\n public setAssetUrlResolver(assetUrlResolver: AssetUrlResolver): ConfigurationBuilder {\n this.config.assetUrlResolver = assetUrlResolver;\n return this;\n }\n\n /**\n * Sets the execution providers for the ONNX runtime.\n *\n * @param executionProviders The execution providers to use.\n */\n public setExecutionProviders(executionProviders: string[]): ConfigurationBuilder {\n // Allow a single string to be passed as well. This is useful for setting a single provider.\n // This will convert the string to an array for consistency.\n if (typeof executionProviders === 'string') {\n executionProviders = [executionProviders];\n }\n this.config.executionProviders = executionProviders;\n return this;\n }\n\n /**\n * Sets the input size for the configuration.\n * @param height The height of the input.\n * @param width The width of the input.\n */\n public setInputSize(height: number, width: number): ConfigurationBuilder {\n this.config.input = { height, width };\n return this;\n }\n\n /**\n * Sets the input configuration.\n * @param inputConfig The input configuration to use.\n */\n public setInputConfig(inputConfig: InputConfig): ConfigurationBuilder {\n this.config.input = { ...inputConfig };\n return this;\n }\n\n /**\n * Sets the render configuration.\n * @param renderConfig The render configuration to use.\n */\n public setRenderConfig(renderConfig: RenderConfig): ConfigurationBuilder {\n this.config.render = { ...renderConfig } as MutableRenderConfig;\n return this;\n }\n\n /**\n * Sets the render type.\n * @param type The render type ('blur', 'passthrough', 'replacement').\n */\n public setRenderType(type: 'blur' | 'passthrough' | 'replacement'): ConfigurationBuilder {\n if (!this.config.render) {\n this.config.render = { type };\n } else {\n this.config.render.type = type;\n }\n return this;\n }\n\n /**\n * Sets the horizontal mirror property for the render configuration.\n * @param horizontalMirror Boolean indicating if horizontal mirror should be applied.\n */\n public setRenderHorizontalMirror(horizontalMirror: boolean): ConfigurationBuilder {\n if (!this.config.render) {\n throw new Error('Render config must be set before setting horizontal mirror.');\n }\n this.config.render.horizontalMirror = horizontalMirror;\n return this;\n }\n\n /**\n * Sets the blur strength for the render configuration.\n * @param blurStrength The blur strength to use.\n */\n public setBlurStrength(blurStrength: BlurStrength): ConfigurationBuilder {\n const blurConfig = ConfigurationBuilder.getBlurConfig(\n blurStrength,\n this.config.render?.horizontalMirror\n );\n this.config.render = { ...this.config.render, ...blurConfig };\n return this;\n }\n\n /**\n * Sets the blur kernel size.\n * @param kernelSize The kernel size for the blur effect.\n */\n public setBlurKernelSize(kernelSize: number): ConfigurationBuilder {\n if (!this.config.render || this.config.render.type !== 'blur') {\n throw new Error('Render config must be of type blur to set blur properties.');\n }\n (this.config.render as MutableBlurConfig).kernelSize = kernelSize;\n return this;\n }\n\n /**\n * Sets the blur sigma value.\n * @param sigma The sigma value for the blur effect.\n */\n public setBlurSigma(sigma: number): ConfigurationBuilder {\n if (!this.config.render || this.config.render.type !== 'blur') {\n throw new Error('Render config must be of type blur to set blur properties.');\n }\n (this.config.render as MutableBlurConfig).sigma = sigma;\n return this;\n }\n\n /**\n * Sets the replacement background.\n * @param background The background to use for replacement.\n */\n public setReplacementBackground(background: HTMLCanvasElement): ConfigurationBuilder {\n if (!this.config.render || this.config.render.type !== 'replacement') {\n throw new Error(\n 'Render config must be of type replacement to set replacement properties.'\n );\n }\n (this.config.render as MutableReplacementConfig).background = background;\n return this;\n }\n\n /**\n * Sets the replacement static property.\n * @param isStatic Boolean indicating if the replacement is static.\n */\n public setReplacementStatic(isStatic: boolean): ConfigurationBuilder {\n if (!this.config.render || this.config.render.type !== 'replacement') {\n throw new Error(\n 'Render config must be of type replacement to set replacement properties.'\n );\n }\n (this.config.render as MutableReplacementConfig).static = isStatic;\n return this;\n }\n\n /**\n * Sets the mask configuration.\n * @param maskConfig The mask configuration to use.\n */\n public setMaskConfig(maskConfig: MaskConfig): ConfigurationBuilder {\n this.config.mask = { ...maskConfig } as MutableMaskConfig;\n return this;\n }\n\n /**\n * Sets the mask generator.\n * @param generator The generator type ('local' or 'worker').\n */\n public setMaskGenerator(generator: Generator): ConfigurationBuilder {\n const mask = this.getMaskConfig();\n mask.generator = generator;\n return this;\n }\n\n /**\n * Sets the mask generation interval in milliseconds.\n * @param intervalMs The generation interval in milliseconds.\n */\n public setMaskGenerationIntervalMs(intervalMs: number): ConfigurationBuilder {\n const mask = this.getMaskConfig();\n mask.generationIntervalMs = intervalMs;\n return this;\n }\n\n /**\n * Sets the mask model rank.\n * @param modelRank The model rank to use.\n */\n public setMaskModelRank(modelRank: number): ConfigurationBuilder {\n const mask = this.getMaskConfig();\n mask.modelRank = modelRank;\n return this;\n }\n\n /**\n * Sets the mask model URI.\n * @param modelUri The model URI to use.\n */\n public setMaskModelUri(modelUri: string): ConfigurationBuilder {\n const mask = this.getMaskConfig();\n mask.modelUri = modelUri;\n return this;\n }\n\n /**\n * Sets the mask worker URI.\n * @param workerUri The worker URI to use.\n */\n public setMaskWorkerUri(workerUri: string): ConfigurationBuilder {\n const mask = this.getMaskConfig();\n mask.workerUri = workerUri;\n return this;\n }\n\n /**\n * Sets the mask input size.\n * @param height The height of the mask input.\n * @param width The width of the mask input.\n */\n public setMaskInputSize(height: number, width: number): ConfigurationBuilder {\n const mask = this.getMaskConfig();\n mask.inputSize = { height, width };\n return this;\n }\n\n /**\n * Sets the mask output size.\n * @param height The height of the mask output.\n * @param width The width of the mask output.\n */\n public setMaskOutputSize(height: number, width: number): ConfigurationBuilder {\n const mask = this.getMaskConfig();\n mask.outputSize = { height, width };\n return this;\n }\n\n /**\n * Sets the mask upscaled size.\n * @param height The height of the upscaled mask.\n * @param width The width of the upscaled mask.\n */\n public setMaskUpscaleSize(height: number, width: number): ConfigurationBuilder {\n const mask = this.getMaskConfig();\n mask.upscaleSize = { height, width };\n return this;\n }\n\n /**\n * Sets the quality level and updates mask configurations accordingly.\n * @param quality The desired quality level.\n */\n public setMaskQuality(quality: Quality): ConfigurationBuilder {\n const { modelQualities } = rawConfig;\n\n const mask = this.getMaskConfig();\n const qualityKey = quality.toLowerCase() as keyof RawConfig['modelQualities'];\n const qualityConfig = modelQualities[qualityKey];\n\n if (!qualityConfig) {\n throw new Error(`[ladon-ts] - unknown quality option: ${quality}`);\n }\n\n // Store the quality key for dynamic resolution later\n mask.qualityKey = qualityKey;\n\n // Copy other quality-specific properties into the mask config\n Object.assign(mask, qualityConfig);\n\n return this;\n }\n\n /**\n * Builds and returns the PreloadConfig or PipelineConfig object.\n *\n * @param requireInputConfig Whether to require the input configuration to be set before building.\n * Input size is not available at preload so this needs to be optional. The default value is true.\n *\n */\n public build(requireInputConfig = true): PipelineConfig | PreloadConfig {\n const baseUrl = this.resolveBaseUrl();\n const modelUri = this.resolveModelUri();\n const wasmUri = this.resolveWasmUri();\n const workerUri = this.resolveWorkerUri();\n\n const input = this.config.input;\n const render = this.config.render;\n const maskConfig = this.config.mask;\n const executionProviders = this.config.executionProviders;\n const assetUrlResolver = this.config.assetUrlResolver;\n\n if (!maskConfig) {\n throw new Error('Mask configuration must be set before building the configuration.');\n }\n\n const mask: MaskConfig = {\n generator: maskConfig.generator,\n generationIntervalMs: maskConfig.generationIntervalMs,\n modelRank: maskConfig.modelRank,\n inputSize: maskConfig.inputSize,\n outputSize: maskConfig.outputSize,\n upscaleSize: maskConfig.upscaleSize,\n modelUri,\n workerUri,\n };\n\n // Build the preload configuration, which is valid for both preload and pipeline.\n const preloadConfig = {\n assetUrlResolver,\n executionProviders,\n baseUrl,\n wasmUri,\n mask,\n };\n\n if (requireInputConfig) {\n if (!input) {\n throw new Error('Input must be set before building the configuration.');\n }\n\n if (!render) {\n throw new Error('Render must be set before building the configuration.');\n }\n\n // Build the full PipelineConfig\n const pipelineConfig = {\n ...preloadConfig,\n input,\n render,\n } as PipelineConfig;\n\n return pipelineConfig;\n }\n\n return preloadConfig as PreloadConfig;\n }\n\n /**\n * Returns the mask configuration, initializing it if necessary.\n */\n private getMaskConfig(): MutableMaskConfig {\n if (!this.config.mask) {\n this.config.mask = {} as MutableMaskConfig;\n }\n return this.config.mask;\n }\n\n /**\n * Returns the base URL for the configuration.\n */\n public resolveBaseUrl(): string {\n // TODO: Do we want to publish the base URL in the raw config? It seems like the models\n // auth service should be responsible for this, or the user should provide the base url.\n return this.config.baseUrl || rawConfig.baseUrls[this.env];\n }\n\n /**\n * Returns the base URL for the configuration.\n *\n * @returns The base URL for the configuration.\n */\n public resolveModelUri(): string {\n // First check if the property is explicitly set in the config, then fallback to rawConfig\n if (this.config.mask?.modelUri) {\n return this.config.mask.modelUri;\n }\n\n const mask = this.getMaskConfig();\n if (!mask.qualityKey) {\n throw new Error('[ladon-ts] No quality set, cannot infer modelFile.');\n }\n\n return this.resolveTemplate(rawConfig.modelUrlTemplate, {\n BASE_PATH_MODELS: rawConfig.basePaths.models,\n MODEL_VERSION: rawConfig.modelVersion,\n MODEL_FILE: rawConfig.modelQualities[mask.qualityKey].modelFile,\n });\n }\n\n public resolveWasmUri(): string {\n // First check if the property is explicitly set in the config, then fallback to rawConfig\n if (this.config.wasmUri) {\n return this.config.wasmUri;\n }\n\n return this.resolveTemplate(rawConfig.wasmPathTemplate, {\n BASE_PATH_WASM: rawConfig.basePaths.wasm,\n ONNX_VERSION: rawConfig.onnxVersion,\n });\n }\n\n public resolveWorkerUri(): string {\n // First check if the property is explicitly set in the config, then fallback to rawConfig\n if (this.config.mask?.workerUri) {\n return this.config.mask.workerUri;\n }\n\n return this.resolveTemplate(rawConfig.workerUrlTemplate, {\n BASE_PATH_WORKERS: rawConfig.basePaths.workers,\n LIB_VERSION: ConfigurationBuilder.getLibVersion(),\n WORKER_FILE: rawConfig.workerFile,\n });\n }\n\n /**\n * Resolves a template string with the specified values.\n *\n * @param template The template string to resolve.\n * @param values The values to use for resolution.\n * @returns The resolved template string.\n */\n private resolveTemplate(template: string, values: Record<string, string>): string {\n return template.replace(/\\$\\{([A-Z_]+)\\}/g, (_, key) => {\n if (!values[key]) {\n throw new Error(`Missing value for template variable: ${key}`);\n }\n return values[key];\n });\n }\n\n /**\n * Generates a blur configuration based on the specified blur strength.\n * @param blurStrength The desired blur strength.\n * @param horizontalMirror Whether to apply horizontal mirroring.\n */\n public static getBlurConfig(\n blurStrength: BlurStrength,\n horizontalMirror?: boolean\n ): BlurConfig {\n const strengthKey = blurStrength.toLowerCase() as keyof RawConfig['blurStrengths'];\n const blurConfig = rawConfig.blurStrengths[strengthKey];\n\n if (!blurConfig) {\n throw new Error(`[ladon-ts] Unknown blur strength: ${blurStrength}`);\n }\n\n return {\n type: 'blur',\n horizontalMirror,\n ...blurConfig,\n };\n }\n\n /**\n * Returns the library version.\n *\n * @returns The library version.\n */\n public static getLibVersion(): string {\n return LIB_VERSION;\n }\n}\n"],"names":["ConfigurationBuilder","env","baseUrl","wasmUri","assetUrlResolver","executionProviders","height","width","inputConfig","renderConfig","type","horizontalMirror","blurStrength","blurConfig","_a","kernelSize","sigma","background","isStatic","maskConfig","generator","mask","intervalMs","modelRank","modelUri","workerUri","quality","modelQualities","rawConfig","qualityKey","qualityConfig","requireInputConfig","input","render","preloadConfig","template","values","_","key","strengthKey","LIB_VERSION"],"mappings":"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"}
1
+ {"version":3,"file":"config-builder.js","sources":["../../../src/lib/config-builder.ts"],"sourcesContent":["import rawConfig from '../config.json';\n\nimport {\n AssetUrlResolver,\n BlurConfig,\n BlurStrength,\n Generator,\n InputConfig,\n MaskConfig,\n PassthroughConfig,\n PipelineConfig,\n PreloadConfig,\n Quality,\n RawConfig,\n RenderConfig,\n} from './config-types';\nimport { LIB_VERSION } from './version';\n\n/**\n * Internal mutable versions of the configurations used within the builder.\n */\ninterface MutableSizeConfig {\n height: number;\n width: number;\n}\n\ninterface MutableRenderConfig {\n type: 'blur' | 'passthrough' | 'replacement';\n horizontalMirror?: boolean;\n}\n\ninterface MutableBlurConfig extends MutableRenderConfig {\n type: 'blur';\n kernelSize: number;\n sigma: number;\n}\n\ninterface MutableReplacementConfig extends MutableRenderConfig {\n type: 'replacement';\n background: HTMLCanvasElement;\n static: boolean;\n // TODO: add reposition args for presentation mode\n}\n\ninterface MutableBaseMaskConfig {\n generator: Generator;\n generationIntervalMs: number;\n modelRank: number;\n modelUri: string;\n workerUri: string;\n inputSize?: MutableSizeConfig;\n outputSize?: MutableSizeConfig;\n upscaleSize?: MutableSizeConfig;\n}\n\ninterface MutableMaskConfig extends MutableBaseMaskConfig {\n inputSize: MutableSizeConfig;\n outputSize: MutableSizeConfig;\n upscaleSize: MutableSizeConfig;\n qualityKey?: keyof RawConfig['modelQualities'];\n}\n\ninterface MutablePipelineConfig {\n baseUrl?: string;\n wasmUri?: string;\n executionProviders?: string[];\n render?: MutableBlurConfig | MutableRenderConfig | MutableReplacementConfig;\n input?: MutableSizeConfig;\n mask?: MutableMaskConfig;\n assetUrlResolver?: AssetUrlResolver;\n}\n\n/**\n * A builder class for creating PipelineConfig instances in a flexible and intuitive way.\n */\nexport class ConfigurationBuilder {\n private config: MutablePipelineConfig = {};\n\n constructor(private env: 'int' | 'prod' = 'prod') {}\n\n /**\n * Sets the base URL for the configuration.\n * @param baseUrl The base URL to use.\n */\n public setBaseUrl(baseUrl: string): ConfigurationBuilder {\n // Remove trailing slashes from the base URL\n this.config.baseUrl = baseUrl.replace(/\\/+$/, '');\n return this;\n }\n\n /**\n * Sets the WASM URI for the configuration.\n * @param wasmUri The WASM URI to use.\n */\n public setWasmUri(wasmUri: string): ConfigurationBuilder {\n this.config.wasmUri = wasmUri;\n return this;\n }\n\n /**\n * Sets the asset URL resolver.\n * @param assetUrlResolver The asset URL resolver to use\n * @returns The current ConfigurationBuilder instance.\n */\n public setAssetUrlResolver(assetUrlResolver: AssetUrlResolver): ConfigurationBuilder {\n this.config.assetUrlResolver = assetUrlResolver;\n return this;\n }\n\n /**\n * Sets the execution providers for the ONNX runtime.\n *\n * @param executionProviders The execution providers to use.\n */\n public setExecutionProviders(executionProviders: string[]): ConfigurationBuilder {\n // Allow a single string to be passed as well. This is useful for setting a single provider.\n // This will convert the string to an array for consistency.\n if (typeof executionProviders === 'string') {\n executionProviders = [executionProviders];\n }\n this.config.executionProviders = executionProviders;\n return this;\n }\n\n /**\n * Sets the input size for the configuration.\n * @param height The height of the input.\n * @param width The width of the input.\n */\n public setInputSize(height: number, width: number): ConfigurationBuilder {\n this.config.input = { height, width };\n return this;\n }\n\n /**\n * Sets the input configuration.\n * @param inputConfig The input configuration to use.\n */\n public setInputConfig(inputConfig: InputConfig): ConfigurationBuilder {\n this.config.input = { ...inputConfig };\n return this;\n }\n\n /**\n * Sets the render configuration.\n * @param renderConfig The render configuration to use.\n */\n public setRenderConfig(renderConfig: RenderConfig): ConfigurationBuilder {\n this.config.render = { ...renderConfig } as MutableRenderConfig;\n return this;\n }\n\n /**\n * Sets the render type.\n * @param type The render type ('blur', 'passthrough', 'replacement').\n */\n public setRenderType(type: 'blur' | 'passthrough' | 'replacement'): ConfigurationBuilder {\n if (!this.config.render) {\n this.config.render = { type };\n } else {\n this.config.render.type = type;\n }\n return this;\n }\n\n /**\n * Sets the horizontal mirror property for the render configuration.\n * @param horizontalMirror Boolean indicating if horizontal mirror should be applied.\n */\n public setRenderHorizontalMirror(horizontalMirror: boolean): ConfigurationBuilder {\n if (!this.config.render) {\n throw new Error('Render config must be set before setting horizontal mirror.');\n }\n this.config.render.horizontalMirror = horizontalMirror;\n return this;\n }\n\n /**\n * Sets the blur strength for the render configuration.\n * @param blurStrength The blur strength to use.\n */\n public setBlurStrength(blurStrength: BlurStrength): ConfigurationBuilder {\n const blurConfig = ConfigurationBuilder.getBlurConfig(\n blurStrength,\n this.config.render?.horizontalMirror\n );\n this.config.render = { ...this.config.render, ...blurConfig };\n return this;\n }\n\n /**\n * Sets the blur kernel size.\n * @param kernelSize The kernel size for the blur effect.\n */\n public setBlurKernelSize(kernelSize: number): ConfigurationBuilder {\n if (!this.config.render || this.config.render.type !== 'blur') {\n throw new Error('Render config must be of type blur to set blur properties.');\n }\n (this.config.render as MutableBlurConfig).kernelSize = kernelSize;\n return this;\n }\n\n /**\n * Sets the blur sigma value.\n * @param sigma The sigma value for the blur effect.\n */\n public setBlurSigma(sigma: number): ConfigurationBuilder {\n if (!this.config.render || this.config.render.type !== 'blur') {\n throw new Error('Render config must be of type blur to set blur properties.');\n }\n (this.config.render as MutableBlurConfig).sigma = sigma;\n return this;\n }\n\n /**\n * Sets the replacement background.\n * @param background The background to use for replacement.\n */\n public setReplacementBackground(background: HTMLCanvasElement): ConfigurationBuilder {\n if (!this.config.render || this.config.render.type !== 'replacement') {\n throw new Error(\n 'Render config must be of type replacement to set replacement properties.'\n );\n }\n (this.config.render as MutableReplacementConfig).background = background;\n return this;\n }\n\n /**\n * Sets the replacement static property.\n * @param isStatic Boolean indicating if the replacement is static.\n */\n public setReplacementStatic(isStatic: boolean): ConfigurationBuilder {\n if (!this.config.render || this.config.render.type !== 'replacement') {\n throw new Error(\n 'Render config must be of type replacement to set replacement properties.'\n );\n }\n (this.config.render as MutableReplacementConfig).static = isStatic;\n return this;\n }\n\n /**\n * Sets the mask configuration.\n * @param maskConfig The mask configuration to use.\n */\n public setMaskConfig(maskConfig: MaskConfig): ConfigurationBuilder {\n this.config.mask = { ...maskConfig } as MutableMaskConfig;\n return this;\n }\n\n /**\n * Sets the mask generator.\n * @param generator The generator type ('local' or 'worker').\n */\n public setMaskGenerator(generator: Generator): ConfigurationBuilder {\n const mask = this.getMaskConfig();\n mask.generator = generator;\n return this;\n }\n\n /**\n * Sets the mask generation interval in milliseconds.\n * @param intervalMs The generation interval in milliseconds.\n */\n public setMaskGenerationIntervalMs(intervalMs: number): ConfigurationBuilder {\n const mask = this.getMaskConfig();\n mask.generationIntervalMs = intervalMs;\n return this;\n }\n\n /**\n * Sets the mask model rank.\n * @param modelRank The model rank to use.\n */\n public setMaskModelRank(modelRank: number): ConfigurationBuilder {\n const mask = this.getMaskConfig();\n mask.modelRank = modelRank;\n return this;\n }\n\n /**\n * Sets the mask model URI.\n * @param modelUri The model URI to use.\n */\n public setMaskModelUri(modelUri: string): ConfigurationBuilder {\n const mask = this.getMaskConfig();\n mask.modelUri = modelUri;\n return this;\n }\n\n /**\n * Sets the mask worker URI.\n * @param workerUri The worker URI to use.\n */\n public setMaskWorkerUri(workerUri: string): ConfigurationBuilder {\n const mask = this.getMaskConfig();\n mask.workerUri = workerUri;\n return this;\n }\n\n /**\n * Sets the mask input size.\n * @param height The height of the mask input.\n * @param width The width of the mask input.\n */\n public setMaskInputSize(height: number, width: number): ConfigurationBuilder {\n const mask = this.getMaskConfig();\n mask.inputSize = { height, width };\n return this;\n }\n\n /**\n * Sets the mask output size.\n * @param height The height of the mask output.\n * @param width The width of the mask output.\n */\n public setMaskOutputSize(height: number, width: number): ConfigurationBuilder {\n const mask = this.getMaskConfig();\n mask.outputSize = { height, width };\n return this;\n }\n\n /**\n * Sets the mask upscaled size.\n * @param height The height of the upscaled mask.\n * @param width The width of the upscaled mask.\n */\n public setMaskUpscaleSize(height: number, width: number): ConfigurationBuilder {\n const mask = this.getMaskConfig();\n mask.upscaleSize = { height, width };\n return this;\n }\n\n /**\n * Sets the quality level and updates mask configurations accordingly.\n * @param quality The desired quality level.\n */\n public setMaskQuality(quality: Quality): ConfigurationBuilder {\n const { modelQualities } = rawConfig;\n\n const mask = this.getMaskConfig();\n const qualityKey = quality.toLowerCase() as keyof RawConfig['modelQualities'];\n const qualityConfig = modelQualities[qualityKey];\n\n if (!qualityConfig) {\n throw new Error(`[ladon-ts] - unknown quality option: ${quality}`);\n }\n\n // Store the quality key for dynamic resolution later\n mask.qualityKey = qualityKey;\n\n // Copy other quality-specific properties into the mask config\n Object.assign(mask, qualityConfig);\n\n return this;\n }\n\n /**\n * Builds and returns the PreloadConfig or PipelineConfig object.\n *\n * @param requireInputConfig Whether to require the input configuration to be set before building.\n * Input size is not available at preload so this needs to be optional. The default value is true.\n *\n */\n public build(requireInputConfig = true): PipelineConfig | PreloadConfig {\n const baseUrl = this.resolveBaseUrl();\n const modelUri = this.resolveModelUri();\n const wasmUri = this.resolveWasmUri();\n const workerUri = this.resolveWorkerUri();\n\n const input = this.config.input;\n const render = this.config.render;\n const maskConfig = this.config.mask;\n const executionProviders = this.config.executionProviders;\n const assetUrlResolver = this.config.assetUrlResolver;\n\n if (!maskConfig) {\n throw new Error('Mask configuration must be set before building the configuration.');\n }\n\n const mask: MaskConfig = {\n generator: maskConfig.generator,\n generationIntervalMs: maskConfig.generationIntervalMs,\n modelRank: maskConfig.modelRank,\n inputSize: maskConfig.inputSize,\n outputSize: maskConfig.outputSize,\n upscaleSize: maskConfig.upscaleSize,\n modelUri,\n workerUri,\n };\n\n // Build the preload configuration, which is valid for both preload and pipeline.\n const preloadConfig = {\n assetUrlResolver,\n executionProviders,\n baseUrl,\n wasmUri,\n mask,\n };\n\n if (requireInputConfig) {\n if (!input) {\n throw new Error('Input must be set before building the configuration.');\n }\n\n if (!render) {\n throw new Error('Render must be set before building the configuration.');\n }\n\n // Build the full PipelineConfig\n const pipelineConfig = {\n ...preloadConfig,\n input,\n render,\n } as PipelineConfig;\n\n return pipelineConfig;\n }\n\n return preloadConfig as PreloadConfig;\n }\n\n /**\n * Returns the mask configuration, initializing it if necessary.\n */\n private getMaskConfig(): MutableMaskConfig {\n if (!this.config.mask) {\n this.config.mask = {} as MutableMaskConfig;\n }\n return this.config.mask;\n }\n\n /**\n * Returns the base URL for the configuration.\n */\n public resolveBaseUrl(): string {\n // TODO: Do we want to publish the base URL in the raw config? It seems like the models\n // auth service should be responsible for this, or the user should provide the base url.\n return this.config.baseUrl || rawConfig.baseUrls[this.env];\n }\n\n /**\n * Returns the base URL for the configuration.\n *\n * @returns The base URL for the configuration.\n */\n public resolveModelUri(): string {\n // First check if the property is explicitly set in the config, then fallback to rawConfig\n if (this.config.mask?.modelUri) {\n return this.config.mask.modelUri;\n }\n\n const mask = this.getMaskConfig();\n if (!mask.qualityKey) {\n throw new Error('[ladon-ts] No quality set, cannot infer modelFile.');\n }\n\n return this.resolveTemplate(rawConfig.modelUrlTemplate, {\n BASE_PATH_MODELS: rawConfig.basePaths.models,\n MODEL_VERSION: rawConfig.modelVersion,\n MODEL_FILE: rawConfig.modelQualities[mask.qualityKey].modelFile,\n });\n }\n\n public resolveWasmUri(): string {\n // First check if the property is explicitly set in the config, then fallback to rawConfig\n if (this.config.wasmUri) {\n return this.config.wasmUri;\n }\n\n return this.resolveTemplate(rawConfig.wasmPathTemplate, {\n BASE_PATH_WASM: rawConfig.basePaths.wasm,\n ONNX_VERSION: rawConfig.onnxVersion,\n });\n }\n\n public resolveWorkerUri(): string {\n // First check if the property is explicitly set in the config, then fallback to rawConfig\n if (this.config.mask?.workerUri) {\n return this.config.mask.workerUri;\n }\n\n return this.resolveTemplate(rawConfig.workerUrlTemplate, {\n BASE_PATH_WORKERS: rawConfig.basePaths.workers,\n LIB_VERSION: ConfigurationBuilder.getLibVersion(),\n WORKER_FILE: rawConfig.workerFile,\n });\n }\n\n /**\n * Resolves a template string with the specified values.\n *\n * @param template The template string to resolve.\n * @param values The values to use for resolution.\n * @returns The resolved template string.\n */\n private resolveTemplate(template: string, values: Record<string, string>): string {\n return template.replace(/\\$\\{([A-Z_]+)\\}/g, (_, key) => {\n if (!values[key]) {\n throw new Error(`Missing value for template variable: ${key}`);\n }\n return values[key];\n });\n }\n\n /**\n * Generates a blur configuration based on the specified blur strength.\n * @param blurStrength The desired blur strength.\n * @param horizontalMirror Whether to apply horizontal mirroring.\n */\n public static getBlurConfig(\n blurStrength: BlurStrength,\n horizontalMirror?: boolean\n ): BlurConfig {\n const strengthKey = blurStrength.toLowerCase() as keyof RawConfig['blurStrengths'];\n const blurConfig = rawConfig.blurStrengths[strengthKey];\n\n if (!blurConfig) {\n throw new Error(`[ladon-ts] Unknown blur strength: ${blurStrength}`);\n }\n\n return {\n type: 'blur',\n horizontalMirror,\n ...blurConfig,\n };\n }\n\n public static getPassthroughConfig(horizontalMirror?: boolean): PassthroughConfig {\n return {\n type: 'passthrough',\n horizontalMirror,\n };\n }\n\n /**\n * Returns the library version.\n *\n * @returns The library version.\n */\n public static getLibVersion(): string {\n return LIB_VERSION;\n }\n}\n"],"names":["ConfigurationBuilder","env","baseUrl","wasmUri","assetUrlResolver","executionProviders","height","width","inputConfig","renderConfig","type","horizontalMirror","blurStrength","blurConfig","_a","kernelSize","sigma","background","isStatic","maskConfig","generator","mask","intervalMs","modelRank","modelUri","workerUri","quality","modelQualities","rawConfig","qualityKey","qualityConfig","requireInputConfig","input","render","preloadConfig","template","values","_","key","strengthKey","LIB_VERSION"],"mappings":"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"}
@@ -45,6 +45,9 @@ export interface ReplacementConfig extends RenderConfig {
45
45
  readonly background: HTMLCanvasElement;
46
46
  readonly static: boolean;
47
47
  }
48
+ export interface PassthroughConfig extends RenderConfig {
49
+ readonly type: 'passthrough';
50
+ }
48
51
  export declare type Generator = 'local' | 'worker';
49
52
  export declare type BaseMaskConfig = {
50
53
  readonly generator: Generator;
@@ -1 +1 @@
1
- {"version":3,"file":"config-types.js","sources":["../../../src/lib/config-types.ts"],"sourcesContent":["export enum Quality {\n TINY = 'TINY',\n LOW = 'LOW',\n MEDIUM = 'MEDIUM',\n HIGH = 'HIGH',\n ULTRA = 'ULTRA',\n}\n\nexport enum BlurStrength {\n WEAK = 'WEAK',\n MODERATE = 'MODERATE',\n STRONG = 'STRONG',\n STRONGER = 'STRONGER',\n STRONGEST = 'STRONGEST',\n}\n\nexport type ResolutionConfig = {\n readonly height: number;\n readonly width: number;\n};\n\nexport interface SizeConfig {\n readonly inputSize: ResolutionConfig;\n readonly outputSize: ResolutionConfig;\n readonly upscaleSize: ResolutionConfig;\n}\n\nexport interface ModelQualityConfig {\n readonly modelFile: string;\n readonly modelRank: number;\n readonly generationIntervalMs: number;\n readonly inputSize: ResolutionConfig;\n readonly outputSize: ResolutionConfig;\n readonly upscaleSize: ResolutionConfig;\n}\n\nexport type InputConfig = ResolutionConfig;\n\nexport type AssetUrlResolver = (assetUri: string, config: PreloadConfig) => Promise<string>;\n\nexport interface RenderConfig {\n readonly type: 'blur' | 'passthrough' | 'replacement';\n readonly horizontalMirror?: boolean;\n}\n\nexport interface BlurConfig extends RenderConfig {\n readonly type: 'blur';\n readonly kernelSize: number;\n readonly sigma: number;\n}\n\nexport interface ReplacementConfig extends RenderConfig {\n readonly type: 'replacement';\n readonly background: HTMLCanvasElement;\n readonly static: boolean;\n // TODO: add reposition args for presentation mode\n}\n\nexport type Generator = 'local' | 'worker';\n\nexport type BaseMaskConfig = {\n readonly generator: Generator;\n readonly generationIntervalMs: number;\n readonly modelRank: number;\n readonly modelUri: string;\n readonly workerUri: string;\n // These are optional because the input and output sizes are not known when preloading the model.\n // However, the sizes are needed when creating the pipeline to match the models seize requirements.\n readonly inputSize?: ResolutionConfig;\n readonly outputSize?: ResolutionConfig;\n readonly upscaleSize?: ResolutionConfig;\n};\n\nexport type MaskConfig = BaseMaskConfig & SizeConfig;\n\nexport type PreloadConfig = {\n readonly baseUrl?: string;\n readonly wasmUri: string;\n readonly mask: BaseMaskConfig;\n readonly executionProviders?: string[];\n readonly assetUrlResolver?: AssetUrlResolver;\n};\n\nexport type WorkerConfig = Omit<PreloadConfig, 'assetUrlResolver'>;\n\nexport type PipelineConfig = PreloadConfig & {\n readonly render: BlurConfig | RenderConfig | ReplacementConfig;\n readonly input: InputConfig;\n readonly mask: MaskConfig;\n};\n\nexport interface RawConfig {\n readonly baseUrls: {\n readonly int: string;\n readonly prod: string;\n };\n readonly basePaths: {\n readonly models: string;\n readonly wasm: string;\n readonly workers: string;\n };\n readonly blurStrengths: {\n readonly [key in Lowercase<BlurStrength>]: {\n readonly kernelSize: number;\n readonly sigma: number;\n };\n };\n readonly modelQualities: {\n readonly [key in Lowercase<Quality>]: ModelQualityConfig;\n };\n readonly onnxVersion: string;\n readonly modelVersion: string;\n readonly workerFile: string;\n readonly modelUrlTemplate: string;\n readonly wasmPathTemplate: string;\n readonly workerUrlTemplate: string;\n}\n"],"names":["Quality","BlurStrength"],"mappings":"AAAY,IAAAA,sBAAAA,OACRA,EAAA,OAAO,QACPA,EAAA,MAAM,OACNA,EAAA,SAAS,UACTA,EAAA,OAAO,QACPA,EAAA,QAAQ,SALAA,IAAAA,KAAA,CAAA,CAAA,GAQAC,sBAAAA,OACRA,EAAA,OAAO,QACPA,EAAA,WAAW,YACXA,EAAA,SAAS,UACTA,EAAA,WAAW,YACXA,EAAA,YAAY,aALJA,IAAAA,KAAA,CAAA,CAAA;"}
1
+ {"version":3,"file":"config-types.js","sources":["../../../src/lib/config-types.ts"],"sourcesContent":["export enum Quality {\n TINY = 'TINY',\n LOW = 'LOW',\n MEDIUM = 'MEDIUM',\n HIGH = 'HIGH',\n ULTRA = 'ULTRA',\n}\n\nexport enum BlurStrength {\n WEAK = 'WEAK',\n MODERATE = 'MODERATE',\n STRONG = 'STRONG',\n STRONGER = 'STRONGER',\n STRONGEST = 'STRONGEST',\n}\n\nexport type ResolutionConfig = {\n readonly height: number;\n readonly width: number;\n};\n\nexport interface SizeConfig {\n readonly inputSize: ResolutionConfig;\n readonly outputSize: ResolutionConfig;\n readonly upscaleSize: ResolutionConfig;\n}\n\nexport interface ModelQualityConfig {\n readonly modelFile: string;\n readonly modelRank: number;\n readonly generationIntervalMs: number;\n readonly inputSize: ResolutionConfig;\n readonly outputSize: ResolutionConfig;\n readonly upscaleSize: ResolutionConfig;\n}\n\nexport type InputConfig = ResolutionConfig;\n\nexport type AssetUrlResolver = (assetUri: string, config: PreloadConfig) => Promise<string>;\n\nexport interface RenderConfig {\n readonly type: 'blur' | 'passthrough' | 'replacement';\n readonly horizontalMirror?: boolean;\n}\n\nexport interface BlurConfig extends RenderConfig {\n readonly type: 'blur';\n readonly kernelSize: number;\n readonly sigma: number;\n}\n\nexport interface ReplacementConfig extends RenderConfig {\n readonly type: 'replacement';\n readonly background: HTMLCanvasElement;\n readonly static: boolean;\n // TODO: add reposition args for presentation mode\n}\n\nexport interface PassthroughConfig extends RenderConfig {\n readonly type: 'passthrough';\n}\n\nexport type Generator = 'local' | 'worker';\n\nexport type BaseMaskConfig = {\n readonly generator: Generator;\n readonly generationIntervalMs: number;\n readonly modelRank: number;\n readonly modelUri: string;\n readonly workerUri: string;\n // These are optional because the input and output sizes are not known when preloading the model.\n // However, the sizes are needed when creating the pipeline to match the models seize requirements.\n readonly inputSize?: ResolutionConfig;\n readonly outputSize?: ResolutionConfig;\n readonly upscaleSize?: ResolutionConfig;\n};\n\nexport type MaskConfig = BaseMaskConfig & SizeConfig;\n\nexport type PreloadConfig = {\n readonly baseUrl?: string;\n readonly wasmUri: string;\n readonly mask: BaseMaskConfig;\n readonly executionProviders?: string[];\n readonly assetUrlResolver?: AssetUrlResolver;\n};\n\nexport type WorkerConfig = Omit<PreloadConfig, 'assetUrlResolver'>;\n\nexport type PipelineConfig = PreloadConfig & {\n readonly render: BlurConfig | RenderConfig | ReplacementConfig;\n readonly input: InputConfig;\n readonly mask: MaskConfig;\n};\n\nexport interface RawConfig {\n readonly baseUrls: {\n readonly int: string;\n readonly prod: string;\n };\n readonly basePaths: {\n readonly models: string;\n readonly wasm: string;\n readonly workers: string;\n };\n readonly blurStrengths: {\n readonly [key in Lowercase<BlurStrength>]: {\n readonly kernelSize: number;\n readonly sigma: number;\n };\n };\n readonly modelQualities: {\n readonly [key in Lowercase<Quality>]: ModelQualityConfig;\n };\n readonly onnxVersion: string;\n readonly modelVersion: string;\n readonly workerFile: string;\n readonly modelUrlTemplate: string;\n readonly wasmPathTemplate: string;\n readonly workerUrlTemplate: string;\n}\n"],"names":["Quality","BlurStrength"],"mappings":"AAAY,IAAAA,sBAAAA,OACRA,EAAA,OAAO,QACPA,EAAA,MAAM,OACNA,EAAA,SAAS,UACTA,EAAA,OAAO,QACPA,EAAA,QAAQ,SALAA,IAAAA,KAAA,CAAA,CAAA,GAQAC,sBAAAA,OACRA,EAAA,OAAO,QACPA,EAAA,WAAW,YACXA,EAAA,SAAS,UACTA,EAAA,WAAW,YACXA,EAAA,YAAY,aALJA,IAAAA,KAAA,CAAA,CAAA;"}
@@ -9,7 +9,7 @@ export interface IFrameInferenceResult {
9
9
  timestamp: number;
10
10
  }
11
11
  export interface IPipeline {
12
- onFrame(timestamp: number, maskNeeded?: boolean, videoElement?: HTMLVideoElement): Promise<IFrameInferenceResult>;
12
+ onFrame(timestamp: number, maskNeeded?: boolean): Promise<IFrameInferenceResult>;
13
13
  isLoaded(): boolean;
14
14
  load(): Promise<void>;
15
15
  destroy(): void;
@@ -31,7 +31,7 @@ export declare class Pipeline implements IPipeline {
31
31
  * Processes a single frame and returns the inference result.
32
32
  *
33
33
  * @param timestamp - The timestamp of the frame.
34
- * @param [performInference=true] - Flag to perform mask inference.
34
+ * @param performInference - Flag to perform mask inference.
35
35
  * @returns The result of the frame processing.
36
36
  * @throws If the pipeline (generator or renderer) is not loaded.
37
37
  */
@@ -1,9 +1,9 @@
1
- import { NullGenerator as n, WorkerGenerator as h, LocalGenerator as o } from "./generator.js";
2
- import { BlurRenderer as u } from "./renderer/blur-renderer.js";
3
- import { PassthroughRenderer as d } from "./renderer/passthrough-renderer.js";
4
- import { ReplacementRenderer as l } from "./renderer/replacement-renderer.js";
1
+ import { WorkerGenerator as n, LocalGenerator as h } from "./generator.js";
2
+ import { BlurRenderer as o } from "./renderer/blur-renderer.js";
3
+ import { PassthroughRenderer as u } from "./renderer/passthrough-renderer.js";
4
+ import { ReplacementRenderer as d } from "./renderer/replacement-renderer.js";
5
5
  import { resizeImage as m } from "./util.js";
6
- class R {
6
+ class w {
7
7
  constructor(e, t, s, i) {
8
8
  this.inputCanvas = e, this.outputCanvas = t, this.config = s, this.videoElement = i, this.loaded = !1, this.frameQueue = [], this.maskQueue = [];
9
9
  const a = this.inputCanvas.getContext("2d", {
@@ -18,7 +18,7 @@ class R {
18
18
  * Processes a single frame and returns the inference result.
19
19
  *
20
20
  * @param timestamp - The timestamp of the frame.
21
- * @param [performInference=true] - Flag to perform mask inference.
21
+ * @param performInference - Flag to perform mask inference.
22
22
  * @returns The result of the frame processing.
23
23
  * @throws If the pipeline (generator or renderer) is not loaded.
24
24
  */
@@ -109,30 +109,27 @@ class R {
109
109
  async load() {
110
110
  switch (this.config.render.type) {
111
111
  case "blur":
112
- this.renderer = new u(this.outputCanvas, this.config);
112
+ this.renderer = new o(this.outputCanvas, this.config);
113
113
  break;
114
114
  case "passthrough":
115
- this.renderer = new d(this.outputCanvas, this.config);
115
+ this.renderer = new u(this.outputCanvas, this.config);
116
116
  break;
117
117
  case "replacement":
118
- this.renderer = new l(this.outputCanvas, this.config);
118
+ this.renderer = new d(this.outputCanvas, this.config);
119
119
  break;
120
120
  default:
121
121
  throw new Error("[ladon-ts] - renderer not implemented.");
122
122
  }
123
- if (await this.renderer.load(), this.config.render.type === "passthrough")
124
- this.generator = new n(this.config);
125
- else
126
- switch (this.config.mask.generator) {
127
- case "local":
128
- this.generator = new o(this.config);
129
- break;
130
- case "worker":
131
- this.generator = new h(this.config);
132
- break;
133
- default:
134
- throw new Error("[ladon-ts] - generator not implemented.");
135
- }
123
+ switch (await this.renderer.load(), this.config.mask.generator) {
124
+ case "local":
125
+ this.generator = new h(this.config);
126
+ break;
127
+ case "worker":
128
+ this.generator = new n(this.config);
129
+ break;
130
+ default:
131
+ throw new Error("[ladon-ts] - generator not implemented.");
132
+ }
136
133
  await this.generator.load(), this.loaded = !0;
137
134
  }
138
135
  /**
@@ -153,6 +150,6 @@ class R {
153
150
  }
154
151
  }
155
152
  export {
156
- R as Pipeline
153
+ w as Pipeline
157
154
  };
158
155
  //# sourceMappingURL=pipeline.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"pipeline.js","sources":["../../../src/lib/pipeline.ts"],"sourcesContent":["import { PipelineConfig } from './config-types';\nimport {\n FacesAndLandmarks,\n FrameData,\n LadonOutput,\n LocalGenerator,\n MaskGenerator,\n NullGenerator,\n WorkerGenerator,\n} from './generator';\nimport { BlurRenderer, LadonRenderer, PassthroughRenderer, ReplacementRenderer } from './renderer';\nimport { resizeImage } from './util';\n\nexport interface IFrameInferenceResult {\n facesAndLandmarks: FacesAndLandmarks;\n gesture: Float32Array;\n motion: number;\n skipped: boolean;\n timestamp: number;\n}\n\nexport interface IPipeline {\n onFrame(\n timestamp: number,\n maskNeeded?: boolean,\n videoElement?: HTMLVideoElement\n ): Promise<IFrameInferenceResult>;\n isLoaded(): boolean;\n load(): Promise<void>;\n destroy(): void;\n}\n\nexport class Pipeline implements IPipeline {\n private generator?: MaskGenerator;\n private renderer?: LadonRenderer;\n private loaded = false;\n\n private inputCanvasCtx: CanvasRenderingContext2D;\n private lastMaskResult?: LadonOutput;\n\n private frameQueue: Array<{ timestamp: number; frameData: FrameData }> = [];\n private maskQueue: Array<{ timestamp: number; maskResult: LadonOutput }> = [];\n\n constructor(\n private inputCanvas: HTMLCanvasElement,\n private outputCanvas: HTMLCanvasElement,\n public readonly config: PipelineConfig,\n private readonly videoElement?: HTMLVideoElement\n ) {\n const inputCanvasCtx = this.inputCanvas.getContext('2d', {\n alpha: false,\n willReadFrequently: true,\n });\n\n if (!inputCanvasCtx) {\n throw new Error('[ladon-ts] - error getting input context 2d');\n }\n this.inputCanvasCtx = inputCanvasCtx;\n }\n\n /**\n * Processes a single frame and returns the inference result.\n *\n * @param timestamp - The timestamp of the frame.\n * @param [performInference=true] - Flag to perform mask inference.\n * @returns The result of the frame processing.\n * @throws If the pipeline (generator or renderer) is not loaded.\n */\n public async onFrame(\n timestamp: number,\n performInference = true\n ): Promise<IFrameInferenceResult> {\n if (!this.generator || !this.renderer) {\n throw new Error('[ladon-ts] - pipeline is not loaded.');\n }\n\n // Get the current frame (raw image data or video element)\n const frameData = this.getInputFrameData(performInference);\n\n // Add the frame to the queue with its timestamp\n this.frameQueue.push({ timestamp, frameData });\n\n if (performInference || !this.lastMaskResult) {\n // Perform inference and add the new mask to the mask queue\n const rawImageData = frameData as Uint8ClampedArray;\n const maskImageData = this.getMaskImageData(rawImageData);\n const maskResult = await this.generator.getLadonOutput(maskImageData, timestamp);\n // Add the mask to the queue and use the mask timestamp to sync frames and masks.\n this.maskQueue.push({ timestamp: maskResult.timestamp, maskResult });\n this.lastMaskResult = maskResult;\n\n // Sync frames and masks to render together\n await this.renderSyncedFrameAndMask();\n\n // Post-process the mask after rendering\n await this.generator.postRender(maskImageData, timestamp);\n } else {\n // Skipping inference. Update the last mask result's timestamp to match the current frame.\n this.maskQueue.push({ timestamp, maskResult: this.lastMaskResult });\n // Sync frames and masks to render together\n await this.renderSyncedFrameAndMask();\n }\n\n // Return the inference result\n return this.createInferenceResult(timestamp, performInference);\n }\n\n /**\n * Synchronizes frames and masks to ensure they are rendered together.\n */\n private async renderSyncedFrameAndMask(): Promise<void> {\n while (this.frameQueue.length > 0 && this.maskQueue.length > 0) {\n const frame = this.frameQueue[0];\n const maskEntry = this.maskQueue[0];\n\n if (frame.timestamp === maskEntry.timestamp) {\n // Render the frame and mask together\n await this.renderer?.render(frame.frameData, maskEntry.maskResult);\n this.frameQueue.shift();\n this.maskQueue.shift();\n } else if (frame.timestamp < maskEntry.timestamp) {\n // Discard the older frame\n this.frameQueue.shift();\n } else {\n // Discard the older mask\n this.maskQueue.shift();\n }\n }\n }\n\n /**\n * Gets the raw image data from the input canvas context.\n *\n * @param needFreshImageData - Flag to indicate if fresh image data is needed.\n *\n * @returns The raw image data.\n */\n private getInputFrameData(needFreshImageData: boolean): FrameData {\n if (needFreshImageData || !this.videoElement) {\n return this.inputCanvasCtx.getImageData(\n 0,\n 0,\n this.config.input.width,\n this.config.input.height\n ).data;\n }\n\n return this.videoElement;\n }\n\n /**\n * Resizes the image data if the model expects a fixed size input.\n *\n * @param {Uint8ClampedArray} rawImageData - The raw image data.\n * @returns {Uint8ClampedArray} - The processed mask image data.\n */\n private getMaskImageData(rawImageData: Uint8ClampedArray): Uint8ClampedArray {\n // Check if resizing is needed based on configuration.\n if (this.config.mask.inputSize.width === this.config.input.width) {\n return rawImageData;\n }\n\n // Resize the image data.\n return resizeImage(\n rawImageData,\n this.config.input.width,\n this.config.input.height,\n this.config.mask.inputSize.width,\n this.config.mask.inputSize.height\n );\n }\n\n /**\n * Creates the inference result object.\n *\n * @param {number} timestamp - The timestamp of the frame.\n * @param {boolean} performedInference - Indicates if the inference was performed.\n * @returns {IFrameInferenceResult} - The result object containing inference details.\n */\n private createInferenceResult(\n timestamp: number,\n performedInference: boolean\n ): IFrameInferenceResult {\n if (!this.lastMaskResult) {\n return {\n facesAndLandmarks: { data: new Float32Array(0), dims: [] },\n gesture: new Float32Array(0),\n motion: 0,\n skipped: true,\n timestamp,\n };\n }\n\n return {\n facesAndLandmarks: this.lastMaskResult.facesAndLandmarks,\n gesture: this.lastMaskResult.gesture,\n motion: this.lastMaskResult.motion,\n skipped: !performedInference,\n timestamp,\n };\n }\n\n /**\n * Checks if the pipeline is loaded.\n *\n * @returns True if the pipeline is loaded, false otherwise.\n */\n public isLoaded(): boolean {\n return this.loaded;\n }\n\n /**\n * Loads the pipeline components such as the generator and renderer.\n */\n public async load(): Promise<void> {\n switch (this.config.render.type) {\n case 'blur':\n this.renderer = new BlurRenderer(this.outputCanvas, this.config);\n break;\n case 'passthrough':\n this.renderer = new PassthroughRenderer(this.outputCanvas, this.config);\n break;\n case 'replacement':\n this.renderer = new ReplacementRenderer(this.outputCanvas, this.config);\n break;\n default:\n throw new Error('[ladon-ts] - renderer not implemented.');\n }\n\n await this.renderer.load();\n\n if (this.config.render.type === 'passthrough') {\n // automatically disable model evaluation when the renderer is set to passthrough\n // Note: this may change when gestures are detected (model eval will be a dependency for more than rendering)\n this.generator = new NullGenerator(this.config);\n } else {\n switch (this.config.mask.generator) {\n case 'local':\n this.generator = new LocalGenerator(this.config);\n break;\n case 'worker':\n this.generator = new WorkerGenerator(this.config);\n break;\n default:\n throw new Error('[ladon-ts] - generator not implemented.');\n }\n }\n\n await this.generator.load();\n\n this.loaded = true;\n }\n\n /**\n * Resets the frame and mask queues.\n */\n private resetQueues(): void {\n this.frameQueue = [];\n this.maskQueue = [];\n }\n\n public reset(): void {\n this.resetQueues();\n this.lastMaskResult = undefined;\n }\n\n /**\n * Destroys the pipeline and cleans up resources.\n */\n public destroy(): void {\n this.reset();\n this.generator?.destroy();\n this.renderer?.destroy();\n }\n}\n"],"names":["Pipeline","inputCanvas","outputCanvas","config","videoElement","inputCanvasCtx","timestamp","performInference","frameData","rawImageData","maskImageData","maskResult","frame","maskEntry","_a","needFreshImageData","resizeImage","performedInference","BlurRenderer","PassthroughRenderer","ReplacementRenderer","NullGenerator","LocalGenerator","WorkerGenerator","_b"],"mappings":";;;;;AAgCO,MAAMA,EAA8B;AAAA,EAWvC,YACYC,GACAC,GACQC,GACCC,GACnB;AAJU,SAAA,cAAAH,GACA,KAAA,eAAAC,GACQ,KAAA,SAAAC,GACC,KAAA,eAAAC,GAZrB,KAAQ,SAAS,IAKjB,KAAQ,aAAiE,CAAC,GAC1E,KAAQ,YAAmE,CAAC;AAQxE,UAAMC,IAAiB,KAAK,YAAY,WAAW,MAAM;AAAA,MACrD,OAAO;AAAA,MACP,oBAAoB;AAAA,IAAA,CACvB;AAED,QAAI,CAACA;AACK,YAAA,IAAI,MAAM,6CAA6C;AAEjE,SAAK,iBAAiBA;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAW1B,MAAa,QACTC,GACAC,IAAmB,IACW;AAC9B,QAAI,CAAC,KAAK,aAAa,CAAC,KAAK;AACnB,YAAA,IAAI,MAAM,sCAAsC;AAIpD,UAAAC,IAAY,KAAK,kBAAkBD,CAAgB;AAKrD,QAFJ,KAAK,WAAW,KAAK,EAAE,WAAAD,GAAW,WAAAE,GAAW,GAEzCD,KAAoB,CAAC,KAAK,gBAAgB;AAE1C,YAAME,IAAeD,GACfE,IAAgB,KAAK,iBAAiBD,CAAY,GAClDE,IAAa,MAAM,KAAK,UAAU,eAAeD,GAAeJ,CAAS;AAE/E,WAAK,UAAU,KAAK,EAAE,WAAWK,EAAW,WAAW,YAAAA,GAAY,GACnE,KAAK,iBAAiBA,GAGtB,MAAM,KAAK,yBAAyB,GAGpC,MAAM,KAAK,UAAU,WAAWD,GAAeJ,CAAS;AAAA,IAAA;AAGxD,WAAK,UAAU,KAAK,EAAE,WAAAA,GAAW,YAAY,KAAK,gBAAgB,GAElE,MAAM,KAAK,yBAAyB;AAIjC,WAAA,KAAK,sBAAsBA,GAAWC,CAAgB;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA,EAMjE,MAAc,2BAA0C;;AACpD,WAAO,KAAK,WAAW,SAAS,KAAK,KAAK,UAAU,SAAS,KAAG;AACtD,YAAAK,IAAQ,KAAK,WAAW,CAAC,GACzBC,IAAY,KAAK,UAAU,CAAC;AAE9B,MAAAD,EAAM,cAAcC,EAAU,aAE9B,QAAMC,IAAA,KAAK,aAAL,gBAAAA,EAAe,OAAOF,EAAM,WAAWC,EAAU,cACvD,KAAK,WAAW,MAAM,GACtB,KAAK,UAAU,MAAM,KACdD,EAAM,YAAYC,EAAU,YAEnC,KAAK,WAAW,MAAM,IAGtB,KAAK,UAAU,MAAM;AAAA,IACzB;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUI,kBAAkBE,GAAwC;AAC1D,WAAAA,KAAsB,CAAC,KAAK,eACrB,KAAK,eAAe;AAAA,MACvB;AAAA,MACA;AAAA,MACA,KAAK,OAAO,MAAM;AAAA,MAClB,KAAK,OAAO,MAAM;AAAA,IAAA,EACpB,OAGC,KAAK;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASR,iBAAiBN,GAAoD;AAErE,WAAA,KAAK,OAAO,KAAK,UAAU,UAAU,KAAK,OAAO,MAAM,QAChDA,IAIJO;AAAA,MACHP;AAAA,MACA,KAAK,OAAO,MAAM;AAAA,MAClB,KAAK,OAAO,MAAM;AAAA,MAClB,KAAK,OAAO,KAAK,UAAU;AAAA,MAC3B,KAAK,OAAO,KAAK,UAAU;AAAA,IAC/B;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUI,sBACJH,GACAW,GACqB;AACjB,WAAC,KAAK,iBAUH;AAAA,MACH,mBAAmB,KAAK,eAAe;AAAA,MACvC,SAAS,KAAK,eAAe;AAAA,MAC7B,QAAQ,KAAK,eAAe;AAAA,MAC5B,SAAS,CAACA;AAAA,MACV,WAAAX;AAAA,IACJ,IAfW;AAAA,MACH,mBAAmB,EAAE,MAAM,IAAI,aAAa,CAAC,GAAG,MAAM,GAAG;AAAA,MACzD,SAAS,IAAI,aAAa,CAAC;AAAA,MAC3B,QAAQ;AAAA,MACR,SAAS;AAAA,MACT,WAAAA;AAAA,IACJ;AAAA,EASJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQG,WAAoB;AACvB,WAAO,KAAK;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA,EAMhB,MAAa,OAAsB;AACvB,YAAA,KAAK,OAAO,OAAO,MAAM;AAAA,MAC7B,KAAK;AACD,aAAK,WAAW,IAAIY,EAAa,KAAK,cAAc,KAAK,MAAM;AAC/D;AAAA,MACJ,KAAK;AACD,aAAK,WAAW,IAAIC,EAAoB,KAAK,cAAc,KAAK,MAAM;AACtE;AAAA,MACJ,KAAK;AACD,aAAK,WAAW,IAAIC,EAAoB,KAAK,cAAc,KAAK,MAAM;AACtE;AAAA,MACJ;AACU,cAAA,IAAI,MAAM,wCAAwC;AAAA,IAAA;AAKhE,QAFM,MAAA,KAAK,SAAS,KAAK,GAErB,KAAK,OAAO,OAAO,SAAS;AAG5B,WAAK,YAAY,IAAIC,EAAc,KAAK,MAAM;AAAA;AAEtC,cAAA,KAAK,OAAO,KAAK,WAAW;AAAA,QAChC,KAAK;AACD,eAAK,YAAY,IAAIC,EAAe,KAAK,MAAM;AAC/C;AAAA,QACJ,KAAK;AACD,eAAK,YAAY,IAAIC,EAAgB,KAAK,MAAM;AAChD;AAAA,QACJ;AACU,gBAAA,IAAI,MAAM,yCAAyC;AAAA,MAAA;AAI/D,UAAA,KAAK,UAAU,KAAK,GAE1B,KAAK,SAAS;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA,EAMV,cAAoB;AACxB,SAAK,aAAa,CAAC,GACnB,KAAK,YAAY,CAAC;AAAA,EAAA;AAAA,EAGf,QAAc;AACjB,SAAK,YAAY,GACjB,KAAK,iBAAiB;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA,EAMnB,UAAgB;;AACnB,SAAK,MAAM,IACXT,IAAA,KAAK,cAAL,QAAAA,EAAgB,YAChBU,IAAA,KAAK,aAAL,QAAAA,EAAe;AAAA,EAAQ;AAE/B;"}
1
+ {"version":3,"file":"pipeline.js","sources":["../../../src/lib/pipeline.ts"],"sourcesContent":["import { PipelineConfig } from './config-types';\nimport {\n FacesAndLandmarks,\n FrameData,\n LadonOutput,\n LocalGenerator,\n MaskGenerator,\n WorkerGenerator,\n} from './generator';\nimport { BlurRenderer, LadonRenderer, PassthroughRenderer, ReplacementRenderer } from './renderer';\nimport { resizeImage } from './util';\n\nexport interface IFrameInferenceResult {\n facesAndLandmarks: FacesAndLandmarks;\n gesture: Float32Array;\n motion: number;\n skipped: boolean;\n timestamp: number;\n}\n\nexport interface IPipeline {\n onFrame(timestamp: number, maskNeeded?: boolean): Promise<IFrameInferenceResult>;\n isLoaded(): boolean;\n load(): Promise<void>;\n destroy(): void;\n}\n\nexport class Pipeline implements IPipeline {\n private generator?: MaskGenerator;\n private renderer?: LadonRenderer;\n private loaded = false;\n\n private inputCanvasCtx: CanvasRenderingContext2D;\n private lastMaskResult?: LadonOutput;\n\n private frameQueue: Array<{ timestamp: number; frameData: FrameData }> = [];\n private maskQueue: Array<{ timestamp: number; maskResult: LadonOutput }> = [];\n\n constructor(\n private inputCanvas: HTMLCanvasElement,\n private outputCanvas: HTMLCanvasElement,\n public readonly config: PipelineConfig,\n private readonly videoElement?: HTMLVideoElement\n ) {\n const inputCanvasCtx = this.inputCanvas.getContext('2d', {\n alpha: false,\n willReadFrequently: true,\n });\n\n if (!inputCanvasCtx) {\n throw new Error('[ladon-ts] - error getting input context 2d');\n }\n this.inputCanvasCtx = inputCanvasCtx;\n }\n\n /**\n * Processes a single frame and returns the inference result.\n *\n * @param timestamp - The timestamp of the frame.\n * @param performInference - Flag to perform mask inference.\n * @returns The result of the frame processing.\n * @throws If the pipeline (generator or renderer) is not loaded.\n */\n public async onFrame(\n timestamp: number,\n performInference = true\n ): Promise<IFrameInferenceResult> {\n if (!this.generator || !this.renderer) {\n throw new Error('[ladon-ts] - pipeline is not loaded.');\n }\n\n // Get the current frame (raw image data or video element)\n const frameData = this.getInputFrameData(performInference);\n\n // Add the frame to the queue with its timestamp\n this.frameQueue.push({ timestamp, frameData });\n\n if (performInference || !this.lastMaskResult) {\n // Perform inference and add the new mask to the mask queue\n const rawImageData = frameData as Uint8ClampedArray;\n const maskImageData = this.getMaskImageData(rawImageData);\n const maskResult = await this.generator.getLadonOutput(maskImageData, timestamp);\n // Add the mask to the queue and use the mask timestamp to sync frames and masks.\n this.maskQueue.push({ timestamp: maskResult.timestamp, maskResult });\n this.lastMaskResult = maskResult;\n\n // Sync frames and masks to render together\n await this.renderSyncedFrameAndMask();\n\n // Post-process the mask after rendering\n await this.generator.postRender(maskImageData, timestamp);\n } else {\n // Skipping inference. Update the last mask result's timestamp to match the current frame.\n this.maskQueue.push({ timestamp, maskResult: this.lastMaskResult });\n // Sync frames and masks to render together\n await this.renderSyncedFrameAndMask();\n }\n\n // Return the inference result\n return this.createInferenceResult(timestamp, performInference);\n }\n\n /**\n * Synchronizes frames and masks to ensure they are rendered together.\n */\n private async renderSyncedFrameAndMask(): Promise<void> {\n while (this.frameQueue.length > 0 && this.maskQueue.length > 0) {\n const frame = this.frameQueue[0];\n const maskEntry = this.maskQueue[0];\n\n if (frame.timestamp === maskEntry.timestamp) {\n // Render the frame and mask together\n await this.renderer?.render(frame.frameData, maskEntry.maskResult);\n this.frameQueue.shift();\n this.maskQueue.shift();\n } else if (frame.timestamp < maskEntry.timestamp) {\n // Discard the older frame\n this.frameQueue.shift();\n } else {\n // Discard the older mask\n this.maskQueue.shift();\n }\n }\n }\n\n /**\n * Gets the raw image data from the input canvas context.\n *\n * @param needFreshImageData - Flag to indicate if fresh image data is needed.\n *\n * @returns The raw image data.\n */\n private getInputFrameData(needFreshImageData: boolean): FrameData {\n if (needFreshImageData || !this.videoElement) {\n return this.inputCanvasCtx.getImageData(\n 0,\n 0,\n this.config.input.width,\n this.config.input.height\n ).data;\n }\n\n return this.videoElement;\n }\n\n /**\n * Resizes the image data if the model expects a fixed size input.\n *\n * @param {Uint8ClampedArray} rawImageData - The raw image data.\n * @returns {Uint8ClampedArray} - The processed mask image data.\n */\n private getMaskImageData(rawImageData: Uint8ClampedArray): Uint8ClampedArray {\n // Check if resizing is needed based on configuration.\n if (this.config.mask.inputSize.width === this.config.input.width) {\n return rawImageData;\n }\n\n // Resize the image data.\n return resizeImage(\n rawImageData,\n this.config.input.width,\n this.config.input.height,\n this.config.mask.inputSize.width,\n this.config.mask.inputSize.height\n );\n }\n\n /**\n * Creates the inference result object.\n *\n * @param {number} timestamp - The timestamp of the frame.\n * @param {boolean} performedInference - Indicates if the inference was performed.\n * @returns {IFrameInferenceResult} - The result object containing inference details.\n */\n private createInferenceResult(\n timestamp: number,\n performedInference: boolean\n ): IFrameInferenceResult {\n if (!this.lastMaskResult) {\n return {\n facesAndLandmarks: { data: new Float32Array(0), dims: [] },\n gesture: new Float32Array(0),\n motion: 0,\n skipped: true,\n timestamp,\n };\n }\n\n return {\n facesAndLandmarks: this.lastMaskResult.facesAndLandmarks,\n gesture: this.lastMaskResult.gesture,\n motion: this.lastMaskResult.motion,\n skipped: !performedInference,\n timestamp,\n };\n }\n\n /**\n * Checks if the pipeline is loaded.\n *\n * @returns True if the pipeline is loaded, false otherwise.\n */\n public isLoaded(): boolean {\n return this.loaded;\n }\n\n /**\n * Loads the pipeline components such as the generator and renderer.\n */\n public async load(): Promise<void> {\n switch (this.config.render.type) {\n case 'blur':\n this.renderer = new BlurRenderer(this.outputCanvas, this.config);\n break;\n case 'passthrough':\n this.renderer = new PassthroughRenderer(this.outputCanvas, this.config);\n break;\n case 'replacement':\n this.renderer = new ReplacementRenderer(this.outputCanvas, this.config);\n break;\n default:\n throw new Error('[ladon-ts] - renderer not implemented.');\n }\n\n await this.renderer.load();\n\n switch (this.config.mask.generator) {\n case 'local':\n this.generator = new LocalGenerator(this.config);\n break;\n case 'worker':\n this.generator = new WorkerGenerator(this.config);\n break;\n default:\n throw new Error('[ladon-ts] - generator not implemented.');\n }\n\n await this.generator.load();\n\n this.loaded = true;\n }\n\n /**\n * Resets the frame and mask queues.\n */\n private resetQueues(): void {\n this.frameQueue = [];\n this.maskQueue = [];\n }\n\n public reset(): void {\n this.resetQueues();\n this.lastMaskResult = undefined;\n }\n\n /**\n * Destroys the pipeline and cleans up resources.\n */\n public destroy(): void {\n this.reset();\n this.generator?.destroy();\n this.renderer?.destroy();\n }\n}\n"],"names":["Pipeline","inputCanvas","outputCanvas","config","videoElement","inputCanvasCtx","timestamp","performInference","frameData","rawImageData","maskImageData","maskResult","frame","maskEntry","_a","needFreshImageData","resizeImage","performedInference","BlurRenderer","PassthroughRenderer","ReplacementRenderer","LocalGenerator","WorkerGenerator","_b"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import { PipelineConfig } from '../config-types';
2
- import { FrameData, LadonOutput } from '../generator';
2
+ import { FrameData } from '../generator';
3
3
  import { LadonRenderer } from './ladon-renderer';
4
4
  import { WebGLRenderer } from './webgl-renderer';
5
5
 
@@ -9,7 +9,7 @@ export declare class PassthroughRenderer extends WebGLRenderer implements LadonR
9
9
  private program;
10
10
  private fragment_shader;
11
11
  constructor(output_canvas: HTMLCanvasElement, config: PipelineConfig);
12
- render(input: FrameData, _: LadonOutput): Promise<void>;
12
+ render(input: FrameData): Promise<void>;
13
13
  load(): Promise<void>;
14
14
  destroy(): void;
15
15
  }
@@ -24,7 +24,7 @@ void main() {
24
24
  );
25
25
  this.program = o(this.gl, e, i), this.gl.useProgram(this.program), this.setSharedUniforms(this.program);
26
26
  }
27
- async render(r, s) {
27
+ async render(r) {
28
28
  this.uploadVideoStream(r), this.gl.useProgram(this.program), this.gl.drawArrays(this.gl.TRIANGLES, 0, this.verts.length / 3), this.postDraw();
29
29
  }
30
30
  async load() {
@@ -1 +1 @@
1
- {"version":3,"file":"passthrough-renderer.js","sources":["../../../../src/lib/renderer/passthrough-renderer.ts"],"sourcesContent":["import { PipelineConfig } from '../config-types';\nimport { FrameData, LadonOutput } from '../generator';\nimport { compileShader, linkProgram } from '../util';\n\nimport { LadonRenderer } from './ladon-renderer';\nimport { WebGLRenderer } from './webgl-renderer';\n\nexport class PassthroughRenderer extends WebGLRenderer implements LadonRenderer {\n private program: WebGLProgram;\n\n private fragment_shader = `#version 300 es\nprecision highp float;\n\nout vec4 outColor;\n\nuniform sampler2D u_image;\nuniform vec2 u_resolution;\n\n\nvoid main() {\n ${this.getUVCalculation()}\n\n outColor = vec4(texture(u_image, st).rgb, 1.0);\n}\n`;\n\n constructor(public output_canvas: HTMLCanvasElement, public readonly config: PipelineConfig) {\n super(output_canvas, config);\n\n const vertex_shader = compileShader(this.gl, this.gl.VERTEX_SHADER, this.vertex_shader_src);\n const fragment_shader = compileShader(\n this.gl,\n this.gl.FRAGMENT_SHADER,\n this.fragment_shader\n );\n\n this.program = linkProgram(this.gl, vertex_shader, fragment_shader);\n this.gl.useProgram(this.program);\n\n this.setSharedUniforms(this.program);\n }\n\n public async render(\n input: FrameData,\n /* eslint-disable-next-line @typescript-eslint/no-unused-vars */\n _: LadonOutput\n ): Promise<void> {\n this.uploadVideoStream(input);\n\n this.gl.useProgram(this.program);\n\n this.gl.drawArrays(this.gl.TRIANGLES, 0, this.verts.length / 3);\n\n this.postDraw();\n }\n\n public async load(): Promise<void> {\n // empty\n }\n\n public destroy(): void {\n // empty\n }\n}\n"],"names":["PassthroughRenderer","WebGLRenderer","output_canvas","config","vertex_shader","compileShader","fragment_shader","linkProgram","input","_"],"mappings":";;AAOO,MAAMA,UAA4BC,EAAuC;AAAA,EAmB5E,YAAmBC,GAAkDC,GAAwB;AACzF,UAAMD,GAAeC,CAAM,GADZ,KAAA,gBAAAD,GAAkD,KAAA,SAAAC,GAhBrE,KAAQ,kBAAkB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAUxB,KAAK,iBAAkB,CAAA;AAAA;AAAA;AAAA;AAAA;AASf,UAAAC,IAAgBC,EAAc,KAAK,IAAI,KAAK,GAAG,eAAe,KAAK,iBAAiB,GACpFC,IAAkBD;AAAA,MACpB,KAAK;AAAA,MACL,KAAK,GAAG;AAAA,MACR,KAAK;AAAA,IACT;AAEA,SAAK,UAAUE,EAAY,KAAK,IAAIH,GAAeE,CAAe,GAC7D,KAAA,GAAG,WAAW,KAAK,OAAO,GAE1B,KAAA,kBAAkB,KAAK,OAAO;AAAA,EAAA;AAAA,EAGvC,MAAa,OACTE,GAEAC,GACa;AACb,SAAK,kBAAkBD,CAAK,GAEvB,KAAA,GAAG,WAAW,KAAK,OAAO,GAE1B,KAAA,GAAG,WAAW,KAAK,GAAG,WAAW,GAAG,KAAK,MAAM,SAAS,CAAC,GAE9D,KAAK,SAAS;AAAA,EAAA;AAAA,EAGlB,MAAa,OAAsB;AAAA,EAAA;AAAA,EAI5B,UAAgB;AAAA,EAAA;AAG3B;"}
1
+ {"version":3,"file":"passthrough-renderer.js","sources":["../../../../src/lib/renderer/passthrough-renderer.ts"],"sourcesContent":["import { PipelineConfig } from '../config-types';\nimport { FrameData } from '../generator';\nimport { compileShader, linkProgram } from '../util';\n\nimport { LadonRenderer } from './ladon-renderer';\nimport { WebGLRenderer } from './webgl-renderer';\n\nexport class PassthroughRenderer extends WebGLRenderer implements LadonRenderer {\n private program: WebGLProgram;\n\n private fragment_shader = `#version 300 es\nprecision highp float;\n\nout vec4 outColor;\n\nuniform sampler2D u_image;\nuniform vec2 u_resolution;\n\n\nvoid main() {\n ${this.getUVCalculation()}\n\n outColor = vec4(texture(u_image, st).rgb, 1.0);\n}\n`;\n\n constructor(public output_canvas: HTMLCanvasElement, public readonly config: PipelineConfig) {\n super(output_canvas, config);\n\n const vertex_shader = compileShader(this.gl, this.gl.VERTEX_SHADER, this.vertex_shader_src);\n const fragment_shader = compileShader(\n this.gl,\n this.gl.FRAGMENT_SHADER,\n this.fragment_shader\n );\n\n this.program = linkProgram(this.gl, vertex_shader, fragment_shader);\n this.gl.useProgram(this.program);\n\n this.setSharedUniforms(this.program);\n }\n\n public async render(input: FrameData): Promise<void> {\n this.uploadVideoStream(input);\n\n this.gl.useProgram(this.program);\n\n this.gl.drawArrays(this.gl.TRIANGLES, 0, this.verts.length / 3);\n\n this.postDraw();\n }\n\n public async load(): Promise<void> {\n // empty\n }\n\n public destroy(): void {\n // empty\n }\n}\n"],"names":["PassthroughRenderer","WebGLRenderer","output_canvas","config","vertex_shader","compileShader","fragment_shader","linkProgram","input"],"mappings":";;AAOO,MAAMA,UAA4BC,EAAuC;AAAA,EAmB5E,YAAmBC,GAAkDC,GAAwB;AACzF,UAAMD,GAAeC,CAAM,GADZ,KAAA,gBAAAD,GAAkD,KAAA,SAAAC,GAhBrE,KAAQ,kBAAkB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAUxB,KAAK,iBAAkB,CAAA;AAAA;AAAA;AAAA;AAAA;AASf,UAAAC,IAAgBC,EAAc,KAAK,IAAI,KAAK,GAAG,eAAe,KAAK,iBAAiB,GACpFC,IAAkBD;AAAA,MACpB,KAAK;AAAA,MACL,KAAK,GAAG;AAAA,MACR,KAAK;AAAA,IACT;AAEA,SAAK,UAAUE,EAAY,KAAK,IAAIH,GAAeE,CAAe,GAC7D,KAAA,GAAG,WAAW,KAAK,OAAO,GAE1B,KAAA,kBAAkB,KAAK,OAAO;AAAA,EAAA;AAAA,EAGvC,MAAa,OAAOE,GAAiC;AACjD,SAAK,kBAAkBA,CAAK,GAEvB,KAAA,GAAG,WAAW,KAAK,OAAO,GAE1B,KAAA,GAAG,WAAW,KAAK,GAAG,WAAW,GAAG,KAAK,MAAM,SAAS,CAAC,GAE9D,KAAK,SAAS;AAAA,EAAA;AAAA,EAGlB,MAAa,OAAsB;AAAA,EAAA;AAAA,EAI5B,UAAgB;AAAA,EAAA;AAG3B;"}
@@ -17,7 +17,7 @@ export declare abstract class WebGLRenderer {
17
17
  constructor(output_canvas: HTMLCanvasElement, config: PipelineConfig);
18
18
  protected initTexturesAndBuffers(): void;
19
19
  protected createTexture(internalFormat: number, width: number, height: number, initializeTexture?: TextureInitializer): WebGLTexture;
20
- protected getUVCalculation(): "vec2 st = vec2(1.0 - gl_FragCoord.x / u_resolution.x, gl_FragCoord.y / u_resolution.y);" | "vec2 st = vec2(gl_FragCoord.x / u_resolution.x, 1.0 - gl_FragCoord.y / u_resolution.y);";
20
+ protected getUVCalculation(): "vec2 st = vec2(1.0 - gl_FragCoord.x / u_resolution.x, 1.0 - gl_FragCoord.y / u_resolution.y);" | "vec2 st = vec2(gl_FragCoord.x / u_resolution.x, 1.0 - gl_FragCoord.y / u_resolution.y);";
21
21
  protected setSharedUniforms(program: WebGLProgram): void;
22
22
  protected uploadVideoStream(input: FrameData): void;
23
23
  protected uploadMask(mask?: LadonOutput): void;
@@ -44,7 +44,7 @@ uniform vec2 u_resolution;
44
44
  `, this.shared_shader_functions = `
45
45
  float get_mask(vec2 uv) {
46
46
  float maskValue = texture(u_mask, uv).r;
47
- return smoothstep(0.0, 1.0, maskValue);
47
+ return smoothstep(0.0, 1.0, maskValue) ( );
48
48
  }
49
49
  `;
50
50
  const e = this.output_canvas.getContext("webgl2", { antialias: !0 });
@@ -102,7 +102,7 @@ float get_mask(vec2 uv) {
102
102
  return this.gl.bindTexture(this.gl.TEXTURE_2D, r), this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MIN_FILTER, this.gl.LINEAR), this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MAG_FILTER, this.gl.LINEAR), this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_S, this.gl.CLAMP_TO_EDGE), this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_T, this.gl.CLAMP_TO_EDGE), s(), this.gl.bindTexture(this.gl.TEXTURE_2D, null), r;
103
103
  }
104
104
  getUVCalculation() {
105
- return this.config.render.horizontalMirror ? "vec2 st = vec2(1.0 - gl_FragCoord.x / u_resolution.x, gl_FragCoord.y / u_resolution.y);" : "vec2 st = vec2(gl_FragCoord.x / u_resolution.x, 1.0 - gl_FragCoord.y / u_resolution.y);";
105
+ return this.config.render.horizontalMirror ? "vec2 st = vec2(1.0 - gl_FragCoord.x / u_resolution.x, 1.0 - gl_FragCoord.y / u_resolution.y);" : "vec2 st = vec2(gl_FragCoord.x / u_resolution.x, 1.0 - gl_FragCoord.y / u_resolution.y);";
106
106
  }
107
107
  setSharedUniforms(t) {
108
108
  const i = this.gl.getUniformLocation(t, "u_resolution");
@@ -1 +1 @@
1
- {"version":3,"file":"webgl-renderer.js","sources":["../../../../src/lib/renderer/webgl-renderer.ts"],"sourcesContent":["// webgl-renderer.ts\n\nimport { PipelineConfig } from '../config-types';\nimport { FrameData, LadonOutput } from '../generator';\nimport { bilinearUpsample } from '../util';\n\ntype TextureInitializer = () => void;\nexport abstract class WebGLRenderer {\n protected intermediate_canvas?: HTMLCanvasElement;\n protected output_canvas_2d?: CanvasRenderingContext2D;\n\n protected gl: WebGL2RenderingContext;\n\n protected image_texture!: WebGLTexture;\n protected mask_texture!: WebGLTexture;\n\n protected verts = new Float32Array([\n -1.0,\n -1.0,\n 0.0, // Vertex 1\n -1.0,\n 1.0,\n 0.0, // Vertex 2\n 1.0,\n 1.0,\n 0.0, // Vertex 3\n 1.0,\n 1.0,\n 0.0, // Vertex 4\n 1.0,\n -1.0,\n 0.0, // Vertex 5\n -1.0,\n -1.0,\n 0.0, // Vertex 6\n ]);\n\n protected vertex_shader_src = `#version 300 es\n\nin vec4 position;\n\nvoid main() {\n gl_Position = position;\n}\n`;\n\n // Shared fragment shader code\n protected fragment_shader_header = `#version 300 es\nprecision highp float;\n\nout vec4 outColor;\n\nuniform sampler2D u_image;\nuniform sampler2D u_mask;\nuniform vec2 u_resolution;\n`;\n\n // Shared shader functions for enhanced edge blending\n protected shared_shader_functions = `\nfloat get_mask(vec2 uv) {\n float maskValue = texture(u_mask, uv).r;\n return smoothstep(0.0, 1.0, maskValue);\n}\n`;\n\n constructor(public output_canvas: HTMLCanvasElement, public readonly config: PipelineConfig) {\n const gl = this.output_canvas.getContext('webgl2', { antialias: true });\n\n if (!gl) {\n const output_2d = this.output_canvas.getContext('2d');\n\n if (!output_2d) {\n throw new Error('[ladon-ts] - output canvas context must be webgl2 or 2d');\n }\n\n this.output_canvas_2d = output_2d;\n this.intermediate_canvas = document.createElement('canvas');\n this.intermediate_canvas.height = this.config.input.height;\n this.intermediate_canvas.width = this.config.input.width;\n\n const gl_intermediate = this.intermediate_canvas.getContext('webgl2', {\n antialias: true,\n });\n\n if (!gl_intermediate) {\n throw new Error('[ladon-ts] - error getting output context webgl');\n }\n\n this.gl = gl_intermediate;\n } else {\n this.gl = gl;\n }\n\n // Initialize textures and buffers\n this.initTexturesAndBuffers();\n }\n\n protected initTexturesAndBuffers() {\n // Initialize image texture\n this.image_texture = this.createTexture(\n this.gl.RGBA,\n this.config.input.width,\n this.config.input.height\n );\n\n // Initialize mask texture\n this.mask_texture = this.createTexture(\n this.gl.R8,\n this.config.mask.upscaleSize.width,\n this.config.mask.upscaleSize.height\n );\n\n // Create and bind vertex array\n const vertex_array = this.gl.createVertexArray();\n if (!vertex_array) {\n throw new Error('[ladon-ts] - error creating vertex array');\n }\n this.gl.bindVertexArray(vertex_array);\n\n // Create and bind buffer\n const buffer = this.gl.createBuffer();\n if (!buffer) {\n throw new Error('[ladon-ts] - error creating buffer');\n }\n this.gl.bindBuffer(this.gl.ARRAY_BUFFER, buffer);\n this.gl.bufferData(this.gl.ARRAY_BUFFER, this.verts, this.gl.STATIC_DRAW);\n this.gl.vertexAttribPointer(0, 3, this.gl.FLOAT, false, 0, 0);\n this.gl.enableVertexAttribArray(0);\n\n this.gl.viewport(0, 0, this.config.input.width, this.config.input.height);\n }\n\n protected createTexture(\n internalFormat: number,\n width: number,\n height: number,\n initializeTexture: TextureInitializer = () => {\n // Default initializer creates an empty texture\n this.gl.texImage2D(\n this.gl.TEXTURE_2D,\n 0,\n internalFormat,\n width,\n height,\n 0,\n internalFormat === this.gl.RGBA ? this.gl.RGBA : this.gl.RED,\n this.gl.UNSIGNED_BYTE,\n null\n );\n }\n ): WebGLTexture {\n const texture = this.gl.createTexture();\n if (!texture) {\n throw new Error('[ladon-ts] - error creating texture');\n }\n\n this.gl.bindTexture(this.gl.TEXTURE_2D, texture);\n\n // Set texture parameters\n this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MIN_FILTER, this.gl.LINEAR);\n this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MAG_FILTER, this.gl.LINEAR);\n this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_S, this.gl.CLAMP_TO_EDGE);\n this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_T, this.gl.CLAMP_TO_EDGE);\n\n // Initialize the texture using the provided function\n initializeTexture();\n\n this.gl.bindTexture(this.gl.TEXTURE_2D, null);\n return texture;\n }\n\n protected getUVCalculation() {\n if (this.config.render.horizontalMirror) {\n return `vec2 st = vec2(1.0 - gl_FragCoord.x / u_resolution.x, gl_FragCoord.y / u_resolution.y);`;\n }\n\n return `vec2 st = vec2(gl_FragCoord.x / u_resolution.x, 1.0 - gl_FragCoord.y / u_resolution.y);`;\n }\n\n protected setSharedUniforms(program: WebGLProgram) {\n const u_resolution = this.gl.getUniformLocation(program, 'u_resolution');\n if (!u_resolution) {\n throw new Error('[ladon-ts] - error finding \"u_resolution\" uniform');\n }\n this.gl.uniform2f(u_resolution, this.config.input.width, this.config.input.height);\n\n const u_image = this.gl.getUniformLocation(program, 'u_image');\n if (!u_image) {\n throw new Error('[ladon-ts] - error finding \"u_image\" uniform');\n }\n this.gl.activeTexture(this.gl.TEXTURE0);\n this.gl.bindTexture(this.gl.TEXTURE_2D, this.image_texture);\n this.gl.uniform1i(u_image, 0);\n\n const u_mask = this.gl.getUniformLocation(program, 'u_mask');\n if (u_mask) {\n this.gl.activeTexture(this.gl.TEXTURE1);\n this.gl.bindTexture(this.gl.TEXTURE_2D, this.mask_texture);\n this.gl.uniform1i(u_mask, 1);\n }\n }\n\n protected uploadVideoStream(input: FrameData) {\n this.gl.activeTexture(this.gl.TEXTURE0);\n this.gl.bindTexture(this.gl.TEXTURE_2D, this.image_texture);\n\n // Upload video frame or image data to the texture\n if (input instanceof HTMLVideoElement) {\n this.gl.texImage2D(\n this.gl.TEXTURE_2D,\n 0,\n this.gl.RGBA,\n this.gl.RGBA,\n this.gl.UNSIGNED_BYTE,\n input\n );\n } else {\n this.gl.texImage2D(\n this.gl.TEXTURE_2D,\n 0,\n this.gl.RGBA,\n this.config.input.width,\n this.config.input.height,\n 0,\n this.gl.RGBA,\n this.gl.UNSIGNED_BYTE,\n input\n );\n }\n }\n\n protected uploadMask(mask?: LadonOutput) {\n // The mask may not be included if it has not been generated (e.g., frame skipped).\n if (mask?.warm) {\n const maskData = bilinearUpsample(\n mask.data,\n this.config.mask.outputSize.width,\n this.config.mask.outputSize.height,\n this.config.mask.upscaleSize.width,\n this.config.mask.upscaleSize.height\n );\n\n this.gl.activeTexture(this.gl.TEXTURE1);\n this.gl.bindTexture(this.gl.TEXTURE_2D, this.mask_texture);\n this.gl.texImage2D(\n this.gl.TEXTURE_2D,\n 0,\n this.gl.R8,\n this.config.mask.upscaleSize.width,\n this.config.mask.upscaleSize.height,\n 0,\n this.gl.RED,\n this.gl.UNSIGNED_BYTE,\n maskData\n );\n }\n }\n\n protected postDraw() {\n if (this.output_canvas_2d && this.intermediate_canvas) {\n this.output_canvas_2d.drawImage(\n this.intermediate_canvas,\n 0,\n 0,\n this.config.input.width,\n this.config.input.height\n );\n }\n }\n}\n"],"names":["WebGLRenderer","output_canvas","config","gl","output_2d","gl_intermediate","vertex_array","buffer","internalFormat","width","height","initializeTexture","texture","program","u_resolution","u_image","u_mask","input","mask","maskData","bilinearUpsample"],"mappings":"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"}
1
+ {"version":3,"file":"webgl-renderer.js","sources":["../../../../src/lib/renderer/webgl-renderer.ts"],"sourcesContent":["// webgl-renderer.ts\n\nimport { PipelineConfig } from '../config-types';\nimport { FrameData, LadonOutput } from '../generator';\nimport { bilinearUpsample } from '../util';\n\ntype TextureInitializer = () => void;\nexport abstract class WebGLRenderer {\n protected intermediate_canvas?: HTMLCanvasElement;\n protected output_canvas_2d?: CanvasRenderingContext2D;\n\n protected gl: WebGL2RenderingContext;\n\n protected image_texture!: WebGLTexture;\n protected mask_texture!: WebGLTexture;\n\n protected verts = new Float32Array([\n -1.0,\n -1.0,\n 0.0, // Vertex 1\n -1.0,\n 1.0,\n 0.0, // Vertex 2\n 1.0,\n 1.0,\n 0.0, // Vertex 3\n 1.0,\n 1.0,\n 0.0, // Vertex 4\n 1.0,\n -1.0,\n 0.0, // Vertex 5\n -1.0,\n -1.0,\n 0.0, // Vertex 6\n ]);\n\n protected vertex_shader_src = `#version 300 es\n\nin vec4 position;\n\nvoid main() {\n gl_Position = position;\n}\n`;\n\n // Shared fragment shader code\n protected fragment_shader_header = `#version 300 es\nprecision highp float;\n\nout vec4 outColor;\n\nuniform sampler2D u_image;\nuniform sampler2D u_mask;\nuniform vec2 u_resolution;\n`;\n\n // Shared shader functions for enhanced edge blending\n protected shared_shader_functions = `\nfloat get_mask(vec2 uv) {\n float maskValue = texture(u_mask, uv).r;\n return smoothstep(0.0, 1.0, maskValue) ( );\n}\n`;\n\n constructor(public output_canvas: HTMLCanvasElement, public readonly config: PipelineConfig) {\n const gl = this.output_canvas.getContext('webgl2', { antialias: true });\n\n if (!gl) {\n const output_2d = this.output_canvas.getContext('2d');\n\n if (!output_2d) {\n throw new Error('[ladon-ts] - output canvas context must be webgl2 or 2d');\n }\n\n this.output_canvas_2d = output_2d;\n this.intermediate_canvas = document.createElement('canvas');\n this.intermediate_canvas.height = this.config.input.height;\n this.intermediate_canvas.width = this.config.input.width;\n\n const gl_intermediate = this.intermediate_canvas.getContext('webgl2', {\n antialias: true,\n });\n\n if (!gl_intermediate) {\n throw new Error('[ladon-ts] - error getting output context webgl');\n }\n\n this.gl = gl_intermediate;\n } else {\n this.gl = gl;\n }\n\n // Initialize textures and buffers\n this.initTexturesAndBuffers();\n }\n\n protected initTexturesAndBuffers() {\n // Initialize image texture\n this.image_texture = this.createTexture(\n this.gl.RGBA,\n this.config.input.width,\n this.config.input.height\n );\n\n // Initialize mask texture\n this.mask_texture = this.createTexture(\n this.gl.R8,\n this.config.mask.upscaleSize.width,\n this.config.mask.upscaleSize.height\n );\n\n // Create and bind vertex array\n const vertex_array = this.gl.createVertexArray();\n if (!vertex_array) {\n throw new Error('[ladon-ts] - error creating vertex array');\n }\n this.gl.bindVertexArray(vertex_array);\n\n // Create and bind buffer\n const buffer = this.gl.createBuffer();\n if (!buffer) {\n throw new Error('[ladon-ts] - error creating buffer');\n }\n this.gl.bindBuffer(this.gl.ARRAY_BUFFER, buffer);\n this.gl.bufferData(this.gl.ARRAY_BUFFER, this.verts, this.gl.STATIC_DRAW);\n this.gl.vertexAttribPointer(0, 3, this.gl.FLOAT, false, 0, 0);\n this.gl.enableVertexAttribArray(0);\n\n this.gl.viewport(0, 0, this.config.input.width, this.config.input.height);\n }\n\n protected createTexture(\n internalFormat: number,\n width: number,\n height: number,\n initializeTexture: TextureInitializer = () => {\n // Default initializer creates an empty texture\n this.gl.texImage2D(\n this.gl.TEXTURE_2D,\n 0,\n internalFormat,\n width,\n height,\n 0,\n internalFormat === this.gl.RGBA ? this.gl.RGBA : this.gl.RED,\n this.gl.UNSIGNED_BYTE,\n null\n );\n }\n ): WebGLTexture {\n const texture = this.gl.createTexture();\n if (!texture) {\n throw new Error('[ladon-ts] - error creating texture');\n }\n\n this.gl.bindTexture(this.gl.TEXTURE_2D, texture);\n\n // Set texture parameters\n this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MIN_FILTER, this.gl.LINEAR);\n this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MAG_FILTER, this.gl.LINEAR);\n this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_S, this.gl.CLAMP_TO_EDGE);\n this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_T, this.gl.CLAMP_TO_EDGE);\n\n // Initialize the texture using the provided function\n initializeTexture();\n\n this.gl.bindTexture(this.gl.TEXTURE_2D, null);\n return texture;\n }\n\n protected getUVCalculation() {\n if (this.config.render.horizontalMirror) {\n // Flip both x and y coordinates when horizontal mirroring\n return `vec2 st = vec2(1.0 - gl_FragCoord.x / u_resolution.x, 1.0 - gl_FragCoord.y / u_resolution.y);`;\n }\n\n // Default behavior (no mirroring)\n return `vec2 st = vec2(gl_FragCoord.x / u_resolution.x, 1.0 - gl_FragCoord.y / u_resolution.y);`;\n }\n\n protected setSharedUniforms(program: WebGLProgram) {\n const u_resolution = this.gl.getUniformLocation(program, 'u_resolution');\n if (!u_resolution) {\n throw new Error('[ladon-ts] - error finding \"u_resolution\" uniform');\n }\n this.gl.uniform2f(u_resolution, this.config.input.width, this.config.input.height);\n\n const u_image = this.gl.getUniformLocation(program, 'u_image');\n if (!u_image) {\n throw new Error('[ladon-ts] - error finding \"u_image\" uniform');\n }\n this.gl.activeTexture(this.gl.TEXTURE0);\n this.gl.bindTexture(this.gl.TEXTURE_2D, this.image_texture);\n this.gl.uniform1i(u_image, 0);\n\n const u_mask = this.gl.getUniformLocation(program, 'u_mask');\n if (u_mask) {\n this.gl.activeTexture(this.gl.TEXTURE1);\n this.gl.bindTexture(this.gl.TEXTURE_2D, this.mask_texture);\n this.gl.uniform1i(u_mask, 1);\n }\n }\n\n protected uploadVideoStream(input: FrameData) {\n this.gl.activeTexture(this.gl.TEXTURE0);\n this.gl.bindTexture(this.gl.TEXTURE_2D, this.image_texture);\n\n // Upload video frame or image data to the texture\n if (input instanceof HTMLVideoElement) {\n this.gl.texImage2D(\n this.gl.TEXTURE_2D,\n 0,\n this.gl.RGBA,\n this.gl.RGBA,\n this.gl.UNSIGNED_BYTE,\n input\n );\n } else {\n this.gl.texImage2D(\n this.gl.TEXTURE_2D,\n 0,\n this.gl.RGBA,\n this.config.input.width,\n this.config.input.height,\n 0,\n this.gl.RGBA,\n this.gl.UNSIGNED_BYTE,\n input\n );\n }\n }\n\n protected uploadMask(mask?: LadonOutput) {\n // The mask may not be included if it has not been generated (e.g., frame skipped).\n if (mask?.warm) {\n const maskData = bilinearUpsample(\n mask.data,\n this.config.mask.outputSize.width,\n this.config.mask.outputSize.height,\n this.config.mask.upscaleSize.width,\n this.config.mask.upscaleSize.height\n );\n\n this.gl.activeTexture(this.gl.TEXTURE1);\n this.gl.bindTexture(this.gl.TEXTURE_2D, this.mask_texture);\n this.gl.texImage2D(\n this.gl.TEXTURE_2D,\n 0,\n this.gl.R8,\n this.config.mask.upscaleSize.width,\n this.config.mask.upscaleSize.height,\n 0,\n this.gl.RED,\n this.gl.UNSIGNED_BYTE,\n maskData\n );\n }\n }\n\n protected postDraw() {\n if (this.output_canvas_2d && this.intermediate_canvas) {\n this.output_canvas_2d.drawImage(\n this.intermediate_canvas,\n 0,\n 0,\n this.config.input.width,\n this.config.input.height\n );\n }\n }\n}\n"],"names":["WebGLRenderer","output_canvas","config","gl","output_2d","gl_intermediate","vertex_array","buffer","internalFormat","width","height","initializeTexture","texture","program","u_resolution","u_image","u_mask","input","mask","maskData","bilinearUpsample"],"mappings":"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"}
@@ -1 +1 @@
1
- export declare const LIB_VERSION = "5.0.3";
1
+ export declare const LIB_VERSION = "5.1.0";
@@ -1,4 +1,4 @@
1
- const o = "5.0.3";
1
+ const o = "5.1.0";
2
2
  export {
3
3
  o as LIB_VERSION
4
4
  };
@@ -1 +1 @@
1
- {"version":3,"file":"version.js","sources":["../../../src/lib/version.ts"],"sourcesContent":["export const LIB_VERSION = '5.0.3';\n"],"names":["LIB_VERSION"],"mappings":"AAAO,MAAMA,IAAc;"}
1
+ {"version":3,"file":"version.js","sources":["../../../src/lib/version.ts"],"sourcesContent":["export const LIB_VERSION = '5.1.0';\n"],"names":["LIB_VERSION"],"mappings":"AAAO,MAAMA,IAAc;"}
@@ -1938,8 +1938,8 @@
1938
1938
  return o(t2, e2), t2;
1939
1939
  };
1940
1940
  Object.defineProperty(t, "__esModule", { value: true }), t.WEBGL_OP_RESOLVE_RULES = void 0;
1941
- const a = n(8817), s = i(n(5194)), u = n(4752), l = n(6668), c2 = n(9754), p = n(5042), d = n(6742), f = n(4125), h = n(6149), g = n(5378), m = n(6981), b = n(7413), y = n(7006), w = n(8276), _ = n(5565), v = n(2834), x = n(1010), T2 = n(8126), S = n(2801), O = n(565), A = n(2444), E = n(815), I = n(564), $ = n(5416), P = n(1240), D = n(5944), k = n(5707), C = i(n(9087)), R = n(7862), M = n(3980);
1942
- t.WEBGL_OP_RESOLVE_RULES = [["Abs", "", "6+", C.abs], ["Acos", "", "7+", C.acos], ["Add", "", "7+", s.add], ["And", "", "7+", s.and], ["Asin", "", "7+", C.asin], ["Atan", "", "7+", C.atan], ["AveragePool", "", "7+", v.averagePool, v.parseAveragePoolAttributes], ["BatchNormalization", "", "7+", a.batchNormalization, a.parseBatchNormalizationAttributes], ["Cast", "", "6+", u.cast, u.parseCastAttributes], ["Ceil", "", "6+", C.ceil], ["Clip", "", "6-10", C.clip, C.parseClipAttributes], ["Clip", "", "11+", C.clipV11], ["Concat", "", "4+", l.concat, l.parseConcatAttributes], ["Conv", "", "1+", c2.conv, c2.parseConvAttributes], ["ConvTranspose", "", "1+", p.convTranspose, p.parseConvTransposeAttributes], ["Cos", "", "7+", C.cos], ["Div", "", "7+", s.div], ["Dropout", "", "7+", C.identity], ["DepthToSpace", "", "1+", d.depthToSpace, d.parseDepthToSpaceAttributes], ["Equal", "", "7+", s.equal], ["Elu", "", "6+", C.elu, C.parseEluAttributes], ["Exp", "", "6+", C.exp], ["Flatten", "", "1+", f.flatten, f.parseFlattenAttributes], ["Floor", "", "6+", C.floor], ["FusedConv", "com.microsoft", "1+", c2.conv, c2.parseConvAttributes], ["Gather", "", "1+", h.gather, h.parseGatherAttributes], ["Gemm", "", "7-10", g.gemm, g.parseGemmAttributesV7], ["Gemm", "", "11+", g.gemm, g.parseGemmAttributesV11], ["GlobalAveragePool", "", "1+", v.globalAveragePool, v.parseGlobalAveragePoolAttributes], ["GlobalMaxPool", "", "1+", v.globalMaxPool], ["Greater", "", "7+", s.greater], ["Identity", "", "1+", C.identity], ["ImageScaler", "", "1+", m.imageScaler, m.parseImageScalerAttributes], ["InstanceNormalization", "", "6+", b.instanceNormalization, b.parseInstanceNormalizationAttributes], ["LeakyRelu", "", "6+", C.leakyRelu, C.parseLeakyReluAttributes], ["Less", "", "7+", s.less], ["LRN", "", "1+", y.lrn, y.parseLrnAttributes], ["Log", "", "6+", C.log], ["MatMul", "", "1+", w.matMul, w.parseMatMulAttributes], ["MaxPool", "", "1+", v.maxPool, v.parseMaxPoolAttributes], ["Mul", "", "7+", s.mul], ["Neg", "", "6+", C.neg], ["Not", "", "1+", C.not], ["Or", "", "7+", s.or], ["Pad", "", "2-10", _.padV2, _.parsePadAttributesV2], ["Pad", "", "11+", _.padV11, _.parsePadAttributesV11], ["Pow", "", "7+", s.pow], ["PRelu", "", "7+", s.pRelu], ["ReduceLogSum", "", "1+", x.reduceLogSum, x.parseReduceAttributes], ["ReduceMax", "", "1+", x.reduceMax, x.parseReduceAttributes], ["ReduceMean", "", "1+", x.reduceMean, x.parseReduceAttributes], ["ReduceMin", "", "1+", x.reduceMin, x.parseReduceAttributes], ["ReduceProd", "", "1+", x.reduceProd, x.parseReduceAttributes], ["ReduceSum", "", "1-12", x.reduceSum, x.parseReduceAttributes], ["ReduceSumSquare", "", "1+", x.reduceLogSumSquare, x.parseReduceAttributes], ["Relu", "", "6+", C.relu], ["Reshape", "", "5+", T2.reshape], ["Resize", "", "10", S.resize, S.parseResizeAttributesV10], ["Resize", "", "11+", S.resize, S.parseResizeAttributesV11], ["Shape", "", "1+", O.shape], ["Sigmoid", "", "6+", C.sigmoid], ["Sin", "", "7+", C.sin], ["Slice", "", "10+", A.sliceV10], ["Slice", "", "1-9", A.slice, A.parseSliceAttributes], ["Softmax", "", "1-12", E.softmax, E.parseSoftmaxAttributes], ["Softmax", "", "13+", E.softmaxV13, E.parseSoftmaxAttributesV13], ["Split", "", "2-12", I.split, I.parseSplitAttributes], ["Sqrt", "", "6+", C.sqrt], ["Squeeze", "", "1-12", $.squeeze, $.parseSqueezeAttributes], ["Squeeze", "", "13+", $.squeezeV13], ["Sub", "", "7+", s.sub], ["Sum", "", "6+", P.sum], ["Tan", "", "7+", C.tan], ["Tanh", "", "6+", C.tanh], ["Tile", "", "6+", D.tile], ["Transpose", "", "1+", k.transpose, k.parseTransposeAttributes], ["Upsample", "", "7-8", M.upsample, M.parseUpsampleAttributesV7], ["Upsample", "", "9", M.upsample, M.parseUpsampleAttributesV9], ["Unsqueeze", "", "1-12", R.unsqueeze, R.parseUnsqueezeAttributes], ["Unsqueeze", "", "13+", R.unsqueezeV13], ["Xor", "", "7+", s.xor]];
1941
+ const a = n(8817), s = i(n(5194)), u = n(4752), l = n(6668), c2 = n(9754), p = n(5042), d = n(6742), f = n(4125), h = n(6149), g = n(5378), m = n(6981), b = n(7413), y = n(7006), w = n(8276), _ = n(5565), v = n(2834), x = n(1010), T2 = n(8126), S = n(2801), O = n(565), A = n(2444), E = n(815), I = n(564), $ = n(5416), P = n(1240), D = n(5944), k = n(5707), C = i(n(9087)), R2 = n(7862), M = n(3980);
1942
+ t.WEBGL_OP_RESOLVE_RULES = [["Abs", "", "6+", C.abs], ["Acos", "", "7+", C.acos], ["Add", "", "7+", s.add], ["And", "", "7+", s.and], ["Asin", "", "7+", C.asin], ["Atan", "", "7+", C.atan], ["AveragePool", "", "7+", v.averagePool, v.parseAveragePoolAttributes], ["BatchNormalization", "", "7+", a.batchNormalization, a.parseBatchNormalizationAttributes], ["Cast", "", "6+", u.cast, u.parseCastAttributes], ["Ceil", "", "6+", C.ceil], ["Clip", "", "6-10", C.clip, C.parseClipAttributes], ["Clip", "", "11+", C.clipV11], ["Concat", "", "4+", l.concat, l.parseConcatAttributes], ["Conv", "", "1+", c2.conv, c2.parseConvAttributes], ["ConvTranspose", "", "1+", p.convTranspose, p.parseConvTransposeAttributes], ["Cos", "", "7+", C.cos], ["Div", "", "7+", s.div], ["Dropout", "", "7+", C.identity], ["DepthToSpace", "", "1+", d.depthToSpace, d.parseDepthToSpaceAttributes], ["Equal", "", "7+", s.equal], ["Elu", "", "6+", C.elu, C.parseEluAttributes], ["Exp", "", "6+", C.exp], ["Flatten", "", "1+", f.flatten, f.parseFlattenAttributes], ["Floor", "", "6+", C.floor], ["FusedConv", "com.microsoft", "1+", c2.conv, c2.parseConvAttributes], ["Gather", "", "1+", h.gather, h.parseGatherAttributes], ["Gemm", "", "7-10", g.gemm, g.parseGemmAttributesV7], ["Gemm", "", "11+", g.gemm, g.parseGemmAttributesV11], ["GlobalAveragePool", "", "1+", v.globalAveragePool, v.parseGlobalAveragePoolAttributes], ["GlobalMaxPool", "", "1+", v.globalMaxPool], ["Greater", "", "7+", s.greater], ["Identity", "", "1+", C.identity], ["ImageScaler", "", "1+", m.imageScaler, m.parseImageScalerAttributes], ["InstanceNormalization", "", "6+", b.instanceNormalization, b.parseInstanceNormalizationAttributes], ["LeakyRelu", "", "6+", C.leakyRelu, C.parseLeakyReluAttributes], ["Less", "", "7+", s.less], ["LRN", "", "1+", y.lrn, y.parseLrnAttributes], ["Log", "", "6+", C.log], ["MatMul", "", "1+", w.matMul, w.parseMatMulAttributes], ["MaxPool", "", "1+", v.maxPool, v.parseMaxPoolAttributes], ["Mul", "", "7+", s.mul], ["Neg", "", "6+", C.neg], ["Not", "", "1+", C.not], ["Or", "", "7+", s.or], ["Pad", "", "2-10", _.padV2, _.parsePadAttributesV2], ["Pad", "", "11+", _.padV11, _.parsePadAttributesV11], ["Pow", "", "7+", s.pow], ["PRelu", "", "7+", s.pRelu], ["ReduceLogSum", "", "1+", x.reduceLogSum, x.parseReduceAttributes], ["ReduceMax", "", "1+", x.reduceMax, x.parseReduceAttributes], ["ReduceMean", "", "1+", x.reduceMean, x.parseReduceAttributes], ["ReduceMin", "", "1+", x.reduceMin, x.parseReduceAttributes], ["ReduceProd", "", "1+", x.reduceProd, x.parseReduceAttributes], ["ReduceSum", "", "1-12", x.reduceSum, x.parseReduceAttributes], ["ReduceSumSquare", "", "1+", x.reduceLogSumSquare, x.parseReduceAttributes], ["Relu", "", "6+", C.relu], ["Reshape", "", "5+", T2.reshape], ["Resize", "", "10", S.resize, S.parseResizeAttributesV10], ["Resize", "", "11+", S.resize, S.parseResizeAttributesV11], ["Shape", "", "1+", O.shape], ["Sigmoid", "", "6+", C.sigmoid], ["Sin", "", "7+", C.sin], ["Slice", "", "10+", A.sliceV10], ["Slice", "", "1-9", A.slice, A.parseSliceAttributes], ["Softmax", "", "1-12", E.softmax, E.parseSoftmaxAttributes], ["Softmax", "", "13+", E.softmaxV13, E.parseSoftmaxAttributesV13], ["Split", "", "2-12", I.split, I.parseSplitAttributes], ["Sqrt", "", "6+", C.sqrt], ["Squeeze", "", "1-12", $.squeeze, $.parseSqueezeAttributes], ["Squeeze", "", "13+", $.squeezeV13], ["Sub", "", "7+", s.sub], ["Sum", "", "6+", P.sum], ["Tan", "", "7+", C.tan], ["Tanh", "", "6+", C.tanh], ["Tile", "", "6+", D.tile], ["Transpose", "", "1+", k.transpose, k.parseTransposeAttributes], ["Upsample", "", "7-8", M.upsample, M.parseUpsampleAttributesV7], ["Upsample", "", "9", M.upsample, M.parseUpsampleAttributesV9], ["Unsqueeze", "", "1-12", R2.unsqueeze, R2.parseUnsqueezeAttributes], ["Unsqueeze", "", "13+", R2.unsqueezeV13], ["Xor", "", "7+", s.xor]];
1943
1943
  }, 8817: (e, t, n) => {
1944
1944
  Object.defineProperty(t, "__esModule", { value: true }), t.parseBatchNormalizationAttributes = t.batchNormalization = void 0;
1945
1945
  const r = n(4910), o = n(6757), i = n(5639), a = { name: "BatchNormalization", inputNames: ["A", "Scale", "B", "Mean", "Variance"], inputTypes: [i.TextureType.unpacked, i.TextureType.unpacked, i.TextureType.unpacked, i.TextureType.unpacked, i.TextureType.unpacked] };
@@ -8579,7 +8579,7 @@ ${e2}`);
8579
8579
  t.createConv2DMatMulProgramInfo = (e2, t2, n2, l, c2, p, d, f, h) => {
8580
8580
  const g = "NHWC" === n2.format, m = g ? e2[0].dims[3] : e2[0].dims[1], b = l[0], y = g ? l[2] : l[3], w = g ? l[1] : l[2], _ = g ? l[3] : l[1], v = ((m % 4 == 0 || m % 3 == 0) && g || y % 4 == 0 && !g) && _ % 4 == 0, x = g ? _ : y * w, T2 = g ? y * w : _, S = v ? [8, 8, 1] : [x <= 4 ? 4 : 16, x > 4 && T2 <= 4 ? 4 : 16, 1], O = v ? [4, 4, 1] : [x <= 4 ? 1 : 2, x > 4 && T2 <= 4 ? 1 : 2, 1], A = [Math.ceil(x / S[0] / O[0]), Math.ceil(T2 / S[1] / O[1]), Math.ceil(b / S[2] / O[1])];
8581
8581
  (0, r.LOG_DEBUG)("verbose", () => `[conv2d_mm_webgpu] dispatch = ${A}`);
8582
- const E = v ? g && m % 4 != 0 ? 3 : 4 : O[0], I = S[1] * O[1], $ = S[0] * O[0], P = Math.max(S[0] * E, S[1]), D = c2 % I == 0, k = p % $ == 0, C = d % P == 0, R = v ? [E, 4, 4] : [1, 1, 1], M = [`@group(0) @binding(0) var<storage, read> x: array<${v && 4 === E ? "vec4<f32>" : "f32"}>;`, `@group(0) @binding(1) var<storage, read> w: array<${v ? "vec4<f32>" : "f32"}>;`];
8582
+ const E = v ? g && m % 4 != 0 ? 3 : 4 : O[0], I = S[1] * O[1], $ = S[0] * O[0], P = Math.max(S[0] * E, S[1]), D = c2 % I == 0, k = p % $ == 0, C = d % P == 0, R2 = v ? [E, 4, 4] : [1, 1, 1], M = [`@group(0) @binding(0) var<storage, read> x: array<${v && 4 === E ? "vec4<f32>" : "f32"}>;`, `@group(0) @binding(1) var<storage, read> w: array<${v ? "vec4<f32>" : "f32"}>;`];
8583
8583
  let N = `
8584
8584
  fn setOutputAtIndex(flatIndex : i32, value : ${v ? "vec4<f32>" : "f32"}) {
8585
8585
  result[flatIndex] = ${v ? "vec4<f32>" : "f32"}(value);
@@ -8688,7 +8688,7 @@ ${e2}`);
8688
8688
  setOutputAtCoords(coords[0], coords[1], coords[2], coords[3], value);
8689
8689
  }
8690
8690
  }`;
8691
- })(g, D, k, C, f, void 0, false, R[0], R[1], R[2])}
8691
+ })(g, D, k, C, f, void 0, false, R2[0], R2[1], R2[2])}
8692
8692
  ${v ? (0, u.makeMatMulPackedVec4Source)(O, S, !g, P) : (0, u.makeMatMulPackedSource)(O, S, !g, P, false, void 0, h)}` });
8693
8693
  };
8694
8694
  }, 4085: (e, t) => {
@@ -10247,7 +10247,7 @@ fn main(@builtin(local_invocation_id) localId : vec3<u32>,
10247
10247
  }, 3474: (e, t, n) => {
10248
10248
  var _scriptDir, r = (_scriptDir = (_scriptDir = "undefined" != typeof document && document.currentScript ? document.currentScript.src : void 0) || "/index.js", function(e2) {
10249
10249
  function t2() {
10250
- return D.buffer != C && H(D.buffer), R;
10250
+ return D.buffer != C && H(D.buffer), R2;
10251
10251
  }
10252
10252
  function r2() {
10253
10253
  return D.buffer != C && H(D.buffer), M;
@@ -10316,7 +10316,7 @@ fn main(@builtin(local_invocation_id) localId : vec3<u32>,
10316
10316
  Object.assign(s, m), m = null, s.thisProgram && (b = s.thisProgram), s.quit && (y = s.quit), s.wasmBinary && (E = s.wasmBinary);
10317
10317
  var P = s.noExitRuntime || true;
10318
10318
  "object" != typeof WebAssembly && ne("no native wasm support detected");
10319
- var D, k, C, R, M, N, F, L2, j = false, U2 = "undefined" != typeof TextDecoder ? new TextDecoder("utf8") : void 0;
10319
+ var D, k, C, R2, M, N, F, L2, j = false, U2 = "undefined" != typeof TextDecoder ? new TextDecoder("utf8") : void 0;
10320
10320
  function B(e3, t3, n2) {
10321
10321
  var r3 = (t3 >>>= 0) + n2;
10322
10322
  for (n2 = t3; e3[n2] && !(n2 >= r3); ) ++n2;
@@ -10373,7 +10373,7 @@ fn main(@builtin(local_invocation_id) localId : vec3<u32>,
10373
10373
  return t3;
10374
10374
  }
10375
10375
  function H(e3) {
10376
- C = e3, s.HEAP8 = R = new Int8Array(e3), s.HEAP16 = new Int16Array(e3), s.HEAP32 = N = new Int32Array(e3), s.HEAPU8 = M = new Uint8Array(e3), s.HEAPU16 = new Uint16Array(e3), s.HEAPU32 = F = new Uint32Array(e3), s.HEAPF32 = new Float32Array(e3), s.HEAPF64 = L2 = new Float64Array(e3);
10376
+ C = e3, s.HEAP8 = R2 = new Int8Array(e3), s.HEAP16 = new Int16Array(e3), s.HEAP32 = N = new Int32Array(e3), s.HEAPU8 = M = new Uint8Array(e3), s.HEAPU16 = new Uint16Array(e3), s.HEAPU32 = F = new Uint32Array(e3), s.HEAPF32 = new Float32Array(e3), s.HEAPF64 = L2 = new Float64Array(e3);
10377
10377
  }
10378
10378
  x && (C = s.buffer);
10379
10379
  var W = s.INITIAL_MEMORY || 16777216;
@@ -11117,7 +11117,7 @@ fn main(@builtin(local_invocation_id) localId : vec3<u32>,
11117
11117
  }
11118
11118
  return t3;
11119
11119
  }
11120
- function R() {
11120
+ function R2() {
11121
11121
  var e3 = x.buffer;
11122
11122
  T2 = e3, t2.HEAP8 = S = new Int8Array(e3), t2.HEAP16 = new Int16Array(e3), t2.HEAP32 = A = new Int32Array(e3), t2.HEAPU8 = O = new Uint8Array(e3), t2.HEAPU16 = new Uint16Array(e3), t2.HEAPU32 = E = new Uint32Array(e3), t2.HEAPF32 = new Float32Array(e3), t2.HEAPF64 = new Float64Array(e3);
11123
11123
  }
@@ -11380,7 +11380,7 @@ fn main(@builtin(local_invocation_id) localId : vec3<u32>,
11380
11380
  r3 = Math.max(e3, r3), o2 = o2.min.call(o2, 4294901760, r3 + (65536 - r3 % 65536) % 65536);
11381
11381
  e: {
11382
11382
  try {
11383
- x.grow(o2 - T2.byteLength + 65535 >>> 16), R();
11383
+ x.grow(o2 - T2.byteLength + 65535 >>> 16), R2();
11384
11384
  var i2 = 1;
11385
11385
  break e;
11386
11386
  } catch (e4) {
@@ -11443,7 +11443,7 @@ fn main(@builtin(local_invocation_id) localId : vec3<u32>,
11443
11443
  } };
11444
11444
  !function() {
11445
11445
  function e3(e4) {
11446
- t2.asm = e4.exports, x = t2.asm.P, R(), N.unshift(t2.asm.Q), U2--, t2.monitorRunDependencies && t2.monitorRunDependencies(U2), 0 == U2 && (G && (e4 = G, G = null, e4()));
11446
+ t2.asm = e4.exports, x = t2.asm.P, R2(), N.unshift(t2.asm.Q), U2--, t2.monitorRunDependencies && t2.monitorRunDependencies(U2), 0 == U2 && (G && (e4 = G, G = null, e4()));
11447
11447
  }
11448
11448
  function n2(t3) {
11449
11449
  e3(t3.instance);
@@ -14153,7 +14153,7 @@ fn main(@builtin(local_invocation_id) localId : vec3<u32>,
14153
14153
  }
14154
14154
  }
14155
14155
  const U = new c();
14156
- let R$1 = class R {
14156
+ class R {
14157
14157
  constructor(t) {
14158
14158
  this.config = t, this.lastMaskGenerationTime = 0;
14159
14159
  const { height: a, width: e } = this.config.mask.outputSize;
@@ -14252,7 +14252,7 @@ fn main(@builtin(local_invocation_id) localId : vec3<u32>,
14252
14252
  }
14253
14253
  destroy() {
14254
14254
  }
14255
- };
14255
+ }
14256
14256
  let generator;
14257
14257
  let busy = false;
14258
14258
  self.addEventListener("message", async (event) => {
@@ -14286,7 +14286,7 @@ fn main(@builtin(local_invocation_id) localId : vec3<u32>,
14286
14286
  postMessage({ status: "preloaded" });
14287
14287
  }
14288
14288
  async function handleInit(config) {
14289
- generator = new R$1(config);
14289
+ generator = new R(config);
14290
14290
  await generator.load();
14291
14291
  postMessage({ status: "initialized" });
14292
14292
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webex/ladon-ts",
3
- "version": "5.0.3",
3
+ "version": "5.1.0",
4
4
  "description": "WebexIntelligence computer vision library",
5
5
  "type": "module",
6
6
  "main": "build/module/index.js",