easyeda 0.0.262 → 0.0.264

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
@@ -4867,9 +4867,21 @@ interface Options {
4867
4867
  cadPositionXMm?: number;
4868
4868
  cadPositionYMm?: number;
4869
4869
  cadPositionZMm?: number;
4870
+ cadModelBounds?: {
4871
+ min: {
4872
+ x: number;
4873
+ y: number;
4874
+ z: number;
4875
+ };
4876
+ max: {
4877
+ x: number;
4878
+ y: number;
4879
+ z: number;
4880
+ };
4881
+ };
4870
4882
  showDesignator?: boolean;
4871
4883
  }
4872
- declare const convertEasyEdaJsonToCircuitJson: (easyEdaJson: BetterEasyEdaJson, { useModelCdn, shouldRecenter, cadPositionXMm, cadPositionYMm, cadPositionZMm, showDesignator, }?: Options) => AnyCircuitElement[];
4884
+ declare const convertEasyEdaJsonToCircuitJson: (easyEdaJson: BetterEasyEdaJson, { useModelCdn, shouldRecenter, cadPositionXMm, cadPositionYMm, cadPositionZMm, cadModelBounds, showDesignator, }?: Options) => AnyCircuitElement[];
4873
4885
 
4874
4886
  declare function fetchEasyEDAComponent(jlcpcbPartNumber: string, { fetch, includeModelMetadata, }?: {
4875
4887
  fetch?: typeof globalThis.fetch;
package/dist/index.js CHANGED
@@ -5033,11 +5033,11 @@ function generateArcFromSweep(startX, startY, endX, endY, radius, largeArcFlag,
5033
5033
  const midY = (startY + endY) / 2;
5034
5034
  const dx = endX - startX;
5035
5035
  const dy = endY - startY;
5036
- const distance2 = Math.sqrt(dx * dx + dy * dy);
5037
- if (distance2 === 0 || radius < distance2 / 2) {
5036
+ const distance3 = Math.sqrt(dx * dx + dy * dy);
5037
+ if (distance3 === 0 || radius < distance3 / 2) {
5038
5038
  return [start, end];
5039
5039
  }
5040
- const h = Math.sqrt(radius * radius - distance2 * distance2 / 4);
5040
+ const h = Math.sqrt(radius * radius - distance3 * distance3 / 4);
5041
5041
  const angle = Math.atan2(dy, dx);
5042
5042
  const centerX = midX + h * Math.sin(angle) * (sweepFlag ? -1 : 1);
5043
5043
  const centerY = midY - h * Math.cos(angle) * (sweepFlag ? -1 : 1);
@@ -5073,6 +5073,142 @@ function generateArcFromSweep(startX, startY, endX, endY, radius, largeArcFlag,
5073
5073
  // lib/utils/easyeda-unit-to-mm.ts
5074
5074
  var mil10ToMm = (value) => value * 10 * 0.0254;
5075
5075
 
5076
+ // node_modules/@tscircuit/math-utils/dist/chunk-3WCUPG5S.js
5077
+ var getBoundsCenter = (bounds) => ({
5078
+ x: (bounds.minX + bounds.maxX) / 2,
5079
+ y: (bounds.minY + bounds.maxY) / 2
5080
+ });
5081
+
5082
+ // node_modules/@tscircuit/math-utils/dist/chunk-5N7UJNVK.js
5083
+ var getBoundsFromPoints = (points) => {
5084
+ if (points.length === 0) {
5085
+ return null;
5086
+ }
5087
+ let minX = points[0].x;
5088
+ let minY = points[0].y;
5089
+ let maxX = points[0].x;
5090
+ let maxY = points[0].y;
5091
+ for (let i = 1; i < points.length; i++) {
5092
+ const point2 = points[i];
5093
+ if (point2.x < minX) minX = point2.x;
5094
+ if (point2.y < minY) minY = point2.y;
5095
+ if (point2.x > maxX) maxX = point2.x;
5096
+ if (point2.y > maxY) maxY = point2.y;
5097
+ }
5098
+ return { minX, minY, maxX, maxY };
5099
+ };
5100
+
5101
+ // lib/websafe/get-easyeda-cad-placement-helpers.ts
5102
+ var getCadSvgNode = (easyEdaJson) => {
5103
+ const svgNode = easyEdaJson.packageDetail.dataStr.shape.find(
5104
+ (shape) => shape.type === "SVGNODE" && shape.svgData.attrs?.uuid
5105
+ );
5106
+ return svgNode?.type === "SVGNODE" ? svgNode : null;
5107
+ };
5108
+ var isSvgChildNodeWithAttrs = (childNode) => typeof childNode === "object" && childNode !== null;
5109
+ var getXyBoundsFromModelBounds = (bounds) => ({
5110
+ minX: bounds.min.x,
5111
+ minY: bounds.min.y,
5112
+ maxX: bounds.max.x,
5113
+ maxY: bounds.max.y
5114
+ });
5115
+ var rotateScenePoint = (point2, rotationDeg) => {
5116
+ switch (rotationDeg) {
5117
+ case 0:
5118
+ return point2;
5119
+ case 90:
5120
+ return { x: point2.y, y: -point2.x };
5121
+ case 180:
5122
+ return { x: -point2.x, y: -point2.y };
5123
+ case 270:
5124
+ return { x: -point2.y, y: point2.x };
5125
+ }
5126
+ };
5127
+ var getEasyEdaModelOriginOnBoardMm = ({
5128
+ svgNode,
5129
+ footprintCenterMm
5130
+ }) => {
5131
+ const points = [];
5132
+ for (const childNode of svgNode.svgData.childNodes ?? []) {
5133
+ if (!isSvgChildNodeWithAttrs(childNode)) continue;
5134
+ const rawPoints = childNode.attrs?.points;
5135
+ if (!rawPoints) continue;
5136
+ const values = String(rawPoints).trim().split(/\s+/).map(Number);
5137
+ for (let i = 0; i + 1 < values.length; i += 2) {
5138
+ const x = values[i];
5139
+ const y = values[i + 1];
5140
+ if (Number.isFinite(x) && Number.isFinite(y)) {
5141
+ points.push({ x: mil10ToMm(x), y: mil10ToMm(y) });
5142
+ }
5143
+ }
5144
+ }
5145
+ let modelOriginMm = null;
5146
+ if (points.length > 0) {
5147
+ const bounds = getBoundsFromPoints(points);
5148
+ modelOriginMm = bounds ? getBoundsCenter(bounds) : null;
5149
+ } else {
5150
+ const [originX, originY] = String(svgNode.svgData.attrs?.c_origin ?? "0,0").split(",").map((value) => Number(value.trim()));
5151
+ if (Number.isFinite(originX) && Number.isFinite(originY)) {
5152
+ modelOriginMm = { x: mil10ToMm(originX), y: mil10ToMm(originY) };
5153
+ }
5154
+ }
5155
+ if (!modelOriginMm) return null;
5156
+ return {
5157
+ x: modelOriginMm.x - footprintCenterMm.x,
5158
+ y: footprintCenterMm.y - modelOriginMm.y
5159
+ };
5160
+ };
5161
+ var snapZero = (value) => Math.abs(value) < 1e-6 ? 0 : value;
5162
+ var normalizePoint = (point2) => ({
5163
+ x: snapZero(point2.x),
5164
+ y: snapZero(point2.y)
5165
+ });
5166
+ var getCadModelOffsetMm = (easyEdaJson) => {
5167
+ const svgNode = getCadSvgNode(easyEdaJson);
5168
+ return getCadModelOffsetMmFromBounds(
5169
+ easyEdaJson,
5170
+ easyEdaJson._objMetadata?.bounds
5171
+ );
5172
+ };
5173
+ var getCadModelOffsetMmFromBounds = (easyEdaJson, bounds, {
5174
+ footprintBoundsCenterMm
5175
+ } = {}) => {
5176
+ const svgNode = getCadSvgNode(easyEdaJson);
5177
+ if (!svgNode || !bounds) return null;
5178
+ const [, , rotationZRaw] = String(
5179
+ svgNode.svgData.attrs?.c_rotation ?? "0,0,0"
5180
+ ).split(",").map((value) => Number(value.trim()));
5181
+ const rotationDeg = (rotationZRaw % 360 + 360) % 360;
5182
+ if (![0, 90, 180, 270].includes(rotationDeg)) return null;
5183
+ const modelCenter = getBoundsCenter(getXyBoundsFromModelBounds(bounds));
5184
+ const footprintCenter = easyEdaJson.packageDetail.dataStr.head;
5185
+ const footprintCenterMm = footprintBoundsCenterMm ?? {
5186
+ x: mil10ToMm(footprintCenter.x),
5187
+ y: mil10ToMm(footprintCenter.y)
5188
+ };
5189
+ const targetOriginOnBoardMm = getEasyEdaModelOriginOnBoardMm({
5190
+ svgNode,
5191
+ footprintCenterMm
5192
+ });
5193
+ if (!targetOriginOnBoardMm) return null;
5194
+ const targetOriginInModelFrame = rotateScenePoint(
5195
+ targetOriginOnBoardMm,
5196
+ rotationDeg
5197
+ );
5198
+ return normalizePoint({
5199
+ x: modelCenter.x - targetOriginInModelFrame.x,
5200
+ y: modelCenter.y - targetOriginInModelFrame.y
5201
+ });
5202
+ };
5203
+ var getCadSvgNodeZOffsetMm = (easyEdaJson) => {
5204
+ const svgNode = getCadSvgNode(easyEdaJson);
5205
+ if (!svgNode) return null;
5206
+ const svgNodeZ = Number(svgNode.svgData.attrs?.z ?? 0);
5207
+ if (!Number.isFinite(svgNodeZ)) return null;
5208
+ return mil10ToMm(svgNodeZ);
5209
+ };
5210
+ var getCadSvgNodeModelUuid = (easyEdaJson) => getCadSvgNode(easyEdaJson)?.svgData.attrs?.uuid ?? null;
5211
+
5076
5212
  // lib/utils/normalize-pin-labels.ts
5077
5213
  var normalizePinLabels = (inputPinLabels) => {
5078
5214
  const uniqueInputPinLabels = inputPinLabels.map((labels) => [
@@ -5289,6 +5425,7 @@ var convertEasyEdaJsonToCircuitJson = (easyEdaJson, {
5289
5425
  cadPositionXMm,
5290
5426
  cadPositionYMm,
5291
5427
  cadPositionZMm,
5428
+ cadModelBounds,
5292
5429
  showDesignator = false
5293
5430
  } = {}) => {
5294
5431
  const resolvedCadPositionZMm = cadPositionZMm ?? getCadPositionZMmFromMetadata(easyEdaJson);
@@ -5641,6 +5778,14 @@ var convertEasyEdaJsonToCircuitJson = (easyEdaJson, {
5641
5778
  if (!cad.model_origin_position) {
5642
5779
  cad.model_origin_position = { x: 0, y: 0, z: 0 };
5643
5780
  }
5781
+ const resolvedCadModelBounds = cadModelBounds ?? easyEdaJson._objMetadata?.bounds;
5782
+ const recenteredCadOffset = resolvedCadModelBounds && getCadModelOffsetMmFromBounds(easyEdaJson, resolvedCadModelBounds, {
5783
+ footprintBoundsCenterMm: bounds.center
5784
+ });
5785
+ if (recenteredCadOffset) {
5786
+ cad.model_origin_position.x = recenteredCadOffset.x;
5787
+ cad.model_origin_position.y = recenteredCadOffset.y;
5788
+ }
5644
5789
  const side = pcb_component2.layer ?? "top";
5645
5790
  const t = DEFAULT_PCB_THICKNESS_MM / 2;
5646
5791
  const attrs = svgNode?.svgData?.attrs ?? {};
@@ -6610,98 +6755,6 @@ function normalizeManufacturerPartNumber(partNumber) {
6610
6755
  return normalized;
6611
6756
  }
6612
6757
 
6613
- // lib/websafe/get-easyeda-cad-placement-helpers.ts
6614
- var milToMm = (mil) => mil * 0.0254;
6615
- var getBoundsCenter = (bounds) => ({
6616
- x: (bounds.min.x + bounds.max.x) / 2,
6617
- y: (bounds.min.y + bounds.max.y) / 2
6618
- });
6619
- var getCadSvgNode = (easyEdaJson) => {
6620
- const svgNode = easyEdaJson.packageDetail.dataStr.shape.find(
6621
- (shape) => shape.type === "SVGNODE" && shape.svgData.attrs?.uuid
6622
- );
6623
- return svgNode?.type === "SVGNODE" ? svgNode : null;
6624
- };
6625
- var parseMil10Value = (value) => Number(String(value).replace("mil", "")) / 10;
6626
- var isZeroishModelCenter = (value) => Math.abs(value) < 1e-6;
6627
- var isZeroishFootprintDelta = (value) => Math.abs(value) < 1e-3;
6628
- var getPadCenter = (easyEdaJson) => {
6629
- const pads = easyEdaJson.packageDetail.dataStr.shape.filter(
6630
- (shape) => shape.type === "PAD"
6631
- );
6632
- if (pads.length === 0) return null;
6633
- const xs = pads.map((pad) => parseMil10Value(pad.center.x));
6634
- const ys = pads.map((pad) => parseMil10Value(pad.center.y));
6635
- return {
6636
- x: (Math.min(...xs) + Math.max(...xs)) / 2,
6637
- y: (Math.min(...ys) + Math.max(...ys)) / 2
6638
- };
6639
- };
6640
- var getRotatedOffsetMm = ({
6641
- bounds,
6642
- rawOffsetMil,
6643
- rotationDeg
6644
- }) => {
6645
- const center = getBoundsCenter(bounds);
6646
- const offsetX = milToMm(rawOffsetMil.x);
6647
- const offsetY = milToMm(rawOffsetMil.y);
6648
- switch (rotationDeg) {
6649
- case 0:
6650
- return { x: center.x + offsetX, y: center.y + offsetY };
6651
- case 90:
6652
- return { x: center.x + offsetY, y: center.y + offsetX };
6653
- case 180:
6654
- return { x: center.x - offsetX, y: center.y - offsetY };
6655
- case 270:
6656
- return { x: center.x - offsetY, y: center.y - offsetX };
6657
- }
6658
- };
6659
- var getCadModelOffsetMm = (easyEdaJson) => {
6660
- const svgNode = getCadSvgNode(easyEdaJson);
6661
- return getCadModelOffsetMmFromBounds(
6662
- easyEdaJson,
6663
- easyEdaJson._objMetadata?.bounds
6664
- );
6665
- };
6666
- var getCadModelOffsetMmFromBounds = (easyEdaJson, bounds) => {
6667
- const svgNode = getCadSvgNode(easyEdaJson);
6668
- if (!svgNode || !bounds) return null;
6669
- const [originX, originY] = String(svgNode.svgData.attrs?.c_origin ?? "0,0").split(",").map((value) => Number(value.trim()));
6670
- if (!Number.isFinite(originX) || !Number.isFinite(originY)) return null;
6671
- const [, , rotationZRaw] = String(
6672
- svgNode.svgData.attrs?.c_rotation ?? "0,0,0"
6673
- ).split(",").map((value) => Number(value.trim()));
6674
- const rotationDeg = (rotationZRaw % 360 + 360) % 360;
6675
- if (![0, 90, 180, 270].includes(rotationDeg)) return null;
6676
- const modelCenter = getBoundsCenter(bounds);
6677
- const footprintCenter = easyEdaJson.packageDetail.dataStr.head;
6678
- const padCenter = getPadCenter(easyEdaJson);
6679
- const padCenterDelta = padCenter ? {
6680
- x: padCenter.x - footprintCenter.x,
6681
- y: padCenter.y - footprintCenter.y
6682
- } : null;
6683
- const rawOffsetMil = {
6684
- x: (originX - footprintCenter.x) * 10,
6685
- y: (originY - footprintCenter.y) * 10
6686
- };
6687
- if (padCenter && padCenterDelta && isZeroishModelCenter(modelCenter.x) && isZeroishModelCenter(modelCenter.y) && isZeroishFootprintDelta(padCenterDelta.x) && isZeroishFootprintDelta(padCenterDelta.y)) {
6688
- return { x: 0, y: 0 };
6689
- }
6690
- return getRotatedOffsetMm({
6691
- bounds,
6692
- rawOffsetMil,
6693
- rotationDeg
6694
- });
6695
- };
6696
- var getCadSvgNodeZOffsetMm = (easyEdaJson) => {
6697
- const svgNode = getCadSvgNode(easyEdaJson);
6698
- if (!svgNode) return null;
6699
- const svgNodeZ = Number(svgNode.svgData.attrs?.z ?? 0);
6700
- if (!Number.isFinite(svgNodeZ)) return null;
6701
- return mil10ToMm(svgNodeZ);
6702
- };
6703
- var getCadSvgNodeModelUuid = (easyEdaJson) => getCadSvgNode(easyEdaJson)?.svgData.attrs?.uuid ?? null;
6704
-
6705
6758
  // lib/websafe/get-easyeda-cad-model-placement.ts
6706
6759
  var placementCache = /* @__PURE__ */ new Map();
6707
6760
  var parseObjBounds2 = (objText) => {
@@ -6896,7 +6949,7 @@ var getPinLabelValues = (labels) => {
6896
6949
  if (typeof labels === "string") return [labels];
6897
6950
  return [...labels];
6898
6951
  };
6899
- var getDiodePortHintsMap = (pinLabels) => {
6952
+ var getPolarizedPortHintsMap = (pinLabels) => {
6900
6953
  const labelsByPin = Object.entries(pinLabels ?? {}).map(([pin, labels]) => ({
6901
6954
  pin,
6902
6955
  labels: getPinLabelValues(labels).map((label) => label.toLowerCase())
@@ -6927,7 +6980,7 @@ var generateTypescriptComponent = ({
6927
6980
  const cadComponent = circuitJson.find((item) => item.type === "cad_component");
6928
6981
  const footprintTsx = generateFootprintTsx(
6929
6982
  circuitJson,
6930
- componentType === "diode" ? { portHintsMap: getDiodePortHintsMap(safePinLabels) } : void 0
6983
+ componentType === "diode" || componentType === "led" ? { portHintsMap: getPolarizedPortHintsMap(safePinLabels) } : void 0
6931
6984
  );
6932
6985
  const simplifiedPinLabels = Object.fromEntries(
6933
6986
  Object.entries(safePinLabels).map(([pin, labels]) => {
@@ -6964,6 +7017,28 @@ ${cadModelLines}
6964
7017
  />
6965
7018
  )
6966
7019
  }
7020
+ `.trim();
7021
+ }
7022
+ if (componentType === "led") {
7023
+ return `
7024
+ import type { LedProps } from "@tscircuit/props"
7025
+
7026
+ export const ${componentName} = (props: LedProps) => {
7027
+ const { name = "LED1", ...restProps } = props
7028
+
7029
+ return (
7030
+ <led
7031
+ name={name}
7032
+ supplierPartNumbers={${JSON.stringify(supplierPartNumbers, null, " ")}}
7033
+ manufacturerPartNumber="${manufacturerPartNumber}"
7034
+ footprint={${footprintTsx}}
7035
+ ${objUrl || stepUrl ? `cadModel={{
7036
+ ${cadModelLines}
7037
+ }}` : ""}
7038
+ {...restProps}
7039
+ />
7040
+ )
7041
+ }
6967
7042
  `.trim();
6968
7043
  }
6969
7044
  return `
@@ -7017,7 +7092,39 @@ var isDiodeCategoryComponent = (betterEasy) => {
7017
7092
  ].some(categoryValueContainsDiode);
7018
7093
  };
7019
7094
 
7095
+ // lib/websafe/convert-to-typescript-component/category-value-contains-led.ts
7096
+ var categoryValueContainsLed = (value) => {
7097
+ if (typeof value === "string") {
7098
+ return /(^|[^a-z])leds?([^a-z]|$)/i.test(value) || /light[-\s]?emitting\s+diodes?/i.test(value);
7099
+ }
7100
+ if (Array.isArray(value)) {
7101
+ return value.some(categoryValueContainsLed);
7102
+ }
7103
+ if (value && typeof value === "object") {
7104
+ return Object.values(value).some(categoryValueContainsLed);
7105
+ }
7106
+ return false;
7107
+ };
7108
+
7109
+ // lib/websafe/convert-to-typescript-component/is-led-category-component.ts
7110
+ var isLedCategoryComponent = (betterEasy) => {
7111
+ const cPara = betterEasy.dataStr.head.c_para;
7112
+ return [
7113
+ betterEasy.tags,
7114
+ cPara.category,
7115
+ cPara.Category,
7116
+ cPara["LCSC Category"],
7117
+ cPara["JLCPCB Category"],
7118
+ betterEasy.category
7119
+ ].some(categoryValueContainsLed);
7120
+ };
7121
+
7020
7122
  // lib/websafe/convert-to-typescript-component/index.tsx
7123
+ var getGeneratedComponentType = (betterEasy) => {
7124
+ if (isLedCategoryComponent(betterEasy)) return "led";
7125
+ if (isDiodeCategoryComponent(betterEasy)) return "diode";
7126
+ return "chip";
7127
+ };
7021
7128
  var convertRawEasyToTsx = async ({ rawEasy }) => {
7022
7129
  const betterEasy = EasyEdaJsonSchema.parse(rawEasy);
7023
7130
  const result = await convertBetterEasyToTsx({
@@ -7035,6 +7142,7 @@ var convertBetterEasyToTsx = async ({
7035
7142
  cadPositionXMm: cadPlacement?.positionXMm,
7036
7143
  cadPositionYMm: cadPlacement?.positionYMm,
7037
7144
  cadPositionZMm: cadPlacement?.positionZMm,
7145
+ cadModelBounds: cadPlacement?.bounds,
7038
7146
  showDesignator: true
7039
7147
  });
7040
7148
  const [cadComponent] = su(circuitJson).cad_component.list();
@@ -7082,7 +7190,7 @@ var convertBetterEasyToTsx = async ({
7082
7190
  stepUrl: modelStepUrl,
7083
7191
  circuitJson,
7084
7192
  supplierPartNumbers,
7085
- componentType: isDiodeCategoryComponent(betterEasy) ? "diode" : "chip"
7193
+ componentType: getGeneratedComponentType(betterEasy)
7086
7194
  });
7087
7195
  };
7088
7196
  var checkModelObjUrlValidity = async (url) => {