@cardenelabs/cdl 0.78.0 → 0.79.0

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/react.cjs CHANGED
@@ -1381,72 +1381,169 @@ function collectBBoxes(lanes, nodes, edges) {
1381
1381
  });
1382
1382
  }
1383
1383
  for (const e of edges) {
1384
- const points = extractPathPoints(e.d);
1385
- if (points.length === 0) continue;
1386
- const xs = points.map((p) => p.x);
1387
- const ys = points.map((p) => p.y);
1388
- const minX = Math.min(...xs);
1389
- const maxX = Math.max(...xs);
1390
- const minY = Math.min(...ys);
1391
- const maxY = Math.max(...ys);
1384
+ const box = pathBBox(e.d);
1385
+ if (!box) continue;
1392
1386
  out.push({
1393
1387
  kind: "edge-path",
1394
1388
  id: e.id,
1395
- x: minX - 2,
1396
- y: minY - 2,
1397
- w: maxX - minX + 4,
1398
- h: maxY - minY + 4
1389
+ x: box.minX - 2,
1390
+ y: box.minY - 2,
1391
+ w: box.maxX - box.minX + 4,
1392
+ h: box.maxY - box.minY + 4
1399
1393
  });
1400
1394
  }
1401
1395
  return out;
1402
1396
  }
