Replace point sampling with proper computational geometry using @flatten-js/core. Previous approach (strategic points): - Tested 9 hardcoded points (corners + center + edge midpoints) - Still sampling-based, just smarter sampling - Could miss edge cases with complex shapes New approach (flatten-js): - Convert SVG path to Polygon using getPointAtLength() (50 samples) - Convert detection box to Box in SVG coordinates - Use polygon.intersect(box) for precise intersection test - Also checks boxContainsRegion for tiny regions fully inside box - Proper computational geometry, not heuristics Algorithm: 1. Sample 50 points evenly along SVG path using getTotalLength() 2. Create Polygon from sampled points 3. Transform detection box corners to SVG coordinates 4. Create Box from transformed corners 5. Check: polygon.intersect(box) || box.contains(polygon.box) Benefits: - Mathematically correct intersection detection - No guessing about where to sample - Handles all cases: intersecting, contained, disjoint - Fallback to 9-point sampling if flatten-js fails Dependencies: - Added @flatten-js/core for 2D computational geometry 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
139 lines
4.7 KiB
JSON
139 lines
4.7 KiB
JSON
{
|
|
"name": "@soroban/web",
|
|
"version": "0.1.0",
|
|
"private": true,
|
|
"scripts": {
|
|
"dev": "tsc -p tsconfig.server.json && tsc-alias -p tsconfig.server.json && concurrently \"node server.js\" \"npx @pandacss/dev --watch\"",
|
|
"build": "node scripts/generate-build-info.js && npx tsx scripts/generateAllDayIcons.tsx && npx @pandacss/dev && tsc -p tsconfig.server.json && tsc-alias -p tsconfig.server.json && next build",
|
|
"start": "NODE_ENV=production node server.js",
|
|
"lint": "npx @biomejs/biome lint . && npx eslint .",
|
|
"lint:fix": "npx @biomejs/biome lint . --write && npx eslint . --fix",
|
|
"format": "npx @biomejs/biome format . --write",
|
|
"format:check": "npx @biomejs/biome format .",
|
|
"check": "npx @biomejs/biome check .",
|
|
"pre-commit": "npm run type-check && npm run format && npm run lint:fix && npm run lint",
|
|
"test": "vitest",
|
|
"test:run": "vitest run",
|
|
"type-check": "tsc --noEmit",
|
|
"clean": "rm -rf .next",
|
|
"storybook": "storybook dev -p 6006",
|
|
"build-storybook": "storybook build",
|
|
"db:generate": "drizzle-kit generate",
|
|
"db:migrate": "tsx src/db/migrate.ts",
|
|
"db:push": "drizzle-kit push",
|
|
"db:studio": "drizzle-kit studio",
|
|
"db:drop": "drizzle-kit drop"
|
|
},
|
|
"dependencies": {
|
|
"@dnd-kit/core": "^6.3.1",
|
|
"@dnd-kit/sortable": "^10.0.0",
|
|
"@dnd-kit/utilities": "^3.2.2",
|
|
"@flatten-js/core": "^1.6.8",
|
|
"@number-flow/react": "^0.5.10",
|
|
"@pandacss/dev": "^0.20.0",
|
|
"@paralleldrive/cuid2": "^2.2.2",
|
|
"@radix-ui/react-accordion": "^1.1.2",
|
|
"@radix-ui/react-checkbox": "^1.0.4",
|
|
"@radix-ui/react-dialog": "^1.0.5",
|
|
"@radix-ui/react-dropdown-menu": "^2.0.6",
|
|
"@radix-ui/react-hover-card": "^1.1.15",
|
|
"@radix-ui/react-label": "^2.0.2",
|
|
"@radix-ui/react-popover": "^1.1.15",
|
|
"@radix-ui/react-progress": "^1.0.3",
|
|
"@radix-ui/react-radio-group": "^1.1.3",
|
|
"@radix-ui/react-select": "^2.0.0",
|
|
"@radix-ui/react-slider": "^1.1.2",
|
|
"@radix-ui/react-switch": "^1.0.3",
|
|
"@radix-ui/react-tabs": "^1.0.4",
|
|
"@radix-ui/react-toast": "^1.1.5",
|
|
"@radix-ui/react-tooltip": "^1.2.8",
|
|
"@react-spring/web": "^10.0.3",
|
|
"@react-three/drei": "^9.117.0",
|
|
"@react-three/fiber": "^8.17.0",
|
|
"@soroban/abacus-react": "workspace:*",
|
|
"@soroban/core": "workspace:*",
|
|
"@soroban/templates": "workspace:*",
|
|
"@svg-maps/usa": "^2.0.0",
|
|
"@svg-maps/world": "^2.0.0",
|
|
"@tanstack/react-form": "^0.19.0",
|
|
"@tanstack/react-query": "^5.90.2",
|
|
"@types/jsdom": "^21.1.7",
|
|
"@types/qrcode": "^1.5.6",
|
|
"@use-gesture/react": "^10.3.1",
|
|
"bcryptjs": "^2.4.3",
|
|
"better-sqlite3": "^12.4.1",
|
|
"d3-force": "^3.0.0",
|
|
"drizzle-orm": "^0.44.6",
|
|
"embla-carousel-autoplay": "^8.6.0",
|
|
"embla-carousel-react": "^8.6.0",
|
|
"emojibase-data": "^16.0.3",
|
|
"gray-matter": "^4.0.3",
|
|
"jose": "^6.1.0",
|
|
"js-yaml": "^4.1.0",
|
|
"lib0": "^0.2.114",
|
|
"lucide-react": "^0.294.0",
|
|
"make-plural": "^7.4.0",
|
|
"nanoid": "^5.1.6",
|
|
"next": "^14.2.32",
|
|
"next-auth": "5.0.0-beta.29",
|
|
"next-intl": "^4.4.0",
|
|
"openscad-wasm-prebuilt": "^1.2.0",
|
|
"python-bridge": "^1.1.0",
|
|
"qrcode": "^1.5.4",
|
|
"qrcode.react": "^4.2.0",
|
|
"react": "^18.2.0",
|
|
"react-dom": "^18.2.0",
|
|
"react-resizable-layout": "^0.7.3",
|
|
"react-resizable-panels": "^3.0.6",
|
|
"react-textfit": "^1.1.1",
|
|
"rehype-autolink-headings": "^7.1.0",
|
|
"rehype-highlight": "^7.0.2",
|
|
"rehype-slug": "^6.0.0",
|
|
"remark": "^15.0.1",
|
|
"remark-gfm": "^4.0.1",
|
|
"remark-html": "^16.0.1",
|
|
"socket.io": "^4.8.1",
|
|
"socket.io-client": "^4.8.1",
|
|
"three": "^0.169.0",
|
|
"y-protocols": "^1.0.6",
|
|
"y-websocket": "^3.0.0",
|
|
"yjs": "^13.6.27",
|
|
"zod": "^4.1.12"
|
|
},
|
|
"devDependencies": {
|
|
"@playwright/test": "^1.55.1",
|
|
"@storybook/addon-docs": "^9.1.7",
|
|
"@storybook/addon-onboarding": "^9.1.7",
|
|
"@storybook/nextjs": "^9.1.7",
|
|
"@testing-library/jest-dom": "^6.8.0",
|
|
"@testing-library/react": "^16.3.0",
|
|
"@types/bcryptjs": "^2.4.6",
|
|
"@types/better-sqlite3": "^7.6.13",
|
|
"@types/d3-force": "^3.0.10",
|
|
"@types/js-yaml": "^4.0.9",
|
|
"@types/node": "^20.0.0",
|
|
"@types/react": "^18.2.0",
|
|
"@types/react-dom": "^18.2.0",
|
|
"@types/react-textfit": "^1.1.4",
|
|
"@types/ws": "^8.18.1",
|
|
"@vitejs/plugin-react": "^5.0.2",
|
|
"concurrently": "^8.2.2",
|
|
"drizzle-kit": "^0.31.5",
|
|
"eslint": "^8.0.0",
|
|
"eslint-config-next": "^14.0.0",
|
|
"eslint-plugin-storybook": "^9.1.7",
|
|
"happy-dom": "^18.0.1",
|
|
"jsdom": "^27.0.0",
|
|
"storybook": "^9.1.7",
|
|
"tsc-alias": "^1.8.16",
|
|
"tsx": "^4.20.5",
|
|
"typescript": "^5.0.0",
|
|
"vitest": "^1.0.0"
|
|
},
|
|
"eslintConfig": {
|
|
"extends": [
|
|
"next/core-web-vitals"
|
|
]
|
|
}
|
|
}
|