blacktrigram 0.7.6 → 0.7.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/ARCHITECTURE.md +2404 -0
  2. package/COMBAT_ARCHITECTURE.md +3322 -0
  3. package/CONTROLS.md +639 -0
  4. package/CRA-ASSESSMENT.md +508 -0
  5. package/DATA_MODEL.md +675 -0
  6. package/ISMS_REFERENCE_MAPPING.md +513 -0
  7. package/README.md +1 -1
  8. package/SECURITY_ARCHITECTURE.md +1160 -0
  9. package/THREAT_MODEL.md +1163 -0
  10. package/lib/audio/AudioAssetLoader.js.map +1 -1
  11. package/lib/components/screens/combat/hooks/useCombatActions.js.map +1 -1
  12. package/lib/components/screens/combat/hooks/useCombatAudio.js.map +1 -1
  13. package/lib/components/screens/intro/IntroScreen3D.js +1 -1
  14. package/lib/components/screens/training/TrainingScreen3D.js.map +1 -1
  15. package/lib/components/screens/training/components/HitFeedbackEffect3D.js.map +1 -1
  16. package/lib/components/screens/training/hooks/useTrainingActions.js.map +1 -1
  17. package/lib/components/shared/ui/SplashScreen.js +2 -2
  18. package/lib/data/archetypeClothing.js +1 -1
  19. package/lib/data/archetypePhysicalAttributes.js +158 -1
  20. package/lib/data/archetypePhysicalAttributes.js.map +1 -1
  21. package/lib/data/index.d.ts +14 -0
  22. package/lib/data/index.d.ts.map +1 -0
  23. package/lib/data/index.js +43 -0
  24. package/lib/data/index.js.map +1 -0
  25. package/lib/data/techniqueMappings.js +47 -2
  26. package/lib/data/techniqueMappings.js.map +1 -1
  27. package/lib/data/techniques.js +1 -1
  28. package/lib/hooks/index.d.ts +29 -0
  29. package/lib/hooks/index.d.ts.map +1 -0
  30. package/lib/hooks/index.js +53 -0
  31. package/lib/hooks/index.js.map +1 -0
  32. package/lib/hooks/useCombatTimer.js.map +1 -1
  33. package/lib/hooks/useDebounce.js +52 -0
  34. package/lib/hooks/useDebounce.js.map +1 -0
  35. package/lib/hooks/usePauseMenu.js +60 -0
  36. package/lib/hooks/usePauseMenu.js.map +1 -0
  37. package/lib/hooks/useResponsiveLayout.js +160 -0
  38. package/lib/hooks/useResponsiveLayout.js.map +1 -0
  39. package/lib/hooks/useRoundTransition.js.map +1 -1
  40. package/lib/hooks/useTechniqueSelection.js.map +1 -1
  41. package/lib/hooks/useThrottle.js.map +1 -1
  42. package/lib/hooks/useWebGLContextLossHandler.js +36 -1
  43. package/lib/hooks/useWebGLContextLossHandler.js.map +1 -1
  44. package/lib/hooks/useWindowSize.js +19 -1
  45. package/lib/hooks/useWindowSize.js.map +1 -1
  46. package/lib/index.d.ts +2 -0
  47. package/lib/index.d.ts.map +1 -1
  48. package/lib/index.js +3 -1
  49. package/package.json +22 -6
