@buley/hexgrid-3d 1.0.0 → 1.1.1

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 (58) hide show
  1. package/build_log.txt +500 -0
  2. package/build_src_log.txt +8 -0
  3. package/examples/basic-usage.tsx +19 -19
  4. package/package.json +1 -1
  5. package/public/hexgrid-worker.js +2350 -1638
  6. package/site/.eslintrc.json +3 -0
  7. package/site/DEPLOYMENT.md +196 -0
  8. package/site/INDEX.md +127 -0
  9. package/site/QUICK_START.md +86 -0
  10. package/site/README.md +85 -0
  11. package/site/SITE_SUMMARY.md +180 -0
  12. package/site/next.config.js +12 -0
  13. package/site/package.json +26 -0
  14. package/site/src/app/docs/page.tsx +148 -0
  15. package/site/src/app/examples/page.tsx +133 -0
  16. package/site/src/app/globals.css +160 -0
  17. package/site/src/app/layout.tsx +29 -0
  18. package/site/src/app/page.tsx +163 -0
  19. package/site/tsconfig.json +29 -0
  20. package/site/vercel.json +6 -0
  21. package/src/Snapshot.ts +790 -585
  22. package/src/adapters/DashAdapter.ts +57 -0
  23. package/src/adapters.ts +16 -18
  24. package/src/algorithms/AdvancedStatistics.ts +58 -24
  25. package/src/algorithms/BayesianStatistics.ts +43 -12
  26. package/src/algorithms/FlowField.ts +30 -6
  27. package/src/algorithms/FlowField3D.ts +573 -0
  28. package/src/algorithms/FluidSimulation.ts +19 -3
  29. package/src/algorithms/FluidSimulation3D.ts +664 -0
  30. package/src/algorithms/GraphAlgorithms.ts +19 -12
  31. package/src/algorithms/OutlierDetection.ts +72 -38
  32. package/src/algorithms/ParticleSystem.ts +12 -2
  33. package/src/algorithms/ParticleSystem3D.ts +567 -0
  34. package/src/algorithms/index.ts +14 -8
  35. package/src/compat.ts +10 -10
  36. package/src/components/HexGrid.tsx +10 -23
  37. package/src/components/NarrationOverlay.tsx +140 -52
  38. package/src/components/index.ts +2 -1
  39. package/src/features.ts +31 -31
  40. package/src/index.ts +11 -11
  41. package/src/lib/narration.ts +17 -0
  42. package/src/lib/stats-tracker.ts +25 -0
  43. package/src/lib/theme-colors.ts +12 -0
  44. package/src/math/HexCoordinates.ts +849 -4
  45. package/src/math/Matrix4.ts +2 -12
  46. package/src/math/Vector3.ts +49 -1
  47. package/src/math/index.ts +6 -6
  48. package/src/note-adapter.ts +50 -42
  49. package/src/ontology-adapter.ts +30 -23
  50. package/src/stores/uiStore.ts +34 -34
  51. package/src/types/shared-utils.d.ts +10 -0
  52. package/src/types.ts +110 -98
  53. package/src/utils/image-utils.ts +9 -6
  54. package/src/wasm/HexGridWasmWrapper.ts +436 -388
  55. package/src/wasm/index.ts +2 -2
  56. package/src/workers/hexgrid-math.ts +40 -35
  57. package/src/workers/hexgrid-worker.worker.ts +1992 -1018
  58. package/tsconfig.json +21 -14
@@ -159,7 +159,9 @@ export function detectGrowthSpikes(values: number[]): TimeSeriesAnomaly[] {
159
159
  });
160
160
  }
161
161
 
