@nasser-sw/fabric 7.0.1-beta6 → 7.0.1-beta8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +79 -12
- package/dist/index.js.map +1 -1
- package/dist/index.min.js +1 -1
- package/dist/index.min.js.map +1 -1
- package/dist/index.min.mjs +1 -1
- package/dist/index.min.mjs.map +1 -1
- package/dist/index.mjs +79 -12
- package/dist/index.mjs.map +1 -1
- package/dist/index.node.cjs +79 -12
- package/dist/index.node.cjs.map +1 -1
- package/dist/index.node.mjs +79 -12
- package/dist/index.node.mjs.map +1 -1
- package/dist/package.json.min.mjs +1 -1
- package/dist/package.json.mjs +1 -1
- package/dist/src/shapes/Line.d.ts +1 -0
- package/dist/src/shapes/Line.d.ts.map +1 -1
- package/dist/src/shapes/Line.min.mjs +1 -1
- package/dist/src/shapes/Line.min.mjs.map +1 -1
- package/dist/src/shapes/Line.mjs +79 -11
- package/dist/src/shapes/Line.mjs.map +1 -1
- package/dist-extensions/src/shapes/Line.d.ts +1 -0
- package/dist-extensions/src/shapes/Line.d.ts.map +1 -1
- package/fabric-test2.html +134 -0
- package/package.json +1 -1
- package/src/shapes/Line.ts +147 -50
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var a="7.0.1-
|
|
1
|
+
var a="7.0.1-beta7";export{a as version};
|
|
2
2
|
//# sourceMappingURL=package.json.min.mjs.map
|
package/dist/package.json.mjs
CHANGED
|
@@ -21,6 +21,7 @@ export declare class Line<Props extends TOptions<FabricObjectProps> = Partial<Fa
|
|
|
21
21
|
hitStrokeWidth: number | 'auto';
|
|
22
22
|
private _updatingEndpoints;
|
|
23
23
|
private _useEndpointCoords;
|
|
24
|
+
private _exportingSVG;
|
|
24
25
|
static type: string;
|
|
25
26
|
static cacheProperties: string[];
|
|
26
27
|
constructor([x1, y1, x2, y2]?: [number, number, number, number], options?: Partial<Props & {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Line.d.ts","sourceRoot":"","sources":["../../../src/shapes/Line.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,gBAAgB,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEzE,OAAO,EAAE,YAAY,EAAmB,MAAM,uBAAuB,CAAC;AACtE,OAAO,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AAEjC,OAAO,KAAK,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AAC/E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAGrD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAEnD,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAKjE,UAAU,gBAAgB;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,MAAM,WAAW,mBACf,SAAQ,qBAAqB,EAC3B,gBAAgB;CAAG;AAEvB,qBAAa,IAAI,CACb,KAAK,SAAS,QAAQ,CAAC,iBAAiB,CAAC,GAAG,OAAO,CAAC,iBAAiB,CAAC,EACtE,MAAM,SAAS,mBAAmB,GAAG,mBAAmB,EACxD,SAAS,SAAS,YAAY,GAAG,YAAY,CAE/C,SAAQ,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,CAC7C,YAAW,gBAAgB;IAEnB,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IAEnB,cAAc,EAAE,MAAM,GAAG,MAAM,CAAU;IAEzC,OAAO,CAAC,kBAAkB,CAAS;IACnC,OAAO,CAAC,kBAAkB,CAAQ;
|
|
1
|
+
{"version":3,"file":"Line.d.ts","sourceRoot":"","sources":["../../../src/shapes/Line.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{defineProperty as t}from"../../_virtual/_rollupPluginBabelHelpers.min.mjs";import{SHARED_ATTRIBUTES as i}from"../parser/attributes.min.mjs";import{parseAttributes as s}from"../parser/parseAttributes.min.mjs";import{classRegistry as e}from"../ClassRegistry.min.mjs";import{FabricObject as o}from"./Object/FabricObject.min.mjs";import{Point as n}from"../Point.min.mjs";import{isFiller as r}from"../util/typeAssertions.min.mjs";import{LEFT as h,TOP as d,CENTER as a}from"../constants.min.mjs";import"../util/misc/vectors.min.mjs";import"../util/misc/projectStroke/StrokeLineJoinProjections.min.mjs";import"../config.min.mjs";import"./Group.min.mjs";import{makeBoundingBoxFromPoints as l}from"../util/misc/boundingBoxFromPoints.min.mjs";import"../cache.min.mjs";import"../parser/constants.min.mjs";import"../util/animation/AnimationRegistry.min.mjs";import{Control as p}from"../controls/Control.min.mjs";import{cacheProperties as m}from"./Object/defaultValues.min.mjs";const u=["x1","x2","y1","y2"];class y extends o{constructor(){let[i,s,e,o]=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[0,0,100,0],n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};super(),t(this,"hitStrokeWidth","auto"),t(this,"_updatingEndpoints",!1),t(this,"_useEndpointCoords",!0),this.setOptions(n),this.x1=i,this.x2=e,this.y1=s,this.y2=o,void 0!==n.hitStrokeWidth&&(this.hitStrokeWidth=n.hitStrokeWidth),this.hasBorders=!1,this.hasControls=!0,this.selectable=!0,this.hoverCursor="move",this.perPixelTargetFind=!1,this.strokeLineCap="butt",this._setWidthHeight();const{left:r,top:a}=n;"number"==typeof r&&this.set(h,r),"number"==typeof a&&this.set(d,a),this._setupLineControls()}_setupLineControls(){this.controls={p1:new p({x:0,y:0,cursorStyle:"move",actionHandler:this._endpointActionHandler.bind(this),positionHandler:this._p1PositionHandler.bind(this),render:this._renderEndpointControl.bind(this),sizeX:12,sizeY:12}),p2:new p({x:0,y:0,cursorStyle:"move",actionHandler:this._endpointActionHandler.bind(this),positionHandler:this._p2PositionHandler.bind(this),render:this._renderEndpointControl.bind(this),sizeX:12,sizeY:12})}}_p1PositionHandler(){return new n(this.x1,this.y1).transform(this.getViewportTransform())}_p2PositionHandler(){return new n(this.x2,this.y2).transform(this.getViewportTransform())}_renderEndpointControl(t,i,s){t.save(),t.fillStyle="#007bff",t.strokeStyle="#ffffff",t.lineWidth=2,t.beginPath(),t.arc(i,s,6,0,2*Math.PI),t.fill(),t.stroke(),t.restore()}drawBorders(t){let i=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return this._useEndpointCoords?(this._drawLineBorders(t,i),this):super.drawBorders(t,i,{})}_drawLineBorders(t){var i;let s=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const e=(null===(i=this.canvas)||void 0===i?void 0:i.viewportTransform)||[1,0,0,1,0,0];t.save(),t.setTransform(e[0],e[1],e[2],e[3],e[4],e[5]),t.strokeStyle=s.borderColor||this.borderColor||"rgba(100, 200, 200, 0.5)",t.lineWidth=(this.strokeWidth||1)+5,t.lineCap=this.strokeLineCap||"butt",t.globalAlpha=this.isMoving?this.borderOpacityWhenMoving:1,t.beginPath(),t.moveTo(this.x1,this.y1),t.lineTo(this.x2,this.y2),t.stroke(),t.restore()}_renderControls(t){let i=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};t.save(),t.globalAlpha=this.isMoving?this.borderOpacityWhenMoving:1,this.drawControls(t,i),t.restore()}getBoundingRect(){if(this._useEndpointCoords){const{x1:t,y1:i,x2:s,y2:e}=this,o="auto"===this.hitStrokeWidth?this.strokeWidth:this.hitStrokeWidth,n=Math.max(o/2+5,10);return{left:Math.min(t,s)-n,top:Math.min(i,e)-n,width:Math.abs(s-t)+2*n||2*n,height:Math.abs(e-i)+2*n||2*n}}return super.getBoundingRect()}setCoords(){if(this._useEndpointCoords){const t=this._findCenterFromElement();this.left=t.x,this.top=t.y;const i="auto"===this.hitStrokeWidth?this.strokeWidth:this.hitStrokeWidth,s=Math.max(i/2+5,10);this.width=Math.abs(this.x2-this.x1)+2*s,this.height=Math.abs(this.y2-this.y1)+2*s}super.setCoords()}getCoords(){if(this._useEndpointCoords){const t=this.x2-this.x1,i=this.y2-this.y1,s=Math.sqrt(t*t+i*i);if(0===s)return super.getCoords();const e="auto"===this.hitStrokeWidth?this.strokeWidth:this.hitStrokeWidth,o=Math.max(e/2+2,5),r=-i/s,h=t/s;return[new n(this.x1+r*o,this.y1+h*o),new n(this.x2+r*o,this.y2+h*o),new n(this.x2-r*o,this.y2-h*o),new n(this.x1-r*o,this.y1-h*o)]}return super.getCoords()}containsPoint(t){if(this._useEndpointCoords){var i;if((null===(i=this.canvas)||void 0===i?void 0:i.getActiveObject())===this)return super.containsPoint(t);const s=this._distanceToLineSegment(t.x,t.y),e="auto"===this.hitStrokeWidth?this.strokeWidth:this.hitStrokeWidth||1;return s<=Math.max(e/2+2,5)}return super.containsPoint(t)}_distanceToLineSegment(t,i){const s=this.x1,e=this.y1,o=this.x2,n=this.y2,r=(s-o)*(s-o)+(e-n)*(e-n);if(0===r)return Math.sqrt((t-s)*(t-s)+(i-e)*(i-e));const h=((t-s)*(o-s)+(i-e)*(n-e))/r;let d,a;return h<0?(d=s,a=e):h>1?(d=o,a=n):(d=s+h*(o-s),a=e+h*(n-e)),Math.sqrt((t-d)*(t-d)+(i-a)*(i-a))}_endpointActionHandler(t,i,s,e){var o;const r=i.corner,h=new n(s,e);let d=h.x,a=h.y;if(t.shiftKey){const t="p1"===r?"p2":"p1",i=this["p1"===t?"x1":"x2"],s=this["p1"===t?"y1":"y2"],e=this._snapToAngle(i,s,d,a);d=e.x,a=e.y}var l;return this._useEndpointCoords?("p1"===r?(this.x1=d,this.y1=a):"p2"===r&&(this.x2=d,this.y2=a),this.dirty=!0,this.setCoords(),null===(l=this.canvas)||void 0===l||l.requestRenderAll(),!0):(this._updatingEndpoints=!0,"p1"===r?(this.x1=d,this.y1=a):"p2"===r&&(this.x2=d,this.y2=a),this._setWidthHeight(),this.dirty=!0,this._updatingEndpoints=!1,null===(o=this.canvas)||void 0===o||o.requestRenderAll(),this.fire("modified",{transform:i,target:this,e:t}),!0)}_snapToAngle(t,i,s,e){const o=s-t,n=e-i,r=Math.sqrt(o*o+n*n);if(0===r)return{x:s,y:e};let h=Math.atan2(n,o)*(180/Math.PI);const d=15*Math.round(h/15)*(Math.PI/180);return{x:t+Math.cos(d)*r,y:i+Math.sin(d)*r}}_setWidthHeight(){let t=arguments.length>0&&void 0!==arguments[0]&&arguments[0];if(this.width=Math.abs(this.x2-this.x1)||1,this.height=Math.abs(this.y2-this.y1)||1,!t&&!this._updatingEndpoints){const{left:t,top:i,width:s,height:e}=l([{x:this.x1,y:this.y1},{x:this.x2,y:this.y2}]);this.setPositionByOrigin(new n(t+s/2,i+e/2),a,a)}}_set(t,i){const s=this.left,e=this.top;if(super._set(t,i),u.includes(t)&&(this._setWidthHeight(),this.dirty=!0),("left"===t||"top"===t)&&this.canvas&&!this._updatingEndpoints){const t=this.left-s,i=this.top-e;0===t&&0===i||(this._updatingEndpoints=!0,this.x1+=t,this.y1+=i,this.x2+=t,this.y2+=i,this._updatingEndpoints=!1)}return this}render(t){this._useEndpointCoords?this._renderDirectly(t):super.render(t)}_renderDirectly(t){var i;this.visible&&(t.save(),t.globalAlpha=this.opacity,t.strokeStyle=(null===(i=this.stroke)||void 0===i?void 0:i.toString())||"#000",t.lineWidth=this.strokeWidth,t.lineCap=this.strokeLineCap||"butt",t.beginPath(),t.moveTo(this.x1,this.y1),t.lineTo(this.x2,this.y2),t.stroke(),t.restore())}_render(t){if(this._useEndpointCoords)return;t.beginPath();const i=this.calcLinePoints();t.moveTo(i.x1,i.y1),t.lineTo(i.x2,i.y2),t.lineWidth=this.strokeWidth;const s=t.strokeStyle;r(this.stroke)&&(t.strokeStyle=this.stroke.toLive(t)),this.stroke&&this._renderStroke(t),t.strokeStyle=s}_findCenterFromElement(){return new n((this.x1+this.x2)/2,(this.y1+this.y2)/2)}toObject(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];return{...super.toObject(t),...this.calcLinePoints()}}_getNonTransformedDimensions(){const t=super._getNonTransformedDimensions();return"round"===this.strokeLineCap&&(t.x+=this.strokeWidth,t.y+=this.strokeWidth),t}calcLinePoints(){if(this._updatingEndpoints){const t=(this.x1+this.x2)/2,i=(this.y1+this.y2)/2;return{x1:this.x1-t,y1:this.y1-i,x2:this.x2-t,y2:this.y2-i}}const{x1:t,x2:i,y1:s,y2:e,width:o,height:n}=this,r=t<=i?-1:1,h=s<=e?-1:1;return{x1:r*o/2,y1:h*n/2,x2:r*-o/2,y2:h*-n/2}}_toSVG(){if(this._useEndpointCoords)return[`<line stroke="${this.stroke}" stroke-width="${this.strokeWidth}" stroke-linecap="${this.strokeLineCap}" `,`x1="${this.x1}" y1="${this.y1}" x2="${this.x2}" y2="${this.y2}" />\n`];{const{x1:t,x2:i,y1:s,y2:e}=this.calcLinePoints();return["<line ","COMMON_PARTS",`x1="${t}" y1="${s}" x2="${i}" y2="${e}" />\n`]}}toSVG(t){if(this._useEndpointCoords){const i=this._toSVG().join("");return t?t(i):i}return super.toSVG(t)}static async fromElement(t,i,e){const{x1:o=0,y1:n=0,x2:r=0,y2:h=0,...d}=s(t,this.ATTRIBUTE_NAMES,e);return new this([o,n,r,h],d)}static fromObject(t){let{x1:i,y1:s,x2:e,y2:o,...n}=t;return this._fromObject({...n,points:[i,s,e,o]},{extraParam:"points"})}}t(y,"type","Line"),t(y,"cacheProperties",[...m,...u]),t(y,"ATTRIBUTE_NAMES",i.concat(u)),e.setClass(y),e.setSVGClass(y);export{y as Line};
|
|
1
|
+
import{defineProperty as t}from"../../_virtual/_rollupPluginBabelHelpers.min.mjs";import{SHARED_ATTRIBUTES as i}from"../parser/attributes.min.mjs";import{parseAttributes as s}from"../parser/parseAttributes.min.mjs";import{classRegistry as e}from"../ClassRegistry.min.mjs";import{FabricObject as o}from"./Object/FabricObject.min.mjs";import{Point as r}from"../Point.min.mjs";import{isFiller as h}from"../util/typeAssertions.min.mjs";import{LEFT as n,TOP as d,CENTER as a}from"../constants.min.mjs";import"../util/misc/vectors.min.mjs";import"../util/misc/projectStroke/StrokeLineJoinProjections.min.mjs";import"../config.min.mjs";import"./Group.min.mjs";import{makeBoundingBoxFromPoints as l}from"../util/misc/boundingBoxFromPoints.min.mjs";import"../cache.min.mjs";import"../parser/constants.min.mjs";import"../util/animation/AnimationRegistry.min.mjs";import{Control as p}from"../controls/Control.min.mjs";import{Gradient as y}from"../gradient/Gradient.min.mjs";import{cacheProperties as c}from"./Object/defaultValues.min.mjs";const m=["x1","x2","y1","y2"];class u extends o{constructor(){let[i,s,e,o]=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[0,0,100,0],r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};super(),t(this,"hitStrokeWidth","auto"),t(this,"_updatingEndpoints",!1),t(this,"_useEndpointCoords",!0),t(this,"_exportingSVG",!1),this.setOptions(r),this.x1=i,this.x2=e,this.y1=s,this.y2=o,void 0!==r.hitStrokeWidth&&(this.hitStrokeWidth=r.hitStrokeWidth),this.hasBorders=!1,this.hasControls=!0,this.selectable=!0,this.hoverCursor="move",this.perPixelTargetFind=!1,this.strokeLineCap="butt",this._setWidthHeight();const{left:h,top:a}=r;"number"==typeof h&&this.set(n,h),"number"==typeof a&&this.set(d,a),this._setupLineControls()}_setupLineControls(){this.controls={p1:new p({x:0,y:0,cursorStyle:"move",actionHandler:this._endpointActionHandler.bind(this),positionHandler:this._p1PositionHandler.bind(this),render:this._renderEndpointControl.bind(this),sizeX:12,sizeY:12}),p2:new p({x:0,y:0,cursorStyle:"move",actionHandler:this._endpointActionHandler.bind(this),positionHandler:this._p2PositionHandler.bind(this),render:this._renderEndpointControl.bind(this),sizeX:12,sizeY:12})}}_p1PositionHandler(){return new r(this.x1,this.y1).transform(this.getViewportTransform())}_p2PositionHandler(){return new r(this.x2,this.y2).transform(this.getViewportTransform())}_renderEndpointControl(t,i,s){t.save(),t.fillStyle="#007bff",t.strokeStyle="#ffffff",t.lineWidth=2,t.beginPath(),t.arc(i,s,6,0,2*Math.PI),t.fill(),t.stroke(),t.restore()}drawBorders(t){let i=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return this._useEndpointCoords?(this._drawLineBorders(t,i),this):super.drawBorders(t,i,{})}_drawLineBorders(t){var i;let s=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const e=(null===(i=this.canvas)||void 0===i?void 0:i.viewportTransform)||[1,0,0,1,0,0];t.save(),t.setTransform(e[0],e[1],e[2],e[3],e[4],e[5]),t.strokeStyle=s.borderColor||this.borderColor||"rgba(100, 200, 200, 0.5)",t.lineWidth=(this.strokeWidth||1)+5,t.lineCap=this.strokeLineCap||"butt",t.globalAlpha=this.isMoving?this.borderOpacityWhenMoving:1,t.beginPath(),t.moveTo(this.x1,this.y1),t.lineTo(this.x2,this.y2),t.stroke(),t.restore()}_renderControls(t){let i=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};t.save(),t.globalAlpha=this.isMoving?this.borderOpacityWhenMoving:1,this.drawControls(t,i),t.restore()}getBoundingRect(){if(this._useEndpointCoords){const{x1:t,y1:i,x2:s,y2:e}=this,o="auto"===this.hitStrokeWidth?this.strokeWidth:this.hitStrokeWidth,r=Math.max(o/2+5,10);return{left:Math.min(t,s)-r,top:Math.min(i,e)-r,width:Math.abs(s-t)+2*r||2*r,height:Math.abs(e-i)+2*r||2*r}}return super.getBoundingRect()}setCoords(){if(this._useEndpointCoords){const t="auto"===this.hitStrokeWidth?this.strokeWidth:this.hitStrokeWidth,i=Math.max(t/2+5,10);if(this.width=Math.abs(this.x2-this.x1)+2*i,this.height=Math.abs(this.y2-this.y1)+2*i,0===this.left&&0===this.top){const t=this._findCenterFromElement();this.left=t.x,this.top=t.y}}super.setCoords()}getCoords(){if(this._useEndpointCoords){const t=this.x2-this.x1,i=this.y2-this.y1,s=Math.sqrt(t*t+i*i);if(0===s)return super.getCoords();const e="auto"===this.hitStrokeWidth?this.strokeWidth:this.hitStrokeWidth,o=Math.max(e/2+2,5),h=-i/s,n=t/s;return[new r(this.x1+h*o,this.y1+n*o),new r(this.x2+h*o,this.y2+n*o),new r(this.x2-h*o,this.y2-n*o),new r(this.x1-h*o,this.y1-n*o)]}return super.getCoords()}containsPoint(t){if(this._useEndpointCoords){var i;if((null===(i=this.canvas)||void 0===i?void 0:i.getActiveObject())===this)return super.containsPoint(t);const s=this._distanceToLineSegment(t.x,t.y),e="auto"===this.hitStrokeWidth?this.strokeWidth:this.hitStrokeWidth||1;return s<=Math.max(e/2+2,5)}return super.containsPoint(t)}_distanceToLineSegment(t,i){const s=this.x1,e=this.y1,o=this.x2,r=this.y2,h=(s-o)*(s-o)+(e-r)*(e-r);if(0===h)return Math.sqrt((t-s)*(t-s)+(i-e)*(i-e));const n=((t-s)*(o-s)+(i-e)*(r-e))/h;let d,a;return n<0?(d=s,a=e):n>1?(d=o,a=r):(d=s+n*(o-s),a=e+n*(r-e)),Math.sqrt((t-d)*(t-d)+(i-a)*(i-a))}_endpointActionHandler(t,i,s,e){var o;const h=i.corner,n=new r(s,e);let d=n.x,a=n.y;if(t.shiftKey){const t="p1"===h?"p2":"p1",i=this["p1"===t?"x1":"x2"],s=this["p1"===t?"y1":"y2"],e=this._snapToAngle(i,s,d,a);d=e.x,a=e.y}var l;return this._useEndpointCoords?("p1"===h?(this.x1=d,this.y1=a):"p2"===h&&(this.x2=d,this.y2=a),this.stroke instanceof y&&!this._exportingSVG&&(this.stroke.coords.x1=this.x1,this.stroke.coords.y1=this.y1,this.stroke.coords.x2=this.x2,this.stroke.coords.y2=this.y2),this.dirty=!0,this.setCoords(),null===(l=this.canvas)||void 0===l||l.requestRenderAll(),!0):(this._updatingEndpoints=!0,"p1"===h?(this.x1=d,this.y1=a):"p2"===h&&(this.x2=d,this.y2=a),this._setWidthHeight(),this.dirty=!0,this._updatingEndpoints=!1,null===(o=this.canvas)||void 0===o||o.requestRenderAll(),this.fire("modified",{transform:i,target:this,e:t}),!0)}_snapToAngle(t,i,s,e){const o=s-t,r=e-i,h=Math.sqrt(o*o+r*r);if(0===h)return{x:s,y:e};let n=Math.atan2(r,o)*(180/Math.PI);const d=15*Math.round(n/15)*(Math.PI/180);return{x:t+Math.cos(d)*h,y:i+Math.sin(d)*h}}_setWidthHeight(){let t=arguments.length>0&&void 0!==arguments[0]&&arguments[0];if(this.width=Math.abs(this.x2-this.x1)||1,this.height=Math.abs(this.y2-this.y1)||1,!t&&!this._updatingEndpoints){const{left:t,top:i,width:s,height:e}=l([{x:this.x1,y:this.y1},{x:this.x2,y:this.y2}]);this.setPositionByOrigin(new r(t+s/2,i+e/2),a,a)}}_set(t,i){const s=this.left,e=this.top;if(super._set(t,i),m.includes(t)&&(this._setWidthHeight(),this.dirty=!0,this.stroke instanceof y&&!this._exportingSVG&&(this.stroke.coords.x1=this.x1,this.stroke.coords.y1=this.y1,this.stroke.coords.x2=this.x2,this.stroke.coords.y2=this.y2)),("left"===t||"top"===t)&&this.canvas&&!this._updatingEndpoints){const t=this.left-s,i=this.top-e;0===t&&0===i||(this._updatingEndpoints=!0,this.x1+=t,this.y1+=i,this.x2+=t,this.y2+=i,this.stroke instanceof y&&(this.stroke.coords.x1=this.x1,this.stroke.coords.y1=this.y1,this.stroke.coords.x2=this.x2,this.stroke.coords.y2=this.y2),this._updatingEndpoints=!1)}return this}render(t){this._useEndpointCoords?this._renderDirectly(t):super.render(t)}_renderDirectly(t){if(!this.visible)return;t.save(),t.globalAlpha=this.opacity,t.lineWidth=this.strokeWidth,t.lineCap=this.strokeLineCap||"butt",t.beginPath(),t.moveTo(this.x1,this.y1),t.lineTo(this.x2,this.y2);const i=t.strokeStyle;var s;h(this.stroke)?t.strokeStyle=this.stroke.toLive(t):t.strokeStyle=(null===(s=this.stroke)||void 0===s?void 0:s.toString())||"#000";t.stroke(),t.strokeStyle=i,t.restore()}_render(t){if(this._useEndpointCoords)return;t.beginPath();const i=this.calcLinePoints();t.moveTo(i.x1,i.y1),t.lineTo(i.x2,i.y2),t.lineWidth=this.strokeWidth;const s=t.strokeStyle;h(this.stroke)&&(t.strokeStyle=this.stroke.toLive(t)),this.stroke&&this._renderStroke(t),t.strokeStyle=s}_findCenterFromElement(){return new r((this.x1+this.x2)/2,(this.y1+this.y2)/2)}toObject(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];return this._useEndpointCoords?{...super.toObject(t),x1:this.x1,y1:this.y1,x2:this.x2,y2:this.y2}:{...super.toObject(t),...this.calcLinePoints()}}_getNonTransformedDimensions(){const t=super._getNonTransformedDimensions();return"round"===this.strokeLineCap&&(t.x+=this.strokeWidth,t.y+=this.strokeWidth),t}calcLinePoints(){if(this._updatingEndpoints){const t=(this.x1+this.x2)/2,i=(this.y1+this.y2)/2;return{x1:this.x1-t,y1:this.y1-i,x2:this.x2-t,y2:this.y2-i}}const{x1:t,x2:i,y1:s,y2:e,width:o,height:r}=this,h=t<=i?-1:1,n=s<=e?-1:1;return{x1:h*o/2,y1:n*r/2,x2:h*-o/2,y2:n*-r/2}}_toSVG(){if(this._useEndpointCoords){let t="";return t=this.stroke instanceof y?`stroke="url(#${this.stroke.id})"`:`stroke="${this.stroke||"none"}"`,[`<line ${t} stroke-width="${this.strokeWidth}" stroke-linecap="${this.strokeLineCap}" `,`stroke-dasharray="${this.strokeDashArray?this.strokeDashArray.join(" "):"none"}" `,`stroke-dashoffset="${this.strokeDashOffset}" stroke-linejoin="${this.strokeLineJoin}" `,`stroke-miterlimit="${this.strokeMiterLimit}" fill="${this.fill||"none"}" `,`fill-rule="${this.fillRule}" opacity="${this.opacity}" `,`x1="${this.x1}" y1="${this.y1}" x2="${this.x2}" y2="${this.y2}" />\n`]}{const{x1:t,x2:i,y1:s,y2:e}=this.calcLinePoints();return["<line ","COMMON_PARTS",`x1="${t}" y1="${s}" x2="${i}" y2="${e}" />\n`]}}toSVG(t){if(this._useEndpointCoords){const i=this.left,s=this.top;this.left=(this.x1+this.x2)/2,this.top=(this.y1+this.y2)/2;const e=super.toSVG(t);this.left=i,this.top=s;return e.replace(/<g transform="[^"]*"[^>]*>/g,"").replace(/<\/g>/g,"").replace(/x1="[^"]*"/g,`x1="${this.x1}"`).replace(/y1="[^"]*"/g,`y1="${this.y1}"`).replace(/x2="[^"]*"/g,`x2="${this.x2}"`).replace(/y2="[^"]*"/g,`y2="${this.y2}"`)}return super.toSVG(t)}static async fromElement(t,i,e){const{x1:o=0,y1:r=0,x2:h=0,y2:n=0,...d}=s(t,this.ATTRIBUTE_NAMES,e);return new this([o,r,h,n],d)}static fromObject(t){let{x1:i,y1:s,x2:e,y2:o,...r}=t;return this._fromObject({...r,points:[i,s,e,o]},{extraParam:"points"})}}t(u,"type","Line"),t(u,"cacheProperties",[...c,...m]),t(u,"ATTRIBUTE_NAMES",i.concat(m)),e.setClass(u),e.setSVGClass(u);export{u as Line};
|
|
2
2
|
//# sourceMappingURL=Line.min.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Line.min.mjs","sources":["../../../src/shapes/Line.ts"],"sourcesContent":["import { SHARED_ATTRIBUTES } from '../parser/attributes';\nimport { parseAttributes } from '../parser/parseAttributes';\nimport type { Abortable, TClassProperties, TOptions } from '../typedefs';\nimport { classRegistry } from '../ClassRegistry';\nimport { FabricObject, cacheProperties } from './Object/FabricObject';\nimport { Point } from '../Point';\nimport { isFiller } from '../util/typeAssertions';\nimport type { FabricObjectProps, SerializedObjectProps } from './Object/types';\nimport type { ObjectEvents } from '../EventTypeDefs';\nimport { makeBoundingBoxFromPoints } from '../util';\nimport { CENTER, LEFT, TOP } from '../constants';\nimport type { CSSRules } from '../parser/typedefs';\nimport { Control } from '../controls/Control';\nimport type { TPointerEvent, Transform } from '../EventTypeDefs';\nimport { multiplyTransformMatrices } from '../util/misc/matrix';\n\nconst coordProps = ['x1', 'x2', 'y1', 'y2'] as const;\n\ninterface UniqueLineCoords {\n x1: number;\n x2: number;\n y1: number;\n y2: number;\n}\n\nexport interface SerializedLineProps\n extends SerializedObjectProps,\n UniqueLineCoords {}\n\nexport class Line< \n Props extends TOptions<FabricObjectProps> = Partial<FabricObjectProps>,\n SProps extends SerializedLineProps = SerializedLineProps,\n EventSpec extends ObjectEvents = ObjectEvents\n >\n extends FabricObject<Props, SProps, EventSpec>\n implements UniqueLineCoords\n{\n declare x1: number;\n declare y1: number;\n declare x2: number;\n declare y2: number;\n\n hitStrokeWidth: number | 'auto' = 'auto';\n\n private _updatingEndpoints = false;\n private _useEndpointCoords = true;\n\n static type = 'Line';\n static cacheProperties = [...cacheProperties, ...coordProps];\n\n constructor([x1, y1, x2, y2] = [0, 0, 100, 0], options: Partial<Props & {hitStrokeWidth?: number | 'auto'}> = {}) {\n super();\n this.setOptions(options);\n this.x1 = x1;\n this.x2 = x2;\n this.y1 = y1;\n this.y2 = y2;\n\n if (options.hitStrokeWidth !== undefined) {\n this.hitStrokeWidth = options.hitStrokeWidth;\n }\n\n this.hasBorders = false;\n this.hasControls = true;\n this.selectable = true;\n this.hoverCursor = 'move';\n this.perPixelTargetFind = false;\n this.strokeLineCap = 'butt';\n\n this._setWidthHeight();\n const { left, top } = options;\n typeof left === 'number' && this.set(LEFT, left);\n typeof top === 'number' && this.set(TOP, top);\n this._setupLineControls();\n }\n\n _setupLineControls() {\n this.controls = {\n p1: new Control({\n x: 0,\n y: 0,\n cursorStyle: 'move',\n actionHandler: this._endpointActionHandler.bind(this),\n positionHandler: this._p1PositionHandler.bind(this),\n render: this._renderEndpointControl.bind(this),\n sizeX: 12,\n sizeY: 12,\n }),\n p2: new Control({\n x: 0,\n y: 0,\n cursorStyle: 'move',\n actionHandler: this._endpointActionHandler.bind(this),\n positionHandler: this._p2PositionHandler.bind(this),\n render: this._renderEndpointControl.bind(this),\n sizeX: 12,\n sizeY: 12,\n }),\n };\n }\n\n _p1PositionHandler() {\n return new Point(this.x1, this.y1).transform(this.getViewportTransform());\n }\n\n _p2PositionHandler() {\n return new Point(this.x2, this.y2).transform(this.getViewportTransform());\n }\n\n _renderEndpointControl(\n ctx: CanvasRenderingContext2D,\n left: number,\n top: number\n ) {\n const size = 12;\n ctx.save();\n ctx.fillStyle = '#007bff';\n ctx.strokeStyle = '#ffffff';\n ctx.lineWidth = 2;\n ctx.beginPath();\n ctx.arc(left, top, size / 2, 0, 2 * Math.PI);\n ctx.fill();\n ctx.stroke();\n ctx.restore();\n }\n\n drawBorders(ctx: CanvasRenderingContext2D, styleOverride: any = {}) {\n if (this._useEndpointCoords) {\n this._drawLineBorders(ctx, styleOverride);\n return this;\n }\n return super.drawBorders(ctx, styleOverride, {});\n }\n\n _drawLineBorders(ctx: CanvasRenderingContext2D, styleOverride: any = {}) {\n const vpt = this.canvas?.viewportTransform || [1, 0, 0, 1, 0, 0];\n ctx.save();\n ctx.setTransform(vpt[0], vpt[1], vpt[2], vpt[3], vpt[4], vpt[5]);\n ctx.strokeStyle =\n styleOverride.borderColor || this.borderColor || 'rgba(100, 200, 200, 0.5)';\n ctx.lineWidth = (this.strokeWidth || 1) + 5;\n ctx.lineCap = this.strokeLineCap || 'butt';\n ctx.globalAlpha = this.isMoving ? this.borderOpacityWhenMoving : 1;\n ctx.beginPath();\n ctx.moveTo(this.x1, this.y1);\n ctx.lineTo(this.x2, this.y2);\n ctx.stroke();\n ctx.restore();\n }\n\n _renderControls(ctx: CanvasRenderingContext2D, styleOverride: any = {}) {\n ctx.save();\n ctx.globalAlpha = this.isMoving ? this.borderOpacityWhenMoving : 1;\n this.drawControls(ctx, styleOverride);\n ctx.restore();\n }\n\n getBoundingRect() {\n if (this._useEndpointCoords) {\n const { x1, y1, x2, y2 } = this;\n const effectiveStrokeWidth =\n this.hitStrokeWidth === 'auto'\n ? this.strokeWidth\n : this.hitStrokeWidth;\n const padding = Math.max(effectiveStrokeWidth / 2 + 5, 10);\n return {\n left: Math.min(x1, x2) - padding,\n top: Math.min(y1, y2) - padding,\n width: Math.abs(x2 - x1) + padding * 2 || padding * 2,\n height: Math.abs(y2 - y1) + padding * 2 || padding * 2,\n };\n }\n return super.getBoundingRect();\n }\n\n setCoords() {\n if (this._useEndpointCoords) {\n // Set the object's center to the geometric center of the line\n const center = this._findCenterFromElement();\n this.left = center.x;\n this.top = center.y;\n \n // Set width and height for hit detection and bounding box\n const effectiveStrokeWidth =\n this.hitStrokeWidth === 'auto'\n ? this.strokeWidth\n : this.hitStrokeWidth;\n const hitPadding = Math.max(effectiveStrokeWidth / 2 + 5, 10);\n this.width = Math.abs(this.x2 - this.x1) + hitPadding * 2;\n this.height = Math.abs(this.y2 - this.y1) + hitPadding * 2;\n }\n super.setCoords();\n }\n\n getCoords(): [Point, Point, Point, Point] {\n if (this._useEndpointCoords) {\n const deltaX = this.x2 - this.x1;\n const deltaY = this.y2 - this.y1;\n const length = Math.sqrt(deltaX * deltaX + deltaY * deltaY);\n \n if (length === 0) {\n return super.getCoords() as [Point, Point, Point, Point];\n }\n \n const effectiveStrokeWidth = this.hitStrokeWidth === 'auto' \n ? this.strokeWidth \n : this.hitStrokeWidth;\n const halfWidth = Math.max(effectiveStrokeWidth / 2 + 2, 5);\n \n // Unit vector perpendicular to line\n const perpX = -deltaY / length;\n const perpY = deltaX / length;\n \n // Four corners of oriented rectangle\n return [\n new Point(this.x1 + perpX * halfWidth, this.y1 + perpY * halfWidth),\n new Point(this.x2 + perpX * halfWidth, this.y2 + perpY * halfWidth),\n new Point(this.x2 - perpX * halfWidth, this.y2 - perpY * halfWidth),\n new Point(this.x1 - perpX * halfWidth, this.y1 - perpY * halfWidth),\n ];\n }\n return super.getCoords() as [Point, Point, Point, Point];\n }\n\n containsPoint(point: Point): boolean {\n if (this._useEndpointCoords) {\n if (this.canvas?.getActiveObject() === this) {\n return super.containsPoint(point);\n }\n const distance = this._distanceToLineSegment(point.x, point.y);\n const effectiveStrokeWidth = this.hitStrokeWidth === 'auto' \n ? this.strokeWidth \n : this.hitStrokeWidth || 1;\n \n const tolerance = Math.max(effectiveStrokeWidth / 2 + 2, 5);\n return distance <= tolerance;\n }\n return super.containsPoint(point);\n }\n\n _distanceToLineSegment(px: number, py: number): number {\n const x1 = this.x1, y1 = this.y1, x2 = this.x2, y2 = this.y2;\n \n const pd2 = (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2);\n if (pd2 === 0) {\n return Math.sqrt((px - x1) * (px - x1) + (py - y1) * (py - y1));\n }\n \n const u = ((px - x1) * (x2 - x1) + (py - y1) * (y2 - y1)) / pd2;\n \n let closestX: number, closestY: number;\n if (u < 0) {\n closestX = x1;\n closestY = y1;\n } else if (u > 1) {\n closestX = x2;\n closestY = y2;\n } else {\n closestX = x1 + u * (x2 - x1);\n closestY = y1 + u * (y2 - y1);\n }\n \n return Math.sqrt((px - closestX) * (px - closestX) + (py - closestY) * (py - closestY));\n }\n\n _endpointActionHandler(\n eventData: TPointerEvent,\n transformData: Transform,\n x: number,\n y: number\n ) {\n const controlKey = transformData.corner;\n const pointer = new Point(x, y);\n let newX = pointer.x;\n let newY = pointer.y;\n\n if (eventData.shiftKey) {\n const otherControl = controlKey === 'p1' ? 'p2' : 'p1';\n const otherX = this[otherControl === 'p1' ? 'x1' : 'x2'];\n const otherY = this[otherControl === 'p1' ? 'y1' : 'y2'];\n const snapped = this._snapToAngle(otherX, otherY, newX, newY);\n newX = snapped.x;\n newY = snapped.y;\n }\n\n if (this._useEndpointCoords) {\n if (controlKey === 'p1') {\n this.x1 = newX;\n this.y1 = newY;\n } else if (controlKey === 'p2') {\n this.x2 = newX;\n this.y2 = newY;\n }\n this.dirty = true;\n this.setCoords();\n this.canvas?.requestRenderAll();\n return true;\n }\n\n // Fallback for old system\n this._updatingEndpoints = true;\n if (controlKey === 'p1') {\n this.x1 = newX;\n this.y1 = newY;\n } else if (controlKey === 'p2') {\n this.x2 = newX;\n this.y2 = newY;\n }\n this._setWidthHeight();\n this.dirty = true;\n this._updatingEndpoints = false;\n this.canvas?.requestRenderAll();\n this.fire('modified', { transform: transformData, target: this, e: eventData });\n return true;\n }\n\n _snapToAngle(\n fromX: number,\n fromY: number,\n toX: number,\n toY: number\n ): { x: number; y: number } {\n const deltaX = toX - fromX;\n const deltaY = toY - fromY;\n const distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);\n if (distance === 0) return { x: toX, y: toY };\n let angle = Math.atan2(deltaY, deltaX) * (180 / Math.PI);\n const snapIncrement = 15;\n const snappedAngle = Math.round(angle / snapIncrement) * snapIncrement;\n const snappedRadians = snappedAngle * (Math.PI / 180);\n return {\n x: fromX + Math.cos(snappedRadians) * distance,\n y: fromY + Math.sin(snappedRadians) * distance,\n };\n }\n\n _setWidthHeight(skipReposition = false) {\n this.width = Math.abs(this.x2 - this.x1) || 1;\n this.height = Math.abs(this.y2 - this.y1) || 1;\n if (!skipReposition && !this._updatingEndpoints) {\n const { left, top, width, height } = makeBoundingBoxFromPoints([\n { x: this.x1, y: this.y1 },\n { x: this.x2, y: this.y2 },\n ]);\n this.setPositionByOrigin(\n new Point(left + width / 2, top + height / 2),\n CENTER,\n CENTER\n );\n }\n }\n\n _set(key: string, value: any) {\n const oldLeft = this.left;\n const oldTop = this.top;\n super._set(key, value);\n if (coordProps.includes(key as keyof UniqueLineCoords)) {\n this._setWidthHeight();\n this.dirty = true;\n }\n if ((key === 'left' || key === 'top') && this.canvas && !this._updatingEndpoints) {\n const deltaX = this.left - oldLeft;\n const deltaY = this.top - oldTop;\n if (deltaX !== 0 || deltaY !== 0) {\n this._updatingEndpoints = true;\n this.x1 += deltaX;\n this.y1 += deltaY;\n this.x2 += deltaX;\n this.y2 += deltaY;\n this._updatingEndpoints = false;\n }\n }\n return this;\n }\n\n render(ctx: CanvasRenderingContext2D) {\n if (this._useEndpointCoords) {\n this._renderDirectly(ctx);\n return;\n }\n super.render(ctx);\n }\n\n _renderDirectly(ctx: CanvasRenderingContext2D) {\n if (!this.visible) return;\n ctx.save();\n ctx.globalAlpha = this.opacity;\n ctx.strokeStyle = this.stroke?.toString() || '#000';\n ctx.lineWidth = this.strokeWidth;\n ctx.lineCap = this.strokeLineCap || 'butt';\n ctx.beginPath();\n ctx.moveTo(this.x1, this.y1);\n ctx.lineTo(this.x2, this.y2);\n ctx.stroke();\n ctx.restore();\n }\n\n _render(ctx: CanvasRenderingContext2D) {\n if (this._useEndpointCoords) return;\n ctx.beginPath();\n const p = this.calcLinePoints();\n ctx.moveTo(p.x1, p.y1);\n ctx.lineTo(p.x2, p.y2);\n ctx.lineWidth = this.strokeWidth;\n const origStrokeStyle = ctx.strokeStyle;\n if (isFiller(this.stroke)) {\n ctx.strokeStyle = this.stroke.toLive(ctx)!;\n }\n this.stroke && this._renderStroke(ctx);\n ctx.strokeStyle = origStrokeStyle;\n }\n\n _findCenterFromElement(): Point {\n return new Point((this.x1 + this.x2) / 2, (this.y1 + this.y2) / 2);\n }\n\n toObject< \n T extends Omit<Props & TClassProperties<this>, keyof SProps>,\n K extends keyof T = never\n >(propertiesToInclude: K[] = []): Pick<T, K> & SProps {\n return {\n ...super.toObject(propertiesToInclude),\n ...this.calcLinePoints(),\n };\n }\n\n _getNonTransformedDimensions(): Point {\n const dim = super._getNonTransformedDimensions();\n if (this.strokeLineCap === 'round') {\n dim.x += this.strokeWidth;\n dim.y += this.strokeWidth;\n }\n return dim;\n }\n\n calcLinePoints(): UniqueLineCoords {\n if (this._updatingEndpoints) {\n const centerX = (this.x1 + this.x2) / 2;\n const centerY = (this.y1 + this.y2) / 2;\n return {\n x1: this.x1 - centerX,\n y1: this.y1 - centerY,\n x2: this.x2 - centerX,\n y2: this.y2 - centerY,\n };\n }\n const { x1: _x1, x2: _x2, y1: _y1, y2: _y2, width, height } = this;\n const xMult = _x1 <= _x2 ? -1 : 1;\n const yMult = _y1 <= _y2 ? -1 : 1;\n return {\n x1: (xMult * width) / 2,\n y1: (yMult * height) / 2,\n x2: (xMult * -width) / 2,\n y2: (yMult * -height) / 2,\n };\n }\n\n _toSVG() {\n if (this._useEndpointCoords) {\n // Use absolute coordinates to bypass all Fabric.js transforms\n return [\n `<line stroke=\"${this.stroke}\" stroke-width=\"${this.strokeWidth}\" stroke-linecap=\"${this.strokeLineCap}\" `,\n `x1=\"${this.x1}\" y1=\"${this.y1}\" x2=\"${this.x2}\" y2=\"${this.y2}\" />\\n`,\n ];\n } else {\n // Use standard calcLinePoints for legacy mode\n const { x1, x2, y1, y2 } = this.calcLinePoints();\n return [\n '<line ',\n 'COMMON_PARTS',\n `x1=\"${x1}\" y1=\"${y1}\" x2=\"${x2}\" y2=\"${y2}\" />\\n`,\n ];\n }\n }\n\n toSVG(reviver?: (markup: string) => string): string {\n if (this._useEndpointCoords) {\n // Override toSVG to prevent Fabric.js from adding transform wrapper\n const markup = this._toSVG().join('');\n return reviver ? reviver(markup) : markup;\n }\n // Use default behavior for legacy mode\n return super.toSVG(reviver);\n }\n\n static ATTRIBUTE_NAMES = SHARED_ATTRIBUTES.concat(coordProps);\n\n static async fromElement(\n element: HTMLElement,\n options?: Abortable,\n cssRules?: CSSRules\n ) {\n const {\n x1 = 0,\n y1 = 0,\n x2 = 0,\n y2 = 0,\n ...parsedAttributes\n } = parseAttributes(element, this.ATTRIBUTE_NAMES, cssRules);\n return new this([x1, y1, x2, y2], parsedAttributes);\n }\n\n static fromObject<T extends TOptions<SerializedLineProps>>({ \n x1,\n y1,\n x2,\n y2,\n ...object\n }: T) {\n return this._fromObject<Line>(\n { ...object, points: [x1, y1, x2, y2] },\n { extraParam: 'points' }\n );\n }\n}\n\nclassRegistry.setClass(Line);\nclassRegistry.setSVGClass(Line);"],"names":["coordProps","Line","FabricObject","constructor","x1","y1","x2","y2","arguments","length","undefined","options","super","_defineProperty","this","setOptions","hitStrokeWidth","hasBorders","hasControls","selectable","hoverCursor","perPixelTargetFind","strokeLineCap","_setWidthHeight","left","top","set","LEFT","TOP","_setupLineControls","controls","p1","Control","x","y","cursorStyle","actionHandler","_endpointActionHandler","bind","positionHandler","_p1PositionHandler","render","_renderEndpointControl","sizeX","sizeY","p2","_p2PositionHandler","Point","transform","getViewportTransform","ctx","save","fillStyle","strokeStyle","lineWidth","beginPath","arc","size","Math","PI","fill","stroke","restore","drawBorders","styleOverride","_useEndpointCoords","_drawLineBorders","_this$canvas","vpt","canvas","viewportTransform","setTransform","borderColor","strokeWidth","lineCap","globalAlpha","isMoving","borderOpacityWhenMoving","moveTo","lineTo","_renderControls","drawControls","getBoundingRect","effectiveStrokeWidth","padding","max","min","width","abs","height","setCoords","center","_findCenterFromElement","hitPadding","getCoords","deltaX","deltaY","sqrt","halfWidth","perpX","perpY","containsPoint","point","_this$canvas2","getActiveObject","distance","_distanceToLineSegment","px","py","pd2","u","closestX","closestY","eventData","transformData","_this$canvas4","controlKey","corner","pointer","newX","newY","shiftKey","otherControl","otherX","otherY","snapped","_snapToAngle","_this$canvas3","dirty","requestRenderAll","_updatingEndpoints","fire","target","e","fromX","fromY","toX","toY","angle","atan2","snappedRadians","round","cos","sin","skipReposition","makeBoundingBoxFromPoints","setPositionByOrigin","CENTER","_set","key","value","oldLeft","oldTop","includes","_renderDirectly","_this$stroke","visible","opacity","toString","_render","p","calcLinePoints","origStrokeStyle","isFiller","toLive","_renderStroke","toObject","propertiesToInclude","_getNonTransformedDimensions","dim","centerX","centerY","_x1","_x2","_y1","_y2","xMult","yMult","_toSVG","toSVG","reviver","markup","join","fromElement","element","cssRules","parsedAttributes","parseAttributes","ATTRIBUTE_NAMES","fromObject","_ref","object","_fromObject","points","extraParam","cacheProperties","SHARED_ATTRIBUTES","concat","classRegistry","setClass","setSVGClass"],"mappings":"48BAgBA,MAAMA,EAAa,CAAC,KAAM,KAAM,KAAM,MAa/B,MAAMC,UAKHC,EAgBRC,WAAAA,GAAkH,IAArGC,EAAIC,EAAIC,EAAIC,GAAGC,UAAAC,OAAA,QAAAC,IAAAF,UAAA,GAAAA,UAAA,GAAG,CAAC,EAAG,EAAG,IAAK,GAAIG,EAA4DH,UAAAC,OAAA,QAAAC,IAAAF,UAAA,GAAAA,UAAA,GAAG,CAAA,EAC5GI,QAAQC,wBATwB,QAAMA,6BAEX,GAAKA,6BACL,GAO3BC,KAAKC,WAAWJ,GAChBG,KAAKV,GAAKA,EACVU,KAAKR,GAAKA,EACVQ,KAAKT,GAAKA,EACVS,KAAKP,GAAKA,OAEqBG,IAA3BC,EAAQK,iBACVF,KAAKE,eAAiBL,EAAQK,gBAGhCF,KAAKG,YAAa,EAClBH,KAAKI,aAAc,EACnBJ,KAAKK,YAAa,EAClBL,KAAKM,YAAc,OACnBN,KAAKO,oBAAqB,EAC1BP,KAAKQ,cAAgB,OAErBR,KAAKS,kBACL,MAAMC,KAAEA,EAAIC,IAAEA,GAAQd,EACN,iBAATa,GAAqBV,KAAKY,IAAIC,EAAMH,GAC5B,iBAARC,GAAoBX,KAAKY,IAAIE,EAAKH,GACzCX,KAAKe,oBACP,CAEAA,kBAAAA,GACEf,KAAKgB,SAAW,CACdC,GAAI,IAAIC,EAAQ,CACdC,EAAG,EACHC,EAAG,EACHC,YAAa,OACbC,cAAetB,KAAKuB,uBAAuBC,KAAKxB,MAChDyB,gBAAiBzB,KAAK0B,mBAAmBF,KAAKxB,MAC9C2B,OAAQ3B,KAAK4B,uBAAuBJ,KAAKxB,MACzC6B,MAAO,GACPC,MAAO,KAETC,GAAI,IAAIb,EAAQ,CACdC,EAAG,EACHC,EAAG,EACHC,YAAa,OACbC,cAAetB,KAAKuB,uBAAuBC,KAAKxB,MAChDyB,gBAAiBzB,KAAKgC,mBAAmBR,KAAKxB,MAC9C2B,OAAQ3B,KAAK4B,uBAAuBJ,KAAKxB,MACzC6B,MAAO,GACPC,MAAO,KAGb,CAEAJ,kBAAAA,GACE,OAAO,IAAIO,EAAMjC,KAAKV,GAAIU,KAAKT,IAAI2C,UAAUlC,KAAKmC,uBACpD,CAEAH,kBAAAA,GACE,OAAO,IAAIC,EAAMjC,KAAKR,GAAIQ,KAAKP,IAAIyC,UAAUlC,KAAKmC,uBACpD,CAEAP,sBAAAA,CACEQ,EACA1B,EACAC,GAGAyB,EAAIC,OACJD,EAAIE,UAAY,UAChBF,EAAIG,YAAc,UAClBH,EAAII,UAAY,EAChBJ,EAAIK,YACJL,EAAIM,IAAIhC,EAAMC,EAAKgC,EAAU,EAAG,EAAIC,KAAKC,IACzCT,EAAIU,OACJV,EAAIW,SACJX,EAAIY,SACN,CAEAC,WAAAA,CAAYb,GAAwD,IAAzBc,EAAkBxD,UAAAC,OAAA,QAAAC,IAAAF,UAAA,GAAAA,UAAA,GAAG,CAAA,EAC9D,OAAIM,KAAKmD,oBACPnD,KAAKoD,iBAAiBhB,EAAKc,GACpBlD,MAEFF,MAAMmD,YAAYb,EAAKc,EAAe,CAAA,EAC/C,CAEAE,gBAAAA,CAAiBhB,GAAwD,IAAAiB,EAAA,IAAzBH,EAAkBxD,UAAAC,OAAA,QAAAC,IAAAF,UAAA,GAAAA,UAAA,GAAG,CAAA,EACnE,MAAM4D,GAAiB,QAAXD,EAAArD,KAAKuD,cAAM,IAAAF,OAAA,EAAXA,EAAaG,oBAAqB,CAAC,EAAG,EAAG,EAAG,EAAG,EAAG,GAC9DpB,EAAIC,OACJD,EAAIqB,aAAaH,EAAI,GAAIA,EAAI,GAAIA,EAAI,GAAIA,EAAI,GAAIA,EAAI,GAAIA,EAAI,IAC7DlB,EAAIG,YACFW,EAAcQ,aAAe1D,KAAK0D,aAAe,2BACnDtB,EAAII,WAAaxC,KAAK2D,aAAe,GAAK,EAC1CvB,EAAIwB,QAAU5D,KAAKQ,eAAiB,OACpC4B,EAAIyB,YAAc7D,KAAK8D,SAAW9D,KAAK+D,wBAA0B,EACjE3B,EAAIK,YACJL,EAAI4B,OAAOhE,KAAKV,GAAIU,KAAKT,IACzB6C,EAAI6B,OAAOjE,KAAKR,GAAIQ,KAAKP,IACzB2C,EAAIW,SACJX,EAAIY,SACN,CAEAkB,eAAAA,CAAgB9B,GAAwD,IAAzBc,EAAkBxD,UAAAC,OAAA,QAAAC,IAAAF,UAAA,GAAAA,UAAA,GAAG,CAAA,EAClE0C,EAAIC,OACJD,EAAIyB,YAAc7D,KAAK8D,SAAW9D,KAAK+D,wBAA0B,EACjE/D,KAAKmE,aAAa/B,EAAKc,GACvBd,EAAIY,SACN,CAEAoB,eAAAA,GACE,GAAIpE,KAAKmD,mBAAoB,CAC3B,MAAM7D,GAAEA,EAAEC,GAAEA,EAAEC,GAAEA,EAAEC,GAAEA,GAAOO,KACrBqE,EACoB,SAAxBrE,KAAKE,eACDF,KAAK2D,YACL3D,KAAKE,eACLoE,EAAU1B,KAAK2B,IAAIF,EAAuB,EAAI,EAAG,IACvD,MAAO,CACL3D,KAAMkC,KAAK4B,IAAIlF,EAAIE,GAAM8E,EACzB3D,IAAKiC,KAAK4B,IAAIjF,EAAIE,GAAM6E,EACxBG,MAAO7B,KAAK8B,IAAIlF,EAAKF,GAAgB,EAAVgF,GAAyB,EAAVA,EAC1CK,OAAQ/B,KAAK8B,IAAIjF,EAAKF,GAAgB,EAAV+E,GAAyB,EAAVA,EAE/C,CACA,OAAOxE,MAAMsE,iBACf,CAEAQ,SAAAA,GACE,GAAI5E,KAAKmD,mBAAoB,CAE3B,MAAM0B,EAAS7E,KAAK8E,yBACpB9E,KAAKU,KAAOmE,EAAO1D,EACnBnB,KAAKW,IAAMkE,EAAOzD,EAGlB,MAAMiD,EACoB,SAAxBrE,KAAKE,eACDF,KAAK2D,YACL3D,KAAKE,eACL6E,EAAanC,KAAK2B,IAAIF,EAAuB,EAAI,EAAG,IAC1DrE,KAAKyE,MAAQ7B,KAAK8B,IAAI1E,KAAKR,GAAKQ,KAAKV,IAAmB,EAAbyF,EAC3C/E,KAAK2E,OAAS/B,KAAK8B,IAAI1E,KAAKP,GAAKO,KAAKT,IAAmB,EAAbwF,CAC9C,CACAjF,MAAM8E,WACR,CAEAI,SAAAA,GACE,GAAIhF,KAAKmD,mBAAoB,CAC3B,MAAM8B,EAASjF,KAAKR,GAAKQ,KAAKV,GACxB4F,EAASlF,KAAKP,GAAKO,KAAKT,GACxBI,EAASiD,KAAKuC,KAAKF,EAASA,EAASC,EAASA,GAEpD,GAAe,IAAXvF,EACF,OAAOG,MAAMkF,YAGf,MAAMX,EAA+C,SAAxBrE,KAAKE,eAC9BF,KAAK2D,YACL3D,KAAKE,eACHkF,EAAYxC,KAAK2B,IAAIF,EAAuB,EAAI,EAAG,GAGnDgB,GAASH,EAASvF,EAClB2F,EAAQL,EAAStF,EAGvB,MAAO,CACL,IAAIsC,EAAMjC,KAAKV,GAAK+F,EAAQD,EAAWpF,KAAKT,GAAK+F,EAAQF,GACzD,IAAInD,EAAMjC,KAAKR,GAAK6F,EAAQD,EAAWpF,KAAKP,GAAK6F,EAAQF,GACzD,IAAInD,EAAMjC,KAAKR,GAAK6F,EAAQD,EAAWpF,KAAKP,GAAK6F,EAAQF,GACzD,IAAInD,EAAMjC,KAAKV,GAAK+F,EAAQD,EAAWpF,KAAKT,GAAK+F,EAAQF,GAE7D,CACA,OAAOtF,MAAMkF,WACf,CAEAO,aAAAA,CAAcC,GACZ,GAAIxF,KAAKmD,mBAAoB,CAAA,IAAAsC,EAC3B,IAAe,QAAXA,EAAAzF,KAAKuD,cAAM,IAAAkC,OAAA,EAAXA,EAAaC,qBAAsB1F,KACrC,OAAOF,MAAMyF,cAAcC,GAE7B,MAAMG,EAAW3F,KAAK4F,uBAAuBJ,EAAMrE,EAAGqE,EAAMpE,GACtDiD,EAA+C,SAAxBrE,KAAKE,eAC9BF,KAAK2D,YACL3D,KAAKE,gBAAkB,EAG3B,OAAOyF,GADW/C,KAAK2B,IAAIF,EAAuB,EAAI,EAAG,EAE3D,CACA,OAAOvE,MAAMyF,cAAcC,EAC7B,CAEAI,sBAAAA,CAAuBC,EAAYC,GACjC,MAAMxG,EAAKU,KAAKV,GAAIC,EAAKS,KAAKT,GAAIC,EAAKQ,KAAKR,GAAIC,EAAKO,KAAKP,GAEpDsG,GAAOzG,EAAKE,IAAOF,EAAKE,IAAOD,EAAKE,IAAOF,EAAKE,GACtD,GAAY,IAARsG,EACF,OAAOnD,KAAKuC,MAAMU,EAAKvG,IAAOuG,EAAKvG,IAAOwG,EAAKvG,IAAOuG,EAAKvG,IAG7D,MAAMyG,IAAMH,EAAKvG,IAAOE,EAAKF,IAAOwG,EAAKvG,IAAOE,EAAKF,IAAOwG,EAE5D,IAAIE,EAAkBC,EAYtB,OAXIF,EAAI,GACNC,EAAW3G,EACX4G,EAAW3G,GACFyG,EAAI,GACbC,EAAWzG,EACX0G,EAAWzG,IAEXwG,EAAW3G,EAAK0G,GAAKxG,EAAKF,GAC1B4G,EAAW3G,EAAKyG,GAAKvG,EAAKF,IAGrBqD,KAAKuC,MAAMU,EAAKI,IAAaJ,EAAKI,IAAaH,EAAKI,IAAaJ,EAAKI,GAC/E,CAEA3E,sBAAAA,CACE4E,EACAC,EACAjF,EACAC,GACA,IAAAiF,EACA,MAAMC,EAAaF,EAAcG,OAC3BC,EAAU,IAAIvE,EAAMd,EAAGC,GAC7B,IAAIqF,EAAOD,EAAQrF,EACfuF,EAAOF,EAAQpF,EAEnB,GAAI+E,EAAUQ,SAAU,CACtB,MAAMC,EAA8B,OAAfN,EAAsB,KAAO,KAC5CO,EAAS7G,KAAsB,OAAjB4G,EAAwB,KAAO,MAC7CE,EAAS9G,KAAsB,OAAjB4G,EAAwB,KAAO,MAC7CG,EAAU/G,KAAKgH,aAAaH,EAAQC,EAAQL,EAAMC,GACxDD,EAAOM,EAAQ5F,EACfuF,EAAOK,EAAQ3F,CACjB,CAE6B,IAAA6F,EAA7B,OAAIjH,KAAKmD,oBACY,OAAfmD,GACFtG,KAAKV,GAAKmH,EACVzG,KAAKT,GAAKmH,GACc,OAAfJ,IACTtG,KAAKR,GAAKiH,EACVzG,KAAKP,GAAKiH,GAEZ1G,KAAKkH,OAAQ,EACblH,KAAK4E,YACM,QAAXqC,EAAAjH,KAAKuD,cAAM,IAAA0D,GAAXA,EAAaE,oBACN,IAITnH,KAAKoH,oBAAqB,EACP,OAAfd,GACFtG,KAAKV,GAAKmH,EACVzG,KAAKT,GAAKmH,GACc,OAAfJ,IACTtG,KAAKR,GAAKiH,EACVzG,KAAKP,GAAKiH,GAEZ1G,KAAKS,kBACLT,KAAKkH,OAAQ,EACblH,KAAKoH,oBAAqB,EACf,QAAXf,EAAArG,KAAKuD,cAAM,IAAA8C,GAAXA,EAAac,mBACbnH,KAAKqH,KAAK,WAAY,CAAEnF,UAAWkE,EAAekB,OAAQtH,KAAMuH,EAAGpB,KAC5D,EACT,CAEAa,YAAAA,CACEQ,EACAC,EACAC,EACAC,GAEA,MAAM1C,EAASyC,EAAMF,EACftC,EAASyC,EAAMF,EACf9B,EAAW/C,KAAKuC,KAAKF,EAASA,EAASC,EAASA,GACtD,GAAiB,IAAbS,EAAgB,MAAO,CAAExE,EAAGuG,EAAKtG,EAAGuG,GACxC,IAAIC,EAAQhF,KAAKiF,MAAM3C,EAAQD,IAAW,IAAMrC,KAAKC,IACrD,MAEMiF,EAFgB,GACDlF,KAAKmF,MAAMH,EADV,KAEiBhF,KAAKC,GAAK,KACjD,MAAO,CACL1B,EAAGqG,EAAQ5E,KAAKoF,IAAIF,GAAkBnC,EACtCvE,EAAGqG,EAAQ7E,KAAKqF,IAAIH,GAAkBnC,EAE1C,CAEAlF,eAAAA,GAAwC,IAAxByH,EAAcxI,UAAAC,OAAA,QAAAC,IAAAF,UAAA,IAAAA,UAAA,GAG5B,GAFAM,KAAKyE,MAAQ7B,KAAK8B,IAAI1E,KAAKR,GAAKQ,KAAKV,KAAO,EAC5CU,KAAK2E,OAAS/B,KAAK8B,IAAI1E,KAAKP,GAAKO,KAAKT,KAAO,GACxC2I,IAAmBlI,KAAKoH,mBAAoB,CAC/C,MAAM1G,KAAEA,EAAIC,IAAEA,EAAG8D,MAAEA,EAAKE,OAAEA,GAAWwD,EAA0B,CAC7D,CAAEhH,EAAGnB,KAAKV,GAAI8B,EAAGpB,KAAKT,IACtB,CAAE4B,EAAGnB,KAAKR,GAAI4B,EAAGpB,KAAKP,MAExBO,KAAKoI,oBACH,IAAInG,EAAMvB,EAAO+D,EAAQ,EAAG9D,EAAMgE,EAAS,GAC3C0D,EACAA,EAEJ,CACF,CAEAC,IAAAA,CAAKC,EAAaC,GAChB,MAAMC,EAAUzI,KAAKU,KACfgI,EAAS1I,KAAKW,IAMpB,GALAb,MAAMwI,KAAKC,EAAKC,GACZtJ,EAAWyJ,SAASJ,KACtBvI,KAAKS,kBACLT,KAAKkH,OAAQ,IAEF,SAARqB,GAA0B,QAARA,IAAkBvI,KAAKuD,SAAWvD,KAAKoH,mBAAoB,CAChF,MAAMnC,EAASjF,KAAKU,KAAO+H,EACrBvD,EAASlF,KAAKW,IAAM+H,EACX,IAAXzD,GAA2B,IAAXC,IAClBlF,KAAKoH,oBAAqB,EAC1BpH,KAAKV,IAAM2F,EACXjF,KAAKT,IAAM2F,EACXlF,KAAKR,IAAMyF,EACXjF,KAAKP,IAAMyF,EACXlF,KAAKoH,oBAAqB,EAE9B,CACA,OAAOpH,IACT,CAEA2B,MAAAA,CAAOS,GACDpC,KAAKmD,mBACPnD,KAAK4I,gBAAgBxG,GAGvBtC,MAAM6B,OAAOS,EACf,CAEAwG,eAAAA,CAAgBxG,GAA+B,IAAAyG,EACxC7I,KAAK8I,UACV1G,EAAIC,OACJD,EAAIyB,YAAc7D,KAAK+I,QACvB3G,EAAIG,aAAyB,QAAXsG,OAAK9F,kBAAM8F,SAAXA,EAAaG,aAAc,OAC7C5G,EAAII,UAAYxC,KAAK2D,YACrBvB,EAAIwB,QAAU5D,KAAKQ,eAAiB,OACpC4B,EAAIK,YACJL,EAAI4B,OAAOhE,KAAKV,GAAIU,KAAKT,IACzB6C,EAAI6B,OAAOjE,KAAKR,GAAIQ,KAAKP,IACzB2C,EAAIW,SACJX,EAAIY,UACN,CAEAiG,OAAAA,CAAQ7G,GACN,GAAIpC,KAAKmD,mBAAoB,OAC7Bf,EAAIK,YACJ,MAAMyG,EAAIlJ,KAAKmJ,iBACf/G,EAAI4B,OAAOkF,EAAE5J,GAAI4J,EAAE3J,IACnB6C,EAAI6B,OAAOiF,EAAE1J,GAAI0J,EAAEzJ,IACnB2C,EAAII,UAAYxC,KAAK2D,YACrB,MAAMyF,EAAkBhH,EAAIG,YACxB8G,EAASrJ,KAAK+C,UAChBX,EAAIG,YAAcvC,KAAK+C,OAAOuG,OAAOlH,IAEvCpC,KAAK+C,QAAU/C,KAAKuJ,cAAcnH,GAClCA,EAAIG,YAAc6G,CACpB,CAEAtE,sBAAAA,GACE,OAAO,IAAI7C,GAAOjC,KAAKV,GAAKU,KAAKR,IAAM,GAAIQ,KAAKT,GAAKS,KAAKP,IAAM,EAClE,CAEA+J,QAAAA,GAGsD,IAApDC,EAAwB/J,UAAAC,OAAA,QAAAC,IAAAF,UAAA,GAAAA,UAAA,GAAG,GAC3B,MAAO,IACFI,MAAM0J,SAASC,MACfzJ,KAAKmJ,iBAEZ,CAEAO,4BAAAA,GACE,MAAMC,EAAM7J,MAAM4J,+BAKlB,MAJ2B,UAAvB1J,KAAKQ,gBACPmJ,EAAIxI,GAAKnB,KAAK2D,YACdgG,EAAIvI,GAAKpB,KAAK2D,aAETgG,CACT,CAEAR,cAAAA,GACE,GAAInJ,KAAKoH,mBAAoB,CAC3B,MAAMwC,GAAW5J,KAAKV,GAAKU,KAAKR,IAAM,EAChCqK,GAAW7J,KAAKT,GAAKS,KAAKP,IAAM,EACtC,MAAO,CACLH,GAAIU,KAAKV,GAAKsK,EACdrK,GAAIS,KAAKT,GAAKsK,EACdrK,GAAIQ,KAAKR,GAAKoK,EACdnK,GAAIO,KAAKP,GAAKoK,EAElB,CACA,MAAQvK,GAAIwK,EAAKtK,GAAIuK,EAAKxK,GAAIyK,EAAKvK,GAAIwK,EAAGxF,MAAEA,EAAKE,OAAEA,GAAW3E,KACxDkK,EAAQJ,GAAOC,GAAM,EAAK,EAC1BI,EAAQH,GAAOC,GAAM,EAAK,EAChC,MAAO,CACL3K,GAAK4K,EAAQzF,EAAS,EACtBlF,GAAK4K,EAAQxF,EAAU,EACvBnF,GAAK0K,GAASzF,EAAS,EACvBhF,GAAK0K,GAASxF,EAAU,EAE5B,CAEAyF,MAAAA,GACE,GAAIpK,KAAKmD,mBAEP,MAAO,CACL,iBAAiBnD,KAAK+C,yBAAyB/C,KAAK2D,gCAAgC3D,KAAKQ,kBACzF,OAAOR,KAAKV,WAAWU,KAAKT,WAAWS,KAAKR,WAAWQ,KAAKP,YAEzD,CAEL,MAAMH,GAAEA,EAAEE,GAAEA,EAAED,GAAEA,EAAEE,GAAEA,GAAOO,KAAKmJ,iBAChC,MAAO,CACL,SACA,eACA,OAAO7J,UAAWC,UAAWC,UAAWC,UAE5C,CACF,CAEA4K,KAAAA,CAAMC,GACJ,GAAItK,KAAKmD,mBAAoB,CAE3B,MAAMoH,EAASvK,KAAKoK,SAASI,KAAK,IAClC,OAAOF,EAAUA,EAAQC,GAAUA,CACrC,CAEA,OAAOzK,MAAMuK,MAAMC,EACrB,CAIA,wBAAaG,CACXC,EACA7K,EACA8K,GAEA,MAAMrL,GACJA,EAAK,EAACC,GACNA,EAAK,EAACC,GACNA,EAAK,EAACC,GACNA,EAAK,KACFmL,GACDC,EAAgBH,EAAS1K,KAAK8K,gBAAiBH,GACnD,OAAO,IAAI3K,KAAK,CAACV,EAAIC,EAAIC,EAAIC,GAAKmL,EACpC,CAEA,iBAAOG,CAAUC,GAMX,IANqD1L,GACzDA,EAAEC,GACFA,EAAEC,GACFA,EAAEC,GACFA,KACGwL,GACDD,EACF,OAAOhL,KAAKkL,YACV,IAAKD,EAAQE,OAAQ,CAAC7L,EAAIC,EAAIC,EAAIC,IAClC,CAAE2L,WAAY,UAElB,EACDrL,EAreYZ,EAAI,OAkBD,QAAMY,EAlBTZ,EAAI,kBAmBU,IAAIkM,KAAoBnM,IAAWa,EAnBjDZ,EAAI,kBAwcUmM,EAAkBC,OAAOrM,IA+BpDsM,EAAcC,SAAStM,GACvBqM,EAAcE,YAAYvM"}
|
|
1
|
+
{"version":3,"file":"Line.min.mjs","sources":["../../../src/shapes/Line.ts"],"sourcesContent":["import { SHARED_ATTRIBUTES } from '../parser/attributes';\nimport { parseAttributes } from '../parser/parseAttributes';\nimport type { Abortable, TClassProperties, TOptions } from '../typedefs';\nimport { classRegistry } from '../ClassRegistry';\nimport { FabricObject, cacheProperties } from './Object/FabricObject';\nimport { Point } from '../Point';\nimport { isFiller } from '../util/typeAssertions';\nimport type { FabricObjectProps, SerializedObjectProps } from './Object/types';\nimport type { ObjectEvents } from '../EventTypeDefs';\nimport { makeBoundingBoxFromPoints } from '../util';\nimport { CENTER, LEFT, TOP } from '../constants';\nimport type { CSSRules } from '../parser/typedefs';\nimport { Control } from '../controls/Control';\nimport type { TPointerEvent, Transform } from '../EventTypeDefs';\nimport { Gradient } from '../gradient/Gradient';\n\nconst coordProps = ['x1', 'x2', 'y1', 'y2'] as const;\n\ninterface UniqueLineCoords {\n x1: number;\n x2: number;\n y1: number;\n y2: number;\n}\n\nexport interface SerializedLineProps\n extends SerializedObjectProps,\n UniqueLineCoords {}\n\nexport class Line<\n Props extends TOptions<FabricObjectProps> = Partial<FabricObjectProps>,\n SProps extends SerializedLineProps = SerializedLineProps,\n EventSpec extends ObjectEvents = ObjectEvents,\n >\n extends FabricObject<Props, SProps, EventSpec>\n implements UniqueLineCoords\n{\n declare x1: number;\n declare y1: number;\n declare x2: number;\n declare y2: number;\n\n hitStrokeWidth: number | 'auto' = 'auto';\n\n private _updatingEndpoints = false;\n private _useEndpointCoords = true;\n private _exportingSVG = false;\n\n static type = 'Line';\n static cacheProperties = [...cacheProperties, ...coordProps];\n\n constructor(\n [x1, y1, x2, y2] = [0, 0, 100, 0],\n options: Partial<Props & { hitStrokeWidth?: number | 'auto' }> = {},\n ) {\n super();\n this.setOptions(options);\n this.x1 = x1;\n this.x2 = x2;\n this.y1 = y1;\n this.y2 = y2;\n\n if (options.hitStrokeWidth !== undefined) {\n this.hitStrokeWidth = options.hitStrokeWidth;\n }\n\n this.hasBorders = false;\n this.hasControls = true;\n this.selectable = true;\n this.hoverCursor = 'move';\n this.perPixelTargetFind = false;\n this.strokeLineCap = 'butt';\n\n this._setWidthHeight();\n const { left, top } = options;\n typeof left === 'number' && this.set(LEFT, left);\n typeof top === 'number' && this.set(TOP, top);\n this._setupLineControls();\n }\n\n _setupLineControls() {\n this.controls = {\n p1: new Control({\n x: 0,\n y: 0,\n cursorStyle: 'move',\n actionHandler: this._endpointActionHandler.bind(this),\n positionHandler: this._p1PositionHandler.bind(this),\n render: this._renderEndpointControl.bind(this),\n sizeX: 12,\n sizeY: 12,\n }),\n p2: new Control({\n x: 0,\n y: 0,\n cursorStyle: 'move',\n actionHandler: this._endpointActionHandler.bind(this),\n positionHandler: this._p2PositionHandler.bind(this),\n render: this._renderEndpointControl.bind(this),\n sizeX: 12,\n sizeY: 12,\n }),\n };\n }\n\n _p1PositionHandler() {\n return new Point(this.x1, this.y1).transform(this.getViewportTransform());\n }\n\n _p2PositionHandler() {\n return new Point(this.x2, this.y2).transform(this.getViewportTransform());\n }\n\n _renderEndpointControl(\n ctx: CanvasRenderingContext2D,\n left: number,\n top: number,\n ) {\n const size = 12;\n ctx.save();\n ctx.fillStyle = '#007bff';\n ctx.strokeStyle = '#ffffff';\n ctx.lineWidth = 2;\n ctx.beginPath();\n ctx.arc(left, top, size / 2, 0, 2 * Math.PI);\n ctx.fill();\n ctx.stroke();\n ctx.restore();\n }\n\n drawBorders(ctx: CanvasRenderingContext2D, styleOverride: any = {}) {\n if (this._useEndpointCoords) {\n this._drawLineBorders(ctx, styleOverride);\n return this;\n }\n return super.drawBorders(ctx, styleOverride, {});\n }\n\n _drawLineBorders(ctx: CanvasRenderingContext2D, styleOverride: any = {}) {\n const vpt = this.canvas?.viewportTransform || [1, 0, 0, 1, 0, 0];\n ctx.save();\n ctx.setTransform(vpt[0], vpt[1], vpt[2], vpt[3], vpt[4], vpt[5]);\n ctx.strokeStyle =\n styleOverride.borderColor ||\n this.borderColor ||\n 'rgba(100, 200, 200, 0.5)';\n ctx.lineWidth = (this.strokeWidth || 1) + 5;\n ctx.lineCap = this.strokeLineCap || 'butt';\n ctx.globalAlpha = this.isMoving ? this.borderOpacityWhenMoving : 1;\n ctx.beginPath();\n ctx.moveTo(this.x1, this.y1);\n ctx.lineTo(this.x2, this.y2);\n ctx.stroke();\n ctx.restore();\n }\n\n _renderControls(ctx: CanvasRenderingContext2D, styleOverride: any = {}) {\n ctx.save();\n ctx.globalAlpha = this.isMoving ? this.borderOpacityWhenMoving : 1;\n this.drawControls(ctx, styleOverride);\n ctx.restore();\n }\n\n getBoundingRect() {\n if (this._useEndpointCoords) {\n const { x1, y1, x2, y2 } = this;\n const effectiveStrokeWidth =\n this.hitStrokeWidth === 'auto' ? this.strokeWidth : this.hitStrokeWidth;\n const padding = Math.max(effectiveStrokeWidth / 2 + 5, 10);\n return {\n left: Math.min(x1, x2) - padding,\n top: Math.min(y1, y2) - padding,\n width: Math.abs(x2 - x1) + padding * 2 || padding * 2,\n height: Math.abs(y2 - y1) + padding * 2 || padding * 2,\n };\n }\n return super.getBoundingRect();\n }\n\n setCoords() {\n if (this._useEndpointCoords) {\n // Set width and height for hit detection and bounding box\n const effectiveStrokeWidth =\n this.hitStrokeWidth === 'auto' ? this.strokeWidth : this.hitStrokeWidth;\n const hitPadding = Math.max(effectiveStrokeWidth / 2 + 5, 10);\n this.width = Math.abs(this.x2 - this.x1) + hitPadding * 2;\n this.height = Math.abs(this.y2 - this.y1) + hitPadding * 2;\n\n // Only update left/top if they haven't been explicitly set (e.g., during loading)\n if (this.left === 0 && this.top === 0) {\n const center = this._findCenterFromElement();\n this.left = center.x;\n this.top = center.y;\n }\n }\n super.setCoords();\n }\n\n getCoords(): [Point, Point, Point, Point] {\n if (this._useEndpointCoords) {\n const deltaX = this.x2 - this.x1;\n const deltaY = this.y2 - this.y1;\n const length = Math.sqrt(deltaX * deltaX + deltaY * deltaY);\n\n if (length === 0) {\n return super.getCoords() as [Point, Point, Point, Point];\n }\n\n const effectiveStrokeWidth =\n this.hitStrokeWidth === 'auto' ? this.strokeWidth : this.hitStrokeWidth;\n const halfWidth = Math.max(effectiveStrokeWidth / 2 + 2, 5);\n\n // Unit vector perpendicular to line\n const perpX = -deltaY / length;\n const perpY = deltaX / length;\n\n // Four corners of oriented rectangle\n return [\n new Point(this.x1 + perpX * halfWidth, this.y1 + perpY * halfWidth),\n new Point(this.x2 + perpX * halfWidth, this.y2 + perpY * halfWidth),\n new Point(this.x2 - perpX * halfWidth, this.y2 - perpY * halfWidth),\n new Point(this.x1 - perpX * halfWidth, this.y1 - perpY * halfWidth),\n ];\n }\n return super.getCoords() as [Point, Point, Point, Point];\n }\n\n containsPoint(point: Point): boolean {\n if (this._useEndpointCoords) {\n if (this.canvas?.getActiveObject() === this) {\n return super.containsPoint(point);\n }\n const distance = this._distanceToLineSegment(point.x, point.y);\n const effectiveStrokeWidth =\n this.hitStrokeWidth === 'auto'\n ? this.strokeWidth\n : this.hitStrokeWidth || 1;\n\n const tolerance = Math.max(effectiveStrokeWidth / 2 + 2, 5);\n return distance <= tolerance;\n }\n return super.containsPoint(point);\n }\n\n _distanceToLineSegment(px: number, py: number): number {\n const x1 = this.x1,\n y1 = this.y1,\n x2 = this.x2,\n y2 = this.y2;\n\n const pd2 = (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2);\n if (pd2 === 0) {\n return Math.sqrt((px - x1) * (px - x1) + (py - y1) * (py - y1));\n }\n\n const u = ((px - x1) * (x2 - x1) + (py - y1) * (y2 - y1)) / pd2;\n\n let closestX: number, closestY: number;\n if (u < 0) {\n closestX = x1;\n closestY = y1;\n } else if (u > 1) {\n closestX = x2;\n closestY = y2;\n } else {\n closestX = x1 + u * (x2 - x1);\n closestY = y1 + u * (y2 - y1);\n }\n\n return Math.sqrt(\n (px - closestX) * (px - closestX) + (py - closestY) * (py - closestY),\n );\n }\n\n _endpointActionHandler(\n eventData: TPointerEvent,\n transformData: Transform,\n x: number,\n y: number,\n ) {\n const controlKey = transformData.corner;\n const pointer = new Point(x, y);\n let newX = pointer.x;\n let newY = pointer.y;\n\n if (eventData.shiftKey) {\n const otherControl = controlKey === 'p1' ? 'p2' : 'p1';\n const otherX = this[otherControl === 'p1' ? 'x1' : 'x2'];\n const otherY = this[otherControl === 'p1' ? 'y1' : 'y2'];\n const snapped = this._snapToAngle(otherX, otherY, newX, newY);\n newX = snapped.x;\n newY = snapped.y;\n }\n\n if (this._useEndpointCoords) {\n if (controlKey === 'p1') {\n this.x1 = newX;\n this.y1 = newY;\n } else if (controlKey === 'p2') {\n this.x2 = newX;\n this.y2 = newY;\n }\n\n // Update gradient coordinates if stroke is a gradient (but not during SVG export)\n if (this.stroke instanceof Gradient && !this._exportingSVG) {\n this.stroke.coords.x1 = this.x1;\n this.stroke.coords.y1 = this.y1;\n this.stroke.coords.x2 = this.x2;\n this.stroke.coords.y2 = this.y2;\n }\n\n this.dirty = true;\n this.setCoords();\n this.canvas?.requestRenderAll();\n return true;\n }\n\n // Fallback for old system\n this._updatingEndpoints = true;\n if (controlKey === 'p1') {\n this.x1 = newX;\n this.y1 = newY;\n } else if (controlKey === 'p2') {\n this.x2 = newX;\n this.y2 = newY;\n }\n this._setWidthHeight();\n this.dirty = true;\n this._updatingEndpoints = false;\n this.canvas?.requestRenderAll();\n this.fire('modified', {\n transform: transformData,\n target: this,\n e: eventData,\n });\n return true;\n }\n\n _snapToAngle(\n fromX: number,\n fromY: number,\n toX: number,\n toY: number,\n ): { x: number; y: number } {\n const deltaX = toX - fromX;\n const deltaY = toY - fromY;\n const distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);\n if (distance === 0) return { x: toX, y: toY };\n let angle = Math.atan2(deltaY, deltaX) * (180 / Math.PI);\n const snapIncrement = 15;\n const snappedAngle = Math.round(angle / snapIncrement) * snapIncrement;\n const snappedRadians = snappedAngle * (Math.PI / 180);\n return {\n x: fromX + Math.cos(snappedRadians) * distance,\n y: fromY + Math.sin(snappedRadians) * distance,\n };\n }\n\n _setWidthHeight(skipReposition = false) {\n this.width = Math.abs(this.x2 - this.x1) || 1;\n this.height = Math.abs(this.y2 - this.y1) || 1;\n if (!skipReposition && !this._updatingEndpoints) {\n const { left, top, width, height } = makeBoundingBoxFromPoints([\n { x: this.x1, y: this.y1 },\n { x: this.x2, y: this.y2 },\n ]);\n this.setPositionByOrigin(\n new Point(left + width / 2, top + height / 2),\n CENTER,\n CENTER,\n );\n }\n }\n\n _set(key: string, value: any) {\n const oldLeft = this.left;\n const oldTop = this.top;\n super._set(key, value);\n if (coordProps.includes(key as keyof UniqueLineCoords)) {\n this._setWidthHeight();\n this.dirty = true;\n\n // Update gradient coordinates if stroke is a gradient (but not during SVG export)\n if (this.stroke instanceof Gradient && !this._exportingSVG) {\n this.stroke.coords.x1 = this.x1;\n this.stroke.coords.y1 = this.y1;\n this.stroke.coords.x2 = this.x2;\n this.stroke.coords.y2 = this.y2;\n }\n }\n if (\n (key === 'left' || key === 'top') &&\n this.canvas &&\n !this._updatingEndpoints\n ) {\n const deltaX = this.left - oldLeft;\n const deltaY = this.top - oldTop;\n if (deltaX !== 0 || deltaY !== 0) {\n this._updatingEndpoints = true;\n this.x1 += deltaX;\n this.y1 += deltaY;\n this.x2 += deltaX;\n this.y2 += deltaY;\n\n // Update gradient coordinates if stroke is a gradient\n if (this.stroke instanceof Gradient) {\n this.stroke.coords.x1 = this.x1;\n this.stroke.coords.y1 = this.y1;\n this.stroke.coords.x2 = this.x2;\n this.stroke.coords.y2 = this.y2;\n }\n\n this._updatingEndpoints = false;\n }\n }\n return this;\n }\n\n render(ctx: CanvasRenderingContext2D) {\n if (this._useEndpointCoords) {\n this._renderDirectly(ctx);\n return;\n }\n super.render(ctx);\n }\n\n _renderDirectly(ctx: CanvasRenderingContext2D) {\n if (!this.visible) return;\n ctx.save();\n ctx.globalAlpha = this.opacity;\n ctx.lineWidth = this.strokeWidth;\n ctx.lineCap = this.strokeLineCap || 'butt';\n ctx.beginPath();\n ctx.moveTo(this.x1, this.y1);\n ctx.lineTo(this.x2, this.y2);\n\n const origStrokeStyle = ctx.strokeStyle;\n if (isFiller(this.stroke)) {\n ctx.strokeStyle = this.stroke.toLive(ctx)!;\n } else {\n ctx.strokeStyle = this.stroke?.toString() || '#000';\n }\n\n ctx.stroke();\n ctx.strokeStyle = origStrokeStyle;\n ctx.restore();\n }\n\n _render(ctx: CanvasRenderingContext2D) {\n if (this._useEndpointCoords) return;\n ctx.beginPath();\n const p = this.calcLinePoints();\n ctx.moveTo(p.x1, p.y1);\n ctx.lineTo(p.x2, p.y2);\n ctx.lineWidth = this.strokeWidth;\n const origStrokeStyle = ctx.strokeStyle;\n if (isFiller(this.stroke)) {\n ctx.strokeStyle = this.stroke.toLive(ctx)!;\n }\n this.stroke && this._renderStroke(ctx);\n ctx.strokeStyle = origStrokeStyle;\n }\n\n _findCenterFromElement(): Point {\n return new Point((this.x1 + this.x2) / 2, (this.y1 + this.y2) / 2);\n }\n\n toObject<\n T extends Omit<Props & TClassProperties<this>, keyof SProps>,\n K extends keyof T = never,\n >(propertiesToInclude: K[] = []): Pick<T, K> & SProps {\n if (this._useEndpointCoords) {\n return {\n ...super.toObject(propertiesToInclude),\n x1: this.x1,\n y1: this.y1,\n x2: this.x2,\n y2: this.y2,\n };\n }\n return {\n ...super.toObject(propertiesToInclude),\n ...this.calcLinePoints(),\n };\n }\n\n _getNonTransformedDimensions(): Point {\n const dim = super._getNonTransformedDimensions();\n if (this.strokeLineCap === 'round') {\n dim.x += this.strokeWidth;\n dim.y += this.strokeWidth;\n }\n return dim;\n }\n\n calcLinePoints(): UniqueLineCoords {\n if (this._updatingEndpoints) {\n const centerX = (this.x1 + this.x2) / 2;\n const centerY = (this.y1 + this.y2) / 2;\n return {\n x1: this.x1 - centerX,\n y1: this.y1 - centerY,\n x2: this.x2 - centerX,\n y2: this.y2 - centerY,\n };\n }\n const { x1: _x1, x2: _x2, y1: _y1, y2: _y2, width, height } = this;\n const xMult = _x1 <= _x2 ? -1 : 1;\n const yMult = _y1 <= _y2 ? -1 : 1;\n return {\n x1: (xMult * width) / 2,\n y1: (yMult * height) / 2,\n x2: (xMult * -width) / 2,\n y2: (yMult * -height) / 2,\n };\n }\n\n _toSVG() {\n if (this._useEndpointCoords) {\n // Use absolute coordinates to bypass all Fabric.js transforms\n // Handle gradients manually for proper SVG export\n let strokeAttr = '';\n if (this.stroke instanceof Gradient) {\n // Let Fabric.js handle gradient definition, but we'll use the reference\n strokeAttr = `stroke=\"url(#${this.stroke.id})\"`;\n } else {\n strokeAttr = `stroke=\"${this.stroke || 'none'}\"`;\n }\n\n return [\n `<line ${strokeAttr} stroke-width=\"${this.strokeWidth}\" stroke-linecap=\"${this.strokeLineCap}\" `,\n `stroke-dasharray=\"${this.strokeDashArray ? this.strokeDashArray.join(' ') : 'none'}\" `,\n `stroke-dashoffset=\"${this.strokeDashOffset}\" stroke-linejoin=\"${this.strokeLineJoin}\" `,\n `stroke-miterlimit=\"${this.strokeMiterLimit}\" fill=\"${this.fill || 'none'}\" `,\n `fill-rule=\"${this.fillRule}\" opacity=\"${this.opacity}\" `,\n `x1=\"${this.x1}\" y1=\"${this.y1}\" x2=\"${this.x2}\" y2=\"${this.y2}\" />\\n`,\n ];\n } else {\n // Use standard calcLinePoints for legacy mode\n const { x1, x2, y1, y2 } = this.calcLinePoints();\n return [\n '<line ',\n 'COMMON_PARTS',\n `x1=\"${x1}\" y1=\"${y1}\" x2=\"${x2}\" y2=\"${y2}\" />\\n`,\n ];\n }\n }\n\n toSVG(reviver?: (markup: string) => string): string {\n if (this._useEndpointCoords) {\n // For endpoint coords, we need to bypass transforms but still allow gradients\n // Let's temporarily disable transforms during SVG generation\n const originalLeft = this.left;\n const originalTop = this.top;\n\n // Set position to center of line for gradient calculation\n this.left = (this.x1 + this.x2) / 2;\n this.top = (this.y1 + this.y2) / 2;\n\n // Get the SVG with standard system (for gradient handling)\n const standardSVG = super.toSVG(reviver);\n\n // Restore original position\n this.left = originalLeft;\n this.top = originalTop;\n\n // Extract gradient definition and clean up the line element\n // Remove the transform wrapper and update coordinates\n const cleanSVG = standardSVG\n .replace(/<g transform=\"[^\"]*\"[^>]*>/g, '')\n .replace(/<\\/g>/g, '')\n .replace(/x1=\"[^\"]*\"/g, `x1=\"${this.x1}\"`)\n .replace(/y1=\"[^\"]*\"/g, `y1=\"${this.y1}\"`)\n .replace(/x2=\"[^\"]*\"/g, `x2=\"${this.x2}\"`)\n .replace(/y2=\"[^\"]*\"/g, `y2=\"${this.y2}\"`);\n\n return cleanSVG;\n }\n // Use default behavior for legacy mode\n return super.toSVG(reviver);\n }\n\n static ATTRIBUTE_NAMES = SHARED_ATTRIBUTES.concat(coordProps);\n\n static async fromElement(\n element: HTMLElement,\n options?: Abortable,\n cssRules?: CSSRules,\n ) {\n const {\n x1 = 0,\n y1 = 0,\n x2 = 0,\n y2 = 0,\n ...parsedAttributes\n } = parseAttributes(element, this.ATTRIBUTE_NAMES, cssRules);\n return new this([x1, y1, x2, y2], parsedAttributes);\n }\n\n static fromObject<T extends TOptions<SerializedLineProps>>({\n x1,\n y1,\n x2,\n y2,\n ...object\n }: T) {\n return this._fromObject<Line>(\n { ...object, points: [x1, y1, x2, y2] },\n { extraParam: 'points' },\n );\n }\n}\n\nclassRegistry.setClass(Line);\nclassRegistry.setSVGClass(Line);\n"],"names":["coordProps","Line","FabricObject","constructor","x1","y1","x2","y2","arguments","length","undefined","options","super","_defineProperty","this","setOptions","hitStrokeWidth","hasBorders","hasControls","selectable","hoverCursor","perPixelTargetFind","strokeLineCap","_setWidthHeight","left","top","set","LEFT","TOP","_setupLineControls","controls","p1","Control","x","y","cursorStyle","actionHandler","_endpointActionHandler","bind","positionHandler","_p1PositionHandler","render","_renderEndpointControl","sizeX","sizeY","p2","_p2PositionHandler","Point","transform","getViewportTransform","ctx","save","fillStyle","strokeStyle","lineWidth","beginPath","arc","size","Math","PI","fill","stroke","restore","drawBorders","styleOverride","_useEndpointCoords","_drawLineBorders","_this$canvas","vpt","canvas","viewportTransform","setTransform","borderColor","strokeWidth","lineCap","globalAlpha","isMoving","borderOpacityWhenMoving","moveTo","lineTo","_renderControls","drawControls","getBoundingRect","effectiveStrokeWidth","padding","max","min","width","abs","height","setCoords","hitPadding","center","_findCenterFromElement","getCoords","deltaX","deltaY","sqrt","halfWidth","perpX","perpY","containsPoint","point","_this$canvas2","getActiveObject","distance","_distanceToLineSegment","px","py","pd2","u","closestX","closestY","eventData","transformData","_this$canvas4","controlKey","corner","pointer","newX","newY","shiftKey","otherControl","otherX","otherY","snapped","_snapToAngle","_this$canvas3","Gradient","_exportingSVG","coords","dirty","requestRenderAll","_updatingEndpoints","fire","target","e","fromX","fromY","toX","toY","angle","atan2","snappedRadians","round","cos","sin","skipReposition","makeBoundingBoxFromPoints","setPositionByOrigin","CENTER","_set","key","value","oldLeft","oldTop","includes","_renderDirectly","visible","opacity","origStrokeStyle","_this$stroke","isFiller","toLive","toString","_render","p","calcLinePoints","_renderStroke","toObject","propertiesToInclude","_getNonTransformedDimensions","dim","centerX","centerY","_x1","_x2","_y1","_y2","xMult","yMult","_toSVG","strokeAttr","id","strokeDashArray","join","strokeDashOffset","strokeLineJoin","strokeMiterLimit","fillRule","toSVG","reviver","originalLeft","originalTop","standardSVG","replace","fromElement","element","cssRules","parsedAttributes","parseAttributes","ATTRIBUTE_NAMES","fromObject","_ref","object","_fromObject","points","extraParam","cacheProperties","SHARED_ATTRIBUTES","concat","classRegistry","setClass","setSVGClass"],"mappings":"ogCAgBA,MAAMA,EAAa,CAAC,KAAM,KAAM,KAAM,MAa/B,MAAMC,UAKHC,EAiBRC,WAAAA,GAGE,IAFCC,EAAIC,EAAIC,EAAIC,GAAGC,UAAAC,OAAA,QAAAC,IAAAF,UAAA,GAAAA,UAAA,GAAG,CAAC,EAAG,EAAG,IAAK,GAC/BG,EAA8DH,UAAAC,OAAA,QAAAC,IAAAF,UAAA,GAAAA,UAAA,GAAG,CAAA,EAEjEI,QAAQC,wBAbwB,QAAMA,6BAEX,GAAKA,6BACL,GAAIA,wBACT,GAUtBC,KAAKC,WAAWJ,GAChBG,KAAKV,GAAKA,EACVU,KAAKR,GAAKA,EACVQ,KAAKT,GAAKA,EACVS,KAAKP,GAAKA,OAEqBG,IAA3BC,EAAQK,iBACVF,KAAKE,eAAiBL,EAAQK,gBAGhCF,KAAKG,YAAa,EAClBH,KAAKI,aAAc,EACnBJ,KAAKK,YAAa,EAClBL,KAAKM,YAAc,OACnBN,KAAKO,oBAAqB,EAC1BP,KAAKQ,cAAgB,OAErBR,KAAKS,kBACL,MAAMC,KAAEA,EAAIC,IAAEA,GAAQd,EACN,iBAATa,GAAqBV,KAAKY,IAAIC,EAAMH,GAC5B,iBAARC,GAAoBX,KAAKY,IAAIE,EAAKH,GACzCX,KAAKe,oBACP,CAEAA,kBAAAA,GACEf,KAAKgB,SAAW,CACdC,GAAI,IAAIC,EAAQ,CACdC,EAAG,EACHC,EAAG,EACHC,YAAa,OACbC,cAAetB,KAAKuB,uBAAuBC,KAAKxB,MAChDyB,gBAAiBzB,KAAK0B,mBAAmBF,KAAKxB,MAC9C2B,OAAQ3B,KAAK4B,uBAAuBJ,KAAKxB,MACzC6B,MAAO,GACPC,MAAO,KAETC,GAAI,IAAIb,EAAQ,CACdC,EAAG,EACHC,EAAG,EACHC,YAAa,OACbC,cAAetB,KAAKuB,uBAAuBC,KAAKxB,MAChDyB,gBAAiBzB,KAAKgC,mBAAmBR,KAAKxB,MAC9C2B,OAAQ3B,KAAK4B,uBAAuBJ,KAAKxB,MACzC6B,MAAO,GACPC,MAAO,KAGb,CAEAJ,kBAAAA,GACE,OAAO,IAAIO,EAAMjC,KAAKV,GAAIU,KAAKT,IAAI2C,UAAUlC,KAAKmC,uBACpD,CAEAH,kBAAAA,GACE,OAAO,IAAIC,EAAMjC,KAAKR,GAAIQ,KAAKP,IAAIyC,UAAUlC,KAAKmC,uBACpD,CAEAP,sBAAAA,CACEQ,EACA1B,EACAC,GAGAyB,EAAIC,OACJD,EAAIE,UAAY,UAChBF,EAAIG,YAAc,UAClBH,EAAII,UAAY,EAChBJ,EAAIK,YACJL,EAAIM,IAAIhC,EAAMC,EAAKgC,EAAU,EAAG,EAAIC,KAAKC,IACzCT,EAAIU,OACJV,EAAIW,SACJX,EAAIY,SACN,CAEAC,WAAAA,CAAYb,GAAwD,IAAzBc,EAAkBxD,UAAAC,OAAA,QAAAC,IAAAF,UAAA,GAAAA,UAAA,GAAG,CAAA,EAC9D,OAAIM,KAAKmD,oBACPnD,KAAKoD,iBAAiBhB,EAAKc,GACpBlD,MAEFF,MAAMmD,YAAYb,EAAKc,EAAe,CAAA,EAC/C,CAEAE,gBAAAA,CAAiBhB,GAAwD,IAAAiB,EAAA,IAAzBH,EAAkBxD,UAAAC,OAAA,QAAAC,IAAAF,UAAA,GAAAA,UAAA,GAAG,CAAA,EACnE,MAAM4D,GAAiB,QAAXD,EAAArD,KAAKuD,cAAM,IAAAF,OAAA,EAAXA,EAAaG,oBAAqB,CAAC,EAAG,EAAG,EAAG,EAAG,EAAG,GAC9DpB,EAAIC,OACJD,EAAIqB,aAAaH,EAAI,GAAIA,EAAI,GAAIA,EAAI,GAAIA,EAAI,GAAIA,EAAI,GAAIA,EAAI,IAC7DlB,EAAIG,YACFW,EAAcQ,aACd1D,KAAK0D,aACL,2BACFtB,EAAII,WAAaxC,KAAK2D,aAAe,GAAK,EAC1CvB,EAAIwB,QAAU5D,KAAKQ,eAAiB,OACpC4B,EAAIyB,YAAc7D,KAAK8D,SAAW9D,KAAK+D,wBAA0B,EACjE3B,EAAIK,YACJL,EAAI4B,OAAOhE,KAAKV,GAAIU,KAAKT,IACzB6C,EAAI6B,OAAOjE,KAAKR,GAAIQ,KAAKP,IACzB2C,EAAIW,SACJX,EAAIY,SACN,CAEAkB,eAAAA,CAAgB9B,GAAwD,IAAzBc,EAAkBxD,UAAAC,OAAA,QAAAC,IAAAF,UAAA,GAAAA,UAAA,GAAG,CAAA,EAClE0C,EAAIC,OACJD,EAAIyB,YAAc7D,KAAK8D,SAAW9D,KAAK+D,wBAA0B,EACjE/D,KAAKmE,aAAa/B,EAAKc,GACvBd,EAAIY,SACN,CAEAoB,eAAAA,GACE,GAAIpE,KAAKmD,mBAAoB,CAC3B,MAAM7D,GAAEA,EAAEC,GAAEA,EAAEC,GAAEA,EAAEC,GAAEA,GAAOO,KACrBqE,EACoB,SAAxBrE,KAAKE,eAA4BF,KAAK2D,YAAc3D,KAAKE,eACrDoE,EAAU1B,KAAK2B,IAAIF,EAAuB,EAAI,EAAG,IACvD,MAAO,CACL3D,KAAMkC,KAAK4B,IAAIlF,EAAIE,GAAM8E,EACzB3D,IAAKiC,KAAK4B,IAAIjF,EAAIE,GAAM6E,EACxBG,MAAO7B,KAAK8B,IAAIlF,EAAKF,GAAgB,EAAVgF,GAAyB,EAAVA,EAC1CK,OAAQ/B,KAAK8B,IAAIjF,EAAKF,GAAgB,EAAV+E,GAAyB,EAAVA,EAE/C,CACA,OAAOxE,MAAMsE,iBACf,CAEAQ,SAAAA,GACE,GAAI5E,KAAKmD,mBAAoB,CAE3B,MAAMkB,EACoB,SAAxBrE,KAAKE,eAA4BF,KAAK2D,YAAc3D,KAAKE,eACrD2E,EAAajC,KAAK2B,IAAIF,EAAuB,EAAI,EAAG,IAK1D,GAJArE,KAAKyE,MAAQ7B,KAAK8B,IAAI1E,KAAKR,GAAKQ,KAAKV,IAAmB,EAAbuF,EAC3C7E,KAAK2E,OAAS/B,KAAK8B,IAAI1E,KAAKP,GAAKO,KAAKT,IAAmB,EAAbsF,EAG1B,IAAd7E,KAAKU,MAA2B,IAAbV,KAAKW,IAAW,CACrC,MAAMmE,EAAS9E,KAAK+E,yBACpB/E,KAAKU,KAAOoE,EAAO3D,EACnBnB,KAAKW,IAAMmE,EAAO1D,CACpB,CACF,CACAtB,MAAM8E,WACR,CAEAI,SAAAA,GACE,GAAIhF,KAAKmD,mBAAoB,CAC3B,MAAM8B,EAASjF,KAAKR,GAAKQ,KAAKV,GACxB4F,EAASlF,KAAKP,GAAKO,KAAKT,GACxBI,EAASiD,KAAKuC,KAAKF,EAASA,EAASC,EAASA,GAEpD,GAAe,IAAXvF,EACF,OAAOG,MAAMkF,YAGf,MAAMX,EACoB,SAAxBrE,KAAKE,eAA4BF,KAAK2D,YAAc3D,KAAKE,eACrDkF,EAAYxC,KAAK2B,IAAIF,EAAuB,EAAI,EAAG,GAGnDgB,GAASH,EAASvF,EAClB2F,EAAQL,EAAStF,EAGvB,MAAO,CACL,IAAIsC,EAAMjC,KAAKV,GAAK+F,EAAQD,EAAWpF,KAAKT,GAAK+F,EAAQF,GACzD,IAAInD,EAAMjC,KAAKR,GAAK6F,EAAQD,EAAWpF,KAAKP,GAAK6F,EAAQF,GACzD,IAAInD,EAAMjC,KAAKR,GAAK6F,EAAQD,EAAWpF,KAAKP,GAAK6F,EAAQF,GACzD,IAAInD,EAAMjC,KAAKV,GAAK+F,EAAQD,EAAWpF,KAAKT,GAAK+F,EAAQF,GAE7D,CACA,OAAOtF,MAAMkF,WACf,CAEAO,aAAAA,CAAcC,GACZ,GAAIxF,KAAKmD,mBAAoB,CAAA,IAAAsC,EAC3B,IAAe,QAAXA,EAAAzF,KAAKuD,cAAM,IAAAkC,OAAA,EAAXA,EAAaC,qBAAsB1F,KACrC,OAAOF,MAAMyF,cAAcC,GAE7B,MAAMG,EAAW3F,KAAK4F,uBAAuBJ,EAAMrE,EAAGqE,EAAMpE,GACtDiD,EACoB,SAAxBrE,KAAKE,eACDF,KAAK2D,YACL3D,KAAKE,gBAAkB,EAG7B,OAAOyF,GADW/C,KAAK2B,IAAIF,EAAuB,EAAI,EAAG,EAE3D,CACA,OAAOvE,MAAMyF,cAAcC,EAC7B,CAEAI,sBAAAA,CAAuBC,EAAYC,GACjC,MAAMxG,EAAKU,KAAKV,GACdC,EAAKS,KAAKT,GACVC,EAAKQ,KAAKR,GACVC,EAAKO,KAAKP,GAENsG,GAAOzG,EAAKE,IAAOF,EAAKE,IAAOD,EAAKE,IAAOF,EAAKE,GACtD,GAAY,IAARsG,EACF,OAAOnD,KAAKuC,MAAMU,EAAKvG,IAAOuG,EAAKvG,IAAOwG,EAAKvG,IAAOuG,EAAKvG,IAG7D,MAAMyG,IAAMH,EAAKvG,IAAOE,EAAKF,IAAOwG,EAAKvG,IAAOE,EAAKF,IAAOwG,EAE5D,IAAIE,EAAkBC,EAYtB,OAXIF,EAAI,GACNC,EAAW3G,EACX4G,EAAW3G,GACFyG,EAAI,GACbC,EAAWzG,EACX0G,EAAWzG,IAEXwG,EAAW3G,EAAK0G,GAAKxG,EAAKF,GAC1B4G,EAAW3G,EAAKyG,GAAKvG,EAAKF,IAGrBqD,KAAKuC,MACTU,EAAKI,IAAaJ,EAAKI,IAAaH,EAAKI,IAAaJ,EAAKI,GAEhE,CAEA3E,sBAAAA,CACE4E,EACAC,EACAjF,EACAC,GACA,IAAAiF,EACA,MAAMC,EAAaF,EAAcG,OAC3BC,EAAU,IAAIvE,EAAMd,EAAGC,GAC7B,IAAIqF,EAAOD,EAAQrF,EACfuF,EAAOF,EAAQpF,EAEnB,GAAI+E,EAAUQ,SAAU,CACtB,MAAMC,EAA8B,OAAfN,EAAsB,KAAO,KAC5CO,EAAS7G,KAAsB,OAAjB4G,EAAwB,KAAO,MAC7CE,EAAS9G,KAAsB,OAAjB4G,EAAwB,KAAO,MAC7CG,EAAU/G,KAAKgH,aAAaH,EAAQC,EAAQL,EAAMC,GACxDD,EAAOM,EAAQ5F,EACfuF,EAAOK,EAAQ3F,CACjB,CAE6B,IAAA6F,EAA7B,OAAIjH,KAAKmD,oBACY,OAAfmD,GACFtG,KAAKV,GAAKmH,EACVzG,KAAKT,GAAKmH,GACc,OAAfJ,IACTtG,KAAKR,GAAKiH,EACVzG,KAAKP,GAAKiH,GAIR1G,KAAK+C,kBAAkBmE,IAAalH,KAAKmH,gBAC3CnH,KAAK+C,OAAOqE,OAAO9H,GAAKU,KAAKV,GAC7BU,KAAK+C,OAAOqE,OAAO7H,GAAKS,KAAKT,GAC7BS,KAAK+C,OAAOqE,OAAO5H,GAAKQ,KAAKR,GAC7BQ,KAAK+C,OAAOqE,OAAO3H,GAAKO,KAAKP,IAG/BO,KAAKqH,OAAQ,EACbrH,KAAK4E,YACM,QAAXqC,EAAAjH,KAAKuD,cAAM,IAAA0D,GAAXA,EAAaK,oBACN,IAITtH,KAAKuH,oBAAqB,EACP,OAAfjB,GACFtG,KAAKV,GAAKmH,EACVzG,KAAKT,GAAKmH,GACc,OAAfJ,IACTtG,KAAKR,GAAKiH,EACVzG,KAAKP,GAAKiH,GAEZ1G,KAAKS,kBACLT,KAAKqH,OAAQ,EACbrH,KAAKuH,oBAAqB,EACf,QAAXlB,EAAArG,KAAKuD,cAAM,IAAA8C,GAAXA,EAAaiB,mBACbtH,KAAKwH,KAAK,WAAY,CACpBtF,UAAWkE,EACXqB,OAAQzH,KACR0H,EAAGvB,KAEE,EACT,CAEAa,YAAAA,CACEW,EACAC,EACAC,EACAC,GAEA,MAAM7C,EAAS4C,EAAMF,EACfzC,EAAS4C,EAAMF,EACfjC,EAAW/C,KAAKuC,KAAKF,EAASA,EAASC,EAASA,GACtD,GAAiB,IAAbS,EAAgB,MAAO,CAAExE,EAAG0G,EAAKzG,EAAG0G,GACxC,IAAIC,EAAQnF,KAAKoF,MAAM9C,EAAQD,IAAW,IAAMrC,KAAKC,IACrD,MAEMoF,EAFgB,GACDrF,KAAKsF,MAAMH,EADV,KAEiBnF,KAAKC,GAAK,KACjD,MAAO,CACL1B,EAAGwG,EAAQ/E,KAAKuF,IAAIF,GAAkBtC,EACtCvE,EAAGwG,EAAQhF,KAAKwF,IAAIH,GAAkBtC,EAE1C,CAEAlF,eAAAA,GAAwC,IAAxB4H,EAAc3I,UAAAC,OAAA,QAAAC,IAAAF,UAAA,IAAAA,UAAA,GAG5B,GAFAM,KAAKyE,MAAQ7B,KAAK8B,IAAI1E,KAAKR,GAAKQ,KAAKV,KAAO,EAC5CU,KAAK2E,OAAS/B,KAAK8B,IAAI1E,KAAKP,GAAKO,KAAKT,KAAO,GACxC8I,IAAmBrI,KAAKuH,mBAAoB,CAC/C,MAAM7G,KAAEA,EAAIC,IAAEA,EAAG8D,MAAEA,EAAKE,OAAEA,GAAW2D,EAA0B,CAC7D,CAAEnH,EAAGnB,KAAKV,GAAI8B,EAAGpB,KAAKT,IACtB,CAAE4B,EAAGnB,KAAKR,GAAI4B,EAAGpB,KAAKP,MAExBO,KAAKuI,oBACH,IAAItG,EAAMvB,EAAO+D,EAAQ,EAAG9D,EAAMgE,EAAS,GAC3C6D,EACAA,EAEJ,CACF,CAEAC,IAAAA,CAAKC,EAAaC,GAChB,MAAMC,EAAU5I,KAAKU,KACfmI,EAAS7I,KAAKW,IAcpB,GAbAb,MAAM2I,KAAKC,EAAKC,GACZzJ,EAAW4J,SAASJ,KACtB1I,KAAKS,kBACLT,KAAKqH,OAAQ,EAGTrH,KAAK+C,kBAAkBmE,IAAalH,KAAKmH,gBAC3CnH,KAAK+C,OAAOqE,OAAO9H,GAAKU,KAAKV,GAC7BU,KAAK+C,OAAOqE,OAAO7H,GAAKS,KAAKT,GAC7BS,KAAK+C,OAAOqE,OAAO5H,GAAKQ,KAAKR,GAC7BQ,KAAK+C,OAAOqE,OAAO3H,GAAKO,KAAKP,MAItB,SAARiJ,GAA0B,QAARA,IACnB1I,KAAKuD,SACJvD,KAAKuH,mBACN,CACA,MAAMtC,EAASjF,KAAKU,KAAOkI,EACrB1D,EAASlF,KAAKW,IAAMkI,EACX,IAAX5D,GAA2B,IAAXC,IAClBlF,KAAKuH,oBAAqB,EAC1BvH,KAAKV,IAAM2F,EACXjF,KAAKT,IAAM2F,EACXlF,KAAKR,IAAMyF,EACXjF,KAAKP,IAAMyF,EAGPlF,KAAK+C,kBAAkBmE,IACzBlH,KAAK+C,OAAOqE,OAAO9H,GAAKU,KAAKV,GAC7BU,KAAK+C,OAAOqE,OAAO7H,GAAKS,KAAKT,GAC7BS,KAAK+C,OAAOqE,OAAO5H,GAAKQ,KAAKR,GAC7BQ,KAAK+C,OAAOqE,OAAO3H,GAAKO,KAAKP,IAG/BO,KAAKuH,oBAAqB,EAE9B,CACA,OAAOvH,IACT,CAEA2B,MAAAA,CAAOS,GACDpC,KAAKmD,mBACPnD,KAAK+I,gBAAgB3G,GAGvBtC,MAAM6B,OAAOS,EACf,CAEA2G,eAAAA,CAAgB3G,GACd,IAAKpC,KAAKgJ,QAAS,OACnB5G,EAAIC,OACJD,EAAIyB,YAAc7D,KAAKiJ,QACvB7G,EAAII,UAAYxC,KAAK2D,YACrBvB,EAAIwB,QAAU5D,KAAKQ,eAAiB,OACpC4B,EAAIK,YACJL,EAAI4B,OAAOhE,KAAKV,GAAIU,KAAKT,IACzB6C,EAAI6B,OAAOjE,KAAKR,GAAIQ,KAAKP,IAEzB,MAAMyJ,EAAkB9G,EAAIG,YAGrB,IAAA4G,EAFHC,EAASpJ,KAAK+C,QAChBX,EAAIG,YAAcvC,KAAK+C,OAAOsG,OAAOjH,GAErCA,EAAIG,aAAyB,QAAX4G,OAAKpG,kBAAMoG,SAAXA,EAAaG,aAAc,OAG/ClH,EAAIW,SACJX,EAAIG,YAAc2G,EAClB9G,EAAIY,SACN,CAEAuG,OAAAA,CAAQnH,GACN,GAAIpC,KAAKmD,mBAAoB,OAC7Bf,EAAIK,YACJ,MAAM+G,EAAIxJ,KAAKyJ,iBACfrH,EAAI4B,OAAOwF,EAAElK,GAAIkK,EAAEjK,IACnB6C,EAAI6B,OAAOuF,EAAEhK,GAAIgK,EAAE/J,IACnB2C,EAAII,UAAYxC,KAAK2D,YACrB,MAAMuF,EAAkB9G,EAAIG,YACxB6G,EAASpJ,KAAK+C,UAChBX,EAAIG,YAAcvC,KAAK+C,OAAOsG,OAAOjH,IAEvCpC,KAAK+C,QAAU/C,KAAK0J,cAActH,GAClCA,EAAIG,YAAc2G,CACpB,CAEAnE,sBAAAA,GACE,OAAO,IAAI9C,GAAOjC,KAAKV,GAAKU,KAAKR,IAAM,GAAIQ,KAAKT,GAAKS,KAAKP,IAAM,EAClE,CAEAkK,QAAAA,GAGsD,IAApDC,EAAwBlK,UAAAC,OAAA,QAAAC,IAAAF,UAAA,GAAAA,UAAA,GAAG,GAC3B,OAAIM,KAAKmD,mBACA,IACFrD,MAAM6J,SAASC,GAClBtK,GAAIU,KAAKV,GACTC,GAAIS,KAAKT,GACTC,GAAIQ,KAAKR,GACTC,GAAIO,KAAKP,IAGN,IACFK,MAAM6J,SAASC,MACf5J,KAAKyJ,iBAEZ,CAEAI,4BAAAA,GACE,MAAMC,EAAMhK,MAAM+J,+BAKlB,MAJ2B,UAAvB7J,KAAKQ,gBACPsJ,EAAI3I,GAAKnB,KAAK2D,YACdmG,EAAI1I,GAAKpB,KAAK2D,aAETmG,CACT,CAEAL,cAAAA,GACE,GAAIzJ,KAAKuH,mBAAoB,CAC3B,MAAMwC,GAAW/J,KAAKV,GAAKU,KAAKR,IAAM,EAChCwK,GAAWhK,KAAKT,GAAKS,KAAKP,IAAM,EACtC,MAAO,CACLH,GAAIU,KAAKV,GAAKyK,EACdxK,GAAIS,KAAKT,GAAKyK,EACdxK,GAAIQ,KAAKR,GAAKuK,EACdtK,GAAIO,KAAKP,GAAKuK,EAElB,CACA,MAAQ1K,GAAI2K,EAAKzK,GAAI0K,EAAK3K,GAAI4K,EAAK1K,GAAI2K,EAAG3F,MAAEA,EAAKE,OAAEA,GAAW3E,KACxDqK,EAAQJ,GAAOC,GAAM,EAAK,EAC1BI,EAAQH,GAAOC,GAAM,EAAK,EAChC,MAAO,CACL9K,GAAK+K,EAAQ5F,EAAS,EACtBlF,GAAK+K,EAAQ3F,EAAU,EACvBnF,GAAK6K,GAAS5F,EAAS,EACvBhF,GAAK6K,GAAS3F,EAAU,EAE5B,CAEA4F,MAAAA,GACE,GAAIvK,KAAKmD,mBAAoB,CAG3B,IAAIqH,EAAa,GAQjB,OALEA,EAFExK,KAAK+C,kBAAkBmE,EAEZ,gBAAgBlH,KAAK+C,OAAO0H,OAE5B,WAAWzK,KAAK+C,QAAU,UAGlC,CACL,SAASyH,mBAA4BxK,KAAK2D,gCAAgC3D,KAAKQ,kBAC/E,qBAAqBR,KAAK0K,gBAAkB1K,KAAK0K,gBAAgBC,KAAK,KAAO,WAC7E,sBAAsB3K,KAAK4K,sCAAsC5K,KAAK6K,mBACtE,sBAAsB7K,KAAK8K,2BAA2B9K,KAAK8C,MAAQ,WACnE,cAAc9C,KAAK+K,sBAAsB/K,KAAKiJ,YAC9C,OAAOjJ,KAAKV,WAAWU,KAAKT,WAAWS,KAAKR,WAAWQ,KAAKP,WAEhE,CAAO,CAEL,MAAMH,GAAEA,EAAEE,GAAEA,EAAED,GAAEA,EAAEE,GAAEA,GAAOO,KAAKyJ,iBAChC,MAAO,CACL,SACA,eACA,OAAOnK,UAAWC,UAAWC,UAAWC,UAE5C,CACF,CAEAuL,KAAAA,CAAMC,GACJ,GAAIjL,KAAKmD,mBAAoB,CAG3B,MAAM+H,EAAelL,KAAKU,KACpByK,EAAcnL,KAAKW,IAGzBX,KAAKU,MAAQV,KAAKV,GAAKU,KAAKR,IAAM,EAClCQ,KAAKW,KAAOX,KAAKT,GAAKS,KAAKP,IAAM,EAGjC,MAAM2L,EAActL,MAAMkL,MAAMC,GAGhCjL,KAAKU,KAAOwK,EACZlL,KAAKW,IAAMwK,EAYX,OARiBC,EACdC,QAAQ,8BAA+B,IACvCA,QAAQ,SAAU,IAClBA,QAAQ,cAAe,OAAOrL,KAAKV,OACnC+L,QAAQ,cAAe,OAAOrL,KAAKT,OACnC8L,QAAQ,cAAe,OAAOrL,KAAKR,OACnC6L,QAAQ,cAAe,OAAOrL,KAAKP,MAGxC,CAEA,OAAOK,MAAMkL,MAAMC,EACrB,CAIA,wBAAaK,CACXC,EACA1L,EACA2L,GAEA,MAAMlM,GACJA,EAAK,EAACC,GACNA,EAAK,EAACC,GACNA,EAAK,EAACC,GACNA,EAAK,KACFgM,GACDC,EAAgBH,EAASvL,KAAK2L,gBAAiBH,GACnD,OAAO,IAAIxL,KAAK,CAACV,EAAIC,EAAIC,EAAIC,GAAKgM,EACpC,CAEA,iBAAOG,CAAUC,GAMX,IANqDvM,GACzDA,EAAEC,GACFA,EAAEC,GACFA,EAAEC,GACFA,KACGqM,GACDD,EACF,OAAO7L,KAAK+L,YACV,IAAKD,EAAQE,OAAQ,CAAC1M,EAAIC,EAAIC,EAAIC,IAClC,CAAEwM,WAAY,UAElB,EACDlM,EAtkBYZ,EAAI,OAmBD,QAAMY,EAnBTZ,EAAI,kBAoBU,IAAI+M,KAAoBhN,IAAWa,EApBjDZ,EAAI,kBAyiBUgN,EAAkBC,OAAOlN,IA+BpDmN,EAAcC,SAASnN,GACvBkN,EAAcE,YAAYpN"}
|
package/dist/src/shapes/Line.mjs
CHANGED
|
@@ -15,6 +15,7 @@ import '../cache.mjs';
|
|
|
15
15
|
import '../parser/constants.mjs';
|
|
16
16
|
import '../util/animation/AnimationRegistry.mjs';
|
|
17
17
|
import { Control } from '../controls/Control.mjs';
|
|
18
|
+
import { Gradient } from '../gradient/Gradient.mjs';
|
|
18
19
|
import { cacheProperties } from './Object/defaultValues.mjs';
|
|
19
20
|
|
|
20
21
|
const coordProps = ['x1', 'x2', 'y1', 'y2'];
|
|
@@ -26,6 +27,7 @@ class Line extends FabricObject {
|
|
|
26
27
|
_defineProperty(this, "hitStrokeWidth", 'auto');
|
|
27
28
|
_defineProperty(this, "_updatingEndpoints", false);
|
|
28
29
|
_defineProperty(this, "_useEndpointCoords", true);
|
|
30
|
+
_defineProperty(this, "_exportingSVG", false);
|
|
29
31
|
this.setOptions(options);
|
|
30
32
|
this.x1 = x1;
|
|
31
33
|
this.x2 = x2;
|
|
@@ -143,16 +145,18 @@ class Line extends FabricObject {
|
|
|
143
145
|
}
|
|
144
146
|
setCoords() {
|
|
145
147
|
if (this._useEndpointCoords) {
|
|
146
|
-
// Set the object's center to the geometric center of the line
|
|
147
|
-
const center = this._findCenterFromElement();
|
|
148
|
-
this.left = center.x;
|
|
149
|
-
this.top = center.y;
|
|
150
|
-
|
|
151
148
|
// Set width and height for hit detection and bounding box
|
|
152
149
|
const effectiveStrokeWidth = this.hitStrokeWidth === 'auto' ? this.strokeWidth : this.hitStrokeWidth;
|
|
153
150
|
const hitPadding = Math.max(effectiveStrokeWidth / 2 + 5, 10);
|
|
154
151
|
this.width = Math.abs(this.x2 - this.x1) + hitPadding * 2;
|
|
155
152
|
this.height = Math.abs(this.y2 - this.y1) + hitPadding * 2;
|
|
153
|
+
|
|
154
|
+
// Only update left/top if they haven't been explicitly set (e.g., during loading)
|
|
155
|
+
if (this.left === 0 && this.top === 0) {
|
|
156
|
+
const center = this._findCenterFromElement();
|
|
157
|
+
this.left = center.x;
|
|
158
|
+
this.top = center.y;
|
|
159
|
+
}
|
|
156
160
|
}
|
|
157
161
|
super.setCoords();
|
|
158
162
|
}
|
|
@@ -235,6 +239,14 @@ class Line extends FabricObject {
|
|
|
235
239
|
this.x2 = newX;
|
|
236
240
|
this.y2 = newY;
|
|
237
241
|
}
|
|
242
|
+
|
|
243
|
+
// Update gradient coordinates if stroke is a gradient (but not during SVG export)
|
|
244
|
+
if (this.stroke instanceof Gradient && !this._exportingSVG) {
|
|
245
|
+
this.stroke.coords.x1 = this.x1;
|
|
246
|
+
this.stroke.coords.y1 = this.y1;
|
|
247
|
+
this.stroke.coords.x2 = this.x2;
|
|
248
|
+
this.stroke.coords.y2 = this.y2;
|
|
249
|
+
}
|
|
238
250
|
this.dirty = true;
|
|
239
251
|
this.setCoords();
|
|
240
252
|
(_this$canvas3 = this.canvas) === null || _this$canvas3 === void 0 || _this$canvas3.requestRenderAll();
|
|
@@ -305,6 +317,14 @@ class Line extends FabricObject {
|
|
|
305
317
|
if (coordProps.includes(key)) {
|
|
306
318
|
this._setWidthHeight();
|
|
307
319
|
this.dirty = true;
|
|
320
|
+
|
|
321
|
+
// Update gradient coordinates if stroke is a gradient (but not during SVG export)
|
|
322
|
+
if (this.stroke instanceof Gradient && !this._exportingSVG) {
|
|
323
|
+
this.stroke.coords.x1 = this.x1;
|
|
324
|
+
this.stroke.coords.y1 = this.y1;
|
|
325
|
+
this.stroke.coords.x2 = this.x2;
|
|
326
|
+
this.stroke.coords.y2 = this.y2;
|
|
327
|
+
}
|
|
308
328
|
}
|
|
309
329
|
if ((key === 'left' || key === 'top') && this.canvas && !this._updatingEndpoints) {
|
|
310
330
|
const deltaX = this.left - oldLeft;
|
|
@@ -315,6 +335,14 @@ class Line extends FabricObject {
|
|
|
315
335
|
this.y1 += deltaY;
|
|
316
336
|
this.x2 += deltaX;
|
|
317
337
|
this.y2 += deltaY;
|
|
338
|
+
|
|
339
|
+
// Update gradient coordinates if stroke is a gradient
|
|
340
|
+
if (this.stroke instanceof Gradient) {
|
|
341
|
+
this.stroke.coords.x1 = this.x1;
|
|
342
|
+
this.stroke.coords.y1 = this.y1;
|
|
343
|
+
this.stroke.coords.x2 = this.x2;
|
|
344
|
+
this.stroke.coords.y2 = this.y2;
|
|
345
|
+
}
|
|
318
346
|
this._updatingEndpoints = false;
|
|
319
347
|
}
|
|
320
348
|
}
|
|
@@ -328,17 +356,23 @@ class Line extends FabricObject {
|
|
|
328
356
|
super.render(ctx);
|
|
329
357
|
}
|
|
330
358
|
_renderDirectly(ctx) {
|
|
331
|
-
var _this$stroke;
|
|
332
359
|
if (!this.visible) return;
|
|
333
360
|
ctx.save();
|
|
334
361
|
ctx.globalAlpha = this.opacity;
|
|
335
|
-
ctx.strokeStyle = ((_this$stroke = this.stroke) === null || _this$stroke === void 0 ? void 0 : _this$stroke.toString()) || '#000';
|
|
336
362
|
ctx.lineWidth = this.strokeWidth;
|
|
337
363
|
ctx.lineCap = this.strokeLineCap || 'butt';
|
|
338
364
|
ctx.beginPath();
|
|
339
365
|
ctx.moveTo(this.x1, this.y1);
|
|
340
366
|
ctx.lineTo(this.x2, this.y2);
|
|
367
|
+
const origStrokeStyle = ctx.strokeStyle;
|
|
368
|
+
if (isFiller(this.stroke)) {
|
|
369
|
+
ctx.strokeStyle = this.stroke.toLive(ctx);
|
|
370
|
+
} else {
|
|
371
|
+
var _this$stroke;
|
|
372
|
+
ctx.strokeStyle = ((_this$stroke = this.stroke) === null || _this$stroke === void 0 ? void 0 : _this$stroke.toString()) || '#000';
|
|
373
|
+
}
|
|
341
374
|
ctx.stroke();
|
|
375
|
+
ctx.strokeStyle = origStrokeStyle;
|
|
342
376
|
ctx.restore();
|
|
343
377
|
}
|
|
344
378
|
_render(ctx) {
|
|
@@ -360,6 +394,15 @@ class Line extends FabricObject {
|
|
|
360
394
|
}
|
|
361
395
|
toObject() {
|
|
362
396
|
let propertiesToInclude = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
|
|
397
|
+
if (this._useEndpointCoords) {
|
|
398
|
+
return {
|
|
399
|
+
...super.toObject(propertiesToInclude),
|
|
400
|
+
x1: this.x1,
|
|
401
|
+
y1: this.y1,
|
|
402
|
+
x2: this.x2,
|
|
403
|
+
y2: this.y2
|
|
404
|
+
};
|
|
405
|
+
}
|
|
363
406
|
return {
|
|
364
407
|
...super.toObject(propertiesToInclude),
|
|
365
408
|
...this.calcLinePoints()
|
|
@@ -404,7 +447,15 @@ class Line extends FabricObject {
|
|
|
404
447
|
_toSVG() {
|
|
405
448
|
if (this._useEndpointCoords) {
|
|
406
449
|
// Use absolute coordinates to bypass all Fabric.js transforms
|
|
407
|
-
|
|
450
|
+
// Handle gradients manually for proper SVG export
|
|
451
|
+
let strokeAttr = '';
|
|
452
|
+
if (this.stroke instanceof Gradient) {
|
|
453
|
+
// Let Fabric.js handle gradient definition, but we'll use the reference
|
|
454
|
+
strokeAttr = `stroke="url(#${this.stroke.id})"`;
|
|
455
|
+
} else {
|
|
456
|
+
strokeAttr = `stroke="${this.stroke || 'none'}"`;
|
|
457
|
+
}
|
|
458
|
+
return [`<line ${strokeAttr} stroke-width="${this.strokeWidth}" stroke-linecap="${this.strokeLineCap}" `, `stroke-dasharray="${this.strokeDashArray ? this.strokeDashArray.join(' ') : 'none'}" `, `stroke-dashoffset="${this.strokeDashOffset}" stroke-linejoin="${this.strokeLineJoin}" `, `stroke-miterlimit="${this.strokeMiterLimit}" fill="${this.fill || 'none'}" `, `fill-rule="${this.fillRule}" opacity="${this.opacity}" `, `x1="${this.x1}" y1="${this.y1}" x2="${this.x2}" y2="${this.y2}" />\n`];
|
|
408
459
|
} else {
|
|
409
460
|
// Use standard calcLinePoints for legacy mode
|
|
410
461
|
const {
|
|
@@ -418,9 +469,26 @@ class Line extends FabricObject {
|
|
|
418
469
|
}
|
|
419
470
|
toSVG(reviver) {
|
|
420
471
|
if (this._useEndpointCoords) {
|
|
421
|
-
//
|
|
422
|
-
|
|
423
|
-
|
|
472
|
+
// For endpoint coords, we need to bypass transforms but still allow gradients
|
|
473
|
+
// Let's temporarily disable transforms during SVG generation
|
|
474
|
+
const originalLeft = this.left;
|
|
475
|
+
const originalTop = this.top;
|
|
476
|
+
|
|
477
|
+
// Set position to center of line for gradient calculation
|
|
478
|
+
this.left = (this.x1 + this.x2) / 2;
|
|
479
|
+
this.top = (this.y1 + this.y2) / 2;
|
|
480
|
+
|
|
481
|
+
// Get the SVG with standard system (for gradient handling)
|
|
482
|
+
const standardSVG = super.toSVG(reviver);
|
|
483
|
+
|
|
484
|
+
// Restore original position
|
|
485
|
+
this.left = originalLeft;
|
|
486
|
+
this.top = originalTop;
|
|
487
|
+
|
|
488
|
+
// Extract gradient definition and clean up the line element
|
|
489
|
+
// Remove the transform wrapper and update coordinates
|
|
490
|
+
const cleanSVG = standardSVG.replace(/<g transform="[^"]*"[^>]*>/g, '').replace(/<\/g>/g, '').replace(/x1="[^"]*"/g, `x1="${this.x1}"`).replace(/y1="[^"]*"/g, `y1="${this.y1}"`).replace(/x2="[^"]*"/g, `x2="${this.x2}"`).replace(/y2="[^"]*"/g, `y2="${this.y2}"`);
|
|
491
|
+
return cleanSVG;
|
|
424
492
|
}
|
|
425
493
|
// Use default behavior for legacy mode
|
|
426
494
|
return super.toSVG(reviver);
|