{"version":3,"sources":["../src/preprocess/runtime.ts"],"names":[],"mappings":"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","file":"chunk-LATOVDXO.cjs","sourcesContent":["import type { SerializedDQVAT } from '../extensions/VATBuilder/VATBuilder';\n\nexport type ShadoModelArtifactMap = {\n  model?: string | null;\n  vat16?: string | null;\n  vat32?: string | null;\n  asm?: string | null;\n  wgsl?: string | null;\n  glsl?: string | null;\n};\n\nexport type ShadoModelImportSource =\n  | {\n      kind?: 'asset-container';\n      url: string;\n    }\n  | {\n      kind: 'scene-loader';\n      rootUrl: string;\n      fileName: string;\n      meshNames?: string[];\n    };\n\nexport type ShadoModelManifestEntry = {\n  name: string;\n  import: ShadoModelImportSource;\n  runtime?: {\n    merge?: boolean;\n    replaceMaterial?: boolean;\n    disposeOriginalMaterial?: boolean;\n  };\n  includeAnimation?: boolean;\n  vat?: {\n    variants?: Array<'float16' | 'float32'>;\n    options?: unknown;\n  };\n  artifacts?: ShadoModelArtifactMap;\n};\n\nexport type ShadoModelManifestDocument = {\n  kind: 'shado.model.manifest';\n  version: number;\n  models: Record<string, ShadoModelManifestEntry>;\n};\n\nexport type ShadoPackedModel = {\n  kind: 'shado.model';\n  version: number;\n  name?: string;\n  source?: ShadoModelImportSource;\n  scene?: unknown;\n  runtime?: ShadoModelManifestEntry['runtime'];\n  artifacts?: Omit<ShadoModelArtifactMap, 'model'>;\n};\n\nexport type ShadoVatSelection = 'auto' | 'float16' | 'float32' | false;\nexport type ShadoShaderSelection = false | true | 'glsl' | 'wgsl' | Array<'glsl' | 'wgsl'>;\n\nexport type ShadoDeserializeRequest = {\n  manifest?: ShadoModelManifestDocument;\n  manifestUrl?: string;\n  modelName?: string;\n  model?: ShadoModelManifestEntry;\n  modelUrl?: string;\n  baseUrl?: string;\n};\n\nexport type ShadoDeserializeOptions = {\n  animation?: boolean;\n  vat?: ShadoVatSelection;\n  reducers?: boolean;\n  shaders?: ShadoShaderSelection;\n  gpu?: {\n    textureHalfFloat?: boolean;\n  };\n  fetch?: typeof fetch;\n};\n\nexport type ShadoDeserializedModel = {\n  manifest?: ShadoModelManifestDocument;\n  manifestModel?: ShadoModelManifestEntry;\n  model?: ShadoPackedModel;\n  modelUrl?: string;\n  vat?: SerializedDQVAT;\n  vatVariant?: 'float16' | 'float32';\n  vatUrl?: string;\n  wasm?: ArrayBuffer;\n  wasmUrl?: string;\n  wgsl?: string;\n  wgslUrl?: string;\n  glsl?: string;\n  glslUrl?: string;\n  artifacts: {\n    model?: string;\n    vat16?: string;\n    vat32?: string;\n    asm?: string;\n    wgsl?: string;\n    glsl?: string;\n  };\n};\n\nexport async function deserializeShadoModel(\n  request: ShadoDeserializeRequest,\n  options: ShadoDeserializeOptions = {}\n): Promise<ShadoDeserializedModel> {\n  const fetcher = getFetch(options.fetch);\n  const manifest =\n    request.manifest ??\n    (request.manifestUrl\n      ? await fetchShadoJson<ShadoModelManifestDocument>(request.manifestUrl, { fetch: fetcher })\n      : undefined);\n  const manifestBase = request.baseUrl ?? (request.manifestUrl ? shadoDirectoryUrl(request.manifestUrl) : undefined);\n  const manifestModel =\n    request.model ??\n    (request.modelName && manifest ? manifest.models[request.modelName] : undefined);\n  const modelRef = request.modelUrl ?? manifestModel?.artifacts?.model;\n  const modelUrl = modelRef ? resolveShadoArtifactUrl(modelRef, request.modelUrl ? request.baseUrl : manifestBase) : undefined;\n  const model = modelUrl\n    ? await fetchShadoJson<ShadoPackedModel>(modelUrl, { fetch: fetcher })\n    : undefined;\n  const modelBase = modelUrl ? shadoDirectoryUrl(modelUrl) : manifestBase;\n\n  const artifacts = {\n    model: modelUrl,\n    vat16: resolveArtifact('vat16', manifestModel?.artifacts, manifestBase, model?.artifacts, modelBase),\n    vat32: resolveArtifact('vat32', manifestModel?.artifacts, manifestBase, model?.artifacts, modelBase),\n    asm: resolveArtifact('asm', manifestModel?.artifacts, manifestBase, model?.artifacts, modelBase),\n    wgsl: resolveArtifact('wgsl', manifestModel?.artifacts, manifestBase, model?.artifacts, modelBase),\n    glsl: resolveArtifact('glsl', manifestModel?.artifacts, manifestBase, model?.artifacts, modelBase),\n  };\n\n  const result: ShadoDeserializedModel = {\n    manifest,\n    manifestModel,\n    model,\n    modelUrl,\n    artifacts,\n  };\n\n  const vatChoice = chooseVatArtifact(artifacts, options);\n  if (vatChoice) {\n    result.vat = await fetchShadoJson<SerializedDQVAT>(vatChoice.url, { fetch: fetcher });\n    result.vatVariant = vatChoice.variant;\n    result.vatUrl = vatChoice.url;\n  }\n\n  if (options.reducers && artifacts.asm) {\n    result.wasm = await fetchShadoBytes(artifacts.asm, { fetch: fetcher });\n    result.wasmUrl = artifacts.asm;\n  }\n\n  const shaders = normalizeShaderSelection(options.shaders ?? false);\n  if (shaders.has('wgsl') && artifacts.wgsl) {\n    result.wgsl = await fetchShadoText(artifacts.wgsl, { fetch: fetcher });\n    result.wgslUrl = artifacts.wgsl;\n  }\n  if (shaders.has('glsl') && artifacts.glsl) {\n    result.glsl = await fetchShadoText(artifacts.glsl, { fetch: fetcher });\n    result.glslUrl = artifacts.glsl;\n  }\n\n  return result;\n}\n\nexport async function fetchShadoJson<T>(\n  url: string,\n  options: { fetch?: typeof fetch } = {}\n): Promise<T> {\n  return JSON.parse(await fetchShadoText(url, options)) as T;\n}\n\nexport async function fetchShadoText(\n  url: string,\n  options: { fetch?: typeof fetch } = {}\n): Promise<string> {\n  const bytes = await fetchShadoBytes(url, options);\n  return new TextDecoder().decode(bytes);\n}\n\nexport async function fetchShadoBytes(\n  url: string,\n  options: { fetch?: typeof fetch } = {}\n): Promise<ArrayBuffer> {\n  const response = await getFetch(options.fetch)(url);\n  if (!response.ok) {\n    throw new Error(`Failed to fetch '${url}': ${response.status} ${response.statusText}`);\n  }\n  const bytes = await response.arrayBuffer();\n  if (!url.endsWith('.gz')) return bytes;\n  return gunzipBrowser(bytes, url);\n}\n\nexport function resolveShadoArtifactUrl(ref: string, baseUrl?: string): string {\n  if (/^(?:[a-z]+:)?\\/\\//i.test(ref) || ref.startsWith('data:') || ref.startsWith('blob:')) {\n    return ref;\n  }\n  const base = normalizeBaseUrl(baseUrl ?? globalThis.location?.href);\n  if (!base) return ref;\n  try {\n    return new URL(ref, base).href;\n  } catch {\n    return joinPathLike(base, ref);\n  }\n}\n\nexport function shadoDirectoryUrl(url: string): string {\n  const base = normalizeBaseUrl(globalThis.location?.href);\n  if (!base && !/^(?:[a-z]+:)?\\/\\//i.test(url)) {\n    return url.endsWith('/') ? url : url.slice(0, url.lastIndexOf('/') + 1);\n  }\n  const resolved = new URL(url, base);\n  if (url.endsWith('/')) return resolved.href;\n  const lastSlash = resolved.pathname.lastIndexOf('/');\n  resolved.pathname = lastSlash >= 0 ? resolved.pathname.slice(0, lastSlash + 1) : '/';\n  resolved.search = '';\n  resolved.hash = '';\n  return resolved.href;\n}\n\nexport function getBabylonSceneDataUrl(model: ShadoPackedModel): string | undefined {\n  return model.scene ? `data:${JSON.stringify(model.scene)}` : undefined;\n}\n\nfunction resolveArtifact(\n  key: keyof Omit<ShadoModelArtifactMap, 'model'>,\n  manifestArtifacts?: ShadoModelArtifactMap,\n  manifestBase?: string,\n  modelArtifacts?: Omit<ShadoModelArtifactMap, 'model'>,\n  modelBase?: string\n): string | undefined {\n  const manifestRef = manifestArtifacts?.[key];\n  if (manifestRef) return resolveShadoArtifactUrl(manifestRef, manifestBase);\n  const modelRef = modelArtifacts?.[key];\n  if (modelRef) return resolveShadoArtifactUrl(modelRef, modelBase);\n  return undefined;\n}\n\nfunction chooseVatArtifact(\n  artifacts: ShadoDeserializedModel['artifacts'],\n  options: ShadoDeserializeOptions\n): { variant: 'float16' | 'float32'; url: string } | undefined {\n  if (options.animation === false || options.vat === false) return undefined;\n  const preferred = options.vat ?? 'auto';\n  if (preferred === 'float16') {\n    return artifacts.vat16\n      ? { variant: 'float16', url: artifacts.vat16 }\n      : artifacts.vat32\n        ? { variant: 'float32', url: artifacts.vat32 }\n        : undefined;\n  }\n  if (preferred === 'float32') {\n    return artifacts.vat32\n      ? { variant: 'float32', url: artifacts.vat32 }\n      : artifacts.vat16\n        ? { variant: 'float16', url: artifacts.vat16 }\n        : undefined;\n  }\n  return options.gpu?.textureHalfFloat && artifacts.vat16\n    ? { variant: 'float16', url: artifacts.vat16 }\n    : artifacts.vat32\n      ? { variant: 'float32', url: artifacts.vat32 }\n      : artifacts.vat16\n        ? { variant: 'float16', url: artifacts.vat16 }\n        : undefined;\n}\n\nfunction normalizeShaderSelection(value: ShadoShaderSelection): Set<'glsl' | 'wgsl'> {\n  if (!value) return new Set();\n  if (value === true) return new Set(['glsl', 'wgsl']);\n  return new Set(Array.isArray(value) ? value : [value]);\n}\n\nfunction getFetch(fetcher?: typeof fetch): typeof fetch {\n  const next = fetcher ?? globalThis.fetch;\n  if (!next) throw new Error('deserializeShadoModel requires fetch');\n  return next.bind(globalThis);\n}\n\nasync function gunzipBrowser(bytes: ArrayBuffer, url: string): Promise<ArrayBuffer> {\n  if (typeof DecompressionStream === 'undefined') {\n    throw new Error(`Cannot decompress '${url}': this runtime does not expose DecompressionStream`);\n  }\n  const stream = new Blob([bytes]).stream().pipeThrough(new DecompressionStream('gzip'));\n  return new Response(stream).arrayBuffer();\n}\n\nfunction normalizeBaseUrl(baseUrl?: string): string | undefined {\n  if (!baseUrl) return undefined;\n  if (/^(?:[a-z]+:)?\\/\\//i.test(baseUrl) || baseUrl.startsWith('data:') || baseUrl.startsWith('blob:')) {\n    return baseUrl;\n  }\n  const locationHref = globalThis.location?.href;\n  return locationHref ? new URL(baseUrl, locationHref).href : baseUrl;\n}\n\nfunction joinPathLike(base: string, ref: string): string {\n  if (ref.startsWith('/')) return ref;\n  return `${base.endsWith('/') ? base : `${base}/`}${ref}`;\n}\n"]}