@tomaszjarosz/react-visualizers 0.2.7 → 0.2.11

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.
package/dist/index.d.ts CHANGED
@@ -203,6 +203,8 @@ declare type SortingAlgorithm = 'bubble' | 'selection' | 'insertion' | 'quick' |
203
203
  export declare const SortingComparisonVisualizer: default_2.NamedExoticComponent<SortingComparisonVisualizerProps>;
204
204
 
205
205
  declare interface SortingComparisonVisualizerProps {
206
+ showControls?: boolean;
207
+ showCode?: boolean;
206
208
  className?: string;
207
209
  }
208
210
 
package/dist/index.js CHANGED
@@ -1208,6 +1208,46 @@ const ALGORITHM_COMPLEXITIES$1 = {
1208
1208
  quick: { time: "O(n log n)", space: "O(log n)" },
1209
1209
  merge: { time: "O(n log n)", space: "O(n)" }
1210
1210
  };
1211
+ const ALGORITHM_CODE$1 = {
1212
+ bubble: [
1213
+ "for (i = 0; i < n-1; i++)",
1214
+ " for (j = 0; j < n-i-1; j++)",
1215
+ " if (arr[j] > arr[j+1])",
1216
+ " swap(arr[j], arr[j+1])"
1217
+ ],
1218
+ selection: [
1219
+ "for (i = 0; i < n-1; i++)",
1220
+ " minIdx = i",
1221
+ " for (j = i+1; j < n; j++)",
1222
+ " if (arr[j] < arr[minIdx])",
1223
+ " minIdx = j",
1224
+ " swap(arr[i], arr[minIdx])"
1225
+ ],
1226
+ insertion: [
1227
+ "for (i = 1; i < n; i++)",
1228
+ " key = arr[i]",
1229
+ " j = i - 1",
1230
+ " while (j >= 0 && arr[j] > key)",
1231
+ " arr[j+1] = arr[j]",
1232
+ " j--",
1233
+ " arr[j+1] = key"
1234
+ ],
1235
+ quick: [
1236
+ "quickSort(arr, low, high)",
1237
+ " if (low < high)",
1238
+ " pi = partition(arr, low, high)",
1239
+ " quickSort(arr, low, pi-1)",
1240
+ " quickSort(arr, pi+1, high)"
1241
+ ],
1242
+ merge: [
1243
+ "mergeSort(arr, l, r)",
1244
+ " if (l < r)",
1245
+ " m = (l + r) / 2",
1246
+ " mergeSort(arr, l, m)",
1247
+ " mergeSort(arr, m+1, r)",
1248
+ " merge(arr, l, m, r)"
1249
+ ]
1250
+ };
1211
1251
  const BINARY_SEARCH_CODE = [
1212
1252
  "binarySearch(arr, target):",
1213
1253
  " left = 0, right = n - 1",
@@ -1494,11 +1534,64 @@ const BinarySearchVisualizerComponent = ({
1494
1534
  ] }) }),
