{
  "version": 3,
  "sources": ["../../../Scripts/scenes/live-scenes.mjs"],
  "sourcesContent": ["// Live 3D scenes: an <img data-scene=\"<key>\" data-poster-frame=\"<n>\"> comes to life in place.\n//\n// The image is frame <n> of scene <key>, rendered by this player at the same framing\n// (Scripts/scenes/render-poster.mjs). It stays a plain image until the page has loaded and the\n// browser is idle; only then is three.js fetched, and the scene's files once the image comes near\n// the viewport. When the scene's first frame is drawn, held on frame <n>, the image fades out and\n// the canvas fades in and plays on from there. Reduced motion, Save-Data, no WebGL2 or any error:\n// the image simply stays. LiveSceneScriptProcessor loads this module on pages that need it.\n//\n// This is the source: Scripts/scenes/build.sh --js minifies it to Content/StaticFiles/scenes/,\n// which is what the site serves (AssetMinifier skips .mjs).\n//\n// The scene packages are NFCcoolScenes' app exports (Scripts/scenes/build.sh): a GLB with the\n// baked animation, the manifest with the opacity tracks, lights and camera, and the phone-screen\n// video, played the way OnboardingKit's FeatureScenePlayer plays them in the app. A scene whose\n// manifest names no phone or screen video (cardfan) is just the GLB and the manifest. Each scene\n// loops like the app's page does and renders only while it is on screen.\n//\n// One WebGL context on an OffscreenCanvas draws every scene (browsers cap contexts at about 16,\n// Safari lower); each frame is handed to the image's canvas as an ImageBitmap, so it scrolls\n// with the page natively. (Copying with a 2D drawImage does not work: Chrome defers the copy to\n// the end of the frame, by when the shared buffer holds the last scene drawn.)\n//\n// data-frame-fill sets how much of the app's square frame the image shows (1 = all of it; the\n// Business Card hero uses 0.5, because its lanyard set runs well past the app's frame).\n// ?debug logs timings and exposes window.liveScenes, which render-poster.mjs drives.\n\nconst BASE = new URL('./', import.meta.url);\nconst MAX_DPR = 2;\nconst NEAR_VIEWPORT = '300px';\n\nconst images = [...document.querySelectorAll('img[data-scene][data-poster-frame]')];\nconst reducedMotion = matchMedia('(prefers-reduced-motion: reduce)').matches;\nconst saveData = navigator.connection?.saveData === true;\nconst debug = new URLSearchParams(location.search).has('debug');\nconst log = (...args) => debug && console.log('[live-scenes]', ...args);\n\nif (images.length && !reducedMotion && !saveData && 'OffscreenCanvas' in window && hasWebGL2()) {\n  afterLoad().then(start).catch(error => console.warn('[live-scenes]', error));\n} else {\n  log('skipped', { reducedMotion, saveData });\n}\n\nfunction hasWebGL2() {\n  try {\n    return !!document.createElement('canvas').getContext('webgl2');\n  } catch {\n    return false;\n  }\n}\n\nfunction afterLoad() {\n  const loaded = document.readyState === 'complete'\n    ? Promise.resolve()\n    : new Promise(resolve => addEventListener('load', resolve, { once: true }));\n  return loaded.then(() => new Promise(resolve => {\n    if ('requestIdleCallback' in window) requestIdleCallback(resolve, { timeout: 2000 });\n    else setTimeout(resolve, 200);\n  }));\n}\n\nasync function start() {\n  const t0 = performance.now();\n  const THREE = await import('./vendor/three.scenes.min.mjs');\n  log(`three loaded in ${Math.round(performance.now() - t0)} ms`);\n  const {\n    AnimationMixer, DoubleSide, GLTFLoader, MeshBasicMaterial, MeshoptDecoder,\n    NeutralToneMapping, PCFShadowMap, PMREMGenerator, PointLight, RoomEnvironment, SRGBColorSpace, Scene,\n    SpotLight, VideoTexture, WebGLRenderer,\n  } = THREE;\n\n  const glCanvas = new OffscreenCanvas(1, 1);\n  const renderer = new WebGLRenderer({ canvas: glCanvas, alpha: true, antialias: true, premultipliedAlpha: true });\n  renderer.outputColorSpace = SRGBColorSpace;\n  // Blender renders these scenes with Khronos PBR Neutral (studio.py), and so does three.\n  renderer.toneMapping = NeutralToneMapping;\n  renderer.setClearColor(0x000000, 0);\n  renderer.setPixelRatio(1); // sizes below are already in device pixels\n  // Only a scene whose manifest asks for shadows has a light and meshes that cast them.\n  renderer.shadowMap.enabled = true;\n  renderer.shadowMap.type = PCFShadowMap;\n\n  const pmrem = new PMREMGenerator(renderer);\n  const environment = pmrem.fromScene(new RoomEnvironment(), 0.04).texture;\n  pmrem.dispose();\n\n  const loader = new GLTFLoader().setMeshoptDecoder(MeshoptDecoder);\n  let phonePromise = null;\n  const loadPhone = () => (phonePromise ??= loader.loadAsync(new URL('feature_phone.glb', BASE).href));\n\n  const views = images.map(img => ({\n    img,\n    key: img.dataset.scene,\n    frameFill: Number(img.dataset.frameFill) || 1,\n    posterFrame: Number(img.dataset.posterFrame),\n    // The scene holds on the poster's frame until the poster has faded out.\n    holding: true,\n    state: 'idle', // idle \u2192 loading \u2192 ready | failed\n    visible: false,\n    canvas: null,\n    ctx: null,\n    scene: null,\n  }));\n\n  const observer = new IntersectionObserver(entries => {\n    for (const entry of entries) {\n      const view = views.find(v => v.img === entry.target || v.canvas === entry.target);\n      if (!view) continue;\n      view.visible = entry.isIntersecting;\n      if (view.visible && view.state === 'idle') load(view);\n      if (view.scene) view.visible ? play(view) : view.scene.video?.pause();\n    }\n    wake();\n  }, { rootMargin: NEAR_VIEWPORT });\n  views.forEach(view => observer.observe(view.img));\n\n  // Two scenes at a time, so a fast scroll does not queue up every package at once.\n  let inFlight = 0;\n  const queue = [];\n  function load(view) {\n    view.state = 'loading';\n    queue.push(view);\n    pump();\n  }\n  function pump() {\n    while (inFlight < 2 && queue.length) {\n      const view = queue.shift();\n      inFlight++;\n      const started = performance.now();\n      buildScene(view.key)\n        .then(scene => seekTo(scene, view.posterFrame))\n        .then(scene => {\n          view.scene = scene;\n          view.state = 'ready';\n          log(`${view.key} ready in ${Math.round(performance.now() - started)} ms`);\n          if (view.visible) play(view);\n          wake();\n        })\n        .catch(error => {\n          view.state = 'failed';\n          console.warn(`[live-scenes] ${view.key}`, error);\n        })\n        .finally(() => {\n          inFlight--;\n          pump();\n        });\n    }\n  }\n\n  async function buildScene(key) {\n    const manifestPromise = fetch(new URL(`${key}.json`, BASE)).then(r => {\n      if (!r.ok) throw new Error(`manifest ${r.status}`);\n      return r.json();\n    });\n    const [gltf, manifest, phone, videoSrc] = await Promise.all([\n      loader.loadAsync(new URL(`${key}.glb`, BASE).href),\n      manifestPromise,\n      manifestPromise.then(m => m.phone ? loadPhone() : null),\n      // A server without range requests (python's http.server) leaves a video unseekable even\n      // once it is fully buffered, and the scene starts on its poster's frame; a blob URL always\n      // seeks. The clips are ~100 KB.\n      manifestPromise.then(m => m.screenVideo && fetch(new URL(`${m.screenVideo}.mp4`, BASE)).then(r => {\n        if (!r.ok) throw new Error(`screen video ${r.status}`);\n        return r.blob();\n      }).then(blob => URL.createObjectURL(blob))),\n    ]);\n    const scene = new Scene();\n    scene.environment = environment;\n    scene.environmentIntensity = manifest.environmentIntensity ?? 0.25;\n    scene.add(gltf.scene);\n\n    for (const light of manifest.lights ?? []) {\n      // Blender's light watts are display-referred: a point light of P watts lights a surface\n      // like a three.js point light of P / 4\u03C0 (three's lux carries no 683 lm/W exposure).\n      const intensity = light.energyW / (4 * Math.PI);\n      if (light.type === 'spot') {\n        // A spot aimed at the scene stands in for an area light that casts shadows: it falls off\n        // the same way, and a one-sided area light of P watts shines P / \u03C0 straight ahead.\n        const distance = Math.hypot(...light.position.map((v, i) => v - light.target[i]));\n        // The normal bias keeps the cards' own faces from shadowing themselves (a fine grain);\n        // it stays well under the 2.5 mm between two cards, so their shadows hold.\n        const { extent, mapSize = 1024, radius = 4, bias = -0.001, normalBias = 0.0012 } = light.shadow;\n        const spot = new SpotLight(light.color, light.energyW / Math.PI, 0, Math.atan(1.5 * extent / distance), 0.4, 2);\n        spot.position.fromArray(light.position);\n        spot.target.position.fromArray(light.target);\n        // The shadow camera covers just the scene (shadow.extent: its radius around the target),\n        // so the map resolves the few millimetres between the cards.\n        spot.castShadow = true;\n        Object.assign(spot.shadow.camera, { near: distance - extent, far: distance + extent });\n        spot.shadow.mapSize.set(mapSize, mapSize);\n        Object.assign(spot.shadow, { radius, bias, normalBias });\n        scene.add(spot, spot.target);\n      } else {\n        const point = new PointLight(light.color, intensity, 3, 2);\n        point.position.fromArray(light.position);\n        scene.add(point);\n      }\n    }\n    if (manifest.shadows) gltf.scene.traverse(o => { if (o.isMesh) o.castShadow = o.receiveShadow = true; });\n    // Glows (nfctags' waves and burst) light nothing and throw no shadow.\n    for (const name of manifest.shadowless ?? []) {\n      byName(gltf.scene, name)?.traverse(o => { o.castShadow = o.receiveShadow = false; });\n    }\n\n    // The phone ships once and is attached under each scene's animated Phone, like the app does.\n    const video = videoSrc ? makeVideo(videoSrc) : null;\n    const phoneNode = gltf.scene.getObjectByName(manifest.phone?.entity ?? 'Phone');\n    if (phoneNode && phone) {\n      const parts = phone.scene.getObjectByName('Phone') ?? phone.scene;\n      for (const child of parts.clone(true).children) phoneNode.add(child);\n      const screen = phoneNode.getObjectByName(manifest.phone.screenEntity);\n      if (screen && video) {\n        const texture = new VideoTexture(video);\n        texture.colorSpace = SRGBColorSpace;\n        texture.flipY = false; // glTF UVs\n        const material = new MeshBasicMaterial({ map: texture, toneMapped: false });\n        screen.traverse(o => { if (o.isMesh) o.material = material; });\n      }\n      for (const name of manifest.phone.hiddenEntities ?? []) {\n        const hidden = phoneNode.getObjectByName(name);\n        if (hidden) hidden.visible = false;\n      }\n    }\n\n    for (const name of manifest.doubleSided ?? []) {\n      byName(gltf.scene, name)?.traverse(o => { if (o.isMesh) o.material.side = DoubleSide; });\n    }\n\n    // Opacity tracks: one value per frame, applied to the entity and everything under it.\n    const stepped = new Set(manifest.steppedOpacity ?? []);\n    const tracks = [];\n    for (const [name, values] of Object.entries(manifest.opacity ?? {})) {\n      const node = byName(gltf.scene, name);\n      if (!node) continue;\n      const materials = [];\n      node.traverse(o => {\n        if (!o.isMesh) return;\n        o.material = o.material.clone();\n        o.material.transparent = true;\n        materials.push(o.material);\n      });\n      tracks.push({ node, values, materials, stepped: stepped.has(name), base: materials.map(m => m.opacity) });\n    }\n\n    // Parts drawn in a colour per theme (nfctags' waves: brand blue on light, brand yellow on\n    // dark), following the site's data-theme as the toggle flips it.\n    const themed = Object.entries(manifest.themeColors ?? {}).map(([name, colors]) => ({ node: byName(gltf.scene, name), colors }))\n      .filter(part => part.node);\n    const applyTheme = () => {\n      const theme = document.documentElement.dataset.theme === 'dark' ? 'dark' : 'light';\n      for (const { node, colors } of themed) {\n        node.traverse(o => { if (o.isMesh) { o.material.color.set(colors[theme]); o.material.emissive?.set(colors[theme]); } });\n      }\n    };\n    if (themed.length) {\n      applyTheme();\n      new MutationObserver(applyTheme).observe(document.documentElement, { attributes: true, attributeFilter: ['data-theme'] });\n    }\n\n    const mixer = new AnimationMixer(gltf.scene);\n    for (const clip of gltf.animations) mixer.clipAction(clip).play();\n\n    const camera = gltf.cameras.find(c => c.name === manifest.camera?.entity) ?? gltf.cameras[0];\n    if (!camera) throw new Error('no camera');\n\n    const fps = manifest.fps ?? 30;\n    const frameCount = manifest.frameCount;\n    return {\n      scene,\n      // Blender's view exposure, in stops.\n      exposure: 2 ** (manifest.exposure ?? 0),\n      camera,\n      manifest,\n      video,\n      mixer,\n      tracks,\n      duration: frameCount / fps,\n      fps,\n      frameCount,\n      time: 0,\n    };\n  }\n\n  function play(view) {\n    if (!view.holding) view.scene.video?.play().catch(() => {});\n  }\n\n  // Puts the scene, screen video included, on the given frame.\n  async function seekTo(scene, frame) {\n    const time = (frame - 1) / scene.fps;\n    const { video } = scene;\n    scene.time = time;\n    step(scene, 0);\n    if (!video) return scene;\n    // iOS Safari loads no frames for a video that has never played, so a seek there never\n    // completes: start it (muted inline playback needs no gesture) and pause it right away. When\n    // playing is refused (Low Power Mode), the waits below time out and the scene runs without\n    // its screen video rather than not at all.\n    if (video.readyState < 2) await within(3000, video.play().then(() => video.pause(), () => {}));\n    if (video.readyState < 1) await within(3000, once(video, 'loadedmetadata'));\n    video.currentTime = time;\n    await within(3000, once(video, 'seeked'));\n    scene.scene.traverse(o => { if (o.material?.map?.isVideoTexture) o.material.map.needsUpdate = true; });\n    scene.time = time;\n    step(scene, 0);\n    return scene;\n  }\n\n  function once(target, name) {\n    return new Promise(resolve => target.addEventListener(name, resolve, { once: true }));\n  }\n\n  // Settles with the promise, or after ms if it has not by then.\n  function within(ms, promise) {\n    return Promise.race([promise, new Promise(resolve => setTimeout(resolve, ms))]);\n  }\n\n  function makeVideo(src) {\n    const video = document.createElement('video');\n    video.muted = true;\n    video.loop = true;\n    video.playsInline = true;\n    video.preload = 'auto';\n    video.src = src;\n    return video;\n  }\n\n  function byName(root, name) {\n    // GLTFLoader sanitizes node names the way PropertyBinding does.\n    return root.getObjectByName(name) ?? root.getObjectByName(name.replace(/\\s/g, '_').replace(/[[\\].:/]/g, ''));\n  }\n\n  function step(entry, dt) {\n    entry.time = (entry.time + dt) % entry.duration;\n    // The screen video is exactly one loop long; keep the animation on its clock.\n    const video = entry.video;\n    if (video && video.readyState >= 2 && !video.paused && Math.abs(video.currentTime - entry.time) > 0.12) {\n      // Across the loop seam the two clocks are a whole loop apart, not out of sync.\n      if (Math.abs(video.currentTime - entry.time) < entry.duration / 2) entry.time = video.currentTime;\n    }\n    entry.mixer.setTime(entry.time);\n    const exact = entry.time * entry.fps;\n    const i = Math.floor(exact) % entry.frameCount;\n    const j = (i + 1) % entry.frameCount;\n    for (const track of entry.tracks) {\n      const a = track.values[i] ?? 1;\n      const b = track.values[j] ?? a;\n      const value = track.stepped ? a : a + (b - a) * (exact - Math.floor(exact));\n      track.node.visible = value > 0.002;\n      track.materials.forEach((m, k) => { m.opacity = track.base[k] * value; });\n    }\n  }\n\n  function fitCamera(entry, width, height, frameFill) {\n    const { camera, manifest } = entry;\n    const aspect = width / height;\n    // Same rule as the app: a portrait view shows the whole square frame across its width.\n    const stretch = Math.max(1, 1 / aspect) / frameFill;\n    if (camera.isOrthographicCamera) {\n      const half = (manifest.camera.scale ?? 1) / 2 * stretch;\n      camera.top = half;\n      camera.bottom = -half;\n      camera.left = -half * aspect;\n      camera.right = half * aspect;\n    } else {\n      const halfAngle = (manifest.camera.verticalFovDegrees ?? camera.fov) * Math.PI / 360;\n      camera.fov = 2 * Math.atan(Math.tan(halfAngle) * stretch) * 180 / Math.PI;\n      camera.aspect = aspect;\n    }\n    camera.updateProjectionMatrix();\n  }\n\n  // ---- the shared loop ----\n  let running = false;\n  let last = 0;\n  let slowFrames = 0;\n  let frameInterval = 0; // 0 = every display frame; 1/30 s once the device struggles\n\n  const needsFrame = view => view.visible && view.state === 'ready';\n\n  function wake() {\n    if (running || document.hidden) return;\n    if (!views.some(needsFrame)) return;\n    running = true;\n    last = performance.now();\n    requestAnimationFrame(frame);\n  }\n\n  document.addEventListener('visibilitychange', () => {\n    if (document.hidden) {\n      running = false;\n      views.forEach(v => v.scene?.video?.pause());\n    } else {\n      views.forEach(v => v.visible && v.scene && play(v));\n      wake();\n    }\n  });\n\n  let accumulated = 0;\n  function frame(now) {\n    if (!running) return;\n    const dt = Math.min(0.1, (now - last) / 1000);\n    last = now;\n    accumulated += dt;\n    if (accumulated >= frameInterval) {\n      const started = performance.now();\n      for (const view of views) {\n        if (!needsFrame(view)) continue;\n        if (!view.holding) step(view.scene, accumulated);\n        draw(view);\n      }\n      accumulated = 0;\n      // Drop to 30 fps when rendering alone keeps eating most of a 60 Hz frame.\n      if (frameInterval === 0 && performance.now() - started > 12) {\n        if (++slowFrames > 30) {\n          frameInterval = 1 / 30;\n          log('dropping to 30 fps');\n        }\n      } else {\n        slowFrames = Math.max(0, slowFrames - 1);\n      }\n    }\n    if (views.some(needsFrame)) requestAnimationFrame(frame);\n    else running = false;\n  }\n\n  function draw(view) {\n    const box = view.canvas?.isConnected ? view.canvas : view.img;\n    const cssWidth = box.offsetWidth;\n    const cssHeight = box.offsetHeight;\n    if (!cssWidth || !cssHeight) return;\n    const dpr = Math.min(devicePixelRatio || 1, MAX_DPR);\n    const width = Math.round(cssWidth * dpr);\n    const height = Math.round(cssHeight * dpr);\n\n    if (glCanvas.width !== width || glCanvas.height !== height) renderer.setSize(width, height, false);\n    render(view.scene, width, height, view.frameFill);\n\n    if (!view.canvas) swapIn(view, cssWidth, cssHeight);\n    // Chrome scales the bitmap to the canvas's own width and height (300 x 150 by default)\n    // before CSS sizes the element; Safari shows it at its own size. Match them.\n    if (view.canvas.width !== width || view.canvas.height !== height) {\n      view.canvas.width = width;\n      view.canvas.height = height;\n    }\n    view.ctx.transferFromImageBitmap(glCanvas.transferToImageBitmap());\n  }\n\n  function render(entry, width, height, frameFill) {\n    fitCamera(entry, width, height, frameFill);\n    renderer.toneMappingExposure = entry.exposure;\n    renderer.render(entry.scene, entry.camera);\n  }\n\n  // The canvas holds the poster's frame: fade the poster out, then fade the canvas in in its\n  // place and let the scene play on.\n  function swapIn(view, cssWidth, cssHeight) {\n    const { img } = view;\n    const canvas = document.createElement('canvas');\n    canvas.className = `${img.className} live-scene`.trim();\n    canvas.setAttribute('role', 'img');\n    canvas.setAttribute('aria-label', img.alt);\n    canvas.dataset.scene = view.key;\n    canvas.style.width = `${cssWidth}px`;\n    canvas.style.aspectRatio = `${cssWidth} / ${cssHeight}`;\n    canvas.style.height = 'auto';\n    canvas.style.maxWidth = '100%';\n    view.canvas = canvas;\n    view.ctx = canvas.getContext('bitmaprenderer');\n    img.animate([{ opacity: 1 }, { opacity: 0 }], { duration: 300, easing: 'ease-in', fill: 'forwards' }).finished.then(() => {\n      if (view.canvas !== canvas || view.state !== 'ready') return;\n      observer.unobserve(img);\n      img.replaceWith(canvas);\n      observer.observe(canvas);\n      img.getAnimations().forEach(animation => animation.cancel());\n      view.holding = false;\n      play(view);\n      canvas.animate([{ opacity: 0 }, { opacity: 1 }], { duration: 450, easing: 'ease-out' });\n    });\n  }\n\n  glCanvas.addEventListener('webglcontextlost', event => {\n    event.preventDefault();\n    running = false;\n    for (const view of views) {\n      view.img.getAnimations().forEach(animation => animation.cancel());\n      if (view.canvas?.isConnected) view.canvas.replaceWith(view.img);\n      view.scene?.video?.pause();\n      view.state = 'failed';\n    }\n  });\n\n  if (debug) window.liveScenes = { views, renderer, step, fitCamera, render, seekTo };\n}\n"],
  "mappings": "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",
  "names": ["BASE", "MAX_DPR", "NEAR_VIEWPORT", "images", "reducedMotion", "saveData", "debug", "log", "args", "hasWebGL2", "afterLoad", "start", "error", "resolve", "t0", "THREE", "AnimationMixer", "DoubleSide", "GLTFLoader", "MeshBasicMaterial", "MeshoptDecoder", "NeutralToneMapping", "PCFShadowMap", "PMREMGenerator", "PointLight", "RoomEnvironment", "SRGBColorSpace", "Scene", "SpotLight", "VideoTexture", "WebGLRenderer", "glCanvas", "renderer", "pmrem", "environment", "loader", "phonePromise", "loadPhone", "views", "img", "observer", "entries", "entry", "view", "v", "load", "play", "wake", "inFlight", "queue", "pump", "started", "buildScene", "scene", "seekTo", "key", "manifestPromise", "r", "gltf", "manifest", "phone", "videoSrc", "m", "blob", "light", "intensity", "distance", "i", "extent", "mapSize", "radius", "bias", "normalBias", "spot", "point", "name", "byName", "o", "video", "makeVideo", "phoneNode", "parts", "child", "screen", "texture", "material", "hidden", "stepped", "tracks", "values", "node", "materials", "themed", "colors", "part", "applyTheme", "theme", "mixer", "clip", "camera", "c", "fps", "frameCount", "frame", "time", "step", "within", "once", "target", "ms", "promise", "src", "root", "dt", "exact", "j", "track", "a", "b", "value", "k", "fitCamera", "width", "height", "frameFill", "aspect", "stretch", "half", "halfAngle", "running", "last", "slowFrames", "frameInterval", "needsFrame", "accumulated", "now", "draw", "box", "cssWidth", "cssHeight", "dpr", "render", "swapIn", "canvas", "animation", "event"]
}