@@ -1 +1 @@
1
- {"version":3,"file":"useWebGLContextLossHandler.js","names":[],"sources":["../../src/hooks/useWebGLContextLossHandler.ts"],"sourcesContent":["/**\n * useWebGLContextLossHandler - React hook for handling WebGL context loss\n *\n * This hook sets up event listeners for WebGL context loss and restoration,\n * which can occur due to GPU issues, memory pressure, or browser tab switching.\n *\n * @example\n * ```tsx\n * const Canvas = () => {\n * useWebGLContextLossHandler();\n * return <Canvas>...</Canvas>;\n * };\n * ```\n */\n\nimport type React from \"react\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\n\n/**\n * Global WebGL context state tracking\n * Helps coordinate context recovery across multiple Canvas components\n */\nlet globalContextLossCount = 0;\nlet globalIsContextLost = false;\nlet lastContextLossTime = 0;\n\n/**\n * Minimum delay between context loss events to prevent thrashing\n */\nexport const MIN_CONTEXT_RECOVERY_DELAY = 100; // ms\n\n/**\n * Get global WebGL context state\n */\nexport const getWebGLContextState = (): {\n isLost: boolean;\n lossCount: number;\n timeSinceLastLoss: number;\n} => ({\n isLost: globalIsContextLost,\n lossCount: globalContextLossCount,\n timeSinceLastLoss: Date.now() - lastContextLossTime,\n});\n\nexport interface WebGLContextLossOptions {\n /**\n * Callback when context is lost\n */\n readonly onContextLost?: () => void;\n\n /**\n * Callback when context is restored\n */\n readonly onContextRestored?: () => void;\n\n /**\n * Whether to attempt automatic restoration (default: true)\n */\n readonly autoRestore?: boolean;\n\n /**\n * Optional canvas ref to attach to a specific canvas element\n * If not provided, will query for the first canvas in the document\n */\n readonly canvasRef?: React.RefObject<HTMLCanvasElement>;\n\n /**\n * Delay in ms before attempting to query for canvas (default: 50)\n * Helps avoid race conditions during screen transitions\n */\n readonly mountDelay?: number;\n\n /**\n * Maximum attempts to find canvas element (default: 5)\n */\n readonly maxRetries?: number;\n}\n\nexport interface WebGLContextState {\n /** Whether context is currently lost */\n readonly isContextLost: boolean;\n /** Number of times context has been lost */\n readonly lossCount: number;\n /** Whether the canvas element has been found */\n readonly isCanvasMounted: boolean;\n}\n\n/**\n * Hook to handle WebGL context loss and restoration\n * Returns state information about the WebGL context\n */\nexport const useWebGLContextLossHandler = (\n options: WebGLContextLossOptions = {}\n): WebGLContextState => {\n const {\n onContextLost,\n onContextRestored,\n autoRestore = true,\n canvasRef,\n mountDelay = 50,\n maxRetries = 5,\n } = options;\n\n const [contextState, setContextState] = useState<WebGLContextState>({\n isContextLost: globalIsContextLost,\n lossCount: globalContextLossCount,\n isCanvasMounted: false,\n });\n\n // Use refs to store the latest callbacks to avoid re-registering event listeners\n const onContextLostRef = useRef(onContextLost);\n const onContextRestoredRef = useRef(onContextRestored);\n const retryCountRef = useRef(0);\n const mountedRef = useRef(true);\n\n // Update refs when callbacks change\n useEffect(() => {\n onContextLostRef.current = onContextLost;\n onContextRestoredRef.current = onContextRestored;\n });\n\n // Track component mount state\n useEffect(() => {\n mountedRef.current = true;\n return () => {\n mountedRef.current = false;\n };\n }, []);\n\n const handleContextLost = useCallback(\n (event: Event) => {\n const now = Date.now();\n globalIsContextLost = true;\n globalContextLossCount++;\n lastContextLossTime = now;\n\n console.warn(\n `⚠️ WebGL context lost (count: ${globalContextLossCount}, time since mount: ${\n now - lastContextLossTime\n }ms)`\n );\n\n // Prevent default behavior to allow restoration\n if (autoRestore) {\n event.preventDefault();\n }\n\n if (mountedRef.current) {\n setContextState({\n isContextLost: true,\n lossCount: globalContextLossCount,\n isCanvasMounted: true,\n });\n }\n\n onContextLostRef.current?.();\n },\n [autoRestore]\n );\n\n const handleContextRestored = useCallback(() => {\n globalIsContextLost = false;\n console.log(\"✅ WebGL context restored successfully\");\n\n if (mountedRef.current) {\n setContextState((prev) => ({\n ...prev,\n isContextLost: false,\n }));\n }\n\n onContextRestoredRef.current?.();\n }, []);\n\n useEffect(() => {\n let canvas = canvasRef?.current ?? document.querySelector(\"canvas\");\n let cleanupFn: (() => void) | undefined;\n let retryTimeout: ReturnType<typeof setTimeout> | undefined;\n let observer: MutationObserver | undefined;\n\n const attachListeners = (canvasEl: HTMLCanvasElement) => {\n canvasEl.addEventListener(\"webglcontextlost\", handleContextLost, false);\n canvasEl.addEventListener(\n \"webglcontextrestored\",\n handleContextRestored,\n false\n );\n\n if (mountedRef.current) {\n setContextState((prev) => ({\n ...prev,\n isCanvasMounted: true,\n }));\n }\n\n return () => {\n canvasEl.removeEventListener(\"webglcontextlost\", handleContextLost);\n canvasEl.removeEventListener(\n \"webglcontextrestored\",\n handleContextRestored\n );\n };\n };\n\n // Retry finding canvas with delay to handle screen transitions\n const tryFindCanvas = () => {\n if (!mountedRef.current) return;\n\n canvas = canvasRef?.current ?? document.querySelector(\"canvas\");\n if (canvas) {\n cleanupFn = attachListeners(canvas);\n retryCountRef.current = 0;\n } else if (retryCountRef.current < maxRetries) {\n retryCountRef.current++;\n retryTimeout = setTimeout(tryFindCanvas, mountDelay);\n } else {\n // Fall back to MutationObserver\n observer = new MutationObserver(() => {\n canvas = document.querySelector(\"canvas\");\n if (canvas && mountedRef.current) {\n observer?.disconnect();\n cleanupFn = attachListeners(canvas);\n }\n });\n\n observer.observe(document.body, {\n childList: true,\n subtree: true,\n });\n }\n };\n\n // Attach immediately if a canvas is already mounted, otherwise retry\n canvas = canvasRef?.current ?? document.querySelector(\"canvas\");\n if (canvas) {\n cleanupFn = attachListeners(canvas);\n } else {\n retryTimeout = setTimeout(tryFindCanvas, mountDelay);\n }\n\n // Cleanup\n return () => {\n if (retryTimeout) clearTimeout(retryTimeout);\n observer?.disconnect();\n cleanupFn?.();\n };\n }, [\n autoRestore,\n canvasRef,\n handleContextLost,\n handleContextRestored,\n maxRetries,\n mountDelay,\n ]);\n\n return contextState;\n};\n\n/**\n * Check if WebGL is available in the current browser\n */\nexport const isWebGLAvailable = (): boolean => {\n try {\n const canvas = document.createElement(\"canvas\");\n const gl =\n canvas.getContext(\"webgl\") ?? canvas.getContext(\"experimental-webgl\");\n const available = gl !== null;\n // Help GC by cleaning up WebGL context\n if (gl && \"getExtension\" in gl) {\n const loseContext = gl.getExtension(\"WEBGL_lose_context\");\n loseContext?.loseContext();\n }\n return available;\n } catch {\n return false;\n }\n};\n\n/**\n * Check if WebGL2 is available in the current browser\n */\nexport const isWebGL2Available = (): boolean => {\n try {\n const canvas = document.createElement(\"canvas\");\n const gl = canvas.getContext(\"webgl2\");\n const available = gl !== null;\n // Help GC by cleaning up WebGL context\n if (gl && \"getExtension\" in gl) {\n const loseContext = gl.getExtension(\"WEBGL_lose_context\");\n loseContext?.loseContext();\n }\n return available;\n } catch {\n return false;\n }\n};\n"],"mappings":";;;;;;AAsBA,IAAI,yBAAyB;AAC7B,IAAI,sBAAsB;AAC1B,IAAI,sBAAsB;;;;;AAmE1B,IAAa,8BACX,UAAmC,EAAE,KACf;CACtB,MAAM,EACJ,eACA,mBACA,cAAc,MACd,WACA,aAAa,IACb,aAAa,MACX;CAEJ,MAAM,CAAC,cAAc,mBAAmB,SAA4B;EAClE,eAAe;EACf,WAAW;EACX,iBAAiB;EAClB,CAAC;CAGF,MAAM,mBAAmB,OAAO,cAAc;CAC9C,MAAM,uBAAuB,OAAO,kBAAkB;CACtD,MAAM,gBAAgB,OAAO,EAAE;CAC/B,MAAM,aAAa,OAAO,KAAK;AAG/B,iBAAgB;AACd,mBAAiB,UAAU;AAC3B,uBAAqB,UAAU;GAC/B;AAGF,iBAAgB;AACd,aAAW,UAAU;AACrB,eAAa;AACX,cAAW,UAAU;;IAEtB,EAAE,CAAC;CAEN,MAAM,oBAAoB,aACvB,UAAiB;EAChB,MAAM,MAAM,KAAK,KAAK;AACtB,wBAAsB;AACtB;AACA,wBAAsB;AAEtB,UAAQ,KACN,iCAAiC,uBAAuB,sBACtD,MAAM,oBACP,KACF;AAGD,MAAI,YACF,OAAM,gBAAgB;AAGxB,MAAI,WAAW,QACb,iBAAgB;GACd,eAAe;GACf,WAAW;GACX,iBAAiB;GAClB,CAAC;AAGJ,mBAAiB,WAAW;IAE9B,CAAC,YAAY,CACd;CAED,MAAM,wBAAwB,kBAAkB;AAC9C,wBAAsB;AACtB,UAAQ,IAAI,wCAAwC;AAEpD,MAAI,WAAW,QACb,kBAAiB,UAAU;GACzB,GAAG;GACH,eAAe;GAChB,EAAE;AAGL,uBAAqB,WAAW;IAC/B,EAAE,CAAC;AAEN,iBAAgB;EACd,IAAI,SAAS,WAAW,WAAW,SAAS,cAAc,SAAS;EACnE,IAAI;EACJ,IAAI;EACJ,IAAI;EAEJ,MAAM,mBAAmB,aAAgC;AACvD,YAAS,iBAAiB,oBAAoB,mBAAmB,MAAM;AACvE,YAAS,iBACP,wBACA,uBACA,MACD;AAED,OAAI,WAAW,QACb,kBAAiB,UAAU;IACzB,GAAG;IACH,iBAAiB;IAClB,EAAE;AAGL,gBAAa;AACX,aAAS,oBAAoB,oBAAoB,kBAAkB;AACnE,aAAS,oBACP,wBACA,sBACD;;;EAKL,MAAM,sBAAsB;AAC1B,OAAI,CAAC,WAAW,QAAS;AAEzB,YAAS,WAAW,WAAW,SAAS,cAAc,SAAS;AAC/D,OAAI,QAAQ;AACV,gBAAY,gBAAgB,OAAO;AACnC,kBAAc,UAAU;cACf,cAAc,UAAU,YAAY;AAC7C,kBAAc;AACd,mBAAe,WAAW,eAAe,WAAW;UAC/C;AAEL,eAAW,IAAI,uBAAuB;AACpC,cAAS,SAAS,cAAc,SAAS;AACzC,SAAI,UAAU,WAAW,SAAS;AAChC,gBAAU,YAAY;AACtB,kBAAY,gBAAgB,OAAO;;MAErC;AAEF,aAAS,QAAQ,SAAS,MAAM;KAC9B,WAAW;KACX,SAAS;KACV,CAAC;;;AAKN,WAAS,WAAW,WAAW,SAAS,cAAc,SAAS;AAC/D,MAAI,OACF,aAAY,gBAAgB,OAAO;MAEnC,gBAAe,WAAW,eAAe,WAAW;AAItD,eAAa;AACX,OAAI,aAAc,cAAa,aAAa;AAC5C,aAAU,YAAY;AACtB,gBAAa;;IAEd;EACD;EACA;EACA;EACA;EACA;EACA;EACD,CAAC;AAEF,QAAO"}
1
+ {"version":3,"file":"useWebGLContextLossHandler.js","names":[],"sources":["../../src/hooks/useWebGLContextLossHandler.ts"],"sourcesContent":["/**\n * useWebGLContextLossHandler - React hook for handling WebGL context loss\n *\n * This hook sets up event listeners for WebGL context loss and restoration,\n * which can occur due to GPU issues, memory pressure, or browser tab switching.\n *\n * @example\n * ```tsx\n * const Canvas = () => {\n * useWebGLContextLossHandler();\n * return <Canvas>...</Canvas>;\n * };\n * ```\n */\n\nimport type React from \"react\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\n\n/**\n * Global WebGL context state tracking\n * Helps coordinate context recovery across multiple Canvas components\n */\nlet globalContextLossCount = 0;\nlet globalIsContextLost = false;\nlet lastContextLossTime = 0;\n\n/**\n * Minimum delay between context loss events to prevent thrashing\n */\nexport const MIN_CONTEXT_RECOVERY_DELAY = 100; // ms\n\n/**\n * Get global WebGL context state\n */\nexport const getWebGLContextState = (): {\n isLost: boolean;\n lossCount: number;\n timeSinceLastLoss: number;\n} => ({\n isLost: globalIsContextLost,\n lossCount: globalContextLossCount,\n timeSinceLastLoss: Date.now() - lastContextLossTime,\n});\n\nexport interface WebGLContextLossOptions {\n /**\n * Callback when context is lost\n */\n readonly onContextLost?: () => void;\n\n /**\n * Callback when context is restored\n */\n readonly onContextRestored?: () => void;\n\n /**\n * Whether to attempt automatic restoration (default: true)\n */\n readonly autoRestore?: boolean;\n\n /**\n * Optional canvas ref to attach to a specific canvas element\n * If not provided, will query for the first canvas in the document\n */\n readonly canvasRef?: React.RefObject<HTMLCanvasElement>;\n\n /**\n * Delay in ms before attempting to query for canvas (default: 50)\n * Helps avoid race conditions during screen transitions\n */\n readonly mountDelay?: number;\n\n /**\n * Maximum attempts to find canvas element (default: 5)\n */\n readonly maxRetries?: number;\n}\n\nexport interface WebGLContextState {\n /** Whether context is currently lost */\n readonly isContextLost: boolean;\n /** Number of times context has been lost */\n readonly lossCount: number;\n /** Whether the canvas element has been found */\n readonly isCanvasMounted: boolean;\n}\n\n/**\n * Hook to handle WebGL context loss and restoration\n * Returns state information about the WebGL context\n */\nexport const useWebGLContextLossHandler = (\n options: WebGLContextLossOptions = {}\n): WebGLContextState => {\n const {\n onContextLost,\n onContextRestored,\n autoRestore = true,\n canvasRef,\n mountDelay = 50,\n maxRetries = 5,\n } = options;\n\n const [contextState, setContextState] = useState<WebGLContextState>({\n isContextLost: globalIsContextLost,\n lossCount: globalContextLossCount,\n isCanvasMounted: false,\n });\n\n // Use refs to store the latest callbacks to avoid re-registering event listeners\n const onContextLostRef = useRef(onContextLost);\n const onContextRestoredRef = useRef(onContextRestored);\n const retryCountRef = useRef(0);\n const mountedRef = useRef(true);\n\n // Update refs when callbacks change\n useEffect(() => {\n onContextLostRef.current = onContextLost;\n onContextRestoredRef.current = onContextRestored;\n });\n\n // Track component mount state\n useEffect(() => {\n mountedRef.current = true;\n return () => {\n mountedRef.current = false;\n };\n }, []);\n\n const handleContextLost = useCallback(\n (event: Event) => {\n const now = Date.now();\n globalIsContextLost = true;\n globalContextLossCount++;\n lastContextLossTime = now;\n\n console.warn(\n `⚠️ WebGL context lost (count: ${globalContextLossCount}, time since mount: ${\n now - lastContextLossTime\n }ms)`\n );\n\n // Prevent default behavior to allow restoration\n if (autoRestore) {\n event.preventDefault();\n }\n\n if (mountedRef.current) {\n setContextState({\n isContextLost: true,\n lossCount: globalContextLossCount,\n isCanvasMounted: true,\n });\n }\n\n onContextLostRef.current?.();\n },\n [autoRestore]\n );\n\n const handleContextRestored = useCallback(() => {\n globalIsContextLost = false;\n console.log(\"✅ WebGL context restored successfully\");\n\n if (mountedRef.current) {\n setContextState((prev) => ({\n ...prev,\n isContextLost: false,\n }));\n }\n\n onContextRestoredRef.current?.();\n }, []);\n\n useEffect(() => {\n let canvas = canvasRef?.current ?? document.querySelector(\"canvas\");\n let cleanupFn: (() => void) | undefined;\n let retryTimeout: ReturnType<typeof setTimeout> | undefined;\n let observer: MutationObserver | undefined;\n\n const attachListeners = (canvasEl: HTMLCanvasElement) => {\n canvasEl.addEventListener(\"webglcontextlost\", handleContextLost, false);\n canvasEl.addEventListener(\n \"webglcontextrestored\",\n handleContextRestored,\n false\n );\n\n if (mountedRef.current) {\n setContextState((prev) => ({\n ...prev,\n isCanvasMounted: true,\n }));\n }\n\n return () => {\n canvasEl.removeEventListener(\"webglcontextlost\", handleContextLost);\n canvasEl.removeEventListener(\n \"webglcontextrestored\",\n handleContextRestored\n );\n };\n };\n\n // Retry finding canvas with delay to handle screen transitions\n const tryFindCanvas = () => {\n if (!mountedRef.current) return;\n\n canvas = canvasRef?.current ?? document.querySelector(\"canvas\");\n if (canvas) {\n cleanupFn = attachListeners(canvas);\n retryCountRef.current = 0;\n } else if (retryCountRef.current < maxRetries) {\n retryCountRef.current++;\n retryTimeout = setTimeout(tryFindCanvas, mountDelay);\n } else {\n // Fall back to MutationObserver\n observer = new MutationObserver(() => {\n canvas = document.querySelector(\"canvas\");\n if (canvas && mountedRef.current) {\n observer?.disconnect();\n cleanupFn = attachListeners(canvas);\n }\n });\n\n observer.observe(document.body, {\n childList: true,\n subtree: true,\n });\n }\n };\n\n // Attach immediately if a canvas is already mounted, otherwise retry\n canvas = canvasRef?.current ?? document.querySelector(\"canvas\");\n if (canvas) {\n cleanupFn = attachListeners(canvas);\n } else {\n retryTimeout = setTimeout(tryFindCanvas, mountDelay);\n }\n\n // Cleanup\n return () => {\n if (retryTimeout) clearTimeout(retryTimeout);\n observer?.disconnect();\n cleanupFn?.();\n };\n }, [\n autoRestore,\n canvasRef,\n handleContextLost,\n handleContextRestored,\n maxRetries,\n mountDelay,\n ]);\n\n return contextState;\n};\n\n/**\n * Check if WebGL is available in the current browser\n */\nexport const isWebGLAvailable = (): boolean => {\n try {\n const canvas = document.createElement(\"canvas\");\n const gl =\n canvas.getContext(\"webgl\") ?? canvas.getContext(\"experimental-webgl\");\n const available = gl !== null;\n // Help GC by cleaning up WebGL context\n if (gl && \"getExtension\" in gl) {\n const loseContext = gl.getExtension(\"WEBGL_lose_context\");\n loseContext?.loseContext();\n }\n return available;\n } catch {\n return false;\n }\n};\n\n/**\n * Check if WebGL2 is available in the current browser\n */\nexport const isWebGL2Available = (): boolean => {\n try {\n const canvas = document.createElement(\"canvas\");\n const gl = canvas.getContext(\"webgl2\");\n const available = gl !== null;\n // Help GC by cleaning up WebGL context\n if (gl && \"getExtension\" in gl) {\n const loseContext = gl.getExtension(\"WEBGL_lose_context\");\n loseContext?.loseContext();\n }\n return available;\n } catch {\n return false;\n }\n};\n"],"mappings":"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"}
@@ -56,7 +56,25 @@ function useWindowSize(options = {}) {
56
56
  }, [handleResize, debounceMs]);