162
- export function detectVarianceChanges(values: number[]): VarianceChangeResult[] {
162
+ export function detectVarianceChanges(
163
+ values: number[]
164
+ ): VarianceChangeResult[] {
163
165
  if (values.length < 6) return [];
164
166
  const results: VarianceChangeResult[] = [];
165
167
  const windowSize = Math.max(3, Math.floor(values.length / 4));
@@ -171,7 +173,8 @@ export function detectVarianceChanges(values: number[]): VarianceChangeResult[]
171
173
  const afterMean = mean(after);
172
174
  const beforeVar = stdDev(before, beforeMean) ** 2;
173
175
  const afterVar = stdDev(after, afterMean) ** 2;
174
- const ratio = beforeVar === 0 ? (afterVar === 0 ? 1 : Infinity) : afterVar / beforeVar;
176
+ const ratio =
177
+ beforeVar === 0 ? (afterVar === 0 ? 1 : Infinity) : afterVar / beforeVar;
175
178
 
176
179
  results.push({
177
180
  index: i,
@@ -199,18 +202,22 @@ export interface GameAnomaly {
199
202
  description: string;
200
203
  }
201
204
 
202
- export function detectGameAnomalies(values: number[], windowSize: number = 5): GameAnomaly[] {
205
+ export function detectGameAnomalies(
206
+ values: number[],
207
+ windowSize: number = 5
208
+ ): GameAnomaly[] {
203
209
  const anomalies: GameAnomaly[] = [];
204
210
  if (values.length < windowSize * 2) return anomalies;
205
-
211
+
206
212
  for (let i = windowSize; i < values.length - windowSize; i++) {
207
213
  const before = values.slice(i - windowSize, i);
208
214
  const after = values.slice(i, i + windowSize);
209
215
  const beforeMean = before.reduce((s, v) => s + v, 0) / before.length;
210
216
  const afterMean = after.reduce((s, v) => s + v, 0) / after.length;
211
217
  const change = Math.abs(afterMean - beforeMean);
212
- const threshold = before.reduce((s, v) => s + Math.abs(v - beforeMean), 0) / before.length;
213
-
218
+ const threshold =
219
+ before.reduce((s, v) => s + Math.abs(v - beforeMean), 0) / before.length;
220
+
214
221
  if (change > threshold * 2) {
215
222
  anomalies.push({
216
223
  index: i,
@@ -220,7 +227,7 @@ export function detectGameAnomalies(values: number[], windowSize: number = 5): G
220
227
  });
221
228
  }
222
229
  }
223
-
230
+
224
231
  return anomalies;
225
232
  }
226
233
 
@@ -231,22 +238,32 @@ export interface MultivariateOutlierResult {
231
238
  method: string;
232
239
  }
233
240
 
234
- export function comprehensiveOutlierAnalysis(values: number[]): MultivariateOutlierResult {
241
+ export function comprehensiveOutlierAnalysis(
242
+ values: number[]
243
+ ): MultivariateOutlierResult {
235
244
  const zScore = detectOutliersZScore(values);
236
245
  const iqr = detectOutliersIQR(values);
237
246
  const combined = new Set([...zScore.outlierIndices, ...iqr.outlierIndices]);
238
-
247
+
239
248
  return {
240
249
  outliers: Array.from(combined),
241
- scores: values.map((v, i) =>
242
- combined.has(i) ? Math.max(Math.abs(zScore.scores[i] ?? 0), Math.abs(iqr.scores[i] ?? 0)) : 0
250
+ scores: values.map((v, i) =>
251
+ combined.has(i)
252
+ ? Math.max(
253
+ Math.abs(zScore.scores[i] ?? 0),
254
+ Math.abs(iqr.scores[i] ?? 0)
255
+ )
256
+ : 0
243
257
  ),
244
258
  method: 'comprehensive',
245
259
  };
246
260
  }
247
261
 
248
262
  // Local Outlier Factor (simplified)
249
- export function localOutlierFactor(values: number[], k: number = 5): OutlierResult {
263
+ export function localOutlierFactor(
264
+ values: number[],
265
+ k: number = 5
266
+ ): OutlierResult {
250
267
  // Simplified LOF implementation
251
268
  if (values.length < k + 1) {
252
269
  return {
@@ -256,32 +273,33 @@ export function localOutlierFactor(values: number[], k: number = 5): OutlierResu
256
273
  threshold: 1.5,
257
274
  };
258
275
  }
259
-
276
+
260
277
  const scores: number[] = [];
261
278
  for (let i = 0; i < values.length; i++) {
262
- const distances = values.map((v, j) =>
263
- i === j ? Infinity : Math.abs(v - values[i]!)
264
- ).sort((a, b) => a - b);
279
+ const distances = values
280
+ .map((v, j) => (i === j ? Infinity : Math.abs(v - values[i]!)))
281
+ .sort((a, b) => a - b);
265
282
  const kthDistance = distances[k] ?? 0;
266
- const reachability = values.map((v, j) =>
283
+ const reachability = values.map((v, j) =>
267
284
  Math.max(kthDistance, Math.abs(v - values[i]!))
268
285
  );
269
286
  const lrd = k / reachability.reduce((s, r) => s + r, 0);
270
287
  scores.push(lrd);
271
288
  }
272
-
289
+
273
290
  const avgLrd = scores.reduce((s, lrd) => s + lrd, 0) / scores.length;
274
- const lofScores = scores.map(lrd => lrd === 0 ? 0 : avgLrd / lrd);
291
+ const lofScores = scores.map((lrd) => (lrd === 0 ? 0 : avgLrd / lrd));
275
292
  const threshold = 1.5;
276
293
  const outlierIndices = lofScores
277
294
  .map((score, idx) => ({ score, idx }))
278
295
  .filter(({ score }) => score > threshold)
279
296
  .map(({ idx }) => idx);
280
-
297
+
281
298
  const avg = values.reduce((s, v) => s + v, 0) / values.length;
282
- const variance = values.reduce((s, v) => s + Math.pow(v - avg, 2), 0) / values.length;
299
+ const variance =
300
+ values.reduce((s, v) => s + Math.pow(v - avg, 2), 0) / values.length;
283
301
  const stdDev = Math.sqrt(variance);
284
-
302
+
285
303
  return {
286
304
  outlierIndices,
287
305
  scores: lofScores,
@@ -291,11 +309,15 @@ export function localOutlierFactor(values: number[], k: number = 5): OutlierResu
291
309
  }
292
310
 
293
311
  // Isolation Forest (simplified)
294
- export function isolationForest(values: number[], trees: number = 100, samples: number = 256): OutlierResult {
312
+ export function isolationForest(
313
+ values: number[],
314
+ trees: number = 100,
315
+ samples: number = 256
316
+ ): OutlierResult {
295
317
  // Simplified isolation forest
296
318
  const scores: number[] = [];
297
319
  const sampleSize = Math.min(samples, values.length);
298
-
320
+
299
321
  for (let i = 0; i < values.length; i++) {
300
322
  let pathLengthSum = 0;
301
323
  for (let t = 0; t < trees; t++) {
@@ -313,17 +335,18 @@ export function isolationForest(values: number[], trees: number = 100, samples:
313
335
  const anomalyScore = Math.pow(2, -avgPathLength / Math.log2(sampleSize));
314
336
  scores.push(anomalyScore);
315
337
  }
316
-
338
+
317
339
  const threshold = 0.5;
318
340
  const outlierIndices = scores
319
341
  .map((score, idx) => ({ score, idx }))
320
342
  .filter(({ score }) => score > threshold)
321
343
  .map(({ idx }) => idx);
322
-
344
+
323
345
  const avg = values.reduce((s, v) => s + v, 0) / values.length;
324
- const variance = values.reduce((s, v) => s + Math.pow(v - avg, 2), 0) / values.length;
346
+ const variance =
347
+ values.reduce((s, v) => s + Math.pow(v - avg, 2), 0) / values.length;
325
348
  const stdDev = Math.sqrt(variance);
326
-
349
+
327
350
  return {
328
351
  outlierIndices,
329
352
  scores,
@@ -333,16 +356,21 @@ export function isolationForest(values: number[], trees: number = 100, samples:
333
356
  }
334
357
 
335
358
  // CUSUM Chart
336
- export function cusumChart(values: number[], target: number, h: number = 5, k: number = 0.5): TimeSeriesAnomaly[] {
359
+ export function cusumChart(
360
+ values: number[],
361
+ target: number,
362
+ h: number = 5,
363
+ k: number = 0.5
364
+ ): TimeSeriesAnomaly[] {
337
365
  const anomalies: TimeSeriesAnomaly[] = [];
338
366
  let sPos = 0;
339
367
  let sNeg = 0;
340
-
368
+
341
369
  for (let i = 0; i < values.length; i++) {
342
370
  const deviation = values[i]! - target;
343
371
  sPos = Math.max(0, sPos + deviation - k);
344
372
  sNeg = Math.max(0, sNeg - deviation - k);
345
-
373
+
346
374
  if (sPos > h || sNeg > h) {
347
375
  anomalies.push({
348
376
  index: i,
@@ -355,25 +383,31 @@ export function cusumChart(values: number[], target: number, h: number = 5, k: n
355
383
  });
356
384
  }
357
385
  }
358
-
386
+
359
387
  return anomalies;
360
388
  }
361
389
 
362
390
  // EWMA Chart (Exponentially Weighted Moving Average)
363
- export function ewmaChart(values: number[], lambda: number = 0.2, lcl: number = -3, ucl: number = 3): TimeSeriesAnomaly[] {
391
+ export function ewmaChart(
392
+ values: number[],
393
+ lambda: number = 0.2,
394
+ lcl: number = -3,
395
+ ucl: number = 3
396
+ ): TimeSeriesAnomaly[] {
364
397
  const anomalies: TimeSeriesAnomaly[] = [];
365
398
  if (values.length === 0) return anomalies;
366
-
399
+
367
400
  let ewma = values[0]!;
368
401
  const mean = values.reduce((s, v) => s + v, 0) / values.length;
369
- const variance = values.reduce((s, v) => s + Math.pow(v - mean, 2), 0) / values.length;
402
+ const variance =
403
+ values.reduce((s, v) => s + Math.pow(v - mean, 2), 0) / values.length;
370
404
  const stdDev = Math.sqrt(variance);
371
405
  const ewmaStdDev = stdDev * Math.sqrt(lambda / (2 - lambda));
372
-
406
+
373
407
  for (let i = 1; i < values.length; i++) {
374
408
  ewma = lambda * values[i]! + (1 - lambda) * ewma;
375
409
  const zScore = (ewma - mean) / (ewmaStdDev || 1);
376
-
410
+
377
411
  if (zScore < lcl || zScore > ucl) {
378
412
  anomalies.push({
379
413
  index: i,
@@ -386,6 +420,6 @@ export function ewmaChart(values: number[], lambda: number = 0.2, lcl: number =
386
420
  });
387
421
  }
388
422
  }
389
-
423
+
390
424
  return anomalies;
391
425
  }
@@ -44,7 +44,15 @@ export class ParticleEffectManager {
44
44
  this.systems.set('default', new ParticleSystem());
45
45
  }
46
46
 
47
- triggerEffect(effect: ParticleEffect, position: Vector2, options?: { count?: number; color?: [number, number, number]; velocity?: Vector2 }): void {
47
+ triggerEffect(
48
+ effect: ParticleEffect,
49
+ position: Vector2,
50
+ options?: {
51
+ count?: number;
52
+ color?: [number, number, number];
53
+ velocity?: Vector2;
54
+ }
55
+ ): void {
48
56
  const system = this.systems.get('default');
49
57
  if (!system) return;
50
58
  const count = options?.count ?? 1;
@@ -54,7 +62,9 @@ export class ParticleEffectManager {
54
62
  x: position.x,
55
63
  y: position.y,
56
64
  size: 4,
57
- color: `rgb(${Math.round(color[0] * 255)}, ${Math.round(color[1] * 255)}, ${Math.round(color[2] * 255)})`,
65
+ color: `rgb(${Math.round(color[0] * 255)}, ${Math.round(
66
+ color[1] * 255
67
+ )}, ${Math.round(color[2] * 255)})`,
58
68
  alpha: 1,
59
69
  });
60
70
  }