Vendor JavaScript Libraries
============================

This directory contains third-party JavaScript libraries used by the
Instinctor plugin. All libraries are MIT-licensed (or BSD-3-Clause for
jQuery/jQuery UI) and are served from this directory (never a CDN) to
keep the site self-contained, work behind a CSP, and avoid third-party
tracking.

Library          Version    License        Source
---------------- ---------- -------------- ----------------------------------
three.min.js     r185       MIT            https://github.com/mrdoob/three.js
three-loaders    r185       MIT            https://github.com/mrdoob/three.js
sortable.min.js  1.15.7     MIT            https://github.com/SortableJS/Sortable
html2canvas.min  1.4.1      MIT            https://github.com/niklasvh/html2canvas
jquery.min.js    3.7.1      MIT            https://jquery.com
jquery-ui.min    1.13.2     MIT            https://jqueryui.com

three.min.js (r185)
-------------------
three.js r163 and later ship as ES modules only (the upstream UMD build
"build/three.min.js" was deprecated at r150 and removed at r161). Our 3D
effects engine loads THREE as a synchronous classic-script global, so we
bundle the official r185 ES-module distribution into an IIFE that exposes
the same global `THREE`, using esbuild:

    import * as THREE from "three";              // official r185 ESM
    if (THREE.ColorManagement) THREE.ColorManagement.enabled = false;
    export * from "three";

    esbuild entry.js --bundle --format=iife --global-name=THREE \
      --minify --legal-comments=eof --banner:js="<MIT license>"

The result is the official r185 module graph wrapped as a global; no
library source is modified. The MIT license and copyright notice are
preserved in the file banner.

three-loaders.min.js (r185)
--------------------------
GLTFLoader from the official r185 examples, bundled as an IIFE that ATTACHES
to the existing global (`THREE.GLTFLoader = ...`). It does NOT contain three
itself: the `three` import is aliased to a generated shim that re-exports the
already-loaded global, so the page keeps ONE THREE instance. Two copies is the
failure this avoids - objects built by one fail `instanceof` in the other,
materials silently do not apply, and nothing throws.

The shim's export list is generated from the loader's own import statements at
build time (69 symbols at r185), so a version bump cannot leave it quietly
short of a symbol.

DRACOLoader and KTX2Loader are deliberately NOT bundled. Both resolve decoder
asset paths from `import.meta.url`, which does not exist in an IIFE, so they
throw "Invalid URL" at load. Adding either means shipping its decoder assets
(~300KB of wasm/js for Draco) and setting the path explicitly at runtime. Do
that when the model library needs compression, not before.

    npm i three@0.185.0 esbuild && node bin/build-three-loaders.mjs

The script generates the shim from the loader's imports and runs esbuild; it
lives at bin/build-three-loaders.mjs in the repo (not shipped in the zips).

`ColorManagement.enabled = false` is set once at load to keep the legacy
(pre-r152) linear color workflow, so effect / material / canvas-texture
colors render identically to the previously pinned build. This is the
only runtime configuration applied.

three.js is a pure client-side rendering library: no networking,
persistence, or server-side surface. r185 has no known CVEs.

Rebuilding (when bumping the pinned version)
--------------------------------------------
    curl -L https://registry.npmjs.org/three/-/three-<ver>.tgz | tar xz
    curl -L https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-<v>.tgz | tar xz
    # write entry.js as above, then run the esbuild command above

Each other library file retains its original /*! ... */ license banner at
the top so the license text travels with the file. To get an unminified
copy of any library for inspection, follow the "Source" URL above and
download the matching tagged release.
