mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-04 02:14:01 +00:00
Knip, configured with the application, package exports, scripts, QA harnesses, workers, tools and tests as entry points, reports exports that no module imports. Each was checked by hand against string-based and namespace imports. - Symbols that are still used inside their own module lose only the `export` keyword (176 constants and helpers). - Unused re-exports are removed from barrel modules (flight, military, vessel, CCTV, directions, transit history, local ADS-B and street-level policy modules). - Declarations that nothing uses at all are deleted, among them AIS_WATCHDOG_STATUSES, applyFilter, isRadioCountryCode, compactText, DENSITY_STOPS, the unused CCTV endpoint constants, and the SDR band constants. - Default exports that nothing imports are removed. The ones in src/data/earthquakes.js, src/data/telegeographySubmarineCables.js, src/data/wind.js and src/data/bhoteKoshiLocator.js each constructed a layer instance at import time that nothing used; those instances are no longer created. Every export of a package.json entry stays, as does TOMTOM_CREDIT, which the traffic layer reads from the credits namespace it is given.
75 lines
2.7 KiB
JavaScript
75 lines
2.7 KiB
JavaScript
// Inspect encoded headers before allowing the browser to decode local images.
|
|
const MAX_IMPORT_IMAGE_PIXELS = 16 * 1024 * 1024;
|
|
const MAX_SIDE = 8192;
|
|
|
|
/** Width and height from a supported raster header; no image is decoded. */
|
|
export function importImageSize(bytes) {
|
|
const v = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
const ascii = (at, n) => String.fromCharCode(...bytes.subarray(at, at + n));
|
|
const u24 = (at) => bytes[at] | (bytes[at + 1] << 8) | (bytes[at + 2] << 16);
|
|
if (
|
|
bytes.length >= 24 &&
|
|
v.getUint32(0) === 0x89504e47 &&
|
|
ascii(12, 4) === 'IHDR'
|
|
)
|
|
return [v.getUint32(16), v.getUint32(20)];
|
|
if (bytes.length >= 10 && /^GIF8[79]a$/.test(ascii(0, 6)))
|
|
return [v.getUint16(6, true), v.getUint16(8, true)];
|
|
if (bytes.length >= 26 && ascii(0, 2) === 'BM') {
|
|
if (v.getUint32(14, true) === 12)
|
|
return [v.getUint16(18, true), v.getUint16(20, true)];
|
|
return [Math.abs(v.getInt32(18, true)), Math.abs(v.getInt32(22, true))];
|
|
}
|
|
if (bytes.length >= 30 && ascii(0, 4) === 'RIFF' && ascii(8, 4) === 'WEBP') {
|
|
const kind = ascii(12, 4);
|
|
if (kind === 'VP8X') return [1 + u24(24), 1 + u24(27)];
|
|
if (kind === 'VP8 ' && u24(23) === 0x2a019d)
|
|
return [v.getUint16(26, true) & 0x3fff, v.getUint16(28, true) & 0x3fff];
|
|
if (kind === 'VP8L' && bytes[20] === 0x2f) {
|
|
const bits = v.getUint32(21, true);
|
|
return [(bits & 0x3fff) + 1, ((bits >>> 14) & 0x3fff) + 1];
|
|
}
|
|
}
|
|
if (bytes.length >= 4 && v.getUint16(0) === 0xffd8) {
|
|
for (let at = 2; at + 4 <= bytes.length;) {
|
|
if (bytes[at++] !== 0xff) break;
|
|
while (bytes[at] === 0xff) at++;
|
|
const marker = bytes[at++];
|
|
if (marker === 0xd9 || marker === 0xda) break;
|
|
if (marker === 1 || (marker >= 0xd0 && marker <= 0xd7)) continue;
|
|
const length = v.getUint16(at);
|
|
if (length < 2 || at + length > bytes.length) break;
|
|
if (
|
|
[
|
|
0xc0, 0xc1, 0xc2, 0xc3, 0xc5, 0xc6, 0xc7, 0xc9, 0xca, 0xcb, 0xcd,
|
|
0xce, 0xcf,
|
|
].includes(marker) &&
|
|
length >= 8
|
|
)
|
|
return [v.getUint16(at + 5), v.getUint16(at + 3)];
|
|
at += length;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
/** Charge each distinct encoded image once against the file's decoded budget. */
|
|
export function createImportImageBudget() {
|
|
const seen = new Set();
|
|
let pixels = 0;
|
|
return (key, bytes) => {
|
|
if (seen.has(key)) return;
|
|
const size = importImageSize(bytes);
|
|
if (
|
|
!size ||
|
|
size.some((n) => !Number.isInteger(n) || n <= 0 || n > MAX_SIDE) ||
|
|
pixels + size[0] * size[1] > MAX_IMPORT_IMAGE_PIXELS
|
|
)
|
|
throw new Error(
|
|
'Local images exceed the decoded image limit or have an unreadable header.',
|
|
);
|
|
pixels += size[0] * size[1];
|
|
seen.add(key);
|
|
};
|
|
}
|