57
57
  return size;
58
58
  }
59
+ /**
60
+ * Hook to determine if current viewport is mobile-sized
61
+ *
62
+ * @korean 현재 뷰포트가 모바일 크기인지 확인하는 훅
63
+ *
64
+ * @param breakpoint - Width threshold for mobile (default: 768)
65
+ * @returns True if viewport width is less than breakpoint
66
+ *
67
+ * @example
68
+ * ```tsx
69
+ * const isMobile = useIsMobile();
70
+ * const isMobileCustom = useIsMobile(640);
71
+ * ```
72
+ */
73
+ function useIsMobile(breakpoint = 768) {
74
+ const { width } = useWindowSize();
75
+ return width < breakpoint;
76
+ }
59
77
  //#endregion
60
- export { useWindowSize as default };
78
+ export { useWindowSize as default, useIsMobile };
61
79
 
62
80
  //# sourceMappingURL=useWindowSize.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"useWindowSize.js","names":[],"sources":["../../src/hooks/useWindowSize.ts"],"sourcesContent":["/**\n * useWindowSize - Shared hook for responsive window dimensions\n *\n * @korean 윈도우크기훅 - 반응형 창 크기를 위한 공유 훅\n *\n * Eliminates duplication across screen components\n */\n\nimport { useCallback, useEffect, useState } from \"react\";\n\nexport interface WindowSize {\n readonly width: number;\n readonly height: number;\n}\n\nexport interface UseWindowSizeOptions {\n /**\n * Initial width if window is not available (SSR)\n * @default 1200\n */\n readonly initialWidth?: number;\n\n /**\n * Initial height if window is not available (SSR)\n * @default 800\n */\n readonly initialHeight?: number;\n\n /**\n * Debounce delay in milliseconds\n * @default 0\n */\n readonly debounceMs?: number;\n}\n\n/**\n * Hook to track window dimensions with optional debouncing\n *\n * @korean 윈도우 크기를 추적하는 훅 (선택적 디바운싱 지원)\n *\n * @param options - Configuration options\n * @returns Current window dimensions\n *\n * @example\n * ```tsx\n * const { width, height } = useWindowSize();\n * const isMobile = width < 768;\n * ```\n */\nexport function useWindowSize(options: UseWindowSizeOptions = {}): WindowSize {\n const { initialWidth = 1200, initialHeight = 800, debounceMs = 0 } = options;\n\n const [size, setSize] = useState<WindowSize>(() => {\n // Check if window is available (SSR safety)\n if (typeof window !== \"undefined\") {\n return {\n width: window.innerWidth,\n height: window.innerHeight,\n };\n }\n return {\n width: initialWidth,\n height: initialHeight,\n };\n });\n\n const handleResize = useCallback(() => {\n setSize({\n width: window.innerWidth,\n height: window.innerHeight,\n });\n }, []);\n\n useEffect(() => {\n // Safety check for SSR\n if (typeof window === \"undefined\") return;\n\n let timeoutId: ReturnType<typeof setTimeout> | null = null;\n\n const debouncedResize = () => {\n if (debounceMs > 0) {\n if (timeoutId) clearTimeout(timeoutId);\n timeoutId = setTimeout(handleResize, debounceMs);\n } else {\n handleResize();\n }\n };\n\n window.addEventListener(\"resize\", debouncedResize);\n\n return () => {\n window.removeEventListener(\"resize\", debouncedResize);\n if (timeoutId) clearTimeout(timeoutId);\n };\n }, [handleResize, debounceMs]);\n\n return size;\n}\n\n/**\n * Hook to determine if current viewport is mobile-sized\n *\n * @korean 현재 뷰포트가 모바일 크기인지 확인하는 훅\n *\n * @param breakpoint - Width threshold for mobile (default: 768)\n * @returns True if viewport width is less than breakpoint\n *\n * @example\n * ```tsx\n * const isMobile = useIsMobile();\n * const isMobileCustom = useIsMobile(640);\n * ```\n */\nexport function useIsMobile(breakpoint = 768): boolean {\n const { width } = useWindowSize();\n return width < breakpoint;\n}\n\nexport default useWindowSize;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAiDA,SAAgB,cAAc,UAAgC,EAAE,EAAc;CAC5E,MAAM,EAAE,eAAe,MAAM,gBAAgB,KAAK,aAAa,MAAM;CAErE,MAAM,CAAC,MAAM,WAAW,eAA2B;AAEjD,MAAI,OAAO,WAAW,YACpB,QAAO;GACL,OAAO,OAAO;GACd,QAAQ,OAAO;GAChB;AAEH,SAAO;GACL,OAAO;GACP,QAAQ;GACT;GACD;CAEF,MAAM,eAAe,kBAAkB;AACrC,UAAQ;GACN,OAAO,OAAO;GACd,QAAQ,OAAO;GAChB,CAAC;IACD,EAAE,CAAC;AAEN,iBAAgB;AAEd,MAAI,OAAO,WAAW,YAAa;EAEnC,IAAI,YAAkD;EAEtD,MAAM,wBAAwB;AAC5B,OAAI,aAAa,GAAG;AAClB,QAAI,UAAW,cAAa,UAAU;AACtC,gBAAY,WAAW,cAAc,WAAW;SAEhD,eAAc;;AAIlB,SAAO,iBAAiB,UAAU,gBAAgB;AAElD,eAAa;AACX,UAAO,oBAAoB,UAAU,gBAAgB;AACrD,OAAI,UAAW,cAAa,UAAU;;IAEvC,CAAC,cAAc,WAAW,CAAC;AAE9B,QAAO"}
