mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-04 10:24:02 +00:00
chore: remove unused imports and local helpers
Drop module-local helpers that nothing calls (linkAbort, summarize, stringOption, summarizeEntity and the polygonCenter, propertyObject and unwrapProperties helpers only it used, CALLOUT_DOT_SIZE_PX) and unused import specifiers in runtime modules, tests, QA scripts and tools. None of the removed bindings is exported. Re-exports such as the ALPR policy constants and every package export are unchanged.
This commit is contained in:
1 parent
e479b6e91d
commit
f60b9ef7c8
42 files changed
+9
-191
No files matched your search
@@ -34,10 +34,6 @@
|
||||
import puppeteer from 'puppeteer';
|
||||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
const REPO_ROOT = path.resolve(__dirname, '..');
|
||||
|
||||
const argv = process.argv.slice(2);
|
||||
const getOpt = (name, dflt) => {
|
||||
|
||||
@@ -86,14 +86,6 @@ function percentile(values, pct) {
|
||||
return sorted[Math.min(sorted.length - 1, Math.ceil(sorted.length * pct) - 1)];
|
||||
}
|
||||
|
||||
function parseJson(value, fallback) {
|
||||
try {
|
||||
return JSON.parse(value);
|
||||
} catch {
|
||||
return fallback;
|
||||
}
|
||||
}
|
||||
|
||||
function analyzeMembership(samples) {
|
||||
let replacements = 0;
|
||||
let exposure = 0;
|
||||
|
||||
@@ -30,7 +30,6 @@ import {
|
||||
import {
|
||||
answerKartaViewRequest,
|
||||
describeKartaViewCall,
|
||||
KV_LINE,
|
||||
KV_SEQUENCE_ID,
|
||||
kartaViewPhotos,
|
||||
resetKartaViewFixture,
|
||||
|
||||
@@ -47,8 +47,6 @@ import {
|
||||
reduceScenario,
|
||||
reduceSensorContrast,
|
||||
reduceScriptedMotion,
|
||||
reduceMotion,
|
||||
reduceFleet,
|
||||
} from '../src/layers/transit/qaMetrics.js';
|
||||
|
||||
const BASE = process.env.QA_BASE_URL || 'http://localhost:4173';
|
||||
|
||||
@@ -8,13 +8,7 @@
|
||||
* node scripts/qa-weather-swap.mjs --url http://localhost:4173 --label google
|
||||
* [--layer weather-satellite] [--product clouds] [--headless]
|
||||
*/
|
||||
import {
|
||||
existsSync,
|
||||
mkdirSync,
|
||||
readdirSync,
|
||||
readFileSync,
|
||||
writeFileSync,
|
||||
} from 'node:fs';
|
||||
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
||||
import path from 'node:path';
|
||||
import puppeteer from 'puppeteer';
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { readdirSync } from 'node:fs';
|
||||
import { spawnSync } from 'node:child_process';
|
||||
import path from 'node:path';
|
||||
import { fileURLToPath, pathToFileURL } from 'node:url';
|
||||
import { pathToFileURL } from 'node:url';
|
||||
|
||||
export const ALLOCATION_TEST_FILES = Object.freeze([
|
||||
'src/data/focusAllocations.test.mjs',
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
import { createCctvCatalog } from './cctv/catalog.js';
|
||||
import {
|
||||
normalizeFeedType,
|
||||
isVideoFeedType,
|
||||
toFiniteNumber,
|
||||
} from './cctv/normalize.js';
|
||||
import { normalizeFeedType, isVideoFeedType } from './cctv/normalize.js';
|
||||
import {
|
||||
buildSyntheticCctvSvg,
|
||||
cctvLiveMediaType,
|
||||
|
||||
@@ -133,7 +133,6 @@ import {
|
||||
fallbackHeadingFromId,
|
||||
isLikelyFinlandCoordinate,
|
||||
fintrafficCameraName,
|
||||
hashSeed,
|
||||
isPlausibleLatLon,
|
||||
isLikelyBcCoordinate,
|
||||
isLikelyTexasCoordinate,
|
||||
|
||||
@@ -103,18 +103,6 @@ export function createAnnotationResolver({
|
||||
cacheWrite(cache, key, null);
|
||||
}
|
||||
|
||||
/** Wire an external AbortSignal to a local controller; returns a detach fn. */
|
||||
function linkAbort(controller, externalSignal) {
|
||||
if (!externalSignal) return () => {};
|
||||
if (externalSignal.aborted) {
|
||||
controller.abort();
|
||||
return () => {};
|
||||
}
|
||||
const onAbort = () => controller.abort();
|
||||
externalSignal.addEventListener('abort', onAbort, { once: true });
|
||||
return () => externalSignal.removeEventListener('abort', onAbort);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve a single annotation target to a normalized world anchor.
|
||||
*
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { readShellSource } from './testSupport/readShellSource.mjs';
|
||||
import { test } from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import { readFileSync } from 'node:fs';
|
||||
import {
|
||||
runCctvLayerEnableFocus,
|
||||
runCctvLayerEnableTransition,
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { readShellSource } from './testSupport/readShellSource.mjs';
|
||||
import test from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import { readFileSync } from 'node:fs';
|
||||
import {
|
||||
CCTV_WORLD_CLICK_FOCUS_DURATION_SEC,
|
||||
CCTV_FOCUS_REQUEST_EVENT,
|
||||
|
||||
@@ -21,8 +21,6 @@ const radioControlsSource = readRadioSource(new URL('./ui/radioControls.js', imp
|
||||
// - the right-rail entry ignored the activation result entirely.
|
||||
import { test } from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import { readFileSync } from 'node:fs';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
|
||||
const src = readShellSource();
|
||||
|
||||
|
||||
@@ -167,28 +167,6 @@ export function applyScope(records, scope, resolved) {
|
||||
return records;
|
||||
}
|
||||
|
||||
/** Numeric summary for the narration layer. */
|
||||
function summarize(items, sortField) {
|
||||
const summary = { count: items.length };
|
||||
if (sortField && items.length) {
|
||||
// A loop, not Math.min(...vals): a full FIRMS day is ~160k values, past
|
||||
// the engine's argument limit.
|
||||
let min = Infinity;
|
||||
let max = -Infinity;
|
||||
for (const item of items) {
|
||||
const value = Number(item[sortField]);
|
||||
if (!Number.isFinite(value)) continue;
|
||||
if (value < min) min = value;
|
||||
if (value > max) max = value;
|
||||
}
|
||||
if (Number.isFinite(min)) {
|
||||
summary[`${sortField}Min`] = min;
|
||||
summary[`${sortField}Max`] = max;
|
||||
}
|
||||
}
|
||||
return summary;
|
||||
}
|
||||
|
||||
const OPS_BY_TYPE = Object.freeze({
|
||||
number: ['gt', 'gte', 'lt', 'lte', 'eq', 'neq'],
|
||||
time: ['gt', 'gte', 'lt', 'lte', 'eq', 'neq'],
|
||||
|
||||
@@ -35,7 +35,6 @@ const BORDER_START_DELAY_MS = 700;
|
||||
const INCIDENT_CALLOUT_GAP_MS = 200;
|
||||
const CALLOUT_REVEAL_DURATION_MS = 1200;
|
||||
const CALLOUT_PULSE_DURATION_MS = 1800;
|
||||
const CALLOUT_DOT_SIZE_PX = 7;
|
||||
const CALLOUT_RING_MIN_SIZE_PX = 16;
|
||||
const CALLOUT_RING_SIZE_RANGE_PX = 14;
|
||||
const CITY_CALLOUT_START_DELAY_MS = 350;
|
||||
|
||||
@@ -2,7 +2,6 @@ import { readLayerSource } from '../testSupport/readLayerSource.mjs';
|
||||
import { dispatchCockpitModeChanged, enter, exit, _adoptTrackedEntity } from '../ui/cockpitTrackingController.js';
|
||||
import test from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import { readFileSync } from 'node:fs';
|
||||
import * as Cesium from 'cesium';
|
||||
import flightsLayer, {
|
||||
_setCockpitDetectionSubjectForTest as setFlightsCockpitSubject,
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { readLayerSource } from '../testSupport/readLayerSource.mjs';
|
||||
import test from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import { readFileSync } from 'node:fs';
|
||||
|
||||
/**
|
||||
* Cockpit 3D aircraft policy.
|
||||
|
||||
@@ -43,7 +43,6 @@ import {
|
||||
detectionHorizontalSector,
|
||||
labelBudgetFor,
|
||||
normalizeAllocationStrategy,
|
||||
normalizeProfile,
|
||||
profileForDensity,
|
||||
viewScaleForAltitude,
|
||||
} from './detectionPolicy.js';
|
||||
|
||||
@@ -157,26 +157,6 @@ function trackingIdOption(key, token, defaultValue = null) {
|
||||
});
|
||||
}
|
||||
|
||||
function stringOption(key, token, defaultValue) {
|
||||
return Object.freeze({
|
||||
key,
|
||||
token,
|
||||
defaultValue,
|
||||
normalize: (value) => {
|
||||
if (typeof value === 'number' && Number.isFinite(value))
|
||||
return String(value).trim().toLowerCase();
|
||||
if (typeof value !== 'string') return null;
|
||||
const normalized = value.trim().toLowerCase();
|
||||
return normalized ? normalized : null;
|
||||
},
|
||||
encode: (value) => String(value),
|
||||
decode: (value) =>
|
||||
typeof value === 'string' && value.trim()
|
||||
? value.trim().toLowerCase()
|
||||
: null,
|
||||
});
|
||||
}
|
||||
|
||||
function enumOption(
|
||||
key,
|
||||
token,
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { readLayerSource } from '../testSupport/readLayerSource.mjs';
|
||||
import { test } from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import fs from 'node:fs';
|
||||
import * as Cesium from 'cesium';
|
||||
import militaryAwarenessLayer, {
|
||||
_getAwarenessNavigationStateForTest,
|
||||
|
||||
@@ -798,7 +798,6 @@ test('zoom-out aborts an active installation request and returns non-loading gui
|
||||
// by source probes against the shipped file, the same technique the HUD datum
|
||||
// tests use where a full boot is impractical.
|
||||
import { installationRetryDelayMs } from './militaryInstallations.js';
|
||||
import fs from 'node:fs';
|
||||
|
||||
const installationsSource = readLayerSource(
|
||||
new URL('./militaryInstallations.js', import.meta.url), 'utf8');
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { readLayerSource } from '../testSupport/readLayerSource.mjs';
|
||||
import test from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import { readFileSync } from 'node:fs';
|
||||
import {
|
||||
bindTrackingClickGesture,
|
||||
isTrackingClickGesture,
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { readStylesheet } from './testSupport/readStylesheet.mjs';
|
||||
import test from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import { readFileSync } from 'node:fs';
|
||||
|
||||
const css = readStylesheet(new URL('../style.css', import.meta.url));
|
||||
|
||||
|
||||
@@ -3,16 +3,12 @@ import * as Cesium from 'cesium';
|
||||
import {
|
||||
LAYER_ID,
|
||||
REQUEST_DEBOUNCE_MS,
|
||||
QUERY_LIMIT,
|
||||
MAX_RENDERED,
|
||||
QUERY_SNAP_DEGREES,
|
||||
QUERY_REUSE_MS,
|
||||
ALPR_COLOR,
|
||||
} from './policy.js';
|
||||
import {
|
||||
snapAlprBox,
|
||||
boxContains,
|
||||
destinationPointDeg,
|
||||
alprRetryDelayMs,
|
||||
validateAlprSnapshot,
|
||||
alprCreditMarkup,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { CAMERA_SEEDS, SOURCE_ENDPOINT } from './policy.js';
|
||||
import { CAMERA_SEEDS } from './policy.js';
|
||||
import {
|
||||
lookupModelSpec,
|
||||
horizontalFovRangeDeg,
|
||||
|
||||
@@ -5,9 +5,6 @@ import {
|
||||
PROJECTION_CANVAS_HEIGHT,
|
||||
PROJECTION_MATTE_COLOR,
|
||||
PROJECTION_TEXTURE_SWAP_MS,
|
||||
ACTIVE_FRAME_REFRESH_MS,
|
||||
FRAME_ENDPOINT,
|
||||
MEDIA_ENDPOINT,
|
||||
PROJECTION_ACTIVE_REFRESH_MS,
|
||||
PROJECTION_IDLE_REFRESH_MS,
|
||||
PLACEHOLDER_REPAINT_MS,
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import * as Cesium from 'cesium';
|
||||
import { createFrustumVolumePrimitive } from '../../data/cctvViewshed.js';
|
||||
import {
|
||||
PROJECTION_VERT_ASPECT,
|
||||
FRUSTUM_GROUND_CLEARANCE_M,
|
||||
PROBE_MIN_RANGE_M,
|
||||
PROBE_CLEARANCE_M,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { HEALTH_SYNC_INTERVAL_MS, HEALTH_ENDPOINT } from './policy.js';
|
||||
import { HEALTH_SYNC_INTERVAL_MS } from './policy.js';
|
||||
|
||||
export function createHealth({ state: layerState, services, parts, source }) {
|
||||
/**
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { normalizeRoadMode } from './roadModes.js';
|
||||
import * as Cesium from 'cesium';
|
||||
import { FLOW_BUCKET_COLORS, TRAFFIC_TIMING_ENABLED } from './policy.js';
|
||||
import { FLOW_BUCKET_COLORS } from './policy.js';
|
||||
|
||||
export function createState({ services }) {
|
||||
const layerState = {};
|
||||
|
||||
@@ -9,7 +9,6 @@ import {
|
||||
FEED_STALE_AFTER_MS,
|
||||
MAX_VEHICLES_TOTAL,
|
||||
MISSED_POLLS_TO_DROP,
|
||||
TRANSIT_POLL_MS,
|
||||
isStaleVehicleFix,
|
||||
transitVehicleKey,
|
||||
vehicleReportTimeMs,
|
||||
|
||||
@@ -6,7 +6,6 @@ import {
|
||||
FEED_EVICT_AFTER_MS,
|
||||
FEED_STALE_AFTER_MS,
|
||||
MISSED_POLLS_TO_DROP,
|
||||
SELECTED_CARD_REFRESH_MS,
|
||||
TRANSIT_POLL_MS,
|
||||
VEHICLE_MAX_FIX_AGE_MS,
|
||||
} from './policy.js';
|
||||
|
||||
@@ -9,7 +9,7 @@ import {
|
||||
displacementPlausible,
|
||||
} from './movement.js';
|
||||
import { buildTransitSelectionCopy } from './policy.js';
|
||||
import { seek, sampleAt } from '../../data/contactPlayback.js';
|
||||
import { sampleAt } from '../../data/contactPlayback.js';
|
||||
const entry = () => {
|
||||
const e = { mode: 'bus', modeInferred: false, courseDeg: null };
|
||||
initializePlayback(e);
|
||||
|
||||
@@ -22,7 +22,6 @@ import {
|
||||
import {
|
||||
MARKER_PIXEL_SIZE,
|
||||
ROTATION_REFRESH_MS,
|
||||
SELECTED_CARD_REFRESH_MS,
|
||||
VISIBILITY_REFRESH_MS,
|
||||
SELECTED_PIXEL_SIZE,
|
||||
TRANSIT_MODE_COLORS,
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
import {
|
||||
keySetupRequirement,
|
||||
keySetupRequirementEnvVars,
|
||||
} from '../keySetupCore.mjs';
|
||||
import { keySetupRequirementEnvVars } from '../keySetupCore.mjs';
|
||||
import { t } from '../i18n/index.js';
|
||||
/**
|
||||
* Why Google 3D is unavailable, phrased so the tooltip and toast recommend the
|
||||
|
||||
@@ -6,7 +6,6 @@ const radioPresentation = readRadioSource(new URL('./ui/radioPresentation.js', i
|
||||
const radioControlsSource = readRadioSource(new URL('./ui/radioControls.js', import.meta.url), 'utf8');
|
||||
import { bindPanelDisclosure, collapsePanelOnEscape } from './ui/panelDisclosure.js';
|
||||
import assert from 'node:assert/strict';
|
||||
import fs from 'node:fs';
|
||||
import test from 'node:test';
|
||||
|
||||
const source = readShellSource();
|
||||
|
||||
@@ -12,7 +12,6 @@ import { readShellSource } from '../testSupport/readShellSource.mjs';
|
||||
// cancellable — an AbortSignal for the data manager, a liveness predicate for
|
||||
// the visual commit. Several of these assert exactly that plumbing.
|
||||
import assert from 'node:assert/strict';
|
||||
import fs from 'node:fs';
|
||||
import test from 'node:test';
|
||||
|
||||
import { SceneDirector } from './director.js';
|
||||
|
||||
@@ -7,7 +7,6 @@ import { _claimContextVisualAuthority, setContextMode } from './ui/contextAction
|
||||
import { _initGlobalContextPanel } from './ui/contextBindings.js';
|
||||
import { test } from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import fs from 'node:fs';
|
||||
import { ShareLinkManager, decodeShareCreatedAtMs } from './sharelink.js';
|
||||
import { createDefaultLayerState } from './data/layerState.js';
|
||||
|
||||
|
||||
@@ -10,7 +10,6 @@ import {
|
||||
MILITARY_DETECTION_PRESET,
|
||||
} from './effects.js';
|
||||
import { createStyleParameters } from './visualInput.js';
|
||||
import * as Cesium from 'cesium';
|
||||
import {
|
||||
BLOOM_SCALE_VERSION,
|
||||
clampBloomIntensity,
|
||||
|
||||
@@ -4369,46 +4369,6 @@ function dominantValue(values) {
|
||||
};
|
||||
}
|
||||
|
||||
function summarizeEntity(viewer, entity, { includeProperties = false } = {}) {
|
||||
const now = Cesium.JulianDate.now();
|
||||
if (entity.__gevContextId) {
|
||||
const store = window.__gevContextStore;
|
||||
const record = store?.entities?.get(entity.__gevContextId);
|
||||
if (record) return summarizeContextRecord(record, { includeProperties });
|
||||
}
|
||||
const props = propertyObject(entity);
|
||||
const layerId = entity.__localLayerId || props.layerId || null;
|
||||
const tags = props.tags || {};
|
||||
const label = cleanText(
|
||||
props.name ||
|
||||
tags.name ||
|
||||
tags['name:en'] ||
|
||||
tags.official_name ||
|
||||
tags.operator ||
|
||||
props.operator ||
|
||||
entity.name ||
|
||||
layerTitle(layerId),
|
||||
);
|
||||
const position =
|
||||
entity.__localBaseCartesian ||
|
||||
entity.position?.getValue?.(now) ||
|
||||
polygonCenter(entity, now);
|
||||
const carto = position ? Cesium.Cartographic.fromCartesian(position) : null;
|
||||
return {
|
||||
id: String(entity.id || ''),
|
||||
name: label || layerTitle(layerId),
|
||||
layerId,
|
||||
layerName: layerTitle(layerId),
|
||||
latitude: carto
|
||||
? Number(Cesium.Math.toDegrees(carto.latitude).toFixed(6))
|
||||
: null,
|
||||
longitude: carto
|
||||
? Number(Cesium.Math.toDegrees(carto.longitude).toFixed(6))
|
||||
: null,
|
||||
properties: includeProperties ? compactProperties(props) : undefined,
|
||||
};
|
||||
}
|
||||
|
||||
function summarizeContextRecord(record, { includeProperties = false } = {}) {
|
||||
return {
|
||||
id: String(record.id || ''),
|
||||
@@ -4427,31 +4387,6 @@ function summarizeContextRecord(record, { includeProperties = false } = {}) {
|
||||
};
|
||||
}
|
||||
|
||||
function polygonCenter(entity, now) {
|
||||
const hierarchy = entity.polygon?.hierarchy?.getValue?.(now);
|
||||
const positions = hierarchy?.positions;
|
||||
if (!positions?.length) return null;
|
||||
return Cesium.BoundingSphere.fromPoints(positions).center;
|
||||
}
|
||||
|
||||
function propertyObject(entity) {
|
||||
const raw = entity?.properties?.getValue?.(Cesium.JulianDate.now()) || {};
|
||||
return unwrapProperties(raw);
|
||||
}
|
||||
|
||||
function unwrapProperties(value) {
|
||||
if (!value || typeof value !== 'object') return value;
|
||||
if (Array.isArray(value)) return value.map(unwrapProperties);
|
||||
const out = {};
|
||||
for (const [key, entry] of Object.entries(value)) {
|
||||
out[key] =
|
||||
entry && typeof entry.getValue === 'function'
|
||||
? unwrapProperties(entry.getValue(Cesium.JulianDate.now()))
|
||||
: unwrapProperties(entry);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
function compactProperties(props) {
|
||||
const preferredKeys = [
|
||||
'name',
|
||||
|
||||
@@ -34,13 +34,11 @@
|
||||
* Dependencies: sharp (devDependency)
|
||||
*/
|
||||
|
||||
import { readFileSync, mkdirSync, writeFileSync } from 'node:fs';
|
||||
import { mkdirSync } from 'node:fs';
|
||||
import { resolve, join, basename, extname } from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import { projectRoot } from '../scripts/project-root.mjs';
|
||||
import sharp from 'sharp';
|
||||
|
||||
const __dirname = fileURLToPath(new URL('.', import.meta.url));
|
||||
const PROJECT_ROOT = projectRoot(import.meta.url);
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
@@ -32,11 +32,9 @@
|
||||
|
||||
import { readFileSync, mkdirSync } from 'node:fs';
|
||||
import { resolve, join } from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import { projectRoot } from '../scripts/project-root.mjs';
|
||||
import sharp from 'sharp';
|
||||
|
||||
const __dirname = fileURLToPath(new URL('.', import.meta.url));
|
||||
const PROJECT_ROOT = projectRoot(import.meta.url);
|
||||
const TILE_SIZE = 256;
|
||||
const MAX_CONCURRENT = 8;
|
||||
|
||||
@@ -28,7 +28,6 @@ import { projectRoot } from '../scripts/project-root.mjs';
|
||||
import { parseEnv } from 'node:util';
|
||||
import { resolveGoogleServerKey } from '../scripts/google-server-key.mjs';
|
||||
|
||||
const __dirname = fileURLToPath(new URL('.', import.meta.url));
|
||||
const PROJECT_ROOT = projectRoot(import.meta.url);
|
||||
|
||||
function parseArgs() {
|
||||
|
||||
@@ -24,11 +24,9 @@
|
||||
|
||||
import { readFileSync, mkdirSync, writeFileSync } from 'node:fs';
|
||||
import { resolve, join } from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import { projectRoot } from '../scripts/project-root.mjs';
|
||||
import sharp from 'sharp';
|
||||
|
||||
const __dirname = fileURLToPath(new URL('.', import.meta.url));
|
||||
const PROJECT_ROOT = projectRoot(import.meta.url);
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
Reference in new issue
Block a user