3dviewer-sdk 1.0.12 → 1.0.13

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.
@@ -1,461 +0,0 @@
1
- const DEFAULT_API_BASE_URL = "https://dev.3dviewer.anybim.vn";
2
- const DEFAULT_VIEWER_ORIGIN = "http://localhost:3000";
3
- export class FilesModule {
4
- constructor(viewer) {
5
- this.viewer = viewer;
6
- this.config = {};
7
- this.operationStartTime = 0;
8
- this.state = {
9
- isLoading: false,
10
- stage: "idle",
11
- };
12
- this.lastUploadSession = null;
13
- // Bind external event helpers to internal typed emitter events.
14
- this.on = {
15
- state: (cb) => this.viewer._on("files:state", cb),
16
- uploadStart: (cb) => this.viewer._on("files:upload:start", cb),
17
- uploadSuccess: (cb) => this.viewer._on("files:upload:success", cb),
18
- uploadError: (cb) => this.viewer._on("files:upload:error", cb),
19
- conversionStart: (cb) => this.viewer._on("files:conversion:start", cb),
20
- conversionSuccess: (cb) => this.viewer._on("files:conversion:success", cb),
21
- conversionError: (cb) => this.viewer._on("files:conversion:error", cb),
22
- renderStart: (cb) => this.viewer._on("files:render:start", cb),
23
- renderSuccess: (cb) => this.viewer._on("files:render:success", cb),
24
- renderError: (cb) => this.viewer._on("files:render:error", cb),
25
- loadSuccess: (cb) => this.viewer._on("files:load:success", cb),
26
- loadError: (cb) => this.viewer._on("files:load:error", cb),
27
- };
28
- }
29
- // Merge file-pipeline runtime config.
30
- setConfig(next) {
31
- this.config = { ...this.config, ...next };
32
- }
33
- // Return a snapshot of current loading state.
34
- getState() {
35
- return { ...this.state };
36
- }
37
- // ---------- public pipeline ----------
38
- // Upload file to conversion server and keep generated baseFileId in session.
39
- async upload(file) {
40
- const target = this.resolveFile(file);
41
- return this.withOperation({ stage: "uploading", message: "Uploading file..." }, async () => {
42
- var _a;
43
- this.viewer._emit("files:upload:start", { fileName: target.name });
44
- await this.uploadInternal(target);
45
- const baseFileId = ((_a = this.getUploadSessionForFile(target)) === null || _a === void 0 ? void 0 : _a.baseFileId) || "";
46
- this.viewer._emit("files:upload:success", { fileName: target.name, baseFileId });
47
- return { fileName: target.name, baseFileId };
48
- });
49
- }
50
- // Trigger conversion flow and resolve final viewer metadata.
51
- async convert(file, options = {}) {
52
- const target = this.resolveFile(file);
53
- return this.withOperation({ stage: "converting", message: "Converting file..." }, async () => {
54
- this.viewer._emit("files:conversion:start", { fileName: target.name });
55
- try {
56
- const prepared = await this.convertInternal(target, options);
57
- this.viewer._emit("files:conversion:success", prepared);
58
- return prepared;
59
- }
60
- catch (e) {
61
- this.viewer._emit("files:conversion:error", { fileName: target.name, error: this.toErrorMessage(e) });
62
- throw e;
63
- }
64
- });
65
- }
66
- // Convenience API: upload first, then convert in one call.
67
- async prepare(file, options = {}) {
68
- const target = this.resolveFile(file);
69
- return this.withOperation({ stage: "uploading", message: "Preparing file..." }, async () => {
70
- await this.uploadInternal(target);
71
- const prepared = await this.convertInternal(target, options);
72
- return prepared;
73
- });
74
- }
75
- // Trigger the newer downloadUrl-based conversion flow.
76
- async convertV2(options) {
77
- return this.withOperation({ stage: "converting", message: "Converting file..." }, async () => {
78
- this.viewer._emit("files:conversion:start", { fileName: options.filename });
79
- try {
80
- const prepared = await this.convertV2Internal(options);
81
- this.viewer._emit("files:conversion:success", prepared);
82
- return prepared;
83
- }
84
- catch (e) {
85
- this.viewer._emit("files:conversion:error", { fileName: options.filename, error: this.toErrorMessage(e) });
86
- throw e;
87
- }
88
- });
89
- }
90
- // Check stream file info by one or more baseFileId values.
91
- async checkFileInfo(baseFileIds) {
92
- const payload = this.buildFileInfoPayload(baseFileIds);
93
- const hostConversion = await this.resolveHostConversion();
94
- const url = `${hostConversion}/api/StreamFile/info`;
95
- const response = await fetch(url, {
96
- method: "POST",
97
- headers: {
98
- "Content-Type": "application/json",
99
- Accept: "application/json",
100
- },
101
- body: JSON.stringify(payload),
102
- });
103
- if (!response.ok) {
104
- throw new Error(`Check file info failed (${response.status} ${response.statusText})`);
105
- }
106
- const text = await response.text();
107
- if (!text)
108
- return null;
109
- try {
110
- return JSON.parse(text);
111
- }
112
- catch {
113
- return text;
114
- }
115
- }
116
- // Open iframe with an already prepared viewer URL.
117
- open(input) {
118
- const url = input.url;
119
- this.viewer._emit("files:render:start", { url });
120
- try {
121
- this.viewer.open(url);
122
- this.viewer._emit("files:render:success", { url });
123
- }
124
- catch (e) {
125
- this.viewer._emit("files:render:error", { url, error: this.toErrorMessage(e) });
126
- throw e;
127
- }
128
- }
129
- // Full pipeline: upload + convert + open iframe.
130
- async render(file, options = {}) {
131
- const target = this.resolveFile(file);
132
- return this.withOperation({ stage: "uploading", message: "Uploading + converting + opening..." }, async () => {
133
- await this.upload(target);
134
- const prepared = await this.convert(target, options);
135
- // open viewer
136
- this.updateState({ stage: "rendering", message: "Opening viewer..." });
137
- this.open(prepared);
138
- this.viewer._emit("files:load:success", prepared);
139
- return prepared;
140
- });
141
- }
142
- // Resolve file argument, fallback to options.file, and persist it back.
143
- resolveFile(file) {
144
- const optFile = this.viewer.getOptions().file;
145
- const target = file || optFile;
146
- if (!target)
147
- throw new Error("No file provided. Pass a File or set options.file");
148
- // store back to viewer options (optional)
149
- this.viewer.patchOptions({ file: target });
150
- return target;
151
- }
152
- // Trim input URL and remove trailing slash.
153
- normalizeBaseUrl(input) {
154
- return input.trim().replace(/\/+$/, "");
155
- }
156
- // Resolve API base URL with default fallback.
157
- resolveBaseUrl() {
158
- const raw = this.config.baseUrl || this.viewer.getOptions().baseUrl || DEFAULT_API_BASE_URL;
159
- return this.normalizeBaseUrl(raw);
160
- }
161
- // Resolve viewer route path (e.g. /mainviewer).
162
- resolveViewerPath() {
163
- const configuredPath = this.config.viewerPath || this.viewer.getOptions().viewerPath;
164
- if (!configuredPath) {
165
- const viewerUrl = this.viewer.getOptions().url;
166
- if (viewerUrl) {
167
- try {
168
- const pathname = new URL(viewerUrl, window.location.href).pathname;
169
- if (pathname && pathname !== "/")
170
- return pathname;
171
- }
172
- catch {
173
- // Fallback to default path below.
174
- }
175
- }
176
- }
177
- const p = (configuredPath || "/mainviewer").trim();
178
- if (!p)
179
- return "/mainviewer";
180
- return p.startsWith("/") ? p : `/${p}`;
181
- }
182
- // Viewer host used to open iframe after conversion completes.
183
- resolveViewerOrigin() {
184
- const configuredBaseUrl = this.config.baseUrl || this.viewer.getOptions().baseUrl;
185
- if (configuredBaseUrl) {
186
- try {
187
- return this.normalizeBaseUrl(new URL(configuredBaseUrl, window.location.href).origin);
188
- }
189
- catch {
190
- // Fallback to viewer URL below.
191
- }
192
- }
193
- const viewerUrl = this.viewer.getOptions().url;
194
- if (viewerUrl) {
195
- try {
196
- return this.normalizeBaseUrl(new URL(viewerUrl, window.location.href).origin);
197
- }
198
- catch {
199
- // Fallback to default origin below.
200
- }
201
- }
202
- return this.normalizeBaseUrl(DEFAULT_VIEWER_ORIGIN);
203
- }
204
- // Build conversion service root from API base URL.
205
- resolveHostConversion() {
206
- const baseUrl = this.resolveBaseUrl();
207
- return baseUrl.endsWith("/service/conversion") ? baseUrl : `${baseUrl}/service/conversion`;
208
- }
209
- // Resolve upload path sent to conversion APIs.
210
- getUploadPath() {
211
- return this.config.uploadPath || this.viewer.getOptions().uploadPath || ".";
212
- }
213
- // Build a stable in-memory signature to identify same file uploads.
214
- fileSignature(file) {
215
- return `${file.name}::${file.size}::${file.lastModified}`;
216
- }
217
- // Create a UUID-like baseFileId when caller does not provide one.
218
- createBaseFileId() {
219
- if (typeof crypto !== "undefined" && "randomUUID" in crypto)
220
- return crypto.randomUUID();
221
- return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
222
- const r = Math.floor(Math.random() * 16);
223
- const v = c === "x" ? r : (r & 0x3) | 0x8;
224
- return v.toString(16);
225
- });
226
- }
227
- // Create upload session metadata reused between upload and convert.
228
- createUploadSession(file) {
229
- return {
230
- signature: this.fileSignature(file),
231
- baseFileId: this.createBaseFileId(),
232
- fileName: file.name,
233
- uploadPath: this.getUploadPath(),
234
- };
235
- }
236
- // Return previous upload session for same file and upload path.
237
- getUploadSessionForFile(file) {
238
- if (!this.lastUploadSession)
239
- return null;
240
- const sameFile = this.lastUploadSession.signature === this.fileSignature(file);
241
- const samePath = this.lastUploadSession.uploadPath === this.getUploadPath();
242
- return sameFile && samePath ? this.lastUploadSession : null;
243
- }
244
- // Call upload endpoint and persist upload session on success.
245
- async uploadInternal(file) {
246
- this.updateState({ stage: "uploading", message: "Uploading file..." });
247
- try {
248
- const existing = this.getUploadSessionForFile(file);
249
- const session = existing || this.createUploadSession(file);
250
- const hostConversion = this.resolveHostConversion();
251
- const path = this.getUploadPath();
252
- // upload endpoint
253
- const url = `${hostConversion}/api/File/upload?path=${encodeURIComponent(path)}`;
254
- const formData = new FormData();
255
- formData.append("file", file, file.name);
256
- const res = await fetch(url, { method: "POST", body: formData, headers: { Accept: "text/plain" } });
257
- if (!res.ok)
258
- throw new Error(`Upload failed (${res.status} ${res.statusText})`);
259
- this.lastUploadSession = session;
260
- }
261
- catch (e) {
262
- const msg = this.toErrorMessage(e);
263
- this.viewer._emit("files:upload:error", { fileName: file.name, error: msg });
264
- throw e;
265
- }
266
- }
267
- // Build StreamFile payload compatible with conversion service.
268
- buildCachePayload(file, baseFileId, options = {}) {
269
- const createdDate = new Date().toISOString();
270
- return {
271
- filename: file.name,
272
- ...(options.downloadUrl ? { downloadUrl: options.downloadUrl } : {}),
273
- baseFileId,
274
- baseMajorRev: 0,
275
- baseMinorRev: 0,
276
- isChecked: false,
277
- status: { size: file.size },
278
- child: [],
279
- isDirectory: false,
280
- createdDate,
281
- cacheStatus: 0,
282
- modelFileId: "",
283
- id: "",
284
- originalFilePath: this.getUploadPath(),
285
- streamLocation: null,
286
- converter: "Hoops",
287
- originalSize: 0,
288
- cacheSize: 0,
289
- importTime: 0,
290
- importAssemblyTreeTime: 0,
291
- creator: {
292
- id: "00000000-0000-0000-0000-000000000000",
293
- name: "Anonymous",
294
- },
295
- originalFile: file.name,
296
- multiStream: false,
297
- isRootModel: 0,
298
- extraConvertOutput: "",
299
- cacheFilename: null,
300
- errorMassage: null,
301
- convertOptions: {
302
- convert3DModel: 1,
303
- convert2DSheet: 1,
304
- extractProperties: 1,
305
- childModels: 0,
306
- },
307
- drawingConvertStatus: {
308
- convert3DModel: 5,
309
- convert2DSheet: 5,
310
- extractProperties: 5,
311
- },
312
- attemptedConvertTimes: 0,
313
- };
314
- }
315
- // Build payload for POST /api/StreamFile/convert.
316
- buildConvertV2Payload(options) {
317
- var _a, _b;
318
- const convertOptions = {
319
- convert3DModel: 1,
320
- convert2DSheet: 1,
321
- extractProperties: 1,
322
- childModels: 0,
323
- ...options.convertOptions,
324
- };
325
- return {
326
- filename: options.filename,
327
- originalFilePath: options.originalFilePath,
328
- convertOptions,
329
- downloadUrl: options.downloadUrl,
330
- baseFileId: options.baseFileId,
331
- baseMajorRev: (_a = options.baseMajorRev) !== null && _a !== void 0 ? _a : 0,
332
- baseMinorRev: (_b = options.baseMinorRev) !== null && _b !== void 0 ? _b : 0,
333
- };
334
- }
335
- buildFileInfoPayload(baseFileIds) {
336
- const ids = (Array.isArray(baseFileIds) ? baseFileIds : [baseFileIds])
337
- .map((baseFileId) => String(baseFileId).trim())
338
- .filter(Boolean);
339
- if (ids.length === 0) {
340
- throw new Error("No baseFileId provided");
341
- }
342
- return ids.map((baseFileId) => ({ baseFileId }));
343
- }
344
- // Submit conversion/caching request and return service response.
345
- async cacheFile(file, baseFileId, options = {}) {
346
- const hostConversion = await this.resolveHostConversion();
347
- const url = `${hostConversion}/api/StreamFile?overwrite=true&ignore_line_weight=1`;
348
- const payload = this.buildCachePayload(file, baseFileId, options);
349
- const response = await fetch(url, {
350
- method: "POST",
351
- headers: {
352
- "Content-Type": "application/json",
353
- Accept: "application/json",
354
- },
355
- body: JSON.stringify(payload),
356
- });
357
- if (!response.ok) {
358
- throw new Error(`Cache/convert failed (${response.status} ${response.statusText})`);
359
- }
360
- return (await response.json());
361
- }
362
- // Submit conversion request to the newer downloadUrl-based endpoint.
363
- async cacheFileV2(options) {
364
- const hostConversion = await this.resolveHostConversion();
365
- const params = new URLSearchParams();
366
- if (typeof options.overwrite === "boolean") {
367
- params.set("overwrite", String(options.overwrite));
368
- }
369
- if (options.project) {
370
- params.set("project", options.project);
371
- }
372
- const query = params.toString();
373
- const url = `${hostConversion}/api/StreamFile/convert${query ? `?${query}` : ""}`;
374
- const payload = this.buildConvertV2Payload(options);
375
- const response = await fetch(url, {
376
- method: "POST",
377
- headers: {
378
- "Content-Type": "application/json",
379
- Accept: "application/json",
380
- },
381
- body: JSON.stringify(payload),
382
- });
383
- if (!response.ok) {
384
- throw new Error(`Cache/convert v2 failed (${response.status} ${response.statusText})`);
385
- }
386
- return (await response.json());
387
- }
388
- // Convert file and generate final iframe URL with query string.
389
- async convertInternal(file, options = {}) {
390
- var _a, _b, _c, _d;
391
- this.updateState({ stage: "converting", message: "Converting file..." });
392
- const uploadSession = this.getUploadSessionForFile(file) || this.createUploadSession(file);
393
- const seedBaseFileId = uploadSession.baseFileId;
394
- // 1) request cache/convert
395
- const cacheResult = await this.cacheFile(file, seedBaseFileId, options);
396
- const baseFileId = (_a = cacheResult.baseFileId) !== null && _a !== void 0 ? _a : seedBaseFileId;
397
- const baseMajorRev = (_b = cacheResult.baseMajorRev) !== null && _b !== void 0 ? _b : 0;
398
- const baseMinorRev = (_c = cacheResult.baseMinorRev) !== null && _c !== void 0 ? _c : 0;
399
- const fileName = cacheResult.filename || cacheResult.fileName || file.name;
400
- const cacheListItem = { baseFileId, baseMajorRev, baseMinorRev, fileName };
401
- // Single-shot mode: one conversion request only, no polling retry.
402
- if (cacheResult.cacheStatus !== 2) {
403
- throw new Error(`Conversion not ready after first request (cacheStatus=${(_d = cacheResult.cacheStatus) !== null && _d !== void 0 ? _d : "unknown"})`);
404
- }
405
- // 3) build viewer url
406
- const query = new URLSearchParams({ fileList: JSON.stringify([cacheListItem]) }).toString();
407
- const viewerBase = this.resolveViewerOrigin();
408
- const viewerPath = this.resolveViewerPath();
409
- const url = `${viewerBase}${viewerPath}?${query}`;
410
- return { baseFileId, baseMajorRev, baseMinorRev, fileName, query, url };
411
- }
412
- async convertV2Internal(options) {
413
- var _a, _b, _c, _d, _e;
414
- this.updateState({ stage: "converting", message: "Converting file..." });
415
- const cacheResult = await this.cacheFileV2(options);
416
- const baseFileId = (_a = cacheResult.baseFileId) !== null && _a !== void 0 ? _a : options.baseFileId;
417
- const baseMajorRev = (_c = (_b = cacheResult.baseMajorRev) !== null && _b !== void 0 ? _b : options.baseMajorRev) !== null && _c !== void 0 ? _c : 0;
418
- const baseMinorRev = (_e = (_d = cacheResult.baseMinorRev) !== null && _d !== void 0 ? _d : options.baseMinorRev) !== null && _e !== void 0 ? _e : 0;
419
- const fileName = cacheResult.filename || cacheResult.fileName || options.filename;
420
- if (cacheResult.cacheStatus !== undefined && cacheResult.cacheStatus !== 2) {
421
- throw new Error(`Conversion not ready after v2 request (cacheStatus=${cacheResult.cacheStatus})`);
422
- }
423
- const cacheListItem = { baseFileId, baseMajorRev, baseMinorRev, fileName };
424
- const query = new URLSearchParams({ fileList: JSON.stringify([cacheListItem]) }).toString();
425
- const viewerBase = this.resolveViewerOrigin();
426
- const viewerPath = this.resolveViewerPath();
427
- const url = `${viewerBase}${viewerPath}?${query}`;
428
- return { baseFileId, baseMajorRev, baseMinorRev, fileName, query, url };
429
- }
430
- // Update internal loading state and emit state event.
431
- updateState(next) {
432
- const elapsedMs = this.operationStartTime > 0 ? Date.now() - this.operationStartTime : 0;
433
- this.state = { ...this.state, ...next, elapsedMs };
434
- this.viewer._emit("files:state", this.state);
435
- }
436
- // Shared wrapper to handle loading state lifecycle and top-level errors.
437
- async withOperation(initial, run) {
438
- // shared operation wrapper for loading state and errors
439
- this.operationStartTime = Date.now();
440
- this.updateState({
441
- isLoading: true,
442
- stage: initial.stage,
443
- message: initial.message,
444
- });
445
- try {
446
- const result = await run();
447
- this.updateState({ isLoading: false, stage: "completed", message: "Completed" });
448
- return result;
449
- }
450
- catch (e) {
451
- const msg = this.toErrorMessage(e);
452
- this.updateState({ isLoading: false, stage: "error", message: msg });
453
- this.viewer._emit("files:load:error", { error: msg });
454
- throw e;
455
- }
456
- }
457
- // Normalize unknown error shape into displayable message.
458
- toErrorMessage(e) {
459
- return e instanceof Error ? e.message : String(e);
460
- }
461
- }
@@ -1,28 +0,0 @@
1
- import { Viewer3D } from "../viewer";
2
- export declare class InteractionModule {
3
- private viewer;
4
- on: {
5
- panChange: (cb: (payload: {
6
- enabled: boolean;
7
- }) => void) => () => void;
8
- };
9
- constructor(viewer: Viewer3D);
10
- enablePan(): void;
11
- disablePan(): void;
12
- select(): void;
13
- areaSelect(): void;
14
- orbit(): void;
15
- rotateZ(): void;
16
- walkThrough(): void;
17
- zoomWindow(): void;
18
- zoomFit(): void;
19
- drawModeShaded(): void;
20
- drawModeWireframe(): void;
21
- drawModeHiddenLine(): void;
22
- drawModeShadedWire(): void;
23
- drawModeXRay(): void;
24
- drawModeGhosting(): void;
25
- explode(magnitude: number): void;
26
- explodeOff(): void;
27
- private setDrawMode;
28
- }
@@ -1,63 +0,0 @@
1
- import { ViewerMessageType } from "../contracts/messages";
2
- export class InteractionModule {
3
- constructor(viewer) {
4
- this.viewer = viewer;
5
- this.on = {
6
- panChange: (cb) => this.viewer._on("interaction:pan-change", cb),
7
- };
8
- }
9
- enablePan() {
10
- this.viewer.postToViewer(ViewerMessageType.PAN_TOGGLE, { enabled: true });
11
- }
12
- disablePan() {
13
- this.viewer.postToViewer(ViewerMessageType.PAN_TOGGLE, { enabled: false });
14
- }
15
- select() {
16
- this.viewer.postToViewer(ViewerMessageType.SELECT);
17
- }
18
- areaSelect() {
19
- this.viewer.postToViewer(ViewerMessageType.AREA_SELECT);
20
- }
21
- orbit() {
22
- this.viewer.postToViewer(ViewerMessageType.ORBIT);
23
- }
24
- rotateZ() {
25
- this.viewer.postToViewer(ViewerMessageType.ROTATE_Z);
26
- }
27
- walkThrough() {
28
- this.viewer.postToViewer(ViewerMessageType.WALK_THROUGH);
29
- }
30
- zoomWindow() {
31
- this.viewer.postToViewer(ViewerMessageType.ZOOM_WINDOW);
32
- }
33
- zoomFit() {
34
- this.viewer.postToViewer(ViewerMessageType.ZOOM_FIT);
35
- }
36
- drawModeShaded() {
37
- this.setDrawMode("shaded");
38
- }
39
- drawModeWireframe() {
40
- this.setDrawMode("wireframe");
41
- }
42
- drawModeHiddenLine() {
43
- this.setDrawMode("hidden-line");
44
- }
45
- drawModeShadedWire() {
46
- this.setDrawMode("shaded-wire");
47
- }
48
- drawModeXRay() {
49
- this.setDrawMode("xray");
50
- }
51
- drawModeGhosting() {
52
- this.setDrawMode("ghosting");
53
- }
54
- explode(magnitude) {
55
- this.viewer.postToViewer(ViewerMessageType.EXPLODE, { magnitude });
56
- }
57
- explodeOff() {
58
- this.explode(0);
59
- }
60
- setDrawMode(mode) {
61
- this.viewer.postToViewer(ViewerMessageType.DRAW_MODE, { mode });
62
- }
63
- }
@@ -1,8 +0,0 @@
1
- import { type LanguageCode } from "../contracts/messages";
2
- import { Viewer3D } from "../viewer";
3
- export declare class LanguageModule {
4
- private viewer;
5
- constructor(viewer: Viewer3D);
6
- change(language: LanguageCode): void;
7
- set(language: LanguageCode): void;
8
- }
@@ -1,15 +0,0 @@
1
- import { ViewerMessageType } from "../contracts/messages";
2
- export class LanguageModule {
3
- constructor(viewer) {
4
- this.viewer = viewer;
5
- }
6
- change(language) {
7
- this.viewer.postToViewer(ViewerMessageType.LANGUAGE_CHANGE, {
8
- language,
9
- timestamp: Date.now(),
10
- });
11
- }
12
- set(language) {
13
- this.change(language);
14
- }
15
- }
@@ -1,26 +0,0 @@
1
- import { Viewer3D } from "../viewer";
2
- import { type MarkupAction, type MarkupListItem } from "../contracts/messages";
3
- export declare type MarkupRequestOptions = {
4
- timeoutMs?: number;
5
- };
6
- export declare class MarkupModule {
7
- private viewer;
8
- constructor(viewer: Viewer3D);
9
- action(action: MarkupAction): void;
10
- drawLine(): void;
11
- drawArrow(): void;
12
- drawCircle(): void;
13
- drawEllipse(): void;
14
- drawRectangle(): void;
15
- drawPolygon(): void;
16
- drawPolyline(): void;
17
- drawTextBox(): void;
18
- drawNote(): void;
19
- drawCallout(): void;
20
- drawCloud(): void;
21
- drawFreehand(): void;
22
- save(options?: MarkupRequestOptions): Promise<void>;
23
- cancel(options?: MarkupRequestOptions): Promise<void>;
24
- getList(options?: MarkupRequestOptions): Promise<MarkupListItem[]>;
25
- private runRequest;
26
- }