1495
1535
  /* @__PURE__ */ jsx("div", { className: "p-4", children: /* @__PURE__ */ jsxs("div", { className: `flex gap-4 ${showCode ? "flex-col lg:flex-row" : ""}`, children: [
1496
1536
  /* @__PURE__ */ jsxs(VisualizationArea, { minHeight: 350, children: [
1537
+ /* @__PURE__ */ jsxs("div", { className: "mb-4 p-4 bg-gradient-to-r from-green-50 to-emerald-50 rounded-xl border-2 border-green-200", children: [
1538
+ /* @__PURE__ */ jsxs("div", { className: "text-sm font-bold text-green-800 mb-3 flex items-center gap-2", children: [
1539
+ /* @__PURE__ */ jsx("span", { className: "text-lg", children: "🎯" }),
1540
+ " Binary Search Invariant"
1541
+ ] }),
1542
+ /* @__PURE__ */ jsxs("div", { className: "font-mono text-sm bg-white rounded-lg p-3 border border-green-200", children: [
1543
+ /* @__PURE__ */ jsx("div", { className: "text-center text-green-700 font-bold mb-2", children: "target ∈ arr[left..right]" }),
1544
+ /* @__PURE__ */ jsx("div", { className: "text-xs text-gray-500 text-center", children: "If target exists, it must be within current search bounds" })
1545
+ ] }),
1546
+ left <= right && /* @__PURE__ */ jsxs("div", { className: "mt-3 p-2 bg-white rounded-lg border border-green-200", children: [
1547
+ /* @__PURE__ */ jsxs("div", { className: "flex justify-between items-center text-xs", children: [
1548
+ /* @__PURE__ */ jsxs("div", { children: [
1549
+ /* @__PURE__ */ jsx("span", { className: "font-semibold text-green-700", children: "Search space:" }),
1550
+ " ",
1551
+ /* @__PURE__ */ jsxs("span", { className: "font-mono", children: [
1552
+ "[",
1553
+ left,
1554
+ "..",
1555
+ right,
1556
+ "]"
1557
+ ] }),
1558
+ " = ",
1559
+ /* @__PURE__ */ jsx("span", { className: "font-bold text-green-600", children: right - left + 1 }),
1560
+ " elements"
1561
+ ] }),
1562
+ /* @__PURE__ */ jsx("div", { className: "text-gray-500", children: currentStep > 0 && /* @__PURE__ */ jsxs("span", { children: [
1563
+ "Eliminated: ",
1564
+ /* @__PURE__ */ jsxs("span", { className: "font-bold text-red-500", children: [
1565
+ Math.round((1 - (right - left + 1) / array.length) * 100),
1566
+ "%"
1567
+ ] })
1568
+ ] }) })
1569
+ ] }),
1570
+ mid >= 0 && /* @__PURE__ */ jsxs("div", { className: "mt-2 text-xs text-center text-gray-600", children: [
1571
+ "mid = ⌊(",
1572
+ left,
1573
+ " + ",
1574
+ right,
1575
+ ") / 2⌋ = ",
1576
+ /* @__PURE__ */ jsx("span", { className: "font-bold text-purple-600", children: mid })
1577
+ ] })
1578
+ ] }),
1579
+ found === true && /* @__PURE__ */ jsx("div", { className: "mt-3 p-2 bg-green-100 rounded-lg border border-green-300 text-center", children: /* @__PURE__ */ jsxs("span", { className: "text-green-800 font-bold", children: [
1580
+ "✓ Found in ",
1581
+ currentStep,
1582
+ " steps (log₂",
1583
+ array.length,
1584
+ " ≈ ",
1585
+ Math.ceil(Math.log2(array.length)),
1586
+ " max)"
1587
+ ] }) }),
1588
+ found === false && /* @__PURE__ */ jsx("div", { className: "mt-3 p-2 bg-red-100 rounded-lg border border-red-300 text-center", children: /* @__PURE__ */ jsx("span", { className: "text-red-800 font-bold", children: "✗ Not found - search space exhausted" }) })
1589
+ ] }),
1497
1590
  /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center gap-1 flex-wrap mb-4", children: array.map((value, index) => /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center", children: [
1498
1591
  /* @__PURE__ */ jsx(
1499
1592
  "div",
1500
1593
  {
1501
- className: `w-10 h-10 flex items-center justify-center rounded-lg font-medium text-sm transition-all duration-300 ${getElementStyle(index)}`,
1594
+ className: `w-10 h-10 flex items-center justify-center rounded-lg font-medium text-sm transition-colors duration-300 ${getElementStyle(index)}`,
1502
1595
  children: value
1503
1596
  }
1504
1597
  ),
@@ -2369,7 +2462,7 @@ const SortingVisualizerComponent = ({
2369
2462
  /* @__PURE__ */ jsx("div", { className: "flex items-end justify-center gap-1 h-48 bg-gray-50 rounded-lg p-4", children: bars.map((bar, index) => /* @__PURE__ */ jsxs(
2370
2463
  "div",
2371
2464
  {
2372
- className: `${getBarColor(bar.state)} rounded-t transition-all duration-200 flex items-end justify-center relative group`,
2465
+ className: `${getBarColor(bar.state)} rounded-t transition-colors duration-200 flex items-end justify-center relative group`,
2373
2466
  style: {
2374
2467
  height: `${bar.value / maxValue * 100}%`,
2375
2468
  width: `${Math.max(100 / bars.length - 1, 8)}%`,
@@ -2719,6 +2812,8 @@ function generateRandomArray(size) {
2719
2812
  return Array.from({ length: size }, () => Math.floor(Math.random() * 100) + 5);
2720
2813
  }
2721
2814
  const SortingComparisonVisualizerComponent = ({
2815
+ showControls = true,
2816
+ showCode = true,
2722
2817
  className = ""
2723
2818
  }) => {
2724
2819
  const [algorithm1, setAlgorithm1] = useState("bubble");
@@ -2829,7 +2924,7 @@ const SortingComparisonVisualizerComponent = ({
2829
2924
  /* @__PURE__ */ jsx("div", { className: "p-3", children: /* @__PURE__ */ jsx("div", { className: "flex items-end justify-center gap-0.5 h-32 bg-gray-50 rounded p-2", children: step.array.map((value, index) => /* @__PURE__ */ jsx(
2830
2925
  "div",
2831
2926
  {
2832
- className: `${getBarColor(step, index)} rounded-t transition-all duration-150`,
2927
+ className: `${getBarColor(step, index)} rounded-t transition-colors duration-150`,
2833
2928
  style: {
2834
2929
  height: `${value / maxValue * 100}%`,
2835
2930
  width: `${Math.max(100 / step.array.length - 1, 6)}%`,
@@ -2887,7 +2982,17 @@ const SortingComparisonVisualizerComponent = ({
2887
2982
  /* @__PURE__ */ jsx("div", { className: "flex items-center text-2xl font-bold text-gray-300", children: "VS" }),
2888
2983
  renderAlgorithmPanel(algorithm2, state2, setAlgorithm2, algorithm1, "border-purple-200")
2889
2984
  ] }) }) }),
2890
- /* @__PURE__ */ jsx("div", { className: "px-4 py-3 bg-gray-50 border-t border-gray-200", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between flex-wrap gap-3", children: [
2985
+ showCode && /* @__PURE__ */ jsx("div", { className: "px-4 py-3 border-t border-gray-200", children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
2986
+ /* @__PURE__ */ jsxs("div", { children: [
2987
+ /* @__PURE__ */ jsx("div", { className: "text-xs font-medium text-indigo-600 mb-2", children: ALGORITHM_NAMES$1[algorithm1] }),
2988
+ /* @__PURE__ */ jsx(CodePanel, { code: ALGORITHM_CODE$1[algorithm1], activeLine: -1 })
2989
+ ] }),
2990
+ /* @__PURE__ */ jsxs("div", { children: [
2991
+ /* @__PURE__ */ jsx("div", { className: "text-xs font-medium text-purple-600 mb-2", children: ALGORITHM_NAMES$1[algorithm2] }),
2992
+ /* @__PURE__ */ jsx(CodePanel, { code: ALGORITHM_CODE$1[algorithm2], activeLine: -1 })
2993
+ ] })
2994
+ ] }) }),
2995
+ showControls && /* @__PURE__ */ jsx("div", { className: "px-4 py-3 bg-gray-50 border-t border-gray-200", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between flex-wrap gap-3", children: [
2891
2996
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
2892
2997
  isPlaying && /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1 text-xs text-indigo-600 font-medium", children: [
2893
2998
  /* @__PURE__ */ jsx("span", { className: "w-2 h-2 bg-indigo-500 rounded-full animate-pulse" }),
@@ -4140,6 +4245,25 @@ const GraphVisualizerComponent = ({
4140
4245
  ] }) }),
4141
4246
  /* @__PURE__ */ jsx("div", { className: "p-4", children: /* @__PURE__ */ jsxs("div", { className: `flex gap-4 ${showCode ? "flex-col lg:flex-row" : ""}`, children: [
4142
4247
  /* @__PURE__ */ jsxs(VisualizationArea, { minHeight: 400, children: [
4248
+ /* @__PURE__ */ jsxs("div", { className: "mb-4 p-4 bg-gradient-to-r from-purple-50 to-indigo-50 rounded-xl border-2 border-purple-200", children: [
4249
+ /* @__PURE__ */ jsxs("div", { className: "text-sm font-bold text-purple-800 mb-3 flex items-center gap-2", children: [
4250
+ /* @__PURE__ */ jsx("span", { className: "text-lg", children: "🔍" }),
4251
+ " DFS vs BFS"
4252
+ ] }),
4253
+ /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-3 text-xs", children: [
4254
+ /* @__PURE__ */ jsxs("div", { className: `p-2 rounded-lg border ${algorithm === "dfs" ? "bg-purple-100 border-purple-300" : "bg-gray-100 border-gray-300"}`, children: [
4255
+ /* @__PURE__ */ jsx("div", { className: "font-bold text-purple-700", children: "Depth-First (DFS)" }),
4256
+ /* @__PURE__ */ jsx("div", { className: "text-purple-600", children: "Uses: Stack" }),
4257
+ /* @__PURE__ */ jsx("div", { className: "text-[10px] text-purple-500", children: "Go deep before wide" })
4258
+ ] }),
4259
+ /* @__PURE__ */ jsxs("div", { className: `p-2 rounded-lg border ${algorithm === "bfs" ? "bg-indigo-100 border-indigo-300" : "bg-gray-100 border-gray-300"}`, children: [
4260
+ /* @__PURE__ */ jsx("div", { className: "font-bold text-indigo-700", children: "Breadth-First (BFS)" }),
4261
+ /* @__PURE__ */ jsx("div", { className: "text-indigo-600", children: "Uses: Queue" }),
4262
+ /* @__PURE__ */ jsx("div", { className: "text-[10px] text-indigo-500", children: "Level by level" })
4263
+ ] })
4264
+ ] }),
4265
+ /* @__PURE__ */ jsx("div", { className: "mt-2 text-[10px] text-gray-600 text-center", children: "Both O(V+E) time • DFS for paths/cycles • BFS for shortest path (unweighted)" })
4266
+ ] }),
4143
4267
  /* @__PURE__ */ jsxs("div", { className: "flex gap-4", children: [
4144
4268
  /* @__PURE__ */ jsx("div", { className: "flex-1 bg-gray-50 rounded-lg", children: /* @__PURE__ */ jsxs("svg", { viewBox: "0 0 400 300", className: "w-full h-64", children: [
4145
4269
  graph.edges.map((edge, index) => {
@@ -4164,7 +4288,7 @@ const GraphVisualizerComponent = ({
4164
4288
  cx: node.x,
4165
4289
  cy: node.y,
4166
4290
  r: 20,
4167
- className: `${getNodeColor(node.id)} stroke-2 transition-all duration-300`
4291
+ className: `${getNodeColor(node.id)} stroke-2 transition-colors duration-300`
4168
4292
  }
4169
4293
  ),
4170
4294
  /* @__PURE__ */ jsx(
@@ -4497,6 +4621,40 @@ const HashMapVisualizerComponent = ({
4497
4621
  ] }) }),
4498
4622
  /* @__PURE__ */ jsx("div", { className: "p-4", children: /* @__PURE__ */ jsxs("div", { className: `flex gap-4 ${showCode ? "flex-col lg:flex-row" : ""}`, children: [
4499
4623
  /* @__PURE__ */ jsxs(VisualizationArea, { minHeight: 350, className: showCode ? "flex-1" : "w-full", children: [
4624
+ /* @__PURE__ */ jsxs("div", { className: "mb-4 p-4 bg-gradient-to-r from-indigo-50 to-purple-50 rounded-xl border-2 border-indigo-200", children: [
4625
+ /* @__PURE__ */ jsxs("div", { className: "text-sm font-bold text-indigo-800 mb-3 flex items-center gap-2", children: [
4626
+ /* @__PURE__ */ jsx("span", { className: "text-lg", children: "#️⃣" }),
4627
+ " Hash Function"
4628
+ ] }),
4629
+ /* @__PURE__ */ jsxs("div", { className: "font-mono text-sm bg-white rounded-lg p-3 border border-indigo-200", children: [
4630
+ /* @__PURE__ */ jsx("div", { className: "text-center text-indigo-700 font-bold mb-2", children: "index = hashCode(key) % capacity" }),
4631
+ /* @__PURE__ */ jsx("div", { className: "text-xs text-gray-500 text-center", children: "Same key → same index (deterministic) • Different keys may collide → chaining" })
4632
+ ] }),
4633
+ stepData.hash !== void 0 && stepData.key && /* @__PURE__ */ jsx("div", { className: "mt-3 p-3 bg-white rounded-lg border border-indigo-200", children: /* @__PURE__ */ jsxs("div", { className: "text-xs text-center", children: [
4634
+ /* @__PURE__ */ jsxs("div", { className: "font-mono mb-1", children: [
4635
+ "hashCode(",
4636
+ /* @__PURE__ */ jsxs("span", { className: "text-indigo-600 font-bold", children: [
4637
+ '"',
4638
+ stepData.key,
4639
+ '"'
4640
+ ] }),
4641
+ ") = ",
4642
+ /* @__PURE__ */ jsx("span", { className: "text-purple-600 font-bold", children: stepData.hash })
4643
+ ] }),
4644
+ /* @__PURE__ */ jsxs("div", { className: "font-mono", children: [
4645
+ /* @__PURE__ */ jsx("span", { className: "text-purple-600", children: stepData.hash }),
4646
+ " % ",
4647
+ /* @__PURE__ */ jsx("span", { className: "text-gray-600", children: BUCKET_COUNT$1 }),
4648
+ " = ",
4649
+ /* @__PURE__ */ jsx("span", { className: "text-indigo-600 font-bold text-lg", children: stepData.bucketIndex })
4650
+ ] }),
4651
+ /* @__PURE__ */ jsxs("div", { className: "mt-2 text-indigo-600 text-lg", children: [
4652
+ "↓ bucket[",
4653
+ stepData.bucketIndex,
4654
+ "]"
4655
+ ] })
4656
+ ] }) })
4657
+ ] }),
4500
4658
  /* @__PURE__ */ jsxs("div", { className: "mb-4", children: [
4501
4659
  /* @__PURE__ */ jsxs("div", { className: "text-sm font-medium text-gray-700 mb-2", children: [
4502
4660
  "Bucket Array (capacity: ",
@@ -4527,22 +4685,6 @@ const HashMapVisualizerComponent = ({
4527
4685
  ] }, eIdx)) : /* @__PURE__ */ jsx("div", { className: "text-[10px] text-gray-400 mt-1", children: "∅" }) })
4528
4686
  ] }, idx)) })
4529
4687
  ] }),
4530
- stepData.hash !== void 0 && /* @__PURE__ */ jsx("div", { className: "mb-4 p-3 bg-gray-100 rounded-lg", children: /* @__PURE__ */ jsxs("div", { className: "text-xs text-gray-600", children: [
4531
- /* @__PURE__ */ jsx("span", { className: "font-medium", children: "Hash Calculation:" }),
4532
- /* @__PURE__ */ jsxs("div", { className: "mt-1 font-mono text-indigo-600", children: [
4533
- 'hashCode("',
4534
- stepData.key,
4535
- '") = ',
4536
- stepData.hash
4537
- ] }),
4538
- /* @__PURE__ */ jsxs("div", { className: "font-mono text-purple-600", children: [
4539
- stepData.hash,
4540
- " % ",
4541
- BUCKET_COUNT$1,
4542
- " = ",
4543
- stepData.bucketIndex
4544
- ] })
4545
- ] }) }),
4546
4688
  /* @__PURE__ */ jsx(
4547
4689
  StatusPanel,
4548
4690
  {
@@ -5215,6 +5357,27 @@ const LinkedListVisualizerComponent = ({
5215
5357
  ] }) }),
5216
5358
  /* @__PURE__ */ jsx("div", { className: "p-4", children: /* @__PURE__ */ jsxs("div", { className: `flex gap-4 ${showCode ? "flex-col lg:flex-row" : ""}`, children: [
5217
5359
  /* @__PURE__ */ jsxs(VisualizationArea, { minHeight: 350, className: showCode ? "flex-1" : "w-full", children: [
5360
+ /* @__PURE__ */ jsxs("div", { className: "mb-4 p-4 bg-gradient-to-r from-blue-50 to-indigo-50 rounded-xl border-2 border-blue-200", children: [
5361
+ /* @__PURE__ */ jsxs("div", { className: "text-sm font-bold text-blue-800 mb-3 flex items-center gap-2", children: [
5362
+ /* @__PURE__ */ jsx("span", { className: "text-lg", children: "🔗" }),
5363
+ " LinkedList vs ArrayList"
5364
+ ] }),
5365
+ /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-3 gap-2 text-xs", children: [
5366
+ /* @__PURE__ */ jsx("div", { className: "bg-white p-2 rounded-lg border border-blue-200 text-center", children: /* @__PURE__ */ jsx("div", { className: "font-semibold text-gray-700 mb-1", children: "Operation" }) }),
5367
+ /* @__PURE__ */ jsx("div", { className: "bg-blue-100 p-2 rounded-lg border border-blue-300 text-center", children: /* @__PURE__ */ jsx("div", { className: "font-semibold text-blue-700 mb-1", children: "LinkedList" }) }),
5368
+ /* @__PURE__ */ jsx("div", { className: "bg-orange-100 p-2 rounded-lg border border-orange-300 text-center", children: /* @__PURE__ */ jsx("div", { className: "font-semibold text-orange-700 mb-1", children: "ArrayList" }) }),
5369
+ /* @__PURE__ */ jsx("div", { className: "bg-white p-2 rounded-lg border border-gray-200 text-center font-medium", children: "add/remove (ends)" }),
5370
+ /* @__PURE__ */ jsx("div", { className: "bg-green-100 p-2 rounded-lg border border-green-300 text-center font-bold text-green-700", children: "O(1)" }),
5371
+ /* @__PURE__ */ jsx("div", { className: "bg-green-100 p-2 rounded-lg border border-green-300 text-center font-bold text-green-700", children: "O(1)*" }),
5372
+ /* @__PURE__ */ jsx("div", { className: "bg-white p-2 rounded-lg border border-gray-200 text-center font-medium", children: "add/remove (middle)" }),
5373
+ /* @__PURE__ */ jsx("div", { className: "bg-green-100 p-2 rounded-lg border border-green-300 text-center font-bold text-green-700", children: "O(1)**" }),
5374
+ /* @__PURE__ */ jsx("div", { className: "bg-red-100 p-2 rounded-lg border border-red-300 text-center font-bold text-red-700", children: "O(n)" }),
5375
+ /* @__PURE__ */ jsx("div", { className: "bg-white p-2 rounded-lg border border-gray-200 text-center font-medium", children: "get(index)" }),
5376
+ /* @__PURE__ */ jsx("div", { className: "bg-red-100 p-2 rounded-lg border border-red-300 text-center font-bold text-red-700", children: "O(n)" }),
5377
+ /* @__PURE__ */ jsx("div", { className: "bg-green-100 p-2 rounded-lg border border-green-300 text-center font-bold text-green-700", children: "O(1)" })
5378
+ ] }),
5379
+ /* @__PURE__ */ jsx("div", { className: "mt-2 text-[10px] text-gray-500 text-center", children: "* amortized | ** if you have the node reference" })
5380
+ ] }),
5218
5381
  /* @__PURE__ */ jsxs("div", { className: "mb-4", children: [
5219
5382
  /* @__PURE__ */ jsx("div", { className: "text-sm font-medium text-gray-700 mb-2", children: "Doubly-Linked List" }),
5220
5383
  /* @__PURE__ */ jsx("div", { className: "bg-gray-50 rounded-lg p-4 overflow-x-auto", children: nodes.length > 0 ? /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1 min-w-max", children: [
@@ -5223,7 +5386,7 @@ const LinkedListVisualizerComponent = ({
5223
5386
  /* @__PURE__ */ jsxs(
5224
5387
  "div",
5225
5388
  {
5226
- className: `flex flex-col items-center transition-all ${node.id === highlightNode ? "scale-110" : ""}`,
5389
+ className: `flex flex-col items-center transition-colors ${node.id === highlightNode ? "scale-110" : ""}`,
5227
5390
  children: [
5228
5391
  /* @__PURE__ */ jsx(
5229
5392
  "div",
@@ -6466,7 +6629,7 @@ const ArrayDequeVisualizerComponent = ({
6466
6629
  const isTail = index === tail;
6467
6630
  const isHighlighted = index === highlightIndex;
6468
6631
  const hasValue = array[index] !== null;
6469
- let baseStyle = "border-2 transition-all duration-200 ";
6632
+ let baseStyle = "border-2 transition-colors duration-200 ";
6470
6633
  if (resizing) {
6471
6634
  baseStyle += "bg-yellow-100 border-yellow-400 ";
6472
6635
  } else if (isHighlighted) {
@@ -8335,6 +8498,25 @@ const ConcurrentHashMapVisualizerComponent = ({ showControls = true, showCode =
8335
8498
  ] }) }),
8336
8499
  /* @__PURE__ */ jsx("div", { className: "p-4", children: /* @__PURE__ */ jsxs("div", { className: `flex gap-4 ${showCode ? "flex-col lg:flex-row" : ""}`, children: [
8337
8500
  /* @__PURE__ */ jsxs(VisualizationArea, { minHeight: 350, children: [
8501
+ /* @__PURE__ */ jsxs("div", { className: "mb-4 p-4 bg-gradient-to-r from-red-50 to-orange-50 rounded-xl border-2 border-red-200", children: [
8502
+ /* @__PURE__ */ jsxs("div", { className: "text-sm font-bold text-red-800 mb-3 flex items-center gap-2", children: [
8503
+ /* @__PURE__ */ jsx("span", { className: "text-lg", children: "⚡" }),
8504
+ " Why ConcurrentHashMap?"
8505
+ ] }),
8506
+ /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-3 text-xs", children: [
8507
+ /* @__PURE__ */ jsxs("div", { className: "bg-red-100 p-2 rounded-lg border border-red-300", children: [
8508
+ /* @__PURE__ */ jsx("div", { className: "font-bold text-red-700", children: "synchronized HashMap" }),
8509
+ /* @__PURE__ */ jsx("div", { className: "text-red-600", children: "❌ Single lock for entire map" }),
8510
+ /* @__PURE__ */ jsx("div", { className: "text-[10px] text-red-500", children: "All threads wait for one lock" })
8511
+ ] }),
8512
+ /* @__PURE__ */ jsxs("div", { className: "bg-green-100 p-2 rounded-lg border border-green-300", children: [
8513
+ /* @__PURE__ */ jsx("div", { className: "font-bold text-green-700", children: "ConcurrentHashMap" }),
8514
+ /* @__PURE__ */ jsx("div", { className: "text-green-600", children: "✓ Segment-level locking" }),
8515
+ /* @__PURE__ */ jsx("div", { className: "text-[10px] text-green-500", children: "Threads work in parallel on different segments" })
8516
+ ] })
8517
+ ] }),
8518
+ /* @__PURE__ */ jsx("div", { className: "mt-2 text-[10px] text-gray-600 text-center", children: "get() never blocks • put() only locks one segment • Much better concurrency!" })
8519
+ ] }),
8338
8520
  /* @__PURE__ */ jsxs("div", { className: "mb-4", children: [
8339
8521
  /* @__PURE__ */ jsx("div", { className: "text-sm font-medium text-gray-700 mb-2", children: "Segments (independent locks)" }),
8340
8522
  /* @__PURE__ */ jsx("div", { className: "grid grid-cols-2 gap-3", children: segments.map((seg, idx) => /* @__PURE__ */ jsxs(
@@ -8685,13 +8867,39 @@ const BlockingQueueVisualizerComponent = ({ showControls = true, showCode = true
8685
8867
  ] }) }) }),
8686
8868
  /* @__PURE__ */ jsx("div", { className: "p-4", children: /* @__PURE__ */ jsxs("div", { className: `flex gap-4 ${showCode ? "flex-col lg:flex-row" : ""}`, children: [
8687
8869
  /* @__PURE__ */ jsxs(VisualizationArea, { minHeight: 350, children: [
8870
+ /* @__PURE__ */ jsxs("div", { className: "mb-4 p-4 bg-gradient-to-r from-cyan-50 to-blue-50 rounded-xl border-2 border-cyan-200", children: [
8871
+ /* @__PURE__ */ jsxs("div", { className: "text-sm font-bold text-cyan-800 mb-3 flex items-center gap-2", children: [
8872
+ /* @__PURE__ */ jsx("span", { className: "text-lg", children: "🔄" }),
8873
+ " Producer-Consumer Pattern"
8874
+ ] }),
8875
+ /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-3 gap-2 text-xs", children: [
8876
+ /* @__PURE__ */ jsxs("div", { className: "bg-green-100 p-2 rounded-lg border border-green-300 text-center", children: [
8877
+ /* @__PURE__ */ jsx("div", { className: "font-bold text-green-700", children: "Producers" }),
8878
+ /* @__PURE__ */ jsx("div", { className: "text-green-600", children: "put() → queue" }),
8879
+ /* @__PURE__ */ jsx("div", { className: "text-[10px] text-green-500", children: "Block if FULL" })
8880
+ ] }),
8881
+ /* @__PURE__ */ jsxs("div", { className: "bg-gray-100 p-2 rounded-lg border border-gray-300 text-center", children: [
8882
+ /* @__PURE__ */ jsx("div", { className: "font-bold text-gray-700", children: "BlockingQueue" }),
8883
+ /* @__PURE__ */ jsx("div", { className: "text-gray-600", children: "Thread-safe buffer" }),
8884
+ /* @__PURE__ */ jsxs("div", { className: "text-[10px] text-gray-500", children: [
8885
+ "Capacity: ",
8886
+ capacity
8887
+ ] })
8888
+ ] }),
8889
+ /* @__PURE__ */ jsxs("div", { className: "bg-blue-100 p-2 rounded-lg border border-blue-300 text-center", children: [
8890
+ /* @__PURE__ */ jsx("div", { className: "font-bold text-blue-700", children: "Consumers" }),
8891
+ /* @__PURE__ */ jsx("div", { className: "text-blue-600", children: "take() ← queue" }),
8892
+ /* @__PURE__ */ jsx("div", { className: "text-[10px] text-blue-500", children: "Block if EMPTY" })
8893
+ ] })
8894
+ ] })
8895
+ ] }),
8688
8896
  /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-4 mb-4", children: [
8689
8897
  /* @__PURE__ */ jsxs("div", { className: "flex-1", children: [
8690
8898
  /* @__PURE__ */ jsx("div", { className: "text-xs font-medium text-gray-500 mb-2 text-center", children: "Producers" }),
8691
8899
  /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-2", children: ["P1", "P2"].map((p) => /* @__PURE__ */ jsxs(
8692
8900
  "div",
8693
8901
  {
8694
- className: `px-3 py-2 rounded-lg text-center text-sm font-medium transition-all ${activeThread === p ? "bg-green-500 text-white scale-105" : blockedProducers.includes(p) ? "bg-red-100 text-red-700 border-2 border-red-300" : "bg-green-100 text-green-700"}`,
8902
+ className: `px-3 py-2 rounded-lg text-center text-sm font-medium transition-colors ${activeThread === p ? "bg-green-500 text-white" : blockedProducers.includes(p) ? "bg-red-100 text-red-700 border-2 border-red-300" : "bg-green-100 text-green-700"}`,
8695
8903
  children: [
8696
8904
  p,
8697
8905
  blockedProducers.includes(p) && /* @__PURE__ */ jsx("span", { className: "block text-[10px]", children: "BLOCKED" })
@@ -8712,7 +8920,7 @@ const BlockingQueueVisualizerComponent = ({ showControls = true, showCode = true
8712
8920
  /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-1", children: queue.length > 0 ? queue.map((item, idx) => /* @__PURE__ */ jsx(
8713
8921
  "div",
8714
8922
  {
8715
- className: `px-2 py-1.5 bg-white rounded border text-xs font-medium text-center transition-all ${idx === 0 ? "border-blue-300 bg-blue-50" : "border-gray-200"}`,
8923
+ className: `px-2 py-1.5 bg-white rounded border text-xs font-medium text-center transition-colors ${idx === 0 ? "border-blue-300 bg-blue-50" : "border-gray-200"}`,
8716
8924
  children: item.value
8717
8925
  },
8718
8926
  item.id
@@ -8720,7 +8928,7 @@ const BlockingQueueVisualizerComponent = ({ showControls = true, showCode = true
8720
8928
  /* @__PURE__ */ jsx("div", { className: "mt-2 h-1.5 bg-gray-200 rounded-full overflow-hidden", children: /* @__PURE__ */ jsx(
8721
8929
  "div",
8722
8930
  {
8723
- className: `h-full transition-all ${queue.length === capacity ? "bg-red-500" : "bg-cyan-500"}`,
8931
+ className: `h-full transition-colors ${queue.length === capacity ? "bg-red-500" : "bg-cyan-500"}`,
8724
8932
  style: { width: `${queue.length / capacity * 100}%` }
8725
8933
  }
8726
8934
  ) })
@@ -8731,7 +8939,7 @@ const BlockingQueueVisualizerComponent = ({ showControls = true, showCode = true
8731
8939
  /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-2", children: ["C1", "C2"].map((c) => /* @__PURE__ */ jsxs(
8732
8940
  "div",
8733
8941
  {
8734
- className: `px-3 py-2 rounded-lg text-center text-sm font-medium transition-all ${activeThread === c ? "bg-blue-500 text-white scale-105" : blockedConsumers.includes(c) ? "bg-red-100 text-red-700 border-2 border-red-300" : "bg-blue-100 text-blue-700"}`,
8942
+ className: `px-3 py-2 rounded-lg text-center text-sm font-medium transition-colors ${activeThread === c ? "bg-blue-500 text-white" : blockedConsumers.includes(c) ? "bg-red-100 text-red-700 border-2 border-red-300" : "bg-blue-100 text-blue-700"}`,
8735
8943
  children: [
8736
8944
  c,
8737
8945
  blockedConsumers.includes(c) && /* @__PURE__ */ jsx("span", { className: "block text-[10px]", children: "BLOCKED" })
@@ -9015,7 +9223,7 @@ const CopyOnWriteVisualizerComponent = ({
9015
9223
  /* @__PURE__ */ jsx("div", { className: "flex justify-center gap-1", children: arr.map((item, idx) => /* @__PURE__ */ jsx(
9016
9224
  "div",
9017
9225
  {
9018
- className: `w-10 h-10 flex items-center justify-center rounded border-2 font-medium transition-all ${isNew && idx === highlightIndex ? "bg-green-500 border-green-600 text-white scale-110" : isNew ? "bg-green-100 border-green-300 text-green-700" : "bg-gray-100 border-gray-300 text-gray-700"}`,
9226
+ className: `w-10 h-10 flex items-center justify-center rounded border-2 font-medium transition-colors ${isNew && idx === highlightIndex ? "bg-green-500 border-green-600 text-white" : isNew ? "bg-green-100 border-green-300 text-green-700" : "bg-gray-100 border-gray-300 text-gray-700"}`,
9019
9227
  children: item
9020
9228
  },
9021
9229
  idx
@@ -9056,6 +9264,25 @@ const CopyOnWriteVisualizerComponent = ({
9056
9264
  ] }) }),
9057
9265
  /* @__PURE__ */ jsx("div", { className: "p-4", children: /* @__PURE__ */ jsxs("div", { className: `flex gap-4 ${showCode ? "flex-col lg:flex-row" : ""}`, children: [
9058
9266
  /* @__PURE__ */ jsxs(VisualizationArea, { minHeight: 350, children: [
9267
+ /* @__PURE__ */ jsxs("div", { className: "mb-4 p-4 bg-gradient-to-r from-lime-50 to-green-50 rounded-xl border-2 border-lime-200", children: [
9268
+ /* @__PURE__ */ jsxs("div", { className: "text-sm font-bold text-lime-800 mb-3 flex items-center gap-2", children: [
9269
+ /* @__PURE__ */ jsx("span", { className: "text-lg", children: "📋" }),
9270
+ " Copy-on-Write Pattern"
9271
+ ] }),
9272
+ /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-3 text-xs", children: [
9273
+ /* @__PURE__ */ jsxs("div", { className: "bg-blue-100 p-2 rounded-lg border border-blue-300 text-center", children: [
9274
+ /* @__PURE__ */ jsx("div", { className: "font-bold text-blue-700", children: "Read (get)" }),
9275
+ /* @__PURE__ */ jsx("div", { className: "text-2xl text-blue-600", children: "O(1)" }),
9276
+ /* @__PURE__ */ jsx("div", { className: "text-[10px] text-blue-500", children: "No lock, no copy" })
9277
+ ] }),
9278
+ /* @__PURE__ */ jsxs("div", { className: "bg-orange-100 p-2 rounded-lg border border-orange-300 text-center", children: [
9279
+ /* @__PURE__ */ jsx("div", { className: "font-bold text-orange-700", children: "Write (add/set)" }),
9280
+ /* @__PURE__ */ jsx("div", { className: "text-2xl text-orange-600", children: "O(n)" }),
9281
+ /* @__PURE__ */ jsx("div", { className: "text-[10px] text-orange-500", children: "Full array copy" })
9282
+ ] })
9283
+ ] }),
9284
+ /* @__PURE__ */ jsx("div", { className: "mt-2 text-[10px] text-gray-600 text-center", children: "Best for: Read-heavy, rarely-modified collections • Iterators never throw ConcurrentModificationException" })
9285
+ ] }),
9059
9286
  /* @__PURE__ */ jsx("div", { className: "mb-4 p-4 bg-gray-50 rounded-lg", children: showCopy ? /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-4", children: [
9060
9287
  renderArray(oldArray, "Old Array (readers use this)"),
9061
9288
  /* @__PURE__ */ jsx("div", { className: "text-2xl text-gray-400", children: "→" }),
@@ -9333,7 +9560,7 @@ const ImmutableCollectionsVisualizerComponent = ({ showControls = true, showCode
9333
9560
  original.map((item, idx) => /* @__PURE__ */ jsx(
9334
9561
  "div",
9335
9562
  {
9336
- className: `w-12 h-12 flex items-center justify-center rounded-lg border-2 font-bold transition-all ${error ? "bg-red-100 border-red-300 text-red-700 animate-pulse" : "bg-violet-100 border-violet-300 text-violet-700"}`,
9563
+ className: `w-12 h-12 flex items-center justify-center rounded-lg border-2 font-bold transition-colors ${error ? "bg-red-100 border-red-300 text-red-700 animate-pulse" : "bg-violet-100 border-violet-300 text-violet-700"}`,
9337
9564
  children: item
9338
9565
  },
9339
9566
  idx
@@ -9766,14 +9993,14 @@ const GCVisualizerComponent = ({
9766
9993
  /* @__PURE__ */ jsx(
9767
9994
  "div",
9768
9995
  {
9769
- className: "absolute inset-y-0 left-0 bg-opacity-30 bg-gray-500 transition-all duration-300",
9996
+ className: "absolute inset-y-0 left-0 bg-opacity-30 bg-gray-500 transition-[width] duration-300",
9770
9997
  style: { width: `${fillPercent}%` }
9771
9998
  }
9772
9999
  ),
9773
10000
  /* @__PURE__ */ jsx("div", { className: "absolute inset-0 flex flex-wrap items-center gap-1 p-1", children: genObjects.map((obj) => /* @__PURE__ */ jsxs(
9774
10001
  "div",
9775
10002
  {
9776
- className: `px-1.5 py-0.5 text-[9px] font-medium rounded transition-all duration-200 ${getObjectStyle(obj)}`,
10003
+ className: `px-1.5 py-0.5 text-[9px] font-medium rounded transition-colors duration-200 ${getObjectStyle(obj)}`,
9777
10004
  title: `${obj.id} (age: ${obj.age}, ${obj.reachable ? "reachable" : "garbage"})`,
9778
10005
  children: [
9779
10006
  obj.id.replace("obj", ""),
@@ -9831,6 +10058,28 @@ const GCVisualizerComponent = ({
9831
10058
  ] }) }),
9832
10059
  /* @__PURE__ */ jsx("div", { className: "p-4", children: /* @__PURE__ */ jsxs("div", { className: `flex gap-4 ${showCode ? "flex-col lg:flex-row" : ""}`, children: [
9833
10060
  /* @__PURE__ */ jsxs(VisualizationArea, { minHeight: 400, className: showCode ? "flex-1" : "w-full", children: [
10061
+ /* @__PURE__ */ jsxs("div", { className: "mb-4 p-4 bg-gradient-to-r from-purple-50 to-pink-50 rounded-xl border-2 border-purple-200", children: [
10062
+ /* @__PURE__ */ jsxs("div", { className: "text-sm font-bold text-purple-800 mb-3 flex items-center gap-2", children: [
10063
+ /* @__PURE__ */ jsx("span", { className: "text-lg", children: "🧬" }),
10064
+ " Generational Hypothesis"
10065
+ ] }),
10066
+ /* @__PURE__ */ jsxs("div", { className: "font-mono text-sm bg-white rounded-lg p-3 border border-purple-200", children: [
10067
+ /* @__PURE__ */ jsx("div", { className: "text-center text-purple-700 font-bold mb-2", children: '"Most objects die young"' }),
10068
+ /* @__PURE__ */ jsx("div", { className: "text-xs text-gray-500 text-center", children: "~95% of objects become garbage before first GC • Optimize for the common case" })
10069
+ ] }),
10070
+ /* @__PURE__ */ jsxs("div", { className: "mt-3 grid grid-cols-2 gap-2 text-xs", children: [
10071
+ /* @__PURE__ */ jsxs("div", { className: "bg-blue-100 p-2 rounded-lg border border-blue-300 text-center", children: [
10072
+ /* @__PURE__ */ jsx("div", { className: "font-bold text-blue-700", children: "Young Gen" }),
10073
+ /* @__PURE__ */ jsx("div", { className: "text-blue-600", children: "Fast copy collection" }),
10074
+ /* @__PURE__ */ jsx("div", { className: "text-[10px] text-blue-500", children: "Minor GC (frequent)" })
10075
+ ] }),
10076
+ /* @__PURE__ */ jsxs("div", { className: "bg-amber-100 p-2 rounded-lg border border-amber-300 text-center", children: [
10077
+ /* @__PURE__ */ jsx("div", { className: "font-bold text-amber-700", children: "Old Gen" }),
10078
+ /* @__PURE__ */ jsx("div", { className: "text-amber-600", children: "Mark-sweep collection" }),
10079
+ /* @__PURE__ */ jsx("div", { className: "text-[10px] text-amber-500", children: "Major GC (rare, slow)" })
10080
+ ] })
10081
+ ] })
10082
+ ] }),
9834
10083
  /* @__PURE__ */ jsxs("div", { className: "mb-4", children: [
9835
10084
  /* @__PURE__ */ jsx("div", { className: "text-sm font-medium text-gray-700 mb-2", children: "JVM Heap Memory" }),
9836
10085
  /* @__PURE__ */ jsxs("div", { className: "mb-4 p-3 bg-blue-50 rounded-lg", children: [