{"_id":"@emdzej/ncsx-chassis","_rev":"6-c213e57c537f3a9bbc9a532b496d1b01","name":"@emdzej/ncsx-chassis","dist-tags":{"latest":"0.9.0"},"versions":{"0.4.0":{"name":"@emdzej/ncsx-chassis","version":"0.4.0","_id":"@emdzej/ncsx-chassis@0.4.0","maintainers":[{"name":"emdzej","email":"michal@jaskolski.pro"}],"homepage":"https://github.com/emdzej/ncsx#readme","bugs":{"url":"https://github.com/emdzej/ncsx/issues"},"dist":{"shasum":"03b7d66e43acd9c1b3f9cab199a7f80b39f02216","tarball":"https://registry.npmjs.org/@emdzej/ncsx-chassis/-/ncsx-chassis-0.4.0.tgz","fileCount":55,"integrity":"sha512-WBq1JuFCqipOr5pvHbRHTzBKLW1Zo//vuPkkcQ28CKL81Zbb/BFxOmR6gp6mFrdg1wRb7SacGk1B601jqmMtIw==","signatures":[{"sig":"MEYCIQC1C7Ykm5uoza+uYnJYTAXRFpIVM9pN5xNTK+agRth5PwIhAPnrMEH1HyB62LVfDo3vCwK2mS3PpSSqzNA6MJD0fCLO","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":90533},"main":"dist/index.js","type":"module","_from":"file:emdzej-ncsx-chassis-0.4.0.tgz","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./node":{"types":"./dist/node.d.ts","default":"./dist/node.js"}},"scripts":{"lint":"eslint .","test":"vitest run --passWithNoTests","build":"tsc -p tsconfig.json","clean":"rm -rf dist .turbo *.tsbuildinfo","typecheck":"tsc --noEmit","test:watch":"vitest"},"_npmUser":{"name":"emdzej","email":"michal@jaskolski.pro"},"_resolved":"/private/var/folders/7h/x_w_580x4s9dq3sq11tpvzkwy3nbj8/T/a687cf81f3e2c3f8fb8dd4003ea5e32b/emdzej-ncsx-chassis-0.4.0.tgz","_integrity":"sha512-WBq1JuFCqipOr5pvHbRHTzBKLW1Zo//vuPkkcQ28CKL81Zbb/BFxOmR6gp6mFrdg1wRb7SacGk1B601jqmMtIw==","repository":{"url":"git+https://github.com/emdzej/ncsx.git","type":"git","directory":"packages/chassis"},"_npmVersion":"11.14.1","description":"Chassis bundle loader — BR_REF aliasing + DST/SGET/SGVT/ZCSUT/CVT + SGFAM/ZST/AT, lazy CABD on demand.","directories":{},"_nodeVersion":"22.22.1","dependencies":{"@emdzej/ncsx-daten":"0.4.0","@emdzej/ncsx-text-tables":"0.4.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^2.1.8","@types/node":"^22.13.1","@emdzej/bimmerz-logger":"^0.1.2"},"peerDependencies":{"@emdzej/bimmerz-logger":"^0.1.2"},"_npmOperationalInternal":{"tmp":"tmp/ncsx-chassis_0.4.0_1779705632347_0.500549977767567","host":"s3://npm-registry-packages-npm-production"}},"0.5.1":{"name":"@emdzej/ncsx-chassis","version":"0.5.1","_id":"@emdzej/ncsx-chassis@0.5.1","maintainers":[{"name":"emdzej","email":"michal@jaskolski.pro"}],"homepage":"https://github.com/emdzej/ncsx#readme","bugs":{"url":"https://github.com/emdzej/ncsx/issues"},"dist":{"shasum":"03db7be800af0bfc152e3845117b75bc649784f1","tarball":"https://registry.npmjs.org/@emdzej/ncsx-chassis/-/ncsx-chassis-0.5.1.tgz","fileCount":55,"integrity":"sha512-qr3L8Igqskp1fQWarDGjD3Kry8Iwehm9miYcGgC+48cT3frrabMofhLIP4wtRmBSxagJ1k830QaEdVJBca7oiw==","signatures":[{"sig":"MEUCIQDVZHYM/VDk4CNC1iSPZRKv5rbcmnv7hCB4zE80zEpwhQIgGJ8h3a7TCPLMmV5PpEkkJjXlHoKWlkZnEA3iIX8Louo=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":90533},"main":"dist/index.js","type":"module","_from":"file:emdzej-ncsx-chassis-0.5.1.tgz","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./node":{"types":"./dist/node.d.ts","default":"./dist/node.js"}},"scripts":{"lint":"eslint .","test":"vitest run --passWithNoTests","build":"tsc -p tsconfig.json","clean":"rm -rf dist .turbo *.tsbuildinfo","typecheck":"tsc --noEmit","test:watch":"vitest"},"_npmUser":{"name":"emdzej","email":"michal@jaskolski.pro"},"_resolved":"/private/var/folders/7h/x_w_580x4s9dq3sq11tpvzkwy3nbj8/T/3268c7a29578d567c6bf6dc5919b762b/emdzej-ncsx-chassis-0.5.1.tgz","_integrity":"sha512-qr3L8Igqskp1fQWarDGjD3Kry8Iwehm9miYcGgC+48cT3frrabMofhLIP4wtRmBSxagJ1k830QaEdVJBca7oiw==","repository":{"url":"git+https://github.com/emdzej/ncsx.git","type":"git","directory":"packages/chassis"},"_npmVersion":"11.14.1","description":"Chassis bundle loader — BR_REF aliasing + DST/SGET/SGVT/ZCSUT/CVT + SGFAM/ZST/AT, lazy CABD on demand.","directories":{},"_nodeVersion":"22.22.1","dependencies":{"@emdzej/ncsx-daten":"0.5.1","@emdzej/ncsx-text-tables":"0.5.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^2.1.8","@types/node":"^22.13.1","@emdzej/bimmerz-logger":"^0.1.2"},"peerDependencies":{"@emdzej/bimmerz-logger":"^0.1.2"},"_npmOperationalInternal":{"tmp":"tmp/ncsx-chassis_0.5.1_1779876442487_0.9660937510142786","host":"s3://npm-registry-packages-npm-production"}},"0.6.0":{"name":"@emdzej/ncsx-chassis","version":"0.6.0","_id":"@emdzej/ncsx-chassis@0.6.0","maintainers":[{"name":"emdzej","email":"michal@jaskolski.pro"}],"homepage":"https://github.com/emdzej/ncsx#readme","bugs":{"url":"https://github.com/emdzej/ncsx/issues"},"dist":{"shasum":"f1bb32471504d474d4d954b0f0e0fe62deb4c023","tarball":"https://registry.npmjs.org/@emdzej/ncsx-chassis/-/ncsx-chassis-0.6.0.tgz","fileCount":55,"integrity":"sha512-U6hzTwUGjRP553AcroWOSXzNjptY+OZL36CQO/SYUio8OojlqxajuficciFDZyJZmXtxP9WX7NAczEzDtyQJhA==","signatures":[{"sig":"MEUCIEnM9ZpD2jL5TpRicsev47N8cp5i/5ujnDZez1iocuMBAiEAwrj3p8FfbRSmxPkiAjT11NSxolbxc8LDtptgd8TL1RA=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":90533},"main":"dist/index.js","type":"module","_from":"file:emdzej-ncsx-chassis-0.6.0.tgz","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./node":{"types":"./dist/node.d.ts","default":"./dist/node.js"}},"scripts":{"lint":"eslint .","test":"vitest run --passWithNoTests","build":"tsc -p tsconfig.json","clean":"rm -rf dist .turbo *.tsbuildinfo","typecheck":"tsc --noEmit","test:watch":"vitest"},"_npmUser":{"name":"emdzej","email":"michal@jaskolski.pro"},"_resolved":"/private/var/folders/7h/x_w_580x4s9dq3sq11tpvzkwy3nbj8/T/9ca1cc05a9b6ff6e59010ccdf5e613eb/emdzej-ncsx-chassis-0.6.0.tgz","_integrity":"sha512-U6hzTwUGjRP553AcroWOSXzNjptY+OZL36CQO/SYUio8OojlqxajuficciFDZyJZmXtxP9WX7NAczEzDtyQJhA==","repository":{"url":"git+https://github.com/emdzej/ncsx.git","type":"git","directory":"packages/chassis"},"_npmVersion":"11.14.1","description":"Chassis bundle loader — BR_REF aliasing + DST/SGET/SGVT/ZCSUT/CVT + SGFAM/ZST/AT, lazy CABD on demand.","directories":{},"_nodeVersion":"22.22.1","dependencies":{"@emdzej/ncsx-daten":"0.6.0","@emdzej/ncsx-text-tables":"0.6.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^2.1.8","@types/node":"^22.13.1","@emdzej/bimmerz-logger":"^0.1.2"},"peerDependencies":{"@emdzej/bimmerz-logger":"^0.1.2"},"_npmOperationalInternal":{"tmp":"tmp/ncsx-chassis_0.6.0_1779981246114_0.46760524575542073","host":"s3://npm-registry-packages-npm-production"}},"0.7.0":{"name":"@emdzej/ncsx-chassis","version":"0.7.0","_id":"@emdzej/ncsx-chassis@0.7.0","maintainers":[{"name":"emdzej","email":"michal@jaskolski.pro"}],"homepage":"https://github.com/emdzej/ncsx#readme","bugs":{"url":"https://github.com/emdzej/ncsx/issues"},"dist":{"shasum":"8e20d06c864e625a3798954645f269ce6a33fd03","tarball":"https://registry.npmjs.org/@emdzej/ncsx-chassis/-/ncsx-chassis-0.7.0.tgz","fileCount":55,"integrity":"sha512-SSVgjy7sEpqdaw600ZdDzYAe1MWLAU6E9DHF7D+OEnYbNSBl6xUv7Kx4t/NEU9Ez8q+xS1104xApOo+BcTY9kA==","signatures":[{"sig":"MEYCIQDbkWc0kQKnYwPX/VtsqWwja4W68HDfgvJNA/Cco9tYsAIhAPxX1E3X+mgsv7m6EcVGX+rf7n6j59ovLzO/WjYOFDav","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":90533},"main":"dist/index.js","type":"module","_from":"file:emdzej-ncsx-chassis-0.7.0.tgz","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./node":{"types":"./dist/node.d.ts","default":"./dist/node.js"}},"scripts":{"lint":"eslint .","test":"vitest run --passWithNoTests","build":"tsc -p tsconfig.json","clean":"rm -rf dist .turbo *.tsbuildinfo","typecheck":"tsc --noEmit","test:watch":"vitest"},"_npmUser":{"name":"emdzej","email":"michal@jaskolski.pro"},"_resolved":"/private/var/folders/7h/x_w_580x4s9dq3sq11tpvzkwy3nbj8/T/d2ab5fdf79c767a276fc05a167a80b7c/emdzej-ncsx-chassis-0.7.0.tgz","_integrity":"sha512-SSVgjy7sEpqdaw600ZdDzYAe1MWLAU6E9DHF7D+OEnYbNSBl6xUv7Kx4t/NEU9Ez8q+xS1104xApOo+BcTY9kA==","repository":{"url":"git+https://github.com/emdzej/ncsx.git","type":"git","directory":"packages/chassis"},"_npmVersion":"11.14.1","description":"Chassis bundle loader — BR_REF aliasing + DST/SGET/SGVT/ZCSUT/CVT + SGFAM/ZST/AT, lazy CABD on demand.","directories":{},"_nodeVersion":"22.22.1","dependencies":{"@emdzej/ncsx-daten":"0.7.0","@emdzej/ncsx-text-tables":"0.7.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^2.1.8","@types/node":"^22.13.1","@emdzej/bimmerz-logger":"^0.1.2"},"peerDependencies":{"@emdzej/bimmerz-logger":"^0.1.2"},"_npmOperationalInternal":{"tmp":"tmp/ncsx-chassis_0.7.0_1780063012360_0.7478490949709187","host":"s3://npm-registry-packages-npm-production"}},"0.8.0":{"name":"@emdzej/ncsx-chassis","version":"0.8.0","_id":"@emdzej/ncsx-chassis@0.8.0","maintainers":[{"name":"emdzej","email":"michal@jaskolski.pro"}],"homepage":"https://github.com/emdzej/ncsx#readme","bugs":{"url":"https://github.com/emdzej/ncsx/issues"},"dist":{"shasum":"98eb073fbf9cd65a3401c740af34f9deb845f339","tarball":"https://registry.npmjs.org/@emdzej/ncsx-chassis/-/ncsx-chassis-0.8.0.tgz","fileCount":55,"integrity":"sha512-qdZzKzpB3ngzSJ9oEJTtj4OedMvV4j39MNYgS4j++ygu+Nut7RSZM1MsZcB6upPSihTycM//xJHbNVtsaVct7Q==","signatures":[{"sig":"MEQCICVLN7C98yQb6GV4J/xfcdQ1UbY4q15ylrB3o+t2jRG5AiBMSRjVA3HQRz3eMsUYeRrLvHxd8jiDQjqUZxAdZ+AU4w==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":90533},"main":"dist/index.js","type":"module","_from":"file:emdzej-ncsx-chassis-0.8.0.tgz","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./node":{"types":"./dist/node.d.ts","default":"./dist/node.js"}},"scripts":{"lint":"eslint .","test":"vitest run --passWithNoTests","build":"tsc -p tsconfig.json","clean":"rm -rf dist .turbo *.tsbuildinfo","typecheck":"tsc --noEmit","test:watch":"vitest"},"_npmUser":{"name":"emdzej","email":"michal@jaskolski.pro"},"_resolved":"/private/var/folders/7h/x_w_580x4s9dq3sq11tpvzkwy3nbj8/T/9d877afd888a716cc00b549e53ddae12/emdzej-ncsx-chassis-0.8.0.tgz","_integrity":"sha512-qdZzKzpB3ngzSJ9oEJTtj4OedMvV4j39MNYgS4j++ygu+Nut7RSZM1MsZcB6upPSihTycM//xJHbNVtsaVct7Q==","repository":{"url":"git+https://github.com/emdzej/ncsx.git","type":"git","directory":"packages/chassis"},"_npmVersion":"11.16.0","description":"Chassis bundle loader — BR_REF aliasing + DST/SGET/SGVT/ZCSUT/CVT + SGFAM/ZST/AT, lazy CABD on demand.","directories":{},"_nodeVersion":"22.22.1","dependencies":{"@emdzej/ncsx-daten":"0.8.0","@emdzej/ncsx-text-tables":"0.8.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^2.1.8","@types/node":"^22.13.1","@emdzej/bimmerz-logger":"^0.1.2"},"peerDependencies":{"@emdzej/bimmerz-logger":"^0.1.2"},"_npmOperationalInternal":{"tmp":"tmp/ncsx-chassis_0.8.0_1780758419755_0.5585567912435541","host":"s3://npm-registry-packages-npm-production"}},"0.9.0":{"name":"@emdzej/ncsx-chassis","version":"0.9.0","description":"Chassis bundle loader — BR_REF aliasing + DST/SGET/SGVT/ZCSUT/CVT + SGFAM/ZST/AT, lazy CABD on demand.","main":"dist/index.js","types":"dist/index.d.ts","type":"module","exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./node":{"types":"./dist/node.d.ts","default":"./dist/node.js"}},"dependencies":{"@emdzej/ncsx-text-tables":"0.9.0","@emdzej/ncsx-daten":"0.9.0"},"peerDependencies":{"@emdzej/bimmerz-logger":"^0.1.2"},"devDependencies":{"@emdzej/bimmerz-logger":"^0.1.2","@types/node":"^22.13.1","vitest":"^2.1.8"},"publishConfig":{"access":"public"},"repository":{"type":"git","url":"git+https://github.com/emdzej/ncsx.git","directory":"packages/chassis"},"scripts":{"build":"tsc -p tsconfig.json","test":"vitest run --passWithNoTests","test:watch":"vitest","lint":"eslint .","typecheck":"tsc --noEmit","clean":"rm -rf dist .turbo *.tsbuildinfo"},"_id":"@emdzej/ncsx-chassis@0.9.0","bugs":{"url":"https://github.com/emdzej/ncsx/issues"},"homepage":"https://github.com/emdzej/ncsx#readme","_integrity":"sha512-2EmSCRrnUp6Js9dhvQM1FD0unYtX8it/+ye1BUzXLSeShr3tG+5kUBW5EklL8dpAz3xb72MJpqrqWeYcOzZbDg==","_resolved":"/private/var/folders/7h/x_w_580x4s9dq3sq11tpvzkwy3nbj8/T/50009e6faebd25439ba5a9aa4af3da87/emdzej-ncsx-chassis-0.9.0.tgz","_from":"file:emdzej-ncsx-chassis-0.9.0.tgz","_nodeVersion":"22.22.1","_npmVersion":"11.16.0","dist":{"integrity":"sha512-2EmSCRrnUp6Js9dhvQM1FD0unYtX8it/+ye1BUzXLSeShr3tG+5kUBW5EklL8dpAz3xb72MJpqrqWeYcOzZbDg==","shasum":"407dba6cc8dcebc543f8cd4c6dc04743281d300d","tarball":"https://registry.npmjs.org/@emdzej/ncsx-chassis/-/ncsx-chassis-0.9.0.tgz","fileCount":55,"unpackedSize":90533,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQDfHmfPP2EOPel3zb31IFgr4dlR8+kIW0htA2liJ5YHRwIhAIYbI7dQLQEwdFSnOUwYDMBRhtF9Cnmub6Ck/2Sn/ILU"}]},"_npmUser":{"name":"emdzej","email":"michal@jaskolski.pro"},"directories":{},"maintainers":[{"name":"emdzej","email":"michal@jaskolski.pro"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/ncsx-chassis_0.9.0_1783336565509_0.7329950396868761"},"_hasShrinkwrap":false}},"time":{"created":"2026-05-25T10:40:32.191Z","modified":"2026-07-06T11:16:05.802Z","0.4.0":"2026-05-25T10:40:32.484Z","0.5.1":"2026-05-27T10:07:22.651Z","0.6.0":"2026-05-28T15:14:06.250Z","0.7.0":"2026-05-29T13:56:52.508Z","0.8.0":"2026-06-06T15:06:59.882Z","0.9.0":"2026-07-06T11:16:05.657Z"},"bugs":{"url":"https://github.com/emdzej/ncsx/issues"},"homepage":"https://github.com/emdzej/ncsx#readme","repository":{"type":"git","url":"git+https://github.com/emdzej/ncsx.git","directory":"packages/chassis"},"description":"Chassis bundle loader — BR_REF aliasing + DST/SGET/SGVT/ZCSUT/CVT + SGFAM/ZST/AT, lazy CABD on demand.","maintainers":[{"name":"emdzej","email":"michal@jaskolski.pro"}],"readme":"# @emdzej/ncsx-chassis\n\nLoads a complete **chassis bundle** from NCSEXPER's DATEN tree. Resolves chassis aliases\n(E91 → E89, R56 → R50, …), opens all the per-chassis text + binary tables in parallel, and\nexposes a lazy CABD-by-SG loader on top.\n\nThis is the package end-user apps reach for first: give it a folder, get a `Chassis`\nobject back, and every downstream piece of the stack (`fa-asw`, `ecu-select`, `coder`,\n`function-list`) works against it.\n\nSpec: [`../../docs/daten-format.md`](../../docs/daten-format.md) for the file formats,\n[`../../docs/ecu-selection.md`](../../docs/ecu-selection.md) for how the loaded tables\ncompose to drive ECU selection.\n\n## What you get\n\n```ts\ninterface Chassis {\n  code: string;            // canonical chassis code (after aliasing) — e.g. 'E89'\n  requestedCode: string;   // what the caller asked for — e.g. 'E91'\n  dir: string;             // lowercase chassis dir name, e.g. 'e89'\n\n  // Binary tables (DatenFile objects from @emdzej/ncsx-daten)\n  brRef: DatenFile;        // BR_REF.DAT\n  dst: DatenFile;          // <BR>DST.000\n  sget: DatenFile;         // <BR>SGET.000\n  sgvt: DatenFile;         // <BR>SGVT.000\n  zcsut: DatenFile;        // <BR>ZCSUT.000 (optional)\n  cvt: DatenFile;          // <BR>CVT.000 (optional)\n\n  // Text tables (parsed; indexed where it helps)\n  sgfam: Map<string, SgfamRow>;  // SG short-name → SGFAM row\n  zst?: ZstIndex;                // <BR>ZST.000 — by FSW and SA\n  at?: Map<string, AtRecord>;    // <BR>AT.000 — by FA code\n  atM00?: AtM00File;             // <BR>AT.M00 (Z/E/W/S rows)\n  atZus?: AtFile;                // <BR>AT.ZUS (optional)\n\n  // SWT lookup tables (FSW/PSW/ASW name ↔ KEYID)\n  swtAsw?: SwtTable;\n  swtFsw?: SwtTable;\n  swtPsw?: SwtTable;\n\n  // Lazy CABD loader — loads <SGBD>.Cxx files on demand and caches them\n  cabd: CabdLoader;\n}\n```\n\n## Install\n\n```bash\npnpm add @emdzej/ncsx-chassis\n# or:\n\"@emdzej/ncsx-chassis\": \"workspace:*\"\n```\n\n## Quick start (Node)\n\n```ts\nimport { loadChassis } from '@emdzej/ncsx-chassis';\nimport { nodeChassisSource } from '@emdzej/ncsx-chassis/node';\n\nconst source = nodeChassisSource('/path/to/NCSEXPER/DATEN');\nconst chassis = await loadChassis(source, 'E91', {\n  onWarning: (w) => console.warn(w),\n});\n\nconsole.log(chassis.code);                  // 'E89' (aliased)\nconsole.log(chassis.sgfam.get('EWS'));      // { sgName: 'EWS', cabd: 'A_EWS3', sgbd: 'C_EWS3', … }\n\n// Lazy enumerate every .Cxx coding-data module shipped for this chassis.\nconst modules = await chassis.cabd.listModules();\n// → [{ moduleName: 'EWS', codingIndexes: [0x81] }, …]\n\n// Open one by basename + coding index:\nconst ews = await chassis.cabd.openModule('EWS', 0x81);\n```\n\nThe `.Cxx` file name is the **physical SG basename** (e.g. `KMB_E46`, `EWS`) — *not* the\nSGFAM `CABD` column. See [`../../docs/ecu-selection.md` §8](../../docs/ecu-selection.md)\nfor the full lookup contract and how to derive the basename from a `SelectedSg` returned\nby `@emdzej/ncsx-ecu-select`.\n\n## Quick start (Browser)\n\nIn the browser we don't have `node:fs`; provide your own `ChassisSource` adapter backed by\n[`FileSystemDirectoryHandle`](https://developer.mozilla.org/docs/Web/API/FileSystemDirectoryHandle).\nThe `apps/web` app does this in\n[`src/lib/fs-chassis-source.ts`](../../apps/web/src/lib/fs-chassis-source.ts) —\n~80 lines, case-insensitive segment drill.\n\n## `ChassisSource`\n\nThin filesystem abstraction so callers can plug in any backing store. Implement three\nmethods:\n\n```ts\ninterface ChassisSource {\n  read(path: string): Promise<Uint8Array>;\n  exists(path: string): Promise<boolean>;\n  list(dir: string): Promise<string[]>;\n}\n```\n\nBundled adapters:\n\n- `nodeChassisSource(rootDir)` — `node:fs/promises` backed. **Import from\n  `@emdzej/ncsx-chassis/node`** (not the default entry — that one is browser-safe).\n- `inMemoryChassisSource(files)` — `Map<string, Uint8Array>` backed; used in tests.\n\n## API\n\n| Export                      | Purpose                                                         |\n|-----------------------------|-----------------------------------------------------------------|\n| `loadChassis(source, code, opts?)` | Top-level loader                                         |\n| `loadBrRef(source)`         | Just `BR_REF.DAT` (used internally, exposed for alias dumps)    |\n| `resolveChassisCode(brRef, requested)` | Apply BR_REF aliases (E91 → E89, …)                  |\n| `CabdLoader`                | The lazy CABD class hung off `chassis.cabd`                     |\n| `indexSgfam` / `indexZst` / `indexAt` / `indexSwt` | Indexers that turn parsed `DatenFile`s into the convenient `Map`s on the chassis bundle |\n| `loadSwtFile(source, dir, kind)` | Find + parse one `SWT<kind><NN>.DAT` lookup table          |\n| `nodeChassisSource(rootDir)` | (subpath `/node`) Node `fs/promises` adapter                   |\n| `inMemoryChassisSource(files)` | Map-backed adapter for tests                                  |\n\n## What gets read\n\n| Required           | Required (otherwise throws)                                    |\n|--------------------|----------------------------------------------------------------|\n| `BR_REF.DAT`       | At the source root — used for aliasing                         |\n| `<BR>DST.000`      | The minimum-viable per-chassis file                            |\n\n| Optional           | If missing, the field is `undefined` and a warning fires       |\n|--------------------|----------------------------------------------------------------|\n| `<BR>SGET.000`     | ECU-selection rows                                             |\n| `<BR>SGVT.000`     | SG variants                                                    |\n| `<BR>ZCSUT.000`    | ZCS update tables                                              |\n| `<BR>CVT.000`      | Coding-variant order-options                                   |\n| `<BR>SGFAM.DAT`    | SG name → CABD/SGBD mapping                                    |\n| `<BR>ZST.000`      | SA / FA / ASW master                                           |\n| `<BR>AT.000`       | FA-code dictionary                                             |\n| `<BR>AT.M00`       | Zwang/Entfall/special rules                                    |\n| `<BR>AT.ZUS`       | AT companion                                                   |\n| `SWTASW<NN>.DAT`   | ASW name ↔ KEYID                                               |\n| `SWTFSW<NN>.DAT`   | FSW name ↔ KEYID                                               |\n| `SWTPSW<NN>.DAT`   | PSW name ↔ KEYID                                               |\n\nCABD `.Cxx` files (~150 per chassis) are **not** preloaded — use\n`chassis.cabd.listModules()` to enumerate them and\n`chassis.cabd.openModule(moduleName, ci)` to fetch one on demand.\n\n## Related\n\n- [`@emdzej/ncsx-daten`](../daten/) — the binary parser this builds on.\n- [`@emdzej/ncsx-text-tables`](../text-tables/) — the text parsers used internally.\n- [`@emdzej/ncsx-fa-asw`](../fa-asw/) — first consumer of the loaded chassis.\n- [`@emdzej/ncsx-ecu-select`](../ecu-select/) / [`@emdzej/ncsx-coder`](../coder/) — downstream.\n","readmeFilename":"README.md"}