({}))),i.push({type:"text",x:n+a*t*.6,y:r,text:s,color:o,fontSize:t,fontFamily:"monospace"})}return i}const qt={snapIndex:s.number,param:(0,s.optional)(s.number),id:s.number},$t={position:s.Position,target:(0,s.optional)(qt)};function Xt(e,t,n){return Yt(e,se(t,t,(e=>!Pe(e))),t,n)}function Yt(e,t,n,r){r&&(t=t.map((e=>(0,s.rotatePosition)(e,{x:0,y:0},r))));const o=(0,s.getPointsBounding)(t);if(o)return Kt(e,o,n)}function Kt(e,t,n){var r,o;const i=null==(o=null==(r=te(e))?void 0:r.getGeometries)?void 0:o.call(r,e,n).bounding;if(!i)return;const a=i.end.x-i.start.x,s=i.end.y-i.start.y,c=t.end.x-t.start.x,l=t.end.y-t.start.y,u=a/c,p=s/l;let d,f=0,g=0;return u!n.includes(e)),r);if(c){const n=te(c);let r=null==(i=null==(o=null==n?void 0:n.getSnapPoints)?void 0:o.call(n,c,t))?void 0:i[e.snapIndex];if(!r&&void 0!==e.param){const o=null==(a=null==n?void 0:n.getGeometries)?void 0:a.call(n,c,t).lines;o&&(r=(0,s.getGeometryLinesPointAtParam)(e.param,o))}return r}}}const en={id:Zt,partIndex:(0,s.optional)(s.number)};function tn(e,t,n=e=>!0,r){var o,i,a;if(void 0!==e){const s=tt(e.id,t,n,r);if(s){const r=te(s);if(void 0!==e.partIndex){const c=null==(a=null==(i=null==(o=null==r?void 0:r.getGeometries)?void 0:o.call(r,s,t))?void 0:i.lines)?void 0:a[e.partIndex];if(c){const e=ie(c);if(e&&n(e))return e}}if(n(s))return s}}}function nn(e,t){return e?{id:Ze(e.content,t),snapIndex:e.snapIndex,param:e.param}:void 0}function rn(e,t,n,r){let o=[];for(let t=0;t0){let n=Ut(Array.from((0,s.iteratePolylineLines)(e)),o);const i=n.filter(((e,t)=>t%2==0)),a=n.filter(((e,t)=>t%2==1));return n=Math.min(...i.map((e=>{var n,o,i,a,c;return null==(c=null!=(a=null==(i=null==(o=null==(n=te(e))?void 0:n.getGeometries)?void 0:o.call(n,e,r))?void 0:i.lines)?a:[])?void 0:c.map((e=>(0,s.getPointAndGeometryLineMinimumDistance)(t,e)))})).flat(2))>Math.min(...a.map((e=>{var n,o,i,a,c;return null==(c=null!=(a=null==(i=null==(o=null==(n=te(e))?void 0:n.getGeometries)?void 0:o.call(n,e,r))?void 0:i.lines)?a:[])?void 0:c.map((e=>(0,s.getPointAndGeometryLineMinimumDistance)(t,e)))})).flat(2))?a:i,Gt(n),n.map((e=>e.points))}return[e]}function on(e){return s.m3.multiply(s.m3.multiply(s.m3.translation(e.x,e.y),s.m3.scaling(e.scale,e.scale)),s.m3.rotation(-(e.rotate||0)))}function an(e,t){return{x:(e=(0,s.rotatePosition)(e,{x:0,y:0},t.rotate||0)).x*t.scale+t.x,y:e.y*t.scale+t.y}}function sn(e,t){return(0,s.rotatePosition)({x:(e.x-t.x)/t.scale,y:(e.y-t.y)/t.scale},{x:0,y:0},-(t.rotate||0))}const cn={lineCap:"round",lineJoin:"round",strokeOpacity:.25};function ln(e,{getStrokeColor:t,time:n,transformStrokeWidth:r,isHoveringOrSelected:o,target:i,contents:a}){var s,c;const l=je(e,a),u=null!=(s=l.strokeWidth)?s:Ge(e),p=r(u),d=o&&p!==u,f=t(l),g=null!=(c=l.strokeOpacity)?c:$e;return{options:y({strokeColor:f,strokeWidth:p,strokeOpacity:g,dashArray:l.dashArray,lineJoin:l.lineJoin,miterLimit:l.miterLimit,lineCap:l.lineCap},d?cn:{}),time:n,contents:a,target:i,fillOptions:y({strokeColor:d?f:void 0,strokeWidth:d?r(0):0,fillColor:d?void 0:f},d?cn:{}),strokeColor:f,strokeOpacity:g}}function un(e,{getStrokeColor:t,getFillColor:n,getFillPattern:r,transformStrokeWidth:o,isHoveringOrSelected:i,time:a,target:s,contents:c,clip:l}){var u,p,d;const f=je(e,c),g=Ve(e,c),h=null!=(u=f.strokeWidth)?u:Ge(e),m=o(h),v=i&&m!==h,x=v&&!h&&void 0!==g.fillColor?g.fillColor:t(f),b=null!=(p=f.strokeOpacity)?p:$e,C=null!=(d=g.fillOpacity)?d:$e;return{options:y({fillColor:n(g),strokeColor:x,strokeWidth:m,strokeOpacity:b,fillPattern:r(g),fillOpacity:C,dashArray:f.dashArray,lineJoin:f.lineJoin,miterLimit:f.miterLimit,lineCap:f.lineCap,clip:l},v?cn:{}),time:a,contents:c,target:s,strokeColor:x,strokeOpacity:b,dashed:!!f.dashArray}}function pn(e,{getFillColor:t,getFillPattern:n,transformStrokeWidth:r,isHoveringOrSelected:o,time:i,target:a,contents:s,clip:c}){var l,u;const p=Ve(e,s),d=r(1),f=o&&1!==d,g=null!=(l=p.fillOpacity)?l:$e,h=null!=(u=t(p))?u:qe;return{options:y({fillColor:h,fillPattern:n(p),fillOpacity:g,clip:c,strokeColor:f?h:void 0,strokeWidth:f?d:0},f?cn:{}),time:i,contents:s,target:a}}function dn(e,{transformStrokeWidth:t,isHoveringOrSelected:n}){const r=t(0),o=n&&0!==r;return v(y({},o?cn:{}),{strokeColor:o?e:void 0,strokeWidth:o?r:void 0})}function fn(e,t,n){var r,o;if(e.clip){const i=te(e.clip.border),a=null==i?void 0:i.render;if(a){if(e.clip.reverse){const a=null==(r=i.getGeometries)?void 0:r.call(i,e.clip.border,n.contents);if(!(null==a?void 0:a.bounding))return t;const c=te(e);if(!c)return t;const l=null==(o=c.getGeometries)?void 0:o.call(c,e,n.contents);return(null==l?void 0:l.bounding)?n.target.renderPath([(0,s.getPolygonFromTwoPointsFormRegion)((0,s.mergeBoundingsUnsafe)([l.bounding,a.bounding])),(0,s.getGeometryLinesPoints)(a.lines)],v(y({},n),{strokeWidth:0,clip:()=>t})):t}return a(e.clip.border,v(y({},n),{transformStrokeWidth:()=>0,clip:()=>t}))}}return t}function gn(e,t,n){if(e.clip){const r=te(e.clip.border),o=null==r?void 0:r.render;if(o)return n.target.renderGroup([t,o(e.clip.border,v(y({},n),{transformColor:e=>e,transformStrokeWidth:()=>n.strokeWidth,getStrokeColor:()=>n.color,getFillColor:()=>{},getFillPattern:()=>{}}))])}return t}function hn(e,t){var n,r;if(!e.clip)return[];const i=null==(r=null==(n=te(e.clip.border))?void 0:n.getEditPoints)?void 0:r.call(n,e.clip.border,t);return i?i.editPoints.map((e=>v(y({},e),{update(t,n){if(!Ne(t))return;if(!t.clip)return;let r;return t.clip.border=(0,o.produce)(t.clip.border,(t=>{e.update&&(r=e.update(t,n))})),r||void 0}}))):[]}const mn=new s.WeakmapCache,yn=new s.WeakmapCache;function vn(e){if(Array.isArray(e)||"ray"!==e.type)return yn.get(e,(()=>(0,s.getGeometryLineBounding)(e)))}function xn(e,t){var n,r;if(!e)return;const o=null==(r=null==(n=te(e))?void 0:n.getGeometries)?void 0:r.call(n,e,t);return!o||o.lines.length>30?void 0:{lines:o.lines,id:Ze(e,t)}}function bn(e){const t=(0,s.getTwoPointsFormRegionSize)(e);return{x:e.start.x-1,y:e.start.y-1,w:t.width+2,h:t.height+2}}},4864:(e,t,n)=>{"use strict";n.d(t,{pluginScripts:()=>r});const r=['// dev/cad-editor/plugins/arrow.plugin.tsx\nfunction getModel(ctx) {\n const ArrowContent = ctx.and(ctx.BaseContent("arrow"), ctx.StrokeFields, ctx.ArrowFields, {\n p1: ctx.Position,\n p2: ctx.Position,\n ref1: ctx.optional(ctx.PositionRef),\n ref2: ctx.optional(ctx.PositionRef)\n });\n const getRefIds = (content) => {\n var _a, _b;\n return [...ctx.getStrokeRefIds(content), ...ctx.toRefIds([(_a = content.ref1) == null ? void 0 : _a.id, (_b = content.ref2) == null ? void 0 : _b.id])];\n };\n function getArrowGeometriesFromCache(content, contents) {\n const refs = new Set(ctx.iterateRefContents(getRefIds(content), contents, [content]));\n return ctx.getGeometriesFromCache(content, refs, () => {\n var _a, _b;\n const p1 = (_a = ctx.getRefPosition(content.ref1, contents, [content])) != null ? _a : content.p1;\n const p2 = (_b = ctx.getRefPosition(content.ref2, contents, [content])) != null ? _b : content.p2;\n const { arrowPoints, endPoint } = ctx.getArrowPoints(p1, p2, content);\n const points = [p1, endPoint];\n return {\n lines: Array.from(ctx.iteratePolylineLines(points)),\n bounding: ctx.getPointsBounding(points),\n regions: [\n {\n points: arrowPoints,\n lines: Array.from(ctx.iteratePolygonLines(arrowPoints))\n }\n ],\n renderingLines: ctx.dashedPolylineToLines(points, content.dashArray)\n };\n });\n }\n const React = ctx.React;\n return {\n type: "arrow",\n ...ctx.strokeModel,\n ...ctx.arrowModel,\n move(content, offset) {\n ctx.movePoint(content.p1, offset);\n ctx.movePoint(content.p2, offset);\n },\n rotate(content, center, angle) {\n ctx.rotatePoint(content.p1, center, angle);\n ctx.rotatePoint(content.p2, center, angle);\n },\n scale(content, center, sx, sy) {\n ctx.scalePoint(content.p1, center, sx, sy);\n ctx.scalePoint(content.p2, center, sx, sy);\n },\n skew(content, center, sx, sy) {\n ctx.skewPoint(content.p1, center, sx, sy);\n ctx.skewPoint(content.p2, center, sx, sy);\n },\n mirror(content, line) {\n ctx.mirrorPoint(content.p1, line);\n ctx.mirrorPoint(content.p2, line);\n },\n render(content, renderCtx) {\n const { options, target, contents, fillOptions } = ctx.getStrokeRenderOptionsFromRenderContext(content, renderCtx);\n const { regions, renderingLines } = getArrowGeometriesFromCache(content, contents);\n const children = [];\n for (const line of renderingLines) {\n children.push(target.renderPolyline(line, options));\n }\n if (regions) {\n for (let i = 0; i < 2 && i < regions.length; i++) {\n children.push(target.renderPolygon(regions[i].points, fillOptions));\n }\n }\n return target.renderGroup(children);\n },\n getEditPoints(content, contents) {\n return ctx.getEditPointsFromCache(content, () => {\n return {\n editPoints: [\n {\n ...content.p1,\n cursor: "move",\n update(c, { cursor, start, scale, target }) {\n if (!isArrowContent(c)) {\n return;\n }\n c.p1.x += cursor.x - start.x;\n c.p1.y += cursor.y - start.y;\n c.ref1 = ctx.getSnapTargetRef(target, contents);\n return { assistentContents: [{ type: "line", dashArray: [4 / scale], points: [start, cursor] }] };\n }\n },\n {\n ...content.p2,\n cursor: "move",\n update(c, { cursor, start, scale, target }) {\n if (!isArrowContent(c)) {\n return;\n }\n c.p2.x += cursor.x - start.x;\n c.p2.y += cursor.y - start.y;\n c.ref2 = ctx.getSnapTargetRef(target, contents);\n return { assistentContents: [{ type: "line", dashArray: [4 / scale], points: [start, cursor] }] };\n }\n }\n ]\n };\n });\n },\n getGeometries: getArrowGeometriesFromCache,\n propertyPanel(content, update, contents, { acquirePoint }) {\n var _a, _b;\n return {\n p1: /* @__PURE__ */ React.createElement(\n ctx.ObjectEditor,\n {\n inline: true,\n properties: {\n from: /* @__PURE__ */ React.createElement(ctx.Button, { onClick: () => acquirePoint((p, ref) => update((c) => {\n if (isArrowContent(c)) {\n c.p1.x = p.x;\n c.p1.y = p.y;\n c.ref1 = ref;\n }\n })) }, "canvas"),\n x: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.p1.x, setValue: (v) => update((c) => {\n if (isArrowContent(c)) {\n c.p1.x = v;\n }\n }) }),\n y: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.p1.y, setValue: (v) => update((c) => {\n if (isArrowContent(c)) {\n c.p1.y = v;\n }\n }) })\n }\n }\n ),\n p2: /* @__PURE__ */ React.createElement(\n ctx.ObjectEditor,\n {\n inline: true,\n properties: {\n from: /* @__PURE__ */ React.createElement(ctx.Button, { onClick: () => acquirePoint((p, ref) => update((c) => {\n if (isArrowContent(c)) {\n c.p2.x = p.x;\n c.p2.y = p.y;\n c.ref2 = ref;\n }\n })) }, "canvas"),\n x: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.p2.x, setValue: (v) => update((c) => {\n if (isArrowContent(c)) {\n c.p2.x = v;\n }\n }) }),\n y: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.p2.y, setValue: (v) => update((c) => {\n if (isArrowContent(c)) {\n c.p2.y = v;\n }\n }) })\n }\n }\n ),\n ref1: [\n /* @__PURE__ */ React.createElement(ctx.BooleanEditor, { value: content.ref1 !== void 0, readOnly: content.ref1 === void 0, setValue: (v) => update((c) => {\n if (isArrowContent(c) && !v) {\n c.ref1 = void 0;\n }\n }) }),\n content.ref1 !== void 0 && typeof content.ref1.id === "number" ? /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.ref1.id, setValue: (v) => update((c) => {\n if (isArrowContent(c) && c.ref1) {\n c.ref1.id = v;\n }\n }) }) : void 0,\n content.ref1 !== void 0 ? /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.ref1.snapIndex, setValue: (v) => update((c) => {\n if (isArrowContent(c) && c.ref1) {\n c.ref1.snapIndex = v;\n }\n }) }) : void 0,\n ((_a = content.ref1) == null ? void 0 : _a.param) !== void 0 ? /* @__PURE__ */ React.createElement(ctx.NumberEditor, { readOnly: true, value: content.ref1.param }) : void 0\n ],\n ref2: [\n /* @__PURE__ */ React.createElement(ctx.BooleanEditor, { value: content.ref2 !== void 0, readOnly: content.ref2 === void 0, setValue: (v) => update((c) => {\n if (isArrowContent(c) && !v) {\n c.ref2 = void 0;\n }\n }) }),\n content.ref2 !== void 0 && typeof content.ref2.id === "number" ? /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.ref2.id, setValue: (v) => update((c) => {\n if (isArrowContent(c) && c.ref2) {\n c.ref2.id = v;\n }\n }) }) : void 0,\n content.ref2 !== void 0 ? /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.ref2.snapIndex, setValue: (v) => update((c) => {\n if (isArrowContent(c) && c.ref2) {\n c.ref2.snapIndex = v;\n }\n }) }) : void 0,\n ((_b = content.ref2) == null ? void 0 : _b.param) !== void 0 ? /* @__PURE__ */ React.createElement(ctx.NumberEditor, { readOnly: true, value: content.ref2.param }) : void 0\n ],\n ...ctx.getArrowContentPropertyPanel(content, update),\n ...ctx.getStrokeContentPropertyPanel(content, update, contents)\n };\n },\n isValid: (c, p) => ctx.validate(c, ArrowContent, p),\n getRefIds,\n updateRefId(content, update) {\n if (content.ref1) {\n const newRefId = update(content.ref1.id);\n if (newRefId !== void 0) {\n content.ref1.id = newRefId;\n }\n }\n if (content.ref2) {\n const newRefId = update(content.ref2.id);\n if (newRefId !== void 0) {\n content.ref2.id = newRefId;\n }\n }\n ctx.updateStrokeRefIds(content, update);\n },\n deleteRefId(content, ids) {\n if (content.ref1 && ids.includes(content.ref1.id)) {\n content.ref1 = void 0;\n }\n if (content.ref2 && ids.includes(content.ref2.id)) {\n content.ref2 = void 0;\n }\n ctx.deleteStrokeRefIds(content, ids);\n },\n reverse: (content) => ({\n ...content,\n p1: content.p2,\n p2: content.p1,\n ref1: content.ref2,\n ref2: content.ref1\n })\n };\n}\nfunction isArrowContent(content) {\n return content.type === "arrow";\n}\nfunction getCommand(ctx) {\n const React = ctx.React;\n const icon = /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 100 100" }, /* @__PURE__ */ React.createElement("g", { transform: "" }, /* @__PURE__ */ React.createElement("polyline", { points: "12,86 81,20", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polyline", { points: "88,14 72,39 62,28", strokeWidth: "0", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "currentColor", stroke: "currentColor" })));\n return {\n name: "create arrow",\n hotkey: "AR",\n icon,\n useCommand({ onEnd, type, strokeStyleId }) {\n const { line, positionTargets, onClick, onMove, input, lastPosition, reset } = ctx.useLineClickCreate(\n type === "create arrow",\n (c, targets) => onEnd({\n updateContents: (contents) => contents.push({\n type: "arrow",\n p1: c[0],\n p2: c[1],\n ref1: targets[0],\n ref2: targets[1],\n strokeStyleId\n })\n }),\n {\n once: true\n }\n );\n const assistentContents = [];\n if (line) {\n assistentContents.push({\n type: "arrow",\n p1: line[0],\n p2: line[1],\n ref1: positionTargets[0],\n ref2: positionTargets[1],\n strokeStyleId\n });\n }\n return {\n onStart: onClick,\n input,\n onMove,\n assistentContents,\n lastPosition,\n reset\n };\n },\n selectCount: 0\n };\n}\nexport {\n getCommand,\n getModel,\n isArrowContent\n};\n','// dev/cad-editor/plugins/block.plugin.tsx\nfunction getModel(ctx) {\n const React = ctx.React;\n const BlockContent = ctx.and(ctx.BaseContent("block"), ctx.ContainerFields, {\n base: ctx.Position\n });\n const BlockReferenceContent = ctx.and(ctx.BaseContent("block reference"), ctx.Position, ctx.VariableValuesFields, {\n refId: ctx.ContentRef,\n angle: ctx.number,\n scale: ctx.optional(ctx.or(ctx.number, ctx.Position))\n });\n const getBlockRefIds = (content) => ctx.toRefIds(content.contents);\n const getBlockReferenceRefIds = (content) => ctx.toRefId(content.refId, true);\n const blockModel = {\n type: "block",\n ...ctx.containerModel,\n explode: ctx.getContainerExplode,\n render: ctx.getContainerRender,\n renderIfSelected: (content, renderCtx) => ctx.getContainerRenderIfSelected(content, renderCtx, [content], getBlockRefIds),\n getOperatorRenderPosition(content) {\n return content.base;\n },\n getEditPoints(content) {\n return ctx.getEditPointsFromCache(content, () => {\n return {\n editPoints: [\n {\n ...content.base,\n cursor: "move",\n update(c, { cursor, start, scale }) {\n if (!isBlockContent(c)) {\n return;\n }\n c.base.x += cursor.x - start.x;\n c.base.y += cursor.y - start.y;\n return { assistentContents: [{ type: "line", dashArray: [4 / scale], points: [content.base, cursor] }] };\n }\n }\n ],\n angleSnapStartPoint: content.base\n };\n });\n },\n getSnapPoints: ctx.getContainerSnapPoints,\n getGeometries: (content, contents) => ctx.getContainerGeometries(content, contents, getBlockRefIds, [content]),\n propertyPanel(content, update, _, { acquirePoint }) {\n return {\n base: /* @__PURE__ */ React.createElement(\n ctx.ObjectEditor,\n {\n inline: true,\n properties: {\n from: /* @__PURE__ */ React.createElement(ctx.Button, { onClick: () => acquirePoint((p) => update((c) => {\n if (isBlockContent(c)) {\n c.base.x = p.x;\n c.base.y = p.y;\n }\n })) }, "canvas"),\n x: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.base.x, setValue: (v) => update((c) => {\n if (isBlockContent(c)) {\n c.base.x = v;\n }\n }) }),\n y: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.base.y, setValue: (v) => update((c) => {\n if (isBlockContent(c)) {\n c.base.y = v;\n }\n }) })\n }\n }\n ),\n ...ctx.getVariableValuesContentPropertyPanel(content, ctx.getContainerVariableNames(content), update)\n };\n },\n isValid: (c, p) => ctx.validate(c, BlockContent, p),\n getRefIds: getBlockRefIds\n };\n const blockSnapPointsCache = new ctx.WeakmapCache2();\n function extractContentInBlockReference(target, content, block, contents) {\n let model = ctx.getContentModel(target);\n if (!model) {\n return void 0;\n }\n let newResult;\n const result = ctx.produce(target, (draft) => {\n var _a, _b, _c;\n const scale = ctx.getScaleOptionsScale(content);\n if (scale) {\n const r = (_a = model == null ? void 0 : model.scale) == null ? void 0 : _a.call(model, draft, block.base, scale.x, scale.y, contents);\n if (r) {\n model = ctx.getContentModel(r);\n newResult = r;\n draft = r;\n }\n }\n if (content.angle) {\n (_b = model == null ? void 0 : model.rotate) == null ? void 0 : _b.call(model, draft, block.base, content.angle, contents);\n }\n (_c = model == null ? void 0 : model.move) == null ? void 0 : _c.call(model, draft, content);\n });\n return newResult || result;\n }\n function getBlockReferenceGeometries(content, contents) {\n const refs = new Set(ctx.iterateRefContents(getBlockReferenceRefIds(content), contents, [content]));\n return ctx.getGeometriesFromCache(content, refs, () => {\n const block = ctx.getReference(content.refId, contents, isBlockContent);\n if (block) {\n const lines = [];\n const boundings = [];\n const renderingLines = [];\n const regions = [];\n block.contents.forEach((c) => {\n var _a, _b;\n if (!c) {\n return;\n }\n const extracted = extractContentInBlockReference(c, content, block, contents);\n if (extracted) {\n const r = (_b = (_a = ctx.getContentModel(extracted)) == null ? void 0 : _a.getGeometries) == null ? void 0 : _b.call(_a, extracted, contents);\n if (r) {\n lines.push(...r.lines);\n if (r.bounding) {\n boundings.push(r.bounding);\n }\n if (r.renderingLines) {\n renderingLines.push(...r.renderingLines);\n }\n if (r.regions) {\n regions.push(...r.regions);\n }\n }\n }\n });\n return {\n lines,\n bounding: ctx.mergeBoundingsUnsafe(boundings),\n renderingLines,\n regions\n };\n }\n return { lines: [], renderingLines: [] };\n });\n }\n const blockReferenceModel = {\n type: "block reference",\n ...ctx.variableValuesModel,\n move(content, offset) {\n ctx.movePoint(content, offset);\n },\n rotate(content, center, angle, contents) {\n const block = ctx.getReference(content.refId, contents, isBlockContent);\n if (block) {\n const p = ctx.rotatePoint({ x: content.x + block.base.x, y: content.y + block.base.y }, center, angle);\n content.x = p.x - block.base.x;\n content.y = p.y - block.base.y;\n content.angle += angle;\n }\n },\n scale(content, center, sx, sy, contents) {\n var _a, _b;\n const block = ctx.getReference(content.refId, contents, isBlockContent);\n if (block) {\n const p = { x: content.x + block.base.x, y: content.y + block.base.y };\n ctx.scalePoint(p, center, sx, sy);\n content.x = p.x - block.base.x;\n content.y = p.y - block.base.y;\n const scale = ctx.getScaleOptionsScale(content);\n content.scale = {\n x: ((_a = scale == null ? void 0 : scale.x) != null ? _a : 1) * sx,\n y: ((_b = scale == null ? void 0 : scale.y) != null ? _b : 1) * sy\n };\n }\n },\n explode(content, contents) {\n const block = ctx.getReference(content.refId, contents, isBlockContent);\n if (block) {\n const result = [];\n block.contents.forEach((c) => {\n if (!c) {\n return;\n }\n const extracted = extractContentInBlockReference(c, content, block, contents);\n if (extracted) {\n result.push(extracted);\n }\n });\n return result;\n }\n return [];\n },\n mirror(content, line, angle, contents) {\n var _a, _b;\n const block = ctx.getReference(content.refId, contents, isBlockContent);\n if (block) {\n const p = ctx.mirrorPoint({ x: content.x + block.base.x, y: content.y + block.base.y }, line);\n content.x = p.x - block.base.x;\n content.y = p.y - block.base.y;\n content.angle = 2 * angle - content.angle;\n const scale = ctx.getScaleOptionsScale(content);\n content.scale = {\n x: (_a = scale == null ? void 0 : scale.x) != null ? _a : 1,\n y: -((_b = scale == null ? void 0 : scale.y) != null ? _b : 1)\n };\n }\n },\n render(content, renderCtx) {\n const block = ctx.getReference(content.refId, renderCtx.contents, isBlockContent);\n if (block) {\n const children = ctx.renderContainerChildren({ ...block, variableValues: content.variableValues }, renderCtx);\n return renderCtx.target.renderGroup(children, { translate: content, base: block.base, angle: content.angle, scale: content.scale });\n }\n return renderCtx.target.renderEmpty();\n },\n renderIfSelected(content, renderCtx) {\n const block = ctx.getReference(content.refId, renderCtx.contents, isBlockContent);\n if (block) {\n const children = ctx.renderContainerIfSelected(block, renderCtx, [content], getBlockRefIds);\n return renderCtx.target.renderGroup([children], { translate: content, base: block.base, angle: content.angle, scale: content.scale });\n }\n return renderCtx.target.renderEmpty();\n },\n getOperatorRenderPosition(content, contents) {\n const block = ctx.getReference(content.refId, contents, isBlockContent);\n if (block) {\n return { x: content.x + block.base.x, y: content.y + block.base.y };\n }\n return content;\n },\n getEditPoints(content, contents) {\n const block = ctx.getReference(content.refId, contents, isBlockContent);\n if (!block) {\n return;\n }\n return ctx.getEditPointsFromCache(content, () => {\n const p = { x: content.x + block.base.x, y: content.y + block.base.y };\n return {\n editPoints: [\n {\n ...p,\n cursor: "move",\n update(c, { cursor, start, scale }) {\n if (!isBlockReferenceContent(c)) {\n return;\n }\n c.x += cursor.x - start.x;\n c.y += cursor.y - start.y;\n return { assistentContents: [{ type: "line", dashArray: [4 / scale], points: [p, cursor] }] };\n }\n }\n ],\n angleSnapStartPoint: p\n };\n });\n },\n getSnapPoints(content, contents) {\n const block = ctx.getReference(content.refId, contents, isBlockContent);\n if (block) {\n return blockSnapPointsCache.get(block, content, () => {\n const result = [];\n block.contents.forEach((c) => {\n var _a;\n if (!c) {\n return;\n }\n const model = ctx.getContentModel(c);\n const extracted = extractContentInBlockReference(c, content, block, contents);\n if (extracted) {\n const r = (_a = model == null ? void 0 : model.getSnapPoints) == null ? void 0 : _a.call(model, extracted, contents);\n if (r) {\n result.push(...r);\n }\n }\n });\n return result;\n });\n }\n return [];\n },\n getGeometries: getBlockReferenceGeometries,\n propertyPanel(content, update, contents, { acquirePoint }) {\n var _a, _b;\n let variableNames = [];\n const block = ctx.getReference(content.refId, contents, isBlockContent);\n if (block) {\n variableNames = ctx.getContainerVariableNames(block);\n }\n const scale = ctx.getScaleOptionsScale(content);\n return {\n refId: typeof content.refId === "number" ? /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.refId, setValue: (v) => update((c) => {\n if (isBlockReferenceContent(c)) {\n c.refId = v;\n }\n }) }) : [],\n from: /* @__PURE__ */ React.createElement(ctx.Button, { onClick: () => acquirePoint((p) => update((c) => {\n if (isBlockReferenceContent(c)) {\n c.x = p.x;\n c.y = p.y;\n }\n })) }, "canvas"),\n x: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.x, setValue: (v) => update((c) => {\n if (isBlockReferenceContent(c)) {\n c.x = v;\n }\n }) }),\n y: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.y, setValue: (v) => update((c) => {\n if (isBlockReferenceContent(c)) {\n c.y = v;\n }\n }) }),\n angle: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.angle, setValue: (v) => update((c) => {\n if (isBlockReferenceContent(c)) {\n c.angle = v;\n }\n }) }),\n sx: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: (_a = scale == null ? void 0 : scale.x) != null ? _a : 1, setValue: (v) => update((c) => {\n var _a2;\n if (isBlockReferenceContent(c)) {\n c.scale = { x: v, y: (_a2 = scale == null ? void 0 : scale.y) != null ? _a2 : v };\n }\n }) }),\n sy: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: (_b = scale == null ? void 0 : scale.y) != null ? _b : 1, setValue: (v) => update((c) => {\n var _a2;\n if (isBlockReferenceContent(c)) {\n c.scale = { x: (_a2 = scale == null ? void 0 : scale.x) != null ? _a2 : v, y: v };\n }\n }) }),\n ...ctx.getVariableValuesContentPropertyPanel(content, variableNames, update)\n };\n },\n isValid: (c, p) => ctx.validate(c, BlockReferenceContent, p),\n getRefIds: getBlockReferenceRefIds,\n updateRefId(content, update) {\n const newRefId = update(content.refId);\n if (newRefId !== void 0) {\n content.refId = newRefId;\n }\n }\n };\n return [\n blockModel,\n blockReferenceModel\n ];\n}\nfunction isBlockContent(content) {\n return content.type === "block";\n}\nfunction isBlockReferenceContent(content) {\n return content.type === "block reference";\n}\nfunction getCommand(ctx) {\n function contentSelectable(content, contents) {\n return ctx.contentIsDeletable(content, contents);\n }\n const React = ctx.React;\n const icon = /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 576 512" }, /* @__PURE__ */ React.createElement("path", { fill: "currentColor", d: "M32 119.4C12.9 108.4 0 87.7 0 64C0 28.7 28.7 0 64 0c23.7 0 44.4 12.9 55.4 32H456.6C467.6 12.9 488.3 0 512 0c35.3 0 64 28.7 64 64c0 23.7-12.9 44.4-32 55.4V392.6c19.1 11.1 32 31.7 32 55.4c0 35.3-28.7 64-64 64c-23.7 0-44.4-12.9-55.4-32H119.4c-11.1 19.1-31.7 32-55.4 32c-35.3 0-64-28.7-64-64c0-23.7 12.9-44.4 32-55.4V119.4zM456.6 96H119.4c-5.6 9.7-13.7 17.8-23.4 23.4V392.6c9.7 5.6 17.8 13.7 23.4 23.4H456.6c5.6-9.7 13.7-17.8 23.4-23.4V119.4c-9.7-5.6-17.8-13.7-23.4-23.4zM128 160c0-17.7 14.3-32 32-32H288c17.7 0 32 14.3 32 32v96c0 17.7-14.3 32-32 32H160c-17.7 0-32-14.3-32-32V160zM256 320h32c35.3 0 64-28.7 64-64V224h64c17.7 0 32 14.3 32 32v96c0 17.7-14.3 32-32 32H288c-17.7 0-32-14.3-32-32V320z" }));\n const referenceIcon = /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 640 512" }, /* @__PURE__ */ React.createElement("path", { fill: "currentColor", d: "M32 119.4C12.9 108.4 0 87.7 0 64C0 28.7 28.7 0 64 0c23.7 0 44.4 12.9 55.4 32H328.6C339.6 12.9 360.3 0 384 0c35.3 0 64 28.7 64 64c0 23.7-12.9 44.4-32 55.4V232.6c19.1 11.1 32 31.7 32 55.4c0 35.3-28.7 64-64 64c-23.7 0-44.4-12.9-55.4-32H119.4c-11.1 19.1-31.7 32-55.4 32c-35.3 0-64-28.7-64-64c0-23.7 12.9-44.4 32-55.4V119.4zM119.4 96c-5.6 9.7-13.7 17.8-23.4 23.4V232.6c9.7 5.6 17.8 13.7 23.4 23.4H328.6c5.6-9.7 13.7-17.8 23.4-23.4V119.4c-9.7-5.6-17.8-13.7-23.4-23.4H119.4zm192 384c-11.1 19.1-31.7 32-55.4 32c-35.3 0-64-28.7-64-64c0-23.7 12.9-44.4 32-55.4V352h64v40.6c9.7 5.6 17.8 13.7 23.4 23.4H520.6c5.6-9.7 13.7-17.8 23.4-23.4V279.4c-9.7-5.6-17.8-13.7-23.4-23.4h-46c-5.4-15.4-14.6-28.9-26.5-39.6V192h72.6c11.1-19.1 31.7-32 55.4-32c35.3 0 64 28.7 64 64c0 23.7-12.9 44.4-32 55.4V392.6c19.1 11.1 32 31.7 32 55.4c0 35.3-28.7 64-64 64c-23.7 0-44.4-12.9-55.4-32H311.4z" }));\n const blockCommand = {\n name: "create block",\n useCommand({ onEnd, type }) {\n let message = "";\n if (type) {\n message = "specify base point";\n }\n const { input, setInputPosition, resetInput } = ctx.useCursorInput(message);\n return {\n onStart(p) {\n onEnd({\n updateContents: (contents, selected) => {\n const newContent = {\n type: "block",\n contents: contents.filter((c, i) => c && ctx.isSelected([i], selected) && contentSelectable(c, contents)),\n base: p\n };\n ctx.deleteSelectedContents(contents, selected.map((s) => s[0]));\n contents.push(newContent);\n }\n });\n },\n input,\n onMove(_, p) {\n setInputPosition(p);\n },\n reset: resetInput\n };\n },\n contentSelectable,\n hotkey: "B",\n icon\n };\n const blockReferenceCommand = {\n name: "create block reference",\n useCommand({ onEnd, type, scale }) {\n let message = "";\n if (type) {\n message = "specify target point";\n }\n const { input, setInputPosition, cursorPosition, setCursorPosition, resetInput } = ctx.useCursorInput(message);\n return {\n onStart(p) {\n resetInput();\n onEnd({\n updateContents: (contents, selected) => {\n contents.push(\n ...contents.filter((c, i) => !!c && ctx.isSelected([i], selected) && isBlockContent(c)).map((block) => ({\n type: "block reference",\n refId: ctx.getContentIndex(block, contents),\n x: p.x - block.base.x,\n y: p.y - block.base.y,\n angle: 0\n }))\n );\n setCursorPosition(void 0);\n }\n });\n },\n input,\n onMove(p, viewportPosition) {\n setInputPosition(viewportPosition || p);\n if (!type) {\n return;\n }\n setCursorPosition(p);\n },\n updateSelectedContent(content, contents) {\n if (!isBlockContent(content)) {\n return {};\n }\n if (cursorPosition) {\n return {\n newContents: [\n {\n type: "block reference",\n refId: ctx.getContentIndex(content, contents),\n x: cursorPosition.x - content.base.x,\n y: cursorPosition.y - content.base.y,\n angle: 0\n }\n ],\n assistentContents: [\n {\n type: "line",\n dashArray: [4 / scale],\n points: [{ x: content.base.x, y: content.base.y }, cursorPosition]\n }\n ]\n };\n }\n return {};\n },\n reset: resetInput\n };\n },\n contentSelectable: isBlockContent,\n selectCount: 1,\n icon: referenceIcon\n };\n return [blockCommand, blockReferenceCommand];\n}\nexport {\n getCommand,\n getModel,\n isBlockContent,\n isBlockReferenceContent\n};\n','// dev/cad-editor/plugins/break.plugin.tsx\nfunction getCommand(ctx) {\n const React = ctx.React;\n const icon = /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 640 512" }, /* @__PURE__ */ React.createElement("path", { fill: "currentColor", d: "M38.8 5.1C28.4-3.1 13.3-1.2 5.1 9.2S-1.2 34.7 9.2 42.9l592 464c10.4 8.2 25.5 6.3 33.7-4.1s6.3-25.5-4.1-33.7L489.3 358.2l90.5-90.5c56.5-56.5 56.5-148 0-204.5c-50-50-128.8-56.5-186.3-15.4l-1.6 1.1c-14.4 10.3-17.7 30.3-7.4 44.6s30.3 17.7 44.6 7.4l1.6-1.1c32.1-22.9 76-19.3 103.8 8.6c31.5 31.5 31.5 82.5 0 114l-96 96-31.9-25C430.9 239.6 420.1 175.1 377 132c-52.2-52.3-134.5-56.2-191.3-11.7L38.8 5.1zM239 162c30.1-14.9 67.7-9.9 92.8 15.3c20 20 27.5 48.3 21.7 74.5L239 162zM406.6 416.4L220.9 270c-2.1 39.8 12.2 80.1 42.2 110c38.9 38.9 94.4 51 143.6 36.3zm-290-228.5L60.2 244.3c-56.5 56.5-56.5 148 0 204.5c50 50 128.8 56.5 186.3 15.4l1.6-1.1c14.4-10.3 17.7-30.3 7.4-44.6s-30.3-17.7-44.6-7.4l-1.6 1.1c-32.1 22.9-76 19.3-103.8-8.6C74 372 74 321 105.5 289.5l61.8-61.8-50.6-39.9z" }));\n return {\n name: "break",\n execute({ contents, selected }) {\n const newContents = [];\n const indexes = [];\n contents.forEach((content, index) => {\n var _a, _b, _c, _d;\n if (content && ctx.isSelected([index], selected) && ((_b = (_a = this.contentSelectable) == null ? void 0 : _a.call(this, content, contents)) != null ? _b : true)) {\n let intersectionPoints = [];\n for (let i = 0; i < contents.length; i++) {\n const c = contents[i];\n if (c && i !== index) {\n const p = i < index ? [c, content] : [content, c];\n intersectionPoints.push(...ctx.getIntersectionPoints(...p, contents));\n }\n }\n intersectionPoints = ctx.deduplicatePosition(intersectionPoints);\n if (intersectionPoints.length > 0) {\n const result = (_d = (_c = ctx.getContentModel(content)) == null ? void 0 : _c.break) == null ? void 0 : _d.call(_c, content, intersectionPoints, contents);\n if (result) {\n newContents.push(...result);\n indexes.push(index);\n }\n }\n }\n });\n ctx.deleteSelectedContents(contents, indexes);\n contents.push(...newContents);\n },\n contentSelectable(content, contents) {\n const model = ctx.getContentModel(content);\n return (model == null ? void 0 : model.break) !== void 0 && ctx.contentIsDeletable(content, contents);\n },\n hotkey: "BR",\n icon\n };\n}\nexport {\n getCommand\n};\n','// dev/cad-editor/plugins/brush.plugin.tsx\nfunction getCommand(ctx) {\n const React = ctx.React;\n const icon = /* @__PURE__ */ React.createElement("svg", { viewBox: "0 0 1024 1024", xmlns: "http://www.w3.org/2000/svg" }, /* @__PURE__ */ React.createElement("path", { d: "m199.04 672.64 193.984 112 224-387.968-193.92-112-224 388.032zm-23.872 60.16 32.896 148.288 144.896-45.696L175.168 732.8zM455.04 229.248l193.92 112 56.704-98.112-193.984-112-56.64 98.112zM104.32 708.8l384-665.024 304.768 175.936L409.152 884.8h.064l-248.448 78.336L104.32 708.8z", fill: "currentColor" }), /* @__PURE__ */ React.createElement("rect", { x: "600", y: "600", width: "400", height: "400", fill: "currentColor" }));\n return {\n name: "brush",\n useCommand({ onEnd, type, fillStyleId }) {\n const [hatch, setHatch] = React.useState();\n const [preview, setPreview] = React.useState();\n const [inputType, setInputType] = React.useState("circle");\n const assistentContents = [];\n const reset = () => {\n setHatch(void 0);\n setPreview(void 0);\n };\n if (hatch) {\n assistentContents.push({ type: "hatch", border: hatch.border, holes: hatch.holes, fillStyleId });\n }\n if (preview) {\n assistentContents.push({ type: "hatch", border: preview.border, holes: preview.holes, fillStyleId });\n }\n return {\n onMouseDown() {\n if (!type) return;\n if (!hatch) {\n setHatch(preview);\n }\n },\n onMove(p) {\n if (!type) return;\n let h;\n if (inputType === "circle") {\n h = { border: [{ type: "arc", curve: ctx.circleToArc({ x: Math.round(p.x), y: Math.round(p.y), r: 10 }) }], holes: [] };\n } else {\n h = { border: Array.from(ctx.iteratePolygonLines(ctx.getPolygonFromRegion({ x: Math.round(p.x), y: Math.round(p.y), width: 20, height: 20 }))), holes: [] };\n }\n if (hatch) {\n setHatch(ctx.getHatchesUnion(hatch, [h])[0]);\n }\n setPreview(h);\n },\n onMouseUp() {\n if (!type) return;\n if (hatch) {\n onEnd({\n updateContents: (contents) => contents.push({ type: "hatch", border: hatch.border, holes: hatch.holes, fillStyleId })\n });\n reset();\n }\n },\n assistentContents,\n subcommand: type === "brush" ? /* @__PURE__ */ React.createElement("span", null, ["circle", "rect"].map((m) => /* @__PURE__ */ React.createElement("button", { key: m, onClick: () => setInputType(m), style: { position: "relative" } }, m))) : void 0,\n reset\n };\n },\n selectCount: 0,\n icon\n };\n}\nexport {\n getCommand\n};\n','// dev/cad-editor/plugins/line-polyline.plugin.tsx\nfunction isLineContent(content) {\n return content.type === "line";\n}\n\n// dev/cad-editor/plugins/center-line.plugin.tsx\nfunction getModel(ctx) {\n const CenterLineReferenceContent = ctx.and(ctx.BaseContent("center line"), {\n ref1: ctx.PartRef,\n ref2: ctx.PartRef\n });\n const getRefIds = (content) => ctx.toRefIds([content.ref1.id, content.ref2.id], true);\n function getCenterLineGeometriesFromCache(content, contents) {\n const refs = new Set(ctx.iterateRefContents(getRefIds(content), contents, [content]));\n return ctx.getGeometriesFromCache(content, refs, () => {\n const ref1 = ctx.getRefPart(content.ref1, contents, isLineContent);\n const ref2 = ctx.getRefPart(content.ref2, contents, isLineContent);\n if (ref1 && ref2) {\n const line = ctx.maximumBy([\n [ctx.getTwoPointCenter(ref1.points[0], ref2.points[0]), ctx.getTwoPointCenter(ref1.points[1], ref2.points[1])],\n [ctx.getTwoPointCenter(ref1.points[0], ref2.points[1]), ctx.getTwoPointCenter(ref1.points[1], ref2.points[0])]\n ], (v) => ctx.getTwoPointsDistance(...v));\n return {\n lines: [line],\n bounding: ctx.getPointsBounding(line),\n renderingLines: ctx.dashedPolylineToLines(line, [8, 4])\n };\n }\n return { lines: [], renderingLines: [] };\n });\n }\n const React = ctx.React;\n return {\n type: "center line",\n render(content, renderCtx) {\n const { options, target, contents } = ctx.getStrokeRenderOptionsFromRenderContext(content, renderCtx);\n const { renderingLines } = getCenterLineGeometriesFromCache(content, contents);\n return target.renderGroup(renderingLines.map((line) => target.renderPolyline(line, options)));\n },\n getGeometries: getCenterLineGeometriesFromCache,\n propertyPanel(content, update, contents, { acquireContent }) {\n return {\n ref1: [\n /* @__PURE__ */ React.createElement(ctx.Button, { onClick: () => acquireContent({ count: 1, part: true, selectable: (v) => contentSelectable(ctx.getContentByIndex(contents, v)) }, (r) => update((c) => {\n if (isCenterLineContent(c)) {\n c.ref1 = r[0];\n }\n })) }, "select"),\n typeof content.ref1.id === "number" ? /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.ref1.id, setValue: (v) => update((c) => {\n if (isCenterLineContent(c)) {\n c.ref1.id = v;\n }\n }) }) : void 0,\n content.ref1.partIndex !== void 0 ? /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.ref1.partIndex, setValue: (v) => update((c) => {\n if (isCenterLineContent(c)) {\n c.ref1.partIndex = v;\n }\n }) }) : void 0\n ],\n ref2: [\n /* @__PURE__ */ React.createElement(ctx.Button, { onClick: () => acquireContent({ count: 1, part: true, selectable: (v) => contentSelectable(ctx.getContentByIndex(contents, v)) }, (r) => update((c) => {\n if (isCenterLineContent(c)) {\n c.ref2 = r[0];\n }\n })) }, "select"),\n typeof content.ref2.id === "number" ? /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.ref2.id, setValue: (v) => update((c) => {\n if (isCenterLineContent(c)) {\n c.ref2.id = v;\n }\n }) }) : void 0,\n content.ref2.partIndex !== void 0 ? /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.ref2.partIndex, setValue: (v) => update((c) => {\n if (isCenterLineContent(c)) {\n c.ref2.partIndex = v;\n }\n }) }) : void 0\n ]\n };\n },\n isValid: (c, p) => ctx.validate(c, CenterLineReferenceContent, p),\n getRefIds,\n updateRefId(content, update) {\n const newRefId1 = update(content.ref1.id);\n if (newRefId1 !== void 0) {\n content.ref1.id = newRefId1;\n }\n const newRefId2 = update(content.ref2.id);\n if (newRefId2 !== void 0) {\n content.ref2.id = newRefId2;\n }\n }\n };\n}\nfunction isCenterLineContent(content) {\n return content.type === "center line";\n}\nfunction contentSelectable(content) {\n return !!content && isLineContent(content);\n}\nfunction getCommand(ctx) {\n const React = ctx.React;\n const icon = /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 100 100" }, /* @__PURE__ */ React.createElement("polyline", { points: "48,0 48,100", strokeWidth: "5", strokeDasharray: "8", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polyline", { points: "100,0 100,100", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polyline", { points: "0,1 0,99", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }));\n return {\n name: "create center line",\n icon,\n contentSelectable,\n selectCount: 2,\n selectType: "select part",\n execute({ contents, selected }) {\n contents.push({\n type: "center line",\n ref1: {\n id: selected[0][0],\n partIndex: selected[0][1]\n },\n ref2: {\n id: selected[1][0],\n partIndex: selected[1][1]\n }\n });\n }\n };\n}\nexport {\n getCommand,\n getModel,\n isCenterLineContent\n};\n','// dev/cad-editor/plugins/circle-arc.plugin.tsx\nfunction isCircleContent(content) {\n return content.type === "circle";\n}\nfunction isArcContent(content) {\n return content.type === "arc";\n}\n\n// dev/cad-editor/plugins/center-mark.plugin.tsx\nfunction getModel(ctx) {\n const CenterMarkReferenceContent = ctx.and(ctx.BaseContent("center mark"), {\n ref: ctx.PartRef\n });\n const getRefIds = (content) => ctx.toRefId(content.ref.id, true);\n function getCenterMarkGeometriesFromCache(content, contents) {\n const refs = new Set(ctx.iterateRefContents(getRefIds(content), contents, [content]));\n return ctx.getGeometriesFromCache(content, refs, () => {\n const target = ctx.getRefPart(content.ref, contents, contentSelectable);\n if (target) {\n const lines = [\n [{ x: target.x - target.r, y: target.y }, { x: target.x + target.r, y: target.y }],\n [{ x: target.x, y: target.y - target.r }, { x: target.x, y: target.y + target.r }]\n ];\n return {\n lines,\n bounding: ctx.getPointsBounding(lines.flat()),\n renderingLines: lines.map((line) => ctx.dashedPolylineToLines(line, [8, 4])).flat()\n };\n }\n return { lines: [], renderingLines: [] };\n });\n }\n const React = ctx.React;\n return {\n type: "center mark",\n render(content, renderCtx) {\n const { options, target, contents } = ctx.getStrokeRenderOptionsFromRenderContext(content, renderCtx);\n const { renderingLines } = getCenterMarkGeometriesFromCache(content, contents);\n return target.renderGroup(renderingLines.map((line) => target.renderPolyline(line, options)));\n },\n getGeometries: getCenterMarkGeometriesFromCache,\n canSelectPart: true,\n propertyPanel(content, update, contents, { acquireContent }) {\n return {\n ref: [\n /* @__PURE__ */ React.createElement(ctx.Button, { onClick: () => acquireContent({ count: 1, part: true, selectable: (v) => contentSelectable(ctx.getContentByIndex(contents, v)) }, (r) => update((c) => {\n if (isCenterMarkContent(c)) {\n c.ref = r[0];\n }\n })) }, "select"),\n typeof content.ref.id === "number" ? /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.ref.id, setValue: (v) => update((c) => {\n if (isCenterMarkContent(c)) {\n c.ref.id = v;\n }\n }) }) : void 0,\n content.ref.partIndex !== void 0 ? /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.ref.partIndex, setValue: (v) => update((c) => {\n if (isCenterMarkContent(c)) {\n c.ref.partIndex = v;\n }\n }) }) : void 0\n ]\n };\n },\n isValid: (c, p) => ctx.validate(c, CenterMarkReferenceContent, p),\n getRefIds,\n updateRefId(content, update) {\n const newRefId = update(content.ref.id);\n if (newRefId !== void 0) {\n content.ref.id = newRefId;\n }\n }\n };\n}\nfunction isCenterMarkContent(content) {\n return content.type === "center mark";\n}\nfunction contentSelectable(content) {\n return !!content && (isArcContent(content) || isCircleContent(content));\n}\nfunction getCommand(ctx) {\n const React = ctx.React;\n const icon = /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 100 100" }, /* @__PURE__ */ React.createElement("polyline", { points: "48,0 48,100", strokeWidth: "5", strokeDasharray: "8", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polyline", { points: "0,49 100,49", strokeWidth: "5", strokeDasharray: "8", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }));\n return {\n name: "create center mark",\n icon,\n contentSelectable,\n selectType: "select part",\n execute({ contents, selected }) {\n contents.push(...selected.map(([index, partIndex]) => ({\n type: "center mark",\n ref: {\n id: index,\n partIndex\n }\n })));\n }\n };\n}\nexport {\n getCommand,\n getModel,\n isCenterMarkContent\n};\n','// dev/cad-editor/plugins/line-polyline.plugin.tsx\nfunction isLineContent(content) {\n return content.type === "line";\n}\n\n// dev/cad-editor/plugins/chamfer.plugin.tsx\nfunction getCommand(ctx) {\n function getChamfers(content1, content2, d1, d2) {\n const result = [];\n if (isLineContent(content1) && isLineContent(content2)) {\n const point = ctx.getTwoLinesIntersectionPoint(content1.points[0], content1.points[1], content2.points[0], content2.points[1]);\n if (point) {\n const p1 = [];\n const a1 = ctx.getPointByLengthAndDirectionSafely(point, d1, content1.points[0]);\n const b1 = ctx.getPointByLengthAndDirectionSafely(point, d1, content1.points[1]);\n if (a1) {\n p1.push(a1);\n }\n if (b1 && (!a1 || !ctx.isSamePoint(a1, b1))) {\n p1.push(b1);\n }\n const p2 = [];\n const a2 = ctx.getPointByLengthAndDirectionSafely(point, d2, content2.points[0]);\n const b2 = ctx.getPointByLengthAndDirectionSafely(point, d2, content2.points[1]);\n if (a2) {\n p2.push(a2);\n }\n if (b2 && (!a2 || !ctx.isSamePoint(a2, b2))) {\n p2.push(b2);\n }\n for (const c1 of p1) {\n for (const c2 of p2) {\n result.push([c1, c2]);\n }\n }\n }\n }\n return result;\n }\n const React = ctx.React;\n const icon = /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 100 100" }, /* @__PURE__ */ React.createElement("polyline", { points: "11,12 57,12 86,41 86,86", strokeWidth: "3", vectorEffect: "non-scaling-stroke", fill: "none", stroke: "currentColor" }));\n return {\n name: "chamfer",\n useCommand({ onEnd, type, selected, scale }) {\n const [candidates, setCandidates] = React.useState([]);\n const [result, setResult] = React.useState();\n let message = "";\n if (type) {\n if (candidates.length > 0) {\n message = "select one result";\n } else {\n message = "input distance";\n }\n }\n const assistentContents = candidates.map((c) => ({\n type: "line",\n points: c,\n dashArray: c === result ? void 0 : [4 / scale]\n }));\n const { input, setInputPosition, setCursorPosition, clearText, resetInput } = ctx.useCursorInput(message, type && candidates.length == 0 ? (e, text) => {\n if (e.key === "Enter") {\n const position = text.split(",");\n if (position.length === 2) {\n const d1 = +position[0];\n const d2 = +position[1];\n if (!isNaN(d1) && !isNaN(d2)) {\n setCandidates(getChamfers(selected[0].content, selected[1].content, d1, d2));\n clearText();\n }\n } else {\n const d = +text;\n if (!isNaN(d)) {\n setCandidates(getChamfers(selected[0].content, selected[1].content, d, d));\n clearText();\n }\n }\n }\n } : void 0);\n const reset = () => {\n setCandidates([]);\n setResult(void 0);\n clearText();\n resetInput();\n };\n return {\n onStart(p) {\n setCursorPosition(p);\n if (result) {\n onEnd({\n updateContents: (contents) => {\n contents.push({ type: "line", points: result });\n }\n });\n setCandidates([]);\n }\n },\n input,\n onMove(p, viewportPosition) {\n setCursorPosition(p);\n setInputPosition(viewportPosition || p);\n setResult(candidates.find((c) => ctx.getPointAndLineSegmentMinimumDistance(p, c[0], c[1]) < 5));\n },\n assistentContents,\n reset\n };\n },\n selectCount: 2,\n contentSelectable: (c) => isLineContent(c),\n selectType: "select part",\n hotkey: "CHA",\n icon\n };\n}\nexport {\n getCommand\n};\n','// dev/cad-editor/plugins/line-polyline.plugin.tsx\nfunction isLineContent(content) {\n return content.type === "line";\n}\nfunction isPolyLineContent(content) {\n return content.type === "polyline";\n}\n\n// dev/cad-editor/plugins/circle-arc.plugin.tsx\nfunction getModel(ctx) {\n const CircleContent = ctx.and(ctx.BaseContent("circle"), ctx.StrokeFields, ctx.FillFields, ctx.Circle, {\n xExpression: ctx.optional(ctx.string),\n yExpression: ctx.optional(ctx.string),\n rExpression: ctx.optional(ctx.string)\n });\n const ArcContent = ctx.and(ctx.BaseContent("arc"), ctx.StrokeFields, ctx.FillFields, ctx.AngleDeltaFields, ctx.Arc);\n const getRefIds = (content) => ctx.getStrokeAndFillRefIds(content);\n const circleGeometriesCache = new ctx.WeakmapValuesCache();\n const arcGeometriesCache = new ctx.WeakmapValuesCache();\n function getCircleGeometries(content, contents, time) {\n const quadrantPoints = ctx.getCircleQuadrantPoints(content);\n if (time && (content.xExpression || content.yExpression || content.rExpression)) {\n const x = ctx.getTimeExpressionValue(content.xExpression, time, content.x);\n const y = ctx.getTimeExpressionValue(content.yExpression, time, content.y);\n const r = ctx.getTimeExpressionValue(content.rExpression, time, content.r);\n return { quadrantPoints, ...getArcGeometries(ctx.circleToArc({ ...content, x, y, r }), contents) };\n }\n const refs = new Set(ctx.iterateRefContents(getRefIds(content), contents, [content]));\n return circleGeometriesCache.get(content, refs, () => {\n return { quadrantPoints, ...getArcGeometries(ctx.circleToArc(content), contents) };\n });\n }\n function getArcGeometries(content, contents) {\n const refs = new Set(ctx.iterateRefContents(getRefIds(content), contents, [content]));\n return arcGeometriesCache.get(content, refs, () => {\n var _a;\n const points = ctx.arcToPolyline(content, (_a = content.angleDelta) != null ? _a : ctx.defaultAngleDelta);\n const middleAngle = ctx.getTwoNumberCenter(content.startAngle, ctx.getFormattedEndAngle(content));\n const geometries = {\n lines: [{ type: "arc", curve: content }],\n points,\n start: ctx.getArcPointAtAngle(content, content.startAngle),\n end: ctx.getArcPointAtAngle(content, content.endAngle),\n middle: ctx.getArcPointAtAngle(content, middleAngle),\n bounding: ctx.getArcBounding(content),\n renderingLines: ctx.dashedPolylineToLines(points, content.dashArray)\n };\n if (ctx.hasFill(content)) {\n return {\n ...geometries,\n lines: [],\n points: geometries.points,\n bounding: geometries.bounding,\n regions: [{\n lines: geometries.lines,\n points: geometries.points\n }],\n renderingLines: []\n };\n }\n return geometries;\n });\n }\n const React = ctx.React;\n return [\n {\n type: "circle",\n ...ctx.strokeModel,\n ...ctx.fillModel,\n move(content, offset) {\n ctx.movePoint(content, offset);\n },\n rotate(content, center, angle) {\n ctx.rotatePoint(content, center, angle);\n },\n scale(content, center, sx, sy) {\n if (sx !== sy && !ctx.isZero(sx + sy)) {\n const ellipse = {\n ...content,\n type: "ellipse",\n cx: content.x,\n cy: content.y,\n rx: content.r,\n ry: content.r\n };\n ctx.scaleEllipse(ellipse, center, sx, sy);\n return ellipse;\n }\n ctx.scalePoint(content, center, sx, sy);\n content.r *= Math.abs(sx);\n return;\n },\n skew(content, center, sx, sy) {\n const ellipse = {\n ...content,\n type: "ellipse",\n cx: content.x,\n cy: content.y,\n rx: content.r,\n ry: content.r\n };\n ctx.skewEllipse(ellipse, center, sx, sy);\n return ellipse;\n },\n mirror(content, line) {\n ctx.mirrorPoint(content, line);\n },\n offset(content, point, distance) {\n if (!distance) {\n distance = ctx.getTwoNumbersDistance(ctx.getTwoPointsDistance(point, content), content.r);\n }\n return ctx.getParallelCirclesByDistance(content, distance)[ctx.pointSideToIndex(ctx.getPointSideOfCircle(point, content))];\n },\n break(content, points) {\n if (points.length < 2) {\n return;\n }\n const angles = points.map((p) => ctx.radianToAngle(ctx.getCircleRadian(p, content)));\n angles.sort((a, b) => a - b);\n return angles.map((a, i) => ({\n ...content,\n type: "arc",\n startAngle: a,\n endAngle: i === angles.length - 1 ? angles[0] + 360 : angles[i + 1]\n }));\n },\n render(content, renderCtx) {\n const { options, dashed, time, contents, target } = ctx.getStrokeFillRenderOptionsFromRenderContext(content, renderCtx);\n if (dashed) {\n const { points } = getCircleGeometries(content, contents, time);\n return target.renderPolyline(points, options);\n }\n const x = ctx.getTimeExpressionValue(content.xExpression, time, content.x);\n const y = ctx.getTimeExpressionValue(content.yExpression, time, content.y);\n const r = ctx.getTimeExpressionValue(content.rExpression, time, content.r);\n return target.renderCircle(x, y, r, options);\n },\n getOperatorRenderPosition(content) {\n return content;\n },\n getEditPoints(content, contents) {\n return ctx.getEditPointsFromCache(content, () => {\n const x = content.x;\n const y = content.y;\n const { quadrantPoints } = getCircleGeometries(content, contents);\n const updateEdges = (c, { cursor, scale }) => {\n if (!isCircleContent(c)) {\n return;\n }\n c.r = ctx.getTwoPointsDistance(cursor, c);\n return { assistentContents: [{ type: "line", dashArray: [4 / scale], points: [content, cursor] }] };\n };\n return {\n editPoints: [\n {\n x,\n y,\n cursor: "move",\n type: "move",\n update(c, { cursor, start, scale }) {\n if (!isCircleContent(c)) {\n return;\n }\n c.x += cursor.x - start.x;\n c.y += cursor.y - start.y;\n return { assistentContents: [{ type: "line", dashArray: [4 / scale], points: [content, cursor] }] };\n }\n },\n {\n ...quadrantPoints[0],\n cursor: "ew-resize",\n update: updateEdges\n },\n {\n ...quadrantPoints[1],\n cursor: "ns-resize",\n update: updateEdges\n },\n {\n ...quadrantPoints[2],\n cursor: "ew-resize",\n update: updateEdges\n },\n {\n ...quadrantPoints[3],\n cursor: "ns-resize",\n update: updateEdges\n }\n ],\n angleSnapStartPoint: content\n };\n });\n },\n getSnapPoints(content, contents) {\n const { quadrantPoints } = getCircleGeometries(content, contents);\n return ctx.getSnapPointsFromCache(content, () => [\n { x: content.x, y: content.y, type: "center" },\n ...quadrantPoints.map((p) => ({ ...p, type: "endpoint" }))\n ]);\n },\n getGeometries: getCircleGeometries,\n propertyPanel(content, update, contents, { acquirePoint }) {\n return {\n from: /* @__PURE__ */ React.createElement(ctx.Button, { onClick: () => acquirePoint((p) => update((c) => {\n if (isCircleContent(c)) {\n c.x = p.x;\n c.y = p.y;\n }\n })) }, "canvas"),\n x: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.x, setValue: (v) => update((c) => {\n if (isCircleContent(c)) {\n c.x = v;\n }\n }) }),\n y: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.y, setValue: (v) => update((c) => {\n if (isCircleContent(c)) {\n c.y = v;\n }\n }) }),\n r: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.r, setValue: (v) => update((c) => {\n if (isCircleContent(c)) {\n c.r = v;\n }\n }) }),\n xExpression: [\n /* @__PURE__ */ React.createElement(ctx.BooleanEditor, { value: content.xExpression !== void 0, setValue: (v) => update((c) => {\n if (isCircleContent(c)) {\n c.xExpression = v ? "" : void 0;\n }\n }) }),\n content.xExpression !== void 0 ? /* @__PURE__ */ React.createElement(ctx.StringEditor, { value: content.xExpression, setValue: (v) => update((c) => {\n if (isCircleContent(c)) {\n c.xExpression = v;\n }\n }) }) : void 0\n ],\n yExpression: [\n /* @__PURE__ */ React.createElement(ctx.BooleanEditor, { value: content.yExpression !== void 0, setValue: (v) => update((c) => {\n if (isCircleContent(c)) {\n c.yExpression = v ? "" : void 0;\n }\n }) }),\n content.yExpression !== void 0 ? /* @__PURE__ */ React.createElement(ctx.StringEditor, { value: content.yExpression, setValue: (v) => update((c) => {\n if (isCircleContent(c)) {\n c.yExpression = v;\n }\n }) }) : void 0\n ],\n rExpression: [\n /* @__PURE__ */ React.createElement(ctx.BooleanEditor, { value: content.rExpression !== void 0, setValue: (v) => update((c) => {\n if (isCircleContent(c)) {\n c.rExpression = v ? "" : void 0;\n }\n }) }),\n content.rExpression !== void 0 ? /* @__PURE__ */ React.createElement(ctx.StringEditor, { value: content.rExpression, setValue: (v) => update((c) => {\n if (isCircleContent(c)) {\n c.rExpression = v;\n }\n }) }) : void 0\n ],\n ...ctx.getStrokeContentPropertyPanel(content, update, contents),\n ...ctx.getFillContentPropertyPanel(content, update, contents)\n };\n },\n isValid: (c, p) => ctx.validate(c, CircleContent, p),\n getRefIds,\n updateRefId: ctx.updateStrokeAndFillRefIds,\n deleteRefId: ctx.deleteStrokeAndFillRefIds,\n isPointIn: (content, point) => ctx.getTwoPointsDistance(content, point) < content.r,\n getArea: (content) => Math.PI * content.r ** 2\n },\n {\n type: "arc",\n ...ctx.strokeModel,\n ...ctx.fillModel,\n ...ctx.angleDeltaModel,\n move(content, offset) {\n ctx.movePoint(content, offset);\n },\n rotate(content, center, angle) {\n ctx.rotateArc(content, center, angle);\n },\n scale(content, center, sx, sy) {\n if (sx !== sy && !ctx.isZero(sx + sy)) {\n const ellipse = {\n ...content,\n type: "ellipse arc",\n cx: content.x,\n cy: content.y,\n rx: content.r,\n ry: content.r\n };\n ctx.scaleEllipseArc(ellipse, center, sx, sy);\n return ellipse;\n }\n ctx.scalePoint(content, center, sx, sy);\n content.r *= Math.abs(sx);\n return;\n },\n skew(content, center, sx, sy) {\n const ellipse = {\n ...content,\n type: "ellipse arc",\n cx: content.x,\n cy: content.y,\n rx: content.r,\n ry: content.r\n };\n ctx.skewEllipseArc(ellipse, center, sx, sy);\n return ellipse;\n },\n mirror(content, line, angle) {\n ctx.mirrorArc(content, line, angle);\n },\n offset(content, point, distance) {\n if (!distance) {\n distance = ctx.getTwoNumbersDistance(ctx.getTwoPointsDistance(point, content), content.r);\n }\n return ctx.getParallelArcsByDistance(content, distance)[ctx.pointSideToIndex(ctx.getPointSideOfArc(point, content))];\n },\n break(content, points) {\n if (points.length === 0) {\n return;\n }\n const angles = points.map((p) => ctx.normalizeAngleInRange(ctx.radianToAngle(ctx.getCircleRadian(p, content)), content));\n angles.sort((a, b) => a - b);\n const result = [];\n if (!ctx.isSameNumber(angles[0], content.startAngle)) {\n result.push({\n ...content,\n type: "arc",\n startAngle: content.startAngle,\n endAngle: angles[0]\n });\n }\n angles.forEach((a, i) => {\n if (i === angles.length - 1) {\n if (!ctx.isSameNumber(a, content.endAngle)) {\n result.push({\n ...content,\n type: "arc",\n startAngle: a,\n endAngle: content.endAngle\n });\n }\n } else {\n result.push({\n ...content,\n type: "arc",\n startAngle: a,\n endAngle: angles[i + 1]\n });\n }\n });\n return result.length > 1 ? result : void 0;\n },\n join(content, target) {\n if (isArcContent(target)) {\n return ctx.mergeArc(content, target);\n }\n if (isLineContent(target) || isPolyLineContent(target)) {\n const newLines = ctx.mergeGeometryLines([{ type: "arc", curve: content }], Array.from(ctx.iteratePolylineLines(target.points)));\n if (newLines) {\n return ctx.geometryLinesToPline(newLines);\n }\n }\n return;\n },\n extend(content, point) {\n const angle = ctx.radianToAngle(ctx.getCircleRadian(point, content));\n const endAngle = ctx.getFormattedEndAngle({ startAngle: content.startAngle, endAngle: angle });\n const startAngle = ctx.getFormattedStartAngle({ startAngle: angle, endAngle: content.endAngle });\n const angle1 = Math.abs(endAngle - content.startAngle);\n const angle2 = Math.abs(content.endAngle - startAngle);\n if (angle1 < angle2) {\n content.endAngle = endAngle;\n } else {\n content.startAngle = startAngle;\n }\n },\n render(content, renderCtx) {\n const { options, dashed, target } = ctx.getStrokeFillRenderOptionsFromRenderContext(content, renderCtx);\n if (dashed) {\n return target.renderPolyline(getArcGeometries(content, renderCtx.contents).points, options);\n }\n return target.renderArc(content.x, content.y, content.r, content.startAngle, content.endAngle, { ...options, counterclockwise: content.counterclockwise });\n },\n renderIfSelected(content, { color, target, strokeWidth, contents }) {\n const { points } = getArcGeometries({ ...content, startAngle: content.endAngle, endAngle: content.startAngle }, contents);\n return target.renderPolyline(points, { strokeColor: color, dashArray: [4], strokeWidth });\n },\n getOperatorRenderPosition(content, contents) {\n const { points } = getArcGeometries(content, contents);\n return points[0];\n },\n getEditPoints(content, contents) {\n return ctx.getEditPointsFromCache(content, () => {\n const { start, end, middle } = getArcGeometries(content, contents);\n return {\n editPoints: [\n {\n x: content.x,\n y: content.y,\n cursor: "move",\n type: "move",\n update(c, { cursor, start: start2, scale }) {\n if (!isArcContent(c)) {\n return;\n }\n c.x += cursor.x - start2.x;\n c.y += cursor.y - start2.y;\n return { assistentContents: [{ type: "line", dashArray: [4 / scale], points: [content, cursor] }] };\n }\n },\n {\n ...start,\n cursor: ctx.getResizeCursor(content.startAngle, "top"),\n update(c, { cursor, scale }) {\n if (!isArcContent(c)) {\n return;\n }\n c.startAngle = ctx.radianToAngle(ctx.getCircleRadian(cursor, c));\n c.r = ctx.getTwoPointsDistance(cursor, c);\n ctx.normalizeAngleRange(c);\n return { assistentContents: [{ type: "line", dashArray: [4 / scale], points: [content, cursor] }] };\n }\n },\n {\n ...end,\n cursor: ctx.getResizeCursor(content.endAngle, "top"),\n update(c, { cursor, scale }) {\n if (!isArcContent(c)) {\n return;\n }\n c.endAngle = ctx.radianToAngle(ctx.getCircleRadian(cursor, c));\n c.r = ctx.getTwoPointsDistance(cursor, c);\n ctx.normalizeAngleRange(c);\n return { assistentContents: [{ type: "line", dashArray: [4 / scale], points: [content, cursor] }] };\n }\n },\n {\n ...middle,\n cursor: ctx.getResizeCursor((content.startAngle + content.endAngle) / 2, "right"),\n update(c, { cursor, scale }) {\n if (!isArcContent(c)) {\n return;\n }\n c.r = ctx.getTwoPointsDistance(cursor, c);\n return { assistentContents: [{ type: "line", dashArray: [4 / scale], points: [content, cursor] }] };\n }\n }\n ],\n angleSnapStartPoint: content\n };\n });\n },\n getSnapPoints(content, contents) {\n return ctx.getSnapPointsFromCache(content, () => {\n const { start, end, middle } = getArcGeometries(content, contents);\n return [\n { x: content.x, y: content.y, type: "center" },\n { ...start, type: "endpoint" },\n { ...end, type: "endpoint" },\n { ...middle, type: "midpoint" }\n ];\n });\n },\n getGeometries: getArcGeometries,\n propertyPanel(content, update, contents, { acquirePoint }) {\n return {\n from: /* @__PURE__ */ React.createElement(ctx.Button, { onClick: () => acquirePoint((p) => update((c) => {\n if (isArcContent(c)) {\n c.x = p.x;\n c.y = p.y;\n }\n })) }, "canvas"),\n x: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.x, setValue: (v) => update((c) => {\n if (isArcContent(c)) {\n c.x = v;\n }\n }) }),\n y: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.y, setValue: (v) => update((c) => {\n if (isArcContent(c)) {\n c.y = v;\n }\n }) }),\n r: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.r, setValue: (v) => update((c) => {\n if (isArcContent(c)) {\n c.r = v;\n }\n }) }),\n startAngle: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.startAngle, setValue: (v) => update((c) => {\n if (isArcContent(c)) {\n c.startAngle = v;\n }\n }) }),\n endAngle: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.endAngle, setValue: (v) => update((c) => {\n if (isArcContent(c)) {\n c.endAngle = v;\n }\n }) }),\n counterclockwise: /* @__PURE__ */ React.createElement(ctx.BooleanEditor, { value: content.counterclockwise === true, setValue: (v) => update((c) => {\n if (isArcContent(c)) {\n c.counterclockwise = v ? true : void 0;\n }\n }) }),\n ...ctx.getStrokeContentPropertyPanel(content, update, contents),\n ...ctx.getFillContentPropertyPanel(content, update, contents),\n ...ctx.getAngleDeltaContentPropertyPanel(content, update)\n };\n },\n isValid: (c, p) => ctx.validate(c, ArcContent, p),\n getRefIds,\n updateRefId: ctx.updateStrokeAndFillRefIds,\n deleteRefId: ctx.deleteStrokeAndFillRefIds,\n getArea: (content) => {\n const radian = ctx.angleToRadian(content.endAngle - content.startAngle);\n return content.r ** 2 * (radian - Math.sin(radian)) / 2;\n },\n reverse: (content) => ctx.reverseArc(content)\n }\n ];\n}\nfunction isCircleContent(content) {\n return content.type === "circle";\n}\nfunction isArcContent(content) {\n return content.type === "arc";\n}\nfunction getCommand(ctx) {\n const React = ctx.React;\n const circleIcon = /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 100 100" }, /* @__PURE__ */ React.createElement("circle", { cx: "44", cy: "48", r: "39", strokeWidth: "2", vectorEffect: "non-scaling-stroke", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polyline", { points: "44,48 66,15", strokeWidth: "2", vectorEffect: "non-scaling-stroke", fill: "none", stroke: "currentColor" }));\n const icon2 = /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 100 100" }, /* @__PURE__ */ React.createElement("circle", { cx: "44", cy: "48", r: "39", strokeWidth: "2", vectorEffect: "non-scaling-stroke", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("circle", { cx: "18", cy: "20", r: "12", strokeWidth: "0", vectorEffect: "non-scaling-stroke", fill: "currentColor", stroke: "#000000" }), /* @__PURE__ */ React.createElement("circle", { cx: "72", cy: "76", r: "12", strokeWidth: "0", vectorEffect: "non-scaling-stroke", fill: "currentColor", stroke: "#000000" }));\n const icon3 = /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 100 100" }, /* @__PURE__ */ React.createElement("circle", { cx: "44", cy: "48", r: "39", strokeWidth: "2", vectorEffect: "non-scaling-stroke", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("circle", { cx: "18", cy: "20", r: "12", strokeWidth: "0", vectorEffect: "non-scaling-stroke", fill: "currentColor", stroke: "#000000" }), /* @__PURE__ */ React.createElement("circle", { cx: "36", cy: "87", r: "12", strokeWidth: "0", vectorEffect: "non-scaling-stroke", fill: "currentColor", stroke: "#000000" }), /* @__PURE__ */ React.createElement("circle", { cx: "80", cy: "28", r: "12", strokeWidth: "0", vectorEffect: "non-scaling-stroke", fill: "currentColor", stroke: "#000000" }));\n const circleIcon4 = /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 100 100" }, /* @__PURE__ */ React.createElement("circle", { cx: "44", cy: "48", r: "39", strokeWidth: "2", vectorEffect: "non-scaling-stroke", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polyline", { points: "25,82 66,15", strokeWidth: "2", vectorEffect: "non-scaling-stroke", fill: "none", stroke: "currentColor" }));\n const arcIcon = /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 100 100" }, /* @__PURE__ */ React.createElement("path", { d: "M 31 80 A 35 35 0 1 0 25 24", strokeWidth: "2", vectorEffect: "non-scaling-stroke", fill: "none", stroke: "currentColor" }));\n return [\n {\n name: "create circle",\n type: [\n { name: "2 points", icon: icon2 },\n { name: "3 points", icon: icon3 },\n { name: "center radius", hotkey: "C", icon: circleIcon },\n { name: "center diameter", icon: circleIcon4 }\n ],\n useCommand({ onEnd, scale, type, strokeStyleId, fillStyleId }) {\n const { circle, onClick, onMove, input, startPosition, middlePosition, cursorPosition, reset } = ctx.useCircleClickCreate(\n type === "2 points" || type === "3 points" || type === "center diameter" || type === "center radius" ? type : void 0,\n (c) => onEnd({\n updateContents: (contents) => contents.push({ ...c, strokeStyleId, fillStyleId, type: "circle" })\n })\n );\n const assistentContents = [];\n if (startPosition && cursorPosition) {\n if (middlePosition) {\n assistentContents.push({ type: "polygon", points: [startPosition, middlePosition, cursorPosition], dashArray: [4 / scale] });\n } else {\n assistentContents.push(\n { type: "line", points: [startPosition, cursorPosition], dashArray: [4 / scale] },\n ...ctx.getAssistentText(\n ctx.getTwoPointsDistance(startPosition, cursorPosition).toFixed(2),\n 16 / scale,\n (startPosition.x + cursorPosition.x) / 2 - 20,\n (startPosition.y + cursorPosition.y) / 2 + 4\n )\n );\n }\n }\n if (circle) {\n assistentContents.push({ ...circle, strokeStyleId, fillStyleId, type: "circle" });\n }\n return {\n onStart: onClick,\n input,\n onMove,\n assistentContents,\n lastPosition: middlePosition != null ? middlePosition : startPosition,\n reset\n };\n },\n selectCount: 0\n },\n {\n name: "create arc",\n useCommand({ onEnd, type, scale, strokeStyleId, fillStyleId }) {\n const { circle, arc, onClick, onMove, input, startPosition, middlePosition, cursorPosition, reset } = ctx.useCircleArcClickCreate(\n type === "create arc" ? "center radius" : void 0,\n (c) => onEnd({\n updateContents: (contents) => contents.push({ ...c, strokeStyleId, fillStyleId, type: "arc" })\n })\n );\n const assistentContents = [];\n if (startPosition && cursorPosition) {\n if (middlePosition) {\n assistentContents.push({ type: "polygon", points: [startPosition, middlePosition, cursorPosition], dashArray: [4 / scale] });\n } else {\n assistentContents.push(\n { type: "line", points: [startPosition, cursorPosition], dashArray: [4 / scale] },\n ...ctx.getAssistentText(\n ctx.getTwoPointsDistance(startPosition, cursorPosition).toFixed(2),\n 16 / scale,\n (startPosition.x + cursorPosition.x) / 2 - 20,\n (startPosition.y + cursorPosition.y) / 2 + 4\n )\n );\n }\n }\n if (arc) {\n assistentContents.push({ ...arc, dashArray: [4 / scale], type: "circle" });\n if (arc.startAngle !== arc.endAngle) {\n assistentContents.push(\n {\n type: "line",\n points: [\n {\n x: arc.x + arc.r * Math.cos(ctx.angleToRadian(arc.startAngle)),\n y: arc.y + arc.r * Math.sin(ctx.angleToRadian(arc.startAngle))\n },\n {\n x: arc.x,\n y: arc.y\n }\n ],\n dashArray: [4 / scale]\n },\n {\n type: "line",\n points: [\n {\n x: arc.x,\n y: arc.y\n },\n {\n x: arc.x + arc.r * Math.cos(ctx.angleToRadian(arc.endAngle)),\n y: arc.y + arc.r * Math.sin(ctx.angleToRadian(arc.endAngle))\n }\n ],\n dashArray: [4 / scale]\n }\n );\n }\n if (cursorPosition) {\n assistentContents.push({ type: "line", points: [arc, cursorPosition], dashArray: [4 / scale] });\n }\n }\n if (circle) {\n assistentContents.push({ ...circle, dashArray: [4 / scale], type: "circle" });\n if (cursorPosition) {\n assistentContents.push({ type: "line", points: [circle, cursorPosition], dashArray: [4 / scale] });\n }\n }\n if (arc && arc.startAngle !== arc.endAngle) {\n assistentContents.push({ ...arc, strokeStyleId, fillStyleId, type: "arc" });\n }\n return {\n onStart: onClick,\n input,\n onMove,\n assistentContents,\n lastPosition: middlePosition != null ? middlePosition : startPosition,\n reset\n };\n },\n selectCount: 0,\n hotkey: "A",\n icon: arcIcon\n }\n ];\n}\nexport {\n getCommand,\n getModel,\n isArcContent,\n isCircleContent\n};\n','// dev/cad-editor/plugins/clip.plugin.tsx\nfunction getCommand(ctx) {\n const React = ctx.React;\n const icon = /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 100 100" }, /* @__PURE__ */ React.createElement("mask", { id: "clip" }, /* @__PURE__ */ React.createElement("path", { d: "M 1 1 L 1 100 L 103 100 L 103 1", strokeWidth: "0", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "white", stroke: "currentColor", fillRule: "evenodd" }), /* @__PURE__ */ React.createElement("path", { d: "M 91 70 L 91 73 L 91 75 L 90 78 L 90 80 L 89 82 L 88 84 L 86 86 L 85 88 L 83 90 L 81 91 L 79 93 L 77 94 L 75 95 L 73 96 L 71 97 L 68 97 L 66 98 L 64 98 L 61 98 L 59 97 L 57 97 L 54 96 L 52 95 L 50 94 L 48 93 L 46 91 L 44 90 L 43 88 L 41 86 L 40 84 L 39 82 L 38 80 L 37 78 L 37 75 L 36 73 L 36 70 L 36 68 L 37 66 L 37 63 L 38 61 L 39 59 L 40 57 L 41 55 L 43 53 L 44 51 L 46 49 L 48 48 L 50 47 L 52 46 L 54 45 L 57 44 L 59 43 L 61 43 L 64 43 L 66 43 L 68 43 L 71 44 L 73 45 L 75 46 L 77 47 L 79 48 L 81 49 L 83 51 L 85 53 L 86 55 L 88 57 L 89 59 L 90 61 L 90 63 L 91 66 L 91 68 L 91 70", fill: "black" })), /* @__PURE__ */ React.createElement("g", { mask: "url(#clip)" }, /* @__PURE__ */ React.createElement("polygon", { points: "83,99 77,64 103,38 67,33 51,1 35,33 1,39 25,64 19,100 51,83", strokeWidth: "0", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fillOpacity: "1", strokeOpacity: "1", fill: "currentColor", stroke: "currentColor" })));\n return {\n name: "clip",\n icon,\n useCommand({ type, onEnd, acquireContent, selected, contents }) {\n const target = React.useRef();\n const border = React.useRef();\n const reset = () => {\n target.current = void 0;\n border.current = void 0;\n };\n React.useEffect(() => {\n if (!type) return;\n if (!target.current) {\n target.current = selected[0].path;\n acquireContent(\n {\n count: 1,\n selectable: (v) => {\n var _a, _b;\n const content = ctx.getContentByIndex(contents, v);\n if (!content) return false;\n const geometries = (_b = (_a = ctx.getContentModel(content)) == null ? void 0 : _a.getGeometries) == null ? void 0 : _b.call(_a, content, contents);\n if (!geometries) return false;\n return geometries.lines.length > 0;\n }\n },\n (r) => {\n border.current = ctx.getRefPart(r[0], contents, (c) => c !== selected[0].content);\n }\n );\n } else if (border.current) {\n onEnd({\n updateContents(contents2) {\n if (target.current) {\n const content = contents2[target.current[0]];\n if (content && ctx.isClipContent(content) && border.current) {\n content.clip = {\n border: border.current\n };\n }\n }\n }\n });\n reset();\n }\n }, [type]);\n return {\n onStart() {\n },\n reset\n };\n },\n selectCount: 1,\n contentSelectable(content) {\n return ctx.isClipContent(content) && !content.readonly;\n }\n };\n}\nexport {\n getCommand\n};\n','// dev/cad-editor/plugins/clone.plugin.tsx\nfunction getCommand(ctx) {\n const React = ctx.React;\n const icon = /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 100 100" }, /* @__PURE__ */ React.createElement("rect", { x: "8", y: "27", width: "62", height: "65", strokeWidth: "3", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("rect", { x: "30", y: "8", width: "62", height: "65", strokeWidth: "3", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }));\n return {\n name: "clone",\n useCommand({ onEnd, transform, type, scale }) {\n const { offset, onStart, mask, startPosition, resetDragMove } = ctx.useDragMove(\n () => onEnd({}),\n {\n repeatedly: true,\n transform,\n ignoreLeavingEvent: true\n }\n );\n let message = "";\n if (type) {\n message = startPosition ? "specify end point" : "specify start point";\n }\n const { input, setInputPosition, resetInput } = ctx.useCursorInput(message);\n const reset = () => {\n resetDragMove();\n resetInput();\n };\n return {\n onStart: (s) => onStart(s),\n mask,\n reset,\n input,\n onMove(_, p) {\n setInputPosition(p);\n },\n updateSelectedContent(content) {\n if (startPosition && (offset.x !== 0 || offset.y !== 0)) {\n return {\n newContents: [\n ctx.produce(content, (d) => {\n var _a, _b;\n (_b = (_a = ctx.getContentModel(d)) == null ? void 0 : _a.move) == null ? void 0 : _b.call(_a, d, offset);\n })\n ]\n };\n }\n return {};\n },\n assistentContents: startPosition && (offset.x !== 0 || offset.y !== 0) ? [\n {\n type: "line",\n dashArray: [4 / scale],\n points: [startPosition, { x: startPosition.x + offset.x, y: startPosition.y + offset.y }]\n }\n ] : void 0\n };\n },\n contentSelectable(content) {\n var _a;\n return ((_a = ctx.getContentModel(content)) == null ? void 0 : _a.move) !== void 0;\n },\n hotkey: "CO",\n icon,\n repeatedly: true\n };\n}\nexport {\n getCommand\n};\n','// dev/cad-editor/plugins/circle-arc.plugin.tsx\nfunction isArcContent(content) {\n return content.type === "arc";\n}\n\n// dev/cad-editor/plugins/line-polyline.plugin.tsx\nfunction isLineContent(content) {\n return content.type === "line";\n}\nfunction isPolyLineContent(content) {\n return content.type === "polyline";\n}\n\n// dev/cad-editor/plugins/ellipse.plugin.tsx\nfunction isEllipseArcContent(content) {\n return content.type === "ellipse arc";\n}\n\n// dev/cad-editor/plugins/combined-path.plugin.tsx\nfunction getModel(ctx) {\n const CombinedPathContent = ctx.and(ctx.BaseContent("combined path"), ctx.ContainerFields, ctx.StrokeFields, ctx.FillFields);\n const getRefIds = (content) => ctx.getStrokeAndFillRefIds(content);\n const getGeometries = (content, contents) => {\n const refs = new Set(ctx.iterateRefContents(getRefIds(content), contents, [content]));\n return ctx.getGeometriesFromCache(content, refs, () => {\n const lines = [];\n const result = [];\n const boundings = [];\n content.contents.forEach((c) => {\n var _a, _b, _c, _d;\n if (!c) {\n return;\n }\n const r = (_b = (_a = ctx.getContentModel(c)) == null ? void 0 : _a.getGeometries) == null ? void 0 : _b.call(_a, c, contents);\n if (r) {\n lines.push(...r.lines);\n if (r.bounding) {\n boundings.push(r.bounding.start, r.bounding.end);\n }\n }\n if (isLineContent(c) || isPolyLineContent(c)) {\n result.push({ points: c.points });\n } else if (isArcContent(c)) {\n result.push({ points: ctx.arcToPolyline(c, (_c = c.angleDelta) != null ? _c : ctx.defaultAngleDelta) });\n } else if (isEllipseArcContent(c)) {\n result.push({ points: ctx.ellipseArcToPolyline(c, (_d = c.angleDelta) != null ? _d : ctx.defaultAngleDelta) });\n }\n });\n ctx.mergePolylinesToPolyline(result);\n const renderingLines = result.map((m) => m.points);\n const points = renderingLines.flat();\n return {\n lines,\n bounding: ctx.getPointsBounding(boundings),\n renderingLines,\n regions: ctx.hasFill(content) ? [{\n lines,\n points\n }] : void 0\n };\n });\n };\n return {\n type: "combined path",\n ...ctx.containerModel,\n ...ctx.strokeModel,\n ...ctx.fillModel,\n move: ctx.getContainerMove,\n rotate: ctx.getContainerRotate,\n scale: ctx.getContainerScale,\n explode: ctx.getContainerExplode,\n mirror: ctx.getContainerMirror,\n render(content, renderCtx) {\n const geometries = getGeometries(content, renderCtx.contents);\n const { options } = ctx.getStrokeFillRenderOptionsFromRenderContext(content, renderCtx);\n return renderCtx.target.renderGroup(geometries.renderingLines.map((line) => {\n return renderCtx.target.renderPolyline(line, options);\n }));\n },\n renderIfSelected: (content, renderCtx) => ctx.getContainerRenderIfSelected(content, renderCtx, [content], getRefIds),\n getSnapPoints: ctx.getContainerSnapPoints,\n getGeometries,\n propertyPanel(content, update, contents) {\n return {\n ...ctx.getStrokeContentPropertyPanel(content, update, contents),\n ...ctx.getFillContentPropertyPanel(content, update, contents)\n };\n },\n isValid: (c, p) => ctx.validate(c, CombinedPathContent, p),\n getRefIds,\n updateRefId: ctx.updateStrokeAndFillRefIds,\n deleteRefId: ctx.deleteStrokeAndFillRefIds\n };\n}\nfunction getCommand(ctx) {\n function contentSelectable(content, contents) {\n return ctx.contentIsDeletable(content, contents) && (isLineContent(content) || isArcContent(content) || isPolyLineContent(content) || isEllipseArcContent(content));\n }\n const React = ctx.React;\n const icon = /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 100 100" }, /* @__PURE__ */ React.createElement("polyline", { points: "36,93 40,92 43,90 47,88 51,86 55,84 58,81 62,79 65,76 69,73 72,70 75,67 78,64 80,60 83,57 85,54 86,51 88,47 89,44 90,41 90,38 91,36 90,33 90,31 89,28 88,26 87,25 85,23 83,22 81,21 78,20 76,20 73,20 69,20 66,20 63,21 59,22 55,23 52,25 48,27 44,29 40,31 37,34 33,36 30,39 26,42 23,45 20,48 17,51 15,55 12,58 10,61 9,64 36,93", strokeWidth: "0", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "currentColor", stroke: "currentColor" }));\n return {\n name: "create combined path",\n execute({ contents, selected, strokeStyleId, fillStyleId }) {\n const newContent = {\n type: "combined path",\n strokeStyleId,\n fillStyleId,\n contents: contents.filter((c, i) => c && ctx.isSelected([i], selected) && contentSelectable(c, contents))\n };\n ctx.deleteSelectedContents(contents, selected.map((s) => s[0]));\n contents.push(newContent);\n },\n contentSelectable,\n icon\n };\n}\nexport {\n getCommand,\n getModel\n};\n','// dev/cad-editor/plugins/compress.plugin.tsx\nfunction getCommand(ctx) {\n const React = ctx.React;\n const icon = /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 100 100" }, /* @__PURE__ */ React.createElement("rect", { x: "10", y: "44", width: "81", height: "20", strokeWidth: "0", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "currentColor", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("rect", { x: "9", y: "69", width: "81", height: "20", strokeWidth: "0", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "currentColor", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polygon", { points: "42,6 57,6 57,31 73,31 51,44 27,32 42,32", strokeWidth: "0", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "currentColor", stroke: "currentColor" }));\n return {\n name: "compress",\n execute({ contents }) {\n var _a, _b;\n const newIndexes = [];\n let validContentCount = 0;\n const invalidContentsIndex = [];\n const contentIsValid = (d) => {\n var _a2, _b2;\n return !!d && ((_b2 = (_a2 = ctx.getContentModel(d)) == null ? void 0 : _a2.isValid(d)) != null ? _b2 : true) === true;\n };\n contents.forEach((d, i) => {\n if (contentIsValid(d)) {\n newIndexes.push(validContentCount);\n if (ctx.isContainerContent(d)) {\n d.contents = d.contents.filter((c) => contentIsValid(c));\n }\n validContentCount++;\n } else {\n newIndexes.push(void 0);\n invalidContentsIndex.unshift(i);\n }\n });\n invalidContentsIndex.forEach((i) => {\n contents.splice(i, 1);\n });\n for (const content of ctx.iterateAllContents(contents)) {\n (_b = (_a = ctx.getContentModel(content)) == null ? void 0 : _a.updateRefId) == null ? void 0 : _b.call(_a, content, (refId) => typeof refId === "number" ? newIndexes[refId] : void 0);\n }\n ctx.contentIndexCache.clear();\n },\n selectCount: 0,\n icon\n };\n}\nexport {\n getCommand\n};\n','// dev/cad-editor/plugins/coordinate-axis.plugin.tsx\nfunction getModel(ctx) {\n const CoordinateAxisContent = ctx.and(ctx.BaseContent("coordinate axis"), ctx.StrokeFields, ctx.ArrowFields, ctx.Position, ctx.Bounding, {\n flipY: ctx.optional(ctx.boolean)\n });\n const getRefIds = (content) => ctx.getStrokeRefIds(content);\n function getGeometriesFromCache(content, contents) {\n const refs = new Set(ctx.iterateRefContents(getRefIds(content), contents, [content]));\n return ctx.getGeometriesFromCache(content, refs, () => {\n const yMin = content.flipY ? -content.yMax : content.yMin;\n const yMax = content.flipY ? -content.yMin : content.yMax;\n const lines = [\n [\n { x: content.x + content.xMin, y: content.y },\n { x: content.x + content.xMax, y: content.y }\n ],\n [\n { x: content.x, y: content.y + yMin },\n { x: content.x, y: content.y + yMax }\n ]\n ];\n const areas = [];\n const renderingLines = [];\n lines.forEach(([p1, p2], i) => {\n if (content.flipY && i === 1) {\n [p2, p1] = [p1, p2];\n }\n const { arrowPoints, endPoint } = ctx.getArrowPoints(p1, p2, content);\n areas.push(arrowPoints);\n lines[i][content.flipY && i === 1 ? 0 : 1] = endPoint;\n renderingLines.push(...ctx.dashedPolylineToLines(lines[i], content.dashArray));\n });\n return {\n lines,\n bounding: {\n start: {\n x: content.x + Math.min(0, content.xMin, content.xMax),\n y: content.y + Math.min(0, yMin, yMax)\n },\n end: {\n x: content.x + Math.max(0, content.xMin, content.xMax),\n y: content.y + Math.max(0, yMin, yMax)\n }\n },\n regions: areas.map((e) => ({\n points: e,\n lines: Array.from(ctx.iteratePolygonLines(e))\n })),\n renderingLines\n };\n });\n }\n const React = ctx.React;\n return {\n type: "coordinate axis",\n ...ctx.strokeModel,\n ...ctx.arrowModel,\n move(content, offset) {\n ctx.movePoint(content, offset);\n },\n render(content, renderCtx) {\n const { options, target, fillOptions } = ctx.getStrokeRenderOptionsFromRenderContext(content, renderCtx);\n const { regions, renderingLines } = getGeometriesFromCache(content, renderCtx.contents);\n const children = [];\n for (const line of renderingLines) {\n children.push(target.renderPolyline(line, options));\n }\n if (regions) {\n for (let i = 0; i < regions.length; i++) {\n children.push(target.renderPolygon(regions[i].points, fillOptions));\n }\n }\n return target.renderGroup(children);\n },\n getEditPoints(content) {\n return ctx.getEditPointsFromCache(content, () => {\n return {\n editPoints: [\n {\n ...content,\n cursor: "move",\n update(c, { cursor, start, scale }) {\n if (!isCoordinateAxisContent(c)) {\n return;\n }\n c.x += cursor.x - start.x;\n c.y += cursor.y - start.y;\n return { assistentContents: [{ type: "line", dashArray: [4 / scale], points: [start, cursor] }] };\n }\n }\n ]\n };\n });\n },\n getGeometries: getGeometriesFromCache,\n propertyPanel(content, update, contents, { acquirePoint }) {\n return {\n from: /* @__PURE__ */ React.createElement(ctx.Button, { onClick: () => acquirePoint((p) => update((c) => {\n if (isCoordinateAxisContent(c)) {\n c.x = p.x;\n c.y = p.y;\n }\n })) }, "canvas"),\n x: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.x, setValue: (v) => update((c) => {\n if (isCoordinateAxisContent(c)) {\n c.x = v;\n }\n }) }),\n y: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.y, setValue: (v) => update((c) => {\n if (isCoordinateAxisContent(c)) {\n c.y = v;\n }\n }) }),\n xMin: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.xMin, setValue: (v) => update((c) => {\n if (isCoordinateAxisContent(c)) {\n c.xMin = v;\n }\n }) }),\n xMax: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.xMax, setValue: (v) => update((c) => {\n if (isCoordinateAxisContent(c)) {\n c.xMax = v;\n }\n }) }),\n yMin: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.yMin, setValue: (v) => update((c) => {\n if (isCoordinateAxisContent(c)) {\n c.yMin = v;\n }\n }) }),\n yMax: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.yMax, setValue: (v) => update((c) => {\n if (isCoordinateAxisContent(c)) {\n c.yMax = v;\n }\n }) }),\n flipY: /* @__PURE__ */ React.createElement(ctx.BooleanEditor, { value: content.flipY === true, setValue: (v) => update((c) => {\n if (isCoordinateAxisContent(c)) {\n c.flipY = v ? true : void 0;\n }\n }) }),\n ...ctx.getArrowContentPropertyPanel(content, update),\n ...ctx.getStrokeContentPropertyPanel(content, update, contents)\n };\n },\n isValid: (c, p) => ctx.validate(c, CoordinateAxisContent, p),\n getRefIds,\n updateRefId: ctx.updateStrokeRefIds,\n deleteRefId: ctx.deleteStrokeRefIds\n };\n}\nfunction isCoordinateAxisContent(content) {\n return content.type === "coordinate axis";\n}\nfunction getCommand(ctx) {\n const React = ctx.React;\n const icon = /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 100 100" }, /* @__PURE__ */ React.createElement("polyline", { points: "0,50 95,50", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polyline", { points: "50,5 50,100", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polyline", { points: "100,50 82,58 82,42", strokeWidth: "0", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "currentColor", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polyline", { points: "50,0 58,18 42,18", strokeWidth: "0", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "currentColor", stroke: "currentColor" }));\n return {\n name: "create coordinate axis",\n selectCount: 0,\n icon,\n useCommand({ onEnd, type }) {\n const [result, setResult] = React.useState();\n const reset = () => {\n setResult(void 0);\n };\n return {\n onStart() {\n if (result) {\n onEnd({\n updateContents: (contents) => {\n if (result) {\n contents.push(result);\n }\n }\n });\n reset();\n }\n },\n onMove(p) {\n if (type) {\n setResult({\n type: "coordinate axis",\n x: p.x,\n y: p.y,\n xMin: -50,\n xMax: 50,\n yMin: -50,\n yMax: 50,\n flipY: true\n });\n }\n },\n assistentContents: result ? [result] : void 0,\n reset\n };\n }\n };\n}\nexport {\n getCommand,\n getModel,\n isCoordinateAxisContent\n};\n','// dev/cad-editor/plugins/copy-paste.plugin.tsx\nfunction getCommand(ctx) {\n const React = ctx.React;\n const CopyData = {\n contents: ctx.minItems(0, [{\n id: ctx.number,\n content: ctx.Content\n }]),\n center: ctx.Position\n };\n const cutOrCopyCommand = {\n name: "copy",\n execute({ contents, selected, type }) {\n const ids = [];\n contents.forEach((content, index) => {\n if (content && ctx.isSelected([index], selected)) {\n for (const id of ctx.iterateRefIds([index], contents)) {\n const index2 = ids.indexOf(id);\n if (index2 >= 0) {\n ids.splice(index2, 1);\n }\n ids.push(id);\n }\n }\n });\n if (type === "cut") {\n ctx.deleteSelectedContents(contents, selected.map((s) => s[0]));\n }\n const copiedContents = [];\n const boundingPoints = [];\n ids.forEach((id) => {\n var _a, _b;\n const content = contents[id];\n if (content) {\n const geometries = (_b = (_a = ctx.getContentModel(content)) == null ? void 0 : _a.getGeometries) == null ? void 0 : _b.call(_a, content, contents);\n if (geometries == null ? void 0 : geometries.bounding) {\n boundingPoints.push(geometries.bounding.start, geometries.bounding.end);\n }\n copiedContents.unshift({\n id,\n content\n });\n }\n });\n const bounding = ctx.getPointsBounding(boundingPoints);\n if (!bounding) {\n return;\n }\n const copyData = {\n contents: copiedContents,\n center: ctx.getTwoPointCenter(bounding.start, bounding.end)\n };\n navigator.clipboard.writeText(JSON.stringify(copyData));\n }\n };\n return [\n cutOrCopyCommand,\n {\n ...cutOrCopyCommand,\n name: "cut"\n },\n {\n name: "paste",\n useCommand({ onEnd, type }) {\n let message = "";\n if (type) {\n message = "specify target point";\n }\n const [copyData, setCopyData] = React.useState();\n const { input, setInputPosition, cursorPosition, setCursorPosition, resetInput } = ctx.useCursorInput(message);\n ctx.useValueChanged(type, () => {\n if (type) {\n (async () => {\n try {\n const text = await navigator.clipboard.readText();\n const copyData2 = JSON.parse(text);\n const r = ctx.validate(copyData2, CopyData);\n if (r === true) {\n setCopyData(copyData2);\n return;\n } else {\n console.info(r);\n reset();\n onEnd();\n }\n } catch (error) {\n console.info(error);\n }\n })();\n }\n });\n const reset = () => {\n setCopyData(void 0);\n resetInput();\n setCursorPosition(void 0);\n setInputPosition(void 0);\n };\n const assistentContents = [];\n if (cursorPosition && copyData) {\n const offset = {\n x: cursorPosition.x - copyData.center.x,\n y: cursorPosition.y - copyData.center.y\n };\n copyData.contents.forEach((c) => {\n assistentContents.push(ctx.produce(c.content, (draft) => {\n var _a, _b;\n const model = ctx.getContentModel(draft);\n (_a = model == null ? void 0 : model.move) == null ? void 0 : _a.call(model, draft, offset);\n (_b = model == null ? void 0 : model.updateRefId) == null ? void 0 : _b.call(model, draft, (d) => {\n if (typeof d === "number") {\n const index = copyData.contents.findIndex((c2) => c2.id === d);\n if (index >= 0 && index < assistentContents.length) {\n return assistentContents[index];\n }\n }\n return void 0;\n });\n }));\n });\n }\n return {\n onStart(p) {\n resetInput();\n onEnd({\n updateContents: (contents) => {\n if (copyData) {\n const offset = {\n x: p.x - copyData.center.x,\n y: p.y - copyData.center.y\n };\n const idMap = {};\n let id = contents.length;\n copyData.contents.forEach((c) => {\n idMap[c.id] = id++;\n });\n copyData.contents.forEach((c) => {\n contents.push(ctx.produce(c.content, (draft) => {\n var _a, _b;\n const model = ctx.getContentModel(draft);\n (_a = model == null ? void 0 : model.move) == null ? void 0 : _a.call(model, draft, offset);\n (_b = model == null ? void 0 : model.updateRefId) == null ? void 0 : _b.call(model, draft, (d) => typeof d === "number" ? idMap[d] : void 0);\n }));\n });\n }\n reset();\n }\n });\n },\n input,\n onMove(p, viewportPosition) {\n setInputPosition(viewportPosition || p);\n if (!type) {\n return;\n }\n setCursorPosition(p);\n },\n assistentContents,\n reset\n };\n },\n selectCount: 0\n }\n ];\n}\nexport {\n getCommand\n};\n','// dev/cad-editor/plugins/create-tangent-tangent-line.plugin.tsx\nfunction getCommand(ctx) {\n function getTangentTangentLines(line1, line2) {\n if (line1 && line2) {\n return ctx.getLinesTangentTo2GeometryLines(line1, line2);\n }\n return [];\n }\n const React = ctx.React;\n const icon = /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 100 100" }, /* @__PURE__ */ React.createElement("circle", { cx: "78", cy: "80", r: "18", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fillOpacity: "1", strokeOpacity: "1", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("circle", { cx: "29", cy: "29", r: "27", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fillOpacity: "1", strokeOpacity: "1", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polyline", { points: "92,70 51,13", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", strokeOpacity: "1", fill: "none", stroke: "currentColor" }));\n return {\n name: "create tangent tangent line",\n useCommand({ onEnd, type, selected, scale }) {\n const [candidates, setCandidates] = React.useState();\n const [result, setResult] = React.useState();\n const assistentContents = (candidates || []).map((c) => ({\n points: c,\n type: "line",\n dashArray: c === result ? void 0 : [4 / scale]\n }));\n React.useEffect(() => {\n var _a, _b;\n if (type && !candidates) {\n setCandidates(getTangentTangentLines((_a = selected[0].lines) == null ? void 0 : _a[0], (_b = selected[1].lines) == null ? void 0 : _b[0]));\n }\n }, [type, selected]);\n const reset = () => {\n setCandidates(void 0);\n setResult(void 0);\n };\n return {\n onStart() {\n if (result) {\n onEnd({\n updateContents: (contents) => {\n contents.push({ type: "line", points: result });\n }\n });\n reset();\n }\n },\n onMove(p) {\n setResult(candidates == null ? void 0 : candidates.find((c) => ctx.getPointAndLineSegmentMinimumDistance(p, ...c) < 5));\n },\n assistentContents,\n reset\n };\n },\n selectCount: 2,\n selectType: "select part",\n icon\n };\n}\nexport {\n getCommand\n};\n','// dev/cad-editor/plugins/circle-arc.plugin.tsx\nfunction isCircleContent(content) {\n return content.type === "circle";\n}\nfunction isArcContent(content) {\n return content.type === "arc";\n}\n\n// dev/cad-editor/plugins/line-polyline.plugin.tsx\nfunction isLineContent(content) {\n return content.type === "line";\n}\n\n// dev/cad-editor/plugins/create-tangent-tangent-radius-circle.plugin.tsx\nfunction getCommand(ctx) {\n function getTangentTangentRadiusCircles(content1, content2, radius) {\n const result = [];\n if (isCircleContent(content1) || isArcContent(content1)) {\n if (isCircleContent(content2) || isArcContent(content2)) {\n result.push(...ctx.getCirclesTangentTo2Circles(content1, content2, radius));\n } else if (isLineContent(content2)) {\n const line2 = ctx.twoPointLineToGeneralFormLine(content2.points[0], content2.points[1]);\n if (!line2) return [];\n result.push(...ctx.getCirclesTangentToLineAndCircle(line2, content1, radius));\n }\n } else if (isLineContent(content1)) {\n const line1 = ctx.twoPointLineToGeneralFormLine(content1.points[0], content1.points[1]);\n if (!line1) return [];\n if (isCircleContent(content2) || isArcContent(content2)) {\n result.push(...ctx.getCirclesTangentToLineAndCircle(line1, content2, radius));\n } else if (isLineContent(content2)) {\n const line2 = ctx.twoPointLineToGeneralFormLine(content2.points[0], content2.points[1]);\n if (!line2) return [];\n result.push(...ctx.getCirclesTangentTo2Lines(line1, line2, radius));\n }\n }\n return result.map((c) => ({ ...c, r: radius }));\n }\n const React = ctx.React;\n const icon = /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 100 100" }, /* @__PURE__ */ React.createElement("polyline", { points: "10,87 89,87", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("circle", { cx: "17", cy: "40", r: "16", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("circle", { cx: "60", cy: "57", r: "30", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }));\n const contentSelectable = (c) => isCircleContent(c) || isArcContent(c) || isLineContent(c);\n const command = {\n name: "create tangent tangent radius circle",\n useCommand({ onEnd, type, selected, scale }) {\n const [candidates, setCandidates] = React.useState([]);\n const [result, setResult] = React.useState();\n let message = "";\n if (type) {\n if (candidates.length > 0) {\n message = "select one result";\n } else {\n message = "input radius";\n }\n }\n const assistentContents = candidates.map((c) => ({\n ...c,\n type: "circle",\n dashArray: c === result ? void 0 : [4 / scale]\n }));\n const { input, setInputPosition, setCursorPosition, clearText, resetInput } = ctx.useCursorInput(message, type && candidates.length == 0 ? (e, text) => {\n if (e.key === "Enter") {\n const radius = +text;\n if (!isNaN(radius)) {\n setCandidates(getTangentTangentRadiusCircles(selected[0].content, selected[1].content, radius));\n clearText();\n }\n }\n } : void 0);\n const reset = () => {\n setCandidates([]);\n setResult(void 0);\n clearText();\n resetInput();\n };\n return {\n onStart(p) {\n setCursorPosition(p);\n if (result) {\n onEnd({\n updateContents: (contents) => {\n contents.push({ type: "circle", ...result });\n }\n });\n setCandidates([]);\n }\n },\n input,\n onMove(p, viewportPosition) {\n setCursorPosition(p);\n setInputPosition(viewportPosition || p);\n setResult(candidates.find((c) => ctx.getTwoNumbersDistance(ctx.getTwoPointsDistance(c, p), c.r) < 5));\n },\n assistentContents,\n reset\n };\n },\n selectCount: 2,\n contentSelectable,\n selectType: "select part",\n icon\n };\n return [\n command,\n {\n ...command,\n name: "create tangent tangent radius circle 2",\n useCommand({ onEnd, type, scale, contentVisible, contents, getContentsInRange }) {\n const [first, setFirst] = React.useState();\n const [second, setSecond] = React.useState();\n const [hovering, setHovering] = React.useState();\n const [result, setResult] = React.useState();\n let message = "";\n if (type) {\n if (!first) {\n message = "select first circle, arc or line";\n } else if (!second) {\n message = "select second circle, arc or line";\n } else {\n message = "input radius";\n }\n }\n const assistentContents = [];\n if (result) {\n assistentContents.push({ ...result, type: "circle", dashArray: [4 / scale] });\n }\n const selected = [];\n if (first) {\n selected.push(first.path);\n }\n if (second) {\n selected.push(second.path);\n }\n const getCandidate = (radius) => {\n if (!first || !second) return;\n const candidates = getTangentTangentRadiusCircles(first.content, second.content, radius);\n return ctx.minimumBy(candidates, (c) => ctx.getTwoPointsDistanceSquare(c, first.point) + ctx.getTwoPointsDistanceSquare(c, second.point));\n };\n const { input, setInputPosition, setCursorPosition, clearText, resetInput } = ctx.useCursorInput(message, type ? (e, text) => {\n if (e.key === "Enter") {\n const radius = +text;\n if (!isNaN(radius) && first && second) {\n const candidate = getCandidate(radius);\n if (!candidate) return;\n onEnd({\n updateContents: (contents2) => {\n contents2.push({ type: "circle", ...candidate });\n }\n });\n reset();\n }\n }\n } : void 0);\n const reset = () => {\n setFirst(void 0);\n setSecond(void 0);\n setHovering(void 0);\n setResult(void 0);\n clearText();\n resetInput();\n };\n const selectContent = (p) => {\n const indexes = getContentsInRange({ start: p, end: p }).filter((c) => !!c).map((c) => ctx.getContentIndex(c, contents));\n const contentPath = ctx.getContentByClickPosition(contents, p, (c) => {\n const content = ctx.getContentByIndex(contents, c);\n return !!content && contentSelectable(content);\n }, ctx.getContentModel, true, contentVisible, indexes, 3 / scale);\n if (contentPath) {\n const content = ctx.getContentByIndex(contents, contentPath);\n if (content) {\n return { content, point: p, path: contentPath };\n }\n }\n return;\n };\n return {\n onStart(p) {\n if (!first) {\n setFirst(hovering);\n setHovering(void 0);\n return;\n } else if (!second) {\n setSecond(hovering);\n setHovering(void 0);\n return;\n }\n setCursorPosition(p);\n if (result) {\n onEnd({\n updateContents: (contents2) => {\n contents2.push({ type: "circle", ...result });\n }\n });\n reset();\n }\n },\n input,\n onMove(p, viewportPosition) {\n setCursorPosition(p);\n setInputPosition(viewportPosition || p);\n if (!first) {\n setHovering(selectContent(p));\n return;\n } else if (!second) {\n setHovering(selectContent(p));\n return;\n }\n setResult(getCandidate(ctx.getTwoPointsDistance(second.point, p)));\n },\n assistentContents,\n selected,\n hovering: hovering ? [hovering.path] : void 0,\n reset\n };\n },\n selectCount: 0\n }\n ];\n}\nexport {\n getCommand\n};\n','// dev/cad-editor/plugins/circle-arc.plugin.tsx\nfunction isCircleContent(content) {\n return content.type === "circle";\n}\nfunction isArcContent(content) {\n return content.type === "arc";\n}\n\n// dev/cad-editor/plugins/line-polyline.plugin.tsx\nfunction isLineContent(content) {\n return content.type === "line";\n}\n\n// dev/cad-editor/plugins/create-tangent-tangent-tangent-circle.plugin.tsx\nfunction getCommand(ctx) {\n function getTangentTangentTangentCircles(content1, content2, content3) {\n const result = [];\n if (isLineContent(content1)) {\n const line1 = ctx.twoPointLineToGeneralFormLine(content1.points[0], content1.points[1]);\n if (!line1) return [];\n if (isLineContent(content2)) {\n const line2 = ctx.twoPointLineToGeneralFormLine(content2.points[0], content2.points[1]);\n if (!line2) return [];\n if (isLineContent(content3)) {\n const line3 = ctx.twoPointLineToGeneralFormLine(content3.points[0], content3.points[1]);\n if (!line3) return [];\n result.push(...ctx.getCirclesTangentTo3Lines(line1, line2, line3));\n } else if (isCircleContent(content3) || isArcContent(content3)) {\n result.push(...ctx.getCirclesTangentToLineLineCircle(line1, line2, content3));\n }\n } else if (isCircleContent(content2) || isArcContent(content2)) {\n if (isLineContent(content3)) {\n const line3 = ctx.twoPointLineToGeneralFormLine(content3.points[0], content3.points[1]);\n if (!line3) return [];\n result.push(...ctx.getCirclesTangentToLineLineCircle(line1, line3, content2));\n } else if (isCircleContent(content3) || isArcContent(content3)) {\n result.push(...ctx.getCirclesTangentToLineCircleCircle(line1, content2, content3));\n }\n }\n } else if (isCircleContent(content1) || isArcContent(content1)) {\n if (isLineContent(content2)) {\n const line2 = ctx.twoPointLineToGeneralFormLine(content2.points[0], content2.points[1]);\n if (!line2) return [];\n if (isLineContent(content3)) {\n const line3 = ctx.twoPointLineToGeneralFormLine(content3.points[0], content3.points[1]);\n if (!line3) return [];\n result.push(...ctx.getCirclesTangentToLineLineCircle(line2, line3, content1));\n } else if (isCircleContent(content3) || isArcContent(content3)) {\n result.push(...ctx.getCirclesTangentToLineCircleCircle(line2, content1, content3));\n }\n } else if (isCircleContent(content2) || isArcContent(content2)) {\n if (isLineContent(content3)) {\n const line3 = ctx.twoPointLineToGeneralFormLine(content3.points[0], content3.points[1]);\n if (!line3) return [];\n result.push(...ctx.getCirclesTangentToLineCircleCircle(line3, content1, content2));\n } else if (isCircleContent(content3) || isArcContent(content3)) {\n result.push(...ctx.getCirclesTangentTo3Circles(content1, content2, content3));\n }\n }\n }\n return result;\n }\n const React = ctx.React;\n const icon = /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 100 100" }, /* @__PURE__ */ React.createElement("polyline", { points: "0,8 100,8", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", strokeOpacity: "1", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polyline", { points: "99,19 60,100", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", strokeOpacity: "1", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polyline", { points: "0,22 44,98", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", strokeOpacity: "1", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("circle", { cx: "50", cy: "42", r: "34", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fillOpacity: "1", strokeOpacity: "1", fill: "none", stroke: "currentColor" }));\n return {\n name: "create tangent tangent tangent circle",\n useCommand({ onEnd, type, selected, scale }) {\n const [candidates, setCandidates] = React.useState();\n const [result, setResult] = React.useState();\n const assistentContents = (candidates || []).map((c) => ({\n ...c,\n type: "circle",\n dashArray: c === result ? void 0 : [4 / scale]\n }));\n const reset = () => {\n setCandidates(void 0);\n setResult(void 0);\n };\n React.useEffect(() => {\n if (type && !candidates) {\n setCandidates(getTangentTangentTangentCircles(selected[0].content, selected[1].content, selected[2].content));\n }\n }, [type, selected]);\n return {\n onStart() {\n if (result) {\n onEnd({\n updateContents: (contents) => {\n contents.push({ type: "circle", ...result });\n }\n });\n setCandidates([]);\n }\n },\n onMove(p) {\n setResult(candidates == null ? void 0 : candidates.find((c) => ctx.getTwoNumbersDistance(ctx.getTwoPointsDistance(c, p), c.r) < 5));\n },\n assistentContents,\n reset\n };\n },\n selectCount: 3,\n contentSelectable: (c) => isLineContent(c) || isCircleContent(c) || isArcContent(c),\n selectType: "select part",\n icon\n };\n}\nexport {\n getCommand\n};\n','// dev/cad-editor/plugins/delete.plugin.tsx\nfunction getCommand(ctx) {\n const React = ctx.React;\n const icon = /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 100 100" }, /* @__PURE__ */ React.createElement("polyline", { points: "17,21 80,84", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polyline", { points: "77,23 19,81", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }));\n return {\n name: "delete",\n execute({ contents, selected }) {\n ctx.deleteSelectedContents(contents, selected.map((s) => s[0]));\n },\n contentSelectable(content, contents) {\n return ctx.contentIsDeletable(content, contents);\n },\n hotkey: "E",\n icon\n };\n}\nexport {\n getCommand\n};\n','// dev/cad-editor/plugins/diamond.plugin.tsx\nfunction getModel(ctx) {\n const DiamondContent = ctx.and(ctx.BaseContent("diamond"), ctx.StrokeFields, ctx.FillFields, ctx.Region);\n const getRefIds = (content) => ctx.getStrokeAndFillRefIds(content);\n const geometriesCache = new ctx.WeakmapValuesCache();\n function getGeometries(content, contents) {\n const refs = new Set(ctx.iterateRefContents(getRefIds(content), contents, [content]));\n return geometriesCache.get(content, refs, () => {\n const points = [\n { x: content.x, y: content.y - content.height / 2 },\n { x: content.x + content.width / 2, y: content.y },\n { x: content.x, y: content.y + content.height / 2 },\n { x: content.x - content.width / 2, y: content.y }\n ];\n const lines = Array.from(ctx.iteratePolygonLines(points));\n return {\n lines,\n points,\n bounding: ctx.getPointsBounding(points),\n renderingLines: ctx.dashedPolylineToLines(ctx.polygonToPolyline(points), content.dashArray),\n regions: ctx.hasFill(content) ? [\n {\n lines,\n points\n }\n ] : void 0\n };\n });\n }\n const React = ctx.React;\n return {\n type: "diamond",\n ...ctx.strokeModel,\n ...ctx.fillModel,\n move(content, offset) {\n ctx.movePoint(content, offset);\n },\n scale(content, center, sx, sy) {\n ctx.scalePoint(content, center, sx, sy);\n content.width *= sx;\n content.height *= sy;\n },\n skew(content, center, sx, sy, contents) {\n const points = ctx.produce(getGeometries(content, contents).points, (draft) => {\n for (const p of draft) {\n ctx.skewPoint(p, center, sx, sy);\n }\n });\n return { ...content, points, type: "polygon" };\n },\n explode(content, contents) {\n const { lines } = getGeometries(content, contents);\n return lines.map((line) => ({ type: "line", points: line }));\n },\n offset(content, point, distance, contents) {\n var _a;\n if (!distance) {\n distance = Math.min(...getGeometries(content, contents).lines.map((line) => ctx.getPointAndGeometryLineMinimumDistance(point, line)));\n }\n distance *= ((_a = this.isPointIn) == null ? void 0 : _a.call(this, content, point, contents)) ? -2 : 2;\n const scale = content.width / content.height;\n const height = distance / Math.sin(Math.atan(scale));\n const width = height * scale;\n return ctx.produce(content, (d) => {\n d.width += width;\n d.height += height;\n });\n },\n render(content, renderCtx) {\n const { options, target } = ctx.getStrokeFillRenderOptionsFromRenderContext(content, renderCtx);\n const { points } = getGeometries(content, renderCtx.contents);\n return target.renderPolygon(points, options);\n },\n getOperatorRenderPosition(content, contents) {\n const { points } = getGeometries(content, contents);\n return points[0];\n },\n getEditPoints(content, contents) {\n return ctx.getEditPointsFromCache(content, () => {\n const { points } = getGeometries(content, contents);\n return {\n editPoints: [\n { x: content.x, y: content.y, direction: "center" },\n { ...points[0], direction: "top" },\n { ...points[1], direction: "right" },\n { ...points[2], direction: "bottom" },\n { ...points[3], direction: "left" }\n ].map((p) => ({\n x: p.x,\n y: p.y,\n cursor: ctx.getResizeCursor(0, p.direction),\n update(c, { cursor, start, scale }) {\n if (!isDiamondContent(c)) {\n return;\n }\n const offset = ctx.getResizeOffset(start, cursor, p.direction);\n if (!offset) {\n return;\n }\n c.x += offset.x + offset.width / 2;\n c.y += offset.y + offset.height / 2;\n c.width += offset.width;\n c.height += offset.height;\n return { assistentContents: [{ type: "line", dashArray: [4 / scale], points: [start, cursor] }] };\n }\n }))\n };\n });\n },\n getSnapPoints(content, contents) {\n return ctx.getSnapPointsFromCache(content, () => {\n const { points, lines } = getGeometries(content, contents);\n return [\n { x: content.x, y: content.y, type: "center" },\n ...points.map((p) => ({ ...p, type: "endpoint" })),\n ...lines.map(([start, end]) => ({\n x: (start.x + end.x) / 2,\n y: (start.y + end.y) / 2,\n type: "midpoint"\n }))\n ];\n });\n },\n getGeometries,\n canSelectPart: true,\n propertyPanel(content, update, contents, { acquirePoint }) {\n return {\n from: /* @__PURE__ */ React.createElement(ctx.Button, { onClick: () => acquirePoint((p) => update((c) => {\n if (isDiamondContent(c)) {\n c.x = p.x;\n c.y = p.y;\n }\n })) }, "canvas"),\n x: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.x, setValue: (v) => update((c) => {\n if (isDiamondContent(c)) {\n c.x = v;\n }\n }) }),\n y: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.y, setValue: (v) => update((c) => {\n if (isDiamondContent(c)) {\n c.y = v;\n }\n }) }),\n width: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.width, setValue: (v) => update((c) => {\n if (isDiamondContent(c)) {\n c.width = v;\n }\n }) }),\n height: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.height, setValue: (v) => update((c) => {\n if (isDiamondContent(c)) {\n c.height = v;\n }\n }) }),\n ...ctx.getStrokeContentPropertyPanel(content, update, contents),\n ...ctx.getFillContentPropertyPanel(content, update, contents)\n };\n },\n isValid: (c, p) => ctx.validate(c, DiamondContent, p),\n getRefIds,\n updateRefId: ctx.updateStrokeAndFillRefIds,\n deleteRefId: ctx.deleteStrokeAndFillRefIds,\n isPointIn: (content, point, contents) => ctx.pointInPolygon(point, getGeometries(content, contents).points)\n };\n}\nfunction isDiamondContent(content) {\n return content.type === "diamond";\n}\nfunction getCommand(ctx) {\n const React = ctx.React;\n const icon = /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 100 100" }, /* @__PURE__ */ React.createElement("polygon", { points: "52,5 97,50 52,96 6,50", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }));\n return {\n name: "create diamond",\n icon,\n useCommand({ onEnd, type, strokeStyleId, fillStyleId, scale }) {\n const { line, onClick, onMove, input, lastPosition, reset } = ctx.useLineClickCreate(\n type === "create diamond",\n (c) => onEnd({\n updateContents: (contents) => contents.push({\n type: "diamond",\n x: (c[0].x + c[1].x) / 2,\n y: (c[0].y + c[1].y) / 2,\n width: Math.abs(c[0].x - c[1].x),\n height: Math.abs(c[0].y - c[1].y),\n strokeStyleId,\n fillStyleId\n })\n }),\n {\n once: true\n }\n );\n const assistentContents = [];\n if (line) {\n assistentContents.push({\n type: "diamond",\n x: (line[0].x + line[1].x) / 2,\n y: (line[0].y + line[1].y) / 2,\n width: Math.abs(line[0].x - line[1].x),\n height: Math.abs(line[0].y - line[1].y),\n strokeStyleId,\n fillStyleId\n });\n assistentContents.push({\n type: "rect",\n x: (line[0].x + line[1].x) / 2,\n y: (line[0].y + line[1].y) / 2,\n width: Math.abs(line[0].x - line[1].x),\n height: Math.abs(line[0].y - line[1].y),\n angle: 0,\n dashArray: [4 / scale]\n });\n }\n return {\n onStart: onClick,\n input,\n onMove,\n assistentContents,\n lastPosition,\n reset\n };\n },\n selectCount: 0\n };\n}\nexport {\n getCommand,\n getModel,\n isDiamondContent\n};\n','// dev/cad-editor/plugins/difference.plugin.tsx\nfunction getCommand(ctx) {\n const React = ctx.React;\n const icon = /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 100 100" }, /* @__PURE__ */ React.createElement("circle", { cx: "32", cy: "50", r: "32", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fillOpacity: "1", strokeOpacity: "1", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("circle", { cx: "65", cy: "50", r: "32", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fillOpacity: "1", strokeOpacity: "1", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("pattern", { id: "difference", patternUnits: "userSpaceOnUse", width: "10", height: "10" }, /* @__PURE__ */ React.createElement("path", { d: "M 0 5 L 5 0 M 10 5 L 5 10", strokeWidth: "1", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor", fillRule: "evenodd" })), /* @__PURE__ */ React.createElement("path", { d: "M 49 78 L 46 79 L 44 81 L 41 81 L 38 82 L 35 82 L 32 82 L 30 82 L 27 82 L 24 81 L 21 81 L 19 79 L 16 78 L 14 77 L 12 75 L 10 73 L 8 71 L 6 69 L 4 66 L 3 64 L 2 61 L 1 58 L 0 56 L 0 53 L 0 50 L 0 47 L 0 44 L 1 42 L 2 39 L 3 36 L 4 34 L 6 31 L 8 29 L 10 27 L 12 25 L 14 23 L 16 22 L 19 21 L 21 19 L 24 19 L 27 18 L 30 18 L 32 18 L 35 18 L 38 18 L 41 19 L 44 19 L 46 21 L 49 22 L 49 22 L 46 23 L 44 25 L 42 27 L 40 29 L 38 31 L 37 34 L 36 36 L 34 39 L 34 42 L 33 44 L 33 47 L 32 50 L 33 53 L 33 56 L 34 58 L 34 61 L 36 64 L 37 66 L 38 69 L 40 71 L 42 73 L 44 75 L 46 77 L 49 78", strokeWidth: "0", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fillOpacity: "1", fill: "url(#difference)", stroke: "currentColor", fillRule: "evenodd" }));\n return {\n name: "difference",\n execute({ contents, selected }) {\n var _a, _b, _c, _d;\n const first = contents[selected[0][0]];\n if (!first) return;\n const firstGeometries = (_b = (_a = ctx.getContentModel(first)) == null ? void 0 : _a.getGeometries) == null ? void 0 : _b.call(_a, first, contents);\n if (!firstGeometries) return;\n const second = contents[selected[1][0]];\n if (!second) return;\n const secondGeometries = (_d = (_c = ctx.getContentModel(second)) == null ? void 0 : _c.getGeometries) == null ? void 0 : _d.call(_c, second, contents);\n if (!secondGeometries) return;\n if (firstGeometries.regions && secondGeometries.regions) {\n const result = firstGeometries.regions.map((r) => ctx.getHatchesDifference({ border: r.lines, holes: r.holes || [] }, (secondGeometries.regions || []).map((g) => ({ border: g.lines, holes: g.holes || [] })))).flat();\n ctx.deleteSelectedContents(contents, selected.map((s) => s[0]));\n contents.push(...result.map((r) => ({ ...first, type: "hatch", border: r.border, holes: r.holes, ref: void 0 })));\n return;\n }\n const lines = ctx.getGeometryLinesDifferenceLines(firstGeometries.lines, secondGeometries.lines);\n ctx.deleteSelectedContents(contents, selected.map((s) => s[0]));\n const allLines = ctx.getSeparatedGeometryLines(lines);\n contents.push(...allLines.map((n) => ({ type: "geometry lines", lines: n })));\n },\n contentSelectable(content, contents) {\n return ctx.contentIsDeletable(content, contents);\n },\n selectCount: 2,\n icon\n };\n}\nexport {\n getCommand\n};\n','// dev/cad-editor/plugins/edit-container.plugin.tsx\nfunction getCommand(ctx) {\n function contentSelectable(c) {\n return !c.readonly && ctx.isContainerContent(c);\n }\n const React = ctx.React;\n const startIcon = /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 100 100" }, /* @__PURE__ */ React.createElement("polyline", { points: "42,73 42,74 41,75 41,77 41,78 40,79 39,81 39,82 38,83 37,84 36,85 35,86 34,86 32,87 31,88 30,88 28,88 27,89 26,89 24,89 23,88 21,88 20,88 19,87 17,86 16,86 15,85 14,84 13,83 12,82 12,81 11,79 10,78 10,77 10,75 9,74 9,73 9,71 10,70 10,68 10,67 11,66 12,64 12,63 13,62 14,61 15,60 16,59 17,59 19,58 20,57 21,57 23,57 24,56 25,56 27,56 28,57 30,57 31,57 32,58 34,59 35,59 36,60 37,61 38,62 39,63 39,64 40,66 41,67 41,68 41,70 42,71 42,73", strokeWidth: "5", strokeDasharray: "10", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polygon", { points: "12,10 76,10 76,45 12,45", strokeWidth: "5", strokeDasharray: "10", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polygon", { points: "70,93 93,52 46,52", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }));\n const startCommand = {\n name: "start edit container",\n icon: startIcon,\n execute({ contents, selected, setEditingContentPath }) {\n contents.forEach((content, index) => {\n var _a, _b;\n if (content && ctx.isSelected([index], selected) && ((_b = (_a = this.contentSelectable) == null ? void 0 : _a.call(this, content, contents)) != null ? _b : true)) {\n setEditingContentPath(contentSelectable(content) ? [index, "contents"] : void 0);\n }\n });\n },\n contentSelectable,\n selectCount: 1\n };\n const cancelIcon = /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 100 100" }, /* @__PURE__ */ React.createElement("polygon", { points: "37,82 32,77 45,64 34,52 22,65 16,58 4,90", strokeWidth: "0", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "currentColor", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polygon", { points: "83,40 78,34 65,46 53,35 67,24 61,17 94,8", strokeWidth: "0", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "currentColor", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polygon", { points: "60,82 66,78 53,64 64,53 76,66 83,60 93,93", strokeWidth: "0", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "currentColor", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polygon", { points: "17,38 22,32 35,45 46,34 34,23 40,16 7,5", strokeWidth: "0", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "currentColor", stroke: "currentColor" }));\n const cancelCommand = {\n name: "cancel edit container",\n execute({ setEditingContentPath }) {\n setEditingContentPath(void 0);\n },\n selectCount: 0,\n icon: cancelIcon\n };\n return [startCommand, cancelCommand];\n}\nexport {\n getCommand\n};\n','// dev/cad-editor/plugins/ellipse.plugin.tsx\nfunction getModel(ctx) {\n const EllipseContent = ctx.and(ctx.BaseContent("ellipse"), ctx.StrokeFields, ctx.FillFields, ctx.AngleDeltaFields, ctx.Ellipse);\n const EllipseArcContent = ctx.and(ctx.BaseContent("ellipse arc"), ctx.StrokeFields, ctx.FillFields, ctx.AngleDeltaFields, ctx.EllipseArc);\n const getRefIds = (content) => ctx.getStrokeAndFillRefIds(content);\n const ellipseGeometriesCache = new ctx.WeakmapValuesCache();\n const ellipseArcGeometriesCache = new ctx.WeakmapValuesCache();\n function getEllipseGeometries(content, contents) {\n const refs = new Set(ctx.iterateRefContents(getRefIds(content), contents, [content]));\n return ellipseGeometriesCache.get(content, refs, () => {\n var _a;\n const points = ctx.ellipseToPolygon(content, (_a = content.angleDelta) != null ? _a : ctx.defaultAngleDelta);\n const lines = Array.from(ctx.iteratePolygonLines(points));\n const polylinePoints = ctx.polygonToPolyline(points);\n const center = ctx.getEllipseCenter(content);\n const left = ctx.rotatePositionByEllipseCenter({ x: content.cx - content.rx, y: content.cy }, content);\n const right = ctx.rotatePositionByEllipseCenter({ x: content.cx + content.rx, y: content.cy }, content);\n const top = ctx.rotatePositionByEllipseCenter({ x: content.cx, y: content.cy - content.ry }, content);\n const bottom = ctx.rotatePositionByEllipseCenter({ x: content.cx, y: content.cy + content.ry }, content);\n const focus = ctx.getEllipseFocus(content);\n return {\n lines: [{\n type: "ellipse arc",\n curve: ctx.ellipseToEllipseArc(content)\n }],\n points,\n center,\n left,\n right,\n top,\n bottom,\n focus,\n bounding: ctx.getEllipseBounding(content),\n renderingLines: ctx.dashedPolylineToLines(polylinePoints, content.dashArray),\n regions: ctx.hasFill(content) ? [\n {\n lines,\n points\n }\n ] : void 0\n };\n });\n }\n function getEllipseArcGeometries(content, contents) {\n const refs = new Set(ctx.iterateRefContents(getRefIds(content), contents, [content]));\n return ellipseArcGeometriesCache.get(content, refs, () => {\n var _a;\n const points = ctx.ellipseArcToPolyline(content, (_a = content.angleDelta) != null ? _a : ctx.defaultAngleDelta);\n const lines = Array.from(ctx.iteratePolylineLines(points));\n const center = ctx.getEllipseCenter(content);\n const focus = ctx.getEllipseFocus(content);\n const startRadian = ctx.angleToRadian(content.startAngle);\n const endRadian = ctx.angleToRadian(content.endAngle);\n const middleRadian = (startRadian + endRadian) / 2;\n return {\n lines: [{\n type: "ellipse arc",\n curve: content\n }],\n points,\n center,\n focus,\n start: ctx.getEllipsePointAtRadian(content, startRadian),\n end: ctx.getEllipsePointAtRadian(content, endRadian),\n middle: ctx.getEllipsePointAtRadian(content, middleRadian),\n bounding: ctx.getEllipseArcBounding(content),\n renderingLines: ctx.dashedPolylineToLines(points, content.dashArray),\n regions: ctx.hasFill(content) ? [\n {\n lines,\n points\n }\n ] : void 0\n };\n });\n }\n const React = ctx.React;\n const ellipseModel = {\n type: "ellipse",\n ...ctx.strokeModel,\n ...ctx.fillModel,\n ...ctx.angleDeltaModel,\n move(content, offset) {\n ctx.moveEllipse(content, offset);\n },\n rotate(content, center, angle) {\n ctx.rotateEllipse(content, center, angle);\n },\n scale(content, center, sx, sy) {\n ctx.scaleEllipse(content, center, sx, sy);\n },\n skew(content, center, sx, sy) {\n ctx.skewEllipse(content, center, sx, sy);\n },\n mirror(content, line, angle) {\n ctx.mirrorEllipse(content, line, angle);\n },\n offset(content, point, distance, contents) {\n if (!distance) {\n distance = Math.min(...getEllipseGeometries(content, contents).lines.map((line) => ctx.getPointAndGeometryLineMinimumDistance(point, line)));\n }\n return ctx.getParallelEllipsesByDistance(content, distance)[ctx.pointSideToIndex(ctx.getPointSideOfEllipse(point, content))];\n },\n break(content, points) {\n if (points.length < 2) {\n return;\n }\n const angles = points.map((p) => ctx.getEllipseAngle(p, content));\n angles.sort((a, b) => a - b);\n return angles.map((a, i) => ({\n ...content,\n type: "ellipse arc",\n startAngle: a,\n endAngle: i === angles.length - 1 ? angles[0] + 360 : angles[i + 1]\n }));\n },\n render(content, renderCtx) {\n const { options, target, dashed } = ctx.getStrokeFillRenderOptionsFromRenderContext(content, renderCtx);\n if (dashed) {\n const { points } = getEllipseGeometries(content, renderCtx.contents);\n return target.renderPolygon(points, options);\n }\n return target.renderEllipse(content.cx, content.cy, content.rx, content.ry, { ...options, angle: content.angle });\n },\n getOperatorRenderPosition(content) {\n return ctx.getEllipseCenter(content);\n },\n getEditPoints(content, contents) {\n return ctx.getEditPointsFromCache(content, () => {\n var _a;\n const { center, left, right, top, bottom } = getEllipseGeometries(content, contents);\n const rotate = -((_a = content.angle) != null ? _a : 0);\n return {\n editPoints: [\n {\n x: content.cx,\n y: content.cy,\n cursor: "move",\n type: "move",\n update(c, { cursor, start, scale }) {\n if (!isEllipseContent(c)) {\n return;\n }\n c.cx += cursor.x - start.x;\n c.cy += cursor.y - start.y;\n return { assistentContents: [{ type: "line", dashArray: [4 / scale], points: [center, cursor] }] };\n }\n },\n {\n x: left.x,\n y: left.y,\n cursor: ctx.getResizeCursor(-rotate, "left"),\n update(c, { cursor, scale }) {\n if (!isEllipseContent(c)) {\n return;\n }\n c.rx = ctx.getTwoPointsDistance(cursor, center);\n return { assistentContents: [{ type: "line", dashArray: [4 / scale], points: [center, cursor] }] };\n }\n },\n {\n x: right.x,\n y: right.y,\n cursor: ctx.getResizeCursor(-rotate, "right"),\n update(c, { cursor, scale }) {\n if (!isEllipseContent(c)) {\n return;\n }\n c.rx = ctx.getTwoPointsDistance(cursor, center);\n return { assistentContents: [{ type: "line", dashArray: [4 / scale], points: [center, cursor] }] };\n }\n },\n {\n x: top.x,\n y: top.y,\n cursor: ctx.getResizeCursor(-rotate, "top"),\n update(c, { cursor, scale }) {\n if (!isEllipseContent(c)) {\n return;\n }\n c.ry = ctx.getTwoPointsDistance(cursor, center);\n return { assistentContents: [{ type: "line", dashArray: [4 / scale], points: [center, cursor] }] };\n }\n },\n {\n x: bottom.x,\n y: bottom.y,\n cursor: ctx.getResizeCursor(-rotate, "bottom"),\n update(c, { cursor, scale }) {\n if (!isEllipseContent(c)) {\n return;\n }\n c.ry = ctx.getTwoPointsDistance(cursor, center);\n return { assistentContents: [{ type: "line", dashArray: [4 / scale], points: [center, cursor] }] };\n }\n }\n ],\n angleSnapStartPoint: ctx.getEllipseCenter(content)\n };\n });\n },\n getSnapPoints(content, contents) {\n const { center, left, right, top, bottom, focus } = getEllipseGeometries(content, contents);\n return ctx.getSnapPointsFromCache(content, () => [\n { ...center, type: "center" },\n { ...left, type: "endpoint" },\n { ...right, type: "endpoint" },\n { ...top, type: "endpoint" },\n { ...bottom, type: "endpoint" },\n ...focus.map((p) => ({ ...p, type: "center" }))\n ]);\n },\n getGeometries: getEllipseGeometries,\n propertyPanel(content, update, contents, { acquirePoint }) {\n return {\n from: /* @__PURE__ */ React.createElement(ctx.Button, { onClick: () => acquirePoint((p) => update((c) => {\n if (isEllipseContent(c)) {\n c.cx = p.x;\n c.cy = p.y;\n }\n })) }, "canvas"),\n cx: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.cx, setValue: (v) => update((c) => {\n if (isEllipseContent(c)) {\n c.cx = v;\n }\n }) }),\n cy: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.cy, setValue: (v) => update((c) => {\n if (isEllipseContent(c)) {\n c.cy = v;\n }\n }) }),\n rx: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.rx, setValue: (v) => update((c) => {\n if (isEllipseContent(c)) {\n c.rx = v;\n }\n }) }),\n ry: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.ry, setValue: (v) => update((c) => {\n if (isEllipseContent(c)) {\n c.ry = v;\n }\n }) }),\n angle: [\n /* @__PURE__ */ React.createElement(ctx.BooleanEditor, { value: content.angle !== void 0, setValue: (v) => update((c) => {\n if (isEllipseContent(c)) {\n c.angle = v ? 0 : void 0;\n }\n }) }),\n content.angle !== void 0 ? /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.angle, setValue: (v) => update((c) => {\n if (isEllipseContent(c)) {\n c.angle = v;\n }\n }) }) : void 0\n ],\n ...ctx.getStrokeContentPropertyPanel(content, update, contents),\n ...ctx.getFillContentPropertyPanel(content, update, contents),\n ...ctx.getAngleDeltaContentPropertyPanel(content, update)\n };\n },\n isValid: (c, p) => ctx.validate(c, EllipseContent, p),\n getRefIds,\n updateRefId: ctx.updateStrokeAndFillRefIds,\n deleteRefId: ctx.deleteStrokeAndFillRefIds,\n isPointIn: (content, point, contents) => ctx.pointInPolygon(point, getEllipseGeometries(content, contents).points),\n getArea: (content) => Math.PI * content.rx * content.ry\n };\n return [\n ellipseModel,\n {\n type: "ellipse arc",\n ...ctx.strokeModel,\n ...ctx.fillModel,\n ...ctx.angleDeltaModel,\n move: ellipseModel.move,\n rotate: ellipseModel.rotate,\n scale(content, center, sx, sy) {\n ctx.scaleEllipseArc(content, center, sx, sy);\n },\n skew(content, center, sx, sy) {\n ctx.skewEllipseArc(content, center, sx, sy);\n },\n mirror(content, line, angle) {\n ctx.mirrorEllipseArc(content, line, angle);\n },\n break(content, points) {\n if (points.length === 0) {\n return;\n }\n const angles = points.map((p) => ctx.normalizeAngleInRange(ctx.getEllipseAngle(p, content), content));\n angles.sort((a, b) => a - b);\n const result = [];\n if (!ctx.isSameNumber(angles[0], content.startAngle)) {\n result.push({\n ...content,\n type: "ellipse arc",\n startAngle: content.startAngle,\n endAngle: angles[0]\n });\n }\n angles.forEach((a, i) => {\n if (i === angles.length - 1) {\n if (!ctx.isSameNumber(a, content.endAngle)) {\n result.push({\n ...content,\n type: "ellipse arc",\n startAngle: a,\n endAngle: content.endAngle\n });\n }\n } else {\n result.push({\n ...content,\n type: "ellipse arc",\n startAngle: a,\n endAngle: angles[i + 1]\n });\n }\n });\n return result.length > 1 ? result : void 0;\n },\n offset(content, point, distance, contents) {\n if (!distance) {\n distance = Math.min(...getEllipseArcGeometries(content, contents).lines.map((line) => ctx.getPointAndGeometryLineMinimumDistance(point, line)));\n }\n return ctx.getParallelEllipseArcsByDistance(content, distance)[ctx.pointSideToIndex(ctx.getPointSideOfEllipseArc(point, content))];\n },\n join(content, target) {\n if (isEllipseArcContent(target)) {\n return ctx.mergeEllipseArc(content, target);\n }\n return;\n },\n extend(content, point) {\n const angle = ctx.getEllipseAngle(point, content);\n const endAngle = ctx.getFormattedEndAngle({ startAngle: content.startAngle, endAngle: angle });\n const startAngle = ctx.getFormattedStartAngle({ startAngle: angle, endAngle: content.endAngle });\n const angle1 = Math.abs(endAngle - content.startAngle);\n const angle2 = Math.abs(content.endAngle - startAngle);\n if (angle1 < angle2) {\n content.endAngle = endAngle;\n } else {\n content.startAngle = startAngle;\n }\n },\n render(content, renderCtx) {\n const { options, target } = ctx.getStrokeFillRenderOptionsFromRenderContext(content, renderCtx);\n const { points } = getEllipseArcGeometries(content, renderCtx.contents);\n return target.renderPolyline(points, options);\n },\n renderIfSelected(content, { color, target, strokeWidth, contents }) {\n const { points } = getEllipseArcGeometries({ ...content, startAngle: content.endAngle, endAngle: content.startAngle }, contents);\n return target.renderPolyline(points, { strokeColor: color, dashArray: [4], strokeWidth });\n },\n getOperatorRenderPosition(content, contents) {\n const { points } = getEllipseArcGeometries(content, contents);\n return points[0];\n },\n getEditPoints(content, contents) {\n return ctx.getEditPointsFromCache(content, () => {\n var _a;\n const { center, start, end } = getEllipseArcGeometries(content, contents);\n const rotate = -((_a = content.angle) != null ? _a : 0);\n return {\n editPoints: [\n {\n x: content.cx,\n y: content.cy,\n cursor: "move",\n update(c, { cursor, start: start2, scale }) {\n if (!isEllipseArcContent(c)) {\n return;\n }\n c.cx += cursor.x - start2.x;\n c.cy += cursor.y - start2.y;\n return { assistentContents: [{ type: "line", dashArray: [4 / scale], points: [center, cursor] }] };\n }\n },\n {\n ...start,\n cursor: ctx.getResizeCursor(content.startAngle - rotate, "top"),\n update(c, { cursor, scale }) {\n if (!isEllipseArcContent(c)) {\n return;\n }\n c.startAngle = ctx.getEllipseAngle(cursor, content);\n ctx.normalizeAngleRange(c);\n return { assistentContents: [{ type: "line", dashArray: [4 / scale], points: [center, cursor] }] };\n }\n },\n {\n ...end,\n cursor: ctx.getResizeCursor(content.endAngle - rotate, "top"),\n update(c, { cursor, scale }) {\n if (!isEllipseArcContent(c)) {\n return;\n }\n c.endAngle = ctx.getEllipseAngle(cursor, content);\n ctx.normalizeAngleRange(c);\n return { assistentContents: [{ type: "line", dashArray: [4 / scale], points: [center, cursor] }] };\n }\n }\n ],\n angleSnapStartPoint: center\n };\n });\n },\n getSnapPoints(content, contents) {\n return ctx.getSnapPointsFromCache(content, () => {\n const { center, start, end, middle, focus } = getEllipseArcGeometries(content, contents);\n return [\n { ...center, type: "center" },\n { ...start, type: "endpoint" },\n { ...end, type: "endpoint" },\n { ...middle, type: "midpoint" },\n ...focus.map((p) => ({ ...p, type: "center" }))\n ];\n });\n },\n getGeometries: getEllipseArcGeometries,\n propertyPanel(content, update, contents, { acquirePoint }) {\n return {\n from: /* @__PURE__ */ React.createElement(ctx.Button, { onClick: () => acquirePoint((p) => update((c) => {\n if (isEllipseArcContent(c)) {\n c.cx = p.x;\n c.cy = p.y;\n }\n })) }, "canvas"),\n cx: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.cx, setValue: (v) => update((c) => {\n if (isEllipseArcContent(c)) {\n c.cx = v;\n }\n }) }),\n cy: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.cy, setValue: (v) => update((c) => {\n if (isEllipseArcContent(c)) {\n c.cy = v;\n }\n }) }),\n rx: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.rx, setValue: (v) => update((c) => {\n if (isEllipseArcContent(c)) {\n c.rx = v;\n }\n }) }),\n ry: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.ry, setValue: (v) => update((c) => {\n if (isEllipseArcContent(c)) {\n c.ry = v;\n }\n }) }),\n angle: [\n /* @__PURE__ */ React.createElement(ctx.BooleanEditor, { value: content.angle !== void 0, setValue: (v) => update((c) => {\n if (isEllipseArcContent(c)) {\n c.angle = v ? 0 : void 0;\n }\n }) }),\n content.angle !== void 0 ? /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.angle, setValue: (v) => update((c) => {\n if (isEllipseArcContent(c)) {\n c.angle = v;\n }\n }) }) : void 0\n ],\n startAngle: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.startAngle, setValue: (v) => update((c) => {\n if (isEllipseArcContent(c)) {\n c.startAngle = v;\n }\n }) }),\n endAngle: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.endAngle, setValue: (v) => update((c) => {\n if (isEllipseArcContent(c)) {\n c.endAngle = v;\n }\n }) }),\n counterclockwise: /* @__PURE__ */ React.createElement(ctx.BooleanEditor, { value: content.counterclockwise === true, setValue: (v) => update((c) => {\n if (isEllipseArcContent(c)) {\n c.counterclockwise = v ? true : void 0;\n }\n }) }),\n ...ctx.getStrokeContentPropertyPanel(content, update, contents),\n ...ctx.getFillContentPropertyPanel(content, update, contents),\n ...ctx.getAngleDeltaContentPropertyPanel(content, update)\n };\n },\n isValid: (c, p) => ctx.validate(c, EllipseArcContent, p),\n getRefIds,\n updateRefId: ctx.updateStrokeAndFillRefIds,\n deleteRefId: ctx.deleteStrokeAndFillRefIds,\n getArea: (content) => {\n const radian = ctx.angleToRadian(content.endAngle - content.startAngle);\n return content.rx * content.ry * (radian - Math.sin(radian)) / 2;\n },\n reverse: (content) => ctx.reverseEllipseArc(content)\n }\n ];\n}\nfunction isEllipseContent(content) {\n return content.type === "ellipse";\n}\nfunction isEllipseArcContent(content) {\n return content.type === "ellipse arc";\n}\nfunction getCommand(ctx) {\n const React = ctx.React;\n const icon1 = /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 100 100" }, /* @__PURE__ */ React.createElement("ellipse", { cx: "50", cy: "50", rx: "42", ry: "25", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("circle", { cx: "50", cy: "50", r: "10", strokeWidth: "0", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "currentColor", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("circle", { cx: "92", cy: "50", r: "10", strokeWidth: "0", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "currentColor", stroke: "currentColor" }));\n const icon2 = /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 100 100" }, /* @__PURE__ */ React.createElement("ellipse", { cx: "50", cy: "50", rx: "42", ry: "25", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("circle", { cx: "8", cy: "50", r: "10", strokeWidth: "0", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "currentColor", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("circle", { cx: "92", cy: "50", r: "10", strokeWidth: "0", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "currentColor", stroke: "currentColor" }));\n const icon3 = /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 100 100" }, /* @__PURE__ */ React.createElement("polyline", { points: "7,71 8,69 8,66 9,64 10,61 12,58 14,55 16,52 18,49 21,46 23,43 27,40 30,38 33,35 37,32 40,30 44,28 48,25 51,23 55,22 59,20 62,19 66,18 69,17 72,16 76,16 78,16 81,16 84,17 86,17 88,18 89,19 91,21 92,22 92,24 93,26 93,29 92,31 92,34 91,36 90,39 88,42 86,45 84,48 82,51 79,54 77,57 73,60 70,62 67,65 63,68 60,70 56,72 52,75 49,77 45,78 41,80 38,81 34,82", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }));\n return [\n {\n name: "create ellipse",\n type: [\n { name: "ellipse center", hotkey: "EL", icon: icon1 },\n { name: "ellipse endpoint", icon: icon2 }\n ],\n useCommand({ onEnd, type, scale, strokeStyleId, fillStyleId }) {\n const { ellipse, onClick, onMove, input, startPosition, middlePosition, cursorPosition, reset } = ctx.useEllipseClickCreate(\n type === "ellipse center" || type === "ellipse endpoint" ? type : void 0,\n (c) => onEnd({\n updateContents: (contents) => contents.push({ ...c, strokeStyleId, fillStyleId, type: "ellipse" })\n })\n );\n const assistentContents = [];\n if (startPosition && cursorPosition) {\n if (middlePosition) {\n assistentContents.push({ type: "line", points: [startPosition, middlePosition], dashArray: [4 / scale] });\n if (type === "ellipse center") {\n assistentContents.push({ type: "line", points: [startPosition, cursorPosition], dashArray: [4 / scale] });\n } else if (ellipse) {\n assistentContents.push({ type: "line", points: [ctx.getEllipseCenter(ellipse), cursorPosition], dashArray: [4 / scale] });\n }\n } else {\n assistentContents.push({ type: "line", points: [startPosition, cursorPosition], dashArray: [4 / scale] });\n }\n }\n if (ellipse) {\n assistentContents.push({ ...ellipse, strokeStyleId, fillStyleId, type: "ellipse" });\n }\n return {\n onStart: onClick,\n input,\n onMove,\n assistentContents,\n lastPosition: middlePosition != null ? middlePosition : startPosition,\n reset\n };\n },\n selectCount: 0\n },\n {\n name: "create ellipse arc",\n useCommand({ onEnd, type, scale, strokeStyleId, fillStyleId }) {\n const { ellipse, ellipseArc, onClick, onMove, input, startPosition, middlePosition, cursorPosition, reset } = ctx.useEllipseArcClickCreate(\n type === "create ellipse arc" ? "ellipse center" : void 0,\n (c) => onEnd({\n updateContents: (contents) => contents.push({ ...c, strokeStyleId, fillStyleId, type: "ellipse arc" })\n })\n );\n const assistentContents = [];\n if (startPosition && cursorPosition) {\n if (middlePosition) {\n assistentContents.push({ type: "line", points: [startPosition, middlePosition], dashArray: [4 / scale] });\n const center = type === "create ellipse arc" ? startPosition : { x: (startPosition.x + middlePosition.x) / 2, y: (startPosition.y + middlePosition.y) / 2 };\n assistentContents.push({ type: "line", points: [center, cursorPosition], dashArray: [4 / scale] });\n } else {\n assistentContents.push({ type: "line", points: [startPosition, cursorPosition], dashArray: [4 / scale] });\n }\n }\n if (ellipseArc) {\n assistentContents.push({ ...ellipseArc, dashArray: [4 / scale], type: "ellipse" });\n if (ellipseArc.startAngle !== ellipseArc.endAngle) {\n assistentContents.push(\n {\n type: "line",\n points: [\n ctx.getEllipsePointAtRadian(ellipseArc, ctx.angleToRadian(ellipseArc.startAngle)),\n {\n x: ellipseArc.cx,\n y: ellipseArc.cy\n }\n ],\n dashArray: [4 / scale]\n },\n {\n type: "line",\n points: [\n {\n x: ellipseArc.cx,\n y: ellipseArc.cy\n },\n ctx.getEllipsePointAtRadian(ellipseArc, ctx.angleToRadian(ellipseArc.endAngle))\n ],\n dashArray: [4 / scale]\n }\n );\n }\n if (cursorPosition) {\n assistentContents.push({ type: "line", points: [ctx.getEllipseCenter(ellipseArc), cursorPosition], dashArray: [4 / scale] });\n }\n } else if (ellipse) {\n assistentContents.push({ ...ellipse, dashArray: [4 / scale], type: "ellipse" });\n if (cursorPosition) {\n assistentContents.push({ type: "line", points: [ctx.getEllipseCenter(ellipse), cursorPosition], dashArray: [4 / scale] });\n }\n }\n if (ellipseArc && ellipseArc.startAngle !== ellipseArc.endAngle) {\n assistentContents.push({ ...ellipseArc, strokeStyleId, fillStyleId, type: "ellipse arc" });\n }\n return {\n onStart: onClick,\n input,\n onMove,\n assistentContents,\n lastPosition: middlePosition != null ? middlePosition : startPosition,\n reset\n };\n },\n selectCount: 0,\n icon: icon3\n }\n ];\n}\nexport {\n getCommand,\n getModel,\n isEllipseArcContent,\n isEllipseContent\n};\n','// dev/cad-editor/plugins/coordinate-axis.plugin.tsx\nfunction isCoordinateAxisContent(content) {\n return content.type === "coordinate axis";\n}\n\n// dev/cad-editor/plugins/equation.plugin.tsx\nfunction getModel(ctx) {\n const EquationContent = ctx.and(ctx.BaseContent("equation"), ctx.StrokeFields, ctx.SegmentCountFields, {\n axisId: ctx.ContentRef,\n dependentVariable: ctx.or("x", "y"),\n expression: ctx.string\n });\n const getRefIds = (content) => [...ctx.getStrokeRefIds(content), ...ctx.toRefId(content.axisId, true)];\n const equationCache = new ctx.WeakmapValuesCache();\n function getGeometriesFromCache(content, contents) {\n const refs = new Set(ctx.iterateRefContents(getRefIds(content), contents, [content]));\n return equationCache.get(content, refs, () => {\n var _a;\n const axis = ctx.getReference(content.axisId, contents, isCoordinateAxisContent);\n if (axis) {\n if (content.expression) {\n try {\n const expression = ctx.parseExpression(ctx.tokenizeExpression(content.expression));\n const points = [];\n const segmentCount = (_a = content.segmentCount) != null ? _a : ctx.defaultSegmentCount;\n if (content.dependentVariable === "y") {\n const step = (axis.xMax - axis.xMin) / segmentCount;\n for (let x = axis.xMin; x <= axis.xMax; x += step) {\n const y = ctx.evaluateExpression(expression, {\n Math,\n x\n });\n if (typeof y === "number" && !isNaN(y)) {\n points.push({ x: x + axis.x, y: y * (axis.flipY ? -1 : 1) + axis.y });\n }\n }\n } else {\n const step = (axis.yMax - axis.yMin) / segmentCount;\n for (let y = axis.yMin; y <= axis.yMax; y += step) {\n const x = ctx.evaluateExpression(expression, {\n Math,\n y\n });\n if (typeof x === "number" && !isNaN(x)) {\n points.push({ x: x + axis.x, y: y * (axis.flipY ? -1 : 1) + axis.y });\n }\n }\n }\n const lines = Array.from(ctx.iteratePolylineLines(points));\n return {\n points,\n lines,\n bounding: ctx.getPointsBounding(points),\n renderingLines: ctx.dashedPolylineToLines(points, content.dashArray)\n };\n } catch (e) {\n console.info(e);\n }\n }\n return { lines: [], points: [], renderingLines: [] };\n }\n return { lines: [], points: [], renderingLines: [] };\n });\n }\n const React = ctx.React;\n return {\n type: "equation",\n ...ctx.strokeModel,\n ...ctx.segmentCountModel,\n render(content, renderCtx) {\n const { options, contents, target } = ctx.getStrokeRenderOptionsFromRenderContext(content, renderCtx);\n const { points } = getGeometriesFromCache(content, contents);\n return target.renderPolyline(points, options);\n },\n getGeometries: getGeometriesFromCache,\n propertyPanel(content, update, contents) {\n return {\n dependentVariable: /* @__PURE__ */ React.createElement(ctx.EnumEditor, { value: content.dependentVariable, enums: ["x", "y"], setValue: (v) => update((c) => {\n if (isEquationContent(c)) {\n c.dependentVariable = v;\n }\n }) }),\n expression: /* @__PURE__ */ React.createElement(ctx.ExpressionEditor, { suggestionSources: ctx.math, validate: ctx.validateExpression, value: content.expression, setValue: (v) => update((c) => {\n if (isEquationContent(c)) {\n c.expression = v;\n }\n }) }),\n ...ctx.getStrokeContentPropertyPanel(content, update, contents),\n ...ctx.getSegmentCountContentPropertyPanel(content, update)\n };\n },\n isValid: (c, p) => ctx.validate(c, EquationContent, p),\n getRefIds,\n updateRefId(content, update) {\n const newAxisId = update(content.axisId);\n if (newAxisId !== void 0) {\n content.axisId = newAxisId;\n }\n ctx.updateStrokeRefIds(content, update);\n },\n deleteRefId: ctx.deleteStrokeRefIds\n };\n}\nfunction isEquationContent(content) {\n return content.type === "equation";\n}\nfunction getCommand(ctx) {\n const React = ctx.React;\n const icon = /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 100 100" }, /* @__PURE__ */ React.createElement("polyline", { points: "7,93 88,93", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polyline", { points: "7,12 7,93", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polyline", { points: "97,93 68,101 68,85", strokeWidth: "0", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "currentColor", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polyline", { points: "7,3 15,32 1,32", strokeWidth: "0", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "currentColor", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polyline", { points: "7,93 8,85 9,81 10,78 11,76 12,74 12,72 13,71 14,69 15,68 16,66 17,65 18,64 19,62 20,61 21,60 21,59 22,58 23,57 24,56 25,55 26,54 27,53 28,52 29,51 29,51 30,50 31,49 32,48 33,47 34,47 35,46 36,45 37,44 38,44 38,43 39,42 40,41 41,41 42,40 43,39 44,39 45,38 46,37 47,37 47,36 48,35 49,35 50,34 51,34 52,33 53,32 54,32 55,31 56,31 56,30 57,30 58,29 59,28 60,28 61,27 62,27 63,26 64,26 65,25 65,25 66,24 67,24 68,23 69,23 70,22 71,22 72,21 73,21 74,20 74,20 75,19 76,19 77,18 78,18 79,17 80,17 81,16 82,16 83,15 84,15 84,14 85,14 86,13 87,13 88,13 89,12 90,12 91,11 92,11 93,10 93,10 94,9 95,9 96,9", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }));\n return {\n name: "create equation",\n icon,\n useCommand({ onEnd, type, selected }) {\n const [dependentVariable, setDependentVariable] = React.useState("y");\n const enabled = type === "create equation";\n let message = "";\n if (enabled) {\n message = dependentVariable === "x" ? "input f(y)" : "input f(x)";\n }\n const { input, setCursorPosition, clearText, setInputPosition, resetInput } = ctx.useCursorInput(message, enabled ? (e, text) => {\n if (e.key === "Enter") {\n onEnd({\n updateContents(contents) {\n contents.push({\n type: "equation",\n axisId: selected[0].path[0],\n dependentVariable,\n expression: text\n });\n }\n });\n clearText();\n }\n } : void 0);\n const reset = () => {\n resetInput();\n setDependentVariable("y");\n };\n return {\n input,\n onStart() {\n },\n onMove(p, viewportPosition) {\n setInputPosition(viewportPosition || p);\n setCursorPosition(p);\n },\n subcommand: enabled ? /* @__PURE__ */ React.createElement("span", null, /* @__PURE__ */ React.createElement("button", { onClick: () => setDependentVariable(dependentVariable === "x" ? "y" : "x"), style: { position: "relative" } }, "f(", dependentVariable, ")")) : void 0,\n reset\n };\n },\n contentSelectable: isCoordinateAxisContent,\n selectCount: 1\n };\n}\nexport {\n getCommand,\n getModel,\n isEquationContent\n};\n','// dev/cad-editor/plugins/explode.plugin.tsx\nfunction getCommand(ctx) {\n const React = ctx.React;\n const icon = /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 100 100" }, /* @__PURE__ */ React.createElement("polyline", { points: "17,11 83,11", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polyline", { points: "80,91 16,91", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polyline", { points: "9,84 9,19", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polyline", { points: "90,19 90,85", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }));\n return {\n name: "explode",\n execute({ contents, selected }) {\n const newContents = [];\n const indexes = [];\n contents.forEach((content, index) => {\n var _a, _b, _c, _d;\n if (content && ctx.isSelected([index], selected) && ((_b = (_a = this.contentSelectable) == null ? void 0 : _a.call(this, content, contents)) != null ? _b : true)) {\n const result = (_d = (_c = ctx.getContentModel(content)) == null ? void 0 : _c.explode) == null ? void 0 : _d.call(_c, content, contents);\n if (result) {\n newContents.push(...result);\n indexes.push(index);\n }\n }\n });\n ctx.deleteSelectedContents(contents, indexes);\n contents.push(...newContents);\n },\n contentSelectable(content, contents) {\n const model = ctx.getContentModel(content);\n return (model == null ? void 0 : model.explode) !== void 0 && ctx.contentIsDeletable(content, contents);\n },\n hotkey: "X",\n icon\n };\n}\nexport {\n getCommand\n};\n','// dev/cad-editor/plugins/export-code.plugin.tsx\nfunction getCommand(ctx) {\n const React = ctx.React;\n const icon = /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 100 100" }, /* @__PURE__ */ React.createElement("polyline", { points: "25,13 7,51 22,90", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polyline", { points: "75,13 93,51 78,90", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }));\n return {\n name: "export code",\n execute({ contents, selected, width, height, transform }) {\n const result = [];\n contents.forEach((content, index) => {\n if (content && ctx.isSelected([index], selected)) {\n const model = ctx.getContentModel(content);\n if (model == null ? void 0 : model.render) {\n const code = model.render(content, {\n target: ctx.codeRenderTarget,\n transformColor: (c) => c,\n transformStrokeWidth: (w) => w,\n getFillColor: (c) => c.fillColor,\n getStrokeColor: (c) => {\n var _a;\n return (_a = c.strokeColor) != null ? _a : ctx.hasFill(c) ? void 0 : ctx.defaultStrokeColor;\n },\n getFillPattern: (c) => c.fillPattern ? {\n width: c.fillPattern.width,\n height: c.fillPattern.height,\n pattern: () => {\n var _a, _b, _c, _d;\n return ctx.codeRenderTarget.renderPath((_b = (_a = c.fillPattern) == null ? void 0 : _a.lines) != null ? _b : [], {\n strokeColor: (_d = (_c = c.fillPattern) == null ? void 0 : _c.strokeColor) != null ? _d : ctx.defaultStrokeColor\n });\n }\n } : void 0,\n contents\n });\n result.push(code);\n }\n }\n });\n navigator.clipboard.writeText(ctx.codeRenderTarget.renderResult(result, width, height, {\n transform\n }));\n },\n icon\n };\n}\nexport {\n getCommand\n};\n','// dev/cad-editor/plugins/export-jsx.plugin.tsx\nfunction getCommand(ctx) {\n const React = ctx.React;\n const icon = /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 100 100" }, /* @__PURE__ */ React.createElement("polyline", { points: "25,13 7,51 22,90", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polyline", { points: "75,13 93,51 78,90", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polyline", { points: "64,15 51,90", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }));\n return {\n name: "export jsx",\n execute({ contents, selected }) {\n const result = [];\n contents.forEach((content, index) => {\n if (content && ctx.isSelected([index], selected)) {\n const model = ctx.getContentModel(content);\n if (model == null ? void 0 : model.render) {\n let color;\n if (ctx.isFillContent(content) && content.fillColor !== void 0) {\n color = content.fillColor;\n } else if (ctx.isStrokeContent(content)) {\n color = content.strokeColor;\n }\n color = color != null ? color : ctx.defaultStrokeColor;\n const svg = ctx.renderToStaticMarkup(model.render(content, {\n target: ctx.reactSvgRenderTarget,\n transformColor: (c) => c,\n transformStrokeWidth: (w) => w,\n getFillColor: (c) => c.fillColor,\n getStrokeColor: (c) => {\n var _a;\n return (_a = c.strokeColor) != null ? _a : ctx.hasFill(c) ? void 0 : ctx.defaultStrokeColor;\n },\n getFillPattern: (c) => c.fillPattern ? {\n width: c.fillPattern.width,\n height: c.fillPattern.height,\n pattern: () => {\n var _a, _b, _c, _d;\n return ctx.reactSvgRenderTarget.renderPath((_b = (_a = c.fillPattern) == null ? void 0 : _a.lines) != null ? _b : [], {\n strokeColor: (_d = (_c = c.fillPattern) == null ? void 0 : _c.strokeColor) != null ? _d : ctx.defaultStrokeColor\n });\n }\n } : void 0,\n contents\n })(index, 1, false, 100, 100));\n let jsx = "";\n for (let j = 0; j < svg.length; j++) {\n const c = svg[j];\n if (c === "-" && ctx.isLetter(svg[j + 1])) {\n jsx += svg[j + 1].toUpperCase();\n j++;\n } else {\n jsx += c;\n }\n }\n jsx = jsx.replaceAll(/[0-9]+\\.[0-9]+/g, (c) => Math.round(+c).toString());\n result.push(jsx.split(ctx.getColorString(color)).join("currentColor"));\n }\n }\n });\n navigator.clipboard.writeText(result.join("\\n"));\n },\n icon\n };\n}\nexport {\n getCommand\n};\n','// dev/cad-editor/plugins/export-png.plugin.tsx\nfunction getCommand(ctx) {\n const React = ctx.React;\n const icon = /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 100 100" }, /* @__PURE__ */ React.createElement("polyline", { points: "51,0 51,60", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", strokeOpacity: "1", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polyline", { points: "51,60 83,28", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", strokeOpacity: "1", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polyline", { points: "51,60 21,31", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", strokeOpacity: "1", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polyline", { points: "11,84 91,84", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", strokeOpacity: "1", fill: "none", stroke: "currentColor" }));\n return {\n name: "export png",\n execute({ state, selected }) {\n const draws = [];\n const targets = [];\n state.forEach((content, index) => {\n if (content && ctx.isSelected([index], selected)) {\n const model = ctx.getContentModel(content);\n if (model == null ? void 0 : model.render) {\n targets.push(content);\n draws.push(model.render(content, {\n target: ctx.reactCanvasRenderTarget,\n transformColor: (c) => c,\n transformStrokeWidth: (w) => w,\n getFillColor: (c) => c.fillColor,\n getStrokeColor: (c) => {\n var _a;\n return (_a = c.strokeColor) != null ? _a : ctx.hasFill(c) ? void 0 : ctx.defaultStrokeColor;\n },\n getFillPattern: (c) => c.fillPattern ? {\n width: c.fillPattern.width,\n height: c.fillPattern.height,\n pattern: () => {\n var _a, _b, _c, _d;\n return ctx.reactCanvasRenderTarget.renderPath((_b = (_a = c.fillPattern) == null ? void 0 : _a.lines) != null ? _b : [], {\n strokeColor: (_d = (_c = c.fillPattern) == null ? void 0 : _c.strokeColor) != null ? _d : ctx.defaultStrokeColor\n });\n }\n } : void 0,\n contents: state\n }));\n }\n }\n });\n const width = window.innerWidth, height = window.innerHeight;\n const transform = ctx.zoomContentsToFit(width, height, targets, state, 0.8);\n if (!transform) return;\n const container = document.createElement("div");\n ctx.createRoot(container).render(/* @__PURE__ */ React.createElement(ctx.CanvasDrawCanvas, { width, height, draws, transform, onRender: () => {\n const child = container.children.item(0);\n if (child && child instanceof HTMLCanvasElement) {\n child.toBlob((blob) => {\n if (blob) {\n navigator.clipboard.write([new ClipboardItem({ [blob.type]: blob })]);\n }\n });\n }\n } }));\n },\n icon\n };\n}\nexport {\n getCommand\n};\n','// dev/cad-editor/plugins/extend.plugin.tsx\nfunction getCommand(ctx) {\n const React = ctx.React;\n const icon = /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 100 100" }, /* @__PURE__ */ React.createElement("polyline", { points: "-0,0 101,0", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", strokeOpacity: "1", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polyline", { points: "56,-0 43,57", strokeWidth: "5", strokeDasharray: "10", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", strokeOpacity: "1", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polyline", { points: "43,57 35,100", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", strokeOpacity: "1", fill: "none", stroke: "currentColor" }));\n return {\n name: "extend",\n useCommand({ onEnd, selected, contents, backgroundColor, setSelected, contentVisible }) {\n var _a;\n const [hovering, setHovering] = React.useState();\n const [trimHovering, setTrimHovering] = React.useState();\n const [shift, setShift] = React.useState(false);\n const reset = () => {\n setHovering(void 0);\n setTrimHovering(void 0);\n };\n const assistentContents = [];\n if (hovering) {\n assistentContents.push(hovering.content);\n } else if (trimHovering) {\n if (ctx.isStrokeContent(trimHovering.content)) {\n assistentContents.push({\n ...trimHovering.content,\n strokeWidth: ((_a = trimHovering.content.strokeWidth) != null ? _a : ctx.getDefaultStrokeWidth(trimHovering.content)) + 2,\n strokeColor: backgroundColor,\n trueStrokeColor: true\n });\n }\n }\n return {\n onStart() {\n var _a2, _b, _c, _d, _e;\n if (hovering) {\n onEnd({\n updateContents(contents2) {\n var _a3, _b2;\n const content = ctx.getContentByIndex(contents2, hovering.path);\n if (content) {\n (_b2 = (_a3 = ctx.getContentModel(content)) == null ? void 0 : _a3.extend) == null ? void 0 : _b2.call(_a3, content, hovering.point, contents2);\n }\n }\n });\n } else if (trimHovering) {\n const content = ctx.getContentByIndex(contents, trimHovering.path);\n if (content) {\n const points = [];\n const lines = (_c = (_b = (_a2 = ctx.getContentModel(trimHovering.content)) == null ? void 0 : _a2.getGeometries) == null ? void 0 : _b.call(_a2, trimHovering.content, contents)) == null ? void 0 : _c.lines;\n if (lines) {\n const { start, end } = ctx.getGeometryLinesStartAndEnd(lines);\n if (start && end) {\n if (!ctx.isSamePoint(start, end)) {\n points.push(start, end);\n }\n } else if (start) {\n points.push(start);\n } else if (end) {\n points.push(end);\n }\n }\n if (points.length > 0) {\n const r = (_e = (_d = ctx.getContentModel(content)) == null ? void 0 : _d.break) == null ? void 0 : _e.call(_d, content, points, contents);\n if (r) {\n const index = ctx.getContentIndex(content, contents);\n const newContents = r.filter((c) => !ctx.deepEquals(trimHovering.content, c));\n onEnd({\n updateContents: (contents2) => {\n contents2[index] = void 0;\n contents2.push(...newContents);\n }\n });\n const newSelected = selected.map((s) => s.path);\n for (let i = 0; i < newContents.length; i++) {\n newSelected.push([contents.length + i]);\n }\n setSelected(...newSelected);\n }\n }\n }\n }\n reset();\n },\n onMove(p) {\n var _a2, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;\n for (const s of selected) {\n if (!contentVisible(s.content)) continue;\n const lines = (_c = (_b = (_a2 = ctx.getContentModel(s.content)) == null ? void 0 : _a2.getGeometries) == null ? void 0 : _b.call(_a2, s.content, contents)) == null ? void 0 : _c.lines;\n if (!lines) continue;\n if (!shift && ctx.isGeometryLinesClosed(lines)) continue;\n const lineIndex = lines.findIndex((line) => ctx.getPointAndGeometryLineMinimumDistance(p, line) < 5);\n if (lineIndex >= 0) {\n let direction;\n if (!shift) {\n if (lineIndex === 0) {\n if (lines.length === 1) {\n const { start, end } = ctx.getGeometryLineStartAndEnd(lines[0]);\n if (!start) {\n direction = "tail";\n } else if (!end) {\n direction = "head";\n } else {\n direction = ctx.getTwoPointsDistanceSquare(p, start) < ctx.getTwoPointsDistanceSquare(p, end) ? "head" : "tail";\n }\n } else {\n direction = "head";\n }\n } else if (lineIndex === lines.length - 1) {\n direction = "tail";\n }\n }\n let points = [];\n if (shift) {\n for (const c of selected) {\n if (c === s) continue;\n if (!contentVisible(c.content)) continue;\n const lines2 = (_f = (_e = (_d = ctx.getContentModel(c.content)) == null ? void 0 : _d.getGeometries) == null ? void 0 : _e.call(_d, c.content, contents)) == null ? void 0 : _f.lines;\n if (lines2) {\n for (let i = 0; i < lines.length; i++) {\n for (const line of lines2) {\n points.push(...ctx.getTwoGeometryLinesIntersectionPoint(lines[i], line));\n }\n }\n }\n }\n } else if (direction) {\n for (const c of selected) {\n if (c === s) continue;\n if (!contentVisible(c.content)) continue;\n const lines2 = (_i = (_h = (_g = ctx.getContentModel(c.content)) == null ? void 0 : _g.getGeometries) == null ? void 0 : _h.call(_g, c.content, contents)) == null ? void 0 : _i.lines;\n if (lines2) {\n for (const line of lines2) {\n points.push(...ctx.getTwoGeometryLinesIntersectionPoint(lines[lineIndex], line, [{ [direction]: true }, ctx.NOT_EXTENDED]));\n }\n }\n }\n }\n points = ctx.deduplicatePosition(points);\n if (shift) {\n let parts = [s.content];\n if (points.length > 0) {\n parts = ((_k = (_j = ctx.getContentModel(s.content)) == null ? void 0 : _j.break) == null ? void 0 : _k.call(_j, s.content, points, contents)) || [s.content];\n }\n const content = parts.length === 1 ? parts[0] : parts.find((f) => {\n var _a3, _b2, _c2;\n return (_c2 = (_b2 = (_a3 = ctx.getContentModel(f)) == null ? void 0 : _a3.getGeometries) == null ? void 0 : _b2.call(_a3, f, contents)) == null ? void 0 : _c2.lines.some((n) => ctx.getPointAndGeometryLineMinimumDistance(p, n) < 5);\n });\n if (content) {\n setTrimHovering({\n ...s,\n content\n });\n return;\n }\n } else if (points.length > 0 && direction) {\n const point = ctx.minimumBy(points, (n) => ctx.getTwoPointsDistanceSquare(n, p));\n setHovering({\n ...s,\n point,\n content: ctx.produce(s.content, (draft) => {\n var _a3, _b2;\n (_b2 = (_a3 = ctx.getContentModel(s.content)) == null ? void 0 : _a3.extend) == null ? void 0 : _b2.call(_a3, draft, point, contents);\n })\n });\n return;\n }\n }\n }\n setHovering(void 0);\n setTrimHovering(void 0);\n },\n onKeyDown(e) {\n setShift(e.shiftKey);\n },\n onKeyUp(e) {\n setShift(e.shiftKey);\n },\n reset,\n assistentContents,\n hovering: hovering ? [hovering.path] : trimHovering ? [trimHovering.path] : void 0\n };\n },\n contentSelectable(content, contents) {\n var _a, _b, _c, _d;\n return !content.readonly && !!((_d = (_c = (_b = (_a = ctx.getContentModel(content)) == null ? void 0 : _a.getGeometries) == null ? void 0 : _b.call(_a, content, contents)) == null ? void 0 : _c.lines) == null ? void 0 : _d.length);\n },\n icon,\n repeatedly: true\n };\n}\nexport {\n getCommand\n};\n','// dev/cad-editor/plugins/fill-style.plugin.tsx\nfunction getModel(ctx) {\n function getGeometriesFromCache(content) {\n return ctx.getGeometriesFromCache(content, /* @__PURE__ */ new Set(), () => {\n const points = [\n { x: content.x, y: content.y },\n { x: content.x + content.width, y: content.y },\n { x: content.x + content.width, y: content.y + content.height },\n { x: content.x, y: content.y + content.height }\n ];\n return {\n lines: [],\n bounding: ctx.getPointsBounding(points),\n regions: [\n {\n points,\n lines: Array.from(ctx.iteratePolygonLines(points))\n }\n ],\n renderingLines: []\n };\n });\n }\n const React = ctx.React;\n return {\n type: "fill style",\n ...ctx.fillModel,\n move(content, offset) {\n ctx.movePoint(content, offset);\n },\n scale(content, center, sx, sy) {\n ctx.scalePoint(content, center, sx, sy);\n },\n render(content, { target, getFillColor, transformColor, getFillPattern }) {\n const options = {\n strokeColor: content.isCurrent ? transformColor(16711680) : void 0,\n strokeWidth: content.isCurrent ? 1 : 0,\n fillColor: getFillColor(content),\n fillOpacity: content.fillOpacity,\n fillPattern: getFillPattern(content)\n };\n return target.renderRect(content.x, content.y, content.width, content.height, options);\n },\n getEditPoints(content) {\n return ctx.getEditPointsFromCache(content, () => {\n return {\n editPoints: [\n {\n ...content,\n cursor: "move",\n update(c, { cursor, start, scale }) {\n if (!ctx.isFillStyleContent(c)) {\n return;\n }\n c.x += cursor.x - start.x;\n c.y += cursor.y - start.y;\n return { assistentContents: [{ type: "line", dashArray: [4 / scale], points: [start, cursor] }] };\n }\n }\n ]\n };\n });\n },\n getGeometries: getGeometriesFromCache,\n propertyPanel(content, update, contents, { acquirePoint }) {\n return {\n isCurrent: /* @__PURE__ */ React.createElement(ctx.BooleanEditor, { value: content.isCurrent === true, setValue: (v) => update((c, draft) => {\n if (ctx.isFillStyleContent(c)) {\n const currentFillStyle = ctx.getFillStyles(contents).find((s) => s.content.isCurrent);\n if (currentFillStyle) {\n const c2 = draft[currentFillStyle.index];\n if (c2 && ctx.isFillStyleContent(c2)) {\n c2.isCurrent = void 0;\n }\n }\n c.isCurrent = v ? true : void 0;\n }\n }) }),\n from: /* @__PURE__ */ React.createElement(ctx.Button, { onClick: () => acquirePoint((p) => update((c) => {\n if (ctx.isFillStyleContent(c)) {\n c.x = p.x;\n c.y = p.y;\n }\n })) }, "canvas"),\n x: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.x, setValue: (v) => update((c) => {\n if (ctx.isFillStyleContent(c)) {\n c.x = v;\n }\n }) }),\n y: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.y, setValue: (v) => update((c) => {\n if (ctx.isFillStyleContent(c)) {\n c.y = v;\n }\n }) }),\n width: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.width, setValue: (v) => update((c) => {\n if (ctx.isFillStyleContent(c)) {\n c.width = v;\n }\n }) }),\n height: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.height, setValue: (v) => update((c) => {\n if (ctx.isFillStyleContent(c)) {\n c.height = v;\n }\n }) }),\n ...ctx.getFillContentPropertyPanel(content, update)\n };\n },\n isValid: (c, p) => ctx.validate(c, ctx.FillStyleContent, p)\n };\n}\nfunction getCommand(ctx) {\n const React = ctx.React;\n const icon = /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 100 100" }, /* @__PURE__ */ React.createElement("rect", { x: "5", y: "6", width: "89", height: "39", strokeWidth: "0", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "currentColor", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("pattern", { id: "fill-style", patternUnits: "userSpaceOnUse", width: "20", height: "20" }, /* @__PURE__ */ React.createElement("path", { d: "M 0 10 L 10 0 M 20 10 L 10 20", strokeWidth: "1", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor", fillRule: "evenodd" })), /* @__PURE__ */ React.createElement("rect", { x: "5", y: "55", width: "89", height: "39", strokeWidth: "0", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "url(#fill-style)", stroke: "currentColor" }));\n return {\n name: "create fill style",\n selectCount: 0,\n icon,\n useCommand({ onEnd, type, scale }) {\n const [result, setResult] = React.useState();\n const reset = () => {\n setResult(void 0);\n };\n return {\n onStart() {\n if (result) {\n onEnd({\n updateContents: (contents) => {\n if (result) {\n contents.push(result);\n }\n }\n });\n reset();\n }\n },\n onMove(p) {\n if (type) {\n setResult({\n type: "fill style",\n x: p.x,\n y: p.y,\n width: 100 / scale,\n height: 20 / scale,\n fillColor: 0\n });\n }\n },\n assistentContents: result ? [result] : void 0,\n reset\n };\n }\n };\n}\nexport {\n getCommand,\n getModel\n};\n','// dev/cad-editor/plugins/circle-arc.plugin.tsx\nfunction isCircleContent(content) {\n return content.type === "circle";\n}\nfunction isArcContent(content) {\n return content.type === "arc";\n}\n\n// dev/cad-editor/plugins/line-polyline.plugin.tsx\nfunction isLineContent(content) {\n return content.type === "line";\n}\n\n// dev/cad-editor/plugins/fillet.plugin.tsx\nfunction getCommand(ctx) {\n function getFillets(content1, content2, radius) {\n const result = [];\n if (!contentSelectable(content1) || !contentSelectable(content2)) {\n return result;\n }\n const circles = [];\n if (isLineContent(content1)) {\n const line1 = ctx.twoPointLineToGeneralFormLine(content1.points[0], content1.points[1]);\n if (!line1) return [];\n if (isLineContent(content2)) {\n const line2 = ctx.twoPointLineToGeneralFormLine(content2.points[0], content2.points[1]);\n if (!line2) return [];\n circles.push(...ctx.getCirclesTangentTo2Lines(line1, line2, radius).map((c) => ({\n center: c,\n foot1: ctx.getPerpendicularPoint(c, line1),\n foot2: ctx.getPerpendicularPoint(c, line2)\n })));\n } else if (isCircleContent(content2) || isArcContent(content2)) {\n circles.push(...ctx.getCirclesTangentToLineAndCircle(line1, content2, radius).map((c) => ({\n center: c,\n foot1: ctx.getPerpendicularPoint(c, line1),\n foot2: ctx.getTwoCircleIntersectionPoints({ ...c, r: radius }, content2)[0]\n })));\n }\n } else if (isCircleContent(content1) || isArcContent(content1)) {\n if (isCircleContent(content2) || isArcContent(content2)) {\n circles.push(...ctx.getCirclesTangentTo2Circles(content1, content2, radius).map((c) => ({\n center: c,\n foot1: ctx.getTwoCircleIntersectionPoints({ ...c, r: radius }, content1)[0],\n foot2: ctx.getTwoCircleIntersectionPoints({ ...c, r: radius }, content2)[0]\n })));\n } else if (isLineContent(content2)) {\n const line2 = ctx.twoPointLineToGeneralFormLine(content2.points[0], content2.points[1]);\n if (!line2) return [];\n circles.push(...ctx.getCirclesTangentToLineAndCircle(line2, content1, radius).map((c) => ({\n center: c,\n foot1: ctx.getPerpendicularPoint(c, line2),\n foot2: ctx.getTwoCircleIntersectionPoints({ ...c, r: radius }, content1)[0]\n })));\n }\n }\n return circles.map(({ foot1, foot2, center: c }) => {\n const angle1 = ctx.radianToAngle(ctx.getTwoPointsRadian(foot1, c));\n const angle2 = ctx.radianToAngle(ctx.getTwoPointsRadian(foot2, c));\n const min = Math.min(angle1, angle2);\n const max = Math.max(angle1, angle2);\n if (max - min < 180) {\n return { ...c, r: radius, startAngle: min, endAngle: max };\n }\n return { ...c, r: radius, startAngle: max, endAngle: min + 360 };\n });\n }\n const React = ctx.React;\n const icon = /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 100 100" }, /* @__PURE__ */ React.createElement("polyline", { points: "9,10 92,10", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polyline", { points: "92,10 92,93", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("path", { d: "M 92 60 A 50 50 0 0 0 42 10", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }));\n return {\n name: "fillet",\n useCommand({ onEnd, type, selected, scale }) {\n const [candidates, setCandidates] = React.useState([]);\n const [result, setResult] = React.useState();\n let message = "";\n if (type) {\n if (candidates.length > 0) {\n message = "select one result";\n } else {\n message = "input radius";\n }\n }\n const assistentContents = candidates.map((c) => ({\n ...c,\n type: "arc",\n dashArray: c === result ? void 0 : [4 / scale]\n }));\n const { input, setInputPosition, setCursorPosition, clearText, resetInput } = ctx.useCursorInput(message, type && candidates.length == 0 ? (e, text) => {\n if (e.key === "Enter") {\n const radius = +text;\n if (!isNaN(radius)) {\n setCandidates(getFillets(selected[0].content, selected[1].content, radius));\n clearText();\n }\n }\n } : void 0);\n const reset = () => {\n setCandidates([]);\n setResult(void 0);\n clearText();\n resetInput();\n };\n return {\n onStart(p) {\n setCursorPosition(p);\n if (result) {\n onEnd({\n updateContents: (contents) => {\n contents.push({ type: "arc", ...result });\n }\n });\n setCandidates([]);\n }\n },\n input,\n onMove(p, viewportPosition) {\n setCursorPosition(p);\n setInputPosition(viewportPosition || p);\n setResult(candidates.find((c) => ctx.getTwoNumbersDistance(ctx.getTwoPointsDistance(c, p), c.r) < 5));\n },\n assistentContents,\n reset\n };\n },\n selectCount: 2,\n contentSelectable,\n selectType: "select part",\n hotkey: "F",\n icon\n };\n}\nfunction contentSelectable(content) {\n return isLineContent(content) || isCircleContent(content) || isArcContent(content);\n}\nexport {\n getCommand\n};\n','// dev/cad-editor/plugins/geometry-lines.plugin.tsx\nfunction getModel(ctx) {\n const GeometryLinesContent = ctx.and(ctx.BaseContent("geometry lines"), ctx.StrokeFields, ctx.FillFields, {\n lines: [ctx.GeometryLine]\n });\n const refGeometriesCache = new ctx.WeakmapValuesCache();\n function getGeometryLinesGeometries(content) {\n return refGeometriesCache.get(content, [], () => {\n const points = ctx.getGeometryLinesPoints(content.lines);\n const rays = [];\n const endPoints = [];\n for (const line of content.lines) {\n if (!Array.isArray(line) && line.type === "ray") {\n rays.push(line.line);\n }\n const { start, end } = ctx.getGeometryLineStartAndEnd(line);\n if (start && endPoints.every((p) => !ctx.isSamePoint(p, start))) {\n endPoints.push(start);\n }\n if (end && endPoints.every((p) => !ctx.isSamePoint(p, end))) {\n endPoints.push(end);\n }\n }\n const geometries = {\n lines: content.lines,\n points,\n endPoints,\n rays,\n bounding: ctx.getGeometryLinesBounding(content.lines),\n renderingLines: rays.length > 0 ? [] : ctx.dashedPolylineToLines(points, content.dashArray),\n region: rays.length > 0 ? [] : void 0\n };\n if (ctx.hasFill(content)) {\n return {\n ...geometries,\n lines: [],\n regions: [{\n lines: geometries.lines,\n points\n }],\n renderingLines: []\n };\n }\n return geometries;\n });\n }\n return {\n type: "geometry lines",\n ...ctx.strokeModel,\n ...ctx.fillModel,\n move(content, offset) {\n for (const line of content.lines) {\n ctx.moveGeometryLine(line, offset);\n }\n },\n rotate(content, center, angle) {\n for (const line of content.lines) {\n ctx.rotateGeometryLine(line, center, angle);\n }\n },\n scale(content, center, sx, sy) {\n ctx.scaleGeometryLines(content.lines, center, sx, sy);\n },\n skew(content, center, sx, sy) {\n ctx.skewGeometryLines(content.lines, center, sx, sy);\n },\n explode(content) {\n return content.lines.map((line) => ctx.geometryLineToContent(line));\n },\n break(content, intersectionPoints) {\n return ctx.breakGeometryLines(content.lines, intersectionPoints).map((lines) => ({ ...content, type: "geometry lines", lines }));\n },\n mirror(content, line, angle) {\n for (const n of content.lines) {\n ctx.mirrorGeometryLine(n, line, angle);\n }\n },\n offset(content, point, distance, _, lineJoin) {\n const newLines = ctx.trimGeometryLinesOffsetResult(ctx.getParallelGeometryLinesByDistancePoint(point, content.lines, distance, lineJoin), point);\n return newLines.map((n) => ctx.geometryLinesToPline(n));\n },\n join(content, target, contents) {\n var _a, _b, _c;\n const line2 = (_c = (_b = (_a = ctx.getContentModel(target)) == null ? void 0 : _a.getGeometries) == null ? void 0 : _b.call(_a, target, contents)) == null ? void 0 : _c.lines;\n if (!line2) return;\n const newLines = ctx.mergeGeometryLines(content.lines, line2);\n if (!newLines) return;\n return { ...content, lines: newLines };\n },\n extend(content, point) {\n ctx.extendGeometryLines(content.lines, point);\n },\n render(content, renderCtx) {\n const { options, target } = ctx.getStrokeFillRenderOptionsFromRenderContext(content, renderCtx);\n const { points, rays } = getGeometryLinesGeometries(content);\n return target.renderGroup([\n target.renderPath([points], options),\n ...rays.map((r) => target.renderRay(r.x, r.y, r.angle, { ...options, bidirectional: r.bidirectional }))\n ]);\n },\n getSnapPoints(content) {\n const { endPoints } = getGeometryLinesGeometries(content);\n return ctx.getSnapPointsFromCache(content, () => {\n return endPoints.map((p) => ({ ...p, type: "endpoint" }));\n });\n },\n getGeometries: getGeometryLinesGeometries,\n canSelectPart: true,\n propertyPanel(content, update, contents) {\n return {\n ...ctx.getStrokeContentPropertyPanel(content, update, contents),\n ...ctx.getFillContentPropertyPanel(content, update, contents)\n };\n },\n getRefIds: ctx.getStrokeAndFillRefIds,\n updateRefId: ctx.updateStrokeAndFillRefIds,\n isValid: (c, p) => ctx.validate(c, GeometryLinesContent, p),\n reverse(content) {\n const newLines = ctx.reverseGeometryLines(content.lines);\n return { ...content, lines: newLines };\n }\n };\n}\nfunction isGeometryLinesContent(content) {\n return content.type === "geometry lines";\n}\nfunction getCommand(ctx) {\n const React = ctx.React;\n return [\n {\n name: "create geometry lines",\n useCommand({ type, onEnd, width, height }) {\n const [json, setJson] = React.useState("");\n const reset = () => {\n setJson("");\n };\n return {\n reset,\n subcommand: type === "create geometry lines" ? /* @__PURE__ */ React.createElement("span", { style: { position: "relative" } }, /* @__PURE__ */ React.createElement(ctx.StringEditor, { textarea: true, value: json, style: { width: width * 0.7 + "px", height: height * 0.7 + "px" }, setValue: setJson }), /* @__PURE__ */ React.createElement(ctx.Button, { onClick: () => {\n if (json) {\n try {\n const lines = JSON.parse(json);\n const result = ctx.validate(lines, [ctx.GeometryLine]);\n if (result === true && lines.length > 0) {\n const allLines = ctx.getSeparatedGeometryLines(lines);\n onEnd({\n updateContents: (contents) => {\n contents.push(...allLines.map((n) => ({ type: "geometry lines", lines: n })));\n }\n });\n } else {\n console.info(result);\n }\n } catch (error) {\n console.info(error);\n }\n }\n } }, "OK")) : void 0\n };\n },\n selectCount: 0\n }\n ];\n}\nexport {\n getCommand,\n getModel,\n isGeometryLinesContent\n};\n','// dev/cad-editor/plugins/group.plugin.tsx\nfunction getModel(ctx) {\n const GroupContent = ctx.and(ctx.BaseContent("group"), ctx.ContainerFields, ctx.ClipFields);\n const getRefIds = (content) => ctx.toRefIds(content.contents);\n return {\n type: "group",\n ...ctx.containerModel,\n ...ctx.clipModel,\n move(content, offset) {\n var _a, _b;\n ctx.getContainerMove(content, offset);\n if (content.clip) {\n (_b = (_a = ctx.getContentModel(content.clip.border)) == null ? void 0 : _a.move) == null ? void 0 : _b.call(_a, content.clip.border, offset);\n }\n },\n rotate(content, center, angle, contents) {\n var _a, _b;\n ctx.getContainerRotate(content, center, angle, contents);\n if (content.clip) {\n (_b = (_a = ctx.getContentModel(content.clip.border)) == null ? void 0 : _a.rotate) == null ? void 0 : _b.call(_a, content.clip.border, center, angle, contents);\n }\n },\n scale(content, center, sx, sy, contents) {\n var _a, _b;\n ctx.getContainerScale(content, center, sx, sy, contents);\n if (content.clip) {\n return (_b = (_a = ctx.getContentModel(content.clip.border)) == null ? void 0 : _a.scale) == null ? void 0 : _b.call(_a, content.clip.border, center, sx, sy, contents);\n }\n },\n skew(content, center, sx, sy, contents) {\n var _a, _b;\n ctx.getContainerSkew(content, center, sx, sy, contents);\n if (content.clip) {\n return (_b = (_a = ctx.getContentModel(content.clip.border)) == null ? void 0 : _a.skew) == null ? void 0 : _b.call(_a, content.clip.border, center, sx, sy, contents);\n }\n },\n explode: ctx.getContainerExplode,\n mirror(content, line, angle, contents) {\n var _a, _b;\n ctx.getContainerMirror(content, line, angle, contents);\n if (content.clip) {\n (_b = (_a = ctx.getContentModel(content.clip.border)) == null ? void 0 : _a.mirror) == null ? void 0 : _b.call(_a, content.clip.border, line, angle, contents);\n }\n },\n getEditPoints(content, contents) {\n return ctx.getEditPointsFromCache(content, () => {\n return {\n editPoints: ctx.getClipContentEditPoints(content, contents)\n };\n });\n },\n render: (content, renderCtx) => {\n return ctx.renderClipContent(content, ctx.getContainerRender(content, renderCtx), renderCtx);\n },\n renderIfSelected(content, renderCtx) {\n const result = ctx.getContainerRenderIfSelected(content, renderCtx, [content], getRefIds);\n return ctx.renderClipContentIfSelected(content, result, renderCtx);\n },\n getSnapPoints: ctx.getContainerSnapPoints,\n getGeometries: (content, contents) => ctx.getContainerGeometries(content, contents, getRefIds, [content]),\n propertyPanel: (content, update, contents, { acquireContent }) => {\n return {\n ...ctx.getVariableValuesContentPropertyPanel(content, ctx.getContainerVariableNames(content), update),\n ...ctx.getClipContentPropertyPanel(content, contents, acquireContent, update)\n };\n },\n isValid: (c, p) => ctx.validate(c, GroupContent, p),\n getRefIds\n };\n}\nfunction getCommand(ctx) {\n function contentSelectable(content, contents) {\n return ctx.contentIsDeletable(content, contents);\n }\n const React = ctx.React;\n const icon = /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 100 100" }, /* @__PURE__ */ React.createElement("circle", { cx: "28", cy: "73", r: "22", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polygon", { points: "93,78 97,48 71,34 49,56 63,82", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("rect", { x: "7", y: "8", width: "50", height: "37", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }));\n return {\n name: "create group",\n execute({ contents, selected }) {\n const newContent = {\n type: "group",\n contents: contents.filter((c, i) => c && ctx.isSelected([i], selected) && contentSelectable(c, contents))\n };\n ctx.deleteSelectedContents(contents, selected.map((s) => s[0]));\n contents.push(newContent);\n },\n contentSelectable,\n hotkey: "G",\n icon\n };\n}\nexport {\n getCommand,\n getModel\n};\n','// dev/cad-editor/plugins/hatch.plugin.tsx\nfunction getModel(ctx) {\n const HatchContent = ctx.and(ctx.BaseContent("hatch"), ctx.FillFields, {\n border: [ctx.GeometryLine],\n holes: ctx.optional([[ctx.GeometryLine]]),\n ref: ctx.optional({\n point: ctx.Position,\n ids: [ctx.ContentRef]\n })\n });\n const getRefIds = (content) => {\n var _a;\n return [...ctx.getFillRefIds(content), ...ctx.toRefIds((_a = content.ref) == null ? void 0 : _a.ids)];\n };\n const refGeometriesCache = new ctx.WeakmapValuesCache();\n function getHatchGeometries(content, contents) {\n const refs = new Set(ctx.iterateRefContents(getRefIds(content), contents, [content]));\n return refGeometriesCache.get(content, refs, () => {\n let hatch = content;\n if (content.ref && content.ref.ids.length > 0) {\n const refContents = content.ref.ids.map((id) => ctx.getReference(id, contents)).filter((d) => !!d && !ctx.shallowEquals(d, content));\n if (refContents.length > 0) {\n const p = content.ref.point;\n const getGeometriesInRange = () => refContents.map((c) => ctx.getContentHatchGeometries(c, contents));\n const border = ctx.getHatchByPosition(p, getGeometriesInRange);\n if (border) {\n const holes = ctx.getHatchHoles(border.lines, getGeometriesInRange);\n hatch = {\n border: border.lines,\n holes: holes == null ? void 0 : holes.holes\n };\n }\n }\n }\n const points = ctx.getGeometryLinesPoints(hatch.border);\n const holesPoints = (hatch.holes || []).map((h) => ctx.getGeometryLinesPoints(h));\n return {\n lines: [],\n border: points,\n holes: holesPoints,\n bounding: ctx.getGeometryLinesBounding(hatch.border),\n renderingLines: [],\n regions: [\n {\n lines: hatch.border,\n points,\n holes: hatch.holes,\n holesPoints\n }\n ]\n };\n });\n }\n const React = ctx.React;\n return {\n type: "hatch",\n ...ctx.fillModel,\n move(content, offset) {\n if (content.ref) {\n ctx.movePoint(content.ref.point, offset);\n }\n for (const line of content.border) {\n ctx.moveGeometryLine(line, offset);\n }\n if (content.holes) {\n for (const hole of content.holes) {\n for (const line of hole) {\n ctx.moveGeometryLine(line, offset);\n }\n }\n }\n },\n rotate(content, center, angle) {\n if (content.ref) {\n ctx.rotatePoint(content.ref.point, center, angle);\n }\n for (const line of content.border) {\n ctx.rotateGeometryLine(line, center, angle);\n }\n if (content.holes) {\n for (const hole of content.holes) {\n for (const line of hole) {\n ctx.rotateGeometryLine(line, center, angle);\n }\n }\n }\n },\n scale(content, center, sx, sy) {\n if (content.ref) {\n ctx.scalePoint(content.ref.point, center, sx, sy);\n }\n ctx.scaleGeometryLines(content.border, center, sx, sy);\n if (content.holes) {\n for (const hole of content.holes) {\n ctx.scaleGeometryLines(hole, center, sx, sy);\n }\n }\n },\n skew(content, center, sx, sy) {\n if (content.ref) {\n ctx.skewPoint(content.ref.point, center, sx, sy);\n }\n ctx.skewGeometryLines(content.border, center, sx, sy);\n if (content.holes) {\n for (const hole of content.holes) {\n ctx.skewGeometryLines(hole, center, sx, sy);\n }\n }\n },\n mirror(content, line, angle) {\n if (content.ref) {\n ctx.mirrorPoint(content.ref.point, line);\n }\n for (const b of content.border) {\n ctx.mirrorGeometryLine(b, line, angle);\n }\n if (content.holes) {\n for (const hole of content.holes) {\n for (const h of hole) {\n ctx.mirrorGeometryLine(h, line, angle);\n }\n }\n }\n },\n join(content, target) {\n var _a;\n if (isHatchContent(target)) {\n const result = (_a = ctx.mergeHatches({ border: content.border, holes: content.holes || [] }, { border: target.border, holes: target.holes || [] })) == null ? void 0 : _a[0];\n if (result) {\n return {\n ...content,\n border: result.border,\n holes: result.holes,\n ref: void 0\n };\n }\n }\n return;\n },\n render(content, renderCtx) {\n const { options, target } = ctx.getFillRenderOptionsFromRenderContext(content, renderCtx);\n const { border, holes } = getHatchGeometries(content, renderCtx.contents);\n return target.renderPath([border, ...holes], options);\n },\n getGeometries: getHatchGeometries,\n getEditPoints(content) {\n return ctx.getEditPointsFromCache(content, () => {\n const editPoints = [];\n if (content.ref) {\n editPoints.push({\n x: content.ref.point.x,\n y: content.ref.point.y,\n cursor: "move",\n update(c, { cursor, start }) {\n if (!isHatchContent(c) || !c.ref) {\n return;\n }\n c.ref.point.x += cursor.x - start.x;\n c.ref.point.y += cursor.y - start.y;\n }\n });\n }\n return { editPoints };\n });\n },\n propertyPanel(content, update, contents) {\n return {\n ref: /* @__PURE__ */ React.createElement(ctx.BooleanEditor, { value: content.ref !== void 0, readOnly: content.ref === void 0, setValue: (v) => update((c) => {\n if (isHatchContent(c) && !v) {\n c.ref = void 0;\n }\n }) }),\n ...ctx.getFillContentPropertyPanel(content, update, contents)\n };\n },\n isValid: (c, p) => ctx.validate(c, HatchContent, p),\n getRefIds,\n updateRefId(content, update) {\n if (content.ref) {\n for (const [i, id] of content.ref.ids.entries()) {\n const newRefId = update(id);\n if (newRefId !== void 0) {\n content.ref.ids[i] = newRefId;\n }\n }\n }\n ctx.updateFillRefIds(content, update);\n },\n deleteRefId(content, ids) {\n if (content.ref) {\n for (const id of ids) {\n const index = content.ref.ids.indexOf(id);\n if (index >= 0) {\n content.ref.ids.splice(index, 1);\n }\n }\n }\n ctx.deleteFillRefIds(content, ids);\n }\n };\n}\nfunction isHatchContent(content) {\n return content.type === "hatch";\n}\nfunction getCommand(ctx) {\n const React = ctx.React;\n const icon = /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 100 100" }, /* @__PURE__ */ React.createElement("polyline", { points: "1,24 100,24", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", strokeOpacity: "1", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polyline", { points: "1,72 100,72", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", strokeOpacity: "1", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polyline", { points: "27,1 27,100", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", strokeOpacity: "1", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polyline", { points: "75,0 75,100", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", strokeOpacity: "1", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("pattern", { id: "hatch", patternUnits: "userSpaceOnUse", width: "10", height: "10" }, /* @__PURE__ */ React.createElement("path", { d: "M 0 5 L 5 0 M 10 5 L 5 10", strokeWidth: "1", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor", fillRule: "evenodd" })), /* @__PURE__ */ React.createElement("polygon", { points: "75,43 75,72 27,72 27,24 75,24 75,43", strokeWidth: "0", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fillOpacity: "1", fill: "url(#hatch)", stroke: "currentColor" }));\n return [\n {\n name: "create hatch",\n icon,\n useCommand({ onEnd, contents, getContentsInRange, width, height, x, y, rotate, scale }) {\n const [hatch, setHatch] = React.useState();\n const reset = () => {\n setHatch(void 0);\n };\n return {\n onStart: () => {\n onEnd({\n updateContents: (contents2) => {\n if (hatch) {\n contents2.push(hatch);\n }\n }\n });\n },\n onMove(p) {\n const lineSegment = ctx.getRayTransformedLineSegment({ x: p.x, y: p.y, angle: 0 }, width, height, { x, y, scale, rotate });\n if (!lineSegment) return;\n const getGeometriesInRange = (region) => getContentsInRange(region).map((c) => ctx.getContentHatchGeometries(c, contents));\n const border = ctx.getHatchByPosition(p, (line) => getGeometriesInRange(ctx.getGeometryLineBoundingFromCache(line)), lineSegment[1].x);\n if (border) {\n const holes = ctx.getHatchHoles(border.lines, getGeometriesInRange);\n setHatch({\n type: "hatch",\n border: border.lines,\n holes: holes == null ? void 0 : holes.holes,\n ref: {\n point: p,\n ids: [...border.ids, ...(holes == null ? void 0 : holes.ids) || []]\n }\n });\n } else {\n setHatch(void 0);\n }\n },\n assistentContents: hatch ? [hatch] : void 0,\n reset\n };\n },\n selectCount: 0\n }\n ];\n}\nexport {\n getCommand,\n getModel,\n isHatchContent\n};\n','// dev/cad-editor/plugins/hyperbola.plugin.tsx\nfunction getModel(ctx) {\n const HyperbolaContent = ctx.and(ctx.BaseContent("hyperbola"), ctx.StrokeFields, ctx.HyperbolaSegment, ctx.SegmentCountFields);\n const geometriesCache = new ctx.WeakmapValuesCache();\n function getHyperbolaGeometries(content, contents) {\n const refs = new Set(ctx.iterateRefContents(ctx.getStrokeRefIds(content), contents, [content]));\n return geometriesCache.get(content, refs, () => {\n var _a;\n const points = ctx.getHyperbolaPoints(content, (_a = content.segmentCount) != null ? _a : ctx.defaultSegmentCount);\n const lines = [{ type: "hyperbola curve", curve: content }];\n const c = Math.sqrt(content.a ** 2 + content.b ** 2);\n return {\n lines,\n c,\n angle: ctx.radianToAngle(Math.atan2(content.b, content.a)),\n start: ctx.getHyperbolaPointAtParam(content, content.t1),\n end: ctx.getHyperbolaPointAtParam(content, content.t2),\n startAngle: ctx.radianToAngle(ctx.getHyperbolaTangentRadianAtParam(content, content.t1)),\n endAngle: ctx.radianToAngle(ctx.getHyperbolaTangentRadianAtParam(content, content.t2)),\n origin: ctx.getPointByLengthAndRadian(content, -content.a, ctx.angleToRadian(content.angle)),\n focus: ctx.getPointByLengthAndRadian(content, c - content.a, ctx.angleToRadian(content.angle)),\n points,\n bounding: ctx.getGeometryLinesBounding(lines),\n renderingLines: ctx.dashedPolylineToLines(points, content.dashArray)\n };\n });\n }\n const React = ctx.React;\n return {\n type: "hyperbola",\n ...ctx.strokeModel,\n ...ctx.segmentCountModel,\n move(content, offset) {\n ctx.movePoint(content, offset);\n },\n rotate(content, center, angle) {\n ctx.rotateHyperbola(content, center, angle);\n },\n scale(content, center, sx, sy, contents) {\n const lines = getHyperbolaGeometries(content, contents).lines;\n ctx.scaleGeometryLines(lines, center, sx, sy);\n },\n skew(content, center, sx, sy, contents) {\n const lines = getHyperbolaGeometries(content, contents).lines;\n ctx.skewGeometryLines(lines, center, sx, sy);\n },\n mirror(content, line, angle) {\n ctx.mirrorHyperbola(content, line, angle);\n },\n break(content, intersectionPoints, contents) {\n const lines = getHyperbolaGeometries(content, contents).lines;\n return ctx.breakGeometryLines(lines, intersectionPoints).map((lines2) => ({ ...content, type: "geometry lines", lines: lines2 }));\n },\n offset(content, point, distance, contents) {\n if (!distance) {\n distance = Math.min(...getHyperbolaGeometries(content, contents).lines.map((line) => ctx.getPointAndGeometryLineMinimumDistance(point, line)));\n }\n return ctx.getParallelHyperbolaSegmentsByDistance(content, distance)[ctx.pointSideToIndex(ctx.getPointSideOfHyperbolaSegment(point, content))];\n },\n join(content, target, contents) {\n var _a, _b, _c;\n const line2 = (_c = (_b = (_a = ctx.getContentModel(target)) == null ? void 0 : _a.getGeometries) == null ? void 0 : _b.call(_a, target, contents)) == null ? void 0 : _c.lines;\n if (!line2) return;\n const lines = getHyperbolaGeometries(content, contents).lines;\n const newLines = ctx.mergeGeometryLines(lines, line2);\n if (!newLines) return;\n return { ...content, type: "geometry lines", lines: newLines };\n },\n extend(content, point) {\n const t = ctx.getHyperbolaParamAtPoint(content, point);\n if (ctx.isBefore(t, content.t1, content.t2)) {\n content.t1 = t;\n } else {\n content.t2 = t;\n }\n },\n render(content, renderCtx) {\n const { options, target } = ctx.getStrokeRenderOptionsFromRenderContext(content, renderCtx);\n const { points } = getHyperbolaGeometries(content, renderCtx.contents);\n return target.renderPolyline(points, options);\n },\n renderIfSelected(content, { color, target, strokeWidth, contents }) {\n const { origin, angle } = getHyperbolaGeometries(content, contents);\n return target.renderGroup([\n target.renderRay(content.x, content.y, content.angle, { strokeColor: color, dashArray: [4], strokeWidth }),\n target.renderRay(origin.x, origin.y, content.angle + angle, { strokeColor: color, dashArray: [4], strokeWidth }),\n target.renderRay(origin.x, origin.y, content.angle - angle, { strokeColor: color, dashArray: [4], strokeWidth })\n ]);\n },\n getEditPoints(content, contents) {\n return ctx.getEditPointsFromCache(content, () => {\n const { start, end, startAngle, endAngle, focus, origin } = getHyperbolaGeometries(content, contents);\n return {\n editPoints: [\n {\n x: content.x,\n y: content.y,\n cursor: "move",\n type: "move",\n update(c, { cursor, start: start2, scale }) {\n if (!isHyperbolaContent(c)) {\n return;\n }\n c.x += cursor.x - start2.x;\n c.y += cursor.y - start2.y;\n return { assistentContents: [{ type: "line", dashArray: [4 / scale], points: [content, cursor] }] };\n }\n },\n {\n x: start.x,\n y: start.y,\n cursor: ctx.getResizeCursor(startAngle, "left"),\n update(c, { cursor, start: start2, scale }) {\n if (!isHyperbolaContent(c)) {\n return;\n }\n c.t1 = ctx.minimumBy(ctx.getPerpendicularParamsToHyperbola(cursor, content), (t) => ctx.getTwoPointsDistanceSquare(cursor, ctx.getHyperbolaPointAtParam(content, t)));\n return { assistentContents: [{ type: "line", dashArray: [4 / scale], points: [start2, cursor] }] };\n }\n },\n {\n x: end.x,\n y: end.y,\n cursor: ctx.getResizeCursor(endAngle, "right"),\n update(c, { cursor, start: start2, scale }) {\n if (!isHyperbolaContent(c)) {\n return;\n }\n c.t2 = ctx.minimumBy(ctx.getPerpendicularParamsToHyperbola(cursor, content), (t) => ctx.getTwoPointsDistanceSquare(cursor, ctx.getHyperbolaPointAtParam(content, t)));\n return { assistentContents: [{ type: "line", dashArray: [4 / scale], points: [start2, cursor] }] };\n }\n },\n {\n x: focus.x,\n y: focus.y,\n cursor: "move",\n update(c, { cursor, scale }) {\n if (!isHyperbolaContent(c)) {\n return;\n }\n const d = ctx.getTwoPointsDistance(content, cursor);\n c.b = Math.sqrt((content.a + d) ** 2 - content.a ** 2);\n c.angle = ctx.radianToAngle(ctx.getTwoPointsRadian(cursor, content));\n return { assistentContents: [{ type: "line", dashArray: [4 / scale], points: [content, cursor] }] };\n }\n },\n {\n x: origin.x,\n y: origin.y,\n cursor: "move",\n update(c, { cursor, scale }) {\n if (!isHyperbolaContent(c)) {\n return;\n }\n c.a = ctx.getTwoPointsDistance(content, cursor);\n c.angle = ctx.radianToAngle(ctx.getTwoPointsRadian(content, cursor));\n return { assistentContents: [{ type: "line", dashArray: [4 / scale], points: [content, cursor] }] };\n }\n }\n ]\n };\n });\n },\n getSnapPoints(content, contents) {\n return ctx.getSnapPointsFromCache(content, () => {\n const { start, end, focus } = getHyperbolaGeometries(content, contents);\n return [\n { ...start, type: "endpoint" },\n { ...end, type: "endpoint" },\n { ...content, type: "center" },\n { ...focus, type: "center" }\n ];\n });\n },\n getGeometries: getHyperbolaGeometries,\n propertyPanel(content, update, contents, { acquirePoint }) {\n const { c } = getHyperbolaGeometries(content, contents);\n return {\n from: /* @__PURE__ */ React.createElement(ctx.Button, { onClick: () => acquirePoint((p) => update((c2) => {\n if (isHyperbolaContent(c2)) {\n c2.x = p.x;\n c2.y = p.y;\n }\n })) }, "canvas"),\n x: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.x, setValue: (v) => update((c2) => {\n if (isHyperbolaContent(c2)) {\n c2.x = v;\n }\n }) }),\n y: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.y, setValue: (v) => update((c2) => {\n if (isHyperbolaContent(c2)) {\n c2.y = v;\n }\n }) }),\n a: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.a, setValue: (v) => update((c2) => {\n if (isHyperbolaContent(c2) && v > 0) {\n c2.a = v;\n }\n }) }),\n b: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.b, setValue: (v) => update((c2) => {\n if (isHyperbolaContent(c2) && v > 0) {\n c2.b = v;\n }\n }) }),\n c: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: c }),\n t1: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.t1, setValue: (v) => update((c2) => {\n if (isHyperbolaContent(c2)) {\n c2.t1 = v;\n }\n }) }),\n t2: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.t2, setValue: (v) => update((c2) => {\n if (isHyperbolaContent(c2)) {\n c2.t2 = v;\n }\n }) }),\n angle: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.angle, setValue: (v) => update((c2) => {\n if (isHyperbolaContent(c2)) {\n c2.angle = v;\n }\n }) }),\n ...ctx.getStrokeContentPropertyPanel(content, update, contents),\n ...ctx.getSegmentCountContentPropertyPanel(content, update)\n };\n },\n isValid: (c, p) => ctx.validate(c, HyperbolaContent, p),\n getRefIds: ctx.getStrokeRefIds,\n updateRefId: ctx.updateStrokeRefIds,\n deleteRefId: ctx.deleteStrokeRefIds,\n reverse: ctx.reverseHyperbola\n };\n}\nfunction isHyperbolaContent(content) {\n return content.type === "hyperbola";\n}\nfunction getCommand(ctx) {\n const React = ctx.React;\n const icon = /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 100 100" }, /* @__PURE__ */ React.createElement("polyline", { points: "100,93 99,92 99,92 98,91 97,90 96,89 96,88 95,87 94,86 93,86 93,85 92,84 91,83 91,82 90,81 89,80 89,79 88,79 87,78 87,77 86,76 85,75 85,74 84,73 84,73 83,72 83,71 82,70 81,69 81,68 80,67 80,66 79,66 79,65 79,64 78,63 78,62 77,61 77,60 77,60 76,59 76,58 76,57 76,56 76,55 75,54 75,53 75,53 75,52 75,51 75,50 75,49 75,48 75,47 75,47 75,46 76,45 76,44 76,43 76,42 76,41 77,40 77,40 77,39 78,38 78,37 79,36 79,35 79,34 80,34 80,33 81,32 81,31 82,30 83,29 83,28 84,27 84,27 85,26 85,25 86,24 87,23 87,22 88,21 89,21 89,20 90,19 91,18 91,17 92,16 93,15 93,14 94,14 95,13 96,12 96,11 97,10 98,9 99,8 99,8 100,7", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", strokeOpacity: "1", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polyline", { points: "0,93 1,92 1,92 2,91 3,90 4,89 4,88 5,87 6,86 7,86 7,85 8,84 9,83 9,82 10,81 11,80 11,79 12,79 13,78 13,77 14,76 15,75 15,74 16,73 16,73 17,72 17,71 18,70 19,69 19,68 20,67 20,66 21,66 21,65 21,64 22,63 22,62 23,61 23,60 23,60 24,59 24,58 24,57 24,56 24,55 25,54 25,53 25,53 25,52 25,51 25,50 25,49 25,48 25,47 25,47 25,46 24,45 24,44 24,43 24,42 24,41 23,40 23,40 23,39 22,38 22,37 21,36 21,35 21,34 20,34 20,33 19,32 19,31 18,30 17,29 17,28 16,27 16,27 15,26 15,25 14,24 13,23 13,22 12,21 11,21 11,20 10,19 9,18 9,17 8,16 7,15 7,14 6,14 5,13 4,12 4,11 3,10 2,9 1,8 1,8 0,7", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", strokeOpacity: "1", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polyline", { points: "100,0 0,100", strokeWidth: "5", strokeDasharray: "10", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", strokeOpacity: "1", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polyline", { points: "0,0 100,100", strokeWidth: "5", strokeDasharray: "10", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", strokeOpacity: "1", fill: "none", stroke: "currentColor" }));\n return {\n name: "create hyperbola",\n icon,\n useCommand({ onEnd, type, strokeStyleId }) {\n const [content, setContent] = React.useState();\n const [status, setStatus] = React.useState("position");\n const reset = () => {\n setContent(void 0);\n setStatus("position");\n };\n const assistentContents = [];\n if (content) {\n assistentContents.push(content);\n }\n return {\n onStart() {\n if (type !== "create hyperbola") return;\n if (status === "position") {\n setStatus("angle");\n } else if (status === "angle") {\n setStatus("t1");\n } else if (status === "t1") {\n setStatus("t2");\n } else if (status === "t2") {\n onEnd({\n updateContents: (contents) => contents.push(content)\n });\n reset();\n }\n },\n onMove(p) {\n if (type !== "create hyperbola") return;\n if (!content) {\n setContent({\n type: "hyperbola",\n x: p.x,\n y: p.y,\n a: 100,\n b: 100,\n t1: -2,\n t2: 2,\n angle: -90,\n strokeStyleId\n });\n } else if (status === "position") {\n setContent({\n ...content,\n x: p.x,\n y: p.y\n });\n } else if (status === "angle") {\n setContent({\n ...content,\n angle: ctx.radianToAngle(ctx.getTwoPointsRadian(p, content))\n });\n } else if (status === "t1") {\n const x = ctx.getPerpendicularParamToLine2D(p, content, ctx.getParabolaXAxisRadian(content));\n const y = ctx.getPerpendicularParamToLine2D(p, content, ctx.angleToRadian(content.angle));\n const t = x / content.b;\n const a = y / (Math.sqrt(t ** 2 + 1) - 1);\n setContent({\n ...content,\n a,\n t1: t\n });\n } else if (status === "t2") {\n setContent({\n ...content,\n t2: ctx.minimumBy(ctx.getPerpendicularParamsToHyperbola(p, content), (t) => ctx.getTwoPointsDistanceSquare(p, ctx.getHyperbolaPointAtParam(content, t)))\n });\n }\n },\n assistentContents,\n reset\n };\n },\n selectCount: 0\n };\n}\nexport {\n getCommand,\n getModel,\n isHyperbolaContent\n};\n','// dev/cad-editor/plugins/image.plugin.tsx\nfunction getModel(ctx) {\n const ImageContent = ctx.and(ctx.BaseContent("image"), ctx.Image, ctx.ClipFields);\n function getImageGeometries(content) {\n return ctx.getGeometriesFromCache(content, /* @__PURE__ */ new Set(), () => {\n const points = [\n { x: content.x, y: content.y + content.height },\n { x: content.x + content.width, y: content.y + content.height },\n { x: content.x + content.width, y: content.y },\n { x: content.x, y: content.y }\n ];\n const lines = Array.from(ctx.iteratePolygonLines(points));\n return {\n lines: [],\n bounding: ctx.getPointsBounding(points),\n regions: [\n {\n lines,\n points\n }\n ],\n renderingLines: []\n };\n });\n }\n const React = ctx.React;\n return {\n type: "image",\n ...ctx.clipModel,\n move(content, offset) {\n var _a, _b;\n ctx.movePoint(content, offset);\n if (content.clip) {\n (_b = (_a = ctx.getContentModel(content.clip.border)) == null ? void 0 : _a.move) == null ? void 0 : _b.call(_a, content.clip.border, offset);\n }\n },\n scale(content, center, sx, sy, contents) {\n var _a, _b;\n ctx.scalePoint(content, center, sx, sy);\n content.width *= sx;\n content.height *= sy;\n if (content.clip) {\n return (_b = (_a = ctx.getContentModel(content.clip.border)) == null ? void 0 : _a.scale) == null ? void 0 : _b.call(_a, content.clip.border, center, sx, sy, contents);\n }\n },\n getEditPoints(content, contents) {\n return ctx.getEditPointsFromCache(content, () => {\n return {\n editPoints: [\n {\n x: content.x,\n y: content.y,\n cursor: "move",\n update(c, { cursor, start, scale }) {\n if (!isImageContent(c)) {\n return;\n }\n c.x += cursor.x - start.x;\n c.y += cursor.y - start.y;\n return { assistentContents: [{ type: "line", dashArray: [4 / scale], points: [content, cursor] }] };\n }\n },\n ...ctx.getClipContentEditPoints(content, contents)\n ]\n };\n });\n },\n render(content, renderCtx) {\n const { target, isHoveringOrSelected, transformStrokeWidth } = renderCtx;\n const strokeWidth = transformStrokeWidth(0);\n const fuzzy = isHoveringOrSelected && strokeWidth !== 0;\n let image = target.renderImage(content.url, content.x, content.y, content.width, content.height);\n image = ctx.renderClipContent(content, image, renderCtx);\n if (fuzzy) {\n return target.renderGroup([\n target.renderRect(content.x, content.y, content.width, content.height, {\n strokeWidth,\n ...ctx.fuzzyStyle\n }),\n image\n ]);\n }\n return image;\n },\n renderIfSelected(content, renderCtx) {\n const { color, target, strokeWidth } = renderCtx;\n const result = target.renderRect(content.x, content.y, content.width, content.height, { strokeColor: color, dashArray: [4], strokeWidth });\n return ctx.renderClipContentIfSelected(content, result, renderCtx);\n },\n getOperatorRenderPosition(content) {\n return content;\n },\n getGeometries: getImageGeometries,\n propertyPanel(content, update, contents, { acquirePoint, acquireContent }) {\n return {\n from: /* @__PURE__ */ React.createElement(ctx.Button, { onClick: () => acquirePoint((p) => update((c) => {\n if (isImageContent(c)) {\n c.x = p.x;\n c.y = p.y;\n }\n })) }, "canvas"),\n x: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.x, setValue: (v) => update((c) => {\n if (isImageContent(c)) {\n c.x = v;\n }\n }) }),\n y: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.y, setValue: (v) => update((c) => {\n if (isImageContent(c)) {\n c.y = v;\n }\n }) }),\n width: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.width, setValue: (v) => update((c) => {\n if (isImageContent(c)) {\n c.width = v;\n }\n }) }),\n height: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.height, setValue: (v) => update((c) => {\n if (isImageContent(c)) {\n c.height = v;\n }\n }) }),\n url: /* @__PURE__ */ React.createElement(ctx.StringEditor, { value: content.url, setValue: (v) => update((c) => {\n if (isImageContent(c)) {\n c.url = v;\n }\n }) }),\n ...ctx.getClipContentPropertyPanel(content, contents, acquireContent, update)\n };\n },\n editPanel(content, _scale, update, _contents, cancel) {\n const y = 100;\n return /* @__PURE__ */ React.createElement(\n ctx.ImageEditor,\n {\n style: {\n zIndex: 11\n },\n y,\n onCancel: cancel,\n src: content.url,\n width: window.innerWidth,\n height: window.innerHeight - y,\n onCpmplete: (url, width, height) => {\n update((c) => {\n if (isImageContent(c)) {\n c.url = url;\n c.width = width;\n c.height = height;\n cancel();\n }\n });\n }\n }\n );\n },\n isValid: (c, p) => ctx.validate(c, ImageContent, p)\n };\n}\nfunction isImageContent(content) {\n return content.type === "image";\n}\nfunction getCommand(ctx) {\n const React = ctx.React;\n const icon = /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 100 100" }, /* @__PURE__ */ React.createElement("polygon", { points: "100,100 100,50 66,67 28,11 0,36 0,100", strokeWidth: "0", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "currentColor", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("circle", { cx: "70", cy: "22", r: "13", strokeWidth: "0", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "currentColor", stroke: "currentColor" }));\n return {\n name: "create image",\n useCommand({ onEnd, type }) {\n const { image, onClick, onMove, input, reset } = ctx.useImageClickCreate(\n type === "create image",\n (c) => onEnd({\n updateContents: (contents) => contents.push({\n type: "image",\n ...c\n })\n })\n );\n const assistentContents = [];\n if (image) {\n assistentContents.push({\n type: "image",\n ...image\n });\n }\n return {\n onStart: onClick,\n input,\n onMove,\n assistentContents,\n reset\n };\n },\n selectCount: 0,\n hotkey: "I",\n icon\n };\n}\nexport {\n getCommand,\n getModel,\n isImageContent\n};\n','// dev/cad-editor/plugins/intersection.plugin.tsx\nfunction getCommand(ctx) {\n const React = ctx.React;\n const icon = /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 100 100" }, /* @__PURE__ */ React.createElement("circle", { cx: "32", cy: "50", r: "32", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fillOpacity: "1", strokeOpacity: "1", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("circle", { cx: "65", cy: "50", r: "32", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fillOpacity: "1", strokeOpacity: "1", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("pattern", { id: "intersection", patternUnits: "userSpaceOnUse", width: "10", height: "10" }, /* @__PURE__ */ React.createElement("path", { d: "M 0 5 L 5 0 M 10 5 L 5 10", strokeWidth: "1", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor", fillRule: "evenodd" })), /* @__PURE__ */ React.createElement("path", { d: "M 49 78 L 46 77 L 44 75 L 42 73 L 40 71 L 38 69 L 37 66 L 36 64 L 34 61 L 34 58 L 33 56 L 33 53 L 32 50 L 33 47 L 33 44 L 34 42 L 34 39 L 36 36 L 37 34 L 38 31 L 40 29 L 42 27 L 44 25 L 46 23 L 49 22 L 49 22 L 51 23 L 53 25 L 55 27 L 57 29 L 59 31 L 61 34 L 62 36 L 63 39 L 64 42 L 64 44 L 65 47 L 65 50 L 65 53 L 64 56 L 64 58 L 63 61 L 62 64 L 61 66 L 59 69 L 57 71 L 55 73 L 53 75 L 51 77 L 49 78", strokeWidth: "0", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fillOpacity: "1", fill: "url(#intersection)", stroke: "currentColor", fillRule: "evenodd" }));\n return {\n name: "intersection",\n execute({ contents, selected }) {\n var _a, _b, _c, _d;\n const first = contents[selected[0][0]];\n if (!first) return;\n const firstGeometries = (_b = (_a = ctx.getContentModel(first)) == null ? void 0 : _a.getGeometries) == null ? void 0 : _b.call(_a, first, contents);\n if (!firstGeometries) return;\n const second = contents[selected[1][0]];\n if (!second) return;\n const secondGeometries = (_d = (_c = ctx.getContentModel(second)) == null ? void 0 : _c.getGeometries) == null ? void 0 : _d.call(_c, second, contents);\n if (!secondGeometries) return;\n if (firstGeometries.regions && secondGeometries.regions) {\n const result = firstGeometries.regions.map((r) => ctx.getHatchesIntersection({ border: r.lines, holes: r.holes || [] }, (secondGeometries.regions || []).map((g) => ({ border: g.lines, holes: g.holes || [] })))).flat();\n ctx.deleteSelectedContents(contents, selected.map((s) => s[0]));\n contents.push(...result.map((r) => ({ ...first, type: "hatch", border: r.border, holes: r.holes, ref: void 0 })));\n return;\n }\n let points = ctx.deduplicatePosition(ctx.getIntersectionPoints(first, second, contents));\n const lines = Array.from(ctx.iterateGeometryLinesIntersectionLines(firstGeometries.lines, secondGeometries.lines));\n const newContents = [];\n if (lines.length > 0) {\n points = points.filter((p) => !ctx.pointIsOnGeometryLines(p, lines));\n const allLines = ctx.getSeparatedGeometryLines(lines);\n newContents.push(...allLines.map((n) => ({ type: "geometry lines", lines: n })));\n }\n newContents.push(...points.map((n) => ({ type: "point", x: n.x, y: n.y })));\n if (newContents.length > 0) {\n ctx.deleteSelectedContents(contents, selected.map((s) => s[0]));\n contents.push(...newContents);\n }\n },\n contentSelectable(content, contents) {\n return ctx.contentIsDeletable(content, contents);\n },\n selectCount: 2,\n icon\n };\n}\nexport {\n getCommand\n};\n','// dev/cad-editor/plugins/join.plugin.tsx\nfunction getCommand(ctx) {\n const React = ctx.React;\n const icon = /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 100 100" }, /* @__PURE__ */ React.createElement("polyline", { points: "0,49 100,49", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", strokeOpacity: "1", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polyline", { points: "51,49 76,32 76,64", strokeWidth: "0", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fillOpacity: "1", strokeOpacity: "1", fill: "currentColor", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polyline", { points: "54,49 27,32 28,65", strokeWidth: "0", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fillOpacity: "1", strokeOpacity: "1", fill: "currentColor", stroke: "currentColor" }));\n return {\n name: "join",\n execute({ contents, selected }) {\n const source = new Set(contents.filter((content, index) => {\n var _a, _b;\n return !!content && ctx.isSelected([index], selected) && ((_b = (_a = this.contentSelectable) == null ? void 0 : _a.call(this, content, contents)) != null ? _b : true);\n }));\n const newContents = ctx.mergeItems(Array.from(source), (item1, item2) => {\n var _a, _b;\n return (_b = (_a = ctx.getContentModel(item1)) == null ? void 0 : _a.join) == null ? void 0 : _b.call(_a, item1, item2, contents);\n });\n ctx.deleteSelectedContents(contents, selected.map((s) => s[0]));\n contents.push(...newContents);\n },\n contentSelectable(content, contents) {\n const model = ctx.getContentModel(content);\n return (model == null ? void 0 : model.join) !== void 0 && ctx.contentIsDeletable(content, contents);\n },\n icon\n };\n}\nexport {\n getCommand\n};\n','// dev/cad-editor/plugins/lead.plugin.tsx\nfunction getModel(ctx) {\n const LeadContent = ctx.and(ctx.BaseContent("lead"), ctx.StrokeFields, ctx.ArrowFields, ctx.TextFields, {\n ref: ctx.optional(ctx.ContentRef),\n points: [ctx.Position],\n text: ctx.string,\n toleranceSymbolId: ctx.optional(ctx.number),\n bordered: ctx.optional(ctx.boolean)\n });\n const getRefIds = (content) => [...ctx.getStrokeRefIds(content), ...ctx.toRefId(content.ref)];\n const leadCache = new ctx.WeakmapValuesCache();\n function getLeadGeometriesFromCache(content, contents) {\n const refs = new Set(ctx.iterateRefContents(getRefIds(content), contents, [content]));\n return leadCache.get(content, refs, () => {\n var _a, _b, _c;\n const ref = ctx.getReference(content.ref, contents, (c) => !ctx.shallowEquals(c, content));\n let p0 = content.points[0];\n let line;\n if (ref && content.points.length > 1) {\n const lines2 = (_c = (_b = (_a = ctx.getContentModel(ref)) == null ? void 0 : _a.getGeometries) == null ? void 0 : _b.call(_a, ref, contents)) == null ? void 0 : _c.lines;\n if (lines2) {\n const p = ctx.getPerpendicularPointToGeometryLines(content.points[1], lines2);\n if (p) {\n p0 = p.point;\n line = p.line;\n }\n }\n }\n let points;\n let arrow;\n if (content.points.length > 1) {\n const arrowPoints = ctx.getArrowPoints(content.points[1], p0, content);\n arrow = arrowPoints.arrowPoints;\n points = [arrowPoints.endPoint, ...content.points.slice(1)];\n } else {\n points = [];\n }\n let extendLine;\n if (line) {\n const { start, end } = ctx.getGeometryLineStartAndEnd(line);\n if (start && (!end || ctx.getTwoPointsDistance(start, p0) < ctx.getTwoPointsDistance(end, p0))) {\n const param0 = ctx.getGeometryLineParamAtPoint(p0, line, true);\n line = ctx.getPartOfGeometryLine(param0, 0, line);\n const marginParam = ctx.getGeometryLineParamByLength(line, -ctx.dimensionStyle.margin);\n if (marginParam !== void 0) {\n extendLine = ctx.getPartOfGeometryLine(marginParam, 1, line);\n }\n } else if (end && (!start || ctx.getTwoPointsDistance(end, p0) < ctx.getTwoPointsDistance(start, p0))) {\n const param0 = ctx.getGeometryLineParamAtPoint(p0, line);\n line = ctx.getPartOfGeometryLine(param0, 1, line);\n const marginParam = ctx.getGeometryLineParamByLength(line, -ctx.dimensionStyle.margin);\n if (marginParam !== void 0) {\n extendLine = ctx.getPartOfGeometryLine(marginParam, 1, line);\n }\n }\n }\n const size = ctx.getTextSize(ctx.getTextStyleFont(content), content.text);\n if (!size) {\n throw "not supported";\n }\n const previous = content.points[content.points.length - 2];\n const last = content.points[content.points.length - 1];\n const right = !previous || previous.x <= last.x;\n const padding = content.fontSize / 4;\n const toleranceSymbol = content.toleranceSymbolId !== void 0 ? toleranceSymbols[content.toleranceSymbolId] : void 0;\n const width = (size.width + content.fontSize * (toleranceSymbol ? 1 : 0) + padding * (toleranceSymbol ? 4 : 2)) * (right ? 1 : -1);\n const height = Math.max(size.height, content.fontSize) / 2 + padding;\n const textPoints = [\n { x: last.x, y: last.y - height },\n { x: last.x + width, y: last.y - height },\n { x: last.x + width, y: last.y + height },\n { x: last.x, y: last.y + height }\n ];\n const lines = Array.from(ctx.iteratePolylineLines(points));\n const renderingLines = ctx.dashedPolylineToLines(points, content.dashArray);\n if (extendLine) {\n lines.push(extendLine);\n renderingLines.push(...ctx.dashedPolylineToLines(ctx.getGeometryLinesPoints([extendLine])));\n }\n return {\n lines,\n first: p0,\n last,\n right,\n padding,\n bounding: ctx.mergeBoundings([ctx.getGeometryLinesBounding(lines), ctx.getPointsBounding(textPoints)]),\n regions: [\n {\n points: textPoints,\n lines: Array.from(ctx.iteratePolygonLines(textPoints))\n },\n ...arrow ? [{\n points: arrow,\n lines: Array.from(ctx.iteratePolygonLines(arrow))\n }] : []\n ],\n renderingLines\n };\n });\n }\n const React = ctx.React;\n return {\n type: "lead",\n ...ctx.strokeModel,\n ...ctx.arrowModel,\n ...ctx.textModel,\n move(content, offset) {\n for (const point of content.points) {\n ctx.movePoint(point, offset);\n }\n },\n rotate(content, center, angle) {\n for (const point of content.points) {\n ctx.rotatePoint(point, center, angle);\n }\n },\n scale(content, center, sx, sy) {\n for (const point of content.points) {\n ctx.scalePoint(point, center, sx, sy);\n }\n content.fontSize *= Math.abs(sx);\n },\n mirror(content, line) {\n for (const point of content.points) {\n ctx.mirrorPoint(point, line);\n }\n },\n render(content, renderCtx) {\n const { options, target, contents, fillOptions } = ctx.getStrokeRenderOptionsFromRenderContext(content, renderCtx);\n const { regions, renderingLines, last, right, padding } = getLeadGeometriesFromCache(content, contents);\n const children = [];\n for (const line of renderingLines) {\n children.push(target.renderPolyline(line, options));\n }\n if (regions && regions.length > 1) {\n children.push(target.renderPolygon(regions[1].points, fillOptions));\n }\n if (content.bordered && regions && regions.length > 0) {\n children.push(target.renderPolygon(regions[0].points, options));\n }\n const textStyleContent = ctx.getTextStyleContent(content, contents);\n const color = renderCtx.transformColor(textStyleContent.color);\n let cacheKey;\n if (renderCtx.isAssistence) {\n cacheKey = ctx.assistentTextCache.get(content.text, textStyleContent.fontSize, textStyleContent.color);\n }\n if (!cacheKey) {\n cacheKey = content;\n }\n let textX = last.x;\n const toleranceSymbol = content.toleranceSymbolId !== void 0 ? toleranceSymbols[content.toleranceSymbolId] : void 0;\n if (toleranceSymbol) {\n children.push(target.renderGroup([\n toleranceSymbol(target, textStyleContent.fontSize, options)\n ], { translate: { x: last.x + textStyleContent.fontSize * (right ? 0 : -1) + padding * (right ? 1 : -1), y: last.y - textStyleContent.fontSize / 2 } }));\n textX += (textStyleContent.fontSize + padding * 2) * (right ? 1 : -1);\n if (content.bordered && regions && regions.length > 0) {\n children.push(target.renderPolyline([{ x: textX, y: regions[0].points[0].y }, { x: textX, y: regions[0].points[2].y }], options));\n }\n }\n textX += padding * (right ? 1 : -1);\n const textOptions = ctx.getTextStyleRenderOptionsFromRenderContext(color, renderCtx);\n children.push(target.renderText(textX, last.y, content.text, color, textStyleContent.fontSize, textStyleContent.fontFamily, { cacheKey, ...textOptions, textBaseline: "middle", textAlign: right ? "left" : "right" }));\n return target.renderGroup(children);\n },\n getEditPoints(content, contents) {\n return ctx.getEditPointsFromCache(content, () => {\n const geometries = getLeadGeometriesFromCache(content, contents);\n return {\n editPoints: content.points.map((p, i) => {\n if (i === 0) {\n p = geometries.first;\n }\n return {\n ...p,\n cursor: "move",\n update(c, { cursor, start, scale }) {\n if (!isLeadContent(c)) {\n return;\n }\n c.points[i].x += cursor.x - start.x;\n c.points[i].y += cursor.y - start.y;\n return { assistentContents: [{ type: "line", dashArray: [4 / scale], points: [start, cursor] }] };\n }\n };\n })\n };\n });\n },\n getSnapPoints(content, contents) {\n return ctx.getSnapPointsFromCache(content, () => {\n const geometries = getLeadGeometriesFromCache(content, contents);\n return content.points.map((p, i) => {\n if (i === 0) {\n p = geometries.first;\n }\n return { ...p, type: "endpoint" };\n });\n });\n },\n getGeometries: getLeadGeometriesFromCache,\n propertyPanel(content, update, contents, { acquirePoint }) {\n var _a;\n return {\n ref: [\n /* @__PURE__ */ React.createElement(ctx.BooleanEditor, { value: content.ref !== void 0, readOnly: content.ref === void 0, setValue: (v) => update((c) => {\n if (isLeadContent(c) && !v) {\n c.ref = void 0;\n }\n }) }),\n typeof content.ref === "number" ? /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.ref, setValue: (v) => update((c) => {\n if (isLeadContent(c)) {\n c.ref = v;\n }\n }) }) : void 0\n ],\n points: /* @__PURE__ */ React.createElement(\n ctx.ArrayEditor,\n {\n inline: true,\n ...ctx.getArrayEditorProps((v) => v.points, { x: 0, y: 0 }, (v) => update((c) => {\n if (isLeadContent(c)) {\n v(c);\n }\n })),\n items: content.points.map((f, i) => /* @__PURE__ */ React.createElement(\n ctx.ObjectEditor,\n {\n inline: true,\n properties: {\n from: /* @__PURE__ */ React.createElement(ctx.Button, { onClick: () => acquirePoint((p) => update((c) => {\n if (isLeadContent(c)) {\n c.points[i].x = p.x;\n c.points[i].y = p.y;\n }\n })) }, "canvas"),\n x: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: f.x, setValue: (v) => update((c) => {\n if (isLeadContent(c)) {\n c.points[i].x = v;\n }\n }) }),\n y: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: f.y, setValue: (v) => update((c) => {\n if (isLeadContent(c)) {\n c.points[i].y = v;\n }\n }) })\n }\n }\n ))\n }\n ),\n text: /* @__PURE__ */ React.createElement(ctx.StringEditor, { textarea: true, value: content.text, setValue: (v) => update((c) => {\n if (isLeadContent(c)) {\n c.text = v;\n }\n }) }),\n toleranceSymbolId: [\n /* @__PURE__ */ React.createElement(ctx.BooleanEditor, { value: content.toleranceSymbolId !== void 0, setValue: (v) => update((c) => {\n if (isLeadContent(c)) {\n c.toleranceSymbolId = v ? 0 : void 0;\n }\n }) }),\n content.toleranceSymbolId !== void 0 ? /* @__PURE__ */ React.createElement(\n ctx.EnumEditor,\n {\n enums: toleranceSymbols.map((_, i) => i),\n enumTitles: toleranceSymbols.map((s) => ctx.reactSvgRenderTarget.renderResult([s(ctx.reactSvgRenderTarget, 13)], 13, 13)),\n value: content.toleranceSymbolId,\n setValue: (v) => update((c) => {\n if (isLeadContent(c)) {\n c.toleranceSymbolId = v;\n }\n })\n }\n ) : void 0\n ],\n bordered: /* @__PURE__ */ React.createElement(ctx.BooleanEditor, { value: (_a = content.bordered) != null ? _a : false, setValue: (v) => update((c) => {\n if (isLeadContent(c)) {\n c.bordered = v;\n }\n }) }),\n ...ctx.getTextContentPropertyPanel(content, update, contents),\n ...ctx.getArrowContentPropertyPanel(content, update),\n ...ctx.getStrokeContentPropertyPanel(content, update, contents)\n };\n },\n editPanel(content, scale, update, contents, cancel, transformPosition) {\n const p = transformPosition(content.points[content.points.length - 1]);\n const textStyleContent = ctx.getTextStyleContent(content, contents);\n const fontSize = textStyleContent.fontSize * scale;\n return /* @__PURE__ */ React.createElement(\n ctx.StringEditor,\n {\n style: {\n zIndex: 10,\n position: "absolute",\n left: `${p.x - 1}px`,\n top: `${p.y - fontSize - 1}px`,\n fontSize: `${fontSize}px`,\n fontFamily: content.fontFamily,\n color: ctx.getColorString(content.color),\n padding: "0px"\n },\n textarea: true,\n autoFocus: true,\n onCancel: cancel,\n value: content.text,\n setValue: (v) => {\n update((c) => {\n if (isLeadContent(c)) {\n c.text = v;\n }\n });\n }\n }\n );\n },\n isValid: (c, p) => ctx.validate(c, LeadContent, p),\n getRefIds,\n updateRefId(content, update) {\n if (content.ref !== void 0) {\n const newRefId = update(content.ref);\n if (newRefId !== void 0) {\n content.ref = newRefId;\n }\n }\n ctx.updateStrokeRefIds(content, update);\n },\n deleteRefId(content, ids) {\n if (content.ref && ids.includes(content.ref)) {\n content.ref = void 0;\n }\n ctx.deleteStrokeRefIds(content, ids);\n }\n };\n}\nfunction isLeadContent(content) {\n return content.type === "lead";\n}\nvar toleranceSymbols = [\n (target, size, options) => target.renderPolyline([{ x: 0, y: size * 0.5 }, { x: size, y: size * 0.5 }], options),\n (target, size, options) => target.renderPolygon([{ x: 0, y: size }, { x: size * 0.7, y: size }, { x: size, y: 0 }, { x: size * 0.3, y: 0 }], options),\n (target, size, options) => target.renderCircle(size * 0.5, size * 0.5, size * 0.48, options),\n (target, size, options) => target.renderGroup([\n target.renderCircle(size * 0.5, size * 0.5, size * 0.25, options),\n target.renderPolyline([{ x: 0, y: size }, { x: size * 0.4, y: 0 }], options),\n target.renderPolyline([{ x: size, y: 0 }, { x: size * 0.6, y: size }], options)\n ]),\n (target, size, options) => target.renderArc(size * 0.5, size * 0.7, size * 0.48, -180, 0, options),\n (target, size, options) => target.renderArc(size * 0.5, size * 0.7, size * 0.48, -180, 0, { ...options, closed: true }),\n (target, size, options) => target.renderGroup([\n target.renderPolyline([{ x: 0, y: size }, { x: size * 0.4, y: 0 }], options),\n target.renderPolyline([{ x: size, y: 0 }, { x: size * 0.6, y: size }], options)\n ]),\n (target, size, options) => target.renderGroup([\n target.renderPolyline([{ x: 0, y: size }, { x: size, y: size }], options),\n target.renderPolyline([{ x: size * 0.5, y: 0 }, { x: size * 0.5, y: size }], options)\n ]),\n (target, size, options) => target.renderPolyline([{ x: size, y: size }, { x: 0, y: size }, { x: size, y: 0 }], options),\n (target, size, options) => target.renderGroup([\n target.renderCircle(size * 0.5, size * 0.5, size * 0.25, options),\n target.renderPolyline([{ x: size * 0.5, y: 0 }, { x: size * 0.5, y: size }], options),\n target.renderPolyline([{ x: 0, y: size * 0.5 }, { x: size, y: size * 0.5 }], options)\n ]),\n (target, size, options) => target.renderGroup([\n target.renderCircle(size * 0.5, size * 0.5, size * 0.25, options),\n target.renderCircle(size * 0.5, size * 0.5, size * 0.45, options)\n ]),\n (target, size, options) => target.renderGroup([\n target.renderPolyline([{ x: 0, y: size * 0.5 }, { x: size, y: size * 0.5 }], options),\n target.renderPolyline([{ x: size * 0.25, y: size * 0.25 }, { x: size * 0.75, y: size * 0.25 }], options),\n target.renderPolyline([{ x: size * 0.25, y: size * 0.75 }, { x: size * 0.75, y: size * 0.75 }], options)\n ]),\n (target, size, options) => target.renderGroup([\n target.renderPolyline([{ x: size * 0.2, y: size }, { x: size * 0.8, y: 0 }], options),\n target.renderPolyline([{ x: size * 0.35, y: size * 0.4 }, { x: size * 0.8, y: 0 }, { x: size * 0.65, y: size * 0.55 }], options)\n ]),\n (target, size, options) => target.renderGroup([\n target.renderPolyline([{ x: size * 0.4, y: 0 }, { x: 0, y: size }, { x: size * 0.6, y: size }, { x: size, y: 0 }], options),\n target.renderPolyline([{ x: 0, y: size * 0.4 }, { x: size * 0.4, y: 0 }, { x: size * 0.35, y: size * 0.55 }], options),\n target.renderPolyline([{ x: size * 0.6, y: size * 0.4 }, { x: size, y: 0 }, { x: size * 0.95, y: size * 0.55 }], options)\n ])\n];\nfunction getCommand(ctx) {\n const React = ctx.React;\n const icon = /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 100 100" }, /* @__PURE__ */ React.createElement("polyline", { points: "47,4 96,4", strokeWidth: "8", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", strokeOpacity: "1", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polyline", { points: "71,4 71,54", strokeWidth: "8", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", strokeOpacity: "1", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polyline", { points: "46,29 5,92", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", strokeOpacity: "1", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polygon", { points: "0,100 12,62 30,73", strokeWidth: "0", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "currentColor", stroke: "currentColor" }));\n return {\n name: "create lead",\n icon,\n useCommand({ onEnd, type, scale, textStyleId, transformPosition, contents }) {\n const [lead, setLead] = React.useState();\n const [editText, setEditText] = React.useState(false);\n let message = "";\n if (type && !editText) {\n message = "press Enter to end";\n }\n const { input, clearText, setCursorPosition, setInputPosition, resetInput } = ctx.useCursorInput(message, type ? (e, text) => {\n if (e.key === "Enter") {\n if (text) {\n clearText();\n } else if (lead) {\n setEditText(true);\n setLead(ctx.produce(lead, (draft) => {\n draft.text = "";\n draft.points.splice(draft.points.length - 1, 1);\n }));\n e.preventDefault();\n }\n }\n } : void 0);\n const reset = () => {\n setLead(void 0);\n resetInput();\n setEditText(false);\n };\n const assistentContents = [];\n let panel;\n if (type) {\n if (lead) {\n assistentContents.push(lead);\n if (editText) {\n const last = lead.points[lead.points.length - 1];\n const p = transformPosition(last);\n const textStyleContent = ctx.getTextStyleContent(lead, contents);\n const fontSize = textStyleContent.fontSize * scale;\n panel = /* @__PURE__ */ React.createElement(\n ctx.StringEditor,\n {\n style: {\n zIndex: 10,\n position: "absolute",\n left: `${p.x - 1}px`,\n top: `${p.y - fontSize - 1}px`,\n fontSize: `${fontSize}px`,\n fontFamily: lead.fontFamily,\n color: ctx.getColorString(lead.color),\n padding: "0px"\n },\n textarea: true,\n autoFocus: true,\n onCancel: reset,\n value: lead.text,\n setValue: (v) => {\n setLead(ctx.produce(lead, (draft) => {\n draft.text = v;\n }));\n }\n }\n );\n }\n }\n }\n return {\n input,\n onStart: (p, target) => {\n if (!type) return;\n if (!lead) {\n setLead({\n type: "lead",\n text: "abc",\n textStyleId,\n color: 0,\n fontSize: 16 / scale,\n fontFamily: "monospace",\n points: [p, p],\n ref: target == null ? void 0 : target.id\n });\n } else if (editText) {\n onEnd({\n updateContents: (contents2) => contents2.push(lead)\n });\n reset();\n } else {\n const last = lead.points[lead.points.length - 1];\n setLead(ctx.produce(lead, (draft) => {\n draft.points.push(last);\n }));\n }\n },\n onMove(p, viewportPosition) {\n if (!type) return;\n if (editText) return;\n setInputPosition(viewportPosition || p);\n setCursorPosition(p);\n if (lead) {\n setLead(ctx.produce(lead, (draft) => {\n draft.points[lead.points.length - 1] = p;\n }));\n }\n },\n assistentContents,\n reset,\n panel\n };\n },\n selectCount: 0\n };\n}\nexport {\n getCommand,\n getModel,\n isLeadContent\n};\n','// dev/cad-editor/plugins/light.plugin.tsx\nfunction getCommand(ctx) {\n const React = ctx.React;\n const icon = /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 100 100" }, /* @__PURE__ */ React.createElement("circle", { cx: "50", cy: "50", r: "30", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fillOpacity: "1", strokeOpacity: "1", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polyline", { points: "50,20 50,0", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", strokeOpacity: "1", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polyline", { points: "29,29 15,15", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", strokeOpacity: "1", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polyline", { points: "20,50 0,50", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", strokeOpacity: "1", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polyline", { points: "29,71 15,85", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", strokeOpacity: "1", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polyline", { points: "50,80 50,100", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", strokeOpacity: "1", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polyline", { points: "71,29 85,15", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", strokeOpacity: "1", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polyline", { points: "71,71 85,85", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", strokeOpacity: "1", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polyline", { points: "80,50 100,50", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", strokeOpacity: "1", fill: "none", stroke: "currentColor" }));\n return {\n name: "light",\n useCommand({ type, getContentsInRange, contents }) {\n const [startPosition, setStartPosition] = React.useState();\n const [path, setPath] = React.useState();\n const reset = () => {\n setStartPosition(void 0);\n setPath(void 0);\n };\n const assistentContents = [];\n if (path) {\n assistentContents.push({ type: "geometry lines", lines: path, strokeColor: 16711680 });\n }\n return {\n onStart(s) {\n if (!type) return;\n setStartPosition(s);\n },\n reset,\n onMove(p) {\n if (!type) return;\n if (!startPosition) return;\n setPath(ctx.getLightPath(\n { x: startPosition.x, y: startPosition.y, angle: ctx.radianToAngle(ctx.getTwoPointsRadian(p, startPosition)) },\n (line) => {\n var _a, _b;\n const result = [];\n const region = ctx.getGeometryLineBoundingFromCache(line);\n for (const content of getContentsInRange(region)) {\n if (content) {\n const geometries = (_b = (_a = ctx.getContentModel(content)) == null ? void 0 : _a.getGeometries) == null ? void 0 : _b.call(_a, content, contents);\n if (geometries) {\n result.push(geometries);\n }\n }\n }\n return result;\n }\n ));\n },\n assistentContents\n };\n },\n selectCount: 0,\n icon\n };\n}\nexport {\n getCommand\n};\n','// dev/cad-editor/plugins/circle-arc.plugin.tsx\nfunction isArcContent(content) {\n return content.type === "arc";\n}\n\n// dev/cad-editor/plugins/line-polyline.plugin.tsx\nfunction getModel(ctx) {\n const LineContent = ctx.and(ctx.BaseContent(ctx.or("line", "polyline")), ctx.StrokeFields, ctx.FillFields, {\n points: ctx.minItems(2, [ctx.Position])\n });\n const getRefIds = (content) => ctx.getStrokeAndFillRefIds(content);\n const geometriesCache = new ctx.WeakmapValuesCache();\n function getPolylineGeometries(content, contents) {\n const refs = new Set(ctx.iterateRefContents(getRefIds(content), contents, [content]));\n return geometriesCache.get(content, refs, () => {\n const lines = Array.from(ctx.iteratePolylineLines(content.points));\n return {\n lines,\n points: content.points,\n bounding: ctx.getPointsBounding(content.points),\n renderingLines: ctx.dashedPolylineToLines(content.points, content.dashArray),\n regions: ctx.hasFill(content) ? [\n {\n lines,\n points: content.points\n }\n ] : void 0\n };\n });\n }\n const React = ctx.React;\n const lineModel = {\n type: "line",\n ...ctx.strokeModel,\n move(content, offset) {\n for (const point of content.points) {\n ctx.movePoint(point, offset);\n }\n },\n rotate(content, center, angle) {\n for (const point of content.points) {\n ctx.rotatePoint(point, center, angle);\n }\n },\n scale(content, center, sx, sy) {\n for (const point of content.points) {\n ctx.scalePoint(point, center, sx, sy);\n }\n },\n skew(content, center, sx, sy) {\n for (const point of content.points) {\n ctx.skewPoint(point, center, sx, sy);\n }\n },\n mirror(content, line) {\n for (const point of content.points) {\n ctx.mirrorPoint(point, line);\n }\n },\n break(content, intersectionPoints, contents) {\n const { lines } = getPolylineGeometries(content, contents);\n return ctx.breakPolyline(lines, intersectionPoints);\n },\n offset(content, point, distance, contents) {\n const { lines } = getPolylineGeometries(content, contents);\n if (!distance) {\n distance = Math.min(...lines.map((line) => ctx.getPointAndGeometryLineMinimumDistance(point, line)));\n }\n const index = ctx.getLinesOffsetDirection(point, lines);\n const points = ctx.getParallelPolylineByDistance(lines, distance, index);\n return ctx.trimOffsetResult(points, point, false, contents).map((p) => ctx.produce(content, (d) => {\n d.points = p;\n }));\n },\n join(content, target, contents) {\n if (isLineContent(target) || isPolyLineContent(target)) {\n const lines = [\n ...getPolylineGeometries(content, contents).lines.map((n) => ({ type: "line", points: [...n] })),\n ...getPolylineGeometries(target, contents).lines.map((n) => ({ type: "line", points: [...n] }))\n ];\n ctx.mergePolylines(lines);\n if (lines.length === 1) {\n return {\n ...content,\n points: lines[0].points\n };\n }\n }\n if (isArcContent(target)) {\n const newLines = ctx.mergeGeometryLines([{ type: "arc", curve: target }], getPolylineGeometries(content, contents).lines);\n if (newLines) {\n return ctx.geometryLinesToPline(newLines);\n }\n }\n return;\n },\n extend(content, point, contents) {\n const { lines } = getPolylineGeometries(content, contents);\n if (ctx.pointIsOnRay(point, { ...lines[0][0], angle: ctx.radianToAngle(ctx.getTwoPointsRadian(lines[0][0], lines[0][1])) })) {\n content.points[0] = point;\n } else {\n content.points[content.points.length - 1] = point;\n }\n },\n render(content, renderCtx) {\n const { options, target } = ctx.getStrokeRenderOptionsFromRenderContext(content, renderCtx);\n return target.renderPolyline(content.points, options);\n },\n getOperatorRenderPosition(content) {\n return content.points[0];\n },\n getEditPoints(content) {\n return ctx.getEditPointsFromCache(content, () => ({ editPoints: ctx.getPolylineEditPoints(content, isLineContent) }));\n },\n getSnapPoints(content, contents) {\n return ctx.getSnapPointsFromCache(content, () => {\n const { points, lines } = getPolylineGeometries(content, contents);\n return [\n ...points.map((p) => ({ ...p, type: "endpoint" })),\n ...lines.map(([start, end]) => ({\n x: (start.x + end.x) / 2,\n y: (start.y + end.y) / 2,\n type: "midpoint"\n }))\n ];\n });\n },\n getGeometries: getPolylineGeometries,\n propertyPanel(content, update, contents, { acquirePoint }) {\n return {\n points: /* @__PURE__ */ React.createElement(\n ctx.ArrayEditor,\n {\n inline: true,\n ...ctx.getArrayEditorProps((v) => v.points, { x: 0, y: 0 }, (v) => update((c) => {\n if (isLineContent(c)) {\n v(c);\n }\n })),\n items: content.points.map((f, i) => /* @__PURE__ */ React.createElement(\n ctx.ObjectEditor,\n {\n inline: true,\n properties: {\n from: /* @__PURE__ */ React.createElement(ctx.Button, { onClick: () => acquirePoint((p) => update((c) => {\n if (isLineContent(c)) {\n c.points[i].x = p.x;\n c.points[i].y = p.y;\n }\n })) }, "canvas"),\n x: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: f.x, setValue: (v) => update((c) => {\n if (isLineContent(c)) {\n c.points[i].x = v;\n }\n }) }),\n y: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: f.y, setValue: (v) => update((c) => {\n if (isLineContent(c)) {\n c.points[i].y = v;\n }\n }) })\n }\n }\n ))\n }\n ),\n ...ctx.getStrokeContentPropertyPanel(content, update, contents)\n };\n },\n isValid: (c, p) => ctx.validate(c, LineContent, p),\n getRefIds,\n updateRefId: ctx.updateStrokeAndFillRefIds,\n deleteRefId: ctx.deleteStrokeAndFillRefIds,\n reverse: (content) => ({\n ...content,\n points: content.points.slice().reverse()\n })\n };\n return [\n lineModel,\n {\n ...lineModel,\n type: "polyline",\n ...ctx.fillModel,\n explode(content, contents) {\n const { lines } = getPolylineGeometries(content, contents);\n return lines.map((line) => ({ type: "line", points: line }));\n },\n render(content, renderCtx) {\n const { options, target } = ctx.getStrokeFillRenderOptionsFromRenderContext(content, renderCtx);\n return target.renderPolyline(content.points, options);\n },\n getEditPoints(content) {\n return ctx.getEditPointsFromCache(content, () => ({ editPoints: ctx.getPolylineEditPoints(content, isPolyLineContent) }));\n },\n canSelectPart: true,\n propertyPanel(content, update, contents, { acquirePoint }) {\n return {\n points: /* @__PURE__ */ React.createElement(\n ctx.ArrayEditor,\n {\n inline: true,\n ...ctx.getArrayEditorProps((v) => v.points, { x: 0, y: 0 }, (v) => update((c) => {\n if (isPolyLineContent(c)) {\n v(c);\n }\n })),\n items: content.points.map((f, i) => /* @__PURE__ */ React.createElement(\n ctx.ObjectEditor,\n {\n inline: true,\n properties: {\n from: /* @__PURE__ */ React.createElement(ctx.Button, { onClick: () => acquirePoint((p) => update((c) => {\n if (isPolyLineContent(c)) {\n c.points[i].x = p.x;\n c.points[i].y = p.y;\n }\n })) }, "canvas"),\n x: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: f.x, setValue: (v) => update((c) => {\n if (isPolyLineContent(c)) {\n c.points[i].x = v;\n }\n }) }),\n y: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: f.y, setValue: (v) => update((c) => {\n if (isPolyLineContent(c)) {\n c.points[i].y = v;\n }\n }) })\n }\n }\n ))\n }\n ),\n ...ctx.getStrokeContentPropertyPanel(content, update, contents),\n ...ctx.getFillContentPropertyPanel(content, update, contents)\n };\n }\n }\n ];\n}\nfunction isLineContent(content) {\n return content.type === "line";\n}\nfunction isPolyLineContent(content) {\n return content.type === "polyline";\n}\nfunction getCommand(ctx) {\n const React = ctx.React;\n const icon1 = /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 100 100" }, /* @__PURE__ */ React.createElement("circle", { cx: "10", cy: "87", r: "12", strokeWidth: "0", vectorEffect: "non-scaling-stroke", fill: "currentColor", stroke: "#000000" }), /* @__PURE__ */ React.createElement("circle", { cx: "87", cy: "9", r: "12", strokeWidth: "0", vectorEffect: "non-scaling-stroke", fill: "currentColor", stroke: "#000000" }), /* @__PURE__ */ React.createElement("polyline", { points: "10,87 87,9", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }));\n const icon2 = /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 100 100" }, /* @__PURE__ */ React.createElement("polyline", { points: "12,86 38,24 62,64 88,13", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }));\n return [\n {\n name: "create line",\n useCommand({ onEnd, scale, type, strokeStyleId, fillStyleId }) {\n const { line, onClick, onMove, input, inputMode, lastPosition, reset } = ctx.useLineClickCreate(\n type === "create line",\n (c) => onEnd({\n updateContents: (contents) => contents.push(...Array.from(ctx.iteratePolylineLines(c)).map((line2) => ({ points: line2, strokeStyleId, fillStyleId, type: "line" })))\n })\n );\n const assistentContents = [];\n if (line && line.length > 1) {\n const start = line[line.length - 2];\n const end = line[line.length - 1];\n const r = ctx.getTwoPointsDistance(start, end);\n const angle = ctx.radianToAngle(ctx.getTwoPointsRadian(end, start));\n assistentContents.push(\n {\n type: "arc",\n x: start.x,\n y: start.y,\n r,\n dashArray: [4 / scale],\n startAngle: angle > 180 || angle < 0 ? angle : 0,\n endAngle: angle > 180 || angle < 0 ? 0 : angle\n },\n {\n type: "line",\n dashArray: [4 / scale],\n points: [start, { x: start.x + r, y: start.y }]\n },\n ...ctx.getAssistentText(\n r.toFixed(2),\n 16 / scale,\n (start.x + end.x) / 2 - 20,\n (start.y + end.y) / 2 + 4,\n inputMode === "length" ? 16711680 : 16764108\n ),\n ...ctx.getAssistentText(\n `${angle.toFixed(1)}\\xB0`,\n 16 / scale,\n end.x + 10,\n end.y - 10,\n inputMode === "angle" ? 16711680 : 16764108\n )\n );\n }\n if (line) {\n for (const lineSegment of ctx.iteratePolylineLines(line)) {\n assistentContents.push({ points: lineSegment, strokeStyleId, fillStyleId, type: "line" });\n }\n }\n return {\n onStart: onClick,\n input,\n onMove,\n assistentContents,\n lastPosition,\n reset\n };\n },\n selectCount: 0,\n hotkey: "L",\n icon: icon1\n },\n {\n name: "create polyline",\n useCommand({ onEnd, scale, type, strokeStyleId, fillStyleId }) {\n const { line, onClick, onMove, input, inputMode, lastPosition, reset, positions } = ctx.useLineClickCreate(\n type === "create polyline",\n (c) => onEnd({\n updateContents: (contents) => contents.push({ points: c, strokeStyleId, fillStyleId, type: "polyline" })\n })\n );\n const assistentContents = [];\n if (line && line.length > 1) {\n const start = line[line.length - 2];\n const end = line[line.length - 1];\n const r = ctx.getTwoPointsDistance(start, end);\n const angle = ctx.radianToAngle(ctx.getTwoPointsRadian(end, start));\n assistentContents.push(\n {\n type: "arc",\n x: start.x,\n y: start.y,\n r,\n dashArray: [4 / scale],\n startAngle: angle > 180 || angle < 0 ? angle : 0,\n endAngle: angle > 180 || angle < 0 ? 0 : angle\n },\n {\n type: "line",\n dashArray: [4 / scale],\n points: [start, { x: start.x + r, y: start.y }]\n },\n ...ctx.getAssistentText(\n r.toFixed(2),\n 16 / scale,\n (start.x + end.x) / 2 - 20,\n (start.y + end.y) / 2 + 4,\n inputMode === "length" ? 16711680 : 16764108\n ),\n ...ctx.getAssistentText(\n `${angle.toFixed(1)}\\xB0`,\n 16 / scale,\n end.x + 10,\n end.y - 10,\n inputMode === "angle" ? 16711680 : 16764108\n )\n );\n }\n if (line) {\n assistentContents.push({ points: line, strokeStyleId, fillStyleId, type: "polyline" });\n }\n return {\n onStart: onClick,\n input,\n onMove,\n assistentContents,\n lastPosition,\n reset,\n subcommand: type === "create polyline" && positions.length > 2 ? /* @__PURE__ */ React.createElement("span", null, /* @__PURE__ */ React.createElement(\n "button",\n {\n onClick: () => {\n onEnd({\n updateContents: (contents) => contents.push({ points: positions, type: "polygon" })\n });\n reset();\n },\n style: { position: "relative" }\n },\n "close"\n )) : void 0\n };\n },\n selectCount: 0,\n hotkey: "PL",\n icon: icon2\n }\n ];\n}\nexport {\n getCommand,\n getModel,\n isLineContent,\n isPolyLineContent\n};\n','// dev/cad-editor/plugins/linear-dimension.plugin.tsx\nfunction getModel(ctx) {\n const LinearDimensionContent = ctx.and(ctx.BaseContent("linear dimension"), ctx.StrokeFields, ctx.ArrowFields, ctx.LinearDimension, {\n ref1: ctx.optional(ctx.PositionRef),\n ref2: ctx.optional(ctx.PositionRef)\n });\n const getRefIds = (content) => {\n var _a, _b;\n return [...ctx.getStrokeRefIds(content), ...ctx.toRefIds([(_a = content.ref1) == null ? void 0 : _a.id, (_b = content.ref2) == null ? void 0 : _b.id])];\n };\n const linearDimensionCache = new ctx.WeakmapValuesCache();\n const getLinearDimensionPositions = (content, contents) => {\n var _a, _b;\n const p1 = (_a = ctx.getRefPosition(content.ref1, contents, [content])) != null ? _a : content.p1;\n const p2 = (_b = ctx.getRefPosition(content.ref2, contents, [content])) != null ? _b : content.p2;\n return { p1, p2 };\n };\n function getLinearDimensionGeometriesFromCache(content, contents) {\n const refs = new Set(ctx.iterateRefContents(getRefIds(content), contents, [content]));\n return linearDimensionCache.get(content, refs, () => {\n var _a, _b;\n const { p1, p2 } = getLinearDimensionPositions(content, contents);\n return ctx.getLinearDimensionGeometries({ ...content, p1, p2 }, {\n arrowAngle: (_a = content.arrowAngle) != null ? _a : ctx.dimensionStyle.arrowAngle,\n arrowSize: (_b = content.arrowSize) != null ? _b : ctx.dimensionStyle.arrowSize,\n margin: ctx.dimensionStyle.margin\n }, (c) => getTextPosition(c, contents));\n });\n }\n const textPositionMap = new ctx.WeakmapCache3();\n function getTextPosition(content, contents) {\n const { p1, p2 } = getLinearDimensionPositions(content, contents);\n return textPositionMap.get(content, p1, p2, () => {\n return ctx.getLinearDimensionTextPosition({ ...content, p1, p2 }, ctx.dimensionStyle.margin, ctx.getTextSizeFromCache);\n });\n }\n const React = ctx.React;\n return {\n type: "linear dimension",\n ...ctx.strokeModel,\n ...ctx.arrowModel,\n move(content, offset) {\n ctx.movePoint(content.p1, offset);\n ctx.movePoint(content.p2, offset);\n ctx.movePoint(content.position, offset);\n },\n scale(content, center, sx, sy) {\n ctx.scalePoint(content.p1, center, sx, sy);\n ctx.scalePoint(content.p2, center, sx, sy);\n ctx.scalePoint(content.position, center, sx, sy);\n },\n render(content, renderCtx) {\n const { options, fillOptions, contents, target, strokeColor } = ctx.getStrokeRenderOptionsFromRenderContext(content, renderCtx);\n const { regions, lines } = getLinearDimensionGeometriesFromCache(content, contents);\n const children = [];\n for (const line of lines) {\n children.push(target.renderPolyline(line, options));\n }\n if (regions) {\n for (let i = 0; i < 2 && i < regions.length; i++) {\n children.push(target.renderPolygon(regions[i].points, fillOptions));\n }\n }\n const { textPosition, text, textRotation } = getTextPosition(content, contents);\n const textOptions = ctx.getTextStyleRenderOptionsFromRenderContext(strokeColor, renderCtx);\n children.push(target.renderGroup(\n [\n target.renderText(textPosition.x, textPosition.y, text, strokeColor, content.fontSize, content.fontFamily, { cacheKey: content, ...textOptions })\n ],\n {\n rotation: textRotation,\n base: textPosition\n }\n ));\n return target.renderGroup(children);\n },\n getEditPoints(content, contents) {\n return ctx.getEditPointsFromCache(content, () => {\n const { p1, p2 } = getLinearDimensionPositions(content, contents);\n return {\n editPoints: [\n {\n x: content.position.x,\n y: content.position.y,\n cursor: "move",\n update(c, { cursor, start, scale }) {\n if (!isLinearDimensionContent(c)) {\n return;\n }\n c.position.x += cursor.x - start.x;\n c.position.y += cursor.y - start.y;\n return { assistentContents: [{ type: "line", dashArray: [4 / scale], points: [start, cursor] }] };\n }\n },\n {\n x: p1.x,\n y: p1.y,\n cursor: "move",\n update(c, { cursor, start, scale, target }) {\n if (!isLinearDimensionContent(c)) {\n return;\n }\n c.p1.x = cursor.x;\n c.p1.y = cursor.y;\n c.ref1 = ctx.getSnapTargetRef(target, contents);\n return { assistentContents: [{ type: "line", dashArray: [4 / scale], points: [start, cursor] }] };\n }\n },\n {\n x: p2.x,\n y: p2.y,\n cursor: "move",\n update(c, { cursor, start, scale, target }) {\n if (!isLinearDimensionContent(c)) {\n return;\n }\n c.p2.x = cursor.x;\n c.p2.y = cursor.y;\n c.ref2 = ctx.getSnapTargetRef(target, contents);\n return { assistentContents: [{ type: "line", dashArray: [4 / scale], points: [start, cursor] }] };\n }\n }\n ]\n };\n });\n },\n getGeometries: getLinearDimensionGeometriesFromCache,\n propertyPanel(content, update, contents, { acquirePoint }) {\n var _a, _b;\n return {\n p1: /* @__PURE__ */ React.createElement(\n ctx.ObjectEditor,\n {\n inline: true,\n properties: {\n from: /* @__PURE__ */ React.createElement(ctx.Button, { onClick: () => acquirePoint((p, ref) => update((c) => {\n if (isLinearDimensionContent(c)) {\n c.p1.x = p.x;\n c.p1.y = p.y;\n c.ref1 = ref;\n }\n })) }, "canvas"),\n x: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.p1.x, setValue: (v) => update((c) => {\n if (isLinearDimensionContent(c)) {\n c.p1.x = v;\n }\n }) }),\n y: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.p1.y, setValue: (v) => update((c) => {\n if (isLinearDimensionContent(c)) {\n c.p1.y = v;\n }\n }) })\n }\n }\n ),\n p2: /* @__PURE__ */ React.createElement(\n ctx.ObjectEditor,\n {\n inline: true,\n properties: {\n from: /* @__PURE__ */ React.createElement(ctx.Button, { onClick: () => acquirePoint((p, ref) => update((c) => {\n if (isLinearDimensionContent(c)) {\n c.p2.x = p.x;\n c.p2.y = p.y;\n c.ref2 = ref;\n }\n })) }, "canvas"),\n x: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.p2.x, setValue: (v) => update((c) => {\n if (isLinearDimensionContent(c)) {\n c.p2.x = v;\n }\n }) }),\n y: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.p2.y, setValue: (v) => update((c) => {\n if (isLinearDimensionContent(c)) {\n c.p2.y = v;\n }\n }) })\n }\n }\n ),\n ref1: [\n /* @__PURE__ */ React.createElement(ctx.BooleanEditor, { value: content.ref1 !== void 0, readOnly: content.ref1 === void 0, setValue: (v) => update((c) => {\n if (isLinearDimensionContent(c) && !v) {\n c.ref1 = void 0;\n }\n }) }),\n content.ref1 !== void 0 && typeof content.ref1.id === "number" ? /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.ref1.id, setValue: (v) => update((c) => {\n if (isLinearDimensionContent(c) && c.ref1) {\n c.ref1.id = v;\n }\n }) }) : void 0,\n content.ref1 !== void 0 ? /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.ref1.snapIndex, setValue: (v) => update((c) => {\n if (isLinearDimensionContent(c) && c.ref1) {\n c.ref1.snapIndex = v;\n }\n }) }) : void 0,\n ((_a = content.ref1) == null ? void 0 : _a.param) !== void 0 ? /* @__PURE__ */ React.createElement(ctx.NumberEditor, { readOnly: true, value: content.ref1.param }) : void 0\n ],\n ref2: [\n /* @__PURE__ */ React.createElement(ctx.BooleanEditor, { value: content.ref2 !== void 0, readOnly: content.ref2 === void 0, setValue: (v) => update((c) => {\n if (isLinearDimensionContent(c) && !v) {\n c.ref2 = void 0;\n }\n }) }),\n content.ref2 !== void 0 && typeof content.ref2.id === "number" ? /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.ref2.id, setValue: (v) => update((c) => {\n if (isLinearDimensionContent(c) && c.ref2) {\n c.ref2.id = v;\n }\n }) }) : void 0,\n content.ref2 !== void 0 ? /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.ref2.snapIndex, setValue: (v) => update((c) => {\n if (isLinearDimensionContent(c) && c.ref2) {\n c.ref2.snapIndex = v;\n }\n }) }) : void 0,\n ((_b = content.ref2) == null ? void 0 : _b.param) !== void 0 ? /* @__PURE__ */ React.createElement(ctx.NumberEditor, { readOnly: true, value: content.ref2.param }) : void 0\n ],\n position: /* @__PURE__ */ React.createElement(\n ctx.ObjectEditor,\n {\n inline: true,\n properties: {\n from: /* @__PURE__ */ React.createElement(ctx.Button, { onClick: () => acquirePoint((p) => update((c) => {\n if (isLinearDimensionContent(c)) {\n c.position.x = p.x;\n c.position.y = p.y;\n }\n })) }, "canvas"),\n x: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.position.x, setValue: (v) => update((c) => {\n if (isLinearDimensionContent(c)) {\n c.position.x = v;\n }\n }) }),\n y: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.position.y, setValue: (v) => update((c) => {\n if (isLinearDimensionContent(c)) {\n c.position.y = v;\n }\n }) })\n }\n }\n ),\n direct: /* @__PURE__ */ React.createElement(ctx.BooleanEditor, { value: content.direct === true, setValue: (v) => update((c) => {\n if (isLinearDimensionContent(c)) {\n c.direct = v ? true : void 0;\n }\n }) }),\n text: [\n /* @__PURE__ */ React.createElement(ctx.BooleanEditor, { value: content.text !== void 0, setValue: (v) => update((c) => {\n if (isLinearDimensionContent(c)) {\n c.text = v ? "" : void 0;\n }\n }) }),\n content.text !== void 0 ? /* @__PURE__ */ React.createElement(ctx.StringEditor, { value: content.text, setValue: (v) => update((c) => {\n if (isLinearDimensionContent(c)) {\n c.text = v;\n }\n }) }) : void 0\n ],\n fontSize: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.fontSize, setValue: (v) => update((c) => {\n if (isLinearDimensionContent(c)) {\n c.fontSize = v;\n }\n }) }),\n fontFamily: /* @__PURE__ */ React.createElement(ctx.StringEditor, { value: content.fontFamily, setValue: (v) => update((c) => {\n if (isLinearDimensionContent(c)) {\n c.fontFamily = v;\n }\n }) }),\n ...ctx.getArrowContentPropertyPanel(content, update),\n ...ctx.getStrokeContentPropertyPanel(content, update, contents)\n };\n },\n isValid: (c, p) => ctx.validate(c, LinearDimensionContent, p),\n getRefIds,\n updateRefId(content, update) {\n if (content.ref1) {\n const newRefId = update(content.ref1.id);\n if (newRefId !== void 0) {\n content.ref1.id = newRefId;\n }\n }\n if (content.ref2) {\n const newRefId = update(content.ref2.id);\n if (newRefId !== void 0) {\n content.ref2.id = newRefId;\n }\n }\n ctx.updateStrokeRefIds(content, update);\n },\n deleteRefId(content, ids) {\n if (content.ref1 && ids.includes(content.ref1.id)) {\n content.ref1 = void 0;\n }\n if (content.ref2 && ids.includes(content.ref2.id)) {\n content.ref2 = void 0;\n }\n ctx.deleteStrokeRefIds(content, ids);\n }\n };\n}\nfunction isLinearDimensionContent(content) {\n return content.type === "linear dimension";\n}\nfunction getCommand(ctx) {\n const React = ctx.React;\n const icon = /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 100 100" }, /* @__PURE__ */ React.createElement("circle", { cx: "15", cy: "83", r: "10", strokeWidth: "0", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "currentColor", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("circle", { cx: "82", cy: "84", r: "10", strokeWidth: "0", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "currentColor", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polyline", { points: "15,83 14,7", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polyline", { points: "82,84 82,6", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polyline", { points: "14,25 81,25", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polygon", { points: "66,34 83,24 65,15", strokeWidth: "0", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "currentColor", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polygon", { points: "29,34 12,25 29,15", strokeWidth: "0", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "currentColor", stroke: "currentColor" }));\n return {\n name: "create linear dimension",\n selectCount: 0,\n useCommand({ onEnd, type, scale, strokeStyleId }) {\n const [p1, setP1] = React.useState();\n const [p2, setP2] = React.useState();\n const [p1Target, setP1Target] = React.useState();\n const [p2Target, setP2Target] = React.useState();\n const [direct, setDirect] = React.useState(false);\n const [result, setResult] = React.useState();\n const [text, setText] = React.useState();\n let message = "";\n if (type) {\n message = "input text";\n }\n const { input, cursorPosition, setCursorPosition, clearText, setInputPosition, resetInput } = ctx.useCursorInput(message, type ? (e, text2) => {\n if (e.key === "Enter") {\n setText(text2);\n if (result) {\n setResult({ ...result, text: text2 });\n }\n clearText();\n }\n } : void 0);\n const reset = () => {\n setP1(void 0);\n setP2(void 0);\n setP1Target(void 0);\n setP2Target(void 0);\n setResult(void 0);\n resetInput();\n setText(void 0);\n };\n const assistentContents = [];\n if (result) {\n assistentContents.push(result);\n } else if (p1 && cursorPosition) {\n assistentContents.push({ type: "line", points: [p1, cursorPosition], dashArray: [4 / scale] });\n }\n return {\n input,\n reset,\n onStart(p, target) {\n if (!p1) {\n setP1(p);\n setP1Target(target);\n } else if (!p2) {\n setP2(p);\n setP2Target(target);\n } else if (result) {\n onEnd({\n updateContents: (contents) => {\n contents.push(result);\n },\n nextCommand: type\n });\n reset();\n }\n },\n onMove(p, viewportPosition) {\n setInputPosition(viewportPosition || p);\n setCursorPosition(p);\n if (type && p1 && p2) {\n setResult({\n type: "linear dimension",\n position: p,\n p1,\n p2,\n ref1: p1Target,\n ref2: p2Target,\n strokeStyleId,\n direct,\n fontSize: 16,\n fontFamily: "monospace",\n text\n });\n }\n },\n subcommand: type ? /* @__PURE__ */ React.createElement("span", null, /* @__PURE__ */ React.createElement("button", { onClick: () => {\n if (result) {\n setResult({ ...result, direct: !direct });\n }\n setDirect(!direct);\n }, style: { position: "relative" } }, direct ? "direct" : "axis")) : void 0,\n assistentContents,\n lastPosition: p2 != null ? p2 : p1\n };\n },\n icon\n };\n}\nexport {\n getCommand,\n getModel,\n isLinearDimensionContent\n};\n','// dev/cad-editor/plugins/measure.plugin.tsx\nfunction getCommand(ctx) {\n const React = ctx.React;\n const icon = /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 100 100" }, /* @__PURE__ */ React.createElement("polyline", { points: "9,14 43,92", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polyline", { points: "94,14 93,21 92,28 91,36 88,43 86,49 82,56 78,62 74,68 69,74 63,79 57,83 51,87 44,91", strokeWidth: "5", strokeDasharray: "10", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polyline", { points: "9,14 94,14", strokeWidth: "5", strokeDasharray: "10", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }));\n return {\n name: "measure",\n useCommand({ transform, type, scale }) {\n const { onStart, mask, startPosition, resetDragMove } = ctx.useDragMove(void 0, {\n transform,\n ignoreLeavingEvent: true\n });\n let message = "";\n if (type) {\n message = startPosition ? "specify end point" : "specify start point";\n }\n const { input, setInputPosition, cursorPosition, setCursorPosition, resetInput } = ctx.useCursorInput(message);\n const reset = () => {\n resetDragMove();\n resetInput();\n };\n const assistentContents = [];\n if (startPosition && cursorPosition) {\n const start = startPosition;\n const end = cursorPosition;\n const r = ctx.getTwoPointsDistance(start, end);\n const angle = ctx.radianToAngle(ctx.getTwoPointsRadian(end, start));\n assistentContents.push(\n {\n type: "arc",\n x: start.x,\n y: start.y,\n r,\n dashArray: [4 / scale],\n startAngle: angle > 180 || angle < 0 ? angle : 0,\n endAngle: angle > 180 || angle < 0 ? 0 : angle\n },\n {\n type: "line",\n dashArray: [4 / scale],\n points: [start, { x: start.x + r, y: start.y }]\n },\n ...ctx.getAssistentText(\n r.toFixed(2),\n 16 / scale,\n (start.x + end.x) / 2 - 20,\n (start.y + end.y) / 2 + 4\n ),\n ...ctx.getAssistentText(\n `${angle.toFixed(1)}\\xB0`,\n 16 / scale,\n end.x + 10,\n end.y - 10\n ),\n {\n type: "line",\n points: [startPosition, cursorPosition]\n }\n );\n }\n return {\n onStart: (s) => onStart(s),\n mask,\n input,\n reset,\n onMove(p, viewportPosition) {\n setCursorPosition(p);\n setInputPosition(viewportPosition != null ? viewportPosition : p);\n },\n assistentContents\n };\n },\n selectCount: 0,\n icon\n };\n}\nexport {\n getCommand\n};\n','// dev/cad-editor/plugins/mirror.plugin.tsx\nfunction getCommand(ctx) {\n const React = ctx.React;\n const icon = /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 100 100" }, /* @__PURE__ */ React.createElement("polygon", { points: "9,91 38,46 9,10", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polyline", { points: "50,0 50,100", strokeWidth: "5", strokeDasharray: "10", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polygon", { points: "90,91 62,46 91,10", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }));\n return {\n name: "mirror",\n useCommand({ onEnd, transform, type, scale }) {\n const [changeOriginal, setChangeOriginal] = React.useState(false);\n const { offset, onStart, mask, startPosition, resetDragMove } = ctx.useDragMove(onEnd, {\n transform,\n ignoreLeavingEvent: true\n });\n let message = "";\n if (type) {\n message = startPosition ? "specify second point" : "specify first point";\n }\n const { input, setInputPosition, clearText, setCursorPosition, resetInput } = ctx.useCursorInput(message, type ? (e, text) => {\n if (e.key === "Enter") {\n if (text.toLowerCase() === "y" || text.toLowerCase() === "n") {\n setChangeOriginal(!changeOriginal);\n clearText();\n }\n }\n } : void 0);\n const reset = () => {\n resetDragMove();\n resetInput();\n };\n return {\n onStart: (s) => onStart(s),\n mask: type ? mask : void 0,\n input,\n reset,\n subcommand: type ? /* @__PURE__ */ React.createElement(\n "button",\n {\n onClick: (e) => {\n setChangeOriginal(!changeOriginal);\n e.stopPropagation();\n }\n },\n changeOriginal ? "create new(N)" : "change original(Y)"\n ) : void 0,\n updateSelectedContent(content, contents, selected) {\n if (startPosition && offset && (offset.x !== 0 || offset.y !== 0)) {\n const end = { x: startPosition.x + offset.x, y: startPosition.y + offset.y };\n const line = ctx.twoPointLineToGeneralFormLine(startPosition, end);\n if (!line) return {};\n const angle = ctx.radianToAngle(ctx.getTwoPointsRadian(end, startPosition));\n if (changeOriginal) {\n const [newContent, ...patches] = ctx.produceWithPatches(content, (draft) => {\n var _a, _b;\n (_b = (_a = ctx.getContentModel(content)) == null ? void 0 : _a.mirror) == null ? void 0 : _b.call(_a, draft, line, angle, contents);\n });\n const assistentContents = ctx.updateReferencedContents(content, newContent, contents, selected);\n return {\n patches,\n assistentContents\n };\n }\n return {\n newContents: [\n ctx.produce(content, (d) => {\n var _a, _b;\n (_b = (_a = ctx.getContentModel(d)) == null ? void 0 : _a.mirror) == null ? void 0 : _b.call(_a, d, line, angle, contents);\n })\n ]\n };\n }\n return {};\n },\n onMove(p, viewportPosition) {\n setCursorPosition(p);\n setInputPosition(viewportPosition || p);\n },\n assistentContents: startPosition && offset && (offset.x !== 0 || offset.y !== 0) ? [\n {\n type: "line",\n dashArray: [4 / scale],\n points: [startPosition, { x: startPosition.x + offset.x, y: startPosition.y + offset.y }]\n }\n ] : void 0\n };\n },\n contentSelectable(content) {\n var _a;\n return !content.readonly && ((_a = ctx.getContentModel(content)) == null ? void 0 : _a.mirror) !== void 0;\n },\n hotkey: "MI",\n icon\n };\n}\nexport {\n getCommand\n};\n','// dev/cad-editor/plugins/move.plugin.tsx\nfunction getCommand(ctx) {\n const React = ctx.React;\n const icon = /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 100 100" }, /* @__PURE__ */ React.createElement("polygon", { points: "9,60 55,60 55,91 9,91", strokeWidth: "5", strokeDasharray: "10", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("rect", { x: "44", y: "10", width: "46", height: "31", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }));\n return {\n name: "move",\n useCommand({ onEnd, transform, type, scale }) {\n const { offset, onStart, mask, startPosition, resetDragMove } = ctx.useDragMove(onEnd, {\n transform,\n ignoreLeavingEvent: true\n });\n let message = "";\n if (type) {\n message = startPosition ? "specify end point" : "specify start point";\n }\n const { input, setInputPosition, resetInput } = ctx.useCursorInput(message);\n const reset = () => {\n resetDragMove();\n resetInput();\n };\n return {\n onStart: (s) => onStart(s),\n mask,\n input,\n onMove(_, p) {\n setInputPosition(p);\n },\n reset,\n updateSelectedContent(content, contents, selected) {\n if (startPosition && (offset.x !== 0 || offset.y !== 0)) {\n const [newContent, ...patches] = ctx.produceWithPatches(content, (draft) => {\n var _a, _b;\n (_b = (_a = ctx.getContentModel(content)) == null ? void 0 : _a.move) == null ? void 0 : _b.call(_a, draft, offset);\n });\n const assistentContents = ctx.updateReferencedContents(content, newContent, contents, selected);\n return {\n patches,\n assistentContents\n };\n }\n return {};\n },\n assistentContents: startPosition && (offset.x !== 0 || offset.y !== 0) ? [\n {\n type: "line",\n dashArray: [4 / scale],\n points: [startPosition, { x: startPosition.x + offset.x, y: startPosition.y + offset.y }]\n }\n ] : void 0\n };\n },\n contentSelectable(content) {\n var _a;\n return !content.readonly && ((_a = ctx.getContentModel(content)) == null ? void 0 : _a.move) !== void 0;\n },\n hotkey: "M",\n icon\n };\n}\nexport {\n getCommand\n};\n','// dev/cad-editor/plugins/nurbs.plugin.tsx\nfunction getModel(ctx) {\n const NurbsContent = ctx.and(ctx.BaseContent("nurbs"), ctx.StrokeFields, ctx.FillFields, ctx.SegmentCountFields, ctx.Nurbs);\n const getRefIds = (content) => ctx.getStrokeAndFillRefIds(content);\n const geometriesCache = new ctx.WeakmapValuesCache();\n function getNurbsGeometries(content, contents) {\n const refs = new Set(ctx.iterateRefContents(getRefIds(content), contents, [content]));\n return geometriesCache.get(content, refs, () => {\n var _a;\n let points;\n const nurbsSegmentCount = (_a = content.segmentCount) != null ? _a : ctx.defaultSegmentCount;\n let lines;\n if (content.points.length > 2) {\n if (!content.weights && !content.knots && (content.degree === 2 || content.points.length === 3)) {\n lines = ctx.getQuadraticSplineCurves(content.points).map((c) => ({ type: "quadratic curve", curve: c }));\n points = ctx.getGeometryLinesPoints(lines, nurbsSegmentCount);\n } else if (!content.weights && !content.knots && content.degree === 3) {\n lines = ctx.getBezierSplineCurves(content.points, false).map((c) => ({ type: "bezier curve", curve: c }));\n points = ctx.getGeometryLinesPoints(lines, nurbsSegmentCount);\n } else if (!content.weights && !content.knots && content.degree === 1) {\n points = content.points;\n lines = Array.from(ctx.iteratePolylineLines(points));\n } else {\n lines = [{\n type: "nurbs curve",\n curve: {\n degree: content.degree,\n points: content.points,\n knots: content.knots || ctx.getDefaultNurbsKnots(content.points.length, content.degree),\n weights: content.weights\n }\n }];\n points = ctx.getGeometryLinesPoints(lines, nurbsSegmentCount);\n }\n } else {\n points = content.points;\n lines = Array.from(ctx.iteratePolylineLines(points));\n }\n return {\n lines,\n points,\n bounding: ctx.getGeometryLinesBounding(lines),\n renderingLines: ctx.dashedPolylineToLines(points, content.dashArray),\n regions: ctx.hasFill(content) ? [\n {\n lines,\n points: content.points\n }\n ] : void 0\n };\n });\n }\n const React = ctx.React;\n const nurbsModel = {\n type: "nurbs",\n ...ctx.strokeModel,\n ...ctx.fillModel,\n ...ctx.segmentCountModel,\n move(content, offset) {\n for (const point of content.points) {\n ctx.movePoint(point, offset);\n }\n },\n rotate(content, center, angle) {\n for (const point of content.points) {\n ctx.rotatePoint(point, center, angle);\n }\n },\n mirror(content, line) {\n for (const point of content.points) {\n ctx.mirrorPoint(point, line);\n }\n },\n break(content, intersectionPoints, contents) {\n const lines = getNurbsGeometries(content, contents).lines;\n const result = ctx.breakGeometryLines(lines, intersectionPoints);\n return result.map((r) => r.map((t) => ctx.geometryLineToContent(t))).flat();\n },\n offset(content, point, distance, contents) {\n const lines = getNurbsGeometries(content, contents).lines;\n return ctx.trimGeometryLinesOffsetResult(ctx.getParallelGeometryLinesByDistancePoint(point, lines, distance), point).map((r) => r.map((n) => ctx.geometryLineToContent(n))).flat();\n },\n render(content, renderCtx) {\n const { points } = getNurbsGeometries(content, renderCtx.contents);\n const { options, target } = ctx.getStrokeFillRenderOptionsFromRenderContext(content, renderCtx);\n return target.renderPolyline(points, options);\n },\n renderIfSelected(content, { color, target, strokeWidth }) {\n return target.renderPolyline(content.points, { strokeColor: color, dashArray: [4], strokeWidth });\n },\n getOperatorRenderPosition(content) {\n return content.points[0];\n },\n getEditPoints(content) {\n return ctx.getEditPointsFromCache(content, () => ({ editPoints: ctx.getPolylineEditPoints(content, isNurbsContent, false, true) }));\n },\n getSnapPoints(content) {\n return ctx.getSnapPointsFromCache(content, () => content.points.map((p) => ({ ...p, type: "endpoint" })));\n },\n getGeometries: getNurbsGeometries,\n propertyPanel(content, update, contents, { acquirePoint }) {\n return {\n points: /* @__PURE__ */ React.createElement(\n ctx.ArrayEditor,\n {\n inline: true,\n ...ctx.getArrayEditorProps((v) => v.points, { x: 0, y: 0 }, (v) => update((c) => {\n if (isNurbsContent(c)) {\n v(c);\n if (c.points.length !== content.points.length) {\n c.knots = void 0;\n c.weights = void 0;\n }\n }\n })),\n items: content.points.map((f, i) => /* @__PURE__ */ React.createElement(\n ctx.ObjectEditor,\n {\n inline: true,\n properties: {\n from: /* @__PURE__ */ React.createElement(ctx.Button, { onClick: () => acquirePoint((p) => update((c) => {\n if (isNurbsContent(c)) {\n c.points[i].x = p.x;\n c.points[i].y = p.y;\n }\n })) }, "canvas"),\n x: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: f.x, setValue: (v) => update((c) => {\n if (isNurbsContent(c)) {\n c.points[i].x = v;\n }\n }) }),\n y: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: f.y, setValue: (v) => update((c) => {\n if (isNurbsContent(c)) {\n c.points[i].y = v;\n }\n }) })\n }\n }\n ))\n }\n ),\n degree: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.degree, setValue: (v) => update((c) => {\n if (isNurbsContent(c) && Number.isInteger(v) && v >= 1) {\n c.degree = v;\n c.knots = void 0;\n }\n }) }),\n knots: [\n /* @__PURE__ */ React.createElement(ctx.BooleanEditor, { value: content.knots !== void 0, setValue: (v) => update((c) => {\n if (isNurbsContent(c)) {\n c.knots = v ? ctx.getDefaultNurbsKnots(content.points.length, content.degree) : void 0;\n }\n }) }),\n content.knots !== void 0 ? /* @__PURE__ */ React.createElement(\n ctx.ArrayEditor,\n {\n inline: true,\n ...ctx.getArrayEditorProps((v) => v.knots || [], () => content.knots && content.knots.length > 0 ? content.knots[content.knots.length - 1] + 1 : 0, (v) => update((c) => {\n if (isNurbsContent(c)) {\n v(c);\n }\n })),\n items: content.knots.map((f, i) => /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: f, setValue: (v) => update((c) => {\n if (isNurbsContent(c) && c.knots) {\n c.knots[i] = v;\n }\n }) }))\n }\n ) : void 0\n ],\n weights: [\n /* @__PURE__ */ React.createElement(ctx.BooleanEditor, { value: content.weights !== void 0, setValue: (v) => update((c) => {\n if (isNurbsContent(c)) {\n c.weights = v ? ctx.getDefaultWeights(content.points.length) : void 0;\n }\n }) }),\n content.weights !== void 0 ? /* @__PURE__ */ React.createElement(\n ctx.ArrayEditor,\n {\n inline: true,\n ...ctx.getArrayEditorProps((v) => v.weights || [], 1, (v) => update((c) => {\n if (isNurbsContent(c)) {\n v(c);\n }\n })),\n items: content.weights.map((f, i) => /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: f, setValue: (v) => update((c) => {\n if (isNurbsContent(c) && c.weights) {\n c.weights[i] = v;\n }\n }) }))\n }\n ) : void 0\n ],\n ...ctx.getStrokeContentPropertyPanel(content, update, contents),\n ...ctx.getFillContentPropertyPanel(content, update, contents),\n ...ctx.getSegmentCountContentPropertyPanel(content, update)\n };\n },\n isValid: (c, p) => ctx.validate(c, NurbsContent, p),\n getRefIds,\n updateRefId: ctx.updateStrokeAndFillRefIds,\n deleteRefId: ctx.deleteStrokeAndFillRefIds,\n reverse: (content) => ctx.reverseNurbs(content)\n };\n return [\n nurbsModel\n ];\n}\nfunction isNurbsContent(content) {\n return content.type === "nurbs";\n}\nfunction getCommand(ctx) {\n const React = ctx.React;\n const icon1 = /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 100 100" }, /* @__PURE__ */ React.createElement("circle", { cx: "13", cy: "22", r: "5", strokeWidth: "0", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "currentColor", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("circle", { cx: "28", cy: "79", r: "5", strokeWidth: "0", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "currentColor", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("circle", { cx: "63", cy: "22", r: "5", strokeWidth: "0", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "currentColor", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("circle", { cx: "85", cy: "80", r: "5", strokeWidth: "0", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "currentColor", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polyline", { points: "13,22 14,24 14,26 15,29 15,31 16,33 17,34 17,36 18,38 18,40 19,41 20,43 20,44 21,46 22,47 22,49 23,50 23,51 24,52 25,53 25,54 26,55 27,56 27,56 28,57 29,58 29,58 30,59 31,59 31,59 32,60 33,60 33,60 34,60 35,60 35,60 36,60 37,60 37,59 38,59 39,58 39,58 40,57 41,57 41,56 42,55 43,55 43,54 44,53 45,52 46,51 46,49 47,48 48,47 48,46 49,46 50,45 50,44 51,44 52,43 53,43 53,42 54,42 55,42 56,41 56,41 57,41 58,41 59,41 59,41 60,42 61,42 62,42 63,43 63,43 64,44 65,44 66,45 67,46 67,47 68,47 69,48 70,49 71,51 71,52 72,53 73,54 74,56 75,57 76,59 76,60 77,62 78,64 79,65 80,67 81,69 82,71 82,73 83,75 84,78 85,80", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }));\n const nurbsCommand = {\n name: "create nurbs",\n type: [\n { name: "nurbs", icon: icon1 }\n ],\n useCommand({ onEnd, type, scale, strokeStyleId, fillStyleId }) {\n const { line, onClick, onMove, input, lastPosition, reset } = ctx.useLineClickCreate(\n type === "nurbs",\n (c) => onEnd({\n updateContents: (contents) => contents.push({ points: c, type: "nurbs", degree: 2, strokeStyleId, fillStyleId })\n })\n );\n const assistentContents = [];\n if (line) {\n assistentContents.push(\n { points: line, type: "nurbs", strokeStyleId, fillStyleId, degree: 2 },\n { points: line, type: "polyline", dashArray: [4 / scale] }\n );\n }\n return {\n onStart: onClick,\n input,\n onMove,\n assistentContents,\n lastPosition,\n reset\n };\n },\n selectCount: 0\n };\n return [\n nurbsCommand\n ];\n}\nexport {\n getCommand,\n getModel,\n isNurbsContent\n};\n','// dev/cad-editor/plugins/offset.plugin.tsx\nfunction getCommand(ctx) {\n const React = ctx.React;\n const icon = /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 100 100" }, /* @__PURE__ */ React.createElement("rect", { x: "8", y: "9", width: "82", height: "82", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("rect", { x: "22", y: "23", width: "55", height: "55", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }));\n function contentSelectable(content) {\n var _a;\n return ((_a = ctx.getContentModel(content)) == null ? void 0 : _a.offset) !== void 0;\n }\n function getOffsetResult(content, p, offset, contents, lineJoin) {\n const model = ctx.getContentModel(content);\n if (model == null ? void 0 : model.offset) {\n const newContent = model.offset(content, p, offset, contents, lineJoin);\n if (Array.isArray(newContent)) {\n return newContent.filter((c) => model.isValid(c) === true);\n }\n if (newContent && model.isValid(newContent) === true) {\n return [newContent];\n }\n }\n return [];\n }\n return {\n name: "offset",\n useCommand({ onEnd, type, contents }) {\n let message = "";\n if (type) {\n message = "input offset or click to end";\n }\n const [lineJoin, setLineJoin] = React.useState(ctx.defaultLineJoin);\n const [offset, setOffset] = React.useState(0);\n const { input, clearText, setInputPosition, cursorPosition, setCursorPosition, resetInput } = ctx.useCursorInput(message, type ? (e, text) => {\n if (e.key === "Enter") {\n const offset2 = +text;\n if (!isNaN(offset2) && offset2 >= 0) {\n setOffset(offset2);\n clearText();\n } else if (text.toUpperCase() === "T") {\n setOffset(0);\n clearText();\n }\n }\n } : void 0);\n return {\n onStart(p) {\n resetInput();\n onEnd({\n nextCommand: "offset",\n updateContents: (contents2, selected) => {\n const target = contents2.filter((c, i) => c && ctx.isSelected([i], selected) && contentSelectable(c));\n for (const content of target) {\n if (content) {\n contents2.push(...getOffsetResult(content, p, offset, contents2, lineJoin));\n }\n }\n setCursorPosition(void 0);\n }\n });\n },\n input,\n onMove(p, viewportPosition) {\n setInputPosition(viewportPosition || p);\n if (!type) {\n return;\n }\n setCursorPosition(p);\n },\n updateSelectedContent(content) {\n if (cursorPosition) {\n const newContents = getOffsetResult(content, cursorPosition, offset, contents, lineJoin);\n if (newContents.length > 0) {\n return {\n newContents\n };\n }\n }\n return {};\n },\n subcommand: type === "offset" ? /* @__PURE__ */ React.createElement("span", null, /* @__PURE__ */ React.createElement(ctx.EnumEditor, { value: lineJoin, enums: ["miter", "bevel", "round"], setValue: setLineJoin })) : void 0,\n reset: resetInput\n };\n },\n contentSelectable,\n selectCount: 1,\n icon,\n pointSnapDisabled: true\n };\n}\nexport {\n getCommand\n};\n','// dev/cad-editor/plugins/parabola.plugin.tsx\nfunction getModel(ctx) {\n const ParabolaContent = ctx.and(ctx.BaseContent("parabola"), ctx.StrokeFields, ctx.ParabolaSegment, ctx.SegmentCountFields);\n const geometriesCache = new ctx.WeakmapValuesCache();\n function getParabolaGeometries(content, contents) {\n const refs = new Set(ctx.iterateRefContents(ctx.getStrokeRefIds(content), contents, [content]));\n return geometriesCache.get(content, refs, () => {\n var _a;\n const segmentCount = (_a = content.segmentCount) != null ? _a : ctx.defaultSegmentCount;\n const curve = ctx.parabolaSegmentToQuadraticCurve(content);\n const points = ctx.getQuadraticCurvePoints(curve.from, curve.cp, curve.to, segmentCount);\n const lines = [\n { type: "quadratic curve", curve }\n ];\n return {\n lines,\n start: curve.from,\n end: curve.to,\n startAngle: ctx.radianToAngle(ctx.getParabolaTangentRadianAtParam(content, content.t1)),\n endAngle: ctx.radianToAngle(ctx.getParabolaTangentRadianAtParam(content, content.t2)),\n focus: ctx.getPointByLengthAndRadian(content, ctx.getParabolaFocusParameter(content.p) / 2, ctx.angleToRadian(content.angle)),\n points,\n bounding: ctx.getGeometryLinesBounding(lines),\n renderingLines: ctx.dashedPolylineToLines(points, content.dashArray)\n };\n });\n }\n const React = ctx.React;\n return {\n type: "parabola",\n ...ctx.strokeModel,\n ...ctx.segmentCountModel,\n move(content, offset) {\n ctx.movePoint(content, offset);\n },\n rotate(content, center, angle) {\n ctx.rotateParabola(content, center, angle);\n },\n scale(content, center, sx, sy) {\n const curve = ctx.parabolaSegmentToQuadraticCurve(content);\n const line = { type: "quadratic curve", curve };\n ctx.scaleGeometryLine(line, center, sx, sy);\n return ctx.geometryLineToContent(line);\n },\n skew(content, center, sx, sy) {\n const curve = ctx.parabolaSegmentToQuadraticCurve(content);\n const line = { type: "quadratic curve", curve };\n ctx.skewGeometryLine(line, center, sx, sy);\n return ctx.geometryLineToContent(line);\n },\n mirror(content, line, angle) {\n ctx.mirrorParabola(content, line, angle);\n },\n break(content, intersectionPoints, contents) {\n const lines = getParabolaGeometries(content, contents).lines;\n return ctx.breakGeometryLinesToPathCommands(lines, intersectionPoints);\n },\n offset(content, point, distance, contents) {\n if (!distance) {\n distance = Math.min(...getParabolaGeometries(content, contents).lines.map((line) => ctx.getPointAndGeometryLineMinimumDistance(point, line)));\n }\n return ctx.getParallelParabolaSegmentsByDistance(content, distance)[ctx.pointSideToIndex(ctx.getPointSideOfParabolaSegment(point, content))];\n },\n join(content, target, contents) {\n var _a, _b, _c;\n const { lines } = getParabolaGeometries(content, contents);\n const line2 = (_c = (_b = (_a = ctx.getContentModel(target)) == null ? void 0 : _a.getGeometries) == null ? void 0 : _b.call(_a, target, contents)) == null ? void 0 : _c.lines;\n if (!line2) return;\n const newLines = ctx.mergeGeometryLines(lines, line2);\n if (!newLines) return;\n return {\n ...content,\n type: "path",\n commands: ctx.geometryLineToPathCommands(newLines)\n };\n },\n extend(content, point) {\n const t = ctx.getParabolaParamAtPoint(content, point);\n if (ctx.isBefore(t, content.t1, content.t2)) {\n content.t1 = t;\n } else {\n content.t2 = t;\n }\n },\n render(content, renderCtx) {\n const { options, target } = ctx.getStrokeRenderOptionsFromRenderContext(content, renderCtx);\n const { points } = getParabolaGeometries(content, renderCtx.contents);\n return target.renderPolyline(points, options);\n },\n renderIfSelected(content, { color, target, strokeWidth }) {\n return target.renderRay(content.x, content.y, content.angle, { strokeColor: color, dashArray: [4], strokeWidth });\n },\n getEditPoints(content, contents) {\n return ctx.getEditPointsFromCache(content, () => {\n const { start, end, startAngle, endAngle, focus } = getParabolaGeometries(content, contents);\n return {\n editPoints: [\n {\n x: content.x,\n y: content.y,\n cursor: "move",\n type: "move",\n update(c, { cursor, start: start2, scale }) {\n if (!isParabolaContent(c)) {\n return;\n }\n c.x += cursor.x - start2.x;\n c.y += cursor.y - start2.y;\n return { assistentContents: [{ type: "line", dashArray: [4 / scale], points: [content, cursor] }] };\n }\n },\n {\n x: start.x,\n y: start.y,\n cursor: ctx.getResizeCursor(startAngle, "left"),\n update(c, { cursor, start: start2, scale }) {\n if (!isParabolaContent(c)) {\n return;\n }\n c.t1 = ctx.minimumBy(ctx.getPerpendicularParamsToParabola(cursor, content), (t) => ctx.getTwoPointsDistanceSquare(cursor, ctx.getParabolaPointAtParam(content, t)));\n return { assistentContents: [{ type: "line", dashArray: [4 / scale], points: [start2, cursor] }] };\n }\n },\n {\n x: end.x,\n y: end.y,\n cursor: ctx.getResizeCursor(endAngle, "right"),\n update(c, { cursor, start: start2, scale }) {\n if (!isParabolaContent(c)) {\n return;\n }\n c.t2 = ctx.minimumBy(ctx.getPerpendicularParamsToParabola(cursor, content), (t) => ctx.getTwoPointsDistanceSquare(cursor, ctx.getParabolaPointAtParam(content, t)));\n return { assistentContents: [{ type: "line", dashArray: [4 / scale], points: [start2, cursor] }] };\n }\n },\n {\n x: focus.x,\n y: focus.y,\n cursor: "move",\n update(c, { cursor, scale }) {\n if (!isParabolaContent(c)) {\n return;\n }\n c.p = ctx.getParabolaFocusParameter(ctx.getTwoPointsDistance(content, cursor) * 2);\n c.angle = ctx.radianToAngle(ctx.getTwoPointsRadian(cursor, content));\n return { assistentContents: [{ type: "line", dashArray: [4 / scale], points: [content, cursor] }] };\n }\n }\n ]\n };\n });\n },\n getSnapPoints(content, contents) {\n return ctx.getSnapPointsFromCache(content, () => {\n const { start, end, focus } = getParabolaGeometries(content, contents);\n return [\n { ...start, type: "endpoint" },\n { ...end, type: "endpoint" },\n { ...content, type: "center" },\n { ...focus, type: "center" }\n ];\n });\n },\n getGeometries: getParabolaGeometries,\n propertyPanel(content, update, contents, { acquirePoint }) {\n return {\n from: /* @__PURE__ */ React.createElement(ctx.Button, { onClick: () => acquirePoint((p) => update((c) => {\n if (isParabolaContent(c)) {\n c.x = p.x;\n c.y = p.y;\n }\n })) }, "canvas"),\n x: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.x, setValue: (v) => update((c) => {\n if (isParabolaContent(c)) {\n c.x = v;\n }\n }) }),\n y: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.y, setValue: (v) => update((c) => {\n if (isParabolaContent(c)) {\n c.y = v;\n }\n }) }),\n p: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.p, setValue: (v) => update((c) => {\n if (isParabolaContent(c) && v > 0) {\n c.p = v;\n }\n }) }),\n t1: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.t1, setValue: (v) => update((c) => {\n if (isParabolaContent(c)) {\n c.t1 = v;\n }\n }) }),\n t2: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.t2, setValue: (v) => update((c) => {\n if (isParabolaContent(c)) {\n c.t2 = v;\n }\n }) }),\n angle: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.angle, setValue: (v) => update((c) => {\n if (isParabolaContent(c)) {\n c.angle = v;\n }\n }) }),\n ...ctx.getStrokeContentPropertyPanel(content, update, contents),\n ...ctx.getSegmentCountContentPropertyPanel(content, update)\n };\n },\n isValid: (c, p) => ctx.validate(c, ParabolaContent, p),\n getRefIds: ctx.getStrokeRefIds,\n updateRefId: ctx.updateStrokeRefIds,\n deleteRefId: ctx.deleteStrokeRefIds,\n reverse: ctx.reverseParabola\n };\n}\nfunction isParabolaContent(content) {\n return content.type === "parabola";\n}\nfunction getCommand(ctx) {\n const React = ctx.React;\n const icon = /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 100 100" }, /* @__PURE__ */ React.createElement("polyline", { points: "99,3 98,7 97,10 96,14 95,18 94,21 93,25 92,28 91,31 90,34 89,38 88,41 87,44 86,46 85,49 84,52 83,55 82,57 81,60 80,62 79,64 78,67 77,69 76,71 75,73 75,75 74,77 73,79 72,80 71,82 70,84 69,85 68,87 67,88 66,89 65,90 64,91 63,93 62,93 61,94 60,95 59,96 58,97 57,97 56,98 55,98 54,98 53,99 52,99 51,99 50,99 49,99 48,99 47,99 46,98 45,98 44,98 43,97 42,97 41,96 40,95 39,94 38,93 37,93 36,91 35,90 34,89 33,88 32,87 31,85 30,84 29,82 28,80 27,79 26,77 26,75 25,73 24,71 23,69 22,67 21,64 20,62 19,60 18,57 17,55 16,52 15,49 14,46 13,44 12,41 11,38 10,34 9,31 8,28 7,25 6,21 5,18 4,14 3,10 2,7 1,3", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", strokeOpacity: "1", fill: "none", stroke: "currentColor" }));\n return {\n name: "create parabola",\n icon,\n useCommand({ onEnd, type, strokeStyleId }) {\n const [content, setContent] = React.useState();\n const [status, setStatus] = React.useState("position");\n const reset = () => {\n setContent(void 0);\n setStatus("position");\n };\n const assistentContents = [];\n if (content) {\n assistentContents.push(content);\n }\n return {\n onStart() {\n if (type !== "create parabola") return;\n if (status === "position") {\n setStatus("angle");\n } else if (status === "angle") {\n setStatus("t1");\n } else if (status === "t1") {\n setStatus("t2");\n } else if (status === "t2") {\n onEnd({\n updateContents: (contents) => contents.push(content)\n });\n reset();\n }\n },\n onMove(p) {\n if (type !== "create parabola") return;\n if (!content) {\n setContent({\n type: "parabola",\n x: p.x,\n y: p.y,\n p: 0.01,\n t1: -100,\n t2: 100,\n angle: -90,\n strokeStyleId\n });\n } else if (status === "position") {\n setContent({\n ...content,\n x: p.x,\n y: p.y\n });\n } else if (status === "angle") {\n setContent({\n ...content,\n angle: ctx.radianToAngle(ctx.getTwoPointsRadian(p, content))\n });\n } else if (status === "t1") {\n const x = ctx.getPerpendicularParamToLine2D(p, content, ctx.getParabolaXAxisRadian(content));\n const y = ctx.getPerpendicularParamToLine2D(p, content, ctx.angleToRadian(content.angle));\n setContent({\n ...content,\n t1: x,\n p: Math.abs(y) / x / x / 2\n });\n } else if (status === "t2") {\n setContent({\n ...content,\n t2: ctx.minimumBy(ctx.getPerpendicularParamsToParabola(p, content), (t) => ctx.getTwoPointsDistanceSquare(p, ctx.getParabolaPointAtParam(content, t)))\n });\n }\n },\n assistentContents,\n reset\n };\n },\n selectCount: 0\n };\n}\nexport {\n getCommand,\n getModel,\n isParabolaContent\n};\n','// dev/cad-editor/plugins/coordinate-axis.plugin.tsx\nfunction isCoordinateAxisContent(content) {\n return content.type === "coordinate axis";\n}\n\n// dev/cad-editor/plugins/parametric-equation.plugin.tsx\nfunction getModel(ctx) {\n const ParametricEquationContent = ctx.and(ctx.BaseContent("parametric equation"), ctx.StrokeFields, ctx.SegmentCountFields, {\n axisId: ctx.ContentRef,\n xExpression: ctx.string,\n yExpression: ctx.string,\n min: ctx.number,\n max: ctx.number\n });\n const getRefIds = (content) => [...ctx.getStrokeRefIds(content), ...ctx.toRefId(content.axisId, true)];\n const equationCache = new ctx.WeakmapValuesCache();\n function getGeometriesFromCache(content, contents) {\n const refs = new Set(ctx.iterateRefContents(getRefIds(content), contents, [content]));\n return equationCache.get(content, refs, () => {\n var _a;\n const axis = ctx.getReference(content.axisId, contents, isCoordinateAxisContent);\n if (axis) {\n if (content.xExpression && content.yExpression) {\n try {\n const xExpression = ctx.parseExpression(ctx.tokenizeExpression(content.xExpression));\n const yExpression = ctx.parseExpression(ctx.tokenizeExpression(content.yExpression));\n const points = [];\n const segmentCount = (_a = content.segmentCount) != null ? _a : ctx.defaultSegmentCount;\n const step = (content.max - content.min) / segmentCount;\n for (let t = content.min; t <= content.max; t += step) {\n const x = ctx.evaluateExpression(xExpression, { Math, t });\n const y = ctx.evaluateExpression(yExpression, { Math, t });\n if (typeof x === "number" && !isNaN(x) && typeof y === "number" && !isNaN(y)) {\n points.push({ x: x + axis.x, y: y * (axis.flipY ? -1 : 1) + axis.y });\n }\n }\n const lines = Array.from(ctx.iteratePolylineLines(points));\n return {\n points,\n lines,\n bounding: ctx.getPointsBounding(points),\n renderingLines: ctx.dashedPolylineToLines(points, content.dashArray)\n };\n } catch (e) {\n console.info(e);\n }\n }\n return { lines: [], points: [], renderingLines: [] };\n }\n return { lines: [], points: [], renderingLines: [] };\n });\n }\n const React = ctx.React;\n return {\n type: "parametric equation",\n ...ctx.strokeModel,\n ...ctx.segmentCountModel,\n render(content, renderCtx) {\n const { options, contents, target } = ctx.getStrokeRenderOptionsFromRenderContext(content, renderCtx);\n const { points } = getGeometriesFromCache(content, contents);\n return target.renderPolyline(points, options);\n },\n getGeometries: getGeometriesFromCache,\n propertyPanel(content, update, contents) {\n return {\n xExpression: /* @__PURE__ */ React.createElement(ctx.ExpressionEditor, { suggestionSources: ctx.math, validate: ctx.validateExpression, value: content.xExpression, setValue: (v) => update((c) => {\n if (isParametricEquationContent(c)) {\n c.xExpression = v;\n }\n }) }),\n yExpression: /* @__PURE__ */ React.createElement(ctx.ExpressionEditor, { suggestionSources: ctx.math, validate: ctx.validateExpression, value: content.yExpression, setValue: (v) => update((c) => {\n if (isParametricEquationContent(c)) {\n c.yExpression = v;\n }\n }) }),\n min: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.min, setValue: (v) => update((c) => {\n if (isParametricEquationContent(c)) {\n c.min = v;\n }\n }) }),\n max: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.max, setValue: (v) => update((c) => {\n if (isParametricEquationContent(c)) {\n c.max = v;\n }\n }) }),\n ...ctx.getStrokeContentPropertyPanel(content, update, contents),\n ...ctx.getSegmentCountContentPropertyPanel(content, update)\n };\n },\n isValid: (c, p) => ctx.validate(c, ParametricEquationContent, p),\n getRefIds,\n updateRefId(content, update) {\n const newAxisId = update(content.axisId);\n if (newAxisId !== void 0) {\n content.axisId = newAxisId;\n }\n ctx.updateStrokeRefIds(content, update);\n },\n deleteRefId: ctx.deleteStrokeRefIds\n };\n}\nfunction isParametricEquationContent(content) {\n return content.type === "parametric equation";\n}\nfunction getCommand(ctx) {\n const React = ctx.React;\n const icon = /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 100 100" }, /* @__PURE__ */ React.createElement("polyline", { points: "7,93 88,93", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polyline", { points: "7,12 7,93", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polyline", { points: "97,93 68,101 68,85", strokeWidth: "0", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "currentColor", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polyline", { points: "7,3 15,32 1,32", strokeWidth: "0", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "currentColor", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polyline", { points: "76,49 76,47 76,46 76,44 76,43 75,41 75,40 74,38 73,37 73,35 72,34 71,33 70,32 69,31 67,29 66,29 65,28 64,27 62,26 61,26 59,25 58,25 56,24 55,24 53,24 51,24 50,24 48,24 47,24 45,25 44,25 42,26 41,26 39,27 38,28 37,29 36,29 34,31 33,32 32,33 31,34 30,35 30,37 29,38 28,40 28,41 27,43 27,44 27,46 27,47 26,49 27,50 27,52 27,53 27,55 28,56 28,58 29,59 30,61 30,62 31,63 32,65 33,66 34,67 36,68 37,69 38,70 39,71 41,71 42,72 44,73 45,73 47,73 48,74 50,74 51,74 53,74 55,74 56,73 58,73 59,73 61,72 62,71 64,71 65,70 66,69 67,68 69,67 70,66 71,65 72,63 73,62 73,61 74,59 75,58 75,56 76,55 76,53 76,52 76,50 76,49", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", strokeOpacity: "1", fill: "none", stroke: "currentColor" }));\n return {\n name: "create parametric equation",\n icon,\n execute({ contents, selected }) {\n contents.push({\n type: "parametric equation",\n axisId: selected[0][0],\n min: 0,\n max: Math.PI * 2,\n xExpression: "25 + 25 * Math.cos(t)",\n yExpression: "25 + 25 * Math.sin(t)"\n });\n },\n contentSelectable: isCoordinateAxisContent,\n selectCount: 1\n };\n}\nexport {\n getCommand,\n getModel,\n isParametricEquationContent\n};\n','// dev/cad-editor/plugins/path-array.plugin.tsx\nfunction getModel(ctx) {\n const PathArrayContent = ctx.and(ctx.BaseContent("path array"), ctx.ContainerFields, {\n path: ctx.PartRef,\n length: ctx.number,\n aligned: ctx.optional(ctx.boolean)\n });\n const getRefIds = (content) => [...ctx.toRefId(content.path.id, true), ...ctx.toRefIds(content.contents)];\n const allContentsCache = new ctx.WeakmapCache2();\n const getAllContentsFromCache = (content, contents) => {\n const path = ctx.getRefPart(content.path, contents, (c) => !ctx.shallowEquals(c, content));\n if (!path) return [];\n return allContentsCache.get(content, path, () => {\n var _a, _b, _c, _d;\n const lines = (_b = (_a = ctx.getContentModel(path)) == null ? void 0 : _a.getGeometries) == null ? void 0 : _b.call(_a, path, contents).lines;\n if (!lines) return [];\n const boundings = [];\n for (const child of content.contents) {\n if (child) {\n const geometries = (_d = (_c = ctx.getContentModel(child)) == null ? void 0 : _c.getGeometries) == null ? void 0 : _d.call(_c, child, contents);\n if (geometries == null ? void 0 : geometries.bounding) {\n boundings.push(geometries.bounding);\n }\n }\n }\n const bounding = ctx.mergeBoundingsUnsafe(boundings);\n const center = ctx.getTwoPointCenter(bounding.start, bounding.end);\n const result = [];\n const lengths = lines.map((line) => ctx.getGeometryLineLength(line) || 0);\n const totalLength = lengths.reduce((p, c) => p + c, 0);\n for (let length = 0; length <= totalLength; length += content.length) {\n const r = ctx.getGeometryLinesPointAndTangentRadianByLength(lines, length, lengths);\n if (r) {\n result.push(...content.contents.map((child) => {\n var _a2, _b2;\n if (!child) return;\n const model = ctx.getContentModel(child);\n if (!model) return;\n const bounding2 = (_b2 = (_a2 = model.getGeometries) == null ? void 0 : _a2.call(model, child, contents)) == null ? void 0 : _b2.bounding;\n if (!bounding2) return;\n const move = model.move;\n if (!move) return;\n return ctx.produce(child, (draft) => {\n var _a3;\n move(draft, { x: -center.x + r.point.x, y: -center.y + r.point.y });\n if (content.aligned) {\n (_a3 = model.rotate) == null ? void 0 : _a3.call(model, draft, r.point, ctx.radianToAngle(r.radian), contents);\n }\n });\n }));\n }\n }\n return result;\n });\n };\n const getGeometries = (content, contents) => ctx.getContentsGeometries(content, contents, getRefIds, [content], (c) => getAllContentsFromCache(c, contents));\n const React = ctx.React;\n return {\n type: "path array",\n ...ctx.containerModel,\n move: ctx.getContainerMove,\n rotate: ctx.getContainerRotate,\n scale: ctx.getContainerScale,\n explode(content, contents) {\n return ctx.getContentsExplode(getAllContentsFromCache(content, contents));\n },\n break(content, points, contents) {\n return ctx.getContentsBreak(getAllContentsFromCache(content, contents), points, contents);\n },\n render(content, renderCtx) {\n return renderCtx.target.renderGroup(ctx.renderContainerChildren({ contents: getAllContentsFromCache(content, renderCtx.contents), variableValues: content.variableValues }, renderCtx));\n },\n getSnapPoints(content, contents) {\n return ctx.getContentsSnapPoints(content, contents, (c) => getAllContentsFromCache(c, contents));\n },\n getGeometries,\n propertyPanel(content, update, contents, { acquireContent }) {\n return {\n path: [\n /* @__PURE__ */ React.createElement(ctx.Button, { onClick: () => acquireContent({ count: 1, selectable: (v) => pathContentSelectable(ctx, ctx.getContentByIndex(contents, v), contents) }, (r) => update((c) => {\n if (isPathArrayContent(c)) {\n c.path = r[0];\n }\n })) }, "select"),\n typeof content.path.id === "number" ? /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.path.id, setValue: (v) => update((c) => {\n if (isPathArrayContent(c)) {\n c.path.id = v;\n }\n }) }) : void 0\n ],\n length: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.length, setValue: (v) => update((c) => {\n if (isPathArrayContent(c)) {\n c.length = v;\n }\n }) }),\n aligned: /* @__PURE__ */ React.createElement(ctx.BooleanEditor, { value: content.aligned === true, setValue: (v) => update((c) => {\n if (isPathArrayContent(c)) {\n c.aligned = v ? true : void 0;\n }\n }) }),\n ...ctx.getVariableValuesContentPropertyPanel(content, ctx.getContainerVariableNames(content), update)\n };\n },\n getRefIds,\n updateRefId(content, update) {\n if (content.path) {\n const newRefId = update(content.path.id);\n if (newRefId !== void 0) {\n content.path.id = newRefId;\n }\n }\n },\n isValid: (c, p) => ctx.validate(c, PathArrayContent, p)\n };\n}\nfunction isPathArrayContent(content) {\n return content.type === "path array";\n}\nfunction pathContentSelectable(ctx, content, contents) {\n var _a, _b;\n if (!content) return false;\n const geometries = (_b = (_a = ctx.getContentModel(content)) == null ? void 0 : _a.getGeometries) == null ? void 0 : _b.call(_a, content, contents);\n if (!geometries) return false;\n return geometries.lines.length > 0;\n}\nfunction getCommand(ctx) {\n function contentSelectable(content, contents) {\n return ctx.contentIsDeletable(content, contents);\n }\n const React = ctx.React;\n const icon = /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 100 100" }, /* @__PURE__ */ React.createElement("polyline", { points: "11,89 92,8", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", strokeOpacity: "1", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("circle", { cx: "11", cy: "89", r: "12", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", strokeOpacity: "1", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("circle", { cx: "36", cy: "64", r: "12", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", strokeOpacity: "1", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("circle", { cx: "61", cy: "39", r: "12", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", strokeOpacity: "1", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("circle", { cx: "86", cy: "14", r: "12", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", strokeOpacity: "1", fill: "none", stroke: "currentColor" }));\n return {\n name: "create path array",\n useCommand({ type, onEnd, acquireContent, selected, contents }) {\n const target = React.useRef();\n const path = React.useRef();\n const reset = () => {\n target.current = void 0;\n path.current = void 0;\n };\n React.useEffect(() => {\n if (!type) return;\n if (!target.current) {\n target.current = selected.map((s) => s.path);\n acquireContent(\n {\n count: 1,\n selectable: (v) => {\n const content = ctx.getContentByIndex(contents, v);\n if (!content) return false;\n return pathContentSelectable(ctx, content, contents);\n }\n },\n (r) => {\n path.current = r[0];\n }\n );\n } else if (path.current) {\n const children = target.current.map((c) => contents[c[0]]);\n const bounding = ctx.getContentsBounding(children, contents);\n if (bounding) {\n const length = ctx.getTwoPointsDistance(bounding.start, bounding.end);\n onEnd({\n updateContents(contents2) {\n if (target.current && path.current) {\n contents2.push({\n type: "path array",\n contents: children,\n path: path.current,\n length\n });\n ctx.deleteSelectedContents(contents2, target.current.map((c) => c[0]));\n }\n }\n });\n }\n reset();\n }\n }, [type]);\n return {\n onStart() {\n },\n reset\n };\n },\n contentSelectable,\n icon\n };\n}\nexport {\n getCommand,\n getModel,\n isPathArrayContent\n};\n','// dev/cad-editor/plugins/path.plugin.tsx\nfunction getModel(ctx) {\n const PathContent = ctx.and(ctx.BaseContent("path"), ctx.StrokeFields, ctx.FillFields, {\n commands: [ctx.PathCommand]\n });\n const getRefIds = (content) => ctx.getStrokeAndFillRefIds(content);\n function getPathGeometriesFromCache(content, contents) {\n const refs = new Set(ctx.iterateRefContents(getRefIds(content), contents, [content]));\n return ctx.getGeometriesFromCache(content, refs, () => {\n const lines = ctx.pathCommandsToGeometryLines(content.commands)[0];\n const points = ctx.getGeometryLinesPoints(lines);\n return {\n lines,\n bounding: ctx.getGeometryLinesBounding(lines),\n renderingLines: ctx.dashedPolylineToLines(points, content.dashArray),\n regions: ctx.hasFill(content) ? [\n {\n lines,\n points\n }\n ] : void 0\n };\n });\n }\n const React = ctx.React;\n return {\n type: "path",\n ...ctx.strokeModel,\n ...ctx.fillModel,\n move(content, offset) {\n for (const command of content.commands) {\n if (command.type !== "close") {\n ctx.movePoint(command.to, offset);\n }\n if (command.type === "arc") {\n ctx.movePoint(command.from, offset);\n } else if (command.type === "bezierCurve") {\n ctx.movePoint(command.cp1, offset);\n ctx.movePoint(command.cp2, offset);\n } else if (command.type === "quadraticCurve") {\n ctx.movePoint(command.cp, offset);\n }\n }\n },\n rotate(content, center, angle) {\n for (const command of content.commands) {\n if (command.type !== "close") {\n ctx.rotatePoint(command.to, center, angle);\n }\n if (command.type === "arc") {\n ctx.rotatePoint(command.from, center, angle);\n } else if (command.type === "bezierCurve") {\n ctx.rotatePoint(command.cp1, center, angle);\n ctx.rotatePoint(command.cp2, center, angle);\n } else if (command.type === "quadraticCurve") {\n ctx.rotatePoint(command.cp, center, angle);\n }\n }\n },\n scale(content, center, sx, sy) {\n for (const command of content.commands) {\n if (command.type !== "close") {\n ctx.scalePoint(command.to, center, sx, sy);\n }\n if (command.type === "arc") {\n ctx.scalePoint(command.from, center, sx, sy);\n } else if (command.type === "bezierCurve") {\n ctx.scalePoint(command.cp1, center, sx, sy);\n ctx.scalePoint(command.cp2, center, sx, sy);\n } else if (command.type === "quadraticCurve") {\n ctx.scalePoint(command.cp, center, sx, sy);\n }\n }\n },\n skew(content, center, sx, sy) {\n for (const command of content.commands) {\n if (command.type !== "close") {\n ctx.skewPoint(command.to, center, sx, sy);\n }\n if (command.type === "arc") {\n ctx.skewPoint(command.from, center, sx, sy);\n } else if (command.type === "bezierCurve") {\n ctx.skewPoint(command.cp1, center, sx, sy);\n ctx.skewPoint(command.cp2, center, sx, sy);\n } else if (command.type === "quadraticCurve") {\n ctx.skewPoint(command.cp, center, sx, sy);\n }\n }\n },\n mirror(content, line) {\n for (const command of content.commands) {\n if (command.type !== "close") {\n ctx.mirrorPoint(command.to, line);\n }\n if (command.type === "arc") {\n ctx.mirrorPoint(command.from, line);\n } else if (command.type === "bezierCurve") {\n ctx.mirrorPoint(command.cp1, line);\n ctx.mirrorPoint(command.cp2, line);\n } else if (command.type === "quadraticCurve") {\n ctx.mirrorPoint(command.cp, line);\n }\n }\n },\n break(content, intersectionPoints, contents) {\n const lines = getPathGeometriesFromCache(content, contents).lines;\n return ctx.breakGeometryLinesToPathCommands(lines, intersectionPoints);\n },\n offset(content, point, distance, contents, lineJoin) {\n const lines = getPathGeometriesFromCache(content, contents).lines;\n const newLines = ctx.trimGeometryLinesOffsetResult(ctx.getParallelGeometryLinesByDistancePoint(point, lines, distance, lineJoin), point);\n return newLines.map((n) => ({\n ...content,\n commands: ctx.geometryLineToPathCommands(n)\n }));\n },\n extend(content, point, contents) {\n const lines = getPathGeometriesFromCache(content, contents).lines;\n const newLines = ctx.produce(lines, (draft) => ctx.extendGeometryLines(draft, point));\n content.commands = ctx.geometryLineToPathCommands(newLines);\n },\n render(content, renderCtx) {\n const { options, target } = ctx.getStrokeFillRenderOptionsFromRenderContext(content, renderCtx);\n return target.renderPathCommands(content.commands, options);\n },\n renderIfSelected(content, { color, target, strokeWidth }) {\n const points = [];\n content.commands.forEach((c, i) => {\n const last = ctx.getPathCommandEndPoint(content.commands, i - 1);\n if (last) {\n if (c.type === "quadraticCurve") {\n points.push([last, c.cp, c.to]);\n } else if (c.type === "bezierCurve") {\n points.push([last, c.cp1, c.cp2, c.to]);\n } else if (c.type === "arc") {\n points.push([last, c.from, c.to]);\n } else if (c.type === "ellipseArc") {\n points.push([last, c.to]);\n }\n }\n });\n return target.renderPath(points, { strokeColor: color, dashArray: [4], strokeWidth });\n },\n getEditPoints(content) {\n return ctx.getEditPointsFromCache(content, () => {\n const editPoints = [];\n content.commands.forEach((command, i) => {\n if (command.type === "arc") {\n editPoints.push({\n ...command.from,\n cursor: "move",\n update(c, { cursor, start, scale }) {\n if (!isPathContent(c)) {\n return;\n }\n const m = c.commands[i];\n if (m.type !== "arc") {\n return;\n }\n m.from.x += cursor.x - start.x;\n m.from.y += cursor.y - start.y;\n return { assistentContents: [{ type: "line", dashArray: [4 / scale], points: [start, cursor] }] };\n }\n });\n } else if (command.type === "bezierCurve") {\n editPoints.push(\n {\n ...command.cp1,\n cursor: "move",\n update(c, { cursor, start, scale }) {\n if (!isPathContent(c)) {\n return;\n }\n const m = c.commands[i];\n if (m.type !== "bezierCurve") {\n return;\n }\n m.cp1.x += cursor.x - start.x;\n m.cp1.y += cursor.y - start.y;\n return { assistentContents: [{ type: "line", dashArray: [4 / scale], points: [start, cursor] }] };\n }\n },\n {\n ...command.cp2,\n cursor: "move",\n update(c, { cursor, start, scale }) {\n if (!isPathContent(c)) {\n return;\n }\n const m = c.commands[i];\n if (m.type !== "bezierCurve") {\n return;\n }\n m.cp2.x += cursor.x - start.x;\n m.cp2.y += cursor.y - start.y;\n return { assistentContents: [{ type: "line", dashArray: [4 / scale], points: [start, cursor] }] };\n }\n }\n );\n } else if (command.type === "quadraticCurve") {\n editPoints.push({\n ...command.cp,\n cursor: "move",\n update(c, { cursor, start, scale }) {\n if (!isPathContent(c)) {\n return;\n }\n const m = c.commands[i];\n if (m.type !== "quadraticCurve") {\n return;\n }\n m.cp.x += cursor.x - start.x;\n m.cp.y += cursor.y - start.y;\n return { assistentContents: [{ type: "line", dashArray: [4 / scale], points: [start, cursor] }] };\n }\n });\n }\n if (command.type !== "close") {\n editPoints.push({\n ...command.to,\n cursor: "move",\n update(c, { cursor, start, scale }) {\n if (!isPathContent(c)) {\n return;\n }\n const m = c.commands[i];\n if (m.type === "close") {\n return;\n }\n m.to.x += cursor.x - start.x;\n m.to.y += cursor.y - start.y;\n return { assistentContents: [{ type: "line", dashArray: [4 / scale], points: [start, cursor] }] };\n }\n });\n }\n });\n return {\n editPoints\n };\n });\n },\n getGeometries: getPathGeometriesFromCache,\n canSelectPart: true,\n propertyPanel(content, update, contents, { acquirePoint }) {\n return {\n commands: /* @__PURE__ */ React.createElement(\n ctx.ArrayEditor,\n {\n inline: true,\n ...ctx.getArrayEditorProps((v) => v.commands, { type: "line", to: { x: 0, y: 0 } }, (v) => update((c) => {\n if (isPathContent(c)) {\n v(c);\n }\n })),\n items: content.commands.map((f, i) => {\n const properties = {\n type: /* @__PURE__ */ React.createElement(ctx.EnumEditor, { select: true, value: f.type, enums: ["move", "line", "arc", "ellipseArc", "bezierCurve", "quadraticCurve", "close"], setValue: (v) => update((c) => {\n if (isPathContent(c)) {\n if (v === "move" || v === "line") {\n c.commands[i] = {\n type: v,\n to: { x: 0, y: 0 }\n };\n } else if (v === "arc") {\n c.commands[i] = {\n type: v,\n radius: 10,\n from: { x: 0, y: 0 },\n to: { x: 0, y: 0 }\n };\n } else if (v === "ellipseArc") {\n c.commands[i] = {\n type: v,\n rx: 10,\n ry: 10,\n angle: 0,\n sweep: true,\n largeArc: true,\n to: { x: 0, y: 0 }\n };\n } else if (v === "bezierCurve") {\n c.commands[i] = {\n type: v,\n cp1: { x: 0, y: 0 },\n cp2: { x: 0, y: 0 },\n to: { x: 0, y: 0 }\n };\n } else if (v === "quadraticCurve") {\n c.commands[i] = {\n type: v,\n cp: { x: 0, y: 0 },\n to: { x: 0, y: 0 }\n };\n } else if (v === "close") {\n c.commands[i] = {\n type: v\n };\n }\n }\n }) })\n };\n if (f.type === "arc") {\n properties.from = /* @__PURE__ */ React.createElement(ctx.ObjectEditor, { inline: true, properties: {\n from: /* @__PURE__ */ React.createElement(ctx.Button, { onClick: () => acquirePoint((p) => update((c) => {\n if (isPathContent(c)) {\n const m = c.commands[i];\n if (m.type === "arc") {\n m.from.x = p.x;\n m.from.y = p.y;\n }\n }\n })) }, "canvas"),\n x: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: f.from.x, setValue: (v) => update((c) => {\n if (isPathContent(c)) {\n const m = c.commands[i];\n if (m.type === "arc") {\n m.from.x = v;\n }\n }\n }) }),\n y: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: f.from.y, setValue: (v) => update((c) => {\n if (isPathContent(c)) {\n const m = c.commands[i];\n if (m.type === "arc") {\n m.from.y = v;\n }\n }\n }) })\n } });\n properties.radius = /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: f.radius, setValue: (v) => update((c) => {\n if (isPathContent(c)) {\n const m = c.commands[i];\n if (m.type === "arc") {\n m.radius = v;\n }\n }\n }) });\n } else if (f.type === "ellipseArc") {\n properties.rx = /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: f.rx, setValue: (v) => update((c) => {\n if (isPathContent(c)) {\n const m = c.commands[i];\n if (m.type === "ellipseArc") {\n m.rx = v;\n }\n }\n }) });\n properties.ry = /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: f.ry, setValue: (v) => update((c) => {\n if (isPathContent(c)) {\n const m = c.commands[i];\n if (m.type === "ellipseArc") {\n m.ry = v;\n }\n }\n }) });\n properties.angle = /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: f.angle, setValue: (v) => update((c) => {\n if (isPathContent(c)) {\n const m = c.commands[i];\n if (m.type === "ellipseArc") {\n m.angle = v;\n }\n }\n }) });\n properties.largeArc = /* @__PURE__ */ React.createElement(ctx.BooleanEditor, { value: f.largeArc, setValue: (v) => update((c) => {\n if (isPathContent(c)) {\n const m = c.commands[i];\n if (m.type === "ellipseArc") {\n m.largeArc = v;\n }\n }\n }) });\n properties.sweep = /* @__PURE__ */ React.createElement(ctx.BooleanEditor, { value: f.sweep, setValue: (v) => update((c) => {\n if (isPathContent(c)) {\n const m = c.commands[i];\n if (m.type === "ellipseArc") {\n m.sweep = v;\n }\n }\n }) });\n } else if (f.type === "bezierCurve") {\n properties.cp1 = /* @__PURE__ */ React.createElement(ctx.ObjectEditor, { inline: true, properties: {\n from: /* @__PURE__ */ React.createElement(ctx.Button, { onClick: () => acquirePoint((p) => update((c) => {\n if (isPathContent(c)) {\n const m = c.commands[i];\n if (m.type === "bezierCurve") {\n m.cp1.x = p.x;\n m.cp1.y = p.y;\n }\n }\n })) }, "canvas"),\n x: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: f.cp1.x, setValue: (v) => update((c) => {\n if (isPathContent(c)) {\n const m = c.commands[i];\n if (m.type === "bezierCurve") {\n m.cp1.x = v;\n }\n }\n }) }),\n y: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: f.cp1.y, setValue: (v) => update((c) => {\n if (isPathContent(c)) {\n const m = c.commands[i];\n if (m.type === "bezierCurve") {\n m.cp1.y = v;\n }\n }\n }) })\n } });\n properties.cp2 = /* @__PURE__ */ React.createElement(ctx.ObjectEditor, { inline: true, properties: {\n from: /* @__PURE__ */ React.createElement(ctx.Button, { onClick: () => acquirePoint((p) => update((c) => {\n if (isPathContent(c)) {\n const m = c.commands[i];\n if (m.type === "bezierCurve") {\n m.cp2.x = p.x;\n m.cp2.y = p.y;\n }\n }\n })) }, "canvas"),\n x: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: f.cp2.x, setValue: (v) => update((c) => {\n if (isPathContent(c)) {\n const m = c.commands[i];\n if (m.type === "bezierCurve") {\n m.cp2.x = v;\n }\n }\n }) }),\n y: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: f.cp2.y, setValue: (v) => update((c) => {\n if (isPathContent(c)) {\n const m = c.commands[i];\n if (m.type === "bezierCurve") {\n m.cp2.y = v;\n }\n }\n }) })\n } });\n } else if (f.type === "quadraticCurve") {\n properties.cp = /* @__PURE__ */ React.createElement(ctx.ObjectEditor, { inline: true, properties: {\n from: /* @__PURE__ */ React.createElement(ctx.Button, { onClick: () => acquirePoint((p) => update((c) => {\n if (isPathContent(c)) {\n const m = c.commands[i];\n if (m.type === "quadraticCurve") {\n m.cp.x = p.x;\n m.cp.y = p.y;\n }\n }\n })) }, "canvas"),\n x: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: f.cp.x, setValue: (v) => update((c) => {\n if (isPathContent(c)) {\n const m = c.commands[i];\n if (m.type === "quadraticCurve") {\n m.cp.x = v;\n }\n }\n }) }),\n y: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: f.cp.y, setValue: (v) => update((c) => {\n if (isPathContent(c)) {\n const m = c.commands[i];\n if (m.type === "quadraticCurve") {\n m.cp.y = v;\n }\n }\n }) })\n } });\n }\n if (f.type !== "close") {\n properties.to = /* @__PURE__ */ React.createElement(ctx.ObjectEditor, { inline: true, properties: {\n from: /* @__PURE__ */ React.createElement(ctx.Button, { onClick: () => acquirePoint((p) => update((c) => {\n if (isPathContent(c)) {\n const m = c.commands[i];\n if (m.type !== "close") {\n m.to.x = p.x;\n m.to.y = p.y;\n }\n }\n })) }, "canvas"),\n x: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: f.to.x, setValue: (v) => update((c) => {\n if (isPathContent(c)) {\n const m = c.commands[i];\n if (m.type !== "close") {\n m.to.x = v;\n }\n }\n }) }),\n y: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: f.to.y, setValue: (v) => update((c) => {\n if (isPathContent(c)) {\n const m = c.commands[i];\n if (m.type !== "close") {\n m.to.y = v;\n }\n }\n }) })\n } });\n }\n return /* @__PURE__ */ React.createElement(ctx.ObjectEditor, { inline: true, properties });\n })\n }\n ),\n ...ctx.getStrokeContentPropertyPanel(content, update, contents),\n ...ctx.getFillContentPropertyPanel(content, update, contents)\n };\n },\n isValid: (c, p) => ctx.validate(c, PathContent, p),\n getRefIds,\n updateRefId: ctx.updateStrokeAndFillRefIds,\n deleteRefId: ctx.deleteStrokeAndFillRefIds,\n reverse: (content, contents) => ({\n ...content,\n commands: ctx.geometryLineToPathCommands(ctx.reverseGeometryLines(getPathGeometriesFromCache(content, contents).lines))\n })\n };\n}\nfunction isPathContent(content) {\n return content.type === "path";\n}\nfunction getCommand(ctx) {\n const React = ctx.React;\n const icon = /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 100 100" }, /* @__PURE__ */ React.createElement("path", { d: " M 8 8 L 40 7 A 50 50 0 0 1 91 57 Q 91 91, 17 90 C 50 72, 50 31, 8 24 Z", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }));\n return {\n name: "create path",\n hotkey: "P",\n icon,\n useCommand({ onEnd, type, scale, strokeStyleId, fillStyleId }) {\n const { path, controlPoint, controlPoint2, preview, onClick, onMove, input, setInputType, cursorPosition, reset } = ctx.usePathClickCreate(\n type === "create path",\n (c) => onEnd({\n updateContents: (contents) => contents.push({\n type: "path",\n strokeStyleId,\n fillStyleId,\n commands: c\n })\n })\n );\n const assistentContents = [];\n if (preview.length > 1) {\n assistentContents.push({\n type: "path",\n strokeStyleId,\n fillStyleId,\n commands: preview\n });\n }\n const last = ctx.getPathCommandEndPoint(path, path.length - 1);\n if (last) {\n if (controlPoint) {\n assistentContents.push({ type: "line", points: [last, controlPoint], dashArray: [4 / scale] });\n if (controlPoint2) {\n assistentContents.push({ type: "line", points: [controlPoint, controlPoint2], dashArray: [4 / scale] });\n if (cursorPosition) {\n assistentContents.push({ type: "line", points: [controlPoint2, cursorPosition], dashArray: [4 / scale] });\n }\n } else {\n if (cursorPosition) {\n assistentContents.push({ type: "line", points: [controlPoint, cursorPosition], dashArray: [4 / scale] });\n }\n }\n } else if (cursorPosition) {\n assistentContents.push({ type: "line", points: [last, cursorPosition], dashArray: [4 / scale] });\n }\n }\n return {\n onStart: onClick,\n input,\n onMove,\n reset,\n subcommand: type === "create path" ? /* @__PURE__ */ React.createElement("span", null, ["line", "arc", "bezierCurve", "quadraticCurve", "close"].map((m) => /* @__PURE__ */ React.createElement("button", { key: m, onClick: () => setInputType(m), style: { position: "relative" } }, m))) : void 0,\n assistentContents\n };\n },\n selectCount: 0\n };\n}\nexport {\n getCommand,\n getModel,\n isPathContent\n};\n','// dev/cad-editor/plugins/pen.plugin.tsx\nfunction getModel(ctx) {\n const PenContent = ctx.and(ctx.BaseContent("pen"), ctx.StrokeFields, {\n points: ctx.minItems(2, [ctx.Position])\n });\n const getRefIds = (content) => ctx.getStrokeRefIds(content);\n function getGeometries(content, contents) {\n const refs = new Set(ctx.iterateRefContents(getRefIds(content), contents, [content]));\n return ctx.getGeometriesFromCache(content, refs, () => {\n const lines = Array.from(ctx.iteratePolylineLines(content.points));\n return {\n lines,\n bounding: ctx.getPointsBounding(content.points),\n renderingLines: ctx.dashedPolylineToLines(content.points, content.dashArray)\n };\n });\n }\n return {\n type: "pen",\n ...ctx.strokeModel,\n move(content, offset) {\n for (const point of content.points) {\n ctx.movePoint(point, offset);\n }\n },\n rotate(content, center, angle) {\n for (const point of content.points) {\n ctx.rotatePoint(point, center, angle);\n }\n },\n scale(content, center, sx, sy) {\n for (const point of content.points) {\n ctx.scalePoint(point, center, sx, sy);\n }\n },\n skew(content, center, sx, sy) {\n for (const point of content.points) {\n ctx.skewPoint(point, center, sx, sy);\n }\n },\n mirror(content, line) {\n for (const point of content.points) {\n ctx.mirrorPoint(point, line);\n }\n },\n render(content, renderCtx) {\n const { options, target } = ctx.getStrokeRenderOptionsFromRenderContext(content, renderCtx);\n return target.renderPolyline(content.points, options);\n },\n getGeometries,\n propertyPanel(content, update, contents) {\n return ctx.getStrokeContentPropertyPanel(content, update, contents);\n },\n isValid: (c, p) => ctx.validate(c, PenContent, p),\n getRefIds,\n updateRefId: ctx.updateStrokeRefIds,\n deleteRefId: ctx.deleteStrokeRefIds,\n reverse: (content) => ({\n ...content,\n points: content.points.slice().reverse()\n })\n };\n}\nfunction isPenContent(content) {\n return content.type === "pen";\n}\nfunction getCommand(ctx) {\n const React = ctx.React;\n const icon = /* @__PURE__ */ React.createElement("svg", { viewBox: "0 0 1024 1024", xmlns: "http://www.w3.org/2000/svg" }, /* @__PURE__ */ React.createElement("path", { d: "m199.04 672.64 193.984 112 224-387.968-193.92-112-224 388.032zm-23.872 60.16 32.896 148.288 144.896-45.696L175.168 732.8zM455.04 229.248l193.92 112 56.704-98.112-193.984-112-56.64 98.112zM104.32 708.8l384-665.024 304.768 175.936L409.152 884.8h.064l-248.448 78.336L104.32 708.8zm384 254.272v-64h448v64h-448z", fill: "currentColor" }));\n return {\n name: "create pen",\n useCommand({ onEnd, type, strokeStyleId }) {\n const { reset, points, onClick, onMove } = ctx.usePenClickCreate(\n type === "create pen",\n () => onEnd({\n updateContents: (contents) => contents.push({ points, strokeStyleId, type: "pen" })\n })\n );\n const assistentContents = [];\n if (points.length > 1) {\n assistentContents.push({ points, strokeStyleId, type: "pen" });\n }\n return {\n onStart: onClick,\n onMove,\n assistentContents,\n reset\n };\n },\n selectCount: 0,\n icon\n };\n}\nexport {\n getCommand,\n getModel,\n isPenContent\n};\n','// dev/cad-editor/plugins/pline.plugin.tsx\nfunction getModel(ctx) {\n const PlineContent = ctx.and(ctx.BaseContent("pline"), ctx.StrokeFields, ctx.FillFields, {\n points: ctx.minItems(2, [{ point: ctx.Position, bulge: ctx.number }]),\n closed: ctx.optional(ctx.boolean)\n });\n const getRefIds = (content) => ctx.getStrokeAndFillRefIds(content);\n const geometriesCache = new ctx.WeakmapValuesCache();\n function getPlineGeometries(content, contents) {\n const refs = new Set(ctx.iterateRefContents(getRefIds(content), contents, [content]));\n return geometriesCache.get(content, refs, () => {\n const lines = [];\n const centers = [];\n const middles = [];\n for (let i = 0; i < content.points.length; i++) {\n const p = content.points[i];\n if (i === content.points.length - 1) {\n if (content.closed) {\n lines.push(ctx.getGeometryLineByStartEndBulge(p.point, content.points[0].point, p.bulge));\n }\n } else {\n lines.push(ctx.getGeometryLineByStartEndBulge(p.point, content.points[i + 1].point, p.bulge));\n }\n }\n for (const line of lines) {\n if (Array.isArray(line)) {\n middles.push(ctx.getTwoPointCenter(...line));\n } else if (line.type === "arc") {\n centers.push(line.curve);\n middles.push(ctx.getArcPointAtAngle(line.curve, ctx.getTwoNumberCenter(line.curve.startAngle, ctx.getFormattedEndAngle(line.curve))));\n }\n }\n const points = ctx.getGeometryLinesPoints(lines);\n return {\n lines,\n points,\n centers,\n middles,\n bounding: ctx.getGeometryLinesBounding(lines),\n renderingLines: ctx.dashedPolylineToLines(points, content.dashArray),\n regions: ctx.hasFill(content) ? [\n {\n lines,\n points\n }\n ] : void 0\n };\n });\n }\n const React = ctx.React;\n return {\n type: "pline",\n ...ctx.strokeModel,\n ...ctx.fillModel,\n move(content, offset) {\n for (const point of content.points) {\n ctx.movePoint(point.point, offset);\n }\n },\n rotate(content, center, angle) {\n for (const point of content.points) {\n ctx.rotatePoint(point.point, center, angle);\n }\n },\n scale(content, center, sx, sy) {\n for (const point of content.points) {\n ctx.scalePoint(point.point, center, sx, sy);\n }\n },\n skew(content, center, sx, sy) {\n for (const point of content.points) {\n ctx.skewPoint(point.point, center, sx, sy);\n }\n },\n mirror(content, line) {\n for (const point of content.points) {\n ctx.mirrorPoint(point.point, line);\n point.bulge *= -1;\n }\n },\n break(content, intersectionPoints, contents) {\n const { lines } = getPlineGeometries(content, contents);\n const newLines = ctx.breakGeometryLines(lines, intersectionPoints);\n return newLines.map((line) => ctx.geometryLinesToPline(line));\n },\n explode(content, contents) {\n const { lines } = getPlineGeometries(content, contents);\n return lines.map((line) => ctx.geometryLineToContent(line));\n },\n offset(content, point, distance, contents, lineJoin) {\n const { lines } = getPlineGeometries(content, contents);\n const newLines = ctx.trimGeometryLinesOffsetResult(ctx.getParallelGeometryLinesByDistancePoint(point, lines, distance, lineJoin), point);\n return newLines.map((n) => ctx.geometryLinesToPline(n));\n },\n join(content, target, contents) {\n var _a, _b, _c;\n const { lines } = getPlineGeometries(content, contents);\n const line2 = (_c = (_b = (_a = ctx.getContentModel(target)) == null ? void 0 : _a.getGeometries) == null ? void 0 : _b.call(_a, target, contents)) == null ? void 0 : _c.lines;\n if (!line2) return;\n const newLines = ctx.mergeGeometryLines(lines, line2);\n if (!newLines) return;\n return ctx.geometryLinesToPline(newLines);\n },\n extend(content, point, contents) {\n if (content.closed) return;\n const { lines } = getPlineGeometries(content, contents);\n const first = lines[0], last = lines[lines.length - 1];\n if (Array.isArray(first)) {\n if (ctx.pointIsOnRay(point, { ...first[0], angle: ctx.radianToAngle(ctx.getTwoPointsRadian(...first)) })) {\n content.points[0].point = point;\n }\n } else if (first.type === "arc") {\n if (ctx.pointIsOnCircle(point, first.curve)) {\n content.points[0].point = point;\n content.points[0].bulge = ctx.getArcBulge({ ...first.curve, startAngle: ctx.radianToAngle(ctx.getCircleRadian(point, first.curve)) }, point);\n }\n }\n if (Array.isArray(last)) {\n if (ctx.pointIsOnRay(point, { ...last[1], angle: ctx.radianToAngle(ctx.getTwoPointsRadian(last[1], last[0])) })) {\n content.points[content.points.length - 1].point = point;\n }\n } else if (last.type === "arc") {\n if (ctx.pointIsOnCircle(point, last.curve)) {\n content.points[content.points.length - 1].point = point;\n content.points[content.points.length - 2].bulge = ctx.getArcBulge({ ...last.curve, endAngle: ctx.radianToAngle(ctx.getCircleRadian(point, last.curve)) }, void 0, point);\n }\n }\n },\n render(content, renderCtx) {\n const { options, target } = ctx.getStrokeFillRenderOptionsFromRenderContext(content, renderCtx);\n return target.renderPath([getPlineGeometries(content, renderCtx.contents).points], options);\n },\n getOperatorRenderPosition(content) {\n return content.points[0].point;\n },\n getEditPoints(content, contents) {\n return ctx.getEditPointsFromCache(content, () => {\n const { middles } = getPlineGeometries(content, contents);\n const endpoints = content.points.map((p, i) => ({\n x: p.point.x,\n y: p.point.y,\n cursor: "move",\n type: "move",\n update(c, { cursor, start, scale }) {\n if (!isPlineContent(c)) {\n return;\n }\n c.points[i].point.x += cursor.x - start.x;\n c.points[i].point.y += cursor.y - start.y;\n return { assistentContents: [{ type: "line", dashArray: [4 / scale], points: [p.point, cursor] }] };\n },\n menu: [\n {\n title: "Remove",\n execute(draft) {\n if (isPlineContent(draft)) {\n draft.points.splice(i, 1);\n }\n }\n },\n ...i === 0 || i === content.points.length - 1 ? [{\n title: "Add",\n update(c, { cursor, scale }) {\n if (!isPlineContent(c)) {\n return;\n }\n c.points.splice(i === 0 ? 0 : i + 1, 0, { point: { x: cursor.x, y: cursor.y }, bulge: 0 });\n return { assistentContents: [{ type: "line", dashArray: [4 / scale], points: [p.point, cursor] }] };\n }\n }] : []\n ]\n }));\n const midpoints = middles.map((p, i) => ({\n x: p.x,\n y: p.y,\n cursor: "move",\n type: "move",\n update(c, { cursor, start, scale }) {\n if (!isPlineContent(c)) {\n return;\n }\n const j = i === content.points.length - 1 ? 0 : i + 1;\n if (ctx.isZero(content.points[i].bulge)) {\n c.points[i].point.x += cursor.x - start.x;\n c.points[i].point.y += cursor.y - start.y;\n c.points[j].point.x += cursor.x - start.x;\n c.points[j].point.y += cursor.y - start.y;\n } else {\n const bulge = ctx.getArcBulgeByStartEndPoint(content.points[i].point, content.points[j].point, cursor);\n if (bulge !== void 0) {\n c.points[i].bulge = bulge;\n }\n }\n return { assistentContents: [{ type: "line", dashArray: [4 / scale], points: [p, cursor] }] };\n },\n menu: [\n {\n title: "Add",\n update(c, { cursor, scale }) {\n if (!isPlineContent(c)) {\n return;\n }\n c.points.splice(i + 1, 0, { point: { x: cursor.x, y: cursor.y }, bulge: 0 });\n return { assistentContents: [{ type: "line", dashArray: [4 / scale], points: [p, cursor] }] };\n }\n },\n ctx.isZero(content.points[i].bulge) ? {\n title: "To Arc",\n update(c, { cursor, scale }) {\n if (!isPlineContent(c)) {\n return;\n }\n const j = i === content.points.length - 1 ? 0 : i + 1;\n const bulge = ctx.getArcBulgeByStartEndPoint(content.points[i].point, content.points[j].point, cursor);\n if (bulge !== void 0) {\n c.points[i].bulge = bulge;\n }\n return { assistentContents: [{ type: "line", dashArray: [4 / scale], points: [p, cursor] }] };\n }\n } : {\n title: "To Line",\n execute(draft) {\n if (isPlineContent(draft)) {\n draft.points[i].bulge = 0;\n }\n }\n }\n ]\n }));\n return {\n editPoints: [\n ...endpoints,\n ...midpoints\n ]\n };\n });\n },\n getSnapPoints(content, contents) {\n const { centers, middles } = getPlineGeometries(content, contents);\n return ctx.getSnapPointsFromCache(content, () => {\n return [\n ...content.points.map((p) => ({ ...p.point, type: "endpoint" })),\n ...centers.map((p) => ({ ...p, type: "center" })),\n ...middles.map((p) => ({ ...p, type: "midpoint" }))\n ];\n });\n },\n getGeometries: getPlineGeometries,\n canSelectPart: true,\n propertyPanel(content, update, contents, { acquirePoint }) {\n var _a;\n return {\n points: /* @__PURE__ */ React.createElement(\n ctx.ArrayEditor,\n {\n inline: true,\n ...ctx.getArrayEditorProps((v) => v.points, { point: { x: 0, y: 0 }, bulge: 0 }, (v) => update((c) => {\n if (isPlineContent(c)) {\n v(c);\n }\n })),\n items: content.points.map((f, i) => /* @__PURE__ */ React.createElement(\n ctx.ObjectEditor,\n {\n inline: true,\n properties: {\n from: /* @__PURE__ */ React.createElement(ctx.Button, { onClick: () => acquirePoint((p) => update((c) => {\n if (isPlineContent(c)) {\n c.points[i].point.x = p.x;\n c.points[i].point.y = p.y;\n }\n })) }, "canvas"),\n x: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: f.point.x, setValue: (v) => update((c) => {\n if (isPlineContent(c)) {\n c.points[i].point.x = v;\n }\n }) }),\n y: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: f.point.y, setValue: (v) => update((c) => {\n if (isPlineContent(c)) {\n c.points[i].point.y = v;\n }\n }) }),\n bulge: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: f.bulge, setValue: (v) => update((c) => {\n if (isPlineContent(c)) {\n c.points[i].bulge = v;\n }\n }) }),\n radius: f.bulge ? /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: ctx.getArcByStartEndBulge(f.point, (content.points[i + 1] || content.points[0]).point, f.bulge).r, setValue: (v) => update((c) => {\n if (isPlineContent(c)) {\n c.points[i].bulge = ctx.getArcBulgeByStartEndRadius(f.point, (content.points[i + 1] || content.points[0]).point, v, f.bulge) || 0;\n }\n }) }) : []\n }\n }\n ))\n }\n ),\n closed: /* @__PURE__ */ React.createElement(ctx.BooleanEditor, { value: (_a = content.closed) != null ? _a : false, setValue: (v) => update((c) => {\n if (isPlineContent(c)) {\n c.closed = v;\n }\n }) }),\n ...ctx.getStrokeContentPropertyPanel(content, update, contents),\n ...ctx.getFillContentPropertyPanel(content, update, contents)\n };\n },\n isValid: (c, p) => ctx.validate(c, PlineContent, p),\n getRefIds,\n updateRefId: ctx.updateStrokeAndFillRefIds,\n deleteRefId: ctx.deleteStrokeAndFillRefIds,\n reverse: (content) => ({\n ...content,\n points: content.points.slice().reverse().map((p, i, points) => ({\n point: p.point,\n bulge: -points[i === points.length - 1 ? 0 : i + 1].bulge\n }))\n }),\n isPointIn: (content, point, contents) => ctx.pointInPolygon(point, getPlineGeometries(content, contents).points)\n };\n}\nfunction isPlineContent(content) {\n return content.type === "pline";\n}\nfunction getCommand(ctx) {\n const React = ctx.React;\n const icon = /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 100 100" }, /* @__PURE__ */ React.createElement("polyline", { points: "6,92 56,92", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", strokeOpacity: "1", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("path", { d: "M 54 15 A 38 38 0 0 1 55 92", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fillOpacity: "1", strokeOpacity: "1", fill: "none", stroke: "currentColor" }));\n return {\n name: "create pline",\n useCommand({ onEnd, scale, type, strokeStyleId, fillStyleId }) {\n const { line, onClick, onMove, input, inputMode, lastPosition, reset, positions } = ctx.useLineClickCreate(\n type === "create pline",\n (c) => onEnd({\n updateContents: (contents) => contents.push({ points: c.map((p) => ({ point: p, bulge: 0 })), strokeStyleId, fillStyleId, type: "pline" })\n })\n );\n const assistentContents = [];\n if (line && line.length > 1) {\n const start = line[line.length - 2];\n const end = line[line.length - 1];\n const r = ctx.getTwoPointsDistance(start, end);\n const angle = ctx.radianToAngle(ctx.getTwoPointsRadian(end, start));\n assistentContents.push(\n {\n type: "arc",\n x: start.x,\n y: start.y,\n r,\n dashArray: [4 / scale],\n startAngle: angle > 180 || angle < 0 ? angle : 0,\n endAngle: angle > 180 || angle < 0 ? 0 : angle\n },\n {\n type: "line",\n dashArray: [4 / scale],\n points: [start, { x: start.x + r, y: start.y }]\n },\n ...ctx.getAssistentText(\n r.toFixed(2),\n 16 / scale,\n (start.x + end.x) / 2 - 20,\n (start.y + end.y) / 2 + 4,\n inputMode === "length" ? 16711680 : 16764108\n ),\n ...ctx.getAssistentText(\n `${angle.toFixed(1)}\\xB0`,\n 16 / scale,\n end.x + 10,\n end.y - 10,\n inputMode === "angle" ? 16711680 : 16764108\n )\n );\n }\n if (line) {\n assistentContents.push({ points: line, strokeStyleId, fillStyleId, type: "polyline" });\n }\n return {\n onStart: onClick,\n input,\n onMove,\n assistentContents,\n lastPosition,\n reset,\n subcommand: type === "create pline" && positions.length > 2 ? /* @__PURE__ */ React.createElement("span", null, /* @__PURE__ */ React.createElement(\n "button",\n {\n onClick: () => {\n onEnd({\n updateContents: (contents) => contents.push({ points: positions, type: "polygon" })\n });\n reset();\n },\n style: { position: "relative" }\n },\n "close"\n )) : void 0\n };\n },\n selectCount: 0,\n icon\n };\n}\nexport {\n getCommand,\n getModel,\n isPlineContent\n};\n','// dev/cad-editor/plugins/point.plugin.tsx\nfunction getModel(ctx) {\n const PointContent = ctx.and(ctx.BaseContent("point"), ctx.Position);\n function getPointGeometries(content) {\n return ctx.getGeometriesFromCache(content, /* @__PURE__ */ new Set(), () => {\n return {\n lines: [[content, content]],\n bounding: ctx.getPointsBounding([content]),\n renderingLines: [],\n regions: []\n };\n });\n }\n const React = ctx.React;\n return {\n type: "point",\n move(content, offset) {\n ctx.movePoint(content, offset);\n },\n rotate(content, center, angle) {\n ctx.rotatePoint(content, center, angle);\n },\n scale(content, center, sx, sy) {\n ctx.scalePoint(content, center, sx, sy);\n },\n skew(content, center, sx, sy) {\n ctx.skewPoint(content, center, sx, sy);\n },\n mirror(content, line) {\n ctx.mirrorPoint(content, line);\n },\n render(content, { target, isHoveringOrSelected, transformStrokeWidth }) {\n const strokeWidth = transformStrokeWidth(1);\n const fuzzy = isHoveringOrSelected && strokeWidth !== 1;\n const result = target.renderCircle(content.x, content.y, 1, { fillColor: 0 });\n if (fuzzy) {\n return target.renderGroup([\n target.renderCircle(content.x, content.y, strokeWidth, {\n fillColor: 0,\n strokeWidth: 0,\n fillOpacity: ctx.fuzzyStyle.strokeOpacity\n }),\n result\n ]);\n }\n return result;\n },\n getOperatorRenderPosition(content) {\n return content;\n },\n getEditPoints(content) {\n return ctx.getEditPointsFromCache(content, () => {\n return {\n editPoints: [\n {\n x: content.x,\n y: content.y,\n cursor: "move",\n type: "move",\n update(c, { cursor, start, scale }) {\n if (!isPointContent(c)) {\n return;\n }\n c.x += cursor.x - start.x;\n c.y += cursor.y - start.y;\n return { assistentContents: [{ type: "line", dashArray: [4 / scale], points: [content, cursor] }] };\n }\n }\n ]\n };\n });\n },\n getSnapPoints(content) {\n return ctx.getSnapPointsFromCache(content, () => [{ x: content.x, y: content.y, type: "endpoint" }]);\n },\n getGeometries: getPointGeometries,\n propertyPanel(content, update, _, { acquirePoint }) {\n return {\n from: /* @__PURE__ */ React.createElement(ctx.Button, { onClick: () => acquirePoint((p) => update((c) => {\n if (isPointContent(c)) {\n c.x = p.x;\n c.y = p.y;\n }\n })) }, "canvas"),\n x: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.x, setValue: (v) => update((c) => {\n if (isPointContent(c)) {\n c.x = v;\n }\n }) }),\n y: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.y, setValue: (v) => update((c) => {\n if (isPointContent(c)) {\n c.y = v;\n }\n }) })\n };\n },\n isValid: (c, p) => ctx.validate(c, PointContent, p)\n };\n}\nfunction isPointContent(content) {\n return content.type === "point";\n}\nfunction getCommand(ctx) {\n const React = ctx.React;\n const icon = /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 100 100" }, /* @__PURE__ */ React.createElement("circle", { cx: "44", cy: "48", r: "4", strokeWidth: "2", vectorEffect: "non-scaling-stroke", fill: "none", stroke: "currentColor" }));\n return [\n {\n name: "create point",\n icon,\n useCommand({ type, onEnd }) {\n const [point, setPoint] = React.useState();\n const reset = () => {\n setPoint(void 0);\n };\n const assistentContents = [];\n if (point) {\n assistentContents.push({ ...point, type: "point" });\n }\n return {\n onStart: (p) => {\n onEnd({\n updateContents: (contents) => contents.push({ x: p.x, y: p.y, type: "point" })\n });\n },\n onMove(p) {\n if (!type) return;\n setPoint(p);\n },\n assistentContents,\n reset\n };\n },\n selectCount: 0\n }\n ];\n}\nexport {\n getCommand,\n getModel,\n isPointContent\n};\n','// dev/cad-editor/plugins/polar-array.plugin.tsx\nfunction getModel(ctx) {\n const PolarArrayContent = ctx.and(ctx.BaseContent("polar array"), ctx.ContainerFields, {\n center: ctx.Position,\n itemCount: ctx.number,\n itemAngle: ctx.number,\n rowCount: ctx.number,\n rowSpacing: ctx.number\n });\n const getRefIds = (content) => ctx.toRefIds(content.contents);\n const getAllContentsFromCache = (content, contents) => {\n return ctx.allContentsCache.get(content, () => {\n const result = [];\n const bounding = ctx.getContentsBounding(content.contents, contents);\n if (!bounding) return result;\n const base = {\n x: ctx.getTwoNumberCenter(bounding.start.x, bounding.end.x),\n y: ctx.getTwoNumberCenter(bounding.start.y, bounding.end.y)\n };\n for (let i = 0; i < content.rowCount; i++) {\n for (let j = 0; j < content.itemCount; j++) {\n const angle = j * content.itemAngle;\n if (i === 0 && j === 0) {\n result.push(...content.contents);\n } else {\n result.push(...content.contents.map((c) => {\n if (!c) return;\n const model = ctx.getContentModel(c);\n const rotate = model == null ? void 0 : model.rotate;\n if (!rotate) return;\n const move = model.move;\n if (!move) return;\n return ctx.produce(c, (draft) => {\n if (i !== 0) {\n const center = ctx.getPointByLengthAndDirection(base, -i * content.rowSpacing, content.center);\n move(draft, {\n x: center.x - base.x,\n y: center.y - base.y\n });\n }\n rotate(draft, content.center, angle, contents);\n });\n }));\n }\n }\n }\n return result;\n });\n };\n const getGeometries = (content, contents) => ctx.getContentsGeometries(content, contents, getRefIds, [content], (c) => getAllContentsFromCache(c, contents));\n const React = ctx.React;\n return {\n type: "polar array",\n ...ctx.containerModel,\n move(content, offset) {\n ctx.getContainerMove(content, offset);\n ctx.movePoint(content.center, offset);\n },\n rotate(content, center, angle, contents) {\n ctx.rotatePoint(content.center, center, angle);\n content.contents.forEach((c) => {\n var _a, _b;\n if (!c) return;\n (_b = (_a = ctx.getContentModel(c)) == null ? void 0 : _a.rotate) == null ? void 0 : _b.call(_a, c, center, angle, contents);\n });\n },\n scale(content, center, sx, sy, contents) {\n ctx.scalePoint(content.center, center, sx, sy);\n ctx.getContainerScale(content, center, sx, sy, contents);\n },\n skew(content, center, sx, sy, contents) {\n ctx.skewPoint(content.center, center, sx, sy);\n ctx.getContainerSkew(content, center, sx, sy, contents);\n },\n explode(content, contents) {\n return ctx.getContentsExplode(getAllContentsFromCache(content, contents));\n },\n break(content, points, contents) {\n return ctx.getContentsBreak(getAllContentsFromCache(content, contents), points, contents);\n },\n render(content, renderCtx) {\n return renderCtx.target.renderGroup(ctx.renderContainerChildren({ contents: getAllContentsFromCache(content, renderCtx.contents), variableValues: content.variableValues }, renderCtx));\n },\n getEditPoints(content, contents) {\n return ctx.getEditPointsFromCache(content, () => {\n const bounding = ctx.getContentsBounding(content.contents, contents);\n if (!bounding) {\n return { editPoints: [] };\n }\n const base = {\n x: ctx.getTwoNumberCenter(bounding.start.x, bounding.end.x),\n y: ctx.getTwoNumberCenter(bounding.start.y, bounding.end.y)\n };\n const editPoints = [\n {\n ...base,\n cursor: "move",\n update(c, { cursor, start, scale }) {\n if (!isPolarArrayContent(c)) {\n return;\n }\n ctx.getContainerMove(c, {\n x: cursor.x - start.x,\n y: cursor.y - start.y\n });\n return { assistentContents: [{ type: "line", dashArray: [4 / scale], points: [start, cursor] }] };\n }\n },\n {\n x: content.center.x,\n y: content.center.y,\n cursor: "move",\n update(c, { cursor, start, scale }) {\n if (!isPolarArrayContent(c)) {\n return;\n }\n c.center.x += cursor.x - start.x;\n c.center.y += cursor.y - start.y;\n return { assistentContents: [{ type: "line", dashArray: [4 / scale], points: [start, cursor] }] };\n }\n }\n ];\n if (content.rowCount > 1) {\n const p = ctx.getPointByLengthAndDirection(base, -content.rowSpacing, content.center);\n editPoints.push({\n ...p,\n cursor: "move",\n update(c, { cursor, start, scale }) {\n if (!isPolarArrayContent(c)) {\n return;\n }\n c.rowSpacing = ctx.getTwoPointsDistance(cursor, base);\n return { assistentContents: [{ type: "line", dashArray: [4 / scale], points: [start, cursor] }] };\n }\n });\n }\n if (content.rowCount > 2) {\n const p = ctx.getPointByLengthAndDirection(base, -(content.rowCount - 1) * content.rowSpacing, content.center);\n editPoints.push({\n ...p,\n cursor: "move",\n update(c, { cursor, start, scale }) {\n if (!isPolarArrayContent(c)) {\n return;\n }\n c.rowCount = Math.round(ctx.getTwoPointsDistance(cursor, base) / c.rowSpacing) + 1;\n return { assistentContents: [{ type: "line", dashArray: [4 / scale], points: [start, cursor] }] };\n }\n });\n }\n if (content.itemCount > 1) {\n const p = ctx.rotatePositionByCenter(base, content.center, -content.itemAngle);\n editPoints.push({\n ...p,\n cursor: "move",\n update(c, { cursor, start, scale }) {\n if (!isPolarArrayContent(c)) {\n return;\n }\n c.itemAngle = ctx.radianToAngle(ctx.getTwoPointsRadian(cursor, content.center) - ctx.getTwoPointsRadian(base, content.center));\n return { assistentContents: [{ type: "line", dashArray: [4 / scale], points: [start, cursor] }] };\n }\n });\n }\n if (content.itemCount > 2) {\n const p = ctx.rotatePositionByCenter(base, content.center, -(content.itemCount - 1) * content.itemAngle);\n editPoints.push({\n ...p,\n cursor: "move",\n update(c, { cursor, start, scale }) {\n if (!isPolarArrayContent(c)) {\n return;\n }\n let angle = ctx.radianToAngle(ctx.getTwoPointsRadian(cursor, content.center) - ctx.getTwoPointsRadian(base, content.center));\n if (c.itemAngle > 0) {\n if (angle < 0) {\n angle += 360;\n }\n } else {\n if (angle > 0) {\n angle -= 360;\n }\n }\n c.itemCount = Math.round(angle / c.itemAngle) + 1;\n return { assistentContents: [{ type: "line", dashArray: [4 / scale], points: [start, cursor] }] };\n }\n });\n }\n return {\n editPoints\n };\n });\n },\n getSnapPoints(content, contents) {\n return ctx.getContentsSnapPoints(content, contents, (c) => getAllContentsFromCache(c, contents));\n },\n getGeometries,\n propertyPanel(content, update, _, { acquirePoint }) {\n return {\n center: /* @__PURE__ */ React.createElement(\n ctx.ObjectEditor,\n {\n inline: true,\n properties: {\n from: /* @__PURE__ */ React.createElement(ctx.Button, { onClick: () => acquirePoint((p) => update((c) => {\n if (isPolarArrayContent(c)) {\n c.center.x = p.x;\n c.center.y = p.y;\n }\n })) }, "canvas"),\n x: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.center.x, setValue: (v) => update((c) => {\n if (isPolarArrayContent(c)) {\n c.center.x = v;\n }\n }) }),\n y: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.center.y, setValue: (v) => update((c) => {\n if (isPolarArrayContent(c)) {\n c.center.y = v;\n }\n }) })\n }\n }\n ),\n rowCount: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.rowCount, setValue: (v) => update((c) => {\n if (isPolarArrayContent(c)) {\n c.rowCount = v;\n }\n }) }),\n itemCount: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.itemCount, setValue: (v) => update((c) => {\n if (isPolarArrayContent(c)) {\n c.itemCount = v;\n }\n }) }),\n rowSpacing: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.rowSpacing, setValue: (v) => update((c) => {\n if (isPolarArrayContent(c)) {\n c.rowSpacing = v;\n }\n }) }),\n itemAngle: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.itemAngle, setValue: (v) => update((c) => {\n if (isPolarArrayContent(c)) {\n c.itemAngle = v;\n }\n }) }),\n ...ctx.getVariableValuesContentPropertyPanel(content, ctx.getContainerVariableNames(content), update)\n };\n },\n isValid: (c, p) => ctx.validate(c, PolarArrayContent, p),\n getRefIds\n };\n}\nfunction isPolarArrayContent(content) {\n return content.type === "polar array";\n}\nfunction getCommand(ctx) {\n function contentSelectable(content, contents) {\n return ctx.contentIsDeletable(content, contents);\n }\n const React = ctx.React;\n const icon = /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 100 100" }, /* @__PURE__ */ React.createElement("circle", { cx: "30", cy: "22", r: "12", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("circle", { cx: "67", cy: "23", r: "12", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("circle", { cx: "82", cy: "53", r: "12", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("circle", { cx: "67", cy: "81", r: "12", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("circle", { cx: "28", cy: "79", r: "12", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("circle", { cx: "13", cy: "50", r: "12", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }));\n return {\n name: "create polar array",\n useCommand({ onEnd, type, scale, contents }) {\n let message = "";\n if (type) {\n message = "specify target point";\n }\n const { input, setInputPosition, cursorPosition, setCursorPosition, resetInput } = ctx.useCursorInput(message);\n return {\n onStart(p) {\n resetInput();\n onEnd({\n updateContents: (contents2, selected) => {\n const target = contents2.filter((c, i) => c && ctx.isSelected([i], selected) && contentSelectable(c, contents2));\n const bounding = ctx.getContentsBounding(target, contents2);\n if (!bounding) return;\n const newContent = {\n type: "polar array",\n center: p,\n contents: target,\n rowCount: 1,\n rowSpacing: ctx.getTwoPointsDistance(bounding.end, bounding.start) * 1.5,\n itemCount: 6,\n itemAngle: 60\n };\n ctx.deleteSelectedContents(contents2, selected.map((c) => c[0]));\n contents2.push(newContent);\n setCursorPosition(void 0);\n }\n });\n },\n input,\n onMove(p, viewportPosition) {\n setInputPosition(viewportPosition || p);\n if (!type) {\n return;\n }\n setCursorPosition(p);\n },\n updateSelectedContent(content) {\n var _a, _b;\n if (cursorPosition) {\n const bounding = (_b = (_a = ctx.getContentModel(content)) == null ? void 0 : _a.getGeometries) == null ? void 0 : _b.call(_a, content, contents).bounding;\n if (!bounding) return {};\n const base = {\n x: ctx.getTwoNumberCenter(bounding.start.x, bounding.end.x),\n y: ctx.getTwoNumberCenter(bounding.start.y, bounding.end.y)\n };\n return {\n newContents: [\n {\n type: "polar array",\n center: cursorPosition,\n contents: [content],\n rowCount: 1,\n rowSpacing: ctx.getTwoPointsDistance(bounding.end, bounding.start) * 1.5,\n itemCount: 6,\n itemAngle: 60\n }\n ],\n assistentContents: [\n {\n type: "line",\n dashArray: [4 / scale],\n points: [base, cursorPosition]\n }\n ]\n };\n }\n return {};\n },\n reset: resetInput\n };\n },\n contentSelectable,\n icon\n };\n}\nexport {\n getCommand,\n getModel,\n isPolarArrayContent\n};\n','// dev/cad-editor/plugins/polygon.plugin.tsx\nfunction getModel(ctx) {\n const PolygonContent = ctx.and(ctx.BaseContent("polygon"), ctx.StrokeFields, ctx.FillFields, {\n points: [ctx.Position]\n });\n const getRefIds = (content) => ctx.getStrokeAndFillRefIds(content);\n const geometriesCache = new ctx.WeakmapValuesCache();\n function getPolygonGeometries(content, contents) {\n const refs = new Set(ctx.iterateRefContents(getRefIds(content), contents, [content]));\n return geometriesCache.get(content, refs, () => {\n const lines = Array.from(ctx.iteratePolygonLines(content.points));\n return {\n lines,\n points: content.points,\n bounding: ctx.getPointsBounding(content.points),\n renderingLines: ctx.dashedPolylineToLines(ctx.polygonToPolyline(content.points), content.dashArray),\n regions: ctx.hasFill(content) ? [\n {\n lines,\n points: content.points\n }\n ] : void 0\n };\n });\n }\n const React = ctx.React;\n return {\n type: "polygon",\n ...ctx.strokeModel,\n ...ctx.fillModel,\n move(content, offset) {\n for (const point of content.points) {\n ctx.movePoint(point, offset);\n }\n },\n rotate(content, center, angle) {\n for (const point of content.points) {\n ctx.rotatePoint(point, center, angle);\n }\n },\n scale(content, center, sx, sy) {\n for (const point of content.points) {\n ctx.scalePoint(point, center, sx, sy);\n }\n },\n skew(content, center, sx, sy) {\n for (const point of content.points) {\n ctx.skewPoint(point, center, sx, sy);\n }\n },\n mirror(content, line) {\n for (const point of content.points) {\n ctx.mirrorPoint(point, line);\n }\n },\n explode(content, contents) {\n const { lines } = getPolygonGeometries(content, contents);\n return lines.map((line) => ({ type: "line", points: line }));\n },\n break(content, intersectionPoints, contents) {\n const { lines } = getPolygonGeometries(content, contents);\n return ctx.breakPolyline(lines, intersectionPoints);\n },\n offset(content, point, distance, contents) {\n const { lines } = getPolygonGeometries(content, contents);\n if (!distance) {\n distance = Math.min(...lines.map((line) => ctx.getPointAndGeometryLineMinimumDistance(point, line)));\n }\n const index = ctx.getLinesOffsetDirection(point, lines);\n const points = ctx.getParallelPolylineByDistance(lines, distance, index);\n return ctx.trimOffsetResult(points.slice(0, points.length - 1), point, true, contents).map((p) => ctx.produce(content, (d) => {\n d.points = p;\n }));\n },\n render(content, renderCtx) {\n const { options, target } = ctx.getStrokeFillRenderOptionsFromRenderContext(content, renderCtx);\n return target.renderPolygon(content.points, options);\n },\n getOperatorRenderPosition(content) {\n return content.points[0];\n },\n getEditPoints(content) {\n return ctx.getEditPointsFromCache(content, () => ({ editPoints: ctx.getPolylineEditPoints(content, isPolygonContent, true) }));\n },\n getSnapPoints(content, contents) {\n return ctx.getSnapPointsFromCache(content, () => {\n const { points, lines } = getPolygonGeometries(content, contents);\n return [\n ...points.map((p) => ({ ...p, type: "endpoint" })),\n ...lines.map(([start, end]) => ({\n x: (start.x + end.x) / 2,\n y: (start.y + end.y) / 2,\n type: "midpoint"\n }))\n ];\n });\n },\n getGeometries: getPolygonGeometries,\n canSelectPart: true,\n propertyPanel(content, update, contents, { acquirePoint }) {\n return {\n points: /* @__PURE__ */ React.createElement(\n ctx.ArrayEditor,\n {\n inline: true,\n ...ctx.getArrayEditorProps((v) => v.points, { x: 0, y: 0 }, (v) => update((c) => {\n if (isPolygonContent(c)) {\n v(c);\n }\n })),\n items: content.points.map((f, i) => /* @__PURE__ */ React.createElement(\n ctx.ObjectEditor,\n {\n inline: true,\n properties: {\n from: /* @__PURE__ */ React.createElement(ctx.Button, { onClick: () => acquirePoint((p) => update((c) => {\n if (isPolygonContent(c)) {\n c.points[i].x = p.x;\n c.points[i].y = p.y;\n }\n })) }, "canvas"),\n x: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: f.x, setValue: (v) => update((c) => {\n if (isPolygonContent(c)) {\n c.points[i].x = v;\n }\n }) }),\n y: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: f.y, setValue: (v) => update((c) => {\n if (isPolygonContent(c)) {\n c.points[i].y = v;\n }\n }) })\n }\n }\n ))\n }\n ),\n ...ctx.getStrokeContentPropertyPanel(content, update, contents),\n ...ctx.getFillContentPropertyPanel(content, update, contents)\n };\n },\n isValid: (c, p) => ctx.validate(c, PolygonContent, p),\n getRefIds,\n updateRefId: ctx.updateStrokeAndFillRefIds,\n deleteRefId: ctx.deleteStrokeAndFillRefIds,\n isPointIn: (content, point) => ctx.pointInPolygon(point, content.points)\n };\n}\nfunction isPolygonContent(content) {\n return content.type === "polygon";\n}\nfunction getCommand(ctx) {\n const React = ctx.React;\n const icon = /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 100 100" }, /* @__PURE__ */ React.createElement("polygon", { points: "10,81 86,83 88,39 52,10 12,35", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }));\n return {\n name: "create polygon",\n useCommand({ onEnd, type, scale, strokeStyleId, fillStyleId }) {\n const [createType, setCreateType] = React.useState("point");\n const { polygon, onClick, onMove, input, startSetSides, startPosition, cursorPosition, reset } = ctx.usePolygonClickCreate(\n type === "create polygon",\n (c) => onEnd({\n updateContents: (contents) => contents.push({ points: c, strokeStyleId, fillStyleId, type: "polygon" })\n }),\n {\n toEdge: createType === "edge",\n setSidesKey: "S",\n switchTypeKey: "T",\n switchType: () => setCreateType(createType === "edge" ? "point" : "edge")\n }\n );\n const assistentContents = [];\n if (startPosition && cursorPosition) {\n assistentContents.push({ type: "line", points: [startPosition, cursorPosition], dashArray: [4 / scale] });\n }\n if (polygon) {\n assistentContents.push({ points: polygon, strokeStyleId, fillStyleId, type: "polygon" });\n }\n return {\n onStart: onClick,\n input,\n onMove,\n reset,\n subcommand: type === "create polygon" ? /* @__PURE__ */ React.createElement("span", null, /* @__PURE__ */ React.createElement("button", { onClick: startSetSides, style: { position: "relative" } }, "set sides(S)"), /* @__PURE__ */ React.createElement("button", { onClick: () => setCreateType(createType === "edge" ? "point" : "edge"), style: { position: "relative" } }, createType, "(T)")) : void 0,\n assistentContents,\n lastPosition: startPosition\n };\n },\n selectCount: 0,\n hotkey: "POL",\n icon\n };\n}\nexport {\n getCommand,\n getModel,\n isPolygonContent\n};\n','// dev/cad-editor/plugins/circle-arc.plugin.tsx\nfunction isCircleContent(content) {\n return content.type === "circle";\n}\nfunction isArcContent(content) {\n return content.type === "arc";\n}\n\n// dev/cad-editor/plugins/radial-dimension.plugin.tsx\nfunction getModel(ctx) {\n const RadialDimensionReferenceContent = ctx.and(ctx.BaseContent("radial dimension reference"), ctx.StrokeFields, ctx.ArrowFields, ctx.RadialDimension, {\n ref: ctx.PartRef\n });\n const getRefIds = (content) => [...ctx.getStrokeRefIds(content), ...ctx.toRefId(content.ref.id, true)];\n const radialDimensionReferenceCache = new ctx.WeakmapValuesCache();\n function getRadialDimensionReferenceGeometriesFromCache(content, contents, patches) {\n const refs = new Set(ctx.iterateRefContents(getRefIds(content), contents, [content]));\n return radialDimensionReferenceCache.get(content, refs, () => {\n var _a, _b;\n const target = ctx.getRefPart(content.ref, contents, contentSelectable, patches);\n if (target) {\n return ctx.getRadialDimensionGeometries(content, target, {\n arrowAngle: (_a = content.arrowAngle) != null ? _a : ctx.dimensionStyle.arrowAngle,\n arrowSize: (_b = content.arrowSize) != null ? _b : ctx.dimensionStyle.arrowSize,\n margin: ctx.dimensionStyle.margin\n }, getTextPosition);\n }\n return { lines: [], points: [], renderingLines: [] };\n });\n }\n const textPositionMap = new ctx.WeakmapCache2();\n function getTextPosition(content, circle) {\n return textPositionMap.get(content, circle, () => {\n return ctx.getRadialDimensionTextPosition(content, circle, ctx.dimensionStyle.margin, ctx.getTextSizeFromCache);\n });\n }\n const React = ctx.React;\n return {\n type: "radial dimension reference",\n ...ctx.strokeModel,\n ...ctx.arrowModel,\n move(content, offset) {\n ctx.movePoint(content.position, offset);\n },\n scale(content, center, sx, sy) {\n ctx.scalePoint(content.position, center, sx, sy);\n },\n skew(content, center, sx, sy) {\n ctx.skewPoint(content.position, center, sx, sy);\n },\n render(content, renderCtx) {\n const { options, contents, target, fillOptions, strokeColor } = ctx.getStrokeRenderOptionsFromRenderContext(content, renderCtx);\n const { regions, lines } = getRadialDimensionReferenceGeometriesFromCache(content, contents, renderCtx.patches);\n const children = [];\n for (const line of lines) {\n children.push(target.renderPolyline(line, options));\n }\n if (regions && regions.length > 0) {\n children.push(target.renderPolygon(regions[0].points, fillOptions));\n }\n const referenceTarget = ctx.getRefPart(content.ref, contents, contentSelectable, renderCtx.patches);\n if (referenceTarget) {\n const { textPosition, textRotation, text } = getTextPosition(content, referenceTarget);\n const textOptions = ctx.getTextStyleRenderOptionsFromRenderContext(strokeColor, renderCtx);\n children.push(target.renderGroup(\n [\n target.renderText(textPosition.x, textPosition.y, text, strokeColor, content.fontSize, content.fontFamily, textOptions)\n ],\n {\n rotation: textRotation,\n base: textPosition\n }\n ));\n }\n return target.renderGroup(children);\n },\n getEditPoints(content, contents) {\n return ctx.getEditPointsFromCache(content, () => {\n return {\n editPoints: [\n {\n x: content.position.x,\n y: content.position.y,\n cursor: "move",\n update(c, { cursor, start, scale }) {\n if (!isRadialDimensionReferenceContent(c)) {\n return;\n }\n c.position.x += cursor.x - start.x;\n c.position.y += cursor.y - start.y;\n const target = ctx.getRefPart(content.ref, contents, contentSelectable);\n if (!target || ctx.getTwoPointsDistance(target, c.position) > target.r) {\n return;\n }\n return { assistentContents: [{ type: "line", dashArray: [4 / scale], points: [target, cursor] }] };\n }\n }\n ]\n };\n });\n },\n getGeometries: getRadialDimensionReferenceGeometriesFromCache,\n propertyPanel(content, update, contents, { acquirePoint, acquireContent }) {\n return {\n ref: [\n /* @__PURE__ */ React.createElement(ctx.Button, { onClick: () => acquireContent({ count: 1, part: true, selectable: (v) => contentSelectable(ctx.getContentByIndex(contents, v)) }, (r) => update((c) => {\n if (isRadialDimensionReferenceContent(c)) {\n c.ref = r[0];\n }\n })) }, "select"),\n typeof content.ref.id === "number" ? /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.ref.id, setValue: (v) => update((c) => {\n if (isRadialDimensionReferenceContent(c)) {\n c.ref.id = v;\n }\n }) }) : void 0,\n content.ref.partIndex !== void 0 ? /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.ref.partIndex, setValue: (v) => update((c) => {\n if (isRadialDimensionReferenceContent(c)) {\n c.ref.partIndex = v;\n }\n }) }) : void 0\n ],\n position: /* @__PURE__ */ React.createElement(\n ctx.ObjectEditor,\n {\n inline: true,\n properties: {\n from: /* @__PURE__ */ React.createElement(ctx.Button, { onClick: () => acquirePoint((p) => update((c) => {\n if (isRadialDimensionReferenceContent(c)) {\n c.position.x = p.x;\n c.position.y = p.y;\n }\n })) }, "canvas"),\n x: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.position.x, setValue: (v) => update((c) => {\n if (isRadialDimensionReferenceContent(c)) {\n c.position.x = v;\n }\n }) }),\n y: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.position.y, setValue: (v) => update((c) => {\n if (isRadialDimensionReferenceContent(c)) {\n c.position.y = v;\n }\n }) })\n }\n }\n ),\n text: [\n /* @__PURE__ */ React.createElement(ctx.BooleanEditor, { value: content.text !== void 0, setValue: (v) => update((c) => {\n if (isRadialDimensionReferenceContent(c)) {\n c.text = v ? "" : void 0;\n }\n }) }),\n content.text !== void 0 ? /* @__PURE__ */ React.createElement(ctx.StringEditor, { value: content.text, setValue: (v) => update((c) => {\n if (isRadialDimensionReferenceContent(c)) {\n c.text = v;\n }\n }) }) : void 0\n ],\n fontSize: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.fontSize, setValue: (v) => update((c) => {\n if (isRadialDimensionReferenceContent(c)) {\n c.fontSize = v;\n }\n }) }),\n fontFamily: /* @__PURE__ */ React.createElement(ctx.StringEditor, { value: content.fontFamily, setValue: (v) => update((c) => {\n if (isRadialDimensionReferenceContent(c)) {\n c.fontFamily = v;\n }\n }) }),\n ...ctx.getArrowContentPropertyPanel(content, update),\n ...ctx.getStrokeContentPropertyPanel(content, update, contents)\n };\n },\n isValid: (c, p) => ctx.validate(c, RadialDimensionReferenceContent, p),\n getRefIds,\n updateRefId(content, update) {\n const newRefId = update(content.ref.id);\n if (newRefId !== void 0) {\n content.ref.id = newRefId;\n }\n ctx.updateStrokeRefIds(content, update);\n },\n deleteRefId: ctx.deleteStrokeRefIds\n };\n}\nfunction isRadialDimensionReferenceContent(content) {\n return content.type === "radial dimension reference";\n}\nfunction contentSelectable(content) {\n return !!content && (isArcContent(content) || isCircleContent(content));\n}\nfunction getCommand(ctx) {\n const React = ctx.React;\n const icon = /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 100 100" }, /* @__PURE__ */ React.createElement("circle", { cx: "36", cy: "64", r: "31", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polyline", { points: "36,64 90,9", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polygon", { points: "75,32 65,22 54,44", strokeWidth: "0", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "currentColor", stroke: "currentColor" }));\n return {\n name: "create radial dimension",\n selectCount: 1,\n selectType: "select part",\n icon,\n contentSelectable,\n useCommand({ onEnd, selected, type, strokeStyleId }) {\n const [result, setResult] = React.useState();\n const [text, setText] = React.useState();\n let message = "";\n if (type) {\n message = "input text";\n }\n const { input, clearText, setCursorPosition, setInputPosition, resetInput } = ctx.useCursorInput(message, type ? (e, text2) => {\n if (e.key === "Enter") {\n setText(text2);\n if (result) {\n setResult({ ...result, text: text2 });\n }\n clearText();\n }\n } : void 0);\n const reset = () => {\n setResult(void 0);\n resetInput();\n setText(void 0);\n };\n return {\n input,\n onStart() {\n if (result) {\n onEnd({\n updateContents: (draft) => {\n if (selected.length > 0 && type) {\n const { content, path } = selected[0];\n if (contentSelectable(content)) {\n result.ref = {\n id: path[0],\n partIndex: path[1]\n };\n }\n }\n draft.push({\n type: "radial dimension reference",\n position: result.position,\n fontSize: result.fontSize,\n fontFamily: result.fontFamily,\n ref: result.ref,\n text: result.text,\n strokeStyleId\n });\n },\n nextCommand: type\n });\n reset();\n }\n },\n onMove(p, viewportPosition) {\n setInputPosition(viewportPosition || p);\n setCursorPosition(p);\n if (selected.length > 0 && type) {\n const { content, path } = selected[0];\n if (contentSelectable(content)) {\n setResult({\n type: "radial dimension reference",\n position: p,\n fontSize: 16,\n fontFamily: "monospace",\n ref: {\n id: path[0],\n partIndex: path[1]\n },\n text,\n strokeStyleId\n });\n }\n }\n },\n assistentContents: result ? [result] : void 0,\n reset\n };\n }\n };\n}\nexport {\n getCommand,\n getModel,\n isRadialDimensionReferenceContent\n};\n','// dev/cad-editor/plugins/ray.plugin.tsx\nfunction getModel(ctx) {\n const RayContent = ctx.and(ctx.BaseContent("ray"), ctx.StrokeFields, ctx.Ray);\n const getRefIds = (content) => ctx.getStrokeRefIds(content);\n function getRayGeometries(content, contents) {\n const refs = new Set(ctx.iterateRefContents(getRefIds(content), contents, [content]));\n return ctx.getGeometriesFromCache(content, refs, () => {\n return {\n lines: [{ type: "ray", line: content }],\n renderingLines: []\n };\n });\n }\n const React = ctx.React;\n const rayModel = {\n type: "ray",\n ...ctx.strokeModel,\n move(content, offset) {\n ctx.movePoint(content, offset);\n },\n rotate(content, center, angle) {\n ctx.rotatePoint(content, center, angle);\n content.angle += angle;\n },\n scale(content, center, sx, sy) {\n ctx.scalePoint(content, center, sx, sy);\n },\n mirror(content, line, angle) {\n ctx.mirrorPoint(content, line);\n content.angle = 2 * angle - content.angle;\n },\n break(content, intersectionPoints, contents) {\n return ctx.breakGeometryLines(getRayGeometries(content, contents).lines, intersectionPoints).flat().map((n) => ctx.geometryLineToContent(n));\n },\n offset(content, point, distance) {\n if (!distance) {\n distance = ctx.getPointAndRayNearestPointAndDistance(point, content).distance;\n }\n const index = ctx.pointSideToIndex(ctx.getPointSideOfGeometryLine(point, { type: "ray", line: content }));\n return ctx.getParallelRaysByDistance(content, distance)[index];\n },\n render(content, renderCtx) {\n const { options, target } = ctx.getStrokeRenderOptionsFromRenderContext(content, renderCtx);\n return target.renderRay(content.x, content.y, content.angle, { ...options, bidirectional: content.bidirectional });\n },\n getEditPoints(content) {\n return ctx.getEditPointsFromCache(content, () => ({\n editPoints: [{\n x: content.x,\n y: content.y,\n cursor: "move",\n type: "move",\n update(c, { cursor, start, scale }) {\n if (!isRayContent(c)) {\n return;\n }\n c.x += cursor.x - start.x;\n c.y += cursor.y - start.y;\n return { assistentContents: [{ type: "line", dashArray: [4 / scale], points: [content, cursor] }] };\n }\n }]\n }));\n },\n getSnapPoints(content) {\n return ctx.getSnapPointsFromCache(content, () => {\n return [{ x: content.x, y: content.y, type: "endpoint" }];\n });\n },\n getGeometries: getRayGeometries,\n propertyPanel(content, update, contents, { acquirePoint }) {\n return {\n from: /* @__PURE__ */ React.createElement(ctx.Button, { onClick: () => acquirePoint((p) => update((c) => {\n if (isRayContent(c)) {\n c.x = p.x;\n c.y = p.y;\n }\n })) }, "canvas"),\n x: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.x, setValue: (v) => update((c) => {\n if (isRayContent(c)) {\n c.x = v;\n }\n }) }),\n y: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.y, setValue: (v) => update((c) => {\n if (isRayContent(c)) {\n c.y = v;\n }\n }) }),\n angle: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.angle, setValue: (v) => update((c) => {\n if (isRayContent(c)) {\n c.angle = v;\n }\n }) }),\n bidirectional: /* @__PURE__ */ React.createElement(ctx.BooleanEditor, { value: content.bidirectional || false, setValue: (v) => update((c) => {\n if (isRayContent(c)) {\n c.bidirectional = v;\n }\n }) }),\n reversed: /* @__PURE__ */ React.createElement(ctx.BooleanEditor, { value: content.reversed || false, setValue: (v) => update((c) => {\n if (isRayContent(c)) {\n c.reversed = v;\n }\n }) }),\n ...ctx.getStrokeContentPropertyPanel(content, update, contents)\n };\n },\n isValid: (c, p) => ctx.validate(c, RayContent, p),\n getRefIds,\n updateRefId: ctx.updateStrokeRefIds,\n deleteRefId: ctx.deleteStrokeRefIds,\n reverse: (content) => ({ ...content, ...ctx.reverseRay(content) })\n };\n return rayModel;\n}\nfunction isRayContent(content) {\n return content.type === "ray";\n}\nfunction getCommand(ctx) {\n const React = ctx.React;\n const icon = /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 100 100" }, /* @__PURE__ */ React.createElement("circle", { cx: "10", cy: "87", r: "12", strokeWidth: "0", vectorEffect: "non-scaling-stroke", fill: "currentColor", stroke: "#000000" }), /* @__PURE__ */ React.createElement("polyline", { points: "10,87 87,9", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }));\n return {\n name: "create ray",\n useCommand({ onEnd, type, strokeStyleId }) {\n const { line, onClick, onMove, input, lastPosition, reset } = ctx.useLineClickCreate(\n type === "create ray",\n (c) => onEnd({\n updateContents: (contents) => contents.push({ type: "ray", x: c[0].x, y: c[0].y, angle: ctx.radianToAngle(ctx.getTwoPointsRadian(c[1], c[0])), strokeStyleId })\n }),\n { once: true }\n );\n const assistentContents = [];\n if (line && line.length > 1) {\n const start = line[line.length - 2];\n const end = line[line.length - 1];\n const angle = ctx.radianToAngle(ctx.getTwoPointsRadian(end, start));\n assistentContents.push({ type: "ray", x: start.x, y: start.y, angle, strokeStyleId });\n }\n return {\n onStart: onClick,\n input,\n onMove,\n assistentContents,\n lastPosition,\n reset\n };\n },\n selectCount: 0,\n icon\n };\n}\nexport {\n getCommand,\n getModel,\n isRayContent\n};\n','// dev/cad-editor/plugins/rect-array.plugin.tsx\nfunction getModel(ctx) {\n const RectArrayContent = ctx.and(ctx.BaseContent("rect array"), ctx.ContainerFields, {\n rowCount: ctx.number,\n rowSpacing: ctx.number,\n columnCount: ctx.number,\n columnSpacing: ctx.number\n });\n const getRefIds = (content) => ctx.toRefIds(content.contents);\n const getAllContentsFromCache = (content) => {\n return ctx.allContentsCache.get(content, () => {\n const result = [];\n for (let i = 0; i < content.columnCount; i++) {\n const x = i * content.columnSpacing;\n for (let j = 0; j < content.rowCount; j++) {\n const y = j * content.rowSpacing;\n if (x === 0 && y === 0) {\n result.push(...content.contents);\n } else {\n result.push(...content.contents.map((c) => {\n var _a;\n if (!c) return;\n const move = (_a = ctx.getContentModel(c)) == null ? void 0 : _a.move;\n if (!move) return;\n return ctx.produce(c, (draft) => {\n move(draft, { x, y });\n });\n }));\n }\n }\n }\n return result;\n });\n };\n const getGeometries = (content, contents) => ctx.getContentsGeometries(content, contents, getRefIds, [content], getAllContentsFromCache);\n const React = ctx.React;\n return {\n type: "rect array",\n ...ctx.containerModel,\n move: ctx.getContainerMove,\n rotate(content, center, angle, contents) {\n const x = content.columnSpacing * (content.columnCount - 1) * 0.5;\n const y = content.rowSpacing * (content.rowCount - 1) * 0.5;\n content.contents.forEach((c) => {\n var _a, _b, _c;\n if (!c) return;\n const m = ctx.getContentModel(c);\n if (!m) return;\n (_a = m.move) == null ? void 0 : _a.call(m, c, { x, y });\n (_b = m.rotate) == null ? void 0 : _b.call(m, c, center, angle, contents);\n (_c = m.move) == null ? void 0 : _c.call(m, c, { x: -x, y: -y });\n });\n },\n scale(content, center, sx, sy, contents) {\n ctx.getContainerScale(content, center, sx, sy, contents);\n content.rowSpacing *= sx;\n content.columnSpacing *= sy;\n },\n explode(content) {\n return ctx.getContentsExplode(getAllContentsFromCache(content));\n },\n break(content, points, contents) {\n return ctx.getContentsBreak(getAllContentsFromCache(content), points, contents);\n },\n render(content, renderCtx) {\n return renderCtx.target.renderGroup(ctx.renderContainerChildren({ contents: getAllContentsFromCache(content), variableValues: content.variableValues }, renderCtx));\n },\n getEditPoints(content, contents) {\n return ctx.getEditPointsFromCache(content, () => {\n const bounding = ctx.getContentsBounding(content.contents, contents);\n if (!bounding) {\n return { editPoints: [] };\n }\n const base = {\n x: ctx.getTwoNumberCenter(bounding.start.x, bounding.end.x),\n y: ctx.getTwoNumberCenter(bounding.start.y, bounding.end.y)\n };\n return {\n editPoints: [\n {\n ...base,\n cursor: "move",\n update(c, { cursor, start, scale }) {\n if (!isRectArrayContent(c)) {\n return;\n }\n ctx.getContainerMove(c, {\n x: cursor.x - start.x,\n y: cursor.y - start.y\n });\n return { assistentContents: [{ type: "line", dashArray: [4 / scale], points: [start, cursor] }] };\n }\n },\n {\n x: base.x + content.columnSpacing,\n y: base.y,\n cursor: "move",\n update(c, { cursor, start, scale }) {\n if (!isRectArrayContent(c)) {\n return;\n }\n c.columnSpacing = cursor.x - base.x;\n return { assistentContents: [{ type: "line", dashArray: [4 / scale], points: [start, cursor] }] };\n }\n },\n {\n x: base.x,\n y: base.y + content.rowSpacing,\n cursor: "move",\n update(c, { cursor, start, scale }) {\n if (!isRectArrayContent(c)) {\n return;\n }\n c.rowSpacing = cursor.y - base.y;\n return { assistentContents: [{ type: "line", dashArray: [4 / scale], points: [start, cursor] }] };\n }\n },\n {\n x: base.x + content.columnSpacing * (content.columnCount - 1),\n y: base.y,\n cursor: "move",\n update(c, { cursor, start, scale }) {\n if (!isRectArrayContent(c)) {\n return;\n }\n let columnCount = Math.round((cursor.x - base.x) / content.columnSpacing);\n if (columnCount < 0) {\n columnCount = -columnCount;\n c.columnSpacing = -content.columnSpacing;\n }\n c.columnCount = columnCount + 1;\n return { assistentContents: [{ type: "line", dashArray: [4 / scale], points: [start, cursor] }] };\n }\n },\n {\n x: base.x,\n y: base.y + content.rowSpacing * (content.rowCount - 1),\n cursor: "move",\n update(c, { cursor, start, scale }) {\n if (!isRectArrayContent(c)) {\n return;\n }\n let rowCount = Math.round((cursor.y - base.y) / content.rowSpacing);\n if (rowCount < 0) {\n rowCount = -rowCount;\n c.rowSpacing = -content.rowSpacing;\n }\n c.rowCount = rowCount + 1;\n return { assistentContents: [{ type: "line", dashArray: [4 / scale], points: [start, cursor] }] };\n }\n },\n {\n x: base.x + content.columnSpacing * (content.columnCount - 1),\n y: base.y + content.rowSpacing * (content.rowCount - 1),\n cursor: "move",\n update(c, { cursor, start, scale }) {\n if (!isRectArrayContent(c)) {\n return;\n }\n let rowCount = Math.round((cursor.y - base.y) / content.rowSpacing);\n if (rowCount < 0) {\n rowCount = -rowCount;\n c.rowSpacing = -content.rowSpacing;\n }\n let columnCount = Math.round((cursor.x - base.x) / content.columnSpacing);\n if (columnCount < 0) {\n columnCount = -columnCount;\n c.columnSpacing = -content.columnSpacing;\n }\n c.rowCount = rowCount + 1;\n c.columnCount = columnCount + 1;\n return { assistentContents: [{ type: "line", dashArray: [4 / scale], points: [start, cursor] }] };\n }\n }\n ]\n };\n });\n },\n getSnapPoints(content, contents) {\n return ctx.getContentsSnapPoints(content, contents, getAllContentsFromCache);\n },\n getGeometries,\n propertyPanel(content, update) {\n return {\n rowCount: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.rowCount, setValue: (v) => update((c) => {\n if (isRectArrayContent(c)) {\n c.rowCount = v;\n }\n }) }),\n columnCount: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.columnCount, setValue: (v) => update((c) => {\n if (isRectArrayContent(c)) {\n c.columnCount = v;\n }\n }) }),\n rowSpacing: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.rowSpacing, setValue: (v) => update((c) => {\n if (isRectArrayContent(c)) {\n c.rowSpacing = v;\n }\n }) }),\n columnSpacing: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.columnSpacing, setValue: (v) => update((c) => {\n if (isRectArrayContent(c)) {\n c.columnSpacing = v;\n }\n }) }),\n ...ctx.getVariableValuesContentPropertyPanel(content, ctx.getContainerVariableNames(content), update)\n };\n },\n isValid: (c, p) => ctx.validate(c, RectArrayContent, p),\n getRefIds\n };\n}\nfunction isRectArrayContent(content) {\n return content.type === "rect array";\n}\nfunction getCommand(ctx) {\n function contentSelectable(content, contents) {\n return ctx.contentIsDeletable(content, contents);\n }\n const React = ctx.React;\n const icon = /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 100 100" }, /* @__PURE__ */ React.createElement("rect", { x: "3", y: "70", width: "40", height: "27", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("rect", { x: "58", y: "70", width: "40", height: "27", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("rect", { x: "3", y: "35", width: "40", height: "27", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("rect", { x: "58", y: "35", width: "40", height: "27", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("rect", { x: "3", y: "0", width: "40", height: "27", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("rect", { x: "58", y: "1", width: "40", height: "27", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }));\n return {\n name: "create rect array",\n execute({ contents, selected }) {\n const target = contents.filter((c, i) => c && ctx.isSelected([i], selected) && contentSelectable(c, contents));\n const bounding = ctx.getContentsBounding(target, contents);\n if (!bounding) return;\n const size = ctx.getTwoPointsFormRegionSize(bounding);\n const newContent = {\n type: "rect array",\n contents: target,\n rowCount: 3,\n rowSpacing: -size.height * 1.5,\n columnCount: 4,\n columnSpacing: size.width * 1.5\n };\n ctx.deleteSelectedContents(contents, selected.map((c) => c[0]));\n contents.push(newContent);\n },\n contentSelectable,\n icon\n };\n}\nexport {\n getCommand,\n getModel,\n isRectArrayContent\n};\n','// dev/cad-editor/plugins/rect.plugin.tsx\nfunction getModel(ctx) {\n const RectContent = ctx.and(ctx.BaseContent("rect"), ctx.StrokeFields, ctx.FillFields, ctx.Region, {\n angle: ctx.number\n });\n const getRefIds = (content) => ctx.getStrokeAndFillRefIds(content);\n const geometriesCache = new ctx.WeakmapValuesCache();\n function getRectGeometries(content, contents) {\n const refs = new Set(ctx.iterateRefContents(getRefIds(content), contents, [content]));\n return geometriesCache.get(content, refs, () => {\n const points = ctx.getPolygonFromRegion(content).map((p) => ctx.rotatePositionByCenter(p, content, -content.angle));\n const lines = Array.from(ctx.iteratePolygonLines(points));\n return {\n lines,\n points,\n midpoints: lines.map((line) => ctx.getTwoPointCenter(...line)),\n bounding: ctx.getPointsBounding(points),\n renderingLines: ctx.dashedPolylineToLines(ctx.polygonToPolyline(points), content.dashArray),\n regions: ctx.hasFill(content) ? [\n {\n lines,\n points\n }\n ] : void 0\n };\n });\n }\n const React = ctx.React;\n return {\n type: "rect",\n ...ctx.strokeModel,\n ...ctx.fillModel,\n move(content, offset) {\n ctx.movePoint(content, offset);\n },\n rotate(content, center, angle) {\n ctx.rotatePoint(content, center, angle);\n content.angle += angle;\n },\n scale(content, center, sx, sy, contents) {\n if (content.angle) {\n const points = ctx.produce(getRectGeometries(content, contents).points, (draft) => {\n for (const p of draft) {\n ctx.scalePoint(p, center, sx, sy);\n }\n });\n return { ...content, points, type: "polygon" };\n }\n ctx.scalePoint(content, center, sx, sy);\n content.width *= sx;\n content.height *= sy;\n return;\n },\n skew(content, center, sx, sy, contents) {\n const points = ctx.produce(getRectGeometries(content, contents).points, (draft) => {\n for (const p of draft) {\n ctx.skewPoint(p, center, sx, sy);\n }\n });\n return { ...content, points, type: "polygon" };\n },\n explode(content, contents) {\n const { lines } = getRectGeometries(content, contents);\n return lines.map((line) => ({ type: "line", points: line }));\n },\n break(content, intersectionPoints, contents) {\n const { lines } = getRectGeometries(content, contents);\n return ctx.breakPolyline(lines, intersectionPoints);\n },\n mirror(content, line, angle) {\n ctx.mirrorPoint(content, line);\n content.angle = 2 * angle - content.angle;\n },\n offset(content, point, distance, contents) {\n var _a;\n if (!distance) {\n distance = Math.min(...getRectGeometries(content, contents).lines.map((line) => ctx.getPointAndGeometryLineMinimumDistance(point, line)));\n }\n distance *= 2 * (((_a = this.isPointIn) == null ? void 0 : _a.call(this, content, point, contents)) ? -1 : 1);\n return ctx.produce(content, (d) => {\n d.width += distance;\n d.height += distance;\n });\n },\n render(content, renderCtx) {\n const { options, dashed, target } = ctx.getStrokeFillRenderOptionsFromRenderContext(content, renderCtx);\n if (dashed) {\n const { points } = getRectGeometries(content, renderCtx.contents);\n return target.renderPolygon(points, options);\n }\n return target.renderRect(content.x - content.width / 2, content.y - content.height / 2, content.width, content.height, { ...options, angle: content.angle });\n },\n getOperatorRenderPosition(content, contents) {\n const { points } = getRectGeometries(content, contents);\n return points[0];\n },\n getEditPoints(content, contents) {\n return ctx.getEditPointsFromCache(content, () => {\n const { points, midpoints } = getRectGeometries(content, contents);\n return {\n editPoints: [\n { x: content.x, y: content.y, direction: "center" },\n { ...points[0], direction: "left-top" },\n { ...points[1], direction: "right-top" },\n { ...points[2], direction: "right-bottom" },\n { ...points[3], direction: "left-bottom" },\n { ...midpoints[0], direction: "top" },\n { ...midpoints[1], direction: "right" },\n { ...midpoints[2], direction: "bottom" },\n { ...midpoints[3] || midpoints[1], direction: "left" }\n ].map((p, i) => ({\n x: p.x,\n y: p.y,\n type: i === 0 ? "move" : void 0,\n cursor: ctx.getResizeCursor(content.angle, p.direction),\n update(c, { cursor, start, scale }) {\n if (!isRectContent(c)) {\n return;\n }\n const offset = ctx.getResizeOffset(start, cursor, p.direction, -ctx.angleToRadian(content.angle));\n if (!offset) {\n return;\n }\n c.x += offset.x + offset.width / 2;\n c.y += offset.y + offset.height / 2;\n c.width = Math.abs(c.width + offset.width);\n c.height = Math.abs(c.height + offset.height);\n return { assistentContents: [{ type: "line", dashArray: [4 / scale], points: [start, cursor] }] };\n }\n }))\n };\n });\n },\n getSnapPoints(content, contents) {\n return ctx.getSnapPointsFromCache(content, () => {\n const { points, midpoints } = getRectGeometries(content, contents);\n return [\n { x: content.x, y: content.y, type: "center" },\n ...points.map((p) => ({ ...p, type: "endpoint" })),\n ...midpoints.map((p) => ({ ...p, type: "midpoint" }))\n ];\n });\n },\n getGeometries: getRectGeometries,\n canSelectPart: true,\n propertyPanel(content, update, contents, { acquirePoint }) {\n return {\n from: /* @__PURE__ */ React.createElement(ctx.Button, { onClick: () => acquirePoint((p) => update((c) => {\n if (isRectContent(c)) {\n c.x = p.x;\n c.y = p.y;\n }\n })) }, "canvas"),\n x: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.x, setValue: (v) => update((c) => {\n if (isRectContent(c)) {\n c.x = v;\n }\n }) }),\n y: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.y, setValue: (v) => update((c) => {\n if (isRectContent(c)) {\n c.y = v;\n }\n }) }),\n width: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.width, setValue: (v) => update((c) => {\n if (isRectContent(c)) {\n c.width = v;\n }\n }) }),\n height: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.height, setValue: (v) => update((c) => {\n if (isRectContent(c)) {\n c.height = v;\n }\n }) }),\n angle: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.angle, setValue: (v) => update((c) => {\n if (isRectContent(c)) {\n c.angle = v;\n }\n }) }),\n ...ctx.getStrokeContentPropertyPanel(content, update, contents),\n ...ctx.getFillContentPropertyPanel(content, update, contents)\n };\n },\n isValid: (c, p) => ctx.validate(c, RectContent, p),\n getRefIds,\n updateRefId: ctx.updateStrokeAndFillRefIds,\n deleteRefId: ctx.deleteStrokeAndFillRefIds,\n isPointIn: (content, point, contents) => ctx.pointInPolygon(point, getRectGeometries(content, contents).points),\n getArea: (content) => content.width * content.height\n };\n}\nfunction isRectContent(content) {\n return content.type === "rect";\n}\nfunction getCommand(ctx) {\n const React = ctx.React;\n const icon = /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 100 100" }, /* @__PURE__ */ React.createElement("rect", { x: "11", y: "26", width: "79", height: "48", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }));\n return {\n name: "create rect",\n icon,\n useCommand({ onEnd, type, strokeStyleId, fillStyleId }) {\n const { line, onClick, onMove, input, lastPosition, reset } = ctx.useLineClickCreate(\n type === "create rect",\n (c) => onEnd({\n updateContents: (contents) => contents.push({\n type: "rect",\n x: (c[0].x + c[1].x) / 2,\n y: (c[0].y + c[1].y) / 2,\n width: Math.abs(c[0].x - c[1].x),\n height: Math.abs(c[0].y - c[1].y),\n angle: 0,\n strokeStyleId,\n fillStyleId\n })\n }),\n {\n once: true\n }\n );\n const assistentContents = [];\n if (line) {\n assistentContents.push({\n type: "rect",\n x: (line[0].x + line[1].x) / 2,\n y: (line[0].y + line[1].y) / 2,\n width: Math.abs(line[0].x - line[1].x),\n height: Math.abs(line[0].y - line[1].y),\n angle: 0,\n strokeStyleId,\n fillStyleId\n });\n }\n return {\n onStart: onClick,\n input,\n onMove,\n assistentContents,\n lastPosition,\n reset\n };\n },\n selectCount: 0,\n hotkey: "REC"\n };\n}\nexport {\n getCommand,\n getModel,\n isRectContent\n};\n','// dev/cad-editor/plugins/regular-polygon.plugin.tsx\nfunction getModel(ctx) {\n const RegularPolygonContent = ctx.and(ctx.BaseContent("regular polygon"), ctx.StrokeFields, ctx.FillFields, ctx.Position, {\n radius: ctx.number,\n count: ctx.number,\n angle: ctx.number\n });\n const getRefIds = (content) => ctx.getStrokeAndFillRefIds(content);\n const geometriesCache = new ctx.WeakmapValuesCache();\n function getRegularPolygonGeometriesFromCache(content, contents) {\n const refs = new Set(ctx.iterateRefContents(getRefIds(content), contents, [content]));\n return geometriesCache.get(content, refs, () => {\n var _a;\n const angle = -((_a = content.angle) != null ? _a : 0);\n const p0 = ctx.rotatePositionByCenter({ x: content.x + content.radius, y: content.y }, content, angle);\n const points = [];\n for (let i = 0; i < content.count; i++) {\n points.push(ctx.rotatePositionByCenter(p0, content, 360 / content.count * i));\n }\n const lines = Array.from(ctx.iteratePolygonLines(points));\n return {\n points,\n lines,\n bounding: ctx.getPointsBounding(points),\n regions: ctx.hasFill(content) ? [\n {\n lines,\n points\n }\n ] : void 0,\n renderingLines: ctx.dashedPolylineToLines(ctx.polygonToPolyline(points), content.dashArray)\n };\n });\n }\n const React = ctx.React;\n return {\n type: "regular polygon",\n ...ctx.strokeModel,\n ...ctx.fillModel,\n move(content, offset) {\n ctx.movePoint(content, offset);\n },\n scale(content, center, sx, sy, contents) {\n if (sx !== sy) {\n const points = ctx.produce(getRegularPolygonGeometriesFromCache(content, contents).points, (draft) => {\n for (const p of draft) {\n ctx.scalePoint(p, center, sx, sy);\n }\n });\n return { ...content, points, type: "polygon" };\n }\n ctx.scalePoint(content, center, sx, sy);\n content.radius *= sx;\n return;\n },\n skew(content, center, sx, sy, contents) {\n const points = ctx.produce(getRegularPolygonGeometriesFromCache(content, contents).points, (draft) => {\n for (const p of draft) {\n ctx.skewPoint(p, center, sx, sy);\n }\n });\n return { ...content, points, type: "polygon" };\n },\n offset(content, point, distance, contents) {\n var _a;\n if (!distance) {\n distance = Math.min(...getRegularPolygonGeometriesFromCache(content, contents).lines.map((line) => ctx.getPointAndGeometryLineMinimumDistance(point, line)));\n }\n distance *= ((_a = this.isPointIn) == null ? void 0 : _a.call(this, content, point, contents)) ? -1 : 1;\n const radius = distance / Math.cos(Math.PI / content.count);\n return ctx.produce(content, (d) => {\n d.radius += radius;\n });\n },\n render(content, renderCtx) {\n const { options, target } = ctx.getStrokeFillRenderOptionsFromRenderContext(content, renderCtx);\n const { points } = getRegularPolygonGeometriesFromCache(content, renderCtx.contents);\n return target.renderPolygon(points, options);\n },\n getEditPoints(content, contents) {\n return ctx.getEditPointsFromCache(content, () => {\n const { points } = getRegularPolygonGeometriesFromCache(content, contents);\n return {\n editPoints: [\n {\n ...content,\n cursor: "move",\n type: "move",\n update(c, { cursor, start, scale }) {\n if (!isRegularPolygonContent(c)) {\n return;\n }\n c.x += cursor.x - start.x;\n c.y += cursor.y - start.y;\n return { assistentContents: [{ type: "line", dashArray: [4 / scale], points: [start, cursor] }] };\n }\n },\n ...points.map((p) => ({\n x: p.x,\n y: p.y,\n cursor: "move",\n update(c, { cursor, start, scale }) {\n if (!isRegularPolygonContent(c)) {\n return;\n }\n c.radius = ctx.getTwoPointsDistance(cursor, c);\n c.angle = ctx.radianToAngle(ctx.getTwoPointsRadian(cursor, c));\n return { assistentContents: [{ type: "line", dashArray: [4 / scale], points: [start, cursor] }] };\n }\n }))\n ]\n };\n });\n },\n getGeometries: getRegularPolygonGeometriesFromCache,\n propertyPanel(content, update, contents, { acquirePoint }) {\n return {\n from: /* @__PURE__ */ React.createElement(ctx.Button, { onClick: () => acquirePoint((p) => update((c) => {\n if (isRegularPolygonContent(c)) {\n c.x = p.x;\n c.y = p.y;\n }\n })) }, "canvas"),\n x: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.x, setValue: (v) => update((c) => {\n if (isRegularPolygonContent(c)) {\n c.x = v;\n }\n }) }),\n y: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.y, setValue: (v) => update((c) => {\n if (isRegularPolygonContent(c)) {\n c.y = v;\n }\n }) }),\n radius: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.radius, setValue: (v) => update((c) => {\n if (isRegularPolygonContent(c)) {\n c.radius = v;\n }\n }) }),\n count: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.count, setValue: (v) => update((c) => {\n if (isRegularPolygonContent(c)) {\n c.count = v;\n }\n }) }),\n angle: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.angle, setValue: (v) => update((c) => {\n if (isRegularPolygonContent(c)) {\n c.angle = v;\n }\n }) }),\n ...ctx.getStrokeContentPropertyPanel(content, update, contents),\n ...ctx.getFillContentPropertyPanel(content, update, contents)\n };\n },\n canSelectPart: true,\n isValid: (c, p) => ctx.validate(c, RegularPolygonContent, p),\n getRefIds,\n updateRefId: ctx.updateStrokeAndFillRefIds,\n deleteRefId: ctx.deleteStrokeAndFillRefIds,\n isPointIn: (content, point, contents) => ctx.pointInPolygon(point, getRegularPolygonGeometriesFromCache(content, contents).points)\n };\n}\nfunction isRegularPolygonContent(content) {\n return content.type === "regular polygon";\n}\nfunction getCommand(ctx) {\n const React = ctx.React;\n const icon = /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 100 100" }, /* @__PURE__ */ React.createElement("polygon", { points: "91,40 53,7 10,33 22,82 72,85", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }));\n return {\n name: "create regular polygon",\n icon,\n useCommand({ onEnd, type, strokeStyleId, fillStyleId }) {\n const { line, onClick, onMove, input, lastPosition, reset } = ctx.useLineClickCreate(\n type === "create regular polygon",\n ([p0, p1]) => onEnd({\n updateContents: (contents) => {\n contents.push({\n type: "regular polygon",\n x: p0.x,\n y: p0.y,\n radius: ctx.getTwoPointsDistance(p0, p1),\n count: 5,\n angle: ctx.radianToAngle(ctx.getTwoPointsRadian(p1, p0)),\n strokeStyleId,\n fillStyleId\n });\n }\n }),\n {\n once: true\n }\n );\n const assistentContents = [];\n if (line) {\n const [p0, p1] = line;\n assistentContents.push({\n type: "regular polygon",\n x: p0.x,\n y: p0.y,\n radius: ctx.getTwoPointsDistance(p0, p1),\n count: 5,\n angle: ctx.radianToAngle(ctx.getTwoPointsRadian(p1, p0)),\n strokeStyleId,\n fillStyleId\n });\n }\n return {\n onStart: onClick,\n input,\n onMove,\n assistentContents,\n lastPosition,\n reset\n };\n },\n selectCount: 0\n };\n}\nexport {\n getCommand,\n getModel,\n isRegularPolygonContent\n};\n','// dev/cad-editor/plugins/reverse.plugin.tsx\nfunction getCommand(ctx) {\n const React = ctx.React;\n const icon = /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 100 100" }, /* @__PURE__ */ React.createElement("polyline", { points: "1,71 56,7", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polyline", { points: "62,0 54,18 46,11", strokeWidth: "0", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "currentColor", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polyline", { points: "97,27 91,34", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polyline", { points: "84,42 78,50", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polyline", { points: "71,57 64,65", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polyline", { points: "58,72 51,80", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polyline", { points: "45,87 42,90", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polyline", { points: "36,97 45,79 53,86", strokeWidth: "0", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "currentColor", stroke: "currentColor" }));\n return {\n name: "reverse",\n execute({ contents, selected }) {\n contents.forEach((content, index) => {\n var _a, _b, _c, _d;\n if (content && ctx.isSelected([index], selected) && ((_b = (_a = this.contentSelectable) == null ? void 0 : _a.call(this, content, contents)) != null ? _b : true)) {\n const result = (_d = (_c = ctx.getContentModel(content)) == null ? void 0 : _c.reverse) == null ? void 0 : _d.call(_c, content, contents);\n if (result) {\n contents[index] = result;\n }\n }\n });\n },\n contentSelectable(content) {\n var _a;\n return !content.readonly && ((_a = ctx.getContentModel(content)) == null ? void 0 : _a.reverse) !== void 0;\n },\n icon\n };\n}\nexport {\n getCommand\n};\n','// dev/cad-editor/plugins/ring.plugin.tsx\nfunction getModel(ctx) {\n const RingContent = ctx.and(ctx.BaseContent("ring"), ctx.StrokeFields, ctx.FillFields, ctx.AngleDeltaFields, ctx.Position, {\n outerRadius: ctx.number,\n innerRadius: ctx.number\n });\n const getRefIds = (content) => ctx.getStrokeAndFillRefIds(content);\n function getRingGeometriesFromCache(content, contents) {\n const refs = new Set(ctx.iterateRefContents(getRefIds(content), contents, [content]));\n return ctx.getGeometriesFromCache(content, refs, () => {\n var _a;\n const angleDelta = (_a = content.angleDelta) != null ? _a : ctx.defaultAngleDelta;\n const arc1 = ctx.circleToArc({ ...content, r: content.outerRadius });\n const arc2 = ctx.circleToArc({ ...content, r: content.innerRadius });\n const points1 = ctx.arcToPolyline(arc1, angleDelta);\n const points2 = ctx.arcToPolyline(arc2, angleDelta);\n const lines = [{ type: "arc", curve: arc1 }, { type: "arc", curve: arc2 }];\n return {\n lines,\n bounding: ctx.getCircleBounding({ ...content, r: content.outerRadius }),\n regions: ctx.hasFill(content) ? [\n {\n lines: [lines[0]],\n points: points1,\n holesPoints: [points2],\n holes: [[lines[1]]]\n }\n ] : void 0,\n renderingLines: [\n ...ctx.dashedPolylineToLines(ctx.polygonToPolyline(points1), content.dashArray),\n ...ctx.dashedPolylineToLines(ctx.polygonToPolyline(points2), content.dashArray)\n ]\n };\n });\n }\n const React = ctx.React;\n return {\n type: "ring",\n ...ctx.strokeModel,\n ...ctx.fillModel,\n ...ctx.angleDeltaModel,\n move(content, offset) {\n ctx.movePoint(content, offset);\n },\n scale(content, center, sx, sy) {\n ctx.scalePoint(content, center, sx, sy);\n content.innerRadius *= sx;\n content.outerRadius *= sx;\n },\n render(content, renderCtx) {\n const { options, target } = ctx.getStrokeFillRenderOptionsFromRenderContext(content, renderCtx);\n const { renderingLines, regions } = getRingGeometriesFromCache(content, renderCtx.contents);\n if (regions) {\n return target.renderPath([regions[0].points, ...regions[0].holesPoints || []], options);\n }\n return target.renderGroup(renderingLines.map((r) => target.renderPolyline(r, options)));\n },\n getEditPoints(content) {\n return ctx.getEditPointsFromCache(content, () => {\n return {\n editPoints: [\n {\n ...content,\n cursor: "move",\n update(c, { cursor, start, scale }) {\n if (!isRingContent(c)) {\n return;\n }\n c.x += cursor.x - start.x;\n c.y += cursor.y - start.y;\n return { assistentContents: [{ type: "line", dashArray: [4 / scale], points: [start, cursor] }] };\n }\n }\n ]\n };\n });\n },\n getGeometries: getRingGeometriesFromCache,\n propertyPanel(content, update, contents, { acquirePoint }) {\n return {\n from: /* @__PURE__ */ React.createElement(ctx.Button, { onClick: () => acquirePoint((p) => update((c) => {\n if (isRingContent(c)) {\n c.x = p.x;\n c.y = p.y;\n }\n })) }, "canvas"),\n x: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.x, setValue: (v) => update((c) => {\n if (isRingContent(c)) {\n c.x = v;\n }\n }) }),\n y: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.y, setValue: (v) => update((c) => {\n if (isRingContent(c)) {\n c.y = v;\n }\n }) }),\n outerRadius: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.outerRadius, setValue: (v) => update((c) => {\n if (isRingContent(c)) {\n c.outerRadius = v;\n }\n }) }),\n innerRadius: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.innerRadius, setValue: (v) => update((c) => {\n if (isRingContent(c)) {\n c.innerRadius = v;\n }\n }) }),\n ...ctx.getStrokeContentPropertyPanel(content, update, contents),\n ...ctx.getFillContentPropertyPanel(content, update, contents),\n ...ctx.getAngleDeltaContentPropertyPanel(content, update)\n };\n },\n isValid: (c, p) => ctx.validate(c, RingContent, p),\n getRefIds,\n updateRefId: ctx.updateStrokeAndFillRefIds,\n deleteRefId: ctx.deleteStrokeAndFillRefIds\n };\n}\nfunction isRingContent(content) {\n return content.type === "ring";\n}\nfunction getCommand(ctx) {\n const React = ctx.React;\n const icon = /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 100 100" }, /* @__PURE__ */ React.createElement("polyline", { points: "91,50 91,53 91,57 90,60 89,64 87,67 86,70 84,74 82,76 79,79 76,82 74,84 70,86 67,87 64,89 60,90 57,91 53,91 50,91 46,91 42,91 39,90 35,89 32,87 29,86 25,84 23,82 20,79 17,76 15,74 13,70 12,67 10,64 9,60 8,57 8,53 8,50 8,46 8,42 9,39 10,35 12,32 13,29 15,25 17,23 20,20 23,17 25,15 29,13 32,12 35,10 39,9 42,8 46,8 49,8 53,8 57,8 60,9 64,10 67,12 70,13 74,15 76,17 79,20 82,23 84,25 86,29 87,32 89,35 90,39 91,42 91,46 91,49", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polyline", { points: "70,50 70,51 70,53 70,55 69,57 68,58 68,60 67,62 66,63 64,64 63,66 62,67 60,68 58,68 57,69 55,70 53,70 51,70 50,70 48,70 46,70 44,70 42,69 41,68 39,68 37,67 36,66 35,64 33,63 32,62 31,60 31,58 30,57 29,55 29,53 29,51 29,50 29,48 29,46 29,44 30,42 31,41 31,39 32,37 33,36 35,35 36,33 37,32 39,31 41,31 42,30 44,29 46,29 48,29 49,29 51,29 53,29 55,29 57,30 58,31 60,31 62,32 63,33 64,35 66,36 67,37 68,39 68,41 69,42 70,44 70,46 70,48 70,49", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }));\n return {\n name: "create ring",\n icon,\n useCommand({ onEnd, type, strokeStyleId, fillStyleId }) {\n const { line, onClick, onMove, input, lastPosition, reset } = ctx.useLineClickCreate(\n type === "create ring",\n (c) => onEnd({\n updateContents: (contents) => {\n const outerRadius = ctx.getTwoPointsDistance(c[0], c[1]);\n contents.push({\n type: "ring",\n x: c[0].x,\n y: c[0].y,\n outerRadius,\n innerRadius: outerRadius * 0.5,\n strokeStyleId,\n fillStyleId\n });\n }\n }),\n {\n once: true\n }\n );\n const assistentContents = [];\n if (line) {\n const outerRadius = ctx.getTwoPointsDistance(line[0], line[1]);\n assistentContents.push({\n type: "ring",\n x: line[0].x,\n y: line[0].y,\n outerRadius,\n innerRadius: outerRadius * 0.5,\n strokeStyleId,\n fillStyleId\n });\n }\n return {\n onStart: onClick,\n input,\n onMove,\n assistentContents,\n lastPosition,\n reset\n };\n },\n selectCount: 0\n };\n}\nexport {\n getCommand,\n getModel,\n isRingContent\n};\n','// dev/cad-editor/plugins/rotate.plugin.tsx\nfunction getCommand(ctx) {\n const React = ctx.React;\n const icon = /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 100 100" }, /* @__PURE__ */ React.createElement("polygon", { points: "5,66 66,66 66,94 5,94", strokeWidth: "5", strokeDasharray: "10", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("rect", { x: "35", y: "26", width: "61", height: "28", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor", transform: "rotate(56,66,40)" }));\n return {\n name: "rotate",\n icon,\n useCommand({ onEnd, transform, type, scale }) {\n const [changeOriginal, setChangeOriginal] = React.useState(true);\n const { offset, onStart, mask, center: startPosition, resetDragRotate } = ctx.useDragRotate(\n onEnd,\n {\n transform,\n transformOffset: (f) => f - 90,\n ignoreLeavingEvent: true\n }\n );\n let message = "";\n if (type) {\n message = startPosition ? "specify angle point" : "specify center point";\n }\n const { input, setInputPosition } = ctx.useCursorInput(message);\n let assistentContents;\n if (startPosition && (offset == null ? void 0 : offset.angle) !== void 0) {\n const r = ctx.getTwoPointsDistance(startPosition, offset);\n assistentContents = [\n {\n type: "line",\n dashArray: [4 / scale],\n points: [startPosition, offset]\n },\n {\n type: "arc",\n x: startPosition.x,\n y: startPosition.y,\n r,\n dashArray: [4 / scale],\n startAngle: offset.angle > 180 || offset.angle < 0 ? offset.angle : 0,\n endAngle: offset.angle > 180 || offset.angle < 0 ? 0 : offset.angle\n },\n {\n type: "line",\n dashArray: [4 / scale],\n points: [startPosition, { x: startPosition.x + r, y: startPosition.y }]\n }\n ];\n }\n return {\n onStart,\n mask,\n input,\n onMove(_, p) {\n setInputPosition(p);\n },\n reset: resetDragRotate,\n subcommand: type ? /* @__PURE__ */ React.createElement(\n "button",\n {\n onClick: (e) => {\n setChangeOriginal(!changeOriginal);\n e.stopPropagation();\n }\n },\n changeOriginal ? "create new(N)" : "change original(Y)"\n ) : void 0,\n updateSelectedContent(content, contents, selected) {\n if (startPosition && (offset == null ? void 0 : offset.angle) !== void 0) {\n const angle = offset.angle;\n if (!changeOriginal) {\n return {\n newContents: [\n ctx.produce(content, (d) => {\n var _a, _b;\n (_b = (_a = ctx.getContentModel(d)) == null ? void 0 : _a.rotate) == null ? void 0 : _b.call(_a, d, startPosition, angle, contents);\n })\n ]\n };\n }\n const [newContent, ...patches] = ctx.produceWithPatches(content, (draft) => {\n var _a, _b;\n (_b = (_a = ctx.getContentModel(content)) == null ? void 0 : _a.rotate) == null ? void 0 : _b.call(_a, draft, startPosition, angle, contents);\n });\n const assistentContents2 = ctx.updateReferencedContents(content, newContent, contents, selected);\n return {\n patches,\n assistentContents: assistentContents2\n };\n }\n return {};\n },\n assistentContents\n };\n },\n contentSelectable(content) {\n var _a;\n return !content.readonly && ((_a = ctx.getContentModel(content)) == null ? void 0 : _a.rotate) !== void 0;\n },\n hotkey: "RO"\n };\n}\nexport {\n getCommand\n};\n','// dev/cad-editor/plugins/rounded-rect.plugin.tsx\nfunction getModel(ctx) {\n const RoundedRectContent = ctx.and(ctx.BaseContent("rounded rect"), ctx.StrokeFields, ctx.FillFields, ctx.Region, ctx.AngleDeltaFields, {\n radius: ctx.number\n });\n const getRefIds = (content) => ctx.getStrokeAndFillRefIds(content);\n const geometriesCache = new ctx.WeakmapValuesCache();\n function getGeometries(content, contents) {\n const refs = new Set(ctx.iterateRefContents(getRefIds(content), contents, [content]));\n return geometriesCache.get(content, refs, () => {\n var _a;\n const rectPoints = [\n { x: content.x - content.width / 2, y: content.y - content.height / 2 },\n { x: content.x + content.width / 2, y: content.y - content.height / 2 },\n { x: content.x + content.width / 2, y: content.y + content.height / 2 },\n { x: content.x - content.width / 2, y: content.y + content.height / 2 }\n ];\n const points = ctx.getRoundedRectPoints(content, content.radius, (_a = content.angleDelta) != null ? _a : ctx.defaultAngleDelta);\n const lines = Array.from(ctx.iteratePolygonLines(points));\n const geometryLines = [\n { type: "arc", curve: { x: content.x - content.width / 2 + content.radius, y: content.y - content.height / 2 + content.radius, r: content.radius, startAngle: 180, endAngle: 270 } },\n [{ x: content.x - content.width / 2 + content.radius, y: content.y - content.height / 2 }, { x: content.x + content.width / 2 - content.radius, y: content.y - content.height / 2 }],\n { type: "arc", curve: { x: content.x + content.width / 2 - content.radius, y: content.y - content.height / 2 + content.radius, r: content.radius, startAngle: 270, endAngle: 360 } },\n [{ x: content.x + content.width / 2, y: content.y - content.height / 2 + content.radius }, { x: content.x + content.width / 2, y: content.y + content.height / 2 - content.radius }],\n { type: "arc", curve: { x: content.x + content.width / 2 - content.radius, y: content.y + content.height / 2 - content.radius, r: content.radius, startAngle: 0, endAngle: 90 } },\n [{ x: content.x + content.width / 2 - content.radius, y: content.y + content.height / 2 }, { x: content.x - content.width / 2 + content.radius, y: content.y + content.height / 2 }],\n { type: "arc", curve: { x: content.x - content.width / 2 + content.radius, y: content.y + content.height / 2 - content.radius, r: content.radius, startAngle: 80, endAngle: 180 } },\n [{ x: content.x - content.width / 2, y: content.y + content.height / 2 - content.radius }, { x: content.x - content.width / 2, y: content.y - content.height / 2 + content.radius }]\n ];\n return {\n lines: geometryLines,\n points: rectPoints,\n arcPoints: [\n { x: rectPoints[0].x + content.radius, y: rectPoints[0].y },\n { x: rectPoints[0].x, y: rectPoints[0].y + content.radius },\n { x: rectPoints[1].x - content.radius, y: rectPoints[1].y },\n { x: rectPoints[1].x, y: rectPoints[1].y + content.radius },\n { x: rectPoints[2].x - content.radius, y: rectPoints[2].y },\n { x: rectPoints[2].x, y: rectPoints[2].y - content.radius },\n { x: rectPoints[3].x + content.radius, y: rectPoints[3].y },\n { x: rectPoints[3].x, y: rectPoints[3].y - content.radius }\n ],\n bounding: ctx.getGeometryLinesBounding(geometryLines),\n renderingLines: ctx.dashedPolylineToLines(ctx.polygonToPolyline(points), content.dashArray),\n regions: ctx.hasFill(content) ? [\n {\n lines,\n points\n }\n ] : void 0\n };\n });\n }\n const React = ctx.React;\n return {\n type: "rounded rect",\n ...ctx.strokeModel,\n ...ctx.fillModel,\n ...ctx.angleDeltaModel,\n move(content, offset) {\n ctx.movePoint(content, offset);\n },\n scale(content, center, sx, sy) {\n ctx.scalePoint(content, center, sx, sy);\n content.width *= sx;\n content.height *= sy;\n content.radius *= sx;\n },\n offset(content, point, distance, contents) {\n var _a;\n if (!distance) {\n distance = Math.min(...getGeometries(content, contents).lines.map((line) => ctx.getPointAndGeometryLineMinimumDistance(point, line)));\n }\n distance *= ((_a = this.isPointIn) == null ? void 0 : _a.call(this, content, point, contents)) ? -2 : 2;\n return ctx.produce(content, (d) => {\n d.width += distance;\n d.height += distance;\n });\n },\n render(content, renderCtx) {\n const { options, target } = ctx.getStrokeFillRenderOptionsFromRenderContext(content, renderCtx);\n const { renderingLines } = getGeometries(content, renderCtx.contents);\n return target.renderPath(renderingLines, options);\n },\n renderIfSelected(content, { color, target, strokeWidth, contents }) {\n const { points, arcPoints } = getGeometries(content, contents);\n return target.renderGroup(points.map((p, i) => target.renderPolyline([arcPoints[2 * i], p, arcPoints[2 * i + 1]], { strokeColor: color, dashArray: [4], strokeWidth })));\n },\n getEditPoints(content, contents) {\n return ctx.getEditPointsFromCache(content, () => {\n const { points } = getGeometries(content, contents);\n return {\n editPoints: [\n { x: content.x, y: content.y, direction: "center" },\n { ...points[0], direction: "left-top" },\n { ...points[1], direction: "right-top" },\n { ...points[2], direction: "right-bottom" },\n { ...points[3], direction: "left-bottom" }\n ].map((p) => ({\n x: p.x,\n y: p.y,\n cursor: ctx.getResizeCursor(0, p.direction),\n update(c, { cursor, start, scale }) {\n if (!isRoundedRectContent(c)) {\n return;\n }\n const offset = ctx.getResizeOffset(start, cursor, p.direction);\n if (!offset) {\n return;\n }\n c.x += offset.x + offset.width / 2;\n c.y += offset.y + offset.height / 2;\n c.width += offset.width;\n c.height += offset.height;\n return { assistentContents: [{ type: "line", dashArray: [4 / scale], points: [start, cursor] }] };\n }\n }))\n };\n });\n },\n getSnapPoints(content, contents) {\n return ctx.getSnapPointsFromCache(content, () => {\n const { points } = getGeometries(content, contents);\n return [\n { x: content.x, y: content.y, type: "center" },\n ...points.map((p) => ({ ...p, type: "endpoint" })),\n ...Array.from(ctx.iteratePolygonLines(points)).map(([start, end]) => ({\n x: (start.x + end.x) / 2,\n y: (start.y + end.y) / 2,\n type: "midpoint"\n }))\n ];\n });\n },\n getGeometries,\n canSelectPart: true,\n propertyPanel(content, update, contents, { acquirePoint }) {\n return {\n from: /* @__PURE__ */ React.createElement(ctx.Button, { onClick: () => acquirePoint((p) => update((c) => {\n if (isRoundedRectContent(c)) {\n c.x = p.x;\n c.y = p.y;\n }\n })) }, "canvas"),\n x: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.x, setValue: (v) => update((c) => {\n if (isRoundedRectContent(c)) {\n c.x = v;\n }\n }) }),\n y: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.y, setValue: (v) => update((c) => {\n if (isRoundedRectContent(c)) {\n c.y = v;\n }\n }) }),\n width: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.width, setValue: (v) => update((c) => {\n if (isRoundedRectContent(c)) {\n c.width = v;\n }\n }) }),\n height: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.height, setValue: (v) => update((c) => {\n if (isRoundedRectContent(c)) {\n c.height = v;\n }\n }) }),\n radius: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.radius, setValue: (v) => update((c) => {\n if (isRoundedRectContent(c)) {\n c.radius = v;\n }\n }) }),\n ...ctx.getStrokeContentPropertyPanel(content, update, contents),\n ...ctx.getFillContentPropertyPanel(content, update, contents),\n ...ctx.getAngleDeltaContentPropertyPanel(content, update)\n };\n },\n isValid: (c, p) => ctx.validate(c, RoundedRectContent, p),\n getRefIds,\n updateRefId: ctx.updateStrokeAndFillRefIds,\n deleteRefId: ctx.deleteStrokeAndFillRefIds,\n isPointIn: (content, point, contents) => ctx.pointInPolygon(point, getGeometries(content, contents).points)\n };\n}\nfunction isRoundedRectContent(content) {\n return content.type === "rounded rect";\n}\nfunction getCommand(ctx) {\n const React = ctx.React;\n const icon = /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 100 100" }, /* @__PURE__ */ React.createElement("path", { d: "M 35 11 L 65 11 L 65 11 L 67 11 L 69 11 L 71 12 L 73 13 L 75 13 L 77 14 L 79 16 L 81 17 L 82 18 L 84 20 L 85 22 L 86 24 L 87 25 L 88 27 L 89 30 L 89 32 L 89 34 L 90 36 L 90 36 L 90 66 L 90 66 L 89 68 L 89 70 L 89 72 L 88 74 L 87 76 L 86 78 L 85 80 L 84 82 L 82 83 L 81 85 L 79 86 L 77 87 L 75 88 L 73 89 L 71 90 L 69 90 L 67 90 L 65 91 L 65 91 L 35 91 L 35 91 L 33 90 L 31 90 L 29 90 L 26 89 L 24 88 L 23 87 L 21 86 L 19 85 L 17 83 L 16 82 L 15 80 L 13 78 L 12 76 L 12 74 L 11 72 L 10 70 L 10 68 L 10 66 L 10 66 L 10 36 L 10 36 L 10 34 L 10 32 L 11 30 L 12 27 L 12 25 L 13 23 L 15 22 L 16 20 L 17 18 L 19 17 L 21 16 L 22 14 L 24 13 L 26 13 L 29 12 L 31 11 L 33 11 L 35 11", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor", fillRule: "evenodd" }));\n return {\n name: "create rounded rect",\n icon,\n useCommand({ onEnd, type, strokeStyleId, fillStyleId }) {\n const { line, onClick, onMove, input, lastPosition, reset } = ctx.useLineClickCreate(\n type === "create rounded rect",\n (c) => onEnd({\n updateContents: (contents) => {\n const width = Math.abs(c[0].x - c[1].x);\n const height = Math.abs(c[0].y - c[1].y);\n contents.push({\n type: "rounded rect",\n x: (c[0].x + c[1].x) / 2,\n y: (c[0].y + c[1].y) / 2,\n width,\n height,\n radius: Math.round(Math.min(width, height) / 4),\n strokeStyleId,\n fillStyleId\n });\n }\n }),\n {\n once: true\n }\n );\n const assistentContents = [];\n if (line) {\n const width = Math.abs(line[0].x - line[1].x);\n const height = Math.abs(line[0].y - line[1].y);\n assistentContents.push({\n type: "rounded rect",\n x: (line[0].x + line[1].x) / 2,\n y: (line[0].y + line[1].y) / 2,\n width,\n height,\n radius: Math.round(Math.min(width, height) / 4),\n strokeStyleId,\n fillStyleId\n });\n }\n return {\n onStart: onClick,\n input,\n onMove,\n assistentContents,\n lastPosition,\n reset\n };\n },\n selectCount: 0\n };\n}\nexport {\n getCommand,\n getModel,\n isRoundedRectContent\n};\n','// dev/cad-editor/plugins/scale.plugin.tsx\nfunction getCommand(ctx) {\n const React = ctx.React;\n const icon = /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 100 100" }, /* @__PURE__ */ React.createElement("polygon", { points: "12,11 91,11 91,90 12,90", strokeWidth: "5", strokeDasharray: "10", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fillOpacity: "1", strokeOpacity: "1", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("rect", { x: "40", y: "37", width: "42", height: "42", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fillOpacity: "1", strokeOpacity: "1", fill: "none", stroke: "currentColor" }));\n return {\n name: "scale",\n useCommand({ onEnd, scale, type, selected, contents }) {\n const [data, setData] = React.useState();\n const [cursor, setCursor] = React.useState();\n let message = "";\n if (type) {\n message = data ? "specify scale" : "specify center point";\n }\n const { input, setInputPosition, resetInput, setCursorPosition } = ctx.useCursorInput(message, type ? (e, text) => {\n if (e.key === "Enter" && data) {\n const value = +text;\n if (!isNaN(value) && value > 0) {\n onEnd({\n updateContents(contents2, selected2) {\n contents2.forEach((content, index) => {\n var _a, _b;\n if (content && ctx.isSelected([index], selected2)) {\n const result = (_b = (_a = ctx.getContentModel(content)) == null ? void 0 : _a.scale) == null ? void 0 : _b.call(_a, content, data.center, value, value, contents2);\n if (result) {\n contents2[index] = result;\n }\n }\n });\n }\n });\n reset();\n }\n }\n } : void 0);\n const reset = () => {\n setData(void 0);\n setCursor(void 0);\n resetInput();\n };\n return {\n onStart(s) {\n var _a, _b, _c;\n if (!type) return;\n if (!data) {\n const boundings = [];\n for (const c of selected) {\n const bounding2 = (_c = (_b = (_a = ctx.getContentModel(c.content)) == null ? void 0 : _a.getGeometries) == null ? void 0 : _b.call(_a, c.content, contents)) == null ? void 0 : _c.bounding;\n if (bounding2) {\n boundings.push(bounding2);\n }\n }\n const bounding = ctx.mergeBoundings(boundings);\n if (bounding) {\n const size = ctx.getTwoPointsFormRegionSize(bounding);\n setData({ center: s, size: Math.max(size.width, size.height) });\n }\n } else {\n onEnd();\n reset();\n }\n },\n onMove(p, c) {\n if (!type) return;\n setInputPosition(c || p);\n setCursorPosition(c || p);\n if (data) {\n setCursor(p);\n }\n },\n reset,\n input,\n updateSelectedContent(content, contents2, selected2) {\n if (data && cursor) {\n const sx = ctx.getTwoNumbersDistance(cursor.x, data.center.x) / data.size;\n const sy = ctx.getTwoNumbersDistance(cursor.y, data.center.y) / data.size;\n if (!sx || !sy) {\n return {};\n }\n const [newContent, ...patches] = ctx.produceWithPatches(content, (draft) => {\n var _a, _b;\n return (_b = (_a = ctx.getContentModel(content)) == null ? void 0 : _a.scale) == null ? void 0 : _b.call(_a, draft, data.center, sx, sy, contents2);\n });\n const assistentContents = ctx.updateReferencedContents(content, newContent, contents2, selected2);\n return {\n patches,\n assistentContents\n };\n }\n return {};\n },\n assistentContents: data && cursor ? [\n {\n type: "line",\n dashArray: [4 / scale],\n points: [data.center, cursor]\n }\n ] : void 0\n };\n },\n contentSelectable(content) {\n var _a;\n return !content.readonly && ((_a = ctx.getContentModel(content)) == null ? void 0 : _a.scale) !== void 0;\n },\n icon\n };\n}\nexport {\n getCommand\n};\n','// dev/cad-editor/plugins/shortest.plugin.tsx\nfunction getCommand(ctx) {\n const React = ctx.React;\n const icon = /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 100 100" }, /* @__PURE__ */ React.createElement("polyline", { points: "24,50 24,56 23,61 22,67 20,72 18,77 15,82 12,87 9,91 5,95 1,99 -3,102 -8,105 -13,108 -18,110 -23,112 -29,113 -34,114 -40,114 -46,114 -51,113 -57,112 -62,110 -67,108 -72,105 -77,102 -81,99 -85,95 -89,91 -92,87 -95,82 -98,77 -100,72 -102,67 -103,61 -104,56 -104,50 -104,44 -103,39 -102,33 -100,28 -98,23 -95,18 -92,13 -89,9 -85,5 -81,1 -77,-2 -72,-5 -67,-8 -62,-10 -57,-12 -51,-13 -46,-14 -40,-14 -34,-14 -29,-13 -23,-12 -18,-10 -13,-8 -8,-5 -3,-2 1,1 5,5 9,9 12,13 15,18 18,23 20,28 22,33 23,39 24,44 24,50", strokeWidth: "4", strokeDasharray: "10", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fillOpacity: "1", strokeOpacity: "1", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polyline", { points: "204,50 204,56 203,61 202,67 200,72 198,77 195,82 192,87 189,91 185,95 181,99 177,102 172,105 167,108 162,110 157,112 151,113 146,114 140,114 134,114 129,113 123,112 118,110 113,108 108,105 103,102 99,99 95,95 91,91 88,87 85,82 82,77 80,72 78,67 77,61 76,56 76,50 76,44 77,39 78,33 80,28 82,23 85,18 88,13 91,9 95,5 99,1 103,-2 108,-5 113,-8 118,-10 123,-12 129,-13 134,-14 140,-14 146,-14 151,-13 157,-12 162,-10 167,-8 172,-5 177,-2 181,1 185,5 189,9 192,13 195,18 198,23 200,28 202,33 203,39 204,44 204,50", strokeWidth: "4", strokeDasharray: "10", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fillOpacity: "1", strokeOpacity: "1", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polyline", { points: "24,50 76,50", strokeWidth: "4", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", strokeOpacity: "1", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("circle", { cx: "24", cy: "50", r: "6", strokeWidth: "0", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fillOpacity: "1", strokeOpacity: "1", fill: "currentColor", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("circle", { cx: "76", cy: "50", r: "6", strokeWidth: "0", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fillOpacity: "1", strokeOpacity: "1", fill: "currentColor", stroke: "currentColor" }));\n return {\n name: "shortest",\n execute({ contents, selected }) {\n var _a, _b, _c, _d;\n const first = contents[selected[0][0]];\n if (!first) return;\n const firstGeometries = (_b = (_a = ctx.getContentModel(first)) == null ? void 0 : _a.getGeometries) == null ? void 0 : _b.call(_a, first, contents);\n if (!firstGeometries) return;\n const second = contents[selected[1][0]];\n if (!second) return;\n const secondGeometries = (_d = (_c = ctx.getContentModel(second)) == null ? void 0 : _c.getGeometries) == null ? void 0 : _d.call(_c, second, contents);\n if (!secondGeometries) return;\n const result = ctx.getShortestDistanceOfTwoGeometryLines(firstGeometries.lines, secondGeometries.lines);\n if (result && ctx.largerThan(result.distance, 0)) {\n contents.push({ type: "line", points: result.points });\n }\n },\n contentSelectable(content, contents) {\n return ctx.contentIsDeletable(content, contents);\n },\n selectCount: 2,\n icon\n };\n}\nexport {\n getCommand\n};\n','// dev/cad-editor/plugins/skew.plugin.tsx\nfunction getCommand(ctx) {\n const React = ctx.React;\n const icon = /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 100 100" }, /* @__PURE__ */ React.createElement("rect", { x: "5", y: "5", width: "51", height: "89", strokeWidth: "5", strokeDasharray: "10", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fillOpacity: "1", strokeOpacity: "1", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polygon", { points: "40,5 92,5 57,95 5,95", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fillOpacity: "1", strokeOpacity: "1", fill: "none", stroke: "currentColor" }));\n return {\n name: "skew",\n useCommand({ onEnd, scale, type, selected, contents }) {\n const [data, setData] = React.useState();\n const [cursor, setCursor] = React.useState();\n let message = "";\n if (type) {\n message = data ? "specify skew" : "specify center point";\n }\n const { input, setInputPosition, resetInput, setCursorPosition } = ctx.useCursorInput(message, type ? (e, text) => {\n if (e.key === "Enter" && data) {\n const value = +text;\n if (!isNaN(value)) {\n onEnd({\n updateContents(contents2, selected2) {\n contents2.forEach((content, index) => {\n var _a, _b;\n if (content && ctx.isSelected([index], selected2)) {\n const result = (_b = (_a = ctx.getContentModel(content)) == null ? void 0 : _a.skew) == null ? void 0 : _b.call(_a, content, data.center, value, 0, contents2);\n if (result) {\n contents2[index] = result;\n }\n }\n });\n }\n });\n reset();\n }\n }\n } : void 0);\n const reset = () => {\n setData(void 0);\n setCursor(void 0);\n resetInput();\n };\n return {\n onStart(s) {\n var _a, _b, _c;\n if (!type) return;\n if (!data) {\n const boundings = [];\n for (const c of selected) {\n const bounding2 = (_c = (_b = (_a = ctx.getContentModel(c.content)) == null ? void 0 : _a.getGeometries) == null ? void 0 : _b.call(_a, c.content, contents)) == null ? void 0 : _c.bounding;\n if (bounding2) {\n boundings.push(bounding2);\n }\n }\n const bounding = ctx.mergeBoundings(boundings);\n if (bounding) {\n const size = ctx.getTwoPointsFormRegionSize(bounding);\n setData({ center: s, size: Math.max(size.width, size.height) });\n }\n } else {\n onEnd();\n reset();\n }\n },\n onMove(p, c) {\n if (!type) return;\n setInputPosition(c || p);\n setCursorPosition(c || p);\n if (data) {\n setCursor(p);\n }\n },\n reset,\n input,\n updateSelectedContent(content, contents2, selected2) {\n if (data && cursor) {\n const sx = (cursor.x - data.center.x) / data.size;\n if (!sx) {\n return {};\n }\n const sy = (cursor.y - data.center.y) / data.size;\n const [newContent, ...patches] = ctx.produceWithPatches(content, (draft) => {\n var _a, _b;\n return (_b = (_a = ctx.getContentModel(content)) == null ? void 0 : _a.skew) == null ? void 0 : _b.call(_a, draft, data.center, sx, sy, contents2);\n });\n const assistentContents = ctx.updateReferencedContents(content, newContent, contents2, selected2);\n return {\n patches,\n assistentContents\n };\n }\n return {};\n },\n assistentContents: data && cursor ? [\n {\n type: "line",\n dashArray: [4 / scale],\n points: [data.center, cursor]\n }\n ] : void 0\n };\n },\n contentSelectable(content) {\n var _a;\n return !content.readonly && ((_a = ctx.getContentModel(content)) == null ? void 0 : _a.skew) !== void 0;\n },\n icon\n };\n}\nexport {\n getCommand\n};\n','// dev/cad-editor/plugins/spline.plugin.tsx\nfunction getModel(ctx) {\n const SplineContent = ctx.and(ctx.BaseContent("spline"), ctx.StrokeFields, ctx.FillFields, ctx.SegmentCountFields, {\n points: [ctx.Position],\n fitting: ctx.optional(ctx.or(ctx.boolean, "closed"))\n });\n const SplineArrowContent = ctx.and(ctx.BaseContent("spline arrow"), ctx.StrokeFields, ctx.SegmentCountFields, {\n points: [ctx.Position],\n fitting: ctx.optional(ctx.boolean)\n });\n const getSplineRefIds = (content) => ctx.getStrokeAndFillRefIds(content);\n const getSplineArrowRefIds = (content) => ctx.getStrokeRefIds(content);\n const geometriesCache = new ctx.WeakmapValuesCache();\n function getSplineGeometries(content, contents) {\n const refs = new Set(ctx.iterateRefContents(getSplineRefIds(content), contents, [content]));\n return geometriesCache.get(content, refs, () => {\n var _a;\n let points;\n let lines;\n const splineSegmentCount = (_a = content.segmentCount) != null ? _a : ctx.defaultSegmentCount;\n if (content.points.length > 2) {\n if (content.fitting === "closed") {\n lines = ctx.getBezierSplineCurves([...content.points.slice(content.points.length - 3), ...content.points, ...content.points.slice(0, 3)]).map((c) => ({ type: "bezier curve", curve: c }));\n lines = lines.slice(3, lines.length - 2);\n } else if (content.fitting) {\n lines = ctx.getBezierSplineCurves(content.points).map((c) => ({ type: "bezier curve", curve: c }));\n } else if (content.points.length === 3) {\n lines = ctx.getQuadraticSplineCurves(content.points).map((c) => ({ type: "quadratic curve", curve: c }));\n } else {\n lines = ctx.getBezierSplineCurves(content.points, false).map((c) => ({ type: "bezier curve", curve: c }));\n }\n points = ctx.getGeometryLinesPoints(lines, splineSegmentCount);\n } else {\n points = content.points;\n lines = Array.from(ctx.iteratePolylineLines(points));\n }\n return {\n lines,\n points,\n bounding: ctx.getGeometryLinesBounding(lines),\n renderingLines: ctx.dashedPolylineToLines(points, content.dashArray),\n regions: ctx.hasFill(content) ? [\n {\n lines,\n points: content.points\n }\n ] : void 0\n };\n });\n }\n function getSplineArrowGeometries(content, contents) {\n const refs = new Set(ctx.iterateRefContents(getSplineArrowRefIds(content), contents, [content]));\n return geometriesCache.get(content, refs, () => {\n const geometry = getSplineGeometries(content, contents);\n let arrowPoints;\n let points = geometry.points;\n if (content.points.length > 1) {\n const p1 = content.points[content.points.length - 2];\n const p2 = content.points[content.points.length - 1];\n const r = ctx.getArrowPoints(p1, p2, content);\n arrowPoints = r.arrowPoints;\n const index = points.findIndex((p) => ctx.getTwoPointsDistance(p, p2) < r.distance);\n points = [...points.slice(0, index), r.endPoint];\n }\n const lines = Array.from(ctx.iteratePolylineLines(points));\n return {\n lines,\n points,\n bounding: ctx.getPointsBounding(points),\n renderingLines: ctx.dashedPolylineToLines(points, content.dashArray),\n regions: arrowPoints ? [\n {\n points: arrowPoints,\n lines: Array.from(ctx.iteratePolygonLines(arrowPoints))\n }\n ] : void 0\n };\n });\n }\n const React = ctx.React;\n const splineModel = {\n type: "spline",\n ...ctx.strokeModel,\n ...ctx.fillModel,\n ...ctx.segmentCountModel,\n move(content, offset) {\n for (const point of content.points) {\n ctx.movePoint(point, offset);\n }\n },\n rotate(content, center, angle) {\n for (const point of content.points) {\n ctx.rotatePoint(point, center, angle);\n }\n },\n scale(content, center, sx, sy) {\n for (const point of content.points) {\n ctx.scalePoint(point, center, sx, sy);\n }\n },\n skew(content, center, sx, sy) {\n for (const point of content.points) {\n ctx.skewPoint(point, center, sx, sy);\n }\n },\n mirror(content, line) {\n for (const point of content.points) {\n ctx.mirrorPoint(point, line);\n }\n },\n break(content, intersectionPoints, contents) {\n const lines = getSplineGeometries(content, contents).lines;\n return ctx.breakGeometryLinesToPathCommands(lines, intersectionPoints);\n },\n explode(content, contents) {\n const lines = getSplineGeometries(content, contents).lines;\n return [{ type: "path", commands: ctx.geometryLineToPathCommands(lines) }];\n },\n render(content, renderCtx) {\n const { options, target } = ctx.getStrokeFillRenderOptionsFromRenderContext(content, renderCtx);\n const { points } = getSplineGeometries(content, renderCtx.contents);\n return target.renderPolyline(points, options);\n },\n renderIfSelected(content, { color, target, strokeWidth }) {\n return target.renderPolyline(content.points, { strokeColor: color, dashArray: [4], strokeWidth });\n },\n getOperatorRenderPosition(content) {\n return content.points[0];\n },\n getEditPoints(content) {\n return ctx.getEditPointsFromCache(content, () => ({ editPoints: ctx.getPolylineEditPoints(content, isSplineContent, false, true) }));\n },\n getSnapPoints(content) {\n return ctx.getSnapPointsFromCache(content, () => content.points.map((p) => ({ ...p, type: "endpoint" })));\n },\n getGeometries: getSplineGeometries,\n propertyPanel(content, update, contents, { acquirePoint }) {\n return {\n points: /* @__PURE__ */ React.createElement(\n ctx.ArrayEditor,\n {\n inline: true,\n ...ctx.getArrayEditorProps((v) => v.points, { x: 0, y: 0 }, (v) => update((c) => {\n if (isSplineContent(c)) {\n v(c);\n }\n })),\n items: content.points.map((f, i) => /* @__PURE__ */ React.createElement(\n ctx.ObjectEditor,\n {\n inline: true,\n properties: {\n from: /* @__PURE__ */ React.createElement(ctx.Button, { onClick: () => acquirePoint((p) => update((c) => {\n if (isSplineContent(c)) {\n c.points[i].x = p.x;\n c.points[i].y = p.y;\n }\n })) }, "canvas"),\n x: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: f.x, setValue: (v) => update((c) => {\n if (isSplineContent(c)) {\n c.points[i].x = v;\n }\n }) }),\n y: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: f.y, setValue: (v) => update((c) => {\n if (isSplineContent(c)) {\n c.points[i].y = v;\n }\n }) })\n }\n }\n ))\n }\n ),\n fitting: /* @__PURE__ */ React.createElement(ctx.EnumEditor, { enums: ["true", "false", "closed"], value: content.fitting === "closed" ? "closed" : content.fitting ? "true" : "false", setValue: (v) => update((c) => {\n if (isSplineContent(c)) {\n c.fitting = v === "closed" ? "closed" : v === "true" ? true : void 0;\n }\n }) }),\n ...ctx.getStrokeContentPropertyPanel(content, update, contents),\n ...ctx.getFillContentPropertyPanel(content, update, contents),\n ...ctx.getSegmentCountContentPropertyPanel(content, update)\n };\n },\n isValid: (c, p) => ctx.validate(c, SplineContent, p),\n getRefIds: getSplineRefIds,\n updateRefId: ctx.updateStrokeAndFillRefIds,\n deleteRefId: ctx.deleteStrokeAndFillRefIds,\n reverse: (content) => ({\n ...content,\n points: content.points.slice().reverse()\n })\n };\n return [\n splineModel,\n {\n type: "spline arrow",\n ...ctx.strokeModel,\n ...ctx.arrowModel,\n ...ctx.segmentCountModel,\n move: splineModel.move,\n rotate: splineModel.rotate,\n scale: splineModel.scale,\n mirror: splineModel.mirror,\n render(content, renderCtx) {\n const { options, target, fillOptions } = ctx.getStrokeRenderOptionsFromRenderContext(content, renderCtx);\n const { regions, renderingLines } = getSplineArrowGeometries(content, renderCtx.contents);\n const children = [];\n for (const line of renderingLines) {\n children.push(target.renderPolyline(line, options));\n }\n if (regions) {\n for (let i = 0; i < 2 && i < regions.length; i++) {\n children.push(target.renderPolyline(regions[i].points, fillOptions));\n }\n }\n return target.renderGroup(children);\n },\n renderIfSelected: splineModel.renderIfSelected,\n getOperatorRenderPosition: splineModel.getOperatorRenderPosition,\n getEditPoints(content) {\n return ctx.getEditPointsFromCache(content, () => ({ editPoints: ctx.getPolylineEditPoints(content, isSplineArrowContent, false, true) }));\n },\n getSnapPoints: splineModel.getSnapPoints,\n getGeometries: getSplineArrowGeometries,\n propertyPanel(content, update, contents, { acquirePoint }) {\n return {\n points: /* @__PURE__ */ React.createElement(\n ctx.ArrayEditor,\n {\n inline: true,\n ...ctx.getArrayEditorProps((v) => v.points, { x: 0, y: 0 }, (v) => update((c) => {\n if (isSplineArrowContent(c)) {\n v(c);\n }\n })),\n items: content.points.map((f, i) => /* @__PURE__ */ React.createElement(\n ctx.ObjectEditor,\n {\n inline: true,\n properties: {\n from: /* @__PURE__ */ React.createElement(ctx.Button, { onClick: () => acquirePoint((p) => update((c) => {\n if (isSplineArrowContent(c)) {\n c.points[i].x = p.x;\n c.points[i].y = p.y;\n }\n })) }, "canvas"),\n x: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: f.x, setValue: (v) => update((c) => {\n if (isSplineArrowContent(c)) {\n c.points[i].x = v;\n }\n }) }),\n y: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: f.y, setValue: (v) => update((c) => {\n if (isSplineArrowContent(c)) {\n c.points[i].y = v;\n }\n }) })\n }\n }\n ))\n }\n ),\n fitting: /* @__PURE__ */ React.createElement(ctx.BooleanEditor, { value: content.fitting === true, setValue: (v) => update((c) => {\n if (isSplineArrowContent(c)) {\n c.fitting = v ? true : void 0;\n }\n }) }),\n ...ctx.getStrokeContentPropertyPanel(content, update, contents),\n ...ctx.getArrowContentPropertyPanel(content, update),\n ...ctx.getSegmentCountContentPropertyPanel(content, update)\n };\n },\n isValid: (c, p) => ctx.validate(c, SplineArrowContent, p),\n getRefIds: getSplineArrowRefIds,\n updateRefId: ctx.updateStrokeRefIds,\n deleteRefId: ctx.deleteStrokeRefIds,\n reverse: (content) => ({\n ...content,\n points: content.points.slice().reverse()\n })\n }\n ];\n}\nfunction isSplineContent(content) {\n return content.type === "spline";\n}\nfunction isSplineArrowContent(content) {\n return content.type === "spline arrow";\n}\nfunction getCommand(ctx) {\n const React = ctx.React;\n const icon1 = /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 100 100" }, /* @__PURE__ */ React.createElement("circle", { cx: "13", cy: "22", r: "5", strokeWidth: "0", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "currentColor", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("circle", { cx: "28", cy: "79", r: "5", strokeWidth: "0", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "currentColor", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("circle", { cx: "63", cy: "22", r: "5", strokeWidth: "0", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "currentColor", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("circle", { cx: "85", cy: "80", r: "5", strokeWidth: "0", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "currentColor", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polyline", { points: "13,22 14,24 14,26 15,29 15,31 16,33 17,34 17,36 18,38 18,40 19,41 20,43 20,44 21,46 22,47 22,49 23,50 23,51 24,52 25,53 25,54 26,55 27,56 27,56 28,57 29,58 29,58 30,59 31,59 31,59 32,60 33,60 33,60 34,60 35,60 35,60 36,60 37,60 37,59 38,59 39,58 39,58 40,57 41,57 41,56 42,55 43,55 43,54 44,53 45,52 46,51 46,49 47,48 48,47 48,46 49,46 50,45 50,44 51,44 52,43 53,43 53,42 54,42 55,42 56,41 56,41 57,41 58,41 59,41 59,41 60,42 61,42 62,42 63,43 63,43 64,44 65,44 66,45 67,46 67,47 68,47 69,48 70,49 71,51 71,52 72,53 73,54 74,56 75,57 76,59 76,60 77,62 78,64 79,65 80,67 81,69 82,71 82,73 83,75 84,78 85,80", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }));\n const icon2 = /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 100 100" }, /* @__PURE__ */ React.createElement("circle", { cx: "13", cy: "22", r: "5", strokeWidth: "0", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "currentColor", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("circle", { cx: "28", cy: "79", r: "5", strokeWidth: "0", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "currentColor", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("circle", { cx: "63", cy: "22", r: "5", strokeWidth: "0", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "currentColor", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("circle", { cx: "85", cy: "80", r: "5", strokeWidth: "0", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "currentColor", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polyline", { points: "13,22 13,23 13,24 13,25 13,26 13,27 14,28 14,29 14,30 14,31 14,31 14,32 14,33 14,34 14,35 14,36 14,37 15,38 15,39 15,40 15,41 15,42 15,43 15,43 15,44 15,45 15,46 15,47 16,48 16,49 16,49 16,50 16,51 16,52 16,53 16,54 16,54 17,55 17,56 17,57 17,58 17,58 17,59 17,60 17,61 18,61 18,62 18,63 18,63 18,64 18,65 18,65 18,66 19,67 19,67 19,68 19,69 19,69 19,70 19,70 20,71 20,71 20,72 20,72 20,73 20,73 21,74 21,74 21,75 21,75 21,75 21,76 22,76 22,77 22,77 22,77 22,78 23,78 23,78 23,78 23,79 23,79 24,79 24,79 24,79 24,79 25,80 25,80 25,80 25,80 25,80 26,80 26,80 26,80 26,80 27,80 27,80 27,79 27,79 28,79 28,79 28,79 29,79 29,78 29,78 29,78 30,77 30,77 30,77 31,76 31,76 31,76 32,75 32,75 32,74 32,74 33,73 33,73 33,72 34,72 34,71 34,71 35,70 35,69 35,69 36,68 36,68 37,67 37,66 37,66 38,65 38,64 38,64 39,63 39,62 39,62 40,61 40,60 40,59 41,59 41,58 42,57 42,56 42,56 43,55 43,54 43,53 44,53 44,52 45,51 45,50 45,50 46,49 46,48 46,47 47,47 47,46 48,45 48,44 48,44 49,43 49,42 50,41 50,41 50,40 51,39 51,39 51,38 52,37 52,37 53,36 53,35 53,35 54,34 54,33 54,33 55,32 55,31 55,31 56,30 56,30 57,29 57,29 57,28 58,28 58,27 58,27 59,26 59,26 59,25 60,25 60,25 60,24 61,24 61,24 61,23 62,23 62,23 62,22 63,22 63,22 63,22 64,22 64,22 64,21 65,21 65,21 65,21 65,21 66,21 66,21 66,21 67,21 67,21 67,22 67,22 68,22 68,22 68,22 69,22 69,23 69,23 69,23 70,23 70,24 70,24 70,24 71,25 71,25 71,25 71,26 72,26 72,27 72,27 72,27 73,28 73,28 73,29 73,29 73,30 74,31 74,31 74,32 74,32 75,33 75,33 75,34 75,35 75,35 76,36 76,37 76,37 76,38 76,39 77,39 77,40 77,41 77,42 77,42 78,43 78,44 78,45 78,46 78,46 79,47 79,48 79,49 79,50 79,50 80,51 80,52 80,53 80,54 80,55 80,56 81,57 81,57 81,58 81,59 81,60 82,61 82,62 82,63 82,64 82,65 82,66 83,67 83,68 83,69 83,69 83,70 83,71 84,72 84,73 84,74 84,75 84,76 84,77 85,78 85,79 85,80", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }));\n const icon3 = /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 100 100" }, /* @__PURE__ */ React.createElement("polyline", { points: "8,93 8,90 8,87 8,83 8,81 8,78 9,75 9,72 9,70 9,67 10,65 10,62 10,60 11,58 11,56 12,54 12,53 13,51 13,49 14,48 15,46 15,45 16,44 17,43 17,42 18,41 19,40 20,39 21,39 22,38 23,38 24,38 25,38 26,37 27,37 28,38 29,38 30,38 32,38 33,39 34,40 36,40 37,41 38,42 40,43 41,44 43,45 44,46 46,48 47,49 49,51 51,53 52,54 54,55 55,57 57,58 58,59 60,60 61,61 62,62 64,62 65,63 66,63 68,64 69,64 70,64 71,64 72,64 73,64 74,64 75,64 76,63 77,63 78,62 79,62 80,61 81,60 81,59 82,58 83,56 83,55 84,54 85,52 85,51 86,49 86,47 87,45 87,43 88,41 88,39 88,37 89,34 89,32 89,29 89,26 90,24 90,21 90,18 90,17", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polyline", { points: "90,8 98,37 82,37", strokeWidth: "0", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "currentColor", stroke: "currentColor" }));\n const splineCommand = {\n name: "create spline",\n type: [\n { name: "spline", hotkey: "SPL", icon: icon1 },\n { name: "spline fitting", icon: icon2 }\n ],\n useCommand({ onEnd, type, scale, strokeStyleId, fillStyleId }) {\n const { line, onClick, onMove, input, lastPosition, reset } = ctx.useLineClickCreate(\n type === "spline" || type === "spline fitting",\n (c) => onEnd({\n updateContents: (contents) => contents.push({ points: c, type: "spline", strokeStyleId, fillStyleId, fitting: type === "spline fitting" })\n })\n );\n const assistentContents = [];\n if (line) {\n assistentContents.push(\n { points: line, type: "spline", strokeStyleId, fillStyleId, fitting: type === "spline fitting" },\n { points: line, type: "polyline", dashArray: [4 / scale] }\n );\n }\n return {\n onStart: onClick,\n input,\n onMove,\n assistentContents,\n lastPosition,\n reset\n };\n },\n selectCount: 0\n };\n return [\n splineCommand,\n {\n name: "create spline arrow",\n icon: icon3,\n useCommand({ onEnd, type, scale, strokeStyleId }) {\n const { line, onClick, onMove, input, lastPosition, reset } = ctx.useLineClickCreate(\n type === "create spline arrow",\n (c) => onEnd({\n updateContents: (contents) => contents.push({ points: c, strokeStyleId, type: "spline arrow" })\n })\n );\n const assistentContents = [];\n if (line) {\n assistentContents.push(\n { points: line, strokeStyleId, type: "spline arrow" },\n { points: line, type: "polyline", dashArray: [4 / scale] }\n );\n }\n return {\n onStart: onClick,\n input,\n onMove,\n assistentContents,\n lastPosition,\n reset\n };\n },\n selectCount: 0\n }\n ];\n}\nexport {\n getCommand,\n getModel,\n isSplineArrowContent,\n isSplineContent\n};\n','// dev/cad-editor/plugins/star.plugin.tsx\nfunction getModel(ctx) {\n const StarContent = ctx.and(ctx.BaseContent("star"), ctx.StrokeFields, ctx.FillFields, ctx.Position, {\n outerRadius: ctx.number,\n innerRadius: ctx.number,\n count: ctx.number,\n angle: ctx.optional(ctx.number)\n });\n const getRefIds = (content) => ctx.getStrokeAndFillRefIds(content);\n const geometriesCache = new ctx.WeakmapValuesCache();\n function getStarGeometriesFromCache(content, contents) {\n const refs = new Set(ctx.iterateRefContents(getRefIds(content), contents, [content]));\n return geometriesCache.get(content, refs, () => {\n var _a;\n const angle = -((_a = content.angle) != null ? _a : 0);\n const p0 = ctx.rotatePositionByCenter({ x: content.x + content.outerRadius, y: content.y }, content, angle);\n const p1 = ctx.rotatePositionByCenter({ x: content.x + content.innerRadius, y: content.y }, content, angle + 180 / content.count);\n const points = [];\n for (let i = 0; i < content.count; i++) {\n const angle2 = 360 / content.count * i;\n points.push(\n ctx.rotatePositionByCenter(p0, content, angle2),\n ctx.rotatePositionByCenter(p1, content, angle2)\n );\n }\n const lines = Array.from(ctx.iteratePolygonLines(points));\n return {\n points,\n lines,\n bounding: ctx.getPointsBounding(points),\n regions: ctx.hasFill(content) ? [\n {\n lines,\n points\n }\n ] : void 0,\n renderingLines: ctx.dashedPolylineToLines(ctx.polygonToPolyline(points), content.dashArray)\n };\n });\n }\n const React = ctx.React;\n return {\n type: "star",\n ...ctx.strokeModel,\n ...ctx.fillModel,\n move(content, offset) {\n ctx.movePoint(content, offset);\n },\n scale(content, center, sx, sy, contents) {\n if (sx !== sy) {\n const points = ctx.produce(getStarGeometriesFromCache(content, contents).points, (draft) => {\n for (const p of draft) {\n ctx.scalePoint(p, center, sx, sy);\n }\n });\n return { ...content, points, type: "polygon" };\n }\n ctx.scalePoint(content, center, sx, sy);\n content.innerRadius *= sx;\n content.outerRadius *= sy;\n return;\n },\n skew(content, center, sx, sy, contents) {\n const points = ctx.produce(getStarGeometriesFromCache(content, contents).points, (draft) => {\n for (const p of draft) {\n ctx.skewPoint(p, center, sx, sy);\n }\n });\n return { ...content, points, type: "polygon" };\n },\n break(content, intersectionPoints, contents) {\n const { lines } = getStarGeometriesFromCache(content, contents);\n return ctx.breakPolyline(lines, intersectionPoints);\n },\n offset(content, point, distance, contents) {\n var _a;\n if (!distance) {\n distance = Math.min(...getStarGeometriesFromCache(content, contents).lines.map((line) => ctx.getPointAndGeometryLineMinimumDistance(point, line)));\n }\n distance *= ((_a = this.isPointIn) == null ? void 0 : _a.call(this, content, point, contents)) ? -1 : 1;\n const angle = Math.PI / content.count;\n const length = Math.sqrt(content.innerRadius ** 2 + content.outerRadius ** 2 - 2 * content.innerRadius * content.outerRadius * Math.cos(angle));\n distance *= length / Math.sin(angle);\n return ctx.produce(content, (d) => {\n d.outerRadius += distance / content.innerRadius;\n d.innerRadius += distance / content.outerRadius;\n });\n },\n render(content, renderCtx) {\n const { options, target } = ctx.getStrokeFillRenderOptionsFromRenderContext(content, renderCtx);\n const { points } = getStarGeometriesFromCache(content, renderCtx.contents);\n return target.renderPolygon(points, options);\n },\n getEditPoints(content, contents) {\n return ctx.getEditPointsFromCache(content, () => {\n const { points } = getStarGeometriesFromCache(content, contents);\n return {\n editPoints: [\n {\n ...content,\n cursor: "move",\n update(c, { cursor, start, scale }) {\n if (!isStarContent(c)) {\n return;\n }\n c.x += cursor.x - start.x;\n c.y += cursor.y - start.y;\n return { assistentContents: [{ type: "line", dashArray: [4 / scale], points: [start, cursor] }] };\n }\n },\n ...points.map((p, i) => ({\n x: p.x,\n y: p.y,\n cursor: "move",\n update(c, { cursor, start, scale }) {\n if (!isStarContent(c)) {\n return;\n }\n if (i % 2 === 0) {\n c.outerRadius = ctx.getTwoPointsDistance(cursor, c);\n } else {\n c.innerRadius = ctx.getTwoPointsDistance(cursor, c);\n }\n return { assistentContents: [{ type: "line", dashArray: [4 / scale], points: [start, cursor] }] };\n }\n }))\n ]\n };\n });\n },\n getGeometries: getStarGeometriesFromCache,\n propertyPanel(content, update, contents, { acquirePoint }) {\n var _a;\n return {\n from: /* @__PURE__ */ React.createElement(ctx.Button, { onClick: () => acquirePoint((p) => update((c) => {\n if (isStarContent(c)) {\n c.x = p.x;\n c.y = p.y;\n }\n })) }, "canvas"),\n x: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.x, setValue: (v) => update((c) => {\n if (isStarContent(c)) {\n c.x = v;\n }\n }) }),\n y: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.y, setValue: (v) => update((c) => {\n if (isStarContent(c)) {\n c.y = v;\n }\n }) }),\n outerRadius: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.outerRadius, setValue: (v) => update((c) => {\n if (isStarContent(c)) {\n c.outerRadius = v;\n }\n }) }),\n innerRadius: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.innerRadius, setValue: (v) => update((c) => {\n if (isStarContent(c)) {\n c.innerRadius = v;\n }\n }) }),\n count: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.count, setValue: (v) => update((c) => {\n if (isStarContent(c)) {\n c.count = v;\n }\n }) }),\n angle: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: (_a = content.angle) != null ? _a : 0, setValue: (v) => update((c) => {\n if (isStarContent(c)) {\n c.angle = v === 0 ? void 0 : v;\n }\n }) }),\n ...ctx.getStrokeContentPropertyPanel(content, update, contents),\n ...ctx.getFillContentPropertyPanel(content, update, contents)\n };\n },\n isValid: (c, p) => ctx.validate(c, StarContent, p),\n getRefIds,\n updateRefId: ctx.updateStrokeAndFillRefIds,\n deleteRefId: ctx.deleteStrokeAndFillRefIds,\n isPointIn: (content, point, contents) => ctx.pointInPolygon(point, getStarGeometriesFromCache(content, contents).points)\n };\n}\nfunction isStarContent(content) {\n return content.type === "star";\n}\nfunction getCommand(ctx) {\n const React = ctx.React;\n const icon = /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 100 100" }, /* @__PURE__ */ React.createElement("polygon", { points: "75,84 70,56 90,36 62,32 49,7 37,33 9,37 29,56 25,84 50,71", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }));\n return {\n name: "create star",\n icon,\n useCommand({ onEnd, type, strokeStyleId, fillStyleId }) {\n const { line, onClick, onMove, input, lastPosition, reset } = ctx.useLineClickCreate(\n type === "create star",\n ([p0, p1]) => onEnd({\n updateContents: (contents) => {\n const outerRadius = ctx.getTwoPointsDistance(p0, p1);\n contents.push({\n type: "star",\n x: p0.x,\n y: p0.y,\n outerRadius,\n innerRadius: outerRadius * 0.5,\n count: 5,\n angle: ctx.radianToAngle(ctx.getTwoPointsRadian(p1, p0)),\n strokeStyleId,\n fillStyleId\n });\n }\n }),\n {\n once: true\n }\n );\n const assistentContents = [];\n if (line) {\n const [p0, p1] = line;\n const outerRadius = ctx.getTwoPointsDistance(p0, p1);\n assistentContents.push({\n type: "star",\n x: p0.x,\n y: p0.y,\n outerRadius,\n innerRadius: outerRadius * 0.5,\n count: 5,\n angle: ctx.radianToAngle(ctx.getTwoPointsRadian(p1, p0)),\n strokeStyleId,\n fillStyleId\n });\n }\n return {\n onStart: onClick,\n input,\n onMove,\n assistentContents,\n lastPosition,\n reset\n };\n },\n selectCount: 0\n };\n}\nexport {\n getCommand,\n getModel,\n isStarContent\n};\n','// dev/cad-editor/plugins/stroke-style.plugin.tsx\nfunction getModel(ctx) {\n function getGeometriesFromCache(content) {\n return ctx.getGeometriesFromCache(content, /* @__PURE__ */ new Set(), () => {\n const points = [\n { x: content.x, y: content.y },\n { x: content.x + content.width, y: content.y },\n { x: content.x + content.width, y: content.y + content.height },\n { x: content.x, y: content.y + content.height }\n ];\n return {\n lines: [],\n bounding: ctx.getPointsBounding(points),\n regions: [\n {\n points,\n lines: Array.from(ctx.iteratePolygonLines(points))\n }\n ],\n renderingLines: []\n };\n });\n }\n const React = ctx.React;\n return {\n type: "stroke style",\n ...ctx.strokeModel,\n move(content, offset) {\n ctx.movePoint(content, offset);\n },\n render(content, { target, getStrokeColor, transformStrokeWidth, transformColor }) {\n var _a;\n const options = {\n strokeColor: getStrokeColor(content),\n strokeWidth: transformStrokeWidth((_a = content.strokeWidth) != null ? _a : ctx.getDefaultStrokeWidth(content)),\n dashArray: content.dashArray,\n strokeOpacity: content.strokeOpacity\n };\n return target.renderGroup([\n target.renderRect(content.x, content.y, content.width, content.height, {\n strokeColor: transformColor(content.isCurrent ? 16711680 : 0)\n }),\n target.renderPolyline([\n { x: content.x, y: content.y + content.height / 2 },\n { x: content.x + content.width, y: content.y + content.height / 2 }\n ], options)\n ]);\n },\n getEditPoints(content) {\n return ctx.getEditPointsFromCache(content, () => {\n return {\n editPoints: [\n {\n ...content,\n cursor: "move",\n update(c, { cursor, start, scale }) {\n if (!ctx.isStrokeStyleContent(c)) {\n return;\n }\n c.x += cursor.x - start.x;\n c.y += cursor.y - start.y;\n return { assistentContents: [{ type: "line", dashArray: [4 / scale], points: [start, cursor] }] };\n }\n }\n ]\n };\n });\n },\n getGeometries: getGeometriesFromCache,\n propertyPanel(content, update, contents, { acquirePoint }) {\n return {\n isCurrent: /* @__PURE__ */ React.createElement(ctx.BooleanEditor, { value: content.isCurrent === true, setValue: (v) => update((c, draft) => {\n if (ctx.isStrokeStyleContent(c)) {\n const currentStrokeStyle = ctx.getStrokeStyles(contents).find((s) => s.content.isCurrent);\n if (currentStrokeStyle) {\n const c2 = draft[currentStrokeStyle.index];\n if (c2 && ctx.isStrokeStyleContent(c2)) {\n c2.isCurrent = void 0;\n }\n }\n c.isCurrent = v ? true : void 0;\n }\n }) }),\n from: /* @__PURE__ */ React.createElement(ctx.Button, { onClick: () => acquirePoint((p) => update((c) => {\n if (ctx.isStrokeStyleContent(c)) {\n c.x = p.x;\n c.y = p.y;\n }\n })) }, "canvas"),\n x: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.x, setValue: (v) => update((c) => {\n if (ctx.isStrokeStyleContent(c)) {\n c.x = v;\n }\n }) }),\n y: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.y, setValue: (v) => update((c) => {\n if (ctx.isStrokeStyleContent(c)) {\n c.y = v;\n }\n }) }),\n width: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.width, setValue: (v) => update((c) => {\n if (ctx.isStrokeStyleContent(c)) {\n c.width = v;\n }\n }) }),\n height: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.height, setValue: (v) => update((c) => {\n if (ctx.isStrokeStyleContent(c)) {\n c.height = v;\n }\n }) }),\n ...ctx.getStrokeContentPropertyPanel(content, update)\n };\n },\n isValid: (c, p) => ctx.validate(c, ctx.StrokeStyleContent, p)\n };\n}\nfunction getCommand(ctx) {\n const React = ctx.React;\n const icon = /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 100 100" }, /* @__PURE__ */ React.createElement("polyline", { points: "0,22 100,22", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polyline", { points: "0,45 100,45", strokeWidth: "10", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polyline", { points: "0,65 100,65", strokeWidth: "5", strokeDasharray: "10 5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polyline", { points: "0,81 100,81", strokeWidth: "5", strokeDasharray: "15", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }));\n return {\n name: "create stroke style",\n selectCount: 0,\n icon,\n useCommand({ onEnd, type, scale }) {\n const [result, setResult] = React.useState();\n const reset = () => {\n setResult(void 0);\n };\n return {\n onStart() {\n if (result) {\n onEnd({\n updateContents: (contents) => {\n if (result) {\n contents.push(result);\n }\n }\n });\n reset();\n }\n },\n onMove(p) {\n if (type) {\n setResult({\n type: "stroke style",\n x: p.x,\n y: p.y,\n width: 100 / scale,\n height: 20 / scale\n });\n }\n },\n assistentContents: result ? [result] : void 0,\n reset\n };\n }\n };\n}\nexport {\n getCommand,\n getModel\n};\n','// dev/cad-editor/plugins/table.plugin.tsx\nfunction getModel(ctx) {\n const TableCellText = ctx.and(ctx.TextFields, {\n type: "table cell text",\n text: ctx.string,\n column: ctx.number\n });\n const TableRow = {\n height: ctx.number,\n cells: ctx.optional([TableCellText])\n };\n const MergedCell = {\n row: ctx.tuple(ctx.number, ctx.number),\n column: ctx.tuple(ctx.number, ctx.number)\n };\n const TableContent = ctx.and(ctx.BaseContent("table"), ctx.Position, ctx.StrokeFields, {\n rows: [TableRow],\n widths: [ctx.number],\n mergedCells: ctx.optional([MergedCell])\n });\n const getRefIds = (content) => ctx.getStrokeRefIds(content);\n const geometriesCache = new ctx.WeakmapValuesCache();\n const textLayoutResultCache = new ctx.WeakmapMap3Cache();\n const getGeometries = (content, contents) => {\n const refs = new Set(ctx.iterateRefContents(getRefIds(content), contents, [content]));\n return geometriesCache.get(content, refs, () => {\n const lines = [];\n const width = content.widths.reduce((p, c) => p + c, 0);\n const height = content.rows.reduce((p, c) => p + c.height, 0);\n lines.push([{ x: content.x, y: content.y }, { x: content.x + width, y: content.y }]);\n lines.push([{ x: content.x, y: content.y }, { x: content.x, y: content.y + height }]);\n const rows = [];\n const columns = [];\n const xs = [];\n const ys = [];\n const children = [];\n let x = content.x;\n content.widths.forEach((w) => {\n x += w;\n xs.push(x - w / 2);\n });\n let yStart = content.y;\n content.rows.forEach((row, i) => {\n const yMiddle = yStart + row.height / 2;\n const yEnd = yStart + row.height;\n ys.push(yMiddle);\n let xStart = content.x;\n content.widths.forEach((w, j) => {\n var _a, _b, _c;\n const xMiddle = xStart + w / 2;\n const xEnd = xStart + w;\n if (!((_a = content.mergedCells) == null ? void 0 : _a.some((c) => i >= c.row[0] && i < c.row[0] + c.row[1] - 1 && j >= c.column[0] && j < c.column[0] + c.column[1]))) {\n lines.push([{ x: xStart, y: yEnd }, { x: xEnd, y: yEnd }]);\n rows.push({ x: xMiddle, y: yEnd, index: i });\n }\n if (!((_b = content.mergedCells) == null ? void 0 : _b.some((c) => i >= c.row[0] && i < c.row[0] + c.row[1] && j >= c.column[0] && j < c.column[0] + c.column[1] - 1))) {\n lines.push([{ x: xEnd, y: yStart }, { x: xEnd, y: yEnd }]);\n columns.push({ x: xEnd, y: yMiddle, index: j });\n }\n const cell = (_c = content.mergedCells) == null ? void 0 : _c.find((c) => i >= c.row[0] && i < c.row[0] + c.row[1] && j >= c.column[0] && j < c.column[0] + c.column[1]);\n if (cell) {\n if (i === cell.row[0] && j === cell.column[0]) {\n const end = {\n x: xEnd,\n y: yEnd\n };\n for (let k = 1; k < cell.column[1] && k < content.widths.length - j; k++) {\n end.x += content.widths[j + k];\n }\n for (let k = 1; k < cell.row[1] && k < content.rows.length - i; k++) {\n end.y += content.rows[i + k].height;\n }\n children.push({\n row: i,\n column: j,\n x: xStart - content.x,\n y: yStart - content.y,\n width: end.x - xStart,\n height: end.y - yStart,\n region: ctx.getPolygonFromTwoPointsFormRegion({ start: { x: xStart, y: yStart }, end })\n });\n }\n } else {\n children.push({\n row: i,\n column: j,\n x: xStart - content.x,\n y: yStart - content.y,\n width: w,\n height: row.height,\n region: ctx.getPolygonFromTwoPointsFormRegion({ start: { x: xStart, y: yStart }, end: { x: xEnd, y: yEnd } })\n });\n }\n xStart = xEnd;\n });\n yStart = yEnd;\n });\n const bounding = { start: { x: content.x, y: content.y }, end: { x: content.x + width, y: content.y + height } };\n const polygon = ctx.getPolygonFromTwoPointsFormRegion(bounding);\n return {\n lines,\n rows,\n columns,\n xs,\n ys,\n bounding,\n renderingLines: lines.map((r) => ctx.dashedPolylineToLines(r, content.dashArray)).flat(),\n regions: [{\n points: polygon,\n lines: Array.from(ctx.iteratePolygonLines(polygon))\n }],\n children\n };\n });\n };\n const React = ctx.React;\n const tableModel = {\n type: "table",\n ...ctx.strokeModel,\n move(content, offset) {\n ctx.movePoint(content, offset);\n },\n scale(content, center, sx, sy) {\n ctx.scalePoint(content, center, sx, sy);\n for (const row of content.rows) {\n row.height *= sy;\n }\n content.widths = content.widths.map((w) => w * sx);\n },\n render(content, renderCtx) {\n const geometries = getGeometries(content, renderCtx.contents);\n const { options, strokeColor } = ctx.getStrokeRenderOptionsFromRenderContext(content, renderCtx);\n const textOptions = ctx.getTextStyleRenderOptionsFromRenderContext(strokeColor, renderCtx);\n const children = geometries.renderingLines.map((line) => renderCtx.target.renderPolyline(line, options));\n content.rows.forEach((row, i) => {\n var _a;\n (_a = row.cells) == null ? void 0 : _a.forEach((cell) => {\n var _a2, _b;\n const child = geometries.children.find((f) => f.row === i && f.column === cell.column);\n if (!child) return;\n const { width, height } = child;\n const textStyleContent = ctx.getTextStyleContent(cell, renderCtx.contents);\n const textLayout = textLayoutResultCache.get(cell, textStyleContent, width, height, () => {\n var _a3, _b2, _c;\n const state = cell.text.split("");\n const getTextWidth = (text) => {\n var _a4, _b3;\n return (_b3 = (_a4 = ctx.getTextSizeFromCache(ctx.getTextStyleFont(textStyleContent), text)) == null ? void 0 : _a4.width) != null ? _b3 : 0;\n };\n return ctx.flowLayout({\n state,\n width,\n height,\n lineHeight: (_a3 = textStyleContent.lineHeight) != null ? _a3 : textStyleContent.fontSize * 1.2,\n getWidth: getTextWidth,\n align: (_b2 = textStyleContent.align) != null ? _b2 : "center",\n verticalAlign: (_c = textStyleContent.verticalAlign) != null ? _c : "middle",\n endContent: "",\n isNewLineContent: (c) => c === "\\n",\n isPartOfComposition: (c) => ctx.isWordCharactor(c),\n getComposition: (index) => ctx.getTextComposition(index, state, getTextWidth, (c) => c)\n });\n });\n const font = ctx.getTextStyleFont(textStyleContent);\n for (const { x, y, content: text } of textLayout.layoutResult) {\n const textWidth = (_b = (_a2 = ctx.getTextSizeFromCache(font, text)) == null ? void 0 : _a2.width) != null ? _b : 0;\n children.push(renderCtx.target.renderText(content.x + child.x + x + textWidth / 2, content.y + child.y + y + textStyleContent.fontSize, text, textStyleContent.color, textStyleContent.fontSize, textStyleContent.fontFamily, { textAlign: "center", cacheKey: cell, ...textOptions }));\n }\n });\n });\n return renderCtx.target.renderGroup(children);\n },\n getEditPoints(content, contents) {\n return ctx.getEditPointsFromCache(content, () => {\n const { rows, columns, xs, ys } = getGeometries(content, contents);\n return {\n editPoints: [\n {\n x: content.x,\n y: content.y,\n cursor: "move",\n update(c, { cursor, start, scale }) {\n if (!isTableContent(c)) {\n return;\n }\n c.x += cursor.x - start.x;\n c.y += cursor.y - start.y;\n return { assistentContents: [{ type: "line", dashArray: [4 / scale], points: [start, cursor] }] };\n }\n },\n ...rows.map((p) => ({\n x: p.x,\n y: p.y,\n cursor: "row-resize",\n update(c, { cursor, start, scale }) {\n if (!isTableContent(c)) {\n return;\n }\n c.rows[p.index].height += cursor.y - start.y;\n return { assistentContents: [{ type: "line", dashArray: [4 / scale], points: [start, cursor] }] };\n }\n })),\n ...columns.map((p) => ({\n x: p.x,\n y: p.y,\n cursor: "col-resize",\n update(c, { cursor, start, scale }) {\n if (!isTableContent(c)) {\n return;\n }\n c.widths[p.index] += cursor.x - start.x;\n return { assistentContents: [{ type: "line", dashArray: [4 / scale], points: [start, cursor] }] };\n }\n })),\n ...xs.map((p, i) => ({\n x: p,\n y: content.y,\n cursor: "not-allowed",\n execute(c) {\n if (isTableContent(c)) {\n deleteTableColumn(c, i);\n }\n }\n })),\n ...ys.map((p, i) => ({\n x: content.x,\n y: p,\n cursor: "not-allowed",\n execute(c) {\n if (isTableContent(c)) {\n deleteTableRow(c, i);\n }\n }\n })),\n ...xs.map((p, i) => ({\n x: p + content.widths[i] / 2,\n y: content.y,\n cursor: "cell",\n execute(c) {\n if (isTableContent(c)) {\n insertTableColumn(c, i);\n }\n }\n })),\n ...ys.map((p, i) => ({\n x: content.x,\n y: p + content.rows[i].height / 2,\n cursor: "cell",\n execute(c) {\n if (isTableContent(c)) {\n insertTableRow(c, i);\n }\n }\n }))\n ]\n };\n });\n },\n getGeometries,\n propertyPanel(content, update, contents, options) {\n var _a, _b, _c, _d, _e;\n const properties = {};\n if (options.activeChild) {\n const [row, column] = options.activeChild;\n properties.row = /* @__PURE__ */ React.createElement(ctx.NumberEditor, { readOnly: true, value: row });\n properties.column = /* @__PURE__ */ React.createElement(ctx.NumberEditor, { readOnly: true, value: column });\n const mergedCell = (_b = (_a = content.mergedCells) == null ? void 0 : _a.find) == null ? void 0 : _b.call(_a, (c) => c.row[0] === row && c.column[0] === column);\n properties.rowSpan = /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: (_c = mergedCell == null ? void 0 : mergedCell.row[1]) != null ? _c : 1, setValue: (v) => update((c) => {\n if (isTableContent(c)) {\n setTableRowSpan(c, row, column, v);\n }\n }) });\n properties.columnSpan = /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: (_d = mergedCell == null ? void 0 : mergedCell.column[1]) != null ? _d : 1, setValue: (v) => update((c) => {\n if (isTableContent(c)) {\n setTableColumnSpan(c, row, column, v);\n }\n }) });\n const cell = (_e = content.rows[row].cells) == null ? void 0 : _e.find((c) => c.column === column);\n if (cell) {\n Object.assign(properties, ctx.getTextContentPropertyPanel(cell, (f) => update((c) => {\n if (isTableContent(c)) {\n setTableCell(c, row, column, f);\n }\n }), contents));\n }\n }\n return {\n ...properties,\n x: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.x, setValue: (v) => update((c) => {\n if (isTableContent(c)) {\n c.x = v;\n }\n }) }),\n y: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.y, setValue: (v) => update((c) => {\n if (isTableContent(c)) {\n c.y = v;\n }\n }) }),\n ...ctx.getStrokeContentPropertyPanel(content, update, contents)\n };\n },\n editPanel(content, scale, update, contents, cancel, transformPosition, activeChild) {\n var _a, _b, _c;\n const p = transformPosition(content);\n if (!activeChild) return /* @__PURE__ */ React.createElement(React.Fragment, null);\n const [row, column] = activeChild;\n const cell = (_a = content.rows[row].cells) == null ? void 0 : _a.find((c) => c.column === column);\n if (!cell) return /* @__PURE__ */ React.createElement(React.Fragment, null);\n const { children } = getGeometries(content, contents);\n const child = children.find((f) => f.row === row && f.column === column);\n if (!child) return /* @__PURE__ */ React.createElement(React.Fragment, null);\n const textStyleContent = ctx.getTextStyleContent(cell, contents);\n const fontSize = textStyleContent.fontSize * scale;\n return /* @__PURE__ */ React.createElement(\n ctx.SimpleTextEditor,\n {\n fontSize,\n width: child.width * scale,\n height: child.height * scale,\n color: textStyleContent.color,\n fontFamily: textStyleContent.fontFamily,\n align: (_b = textStyleContent.align) != null ? _b : "center",\n verticalAlign: (_c = textStyleContent.verticalAlign) != null ? _c : "middle",\n lineHeight: textStyleContent.lineHeight ? textStyleContent.lineHeight * scale : void 0,\n onCancel: cancel,\n x: p.x + child.x * scale,\n y: p.y + child.y * scale,\n borderWidth: 0,\n value: cell.text,\n setValue: (v) => update((c) => {\n if (isTableContent(c)) {\n setTableCell(c, row, column, (t) => t.text = v);\n }\n })\n }\n );\n },\n isValid: (c, p) => ctx.validate(c, TableContent, p),\n getRefIds,\n getChildByPoint(content, point, contents, { textStyleId }) {\n var _a;\n const { children } = getGeometries(content, contents);\n const child = children.find((c) => ctx.pointInPolygon(point, c.region));\n if (child) {\n if (!((_a = content.rows[child.row].cells) == null ? void 0 : _a.some((c) => c.column === child.column))) {\n const [, patches, reversePatches] = ctx.produceWithPatches(content, (draft) => {\n const row = draft.rows[child.row];\n if (!row.cells) {\n row.cells = [];\n }\n row.cells.push({\n type: "table cell text",\n textStyleId,\n text: "",\n color: 0,\n fontSize: 16,\n fontFamily: "monospace",\n column: child.column\n });\n });\n return {\n child: [child.row, child.column],\n patches: [patches, reversePatches]\n };\n }\n return {\n child: [child.row, child.column]\n };\n }\n return;\n }\n };\n return [\n tableModel,\n {\n type: "table cell text",\n ...ctx.textModel,\n isValid: (c, p) => ctx.validate(c, TableCellText, p)\n }\n ];\n}\nfunction isTableContent(content) {\n return content.type === "table";\n}\nfunction getCommand(ctx) {\n const React = ctx.React;\n const icon = /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 100 100" }, /* @__PURE__ */ React.createElement("polyline", { points: "7,10 91,10", strokeWidth: "4", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polyline", { points: "7,10 7,87", strokeWidth: "4", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polyline", { points: "35,10 35,87", strokeWidth: "4", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polyline", { points: "63,10 63,87", strokeWidth: "4", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polyline", { points: "91,10 91,87", strokeWidth: "4", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polyline", { points: "7,34 91,34", strokeWidth: "4", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polyline", { points: "7,60 91,60", strokeWidth: "4", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polyline", { points: "7,87 91,87", strokeWidth: "4", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }));\n return {\n name: "create table",\n useCommand({ onEnd, strokeStyleId }) {\n const assistentContents = [];\n const [position, setPosition] = React.useState();\n const newContent = {\n type: "table",\n x: 0,\n y: 0,\n widths: [100, 100, 100],\n rows: [\n { height: 20 },\n { height: 20 },\n { height: 20 },\n { height: 20 }\n ],\n strokeStyleId\n };\n if (position) {\n assistentContents.push({\n ...newContent,\n x: position.x,\n y: position.y\n });\n }\n return {\n onStart(p) {\n onEnd({\n updateContents: (contents) => {\n contents.push({\n ...newContent,\n x: p.x,\n y: p.y\n });\n }\n });\n },\n onMove(p) {\n setPosition(p);\n },\n assistentContents,\n reset() {\n setPosition(void 0);\n }\n };\n },\n selectCount: 0,\n icon\n };\n}\nfunction deleteTableColumn(c, i) {\n c.widths.splice(i, 1);\n if (c.mergedCells) {\n const indexes = [];\n c.mergedCells.forEach((cell, k) => {\n if (i < cell.column[0]) {\n cell.column[0]--;\n } else if (i === cell.column[0]) {\n indexes.unshift(k);\n } else if (i < cell.column[0] + cell.column[1]) {\n cell.column[1]--;\n }\n });\n indexes.forEach((d) => {\n var _a;\n return (_a = c.mergedCells) == null ? void 0 : _a.splice(d, 1);\n });\n }\n}\nfunction deleteTableRow(c, i) {\n c.rows.splice(i, 1);\n if (c.mergedCells) {\n const indexes = [];\n c.mergedCells.forEach((cell, k) => {\n if (i < cell.row[0]) {\n cell.row[0]--;\n } else if (i === cell.row[0]) {\n indexes.unshift(k);\n } else if (i < cell.row[0] + cell.row[1]) {\n cell.row[1]--;\n }\n });\n indexes.forEach((d) => {\n var _a;\n return (_a = c.mergedCells) == null ? void 0 : _a.splice(d, 1);\n });\n }\n}\nfunction setTableRowSpan(c, row, column, v) {\n if (!c.mergedCells) c.mergedCells = [];\n const index = c.mergedCells.findIndex((m) => m.row[0] === row && m.column[0] === column);\n if (index < 0) {\n c.mergedCells.push({ row: [row, v], column: [column, 1] });\n } else if (v <= 1 && c.mergedCells[index].column[1] <= 1) {\n c.mergedCells.splice(index, 1);\n if (c.mergedCells.length === 0) c.mergedCells = void 0;\n } else {\n c.mergedCells[index].row[1] = v;\n }\n}\nfunction setTableColumnSpan(c, row, column, v) {\n if (!c.mergedCells) c.mergedCells = [];\n const index = c.mergedCells.findIndex((m) => m.row[0] === row && m.column[0] === column);\n if (index < 0) {\n c.mergedCells.push({ row: [row, 1], column: [column, v] });\n } else if (v <= 1 && c.mergedCells[index].row[1] <= 1) {\n c.mergedCells.splice(index, 1);\n if (c.mergedCells.length === 0) c.mergedCells = void 0;\n } else {\n c.mergedCells[index].column[1] = v;\n }\n}\nfunction insertTableColumn(c, i) {\n var _a;\n c.widths.splice(i, 0, c.widths[i]);\n (_a = c.mergedCells) == null ? void 0 : _a.forEach((cell) => {\n if (i < cell.column[0]) {\n cell.column[0]++;\n } else if (i < cell.column[0] + cell.column[1] - 1) {\n cell.column[1]++;\n }\n });\n}\nfunction insertTableRow(c, i) {\n var _a;\n c.rows.splice(i, 0, c.rows[i]);\n (_a = c.mergedCells) == null ? void 0 : _a.forEach((cell) => {\n if (i < cell.row[0]) {\n cell.row[0]++;\n } else if (i < cell.row[0] + cell.row[1] - 1) {\n cell.row[1]++;\n }\n });\n}\nfunction setTableCell(c, row, column, update) {\n var _a;\n const t = (_a = c.rows[row].cells) == null ? void 0 : _a.find((c2) => c2.column === column);\n if (t) {\n update(t);\n }\n}\nexport {\n getCommand,\n getModel,\n isTableContent\n};\n','// dev/cad-editor/plugins/text-style.plugin.tsx\nfunction getModel(ctx) {\n const geometriesCache = new ctx.WeakmapCache();\n function getGeometriesFromCache(content) {\n return geometriesCache.get(content, () => {\n var _a, _b;\n const text = `${content.fontFamily} ${content.fontSize} ${ctx.getColorString(content.color)}`;\n const width = (_b = (_a = ctx.getTextSizeFromCache(ctx.getTextStyleFont(content), text)) == null ? void 0 : _a.width) != null ? _b : 0;\n const height = content.fontSize * 1.2;\n const points = ctx.getPolygonFromTwoPointsFormRegion({ start: content, end: { x: content.x + width, y: content.y + height } });\n return {\n lines: [],\n bounding: ctx.getPointsBounding(points),\n text,\n width,\n height,\n regions: [\n {\n points,\n lines: Array.from(ctx.iteratePolygonLines(points))\n }\n ],\n renderingLines: []\n };\n });\n }\n const React = ctx.React;\n return {\n type: "text style",\n ...ctx.textModel,\n move(content, offset) {\n ctx.movePoint(content, offset);\n },\n render(content, { target, transformColor }) {\n const { width, height, text } = getGeometriesFromCache(content);\n return target.renderGroup([\n target.renderRect(content.x, content.y, width, height, {\n strokeColor: transformColor(content.isCurrent ? 16711680 : 0)\n }),\n target.renderText(content.x, content.y, text, content.color, content.fontSize, content.fontFamily, { textBaseline: "top" })\n ]);\n },\n getEditPoints(content) {\n return ctx.getEditPointsFromCache(content, () => {\n return {\n editPoints: [\n {\n ...content,\n cursor: "move",\n update(c, { cursor, start, scale }) {\n if (!ctx.isTextStyleContent(c)) {\n return;\n }\n c.x += cursor.x - start.x;\n c.y += cursor.y - start.y;\n return { assistentContents: [{ type: "line", dashArray: [4 / scale], points: [start, cursor] }] };\n }\n }\n ]\n };\n });\n },\n getGeometries: getGeometriesFromCache,\n propertyPanel(content, update, contents, { acquirePoint }) {\n return {\n isCurrent: /* @__PURE__ */ React.createElement(ctx.BooleanEditor, { value: content.isCurrent === true, setValue: (v) => update((c, draft) => {\n if (ctx.isTextStyleContent(c)) {\n const currentTextStyle = ctx.getTextStyles(contents).find((s) => s.content.isCurrent);\n if (currentTextStyle) {\n const c2 = draft[currentTextStyle.index];\n if (c2 && ctx.isTextStyleContent(c2)) {\n c2.isCurrent = void 0;\n }\n }\n c.isCurrent = v ? true : void 0;\n }\n }) }),\n from: /* @__PURE__ */ React.createElement(ctx.Button, { onClick: () => acquirePoint((p) => update((c) => {\n if (ctx.isTextStyleContent(c)) {\n c.x = p.x;\n c.y = p.y;\n }\n })) }, "canvas"),\n x: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.x, setValue: (v) => update((c) => {\n if (ctx.isTextStyleContent(c)) {\n c.x = v;\n }\n }) }),\n y: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.y, setValue: (v) => update((c) => {\n if (ctx.isTextStyleContent(c)) {\n c.y = v;\n }\n }) }),\n ...ctx.getTextContentPropertyPanel(content, update)\n };\n },\n isValid: (c, p) => ctx.validate(c, ctx.TextStyleContent, p)\n };\n}\nfunction getCommand(ctx) {\n const React = ctx.React;\n const icon = /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 100 100" }, /* @__PURE__ */ React.createElement("polyline", { points: "6,7 40,7", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polyline", { points: "23,7 23,43", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polyline", { points: "61,7 82,7", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polyline", { points: "72,7 72,26", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polyline", { points: "51,49 90,49", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polyline", { points: "71,47 71,94", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polyline", { points: "11,71 32,71", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polyline", { points: "21,71 21,89", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }));\n return {\n name: "create text style",\n selectCount: 0,\n icon,\n useCommand({ onEnd, type }) {\n const [result, setResult] = React.useState();\n const reset = () => {\n setResult(void 0);\n };\n return {\n onStart() {\n if (result) {\n onEnd({\n updateContents: (contents) => {\n if (result) {\n contents.push(result);\n }\n }\n });\n reset();\n }\n },\n onMove(p) {\n if (type) {\n setResult({\n type: "text style",\n x: p.x,\n y: p.y,\n fontFamily: "monospace",\n fontSize: 20,\n color: 0\n });\n }\n },\n assistentContents: result ? [result] : void 0,\n reset\n };\n }\n };\n}\nexport {\n getCommand,\n getModel\n};\n','// dev/cad-editor/plugins/text.plugin.tsx\nfunction getModel(ctx) {\n const TextContent = ctx.and(ctx.BaseContent("text"), ctx.Position, ctx.TextFields, {\n text: ctx.string,\n width: ctx.optional(ctx.number),\n textVariableName: ctx.optional(ctx.string),\n angle: ctx.optional(ctx.number),\n scale: ctx.optional(ctx.or(ctx.number, ctx.Position))\n });\n const getRefIds = (content) => ctx.toRefId(content.textStyleId);\n const textLayoutResultCache = new ctx.WeakmapCache2();\n function getTextLayoutResult(content, c, variableContext) {\n return textLayoutResultCache.get(content, c, () => {\n var _a;\n const state = getText(content, variableContext).split("");\n const getTextWidth = (text) => {\n var _a2, _b;\n return (_b = (_a2 = ctx.getTextSizeFromCache(ctx.getTextStyleFont(c), text)) == null ? void 0 : _a2.width) != null ? _b : 0;\n };\n return ctx.flowLayout({\n state,\n width: content.width,\n lineHeight: (_a = c.lineHeight) != null ? _a : c.fontSize * 1.2,\n getWidth: getTextWidth,\n align: c.align,\n endContent: "",\n isNewLineContent: (c2) => c2 === "\\n",\n isPartOfComposition: (c2) => ctx.isWordCharactor(c2),\n getComposition: (index) => ctx.getTextComposition(index, state, getTextWidth, (c2) => c2)\n });\n });\n }\n function hasWidth(content) {\n return content.width !== void 0;\n }\n function getText(content, variableContext) {\n if (content.textVariableName && variableContext) {\n const text = variableContext[content.textVariableName];\n if (typeof text === "string") {\n return text;\n }\n }\n return content.text;\n }\n function getTextGeometries(content, contents) {\n const refs = new Set(ctx.iterateRefContents(getRefIds(content), contents, [content]));\n return ctx.getGeometriesFromCache(content, refs, () => {\n let points;\n if (hasWidth(content)) {\n const textStyleContent = ctx.getTextStyleContent(content, contents);\n const { newContentHeight } = getTextLayoutResult(content, textStyleContent);\n points = [\n { x: content.x, y: content.y + newContentHeight },\n { x: content.x + content.width, y: content.y + newContentHeight },\n { x: content.x + content.width, y: content.y },\n { x: content.x, y: content.y }\n ];\n } else {\n const size = ctx.getTextSize(ctx.getTextStyleFont(content), content.text);\n if (!size) {\n throw "not supported";\n }\n points = [\n { x: content.x, y: content.y - size.height },\n { x: content.x + size.width, y: content.y - size.height },\n { x: content.x + size.width, y: content.y },\n { x: content.x, y: content.y }\n ];\n }\n const scale = ctx.getScaleOptionsScale(content);\n if (scale) {\n for (const p of points) {\n ctx.scalePoint(p, content, scale.x, scale.y);\n }\n }\n if (content.angle) {\n for (const p of points) {\n ctx.rotatePoint(p, content, content.angle);\n }\n }\n const lines = Array.from(ctx.iteratePolygonLines(points));\n return {\n lines: [],\n bounding: ctx.getPointsBounding(points),\n regions: [\n {\n lines,\n points\n }\n ],\n renderingLines: []\n };\n });\n }\n const React = ctx.React;\n return {\n type: "text",\n ...ctx.textModel,\n move(content, offset) {\n ctx.movePoint(content, offset);\n },\n rotate(content, center, angle) {\n var _a;\n ctx.rotatePoint(content, center, angle);\n content.angle = ((_a = content.angle) != null ? _a : 0) + angle;\n },\n scale(content, center, sx, sy) {\n var _a, _b;\n ctx.scalePoint(content, center, sx, sy);\n const scale = ctx.getScaleOptionsScale(content);\n content.scale = {\n x: ((_a = scale == null ? void 0 : scale.x) != null ? _a : 1) * sx,\n y: ((_b = scale == null ? void 0 : scale.y) != null ? _b : 1) * sy\n };\n },\n mirror(content, line, angle) {\n var _a, _b, _c;\n ctx.mirrorPoint(content, line);\n content.angle = 2 * angle - ((_a = content.angle) != null ? _a : 0);\n const scale = ctx.getScaleOptionsScale(content);\n content.scale = {\n x: (_b = scale == null ? void 0 : scale.x) != null ? _b : 1,\n y: -((_c = scale == null ? void 0 : scale.y) != null ? _c : 1)\n };\n },\n getEditPoints(content) {\n return ctx.getEditPointsFromCache(content, () => {\n return {\n editPoints: [\n {\n x: content.x,\n y: content.y,\n cursor: "move",\n update(c, { cursor, start, scale }) {\n if (!isTextContent(c)) {\n return;\n }\n c.x += cursor.x - start.x;\n c.y += cursor.y - start.y;\n return { assistentContents: [{ type: "line", dashArray: [4 / scale], points: [content, cursor] }] };\n }\n },\n {\n x: content.x,\n y: content.y + content.fontSize * (content.width ? 1 : -1),\n cursor: "move",\n update(c, { cursor, scale }) {\n if (!isTextContent(c)) {\n return;\n }\n c.fontSize = Math.abs(cursor.y - content.y);\n return { assistentContents: [{ type: "line", dashArray: [4 / scale], points: [content, cursor] }] };\n }\n },\n ...content.width ? [{\n x: content.x + content.width,\n y: content.y,\n cursor: "move",\n update(c, { cursor, scale }) {\n if (!isTextContent(c)) {\n return;\n }\n c.width = Math.abs(cursor.x - content.x);\n return { assistentContents: [{ type: "line", dashArray: [4 / scale], points: [content, cursor] }] };\n }\n }] : []\n ]\n };\n });\n },\n render(content, renderCtx) {\n var _a, _b;\n const { contents, transformColor, variableContext, isAssistence, target } = renderCtx;\n const textStyleContent = ctx.getTextStyleContent(content, contents);\n const color = transformColor(textStyleContent.color);\n const text = getText(content, variableContext);\n let cacheKey;\n if (isAssistence) {\n cacheKey = ctx.assistentTextCache.get(text, textStyleContent.fontSize, textStyleContent.color);\n }\n if (!cacheKey) {\n cacheKey = content;\n }\n const textOptions = ctx.getTextStyleRenderOptionsFromRenderContext(color, renderCtx);\n const children = [];\n if (hasWidth(content)) {\n const { layoutResult } = getTextLayoutResult(content, textStyleContent, variableContext);\n for (const { x, y, content: text2 } of layoutResult) {\n const textWidth = (_b = (_a = ctx.getTextSizeFromCache(ctx.getTextStyleFont(textStyleContent), text2)) == null ? void 0 : _a.width) != null ? _b : 0;\n children.push(target.renderText(content.x + x + textWidth / 2, content.y + y + textStyleContent.fontSize, text2, textStyleContent.color, textStyleContent.fontSize, textStyleContent.fontFamily, { textAlign: "center", cacheKey, ...textOptions }));\n }\n } else {\n children.push(target.renderText(content.x, content.y, text, color, textStyleContent.fontSize, textStyleContent.fontFamily, { cacheKey, ...textOptions }));\n }\n return target.renderGroup(children, { base: content, angle: content.angle, scale: content.scale });\n },\n getGeometries: getTextGeometries,\n propertyPanel(content, update, contents, { acquirePoint }) {\n var _a, _b, _c;\n const scale = ctx.getScaleOptionsScale(content);\n return {\n from: /* @__PURE__ */ React.createElement(ctx.Button, { onClick: () => acquirePoint((p) => update((c) => {\n if (isTextContent(c)) {\n c.x = p.x;\n c.y = p.y;\n }\n })) }, "canvas"),\n x: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.x, setValue: (v) => update((c) => {\n if (isTextContent(c)) {\n c.x = v;\n }\n }) }),\n y: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.y, setValue: (v) => update((c) => {\n if (isTextContent(c)) {\n c.y = v;\n }\n }) }),\n ...ctx.getTextContentPropertyPanel(content, update, contents),\n text: /* @__PURE__ */ React.createElement(ctx.StringEditor, { textarea: true, value: content.text, setValue: (v) => update((c) => {\n if (isTextContent(c)) {\n c.text = v;\n }\n }) }),\n width: [\n /* @__PURE__ */ React.createElement(ctx.BooleanEditor, { value: content.width !== void 0, setValue: (v) => update((c) => {\n if (isTextContent(c)) {\n c.width = v ? 600 : void 0;\n }\n }) }),\n content.width !== void 0 ? /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.width, setValue: (v) => update((c) => {\n if (isTextContent(c)) {\n c.width = v;\n }\n }) }) : void 0\n ],\n textVariableName: [\n /* @__PURE__ */ React.createElement(ctx.BooleanEditor, { value: content.textVariableName !== void 0, setValue: (v) => update((c) => {\n if (isTextContent(c)) {\n c.textVariableName = v ? "" : void 0;\n }\n }) }),\n content.textVariableName !== void 0 ? /* @__PURE__ */ React.createElement(ctx.StringEditor, { value: content.textVariableName, setValue: (v) => update((c) => {\n if (isTextContent(c)) {\n c.textVariableName = v;\n }\n }) }) : void 0\n ],\n angle: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: (_a = content.angle) != null ? _a : 0, setValue: (v) => update((c) => {\n if (isTextContent(c)) {\n c.angle = v;\n }\n }) }),\n sx: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: (_b = scale == null ? void 0 : scale.x) != null ? _b : 1, setValue: (v) => update((c) => {\n var _a2;\n if (isTextContent(c)) {\n c.scale = { x: v, y: (_a2 = scale == null ? void 0 : scale.y) != null ? _a2 : v };\n }\n }) }),\n sy: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: (_c = scale == null ? void 0 : scale.y) != null ? _c : 1, setValue: (v) => update((c) => {\n var _a2;\n if (isTextContent(c)) {\n c.scale = { x: (_a2 = scale == null ? void 0 : scale.x) != null ? _a2 : v, y: v };\n }\n }) })\n };\n },\n editPanel(content, scale, update, contents, cancel, transformPosition) {\n const p = transformPosition(content);\n const textStyleContent = ctx.getTextStyleContent(content, contents);\n const fontSize = textStyleContent.fontSize * scale;\n if (content.width) {\n return /* @__PURE__ */ React.createElement(\n ctx.SimpleTextEditor,\n {\n fontSize,\n width: content.width * scale,\n color: textStyleContent.color,\n fontFamily: textStyleContent.fontFamily,\n align: textStyleContent.align,\n lineHeight: textStyleContent.lineHeight ? textStyleContent.lineHeight * scale : void 0,\n onCancel: cancel,\n x: p.x,\n y: p.y,\n value: content.text,\n setValue: (v) => update((c) => {\n if (isTextContent(c)) {\n c.text = v;\n }\n })\n }\n );\n }\n return /* @__PURE__ */ React.createElement(ctx.StringEditor, { style: {\n zIndex: 10,\n position: "absolute",\n left: `${p.x - 1}px`,\n top: `${p.y - fontSize - 1}px`,\n fontSize: `${fontSize}px`,\n fontFamily: content.fontFamily,\n color: ctx.getColorString(content.color),\n padding: "0px"\n }, textarea: true, autoFocus: true, onCancel: cancel, value: content.text, setValue: (v) => update((c) => {\n if (isTextContent(c)) {\n c.text = v;\n }\n }) });\n },\n isValid: (c, p) => ctx.validate(c, TextContent, p),\n getRefIds,\n updateRefId: ctx.updateTextStyleRefIds,\n deleteRefId: ctx.deleteTextStyleRefIds,\n getVariableNames: (content) => content.textVariableName ? [content.textVariableName] : []\n };\n}\nfunction isTextContent(content) {\n return content.type === "text";\n}\nfunction getCommand(ctx) {\n const React = ctx.React;\n const icon = /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 100 100" }, /* @__PURE__ */ React.createElement("polyline", { points: "16,22 83,22", strokeWidth: "10", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polyline", { points: "49,22 49,89", strokeWidth: "10", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }));\n return {\n name: "create text",\n icon,\n useCommand({ onEnd, type, scale, textStyleId, transformPosition, contents }) {\n const [start, setStart] = React.useState();\n const [cursor, setCursor] = React.useState();\n const [text, setText] = React.useState();\n const reset = () => {\n setText(void 0);\n setStart(void 0);\n setCursor(void 0);\n };\n const assistentContents = [];\n let panel;\n if (type) {\n if (text) {\n assistentContents.push(text);\n const p = transformPosition(text);\n const textStyleContent = ctx.getTextStyleContent(text, contents);\n const fontSize = textStyleContent.fontSize * scale;\n if (text.width) {\n panel = /* @__PURE__ */ React.createElement(\n ctx.SimpleTextEditor,\n {\n fontSize,\n width: text.width * scale,\n color: textStyleContent.color,\n fontFamily: textStyleContent.fontFamily,\n align: textStyleContent.align,\n lineHeight: textStyleContent.lineHeight ? textStyleContent.lineHeight * scale : void 0,\n onCancel: reset,\n x: p.x,\n y: p.y,\n value: text.text,\n setValue: (v) => setText({\n ...text,\n text: v\n })\n }\n );\n }\n } else if (cursor) {\n if (start) {\n assistentContents.push({ type: "polygon", points: ctx.getPolygonFromTwoPointsFormRegion(ctx.getTwoPointsFormRegion(start, cursor)), dashArray: [4 / scale] });\n assistentContents.push({\n type: "text",\n text: "abc",\n textStyleId,\n color: 0,\n fontSize: 16 / scale,\n fontFamily: "monospace",\n x: Math.min(start.x, cursor.x),\n y: Math.min(start.y, cursor.y),\n width: Math.abs(start.x - cursor.x)\n });\n } else {\n assistentContents.push({\n type: "text",\n text: "abc",\n textStyleId,\n color: 0,\n fontSize: 16 / scale,\n fontFamily: "monospace",\n x: cursor.x,\n y: cursor.y,\n width: 100\n });\n }\n }\n }\n return {\n onStart: (p) => {\n if (!type) return;\n if (text) {\n onEnd({ updateContents: (contents2) => contents2.push(text) });\n reset();\n return;\n }\n if (start) {\n setText({\n type: "text",\n text: "",\n textStyleId,\n color: 0,\n fontSize: 16 / scale,\n fontFamily: "monospace",\n x: Math.min(start.x, p.x),\n y: Math.min(start.y, p.y),\n width: Math.abs(start.x - p.x)\n });\n } else {\n setStart(p);\n }\n },\n onMove: (p) => {\n if (!type) return;\n setCursor(p);\n },\n assistentContents,\n reset,\n panel\n };\n },\n selectCount: 0,\n hotkey: "T"\n };\n}\nexport {\n getCommand,\n getModel,\n isTextContent\n};\n','// dev/cad-editor/plugins/time-axis.plugin.tsx\nfunction getModel(ctx) {\n const TimeAxisContent = ctx.and(ctx.BaseContent("time axis"), ctx.StrokeFields, ctx.ArrowFields, ctx.Position, {\n max: ctx.number\n });\n const getRefIds = (content) => ctx.toRefId(content.strokeStyleId);\n function getGeometriesFromCache(content, contents, time) {\n const getGeometries = () => {\n const { arrowPoints, endPoint } = ctx.getArrowPoints(content, { x: content.x + content.max / 10, y: content.y }, content);\n const points = [content, endPoint];\n const result = {\n lines: Array.from(ctx.iteratePolylineLines(points)),\n bounding: ctx.getPointsBounding(points),\n regions: [\n {\n points: arrowPoints,\n lines: Array.from(ctx.iteratePolygonLines(arrowPoints))\n }\n ],\n renderingLines: ctx.dashedPolylineToLines(points, content.dashArray)\n };\n if (time) {\n const timePoints = ctx.arcToPolyline(ctx.circleToArc({ x: content.x + time / 10, y: content.y, r: 5 }), ctx.defaultAngleDelta);\n result.regions.push({\n points: timePoints,\n lines: Array.from(ctx.iteratePolygonLines(timePoints))\n });\n }\n return result;\n };\n if (time) {\n return getGeometries();\n }\n const refs = new Set(ctx.iterateRefContents(getRefIds(content), contents, [content]));\n return ctx.getGeometriesFromCache(content, refs, getGeometries);\n }\n const React = ctx.React;\n return {\n type: "time axis",\n ...ctx.strokeModel,\n ...ctx.arrowModel,\n move(content, offset) {\n ctx.movePoint(content, offset);\n },\n render(content, renderCtx) {\n const { options, contents, time, target, fillOptions } = ctx.getStrokeRenderOptionsFromRenderContext(content, renderCtx);\n const { regions, renderingLines } = getGeometriesFromCache(content, contents, time);\n const children = [];\n for (const line of renderingLines) {\n children.push(target.renderPolyline(line, options));\n }\n if (regions) {\n for (let i = 0; i < regions.length; i++) {\n children.push(target.renderPolygon(regions[i].points, fillOptions));\n }\n }\n return target.renderGroup(children);\n },\n getEditPoints(content) {\n return ctx.getEditPointsFromCache(content, () => {\n return {\n editPoints: [\n {\n ...content,\n cursor: "move",\n update(c, { cursor, start, scale }) {\n if (!isTimeAxisContent(c)) {\n return;\n }\n c.x += cursor.x - start.x;\n c.y += cursor.y - start.y;\n return { assistentContents: [{ type: "line", dashArray: [4 / scale], points: [start, cursor] }] };\n }\n }\n ]\n };\n });\n },\n getGeometries: getGeometriesFromCache,\n propertyPanel(content, update, contents, { startTime, acquirePoint }) {\n return {\n from: /* @__PURE__ */ React.createElement(ctx.Button, { onClick: () => acquirePoint((p) => update((c) => {\n if (isTimeAxisContent(c)) {\n c.x = p.x;\n c.y = p.y;\n }\n })) }, "canvas"),\n x: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.x, setValue: (v) => update((c) => {\n if (isTimeAxisContent(c)) {\n c.x = v;\n }\n }) }),\n y: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.y, setValue: (v) => update((c) => {\n if (isTimeAxisContent(c)) {\n c.y = v;\n }\n }) }),\n max: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.max, setValue: (v) => update((c) => {\n if (isTimeAxisContent(c) && v > 0) {\n c.max = v;\n }\n }) }),\n action: /* @__PURE__ */ React.createElement(ctx.Button, { onClick: () => startTime(content.max) }, "start"),\n ...ctx.getArrowContentPropertyPanel(content, update),\n ...ctx.getStrokeContentPropertyPanel(content, update, contents)\n };\n },\n isValid: (c, p) => ctx.validate(c, TimeAxisContent, p),\n getRefIds,\n updateRefId: ctx.updateStrokeRefIds,\n deleteRefId: ctx.deleteStrokeRefIds\n };\n}\nfunction isTimeAxisContent(content) {\n return content.type === "time axis";\n}\nfunction getCommand(ctx) {\n const React = ctx.React;\n const icon = /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 100 100" }, /* @__PURE__ */ React.createElement("g", { transform: "" }, /* @__PURE__ */ React.createElement("polyline", { points: "3,52 90,53", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polyline", { points: "99,53 70,60 70,45", strokeWidth: "0", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "currentColor", stroke: "currentColor" })));\n return {\n name: "create time axis",\n selectCount: 0,\n icon,\n useCommand({ onEnd, type }) {\n const [result, setResult] = React.useState();\n const reset = () => {\n setResult(void 0);\n };\n return {\n onStart() {\n if (result) {\n onEnd({\n updateContents: (contents) => {\n if (result) {\n contents.push(result);\n }\n }\n });\n reset();\n }\n },\n onMove(p) {\n if (type) {\n setResult({\n type: "time axis",\n x: p.x,\n y: p.y,\n max: 5e3\n });\n }\n },\n assistentContents: result ? [result] : void 0,\n reset\n };\n }\n };\n}\nexport {\n getCommand,\n getModel,\n isTimeAxisContent\n};\n','// dev/cad-editor/plugins/hatch.plugin.tsx\nfunction isHatchContent(content) {\n return content.type === "hatch";\n}\n\n// dev/cad-editor/plugins/trim.plugin.tsx\nfunction getCommand(ctx) {\n const React = ctx.React;\n const icon = /* @__PURE__ */ React.createElement("svg", { viewBox: "64 64 896 896", width: "1em", height: "1em", fill: "currentColor" }, /* @__PURE__ */ React.createElement("path", { d: "M567.1 512l318.5-319.3c5-5 1.5-13.7-5.6-13.7h-90.5c-2.1 0-4.2.8-5.6 2.3l-273.3 274-90.2-90.5c12.5-22.1 19.7-47.6 19.7-74.8 0-83.9-68.1-152-152-152s-152 68.1-152 152 68.1 152 152 152c27.7 0 53.6-7.4 75.9-20.3l90 90.3-90.1 90.3A151.04 151.04 0 00288 582c-83.9 0-152 68.1-152 152s68.1 152 152 152 152-68.1 152-152c0-27.2-7.2-52.7-19.7-74.8l90.2-90.5 273.3 274c1.5 1.5 3.5 2.3 5.6 2.3H880c7.1 0 10.7-8.6 5.6-13.7L567.1 512zM288 370c-44.1 0-80-35.9-80-80s35.9-80 80-80 80 35.9 80 80-35.9 80-80 80zm0 444c-44.1 0-80-35.9-80-80s35.9-80 80-80 80 35.9 80 80-35.9 80-80 80z" }));\n return {\n name: "trim",\n useCommand({ onEnd, type, selected, backgroundColor, contents, getContentsInRange }) {\n const [candidates, setCandidates] = React.useState([]);\n const [currents, setCurrents] = React.useState([]);\n const [trackPoints, setTrackPoints] = React.useState([]);\n const { state, setState, resetHistory, undo, redo } = ctx.useUndoRedo([]);\n React.useEffect(() => {\n var _a, _b;\n if (type) {\n const allContents = [];\n for (let i = 0; i < selected.length; i++) {\n const content = selected[i].content;\n let intersectionPoints = [];\n for (let j = 0; j < selected.length; j++) {\n const c = selected[j].content;\n if (c && i !== j) {\n const p = i < j ? [c, content] : [content, c];\n intersectionPoints.push(...ctx.getIntersectionPoints(...p, contents));\n }\n }\n intersectionPoints = ctx.deduplicatePosition(intersectionPoints);\n if (intersectionPoints.length > 0) {\n const result = (_b = (_a = ctx.getContentModel(content)) == null ? void 0 : _a.break) == null ? void 0 : _b.call(_a, content, intersectionPoints, contents);\n if (result) {\n allContents.push({ content, children: result });\n }\n } else {\n allContents.push({ content, children: [content] });\n }\n }\n setCandidates(allContents);\n }\n }, [type]);\n const assistentContents = [];\n const collectAssistentContent = (child) => {\n var _a;\n if (ctx.isStrokeContent(child)) {\n assistentContents.push({\n ...child,\n strokeWidth: ((_a = child.strokeWidth) != null ? _a : ctx.getDefaultStrokeWidth(child)) + 2,\n strokeColor: backgroundColor,\n trueStrokeColor: true\n });\n } else if (isHatchContent(child)) {\n assistentContents.push({\n ...child,\n fillPattern: void 0,\n fillColor: backgroundColor,\n trueFillColor: true\n });\n }\n };\n for (const current of currents) {\n for (const child of current.children) {\n collectAssistentContent(child);\n }\n }\n if (trackPoints.length > 1) {\n assistentContents.push({ points: trackPoints, type: "polyline" });\n }\n for (const { children } of state) {\n for (const child of children) {\n collectAssistentContent(child);\n }\n }\n const reset = () => {\n setCandidates([]);\n setCurrents([]);\n resetHistory();\n setTrackPoints([]);\n };\n return {\n onStart() {\n if (currents.length > 0) {\n setState((draft) => {\n for (const current of currents) {\n const index = state.findIndex((s) => s.content === current.content);\n if (index >= 0) {\n draft[index].children.push(...current.children);\n } else {\n draft.push(current);\n }\n }\n });\n }\n setTrackPoints([]);\n },\n onMouseDown(p) {\n if (currents.length === 0) {\n setTrackPoints([p]);\n }\n },\n onMove(p) {\n var _a, _b, _c, _d;\n if (trackPoints.length > 0) {\n const newTracePoints = [...trackPoints, p];\n if (newTracePoints.length > 1) {\n const trackLines = Array.from(ctx.iteratePolylineLines(newTracePoints));\n const newCurrents = [];\n for (const candidate of candidates) {\n for (const child of candidate.children) {\n const geometries = (_b = (_a = ctx.getContentModel(child)) == null ? void 0 : _a.getGeometries) == null ? void 0 : _b.call(_a, child, contents);\n if (geometries) {\n for (const line of geometries.lines) {\n if (trackLines.some((t) => ctx.getTwoGeometryLinesIntersectionPoint(line, t).length > 0)) {\n const index = newCurrents.findIndex((s) => s.content === candidate.content);\n if (index >= 0) {\n newCurrents[index].children.push(child);\n } else {\n newCurrents.push({ content: candidate.content, children: [child] });\n }\n break;\n }\n }\n }\n }\n }\n setCurrents(newCurrents);\n }\n setTrackPoints(newTracePoints);\n return;\n }\n for (const candidate of candidates) {\n for (const child of candidate.children) {\n const geometries = (_d = (_c = ctx.getContentModel(child)) == null ? void 0 : _c.getGeometries) == null ? void 0 : _d.call(_c, child, contents);\n if (geometries) {\n if (isHatchContent(child) && geometries.regions && geometries.bounding) {\n for (const region of geometries.regions) {\n if (region.holesPoints && region.holesPoints.some((h) => ctx.pointInPolygon(p, h))) {\n continue;\n }\n if (ctx.pointInPolygon(p, region.points)) {\n const getGeometriesInRange = (region2) => getContentsInRange(region2).map((c) => ctx.getContentHatchGeometries(c, contents));\n const border = ctx.getHatchByPosition(p, (line) => getGeometriesInRange(ctx.getGeometryLineBoundingFromCache(line)), geometries.bounding.end.x);\n if (border) {\n const holes = ctx.getHatchHoles(border.lines, getGeometriesInRange);\n setCurrents([{\n children: [{\n type: "hatch",\n border: border.lines,\n holes: holes == null ? void 0 : holes.holes,\n ref: {\n point: p,\n ids: [...border.ids, ...(holes == null ? void 0 : holes.ids) || []]\n }\n }],\n content: candidate.content\n }]);\n }\n return;\n }\n }\n }\n for (const line of geometries.lines) {\n if (ctx.getPointAndGeometryLineMinimumDistance(p, line) < 5) {\n setCurrents([{ children: [child], content: candidate.content }]);\n return;\n }\n }\n }\n }\n }\n setCurrents([]);\n },\n onKeyDown(e) {\n var _a, _b;\n if (e.code === "KeyZ" && ctx.metaKeyIfMacElseCtrlKey(e)) {\n if (e.shiftKey) {\n redo(e);\n } else {\n undo(e);\n }\n } else if (e.key === "Enter") {\n if (!type) return;\n const removedIndexes = [];\n const newContents = [];\n for (const { content, children } of state) {\n const parentModel = ctx.getContentModel(content);\n if (parentModel == null ? void 0 : parentModel.break) {\n let points = [];\n for (const child of children) {\n const geometries = (_b = (_a = ctx.getContentModel(child)) == null ? void 0 : _a.getGeometries) == null ? void 0 : _b.call(_a, child, contents);\n if (geometries) {\n const { start, end } = ctx.getGeometryLinesStartAndEnd(geometries.lines);\n if (start && end) {\n if (!ctx.isSamePoint(start, end)) {\n points.push(start, end);\n }\n } else if (start) {\n points.push(start);\n } else if (end) {\n points.push(end);\n }\n }\n }\n points = ctx.deduplicatePosition(points);\n const r = parentModel.break(content, points, contents);\n if (r) {\n removedIndexes.push(ctx.getContentIndex(content, contents));\n newContents.push(...r.filter((c) => children.every((f) => !ctx.deepEquals(f, c))));\n }\n } else if (isHatchContent(content)) {\n const holes = [];\n const ids = [];\n if (content.ref) {\n ids.push(...content.ref.ids);\n }\n const borders = [content.border];\n if (content.holes) {\n holes.push(...content.holes);\n }\n for (const child of children) {\n if (isHatchContent(child)) {\n holes.push(child.border);\n if (child.holes) {\n borders.push(...child.holes);\n }\n if (child.ref) {\n ids.push(...child.ref.ids);\n }\n }\n }\n removedIndexes.push(ctx.getContentIndex(content, contents));\n const result = borders.map((b) => {\n const polygon = ctx.getGeometryLinesPoints(b);\n return ctx.optimizeHatch(b, holes.filter((h) => {\n const start = ctx.getGeometryLineStartAndEnd(h[0]).start;\n return start && (ctx.pointIsOnGeometryLines(start, b) || ctx.pointInPolygon(start, polygon));\n }));\n }).flat();\n newContents.push(...result.map((r) => {\n let ref;\n if (content.ref) {\n const p = content.ref.point;\n if (ctx.pointInPolygon(p, ctx.getGeometryLinesPoints(r.border)) && r.holes.every((h) => !ctx.pointInPolygon(p, ctx.getGeometryLinesPoints(h)))) {\n ref = {\n point: p,\n ids: Array.from(new Set(ids))\n };\n }\n }\n return { ...content, border: r.border, holes: r.holes, ref };\n }));\n }\n }\n onEnd({\n updateContents: (contents2) => {\n ctx.deleteSelectedContents(contents2, removedIndexes);\n contents2.push(...newContents);\n }\n });\n reset();\n }\n },\n assistentContents,\n reset\n };\n },\n contentSelectable(content, contents) {\n return ctx.contentIsDeletable(content, contents);\n },\n hotkey: "TR",\n icon,\n pointSnapDisabled: true\n };\n}\nexport {\n getCommand\n};\n','// dev/cad-editor/plugins/union.plugin.tsx\nfunction getCommand(ctx) {\n const React = ctx.React;\n const icon = /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 100 100" }, /* @__PURE__ */ React.createElement("circle", { cx: "32", cy: "50", r: "32", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fillOpacity: "1", strokeOpacity: "1", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("circle", { cx: "65", cy: "50", r: "32", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fillOpacity: "1", strokeOpacity: "1", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("pattern", { id: "union", patternUnits: "userSpaceOnUse", width: "10", height: "10" }, /* @__PURE__ */ React.createElement("path", { d: "M 0 5 L 5 0 M 10 5 L 5 10", strokeWidth: "1", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor", fillRule: "evenodd" })), /* @__PURE__ */ React.createElement("path", { d: "M 50 78 L 47 79 L 45 81 L 42 81 L 39 82 L 37 82 L 34 82 L 31 82 L 28 82 L 25 81 L 23 81 L 20 79 L 18 78 L 15 77 L 13 75 L 11 73 L 9 71 L 7 69 L 6 66 L 4 64 L 3 61 L 2 58 L 2 56 L 1 53 L 1 50 L 1 47 L 2 44 L 2 42 L 3 39 L 4 36 L 6 34 L 7 31 L 9 29 L 11 27 L 13 25 L 15 23 L 18 22 L 20 21 L 23 19 L 25 19 L 28 18 L 31 18 L 34 18 L 37 18 L 39 18 L 42 19 L 45 19 L 47 21 L 50 22 L 50 22 L 53 21 L 55 19 L 58 19 L 61 18 L 63 18 L 66 18 L 69 18 L 72 18 L 75 19 L 77 19 L 80 21 L 82 22 L 85 23 L 87 25 L 89 27 L 91 29 L 93 31 L 94 34 L 96 36 L 97 39 L 98 42 L 98 44 L 99 47 L 99 50 L 99 53 L 98 56 L 98 58 L 97 61 L 96 64 L 94 66 L 93 69 L 91 71 L 89 73 L 87 75 L 85 77 L 82 78 L 80 79 L 77 81 L 75 81 L 72 82 L 69 82 L 66 82 L 63 82 L 61 82 L 58 81 L 55 81 L 53 79 L 50 78", strokeWidth: "0", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fillOpacity: "1", fill: "url(#union)", stroke: "currentColor", fillRule: "evenodd" }));\n return {\n name: "union",\n execute({ contents, selected }) {\n var _a, _b, _c, _d;\n const first = contents[selected[0][0]];\n if (!first) return;\n const firstGeometries = (_b = (_a = ctx.getContentModel(first)) == null ? void 0 : _a.getGeometries) == null ? void 0 : _b.call(_a, first, contents);\n if (!firstGeometries) return;\n const second = contents[selected[1][0]];\n if (!second) return;\n const secondGeometries = (_d = (_c = ctx.getContentModel(second)) == null ? void 0 : _c.getGeometries) == null ? void 0 : _d.call(_c, second, contents);\n if (!secondGeometries) return;\n if (firstGeometries.regions && secondGeometries.regions) {\n const result = firstGeometries.regions.map((r) => ctx.getHatchesUnion({ border: r.lines, holes: r.holes || [] }, (secondGeometries.regions || []).map((g) => ({ border: g.lines, holes: g.holes || [] })))).flat();\n ctx.deleteSelectedContents(contents, selected.map((s) => s[0]));\n contents.push(...result.map((r) => ({ ...first, type: "hatch", border: r.border, holes: r.holes, ref: void 0 })));\n return;\n }\n const lines = ctx.mergeItems([...firstGeometries.lines, ...secondGeometries.lines], ctx.getTwoGeometryLinesUnionLine);\n ctx.deleteSelectedContents(contents, selected.map((s) => s[0]));\n const allLines = ctx.getSeparatedGeometryLines(lines);\n contents.push(...allLines.map((n) => ({ type: "geometry lines", lines: n })));\n },\n contentSelectable(content, contents) {\n return ctx.contentIsDeletable(content, contents);\n },\n selectCount: 2,\n icon\n };\n}\nexport {\n getCommand\n};\n','// dev/cad-editor/plugins/viewport.plugin.tsx\nfunction getModel(ctx) {\n const getRefIds = (content) => [...ctx.getStrokeRefIds(content), ...ctx.toRefId(content.border, true)];\n function getViewportGeometriesFromCache(content, contents) {\n var _a, _b;\n const geometries = (_b = (_a = ctx.getContentModel(content.border)) == null ? void 0 : _a.getGeometries) == null ? void 0 : _b.call(_a, content.border, contents);\n if (geometries) {\n return geometries;\n }\n return { lines: [], renderingLines: [] };\n }\n const renderCache = new ctx.WeakmapMapCache();\n const React = ctx.React;\n return {\n type: "viewport",\n ...ctx.strokeModel,\n ...ctx.arrowModel,\n move(content, offset) {\n var _a, _b;\n (_b = (_a = ctx.getContentModel(content.border)) == null ? void 0 : _a.move) == null ? void 0 : _b.call(_a, content.border, offset);\n ctx.movePoint(content, offset);\n },\n rotate(content, center, angle, contents) {\n var _a, _b;\n (_b = (_a = ctx.getContentModel(content.border)) == null ? void 0 : _a.rotate) == null ? void 0 : _b.call(_a, content.border, center, angle, contents);\n },\n scale(content, center, sx, sy, contents) {\n var _a, _b;\n return (_b = (_a = ctx.getContentModel(content.border)) == null ? void 0 : _a.scale) == null ? void 0 : _b.call(_a, content.border, center, sx, sy, contents);\n },\n skew(content, center, sx, sy, contents) {\n var _a, _b;\n return (_b = (_a = ctx.getContentModel(content.border)) == null ? void 0 : _a.skew) == null ? void 0 : _b.call(_a, content.border, center, sx, sy, contents);\n },\n mirror(content, line, angle, contents) {\n var _a, _b;\n (_b = (_a = ctx.getContentModel(content.border)) == null ? void 0 : _a.mirror) == null ? void 0 : _b.call(_a, content.border, line, angle, contents);\n },\n render(content, renderCtx) {\n var _a;\n const render = (_a = ctx.getContentModel(content.border)) == null ? void 0 : _a.render;\n if (render) {\n return render(content.border, {\n ...renderCtx,\n clip: renderCtx.isHoveringOrSelected || content.hidden ? void 0 : () => {\n const sortedContents = ctx.getSortedContents(renderCtx.contents).contents;\n const children = renderCache.get(sortedContents, renderCtx.target.type, () => {\n const children2 = [];\n sortedContents.forEach((content2) => {\n var _a2;\n if (!content2 || content2.visible === false || ctx.isViewportContent(content2)) {\n return;\n }\n const ContentRender = (_a2 = ctx.getContentModel(content2)) == null ? void 0 : _a2.render;\n if (ContentRender) {\n children2.push(ContentRender(content2, renderCtx));\n }\n });\n return children2;\n });\n return renderCtx.target.renderGroup(children, { matrix: ctx.getViewportMatrix(content) });\n }\n });\n }\n return renderCtx.target.renderEmpty();\n },\n getEditPoints(content, contents) {\n var _a, _b;\n const editPoints = (_b = (_a = ctx.getContentModel(content.border)) == null ? void 0 : _a.getEditPoints) == null ? void 0 : _b.call(_a, content.border, contents);\n if (!editPoints) return;\n return ctx.getEditPointsFromCache(content, () => {\n return {\n ...editPoints,\n editPoints: editPoints.editPoints.map((e) => ({\n ...e,\n update(c, props) {\n var _a2;\n if (!ctx.isViewportContent(c)) {\n return;\n }\n if (e.type === "move") {\n c.x += props.cursor.x - props.start.x;\n c.y += props.cursor.y - props.start.y;\n }\n return (_a2 = e.update) == null ? void 0 : _a2.call(e, c.border, props);\n }\n }))\n };\n });\n },\n getGeometries: getViewportGeometriesFromCache,\n propertyPanel(content, update, contents, options) {\n var _a, _b;\n const border = (_b = (_a = ctx.getContentModel(content.border)) == null ? void 0 : _a.propertyPanel) == null ? void 0 : _b.call(_a, content.border, (recipe) => {\n update((c) => {\n if (ctx.isViewportContent(c)) {\n recipe(c.border, contents);\n }\n });\n }, contents, options);\n const result = {\n from: /* @__PURE__ */ React.createElement(ctx.Button, { onClick: () => options.acquirePoint((p) => update((c) => {\n if (ctx.isViewportContent(c)) {\n c.x = p.x;\n c.y = p.y;\n }\n })) }, "canvas"),\n x: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.x, setValue: (v) => update((c) => {\n if (ctx.isViewportContent(c)) {\n c.x = v;\n }\n }) }),\n y: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.y, setValue: (v) => update((c) => {\n if (ctx.isViewportContent(c)) {\n c.y = v;\n }\n }) }),\n scale: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.scale, setValue: (v) => update((c) => {\n if (ctx.isViewportContent(c)) {\n c.scale = v;\n }\n }) }),\n rotate: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.rotate || 0, setValue: (v) => update((c) => {\n if (ctx.isViewportContent(c)) {\n c.rotate = v;\n }\n }) }),\n locked: /* @__PURE__ */ React.createElement(ctx.BooleanEditor, { value: content.locked || false, setValue: (v) => update((c) => {\n if (ctx.isViewportContent(c)) {\n c.locked = v;\n }\n }) }),\n hidden: /* @__PURE__ */ React.createElement(ctx.BooleanEditor, { value: content.hidden || false, setValue: (v) => update((c) => {\n if (ctx.isViewportContent(c)) {\n c.hidden = v;\n }\n }) })\n };\n if (border) {\n result.border = /* @__PURE__ */ React.createElement(ctx.ObjectEditor, { properties: border });\n }\n return {\n ...result,\n ...ctx.getStrokeContentPropertyPanel(content, update, contents)\n };\n },\n isValid: (c, p) => ctx.validate(c, ctx.ViewportContent, p),\n getRefIds,\n updateRefId: ctx.updateStrokeRefIds,\n deleteRefId: ctx.deleteStrokeRefIds\n };\n}\nfunction getCommand(ctx) {\n const React = ctx.React;\n const icon = /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 100 100" }, /* @__PURE__ */ React.createElement("rect", { x: "14", y: "18", width: "71", height: "71", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("g", { transform: "" }, /* @__PURE__ */ React.createElement("polyline", { points: "47,55 78,24", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polyline", { points: "85,18 70,43 59,32", strokeWidth: "0", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "currentColor", stroke: "currentColor" })), /* @__PURE__ */ React.createElement("g", { transform: "" }, /* @__PURE__ */ React.createElement("polyline", { points: "47,55 20,82", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polyline", { points: "14,89 29,62 40,73", strokeWidth: "0", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "currentColor", stroke: "currentColor" })), /* @__PURE__ */ React.createElement("g", { transform: "" }, /* @__PURE__ */ React.createElement("polyline", { points: "47,54 78,82", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polyline", { points: "85,89 58,75 69,63", strokeWidth: "0", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "currentColor", stroke: "currentColor" })), /* @__PURE__ */ React.createElement("g", { transform: "" }, /* @__PURE__ */ React.createElement("polyline", { points: "47,55 20,25", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polyline", { points: "14,18 39,34 27,44", strokeWidth: "0", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", fill: "currentColor", stroke: "currentColor" })));\n return {\n name: "create viewport",\n selectCount: 1,\n icon,\n contentSelectable(content) {\n return ctx.contentIsClosedPath(content);\n },\n execute({ contents, selected }) {\n contents.forEach((content, index) => {\n var _a, _b;\n if (content && ctx.isSelected([index], selected) && ((_b = (_a = this.contentSelectable) == null ? void 0 : _a.call(this, content, contents)) != null ? _b : true)) {\n const viewport = ctx.getDefaultViewport(content, contents);\n if (!viewport) return;\n const result = {\n type: "viewport",\n border: content,\n ...viewport\n };\n if (result) {\n contents[index] = result;\n }\n }\n });\n }\n };\n}\nexport {\n getCommand,\n getModel\n};\n','// dev/cad-editor/plugins/wire.plugin.tsx\nfunction getModel(ctx) {\n const WireContent = ctx.and(ctx.BaseContent("wire"), {\n points: ctx.minItems(2, [ctx.Position]),\n refs: [ctx.ContentRef]\n });\n const LampContent = ctx.and(ctx.BaseContent("lamp"), ctx.Position, {\n size: ctx.number\n });\n const getIntersectedWires = (content, contents) => {\n const lines = Array.from(ctx.iteratePolylineLines(content.points));\n const wires = [];\n for (const c of ctx.getSortedContents(contents).contents) {\n if (!c) continue;\n if (ctx.shallowEquals(c, content)) {\n return wires;\n }\n if (isWireContent(c) && ctx.first(ctx.iterateGeometryLinesIntersectionPoints(getWireGeometries(c, contents).lines, lines))) {\n wires.push(c);\n }\n }\n return wires;\n };\n const getWireRefIds = (content) => [...ctx.getStrokeRefIds(content), ...ctx.toRefIds(content.refs)];\n const getLampRefIds = (content) => ctx.getStrokeRefIds(content);\n const wireGeometriesCache = new ctx.WeakmapValuesCache();\n function getWireGeometries(content, contents) {\n const refs = new Set(ctx.iterateRefContents(getWireRefIds(content), contents, [content]));\n getIntersectedWires(content, contents).forEach((e) => refs.add(e));\n return wireGeometriesCache.get(content, refs, () => {\n let lines = Array.from(ctx.iteratePolylineLines(content.points));\n const joints = [];\n for (const ref of refs) {\n if (isWireContent(ref)) {\n const intersections = Array.from(ctx.iterateGeometryLinesIntersectionPoints(lines, getWireGeometries(ref, contents).lines));\n for (const intersection of intersections) {\n const param = ctx.getGeometryLinesParamAtPoint(intersection, lines);\n if (ctx.isZero(param) || ctx.isSameNumber(lines.length, param)) {\n let joint = joints.find((j) => ctx.isSamePoint(j.position, intersection));\n if (!joint) {\n joint = { position: intersection, count: 1 };\n joints.push(joint);\n }\n joint.count++;\n continue;\n }\n const radian = ctx.getGeometryLinesTangentRadianAtParam(param, lines);\n if (radian === void 0) continue;\n const angle = ctx.radianToAngle(radian);\n const radius = 5;\n const startPoint = ctx.getPointByLengthAndRadian(intersection, -radius, radian);\n const endPoint = ctx.getPointByLengthAndRadian(intersection, radius, radian);\n lines = [\n ...ctx.getPartOfGeometryLines(0, ctx.getGeometryLinesParamAtPoint(startPoint, lines), lines),\n { type: "arc", curve: { x: intersection.x, y: intersection.y, r: radius, startAngle: angle, endAngle: ctx.reverseAngle(angle) } },\n ...ctx.getPartOfGeometryLines(ctx.getGeometryLinesParamAtPoint(endPoint, lines), lines.length, lines)\n ];\n }\n } else if (isLampContent(ref)) {\n const params = ctx.deduplicate(Array.from(ctx.iterateGeometryLinesIntersectionPoints(lines, getLampGeometries(ref, contents).lines)).map((p) => ctx.getGeometryLinesParamAtPoint(p, lines)), ctx.isSameNumber);\n if (params.length === 1) {\n const param = params[0];\n if (param < lines.length / 2) {\n lines = ctx.getPartOfGeometryLines(param, lines.length, lines);\n } else {\n lines = ctx.getPartOfGeometryLines(0, param, lines);\n }\n } else if (params.length > 1) {\n lines = [\n ...ctx.getPartOfGeometryLines(0, Math.min(...params), lines),\n ...ctx.getPartOfGeometryLines(Math.max(...params), lines.length, lines)\n ];\n }\n }\n }\n const validJoints = joints.filter((j) => j.count === 3).map((j) => j.position);\n return {\n lines,\n joints: validJoints,\n bounding: ctx.getPointsBounding(content.points),\n regions: validJoints.length > 0 ? [] : void 0,\n renderingLines: lines.map((line) => ctx.dashedPolylineToLines(ctx.getGeometryLinesPoints([line]), content.dashArray)).flat()\n };\n });\n }\n function getLampGeometries(content, contents) {\n const refs = new Set(ctx.iterateRefContents(getLampRefIds(content), contents, [content]));\n const arc = ctx.circleToArc({ x: content.x, y: content.y, r: content.size });\n return ctx.getGeometriesFromCache(content, refs, () => {\n const size = content.size * Math.SQRT1_2;\n const lineSegments = [\n [{ x: content.x - size, y: content.y - size }, { x: content.x + size, y: content.y + size }],\n [{ x: content.x - size, y: content.y + size }, { x: content.x + size, y: content.y - size }]\n ];\n const points = ctx.arcToPolyline(arc, ctx.defaultAngleDelta);\n return {\n lines: [{ type: "arc", curve: arc }, ...lineSegments],\n bounding: {\n start: { x: content.x - content.size, y: content.y - content.size },\n end: { x: content.x + content.size, y: content.y + content.size }\n },\n renderingLines: [\n ...ctx.dashedPolylineToLines(points, content.dashArray),\n ...lineSegments.map((s) => ctx.dashedPolylineToLines(s, content.dashArray)).flat()\n ]\n };\n });\n }\n const React = ctx.React;\n return [\n {\n type: "wire",\n ...ctx.strokeModel,\n move(content, offset) {\n for (const point of content.points) {\n ctx.movePoint(point, offset);\n }\n },\n render(content, renderCtx) {\n const { options, target } = ctx.getStrokeRenderOptionsFromRenderContext(content, renderCtx);\n const { renderingLines, joints } = getWireGeometries(content, renderCtx.contents);\n return target.renderGroup([\n ...renderingLines.map((line) => target.renderPolyline(line, options)),\n ...joints.map((joint) => target.renderCircle(joint.x, joint.y, 1, { fillColor: 0 }))\n ]);\n },\n getGeometries: getWireGeometries,\n propertyPanel(content, update, contents) {\n return {\n ...ctx.getStrokeContentPropertyPanel(content, update, contents)\n };\n },\n isValid: (c, p) => ctx.validate(c, WireContent, p),\n getRefIds: getWireRefIds,\n updateRefId(content, update) {\n for (const [i, id] of content.refs.entries()) {\n const newRefId = update(id);\n if (newRefId !== void 0) {\n content.refs[i] = newRefId;\n }\n }\n ctx.updateStrokeRefIds(content, update);\n },\n deleteRefId(content, ids) {\n for (const id of ids) {\n const index = content.refs.indexOf(id);\n if (index >= 0) {\n content.refs.splice(index, 1);\n }\n }\n ctx.deleteStrokeRefIds(content, ids);\n }\n },\n {\n type: "lamp",\n ...ctx.strokeModel,\n move(content, offset) {\n ctx.movePoint(content, offset);\n },\n render(content, renderCtx) {\n const { options, target } = ctx.getStrokeRenderOptionsFromRenderContext(content, renderCtx);\n const geometries = getLampGeometries(content, renderCtx.contents);\n const children = [target.renderCircle(content.x, content.y, content.size, options)];\n for (const line of geometries.lines) {\n if (Array.isArray(line)) {\n children.push(target.renderPolyline(line, options));\n }\n }\n return target.renderGroup(children);\n },\n getGeometries: getLampGeometries,\n getEditPoints(content, contents) {\n return ctx.getEditPointsFromCache(content, () => {\n const editPoints = [{\n x: content.x,\n y: content.y,\n cursor: "move",\n update(c, { cursor, start, target }) {\n if (!isLampContent(c)) {\n return;\n }\n c.x += cursor.x - start.x;\n c.y += cursor.y - start.y;\n return {\n updateRelatedContents() {\n const index = ctx.getContentIndex(content, contents);\n const targetIndex = target ? ctx.getContentIndex(target.content, contents) : void 0;\n const [, patches, reversePatches] = ctx.produceWithPatches(contents, (draft) => {\n var _a, _b;\n for (let i = 0; i < draft.length; i++) {\n const c2 = draft[i];\n if (!c2) continue;\n if (i === targetIndex && isWireContent(c2)) {\n if (!c2.refs.includes(index)) {\n c2.refs.push(index);\n }\n } else {\n (_b = (_a = ctx.getContentModel(c2)) == null ? void 0 : _a.deleteRefId) == null ? void 0 : _b.call(_a, c2, [index]);\n }\n }\n });\n return { patches, reversePatches };\n }\n };\n }\n }];\n return { editPoints };\n });\n },\n propertyPanel(content, update, contents) {\n return {\n size: /* @__PURE__ */ React.createElement(ctx.NumberEditor, { value: content.size, setValue: (v) => update((c) => {\n if (isLampContent(c)) {\n c.size = v;\n }\n }) }),\n ...ctx.getStrokeContentPropertyPanel(content, update, contents)\n };\n },\n isValid: (c, p) => ctx.validate(c, LampContent, p),\n getRefIds: getLampRefIds,\n updateRefId: ctx.updateStrokeRefIds,\n deleteRefId: ctx.deleteStrokeRefIds\n }\n ];\n}\nfunction isWireContent(content) {\n return content.type === "wire";\n}\nfunction isLampContent(content) {\n return content.type === "lamp";\n}\nfunction getCommand(ctx) {\n const React = ctx.React;\n const icon1 = /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 100 100" }, /* @__PURE__ */ React.createElement("polyline", { points: "4,4 97,4 97,96", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", strokeOpacity: "1", fill: "none", stroke: "currentColor" }));\n const icon2 = /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 100 100" }, /* @__PURE__ */ React.createElement("circle", { cx: "50", cy: "50", r: "45", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", strokeOpacity: "1", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polyline", { points: "18,18 82,82", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", strokeOpacity: "1", fill: "none", stroke: "currentColor" }), /* @__PURE__ */ React.createElement("polyline", { points: "18,82 82,18", strokeWidth: "5", strokeMiterlimit: "10", strokeLinejoin: "miter", strokeLinecap: "butt", strokeOpacity: "1", fill: "none", stroke: "currentColor" }));\n return [\n {\n name: "create wire",\n useCommand({ onEnd, type, strokeStyleId }) {\n const { line, onClick, onMove, input, lastPosition, reset } = ctx.useLineClickCreate(\n type === "create wire",\n (c) => onEnd({\n updateContents: (contents) => contents.push({ points: c, refs: [], strokeStyleId, type: "wire" })\n })\n );\n const assistentContents = [];\n if (line) {\n assistentContents.push({ points: line, refs: [], strokeStyleId, type: "wire" });\n }\n return {\n onStart: onClick,\n input,\n onMove,\n assistentContents,\n lastPosition,\n reset\n };\n },\n selectCount: 0,\n icon: icon1\n },\n {\n name: "create lamp",\n useCommand({ onEnd, type, strokeStyleId }) {\n const [lamp, setLamp] = React.useState();\n const [wireId, setWireId] = React.useState();\n const reset = () => {\n setWireId(void 0);\n setLamp(void 0);\n };\n const assistentContents = [];\n if (lamp) {\n assistentContents.push(lamp);\n }\n return {\n onStart: (p) => {\n onEnd({\n updateContents: (contents) => {\n if (wireId !== void 0) {\n const content = contents[wireId];\n if (content && isWireContent(content)) {\n content.refs.push(contents.length);\n }\n }\n contents.push({ x: p.x, y: p.y, size: 5, strokeStyleId, type: "lamp" });\n }\n });\n },\n onMove(p, _, target) {\n if (!type) return;\n setWireId(target == null ? void 0 : target.id);\n setLamp({ x: p.x, y: p.y, size: 5, strokeStyleId, type: "lamp" });\n },\n assistentContents,\n reset\n };\n },\n selectCount: 0,\n icon: icon2\n }\n ];\n}\nexport {\n getCommand,\n getModel,\n isLampContent,\n isWireContent\n};\n']},7449:(e,t,n)=>{"use strict";n.d(t,{MemoizedRenderer:()=>y,getAllRendererTypes:()=>b,registerRenderer:()=>x});var r=n(8662),o=n(3696),i=n.n(o),a=n(9758),s=n(4469),c=Object.defineProperty,l=Object.defineProperties,u=Object.getOwnPropertyDescriptors,p=Object.getOwnPropertySymbols,d=Object.prototype.hasOwnProperty,f=Object.prototype.propertyIsEnumerable,g=(e,t,n)=>t in e?c(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,h=(e,t)=>{for(var n in t||(t={}))d.call(t,n)&&g(e,n,t[n]);if(p)for(var n of p(t))f.call(t,n)&&g(e,n,t[n]);return e},m=(e,t)=>l(e,u(t));const y=i().memo((function(e){var t,n,o,c,l,u;const p=new a.Debug(e.debug),d=v[e.type||b()[0]],f=i().useRef(new a.WeakmapMapCache);(0,a.useValueChanged)(e.type,(()=>f.current.clear())),(0,a.useValueChanged)(e.backgroundColor,(()=>f.current.clear()));const g=i().useRef(new a.WeakmapCache);if((0,a.useValueChanged)(d,(()=>g.current.clear())),!d)return null;const y=(0,a.getColorString)(e.backgroundColor),x=+`0x${y.substring(1,3)}`,C=+`0x${y.substring(3,5)}`,E=+`0x${y.substring(5)}`,P=(Math.max(x,E,C)+Math.min(x,E,C))/2,w=e=>P<128?0===e?16777215:e:16777215===e?0:e;p.mark("before contents");let k=[];const _=new a.Merger((e=>k.push(d.renderPath(e.target,{strokeColor:e.type.strokeColor,dashArray:e.type.dashArray,strokeWidth:e.type.strokeWidth,strokeOpacity:e.type.strokeOpacity,lineJoin:e.type.lineJoin,miterLimit:e.type.miterLimit,lineCap:e.type.lineCap}))),((e,t)=>e.strokeColor===t.strokeColor&&e.strokeWidth===t.strokeWidth&&e.strokeOpacity===t.strokeOpacity&&e.lineJoin===t.lineJoin&&e.miterLimit===t.miterLimit&&e.lineCap===t.lineCap&&(0,a.isSamePath)(e.dashArray,t.dashArray)),(e=>e.line)),S=null!=(t=e.previewPatches)?t:[],R=S.length>0&&!e.performanceMode?(0,r.applyPatches)(e.contents,S):e.contents,T=(0,s.getSortedContents)(R).contents,A={transformColor:w,target:d,getStrokeColor:e=>void 0!==e.strokeColor?e.trueStrokeColor?e.strokeColor:w(e.strokeColor):(0,s.hasFill)(e)?void 0:s.defaultStrokeColor,getFillColor:e=>void 0!==e.fillColor?e.trueFillColor?e.fillColor:w(e.fillColor):void 0,getFillPattern:e=>{if(void 0===e.fillPattern)return;const t=e.fillPattern;return g.current.get(t,(()=>({width:t.width,height:t.height,pattern:()=>{var e;return d.renderPath(t.lines,{strokeColor:null!=(e=void 0!==t.strokeColor?w(t.strokeColor):void 0)?e:s.defaultStrokeColor,strokeOpacity:t.strokeOpacity,lineCap:"square"})}})))},time:e.time,contents:R,patches:S};k=f.current.get(T,e.time,(()=>(T.forEach((t=>{var n,r,o,i,c,l;if(!t||!1===t.visible)return;const u=(0,s.getContentModel)(t);if(u)if("svg"!==d.type&&u.getGeometries){const{renderingLines:p,regions:d,bounding:f}=u.getGeometries(t,e.contents);if(!p||!f||d||(0,s.isClipContent)(t)&&t.clip||(0,s.isViewportContent)(t)&&!t.hidden){const e=u.render;e&&(_.flushLast(),k.push(e(t,h({transformStrokeWidth:e=>e},A))))}else{const e=null!=(n=(0,s.isStrokeContent)(t)?t.strokeWidth:void 0)?n:(0,s.getDefaultStrokeWidth)(t);let u=null!=(r=(0,s.isStrokeContent)(t)?t.strokeColor:void 0)?r:s.defaultStrokeColor;u=w(u);const d=null!=(o=(0,s.isStrokeContent)(t)?t.strokeOpacity:void 0)?o:s.defaultOpacity,f=null!=(i=(0,s.isStrokeContent)(t)?t.lineJoin:void 0)?i:a.defaultLineJoin,g=null!=(c=(0,s.isStrokeContent)(t)?t.miterLimit:void 0)?c:a.defaultMiterLimit,h=null!=(l=(0,s.isStrokeContent)(t)?t.lineCap:void 0)?l:a.defaultLineCap;for(const t of p)_.push({line:t,strokeColor:u,strokeWidth:e,strokeOpacity:d,lineJoin:f,miterLimit:g,lineCap:h})}}else{const e=u.render;e&&(_.flushLast(),k.push(e(t,h({transformStrokeWidth:e=>e},A))))}})),k))),_.flushLast(),p.mark("before assistent contents");const L=[],M=[];if(e.performanceMode){const t=new Set(S.map((e=>e.path[0]))),n=[];for(const o of t){const t=S.filter((e=>e.path[0]===o));if(t.length>0){const i=e.contents[o];i?n.push((0,r.applyPatches)(i,t.map((e=>m(h({},e),{path:e.path.slice(1)}))))):t.forEach((e=>{"add"===e.op&&e.value&&n.push(e.value)}))}}let o=[];if(n.forEach((e=>{var t;const n=null==(t=(0,s.getContentModel)(e))?void 0:t.render;n&&o.push(n(e,m(h({transformStrokeWidth:e=>e},A),{isAssistence:!0})))})),o.length>0&&void 0!==e.activeViewportIndex){const t=R[e.activeViewportIndex];t&&(0,s.isViewportContent)(t)&&(o=[d.renderGroup(o,{matrix:(0,s.getViewportMatrix)(t)})])}L.push(...o)}if(!1!==e.operatorVisible){const t=e.selected||[],n=e.othersSelectedContents||[];t.length+n.length>0&&e.contents.forEach(((r,o)=>{if(!r)return;const i=(0,s.getContentModel)(r);if(!i)return;const c=n.filter((e=>e.selection.includes(o))).map((e=>e.operator));if((0,a.isSelected)([o],t)&&c.unshift("me"),i.getOperatorRenderPosition&&c.length>0){const t=i.getOperatorRenderPosition(r,e.contents);M.push(d.renderText(t.x,t.y,c.join(","),16711680,16,"monospace"))}}))}for(const t of[...e.hovering||[],...e.assistentHovering||[]]){const e=(0,s.getContentByIndex)(R,t);if(e){const t=null==(n=(0,s.getContentModel)(e))?void 0:n.render;t&&(M.push(t(e,m(h({transformStrokeWidth:e=>e+4},A),{isHoveringOrSelected:!0}))),M.push(t(e,m(h({transformStrokeWidth:e=>e+2},A),{isHoveringOrSelected:!0}))),M.push(t(e,m(h({transformStrokeWidth:e=>e},A),{isHoveringOrSelected:!0}))))}}for(const t of[...e.selected||[],...e.assistentSelected||[]]){const n=(0,s.getContentByIndex)(R,t);if(n){const t=null!=(o=(0,s.isStrokeContent)(n)?n.strokeWidth:void 0)?o:(0,s.getDefaultStrokeWidth)(n),r=(0,s.getContentModel)(n),i=null==r?void 0:r.render;i&&(M.push(i(n,m(h({transformStrokeWidth:e=>e+4},A),{isHoveringOrSelected:!0}))),M.push(i(n,m(h({transformStrokeWidth:e=>e+2},A),{isHoveringOrSelected:!0}))),M.push(i(n,m(h({transformStrokeWidth:e=>e},A),{isHoveringOrSelected:!0}))));const a=null==r?void 0:r.renderIfSelected;a&&M.push(a(n,{color:w(16711680),target:d,strokeWidth:t,contents:e.contents}))}}if(void 0!==e.activeViewportIndex){const t=R[e.activeViewportIndex];if(t){const e=null==(c=(0,s.getContentModel)(t))?void 0:c.render;e&&(L.push(e(t,m(h({transformStrokeWidth:e=>e+4},A),{isHoveringOrSelected:!0}))),L.push(e(t,m(h({transformStrokeWidth:e=>e+2},A),{isHoveringOrSelected:!0}))))}}else if(void 0!==e.active){const t=R[e.active];if(t){const e=null==(l=(0,s.getContentModel)(t))?void 0:l.render;e&&L.push(e(t,m(h({transformStrokeWidth:e=>e+1},A),{isHoveringOrSelected:!0})))}}if(null==(u=e.assistentContents)||u.forEach((e=>{var t;const n=null==(t=(0,s.getContentModel)(e))?void 0:t.render;n&&M.push(n(e,m(h({transformStrokeWidth:e=>e},A),{isAssistence:!0})))})),M.length>0){const t=void 0!==e.activeViewportIndex?R[e.activeViewportIndex]:void 0;t&&(0,s.isViewportContent)(t)?L.push(d.renderGroup(M,{matrix:(0,s.getViewportMatrix)(t)})):L.push(...M)}const I=0===L.length?k:[...k,...L];return e.debug&&console.info(p.print()),d.renderResult(I,e.width,e.height,{attributes:{style:h({position:"absolute",boxSizing:"border-box"},e.style),onClick:e.onClick,onMouseDown:e.onMouseDown,onMouseUp:e.onMouseUp,onContextMenu:e.onContextMenu,onDoubleClick:e.onDoubleClick,onMouseLeave:e.onMouseLeave},transform:{x:e.x,y:e.y,scale:e.scale,rotate:e.rotate},backgroundColor:e.backgroundColor,debug:e.debug,strokeWidthFixed:!e.printMode})})),v={};function x(e){v[e.type]=e}function b(){return Object.keys(v)}},2197:(e,t,n)=>{"use strict";n.d(t,{default:()=>s});var r=n(8662),o=n(3696),i=n.n(o),a=n(9758);const s=()=>{const[e,t]=i().useState([]),{circle:n,arc:o,onClick:s,onMove:c,input:l,reset:u}=(0,a.useCircleArcClickCreate)("center radius",(n=>{t((0,r.produce)(e,(e=>{e.push(n)})))}));(0,a.useGlobalKeyDown)((e=>{"Escape"===e.key&&u()}));const p=n||o;return i().createElement("div",{onClick:e=>s({x:e.clientX,y:e.clientY}),onMouseMove:e=>c({x:e.clientX,y:e.clientY}),style:{height:"100%"}},i().createElement("svg",{viewBox:"0 0 800 600",width:800,height:600,xmlns:"http://www.w3.org/2000/svg",fill:"none",style:{position:"absolute",left:0,top:0},onClick:e=>s({x:e.clientX,y:e.clientY}),onMouseMove:e=>c({x:e.clientX,y:e.clientY})},p&&i().createElement("circle",{cx:p.x,cy:p.y,r:p.r,stroke:"#00ff00",strokeDasharray:"4"}),[...e,o].map(((e,t)=>{if(e){const n=(0,a.polarToCartesian)(e.x,e.y,e.r,e.endAngle),r=(0,a.polarToCartesian)(e.x,e.y,e.r,e.startAngle);return i().createElement("path",{key:t,d:`M ${n.x} ${n.y} A ${e.r} ${e.r} 0 ${e.endAngle-e.startAngle<=180?"0":"1"} 0 ${r.x} ${r.y}`,stroke:"#00ff00"})}return null}))),l)}},6844:(e,t,n)=>{"use strict";n.d(t,{default:()=>m});var r=n(8662),o=n(3696),i=n.n(o),a=n(9758),s=Object.defineProperty,c=Object.defineProperties,l=Object.getOwnPropertyDescriptors,u=Object.getOwnPropertySymbols,p=Object.prototype.hasOwnProperty,d=Object.prototype.propertyIsEnumerable,f=(e,t,n)=>t in e?s(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,g=(e,t)=>{for(var n in t||(t={}))p.call(t,n)&&f(e,n,t[n]);if(u)for(var n of u(t))d.call(t,n)&&f(e,n,t[n]);return e},h=(e,t)=>c(e,l(t));const m=()=>{const[e,t]=i().useState({x:200,y:200,r:100,startAngle:-30,endAngle:120}),{offset:n,onStart:o,mask:s,reset:c}=(0,a.useCircleArcEdit)((()=>t(l)));(0,a.useGlobalKeyDown)((e=>{"Escape"===e.key&&c()}));const l=(0,r.produce)(e,(e=>{n&&(e.x+=n.x,e.y+=n.y,e.r+=n.r,e.startAngle+=n.startAngle,e.endAngle+=n.endAngle,(0,a.normalizeAngleRange)(e))})),u=(0,a.polarToCartesian)(l.x,l.y,l.r,l.endAngle),p=(0,a.polarToCartesian)(l.x,l.y,l.r,l.startAngle);return i().createElement(i().Fragment,null,i().createElement("svg",{viewBox:"0 0 800 600",width:800,height:600,xmlns:"http://www.w3.org/2000/svg",fill:"none",style:{position:"absolute",left:0,top:0}},i().createElement("path",{d:`M ${u.x} ${u.y} A ${l.r} ${l.r} 0 ${l.endAngle-l.startAngle<=180?"0":"1"} 0 ${p.x} ${p.y}`,stroke:"#00ff00"})),i().createElement(a.CircleArcEditBar,h(g({},l),{onMouseDown:(e,t,n)=>o(e,h(g({},l),{type:t,cursor:n}))})),s)}},2960:(e,t,n)=>{"use strict";n.d(t,{default:()=>s});var r=n(8662),o=n(3696),i=n.n(o),a=n(9758);const s=()=>{const[e,t]=i().useState([]),{circle:n,onClick:o,onMove:s,input:c,reset:l}=(0,a.useCircleClickCreate)("center radius",(n=>{t((0,r.produce)(e,(e=>{e.push(n)})))}));return(0,a.useGlobalKeyDown)((e=>{"Escape"===e.key&&l()})),i().createElement("div",{onClick:e=>o({x:e.clientX,y:e.clientY}),onMouseMove:e=>s({x:e.clientX,y:e.clientY}),style:{height:"100%"}},[...e,n].map(((e,t)=>e&&i().createElement("div",{key:t,style:{width:2*e.r+"px",height:2*e.r+"px",left:e.x-e.r+"px",top:e.y-e.r+"px",borderRadius:`${e.r}px`,position:"absolute",border:"1px solid #00ff00"}}))),c)}},9857:(e,t,n)=>{"use strict";n.d(t,{default:()=>g});var r=n(8662),o=n(3696),i=n.n(o),a=n(9758),s=Object.defineProperty,c=Object.defineProperties,l=Object.getOwnPropertyDescriptors,u=Object.getOwnPropertySymbols,p=Object.prototype.hasOwnProperty,d=Object.prototype.propertyIsEnumerable,f=(e,t,n)=>t in e?s(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n;const g=()=>{const[e,t]=i().useState({x:300,y:200,r:100}),{offset:n,onStart:o,mask:s,reset:g}=(0,a.useCircleEdit)((()=>t(h))),h=(0,r.produce)(e,(e=>{e.x+=n.x,e.y+=n.y,e.r+=n.r}));return(0,a.useGlobalKeyDown)((e=>{"Escape"===e.key&&g()})),i().createElement(i().Fragment,null,i().createElement("div",{style:{width:2*h.r+"px",height:2*h.r+"px",left:h.x-h.r+"px",top:h.y-h.r+"px",borderRadius:`${h.r}px`,position:"absolute",border:"1px solid #00ff00"}}),i().createElement(a.CircleEditBar,{x:h.x,y:h.y,radius:h.r,onMouseDown:(t,n,r)=>{return o(t,(i=((e,t)=>{for(var n in t||(t={}))p.call(t,n)&&f(e,n,t[n]);if(u)for(var n of u(t))d.call(t,n)&&f(e,n,t[n]);return e})({},e),c(i,l({type:n,cursor:r}))));var i}}),s)}},3802:(e,t,n)=>{"use strict";n.d(t,{CircuitGraphEditor:()=>h});var r=n(3696),o=n.n(r),i=n(8662),a=n(9758),s=n(7883),c=n(4942),l=n(5918),u=n(66),p=n(4607),d=n(3031),f=n(7305),g=n(3649);(0,i.enablePatches)(),(0,s.registerModel)(c.powerModel),(0,s.registerModel)(l.resistanceModel),(0,s.registerModel)(u.wireModel),(0,s.registerModel)(f.switchModel),(0,s.registerModel)(g.capacitorModel);const h=o().forwardRef(((e,t)=>{var n,r,c,l,u;const{width:f,height:g}=(0,a.useWindowSize)(),{state:h,setState:m,undo:y,redo:v,applyPatchFromSelf:x,applyPatchFromOtherOperators:b}=(0,a.usePatchBasedUndoRedo)(e.initialState,e.operator,{onApplyPatchesFromSelf:e.onApplyPatchesFromSelf}),{x:C,y:E,ref:P,setX:w,setY:k}=(0,a.useWheelScroll)(),{scale:_,ref:S}=(0,a.useWheelZoom)({min:.001,onChange(e,t,n){const r=(0,a.scaleByCursorPosition)({width:f,height:g},t/e,n);w(r.setX),k(r.setY)}}),[R,T]=o().useState(),[A,L]=o().useState(),[M,I]=o().useState(),[O,D]=o().useState(),B=M?s.modelCenter[M]:void 0,z=[],F=[],N=[],U=[],[G,j]=o().useState();let V;const[W,H]=o().useState([]),[q,$]=o().useState(),X=o().useRef(),Y=o().useRef(),{line:K,onClick:Z,reset:Q,onMove:J,lastPosition:ee}=(0,a.useLineClickCreate)(void 0!==M,(e=>{m((t=>{if(!(null==B?void 0:B.createPreview))return;let n,r,o=h.length;if(void 0===X.current){const r={type:"junction",position:e[0]};t.push(r),n=o,o++}else n=X.current;if(void 0===Y.current){const n={type:"junction",position:e[1]};t.push(n),r=o,o++}else r=Y.current;t.push(B.createPreview({start:n,end:r}))})),ne()}),{once:!0});if(K&&(null==B?void 0:B.createPreview)){const e={type:"junction",position:K[0]},t={type:"junction",position:K[1]};z.push(e,t,B.createPreview({start:e,end:t}))}const te={x:C,y:E,scale:_,center:{x:f/2,y:g/2}},ne=()=>{I(void 0),X.current=void 0,Y.current=void 0,D(void 0),T(void 0),L(void 0),$(void 0)},{editPoint:re,updateEditPreview:oe,onEditMove:ie,onEditClick:ae,editLastPosition:se,getEditAssistentContents:ce,resetEdit:le}=(0,a.useEdit)((()=>{const e=[],t=[];let n=h.length;for(const r of F)if("replace"===r.op&&2===r.path.length&&r.value&&(0,s.isJunctionContent)(r.value)){const o=r.path[1];"start"!==o&&"end"!==o||(e.push({op:"add",path:[n],value:r.value}),r.value=n,t.push({op:"replace",path:["length"],value:n}),n++)}x([...F,...e],[...N,...t])}),(e=>{var t,n;return null==(n=null==(t=(0,s.getContentModel)(e))?void 0:t.getEditPoints)?void 0:n.call(t,e,h)}),{scale:te.scale,readOnly:!!M}),ue=oe();if(F.push(...null!=(n=null==ue?void 0:ue.patches)?n:[]),N.push(...null!=(r=null==ue?void 0:ue.reversePatches)?r:[]),z.push(...null!=(c=null==ue?void 0:ue.assistentContents)?c:[]),ue&&z.push(...(0,s.updateReferencedContents)(ue.content,ue.result,h)),void 0!==A){const e=h[A];if(e){U.push({content:e,path:[A]});const t=re&&(0,a.isSamePath)(re.path,[A])?null==ue?void 0:ue.result:null==ue?void 0:ue.relatedEditPointResults.get(e);z.push(...ce(null!=t?t:e,(e=>({type:"circle",x:e.x,y:e.y,radius:7}))));const n=e=>{const[,...t]=(0,i.produceWithPatches)(h,(t=>{const n=t[A];n&&e(n,t)}));x(...t)},r=null==(u=null==(l=(0,s.getContentModel)(e))?void 0:l.propertyPanel)?void 0:u.call(l,e,n,h);let c;if((0,s.isJunctionContent)(e)){const e=W[A];void 0!==e&&(c=o().createElement("div",null,e,"V"))}V=o().createElement("div",{style:{position:"absolute",right:"0px",top:"0px",bottom:"0px",width:"300px",overflowY:"auto",background:"white",zIndex:11}},e.type,o().createElement("div",null,A),c,r&&o().createElement(a.ObjectEditor,{properties:r}))}}const pe=null!=se?se:ee,de=e=>{for(let t=0;t{const t=90*Math.round(e/90);if(t!==e&&Math.abs(t-e)<5)return t})),(0,a.isSameNumber)(pe.x,e.x)){for(const t of h)if(t&&(0,s.isJunctionContent)(t)&&(0,a.getTwoNumbersDistance)(e.y,t.position.y)<=5){const n={type:"line",point:{x:e.x,y:t.position.y},start:t.position};return D(n),n}}else if((0,a.isSameNumber)(pe.y,e.y))for(const t of h)if(t&&(0,s.isJunctionContent)(t)&&(0,a.getTwoNumbersDistance)(e.x,t.position.x)<=5){const n={type:"line",point:{x:t.position.x,y:e.y},start:t.position};return D(n),n}return D(void 0),{point:e}};"point"===(null==O?void 0:O.type)&&z.push({type:"circle",x:O.point.x,y:O.point.y,radius:7}),"line"===(null==O?void 0:O.type)&&z.push({type:"line",p1:O.start,p2:O.point});const fe=e=>{j(e),Q(),I(e)},ge=(0,a.useEvent)((e=>{const t={x:e.clientX,y:e.clientY},n=(0,a.reverseTransformPosition)(t,te),r=de(n);M?(void 0===K?X.current=r.id:Y.current=r.id,Z(r.point)):re?ae(r.point):q?q.act((e=>{const[,...t]=(0,i.produceWithPatches)(h,(t=>{const n=t[q.index];n&&e(n,t)}));x(...t)})):void 0!==R&&(L(R),T(void 0))})),he=(0,a.useEvent)((e=>{const t={x:e.clientX,y:e.clientY},n=(0,a.reverseTransformPosition)(t,te),r=de(n);M?J(r.point,t):(ie(r.point,U),T((e=>{var t,n;for(let t=0;t{var t,n;for(let r=0;r{G&&(fe(G),e.preventDefault())}));let ye;return(0,a.useGlobalKeyDown)((e=>{"Escape"===e.key?(ne(),Q(!0),le()):(0,a.metaKeyIfMacElseCtrlKey)(e)&&(e.shiftKey?"KeyZ"===e.code&&v(e):"KeyZ"===e.code?y(e):"Backspace"===e.code&&(void 0===R||(0,s.contentIsReferenced)(R,h)?void 0===A||(0,s.contentIsReferenced)(A,h)||(m((e=>{e[A]=void 0})),L(void 0)):(m((e=>{e[R]=void 0})),T(void 0))))})),o().useImperativeHandle(t,(()=>({handlePatchesEvent(e){try{b(e.patches,e.reversePatches,e.operator)}catch(e){console.error(e)}}})),[b]),o().useEffect((()=>{const e=[];h.forEach(((t,n)=>{var r,o;if(t)if((0,s.isJunctionContent)(t)){const r=[],o=[];h.forEach(((e,t)=>{e&&(0,s.isDeviceContent)(e)&&(e.start===n?r.push(`I${t}`):e.end===n&&o.push(`I${t}`))})),r.length+o.length>0&&e.push({left:r.join(" + ")||"0",right:o.join(" + ")||"0"}),t.ground&&e.push({left:`U${n}`,right:"0"})}else if((0,s.isDeviceContent)(t)&&"number"==typeof t.start&&"number"==typeof t.end){const i=null==(o=null==(r=(0,s.getContentModel)(t))?void 0:r.getEquationData)?void 0:o.call(r,t,n);i&&e.push(i)}}));const t=e.map((e=>({left:(0,d.parseExpression)((0,d.tokenizeExpression)(e.left)),right:(0,d.parseExpression)((0,d.tokenizeExpression)(e.right))}))),n=[];for(const[e,r]of Object.entries((0,a.solveEquations)(t)[0]))Array.isArray(r)||"NumericLiteral"!==r.type||(n[+e.slice(1)]=r.value);H(n)}),[h]),re?ye=re.cursor:(void 0!==R&&R!==A||q)&&(ye="pointer"),o().createElement(o().Fragment,null,o().createElement("div",{ref:(0,a.bindMultipleRefs)(P,S)},o().createElement("div",{style:{cursor:ye,position:"absolute",inset:"0px"},onMouseMove:he},o().createElement(p.Renderer,{contents:h,x:te.x,y:te.y,scale:te.scale,width:f,height:g,assistentContents:z,hovering:R,selected:A,previewPatches:F,equationResult:W,onClick:ge,onContextMenu:me}))),o().createElement("div",{style:{position:"relative"}},Object.values(s.modelCenter).filter((e=>e.createPreview)).map((e=>{if(e.icon){const t=o().cloneElement(e.icon,{onClick:()=>fe(e.type),style:{width:"20px",height:"20px",margin:"5px",cursor:"pointer",color:M===e.type?"red":void 0}});return o().createElement("span",{title:e.type,key:e.type},t)}return null})),o().createElement("span",{title:"compress"},o().createElement("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 100 100",style:{width:"20px",height:"20px",margin:"5px",cursor:"pointer"},onClick:()=>{m((e=>{var t,n;const r=[];let o=0;const i=[];e.forEach(((e,t)=>{e?(r.push(o),o++):(r.push(void 0),i.unshift(t))})),i.forEach((t=>{e.splice(t,1)}));for(const o of e)o&&(null==(n=null==(t=(0,s.getContentModel)(o))?void 0:t.updateRefId)||n.call(t,o,(e=>"number"==typeof e?r[e]:void 0)));s.contentIndexCache.clear()}))}},o().createElement("rect",{x:"10",y:"44",width:"81",height:"20",strokeWidth:"0",strokeMiterlimit:"10",strokeLinejoin:"miter",strokeLinecap:"butt",fill:"currentColor",stroke:"currentColor"}),o().createElement("rect",{x:"9",y:"69",width:"81",height:"20",strokeWidth:"0",strokeMiterlimit:"10",strokeLinejoin:"miter",strokeLinecap:"butt",fill:"currentColor",stroke:"currentColor"}),o().createElement("polygon",{points:"42,6 57,6 57,31 73,31 51,44 27,32 42,32",strokeWidth:"0",strokeMiterlimit:"10",strokeLinejoin:"miter",strokeLinecap:"butt",fill:"currentColor",stroke:"currentColor"})))),V)}))},7883:(e,t,n)=>{"use strict";n.d(t,{contentIndexCache:()=>g,contentIsReferenced:()=>x,deviceGeometryCache:()=>p,deviceModel:()=>s,getContentModel:()=>v,getDeviceText:()=>b,getReference:()=>f,isDeviceContent:()=>u,isJunctionContent:()=>c,modelCenter:()=>m,registerModel:()=>y,updateReferencedContents:()=>h});var r=n(8662),o=n(3696),i=n.n(o),a=n(9758);const s={isDevice:!0,getRefIds(e){const t=[];return"number"==typeof e.start&&t.push(e.start),"number"==typeof e.end&&t.push(e.end),t},updateRefId(e,t){const n=t(e.start);void 0!==n&&(e.start=n);const r=t(e.end);void 0!==r&&(e.end=r)},getEditPoints:(e,t)=>d.get(e,(()=>{const n=[],r=f(e.start,t,c);r&&n.push({field:"start",content:r});const o=f(e.end,t,c);return o&&n.push({field:"end",content:o}),{editPoints:n.map((({field:e,content:n})=>({x:n.position.x,y:n.position.y,cursor:"move",update(r,{cursor:o}){if(!u(r))return;const i=t.findIndex((e=>e&&c(e)&&(0,a.isSamePoint)(e.position,o)));return r[e]=i>=0?i:{type:"junction",position:{x:o.x,y:o.y}},{assistentContents:[{type:"line",p1:n.position,p2:o}]}}})))}}))};function c(e){return"junction"===e.type}const l={type:"junction",render(e,{target:t,transformStrokeWidth:n}){const r=n(3),o=[t.renderCircle(e.position.x,e.position.y,r,{fillColor:0})];return e.ground&&o.push(t.renderPolyline([{x:e.position.x,y:e.position.y+20},{x:e.position.x,y:e.position.y}]),t.renderPolyline([{x:e.position.x-12,y:e.position.y+20},{x:e.position.x+12,y:e.position.y+20}]),t.renderPolyline([{x:e.position.x-8,y:e.position.y+23},{x:e.position.x+8,y:e.position.y+23}]),t.renderPolyline([{x:e.position.x-4,y:e.position.y+26},{x:e.position.x+4,y:e.position.y+26}])),t.renderGroup(o)},getEditPoints:e=>d.get(e,(()=>({editPoints:[{x:e.position.x,y:e.position.y,cursor:"move",update(t,{cursor:n}){if(c(t))return t.position.x=n.x,t.position.y=n.y,{assistentContents:[{type:"line",p1:e.position,p2:n}]}}}]}))),propertyPanel(e,t){var n;return{ground:i().createElement(a.BooleanEditor,{value:null!=(n=e.ground)&&n,setValue:e=>t((t=>{c(t)&&(t.ground=!!e||void 0)}))})}}};function u(e){var t;return!!(null==(t=v(e))?void 0:t.isDevice)}const p=new a.WeakmapCache3,d=new a.WeakmapCache;function f(e,t,n){if("number"!=typeof e)return n(e)?e:void 0;const r=t[e];return r&&n(r)?r:void 0}const g=new a.WeakmapCache;function h(e,t,n){var o,i;const a=[];if(!c(t))return a;const s=function(e,t){return g.get(e,(()=>t.findIndex((t=>e===t))))}(e,n);for(const e of n){if(!e)continue;const n=v(e);(null==(i=null==(o=null==n?void 0:n.getRefIds)?void 0:o.call(n,e))?void 0:i.includes(s))&&a.push((0,r.produce)(e,(e=>{var r;null==(r=n.updateRefId)||r.call(n,e,(e=>{if(e===s)return t}))})))}return a}const m={};function y(e){m[e.type]=e}function v(e){return m[e.type]}function x(e,t){var n,r,o;for(const i of t)if(i&&(null==(o=null==(r=null==(n=v(i))?void 0:n.getRefIds)?void 0:r.call(n,i))?void 0:o.includes(e)))return!0;return!1}function b(e,t,n,r,o="A"){const i=Math.abs((0,a.getTwoPointsRadian)(e.right,e.left))/Math.PI;let s,c,l=e.center.x,u=e.center.y,p=e.center.x,d=e.center.y;i>1/4&&i<3/4?(l+=10,p-=10,s="left",c="right"):(u-=15,d+=15,s="center",c="center");const f=[];if(n&&f.push(t.renderText(l,u,n,0,16,"monospace",{textAlign:s,textBaseline:"middle"})),void 0!==r){const n=(0,a.isZero)(r)?0:+Math.abs(r).toPrecision(3);if(f.push(t.renderText(p,d,n+o,0,16,"monospace",{textAlign:c,textBaseline:"middle"})),!(0,a.isZero)(r)&&"A"===o){const n=r>0?e.right:e.left,o=(0,a.getPointByLengthAndDirection)(e.center,12,n),i=(0,a.getPointByLengthAndDirection)(e.center,20,n);f.push(t.renderPolyline([(0,a.rotatePositionByCenter)(o,i,30),i,(0,a.rotatePositionByCenter)(o,i,-30)]))}}return f}y(l),y({type:"circle",render:(e,{target:t})=>t.renderCircle(e.x,e.y,e.radius)}),y({type:"line",render:(e,{target:t})=>t.renderPolyline([e.p1,e.p2],{dashArray:[4]})})},3649:(e,t,n)=>{"use strict";n.d(t,{capacitorModel:()=>g});var r=n(3696),o=n.n(r),i=n(9758),a=n(7883),s=Object.defineProperty,c=Object.defineProperties,l=Object.getOwnPropertyDescriptors,u=Object.getOwnPropertySymbols,p=Object.prototype.hasOwnProperty,d=Object.prototype.propertyIsEnumerable,f=(e,t,n)=>t in e?s(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n;const g=c(((e,t)=>{for(var n in t||(t={}))p.call(t,n)&&f(e,n,t[n]);if(u)for(var n of u(t))d.call(t,n)&&f(e,n,t[n]);return e})({type:"capacitor"},a.deviceModel),l({render(e,{target:t,transformStrokeWidth:n,contents:r,value:o,equationResult:i}){const s=n(1),{lines:c,data:l}=h(e,r),u=c.map((e=>t.renderPolyline(e,{strokeWidth:s})));if(l){if(i&&"number"==typeof e.start&&"number"==typeof e.end){const t=i[e.start],n=i[e.end];void 0!==t&&void 0!==n&&(o=(n-t)*e.value)}u.push(...(0,a.getDeviceText)(l,t,e.value+"F",o,"C"))}return t.renderGroup(u)},createPreview:e=>({type:"capacitor",start:e.start,end:e.end,value:1}),getGeometries:h,icon:o().createElement("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 100 100"},o().createElement("polyline",{points:"9,48 37,48",strokeWidth:"5",strokeMiterlimit:"10",strokeLinejoin:"miter",strokeLinecap:"butt",fill:"none",stroke:"currentColor"}),o().createElement("polyline",{points:"36,75 36,22",strokeWidth:"5",strokeMiterlimit:"10",strokeLinejoin:"miter",strokeLinecap:"butt",fill:"none",stroke:"currentColor"}),o().createElement("polyline",{points:"96,48 64,48",strokeWidth:"5",strokeMiterlimit:"10",strokeLinejoin:"miter",strokeLinecap:"butt",fill:"none",stroke:"currentColor"}),o().createElement("polyline",{points:"64,75 64,22",strokeWidth:"5",strokeMiterlimit:"10",strokeLinejoin:"miter",strokeLinecap:"butt",fill:"none",stroke:"currentColor"})),propertyPanel:(e,t)=>({value:o().createElement(i.NumberEditor,{value:e.value,setValue:e=>t((t=>{(function(e){return"capacitor"===e.type})(t)&&(t.value=e)}))})}),getEquationData:(e,t)=>({left:`I${t}`,right:"0"})}));function h(e,t){const n=(0,a.getReference)(e.start,t,a.isJunctionContent),r=(0,a.getReference)(e.end,t,a.isJunctionContent);return n&&r?a.deviceGeometryCache.get(e,n,r,(()=>{const e=(0,i.getTwoPointCenter)(n.position,r.position),t=(0,i.getPointByLengthAndDirection)(e,3,n.position),o=(0,i.getPointByLengthAndDirection)(e,3,r.position),a=(0,i.getTwoPointsRadian)(n.position,r.position)+Math.PI/2,s=[[n.position,t],[r.position,o],[(0,i.getPointByLengthAndRadian)(t,8,a),(0,i.getPointByLengthAndRadian)(t,-8,a)],[(0,i.getPointByLengthAndRadian)(o,8,a),(0,i.getPointByLengthAndRadian)(o,-8,a)]];return{data:{center:e,left:n.position,right:r.position},lines:s}})):{lines:[]}}},4942:(e,t,n)=>{"use strict";n.d(t,{powerModel:()=>h});var r=n(3696),o=n.n(r),i=n(9758),a=n(7883),s=Object.defineProperty,c=Object.defineProperties,l=Object.getOwnPropertyDescriptors,u=Object.getOwnPropertySymbols,p=Object.prototype.hasOwnProperty,d=Object.prototype.propertyIsEnumerable,f=(e,t,n)=>t in e?s(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n;function g(e){return"power"===e.type}const h=(m=((e,t)=>{for(var n in t||(t={}))p.call(t,n)&&f(e,n,t[n]);if(u)for(var n of u(t))d.call(t,n)&&f(e,n,t[n]);return e})({type:"power"},a.deviceModel),y={render(e,{target:t,transformStrokeWidth:n,contents:r,value:o}){const i=n(1),{lines:s,data:c}=v(e,r),l=s.map((e=>t.renderPolyline(e,{strokeWidth:i})));return c&&l.push(...(0,a.getDeviceText)(c,t,e.value+"V",o)),t.renderGroup(l)},createPreview:e=>({type:"power",start:e.start,end:e.end,value:1}),getGeometries:v,icon:o().createElement("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 100 100"},o().createElement("polyline",{points:"9,48 37,48",strokeWidth:"5",strokeMiterlimit:"10",strokeLinejoin:"miter",strokeLinecap:"butt",fill:"none",stroke:"currentColor"}),o().createElement("polyline",{points:"36,66 36,32",strokeWidth:"5",strokeMiterlimit:"10",strokeLinejoin:"miter",strokeLinecap:"butt",fill:"none",stroke:"currentColor"}),o().createElement("polyline",{points:"96,48 64,48",strokeWidth:"5",strokeMiterlimit:"10",strokeLinejoin:"miter",strokeLinecap:"butt",fill:"none",stroke:"currentColor"}),o().createElement("polyline",{points:"64,75 64,22",strokeWidth:"5",strokeMiterlimit:"10",strokeLinejoin:"miter",strokeLinecap:"butt",fill:"none",stroke:"currentColor"})),propertyPanel:(e,t)=>({value:o().createElement(i.NumberEditor,{value:e.value,setValue:e=>t((t=>{g(t)&&(t.value=e)}))}),direction:o().createElement(i.Button,{onClick:()=>t((e=>{if(g(e)){const t=e.end;e.end=e.start,e.start=t}}))},"switch")}),getEquationData:e=>({left:`U${e.start} + ${e.value}`,right:`U${e.end}`})},c(m,l(y)));var m,y;function v(e,t){const n=(0,a.getReference)(e.start,t,a.isJunctionContent),r=(0,a.getReference)(e.end,t,a.isJunctionContent);return n&&r?a.deviceGeometryCache.get(e,n,r,(()=>{const e=(0,i.getTwoPointCenter)(n.position,r.position),t=(0,i.getPointByLengthAndDirection)(e,3,n.position),o=(0,i.getPointByLengthAndDirection)(e,3,r.position),a=(0,i.getTwoPointsRadian)(n.position,r.position)+Math.PI/2,s=[[n.position,t],[r.position,o],[(0,i.getPointByLengthAndRadian)(t,4,a),(0,i.getPointByLengthAndRadian)(t,-4,a)],[(0,i.getPointByLengthAndRadian)(o,8,a),(0,i.getPointByLengthAndRadian)(o,-8,a)]];return{data:{center:e,left:n.position,right:r.position},lines:s}})):{lines:[]}}},5918:(e,t,n)=>{"use strict";n.d(t,{resistanceModel:()=>g});var r=n(3696),o=n.n(r),i=n(9758),a=n(7883),s=Object.defineProperty,c=Object.defineProperties,l=Object.getOwnPropertyDescriptors,u=Object.getOwnPropertySymbols,p=Object.prototype.hasOwnProperty,d=Object.prototype.propertyIsEnumerable,f=(e,t,n)=>t in e?s(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n;const g=c(((e,t)=>{for(var n in t||(t={}))p.call(t,n)&&f(e,n,t[n]);if(u)for(var n of u(t))d.call(t,n)&&f(e,n,t[n]);return e})({type:"resistance"},a.deviceModel),l({render(e,{target:t,transformStrokeWidth:n,contents:r,value:o}){const i=n(1),{lines:s,data:c}=h(e,r),l=s.map((e=>t.renderPolyline(e,{strokeWidth:i})));return c&&l.push(...(0,a.getDeviceText)(c,t,e.value+"Ω",o)),t.renderGroup(l)},createPreview:e=>({type:"resistance",start:e.start,end:e.end,value:1}),getGeometries:h,icon:o().createElement("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 100 100"},o().createElement("rect",{x:"15",y:"35",width:"71",height:"24",strokeWidth:"5",strokeMiterlimit:"10",strokeLinejoin:"miter",strokeLinecap:"butt",fill:"none",stroke:"currentColor"}),o().createElement("polyline",{points:"85,45 99,45",strokeWidth:"5",strokeMiterlimit:"10",strokeLinejoin:"miter",strokeLinecap:"butt",fill:"none",stroke:"currentColor"}),o().createElement("polyline",{points:"13,44 0,44",strokeWidth:"5",strokeMiterlimit:"10",strokeLinejoin:"miter",strokeLinecap:"butt",fill:"none",stroke:"currentColor"})),propertyPanel:(e,t)=>({value:o().createElement(i.NumberEditor,{value:e.value,setValue:e=>t((t=>{(function(e){return"resistance"===e.type})(t)&&(t.value=e)}))})}),getEquationData:(e,t)=>({left:`U${e.start} - ${e.value} * I${t}`,right:`U${e.end}`})}));function h(e,t){const n=(0,a.getReference)(e.start,t,a.isJunctionContent),r=(0,a.getReference)(e.end,t,a.isJunctionContent);return n&&r?a.deviceGeometryCache.get(e,n,r,(()=>{const e=(0,i.getTwoPointCenter)(n.position,r.position),t=(0,i.getPointByLengthAndDirection)(e,8,n.position),o=(0,i.getPointByLengthAndDirection)(e,8,r.position),a=(0,i.getTwoPointsRadian)(n.position,r.position)+Math.PI/2,s=[[n.position,t],[r.position,o],...(0,i.iteratePolygonLines)([(0,i.getPointByLengthAndRadian)(t,4,a),(0,i.getPointByLengthAndRadian)(t,-4,a),(0,i.getPointByLengthAndRadian)(o,-4,a),(0,i.getPointByLengthAndRadian)(o,4,a)])];return{data:{center:e,left:n.position,right:r.position},lines:s}})):{lines:[]}}},7305:(e,t,n)=>{"use strict";n.d(t,{switchModel:()=>h});var r=n(3696),o=n.n(r),i=n(9758),a=n(7883),s=Object.defineProperty,c=Object.defineProperties,l=Object.getOwnPropertyDescriptors,u=Object.getOwnPropertySymbols,p=Object.prototype.hasOwnProperty,d=Object.prototype.propertyIsEnumerable,f=(e,t,n)=>t in e?s(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n;function g(e){return"switch"===e.type}const h=c(((e,t)=>{for(var n in t||(t={}))p.call(t,n)&&f(e,n,t[n]);if(u)for(var n of u(t))d.call(t,n)&&f(e,n,t[n]);return e})({type:"switch"},a.deviceModel),l({render(e,{target:t,transformStrokeWidth:n,contents:r,value:o}){const i=n(1),{lines:s,data:c}=m(e,r),l=s.map((e=>t.renderPolyline(e,{strokeWidth:i})));return c&&l.push(...(0,a.getDeviceText)(c,t,void 0,o)),t.renderGroup(l)},createPreview:e=>({type:"switch",start:e.start,end:e.end,on:!1}),getGeometries:m,icon:o().createElement("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 100 100"},o().createElement("polyline",{points:"1,46 34,46",strokeWidth:"5",strokeMiterlimit:"10",strokeLinejoin:"miter",strokeLinecap:"butt",fill:"none",stroke:"currentColor"}),o().createElement("circle",{cx:"39",cy:"47",r:"7",strokeWidth:"5",strokeMiterlimit:"10",strokeLinejoin:"miter",strokeLinecap:"butt",fill:"none",stroke:"currentColor"}),o().createElement("polyline",{points:"43,41 71,27",strokeWidth:"5",strokeMiterlimit:"10",strokeLinejoin:"miter",strokeLinecap:"butt",fill:"none",stroke:"currentColor"}),o().createElement("polyline",{points:"69,47 100,47",strokeWidth:"5",strokeMiterlimit:"10",strokeLinejoin:"miter",strokeLinecap:"butt",fill:"none",stroke:"currentColor"})),propertyPanel:(e,t)=>({on:o().createElement(i.BooleanEditor,{value:e.on,setValue:e=>t((t=>{g(t)&&(t.on=e)}))})}),getEquationData:(e,t)=>e.on?{left:`U${e.start}`,right:`U${e.end}`}:{left:`I${t}`,right:"0"},getAction(e,t,n){const{data:r}=m(t,n);if(r&&(0,i.getTwoPointsDistance)(r.center,e)<16)return e=>{e((e=>{g(e)&&(e.on=!e.on)}))}}}));function m(e,t){const n=(0,a.getReference)(e.start,t,a.isJunctionContent),r=(0,a.getReference)(e.end,t,a.isJunctionContent);return n&&r?a.deviceGeometryCache.get(e,n,r,(()=>{const t=(0,i.getTwoPointCenter)(n.position,r.position),o=(0,i.getPointByLengthAndDirection)(t,8,n.position),a=[[n.position,(0,i.getPointByLengthAndDirection)(o,3,n.position)],...(0,i.iteratePolylineLines)((0,i.arcToPolyline)((0,i.circleToArc)({x:o.x,y:o.y,r:3}),5))];if(e.on)a.push([(0,i.getPointByLengthAndDirection)(o,3,r.position),r.position]);else{const e=(0,i.getPointByLengthAndDirection)(t,8,r.position),n=(0,i.rotatePositionByCenter)(e,o,30);a.push([(0,i.getPointByLengthAndDirection)(o,3,n),n],[e,r.position])}return{lines:a,data:{center:t,left:n.position,right:r.position}}})):{lines:[]}}},66:(e,t,n)=>{"use strict";n.d(t,{wireModel:()=>g});var r=n(3696),o=n.n(r),i=n(9758),a=n(7883),s=Object.defineProperty,c=Object.defineProperties,l=Object.getOwnPropertyDescriptors,u=Object.getOwnPropertySymbols,p=Object.prototype.hasOwnProperty,d=Object.prototype.propertyIsEnumerable,f=(e,t,n)=>t in e?s(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n;const g=c(((e,t)=>{for(var n in t||(t={}))p.call(t,n)&&f(e,n,t[n]);if(u)for(var n of u(t))d.call(t,n)&&f(e,n,t[n]);return e})({type:"wire"},a.deviceModel),l({render(e,{target:t,transformStrokeWidth:n,contents:r,value:o}){const i=n(1),{lines:s,data:c}=h(e,r),l=s.map((e=>t.renderPolyline(e,{strokeWidth:i})));return c&&l.push(...(0,a.getDeviceText)(c,t,void 0,o)),t.renderGroup(l)},createPreview:e=>({type:"wire",start:e.start,end:e.end}),getGeometries:h,icon:o().createElement("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 100 100"},o().createElement("polyline",{points:"1,46 100,46",strokeWidth:"5",strokeMiterlimit:"10",strokeLinejoin:"miter",strokeLinecap:"butt",fill:"none",stroke:"currentColor"})),getEquationData:e=>({left:`U${e.start}`,right:`U${e.end}`})}));function h(e,t){const n=(0,a.getReference)(e.start,t,a.isJunctionContent),r=(0,a.getReference)(e.end,t,a.isJunctionContent);return n&&r?a.deviceGeometryCache.get(e,n,r,(()=>{const e=(0,i.getTwoPointCenter)(n.position,r.position);return{lines:[[n.position,r.position]],data:{center:e,left:n.position,right:r.position}}})):{lines:[]}}},4607:(e,t,n)=>{"use strict";n.d(t,{Renderer:()=>d});var r=n(8662),o=n(9758),i=n(7883),a=Object.defineProperty,s=Object.getOwnPropertySymbols,c=Object.prototype.hasOwnProperty,l=Object.prototype.propertyIsEnumerable,u=(e,t,n)=>t in e?a(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,p=(e,t)=>{for(var n in t||(t={}))c.call(t,n)&&u(e,n,t[n]);if(s)for(var n of s(t))l.call(t,n)&&u(e,n,t[n]);return e};function d(e){var t,n;const a=o.reactSvgRenderTarget,s=[],c=e.previewPatches.length>0?(0,r.applyPatches)(e.contents,e.previewPatches):e.contents;for(let n=0;ne.hovering===n||e.selected===n?t+1:t,contents:c,value:e.equationResult[n],equationResult:e.equationResult}))}}for(const t of e.assistentContents){if(!t)continue;const e=null==(n=(0,i.getContentModel)(t))?void 0:n.render;e&&s.push(e(t,{target:a,transformStrokeWidth:e=>e,contents:c}))}return a.renderResult(s,e.width,e.height,{attributes:{style:p({position:"absolute",boxSizing:"border-box"},e.style),onClick:e.onClick,onMouseDown:e.onMouseDown,onContextMenu:e.onContextMenu},transform:{x:e.x,y:e.y,scale:e.scale}})}},9277:(e,t,n)=>{"use strict";n.d(t,{Combination2:()=>u});var r=n(3696),o=n.n(r),i=n(9758),a=n(7449),s=n(1406),c=Math.pow;const l=Math.round(15*Math.random()*c(16,3)+c(16,3)).toString(16);function u(){const[e,t]=o().useState(),{pluginLoaded:n,pluginCommandTypes:r}=(0,s.usePlugins)(),[c,u]=(0,i.useLocalStorageState)("composable-editor-canvas-combination2:panel",!0),[p,d]=(0,i.useLocalStorageState)("composable-editor-canvas-combination2:print-mode",!1),[f,g]=(0,i.useLocalStorageState)("composable-editor-canvas-combination2:performance-mode",!1),h=(0,s.useInitialStateValidated)(e,n);o().useEffect((()=>{t([])}),[]);const m=o().useRef(null),[y,v]=o().useState(!1),[x,b]=(0,i.useLocalStorageState)("composable-editor-canvas-combination2:snaps",i.allSnapTypes),[C,E]=(0,i.useLocalStorageState)("composable-editor-canvas-combination2:render-target",void 0),[P,w]=o().useState(!1),[k,_]=o().useState(!1),[S,R]=o().useState(),[T,A]=(0,i.useLocalStorageState)("composable-editor-canvas-combination2:input-fixed",!1),[L,M]=(0,i.useLocalStorageState)("composable-editor-canvas-combination2:background-color",16777215),[I,O]=(0,i.useLocalStorageState)("composable-editor-canvas-combination2:debug",!1);return o().createElement("div",{style:{height:"100%"}},e&&n&&h&&o().createElement(s.CADEditor,{ref:m,id:"combination2",operator:l,initialState:e,readOnly:y,snapTypes:x,renderTarget:C,setCanUndo:w,setCanRedo:_,setOperation:R,inputFixed:T,backgroundColor:L,debug:I,panelVisible:c,printMode:p,performanceMode:f}),o().createElement("div",{style:{position:"fixed",width:"100%"}},!y&&r.map((e=>{if(e.icon){const t=o().cloneElement(e.icon,{onClick:()=>{var t;return null==(t=m.current)?void 0:t.startOperation({type:"command",name:e.name})},key:e.name,style:{width:"20px",height:"20px",margin:"5px",cursor:"pointer",color:S===e.name?"red":void 0}});return o().createElement("span",{title:e.name,key:e.name},t)}return null})),["move canvas","zoom window"].map((e=>o().createElement("button",{onClick:()=>{var t;return null==(t=m.current)?void 0:t.startOperation({type:"non command",name:e})},key:e,style:{position:"relative",top:"-10px",borderColor:S===e?"red":void 0}},e))),o().createElement("button",{onClick:()=>(t(void 0),void setTimeout((()=>{const e=[];for(let t=0;t<200;t++)for(let n=0;n<200;n++){const r=Math.random();if(r<.05)e.push({type:"circle",x:100*t+50*(Math.random()-.5),y:100*n+50*(Math.random()-.5),r:80*Math.random()+20});else if(r<.1)e.push({type:"rect",x:100*t+50*(Math.random()-.5),y:100*n+50*(Math.random()-.5),width:80*Math.random()+20,height:20*Math.random()+80,angle:360*Math.random()-180});else if(r<.15)e.push({type:"ellipse",cx:100*t+50*(Math.random()-.5),cy:100*n+50*(Math.random()-.5),rx:80*Math.random()+20,ry:20*Math.random()+80,angle:360*Math.random()-180});else if(r<.2)e.push({type:"regular polygon",x:100*t+50*(Math.random()-.5),y:100*n+50*(Math.random()-.5),radius:80*Math.random()+20,count:[3,5,6,8][Math.floor(4*Math.random())],angle:360*Math.random()-180});else if(r<.25){const r=80*Math.random()+20;e.push({type:"star",x:100*t+50*(Math.random()-.5),y:100*n+50*(Math.random()-.5),innerRadius:r*(.4*Math.random()+.3),outerRadius:r,count:[5,6,8][Math.floor(3*Math.random())],angle:360*Math.random()-180})}}t(e)}),0)),style:{position:"relative",top:"-10px"}},"add mock data"),!y&&o().createElement("button",{disabled:!P,onClick:()=>{var e;return null==(e=m.current)?void 0:e.undo()},style:{position:"relative",top:"-10px"}},"undo"),!y&&o().createElement("button",{disabled:!k,onClick:()=>{var e;return null==(e=m.current)?void 0:e.redo()},style:{position:"relative",top:"-10px"}},"redo"),!y&&o().createElement("label",null,o().createElement("input",{type:"checkbox",checked:c,onChange:()=>u(!c)}),"panel"),o().createElement("label",null,o().createElement("input",{type:"checkbox",checked:p,onChange:()=>d(!p)}),"print mode"),o().createElement("label",null,o().createElement("input",{type:"checkbox",checked:f,onChange:()=>g(!f)}),"performance mode"),o().createElement("label",null,o().createElement("input",{type:"checkbox",checked:I,onChange:()=>O(!I)}),"debug"),o().createElement("select",{value:C,onChange:e=>E(e.target.value),style:{position:"relative"}},(0,a.getAllRendererTypes)().map((e=>o().createElement("option",{key:e,value:e},e)))),!y&&i.allSnapTypes.map((e=>o().createElement("label",{key:e,style:{position:"relative"}},o().createElement("input",{type:"checkbox",checked:x.includes(e),onChange:t=>b(t.target.checked?[...x,e]:x.filter((t=>t!==e)))}),e))),o().createElement("label",{style:{position:"relative"}},o().createElement("input",{type:"checkbox",checked:y,onChange:e=>v(e.target.checked)}),"read only"),!y&&o().createElement("label",{style:{position:"relative"}},o().createElement("input",{type:"checkbox",checked:T,onChange:e=>A(e.target.checked)}),"input fixed"),o().createElement("input",{type:"color",style:{position:"relative"},value:(0,i.getColorString)(L),onChange:e=>M((0,i.colorStringToNumber)(e.target.value))})))}},9456:(e,t,n)=>{"use strict";n.d(t,{Combination3:()=>y});var r=n(3696),o=n.n(r),i=n(8214),a=n(5011),s=n(395),c=n(7310),l=n(2693),u=n(726),p=n(4430),d=n(3685),f=n(8749),g=n(6286),h=Math.pow;const m=Math.round(15*Math.random()*h(16,3)+h(16,3)).toString(16);function y(){const[e]=o().useState(g.richTextData),[t,n]=o().useState(!0),[r,h]=o().useState(!1),y=o().useRef({blocks:{h1:a.h1,h2:a.h2,h3:a.h3,h4:a.h4,h5:a.h5,h6:a.h6,p:a.p,ul:a.ul,ol:a.ol,hr:a.hr},styles:{"font size":s.fontSize,"font family":s.fontFamily,bold:s.bold,italic:s.italic,underline:s.underline,"pass through":s.passThrough,color:s.color,"background color":s.backgroundColor},hooks:[c.useAt,l.useLink,u.useImage,d.useCircle,f.useStack],inlines:[l.link,u.image,d.circle,f.stack],textInlines:{span:p.span,code:p.code,mark:p.mark,sub:p.sub,sup:p.sup}});return e?o().createElement("div",null,o().createElement("div",null,o().createElement("label",null,o().createElement("input",{type:"checkbox",checked:t,onChange:e=>n(e.target.checked)}),"autoHeight"),o().createElement("label",null,o().createElement("input",{type:"checkbox",checked:r,onChange:e=>h(e.target.checked)}),"readOnly")),o().createElement(i.RichTextEditor,{initialState:e,width:500,height:300,autoHeight:t,readOnly:r,operator:m,plugin:y.current})):null}},7511:(e,t,n)=>{"use strict";n.d(t,{Combination4:()=>c});var r=n(3696),o=n.n(r),i=n(3802),a=Math.pow;const s=Math.round(15*Math.random()*a(16,3)+a(16,3)).toString(16);function c(){const[e]=o().useState([]),t=o().useRef(null);return e?o().createElement("div",null,o().createElement(i.CircuitGraphEditor,{operator:s,ref:t,initialState:e})):null}},3714:(e,t,n)=>{"use strict";n.d(t,{Combination5:()=>l});var r=n(3696),o=n.n(r),i=n(2100),a=n(6129),s=Math.pow;const c=Math.round(15*Math.random()*s(16,3)+s(16,3)).toString(16);function l(){const[e]=o().useState(a.astronomicalObjectData),t=o().useRef(null);return o().createElement("div",null,o().createElement(i.AstronomicalObjectSimulator,{operator:c,ref:t,initialState:e}))}},577:(e,t,n)=>{"use strict";n.d(t,{Combination6:()=>y});var r=n(3696),o=n.n(r),i=n(8662),a=n(9758),s=Object.defineProperty,c=Object.defineProperties,l=Object.getOwnPropertyDescriptors,u=Object.getOwnPropertySymbols,p=Object.prototype.hasOwnProperty,d=Object.prototype.propertyIsEnumerable,f=Math.pow,g=(e,t,n)=>t in e?s(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,h=(e,t)=>{for(var n in t||(t={}))p.call(t,n)&&g(e,n,t[n]);if(u)for(var n of u(t))d.call(t,n)&&g(e,n,t[n]);return e},m=(e,t)=>c(e,l(t));function y(){const{width:e,height:t}=(0,a.useWindowSize)(),n=a.reactCanvasRenderTarget,[r,s,c]=(0,a.useRefState)([]),[l,u]=o().useState(),[p,d]=o().useState(!1),[g,y]=o().useState(!1),P=o().useRef(!1),[w,k]=o().useState(),_=[],S={x:e/2,y:t-v},R=o().useRef(new WeakSet);o().useEffect((()=>{let n;const r=o=>{if(void 0!==n){const r=.002*(o-n),l=P.current?x:v,u=[];for(const n of c.current){if(n.x<0||n.y<0||n.x>e||n.y>t)continue;const o=(0,i.produce)(n,(e=>{e.x=n.x+r*n.speed.x;const t=n.speed.y+r*b;e.y=n.y+r*(0,a.getTwoNumberCenter)(t,n.speed.y),e.speed.y=t})),s=u.findIndex((e=>f(e.x-o.x,2)+f(e.y-o.y,2)<=f(l,2)));s>=0?u.splice(s,1):(u.push(o),R.current.has(n)&&(R.current.add(o),R.current.delete(n)))}s(u)}n=o,requestAnimationFrame(r)};requestAnimationFrame(r)}),[]),o().useEffect((()=>{if(!p)return;const t=setInterval((()=>{const t=Math.random();s((0,i.produce)(c.current,(n=>{n.push({type:"drop",x:t*e,y:v,speed:{x:(t>.5?-1:1)*Math.random()*e*.03,y:0}})})))}),1e3);return()=>clearInterval(t)}),[p]),o().useEffect((()=>{if(!g)return;const e=setInterval((()=>{D()}),1e3);return()=>clearInterval(e)}),[g]);const{line:T,cursorPosition:A,onClick:L,reset:M,onMove:I}=(0,a.useLineClickCreate)("drop"===l,(e=>{s((0,i.produce)(r,(t=>{t.push(E(e,v,l))}))),M()}),{once:!0}),O=e=>{M(),u(e)},D=()=>{const e=c.current.find((e=>"drop"===e.type&&!R.current.has(e)));if(!e)return;const t=function(e,t){const n=t.x-e.x,r=t.y-e.y,o=n*e.speed.y-r*e.speed.x,i=f(C,2),s=f(n,2)+f(r,2),c=4*i*f(n,2)-4*f(o,2)+4*i*f(r,2);if((0,a.lessThan)(c,0))return[];const l=-o*r,u=o*n;if((0,a.isZero)(c))return[{x:l/s,y:u/s}];const p=f(c,.5),d=.5*n*p,g=.5*r*p;return[{x:(l+d)/s,y:(u+g)/s},{x:(l-d)/s,y:(u-g)/s}]}(e,S);0!==t.length&&(s((0,i.produce)(c.current,(e=>{for(const n of t)n.y<0&&e.push(m(h({type:"shoot down"},S),{speed:n}))}))),R.current.add(e))};T?_.push(E(T,v,l)):A?_.push(E([A,A],v,l)):w&&_.push(E([S,w],v,l));const B=[];for(const e of[...r,..._]){const t="drop"===e.type?16711680:65280,r=P.current&&"shoot down"===e.type?x:v;if(B.push(n.renderCircle(e.x,e.y,r,{fillColor:t,strokeWidth:0})),e.speed.x||e.speed.y){const r=(0,a.getTwoPointsDistance)(e.speed),o=(0,a.getTwoPointsRadian)(e.speed),i=(0,a.getPointByLengthAndRadian)(e,r+v,o);B.push(n.renderPolyline([e,i],{strokeColor:t}))}}const z=(0,a.useEvent)((e=>{const t={x:e.clientX,y:e.clientY};"drop"===l?L(t):"shoot down"===l&&w&&s((0,i.produce)(r,(e=>{e.push(E([S,w],v,l))})))})),F=(0,a.useEvent)((e=>{const t={x:e.clientX,y:e.clientY};"drop"===l?I(t):"shoot down"===l&&k(t)}));return(0,a.useGlobalKeyDown)((e=>{"Escape"===e.key&&(u(void 0),k(void 0),M(!0))})),o().createElement("div",{style:{position:"absolute",inset:"0px",overflow:"hidden"},onMouseMove:F},n.renderResult(B,e,t,{attributes:{onClick:z}}),o().createElement("div",{style:{position:"absolute",top:"0px"}},o().createElement(a.Button,{style:{color:"drop"===l?"red":void 0},onClick:()=>O("drop")},"drop"),o().createElement("label",{style:{position:"relative"}},o().createElement("input",{type:"checkbox",checked:p,onChange:e=>d(e.target.checked)}),"drop auto")),o().createElement("div",{style:{position:"absolute",bottom:"0px",right:"0px"}},o().createElement(a.Button,{style:{color:"shoot down"===l?"red":void 0},onClick:()=>O("shoot down")},"shoot down"),o().createElement("label",{style:{position:"relative"}},o().createElement("input",{type:"checkbox",checked:P.current,onChange:e=>P.current=e.target.checked}),"detonate"),o().createElement(a.Button,{onClick:()=>D()},"aim auto"),o().createElement("label",{style:{position:"relative"}},o().createElement("input",{type:"checkbox",checked:g,onChange:e=>y(e.target.checked)}),"shoot auto")))}const v=5,x=25,b=9.8,C=200;function E([e,t],n,r){if("drop"===r)e={x:e.x,y:n},t={x:t.x,y:n};else if("shoot down"===r){const n=(0,a.getTwoPointsRadian)(t,e),r=(0,a.multiplyDirection)((0,a.getDirectionByRadian)(n),C);return m(h({type:"shoot down"},e),{speed:r})}const o=(0,a.getTwoPointsDistance)(e,t);let i;if(o>n){const r=(0,a.getPointByLengthAndDirection)(t,o-n,e);i={x:t.x-r.x,y:t.y-r.y}}else i={x:0,y:0};return m(h({type:"drop"},e),{speed:i})}},84:(e,t,n)=>{"use strict";n.d(t,{Combination7:()=>f});var r=n(3696),o=n.n(r),i=n(8662),a=n(9758),s=n(7951),c=n(490),l=n(5527),u=n(3107),p=n(7728),d=n(5722);function f(){const e=a.reactCanvasRenderTarget,{width:t,height:n}=(0,a.useWindowSize)(),[r,f,g]=(0,a.useRefState)(s.initialModels),[h,m,y]=(0,a.useRefState)([]),[v,x]=o().useState([]),[,b,C]=(0,a.useRefState)(0),E=o().useRef();let P;v.length>0&&(P=o().createElement(l.Panel,{target:r[v[0]],status:E,updater:e=>{f((0,i.produce)(r,(t=>{e(t[0])})))}}));const{onStartSelect:w,dragSelectMask:k,resetDragSelect:_}=(0,a.useDragSelect)(((e,t)=>{var n,o;if(t&&Math.abs(e.x-t.x)>10&&Math.abs(e.y-t.y)>10){const n={start:{x:Math.min(e.x,t.x),y:Math.min(e.y,t.y)},end:{x:Math.max(e.x,t.x),y:Math.max(e.y,t.y)}};x(Array.from(r.entries()).filter((([,e])=>(0,a.pointIsInRegion)(e.position,n))).map((([e])=>e)))}else{if(null==(n=E.current)?void 0:n.ability){const t=(0,d.getAbilityFromIndex)(E.current.ability);if(null==(o=null==t?void 0:t.cast)?void 0:o.radius)return f((0,i.produce)(r,(t=>{for(const n of v)t[n].canControl&&E.current&&(t[n].action={type:"attack",ability:E.current.ability,target:e})}))),void(E.current=void 0)}for(const[t,n]of r.entries())if((0,a.getTwoPointsDistance)(n.position,e)<=p.units[n.unit].size){if(E.current){f((0,i.produce)(r,(e=>{for(const n of v)e[n].canControl&&E.current&&(e[n].action={type:"attack",ability:E.current.ability,target:t})}))),E.current=void 0;break}x([t]);break}}}));return(0,a.useGlobalKeyDown)((e=>{"Escape"===e.key?(_(),x([])):"s"===e.key?f((0,i.produce)(r,(e=>{for(const t of v)e[t].canControl&&e[t].action&&(e[t].action=void 0)}))):"a"===e.key&&(E.current={type:"attack"})})),o().useEffect((()=>{const e=t=>{if(0!==C.current){const e=(0,c.updateModels)(.001*(t-C.current),g.current,y.current);e.models&&f(e.models),e.bullets&&m(e.bullets)}b(t),requestAnimationFrame(e)};requestAnimationFrame(e)}),[]),o().createElement(o().Fragment,null,o().createElement("div",{style:{position:"absolute",inset:"0px",overflow:"hidden"},onMouseDown:w,onContextMenu:e=>{f((0,i.produce)(r,(t=>{for(const n of v)t[n].canControl&&(t[n].action={type:"move",to:{x:Math.round(e.clientX),y:Math.round(e.clientY)}})}))),e.preventDefault()}},e.renderResult((0,u.renderModels)(r,h,v),t,n),k),P)}},8977:(e,t,n)=>{"use strict";n.d(t,{abilities:()=>i});var r=n(5722),o=n(1915);const i=[{name:"Laguna Blade",cooldown:70,mana:150,cast:{range:300,bulletSpeed:400,hit:(e,t)=>(0,r.attackPureDamage)(e,t,500)},launch(e,t){t((t=>{a(t,e)}))}},{name:"Firestorm",cooldown:16,mana:110,cast:{range:300,bulletSpeed:400,radius:200,hit:(e,t)=>(0,r.attackPureDamage)(e,t,200)},launch(e,t){t((t=>{a(t,e)}))}}];function a(e,t){const n=i[t];if(void 0!==e.mana){const i=(0,r.getModelResult)(e);i.mana&&(e.mana=Math.min(e.mana-n.mana/i.mana.total,1)),(0,o.updateAbilityCooldown)(e,t,"abilities",n.cooldown)}}},7951:(e,t,n)=>{"use strict";n.d(t,{initialModels:()=>r});const r=[{unit:0,position:{x:200,y:200},facing:0,canControl:!0,health:.4,mana:.5,attackCooldown:0,items:[],abilities:[0,1]},{unit:1,position:{x:300,y:200},facing:0,canControl:!0,health:.8},{unit:2,position:{x:400,y:200},facing:0,canControl:!1,health:1}]},1915:(e,t,n)=>{"use strict";n.d(t,{items:()=>o,updateAbilityCooldown:()=>i});var r=n(5722);const o=[{name:"Icon Branch",strength:1,agility:1,intelligence:1},{name:"Boots of Speed",speed:45},{name:"Vitality Booster",health:250},{name:"Ring of Health",heathRegeneration:4.5},{name:"Platemail",armor:10},{name:"Cloak",magicResistance:.2},{name:"Aether Lens",mana:300,manaRegeneration:2.5},{name:"Monkey King Bar",attackDamage:40,attackSpeed:45},{name:"Arcane Boots",mana:250,speed:45,ability:{name:"Replenish Mana",cooldown:55,mana:0,launch(e,t){t((t=>{if(void 0!==t.mana){const e=(0,r.getModelResult)(t);e.mana&&(t.mana=Math.min(t.mana+175/e.mana.total,1))}const n=o[e];n.ability&&i(t,e,"items",n.ability.cooldown)}))}}},{name:"Dagon",strength:7,agility:7,intelligence:7,ability:{name:"Energy Burst",cooldown:35,mana:120,cast:{range:300,hit:(e,t)=>(0,r.attackMagicDamage)(e,t,400)},launch(e,t){t((t=>{!function(e,t){const n=o[t];if(void 0!==e.mana&&n.ability){const o=(0,r.getModelResult)(e);o.mana&&(e.mana=Math.min(e.mana-n.ability.mana/o.mana.total,1)),i(e,t,"items",n.ability.cooldown)}}(t,e)}))}}}];function i(e,t,n,r){e.abilityCooldowns||(e.abilityCooldowns=[]);const o=e.abilityCooldowns.find((e=>e.index===t));o?o.cooldown=r:e.abilityCooldowns.push({index:t,cooldown:r,source:n})}},5527:(e,t,n)=>{"use strict";n.d(t,{Panel:()=>l});var r=n(3696),o=n.n(r),i=n(9758),a=n(5722),s=n(1915),c=n(8977);function l({target:e,updater:t,status:n}){const[r,l]=o().useState(0),u=(0,a.getModelResult)(e),p={speed:o().createElement(i.Label,null,u.speed,"<-",u.baseSpeed),canControl:o().createElement(i.BooleanEditor,{value:e.canControl,setValue:e=>t((t=>{t.canControl=e}))})};let d;return u.health&&(p.health=o().createElement(i.Label,null,Math.round(u.health.current),"/",Math.round(u.health.total),"<-",Math.round(u.health.base.total)),p.healthRegeneration=o().createElement(i.Label,null,u.health.regeneration,"<-",u.health.base.regeneration),p.armor=o().createElement(i.Label,null,Math.round(u.health.armor),"<-",u.health.base.armor),p.magicResistance=o().createElement(i.Label,null,u.health.magicResistance,"<-",u.health.base.magicResistance)),u.mana&&(d=Math.round(u.mana.current),p.mana=o().createElement(i.Label,null,d,"/",Math.round(u.mana.total),"<-",Math.round(u.mana.base.total)),p.manaRegeneration=o().createElement(i.Label,null,u.mana.regeneration,"<-",u.mana.regeneration)),u.attack&&(p.damage=o().createElement(i.Label,null,Math.round(u.attack.damage),"+-",u.attack.damageRange,"<-",u.attack.base.damage),p.attackSpeed=o().createElement(i.Label,null,u.attack.speed,"<-",u.attack.base.speed),p.attackTime=o().createElement(i.Label,null,Math.round(u.attack.time),"<-",u.attack.base.time),p.bulletSpeed=o().createElement(i.Label,null,u.attack.bulletSpeed),p.attackRange=o().createElement(i.Label,null,u.attack.range,"<-",u.attack.base.range)),u.attributes&&(p.strength=o().createElement(i.Label,null,u.attributes.strength,"<-",u.attributes.base.strength),p.agility=o().createElement(i.Label,null,u.attributes.agility,"<-",u.attributes.base.agility),p.intelligence=o().createElement(i.Label,null,u.attributes.intelligence,"<-",u.attributes.base.intelligence),p.primary=o().createElement(i.Label,null,u.attributes.primary)),o().createElement("div",{style:{position:"absolute",right:"0px",top:"0px",bottom:"0px",width:"400px",overflowY:"auto",background:"white",zIndex:11}},o().createElement("select",{value:r,onChange:e=>l(+e.target.value)},s.items.map(((e,t)=>o().createElement("option",{key:e.name,value:t},e.name)))),e.items&&o().createElement(i.ArrayEditor,{inline:!0,add:()=>t((e=>{e.items&&e.items.push(r)})),remove:e=>t((t=>{t.items&&t.items.splice(e,1)})),items:e.items.map((r=>{var a,c;const l=s.items[r],u=null==(c=null==(a=e.abilityCooldowns)?void 0:a.find((e=>"items"===e.source&&e.index===r)))?void 0:c.cooldown;if(!l.ability)return o().createElement(i.Label,null,s.items[r].name);const p=!!u||void 0===d||d{l.ability&&!p&&(l.ability.cast?n.current={type:"attack",ability:{index:r,source:"items"}}:l.ability.launch(r,t))}},s.items[r].name," ",u?u.toFixed(1):"")}))}),e.abilities&&o().createElement(i.ArrayEditor,{inline:!0,items:e.abilities.map((r=>{var a,s;const l=c.abilities[r],u=null==(s=null==(a=e.abilityCooldowns)?void 0:a.find((e=>"abilities"===e.source&&e.index===r)))?void 0:s.cooldown,p=!!u||void 0===d||d{p||(l.cast?n.current={type:"attack",ability:{index:r,source:"abilities"}}:l.launch(r,t))}},c.abilities[r].name," ",u?u.toFixed(1):"")}))}),o().createElement(i.ObjectEditor,{inline:!0,properties:p}))}},3107:(e,t,n)=>{"use strict";n.d(t,{renderModels:()=>i});var r=n(9758),o=n(7728);function i(e,t,n){const i=r.reactCanvasRenderTarget,a=e.map(((e,t)=>{const a=o.units[e.unit].size,s=n.includes(t)?e.canControl?65280:255:void 0,c=[i.renderCircle(e.position.x,e.position.y,a,{strokeColor:s}),i.renderPolyline([(0,r.getPointByLengthAndRadian)(e.position,a,e.facing),(0,r.getPointByLengthAndRadian)(e.position,2*a,e.facing)],{strokeColor:s})];if(void 0!==e.health){const t=6,n=a,r=e.health;c.push(i.renderRect(e.position.x-n/2,e.position.y-a-t,n,t),i.renderRect(e.position.x-n/2,e.position.y-a-t,r*a,t,{fillColor:65280}))}if(void 0!==e.mana){const t=6,n=-6,r=a,o=e.mana;c.push(i.renderRect(e.position.x-r/2,e.position.y-a-t-n,r,t),i.renderRect(e.position.x-r/2,e.position.y-a-t-n,o*a,t,{fillColor:255}))}return i.renderGroup(c)}));return a.push(...t.map((e=>"instant"===e.type?i.renderEmpty():i.renderCircle(e.position.x,e.position.y,5)))),a}},490:(e,t,n)=>{"use strict";n.d(t,{updateModels:()=>c});var r=n(8662),o=n(9758),i=n(5722),a=n(1915),s=n(7728);function c(e,t,n){var c,l;const u=[...t];let p=!1;const d=[];for(const t of n){const n=u[t.source];let a;if(void 0===t.type){const n=e*t.speed,r=u[t.target];(0,o.getTwoPointsDistance)(t.position,r.position)-s.units[r.unit].size>n&&(a=(0,o.getPointByLengthAndDirection)(t.position,n,r.position))}else if("position"===t.type){const n=e*t.speed;(0,o.getTwoPointsDistance)(t.position,t.target)>n&&(a=(0,o.getPointByLengthAndDirection)(t.position,n,t.target))}if(a){const e=a;d.push((0,r.produce)(t,(t=>{void 0!==t.type&&"position"!==t.type||(t.position=e)})))}else{const e="position"===t.type?(0,i.getModelsAroundPositionByRadiusExcept)(u,t.target,t.radius,t.source):[[t.target,u[t.target]]];for(const[o,a]of e){if(!s.units[a.unit].health)continue;const e=(0,i.getModelResult)(n),c=(0,i.getModelResult)(a);if(t.ability){const e=(0,i.getAbilityFromIndex)(t.ability);if(null==e?void 0:e.cast){const t=e.cast.hit(a,c);t&&(u[o]=t,p=!0)}}else if(e.attack&&c.health){const s=(0,i.getDamageAfterArmor)(e.attack.damage+Math.random()*e.attack.damageRange,c.health.armor),l=Math.max(0,(c.health.current-s)/c.health.total);u[o]=(0,r.produce)(a,(e=>{e.health=l})),0===l&&(u[t.source]=(0,r.produce)(n,(e=>{e.action=void 0}))),p=!0}}}}for(const t of u.keys()){let n=u[t];const f=(0,i.getModelResult)(n);if(void 0!==n.health&&f.health&&f.health.regeneration&&n.health>0&&n.health<1){const o=e*f.health.regeneration,i=f.health.total;u[t]=(0,r.produce)(n,(e=>{e.health&&(e.health=Math.min(e.health+o/i,1))})),p=!0,n=u[t]}if(void 0!==n.mana&&f.mana&&f.mana.regeneration&&n.mana<1){const o=e*f.mana.regeneration,i=f.mana.total;u[t]=(0,r.produce)(n,(e=>{e.mana&&(e.mana=Math.min(e.mana+o/i,1))})),p=!0,n=u[t]}if(n.abilityCooldowns&&n.abilityCooldowns.length>0){const o=[];for(const t of n.abilityCooldowns){const n=Math.max(0,t.cooldown-e);n&&o.push({index:t.index,source:t.source,cooldown:n})}u[t]=(0,r.produce)(n,(e=>{e.abilityCooldowns=o})),p=!0,n=u[t]}if(n.action){if("attack"===n.action.type){let g,h,m=0;if("number"==typeof n.action.target){const e=u[n.action.target];g=e.position,h=!!e.health&&e.health>0,m=s.units[e.unit].size}else g=n.action.target,h=!0;const y=(0,o.getTwoPointsRadian)(g,n.position);if(h){const h=(0,o.getTwoPointsDistance)(n.position,g)-s.units[n.unit].size-m;if(n.action.ability){const m=(0,i.getAbilityFromIndex)(n.action.ability),{index:v,source:x}=n.action.ability;if(null==m?void 0:m.cast){if(h>m.cast.range){const i=e*f.speed,a=(0,o.getPointByLengthAndDirection)(n.position,i,g);u[t]=(0,r.produce)(n,(e=>{e.position=a,e.facing=y})),p=!0;continue}if(!(null==(l=null==(c=n.abilityCooldowns)?void 0:c.find((e=>e.source===x&&e.index===v)))?void 0:l.cooldown)){if(u[t]=(0,r.produce)(n,(e=>{e.facing=y,e.action=void 0,(0,a.updateAbilityCooldown)(e,v,x,m.cooldown),m.launch(v,(t=>{t(e)}))})),"number"!=typeof n.action.target){m.cast.bulletSpeed&&m.cast.radius&&(d.push({type:"position",position:(0,o.getPointByLengthAndDirection)(n.position,s.units[n.unit].size,g),source:t,target:g,speed:m.cast.bulletSpeed,radius:m.cast.radius,ability:{index:v,source:x}}),p=!0);continue}if(!m.cast.bulletSpeed){d.push({type:"instant",source:t,target:n.action.target,ability:{index:v,source:x}}),p=!0;continue}d.push({position:(0,o.getPointByLengthAndDirection)(n.position,s.units[n.unit].size,g),source:t,target:n.action.target,ability:{index:v,source:x},speed:m.cast.bulletSpeed}),p=!0;continue}u[t]=(0,r.produce)(n,(e=>{e.facing=y})),p=!0;continue}}else if(f.attack){if(h>f.attack.range){const i=e*f.speed,a=(0,o.getPointByLengthAndDirection)(n.position,i,g);u[t]=(0,r.produce)(n,(e=>{e.position=a,e.facing=y})),p=!0;continue}const i=f.attack.time;if(0===f.attack.cooldown&&"number"==typeof n.action.target){u[t]=(0,r.produce)(n,(e=>{e.facing=y,e.attackCooldown=.001*i})),d.push({position:(0,o.getPointByLengthAndDirection)(n.position,s.units[n.unit].size,g),source:t,target:n.action.target,speed:f.attack.bulletSpeed}),p=!0;continue}u[t]=(0,r.produce)(n,(t=>{t.facing=y,t.attackCooldown&&(t.attackCooldown=Math.max(0,t.attackCooldown-e))})),p=!0;continue}}y!==n.facing&&(u[t]=(0,r.produce)(n,(e=>{e.facing=y})),p=!0);continue}const g=e*f.speed,h=n.action.to,m=(0,o.getTwoPointsDistance)(n.position,h),y=(0,o.getTwoPointsRadian)(h,n.position);let v;if(m<=g)v=(0,r.produce)(n,(e=>{e.position=h,e.action=void 0,e.facing=y}));else{const e=(0,o.getPointByLengthAndDirection)(n.position,g,h);v=(0,r.produce)(n,(t=>{t.position=e,t.facing=y}))}let x=!0;for(let e=0;e{e.facing=y})),p=!0)}}return{models:p?u:void 0,bullets:d.length>0||n.length>0?d:void 0}}},7728:(e,t,n)=>{"use strict";n.d(t,{units:()=>r});const r=[{speed:300,size:24,health:{total:500,regeneration:10,armor:0,magicResistance:.25},mana:{total:400,regeneration:.5},attack:{damage:50,damageRange:2,speed:100,time:1700,bulletSpeed:900,range:300},attributes:{strength:20,agility:30,intelligence:15,primary:"agility"}},{speed:300,size:24,health:{total:600,regeneration:10,armor:10,magicResistance:.25}},{speed:300,size:24,health:{total:700,regeneration:10,armor:-10,magicResistance:0}}]},5722:(e,t,n)=>{"use strict";n.d(t,{attackMagicDamage:()=>C,attackPureDamage:()=>b,getAbilityFromIndex:()=>x,getDamageAfterArmor:()=>v,getModelResult:()=>y,getModelsAroundPositionByRadiusExcept:()=>E});var r=n(8662),o=n(8977),i=n(1915),a=n(7728),s=n(9758),c=Object.defineProperty,l=Object.defineProperties,u=Object.getOwnPropertyDescriptors,p=Object.getOwnPropertySymbols,d=Object.prototype.hasOwnProperty,f=Object.prototype.propertyIsEnumerable,g=(e,t,n)=>t in e?c(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,h=(e,t)=>{for(var n in t||(t={}))d.call(t,n)&&g(e,n,t[n]);if(p)for(var n of p(t))f.call(t,n)&&g(e,n,t[n]);return e},m=(e,t)=>l(e,u(t));function y(e){const t=a.units[e.unit];let n=t.speed;const r=t.attributes?m(h({},t.attributes),{base:t.attributes}):void 0,o=t.health&&void 0!==e.health?m(h({},t.health),{current:e.health,base:t.health}):void 0,s=t.mana&&void 0!==e.mana?m(h({},t.mana),{current:e.mana,base:t.mana}):void 0,c=t.attack&&void 0!==e.attackCooldown?m(h({},t.attack),{cooldown:e.attackCooldown,base:t.attack}):void 0;let l=1;if(e.items)for(const t of e.items){const e=i.items[t];e.speed&&(n+=e.speed),o&&(e.health&&(o.total+=e.health),e.heathRegeneration&&(o.regeneration+=e.heathRegeneration),e.armor&&(o.armor+=e.armor),e.magicResistance&&(l*=1-e.magicResistance)),s&&(e.mana&&(s.total+=e.mana),e.manaRegeneration&&(s.regeneration+=e.manaRegeneration)),c&&(e.attackDamage&&(c.damage+=e.attackDamage),e.attackSpeed&&(c.speed+=e.attackSpeed),e.attackRange&&(c.range+=e.attackRange)),r&&(e.strength&&(r.strength+=e.strength),e.agility&&(r.agility+=e.agility),e.intelligence&&(r.intelligence+=e.intelligence))}return o&&((null==r?void 0:r.strength)&&(o.total+=22*r.strength,o.regeneration+=.1*r.strength),(null==r?void 0:r.agility)&&(o.armor+=r.agility/6),(null==r?void 0:r.intelligence)&&(o.magicResistance=1-(1-(o.magicResistance+.001*r.intelligence))*l),o.current*=o.total),s&&((null==r?void 0:r.intelligence)&&(s.total+=12*r.intelligence,s.regeneration+=.05*r.intelligence),s.current*=s.total),c&&r&&("strength"===r.primary?c.damage+=r.strength:"agility"===r.primary?c.damage+=r.agility:"intelligence"===r.primary?c.damage+=r.intelligence:c.damage+=.7*(r.strength+r.agility+r.intelligence),r.agility&&(c.speed+=r.agility),c.time*=100/c.speed),{size:t.size,baseSpeed:t.speed,speed:n,health:o,mana:s,attack:c,attributes:r}}function v(e,t){return e*(1-.06*t/(1+.06*Math.abs(t)))}function x(e){return"abilities"===e.source?o.abilities[e.index]:i.items[e.index].ability}function b(e,t,n){if(!t.health||void 0===e.health)return e;const o=t.health.total,i=Math.max(0,e.health-n/o);return(0,r.produce)(e,(e=>{e.health=i}))}function C(e,t,n){if(!t.health||void 0===e.health)return e;const o=t.health.magicResistance,i=t.health.total,a=n*(1-o),s=Math.max(0,e.health-a/i);return(0,r.produce)(e,(e=>{e.health=s}))}function E(e,t,n,r){return Array.from(e.entries()).filter((([e,o])=>e!==r&&(0,s.getTwoPointsDistance)(o.position,t)-a.units[o.unit].size<=n))}},6523:(e,t,n)=>{"use strict";n.d(t,{Combination8:()=>m});var r=n(3696),o=n(8662),i=n(9397),a=n(9758),s=Object.defineProperty,c=Object.defineProperties,l=Object.getOwnPropertyDescriptors,u=Object.getOwnPropertySymbols,p=Object.prototype.hasOwnProperty,d=Object.prototype.propertyIsEnumerable,f=(e,t,n)=>t in e?s(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,g=(e,t)=>{for(var n in t||(t={}))p.call(t,n)&&f(e,n,t[n]);if(u)for(var n of u(t))d.call(t,n)&&f(e,n,t[n]);return e},h=(e,t)=>c(e,l(t));function m(){const e=r.useRef(null),t=r.useRef(),{x:n,y:i,setX:s,setY:c,ref:l}=(0,a.useWheelScroll)(),{scale:u,setScale:p,ref:d}=(0,a.useWheelZoom)(),f=(0,a.useWindowSize)(),m=f.width,P=f.height,[w,k]=r.useState(),_=r.useRef(new a.WeakmapCache),S=r.useRef(new a.WeakmapCache),R=r.useRef((0,a.getAxesGraphics)()),[,T,A]=(0,a.useLocalStorageState)("composable-editor-canvas-combination8-data",[]),{state:L,setState:M,undo:I,redo:O}=(0,a.useUndoRedo)(A,{onChange:({newState:e})=>{T(e)}}),[D,B]=r.useState(),z=r.useRef(16711680),F=r.useRef(1),N=r.useRef(5),U=r.useRef(0),[G,j]=r.useState(),[V,W]=r.useState(),[H,q]=r.useState();r.useEffect((()=>{e.current&&!t.current&&(t.current=(0,a.createWebgl3DRenderer)(e.current))}),[e.current]),(0,a.useGlobalKeyDown)((e=>{(0,a.metaKeyIfMacElseCtrlKey)(e)?"KeyZ"===e.code?e.shiftKey?O(e):I(e):"Digit0"!==e.code||e.shiftKey||(p(1),s(0),c(0),e.preventDefault()):"Escape"===e.key?(k(void 0),B(void 0),j(void 0),W(void 0),q(void 0)):"Delete"!==e.key&&"Backspace"!==e.key&&"KeyE"!==e.code||void 0!==V&&(M((e=>{e.splice(V,1)})),W(void 0))}));const{position:$,up:X}=(0,a.updateCamera)(0,0,200/u,-.3*n,-.3*i),Y=(0,a.position3DToVec3)($),K=[0,0,0],Z=e=>{const t=a.v3.substract(Y,K);return e?(0,a.getPlaneByPointAndNormal)(e,t):{a:t[0],b:t[1],c:t[2],d:-U.current*a.v3.length(t)}};let Q;if(void 0!==V){const e={},t=L[V].geometry;if(e.color=r.createElement(a.NumberEditor,{value:(0,a.vecToColorNumber)(L[V].color),type:"color",setValue:e=>{M((t=>{t[V].color=(0,a.colorNumberToVec)(e,L[V].color[3])}))}}),e.opacity=r.createElement(a.NumberEditor,{value:100*L[V].color[3],setValue:e=>{M((t=>{t[V].color[3]=.01*e}))}}),"cube"===t.type)e.size=r.createElement(a.NumberEditor,{value:t.size,setValue:e=>{M((t=>{"cube"===t[V].geometry.type&&(t[V].geometry.size=e)}))}});else if("sphere"===t.type)e.radius=r.createElement(a.NumberEditor,{value:t.radius,setValue:e=>{M((t=>{"sphere"===t[V].geometry.type&&(t[V].geometry.radius=e)}))}});else if("cylinder"===t.type)e.radius=r.createElement(a.NumberEditor,{value:t.radius,setValue:e=>{M((t=>{"cylinder"===t[V].geometry.type&&(t[V].geometry.radius=e)}))}}),e.height=r.createElement(a.NumberEditor,{value:t.height,setValue:e=>{M((t=>{"cylinder"===t[V].geometry.type&&(t[V].geometry.height=e)}))}});else if("cone"===t.type)e.topRadius=r.createElement(a.NumberEditor,{value:t.topRadius,setValue:e=>{M((t=>{"cone"===t[V].geometry.type&&(t[V].geometry.topRadius=e)}))}}),e.bottomRadius=r.createElement(a.NumberEditor,{value:t.bottomRadius,setValue:e=>{M((t=>{"cone"===t[V].geometry.type&&(t[V].geometry.bottomRadius=e)}))}}),e.height=r.createElement(a.NumberEditor,{value:t.height,setValue:e=>{M((t=>{"cone"===t[V].geometry.type&&(t[V].geometry.height=e)}))}});else if("point"===t.type){for(const n of["x","y","z"])e[`point ${n}`]=r.createElement(a.NumberEditor,{value:t.position[n],setValue:e=>{M((t=>{"point"===t[V].geometry.type&&(t[V].geometry.position[n]=e)}))}});e.point=r.createElement(a.Button,{onClick:()=>{k({type:"update point",plane:Z((0,a.position3DToVec3)(t.position)),updatePoint(e){B((0,o.produce)(L[V],(t=>{"point"===t.geometry.type&&(t.geometry.position=e)})))}})}},"update")}else if("triangle"===t.type)for(const n of["p1","p2"]){for(const o of["x","y","z"])e[`${n} ${o}`]=r.createElement(a.NumberEditor,{value:t[n][o],setValue:e=>{M((t=>{"triangle"===t[V].geometry.type&&(t[V].geometry[n][o]=e)}))}});e[n]=r.createElement(a.Button,{onClick:()=>{k({type:"update point",plane:Z((0,a.position3DToVec3)(t[n])),updatePoint(e){B((0,o.produce)(L[V],(t=>{"triangle"===t.geometry.type&&(t.geometry[n]=e)})))}})}},"update")}for(const t of["x","y","z"])e[`position ${t}`]=r.createElement(a.NumberEditor,{value:L[V].position[t],setValue:e=>{M((n=>{n[V].position[t]=e}))}});if(e.position=r.createElement(a.Button,{onClick:()=>{k({type:"update point",plane:Z((0,a.position3DToVec3)(L[V].position)),updatePoint(e){B((0,o.produce)(L[V],(t=>{t.position=e})))}})}},"update"),"cylinder"===t.type||"cone"===t.type){for(const t of["x","y","z"])e[`direction ${t}`]=r.createElement(a.NumberEditor,{value:(L[V].direction||{x:0,y:1,z:0})[t],setValue:e=>{M((n=>{n[V].direction||(n[V].direction={x:0,y:1,z:0}),n[V].direction[t]=e}))}});e.direction=r.createElement(a.Button,{onClick:()=>{k({type:"update point",plane:Z((0,a.position3DToVec3)(L[V].position)),updatePoint(e){B((0,o.produce)(L[V],(t=>{t.direction=(0,a.vec3ToPosition3D)(a.v3.substract((0,a.position3DToVec3)(e),(0,a.position3DToVec3)(t.position)))})))}})}},"update")}Q=r.createElement("div",{style:{position:"absolute",right:"0px",top:"40px",bottom:"0px",width:"360px",overflowY:"auto",background:"white"}},r.createElement(a.ObjectEditor,{inline:!0,properties:e}))}const J=e=>_.current.get(e,(()=>"point"===e.geometry.type?{geometry:{type:"lines",points:[...(0,a.position3DToVec3)(e.position),...(0,a.position3DToVec3)(e.geometry.position)]},color:e.color}:"triangle"===e.geometry.type?{geometry:{type:"triangles",points:[...(0,a.position3DToVec3)(e.position),...(0,a.position3DToVec3)(e.geometry.p1),...(0,a.position3DToVec3)(e.geometry.p2)]},color:e.color}:"line strip"===e.geometry.type?{geometry:{type:"line strip",points:e.geometry.points.flat()},color:e.color}:{geometry:e.geometry,color:e.color,position:(0,a.position3DToVec3)(e.position),direction:e.direction?(0,a.position3DToVec3)(e.direction):void 0}));return r.useEffect((()=>{const e=[...L.map(((e,t)=>(G!==t&&V!==t||(e=S.current.get(e,(()=>(0,o.produce)(e,(e=>{e.color[3]*=.5}))))),J(e))))];var n,r,i;e.push(...R.current),D&&e.push(J(D)),n=e,null==(i=null==(r=t.current)?void 0:r.render)||i.call(r,n,{eye:Y,up:(0,a.position3DToVec3)(X),target:K,fov:(0,a.angleToRadian)(60),near:.1,far:2e4},{position:[1e3,1e3,1e3],color:[1,1,1,1],specular:[1,1,1,1],shininess:50,specularFactor:1},[1,1,1,1])}),[L,D,G,V,n,i,u,m,P]),r.createElement("div",{ref:(0,a.bindMultipleRefs)(l,d),style:{position:"absolute",inset:"0px",cursor:H?"pointer":void 0}},r.createElement("canvas",{ref:e,width:m,height:P,onMouseMove:e=>{var n;if(!w&&void 0!==V&&t.current){const n=t.current.reversedProjection,r=L[V];if(n&&r){const o=(0,a.reverse3dPosition)(e.clientX,e.clientY,t.current.canvas,n),i=[{point:r.position,updatePoint(e,t){e.position=t}}];if("point"===r.geometry.type)i.push({point:r.geometry.position,updatePoint(e,t){"point"===e.geometry.type&&(e.geometry.position=t)}});else if("triangle"===r.geometry.type)i.push({point:r.geometry.p1,updatePoint(e,t){"triangle"===e.geometry.type&&(e.geometry.p1=t)}},{point:r.geometry.p2,updatePoint(e,t){"triangle"===e.geometry.type&&(e.geometry.p2=t)}});else if("cylinder"===r.geometry.type||"cone"===r.geometry.type){const e=(0,a.position3DToVec3)(r.position);i.push({point:(0,a.vec3ToPosition3D)((0,a.getPointByLengthAndDirection3D)(e,r.geometry.height/2,(0,a.position3DToVec3)(r.direction||{x:0,y:1,z:0}))),updatePoint(t,n){t.direction=(0,a.vec3ToPosition3D)(a.v3.substract((0,a.position3DToVec3)(n),e))}})}for(const e of i)if((0,a.getPerpendicularDistanceToLine3D)((0,a.position3DToVec3)(e.point),o,a.v3.substract(Y,o))<3)return void q(e);q(void 0)}}if(w&&"intersect"!==w){if(t.current){const n=t.current.reversedProjection;if(n){if("string"!=typeof w&&void 0!==V&&"update point"===w.type){const r=t.current.getTarget(e.clientX,e.clientY,Y,w.plane,n);return void(r&&w.updatePoint((0,a.vec3ToPosition3D)(r)))}const r=t.current.getTarget(e.clientX,e.clientY,Y,Z(),n);if(!r)return;const o=(0,a.colorNumberToVec)(z.current,F.current),i=(0,a.vec3ToPosition3D)(r);if("cube"===w?B({geometry:{type:"cube",size:N.current},color:o,position:i}):"sphere"===w?B({geometry:{type:"sphere",radius:N.current},color:o,position:i}):"cylinder"===w?B({geometry:{type:"cylinder",radius:N.current,height:N.current},color:o,position:i}):"cone"===w&&B({geometry:{type:"cone",topRadius:0,bottomRadius:N.current,height:2*N.current},color:o,position:i}),"string"==typeof w)return;"line start"===w.type?k(h(g({},w),{position:i})):"line end"===w.type?B({geometry:{type:"point",position:w.position},color:o,position:i}):"plane 1st point"===w.type?k(h(g({},w),{p1:i})):"plane 2nd point"===w.type?(k(h(g({},w),{p2:i})),B({geometry:{type:"point",position:w.p1},color:o,position:i})):"plane 3rd point"===w.type&&B({geometry:{type:"triangle",p1:w.p1,p2:w.p2},color:o,position:i})}}}else{const r=null==(n=t.current)?void 0:n.pick(e.clientX,e.clientY);j(r)}},onMouseDown:()=>{if(w){if("string"!=typeof w&&"plane 2nd point"===w.type&&w.p2)k({type:"plane 3rd point",p1:w.p1,p2:w.p2});else if(D)"string"!=typeof w&&"update point"===w.type&&void 0!==V?(M((e=>{e[V]=D})),k(void 0)):M((e=>{e.push(D)})),B(void 0),"string"==typeof w||"line end"!==w.type&&"plane 3rd point"!==w.type||k(void 0);else if("string"!=typeof w&&"line start"===w.type&&w.position)k({type:"line end",position:w.position});else if("string"!=typeof w&&"plane 1st point"===w.type&&w.p1)k({type:"plane 2nd point",p1:w.p1});else if("intersect"===w&&void 0!==G&&void 0!==V&&G!==V){const e=L[G],t=L[V];let n,r;if("point"===e.geometry.type){if("point"===t.geometry.type){const r=v(e.geometry,e.position),o=v(t.geometry,t.position),i=(0,a.getTwoLine3DIntersectionPoint)(r[0],a.v3.substract(...r),o[0],a.v3.substract(...o));i&&(n=[i])}else if("sphere"===t.geometry.type)n=(0,a.getLineAndSphereIntersectionPoints)(v(e.geometry,e.position),C(t.geometry,t.position));else if("cylinder"===t.geometry.type)n=(0,a.getLineAndCylinderIntersectionPoints)(v(e.geometry,e.position),b(t.geometry,t.position,t.direction));else if("cone"===t.geometry.type)n=(0,a.equals)(t.geometry.topRadius,t.geometry.bottomRadius)?(0,a.getLineAndCylinderIntersectionPoints)(v(e.geometry,e.position),b({type:"cylinder",height:t.geometry.height,radius:t.geometry.bottomRadius},t.position,t.direction)):(0,a.getLineAndConeIntersectionPoints)(v(e.geometry,e.position),E(t.geometry,t.position,t.direction));else if("triangle"===t.geometry.type){const r=x(t.geometry,t.position);if(r){const t=(0,a.getLineAndPlaneIntersectionPoint)(v(e.geometry,e.position),r);t&&(n=[t])}}else if("cube"===t.geometry.type){const r=y(t.geometry,t.position);n=(0,a.getLineAndTrianglesIntersectionPoint)(v(e.geometry,e.position),r)}}else if("sphere"===e.geometry.type)if("point"===t.geometry.type)n=(0,a.getLineAndSphereIntersectionPoints)(v(t.geometry,t.position),C(e.geometry,e.position));else if("triangle"===t.geometry.type){const n=x(t.geometry,t.position);n&&(r=(0,a.getPlaneSphereIntersection)(n,C(e.geometry,e.position)))}else"sphere"===t.geometry.type&&(r=(0,a.getTwoSpheresIntersection)(C(e.geometry,e.position),C(t.geometry,t.position)));else if("cylinder"===e.geometry.type){if("point"===t.geometry.type)n=(0,a.getLineAndCylinderIntersectionPoints)(v(t.geometry,t.position),b(e.geometry,e.position,e.direction));else if("triangle"===t.geometry.type){const n=x(t.geometry,t.position);n&&(r=(0,a.getPlaneCylinderIntersection)(n,b(e.geometry,e.position,e.direction)))}}else if("cone"===e.geometry.type)"point"===t.geometry.type&&(n=(0,a.equals)(e.geometry.topRadius,e.geometry.bottomRadius)?(0,a.getLineAndCylinderIntersectionPoints)(v(t.geometry,t.position),b({type:"cylinder",height:e.geometry.height,radius:e.geometry.bottomRadius},e.position,e.direction)):(0,a.getLineAndConeIntersectionPoints)(v(t.geometry,t.position),E(e.geometry,e.position,e.direction)));else if("triangle"===e.geometry.type){if("point"===t.geometry.type){const r=x(e.geometry,e.position);if(r){const e=(0,a.getLineAndPlaneIntersectionPoint)(v(t.geometry,t.position),r);e&&(n=[e])}}else if("sphere"===t.geometry.type){const n=x(e.geometry,e.position);n&&(r=(0,a.getPlaneSphereIntersection)(n,C(t.geometry,t.position)))}else if("cylinder"===t.geometry.type){const n=x(e.geometry,e.position);n&&(r=(0,a.getPlaneCylinderIntersection)(n,b(t.geometry,t.position,t.direction)))}}else if("cube"===e.geometry.type&&"point"===t.geometry.type){const r=y(e.geometry,e.position);n=(0,a.getLineAndTrianglesIntersectionPoint)(v(t.geometry,t.position),r)}n&&n.length>0&&(M((e=>{e.push(...n.map((e=>({geometry:{type:"sphere",radius:N.current},color:(0,a.colorNumberToVec)(z.current,F.current),position:(0,a.vec3ToPosition3D)(e)}))))})),k(void 0)),r&&r.length>0&&(M((e=>{e.push({geometry:{type:"line strip",points:r},color:(0,a.colorNumberToVec)(z.current,F.current),position:{x:0,y:0,z:0}})})),k(void 0))}}else{if(void 0!==V&&H){const e=L[V];if(e)return void k({type:"update point",plane:Z((0,a.position3DToVec3)(H.point)),updatePoint(t){B((0,o.produce)(e,(e=>{H.updatePoint(e,t)})))}})}void 0!==G&&W(G)}}}),r.createElement("div",{style:{position:"absolute",top:"0px"}},["cube","sphere","cylinder","cone"].map((e=>r.createElement(a.Button,{key:e,style:{color:w===e?"red":void 0},onClick:()=>k(e)},e))),r.createElement(a.Button,{style:{color:"string"!=typeof w&&"line start"===(null==w?void 0:w.type)?"red":void 0},onClick:()=>k({type:"line start"})},"line"),r.createElement(a.Button,{style:{color:"string"!=typeof w&&"plane 1st point"===(null==w?void 0:w.type)?"red":void 0},onClick:()=>k({type:"plane 1st point"})},"plane"),void 0!==V&&r.createElement(a.Button,{onClick:()=>{M((e=>{e.splice(V,1)})),W(void 0)}},"delete"),void 0!==V&&r.createElement(a.Button,{onClick:()=>k("intersect")},"intersect"),r.createElement(a.NumberEditor,{value:U.current,style:{width:"50px",position:"relative"},setValue:e=>{U.current=e}}),r.createElement(a.NumberEditor,{value:N.current,style:{width:"40px",position:"relative"},setValue:e=>{N.current=e}}),r.createElement(a.NumberEditor,{value:100*F.current,style:{width:"50px",position:"relative"},setValue:e=>{F.current=.01*e}}),r.createElement(a.NumberEditor,{value:z.current,type:"color",style:{width:"50px",position:"relative"},setValue:e=>{z.current=e}})),Q)}function y(e,t){return(0,a.getVerticesTriangles)(i.primitives.createCubeVertices(e.size),(0,a.position3DToVec3)(t))}function v(e,t){return[(0,a.position3DToVec3)(t),(0,a.position3DToVec3)(e.position)]}function x(e,t){return(0,a.getThreePointPlane)((0,a.position3DToVec3)(t),(0,a.position3DToVec3)(e.p1),(0,a.position3DToVec3)(e.p2))}function b(e,t,n={x:0,y:1,z:0}){return{base:(0,a.position3DToVec3)(t),radius:e.radius,direction:(0,a.position3DToVec3)(n),height1:-e.height/2,height2:e.height/2}}function C(e,t){return g({radius:e.radius},t)}function E(e,t,n={x:0,y:1,z:0}){const r=(0,a.position3DToVec3)(n),o=e.height/2*(e.topRadius+e.bottomRadius)/(e.bottomRadius-e.topRadius);return{base:(0,a.getPointByLengthAndDirection3D)((0,a.position3DToVec3)(t),o,r),radiusHeightRate:Math.abs(e.bottomRadius-e.topRadius)/e.height,direction:r,height1:-o-e.height/2,height2:-o+e.height/2}}},8781:(e,t,n)=>{"use strict";n.d(t,{styleGuide:()=>r});const r={name:"test",templates:[{id:"1",name:"组件",x:0,y:0,width:500,height:300,contents:[{kind:"text",text:"test",fontFamily:"serif",fontSize:50,color:"#ff0000",width:100,height:100,x:10,y:10},{kind:"image",url:"https://interactive-examples.mdn.mozilla.net/media/cc0-images/grapefruit-slice-332-332.jpg",width:100,height:100,x:210,y:10}]},{id:"2",name:"模板",x:600,y:0,width:1100,height:400,contents:[{kind:"color",x:0,y:0,width:1100,height:400,color:"#cccccc"},{kind:"reference",id:"1",x:10,y:10},{kind:"snapshot",rotate:30,snapshot:{id:"1",name:"组件",x:0,y:0,width:500,height:300,contents:[{kind:"text",text:"test",fontFamily:"serif",fontSize:50,color:"#ff0000",width:100,height:100,x:10,y:10},{kind:"image",url:"https://interactive-examples.mdn.mozilla.net/media/cc0-images/grapefruit-slice-332-332.jpg",width:100,height:100,x:210,y:10}]},x:550,y:10}]}]}},4341:(e,t,n)=>{"use strict";n.d(t,{HoverRenderer:()=>a});var r=n(3696),o=n.n(r),i=n(681);function a(e){var t,n;const{styleGuide:r,hovered:a}=e,s=(0,i.getTargetByPath)(a,r);if(!s)return null;const c=s.template;if("template"===s.kind)return o().createElement(o().Fragment,null,o().createElement("div",{style:{position:"absolute",boxSizing:"border-box",left:c.x,top:c.y,width:c.width,height:c.height,backgroundColor:"green",opacity:.1}}));const l=s.content,u=(0,i.getTemplateContentSize)(l,r);if(!u)return null;const{width:p,height:d}=u;let f=o().createElement("div",{style:{position:"absolute",boxSizing:"border-box",left:l.x,top:l.y,width:p,height:d,backgroundColor:"green",opacity:.1,transform:`rotate(${null!=(t=l.rotate)?t:0}deg)`}});for(const e of s.parents)"snapshot"===e.kind&&(f=o().createElement("div",{style:{position:"absolute",left:e.x,top:e.y,width:e.snapshot.width,height:e.snapshot.height,transform:`rotate(${null!=(n=e.rotate)?n:0}deg)`}},f));return o().createElement("div",{style:{position:"absolute",left:c.x,top:c.y,width:c.width,height:c.height}},f)}},5371:(e,t,n)=>{"use strict";n.d(t,{App:()=>f});var r=n(3696),o=n.n(r),i=n(9758),a=n(8781),s=n(4341),c=n(2550),l=n(2801),u=n(681);const p="composable-editor-canvas-draft",d=localStorage.getItem(p);function f(){var e;const{state:t,setState:n,undo:r,redo:f,stateIndex:h}=(0,i.useUndoRedo)(d?JSON.parse(d):a.styleGuide);o().useEffect((()=>{h>0&&localStorage.setItem(p,JSON.stringify(t))}),[t,h]);const m=Math.min(...t.templates.map((e=>e.x))),y=Math.min(...t.templates.map((e=>e.y))),[v]=o().useState({width:Math.max(...t.templates.map((e=>e.x+e.width)))-m,height:Math.max(...t.templates.map((e=>e.y+e.height)))-y}),x={width:window.innerWidth,height:window.innerHeight},{ref:b,scale:C,setScale:E}=(0,i.useWheelZoom)(),P=C*Math.min((x.width-80)/v.width,(x.height-80)/v.height),w={width:v.width*P+80,height:v.height*P+80},{x:k,y:_,setX:S,setY:R,ref:T}=(0,i.useWheelScroll)({maxOffsetX:(w.width-x.width)/2,maxOffsetY:(w.height-x.height)/2}),{zoomIn:A,zoomOut:L}=(0,i.useZoom)(C,E),{selected:[M],setSelected:I,onSelectedKeyDown:O}=(0,i.useSelected)({maxCount:1}),{selected:[D],setSelected:B,onSelectedKeyDown:z}=(0,i.useSelected)({maxCount:1}),F={containerSize:x,targetSize:v,x:k,y:_,scale:P},N=(0,u.getSelectedSize)(M,t),U=(0,u.getTargetByPath)(M,t),G="content"===(null==U?void 0:U.kind)?U.parents.reduce(((e,t)=>{var n;return e+(null!=(n=t.rotate)?n:0)}),0):void 0,{regionAlignmentX:j,regionAlignmentY:V,changeOffsetByRegionAlignment:W,clearRegionAlignments:H}=(0,i.useRegionAlignment)(6/P),{offset:q,onStart:$,mask:X,startPosition:Y,resetDragMove:K}=(0,i.useDragMove)((()=>{H(),0===q.x&&0===q.y&&Y?I((0,u.selectByPosition)(t,g(Y,F),P)):n((e=>{const t=(0,u.getSelectedPosition)(M,e);t&&(t.x+=q.x,t.y+=q.y)}))}),{scale:P,parentRotate:G,transformOffset:(e,n)=>{if(n&&!n.shiftKey&&"template"===(null==U?void 0:U.kind)){const n=U.template;W(e,n,t.templates.filter((e=>e!==n)))}else H();return e}}),{offset:Z,onStart:Q,mask:J,center:ee,resetDragRotate:te}=(0,i.useDragRotate)((()=>{n((e=>{const t=(0,u.getTargetByPath)(M,e);"content"===(null==t?void 0:t.kind)&&(t.content.rotate=null==Z?void 0:Z.angle)}))}),{transform:e=>g(e,F),parentRotate:G,transformOffset:(e,t)=>{if(t&&void 0!==e&&!t.shiftKey){const t=45*Math.round(e/45);Math.abs(t-e)<5&&(e=t)}return e}}),{lineAlignmentX:ne,lineAlignmentY:re,changeOffsetByLineAlignment:oe,clearLineAlignments:ie}=(0,i.useLineAlignment)(6/P),{offset:ae,onStart:se,mask:ce,startPosition:le,resetDragResize:ue}=(0,i.useDragResize)((()=>{ie(),n((e=>{const t=(0,u.getSelectedSize)(M,e),n=(0,u.getSelectedPosition)(M,e);t&&(t.width+=ae.width,t.height+=ae.height),n&&(n.x+=ae.x,n.y+=ae.y)}))}),{centeredScaling:e=>e.shiftKey,keepRatio:e=>{if((0,i.metaKeyIfMacElseCtrlKey)(e)&&N)return N.width/N.height},rotate:"content"===(null==U?void 0:U.kind)&&null!=(e=U.content.rotate)?e:0,parentRotate:G,transform:e=>g(e,F),transformOffset:(e,n,r)=>{if(n&&r&&!n.altKey&&"template"===(null==U?void 0:U.kind)){const n=U.template,o=t.templates.filter((e=>e!==n)).map((e=>[e.x,e.x+e.width])).flat(),i=t.templates.filter((e=>e!==n)).map((e=>[e.y,e.y+e.height])).flat();oe(e,r,n,o,i)}else ie();return e}}),{onStartSelect:pe,dragSelectMask:de,dragSelectStartPosition:fe,resetDragSelect:ge}=(0,i.useDragSelect)(((e,n)=>{if(n){const r=(0,u.selectTemplateByArea)(t,g(e,F),g(n,F));void 0!==r&&I([r])}else I((0,u.selectByPosition)(t,g(e,F),P))}),(e=>e.shiftKey));(0,i.useGlobalKeyDown)((e=>{O(e),z(e),"Escape"===e.key?(ge(),te(),ue(),K()):(0,i.metaKeyIfMacElseCtrlKey)(e)&&("KeyZ"===e.code?e.shiftKey?f(e):r(e):"Minus"===e.code?L(e):"Equal"===e.code&&A(e))}));const he={x:q.x+ae.x,y:q.y+ae.y,width:ae.width,height:ae.height},me=Y||ee||le||fe;return o().createElement("div",{style:{position:"absolute",inset:"0px",backgroundColor:"#E0DFDE",display:"flex",alignItems:"center",justifyContent:"center",overflow:"hidden"},ref:(0,i.bindMultipleRefs)(T,b),onMouseMove:e=>{if(me)B();else{const n=(0,u.selectByPosition)(t,g({x:e.clientX,y:e.clientY},F),P);(0,i.isSamePath)(n,D)||B(n)}},onMouseDown:e=>{pe(e,void 0)}},o().createElement(c.StyleGuideRenderer,{styleGuide:t,targetSize:v,x:k,y:_,scale:P,onStartSelect:pe,offset:he,rotate:null==Z?void 0:Z.angle,selected:M}),M&&o().createElement("div",{style:{position:"absolute",transform:`translate(${k}px, ${_}px) scale(${P})`,width:v.width,height:v.height,pointerEvents:"none"}},o().createElement(l.SelectionRenderer,{styleGuide:t,scale:P,selected:M,onStartMove:$,offset:he,rotate:null==Z?void 0:Z.angle,onStartRotate:Q,onStartResize:se})),D&&o().createElement("div",{style:{position:"absolute",transform:`translate(${k}px, ${_}px) scale(${P})`,width:v.width,height:v.height,pointerEvents:"none"}},o().createElement(s.HoverRenderer,{styleGuide:t,hovered:D})),o().createElement(i.Scrollbar,{value:k,type:"horizontal",containerSize:x.width,contentSize:w.width,onChange:S}),o().createElement(i.Scrollbar,{value:_,type:"vertical",containerSize:x.height,contentSize:w.height,onChange:R}),o().createElement(i.AlignmentLine,{type:"x",value:null!=j?j:ne,transformX:e=>function(e,t){var n,r,o,i,a,s;return(null!=(r=null==(n=null==t?void 0:t.containerSize)?void 0:n.width)?r:0)/2-((null!=(i=null==(o=null==t?void 0:t.targetSize)?void 0:o.width)?i:0)/2-e)*(null!=(a=null==t?void 0:t.scale)?a:1)+(null!=(s=null==t?void 0:t.x)?s:0)}(e,F)}),o().createElement(i.AlignmentLine,{type:"y",value:null!=V?V:re,transformY:e=>function(e,t){var n,r,o,i,a,s;return(null!=(r=null==(n=null==t?void 0:t.containerSize)?void 0:n.height)?r:0)/2-((null!=(i=null==(o=null==t?void 0:t.targetSize)?void 0:o.height)?i:0)/2-e)*(null!=(a=null==t?void 0:t.scale)?a:1)+(null!=(s=null==t?void 0:t.y)?s:0)}(e,F)}),X,J,ce,de)}function g({x:e,y:t},n){var r,o,i,a,s,c,l,u,p,d,f,g;return{x:(null!=(o=null==(r=null==n?void 0:n.targetSize)?void 0:r.width)?o:0)/2-((null!=(a=null==(i=null==n?void 0:n.containerSize)?void 0:i.width)?a:0)/2-e+(null!=(s=null==n?void 0:n.x)?s:0))/(null!=(c=null==n?void 0:n.scale)?c:1),y:(null!=(u=null==(l=null==n?void 0:n.targetSize)?void 0:l.height)?u:0)/2-((null!=(d=null==(p=null==n?void 0:n.containerSize)?void 0:p.height)?d:0)/2-t+(null!=(f=null==n?void 0:n.y)?f:0))/(null!=(g=null==n?void 0:n.scale)?g:1)}}},2550:(e,t,n)=>{"use strict";n.d(t,{StyleGuideRenderer:()=>s});var r=n(3696),o=n.n(r),i=n(9758),a=n(681);function s(e){const{x:t,y:n,scale:r,styleGuide:a,targetSize:s,onStartSelect:l,selected:u,offset:p,rotate:d}=e;return o().createElement("div",{style:{position:"absolute",boxSizing:"border-box",transform:`translate(${t}px, ${n}px) scale(${r})`,width:s.width,height:s.height}},a.templates.map(((e,t)=>o().createElement(c,{key:e.id,template:e,styleGuide:a,path:[t],onStartSelect:l,selected:u,offset:p,rotate:d,scale:r,isSelected:(0,i.isSamePath)(u,[t])}))))}function c(e){const{template:t,selected:n,offset:r,rotate:i,onStartSelect:s,scale:c}=e;return o().createElement("div",{style:{position:"absolute",boxSizing:"border-box",left:t.x+(e.isSelected?r.x:0),top:t.y+(e.isSelected?r.y:0),width:t.width+(e.isSelected?r.width:0),height:t.height+(e.isSelected?r.height:0),border:1/c+"px solid rgb(160, 160, 160)",backgroundColor:"white"},onMouseDown:e=>{e.stopPropagation(),s(e)}},t.name&&o().createElement("div",{style:{position:"absolute",top:`-${a.nameSize}px`,lineHeight:`${a.nameSize}px`,fontSize:"12px",width:t.name.length*a.nameSize+"px",transform:`scale(${1/c})`,transformOrigin:"left bottom",cursor:"pointer"}},t.name),t.contents.map(((t,a)=>o().createElement(u,{key:a,content:t,styleGuide:e.styleGuide,offset:r,rotate:i,path:[...e.path,a],selected:n}))))}function l(e){var t,n,r,i,a,s;const{template:c,styleGuide:l,content:p,offset:d,rotate:f}=e;return o().createElement("div",{style:{position:"absolute",boxSizing:"border-box",left:p.x+(e.isSelected&&null!=(t=null==d?void 0:d.x)?t:0),top:p.y+(e.isSelected&&null!=(n=null==d?void 0:d.y)?n:0),width:c.width+(e.isSelected&&null!=(r=null==d?void 0:d.width)?r:0),height:c.height+(e.isSelected&&null!=(i=null==d?void 0:d.height)?i:0),clipPath:"inset(0)",backgroundColor:"white",transform:`rotate(${null!=(s=null!=(a=e.isSelected?f:void 0)?a:p.rotate)?s:0}deg)`}},c.contents.map(((t,n)=>o().createElement(u,{key:n,content:t,styleGuide:l,path:[...e.path,n],offset:d,rotate:f,selected:e.selected}))))}function u(e){const{content:t,offset:n,rotate:r}=e;if(t.hidden)return null;const a=(0,i.isSamePath)(e.selected,e.path);if("text"===t.kind)return o().createElement(p,{content:t,offset:a?n:void 0,rotate:a?r:void 0});if("image"===t.kind)return o().createElement(d,{content:t,offset:a?n:void 0,rotate:a?r:void 0});if("color"===t.kind)return o().createElement(f,{content:t,offset:a?n:void 0,rotate:a?r:void 0});if("reference"===t.kind){const i=e.styleGuide.templates.findIndex((e=>e.id===t.id));if(i>=0)return o().createElement(l,{template:e.styleGuide.templates[i],styleGuide:e.styleGuide,content:t,path:[i],offset:n,rotate:r,selected:e.selected,isSelected:a})}return"snapshot"===t.kind?o().createElement(l,{template:t.snapshot,styleGuide:e.styleGuide,content:t,path:e.path,offset:n,rotate:r,selected:e.selected,isSelected:a}):null}function p(e){var t,n,r,i,a;const{content:s,offset:c,rotate:l}=e;return o().createElement("div",{style:{position:"absolute",boxSizing:"border-box",left:s.x+(null!=(t=null==c?void 0:c.x)?t:0),top:s.y+(null!=(n=null==c?void 0:c.y)?n:0),width:s.width+(null!=(r=null==c?void 0:c.width)?r:0),height:s.height+(null!=(i=null==c?void 0:c.height)?i:0),color:s.color,fontSize:s.fontSize,fontFamily:s.fontFamily,transform:`rotate(${null!=(a=null!=l?l:s.rotate)?a:0}deg)`}},s.text)}function d(e){var t,n,r,i,a;const{content:s,offset:c,rotate:l}=e;return o().createElement("img",{src:s.url,style:{position:"absolute",boxSizing:"border-box",left:s.x+(null!=(t=null==c?void 0:c.x)?t:0),top:s.y+(null!=(n=null==c?void 0:c.y)?n:0),width:s.width+(null!=(r=null==c?void 0:c.width)?r:0),height:s.height+(null!=(i=null==c?void 0:c.height)?i:0),transform:`rotate(${null!=(a=null!=l?l:s.rotate)?a:0}deg)`}})}function f(e){var t,n,r,i,a;const{content:s,offset:c,rotate:l}=e;return o().createElement("div",{style:{position:"absolute",boxSizing:"border-box",left:s.x+(null!=(t=null==c?void 0:c.x)?t:0),top:s.y+(null!=(n=null==c?void 0:c.y)?n:0),width:s.width+(null!=(r=null==c?void 0:c.width)?r:0),height:s.height+(null!=(i=null==c?void 0:c.height)?i:0),backgroundColor:s.color,transform:`rotate(${null!=(a=null!=l?l:s.rotate)?a:0}deg)`}})}},2801:(e,t,n)=>{"use strict";n.d(t,{SelectionRenderer:()=>s});var r=n(3696),o=n.n(r),i=n(9758),a=n(681);function s(e){var t,n,r,s;const{styleGuide:c,scale:l,selected:u,offset:p,rotate:d,onStartRotate:f,onStartResize:g}=e,h=(0,a.getTargetByPath)(u,c);if(!h)return null;const m=t=>{var n;t.stopPropagation(),null==(n=e.onStartMove)||n.call(e,{x:t.clientX,y:t.clientY})},y=h.template;if("template"===h.kind)return o().createElement(o().Fragment,null,o().createElement("div",{style:{position:"absolute",boxSizing:"border-box",left:y.x+p.x,top:y.y+p.y,width:y.width+p.width,height:y.height+p.height,border:1/l+"px solid green",cursor:"move",pointerEvents:"auto"},onMouseDown:m}),o().createElement("div",{style:{position:"absolute",boxSizing:"border-box",left:y.x+p.x,top:y.y+p.y,width:y.width+p.width,height:y.height+p.height}},o().createElement(i.ResizeBar,{scale:l,onMouseDown:g})),y.name&&o().createElement("div",{style:{position:"absolute",left:y.x+p.x,top:y.y+p.y-a.nameSize,height:a.nameSize,fontSize:"12px",width:y.name.length*a.nameSize,transform:`scale(${1/l})`,transformOrigin:"left bottom",cursor:"move",pointerEvents:"auto"},onMouseDown:m}));const v=h.content,x=(0,a.getTemplateContentSize)(v,c);if(!x)return null;const{width:b,height:C}=x;let E=o().createElement(o().Fragment,null,o().createElement("div",{style:{position:"absolute",boxSizing:"border-box",left:v.x+p.x,top:v.y+p.y,width:b+p.width,height:C+p.height,border:1/l+"px solid green",cursor:"move",pointerEvents:"auto",transform:`rotate(${null!=(t=null!=d?d:v.rotate)?t:0}deg)`},onMouseDown:m}),o().createElement("div",{style:{position:"absolute",boxSizing:"border-box",left:v.x+p.x,top:v.y+p.y,width:b+p.width,height:C+p.height,transform:`rotate(${null!=(n=null!=d?d:v.rotate)?n:0}deg)`}},o().createElement(i.RotationBar,{scale:l,onMouseDown:e=>{e.stopPropagation(),f((0,a.getRotatedCenter)(h,c))}}),o().createElement(i.ResizeBar,{scale:l,onMouseDown:g,rotate:(null!=(r=v.rotate)?r:0)+h.parents.reduce(((e,t)=>{var n;return e+(null!=(n=t.rotate)?n:0)}),0)})));for(const e of h.parents)"snapshot"===e.kind&&(E=o().createElement("div",{style:{position:"absolute",left:e.x,top:e.y,width:e.snapshot.width,height:e.snapshot.height,transform:`rotate(${null!=(s=e.rotate)?s:0}deg)`}},E));return o().createElement("div",{style:{position:"absolute",left:y.x,top:y.y,width:y.width,height:y.height}},E)}},681:(e,t,n)=>{"use strict";n.d(t,{getRotatedCenter:()=>y,getSelectedPosition:()=>c,getSelectedSize:()=>s,getTargetByPath:()=>l,getTemplateContentSize:()=>p,nameSize:()=>g,selectByPosition:()=>h,selectTemplateByArea:()=>d});var r=n(9758),o=(e,t)=>(t=Symbol[e])?t:Symbol.for("Symbol."+e),i=function(e,t){this[0]=e,this[1]=t},a=e=>{var t,n=e[o("asyncIterator")],r=!1,a={};return null==n?(n=e[o("iterator")](),t=e=>a[e]=t=>n[e](t)):(n=n.call(e),t=e=>a[e]=t=>{if(r){if(r=!1,"throw"===e)throw t;return t}return r=!0,{done:!1,value:new i(new Promise((r=>{var o=n[e](t);o instanceof Object||(()=>{throw TypeError("Object expected")})(),r(o)})),1)}}),a[o("iterator")]=()=>a,t("next"),"throw"in n?t("throw"):a.throw=e=>{throw e},"return"in n&&t("return"),a};function s(e,t){const n=l(e,t);if(!n)return;const r=n.template;return"content"===n.kind?p(n.content,t):r}function c(e,t){const n=l(e,t);if(n)return"template"===n.kind?n.template:n.content}function l(e,t){if(!e)return;const[n,...r]=e,o=t.templates[n];if(0===r.length)return{kind:"template",template:o};const i=u(r,o,t,[]);return i?{kind:"content",template:o,content:i.content,parents:i.parents}:void 0}function u([e,...t],n,r,o){const i=n.contents[e];if(0===t.length)return{content:i,parents:o};if("snapshot"===i.kind)return u(t,i.snapshot,r,[...o,i]);if("reference"===i.kind){const e=r.templates.find((e=>e.id===i.id));if(!e)return;return u(t,e,r,[...o,i])}}function p(e,t){if("snapshot"===e.kind)return e.snapshot;if("reference"===e.kind){const n=t.templates.find((t=>t.id===e.id));if(!n)return;return n}return e}function d(e,t,n){const r={x:Math.min(t.x,n.x),y:Math.min(t.y,n.y),width:Math.abs(t.x-n.x),height:Math.abs(t.y-n.y)};for(let t=0;tf(e,t))):(e=function(e,t){if(!t.rotate)return e;const n=t.x+t.width/2,o=t.y+t.height/2;return(0,r.rotatePositionByCenter)(e,{x:n,y:o},t.rotate)}(e,t),e.x>=t.x&&e.y>=t.y&&e.x<=t.x+t.width&&e.y<=t.y+t.height)}const g=14;function h(e,t,n){const r=g/n;for(let n=e.templates.length-1;n>=0;n--){const o=e.templates[n];if(o.name&&f(t,{x:o.x,y:o.y-r,width:r*o.name.length,height:r}))return[n];for(const r of m(o,o,e,[],[]))if(f(t,r))return[n,...r.path];if(f(t,o))return[n]}}function*m(e,t,n,o,i){var s,c,l;for(let u=e.contents.length-1;u>=0;u--){const d=e.contents[u],f=[...i,u];let g=t.x+d.x,h=t.y+d.y;if("snapshot"===d.kind){const e=[{rotate:null!=(s=d.rotate)?s:0,x:g+d.snapshot.width/2,y:h+d.snapshot.height/2},...o];yield*a(m(d.snapshot,{x:g,y:h},n,e,f))}const{width:y,height:v}=null!=(c=p(d,n))?c:{width:0,height:0};let x={x:g+y/2,y:h+v/2},b=null!=(l=d.rotate)?l:0;for(const e of o)b+=e.rotate,x=(0,r.rotatePositionByCenter)(x,e,-e.rotate);g=x.x-y/2,h=x.y-v/2,yield{x:g,y:h,rotate:b,width:y,height:v,path:f}}}function y(e,t){var n,o;let i={x:e.template.x,y:e.template.y};const a=[];for(const t of e.parents)"snapshot"===t.kind&&(i.x+=t.x,i.y+=t.y,a.unshift({rotate:null!=(n=t.rotate)?n:0,x:i.x+t.snapshot.width/2,y:i.y+t.snapshot.height/2}));const{width:s,height:c}=null!=(o=p(e.content,t))?o:{width:0,height:0};i.x+=e.content.x+s/2,i.y+=e.content.y+c/2;for(const e of a)i=(0,r.rotatePositionByCenter)(i,e,-e.rotate);return i}},3464:(e,t,n)=>{"use strict";n.d(t,{default:()=>a});var r=n(3696),o=n.n(r),i=n(9758);const a=()=>{const[e,t]=o().useState(0),[n,r]=o().useState(0),{offset:a,onStart:s,mask:c,resetDragMove:l}=(0,i.useDragMove)((()=>{t((e=>e+a.x)),r((e=>e+a.y))}));return(0,i.useGlobalKeyDown)((e=>{"Escape"===e.key&&l()})),o().createElement("div",{style:{width:"300px",height:"300px",overflow:"hidden",position:"absolute",display:"flex",alignItems:"center",justifyContent:"center",border:"1px solid green"}},o().createElement("div",{style:{width:"800px",height:"800px",position:"absolute",transform:`translate(${e+a.x}px, ${n+a.y}px)`,background:"radial-gradient(50% 50% at 50% 50%, red 0%, white 100%)",cursor:"grab"},onMouseDown:e=>s({x:e.clientX,y:e.clientY})}),c)}},7215:(e,t,n)=>{"use strict";n.d(t,{default:()=>s});var r=n(8662),o=n(3696),i=n.n(o),a=n(9758);const s=()=>{const[e,t]=i().useState({x:200,y:200,width:100,height:100}),{offset:n,onStart:o,mask:s,resetDragResize:c}=(0,a.useDragResize)((()=>t(l)),{centeredScaling:e=>e.shiftKey,keepRatio:t=>(0,a.metaKeyIfMacElseCtrlKey)(t)?e.width/e.height:void 0,transformOffset:(t,n)=>(t.width+e.width<0&&(t.width=-e.width,t.x=Math.min(t.x,e.width*((null==n?void 0:n.shiftKey)?.5:1))),t.height+e.height<0&&(t.height=-e.height,t.y=Math.min(t.y,e.height*((null==n?void 0:n.shiftKey)?.5:1))),t)});(0,a.useGlobalKeyDown)((e=>{"Escape"===e.key&&c()}));const l=(0,r.produce)(e,(e=>{e.width+=n.width,e.height+=n.height,e.x+=n.x,e.y+=n.y}));return i().createElement(i().Fragment,null,i().createElement("div",{style:{width:`${l.width}px`,height:`${l.height}px`,left:`${l.x}px`,top:`${l.y}px`,boxSizing:"border-box",position:"absolute",background:"radial-gradient(50% 50% at 50% 50%, red 0%, white 100%)"}},i().createElement(a.ResizeBar,{onMouseDown:o})),s)}},4874:(e,t,n)=>{"use strict";n.d(t,{default:()=>s});var r=n(8662),o=n(3696),i=n.n(o),a=n(9758);const s=()=>{const[e,t]=i().useState({x:200,y:200,width:100,height:100,rotate:0,url:"https://interactive-examples.mdn.mozilla.net/media/cc0-images/grapefruit-slice-332-332.jpg"}),{offset:n,onStart:o,mask:s,resetDragRotate:c}=(0,a.useDragRotate)((()=>t(l)),{transformOffset:(e,t)=>{if(t&&void 0!==e&&!t.shiftKey){const t=45*Math.round(e/45);Math.abs(t-e)<5&&(e=t)}return e}});(0,a.useGlobalKeyDown)((e=>{"Escape"===e.key&&c()}));const l=(0,r.produce)(e,(e=>{void 0!==(null==n?void 0:n.angle)&&(e.rotate=n.angle)}));return i().createElement(i().Fragment,null,i().createElement("div",{style:{width:`${e.width}px`,height:`${e.width}px`,left:`${e.x}px`,top:`${e.y}px`,boxSizing:"border-box",position:"absolute",transform:`rotate(${l.rotate}deg)`,background:`url(${e.url})`,backgroundSize:"contain"}},i().createElement(a.RotationBar,{onMouseDown:()=>o({x:e.x+e.width/2,y:e.y+e.height/2})})),s)}},3191:(e,t,n)=>{"use strict";n.d(t,{default:()=>s});var r=n(8662),o=n(3696),i=n.n(o),a=n(9758);const s=()=>{const[e,t]=i().useState([]),{onStartSelect:n,dragSelectMask:o,resetDragSelect:s}=(0,a.useDragSelect)(((n,o)=>{o&&t((0,r.produce)(e,(e=>{e.push({x:Math.min(n.x,o.x),y:Math.min(n.y,o.y),width:Math.abs(o.x-n.x),height:Math.abs(o.y-n.y)})})))}),(e=>e.shiftKey));return(0,a.useGlobalKeyDown)((e=>{"Escape"===e.key&&s()})),i().createElement("div",{onMouseDown:e=>n(e,void 0),style:{height:"100%"}},e.map(((e,t)=>i().createElement("div",{key:t,style:{width:`${e.width}px`,height:`${e.height}px`,left:`${e.x}px`,top:`${e.y}px`,position:"absolute",border:"1px solid green"}}))),o)}},9612:(e,t,n)=>{"use strict";n.d(t,{default:()=>a});var r=n(3696),o=n.n(r),i=n(9758);const a=()=>{var e;const[t,n]=o().useState({x:300,y:200,r:100}),{editPoint:r,updateEditPreview:a,onEditMove:s,onEditClick:c,getEditAssistentContents:l,resetEdit:u}=(0,i.useEdit)((()=>n(f)),(e=>({editPoints:[{x:e.x,y:e.y,cursor:"move",update(e,{cursor:t,start:n}){e.x+=t.x-n.x,e.y+=t.y-n.y}},{x:e.x-e.r,y:e.y,cursor:"ew-resize",update(e,{cursor:t}){e.r=(0,i.getTwoPointsDistance)(t,e)}},{x:e.x,y:e.y-e.r,cursor:"ns-resize",update(e,{cursor:t}){e.r=(0,i.getTwoPointsDistance)(t,e)}},{x:e.x+e.r,y:e.y,cursor:"ew-resize",update(e,{cursor:t}){e.r=(0,i.getTwoPointsDistance)(t,e)}},{x:e.x,y:e.y+e.r,cursor:"ns-resize",update(e,{cursor:t}){e.r=(0,i.getTwoPointsDistance)(t,e)}}]})));(0,i.useGlobalKeyDown)((e=>{"Escape"===e.key&&u()}));const p=[],d=a(),f=null!=(e=null==d?void 0:d.result)?e:t;return p.push(...l(f,(e=>e))),o().createElement(o().Fragment,null,o().createElement("svg",{viewBox:"0 0 800 600",width:800,height:600,xmlns:"http://www.w3.org/2000/svg",fill:"none",style:{position:"absolute",left:0,top:0,cursor:null==r?void 0:r.cursor},onMouseMove:e=>s({x:e.clientX,y:e.clientY},[{content:f,path:[0]}]),onClick:e=>r&&c({x:e.clientX,y:e.clientY})},o().createElement("circle",{cx:f.x,cy:f.y,r:f.r,stroke:"#00ff00"}),p.map(((e,t)=>o().createElement("rect",{key:t,x:e.x-e.width/2,y:e.y-e.height/2,width:e.width,height:e.height,stroke:"#00ff00",fill:"#ffffff"})))))}},2071:(e,t,n)=>{"use strict";n.d(t,{default:()=>c});var r=n(8662),o=n(3696),i=n.n(o),a=n(9758),s=n(4469);const c=()=>{const[e,t]=i().useState([]),{ellipse:n,ellipseArc:o,onClick:c,onMove:l,input:u,reset:p}=(0,a.useEllipseArcClickCreate)("ellipse center",(n=>{t((0,r.produce)(e,(e=>{e.push(n)})))}));(0,a.useGlobalKeyDown)((e=>{"Escape"===e.key&&p()}));const d=n||o;return i().createElement("div",{onClick:e=>c({x:e.clientX,y:e.clientY}),onMouseMove:e=>l({x:e.clientX,y:e.clientY}),style:{height:"100%"}},i().createElement("svg",{viewBox:"0 0 800 600",width:800,height:600,xmlns:"http://www.w3.org/2000/svg",fill:"none",style:{position:"absolute",left:0,top:0},onClick:e=>c({x:e.clientX,y:e.clientY}),onMouseMove:e=>l({x:e.clientX,y:e.clientY})},d&&i().createElement("ellipse",{stroke:"#00ff00",cx:d.cx,cy:d.cy,rx:d.rx,ry:d.ry,transform:d.angle?`rotate(${d.angle},${d.cx},${d.cy})`:void 0,strokeDasharray:"4"}),[...e,o].map(((e,t)=>{if(e){const n=(0,a.ellipseArcToPolyline)(e,s.defaultAngleDelta);return i().createElement("polyline",{key:t,points:n.map((e=>`${e.x},${e.y}`)).join(" "),stroke:"#00ff00"})}return null}))),u)}},7258:(e,t,n)=>{"use strict";n.d(t,{default:()=>y});var r=n(8662),o=n(3696),i=n.n(o),a=n(9758),s=n(4469),c=Object.defineProperty,l=Object.defineProperties,u=Object.getOwnPropertyDescriptors,p=Object.getOwnPropertySymbols,d=Object.prototype.hasOwnProperty,f=Object.prototype.propertyIsEnumerable,g=(e,t,n)=>t in e?c(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,h=(e,t)=>{for(var n in t||(t={}))d.call(t,n)&&g(e,n,t[n]);if(p)for(var n of p(t))f.call(t,n)&&g(e,n,t[n]);return e},m=(e,t)=>l(e,u(t));const y=()=>{const[e,t]=i().useState({cx:200,cy:200,rx:100,ry:150,angle:45,startAngle:-30,endAngle:120}),{offset:n,onStart:o,mask:c,reset:l}=(0,a.useEllipseArcEdit)((()=>t(u))),u=(0,r.produce)(e,(e=>{n&&(e.cx+=n.cx,e.cy+=n.cy,e.rx+=n.rx,e.ry+=n.ry,e.startAngle+=n.startAngle,e.endAngle+=n.endAngle,(0,a.normalizeAngleRange)(e))}));(0,a.useGlobalKeyDown)((e=>{"Escape"===e.key&&l()}));const p=(0,a.ellipseArcToPolyline)(u,s.defaultAngleDelta);return i().createElement(i().Fragment,null,i().createElement("svg",{viewBox:"0 0 800 600",width:800,height:600,xmlns:"http://www.w3.org/2000/svg",fill:"none",style:{position:"absolute",left:0,top:0}},i().createElement("polyline",{points:p.map((e=>`${e.x},${e.y}`)).join(" "),stroke:"#00ff00"})),i().createElement(a.EllipseArcEditBar,m(h({},u),{onMouseDown:(e,t,n)=>o(e,m(h({},u),{type:t,cursor:n}))})),c)}},2682:(e,t,n)=>{"use strict";n.d(t,{default:()=>s});var r=n(8662),o=n(3696),i=n.n(o),a=n(9758);const s=()=>{const[e,t]=i().useState([]),{ellipse:n,onClick:o,onMove:s,input:c,reset:l}=(0,a.useEllipseClickCreate)("ellipse center",(n=>{t((0,r.produce)(e,(e=>{e.push(n)})))}));return(0,a.useGlobalKeyDown)((e=>{"Escape"===e.key&&l()})),i().createElement("div",{style:{height:"100%"}},i().createElement("svg",{viewBox:"0 0 800 600",width:800,height:600,xmlns:"http://www.w3.org/2000/svg",fill:"none",style:{position:"absolute",left:0,top:0},onClick:e=>o({x:e.clientX,y:e.clientY}),onMouseMove:e=>s({x:e.clientX,y:e.clientY})},[...e,n].map(((e,t)=>e&&i().createElement("ellipse",{key:t,stroke:"#00ff00",cx:e.cx,cy:e.cy,rx:e.rx,ry:e.ry,transform:e.angle?`rotate(${e.angle},${e.cx},${e.cy})`:void 0})))),c)}},1783:(e,t,n)=>{"use strict";n.d(t,{default:()=>m});var r=n(8662),o=n(3696),i=n.n(o),a=n(9758),s=Object.defineProperty,c=Object.defineProperties,l=Object.getOwnPropertyDescriptors,u=Object.getOwnPropertySymbols,p=Object.prototype.hasOwnProperty,d=Object.prototype.propertyIsEnumerable,f=(e,t,n)=>t in e?s(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,g=(e,t)=>{for(var n in t||(t={}))p.call(t,n)&&f(e,n,t[n]);if(u)for(var n of u(t))d.call(t,n)&&f(e,n,t[n]);return e},h=(e,t)=>c(e,l(t));const m=()=>{const[e,t]=i().useState({cx:200,cy:200,rx:100,ry:150,angle:45}),{offset:n,onStart:o,mask:s,reset:c}=(0,a.useEllipseEdit)((()=>t(l))),l=(0,r.produce)(e,(e=>{n&&(e.cx+=n.cx,e.cy+=n.cy,e.rx+=n.rx,e.ry+=n.ry)}));return(0,a.useGlobalKeyDown)((e=>{"Escape"===e.key&&c()})),i().createElement(i().Fragment,null,i().createElement("svg",{viewBox:"0 0 800 600",width:800,height:600,xmlns:"http://www.w3.org/2000/svg",fill:"none",style:{position:"absolute",left:0,top:0}},i().createElement("ellipse",{stroke:"#00ff00",cx:l.cx,cy:l.cy,rx:l.rx,ry:l.ry,transform:l.angle?`rotate(${l.angle},${l.cx},${l.cy})`:void 0})),i().createElement(a.EllipseEditBar,h(g({},l),{onMouseDown:(e,t,n)=>o(e,h(g({},l),{type:t,cursor:n}))})),s)}},5090:(e,t,n)=>{"use strict";n.d(t,{default:()=>s});var r=n(3031),o=n(3696),i=n.n(o),a=n(9758);const s=()=>{const[e,t]=i().useState("X1 ** 2 + X2 * X3"),[n,o]=i().useState("(-X6) ** 0.5 / (X4 - X5 ** 3)"),[s,c]=i().useState(),[l,u]=i().useState(!1);return i().useEffect((()=>{try{c({left:(0,r.parseExpression)((0,r.tokenizeExpression)(e)),right:(0,r.parseExpression)((0,r.tokenizeExpression)(n))})}catch(e){console.info(e)}}),[e,n]),i().createElement("div",null,i().createElement(a.ExpressionEditor,{value:e,setValue:t,validate:a.validateExpression}),i().createElement(a.ExpressionEditor,{value:n,setValue:o,validate:a.validateExpression}),i().createElement("label",null,i().createElement("input",{type:"checkbox",checked:l,onChange:()=>u(!l)}),"keep binary expression order"),s&&(0,a.renderEquation)(a.reactSvgRenderTarget,s,{keepBinaryExpressionOrder:l}),s&&i().createElement("code",null,(0,a.printEquation)(s,{keepBinaryExpressionOrder:l})))}},6690:(e,t,n)=>{"use strict";n.d(t,{default:()=>g});var r=n(3031),o=n(3696),i=n.n(o),a=n(9758),s=Object.defineProperty,c=Object.defineProperties,l=Object.getOwnPropertyDescriptors,u=Object.getOwnPropertySymbols,p=Object.prototype.hasOwnProperty,d=Object.prototype.propertyIsEnumerable,f=(e,t,n)=>t in e?s(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n;const g=()=>{const{value:e,update:t,getArrayProps:n}=(0,a.useJsonEditorData)([{equation:"a * x + b * y = c",variable:"x"},{equation:"x ** 2 + y ** 2 = r",variable:"y"}]),[o,s]=i().useState(!1),[g,h]=i().useState([]),[m,y]=i().useState(!1),[v,x]=i().useState(!1);return i().useEffect((()=>{try{const t=(0,a.solveEquations)(e.map((e=>{const t=e.equation.split("=");return{left:(0,r.parseExpression)((0,r.tokenizeExpression)(o?(0,a.mathStyleExpressionToExpression)(t[0]):t[0])),right:(0,r.parseExpression)((0,r.tokenizeExpression)(o?(0,a.mathStyleExpressionToExpression)(t[1]):t[1]))}})),new Set(e.map((e=>e.variable))));h(t.map((e=>Object.entries(e).map((([e,t])=>Array.isArray(t)?{left:t[0],right:t[1]}:{left:{type:"Identifier",name:e},right:t})))))}catch(e){console.info(e)}}),[e,o]),i().createElement("div",null,i().createElement(a.ObjectArrayEditor,(b=((e,t)=>{for(var n in t||(t={}))p.call(t,n)&&f(e,n,t[n]);if(u)for(var n of u(t))d.call(t,n)&&f(e,n,t[n]);return e})({},n((e=>e),{equation:"x = 1",variable:"x"})),C={properties:e.map(((e,n)=>({equation:i().createElement(a.ExpressionEditor,{value:e.equation,setValue:t(((e,t)=>e[n].equation=t)),height:20,width:400,autoHeight:!0}),variable:i().createElement(a.StringEditor,{style:{width:"30px"},value:e.variable,setValue:t(((e,t)=>e[n].variable=t))})})))},c(b,l(C)))),i().createElement("label",null,i().createElement("input",{type:"checkbox",checked:o,onChange:()=>s(!o)}),"math style expression"),i().createElement("label",null,i().createElement("input",{type:"checkbox",checked:m,onChange:()=>y(!m)}),"keep binary expression order"),i().createElement("label",null,i().createElement("input",{type:"checkbox",checked:v,onChange:()=>x(!v)}),"show text"),g.map(((e,t)=>i().createElement("div",{key:t,style:{borderBottom:"1px solid black",display:"flex",flexDirection:"column"}},e.map(((e,t)=>i().createElement(i().Fragment,{key:t},!v&&(0,a.renderEquation)(a.reactSvgRenderTarget,e,{keepBinaryExpressionOrder:m}),v&&i().createElement("div",null,i().createElement("code",null,(0,a.printEquation)(e,{keepBinaryExpressionOrder:m}))))))))),o&&g.map(((e,t)=>i().createElement("div",{key:t,style:{borderBottom:"1px solid black",display:"flex",flexDirection:"column"}},e.map(((e,t)=>i().createElement("div",{key:t},i().createElement("code",null,(0,a.printMathStyleExpression)(e.left)," = ",(0,a.printMathStyleExpression)(e.right)))))))));var b,C}},8673:(e,t,n)=>{"use strict";n.d(t,{default:()=>m});var r=n(3696),o=n.n(r),i=n(9758),a=n(3031),s=Object.defineProperty,c=Object.defineProperties,l=Object.getOwnPropertyDescriptors,u=Object.getOwnPropertySymbols,p=Object.prototype.hasOwnProperty,d=Object.prototype.propertyIsEnumerable,f=(e,t,n)=>t in e?s(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,g=(e,t)=>{for(var n in t||(t={}))p.call(t,n)&&f(e,n,t[n]);if(u)for(var n of u(t))d.call(t,n)&&f(e,n,t[n]);return e},h=(e,t)=>c(e,l(t));const m=()=>{const{value:e,update:t,getArrayProps:n}=(0,i.useJsonEditorData)(["sin(x)"]),[r,s]=o().useState(),[c,l]=o().useState(0),[u,p]=o().useState(10),[d,f]=o().useState(!0),[m,y]=o().useState([]),[v,x]=o().useState(),b=(0,i.useWindowSize)().width/2,C=i.reactSvgRenderTarget,[E,P]=o().useState(),w=e=>(0,a.parseExpression)((0,a.tokenizeExpression)(d?(0,i.mathStyleExpressionToExpression)(e):e));let k;return E&&(k=E.children,r&&(k=[...E.children,...(0,i.renderChartTooltip)(C,r,r.value)])),o().createElement("div",{style:{position:"absolute",inset:"0px"}},E&&k&&o().createElement("div",null,C.renderResult(k,b,300,{attributes:{onMouseMove:e=>s(E.select({x:e.clientX,y:e.clientY}))}})),o().createElement("div",{style:{margin:"10px"}},o().createElement(i.ArrayEditor,h(g({},n((e=>e),"")),{inline:!0,style:{width:"calc(50% - 30px)"},items:e.map(((e,n)=>o().createElement(i.StringEditor,{style:{height:"50px"},textarea:!0,value:e,setValue:t(((e,t)=>e[n]=t))})))})),o().createElement("div",null,o().createElement("label",null,o().createElement("input",{type:"checkbox",checked:d,onChange:()=>f(!d)}),"input math style expression")),o().createElement("div",null,o().createElement(i.NumberEditor,{style:{width:"50px"},value:c,setValue:l}),"~",o().createElement(i.NumberEditor,{style:{width:"50px"},value:u,setValue:p})),o().createElement(i.Button,{disabled:0===e.length,onClick:()=>{try{if(0===e.length)return;const t=[],n=(u-c)/100,r=(0,i.getTwoNumberCenter)(c,u),o={sin:Math.sin,cos:Math.cos,tan:Math.tan,ln:Math.log,sqrt:Math.sqrt},s=[];for(const l of e){if(!l)continue;const e=[],p=w(l),d=(0,i.expressionToFactors)(p);if(d){const e=(0,i.factorsToEquationParams)(d,"x");e&&s.push(...(0,i.calculateEquation5)(e,r,i.delta1))}const f=w((0,a.printExpression)((0,i.optimizeExpression)((0,i.deriveExpressionWith)(p,"x"),(e=>(0,i.expressionHasVariable)(e,"x"))))),m=(0,i.newtonIterate)(r,(e=>{try{const t=(0,a.evaluateExpression)(p,h(g({},o),{x:e}));return"number"==typeof t?t:NaN}catch(e){return NaN}}),(e=>{try{const t=(0,a.evaluateExpression)(f,h(g({},o),{x:e}));return"number"==typeof t?t:NaN}catch(e){return NaN}}),i.delta1);void 0!==m&&s.every((e=>!(0,i.isSameNumber)(e,m)))&&s.push(m);for(let t=c;t<=u;t+=n){const n=(0,a.evaluateExpression)(p,h(g({},o),{x:t}));"number"!=typeof n||isNaN(n)||e.push({x:t,y:n})}e.length>0&&t.push(e)}y(s);const l=t.flat().map((e=>e.y)),p=Math.min(...l),d=Math.max(...l),f=s.filter((e=>(0,i.isBetween)(e,c,u))).map((e=>[{x:e,y:p},{x:e,y:d}])),m=(0,i.getLineChart)([[{x:c,y:0},{x:u,y:0}],...f,...t],C,{x:.01,y:.01},{width:b,height:300},{left:25,right:25,top:10,bottom:20},{xLabelDisabled:!0,yLabelDisabled:!0});if(!m)return;const{points:[v,...E],children:k,select:_}=m;k.push(C.renderPolyline(v,{strokeColor:65280}));for(let e=0;eo().createElement("div",{key:t,style:{border:"1px solid black",maxHeight:"150px",overflowY:"auto",position:"relative"}},o().createElement("code",{key:t},"x = ",e)))),v&&o().createElement("div",null,v)))}},6808:(e,t,n)=>{"use strict";n.d(t,{default:()=>s});var r=n(3696),o=n.n(r),i=n(9758),a=n(5358);const s=()=>{const[e,t]=o().useState("1 + 2 - 3");return o().createElement(i.ExpressionEditor,{suggestionSources:a.math,value:e,setValue:t,validate:i.validateExpression})}},2458:(e,t,n)=>{"use strict";n.d(t,{default:()=>s});var r=n(3696),o=n.n(r),i=n(9758),a=n(3031);const s=()=>{const[e,t]=o().useState("(x + a)^3"),[n,r]=o().useState("x"),[s,c]=o().useState(""),[l,u]=o().useState(!0),[p,d]=o().useState(!0),[f,g]=o().useState(),[h,m]=o().useState(),[y,v]=o().useState(),x=e=>(0,a.parseExpression)((0,a.tokenizeExpression)(l?(0,i.mathStyleExpressionToExpression)(e):e)),b=e=>p?(0,i.printMathStyleExpression)(e):(0,a.printExpression)(e),C=t=>{try{if(!n)return;if(!e)return;const r=x(e),o=(0,i.taylorExpandExpressionWith)(r,n,+s||5,t);v(o),g(void 0)}catch(e){g(String(e)),v(void 0)}},E=e=>{t(e),g(void 0),m(void 0),v(void 0)};return o().createElement("div",null,o().createElement(i.StringEditor,{style:{width:"calc(100% - 30px)",height:"150px"},textarea:!0,value:e,setValue:E}),o().createElement("div",null,o().createElement("label",null,o().createElement("input",{type:"checkbox",checked:l,onChange:()=>u(!l)}),"input math style expression"),o().createElement("label",null,o().createElement("input",{type:"checkbox",checked:p,onChange:()=>d(!p)}),"output math style expression")),o().createElement("div",null,o().createElement(i.StringEditor,{style:{width:"50px"},value:n,setValue:r}),"=",o().createElement(i.StringEditor,{style:{width:"calc(100% - 115px)"},value:s,setValue:c})),o().createElement(i.Button,{disabled:!e,onClick:()=>{try{if(!e)return;const t=(0,i.expandExpression)(x(e));let n=(0,i.expressionToFactors)(t);n?(n=(0,i.optimizeFactors)(n),(0,i.sortFactors)(n),m(n),v(void 0)):(v(t),m(void 0)),g(void 0)}catch(e){console.info(e),g(String(e)),m(void 0),v(void 0)}}},"expand all"),o().createElement(i.Button,{disabled:!n||!h,onClick:()=>{try{if(!n)return;if(!h)return;const e=x(n),t=(0,i.expressionToFactors)(e);if(t){const e=(0,i.divideFactors)(h,t);e&&m(e)}g(void 0)}catch(e){g(String(e))}}},"divide by"),o().createElement(i.Button,{disabled:!n||!h,onClick:()=>{try{if(!n)return;if(!h)return;const e=x(n),t=(0,i.expressionToFactors)(e);if(t&&1===t.length){const e=(0,i.groupFactorsBy)(h,t[0]);e&&v(e)}g(void 0)}catch(e){g(String(e))}}},"group by"),o().createElement(i.Button,{disabled:!e||!n||!s,onClick:()=>{try{if(!n)return;if(!s)return;if(!e)return;const t=x(e),r=x(s),o=(0,i.composeExpression)(t,{[n]:r});o&&v(o),g(void 0)}catch(e){g(String(e))}}},"replace with"),o().createElement(i.Button,{disabled:!e,onClick:()=>{try{if(!e)return;const t=x(e);v(t),g(void 0)}catch(e){g(String(e)),v(void 0)}}},"format style"),o().createElement(i.Button,{disabled:!h,onClick:()=>{h&&v((0,i.groupAllFactors)(h))}},"group all"),o().createElement(i.Button,{disabled:!e||!n,onClick:()=>{try{if(!n)return;if(!e)return;const t=x(e),r=(0,i.optimizeExpression)((0,i.deriveExpressionWith)(t,n),(e=>(0,i.expressionHasVariable)(e,n)));v(r),g(void 0)}catch(e){g(String(e)),v(void 0)}}},"derive with"),o().createElement(i.Button,{disabled:!e,onClick:()=>{try{if(!e)return;const t=x(e),n=(0,i.optimizeExpression)(t);v(n),g(void 0)}catch(e){g(String(e)),v(void 0)}}},"optimize"),o().createElement(i.Button,{disabled:!n||!h,onClick:()=>{try{if(!n)return;if(!h)return;const e=x(n),t=(0,i.expressionToFactors)(e);if(t&&1===t.length){const e=(0,i.groupFactorsByVariables)(h,t[0].variables.filter((e=>"string"==typeof e)));e&&v(e)}g(void 0)}catch(e){g(String(e))}}},"group by variables"),o().createElement(i.Button,{disabled:!e||!n,onClick:()=>C(!1)},"taylor expand"),o().createElement(i.Button,{disabled:!e||!n,onClick:()=>C(!0)},"primary function"),h&&h.length>0&&o().createElement("div",{style:{border:"1px solid black",maxHeight:"150px",overflowY:"auto",marginBottom:"5px"}},h.map(((e,t)=>o().createElement("div",{key:t},o().createElement("code",null,b((0,i.factorToExpression)(e))))))),h&&o().createElement("div",{style:{border:"1px solid black",maxHeight:"150px",overflowY:"auto",marginBottom:"5px",position:"relative"}},o().createElement("code",null,b((0,i.factorsToExpression)(h))),o().createElement(i.Button,{style:{position:"absolute",right:0,top:0,background:"wheat"},onClick:()=>navigator.clipboard.writeText(b((0,i.factorsToExpression)(h)))},"copy"),o().createElement(i.Button,{style:{position:"absolute",right:65,top:0,background:"wheat"},onClick:()=>E(b((0,i.factorsToExpression)(h)))},"edit")),y&&o().createElement("div",{style:{border:"1px solid black",maxHeight:"150px",overflowY:"auto",position:"relative"}},o().createElement("code",null,b(y)),o().createElement(i.Button,{style:{position:"absolute",right:0,top:0,background:"wheat"},onClick:()=>navigator.clipboard.writeText(b(y))},"copy"),o().createElement(i.Button,{style:{position:"absolute",right:65,top:0,background:"wheat"},onClick:()=>E(b(y))},"edit")),y&&(0,i.renderExpression)(i.reactSvgRenderTarget,y),f&&o().createElement("div",null,f))}},5358:(e,t,n)=>{"use strict";n.d(t,{math:()=>r});const r=[{name:"Math",members:[{name:"E",comment:"The mathematical constant e. This is Euler's number, the base of natural logarithms."},{name:"LN10",comment:"The natural logarithm of 10."},{name:"LN2",comment:"The natural logarithm of 2."},{name:"LOG2E",comment:"The base-2 logarithm of e."},{name:"LOG10E",comment:"The base-10 logarithm of e."},{name:"PI",comment:"Pi. This is the ratio of the circumference of a circle to its diameter."},{name:"SQRT1_2",comment:"The square root of 0.5, or, equivalently, one divided by the square root of 2."},{name:"SQRT2",comment:"The square root of 2."},{name:"abs",comment:"Returns the absolute value of a number (the value without regard to whether it is positive or negative).\r\nFor example, the absolute value of -5 is the same as the absolute value of 5.",parameters:[{name:"x",comment:"A numeric expression for which the absolute value is needed.",optional:!1}]},{name:"acos",comment:"Returns the arc cosine (or inverse cosine) of a number.",parameters:[{name:"x",comment:"A numeric expression.",optional:!1}]},{name:"asin",comment:"Returns the arcsine of a number.",parameters:[{name:"x",comment:"A numeric expression.",optional:!1}]},{name:"atan",comment:"Returns the arctangent of a number.",parameters:[{name:"x",comment:"A numeric expression for which the arctangent is needed.",optional:!1}]},{name:"atan2",comment:"Returns the angle (in radians) from the X axis to a point.",parameters:[{name:"y",comment:"A numeric expression representing the cartesian y-coordinate.",optional:!1},{name:"x",comment:"A numeric expression representing the cartesian x-coordinate.",optional:!1}]},{name:"ceil",comment:"Returns the smallest integer greater than or equal to its numeric argument.",parameters:[{name:"x",comment:"A numeric expression.",optional:!1}]},{name:"cos",comment:"Returns the cosine of a number.",parameters:[{name:"x",comment:"A numeric expression that contains an angle measured in radians.",optional:!1}]},{name:"exp",comment:"Returns e (the base of natural logarithms) raised to a power.",parameters:[{name:"x",comment:"A numeric expression representing the power of e.",optional:!1}]},{name:"floor",comment:"Returns the greatest integer less than or equal to its numeric argument.",parameters:[{name:"x",comment:"A numeric expression.",optional:!1}]},{name:"log",comment:"Returns the natural logarithm (base e) of a number.",parameters:[{name:"x",comment:"A numeric expression.",optional:!1}]},{name:"max",comment:"Returns the larger of a set of supplied numeric expressions.",parameters:[{name:"values",comment:"Numeric expressions to be evaluated.",optional:!1}]},{name:"min",comment:"Returns the smaller of a set of supplied numeric expressions.",parameters:[{name:"values",comment:"Numeric expressions to be evaluated.",optional:!1}]},{name:"pow",comment:"Returns the value of a base expression taken to a specified power.",parameters:[{name:"x",comment:"The base value of the expression.",optional:!1},{name:"y",comment:"The exponent value of the expression.",optional:!1}]},{name:"random",comment:"Returns a pseudorandom number between 0 and 1.",parameters:[]},{name:"round",comment:"Returns a supplied numeric expression rounded to the nearest integer.",parameters:[{name:"x",comment:"The value to be rounded to the nearest integer.",optional:!1}]},{name:"sin",comment:"Returns the sine of a number.",parameters:[{name:"x",comment:"A numeric expression that contains an angle measured in radians.",optional:!1}]},{name:"sqrt",comment:"Returns the square root of a number.",parameters:[{name:"x",comment:"A numeric expression.",optional:!1}]},{name:"tan",comment:"Returns the tangent of a number.",parameters:[{name:"x",comment:"A numeric expression that contains an angle measured in radians.",optional:!1}]},{name:"clz32",comment:"Returns the number of leading zero bits in the 32-bit binary representation of a number.",parameters:[{name:"x",comment:"A numeric expression.",optional:!1}]},{name:"imul",comment:"Returns the result of 32-bit multiplication of two numbers.",parameters:[{name:"x",comment:"First number",optional:!1},{name:"y",comment:"Second number",optional:!1}]},{name:"sign",comment:"Returns the sign of the x, indicating whether x is positive, negative or zero.",parameters:[{name:"x",comment:"The numeric expression to test",optional:!1}]},{name:"log10",comment:"Returns the base 10 logarithm of a number.",parameters:[{name:"x",comment:"A numeric expression.",optional:!1}]},{name:"log2",comment:"Returns the base 2 logarithm of a number.",parameters:[{name:"x",comment:"A numeric expression.",optional:!1}]},{name:"log1p",comment:"Returns the natural logarithm of 1 + x.",parameters:[{name:"x",comment:"A numeric expression.",optional:!1}]},{name:"expm1",comment:"Returns the result of (e^x - 1), which is an implementation-dependent approximation to\r\nsubtracting 1 from the exponential function of x (e raised to the power of x, where e\r\nis the base of the natural logarithms).",parameters:[{name:"x",comment:"A numeric expression.",optional:!1}]},{name:"cosh",comment:"Returns the hyperbolic cosine of a number.",parameters:[{name:"x",comment:"A numeric expression that contains an angle measured in radians.",optional:!1}]},{name:"sinh",comment:"Returns the hyperbolic sine of a number.",parameters:[{name:"x",comment:"A numeric expression that contains an angle measured in radians.",optional:!1}]},{name:"tanh",comment:"Returns the hyperbolic tangent of a number.",parameters:[{name:"x",comment:"A numeric expression that contains an angle measured in radians.",optional:!1}]},{name:"acosh",comment:"Returns the inverse hyperbolic cosine of a number.",parameters:[{name:"x",comment:"A numeric expression that contains an angle measured in radians.",optional:!1}]},{name:"asinh",comment:"Returns the inverse hyperbolic sine of a number.",parameters:[{name:"x",comment:"A numeric expression that contains an angle measured in radians.",optional:!1}]},{name:"atanh",comment:"Returns the inverse hyperbolic tangent of a number.",parameters:[{name:"x",comment:"A numeric expression that contains an angle measured in radians.",optional:!1}]},{name:"hypot",comment:"Returns the square root of the sum of squares of its arguments.",parameters:[{name:"values",comment:"Values to compute the square root for.\r\nIf no arguments are passed, the result is +0.\r\nIf there is only one argument, the result is the absolute value.\r\nIf any argument is +Infinity or -Infinity, the result is +Infinity.\r\nIf any argument is NaN, the result is NaN.\r\nIf all arguments are either +0 or −0, the result is +0.",optional:!1}]},{name:"trunc",comment:"Returns the integral part of the a numeric expression, x, removing any fractional digits.\r\nIf x is already an integer, the result is x.",parameters:[{name:"x",comment:"A numeric expression.",optional:!1}]},{name:"fround",comment:"Returns the nearest single precision float representation of a number.",parameters:[{name:"x",comment:"A numeric expression.",optional:!1}]},{name:"cbrt",comment:"Returns an implementation-dependent approximation to the cube root of number.",parameters:[{name:"x",comment:"A numeric expression.",optional:!1}]}]}]},8859:(e,t,n)=>{"use strict";n.d(t,{default:()=>s});var r=n(8662),o=n(3696),i=n.n(o),a=n(9758);const s=()=>{const[e,t]=i().useState((()=>new Array(3).fill(0).map((()=>({children:new Array(20).fill(0).map((()=>({radius:5+Math.round(20*Math.random()),color:Math.round(16777215*Math.random())}))),blockStart:5,blockEnd:5}))))),[n,o]=i().useState("left"),[s,c]=i().useState("top"),{renderEditor:l,layoutResult:u,lineHeights:p,isSelected:d,actualHeight:f,inputContent:g,inputInline:h,getCopiedContents:m}=(0,a.useFlowLayoutBlockEditor)({state:e,setState:n=>t((0,r.produce)(e,n)),width:400,height:400,lineHeight:e=>2*e.radius,getWidth:e=>2*e.radius,endContent:{radius:0,color:0},isNewLineContent:e=>0===e.radius,align:n,verticalAlign:s,processInput(e){if((0,a.metaKeyIfMacElseCtrlKey)(e)){if("v"===e.key)return navigator.clipboard.readText().then((e=>{if(e){const t=JSON.parse(e);1===t.length?h(t[0].children):g(t)}})),e.preventDefault(),!0;if("c"===e.key||"x"===e.key){const t=m("x"===e.key);return t&&navigator.clipboard.writeText(JSON.stringify(t)),!0}}return!1}}),y=a.reactCanvasRenderTarget,v=[];u.forEach(((e,t)=>{e.forEach((({x:e,y:n,content:r,visible:o,row:i},a)=>{o&&(d([t,a])&&v.push(y.renderRect(e,n,2*r.radius,p[i],{fillColor:11785981,strokeWidth:0})),v.push(y.renderCircle(e+r.radius,n+p[i]/2,r.radius,{fillColor:r.color,strokeWidth:0})))}))}));const x=y.renderResult(v,400,f);return i().createElement(i().Fragment,null,l(x),i().createElement(a.EnumEditor,{enums:a.aligns,value:n,setValue:o}),i().createElement(a.EnumEditor,{enums:a.verticalAligns,value:s,setValue:c}))}},3823:(e,t,n)=>{"use strict";n.d(t,{default:()=>s});var r=n(8662),o=n(3696),i=n.n(o),a=n(9758);const s=()=>{const[e,t]=i().useState((()=>new Array(30).fill(0).map((()=>({radius:5+Math.round(20*Math.random()),color:Math.round(16777215*Math.random())}))))),[n,o]=i().useState("left"),[s,c]=i().useState("top"),{renderEditor:l,layoutResult:u,lineHeights:p,isSelected:d,actualHeight:f,inputContent:g,getCopiedContents:h}=(0,a.useFlowLayoutEditor)({state:e,setState:n=>t((0,r.produce)(e,n)),width:400,height:200,lineHeight:e=>2*e.radius,getWidth:e=>2*e.radius,endContent:{radius:0,color:0},isNewLineContent:e=>0===e.radius,align:n,verticalAlign:s,processInput(e){if("Enter"===e.key)return g([{radius:0,color:0}]),!0;if((0,a.metaKeyIfMacElseCtrlKey)(e)){if("v"===e.key)return navigator.clipboard.readText().then((e=>{e&&g(JSON.parse(e))})),e.preventDefault(),!0;if("c"===e.key||"x"===e.key){const t=h("x"===e.key);return t&&navigator.clipboard.writeText(JSON.stringify(t)),!0}}return!1}}),m=a.reactCanvasRenderTarget,y=[];for(const{x:e,y:t,i:n,content:r,visible:o,row:i}of u)o&&(d(n)&&y.push(m.renderRect(e,t,2*r.radius,p[i],{fillColor:11785981,strokeWidth:0})),y.push(m.renderCircle(e+r.radius,t+p[i]/2,r.radius,{fillColor:r.color,strokeWidth:0})));const v=m.renderResult(y,400,f);return i().createElement(i().Fragment,null,l(v),i().createElement(a.EnumEditor,{enums:a.aligns,value:n,setValue:o}),i().createElement(a.EnumEditor,{enums:a.verticalAligns,value:s,setValue:c}))}},1805:(e,t,n)=>{"use strict";n.d(t,{default:()=>s});var r=n(8662),o=n(3696),i=n.n(o),a=n(9758);const s=()=>{const[e,t]=i().useState((()=>"1 + 2 = 3".split(""))),[n,o]=i().useState("left"),[s,c]=i().useState("top"),{renderEditor:l,layoutResult:u}=(0,a.useFlowLayoutTextEditor)({state:e,setState:n=>t((0,r.produce)(e,n)),width:400,height:200,fontSize:20,fontFamily:"monospace",lineHeight:24,align:n,verticalAlign:s});return i().createElement(i().Fragment,null,l({target:a.reactCanvasRenderTarget,getTextColors:e=>{if(["+","-","*","/","="].includes(u[e].content))return{color:255}}}),i().createElement(a.EnumEditor,{enums:a.aligns,value:n,setValue:o}),i().createElement(a.EnumEditor,{enums:a.verticalAligns,value:s,setValue:c}))}},601:(e,t,n)=>{"use strict";n.d(t,{default:()=>s});var r=n(8662),o=n(3696),i=n.n(o),a=n(9758);const s=()=>{const[e,t]=i().useState([]),{image:n,onClick:o,onMove:s,input:c,reset:l}=(0,a.useImageClickCreate)(!0,(n=>{t((0,r.produce)(e,(e=>{e.push(n)})))}));return(0,a.useGlobalKeyDown)((e=>{"Escape"===e.key&&l()})),i().createElement("div",{style:{height:"100%"}},i().createElement("svg",{viewBox:"0 0 800 600",width:800,height:600,xmlns:"http://www.w3.org/2000/svg",fill:"none",style:{position:"absolute",left:0,top:0},onClick:e=>o({x:e.clientX,y:e.clientY}),onMouseMove:e=>s({x:e.clientX,y:e.clientY})},[...e,n].map(((e,t)=>e&&i().createElement("image",{key:t,href:e.url,x:e.x,y:e.y,width:e.width,height:e.height})))),c)}},2083:(e,t,n)=>{"use strict";n.d(t,{default:()=>a});var r=n(3696),o=n.n(r),i=n(9758);const a=()=>{const e=(0,i.useWindowSize)();return o().createElement(i.ImageEditor,{src:"https://farm9.staticflickr.com/8873/18598400202_3af67ef38f_z_d.jpg",width:e.width/2,height:e.height})}},250:(e,t,n)=>{"use strict";n.d(t,{stories:()=>fe});var r=n(8995),o=n(7474),i=n(8576),a=n(3388),s=n(2268),c=n(2197),l=n(6844),u=n(2960),p=n(9857),d=n(3464),f=n(7215),g=n(4874),h=n(3191),m=n(9612),y=n(2071),v=n(7258),x=n(2682),b=n(1783),C=n(5090),E=n(6690),P=n(8673),w=n(6808),k=n(2458),_=n(8859),S=n(3823),R=n(1805),T=n(601),A=n(2083),L=n(3613),M=n(4565),I=n(4855),O=n(7265),D=n(2754),B=n(8208),z=n(6821),F=n(425),N=n(6856),U=n(5047),G=n(5836),j=n(5207),V=n(5779),W=n(2890),H=n(1993),q=n(7631),$=n(277),X=n(574),Y=n(597),K=n(4623),Z=n(4922),Q=n(5982),J=n(7560),ee=n(4339),te=n(94),ne=n(8751),re=n(9967),oe=n(5503),ie=n(8119),ae=n(2929),se=n(8337),ce=n(1459),le=n(432),ue=n(5301),pe=n(7507),de=n(1986);const fe=[{path:"attributed-opentype-text-editor.story",name:"",Component:r.default,code:"() => {\n type Attribute = Partial<{ color: number, fontSize: number, backgroundColor: number, underline: boolean, passThrough: boolean, script?: 'sub' | 'sup', circle?: boolean, stackText?: string, bold?: boolean, italic?: boolean, opacity?: number }>\n const size = useWindowSize()\n const width = size.width / 2 - 30\n const [font, setFont] = React.useState()\n const cache = React.useRef(new MapCache4())\n const getTextLayout = (text: string, fontSize: number, italic = false, bold = false) => {\n if (!font || !text) return\n return cache.current.get(italic, bold, fontSize, text, () => {\n const path = font.getPath(text, 0, fontSize, fontSize, { xScale: fontSize / font.unitsPerEm, yScale: fontSize / font.unitsPerEm })\n const glyph = font.charToGlyph(text)\n const box = glyph.getBoundingBox()\n const advanceWidth = glyph.advanceWidth || 0\n const width = box.x2 - box.x1\n const commands = opentypeCommandsToPathCommands(path, italic ? fontSize * 0.7 : undefined)\n let hatches = geometryLinesToHatches(pathCommandsToGeometryLines(commands))\n if (bold) {\n hatches = hatches.map(h => boldHatch(h, fontSize * 0.01))\n }\n return {\n commands: hatches.map(h => [h.border, ...h.holes]).map(h => h.map(lines => geometryLineToPathCommands(lines)).flat()),\n x1: (advanceWidth > width ? 0 : box.x1) / font.unitsPerEm * fontSize,\n y1: (glyph.unicode && glyph.unicode < 256 ? 0 : box.y1) / font.unitsPerEm * fontSize,\n width: Math.max(advanceWidth, width) / font.unitsPerEm * fontSize,\n }\n })\n }\n const [state, setState] = React.useState[]>([{ insert: '我们出' }, { insert: '去吧', attributes: { stackText: 'ab' } }, { insert: 'Aag jioIb BDxVX晒回吧', attributes: { color: 0xff0000 } }])\n const [align, setAlign] = React.useState('left')\n const [verticalAlign, setVerticalAlign] = React.useState('top')\n const [strokeOnly, setStrokeOnly] = React.useState(false)\n const getColor = (content: AttributedText) => content?.attributes?.color ?? 0x000000\n const getOpacity = (content: AttributedText) => content?.attributes?.opacity ?? 1\n const getFontSize = (content?: AttributedText) => content?.attributes?.fontSize ?? 50\n const getComputedFontSize = (content?: AttributedText) => getFontSize(content) * (content?.attributes?.script || content?.attributes?.stackText ? 0.7 : 1)\n const getBackgroundColor = (content?: AttributedText) => content?.attributes?.backgroundColor ?? 0xffffff\n const getUnderline = (content?: AttributedText) => content?.attributes?.underline ?? false\n const getPassThrough = (content?: AttributedText) => content?.attributes?.passThrough ?? false\n const getBold = (content?: AttributedText) => content?.attributes?.bold ?? false\n const getItalic = (content?: AttributedText) => content?.attributes?.italic ?? false\n const getScript = (content?: AttributedText) => content?.attributes?.script\n const getCircle = (content?: AttributedText) => content?.attributes?.circle ?? false\n const getStackText = (content?: AttributedText) => content?.attributes?.stackText ?? ''\n const getLineHeight = (content: AttributedText) => getComputedFontSize(content) * 1.5\n const getWidth = (content: AttributedText) => {\n const fontSize = getComputedFontSize(content)\n if (content.attributes?.stackText) {\n const width = content.insert.split('').reduce((p, c) => p + (getTextLayout(c, fontSize)?.width ?? 0), 0)\n const stackWidth = content.attributes.stackText.split('').reduce((p, c) => p + (getTextLayout(c, fontSize)?.width ?? 0), 0)\n return Math.max(stackWidth, width)\n }\n return getTextLayout(content.insert, fontSize)?.width ?? 0\n }\n const getComputedWidth = (content: AttributedText) => getCircle(content) ? getLineHeight(content) : getWidth(content)\n const getReadonlyType = (attributes?: Attribute) => attributes?.stackText ? true : undefined\n const { renderEditor, layoutResult, lineHeights, isSelected, actualHeight, cursorContent, setSelectedAttributes } = useAttributedTextEditor({\n state,\n setState,\n width,\n height: 200,\n lineHeight: getLineHeight,\n getWidth: getComputedWidth,\n getReadonlyType,\n align,\n verticalAlign,\n })\n\n React.useEffect(() => {\n const fetchFont = async () => {\n const res = await fetch(allFonts[0].url)\n const buffer = await res.arrayBuffer()\n setFont(opentype.parse(buffer))\n }\n fetchFont()\n }, [])\n\n const target = reactSvgRenderTarget\n const children: ReturnType[] = []\n const commands: PathCommand[][] = []\n for (const { x, y, i, content, visible, row } of layoutResult) {\n if (!visible) continue\n const width = getComputedWidth(content)\n const lineHeight = lineHeights[row]\n const selected = isSelected(i)\n if (selected) {\n children.push(target.renderRect(x, y, width, lineHeight, { fillColor: 0xB3D6FD, strokeWidth: 0 }))\n }\n const fontSize = getComputedFontSize(content)\n const italic = getItalic(content)\n const bold = getBold(content)\n const layout = getTextLayout(content.insert, fontSize, italic, bold)\n if (layout) {\n const color = getColor(content)\n const opacity = getOpacity(content)\n const backgroundColor = getBackgroundColor(content)\n if (!selected && backgroundColor !== 0xffffff) {\n children.push(target.renderRect(x, y, width, lineHeight, { fillColor: backgroundColor, strokeWidth: 0 }))\n }\n if (getUnderline(content)) {\n children.push(target.renderPolyline([{ x, y: y + lineHeight }, { x: x + width, y: y + lineHeight }], { strokeColor: color, strokeOpacity: opacity }))\n }\n if (getPassThrough(content)) {\n children.push(target.renderPolyline([{ x, y: y + lineHeight / 2 }, { x: x + width, y: y + lineHeight / 2 }], { strokeColor: color, strokeOpacity: opacity }))\n }\n const pos = {\n x: x - layout.x1,\n y: y + layout.y1 + (lineHeight - getLineHeight(content)),\n }\n const script = getScript(content)\n const stackText = getStackText(content)\n if (script === 'sub') {\n pos.y += fontSize * 0.2\n } else if (script === 'sup' || stackText) {\n pos.y -= fontSize * 0.7\n }\n if (stackText) {\n const textWidth = content.insert.split('').reduce((p, c) => p + (getTextLayout(c, fontSize)?.width ?? 0), 0)\n pos.x += (width - textWidth) / 2\n }\n if (getCircle(content)) {\n pos.x += (lineHeight - getWidth(content)) / 2\n children.push(target.renderCircle(x + width / 2, y + lineHeight / 2, lineHeight / 2, { strokeColor: color, strokeOpacity: opacity }))\n }\n const style = strokeOnly ? { strokeColor: color, strokeOpacity: opacity, strokeWidth: 1 } : { fillColor: color, fillOpacity: opacity, strokeWidth: 0 }\n children.push(target.renderGroup(layout.commands.map(c => target.renderPathCommands(c, style)), { translate: pos }))\n if (selected) {\n commands.push(...layout.commands)\n }\n if (stackText) {\n const stackWidth = stackText.split('').reduce((p, c) => p + (getTextLayout(c, fontSize)?.width ?? 0), 0)\n let xOffset = 0\n for (const char of stackText.split('')) {\n const stackLayout = getTextLayout(char, fontSize, italic, bold)\n if (stackLayout) {\n const stackPos = {\n x: x - stackLayout.x1 + (width - stackWidth) / 2 + xOffset,\n y: y + stackLayout.y1 + (lineHeight - getLineHeight(content)) + fontSize * 0.2,\n }\n xOffset += stackLayout.width\n children.push(target.renderGroup(stackLayout.commands.map(c => target.renderPathCommands(c, style)), { translate: stackPos }))\n }\n }\n }\n }\n }\n const result = target.renderResult(children, width, actualHeight)\n return (\n <>\n {renderEditor(result)}\n \n \n setSelectedAttributes({ color: v })} />,\n opacity: setSelectedAttributes({ opacity: v })} />,\n fontSize: setSelectedAttributes({ fontSize: v })} />,\n backgroundColor: setSelectedAttributes({ backgroundColor: v === 0xffffff ? undefined : v })} />,\n underline: setSelectedAttributes({ underline: v ? true : undefined })} />,\n passThrough: setSelectedAttributes({ passThrough: v ? true : undefined })} />,\n bold: setSelectedAttributes({ bold: v ? true : undefined })} />,\n italic: setSelectedAttributes({ italic: v ? true : undefined })} />,\n strokeOnly: setStrokeOnly(v)} />,\n sub: setSelectedAttributes({ script: v ? 'sub' : undefined })} />,\n sup: setSelectedAttributes({ script: v ? 'sup' : undefined })} />,\n circle: setSelectedAttributes({ circle: v ? true : undefined })} />,\n stackText: setSelectedAttributes({ stackText: v ? v : undefined })} />,\n actions: ,\n }}\n />\n >\n )\n}",props:[],componentName:"",parentComponentName:""},{path:"attributed-text-editor.story",name:"",Component:o.default,code:"() => {\n type Attribute = Partial<{ color: number, fontFamily: string, bold: boolean, italic: boolean, readonly?: string }>\n const [state, setState] = React.useState[]>([{ insert: 'abc' }, { insert: '123', attributes: { color: 0xff0000, readonly: '1' } }, { insert: 'edf', attributes: { readonly: '1' } }, { insert: 'ghi', attributes: { color: 0x00ff00 } }])\n const [align, setAlign] = React.useState('left')\n const [verticalAlign, setVerticalAlign] = React.useState('top')\n const fontSize = 20\n const getFontFamily = (content?: AttributedText) => content?.attributes?.fontFamily ?? 'monospace'\n const getColor = (content?: AttributedText) => content?.attributes?.color ?? 0x000000\n const getBold = (content?: AttributedText) => content?.attributes?.bold ?? false\n const getItalic = (content?: AttributedText) => content?.attributes?.italic ?? false\n const width = 400\n const lineHeight = fontSize * 1.2\n const getWidth = (content: AttributedText) => getTextSizeFromCache(`${getBold(content) ? 'bold ' : ''}${getItalic(content) ? 'italic ' : ''}${fontSize}px ${getFontFamily(content)}`, content.insert)?.width ?? 0\n const { renderEditor, layoutResult, isSelected, actualHeight, cursorContent, setSelectedAttributes } = useAttributedTextEditor({\n state,\n setState,\n width,\n height: 200,\n lineHeight,\n getWidth,\n align,\n verticalAlign,\n getReadonlyType: attributes => attributes?.readonly,\n })\n const children: CanvasDraw[] = []\n const target = reactCanvasRenderTarget\n for (const { x, y, i, content, visible } of layoutResult) {\n if (!visible) continue\n const textWidth = getWidth(content)\n if (isSelected(i)) {\n children.push(target.renderRect(x, y, textWidth, lineHeight, { fillColor: 0xB3D6FD, strokeWidth: 0 }))\n }\n children.push(target.renderText(x + textWidth / 2, y + fontSize, content.insert, getColor(content), fontSize, getFontFamily(content), {\n textAlign: 'center',\n fontWeight: getBold(content) ? 'bold' : undefined,\n fontStyle: getItalic(content) ? 'italic' : undefined,\n }))\n }\n const result = target.renderResult(children, width, actualHeight)\n return (\n <>\n {renderEditor(result)}\n \n \n setSelectedAttributes({ color: v })} />,\n fontFamily: setSelectedAttributes({ fontFamily: v })} />,\n bold: setSelectedAttributes({ bold: v ? true : undefined })} />,\n italic: setSelectedAttributes({ italic: v ? true : undefined })} />,\n }}\n />\n >\n )\n}",props:[],componentName:"",parentComponentName:""},{path:"audio-record.story",name:"",Component:i.default,code:"() => {\n const { start, stop, duration, volume, audioUrl, recording } = useAudioRecorder()\n const { play, pause, playing, currentTime, audio, duration: audioDuration } = useAudioPlayer(audioUrl)\n return (\n \n {!recording ? : null}\n {recording ? : null}\n {recording && volume !== undefined ? : null}\n {audioUrl && (\n <>\n \n {currentTime}/{audioDuration}\n {audio}\n >\n )}\n
\n )\n}",props:[],componentName:"",parentComponentName:""},{path:"bar-chart-3d.story",name:"",Component:a.default,code:"() => {\n const ref = React.useRef(null)\n const renderer = React.useRef>()\n const { x, y, ref: wheelScrollRef } = useWheelScroll()\n const { scale, ref: wheelZoomRef } = useWheelZoom()\n const [rotate, setRotate] = React.useState({ x: 0, y: 0 })\n const { offset, onStart: onStartMoveCanvas, mask: moveCanvasMask, resetDragMove } = useDragMove(() => {\n setRotate((v) => ({ x: v.x + offset.x, y: v.y + offset.y }))\n })\n const size = useWindowSize()\n const width = size.width / 2\n const height = size.height\n const [hovering, setHovering] = React.useState()\n const rotateX = offset.x + rotate.x\n const rotateY = offset.y + rotate.y\n const graphics = React.useRef<(Graphic3d)[]>([])\n const getXLabel = (x: number) => Intl.DateTimeFormat('zh', { month: 'long' }).format(new Date(x.toString()))\n\n React.useEffect(() => {\n if (!ref.current || renderer.current) return\n renderer.current = createWebgl3DRenderer(ref.current)\n }, [ref.current])\n useGlobalKeyDown(e => {\n if (e.key === 'Escape') {\n resetDragMove()\n }\n })\n\n React.useEffect(() => {\n const points1 = [65, 59, 80, 81, 56, 55, 40].map((s, i) => [(i + 1) * 20, s, 0] as Vec3)\n const points2 = [55, 49, 70, 71, 46, 45, 30].map((s, i) => [(i + 1) * 20, s, 20] as Vec3)\n const points3 = [45, 39, 60, 61, 36, 35, 20].map((s, i) => [(i + 1) * 20, s, 40] as Vec3)\n const points4 = [75, 69, 90, 91, 66, 65, 50].map((s, i) => [(i + 1) * 20, s, -20] as Vec3)\n const axis = getChartAxis3D([points1, points2, points3, points4], { x: 20, y: 10, z: 20 })\n graphics.current.push(\n ...axis,\n ...points1.map(p => ({ geometry: { type: 'cylinder' as const, radius: 3, height: p[1] }, color: [1, 0, 0, 1] as Vec4, position: [p[0], p[1] / 2, p[2]] as Vec3 })),\n ...points2.map(p => ({ geometry: { type: 'cylinder' as const, radius: 3, height: p[1] }, color: [0, 1, 0, 1] as Vec4, position: [p[0], p[1] / 2, p[2]] as Vec3 })),\n ...points3.map(p => ({ geometry: { type: 'cylinder' as const, radius: 3, height: p[1] }, color: [0, 0, 1, 1] as Vec4, position: [p[0], p[1] / 2, p[2]] as Vec3 })),\n ...points4.map(p => ({ geometry: { type: 'cylinder' as const, radius: 3, height: p[1] }, color: [0, 0, 0, 1] as Vec4, position: [p[0], p[1] / 2, p[2]] as Vec3 })),\n )\n }, [])\n\n React.useEffect(() => {\n const { position, up } = updateCamera(-x, y, 200 / scale, -0.3 * rotateX, -0.3 * rotateY)\n renderer.current?.render?.(\n graphics.current,\n {\n eye: [position.x + 40, position.y + 40, position.z],\n up: position3DToVec3(up),\n target: [-x + 40, y + 40, 0],\n fov: angleToRadian(60),\n near: 0.1,\n far: 2000,\n },\n {\n position: [1000, 1000, 1000],\n color: [1, 1, 1, 1],\n specular: [1, 1, 1, 1],\n shininess: 50,\n specularFactor: 1,\n },\n [1, 1, 1, 1],\n )\n }, [x, y, scale, rotateX, rotateY, hovering, width, height])\n\n return (\n \n
\n )\n}",props:[],componentName:"",parentComponentName:""},{path:"bar-chart.story",name:"",Component:s.default,code:"() => {\n const size = useWindowSize()\n const width = size.width / 2\n const height = 500\n const target = reactSvgRenderTarget\n const [hovering, setHovering] = React.useState()\n const [result, setResult] = React.useState<{ children: SvgDraw[], select: (p: Position) => Position & { value: { x: number, y: number | number[] } } | undefined }>()\n const getXLabel = (x: number) => Intl.DateTimeFormat('zh', { month: 'long' }).format(new Date((x + 1).toString()))\n\n React.useEffect(() => {\n const datas = [\n [65, 59, 80, 81, 56, 55, 40].map(x => [x]),\n [55, 49, 70, 71, 46, 45, 30].map(x => [x]),\n [45, 39, 60, 61, 36, 35, 30].map(x => [x - 20, x]),\n [65, 59, 80, 81, 56, 55, 40].map(x => [x - 30, x - 15, x - 5, x]),\n ]\n const data1 = [35, 29, 50, 51, 26, 25, 10].map((s, i) => ({ x: i, y: s }))\n const colors = [[0xff0000], [0x00ff00], [0x0000ff], [0xff0000, 0x00ff00, 0x0000ff]]\n const { children, select, tx, ty } = getBarChart(datas, colors, (region, color) => target.renderPolygon(getRoundedRectPoints(region, 5, 30), { fillColor: color, strokeWidth: 0 }), target, { y: 5 }, { width, height }, { left: 25, right: 10, top: 10, bottom: 20 }, {\n getXLabel,\n bounding: getPointsBounding(data1)\n })\n\n const points1 = data1.map(c => ({ x: tx(c.x + 0.5), y: ty(c.y) }))\n children.push(target.renderPolyline(points1, { strokeColor: 0x000000 }))\n children.push(...points1.map(c => target.renderCircle(c.x, c.y, 3, { fillColor: 0x000000, strokeWidth: 0 })))\n\n setResult({\n children,\n select: (p) => {\n const j = points1.findIndex(n => getTwoPointsDistance(n, p) <= 5)\n if (j >= 0) {\n return { ...points1[j], value: data1[j] }\n }\n return select(p)\n }\n })\n }, [width])\n\n if (!result) {\n return null\n }\n let children = result.children\n if (hovering) {\n children = [\n ...result.children,\n ...renderChartTooltip(target, hovering, hovering.value, { getXLabel }),\n ]\n }\n return (\n \n {target.renderResult(children, width, height, { attributes: { onMouseMove: e => setHovering(result.select({ x: e.clientX, y: e.clientY })) } })}\n
\n )\n}",props:[],componentName:"",parentComponentName:""},{path:"circle-arc-click-create.story",name:"",Component:c.default,code:"() => {\n const [contents, setContents] = React.useState([])\n const { circle, arc, onClick, onMove, input, reset } = useCircleArcClickCreate('center radius', (c) => {\n setContents(produce(contents, (draft) => {\n draft.push(c)\n }))\n })\n useGlobalKeyDown(e => {\n if (e.key === 'Escape') {\n reset()\n }\n })\n const arcCircle = circle || arc\n return (\n onClick({ x: e.clientX, y: e.clientY })}\n onMouseMove={(e) => onMove({ x: e.clientX, y: e.clientY })}\n style={{ height: '100%' }}\n >\n
\n {input}\n
\n )\n}",props:[],componentName:"",parentComponentName:""},{path:"circle-arc-edit.story",name:"",Component:l.default,code:"() => {\n const [content, setContent] = React.useState({ x: 200, y: 200, r: 100, startAngle: -30, endAngle: 120 })\n const { offset, onStart, mask, reset } = useCircleArcEdit(() => setContent(circleArc))\n useGlobalKeyDown(e => {\n if (e.key === 'Escape') {\n reset()\n }\n })\n const circleArc = produce(content, (draft) => {\n if (offset) {\n draft.x += offset.x\n draft.y += offset.y\n draft.r += offset.r\n draft.startAngle += offset.startAngle\n draft.endAngle += offset.endAngle\n normalizeAngleRange(draft)\n }\n })\n const start = polarToCartesian(circleArc.x, circleArc.y, circleArc.r, circleArc.endAngle)\n const end = polarToCartesian(circleArc.x, circleArc.y, circleArc.r, circleArc.startAngle)\n return (\n <>\n \n onStart(e, { ...circleArc, type, cursor })}\n />\n {mask}\n >\n )\n}",props:[],componentName:"",parentComponentName:""},{path:"circle-click-create.story",name:"",Component:u.default,code:"() => {\n const [contents, setContents] = React.useState([])\n const { circle, onClick, onMove, input, reset } = useCircleClickCreate('center radius', (c) => {\n setContents(produce(contents, (draft) => {\n draft.push(c)\n }))\n })\n useGlobalKeyDown(e => {\n if (e.key === 'Escape') {\n reset()\n }\n })\n\n return (\n onClick({ x: e.clientX, y: e.clientY })}\n onMouseMove={(e) => onMove({ x: e.clientX, y: e.clientY })}\n style={{ height: '100%' }}\n >\n {[...contents, circle].map((content, i) => content && (\n
\n
\n ))}\n {input}\n
\n )\n}",props:[],componentName:"",parentComponentName:""},{path:"circle-edit.story",name:"",Component:p.default,code:"() => {\n const [content, setContent] = React.useState({ x: 300, y: 200, r: 100 })\n const { offset, onStart, mask, reset } = useCircleEdit(() => setContent(circle))\n const circle = produce(content, (draft) => {\n draft.x += offset.x\n draft.y += offset.y\n draft.r += offset.r\n })\n useGlobalKeyDown(e => {\n if (e.key === 'Escape') {\n reset()\n }\n })\n return (\n <>\n \n
\n onStart(e, { ...content, type, cursor })}\n />\n {mask}\n >\n )\n}",props:[],componentName:"",parentComponentName:""},{path:"drag-move.story",name:"",Component:d.default,code:"() => {\n const [x, setX] = React.useState(0)\n const [y, setY] = React.useState(0)\n const { offset, onStart, mask, resetDragMove } = useDragMove(() => {\n setX((v) => v + offset.x)\n setY((v) => v + offset.y)\n })\n useGlobalKeyDown(e => {\n if (e.key === 'Escape') {\n resetDragMove()\n }\n })\n\n return (\n \n
onStart({ x: e.clientX, y: e.clientY })}\n >
\n {mask}\n
\n )\n}",props:[],componentName:"",parentComponentName:""},{path:"drag-resize.story",name:"",Component:f.default,code:"() => {\n const [content, setContent] = React.useState({\n x: 200,\n y: 200,\n width: 100,\n height: 100,\n })\n const { offset, onStart, mask, resetDragResize } = useDragResize(\n () => setContent(previewContent),\n {\n centeredScaling: (e) => e.shiftKey,\n keepRatio: (e) => metaKeyIfMacElseCtrlKey(e) ? content.width / content.height : undefined,\n transformOffset: (f, e) => {\n // keep width >= 0\n if (f.width + content.width < 0) {\n f.width = -content.width\n // keep x < content right border(or content center if centeredScaling is true)\n f.x = Math.min(f.x, content.width * (e?.shiftKey ? 0.5 : 1))\n }\n if (f.height + content.height < 0) {\n f.height = -content.height\n f.y = Math.min(f.y, content.height * (e?.shiftKey ? 0.5 : 1))\n }\n return f\n },\n },\n )\n useGlobalKeyDown(e => {\n if (e.key === 'Escape') {\n resetDragResize()\n }\n })\n const previewContent = produce(content, (draft) => {\n draft.width += offset.width\n draft.height += offset.height\n draft.x += offset.x\n draft.y += offset.y\n })\n\n return (\n <>\n \n \n
\n {mask}\n >\n )\n}",props:[],componentName:"",parentComponentName:""},{path:"drag-rotate.story",name:"",Component:g.default,code:"() => {\n const [content, setContent] = React.useState({\n x: 200,\n y: 200,\n width: 100,\n height: 100,\n rotate: 0,\n url: 'https://interactive-examples.mdn.mozilla.net/media/cc0-images/grapefruit-slice-332-332.jpg',\n })\n const { offset, onStart, mask, resetDragRotate } = useDragRotate(\n () => setContent(previewContent),\n {\n transformOffset: (r, e) => {\n if (e && r !== undefined && !e.shiftKey) {\n const snap = Math.round(r / 45) * 45\n if (Math.abs(snap - r) < 5) {\n r = snap\n }\n }\n return r\n },\n }\n )\n useGlobalKeyDown(e => {\n if (e.key === 'Escape') {\n resetDragRotate()\n }\n })\n const previewContent = produce(content, (draft) => {\n if (offset?.angle !== undefined) {\n draft.rotate = offset.angle\n }\n })\n\n return (\n <>\n \n onStart({ x: content.x + content.width / 2, y: content.y + content.height / 2 })} />\n
\n {mask}\n >\n )\n}",props:[],componentName:"",parentComponentName:""},{path:"drag-select.story",name:"",Component:h.default,code:"() => {\n const [contents, setContents] = React.useState([])\n const { onStartSelect, dragSelectMask, resetDragSelect } = useDragSelect((dragSelectStartPosition, dragSelectEndPosition) => {\n if (dragSelectEndPosition) {\n setContents(produce(contents, (draft) => {\n draft.push({\n x: Math.min(dragSelectStartPosition.x, dragSelectEndPosition.x),\n y: Math.min(dragSelectStartPosition.y, dragSelectEndPosition.y),\n width: Math.abs(dragSelectEndPosition.x - dragSelectStartPosition.x),\n height: Math.abs(dragSelectEndPosition.y - dragSelectStartPosition.y),\n })\n }))\n }\n }, (e) => e.shiftKey)\n useGlobalKeyDown(e => {\n if (e.key === 'Escape') {\n resetDragSelect()\n }\n })\n\n return (\n onStartSelect(e, undefined)}\n style={{ height: '100%' }}\n >\n {contents.map((content, i) => (\n
\n
\n ))}\n {dragSelectMask}\n
\n )\n}",props:[],componentName:"",parentComponentName:""},{path:"edit.story",name:"",Component:m.default,code:"() => {\n const [content, setContent] = React.useState({ x: 300, y: 200, r: 100 })\n const { editPoint, updateEditPreview, onEditMove, onEditClick, getEditAssistentContents, resetEdit } = useEdit(\n () => setContent(circle),\n (s) => ({\n editPoints: [\n {\n x: s.x,\n y: s.y,\n cursor: 'move',\n update(c, { cursor, start }) {\n c.x += cursor.x - start.x\n c.y += cursor.y - start.y\n }\n },\n { x: s.x - s.r, y: s.y, cursor: 'ew-resize', update(c, { cursor }) { c.r = getTwoPointsDistance(cursor, c) } },\n { x: s.x, y: s.y - s.r, cursor: 'ns-resize', update(c, { cursor }) { c.r = getTwoPointsDistance(cursor, c) } },\n { x: s.x + s.r, y: s.y, cursor: 'ew-resize', update(c, { cursor }) { c.r = getTwoPointsDistance(cursor, c) } },\n { x: s.x, y: s.y + s.r, cursor: 'ns-resize', update(c, { cursor }) { c.r = getTwoPointsDistance(cursor, c) } },\n ],\n }),\n )\n useGlobalKeyDown(e => {\n if (e.key === 'Escape') {\n resetEdit()\n }\n })\n const assistentContents: Region[] = []\n const newContent = updateEditPreview()\n const circle = newContent?.result ?? content\n assistentContents.push(...getEditAssistentContents(circle, (rect) => rect))\n\n return (\n <>\n \n >\n )\n}",props:[],componentName:"",parentComponentName:""},{path:"ellipse-arc-click-create.story",name:"",Component:y.default,code:"() => {\n const [contents, setContents] = React.useState([])\n const { ellipse, ellipseArc, onClick, onMove, input, reset } = useEllipseArcClickCreate('ellipse center', (c) => {\n setContents(produce(contents, (draft) => {\n draft.push(c)\n }))\n })\n useGlobalKeyDown(e => {\n if (e.key === 'Escape') {\n reset()\n }\n })\n const arcEllipse = ellipse || ellipseArc\n return (\n onClick({ x: e.clientX, y: e.clientY })}\n onMouseMove={(e) => onMove({ x: e.clientX, y: e.clientY })}\n style={{ height: '100%' }}\n >\n
\n {input}\n
\n )\n}",props:[],componentName:"",parentComponentName:""},{path:"ellipse-arc-edit.story",name:"",Component:v.default,code:"() => {\n const [content, setContent] = React.useState({ cx: 200, cy: 200, rx: 100, ry: 150, angle: 45, startAngle: -30, endAngle: 120 })\n const { offset, onStart, mask, reset } = useEllipseArcEdit(() => setContent(ellipseArc))\n const ellipseArc = produce(content, (draft) => {\n if (offset) {\n draft.cx += offset.cx\n draft.cy += offset.cy\n draft.rx += offset.rx\n draft.ry += offset.ry\n draft.startAngle += offset.startAngle\n draft.endAngle += offset.endAngle\n normalizeAngleRange(draft)\n }\n })\n useGlobalKeyDown(e => {\n if (e.key === 'Escape') {\n reset()\n }\n })\n const points = ellipseArcToPolyline(ellipseArc, defaultAngleDelta)\n return (\n <>\n \n onStart(e, { ...ellipseArc, type, cursor })}\n />\n {mask}\n >\n )\n}",props:[],componentName:"",parentComponentName:""},{path:"ellipse-click-create.story",name:"",Component:x.default,code:"() => {\n const [contents, setContents] = React.useState([])\n const { ellipse, onClick, onMove, input, reset } = useEllipseClickCreate('ellipse center', (c) => {\n setContents(produce(contents, (draft) => {\n draft.push(c)\n }))\n })\n useGlobalKeyDown(e => {\n if (e.key === 'Escape') {\n reset()\n }\n })\n\n return (\n \n \n {input}\n
\n )\n}",props:[],componentName:"",parentComponentName:""},{path:"ellipse-edit.story",name:"",Component:b.default,code:"() => {\n const [content, setContent] = React.useState({ cx: 200, cy: 200, rx: 100, ry: 150, angle: 45 })\n const { offset, onStart, mask, reset } = useEllipseEdit(() => setContent(ellipse))\n const ellipse = produce(content, (draft) => {\n if (offset) {\n draft.cx += offset.cx\n draft.cy += offset.cy\n draft.rx += offset.rx\n draft.ry += offset.ry\n }\n })\n useGlobalKeyDown(e => {\n if (e.key === 'Escape') {\n reset()\n }\n })\n return (\n <>\n \n onStart(e, { ...ellipse, type, cursor })}\n />\n {mask}\n >\n )\n}",props:[],componentName:"",parentComponentName:""},{path:"equation-renderer.story",name:"",Component:C.default,code:"() => {\n const [left, setLeft] = React.useState('X1 ** 2 + X2 * X3')\n const [right, setRight] = React.useState('(-X6) ** 0.5 / (X4 - X5 ** 3)')\n const [equation, setEquation] = React.useState()\n const [keepBinaryExpressionOrder, setKeepBinaryExpressionOrder] = React.useState(false)\n React.useEffect(() => {\n try {\n setEquation({\n left: parseExpression(tokenizeExpression(left)),\n right: parseExpression(tokenizeExpression(right)),\n })\n } catch (error) {\n console.info(error)\n }\n }, [left, right])\n return (\n \n \n \n \n {equation && renderEquation(reactSvgRenderTarget, equation, { keepBinaryExpressionOrder })}\n {equation && {printEquation(equation, { keepBinaryExpressionOrder })}
}\n
\n )\n}",props:[],componentName:"",parentComponentName:""},{path:"equation-solver.story",name:"",Component:E.default,code:"() => {\n const { value, update, getArrayProps } = useJsonEditorData([\n { equation: 'a * x + b * y = c', variable: 'x' },\n { equation: 'x ** 2 + y ** 2 = r', variable: 'y' },\n ])\n const [isMath, setIsMath] = React.useState(false)\n const [equations, setEquations] = React.useState([])\n const [keepBinaryExpressionOrder, setKeepBinaryExpressionOrder] = React.useState(false)\n const [showText, setShowText] = React.useState(false)\n React.useEffect(() => {\n try {\n const result = solveEquations(value.map(e => {\n const equation = e.equation.split('=')\n return {\n left: parseExpression(tokenizeExpression(isMath ? mathStyleExpressionToExpression(equation[0]) : equation[0])),\n right: parseExpression(tokenizeExpression(isMath ? mathStyleExpressionToExpression(equation[1]) : equation[1])),\n }\n }), new Set(value.map(e => e.variable)))\n setEquations(result.map(e => Object.entries(e).map(([key, e]) => {\n return !Array.isArray(e) ? { left: { type: 'Identifier', name: key }, right: e } : { left: e[0], right: e[1] }\n })))\n } catch (error) {\n console.info(error)\n }\n }, [value, isMath])\n return (\n \n
v, { equation: 'x = 1', variable: 'x' })}\n properties={value.map((f, i) => ({\n equation: draft[i].equation = v)} height={20} width={400} autoHeight />,\n variable: draft[i].variable = v)} />\n }))}\n />\n \n \n \n {equations.map((a, j) => (\n \n {a.map((e, i) => (\n
\n {!showText && renderEquation(reactSvgRenderTarget, e, { keepBinaryExpressionOrder })}\n {showText && {printEquation(e, { keepBinaryExpressionOrder })}
}\n \n ))}\n
\n ))}\n {isMath && equations.map((a, j) => (\n \n {a.map((e, i) => (\n
{printMathStyleExpression(e.left)} = {printMathStyleExpression(e.right)}
\n ))}\n
\n ))}\n \n )\n}",props:[],componentName:"",parentComponentName:""},{path:"expression-chart.story",name:"",Component:P.default,code:"() => {\n const { value, update, getArrayProps } = useJsonEditorData(['sin(x)'])\n const [hovering, setHovering] = React.useState()\n const [min, setMin] = React.useState(0)\n const [max, setMax] = React.useState(10)\n const [isMath, setIsMath] = React.useState(true)\n const [equationResult, setEquationResult] = React.useState([])\n const [error, setError] = React.useState()\n\n const size = useWindowSize()\n const width = size.width / 2\n const height = 300\n const target = reactSvgRenderTarget\n const [result, setResult] = React.useState<{ children: SvgDraw[], select: (p: Position) => Position & { value: Position } | undefined }>()\n const parseInputExpression = (v: string) => parseExpression(tokenizeExpression(isMath ? mathStyleExpressionToExpression(v) : v))\n\n const drawChart = () => {\n try {\n if (value.length === 0) return\n const points: Position[][] = []\n const step = (max - min) / 100\n const x0 = getTwoNumberCenter(min, max)\n const ctx = {\n sin: Math.sin,\n cos: Math.cos,\n tan: Math.tan,\n ln: Math.log,\n sqrt: Math.sqrt,\n }\n const newEquationResult: number[] = []\n for (const v of value) {\n if (!v) continue\n const p: Position[] = []\n const e = parseInputExpression(v)\n\n const factors = expressionToFactors(e)\n if (factors) {\n const params = factorsToEquationParams(factors, 'x')\n if (params) {\n newEquationResult.push(...calculateEquation5(params, x0, delta1))\n }\n }\n const g = parseInputExpression(printExpression(optimizeExpression(deriveExpressionWith(e, 'x'), v => expressionHasVariable(v, 'x'))))\n const r1 = newtonIterate(x0, x => {\n try {\n const y = evaluateExpression(e, { ...ctx, x })\n return typeof y === 'number' ? y : NaN\n } catch {\n return NaN\n }\n }, x => {\n try {\n const y = evaluateExpression(g, { ...ctx, x })\n return typeof y === 'number' ? y : NaN\n } catch {\n return NaN\n }\n }, delta1)\n if (r1 !== undefined && newEquationResult.every(n => !isSameNumber(n, r1))) {\n newEquationResult.push(r1)\n }\n\n for (let x = min; x <= max; x += step) {\n const y = evaluateExpression(e, { ...ctx, x })\n if (typeof y === 'number' && !isNaN(y)) {\n p.push({ x, y })\n }\n }\n if (p.length > 0) {\n points.push(p)\n }\n }\n setEquationResult(newEquationResult)\n const ys = points.flat().map(p => p.y)\n const minY = Math.min(...ys)\n const maxY = Math.max(...ys)\n const equationResultPoints = newEquationResult.filter(n => isBetween(n, min, max)).map(x => [{ x, y: minY }, { x, y: maxY }])\n const r = getLineChart([[{ x: min, y: 0 }, { x: max, y: 0 }], ...equationResultPoints, ...points], target, { x: 0.01, y: 0.01 }, { width, height }, { left: 25, right: 25, top: 10, bottom: 20 }, { xLabelDisabled: true, yLabelDisabled: true })\n if (!r) return\n const { points: [axis, ...p], children, select } = r\n children.push(target.renderPolyline(axis, { strokeColor: 0x00ff00 }))\n for (let i = 0; i < p.length; i++) {\n children.push(target.renderPolyline(p[i], { strokeColor: i < equationResultPoints.length ? 0x0000ff : 0xff0000 }))\n }\n setResult({ children, select })\n setError(undefined)\n } catch (error) {\n console.info(error)\n setError(String(error))\n }\n }\n let children: SvgDraw[] | undefined\n if (result) {\n children = result.children\n if (hovering) {\n children = [\n ...result.children,\n ...renderChartTooltip(target, hovering, hovering.value),\n ]\n }\n }\n return (\n \n {result && children &&
\n {target.renderResult(children, width, height, { attributes: { onMouseMove: e => setHovering(result.select({ x: e.clientX, y: e.clientY })) } })}\n
}\n
\n
v, '')}\n inline\n style={{ width: 'calc(50% - 30px)' }}\n items={value.map((f, i) => draft[i] = v)} />)}\n />\n \n \n
\n \n \n ~\n \n
\n \n {equationResult.map((r, i) => \n x = {r}
\n
)}\n {error && {error}
}\n \n
\n )\n}",props:[],componentName:"",parentComponentName:""},{path:"expression-editor.story",name:"",Component:w.default,code:"() => {\n const [value, setValue] = React.useState('1 + 2 - 3')\n\n return (\n \n )\n}",props:[],componentName:"",parentComponentName:""},{path:"expression-expansion.story",name:"",Component:k.default,code:"() => {\n const [value, setValue] = React.useState('(x + a)^3')\n const [secondValue, setSecondValue] = React.useState('x')\n const [thirdValue, setThirdValue] = React.useState('')\n const [isMath, setIsMath] = React.useState(true)\n const [outputMath, setOutputMath] = React.useState(true)\n const [error, setError] = React.useState()\n const [factors, setFactors] = React.useState()\n const [expression, setExpression] = React.useState()\n\n const parseInputExpression = (v: string) => parseExpression(tokenizeExpression(isMath ? mathStyleExpressionToExpression(v) : v))\n const outputExpression = (e: Expression2) => outputMath ? printMathStyleExpression(e) : printExpression(e)\n const expandAll = () => {\n try {\n if (!value) return\n const r = expandExpression(parseInputExpression(value))\n let f = expressionToFactors(r)\n if (f) {\n f = optimizeFactors(f)\n sortFactors(f)\n setFactors(f)\n setExpression(undefined)\n } else {\n setExpression(r)\n setFactors(undefined)\n }\n setError(undefined)\n } catch (error) {\n console.info(error)\n setError(String(error))\n setFactors(undefined)\n setExpression(undefined)\n }\n }\n const divideBy = () => {\n try {\n if (!secondValue) return\n if (!factors) return\n const r = parseInputExpression(secondValue)\n const f = expressionToFactors(r)\n if (f) {\n const g = divideFactors(factors, f)\n if (g) {\n setFactors(g)\n }\n }\n setError(undefined)\n } catch (error) {\n setError(String(error))\n }\n }\n const groupBy = () => {\n try {\n if (!secondValue) return\n if (!factors) return\n const r = parseInputExpression(secondValue)\n const f = expressionToFactors(r)\n if (f && f.length === 1) {\n const g = groupFactorsBy(factors, f[0])\n if (g) {\n setExpression(g)\n }\n }\n setError(undefined)\n } catch (error) {\n setError(String(error))\n }\n }\n const replaceWith = () => {\n try {\n if (!secondValue) return\n if (!thirdValue) return\n if (!value) return\n const r1 = parseInputExpression(value)\n const r3 = parseInputExpression(thirdValue)\n const g = composeExpression(r1, { [secondValue]: r3 })\n if (g) {\n setExpression(g)\n }\n setError(undefined)\n } catch (error) {\n setError(String(error))\n }\n }\n const formatStyle = () => {\n try {\n if (!value) return\n const r = parseInputExpression(value)\n setExpression(r)\n setError(undefined)\n } catch (error) {\n setError(String(error))\n setExpression(undefined)\n }\n }\n const groupAll = () => {\n if (!factors) return\n setExpression(groupAllFactors(factors))\n }\n const deriveWith = () => {\n try {\n if (!secondValue) return\n if (!value) return\n const r = parseInputExpression(value)\n const g = optimizeExpression(deriveExpressionWith(r, secondValue), v => expressionHasVariable(v, secondValue))\n setExpression(g)\n setError(undefined)\n } catch (error) {\n setError(String(error))\n setExpression(undefined)\n }\n }\n const optimize = () => {\n try {\n if (!value) return\n const r = parseInputExpression(value)\n const g = optimizeExpression(r)\n setExpression(g)\n setError(undefined)\n } catch (error) {\n setError(String(error))\n setExpression(undefined)\n }\n }\n const groupByVariables = () => {\n try {\n if (!secondValue) return\n if (!factors) return\n const r = parseInputExpression(secondValue)\n const f = expressionToFactors(r)\n if (f && f.length === 1) {\n const g = groupFactorsByVariables(factors, f[0].variables.filter((v): v is string => typeof v === 'string'))\n if (g) {\n setExpression(g)\n }\n }\n setError(undefined)\n } catch (error) {\n setError(String(error))\n }\n }\n const taylorExpand = (toPrimaryFunction: boolean) => {\n try {\n if (!secondValue) return\n if (!value) return\n const r = parseInputExpression(value)\n const g = taylorExpandExpressionWith(r, secondValue, +thirdValue || 5, toPrimaryFunction)\n setExpression(g)\n setError(undefined)\n } catch (error) {\n setError(String(error))\n setExpression(undefined)\n }\n }\n const setText = (text: string) => {\n setValue(text)\n setError(undefined)\n setFactors(undefined)\n setExpression(undefined)\n }\n\n return (\n \n
\n
\n \n \n
\n
\n \n =\n \n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n {factors && factors.length > 0 &&
\n {factors.map((f, i) =>
{outputExpression(factorToExpression(f))}
)}\n
}\n {factors &&
\n {outputExpression(factorsToExpression(factors))}
\n \n \n
}\n {expression &&
\n {outputExpression(expression)}
\n \n \n
}\n {expression && renderExpression(reactSvgRenderTarget, expression)}\n {error &&
{error}
}\n
\n )\n}",props:[],componentName:"",parentComponentName:""},{path:"flow-layout-block-editor.story",name:"",Component:_.default,code:"() => {\n const [state, setState] = React.useState(() => new Array(3).fill(0).map(() => ({\n children: new Array(20).fill(0).map(() => ({\n radius: 5 + Math.round(Math.random() * 20),\n color: Math.round(Math.random() * 0xffffff),\n })),\n blockStart: 5,\n blockEnd: 5\n })))\n const [align, setAlign] = React.useState('left')\n const [verticalAlign, setVerticalAlign] = React.useState('top')\n const width = 400\n const { renderEditor, layoutResult, lineHeights, isSelected, actualHeight, inputContent, inputInline, getCopiedContents } = useFlowLayoutBlockEditor<{ radius: number, color: number }>({\n state,\n setState: recipe => setState(produce(state, recipe)),\n width,\n height: 400,\n lineHeight: c => c.radius * 2,\n getWidth: c => c.radius * 2,\n endContent: { radius: 0, color: 0 },\n isNewLineContent: content => content.radius === 0,\n align,\n verticalAlign,\n processInput(e) {\n if (metaKeyIfMacElseCtrlKey(e)) {\n if (e.key === 'v') {\n navigator.clipboard.readText().then(v => {\n if (v) {\n const contents: FlowLayoutBlock<{ radius: number, color: number }>[] = JSON.parse(v)\n if (contents.length === 1) {\n inputInline(contents[0].children)\n } else {\n inputContent(contents)\n }\n }\n })\n e.preventDefault()\n return true\n }\n if (e.key === 'c' || e.key === 'x') {\n const contents = getCopiedContents(e.key === 'x')\n if (contents) {\n navigator.clipboard.writeText(JSON.stringify(contents))\n }\n return true\n }\n }\n return false\n },\n })\n const target: ReactRenderTarget = reactCanvasRenderTarget\n const children: unknown[] = []\n layoutResult.forEach((r, blockIndex) => {\n r.forEach(({ x, y, content, visible, row }, contentIndex) => {\n if (!visible) return\n if (isSelected([blockIndex, contentIndex])) {\n children.push(target.renderRect(x, y, content.radius * 2, lineHeights[row], { fillColor: 0xB3D6FD, strokeWidth: 0 }))\n }\n children.push(target.renderCircle(x + content.radius, y + lineHeights[row] / 2, content.radius, { fillColor: content.color, strokeWidth: 0 }))\n })\n })\n const result = target.renderResult(children, width, actualHeight)\n return (\n <>\n {renderEditor(result)}\n \n \n >\n )\n}",props:[],componentName:"",parentComponentName:""},{path:"flow-layout-editor.story",name:"",Component:S.default,code:"() => {\n const [state, setState] = React.useState(() => new Array(30).fill(0).map(() => ({\n radius: 5 + Math.round(Math.random() * 20),\n color: Math.round(Math.random() * 0xffffff),\n })))\n const [align, setAlign] = React.useState('left')\n const [verticalAlign, setVerticalAlign] = React.useState('top')\n const width = 400\n const { renderEditor, layoutResult, lineHeights, isSelected, actualHeight, inputContent, getCopiedContents } = useFlowLayoutEditor({\n state,\n setState: recipe => setState(produce(state, recipe)),\n width,\n height: 200,\n lineHeight: c => c.radius * 2,\n getWidth: c => c.radius * 2,\n endContent: { radius: 0, color: 0 },\n isNewLineContent: content => content.radius === 0,\n align,\n verticalAlign,\n processInput(e) {\n if (e.key === 'Enter') {\n inputContent([{ radius: 0, color: 0 }])\n return true\n }\n if (metaKeyIfMacElseCtrlKey(e)) {\n if (e.key === 'v') {\n navigator.clipboard.readText().then(v => {\n if (v) {\n inputContent(JSON.parse(v))\n }\n })\n e.preventDefault()\n return true\n }\n if (e.key === 'c' || e.key === 'x') {\n const contents = getCopiedContents(e.key === 'x')\n if (contents) {\n navigator.clipboard.writeText(JSON.stringify(contents))\n }\n return true\n }\n }\n return false\n },\n })\n const target: ReactRenderTarget = reactCanvasRenderTarget\n const children: unknown[] = []\n for (const { x, y, i, content, visible, row } of layoutResult) {\n if (!visible) continue\n if (isSelected(i)) {\n children.push(target.renderRect(x, y, content.radius * 2, lineHeights[row], { fillColor: 0xB3D6FD, strokeWidth: 0 }))\n }\n children.push(target.renderCircle(x + content.radius, y + lineHeights[row] / 2, content.radius, { fillColor: content.color, strokeWidth: 0 }))\n }\n const result = target.renderResult(children, width, actualHeight)\n return (\n <>\n {renderEditor(result)}\n \n \n >\n )\n}",props:[],componentName:"",parentComponentName:""},{path:"flow-layout-text-editor.story",name:"",Component:R.default,code:"() => {\n const [state, setState] = React.useState(() => '1 + 2 = 3'.split(''))\n const [align, setAlign] = React.useState('left')\n const [verticalAlign, setVerticalAlign] = React.useState('top')\n const { renderEditor, layoutResult } = useFlowLayoutTextEditor({\n state,\n setState: recipe => setState(produce(state, recipe)),\n width: 400,\n height: 200,\n fontSize: 20,\n fontFamily: 'monospace',\n lineHeight: 20 * 1.2,\n align,\n verticalAlign,\n })\n const getTextColors = (index: number) => {\n if (['+', '-', '*', '/', '='].includes(layoutResult[index].content)) {\n return { color: 0x0000ff }\n }\n return\n }\n\n return (\n <>\n {renderEditor({ target: reactCanvasRenderTarget, getTextColors })}\n \n \n >\n )\n}",props:[],componentName:"",parentComponentName:""},{path:"image-click-create.story",name:"",Component:T.default,code:"() => {\n const [contents, setContents] = React.useState([])\n const { image, onClick, onMove, input, reset } = useImageClickCreate(true, (c) => {\n setContents(produce(contents, (draft) => {\n draft.push(c)\n }))\n })\n useGlobalKeyDown(e => {\n if (e.key === 'Escape') {\n reset()\n }\n })\n\n return (\n \n \n {input}\n
\n )\n}",props:[],componentName:"",parentComponentName:""},{path:"image-editor.story",name:"",Component:A.default,code:"() => {\n const size = useWindowSize()\n return (\n \n )\n}",props:[],componentName:"",parentComponentName:""},{path:"keyboard-zoom.story",name:"",Component:L.default,code:"() => {\n const [scale, setScale] = React.useState(1)\n const { zoomIn, zoomOut } = useZoom(scale, setScale)\n useGlobalKeyDown(e => {\n if (metaKeyIfMacElseCtrlKey(e)) {\n if (e.code === 'Minus') {\n zoomOut(e)\n } else if (e.code === 'Equal') {\n zoomIn(e)\n }\n }\n })\n return (\n \n )\n}",props:[],componentName:"",parentComponentName:""},{path:"line-alignment-line.story",name:"",Component:M.default,code:"() => {\n const [contents, setContents] = React.useState(defaultContents)\n const [selectedIndex, setSelectedIndex] = React.useState(0)\n\n const { lineAlignmentX, lineAlignmentY, changeOffsetByLineAlignment, clearLineAlignments } = useLineAlignment(10)\n const { offset, onStart, mask, resetDragResize } = useDragResize(\n () => {\n clearLineAlignments()\n setContents(produce(contents, (draft) => {\n draft[selectedIndex].x += offset.x\n draft[selectedIndex].y += offset.y\n draft[selectedIndex].width += offset.width\n draft[selectedIndex].height += offset.height\n }))\n },\n {\n centeredScaling: (e) => e.shiftKey,\n transformOffset: (f, e, direction) => {\n if (!e?.metaKey && direction) {\n const target = contents[selectedIndex]\n const xLines = contents.filter((t) => t !== target).map((t) => [t.x, t.x + t.width]).flat()\n const yLines = contents.filter((t) => t !== target).map((t) => [t.y, t.y + t.height]).flat()\n changeOffsetByLineAlignment(f, direction, target, xLines, yLines)\n } else {\n clearLineAlignments()\n }\n return f\n },\n }\n )\n useGlobalKeyDown(e => {\n if (e.key === 'Escape') {\n resetDragResize()\n }\n })\n return (\n <>\n {contents.map((content, i) => (\n setSelectedIndex(i)}\n >\n
\n {selectedIndex === i &&
}\n
\n ))}\n \n \n {mask}\n >\n )\n}",props:[],componentName:"",parentComponentName:""},{path:"line-chart-3d.story",name:"",Component:I.default,code:"() => {\n const ref = React.useRef(null)\n const renderer = React.useRef>()\n const { x, y, ref: wheelScrollRef } = useWheelScroll()\n const { scale, ref: wheelZoomRef } = useWheelZoom()\n const [rotate, setRotate] = React.useState({ x: 0, y: 0 })\n const { offset, onStart: onStartMoveCanvas, mask: moveCanvasMask, resetDragMove } = useDragMove(() => {\n setRotate((v) => ({ x: v.x + offset.x, y: v.y + offset.y }))\n })\n const size = useWindowSize()\n const width = size.width / 2\n const height = size.height\n const [hovering, setHovering] = React.useState()\n const rotateX = offset.x + rotate.x\n const rotateY = offset.y + rotate.y\n const graphics = React.useRef<(Graphic3d)[]>([])\n const getXLabel = (x: number) => Intl.DateTimeFormat('zh', { month: 'long' }).format(new Date(x.toString()))\n\n React.useEffect(() => {\n if (!ref.current || renderer.current) return\n renderer.current = createWebgl3DRenderer(ref.current)\n }, [ref.current])\n useGlobalKeyDown(e => {\n if (e.key === 'Escape') {\n resetDragMove()\n }\n })\n\n React.useEffect(() => {\n const points1 = [65, 59, 80, 81, 56, 55, 40].map((s, i) => [(i + 1) * 20, s, 0] as Vec3)\n const points2 = [55, 49, 70, 71, 46, 45, 30].map((s, i) => [(i + 1) * 20, s, 20] as Vec3)\n const points3 = [45, 39, 60, 61, 36, 35, 20].map((s, i) => [(i + 1) * 20, s, -20] as Vec3)\n const points4 = [75, 69, 90, 91, 66, 65, 50].map((s, i) => [(i + 1) * 20, s, 40] as Vec3)\n const axis = getChartAxis3D([points1, points2, points3, points4], { x: 20, y: 10, z: 20 })\n graphics.current.push(\n ...axis,\n { geometry: { type: 'line strip', points: points1.flat() }, color: [1, 0, 0, 1] },\n ...points1.map(p => ({ geometry: { type: 'sphere' as const, radius: 1 }, color: [1, 0, 0, 1] as Vec4, position: p })),\n { geometry: { type: 'line strip', points: getBezierSplinePoints3D(points2, 20).flat() }, color: [0, 1, 0, 1] },\n ...points2.map(p => ({ geometry: { type: 'sphere' as const, radius: 1 }, color: [0, 1, 0, 1] as Vec4, position: p })),\n { geometry: { type: 'polygon', points: [...points3.flat(), points3[points3.length - 1][0], 0, points3[points3.length - 1][2], points3[0][0], 0, points3[0][2]] }, color: [0, 0, 1, 1] },\n ...points3.map(p => ({ geometry: { type: 'sphere' as const, radius: 1 }, color: [0, 0, 1, 1] as Vec4, position: p })),\n ...points4.map((p, i) => ({ geometry: { type: 'sphere' as const, radius: i / 2 + 1 }, color: [1, 0, 0, 1] as Vec4, position: p })),\n )\n }, [])\n\n React.useEffect(() => {\n const { position, up } = updateCamera(-x, y, 200 / scale, -0.3 * rotateX, -0.3 * rotateY)\n renderer.current?.render?.(\n graphics.current,\n {\n eye: [position.x + 40, position.y + 40, position.z],\n up: position3DToVec3(up),\n target: [-x + 40, y + 40, 0],\n fov: angleToRadian(60),\n near: 0.1,\n far: 2000,\n },\n {\n position: [1000, 1000, 1000],\n color: [1, 1, 1, 1],\n specular: [1, 1, 1, 1],\n shininess: 50,\n specularFactor: 1,\n },\n [1, 1, 1, 1],\n )\n }, [x, y, scale, rotateX, rotateY, hovering, width, height])\n\n return (\n \n
\n )\n}",props:[],componentName:"",parentComponentName:""},{path:"line-chart.story",name:"",Component:O.default,code:"() => {\n const size = useWindowSize()\n const width = size.width / 2\n const height = 300\n const target = reactSvgRenderTarget\n const [hovering, setHovering] = React.useState()\n const [result, setResult] = React.useState<{ children: SvgDraw[], select: (p: Position) => Position & { value: Position } | undefined }>()\n const getXLabel = (x: number) => Intl.DateTimeFormat('zh', { month: 'long' }).format(new Date(x.toString()))\n\n React.useEffect(() => {\n const data1 = [65, 59, 80, 81, 56, 55, 40].map((s, i) => ({ x: i + 1, y: s }))\n const data2 = [55, 49, 70, 71, 46, 45, 30].map((s, i) => ({ x: i + 1, y: s }))\n const data3 = [45, 39, 60, 61, 36, 35, 20].map((s, i) => ({ x: i + 1, y: s }))\n const data4 = [35, 29, 50, 51, 26, 25, 10].map((s, i) => ({ x: i + 1, y: s }))\n const data5 = [75, 69, 90, 91, 66, 65, 50].map((s, i) => ({ x: i + 1, y: s, r: i * 3 + 5 }))\n const r = getLineChart([data1, data2, data3, data4, data5], target, { x: 1, y: 5 }, { width, height }, { left: 25, right: 25, top: 10, bottom: 20 }, {\n getXLabel,\n ySecondary: true,\n })\n if (!r) return\n const { points: [points1, points2, points3, points4, points5], children, select, minY } = r\n\n children.push(target.renderPolyline(points1, { strokeColor: 0xff0000 }))\n children.push(...points1.map(c => target.renderCircle(c.x, c.y, 3, { fillColor: 0xff0000, strokeWidth: 0 })))\n children.push(target.renderPolyline(getBezierSplinePoints(points2, 50), { strokeColor: 0x00ff00 }))\n children.push(...points2.map(c => target.renderCircle(c.x, c.y, 3, { fillColor: 0x00ff00, strokeWidth: 0 })))\n children.push(target.renderPolyline(points3.map((p, i) => {\n const r = [p]\n if (i !== 0) r.unshift({ x: getTwoNumberCenter(p.x, points3[i - 1].x), y: p.y })\n if (i !== points3.length - 1) r.push({ x: getTwoNumberCenter(p.x, points3[i + 1].x), y: p.y })\n return r\n }).flat(), { strokeColor: 0x0000ff }))\n children.push(...points3.map(c => target.renderCircle(c.x, c.y, 3, { fillColor: 0x0000ff, strokeWidth: 0 })))\n children.push(target.renderPolygon([...points4, { x: points4[points4.length - 1].x, y: minY }, { x: points4[0].x, y: minY }], { fillColor: 0xff0000, strokeWidth: 0 }))\n children.push(...points4.map(c => target.renderCircle(c.x, c.y, 3, { fillColor: 0xff0000, strokeWidth: 0 })))\n children.push(...points5.map(c => target.renderCircle(c.x, c.y, c.r ?? 5, { fillColor: 0x00ff00, strokeWidth: 0 })))\n\n setResult({ children, select })\n }, [width])\n\n if (!result) {\n return null\n }\n let children = result.children\n if (hovering) {\n children = [\n ...result.children,\n ...renderChartTooltip(target, hovering, hovering.value, { getXLabel }),\n ]\n }\n return (\n \n {target.renderResult(children, width, height, { attributes: { onMouseMove: e => setHovering(result.select({ x: e.clientX, y: e.clientY })) } })}\n
\n )\n}",props:[],componentName:"",parentComponentName:""},{path:"line-click-create.story",name:"",Component:D.default,code:"() => {\n const [contents, setContents] = React.useState([])\n const { line, onClick, onMove, input, reset } = useLineClickCreate(true, (c) => {\n setContents(produce(contents, (draft) => {\n draft.push(c)\n }))\n })\n useGlobalKeyDown(e => {\n if (e.key === 'Escape') {\n reset(true)\n }\n })\n\n return (\n \n
\n {input}\n
\n )\n}",props:[],componentName:"",parentComponentName:""},{path:"linear-dimension.story",name:"",Component:B.default,code:"() => {\n const dimension: LinearDimension = {\n p1: { x: 200, y: 200 },\n p2: { x: 300, y: 300 },\n position: {\n x: 400,\n y: 100,\n },\n fontFamily: 'monospace',\n fontSize: 16,\n direct: true,\n }\n const { regions, lines } = getLinearDimensionGeometries(\n dimension,\n dimensionStyle,\n (c) => getLinearDimensionTextPosition(c, dimensionStyle.margin, getTextSize)\n )\n const { textPosition, textRotation, text } = getLinearDimensionTextPosition(dimension, dimensionStyle.margin, getTextSize)\n return (\n \n )\n}",props:[],componentName:"",parentComponentName:""},{path:"menu.story",name:"",Component:z.default,code:"() => {\n return (\n \n )\n}",props:[],componentName:"",parentComponentName:""},{path:"minimap.story",name:"",Component:F.default,code:"() => {\n const { ref: scrollRef, x, setX, y, setY } = useWheelScroll()\n const { ref: zoomRef, scale } = useWheelZoom({\n onChange(oldScale, newScale, cursor) {\n const result = scaleByCursorPosition({ width, height }, newScale / oldScale, cursor)\n setX(result.setX)\n setY(result.setY)\n }\n })\n const target = reactSvgRenderTarget\n const minimapWidth = 100, minimapHeight = 100\n const size = useWindowSize()\n const width = size.width / 2, height = size.height / 2\n const contentWidth = 1200, contentHeight = 800\n const transform: Transform = {\n x,\n y,\n scale,\n center: {\n x: width / 2,\n y: height / 2,\n },\n }\n const children = [target.renderImage('https://farm9.staticflickr.com/8873/18598400202_3af67ef38f_z_d.jpg', 0, 0, contentWidth, contentHeight)]\n const { setMinimapTransform, minimap, getMinimapPosition } = useMinimap({\n width: minimapWidth,\n height: minimapHeight,\n viewport: {\n width: width / transform.scale,\n height: height / transform.scale,\n center: reverseTransformPosition(transform.center, transform),\n },\n children(minimapTransform) {\n return target.renderResult(children, minimapWidth, minimapHeight, {\n transform: minimapTransform, attributes: {\n onClick: e => {\n if (getMinimapPosition) {\n const p = getMinimapPosition(e)\n setX((transform.center.x - p.x) * transform.scale)\n setY((transform.center.y - p.y) * transform.scale)\n }\n }\n }\n })\n },\n })\n React.useEffect(() => {\n const bounding = {\n start: { x: 0, y: 0 },\n end: { x: contentWidth, y: contentHeight },\n }\n const result = zoomToFit(bounding, { width: minimapWidth, height: minimapHeight }, { x: minimapWidth / 2, y: minimapHeight / 2 }, 1)\n if (result) {\n setMinimapTransform({\n bounding,\n ...result,\n })\n }\n }, [])\n return (\n \n {target.renderResult(children, width, height, { transform, attributes: { style: { border: '1px solid green' } } })}\n {minimap}\n
\n )\n}",props:[],componentName:"",parentComponentName:""},{path:"opentype.story",name:"",Component:N.default,code:"() => {\n const size = useWindowSize()\n const width = size.width / 2\n const height = 300\n const { x, y, ref: wheelScrollRef, setX, setY } = useWheelScroll()\n const { scale, setScale, ref: wheelZoomRef } = useWheelZoom({\n onChange(oldScale, newScale, cursor) {\n const result = scaleByCursorPosition({ width, height }, newScale / oldScale, cursor)\n setX(result.setX)\n setY(result.setY)\n }\n })\n const [fonts, setFonts] = React.useState>()\n const [text, setText] = React.useState('测试ABC')\n const [fontFamily, setFontFamily] = React.useState(allFonts[0].name)\n const [fontSize, setFontSize] = React.useState(50)\n const [color, setColor] = React.useState(0x000000)\n const [backgroundColor, setBackgroundColor] = React.useState(0xffffff)\n const [xScale, setXScale] = React.useState(1)\n const [yScale, setYScale] = React.useState(1)\n const [commands, setCommands] = React.useState([])\n const [target, setTarget] = React.useState>(allRenderTargets[0])\n const font = fonts?.[fontFamily]\n\n React.useEffect(() => {\n const fetchFonts = async () => {\n const result: Record = {}\n for (const f of allFonts) {\n const res = await fetch(f.url)\n const buffer = await res.arrayBuffer()\n result[f.name] = opentype.parse(buffer)\n }\n setFonts(result)\n }\n fetchFonts()\n }, [])\n useGlobalKeyDown(e => {\n if (e.code === 'Digit0' && !e.shiftKey && metaKeyIfMacElseCtrlKey(e)) {\n setScale(1)\n setX(0)\n setY(0)\n e.preventDefault()\n }\n })\n\n React.useEffect(() => {\n if (!font) return\n const paths = font.getPaths(text, 0, fontSize, fontSize, { xScale: xScale * fontSize / font.unitsPerEm, yScale: yScale * fontSize / font.unitsPerEm })\n const commands = paths.map(path => opentypeCommandsToPathCommands(path))\n setCommands(commands)\n }, [text, font, fontSize, target, xScale, yScale])\n\n const children = commands.map(c => target.renderPathCommands(c, { fillColor: color, strokeColor: color })).flat()\n children.push(target.renderText(0, fontSize * 2, text, color, fontSize * Math.max(xScale, yScale), fontFamily))\n return (\n \n {target.renderResult(children, width, height, { transform: { x, y, scale }, backgroundColor })}\n
\n setText(v)} />,\n 'font family': t.name)} setValue={v => setFontFamily(allFonts.find(t => t.name === v)?.name ?? allFonts[0].name)} />,\n 'font size': setFontSize(v)} />,\n 'render target': t.type)} setValue={v => setTarget(allRenderTargets.find(t => t.type === v) ?? allRenderTargets[0])} />,\n color: setColor(v)} />,\n 'background color': setBackgroundColor(v)} />,\n 'x scale': setXScale(v)} />,\n 'y scale': setYScale(v)} />,\n actions: ,\n }}\n />\n
\n
\n )\n}",props:[],componentName:"",parentComponentName:""},{path:"partial-edit.story",name:"",Component:U.default,code:"() => {\n interface Content {\n value: number\n children?: Content[]\n }\n const [content, setContent] = React.useState({\n value: 1,\n children: [\n { value: 10 },\n { value: 100 }\n ]\n })\n const { editingContent, setEditingContentPath, prependPatchPath } = usePartialEdit(content)\n const addOne = () => {\n const [, patches] = produceWithPatches(editingContent, (draft) => {\n draft.value++\n })\n setContent(applyPatches(content, prependPatchPath(patches)))\n }\n\n return (\n <>\n \n \n \n {editingContent.value}\n {editingContent.children && editingContent.children.map((c, i) => (\n \n ))}\n
\n >\n )\n}",props:[],componentName:"",parentComponentName:""},{path:"patch-based-undo-redo.story",name:"",Component:G.default,code:"() => {\n const { state, setState, undo, redo } = usePatchBasedUndoRedo(initialState, 'a')\n useGlobalKeyDown(e => {\n if (e.code === 'KeyZ' && metaKeyIfMacElseCtrlKey(e)) {\n if (e.shiftKey) {\n redo(e)\n } else {\n undo(e)\n }\n }\n })\n return (\n \n )\n}",props:[],componentName:"",parentComponentName:""},{path:"path-click-create.story",name:"",Component:j.default,code:"() => {\n const [contents, setContents] = React.useState([])\n const { preview, onClick, onMove, input, setInputType, reset } = usePathClickCreate(true, (c) => {\n setContents(produce(contents, (draft) => {\n draft.push(c)\n }))\n })\n useGlobalKeyDown(e => {\n if (e.key === 'Escape') {\n reset(true)\n }\n })\n\n return (\n \n \n {(['line', 'arc', 'bezierCurve', 'quadraticCurve', 'close'] as const).map(m => )}\n {input}\n
\n )\n}",props:[],componentName:"",parentComponentName:""},{path:"pen-click-create.story",name:"",Component:V.default,code:"() => {\n const [contents, setContents] = React.useState([])\n const { points, onClick, onMove, reset } = usePenClickCreate(true, () => {\n setContents(produce(contents, (draft) => {\n draft.push(points)\n }))\n })\n useGlobalKeyDown(e => {\n if (e.key === 'Escape') {\n reset()\n }\n })\n\n return (\n \n
\n
\n )\n}",props:[],componentName:"",parentComponentName:""},{path:"pendulum.story",name:"",Component:W.default,code:"() => {\n const size = useWindowSize()\n const width = size.width / 2\n const height = size.height\n const target = reactCanvasRenderTarget\n const center = { x: width / 2, y: height / 3 }\n const [length, setLength] = React.useState(width / 2)\n const [editing, setEditing] = React.useState(false)\n const [state, setState] = React.useState({ radian: -Math.PI / 4, speed: 0 })\n const [editingState, setEditingState] = React.useState<(typeof state) & { length: number }>()\n const [running, setRunning, runningRef] = useRefState(false)\n const [runningState, setRunningState, runningStateRef] = useRefState2()\n const currentState = runningState ?? editingState ?? state\n const currentLength = editingState?.length ?? length\n const position = {\n x: center.x - currentLength * Math.sin(currentState.radian),\n y: center.y + currentLength * Math.cos(currentState.radian),\n r: 10,\n }\n const p = getPointByLengthAndRadian(position, currentState.speed * currentLength + position.r * (currentState.speed >= 0 ? 1 : -1), getTwoPointsRadian(position, center) + Math.PI / 2)\n const children = [\n target.renderCircle(center.x, center.y, 5),\n target.renderCircle(position.x, position.y, position.r, { fillColor: 0x000000, strokeWidth: 0 }),\n target.renderPolyline([center, position]),\n target.renderPolyline([position, p])\n ]\n\n const stop = () => {\n setRunning(false)\n setRunningState(undefined)\n }\n const run = () => {\n if (runningRef.current) {\n setRunning(false)\n return\n }\n setRunning(true)\n let lastTime: number | undefined\n const step = (time: number) => {\n if (!runningRef.current) return\n if (lastTime !== undefined) {\n const t = (time - lastTime) * 0.005\n const current = runningStateRef.current ?? state\n const initialY = center.y + currentLength * Math.cos(state.radian)\n const y = center.y + currentLength * Math.cos(current.radian)\n const g = 9.8\n let newSpeed = current.speed - g * Math.sin(current.radian) / currentLength * t\n if (y !== initialY) {\n const newSpeed2 = Math.sqrt(g * Math.abs(y - initialY) * 2) / currentLength\n if (newSpeed2 < Math.abs(newSpeed)) {\n newSpeed = Math.sign(newSpeed) * newSpeed2\n }\n }\n setRunningState({ radian: current.radian + current.speed * t, speed: newSpeed })\n }\n lastTime = time\n requestAnimationFrame(step)\n }\n requestAnimationFrame(step)\n }\n const onClick = useEvent(() => {\n if (editingState) {\n setState(editingState)\n setLength(editingState.length)\n setEditing(false)\n setEditingState(undefined)\n }\n })\n const onMouseMove = useEvent((e: React.MouseEvent) => {\n if (editing) {\n const p = { x: e.clientX, y: e.clientY }\n setEditingState({\n radian: getTwoPointsRadian(p, center) - Math.PI / 2,\n speed: 0,\n length: getTwoPointsDistance(p, center),\n })\n }\n })\n\n return (\n \n {target.renderResult(children, width, height, { attributes: { onClick } })}\n
\n \n {runningState !== undefined && }\n {runningState === undefined && }\n
\n
\n )\n}",props:[],componentName:"",parentComponentName:""},{path:"pie-chart.story",name:"",Component:H.default,code:"() => {\n const size = useWindowSize()\n const width = size.width / 2\n const height = 350\n const target = reactSvgRenderTarget\n const [hovering, setHovering] = React.useState()\n const [hovering2, setHovering2] = React.useState()\n const [result, setResult] = React.useState<{ children: SvgDraw[], select: (p: Position) => Position & { value: { x: number, y: number } } | undefined }>()\n const [result2, setResult2] = React.useState<{ children: SvgDraw[], select: (p: Position) => Position & { value: { x: number, y: number } } | undefined }>()\n const getXLabel = (x: number) => Intl.DateTimeFormat('zh', { month: 'long' }).format(new Date(x.toString()))\n\n React.useEffect(() => {\n const datas = [\n [65, 59, 80, 81, 56, 55, 40],\n [75, 49, 70, 71, 46, 45, 30],\n [85, 39, 60, 61, 36, 35, 20],\n ]\n const colors = [0xff0000, 0x00ff00, 0x0000ff, 0xff0000, 0x00ff00, 0x0000ff, 0x000000]\n setResult(getPieChart(datas, colors, target, { width, height }, { left: 10, right: 10, top: 10, bottom: 10 }))\n setResult2(getPieChart(datas, colors, target, { width, height }, { left: 10, right: 10, top: 10, bottom: 10 }, { type: 'doughnut' }))\n }, [width])\n\n if (!result || !result2) {\n return null\n }\n let children = result.children\n if (hovering) {\n children = [\n ...result.children,\n ...renderChartTooltip(target, hovering, hovering.value, { getXLabel }),\n ]\n }\n let children2 = result2.children\n if (hovering2) {\n children2 = [\n ...result2.children,\n ...renderChartTooltip(target, hovering2, hovering2.value, { getXLabel }),\n ]\n }\n return (\n \n {target.renderResult(children, width, height, { attributes: { onMouseMove: e => setHovering(result.select({ x: e.clientX, y: e.clientY })) } })}\n {target.renderResult(children2, width, height, { attributes: { onMouseMove: e => setHovering2(result2.select({ x: e.clientX, y: e.clientY - height })) } })}\n
\n )\n}",props:[],componentName:"",parentComponentName:""},{path:"point-snap.story",name:"",Component:q.default,code:"() => {\n const [position, setPosition] = React.useState()\n const { width, height } = useWindowSize()\n const startPosition = { x: 500, y: 100 }\n const gridSize = 20\n const { getSnapAssistentContents, getSnapPoint } = usePointSnap(\n true,\n (c1, c2) => intersectionPointsCache.get(c1, c2, () => Array.from(iterateIntersectionPoints(c1, c2, contents, () => ({ getGeometries: (c) => ({ lines: [{ type: 'arc', curve: circleToArc(c) }] }) })))),\n allSnapTypes,\n () => ({\n getSnapPoints(c) {\n return [\n { x: c.x, y: c.y, type: 'center' },\n { x: c.x - c.r, y: c.y, type: 'endpoint' },\n { x: c.x + c.r, y: c.y, type: 'endpoint' },\n { x: c.x, y: c.y - c.r, type: 'endpoint' },\n { x: c.x, y: c.y + c.r, type: 'endpoint' },\n ]\n },\n getGeometries(c) {\n return {\n lines: [{ type: 'arc', curve: circleToArc(c) }],\n bounding: {\n start: { x: c.x - c.r, y: c.y - c.r },\n end: { x: c.x + c.r, y: c.y + c.r },\n }\n }\n },\n }),\n undefined, undefined,\n p => ({ x: formatNumber(p.x, 1 / gridSize), y: formatNumber(p.y, 1 / gridSize) }),\n )\n const assistentContents = getSnapAssistentContents(\n (circle) => ({ type: 'circle' as const, ...circle }),\n (rect) => ({ type: 'rect' as const, ...rect }),\n (points) => ({ type: 'polyline' as const, points }),\n (ray) => ({ type: 'ray' as const, ...ray }),\n )\n const lines = getGridLines({ start: { x: 0, y: 0 }, end: { x: width / 2, y: height } }, gridSize)\n return (\n <>\n \n >\n )\n}",props:[],componentName:"",parentComponentName:""},{path:"polar-area-chart.story",name:"",Component:$.default,code:"() => {\n const size = useWindowSize()\n const width = size.width / 2\n const height = 350\n const target = reactSvgRenderTarget\n const [hovering, setHovering] = React.useState()\n const [result, setResult] = React.useState<{ children: SvgDraw[], select: (p: Position) => Position & { value: { x: number, y: number } } | undefined }>()\n const getXLabel = (x: number) => Intl.DateTimeFormat('zh', { month: 'long' }).format(new Date((x + 1).toString()))\n\n React.useEffect(() => {\n const datas = [65, 59, 80, 81, 56, 55, 40]\n const colors = [0xff0000, 0x00ff00, 0x0000ff, 0xff0000, 0x00ff00, 0x0000ff, 0x000000]\n const r = getPolarAreaChart(datas, colors, target, { width, height }, 10, { left: 10, right: 10, top: 30, bottom: 10 })\n r.angles.forEach((angle, i) => {\n const p = getArcPointAtAngle({ ...r.circle, r: r.circle.r + 30 }, angle)\n r.children.push(target.renderText(p.x, p.y, getXLabel(i), 0xcccccc, 20, 'monospace', { textAlign: 'center', textBaseline: 'middle' }))\n })\n setResult(r)\n }, [width])\n\n if (!result) {\n return null\n }\n let children = result.children\n if (hovering) {\n children = [\n ...result.children,\n ...renderChartTooltip(target, hovering, hovering.value, { getXLabel }),\n ]\n }\n return (\n \n {target.renderResult(children, width, height, { attributes: { onMouseMove: e => setHovering(result.select({ x: e.clientX, y: e.clientY })) } })}\n
\n )\n}",props:[],componentName:"",parentComponentName:""},{path:"polygon-click-create.story",name:"",Component:X.default,code:"() => {\n const [contents, setContents] = React.useState([])\n const { polygon, onClick, onMove, input, reset } = usePolygonClickCreate(true, (c) => {\n const data = c || polygon\n if (data) {\n setContents(produce(contents, (draft) => {\n draft.push(data)\n }))\n }\n })\n useGlobalKeyDown(e => {\n if (e.key === 'Escape') {\n reset()\n }\n })\n\n return (\n \n
\n {input}\n
\n )\n}",props:[],componentName:"",parentComponentName:""},{path:"polyline-edit.story",name:"",Component:Y.default,code:"() => {\n const [content, setContent] = React.useState([\n { x: 100, y: 100 },\n { x: 300, y: 200 },\n { x: 100, y: 200 },\n ])\n const { offset, onStart, mask, reset } = usePolylineEdit(() => setContent(points))\n const points = produce(content, (draft) => {\n if (offset) {\n for (const pointIndex of offset.pointIndexes) {\n draft[pointIndex].x += offset.x\n draft[pointIndex].y += offset.y\n }\n }\n })\n useGlobalKeyDown(e => {\n if (e.key === 'Escape') {\n reset()\n }\n })\n return (\n <>\n \n onStart(e, pointIndexes)}\n />\n {mask}\n >\n )\n}",props:[],componentName:"",parentComponentName:""},{path:"radar-chart.story",name:"",Component:K.default,code:"() => {\n const size = useWindowSize()\n const width = size.width / 2\n const height = 350\n const target = reactSvgRenderTarget\n const [hovering, setHovering] = React.useState()\n const [result, setResult] = React.useState<{ children: SvgDraw[], select: (p: Position) => Position & { value: { x: number, y: number } } | undefined }>()\n const getXLabel = (x: number) => Intl.DateTimeFormat('zh', { month: 'long' }).format(new Date((x + 1).toString()))\n\n React.useEffect(() => {\n const datas = [\n [65, 59, 80, 81, 56, 55, 40],\n [45, 39, 60, 61, 36, 35, 20],\n ]\n const colors = [0xff0000, 0x00ff00]\n const r = getRadarChart(datas, colors, target, { width, height }, 20, { left: 10, right: 10, top: 30, bottom: 30 })\n r.angles.forEach((angle, i) => {\n const p = getArcPointAtAngle({ ...r.circle, r: r.circle.r + 15 }, angle)\n r.children.push(target.renderText(p.x, p.y, getXLabel(i), 0xcccccc, 12, 'monospace', { textAlign: 'center', textBaseline: 'middle' }))\n })\n setResult(r)\n }, [width])\n\n if (!result) {\n return null\n }\n let children = result.children\n if (hovering) {\n children = [\n ...result.children,\n ...renderChartTooltip(target, hovering, hovering.value, { getXLabel }),\n ]\n }\n return (\n \n {target.renderResult(children, width, height, { attributes: { onMouseMove: e => setHovering(result.select({ x: e.clientX, y: e.clientY })) } })}\n
\n )\n}",props:[],componentName:"",parentComponentName:""},{path:"radial-dimension.story",name:"",Component:Z.default,code:"() => {\n const circle: Circle = {\n x: 200,\n y: 200,\n r: 100,\n }\n const dimension: RadialDimension = {\n position: {\n x: 400,\n y: 300,\n },\n fontFamily: 'monospace',\n fontSize: 16,\n }\n const { regions, lines } = getRadialDimensionGeometries(\n dimension,\n circle,\n dimensionStyle,\n (d, c) => getRadialDimensionTextPosition(d, c, dimensionStyle.margin, getTextSize)\n )\n const { textPosition, textRotation, text } = getRadialDimensionTextPosition(dimension, circle, dimensionStyle.margin, getTextSize)\n return (\n \n )\n}",props:[],componentName:"",parentComponentName:""},{path:"react-composable-json-editor.story",name:"",Component:Q.default,code:"() => {\n const [readOnly, setReadOnly] = React.useState(false)\n const { value, update, getArrayProps } = useJsonEditorData({\n stringExample: 'a string example',\n booleanExample: false,\n numberExample: 123.4,\n objectExample: {\n propertyExample1: '',\n propertyExample2: 0,\n },\n inlineObjectExample: {\n propertyExample1: '',\n propertyExample2: 0,\n },\n arrayExample: ['item1', 'item2'],\n inlineArrayExample: ['item1', 'item2'],\n optionalExample: undefined as string | undefined,\n enumExample: 'enum 1' as 'enum 1' | 'enum 2',\n colorExample: '#000000',\n textareaExample: '',\n imagePreviewExample: 'http://image2.sina.com.cn/bj/art/2004-08-02/U91P52T4D51657F160DT20040802125523.jpg',\n itemTitleExample: [\n {\n propertyExample1: 'foo',\n propertyExample2: 1,\n },\n {\n propertyExample1: 'bar',\n propertyExample2: 2,\n },\n ],\n inlineObjectArrayExample: [\n {\n propertyExample1: 'foo',\n propertyExample2: 1,\n propertyExample3: {\n propertyExample4: 2,\n propertyExample5: '',\n },\n },\n {\n propertyExample1: 'bar',\n propertyExample2: 2,\n propertyExample3: {\n propertyExample4: 3,\n propertyExample5: '',\n },\n },\n ],\n enumTitlesExample: 'enum 1' as 'enum 1' | 'enum 2',\n enumArrayExample: ['foo'] as ('foo' | 'bar')[],\n })\n const valueHtml = JSON.stringify(value, null, ' ')\n return (\n \n
setReadOnly(v)} /> read only\n
\n \n
draft.stringExample = v)} />,\n 'A boolean example': draft.booleanExample = v)} />,\n 'A number example': draft.numberExample = v)} />,\n 'A object example': draft.objectExample.propertyExample1 = v)} />,\n 'Property example 2': draft.objectExample.propertyExample2 = v)} />,\n }}\n />,\n 'A inline object example': draft.inlineObjectExample.propertyExample1 = v)} />,\n 'Property example 2': draft.inlineObjectExample.propertyExample2 = v)} />,\n }}\n />,\n 'A array example': v.arrayExample, '')}\n items={value.arrayExample.map((f, i) => draft.arrayExample[i] = v)} />)}\n />,\n 'A inline array example': v.inlineArrayExample, '')}\n items={value.inlineArrayExample.map((f, i) => draft.inlineArrayExample[i] = v)} />)}\n />,\n 'A optional example': [\n draft.optionalExample = v ? '' : undefined)} />,\n value.optionalExample !== undefined ? draft.optionalExample = v)} /> : undefined,\n ],\n 'A enum example': draft.enumExample = v)} />,\n 'A enum example 2': draft.enumExample = v)} />,\n 'A color example': draft.colorExample = v)} />,\n 'A textarea example': draft.textareaExample = v)} />,\n 'A image preview example': draft.imagePreviewExample = v)} />,\n 'A item title example': v.itemTitleExample, { propertyExample1: '', propertyExample2: 0 })}\n title={(i) => value.itemTitleExample[i].propertyExample1}\n items={value.itemTitleExample.map((f, i) => draft.itemTitleExample[i].propertyExample1 = v)} />,\n 'Property example 2': draft.itemTitleExample[i].propertyExample2 = v)} />,\n }}\n />)}\n />,\n 'A inline object array example': v.inlineObjectArrayExample, { propertyExample1: '', propertyExample2: 0, propertyExample3: { propertyExample4: 0, propertyExample5: '' } })}\n properties={value.inlineObjectArrayExample.map((f, i) => ({\n 'Property example 1': draft.inlineObjectArrayExample[i].propertyExample1 = v)} />,\n 'Property example 2': draft.inlineObjectArrayExample[i].propertyExample2 = v)} />,\n 'Property example 3': draft.inlineObjectArrayExample[i].propertyExample3.propertyExample4 = v)} />,\n 'Property example 4': draft.inlineObjectArrayExample[i].propertyExample3.propertyExample5 = v)} />,\n }}\n />,\n }))}\n />,\n 'A enum titles example': draft.enumTitlesExample = v)} />,\n 'A enum array example': draft.enumArrayExample = v)} />,\n }}\n readOnly={readOnly}\n />\n \n \n \n )\n}",props:[],componentName:"",parentComponentName:""},{path:"react-render-target.story",name:"",Component:J.default,code:"() => {\n const renderArcs = (target: ReactRenderTarget) => target.renderResult([\n target.renderArc(40, 20, 50, 0, 120, { fillPattern: { width: 10, height: 10, pattern: () => target.renderPath([[{ x: 0, y: 5 }, { x: 5, y: 0 }], [{ x: 10, y: 5 }, { x: 5, y: 10 }]], { strokeColor: 0x0000ff }) } }),\n target.renderArc(40, 40, 80, 0, 120, { fillColor: 0xff0000, strokeWidth: 0 }),\n target.renderArc(50, 50, 100, 0, 120, { strokeColor: 0x00ff00 }),\n target.renderArc(60, 60, 100, 0, 120, { strokeWidth: 5 }),\n target.renderArc(70, 70, 100, 0, 120, { dashArray: [4] }),\n target.renderArc(170, 170, 30, 0, 120, { counterclockwise: true }),\n target.renderArc(170, 170, 20, 120, 0, { counterclockwise: true }),\n target.renderArc(120, 200, 15, 0, 360,),\n target.renderArc(120, 200, 10, 360, 0, { counterclockwise: true }),\n target.renderArc(170, 170, 10, 0, 120, { closed: true }),\n ], 230, 310)\n\n const renderCircles = (target: ReactRenderTarget) => target.renderResult([\n target.renderCircle(70, 100, 30, { fillPattern: { width: 10, height: 10, pattern: () => target.renderPath([[{ x: 0, y: 5 }, { x: 5, y: 0 }], [{ x: 10, y: 5 }, { x: 5, y: 10 }]], { strokeColor: 0x0000ff }) } }),\n target.renderCircle(150, 100, 30, { fillColor: 0xff0000, strokeWidth: 0 }),\n target.renderCircle(110, 100, 70, { strokeColor: 0x00ff00 }),\n target.renderCircle(110, 100, 80, { strokeWidth: 5 }),\n target.renderCircle(110, 100, 90, { dashArray: [4] }),\n ], 230, 200)\n\n const renderTexts = (target: ReactRenderTarget) => target.renderResult([\n target.renderText(10, 30, 'Hello World!', 0xff0000, 30, 'monospace'),\n target.renderText(10, 60, 'Hello World!', 0xff0000, 30, 'monospace', { fontWeight: 'bold' }),\n target.renderText(10, 90, 'Hello World!', 0xff0000, 30, 'monospace', { fontStyle: 'italic' }),\n target.renderText(10, 150, 'He', { width: 4, height: 4, pattern: () => target.renderPath([[{ x: 0, y: 2 }, { x: 2, y: 0 }], [{ x: 4, y: 2 }, { x: 2, y: 4 }]], { strokeColor: 0x0000ff }) }, 70, 'monospace'),\n target.renderText(90, 150, 'l', undefined, 70, 'monospace', { strokeColor: 0xff0000 }),\n target.renderText(130, 150, 'l', undefined, 70, 'monospace', { strokeColor: 0xff0000, dashArray: [2] }),\n target.renderText(170, 150, 'l', undefined, 70, 'monospace', { strokeColor: 0xff0000, strokeWidth: 3 }),\n target.renderText(10, 200, 'H', 0x00ff00, 70, 'monospace', { strokeColor: 0xff0000, strokeWidth: 3 }),\n target.renderText(50, 200, 'H', 0x00ff00, 70, 'monospace', { strokeColor: 0xff0000, strokeWidth: 3, strokeOpacity: 0.3, fillOpacity: 0.3 }),\n target.renderText(90, 200, 'H', undefined, 70, 'monospace', { strokePattern: { width: 4, height: 4, pattern: () => target.renderPath([[{ x: 0, y: 2 }, { x: 2, y: 0 }], [{ x: 4, y: 2 }, { x: 2, y: 4 }]], { strokeColor: 0x0000ff }) }, strokeWidth: 3 }),\n target.renderText(130, 200, 'H', undefined, 70, 'monospace', { strokeLinearGradient: { start: { x: 150, y: 230 }, end: { x: 190, y: 150 }, stops: [{ offset: 0.2, color: 0xff0000 }, { offset: 0.5, color: 0xffff00 }, { offset: 0.8, color: 0x00ff00 }] }, strokeWidth: 3 }),\n target.renderText(170, 200, 'H', undefined, 70, 'monospace', { strokeRadialGradient: { start: { x: 190, y: 185, r: 5 }, end: { x: 190, y: 180, r: 30 }, stops: [{ offset: 0, color: 0xff0000 }, { offset: 0.5, color: 0xffff00 }, { offset: 1, color: 0x00ff00 }] }, strokeWidth: 3 }),\n target.renderText(70, 225, 'center', 0x00ff00, 30, 'monospace', { textAlign: 'center' }),\n target.renderText(130, 250, 'right', 0x00ff00, 30, 'monospace', { textAlign: 'right' }),\n target.renderText(130, 250, 'H', undefined, 70, 'monospace', { fillLinearGradient: { start: { x: 150, y: 280 }, end: { x: 190, y: 200 }, stops: [{ offset: 0.2, color: 0xff0000 }, { offset: 0.5, color: 0xffff00 }, { offset: 0.8, color: 0x00ff00 }] }, strokeWidth: 3 }),\n target.renderText(170, 250, 'H', undefined, 70, 'monospace', { fillRadialGradient: { start: { x: 190, y: 235, r: 5 }, end: { x: 190, y: 230, r: 30 }, stops: [{ offset: 0, color: 0xff0000 }, { offset: 0.5, color: 0xffff00 }, { offset: 1, color: 0x00ff00 }] }, strokeWidth: 3 }),\n target.renderText(10, 300, 'fgj', 0x00ff00, 30, 'monospace', { textBaseline: 'alphabetic' }),\n target.renderText(65, 300, 'fgj', 0x00ff00, 30, 'monospace', { textBaseline: 'top' }),\n target.renderText(120, 300, 'fgj', 0x00ff00, 30, 'monospace', { textBaseline: 'middle' }),\n target.renderText(175, 300, 'fgj', 0x00ff00, 30, 'monospace', { textBaseline: 'bottom' }),\n ], 230, 550)\n\n const renderEllipseArcs = (target: ReactRenderTarget) => target.renderResult([\n target.renderEllipseArc(40, 10, 50, 30, 0, 120, { fillPattern: { width: 10, height: 10, pattern: () => target.renderPath([[{ x: 0, y: 5 }, { x: 5, y: 0 }], [{ x: 10, y: 5 }, { x: 5, y: 10 }]], { strokeColor: 0x0000ff }) } }),\n target.renderEllipseArc(40, 30, 80, 40, 0, 120, { fillColor: 0xff0000, strokeWidth: 0 }),\n target.renderEllipseArc(50, 40, 100, 50, 0, 120, { strokeColor: 0x00ff00 }),\n target.renderEllipseArc(60, 50, 100, 50, 0, 120, { strokeWidth: 5 }),\n target.renderEllipseArc(70, 60, 100, 50, 0, 120, { dashArray: [4] }),\n target.renderEllipseArc(170, 160, 30, 15, 0, 120, { counterclockwise: true }),\n target.renderEllipseArc(170, 160, 30, 25, 120, 20, { counterclockwise: true }),\n target.renderEllipseArc(110, 100, 80, 40, 0, 120, { strokeColor: 0x00ff00, angle: 30 }),\n target.renderEllipseArc(120, 200, 30, 15, 0, 360,),\n target.renderEllipseArc(120, 200, 20, 10, 360, 0, { counterclockwise: true }),\n target.renderEllipseArc(170, 160, 25, 20, 0, 120, { closed: true }),\n ], 230, 330)\n\n const renderEllipses = (target: ReactRenderTarget) => target.renderResult([\n target.renderEllipse(70, 60, 40, 20, { fillPattern: { width: 10, height: 10, pattern: () => target.renderPath([[{ x: 0, y: 5 }, { x: 5, y: 0 }], [{ x: 10, y: 5 }, { x: 5, y: 10 }]], { strokeColor: 0x0000ff }) } }),\n target.renderEllipse(150, 60, 40, 20, { fillColor: 0xff0000, strokeWidth: 0 }),\n target.renderEllipse(110, 60, 90, 45, { strokeColor: 0x00ff00 }),\n target.renderEllipse(110, 60, 100, 50, { strokeWidth: 5 }),\n target.renderEllipse(110, 60, 110, 55, { dashArray: [4] }),\n target.renderEllipse(110, 140, 80, 40, { strokeColor: 0x0000ff, angle: 30 }),\n target.renderEllipse(110, 30, 10, 20, { angle: 60, fillPattern: { width: 10, height: 10, pattern: () => target.renderPath([[{ x: 0, y: 5 }, { x: 5, y: 0 }], [{ x: 10, y: 5 }, { x: 5, y: 10 }]], { strokeColor: 0x0000ff }) } }),\n ], 230, 230)\n\n const renderRects = (target: ReactRenderTarget) => target.renderResult([\n target.renderRect(10, 10, 50, 30, { fillPattern: { width: 10, height: 10, pattern: () => target.renderPath([[{ x: 0, y: 5 }, { x: 5, y: 0 }], [{ x: 10, y: 5 }, { x: 5, y: 10 }]], { strokeColor: 0x0000ff }) } }),\n target.renderRect(70, 10, 80, 40, { fillColor: 0xff0000, strokeWidth: 0 }),\n target.renderRect(90, 60, 100, 140, { strokeColor: 0x00ff00 }),\n target.renderRect(100, 70, 80, 120, { strokeWidth: 5 }),\n target.renderRect(110, 80, 60, 100, { dashArray: [4] }),\n target.renderRect(10, 90, 60, 30, { angle: 60 }),\n ], 230, 220)\n\n const renderPaths = (target: ReactRenderTarget) => target.renderResult([\n target.renderPath([[{ x: 5, y: 10 }, { x: 45, y: 150 }, { x: 45, y: 10 }], [{ x: 25, y: 30 }, { x: 25, y: 70 }, { x: 35, y: 70 }, { x: 35, y: 30 }]], { fillPattern: { width: 10, height: 10, pattern: () => target.renderPath([[{ x: 0, y: 5 }, { x: 5, y: 0 }], [{ x: 10, y: 5 }, { x: 5, y: 10 }]], { strokeColor: 0x0000ff }) }, strokeWidth: 0 }),\n target.renderPath([[{ x: 50, y: 10 }, { x: 90, y: 150 }, { x: 90, y: 10 }], [{ x: 70, y: 30 }, { x: 70, y: 70 }, { x: 80, y: 70 }, { x: 80, y: 30 }]], { fillColor: 0xff0000, strokeWidth: 0 }),\n target.renderPath([[{ x: 95, y: 10 }, { x: 135, y: 150 }, { x: 135, y: 10 }], [{ x: 115, y: 30 }, { x: 115, y: 70 }, { x: 125, y: 70 }, { x: 125, y: 30 }]], { strokeColor: 0x00ff00 }),\n target.renderPath([[{ x: 140, y: 10 }, { x: 180, y: 150 }, { x: 180, y: 10 }], [{ x: 160, y: 30 }, { x: 160, y: 70 }, { x: 170, y: 70 }, { x: 170, y: 30 }]], { fillPattern: { width: 100, height: 100, pattern: () => target.renderImage('https://farm9.staticflickr.com/8873/18598400202_3af67ef38f_z_d.jpg', 0, 0, 100, 100, { crossOrigin: '' }) }, strokeWidth: 0 }),\n target.renderPath([[{ x: 185, y: 10 }, { x: 225, y: 150 }, { x: 225, y: 10 }], [{ x: 205, y: 30 }, { x: 205, y: 70 }, { x: 215, y: 70 }, { x: 215, y: 30 }]], { dashArray: [4] }),\n target.renderPath([[{ x: 5, y: 160 }, { x: 35, y: 160 }, { x: 35, y: 190 }]], { strokeColor: 0xff0000, strokeWidth: 5 }),\n target.renderPath([[{ x: 45, y: 160 }, { x: 75, y: 160 }, { x: 75, y: 190 }]], { strokeColor: 0xff0000, strokeWidth: 5, closed: true }),\n target.renderPath([[{ x: 85, y: 160 }, { x: 125, y: 160 }, { x: 125, y: 190 }]], { strokeColor: 0xff0000, strokeWidth: 5, closed: true, miterLimit: 2 }),\n target.renderPath([[{ x: 135, y: 160 }, { x: 175, y: 160 }, { x: 175, y: 190 }]], { strokeColor: 0xff0000, strokeWidth: 10, lineJoin: 'bevel' }),\n target.renderPath([[{ x: 185, y: 160 }, { x: 225, y: 160 }, { x: 225, y: 190 }]], { strokeColor: 0xff0000, strokeWidth: 10, lineJoin: 'round' }),\n target.renderPath([[{ x: 10, y: 210 }, { x: 40, y: 210 }, { x: 40, y: 240 }]], { strokeColor: 0xff0000, strokeWidth: 10, lineCap: 'square' }),\n target.renderPath([[{ x: 55, y: 210 }, { x: 85, y: 210 }, { x: 85, y: 240 }]], { strokeColor: 0xff0000, strokeWidth: 10, lineCap: 'round' }),\n target.renderPath([[{ x: 100, y: 210 }, { x: 220, y: 210 }]], { dashArray: [12, 4] }),\n target.renderPath([[{ x: 100, y: 220 }, { x: 220, y: 220 }]], { dashArray: [12, 4], dashOffset: 4 }),\n target.renderPath([[{ x: 5, y: 250 }, { x: 45, y: 390 }, { x: 45, y: 250 }], [{ x: 25, y: 270 }, { x: 25, y: 310 }, { x: 35, y: 310 }, { x: 35, y: 270 }]], { fillLinearGradient: { start: { x: 5, y: 250 }, end: { x: 45, y: 390 }, stops: [{ offset: 0.2, color: 0xff0000 }, { offset: 0.5, color: 0xffff00 }, { offset: 0.8, color: 0x00ff00 }] }, strokeWidth: 0 }),\n target.renderPath([[{ x: 50, y: 250 }, { x: 90, y: 390 }, { x: 90, y: 250 }], [{ x: 70, y: 270 }, { x: 70, y: 310 }, { x: 80, y: 310 }, { x: 80, y: 270 }]], { fillRadialGradient: { start: { x: 70, y: 320, r: 10 }, end: { x: 70, y: 320, r: 70 }, stops: [{ offset: 0, color: 0xff0000 }, { offset: 0.5, color: 0xffff00 }, { offset: 1, color: 0x00ff00 }] }, strokeWidth: 0 }),\n target.renderPath([[{ x: 95, y: 250 }, { x: 135, y: 390 }, { x: 135, y: 250 }], [{ x: 115, y: 270 }, { x: 115, y: 310 }, { x: 125, y: 310 }, { x: 125, y: 270 }]], { fillColor: 0xff0000, fillOpacity: 0.3, strokeOpacity: 0.3 }),\n target.renderPath([[{ x: 140, y: 250 }, { x: 180, y: 390 }, { x: 180, y: 250 }], [{ x: 160, y: 270 }, { x: 160, y: 310 }, { x: 170, y: 310 }, { x: 170, y: 270 }]], { fillRadialGradient: { start: { x: 160, y: 320, r: 10 }, end: { x: 160, y: 320, r: 70 }, stops: [{ offset: 0, color: 0xff0000, opacity: 0.3 }, { offset: 0.5, color: 0xffff00, opacity: 0.3 }, { offset: 1, color: 0x00ff00, opacity: 0.3 }] }, strokeWidth: 0 }),\n target.renderPath([[{ x: 185, y: 250 }, { x: 225, y: 390 }, { x: 225, y: 250 }], [{ x: 205, y: 270 }, { x: 205, y: 310 }, { x: 215, y: 310 }, { x: 215, y: 270 }]], { strokePattern: { width: 10, height: 10, pattern: () => target.renderPath([[{ x: 0, y: 5 }, { x: 5, y: 0 }], [{ x: 10, y: 5 }, { x: 5, y: 10 }]], { strokeColor: 0x0000ff }) }, strokeWidth: 5 }),\n target.renderPath([[{ x: 5, y: 400 }, { x: 45, y: 540 }, { x: 45, y: 400 }], [{ x: 25, y: 420 }, { x: 25, y: 460 }, { x: 35, y: 460 }, { x: 35, y: 420 }]], { strokeLinearGradient: { start: { x: 5, y: 400 }, end: { x: 45, y: 540 }, stops: [{ offset: 0.2, color: 0xff0000 }, { offset: 0.5, color: 0xffff00 }, { offset: 0.8, color: 0x00ff00 }] }, strokeWidth: 5 }),\n target.renderPath([[{ x: 50, y: 400 }, { x: 90, y: 540 }, { x: 90, y: 400 }], [{ x: 70, y: 420 }, { x: 70, y: 460 }, { x: 80, y: 460 }, { x: 80, y: 420 }]], { strokeRadialGradient: { start: { x: 70, y: 470, r: 10 }, end: { x: 70, y: 470, r: 70 }, stops: [{ offset: 0, color: 0xff0000 }, { offset: 0.5, color: 0xffff00 }, { offset: 1, color: 0x00ff00 }] }, strokeWidth: 5 }),\n target.renderPath([[{ x: 110, y: 400 }, { x: 110, y: 470 }, { x: 110, y: 540 }]], { strokeColor: 0xff0000, strokeWidth: 10 }),\n target.renderPath([[{ x: 130, y: 400 }, { x: 130, y: 540 }, { x: 130, y: 470 }]], { strokeColor: 0xff0000, strokeWidth: 10 }),\n ], 230, 620)\n\n const renderImages = (target: ReactRenderTarget) => target.renderResult([\n target.renderImage('https://farm9.staticflickr.com/8873/18598400202_3af67ef38f_z_d.jpg', 0, 0, 75, 65, { crossOrigin: '' }),\n target.renderImage('https://farm9.staticflickr.com/8873/18598400202_3af67ef38f_z_d.jpg', 77, 0, 75, 65, { opacity: 0.5, crossOrigin: '' }),\n target.renderImage('https://farm9.staticflickr.com/8873/18598400202_3af67ef38f_z_d.jpg', 154, 0, 75, 65, { filters: [{ type: 'brightness', value: 2 }], crossOrigin: '' }),\n target.renderImage('https://farm9.staticflickr.com/8873/18598400202_3af67ef38f_z_d.jpg', 0, 70, 75, 65, { filters: [{ type: 'contrast', value: 2 }], crossOrigin: '' }),\n target.renderImage('https://farm9.staticflickr.com/8873/18598400202_3af67ef38f_z_d.jpg', 77, 70, 75, 65, { filters: [{ type: 'hue-rotate', value: 90 }], crossOrigin: '' }),\n target.renderImage('https://farm9.staticflickr.com/8873/18598400202_3af67ef38f_z_d.jpg', 154, 70, 75, 65, { filters: [{ type: 'saturate', value: 2 }], crossOrigin: '' }),\n target.renderImage('https://farm9.staticflickr.com/8873/18598400202_3af67ef38f_z_d.jpg', 0, 140, 75, 65, { filters: [{ type: 'saturate', value: 2 }, { type: 'hue-rotate', value: 90 }], crossOrigin: '' }),\n target.renderImage('https://farm9.staticflickr.com/8873/18598400202_3af67ef38f_z_d.jpg', 77, 140, 75, 65, { filters: [{ type: 'saturate', value: 2 }, { type: 'hue-rotate', value: 90 }, { type: 'contrast', value: 2 }], crossOrigin: '' }),\n target.renderImage('https://farm9.staticflickr.com/8873/18598400202_3af67ef38f_z_d.jpg', 154, 140, 75, 65, { filters: [{ type: 'grayscale', value: 1 }], crossOrigin: '' }),\n target.renderImage('https://farm9.staticflickr.com/8873/18598400202_3af67ef38f_z_d.jpg', 0, 210, 75, 65, { filters: [{ type: 'sepia', value: 1 }], crossOrigin: '' }),\n target.renderImage('https://farm9.staticflickr.com/8873/18598400202_3af67ef38f_z_d.jpg', 77, 210, 75, 65, { filters: [{ type: 'invert', value: 1 }], crossOrigin: '' }),\n target.renderImage('https://farm9.staticflickr.com/8873/18598400202_3af67ef38f_z_d.jpg', 154, 210, 75, 65, { filters: [{ type: 'opacity', value: 0.5 }], crossOrigin: '' }),\n target.renderImage('https://farm9.staticflickr.com/8873/18598400202_3af67ef38f_z_d.jpg', 0, 280, 75, 65, { filters: [{ type: 'blur', value: 2 }], crossOrigin: '' }),\n ], 230, 370)\n\n const renderPolylines = (target: ReactRenderTarget) => target.renderResult([\n target.renderPolyline([{ x: 5, y: 10 }, { x: 45, y: 150 }, { x: 45, y: 10 }], { fillPattern: { width: 10, height: 10, pattern: () => target.renderPath([[{ x: 0, y: 5 }, { x: 5, y: 0 }], [{ x: 10, y: 5 }, { x: 5, y: 10 }]], { strokeColor: 0x0000ff }) } }),\n target.renderPolyline([{ x: 50, y: 10 }, { x: 90, y: 150 }, { x: 90, y: 10 }], { fillColor: 0xff0000, strokeWidth: 0 }),\n target.renderPolyline([{ x: 95, y: 10 }, { x: 135, y: 150 }, { x: 135, y: 10 }], { strokeColor: 0x00ff00 }),\n target.renderPolyline([{ x: 140, y: 10 }, { x: 180, y: 150 }, { x: 180, y: 10 }], { strokeWidth: 5 }),\n target.renderPolyline([{ x: 185, y: 10 }, { x: 225, y: 150 }, { x: 225, y: 10 }], { dashArray: [4] }),\n target.renderPolyline([{ x: 195, y: 10 }, { x: 215, y: 80 }, { x: 215, y: 10 }], { closed: true }),\n ], 230, 220)\n\n const renderPolygons = (target: ReactRenderTarget) => target.renderResult([\n target.renderPolygon([{ x: 5, y: 10 }, { x: 45, y: 150 }, { x: 45, y: 10 }], { fillPattern: { width: 10, height: 10, pattern: () => target.renderPath([[{ x: 0, y: 5 }, { x: 5, y: 0 }], [{ x: 10, y: 5 }, { x: 5, y: 10 }]], { strokeColor: 0x0000ff }) } }),\n target.renderPolygon([{ x: 50, y: 10 }, { x: 90, y: 150 }, { x: 90, y: 10 }], { fillColor: 0xff0000, strokeWidth: 0 }),\n target.renderPolygon([{ x: 95, y: 10 }, { x: 135, y: 150 }, { x: 135, y: 10 }], { strokeColor: 0x00ff00 }),\n target.renderPolygon([{ x: 140, y: 10 }, { x: 180, y: 150 }, { x: 180, y: 10 }], { strokeWidth: 5 }),\n target.renderPolygon([{ x: 185, y: 10 }, { x: 225, y: 150 }, { x: 225, y: 10 }], { dashArray: [4] }),\n ], 230, 190)\n\n const renderPathCommands = (target: ReactRenderTarget) => target.renderResult([\n target.renderPathCommands([{ type: 'move', to: { x: 220, y: 10 } }, { type: 'arc', from: { x: 220, y: 80 }, to: { x: 150, y: 10 }, radius: 20 }, { type: 'line', to: { x: 150, y: 10 } }, { type: 'quadraticCurve', cp: { x: 150, y: 90 }, to: { x: 110, y: 70 } }, { type: 'bezierCurve', cp1: { x: 70, y: 20 }, cp2: { x: 40, y: 80 }, to: { x: 10, y: 10 } }, { type: 'ellipseArc', rx: 30, ry: 20, angle: 0, largeArc: false, sweep: true, to: { x: 50, y: 30 } }], { strokeColor: 0x00ff00 }),\n target.renderPathCommands([{ type: 'move', to: { x: 210, y: 10 } }, { type: 'arc', from: { x: 210, y: 80 }, to: { x: 160, y: 10 }, radius: 20 }, { type: 'line', to: { x: 160, y: 10 } }], { closed: true }),\n ], 230, 120)\n\n const renderGroups = (target: ReactRenderTarget) => {\n const items = [\n target.renderCircle(50, 50, 20),\n target.renderCircle(50, 50, 35),\n target.renderText(0, 40, 'abc', 0xff0000, 30, 'monospace'),\n target.renderGroup([target.renderCircle(50, 50, 15),], { translate: { x: 20, y: 20 } })\n ]\n return target.renderResult([\n target.renderGroup(items, { opacity: 0.2, translate: { x: 10, y: 0 } }),\n target.renderRect(120, 10, 80, 80, { clip: () => target.renderGroup(items, { translate: { x: 100, y: 0 } }) }),\n target.renderCircle(180, 150, 50, { clip: () => target.renderGroup(items, { matrix: m3.multiply(m3.translation(150, 150), m3.scaling(0.7, 0.7)) }) }),\n target.renderPath([[{ x: 0, y: 200 }, { x: 120, y: 200 }, { x: 120, y: 300 }, { x: 0, y: 300 }, { x: 0, y: 200 }], [{ x: 55, y: 230 }, { x: 90, y: 220 }, { x: 90, y: 260 }, { x: 50, y: 260 }, { x: 55, y: 230 }]], { clip: () => target.renderGroup(items, { translate: { x: 10, y: 200 } }), strokeWidth: 0 }),\n target.renderPolygon([{ x: 55, y: 230 }, { x: 90, y: 220 }, { x: 90, y: 260 }, { x: 50, y: 260 }]),\n target.renderRect(30, 100, 80, 80, {\n clip: () => target.renderGroup([\n target.renderCircle(90, 50, 20, { fillPattern: { width: 10, height: 10, pattern: () => target.renderPath([[{ x: 0, y: 5 }, { x: 5, y: 0 }], [{ x: 10, y: 5 }, { x: 5, y: 10 }]], { strokeColor: 0x0000ff }) } }),\n target.renderCircle(30, 50, 20),\n ], { translate: { x: 10, y: 90 } })\n }),\n target.renderGroup(items, { translate: { x: 110, y: 200 }, base: { x: 50, y: 50 }, scale: { x: 0.6, y: 0.3 } }),\n ], 230, 550)\n }\n\n const renderRay = (target: ReactRenderTarget) => target.renderResult([\n target.renderRay(50, 50, 30),\n target.renderRay(80, 50, 30, { bidirectional: true }),\n target.renderGroup([\n target.renderRay(60, 60, 30),\n target.renderGroup([\n target.renderRay(60, 60, 30),\n ], { translate: { x: 0, y: -20 } })\n ], { translate: { x: -20, y: 0 } })\n ], 230, 90)\n\n const { setOffset } = React.useContext(OffsetXContext)\n React.useEffect(() => {\n if (navigator.gpu) {\n setOffset?.(230)\n }\n }, [setOffset])\n return (\n \n
\n {reactSvgRenderTarget.type}\n {reactCanvasRenderTarget.type}\n {reactWebglRenderTarget.type}\n {navigator.gpu && {reactWebgpuRenderTarget.type}}\n
\n {renderArcs(reactSvgRenderTarget)}\n {renderArcs(reactCanvasRenderTarget)}\n {renderArcs(reactWebglRenderTarget)}\n {navigator.gpu && renderArcs(reactWebgpuRenderTarget)}\n
\n {renderCircles(reactSvgRenderTarget)}\n {renderCircles(reactCanvasRenderTarget)}\n {renderCircles(reactWebglRenderTarget)}\n {navigator.gpu && renderCircles(reactWebgpuRenderTarget)}\n
\n {renderTexts(reactSvgRenderTarget)}\n {renderTexts(reactCanvasRenderTarget)}\n {renderTexts(reactWebglRenderTarget)}\n {navigator.gpu && renderTexts(reactWebgpuRenderTarget)}\n
\n {renderEllipseArcs(reactSvgRenderTarget)}\n {renderEllipseArcs(reactCanvasRenderTarget)}\n {renderEllipseArcs(reactWebglRenderTarget)}\n {navigator.gpu && renderEllipseArcs(reactWebgpuRenderTarget)}\n
\n {renderEllipses(reactSvgRenderTarget)}\n {renderEllipses(reactCanvasRenderTarget)}\n {renderEllipses(reactWebglRenderTarget)}\n {navigator.gpu && renderEllipses(reactWebgpuRenderTarget)}\n
\n {renderRects(reactSvgRenderTarget)}\n {renderRects(reactCanvasRenderTarget)}\n {renderRects(reactWebglRenderTarget)}\n {navigator.gpu && renderRects(reactWebgpuRenderTarget)}\n
\n {renderPaths(reactSvgRenderTarget)}\n {renderPaths(reactCanvasRenderTarget)}\n {renderPaths(reactWebglRenderTarget)}\n {navigator.gpu && renderPaths(reactWebgpuRenderTarget)}\n
\n {renderImages(reactSvgRenderTarget)}\n {renderImages(reactCanvasRenderTarget)}\n {renderImages(reactWebglRenderTarget)}\n {navigator.gpu && renderImages(reactWebgpuRenderTarget)}\n
\n {renderPolylines(reactSvgRenderTarget)}\n {renderPolylines(reactCanvasRenderTarget)}\n {renderPolylines(reactWebglRenderTarget)}\n {navigator.gpu && renderPolylines(reactWebgpuRenderTarget)}\n
\n {renderPolygons(reactSvgRenderTarget)}\n {renderPolygons(reactCanvasRenderTarget)}\n {renderPolygons(reactWebglRenderTarget)}\n {navigator.gpu && renderPolygons(reactWebgpuRenderTarget)}\n
\n {renderPathCommands(reactSvgRenderTarget)}\n {renderPathCommands(reactCanvasRenderTarget)}\n {renderPathCommands(reactWebglRenderTarget)}\n {navigator.gpu && renderPathCommands(reactWebgpuRenderTarget)}\n
\n {renderGroups(reactSvgRenderTarget)}\n {renderGroups(reactCanvasRenderTarget)}\n {renderGroups(reactWebglRenderTarget)}\n {navigator.gpu && renderGroups(reactWebgpuRenderTarget)}\n
\n {renderRay(reactSvgRenderTarget)}\n {renderRay(reactCanvasRenderTarget)}\n {renderRay(reactWebglRenderTarget)}\n {navigator.gpu && renderRay(reactWebgpuRenderTarget)}\n
\n )\n}",props:[],componentName:"",parentComponentName:""},{path:"region-alignment-line.story",name:"",Component:ee.default,code:"() => {\n const [contents, setContents] = React.useState(defaultContents)\n const [selectedIndex, setSelectedIndex] = React.useState(0)\n\n const { regionAlignmentX, regionAlignmentY, changeOffsetByRegionAlignment, clearRegionAlignments } = useRegionAlignment(10)\n const { offset, onStart, mask, startPosition, resetDragMove } = useDragMove(\n () => {\n clearRegionAlignments()\n if (offset.x === 0 && offset.y === 0 && startPosition?.data !== undefined) {\n setSelectedIndex(startPosition.data)\n return\n }\n setContents(produce(contents, (draft) => {\n draft[selectedIndex].x += offset.x\n draft[selectedIndex].y += offset.y\n }))\n },\n {\n transformOffset: (f, e) => {\n if (!e?.shiftKey) {\n changeOffsetByRegionAlignment(f, contents[selectedIndex], contents.filter((_, i) => i !== selectedIndex))\n } else {\n clearRegionAlignments()\n }\n return f\n },\n }\n )\n useGlobalKeyDown(e => {\n if (e.key === 'Escape') {\n resetDragMove()\n }\n })\n return (\n <>\n {contents.map((content, i) => (\n onStart({ x: e.clientX, y: e.clientY }, { data: i })}\n >\n
\n ))}\n \n \n {mask}\n >\n )\n}",props:[],componentName:"",parentComponentName:""},{path:"scrollbar.story",name:"",Component:te.default,code:"() => {\n const [x, setX] = React.useState(0)\n const [y, setY] = React.useState(0)\n return (\n \n )\n}",props:[],componentName:"",parentComponentName:""},{path:"select-before-operate.story",name:"",Component:ne.default,code:"() => {\n const { isSelected, addSelection, filterSelection, executeOperation, selectBeforeOperate, message, onSelectBeforeOperateKeyDown } = useSelectBeforeOperate<{ count?: number, selectable?: (index: number[]) => boolean }, 'alert', number[]>({}, (_, s) => {\n alert(s.map(([i]) => i).join(','))\n return true\n })\n useGlobalKeyDown(e => {\n onSelectBeforeOperateKeyDown(e)\n })\n const startOperation = (maxCount?: number, selectable?: (index: number[]) => boolean) => {\n const { result, needSelect } = filterSelection(selectable, maxCount)\n if (needSelect) {\n selectBeforeOperate({ count: maxCount, selectable }, 'alert')\n } else {\n executeOperation('alert', result)\n }\n }\n\n return (\n \n \n \n \n \n {new Array(10).fill(1).map((_, i) => (\n \n ))}\n {message}\n
\n )\n}",props:[],componentName:"",parentComponentName:""},{path:"selected.story",name:"",Component:re.default,code:"() => {\n const { isSelected, addSelection, onSelectedKeyDown } = useSelected({ maxCount: 3 })\n useGlobalKeyDown(e => {\n onSelectedKeyDown(e)\n })\n\n return (\n \n {new Array(10).fill(1).map((_, i) => (\n \n ))}\n
\n )\n}",props:[],componentName:"",parentComponentName:""},{path:"text-click-create.story",name:"",Component:oe.default,code:"() => {\n const [contents, setContents] = React.useState([])\n const { text, onClick, onMove, input, reset } = useTextClickCreate(true, (c) => {\n setContents(produce(contents, (draft) => {\n draft.push(c)\n }))\n })\n useGlobalKeyDown(e => {\n if (e.key === 'Escape') {\n reset()\n }\n })\n\n return (\n \n \n {input}\n
\n )\n}",props:[],componentName:"",parentComponentName:""},{path:"undo-redo.story",name:"",Component:ie.default,code:"() => {\n const { state, setState, undo, redo } = useUndoRedo({ count: 0 })\n useGlobalKeyDown(e => {\n if (e.code === 'KeyZ' && metaKeyIfMacElseCtrlKey(e)) {\n if (e.shiftKey) {\n redo(e)\n } else {\n undo(e)\n }\n }\n })\n return (\n \n )\n}",props:[],componentName:"",parentComponentName:""},{path:"webgl-3d-land.story",name:"",Component:ae.default,code:"() => {\n const ref = React.useRef(null)\n const renderer = React.useRef>()\n const size = useWindowSize()\n const width = size.width / 2\n const height = size.height\n const [point, setPoint] = React.useState()\n const eye: Vec3 = [0, -90, 90]\n const count = 10\n const step = 5\n const minZ = -100\n const zStep = 5\n const degree = 3\n const { state, setState, undo, redo } = useUndoRedo(getInitialData(getMapPoints(step, count), degree))\n const [contextMenu, setContextMenu] = React.useState()\n const [status, setStatus] = React.useState<'up' | 'down' | 'set'>()\n const [z, setZ] = React.useState(5)\n\n React.useEffect(() => {\n if (!ref.current || renderer.current) {\n return\n }\n renderer.current = createWebgl3DRenderer(ref.current)\n }, [ref.current])\n\n useGlobalKeyDown(e => {\n if (metaKeyIfMacElseCtrlKey(e)) {\n if (e.code === 'KeyZ') {\n if (e.shiftKey) {\n redo(e)\n } else {\n undo(e)\n }\n }\n } else if (e.key === 'Escape') {\n setStatus(undefined)\n setContextMenu(undefined)\n }\n })\n const render = (g: Nullable[]) => {\n renderer.current?.render?.(\n g,\n {\n eye,\n up: [0, 1, 0],\n target: [0, 0, 0],\n fov: angleToRadian(60),\n near: 0.1,\n far: 1000,\n },\n {\n position: [1000, -1000, 1000],\n color: [1, 1, 1, 1],\n specular: [1, 1, 1, 1],\n shininess: 50,\n specularFactor: 1,\n },\n [1, 1, 1, 1],\n )\n }\n\n React.useEffect(() => {\n const pointGraphics: Graphic3d[] = []\n if (point) {\n pointGraphics.push({\n geometry: {\n type: 'sphere',\n radius: 1,\n },\n color: [1, 0, 0, 1],\n position: point,\n })\n }\n render([...state, ...pointGraphics])\n }, [point, state])\n\n return (\n \n
\n )\n}",props:[],componentName:"",parentComponentName:""},{path:"webgl-3d.story",name:"",Component:se.default,code:"() => {\n const ref = React.useRef(null)\n const renderer = React.useRef>()\n const { x, y, setX, setY, ref: wheelScrollRef } = useWheelScroll()\n const { scale, setScale, ref: wheelZoomRef } = useWheelZoom()\n const [rotate, setRotate] = React.useState({ x: 0, y: 0 })\n const { offset, onStart: onStartMoveCanvas, mask: moveCanvasMask, resetDragMove } = useDragMove(() => {\n setRotate((v) => ({ x: v.x + offset.x, y: v.y + offset.y }))\n })\n useGlobalKeyDown(e => {\n if (e.key === 'Escape') {\n resetDragMove()\n } else if (e.code === 'Digit0' && !e.shiftKey && metaKeyIfMacElseCtrlKey(e)) {\n setScale(1)\n setX(0)\n setY(0)\n setRotate({ x: 0, y: 0 })\n e.preventDefault()\n }\n })\n const size = useWindowSize()\n const width = size.width / 2\n const height = size.height\n const rotateX = offset.x + rotate.x\n const rotateY = offset.y + rotate.y\n const [hovering, setHovering] = React.useState()\n const graphics = React.useRef([\n ...getAxesGraphics(),\n {\n geometry: {\n type: 'lines',\n points: getDashedLine([0, 0, 0], [100, 100, 100], 6).flat(),\n },\n color: [0, 0, 0, 1],\n },\n {\n geometry: {\n type: 'sphere',\n radius: 100,\n },\n color: [1, 0, 0, 1],\n position: [0, 250, 0],\n },\n {\n geometry: {\n type: 'cube',\n size: 150,\n },\n color: [0, 1, 0, 1],\n position: [250, 0, 0],\n },\n {\n geometry: {\n type: 'cylinder',\n radius: 100,\n height: 200,\n },\n color: [0, 0, 1, 1],\n position: [-250, 0, 0],\n },\n {\n geometry: {\n type: 'cone',\n topRadius: 0,\n bottomRadius: 100,\n height: 200,\n },\n color: [1, 0, 1, 1],\n position: [0, -250, 0],\n },\n {\n geometry: {\n type: 'triangles',\n points: [-50, -50, 50, 50, 50, 50, -50, 50, 50],\n },\n color: [0.5, 0, 0.5, 1],\n position: [250, 250, 250],\n },\n {\n geometry: {\n type: 'vertices',\n ...getNurbsSurfaceVertices([\n [[0, 0, -20], [20, 0, 0], [40, 0, 0], [60, 0, 0], [80, 0, 0], [100, 0, 0]],\n [[0, -20, 0], [20, -20, 10], [40, -20, 20], [60, -20, 0], [80, -20, 0], [100, -20, 0]],\n [[0, -40, 0], [20, -40, 10], [40, -40, 20], [60, -40, 0], [80, -40, -4], [100, -40, -24]],\n [[0, -50, 0], [20, -60, 0], [40, -60, -46], [60, -60, 0], [80, -60, 0], [100, -50, 0]],\n [[0, -80, 0], [20, -80, 0], [40, -80, 0], [60, -80, 8], [80, -80, -40], [100, -80, 0]],\n [[0, -100, 24], [20, -100, 0], [40, -100, 40], [60, -100, 0], [100, -100, -20], [100, -100, -30]],\n ], 3, [0, 0, 0, 0, 0.333, 0.666, 1, 1, 1, 1], 3, [0, 0, 0, 0, 0.333, 0.666, 1, 1, 1, 1]),\n },\n color: [0, 0.5, 0, 1],\n position: [-250, 250, 250],\n },\n ])\n\n React.useEffect(() => {\n if (!ref.current || renderer.current) {\n return\n }\n renderer.current = createWebgl3DRenderer(ref.current)\n }, [ref.current])\n\n React.useEffect(() => {\n const { position, up } = updateCamera(-x, y, 1000 / scale, -0.3 * rotateX, -0.3 * rotateY)\n graphics.current.forEach((g, i) => {\n g.color[3] = i === hovering ? 0.5 : 1\n })\n renderer.current?.render?.(\n graphics.current,\n {\n eye: position3DToVec3(position),\n up: position3DToVec3(up),\n target: [-x, y, 0],\n fov: angleToRadian(60),\n near: 0.1,\n far: 20000,\n },\n {\n position: [1000, 1000, 1000],\n color: [1, 1, 1, 1],\n specular: [1, 1, 1, 1],\n shininess: 50,\n specularFactor: 1,\n },\n [1, 1, 1, 1],\n )\n }, [x, y, scale, rotateX, rotateY, hovering, width, height])\n\n return (\n \n
\n )\n}",props:[],componentName:"",parentComponentName:""},{path:"webgl.story",name:"",Component:ce.default,code:"() => {\n const ref = React.useRef(null)\n const render = React.useRef<(g: typeof graphics, x: number, y: number, scale: number) => void>()\n const { x, y, ref: wheelScrollRef, setX, setY } = useWheelScroll()\n const { scale, setScale, ref: wheelZoomRef } = useWheelZoom({\n onChange(oldScale, newScale, cursor) {\n const result = scaleByCursorPosition({ width, height }, newScale / oldScale, cursor)\n setX(result.setX)\n setY(result.setY)\n }\n })\n const { zoomIn, zoomOut } = useZoom(scale, setScale)\n const { offset, onStart: onStartMoveCanvas, mask: moveCanvasMask, resetDragMove } = useDragMove(() => {\n setX((v) => v + offset.x)\n setY((v) => v + offset.y)\n })\n useGlobalKeyDown(e => {\n if (e.key === 'Escape') {\n resetDragMove()\n } else if (metaKeyIfMacElseCtrlKey(e) ) {\n if (e.code === 'Minus') {\n zoomOut(e)\n } else if (e.code === 'Equal') {\n zoomIn(e)\n }\n }\n })\n const size = useWindowSize()\n const width = size.width / 2\n const height = size.height\n const generateGraphics = () => {\n const canvas = document.createElement(\"canvas\")\n const ctx = canvas.getContext(\"2d\")\n if (ctx) {\n ctx.font = \"50px monospace\";\n const t = ctx.measureText('abc');\n ctx.canvas.width = Math.ceil(t.width) + 2;\n ctx.canvas.height = 50;\n ctx.font = \"50px monospace\";\n ctx.fillStyle = 'white';\n ctx.fillText('abc', 0, ctx.canvas.height);\n }\n const lineWidth = 10\n const miterLimit = 'round'\n const closed = undefined\n return {\n backgroundColor: [Math.random(), Math.random(), Math.random(), 1] as Vec4,\n lines: [\n {\n points: combineStripTriangles([\n getPolylineTriangles([\n { x: Math.random() * 600, y: Math.random() * 400 },\n { x: Math.random() * 600, y: Math.random() * 400 },\n { x: Math.random() * 600, y: Math.random() * 400 },\n { x: Math.random() * 600, y: Math.random() * 400 },\n ], lineWidth, closed, miterLimit).points,\n getPolylineTriangles([\n { x: Math.random() * 600, y: Math.random() * 400 },\n { x: Math.random() * 600, y: Math.random() * 400 },\n { x: Math.random() * 600, y: Math.random() * 400 },\n { x: Math.random() * 600, y: Math.random() * 400 },\n ], lineWidth, closed, miterLimit).points,\n ]),\n color: [Math.random(), Math.random(), Math.random(), 1],\n },\n {\n points: combineStripTriangles([\n getPolylineTriangles([\n { x: Math.random() * 600, y: Math.random() * 400 },\n { x: Math.random() * 600, y: Math.random() * 400 },\n { x: Math.random() * 600, y: Math.random() * 400 },\n { x: Math.random() * 600, y: Math.random() * 400 },\n ], lineWidth, closed, miterLimit).points,\n getPolylineTriangles([\n { x: Math.random() * 600, y: Math.random() * 400 },\n { x: Math.random() * 600, y: Math.random() * 400 },\n { x: Math.random() * 600, y: Math.random() * 400 },\n { x: Math.random() * 600, y: Math.random() * 400 },\n ], lineWidth, closed, miterLimit).points,\n ]),\n color: [Math.random(), Math.random(), Math.random(), 1],\n },\n ],\n line: [\n Math.random() * 600,\n Math.random() * 400,\n Math.random() * 600,\n Math.random() * 400,\n Math.random() * 600,\n Math.random() * 400,\n ],\n triangles: [\n Math.random() * 600,\n Math.random() * 400,\n Math.random() * 600,\n Math.random() * 400,\n Math.random() * 600,\n Math.random() * 400,\n ],\n triangleColors: [\n Math.random(), Math.random(), Math.random(), 1,\n Math.random(), Math.random(), Math.random(), 1,\n Math.random(), Math.random(), Math.random(), 1,\n ],\n canvas,\n color: [Math.random(), Math.random(), Math.random(), 1],\n position: { x: Math.random() * 600, y: Math.random() * 400 },\n }\n }\n const [graphics, setGraphics] = React.useState(generateGraphics())\n\n React.useEffect(() => {\n if (!ref.current || render.current) {\n return\n }\n const canvas = ref.current\n const gl = ref.current.getContext(\"webgl\", { antialias: true, stencil: true });\n if (!gl) {\n return\n }\n gl.enable(gl.BLEND);\n gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);\n const programInfo = twgl.createProgramInfo(gl, [`\n attribute vec4 position;\n uniform mat3 matrix;\n void main() {\n gl_Position = vec4((matrix * vec3(position.xy, 1)).xy, 0, 1);\n }\n `, `\n precision mediump float;\n uniform vec4 color;\n void main() {\n gl_FragColor = color;\n }`]);\n const programInfo2 = twgl.createProgramInfo(gl, [`\n attribute vec4 position; \n uniform mat3 matrix;\n varying vec2 texcoord;\n\n void main () {\n gl_Position = vec4((matrix * vec3(position.xy, 1)).xy, 0, 1);\n texcoord = position.xy;\n }\n `, `\n precision mediump float;\n\n varying vec2 texcoord;\n uniform sampler2D texture;\n uniform vec4 color;\n\n void main() {\n if (texcoord.x < 0.0 || texcoord.x > 1.0 ||\n texcoord.y < 0.0 || texcoord.y > 1.0) {\n discard;\n }\n vec4 color = texture2D(texture, texcoord) * color;\n if (color.a < 0.1) {\n discard;\n }\n gl_FragColor = color;\n }`]);\n gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);\n const textBufferInfo = twgl.primitives.createXYQuadBufferInfo(gl);\n const programInfo3 = twgl.createProgramInfo(gl, [`\n attribute vec4 position;\n varying vec2 texcoord;\n void main() {\n gl_Position = position;\n texcoord = position.xy * .5 + .5;\n }\n `, `\n precision mediump float;\n varying vec2 texcoord;\n uniform sampler2D texture;\n void main() {\n gl_FragColor = texture2D(texture, texcoord); \n }\n `]);\n const imageBufferInfo = twgl.primitives.createXYQuadBufferInfo(gl);\n const imageTexture = twgl.createTexture(gl, {\n src: \"https://farm9.staticflickr.com/8873/18598400202_3af67ef38f_z_d.jpg\",\n crossOrigin: \"\",\n });\n const gradientProgramInfo = twgl.createProgramInfo(gl, [`\n attribute vec4 position;\n attribute vec4 color;\n uniform mat3 matrix;\n varying vec4 v_color;\n\n void main () {\n gl_Position = vec4((matrix * vec3(position.xy, 1)).xy, 0, 1);\n v_color = color;\n }\n `, `\n precision mediump float;\n\n varying vec4 v_color;\n\n void main() {\n gl_FragColor = v_color;\n }`]);\n\n render.current = (gs, x, y, scale) => {\n gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);\n gl.useProgram(programInfo.program);\n twgl.resizeCanvasToDisplaySize(canvas);\n gl.clearColor(...gs.backgroundColor)\n gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT)\n\n let matrix = m3.projection(gl.canvas.width, gl.canvas.height)\n matrix = m3.multiply(matrix, m3.translation(x, y))\n if (scale !== 1) {\n matrix = m3.multiply(matrix, m3.translation(gl.canvas.width / 2, gl.canvas.height / 2));\n matrix = m3.multiply(matrix, m3.scaling(scale, scale));\n matrix = m3.multiply(matrix, m3.translation(-gl.canvas.width / 2, -gl.canvas.height / 2));\n }\n\n const objectsToDraw: twgl.DrawObject[] = []\n for (const line of gs.lines) {\n objectsToDraw.push({\n programInfo,\n bufferInfo: twgl.createBufferInfoFromArrays(gl, {\n position: {\n numComponents: 2,\n data: line.points\n },\n }),\n uniforms: {\n color: line.color,\n matrix,\n },\n type: gl.TRIANGLE_STRIP,\n })\n }\n const objectsToDraw2 = [{\n programInfo,\n bufferInfo: twgl.createBufferInfoFromArrays(gl, {\n position: {\n numComponents: 2,\n data: gs.line\n },\n }),\n uniforms: {\n color: gs.color,\n matrix,\n },\n type: gl.LINE_STRIP,\n }]\n\n const objectsToDraw3 = [{\n programInfo: gradientProgramInfo,\n bufferInfo: twgl.createBufferInfoFromArrays(gl, {\n position: {\n numComponents: 2,\n data: gs.triangles\n },\n color: {\n numComponents: 4,\n data: gs.triangleColors\n },\n }),\n uniforms: {\n matrix,\n },\n type: gl.TRIANGLES,\n }]\n\n matrix = m3.multiply(matrix, m3.translation(gs.position.x, gs.position.y))\n matrix = m3.multiply(matrix, m3.scaling(gs.canvas.width, gs.canvas.height))\n twgl.drawObjectList(gl, objectsToDraw)\n\n gl.enable(gl.STENCIL_TEST);\n gl.stencilFunc(gl.ALWAYS, 1, 0xFF);\n gl.stencilOp(gl.KEEP, gl.KEEP, gl.REPLACE);\n twgl.drawObjectList(gl, [\n {\n programInfo: programInfo2,\n bufferInfo: textBufferInfo,\n uniforms: {\n matrix,\n color: gs.color,\n texture: twgl.createTexture(gl, { src: gs.canvas }),\n },\n },\n {\n programInfo: programInfo2,\n bufferInfo: textBufferInfo,\n uniforms: {\n matrix: m3.multiply(matrix, m3.translation(1, 0)),\n color: gs.color,\n texture: twgl.createTexture(gl, { src: gs.canvas }),\n },\n },\n {\n programInfo: programInfo2,\n bufferInfo: textBufferInfo,\n uniforms: {\n matrix: m3.multiply(matrix, m3.translation(1, 1)),\n color: gs.color,\n texture: twgl.createTexture(gl, { src: gs.canvas }),\n },\n }\n ])\n\n gl.stencilFunc(gl.EQUAL, 1, 0xFF);\n gl.stencilOp(gl.KEEP, gl.KEEP, gl.KEEP);\n twgl.drawObjectList(gl, [{\n programInfo: programInfo3,\n bufferInfo: imageBufferInfo,\n uniforms: {\n texture: imageTexture\n },\n }])\n gl.disable(gl.STENCIL_TEST);\n\n twgl.drawObjectList(gl, objectsToDraw2)\n\n twgl.drawObjectList(gl, objectsToDraw3)\n }\n }, [ref.current])\n\n React.useEffect(() => {\n if (render.current) {\n render.current(graphics, x + offset.x, y + offset.y, scale)\n }\n }, [graphics, render.current, x, y, offset, scale])\n\n return (\n \n
\n )\n}",props:[],componentName:"",parentComponentName:""},{path:"webgpu-3d.story",name:"",Component:le.default,code:"() => {\n const ref = React.useRef(null)\n const renderer = React.useRef>>()\n const { x, y, setX, setY, ref: wheelScrollRef } = useWheelScroll()\n const { scale, setScale, ref: wheelZoomRef } = useWheelZoom()\n const [rotate, setRotate] = React.useState({ x: 0, y: 0 })\n const { offset, onStart: onStartMoveCanvas, mask: moveCanvasMask, resetDragMove } = useDragMove(() => {\n setRotate((v) => ({ x: v.x + offset.x, y: v.y + offset.y }))\n })\n useGlobalKeyDown(e => {\n if (e.key === 'Escape') {\n resetDragMove()\n } else if (e.code === 'Digit0' && !e.shiftKey && metaKeyIfMacElseCtrlKey(e)) {\n setScale(1)\n setX(0)\n setY(0)\n setRotate({ x: 0, y: 0 })\n e.preventDefault()\n }\n })\n const size = useWindowSize()\n const width = size.width / 2\n const height = size.height\n const rotateX = offset.x + rotate.x\n const rotateY = offset.y + rotate.y\n const [hovering, setHovering] = React.useState()\n const graphics = React.useRef([\n ...getAxesGraphics(),\n {\n geometry: {\n type: 'lines',\n points: getDashedLine([0, 0, 0], [100, 100, 100], 6).flat(),\n },\n color: [0, 0, 0, 1],\n },\n {\n geometry: {\n type: 'sphere',\n radius: 100,\n },\n color: [1, 0, 0, 1],\n position: [0, 250, 0],\n },\n {\n geometry: {\n type: 'cube',\n size: 150,\n },\n color: [0, 1, 0, 1],\n position: [250, 0, 0],\n },\n {\n geometry: {\n type: 'cylinder',\n radius: 100,\n height: 200,\n },\n color: [0, 0, 1, 1],\n position: [-250, 0, 0],\n },\n {\n geometry: {\n type: 'cone',\n topRadius: 0,\n bottomRadius: 100,\n height: 200,\n },\n color: [1, 0, 1, 1],\n position: [0, -250, 0],\n },\n {\n geometry: {\n type: 'triangles',\n points: [-50, -50, 50, 50, 50, 50, -50, 50, 50],\n },\n color: [0.5, 0, 0.5, 1],\n position: [250, 250, 250],\n },\n {\n geometry: {\n type: 'vertices',\n ...getNurbsSurfaceVertices([\n [[0, 0, -20], [20, 0, 0], [40, 0, 0], [60, 0, 0], [80, 0, 0], [100, 0, 0]],\n [[0, -20, 0], [20, -20, 10], [40, -20, 20], [60, -20, 0], [80, -20, 0], [100, -20, 0]],\n [[0, -40, 0], [20, -40, 10], [40, -40, 20], [60, -40, 0], [80, -40, -4], [100, -40, -24]],\n [[0, -50, 0], [20, -60, 0], [40, -60, -46], [60, -60, 0], [80, -60, 0], [100, -50, 0]],\n [[0, -80, 0], [20, -80, 0], [40, -80, 0], [60, -80, 8], [80, -80, -40], [100, -80, 0]],\n [[0, -100, 24], [20, -100, 0], [40, -100, 40], [60, -100, 0], [100, -100, -20], [100, -100, -30]],\n ], 3, [0, 0, 0, 0, 0.333, 0.666, 1, 1, 1, 1], 3, [0, 0, 0, 0, 0.333, 0.666, 1, 1, 1, 1]),\n },\n color: [0, 0.5, 0, 1],\n position: [250, 250, -250],\n rotateY: Math.PI,\n },\n ])\n\n React.useEffect(() => {\n if (!ref.current || renderer.current) {\n return\n }\n createWebgpu3DRenderer(ref.current).then(r => {\n renderer.current = r\n setHovering(-1)\n })\n }, [ref.current])\n\n React.useEffect(() => {\n const { position, up } = updateCamera(-x, y, 1000 / scale, -0.3 * rotateX, -0.3 * rotateY)\n graphics.current.forEach((g, i) => {\n g.color[3] = i === hovering ? 0.5 : 1\n })\n renderer.current?.render?.(\n graphics.current,\n {\n eye: position3DToVec3(position),\n up: position3DToVec3(up),\n target: [-x, y, 0],\n fov: angleToRadian(60),\n near: 0.1,\n far: 20000,\n },\n {\n position: [1000, 1000, 1000],\n color: [1, 1, 1, 1],\n specular: [1, 1, 1, 1],\n shininess: 50,\n specularFactor: 1,\n },\n [1, 1, 1, 1],\n )\n }, [x, y, scale, rotateX, rotateY, hovering, width, height])\n\n return (\n \n
\n )\n}",props:[],componentName:"",parentComponentName:""},{path:"wheel-scroll.story",name:"",Component:ue.default,code:"() => {\n const { ref, x, y } = useWheelScroll({\n maxOffsetX: 250,\n maxOffsetY: 250,\n })\n return (\n \n )\n}",props:[],componentName:"",parentComponentName:""},{path:"wheel-zoom.story",name:"",Component:pe.default,code:"() => {\n const { ref, scale } = useWheelZoom()\n return (\n \n )\n}",props:[],componentName:"",parentComponentName:""},{path:"window-size.story",name:"",Component:de.default,code:"() => {\n const { width, height } = useWindowSize()\n\n return (\n \n {Math.round(width)} {Math.round(height)}\n
\n )\n}",props:[],componentName:"",parentComponentName:""}]},3613:(e,t,n)=>{"use strict";n.d(t,{default:()=>a});var r=n(3696),o=n.n(r),i=n(9758);const a=()=>{const[e,t]=o().useState(1),{zoomIn:n,zoomOut:r}=(0,i.useZoom)(e,t);return(0,i.useGlobalKeyDown)((e=>{(0,i.metaKeyIfMacElseCtrlKey)(e)&&("Minus"===e.code?r(e):"Equal"===e.code&&n(e))})),o().createElement("div",{style:{width:"300px",height:"300px",overflow:"hidden",position:"absolute",display:"flex",alignItems:"center",justifyContent:"center",border:"1px solid green"}},o().createElement("div",{style:{width:"800px",height:"800px",position:"absolute",transform:`scale(${e})`,background:"radial-gradient(50% 50% at 50% 50%, red 0%, white 100%)"}}))}},4565:(e,t,n)=>{"use strict";n.d(t,{default:()=>c});var r=n(8662),o=n(3696),i=n.n(o),a=n(9758),s=n(9299);const c=()=>{const[e,t]=i().useState(s.defaultContents),[n,o]=i().useState(0),{lineAlignmentX:c,lineAlignmentY:l,changeOffsetByLineAlignment:u,clearLineAlignments:p}=(0,a.useLineAlignment)(10),{offset:d,onStart:f,mask:g,resetDragResize:h}=(0,a.useDragResize)((()=>{p(),t((0,r.produce)(e,(e=>{e[n].x+=d.x,e[n].y+=d.y,e[n].width+=d.width,e[n].height+=d.height})))}),{centeredScaling:e=>e.shiftKey,transformOffset:(t,r,o)=>{if(!(null==r?void 0:r.metaKey)&&o){const r=e[n],i=e.filter((e=>e!==r)).map((e=>[e.x,e.x+e.width])).flat(),a=e.filter((e=>e!==r)).map((e=>[e.y,e.y+e.height])).flat();u(t,o,r,i,a)}else p();return t}});return(0,a.useGlobalKeyDown)((e=>{"Escape"===e.key&&h()})),i().createElement(i().Fragment,null,e.map(((e,t)=>i().createElement("div",{key:t,style:{width:`${e.width+(n===t?d.width:0)}px`,height:`${e.height+(n===t?d.height:0)}px`,left:`${e.x+(n===t?d.x:0)}px`,top:`${e.y+(n===t?d.y:0)}px`,position:"absolute",boxSizing:"border-box",border:n===t?"1px solid green":void 0},onClick:()=>o(t)},i().createElement("img",{src:e.url,style:{objectFit:"fill",width:"100%",height:"100%"}}),n===t&&i().createElement(a.ResizeBar,{onMouseDown:f})))),i().createElement(a.AlignmentLine,{type:"x",value:c}),i().createElement(a.AlignmentLine,{type:"y",value:l}),g)}},4855:(e,t,n)=>{"use strict";n.d(t,{default:()=>f});var r=n(3696),o=n.n(r),i=n(9758),a=Object.defineProperty,s=Object.defineProperties,c=Object.getOwnPropertyDescriptors,l=Object.getOwnPropertySymbols,u=Object.prototype.hasOwnProperty,p=Object.prototype.propertyIsEnumerable,d=(e,t,n)=>t in e?a(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n;const f=()=>{const e=o().useRef(null),t=o().useRef(),{x:n,y:r,ref:a}=(0,i.useWheelScroll)(),{scale:f,ref:g}=(0,i.useWheelZoom)(),[h,m]=o().useState({x:0,y:0}),{offset:y,onStart:v,mask:x,resetDragMove:b}=(0,i.useDragMove)((()=>{m((e=>({x:e.x+y.x,y:e.y+y.y})))})),C=(0,i.useWindowSize)(),E=C.width/2,P=C.height,[w,k]=o().useState(),_=y.x+h.x,S=y.y+h.y,R=o().useRef([]);return o().useEffect((()=>{e.current&&!t.current&&(t.current=(0,i.createWebgl3DRenderer)(e.current))}),[e.current]),(0,i.useGlobalKeyDown)((e=>{"Escape"===e.key&&b()})),o().useEffect((()=>{const e=[65,59,80,81,56,55,40].map(((e,t)=>[20*(t+1),e,0])),t=[55,49,70,71,46,45,30].map(((e,t)=>[20*(t+1),e,20])),n=[45,39,60,61,36,35,20].map(((e,t)=>[20*(t+1),e,-20])),r=[75,69,90,91,66,65,50].map(((e,t)=>[20*(t+1),e,40])),o=(0,i.getChartAxis3D)([e,t,n,r],{x:20,y:10,z:20});R.current.push(...o,{geometry:{type:"line strip",points:e.flat()},color:[1,0,0,1]},...e.map((e=>({geometry:{type:"sphere",radius:1},color:[1,0,0,1],position:e}))),{geometry:{type:"line strip",points:(0,i.getBezierSplinePoints3D)(t,20).flat()},color:[0,1,0,1]},...t.map((e=>({geometry:{type:"sphere",radius:1},color:[0,1,0,1],position:e}))),{geometry:{type:"polygon",points:[...n.flat(),n[n.length-1][0],0,n[n.length-1][2],n[0][0],0,n[0][2]]},color:[0,0,1,1]},...n.map((e=>({geometry:{type:"sphere",radius:1},color:[0,0,1,1],position:e}))),...r.map(((e,t)=>({geometry:{type:"sphere",radius:t/2+1},color:[1,0,0,1],position:e}))))}),[]),o().useEffect((()=>{var e,o;const{position:a,up:s}=(0,i.updateCamera)(-n,r,200/f,-.3*_,-.3*S);null==(o=null==(e=t.current)?void 0:e.render)||o.call(e,R.current,{eye:[a.x+40,a.y+40,a.z],up:(0,i.position3DToVec3)(s),target:[40-n,r+40,0],fov:(0,i.angleToRadian)(60),near:.1,far:2e3},{position:[1e3,1e3,1e3],color:[1,1,1,1],specular:[1,1,1,1],shininess:50,specularFactor:1},[1,1,1,1])}),[n,r,f,_,S,w,E,P]),o().createElement("div",{style:{position:"absolute",inset:"0px"}},o().createElement("canvas",{ref:(0,i.bindMultipleRefs)(a,g,e),width:E,height:P,onMouseDown:e=>v({x:e.clientX,y:e.clientY}),onMouseMove:e=>{var n,r;k(void 0);const o=null==(r=null==(n=t.current)?void 0:n.pick)?void 0:r.call(n,e.clientX,e.clientY,(e=>"sphere"===e.geometry.type));if(void 0!==o){const t=R.current[o];t.position&&k({value:t.position,x:e.clientX,y:e.clientY})}}}),w&&o().createElement(i.ChartTooltip,(T=((e,t)=>{for(var n in t||(t={}))u.call(t,n)&&d(e,n,t[n]);if(l)for(var n of l(t))p.call(t,n)&&d(e,n,t[n]);return e})({},w),A={label:(L=w.value[0]/20,Intl.DateTimeFormat("zh",{month:"long"}).format(new Date(L.toString()))),value:w.value[1]},s(T,c(A)))),x);var T,A,L}},7265:(e,t,n)=>{"use strict";n.d(t,{default:()=>a});var r=n(3696),o=n.n(r),i=n(9758);const a=()=>{const e=(0,i.useWindowSize)().width/2,t=i.reactSvgRenderTarget,[n,r]=o().useState(),[a,s]=o().useState(),c=e=>Intl.DateTimeFormat("zh",{month:"long"}).format(new Date(e.toString()));if(o().useEffect((()=>{const n=[65,59,80,81,56,55,40].map(((e,t)=>({x:t+1,y:e}))),r=[55,49,70,71,46,45,30].map(((e,t)=>({x:t+1,y:e}))),o=[45,39,60,61,36,35,20].map(((e,t)=>({x:t+1,y:e}))),a=[35,29,50,51,26,25,10].map(((e,t)=>({x:t+1,y:e}))),l=[75,69,90,91,66,65,50].map(((e,t)=>({x:t+1,y:e,r:3*t+5}))),u=(0,i.getLineChart)([n,r,o,a,l],t,{x:1,y:5},{width:e,height:300},{left:25,right:25,top:10,bottom:20},{getXLabel:c,ySecondary:!0});if(!u)return;const{points:[p,d,f,g,h],children:m,select:y,minY:v}=u;m.push(t.renderPolyline(p,{strokeColor:16711680})),m.push(...p.map((e=>t.renderCircle(e.x,e.y,3,{fillColor:16711680,strokeWidth:0})))),m.push(t.renderPolyline((0,i.getBezierSplinePoints)(d,50),{strokeColor:65280})),m.push(...d.map((e=>t.renderCircle(e.x,e.y,3,{fillColor:65280,strokeWidth:0})))),m.push(t.renderPolyline(f.map(((e,t)=>{const n=[e];return 0!==t&&n.unshift({x:(0,i.getTwoNumberCenter)(e.x,f[t-1].x),y:e.y}),t!==f.length-1&&n.push({x:(0,i.getTwoNumberCenter)(e.x,f[t+1].x),y:e.y}),n})).flat(),{strokeColor:255})),m.push(...f.map((e=>t.renderCircle(e.x,e.y,3,{fillColor:255,strokeWidth:0})))),m.push(t.renderPolygon([...g,{x:g[g.length-1].x,y:v},{x:g[0].x,y:v}],{fillColor:16711680,strokeWidth:0})),m.push(...g.map((e=>t.renderCircle(e.x,e.y,3,{fillColor:16711680,strokeWidth:0})))),m.push(...h.map((e=>{var n;return t.renderCircle(e.x,e.y,null!=(n=e.r)?n:5,{fillColor:65280,strokeWidth:0})}))),s({children:m,select:y})}),[e]),!a)return null;let l=a.children;return n&&(l=[...a.children,...(0,i.renderChartTooltip)(t,n,n.value,{getXLabel:c})]),o().createElement("div",{style:{position:"absolute",inset:"0px"}},t.renderResult(l,e,300,{attributes:{onMouseMove:e=>r(a.select({x:e.clientX,y:e.clientY}))}}))}},2754:(e,t,n)=>{"use strict";n.d(t,{default:()=>s});var r=n(8662),o=n(3696),i=n.n(o),a=n(9758);const s=()=>{const[e,t]=i().useState([]),{line:n,onClick:o,onMove:s,input:c,reset:l}=(0,a.useLineClickCreate)(!0,(n=>{t((0,r.produce)(e,(e=>{e.push(n)})))}));return(0,a.useGlobalKeyDown)((e=>{"Escape"===e.key&&l(!0)})),i().createElement("div",{style:{height:"100%"}},i().createElement("svg",{viewBox:"0 0 800 600",width:800,height:600,xmlns:"http://www.w3.org/2000/svg",fill:"none",style:{position:"absolute",left:0,top:0},onClick:e=>o({x:e.clientX,y:e.clientY}),onMouseMove:e=>s({x:e.clientX,y:e.clientY})},[...e,n].map(((e,t)=>e&&i().createElement("polyline",{key:t,stroke:"#00ff00",points:e.map((e=>`${e.x},${e.y}`)).join(" ")})))),c)}},8208:(e,t,n)=>{"use strict";n.d(t,{default:()=>s});var r=n(3696),o=n.n(r),i=n(9758),a=n(4469);const s=()=>{const e={p1:{x:200,y:200},p2:{x:300,y:300},position:{x:400,y:100},fontFamily:"monospace",fontSize:16,direct:!0},{regions:t,lines:n}=(0,i.getLinearDimensionGeometries)(e,a.dimensionStyle,(e=>(0,i.getLinearDimensionTextPosition)(e,a.dimensionStyle.margin,i.getTextSize))),{textPosition:r,textRotation:s,text:c}=(0,i.getLinearDimensionTextPosition)(e,a.dimensionStyle.margin,i.getTextSize);return o().createElement("svg",{viewBox:"0 0 800 600",width:800,height:600,xmlns:"http://www.w3.org/2000/svg",fill:"none",style:{position:"absolute",left:0,top:0}},n.map(((e,t)=>o().createElement("polyline",{key:t,stroke:"black",points:e.map((e=>`${e.x},${e.y}`)).join(" ")}))),t[0]&&o().createElement("polyline",{stroke:"black",points:t[0].points.map((e=>`${e.x},${e.y}`)).join(" "),fill:"black"}),t[1]&&o().createElement("polyline",{stroke:"black",points:t[1].points.map((e=>`${e.x},${e.y}`)).join(" "),fill:"black"}),o().createElement("text",{x:r.x,y:r.y,fill:"black",transform:(0,i.getRotateTransform)(r.x,r.y,{rotation:s}),style:{fontSize:`${e.fontSize}px`,fontFamily:e.fontFamily}},c))}},6821:(e,t,n)=>{"use strict";n.d(t,{default:()=>a});var r=n(3696),o=n.n(r),i=n(9758);const a=()=>o().createElement(i.Menu,{items:[{title:"item 1",children:[{title:"item 1 child 1"},{title:"item 1 child 2",children:[{title:"item 1 child 2 child 1"},{title:"item 1 child 2 child 2"}]}]},{title:"item 2",children:[{title:"item 2 child 1"},{title:"item 2 child 2 disabled",disabled:!0}]},{type:"divider"},{title:"item 3"}],style:{left:"100px",top:"100px"}})},425:(e,t,n)=>{"use strict";n.d(t,{default:()=>p});var r=n(3696),o=n.n(r),i=n(9758),a=Object.defineProperty,s=Object.getOwnPropertySymbols,c=Object.prototype.hasOwnProperty,l=Object.prototype.propertyIsEnumerable,u=(e,t,n)=>t in e?a(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n;const p=()=>{const{ref:e,x:t,setX:n,y:r,setY:a}=(0,i.useWheelScroll)(),{ref:p,scale:d}=(0,i.useWheelZoom)({onChange(e,t,r){const o=(0,i.scaleByCursorPosition)({width:h,height:m},t/e,r);n(o.setX),a(o.setY)}}),f=i.reactSvgRenderTarget,g=(0,i.useWindowSize)(),h=g.width/2,m=g.height/2,y={x:t,y:r,scale:d,center:{x:h/2,y:m/2}},v=[f.renderImage("https://farm9.staticflickr.com/8873/18598400202_3af67ef38f_z_d.jpg",0,0,1200,800)],{setMinimapTransform:x,minimap:b,getMinimapPosition:C}=(0,i.useMinimap)({width:100,height:100,viewport:{width:h/y.scale,height:m/y.scale,center:(0,i.reverseTransformPosition)(y.center,y)},children:e=>f.renderResult(v,100,100,{transform:e,attributes:{onClick:e=>{if(C){const t=C(e);n((y.center.x-t.x)*y.scale),a((y.center.y-t.y)*y.scale)}}}})});return o().useEffect((()=>{const e={start:{x:0,y:0},end:{x:1200,y:800}},t=(0,i.zoomToFit)(e,{width:100,height:100},{x:50,y:50},1);t&&x(((e,t)=>{for(var n in t||(t={}))c.call(t,n)&&u(e,n,t[n]);if(s)for(var n of s(t))l.call(t,n)&&u(e,n,t[n]);return e})({bounding:e},t))}),[]),o().createElement("div",{ref:(0,i.bindMultipleRefs)(e,p),style:{position:"absolute",inset:"0px"}},f.renderResult(v,h,m,{transform:y,attributes:{style:{border:"1px solid green"}}}),b)}},6856:(e,t,n)=>{"use strict";n.d(t,{default:()=>c});var r=n(3696),o=n.n(r),i=n(7469),a=n(9758),s=n(3385);const c=()=>{const e=(0,a.useWindowSize)().width/2,{x:t,y:n,ref:r,setX:c,setY:u}=(0,a.useWheelScroll)(),{scale:p,setScale:d,ref:f}=(0,a.useWheelZoom)({onChange(t,n,r){const o=(0,a.scaleByCursorPosition)({width:e,height:300},n/t,r);c(o.setX),u(o.setY)}}),[g,h]=o().useState(),[m,y]=o().useState("测试ABC"),[v,x]=o().useState(s.allFonts[0].name),[b,C]=o().useState(50),[E,P]=o().useState(0),[w,k]=o().useState(16777215),[_,S]=o().useState(1),[R,T]=o().useState(1),[A,L]=o().useState([]),[M,I]=o().useState(l[0]),O=null==g?void 0:g[v];o().useEffect((()=>{var e;e=function*(){const e={};for(const t of s.allFonts){const n=yield fetch(t.url),r=yield n.arrayBuffer();e[t.name]=i.parse(r)}h(e)},new Promise(((t,n)=>{var r=t=>{try{i(e.next(t))}catch(e){n(e)}},o=t=>{try{i(e.throw(t))}catch(e){n(e)}},i=e=>e.done?t(e.value):Promise.resolve(e.value).then(r,o);i((e=e.apply(undefined,null)).next())}))}),[]),(0,a.useGlobalKeyDown)((e=>{"Digit0"===e.code&&!e.shiftKey&&(0,a.metaKeyIfMacElseCtrlKey)(e)&&(d(1),c(0),u(0),e.preventDefault())})),o().useEffect((()=>{if(!O)return;const e=O.getPaths(m,0,b,b,{xScale:_*b/O.unitsPerEm,yScale:R*b/O.unitsPerEm}).map((e=>(0,s.opentypeCommandsToPathCommands)(e)));L(e)}),[m,O,b,M,_,R]);const D=A.map((e=>M.renderPathCommands(e,{fillColor:E,strokeColor:E}))).flat();return D.push(M.renderText(0,2*b,m,E,b*Math.max(_,R),v)),o().createElement("div",{style:{position:"absolute",inset:"0px"},ref:(0,a.bindMultipleRefs)(f,r)},M.renderResult(D,e,300,{transform:{x:t,y:n,scale:p},backgroundColor:w}),o().createElement("div",{style:{display:"flex",width:`${e}px`}},o().createElement(a.ObjectEditor,{inline:!0,properties:{text:o().createElement(a.StringEditor,{value:m,setValue:e=>y(e)}),"font family":o().createElement(a.EnumEditor,{select:!0,value:v,enums:s.allFonts.map((e=>e.name)),setValue:e=>{var t,n;return x(null!=(n=null==(t=s.allFonts.find((t=>t.name===e)))?void 0:t.name)?n:s.allFonts[0].name)}}),"font size":o().createElement(a.NumberEditor,{value:b,setValue:e=>C(e)}),"render target":o().createElement(a.EnumEditor,{select:!0,value:M.type,enums:l.map((e=>e.type)),setValue:e=>{var t;return I(null!=(t=l.find((t=>t.type===e)))?t:l[0])}}),color:o().createElement(a.NumberEditor,{type:"color",value:E,setValue:e=>P(e)}),"background color":o().createElement(a.NumberEditor,{type:"color",value:w,setValue:e=>k(e)}),"x scale":o().createElement(a.NumberEditor,{value:_,setValue:e=>S(e)}),"y scale":o().createElement(a.NumberEditor,{value:R,setValue:e=>T(e)}),actions:o().createElement(a.Button,{onClick:()=>navigator.clipboard.writeText(JSON.stringify({contents:A.map(((e,t)=>({id:t,content:{type:"path",commands:e,strokeColor:E,fillColor:E}}))),center:{x:0,y:0}}))},"copy as command path")}})))},l=[a.reactCanvasRenderTarget,a.reactSvgRenderTarget,a.reactWebglRenderTarget]},3385:(e,t,n)=>{"use strict";n.d(t,{allFonts:()=>a,opentypeCommandsToPathCommands:()=>o});var r=n(9758);function o(e,t){const n=[];for(const r of e.commands)"M"===r.type?n.push({type:"move",to:i({x:r.x,y:r.y},t)}):"L"===r.type?n.push({type:"line",to:i({x:r.x,y:r.y},t)}):"C"===r.type?n.push({type:"bezierCurve",cp1:i({x:r.x1,y:r.y1},t),cp2:i({x:r.x2,y:r.y2},t),to:i({x:r.x,y:r.y},t)}):"Q"===r.type?n.push({type:"quadraticCurve",cp:i({x:r.x1,y:r.y1},t),to:i({x:r.x,y:r.y},t)}):n.push({type:"close"});return n}function i(e,t){return void 0!==t&&(0,r.skewPoint)(e,{x:0,y:t},-.15),e}const a=[{name:"STSong",url:"https://raw.githubusercontent.com/Haixing-Hu/latex-chinese-fonts/master/chinese/%E5%AE%8B%E4%BD%93/STSong.ttf"},{name:"Arial",url:"https://raw.githubusercontent.com/Haixing-Hu/latex-chinese-fonts/master/english/Sans/Arial.ttf"}]},5047:(e,t,n)=>{"use strict";n.d(t,{default:()=>s});var r=n(8662),o=n(3696),i=n.n(o),a=n(9758);const s=()=>{const[e,t]=i().useState({value:1,children:[{value:10},{value:100}]}),{editingContent:n,setEditingContentPath:o,prependPatchPath:s}=(0,a.usePartialEdit)(e);return i().createElement(i().Fragment,null,i().createElement("button",{onClick:()=>{const[,o]=(0,r.produceWithPatches)(n,(e=>{e.value++}));t((0,r.applyPatches)(e,s(o)))}},"+1"),i().createElement("button",{onClick:()=>o([])},"exit"),i().createElement("div",null,n.value,n.children&&n.children.map(((e,t)=>i().createElement("button",{key:t,style:{width:"50px",height:"50px"},onClick:()=>o(["children",t])},e.value)))))}},5836:(e,t,n)=>{"use strict";n.d(t,{default:()=>s});var r=n(3696),o=n.n(r),i=n(9758);const a={count:0},s=()=>{const{state:e,setState:t,undo:n,redo:r}=(0,i.usePatchBasedUndoRedo)(a,"a");return(0,i.useGlobalKeyDown)((e=>{"KeyZ"===e.code&&(0,i.metaKeyIfMacElseCtrlKey)(e)&&(e.shiftKey?r(e):n(e))})),o().createElement("button",{onClick:()=>t((e=>{e.count++})),style:{width:"200px",height:"100px"}},e.count)}},5207:(e,t,n)=>{"use strict";n.d(t,{default:()=>s});var r=n(8662),o=n(3696),i=n.n(o),a=n(9758);const s=()=>{const[e,t]=i().useState([]),{preview:n,onClick:o,onMove:s,input:c,setInputType:l,reset:u}=(0,a.usePathClickCreate)(!0,(n=>{t((0,r.produce)(e,(e=>{e.push(n)})))}));return(0,a.useGlobalKeyDown)((e=>{"Escape"===e.key&&u(!0)})),i().createElement("div",{style:{height:"100%"}},i().createElement("svg",{viewBox:"0 0 800 600",width:800,height:600,xmlns:"http://www.w3.org/2000/svg",fill:"none",style:{position:"absolute",left:0,top:0},onClick:e=>o({x:e.clientX,y:e.clientY}),onMouseMove:e=>s({x:e.clientX,y:e.clientY})},[...e,n].map(((e,t)=>e&&a.reactSvgRenderTarget.renderPathCommands(e,{strokeColor:65280})(t,1,!1,800,600)))),["line","arc","bezierCurve","quadraticCurve","close"].map((e=>i().createElement("button",{key:e,style:{position:"relative"},onClick:()=>l(e)},e))),c)}},5779:(e,t,n)=>{"use strict";n.d(t,{default:()=>s});var r=n(8662),o=n(3696),i=n.n(o),a=n(9758);const s=()=>{const[e,t]=i().useState([]),{points:n,onClick:o,onMove:s,reset:c}=(0,a.usePenClickCreate)(!0,(()=>{t((0,r.produce)(e,(e=>{e.push(n)})))}));return(0,a.useGlobalKeyDown)((e=>{"Escape"===e.key&&c()})),i().createElement("div",{style:{height:"100%"}},i().createElement("svg",{viewBox:"0 0 800 600",width:800,height:600,xmlns:"http://www.w3.org/2000/svg",fill:"none",style:{position:"absolute",left:0,top:0},onClick:e=>o({x:e.clientX,y:e.clientY}),onMouseMove:e=>s({x:e.clientX,y:e.clientY})},[...e,n].map(((e,t)=>e&&i().createElement("polyline",{key:t,stroke:"#00ff00",points:e.map((e=>`${e.x},${e.y}`)).join(" ")})))))}},2890:(e,t,n)=>{"use strict";n.d(t,{default:()=>a});var r=n(3696),o=n.n(r),i=n(9758);const a=()=>{var e,t;const n=(0,i.useWindowSize)(),r=n.width/2,a=n.height,s=i.reactCanvasRenderTarget,c={x:r/2,y:a/3},[l,u]=o().useState(r/2),[p,d]=o().useState(!1),[f,g]=o().useState({radian:-Math.PI/4,speed:0}),[h,m]=o().useState(),[y,v,x]=(0,i.useRefState)(!1),[b,C,E]=(0,i.useRefState2)(),P=null!=(e=null!=b?b:h)?e:f,w=null!=(t=null==h?void 0:h.length)?t:l,k={x:c.x-w*Math.sin(P.radian),y:c.y+w*Math.cos(P.radian),r:10},_=(0,i.getPointByLengthAndRadian)(k,P.speed*w+k.r*(P.speed>=0?1:-1),(0,i.getTwoPointsRadian)(k,c)+Math.PI/2),S=[s.renderCircle(c.x,c.y,5),s.renderCircle(k.x,k.y,k.r,{fillColor:0,strokeWidth:0}),s.renderPolyline([c,k]),s.renderPolyline([k,_])],R=(0,i.useEvent)((()=>{h&&(g(h),u(h.length),d(!1),m(void 0))})),T=(0,i.useEvent)((e=>{if(p){const t={x:e.clientX,y:e.clientY};m({radian:(0,i.getTwoPointsRadian)(t,c)-Math.PI/2,speed:0,length:(0,i.getTwoPointsDistance)(t,c)})}}));return o().createElement("div",{style:{position:"absolute",inset:"0px"},onMouseMove:T},s.renderResult(S,r,a,{attributes:{onClick:R}}),o().createElement("div",{style:{position:"absolute",top:"0px"}},o().createElement(i.Button,{onClick:()=>{if(x.current)return void v(!1);let e;v(!0);const t=n=>{var r;if(x.current){if(void 0!==e){const t=.005*(n-e),o=null!=(r=E.current)?r:f,i=c.y+w*Math.cos(f.radian),a=c.y+w*Math.cos(o.radian),s=9.8;let l=o.speed-s*Math.sin(o.radian)/w*t;if(a!==i){const e=Math.sqrt(s*Math.abs(a-i)*2)/w;e{v(!1),C(void 0)}},"stop"),void 0===b&&o().createElement(i.Button,{style:{color:p?"red":void 0},onClick:()=>d(!0)},"edit")))}},1993:(e,t,n)=>{"use strict";n.d(t,{default:()=>a});var r=n(3696),o=n.n(r),i=n(9758);const a=()=>{const e=(0,i.useWindowSize)().width/2,t=350,n=i.reactSvgRenderTarget,[r,a]=o().useState(),[s,c]=o().useState(),[l,u]=o().useState(),[p,d]=o().useState(),f=e=>Intl.DateTimeFormat("zh",{month:"long"}).format(new Date(e.toString()));if(o().useEffect((()=>{const r=[[65,59,80,81,56,55,40],[75,49,70,71,46,45,30],[85,39,60,61,36,35,20]],o=[16711680,65280,255,16711680,65280,255,0];u((0,i.getPieChart)(r,o,n,{width:e,height:t},{left:10,right:10,top:10,bottom:10})),d((0,i.getPieChart)(r,o,n,{width:e,height:t},{left:10,right:10,top:10,bottom:10},{type:"doughnut"}))}),[e]),!l||!p)return null;let g=l.children;r&&(g=[...l.children,...(0,i.renderChartTooltip)(n,r,r.value,{getXLabel:f})]);let h=p.children;return s&&(h=[...p.children,...(0,i.renderChartTooltip)(n,s,s.value,{getXLabel:f})]),o().createElement("div",{style:{position:"absolute",inset:"0px",display:"flex",flexDirection:"column"}},n.renderResult(g,e,t,{attributes:{onMouseMove:e=>a(l.select({x:e.clientX,y:e.clientY}))}}),n.renderResult(h,e,t,{attributes:{onMouseMove:e=>c(p.select({x:e.clientX,y:e.clientY-t}))}}))}},7631:(e,t,n)=>{"use strict";n.d(t,{default:()=>g});var r=n(3696),o=n.n(r),i=n(9758),a=Object.defineProperty,s=Object.getOwnPropertySymbols,c=Object.prototype.hasOwnProperty,l=Object.prototype.propertyIsEnumerable,u=(e,t,n)=>t in e?a(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,p=(e,t)=>{for(var n in t||(t={}))c.call(t,n)&&u(e,n,t[n]);if(s)for(var n of s(t))l.call(t,n)&&u(e,n,t[n]);return e};const d=new i.WeakmapCache2,f=[{x:300,y:200,r:100},{x:450,y:350,r:130}],g=()=>{const[e,t]=o().useState(),{width:n,height:r}=(0,i.useWindowSize)(),a={x:500,y:100},{getSnapAssistentContents:s,getSnapPoint:c}=(0,i.usePointSnap)(!0,((e,t)=>d.get(e,t,(()=>Array.from((0,i.iterateIntersectionPoints)(e,t,f,(()=>({getGeometries:e=>({lines:[{type:"arc",curve:(0,i.circleToArc)(e)}]})}))))))),i.allSnapTypes,(()=>({getSnapPoints:e=>[{x:e.x,y:e.y,type:"center"},{x:e.x-e.r,y:e.y,type:"endpoint"},{x:e.x+e.r,y:e.y,type:"endpoint"},{x:e.x,y:e.y-e.r,type:"endpoint"},{x:e.x,y:e.y+e.r,type:"endpoint"}],getGeometries:e=>({lines:[{type:"arc",curve:(0,i.circleToArc)(e)}],bounding:{start:{x:e.x-e.r,y:e.y-e.r},end:{x:e.x+e.r,y:e.y+e.r}}})})),void 0,void 0,(e=>({x:(0,i.formatNumber)(e.x,.05),y:(0,i.formatNumber)(e.y,.05)}))),l=s((e=>p({type:"circle"},e)),(e=>p({type:"rect"},e)),(e=>({type:"polyline",points:e})),(e=>p({type:"ray"},e))),u=(0,i.getGridLines)({start:{x:0,y:0},end:{x:n/2,y:r}},20);return o().createElement(o().Fragment,null,o().createElement("svg",{viewBox:`0 0 ${n/2} ${r}`,width:n/2,height:r,xmlns:"http://www.w3.org/2000/svg",fill:"none",style:{position:"absolute",left:0,top:0},onMouseMove:e=>t(c({x:e.clientX,y:e.clientY},f,void 0,a).position)},f.map(((e,t)=>o().createElement("circle",{key:t,cx:e.x,cy:e.y,r:e.r,stroke:"#000000"}))),u.map(((e,t)=>o().createElement("polyline",{key:t,points:e.map((e=>`${e.x},${e.y}`)).join(" "),stroke:"black",strokeOpacity:"0.2"}))),e&&o().createElement("polyline",{points:`${a.x},${a.y} ${e.x},${e.y}`,strokeDasharray:4,stroke:"#ff0000"}),l.map(((e,t)=>"rect"===e.type?o().createElement("rect",{key:t,x:e.x-e.width/2,y:e.y-e.height/2,width:e.width,height:e.height,stroke:"#00ff00"}):"circle"===e.type?o().createElement("circle",{key:t,cx:e.x,cy:e.y,r:e.r,stroke:"#00ff00"}):"ray"===e.type?null:o().createElement("polyline",{key:t,points:e.points.map((e=>`${e.x},${e.y}`)).join(" "),stroke:"#00ff00"}))),e&&o().createElement("circle",{cx:e.x,cy:e.y,r:5,stroke:"#ff0000"})))}},277:(e,t,n)=>{"use strict";n.d(t,{default:()=>f});var r=n(3696),o=n.n(r),i=n(9758),a=Object.defineProperty,s=Object.defineProperties,c=Object.getOwnPropertyDescriptors,l=Object.getOwnPropertySymbols,u=Object.prototype.hasOwnProperty,p=Object.prototype.propertyIsEnumerable,d=(e,t,n)=>t in e?a(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n;const f=()=>{const e=(0,i.useWindowSize)().width/2,t=i.reactSvgRenderTarget,[n,r]=o().useState(),[a,f]=o().useState(),g=e=>Intl.DateTimeFormat("zh",{month:"long"}).format(new Date((e+1).toString()));if(o().useEffect((()=>{const n=(0,i.getPolarAreaChart)([65,59,80,81,56,55,40],[16711680,65280,255,16711680,65280,255,0],t,{width:e,height:350},10,{left:10,right:10,top:30,bottom:10});n.angles.forEach(((e,r)=>{const o=(0,i.getArcPointAtAngle)((a=((e,t)=>{for(var n in t||(t={}))u.call(t,n)&&d(e,n,t[n]);if(l)for(var n of l(t))p.call(t,n)&&d(e,n,t[n]);return e})({},n.circle),f={r:n.circle.r+30},s(a,c(f))),e);var a,f;n.children.push(t.renderText(o.x,o.y,g(r),13421772,20,"monospace",{textAlign:"center",textBaseline:"middle"}))})),f(n)}),[e]),!a)return null;let h=a.children;return n&&(h=[...a.children,...(0,i.renderChartTooltip)(t,n,n.value,{getXLabel:g})]),o().createElement("div",{style:{position:"absolute",inset:"0px",display:"flex",flexDirection:"column"}},t.renderResult(h,e,350,{attributes:{onMouseMove:e=>r(a.select({x:e.clientX,y:e.clientY}))}}))}},574:(e,t,n)=>{"use strict";n.d(t,{default:()=>s});var r=n(8662),o=n(3696),i=n.n(o),a=n(9758);const s=()=>{const[e,t]=i().useState([]),{polygon:n,onClick:o,onMove:s,input:c,reset:l}=(0,a.usePolygonClickCreate)(!0,(o=>{const i=o||n;i&&t((0,r.produce)(e,(e=>{e.push(i)})))}));return(0,a.useGlobalKeyDown)((e=>{"Escape"===e.key&&l()})),i().createElement("div",{style:{height:"100%"}},i().createElement("svg",{viewBox:"0 0 800 600",width:800,height:600,xmlns:"http://www.w3.org/2000/svg",fill:"none",style:{position:"absolute",left:0,top:0},onClick:e=>o({x:e.clientX,y:e.clientY}),onMouseMove:e=>s({x:e.clientX,y:e.clientY})},[...e,n].map(((e,t)=>e&&i().createElement("polygon",{key:t,stroke:"#00ff00",points:e.map((e=>`${e.x},${e.y}`)).join(" ")})))),c)}},597:(e,t,n)=>{"use strict";n.d(t,{default:()=>s});var r=n(8662),o=n(3696),i=n.n(o),a=n(9758);const s=()=>{const[e,t]=i().useState([{x:100,y:100},{x:300,y:200},{x:100,y:200}]),{offset:n,onStart:o,mask:s,reset:c}=(0,a.usePolylineEdit)((()=>t(l))),l=(0,r.produce)(e,(e=>{if(n)for(const t of n.pointIndexes)e[t].x+=n.x,e[t].y+=n.y}));return(0,a.useGlobalKeyDown)((e=>{"Escape"===e.key&&c()})),i().createElement(i().Fragment,null,i().createElement("svg",{viewBox:"0 0 800 600",width:800,height:600,xmlns:"http://www.w3.org/2000/svg",fill:"none",style:{position:"absolute",left:0,top:0}},i().createElement("polyline",{stroke:"#00ff00",points:l.map((e=>`${e.x},${e.y}`)).join(" ")})),i().createElement(a.PolylineEditBar,{points:l,onMouseDown:(e,t)=>o(e,t)}),s)}},4623:(e,t,n)=>{"use strict";n.d(t,{default:()=>f});var r=n(3696),o=n.n(r),i=n(9758),a=Object.defineProperty,s=Object.defineProperties,c=Object.getOwnPropertyDescriptors,l=Object.getOwnPropertySymbols,u=Object.prototype.hasOwnProperty,p=Object.prototype.propertyIsEnumerable,d=(e,t,n)=>t in e?a(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n;const f=()=>{const e=(0,i.useWindowSize)().width/2,t=i.reactSvgRenderTarget,[n,r]=o().useState(),[a,f]=o().useState(),g=e=>Intl.DateTimeFormat("zh",{month:"long"}).format(new Date((e+1).toString()));if(o().useEffect((()=>{const n=(0,i.getRadarChart)([[65,59,80,81,56,55,40],[45,39,60,61,36,35,20]],[16711680,65280],t,{width:e,height:350},20,{left:10,right:10,top:30,bottom:30});n.angles.forEach(((e,r)=>{const o=(0,i.getArcPointAtAngle)((a=((e,t)=>{for(var n in t||(t={}))u.call(t,n)&&d(e,n,t[n]);if(l)for(var n of l(t))p.call(t,n)&&d(e,n,t[n]);return e})({},n.circle),f={r:n.circle.r+15},s(a,c(f))),e);var a,f;n.children.push(t.renderText(o.x,o.y,g(r),13421772,12,"monospace",{textAlign:"center",textBaseline:"middle"}))})),f(n)}),[e]),!a)return null;let h=a.children;return n&&(h=[...a.children,...(0,i.renderChartTooltip)(t,n,n.value,{getXLabel:g})]),o().createElement("div",{style:{position:"absolute",inset:"0px",display:"flex",flexDirection:"column"}},t.renderResult(h,e,350,{attributes:{onMouseMove:e=>r(a.select({x:e.clientX,y:e.clientY}))}}))}},4922:(e,t,n)=>{"use strict";n.d(t,{default:()=>s});var r=n(3696),o=n.n(r),i=n(9758),a=n(4469);const s=()=>{const e={x:200,y:200,r:100},t={position:{x:400,y:300},fontFamily:"monospace",fontSize:16},{regions:n,lines:r}=(0,i.getRadialDimensionGeometries)(t,e,a.dimensionStyle,((e,t)=>(0,i.getRadialDimensionTextPosition)(e,t,a.dimensionStyle.margin,i.getTextSize))),{textPosition:s,textRotation:c,text:l}=(0,i.getRadialDimensionTextPosition)(t,e,a.dimensionStyle.margin,i.getTextSize);return o().createElement("svg",{viewBox:"0 0 800 600",width:800,height:600,xmlns:"http://www.w3.org/2000/svg",fill:"none",style:{position:"absolute",left:0,top:0}},o().createElement("circle",{cx:e.x,cy:e.y,r:e.r,stroke:"black"}),r.map(((e,t)=>o().createElement("polyline",{key:t,stroke:"black",points:e.map((e=>`${e.x},${e.y}`)).join(" ")}))),n&&n.length>0&&o().createElement("polyline",{stroke:"black",points:n[0].points.map((e=>`${e.x},${e.y}`)).join(" "),fill:"black"}),o().createElement("text",{x:s.x,y:s.y,fill:"black",transform:(0,i.getRotateTransform)(s.x,s.y,{rotation:c}),style:{fontSize:`${t.fontSize}px`,fontFamily:t.fontFamily}},l))}},5982:(e,t,n)=>{"use strict";n.d(t,{default:()=>g});var r=n(3696),o=n(9758),i=Object.defineProperty,a=Object.defineProperties,s=Object.getOwnPropertyDescriptors,c=Object.getOwnPropertySymbols,l=Object.prototype.hasOwnProperty,u=Object.prototype.propertyIsEnumerable,p=(e,t,n)=>t in e?i(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,d=(e,t)=>{for(var n in t||(t={}))l.call(t,n)&&p(e,n,t[n]);if(c)for(var n of c(t))u.call(t,n)&&p(e,n,t[n]);return e},f=(e,t)=>a(e,s(t));const g=()=>{const[e,t]=r.useState(!1),{value:n,update:i,getArrayProps:a}=(0,o.useJsonEditorData)({stringExample:"a string example",booleanExample:!1,numberExample:123.4,objectExample:{propertyExample1:"",propertyExample2:0},inlineObjectExample:{propertyExample1:"",propertyExample2:0},arrayExample:["item1","item2"],inlineArrayExample:["item1","item2"],optionalExample:void 0,enumExample:"enum 1",colorExample:"#000000",textareaExample:"",imagePreviewExample:"http://image2.sina.com.cn/bj/art/2004-08-02/U91P52T4D51657F160DT20040802125523.jpg",itemTitleExample:[{propertyExample1:"foo",propertyExample2:1},{propertyExample1:"bar",propertyExample2:2}],inlineObjectArrayExample:[{propertyExample1:"foo",propertyExample2:1,propertyExample3:{propertyExample4:2,propertyExample5:""}},{propertyExample1:"bar",propertyExample2:2,propertyExample3:{propertyExample4:3,propertyExample5:""}}],enumTitlesExample:"enum 1",enumArrayExample:["foo"]}),s=JSON.stringify(n,null," ");return r.createElement("div",{style:{position:"relative"}},r.createElement(o.BooleanEditor,{style:{display:"inline"},value:e,setValue:e=>t(e)})," read only",r.createElement("br",null),r.createElement("div",{style:{height:"400px",margin:"10px",position:"absolute",overflowY:"auto"}},r.createElement(o.ObjectEditor,{properties:{"A string example":r.createElement(o.StringEditor,{value:n.stringExample,setValue:i(((e,t)=>e.stringExample=t))}),"A boolean example":r.createElement(o.BooleanEditor,{value:n.booleanExample,setValue:i(((e,t)=>e.booleanExample=t))}),"A number example":r.createElement(o.NumberEditor,{value:n.numberExample,setValue:i(((e,t)=>e.numberExample=t))}),"A object example":r.createElement(o.ObjectEditor,{properties:{"Property example 1":r.createElement(o.StringEditor,{value:n.objectExample.propertyExample1,setValue:i(((e,t)=>e.objectExample.propertyExample1=t))}),"Property example 2":r.createElement(o.NumberEditor,{value:n.objectExample.propertyExample2,setValue:i(((e,t)=>e.objectExample.propertyExample2=t))})}}),"A inline object example":r.createElement(o.ObjectEditor,{inline:!0,properties:{"Property example 1":r.createElement(o.StringEditor,{value:n.inlineObjectExample.propertyExample1,setValue:i(((e,t)=>e.inlineObjectExample.propertyExample1=t))}),"Property example 2":r.createElement(o.NumberEditor,{value:n.inlineObjectExample.propertyExample2,setValue:i(((e,t)=>e.inlineObjectExample.propertyExample2=t))})}}),"A array example":r.createElement(o.ArrayEditor,f(d({},a((e=>e.arrayExample),"")),{items:n.arrayExample.map(((e,t)=>r.createElement(o.StringEditor,{value:e,setValue:i(((e,n)=>e.arrayExample[t]=n))})))})),"A inline array example":r.createElement(o.ArrayEditor,f(d({inline:!0},a((e=>e.inlineArrayExample),"")),{items:n.inlineArrayExample.map(((e,t)=>r.createElement(o.StringEditor,{value:e,setValue:i(((e,n)=>e.inlineArrayExample[t]=n))})))})),"A optional example":[r.createElement(o.BooleanEditor,{value:void 0!==n.optionalExample,setValue:i(((e,t)=>e.optionalExample=t?"":void 0))}),void 0!==n.optionalExample?r.createElement(o.StringEditor,{value:n.optionalExample,setValue:i(((e,t)=>e.optionalExample=t))}):void 0],"A enum example":r.createElement(o.EnumEditor,{value:n.enumExample,enums:["enum 1","enum 2"],setValue:i(((e,t)=>e.enumExample=t))}),"A enum example 2":r.createElement(o.EnumEditor,{select:!0,value:n.enumExample,enums:["enum 1","enum 2"],setValue:i(((e,t)=>e.enumExample=t))}),"A color example":r.createElement(o.StringEditor,{type:"color",value:n.colorExample,setValue:i(((e,t)=>e.colorExample=t))}),"A textarea example":r.createElement(o.StringEditor,{textarea:!0,value:n.textareaExample,setValue:i(((e,t)=>e.textareaExample=t))}),"A image preview example":r.createElement(o.StringEditor,{value:n.imagePreviewExample,setValue:i(((e,t)=>e.imagePreviewExample=t))}),"A item title example":r.createElement(o.ArrayEditor,f(d({},a((e=>e.itemTitleExample),{propertyExample1:"",propertyExample2:0})),{title:e=>n.itemTitleExample[e].propertyExample1,items:n.itemTitleExample.map(((e,t)=>r.createElement(o.ObjectEditor,{properties:{"Property example 1":r.createElement(o.StringEditor,{value:e.propertyExample1,setValue:i(((e,n)=>e.itemTitleExample[t].propertyExample1=n))}),"Property example 2":r.createElement(o.NumberEditor,{value:e.propertyExample2,setValue:i(((e,n)=>e.itemTitleExample[t].propertyExample2=n))})}})))})),"A inline object array example":r.createElement(o.ObjectArrayEditor,f(d({},a((e=>e.inlineObjectArrayExample),{propertyExample1:"",propertyExample2:0,propertyExample3:{propertyExample4:0,propertyExample5:""}})),{properties:n.inlineObjectArrayExample.map(((e,t)=>({"Property example 1":r.createElement(o.StringEditor,{value:e.propertyExample1,setValue:i(((e,n)=>e.inlineObjectArrayExample[t].propertyExample1=n))}),"Property example 2":r.createElement(o.NumberEditor,{value:e.propertyExample2,setValue:i(((e,n)=>e.inlineObjectArrayExample[t].propertyExample2=n))}),"Property example 3":r.createElement(o.DialogContainer,null,r.createElement(o.ObjectEditor,{inline:!0,properties:{"Property example 3":r.createElement(o.NumberEditor,{value:e.propertyExample3.propertyExample4,setValue:i(((e,n)=>e.inlineObjectArrayExample[t].propertyExample3.propertyExample4=n))}),"Property example 4":r.createElement(o.StringEditor,{value:e.propertyExample3.propertyExample5,setValue:i(((e,n)=>e.inlineObjectArrayExample[t].propertyExample3.propertyExample5=n))})}}))})))})),"A enum titles example":r.createElement(o.EnumEditor,{enumTitles:["enum title 1","enum title 2"],value:n.enumTitlesExample,enums:["enum 1","enum 2"],setValue:i(((e,t)=>e.enumTitlesExample=t))}),"A enum array example":r.createElement(o.EnumArrayEditor,{enumTitles:["foo title","bar title"],value:n.enumArrayExample,enums:["foo","bar"],setValue:i(((e,t)=>e.enumArrayExample=t))})},readOnly:e})),r.createElement("div",{style:{margin:"10px",position:"absolute",top:"450px"}},r.createElement("pre",{style:{borderColor:"black",padding:"10px"}},r.createElement("code",{dangerouslySetInnerHTML:{__html:s}}))))}},7560:(e,t,n)=>{"use strict";n.d(t,{default:()=>s});var r=n(3696),o=n.n(r),i=n(9758),a=n(5052);const s=()=>{const e=e=>e.renderResult([e.renderArc(40,20,50,0,120,{fillPattern:{width:10,height:10,pattern:()=>e.renderPath([[{x:0,y:5},{x:5,y:0}],[{x:10,y:5},{x:5,y:10}]],{strokeColor:255})}}),e.renderArc(40,40,80,0,120,{fillColor:16711680,strokeWidth:0}),e.renderArc(50,50,100,0,120,{strokeColor:65280}),e.renderArc(60,60,100,0,120,{strokeWidth:5}),e.renderArc(70,70,100,0,120,{dashArray:[4]}),e.renderArc(170,170,30,0,120,{counterclockwise:!0}),e.renderArc(170,170,20,120,0,{counterclockwise:!0}),e.renderArc(120,200,15,0,360),e.renderArc(120,200,10,360,0,{counterclockwise:!0}),e.renderArc(170,170,10,0,120,{closed:!0})],230,310),t=e=>e.renderResult([e.renderCircle(70,100,30,{fillPattern:{width:10,height:10,pattern:()=>e.renderPath([[{x:0,y:5},{x:5,y:0}],[{x:10,y:5},{x:5,y:10}]],{strokeColor:255})}}),e.renderCircle(150,100,30,{fillColor:16711680,strokeWidth:0}),e.renderCircle(110,100,70,{strokeColor:65280}),e.renderCircle(110,100,80,{strokeWidth:5}),e.renderCircle(110,100,90,{dashArray:[4]})],230,200),n=e=>e.renderResult([e.renderText(10,30,"Hello World!",16711680,30,"monospace"),e.renderText(10,60,"Hello World!",16711680,30,"monospace",{fontWeight:"bold"}),e.renderText(10,90,"Hello World!",16711680,30,"monospace",{fontStyle:"italic"}),e.renderText(10,150,"He",{width:4,height:4,pattern:()=>e.renderPath([[{x:0,y:2},{x:2,y:0}],[{x:4,y:2},{x:2,y:4}]],{strokeColor:255})},70,"monospace"),e.renderText(90,150,"l",void 0,70,"monospace",{strokeColor:16711680}),e.renderText(130,150,"l",void 0,70,"monospace",{strokeColor:16711680,dashArray:[2]}),e.renderText(170,150,"l",void 0,70,"monospace",{strokeColor:16711680,strokeWidth:3}),e.renderText(10,200,"H",65280,70,"monospace",{strokeColor:16711680,strokeWidth:3}),e.renderText(50,200,"H",65280,70,"monospace",{strokeColor:16711680,strokeWidth:3,strokeOpacity:.3,fillOpacity:.3}),e.renderText(90,200,"H",void 0,70,"monospace",{strokePattern:{width:4,height:4,pattern:()=>e.renderPath([[{x:0,y:2},{x:2,y:0}],[{x:4,y:2},{x:2,y:4}]],{strokeColor:255})},strokeWidth:3}),e.renderText(130,200,"H",void 0,70,"monospace",{strokeLinearGradient:{start:{x:150,y:230},end:{x:190,y:150},stops:[{offset:.2,color:16711680},{offset:.5,color:16776960},{offset:.8,color:65280}]},strokeWidth:3}),e.renderText(170,200,"H",void 0,70,"monospace",{strokeRadialGradient:{start:{x:190,y:185,r:5},end:{x:190,y:180,r:30},stops:[{offset:0,color:16711680},{offset:.5,color:16776960},{offset:1,color:65280}]},strokeWidth:3}),e.renderText(70,225,"center",65280,30,"monospace",{textAlign:"center"}),e.renderText(130,250,"right",65280,30,"monospace",{textAlign:"right"}),e.renderText(130,250,"H",void 0,70,"monospace",{fillLinearGradient:{start:{x:150,y:280},end:{x:190,y:200},stops:[{offset:.2,color:16711680},{offset:.5,color:16776960},{offset:.8,color:65280}]},strokeWidth:3}),e.renderText(170,250,"H",void 0,70,"monospace",{fillRadialGradient:{start:{x:190,y:235,r:5},end:{x:190,y:230,r:30},stops:[{offset:0,color:16711680},{offset:.5,color:16776960},{offset:1,color:65280}]},strokeWidth:3}),e.renderText(10,300,"fgj",65280,30,"monospace",{textBaseline:"alphabetic"}),e.renderText(65,300,"fgj",65280,30,"monospace",{textBaseline:"top"}),e.renderText(120,300,"fgj",65280,30,"monospace",{textBaseline:"middle"}),e.renderText(175,300,"fgj",65280,30,"monospace",{textBaseline:"bottom"})],230,550),r=e=>e.renderResult([e.renderEllipseArc(40,10,50,30,0,120,{fillPattern:{width:10,height:10,pattern:()=>e.renderPath([[{x:0,y:5},{x:5,y:0}],[{x:10,y:5},{x:5,y:10}]],{strokeColor:255})}}),e.renderEllipseArc(40,30,80,40,0,120,{fillColor:16711680,strokeWidth:0}),e.renderEllipseArc(50,40,100,50,0,120,{strokeColor:65280}),e.renderEllipseArc(60,50,100,50,0,120,{strokeWidth:5}),e.renderEllipseArc(70,60,100,50,0,120,{dashArray:[4]}),e.renderEllipseArc(170,160,30,15,0,120,{counterclockwise:!0}),e.renderEllipseArc(170,160,30,25,120,20,{counterclockwise:!0}),e.renderEllipseArc(110,100,80,40,0,120,{strokeColor:65280,angle:30}),e.renderEllipseArc(120,200,30,15,0,360),e.renderEllipseArc(120,200,20,10,360,0,{counterclockwise:!0}),e.renderEllipseArc(170,160,25,20,0,120,{closed:!0})],230,330),s=e=>e.renderResult([e.renderEllipse(70,60,40,20,{fillPattern:{width:10,height:10,pattern:()=>e.renderPath([[{x:0,y:5},{x:5,y:0}],[{x:10,y:5},{x:5,y:10}]],{strokeColor:255})}}),e.renderEllipse(150,60,40,20,{fillColor:16711680,strokeWidth:0}),e.renderEllipse(110,60,90,45,{strokeColor:65280}),e.renderEllipse(110,60,100,50,{strokeWidth:5}),e.renderEllipse(110,60,110,55,{dashArray:[4]}),e.renderEllipse(110,140,80,40,{strokeColor:255,angle:30}),e.renderEllipse(110,30,10,20,{angle:60,fillPattern:{width:10,height:10,pattern:()=>e.renderPath([[{x:0,y:5},{x:5,y:0}],[{x:10,y:5},{x:5,y:10}]],{strokeColor:255})}})],230,230),c=e=>e.renderResult([e.renderRect(10,10,50,30,{fillPattern:{width:10,height:10,pattern:()=>e.renderPath([[{x:0,y:5},{x:5,y:0}],[{x:10,y:5},{x:5,y:10}]],{strokeColor:255})}}),e.renderRect(70,10,80,40,{fillColor:16711680,strokeWidth:0}),e.renderRect(90,60,100,140,{strokeColor:65280}),e.renderRect(100,70,80,120,{strokeWidth:5}),e.renderRect(110,80,60,100,{dashArray:[4]}),e.renderRect(10,90,60,30,{angle:60})],230,220),l=e=>e.renderResult([e.renderPath([[{x:5,y:10},{x:45,y:150},{x:45,y:10}],[{x:25,y:30},{x:25,y:70},{x:35,y:70},{x:35,y:30}]],{fillPattern:{width:10,height:10,pattern:()=>e.renderPath([[{x:0,y:5},{x:5,y:0}],[{x:10,y:5},{x:5,y:10}]],{strokeColor:255})},strokeWidth:0}),e.renderPath([[{x:50,y:10},{x:90,y:150},{x:90,y:10}],[{x:70,y:30},{x:70,y:70},{x:80,y:70},{x:80,y:30}]],{fillColor:16711680,strokeWidth:0}),e.renderPath([[{x:95,y:10},{x:135,y:150},{x:135,y:10}],[{x:115,y:30},{x:115,y:70},{x:125,y:70},{x:125,y:30}]],{strokeColor:65280}),e.renderPath([[{x:140,y:10},{x:180,y:150},{x:180,y:10}],[{x:160,y:30},{x:160,y:70},{x:170,y:70},{x:170,y:30}]],{fillPattern:{width:100,height:100,pattern:()=>e.renderImage("https://farm9.staticflickr.com/8873/18598400202_3af67ef38f_z_d.jpg",0,0,100,100,{crossOrigin:""})},strokeWidth:0}),e.renderPath([[{x:185,y:10},{x:225,y:150},{x:225,y:10}],[{x:205,y:30},{x:205,y:70},{x:215,y:70},{x:215,y:30}]],{dashArray:[4]}),e.renderPath([[{x:5,y:160},{x:35,y:160},{x:35,y:190}]],{strokeColor:16711680,strokeWidth:5}),e.renderPath([[{x:45,y:160},{x:75,y:160},{x:75,y:190}]],{strokeColor:16711680,strokeWidth:5,closed:!0}),e.renderPath([[{x:85,y:160},{x:125,y:160},{x:125,y:190}]],{strokeColor:16711680,strokeWidth:5,closed:!0,miterLimit:2}),e.renderPath([[{x:135,y:160},{x:175,y:160},{x:175,y:190}]],{strokeColor:16711680,strokeWidth:10,lineJoin:"bevel"}),e.renderPath([[{x:185,y:160},{x:225,y:160},{x:225,y:190}]],{strokeColor:16711680,strokeWidth:10,lineJoin:"round"}),e.renderPath([[{x:10,y:210},{x:40,y:210},{x:40,y:240}]],{strokeColor:16711680,strokeWidth:10,lineCap:"square"}),e.renderPath([[{x:55,y:210},{x:85,y:210},{x:85,y:240}]],{strokeColor:16711680,strokeWidth:10,lineCap:"round"}),e.renderPath([[{x:100,y:210},{x:220,y:210}]],{dashArray:[12,4]}),e.renderPath([[{x:100,y:220},{x:220,y:220}]],{dashArray:[12,4],dashOffset:4}),e.renderPath([[{x:5,y:250},{x:45,y:390},{x:45,y:250}],[{x:25,y:270},{x:25,y:310},{x:35,y:310},{x:35,y:270}]],{fillLinearGradient:{start:{x:5,y:250},end:{x:45,y:390},stops:[{offset:.2,color:16711680},{offset:.5,color:16776960},{offset:.8,color:65280}]},strokeWidth:0}),e.renderPath([[{x:50,y:250},{x:90,y:390},{x:90,y:250}],[{x:70,y:270},{x:70,y:310},{x:80,y:310},{x:80,y:270}]],{fillRadialGradient:{start:{x:70,y:320,r:10},end:{x:70,y:320,r:70},stops:[{offset:0,color:16711680},{offset:.5,color:16776960},{offset:1,color:65280}]},strokeWidth:0}),e.renderPath([[{x:95,y:250},{x:135,y:390},{x:135,y:250}],[{x:115,y:270},{x:115,y:310},{x:125,y:310},{x:125,y:270}]],{fillColor:16711680,fillOpacity:.3,strokeOpacity:.3}),e.renderPath([[{x:140,y:250},{x:180,y:390},{x:180,y:250}],[{x:160,y:270},{x:160,y:310},{x:170,y:310},{x:170,y:270}]],{fillRadialGradient:{start:{x:160,y:320,r:10},end:{x:160,y:320,r:70},stops:[{offset:0,color:16711680,opacity:.3},{offset:.5,color:16776960,opacity:.3},{offset:1,color:65280,opacity:.3}]},strokeWidth:0}),e.renderPath([[{x:185,y:250},{x:225,y:390},{x:225,y:250}],[{x:205,y:270},{x:205,y:310},{x:215,y:310},{x:215,y:270}]],{strokePattern:{width:10,height:10,pattern:()=>e.renderPath([[{x:0,y:5},{x:5,y:0}],[{x:10,y:5},{x:5,y:10}]],{strokeColor:255})},strokeWidth:5}),e.renderPath([[{x:5,y:400},{x:45,y:540},{x:45,y:400}],[{x:25,y:420},{x:25,y:460},{x:35,y:460},{x:35,y:420}]],{strokeLinearGradient:{start:{x:5,y:400},end:{x:45,y:540},stops:[{offset:.2,color:16711680},{offset:.5,color:16776960},{offset:.8,color:65280}]},strokeWidth:5}),e.renderPath([[{x:50,y:400},{x:90,y:540},{x:90,y:400}],[{x:70,y:420},{x:70,y:460},{x:80,y:460},{x:80,y:420}]],{strokeRadialGradient:{start:{x:70,y:470,r:10},end:{x:70,y:470,r:70},stops:[{offset:0,color:16711680},{offset:.5,color:16776960},{offset:1,color:65280}]},strokeWidth:5}),e.renderPath([[{x:110,y:400},{x:110,y:470},{x:110,y:540}]],{strokeColor:16711680,strokeWidth:10}),e.renderPath([[{x:130,y:400},{x:130,y:540},{x:130,y:470}]],{strokeColor:16711680,strokeWidth:10})],230,620),u=e=>e.renderResult([e.renderImage("https://farm9.staticflickr.com/8873/18598400202_3af67ef38f_z_d.jpg",0,0,75,65,{crossOrigin:""}),e.renderImage("https://farm9.staticflickr.com/8873/18598400202_3af67ef38f_z_d.jpg",77,0,75,65,{opacity:.5,crossOrigin:""}),e.renderImage("https://farm9.staticflickr.com/8873/18598400202_3af67ef38f_z_d.jpg",154,0,75,65,{filters:[{type:"brightness",value:2}],crossOrigin:""}),e.renderImage("https://farm9.staticflickr.com/8873/18598400202_3af67ef38f_z_d.jpg",0,70,75,65,{filters:[{type:"contrast",value:2}],crossOrigin:""}),e.renderImage("https://farm9.staticflickr.com/8873/18598400202_3af67ef38f_z_d.jpg",77,70,75,65,{filters:[{type:"hue-rotate",value:90}],crossOrigin:""}),e.renderImage("https://farm9.staticflickr.com/8873/18598400202_3af67ef38f_z_d.jpg",154,70,75,65,{filters:[{type:"saturate",value:2}],crossOrigin:""}),e.renderImage("https://farm9.staticflickr.com/8873/18598400202_3af67ef38f_z_d.jpg",0,140,75,65,{filters:[{type:"saturate",value:2},{type:"hue-rotate",value:90}],crossOrigin:""}),e.renderImage("https://farm9.staticflickr.com/8873/18598400202_3af67ef38f_z_d.jpg",77,140,75,65,{filters:[{type:"saturate",value:2},{type:"hue-rotate",value:90},{type:"contrast",value:2}],crossOrigin:""}),e.renderImage("https://farm9.staticflickr.com/8873/18598400202_3af67ef38f_z_d.jpg",154,140,75,65,{filters:[{type:"grayscale",value:1}],crossOrigin:""}),e.renderImage("https://farm9.staticflickr.com/8873/18598400202_3af67ef38f_z_d.jpg",0,210,75,65,{filters:[{type:"sepia",value:1}],crossOrigin:""}),e.renderImage("https://farm9.staticflickr.com/8873/18598400202_3af67ef38f_z_d.jpg",77,210,75,65,{filters:[{type:"invert",value:1}],crossOrigin:""}),e.renderImage("https://farm9.staticflickr.com/8873/18598400202_3af67ef38f_z_d.jpg",154,210,75,65,{filters:[{type:"opacity",value:.5}],crossOrigin:""}),e.renderImage("https://farm9.staticflickr.com/8873/18598400202_3af67ef38f_z_d.jpg",0,280,75,65,{filters:[{type:"blur",value:2}],crossOrigin:""})],230,370),p=e=>e.renderResult([e.renderPolyline([{x:5,y:10},{x:45,y:150},{x:45,y:10}],{fillPattern:{width:10,height:10,pattern:()=>e.renderPath([[{x:0,y:5},{x:5,y:0}],[{x:10,y:5},{x:5,y:10}]],{strokeColor:255})}}),e.renderPolyline([{x:50,y:10},{x:90,y:150},{x:90,y:10}],{fillColor:16711680,strokeWidth:0}),e.renderPolyline([{x:95,y:10},{x:135,y:150},{x:135,y:10}],{strokeColor:65280}),e.renderPolyline([{x:140,y:10},{x:180,y:150},{x:180,y:10}],{strokeWidth:5}),e.renderPolyline([{x:185,y:10},{x:225,y:150},{x:225,y:10}],{dashArray:[4]}),e.renderPolyline([{x:195,y:10},{x:215,y:80},{x:215,y:10}],{closed:!0})],230,220),d=e=>e.renderResult([e.renderPolygon([{x:5,y:10},{x:45,y:150},{x:45,y:10}],{fillPattern:{width:10,height:10,pattern:()=>e.renderPath([[{x:0,y:5},{x:5,y:0}],[{x:10,y:5},{x:5,y:10}]],{strokeColor:255})}}),e.renderPolygon([{x:50,y:10},{x:90,y:150},{x:90,y:10}],{fillColor:16711680,strokeWidth:0}),e.renderPolygon([{x:95,y:10},{x:135,y:150},{x:135,y:10}],{strokeColor:65280}),e.renderPolygon([{x:140,y:10},{x:180,y:150},{x:180,y:10}],{strokeWidth:5}),e.renderPolygon([{x:185,y:10},{x:225,y:150},{x:225,y:10}],{dashArray:[4]})],230,190),f=e=>e.renderResult([e.renderPathCommands([{type:"move",to:{x:220,y:10}},{type:"arc",from:{x:220,y:80},to:{x:150,y:10},radius:20},{type:"line",to:{x:150,y:10}},{type:"quadraticCurve",cp:{x:150,y:90},to:{x:110,y:70}},{type:"bezierCurve",cp1:{x:70,y:20},cp2:{x:40,y:80},to:{x:10,y:10}},{type:"ellipseArc",rx:30,ry:20,angle:0,largeArc:!1,sweep:!0,to:{x:50,y:30}}],{strokeColor:65280}),e.renderPathCommands([{type:"move",to:{x:210,y:10}},{type:"arc",from:{x:210,y:80},to:{x:160,y:10},radius:20},{type:"line",to:{x:160,y:10}}],{closed:!0})],230,120),g=e=>{const t=[e.renderCircle(50,50,20),e.renderCircle(50,50,35),e.renderText(0,40,"abc",16711680,30,"monospace"),e.renderGroup([e.renderCircle(50,50,15)],{translate:{x:20,y:20}})];return e.renderResult([e.renderGroup(t,{opacity:.2,translate:{x:10,y:0}}),e.renderRect(120,10,80,80,{clip:()=>e.renderGroup(t,{translate:{x:100,y:0}})}),e.renderCircle(180,150,50,{clip:()=>e.renderGroup(t,{matrix:i.m3.multiply(i.m3.translation(150,150),i.m3.scaling(.7,.7))})}),e.renderPath([[{x:0,y:200},{x:120,y:200},{x:120,y:300},{x:0,y:300},{x:0,y:200}],[{x:55,y:230},{x:90,y:220},{x:90,y:260},{x:50,y:260},{x:55,y:230}]],{clip:()=>e.renderGroup(t,{translate:{x:10,y:200}}),strokeWidth:0}),e.renderPolygon([{x:55,y:230},{x:90,y:220},{x:90,y:260},{x:50,y:260}]),e.renderRect(30,100,80,80,{clip:()=>e.renderGroup([e.renderCircle(90,50,20,{fillPattern:{width:10,height:10,pattern:()=>e.renderPath([[{x:0,y:5},{x:5,y:0}],[{x:10,y:5},{x:5,y:10}]],{strokeColor:255})}}),e.renderCircle(30,50,20)],{translate:{x:10,y:90}})}),e.renderGroup(t,{translate:{x:110,y:200},base:{x:50,y:50},scale:{x:.6,y:.3}})],230,550)},h=e=>e.renderResult([e.renderRay(50,50,30),e.renderRay(80,50,30,{bidirectional:!0}),e.renderGroup([e.renderRay(60,60,30),e.renderGroup([e.renderRay(60,60,30)],{translate:{x:0,y:-20}})],{translate:{x:-20,y:0}})],230,90),{setOffset:m}=o().useContext(a.OffsetXContext);return o().useEffect((()=>{navigator.gpu&&(null==m||m(230))}),[m]),o().createElement("div",null,o().createElement("div",{style:{display:"flex",height:"40px",alignItems:"center",fontSize:"25px",justifyContent:"space-around"}},o().createElement("span",null,i.reactSvgRenderTarget.type),o().createElement("span",null,i.reactCanvasRenderTarget.type),o().createElement("span",null,i.reactWebglRenderTarget.type),navigator.gpu&&o().createElement("span",null,i.reactWebgpuRenderTarget.type)),e(i.reactSvgRenderTarget),e(i.reactCanvasRenderTarget),e(i.reactWebglRenderTarget),navigator.gpu&&e(i.reactWebgpuRenderTarget),o().createElement("br",null),t(i.reactSvgRenderTarget),t(i.reactCanvasRenderTarget),t(i.reactWebglRenderTarget),navigator.gpu&&t(i.reactWebgpuRenderTarget),o().createElement("br",null),n(i.reactSvgRenderTarget),n(i.reactCanvasRenderTarget),n(i.reactWebglRenderTarget),navigator.gpu&&n(i.reactWebgpuRenderTarget),o().createElement("br",null),r(i.reactSvgRenderTarget),r(i.reactCanvasRenderTarget),r(i.reactWebglRenderTarget),navigator.gpu&&r(i.reactWebgpuRenderTarget),o().createElement("br",null),s(i.reactSvgRenderTarget),s(i.reactCanvasRenderTarget),s(i.reactWebglRenderTarget),navigator.gpu&&s(i.reactWebgpuRenderTarget),o().createElement("br",null),c(i.reactSvgRenderTarget),c(i.reactCanvasRenderTarget),c(i.reactWebglRenderTarget),navigator.gpu&&c(i.reactWebgpuRenderTarget),o().createElement("br",null),l(i.reactSvgRenderTarget),l(i.reactCanvasRenderTarget),l(i.reactWebglRenderTarget),navigator.gpu&&l(i.reactWebgpuRenderTarget),o().createElement("br",null),u(i.reactSvgRenderTarget),u(i.reactCanvasRenderTarget),u(i.reactWebglRenderTarget),navigator.gpu&&u(i.reactWebgpuRenderTarget),o().createElement("br",null),p(i.reactSvgRenderTarget),p(i.reactCanvasRenderTarget),p(i.reactWebglRenderTarget),navigator.gpu&&p(i.reactWebgpuRenderTarget),o().createElement("br",null),d(i.reactSvgRenderTarget),d(i.reactCanvasRenderTarget),d(i.reactWebglRenderTarget),navigator.gpu&&d(i.reactWebgpuRenderTarget),o().createElement("br",null),f(i.reactSvgRenderTarget),f(i.reactCanvasRenderTarget),f(i.reactWebglRenderTarget),navigator.gpu&&f(i.reactWebgpuRenderTarget),o().createElement("br",null),g(i.reactSvgRenderTarget),g(i.reactCanvasRenderTarget),g(i.reactWebglRenderTarget),navigator.gpu&&g(i.reactWebgpuRenderTarget),o().createElement("br",null),h(i.reactSvgRenderTarget),h(i.reactCanvasRenderTarget),h(i.reactWebglRenderTarget),navigator.gpu&&h(i.reactWebgpuRenderTarget))}},4339:(e,t,n)=>{"use strict";n.d(t,{default:()=>c});var r=n(8662),o=n(3696),i=n.n(o),a=n(9758),s=n(9299);const c=()=>{const[e,t]=i().useState(s.defaultContents),[n,o]=i().useState(0),{regionAlignmentX:c,regionAlignmentY:l,changeOffsetByRegionAlignment:u,clearRegionAlignments:p}=(0,a.useRegionAlignment)(10),{offset:d,onStart:f,mask:g,startPosition:h,resetDragMove:m}=(0,a.useDragMove)((()=>{p(),0!==d.x||0!==d.y||void 0===(null==h?void 0:h.data)?t((0,r.produce)(e,(e=>{e[n].x+=d.x,e[n].y+=d.y}))):o(h.data)}),{transformOffset:(t,r)=>((null==r?void 0:r.shiftKey)?p():u(t,e[n],e.filter(((e,t)=>t!==n))),t)});return(0,a.useGlobalKeyDown)((e=>{"Escape"===e.key&&m()})),i().createElement(i().Fragment,null,e.map(((e,t)=>i().createElement("div",{key:t,style:{width:`${e.width}px`,height:`${e.height}px`,left:`${e.x+(n===t?d.x:0)}px`,top:`${e.y+(n===t?d.y:0)}px`,position:"absolute",boxSizing:"border-box",background:`url(${e.url})`,backgroundSize:"contain",border:n===t?"1px solid green":void 0},onMouseDown:e=>f({x:e.clientX,y:e.clientY},{data:t})}))),i().createElement(a.AlignmentLine,{type:"x",value:c}),i().createElement(a.AlignmentLine,{type:"y",value:l}),g)}},6286:(e,t,n)=>{"use strict";n.d(t,{richTextData:()=>r});const r=[{type:"h2",blockStart:13.28,blockEnd:13.28,children:[{text:"G"},{text:"e"},{text:"t"},{text:"t"},{text:"i"},{text:"n"},{text:"g"},{text:" "},{text:"u"},{text:"s"},{text:"e"},{text:"d"},{text:" "},{text:"t"},{text:"o"},{text:" "},{text:"a"},{text:"n"},{text:" "},{text:"e"},{text:"n"},{text:"t"},{text:"i"},{text:"r"},{text:"e"},{text:"l"},{text:"y"}]},{type:"p",blockStart:16,blockEnd:16,children:[{text:"d"},{text:"i"},{text:"f"},{text:"f"},{text:"e"},{text:"r"},{text:"e"},{text:"n"},{text:"t"},{text:" "},{text:"c"},{text:"u"},{text:"l"},{text:"t"},{text:"u"},{text:"r"},{text:"e"},{text:" "},{text:"c"},{text:"a"},{text:"n"},{text:" "},{text:"b"},{text:"e"},{text:" "},{text:"c",underline:!0},{text:"h",underline:!0},{text:"a",underline:!0},{text:"l",underline:!0},{text:"l",underline:!0},{text:"e",underline:!0},{text:"n",underline:!0},{text:"g",underline:!0},{text:"i",underline:!0},{text:"n",underline:!0},{text:"g",underline:!0},{text:"."},{text:"abc",type:"link",targetBlank:!0,url:"abc"},{text:" "},{text:" "},{text:"W"},{text:"h"},{text:"i"},{text:"l"},{text:"e"},{text:" "},{text:"i"},{text:"t"},{text:"’"},{text:"s"},{text:" "},{text:"a"},{text:"l"},{text:"s"},{text:"o"},{text:" "},{text:"n"},{text:"i"},{text:"c"},{text:"e"},{text:" "},{text:"t"},{text:"o"},{text:" "},{text:"l"},{text:"e"},{text:"a"},{text:"r"},{text:"n"},{text:" "},{text:"a"},{text:"b"},{text:"o"},{text:"u"},{text:"t"},{text:" "},{text:"c",type:"code",backgroundColor:15921649},{text:"u",type:"code",backgroundColor:15921649},{text:"l",type:"code",backgroundColor:15921649},{text:"t",type:"code",backgroundColor:15921649},{text:"u",type:"code",backgroundColor:15921649},{text:"r",type:"code",backgroundColor:15921649},{text:"e",type:"code",backgroundColor:15921649},{text:"s",type:"code",backgroundColor:15921649},{text:" "},{text:"o"},{text:"n"},{text:"l"},{text:"i"},{text:"n"},{text:"e"},{text:" "},{text:"o"},{text:"r"},{text:" "},{text:"f"},{text:"r"},{text:"o"},{text:"m"},{text:" "},{text:"b"},{text:"o"},{text:"o"},{text:"k"},{text:"s"},{text:","},{text:" "},{text:"d"},{text:"d"},{text:"d"},{text:" "},{text:"c"},{text:"o"},{text:"m"},{text:"e"},{text:"s"},{text:" "},{text:"c",type:"span"},{text:"l",type:"span"},{text:"o",type:"span"},{text:"s",type:"span"},{text:"e",type:"span"},{text:" "},{text:"t"},{text:"o"},{text:" "},{text:"e",bold:!1},{text:"x",bold:!1},{text:"p",bold:!1},{text:"e",bold:!1},{text:"r",bold:!1},{text:"i",bold:!1},{text:"e",bold:!1},{text:"n",bold:!1},{text:"c",bold:!1},{text:"i",bold:!1},{text:"n",bold:!1},{text:"g",bold:!1},{text:"a",bold:!1},{text:" "},{text:"c"},{text:"u"},{text:"l"},{text:"t"},{text:"u"},{text:"r"},{text:"a"},{text:"l"},{text:" "},{text:"d"},{text:"i"},{text:"v"},{text:"e"},{text:"r"},{text:"s"},{text:"i"},{text:"t"},{text:"y"},{text:" "},{text:"i"},{text:"n"},{text:" "},{text:"p"},{text:"e"},{text:"r"},{text:"s"},{text:"o"},{text:"n"},{text:"."},{text:" "},{text:"Y"},{text:"o"},{text:"u"},{text:"A",type:"circle"},{text:" "},{text:"B",type:"stack",bottomText:"C"},{text:" "},{text:"l"},{text:"e"},{text:"a"},{text:"r"},{text:"n"},{text:"a"},{text:"a"},{text:"啊"},{text:"啊"},{text:" "},{text:"t"},{text:"o"},{text:" "},{text:"a"},{text:"p",bold:!0,italic:!0,underline:!0,passThrough:!0},{text:"p",bold:!0,italic:!0,underline:!0,passThrough:!0},{text:"r",bold:!0,italic:!0,underline:!0,passThrough:!0},{text:"e",bold:!0,italic:!0,underline:!0,passThrough:!0},{text:"c",bold:!0,italic:!0,underline:!0,passThrough:!0},{text:"i",bold:!0,italic:!0,underline:!0,passThrough:!0},{text:"a"},{text:"t"},{text:"e"},{text:" "},{text:"e"},{text:"a"},{text:"c"},{text:"h"},{text:" "},{text:"a"},{text:"n"},{text:"d"},{text:" "},{text:"e"},{text:"v"},{text:"e"},{text:"r"},{text:"y"},{text:" "},{text:"s"},{text:"i"},{text:"n"},{text:"g"},{text:"l"},{text:"e"},{text:" "},{text:"o"},{text:"n"},{text:"e"},{text:" "},{text:"o"},{text:"f"},{text:" "},{text:"t"},{text:"h"},{text:"e"},{text:" "},{text:"d"},{text:"i"},{text:"f"},{text:"f"},{text:"e"},{text:"r"},{text:"e"},{text:"n"},{text:"c"},{text:"e"},{text:"s"},{text:" "},{text:"x"},{text:"2",type:"sub"},{text:"2",type:"sup"},{text:" "},{text:"2"},{text:" "},{text:"w"},{text:"h"},{text:"i"},{text:"l"},{text:"e"},{text:" "},{text:"y"},{text:"o"},{text:"u"},{text:" "},{text:"b"},{text:"e"},{text:"c"},{text:"o"},{text:"m"},{text:"e"},{text:" "},{text:"m"},{text:"o"},{text:"r"},{text:"e"},{text:" "},{text:"c"},{text:"u"},{text:"l"},{text:"t"},{text:"u"},{text:"r"},{text:"a"},{text:"l"},{text:"l"},{text:"y"},{text:" "},{text:"f"},{text:"l"},{text:"u"},{text:"i"},{text:"d"},{text:"."},{text:"<"},{text:"a"},{text:">"},{text:" "},{text:"@aa_2",color:16777215,backgroundColor:255},{text:" "},{text:" "},{text:"s"},{text:"d"},{text:"a"},{text:"d"},{text:" "},{text:"a"},{text:"f"},{text:"f"},{text:"s"},{text:" "},{text:"f"},{text:"d"},{text:"f"},{text:"d"},{text:"s"},{text:"f"},{text:"@aa_1",color:16777215,backgroundColor:255},{text:" "},{text:"@aa_1",color:16777215,backgroundColor:255},{text:" "},{text:"@aa_1",color:16777215,backgroundColor:255},{text:" "}]},{type:"ul",blockStart:16,blockEnd:16,children:[{text:"a"},{text:"a"}],inlineStart:40},{type:"ul",blockStart:16,blockEnd:16,children:[{text:"b"},{text:"b"}],inlineStart:40},{blockStart:.5,blockEnd:.5,void:!0,type:"hr",children:[]},{type:"ol",blockStart:16,blockEnd:16,children:[{text:"a"},{text:"a"},{text:"x"}],inlineStart:40,listStyleType:"decimal"},{type:"ol",blockStart:16,blockEnd:16,children:[{text:"https://stackoverflow.com/",type:"link",underline:!0,color:5577354,targetBlank:!0,url:"https://stackoverflow.com/"}],inlineStart:40,listStyleType:"decimal"},{type:"p",blockStart:16,blockEnd:16,children:[{text:"c",type:"code",backgroundColor:15921649},{text:"o",type:"code",backgroundColor:15921649},{text:"d",type:"code",backgroundColor:15921649},{text:"e",type:"code",backgroundColor:15921649}],fontSize:16},{type:"p",blockStart:16,blockEnd:16,children:[{url:"https://farm9.staticflickr.com/8873/18598400202_3af67ef38f_z_d.jpg",width:263.0291970802921,height:180.17499999999998,text:" "},{kind:"image",url:"https://farm9.staticflickr.com/8873/18598400202_3af67ef38f_z_d.jpg",width:192.27007299270085,height:131.705},{url:"https://farm9.staticflickr.com/8873/18598400202_3af67ef38f_z_d.jpg",width:195.8759124087592,height:134.17499999999998,text:" "},{url:"tyejtey",text:"tyejtey",type:"link",targetBlank:!0},{url:"https://farm9.staticflickr.com/8873/18598400202_3af67ef38f_z_d.jpg",width:195.8759124087592,height:134.17499999999998,text:" "}],fontSize:16},{type:"p",blockStart:16,blockEnd:16,children:[{text:"a",type:"mark",backgroundColor:16776960},{text:"a",type:"mark",backgroundColor:16776960},{text:"s",type:"mark",backgroundColor:16776960},{text:"a",type:"mark",backgroundColor:16776960},{text:" ",type:"mark",backgroundColor:16776960}],fontSize:16}]},7310:(e,t,n)=>{"use strict";n.d(t,{useAt:()=>p});var r=n(3696),o=n.n(r),i=Object.defineProperty,a=Object.getOwnPropertySymbols,s=Object.prototype.hasOwnProperty,c=Object.prototype.propertyIsEnumerable,l=(e,t,n)=>t in e?i(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,u=(e,t)=>{for(var n in t||(t={}))s.call(t,n)&&l(e,n,t[n]);if(a)for(var n of a(t))c.call(t,n)&&l(e,n,t[n]);return e};const p=({cursor:e,cursorHeight:t,inputText:n})=>{const[r,i]=o().useState(""),[a,s]=o().useState(0),c={color:16777215,backgroundColor:255};return{processInput(e){if(r){if(1===e.key.length&&e.key>="a"&&e.key<="z")return i((t=>t+e.key)),e.preventDefault(),!0;if("Enter"===e.key&&r){const e=u({text:r+"_"+a},c);return n([e," "]),i(""),!0}if("Escape"===e.key)return i(""),e.preventDefault(),!0;if("ArrowDown"===e.key)return s((a+1)%5),e.preventDefault(),!0;if("ArrowUp"===e.key)return s((a+4)%5),e.preventDefault(),!0;if("Backspace"===e.key)return r.length>1?i((e=>e.slice(0,e.length-1))):i(""),e.preventDefault(),!0}return"@"===e.key&&(i("@"),e.preventDefault(),!0)},ui:r?o().createElement("div",{style:{position:"absolute",left:e.x+"px",top:e.y+t+"px",background:"white",width:"100px",border:"1px solid black"}},o().createElement("div",null,r),new Array(5).fill(0).map(((e,t)=>o().createElement("div",{key:t,style:{background:a===t?"#ccc":void 0},onMouseDown:e=>{e.preventDefault();const o=u({text:r+"_"+t},c);n([o," "]),i("")}},r+"_"+t)))):void 0}}},5011:(e,t,n)=>{"use strict";n.d(t,{h1:()=>r,h2:()=>o,h3:()=>i,h4:()=>a,h5:()=>s,h6:()=>c,hr:()=>d,ol:()=>p,p:()=>l,ul:()=>u});const r={blockStart:.67,blockEnd:.67},o={blockStart:.83,blockEnd:.83},i={blockStart:1.17,blockEnd:1.17},a={blockStart:1,blockEnd:1},s={blockStart:1,blockEnd:1},c={blockStart:2.33,blockEnd:2.33},l={blockStart:1,blockEnd:1},u={blockStart:1,blockEnd:1,inlineStart:40},p={blockStart:1,blockEnd:1,inlineStart:40},d={blockStart:.5,blockEnd:.5,void:!0}},3685:(e,t,n)=>{"use strict";n.d(t,{circle:()=>h,useCircle:()=>m});var r=n(3696),o=n.n(r),i=n(9758),a=Object.defineProperty,s=Object.defineProperties,c=Object.getOwnPropertyDescriptors,l=Object.getOwnPropertySymbols,u=Object.prototype.hasOwnProperty,p=Object.prototype.propertyIsEnumerable,d=(e,t,n)=>t in e?a(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,f=(e,t)=>{for(var n in t||(t={}))u.call(t,n)&&d(e,n,t[n]);if(l)for(var n of l(t))p.call(t,n)&&d(e,n,t[n]);return e};function g(e){return(0,i.isHtmlText)(e)&&"circle"===e.type}const h={render(e){var t,n,r;if(g(e)){const a=(0,i.renderHtmlTextStyle)(e),l=1.2*(null!=(t=e.fontSize)?t:i.defaultFontSize);return o().createElement("span",{style:(n=f({},a),r={borderWidth:"1px",borderStyle:"solid",borderColor:a.color,borderRadius:l/2+"px",width:`${l}px`,height:`${l}px`,display:"inline-flex",justifyContent:"center"},s(n,c(r)))},e.text)}}},m=({inputText:e,currentContent:t,updateCurrentContent:n})=>{const[r,a]=o().useState(""),s={"insert circle":o().createElement(i.StringEditor,{value:r,setValue:t=>{t&&(e([{type:"circle",text:t}," "]),a(t),setTimeout((()=>{a("")}),0))}})};return t&&g(t)&&(s["circle text"]=o().createElement(i.StringEditor,{value:t.text,setValue:e=>n((t=>{g(t)&&(t.text=e)}))})),{propertyPanel:s}}},726:(e,t,n)=>{"use strict";n.d(t,{image:()=>s,useImage:()=>c});var r=n(3696),o=n.n(r),i=n(9758);function a(e){return"image"===e.kind}const s={render(e,t){if(a(e))return o().createElement("img",{style:{width:`${e.width+t.width}px`,height:`${e.height+t.height}px`},src:e.url})}},c=({inputText:e,currentContent:t,currentContentLayout:n,updateCurrentContent:r,setResizeOffset:s})=>{const[c,l]=o().useState(""),{offset:u,onStart:p,mask:d,resetDragResize:f}=(0,i.useDragResize)((()=>{r((e=>{a(e)&&(e.width+=u.width,e.height+=u.height)}))}),{keepRatio:t&&a(t)?t.width/t.height:void 0});(0,i.useGlobalKeyDown)((e=>{"Escape"===e.key&&f()})),o().useEffect((()=>{s(u)}),[u.x,u.y]);const g={"insert image":o().createElement(i.StringEditor,{value:c,setValue:t=>{t&&((0,i.getImageFromCache)(t,{callback(n){const r=Math.min(n.width,200),o=Math.round(r/n.width*n.height);e([{kind:"image",url:t,width:r,height:o}," "])}}),l(t),setTimeout((()=>{l("")}),0))}})};return t&&a(t)&&(g["image url"]=o().createElement(i.StringEditor,{value:t.url,setValue:e=>r((t=>{a(t)&&(t.url=e)}))}),g["image width"]=o().createElement(i.NumberEditor,{value:t.width,setValue:e=>r((t=>{a(t)&&(t.width=e)}))}),g["image height"]=o().createElement(i.NumberEditor,{value:t.height,setValue:e=>r((t=>{a(t)&&(t.height=e)}))})),{propertyPanel:g,ui:t&&a(t)&&n?o().createElement("div",{style:{width:`${t.width+u.width}px`,height:`${t.height+u.height}px`,left:`${n.x+u.x}px`,top:`${n.y+u.y}px`,border:"1px solid green",boxSizing:"border-box",position:"absolute"}},o().createElement(i.ResizeBar,{directions:["right-bottom"],onMouseDown:p}),d):void 0}}},4430:(e,t,n)=>{"use strict";n.d(t,{code:()=>o,mark:()=>i,span:()=>r,sub:()=>a,sup:()=>s});const r={},o={backgroundColor:15921649},i={},a={},s={}},2693:(e,t,n)=>{"use strict";n.d(t,{link:()=>s,useLink:()=>c});var r=n(3696),o=n.n(r),i=n(9758);function a(e){return(0,i.isHtmlText)(e)&&"link"===e.type}const s={render(e){if(a(e))return o().createElement("a",{style:(0,i.renderHtmlTextStyle)(e),target:e.targetBlank?"_blank":"",href:e.url},e.text)}},c=({inputText:e,currentContent:t,updateCurrentContent:n})=>{var r;const[s,c]=o().useState(""),l={"insert link":o().createElement(i.StringEditor,{value:s,setValue:t=>{t&&(e([{type:"link",text:t,targetBlank:!0,url:t}," "]),c(t),setTimeout((()=>{c("")}),0))}})};return t&&a(t)&&(l["link text"]=o().createElement(i.StringEditor,{value:t.text,setValue:e=>n((t=>{a(t)&&(t.text=e)}))}),l["link url"]=o().createElement(i.StringEditor,{value:t.url,setValue:e=>n((t=>{a(t)&&(t.url=e)}))}),l["link target blank"]=o().createElement(i.BooleanEditor,{value:null!=(r=t.targetBlank)&&r,setValue:e=>n((t=>{a(t)&&(t.targetBlank=!!e||void 0)}))})),{propertyPanel:l}}},8749:(e,t,n)=>{"use strict";n.d(t,{stack:()=>h,useStack:()=>m});var r=n(3696),o=n.n(r),i=n(9758),a=Object.defineProperty,s=Object.defineProperties,c=Object.getOwnPropertyDescriptors,l=Object.getOwnPropertySymbols,u=Object.prototype.hasOwnProperty,p=Object.prototype.propertyIsEnumerable,d=(e,t,n)=>t in e?a(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,f=(e,t)=>{for(var n in t||(t={}))u.call(t,n)&&d(e,n,t[n]);if(l)for(var n of l(t))p.call(t,n)&&d(e,n,t[n]);return e};function g(e){return(0,i.isHtmlText)(e)&&"stack"===e.type}const h={render(e){if(g(e)){const r=(0,i.renderHtmlTextStyle)(e);return o().createElement("span",{style:(t=f({},r),n={display:"inline-flex",flexDirection:"column",verticalAlign:"middle"},s(t,c(n)))},o().createElement("span",{style:{borderBottomWidth:"1px",borderBottomStyle:"solid",borderBottomColor:r.color}},e.text),o().createElement("span",null,e.bottomText))}var t,n}},m=({inputText:e,currentContent:t,updateCurrentContent:n})=>{const[r,a]=o().useState(""),s={"insert stack":o().createElement(i.StringEditor,{value:r,setValue:t=>{if(t){let n=t,r=t;const o=t.indexOf("/");o>0&&o{a("")}),0)}}})};return t&&g(t)&&(s["stack top"]=o().createElement(i.StringEditor,{value:t.text,setValue:e=>n((t=>{g(t)&&(t.text=e)}))}),s["stack bottom"]=o().createElement(i.StringEditor,{value:t.bottomText,setValue:e=>n((t=>{g(t)&&(t.bottomText=e)}))})),{propertyPanel:s}}},395:(e,t,n)=>{"use strict";n.d(t,{backgroundColor:()=>f,bold:()=>c,color:()=>d,fontFamily:()=>s,fontSize:()=>a,italic:()=>l,passThrough:()=>p,underline:()=>u});var r=n(3696),o=n.n(r),i=n(9758);const a=(e,t,n)=>{var r,a;return o().createElement(i.NumberEditor,{value:null!=(a=null!=(r=null==e?void 0:e.fontSize)?r:null==t?void 0:t.fontSize)?a:i.defaultFontSize,setValue:e=>n((t=>t.fontSize=e)),style:{width:"100px"}})},s=(e,t,n)=>{var r,a;return o().createElement(i.StringEditor,{value:null!=(a=null!=(r=null==e?void 0:e.fontFamily)?r:null==t?void 0:t.fontFamily)?a:i.defaultFontFamily,setValue:e=>n((t=>t.fontFamily=e)),style:{width:"100px"}})},c=(e,t,n)=>{var r;return o().createElement(i.BooleanEditor,{value:!0===(null!=(r=null==e?void 0:e.bold)?r:null==t?void 0:t.bold),setValue:e=>n((t=>t.bold=!!e||void 0))})},l=(e,t,n)=>{var r;return o().createElement(i.BooleanEditor,{value:!0===(null!=(r=null==e?void 0:e.italic)?r:null==t?void 0:t.italic),setValue:e=>n((t=>t.italic=!!e||void 0))})},u=(e,t,n)=>{var r;return o().createElement(i.BooleanEditor,{value:!0===(null!=(r=null==e?void 0:e.underline)?r:null==t?void 0:t.underline),setValue:e=>n((t=>t.underline=!!e||void 0))})},p=(e,t,n)=>{var r;return o().createElement(i.BooleanEditor,{value:!0===(null!=(r=null==e?void 0:e.passThrough)?r:null==t?void 0:t.passThrough),setValue:e=>n((t=>t.passThrough=!!e||void 0))})},d=(e,t,n)=>{var r,a;return o().createElement(i.NumberEditor,{type:"color",value:null!=(a=null!=(r=null==e?void 0:e.color)?r:null==t?void 0:t.color)?a:0,setValue:e=>n((t=>t.color=e||void 0))})},f=(e,t,n)=>{var r,a;return o().createElement(i.NumberEditor,{type:"color",value:null!=(a=null!=(r=null==e?void 0:e.backgroundColor)?r:null==t?void 0:t.backgroundColor)?a:16777215,setValue:e=>n((t=>t.backgroundColor=e||void 0))})}},8214:(e,t,n)=>{"use strict";n.d(t,{RichTextEditor:()=>s});var r=n(3696),o=n.n(r),i=n(9758),a=n(8662);const s=o().forwardRef(((e,t)=>{var n,r,s,c,l;const{state:u,setState:p,undo:d,redo:f,applyPatchFromOtherOperators:g}=(0,i.usePatchBasedUndoRedo)(e.initialState,e.operator,{onApplyPatchesFromSelf:e.onApplyPatchesFromSelf}),[h,m]=o().useState({width:0,height:0}),{renderEditor:y,currentContent:v,currentBlock:x,currentContentLayout:b,inputText:C,layoutResult:E,cursor:P,inputContent:w,location:k,scrollY:_,updateSelection:S,updateTextInline:R,updateParagraph:T,updateCurrentContent:A}=(0,i.useHtmlEditor)({state:u,setState:p,width:e.width,height:e.height,readOnly:e.readOnly,processInput(e){for(const t of L)if(t(e))return!0;return!(!(0,i.metaKeyIfMacElseCtrlKey)(e)||"z"!==e.key||(e.shiftKey?f(e):d(e),0))},onLocationChanged:e.onSendLocation,autoHeight:e.autoHeight,plugin:e.plugin,resizeOffset:h,keepSelectionOnBlur:!0}),L=[],M=[],I={};if(null==(n=e.plugin)?void 0:n.hooks){const t={cursor:P,cursorHeight:P.height,inputText:C,inputContent:w,currentContent:v,currentContentLayout:b,updateCurrentContent:A,setResizeOffset:m};e.plugin.hooks.forEach(((e,n)=>{const{processInput:r,ui:i,propertyPanel:a}=e(t);r&&L.push(r),i&&M.push(o().cloneElement(i,{key:n})),a&&Object.assign(I,a)}))}const[O,D]=o().useState([]);o().useImperativeHandle(t,(()=>({handlePatchesEvent(e){try{g(e.patches,e.reversePatches,e.operator)}catch(e){console.error(e)}},handleLocationEvent(e){D((0,a.produce)(O,(t=>{var n,r;const o=O.findIndex((t=>t.operator===e.operator));o>=0?e.location&&(null==(r=null==(n=u[e.location[0]])?void 0:n.children)?void 0:r[e.location[1]])?t[o].location=e.location:t.splice(o,1):e.location&&t.push({location:e.location,operator:e.operator})})))}})),[g]);const B=[];if(null==(r=null==E?void 0:E.cells)||r.forEach(((e,t)=>{var n;const r=u[t],a=null!=(n=null==r?void 0:r.fontFamily)?n:i.defaultFontFamily;e.forEach((({x:e,y:n,height:r},i)=>{const s=O.filter((e=>e.location[0]===t&&e.location[1]===i));s.length>0&&B.push(o().createElement("div",{style:{position:"absolute",left:e+"px",top:n+_+"px",width:"2px",height:r+"px",backgroundColor:"red"}}),o().createElement("span",{style:{position:"absolute",left:e+"px",top:n+_+r+"px",fontSize:"12px",fontFamily:a,color:"red"}},s.map((e=>e.operator)).join(",")))}))})),(null==(s=e.plugin)?void 0:s.styles)&&v&&(0,i.isHtmlText)(v))for(const t in e.plugin.styles)I[t]=e.plugin.styles[t](v,x,S);return(null==(c=e.plugin)?void 0:c.textInlines)&&(I.textInlines=o().createElement("div",null,(0,i.getKeys)(e.plugin.textInlines).map((e=>o().createElement(i.Button,{key:e,style:{fontWeight:v&&(0,i.isHtmlText)(v)&&v.type===e?"bold":void 0},onClick:()=>R(e)},e))))),(null==(l=e.plugin)?void 0:l.blocks)&&(I.block=o().createElement("div",null,(0,i.getKeys)(e.plugin.blocks).map((e=>{var t;return o().createElement(i.Button,{key:e,style:{fontWeight:(null==(t=u[k[0]])?void 0:t.type)===e?"bold":void 0},onClick:()=>T(e)},e)})))),o().createElement("div",{style:{position:"relative",margin:"10px"}},o().createElement("div",{style:{display:"flex"}},y(o().createElement(o().Fragment,null,B)),o().createElement(i.ObjectEditor,{inline:!0,properties:I})),M)}))},94:(e,t,n)=>{"use strict";n.d(t,{default:()=>a});var r=n(3696),o=n.n(r),i=n(9758);const a=()=>{const[e,t]=o().useState(0),[n,r]=o().useState(0);return o().createElement("div",{style:{width:"300px",height:"300px",overflow:"hidden",position:"absolute",display:"flex",alignItems:"center",justifyContent:"center"}},o().createElement("div",{style:{width:"800px",height:"800px",position:"absolute",transform:`translate(${e}px, ${n}px)`,background:"radial-gradient(50% 50% at 50% 50%, red 0%, white 100%)"}}),o().createElement(i.Scrollbar,{value:e,type:"horizontal",containerSize:300,contentSize:800,onChange:t}),o().createElement(i.Scrollbar,{value:n,type:"vertical",containerSize:300,contentSize:800,onChange:r}))}},8751:(e,t,n)=>{"use strict";n.d(t,{default:()=>a});var r=n(3696),o=n.n(r),i=n(9758);const a=()=>{const{isSelected:e,addSelection:t,filterSelection:n,executeOperation:r,selectBeforeOperate:a,message:s,onSelectBeforeOperateKeyDown:c}=(0,i.useSelectBeforeOperate)({},((e,t)=>(alert(t.map((([e])=>e)).join(",")),!0)));(0,i.useGlobalKeyDown)((e=>{c(e)}));const l=(e,t)=>{const{result:o,needSelect:i}=n(t,e);i?a({count:e,selectable:t},"alert"):r("alert",o)};return o().createElement("div",null,o().createElement("button",{onClick:()=>l()},"select count ",">"," 0"),o().createElement("button",{onClick:()=>l(3)},"select count = 3"),o().createElement("button",{onClick:()=>l(void 0,(([e])=>e%2==1))},"select count ",">"," 0 && i % 2 === 1"),o().createElement("button",{onClick:()=>l(3,(([e])=>e%2==1))},"select count = 3 && i % 2 === 1"),new Array(10).fill(1).map(((n,r)=>o().createElement("button",{key:r,style:{backgroundColor:e([r])?"green":void 0,width:"50px",height:"50px"},onClick:()=>t([r])},r))),s)}},9967:(e,t,n)=>{"use strict";n.d(t,{default:()=>a});var r=n(3696),o=n.n(r),i=n(9758);const a=()=>{const{isSelected:e,addSelection:t,onSelectedKeyDown:n}=(0,i.useSelected)({maxCount:3});return(0,i.useGlobalKeyDown)((e=>{n(e)})),o().createElement("div",null,new Array(10).fill(1).map(((n,r)=>o().createElement("button",{key:r,style:{backgroundColor:e([r])?"green":void 0,width:"50px",height:"50px"},onClick:()=>t([[r]])},r))))}},5052:(e,t,n)=>{"use strict";n.d(t,{OffsetXContext:()=>b});var r=n(7470),o=n(3696),i=n.n(o),a=(n(9532),n(831),n(8941)),s=n(250),c=n(5371),l=n(9758),u=n(6708),p=n(9277),d=n(9456),f=n(7511),g=n(3714),h=n(577),m=n(84),y=n(6523);const v=[{path:"whiteboard",name:"whiteboard",component:u.WhiteBoard},{path:"index",name:"combination 1",component:c.App},{path:"combination2",name:"combination 2",component:p.Combination2},{path:"combination3",name:"combination 3",component:d.Combination3},{path:"combination4",name:"combination 4",component:f.Combination4},{path:"combination5",name:"combination 5",component:g.Combination5},{path:"combination6",name:"combination 6",component:h.Combination6},{path:"combination7",name:"combination 7",component:m.Combination7},{path:"combination8",name:"combination 8",component:y.Combination8}];function x(){const[,e]=(0,a.useLocation)(i()),[t,n]=i().useState(0),{onStart:r,offset:o,mask:c}=(0,l.useDragMove)((()=>{n((e=>e+o.x))}));if(!e)return i().createElement("ul",{style:{margin:"20px 50px"}},v.map((e=>i().createElement("li",{style:{cursor:"pointer"},key:e.path,onClick:()=>(0,a.navigateTo)(location.pathname+"?p="+e.path)},e.name))),s.stories.map((e=>i().createElement("li",{style:{cursor:"pointer"},key:e.path,onClick:()=>(0,a.navigateTo)(location.pathname+"?p="+e.path)},e.name," ",e.path))));const u=e.substring(3),p=v.find((e=>e.path===u));if(p)return i().createElement(p.component,null);for(const e of s.stories)if(u===e.path)return i().createElement("div",{style:{display:"flex",padding:"20px",height:`calc(${window.innerHeight}px - 40px)`,overflowY:"auto"}},i().createElement("div",{style:{width:`calc(50% + ${t+o.x}px)`}},i().createElement(b.Provider,{value:{offset:t,setOffset:n}},i().createElement(e.Component,null))),i().createElement("div",{style:{width:"5px",cursor:"ew-resize",zIndex:1},onMouseDown:e=>r({x:e.clientX,y:e.clientY})}),i().createElement("div",{style:{width:`calc(50% - 5px - ${t+o.x}px)`}},i().createElement(C,{code:e.code})),c);return null}const b=i().createContext({offset:0});function C(e){const t=i().useRef(null);return i().useEffect((()=>{t.current&&Prism.highlightElement(t.current)}),[e.code,t.current]),i().createElement("pre",{className:"line-numbers"},i().createElement("code",{ref:t,className:"language-tsx"},e.code))}const E=document.querySelector("#container");E&&(0,r.createRoot)(E).render(i().createElement(x,null))},9299:(e,t,n)=>{"use strict";n.d(t,{defaultContents:()=>r});const r=[{x:500,y:100,width:100,height:100,url:"https://interactive-examples.mdn.mozilla.net/media/cc0-images/grapefruit-slice-332-332.jpg"},{x:20,y:200,width:300,height:300,url:"https://interactive-examples.mdn.mozilla.net/media/cc0-images/grapefruit-slice-332-332.jpg"},{x:200,y:20,width:200,height:200,url:"https://interactive-examples.mdn.mozilla.net/media/cc0-images/grapefruit-slice-332-332.jpg"}]},5503:(e,t,n)=>{"use strict";n.d(t,{default:()=>s});var r=n(8662),o=n(3696),i=n.n(o),a=n(9758);const s=()=>{const[e,t]=i().useState([]),{text:n,onClick:o,onMove:s,input:c,reset:l}=(0,a.useTextClickCreate)(!0,(n=>{t((0,r.produce)(e,(e=>{e.push(n)})))}));return(0,a.useGlobalKeyDown)((e=>{"Escape"===e.key&&l()})),i().createElement("div",{style:{height:"100%"}},i().createElement("svg",{viewBox:"0 0 800 600",width:800,height:600,xmlns:"http://www.w3.org/2000/svg",fill:"none",style:{position:"absolute",left:0,top:0},onClick:e=>o({x:e.clientX,y:e.clientY}),onMouseMove:e=>s({x:e.clientX,y:e.clientY})},[...e,n].map(((e,t)=>e&&i().createElement("text",{key:t,x:e.x,y:e.y,style:{fill:(0,a.getColorString)(e.color),fontSize:`${e.fontSize}px`,fontFamily:e.fontFamily}},e.text)))),c)}},8119:(e,t,n)=>{"use strict";n.d(t,{default:()=>a});var r=n(3696),o=n.n(r),i=n(9758);const a=()=>{const{state:e,setState:t,undo:n,redo:r}=(0,i.useUndoRedo)({count:0});return(0,i.useGlobalKeyDown)((e=>{"KeyZ"===e.code&&(0,i.metaKeyIfMacElseCtrlKey)(e)&&(e.shiftKey?r(e):n(e))})),o().createElement("button",{onClick:()=>t((e=>{e.count++})),style:{width:"200px",height:"100px"}},e.count)}},2929:(e,t,n)=>{"use strict";n.d(t,{default:()=>f});var r=n(3696),o=n(670),i=n(8662),a=n(9758),s=Object.defineProperty,c=Object.getOwnPropertySymbols,l=Object.prototype.hasOwnProperty,u=Object.prototype.propertyIsEnumerable,p=(e,t,n)=>t in e?s(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,d=(e,t)=>{for(var n in t||(t={}))l.call(t,n)&&p(e,n,t[n]);if(c)for(var n of c(t))u.call(t,n)&&p(e,n,t[n]);return e};const f=()=>{const e=r.useRef(null),t=r.useRef(),n=(0,a.useWindowSize)(),o=n.width/2,s=n.height,[c,l]=r.useState(),u=[0,-90,90],p=-100,{state:d,setState:f,undo:h,redo:m}=(0,a.useUndoRedo)(g(function(){const e=[];for(let t=-10;t<=10;t++){const n=5*t,r=[];for(let e=-10;e<=10;e++)r.push([n,5*e,0]);e.push(r)}return e}(),3)),[y,v]=r.useState(),[x,b]=r.useState(),[C,E]=r.useState(5);return r.useEffect((()=>{e.current&&!t.current&&(t.current=(0,a.createWebgl3DRenderer)(e.current))}),[e.current]),(0,a.useGlobalKeyDown)((e=>{(0,a.metaKeyIfMacElseCtrlKey)(e)?"KeyZ"===e.code&&(e.shiftKey?m(e):h(e)):"Escape"===e.key&&(b(void 0),v(void 0))})),r.useEffect((()=>{const e=[];var n,r,o;c&&e.push({geometry:{type:"sphere",radius:1},color:[1,0,0,1],position:c}),n=[...d,...e],null==(o=null==(r=t.current)?void 0:r.render)||o.call(r,n,{eye:u,up:[0,1,0],target:[0,0,0],fov:(0,a.angleToRadian)(60),near:.1,far:1e3},{position:[1e3,-1e3,1e3],color:[1,1,1,1],specular:[1,1,1,1],shininess:50,specularFactor:1},[1,1,1,1])}),[c,d]),r.createElement("div",{style:{position:"absolute",inset:"0px"}},r.createElement("canvas",{ref:e,width:o,height:s,onMouseMove:e=>{var n,r;l(x||null==(r=null==(n=t.current)?void 0:n.pickPoint)?void 0:r.call(n,e.clientX,e.clientY,u,p,(e=>"vertices"===e.geometry.type)))},onMouseDown:e=>{var n,r;if(!x)return;const o=d[0].geometry;if("vertices"===o.type){const a=null==(r=null==(n=t.current)?void 0:n.pickPoint)?void 0:r.call(n,e.clientX,e.clientY,u,p,(e=>"vertices"===e.geometry.type));if(a){const e=Math.round(a[0]/5)+10;if(e>=0&&e=0&&t{const r=n[e][t];if("set"===x)r[2]=C;else if("up"===x)r[2]+=5;else{if(r[2]-5g(n,3)))}}}}},onContextMenu:e=>{e.preventDefault();const t={x:e.clientX,y:e.clientY};v(y?void 0:r.createElement(a.Menu,{items:[{title:"up",onClick(){b("up"),v(void 0)}},{title:"down",onClick(){b("down"),v(void 0)}},{title:r.createElement(r.Fragment,null,r.createElement(a.NumberEditor,{value:C,style:{width:"50px"},setValue:E}),r.createElement(a.Button,{onClick:()=>{b("set"),v(void 0)}},"set")),height:41}],y:t.y,height:s,style:{left:t.x+"px"}}))}}),y)};function g(e,t){const n=(0,a.getNurbsSurfaceVertices)(e,t),r=[{geometry:d({type:"vertices"},n),color:[0,1,0,1]}],i=(0,a.getDefaultNurbsKnots)(e.length,t);for(let n=0;n[e[0],e[1],e[2]+.1])).flat()}});const c=e.map((e=>e[n])),l=o.geom.NurbsCurve.byKnotsControlPointsWeights(t,i,c);r.push({color:[0,0,1,1],geometry:{type:"lines",points:l.tessellate().map((e=>[e[0],e[1],e[2]+.1])).flat()}})}return r}},8337:(e,t,n)=>{"use strict";n.d(t,{default:()=>p});var r=n(3696),o=n(9758),i=Object.defineProperty,a=Object.getOwnPropertySymbols,s=Object.prototype.hasOwnProperty,c=Object.prototype.propertyIsEnumerable,l=(e,t,n)=>t in e?i(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,u=(e,t)=>{for(var n in t||(t={}))s.call(t,n)&&l(e,n,t[n]);if(a)for(var n of a(t))c.call(t,n)&&l(e,n,t[n]);return e};const p=()=>{const e=r.useRef(null),t=r.useRef(),{x:n,y:i,setX:a,setY:s,ref:c}=(0,o.useWheelScroll)(),{scale:l,setScale:p,ref:d}=(0,o.useWheelZoom)(),[f,g]=r.useState({x:0,y:0}),{offset:h,onStart:m,mask:y,resetDragMove:v}=(0,o.useDragMove)((()=>{g((e=>({x:e.x+h.x,y:e.y+h.y})))}));(0,o.useGlobalKeyDown)((e=>{"Escape"===e.key?v():"Digit0"===e.code&&!e.shiftKey&&(0,o.metaKeyIfMacElseCtrlKey)(e)&&(p(1),a(0),s(0),g({x:0,y:0}),e.preventDefault())}));const x=(0,o.useWindowSize)(),b=x.width/2,C=x.height,E=h.x+f.x,P=h.y+f.y,[w,k]=r.useState(),_=r.useRef([...(0,o.getAxesGraphics)(),{geometry:{type:"lines",points:(0,o.getDashedLine)([0,0,0],[100,100,100],6).flat()},color:[0,0,0,1]},{geometry:{type:"sphere",radius:100},color:[1,0,0,1],position:[0,250,0]},{geometry:{type:"cube",size:150},color:[0,1,0,1],position:[250,0,0]},{geometry:{type:"cylinder",radius:100,height:200},color:[0,0,1,1],position:[-250,0,0]},{geometry:{type:"cone",topRadius:0,bottomRadius:100,height:200},color:[1,0,1,1],position:[0,-250,0]},{geometry:{type:"triangles",points:[-50,-50,50,50,50,50,-50,50,50]},color:[.5,0,.5,1],position:[250,250,250]},{geometry:u({type:"vertices"},(0,o.getNurbsSurfaceVertices)([[[0,0,-20],[20,0,0],[40,0,0],[60,0,0],[80,0,0],[100,0,0]],[[0,-20,0],[20,-20,10],[40,-20,20],[60,-20,0],[80,-20,0],[100,-20,0]],[[0,-40,0],[20,-40,10],[40,-40,20],[60,-40,0],[80,-40,-4],[100,-40,-24]],[[0,-50,0],[20,-60,0],[40,-60,-46],[60,-60,0],[80,-60,0],[100,-50,0]],[[0,-80,0],[20,-80,0],[40,-80,0],[60,-80,8],[80,-80,-40],[100,-80,0]],[[0,-100,24],[20,-100,0],[40,-100,40],[60,-100,0],[100,-100,-20],[100,-100,-30]]],3,[0,0,0,0,.333,.666,1,1,1,1],3,[0,0,0,0,.333,.666,1,1,1,1])),color:[0,.5,0,1],position:[-250,250,250]}]);return r.useEffect((()=>{e.current&&!t.current&&(t.current=(0,o.createWebgl3DRenderer)(e.current))}),[e.current]),r.useEffect((()=>{var e,r;const{position:a,up:s}=(0,o.updateCamera)(-n,i,1e3/l,-.3*E,-.3*P);_.current.forEach(((e,t)=>{e.color[3]=t===w?.5:1})),null==(r=null==(e=t.current)?void 0:e.render)||r.call(e,_.current,{eye:(0,o.position3DToVec3)(a),up:(0,o.position3DToVec3)(s),target:[-n,i,0],fov:(0,o.angleToRadian)(60),near:.1,far:2e4},{position:[1e3,1e3,1e3],color:[1,1,1,1],specular:[1,1,1,1],shininess:50,specularFactor:1},[1,1,1,1])}),[n,i,l,E,P,w,b,C]),r.createElement("div",{ref:(0,o.bindMultipleRefs)(c,d),style:{position:"absolute",inset:"0px"}},r.createElement("canvas",{ref:e,width:b,height:C,onMouseDown:e=>m({x:e.clientX,y:e.clientY}),onMouseMove:e=>{var n,r;return k(null==(r=null==(n=t.current)?void 0:n.pick)?void 0:r.call(n,e.clientX,e.clientY,(e=>"lines"!==e.geometry.type)))}}),y)}},1459:(e,t,n)=>{"use strict";n.d(t,{default:()=>a});var r=n(3696),o=n(9397),i=n(9758);const a=()=>{const e=r.useRef(null),t=r.useRef(),{x:n,y:a,ref:s,setX:c,setY:l}=(0,i.useWheelScroll)(),{scale:u,setScale:p,ref:d}=(0,i.useWheelZoom)({onChange(e,t,n){const r=(0,i.scaleByCursorPosition)({width:b,height:C},t/e,n);c(r.setX),l(r.setY)}}),{zoomIn:f,zoomOut:g}=(0,i.useZoom)(u,p),{offset:h,onStart:m,mask:y,resetDragMove:v}=(0,i.useDragMove)((()=>{c((e=>e+h.x)),l((e=>e+h.y))}));(0,i.useGlobalKeyDown)((e=>{"Escape"===e.key?v():(0,i.metaKeyIfMacElseCtrlKey)(e)&&("Minus"===e.code?g(e):"Equal"===e.code&&f(e))}));const x=(0,i.useWindowSize)(),b=x.width/2,C=x.height,E=()=>{const e=document.createElement("canvas"),t=e.getContext("2d");if(t){t.font="50px monospace";const e=t.measureText("abc");t.canvas.width=Math.ceil(e.width)+2,t.canvas.height=50,t.font="50px monospace",t.fillStyle="white",t.fillText("abc",0,t.canvas.height)}const n="round",r=void 0;return{backgroundColor:[Math.random(),Math.random(),Math.random(),1],lines:[{points:(0,i.combineStripTriangles)([(0,i.getPolylineTriangles)([{x:600*Math.random(),y:400*Math.random()},{x:600*Math.random(),y:400*Math.random()},{x:600*Math.random(),y:400*Math.random()},{x:600*Math.random(),y:400*Math.random()}],10,r,n).points,(0,i.getPolylineTriangles)([{x:600*Math.random(),y:400*Math.random()},{x:600*Math.random(),y:400*Math.random()},{x:600*Math.random(),y:400*Math.random()},{x:600*Math.random(),y:400*Math.random()}],10,r,n).points]),color:[Math.random(),Math.random(),Math.random(),1]},{points:(0,i.combineStripTriangles)([(0,i.getPolylineTriangles)([{x:600*Math.random(),y:400*Math.random()},{x:600*Math.random(),y:400*Math.random()},{x:600*Math.random(),y:400*Math.random()},{x:600*Math.random(),y:400*Math.random()}],10,r,n).points,(0,i.getPolylineTriangles)([{x:600*Math.random(),y:400*Math.random()},{x:600*Math.random(),y:400*Math.random()},{x:600*Math.random(),y:400*Math.random()},{x:600*Math.random(),y:400*Math.random()}],10,r,n).points]),color:[Math.random(),Math.random(),Math.random(),1]}],line:[600*Math.random(),400*Math.random(),600*Math.random(),400*Math.random(),600*Math.random(),400*Math.random()],triangles:[600*Math.random(),400*Math.random(),600*Math.random(),400*Math.random(),600*Math.random(),400*Math.random()],triangleColors:[Math.random(),Math.random(),Math.random(),1,Math.random(),Math.random(),Math.random(),1,Math.random(),Math.random(),Math.random(),1],canvas:e,color:[Math.random(),Math.random(),Math.random(),1],position:{x:600*Math.random(),y:400*Math.random()}}},[P,w]=r.useState(E());return r.useEffect((()=>{if(!e.current||t.current)return;const n=e.current,r=e.current.getContext("webgl",{antialias:!0,stencil:!0});if(!r)return;r.enable(r.BLEND),r.blendFunc(r.SRC_ALPHA,r.ONE_MINUS_SRC_ALPHA);const a=o.createProgramInfo(r,["\n attribute vec4 position;\n uniform mat3 matrix;\n void main() {\n gl_Position = vec4((matrix * vec3(position.xy, 1)).xy, 0, 1);\n }\n ","\n precision mediump float;\n uniform vec4 color;\n void main() {\n gl_FragColor = color;\n }"]),s=o.createProgramInfo(r,["\n attribute vec4 position; \n uniform mat3 matrix;\n varying vec2 texcoord;\n\n void main () {\n gl_Position = vec4((matrix * vec3(position.xy, 1)).xy, 0, 1);\n texcoord = position.xy;\n }\n ","\n precision mediump float;\n\n varying vec2 texcoord;\n uniform sampler2D texture;\n uniform vec4 color;\n\n void main() {\n if (texcoord.x < 0.0 || texcoord.x > 1.0 ||\n texcoord.y < 0.0 || texcoord.y > 1.0) {\n discard;\n }\n vec4 color = texture2D(texture, texcoord) * color;\n if (color.a < 0.1) {\n discard;\n }\n gl_FragColor = color;\n }"]);r.pixelStorei(r.UNPACK_PREMULTIPLY_ALPHA_WEBGL,!0);const c=o.primitives.createXYQuadBufferInfo(r),l=o.createProgramInfo(r,["\n attribute vec4 position;\n varying vec2 texcoord;\n void main() {\n gl_Position = position;\n texcoord = position.xy * .5 + .5;\n }\n ","\n precision mediump float;\n varying vec2 texcoord;\n uniform sampler2D texture;\n void main() {\n gl_FragColor = texture2D(texture, texcoord); \n }\n "]),u=o.primitives.createXYQuadBufferInfo(r),p=o.createTexture(r,{src:"https://farm9.staticflickr.com/8873/18598400202_3af67ef38f_z_d.jpg",crossOrigin:""}),d=o.createProgramInfo(r,["\n attribute vec4 position;\n attribute vec4 color;\n uniform mat3 matrix;\n varying vec4 v_color;\n\n void main () {\n gl_Position = vec4((matrix * vec3(position.xy, 1)).xy, 0, 1);\n v_color = color;\n }\n ","\n precision mediump float;\n\n varying vec4 v_color;\n\n void main() {\n gl_FragColor = v_color;\n }"]);t.current=(e,t,f,g)=>{r.viewport(0,0,r.canvas.width,r.canvas.height),r.useProgram(a.program),o.resizeCanvasToDisplaySize(n),r.clearColor(...e.backgroundColor),r.clear(r.COLOR_BUFFER_BIT|r.DEPTH_BUFFER_BIT|r.STENCIL_BUFFER_BIT);let h=i.m3.projection(r.canvas.width,r.canvas.height);h=i.m3.multiply(h,i.m3.translation(t,f)),1!==g&&(h=i.m3.multiply(h,i.m3.translation(r.canvas.width/2,r.canvas.height/2)),h=i.m3.multiply(h,i.m3.scaling(g,g)),h=i.m3.multiply(h,i.m3.translation(-r.canvas.width/2,-r.canvas.height/2)));const m=[];for(const t of e.lines)m.push({programInfo:a,bufferInfo:o.createBufferInfoFromArrays(r,{position:{numComponents:2,data:t.points}}),uniforms:{color:t.color,matrix:h},type:r.TRIANGLE_STRIP});const y=[{programInfo:a,bufferInfo:o.createBufferInfoFromArrays(r,{position:{numComponents:2,data:e.line}}),uniforms:{color:e.color,matrix:h},type:r.LINE_STRIP}],v=[{programInfo:d,bufferInfo:o.createBufferInfoFromArrays(r,{position:{numComponents:2,data:e.triangles},color:{numComponents:4,data:e.triangleColors}}),uniforms:{matrix:h},type:r.TRIANGLES}];h=i.m3.multiply(h,i.m3.translation(e.position.x,e.position.y)),h=i.m3.multiply(h,i.m3.scaling(e.canvas.width,e.canvas.height)),o.drawObjectList(r,m),r.enable(r.STENCIL_TEST),r.stencilFunc(r.ALWAYS,1,255),r.stencilOp(r.KEEP,r.KEEP,r.REPLACE),o.drawObjectList(r,[{programInfo:s,bufferInfo:c,uniforms:{matrix:h,color:e.color,texture:o.createTexture(r,{src:e.canvas})}},{programInfo:s,bufferInfo:c,uniforms:{matrix:i.m3.multiply(h,i.m3.translation(1,0)),color:e.color,texture:o.createTexture(r,{src:e.canvas})}},{programInfo:s,bufferInfo:c,uniforms:{matrix:i.m3.multiply(h,i.m3.translation(1,1)),color:e.color,texture:o.createTexture(r,{src:e.canvas})}}]),r.stencilFunc(r.EQUAL,1,255),r.stencilOp(r.KEEP,r.KEEP,r.KEEP),o.drawObjectList(r,[{programInfo:l,bufferInfo:u,uniforms:{texture:p}}]),r.disable(r.STENCIL_TEST),o.drawObjectList(r,y),o.drawObjectList(r,v)}}),[e.current]),r.useEffect((()=>{t.current&&t.current(P,n+h.x,a+h.y,u)}),[P,t.current,n,a,h,u]),r.createElement("div",{ref:(0,i.bindMultipleRefs)(s,d),style:{position:"absolute",inset:"0px"}},r.createElement("canvas",{ref:e,width:b,height:C,onMouseDown:e=>m({x:e.clientX,y:e.clientY})}),r.createElement("button",{style:{position:"fixed"},onClick:()=>w(E())},"update"),y)}},432:(e,t,n)=>{"use strict";n.d(t,{default:()=>p});var r=n(3696),o=n(9758),i=Object.defineProperty,a=Object.getOwnPropertySymbols,s=Object.prototype.hasOwnProperty,c=Object.prototype.propertyIsEnumerable,l=(e,t,n)=>t in e?i(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,u=(e,t)=>{for(var n in t||(t={}))s.call(t,n)&&l(e,n,t[n]);if(a)for(var n of a(t))c.call(t,n)&&l(e,n,t[n]);return e};const p=()=>{const e=r.useRef(null),t=r.useRef(),{x:n,y:i,setX:a,setY:s,ref:c}=(0,o.useWheelScroll)(),{scale:l,setScale:p,ref:d}=(0,o.useWheelZoom)(),[f,g]=r.useState({x:0,y:0}),{offset:h,onStart:m,mask:y,resetDragMove:v}=(0,o.useDragMove)((()=>{g((e=>({x:e.x+h.x,y:e.y+h.y})))}));(0,o.useGlobalKeyDown)((e=>{"Escape"===e.key?v():"Digit0"===e.code&&!e.shiftKey&&(0,o.metaKeyIfMacElseCtrlKey)(e)&&(p(1),a(0),s(0),g({x:0,y:0}),e.preventDefault())}));const x=(0,o.useWindowSize)(),b=x.width/2,C=x.height,E=h.x+f.x,P=h.y+f.y,[w,k]=r.useState(),_=r.useRef([...(0,o.getAxesGraphics)(),{geometry:{type:"lines",points:(0,o.getDashedLine)([0,0,0],[100,100,100],6).flat()},color:[0,0,0,1]},{geometry:{type:"sphere",radius:100},color:[1,0,0,1],position:[0,250,0]},{geometry:{type:"cube",size:150},color:[0,1,0,1],position:[250,0,0]},{geometry:{type:"cylinder",radius:100,height:200},color:[0,0,1,1],position:[-250,0,0]},{geometry:{type:"cone",topRadius:0,bottomRadius:100,height:200},color:[1,0,1,1],position:[0,-250,0]},{geometry:{type:"triangles",points:[-50,-50,50,50,50,50,-50,50,50]},color:[.5,0,.5,1],position:[250,250,250]},{geometry:u({type:"vertices"},(0,o.getNurbsSurfaceVertices)([[[0,0,-20],[20,0,0],[40,0,0],[60,0,0],[80,0,0],[100,0,0]],[[0,-20,0],[20,-20,10],[40,-20,20],[60,-20,0],[80,-20,0],[100,-20,0]],[[0,-40,0],[20,-40,10],[40,-40,20],[60,-40,0],[80,-40,-4],[100,-40,-24]],[[0,-50,0],[20,-60,0],[40,-60,-46],[60,-60,0],[80,-60,0],[100,-50,0]],[[0,-80,0],[20,-80,0],[40,-80,0],[60,-80,8],[80,-80,-40],[100,-80,0]],[[0,-100,24],[20,-100,0],[40,-100,40],[60,-100,0],[100,-100,-20],[100,-100,-30]]],3,[0,0,0,0,.333,.666,1,1,1,1],3,[0,0,0,0,.333,.666,1,1,1,1])),color:[0,.5,0,1],position:[250,250,-250],rotateY:Math.PI}]);return r.useEffect((()=>{e.current&&!t.current&&(0,o.createWebgpu3DRenderer)(e.current).then((e=>{t.current=e,k(-1)}))}),[e.current]),r.useEffect((()=>{var e,r;const{position:a,up:s}=(0,o.updateCamera)(-n,i,1e3/l,-.3*E,-.3*P);_.current.forEach(((e,t)=>{e.color[3]=t===w?.5:1})),null==(r=null==(e=t.current)?void 0:e.render)||r.call(e,_.current,{eye:(0,o.position3DToVec3)(a),up:(0,o.position3DToVec3)(s),target:[-n,i,0],fov:(0,o.angleToRadian)(60),near:.1,far:2e4},{position:[1e3,1e3,1e3],color:[1,1,1,1],specular:[1,1,1,1],shininess:50,specularFactor:1},[1,1,1,1])}),[n,i,l,E,P,w,b,C]),r.createElement("div",{ref:(0,o.bindMultipleRefs)(c,d),style:{position:"absolute",inset:"0px"}},r.createElement("canvas",{ref:e,width:b,height:C,onMouseDown:e=>m({x:e.clientX,y:e.clientY}),onMouseMove:e=>{return n=function*(){var n,r;return k(yield null==(r=null==(n=t.current)?void 0:n.pick)?void 0:r.call(n,e.clientX,e.clientY,(e=>"lines"!==e.geometry.type&&"triangles"!==e.geometry.type)))},new Promise(((e,t)=>{var r=e=>{try{i(n.next(e))}catch(e){t(e)}},o=e=>{try{i(n.throw(e))}catch(e){t(e)}},i=t=>t.done?e(t.value):Promise.resolve(t.value).then(r,o);i((n=n.apply(undefined,null)).next())}));var n}}),y)}},5301:(e,t,n)=>{"use strict";n.d(t,{default:()=>a});var r=n(3696),o=n.n(r),i=n(9758);const a=()=>{const{ref:e,x:t,y:n}=(0,i.useWheelScroll)({maxOffsetX:250,maxOffsetY:250});return o().createElement("div",{style:{width:"300px",height:"300px",overflow:"hidden",position:"absolute",display:"flex",alignItems:"center",justifyContent:"center",border:"1px solid green"},ref:e},o().createElement("div",{style:{width:"800px",height:"800px",position:"absolute",transform:`translate(${t}px, ${n}px)`,background:"radial-gradient(50% 50% at 50% 50%, red 0%, white 100%)"}}))}},7507:(e,t,n)=>{"use strict";n.d(t,{default:()=>a});var r=n(3696),o=n.n(r),i=n(9758);const a=()=>{const{ref:e,scale:t}=(0,i.useWheelZoom)();return o().createElement("div",{style:{width:"300px",height:"300px",overflow:"hidden",position:"absolute",display:"flex",alignItems:"center",justifyContent:"center",border:"1px solid green"},ref:e},o().createElement("div",{style:{width:"800px",height:"800px",position:"absolute",transform:`scale(${t})`,background:"radial-gradient(50% 50% at 50% 50%, red 0%, white 100%)"}}))}},6708:(e,t,n)=>{"use strict";n.d(t,{WhiteBoard:()=>u});var r=n(3696),o=n.n(r),i=n(9758),a=n(1406),s=n(7449),c=Math.pow;const l=Math.round(15*Math.random()*c(16,3)+c(16,3)).toString(16);function u(){const[,e,t]=(0,i.useLocalStorageState)("composable-editor-canvas-whiteboard",[]),n=o().useRef(null),[r,c]=(0,i.useLocalStorageState)("composable-editor-canvas-whiteboard:snaps",i.allSnapTypes),[u,p]=(0,i.useLocalStorageState)("composable-editor-canvas-whiteboard:print-mode",!1),[d,f]=(0,i.useLocalStorageState)("composable-editor-canvas-whiteboard:performance-mode",!1),[g,h]=(0,i.useLocalStorageState)("composable-editor-canvas-whiteboard:render-target","svg"),[m,y]=o().useState(!1),[v,x]=o().useState(!1),[b,C]=(0,i.useLocalStorageState)("composable-editor-canvas-whiteboard:background-color",16777215),[E,P]=o().useState(),{pluginLoaded:w,pluginCommandTypes:k}=(0,a.usePlugins)();return(0,a.useInitialStateValidated)(t,w)?o().createElement("div",null,o().createElement(a.CADEditor,{ref:n,id:"whiteboard",operator:l,initialState:t,snapTypes:r,renderTarget:g,setCanUndo:y,setCanRedo:x,setOperation:P,backgroundColor:b,panelVisible:!0,printMode:u,performanceMode:d,onChange:e}),o().createElement("div",{style:{position:"relative"}},o().createElement("label",null,o().createElement("input",{type:"checkbox",checked:u,onChange:()=>p(!u)}),"print mode"),o().createElement("label",null,o().createElement("input",{type:"checkbox",checked:d,onChange:()=>f(!d)}),"performance mode"),i.allSnapTypes.map((e=>o().createElement("label",{key:e},o().createElement("input",{type:"checkbox",checked:r.includes(e),onChange:t=>c(t.target.checked?[...r,e]:r.filter((t=>t!==e)))}),e))),["move canvas","zoom window"].map((e=>o().createElement("button",{onClick:()=>{var t;return null==(t=n.current)?void 0:t.startOperation({type:"non command",name:e})},key:e,style:{position:"relative",borderColor:E===e?"red":void 0}},e)))),o().createElement("div",{style:{position:"relative"}},k.map((e=>{if(e.icon){const t=o().cloneElement(e.icon,{onClick:()=>{var t;return null==(t=n.current)?void 0:t.startOperation({type:"command",name:e.name})},style:{width:"20px",height:"20px",margin:"5px",cursor:"pointer",color:E===e.name?"red":void 0}});return o().createElement("span",{title:e.name,key:e.name},t)}return null})),o().createElement("input",{type:"color",style:{position:"relative",top:"-5px"},value:(0,i.getColorString)(b),onChange:e=>C((0,i.colorStringToNumber)(e.target.value))}),o().createElement("button",{disabled:!m,onClick:()=>{var e;return null==(e=n.current)?void 0:e.undo()},style:{position:"relative",top:"-10px"}},"undo"),o().createElement("button",{disabled:!v,onClick:()=>{var e;return null==(e=n.current)?void 0:e.redo()},style:{position:"relative",top:"-10px"}},"redo"),o().createElement("select",{value:g,onChange:e=>h(e.target.value),style:{position:"relative",top:"-10px"}},(0,s.getAllRendererTypes)().map((e=>o().createElement("option",{key:e,value:e},e)))))):null}},1986:(e,t,n)=>{"use strict";n.d(t,{default:()=>a});var r=n(3696),o=n.n(r),i=n(9758);const a=()=>{const{width:e,height:t}=(0,i.useWindowSize)();return o().createElement("div",null,Math.round(e)," ",Math.round(t))}},3307:(e,t,n)=>{"use strict";n.r(t),n.d(t,{AlignmentLine:()=>u});var r=n(3696),o=Object.defineProperty,i=Object.getOwnPropertySymbols,a=Object.prototype.hasOwnProperty,s=Object.prototype.propertyIsEnumerable,c=(e,t,n)=>t in e?o(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,l=(e,t)=>{for(var n in t||(t={}))a.call(t,n)&&c(e,n,t[n]);if(i)for(var n of i(t))s.call(t,n)&&c(e,n,t[n]);return e};function u(e){var t,n,o,i;if(void 0===e.value)return null;const a=l({position:"absolute"},e.style);return"x"===e.type?(a.borderLeft="1px dashed black",a.left=(null!=(n=null==(t=e.transformX)?void 0:t.call(e,e.value))?n:e.value)+"px",a.top="0px",a.width="1px",a.height="100%"):(a.borderTop="1px dashed black",a.top=(null!=(i=null==(o=e.transformY)?void 0:o.call(e,e.value))?i:e.value)+"px",a.left="0px",a.width="100%",a.height="1px"),r.createElement("div",{style:a})}},7921:(e,t,n)=>{"use strict";n.r(t),n.d(t,{ChartTooltip:()=>A,getBarChart:()=>_,getChartAxis:()=>P,getChartAxis3D:()=>L,getGridLines:()=>w,getLineChart:()=>E,getPieChart:()=>S,getPolarAreaChart:()=>R,getRadarChart:()=>T,renderChartTooltip:()=>k});var r=n(3696),o=n.n(r),i=n(2792),a=n(8905),s=n(6842),c=n(5773),l=n(1715),u=n(2318),p=n(7486),d=n(1324),f=Object.defineProperty,g=Object.defineProperties,h=Object.getOwnPropertyDescriptors,m=Object.getOwnPropertySymbols,y=Object.prototype.hasOwnProperty,v=Object.prototype.propertyIsEnumerable,x=(e,t,n)=>t in e?f(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,b=(e,t)=>{for(var n in t||(t={}))y.call(t,n)&&x(e,n,t[n]);if(m)for(var n of m(t))v.call(t,n)&&x(e,n,t[n]);return e},C=(e,t)=>g(e,h(t));function E(e,t,n,r,o,i){const a=(0,s.getPointsBounding)(e.flat());if(!a)return;const{axis:l,tx:u,ty:p,minY:d}=P(t,a,n,r,o,i),f=e.map((e=>e.map((e=>({x:u(e.x),y:p(e.y),r:e.r})))));return{children:l,points:f,select:t=>{for(let n=0;n{var n;return(0,c.getTwoPointsDistance)(e,t)<=(null!=(n=e.r)?n:5)}));if(r>=0)return C(b({},f[n][r]),{value:e[n][r]})}},minY:d}}function P(e,t,n,{width:r,height:o},i,a){var s,c,l,u,p,d,f,g;const h=null!=(s=null==a?void 0:a.axisColor)?s:13421772,m=null!=(c=null==a?void 0:a.textColor)?c:0,y=null!=(l=null==a?void 0:a.textSize)?l:12,v=null!=(u=null==a?void 0:a.fontFamily)?u:"monospace",x=null!=(p=null==a?void 0:a.textLineLength)?p:5,b=e=>{var t,n;return null!=(n=null==(t=null==a?void 0:a.getXLabel)?void 0:t.call(a,e))?n:e.toString()},C=e=>{var t,n;return null!=(n=null==(t=null==a?void 0:a.getYLabel)?void 0:t.call(a,e))?n:e.toString()},E=null!=(d=null==n?void 0:n.x)?d:1,P=null!=(f=null==n?void 0:n.y)?f:1,w=null!=(g=null==a?void 0:a.type)?g:"line",k=Math.floor(t.start.x/E)*E,_=Math.ceil(t.end.x/E)*E,S=Math.floor(t.start.y/P)*P,R=Math.ceil(t.end.y/P)*P,T=(r-i.left-i.right)/(_-k),A=(o-i.top-i.bottom)/(R-S),L=e=>(e-k)*T+i.left,M=e=>(R-e)*A+i.top,I=L(k)-x,O=L(_)+((null==a?void 0:a.ySecondary)?x:0),D=M(S),B=D+x,z=M(R),F=E*T,N=[];if(!(null==a?void 0:a.xLabelDisabled))for(let t=k;t<=_;t+=E){const n=L(t);N.push(e.renderPolyline([{x:n,y:B},{x:n,y:z}],{strokeColor:h})),N.push(e.renderText(n+("bar"===w?F/2:0),B,b(t),m,y,v,{textBaseline:"top",textAlign:"center"}))}if(!(null==a?void 0:a.yLabelDisabled))for(let t=S;t<=R;t+=P){const n=M(t);N.push(e.renderPolyline([{x:I,y:n},{x:O,y:n}],{strokeColor:h})),N.push(e.renderText(I,n,C(t),m,y,v,{textBaseline:"middle",textAlign:"right"})),(null==a?void 0:a.ySecondary)&&N.push(e.renderText(O,n,C(t),m,y,v,{textBaseline:"middle",textAlign:"left"}))}return{axis:N,minY:D,tx:L,ty:M,unitWidth:F,reverseTransform:e=>({x:(e.x-i.left)/T+k,y:R-(e.y-i.top)/A})}}function w(e,t,n=t,r=1/0){const o=Math.floor(e.start.x/t),i=Math.ceil(e.end.x/t),a=Math.floor(e.start.y/n),s=Math.ceil(e.end.y/n);if(i-o+1+(s-a)+1>r)return[];const c=[],l=o*t,u=i*t,p=a*n,d=s*n;for(let e=o;e<=i;e++){const n=e*t;c.push([{x:n,y:p},{x:n,y:d}])}for(let e=a;e<=s;e++){const t=e*n;c.push([{x:l,y:t},{x:u,y:t}])}return c}function k(e,{x:t,y:n},r,o){var i,s,c,l,u,f;const g=null!=(i=null==o?void 0:o.textSize)?i:12,h=null!=(s=null==o?void 0:o.fontFamily)?s:"monospace",m=(y=r.x,null!=(x=null==(v=null==o?void 0:o.getXLabel)?void 0:v.call(o,y))?x:y.toString());var y,v,x;const b=(e=>{var t,n;return null!=(n=null==(t=null==o?void 0:o.getYLabel)?void 0:t.call(o,e))?n:e.toString()})(r.y);let C;if(null==o?void 0:o.width)C=o.width;else{const e=(0,d.getTextSizeFromCache)((0,a.getTextStyleFont)({fontFamily:h,fontSize:g}),m),t=(0,d.getTextSizeFromCache)((0,a.getTextStyleFont)({fontFamily:h,fontSize:g}),b);C=e&&t?Math.max(e.width,t.width,40):40}const E=null!=(c=null==o?void 0:o.height)?c:30,P=null!=(l=null==o?void 0:o.textColor)?l:16777215,w=null!=(u=null==o?void 0:o.radius)?u:5,k=null!=(f=null==o?void 0:o.backgroundColor)?f:0;return t+=C/2,n-=E/2,[e.renderPolygon((0,p.getRoundedRectPoints)({x:t,y:n,width:C,height:E},w,30),{fillColor:k}),e.renderText(t,n,m,P,g,h,{textBaseline:"bottom",textAlign:"center"}),e.renderText(t,n,b,P,g,h,{textBaseline:"top",textAlign:"center"})]}function _(e,t,n,r,o,i,a,c){var l,u;let p={start:{x:0,y:0},end:{x:Math.max(...e.map((e=>e.length))),y:0}};for(const t of e.flat(2))tp.end.y&&(p.end.y=t);(null==c?void 0:c.bounding)&&(p=(0,s.getPointsBoundingUnsafe)([c.bounding.start,c.bounding.end,p.start,p.end]));const{axis:d,tx:f,ty:g,reverseTransform:h,unitWidth:m}=P(r,p,o,i,a,b({type:"bar"},c)),y=null!=(l=null==c?void 0:c.barPadding)?l:.1,v=null!=(u=null==c?void 0:c.barSpacing)?u:.05,x=(1-2*y-(e.length-1)*v)/e.length,E=x*m,w=x+v;return e.forEach(((e,r)=>{e.forEach(((e,o)=>{1===e.length&&(e=[0,...e]);const i=f(o)+m*(y+r*w)+E/2,a=e.map((e=>g(e)));for(let e=1;e{const n=h(t),r=Math.floor(n.x),o=n.x-r;if(o>=y&&o<=1-y){const i=Math.floor((o-y)/w);if(o-y-i*w<=x&&i>=0&&i=o[a-1]&&n.y<=o[a]){const n=e[i][r];return C(b({},t),{value:{x:r,y:n.length>2?Math.abs(n[a-1]-n[a]):n}})}}}},tx:f,ty:g}}function S(e,t,n,{width:r,height:o},i,a){var s,p;const d=null!=(s=null==a?void 0:a.type)?s:"pie",f=null!=(p=null==a?void 0:a.startAngle)?p:-90,g=e.map((e=>e.reduce(((e,t)=>e+t),0))),h={x:(r+i.left-i.right)/2,y:(o+i.top-i.bottom)/2,r:Math.min((r-i.left-i.right)/2,(o-i.top-i.bottom)/2)},m=h.r*("doughnut"===d?.5:0),y=h.r-m,v=[],x=[];return e.forEach(((r,o)=>{let i=f;const a=[],s=m+y*o/e.length,c=m+y*(o+1)/e.length;r.forEach(((e,r)=>{a.push(i);const l=i+e/g[o]*360;v.push(n.renderPolygon([...(0,u.arcToPolyline)(C(b({},h),{r:s,startAngle:i,endAngle:l}),5),...(0,u.arcToPolyline)(C(b({},h),{r:c,startAngle:l,endAngle:i,counterclockwise:!0}),5)],{fillColor:t[r],strokeColor:16777215,strokeWidth:2})),i=l})),x.push(a)})),{children:v,select:t=>{const n=(0,c.getTwoPointsDistance)(t,h),r=Math.floor((n-m)/y*e.length);if(r>=0&&re>=o));return-1===i&&(i=n.length-1),C(b({},t),{value:{x:i,y:e[r][i]}})}}}}function R(e,t,n,{width:r,height:o},a,s,p){var d,f;const g=null!=(d=null==p?void 0:p.opacity)?d:.5,h=null!=(f=null==p?void 0:p.axisColor)?f:13421772,m=Math.ceil(Math.max(...e)/a)*a,y={x:(r+s.left-s.right)/2,y:(o+s.top-s.bottom)/2,r:Math.min((r-s.left-s.right)/2,(o-s.top-s.bottom)/2)},v=e=>y.r*e/m,x=[];for(let e=a;e<=m;e+=a){const t=v(e);x.push(n.renderCircle(y.x,y.y,t,{strokeColor:h})),x.push(n.renderCircle(y.x,y.y-t,8,{fillColor:16777215,strokeWidth:0})),x.push(n.renderText(y.x,y.y-t,e.toString(),h,12,"monospace",{textAlign:"center",textBaseline:"middle"}))}let E=-90;const P=[];return e.forEach(((r,o)=>{const a=E+360/e.length;P.push((0,i.getTwoNumberCenter)(E,a)),x.push(n.renderPolygon([y,...(0,u.arcToPolyline)(C(b({},y),{r:v(r),startAngle:E,endAngle:a}),5)],{fillColor:t[o],strokeColor:16777215,strokeWidth:2,fillOpacity:g})),E=a})),{children:x,select:t=>{const n=(0,c.getTwoPointsDistance)(t,y);let r=(0,l.radianToAngle)((0,l.getTwoPointsRadian)(t,y))- -90;r<0&&(r+=360);const o=Math.floor(r*e.length/360);if(o>=0&&oh.r*e/g,y=e[0].map(((t,n)=>360*n/e[0].length-90)),v=[],x=m(g);for(const e of y){const t=(0,u.getArcPointAtAngle)(C(b({},h),{r:x}),e);v.push(n.renderPolyline([h,t],{strokeColor:f}))}for(let e=i;e<=g;e+=i){const t=m(e),r=[];for(const e of y)r.push((0,u.getArcPointAtAngle)(C(b({},h),{r:t}),e));v.push(n.renderPolygon(r,{strokeColor:f})),v.push(n.renderRect(h.x-10,h.y-t-6,20,12,{fillColor:16777215,strokeWidth:0})),v.push(n.renderText(h.x,h.y-t,e.toString(),f,12,"monospace",{textAlign:"center",textBaseline:"middle"}))}const E=e.map((e=>e.map(((e,t)=>(0,u.getArcPointAtAngle)(C(b({},h),{r:m(e)}),y[t])))));return E.forEach(((e,r)=>{v.push(n.renderPolygon(e,{fillColor:t[r],strokeWidth:0,fillOpacity:d})),v.push(n.renderPolygon(e,{strokeColor:t[r],strokeWidth:2}));for(const o of e)v.push(n.renderCircle(o.x,o.y,3,{fillColor:t[r],strokeWidth:0}))})),{children:v,select:t=>{for(let n=0;n(0,c.getTwoPointsDistance)(e,t)<=3));if(r>=0)return C(b({},E[n][r]),{value:{x:r,y:e[n][r]}})}},circle:h,angles:y}}function A(e){return o().createElement("div",{style:{position:"absolute",top:e.y-35+"px",left:`${e.x}px`,display:"flex",flexDirection:"column",background:"black",color:"white",width:"40px",textAlign:"center",fontSize:"12px",borderRadius:"5px",pointerEvents:"none"}},o().createElement("span",null,e.label),o().createElement("span",null,e.value))}function L(e,t){const{minX:n,minY:r,minZ:o,maxX:i,maxY:a,maxZ:s}=function(e,t={min:1/0,max:-1/0}){let n=t.min,r=t.min,o=t.min,i=t.max,a=t.max,s=t.max;for(const t of e){const e=t[0],c=t[1],l=t[2];ei&&(i=e),ca&&(a=c),ls&&(s=l)}return{maxX:i,minX:n,minY:r,maxY:a,minZ:o,maxZ:s}}(e.flat(),{min:0,max:0}),c=Math.floor(n/t.x)*t.x,l=Math.ceil(i/t.x)*t.x,u=Math.floor(r/t.y)*t.y,p=Math.ceil(a/t.y)*t.y,d=Math.floor(o/t.z)*t.z,f=Math.ceil(s/t.z)*t.z,g=[];for(let e=n;e<=l;e+=t.x)g.push({geometry:{type:"lines",points:[e,u,0,e,p,0]},color:[0,1,0,1]}),g.push({geometry:{type:"lines",points:[e,0,d,e,0,f]},color:[0,0,1,1]});for(let e=r;e<=p;e+=t.y)g.push({geometry:{type:"lines",points:[c,e,0,l,e,0]},color:[1,0,0,1]}),g.push({geometry:{type:"lines",points:[0,e,d,0,e,f]},color:[0,0,1,1]});for(let e=o;e<=f;e+=t.z)g.push({geometry:{type:"lines",points:[c,0,e,l,0,e]},color:[1,0,0,1]}),g.push({geometry:{type:"lines",points:[0,u,e,0,p,e]},color:[0,1,0,1]});return g}},6487:(e,t,n)=>{"use strict";n.d(t,{Cursor:()=>f});var r=n(3696),o=n.n(r),i=Object.defineProperty,a=Object.defineProperties,s=Object.getOwnPropertyDescriptors,c=Object.getOwnPropertySymbols,l=Object.prototype.hasOwnProperty,u=Object.prototype.propertyIsEnumerable,p=(e,t,n)=>t in e?i(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,d=(e,t)=>{for(var n in t||(t={}))l.call(t,n)&&p(e,n,t[n]);if(c)for(var n of c(t))u.call(t,n)&&p(e,n,t[n]);return e};const f=o().forwardRef(((e,t)=>{var n,r;const[i,c]=o().useState(!1),[l,u]=o().useState(!1),p=o().useRef();return o().useEffect((()=>{u(!0),p.current&&clearTimeout(p.current),p.current=setTimeout((()=>{u(!1)}),500)}),[null==(n=e.style)?void 0:n.left,null==(r=e.style)?void 0:r.top]),o().createElement(o().Fragment,null,o().createElement("input",{ref:t,style:(f=d({},e.style),g={border:0,outline:"none",width:"0px",position:"absolute",opacity:0},a(f,s(g))),readOnly:e.readOnly,onKeyDown:e.onKeyDown,onCompositionEnd:e.onCompositionEnd,onBlur:t=>{var n;null==(n=e.onBlur)||n.call(e,t),c(!1)},autoFocus:e.autoFocus,onFocus:t=>{var n;null==(n=e.onFocus)||n.call(e,t),c(!0)}}),o().createElement("style",null,"@-webkit-keyframes blink {\n 0%, 49.9%, 100% { opacity: 0; }\n 50%, 99.9% { opacity: 1; }\n }"),o().createElement("span",{style:d({display:!i||e.readOnly?"none":"inline-block",position:"absolute",width:"1px",animation:l?void 0:"blink 1s infinite",borderLeft:"1px solid black",userSelect:"none"},e.style)}));var f,g}))},9294:(e,t,n)=>{"use strict";n.r(t),n.d(t,{LinearDimension:()=>a,getLinearDimensionGeometries:()=>o,getLinearDimensionTextPosition:()=>i});var r=n(1324);function o(e,t,n){const o=(0,r.getTwoPointCenter)(e.p1,e.p2);let i,a,s,c,l,u=[];const{textPosition:p,size:d,textRotation:f}=n(e),g=(0,r.getTwoPointsRadian)(e.position,o),h=Math.abs(g);if(e.direct){const n=e.p1.x>e.p2.x?e.p2:e.p1,o=e.p1.x>e.p2.x?e.p1:e.p2,u=(0,r.twoPointLineToGeneralFormLine)(n,o),p=u?(0,r.getPerpendicularDistance)(e.position,u):(0,r.getTwoPointsDistance)(e.position,n),f=(0,r.getTwoPointsRadian)(o,n);let h=f-g;h<-Math.PI&&(h+=2*Math.PI);const m=h>0&&hMath.PI/4&&h<3*Math.PI/4){const n=e.position.y>o.y?1:-1;i=[e.p1,{x:e.p1.x,y:e.position.y+n*t.margin}],a=[e.p2,{x:e.p2.x,y:e.position.y+n*t.margin}];const u={x:e.p1.x,y:e.position.y},p={x:e.p2.x,y:e.position.y};s=[{x:Math.min(e.p1.x,e.p2.x,e.position.x),y:e.position.y},{x:Math.max(e.p1.x,e.p2.x,e.position.x),y:e.position.y}];let f=u.xo.x?1:-1;i=[e.p1,{x:e.position.x+n*t.margin,y:e.p1.y}],a=[e.p2,{x:e.position.x+n*t.margin,y:e.p2.y}];const u={x:e.position.x,y:e.p1.y},p={x:e.position.x,y:e.p2.y};s=[{x:e.position.x,y:Math.min(e.p1.y,e.p2.y,e.position.y)},{x:e.position.x,y:Math.max(e.p1.y,e.p2.y,e.position.y)}];let f=u.y(0,r.rotatePosition)(e,p,f))));const m=[...i,...a,...s,...c,...l,...u];return{lines:[...(0,r.iteratePolylineLines)(i),...(0,r.iteratePolylineLines)(a),...(0,r.iteratePolylineLines)(s)],regions:[{points:c,lines:Array.from((0,r.iteratePolygonLines)(c))},{points:l,lines:Array.from((0,r.iteratePolygonLines)(l))},{points:u,lines:Array.from((0,r.iteratePolygonLines)(u))}],points:m,bounding:(0,r.getPointsBounding)(m),renderingLines:[]}}function i(e,t,n){const o=(0,r.getTwoPointCenter)(e.p1,e.p2);let i,a,s,c=0;const l=(0,r.getTwoPointsRadian)(e.position,o),u=Math.abs(l);if(e.direct){const o=e.p1.x>e.p2.x?e.p2:e.p1,u=e.p1.x>e.p2.x?e.p1:e.p2,p=(0,r.twoPointLineToGeneralFormLine)(o,u),d=p?(0,r.getPerpendicularPoint)(e.position,p):o,f=(0,r.getTwoPointsDistance)(e.position,d);c=(0,r.getTwoPointsRadian)(u,o);let g=(0,r.getTwoPointsRadian)(u,o)-l;g<-Math.PI&&(g+=2*Math.PI);const h=g>0&&gMath.PI/4&&u<3*Math.PI/4?(i={x:e.position.x,y:e.position.y-t},a=(0,r.formatNumber)((0,r.getTwoNumbersDistance)(e.p1.x,e.p2.x)).toString(),s=n((0,r.getTextStyleFont)(e),a),s&&(i.x-=s.width/2)):(i={x:e.position.x-t,y:e.position.y},a=(0,r.formatNumber)((0,r.getTwoNumbersDistance)(e.p1.y,e.p2.y)).toString(),s=n((0,r.getTextStyleFont)(e),a),s&&(i.y+=s.width/2),c=-Math.PI/2);return{text:e.text||a,textPosition:i,size:s,textRotation:c}}const a=(0,r.and)(r.TextStyle,{p1:r.Position,p2:r.Position,position:r.Position,direct:(0,r.optional)(r.boolean),text:(0,r.optional)(r.string)})},6424:(e,t,n)=>{"use strict";n.r(t),n.d(t,{RadialDimension:()=>a,getRadialDimensionGeometries:()=>o,getRadialDimensionTextPosition:()=>i});var r=n(1324);function o(e,t,n,o){const i=(0,r.getPointByLengthAndDirection)(t,t.r,e.position),a=(0,r.getTwoPointsDistance)(t,e.position),s=(0,r.getPointByLengthAndDirection)(i,n.arrowSize,e.position),c=(0,r.rotatePositionByCenter)(s,i,n.arrowAngle),l=(0,r.rotatePositionByCenter)(s,i,-n.arrowAngle),u=[a>t.r?t:i,e.position],p=[i,c,l];let d=[];const{textPosition:f,textRotation:g,size:h}=o(e,t);h&&(d=[{x:f.x,y:f.y-h.height},{x:f.x+h.width,y:f.y-h.height},{x:f.x+h.width,y:f.y},{x:f.x,y:f.y}].map((e=>(0,r.rotatePosition)(e,f,g))));const m=[...u,...p,...d];return{lines:Array.from((0,r.iteratePolylineLines)(u)),regions:[{points:p,lines:Array.from((0,r.iteratePolygonLines)(p))},{points:d,lines:Array.from((0,r.iteratePolygonLines)(d))}],points:m,bounding:(0,r.getPointsBounding)(m),renderingLines:[]}}function i(e,t,n,o){let i=e.position;const a=`R${(0,r.formatNumber)(t.r)}`,s=o((0,r.getTextStyleFont)(e),a);let c=(0,r.getTwoPointsRadian)(e.position,t);return s&&((0,r.getTwoPointsDistance)(t,e.position)>t.r?e.position.x>t.x?i=(0,r.getPointByLengthAndDirection)(e.position,s.width,t):c-=Math.PI:e.position.x{"use strict";n.r(t),n.d(t,{DragMask:()=>u});var r=n(3696),o=Object.defineProperty,i=Object.getOwnPropertySymbols,a=Object.prototype.hasOwnProperty,s=Object.prototype.propertyIsEnumerable,c=(e,t,n)=>t in e?o(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,l=(e,t)=>{for(var n in t||(t={}))a.call(t,n)&&c(e,n,t[n]);if(i)for(var n of i(t))s.call(t,n)&&c(e,n,t[n]);return e};function u(e){return r.createElement("div",{style:l({position:"fixed",inset:"0px",cursor:"grabbing"},e.style),onMouseUp:e.onDragEnd,onMouseMove:e.onDragging,onMouseLeave:e.ignoreLeavingEvent?void 0:e.onDragEnd},e.children)}},4848:(e,t,n)=>{"use strict";n.r(t),n.d(t,{CircleArcEditBar:()=>a});var r=n(3696),o=n(1324),i=n(2286);function a(e){const t=e.x,n=e.y,a=(0,o.angleToRadian)(e.startAngle),s=(0,o.angleToRadian)(e.endAngle),c=(a+s)/2,l=[{data:"center",x:t,y:n,cursor:"move"},{data:"start angle",x:t+e.r*Math.cos(a),y:n+e.r*Math.sin(a),cursor:(0,o.getResizeCursor)(e.startAngle,"top")},{data:"end angle",x:t+e.r*Math.cos(s),y:n+e.r*Math.sin(s),cursor:(0,o.getResizeCursor)(e.endAngle,"top")},{data:"radius",x:t+e.r*Math.cos(c),y:n+e.r*Math.sin(c),cursor:(0,o.getResizeCursor)((e.startAngle+e.endAngle)/2,"right")}];return r.createElement(i.EditBar,{positions:l,scale:e.scale,resizeSize:e.resizeSize,onClick:e.onClick,onMouseDown:e.onMouseDown})}},1369:(e,t,n)=>{"use strict";n.r(t),n.d(t,{CircleEditBar:()=>i});var r=n(3696),o=n(2286);function i(e){const t=e.x,n=e.y,i=[{data:"center",x:t,y:n,cursor:"move"},{data:"edge",x:t-e.radius,y:n,cursor:"ew-resize"},{data:"edge",x:t,y:n-e.radius,cursor:"ns-resize"},{data:"edge",x:t+e.radius,y:n,cursor:"ew-resize"},{data:"edge",x:t,y:n+e.radius,cursor:"ns-resize"}];return r.createElement(o.EditBar,{positions:i,scale:e.scale,resizeSize:e.resizeSize,onClick:e.onClick,onMouseDown:e.onMouseDown})}},2286:(e,t,n)=>{"use strict";n.r(t),n.d(t,{EditBar:()=>o});var r=n(3696);function o(e){var t,n;const o=null!=(t=e.scale)?t:1,i=(null!=(n=e.resizeSize)?n:5)/o,a=1/o;return r.createElement(r.Fragment,null,e.positions.map(((t,n)=>r.createElement("div",{key:n,style:{width:i+"px",height:i+"px",border:`${a}px solid green`,position:"absolute",backgroundColor:"white",boxSizing:"border-box",pointerEvents:"auto",left:t.x-i/2+"px",top:t.y-i/2+"px",cursor:t.cursor},onMouseDown:n=>{var r;return null==(r=e.onMouseDown)?void 0:r.call(e,n,t.data,t.cursor)},onClick:n=>{var r;return null==(r=e.onClick)?void 0:r.call(e,n,t.data,t.cursor)}}))))}},4332:(e,t,n)=>{"use strict";n.r(t),n.d(t,{EllipseArcEditBar:()=>h});var r=n(3696),o=n(1324),i=n(2286),a=Object.defineProperty,s=Object.defineProperties,c=Object.getOwnPropertyDescriptors,l=Object.getOwnPropertySymbols,u=Object.prototype.hasOwnProperty,p=Object.prototype.propertyIsEnumerable,d=(e,t,n)=>t in e?a(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,f=(e,t)=>{for(var n in t||(t={}))u.call(t,n)&&d(e,n,t[n]);if(l)for(var n of l(t))p.call(t,n)&&d(e,n,t[n]);return e},g=(e,t)=>s(e,c(t));function h(e){var t;const n={x:e.cx,y:e.cy},a=(0,o.angleToRadian)(e.startAngle),s=(0,o.angleToRadian)(e.endAngle),c=-(null!=(t=e.angle)?t:0),l=[{data:"center",x:e.cx,y:e.cy,cursor:"move"},g(f({data:"start angle"},(0,o.rotatePositionByCenter)({x:e.cx+e.rx*Math.cos(a),y:e.cy+e.ry*Math.sin(a)},n,c)),{cursor:(0,o.getResizeCursor)(e.startAngle-c,"top")}),g(f({data:"end angle"},(0,o.rotatePositionByCenter)({x:e.cx+e.rx*Math.cos(s),y:e.cy+e.ry*Math.sin(s)},n,c)),{cursor:(0,o.getResizeCursor)(e.endAngle-c,"top")})];return r.createElement(i.EditBar,{positions:l,scale:e.scale,resizeSize:e.resizeSize,onClick:e.onClick,onMouseDown:e.onMouseDown})}},3869:(e,t,n)=>{"use strict";n.r(t),n.d(t,{EllipseEditBar:()=>a});var r=n(3696),o=n(1324),i=n(2286);function a(e){var t;const n={x:e.cx,y:e.cy},a=-(null!=(t=e.angle)?t:0),s=(0,o.rotatePositionByCenter)({x:e.cx-e.rx,y:e.cy},n,a),c=(0,o.rotatePositionByCenter)({x:e.cx+e.rx,y:e.cy},n,a),l=(0,o.rotatePositionByCenter)({x:e.cx,y:e.cy-e.ry},n,a),u=(0,o.rotatePositionByCenter)({x:e.cx,y:e.cy+e.ry},n,a),p=[{data:"center",x:e.cx,y:e.cy,cursor:"move"},{data:"major axis",x:s.x,y:s.y,cursor:(0,o.getResizeCursor)(-a,"left")},{data:"major axis",x:c.x,y:c.y,cursor:(0,o.getResizeCursor)(-a,"right")},{data:"minor axis",x:l.x,y:l.y,cursor:(0,o.getResizeCursor)(-a,"top")},{data:"minor axis",x:u.x,y:u.y,cursor:(0,o.getResizeCursor)(-a,"bottom")}];return r.createElement(i.EditBar,{positions:p,scale:e.scale,resizeSize:e.resizeSize,onClick:e.onClick,onMouseDown:e.onMouseDown})}},4489:(e,t,n)=>{"use strict";n.r(t),n.d(t,{PolylineEditBar:()=>a});var r=n(3696),o=n(1324),i=n(2286);function a(e){const t=e.points,n=!e.isPolygon&&t.length>2&&(0,o.isSamePoint)(t[0],t[t.length-1]),a=[];if(t.forEach(((r,o)=>{if(!e.isPolygon&&o===t.length-1&&n||a.push({data:[o],x:r.x,y:r.y,cursor:"move"}),!e.midpointDisabled&&o!==t.length-1){const e=t[o+1];a.push({data:[o,o+1],x:(r.x+e.x)/2,y:(r.y+e.y)/2,cursor:"move"})}if(e.isPolygon&&o===t.length-1){const e=t[0];a.push({data:[t.length-1,0],x:(r.x+e.x)/2,y:(r.y+e.y)/2,cursor:"move"})}})),n)for(const e of a)e.data.includes(0)?e.data.push(t.length-1):e.data.includes(t.length-1)&&e.data.push(0);return r.createElement(i.EditBar,{positions:a,scale:e.scale,resizeSize:e.resizeSize,onClick:e.onClick,onMouseDown:e.onMouseDown})}},5634:(e,t,n)=>{"use strict";n.r(t),n.d(t,{ResizeBar:()=>p});var r=n(3696),o=n(9758),i=Object.defineProperty,a=Object.getOwnPropertySymbols,s=Object.prototype.hasOwnProperty,c=Object.prototype.propertyIsEnumerable,l=(e,t,n)=>t in e?i(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,u=(e,t)=>{for(var n in t||(t={}))s.call(t,n)&&l(e,n,t[n]);if(a)for(var n of a(t))c.call(t,n)&&l(e,n,t[n]);return e};function p(e){var t,n,i;const{resizeSize:a}=e,s=null!=(t=e.scale)?t:1,c=(null!=a?a:5)/s,l=1/s,p=c/2,d=c/2-l,f=null!=(n=e.rotate)?n:0,g=null!=(i=e.directions)?i:o.allDirections,h=[];for(const e of o.allDirections)if(g.includes(e)){const t={cursor:(0,o.getResizeCursor)(f,e)};e.includes("left")&&(t.left=-p+"px"),e.includes("right")&&(t.right=-d+"px"),e.includes("top")&&(t.top=-p+"px"),e.includes("bottom")&&(t.bottom=-d+"px"),"left"!==e&&"right"!==e&&"center"!==e||(t.top=`calc(50% - ${p}px)`),"top"!==e&&"bottom"!==e&&"center"!==e||(t.left=`calc(50% - ${p}px)`),h.push({direction:e,style:t})}return r.createElement(r.Fragment,null,h.map(((t,n)=>r.createElement("div",{key:n,style:u({width:c+"px",height:c+"px",border:`${l}px solid green`,position:"absolute",backgroundColor:"white",boxSizing:"border-box",pointerEvents:"auto"},t.style),onMouseDown:n=>{var r;null==(r=e.onMouseDown)||r.call(e,n,t.direction)},onClick:n=>{var r;null==(r=e.onClick)||r.call(e,n,t.direction)}}))))}},2800:(e,t,n)=>{"use strict";n.r(t),n.d(t,{RotationBar:()=>o});var r=n(3696);function o(e){var t,n,o;const i=null!=(t=e.scale)?t:1,a=(null!=(n=e.rotateStickLength)?n:40)/i,s=1/i,c=(null!=(o=e.rotateCircleSize)?o:10)/i;return r.createElement(r.Fragment,null,r.createElement("div",{style:{left:`calc(50% - ${s/2}px)`,top:-a+"px",width:Math.max(s,1)+"px",height:a+"px",position:"absolute",boxSizing:"border-box",backgroundColor:"green"}}),r.createElement("div",{style:{left:`calc(50% - ${s/2+c/2}px)`,top:-a-c+"px",width:c+"px",height:c+"px",position:"absolute",border:`${Math.max(s,1)}px solid green`,backgroundColor:"white",borderRadius:c/2+"px",cursor:"grab",pointerEvents:"auto"},onMouseDown:e.onMouseDown}))}},2607:(e,t,n)=>{"use strict";n.r(t),n.d(t,{renderEquation:()=>p,renderExpression:()=>d});var r=n(3031),o=n(8905),i=Object.defineProperty,a=Object.getOwnPropertySymbols,s=Object.prototype.hasOwnProperty,c=Object.prototype.propertyIsEnumerable,l=(e,t,n)=>t in e?i(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,u=(e,t)=>{for(var n in t||(t={}))s.call(t,n)&&l(e,n,t[n]);if(a)for(var n of a(t))c.call(t,n)&&l(e,n,t[n]);return e};function p(e,t,n={}){const r=u(u({},f),n),{children:i,render:a,font:s}=g(e,r.color,r.fontSize,r.fontFamily,r.paddingOperator,r.keepBinaryExpressionOrder),c=a(t.left),l=a(t.right);let p;if(c&&l){const t=" = ",n=(0,o.getTextSizeFromCache)(s,t);if(n){const o=c.size.width+n.width+l.size.width,a=Math.max(c.size.height,n.height,l.size.height),s=o+2*r.paddingX,u=a+2*r.paddingY,d=u/2;let f=s/2-o/2;c.render(f+c.size.width/2,d),f+=c.size.width,i.push(e.renderText(f+n.width/2,d,t,r.color,r.fontSize,r.fontFamily,{textBaseline:"middle",textAlign:"center"})),f+=n.width,l.render(f+l.size.width/2,d),p=e.renderResult(i,s,u,{attributes:{style:{width:"100%"}}})}}return p}function d(e,t,n={}){const r=u(u({},f),n),{children:o,render:i}=g(e,r.color,r.fontSize,r.fontFamily,r.paddingOperator,r.keepBinaryExpressionOrder),a=i(t);let s;if(a){const t=a.size.width+2*r.paddingX,n=a.size.height+2*r.paddingY;a.render(t/2,n/2),s=e.renderResult(o,t,n,{attributes:{style:{width:"100%"}}})}return s}const f={color:0,fontSize:20,fontFamily:"monospace",paddingX:10,paddingY:10,paddingOperator:5,keepBinaryExpressionOrder:!1};function g(e,t,n,i,a,s){const c=[],l=`${n}px ${i}`,u=(p,d=Number.MAX_SAFE_INTEGER,f=1,g=!1)=>{const h=n*f,m=1===f?l:`${h}px ${i}`;if("BinaryExpression"===p.type){const n="/"===p.operator||"**"===p.operator&&"NumericLiteral"===p.right.type&&.5===p.right.value?Number.MAX_SAFE_INTEGER:r.priorizedBinaryOperators.findIndex((e=>e.includes(p.operator))),l=u(p.left,n,f),g=u(p.right,"+"===p.operator||"*"===p.operator?n:n-.1,"**"===p.operator?.75*f:f);if(l&&g){if("**"===p.operator){if("NumericLiteral"===p.right.type&&.5===p.right.value){const n=l.size.width+2*a,r=l.size.height+a;return{size:{width:n,height:r},render(o,i){l.render(o+a,i+a/2),c.push(e.renderPolyline([{x:o+n/2,y:i-r/2},{x:o-n/2+2*a,y:i-r/2},{x:o-n/2+a,y:i+r/2},{x:o-n/2,y:i+r/2-a}],{strokeColor:t,strokeWidth:1}))}}}const n=l.size.width+g.size.width,r=l.size.height+g.size.height/2;return{size:{width:n,height:r},render(e,t){l.render(e-n/2+l.size.width/2,t+r/2-l.size.height/2-g.size.height/4),g.render(e-n/2+l.size.width+g.size.width/2,t-r/2+g.size.height/2)}}}if("/"===p.operator){let r=Math.max(l.size.width,g.size.width)+2*a;const s=l.size.height+2*a+g.size.height;let u;const p=Math.max(s,h);return n>d&&(u=(0,o.getTextSizeFromCache)(`${p}px ${i}`,"(")),u&&(r+=2*u.width),{size:{width:r,height:s},render(n,o){var d;o=o-s/2+l.size.height+a,u&&c.push(e.renderText(n-r/2+u.width/2,o,"(",t,p,i,{textBaseline:"middle",textAlign:"center"})),l.render(n,o-a-l.size.height/2);const f=null!=(d=null==u?void 0:u.width)?d:0;c.push(e.renderPolyline([{x:n-r/2+f,y:o},{x:n+r/2-f,y:o}],{strokeColor:t,strokeWidth:1})),g.render(n,o+a+g.size.height/2),u&&c.push(e.renderText(n+r/2-u.width/2,o,")",t,p,i,{textBaseline:"middle",textAlign:"center"}))}}}const r="*"===p.operator?"":p.operator,u=(0,o.getTextSizeFromCache)(m,r);if(u){let p=l.size.width+u.width+g.size.width+a*(u.width?2:0);const f=Math.max(l.size.height,u.height,g.size.height);let m;const y=Math.max(f,h);return(n>d||n===d&&s)&&(m=(0,o.getTextSizeFromCache)(`${y}px ${i}`,"(")),m&&(p+=2*m.width),{size:{width:p,height:f},render(n,o){let s=n-p/2;m&&(c.push(e.renderText(s+m.width/2,o,"(",t,y,i,{textBaseline:"middle",textAlign:"center"})),s+=m.width),l.render(s+l.size.width/2,o),s+=l.size.width,u.width&&(s+=a,c.push(e.renderText(s+u.width/2,o,r,t,h,i,{textBaseline:"middle",textAlign:"center"})),s+=u.width+a),g.render(s+g.size.width/2,o),m&&(s+=g.size.width,c.push(e.renderText(s+m.width/2,o,")",t,y,i,{textBaseline:"middle",textAlign:"center"})))}}}}return}if("UnaryExpression"===p.type){const n=(0,o.getTextSizeFromCache)(l,p.operator),r=u(p.argument,-1,f);if(n&&r){let a=n.width+r.size.width;const s=Math.max(n.height,r.size.height);let l;const u=Math.max(s,h);return d<=1&&(l=(0,o.getTextSizeFromCache)(`${u}px ${i}`,"(")),l&&(a+=2*l.width),{size:{width:a,height:s},render(o,s){var d;l&&c.push(e.renderText(o-a/2+l.width/2,s,"(",t,u,i,{textBaseline:"middle",textAlign:"center"}));const f=null!=(d=null==l?void 0:l.width)?d:0;c.push(e.renderText(o-a/2+n.width/2+f,s,p.operator,t,h,i,{textBaseline:"middle",textAlign:"center"})),r.render(o-a/2+n.width+r.size.width/2+f,s),l&&c.push(e.renderText(o+a/2-l.width/2,s,")",t,u,i,{textBaseline:"middle",textAlign:"center"}))}}}return}let y;if("Identifier"===p.type){if(!g&&p.name.length>1){const e=u({type:"Identifier",name:p.name[0]},void 0,f),t=u({type:"Identifier",name:p.name.substring(1)},void 0,.75*f,!0);if(e&&t){const n=e.size.width+t.size.width,r=e.size.height+t.size.height/2;return{size:{width:n,height:r},render(o,i){e.render(o-n/2+e.size.width/2,i-r/2+e.size.height/2+t.size.height/4),t.render(o-n/2+e.size.width+t.size.width/2,i+r/2-t.size.height/2)}}}}y=p.name}else"NumericLiteral"===p.type&&(y=p.value.toString());if(y){const n=(0,o.getTextSizeFromCache)(l,y);if(n){const r=y;return{size:n,render:(n,o)=>c.push(e.renderText(n,o,r,t,h,i,{textBaseline:"middle",textAlign:"center"}))}}}};return{font:l,children:c,render:u}}},123:(e,t,n)=>{"use strict";n.r(t),n.d(t,{divide:()=>a,divideFactors:()=>l,expressionToFactors:()=>g,extractFactors:()=>s,factorToExpression:()=>y,factorsToEquationParams:()=>w,factorsToExpression:()=>m,optimizeFactor:()=>E,optimizeFactors:()=>C,powerFactor:()=>v});var r=n(6072),o=n(2792),i=Math.pow;function a(e,t){const n=g(e);if(!n)return;const r=g(t);if(!r)return;const o=l(n,r);return o?m(o):void 0}function s(e,t){let n;for(const r of e){const e=c(r,t);if(!e)return;if(n){const t={variables:{},constant:P(n.constant,e.constant)};for(const[r,o]of Object.entries(e.variables)){const e=n.variables[r];e&&(t.variables[r]=Math.min(e,o))}n=t}else n=e}if(n&&(Object.keys(n.variables).length>0||n.constant>1)){const r={constant:i(n.constant,1/t),variables:[]},o={constant:n.constant,variables:[]};for(const[e,i]of Object.entries(n.variables))r.variables.push(...new Array(i).fill(e)),o.variables.push(...new Array(i*t).fill(e));const a=l(e,[o]);if(!a)return;return{base:r,factors:a}}}function c(e,t){var n,r;const o=new Map;for(const t of e.variables){if("string"!=typeof t)return;o.set(t,(null!=(n=o.get(t))?n:0)+1)}const i=null!=(r=e.constant)?r:1,a={variables:{},constant:Number.isInteger(i)&&i?Math.abs(i):1};for(const[e,n]of o)n>=t&&(a.variables[e]=Math.floor(n/t));if(Object.keys(a.variables).length>0)return a}function l(e,t){for(const n of e){const r=f(n,t[0]);if(r){const n=d(e,t.map((e=>x(e,r))));if(0===n.length)return[r];if(n.length>e.length)continue;const o=l(n,t);if(!o)continue;return[r,...o]}}}function u(e,t){var n,r;const o=f(e,t);if(o&&0===o.variables.length)return(null!=(n=e.constant)?n:1)-(null!=(r=t.constant)?r:1)}function p(e,t){var n,r;const o=f(e,t);if(o&&0===o.variables.length)return(null!=(n=e.constant)?n:1)+(null!=(r=t.constant)?r:1)}function d(e,t){var n;const r=[...e];for(const e of t){let t=!1;for(let n=0;n=0)o.splice(t,1);else{for(let n=0;nb(e)))),[...t,...n]}const t=h(e);if(t)return[t]}function h(e){if("NumericLiteral"===e.type)return{constant:e.value,variables:[]};if("Identifier"===e.type)return{variables:[e.name]};if("UnaryExpression"===e.type&&"-"===e.operator){const t=h(e.argument);if(!t)return;return b(t)}if("BinaryExpression"===e.type){if("*"===e.operator){const t=h(e.left);if(!t)return;const n=h(e.right);if(!n)return;return x(t,n)}if("/"===e.operator){const t=h(e.left);if(!t)return;const n=h(e.right);if(!n)return;return f(t,n)||(t.variables.push({value:[n],power:-1}),t)}if("**"===e.operator){if("NumericLiteral"===e.right.type&&(e.right.value<1||!Number.isInteger(e.right.value))){const t=g(e.left);if(!t)return;return{variables:[{value:t,power:e.right.value}]}}const t=h(e.left);if(!t)return;if("NumericLiteral"!==e.right.type)return;if(!Number.isInteger(e.right.value))return;if(e.right.value<1)return;return v(t,e.right.value)}}return"CallExpression"===e.type?{variables:[(0,r.printMathStyleExpression)(e)]}:void 0}function m(e){if(0===e.length)return{type:"NumericLiteral",value:0};if(1===e.length)return y(e[0]);const[t,...n]=e;return{type:"BinaryExpression",left:y(t),operator:"+",right:m(n)}}function y(e){var t;if(0===e.variables.length)return{type:"NumericLiteral",value:null!=(t=e.constant)?t:1};if(void 0!==e.constant)return{type:"BinaryExpression",left:{type:"NumericLiteral",value:e.constant},operator:"*",right:y({variables:e.variables})};if(1===e.variables.length){const t=e.variables[0];return"string"!=typeof t?{type:"BinaryExpression",left:m(t.value),operator:"**",right:{type:"NumericLiteral",value:t.power}}:{type:"Identifier",name:t}}const[n,...r]=[...e.variables];return{type:"BinaryExpression",left:y({variables:[n]}),operator:"*",right:y({variables:r})}}function v(e,t){let n=1;const r=[];for(let o=0;o"string"==typeof e));let n=e.constant||1;for(const r of e.variables)if("string"!=typeof r){if(-1===r.power){for(const e of r.value){e.constant&&(n/=e.constant);for(const n of e.variables){const e=t.indexOf(n);e>=0?t.splice(e,1):t.push({power:-1,value:[{variables:[n]}]})}}continue}let e=!1;for(const a of r.value){const s=t.find((e=>"string"!=typeof e&&(0,o.deepEquals)(r.value,e.value)));if(s&&"string"!=typeof s){a.constant&&(n*=i(a.constant,r.power)),s.power+=r.power,e=!0;break}}e||t.push(r)}return{variables:t,constant:1===n?void 0:n}}function P(e,t){return e<=1||t<=1?1:e===t?e:e>t?P(e%t,t):P(e,t%e)}function w(e,t){const n=[];for(const r of e){if(r.variables.some((e=>e!==t)))return;const e=r.variables.length;for(let t=n.length;t<=e;t++)n.push(0);n[e]+=r.constant||1}return n.reverse()}},4546:(e,t,n)=>{"use strict";n.r(t);var r=n(4281),o={};for(const e in r)"default"!==e&&(o[e]=()=>r[e]);n.d(t,o);var i=n(123);o={};for(const e in i)"default"!==e&&(o[e]=()=>i[e]);n.d(t,o);var a=n(6277);o={};for(const e in a)"default"!==e&&(o[e]=()=>a[e]);n.d(t,o);var s=n(7492);o={};for(const e in s)"default"!==e&&(o[e]=()=>s[e]);n.d(t,o)},6277:(e,t,n)=>{"use strict";n.r(t),n.d(t,{expressionHasVariable:()=>d,getReverseOperator:()=>x,iterateEquation:()=>p,iterateExpression:()=>u,optimizeEquation:()=>f,optimizeExpression:()=>v,printEquation:()=>g});var r=n(3031),o=n(2792),i=n(123),a=(e,t)=>(t=Symbol[e])?t:Symbol.for("Symbol."+e),s=Math.pow,c=function(e,t){this[0]=e,this[1]=t},l=e=>{var t,n=e[a("asyncIterator")],r=!1,o={};return null==n?(n=e[a("iterator")](),t=e=>o[e]=t=>n[e](t)):(n=n.call(e),t=e=>o[e]=t=>{if(r){if(r=!1,"throw"===e)throw t;return t}return r=!0,{done:!1,value:new c(new Promise((r=>{var o=n[e](t);o instanceof Object||(()=>{throw TypeError("Object expected")})(),r(o)})),1)}}),o[a("iterator")]=()=>o,t("next"),"throw"in n?t("throw"):o.throw=e=>{throw e},"return"in n&&t("return"),o};function*u(e){if(yield e,"BinaryExpression"===e.type)yield*l(u(e.left)),yield*l(u(e.right));else if("UnaryExpression"===e.type)yield*l(u(e.argument));else if("CallExpression"===e.type)for(const t of e.arguments)"SpreadElement"!==t.type&&(yield*l(u(t)))}function*p(e){yield*l(u(e.left)),yield*l(u(e.right))}function d(e,t){for(const n of u(e))if("Identifier"===n.type&&n.name===t)return!0;return!1}function f(e,t){return e.left=v(e.left,t),e.right=v(e.right,t),e}function g(e,t){return(0,r.printExpression)(e.left,t)+" = "+(0,r.printExpression)(e.right,t)}function h(e,t){return e.type===t.type&&("BinaryExpression"===e.type&&"BinaryExpression"===t.type?e.operator===t.operator&&h(e.left,t.left)&&h(e.right,t.right):"UnaryExpression"===e.type&&"UnaryExpression"===t.type?e.operator===t.operator&&h(e.argument,t.argument):"NumericLiteral"===e.type&&"NumericLiteral"===t.type?e.value===t.value:"Identifier"===e.type&&"Identifier"===t.type?e.name===t.name:"CallExpression"===e.type&&"CallExpression"===t.type&&h(e.callee,t.callee)&&e.arguments.length===t.arguments.length&&e.arguments.every(((e,n)=>h(e,t.arguments[n]))))}function m(e,t){return"UnaryExpression"===e.type?m(e.argument,t):"UnaryExpression"===t.type?m(e,t.argument):"BinaryExpression"===e.type&&"BinaryExpression"===t.type?!!m(e.left,t.left)||!!h(e,t)&&m(e.right,t.right):"Identifier"===e.type&&"Identifier"===t.type&&e.name>t.name}function y(e){return"UnaryExpression"===e.type&&"NumericLiteral"===e.argument.type||"NumericLiteral"===e.type}function v(e,t){const n=e=>{if("BinaryExpression"===e.type){if(e.left=n(e.left),e.right=n(e.right),"NumericLiteral"===e.left.type&&"NumericLiteral"===e.right.type){let t;if("+"===e.operator)t=e.left.value+e.right.value;else if("-"===e.operator)t=e.left.value-e.right.value;else if("*"===e.operator)t=e.left.value*e.right.value;else if("/"===e.operator)t=e.left.value/e.right.value;else{if("**"!==e.operator)throw new Error(`Unsupported operator: ${e.operator}`);t=s(e.left.value,e.right.value)}return{type:"NumericLiteral",value:t}}if("NumericLiteral"===e.left.type&&(0,o.isZero)(e.left.value)){if("+"===e.operator)return e.right;if("-"===e.operator)return n({type:"UnaryExpression",operator:"-",argument:e.right});if("*"===e.operator||"/"===e.operator)return e.left}if("NumericLiteral"===e.right.type&&(0,o.isZero)(e.right.value)){if("+"===e.operator||"-"===e.operator)return e.left;if("*"===e.operator)return e.right;if("**"===e.operator)return{type:"NumericLiteral",value:1}}if("NumericLiteral"===e.right.type&&1===e.right.value&&("*"===e.operator||"/"===e.operator||"**"===e.operator))return e.left;if("NumericLiteral"===e.left.type&&1===e.left.value&&"*"===e.operator)return e.right;if("NumericLiteral"===e.right.type&&-1===e.right.value&&("*"===e.operator||"/"===e.operator))return{type:"UnaryExpression",argument:e.left,operator:"-"};if("NumericLiteral"===e.left.type&&-1===e.left.value&&"*"===e.operator)return{type:"UnaryExpression",argument:e.right,operator:"-"};if(h(e.left,e.right)){if("+"===e.operator)return n({type:"BinaryExpression",left:{type:"NumericLiteral",value:2},operator:"*",right:e.left});if("-"===e.operator)return{type:"NumericLiteral",value:0};if("*"===e.operator)return n({type:"BinaryExpression",left:e.left,operator:"**",right:{type:"NumericLiteral",value:2}});if("/"===e.operator)return{type:"NumericLiteral",value:1}}if("UnaryExpression"===e.left.type&&"-"===e.left.operator&&h(e.left.argument,e.right)){if("+"===e.operator)return{type:"NumericLiteral",value:0};if("-"===e.operator)return n({type:"BinaryExpression",left:{type:"NumericLiteral",value:-2},operator:"*",right:n(e.left.argument)});if("/"===e.operator)return{type:"NumericLiteral",value:-1}}if("-"===e.operator&&"NumericLiteral"===e.right.type)return n({type:"BinaryExpression",left:e.left,operator:"+",right:{type:"NumericLiteral",value:-e.right.value}});if("/"===e.operator&&"NumericLiteral"===e.right.type){const t=(0,i.expressionToFactors)(e.left);if(t){const r=e.right.value;return t.forEach((e=>{var t;e.constant=(null!=(t=e.constant)?t:1)/r})),n((0,i.factorsToExpression)(t))}return{type:"BinaryExpression",left:e.left,operator:"*",right:{type:"NumericLiteral",value:1/e.right.value}}}if("-"===e.operator&&"UnaryExpression"===e.right.type&&"-"===e.right.operator)return n({type:"BinaryExpression",operator:"+",left:e.left,right:n(e.right.argument)});if("-"===e.operator&&"BinaryExpression"===e.right.type&&"*"===e.right.operator&&"NumericLiteral"===e.right.left.type)return n({type:"BinaryExpression",left:e.left,operator:"+",right:n({type:"BinaryExpression",left:{type:"NumericLiteral",value:-e.right.left.value},operator:e.right.operator,right:n(e.right.right)})});if("BinaryExpression"===e.left.type){if("-"===e.operator&&"+"===e.left.operator&&h(e.left.right,e.right))return n(e.left.left);if("-"===e.operator&&"-"===e.left.operator&&h(e.left.left,e.right))return n({type:"UnaryExpression",operator:"-",argument:n(e.left.right)});if("+"===e.operator&&"+"===e.left.operator&&"UnaryExpression"===e.left.right.type&&"-"===e.left.right.operator&&h(e.left.right.argument,e.right))return n(e.left.left);if("+"===e.operator&&"-"===e.left.operator&&h(e.left.right,e.right))return n(e.left.left);if("+"===e.operator&&"+"===e.left.operator&&"UnaryExpression"===e.right.type&&"-"===e.right.operator&&h(e.left.right,e.right.argument))return n(e.left.left);if(!("+"!==e.operator&&"-"!==e.operator||"+"!==e.left.operator&&"-"!==e.left.operator||"NumericLiteral"!==e.left.right.type||"NumericLiteral"!==e.right.type)){const t=e.left.right.value*("-"===e.left.operator?-1:1)+e.right.value*("-"===e.operator?-1:1);return n(0===t?e.left.left:{type:"BinaryExpression",left:n(e.left.left),operator:t>0?"+":"-",right:{type:"NumericLiteral",value:t>0?t:-t}})}if(("+"===e.operator||"*"===e.operator)&&e.left.operator===e.operator&&"NumericLiteral"===e.left.left.type&&"NumericLiteral"===e.right.type)return n({type:"BinaryExpression",operator:e.operator,left:{type:"NumericLiteral",value:"*"===e.operator?e.left.left.value*e.right.value:e.left.left.value+e.right.value},right:n(e.left.right)});if(("+"===e.operator||"*"===e.operator)&&e.left.operator===e.operator&&"NumericLiteral"===e.left.right.type&&"NumericLiteral"===e.right.type)return n({type:"BinaryExpression",operator:e.operator,left:{type:"NumericLiteral",value:"*"===e.operator?e.left.right.value*e.right.value:e.left.right.value+e.right.value},right:n(e.left.left)});if("+"===e.operator&&"+"===e.left.operator&&"NumericLiteral"===e.left.left.type&&"BinaryExpression"===e.left.right.type&&"*"===e.left.right.operator&&"NumericLiteral"===e.left.right.left.type&&h(e.left.right.right,e.right))return n({type:"BinaryExpression",left:e.left.left,operator:"+",right:n({type:"BinaryExpression",left:{type:"NumericLiteral",value:e.left.right.left.value+1},operator:"*",right:n(e.left.right.right)})});if(("+"===e.operator||"-"===e.operator)&&e.left.operator===e.operator&&h(e.left.right,e.right))return n({type:"BinaryExpression",left:n(e.left.left),operator:e.operator,right:n({type:"BinaryExpression",left:{type:"NumericLiteral",value:2},operator:"*",right:n(e.left.right)})});if("-"===e.operator&&"+"===e.left.operator&&"NumericLiteral"===e.left.left.type&&"BinaryExpression"===e.left.right.type&&"*"===e.left.right.operator&&"NumericLiteral"===e.left.right.left.type&&h(e.left.right.right,e.right))return n({type:"BinaryExpression",operator:"+",left:e.left.left,right:n({type:"BinaryExpression",left:{type:"NumericLiteral",value:e.left.right.left.value-1},operator:"*",right:e.right})});if("+"===e.operator&&"+"===e.left.operator&&"NumericLiteral"===e.left.left.type&&"BinaryExpression"===e.left.right.type&&"*"===e.left.right.operator&&"NumericLiteral"===e.left.right.left.type&&"BinaryExpression"===e.right.type&&"*"===e.right.operator&&"NumericLiteral"===e.right.left.type&&h(e.left.right.right,e.right.right))return n({type:"BinaryExpression",left:e.left.left,operator:"+",right:n({type:"BinaryExpression",left:{type:"NumericLiteral",value:e.left.right.left.value+e.right.left.value},operator:"*",right:n(e.left.right.right)})});if("+"===e.operator&&"-"===e.left.operator&&"NumericLiteral"===e.left.left.type&&"BinaryExpression"===e.right.type&&"*"===e.right.operator&&"NumericLiteral"===e.right.left.type&&h(e.left.right,e.right.right))return n({type:"BinaryExpression",left:e.left.left,operator:"+",right:n({type:"BinaryExpression",left:{type:"NumericLiteral",value:-1+e.right.left.value},operator:"*",right:n(e.right.right)})});if(!("+"!==e.operator&&"-"!==e.operator||"+"!==e.left.operator&&"-"!==e.left.operator||"NumericLiteral"!==e.left.right.type))return n({type:"BinaryExpression",left:n({type:"BinaryExpression",left:n(e.left.left),operator:e.operator,right:e.right}),operator:e.left.operator,right:e.left.right});if(("+"===e.operator||"-"===e.operator)&&t&&("+"===e.left.operator||"-"===e.left.operator)&&t(e.right)&&t(e.left.left)&&!t(e.left.right))return n({type:"BinaryExpression",operator:e.left.operator,left:n({type:"BinaryExpression",operator:e.operator,left:n(e.left.left),right:e.right}),right:n(e.left.right)});if(("+"===e.operator||"-"===e.operator)&&t&&"-"===e.left.operator&&t(e.right)&&t(e.left.right)&&!t(e.left.left))return n({type:"BinaryExpression",left:n({type:"BinaryExpression",left:n({type:"UnaryExpression",operator:"-",argument:n(e.left.right)}),operator:e.operator,right:e.right}),operator:"+",right:n(e.left.left)});if(("*"===e.operator||"/"===e.operator)&&"BinaryExpression"===e.left.type&&e.left.operator===e.operator&&(!t||!t(e.left.right))&&m(e.left.right,e.right))return n({type:"BinaryExpression",left:{type:"BinaryExpression",left:n(e.left.left),operator:e.operator,right:e.right},operator:e.left.operator,right:n(e.left.right)});if(!("*"!==e.operator||"BinaryExpression"!==e.left.type||"/"!==e.left.operator||t&&t(e.left.right)))return n({type:"BinaryExpression",left:{type:"BinaryExpression",left:n(e.left.left),operator:e.operator,right:e.right},operator:e.left.operator,right:n(e.left.right)});if(("+"===e.operator||"-"===e.operator)&&"BinaryExpression"===e.left.type&&("+"===e.left.operator||"-"===e.left.operator)&&(!t||!t(e.left.right))&&m(e.left.right,e.right))return n({type:"BinaryExpression",left:{type:"BinaryExpression",left:n(e.left.left),operator:e.operator,right:e.right},operator:e.left.operator,right:n(e.left.right)})}if("BinaryExpression"===e.right.type){if("+"===e.operator&&("+"===e.right.operator||"-"===e.right.operator))return n({type:"BinaryExpression",operator:e.right.operator,left:n({type:"BinaryExpression",operator:"+",left:e.left,right:n(e.right.left)}),right:n(e.right.right)});if("-"===e.operator&&("+"===e.right.operator||"-"===e.right.operator))return n({type:"BinaryExpression",operator:x(e.right.operator),left:n({type:"BinaryExpression",operator:"-",left:e.left,right:n(e.right.left)}),right:n(e.right.right)});if("*"===e.operator&&("*"===e.right.operator||"/"===e.right.operator))return n({type:"BinaryExpression",operator:e.right.operator,left:n({type:"BinaryExpression",operator:"*",left:e.left,right:n(e.right.left)}),right:n(e.right.right)})}if(("+"===e.operator||"*"===e.operator)&&(!t||t(e.left)&&t(e.right)||!t(e.left)&&!t(e.right))&&m(e.left,e.right))return n({type:"BinaryExpression",operator:e.operator,left:e.right,right:e.left});if("*"===e.operator&&t&&t(e.left)&&!t(e.right))return n({type:"BinaryExpression",left:e.right,operator:e.operator,right:e.left});if("+"===e.operator&&t&&!t(e.left)&&t(e.right))return n({type:"BinaryExpression",left:e.right,operator:e.operator,right:e.left});if("UnaryExpression"===e.right.type&&("*"===e.operator||"/"===e.operator)&&"-"===e.right.operator)return n({type:"UnaryExpression",operator:e.right.operator,argument:n({type:"BinaryExpression",left:e.left,right:n(e.right.argument),operator:e.operator})});if("UnaryExpression"===e.left.type&&("*"===e.operator||"/"===e.operator)&&"-"===e.left.operator)return n({type:"UnaryExpression",operator:e.left.operator,argument:n({type:"BinaryExpression",left:n(e.left.argument),right:e.right,operator:e.operator})});if("+"===e.operator||"-"===e.operator){if("BinaryExpression"===e.right.type&&"/"===e.right.operator&&!y(e.right.right))return n({type:"BinaryExpression",left:n({type:"BinaryExpression",left:n({type:"BinaryExpression",left:e.left,operator:"*",right:n(e.right.right)}),operator:e.operator,right:n(e.right.left)}),operator:"/",right:n(e.right.right)});if("BinaryExpression"===e.left.type&&"/"===e.left.operator&&!y(e.left.right))return n({type:"BinaryExpression",left:n({type:"BinaryExpression",left:n(e.left.left),operator:e.operator,right:n({type:"BinaryExpression",left:n(e.left.right),operator:"*",right:e.right})}),operator:"/",right:n(e.left.right)})}if("*"===e.operator){if(!(t&&t(e.right)||"BinaryExpression"!==e.left.type||"+"!==e.left.operator&&"-"!==e.left.operator))return n({type:"BinaryExpression",left:n({type:"BinaryExpression",left:n(e.left.left),operator:"*",right:e.right}),operator:e.left.operator,right:n({type:"BinaryExpression",left:n(e.left.right),operator:"*",right:e.right})});if(!(t&&t(e.left)||"BinaryExpression"!==e.right.type||"+"!==e.right.operator&&"-"!==e.right.operator))return n({type:"BinaryExpression",left:n({type:"BinaryExpression",left:e.left,operator:"*",right:n(e.right.left)}),operator:e.right.operator,right:n({type:"BinaryExpression",left:e.left,operator:"*",right:n(e.right.right)})})}if(t&&("+"===e.operator||"-"===e.operator)){if("BinaryExpression"===e.left.type&&"*"===e.left.operator&&"BinaryExpression"===e.right.type&&"*"===e.right.operator&&h(e.left.right,e.right.right)&&!t(e.left.left)&&t(e.left.right)&&!t(e.right.left))return n({type:"BinaryExpression",left:n({type:"BinaryExpression",left:n(e.left.left),right:n(e.right.left),operator:e.operator}),operator:"*",right:n(e.left.right)});if("BinaryExpression"===e.left.type&&"*"===e.left.operator&&!t(e.left.left)&&t(e.left.right)&&h(e.left.right,e.right))return n({type:"BinaryExpression",left:n({type:"BinaryExpression",left:n(e.left.left),right:{type:"NumericLiteral",value:1},operator:e.operator}),operator:"*",right:n(e.left.right)});if("BinaryExpression"===e.right.type&&"*"===e.right.operator&&!t(e.right.left)&&t(e.right.right)&&h(e.left,e.right.right))return n({type:"BinaryExpression",left:n({type:"BinaryExpression",left:{type:"NumericLiteral",value:1},right:n(e.right.left),operator:e.operator}),operator:"*",right:e.left});if("BinaryExpression"===e.right.type&&"*"===e.right.operator&&"UnaryExpression"===e.left.type&&"-"===e.left.operator&&!t(e.right.left)&&t(e.right.right)&&h(e.left.argument,e.right.right))return n({type:"BinaryExpression",left:n({type:"BinaryExpression",left:{type:"NumericLiteral",value:-1},right:n(e.right.left),operator:e.operator}),operator:"*",right:n(e.left.argument)})}if(t&&"**"===e.operator&&!t(e.right)&&"BinaryExpression"===e.left.type&&("*"===e.left.operator||"/"===e.left.operator)&&(t(e.left.left)&&!t(e.left.right)||!t(e.left.left)&&t(e.left.right)))return n({type:"BinaryExpression",left:n({type:"BinaryExpression",left:n(e.left.left),operator:"**",right:e.right}),operator:e.left.operator,right:n({type:"BinaryExpression",left:n(e.left.right),operator:"**",right:e.right})});if("**"===e.operator&&"NumericLiteral"===e.right.type&&2===e.right.value&&"BinaryExpression"===e.left.type&&("+"===e.left.operator||"-"===e.left.operator)){const t=n(e.left.left),r=n(e.left.right);return n({type:"BinaryExpression",left:n({type:"BinaryExpression",left:n({type:"BinaryExpression",left:t,operator:"**",right:e.right}),operator:e.left.operator,right:n({type:"BinaryExpression",left:n({type:"BinaryExpression",left:e.right,operator:"*",right:t}),operator:"*",right:r})}),operator:"+",right:n({type:"BinaryExpression",left:r,operator:"**",right:e.right})})}if("/"===e.operator){const t=(0,i.divide)(e.left,e.right);if(t)return n(t)}if("/"===e.operator&&"BinaryExpression"===e.left.type&&"/"===e.left.operator){const t=(0,i.divide)(e.left.left,e.right);if(t)return n({type:"BinaryExpression",left:n(t),operator:"/",right:n(e.left.right)})}if("+"===e.operator||"-"===e.operator){const t=(0,i.expressionToFactors)(e);if(t){const e=(0,i.optimizeFactors)(t);if(e.length0&&e.right.value<1){const t=1/e.right.value;if(Number.isInteger(t)){const r=(0,i.expressionToFactors)(e.left);if(r){const o=(0,i.extractFactors)(r,t);if(o)return n({type:"BinaryExpression",left:(0,i.factorToExpression)(o.base),operator:"*",right:n({type:"BinaryExpression",left:(0,i.factorsToExpression)(o.factors),operator:"**",right:e.right})})}}}if("/"===e.operator&&"BinaryExpression"===e.right.type&&("+"===e.right.operator||"-"===e.right.operator)){const t=(0,i.expressionToFactors)(e.right);if(t){const r=(0,i.extractFactors)(t,1);if(r)return n({type:"BinaryExpression",left:n({type:"BinaryExpression",left:e.left,operator:"/",right:(0,i.factorToExpression)(r.base)}),operator:"/",right:(0,i.factorsToExpression)(r.factors)})}}}else if("UnaryExpression"===e.type){if(e.argument=n(e.argument),"-"===e.operator){if("NumericLiteral"===e.argument.type)return{type:"NumericLiteral",value:-e.argument.value};if("UnaryExpression"===e.argument.type&&"-"===e.argument.operator)return n(e.argument.argument);if("BinaryExpression"===e.argument.type&&("+"===e.argument.operator||"-"===e.argument.operator))return n({type:"BinaryExpression",left:n({type:"UnaryExpression",operator:"-",argument:n(e.argument.left)}),operator:x(e.argument.operator),right:n(e.argument.right)});if("BinaryExpression"===e.argument.type&&("*"===e.argument.operator||"/"===e.argument.operator)){if("NumericLiteral"===e.argument.left.type)return n({type:"BinaryExpression",left:n({type:"NumericLiteral",value:-e.argument.left.value}),operator:e.argument.operator,right:n(e.argument.right)});if("NumericLiteral"===e.argument.right.type)return n({type:"BinaryExpression",left:n(e.argument.left),operator:"*",right:n({type:"NumericLiteral",value:-e.argument.right.value})})}}}else if("CallExpression"===e.type&&(e.arguments=e.arguments.map((e=>"SpreadElement"===e.type?e:n(e))),"Identifier"===e.callee.type))if("sin"===e.callee.name){if(1===e.arguments.length){const t=e.arguments[0];if("NumericLiteral"===t.type)return{type:"NumericLiteral",value:Math.sin(t.value)}}}else if("cos"===e.callee.name){if(1===e.arguments.length){const t=e.arguments[0];if("NumericLiteral"===t.type)return{type:"NumericLiteral",value:Math.cos(t.value)}}}else if("tan"===e.callee.name){if(1===e.arguments.length){const t=e.arguments[0];if("NumericLiteral"===t.type)return{type:"NumericLiteral",value:Math.tan(t.value)}}}else if("ln"===e.callee.name){if(1===e.arguments.length){const t=e.arguments[0];if("NumericLiteral"===t.type)return{type:"NumericLiteral",value:Math.log(t.value)}}}else if("exp"===e.callee.name&&1===e.arguments.length){const t=e.arguments[0];if("NumericLiteral"===t.type)return{type:"NumericLiteral",value:Math.exp(t.value)}}return e};return n(e)}function x(e){return"+"===e?"-":"-"===e?"+":"*"===e?"/":"/"===e?"*":e}},7492:(e,t,n)=>{"use strict";n.r(t),n.d(t,{solveQuadraticEquation:()=>o});var r=n(6277);function o(e,t){const n=i(e.left,t);if(n&&n.length>0){n.sort(((e,t)=>t.degree-e.degree));const t=n[0];if(2===t.degree){const r=t.constant;if(2===n.length){const t=n[1];if(1===t.degree)return l(r,t.constant,e.right)}else if(1===n.length)return l(r,{type:"NumericLiteral",value:0},e.right)}else if(1===t.degree)return[{type:"BinaryExpression",left:e.right,operator:"/",right:t.constant}]}}function i(e,t){if("BinaryExpression"===e.type&&("+"===e.operator||"-"===e.operator)){const n=i(e.left,t);if(!n)return;let r=i(e.right,t);if(!r)return;"-"===e.operator&&(r=r.map((e=>c(e))));const o=[...n];for(const e of r){const t=o.find((t=>t.degree===e.degree));t?t.constant={type:"BinaryExpression",left:t.constant,operator:"+",right:e.constant}:o.push(e)}return o}const n=a(e,t);if(n)return[n]}function a(e,t){if("NumericLiteral"===e.type)return{constant:e,degree:0};if(!(0,r.expressionHasVariable)(e,t))return{constant:e,degree:0};if("Identifier"===e.type)return e.name===t?{constant:{type:"NumericLiteral",value:1},degree:1}:{constant:e,degree:0};if("UnaryExpression"===e.type&&"-"===e.operator){const n=a(e.argument,t);if(!n)return;return c(n)}if("BinaryExpression"===e.type){if("*"===e.operator){const n=a(e.left,t);if(!n)return;const r=a(e.right,t);if(!r)return;return s(n,r)}if("**"===e.operator){const n=a(e.left,t);if(!n)return;if("NumericLiteral"!==e.right.type)return;if(!Number.isInteger(e.right.value))return;if(e.right.value<1)return;return{constant:{type:"BinaryExpression",left:n.constant,operator:"**",right:e.right},degree:n.degree*e.right.value}}}}function s(...e){let t,n=0;for(const r of e)t=t?{type:"BinaryExpression",left:t,operator:"*",right:r.constant}:r.constant,n+=r.degree;return{degree:n,constant:t||{type:"NumericLiteral",value:1}}}function c(e){return s(e,{constant:{type:"NumericLiteral",value:-1},degree:0})}function l(e,t,n){return[{type:"BinaryExpression",left:{type:"BinaryExpression",left:{type:"UnaryExpression",operator:"-",argument:t},operator:"+",right:{type:"BinaryExpression",left:{type:"BinaryExpression",left:{type:"BinaryExpression",left:t,operator:"**",right:{type:"NumericLiteral",value:2}},operator:"+",right:{type:"BinaryExpression",left:{type:"BinaryExpression",left:{type:"NumericLiteral",value:4},operator:"*",right:e},operator:"*",right:n}},operator:"**",right:{type:"NumericLiteral",value:.5}}},operator:"/",right:{type:"BinaryExpression",left:{type:"NumericLiteral",value:2},operator:"*",right:e}},{type:"BinaryExpression",left:{type:"BinaryExpression",left:{type:"UnaryExpression",operator:"-",argument:t},operator:"-",right:{type:"BinaryExpression",left:{type:"BinaryExpression",left:{type:"BinaryExpression",left:t,operator:"**",right:{type:"NumericLiteral",value:2}},operator:"+",right:{type:"BinaryExpression",left:{type:"BinaryExpression",left:{type:"NumericLiteral",value:4},operator:"*",right:e},operator:"*",right:n}},operator:"**",right:{type:"NumericLiteral",value:.5}}},operator:"/",right:{type:"BinaryExpression",left:{type:"NumericLiteral",value:2},operator:"*",right:e}}]}},4281:(e,t,n)=>{"use strict";n.r(t),n.d(t,{cloneExpression:()=>w,composeExpression:()=>C,equationHasVariable:()=>m,solveEquation:()=>h,solveEquations:()=>v});var r=n(9292),o=n(6277),i=n(7492),a=Object.defineProperty,s=Object.defineProperties,c=Object.getOwnPropertyDescriptors,l=Object.getOwnPropertySymbols,u=Object.prototype.hasOwnProperty,p=Object.prototype.propertyIsEnumerable,d=(e,t,n)=>t in e?a(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,f=(e,t)=>{for(var n in t||(t={}))u.call(t,n)&&d(e,n,t[n]);if(l)for(var n of l(t))p.call(t,n)&&d(e,n,t[n]);return e},g=(e,t)=>s(e,c(t));function h(e,t){const n=e=>(0,o.expressionHasVariable)(e,t),a=e=>(0,o.optimizeExpression)(e,n),s=e=>{if((0,o.optimizeEquation)(e,n),!n(e.left)){if(!n(e.right))return e;e={left:e.right,right:e.left}}if(!n(e.right)){if("UnaryExpression"===e.left.type&&"-"===e.left.operator)return s({left:a(e.left.argument),right:a({type:"UnaryExpression",argument:e.right,operator:e.left.operator})});if("BinaryExpression"===e.left.type){if(n(e.left.left)&&!n(e.left.right)){const t="**"===e.left.operator?{type:"BinaryExpression",left:{type:"NumericLiteral",value:1},operator:"/",right:e.left.right}:e.left.right;return"**"===e.left.operator&&"NumericLiteral"===e.left.right.type&&e.left.right.value%2==0?[...(0,r.iterateItemOrArray)(s({left:a(e.left.left),right:a({type:"BinaryExpression",left:e.right,right:a(t),operator:(0,o.getReverseOperator)(e.left.operator)})})),...(0,r.iterateItemOrArray)(s({left:a(e.left.left),right:a({type:"UnaryExpression",operator:"-",argument:{type:"BinaryExpression",left:e.right,right:a(t),operator:(0,o.getReverseOperator)(e.left.operator)}})}))]:s({left:a(e.left.left),right:a({type:"BinaryExpression",left:e.right,right:a(t),operator:(0,o.getReverseOperator)(e.left.operator)})})}if(n(e.left.right)&&!n(e.left.left))return"-"===e.left.operator||"/"===e.left.operator?s({left:a(e.left.right),right:a({type:"BinaryExpression",left:a(e.left.left),right:e.right,operator:e.left.operator})}):s({left:a(e.left.right),right:a({type:"BinaryExpression",left:e.right,right:a(e.left.left),operator:(0,o.getReverseOperator)(e.left.operator)})});if("NumericLiteral"===e.right.type&&0===e.right.value&&"/"===e.left.operator)return s({left:a(e.left.left),right:e.right});if("NumericLiteral"===e.right.type&&0===e.right.value&&"*"===e.left.operator)return[...(0,r.iterateItemOrArray)(s({left:a(e.left.left),right:e.right})),...(0,r.iterateItemOrArray)(s({left:a(e.left.right),right:e.right}))];if("+"===e.left.operator||"-"===e.left.operator||"*"===e.left.operator){const n=(0,i.solveQuadraticEquation)(e,t);if(n)return n.map((e=>Array.from((0,r.iterateItemOrArray)(s({left:{type:"Identifier",name:t},right:a(e)}))).flat())).flat()}}return e}return"BinaryExpression"===e.right.type?"/"===e.right.operator?s({left:a({type:"BinaryExpression",left:e.left,right:a(e.right.right),operator:"*"}),right:a(e.right.left)}):s({left:{type:"BinaryExpression",left:e.left,operator:"-",right:e.right},right:{type:"NumericLiteral",value:0}}):"Identifier"===e.right.type?s({left:{type:"BinaryExpression",left:e.left,operator:"-",right:e.right},right:{type:"NumericLiteral",value:0}}):"UnaryExpression"===e.right.type?s({left:{type:"BinaryExpression",left:e.left,operator:"+",right:a(e.right.argument)},right:{type:"NumericLiteral",value:0}}):e};return Array.from((0,r.iterateItemOrArray)(s(e)))}function m(e,t){return(0,o.expressionHasVariable)(e.left,t)||(0,o.expressionHasVariable)(e.right,t)}function y(e){const t=new Set;for(const n of(0,o.iterateEquation)(e))"Identifier"===n.type&&t.add(n.name);return Array.from(t)}function v(e,t,n={}){if(!t){t=new Set;for(const n of e)for(const e of y(n))t.add(e)}const r=[],i=t,a=()=>{let t=e.length;for(;;){const a=[];for(let t=0;ti.has(e)));if(c.length>0){if(1===c.length){(0,o.optimizeEquation)(s,(e=>(0,o.expressionHasVariable)(e,c[0])));const[l,...u]=h(s,c[0]);r.push(...u.map((r=>v([...a.map((e=>P(e))),r,...e.slice(t+1).map((e=>P(e)))],new Set(i),x(n)))).flat()),s=l}if("Identifier"===s.left.type&&"NumericLiteral"===s.right.type){for(const e in n){const t=n[e];Array.isArray(t)?n[e]=[(0,o.optimizeExpression)(C(t[0],{[s.left.name]:s.right}),(t=>(0,o.expressionHasVariable)(t,e))),(0,o.optimizeExpression)(C(t[1],{[s.left.name]:s.right}),(t=>(0,o.expressionHasVariable)(t,e)))]:n[e]=(0,o.optimizeExpression)(C(t,{[s.left.name]:s.right}),(t=>(0,o.expressionHasVariable)(t,e)))}n[s.left.name]=s.right,i.delete(s.left.name)}else a.push(s)}}const s=b(a,n,i);if(e=s.equations,r.push(...s.result),e.length===t)break;t=e.length}};for(a();;){const t=e.shift();if(!t)break;let s=y(t).filter((e=>i.has(e)))[0],[c,...l]=h(t,s);for(;!y(c).includes(s);){const e=y(c).filter((e=>i.has(e)))[0];if(e===s)break;s=e,[c,...l]=h(c,s)}if(r.push(...l.map((t=>v([t,...e.map((e=>P(e)))],new Set(i),x(n)))).flat()),"Identifier"===c.left.type){for(const e in n){const t=n[e];Array.isArray(t)?n[e]=[(0,o.optimizeExpression)(C(t[0],{[s]:c.right}),(t=>(0,o.expressionHasVariable)(t,e))),(0,o.optimizeExpression)(C(t[1],{[s]:c.right}),(t=>(0,o.expressionHasVariable)(t,e)))]:n[e]=(0,o.optimizeExpression)(C(t,{[s]:c.right}),(t=>(0,o.expressionHasVariable)(t,e)))}n[s]=c.right,i.delete(s);const t=b(e,{[s]:c.right},i);e=t.equations,r.push(...t.result),a()}else n[s]=[c.left,c.right],i.delete(s)}return[n,...r]}function x(e){const t={};for(const[n,r]of Object.entries(e))Array.isArray(r)?t[n]=[w(r[0]),w(r[1])]:t[n]=w(r);return t}function b(e,t,n){const r=[],i=[];for(let a=0;an.has(e)));if(c.length>0)if(1===c.length){s=(0,o.optimizeEquation)(s,(e=>(0,o.expressionHasVariable)(e,c[0])));const[l,...u]=h(s,c[0]);i.push(...u.map((o=>v([...r.map((e=>P(e))),o,...e.slice(a+1).map((e=>P(e)))],new Set(n),x(t)))).flat()),r.push(l)}else r.push(s)}return{equations:r,result:i}}function C(e,t){if("BinaryExpression"===e.type)E(e,"left",t),E(e,"right",t);else if("UnaryExpression"===e.type)E(e,"argument",t);else if("Identifier"===e.type){const n=t[e.name];if(n&&!Array.isArray(n))return n}else"CallExpression"===e.type&&e.arguments.forEach(((n,r)=>{"SpreadElement"!==n.type&&(e.arguments[r]=C(n,t))}));return e}function E(e,t,n){const r=e[t];if("Identifier"===r.type){const o=n[r.name];o&&!Array.isArray(o)&&(e[t]=w(o))}else C(r,n)}function P(e){return{left:w(e.left),right:w(e.right)}}function w(e){return"BinaryExpression"===e.type?g(f({},e),{left:w(e.left),right:w(e.right)}):"UnaryExpression"===e.type?g(f({},e),{argument:w(e.argument)}):"CallExpression"===e.type?g(f({},e),{arguments:e.arguments.map((e=>"SpreadElement"===e.type?e:w(e)))}):f({},e)}},6845:(e,t,n)=>{"use strict";n.r(t),n.d(t,{ExpressionEditor:()=>m});var r=n(3696),o=n(1777),i=n(9424),a=n(7670),s=n(8905),c=n(8174),l=n(623),u=Object.defineProperty,p=Object.getOwnPropertySymbols,d=Object.prototype.hasOwnProperty,f=Object.prototype.propertyIsEnumerable,g=(e,t,n)=>t in e?u(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,h=(e,t)=>{for(var n in t||(t={}))d.call(t,n)&&g(e,n,t[n]);if(p)for(var n of p(t))f.call(t,n)&&g(e,n,t[n]);return e};function m(e){var t,n,u,p,d,f,g,m;const y=null!=(t=e.height)?t:100,v=null!=(n=e.target)?n:o.reactCanvasRenderTarget,x=null!=(u=e.fontSize)?u:16,b=null!=(f=null!=(d=null==(p=e.style)?void 0:p.fontFamily)?d:c.controlStyle.fontFamily)?f:"monospace",C=null!=(g=e.numberColor)?g:820234,E=1.2*x,[P,w]=r.useState(null!=(m=e.width)?m:250),{state:k,setState:_,undo:S,redo:R,resetHistory:T}=(0,i.useUndoRedo)(e.value.split("")),[A,L]=r.useState([]),[M,I]=r.useState(0),[O,D]=r.useState(""),[B,z]=r.useState(),[F,N]=r.useState(),{renderEditor:U,layoutResult:G,location:j,cursor:V,setLocation:W,inputText:H}=(0,a.useFlowLayoutTextEditor)({state:k,setState:_,width:P,height:y,fontSize:x,fontFamily:b,lineHeight:E,readOnly:e.readOnly,processInput(t){var n;if("Escape"===t.key)return null==(n=e.onCancel)||n.call(e),!0;if(A.length>0&&!e.readOnly){if("ArrowDown"===t.key)return I((M+1)%A.length),t.preventDefault(),!0;if("ArrowUp"===t.key)return I((M-1+A.length)%A.length),t.preventDefault(),!0;if("Enter"===t.key&&M>=0&&M{setTimeout((()=>{$()}),0)},style:{border:"unset"}});r.useEffect((()=>{var t,n,r,o;if(!e.suggestionSources||e.readOnly)return;if(j-1<0||j-1>=k.length)return;L([]),z(void 0);const i=k[j-1];if((0,s.isLetter)(i)||(0,s.isNumber)(i)||"."==i){let r;for(let e=j-1;e>=0&&et.name===o[e])))?void 0:t.members)?n:[];else{const t=o[e].toLowerCase();i=i.filter((e=>e.name.toLowerCase().includes(t))).sort(((e,n)=>e.name.toLowerCase()===t?-1:n.name.toLowerCase()===t?1:e.name.localeCompare(n.name)))}L(i),I(0),D(o[o.length-1])}else if("("===i){let t;for(let e=j-2;e>=0&&et.name===n[e])))?void 0:r.members)?o:[]:i=a.find((t=>t.name===n[e]));z(i)}}),[k,j]),r.useEffect((()=>{T(e.value.split(""))}),[e.value]),r.useEffect((()=>{var t;N(null==(t=e.validate)?void 0:t.call(e,k.join("")))}),[k,e.validate]);const q=r.useRef(null);r.useEffect((()=>{if(!q.current)return;const e=new ResizeObserver((e=>{for(const t of e)w(t.contentRect.width)}));return e.observe(q.current),()=>e.disconnect()}),[q.current]);const $=()=>{if(!e.readOnly&&e.setValue){const t=k.join("");t!==e.value&&e.setValue(t)}},X={};e.readOnly&&(X.opacity=.5);const Y=e=>{const t=A[e];_((e=>{e.splice(j-O.length,O.length,...t.name.split(""))})),W(j-O.length+t.name.length),L([])};return r.createElement("div",{ref:q,style:h(h(h({position:"relative"},c.controlStyle),e.style),X)},U({target:v,getTextColors:t=>{let n=e.color;const r=G[t].content;if(F&&t>=F[0]&&t=0;n--){const t=G[n].content;if((0,s.isNumber)(t))e=!1;else{if(!(0,s.isLetter)(t))break;e=!0}}e||(n=C)}else if("."===r&&t0&&r.createElement("div",{style:{position:"absolute",left:V.x+"px",top:V.y+E+"px",background:"white",width:"200px",border:"1px solid black",maxHeight:"200px",overflowY:"auto"}},A.map(((e,t)=>{const n=e.name.toLowerCase().indexOf(O.toLowerCase());return r.createElement("div",{key:e.name,style:{background:M===t?"#ccc":void 0,cursor:"pointer"},onMouseDown:e=>{e.preventDefault(),Y(t)},title:e.comment},e.name.substring(0,n),r.createElement("span",{style:{color:"#0c840a"}},e.name.substring(n,n+O.length)),e.name.substring(n+O.length))}))),(null==B?void 0:B.parameters)&&r.createElement("div",{style:{position:"absolute",left:V.x+"px",top:V.y+E+"px",background:"white",width:"400px",border:"1px solid black",maxHeight:"200px",overflowY:"auto"}},r.createElement("div",{onMouseDown:e=>e.preventDefault()},B.name,"(",B.parameters.map((e=>e.name)).join(", "),")",B.parameters.map((e=>e.comment?r.createElement("div",{key:e.name,style:{fontSize:"12px"}},e.name,": ",e.comment):null)),B.comment&&r.createElement("div",{style:{fontSize:"12px"}},B.comment))))}},3549:(e,t,n)=>{"use strict";n.r(t),n.d(t,{deriveExpressionWith:()=>g,expandExpression:()=>s,groupAllFactors:()=>d,groupFactorsBy:()=>p,groupFactorsByVariables:()=>f,sortFactors:()=>c,taylorExpandExpressionWith:()=>h});var r=n(767),o=n(123),i=n(6277),a=n(4281);function s(e){if("BinaryExpression"===e.type){if("**"===e.operator&&"NumericLiteral"===e.right.type){if(2===e.right.value&&"BinaryExpression"===e.left.type){if("+"===e.left.operator||"-"===e.left.operator)return s({type:"BinaryExpression",operator:"+",left:{type:"BinaryExpression",operator:e.left.operator,left:{type:"BinaryExpression",operator:"*",left:e.left.left,right:e.left.left},right:{type:"BinaryExpression",operator:"*",left:{type:"NumericLiteral",value:2},right:{type:"BinaryExpression",operator:"*",left:e.left.left,right:e.left.right}}},right:{type:"BinaryExpression",operator:"*",left:e.left.right,right:e.left.right}});if("*"===e.left.operator||"/"===e.left.operator)return s({type:"BinaryExpression",operator:e.left.operator,left:{type:"BinaryExpression",operator:e.left.operator,left:{type:"BinaryExpression",operator:"*",left:e.left.left,right:e.left.left},right:e.left.right},right:e.left.right})}if(Number.isInteger(e.right.value)&&e.right.value>=3&&"Identifier"!==e.left.type)return s({type:"BinaryExpression",operator:"*",left:{type:"BinaryExpression",operator:"**",left:e.left,right:{type:"NumericLiteral",value:e.right.value-1}},right:e.left})}if("*"===e.operator){if("BinaryExpression"===e.right.type&&("+"===e.right.operator||"-"===e.right.operator))return s({type:"BinaryExpression",operator:e.right.operator,left:{type:"BinaryExpression",operator:"*",left:e.left,right:e.right.left},right:{type:"BinaryExpression",operator:"*",left:e.left,right:e.right.right}});if("BinaryExpression"===e.left.type){if("+"===e.left.operator||"-"===e.left.operator)return s({type:"BinaryExpression",operator:e.left.operator,left:{type:"BinaryExpression",operator:"*",left:e.left.left,right:e.right},right:{type:"BinaryExpression",operator:"*",left:e.left.right,right:e.right}});if("/"===e.left.operator&&"Identifier"===e.left.right.type){if("Identifier"!==e.right.type)return s({type:"BinaryExpression",operator:"/",left:{type:"BinaryExpression",operator:"*",left:e.left.left,right:e.right},right:e.left.right});if(e.left.right.name===e.right.name)return s(e.left.left)}}}if("/"===e.operator&&"BinaryExpression"===e.left.type&&("+"===e.left.operator||"-"===e.left.operator))return s({type:"BinaryExpression",operator:e.left.operator,left:{type:"BinaryExpression",operator:"/",left:e.left.left,right:e.right},right:{type:"BinaryExpression",operator:"/",left:e.left.right,right:e.right}});const t=s(e.left),n=s(e.right);return t===e.left&&n===e.right?e:s({type:"BinaryExpression",operator:e.operator,left:t,right:n})}if("UnaryExpression"===e.type){if("-"===e.operator&&"BinaryExpression"===e.argument.type&&("+"===e.argument.operator||"-"===e.argument.operator))return s({type:"BinaryExpression",left:{type:"UnaryExpression",operator:"-",argument:e.argument.left},operator:(0,i.getReverseOperator)(e.argument.operator),right:e.argument.right});const t=s(e.argument);return t===e.argument?e:s({type:"UnaryExpression",operator:e.operator,argument:t})}return e}function c(e){e.forEach((e=>{e.variables.sort(l)})),e.sort(((e,t)=>{for(let n=0;nt.count===e));a?a.factors.push(...i):n.push({count:e,factors:i})}return n.sort(((e,t)=>t.count-e.count)),n}function p(e,t){return function(e,t){let n;for(const r of e){let e;for(const t of r.factors){const n=(0,o.factorToExpression)(t);e=e?{type:"BinaryExpression",operator:"+",left:e,right:n}:n}if(r.count>0){const n=(0,o.factorToExpression)((0,o.powerFactor)(t,r.count));e=e?{type:"BinaryExpression",operator:"*",left:e,right:n}:n}e&&(n=n?{type:"BinaryExpression",operator:"+",left:n,right:e}:e)}return n}(u(e,t),t)}function d(e){const t=[];for(const n of e)for(const e of n.variables)if("string"==typeof e){const n=t.find((t=>t.name===e));n?n.count++:t.push({name:e,count:1})}return t.sort(((e,t)=>t.count-e.count)),f(e,t.map((e=>e.name)))}function f(e,t){const n=(e,r)=>{if(e.length<=1)return;if(!t[r])return;const i={variables:[t[r]]},a=u(e,i);let s;for(const e of a){let t=n(e.factors,r+1);if(!t)for(const n of e.factors){const e=(0,o.factorToExpression)(n);t=t?{type:"BinaryExpression",operator:"+",left:t,right:e}:e}if(e.count>0){const n=(0,o.factorToExpression)((0,o.powerFactor)(i,e.count));t=t?{type:"BinaryExpression",operator:"*",left:t,right:n}:n}t&&(s=s?{type:"BinaryExpression",operator:"+",left:s,right:t}:t)}return s};return n(e,0)}function g(e,t){if("BinaryExpression"===e.type){if("+"===e.operator||"-"===e.operator)return{type:"BinaryExpression",operator:e.operator,left:g(e.left,t),right:g(e.right,t)};if("*"===e.operator)return{type:"BinaryExpression",operator:"+",left:{type:"BinaryExpression",operator:"*",left:g(e.left,t),right:e.right},right:{type:"BinaryExpression",operator:"*",left:e.left,right:g(e.right,t)}};if("/"===e.operator)return{type:"BinaryExpression",operator:"/",left:{type:"BinaryExpression",operator:"/",left:{type:"BinaryExpression",operator:"-",left:{type:"BinaryExpression",operator:"*",left:g(e.left,t),right:e.right},right:{type:"BinaryExpression",operator:"*",left:e.left,right:g(e.right,t)}},right:e.right},right:e.right};if("**"===e.operator){if(!(0,i.expressionHasVariable)(e.left,t))return(0,i.expressionHasVariable)(e.right,t)?{type:"BinaryExpression",operator:"*",left:{type:"BinaryExpression",operator:"*",left:{type:"CallExpression",callee:{type:"Identifier",name:"ln"},arguments:[e.left]},right:e},right:g(e.right,t)}:{type:"NumericLiteral",value:0};if(!(0,i.expressionHasVariable)(e.right,t))return{type:"BinaryExpression",operator:"*",left:{type:"BinaryExpression",operator:"*",left:g(e.left,t),right:e.right},right:{type:"BinaryExpression",operator:"**",left:e.left,right:{type:"BinaryExpression",operator:"-",left:e.right,right:{type:"NumericLiteral",value:1}}}}}}if("UnaryExpression"===e.type)return{type:"UnaryExpression",operator:e.operator,argument:g(e.argument,t)};if("CallExpression"===e.type){let n;"Identifier"===e.callee.type?n=e.callee.name:"MemberExpression"===e.callee.type&&"Identifier"===e.callee.object.type&&"Math"===e.callee.object.name&&"Identifier"===e.callee.property.type&&(n=e.callee.property.name);const r=e.arguments[0];if(n&&r&&"SpreadElement"!==r.type&&(0,i.expressionHasVariable)(r,t)){if("sin"===n)return{type:"BinaryExpression",operator:"*",left:{type:"CallExpression",callee:{type:"Identifier",name:"cos"},arguments:e.arguments},right:g(r,t)};if("cos"===n)return{type:"UnaryExpression",operator:"-",argument:{type:"BinaryExpression",operator:"*",left:{type:"CallExpression",callee:{type:"Identifier",name:"sin"},arguments:e.arguments},right:g(r,t)}};if("tan"===n)return{type:"BinaryExpression",operator:"/",left:{type:"BinaryExpression",operator:"/",left:g(r,t),right:{type:"CallExpression",callee:{type:"Identifier",name:"cos"},arguments:e.arguments}},right:{type:"CallExpression",callee:{type:"Identifier",name:"cos"},arguments:e.arguments}};if("ln"===n)return{type:"BinaryExpression",operator:"/",left:g(r,t),right:r};if("exp"===n)return{type:"BinaryExpression",operator:"*",left:e,right:g(r,t)}}}return"NumericLiteral"===e.type?{type:"NumericLiteral",value:0}:"Identifier"===e.type?{type:"NumericLiteral",value:e.name===t?1:0}:e}function h(e,t,n,o){const s=e=>(0,i.expressionHasVariable)(e,t);let c=(0,i.optimizeExpression)((0,a.composeExpression)((0,a.cloneExpression)(e),{[t]:{type:"NumericLiteral",value:0}}),s);o&&(c=(0,i.optimizeExpression)({type:"BinaryExpression",operator:"*",left:c,right:{type:"Identifier",name:t}},s));for(let l=1;l{"use strict";n.r(t),n.d(t,{ImageEditor:()=>$});var r=n(3696),o=n.n(r),i=n(8662),a=n(4840),s=n(6376),c=n(8907),l=n(9182),u=n(4104),p=n(360),d=n(3537),f=n(623),g=n(370),h=n(9160),m=n(7486),y=n(5481),v=n(1796),x=n(6842),b=n(2792),C=n(7195),E=n(9424),P=n(6487),w=n(8174),k=n(3975),_=n(5644),S=n(2318),R=n(5072),T=n(2298),A=n(7662),L=n(4205),M=n(3181),I=n(6301),O=n(8905),D=n(7670),B=n(1715),z=Object.defineProperty,F=Object.defineProperties,N=Object.getOwnPropertyDescriptors,U=Object.getOwnPropertySymbols,G=Object.prototype.hasOwnProperty,j=Object.prototype.propertyIsEnumerable,V=(e,t,n)=>t in e?z(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,W=(e,t)=>{for(var n in t||(t={}))G.call(t,n)&&V(e,n,t[n]);if(U)for(var n of U(t))j.call(t,n)&&V(e,n,t[n]);return e},H=(e,t)=>F(e,N(t)),q=(e,t,n)=>new Promise(((r,o)=>{var i=e=>{try{s(n.next(e))}catch(e){o(e)}},a=e=>{try{s(n.throw(e))}catch(e){o(e)}},s=e=>e.done?r(e.value):Promise.resolve(e.value).then(i,a);s((n=n.apply(e,t)).next())}));function $(e){const{state:t,setState:n,resetHistory:r,undo:z,redo:F,canRedo:N,canUndo:U}=(0,E.useUndoRedo)(void 0),[G,j]=o().useState(),[V,$]=o().useState(),[Y,K]=o().useState("select"),[Z,Q]=o().useState(),[J,ee]=o().useState(),te=o().useRef(null),[ne,re]=o().useState(10),oe=o().useRef(0),ie=o().useRef(.5),ae=o().useRef(20),se=o().useRef("monospace"),ce=o().useRef(1),[le,ue]=o().useState(),pe=()=>{setTimeout((()=>{var e;null==(e=te.current)||e.focus()}))},de=t=>q(this,null,(function*(){var n,o;const i=yield(0,y.dataUrlToImage)(t,"anonymous"),a=Math.min(e.width/i.width,e.height/i.height),s=i.width*a,c=i.height*a,l=(e.width-s)/2+(null!=(n=e.x)?n:0),u=(e.height-c)/2+(null!=(o=e.y)?o:0),d=(0,p.zoomToFitPoints)((0,m.getPolygonFromTwoPointsFormRegion)({start:{x:0,y:0},end:{x:i.width,y:i.height}}),{width:s,height:c},{x:s/2,y:c/2},1);d&&(xe(d.scale),me(d.x),ye(d.y));const f=(0,y.createCanvasContext)(i);f&&(f.drawImage(i,0,0,i.width,i.height),r({url:t,ctx:f,x:l,y:u,canvasWidth:s,canvasHeight:c}),pe())}));o().useEffect((()=>{de(e.src)}),[]);const{x:fe,y:ge,ref:he,setX:me,setY:ye}=(0,l.useWheelScroll)(),{scale:ve,setScale:xe,ref:be}=(0,u.useWheelZoom)({onChange(e,n,r){if(!t)return;const o=(0,p.scaleByCursorPosition)({width:t.canvasWidth,height:t.canvasHeight},n/e,r);me(o.setX),ye(o.setY)}}),{zoomIn:Ce,zoomOut:Ee}=(0,g.useZoom)(ve,xe),{offset:Pe,onStart:we,mask:ke,resetDragMove:_e}=(0,c.useDragMove)((()=>{me((e=>e+Pe.x)),ye((e=>e+Pe.y)),K("select"),Le()})),{onStartSelect:Se,dragSelectMask:Re,endDragSelect:Te,resetDragSelect:Ae}=(0,h.useDragSelect)(((e,t)=>{if(t){e=Je(e),t=Je(t);const n=(0,m.getTwoPointsFormRegion)(e,t);if("add text"===Y)return void ue(H(W(W({},n.start),(0,m.getTwoPointsFormRegionSize)(n)),{text:""}));const r=(0,m.getPolygonFromTwoPointsFormRegion)(n);Q({type:"polygon",points:r}),pe()}})),Le=()=>{$(void 0),pe()},Me=(e=!0)=>{K("select"),Le(),_e(),Ae(),Q(void 0),j(void 0),ee(void 0),Fe(),je(),qe(e),Ke(),ue(void 0)},{start:Ie,ui:Oe}=(0,C.useChooseFile)((e=>q(this,null,(function*(){const t=yield(0,y.blobToDataUrl)(e);if("add image"===Y){const e=yield(0,y.dataUrlToImage)(t,"anonymous"),n=(0,y.createCanvasContext)(e);return n&&(n.drawImage(e,0,0,e.width,e.height),j({url:t,ctx:n})),void K("paste")}yield de(t)})))),{circle:De,onClick:Be,onMove:ze,reset:Fe}=(0,_.useCircleClickCreate)("circle select"===Y||"add circle"===Y?"center radius":void 0,(e=>{if("add circle"===Y)return void lt((t=>{t.arc(e.x,e.y,e.r,0,2*Math.PI)}));const t=(0,S.arcToPolyline)((0,S.circleToArc)(e),10).map((e=>({x:Math.round(e.x),y:Math.round(e.y)})));Q({type:"polygon",points:t}),pe()})),{ellipse:Ne,onClick:Ue,onMove:Ge,reset:je}=(0,R.useEllipseClickCreate)("ellipse select"===Y||"add ellipse"===Y?"ellipse center":void 0,(e=>{if("add ellipse"===Y)return void lt((t=>{t.ellipse(e.cx,e.cy,e.rx,e.ry,(0,B.angleToRadian)(e.angle),0,2*Math.PI)}));const t=(0,T.ellipseArcToPolyline)((0,T.ellipseToEllipseArc)(e),10).map((e=>({x:Math.round(e.x),y:Math.round(e.y)})));Q({type:"polygon",points:t}),pe()})),{line:Ve,onClick:We,onMove:He,reset:qe}=(0,A.useLineClickCreate)("polygon select"===Y||"add polyline"===Y||"add rect"===Y,(e=>{if("add polyline"!==Y)if("add rect"!==Y){if(e.length>2){const t=e.map((e=>({x:Math.round(e.x),y:Math.round(e.y)})));Q({type:"polygon",points:t})}pe()}else{const t=(0,m.getTwoPointsFormRegion)(e[0],e[1]),n=(0,m.getTwoPointsFormRegionSize)(t);lt((e=>{e.rect(t.start.x,t.start.y,n.width,n.height)}))}else lt((t=>{for(let n=0;n{if("add pen"===Y)return void lt((e=>{for(let t=0;t<$e.length;t++)0===t?e.moveTo($e[t].x,$e[t].y):e.lineTo($e[t].x,$e[t].y)}));const e=$e.map((e=>({x:Math.round(e.x),y:Math.round(e.y)})));Q({type:"polygon",points:e}),pe()}));if(!t)return null;const Ze={x:fe,y:ge,scale:ve,center:{x:t.canvasWidth/2,y:t.canvasHeight/2}};Ze.x+=Pe.x,Ze.y+=Pe.y;const Qe=e=>({x:e.x-t.x,y:e.y-t.y}),Je=e=>(e=Qe(e),(e=(0,p.reverseTransformPosition)(e,Ze)).x=Math.floor(e.x),e.y=Math.floor(e.y),e),et=a.reactCanvasRenderTarget,tt=[];tt.push(et.renderImage(t.url,0,0,t.ctx.canvas.width,t.ctx.canvas.height)),G&&J&&tt.push(et.renderImage(G.url,J.x,J.y,G.ctx.canvas.width,G.ctx.canvas.height));const nt={strokeWidth:0,fillColor:0,fillOpacity:.3},rt={strokeWidth:ce.current,strokeColor:oe.current,strokeOpacity:ie.current};if("polygon"===(null==Z?void 0:Z.type)&&tt.push(et.renderPolygon(Z.points,nt)),"range"===(null==Z?void 0:Z.type))for(const e of Z.ranges)for(const t of e.ys)tt.push(et.renderRect(e.x,t[0],1,t[1]-t[0]+1,nt));else"brush"===Y&&J&&tt.push(et.renderRect(J.x,J.y,2*ne+1,2*ne+1,nt));if(De&&tt.push(et.renderCircle(De.x,De.y,De.r,"add circle"===Y?rt:nt)),Ne&&tt.push(et.renderEllipse(Ne.cx,Ne.cy,Ne.rx,Ne.ry,H(W({},"add ellipse"===Y?rt:nt),{angle:Ne.angle}))),Ve)if("add polyline"===Y&&Ve.length>1)tt.push(et.renderPolyline(Ve,rt));else if("add rect"===Y&&Ve.length>1){const e=(0,m.getTwoPointsFormRegion)(Ve[0],Ve[1]),t=(0,m.getTwoPointsFormRegionSize)(e);tt.push(et.renderRect(e.start.x,e.start.y,t.width,t.height,rt))}else"polygon select"===Y&&Ve.length>2&&tt.push(et.renderPolygon(Ve,nt));$e&&("add pen"===Y&&$e.length>1?tt.push(et.renderPolyline($e,rt)):"pen select"===Y&&$e.length>2&&tt.push(et.renderPolygon($e,nt))),tt.push(et.renderRect(0,0,t.ctx.canvas.width,t.ctx.canvas.height,{strokeOpacity:.3,dashArray:[4]}));const ot=e=>{let r;if("polygon"===(null==Z?void 0:Z.type)?r=e=>t=>(0,v.pointInPolygon)({x:e,y:t},Z.points):"range"===(null==Z?void 0:Z.type)&&(r=e=>{const t=Z.ranges.find((t=>t.x===e));if(t)return e=>t.ys.some((t=>(0,b.isBetween)(e,...t)))}),r){const o=t.ctx.getImageData(0,0,t.ctx.canvas.width,t.ctx.canvas.height);for(let n=0;n{e&&(e.url=t.ctx.canvas.toDataURL())}))}Q(void 0)},it=()=>{ot((()=>[0,0,0,0]))},at=()=>{let e;if("polygon"===(null==Z?void 0:Z.type))e={bounding:(0,x.getPointsBounding)(Z.points),inRange:e=>t=>(0,v.pointInPolygon)({x:e,y:t},Z.points)};else if("range"===(null==Z?void 0:Z.type)){const t=Z.ranges.map((e=>e.x));e={bounding:{start:{x:Math.min(...t),y:Math.min(...Z.ranges.map((e=>e.ys.map((e=>e[0])))).flat())},end:{x:Math.max(...t),y:Math.max(...Z.ranges.map((e=>e.ys.map((e=>e[1])))).flat())}},inRange:e=>{const t=Z.ranges.find((t=>t.x===e));if(t)return e=>t.ys.some((t=>(0,b.isBetween)(e,...t)))}}}if(e){const n=e.bounding;if(n){const r=(0,m.getTwoPointsFormRegionSize)(n);r.width++,r.height++;const o=(0,y.createCanvasContext)(r);if(o){const i=o.createImageData(r.width,r.height),a=n.start.x,s=n.start.y,c=t.ctx.getImageData(0,0,t.ctx.canvas.width,t.ctx.canvas.height);for(let t=0;t{e&&navigator.clipboard.write([new ClipboardItem({[e.type]:e})])}))}}}Q(void 0)},st=()=>q(this,null,(function*(){const e=yield navigator.clipboard.read();for(const t of e)if(t.types.includes("image/png")){const e=yield t.getType("image/png"),n=yield(0,y.blobToDataUrl)(e),r=yield(0,y.dataUrlToImage)(n,"anonymous"),o=(0,y.createCanvasContext)(r);o&&(o.drawImage(r,0,0,r.width,r.height),j({url:n,ctx:o})),K("paste");break}})),ct=()=>q(this,null,(function*(){const e=yield navigator.clipboard.read();for(const t of e)if(t.types.includes("image/png")){const e=yield t.getType("image/png"),n=yield(0,y.blobToDataUrl)(e);yield de(n);break}})),lt=e=>{t.ctx.save(),t.ctx.beginPath(),e(t.ctx),t.ctx.lineWidth=ce.current,t.ctx.strokeStyle=(0,k.getColorString)(oe.current,ie.current),t.ctx.stroke(),t.ctx.restore(),n((e=>{e&&(e.url=t.ctx.canvas.toDataURL())})),Me(!1)};let ut;if("add text"===Y&&le){const e=(0,p.transformPosition)(le,Ze);ut=o().createElement(M.SimpleTextEditor,{fontSize:ae.current*ve,width:le.width*ve,height:le.height*ve,color:oe.current,fontFamily:se.current,onCancel:Me,x:e.x,y:e.y,value:le.text,setValue:e=>{le.text=e}})}return o().createElement("div",{ref:(0,d.bindMultipleRefs)(he,be),style:{cursor:"move"===Y?"grab":"crosshair",position:"absolute",inset:"0px",left:t.x+"px",top:t.y+"px",overflow:"hidden"},onMouseMove:e=>{if("brush"===Y){const t=Je({x:e.clientX,y:e.clientY});if("range"===(null==Z?void 0:Z.type)){const e=X(t,ne);Q({type:"range",ranges:(0,i.produce)(Z.ranges,(t=>{for(const n of e){const e=t.find((e=>e.x===n.x));e?e.ys=(0,b.mergeItems)([...n.ys,...e.ys],b.getNumberRangeUnion):t.push(n)}}))})}else ee({x:t.x-ne,y:t.y-ne})}if(G&&"paste"===Y){const t=Je({x:e.clientX,y:e.clientY});ee({x:Math.floor(t.x-G.ctx.canvas.width/2),y:Math.floor(t.y-G.ctx.canvas.height/2)})}else"circle select"===Y||"add circle"===Y?ze(Je({x:e.clientX,y:e.clientY})):"ellipse select"===Y||"add ellipse"===Y?Ge(Je({x:e.clientX,y:e.clientY})):"polygon select"===Y||"add polyline"===Y||"add rect"===Y?He(Je({x:e.clientX,y:e.clientY})):"pen select"!==Y&&"add pen"!==Y||Ye(Je({x:e.clientX,y:e.clientY}))}},et.renderResult(tt,t.canvasWidth,t.canvasHeight,{attributes:{onMouseDown(e){if("move"===Y)we({x:e.clientX,y:e.clientY});else if(4===e.buttons)we({x:e.clientX,y:e.clientY});else if("brush"===Y&&"range"!==(null==Z?void 0:Z.type)){const t=X(Je({x:e.clientX,y:e.clientY}),ne);Q({type:"range",ranges:t})}},onClick(e){if("select"===Y)Se(e);else if("paste"===Y&&G&&J){const e=t.ctx.getImageData(0,0,t.ctx.canvas.width,t.ctx.canvas.height),r=G.ctx.getImageData(0,0,G.ctx.canvas.width,G.ctx.canvas.height),o=Math.floor(J.x),i=Math.floor(J.y),a=Math.max(o,0),s=Math.min(o+G.ctx.canvas.width,t.ctx.canvas.width),c=Math.max(i,0),l=Math.min(i+G.ctx.canvas.height,t.ctx.canvas.height);for(let t=a;t{e&&(e.url=t.ctx.canvas.toDataURL())})),Me()}else if("brush"===Y&&"range"===(null==Z?void 0:Z.type)){const e=Z.ranges;Me(),Q({type:"range",ranges:e})}else if("circle select"===Y||"add circle"===Y)Be(Je({x:e.clientX,y:e.clientY}));else if("ellipse select"===Y||"add ellipse"===Y)Ue(Je({x:e.clientX,y:e.clientY}));else if("polygon select"===Y||"add polyline"===Y||"add rect"===Y)We(Je({x:e.clientX,y:e.clientY})),pe();else if("pen select"===Y||"add pen"===Y)Xe(Je({x:e.clientX,y:e.clientY}));else if("add text"===Y)if(le){if(le.text){const e=le.text.split(""),r=(0,O.getTextStyleFont)({fontSize:ae.current,fontFamily:se.current}),o=e=>{var t,n;return null!=(n=null==(t=(0,O.getTextSizeFromCache)(r,e))?void 0:t.width)?n:0},{layoutResult:i}=(0,I.flowLayout)({state:e,width:le.width,lineHeight:1.2*ae.current,getWidth:o,endContent:"",isNewLineContent:e=>"\n"===e,isPartOfComposition:e=>(0,O.isWordCharactor)(e),getComposition:t=>(0,D.getTextComposition)(t,e,o,(e=>e))});t.ctx.save(),t.ctx.font=r,t.ctx.textAlign="center",t.ctx.textBaseline="alphabetic",t.ctx.fillStyle=(0,k.getColorString)(oe.current);for(const{x:e,y:n,content:r}of i){const i=o(r);t.ctx.fillText(r,le.x+e+i/2,le.y+n+ae.current)}t.ctx.restore(),n((e=>{e&&(e.url=t.ctx.canvas.toDataURL())})),Me()}}else Se(e)},onDoubleClick(e){Te(e)},onContextMenu(n){n.preventDefault();const r=Qe({x:n.clientX,y:n.clientY});if(V)return void Le();const i=[];e.onCpmplete&&i.push({title:"complete",onClick(){var n;null==(n=e.onCpmplete)||n.call(e,t.url,t.canvasWidth,t.canvasHeight),Le()}}),e.onCancel&&i.push({title:"cancel",onClick(){var t;null==(t=e.onCancel)||t.call(e),Le()}}),i.push({title:"open",children:[{title:"file",onClick(){Ie(),Le()}},{title:"clipboard image",onClick(){return q(this,null,(function*(){yield ct(),Le()}))}}]});const a=[];U&&a.push({title:"undo",onClick(){z(),Le()}}),N&&a.push({title:"redo",onClick(){F(),Le()}}),a.push({title:"move",onClick:()=>{K("move"),Le()}}),i.push({title:"select",children:[{title:o().createElement(o().Fragment,null,o().createElement(w.NumberEditor,{value:ne,style:{width:"50px"},setValue:re}),o().createElement(w.Button,{onClick:()=>{K("brush"),Le(),Q(void 0)}},"brush select")),height:41},{title:"circle select",onClick:()=>{K("circle select"),Le()}},{title:"ellipse select",onClick:()=>{K("ellipse select"),Le()}},{title:"polygon select",onClick:()=>{K("polygon select"),Le()}},{title:"pen select",onClick:()=>{K("pen select"),Le()}}]}),Z&&a.push({title:"delete",onClick(){it(),Le()}},{title:o().createElement(o().Fragment,null,o().createElement(w.NumberEditor,{value:oe.current,type:"color",style:{width:"50px"},setValue:e=>oe.current=e}),o().createElement(w.Button,{onClick:()=>{const e=(0,k.colorNumberToPixelColor)(oe.current);ot((t=>[e[0],e[1],e[2],t[3]])),Le()}},"apply color")),height:33},{title:o().createElement(o().Fragment,null,o().createElement(w.NumberEditor,{value:100*ie.current,style:{width:"50px"},setValue:e=>ie.current=.01*e}),o().createElement(w.Button,{onClick:()=>{const e=Math.round(255*ie.current);ot((t=>[t[0],t[1],t[2],e])),Le()}},"apply opacity")),height:41},{title:"cut",onClick(){at(),it(),Le()}},{title:"copy",onClick(){at(),Le()}}),i.push({title:"edit",children:a}),i.push({title:"add",children:[{title:"paste",onClick(){return q(this,null,(function*(){yield st(),Le()}))}},{title:"image",onClick(){K("add image"),Ie(),Le()}},{title:o().createElement(o().Fragment,null,o().createElement(w.NumberEditor,{value:ae.current,style:{width:"40px"},setValue:e=>ae.current=e}),o().createElement(w.StringEditor,{value:se.current,style:{width:"100px"},setValue:e=>se.current=e}),o().createElement(w.Button,{onClick:()=>{K("add text"),Le()}},"text")),height:41},{title:o().createElement(o().Fragment,null,o().createElement(w.NumberEditor,{value:oe.current,type:"color",style:{width:"50px"},setValue:e=>oe.current=e}),o().createElement(w.NumberEditor,{value:100*ie.current,style:{width:"50px"},setValue:e=>ie.current=.01*e}),o().createElement(w.NumberEditor,{value:ce.current,style:{width:"40px"},setValue:e=>ce.current=e})),height:41},{title:"polyline",onClick(){K("add polyline"),Le()}},{title:"pen",onClick(){K("add pen"),Le()}},{title:"circle",onClick(){K("add circle"),Le()}},{title:"ellipse",onClick(){K("add ellipse"),Le()}},{title:"rect",onClick(){K("add rect"),Le()}}]}),i.push({title:"export",children:[{title:"to clipboard",onClick(){t.ctx.canvas.toBlob((e=>{e&&navigator.clipboard.write([new ClipboardItem({[e.type]:e})])})),Le(),Q(void 0)}}]}),$(o().createElement(s.Menu,{items:i,y:r.y,height:t.canvasHeight,style:{left:r.x+"px"}}))},style:e.style},transform:Ze}),ut,V,Re,ke,Oe,o().createElement(P.Cursor,{ref:te,onKeyDown:n=>{var r,o;if(n.stopPropagation(),(0,f.metaKeyIfMacElseCtrlKey)(n)){if("Minus"===n.code)Ee(n);else if("Equal"===n.code)Ce(n);else if("ArrowLeft"===n.key){if(!t)return;me((e=>e+t.canvasWidth/10)),n.preventDefault()}else if("ArrowRight"===n.key){if(!t)return;me((e=>e-t.canvasWidth/10)),n.preventDefault()}else if("ArrowUp"===n.key){if(!t)return;ye((e=>e+t.canvasHeight/10)),n.preventDefault()}else if("ArrowDown"===n.key){if(!t)return;ye((e=>e-t.canvasHeight/10)),n.preventDefault()}else if("KeyZ"===n.code)n.shiftKey?F(n):z(n);else if(!n.shiftKey)if("KeyA"===n.code){if(!t)return;const e=(0,m.getPolygonFromTwoPointsFormRegion)((0,m.getTwoPointsFormRegion)({x:0,y:0},{x:t.ctx.canvas.width,y:t.ctx.canvas.height}));Q({type:"polygon",points:e}),n.preventDefault()}else"KeyC"===n.code?(at(),n.preventDefault()):"KeyV"===n.code?(st(),n.preventDefault()):"KeyX"===n.code?(at(),it(),n.preventDefault()):"KeyS"===n.code&&(t&&(null==(r=e.onCpmplete)||r.call(e,t.url,t.canvasWidth,t.canvasHeight)),n.preventDefault())}else"Escape"===n.key&&(Me(),null==(o=e.onCancel)||o.call(e))}}))}function X({x:e,y:t},n){const r=[];for(let o=-n;o<=n;o++)r.push({x:e+o,ys:[[t-n,t+n]]});return r}},7875:(e,t,n)=>{"use strict";n.r(t);var r=n(3158),o={};for(const e in r)"default"!==e&&(o[e]=()=>r[e]);n.d(t,o);var i=n(8907);o={};for(const e in i)"default"!==e&&(o[e]=()=>i[e]);n.d(t,o);var a=n(3331);o={};for(const e in a)"default"!==e&&(o[e]=()=>a[e]);n.d(t,o);var s=n(9182);o={};for(const e in s)"default"!==e&&(o[e]=()=>s[e]);n.d(t,o);var c=n(4104);o={};for(const e in c)"default"!==e&&(o[e]=()=>c[e]);n.d(t,o);var l=n(9424);o={};for(const e in l)"default"!==e&&(o[e]=()=>l[e]);n.d(t,o);var u=n(2931);o={};for(const e in u)"default"!==e&&(o[e]=()=>u[e]);n.d(t,o);var p=n(370);o={};for(const e in p)"default"!==e&&(o[e]=()=>p[e]);n.d(t,o);var d=n(2789);o={};for(const e in d)"default"!==e&&(o[e]=()=>d[e]);n.d(t,o);var f=n(2800);o={};for(const e in f)"default"!==e&&(o[e]=()=>f[e]);n.d(t,o);var g=n(5634);o={};for(const e in g)"default"!==e&&(o[e]=()=>g[e]);n.d(t,o);var h=n(1412);o={};for(const e in h)"default"!==e&&(o[e]=()=>h[e]);n.d(t,o);var m=n(9160);o={};for(const e in m)"default"!==e&&(o[e]=()=>m[e]);n.d(t,o);var y=n(3307);o={};for(const e in y)"default"!==e&&(o[e]=()=>y[e]);n.d(t,o);var v=n(7923);o={};for(const e in v)"default"!==e&&(o[e]=()=>v[e]);n.d(t,o);var x=n(6545);o={};for(const e in x)"default"!==e&&(o[e]=()=>x[e]);n.d(t,o);var b=n(5644);o={};for(const e in b)"default"!==e&&(o[e]=()=>b[e]);n.d(t,o);var C=n(7662);o={};for(const e in C)"default"!==e&&(o[e]=()=>C[e]);n.d(t,o);var E=n(5970);o={};for(const e in E)"default"!==e&&(o[e]=()=>E[e]);n.d(t,o);var P=n(1369);o={};for(const e in P)"default"!==e&&(o[e]=()=>P[e]);n.d(t,o);var w=n(8285);o={};for(const e in w)"default"!==e&&(o[e]=()=>w[e]);n.d(t,o);var k=n(4489);o={};for(const e in k)"default"!==e&&(o[e]=()=>k[e]);n.d(t,o);var _=n(341);o={};for(const e in _)"default"!==e&&(o[e]=()=>_[e]);n.d(t,o);var S=n(4840);o={};for(const e in S)"default"!==e&&(o[e]=()=>S[e]);n.d(t,o);var R=n(2628);o={};for(const e in R)"default"!==e&&(o[e]=()=>R[e]);n.d(t,o);var T=n(5072);o={};for(const e in T)"default"!==e&&(o[e]=()=>T[e]);n.d(t,o);var A=n(2817);o={};for(const e in A)"default"!==e&&(o[e]=()=>A[e]);n.d(t,o);var L=n(3869);o={};for(const e in L)"default"!==e&&(o[e]=()=>L[e]);n.d(t,o);var M=n(1749);o={};for(const e in M)"default"!==e&&(o[e]=()=>M[e]);n.d(t,o);var I=n(4848);o={};for(const e in I)"default"!==e&&(o[e]=()=>I[e]);n.d(t,o);var O=n(3404);o={};for(const e in O)"default"!==e&&(o[e]=()=>O[e]);n.d(t,o);var D=n(9345);o={};for(const e in D)"default"!==e&&(o[e]=()=>D[e]);n.d(t,o);var B=n(4970);o={};for(const e in B)"default"!==e&&(o[e]=()=>B[e]);n.d(t,o);var z=n(5115);o={};for(const e in z)"default"!==e&&(o[e]=()=>z[e]);n.d(t,o);var F=n(2286);o={};for(const e in F)"default"!==e&&(o[e]=()=>F[e]);n.d(t,o);var N=n(4332);o={};for(const e in N)"default"!==e&&(o[e]=()=>N[e]);n.d(t,o);var U=n(5384);o={};for(const e in U)"default"!==e&&(o[e]=()=>U[e]);n.d(t,o);var G=n(6421);o={};for(const e in G)"default"!==e&&(o[e]=()=>G[e]);n.d(t,o);var j=n(7332);o={};for(const e in j)"default"!==e&&(o[e]=()=>j[e]);n.d(t,o);var V=n(5632);o={};for(const e in V)"default"!==e&&(o[e]=()=>V[e]);n.d(t,o);var W=n(9055);o={};for(const e in W)"default"!==e&&(o[e]=()=>W[e]);n.d(t,o);var H=n(2244);o={};for(const e in H)"default"!==e&&(o[e]=()=>H[e]);n.d(t,o);var q=n(6424);o={};for(const e in q)"default"!==e&&(o[e]=()=>q[e]);n.d(t,o);var $=n(9294);o={};for(const e in $)"default"!==e&&(o[e]=()=>$[e]);n.d(t,o);var X=n(69);o={};for(const e in X)"default"!==e&&(o[e]=()=>X[e]);n.d(t,o);var Y=n(4399);o={};for(const e in Y)"default"!==e&&(o[e]=()=>Y[e]);n.d(t,o);var K=n(6278);o={};for(const e in K)"default"!==e&&(o[e]=()=>K[e]);n.d(t,o);var Z=n(6845);o={};for(const e in Z)"default"!==e&&(o[e]=()=>Z[e]);n.d(t,o);var Q=n(3175);o={};for(const e in Q)"default"!==e&&(o[e]=()=>Q[e]);n.d(t,o);var J=n(7195);o={};for(const e in J)"default"!==e&&(o[e]=()=>J[e]);n.d(t,o);var ee=n(7658);o={};for(const e in ee)"default"!==e&&(o[e]=()=>ee[e]);n.d(t,o);var te=n(327);o={};for(const e in te)"default"!==e&&(o[e]=()=>te[e]);n.d(t,o);var ne=n(4205);o={};for(const e in ne)"default"!==e&&(o[e]=()=>ne[e]);n.d(t,o);var re=n(4844);o={};for(const e in re)"default"!==e&&(o[e]=()=>re[e]);n.d(t,o);var oe=n(7670);o={};for(const e in oe)"default"!==e&&(o[e]=()=>oe[e]);n.d(t,o);var ie=n(135);o={};for(const e in ie)"default"!==e&&(o[e]=()=>ie[e]);n.d(t,o);var ae=n(7816);o={};for(const e in ae)"default"!==e&&(o[e]=()=>ae[e]);n.d(t,o);var se=n(2432);o={};for(const e in se)"default"!==e&&(o[e]=()=>se[e]);n.d(t,o);var ce=n(4740);o={};for(const e in ce)"default"!==e&&(o[e]=()=>ce[e]);n.d(t,o);var le=n(8174);o={};for(const e in le)"default"!==e&&(o[e]=()=>le[e]);n.d(t,o);var ue=n(2607);o={};for(const e in ue)"default"!==e&&(o[e]=()=>ue[e]);n.d(t,o);var pe=n(4546);o={};for(const e in pe)"default"!==e&&(o[e]=()=>pe[e]);n.d(t,o);var de=n(9436);o={};for(const e in de)"default"!==e&&(o[e]=()=>de[e]);n.d(t,o);var fe=n(2978);o={};for(const e in fe)"default"!==e&&(o[e]=()=>fe[e]);n.d(t,o);var ge=n(3274);o={};for(const e in ge)"default"!==e&&(o[e]=()=>ge[e]);n.d(t,o);var he=n(4468);o={};for(const e in he)"default"!==e&&(o[e]=()=>he[e]);n.d(t,o);var me=n(5936);o={};for(const e in me)"default"!==e&&(o[e]=()=>me[e]);n.d(t,o);var ye=n(2202);o={};for(const e in ye)"default"!==e&&(o[e]=()=>ye[e]);n.d(t,o);var ve=n(7921);o={};for(const e in ve)"default"!==e&&(o[e]=()=>ve[e]);n.d(t,o);var xe=n(8454);o={};for(const e in xe)"default"!==e&&(o[e]=()=>xe[e]);n.d(t,o);var be=n(9201);o={};for(const e in be)"default"!==e&&(o[e]=()=>be[e]);n.d(t,o);var Ce=n(1121);o={};for(const e in Ce)"default"!==e&&(o[e]=()=>Ce[e]);n.d(t,o);var Ee=n(3549);o={};for(const e in Ee)"default"!==e&&(o[e]=()=>Ee[e]);n.d(t,o);var Pe=n(6376);o={};for(const e in Pe)"default"!==e&&(o[e]=()=>Pe[e]);n.d(t,o);var we=n(1478);o={};for(const e in we)"default"!==e&&(o[e]=()=>we[e]);n.d(t,o);var ke=n(3181);o={};for(const e in ke)"default"!==e&&(o[e]=()=>ke[e]);n.d(t,o)},6376:(e,t,n)=>{"use strict";n.r(t),n.d(t,{Menu:()=>p,getMenuHeight:()=>f,getMenuPosition:()=>d});var r=n(3696),o=n.n(r),i=Object.defineProperty,a=Object.getOwnPropertySymbols,s=Object.prototype.hasOwnProperty,c=Object.prototype.propertyIsEnumerable,l=(e,t,n)=>t in e?i(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,u=(e,t)=>{for(var n in t||(t={}))s.call(t,n)&&l(e,n,t[n]);if(a)for(var n of a(t))c.call(t,n)&&l(e,n,t[n]);return e};function p(e){var t;let n=0;const r=null!=(t=e.height)?t:window.innerHeight;void 0!==e.y&&(n=Math.min(e.y,r-f(e.items,16)));const[i,a]=o().useState(-1);return o().createElement("ul",{style:u({position:"absolute",boxShadow:"0 0.5rem 1rem rgba(0, 0, 0, 0.15)",borderRadius:"0.375rem",border:"1px solid rgba(0, 0, 0, 0.175)",background:"white",padding:"0.5em 0",top:`${n}px`},e.style)},e.items.map(((t,s)=>"divider"===t.type?o().createElement("li",{key:s,style:{listStyle:"none"}},o().createElement("hr",{style:{height:0,margin:"0.5em 0",border:0,borderTop:"1px solid rgba(0, 0, 0, 0.175)"}})):o().createElement("li",{key:s,style:{padding:"0 0.5em",paddingRight:"1.5em",position:"relative",listStyle:"none",background:i===s?"#f8f9fa":void 0,color:t.disabled?"rgba(33, 37, 41, 0.5)":void 0,cursor:t.disabled?"not-allowed":"pointer",whiteSpace:"nowrap",lineHeight:"32px"},onMouseEnter:()=>a(s),onClick:t.onClick},o().createElement("span",null,t.title),t.children&&t.children.length>0&&o().createElement("svg",{style:{right:"0.5em",height:"100%",position:"absolute"},xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 10 10",width:"10",height:"10"},o().createElement("polyline",{points:"2,0 8,5 2,10",stroke:"currentColor",fill:"none"})),i===s&&t.children&&t.children.length>0&&o().createElement(p,{items:t.children,height:r-d(e.items,s,16)-n,y:0,style:{left:"100%"}})))))}function d(e,t,n){return e.slice(0,t).reduce(((e,t)=>{var r;return e+("divider"===t.type?n+1:null!=(r=t.height)?r:32)}),0)+n/2+1}function f(e,t){return e.reduce(((e,n)=>{var r;return e+("divider"===n.type?t+1:null!=(r=n.height)?r:32)}),0)+t+2}},6199:(e,t,n)=>{"use strict";n.r(t),n.d(t,{ArrayEditor:()=>d,ObjectArrayEditor:()=>f});var r=n(3696),o=n(8640),i=n(7749),a=Object.defineProperty,s=Object.getOwnPropertySymbols,c=Object.prototype.hasOwnProperty,l=Object.prototype.propertyIsEnumerable,u=(e,t,n)=>t in e?a(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,p=(e,t)=>{for(var n in t||(t={}))c.call(t,n)&&u(e,n,t[n]);if(s)for(var n of s(t))l.call(t,n)&&u(e,n,t[n]);return e};function d(e){return e.inline?r.createElement("div",{style:p(p({},i.groupStyle),e.style)},r.createElement("div",null,e.items.map(((t,n)=>r.createElement("div",{key:n,style:{display:"flex",alignItems:"center",marginBottom:"3px"}},r.createElement("div",{style:{paddingRight:"5px",width:"14px"}},n+1),r.createElement("div",{style:{flex:1,display:"flex"}},r.cloneElement(t,(0,i.getChildProps)(e))),!e.readOnly&&r.createElement("div",null,e.remove&&r.createElement(o.Button,{onClick:()=>{var t;return null==(t=e.remove)?void 0:t.call(e,n)}},h),e.copy&&r.createElement(o.Button,{onClick:()=>{var t;return null==(t=e.copy)?void 0:t.call(e,n)}},v),n>0&&e.moveUp&&r.createElement(o.Button,{onClick:()=>{var t;return null==(t=e.moveUp)?void 0:t.call(e,n)}},m),n{var t;return null==(t=e.moveDown)?void 0:t.call(e,n)}},y)))))),!e.readOnly&&e.add&&r.createElement(o.Button,{onClick:e.add},g)):r.createElement("div",{style:p(p({},i.groupStyle),e.style)},e.items.map(((t,n)=>{var a,s;return r.createElement(r.Fragment,{key:n},r.createElement("div",{style:{marginBottom:"5px",marginTop:"5px"}},null!=(s=null==(a=e.title)?void 0:a.call(e,n))?s:n+1,!e.readOnly&&e.remove&&r.createElement(o.Button,{style:{marginLeft:"5px"},onClick:()=>{var t;return null==(t=e.remove)?void 0:t.call(e,n)}},h),!e.readOnly&&e.copy&&r.createElement(o.Button,{onClick:()=>{var t;return null==(t=e.copy)?void 0:t.call(e,n)}},v),!e.readOnly&&e.moveUp&&n>0&&r.createElement(o.Button,{onClick:()=>{var t;return null==(t=e.moveUp)?void 0:t.call(e,n)}},m),!e.readOnly&&e.moveDown&&n{var t;return null==(t=e.moveDown)?void 0:t.call(e,n)}},y)),r.createElement("div",{style:{display:"flex"}},r.cloneElement(t,(0,i.getChildProps)(e))))})),!e.readOnly&&e.add&&r.createElement(o.Button,{onClick:e.add},g))}function f(e){return 0===e.properties.length?null:r.createElement("div",{style:p(p({},i.groupStyle),e.style)},r.createElement("table",null,r.createElement("thead",null,r.createElement("tr",null,r.createElement("td",null),Object.entries(e.properties[0]).map((([e])=>r.createElement("td",{key:e},e))),!e.readOnly&&r.createElement("td",null))),r.createElement("tbody",null,e.properties.map(((t,n)=>r.createElement("tr",{key:n},r.createElement("td",{style:{paddingRight:"5px"}},n+1),Object.values(t).map(((t,n)=>r.createElement("td",{key:n},r.cloneElement(t,(0,i.getChildProps)(e))))),!e.readOnly&&r.createElement("td",null,e.remove&&r.createElement(o.Button,{onClick:()=>{var t;return null==(t=e.remove)?void 0:t.call(e,n)}},h),e.copy&&r.createElement(o.Button,{onClick:()=>{var t;return null==(t=e.copy)?void 0:t.call(e,n)}},v),e.moveUp&&n>0&&r.createElement(o.Button,{onClick:()=>{var t;return null==(t=e.moveUp)?void 0:t.call(e,n)}},m),e.moveDown&&n{var t;return null==(t=e.moveDown)?void 0:t.call(e,n)}},y))))))),!e.readOnly&&e.add&&r.createElement(o.Button,{onClick:e.add},g))}const g=r.createElement("svg",{style:{width:"20px",height:"20px"},viewBox:"0 0 1024 1024",xmlns:"http://www.w3.org/2000/svg"},r.createElement("path",{fill:"currentColor",d:"M480 480V128a32 32 0 0 1 64 0v352h352a32 32 0 1 1 0 64H544v352a32 32 0 1 1-64 0V544H128a32 32 0 0 1 0-64h352z"})),h=r.createElement("svg",{style:{width:"20px",height:"20px"},viewBox:"0 0 1024 1024",xmlns:"http://www.w3.org/2000/svg"},r.createElement("path",{fill:"currentColor",d:"M764.288 214.592 512 466.88 259.712 214.592a31.936 31.936 0 0 0-45.12 45.12L466.752 512 214.528 764.224a31.936 31.936 0 1 0 45.12 45.184L512 557.184l252.288 252.288a31.936 31.936 0 0 0 45.12-45.12L557.12 512.064l252.288-252.352a31.936 31.936 0 1 0-45.12-45.184z"})),m=r.createElement("svg",{style:{width:"20px",height:"20px"},viewBox:"0 0 1024 1024",xmlns:"http://www.w3.org/2000/svg"},r.createElement("path",{fill:"currentColor",d:"M572.235 205.282v600.365a30.118 30.118 0 1 1-60.235 0V205.282L292.382 438.633a28.913 28.913 0 0 1-42.646 0 33.43 33.43 0 0 1 0-45.236l271.058-288.045a28.913 28.913 0 0 1 42.647 0L834.5 393.397a33.43 33.43 0 0 1 0 45.176 28.913 28.913 0 0 1-42.647 0l-219.618-233.23z"})),y=r.createElement("svg",{style:{width:"20px",height:"20px"},viewBox:"0 0 1024 1024",xmlns:"http://www.w3.org/2000/svg"},r.createElement("path",{fill:"currentColor",d:"M544 805.888V168a32 32 0 1 0-64 0v637.888L246.656 557.952a30.72 30.72 0 0 0-45.312 0 35.52 35.52 0 0 0 0 48.064l288 306.048a30.72 30.72 0 0 0 45.312 0l288-306.048a35.52 35.52 0 0 0 0-48 30.72 30.72 0 0 0-45.312 0L544 805.824z"})),v=r.createElement("svg",{style:{width:"20px",height:"20px"},viewBox:"0 0 1024 1024",xmlns:"http://www.w3.org/2000/svg"},r.createElement("path",{fill:"currentColor",d:"M128 320v576h576V320H128zm-32-64h640a32 32 0 0 1 32 32v640a32 32 0 0 1-32 32H96a32 32 0 0 1-32-32V288a32 32 0 0 1 32-32zM960 96v704a32 32 0 0 1-32 32h-96v-64h64V128H384v64h-64V96a32 32 0 0 1 32-32h576a32 32 0 0 1 32 32zM256 672h320v64H256v-64zm0-192h320v64H256v-64z"}))},2290:(e,t,n)=>{"use strict";n.r(t),n.d(t,{BooleanEditor:()=>o});var r=n(3696);function o(e){return r.createElement("div",{style:e.style},r.createElement("input",{type:"checkbox",disabled:e.readOnly||!e.setValue,checked:e.value,onChange:t=>{!e.readOnly&&e.setValue&&e.setValue(t.target.checked)}}))}},8640:(e,t,n)=>{"use strict";n.r(t),n.d(t,{Button:()=>g,Label:()=>h});var r=n(3696),o=n(7749),i=Object.defineProperty,a=Object.defineProperties,s=Object.getOwnPropertyDescriptors,c=Object.getOwnPropertySymbols,l=Object.prototype.hasOwnProperty,u=Object.prototype.propertyIsEnumerable,p=(e,t,n)=>t in e?i(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,d=(e,t)=>{for(var n in t||(t={}))l.call(t,n)&&p(e,n,t[n]);if(c)for(var n of c(t))u.call(t,n)&&p(e,n,t[n]);return e},f=(e,t)=>a(e,s(t));function g(e){return r.createElement("button",f(d({},e),{style:d(d(d({},o.buttonStyle),e.style),e.disabled?o.disabledStyle:{})})," ",e.children)}function h(e){return r.createElement("span",f(d({},e),{style:d(d({},o.labelStyle),e.style)})," ",e.children)}},7749:(e,t,n)=>{"use strict";n.r(t),n.d(t,{buttonStyle:()=>p,controlStyle:()=>u,disabledStyle:()=>d,getChildProps:()=>h,groupStyle:()=>g,labelStyle:()=>f});var r=Object.defineProperty,o=Object.defineProperties,i=Object.getOwnPropertyDescriptors,a=Object.getOwnPropertySymbols,s=Object.prototype.hasOwnProperty,c=Object.prototype.propertyIsEnumerable,l=(e,t,n)=>t in e?r(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n;const u={outline:0,padding:"0.375rem 0.75rem",fontSize:"1rem",fontWeight:400,fontFamily:"monospace",lineHeight:1.5,color:"#212529",backgroundColor:"#fff",backgroundClip:"padding-box",border:"1px solid #ced4da",appearance:"none",borderRadius:"0.25rem",flex:1,marginBottom:"3px"},p={display:"inline-block",fontWeight:400,lineHeight:1,color:"#212529",textAlign:"center",textDecoration:"none",verticalAlign:"middle",cursor:"pointer",userSelect:"none",backgroundColor:"transparent",border:"1px solid transparent",padding:"0.375rem 0.75rem",fontSize:"1rem",borderRadius:"0.25rem"},d={cursor:"not-allowed",opacity:.5},f=o(((e,t)=>{for(var n in t||(t={}))s.call(t,n)&&l(e,n,t[n]);if(a)for(var n of a(t))c.call(t,n)&&l(e,n,t[n]);return e})({},p),i({cursor:void 0}));const g={padding:"10px",border:"1px solid rgba(0,0,0,.125)",borderRadius:"0.25rem",flex:1,marginBottom:"3px"};function h(e){const t={};return void 0!==e.readOnly&&(t.readOnly=e.readOnly),t}},1030:(e,t,n)=>{"use strict";n.r(t),n.d(t,{DialogContainer:()=>a});var r=n(3696),o=n(8640),i=n(7749);function a(e){const[t,n]=r.useState(!1);return r.createElement(r.Fragment,null,r.createElement(o.Button,{onClick:()=>n(!0)},s),t&&r.createElement("div",{style:{position:"fixed",inset:0,background:"rgba(0,0,0,0.5)",display:"flex",justifyContent:"center",alignItems:"center",zIndex:2},onClick:()=>n(!1)},r.createElement("div",{style:{width:"600px",display:"flex",background:"white"},onClick:e=>e.stopPropagation()},r.cloneElement(e.children,(0,i.getChildProps)(e)))))}const s=r.createElement("svg",{style:{width:"20px",height:"20px"},viewBox:"0 0 1024 1024",xmlns:"http://www.w3.org/2000/svg"},r.createElement("path",{fill:"currentColor",d:"M832 512a32 32 0 1 1 64 0v352a32 32 0 0 1-32 32H160a32 32 0 0 1-32-32V160a32 32 0 0 1 32-32h352a32 32 0 0 1 0 64H192v640h640V512z"}),r.createElement("path",{fill:"currentColor",d:"m469.952 554.24 52.8-7.552L847.104 222.4a32 32 0 1 0-45.248-45.248L477.44 501.44l-7.552 52.8zm422.4-422.4a96 96 0 0 1 0 135.808l-331.84 331.84a32 32 0 0 1-18.112 9.088L436.8 623.68a32 32 0 0 1-36.224-36.224l15.104-105.6a32 32 0 0 1 9.024-18.112l331.904-331.84a96 96 0 0 1 135.744 0z"}))},6209:(e,t,n)=>{"use strict";n.r(t),n.d(t,{EnumArrayEditor:()=>d,EnumEditor:()=>f});var r=n(3696),o=n(8662),i=n(7749),a=Object.defineProperty,s=Object.getOwnPropertySymbols,c=Object.prototype.hasOwnProperty,l=Object.prototype.propertyIsEnumerable,u=(e,t,n)=>t in e?a(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,p=(e,t)=>{for(var n in t||(t={}))c.call(t,n)&&u(e,n,t[n]);if(s)for(var n of s(t))l.call(t,n)&&u(e,n,t[n]);return e};function d(e){return r.createElement("div",{style:e.style},e.enums.map(((t,n)=>{var i,a;return r.createElement("label",{key:t,style:{marginRight:"10px"}},r.createElement("input",{type:"checkbox",checked:e.value.includes(t),style:{marginRight:"5px"},disabled:e.readOnly||!e.setValue,onChange:()=>{if(e.readOnly||!e.setValue)return;const n=e.value.indexOf(t);e.setValue((0,o.produce)(e.value,(e=>{n>=0?e.splice(n,1):e.push((0,o.castDraft)(t))})))}}),null!=(a=null==(i=e.enumTitles)?void 0:i[n])?a:t)})))}function f(e){return e.select?r.createElement("select",{style:p(p({},i.controlStyle),e.style),disabled:e.readOnly||!e.setValue,value:e.value,onChange:t=>{if(e.readOnly||!e.setValue)return;let n=t.target.value;"number"==typeof e.enums[0]&&(n=+n),e.setValue(n)}},e.enums.map(((t,n)=>{var o,i;return r.createElement("option",{key:t,value:t},null!=(i=null==(o=e.enumTitles)?void 0:o[n])?i:t)}))):r.createElement("div",{style:e.style},e.enums.map(((t,n)=>{var o,i;return r.createElement("label",{key:t,style:{marginRight:"10px"}},r.createElement("input",{type:"radio",disabled:e.readOnly||!e.setValue,checked:e.value===t,style:{marginRight:"5px"},onChange:()=>{!e.readOnly&&e.setValue&&e.setValue(t)}}),null!=(i=null==(o=e.enumTitles)?void 0:o[n])?i:t)})))}},8174:(e,t,n)=>{"use strict";n.r(t);var r=n(6199),o={};for(const e in r)"default"!==e&&(o[e]=()=>r[e]);n.d(t,o);var i=n(2290);o={};for(const e in i)"default"!==e&&(o[e]=()=>i[e]);n.d(t,o);var a=n(1030);o={};for(const e in a)"default"!==e&&(o[e]=()=>a[e]);n.d(t,o);var s=n(6209);o={};for(const e in s)"default"!==e&&(o[e]=()=>s[e]);n.d(t,o);var c=n(4993);o={};for(const e in c)"default"!==e&&(o[e]=()=>c[e]);n.d(t,o);var l=n(6467);o={};for(const e in l)"default"!==e&&(o[e]=()=>l[e]);n.d(t,o);var u=n(2729);o={};for(const e in u)"default"!==e&&(o[e]=()=>u[e]);n.d(t,o);var p=n(3675);o={};for(const e in p)"default"!==e&&(o[e]=()=>p[e]);n.d(t,o);var d=n(8640);o={};for(const e in d)"default"!==e&&(o[e]=()=>d[e]);n.d(t,o);var f=n(7749);o={};for(const e in f)"default"!==e&&(o[e]=()=>f[e]);n.d(t,o)},4993:(e,t,n)=>{"use strict";n.r(t),n.d(t,{NumberEditor:()=>d});var r=n(3696),o=n(3975),i=n(7749),a=Object.defineProperty,s=Object.getOwnPropertySymbols,c=Object.prototype.hasOwnProperty,l=Object.prototype.propertyIsEnumerable,u=(e,t,n)=>t in e?a(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,p=(e,t)=>{for(var n in t||(t={}))c.call(t,n)&&u(e,n,t[n]);if(s)for(var n of s(t))l.call(t,n)&&u(e,n,t[n]);return e};function d(e){var t;const[n,a]=r.useState("color"===e.type?(0,o.getColorString)(e.value):e.value.toString());r.useEffect((()=>{a("color"===e.type?(0,o.getColorString)(e.value):e.value.toString())}),[e.value]);const s=()=>{if(e.readOnly||!e.setValue)return;let t;t="color"===e.type?(0,o.colorStringToNumber)(n):+n,isNaN(t)||t===e.value||e.setValue(t)};let c={};return"color"===e.type&&(c={flex:"unset",padding:0}),!e.readOnly&&e.setValue||(c.opacity=.5),r.createElement("input",{value:n,type:null!=(t=e.type)?t:"number",disabled:e.readOnly||!e.setValue,onChange:t=>{!e.readOnly&&e.setValue&&a(t.target.value)},style:p(p(p({},i.controlStyle),e.style),c),onKeyDown:t=>{var n;"Enter"===t.key&&s(),"Escape"!==t.key?t.stopPropagation():null==(n=e.onCancel)||n.call(e)},onBlur:()=>{setTimeout((()=>{s()}),0)}})}},6467:(e,t,n)=>{"use strict";n.r(t),n.d(t,{ObjectEditor:()=>p});var r=n(3696),o=n(7749),i=Object.defineProperty,a=Object.getOwnPropertySymbols,s=Object.prototype.hasOwnProperty,c=Object.prototype.propertyIsEnumerable,l=(e,t,n)=>t in e?i(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,u=(e,t)=>{for(var n in t||(t={}))s.call(t,n)&&l(e,n,t[n]);if(a)for(var n of a(t))c.call(t,n)&&l(e,n,t[n]);return e};function p(e){const t=Object.entries(e.properties).map((([t,n])=>[t,Array.isArray(n)?n.map(((t,n)=>t?r.cloneElement(t,u({key:n},(0,o.getChildProps)(e))):null)):r.cloneElement(n,(0,o.getChildProps)(e))]));return e.inline?r.createElement("table",{style:o.groupStyle},r.createElement("thead",null),r.createElement("tbody",null,t.map((([e,t])=>r.createElement("tr",{key:e},r.createElement("td",{style:{paddingRight:"5px"}},e),r.createElement("td",{style:{display:"flex",flexDirection:"column"}},t)))))):r.createElement("div",{style:o.groupStyle},t.map((([e,t])=>r.createElement(r.Fragment,{key:e},r.createElement("div",{style:{marginTop:"5px",marginBottom:"5px"}},e),r.createElement("div",{style:{display:"flex",flexDirection:"column"}},t)))))}},2729:(e,t,n)=>{"use strict";n.r(t),n.d(t,{StringEditor:()=>p});var r=n(3696),o=n(7749),i=Object.defineProperty,a=Object.getOwnPropertySymbols,s=Object.prototype.hasOwnProperty,c=Object.prototype.propertyIsEnumerable,l=(e,t,n)=>t in e?i(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,u=(e,t)=>{for(var n in t||(t={}))s.call(t,n)&&l(e,n,t[n]);if(a)for(var n of a(t))c.call(t,n)&&l(e,n,t[n]);return e};function p(e){var t;const[n,i]=r.useState(e.value);r.useEffect((()=>{i(e.value)}),[e.value]);const a=()=>{!e.readOnly&&e.setValue&&n!==e.value&&e.setValue(n)};let s,c={};return"color"===e.type&&(c={flex:"unset",padding:0}),!e.readOnly&&e.setValue||(c.opacity=.5),e.textarea?r.createElement("textarea",{value:n,disabled:e.readOnly||!e.setValue,onChange:t=>{!e.readOnly&&e.setValue&&i(t.target.value)},onKeyDown:t=>{var n;"Escape"!==t.key?t.stopPropagation():null==(n=e.onCancel)||n.call(e)},autoFocus:e.autoFocus,onBlur:()=>{setTimeout((()=>{a()}),0)},style:u(u(u({},o.controlStyle),e.style),c)}):((function(e){if(!e||e.length<=8)return!1;if("http://"!==e.substr(0,7)&&"https://"!==e.substr(0,8))return!1;const t=e.substr(e.length-4,4);return-1!==d.indexOf(t)}(e.value)||!!(l=e.value)&&0===l.indexOf("data:image/")&&-1!==l.indexOf(";base64,"))&&(s=r.createElement("img",{src:e.value,style:{display:"block",height:"auto",margin:"6px 0px",maxWidth:"100%"}})),r.createElement(r.Fragment,null,r.createElement("input",{value:n,disabled:e.readOnly||!e.setValue,type:null!=(t=e.type)?t:"text",onChange:t=>{!e.readOnly&&e.setValue&&i(t.target.value)},onKeyDown:t=>{var n;"Enter"===t.key&&a(),"Escape"!==t.key?t.stopPropagation():null==(n=e.onCancel)||n.call(e)},onBlur:()=>{setTimeout((()=>{a()}),0)},style:u(u(u({},o.controlStyle),e.style),c)}),s));var l}const d=[".png",".jpg",".bmp",".gif"]},3675:(e,t,n)=>{"use strict";n.r(t),n.d(t,{getArrayEditorProps:()=>a,useJsonEditorData:()=>i});var r=n(8662),o=n(3696);function i(e){const[t,n]=o.useState(e);return{value:t,update:e=>o=>{n((0,r.produce)(t,(t=>{e(t,o)})))},getArrayProps:(e,o)=>a(e,o,(e=>{n((0,r.produce)(t,(t=>{e(t)})))}))}}function a(e,t,n){return{add:()=>n((n=>{e(n).push("function"==typeof t?t():t)})),remove:t=>n((n=>{e(n).splice(t,1)})),copy:t=>n((n=>{const r=e(n);r.splice(t,0,r[t])})),moveUp:t=>n((n=>{const r=e(n);r.splice(t-1,0,r[t]),r.splice(t+1,1)})),moveDown:t=>n((n=>{const r=e(n);r.splice(t+2,0,r[t]),r.splice(t,1)}))}}},6176:(e,t,n)=>{"use strict";n.r(t),n.d(t,{codeRenderTarget:()=>o});var r=n(7727);const o={type:"code",renderResult:(e,t,n,r)=>`target.renderResult([\n${e.map((e=>" "+e)).join(",\n")}\n], ${t}, ${n}, ${i(r)})`,renderEmpty:()=>"target.renderEmpty()",renderGroup:(e,t)=>`target.renderGroup([\n${e.map((e=>" "+e)).join(",\n")}\n], ${i(t)})`,renderRect:(e,t,n,r,o)=>`target.renderRect(${e}, ${t}, ${n}, ${r}, ${i(o)})`,renderPolyline:(e,t)=>`target.renderPolyline(${i(e)}, ${i(t)})`,renderPolygon:(e,t)=>`target.renderPolygon(${i(e)}, ${i(t)})`,renderCircle:(e,t,n,r)=>`target.renderCircle(${e}, ${t}, ${n}, ${i(r)})`,renderEllipse:(e,t,n,r,o)=>`target.renderEllipse(${e}, ${t}, ${n}, ${r}, ${i(o)})`,renderArc:(e,t,n,r,o,a)=>`target.renderArc(${e}, ${t}, ${n}, ${r}, ${o}, ${i(a)})`,renderEllipseArc:(e,t,n,r,o,a,s)=>`target.renderEllipseArc(${e}, ${t}, ${n}, ${r}, ${o}, ${a}, ${i(s)})`,renderPathCommands:(e,t)=>`target.renderPathCommands(${i(e)}, ${i(t)})`,renderText:(e,t,n,r,o,a,s)=>`target.renderText(${e}, ${t}, ${i(n)}, ${i(r)}, ${o}, ${i(a)}, ${i(s)})`,renderImage:(e,t,n,r,o,a)=>`target.renderImage(${i(e)}, ${t}, ${n}, ${r}, ${o}, ${i(a)})`,renderPath:(e,t)=>`target.renderPath(${i(e)}, ${i(t)})`,renderRay:(e,t,n,r)=>`target.renderRay(${e}, ${t}, ${n}, ${i(r)})`};function i(e){return(0,r.printJsToCode)(e,{functionPrinter:e=>"() => "+e()})}},3876:(e,t,n)=>{"use strict";n.r(t),n.d(t,{createWebglRenderer:()=>_,defaultVec4Color:()=>R,forEachPatternGraphicRepeatedGraphic:()=>G,getImageGraphic:()=>A,getNumArrayPointsBounding:()=>U,getPathGraphics:()=>T,getTextGraphic:()=>S,getTextureGraphicMatrix:()=>j,getWorldMatrix:()=>V,setCanvasLineDash:()=>B});var r=n(9397),o=n(2087),i=n(7237),a=n(3975),s=n(5147),c=n(2792),l=n(5773),u=n(1796),p=n(2318),d=n(7713),f=n(1715),g=n(7764),h=n(8392),m=n(3793),y=Object.defineProperty,v=Object.defineProperties,x=Object.getOwnPropertyDescriptors,b=Object.getOwnPropertySymbols,C=Object.prototype.hasOwnProperty,E=Object.prototype.propertyIsEnumerable,P=(e,t,n)=>t in e?y(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,w=(e,t)=>{for(var n in t||(t={}))C.call(t,n)&&P(e,n,t[n]);if(b)for(var n of b(t))E.call(t,n)&&P(e,n,t[n]);return e},k=(e,t)=>v(e,x(t));function _(e){const t=e.getContext("webgl",{antialias:!0,stencil:!0,premultipliedAlpha:!1});if(!t)return;t.enable(t.BLEND),t.blendFunc(t.SRC_ALPHA,t.ONE_MINUS_SRC_ALPHA);const n=new g.Lazy((()=>r.createProgramInfo(t,["\n attribute vec2 position;\n uniform mat3 matrix;\n uniform float flipY;\n void main() {\n gl_Position = vec4((matrix * vec3(position, 1)).xy * vec2(1, flipY), 0, 1);\n }\n ","\n precision mediump float;\n uniform vec4 color;\n void main() {\n gl_FragColor = color;\n }"]))),o=new g.Lazy((()=>r.createProgramInfo(t,["\n attribute vec2 position;\n attribute vec2 base;\n uniform mat3 matrix;\n uniform float flipY;\n uniform float scale;\n void main() {\n vec2 p = (position - base) * scale + base;\n gl_Position = vec4((matrix * vec3(p, 1)).xy * vec2(1, flipY), 0, 1);\n }\n ","\n precision mediump float;\n uniform vec4 color;\n void main() {\n gl_FragColor = color;\n }"]))),i=new g.Lazy((()=>r.createProgramInfo(t,["\n attribute vec2 position;\n uniform mat3 matrix;\n varying vec2 texcoord;\n\n void main () {\n gl_Position = vec4((matrix * vec3(position, 1)).xy, 0, 1);\n texcoord = position;\n }\n ","\n precision mediump float;\n\n varying vec2 texcoord;\n uniform sampler2D texture;\n uniform vec4 color;\n\n void main() {\n if (texcoord.x < 0.0 || texcoord.x > 1.0 ||\n texcoord.y < 0.0 || texcoord.y > 1.0) {\n discard;\n }\n vec4 color = texture2D(texture, texcoord) * color;\n if (color.a < 0.1) {\n discard;\n }\n gl_FragColor = color;\n }"]))),c=new g.Lazy((()=>r.createProgramInfo(t,["\n attribute vec2 position;\n uniform mat3 matrix;\n uniform float flipY;\n varying vec2 texcoord;\n\n void main () {\n gl_Position = vec4((matrix * vec3(position, 1)).xy * vec2(1, flipY), 0, 1);\n texcoord = position;\n }\n ","\n precision mediump float;\n\n varying vec2 texcoord;\n uniform sampler2D texture;\n uniform float opacity;\n\n void main() {\n if (texcoord.x < 0.0 || texcoord.x > 1.0 ||\n texcoord.y < 0.0 || texcoord.y > 1.0) {\n discard;\n }\n gl_FragColor = texture2D(texture, texcoord) * vec4(1, 1, 1, opacity);\n }"]))),l=new g.Lazy((()=>r.createProgramInfo(t,["\n attribute vec2 position;\n uniform mat3 matrix;\n uniform float flipY;\n varying vec2 texcoord;\n\n void main () {\n gl_Position = vec4((matrix * vec3(position, 1)).xy * vec2(1, flipY), 0, 1);\n texcoord = position;\n }\n ","\n precision mediump float;\n\n varying vec2 texcoord;\n uniform sampler2D texture;\n uniform float opacity;\n uniform float colorMatrix[20];\n\n void main() {\n if (texcoord.x < 0.0 || texcoord.x > 1.0 ||\n texcoord.y < 0.0 || texcoord.y > 1.0) {\n discard;\n }\n vec4 c = texture2D(texture, texcoord) * vec4(1, 1, 1, opacity);\n\t\t\tgl_FragColor.r = colorMatrix[0] * c.r + colorMatrix[1] * c.g + colorMatrix[2] * c.b + colorMatrix[3] * c.a + colorMatrix[4];\n\t\t\tgl_FragColor.g = colorMatrix[5] * c.r + colorMatrix[6] * c.g + colorMatrix[7] * c.b + colorMatrix[8] * c.a + colorMatrix[9];\n\t\t\tgl_FragColor.b = colorMatrix[10] * c.r + colorMatrix[11] * c.g + colorMatrix[12] * c.b + colorMatrix[13] * c.a + colorMatrix[14];\n\t\t\tgl_FragColor.a = colorMatrix[15] * c.r + colorMatrix[16] * c.g + colorMatrix[17] * c.b + colorMatrix[18] * c.a + colorMatrix[19];\n }"]))),u=new g.Lazy((()=>r.createProgramInfo(t,["\n attribute vec2 position;\n uniform mat3 matrix;\n uniform float flipY;\n varying vec2 texcoord;\n\n void main () {\n gl_Position = vec4((matrix * vec3(position, 1)).xy * vec2(1, flipY), 0, 1);\n texcoord = position;\n }\n ","\n precision mediump float;\n\n varying vec2 texcoord;\n uniform sampler2D texture;\n uniform float opacity;\n uniform vec2 px;\n\n void main() {\n if (texcoord.x < 0.0 || texcoord.x > 1.0 ||\n texcoord.y < 0.0 || texcoord.y > 1.0) {\n discard;\n }\n\t\t\tgl_FragColor = vec4(0.0);\n\t\t\tgl_FragColor += texture2D(texture, texcoord + vec2(-7.0*px.x, -7.0*px.y))*0.0044299121055113265;\n\t\t\tgl_FragColor += texture2D(texture, texcoord + vec2(-6.0*px.x, -6.0*px.y))*0.00895781211794;\n\t\t\tgl_FragColor += texture2D(texture, texcoord + vec2(-5.0*px.x, -5.0*px.y))*0.0215963866053;\n\t\t\tgl_FragColor += texture2D(texture, texcoord + vec2(-4.0*px.x, -4.0*px.y))*0.0443683338718;\n\t\t\tgl_FragColor += texture2D(texture, texcoord + vec2(-3.0*px.x, -3.0*px.y))*0.0776744219933;\n\t\t\tgl_FragColor += texture2D(texture, texcoord + vec2(-2.0*px.x, -2.0*px.y))*0.115876621105;\n\t\t\tgl_FragColor += texture2D(texture, texcoord + vec2(-1.0*px.x, -1.0*px.y))*0.147308056121;\n\t\t\tgl_FragColor += texture2D(texture, texcoord )*0.159576912161;\n\t\t\tgl_FragColor += texture2D(texture, texcoord + vec2( 1.0*px.x, 1.0*px.y))*0.147308056121;\n\t\t\tgl_FragColor += texture2D(texture, texcoord + vec2( 2.0*px.x, 2.0*px.y))*0.115876621105;\n\t\t\tgl_FragColor += texture2D(texture, texcoord + vec2( 3.0*px.x, 3.0*px.y))*0.0776744219933;\n\t\t\tgl_FragColor += texture2D(texture, texcoord + vec2( 4.0*px.x, 4.0*px.y))*0.0443683338718;\n\t\t\tgl_FragColor += texture2D(texture, texcoord + vec2( 5.0*px.x, 5.0*px.y))*0.0215963866053;\n\t\t\tgl_FragColor += texture2D(texture, texcoord + vec2( 6.0*px.x, 6.0*px.y))*0.00895781211794;\n\t\t\tgl_FragColor += texture2D(texture, texcoord + vec2( 7.0*px.x, 7.0*px.y))*0.0044299121055113265;\n }"]))),p=new g.Lazy((()=>r.createProgramInfo(t,["\n attribute vec2 position;\n uniform mat3 matrix;\n varying vec2 texcoord;\n\n void main () {\n gl_Position = vec4((matrix * vec3(position, 1)).xy, 0, 1);\n texcoord = position;\n }\n ","\n precision mediump float;\n\n varying vec2 texcoord;\n uniform sampler2D texture;\n uniform vec4 color;\n\n void main() {\n if (texcoord.x < 0.0 || texcoord.x > 1.0 ||\n texcoord.y < 0.0 || texcoord.y > 1.0) {\n discard;\n }\n vec4 color2 = texture2D(texture, texcoord);\n vec4 color3 = color2 * color;\n if (color3.a < 0.1) {\n discard;\n }\n gl_FragColor = color2;\n }"]))),f=new g.Lazy((()=>r.createProgramInfo(t,["\n attribute vec2 position;\n attribute vec4 color;\n uniform mat3 matrix;\n uniform float flipY;\n varying vec4 v_color;\n\n void main () {\n gl_Position = vec4((matrix * vec3(position, 1)).xy * vec2(1, flipY), 0, 1);\n v_color = color;\n }\n ","\n precision mediump float;\n\n varying vec4 v_color;\n\n void main() {\n gl_FragColor = v_color;\n }"]))),h=r.primitives.createXYQuadBufferInfo(t),m=new d.WeakmapCache,y=new d.WeakmapCache,v=e=>{const t={};let n;return"color matrix"===e.type?(n=l.instance,t.colorMatrix=e.value):(n=u.instance,t.px=e.value),{programInfo:n,filterUniforms:t}},x=()=>{r.drawObjectList(t,b),b=[]};let b=[];const C=(n,o,i,a,l)=>{let u;if(x(),n.graphics.some((e=>e.pattern))){const a=r.createFramebufferInfo(t,void 0,e.width,e.height);r.bindFramebufferInfo(t,a),G(n,o,i,((e,t)=>{E(e,t,l)})),x(),u=a.attachments[0],t.bindFramebuffer(t.FRAMEBUFFER,null),t.viewport(0,0,t.canvas.width,t.canvas.height)}t.clearStencil(0),t.clear(t.STENCIL_BUFFER_BIT),t.colorMask(!1,!1,!1,!1),t.enable(t.STENCIL_TEST),t.stencilFunc(t.ALWAYS,1,255),t.stencilOp(t.KEEP,t.KEEP,t.REPLACE),r.drawObjectList(t,[a]),t.stencilFunc(t.EQUAL,1,255),t.stencilOp(t.KEEP,t.KEEP,t.KEEP),t.colorMask(!0,!0,!0,!0),u?r.drawObjectList(t,[{programInfo:c.instance,bufferInfo:h,uniforms:{matrix:s.m3.projection(1,1),opacity:null!=l?l:1,texture:u,flipY:-1}}]):(G(n,o,i,((e,t)=>{E(e,t,l)})),x()),t.disable(t.STENCIL_TEST)},E=(e,l,u,d)=>{var g,E;const P=(0,a.mergeOpacities)(e.opacity,u),_=(0,a.mergeOpacityToColor)(e.color,P);if("texture"===e.type){const{textureMatrix:n,width:o,height:a}=j(l,e);let u=m.get(e.src,(()=>r.createTexture(t,{src:e.src})));if(e.filters&&e.filters.length>1){x();const n=[];for(let o=0;o0){const t=v(e.filters[e.filters.length-1]);d=t.programInfo,f=t.filterUniforms}else d=e.pattern?p.instance:e.color?i.instance:c.instance;const y={programInfo:d,bufferInfo:h,uniforms:k(w({matrix:n,color:_,opacity:null!=(E=e.opacity)?E:1,texture:u},f),{flipY:1})};e.pattern?C(e.pattern,l,{xMin:e.x,yMin:e.y,xMax:e.x+o,yMax:e.y+a},y,P):b.push(y)}else{const i={programInfo:e.colors?f.instance:e.basePoints&&d?o.instance:n.instance,bufferInfo:y.get(e.points,(()=>{const n={position:{numComponents:2,data:e.points}};return e.colors&&(n.color={numComponents:4,data:e.colors}),e.basePoints&&d&&(n.base={numComponents:2,data:e.basePoints}),r.createBufferInfoFromArrays(t,n)})),uniforms:{color:_,matrix:l,flipY:1,scale:d?1/d:void 0},type:"triangles"===e.type?t.TRIANGLES:"line strip"===e.type?t.LINE_STRIP:"lines"===e.type?t.LINES:t.TRIANGLE_STRIP};if(e.pattern){const t=U(e.points);C(e.pattern,l,t,i,P)}else b.push(i)}};return(n,o,i,a,c,l)=>{t.viewport(0,0,t.canvas.width,t.canvas.height),r.resizeCanvasToDisplaySize(e),t.clearColor(...o),t.clear(t.COLOR_BUFFER_BIT|t.DEPTH_BUFFER_BIT|t.STENCIL_BUFFER_BIT);const u=V(t.canvas,i,a,c,l);for(const e of n){const t=e.matrix?s.m3.multiply(u,e.matrix):u;E(e,t,void 0,c)}x()}}function S(e,t,n,r,o,i,s){var c;const l=null!=(c=null==s?void 0:s.strokeWidth)?c:0,u=()=>{var e,t;const c=document.createElement("canvas"),u=c.getContext("2d");if(!u)return;const p=`${null!=(e=null==s?void 0:s.fontWeight)?e:"normal"} ${null!=(t=null==s?void 0:s.fontStyle)?t:"normal"} ${o}px ${i}`;u.font=p;const d=u.measureText(n);return u.canvas.width=Math.ceil(d.width)+2,u.canvas.height=o+d.actualBoundingBoxDescent,u.font=p,(void 0!==r||(null==s?void 0:s.fillLinearGradient)||(null==s?void 0:s.fillRadialGradient))&&(u.fillStyle=void 0!==(null==s?void 0:s.strokeColor)&&"number"==typeof r?(0,a.getColorString)(r,s.fillOpacity):"white",u.fillText(n,0,o)),void 0!==(null==s?void 0:s.strokeColor)?(u.strokeStyle=void 0!==r&&"number"==typeof r?(0,a.getColorString)(s.strokeColor,s.strokeOpacity):"white",void 0!==s.strokeWidth&&(u.lineWidth=s.strokeWidth),B(u,s),u.strokeText(n,0,o)):((null==s?void 0:s.strokePattern)||(null==s?void 0:s.strokeLinearGradient)||(null==s?void 0:s.strokeRadialGradient))&&(u.strokeStyle="white",void 0!==s.strokeWidth&&(u.lineWidth=s.strokeWidth-1),B(u,s),u.strokeText(n,0,o-l)),{textMetrics:d,imageData:u.getImageData(0,0,c.width,c.height),canvas:c}},p=(null==s?void 0:s.cacheKey)?L.get(s.cacheKey,n,u):u();if(!p)return;const{imageData:d,textMetrics:f,canvas:g}=p;let h=t-d.height+l+f.actualBoundingBoxDescent;"top"===(null==s?void 0:s.textBaseline)?h+=f.actualBoundingBoxAscent+f.actualBoundingBoxDescent/2:"middle"===(null==s?void 0:s.textBaseline)?h+=(f.actualBoundingBoxAscent-f.actualBoundingBoxDescent)/2:"bottom"===(null==s?void 0:s.textBaseline)&&(h-=f.fontBoundingBoxDescent);let m,y=e;if("right"===(null==s?void 0:s.textAlign)?y-=d.width:"center"===(null==s?void 0:s.textAlign)&&(y-=d.width/2),(null==s?void 0:s.strokePattern)?m=s.strokePattern:(null==s?void 0:s.strokeLinearGradient)?m={graphics:[z(s.strokeLinearGradient,[{x:y,y:h},{x:y+d.width,y:h},{x:y,y:t},{x:y+d.width,y:t}])]}:(null==s?void 0:s.strokeRadialGradient)?m={graphics:[F(s.strokeRadialGradient,[{x:y,y:h},{x:y+d.width,y:h},{x:y,y:t},{x:y+d.width,y:t}])]}:(null==s?void 0:s.fillLinearGradient)?m={graphics:[z(s.fillLinearGradient,[{x:y,y:h},{x:y+d.width,y:h},{x:y,y:t},{x:y+d.width,y:t}])]}:(null==s?void 0:s.fillRadialGradient)&&(m={graphics:[F(s.fillRadialGradient,[{x:y,y:h},{x:y+d.width,y:h},{x:y,y:t},{x:y+d.width,y:t}])]}),m)return{type:"texture",x:y,y:h,src:d,canvas:g,color:R,pattern:m};if(void 0!==r&&"number"!=typeof r)return{type:"texture",x:y,y:h,src:d,canvas:g,color:R,pattern:r};if(void 0===r){if(void 0===(null==s?void 0:s.strokeColor))return;return{type:"texture",x:y,y:h,color:(0,a.colorNumberToVec)(s.strokeColor,s.strokeOpacity),src:d,canvas:g}}return void 0!==(null==s?void 0:s.strokeColor)?{type:"texture",x:y,y:h,src:d,canvas:g}:{type:"texture",x:y,y:h,color:(0,a.colorNumberToVec)(r,null==s?void 0:s.fillOpacity),src:d,canvas:g}}const R=[0,0,0,1];function T(e,t,n){var r,i,s,l,p;const d=null!=(r=null==n?void 0:n.strokeWidth)?r:1,f=!!(null==n?void 0:n.closed)||(null!=(i=null==n?void 0:n.lineCap)?i:m.defaultLineCap),g=null!=(s=null==n?void 0:n.lineJoin)?s:m.defaultLineJoin,h="miter"===g?null!=(l=null==n?void 0:n.miterLimit)?l:m.defaultMiterLimit:g,y=(0,a.colorNumberToVec)(null!=(p=null==n?void 0:n.strokeColor)?p:0,null==n?void 0:n.strokeOpacity),v=[];if(d){if(null==n?void 0:n.dashArray){const t=n.dashArray;e=e.map((e=>(!0===f&&(e=(0,u.polygonToPolyline)(e)),(0,u.dashedPolylineToLines)(e,t,void 0,n.dashOffset)))).flat()}if(t&&(0,c.isSameNumber)(d,1))v.push({type:"lines",points:D.get(e,f,(()=>e.map((e=>O.get(e,f,(()=>{!0===f&&(e=(0,u.polygonToPolyline)(e));const t=[];for(let n=1;n{const t={points:[],base:[]};for(const n of e){const e=M.get(n,d,f,h,(()=>{const e=(0,m.getPolylineTriangles)(n,d,f,h);return{points:(0,m.triangleStripToTriangles)(e.points),base:(0,m.triangleStripToTriangles)(e.base)}}));t.points.push(...e.points),t.base.push(...e.base)}return t}));let o,i=y;(null==n?void 0:n.strokePattern)?(o=n.strokePattern,i=[0,0,0,0]):(null==n?void 0:n.strokeLinearGradient)?(o={graphics:[z(n.strokeLinearGradient,N(r.points))]},i=[0,0,0,0]):(null==n?void 0:n.strokeRadialGradient)&&(o={graphics:[F(n.strokeRadialGradient,N(r.points))]},i=[0,0,0,0]),v.push({type:"triangles",points:r.points,basePoints:t?r.base:void 0,color:i,pattern:o})}}if(void 0!==(null==n?void 0:n.fillColor)||void 0!==(null==n?void 0:n.fillPattern)||void 0!==(null==n?void 0:n.fillLinearGradient)||void 0!==(null==n?void 0:n.fillRadialGradient)){const t=[],r=[];for(let n=0;n[e.x,e.y])).flat());const i=(0,o.default)(t,r),s=[];for(let e=0;e0&&s.filters.forEach((e=>{if("brightness"===e.type)l.push({type:"color matrix",value:[e.value,0,0,0,0,0,e.value,0,0,0,0,0,e.value,0,0,0,0,0,1,0]});else if("contrast"===e.type){const t=.5*(1-e.value);l.push({type:"color matrix",value:[e.value,0,0,0,t,0,e.value,0,0,t,0,0,e.value,0,t,0,0,0,1,0]})}else if("hue-rotate"===e.type){const t=(0,f.angleToRadian)(e.value),n=Math.cos(t),r=Math.sin(t),o=.213,i=.715,a=.072;l.push({type:"color matrix",value:[o+n*(1-o)+r*-o,i+n*-i+r*-i,a+n*-a+r*(1-a),0,0,o+n*-o+.143*r,i+n*(1-i)+.14*r,a+n*-a+-.283*r,0,0,o+n*-o+r*-(1-o),i+n*-i+r*i,a+n*(1-a)+r*a,0,0,0,0,0,1,0]})}else if("saturate"===e.type){const t=2*(e.value-1)/3+1,n=-.5*(t-1);l.push({type:"color matrix",value:[t,n,n,0,0,n,t,n,0,0,n,n,t,0,0,0,0,0,1,0]})}else if("grayscale"===e.type){const t=1-e.value;l.push({type:"color matrix",value:[.2126+.7874*t,.7152-.7152*t,.0722-.0722*t,0,0,.2126-.2126*t,.7152+.2848*t,.0722-.0722*t,0,0,.2126-.2126*t,.7152-.7152*t,.0722+.9278*t,0,0,0,0,0,1,0]})}else if("sepia"===e.type){const t=1-e.value;l.push({type:"color matrix",value:[.393+.607*t,.769-.769*t,.189-.189*t,0,0,.349-.349*t,.686+.314*t,.168-.168*t,0,0,.272-.272*t,.534-.534*t,.131+.869*t,0,0,0,0,0,1,0]})}else if("invert"===e.type){const t=1-2*e.value;l.push({type:"color matrix",value:[t,0,0,0,e.value,0,t,0,0,e.value,0,0,t,0,e.value,0,0,0,1,0]})}else"opacity"===e.type?l.push({type:"color matrix",value:[1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,e.value,0]}):"blur"===e.type&&l.push({type:"blur",value:[0,3*e.value/7/o]},{type:"blur",value:[3*e.value/7/r,0]})})),{type:"texture",x:t,y:n,width:r,height:o,src:c,opacity:null==s?void 0:s.opacity,filters:l.length>0?l:void 0}}const L=new d.WeakmapMapCache,M=new d.WeakmapMap3Cache,I=new d.WeakmapMap3Cache,O=new d.WeakmapMapCache,D=new d.WeakmapMapCache;function B(e,t){(null==t?void 0:t.dashArray)&&(e.setLineDash(t.dashArray),t.dashOffset&&(e.lineDashOffset=t.dashOffset))}function z(e,t){const{start:n,end:r}=e,o=r.x-n.x,i=r.y-n.y,s=(0,u.twoPointLineToGeneralFormLine)(n,r);if(!s)return{type:"triangle strip",points:[],colors:[]};const p=e.stops.slice(0).sort(((e,t)=>e.offset-t.offset)),d=[];let f=p[0].offset,g=p[p.length-1].offset;t.forEach((e=>{const t=(0,h.getPerpendicularPoint)(e,s),r=(0,u.getPointSideOfLine)(e,s);if((0,c.isZero)(r))d.push(0);else{const n=(0,l.getTwoPointsDistance)(t,e);r>0?d.push(n):r<0&&d.push(-n)}const a=(0,c.isSameNumber)(t.x,n.x)?(t.y-n.y)/i:(t.x-n.x)/o;ag&&(g=a)})),(0,c.isSameNumber)(f,p[0].offset)||p.unshift({offset:f,color:p[0].color}),(0,c.isSameNumber)(g,p[p.length-1].offset)||p.push({offset:g,color:p[p.length-1].color});const m=(0,u.getParallelLinesByDistance)(s,Math.max(...d))[1],y=(0,u.getParallelLinesByDistance)(s,Math.min(...d))[1],v=[],x=[];return p.forEach((e=>{const t={x:n.x+o*e.offset,y:n.y+i*e.offset},r=(0,h.getPerpendicularPoint)(t,m),s=(0,h.getPerpendicularPoint)(t,y),c=(0,a.colorNumberToVec)(e.color,e.opacity);v.push(r.x,r.y,s.x,s.y),x.push(...c,...c)})),{type:"triangle strip",points:v,colors:x}}function F(e,t){let{start:n,end:r,stops:o}=e;if(n.r>r.r){const e=n;n=r,r=e,o=o.map((e=>({offset:1-e.offset,color:e.color})))}const i=r.x-n.x,s=r.y-n.y,c=r.r-n.r,u=o.slice(0).sort(((e,t)=>e.offset-t.offset)).map((e=>{const t={x:n.x+i*e.offset,y:n.y+s*e.offset,r:n.r+c*e.offset};return{color:(0,a.colorNumberToVec)(e.color,e.opacity),points:(0,p.arcToPolyline)((0,p.circleToArc)(t),5)}})),d=Math.max(...t.map((e=>(0,l.getTwoPointsDistance)(e,r))));d>r.r&&u.push({color:u[u.length-1].color,points:(0,p.arcToPolyline)((0,p.circleToArc)({x:r.x,y:r.y,r:d}),5)});const f=[],g=[];if(n.r>0){const e=u[0],t=[],r=[];e.points.forEach((o=>{t.push(o.x,o.y,n.x,n.y),r.push(...e.color,...e.color)})),f.push(t),g.push(r)}for(let e=1;e{const a=n.points[i];r.unshift(e.x,e.y,a.x,a.y),o.unshift(...t.color,...n.color)})),f.push(r),g.push(o)}return{type:"triangle strip",points:(0,m.combineStripTriangles)(f),colors:(0,m.combineStripTriangleColors)(g)}}function N(e){const t=[];for(let n=0;nr&&(r=a),so&&(o=s)}return{xMax:r,xMin:t,yMin:n,yMax:o}}function G(e,t,n,r){var o,i;const{xMin:a,yMin:c,xMax:l,yMax:u}=n,p=null!=(o=e.width)?o:Number.MAX_SAFE_INTEGER,d=null!=(i=e.height)?i:Number.MAX_SAFE_INTEGER,f=Math.floor(a/p),g=Math.floor(l/p),h=Math.floor(c/d),m=Math.floor(u/d);for(let n=f;n<=g;n++)for(let o=h;o<=m;o++){const i=s.m3.multiply(t,s.m3.translation(n*p,o*d));for(const t of e.graphics)r(t,t.matrix?s.m3.multiply(i,t.matrix):i)}}function j(e,t){var n,r;const o=s.m3.multiply(e,s.m3.translation(t.x,t.y)),i=null!=(n=t.width)?n:t.src.width,a=null!=(r=t.height)?r:t.src.height;return{textureMatrix:s.m3.multiply(o,s.m3.scaling(i,a)),width:i,height:a}}function V(e,t,n,r,o){let i=s.m3.projection(e.width,e.height);return i=s.m3.multiply(i,s.m3.translation(t,n)),1!==r&&(i=s.m3.multiply(i,s.m3.translation(e.width/2,e.height/2)),i=s.m3.multiply(i,s.m3.scaling(r,r)),i=s.m3.multiply(i,s.m3.translation(-e.width/2,-e.height/2))),o&&(i=s.m3.multiply(i,s.m3.rotation(-o))),i}},7191:(e,t,n)=>{"use strict";n.r(t),n.d(t,{createUniformsBuffer:()=>p,createWebgpuRenderer:()=>u});var r=n(7764),o=n(3975),i=n(5147),a=n(6300),s=n(7713),c=n(3876),l=(e,t,n)=>new Promise(((r,o)=>{var i=e=>{try{s(n.next(e))}catch(e){o(e)}},a=e=>{try{s(n.throw(e))}catch(e){o(e)}},s=e=>e.done?r(e.value):Promise.resolve(e.value).then(i,a);s((n=n.apply(e,t)).next())}));function u(e){return l(this,null,(function*(){if(!navigator.gpu)return;const t=e.getContext("webgpu");if(!t)return;const n=yield navigator.gpu.requestAdapter();if(!n)return;const a=yield n.requestDevice(),l=navigator.gpu.getPreferredCanvasFormat();t.configure({device:a,format:l});const u={color:{srcFactor:"src-alpha",dstFactor:"one-minus-src-alpha"},alpha:{srcFactor:"src-alpha",dstFactor:"one-minus-src-alpha"}},f=new r.Lazy((()=>a.createShaderModule({code:"struct Uniforms {\n color: vec4f,\n matrix: mat3x3f,\n };\n @group(0) @binding(0) var uniforms: Uniforms;\n \n @vertex\n fn vertex_main(@location(0) position: vec2f) -> @builtin(position) vec4f\n {\n return vec4f((uniforms.matrix * vec3(position, 1)).xy, 0, 1);\n }\n \n @fragment\n fn fragment_main() -> @location(0) vec4f\n {\n return uniforms.color;\n }"}))),g=new r.Lazy((()=>a.createShaderModule({code:"struct Uniforms {\n color: vec4f,\n matrix: mat3x3f,\n scale: f32,\n };\n @group(0) @binding(0) var uniforms: Uniforms;\n \n @vertex\n fn vertex_main(@location(0) position: vec2f, @location(1) base: vec2f) -> @builtin(position) vec4f\n {\n let p = (position - base) * uniforms.scale + base;\n return vec4f((uniforms.matrix * vec3(p, 1)).xy, 0, 1);\n }\n \n @fragment\n fn fragment_main() -> @location(0) vec4f\n {\n return uniforms.color;\n }"}))),h=new r.Lazy((()=>a.createShaderModule({code:"struct Uniforms {\n matrix: mat3x3f,\n color: vec4f,\n };\n @group(0) @binding(0) var uniforms: Uniforms;\n @group(0) @binding(1) var mySampler: sampler;\n @group(0) @binding(2) var myTexture: texture_2d;\n\n struct VertexOutput {\n @builtin(position) position: vec4f,\n @location(0) texcoord: vec2f,\n };\n \n @vertex\n fn vertex_main(@builtin(vertex_index) vertexIndex: u32) -> VertexOutput\n {\n var pos = array(\n vec2f(0.0, 0.0),\n vec2f(0.0, 1.0),\n vec2f(1.0, 0.0),\n vec2f(0.0, 1.0),\n vec2f(1.0, 1.0),\n vec2f(1.0, 0.0),\n );\n let xy = pos[vertexIndex];\n var vsOut: VertexOutput;\n vsOut.position = vec4f((uniforms.matrix * vec3(xy, 1)).xy, 0, 1);\n vsOut.texcoord = xy;\n return vsOut;\n }\n \n @fragment\n fn fragment_main(@location(0) texcoord: vec2f) -> @location(0) vec4f\n {\n if (texcoord.x < 0.0 || texcoord.x > 1.0 || texcoord.y < 0.0 || texcoord.y > 1.0) {\n discard;\n }\n var color = textureSample(myTexture, mySampler, texcoord) * uniforms.color;\n if (color.a < 0.1) {\n discard;\n }\n return color;\n }"}))),m=new r.Lazy((()=>a.createShaderModule({code:"struct Uniforms {\n matrix: mat3x3f,\n opacity: f32,\n };\n @group(0) @binding(0) var uniforms: Uniforms;\n @group(0) @binding(1) var mySampler: sampler;\n @group(0) @binding(2) var myTexture: texture_2d;\n\n struct VertexOutput {\n @builtin(position) position: vec4f,\n @location(0) texcoord: vec2f,\n };\n \n @vertex\n fn vertex_main(@builtin(vertex_index) vertexIndex: u32) -> VertexOutput\n {\n var pos = array(\n vec2f(0.0, 0.0),\n vec2f(0.0, 1.0),\n vec2f(1.0, 0.0),\n vec2f(0.0, 1.0),\n vec2f(1.0, 1.0),\n vec2f(1.0, 0.0),\n );\n let xy = pos[vertexIndex];\n var vsOut: VertexOutput;\n vsOut.position = vec4f((uniforms.matrix * vec3(xy, 1)).xy, 0, 1);\n vsOut.texcoord = xy;\n return vsOut;\n }\n \n @fragment\n fn fragment_main(@location(0) texcoord: vec2f) -> @location(0) vec4f\n {\n if (texcoord.x < 0.0 || texcoord.x > 1.0 || texcoord.y < 0.0 || texcoord.y > 1.0) {\n discard;\n }\n return textureSample(myTexture, mySampler, texcoord) * vec4f(1, 1, 1, uniforms.opacity);\n }"}))),y=new r.Lazy((()=>a.createShaderModule({code:"struct Uniforms {\n matrix: mat3x3f,\n opacity: f32,\n colorMatrix: array,\n };\n @group(0) @binding(0) var uniforms: Uniforms;\n @group(0) @binding(1) var mySampler: sampler;\n @group(0) @binding(2) var myTexture: texture_2d;\n\n struct VertexOutput {\n @builtin(position) position: vec4f,\n @location(0) texcoord: vec2f,\n };\n \n @vertex\n fn vertex_main(@builtin(vertex_index) vertexIndex: u32) -> VertexOutput\n {\n var pos = array(\n vec2f(0.0, 0.0),\n vec2f(0.0, 1.0),\n vec2f(1.0, 0.0),\n vec2f(0.0, 1.0),\n vec2f(1.0, 1.0),\n vec2f(1.0, 0.0),\n );\n let xy = pos[vertexIndex];\n var vsOut: VertexOutput;\n vsOut.position = vec4f((uniforms.matrix * vec3(xy, 1)).xy, 0, 1);\n vsOut.texcoord = xy;\n return vsOut;\n }\n \n @fragment\n fn fragment_main(@location(0) texcoord: vec2f) -> @location(0) vec4f\n {\n if (texcoord.x < 0.0 || texcoord.x > 1.0 || texcoord.y < 0.0 || texcoord.y > 1.0) {\n discard;\n }\n var c = textureSample(myTexture, mySampler, texcoord) * vec4f(1, 1, 1, uniforms.opacity);\n var r = uniforms.colorMatrix[0][0] * c.r + uniforms.colorMatrix[0][1] * c.g + uniforms.colorMatrix[0][2] * c.b + uniforms.colorMatrix[0][3] * c.a + uniforms.colorMatrix[1][0];\n var g = uniforms.colorMatrix[1][1] * c.r + uniforms.colorMatrix[1][2] * c.g + uniforms.colorMatrix[1][3] * c.b + uniforms.colorMatrix[2][0] * c.a + uniforms.colorMatrix[2][1];\n var b = uniforms.colorMatrix[2][2] * c.r + uniforms.colorMatrix[2][3] * c.g + uniforms.colorMatrix[3][0] * c.b + uniforms.colorMatrix[3][1] * c.a + uniforms.colorMatrix[3][2];\n var a = uniforms.colorMatrix[3][3] * c.r + uniforms.colorMatrix[4][0] * c.g + uniforms.colorMatrix[4][1] * c.b + uniforms.colorMatrix[4][2] * c.a + uniforms.colorMatrix[4][3];\n return vec4f(r, g, b, a);\n }"}))),v=new r.Lazy((()=>a.createShaderModule({code:"struct Uniforms {\n matrix: mat3x3f,\n opacity: f32,\n px: vec4f,\n };\n @group(0) @binding(0) var uniforms: Uniforms;\n @group(0) @binding(1) var mySampler: sampler;\n @group(0) @binding(2) var myTexture: texture_2d;\n\n struct VertexOutput {\n @builtin(position) position: vec4f,\n @location(0) texcoord: vec2f,\n };\n \n @vertex\n fn vertex_main(@builtin(vertex_index) vertexIndex: u32) -> VertexOutput\n {\n var pos = array(\n vec2f(0.0, 0.0),\n vec2f(0.0, 1.0),\n vec2f(1.0, 0.0),\n vec2f(0.0, 1.0),\n vec2f(1.0, 1.0),\n vec2f(1.0, 0.0),\n );\n let xy = pos[vertexIndex];\n var vsOut: VertexOutput;\n vsOut.position = vec4f((uniforms.matrix * vec3(xy, 1)).xy, 0, 1);\n vsOut.texcoord = xy;\n return vsOut;\n }\n \n @fragment\n fn fragment_main(@location(0) texcoord: vec2f) -> @location(0) vec4f\n {\n if (texcoord.x < 0.0 || texcoord.x > 1.0 || texcoord.y < 0.0 || texcoord.y > 1.0) {\n discard;\n }\n var r = vec4f(0.0);\n r += textureSample(myTexture, mySampler, texcoord + vec2(-7.0*uniforms.px.x, -7.0*uniforms.px.y))*0.0044299121055113265;\n r += textureSample(myTexture, mySampler, texcoord + vec2(-6.0*uniforms.px.x, -6.0*uniforms.px.y))*0.00895781211794;\n r += textureSample(myTexture, mySampler, texcoord + vec2(-5.0*uniforms.px.x, -5.0*uniforms.px.y))*0.0215963866053;\n r += textureSample(myTexture, mySampler, texcoord + vec2(-4.0*uniforms.px.x, -4.0*uniforms.px.y))*0.0443683338718;\n r += textureSample(myTexture, mySampler, texcoord + vec2(-3.0*uniforms.px.x, -3.0*uniforms.px.y))*0.0776744219933;\n r += textureSample(myTexture, mySampler, texcoord + vec2(-2.0*uniforms.px.x, -2.0*uniforms.px.y))*0.115876621105;\n r += textureSample(myTexture, mySampler, texcoord + vec2(-1.0*uniforms.px.x, -1.0*uniforms.px.y))*0.147308056121;\n r += textureSample(myTexture, mySampler, texcoord )*0.159576912161;\n r += textureSample(myTexture, mySampler, texcoord + vec2( 1.0*uniforms.px.x, 1.0*uniforms.px.y))*0.147308056121;\n r += textureSample(myTexture, mySampler, texcoord + vec2( 2.0*uniforms.px.x, 2.0*uniforms.px.y))*0.115876621105;\n r += textureSample(myTexture, mySampler, texcoord + vec2( 3.0*uniforms.px.x, 3.0*uniforms.px.y))*0.0776744219933;\n r += textureSample(myTexture, mySampler, texcoord + vec2( 4.0*uniforms.px.x, 4.0*uniforms.px.y))*0.0443683338718;\n r += textureSample(myTexture, mySampler, texcoord + vec2( 5.0*uniforms.px.x, 5.0*uniforms.px.y))*0.0215963866053;\n r += textureSample(myTexture, mySampler, texcoord + vec2( 6.0*uniforms.px.x, 6.0*uniforms.px.y))*0.00895781211794;\n r += textureSample(myTexture, mySampler, texcoord + vec2( 7.0*uniforms.px.x, 7.0*uniforms.px.y))*0.0044299121055113265;\n return r;\n }"}))),x=new r.Lazy((()=>a.createShaderModule({code:"struct Uniforms {\n matrix: mat3x3f,\n color: vec4f,\n };\n @group(0) @binding(0) var uniforms: Uniforms;\n @group(0) @binding(1) var mySampler: sampler;\n @group(0) @binding(2) var myTexture: texture_2d;\n\n struct VertexOutput {\n @builtin(position) position: vec4f,\n @location(0) texcoord: vec2f,\n };\n \n @vertex\n fn vertex_main(@builtin(vertex_index) vertexIndex: u32) -> VertexOutput\n {\n var pos = array