1
+ {"version":3,"file":"useWindowSize.js","names":[],"sources":["../../src/hooks/useWindowSize.ts"],"sourcesContent":["/**\n * useWindowSize - Shared hook for responsive window dimensions\n *\n * @korean 윈도우크기훅 - 반응형 창 크기를 위한 공유 훅\n *\n * Eliminates duplication across screen components\n */\n\nimport { useCallback, useEffect, useState } from \"react\";\n\nexport interface WindowSize {\n readonly width: number;\n readonly height: number;\n}\n\nexport interface UseWindowSizeOptions {\n /**\n * Initial width if window is not available (SSR)\n * @default 1200\n */\n readonly initialWidth?: number;\n\n /**\n * Initial height if window is not available (SSR)\n * @default 800\n */\n readonly initialHeight?: number;\n\n /**\n * Debounce delay in milliseconds\n * @default 0\n */\n readonly debounceMs?: number;\n}\n\n/**\n * Hook to track window dimensions with optional debouncing\n *\n * @korean 윈도우 크기를 추적하는 훅 (선택적 디바운싱 지원)\n *\n * @param options - Configuration options\n * @returns Current window dimensions\n *\n * @example\n * ```tsx\n * const { width, height } = useWindowSize();\n * const isMobile = width < 768;\n * ```\n */\nexport function useWindowSize(options: UseWindowSizeOptions = {}): WindowSize {\n const { initialWidth = 1200, initialHeight = 800, debounceMs = 0 } = options;\n\n const [size, setSize] = useState<WindowSize>(() => {\n // Check if window is available (SSR safety)\n if (typeof window !== \"undefined\") {\n return {\n width: window.innerWidth,\n height: window.innerHeight,\n };\n }\n return {\n width: initialWidth,\n height: initialHeight,\n };\n });\n\n const handleResize = useCallback(() => {\n setSize({\n width: window.innerWidth,\n height: window.innerHeight,\n });\n }, []);\n\n useEffect(() => {\n // Safety check for SSR\n if (typeof window === \"undefined\") return;\n\n let timeoutId: ReturnType<typeof setTimeout> | null = null;\n\n const debouncedResize = () => {\n if (debounceMs > 0) {\n if (timeoutId) clearTimeout(timeoutId);\n timeoutId = setTimeout(handleResize, debounceMs);\n } else {\n handleResize();\n }\n };\n\n window.addEventListener(\"resize\", debouncedResize);\n\n return () => {\n window.removeEventListener(\"resize\", debouncedResize);\n if (timeoutId) clearTimeout(timeoutId);\n };\n }, [handleResize, debounceMs]);\n\n return size;\n}\n\n/**\n * Hook to determine if current viewport is mobile-sized\n *\n * @korean 현재 뷰포트가 모바일 크기인지 확인하는 훅\n *\n * @param breakpoint - Width threshold for mobile (default: 768)\n * @returns True if viewport width is less than breakpoint\n *\n * @example\n * ```tsx\n * const isMobile = useIsMobile();\n * const isMobileCustom = useIsMobile(640);\n * ```\n */\nexport function useIsMobile(breakpoint = 768): boolean {\n const { width } = useWindowSize();\n return width < breakpoint;\n}\n\nexport default useWindowSize;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAiDA,SAAgB,cAAc,UAAgC,EAAE,EAAc;CAC5E,MAAM,EAAE,eAAe,MAAM,gBAAgB,KAAK,aAAa,MAAM;CAErE,MAAM,CAAC,MAAM,WAAW,eAA2B;AAEjD,MAAI,OAAO,WAAW,YACpB,QAAO;GACL,OAAO,OAAO;GACd,QAAQ,OAAO;GAChB;AAEH,SAAO;GACL,OAAO;GACP,QAAQ;GACT;GACD;CAEF,MAAM,eAAe,kBAAkB;AACrC,UAAQ;GACN,OAAO,OAAO;GACd,QAAQ,OAAO;GAChB,CAAC;IACD,EAAE,CAAC;AAEN,iBAAgB;AAEd,MAAI,OAAO,WAAW,YAAa;EAEnC,IAAI,YAAkD;EAEtD,MAAM,wBAAwB;AAC5B,OAAI,aAAa,GAAG;AAClB,QAAI,UAAW,cAAa,UAAU;AACtC,gBAAY,WAAW,cAAc,WAAW;SAEhD,eAAc;;AAIlB,SAAO,iBAAiB,UAAU,gBAAgB;AAElD,eAAa;AACX,UAAO,oBAAoB,UAAU,gBAAgB;AACrD,OAAI,UAAW,cAAa,UAAU;;IAEvC,CAAC,cAAc,WAAW,CAAC;AAE9B,QAAO;;;;;;;;;;;;;;;;AAiBT,SAAgB,YAAY,aAAa,KAAc;CACrD,MAAM,EAAE,UAAU,eAAe;AACjC,QAAO,QAAQ"}
package/lib/index.d.ts CHANGED
@@ -14,6 +14,8 @@ export * from "./types";
14
14
  export * from "./utils";
15
15
  export * as Audio from "./audio";
16
16
  export * as Components from "./components";
17
+ export * as Data from "./data";
18
+ export * as Hooks from "./hooks";
17
19
  export * as Systems from "./systems";
18
20
  export * as Types from "./types";
19
21
  export * as Utils from "./utils";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,cAAc,SAAS,CAAC;AACxB,cAAc,cAAc,CAAC;AAC7B,cAAc,WAAW,CAAC;AAC1B,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC;AAGxB,OAAO,KAAK,KAAK,MAAM,SAAS,CAAC;AACjC,OAAO,KAAK,UAAU,MAAM,cAAc,CAAC;AAC3C,OAAO,KAAK,OAAO,MAAM,WAAW,CAAC;AACrC,OAAO,KAAK,KAAK,MAAM,SAAS,CAAC;AACjC,OAAO,KAAK,KAAK,MAAM,SAAS,CAAC;AAGjC,OAAO,EAAE,OAAO,IAAI,GAAG,EAAE,MAAM,OAAO,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,cAAc,SAAS,CAAC;AACxB,cAAc,cAAc,CAAC;AAC7B,cAAc,WAAW,CAAC;AAC1B,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC;AAGxB,OAAO,KAAK,KAAK,MAAM,SAAS,CAAC;AACjC,OAAO,KAAK,UAAU,MAAM,cAAc,CAAC;AAC3C,OAAO,KAAK,IAAI,MAAM,QAAQ,CAAC;AAC/B,OAAO,KAAK,KAAK,MAAM,SAAS,CAAC;AACjC,OAAO,KAAK,OAAO,MAAM,WAAW,CAAC;AACrC,OAAO,KAAK,KAAK,MAAM,SAAS,CAAC;AACjC,OAAO,KAAK,KAAK,MAAM,SAAS,CAAC;AAGjC,OAAO,EAAE,OAAO,IAAI,GAAG,EAAE,MAAM,OAAO,CAAC"}
package/lib/index.js CHANGED
@@ -110,5 +110,7 @@ import { components_exports } from "./components/index.js";
110
110
  import { getAssetBasePath, resolveAssetPath, setAssetBasePath } from "./utils/assetConfig.js";
111
111
  import { applyEffectModifiers, calculateEffectIntensity, combineEffects, createEffectFromKoreanText, createHitEffect, createKoreanStatusEffect, createStatusEffect, createTrigramEffect, getEffectDescription, getEffectDisplayText, getEffectDurationModifier, getHitEffectColor, groupEffectsByType, groupEffectsByTypeEnum, isEffectBeneficial, removeExpiredEffects, updateEffect } from "./utils/effectUtils.js";
112
112
  import { utils_exports } from "./utils/index.js";
113
+ import { data_exports } from "./data/index.js";
114
+ import { hooks_exports } from "./hooks/index.js";
113
115
  import App from "./App2.js";
114
- export { AIActionType, AIComboSystem, AIDecisionTree, AI_PERSONALITIES, ANATOMICAL_DIMENSIONS, ANATOMICAL_REGIONS_DATA, ANIMATION_DURATIONS, ANIMATION_TIMINGS, ARCHETYPE_ASSETS, ARCHETYPE_BACKGROUNDS, ARCHETYPE_BEHAVIORS, ARCHETYPE_ENFORCEMENT, ARCHETYPE_SIGNATURE_COMBOS, ARCHETYPE_TECHNIQUE_BONUSES, AUDIO_DEFAULTS, AUDIO_FORMATS, AdaptiveDifficulty, App, ArchetypeCard, AttackAnimationType, audio_exports as Audio, AudioAssetRegistry, AudioCache, AudioCategory, AudioContext, AudioManager, AudioProvider, AudioUtils, BASE_PLAYER_STATS, BASE_REACH, BORDERS, BORDER_RADIUS, BREAKING_STATUS_EFFECT_IDS, BalanceIndicator, BalanceLevel, BalanceSystem, BloodDecals3D, BloodLossOverlayHtml, BloodParticles3D, BodyRegion, BoneName, CANVAS_ASPECT_RATIO, CENTER_POSITION_X, COLLISION_KOREAN_TERMS, COMBAT_AUDIO_MAP, COMBAT_CONFIG, COMBAT_CONSTANTS, COMBAT_CONTROLS, COMBAT_PHASES, COMBAT_RANGES, COMBAT_STATE_MACHINE, COMBAT_TIMING, COMBAT_UI_DIMENSIONS, COMBAT_UI_DIMENSIONS_NUMERIC, COUNTER_STANCE_DAMAGE_MULTIPLIER, CYBERPUNK_COLORS, CombatAttackType, CombatControlsPanel, CombatReadinessState, CombatScreen3D, CombatScreen3D as CombatScreen3DDefault, CombatState, CombatStateSystem, CombatSystem, components_exports as Components, ConsciousnessBlur, ConsciousnessLevel, ConsciousnessSystem, ControlsGuide, DAMAGE_CONSTANTS, DAMAGE_TYPES, DAMAGE_TYPE_EFFECTIVENESS, DARK_OPS_ARCHETYPE_BONUSES, DARK_OPS_NIGHT_BONUS, DARK_OPS_SPECIAL_EFFECTS, DARK_OPS_TECHNIQUES, DARK_OPS_TECHNIQUE_COUNT, DARK_OPS_UNITS, DEFAULT_GAME_SPEED, DEFAULT_GRAPPLE_CONFIG, DEFAULT_RESIZE_TRANSITION, DEFAULT_ROW_HEIGHT, DIFFICULTY_PARAMETERS, DIFFICULTY_SETTINGS, DamageCalculator, DamageType, DeviceType, DifficultyIndicator, DifficultyTier, EFFECTIVENESS_MODIFIERS, ELEMENTAL_RELATIONS, ENERGY_MERIDIANS, ENERGY_MERIDIANS_ARRAY, ENHANCED_ANATOMICAL_ZONES, ENHANCED_DAMAGE_CONSTANTS, EffectIntensity, FALLBACK_ARCHETYPE_IMAGE, FONT_FAMILY, FONT_SCALE_MAP, FONT_SIZES, FONT_SIZE_CONSTRAINTS, FONT_SIZE_MULTIPLIERS, FONT_WEIGHTS, FPSMonitor, FRAME_TIME, FRAME_TIME_BUDGET, FingerType, GAME_CONFIG, GAME_METADATA, GAME_MODE_CONFIG, GAME_PHASES, GAME_STATES, GAM_TECHNIQUES, GAM_TECHNIQUE_COUNT, GAN_TECHNIQUES, GAN_TECHNIQUE_COUNT, GEON_TECHNIQUES, GON_TECHNIQUES, GON_TECHNIQUE_COUNT, GRADIENTS, GameEventType, GameMode, GamePhase, GrappleState, GrappleSystem, GrappleTarget, HALF_CANVAS_HEIGHT, HALF_CANVAS_WIDTH, HEALTH_COLORS, HIERARCHY, HIT_DETECTION, HUD_HEIGHT, HUD_STYLE, HUD_WIDTH_PERCENT, HandPoseType, HitDetection, HitEffectEnum, HitEffectType, INPUT_CONSTANTS, InputBufferDisplay, JIN_TECHNIQUES, KEYBOARD_MAPPING, KOREAN_ANATOMICAL_ZONES, KOREAN_ANATOMICAL_ZONES_ARRAY, KOREAN_COLORS, KOREAN_FONT_WEIGHTS, KOREAN_MOBILE_FONT_SIZES, KOREAN_TECHNIQUE_CATEGORIES, KOREAN_TEXT_SIZES, KOREAN_VITAL_POINTS, KeyboardHints, KoreanAnatomySystem, KoreanButton, KoreanCulture, KoreanPanel, KoreanTechniquesSystem, KoreanText as KoreanText3D, KoreanTextSize, KoreanTextWeight, LAYOUT_MULTIPLIERS, LI_TECHNIQUES, LayoutSystem, MARTIAL_ARTS_CONFIG, MAX_TRANSITION_COST_KI, MAX_TRANSITION_COST_STAMINA, MAX_TRANSITION_TIME_MILLISECONDS, MOBILE_BREAKPOINT, MatchCountdown, MenuList, MobileControlsWrapper, OPACITY, PERFORMANCE_CONFIG, PERFORMANCE_RATING_THRESHOLDS, PERFORMANCE_SETTINGS_BY_TIER, PERFORMANCE_THRESHOLDS, PLAYER_ARCHETYPES_DATA, PLAYER_COLORS, PLAYER_DISTANCE, PainLevel, PainResponseSystem, PainVignette, PauseMenu, PlayerArchetype, PlayerStateOverlayHtml, ProgressBar, QuickSettings, RESOURCE_COSTS, RESPONSIVE_BREAKPOINTS, ROUND_ANNOUNCEMENT_TIMINGS, RoundAnnouncement, RoundDisplayStatus, RoundStartAnnouncement, SAMPLE_VITAL_POINTS, SON_TECHNIQUES, SON_TECHNIQUE_COUNT, SPACING, SPACING_ADJUSTMENTS, SPACING_NUMERIC, SPACING_SCALE_MAP, STANCE_COUNTERS, STANCE_EFFECTIVENESS_MATRIX, STANCE_REACH_MODIFIERS, STATUS_DURATIONS, StaminaWarning, StanceManager, systems_exports as Systems, TABLET_BREAKPOINT, TAE_TECHNIQUES, TECHNIQUE_DIFFICULTY_LEVELS, TECHNIQUE_EFFECTIVENESS_MATRIX, TECHNIQUE_MODIFIERS, TECHNIQUE_NAMING, TECHNIQUE_PROPERTIES, TECHNIQUE_RESULTS, TEXT_EFFECTS, TICK_RATE, TRAINING_COMBAT_SETTINGS, TRAINING_CONFIG, TRAINING_STATE_MACHINE, TRANSITIONS, TRIGRAM_DATA, TRIGRAM_STANCES_ORDER, TRIGRAM_TECHNIQUES, TRIGRAM_TECHNIQUE_PROPERTIES, TYPOGRAPHY, TYPOGRAPHY_NUMERIC, TechniqueNameDisplay, TrainingAI, TrainingCombatSystem, TrainingScreen3D, TransitionCalculator, TraumaOverlay3D, TrigramCalculator, TrigramStance, TrigramSystem, types_exports as Types, UI_CONSTANTS, UI_DIMENSIONS, UI_LAYOUT, utils_exports as Utils, VISUAL_EFFECTS, VITAL_POINT_MERIDIAN_MAP, VariantSelector, VitalPointCategory, VitalPointEffectType, VitalPointSeverity, VitalPointSystem, Z_INDEX, alignHorizontal, alignVertical, animationStateToPlayerAnimation, applyCounterStanceDamage, applyDamage, applyEffectModifiers, applyHtmlOverlayStyles, applyStatusEffect, assertValidPhysicalReachConfig, audioAssetRegistry, calculateAnatomicalVulnerability, calculateBreakingResult, calculateCombatEffectiveness, calculateCounterOpportunity, calculateDamageEffectiveness, calculateDistanceFactor, calculateEffectIntensity, calculateEnhancedVulnerability, calculateFontSize, calculateGridPosition, calculateMeridianFlow, calculateResponsiveValues, calculateSafePosition, calculateSpacing, calculateVulnerabilityMultiplier, canExecuteCounter, canPlayType, canPlayerAct, centerElement, checkForFall, clampVolume, clearPlatformCache, combineEffects, combineStanceWithSide, convertPlayerStateToProps, createAudioElement, createCameraConfig, createCombatResult, createEffectFromKoreanText, createHitEffect, createHtmlOverlayConfig, createKoreanStatusEffect, createPhysicsConfig, createPlayerFromArchetype, createResponsiveConfig, createStatusEffect, createTransitionString, createTrigramEffect, createVitalPointEffect, darkenColor, defaultLayoutSystem, detectPlatform, detectSupportedFormats, determineExposedLimb, enforceArchetypeBehavior, extractVitalPointCategory, findOptimalVitalPoints, followsHonorCode, formatDuration, formatPainConsciousnessDisplay, generateLimbExposureWindow, generateMeridianEffects, generateVulnerabilityHeatMap, getActionFrequency, getAllBreakingStatusEffectIds, getAllPersonalities, getAllTechniques, getAnatomicalZones, getArchetypeAssets, getArchetypeBehavior, getArchetypeBonuses, getArchetypeColors, getArchetypeSkinTone, getArchetypeVisualProperties, getAssetBasePath, getBalanceState, getBestFormatMetadata, getColorRGB, getColorWithAlpha, getContrastColor, getDarkOpsArchetypeBonus, getDarkOpsTechniqueById, getDarkOpsTechniquesByUnit, getDefaultSafeArea, getEffectDescription, getEffectDisplayText, getEffectDurationModifier, getEnhancedZonesByPosition, getFallTypeName, getFontScale, getGamTechniqueById, getGamTechniquesByType, getGanTechniqueById, getGanTechniquesByType, getGonTechniqueById, getGonTechniquesByType, getHealthColor, getHitEffectColor, getKoreanFontSize, getMeridian, getMeridianMappingStatistics, getMeridiansByElement, getMeridiansForVitalPoint, getNextComboTechnique, getOptimalFormat, getOptimalRange, getPainConsciousnessStatus, getPerformanceSettings, getPerformanceTier, getPersonalityByArchetype, getPersonalityByName, getPlayerAnimation, getPlayerLeadFoot, getPlayerRearFoot, getPreferredFormat, getRandomPersonality, getRecommendedRecoveryTime, getRegionBoundaries, getRegionForPosition, getResponsiveFontSize, getResponsiveSpacing, getSafeAreaInsets, getScreenSize, getShockPainRemainingDuration, getSignatureMove, getSonTechniqueById, getSonTechniquesByType, getSpacingScale, getStanceEffectiveness, getStanceFromKey, getTechniqueById, getTechniqueCountByStance, getTechniquesByStance, getTotalTechniqueCount, getTrigramKey, getTrigramProperties, getVitalPointById, getVitalPointByOnPlayerId, getVitalPointsByCategory, getVitalPointsByDifficulty, getVitalPointsByRegion, getVitalPointsBySeverity, getVitalPointsByStance, getVitalPointsForMeridian, getVitalPointsInRegion, getVitalPointsStats, getZIndexForLayer, getZoneByPosition, groupEffectsByType, groupEffectsByTypeEnum, hasEnoughResources, hexColorToCSS, hexToRgb, hexToRgbaString, initializeBodyFacing, interpolateColor, interpolateDifficultyParameters, isActionProhibited, isAudioSupported, isBreakingStatusEffectId, isDesktopSize, isEffectBeneficial, isHeadTraumaHit, isInFallOrGroundState, isMobileDevice, isMobileSize, isPointInPolygon, isPositionInEnhancedZone, isPositionInRegion, isShockPainActive, isTabletSize, isValidArchetype, isValidBaseExtension, isVitalPoint, isVitalPointCategory, isVitalPointOnMeridian, lightenColor, mapLimbToBreakingTarget, measureTextBounds, mirrorGuardPose, mixColors, normalizeVolume, parseStanceWithSide, removeExpiredEffects, resetPlayerState, resolveAssetPath, rgbToHex, selectAudioFormat, selectCombatMusic, selectCombatSound, selectHitSound, setAssetBasePath, shouldExecuteSignatureMove, shouldUseMobileControls, skillScoreToTier, testScreenSize, toHex, toHexColor, toggleStanceSide, updateEffect, updatePlayerState, updateStatusEffects, useAudio, validateAudioUrl };
116
+ export { AIActionType, AIComboSystem, AIDecisionTree, AI_PERSONALITIES, ANATOMICAL_DIMENSIONS, ANATOMICAL_REGIONS_DATA, ANIMATION_DURATIONS, ANIMATION_TIMINGS, ARCHETYPE_ASSETS, ARCHETYPE_BACKGROUNDS, ARCHETYPE_BEHAVIORS, ARCHETYPE_ENFORCEMENT, ARCHETYPE_SIGNATURE_COMBOS, ARCHETYPE_TECHNIQUE_BONUSES, AUDIO_DEFAULTS, AUDIO_FORMATS, AdaptiveDifficulty, App, ArchetypeCard, AttackAnimationType, audio_exports as Audio, AudioAssetRegistry, AudioCache, AudioCategory, AudioContext, AudioManager, AudioProvider, AudioUtils, BASE_PLAYER_STATS, BASE_REACH, BORDERS, BORDER_RADIUS, BREAKING_STATUS_EFFECT_IDS, BalanceIndicator, BalanceLevel, BalanceSystem, BloodDecals3D, BloodLossOverlayHtml, BloodParticles3D, BodyRegion, BoneName, CANVAS_ASPECT_RATIO, CENTER_POSITION_X, COLLISION_KOREAN_TERMS, COMBAT_AUDIO_MAP, COMBAT_CONFIG, COMBAT_CONSTANTS, COMBAT_CONTROLS, COMBAT_PHASES, COMBAT_RANGES, COMBAT_STATE_MACHINE, COMBAT_TIMING, COMBAT_UI_DIMENSIONS, COMBAT_UI_DIMENSIONS_NUMERIC, COUNTER_STANCE_DAMAGE_MULTIPLIER, CYBERPUNK_COLORS, CombatAttackType, CombatControlsPanel, CombatReadinessState, CombatScreen3D, CombatScreen3D as CombatScreen3DDefault, CombatState, CombatStateSystem, CombatSystem, components_exports as Components, ConsciousnessBlur, ConsciousnessLevel, ConsciousnessSystem, ControlsGuide, DAMAGE_CONSTANTS, DAMAGE_TYPES, DAMAGE_TYPE_EFFECTIVENESS, DARK_OPS_ARCHETYPE_BONUSES, DARK_OPS_NIGHT_BONUS, DARK_OPS_SPECIAL_EFFECTS, DARK_OPS_TECHNIQUES, DARK_OPS_TECHNIQUE_COUNT, DARK_OPS_UNITS, DEFAULT_GAME_SPEED, DEFAULT_GRAPPLE_CONFIG, DEFAULT_RESIZE_TRANSITION, DEFAULT_ROW_HEIGHT, DIFFICULTY_PARAMETERS, DIFFICULTY_SETTINGS, DamageCalculator, DamageType, data_exports as Data, DeviceType, DifficultyIndicator, DifficultyTier, EFFECTIVENESS_MODIFIERS, ELEMENTAL_RELATIONS, ENERGY_MERIDIANS, ENERGY_MERIDIANS_ARRAY, ENHANCED_ANATOMICAL_ZONES, ENHANCED_DAMAGE_CONSTANTS, EffectIntensity, FALLBACK_ARCHETYPE_IMAGE, FONT_FAMILY, FONT_SCALE_MAP, FONT_SIZES, FONT_SIZE_CONSTRAINTS, FONT_SIZE_MULTIPLIERS, FONT_WEIGHTS, FPSMonitor, FRAME_TIME, FRAME_TIME_BUDGET, FingerType, GAME_CONFIG, GAME_METADATA, GAME_MODE_CONFIG, GAME_PHASES, GAME_STATES, GAM_TECHNIQUES, GAM_TECHNIQUE_COUNT, GAN_TECHNIQUES, GAN_TECHNIQUE_COUNT, GEON_TECHNIQUES, GON_TECHNIQUES, GON_TECHNIQUE_COUNT, GRADIENTS, GameEventType, GameMode, GamePhase, GrappleState, GrappleSystem, GrappleTarget, HALF_CANVAS_HEIGHT, HALF_CANVAS_WIDTH, HEALTH_COLORS, HIERARCHY, HIT_DETECTION, HUD_HEIGHT, HUD_STYLE, HUD_WIDTH_PERCENT, HandPoseType, HitDetection, HitEffectEnum, HitEffectType, hooks_exports as Hooks, INPUT_CONSTANTS, InputBufferDisplay, JIN_TECHNIQUES, KEYBOARD_MAPPING, KOREAN_ANATOMICAL_ZONES, KOREAN_ANATOMICAL_ZONES_ARRAY, KOREAN_COLORS, KOREAN_FONT_WEIGHTS, KOREAN_MOBILE_FONT_SIZES, KOREAN_TECHNIQUE_CATEGORIES, KOREAN_TEXT_SIZES, KOREAN_VITAL_POINTS, KeyboardHints, KoreanAnatomySystem, KoreanButton, KoreanCulture, KoreanPanel, KoreanTechniquesSystem, KoreanText as KoreanText3D, KoreanTextSize, KoreanTextWeight, LAYOUT_MULTIPLIERS, LI_TECHNIQUES, LayoutSystem, MARTIAL_ARTS_CONFIG, MAX_TRANSITION_COST_KI, MAX_TRANSITION_COST_STAMINA, MAX_TRANSITION_TIME_MILLISECONDS, MOBILE_BREAKPOINT, MatchCountdown, MenuList, MobileControlsWrapper, OPACITY, PERFORMANCE_CONFIG, PERFORMANCE_RATING_THRESHOLDS, PERFORMANCE_SETTINGS_BY_TIER, PERFORMANCE_THRESHOLDS, PLAYER_ARCHETYPES_DATA, PLAYER_COLORS, PLAYER_DISTANCE, PainLevel, PainResponseSystem, PainVignette, PauseMenu, PlayerArchetype, PlayerStateOverlayHtml, ProgressBar, QuickSettings, RESOURCE_COSTS, RESPONSIVE_BREAKPOINTS, ROUND_ANNOUNCEMENT_TIMINGS, RoundAnnouncement, RoundDisplayStatus, RoundStartAnnouncement, SAMPLE_VITAL_POINTS, SON_TECHNIQUES, SON_TECHNIQUE_COUNT, SPACING, SPACING_ADJUSTMENTS, SPACING_NUMERIC, SPACING_SCALE_MAP, STANCE_COUNTERS, STANCE_EFFECTIVENESS_MATRIX, STANCE_REACH_MODIFIERS, STATUS_DURATIONS, StaminaWarning, StanceManager, systems_exports as Systems, TABLET_BREAKPOINT, TAE_TECHNIQUES, TECHNIQUE_DIFFICULTY_LEVELS, TECHNIQUE_EFFECTIVENESS_MATRIX, TECHNIQUE_MODIFIERS, TECHNIQUE_NAMING, TECHNIQUE_PROPERTIES, TECHNIQUE_RESULTS, TEXT_EFFECTS, TICK_RATE, TRAINING_COMBAT_SETTINGS, TRAINING_CONFIG, TRAINING_STATE_MACHINE, TRANSITIONS, TRIGRAM_DATA, TRIGRAM_STANCES_ORDER, TRIGRAM_TECHNIQUES, TRIGRAM_TECHNIQUE_PROPERTIES, TYPOGRAPHY, TYPOGRAPHY_NUMERIC, TechniqueNameDisplay, TrainingAI, TrainingCombatSystem, TrainingScreen3D, TransitionCalculator, TraumaOverlay3D, TrigramCalculator, TrigramStance, TrigramSystem, types_exports as Types, UI_CONSTANTS, UI_DIMENSIONS, UI_LAYOUT, utils_exports as Utils, VISUAL_EFFECTS, VITAL_POINT_MERIDIAN_MAP, VariantSelector, VitalPointCategory, VitalPointEffectType, VitalPointSeverity, VitalPointSystem, Z_INDEX, alignHorizontal, alignVertical, animationStateToPlayerAnimation, applyCounterStanceDamage, applyDamage, applyEffectModifiers, applyHtmlOverlayStyles, applyStatusEffect, assertValidPhysicalReachConfig, audioAssetRegistry, calculateAnatomicalVulnerability, calculateBreakingResult, calculateCombatEffectiveness, calculateCounterOpportunity, calculateDamageEffectiveness, calculateDistanceFactor, calculateEffectIntensity, calculateEnhancedVulnerability, calculateFontSize, calculateGridPosition, calculateMeridianFlow, calculateResponsiveValues, calculateSafePosition, calculateSpacing, calculateVulnerabilityMultiplier, canExecuteCounter, canPlayType, canPlayerAct, centerElement, checkForFall, clampVolume, clearPlatformCache, combineEffects, combineStanceWithSide, convertPlayerStateToProps, createAudioElement, createCameraConfig, createCombatResult, createEffectFromKoreanText, createHitEffect, createHtmlOverlayConfig, createKoreanStatusEffect, createPhysicsConfig, createPlayerFromArchetype, createResponsiveConfig, createStatusEffect, createTransitionString, createTrigramEffect, createVitalPointEffect, darkenColor, defaultLayoutSystem, detectPlatform, detectSupportedFormats, determineExposedLimb, enforceArchetypeBehavior, extractVitalPointCategory, findOptimalVitalPoints, followsHonorCode, formatDuration, formatPainConsciousnessDisplay, generateLimbExposureWindow, generateMeridianEffects, generateVulnerabilityHeatMap, getActionFrequency, getAllBreakingStatusEffectIds, getAllPersonalities, getAllTechniques, getAnatomicalZones, getArchetypeAssets, getArchetypeBehavior, getArchetypeBonuses, getArchetypeColors, getArchetypeSkinTone, getArchetypeVisualProperties, getAssetBasePath, getBalanceState, getBestFormatMetadata, getColorRGB, getColorWithAlpha, getContrastColor, getDarkOpsArchetypeBonus, getDarkOpsTechniqueById, getDarkOpsTechniquesByUnit, getDefaultSafeArea, getEffectDescription, getEffectDisplayText, getEffectDurationModifier, getEnhancedZonesByPosition, getFallTypeName, getFontScale, getGamTechniqueById, getGamTechniquesByType, getGanTechniqueById, getGanTechniquesByType, getGonTechniqueById, getGonTechniquesByType, getHealthColor, getHitEffectColor, getKoreanFontSize, getMeridian, getMeridianMappingStatistics, getMeridiansByElement, getMeridiansForVitalPoint, getNextComboTechnique, getOptimalFormat, getOptimalRange, getPainConsciousnessStatus, getPerformanceSettings, getPerformanceTier, getPersonalityByArchetype, getPersonalityByName, getPlayerAnimation, getPlayerLeadFoot, getPlayerRearFoot, getPreferredFormat, getRandomPersonality, getRecommendedRecoveryTime, getRegionBoundaries, getRegionForPosition, getResponsiveFontSize, getResponsiveSpacing, getSafeAreaInsets, getScreenSize, getShockPainRemainingDuration, getSignatureMove, getSonTechniqueById, getSonTechniquesByType, getSpacingScale, getStanceEffectiveness, getStanceFromKey, getTechniqueById, getTechniqueCountByStance, getTechniquesByStance, getTotalTechniqueCount, getTrigramKey, getTrigramProperties, getVitalPointById, getVitalPointByOnPlayerId, getVitalPointsByCategory, getVitalPointsByDifficulty, getVitalPointsByRegion, getVitalPointsBySeverity, getVitalPointsByStance, getVitalPointsForMeridian, getVitalPointsInRegion, getVitalPointsStats, getZIndexForLayer, getZoneByPosition, groupEffectsByType, groupEffectsByTypeEnum, hasEnoughResources, hexColorToCSS, hexToRgb, hexToRgbaString, initializeBodyFacing, interpolateColor, interpolateDifficultyParameters, isActionProhibited, isAudioSupported, isBreakingStatusEffectId, isDesktopSize, isEffectBeneficial, isHeadTraumaHit, isInFallOrGroundState, isMobileDevice, isMobileSize, isPointInPolygon, isPositionInEnhancedZone, isPositionInRegion, isShockPainActive, isTabletSize, isValidArchetype, isValidBaseExtension, isVitalPoint, isVitalPointCategory, isVitalPointOnMeridian, lightenColor, mapLimbToBreakingTarget, measureTextBounds, mirrorGuardPose, mixColors, normalizeVolume, parseStanceWithSide, removeExpiredEffects, resetPlayerState, resolveAssetPath, rgbToHex, selectAudioFormat, selectCombatMusic, selectCombatSound, selectHitSound, setAssetBasePath, shouldExecuteSignatureMove, shouldUseMobileControls, skillScoreToTier, testScreenSize, toHex, toHexColor, toggleStanceSide, updateEffect, updatePlayerState, updateStatusEffects, useAudio, validateAudioUrl };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "blacktrigram",
3
- "version": "0.7.6",
3
+ "version": "0.7.9",
4
4
  "description": "Black Trigram (흑괘) - Korean Martial Arts Combat Simulator. Reusable game systems, combat mechanics, animation framework, and Korean martial arts data built with React, Three.js, and TypeScript.",
5
5
  "type": "module",
6
6
  "main": "./lib/index.js",
@@ -30,13 +30,29 @@
30
30
  "./components": {
31
31
  "types": "./lib/components/index.d.ts",
32
32
  "import": "./lib/components/index.js"
33
+ },
34
+ "./hooks": {
35
+ "types": "./lib/hooks/index.d.ts",
36
+ "import": "./lib/hooks/index.js"
37
+ },
38
+ "./data": {
39
+ "types": "./lib/data/index.d.ts",
40
+ "import": "./lib/data/index.js"
33
41
  }
34
42
  },
