@mlightcad/cad-simple-viewer 1.0.0 → 1.0.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 (136) hide show
  1. package/README.md +296 -2
  2. package/dist/index.js +1347 -122
  3. package/dist/index.umd.cjs +2 -2
  4. package/lib/app/AcApContext.d.ts +45 -3
  5. package/lib/app/AcApContext.d.ts.map +1 -1
  6. package/lib/app/AcApContext.js +43 -3
  7. package/lib/app/AcApContext.js.map +1 -1
  8. package/lib/app/AcApDocCreator.d.ts +68 -2
  9. package/lib/app/AcApDocCreator.d.ts.map +1 -1
  10. package/lib/app/AcApDocCreator.js +67 -2
  11. package/lib/app/AcApDocCreator.js.map +1 -1
  12. package/lib/app/AcApDocManager.d.ts +227 -12
  13. package/lib/app/AcApDocManager.d.ts.map +1 -1
  14. package/lib/app/AcApDocManager.js +228 -17
  15. package/lib/app/AcApDocManager.js.map +1 -1
  16. package/lib/app/AcApDocument.d.ts +77 -3
  17. package/lib/app/AcApDocument.d.ts.map +1 -1
  18. package/lib/app/AcApDocument.js +75 -3
  19. package/lib/app/AcApDocument.js.map +1 -1
  20. package/lib/app/AcApFontLoader.d.ts +32 -0
  21. package/lib/app/AcApFontLoader.d.ts.map +1 -1
  22. package/lib/app/AcApFontLoader.js +30 -0
  23. package/lib/app/AcApFontLoader.js.map +1 -1
  24. package/lib/app/AcApSettingManager.d.ts +191 -3
  25. package/lib/app/AcApSettingManager.d.ts.map +1 -1
  26. package/lib/app/AcApSettingManager.js +161 -0
  27. package/lib/app/AcApSettingManager.js.map +1 -1
  28. package/lib/command/AcApConvertToSvgCmd.d.ts +26 -0
  29. package/lib/command/AcApConvertToSvgCmd.d.ts.map +1 -1
  30. package/lib/command/AcApConvertToSvgCmd.js +26 -0
  31. package/lib/command/AcApConvertToSvgCmd.js.map +1 -1
  32. package/lib/command/AcApOpenCmd.d.ts +31 -0
  33. package/lib/command/AcApOpenCmd.d.ts.map +1 -1
  34. package/lib/command/AcApOpenCmd.js +31 -0
  35. package/lib/command/AcApOpenCmd.js.map +1 -1
  36. package/lib/command/AcApPanCmd.d.ts +25 -0
  37. package/lib/command/AcApPanCmd.d.ts.map +1 -1
  38. package/lib/command/AcApPanCmd.js +25 -0
  39. package/lib/command/AcApPanCmd.js.map +1 -1
  40. package/lib/command/AcApQNewCmd.d.ts +26 -0
  41. package/lib/command/AcApQNewCmd.d.ts.map +1 -1
  42. package/lib/command/AcApQNewCmd.js +26 -0
  43. package/lib/command/AcApQNewCmd.js.map +1 -1
  44. package/lib/command/AcApSelectCmd.d.ts +26 -0
  45. package/lib/command/AcApSelectCmd.d.ts.map +1 -1
  46. package/lib/command/AcApSelectCmd.js +26 -0
  47. package/lib/command/AcApSelectCmd.js.map +1 -1
  48. package/lib/command/AcApSvgConvertor.d.ts +48 -0
  49. package/lib/command/AcApSvgConvertor.d.ts.map +1 -1
  50. package/lib/command/AcApSvgConvertor.js +48 -0
  51. package/lib/command/AcApSvgConvertor.js.map +1 -1
  52. package/lib/command/AcApZoomCmd.d.ts +29 -0
  53. package/lib/command/AcApZoomCmd.d.ts.map +1 -1
  54. package/lib/command/AcApZoomCmd.js +29 -0
  55. package/lib/command/AcApZoomCmd.js.map +1 -1
  56. package/lib/command/AcApZoomToBoxCmd.d.ts +57 -0
  57. package/lib/command/AcApZoomToBoxCmd.d.ts.map +1 -1
  58. package/lib/command/AcApZoomToBoxCmd.js +57 -0
  59. package/lib/command/AcApZoomToBoxCmd.js.map +1 -1
  60. package/lib/editor/command/AcEdCommand.d.ts +118 -9
  61. package/lib/editor/command/AcEdCommand.d.ts.map +1 -1
  62. package/lib/editor/command/AcEdCommand.js +113 -9
  63. package/lib/editor/command/AcEdCommand.js.map +1 -1
  64. package/lib/editor/command/AcEdCommandStack.d.ts +59 -5
  65. package/lib/editor/command/AcEdCommandStack.d.ts.map +1 -1
  66. package/lib/editor/command/AcEdCommandStack.js +48 -5
  67. package/lib/editor/command/AcEdCommandStack.js.map +1 -1
  68. package/lib/editor/global/eventBus.d.ts +69 -1
  69. package/lib/editor/global/eventBus.d.ts.map +1 -1
  70. package/lib/editor/global/eventBus.js +37 -0
  71. package/lib/editor/global/eventBus.js.map +1 -1
  72. package/lib/editor/input/AcEdBaseInput.d.ts +65 -1
  73. package/lib/editor/input/AcEdBaseInput.d.ts.map +1 -1
  74. package/lib/editor/input/AcEdBaseInput.js +62 -1
  75. package/lib/editor/input/AcEdBaseInput.js.map +1 -1
  76. package/lib/editor/input/AcEdBoxSelector.d.ts +81 -0
  77. package/lib/editor/input/AcEdBoxSelector.d.ts.map +1 -1
  78. package/lib/editor/input/AcEdBoxSelector.js +80 -0
  79. package/lib/editor/input/AcEdBoxSelector.js.map +1 -1
  80. package/lib/editor/input/AcEdCursorManager.d.ts +95 -8
  81. package/lib/editor/input/AcEdCursorManager.d.ts.map +1 -1
  82. package/lib/editor/input/AcEdCursorManager.js +95 -11
  83. package/lib/editor/input/AcEdCursorManager.js.map +1 -1
  84. package/lib/editor/input/AcEdInputPoint.d.ts +38 -1
  85. package/lib/editor/input/AcEdInputPoint.d.ts.map +1 -1
  86. package/lib/editor/input/AcEdInputPoint.js +38 -1
  87. package/lib/editor/input/AcEdInputPoint.js.map +1 -1
  88. package/lib/editor/input/AcEdJig.d.ts +166 -0
  89. package/lib/editor/input/AcEdJig.d.ts.map +1 -1
  90. package/lib/editor/input/AcEdJig.js +164 -0
  91. package/lib/editor/input/AcEdJig.js.map +1 -1
  92. package/lib/editor/input/AcEdJigLoop.d.ts +49 -0
  93. package/lib/editor/input/AcEdJigLoop.d.ts.map +1 -1
  94. package/lib/editor/input/AcEdJigLoop.js +48 -0
  95. package/lib/editor/input/AcEdJigLoop.js.map +1 -1
  96. package/lib/editor/input/AcEdSelectionSet.d.ts +122 -2
  97. package/lib/editor/input/AcEdSelectionSet.d.ts.map +1 -1
  98. package/lib/editor/input/AcEdSelectionSet.js +117 -1
  99. package/lib/editor/input/AcEdSelectionSet.js.map +1 -1
  100. package/lib/editor/input/AcEditor.d.ts +90 -6
  101. package/lib/editor/input/AcEditor.d.ts.map +1 -1
  102. package/lib/editor/input/AcEditor.js +86 -6
  103. package/lib/editor/input/AcEditor.js.map +1 -1
  104. package/lib/editor/view/AcEdBaseView.d.ts +163 -16
  105. package/lib/editor/view/AcEdBaseView.d.ts.map +1 -1
  106. package/lib/editor/view/AcEdBaseView.js +94 -5
  107. package/lib/editor/view/AcEdBaseView.js.map +1 -1
  108. package/lib/util/AcTrGeometryUtil.d.ts +65 -0
  109. package/lib/util/AcTrGeometryUtil.d.ts.map +1 -1
  110. package/lib/util/AcTrGeometryUtil.js +65 -0
  111. package/lib/util/AcTrGeometryUtil.js.map +1 -1
  112. package/lib/view/AcTrLayer.d.ts +40 -5
  113. package/lib/view/AcTrLayer.d.ts.map +1 -1
  114. package/lib/view/AcTrLayer.js +34 -5
  115. package/lib/view/AcTrLayer.js.map +1 -1
  116. package/lib/view/AcTrLayout.d.ts +122 -23
  117. package/lib/view/AcTrLayout.d.ts.map +1 -1
  118. package/lib/view/AcTrLayout.js +103 -23
  119. package/lib/view/AcTrLayout.js.map +1 -1
  120. package/lib/view/AcTrLayoutView.d.ts +74 -16
  121. package/lib/view/AcTrLayoutView.d.ts.map +1 -1
  122. package/lib/view/AcTrLayoutView.js +65 -16
  123. package/lib/view/AcTrLayoutView.js.map +1 -1
  124. package/lib/view/AcTrLayoutViewManager.d.ts +58 -12
  125. package/lib/view/AcTrLayoutViewManager.d.ts.map +1 -1
  126. package/lib/view/AcTrLayoutViewManager.js +56 -12
  127. package/lib/view/AcTrLayoutViewManager.js.map +1 -1
  128. package/lib/view/AcTrScene.d.ts +48 -4
  129. package/lib/view/AcTrScene.d.ts.map +1 -1
  130. package/lib/view/AcTrScene.js +44 -4
  131. package/lib/view/AcTrScene.js.map +1 -1
  132. package/lib/view/AcTrView2d.d.ts +71 -0
  133. package/lib/view/AcTrView2d.d.ts.map +1 -1
  134. package/lib/view/AcTrView2d.js +65 -0
  135. package/lib/view/AcTrView2d.js.map +1 -1
  136. package/package.json +8 -4
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { AcCmEventManager as m, AcGePoint2d as u, AcGeBox2d as N, AcCmColor as k, AcGeBox3d as $, AcDbDatabase as J, AcDbFileType as G, acdbHostApplicationServices as W, AcDbViewport as K, AcDbRasterImage as Z, AcDbRay as Q, AcDbXline as tt, AcDbHatch as j, AcGePolyline2d as et, AcDbLine as st, AcDbTextStyleTableRecord as it, AcDbMText as nt, AcGiMTextAttachmentPoint as ot, AcGePoint3d as rt, AcGeLoop2d as at, AcGeCircArc2d as ct, AcGeMathUtil as T, AcGeLine2d as ht, AcDbArc as lt, AcGeLine3d as M } from "@mlightcad/data-model";
1
+ import { AcCmEventManager as m, AcGePoint2d as u, AcGeBox2d as N, AcCmColor as k, AcGeBox3d as $, AcDbDatabase as J, AcDbFileType as G, acdbHostApplicationServices as W, AcDbViewport as K, AcDbRasterImage as Z, AcDbRay as Q, AcDbXline as tt, AcDbHatch as j, AcGePolyline2d as et, AcDbLine as st, AcDbTextStyleTableRecord as it, AcDbMText as nt, AcGiMTextAttachmentPoint as ot, AcGePoint3d as rt, AcGeLoop2d as at, AcGeCircArc2d as ct, AcGeMathUtil as T, AcGeLine2d as ht, AcDbArc as lt, AcGeLine3d as L } from "@mlightcad/data-model";
2
2
  import { AcSvgRenderer as dt } from "@mlightcad/svg-renderer";
3
3
  import { find as ut, findIndex as mt, defaults as _t } from "lodash-es";
4
4
  import { AcTrBaseView as wt, AcTrBatchedGroup as pt, AcTrRenderer as ft, AcTrViewportView as yt } from "@mlightcad/three-renderer";
@@ -7,9 +7,16 @@ import vt from "three/examples/jsm/libs/stats.module";
7
7
  import { AxesGizmo as gt, ObjectPosition as xt } from "@mlightcad/three-viewcube";
