{"version":3,"file":"build-BiyVcX4s.cjs","names":[],"sources":["../src/orchestration/generateRequestId.ts","../src/common/sucrasePlugin.ts","../src/common/packageJson.ts","../src/v3/parseId.ts","../src/v3/transformDSV/dsvParseSrc.ts","../src/v3/transformDSV/index.ts","../src/v3/extractVizImport.ts","../src/v3/vizResolve.ts","../src/common/imageSupport.ts","../src/v3/vizLoad.ts","../src/v3/transformSvelte.ts","../src/v3/computeBundleJSV3.ts","../src/common/runtimeErrorHandling.ts","../src/v3/htmlTemplate.ts","../src/v3/v3Build.ts","../src/v3/vizCache.ts","../src/v3/slugCache.ts","../src/v3/cleanRollupErrorMessage.ts","../src/v3/createVizContent.ts","../src/build/determineRuntimeVersion.ts","../src/v2/getComputedIndexHtml.ts","../node_modules/vizhub-libraries/index.js","../src/common/virtualFileSystem.ts","../src/v2/computeBundleJSV2.ts","../src/v2/v2Build.ts","../src/v4/extractEntryPoints.ts","../src/v4/catchAll.ts","../src/v4/bundleModule.ts","../src/v4/stringUtils.ts","../src/v4/importMap.ts","../src/v4/hotReloadScript.ts","../src/v4/updateHTML.ts","../src/v4/index.ts","../src/build/build.ts"],"sourcesContent":["// Generate a unique request ID,\n// for uniquely identifying messages\n// sent to the worker or iframe from the\n// main thread.\nexport const generateRequestId = (): string =>\n  (Math.random() + \"\").slice(2);\n","import { transform } from \"sucrase\";\nimport type { Plugin } from \"rollup\";\n\nexport function sucrasePlugin(\n  additionalOptions = {},\n): Plugin {\n  return {\n    name: \"sucrase\",\n    transform(code, id) {\n      // Transform .js, .jsx, and .tsx files\n      if (!id.match(/\\.(?:js|[jt]sx)$/)) {\n        return null;\n      }\n\n      const result = transform(code, {\n        transforms: [\"jsx\", \"typescript\"],\n\n        // For source maps\n        filePath: id,\n        sourceMapOptions: {\n          compiledFilename: \"bundle.js\",\n        },\n        production: true,\n        ...additionalOptions,\n      });\n\n      return {\n        code: result.code,\n        map: result.sourceMap,\n      };\n    },\n  };\n}\n","import { FileCollection } from \"@vizhub/viz-types\";\n\nexport type Licence = string;\n\nexport interface PackageJson {\n  dependencies?: {\n    [key: string]: string;\n  };\n  vizhub?: {\n    libraries?: {\n      [key: string]: VizHubLibraryConfig;\n    };\n  };\n  license?: Licence | { type: string };\n}\n\nconst EMPTY_PKG_JSON: PackageJson = {\n  dependencies: {},\n  vizhub: {},\n  license: \"MIT\",\n};\n\nexport interface Dependency {\n  name: string;\n  version: string;\n}\n\nexport interface VizHubLibraryConfig {\n  path?: string;\n  global?: string;\n}\n\nexport interface VizHubLibraryConfigs {\n  [key: string]: VizHubLibraryConfig;\n}\n\nconst DEBUG = false;\n\nexport const packageJSON = (\n  files: FileCollection,\n): PackageJson => {\n  const packageJsonText = files[\"package.json\"];\n  DEBUG &&\n    console.log(\n      \"[packageJSON] packageJsonText:\",\n      packageJsonText,\n    );\n  try {\n    const pkg = packageJsonText\n      ? JSON.parse(packageJsonText)\n      : EMPTY_PKG_JSON;\n    DEBUG &&\n      console.log(\n        \"[packageJSON] pkg:\",\n        JSON.stringify(pkg, null, 2),\n      );\n    return pkg;\n  } catch {\n    DEBUG &&\n      console.log(\n        \"[packageJSON] Error parsing package.json\",\n      );\n    return EMPTY_PKG_JSON;\n  }\n};\n\nexport const dependencies = (files: FileCollection) =>\n  packageJSON(files).dependencies || {};\n\nexport const getConfiguredLibraries = (\n  files: FileCollection,\n) => {\n  const vizhubConfig = packageJSON(files).vizhub || {};\n  return vizhubConfig.libraries || {};\n};\n\nexport const dependencySource = (\n  { name, version }: Dependency,\n  libraries: VizHubLibraryConfigs,\n  cdn = \"jsdelivr\",\n) => {\n  const path = libraries[name]\n    ? libraries[name].path || \"\"\n    : \"\";\n  const src =\n    cdn === \"jsdelivr\"\n      ? `https://cdn.jsdelivr.net/npm/${name}@${version}${path}`\n      : `https://unpkg.com/${name}@${version}${path}`;\n  return src;\n};\n\nexport const getLicense = (files: FileCollection) => {\n  const license = packageJSON(files).license;\n  if (\n    typeof license === \"object\" &&\n    license !== null &&\n    \"type\" in license\n  ) {\n    return license.type;\n  }\n  return license || EMPTY_PKG_JSON.license;\n};\n\nexport const getConfiguredGlobals = (\n  pkg: PackageJson,\n): Record<string, string> => {\n  const libraries = pkg?.vizhub?.libraries;\n  if (libraries) {\n    return Object.entries(libraries).reduce(\n      (accumulator, [packageName, config]) => {\n        if (config.global) {\n          accumulator[packageName] = config.global;\n        }\n        return accumulator;\n      },\n      {} as Record<string, string>,\n    );\n  }\n  return {};\n};\n\nconst defaultGlobals = {\n  d3: \"d3\",\n  react: \"React\",\n  \"react-dom\": \"ReactDOM\",\n};\n\nexport const getGlobals = (\n  pkg: PackageJson,\n): Record<string, string> => {\n  const configuredGlobals = getConfiguredGlobals(pkg);\n\n  return {\n    ...defaultGlobals,\n    ...configuredGlobals,\n  };\n};\n","import type { VizId } from \"@vizhub/viz-types\";\nimport type { ResolvedVizFileId } from \"./types\";\n\nexport const parseId = (\n  id: ResolvedVizFileId,\n): {\n  vizId: VizId;\n  fileName: string;\n} => {\n  const [vizId, ...fileNameParts] = id.split(\"/\");\n  const fileName = fileNameParts.join(\"/\");\n  return { vizId, fileName };\n};\n","export const dsvParseSrc = `var EOL = {},\n  EOF = {},\n  QUOTE = 34,\n  NEWLINE = 10,\n  RETURN = 13;\n\nfunction objectConverter(columns) {\n  return new Function(\n    'd',\n    'return {' +\n      columns\n        .map(function (name, i) {\n          return (\n            JSON.stringify(name) + ': d[' + i + '] || \"\"'\n          );\n        })\n        .join(',') +\n      '}',\n  );\n}\n\nfunction customConverter(columns, f) {\n  var object = objectConverter(columns);\n  return function (row, i) {\n    return f(object(row), i, columns);\n  };\n}\n\nfunction dsv(delimiter) {\n  var DELIMITER = delimiter.charCodeAt(0);\n\n  function parse(text, f) {\n    var convert,\n      columns,\n      rows = parseRows(text, function (row, i) {\n        if (convert) return convert(row, i - 1);\n        (columns = row),\n          (convert = f\n            ? customConverter(row, f)\n            : objectConverter(row));\n      });\n    rows.columns = columns || [];\n    return rows;\n  }\n\n  function parseRows(text, f) {\n    var rows = [], // output rows\n      N = text.length,\n      I = 0, // current character index\n      n = 0, // current line number\n      t, // current token\n      eof = N <= 0, // current token followed by EOF?\n      eol = false; // current token followed by EOL?\n\n    // Strip the trailing newline.\n    if (text.charCodeAt(N - 1) === NEWLINE) --N;\n    if (text.charCodeAt(N - 1) === RETURN) --N;\n\n    function token() {\n      if (eof) return EOF;\n      if (eol) return (eol = false), EOL;\n\n      // Unescape quotes.\n      var i,\n        j = I,\n        c;\n      if (text.charCodeAt(j) === QUOTE) {\n        while (\n          (I++ < N && text.charCodeAt(I) !== QUOTE) ||\n          text.charCodeAt(++I) === QUOTE\n        );\n        if ((i = I) >= N) eof = true;\n        else if ((c = text.charCodeAt(I++)) === NEWLINE)\n          eol = true;\n        else if (c === RETURN) {\n          eol = true;\n          if (text.charCodeAt(I) === NEWLINE) ++I;\n        }\n        return text.slice(j + 1, i - 1).replace(/\"\"/g, '\"');\n      }\n\n      // Find next delimiter or newline.\n      while (I < N) {\n        if ((c = text.charCodeAt((i = I++))) === NEWLINE)\n          eol = true;\n        else if (c === RETURN) {\n          eol = true;\n          if (text.charCodeAt(I) === NEWLINE) ++I;\n        } else if (c !== DELIMITER) continue;\n        return text.slice(j, i);\n      }\n\n      // Return last token before EOF.\n      return (eof = true), text.slice(j, N);\n    }\n\n    while ((t = token()) !== EOF) {\n      var row = [];\n      while (t !== EOL && t !== EOF)\n        row.push(t), (t = token());\n      if (f && (row = f(row, n++)) == null) continue;\n      rows.push(row);\n    }\n\n    return rows;\n  }\n\n  return {\n    parse: parse,\n  };\n}\n\nvar csv = dsv(',');\n\nvar csvParse = csv.parse;\n\nvar tsv = dsv('\\t');\n\nvar tsvParse = tsv.parse;\n\nexport { csvParse, tsvParse };`;\n","import { InputPluginOption } from \"rollup\";\nimport type { ResolvedVizFileId } from \"../types\";\nimport { parseId } from \"../parseId\";\nimport { dsvParseSrc } from \"./dsvParseSrc.js\";\n\nconst DEBUG = false;\n\n// Escape backticks in a string so that it can be\n// used in a template literal. Also need to escape backslashes.\nconst escapeBackticks = (str: string) =>\n  // str.replace(/`/g, '\\\\`');\n  str.replace(/\\\\/g, \"\\\\\\\\\").replace(/`/g, \"\\\\`\");\n\n// Responsible for loading CSV and TSV files, which are\n// in general called Delimiter-Separated Values (DSV).\nexport const transformDSV = (): InputPluginOption => ({\n  name: \"transformDSV\",\n\n  // `id` here is of the form\n  // `{vizId}/{fileName}`\n  transform: async (\n    text: string,\n    id: ResolvedVizFileId,\n  ) => {\n    DEBUG && console.log(\"[transformDSV]: load() \" + id);\n    const { vizId, fileName } = parseId(id);\n\n    DEBUG &&\n      console.log(\"  [transformDSV] vizId: \" + vizId);\n    DEBUG &&\n      console.log(\"  [transformDSV] fileName: \" + fileName);\n    const isCSV = fileName.endsWith(\".csv\");\n    const isTSV = fileName.endsWith(\".tsv\");\n    if (isCSV || isTSV) {\n      DEBUG &&\n        console.log(\n          \"    [transformDSV] tracking DSV import for \" +\n            id,\n        );\n\n      const parseFunction = isCSV ? \"csvParse\" : \"tsvParse\";\n\n      return {\n        code: `\n            ${dsvParseSrc}\n            const data = ${parseFunction}(\\`${escapeBackticks(text)}\\`);\n            export default data;\n          `,\n        map: { mappings: \"\" },\n      };\n    }\n    return undefined;\n  },\n});\n","import { VizId } from \"@vizhub/viz-types\";\n\nexport type VizImport = {\n  userName: string;\n  idOrSlug: VizId | string;\n};\n\nexport const extractVizImport = (\n  str: string,\n): VizImport | null => {\n  // Updated regular expression pattern\n  // Username: Alphanumeric characters, including underscores and hyphens\n  // ID: Alphanumeric characters, including underscores, hyphens, and possibly other special characters\n  const pattern = /^@([a-zA-Z0-9_-]+)\\/([a-zA-Z0-9_-]+)$/;\n  const match = str.match(pattern);\n\n  if (match) {\n    // Extract the username and id\n    return {\n      userName: match[1],\n      idOrSlug: match[2],\n    };\n  } else {\n    // Return null if the string does not match\n    return null;\n  }\n};\n\n// // Example usages\n// const result1 = extractDetails(\"@curran/21f72bf74ef04ea0b9c9b82aaaec859a\");\n// console.log(result1); // { username: \"curran\", id: \"21f72bf74ef04ea0b9c9b82aaaec859a\" }\n\n// const result2 = extractDetails(\"@curran/scatter-plot\");\n// console.log(result2); // { username: \"curran\", id: \"scatter-plot\" }\n","// A custom Rollup plugin to:\n//  * Implement a virtual file system\n//  * Support importing across vizzes\n// Unified Rollup plugin for virtual file system and viz imports\n// Combines functionalities of 'virtual' and 'importFromViz' plugins\nimport { InputPluginOption } from \"rollup\";\nimport { VizId } from \"@vizhub/viz-types\";\nimport { isVizId } from \"@vizhub/viz-utils\";\nimport { extractVizImport } from \"./extractVizImport.js\";\nimport type { ResolvedVizFileId } from \"./types.js\";\nimport { parseId } from \"./parseId\";\nimport { SlugCache } from \"./slugCache.js\";\n\nconst debug = false;\n\nexport const vizResolve = ({\n  vizId,\n  slugCache,\n}: {\n  vizId: VizId;\n  slugCache?: SlugCache;\n}): InputPluginOption => ({\n  name: \"vizResolve\",\n  resolveId: async (\n    id: string,\n    importer: string | undefined,\n  ): Promise<ResolvedVizFileId | undefined> => {\n    if (debug) {\n      console.log(\"[vizIdResolve] resolveId() \" + id);\n      console.log(\"  importer: \" + importer);\n    }\n\n    // Handle virtual file system resolution\n    // .e.g. `import { foo } from './foo.js'`\n    // .e.g. `import { foo } from './foo'`\n    if (\n      id.startsWith(\"./\") &&\n      !importer?.startsWith(\"https://\")\n    ) {\n      let fileName = id.substring(2);\n\n      // Handle CSS files\n      // e.g. `import './styles.css'`\n      // Handle JS files\n      // e.g. `import { foo } from './foo.js'`\n      // e.g. `import { foo } from './foo'`\n      // Handle image files\n      // e.g. `import logoSrc from './logo.png'`\n      if (\n        !fileName.endsWith(\".js\") &&\n        !fileName.endsWith(\".css\") &&\n        !fileName.endsWith(\".csv\") &&\n        !fileName.endsWith(\".svelte\") &&\n        !fileName.endsWith(\".png\") &&\n        !fileName.endsWith(\".jpg\") &&\n        !fileName.endsWith(\".jpeg\") &&\n        !fileName.endsWith(\".gif\") &&\n        !fileName.endsWith(\".svg\") &&\n        !fileName.endsWith(\".webp\") &&\n        !fileName.endsWith(\".bmp\")\n      ) {\n        fileName += \".js\";\n      }\n\n      // const js = (name: string) =>\n      // name.endsWith('.js') ? name : name + '.js';\n\n      // If there is an importer, then the file is not part of\n      // the entry point, so it should be resolved relative\n      // to the importer's directory\n      if (importer) {\n        const {\n          vizId: importerVizId,\n          fileName: importerFileName,\n        } = parseId(importer);\n        // Get the directory of the importing file\n        const importerDir = importerFileName\n          .split(\"/\")\n          .slice(0, -1)\n          .join(\"/\");\n        // Combine the directory with the imported file name\n        const resolvedFileName = importerDir\n          ? `${importerDir}/${fileName}`\n          : fileName;\n        return `${importerVizId}/${resolvedFileName}`;\n      }\n      return vizId + \"/\" + fileName;\n    }\n\n    // Handle viz import resolution\n    // e.g. `import { foo } from '@curran/98e6d6509a1e407897d4f238a330efec'`\n    // e.g. `import { foo } from '@curran/scatter-plot'`\n    const vizImport = extractVizImport(id);\n    if (vizImport) {\n      let vizId: VizId;\n      if (isVizId(vizImport.idOrSlug)) {\n        vizId = vizImport.idOrSlug;\n      } else {\n        if (!slugCache) {\n          throw new Error(\n            \"slugCache is required to import by slug in v3 runtime\",\n          );\n        }\n\n        vizId = await slugCache.get(\n          `${vizImport.userName}/${vizImport.idOrSlug}`,\n        );\n      }\n      return vizId + \"/index.js\";\n    }\n\n    // If neither condition is met, return undefined.\n    return undefined;\n  },\n});\n","/**\n * Image support utilities for VizHub Runtime\n * Handles detection, MIME type resolution, and data URL conversion for image files\n */\n\nexport const IMAGE_EXTENSIONS = [\n  \".jpg\",\n  \".jpeg\",\n  \".png\",\n  \".gif\",\n  \".svg\",\n  \".webp\",\n  \".bmp\",\n] as const;\n\n/**\n * Checks if a filename represents an image file based on its extension\n */\nexport const isImageFile = (filename: string): boolean => {\n  const extension = filename.toLowerCase().split(\".\").pop();\n  if (!extension) return false;\n  return IMAGE_EXTENSIONS.includes(`.${extension}` as any);\n};\n\n/**\n * Gets the appropriate MIME type for an image file based on its extension\n */\nexport const getImageMimeType = (\n  filename: string,\n): string => {\n  const extension = filename.toLowerCase().split(\".\").pop();\n  switch (extension) {\n    case \"jpg\":\n    case \"jpeg\":\n      return \"image/jpeg\";\n    case \"png\":\n      return \"image/png\";\n    case \"gif\":\n      return \"image/gif\";\n    case \"svg\":\n      return \"image/svg+xml\";\n    case \"webp\":\n      return \"image/webp\";\n    case \"bmp\":\n      return \"image/bmp\";\n    default:\n      return \"image/png\"; // fallback\n  }\n};\n\n/**\n * Simple check to determine if content appears to be base64 encoded\n */\nconst isBase64Encoded = (content: string): boolean => {\n  // Remove whitespace and check if it matches base64 pattern\n  const cleaned = content.replace(/\\s/g, \"\");\n  // Base64 regex pattern - allow empty content as base64\n  return /^[A-Za-z0-9+/]*={0,2}$/.test(cleaned);\n};\n\n/**\n * Converts image file content to a data URL for use in HTML/CSS\n */\nexport const convertImageToDataURL = (\n  filename: string,\n  content: string,\n): string => {\n  const mimeType = getImageMimeType(filename);\n  const extension = filename.toLowerCase().split(\".\").pop();\n\n  // Handle SVG files that might not be base64 encoded\n  if (extension === \"svg\" && !isBase64Encoded(content)) {\n    return `data:${mimeType};utf8,${encodeURIComponent(content)}`;\n  }\n\n  // For all other images, assume base64 encoding\n  return `data:${mimeType};base64,${content}`;\n};\n\n/**\n * Processes HTML content by replacing image src attributes with data URLs\n * when the corresponding image files are available in the file collection\n */\nexport const processHTMLImages = (\n  html: string,\n  files: Record<string, string>,\n): string => {\n  // Match img tags and capture the src attribute value\n  return html.replace(\n    /<img([^>]*)\\s+src=[\"']([^\"']+)[\"']([^>]*)>/gi,\n    (match, beforeSrc, src, afterSrc) => {\n      // Check if the src references a file in our collection and is an image\n      if (files[src] !== undefined && isImageFile(src)) {\n        const dataURL = convertImageToDataURL(\n          src,\n          files[src],\n        );\n        return `<img${beforeSrc} src=\"${dataURL}\"${afterSrc}>`;\n      }\n      return match;\n    },\n  );\n};\n","import { InputPluginOption } from \"rollup\";\nimport {\n  FileCollection,\n  VizContent,\n  VizId,\n} from \"@vizhub/viz-types\";\nimport { getFileText } from \"@vizhub/viz-utils\";\nimport type { ResolvedVizFileId } from \"./types\";\nimport { parseId } from \"./parseId\";\nimport { VizCache } from \"./vizCache.js\";\nimport {\n  isImageFile,\n  convertImageToDataURL,\n} from \"../common/imageSupport\";\n\nconst debug = false;\n\n// Responsible for loading all imports and\n// tracking which CSS files are imported.\n// Throws an error if a file is imported but not found.\nexport const vizLoad = ({\n  vizCache,\n  trackCSSImport,\n  vizId,\n  files,\n}: {\n  vizCache: VizCache;\n  trackCSSImport: (cssFile: ResolvedVizFileId) => void;\n  vizId?: VizId;\n  files?: FileCollection;\n}): InputPluginOption => ({\n  name: \"vizLoad\",\n\n  // `id` here is of the form\n  // `{vizId}/{fileName}`\n  load: async (id: ResolvedVizFileId) => {\n    if (debug) {\n      console.log(\"[vizLoadCSS]: load() \" + id);\n    }\n\n    const parsedId = parseId(id);\n    const parsedVizId = parsedId.vizId;\n    const parsedFileName = parsedId.fileName;\n\n    if (debug) {\n      console.log(\"  [vizLoadCSS] vizId: \" + parsedVizId);\n      console.log(\n        \"  [vizLoadCSS] fileName: \" + parsedFileName,\n      );\n    }\n\n    // For CSS imports, all we need to do here is\n    // keep track of them so they can be injected\n    // into the IFrame later.\n    if (parsedFileName.endsWith(\".css\")) {\n      if (debug) {\n        console.log(\n          \"    [vizResolve] tracking CSS import for \" + id,\n        );\n      }\n      // The import is tracked here so that it can be\n      // injected into the IFrame later, external to the\n      // Rollup build.\n      trackCSSImport(id);\n      // TODO consider using Rollup's `emitFile` to emit a CSS file.\n      return \"\";\n    }\n\n    // If we are resolving to the root vizId, we can\n    // use the files object directly.\n    // Otherwise, we need to get the content from the vizCache.\n    // This makes it so the vizCache is _only_ used for\n    // resolving cross-viz imports.\n    let fileText: string | null = null;\n    if (parsedVizId === vizId && files) {\n      fileText = files[parsedFileName] || null;\n    } else {\n      const content = await vizCache.get(parsedVizId);\n      fileText = getFileText(content, parsedFileName);\n    }\n\n    // If a file is imported but not found, throw an error.\n    if (fileText === null) {\n      throw new Error(\n        `Imported file \"${parsedFileName}\" not found.`,\n      );\n      // TODO ideally show username/slug instead of vizId\n      // `Imported file \"${fileName}\" not found in viz ${vizId}`,\n      // `Imported file \"${fileName}\" not found.`,\n      // );\n    }\n\n    // Handle image files by returning them as data URL exports\n    if (isImageFile(parsedFileName)) {\n      const dataURL = convertImageToDataURL(\n        parsedFileName,\n        fileText,\n      );\n      return `export default \"${dataURL}\";`;\n    }\n\n    return fileText;\n  },\n});\n","import type { InputPluginOption } from \"rollup\";\nimport { parseId } from \"./parseId\";\nimport type { ResolvedVizFileId } from \"./types\";\n\nconst debug = false;\n\n// The cache of fetched files.\nconst fetchedFileCache = new Map<string, string>();\n\n// Cache for resolved svelte import paths to avoid repeated HTTP requests\nconst svelteImportCache = new Map<string, string>();\n\n// The Svelte compiler.\nexport type SvelteCompiler = (\n  code: string,\n  options: any,\n) => {\n  js: { code: string; map?: object };\n  css?: { code: string; map?: object } | null;\n};\nlet compile: SvelteCompiler;\n\nconst svelteURL =\n  \"https://cdn.jsdelivr.net/npm/svelte@5.37.1\";\n\nexport const svelteCompilerUrl = `${svelteURL}/compiler/index.js`;\n\n/**\n * Tries to resolve a svelte import path by testing different suffixes.\n * Similar to the resolve function in the alias plugin reference.\n */\nasync function resolveSvelteImport(\n  basePath: string,\n): Promise<string> {\n  // Check cache first\n  const cached = svelteImportCache.get(basePath);\n  if (cached) {\n    return cached;\n  }\n\n  const suffixes = [\".js\", \"/index.js\"];\n\n  for (const suffix of suffixes) {\n    const url = `${basePath}${suffix}`;\n    try {\n      // Make a HEAD request to check if the file exists without downloading it\n      const response = await fetch(url, { method: \"HEAD\" });\n      if (response.ok) {\n        // Cache the successful resolution\n        svelteImportCache.set(basePath, url);\n        return url;\n      }\n    } catch (error) {\n      // Continue to next suffix if this one fails\n      continue;\n    }\n  }\n\n  // If none of the suffixes work, return the original .js version as fallback\n  const fallback = `${basePath}.js`;\n  svelteImportCache.set(basePath, fallback);\n  return fallback;\n}\n\n// Responsible for transforming Svelte files.\n// Inspired by:\n//  * https://github.com/sveltejs/sites/blob/master/packages/repl/src/lib/workers/compiler/index.js#L2\n//  * https://github.com/sveltejs/sites/blob/master/packages/repl/src/lib/workers/bundler/index.js#L358\n//  * https://github.com/sveltejs/rollup-plugin-svelte/blob/master/index.js#L146C4-L146C51\nexport const transformSvelte = ({\n  getSvelteCompiler,\n}: {\n  getSvelteCompiler?: () => Promise<any>;\n}): InputPluginOption => ({\n  name: \"transformSvelte\",\n\n  load: async (resolved: string) => {\n    // Handle virtual esm-env module\n    if (resolved === \"virtual:esm-env\") {\n      return `\nexport const BROWSER = true;\nexport const DEV = true;\nexport const NODE = false;\nexport const PROD = false;\n`;\n    }\n\n    if (!resolved.startsWith(svelteURL)) {\n      return;\n    }\n    if (debug) {\n      console.log(\"[transformSvelte]: load() \" + resolved);\n    }\n\n    const cachedFile = fetchedFileCache.get(resolved);\n    if (cachedFile) return cachedFile;\n\n    const fetchedFile = await fetch(resolved).then((res) =>\n      res.text(),\n    );\n\n    fetchedFileCache.set(resolved, fetchedFile);\n\n    return fetchedFile;\n  },\n\n  // From https://github.com/sveltejs/sites/blob/master/packages/repl/src/lib/workers/bundler/index.js#L255C2-L271C5\n  resolveId: async (importee, importer) => {\n    if (debug) {\n      console.log(\n        \"[transformSvelte] resolveId() \" + importee,\n      );\n      console.log(\"importee: \" + importee);\n      console.log(\"importer: \" + importer);\n    }\n\n    // Special case for esm-env - provide browser environment constants\n    if (importee === \"esm-env\") {\n      return \"virtual:esm-env\";\n    }\n\n    // importing from Svelte\n    if (importee === `svelte`) {\n      return `${svelteURL}/src/index-client.js`;\n    }\n    if (importee.startsWith(`svelte/`)) {\n      const sub_path = importee.slice(7);\n      const basePath = `${svelteURL}/src/${sub_path}`;\n      return await resolveSvelteImport(basePath);\n    }\n\n    // Handle Svelte internal package imports (e.g., #client/constants)\n    if (importee.startsWith(\"#client/\")) {\n      const sub_path = importee.slice(8); // Remove '#client/'\n      const basePath = `${svelteURL}/src/internal/client/${sub_path}`;\n      return await resolveSvelteImport(basePath);\n    }\n\n    // importing from a URL\n    if (/^https?:/.test(importee)) return importee;\n\n    // Relative imports\n    if (importee.startsWith(\".\")) {\n      if (importer && importer.startsWith(svelteURL)) {\n        const resolved = new URL(importee, importer).href;\n        const url = new URL(importee, importer).href;\n        if (debug) {\n          console.log(\n            \"[transformSvelte] resolveId() \" + resolved,\n          );\n        }\n        return resolved;\n      }\n    }\n  },\n\n  transform: async (\n    code: string,\n    id: ResolvedVizFileId,\n  ) => {\n    const { fileName } = parseId(id);\n\n    const isSvelte = fileName.endsWith(\".svelte\");\n\n    if (isSvelte) {\n      if (!compile) {\n        if (!getSvelteCompiler) {\n          throw new Error(\"Svelte compiler not available\");\n        }\n        compile = await getSvelteCompiler();\n      }\n\n      const compiled = compile(code, {\n        filename: fileName,\n        generate: \"client\", // Svelte 5 uses 'client' instead of 'dom'\n        css: \"external\", // Extract CSS instead of auto-injecting\n        dev: false, // Production mode\n      });\n\n      // In Svelte 5, CSS is extracted separately if css: 'external' is used\n      let result = compiled.js.code;\n\n      // If there's CSS, inject it into the component\n      if (compiled.css && compiled.css.code) {\n        // Prepend CSS injection code to the component\n        const cssCode = JSON.stringify(compiled.css.code);\n        const cssInjection = `\n// Auto-inject CSS for Svelte component\n(function() {\n  if (typeof document !== 'undefined') {\n    const style = document.createElement('style');\n    style.textContent = ${cssCode};\n    document.head.appendChild(style);\n  }\n})();\n`;\n        result = cssInjection + result;\n      }\n\n      return result;\n    }\n    return undefined;\n  },\n});\n","import { sucrasePlugin } from \"../common/sucrasePlugin\";\nimport type {\n  RollupBuild,\n  RollupOptions,\n  OutputOptions,\n  Plugin,\n} from \"rollup\";\nimport { FileCollection, VizId } from \"@vizhub/viz-types\";\nimport {\n  getGlobals,\n  packageJSON,\n} from \"../common/packageJson.js\";\nimport { transformDSV } from \"./transformDSV/index.js\";\nimport { vizResolve } from \"./vizResolve.js\";\nimport { VizCache } from \"./vizCache.js\";\nimport { vizLoad } from \"./vizLoad.js\";\nimport { SlugCache } from \"./slugCache.js\";\nimport {\n  SvelteCompiler,\n  transformSvelte,\n} from \"./transformSvelte.js\";\n\nexport const computeBundleJSV3 = async ({\n  files,\n  rollup,\n  enableSourcemap = true,\n  vizCache,\n  vizId,\n  slugCache,\n  getSvelteCompiler,\n}: {\n  files: FileCollection;\n  rollup: (options: RollupOptions) => Promise<RollupBuild>;\n  enableSourcemap?: boolean;\n  vizCache?: VizCache;\n  vizId?: VizId;\n  slugCache?: SlugCache;\n  getSvelteCompiler?: () => Promise<SvelteCompiler>;\n}): Promise<{ src: string; cssFiles: string[] }> => {\n  // Track CSS imports\n  const cssFilesSet = new Set<string>();\n  const trackCSSImport = (cssFile: string) => {\n    cssFilesSet.add(cssFile);\n  };\n  const indexJSContent = files[\"index.js\"];\n  if (!indexJSContent) {\n    throw new Error(\"Missing index.js\");\n  }\n\n  // Create a replace plugin similar to the REPL implementation\n  const replacePlugin: Plugin = {\n    name: \"replace\",\n    transform(code, id) {\n      // Replace process.env.NODE_ENV and other environment variables\n      let hasReplacements = false;\n      let transformedCode = code;\n\n      // Replace process.env.NODE_ENV\n      if (\n        transformedCode.includes(\"process.env.NODE_ENV\")\n      ) {\n        transformedCode = transformedCode.replace(\n          /\\bprocess\\.env\\.NODE_ENV\\b/g,\n          JSON.stringify(\"production\"),\n        );\n        hasReplacements = true;\n      }\n\n      return hasReplacements\n        ? { code: transformedCode, map: null }\n        : null;\n    },\n  };\n\n  const inputOptions: RollupOptions = {\n    input: \"./index.js\",\n    plugins: [\n      ...(vizId ? [vizResolve({ vizId, slugCache })] : []),\n      transformDSV(),\n      sucrasePlugin(),\n      transformSvelte({ getSvelteCompiler }),\n      replacePlugin,\n      ...(vizCache\n        ? [\n            vizLoad({\n              vizCache,\n              trackCSSImport,\n              vizId,\n              files,\n            }),\n          ]\n        : []),\n    ],\n    onwarn(warning, warn) {\n      // Suppress \"treating module as external dependency\" warnings\n      if (warning.code === \"UNRESOLVED_IMPORT\") return;\n      warn(warning);\n    },\n  };\n\n  const outputOptions: OutputOptions = {\n    format: \"umd\",\n    name: \"Viz\",\n    sourcemap: enableSourcemap ? true : false,\n    compact: true,\n  };\n\n  const pkg = packageJSON(files);\n  if (pkg) {\n    const globals = getGlobals(pkg);\n    if (globals) {\n      inputOptions.external = Object.keys(globals);\n      outputOptions.globals = globals;\n    }\n  }\n\n  // Handle Svelte internal modules that might be treated as external\n  if (!inputOptions.external) {\n    inputOptions.external = [];\n  }\n  if (!outputOptions.globals) {\n    outputOptions.globals = {};\n  }\n\n  // Ensure Svelte internal modules are not treated as external\n  // by filtering them out if they were added\n  if (Array.isArray(inputOptions.external)) {\n    inputOptions.external = inputOptions.external.filter(\n      (ext) =>\n        typeof ext === \"string\" &&\n        !ext.startsWith(\"#client/\"),\n    );\n  }\n\n  const bundle = await rollup(inputOptions);\n\n  const { output } = await bundle.generate(outputOptions);\n  return {\n    src: output[0].code,\n    cssFiles: Array.from(cssFilesSet),\n  };\n};\n","/**\n * Formats an error object into a readable error message for runtime errors\n */\nexport const formatRuntimeError = (\n  error: Error | ErrorEvent | PromiseRejectionEvent,\n): string => {\n  if (error instanceof Error) {\n    // Regular Error object\n    const stack = error.stack || \"\";\n    const message = error.message || \"Unknown error\";\n    return `${error.name || \"Error\"}: ${message}\\n${stack}`;\n  } else if (\n    \"error\" in error &&\n    error.error instanceof Error\n  ) {\n    // ErrorEvent from window.addEventListener('error')\n    const err = error.error;\n    const stack = err.stack || \"\";\n    const message = err.message || \"Unknown error\";\n    const filename =\n      \"filename\" in error ? error.filename : \"\";\n    const lineno = \"lineno\" in error ? error.lineno : \"\";\n    const colno = \"colno\" in error ? error.colno : \"\";\n\n    let location = \"\";\n    if (filename && lineno) {\n      location = ` at ${filename}:${lineno}`;\n      if (colno) location += `:${colno}`;\n    }\n\n    return `${err.name || \"Error\"}: ${message}${location}\\n${stack}`;\n  } else if (\"reason\" in error) {\n    // PromiseRejectionEvent from window.addEventListener('unhandledrejection')\n    const reason = error.reason;\n    if (reason instanceof Error) {\n      const stack = reason.stack || \"\";\n      const message = reason.message || \"Unknown error\";\n      return `Unhandled Promise Rejection - ${reason.name || \"Error\"}: ${message}\\n${stack}`;\n    } else {\n      return `Unhandled Promise Rejection: ${String(reason)}`;\n    }\n  } else {\n    // Fallback for unknown error types\n    return `Unknown runtime error: ${String(error)}`;\n  }\n};\n\n/**\n * Returns JavaScript code that sets up global error handlers for runtime error detection\n */\nexport const getRuntimeErrorHandlerScript = (): string => {\n  return `\n    // Global error handling for runtime errors\n    (() => {\n      const formatRuntimeError = ${formatRuntimeError.toString()};\n      \n      // Handle uncaught JavaScript errors\n      window.addEventListener('error', (event) => {\n        const formattedErrorMessage = formatRuntimeError(event);\n        parent.postMessage({ \n          type: 'runtimeError', \n          formattedErrorMessage \n        }, \"*\");\n      });\n      \n      // Handle unhandled promise rejections\n      window.addEventListener('unhandledrejection', (event) => {\n        const formattedErrorMessage = formatRuntimeError(event);\n        parent.postMessage({ \n          type: 'runtimeError', \n          formattedErrorMessage \n        }, \"*\");\n      });\n    })();\n  `;\n};\n","import { getRuntimeErrorHandlerScript } from \"../common/runtimeErrorHandling\";\n\nfunction randomDigits() {\n  return Math.random().toString().slice(2, 7);\n}\n\nexport const htmlTemplate = ({\n  cdn,\n  src,\n  styles,\n}: {\n  cdn: string;\n  src: string;\n  styles: string;\n}) => {\n  // Random container id to avoid conflicts and guarantee\n  // the code is portable.\n  const containerSuffix = randomDigits();\n\n  const vizContainerId = `viz-container-${containerSuffix}`;\n\n  return `<!DOCTYPE html>\n<html>\n<head>\n  <meta charset=\"utf-8\">${cdn}${styles}\n  <style>\n    body {\n      margin: 0;\n      overflow: hidden;\n    }\n    #${vizContainerId} {\n      height: 100vh;\n    }\n  </style>\n</head>\n<body>\n  <div id=\"${vizContainerId}\"></div>\n  <script>${getRuntimeErrorHandlerScript()}</script>\n  <script id=\"injected-script\">${src}</script>\n  <script>\n    (() => {\n      let cleanup;\n      const render = () => {\n        const container = document.getElementById('${vizContainerId}');\n        typeof cleanup === 'function' && cleanup();\n        cleanup = (Viz.viz || Viz.main)(container, { state: window.state, setState, writeFile });\n      };\n      const setState = (next) => {\n        window.state = next(window.state);\n        render();\n      };\n      const writeFile = (fileName, content) => {\n        parent.postMessage({ type: 'writeFile', fileName, content }, \"*\");\n      };\n      const run = () => {\n        try {\n          setState((state) => state || {});\n        } catch (error) {\n          console.error(error);\n          parent.postMessage({ type: 'runError', error }, \"*\");\n        }\n      }\n      run();\n      const runJS = (src) => {\n        document.getElementById('injected-script')?.remove();\n        const script = document.createElement('script');\n        script.textContent = src;\n        script.id = 'injected-script';\n        document.body.appendChild(script);\n        run();\n      };\n      const runCSS = (css) => {\n        let style = document.getElementById('injected-style');\n        if (!style) {\n          style = document.createElement('style');\n          style.type = 'text/css';\n          style.id = 'injected-style';\n          document.head.appendChild(style);\n        }\n        style.textContent = css;\n      };\n      onmessage = (message) => {\n        switch (message.data.type) {\n          case 'runJS':\n            runJS(message.data.js);\n            parent.postMessage({ type: 'runDone' }, \"*\");\n            break;\n          case 'runCSS':\n            runCSS(message.data.css);\n            break;\n          case 'ping':\n            parent.postMessage({ type: 'pong' }, \"*\");\n            break;\n          default:\n            break;\n        }\n      }\n    })();\n  </script>\n</body>\n</html>`;\n};\n","import { RollupBuild, RollupOptions } from \"rollup\";\nimport { getFileText } from \"@vizhub/viz-utils\";\nimport { computeBundleJSV3 } from \"./computeBundleJSV3\";\nimport { htmlTemplate } from \"./htmlTemplate\";\nimport { VizCache } from \"./vizCache.js\";\nimport {\n  FileCollection,\n  VizContent,\n  VizId,\n} from \"@vizhub/viz-types\";\nimport { parseId } from \"./parseId.js\";\nimport { ResolvedVizFileId } from \"./types.js\";\nimport { SlugCache } from \"./slugCache.js\";\nimport { SvelteCompiler } from \"./transformSvelte.js\";\nimport {\n  dependencies,\n  getConfiguredLibraries,\n  dependencySource,\n} from \"../common/packageJson\";\nimport { BuildResult } from \"../build/types\";\n\nexport const v3Build = async ({\n  files,\n  rollup,\n  enableSourcemap = true,\n  vizCache,\n  vizId,\n  slugCache,\n  getSvelteCompiler,\n}: {\n  files: FileCollection;\n  rollup: (options: RollupOptions) => Promise<RollupBuild>;\n  enableSourcemap?: boolean;\n  vizCache: VizCache;\n  vizId: VizId;\n  slugCache?: SlugCache;\n  getSvelteCompiler?: () => Promise<SvelteCompiler>;\n}): Promise<BuildResult> => {\n  const { src, cssFiles } = await computeBundleJSV3({\n    files,\n    rollup,\n    enableSourcemap,\n    vizCache,\n    vizId,\n    slugCache,\n    getSvelteCompiler,\n  });\n\n  // Generate CSS styles from imported CSS files\n  let cssFileTextArray: string[] = [];\n\n  // Inject CSS files.\n  if (cssFiles.length > 0) {\n    for (let i = 0; i < cssFiles.length; i++) {\n      const id: ResolvedVizFileId = cssFiles[i];\n\n      const parsedId = parseId(id);\n      const parsedVizId = parsedId.vizId;\n      const parsedFileName = parsedId.fileName;\n\n      // If we are resolving to the root vizId, we can\n      // use the files object directly.\n      // Otherwise, we need to get the content from the vizCache.\n      // This makes it so the vizCache is _only_ used for\n      // resolving cross-viz imports.\n      let fileText: string | null = null;\n      if (parsedVizId === vizId && files) {\n        fileText = files[parsedFileName] || null;\n      } else {\n        const content = await vizCache.get(parsedVizId);\n        fileText = getFileText(content, parsedFileName);\n      }\n      if (fileText) {\n        cssFileTextArray.push(fileText);\n      }\n    }\n  }\n\n  // The concatenated CSS text.\n  const css = cssFileTextArray.join(\"\\n\");\n\n  const styles = `\\n    <style id=\"injected-style\">${css}</style>`;\n  // Generate CDN script tags for dependencies\n  let cdn = \"\";\n  const deps: [string, string][] = Object.entries(\n    dependencies(files),\n  );\n  if (deps.length > 0) {\n    const libraries = getConfiguredLibraries(files);\n    cdn = deps\n      .map(([name, version], i) => {\n        const dependencySrc = dependencySource(\n          { name, version },\n          libraries,\n        );\n        const indent = i > 0 ? \"    \" : \"\\n    \";\n        return `${indent}<script src=\"${dependencySrc}\"></script>`;\n      })\n      .join(\"\");\n  }\n\n  return {\n    html: htmlTemplate({ cdn, src, styles }),\n    css,\n    js: src,\n    runtimeVersion: \"v3\",\n  };\n};\n","import { VizContent, VizId } from \"@vizhub/viz-types\";\n\nexport type VizCache = {\n  get: (vizId: string) => Promise<VizContent>;\n  set: (content: VizContent) => void;\n  invalidate: (vizId: string) => void;\n};\n\n// A cache of viz content.\n// For use in resolving imports from other vizzes.\n// Runs both on the server and in the browser.\nexport const createVizCache = ({\n  initialContents,\n  handleCacheMiss,\n}: {\n  initialContents: Array<VizContent>;\n  handleCacheMiss?: (vizId: VizId) => Promise<VizContent>;\n}): VizCache => {\n  // Track the content of cached vizzes.\n  const contentMap = new Map<VizId, VizContent>(\n    initialContents.map((content) => [content.id, content]),\n  );\n\n  // Gets the content of a viz.\n  // Returns the cached content if it exists.\n  // Otherwise, calls handleCacheMiss to fetch the content.\n  const get = async (\n    vizId: string,\n  ): Promise<VizContent> => {\n    const cachedContent: VizContent | undefined =\n      contentMap.get(vizId);\n\n    // Cache hit\n    if (cachedContent !== undefined) {\n      return cachedContent;\n    }\n\n    // Cache miss\n    if (!handleCacheMiss) {\n      throw new Error(\n        `Unresolved import from vizId ${vizId}, cache miss handler not provided.`,\n      );\n    }\n    const freshContent = await handleCacheMiss(vizId);\n\n    if (freshContent) {\n      contentMap.set(vizId, freshContent);\n      return freshContent;\n    }\n\n    // TODO surface this error to the user\n    throw new Error(\n      `Unresolved import from vizId ${vizId}`,\n    );\n  };\n\n  // Updates the content of a viz in the cache.\n  const set = (content: VizContent) => {\n    contentMap.set(content.id, content);\n  };\n\n  const invalidate = (vizId: VizId) => {\n    contentMap.delete(vizId);\n  };\n\n  return { get, set, invalidate };\n};\n","import { VizId } from \"@vizhub/viz-types\";\n\nexport type SlugIdentifier = `${string}/${string}`;\n\nexport type SlugCache = {\n  get: (slug: SlugIdentifier) => Promise<VizId>;\n  set: (slug: SlugIdentifier, vizId: VizId) => void;\n  invalidate: (slug: SlugIdentifier) => void;\n};\n\n// A cache of viz IDs for slug resolution.\n// Maps slug strings (username/slug) to viz IDs.\n// Side effect: `initialMappings` is mutated to add new mappings.\n// This is used to resolve slugs to viz IDs.\nexport const createSlugCache = ({\n  initialMappings = {},\n  handleCacheMiss,\n}: {\n  initialMappings?: Record<SlugIdentifier, VizId>;\n  handleCacheMiss?: (\n    slug: SlugIdentifier,\n  ) => Promise<VizId>;\n}): SlugCache => {\n  // Gets the viz ID for a slug.\n  // Returns the cached ID if it exists.\n  // Otherwise, calls handleCacheMiss to resolve the slug.\n  const get = async (\n    slug: SlugIdentifier,\n  ): Promise<VizId> => {\n    const cachedVizId: VizId | undefined =\n      initialMappings[slug];\n\n    // Cache hit\n    if (cachedVizId !== undefined) {\n      return cachedVizId;\n    }\n\n    // Cache miss\n    if (!handleCacheMiss) {\n      throw new Error(\n        `Unresolved slug ${slug}, cache miss handler not provided.`,\n      );\n    }\n\n    const resolvedVizId = await handleCacheMiss(slug);\n\n    if (resolvedVizId) {\n      initialMappings[slug] = resolvedVizId;\n      return resolvedVizId;\n    }\n\n    throw new Error(`Unresolved slug ${slug}`);\n  };\n\n  // Updates the mapping of a slug to a viz ID in the cache.\n  const set = (slug: SlugIdentifier, vizId: VizId) => {\n    initialMappings[slug] = vizId;\n  };\n\n  // Removes a slug mapping from the cache.\n  const invalidate = (slug: SlugIdentifier) => {\n    delete initialMappings[slug];\n  };\n\n  return { get, set, invalidate };\n};\n","// We want to remove the vizId from the error message\n// to make it more user-friendly.\n// Example error message before and after:\n// Before: \"7f0b69fcb754479699172d1887817027/index.js (14:8): Expected ';', '}' or <eof>\"\n// After: \"./index.js (14:8): Expected ';', '}' or <eof>\"\nexport const cleanRollupErrorMessage = ({\n  rawMessage,\n  vizId,\n}: {\n  rawMessage: string;\n  vizId: string;\n}) => {\n  const regex = new RegExp(vizId, \"g\");\n  return rawMessage?.replace(regex, \".\");\n};\n","import {\n  FileCollection,\n  VizContent,\n} from \"@vizhub/viz-types\";\nimport {\n  fileCollectionToVizFiles,\n  generateVizId,\n} from \"@vizhub/viz-utils\";\n\n/**\n * Creates a VizContent object with the given files\n * @param files An object with file names as keys and file content as values\n * @param title Optional title for the content\n * @returns A VizContent object with randomly generated IDs\n */\nexport const createVizContent = (\n  files: FileCollection,\n  title = \"Sample Content for Exporting\",\n  id = generateVizId(),\n): VizContent => {\n  return {\n    id,\n    files: fileCollectionToVizFiles(files),\n    title,\n  };\n};\n","import { FileCollection } from \"@vizhub/viz-types\";\nimport { runtimeVersion } from \"./types\";\n\nexport const determineRuntimeVersion = (\n  files: FileCollection,\n): runtimeVersion | null => {\n  if (Object.keys(files).length === 0) {\n    return null;\n  }\n\n  const hasIndexHTML = \"index.html\" in files;\n  const hasIndexJS = \"index.js\" in files;\n  const hasIndexJSX = \"index.jsx\" in files;\n\n  if (hasIndexHTML) {\n    const hasModuleScript =\n      files[\"index.html\"].includes('type=\"module\"');\n    if (hasModuleScript) {\n      return \"v4\";\n    }\n\n    if (hasIndexJS || hasIndexJSX) {\n      return \"v2\";\n    }\n    return \"v1\";\n  }\n\n  if (!hasIndexHTML && hasIndexJS) {\n    return \"v3\";\n  }\n\n  return null;\n};\n","import { FileCollection } from \"@vizhub/viz-types\";\nimport {\n  dependencies,\n  getConfiguredLibraries,\n  dependencySource,\n} from \"../common/packageJson\";\nimport { getRuntimeErrorHandlerScript } from \"../common/runtimeErrorHandling\";\n\nconst DEBUG = false;\n\n/* ------------------------------------------------------------------ */\n/*  tiny helpers                                                      */\n/* ------------------------------------------------------------------ */\n\nconst hasTagPair = (html: string, tag: string) =>\n  new RegExp(`<${tag}\\\\b`, \"i\").test(html) &&\n  new RegExp(`</${tag}>`, \"i\").test(html);\n\n/**  Make sure we have a complete <html><head></head><body></body> skeleton.   */\nconst normaliseSkeleton = (raw: string): string => {\n  const trimmed = raw.trim();\n\n  // If it already contains a *complete* html‑head‑body trio we keep it.\n  if (\n    hasTagPair(trimmed, \"html\") &&\n    hasTagPair(trimmed, \"head\") &&\n    hasTagPair(trimmed, \"body\")\n  )\n    return trimmed;\n\n  // Otherwise wrap whatever is there inside a fresh skeleton.\n  return `<html><head></head><body>${trimmed}</body></html>`;\n};\n\n/** Remove every script whose src matches the supplied RegExp (global & i). */\nconst stripScripts = (\n  html: string,\n  srcPattern: RegExp,\n): string =>\n  html.replace(\n    new RegExp(\n      `<script[^>]*src=[\"'][^\"']*${srcPattern.source}[^\"']*[\"'][^>]*>\\\\s*</script>`,\n      \"gi\",\n    ),\n    \"\",\n  );\n\n/** Inject markup just before a closing tag (</head> or </body>). */\nconst injectBeforeClose = (\n  html: string,\n  closing: \"</head>\" | \"</body>\",\n  markup: string,\n) =>\n  html.replace(\n    new RegExp(closing, \"i\"),\n    `${markup}${closing}`,\n  );\n\n/* ------------------------------------------------------------------ */\n/*  core logic                                                        */\n/* ------------------------------------------------------------------ */\n\nconst injectScripts = (\n  template: string,\n  files: FileCollection,\n): string => {\n  let html = normaliseSkeleton(template);\n\n  /* -------------------- dependencies from package.json ------------ */\n  const deps = Object.entries(dependencies(files)) as [\n    string,\n    string,\n  ][];\n\n  if (deps.length) {\n    const libraries = getConfiguredLibraries(files);\n\n    // Remove any previous dependency scripts\n    deps.forEach(([name]) => {\n      html = stripScripts(html, new RegExp(`${name}@`));\n    });\n\n    // Build & inject new ones (order preserved)\n    const depMarkup = deps\n      .map(([name, version]) =>\n        dependencySource({ name, version }, libraries),\n      )\n      .map((src) => `<script src=\"${src}\"></script>`)\n      .join(\"\\n\");\n\n    html = injectBeforeClose(\n      html,\n      \"</head>\",\n      depMarkup + \"\\n\",\n    );\n  }\n\n  /* -------------------- ensure exactly ONE bundle.js -------------- */\n  const needBundle =\n    files[\"bundle.js\"] !== undefined ||\n    files[\"index.js\"] !== undefined;\n\n  if (needBundle) {\n    const bundleTag = `<script src=\"bundle.js\"></script>`; // **no newline – keeps test #3 exact**\n\n    // How many bundle.js scripts are already there & where?\n    const bundleRe =\n      /<script\\b[^>]*\\bsrc=[\"']bundle\\.js[\"'][^>]*>\\s*<\\/script>/gi;\n    const matches = [...html.matchAll(bundleRe)];\n\n    const oneInBody =\n      matches.length === 1 &&\n      (() => {\n        const idx = matches[0].index ?? -1;\n        if (idx === -1) return false;\n        const bodyOpen = html.search(/<body\\b[^>]*>/i);\n        const bodyClose = html.search(/<\\/body>/i);\n        return (\n          bodyOpen !== -1 &&\n          bodyClose !== -1 &&\n          idx > bodyOpen &&\n          idx < bodyClose\n        );\n      })();\n\n    if (!oneInBody) {\n      // wipe them all, then inject a clean one at the end of <body>\n      html = html.replace(bundleRe, \"\");\n      html = injectBeforeClose(html, \"</body>\", bundleTag);\n    }\n  }\n\n  /* -------------------- inject runtime error handler ------------- */\n  const errorHandlerScript = `<script>${getRuntimeErrorHandlerScript()}</script>\\n`;\n  html = injectBeforeClose(\n    html,\n    \"</head>\",\n    errorHandlerScript,\n  );\n\n  /* -------------------- make sure <!DOCTYPE html> ----------------- */\n  return /^\\s*<!DOCTYPE/i.test(html)\n    ? html\n    : `<!DOCTYPE html>${html}`;\n};\n\n/* ------------------------------------------------------------------ */\n/*  public API                                                        */\n/* ------------------------------------------------------------------ */\n\nexport const getComputedIndexHtml = (\n  files: FileCollection,\n): string => {\n  const htmlTemplate = files[\"index.html\"];\n\n  // No html and no JS – nothing to do.\n  if (\n    !htmlTemplate &&\n    !files[\"index.js\"] &&\n    !files[\"bundle.js\"]\n  ) {\n    DEBUG &&\n      console.log(\n        \"[getComputedIndexHtml] No index.html file found\",\n      );\n    return \"\";\n  }\n\n  const template =\n    htmlTemplate ||\n    \"<!DOCTYPE html><html><head></head><body></body></html>\";\n\n  const result = injectScripts(template, files);\n\n  DEBUG &&\n    console.log(\"[getComputedIndexHtml] indexHtml\", result);\n\n  return result;\n};\n","module.exports = {\n  'd3': 'd3',\n  'd3-array': 'd3',\n  'd3-axis': 'd3',\n  'd3-brush': 'd3',\n  'd3-chord': 'd3',\n  'd3-collection': 'd3',\n  'd3-color': 'd3',\n  'd3-contour': 'd3',\n  'd3-dispatch': 'd3',\n  'd3-drag': 'd3',\n  'd3-dsv': 'd3',\n  'd3-ease': 'd3',\n  'd3-fetch': 'd3',\n  'd3-force': 'd3',\n  'd3-format': 'd3',\n  'd3-geo': 'd3',\n  'd3-hierarchy': 'd3',\n  'd3-interpolate': 'd3',\n  'd3-path': 'd3',\n  'd3-polygon': 'd3',\n  'd3-quadtree': 'd3',\n  'd3-random': 'd3',\n  'd3-scale': 'd3',\n  'd3-scale-chromatic': 'd3',\n  'd3-selection': 'd3',\n  'd3-shape': 'd3',\n  'd3-tile': 'd3',\n  'd3-time': 'd3',\n  'd3-time-format': 'd3',\n  'd3-timer': 'd3',\n  'd3-transition': 'd3',\n  'd3-voronoi': 'd3',\n  'd3-zoom': 'd3',\n\n  'react': 'React',\n  'react-dom': 'ReactDOM',\n  'react-dropdown-browser': 'ReactDropdown',\n  'react-dropdown': 'ReactDropdown',\n\n  'three': 'THREE',\n\n  'vega': 'vega',\n  'vega-embed': 'vegaEmbed',\n  'vega-lite': 'vegaLite',\n  'vega-lite-api': 'vl',\n  'vega-tooltip': 'vegaTooltip',\n  'vega-themes': 'vegaThemes',\n  'vizhub-vega-lite-config': 'vizhubVegaLiteConfig',\n  \n  'semiotic': 'Semiotic',\n  \n  'viz.js': 'Viz'\n};\n","import { FileCollection } from \"@vizhub/viz-types\";\nimport type { Plugin } from \"rollup\";\nimport {\n  isImageFile,\n  convertImageToDataURL,\n} from \"./imageSupport\";\n\nexport const VIRTUAL_PREFIX = \"\\0virtual:\";\n\nconst normalizePath = (filepath: string): string => {\n  // Remove leading ./\n  let normalized = filepath.replace(/^\\.\\//, \"\");\n  // Replace multiple slashes with single slash\n  normalized = normalized.replace(/\\/+/g, \"/\");\n  // Remove trailing slash\n  normalized = normalized.replace(/\\/$/, \"\");\n  return normalized;\n};\n\nconst joinPaths = (\n  base: string,\n  relative: string,\n): string => {\n  // Get directory name of base path\n  const baseDir = base.includes(\"/\")\n    ? base.slice(0, base.lastIndexOf(\"/\"))\n    : \"\";\n\n  // Handle .. by removing one directory level\n  const parts = relative.split(\"/\");\n  const resultParts: string[] = baseDir\n    ? baseDir.split(\"/\")\n    : [];\n\n  for (const part of parts) {\n    if (part === \"..\") {\n      resultParts.pop();\n    } else if (part !== \".\" && part !== \"\") {\n      resultParts.push(part);\n    }\n  }\n\n  return resultParts.join(\"/\");\n};\n\nexport const virtualFileSystem = (\n  files: FileCollection,\n): Plugin => {\n  return {\n    name: \"virtual-file-system\",\n\n    resolveId(source: string, importer?: string) {\n      // Strip prefix from importer if present\n      const cleanImporter = importer?.startsWith(\n        VIRTUAL_PREFIX,\n      )\n        ? importer.slice(VIRTUAL_PREFIX.length)\n        : importer;\n\n      // Handle relative paths\n      if (\n        source.startsWith(\"./\") ||\n        source.startsWith(\"../\")\n      ) {\n        const resolvedPath = cleanImporter\n          ? normalizePath(joinPaths(cleanImporter, source))\n          : normalizePath(source);\n\n        // Try exact match first\n        if (files[resolvedPath]) {\n          return VIRTUAL_PREFIX + resolvedPath;\n        }\n\n        // Try with extensions if no exact match is found\n        const extensions = [\".js\", \".jsx\", \".ts\", \".tsx\"];\n        for (const ext of extensions) {\n          const pathWithExt = resolvedPath + ext;\n          if (files[pathWithExt]) {\n            return VIRTUAL_PREFIX + pathWithExt;\n          }\n        }\n      }\n\n      // Handle bare module imports\n      if (files[source]) {\n        return VIRTUAL_PREFIX + source;\n      }\n\n      // Try bare imports with extensions\n      const extensions = [\".js\", \".jsx\", \".ts\", \".tsx\"];\n      for (const ext of extensions) {\n        const pathWithExt = source + ext;\n        if (files[pathWithExt]) {\n          return VIRTUAL_PREFIX + pathWithExt;\n        }\n      }\n\n      return null;\n    },\n\n    load(id: string) {\n      // Only handle our virtual-prefixed IDs\n      if (id.startsWith(VIRTUAL_PREFIX)) {\n        const actualId = id.slice(VIRTUAL_PREFIX.length);\n        if (files[actualId]) {\n          // Handle image files by returning them as data URL exports\n          if (isImageFile(actualId)) {\n            const dataURL = convertImageToDataURL(\n              actualId,\n              files[actualId],\n            );\n            return `export default \"${dataURL}\";`;\n          }\n          // Handle regular files\n          return files[actualId];\n        }\n      }\n      return null;\n    },\n  };\n};\n","import type {\n  RollupBuild,\n  RollupOptions,\n  OutputOptions,\n} from \"rollup\";\nimport { FileCollection } from \"@vizhub/viz-types\";\n// @ts-ignore\nimport libraries from \"vizhub-libraries\";\nimport { virtualFileSystem } from \"../common/virtualFileSystem.js\";\nimport { sucrasePlugin } from \"../common/sucrasePlugin.js\";\nimport {\n  getGlobals,\n  packageJSON,\n} from \"../common/packageJson.js\";\n\nexport const computeBundleJSV2 = async ({\n  files,\n  rollup,\n  enableSourcemap = true,\n}: {\n  files: FileCollection;\n  rollup: (options: RollupOptions) => Promise<RollupBuild>;\n  enableSourcemap?: boolean;\n}): Promise<string> => {\n  // Check if the files contain index.js\n  let entryPoint = \"index.js\";\n  let indexJSContent = files[entryPoint];\n\n  // Check for index.jsx as a fallback\n  if (!indexJSContent) {\n    entryPoint = \"index.jsx\";\n    const indexJSContent = files[entryPoint];\n    if (!indexJSContent) {\n      throw new Error(\n        \"Missing entry point, can't find index.js or index.jsx\",\n      );\n    }\n  }\n\n  const inputOptions: RollupOptions = {\n    input: \"./\" + entryPoint,\n    plugins: [virtualFileSystem(files), sucrasePlugin()],\n    onwarn(warning, warn) {\n      // Suppress \"treating module as external dependency\" warnings\n      if (warning.code === \"UNRESOLVED_IMPORT\") return;\n      warn(warning);\n    },\n  };\n\n  const outputOptions: OutputOptions = {\n    format: \"iife\",\n    sourcemap: enableSourcemap,\n  };\n\n  const pkg = packageJSON(files);\n\n  if (pkg) {\n    const globals = {\n      // Pre-configured globals for v2 only\n      ...libraries,\n      // Libraries from package.json\n      ...getGlobals(pkg),\n    };\n    if (globals) {\n      inputOptions.external = Object.keys(globals);\n      outputOptions.globals = globals;\n    }\n  }\n\n  const bundle = await rollup(inputOptions);\n\n  const { output } = await bundle.generate(outputOptions);\n  return output[0].code;\n};\n","import type { RollupBuild, RollupOptions } from \"rollup\";\nimport { FileCollection } from \"@vizhub/viz-types\";\nimport { getComputedIndexHtml } from \"./getComputedIndexHtml\";\nimport { computeBundleJSV2 } from \"./computeBundleJSV2\";\n\nexport const v2Build = async ({\n  files,\n  rollup,\n  enableSourcemap,\n}: {\n  files: FileCollection;\n  rollup: (options: RollupOptions) => Promise<RollupBuild>;\n  enableSourcemap?: boolean;\n}): Promise<FileCollection> => ({\n  ...files,\n  \"bundle.js\": await computeBundleJSV2({\n    files,\n    rollup,\n    enableSourcemap,\n  }),\n  \"index.html\": getComputedIndexHtml(files),\n});\n","/**\n * Extract module script entry points from index.html\n */\nexport const extractModuleEntryPoints = (\n  html: string,\n): {\n  entryPoints: string[];\n  inlineScripts: Array<{ id: string; content: string }>;\n} => {\n  const entryPoints: string[] = [];\n  const inlineScripts: Array<{\n    id: string;\n    content: string;\n  }> = [];\n  const scriptTag =\n    /<script\\b([^>]*)>([\\s\\S]*?)<\\/script>/gi;\n  let m: RegExpExecArray | null;\n  let inlineScriptCounter = 0;\n\n  while ((m = scriptTag.exec(html)) !== null) {\n    const attrs = m[1];\n    const content = m[2];\n\n    if (!/\\btype\\s*=\\s*[\"']module[\"']/i.test(attrs))\n      continue;\n\n    const srcMatch = attrs.match(\n      /\\bsrc\\s*=\\s*[\"']([^\"']+)[\"']/i,\n    );\n\n    if (srcMatch) {\n      entryPoints.push(srcMatch[1]);\n    } else if (content.trim()) {\n      // Handle inline script\n      const inlineId = `__inline_script_${inlineScriptCounter++}.js`;\n      inlineScripts.push({\n        id: inlineId,\n        content: content.trim(),\n      });\n      entryPoints.push(inlineId);\n    }\n  }\n\n  return { entryPoints, inlineScripts };\n};\n","const DEBUG = false;\n\n// Catch unresolved module identifiers\n// and mark them as external,\n// assuming they are set up with import maps.\nexport const catchAll = () => ({\n  name: \"catch-all-prevent-fs\",\n\n  resolveId(source: string, importer: string | undefined) {\n    DEBUG &&\n      console.log(\n        \"[catch-all-prevent-fs] resolveId\",\n        source,\n        importer,\n      );\n    return { id: source, external: true };\n  },\n});\n","import type {\n  RollupBuild,\n  RollupOptions,\n  OutputOptions,\n} from \"rollup\";\nimport { FileCollection } from \"@vizhub/viz-types\";\nimport { virtualFileSystem } from \"..//common/virtualFileSystem.js\";\nimport { sucrasePlugin } from \"..//common/sucrasePlugin.js\";\nimport { catchAll } from \"./catchAll.js\";\n\nconst DEBUG = true;\n\n/**\n * Bundle a single ES module entry point\n */\nexport const bundleESModule = async ({\n  entryPoint,\n  files,\n  rollup,\n  enableSourcemap = true,\n}: {\n  entryPoint: string;\n  files: FileCollection;\n  rollup: (o: RollupOptions) => Promise<RollupBuild>;\n  enableSourcemap?: boolean;\n}): Promise<string> => {\n  // Support either of these:\n  // - <script type=\"module\" src=\"index.js\"></script>\n  // - <script type=\"module\" src=\"./index.js\"></script>\n  const input = entryPoint.startsWith(\"./\")\n    ? entryPoint\n    : `./${entryPoint}`;\n\n  const inputOptions: RollupOptions = {\n    input,\n    plugins: [\n      virtualFileSystem(files),\n      sucrasePlugin({\n        // Enable JSX runtime\n        // so we don't need to import React\n        // in every file that uses JSX\n        jsxRuntime: \"automatic\",\n      }),\n      catchAll(),\n    ],\n    // external: (source: string) => {\n    //   DEBUG && console.log(\"external\", source);\n\n    //   // Handle strings resolved by `virtualFileSystem`.\n    //   const isVirtualFile = source.startsWith(\"./\");\n\n    //   // Handle external dependencies, e.g. from import maps.\n    //   const isLibrary = !source.startsWith(\"./\");\n\n    //   const isExternal = !isVirtualFile || isLibrary;\n\n    //   DEBUG && console.log(\"isExternal\", isExternal);\n    //   return isExternal;\n    // },\n    onwarn(rollupLog, warn) {\n      // console.log(\"onwarn\", rollupLog);\n      // if (w.code === \"UNRESOLVED_IMPORT\") return; // quiet noisy warnings\n      // warn(rollupLog);\n\n      // Ignore all warnings\n      // TODO nicely present these warnings to the user\n      return;\n    },\n  };\n\n  const bundle = await rollup(inputOptions);\n  const { output } = await bundle.generate({\n    format: \"es\",\n    sourcemap: enableSourcemap,\n  } as OutputOptions);\n  return output[0].code;\n};\n","/**\n * Does the html already contain a <tag>…</tag> pair?\n */\nexport const hasTagPair = (html: string, tag: string) =>\n  new RegExp(`<${tag}\\\\b`, \"i\").test(html) &&\n  new RegExp(`</${tag}>`, \"i\").test(html);\n\n/**\n * Ensure <html><head></head><body></body> skeleton exists.\n */\nexport const normaliseSkeleton = (raw: string): string => {\n  const trimmed = raw.trim();\n\n  if (\n    hasTagPair(trimmed, \"html\") &&\n    hasTagPair(trimmed, \"head\") &&\n    hasTagPair(trimmed, \"body\")\n  )\n    return trimmed;\n\n  return `<html><head></head><body>${trimmed}</body></html>`;\n};\n\n/**\n * Escape characters so they can appear literally inside a RegExp.\n */\nexport const escapeRegExp = (s: string) =>\n  s.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n\n/**\n * Inject markup immediately before </head> or </body>.\n */\nexport const injectBeforeClose = (\n  html: string,\n  closing: \"</head>\" | \"</body>\",\n  markup: string,\n) =>\n  html.replace(\n    new RegExp(closing, \"i\"),\n    `${markup}${closing}`,\n  );\n","import { FileCollection } from \"@vizhub/viz-types\";\nimport {\n  dependencies,\n  getConfiguredLibraries,\n  dependencySource,\n} from \"../common/packageJson.js\";\n\n/**\n * Generate an import map for all dependencies\n */\nexport const generateImportMap = (\n  files: FileCollection,\n): string | null => {\n  const deps = dependencies(files);\n  if (Object.keys(deps).length === 0) return null;\n\n  const libraries = getConfiguredLibraries(files);\n  const imports: Record<string, string> = {};\n\n  for (const [name, version] of Object.entries(deps)) {\n    imports[name] = dependencySource(\n      { name, version },\n      libraries,\n    );\n  }\n  return JSON.stringify({ imports }, null, 2);\n};\n","/**\n * Hot reloading script for V4 runtime\n * This script is injected into V4 HTML to handle runJS messages\n */\nexport const getV4HotReloadScript = (): string => {\n  return `\n    // V4 Hot Reloading Support\n    (() => {\n      const runJS = (js) => {\n        // Remove all existing bundled module scripts\n        const existingScripts = document.querySelectorAll('script[type=\"module\"]');\n        existingScripts.forEach(script => {\n          // Only remove scripts that contain bundled code (not import maps or external scripts)\n          if (script.textContent && script.textContent.trim()) {\n            script.remove();\n          }\n        });\n        \n        // Create new script with updated bundled code\n        const script = document.createElement('script');\n        script.type = 'module';\n        script.textContent = js;\n        document.body.appendChild(script);\n      };\n      \n      const runCSS = (css) => {\n        let style = document.getElementById('v4-injected-style');\n        if (!style) {\n          style = document.createElement('style');\n          style.type = 'text/css';\n          style.id = 'v4-injected-style';\n          document.head.appendChild(style);\n        }\n        style.textContent = css;\n      };\n      \n      // Listen for hot reload messages\n      window.addEventListener('message', (message) => {\n        switch (message.data.type) {\n          case 'runJS':\n            try {\n              runJS(message.data.js);\n              parent.postMessage({ type: 'runDone' }, \"*\");\n            } catch (error) {\n              console.error('V4 Hot reload error:', error);\n              parent.postMessage({ type: 'runError', error }, \"*\");\n            }\n            break;\n          case 'runCSS':\n            runCSS(message.data.css);\n            break;\n          case 'ping':\n            parent.postMessage({ type: 'pong' }, \"*\");\n            break;\n          default:\n            break;\n        }\n      });\n    })();\n  `;\n};\n","import { FileCollection } from \"@vizhub/viz-types\";\nimport {\n  normaliseSkeleton,\n  escapeRegExp,\n  injectBeforeClose,\n} from \"./stringUtils.js\";\nimport { generateImportMap } from \"./importMap.js\";\nimport { getRuntimeErrorHandlerScript } from \"../common/runtimeErrorHandling.js\";\nimport { getV4HotReloadScript } from \"./hotReloadScript.js\";\n\n/**\n * Update HTML to include import map and bundled modules\n */\nexport const updateHTML = (\n  files: FileCollection,\n  bundled: Map<string, string>,\n  inlineScripts: Array<{\n    id: string;\n    content: string;\n  }> = [],\n  enableHotReload: boolean = false,\n): string => {\n  if (!files[\"index.html\"]) return \"\";\n\n  let html = normaliseSkeleton(files[\"index.html\"]);\n\n  // Replace each <script src=\"…\"> with inline module\n  bundled.forEach((code, src) => {\n    // Check if this is an inline script\n    const isInlineScript = inlineScripts.some(\n      (script) => script.id === src,\n    );\n\n    if (isInlineScript) {\n      // Find and replace the inline script tag\n      const inlineScriptContent =\n        inlineScripts.find((script) => script.id === src)\n          ?.content || \"\";\n      const escapedContent = escapeRegExp(\n        inlineScriptContent,\n      );\n      const inlineTagRe = new RegExp(\n        `<script\\\\b[^>]*\\\\btype=[\"']module[\"'][^>]*>\\\\s*${escapedContent}\\\\s*</script>`,\n        \"gi\",\n      );\n      html = html.replace(\n        inlineTagRe,\n        `<script type=\"module\">\\n${code}\\n</script>`,\n      );\n    } else {\n      // Handle src-based scripts\n      const tagRe = new RegExp(\n        `<script\\\\b[^>]*\\\\bsrc=[\"']${escapeRegExp(src)}[\"'][^>]*>[^<]*</script>`,\n        \"gi\",\n      );\n      html = html.replace(\n        tagRe,\n        `<script type=\"module\">\\n${code}\\n</script>`,\n      );\n    }\n  });\n\n  // Add <script type=\"importmap\"> if needed\n  const importMapJson = generateImportMap(files);\n  if (importMapJson) {\n    const already =\n      /<script\\b[^>]*type=[\"']importmap[\"'][^>]*>/i.test(\n        html,\n      );\n\n    if (!already) {\n      const importMapTag = `<script type=\"importmap\">\\n${importMapJson}\\n</script>\\n`;\n      html = injectBeforeClose(\n        html,\n        \"</head>\",\n        importMapTag,\n      );\n    }\n  }\n\n  // Add runtime error handler script\n  const errorHandlerScript = `<script>${getRuntimeErrorHandlerScript()}</script>\\n`;\n  html = injectBeforeClose(\n    html,\n    \"</head>\",\n    errorHandlerScript,\n  );\n\n  // Add hot reload script if enabled\n  if (enableHotReload) {\n    const hotReloadScript = `<script>${getV4HotReloadScript()}</script>\\n`;\n    html = injectBeforeClose(\n      html,\n      \"</body>\",\n      hotReloadScript,\n    );\n  }\n\n  // Ensure <!DOCTYPE html>\n  return /^\\s*<!DOCTYPE/i.test(html)\n    ? html\n    : `<!DOCTYPE html>${html}`;\n};\n","import type { RollupBuild, RollupOptions } from \"rollup\";\nimport { FileCollection } from \"@vizhub/viz-types\";\nimport { extractModuleEntryPoints } from \"./extractEntryPoints.js\";\nimport { bundleESModule } from \"./bundleModule.js\";\nimport { updateHTML } from \"./updateHTML.js\";\n\nconst DEBUG = false;\n\n/**\n * Build for v4 runtime\n */\nexport const v4Build = async ({\n  files,\n  rollup,\n  enableSourcemap = true,\n}: {\n  files: FileCollection;\n  rollup: (o: RollupOptions) => Promise<RollupBuild>;\n  enableSourcemap?: boolean;\n}): Promise<FileCollection> => {\n  const html = files[\"index.html\"] || \"\";\n  const { entryPoints, inlineScripts } =\n    extractModuleEntryPoints(html);\n\n  if (entryPoints.length === 0) {\n    DEBUG &&\n      console.log(\"[v4Build] No module entry points found\");\n    return files; // nothing to bundle\n  }\n\n  // Add inline scripts to the files collection\n  const extendedFiles = { ...files };\n  for (const inlineScript of inlineScripts) {\n    extendedFiles[inlineScript.id] = inlineScript.content;\n  }\n\n  const bundled = new Map<string, string>();\n  for (const entry of entryPoints) {\n    const code = await bundleESModule({\n      entryPoint: entry,\n      files: extendedFiles,\n      rollup,\n      enableSourcemap,\n    });\n    bundled.set(entry, code);\n  }\n\n  const updatedHTML = updateHTML(\n    extendedFiles,\n    bundled,\n    inlineScripts,\n    false,\n  );\n\n  return {\n    ...files,\n    \"index.html\": updatedHTML,\n  };\n};\n\n/**\n * Build for v4 runtime with hot reloading support\n * Returns both HTML and separate JS for hot reloading\n */\nexport const v4BuildWithHotReload = async ({\n  files,\n  rollup,\n  enableSourcemap = true,\n}: {\n  files: FileCollection;\n  rollup: (o: RollupOptions) => Promise<RollupBuild>;\n  enableSourcemap?: boolean;\n}): Promise<{\n  files: FileCollection;\n  bundledJS: string;\n}> => {\n  const html = files[\"index.html\"] || \"\";\n  const { entryPoints, inlineScripts } =\n    extractModuleEntryPoints(html);\n\n  if (entryPoints.length === 0) {\n    DEBUG &&\n      console.log(\n        \"[v4BuildWithHotReload] No module entry points found\",\n      );\n    return { files, bundledJS: \"\" };\n  }\n\n  // Add inline scripts to the files collection\n  const extendedFiles = { ...files };\n  for (const inlineScript of inlineScripts) {\n    extendedFiles[inlineScript.id] = inlineScript.content;\n  }\n\n  const bundled = new Map<string, string>();\n  const allBundledCode: string[] = [];\n\n  for (const entry of entryPoints) {\n    const code = await bundleESModule({\n      entryPoint: entry,\n      files: extendedFiles,\n      rollup,\n      enableSourcemap,\n    });\n    bundled.set(entry, code);\n    allBundledCode.push(code);\n  }\n\n  const updatedHTML = updateHTML(\n    extendedFiles,\n    bundled,\n    inlineScripts,\n    true,\n  );\n\n  // Concatenate all bundled JS for hot reloading\n  const bundledJS = allBundledCode.join(\"\\n\");\n\n  return {\n    files: {\n      ...files,\n      \"index.html\": updatedHTML,\n    },\n    bundledJS,\n  };\n};\n\n// Export the extractModuleEntryPoints function for external use\nexport { extractModuleEntryPoints };\n","import { magicSandbox } from \"magic-sandbox\";\nimport { FileCollection } from \"@vizhub/viz-types\";\nimport type { RollupBuild, RollupOptions } from \"rollup\";\nimport {\n  createVizCache,\n  createVizContent,\n  SlugCache,\n  SvelteCompiler,\n  v3Build,\n  VizCache,\n} from \"../v3\";\nimport { BuildResult } from \"./types\";\nimport { vizFilesToFileCollection } from \"@vizhub/viz-utils\";\nimport { determineRuntimeVersion } from \"./determineRuntimeVersion\";\nimport { v2Build } from \"../v2\";\nimport { v4Build, v4BuildWithHotReload } from \"../v4\";\nimport { VIRTUAL_PREFIX } from \"../common/virtualFileSystem\";\nimport { getRuntimeErrorHandlerScript } from \"../common/runtimeErrorHandling\";\nimport { processHTMLImages } from \"../common/imageSupport\";\n\nconst DEBUG = false;\n\n/**\n * Adds runtime error handling to V1 HTML that was processed by magicSandbox\n */\nconst addRuntimeErrorHandlingToV1 = (\n  html: string,\n): string => {\n  const errorHandlerScript = `<script>${getRuntimeErrorHandlerScript()}</script>`;\n\n  // Try to inject before </head> if it exists\n  if (html.includes(\"</head>\")) {\n    return html.replace(\n      \"</head>\",\n      `${errorHandlerScript}\\n</head>`,\n    );\n  }\n\n  // Try to inject before </body> if it exists\n  if (html.includes(\"</body>\")) {\n    return html.replace(\n      \"</body>\",\n      `${errorHandlerScript}\\n</body>`,\n    );\n  }\n\n  // If neither exists, inject at the end\n  return html + errorHandlerScript;\n};\n\n/**\n * Processes files for V1 runtime by converting image references in HTML to data URLs\n */\nconst processImagesForV1 = (\n  files: FileCollection,\n): FileCollection => {\n  const processedFiles = { ...files };\n\n  // Process HTML files to replace image src attributes with data URLs\n  for (const [filename, content] of Object.entries(\n    processedFiles,\n  )) {\n    if (filename.toLowerCase().endsWith(\".html\")) {\n      processedFiles[filename] = processHTMLImages(\n        content,\n        files,\n      );\n    }\n  }\n\n  return processedFiles;\n};\n\n// Builds the given files.\nexport const build = async ({\n  files,\n  rollup,\n  enableSourcemap = true,\n  vizCache,\n  vizId,\n  slugCache,\n  getSvelteCompiler,\n}: {\n  // Only required for v1 and v2 runtime\n  // For v3, EITHER files OR vizCache is required\n  files?: FileCollection;\n\n  // Only required for v2 and v3 runtime\n  rollup?: (options: RollupOptions) => Promise<RollupBuild>;\n\n  // True to enable sourcemaps, which help with\n  // tracing runtime errors back to source code,\n  // including specific source files and line numbers.\n  // When true, there is additional overhead\n  // for generating the sourcemaps, and the generated bundle\n  // is larger.\n  enableSourcemap?: boolean;\n\n  // Only required for v3 runtime\n  // For v3, EITHER files OR vizCache is required\n  vizCache?: VizCache;\n\n  // Only required for v3 runtime\n  vizId?: string;\n\n  // Only required for v3 runtime\n  slugCache?: SlugCache;\n\n  // Only required for v3 runtime\n  getSvelteCompiler?: () => Promise<SvelteCompiler>;\n}): Promise<BuildResult> => {\n  try {\n    DEBUG &&\n      console.log(\n        \"[build] files:\",\n        files\n          ? JSON.stringify(files).substring(0, 100)\n          : undefined,\n      );\n    DEBUG && console.log(\"[build] vizCache:\", vizCache);\n    DEBUG && console.log(\"[build] vizId:\", vizId);\n\n    if (!files && !vizCache) {\n      throw new Error(\n        \"Either files or vizCache is required\",\n      );\n    }\n\n    if (!files && vizCache && !vizId) {\n      throw new Error(\n        \"vizId is required when using vizCache\",\n      );\n    }\n\n    if (!files && vizCache && vizId) {\n      files = vizFilesToFileCollection(\n        (await vizCache.get(vizId))?.files,\n      );\n    }\n\n    if (!files) {\n      throw new Error(\"Upable to extract viz files\");\n    }\n\n    const runtimeVersion = determineRuntimeVersion(files);\n    DEBUG &&\n      console.log(\"[build] version:\", runtimeVersion);\n    if (runtimeVersion === \"v1\") {\n      const processedFiles = processImagesForV1(files);\n      return {\n        html: addRuntimeErrorHandlingToV1(\n          magicSandbox(processedFiles),\n        ),\n        runtimeVersion,\n      };\n    }\n\n    if (runtimeVersion === \"v2\") {\n      if (!rollup) {\n        throw new Error(\n          \"Rollup is required for v2 runtime\",\n        );\n      }\n      const v2Files = await v2Build({\n        files,\n        rollup,\n        enableSourcemap,\n      });\n      const processedFiles = processImagesForV1(v2Files); // Same processing as V1 for HTML\n      return {\n        html: magicSandbox(processedFiles),\n        runtimeVersion,\n      };\n    }\n    if (runtimeVersion === \"v3\") {\n      if (!rollup) {\n        throw new Error(\n          \"Rollup is required for v3 runtime\",\n        );\n      }\n\n      // We set up a \"fake\" viz cache.\n      // It's needed because of the way the CSS import resolution works.\n      if (!vizCache && !vizId) {\n        const vizContent = createVizContent(files);\n        vizId = vizContent.id;\n        vizCache = createVizCache({\n          initialContents: [vizContent],\n          handleCacheMiss: async () => {\n            throw new Error(\n              \"Cache miss handler not implemented\",\n            );\n          },\n        });\n      }\n\n      if (!vizCache) {\n        throw new Error(\n          \"vizCache is required for v3 runtime\",\n        );\n      }\n\n      if (!vizId) {\n        throw new Error(\n          \"vizId is required for v3 runtime if vizCache is provided\",\n        );\n      }\n\n      return await v3Build({\n        files,\n        rollup,\n        vizCache,\n        vizId,\n        slugCache,\n        getSvelteCompiler,\n      });\n    }\n\n    if (runtimeVersion === \"v4\") {\n      if (!rollup) {\n        throw new Error(\n          \"Rollup is required for v4 runtime\",\n        );\n      }\n      DEBUG &&\n        console.log(\"[build] v4Build\", {\n          files,\n          rollup,\n          enableSourcemap,\n        });\n\n      // For V4, we need to determine if we need hot reload support\n      // by checking if we need separate JS (this will be called from the runtime)\n      const v4Result = await v4BuildWithHotReload({\n        files,\n        rollup,\n        enableSourcemap,\n      });\n\n      const processedFiles = processImagesForV1(\n        v4Result.files,\n      ); // Same processing as V1 for HTML\n\n      return {\n        html: magicSandbox(processedFiles),\n        js: v4Result.bundledJS,\n        runtimeVersion,\n      };\n    }\n    throw new Error(\n      `Unsupported runtime version: ${runtimeVersion}`,\n    );\n  } catch (error) {\n    if (error instanceof Error) {\n      // Clean up the error message for user facing error messages.\n      if (error.message.indexOf(VIRTUAL_PREFIX)) {\n        error.message = error.message.replace(\n          VIRTUAL_PREFIX,\n          \"\",\n        );\n      }\n    }\n    throw error;\n  }\n};\n"],"x_google_ignoreList":[21],"mappings":"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"}