35
43
  "files": [
36
44
  "lib",
37
45
  "README.md",
38
46
  "LICENSE",
39
- "SECURITY.md"
47
+ "SECURITY.md",
48
+ "ARCHITECTURE.md",
49
+ "SECURITY_ARCHITECTURE.md",
50
+ "COMBAT_ARCHITECTURE.md",
51
+ "DATA_MODEL.md",
52
+ "THREAT_MODEL.md",
53
+ "ISMS_REFERENCE_MAPPING.md",
54
+ "CONTROLS.md",
55
+ "CRA-ASSESSMENT.md"
40
56
  ],
41
57
  "keywords": [
42
58
  "korean-martial-arts",
@@ -157,7 +173,7 @@
157
173
  "three": "^0.183.0"
158
174
  },
159
175
  "devDependencies": {
160
- "@aws-sdk/client-bedrock-runtime": "3.1019.0",
176
+ "@aws-sdk/client-bedrock-runtime": "3.1021.0",
161
177
  "@eslint/js": "10.0.1",
162
178
  "@react-three/drei": "10.7.7",
163
179
  "@react-three/fiber": "9.5.0",
@@ -185,7 +201,7 @@
185
201
  "globals": "17.4.0",
186
202
  "jest-axe": "10.0.0",
187
203
  "jsdom": "29.0.1",
188
- "knip": "6.1.0",
204
+ "knip": "6.1.1",
189
205
  "license-compliance": "3.0.1",
190
206
  "mocha-junit-reporter": "2.2.1",
191
207
  "mochawesome": "7.1.4",
@@ -206,8 +222,8 @@
206
222
  "typedoc-plugin-markdown": "4.11.0",
207
223
  "typedoc-plugin-mermaid": "1.12.0",
208
224
  "typedoc-plugin-missing-exports": "4.1.2",
209
- "typescript": "5.9.3",
210
- "typescript-eslint": "8.57.2",
225
+ "typescript": "6.0.2",
226
+ "typescript-eslint": "8.58.0",
211
227
  "vite": "8.0.3",
212
228
  "vite-bundle-analyzer": "1.3.6",
213
229
  "vite-tsconfig-paths": "6.1.1",