1397
+ var PATH_ARITY = {
1398
+ M: 2,
1399
+ L: 2,
1400
+ H: 1,
1401
+ V: 1,
1402
+ C: 6,
1403
+ S: 4,
1404
+ Q: 4,
1405
+ T: 2,
1406
+ A: 7,
1407
+ Z: 0
1408
+ };
1409
+ function isRelative(cmd) {
1410
+ return cmd >= "a" && cmd <= "z";
1411
+ }
1412
+ function coordSlots(cmd) {
1413
+ switch (cmd.toUpperCase()) {
1414
+ case "M":
1415
+ case "L":
1416
+ case "T":
1417
+ return [[0, 1]];
1418
+ case "H":
1419
+ return [[0, -1]];
1420
+ case "V":
1421
+ return [[-1, 0]];
1422
+ case "Q":
1423
+ case "S":
1424
+ return [[0, 1], [2, 3]];
1425
+ case "C":
1426
+ return [[0, 1], [2, 3], [4, 5]];
1427
+ case "A":
1428
+ return [[5, 6]];
1429
+ default:
1430
+ return [];
1431
+ }
1432
+ }
1433
+ function parsePathCommands(d) {
1434
+ const out = [];
1435
+ const commandRegex = /([MmLlHhVvCcSsQqTtAaZz])([^MmLlHhVvCcSsQqTtAaZz]*)/g;
1436
+ let m;
1437
+ while ((m = commandRegex.exec(d)) !== null) {
1438
+ const cmd = m[1];
1439
+ const arity = PATH_ARITY[cmd.toUpperCase()] ?? 0;
1440
+ if (arity === 0) {
1441
+ out.push({ cmd, args: [] });
1442
+ continue;
1443
+ }
1444
+ const nums = (m[2] ?? "").trim().split(/[\s,]+/).filter(Boolean).map(parseFloat);
1445
+ for (let i = 0; i + arity <= nums.length; i += arity) {
1446
+ const args = nums.slice(i, i + arity);
1447
+ if (!args.every(Number.isFinite)) break;
1448
+ const \u7E70\u308A\u8FD4\u3057 = i > 0;
1449
+ const c = \u7E70\u308A\u8FD4\u3057 && cmd === "M" ? "L" : \u7E70\u308A\u8FD4\u3057 && cmd === "m" ? "l" : cmd;
1450
+ out.push({ cmd: c, args });
1451
+ }
1452
+ }
1453
+ return out;
1454
+ }
1403
1455
  function extractPathPoints(d) {
1404
1456
  const out = [];
1405
- const tokens = d.replace(/[A-Za-z]/g, " ").trim().split(/[\s,]+/).filter(Boolean);
1406
- for (let i = 0; i + 1 < tokens.length; i += 2) {
1407
- const x = parseFloat(tokens[i]);
1408
- const y = parseFloat(tokens[i + 1]);
1409
- if (Number.isFinite(x) && Number.isFinite(y)) {
1457
+ let cur = { x: 0, y: 0 };
1458
+ let started = false;
1459
+ for (const { cmd, args } of parsePathCommands(d)) {
1460
+ const \u76F8\u5BFE = started && isRelative(cmd);
1461
+ const \u57FA\u70B9 = cur;
1462
+ for (const [xi, yi] of coordSlots(cmd)) {
1463
+ const x = xi >= 0 ? \u76F8\u5BFE ? \u57FA\u70B9.x + args[xi] : args[xi] : \u57FA\u70B9.x;
1464
+ const y = yi >= 0 ? \u76F8\u5BFE ? \u57FA\u70B9.y + args[yi] : args[yi] : \u57FA\u70B9.y;
1410
1465
  out.push({ x, y });
1466
+ cur = { x, y };
1411
1467
  }
1468
+ started = true;
1412
1469
  }
1413
1470
  return out;
1414
1471
  }
1472
+ function pathBBox(d) {
1473
+ let minX = Infinity;
1474
+ let minY = Infinity;
1475
+ let maxX = -Infinity;
1476
+ let maxY = -Infinity;
1477
+ let \u70B9\u3042\u308A = false;
1478
+ const \u53D6\u308B = (x, y) => {
1479
+ minX = Math.min(minX, x);
1480
+ minY = Math.min(minY, y);
1481
+ maxX = Math.max(maxX, x);
1482
+ maxY = Math.max(maxY, y);
1483
+ \u70B9\u3042\u308A = true;
1484
+ };
1485
+ let cur = { x: 0, y: 0 };
1486
+ let started = false;
1487
+ for (const { cmd, args } of parsePathCommands(d)) {
1488
+ const \u76F8\u5BFE = started && isRelative(cmd);
1489
+ const \u57FA\u70B9 = cur;
1490
+ for (const [xi, yi] of coordSlots(cmd)) {
1491
+ const x = xi >= 0 ? \u76F8\u5BFE ? \u57FA\u70B9.x + args[xi] : args[xi] : \u57FA\u70B9.x;
1492
+ const y = yi >= 0 ? \u76F8\u5BFE ? \u57FA\u70B9.y + args[yi] : args[yi] : \u57FA\u70B9.y;
1493
+ \u53D6\u308B(x, y);
1494
+ cur = { x, y };
1495
+ }
1496
+ if (cmd.toUpperCase() === "A") {
1497
+ const r = Math.max(Math.abs(args[0]), Math.abs(args[1]));
1498
+ const \u5F26 = Math.hypot(cur.x - \u57FA\u70B9.x, cur.y - \u57FA\u70B9.y);
1499
+ const \u534A\u5F26 = Math.min(\u5F26 / 2, r);
1500
+ const \u4F59 = Math.sqrt(Math.max(0, r * r - \u534A\u5F26 * \u534A\u5F26));
1501
+ const \u81A8\u3089\u307F = args[3] !== 0 ? r + \u4F59 : r - \u4F59;
1502
+ \u53D6\u308B(Math.min(\u57FA\u70B9.x, cur.x) - \u81A8\u3089\u307F, Math.min(\u57FA\u70B9.y, cur.y) - \u81A8\u3089\u307F);
1503
+ \u53D6\u308B(Math.max(\u57FA\u70B9.x, cur.x) + \u81A8\u3089\u307F, Math.max(\u57FA\u70B9.y, cur.y) + \u81A8\u3089\u307F);
1504
+ }
1505
+ started = true;
1506
+ }
1507
+ return \u70B9\u3042\u308A ? { minX, minY, maxX, maxY } : null;
1508
+ }
1415
1509
  function rebuildPathD(d, map) {
1416
- const commandRegex = /([MLCQZmlcqz])([^MLCQZmlcqz]*)/g;
1417
1510
  let out = "";
1418
1511
  let idx = 0;
1419
- let m;
1420
- while ((m = commandRegex.exec(d)) !== null) {
1421
- const cmd = m[1];
1422
- const argsStr = (m[2] ?? "").trim();
1423
- if (argsStr === "" || cmd === "Z" || cmd === "z") {
1512
+ let cur = { x: 0, y: 0 };
1513
+ let started = false;
1514
+ for (const { cmd, args } of parsePathCommands(d)) {
1515
+ const slots = coordSlots(cmd);
1516
+ if (slots.length === 0) {
1424
1517
  out += cmd + " ";
1518
+ started = true;
1425
1519
  continue;
1426
1520
  }
1427
- const args = argsStr.split(/[\s,]+/).filter(Boolean).map(parseFloat);
1428
- const translated = [];
1429
- for (let i = 0; i + 1 < args.length; i += 2) {
1430
- const [nx, ny] = map(args[i], args[i + 1], idx);
1431
- translated.push(nx, ny);
1521
+ const \u76F8\u5BFE = started && isRelative(cmd);
1522
+ const \u57FA\u70B9 = cur;
1523
+ const \u6B21\u306E\u5F15\u6570 = args.slice();
1524
+ for (const [xi, yi] of slots) {
1525
+ const x = xi >= 0 ? \u76F8\u5BFE ? \u57FA\u70B9.x + args[xi] : args[xi] : \u57FA\u70B9.x;
1526
+ const y = yi >= 0 ? \u76F8\u5BFE ? \u57FA\u70B9.y + args[yi] : args[yi] : \u57FA\u70B9.y;
1527
+ const [nx, ny] = map(x, y, idx);
1528
+ if (!\u76F8\u5BFE) {
1529
+ if (xi >= 0) \u6B21\u306E\u5F15\u6570[xi] = nx;
1530
+ if (yi >= 0) \u6B21\u306E\u5F15\u6570[yi] = ny;
1531
+ }
1432
1532
  idx += 1;
1533
+ cur = { x, y };
1433
1534
  }
1434
- out += cmd + " " + translated.join(" ") + " ";
1535
+ out += cmd + " " + \u6B21\u306E\u5F15\u6570.join(" ") + " ";
1536
+ started = true;
1435
1537
  }
1436
1538
  return out.trim();
1437
1539
  }
1438
1540
  function cornerBoundaryIndices(d) {
1439
- const commandRegex = /([MLCQZmlcqz])([^MLCQZmlcqz]*)/g;
1440
1541
  let idx = 0;
1441
1542
  let firstCornerEnd = -1;
1442
1543
  let lastCornerStart = -1;
1443
- let m;
1444
- while ((m = commandRegex.exec(d)) !== null) {
1445
- const cmd = m[1];
1446
- const argsStr = (m[2] ?? "").trim();
1447
- if (argsStr === "" || cmd === "Z" || cmd === "z") continue;
1448
- const pairs = argsStr.split(/[\s,]+/).filter(Boolean).length >> 1;
1449
- if ((cmd === "Q" || cmd === "q") && pairs >= 2) {
1544
+ for (const { cmd } of parsePathCommands(d)) {
1545
+ const pairs = coordSlots(cmd).length;
1546
+ if (cmd.toUpperCase() === "Q" && pairs >= 2) {
1450
1547
  if (firstCornerEnd < 0) firstCornerEnd = idx + 1;
1451
1548
  lastCornerStart = idx;
1452
1549
  }