8
8
  class bt {
9
9
  /**
10
- * Construct one context to bind one drawing database with its viewer
11
- * @param view Input the view used to show the specified drawing
12
- * @param doc Input the document associated with the drawing database
10
+ * Creates a new application context that binds a document with its view.
11
+ *
12
+ * The constructor sets up event listeners to synchronize the document and view:
13
+ * - Entity additions/modifications are reflected in the view
14
+ * - Layer visibility changes update the view
15
+ * - System variable changes (like point display mode) update rendering
16
+ * - Entity selections show/hide grip points
17
+ *
18
+ * @param view - The view used to display the drawing
19
+ * @param doc - The document containing the drawing database
13
20
  */
14
21
  constructor(t, e) {
15
22
  this._view = t, this._doc = e, e.database.events.entityAppended.addEventListener((s) => {
@@ -26,49 +33,122 @@ class bt {
26
33
  t.unhighlight(s.ids);
27
34
  });
28
35
  }
36
+ /**
37
+ * Gets the view component that renders the CAD drawing.
38
+ *
39
+ * @returns The associated view instance
40
+ */
29
41
  get view() {
30
42
  return this._view;
31
43
  }
44
+ /**
45
+ * Gets the document containing the CAD database.
46
+ *
47
+ * @returns The associated document instance
48
+ */
32
49
  get doc() {
33
50
  return this._doc;
34
51
  }
35
52
  }
36
53
  class x {
54
+ /**
55
+ * Creates a new command instance.
56
+ *
57
+ * Initializes the command with empty names. Subclasses should set
58
+ * appropriate global and local names in their constructors.
59
+ */
37
60
  constructor() {
38
61
  this.events = {
62
+ /** Fired just before the command starts executing */
39
63
  commandWillStart: new m(),
64
+ /** Fired after the command finishes executing */
40
65
  commandEnded: new m()
41
66
  }, this._globalName = "", this._localName = "";
42
67
  }
43
68
  /**
44
- * The global or untranslated name associated with the command.
69
+ * Gets the global (untranslated) name of the command.
70
+ *
71
+ * The global name is typically used for programmatic access and
72
+ * should remain consistent across different language localizations.
73
+ *
74
+ * @returns The global command name
45
75
  */
46
76
  get globalName() {
47
77
  return this._globalName;
48
78
  }
79
+ /**
80
+ * Sets the global (untranslated) name of the command.
81
+ *
82
+ * @param value - The global command name (e.g., 'LINE', 'CIRCLE', 'ZOOM')
83
+ */
49
84
  set globalName(t) {
50
85
  this._globalName = t;
51
86
  }
52
87
  /**
53
- * The local or translated name associated with the command.
88
+ * Gets the local (translated) name of the command.
89
+ *
90
+ * The local name is displayed to users and should be localized
91
+ * to the current language/region.
92
+ *
93
+ * @returns The localized command name
54
94
  */
55
95
  get localName() {
56
96
  return this._localName;
57
97
  }
98
+ /**
99
+ * Sets the local (translated) name of the command.
100
+ *
101
+ * @param value - The localized command name (e.g., 'Draw Line', 'Zoom In')
102
+ */
58
103
  set localName(t) {
59
104
  this._localName = t;
60
105
  }
61
106
  /**
62
- * Trigger this command. The children class should not override this method to keep event notification
63
- * work correctly.
64
- * @param context Input current context to execute this command.
107
+ * Triggers the command execution with proper event handling.
108
+ *
109
+ * This method should not be overridden by subclasses as it handles
110
+ * the event notification workflow. Subclasses should implement the
111
+ * `execute()` method instead.
112
+ *
113
+ * The execution flow:
114
+ * 1. Fires `commandWillStart` event
115
+ * 2. Calls the `execute()` method
116
+ * 3. Fires `commandEnded` event
117
+ *
118
+ * @param context - The current application context containing view and document
119
+ *
120
+ * @example
121
+ * ```typescript
122
+ * const command = new MyCommand();
123
+ * command.trigger(docManager.context);
124
+ * ```
65
125
  */
66
126
  tirgger(t) {
67
127
  this.events.commandWillStart.dispatch({ command: this }), this.execute(t), this.events.commandEnded.dispatch({ command: this });
68
128
  }
69
129
  /**
70
- * Execute this command. The children class should override this method to add business logic of this command.
71
- * @param _context Input current context to execute this command.
130
+ * Executes the command logic.
131
+ *
132
+ * This abstract method must be implemented by subclasses to define
133
+ * the specific behavior of the command. The method receives the current
134
+ * application context providing access to the view and document.
135
+ *
136
+ * @param _context - The current application context
137
+ *
138
+ * @example
139
+ * ```typescript
140
+ * execute(context: AcApContext) {
141
+ * const view = context.view;
142
+ * const doc = context.doc;
143
+ *
144
+ * // Get user input
145
+ * const point = await view.editor.getPoint();
146
+ *
147
+ * // Create entity in document
148
+ * const entity = new SomeEntity(point);
149
+ * doc.database.addEntity(entity);
150
+ * }
151
+ * ```
72
152
  */
73
153
  execute(t) {
74
154
  }
@@ -116,6 +196,10 @@ class St {
116
196
  }
117
197
  }
118
198
  const p = class p {
199
+ /**
200
+ * Private constructor to enforce singleton pattern.
201
+ * Initializes the command stack with system and default command groups.
202
+ */
119
203
  constructor() {
120
204
  this._commandsByGroup = [], this._systemCommandGroup = {
121
205
  groupName: p.SYSTEMT_COMMAND_GROUP_NAME,
@@ -127,9 +211,30 @@ const p = class p {
127
211
  commandsByLocalName: /* @__PURE__ */ new Map()
128
212
  }, this._commandsByGroup.push(this._systemCommandGroup), this._commandsByGroup.push(this._defaultCommandGroup);
129
213
  }
214
+ /**
215
+ * Gets the singleton instance of the command stack.
216
+ * Creates a new instance if one doesn't exist.
217
+ *
218
+ * @returns The singleton instance of AcEdCommandStack
219
+ */
130
220
  static get instance() {
131
221
  return p._instance || (p._instance = new p()), p._instance;
132
222
  }
223
+ /**
224
+ * Adds a command to the specified command group.
225
+ *
226
+ * @param cmdGroupName - The name of the command group. If empty, uses the default group.
227
+ * @param cmdGlobalName - The global (untranslated) name of the command. Must be unique within the group.
228
+ * @param cmdLocalName - The local (translated) name of the command. Defaults to global name if empty.
229
+ * @param cmd - The command object to add to the stack.
230
+ *
231
+ * @throws {Error} When the global name is empty or when a command with the same name already exists
232
+ *
233
+ * @example
234
+ * ```typescript
235
+ * commandStack.addCommand('USER', 'LINE', 'ligne', new LineCommand());
236
+ * ```
237
+ */
133
238
  addCommand(t, e, s, n) {
134
239
  if (!e)
135
240
  throw new Error(
@@ -160,6 +265,7 @@ const p = class p {
160
265
  /**
161
266
  * Return an iterator that can be used to traverse all of command objects in this command stack
162
267
  * (that is, the iterator iterates through all commands in all groups).
268
+ *
163
269
  * @returns Return an iterator that can be used to traverse all of command objects in this command
164
270
  * stack.
165
271
  */
@@ -172,7 +278,8 @@ const p = class p {
172
278
  * matched AcEdCommand object is returned. Otherwise undefined is returned to indicate that the command
173
279
  * could not be found. If more than one command of the same name is present in the command stack (that
174
280
  * is, in separate command groups), then the first one found is used.
175
- * @param cmdName Input the command name to search for
281
+ *
282
+ * @param cmdName - Input the command name to search for
176
283
  * @returns Return the matched AcEdCommand object if a match is found. Otherwise, return undefined.
177
284
  */
178
285
  lookupGlobalCmd(t) {
@@ -187,7 +294,8 @@ const p = class p {
187
294
  * AcEdCommand object is returned. Otherwise undefined is returned to indicate that the command could not
188
295
  * be found. If more than one command of the same name is present in the command stack (that is, in
189
296
  * separate command groups), then the first one found is used.
190
- * @param cmdName Input the command name to search for
297
+ *
298
+ * @param cmdName - Input the command name to search for
191
299
  * @returns Return the matched AcEdCommand object if a match is found. Otherwise, return undefined.
192
300
  */
193
301
  lookupLocalCmd(t) {
@@ -200,8 +308,9 @@ const p = class p {
200
308
  * Remove the command with the global and untranslated name `cmdGlobalName` from the `cmdGroupName`
201
309
  * command group. Return true if successful. Return false if no command with the global and untranslated
202
310
  * name `cmdGlobalName` is found in the `cmdGroupName` command group.
203
- * @param cmdGroupName Input the name of the command group containing the command to be removed
204
- * @param cmdGlobalName Input the command name which is to be removed from cmdGroupName
311
+ *
312
+ * @param cmdGroupName - Input the name of the command group containing the command to be removed
313
+ * @param cmdGlobalName - Input the command name which is to be removed from cmdGroupName
205
314
  * @returns Return true if successful. Return false if no command with the global and untranslated
206
315
  * name `cmdGlobalName` is found in the `cmdGroupName` command group.
207
316
  */
@@ -214,7 +323,8 @@ const p = class p {
214
323
  /**
215
324
  * Remove the command group with the name `GroupName` from the command stack and delete the command group
216
325
  * dictionary object and all the AcEdCommand objects stored within it.
217
- * @param groupName Input the name of the command group to be removed from the command stack.
326
+ *
327
+ * @param groupName - Input the name of the command group to be removed from the command stack.
218
328
  * @returns Return true if successful. Return false if no command group is found with the name `GroupName`.
219
329
  */
220
330
  removeGroup(t) {
@@ -248,13 +358,34 @@ function ve(i) {
248
358
  });
249
359
  }
250
360
  var C = /* @__PURE__ */ ((i) => (i[i.NoSpecialCursor = -1] = "NoSpecialCursor", i[i.Crosshair = 0] = "Crosshair", i[i.RectCursor = 1] = "RectCursor", i[i.RubberBand = 2] = "RubberBand", i[i.NotRotated = 3] = "NotRotated", i[i.TargetBox = 4] = "TargetBox", i[i.RotatedCrosshair = 5] = "RotatedCrosshair", i[i.CrosshairNoRotate = 6] = "CrosshairNoRotate", i[i.Invisible = 7] = "Invisible", i[i.EntitySelect = 8] = "EntitySelect", i[i.Parallelogram = 9] = "Parallelogram", i[i.EntitySelectNoPersp = 10] = "EntitySelectNoPersp", i[i.PkfirstOrGrips = 11] = "PkfirstOrGrips", i[i.CrosshairDashed = 12] = "CrosshairDashed", i[i.Grab = 13] = "Grab", i))(C || {});
251
- class Mt {
361
+ class Lt {
362
+ /**
363
+ * Creates a new cursor manager instance.
364
+ *
365
+ * Initializes the cursor cache and creates default cursor definitions.
366
+ */
252
367
  constructor() {
253
368
  this._cursorMap = /* @__PURE__ */ new Map(), this._cursorMap.set(
254
369
  0,
255
370
  this.createRectCrossIcon(10, 10)
256
371
  );
257
372
  }
373
+ /**
374
+ * Sets the cursor for the specified HTML element.
375
+ *
376
+ * Applies the appropriate cursor style based on the cursor type.
377
+ * For built-in cursor types, uses CSS cursor values. For custom
378
+ * cursor types, uses cached SVG-based cursor definitions.
379
+ *
380
+ * @param cursorType - The type of cursor to set
381
+ * @param element - The HTML element to apply the cursor to
382
+ *
383
+ * @example
384
+ * ```typescript
385
+ * const canvas = document.getElementById('canvas') as HTMLCanvasElement;
386
+ * cursorManager.setCursor(AcEdCorsorType.Crosshair, canvas);
387
+ * ```
388
+ */
258
389
  setCursor(t, e) {
259
390
  if (t <= -1)
260
391
  e.style.cursor = "default";
@@ -266,13 +397,24 @@ class Mt {
266
397
  }
267
398
  }
268
399
  /**
269
- * Encode SVG string to one cursor defined using url() in CSS
270
- * @param svgString Input svg string
271
- * @param xOffset Input x offset for cursor hotspot
272
- * @param yOffset Input y offset for cursor hotspot
273
- * @returns
274
- */
275
- encodeSvg(t, e = 0, s = 0) {
400
+ * Encodes an SVG string into a CSS cursor URL.
401
+ *
402
+ * This method converts SVG markup into a data URI that can be used
403
+ * as a CSS cursor value, with specified hotspot coordinates.
404
+ *
405
+ * @param svgString - The SVG markup as a string
406
+ * @param xOffset - X coordinate of the cursor hotspot
407
+ * @param yOffset - Y coordinate of the cursor hotspot
408
+ * @returns CSS cursor string in url() format
409
+ *
410
+ * @example
411
+ * ```typescript
412
+ * const svgCursor = '<svg width="20" height="20">...</svg>';
413
+ * const cursorUrl = cursorManager.encodeSvgToCursor(svgCursor, 10, 10);
414
+ * element.style.cursor = cursorUrl;
415
+ * ```
416
+ */
417
+ encodeSvgToCursor(t, e, s) {
276
418
  return `url('data:image/svg+xml;base64,${btoa(t)}') ${e} ${s}, auto`;
277
419
  }
278
420
  /**
@@ -292,32 +434,68 @@ class Mt {
292
434
  <line x1="0" y1="${n + e}" x2="${e}" y2="${n + e}" stroke="${s}" />
293
435
  </svg>
294
436
  `;
295
- return this.encodeSvg(r, n + e, n + e);
437
+ return this.encodeSvgToCursor(r, n + e, n + e);
296
438
  }
297
439
  }
298
440
  class V {
441
+ /**
442
+ * Creates a new base input instance.
443
+ *
444
+ * @param view - The view that will handle this input operation
445
+ */
299
446
  constructor(t) {
300
447
  this.active = !1, this.isResolvedOrRejected = !1, this.onKeyDown = (e) => {
301
448
  e.code === "Escape" && this.reject("Canceled by user!");
302
449
  }, this.view = t;
303
450
  }
451
+ /**
452
+ * Gets whether this input is currently active.
453
+ *
454
+ * @returns True if the input is active, false otherwise
455
+ */
304
456
  get isActive() {
305
457
  return this.active;
306
458
  }
459
+ /**
460
+ * Activates this input operation.
461
+ * Sets up event listeners and marks the input as active.
462
+ * Subclasses should call super.activate() when overriding.
463
+ */
307
464
  activate() {
308
465
  this.isActive && console.warn("Something wrong here!"), this.active = !0, this.view.canvas.addEventListener("keydown", this.onKeyDown);
309
466
  }
467
+ /**
468
+ * Deactivates this input operation.
469
+ * Removes event listeners and marks the input as inactive.
470
+ * Subclasses should call super.deactivate() when overriding.
471
+ */
310
472
  deactivate() {
311
473
  this.active = !1, this.view.canvas.removeEventListener("keydown", this.onKeyDown);
312
474
  }
475
+ /**
476
+ * Resolves the input operation with the specified result.
477
+ * Automatically deactivates the input and prevents multiple resolutions.
478
+ *
479
+ * @param result - The result to resolve the promise with
480
+ */
313
481
  resolve(t) {
314
482
  this.deactivate(), this._resolve && !this.isResolvedOrRejected && (this._resolve(t), this.isResolvedOrRejected = !0);
315
483
  }
484
+ /**
485
+ * Rejects the input operation with the specified reason.
486
+ * Automatically deactivates the input and prevents multiple rejections.
487
+ *
488
+ * @param reason - The reason for rejecting the input operation
489
+ */
316
490
  reject(t) {
317
491
  this.deactivate(), this._reject && !this.isResolvedOrRejected && (this._reject(t), this.isResolvedOrRejected = !0);
318
492
  }
319
493
  /**
320
- * Start inputting
494
+ * Starts the input operation and returns a promise that resolves with the result.
495
+ * This method activates the input and returns a promise that will be resolved
496
+ * when the user completes the input operation.
497
+ *
498
+ * @returns A promise that resolves with the input result
321
499
  */
322
500
  async start() {
323
501
  return this.isResolvedOrRejected = !1, new Promise((t, e) => {
@@ -325,47 +503,182 @@ class V {
325
503
  });
326
504
  }
327
505
  }
328
- class Et extends V {
506
+ class Mt extends V {
507
+ /**
508
+ * Creates a new jig loop instance.
509
+ *
510
+ * @param view - The view that will handle this jig operation
511
+ */
329
512
  constructor(t) {
330
513
  super(t), this.events = {
514
+ /** Event fired when the mouse position updates */
331
515
  update: new m()
332
516
  }, this.onMouseMove = (e) => {
333
517
  this.curPos.set(e.clientX, e.clientY), this.events.update.dispatch();
334
518
  }, this.curPos = new u();
335
519
  }
520
+ /**
521
+ * Activates the jig loop operation.
522
+ * Sets up the mouse move event listener to track cursor position.
523
+ * Overrides the base class to add mouse move event handling.
524
+ */
336
525
  activate() {
337
526
  super.activate(), this.view.canvas.addEventListener("mousemove", this.onMouseMove);
338
527
  }
528
+ /**
529
+ * Deactivates the jig loop operation.
530
+ * Removes the mouse move event listener.
531
+ * Overrides the base class to clean up mouse move event handling.
532
+ */
339
533
  deactivate() {
340
534
  super.deactivate(), this.view.canvas.removeEventListener("mousemove", this.onMouseMove);
341
535
  }
342
536
  }
343
- class Lt {
537
+ class Et {
538
+ /**
539
+ * Creates a new jig instance for the specified view.
540
+ *
541
+ * Sets up the jig loop and connects update event handling.
542
+ *
543
+ * @param view - The view this jig will operate in
544
+ */
344
545
  constructor(t) {
345
546
  this.onUpdate = () => {
346
547
  this.update();
347
- }, this._view = t, this._jigLoop = new Et(t), this._jigLoop.events.update.addEventListener(this.onUpdate);
548
+ }, this._view = t, this._jigLoop = new Mt(t), this._jigLoop.events.update.addEventListener(this.onUpdate);
348
549
  }
550
+ /**
551
+ * Gets the view associated with this jig.
552
+ *
553
+ * @returns The view instance
554
+ */
349
555
  get view() {
350
556
  return this._view;
351
557
  }
558
+ /**
559
+ * Resolves the jig operation with the specified result.
560
+ *
561
+ * This method should be called when the jig operation completes successfully.
562
+ * It cleans up event listeners and resolves the underlying promise.
563
+ *
564
+ * @param result - The result to return from the jig operation
565
+ *
566
+ * @example
567
+ * ```typescript
568
+ * // In a line drawing jig, when user completes the line
569
+ * if (this.hasValidEndPoint()) {
570
+ * const line = new Line(this.startPoint, this.endPoint);
571
+ * this.resolve(line);
572
+ * }
573
+ * ```
574
+ */
352
575
  resolve(t) {
353
576
  this._jigLoop.events.update.removeEventListener(this.onUpdate), this._jigLoop.resolve(t);
354
577
  }
578
+ /**
579
+ * Rejects the jig operation with an error.
580
+ *
581
+ * This method should be called when the jig operation fails or is cancelled.
582
+ * It cleans up event listeners and rejects the underlying promise.
583
+ *
584
+ * @param reason - The reason for the rejection
585
+ *
586
+ * @example
587
+ * ```typescript
588
+ * // If user cancels or invalid input is detected
589
+ * if (userPressedEscape) {
590
+ * this.reject('Operation cancelled by user');
591
+ * }
592
+ * ```
593
+ */
355
594
  reject(t) {
356
595
  this._jigLoop.events.update.removeEventListener(this.onUpdate), this._jigLoop.reject(t);
357
596
  }
597
+ /**
598
+ * Starts the interactive jig operation.
599
+ *
600
+ * This method initiates both the jig loop and the sampling process.
601
+ * It returns a promise that resolves when the jig operation completes
602
+ * or rejects if an error occurs.
603
+ *
604
+ * @returns Promise that resolves when the jig operation completes
605
+ *
606
+ * @example
607
+ * ```typescript
608
+ * const jig = new MyCustomJig(view);
609
+ * try {
610
+ * const result = await jig.drag();
611
+ * console.log('Jig completed with result:', result);
612
+ * } catch (error) {
613
+ * console.log('Jig was cancelled or failed:', error);
614
+ * }
615
+ * ```
616
+ */
358
617
  async drag() {
359
618
  const t = this._jigLoop.start(), e = this.sampler();
360
619
  await Promise.allSettled([t, e]);
361
620
  }
621
+ /**
622
+ * Abstract method for handling jig input sampling.
623
+ *
624
+ * This method should be overridden by subclasses to implement
625
+ * the specific input handling logic for the jig. It typically:
626
+ * - Gets initial user input (like a start point)
627
+ * - Sets up event listeners for dynamic updates
628
+ * - Handles user interaction until completion
629
+ *
630
+ * The sampler runs concurrently with the jig loop and should
631
+ * call `resolve()` or `reject()` when the operation completes.
632
+ *
633
+ * @example
634
+ * ```typescript
635
+ * async sampler() {
636
+ * // Get initial point
637
+ * const startPoint = await this.view.editor.getPoint();
638
+ *
639
+ * // Set up mouse tracking for dynamic preview
640
+ * this.view.events.mouseMove.addEventListener(this.onMouseMove);
641
+ * this.view.events.mouseClick.addEventListener(this.onMouseClick);
642
+ * }
643
+ * ```
644
+ */
362
645
  async sampler() {
363
646
  }
647
+ /**
648
+ * Called during each update cycle to refresh the jig display.
649
+ *
650
+ * This method should be overridden by subclasses to implement
651
+ * the visual update logic. It's called automatically by the jig loop
652
+ * whenever the display needs to be refreshed (typically on mouse movement).
653
+ *
654
+ * Common update operations include:
655
+ * - Redrawing preview geometry
656
+ * - Updating dimension displays
657
+ * - Refreshing visual feedback elements
658
+ *
659
+ * @example
660
+ * ```typescript
661
+ * update() {
662
+ * if (this.startPoint && this.currentMousePoint) {
663
+ * // Clear previous preview
664
+ * this.clearPreview();
665
+ *
666
+ * // Draw new preview line
667
+ * this.drawPreviewLine(this.startPoint, this.currentMousePoint);
668
+ * }
669
+ * }
670
+ * ```
671
+ */
364
672
  update() {
365
673
  }
366
674
  }
367
675
  const Dt = 16777215, It = "1px";
368
676
  class Ct extends V {
677
+ /**
678
+ * Creates a new box selector instance.
679
+ *
680
+ * @param view - The view that will handle this box selection operation
681
+ */
369
682
  constructor(t) {
370
683
  super(t), this.mouseDown = !1, this.mouseMove = !1, this.mouseDownPositionX = -1, this.mouseDownPositionY = -1, this.mousedown = (e) => {
371
684
  if (e.button === 0) {
@@ -402,16 +715,39 @@ class Ct extends V {
402
715
  this.mouseDown = !1, this.mouseMove = !1, this.mouseDownPositionX = -1, this.mouseDownPositionY = -1;
403
716
  }, this.container = t.canvas, this.color = Dt;
404
717
  }
718
+ /**
719
+ * Activates the box selector.
720
+ * Sets up mouse event listeners for tracking selection area.
721
+ * Overrides the base class to add mouse event handling.
722
+ */
405
723
  activate() {
406
724
  super.activate(), this.active = !0, this.container.addEventListener("pointerdown", this.mousedown), this.container.addEventListener("pointermove", this.mousemove), this.container.addEventListener("pointerup", this.mouseup);
407
725
  }
726
+ /**
727
+ * Deactivates the box selector.
728
+ * Removes mouse event listeners and hides the selection box.
729
+ * Overrides the base class to clean up mouse event handling.
730
+ */
408
731
  deactivate() {
409
732
  super.deactivate(), this.container.removeEventListener("pointerdown", this.mousedown), this.container.removeEventListener("pointermove", this.mousemove), this.container.removeEventListener("pointerup", this.mouseup), this.setRectDomVisible(!1);
410
733
  }
734
+ /**
735
+ * Rejects the box selection operation.
736
+ * Cleans up the selection box DOM element.
737
+ *
738
+ * @param reason - The reason for rejecting the selection operation
739
+ */
411
740
  reject(t) {
412
741
  var e;
413
742
  super.reject(t), (e = this.boxDom) == null || e.remove(), this.boxDom = void 0;
414
743
  }
744
+ /**
745
+ * Draws the selection rectangle on screen.
746
+ * Creates or updates the DOM element representing the selection box.
747
+ *
748
+ * @param leftTop - The top-left corner of the selection rectangle
749
+ * @param rightBottom - The bottom-right corner of the selection rectangle
750
+ */
415
751
  drawRect(t, e) {
416
752
  if (!this.boxDom) {
417
753
  const o = new k();
@@ -421,75 +757,245 @@ class Ct extends V {
421
757
  const s = Math.abs(e.x - t.x), n = Math.abs(e.y - t.y);
422
758
  this.boxDom.style.width = `${s}px`, this.boxDom.style.height = `${n}px`;
423
759
  }
760
+ /**
761
+ * Sets the visibility of the selection rectangle DOM element.
762
+ *
763
+ * @param visible - Whether the selection rectangle should be visible
764
+ */
424
765
  setRectDomVisible(t) {
425
766
  this.boxDom && (this.boxDom.style.display = t ? "inline-block" : "none");
426
767
  }
768
+ /**
769
+ * Converts a screen coordinate box to world coordinate system.
770
+ * Transforms the selection box from screen coordinates to world coordinates
771
+ * for use in entity selection operations.
772
+ *
773
+ * @param box - The selection box in screen coordinates
774
+ * @returns The selection box in world coordinates
775
+ */
427
776
  toWcs(t) {
428
777
  const e = new N(), s = new u(t.min.x, t.min.y), n = new u(t.max.x, t.max.y);
429
778
  return e.expandByPoint(this.view.cwcs2Wcs(s)), e.expandByPoint(this.view.cwcs2Wcs(n)), e;
430
779
  }
431
780
  }
432
781
  class Tt extends V {
782
+ /**
783
+ * Creates a new point input instance.
784
+ *
785
+ * @param view - The view that will handle this point input operation
786
+ */
433
787
  constructor(t) {
434
788
  super(t), this.onClick = (e) => {
435
789
  this.resolve(this.view.cwcs2Wcs({ x: e.clientX, y: e.clientY }));
436
790
  };
437
791
  }
792
+ /**
793
+ * Activates the point input operation.
794
+ * Sets up the click event listener to capture user point selection.
795
+ * Overrides the base class to add click event handling.
796
+ */
438
797
  activate() {
439
798
  super.activate(), this.view.canvas.addEventListener("click", this.onClick);
440
799
  }
800
+ /**
801
+ * Deactivates the point input operation.
802
+ * Removes the click event listener.
803
+ * Overrides the base class to clean up click event handling.
804
+ */
441
805
  deactivate() {
442
806
  super.deactivate(), this.view.canvas.removeEventListener("click", this.onClick);
443
807
  }
444
808
  }
445
809
  class At {
810
+ /**
811
+ * Creates a new editor instance for the specified view.
812
+ *
813
+ * @param view - The view that this editor will handle input for
814
+ */
446
815
  constructor(t) {
447
- this._view = t, this._cursorManager = new Mt();
816
+ this._view = t, this._cursorManager = new Lt();
448
817
  }
818
+ /**
819
+ * Gets the currently active cursor type.
820
+ *
821
+ * @returns The current cursor type, or undefined if none is set
822
+ */
449
823
  get currentCursor() {
450
824
  return this._currentCursor;
451
825
  }
826
+ /**
827
+ * Restores the previously set cursor.
828
+ *
829
+ * This is useful for temporarily changing the cursor and then reverting
830
+ * to the previous state.
831
+ */
452
832
  restoreCursor() {
453
833
  this._previousCursor != null && this.setCursor(this._previousCursor);
454
834
  }
835
+ /**
836
+ * Sets the cursor appearance for the view.
837
+ *
838
+ * The previous cursor type is stored for potential restoration.
839
+ *
840
+ * @param cursorType - The cursor type to set
841
+ *
842
+ * @example
843
+ * ```typescript
844
+ * editor.setCursor(AcEdCorsorType.Crosshair); // For precise point input
845
+ * editor.setCursor(AcEdCorsorType.Grab); // For pan operations
846
+ * ```
847
+ */
455
848
  setCursor(t) {
456
849
  this._cursorManager.setCursor(t, this._view.canvas), this._previousCursor = this._currentCursor, this._currentCursor = t;
457
850
  }
458
851
  /**
459
- * Get user input for a point.
852
+ * Prompts the user to input a point by clicking on the view.
853
+ *
854
+ * This method returns a promise that resolves when the user clicks
855
+ * on the view, providing the world coordinates of the click point.
856
+ *
857
+ * @returns Promise that resolves to the input point coordinates
858
+ *
859
+ * @example
860
+ * ```typescript
861
+ * const startPoint = await editor.getPoint();
862
+ * const endPoint = await editor.getPoint();
863
+ * // Now you can create a line from startPoint to endPoint
864
+ * ```
460
865
  */
461
866
  async getPoint() {
462
867
  return await new Tt(this._view).start();
463
868
  }
464
869
  /**
465
- * Get the selection set obtained.
870
+ * Prompts the user to select entities using box selection.
871
+ *
872
+ * This method allows the user to drag a selection box to select
873
+ * multiple entities at once. The selection behavior follows CAD
874
+ * conventions (left-to-right for crossing, right-to-left for window).
875
+ *
876
+ * @returns Promise that resolves to the selection set containing selected entity IDs
877
+ *
878
+ * @example
879
+ * ```typescript
880
+ * const selection = await editor.getSelection();
881
+ * if (selection.count > 0) {
882
+ * console.log(`Selected ${selection.count} entities`);
883
+ * // Process the selected entities
884
+ * for (const id of selection.ids) {
885
+ * // Do something with each selected entity
886
+ * }
887
+ * }
888
+ * ```
466
889
  */
467
890
  async getSelection() {
468
891
  return await new Ct(this._view).start();
469
892
  }
470
893
  }
471
894
  class Ot {
895
+ /**
896
+ * Creates a new selection set.
897
+ *
898
+ * @param ids - Optional initial array of entity IDs to include in the selection
899
+ *
900
+ * @example
901
+ * ```typescript
902
+ * // Create empty selection set
903
+ * const selectionSet = new AcEdSelectionSet();
904
+ *
905
+ * // Create selection set with initial entities
906
+ * const selectionSet = new AcEdSelectionSet(['entity1', 'entity2']);
907
+ * ```
908
+ */
472
909
  constructor(t = []) {
473
910
  this.events = {
911
+ /** Fired when entities are added to the selection */
474
912
  selectionAdded: new m(),
913
+ /** Fired when entities are removed from the selection */
475
914
  selectionRemoved: new m()
476
915
  }, this._ids = new Set(t);
477
916
  }
917
+ /**
918
+ * Gets an array of all selected entity IDs.
919
+ *
920
+ * @returns Array containing all selected entity IDs
921
+ */
478
922
  get ids() {
479
923
  return Array.from(this._ids);
480
924
  }
925
+ /**
926
+ * Gets the number of selected entities.
927
+ *
928
+ * @returns The count of selected entities
929
+ */
481
930
  get count() {
482
931
  return this._ids.size;
483
932
  }
933
+ /**
934
+ * Adds one or more entities to the selection.
935
+ *
936
+ * Fires a `selectionAdded` event with the added entity IDs.
937
+ * Duplicate IDs are automatically handled by the internal Set.
938
+ *
939
+ * @param value - Single entity ID or array of entity IDs to add
940
+ *
941
+ * @example
942
+ * ```typescript
943
+ * // Add single entity
944
+ * selectionSet.add('entity1');
945
+ *
946
+ * // Add multiple entities
947
+ * selectionSet.add(['entity2', 'entity3', 'entity4']);
948
+ * ```
949
+ */
484
950
  add(t) {
485
951
  Array.isArray(t) ? (t.forEach((e) => this._ids.add(e)), this.events.selectionAdded.dispatch({ ids: t })) : (this._ids.add(t), this.events.selectionAdded.dispatch({ ids: [t] }));
486
952
  }
953
+ /**
954
+ * Removes one or more entities from the selection.
955
+ *
956
+ * Fires a `selectionRemoved` event with the removed entity IDs.
957
+ * Non-existent IDs are silently ignored.
958
+ *
959
+ * @param value - Single entity ID or array of entity IDs to remove
960
+ *
961
+ * @example
962
+ * ```typescript
963
+ * // Remove single entity
964
+ * selectionSet.delete('entity1');
965
+ *
966
+ * // Remove multiple entities
967
+ * selectionSet.delete(['entity2', 'entity3']);
968
+ * ```
969
+ */
487
970
  delete(t) {
488
971
  Array.isArray(t) ? (t.forEach((e) => this._ids.delete(e)), this.events.selectionRemoved.dispatch({ ids: t })) : (this._ids.delete(t), this.events.selectionRemoved.dispatch({ ids: [t] }));
489
972
  }
973
+ /**
974
+ * Checks if an entity is currently selected.
975
+ *
976
+ * @param id - The entity ID to check
977
+ * @returns True if the entity is selected, false otherwise
978
+ *
979
+ * @example
980
+ * ```typescript
981
+ * if (selectionSet.has('entity1')) {
982
+ * console.log('Entity1 is selected');
983
+ * }
984
+ * ```
985
+ */
490
986
  has(t) {
491
987
  return this._ids.has(t);
492
988
  }
989
+ /**
990
+ * Removes all entities from the selection.
991
+ *
992
+ * Fires a `selectionRemoved` event with all previously selected entity IDs.
993
+ *
994
+ * @example
995
+ * ```typescript
996
+ * selectionSet.clear(); // Deselect everything
997
+ * ```
998
+ */
493
999
  clear() {
494
1000
  if (this._ids.size > 0) {
495
1001
  const t = Array.from(this._ids);
@@ -499,11 +1005,23 @@ class Ot {
499
1005
  }
500
1006
  var y = /* @__PURE__ */ ((i) => (i[i.SELECTION = 0] = "SELECTION", i[i.PAN = 1] = "PAN", i))(y || {});
501
1007
  class Nt {
1008
+ /**
1009
+ * Creates a new base view instance.
1010
+ *
1011
+ * Sets up the canvas, initializes internal state, and registers event listeners
1012
+ * for mouse interactions and window resize events.
1013
+ *
1014
+ * @param canvas - The HTML canvas element to render into
1015
+ */
502
1016
  constructor(t) {
503
1017
  this.events = {
1018
+ /** Fired when mouse moves over the view */
504
1019
  mouseMove: new m(),
1020
+ /** Fired when the view is resized */
505
1021
  viewResize: new m(),
1022
+ /** Fired when mouse hovers over an entity */
506
1023
  hover: new m(),
1024
+ /** Fired when mouse stops hovering over an entity */
507
1025
  unhover: new m()
508
1026
  }, this._canvas = t;
509
1027
  const e = t.getBoundingClientRect();
@@ -514,17 +1032,32 @@ class Nt {
514
1032
  }), window.addEventListener("resize", this.onWindowResize.bind(this)), this._selectionBoxSize = 4, this._hoverTimer = null, this._pauseTimer = null, this._hoveredObjectId = null;
515
1033
  }
516
1034
  /**
517
- * The input manager
1035
+ * Gets the input manager for handling user interactions.
1036
+ *
1037
+ * The editor provides high-level methods for getting user input like
1038
+ * point selection, entity selection, and cursor management.
1039
+ *
1040
+ * @returns The editor instance
518
1041
  */
519
1042
  get editor() {
520
1043
  return this._editor;
521
1044
  }
522
1045
  /**
523
- * The size of selection box in pixel unit
1046
+ * Gets the size of the selection box used for entity picking.
1047
+ *
1048
+ * This determines how close the mouse needs to be to an entity
1049
+ * to select it, measured in screen pixels.
1050
+ *
1051
+ * @returns Selection box size in pixels
524
1052
  */
525
1053
  get selectionBoxSize() {
526
1054
  return this._selectionBoxSize;
527
1055
  }
1056
+ /**
1057
+ * Sets the size of the selection box used for entity picking.
1058
+ *
1059
+ * @param value - Selection box size in pixels
1060
+ */
528
1061
  set selectionBoxSize(t) {
529
1062
  this._selectionBoxSize = t;
530
1063
  }
@@ -646,9 +1179,28 @@ class Nt {
646
1179
  }
647
1180
  }
648
1181
  class Pt {
1182
+ /**
1183
+ * Creates a new document instance with an empty database.
1184
+ *
1185
+ * The document is initialized with an "Untitled" title and read-only mode enabled.
1186
+ */
649
1187
  constructor() {
650
1188
  this._fileName = "", this._docTitle = "", this._isReadOnly = !0, this._database = new J(), this.docTitle = "Untitled";
651
1189
  }
1190
+ /**
1191
+ * Opens a CAD document from a URI.
1192
+ *
1193
+ * @param uri - The URI of the CAD file to open
1194
+ * @param options - Options for opening the database, including read-only mode
1195
+ * @returns Promise resolving to true if successful, false if failed
1196
+ *
1197
+ * @example
1198
+ * ```typescript
1199
+ * const success = await document.openUri('https://example.com/drawing.dwg', {
1200
+ * readOnly: true
1201
+ * });
1202
+ * ```
1203
+ */
652
1204
  async openUri(t, e) {
653
1205
  this._uri = t, this._isReadOnly = e && e.readOnly || !1, this._fileName = this.getFileNameFromUri(t);
654
1206
  let s = !0;
@@ -659,6 +1211,22 @@ class Pt {
659
1211
  }
660
1212
  return s;
661
1213
  }
1214
+ /**
1215
+ * Opens a CAD document from file content.
1216
+ *
1217
+ * @param fileName - The name of the file (used to determine file type from extension)
1218
+ * @param content - The file content as string or ArrayBuffer
1219
+ * @param options - Options for opening the database, including read-only mode
1220
+ * @returns Promise resolving to true if successful, false if failed
1221
+ *
1222
+ * @example
1223
+ * ```typescript
1224
+ * const fileContent = await fetch('drawing.dwg').then(r => r.arrayBuffer());
1225
+ * const success = await document.openDocument('drawing.dwg', fileContent, {
1226
+ * readOnly: false
1227
+ * });
1228
+ * ```
1229
+ */
662
1230
  async openDocument(t, e, s) {
663
1231
  var o;
664
1232
  let n = !0;
@@ -675,30 +1243,55 @@ class Pt {
675
1243
  }
676
1244
  return n;
677
1245
  }
1246
+ /**
1247
+ * Gets the URI of the document if opened from a URI.
1248
+ *
1249
+ * @returns The document URI, or undefined if not opened from URI
1250
+ */
678
1251
  get uri() {
679
1252
  return this._uri;
680
1253
  }
681
1254
  /**
682
- * The database object being used by this document instance.
1255
+ * Gets the database object containing all drawing data.
1256
+ *
1257
+ * @returns The underlying CAD database instance
683
1258
  */
684
1259
  get database() {
685
1260
  return this._database;
686
1261
  }
687
1262
  /**
688
- * The window title of the document
1263
+ * Gets the display title of the document.
1264
+ *
1265
+ * @returns The document title displayed in the window/tab
689
1266
  */
690
1267
  get docTitle() {
691
1268
  return this._docTitle;
692
1269
  }
1270
+ /**
1271
+ * Sets the display title of the document.
1272
+ *
1273
+ * Also updates the browser tab title if running in a browser environment.
1274
+ *
1275
+ * @param value - The new document title
1276
+ */
693
1277
  set docTitle(t) {
694
1278
  this._docTitle = t, typeof document < "u" && (document.title = t);
695
1279
  }
696
1280
  /**
697
- * Return true if the document is read only; otherwise, returns false.
1281
+ * Gets whether the document is opened in read-only mode.
1282
+ *
1283
+ * @returns True if the document is read-only, false if editable
698
1284
  */
699
1285
  get isReadOnly() {
700
1286
  return this._isReadOnly;
701
1287
  }
1288
+ /**
1289
+ * Extracts the file name from a URI.
1290
+ *
1291
+ * @param uri - The URI to extract the file name from
1292
+ * @returns The extracted file name, or empty string if extraction fails
1293
+ * @private
1294
+ */
702
1295
  getFileNameFromUri(t) {
703
1296
  try {
704
1297
  const s = new URL(t).pathname.split("/");
@@ -709,12 +1302,39 @@ class Pt {
709
1302
  }
710
1303
  }
711
1304
  class Rt {
1305
+ /**
1306
+ * Converts the current CAD drawing to SVG format and initiates download.
1307
+ *
1308
+ * This method:
1309
+ * - Retrieves all entities from the current document's model space
1310
+ * - Renders each entity using the SVG renderer
1311
+ * - Exports the complete SVG markup
1312
+ * - Automatically downloads the SVG file as 'example.svg'
1313
+ *
1314
+ * @example
1315
+ * ```typescript
1316
+ * const converter = new AcApSvgConvertor();
1317
+ * converter.convert(); // Downloads the drawing as SVG
1318
+ * ```
1319
+ */
712
1320
  convert() {
713
1321
  const t = w.instance.curDocument.database.tables.blockTable.modelSpace.newIterator(), e = new dt();
714
1322
  for (const s of t)
715
1323
  s.draw(e);
716
1324
  this.createFileAndDownloadIt(e.export());
717
1325
  }
1326
+ /**
1327
+ * Creates a downloadable SVG file and triggers the download.
1328
+ *
1329
+ * This method:
1330
+ * - Creates a Blob from the SVG content with proper MIME type
1331
+ * - Generates a temporary download URL
1332
+ * - Creates and triggers a download link
1333
+ * - Cleans up the temporary elements
1334
+ *
1335
+ * @param svgContent - The SVG markup content to download
1336
+ * @private
1337
+ */
718
1338
  createFileAndDownloadIt(t) {
719
1339
  const e = new Blob([t], {
720
1340
  type: "image/svg+xml;charset=utf-8"
@@ -723,44 +1343,115 @@ class Rt {
723
1343
  }
724
1344
  }
725
1345
  class zt extends x {
1346
+ /**
1347
+ * Executes the SVG conversion command.
1348
+ *
1349
+ * Creates a converter instance and initiates the conversion process
1350
+ * for the current document.
1351
+ *
1352
+ * @param _context - The application context (unused in this command)
1353
+ */
726
1354
  execute(t) {
727
1355
  new Rt().convert();
728
1356
  }
729
1357
  }
730
1358
  class Vt extends x {
1359
+ /**
1360
+ * Executes the open file command.
1361
+ *
1362
+ * Emits an 'open-file' event on the global event bus to trigger
1363
+ * the file opening workflow. UI components typically listen for
1364
+ * this event to display file selection dialogs.
1365
+ *
1366
+ * @param _context - The current application context (not used in this command)
1367
+ */
731
1368
  execute(t) {
732
1369
  v.emit("open-file", {});
733
1370
  }
734
1371
  }
735
1372
  class Gt extends x {
1373
+ /**
1374
+ * Executes the quick new command.
1375
+ *
1376
+ * Opens the ISO template from the CDN to create a new document
1377
+ * with standard drawing settings.
1378
+ *
1379
+ * @param _context - The application context (unused in this command)
1380
+ */
736
1381
  execute(t) {
737
1382
  w.instance.openUrl("https://cdn.jsdelivr.net/gh/mlight-lee/cad-data/templates/" + "acadiso.dxf");
738
1383
  }
739
1384
  }
740
1385
  class jt extends x {
1386
+ /**
1387
+ * Executes the select command.
1388
+ *
1389
+ * Sets the view to selection mode and updates the cursor appearance
1390
+ * to indicate that entity selection is active.
1391
+ *
1392
+ * @param context - The application context containing the view
1393
+ */
741
1394
  execute(t) {
742
1395
  t.view.mode = y.SELECTION, t.view.setCursor(C.Crosshair);
743
1396
  }
744
1397
  }
745
1398
  class Yt extends x {
1399
+ /**
1400
+ * Executes the zoom to fit command.
1401
+ *
1402
+ * Calls the view's `zoomToFit()` method to adjust the camera position
1403
+ * and zoom level to display all visible entities within the viewport.
1404
+ *
1405
+ * @param context - The current application context containing the view to zoom
1406
+ */
746
1407
  execute(t) {
747
1408
  t.view.zoomToFit();
748
1409
  }
749
1410
  }
750
- class Xt extends Lt {
1411
+ class Xt extends Et {
1412
+ /**
1413
+ * Creates a new zoom-to-box jig.
1414
+ *
1415
+ * @param view - The view that will be zoomed
1416
+ */
751
1417
  constructor(t) {
752
1418
  super(t);
753
1419
  }
1420
+ /**
1421
+ * Handles the selection sampling and zooming operation.
1422
+ *
1423
+ * This method gets the user's selection box and applies
1424
+ * the zoom operation to fit that area in the view.
1425
+ *
1426
+ * @returns Promise that resolves when the zoom operation completes
1427
+ */
754
1428
  async sampler() {
755
1429
  await w.instance.editor.getSelection().then((t) => this.view.zoomTo(t, 1));
756
1430
  }
757
1431
  }
758
1432
  class Ft extends x {
1433
+ /**
1434
+ * Executes the zoom-to-box command.
1435
+ *
1436
+ * Creates a jig for interactive area selection and initiates
1437
+ * the drag operation for the user to select the zoom area.
1438
+ *
1439
+ * @param context - The application context containing the view
1440
+ * @returns Promise that resolves when the zoom operation completes
1441
+ */
759
1442
  async execute(t) {
760
1443
  await new Xt(t.view).drag();
761
1444
  }
762
1445
  }
763
1446
  class Ut extends x {
1447
+ /**
1448
+ * Executes the pan command.
1449
+ *
1450
+ * Sets the view to pan mode and updates the cursor appearance
1451
+ * to indicate that panning is active.
1452
+ *
1453
+ * @param context - The application context containing the view
1454
+ */
764
1455
  execute(t) {
765
1456
  t.view.mode = y.PAN, t.view.setCursor(C.Grab);
766
1457
  }
@@ -775,29 +1466,42 @@ const kt = (i) => new $(i.min, i.max), $t = (i) => new f.Box3(
775
1466
  const t = new f.Box3();
776
1467
  return t.min.set(i.min.x, i.min.y, 0), t.max.set(i.max.x, i.max.y, 0), t;
777
1468
  }, Kt = {
1469
+ /** Converts Three.js Box2 to CAD geometry Box2d */
778
1470
  threeBo2dToGeBox2d: Wt,
1471
+ /** Converts CAD geometry Box2d to Three.js Box2 */
779
1472
  goBox2dToThreeBox2d: Ht,
1473
+ /** Converts Three.js Box3 to CAD geometry Box3d */
780
1474
  threeBox3dToGeBox3d: kt,
1475
+ /** Converts CAD geometry Box3d to Three.js Box3 */
781
1476
  goBox3dToThreeBox3d: $t,
1477
+ /** Converts Three.js Box3 to CAD geometry Box2d (ignores Z) */
782
1478
  threeBox3dToGeBox2d: qt,
1479
+ /** Converts CAD geometry Box2d to Three.js Box3 (Z=0) */
783
1480
  goBox2dToThreeBox3d: Jt
784
1481
  };
785
1482
  class Zt extends wt {
786
1483
  /**
787
- * Construct one instance of this class
788
- * @param layoutBtrId Input the id of the block table record associated the layout
789
- * @param renderer Input renderer
790
- * @param width Input width of this view
791
- * @param height Input height of this view
1484
+ * Construct one instance of this class.
1485
+ *
1486
+ * @param renderer - Input renderer for this view
1487
+ * @param layoutBtrId - Input the id of the block table record associated the layout
1488
+ * @param width - Input width of this view in pixels
1489
+ * @param height - Input height of this view in pixels
792
1490
  */
793
1491
  constructor(t, e, s, n) {
794
1492
  super(t, s, n), this._layoutBtrId = e, this._mode = y.SELECTION, this._axesGizmo = this.createAxesGizmo(), this._viewportViews = /* @__PURE__ */ new Map();
795
1493
  }
1494
+ /**
1495
+ * Gets the block table record ID associated with this layout.
1496
+ *
1497
+ * @returns The layout's block table record ID
1498
+ */
796
1499
  get layoutBtrId() {
797
1500
  return this._layoutBtrId;
798
1501
  }
799
1502
  /**
800
- * The view mode of the current layout view
1503
+ * The view mode of the current layout view.
1504
+ * Controls how mouse interactions are interpreted (selection vs pan mode).
801
1505
  */
802
1506
  get mode() {
803
1507
  return this._mode;
@@ -810,41 +1514,61 @@ class Zt extends wt {
810
1514
  }), this._cameraControls.update(), this._mode = t;
811
1515
  }
812
1516
  /**
813
- * The number of viewports in this layout view
1517
+ * The number of viewports in this layout view.
1518
+ * Paper space layouts can contain multiple viewports showing different views of model space.
814
1519
  */
815
1520
  get viewportCount() {
816
1521
  return this._viewportViews.size;
817
1522
  }
818
1523
  /**
819
- * Add one viewport view instance to this layout view
820
- * @param viewportView Input one viewport instance
1524
+ * Add one viewport view instance to this layout view.
1525
+ * Viewports are used in paper space layouts to show different views of the model.
1526
+ *
1527
+ * @param viewportView - Input one viewport instance to add
821
1528
  */
822
1529
  addViewport(t) {
823
1530
  this._viewportViews.set(t.viewport.id, t);
824
1531
  }
825
1532
  /**
826
- * Remove the specified viewport view by its id from this layout view
827
- * @param id Input the id of one viewport instance
1533
+ * Remove the specified viewport view by its id from this layout view.
1534
+ *
1535
+ * @param id - Input the id of one viewport instance to remove
828
1536
  */
829
1537
  removeViewport(t) {
830
1538
  this._viewportViews.delete(t);
831
1539
  }
832
1540
  /**
833
- * Resize this layout view
834
- * @param width Input new width of the layout view
835
- * @param height Input new height of the layout view
1541
+ * Resize this layout view.
1542
+ * Updates the view dimensions and notifies all viewports of the size change.
1543
+ *
1544
+ * @param width - Input new width of the layout view in pixels
1545
+ * @param height - Input new height of the layout view in pixels
836
1546
  */
837
1547
  resize(t, e) {
838
1548
  this._height = e, this._width = t, this.updateCameraFrustum(), this._viewportViews.forEach((s) => {
839
1549
  s.update();
840
1550
  });
841
1551
  }
1552
+ /**
1553
+ * Renders the scene in this layout view.
1554
+ * Performs the main rendering pass and then renders any viewports if present.
1555
+ * Updates the axes gizmo to reflect the current camera orientation.
1556
+ *
1557
+ * @param scene - The scene containing the layout data to render
1558
+ */
842
1559
  render(t) {
843
1560
  var s;
844
1561
  this._renderer.clear(), this._renderer.render(t.internalScene, this._camera);
845
1562
  const e = t.modelSpaceLayout;
846
1563
  e && this.drawViewports(e.internalObject), (s = this._axesGizmo) == null || s.update();
847
1564
  }
1565
+ /**
1566
+ * Creates and configures the axes gizmo for this view.
1567
+ * The gizmo shows the current coordinate system orientation and is positioned
1568
+ * at the bottom-left of the view without a Z-axis (2D view).
1569
+ *
1570
+ * @returns The configured axes gizmo instance
1571
+ */
848
1572
  createAxesGizmo() {
849
1573
  return new gt(
850
1574
  this._camera.internalCamera,
@@ -856,8 +1580,11 @@ class Zt extends wt {
856
1580
  );
857
1581
  }
858
1582
  /**
859
- * Draw viewports
860
- * @param scene Input the scene to draw
1583
+ * Draw viewports into the current rendering context.
1584
+ * Handles the complex rendering process for paper space layouts that contain
1585
+ * multiple viewports, each with their own view of model space.
1586
+ *
1587
+ * @param scene - Input the scene object to draw in each viewport
861
1588
  */
862
1589
  drawViewports(t) {
863
1590
  if (this._viewportViews.size > 0) {
@@ -878,11 +1605,17 @@ class Zt extends wt {
878
1605
  }
879
1606
  }
880
1607
  class Qt {
1608
+ /**
1609
+ * Creates a new layout view manager instance.
1610
+ * Initializes with no active layout and an empty collection of views.
1611
+ */
881
1612
  constructor() {
882
1613
  this._activeLayoutBtrId = "", this._layoutViews = /* @__PURE__ */ new Map();
883
1614
  }
884
1615
  /**
885
- * The block table record id associated with the active layout
1616
+ * The block table record id associated with the active layout.
1617
+ * Setting this property switches the active layout and enables/disables
1618
+ * the appropriate layout views.
886
1619
  */
887
1620
  get activeLayoutBtrId() {
888
1621
  return this._activeLayoutBtrId;
@@ -894,44 +1627,60 @@ class Qt {
894
1627
  }
895
1628
  /**
896
1629
  * The active layout view.
1630
+ * Returns the layout view corresponding to the currently active layout,
1631
+ * or undefined if no layout is active or the active layout doesn't exist.
897
1632
  */
898
1633
  get activeLayoutView() {
899
1634
  return this._layoutViews.get(this._activeLayoutBtrId);
900
1635
  }
901
1636
  /**
902
- * Return true if the layout view manager contains one layout view associated with the sepcified block
1637
+ * Return true if the layout view manager contains one layout view associated with the specified block
903
1638
  * table record id. Otherwise it returns false.
904
- * @param name Input the block table record id associated with the layout view
905
- * @returns Return true if the layout view manager contains one layout view associated with the sepcified
1639
+ *
1640
+ * @param layoutBtrId - Input the block table record id associated with the layout view
1641
+ * @returns Return true if the layout view manager contains one layout view associated with the specified
906
1642
  * block table record id. Otherwise it returns false.
907
1643
  */
908
1644
  has(t) {
909
1645
  return this._layoutViews.has(t);
910
1646
  }
911
1647
  /**
912
- * Get the layout view by the block table record id associated with the layout
913
- * @param layoutBtrId Input the id of the block table record associated the layout
914
- * @returns Return the layout view by the block table record id associated with the layout
1648
+ * Get the layout view by the block table record id associated with the layout.
1649
+ *
1650
+ * @param layoutBtrId - Input the id of the block table record associated the layout
1651
+ * @returns Return the layout view by the block table record id associated with the layout,
1652
+ * or undefined if not found
915
1653
  */
916
1654
  getAt(t) {
917
1655
  return this._layoutViews.get(t);
918
1656
  }
919
1657
  /**
920
- * Resize all of layout views managed by layout view manager
921
- * @param width Input new width of the layout view
922
- * @param height Input new height of the layout view
1658
+ * Resize all of layout views managed by layout view manager.
1659
+ * This is typically called when the viewport or container size changes
1660
+ * and all layouts need to update their dimensions.
1661
+ *
1662
+ * @param width - Input new width of the layout view in pixels
1663
+ * @param height - Input new height of the layout view in pixels
923
1664
  */
924
1665
  resize(t, e) {
925
1666
  this._layoutViews.forEach((s) => {
926
1667
  s.resize(t, e);
927
1668
  });
928
1669
  }
1670
+ /**
1671
+ * Adds a layout view to the manager.
1672
+ * The layout view is indexed by its block table record ID for fast lookup.
1673
+ *
1674
+ * @param layoutView - The layout view to add to the manager
1675
+ */
929
1676
  add(t) {
930
1677
  this._layoutViews.set(t.layoutBtrId, t);
931
1678
  }
932
1679
  /**
933
- * Render the specified scene in the current layout view
934
- * @param scene Input the scene to render
1680
+ * Render the specified scene in the current layout view.
1681
+ * Only renders the currently active layout view, if one is set.
1682
+ *
1683
+ * @param scene - Input the scene to render
935
1684
  */
936
1685
  render(t) {
937
1686
  var e;
@@ -946,14 +1695,14 @@ function H(i, t, e = 0, s = i.length - 1, n = te) {
946
1695
  }
947
1696
  const o = i[t];
948
1697
  let r = e, a = s;
949
- for (E(i, e, t), n(i[s], o) > 0 && E(i, e, s); r < a; ) {
950
- for (E(i, r, a), r++, a--; n(i[r], o) < 0; ) r++;
1698
+ for (M(i, e, t), n(i[s], o) > 0 && M(i, e, s); r < a; ) {
1699
+ for (M(i, r, a), r++, a--; n(i[r], o) < 0; ) r++;
951
1700
  for (; n(i[a], o) > 0; ) a--;
952
1701
  }
953
- n(i[e], o) === 0 ? E(i, e, a) : (a++, E(i, a, s)), a <= t && (e = a + 1), t <= a && (s = a - 1);
1702
+ n(i[e], o) === 0 ? M(i, e, a) : (a++, M(i, a, s)), a <= t && (e = a + 1), t <= a && (s = a - 1);
954
1703
  }
955
1704
  }
956
- function E(i, t, e) {
1705
+ function M(i, t, e) {
957
1706
  const s = i[t];
958
1707
  i[t] = i[e], i[e] = s;
959
1708
  }
@@ -1108,7 +1857,7 @@ class ee {
1108
1857
  _chooseSplitIndex(t, e, s) {
1109
1858
  let n, o = 1 / 0, r = 1 / 0;
1110
1859
  for (let a = e; a <= s - e; a++) {
1111
- const c = L(t, 0, a, this.toBBox), l = L(t, a, s, this.toBBox), h = re(c, l), d = R(c) + R(l);
1860
+ const c = E(t, 0, a, this.toBBox), l = E(t, a, s, this.toBBox), h = re(c, l), d = R(c) + R(l);
1112
1861
  h < o ? (o = h, n = a, r = d < r ? d : r) : h === o && d < r && (r = d, n = a);
1113
1862
  }
1114
1863
  return n || s - e;
@@ -1121,7 +1870,7 @@ class ee {
1121
1870
  // total margin of all possible split distributions where each node is at least m full
1122
1871
  _allDistMargin(t, e, s, n) {
1123
1872
  t.children.sort(n);
1124
- const o = this.toBBox, r = L(t, 0, e, o), a = L(t, s - e, s, o);
1873
+ const o = this.toBBox, r = E(t, 0, e, o), a = E(t, s - e, s, o);
1125
1874
  let c = A(r) + A(a);
1126
1875
  for (let l = e; l < s - e; l++) {
1127
1876
  const h = t.children[l];
@@ -1149,9 +1898,9 @@ function se(i, t, e) {
1149
1898
  return -1;
1150
1899
  }
1151
1900
  function b(i, t) {
1152
- L(i, 0, i.children.length, t, i);
1901
+ E(i, 0, i.children.length, t, i);
1153
1902
  }
1154
- function L(i, t, e, s, n) {
1903
+ function E(i, t, e, s, n) {
1155
1904
  n || (n = S(null)), n.minX = 1 / 0, n.minY = 1 / 0, n.maxX = -1 / 0, n.maxY = -1 / 0;
1156
1905
  for (let o = t; o < e; o++) {
1157
1906
  const r = i.children[o];
@@ -1329,6 +2078,10 @@ class ae {
1329
2078
  }
1330
2079
  }
1331
2080
  class ce {
2081
+ /**
2082
+ * Creates a new layout instance.
2083
+ * Initializes the layout with empty collections and a spatial index.
2084
+ */
1332
2085
  constructor() {
1333
2086
  this._group = new f.Group(), this._indexTree = new ee(), this._box = new f.Box3(), this._layers = /* @__PURE__ */ new Map();
1334
2087
  }
@@ -1339,14 +2092,25 @@ class ce {
1339
2092
  get internalObject() {
1340
2093
  return this._group;
1341
2094
  }
2095
+ /**
2096
+ * Gets the map of layers in this layout.
2097
+ *
2098
+ * @returns Map of layer names to layer objects
2099
+ */
1342
2100
  get layers() {
1343
2101
  return this._layers;
1344
2102
  }
2103
+ /**
2104
+ * Gets the bounding box that contains all entities in this layout.
2105
+ *
2106
+ * @returns The layout's bounding box
2107
+ */
1345
2108
  get box() {
1346
2109
  return this._box;
1347
2110
  }
1348
2111
  /**
1349
- * The visibility of this layout
2112
+ * The visibility of this layout.
2113
+ * When set to false, the entire layout and all its contents are hidden.
1350
2114
  */
1351
2115
  get visible() {
1352
2116
  return this._group.visible;
@@ -1355,14 +2119,16 @@ class ce {
1355
2119
  this._group.visible = t;
1356
2120
  }
1357
2121
  /**
1358
- * The number of entities stored in this layer
2122
+ * The number of entities stored in this layout.
2123
+ * Calculates the total by summing entities across all layers.
1359
2124
  */
1360
2125
  get entityCount() {
1361
2126
  let t = 0;
1362
2127
  return this._layers.forEach((e) => t += e.entityCount), t;
1363
2128
  }
1364
2129
  /**
1365
- * The statistics of this layout
2130
+ * The statistics of this layout.
2131
+ * Provides detailed information about memory usage and entity counts.
1366
2132
  */
1367
2133
  get stats() {
1368
2134
  const t = [];
@@ -1384,14 +2150,22 @@ class ce {
1384
2150
  }
1385
2151
  };
1386
2152
  }
2153
+ /**
2154
+ * Clears all entities from the layout.
2155
+ * Removes all layers, resets the bounding box, and clears the spatial index.
2156
+ *
2157
+ * @returns This layout instance for method chaining
2158
+ */
1387
2159
  clear() {
1388
2160
  return this._layers.forEach((t) => {
1389
2161
  this._group.remove(t.internalObject);
1390
2162
  }), this._layers.clear(), this._box.makeEmpty(), this._indexTree.clear(), this;
1391
2163
  }
1392
2164
  /**
1393
- * Re-render points with latest point style settings
1394
- * @param displayMode Input display mode of points
2165
+ * Re-render points with latest point style settings.
2166
+ * Updates the visual representation of all point entities across all layers.
2167
+ *
2168
+ * @param displayMode - Input display mode of points
1395
2169
  */
1396
2170
  rerenderPoints(t) {
1397
2171
  this._layers.forEach((e) => {
@@ -1400,8 +2174,10 @@ class ce {
1400
2174
  }
1401
2175
  /**
1402
2176
  * Return true if the object with the specified object id is intersected with the ray by using raycast.
1403
- * @param objectId Input object id of object to check for intersection with the ray.
1404
- * @param raycaster Input raycaster to check intersection
2177
+ *
2178
+ * @param objectId - Input object id of object to check for intersection with the ray.
2179
+ * @param raycaster - Input raycaster to check intersection
2180
+ * @returns True if the object intersects with the ray, false otherwise
1405
2181
  */
1406
2182
  isIntersectWith(t, e) {
1407
2183
  const s = this.getLayerByObjectId(t);
@@ -1410,9 +2186,13 @@ class ce {
1410
2186
  /**
1411
2187
  * Add one AutoCAD entity into this layout. If layer group referenced by the entity doesn't exist, create one
1412
2188
  * layer group and add this entity this group.
1413
- * @param entity Input AutoCAD entity to be added into this layout.
1414
- * @param extendBbox Input the flag whether to extend the bounding box of the scene by union the bounding box
1415
- * of the specified entity.
2189
+ *
2190
+ * @param entity - Input AutoCAD entity to be added into this layout.
2191
+ * @param extendBbox - Input the flag whether to extend the bounding box of the scene by union the bounding box
2192
+ * of the specified entity. Defaults to true.
2193
+ * @returns This layout instance for method chaining
2194
+ *
2195
+ * @throws {Error} When entity is missing required objectId or layerName
1416
2196
  */
1417
2197
  addEntity(t, e = !0) {
1418
2198
  if (!t.objectId)
@@ -1435,7 +2215,8 @@ class ce {
1435
2215
  }
1436
2216
  /**
1437
2217
  * Remove the specified entity from this layout.
1438
- * @param objectId Input the object id of the entity to remove
2218
+ *
2219
+ * @param objectId - Input the object id of the entity to remove
1439
2220
  * @returns Return true if remove the specified entity successfully. Otherwise, return false.
1440
2221
  */
1441
2222
  remove(t) {
@@ -1445,7 +2226,8 @@ class ce {
1445
2226
  }
1446
2227
  /**
1447
2228
  * Update the specified entity in this layout.
1448
- * @param objectId Input the entity to update
2229
+ *
2230
+ * @param entity - Input the entity to update
1449
2231
  * @returns Return true if update the specified entity successfully. Otherwise, return false.
1450
2232
  */
1451
2233
  update(t) {
@@ -1454,7 +2236,10 @@ class ce {
1454
2236
  return !1;
1455
2237
  }
1456
2238
  /**
1457
- * Hover the specified entities
2239
+ * Hover the specified entities.
2240
+ * Applies hover highlighting to the entities with the given IDs.
2241
+ *
2242
+ * @param ids - Array of entity object IDs to hover
1458
2243
  */
1459
2244
  hover(t) {
1460
2245
  t.forEach((e) => {
@@ -1463,7 +2248,10 @@ class ce {
1463
2248
  });
1464
2249
  }
1465
2250
  /**
1466
- * Unhover the specified entities
2251
+ * Unhover the specified entities.
2252
+ * Removes hover highlighting from the entities with the given IDs.
2253
+ *
2254
+ * @param ids - Array of entity object IDs to unhover
1467
2255
  */
1468
2256
  unhover(t) {
1469
2257
  t.forEach((e) => {
@@ -1472,7 +2260,10 @@ class ce {
1472
2260
  });
1473
2261
  }
1474
2262
  /**
1475
- * Select the specified entities
2263
+ * Select the specified entities.
2264
+ * Applies selection highlighting to the entities with the given IDs.
2265
+ *
2266
+ * @param ids - Array of entity object IDs to select
1476
2267
  */
1477
2268
  select(t) {
1478
2269
  t.forEach((e) => {
@@ -1481,7 +2272,10 @@ class ce {
1481
2272
  });
1482
2273
  }
1483
2274
  /**
1484
- * Unselect the specified entities
2275
+ * Unselect the specified entities.
2276
+ * Removes selection highlighting from the entities with the given IDs.
2277
+ *
2278
+ * @param ids - Array of entity object IDs to unselect
1485
2279
  */
1486
2280
  unselect(t) {
1487
2281
  t.forEach((e) => {
@@ -1489,13 +2283,21 @@ class ce {
1489
2283
  s && s.unselect([e]);
1490
2284
  });
1491
2285
  }
2286
+ /**
2287
+ * Sets the snap points object for this layout.
2288
+ * Replaces any existing snap points object with the new one.
2289
+ *
2290
+ * @param object - The snap points object to display
2291
+ */
1492
2292
  setSnapObject(t) {
1493
2293
  this._snapPointsObject && this._group.remove(this._snapPointsObject), this._snapPointsObject = t, this._group.add(t);
1494
2294
  }
1495
2295
  /**
1496
2296
  * Search entities intersected or contained in the specified bounding box.
1497
- * @param box Input the query bounding box
1498
- * @returns Return query results
2297
+ * Uses the spatial index for efficient querying of entities within the given bounds.
2298
+ *
2299
+ * @param box - Input the query bounding box (2D or 3D)
2300
+ * @returns Return query results containing entity IDs and their bounds
1499
2301
  */
1500
2302
  search(t) {
1501
2303
  return this._indexTree.search({
@@ -1505,16 +2307,23 @@ class ce {
1505
2307
  maxY: t.max.y
1506
2308
  });
1507
2309
  }
2310
+ /**
2311
+ * Finds the layer containing the entity with the specified object ID.
2312
+ *
2313
+ * @param objectId - The object ID to search for
2314
+ * @returns The layer containing the entity, or undefined if not found
2315
+ */
1508
2316
  getLayerByObjectId(t) {
1509
2317
  for (const [e, s] of this._layers)
1510
2318
  if (s.hasEntity(t)) return s;
1511
2319
  }
1512
2320
  /**
1513
2321
  * Get layer group by name. If the layer doesn't exist, create one layer group into this layout.
1514
- * @param name Input layer name
1515
- * @param createIfNotExist Input one flag to indicate whether to create layer group if it doesn't exist in
1516
- * this layout.
1517
- * @returns Return matched layer
2322
+ *
2323
+ * @param name - Input layer name
2324
+ * @param createIfNotExist - Input one flag to indicate whether to create layer group if it doesn't exist in
2325
+ * this layout. Defaults to true.
2326
+ * @returns Return matched layer, or undefined if not found and createIfNotExist is false
1518
2327
  */
1519
2328
  getLayer(t, e = !0) {
1520
2329
  let s = this._layers.get(t);
@@ -1522,6 +2331,11 @@ class ce {
1522
2331
  }
1523
2332
  }
1524
2333
  class he {
2334
+ /**
2335
+ * Creates a new CAD scene instance.
2336
+ *
2337
+ * Initializes the Three.js scene and layout management structures.
2338
+ */
1525
2339
  constructor() {
1526
2340
  this._scene = new f.Scene(), this._layouts = /* @__PURE__ */ new Map(), this._activeLayoutBtrId = "", this._modelSpaceBtrId = "";
1527
2341
  }
@@ -1700,6 +2514,14 @@ const X = {
1700
2514
  background: 0
1701
2515
  };
1702
2516
  class le extends Nt {
2517
+ /**
2518
+ * Creates a new 2D CAD viewer instance.
2519
+ *
2520
+ * @param options - Configuration options for the viewer
2521
+ * @param options.canvas - Optional HTML canvas element. If not provided, a new canvas will be created
2522
+ * @param options.calculateSizeCallback - Optional callback function to calculate canvas size on window resize
2523
+ * @param options.background - Optional background color as hex number (default: 0x000000)
2524
+ */
1703
2525
  constructor(t = X) {
1704
2526
  const e = {
1705
2527
  ...X,
@@ -1728,28 +2550,64 @@ class le extends Nt {
1728
2550
  }
1729
2551
  ), this._missedImages = /* @__PURE__ */ new Map(), this._layoutViewManager = new Qt(), this.initialize(), this.onWindowResize(), this.animate(), this._isDirty = !0;
1730
2552
  }
2553
+ /**
2554
+ * Initializes the viewer after renderer and camera are created.
2555
+ *
2556
+ * This method sets up the initial cursor and can be overridden by child classes
2557
+ * to add custom initialization logic.
2558
+ *
2559
+ * @protected
2560
+ */
1731
2561
  initialize() {
1732
2562
  this.setCursor(C.Crosshair);
1733
2563
  }
1734
2564
  /**
2565
+ * Gets the current view mode (selection or pan).
2566
+ *
2567
+ * @returns The current view mode
1735
2568
  * @inheritdoc
1736
2569
  */
1737
2570
  get mode() {
1738
2571
  const t = this.activeLayoutView;
1739
2572
  return t ? t.mode : y.SELECTION;
1740
2573
  }
2574
+ /**
2575
+ * Sets the view mode (selection or pan).
2576
+ *
2577
+ * @param value - The view mode to set
2578
+ */
1741
2579
  set mode(t) {
1742
2580
  this.activeLayoutView.mode = t, this.editor.getPoint();
1743
2581
  }
2582
+ /**
2583
+ * Gets the Three.js renderer wrapper used for CAD rendering.
2584
+ *
2585
+ * @returns The renderer instance
2586
+ */
1744
2587
  get renderer() {
1745
2588
  return this._renderer;
1746
2589
  }
2590
+ /**
2591
+ * Gets whether the view needs to be re-rendered.
2592
+ *
2593
+ * @returns True if the view is dirty and needs re-rendering
2594
+ */
1747
2595
  get isDirty() {
1748
2596
  return this._isDirty;
1749
2597
  }
2598
+ /**
2599
+ * Sets whether the view needs to be re-rendered.
2600
+ *
2601
+ * @param value - True to mark the view as needing re-rendering
2602
+ */
1750
2603
  set isDirty(t) {
1751
2604
  this._isDirty = t;
1752
2605
  }
2606
+ /**
2607
+ * Gets information about missing data during rendering (fonts and images).
2608
+ *
2609
+ * @returns Object containing maps of missing fonts and images
2610
+ */
1753
2611
  get missedData() {
1754
2612
  return {
1755
2613
  fonts: this._renderer.missedFonts,
@@ -1988,9 +2846,30 @@ class le extends Nt {
1988
2846
  }
1989
2847
  const F = "simsun";
1990
2848
  class B {
2849
+ /**
2850
+ * Gets the singleton instance of the document creator.
2851
+ *
2852
+ * @returns The singleton AcApDocCreator instance
2853
+ */
1991
2854
  static get instance() {
1992
2855
  return B._instance || (B._instance = new B()), B._instance;
1993
2856
  }
2857
+ /**
2858
+ * Creates a simple example document with circular hatches.
2859
+ *
2860
+ * This method generates a 2x2 grid of circular hatched areas,
2861
+ * useful for testing hatch rendering and basic geometry display.
2862
+ *
2863
+ * @param db - The database to add the example entities to
2864
+ *
2865
+ * @example
2866
+ * ```typescript
2867
+ * const creator = AcApDocCreator.instance;
2868
+ * const database = new AcDbDatabase();
2869
+ * creator.createExampleDoc1(database);
2870
+ * // Database now contains 4 circular hatches in a grid
2871
+ * ```
2872
+ */
1994
2873
  createExampleDoc1(t) {
1995
2874
  for (let n = 0; n < 2; ++n)
1996
2875
  for (let o = 0; o < 2; ++o) {
@@ -1998,6 +2877,28 @@ class B {
1998
2877
  a.addVertexAt(0, { x: o * 100, y: n * 100, bulge: 1 }), a.addVertexAt(1, { x: o * 100 + 100, y: n * 100, bulge: 1 }), a.closed = !0, r.add(a), t.tables.blockTable.modelSpace.appendEntity(r);
1999
2878
  }
2000
2879
  }
2880
+ /**
2881
+ * Creates a comprehensive example document with various CAD entities.
2882
+ *
2883
+ * This method generates a more complex document containing:
2884
+ * - Arcs and lines forming geometric shapes
2885
+ * - Complex hatches with boundary loops
2886
+ * - Formatted text (MText) with Chinese characters
2887
+ * - Custom text styles
2888
+ *
2889
+ * This example is useful for testing complex rendering scenarios,
2890
+ * text handling, and international character support.
2891
+ *
2892
+ * @param db - The database to add the example entities to
2893
+ *
2894
+ * @example
2895
+ * ```typescript
2896
+ * const creator = AcApDocCreator.instance;
2897
+ * const database = new AcDbDatabase();
2898
+ * creator.createExampleDoc2(database);
2899
+ * // Database now contains arcs, lines, hatches, and formatted text
2900
+ * ```
2901
+ */
2001
2902
  createExampleDoc2(t) {
2002
2903
  const e = t.tables.blockTable.modelSpace;
2003
2904
  e.appendEntity(this.createArc()), this.createLines().forEach((n) => {
@@ -2051,7 +2952,7 @@ class B {
2051
2952
  createLines() {
2052
2953
  const t = [];
2053
2954
  return t.push(
2054
- new M(
2955
+ new L(
2055
2956
  {
2056
2957
  x: 11600.20888122753,
2057
2958
  y: 85279.57362051727,
@@ -2064,7 +2965,7 @@ class B {
2064
2965
  }
2065
2966
  )
2066
2967
  ), t.push(
2067
- new M(
2968
+ new L(
2068
2969
  {
2069
2970
  x: 11600.20890652924,
2070
2971
  y: 86546.03982284805,
@@ -2077,7 +2978,7 @@ class B {
2077
2978
  }
2078
2979
  )
2079
2980
  ), t.push(
2080
- new M(
2981
+ new L(
2081
2982
  {
2082
2983
  x: 10850.2088602169,
2083
2984
  y: 86546.03967292747,
@@ -2090,7 +2991,7 @@ class B {
2090
2991
  }
2091
2992
  )
2092
2993
  ), t.push(
2093
- new M(
2994
+ new L(
2094
2995
  {
2095
2996
  x: 9050.208855839213,
2096
2997
  y: 86546.0397510943,
@@ -2103,7 +3004,7 @@ class B {
2103
3004
  }
2104
3005
  )
2105
3006
  ), t.push(
2106
- new M(
3007
+ new L(
2107
3008
  {
2108
3009
  x: 8200.209067034302,
2109
3010
  y: 86546.039727177,
@@ -2119,6 +3020,11 @@ class B {
2119
3020
  }
2120
3021
  }
2121
3022
  class de {
3023
+ /**
3024
+ * Creates a new font loader instance.
3025
+ *
3026
+ * @param renderer - The Three.js renderer that will use the loaded fonts
3027
+ */
2122
3028
  constructor(t) {
2123
3029
  this._cadRenderer = t, this._avaiableFonts = [];
2124
3030
  }
@@ -2166,9 +3072,20 @@ class de {
2166
3072
  }
2167
3073
  }
2168
3074
  class w {
3075
+ /**
3076
+ * Private constructor for singleton pattern.
3077
+ *
3078
+ * Creates an empty document with a 2D view and sets up the application context.
3079
+ * Registers default commands and creates an example document.
3080
+ *
3081
+ * @param canvas - Optional HTML canvas element for rendering. If not provided, a new canvas will be created
3082
+ * @private
3083
+ */
2169
3084
  constructor(t) {
2170
3085
  this.events = {
3086
+ /** Fired when a new document is created */
2171
3087
  documentCreated: new m(),
3088
+ /** Fired when a document becomes active */
2172
3089
  documentActivated: new m()
2173
3090
  };
2174
3091
  const e = new Pt();
@@ -2183,72 +3100,190 @@ class w {
2183
3100
  width: window.innerWidth,
2184
3101
  height: window.innerHeight - 30
2185
3102
  }), n = new le({ canvas: t, calculateSizeCallback: s });
2186
- this._context = new bt(n, e), this._fontLoader = new de(n.renderer), W().workingDatabase = e.database, this.registerCommands(), this.createExampleDoc();
2187
- }
3103
+ this._context = new bt(n, e), this._fontLoader = new de(n.renderer), W().workingDatabase = e.database, this.registerCommands();
3104
+ }
3105
+ /**
3106
+ * Creates the singleton instance with an optional canvas element.
3107
+ *
3108
+ * This method should be called before accessing the `instance` property
3109
+ * if you want to provide a specific canvas element.
3110
+ *
3111
+ * @param canvas - Optional HTML canvas element for rendering
3112
+ * @returns The singleton instance
3113
+ *
3114
+ * @example
3115
+ * ```typescript
3116
+ * const canvas = document.getElementById('my-canvas') as HTMLCanvasElement;
3117
+ * const docManager = AcApDocManager.createInstance(canvas);
3118
+ * ```
3119
+ */
2188
3120
  static createInstance(t) {
2189
3121
  return w._instance == null && (w._instance = new w(t)), this._instance;
2190
3122
  }
3123
+ /**
3124
+ * Gets the singleton instance of the document manager.
3125
+ *
3126
+ * Creates a new instance if one doesn't exist yet.
3127
+ *
3128
+ * @returns The singleton document manager instance
3129
+ */
2191
3130
  static get instance() {
2192
3131
  return w._instance || (w._instance = new w()), w._instance;
2193
3132
  }
2194
3133
  /**
2195
- * Current context
3134
+ * Gets the current application context.
3135
+ *
3136
+ * The context binds the current document with its associated view.
3137
+ *
3138
+ * @returns The current application context
2196
3139
  */
2197
3140
  get context() {
2198
3141
  return this._context;
2199
3142
  }
2200
3143
  /**
2201
- * Current open drawing
3144
+ * Gets the currently open CAD document.
3145
+ *
3146
+ * @returns The current document instance
2202
3147
  */
2203
3148
  get curDocument() {
2204
3149
  return this._context.doc;
2205
3150
  }
2206
3151
  /**
2207
- * For now, it is same as property `curDocument`.
3152
+ * Gets the currently active document.
3153
+ *
3154
+ * For now, this is the same as `curDocument` since only one document
3155
+ * can be active at a time.
3156
+ *
3157
+ * @returns The current active document
2208
3158
  */
2209
3159
  get mdiActiveDocument() {
2210
3160
  return this._context.doc;
2211
3161
  }
2212
3162
  /**
2213
- * Current view used to show current drawing
3163
+ * Gets the current 2D view used to display the drawing.
3164
+ *
3165
+ * @returns The current 2D view instance
2214
3166
  */
2215
3167
  get curView() {
2216
3168
  return this._context.view;
2217
3169
  }
3170
+ /**
3171
+ * Gets the editor instance for handling user input.
3172
+ *
3173
+ * @returns The current editor instance
3174
+ */
2218
3175
  get editor() {
2219
3176
  return this._context.view.editor;
2220
3177
  }
2221
3178
  /**
2222
- * Avaiable fonts to load. It means those fonts are avaiable to load. However, it
2223
- * doesn't mean those fonts are already loaded and avaiable to use.
3179
+ * Gets the list of available fonts that can be loaded.
3180
+ *
3181
+ * Note: These fonts are available for loading but may not be loaded yet.
3182
+ *
3183
+ * @returns Array of available font names
2224
3184
  */
2225
3185
  get avaiableFonts() {
2226
3186
  return this._fontLoader.avaiableFonts;
2227
3187
  }
2228
3188
  /**
2229
- * Load the specified fonts
2230
- * @param fonts Input one list of font names
3189
+ * Loads the specified fonts for text rendering.
3190
+ *
3191
+ * @param fonts - Array of font names to load
3192
+ * @returns Promise that resolves when fonts are loaded
3193
+ *
3194
+ * @example
3195
+ * ```typescript
3196
+ * await docManager.loadFonts(['Arial', 'Times New Roman']);
3197
+ * ```
2231
3198
  */
2232
3199
  async loadFonts(t) {
2233
3200
  await this._fontLoader.load(t);
2234
3201
  }
2235
3202
  /**
2236
- * Load default fonts
3203
+ * Loads default fonts for CAD text rendering.
3204
+ *
3205
+ * This method loads either the specified fonts or falls back to default Chinese fonts
3206
+ * (specifically 'simkai') if no fonts are provided. The loaded fonts are used for
3207
+ * rendering CAD text entities like MText and Text in the viewer.
3208
+ *
3209
+ * It is better to load default fonts when viewer is initialized so that the viewer can
3210
+ * render text correctly if fonts used in the document are not available.
3211
+ *
3212
+ * @param fonts - Optional array of font names to load. If not provided or null,
3213
+ * defaults to ['simkai'] for Chinese text support
3214
+ * @returns Promise that resolves when all specified fonts are loaded
3215
+ *
3216
+ * @example
3217
+ * ```typescript
3218
+ * // Load default fonts (simkai)
3219
+ * await docManager.loadDefaultFonts();
3220
+ *
3221
+ * // Load specific fonts
3222
+ * await docManager.loadDefaultFonts(['Arial', 'SimSun']);
3223
+ *
3224
+ * // Load no fonts (empty array)
3225
+ * await docManager.loadDefaultFonts([]);
3226
+ * ```
3227
+ *
3228
+ * @see {@link AcApFontLoader.load} - The underlying font loading implementation
3229
+ * @see {@link createExampleDoc} - Method that uses this for example document creation
3230
+ */
3231
+ async loadDefaultFonts(t) {
3232
+ t == null ? await this._fontLoader.load(["simkai"]) : await this._fontLoader.load(t);
3233
+ }
3234
+ /**
3235
+ * Creates an example CAD document with sample content.
3236
+ *
3237
+ * This method asynchronously loads default fonts, creates example drawing content,
3238
+ * sets up layout information, and zooms the view to fit the content.
3239
+ * The creation is performed after a short delay to ensure proper initialization.
2237
3240
  */
2238
- async loadDefaultFonts() {
2239
- const t = ["simkai"];
2240
- await this._fontLoader.load(t);
2241
- }
2242
3241
  createExampleDoc() {
2243
3242
  setTimeout(async () => {
2244
3243
  await this.loadDefaultFonts(), B.instance.createExampleDoc2(this.curDocument.database), this.setLayoutInfo(), this.curView.zoomToFit();
2245
3244
  });
2246
3245
  }
3246
+ /**
3247
+ * Opens a CAD document from a URL.
3248
+ *
3249
+ * This method loads a document from the specified URL and replaces the current document.
3250
+ * It handles the complete document lifecycle including before/after open events.
3251
+ *
3252
+ * @param url - The URL of the CAD file to open
3253
+ * @param options - Optional database opening options. If not provided, default options with font loader will be used
3254
+ * @returns Promise that resolves to true if the document was successfully opened, false otherwise
3255
+ *
3256
+ * @example
3257
+ * ```typescript
3258
+ * const success = await docManager.openUrl('https://example.com/drawing.dwg');
3259
+ * if (success) {
3260
+ * console.log('Document opened successfully');
3261
+ * }
3262
+ * ```
3263
+ */
2247
3264
  async openUrl(t, e) {
2248
3265
  this.onBeforeOpenDocument(), e = this.setOptions(e);
2249
3266
  const s = await this.context.doc.openUri(t, e);
2250
- this.onAfterOpenDocument(s);
2251
- }
3267
+ return this.onAfterOpenDocument(s), s;
3268
+ }
3269
+ /**
3270
+ * Opens a CAD document from file content.
3271
+ *
3272
+ * This method loads a document from the provided file content (string or binary data)
3273
+ * and replaces the current document. It handles the complete document lifecycle
3274
+ * including before/after open events.
3275
+ *
3276
+ * @param fileName - The name of the file being opened (used for format detection)
3277
+ * @param content - The file content as string or ArrayBuffer
3278
+ * @param options - Database opening options including font loader settings
3279
+ * @returns Promise that resolves to true if the document was successfully opened, false otherwise
3280
+ *
3281
+ * @example
3282
+ * ```typescript
3283
+ * const fileContent = await file.arrayBuffer();
3284
+ * const success = await docManager.openDocument('drawing.dwg', fileContent, options);
3285
+ * ```
3286
+ */
2252
3287
  async openDocument(t, e, s) {
2253
3288
  this.onBeforeOpenDocument(), s = this.setOptions(s);
2254
3289
  const n = await this.context.doc.openDocument(
@@ -2256,8 +3291,22 @@ class w {
2256
3291
  e,
2257
3292
  s
2258
3293
  );
2259
- this.onAfterOpenDocument(n);
2260
- }
3294
+ return this.onAfterOpenDocument(n), n;
3295
+ }
3296
+ /**
3297
+ * Registers all default commands available in the CAD viewer.
3298
+ *
3299
+ * This method sets up the command system by registering built-in commands including:
3300
+ * - pan: Pan/move the view
3301
+ * - select: Select entities
3302
+ * - zoom: Zoom in/out
3303
+ * - zoomw: Zoom to window/box
3304
+ * - csvg: Convert to SVG
3305
+ * - qnew: Quick new document
3306
+ * - open: Open document
3307
+ *
3308
+ * All commands are registered under the system command group.
3309
+ */
2261
3310
  registerCommands() {
2262
3311
  const t = _.instance;
2263
3312
  t.addCommand(
@@ -2297,21 +3346,72 @@ class w {
2297
3346
  new Vt()
2298
3347
  );
2299
3348
  }
3349
+ /**
3350
+ * Executes a command by its string name.
3351
+ *
3352
+ * This method looks up a registered command by name and executes it with the current context.
3353
+ * If the command is not found, no action is taken.
3354
+ *
3355
+ * @param cmdStr - The command string to execute (e.g., 'pan', 'zoom', 'select')
3356
+ *
3357
+ * @example
3358
+ * ```typescript
3359
+ * docManager.sendStringToExecute('zoom');
3360
+ * docManager.sendStringToExecute('pan');
3361
+ * ```
3362
+ */
2300
3363
  sendStringToExecute(t) {
2301
3364
  const s = _.instance.lookupGlobalCmd(t);
2302
3365
  s == null || s.execute(this.context);
2303
3366
  }
3367
+ /**
3368
+ * Performs cleanup operations before opening a new document.
3369
+ *
3370
+ * This protected method is called automatically before any document opening operation.
3371
+ * It clears the current view to prepare for the new document content.
3372
+ *
3373
+ * @protected
3374
+ */
2304
3375
  onBeforeOpenDocument() {
2305
3376
  this.curView.clear();
2306
3377
  }
3378
+ /**
3379
+ * Performs setup operations after a document opening attempt.
3380
+ *
3381
+ * This protected method is called automatically after any document opening operation.
3382
+ * If the document was successfully opened, it dispatches the documentActivated event,
3383
+ * sets up layout information, and zooms the view to fit the content.
3384
+ *
3385
+ * @param isSuccess - Whether the document was successfully opened
3386
+ * @protected
3387
+ */
2307
3388
  onAfterOpenDocument(t) {
2308
3389
  t && (this.events.documentActivated.dispatch({
2309
3390
  doc: this.context.doc
2310
3391
  }), this.setLayoutInfo(), this.curView.zoomToFit());
2311
3392
  }
3393
+ /**
3394
+ * Sets up or validates database opening options.
3395
+ *
3396
+ * This private method ensures that the options object has a font loader configured.
3397
+ * If no options are provided, creates new options with the font loader.
3398
+ * If options are provided but missing a font loader, adds the font loader.
3399
+ *
3400
+ * @param options - Optional database opening options to validate/modify
3401
+ * @returns The validated options object with font loader configured
3402
+ * @private
3403
+ */
2312
3404
  setOptions(t) {
2313
3405
  return t == null ? t = { fontLoader: this._fontLoader } : t.fontLoader == null && (t.fontLoader = this._fontLoader), t;
2314
3406
  }
3407
+ /**
3408
+ * Configures layout information for the current view.
3409
+ *
3410
+ * This private method sets up the active layout block table record ID and
3411
+ * model space block table record ID based on the current document's space configuration.
3412
+ *
3413
+ * @private
3414
+ */
2315
3415
  setLayoutInfo() {
2316
3416
  const t = this.curView;
2317
3417
  t.activeLayoutBtrId = this.curDocument.database.currentSpaceId, t.modelSpaceBtrId = this.curDocument.database.currentSpaceId;
@@ -2328,12 +3428,35 @@ const ue = {
2328
3428
  class I {
2329
3429
  constructor() {
2330
3430
  this.events = {
3431
+ /** Fired when any setting is modified */
2331
3432
  modified: new m()
2332
3433
  };
2333
3434
  }
3435
+ /**
3436
+ * Gets the singleton instance of the settings manager.
3437
+ *
3438
+ * Creates a new instance if one doesn't exist yet.
3439
+ *
3440
+ * @returns The singleton settings manager instance
3441
+ */
2334
3442
  static get instance() {
2335
3443
  return this._instance || (this._instance = new I()), this._instance;
2336
3444
  }
3445
+ /**
3446
+ * Sets a setting value and persists it to localStorage.
3447
+ *
3448
+ * Fires a modified event after the setting is saved.
3449
+ *
3450
+ * @template K - The setting key type
3451
+ * @param key - The setting key to modify
3452
+ * @param value - The new value for the setting
3453
+ *
3454
+ * @example
3455
+ * ```typescript
3456
+ * settings.set('isShowToolbar', false);
3457
+ * settings.set('fontMapping', { 'Arial': 'Helvetica' });
3458
+ * ```
3459
+ */
2337
3460
  set(t, e) {
2338
3461
  const s = this.settings;
2339
3462
  s[t] = e, localStorage.setItem(U, JSON.stringify(s)), this.events.modified.dispatch({
@@ -2341,53 +3464,155 @@ class I {
2341
3464
  value: e
2342
3465
  });
2343
3466
  }
3467
+ /**
3468
+ * Gets a setting value.
3469
+ *
3470
+ * Returns the stored value or the default value if not set.
3471
+ *
3472
+ * @template K - The setting key type
3473
+ * @param key - The setting key to retrieve
3474
+ * @returns The setting value
3475
+ *
3476
+ * @example
3477
+ * ```typescript
3478
+ * const isDebug = settings.get('isDebug');
3479
+ * const fontMapping = settings.get('fontMapping');
3480
+ * ```
3481
+ */
2344
3482
  get(t) {
2345
3483
  return this.settings[t];
2346
3484
  }
3485
+ /**
3486
+ * Toggles a boolean setting value.
3487
+ *
3488
+ * Only works with boolean settings. The caller should ensure the setting is boolean.
3489
+ *
3490
+ * @template K - The setting key type
3491
+ * @param key - The boolean setting key to toggle
3492
+ *
3493
+ * @example
3494
+ * ```typescript
3495
+ * settings.toggle('isDebug'); // false -> true
3496
+ * settings.toggle('isShowToolbar'); // true -> false
3497
+ * ```
3498
+ */
2347
3499
  toggle(t) {
2348
3500
  const e = this.get(t);
2349
3501
  this.set(t, !e);
2350
3502
  }
3503
+ /**
3504
+ * Gets whether debug mode is enabled.
3505
+ *
3506
+ * @returns True if debug mode is enabled
3507
+ */
2351
3508
  get isDebug() {
2352
3509
  return this.get("isDebug");
2353
3510
  }
3511
+ /**
3512
+ * Sets whether debug mode is enabled.
3513
+ *
3514
+ * @param value - True to enable debug mode
3515
+ */
2354
3516
  set isDebug(t) {
2355
3517
  this.set("isDebug", t);
2356
3518
  }
3519
+ /**
3520
+ * Gets whether the command line is visible.
3521
+ *
3522
+ * @returns True if command line should be shown
3523
+ */
2357
3524
  get isShowCommandLine() {
2358
3525
  return this.get("isShowCommandLine");
2359
3526
  }
3527
+ /**
3528
+ * Sets whether the command line is visible.
3529
+ *
3530
+ * @param value - True to show the command line
3531
+ */
2360
3532
  set isShowCommandLine(t) {
2361
3533
  this.set("isShowCommandLine", t);
2362
3534
  }
3535
+ /**
3536
+ * Gets whether coordinate display is visible.
3537
+ *
3538
+ * @returns True if coordinates should be displayed
3539
+ */
2363
3540
  get isShowCoordinate() {
2364
3541
  return this.get("isShowCoordinate");
2365
3542
  }
3543
+ /**
3544
+ * Sets whether coordinate display is visible.
3545
+ *
3546
+ * @param value - True to show coordinates
3547
+ */
2366
3548
  set isShowCoordinate(t) {
2367
3549
  this.set("isShowCoordinate", t);
2368
3550
  }
3551
+ /**
3552
+ * Gets whether the toolbar is visible.
3553
+ *
3554
+ * @returns True if toolbar should be shown
3555
+ */
2369
3556
  get isShowToolbar() {
2370
3557
  return this.get("isShowToolbar");
2371
3558
  }
3559
+ /**
3560
+ * Sets whether the toolbar is visible.
3561
+ *
3562
+ * @param value - True to show the toolbar
3563
+ */
2372
3564
  set isShowToolbar(t) {
2373
3565
  this.set("isShowToolbar", t);
2374
3566
  }
3567
+ /**
3568
+ * Gets whether performance statistics are displayed.
3569
+ *
3570
+ * @returns True if stats should be shown
3571
+ */
2375
3572
  get isShowStats() {
2376
3573
  return this.get("isShowStats");
2377
3574
  }
3575
+ /**
3576
+ * Sets whether performance statistics are displayed.
3577
+ *
3578
+ * @param value - True to show stats
3579
+ */
2378
3580
  set isShowStats(t) {
2379
3581
  this.set("isShowStats", t);
2380
3582
  }
3583
+ /**
3584
+ * Gets the font mapping configuration.
3585
+ *
3586
+ * @returns The current font mapping
3587
+ */
2381
3588
  get fontMapping() {
2382
3589
  return this.get("fontMapping");
2383
3590
  }
3591
+ /**
3592
+ * Sets the font mapping configuration.
3593
+ *
3594
+ * @param value - The new font mapping
3595
+ */
2384
3596
  set fontMapping(t) {
2385
3597
  this.set("fontMapping", t);
2386
3598
  }
3599
+ /**
3600
+ * Sets a single font mapping entry.
3601
+ *
3602
+ * @param originalFont - The original font name
3603
+ * @param mappedFont - The replacement font name
3604
+ */
2387
3605
  setFontMapping(t, e) {
2388
3606
  const s = this.get("fontMapping");
2389
3607
  s[t] = e, this.set("fontMapping", s);
2390
3608
  }
3609
+ /**
3610
+ * Gets the current settings object.
3611
+ *
3612
+ * This method combines localStorage values with default values.
3613
+ *
3614
+ * @returns The current settings object
3615
+ */
2391
3616
  get settings() {
2392
3617
  const t = localStorage.getItem(U), e = t == null ? {} : JSON.parse(t);
2393
3618
  return _t(e, ue);
@@ -2410,8 +3635,8 @@ export {
2410
3635
  x as AcEdCommand,
2411
3636
  _ as AcEdCommandStack,
2412
3637
  C as AcEdCorsorType,
2413
- Mt as AcEdCursorManager,
2414
- Lt as AcEdJig,
3638
+ Lt as AcEdCursorManager,
3639
+ Et as AcEdJig,
2415
3640
  Ot as AcEdSelectionSet,
2416
3641
  y as AcEdViewMode,
2417
3642
  At as AcEditor,