diff --git a/web/npm_output.log b/web/npm_output.log new file mode 100644 index 0000000..d415828 --- /dev/null +++ b/web/npm_output.log @@ -0,0 +1,879 @@ + +> village-generator@0.1.0 dev +> vite --debug + +2025-08-04T22:11:07.247Z vite:config config file loaded in 36.34ms +2025-08-04T22:11:07.250Z vite:env loading env files: [ + '/app/web/.env', + '/app/web/.env.local', + '/app/web/.env.development', + '/app/web/.env.development.local' +] +2025-08-04T22:11:07.250Z vite:env env files loaded in 0.80ms +2025-08-04T22:11:07.251Z vite:env using resolved env: {} +2025-08-04T22:11:07.266Z vite:config using resolved config: { + plugins: [ + 'vite:optimized-deps', + 'vite:watch-package-data', + 'vite:pre-alias', + 'alias', + 'vite:react-babel', + 'vite:react-refresh', + 'vite:modulepreload-polyfill', + 'vite:resolve', + 'vite:html-inline-proxy', + 'vite:css', + 'vite:esbuild', + 'vite:json', + 'vite:wasm-helper', + 'vite:worker', + 'vite:asset', + 'vite:wasm-fallback', + 'vite:define', + 'vite:css-post', + 'vite:worker-import-meta-url', + 'vite:asset-import-meta-url', + 'vite:dynamic-import-vars', + 'vite:import-glob', + 'vite:client-inject', + 'vite:css-analysis', + 'vite:import-analysis' + ], + root: '/app/web', + build: { + target: [ 'chrome107', 'edge107', 'firefox104', 'safari16' ], + polyfillModulePreload: true, + modulePreload: { polyfill: true }, + outDir: 'dist', + assetsDir: 'assets', + assetsInlineLimit: 4096, + sourcemap: false, + terserOptions: {}, + rollupOptions: { onwarn: [Function: onwarn] }, + commonjsOptions: { include: [ /node_modules/ ], extensions: [ '.js', '.cjs' ] }, + dynamicImportVarsOptions: { warnOnError: true, exclude: [ /node_modules/ ] }, + write: true, + emptyOutDir: null, + copyPublicDir: true, + manifest: false, + lib: false, + ssrManifest: false, + ssrEmitAssets: false, + reportCompressedSize: true, + chunkSizeWarningLimit: 500, + watch: null, + cssCodeSplit: true, + minify: 'esbuild', + ssr: false, + emitAssets: false, + createEnvironment: [Function: createEnvironment], + cssTarget: [ 'chrome107', 'edge107', 'firefox104', 'safari16' ], + cssMinify: true + }, + server: { + port: 3000, + strictPort: false, + host: true, + allowedHosts: [], + https: undefined, + open: false, + proxy: undefined, + cors: { + origin: /^https?:\/\/(?:(?:[^:]+\.)?localhost|127\.0\.0\.1|\[::1\])(?::\d+)?$/ + }, + headers: {}, + warmup: { clientFiles: [], ssrFiles: [] }, + middlewareMode: false, + fs: { + strict: true, + deny: [ '.env', '.env.*', '*.{crt,pem}', '**/.git/**' ], + allow: [ '/app/web' ] + }, + preTransformRequests: true, + perEnvironmentStartEndDuringDev: false, + sourcemapIgnoreList: [Function: isInNodeModules] + }, + test: { globals: true, environment: 'jsdom' }, + resolve: { + externalConditions: [ 'node' ], + extensions: [ + '.mjs', '.js', + '.mts', '.ts', + '.jsx', '.tsx', + '.json' + ], + dedupe: [ 'react', 'react-dom' ], + noExternal: [], + external: [], + preserveSymlinks: false, + alias: [ + { find: '@', replacement: '/app/web/src' }, + { + find: /^\/?@vite\/env/, + replacement: '/@fs/app/web/node_modules/vite/dist/client/env.mjs' + }, + { + find: /^\/?@vite\/client/, + replacement: '/@fs/app/web/node_modules/vite/dist/client/client.mjs' + } + ], + mainFields: [ 'browser', 'module', 'jsnext:main', 'jsnext' ], + conditions: [ 'module', 'browser', 'development|production' ], + builtins: [] + }, + esbuild: { jsxDev: true, jsx: 'automatic', jsxImportSource: undefined }, + optimizeDeps: { + include: [ + 'react', + 'react-dom', + 'react/jsx-dev-runtime', + 'react/jsx-runtime' + ], + exclude: [], + needsInterop: [], + extensions: [], + disabled: undefined, + holdUntilCrawlEnd: true, + force: false, + noDiscovery: false, + esbuildOptions: { preserveSymlinks: false, jsx: 'automatic' } + }, + environments: { + client: { + define: undefined, + resolve: { + externalConditions: [ 'node' ], + extensions: [ + '.mjs', '.js', + '.mts', '.ts', + '.jsx', '.tsx', + '.json' + ], + dedupe: [ 'react', 'react-dom' ], + noExternal: [], + external: [], + preserveSymlinks: false, + alias: [ + { find: '@', replacement: '/app/web/src' }, + { + find: /^\/?@vite\/env/, + replacement: '/@fs/app/web/node_modules/vite/dist/client/env.mjs' + }, + { + find: /^\/?@vite\/client/, + replacement: '/@fs/app/web/node_modules/vite/dist/client/client.mjs' + } + ], + mainFields: [ 'browser', 'module', 'jsnext:main', 'jsnext' ], + conditions: [ 'module', 'browser', 'development|production' ], + builtins: [] + }, + keepProcessEnv: false, + consumer: 'client', + optimizeDeps: { + include: [ + 'react', + 'react-dom', + 'react/jsx-dev-runtime', + 'react/jsx-runtime' + ], + exclude: [], + needsInterop: [], + extensions: [], + disabled: undefined, + holdUntilCrawlEnd: true, + force: false, + noDiscovery: false, + esbuildOptions: { preserveSymlinks: false, jsx: 'automatic' } + }, + dev: { + warmup: [], + sourcemap: { js: true }, + sourcemapIgnoreList: [Function: isInNodeModules], + preTransformRequests: true, + createEnvironment: [Function: defaultCreateClientDevEnvironment], + recoverable: true, + moduleRunnerTransform: false + }, + build: { + target: [ 'chrome107', 'edge107', 'firefox104', 'safari16' ], + polyfillModulePreload: true, + modulePreload: { polyfill: true }, + outDir: 'dist', + assetsDir: 'assets', + assetsInlineLimit: 4096, + sourcemap: false, + terserOptions: {}, + rollupOptions: { onwarn: [Function: onwarn] }, + commonjsOptions: { include: [ /node_modules/ ], extensions: [ '.js', '.cjs' ] }, + dynamicImportVarsOptions: { warnOnError: true, exclude: [ /node_modules/ ] }, + write: true, + emptyOutDir: null, + copyPublicDir: true, + manifest: false, + lib: false, + ssrManifest: false, + ssrEmitAssets: false, + reportCompressedSize: true, + chunkSizeWarningLimit: 500, + watch: null, + cssCodeSplit: true, + minify: 'esbuild', + ssr: false, + emitAssets: true, + createEnvironment: [Function: createEnvironment], + cssTarget: [ 'chrome107', 'edge107', 'firefox104', 'safari16' ], + cssMinify: true + }, + plugins: [ + { + name: 'vite:optimized-deps', + applyToEnvironment: [Function: applyToEnvironment], + resolveId: [Function: resolveId], + load: [AsyncFunction: load] + }, + { + name: 'vite:watch-package-data', + buildStart: [Function: buildStart], + buildEnd: [Function: buildEnd], + watchChange: [Function: watchChange] + }, + { + name: 'vite:pre-alias', + applyToEnvironment: [Function: applyToEnvironment], + resolveId: [AsyncFunction: resolveId] + }, + { + name: 'alias', + buildStart: [AsyncFunction: buildStart], + resolveId: [Function: resolveId] + }, + { + name: 'vite:react-babel', + enforce: 'pre', + config: [Function: config], + configResolved: [Function: configResolved], + options: [Function: options], + transform: { + filter: { + id: { + include: /\.[tj]sx?(?:\?.*)?$/, + exclude: [ /\/node_modules\// ] + } + }, + handler: [AsyncFunction: handler] + } + }, + { + name: 'vite:react-refresh', + enforce: 'pre', + config: [Function: config], + resolveId: { + filter: { id: /^\/@react\-refresh$/ }, + handler: [Function: handler] + }, + load: { + filter: { id: /^\/@react\-refresh$/ }, + handler: [Function: handler] + }, + transformIndexHtml: [Function: transformIndexHtml] + }, + { + name: 'vite:modulepreload-polyfill', + resolveId: { handler: [Function: handler] }, + load: { handler: [Function: handler] } + }, + { + name: 'vite:resolve', + resolveId: [AsyncFunction: resolveId], + load: { handler: [Function: handler] } + }, + { + name: 'vite:html-inline-proxy', + resolveId: { handler: [Function: handler] }, + load: { handler: [Function: handler] } + }, + { + name: 'vite:css', + buildStart: [Function: buildStart], + buildEnd: [Function: buildEnd], + load: { handler: [AsyncFunction: handler] }, + transform: { handler: [AsyncFunction: handler] } + }, + { + name: 'vite:esbuild', + configureServer: [Function: configureServer], + transform: [AsyncFunction: transform] + }, + { + name: 'vite:json', + transform: { handler: [Function: handler] } + }, + { + name: 'vite:wasm-helper', + resolveId: { handler: [Function: handler] }, + load: { handler: [AsyncFunction: handler] } + }, + { + name: 'vite:worker', + buildStart: [Function: buildStart], + load: { handler: [AsyncFunction: handler] }, + shouldTransformCachedModule: [Function: shouldTransformCachedModule], + transform: { handler: [AsyncFunction: handler] }, + renderChunk: [Function: renderChunk], + generateBundle: [Function: generateBundle] + }, + { + name: 'vite:asset', + perEnvironmentStartEndDuringDev: true, + buildStart: [Function: buildStart], + resolveId: { handler: [Function: handler] }, + load: { handler: [AsyncFunction: handler] }, + renderChunk: [Function: renderChunk], + generateBundle: [Function: generateBundle] + }, + { + name: 'vite:wasm-fallback', + load: { handler: [Function: handler] } + }, + { + name: 'vite:define', + transform: { handler: [AsyncFunction: handler] } + }, + { + name: 'vite:css-post', + renderStart: [Function: renderStart], + transform: { handler: [AsyncFunction: handler] }, + renderChunk: [AsyncFunction: renderChunk], + augmentChunkHash: [Function: augmentChunkHash], + generateBundle: [AsyncFunction: generateBundle] + }, + { + name: 'vite:worker-import-meta-url', + applyToEnvironment: [Function: applyToEnvironment], + shouldTransformCachedModule: [Function: shouldTransformCachedModule], + transform: { handler: [AsyncFunction: handler] } + }, + { + name: 'vite:asset-import-meta-url', + applyToEnvironment: [Function: applyToEnvironment], + transform: { handler: [AsyncFunction: handler] } + }, + { + name: 'vite:dynamic-import-vars', + resolveId: { handler: [Function: handler] }, + load: { handler: [Function: handler] }, + transform: { handler: [AsyncFunction: handler] } + }, + { + name: 'vite:import-glob', + buildStart: [Function: buildStart], + transform: { handler: [AsyncFunction: handler] }, + hotUpdate: [Function: hotUpdate] + }, + { + name: 'vite:client-inject', + buildStart: [AsyncFunction: buildStart], + transform: [AsyncFunction: transform] + }, + { + name: 'vite:css-analysis', + transform: { handler: [AsyncFunction: handler] } + }, + { + name: 'vite:import-analysis', + transform: [AsyncFunction: transform] + } + ] + }, + ssr: { + define: undefined, + resolve: { + externalConditions: [ 'node' ], + extensions: [ + '.mjs', '.js', + '.mts', '.ts', + '.jsx', '.tsx', + '.json' + ], + dedupe: [ 'react', 'react-dom' ], + noExternal: [], + external: [], + preserveSymlinks: false, + alias: [ + { find: '@', replacement: '/app/web/src' }, + { + find: /^\/?@vite\/env/, + replacement: '/@fs/app/web/node_modules/vite/dist/client/env.mjs' + }, + { + find: /^\/?@vite\/client/, + replacement: '/@fs/app/web/node_modules/vite/dist/client/client.mjs' + } + ], + mainFields: [ 'module', 'jsnext:main', 'jsnext' ], + conditions: [ 'module', 'node', 'development|production' ], + builtins: [ + '_http_agent', '_http_client', '_http_common', + '_http_incoming', '_http_outgoing', '_http_server', + '_stream_duplex', '_stream_passthrough', '_stream_readable', + '_stream_transform', '_stream_wrap', '_stream_writable', + '_tls_common', '_tls_wrap', 'assert', + 'assert/strict', 'async_hooks', 'buffer', + 'child_process', 'cluster', 'console', + 'constants', 'crypto', 'dgram', + 'diagnostics_channel', 'dns', 'dns/promises', + 'domain', 'events', 'fs', + 'fs/promises', 'http', 'http2', + 'https', 'inspector', 'inspector/promises', + 'module', 'net', 'os', + 'path', 'path/posix', 'path/win32', + 'perf_hooks', 'process', 'punycode', + 'querystring', 'readline', 'readline/promises', + 'repl', 'stream', 'stream/consumers', + 'stream/promises', 'stream/web', 'string_decoder', + 'sys', 'timers', 'timers/promises', + 'tls', 'trace_events', 'tty', + 'url', 'util', 'util/types', + 'v8', 'vm', 'wasi', + 'worker_threads', 'zlib', /^node:/, + /^npm:/, /^bun:/ + ] + }, + keepProcessEnv: true, + consumer: 'server', + optimizeDeps: { + include: [], + exclude: [], + needsInterop: [], + extensions: [], + disabled: undefined, + holdUntilCrawlEnd: true, + force: false, + noDiscovery: true, + esbuildOptions: { preserveSymlinks: false } + }, + dev: { + warmup: [], + sourcemap: { js: true }, + sourcemapIgnoreList: [Function: isInNodeModules], + preTransformRequests: false, + createEnvironment: [Function: defaultCreateDevEnvironment], + recoverable: false, + moduleRunnerTransform: true + }, + build: { + target: [ 'chrome107', 'edge107', 'firefox104', 'safari16' ], + polyfillModulePreload: true, + modulePreload: { polyfill: true }, + outDir: 'dist', + assetsDir: 'assets', + assetsInlineLimit: 4096, + sourcemap: false, + terserOptions: {}, + rollupOptions: { onwarn: [Function: onwarn] }, + commonjsOptions: { include: [ /node_modules/ ], extensions: [ '.js', '.cjs' ] }, + dynamicImportVarsOptions: { warnOnError: true, exclude: [ /node_modules/ ] }, + write: true, + emptyOutDir: null, + copyPublicDir: true, + manifest: false, + lib: false, + ssrManifest: false, + ssrEmitAssets: false, + reportCompressedSize: true, + chunkSizeWarningLimit: 500, + watch: null, + cssCodeSplit: true, + minify: false, + ssr: true, + emitAssets: false, + createEnvironment: [Function: createEnvironment], + cssTarget: [ 'chrome107', 'edge107', 'firefox104', 'safari16' ], + cssMinify: 'esbuild' + }, + plugins: [ + { + name: 'vite:watch-package-data', + buildStart: [Function: buildStart], + buildEnd: [Function: buildEnd], + watchChange: [Function: watchChange] + }, + { + name: 'alias', + buildStart: [AsyncFunction: buildStart], + resolveId: [Function: resolveId] + }, + { + name: 'vite:react-babel', + enforce: 'pre', + config: [Function: config], + configResolved: [Function: configResolved], + options: [Function: options], + transform: { + filter: { + id: { + include: /\.[tj]sx?(?:\?.*)?$/, + exclude: [ /\/node_modules\// ] + } + }, + handler: [AsyncFunction: handler] + } + }, + { + name: 'vite:react-refresh', + enforce: 'pre', + config: [Function: config], + resolveId: { + filter: { id: /^\/@react\-refresh$/ }, + handler: [Function: handler] + }, + load: { + filter: { id: /^\/@react\-refresh$/ }, + handler: [Function: handler] + }, + transformIndexHtml: [Function: transformIndexHtml] + }, + { + name: 'vite:modulepreload-polyfill', + resolveId: { handler: [Function: handler] }, + load: { handler: [Function: handler] } + }, + { + name: 'vite:resolve', + resolveId: [AsyncFunction: resolveId], + load: { handler: [Function: handler] } + }, + { + name: 'vite:html-inline-proxy', + resolveId: { handler: [Function: handler] }, + load: { handler: [Function: handler] } + }, + { + name: 'vite:css', + buildStart: [Function: buildStart], + buildEnd: [Function: buildEnd], + load: { handler: [AsyncFunction: handler] }, + transform: { handler: [AsyncFunction: handler] } + }, + { + name: 'vite:esbuild', + configureServer: [Function: configureServer], + transform: [AsyncFunction: transform] + }, + { + name: 'vite:json', + transform: { handler: [Function: handler] } + }, + { + name: 'vite:wasm-helper', + resolveId: { handler: [Function: handler] }, + load: { handler: [AsyncFunction: handler] } + }, + { + name: 'vite:worker', + buildStart: [Function: buildStart], + load: { handler: [AsyncFunction: handler] }, + shouldTransformCachedModule: [Function: shouldTransformCachedModule], + transform: { handler: [AsyncFunction: handler] }, + renderChunk: [Function: renderChunk], + generateBundle: [Function: generateBundle] + }, + { + name: 'vite:asset', + perEnvironmentStartEndDuringDev: true, + buildStart: [Function: buildStart], + resolveId: { handler: [Function: handler] }, + load: { handler: [AsyncFunction: handler] }, + renderChunk: [Function: renderChunk], + generateBundle: [Function: generateBundle] + }, + { + name: 'vite:wasm-fallback', + load: { handler: [Function: handler] } + }, + { + name: 'vite:define', + transform: { handler: [AsyncFunction: handler] } + }, + { + name: 'vite:css-post', + renderStart: [Function: renderStart], + transform: { handler: [AsyncFunction: handler] }, + renderChunk: [AsyncFunction: renderChunk], + augmentChunkHash: [Function: augmentChunkHash], + generateBundle: [AsyncFunction: generateBundle] + }, + { + name: 'vite:dynamic-import-vars', + resolveId: { handler: [Function: handler] }, + load: { handler: [Function: handler] }, + transform: { handler: [AsyncFunction: handler] } + }, + { + name: 'vite:import-glob', + buildStart: [Function: buildStart], + transform: { handler: [AsyncFunction: handler] }, + hotUpdate: [Function: hotUpdate] + }, + { + name: 'vite:client-inject', + buildStart: [AsyncFunction: buildStart], + transform: [AsyncFunction: transform] + }, + { + name: 'vite:css-analysis', + transform: { handler: [AsyncFunction: handler] } + }, + { + name: 'vite:import-analysis', + transform: [AsyncFunction: transform] + } + ] + } + }, + configFile: '/app/web/vite.config.ts', + configFileDependencies: [ '/app/web/vite.config.ts' ], + inlineConfig: { + root: undefined, + base: undefined, + mode: undefined, + configFile: undefined, + configLoader: undefined, + logLevel: undefined, + clearScreen: undefined, + server: { host: undefined }, + forceOptimizeDeps: undefined + }, + base: '/', + decodedBase: '/', + rawBase: '/', + publicDir: '/app/web/public', + cacheDir: '/app/web/node_modules/.vite', + command: 'serve', + mode: 'development', + isWorker: false, + mainConfig: null, + bundleChain: [], + isProduction: false, + css: { + transformer: 'postcss', + preprocessorMaxWorkers: true, + devSourcemap: false + }, + json: { namedExports: true, stringify: 'auto' }, + builder: undefined, + preview: { + port: 4173, + strictPort: false, + host: true, + allowedHosts: [], + https: undefined, + open: false, + proxy: undefined, + cors: { + origin: /^https?:\/\/(?:(?:[^:]+\.)?localhost|127\.0\.0\.1|\[::1\])(?::\d+)?$/ + }, + headers: {} + }, + envDir: '/app/web', + env: { BASE_URL: '/', MODE: 'development', DEV: true, PROD: false }, + assetsInclude: [Function: assetsInclude], + logger: { + hasWarned: false, + info: [Function: info], + warn: [Function: warn], + warnOnce: [Function: warnOnce], + error: [Function: error], + clearScreen: [Function: clearScreen], + hasErrorLogged: [Function: hasErrorLogged] + }, + packageCache: Map(1) { + 'fnpd_/app/web' => { + dir: '/app/web', + data: { + name: 'village-generator', + version: '0.1.0', + private: true, + type: 'module', + scripts: { + start: `tsc --watch && copy index.html dist\\index.html && (echo SET "s|./dist/index.js|./index.js|" & SET "file=dist\\index.html" & powershell -Command "(Get-Content $env:file) -replace $env:s, '' | Set-Content $env:file")`, + build: `tsc && copy index.html dist\\index.html && (echo SET "s|./dist/index.js|./index.js|" & SET "file=dist\\index.html" & powershell -Command "(Get-Content $env:file) -replace $env:s, '' | Set-Content $env:file")`, + dev: 'vite --debug', + serve: 'http-server dist -p 8000', + test: 'vitest' + }, + dependencies: { + '@kobandavis/wfc': '^1.1.0', + '@rollup/rollup-linux-x64-gnu': '^4.46.2', + 'd3-delaunay': '^6.0.4', + react: '^18.2.0', + 'react-dom': '^18.2.0' + }, + devDependencies: { + '@testing-library/react': '^16.3.0', + '@types/d3-delaunay': '^6.0.4', + '@types/react': '^19.1.9', + '@types/react-dom': '^19.1.7', + '@vitejs/plugin-react': '^4.7.0', + 'http-server': '^14.1.1', + jsdom: '^26.1.0', + typescript: '^5.4.0', + vite: '^7.0.6', + vitest: '^3.2.4' + } + }, + hasSideEffects: [Function: hasSideEffects], + setResolvedCache: [Function: setResolvedCache], + getResolvedCache: [Function: getResolvedCache] + }, + set: [Function (anonymous)] + }, + worker: { format: 'iife', plugins: '() => plugins', rollupOptions: {} }, + appType: 'spa', + experimental: { + importGlobRestoreExtension: false, + renderBuiltUrl: undefined, + hmrPartialAccept: false + }, + future: undefined, + ssr: { + target: 'node', + optimizeDeps: { + esbuildOptions: { preserveSymlinks: false }, + include: [], + exclude: [], + needsInterop: [], + extensions: [], + holdUntilCrawlEnd: true, + force: false, + noDiscovery: true + }, + external: [], + noExternal: [], + resolve: { + conditions: [ 'module', 'node', 'development|production' ], + externalConditions: [ 'node' ] + } + }, + dev: { + warmup: [], + sourcemap: { js: true }, + sourcemapIgnoreList: [Function: isInNodeModules], + preTransformRequests: false, + createEnvironment: [Function: defaultCreateDevEnvironment], + recoverable: false, + moduleRunnerTransform: false + }, + webSocketToken: 'W9oBlQ9adqg0', + getSortedPlugins: [Function: getSortedPlugins], + getSortedPluginHooks: [Function: getSortedPluginHooks], + createResolver: [Function: createResolver], + fsDenyGlob: [Function: arrayMatcher], + safeModulePaths: Set(0) {}, + [Symbol(vite:resolved-config)]: true +} +2025-08-04T22:11:07.284Z vite:deps (client) removing old cache dir /app/web/node_modules/.vite/deps +2025-08-04T22:11:07.291Z vite:resolve 1.91ms react -> /app/web/node_modules/react/index.js +2025-08-04T22:11:07.292Z vite:resolve 0.73ms react-dom -> /app/web/node_modules/react-dom/index.js +2025-08-04T22:11:07.293Z vite:resolve 0.38ms react/jsx-dev-runtime -> /app/web/node_modules/react/jsx-dev-runtime.js +2025-08-04T22:11:07.293Z vite:resolve 0.23ms react/jsx-runtime -> /app/web/node_modules/react/jsx-runtime.js +2025-08-04T22:11:07.295Z vite:deps scanning for dependencies... + + VITE v7.0.6 ready in 257 ms + + ➜ Local: http://localhost:3000/ + ➜ Network: http://192.168.0.2:3000/ +2025-08-04T22:11:07.321Z vite:deps Crawling dependencies using entries: + /app/web/index.html +2025-08-04T22:11:07.327Z vite:hmr [file change] npm_output.log +2025-08-04T22:11:07.328Z vite:hmr (client) [no modules matched] npm_output.log +2025-08-04T22:11:07.328Z vite:hmr (ssr) [no modules matched] npm_output.log +2025-08-04T22:11:07.348Z vite:deps ✨ static imports crawl ended +2025-08-04T22:11:07.360Z vite:resolve 0.22ms /src/index.tsx -> /app/web/src/index.tsx +2025-08-04T22:11:07.364Z vite:resolve 0.80ms react -> /app/web/node_modules/react/index.js +2025-08-04T22:11:07.365Z vite:resolve 0.45ms react-dom/client -> /app/web/node_modules/react-dom/client.js +2025-08-04T22:11:07.366Z vite:resolve 0.19ms ./components/TownScene -> /app/web/src/components/TownScene.tsx +2025-08-04T22:11:07.367Z vite:resolve 0.16ms ./services/StateManager -> /app/web/src/services/StateManager.ts +2025-08-04T22:11:07.368Z vite:resolve 0.16ms ./services/Model -> /app/web/src/services/Model.ts +2025-08-04T22:11:07.369Z vite:resolve 0.27ms react/jsx-runtime -> /app/web/node_modules/react/jsx-runtime.js +2025-08-04T22:11:07.374Z vite:resolve 0.53ms ../utils/Random -> /app/web/src/utils/Random.ts +2025-08-04T22:11:07.375Z vite:resolve 0.20ms ../services/CityMap -> /app/web/src/services/CityMap.tsx +2025-08-04T22:11:07.376Z vite:resolve 0.80ms ../services/Model -> /app/web/src/services/Model.ts +2025-08-04T22:11:07.376Z vite:resolve 0.62ms /app/web/src/types/patch -> /app/web/src/types/patch.ts +2025-08-04T22:11:07.376Z vite:resolve 1.08ms @/types/patch -> /app/web/src/types/patch.ts +2025-08-04T22:11:07.377Z vite:resolve 0.24ms ./Tooltip -> /app/web/src/components/Tooltip.tsx +2025-08-04T22:11:07.377Z vite:resolve 0.36ms /app/web/src/types/polygon -> /app/web/src/types/polygon.ts +2025-08-04T22:11:07.377Z vite:resolve 0.48ms @/types/polygon -> /app/web/src/types/polygon.ts +2025-08-04T22:11:07.379Z vite:resolve 0.22ms ./CitySizeButton -> /app/web/src/components/CitySizeButton.tsx +2025-08-04T22:11:07.379Z vite:resolve 0.37ms /app/web/src/types/street -> /app/web/src/types/street.ts +2025-08-04T22:11:07.379Z vite:resolve 0.49ms @/types/street -> /app/web/src/types/street.ts +2025-08-04T22:11:07.380Z vite:resolve 0.27ms ./Ward -> /app/web/src/services/Ward.ts +2025-08-04T22:11:07.381Z vite:resolve 0.16ms ./CurtainWall -> /app/web/src/services/CurtainWall.ts +2025-08-04T22:11:07.382Z vite:hmr [file change] npm_output.log +2025-08-04T22:11:07.382Z vite:hmr (client) [no modules matched] npm_output.log +2025-08-04T22:11:07.382Z vite:hmr (ssr) [no modules matched] npm_output.log +2025-08-04T22:11:07.383Z vite:resolve 0.08ms /app/web/src/utils/Random -> /app/web/src/utils/Random.ts +2025-08-04T22:11:07.383Z vite:resolve 0.20ms @/utils/Random -> /app/web/src/utils/Random.ts +2025-08-04T22:11:07.384Z vite:resolve 0.14ms ./voronoi -> /app/web/src/services/voronoi.ts +2025-08-04T22:11:07.385Z vite:resolve 0.10ms /app/web/src/types/point -> /app/web/src/types/point.ts +2025-08-04T22:11:07.385Z vite:resolve 0.22ms @/types/point -> /app/web/src/types/point.ts +2025-08-04T22:11:07.389Z vite:resolve 1.52ms ./Topology -> /app/web/src/services/Topology.ts +2025-08-04T22:11:07.389Z vite:resolve 1.56ms ./Button -> /app/web/src/components/Button.tsx +2025-08-04T22:11:07.390Z vite:resolve 0.30ms /app/web/src/types/palette -> /app/web/src/types/palette.ts +2025-08-04T22:11:07.390Z vite:resolve 0.35ms /app/web/src/types/segment -> /app/web/src/types/segment.ts +2025-08-04T22:11:07.390Z vite:resolve 0.63ms @/types/palette -> /app/web/src/types/palette.ts +2025-08-04T22:11:07.390Z vite:resolve 0.62ms @/types/segment -> /app/web/src/types/segment.ts +2025-08-04T22:11:07.392Z vite:resolve 0.66ms ./Brush -> /app/web/src/services/Brush.ts +2025-08-04T22:11:07.394Z vite:resolve 0.24ms ./wards/Castle -> /app/web/src/services/wards/Castle.ts +2025-08-04T22:11:07.397Z vite:resolve 0.27ms ./polygon -> /app/web/src/types/polygon.ts +2025-08-04T22:11:07.403Z vite:resolve 0.66ms d3-delaunay -> /app/web/node_modules/d3-delaunay/src/index.js +2025-08-04T22:11:07.404Z vite:resolve 0.27ms ./point -> /app/web/src/types/point.ts +2025-08-04T22:11:07.404Z vite:resolve 0.29ms ./Model -> /app/web/src/services/Model.ts +2025-08-04T22:11:07.405Z vite:resolve 0.39ms /app/web/src/types/graph -> /app/web/src/types/graph.ts +2025-08-04T22:11:07.405Z vite:resolve 0.49ms @/types/graph -> /app/web/src/types/graph.ts +2025-08-04T22:11:07.406Z vite:resolve 0.50ms ../../building/CurtainWall -> /app/web/src/building/CurtainWall.ts +2025-08-04T22:11:07.406Z vite:resolve 0.48ms ./geomUtils -> /app/web/src/types/geomUtils.ts +2025-08-04T22:11:07.407Z vite:resolve 0.37ms ./Ward -> /app/web/src/services/wards/Ward.ts +2025-08-04T22:11:07.408Z vite:resolve 1.18ms ./MathUtils -> null +2025-08-04T22:11:07.411Z vite:resolve 0.11ms /app/web/src/services/Cutter -> /app/web/src/services/Cutter.ts +2025-08-04T22:11:07.411Z vite:resolve 0.23ms @/services/Cutter -> /app/web/src/services/Cutter.ts +2025-08-04T22:11:07.413Z vite:resolve 0.55ms ./node -> /app/web/src/types/node.ts +2025-08-04T22:11:07.413Z vite:resolve 0.58ms ../../geom/GeomUtils -> /app/web/src/geom/GeomUtils.ts +2025-08-04T22:11:07.413Z vite:resolve 0.58ms ../geom/Point -> /app/web/src/geom/Point.ts +2025-08-04T22:11:07.413Z vite:resolve 0.51ms /app/web/src/types/geomUtils -> /app/web/src/types/geomUtils.ts +2025-08-04T22:11:07.413Z vite:resolve 0.86ms @/types/geomUtils -> /app/web/src/types/geomUtils.ts +2025-08-04T22:11:07.415Z vite:resolve 0.47ms ../../utils/Random -> /app/web/src/utils/Random.ts +2025-08-04T22:11:07.417Z vite:resolve 0.30ms ../../building/Cutter -> /app/web/src/building/Cutter.ts +2025-08-04T22:11:07.417Z vite:resolve 0.33ms ./Model -> /app/web/src/building/Model.ts +2025-08-04T22:11:07.417Z vite:resolve 0.31ms /app/web/src/services/CurtainWall -> /app/web/src/services/CurtainWall.ts +2025-08-04T22:11:07.418Z vite:resolve 0.67ms @/services/CurtainWall -> /app/web/src/services/CurtainWall.ts +2025-08-04T22:11:07.419Z vite:resolve 0.24ms ./Patch -> /app/web/src/building/Patch.ts +2025-08-04T22:11:07.421Z vite:resolve 0.15ms ../utils/ArrayUtils -> /app/web/src/utils/ArrayUtils.ts +2025-08-04T22:11:07.426Z vite:resolve 0.30ms ../geom/Polygon -> /app/web/src/geom/Polygon.ts +2025-08-04T22:11:07.430Z vite:resolve 0.20ms ./Point -> /app/web/src/geom/Point.ts +2025-08-04T22:11:07.451Z vite:deps Scan completed in 155.92ms: + d3-delaunay -> /app/web/node_modules/d3-delaunay/src/index.js + react -> /app/web/node_modules/react/index.js + react-dom/client -> /app/web/node_modules/react-dom/client.js + react/jsx-runtime -> /app/web/node_modules/react/jsx-runtime.js +2025-08-04T22:11:07.453Z vite:deps creating package.json in /app/web/node_modules/.vite/deps_temp_6d3ce6db +2025-08-04T22:11:07.456Z vite:hmr [file change] npm_output.log +2025-08-04T22:11:07.456Z vite:hmr (client) [no modules matched] npm_output.log +2025-08-04T22:11:07.456Z vite:hmr (ssr) [no modules matched] npm_output.log +2025-08-04T22:11:07.464Z vite:resolve 0.60ms react-dom -> /app/web/node_modules/react-dom/index.js +2025-08-04T22:11:07.470Z vite:resolve 0.51ms react -> /app/web/node_modules/react/index.js +2025-08-04T22:11:07.475Z vite:resolve 0.82ms delaunator -> /app/web/node_modules/delaunator/index.js +2025-08-04T22:11:07.477Z vite:resolve 0.41ms robust-predicates -> /app/web/node_modules/robust-predicates/index.js +2025-08-04T22:11:07.528Z vite:resolve 0.41ms scheduler -> /app/web/node_modules/scheduler/index.js +2025-08-04T22:11:07.529Z vite:hmr [file change] npm_output.log +2025-08-04T22:11:07.530Z vite:hmr (client) [no modules matched] npm_output.log +2025-08-04T22:11:07.530Z vite:hmr (ssr) [no modules matched] npm_output.log +2025-08-04T22:11:07.614Z vite:deps Dependencies bundled in 159.90ms +2025-08-04T22:11:07.615Z vite:deps ✨ using post-scan optimizer result, the scanner found every used dependency +2025-08-04T22:11:07.615Z vite:deps creating _metadata.json in /app/web/node_modules/.vite/deps_temp_6d3ce6db +2025-08-04T22:11:07.616Z vite:deps renaming /app/web/node_modules/.vite/deps_temp_6d3ce6db to /app/web/node_modules/.vite/deps +2025-08-04T22:11:07.616Z vite:deps ✨ dependencies optimized +2025-08-04T22:11:07.616Z vite:hmr [file change] npm_output.log +2025-08-04T22:11:07.617Z vite:hmr (client) [no modules matched] npm_output.log +2025-08-04T22:11:07.617Z vite:hmr (ssr) [no modules matched] npm_output.log diff --git a/web/package-lock.json b/web/package-lock.json index 9c87542..751233c 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -9,6 +9,7 @@ "version": "0.1.0", "dependencies": { "@kobandavis/wfc": "^1.1.0", + "@rollup/rollup-linux-x64-gnu": "^4.46.2", "d3-delaunay": "^6.0.4", "react": "^18.2.0", "react-dom": "^18.2.0" @@ -18,12 +19,28 @@ "@types/d3-delaunay": "^6.0.4", "@types/react": "^19.1.9", "@types/react-dom": "^19.1.7", + "@vitejs/plugin-react": "^4.7.0", "http-server": "^14.1.1", "jsdom": "^26.1.0", "typescript": "^5.4.0", + "vite": "^7.0.6", "vitest": "^3.2.4" } }, + "node_modules/@ampproject/remapping": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/@asamuzakjp/css-color": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-3.2.0.tgz", @@ -44,7 +61,6 @@ "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/helper-validator-identifier": "^7.27.1", "js-tokens": "^4.0.0", @@ -54,17 +70,235 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/compat-data": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.0.tgz", + "integrity": "sha512-60X7qkglvrap8mn1lh2ebxXdZYtUcpd7gsmy9kLaBJ4i/WdY8PqTSdxyA8qraikqKQK5C1KRBKXqznrVapyNaw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.0.tgz", + "integrity": "sha512-UlLAnTPrFdNGoFtbSXwcGFQBtQZJCNjaN6hQNP3UPvuNXT1i82N26KL3dZeIpNalWywr9IuQuncaAfUaS1g6sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.28.0", + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-module-transforms": "^7.27.3", + "@babel/helpers": "^7.27.6", + "@babel/parser": "^7.28.0", + "@babel/template": "^7.27.2", + "@babel/traverse": "^7.28.0", + "@babel/types": "^7.28.0", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/generator": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.0.tgz", + "integrity": "sha512-lJjzvrbEeWrhB4P3QBsH7tey117PjLZnDbLiQEKjQ/fNJTjuq4HSqgFA+UNSwZT8D7dxxbnuSBMsa1lrWzKlQg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.28.0", + "@babel/types": "^7.28.0", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.27.2", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz", + "integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.27.2", + "@babel/helper-validator-option": "^7.27.1", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/@babel/helper-globals": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", + "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz", + "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.27.1", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.27.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.27.3.tgz", + "integrity": "sha512-dSOvYwvyLsWBeIRyOeHXp5vPj5l1I011r52FM1+r1jCERv+aFXYk4whgQccYEGYxK2H3ZAIA8nuPkQ0HaUo3qg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1", + "@babel/traverse": "^7.27.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz", + "integrity": "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/helper-validator-identifier": { "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz", "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=6.9.0" } }, + "node_modules/@babel/helper-validator-option": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", + "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.28.2", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.2.tgz", + "integrity": "sha512-/V9771t+EgXz62aCcyofnQhGM8DQACbRhvzKFsXKC9QM+5MadF8ZmIm0crDMaz3+o0h0zXfJnd4EhbYbxsrcFw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.27.2", + "@babel/types": "^7.28.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.0.tgz", + "integrity": "sha512-jVZGvOxOuNSsuQuLRTh13nU0AogFlw32w/MT+LV6D3sP5WdbW61E77RnkbaO2dUvmPAYrBDJXGn5gGS6tH4j8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.0" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-self": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.27.1.tgz", + "integrity": "sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-source": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.27.1.tgz", + "integrity": "sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, "node_modules/@babel/runtime": { "version": "7.28.2", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.2.tgz", @@ -75,6 +309,54 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/template": { + "version": "7.27.2", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", + "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/parser": "^7.27.2", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.0.tgz", + "integrity": "sha512-mGe7UK5wWyh0bKRfupsUchrQGqvDbZDbKJw+kcRGSmdHVYrv+ltd0pnpDTVpiTqnaBru9iEvA8pz8W46v0Amwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.28.0", + "@babel/helper-globals": "^7.28.0", + "@babel/parser": "^7.28.0", + "@babel/template": "^7.27.2", + "@babel/types": "^7.28.0", + "debug": "^4.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.28.2", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.2.tgz", + "integrity": "sha512-ruv7Ae4J5dUYULmeXw1gmb7rYRz57OWCPM57pHojnLq/3Z1CK2lNSLTCVjxVk1F/TZHwOZZrOWi0ur95BbLxNQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@csstools/color-helpers": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-5.0.2.tgz", @@ -632,6 +914,27 @@ "node": ">=18" } }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.12", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.12.tgz", + "integrity": "sha512-OuLGC46TjB5BbN1dH8JULVVZY4WTdkF7tV9Ys6wLL1rubZnCMstOhNHueU5bLCrnRuDhKPDM4g6sw4Bel5Gzqg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/@jridgewell/sourcemap-codec": { "version": "1.5.4", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.4.tgz", @@ -639,12 +942,30 @@ "dev": true, "license": "MIT" }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.29", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.29.tgz", + "integrity": "sha512-uw6guiW/gcAGPDhLmd77/6lW8QLeiV5RUTsAX46Db6oLhGaVj4lhnPwb184s1bkc8kdVg/+h988dro8GRDpmYQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, "node_modules/@kobandavis/wfc": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@kobandavis/wfc/-/wfc-1.1.0.tgz", "integrity": "sha512-tFF3j/vK5oQ3aFtd5zzayI122ZZg7tuyx6sqvAblofnToag+6Vvz5vC4IZ2LsvHv5vG3Qko2rAa5q4+eVb3SXA==", "license": "ISC" }, + "node_modules/@rolldown/pluginutils": { + "version": "1.0.0-beta.27", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.27.tgz", + "integrity": "sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA==", + "dev": true, + "license": "MIT" + }, "node_modules/@rollup/rollup-android-arm-eabi": { "version": "4.46.2", "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.46.2.tgz", @@ -862,9 +1183,7 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", - "optional": true, "os": [ "linux" ] @@ -982,6 +1301,51 @@ "license": "MIT", "peer": true }, + "node_modules/@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz", + "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz", + "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.2" + } + }, "node_modules/@types/chai": { "version": "5.2.2", "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.2.tgz", @@ -1033,6 +1397,27 @@ "@types/react": "^19.0.0" } }, + "node_modules/@vitejs/plugin-react": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.7.0.tgz", + "integrity": "sha512-gUu9hwfWvvEDBBmgtAowQCojwZmJ5mcLn3aufeCsitijs3+f2NsrPtlAWIR6OPiqljl96GVCUbLe0HyqIpVaoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.28.0", + "@babel/plugin-transform-react-jsx-self": "^7.27.1", + "@babel/plugin-transform-react-jsx-source": "^7.27.1", + "@rolldown/pluginutils": "1.0.0-beta.27", + "@types/babel__core": "^7.20.5", + "react-refresh": "^0.17.0" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "peerDependencies": { + "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" + } + }, "node_modules/@vitest/expect": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.2.4.tgz", @@ -1226,6 +1611,39 @@ "node": ">= 0.8" } }, + "node_modules/browserslist": { + "version": "4.25.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.25.1.tgz", + "integrity": "sha512-KGj0KoOMXLpSNkkEI6Z6mShmQy0bc1I+T7K9N81k4WWMrfz+6fQ6es80B/YLAeRoKvjYE1YSHHOW1qe9xIVzHw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "caniuse-lite": "^1.0.30001726", + "electron-to-chromium": "^1.5.173", + "node-releases": "^2.0.19", + "update-browserslist-db": "^1.1.3" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, "node_modules/cac": { "version": "6.7.14", "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", @@ -1267,6 +1685,27 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/caniuse-lite": { + "version": "1.0.30001731", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001731.tgz", + "integrity": "sha512-lDdp2/wrOmTRWuoB5DpfNkC0rJDU8DqRa6nYL6HK6sytw70QMopt/NIc/9SM7ylItlBWfACXk0tEn37UWM/+mg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, "node_modules/chai": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/chai/-/chai-5.2.1.tgz", @@ -1331,6 +1770,13 @@ "dev": true, "license": "MIT" }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, "node_modules/corser": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/corser/-/corser-2.0.1.tgz", @@ -1466,6 +1912,13 @@ "node": ">= 0.4" } }, + "node_modules/electron-to-chromium": { + "version": "1.5.195", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.195.tgz", + "integrity": "sha512-URclP0iIaDUzqcAyV1v2PgduJ9N0IdXmWsnPzPfelvBmjmZzEy6xJcjb1cXj+TbYqXgtLrjHEoaSIdTYhw4ezg==", + "dev": true, + "license": "ISC" + }, "node_modules/entities": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", @@ -1561,6 +2014,16 @@ "@esbuild/win32-x64": "0.25.8" } }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/estree-walker": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", @@ -1649,6 +2112,16 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/get-intrinsic": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", @@ -1923,6 +2396,32 @@ "node": ">=18" } }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -2029,6 +2528,13 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, + "node_modules/node-releases": { + "version": "2.0.19", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", + "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", + "dev": true, + "license": "MIT" + }, "node_modules/nwsapi": { "version": "2.2.21", "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.21.tgz", @@ -2241,6 +2747,16 @@ "license": "MIT", "peer": true }, + "node_modules/react-refresh": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.17.0.tgz", + "integrity": "sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/requires-port": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", @@ -2344,6 +2860,16 @@ "dev": true, "license": "MIT" }, + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, "node_modules/side-channel": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", @@ -2624,6 +3150,37 @@ "node": ">= 0.8.0" } }, + "node_modules/update-browserslist-db": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz", + "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, "node_modules/url-join": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz", @@ -2917,6 +3474,13 @@ "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", "dev": true, "license": "MIT" + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true, + "license": "ISC" } } } diff --git a/web/package.json b/web/package.json index 1a9e339..d51ff4a 100644 --- a/web/package.json +++ b/web/package.json @@ -12,6 +12,7 @@ }, "dependencies": { "@kobandavis/wfc": "^1.1.0", + "@rollup/rollup-linux-x64-gnu": "^4.46.2", "d3-delaunay": "^6.0.4", "react": "^18.2.0", "react-dom": "^18.2.0" @@ -21,9 +22,11 @@ "@types/d3-delaunay": "^6.0.4", "@types/react": "^19.1.9", "@types/react-dom": "^19.1.7", + "@vitejs/plugin-react": "^4.7.0", "http-server": "^14.1.1", "jsdom": "^26.1.0", "typescript": "^5.4.0", + "vite": "^7.0.6", "vitest": "^3.2.4" } } diff --git a/web/src/services/CityMap.tsx b/web/src/services/CityMap.tsx index 385f8d3..229f09d 100644 --- a/web/src/services/CityMap.tsx +++ b/web/src/services/CityMap.tsx @@ -34,6 +34,15 @@ export const CityMap: React.FC = ({ model }) => { ctx.fillStyle = `#${palette.paper.toString(16)}`; ctx.fillRect(0, 0, canvas.width, canvas.height); + ctx.save(); + + const cityRadius = model.cityRadius * 1.2; + const scale = Math.min(canvas.width, canvas.height) / (2 * cityRadius); + + ctx.translate(canvas.width / 2, canvas.height / 2); + ctx.scale(scale, -scale); + ctx.translate(-model.center.x, -model.center.y); + for (const road of model.roads) { drawRoad(ctx, brush, road, palette); } @@ -57,6 +66,8 @@ export const CityMap: React.FC = ({ model }) => { if (model.citadel) { drawWall(ctx, brush, (model.citadel.ward as Castle).wall, true, palette); } + + ctx.restore(); }, [model]); const drawRoad = (ctx: CanvasRenderingContext2D, brush: Brush, road: Street, palette: Palette) => { diff --git a/web/src/services/Topology.ts b/web/src/services/Topology.ts index 5ab2066..add0222 100644 --- a/web/src/services/Topology.ts +++ b/web/src/services/Topology.ts @@ -85,8 +85,25 @@ export class Topology { } public buildPath(from: Point, to: Point, exclude: Node[] = []): Street | null { - const startNodePoint = Array.from(this.pt2node.keys()).find((p: Point) => p.x === from.x && p.y === from.y); - const endNodePoint = Array.from(this.pt2node.keys()).find((p: Point) => p.x === to.x && p.y === to.y); + let startNodePoint: Point | null = null; + let minStartDist = Infinity; + for (const p of this.pt2node.keys()) { + const d = Point.distance(p, from); + if (d < minStartDist) { + minStartDist = d; + startNodePoint = p; + } + } + + let endNodePoint: Point | null = null; + let minEndDist = Infinity; + for (const p of this.pt2node.keys()) { + const d = Point.distance(p, to); + if (d < minEndDist) { + minEndDist = d; + endNodePoint = p; + } + } if (!startNodePoint || !endNodePoint) return null;