{
  "schemaVersion": 2,
  "release": "exact-snapshots-improvements-v5-nonoverlap-viewer-2026-08-17",
  "role": "historical-conservation-baseline-only",
  "currentAuthority": "blue-bridge-classroom-screen-capture-display-prompt-2026-08-23-v1",
  "releaseUse": "Before/after regression comparison only. This baseline cannot replace, recover, backport or supply files to the current release.",
  "baseline": "Blue-Bridge-Latest-Snapshots-Cloudflare-Pages-iPad.zip",
  "baselineSha256": "99a10c9a637636859f2aac04a10f1ab32b63949392b42f1c51ed6dc674dedb03",
  "policy": "Historical conservation record: the eight supplied commit-stamped snapshots formed the 2026-08-17 baseline. Product algorithms, curriculum/knowledge data, storage schemas and source modules were retained. Four recorded recovery changes were permitted: MMS-NL-001, BSL-SHELL-001, BB-VIEWER-002 and WRITER-BOOT-001. The current definitive tree, not this baseline, is the production authority.",
  "protectedFiles": 59,
  "runtimeMarker": {
    "begin": "<!-- BLUE_BRIDGE_SUITE_RUNTIME_BEGIN -->",
    "end": "<!-- BLUE_BRIDGE_SUITE_RUNTIME_END -->"
  },
  "apps": [
    {
      "id": "blue-bridge",
      "commit": "33d3c11366c2862490cce76d4212851d6a1e62bd",
      "route": "/",
      "files": [
        {
          "path": "index.html",
          "sha256": "6f78d75a8c431b1e94b84d29e0172e1cd91ec57925092942a794b481d901ec5b",
          "bytes": 60249,
          "verification": "approved-shell-divergence-BB-VIEWER-002"
        }
      ],
      "originalServiceWorker": null
    },
    {
      "id": "bsl",
      "commit": "29f2e15b62c1dbc13d5c0f73ff32712c26148de2",
      "route": "/bsl/",
      "files": [
        {
          "path": "bsl/app.js",
          "sha256": "d310921c4be4fce6c4199c2ce5ea5a5b6ddae6cebbfcc6270b894415129e3fd1",
          "bytes": 99179,
          "verification": "exact-bytes"
        },
        {
          "path": "bsl/course.js",
          "sha256": "1449dcb70a383a2bd1b77ca816ad29c21aa805f18a663a0801aac5d76879e8f8",
          "bytes": 117800,
          "verification": "exact-bytes"
        },
        {
          "path": "bsl/index.html",
          "sha256": "e77bad82d5ad297f1f1d29e0c6569586be6d1fd50ed56139d2fb2b2ec5ce29e4",
          "bytes": 9831,
          "verification": "approved-hosting-divergence-BSL-SHELL-001"
        },
        {
          "path": "bsl/knowledge.js",
          "sha256": "9d5ea1995e4df4c4d9a0e930c336c52b687aaeb25036f4a3a76e2d058e2924e5",
          "bytes": 208766,
          "verification": "exact-bytes"
        },
        {
          "path": "bsl/style.css",
          "sha256": "1506c8bbcf8a920c98275f59d9b8ad319800cc442b0604ea3c744667b5027a06",
          "bytes": 57954,
          "verification": "exact-bytes"
        }
      ],
      "originalServiceWorker": {
        "path": "bsl/service-worker.js",
        "sha256": "3f9b351146c5b0d85f1396aab776eb76ede124403f3dcb1a442d5f291c469024",
        "content": "const CACHE = \"bsl-classroom-readiness-v15\";\nconst SHELL = [\n  \"./\",\n  \"./index.html\",\n  \"./style.css?v=15\",\n  \"./course.js?v=15\",\n  \"./knowledge.js?v=15\",\n  \"./app.js?v=15\",\n];\n\nself.addEventListener(\"install\", (event) => {\n  event.waitUntil(caches.open(CACHE).then((cache) => cache.addAll(SHELL)));\n  self.skipWaiting();\n});\n\nself.addEventListener(\"activate\", (event) => {\n  event.waitUntil(\n    caches\n      .keys()\n      .then((keys) =>\n        Promise.all(\n          keys\n            .filter((key) => key.startsWith(\"bsl-\") && key !== CACHE)\n            .map((key) => caches.delete(key)),\n        ),\n      )\n      .then(() => self.clients.claim()),\n  );\n});\n\nself.addEventListener(\"fetch\", (event) => {\n  const request = event.request;\n  if (request.method !== \"GET\") return;\n  const url = new URL(request.url);\n  if (url.origin !== self.location.origin) return;\n\n  if (request.mode === \"navigate\") {\n    event.respondWith(\n      fetch(request)\n        .then((response) => {\n          if (!response.ok) return response;\n          const copy = response.clone();\n          return caches\n            .open(CACHE)\n            .then((cache) => cache.put(\"./index.html\", copy))\n            .then(() => response);\n        })\n        .catch(() => caches.match(\"./index.html\")),\n    );\n    return;\n  }\n\n  event.respondWith(\n    caches.match(request).then(\n      (cached) =>\n        cached ||\n        fetch(request).then((response) => {\n          if (response.ok) {\n            const copy = response.clone();\n            caches.open(CACHE).then((cache) => cache.put(request, copy));\n          }\n          return response;\n        }),\n    ),\n  );\n});\n"
      }
    },
    {
      "id": "maths-modelling-studio",
      "commit": "61253d05f72a72cf1d53c283ab7d51f7bfea65a5",
      "route": "/maths-modelling-studio/",
      "files": [
        {
          "path": "maths-modelling-studio/index.html",
          "sha256": "635a4af1dabe1a4e366e8ff8826056fc3a588ecfeb36271fe3de0588f7d384b2",
          "bytes": 1081202,
          "verification": "strip-blue-bridge-suite-runtime-app-icon-and-number-line-hotfix-markers"
        }
      ],
      "originalServiceWorker": null
    },
    {
      "id": "maths-page-studio",
      "commit": "a85b57be00ed3ececb65bf5423f0dda23317be2a",
      "route": "/maths-page-studio/",
      "files": [
        {
          "path": "maths-page-studio/assets/icon.svg",
          "sha256": "d8bb711f0d263ef2e8bda13078a2b809df89fcd45e94aadb95c72898022fa3dc",
          "bytes": 377,
          "verification": "exact-bytes"
        },
        {
          "path": "maths-page-studio/css/styles.css",
          "sha256": "39611306fc8191f5830fe94a3c6dfa5db6b352f93a5bd5a7c8495de111991484",
          "bytes": 80055,
          "verification": "exact-bytes"
        },
        {
          "path": "maths-page-studio/index.html",
          "sha256": "76802cc9eb5a828db0c8b43eb771a1902e6a2f929eb20e1f523421a2bc8c85fc",
          "bytes": 5590,
          "verification": "strip-blue-bridge-suite-runtime-and-app-icon-markers"
        },
        {
          "path": "maths-page-studio/js/app.js",
          "sha256": "a72823721028977b35ca596234839529cfb09664e25ed8626b9807c8c7ed4241",
          "bytes": 303357,
          "verification": "exact-bytes"
        },
        {
          "path": "maths-page-studio/js/build2-model-bank.js",
          "sha256": "53c16596df1939a2af785ff73cace7f3875e5aa5a46cb501b05857aa55d49acf",
          "bytes": 114315,
          "verification": "exact-bytes"
        },
        {
          "path": "maths-page-studio/js/build2-model-renderers.js",
          "sha256": "d4aba22102d76591706b097d91835aac2bc7a3e08752616f4e5b1db66543bb43",
          "bytes": 85687,
          "verification": "exact-bytes"
        },
        {
          "path": "maths-page-studio/js/matcher.js",
          "sha256": "633698e16158d923039ea3b22ab9f5fc5b5e391efaa114ed0be74b17dfb0b06e",
          "bytes": 79264,
          "verification": "exact-bytes"
        },
        {
          "path": "maths-page-studio/js/model-registry.js",
          "sha256": "1f5baf6f8751f83fcafec03c9af1a5a253db2118957a3f4c36b15def26fd9dac",
          "bytes": 52685,
          "verification": "exact-bytes"
        },
        {
          "path": "maths-page-studio/js/model-renderers.js",
          "sha256": "03ef34d5f7531bee760134f150827fa50a07cdcc44dea685172320b9c166c049",
          "bytes": 29267,
          "verification": "exact-bytes"
        },
        {
          "path": "maths-page-studio/js/number-variation.js",
          "sha256": "d3901d89534c61a100816d153a7c7d1ed36c5ddb8d35247a2a4825f0dd27ae90",
          "bytes": 35575,
          "verification": "exact-bytes"
        },
        {
          "path": "maths-page-studio/js/pagination.js",
          "sha256": "a02bafb2cc2251ce5bd48a5cbbfe3245428256f00b75f78de4a9bd906481d9f4",
          "bytes": 51999,
          "verification": "exact-bytes"
        },
        {
          "path": "maths-page-studio/js/parser.js",
          "sha256": "f9b1da4840f6fb5e771539230e0506b728f1e5d971985f42fd63b0892a4d755a",
          "bytes": 30595,
          "verification": "exact-bytes"
        },
        {
          "path": "maths-page-studio/js/question-intelligence.js",
          "sha256": "db79b9aa95f1fad32978ac2d1920b98a952201c0b41a937a9ba364f39f36fab1",
          "bytes": 97097,
          "verification": "exact-bytes"
        },
        {
          "path": "maths-page-studio/js/state.js",
          "sha256": "d774c0c6c28a399edf5d7ee462f5b437e20ae80bda784815a3b96ed6dcbd5354",
          "bytes": 93158,
          "verification": "exact-bytes"
        },
        {
          "path": "maths-page-studio/js/storage-transaction.js",
          "sha256": "bdf4a3be367ea400b8a7f84b435da8d5a0f50ee9d8b3fc1cc64af39364931dea",
          "bytes": 1824,
          "verification": "exact-bytes"
        },
        {
          "path": "maths-page-studio/js/worksheet-architecture.js",
          "sha256": "82758aa11e53f117ab6ec60e89b8742e9f97137369e1e0c15f52365bf2d0fbc1",
          "bytes": 20708,
          "verification": "exact-bytes"
        },
        {
          "path": "maths-page-studio/js/worksheet-versions.js",
          "sha256": "25f20c43f24074a1fee5d35c54d088396a9f6e7f6103ba2cacfbea1679ea47dc",
          "bytes": 42050,
          "verification": "exact-bytes"
        },
        {
          "path": "maths-page-studio/js/year4-knowledge.js",
          "sha256": "43b64357041ca2fcd431fd4788da5b8a845054ff2310abce3217b33fbc1cb540",
          "bytes": 29924,
          "verification": "exact-bytes"
        },
        {
          "path": "maths-page-studio/manifest.webmanifest",
          "sha256": "11ecc0692bf248d4c85b270652926474379bc97327102fad5545ff35d09f5ad8",
          "bytes": 436,
          "verification": "exact-bytes"
        }
      ],
      "originalServiceWorker": {
        "path": "maths-page-studio/service-worker.js",
        "sha256": "b5613db4ca134b99e228caef47fcc408a0df10fdd31e950ea8e369da77a6bc5f",
        "content": "// Change this namespace for every release that changes the offline shell.\n// The prefix is deliberately product-specific so activation never removes\n// unrelated caches that happen to share the same origin.\nconst CACHE_PREFIX = 'maths-page-studio-';\nconst CACHE = `${CACHE_PREFIX}release-v19`;\nconst SHELL = [\n  './',\n  './index.html',\n  './css/styles.css?v=release-v19',\n  './js/app.js?v=release-v19',\n  './js/parser.js?v=release-v19',\n  './js/matcher.js?v=release-v19',\n  './js/question-intelligence.js?v=release-v19',\n  './js/year4-knowledge.js?v=release-v19',\n  './js/build2-model-bank.js?v=release-v19',\n  './js/model-registry.js?v=release-v19',\n  './js/model-renderers.js?v=release-v19',\n  './js/build2-model-renderers.js?v=release-v19',\n  './js/state.js?v=release-v19',\n  './js/pagination.js?v=release-v19',\n  './js/storage-transaction.js?v=release-v19',\n  './js/worksheet-architecture.js?v=release-v19',\n  './js/worksheet-versions.js?v=release-v19',\n  './js/number-variation.js?v=release-v19',\n  './assets/icon.svg',\n  './manifest.webmanifest'\n];\n\nconst OFFLINE_DOCUMENT = './index.html';\n\nself.addEventListener('install', (event) => {\n  event.waitUntil((async () => {\n    const cache = await caches.open(CACHE);\n    // A previously controlled page may still have an older index document in\n    // the browser's HTTP cache. Reload every shell request during installation\n    // so the new Cache Storage namespace cannot contain mixed release graphs.\n    const installRequests = SHELL.map((path) => new Request(\n      new URL(path, self.registration.scope),\n      { cache: 'reload' },\n    ));\n    await cache.addAll(installRequests);\n    await self.skipWaiting();\n  })());\n});\n\nself.addEventListener('activate', (event) => {\n  event.waitUntil((async () => {\n    const keys = await caches.keys();\n    await Promise.all(keys\n      .filter((key) => key.startsWith(CACHE_PREFIX) && key !== CACHE)\n      .map((key) => caches.delete(key)));\n    await self.clients.claim();\n  })());\n});\n\nasync function cachedFallbackFor(request) {\n  try {\n    const cache = await caches.open(CACHE);\n    // Vite and common static hosts send `Vary: Origin` for built CSS and JS.\n    // Install-time reload Requests do not carry the later element request's\n    // Origin header, so an ordinary Cache match can reject the exact cached\n    // URL while offline. The release cache is product-scoped and its URLs are\n    // exact, making an ignoreVary lookup both safe and deterministic here.\n    const cached = await cache.match(request, { ignoreVary: true });\n    if (cached) return cached;\n    if (request.mode === 'navigate') {\n      return await cache.match(OFFLINE_DOCUMENT, { ignoreVary: true });\n    }\n  } catch {\n    // Cache access can be denied independently of network access.\n  }\n  return null;\n}\n\nself.addEventListener('fetch', (event) => {\n  if (event.request.method !== 'GET') return;\n  event.respondWith((async () => {\n    try {\n      const response = await fetch(event.request);\n      if (response.ok && new URL(event.request.url).origin === self.location.origin) {\n        try {\n          const cache = await caches.open(CACHE);\n          await cache.put(event.request, response.clone());\n        } catch {\n          // A full or unavailable cache must never discard a valid network response.\n        }\n      }\n      if (response.status >= 500) {\n        const fallback = await cachedFallbackFor(event.request);\n        if (fallback) return fallback;\n      }\n      return response;\n    } catch {\n      const fallback = await cachedFallbackFor(event.request);\n      if (fallback) return fallback;\n      return Response.error();\n    }\n  })());\n});\n"
      }
    },
    {
      "id": "writer",
      "commit": "0167082c9ca9d094a1a28ee5e5172666d6f49b61",
      "route": "/writer/",
      "files": [
        {
          "path": "writer/REACT-LICENSE.txt",
          "sha256": "da6d3703ed11cbe42bd212c725957c98da23cbff1998c05fa4b3d976d1a58e93",
          "bytes": 1088,
          "verification": "exact-bytes"
        },
        {
          "path": "writer/assets/app.css",
          "sha256": "f16727d18d79edda1cfaf161177d41949dee573a696044bd7aa4d7ae7fe28b2c",
          "bytes": 67967,
          "verification": "exact-bytes"
        },
        {
          "path": "writer/assets/app.js",
          "sha256": "5235421773978291b8b7a90421916aff597016513cbeacecbf180fb76d6368eb",
          "bytes": 780,
          "verification": "exact-bytes"
        },
        {
          "path": "writer/assets/react-runtime.js",
          "sha256": "6e090f99e713e711134041599c295756edfc0938bfc58c2004fb51a97031dda0",
          "bytes": 191174,
          "verification": "exact-bytes"
        },
        {
          "path": "writer/assets/src/SimpleApp.js",
          "sha256": "e64bbe86e0e9f96a00ea3ee99e906d54fc49abbc7c207906924b8695c1aa0382",
          "bytes": 12434,
          "verification": "exact-bytes"
        },
        {
          "path": "writer/assets/src/components/PupilPage.js",
          "sha256": "9e57e31fd8ff95e852ac47818e2e3257b4a3bfc6170d8099f557cc29c82ac039",
          "bytes": 19029,
          "verification": "exact-bytes"
        },
        {
          "path": "writer/assets/src/data.js",
          "sha256": "a17f18511e90fe54cf9261258d60194477b0cdad6f81b8e8260443fd29bbc077",
          "bytes": 12890,
          "verification": "exact-bytes"
        },
        {
          "path": "writer/assets/src/design-system/blueBridgePalette.js",
          "sha256": "b7b29fbb2db50aed2a32b1eb5c846dac79bbdb6791b90264bdbb8eacd632bfb5",
          "bytes": 710,
          "verification": "exact-bytes"
        },
        {
          "path": "writer/assets/src/lib/brief.js",
          "sha256": "49d96d626c9343d8d997ab3566b52c663dc88ef90b27590b432677fcdf9ba8ce",
          "bytes": 12500,
          "verification": "exact-bytes"
        },
        {
          "path": "writer/assets/src/lib/engine.js",
          "sha256": "b5c3026832041a5eb20b50d8802ac6684141f4a0a0ccbe319a148bf2f23f68a5",
          "bytes": 23429,
          "verification": "exact-bytes"
        },
        {
          "path": "writer/assets/src/lib/evidenceRegistry.js",
          "sha256": "bdbe94d53903665d827d471713f5782fa3e48f24ec6dafc40cfa1dc52be40201",
          "bytes": 10830,
          "verification": "exact-bytes"
        },
        {
          "path": "writer/assets/src/lib/intelligence.js",
          "sha256": "e01db25cad246f121b77f8d8e9bfd244ae7473f6403dde1b50b105bc9342a6f4",
          "bytes": 14380,
          "verification": "exact-bytes"
        },
        {
          "path": "writer/assets/src/lib/masteryEngine.js",
          "sha256": "f1ac39122c88fd5ba270778eaea640db4f5f5b277ec3971952149078f1fb5f5a",
          "bytes": 33931,
          "verification": "exact-bytes"
        },
        {
          "path": "writer/assets/src/lib/physicalPrint.js",
          "sha256": "c8abf9f6e37ae7e95982477f536b6ffac10b9e1a5719f8f91311d3565a36f31c",
          "bytes": 5369,
          "verification": "exact-bytes"
        },
        {
          "path": "writer/assets/src/lib/projectLibrary.js",
          "sha256": "b54f15440295481c657fe3e0550d921057a1d0f849ab060aa4e2c8bce27df489",
          "bytes": 5642,
          "verification": "exact-bytes"
        },
        {
          "path": "writer/assets/src/lib/scaffold.js",
          "sha256": "116c60f5797c583b71ec17a07a2be9ceba2d6e14c0ec5b013a16665896fa15cc",
          "bytes": 11281,
          "verification": "exact-bytes"
        },
        {
          "path": "writer/assets/src/lib/simpleMaker.js",
          "sha256": "5c6005bc2f12f101c592f969be8c6167575d800470392a09a18e2918b999fb76",
          "bytes": 12419,
          "verification": "exact-bytes"
        },
        {
          "path": "writer/assets/src/lib/sourceMapper.js",
          "sha256": "54502e1873cca54266c68f27b13ed96951fbe343c24f514843fcde2a87f479e1",
          "bytes": 11136,
          "verification": "exact-bytes"
        },
        {
          "path": "writer/assets/src/lib/storage.js",
          "sha256": "3160a9b5f8611f35ef7ad5d2ab72bccd666d1ddcadbeb08be77a632cc125948d",
          "bytes": 28456,
          "verification": "exact-bytes"
        },
        {
          "path": "writer/assets/src/lib/text.js",
          "sha256": "37fb9c1270b663bbf3de7dc12f1010d178c764e462e7a9039fdfbebd6edf027b",
          "bytes": 5675,
          "verification": "exact-bytes"
        },
        {
          "path": "writer/assets/src/palette.js",
          "sha256": "c85923c092db86992781192eea1024844baab3b9ef0ac73f64ba66de1a570f84",
          "bytes": 792,
          "verification": "exact-bytes"
        },
        {
          "path": "writer/assets/src/types.js",
          "sha256": "8e609bb71c20b858c77f0e9f90bb1319db8477b13f9f965f1a1e18524bf50881",
          "bytes": 11,
          "verification": "exact-bytes"
        },
        {
          "path": "writer/icons/scaffold.svg",
          "sha256": "cd90adc628b5e813801a0eeda7f6585160209d960033f08a29a85540b7d488e3",
          "bytes": 302,
          "verification": "exact-bytes"
        },
        {
          "path": "writer/index.html",
          "sha256": "3e7edd29a8dfcfab142f64ab9ce1b050829e9ebc5dc152b8fcf13b6146877c2b",
          "bytes": 870,
          "verification": "approved-startup-shell-divergence-WRITER-BOOT-001"
        },
        {
          "path": "writer/manifest.webmanifest",
          "sha256": "e8b99aa386c16a2061feeeda3ccb74e3a78a7e19e5e55a7aff8e83e57843a2a1",
          "bytes": 442,
          "verification": "exact-bytes"
        }
      ],
      "originalServiceWorker": {
        "path": "writer/service-worker.js",
        "sha256": "40a73de4743cd655c4d9c67b296c024f1530e57997dafc037e10012b500a445e",
        "content": "const CACHE_PREFIX = 'scaffold-studio-portable-'\nconst CACHE = CACHE_PREFIX + 'baaf59f2cd22'\nconst CORE = [\n  \"./\",\n  \"./index.html\",\n  \"./manifest.webmanifest\",\n  \"./icons/scaffold.svg\",\n  \"./assets/app.css\",\n  \"./assets/app.js\",\n  \"./assets/react-runtime.js\",\n  \"./assets/src/SimpleApp.js\",\n  \"./assets/src/components/PupilPage.js\",\n  \"./assets/src/data.js\",\n  \"./assets/src/design-system/blueBridgePalette.js\",\n  \"./assets/src/lib/brief.js\",\n  \"./assets/src/lib/engine.js\",\n  \"./assets/src/lib/evidenceRegistry.js\",\n  \"./assets/src/lib/intelligence.js\",\n  \"./assets/src/lib/masteryEngine.js\",\n  \"./assets/src/lib/physicalPrint.js\",\n  \"./assets/src/lib/projectLibrary.js\",\n  \"./assets/src/lib/scaffold.js\",\n  \"./assets/src/lib/simpleMaker.js\",\n  \"./assets/src/lib/sourceMapper.js\",\n  \"./assets/src/lib/storage.js\",\n  \"./assets/src/lib/text.js\",\n  \"./assets/src/palette.js\",\n  \"./assets/src/types.js\"\n]\n\nself.addEventListener('install', (event) => {\n  event.waitUntil(\n    caches.open(CACHE)\n      .then((cache) => cache.addAll(CORE))\n      .then(() => self.skipWaiting()),\n  )\n})\n\nself.addEventListener('activate', (event) => {\n  event.waitUntil(\n    caches.keys()\n      .then((keys) => Promise.all(keys\n        .filter((key) => key.startsWith(CACHE_PREFIX) && key !== CACHE)\n        .map((key) => caches.delete(key))))\n      .then(() => self.clients.claim()),\n  )\n})\n\nself.addEventListener('fetch', (event) => {\n  const request = event.request\n  if (request.method !== 'GET') return\n  const url = new URL(request.url)\n  if (url.origin !== self.location.origin) return\n\n  if (request.mode === 'navigate') {\n    event.respondWith(\n      fetch(request)\n        .then((response) => {\n          const copy = response.clone()\n          caches.open(CACHE).then((cache) => cache.put('./index.html', copy))\n          return response\n        })\n        .catch(() => caches.match('./index.html')),\n    )\n    return\n  }\n\n  event.respondWith(\n    caches.match(request).then((cached) => cached || fetch(request).then((response) => {\n      if (response.ok) {\n        const copy = response.clone()\n        caches.open(CACHE).then((cache) => cache.put(request, copy))\n      }\n      return response\n    })),\n  )\n})\n"
      }
    },
    {
      "id": "maths-web",
      "commit": "6664fa2248494a29af92bcd2f62c35bb758b2946",
      "route": "/maths-web/",
      "files": [
        {
          "path": "maths-web/index.html",
          "sha256": "0aebec03e75e8944de4a7fe7c259a6bfe1ecdad17c9169635ea2c4c9f78c22be",
          "bytes": 460556,
          "verification": "strip-blue-bridge-suite-runtime-and-app-icon-markers"
        }
      ],
      "originalServiceWorker": null
    },
    {
      "id": "4s",
      "commit": "6da3874015093622c02af9b8f337fc205b5d6ad4",
      "route": "/4s/",
      "files": [
        {
          "path": "4s/assets/app.js",
          "sha256": "69368215f77a0c90516a6ef4dc35137e5ee0a64499406e79a37b63820213185a",
          "bytes": 531635,
          "verification": "exact-bytes"
        },
        {
          "path": "4s/assets/index.css",
          "sha256": "31c41e021fa4b040ad010f2687f55852c575833484002be936756b50259b0a57",
          "bytes": 140301,
          "verification": "exact-bytes"
        },
        {
          "path": "4s/favicon.svg",
          "sha256": "1fb1c0b347c6e94911aad18952ecc7d440584a4165fa297f87d34847efda83b0",
          "bytes": 258,
          "verification": "exact-bytes"
        },
        {
          "path": "4s/index.html",
          "sha256": "5951d4c5ac76db240778e18f54878c82928b8ba2a36661eb990d0f7f53be32c0",
          "bytes": 689,
          "verification": "strip-blue-bridge-suite-runtime-and-app-icon-markers"
        },
        {
          "path": "4s/manifest.webmanifest",
          "sha256": "3e97d25d374f188e11033044b6d1478eb20418a8085518e57b27287753d40ebd",
          "bytes": 403,
          "verification": "exact-bytes"
        },
        {
          "path": "4s/release.json",
          "sha256": "ee47335670f97843c8303953b89c233380482c005228f3a1163edadc9914bbda",
          "bytes": 108,
          "verification": "exact-bytes"
        }
      ],
      "originalServiceWorker": {
        "path": "4s/sw.js",
        "sha256": "415f16fdd43eea17ec715abeb6cb48ac27bb4a80cd44ad971d310812668cfae1",
        "content": "const CACHE_PREFIX = \"year-4-fluency-\";\nconst CACHE_NAME = `${CACHE_PREFIX}release-4s-v9`;\nconst APP_SHELL = [\"./\", \"./index.html\", \"./assets/app.js\", \"./assets/index.css\", \"./manifest.webmanifest\", \"./favicon.svg\"];\n\nself.addEventListener(\"install\", (event) => {\n  const freshShell = APP_SHELL.map((url) => new Request(url, { cache: \"reload\" }));\n  event.waitUntil(caches.open(CACHE_NAME).then((cache) => cache.addAll(freshShell)));\n});\n\nself.addEventListener(\"activate\", (event) => {\n  event.waitUntil(\n    caches.keys()\n      .then((keys) => Promise.all(keys\n        .filter((key) => key.startsWith(CACHE_PREFIX) && key !== CACHE_NAME)\n        .map((key) => caches.delete(key))))\n      .then(() => self.clients.claim()),\n  );\n});\n\nself.addEventListener(\"message\", (event) => {\n  if (event.data?.type === \"SKIP_WAITING\") self.skipWaiting();\n});\n\nself.addEventListener(\"fetch\", (event) => {\n  const request = event.request;\n  if (request.method !== \"GET\" || new URL(request.url).origin !== self.location.origin) return;\n\n  if (request.mode === \"navigate\") {\n    event.respondWith(\n      fetch(request)\n        .then((response) => {\n          const copy = response.clone();\n          caches.open(CACHE_NAME).then((cache) => cache.put(request, copy));\n          return response;\n        })\n        .catch(async () => (await caches.match(request)) ?? (await caches.match(\"./index.html\")) ?? (await caches.match(\"./\"))),\n    );\n    return;\n  }\n\n  event.respondWith(\n    caches.match(request).then((cached) => cached ?? fetch(request).then((response) => {\n      if (response.ok) {\n        const copy = response.clone();\n        caches.open(CACHE_NAME).then((cache) => cache.put(request, copy));\n      }\n      return response;\n    })),\n  );\n});\n"
      }
    },
    {
      "id": "anchor-art",
      "commit": "c089ebbb8a5208228561f6f2d04a57dbd815e557",
      "route": "/anchor-art/",
      "files": [
        {
          "path": "anchor-art/index.html",
          "sha256": "487aca41d4f9cf9db7cf790242a886089af773bcd0542a582b001c58330f4670",
          "bytes": 1048996,
          "verification": "strip-blue-bridge-suite-runtime-and-app-icon-markers"
        }
      ],
      "originalServiceWorker": null
    }
  ],
  "iconMarker": {
    "begin": "<!-- BLUE_BRIDGE_APP_ICON_BEGIN -->",
    "end": "<!-- BLUE_BRIDGE_APP_ICON_END -->"
  },
  "hotfixMarkers": {
    "begin": "<!-- BLUE_BRIDGE_NUMBER_LINE_HOTFIX_BEGIN -->",
    "end": "<!-- BLUE_BRIDGE_NUMBER_LINE_HOTFIX_END -->"
  },
  "approvedProductHotfixes": [
    {
      "id": "MMS-NL-001",
      "path": "maths-modelling-studio/index.html",
      "verification": "strip-blue-bridge-suite-runtime-app-icon-and-number-line-hotfix-markers"
    },
    {
      "id": "BSL-SHELL-001",
      "path": "bsl/index.html",
      "verification": "product JavaScript, course data, knowledge data and external stylesheet remain exact; index hosting additions are recorded"
    },
    {
      "id": "BB-VIEWER-002",
      "path": "index.html",
      "verification": "requested Blue Bridge viewer shell divergence; app catalog and source commit remain recorded"
    },
    {
      "id": "WRITER-BOOT-001",
      "path": "writer/index.html",
      "generatedPath": "writer/assets/app-bundle.js",
      "verification": "bundle generated from unchanged checked-in compiled modules and local React runtime"
    },
    {
      "id": "BB-VIEWER-003",
      "path": "index.html",
      "verification": "shared viewer controls occupy a dedicated grid row and do not modify embedded application files"
    }
  ],
  "bslHostingFixMarkers": {
    "styleBegin": "<!-- BLUE_BRIDGE_BSL_STYLE_RECOVERY_BEGIN -->",
    "styleEnd": "<!-- BLUE_BRIDGE_BSL_STYLE_RECOVERY_END -->",
    "navigationBegin": "<!-- BLUE_BRIDGE_BSL_NAVIGATION_BEGIN -->",
    "navigationEnd": "<!-- BLUE_BRIDGE_BSL_NAVIGATION_END -->",
    "blueBridgeLaunchBegin": "<!-- BLUE_BRIDGE_BSL_LAUNCH_FIX_BEGIN -->",
    "blueBridgeLaunchEnd": "<!-- BLUE_BRIDGE_BSL_LAUNCH_FIX_END -->"
  },
  "unifiedViewerMarker": {
    "cssBegin": "/* BLUE_BRIDGE_UNIFIED_VIEWER_V4_BEGIN */",
    "cssEnd": "/* BLUE_BRIDGE_UNIFIED_VIEWER_V4_END */",
    "hotfix": "BB-VIEWER-002"
  },
  "writerStartupArtifacts": {
    "bundle": "writer/assets/app-bundle.js",
    "sourceDirectory": "writer/assets/src/",
    "stylesheetFallbackMarkerBegin": "<!-- BLUE_BRIDGE_WRITER_STYLE_FALLBACK_BEGIN -->",
    "stylesheetFallbackMarkerEnd": "<!-- BLUE_BRIDGE_WRITER_STYLE_FALLBACK_END -->",
    "hotfix": "WRITER-BOOT-001"
  },
  "viewerNonOverlapMarker": {
    "cssBegin": "/* BLUE_BRIDGE_VIEWER_NON_OVERLAP_HOTFIX_BEGIN */",
    "cssEnd": "/* BLUE_BRIDGE_VIEWER_NON_OVERLAP_HOTFIX_END */",
    "hotfix": "BB-VIEWER-003"
  }
}
