{
  "version": 3,
  "sources": ["../src/denormalise.ts"],
  "sourcesContent": ["import cloneDeep from 'lodash/cloneDeep'\n\nimport logger from './util/logger'\n\nimport type {\n    ArcEntity,\n    Block,\n    CircleEntity,\n    DimensionEntity,\n    EllipseEntity,\n    Entity,\n    InsertEntity,\n    LineEntity,\n    MTextEntity,\n    ParsedDXF,\n    PolylineEntity,\n    SplineEntity,\n    TextEntity,\n    Transform,\n} from './types'\n\ntype BlockBasePointAdjuster = (entity: Entity, block: Block) => void\n\nfunction adjustLineForBlockBasePoint(entity: Entity, block: Block): void {\n  const line = entity as LineEntity\n  line.start.x -= block.x\n  line.start.y -= block.y\n  line.end.x -= block.x\n  line.end.y -= block.y\n}\n\nfunction adjustPolylineForBlockBasePoint(entity: Entity, block: Block): void {\n  const poly = entity as PolylineEntity\n  for (const v of poly.vertices) {\n    if (v.x !== undefined) v.x -= block.x\n    if (v.y !== undefined) v.y -= block.y\n  }\n}\n\nfunction adjustCircleForBlockBasePoint(entity: Entity, block: Block): void {\n  const circle = entity as CircleEntity\n  circle.x -= block.x\n  circle.y -= block.y\n}\n\nfunction adjustEllipseForBlockBasePoint(entity: Entity, block: Block): void {\n  const ellipse = entity as EllipseEntity\n  ellipse.x -= block.x\n  ellipse.y -= block.y\n}\n\nfunction adjustArcForBlockBasePoint(entity: Entity, block: Block): void {\n  const arc = entity as ArcEntity\n  arc.x -= block.x\n  arc.y -= block.y\n}\n\nfunction adjustSplineForBlockBasePoint(entity: Entity, block: Block): void {\n  const spline = entity as SplineEntity\n  for (const cp of spline.controlPoints) {\n    cp.x -= block.x\n    cp.y -= block.y\n  }\n}\n\nfunction adjustTextForBlockBasePoint(entity: Entity, block: Block): void {\n  const text = entity as TextEntity\n  if (text.x !== undefined) text.x -= block.x\n  if (text.y !== undefined) text.y -= block.y\n  if (text.x2 !== undefined) text.x2 -= block.x\n  if (text.y2 !== undefined) text.y2 -= block.y\n}\n\nfunction adjustMTextForBlockBasePoint(entity: Entity, block: Block): void {\n  const mtext = entity as MTextEntity\n  if (mtext.x !== undefined) mtext.x -= block.x\n  if (mtext.y !== undefined) mtext.y -= block.y\n}\n\nfunction adjustDimensionForBlockBasePoint(entity: Entity, block: Block): void {\n  const dim = entity as DimensionEntity\n  dim.start.x -= block.x\n  dim.start.y -= block.y\n  dim.textMidpoint.x -= block.x\n  dim.textMidpoint.y -= block.y\n  dim.measureStart.x -= block.x\n  dim.measureStart.y -= block.y\n  dim.measureEnd.x -= block.x\n  dim.measureEnd.y -= block.y\n}\n\nconst BLOCK_BASEPOINT_ADJUSTERS: Record<string, BlockBasePointAdjuster> = {\n  LINE: adjustLineForBlockBasePoint,\n  LWPOLYLINE: adjustPolylineForBlockBasePoint,\n  POLYLINE: adjustPolylineForBlockBasePoint,\n  CIRCLE: adjustCircleForBlockBasePoint,\n  ELLIPSE: adjustEllipseForBlockBasePoint,\n  ARC: adjustArcForBlockBasePoint,\n  SPLINE: adjustSplineForBlockBasePoint,\n  TEXT: adjustTextForBlockBasePoint,\n  MTEXT: adjustMTextForBlockBasePoint,\n  DIMENSION: adjustDimensionForBlockBasePoint,\n}\n\nfunction applyBlockBasePointAdjustment(entity: Entity, block: Block): void {\n  // https://github.com/bjnortier/dxf/issues/52\n  // See Issue 52. If we don't modify the entity coordinates here it creates an\n  // issue with the transformation matrices (which are only applied AFTER block\n  // insertion modifications has been applied).\n  const adjust = BLOCK_BASEPOINT_ADJUSTERS[entity.type]\n  if (adjust) adjust(entity, block)\n}\n\nfunction computeRectangularArrayVectors(insert: InsertEntity): {\n  rowVec: { x: number; y: number }\n  colVec: { x: number; y: number }\n} {\n  const rowCount = insert.rowCount ?? 1\n  const columnCount = insert.columnCount ?? 1\n  const rowSpacing = insert.rowSpacing ?? 0\n  const columnSpacing = insert.columnSpacing ?? 0\n  const rotation = insert.rotation ?? 0\n\n  // It appears that the rectangular array is affected by rotation, but NOT by scale.\n  if (rowCount <= 1 && columnCount <= 1) {\n    return { rowVec: { x: 0, y: 0 }, colVec: { x: 0, y: 0 } }\n  }\n\n  const cos = Math.cos((rotation * Math.PI) / 180)\n  const sin = Math.sin((rotation * Math.PI) / 180)\n  return {\n    rowVec: { x: -sin * rowSpacing, y: cos * rowSpacing },\n    colVec: { x: cos * columnSpacing, y: sin * columnSpacing },\n  }\n}\n\nfunction expandInsert(\n  insert: InsertEntity,\n  blocksByName: Record<string, Block>,\n  transforms: Transform[],\n  gatherEntities: (entities: Entity[], transforms: Transform[]) => Entity[],\n): Entity[] {\n  const block = blocksByName[insert.block]\n  if (!block) {\n    logger.error('no block found for insert. block:', insert.block)\n    return []\n  }\n\n  const rowCount = insert.rowCount ?? 1\n  const columnCount = insert.columnCount ?? 1\n  const { rowVec, colVec } = computeRectangularArrayVectors(insert)\n\n  const current: Entity[] = []\n  for (let r = 0; r < rowCount; r++) {\n    for (let c = 0; c < columnCount; c++) {\n      const t: Transform = {\n        x: insert.x + rowVec.x * r + colVec.x * c,\n        y: insert.y + rowVec.y * r + colVec.y * c,\n        scaleX: insert.scaleX,\n        scaleY: insert.scaleY,\n        scaleZ: insert.scaleZ,\n        extrusionX: insert.extrusionX,\n        extrusionY: insert.extrusionY,\n        extrusionZ: insert.extrusionZ,\n        rotation: insert.rotation,\n      }\n\n      const transforms2 = transforms.slice(0)\n      transforms2.push(t)\n\n      // Use the insert layer\n      const blockEntities = block.entities.map((be: Entity) => {\n        const be2 = cloneDeep(be)\n        be2.layer = insert.layer\n        applyBlockBasePointAdjustment(be2, block)\n        return be2\n      })\n\n      current.push(...gatherEntities(blockEntities, transforms2))\n    }\n  }\n\n  return current\n}\n\nexport default function denormalise(parseResult: ParsedDXF): Entity[] {\n  const blocksByName = parseResult.blocks.reduce(\n    (acc: { [name: string]: Block }, b: Block) => {\n      acc[b.name] = b\n      return acc\n    },\n    {},\n  )\n\n  const gatherEntities = (\n    entities: Entity[],\n    transforms: Transform[],\n  ): Entity[] => {\n    const current: Entity[] = []\n    for (const e of entities) {\n      if (e.type === 'INSERT') {\n        current.push(\n          ...expandInsert(e as InsertEntity, blocksByName, transforms, gatherEntities),\n        )\n      } else {\n        // Top-level entity. Clone and add the transforms\n        // The transforms are reversed so they occur in\n        // order of application - i.e. the transform of the\n        // top-level insert is applied last\n        const e2 = cloneDeep(e)\n        e2.transforms = transforms.slice().reverse()\n        current.push(e2)\n      }\n    }\n    return current\n  }\n\n  return gatherEntities(parseResult.entities, [])\n}\n"],
  "mappings": "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",
  "names": ["logger", "cloneDeep"]
}
