').parent().attr({id:u+"_"+l,title:l})[0]}))},y=function _loadIcons(){l("#shape_buttons").empty().append(_.buttons)},l=t.$,n=t.importLocale,x.next=6,n();case 6:return r=x.sent,a=e.canvas,o=a.getRootElem(),c={},i=r.categories,u="shapelib",m={},_=(s={basic:{data:{heart:"m150,73c61,-175 300,0 0,225c-300,-225 -61,-400 0,-225z",frame:"m0,0l300,0l0,300l-300,0zm35,-265l0,230l230,0l0,-230z",donut:"m1,150l0,0c0,-82.29042 66.70958,-149 149,-149l0,0c39.51724,0 77.41599,15.69816 105.35889,43.64108c27.94293,27.94293 43.64111,65.84165 43.64111,105.35892l0,0c0,82.29041 -66.70958,149 -149,149l0,0c-82.29041,0 -149,-66.70959 -149,-149zm74.5,0l0,0c0,41.1452 33.35481,74.5 74.5,74.5c41.14522,0 74.5,-33.3548 74.5,-74.5c0,-41.1452 -33.3548,-74.5 -74.5,-74.5l0,0c-41.14519,0 -74.5,33.35481 -74.5,74.5z",triangle:"m1,280.375l149,-260.75l149,260.75z",right_triangle:"m1,299l0,-298l298,298z",diamond:"m1,150l149,-149l149,149l-149,149l-149,-149z",pentagon:"m1.00035,116.97758l148.99963,-108.4053l148.99998,108.4053l-56.91267,175.4042l-184.1741,0l-56.91284,-175.4042z",hexagon:"m1,149.99944l63.85715,-127.71428l170.28572,0l63.85713,127.71428l-63.85713,127.71428l-170.28572,0l-63.85715,-127.71428z",septagon1:"m0.99917,191.06511l29.51249,-127.7108l119.48833,-56.83673l119.48836,56.83673l29.51303,127.7108l-82.69087,102.41679l-132.62103,0l-82.69031,-102.41679z",heptagon:"m1,88.28171l87.28172,-87.28171l123.43653,0l87.28172,87.28171l0,123.43654l-87.28172,87.28172l-123.43653,0l-87.28172,-87.28172l0,-123.43654z",decagon:"m1,150.00093l28.45646,-88.40318l74.49956,-54.63682l92.08794,0l74.50002,54.63682l28.45599,88.40318l-28.45599,88.40318l-74.50002,54.63681l-92.08794,0l-74.49956,-54.63681l-28.45646,-88.40318z",dodecagon:"m1,110.07421l39.92579,-69.14842l69.14842,-39.92579l79.85159,0l69.14842,39.92579l39.92578,69.14842l0,79.85159l-39.92578,69.14842l-69.14842,39.92578l-79.85159,0l-69.14842,-39.92578l-39.92579,-69.14842l0,-79.85159z",star_points_5:"m1,116.58409l113.82668,0l35.17332,-108.13487l35.17334,108.13487l113.82666,0l-92.08755,66.83026l35.17514,108.13487l-92.08759,-66.83208l-92.08757,66.83208l35.17515,-108.13487l-92.08758,-66.83026z",trapezoid:"m1,299l55.875,-298l186.25001,0l55.87498,298z",arrow_up:"m1.49805,149.64304l148.50121,-148.00241l148.50121,148.00241l-74.25061,0l0,148.71457l-148.5012,0l0,-148.71457z",vertical_scrool:"m37.375,261.625l0,-242.9375l0,0c0,-10.32083 8.36669,-18.6875 18.6875,-18.6875l224.25,0c10.32083,0 18.6875,8.36667 18.6875,18.6875c0,10.32081 -8.36667,18.6875 -18.6875,18.6875l-18.6875,0l0,242.9375c0,10.32083 -8.36668,18.6875 -18.6875,18.6875l-224.25,0l0,0c-10.32083,0 -18.6875,-8.36667 -18.6875,-18.6875c0,-10.32083 8.36667,-18.6875 18.6875,-18.6875zm37.375,-261.625l0,0c10.32081,0 18.6875,8.36667 18.6875,18.6875c0,10.32081 -8.36669,18.6875 -18.6875,18.6875c-5.1604,0 -9.34375,-4.18335 -9.34375,-9.34375c0,-5.16041 4.18335,-9.34375 9.34375,-9.34375l18.6875,0m186.875,18.6875l-205.5625,0m-37.375,224.25l0,0c5.1604,0 9.34375,4.18335 9.34375,9.34375c0,5.1604 -4.18335,9.34375 -9.34375,9.34375l18.6875,0m-18.6875,18.6875l0,0c10.32081,0 18.6875,-8.36667 18.6875,-18.6875l0,-18.6875",smiley:"m68.49886,214.78838q81.06408,55.67332 161.93891,0m-144.36983,-109.9558c0,-8.60432 6.97517,-15.57949 15.57948,-15.57949c8.60431,0 15.57948,6.97517 15.57948,15.57949c0,8.60431 -6.97517,15.57947 -15.57948,15.57947c-8.60431,0 -15.57948,-6.97516 -15.57948,-15.57947m95.83109,0c0,-8.60432 6.97517,-15.57949 15.57948,-15.57949c8.60431,0 15.57947,6.97517 15.57947,15.57949c0,8.60431 -6.97516,15.57947 -15.57947,15.57947c-8.60429,0 -15.57948,-6.97516 -15.57948,-15.57947m-181.89903,44.73038l0,0c0,-82.60133 66.96162,-149.56296 149.56296,-149.56296c82.60135,0 149.56296,66.96162 149.56296,149.56296c0,82.60135 -66.96161,149.56296 -149.56296,149.56296c-82.60133,0 -149.56296,-66.96161 -149.56296,-149.56296zm0,0l0,0c0,-82.60133 66.96162,-149.56296 149.56296,-149.56296c82.60135,0 149.56296,66.96162 149.56296,149.56296c0,82.60135 -66.96161,149.56296 -149.56296,149.56296c-82.60133,0 -149.56296,-66.96161 -149.56296,-149.56296z",left_braket:"m174.24565,298.5c-13.39009,0 -24.24489,-1.80908 -24.24489,-4.04065l0,-140.4187c0,-2.23158 -10.85481,-4.04065 -24.2449,-4.04065l0,0c13.39009,0 24.2449,-1.80907 24.2449,-4.04065l0,-140.4187l0,0c0,-2.23159 10.8548,-4.04066 24.24489,-4.04066",uml_actor:"m40.5,100l219,0m-108.99991,94.00006l107,105m-107.00009,-106.00006l-100,106m99.5,-231l0,125m33.24219,-158.75781c0,18.35916 -14.88303,33.24219 -33.24219,33.24219c-18.35916,0 -33.2422,-14.88303 -33.2422,-33.24219c0.00002,-18.35915 14.88304,-33.24219 33.2422,-33.24219c18.35916,0 33.24219,14.88304 33.24219,33.24219z",dialog_balloon_1:"m0.99786,35.96579l0,0c0,-19.31077 15.28761,-34.96524 34.14583,-34.96524l15.52084,0l0,0l74.50001,0l139.68748,0c9.05606,0 17.74118,3.68382 24.14478,10.24108c6.40356,6.55726 10.00107,15.45081 10.00107,24.72416l0,87.41311l0,0l0,52.44785l0,0c0,19.31078 -15.2876,34.96524 -34.14584,34.96524l-139.68748,0l-97.32507,88.90848l22.82506,-88.90848l-15.52084,0c-18.85822,0 -34.14583,-15.65446 -34.14583,-34.96524l0,0l0,-52.44785l0,0z",cloud:"m182.05086,34.31005c-0.64743,0.02048 -1.27309,0.07504 -1.92319,0.13979c-10.40161,1.03605 -19.58215,7.63722 -24.24597,17.4734l-2.47269,7.44367c0.53346,-2.57959 1.35258,-5.08134 2.47269,-7.44367c-8.31731,-8.61741 -19.99149,-12.59487 -31.52664,-10.72866c-11.53516,1.8662 -21.55294,9.3505 -27.02773,20.19925c-15.45544,-9.51897 -34.72095,-8.94245 -49.62526,1.50272c-14.90431,10.44516 -22.84828,28.93916 -20.43393,47.59753l1.57977,7.58346c-0.71388,-2.48442 -1.24701,-5.01186 -1.57977,-7.58346l-0.2404,0.69894c-12.95573,1.4119 -23.58103,11.46413 -26.34088,24.91708c-2.75985,13.45294 2.9789,27.25658 14.21789,34.21291l17.54914,4.26352c-6.1277,0.50439 -12.24542,-0.9808 -17.54914,-4.26352c-8.66903,9.71078 -10.6639,24.08736 -4.94535,35.96027c5.71854,11.87289 17.93128,18.70935 30.53069,17.15887l7.65843,-2.02692c-2.46413,1.0314 -5.02329,1.70264 -7.65843,2.02692c7.15259,13.16728 19.01251,22.77237 32.93468,26.5945c13.92217,3.82214 28.70987,1.56322 41.03957,-6.25546c10.05858,15.86252 27.91113,24.19412 45.81322,21.38742c17.90208,-2.8067 32.66954,-16.26563 37.91438,-34.52742l1.82016,-10.20447c-0.27254,3.46677 -0.86394,6.87508 -1.82016,10.20447c12.31329,8.07489 27.80199,8.52994 40.52443,1.18819c12.72244,-7.34175 20.6609,-21.34155 20.77736,-36.58929l-4.56108,-22.7823l-17.96776,-15.41455c13.89359,8.70317 22.6528,21.96329 22.52884,38.19685c16.5202,0.17313 30.55292,-13.98268 36.84976,-30.22897c6.29684,-16.24631 3.91486,-34.76801 -6.2504,-48.68089c4.21637,-10.35873 3.96622,-22.14172 -0.68683,-32.29084c-4.65308,-10.14912 -13.23602,-17.69244 -23.55914,-20.65356c-2.31018,-13.45141 -11.83276,-24.27162 -24.41768,-27.81765c-12.58492,-3.54603 -25.98557,0.82654 -34.41142,11.25287l-5.11707,8.63186c1.30753,-3.12148 3.01521,-6.03101 5.11707,-8.63186c-5.93959,-8.19432 -15.2556,-12.8181 -24.96718,-12.51096z",cylinder:"m299.0007,83.77844c0,18.28676 -66.70958,33.11111 -149.00002,33.11111m149.00002,-33.11111l0,0c0,18.28676 -66.70958,33.11111 -149.00002,33.11111c-82.29041,0 -148.99997,-14.82432 -148.99997,-33.11111m0,0l0,0c0,-18.28674 66.70956,-33.1111 148.99997,-33.1111c82.29044,0 149.00002,14.82436 149.00002,33.1111l0,132.44449c0,18.28674 -66.70958,33.11105 -149.00002,33.11105c-82.29041,0 -148.99997,-14.82431 -148.99997,-33.11105z",arrow_u_turn:"m1.00059,299.00055l0,-167.62497l0,0c0,-72.00411 58.37087,-130.37499 130.375,-130.37499l0,0l0,0c34.57759,0 67.73898,13.7359 92.18906,38.18595c24.45006,24.45005 38.18593,57.61144 38.18593,92.18904l0,18.625l37.24997,0l-74.49995,74.50002l-74.50002,-74.50002l37.25,0l0,-18.625c0,-30.8589 -25.0161,-55.87498 -55.87498,-55.87498l0,0l0,0c-30.85892,0 -55.875,25.01608 -55.875,55.87498l0,167.62497z",arrow_left_up:"m0.99865,224.5l74.50004,-74.5l0,37.25l111.74991,0l0,-111.75l-37.25,0l74.5,-74.5l74.5,74.5l-37.25,0l0,186.25l-186.24989,0l0,37.25l-74.50005,-74.5z",maximize:"m1.00037,150.34581l55.30305,-55.30267l0,27.65093l22.17356,0l0,-44.21833l44.21825,0l0,-22.17357l-27.65095,0l55.30267,-55.30292l55.3035,55.30292l-27.65175,0l0,22.17357l44.21835,0l0,44.21833l22.17357,0l0,-27.65093l55.30345,55.30267l-55.30345,55.3035l0,-27.65175l-22.17357,0l0,44.21834l-44.21835,0l0,22.17355l27.65175,0l-55.3035,55.30348l-55.30267,-55.30348l27.65095,0l0,-22.17355l-44.21825,0l0,-44.21834l-22.17356,0l0,27.65175l-55.30305,-55.3035z",cross:"m0.99844,99.71339l98.71494,0l0,-98.71495l101.26279,0l0,98.71495l98.71495,0l0,101.2628l-98.71495,0l0,98.71494l-101.26279,0l0,-98.71494l-98.71494,0z",plaque:"m-0.00197,49.94376l0,0c27.5829,0 49.94327,-22.36036 49.94327,-49.94327l199.76709,0l0,0c0,27.5829 22.36037,49.94327 49.94325,49.94327l0,199.7671l0,0c-27.58289,0 -49.94325,22.36034 -49.94325,49.94325l-199.76709,0c0,-27.58292 -22.36037,-49.94325 -49.94327,-49.94325z",page:"m249.3298,298.99744l9.9335,-39.73413l39.73413,-9.93355l-49.66763,49.66768l-248.33237,0l0,-298.00001l298.00001,0l0,248.33234"},buttons:[]}}).basic,w=[{id:"tool_shapelib",icon:"shapes.png",type:"mode_flyout",position:6,events:{click:function click(){a.setMode(u)}}}],x.abrupt("return",{svgicons:"ext-shapes.xml",buttons:r.buttons.map((function(t,e){return Object.assign(w[e],t)})),callback:function callback(){l("').appendTo("head")),e.text(t?" #tool_topath { display: none !important; }":""),r("#star_panel").toggle(t)},n=e.canvas,r=t.$,o=t.importLocale,p.next=7,o();case 7:return u=p.sent,h=[{id:"tool_star",icon:"star.png",type:"mode",position:12,events:{click:function click(){l(!0),n.setMode("star")}}}],d=[{type:"input",panel:"star_panel",id:"starNumPoints",size:3,defval:5,events:{change:function change(){c("point",this.value)}}},{type:"input",panel:"star_panel",id:"starRadiusMulitplier",size:3,defval:2.5},{type:"input",panel:"star_panel",id:"radialShift",size:3,defval:0,events:{change:function change(){c("radialshift",this.value)}}}],p.abrupt("return",{name:u.name,svgicons:"star-icons.svg",buttons:u.buttons.map((function(t,e){return Object.assign(h[e],t)})),context_tools:u.contextTools.map((function(t,e){return Object.assign(d[e],t)})),callback:function callback(){r("#star_panel").hide()},mouseDown:function mouseDown(t){var e=n.getColor("fill"),r=n.getColor("stroke"),o=n.getStrokeWidth();if("star"===n.getMode())return i=!0,s=n.addSVGElementFromJson({element:"polygon",attr:{cx:t.start_x,cy:t.start_y,id:n.getNextId(),shape:"star",point:document.getElementById("starNumPoints").value,r:0,radialshift:document.getElementById("radialShift").value,r2:0,orient:"point",fill:e,strokecolor:r,strokeWidth:o}}),{started:!0}},mouseMove:function mouseMove(t){if(i&&"star"===n.getMode()){var e=r(s).attr(["cx","cy","point","orient","fill","strokecolor","strokeWidth","radialshift"]),o=t.mouse_x,a=t.mouse_y,u=e.cx,l=e.cy,c=e.fill,h=e.strokecolor,d=e.strokeWidth,p=e.radialshift,f=e.point,v=e.orient,m=Math.sqrt((o-u)*(o-u)+(a-l)*(a-l))/1.5,y=m/document.getElementById("starRadiusMulitplier").value;s.setAttribute("r",m),s.setAttribute("r2",y);for(var g="",_=0;f>=_;_++){var k=2*Math.PI*(_/f);"point"===v?k-=Math.PI/2:"edge"===v&&(k=k+Math.PI/f-Math.PI/2),g+=(o=m*Math.cos(k)+u)+","+(a=m*Math.sin(k)+l)+" ",isNaN(y)||(k=2*Math.PI*(_/f)+Math.PI/f,"point"===v?k-=Math.PI/2:"edge"===v&&(k=k+Math.PI/f-Math.PI/2),k+=p,g+=(o=y*Math.cos(k)+u)+","+(a=y*Math.sin(k)+l)+" ")}return s.setAttribute("points",g),s.setAttribute("fill",c),s.setAttribute("stroke",h),s.setAttribute("stroke-width",d),s.getAttribute("shape"),{started:!0}}},mouseUp:function mouseUp(){if("star"===n.getMode())return{keep:"0"!==r(s).attr(["r"]).r,element:s}},selectedChanged:function selectedChanged(t){for(var e=(a=t.elems).length;e--;){var n=a[e];n&&"star"===n.getAttribute("shape")&&t.selectedElement&&!t.multiselected?(r("#starNumPoints").val(n.getAttribute("point")),r("#radialShift").val(n.getAttribute("radialshift")),l(!0)):l(!1)}},elementChanged:function elementChanged(t){}});case 11:case"end":return p.stop()}}),_callee)})))()}};export default t;
-//# sourceMappingURL=ext-star.js.map
diff --git a/dist/editor/extensions/ext-star.js.map b/dist/editor/extensions/ext-star.js.map
deleted file mode 100644
index da7c7afc..00000000
--- a/dist/editor/extensions/ext-star.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"ext-star.js","sources":["../../../src/editor/extensions/ext-star.js"],"sourcesContent":["/**\n * @file ext-star.js\n *\n *\n * @copyright 2010 CloudCanvas, Inc. All rights reserved\n *\n */\n\nexport default {\n name: 'star',\n async init (S) {\n const svgEditor = this;\n const svgCanvas = svgEditor.canvas;\n\n const {$, importLocale} = S; // {svgcontent},\n let\n selElems,\n // editingitex = false,\n // svgdoc = S.svgroot.parentNode.ownerDocument,\n started,\n newFO;\n // edg = 0,\n // newFOG, newFOGParent, newDef, newImageName, newMaskID,\n // undoCommand = 'Not image',\n // modeChangeG, ccZoom, wEl, hEl, wOffset, hOffset, ccRgbEl, brushW, brushH;\n const strings = await importLocale();\n\n /**\n *\n * @param {boolean} on\n * @returns {void}\n */\n function showPanel (on) {\n let fcRules = $('#fc_rules');\n if (!fcRules.length) {\n fcRules = $('').appendTo('head');\n }\n fcRules.text(!on ? '' : ' #tool_topath { display: none !important; }');\n $('#star_panel').toggle(on);\n }\n\n /*\n function toggleSourceButtons(on){\n $('#star_save, #star_cancel').toggle(on);\n }\n */\n\n /**\n *\n * @param {string} attr\n * @param {string|Float} val\n * @returns {void}\n */\n function setAttr (attr, val) {\n svgCanvas.changeSelectedAttribute(attr, val);\n svgCanvas.call('changed', selElems);\n }\n\n /*\n function cot(n){\n return 1 / Math.tan(n);\n }\n\n function sec(n){\n return 1 / Math.cos(n);\n }\n */\n const buttons = [{\n id: 'tool_star',\n icon: 'star.png',\n type: 'mode',\n position: 12,\n events: {\n click () {\n showPanel(true);\n svgCanvas.setMode('star');\n }\n }\n }];\n const contextTools = [{\n type: 'input',\n panel: 'star_panel',\n id: 'starNumPoints',\n size: 3,\n defval: 5,\n events: {\n change () {\n setAttr('point', this.value);\n }\n }\n }, {\n type: 'input',\n panel: 'star_panel',\n id: 'starRadiusMulitplier',\n size: 3,\n defval: 2.5\n }, {\n type: 'input',\n panel: 'star_panel',\n id: 'radialShift',\n size: 3,\n defval: 0,\n events: {\n change () {\n setAttr('radialshift', this.value);\n }\n }\n }];\n\n return {\n name: strings.name,\n svgicons: 'star-icons.svg',\n buttons: strings.buttons.map((button, i) => {\n return Object.assign(buttons[i], button);\n }),\n context_tools: strings.contextTools.map((contextTool, i) => {\n return Object.assign(contextTools[i], contextTool);\n }),\n callback () {\n $('#star_panel').hide();\n // const endChanges = function(){};\n },\n mouseDown (opts) {\n const rgb = svgCanvas.getColor('fill');\n // const ccRgbEl = rgb.substring(1, rgb.length);\n const sRgb = svgCanvas.getColor('stroke');\n // const ccSRgbEl = sRgb.substring(1, rgb.length);\n const sWidth = svgCanvas.getStrokeWidth();\n\n if (svgCanvas.getMode() === 'star') {\n started = true;\n\n newFO = svgCanvas.addSVGElementFromJson({\n element: 'polygon',\n attr: {\n cx: opts.start_x,\n cy: opts.start_y,\n id: svgCanvas.getNextId(),\n shape: 'star',\n point: document.getElementById('starNumPoints').value,\n r: 0,\n radialshift: document.getElementById('radialShift').value,\n r2: 0,\n orient: 'point',\n fill: rgb,\n strokecolor: sRgb,\n strokeWidth: sWidth\n }\n });\n return {\n started: true\n };\n }\n return undefined;\n },\n mouseMove (opts) {\n if (!started) {\n return undefined;\n }\n if (svgCanvas.getMode() === 'star') {\n const c = $(newFO).attr(['cx', 'cy', 'point', 'orient', 'fill', 'strokecolor', 'strokeWidth', 'radialshift']);\n\n let x = opts.mouse_x;\n let y = opts.mouse_y;\n const {cx, cy, fill, strokecolor, strokeWidth, radialshift, point, orient} = c,\n circumradius = (Math.sqrt((x - cx) * (x - cx) + (y - cy) * (y - cy))) / 1.5,\n inradius = circumradius / document.getElementById('starRadiusMulitplier').value;\n newFO.setAttribute('r', circumradius);\n newFO.setAttribute('r2', inradius);\n\n let polyPoints = '';\n for (let s = 0; point >= s; s++) {\n let angle = 2.0 * Math.PI * (s / point);\n if (orient === 'point') {\n angle -= (Math.PI / 2);\n } else if (orient === 'edge') {\n angle = (angle + (Math.PI / point)) - (Math.PI / 2);\n }\n\n x = (circumradius * Math.cos(angle)) + cx;\n y = (circumradius * Math.sin(angle)) + cy;\n\n polyPoints += x + ',' + y + ' ';\n\n if (!isNaN(inradius)) {\n angle = (2.0 * Math.PI * (s / point)) + (Math.PI / point);\n if (orient === 'point') {\n angle -= (Math.PI / 2);\n } else if (orient === 'edge') {\n angle = (angle + (Math.PI / point)) - (Math.PI / 2);\n }\n angle += radialshift;\n\n x = (inradius * Math.cos(angle)) + cx;\n y = (inradius * Math.sin(angle)) + cy;\n\n polyPoints += x + ',' + y + ' ';\n }\n }\n newFO.setAttribute('points', polyPoints);\n newFO.setAttribute('fill', fill);\n newFO.setAttribute('stroke', strokecolor);\n newFO.setAttribute('stroke-width', strokeWidth);\n /* const shape = */ newFO.getAttribute('shape');\n\n return {\n started: true\n };\n }\n return undefined;\n },\n mouseUp () {\n if (svgCanvas.getMode() === 'star') {\n const attrs = $(newFO).attr(['r']);\n // svgCanvas.addToSelection([newFO], true);\n return {\n keep: (attrs.r !== '0'),\n element: newFO\n };\n }\n return undefined;\n },\n selectedChanged (opts) {\n // Use this to update the current selected elements\n selElems = opts.elems;\n\n let i = selElems.length;\n while (i--) {\n const elem = selElems[i];\n if (elem && elem.getAttribute('shape') === 'star') {\n if (opts.selectedElement && !opts.multiselected) {\n // $('#starRadiusMulitplier').val(elem.getAttribute('r2'));\n $('#starNumPoints').val(elem.getAttribute('point'));\n $('#radialShift').val(elem.getAttribute('radialshift'));\n showPanel(true);\n } else {\n showPanel(false);\n }\n } else {\n showPanel(false);\n }\n }\n },\n elementChanged (opts) {\n // const elem = opts.elems[0];\n }\n };\n }\n};\n"],"names":["name","init","S","showPanel","setAttr","attr","val","svgCanvas","changeSelectedAttribute","call","selElems","on","fcRules","$","length","appendTo","text","toggle","_this","canvas","importLocale","strings","buttons","id","icon","type","position","events","click","setMode","contextTools","panel","size","defval","change","this","value","svgicons","map","button","i","Object","assign","context_tools","contextTool","callback","hide","mouseDown","opts","rgb","getColor","sRgb","sWidth","getStrokeWidth","getMode","started","newFO","addSVGElementFromJson","element","cx","start_x","cy","start_y","getNextId","shape","point","document","getElementById","r","radialshift","r2","orient","fill","strokecolor","strokeWidth","mouseMove","c","x","mouse_x","y","mouse_y","circumradius","Math","sqrt","inradius","setAttribute","polyPoints","s","angle","PI","cos","sin","isNaN","getAttribute","mouseUp","keep","selectedChanged","elems","elem","selectedElement","multiselected","elementChanged"],"mappings":"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"}
\ No newline at end of file
diff --git a/dist/editor/extensions/ext-star/ext-star.js b/dist/editor/extensions/ext-star/ext-star.js
new file mode 100644
index 00000000..92306534
--- /dev/null
+++ b/dist/editor/extensions/ext-star/ext-star.js
@@ -0,0 +1,2 @@
+function asyncGeneratorStep(t,e,n,a,r,o,i){try{var s=t[o](i),l=s.value}catch(t){return void n(t)}s.done?e(l):Promise.resolve(l).then(a,r)}var t={name:"star",init:function init(t){var e=this;return function _asyncToGenerator(t){return function(){var e=this,n=arguments;return new Promise((function(a,r){var o=t.apply(e,n);function _next(t){asyncGeneratorStep(o,a,r,_next,_throw,"next",t)}function _throw(t){asyncGeneratorStep(o,a,r,_next,_throw,"throw",t)}_next(void 0)}))}}(regeneratorRuntime.mark((function _callee(){var n,a,r,o,i,s,l,u,c,d,h,p;return regeneratorRuntime.wrap((function _callee$(f){for(;;)switch(f.prev=f.next){case 0:return d=function _setAttr(t,e){a.changeSelectedAttribute(t,e),a.call("changed",o)},c=function _showPanel(t){var e=r("#fc_rules");e.length||(e=r('').appendTo("head")),e.text(t?" #tool_topath { display: none !important; }":""),r("#star_panel").toggle(t)},a=(n=e).canvas,r=t.$,f.next=7,import("./locale/".concat(n.curPrefs.lang,".js"));case 7:return l=f.sent,u=l.default,h=[{id:"tool_star",icon:"star.png",type:"mode",position:12,events:{click:function click(){c(!0),a.setMode("star")}}}],p=[{type:"input",panel:"star_panel",id:"starNumPoints",size:3,defval:5,events:{change:function change(){d("point",this.value)}}},{type:"input",panel:"star_panel",id:"starRadiusMulitplier",size:3,defval:2.5},{type:"input",panel:"star_panel",id:"radialShift",size:3,defval:0,events:{change:function change(){d("radialshift",this.value)}}}],f.abrupt("return",{name:u.name,svgicons:"star-icons.svg",buttons:u.buttons.map((function(t,e){return Object.assign(h[e],t)})),context_tools:u.contextTools.map((function(t,e){return Object.assign(p[e],t)})),callback:function callback(){r("#star_panel").hide()},mouseDown:function mouseDown(t){var e=a.getColor("fill"),n=a.getColor("stroke"),r=a.getStrokeWidth();if("star"===a.getMode())return i=!0,s=a.addSVGElementFromJson({element:"polygon",attr:{cx:t.start_x,cy:t.start_y,id:a.getNextId(),shape:"star",point:document.getElementById("starNumPoints").value,r:0,radialshift:document.getElementById("radialShift").value,r2:0,orient:"point",fill:e,strokecolor:n,strokeWidth:r}}),{started:!0}},mouseMove:function mouseMove(t){if(i&&"star"===a.getMode()){var e=r(s).attr(["cx","cy","point","orient","fill","strokecolor","strokeWidth","radialshift"]),n=t.mouse_x,o=t.mouse_y,l=e.cx,u=e.cy,c=e.fill,d=e.strokecolor,h=e.strokeWidth,p=e.radialshift,f=e.point,g=e.orient,m=Math.sqrt((n-l)*(n-l)+(o-u)*(o-u))/1.5,v=m/document.getElementById("starRadiusMulitplier").value;s.setAttribute("r",m),s.setAttribute("r2",v);for(var _="",y=0;f>=y;y++){var M=2*Math.PI*(y/f);"point"===g?M-=Math.PI/2:"edge"===g&&(M=M+Math.PI/f-Math.PI/2),_+=(n=m*Math.cos(M)+l)+","+(o=m*Math.sin(M)+u)+" ",isNaN(v)||(M=2*Math.PI*(y/f)+Math.PI/f,"point"===g?M-=Math.PI/2:"edge"===g&&(M=M+Math.PI/f-Math.PI/2),M+=p,_+=(n=v*Math.cos(M)+l)+","+(o=v*Math.sin(M)+u)+" ")}return s.setAttribute("points",_),s.setAttribute("fill",c),s.setAttribute("stroke",d),s.setAttribute("stroke-width",h),s.getAttribute("shape"),{started:!0}}},mouseUp:function mouseUp(){if("star"===a.getMode())return{keep:"0"!==r(s).attr(["r"]).r,element:s}},selectedChanged:function selectedChanged(t){for(var e=(o=t.elems).length;e--;){var n=o[e];n&&"star"===n.getAttribute("shape")&&t.selectedElement&&!t.multiselected?(r("#starNumPoints").val(n.getAttribute("point")),r("#radialShift").val(n.getAttribute("radialshift")),c(!0)):c(!1)}},elementChanged:function elementChanged(t){}});case 12:case"end":return f.stop()}}),_callee)})))()}};export default t;
+//# sourceMappingURL=ext-star.js.map
diff --git a/dist/editor/extensions/ext-star/ext-star.js.map b/dist/editor/extensions/ext-star/ext-star.js.map
new file mode 100644
index 00000000..0bc9129e
--- /dev/null
+++ b/dist/editor/extensions/ext-star/ext-star.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"ext-star.js","sources":["../../../../src/editor/extensions/ext-star/ext-star.js"],"sourcesContent":["/**\n * @file ext-star.js\n *\n *\n * @copyright 2010 CloudCanvas, Inc. All rights reserved\n *\n */\n\nexport default {\n name: 'star',\n async init (S) {\n const svgEditor = this;\n const svgCanvas = svgEditor.canvas;\n\n const {$} = S; // {svgcontent},\n let\n selElems,\n // editingitex = false,\n // svgdoc = S.svgroot.parentNode.ownerDocument,\n started,\n newFO;\n // edg = 0,\n // newFOG, newFOGParent, newDef, newImageName, newMaskID,\n // undoCommand = 'Not image',\n // modeChangeG, ccZoom, wEl, hEl, wOffset, hOffset, ccRgbEl, brushW, brushH;\n // eslint-disable-next-line node/no-unsupported-features/es-syntax\n const {default: strings} = await import(`./locale/${svgEditor.curPrefs.lang}.js`);\n\n /**\n *\n * @param {boolean} on\n * @returns {void}\n */\n function showPanel (on) {\n let fcRules = $('#fc_rules');\n if (!fcRules.length) {\n fcRules = $('').appendTo('head');\n }\n fcRules.text(!on ? '' : ' #tool_topath { display: none !important; }');\n $('#star_panel').toggle(on);\n }\n\n /*\n function toggleSourceButtons(on){\n $('#star_save, #star_cancel').toggle(on);\n }\n */\n\n /**\n *\n * @param {string} attr\n * @param {string|Float} val\n * @returns {void}\n */\n function setAttr (attr, val) {\n svgCanvas.changeSelectedAttribute(attr, val);\n svgCanvas.call('changed', selElems);\n }\n\n /*\n function cot(n){\n return 1 / Math.tan(n);\n }\n\n function sec(n){\n return 1 / Math.cos(n);\n }\n */\n const buttons = [{\n id: 'tool_star',\n icon: 'star.png',\n type: 'mode',\n position: 12,\n events: {\n click () {\n showPanel(true);\n svgCanvas.setMode('star');\n }\n }\n }];\n const contextTools = [{\n type: 'input',\n panel: 'star_panel',\n id: 'starNumPoints',\n size: 3,\n defval: 5,\n events: {\n change () {\n setAttr('point', this.value);\n }\n }\n }, {\n type: 'input',\n panel: 'star_panel',\n id: 'starRadiusMulitplier',\n size: 3,\n defval: 2.5\n }, {\n type: 'input',\n panel: 'star_panel',\n id: 'radialShift',\n size: 3,\n defval: 0,\n events: {\n change () {\n setAttr('radialshift', this.value);\n }\n }\n }];\n\n return {\n name: strings.name,\n svgicons: 'star-icons.svg',\n buttons: strings.buttons.map((button, i) => {\n return Object.assign(buttons[i], button);\n }),\n context_tools: strings.contextTools.map((contextTool, i) => {\n return Object.assign(contextTools[i], contextTool);\n }),\n callback () {\n $('#star_panel').hide();\n // const endChanges = function(){};\n },\n mouseDown (opts) {\n const rgb = svgCanvas.getColor('fill');\n // const ccRgbEl = rgb.substring(1, rgb.length);\n const sRgb = svgCanvas.getColor('stroke');\n // const ccSRgbEl = sRgb.substring(1, rgb.length);\n const sWidth = svgCanvas.getStrokeWidth();\n\n if (svgCanvas.getMode() === 'star') {\n started = true;\n\n newFO = svgCanvas.addSVGElementFromJson({\n element: 'polygon',\n attr: {\n cx: opts.start_x,\n cy: opts.start_y,\n id: svgCanvas.getNextId(),\n shape: 'star',\n point: document.getElementById('starNumPoints').value,\n r: 0,\n radialshift: document.getElementById('radialShift').value,\n r2: 0,\n orient: 'point',\n fill: rgb,\n strokecolor: sRgb,\n strokeWidth: sWidth\n }\n });\n return {\n started: true\n };\n }\n return undefined;\n },\n mouseMove (opts) {\n if (!started) {\n return undefined;\n }\n if (svgCanvas.getMode() === 'star') {\n const c = $(newFO).attr(['cx', 'cy', 'point', 'orient', 'fill', 'strokecolor', 'strokeWidth', 'radialshift']);\n\n let x = opts.mouse_x;\n let y = opts.mouse_y;\n const {cx, cy, fill, strokecolor, strokeWidth, radialshift, point, orient} = c,\n circumradius = (Math.sqrt((x - cx) * (x - cx) + (y - cy) * (y - cy))) / 1.5,\n inradius = circumradius / document.getElementById('starRadiusMulitplier').value;\n newFO.setAttribute('r', circumradius);\n newFO.setAttribute('r2', inradius);\n\n let polyPoints = '';\n for (let s = 0; point >= s; s++) {\n let angle = 2.0 * Math.PI * (s / point);\n if (orient === 'point') {\n angle -= (Math.PI / 2);\n } else if (orient === 'edge') {\n angle = (angle + (Math.PI / point)) - (Math.PI / 2);\n }\n\n x = (circumradius * Math.cos(angle)) + cx;\n y = (circumradius * Math.sin(angle)) + cy;\n\n polyPoints += x + ',' + y + ' ';\n\n if (!isNaN(inradius)) {\n angle = (2.0 * Math.PI * (s / point)) + (Math.PI / point);\n if (orient === 'point') {\n angle -= (Math.PI / 2);\n } else if (orient === 'edge') {\n angle = (angle + (Math.PI / point)) - (Math.PI / 2);\n }\n angle += radialshift;\n\n x = (inradius * Math.cos(angle)) + cx;\n y = (inradius * Math.sin(angle)) + cy;\n\n polyPoints += x + ',' + y + ' ';\n }\n }\n newFO.setAttribute('points', polyPoints);\n newFO.setAttribute('fill', fill);\n newFO.setAttribute('stroke', strokecolor);\n newFO.setAttribute('stroke-width', strokeWidth);\n /* const shape = */ newFO.getAttribute('shape');\n\n return {\n started: true\n };\n }\n return undefined;\n },\n mouseUp () {\n if (svgCanvas.getMode() === 'star') {\n const attrs = $(newFO).attr(['r']);\n // svgCanvas.addToSelection([newFO], true);\n return {\n keep: (attrs.r !== '0'),\n element: newFO\n };\n }\n return undefined;\n },\n selectedChanged (opts) {\n // Use this to update the current selected elements\n selElems = opts.elems;\n\n let i = selElems.length;\n while (i--) {\n const elem = selElems[i];\n if (elem && elem.getAttribute('shape') === 'star') {\n if (opts.selectedElement && !opts.multiselected) {\n // $('#starRadiusMulitplier').val(elem.getAttribute('r2'));\n $('#starNumPoints').val(elem.getAttribute('point'));\n $('#radialShift').val(elem.getAttribute('radialshift'));\n showPanel(true);\n } else {\n showPanel(false);\n }\n } else {\n showPanel(false);\n }\n }\n },\n elementChanged (opts) {\n // const elem = opts.elems[0];\n }\n };\n }\n};\n"],"names":["name","init","S","showPanel","setAttr","attr","val","svgCanvas","changeSelectedAttribute","call","selElems","on","fcRules","$","length","appendTo","text","toggle","svgEditor","_this","canvas","import","curPrefs","lang","strings","buttons","id","icon","type","position","events","click","setMode","contextTools","panel","size","defval","change","this","value","svgicons","map","button","i","Object","assign","context_tools","contextTool","callback","hide","mouseDown","opts","rgb","getColor","sRgb","sWidth","getStrokeWidth","getMode","started","newFO","addSVGElementFromJson","element","cx","start_x","cy","start_y","getNextId","shape","point","document","getElementById","r","radialshift","r2","orient","fill","strokecolor","strokeWidth","mouseMove","c","x","mouse_x","y","mouse_y","circumradius","Math","sqrt","inradius","setAttribute","polyPoints","s","angle","PI","cos","sin","isNaN","getAttribute","mouseUp","keep","selectedChanged","elems","elem","selectedElement","multiselected","elementChanged"],"mappings":"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"}
\ No newline at end of file
diff --git a/dist/editor/extensions/ext-storage.js b/dist/editor/extensions/ext-storage.js
deleted file mode 100644
index ea8b02e0..00000000
--- a/dist/editor/extensions/ext-storage.js
+++ /dev/null
@@ -1,23 +0,0 @@
-function _AwaitValue(e){this.wrapped=e}function _AsyncGenerator(e){var t,r;function resume(t,r){try{var n=e[t](r),o=n.value,a=o instanceof _AwaitValue;Promise.resolve(a?o.wrapped:o).then((function(e){a?resume("return"===t?"return":"next",e):settle(n.done?"return":"normal",e)}),(function(e){resume("throw",e)}))}catch(e){settle("throw",e)}}function settle(e,n){switch(e){case"return":t.resolve({value:n,done:!0});break;case"throw":t.reject(n);break;default:t.resolve({value:n,done:!1})}(t=t.next)?resume(t.key,t.arg):r=null}this._invoke=function send(e,n){return new Promise((function(o,a){var i={key:e,arg:n,resolve:o,reject:a,next:null};r?r=r.next=i:(t=r=i,resume(e,n))}))},"function"!=typeof e.return&&(this.return=void 0)}function asyncGeneratorStep(e,t,r,n,o,a,i){try{var s=e[a](i),c=s.value}catch(e){return void r(e)}s.done?t(c):Promise.resolve(c).then(n,o)}function _slicedToArray(e,t){return _arrayWithHoles(e)||function _iterableToArrayLimit(e,t){if("undefined"==typeof Symbol||!(Symbol.iterator in Object(e)))return;var r=[],n=!0,o=!1,a=void 0;try{for(var i,s=e[Symbol.iterator]();!(n=(i=s.next()).done)&&(r.push(i.value),!t||r.length!==t);n=!0);}catch(e){o=!0,a=e}finally{try{n||null==s.return||s.return()}finally{if(o)throw a}}return r}(e,t)||_unsupportedIterableToArray(e,t)||_nonIterableRest()}function _arrayWithHoles(e){if(Array.isArray(e))return e}function _unsupportedIterableToArray(e,t){if(e){if("string"==typeof e)return _arrayLikeToArray(e,t);var r=Object.prototype.toString.call(e).slice(8,-1);return"Object"===r&&e.constructor&&(r=e.constructor.name),"Map"===r||"Set"===r?Array.from(e):"Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r)?_arrayLikeToArray(e,t):void 0}}function _arrayLikeToArray(e,t){(null==t||t>e.length)&&(t=e.length);for(var r=0,n=new Array(t);r
[&?])storagePrompt=[^&]*(?&?)/, function (n0, sep, amp) {\n return (val ? sep : '') + val + (!val && amp ? sep : (amp || ''));\n });\n */\n loc.href = loc.href.replace(/([&?])storagePrompt=[^&]*(&?)/, function (n0, n1, amp) {\n return (val ? n1 : '') + val + (!val && amp ? n1 : (amp || ''));\n });\n } else {\n loc.href += (loc.href.includes('?') ? '&' : '?') + val;\n }\n }\n\n /**\n * Sets SVG content as a string with \"svgedit-\" and the current\n * canvas name as namespace.\n * @param {string} val\n * @returns {void}\n */\n function setSVGContentStorage (val) {\n if (storage) {\n const name = 'svgedit-' + svgEditor.curConfig.canvasName;\n if (!val) {\n storage.removeItem(name);\n } else {\n storage.setItem(name, val);\n }\n }\n }\n\n /**\n * Set the cookie to expire.\n * @param {string} cookie\n * @returns {void}\n */\n function expireCookie (cookie) {\n document.cookie = encodeURIComponent(cookie) + '=; expires=Thu, 01 Jan 1970 00:00:00 GMT';\n }\n\n /**\n * Expire the storage cookie.\n * @returns {void}\n */\n function removeStoragePrefCookie () {\n expireCookie('svgeditstore');\n }\n\n /**\n * Empties storage for each of the current preferences.\n * @returns {void}\n */\n function emptyStorage () {\n setSVGContentStorage('');\n Object.keys(svgEditor.curPrefs).forEach((name) => {\n name = 'svg-edit-' + name;\n if (storage) {\n storage.removeItem(name);\n }\n expireCookie(name);\n });\n }\n\n // emptyStorage();\n\n /**\n * Listen for unloading: If and only if opted in by the user, set the content\n * document and preferences into storage:\n * 1. Prevent save warnings (since we're automatically saving unsaved\n * content into storage)\n * 2. Use localStorage to set SVG contents (potentially too large to allow in cookies)\n * 3. Use localStorage (where available) or cookies to set preferences.\n * @returns {void}\n */\n function setupBeforeUnloadListener () {\n window.addEventListener('beforeunload', function (e) {\n // Don't save anything unless the user opted in to storage\n if (!document.cookie.match(/(?:^|;\\s*)svgeditstore=(?:prefsAndContent|prefsOnly)/)) {\n return;\n }\n if (document.cookie.match(/(?:^|;\\s*)svgeditstore=prefsAndContent/)) {\n setSVGContentStorage(svgCanvas.getSvgString());\n }\n\n svgEditor.setConfig({no_save_warning: true}); // No need for explicit saving at all once storage is on\n // svgEditor.showSaveWarning = false;\n\n const {curPrefs} = svgEditor;\n\n Object.entries(curPrefs).forEach(([key, val]) => {\n const store = (val !== undefined);\n key = 'svg-edit-' + key;\n if (!store) {\n return;\n }\n if (storage) {\n storage.setItem(key, val);\n } else if (window.widget) {\n window.widget.setPreferenceForKey(val, key);\n } else {\n val = encodeURIComponent(val);\n document.cookie = encodeURIComponent(key) + '=' + val + '; expires=Fri, 31 Dec 9999 23:59:59 GMT';\n }\n });\n });\n }\n\n let loaded = false;\n return {\n name: 'storage',\n async langReady ({importLocale}) {\n const storagePrompt = new URL(top.location).searchParams.get('storagePrompt');\n\n const confirmSetStorage = await importLocale();\n const {\n message, storagePrefsAndContent, storagePrefsOnly,\n storagePrefs, storageNoPrefsOrContent, storageNoPrefs,\n rememberLabel, rememberTooltip\n } = confirmSetStorage;\n\n // No need to run this one-time dialog again just because the user\n // changes the language\n if (loaded) {\n return;\n }\n loaded = true;\n\n // Note that the following can load even if \"noStorageOnLoad\" is\n // set to false; to avoid any chance of storage, avoid this\n // extension! (and to avoid using any prior storage, set the\n // config option \"noStorageOnLoad\" to true).\n if (!forceStorage && (\n // If the URL has been explicitly set to always prompt the\n // user (e.g., so one can be pointed to a URL where one\n // can alter one's settings, say to prevent future storage)...\n storagePrompt === 'true' ||\n (\n // ...or...if the URL at least doesn't explicitly prevent a\n // storage prompt (as we use for users who\n // don't want to set cookies at all but who don't want\n // continual prompts about it)...\n storagePrompt !== 'false' &&\n // ...and this user hasn't previously indicated a desire for storage\n !document.cookie.match(/(?:^|;\\s*)svgeditstore=(?:prefsAndContent|prefsOnly)/)\n )\n // ...then show the storage prompt.\n )) {\n const options = [];\n if (storage) {\n options.unshift(\n {value: 'prefsAndContent', text: storagePrefsAndContent},\n {value: 'prefsOnly', text: storagePrefsOnly},\n {value: 'noPrefsOrContent', text: storageNoPrefsOrContent}\n );\n } else {\n options.unshift(\n {value: 'prefsOnly', text: storagePrefs},\n {value: 'noPrefsOrContent', text: storageNoPrefs}\n );\n }\n\n // Hack to temporarily provide a wide and high enough dialog\n const oldContainerWidth = $('#dialog_container')[0].style.width,\n oldContainerMarginLeft = $('#dialog_container')[0].style.marginLeft,\n oldContentHeight = $('#dialog_content')[0].style.height,\n oldContainerHeight = $('#dialog_container')[0].style.height;\n $('#dialog_content')[0].style.height = '120px';\n $('#dialog_container')[0].style.height = '170px';\n $('#dialog_container')[0].style.width = '800px';\n $('#dialog_container')[0].style.marginLeft = '-400px';\n\n // Open select-with-checkbox dialog\n // From svg-editor.js\n svgEditor.storagePromptState = 'waiting';\n const {response: pref, checked} = await $.select(\n message,\n options,\n null,\n null,\n {\n label: rememberLabel,\n checked: true,\n tooltip: rememberTooltip\n }\n );\n if (pref && pref !== 'noPrefsOrContent') {\n // Regardless of whether the user opted\n // to remember the choice (and move to a URL which won't\n // ask them again), we have to assume the user\n // doesn't even want to remember their not wanting\n // storage, so we don't set the cookie or continue on with\n // setting storage on beforeunload\n document.cookie = 'svgeditstore=' + encodeURIComponent(pref) + '; expires=Fri, 31 Dec 9999 23:59:59 GMT'; // 'prefsAndContent' | 'prefsOnly'\n // If the URL was configured to always insist on a prompt, if\n // the user does indicate a wish to store their info, we\n // don't want ask them again upon page refresh so move\n // them instead to a URL which does not always prompt\n if (storagePrompt === 'true' && checked) {\n replaceStoragePrompt();\n return;\n }\n } else { // The user does not wish storage (or cancelled, which we treat equivalently)\n removeStoragePrefCookie();\n if (pref && // If the user explicitly expresses wish for no storage\n emptyStorageOnDecline\n ) {\n emptyStorage();\n }\n if (pref && checked) {\n // Open a URL which won't set storage and won't prompt user about storage\n replaceStoragePrompt('false');\n return;\n }\n }\n\n // Reset width/height of dialog (e.g., for use by Export)\n $('#dialog_container')[0].style.width = oldContainerWidth;\n $('#dialog_container')[0].style.marginLeft = oldContainerMarginLeft;\n $('#dialog_content')[0].style.height = oldContentHeight;\n $('#dialog_container')[0].style.height = oldContainerHeight;\n\n // It should be enough to (conditionally) add to storage on\n // beforeunload, but if we wished to update immediately,\n // we might wish to try setting:\n // svgEditor.setConfig({noStorageOnLoad: true});\n // and then call:\n // svgEditor.loadContentAndPrefs();\n\n // We don't check for noStorageOnLoad here because\n // the prompt gives the user the option to store data\n setupBeforeUnloadListener();\n\n svgEditor.storagePromptState = 'closed';\n updateCanvas(true);\n } else if (!noStorageOnLoad || forceStorage) {\n setupBeforeUnloadListener();\n }\n }\n };\n }\n};\n"],"names":["name","init","$","svgEditor","this","svgCanvas","canvas","curConfig","emptyStorageOnDecline","noStorageOnLoad","forceStorage","storage","updateCanvas","replaceStoragePrompt","val","loc","top","location","href","includes","replace","n0","n1","amp","setSVGContentStorage","canvasName","setItem","removeItem","expireCookie","cookie","document","encodeURIComponent","setupBeforeUnloadListener","window","addEventListener","e","match","getSvgString","setConfig","no_save_warning","curPrefs","Object","entries","forEach","key","undefined","widget","setPreferenceForKey","loaded","langReady","importLocale","storagePrompt","URL","searchParams","get","confirmSetStorage","message","storagePrefsAndContent","storagePrefsOnly","storagePrefs","storageNoPrefsOrContent","storageNoPrefs","rememberLabel","rememberTooltip","options","unshift","value","text","oldContainerWidth","style","width","oldContainerMarginLeft","marginLeft","oldContentHeight","height","oldContainerHeight","storagePromptState","select","label","checked","tooltip","pref","response","keys"],"mappings":"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"}
\ No newline at end of file
diff --git a/dist/editor/extensions/ext-storage/ext-storage.js b/dist/editor/extensions/ext-storage/ext-storage.js
new file mode 100644
index 00000000..d1b2bb2c
--- /dev/null
+++ b/dist/editor/extensions/ext-storage/ext-storage.js
@@ -0,0 +1,22 @@
+function asyncGeneratorStep(e,t,r,n,o,a,i){try{var s=e[a](i),c=s.value}catch(e){return void r(e)}s.done?t(c):Promise.resolve(c).then(n,o)}function _slicedToArray(e,t){return function _arrayWithHoles(e){if(Array.isArray(e))return e}(e)||function _iterableToArrayLimit(e,t){if("undefined"==typeof Symbol||!(Symbol.iterator in Object(e)))return;var r=[],n=!0,o=!1,a=void 0;try{for(var i,s=e[Symbol.iterator]();!(n=(i=s.next()).done)&&(r.push(i.value),!t||r.length!==t);n=!0);}catch(e){o=!0,a=e}finally{try{n||null==s.return||s.return()}finally{if(o)throw a}}return r}(e,t)||function _unsupportedIterableToArray(e,t){if(!e)return;if("string"==typeof e)return _arrayLikeToArray(e,t);var r=Object.prototype.toString.call(e).slice(8,-1);"Object"===r&&e.constructor&&(r=e.constructor.name);if("Map"===r||"Set"===r)return Array.from(e);if("Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r))return _arrayLikeToArray(e,t)}(e,t)||function _nonIterableRest(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}
+/**
+ * @file ext-storage.js
+ *
+ * This extension allows automatic saving of the SVG canvas contents upon
+ * page unload (which can later be automatically retrieved upon future
+ * editor loads).
+ *
+ * The functionality was originally part of the SVG Editor, but moved to a
+ * separate extension to make the setting behavior optional, and adapted
+ * to inform the user of its setting of local data.
+ *
+ * @license MIT
+ *
+ * @copyright 2010 Brett Zamir
+ * @todo Revisit on whether to use `svgEditor.pref` over directly setting
+ * `curConfig` in all extensions for a more public API (not only for `extPath`
+ * and `imagePath`, but other currently used config in the extensions)
+ * @todo We might provide control of storage settings through the UI besides the
+ * initial (or URL-forced) dialog. *
+*/()}function _arrayLikeToArray(e,t){(null==t||t>e.length)&&(t=e.length);for(var r=0,n=new Array(t);r[&?])storagePrompt=[^&]*(?&?)/, function (n0, sep, amp) {\n return (val ? sep : '') + val + (!val && amp ? sep : (amp || ''));\n });\n */\n loc.href = loc.href.replace(/([&?])storagePrompt=[^&]*(&?)/, function (n0, n1, amp) {\n return (val ? n1 : '') + val + (!val && amp ? n1 : (amp || ''));\n });\n } else {\n loc.href += (loc.href.includes('?') ? '&' : '?') + val;\n }\n }\n\n /**\n * Sets SVG content as a string with \"svgedit-\" and the current\n * canvas name as namespace.\n * @param {string} val\n * @returns {void}\n */\n function setSVGContentStorage (val) {\n if (storage) {\n const name = 'svgedit-' + svgEditor.curConfig.canvasName;\n if (!val) {\n storage.removeItem(name);\n } else {\n storage.setItem(name, val);\n }\n }\n }\n\n /**\n * Set the cookie to expire.\n * @param {string} cookie\n * @returns {void}\n */\n function expireCookie (cookie) {\n document.cookie = encodeURIComponent(cookie) + '=; expires=Thu, 01 Jan 1970 00:00:00 GMT';\n }\n\n /**\n * Expire the storage cookie.\n * @returns {void}\n */\n function removeStoragePrefCookie () {\n expireCookie('svgeditstore');\n }\n\n /**\n * Empties storage for each of the current preferences.\n * @returns {void}\n */\n function emptyStorage () {\n setSVGContentStorage('');\n Object.keys(svgEditor.curPrefs).forEach((name) => {\n name = 'svg-edit-' + name;\n if (storage) {\n storage.removeItem(name);\n }\n expireCookie(name);\n });\n }\n\n // emptyStorage();\n\n /**\n * Listen for unloading: If and only if opted in by the user, set the content\n * document and preferences into storage:\n * 1. Prevent save warnings (since we're automatically saving unsaved\n * content into storage)\n * 2. Use localStorage to set SVG contents (potentially too large to allow in cookies)\n * 3. Use localStorage (where available) or cookies to set preferences.\n * @returns {void}\n */\n function setupBeforeUnloadListener () {\n window.addEventListener('beforeunload', function (e) {\n // Don't save anything unless the user opted in to storage\n if (!document.cookie.match(/(?:^|;\\s*)svgeditstore=(?:prefsAndContent|prefsOnly)/)) {\n return;\n }\n if (document.cookie.match(/(?:^|;\\s*)svgeditstore=prefsAndContent/)) {\n setSVGContentStorage(svgCanvas.getSvgString());\n }\n\n svgEditor.setConfig({no_save_warning: true}); // No need for explicit saving at all once storage is on\n // svgEditor.showSaveWarning = false;\n\n const {curPrefs} = svgEditor;\n\n Object.entries(curPrefs).forEach(([key, val]) => {\n const store = (val !== undefined);\n key = 'svg-edit-' + key;\n if (!store) {\n return;\n }\n if (storage) {\n storage.setItem(key, val);\n } else if (window.widget) {\n window.widget.setPreferenceForKey(val, key);\n } else {\n val = encodeURIComponent(val);\n document.cookie = encodeURIComponent(key) + '=' + val + '; expires=Fri, 31 Dec 9999 23:59:59 GMT';\n }\n });\n });\n }\n\n let loaded = false;\n return {\n name: 'storage',\n async langReady ({importLocale}) {\n const storagePrompt = new URL(top.location).searchParams.get('storagePrompt');\n\n const confirmSetStorage = await importLocale();\n const {\n message, storagePrefsAndContent, storagePrefsOnly,\n storagePrefs, storageNoPrefsOrContent, storageNoPrefs,\n rememberLabel, rememberTooltip\n } = confirmSetStorage;\n\n // No need to run this one-time dialog again just because the user\n // changes the language\n if (loaded) {\n return;\n }\n loaded = true;\n\n // Note that the following can load even if \"noStorageOnLoad\" is\n // set to false; to avoid any chance of storage, avoid this\n // extension! (and to avoid using any prior storage, set the\n // config option \"noStorageOnLoad\" to true).\n if (!forceStorage && (\n // If the URL has been explicitly set to always prompt the\n // user (e.g., so one can be pointed to a URL where one\n // can alter one's settings, say to prevent future storage)...\n storagePrompt === 'true' ||\n (\n // ...or...if the URL at least doesn't explicitly prevent a\n // storage prompt (as we use for users who\n // don't want to set cookies at all but who don't want\n // continual prompts about it)...\n storagePrompt !== 'false' &&\n // ...and this user hasn't previously indicated a desire for storage\n !document.cookie.match(/(?:^|;\\s*)svgeditstore=(?:prefsAndContent|prefsOnly)/)\n )\n // ...then show the storage prompt.\n )) {\n const options = [];\n if (storage) {\n options.unshift(\n {value: 'prefsAndContent', text: storagePrefsAndContent},\n {value: 'prefsOnly', text: storagePrefsOnly},\n {value: 'noPrefsOrContent', text: storageNoPrefsOrContent}\n );\n } else {\n options.unshift(\n {value: 'prefsOnly', text: storagePrefs},\n {value: 'noPrefsOrContent', text: storageNoPrefs}\n );\n }\n\n // Hack to temporarily provide a wide and high enough dialog\n const oldContainerWidth = $('#dialog_container')[0].style.width,\n oldContainerMarginLeft = $('#dialog_container')[0].style.marginLeft,\n oldContentHeight = $('#dialog_content')[0].style.height,\n oldContainerHeight = $('#dialog_container')[0].style.height;\n $('#dialog_content')[0].style.height = '120px';\n $('#dialog_container')[0].style.height = '170px';\n $('#dialog_container')[0].style.width = '800px';\n $('#dialog_container')[0].style.marginLeft = '-400px';\n\n // Open select-with-checkbox dialog\n // From svg-editor.js\n svgEditor.storagePromptState = 'waiting';\n const {response: pref, checked} = await $.select(\n message,\n options,\n null,\n null,\n {\n label: rememberLabel,\n checked: true,\n tooltip: rememberTooltip\n }\n );\n if (pref && pref !== 'noPrefsOrContent') {\n // Regardless of whether the user opted\n // to remember the choice (and move to a URL which won't\n // ask them again), we have to assume the user\n // doesn't even want to remember their not wanting\n // storage, so we don't set the cookie or continue on with\n // setting storage on beforeunload\n document.cookie = 'svgeditstore=' + encodeURIComponent(pref) + '; expires=Fri, 31 Dec 9999 23:59:59 GMT'; // 'prefsAndContent' | 'prefsOnly'\n // If the URL was configured to always insist on a prompt, if\n // the user does indicate a wish to store their info, we\n // don't want ask them again upon page refresh so move\n // them instead to a URL which does not always prompt\n if (storagePrompt === 'true' && checked) {\n replaceStoragePrompt();\n return;\n }\n } else { // The user does not wish storage (or cancelled, which we treat equivalently)\n removeStoragePrefCookie();\n if (pref && // If the user explicitly expresses wish for no storage\n emptyStorageOnDecline\n ) {\n emptyStorage();\n }\n if (pref && checked) {\n // Open a URL which won't set storage and won't prompt user about storage\n replaceStoragePrompt('false');\n return;\n }\n }\n\n // Reset width/height of dialog (e.g., for use by Export)\n $('#dialog_container')[0].style.width = oldContainerWidth;\n $('#dialog_container')[0].style.marginLeft = oldContainerMarginLeft;\n $('#dialog_content')[0].style.height = oldContentHeight;\n $('#dialog_container')[0].style.height = oldContainerHeight;\n\n // It should be enough to (conditionally) add to storage on\n // beforeunload, but if we wished to update immediately,\n // we might wish to try setting:\n // svgEditor.setConfig({noStorageOnLoad: true});\n // and then call:\n // svgEditor.loadContentAndPrefs();\n\n // We don't check for noStorageOnLoad here because\n // the prompt gives the user the option to store data\n setupBeforeUnloadListener();\n\n svgEditor.storagePromptState = 'closed';\n updateCanvas(true);\n } else if (!noStorageOnLoad || forceStorage) {\n setupBeforeUnloadListener();\n }\n }\n };\n }\n};\n"],"names":["name","init","$","svgEditor","this","svgCanvas","canvas","curConfig","emptyStorageOnDecline","noStorageOnLoad","forceStorage","storage","updateCanvas","replaceStoragePrompt","val","loc","top","location","href","includes","replace","n0","n1","amp","setSVGContentStorage","canvasName","setItem","removeItem","expireCookie","cookie","document","encodeURIComponent","setupBeforeUnloadListener","window","addEventListener","e","match","getSvgString","setConfig","no_save_warning","curPrefs","Object","entries","forEach","key","undefined","widget","setPreferenceForKey","loaded","langReady","importLocale","storagePrompt","URL","searchParams","get","confirmSetStorage","message","storagePrefsAndContent","storagePrefsOnly","storagePrefs","storageNoPrefsOrContent","storageNoPrefs","rememberLabel","rememberTooltip","options","unshift","value","text","oldContainerWidth","style","width","oldContainerMarginLeft","marginLeft","oldContentHeight","height","oldContainerHeight","storagePromptState","select","label","checked","tooltip","pref","response","keys"],"mappings":"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"}
\ No newline at end of file
diff --git a/dist/editor/extensions/ext-webappfind.js b/dist/editor/extensions/ext-webappfind.js
deleted file mode 100644
index 8b172339..00000000
--- a/dist/editor/extensions/ext-webappfind.js
+++ /dev/null
@@ -1,10 +0,0 @@
-function _AwaitValue(e){this.wrapped=e}function _AsyncGenerator(e){var n,t;function resume(n,t){try{var r=e[n](t),o=r.value,a=o instanceof _AwaitValue;Promise.resolve(a?o.wrapped:o).then((function(e){a?resume("return"===n?"return":"next",e):settle(r.done?"return":"normal",e)}),(function(e){resume("throw",e)}))}catch(e){settle("throw",e)}}function settle(e,r){switch(e){case"return":n.resolve({value:r,done:!0});break;case"throw":n.reject(r);break;default:n.resolve({value:r,done:!1})}(n=n.next)?resume(n.key,n.arg):t=null}this._invoke=function send(e,r){return new Promise((function(o,a){var i={key:e,arg:r,resolve:o,reject:a,next:null};t?t=t.next=i:(n=t=i,resume(e,r))}))},"function"!=typeof e.return&&(this.return=void 0)}function asyncGeneratorStep(e,n,t,r,o,a,i){try{var c=e[a](i),u=c.value}catch(e){return void t(e)}c.done?n(u):Promise.resolve(u).then(r,o)}"function"==typeof Symbol&&Symbol.asyncIterator&&(_AsyncGenerator.prototype[Symbol.asyncIterator]=function(){return this}),_AsyncGenerator.prototype.next=function(e){return this._invoke("next",e)},_AsyncGenerator.prototype.throw=function(e){return this._invoke("throw",e)},_AsyncGenerator.prototype.return=function(e){return this._invoke("return",e)};
-/**
-* Depends on Firefox add-on and executables from
-* {@link https://github.com/brettz9/webappfind}.
-* @author Brett Zamir
-* @license MIT
-* @todo See WebAppFind Readme for SVG-related todos
-*/
-var e={name:"webappfind",init:function init(e){var n=this;return function _asyncToGenerator(e){return function(){var n=this,t=arguments;return new Promise((function(r,o){var a=e.apply(n,t);function _next(e){asyncGeneratorStep(a,r,o,_next,_throw,"next",e)}function _throw(e){asyncGeneratorStep(a,r,o,_next,_throw,"throw",e)}_next(void 0)}))}}(regeneratorRuntime.mark((function _callee(){var t,r,o,a,i,c,u,s;return regeneratorRuntime.wrap((function _callee$(p){for(;;)switch(p.prev=p.next){case 0:return t=e.importLocale,r=e.$,p.next=3,t();case 3:return o=p.sent,a=n,"read",c=["read",i="save"],n.canvas.bind("message",(function(e,n){var t,o,i=n.data,s=n.origin;try{var p=i.webappfind;if(t=p.type,u=p.pathID,o=p.content,s!==location.origin||c.includes(t))return}catch(e){return}switch(t){case"view":a.loadFromString(o);break;case"save-end":r.alert("save complete for pathID ".concat(u,"!"));break;default:throw new Error("Unexpected WebAppFind event type")}})),s=[{id:"webappfind_save",icon:"webappfind.png",type:"app_menu",position:4,events:{click:function click(){u&&window.postMessage({webappfind:{type:i,pathID:u,content:a.canvas.getSvgString()}},"null"===window.location.origin?"*":window.location.origin)}}}],p.abrupt("return",{name:o.name,svgicons:"webappfind-icon.svg",buttons:o.buttons.map((function(e,n){return Object.assign(s[n],e)}))});case 9:case"end":return p.stop()}}),_callee)})))()}};export default e;
-//# sourceMappingURL=ext-webappfind.js.map
diff --git a/dist/editor/extensions/ext-webappfind.js.map b/dist/editor/extensions/ext-webappfind.js.map
deleted file mode 100644
index 51dfbf6d..00000000
--- a/dist/editor/extensions/ext-webappfind.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"ext-webappfind.js","sources":["../../../src/editor/extensions/ext-webappfind.js"],"sourcesContent":["/**\n* Depends on Firefox add-on and executables from\n* {@link https://github.com/brettz9/webappfind}.\n* @author Brett Zamir\n* @license MIT\n* @todo See WebAppFind Readme for SVG-related todos\n*/\n\nexport default {\n name: 'webappfind',\n async init ({importLocale, $}) {\n const strings = await importLocale();\n const svgEditor = this;\n const saveMessage = 'save',\n readMessage = 'read',\n excludedMessages = [readMessage, saveMessage];\n\n let pathID;\n this.canvas.bind(\n 'message',\n /**\n * @param {external:Window} win\n * @param {PlainObject} info\n * @param {module:svgcanvas.SvgCanvas#event:message} info.data\n * @param {string} info.origin\n * @listens module:svgcanvas.SvgCanvas#event:message\n * @throws {Error} Unexpected event type\n * @returns {void}\n */\n (win, {data, origin}) => { // eslint-disable-line no-shadow\n // console.log('data, origin', data, origin);\n let type, content;\n try {\n ({type, pathID, content} = data.webappfind); // May throw if data is not an object\n if (origin !== location.origin || // We are only interested in a message sent as though within this URL by our browser add-on\n excludedMessages.includes(type) // Avoid our post below (other messages might be possible in the future which may also need to be excluded if your subsequent code makes assumptions on the type of message this is)\n ) {\n return;\n }\n } catch (err) {\n return;\n }\n\n switch (type) {\n case 'view':\n // Populate the contents\n svgEditor.loadFromString(content);\n\n /* if ($('#tool_save_file')) {\n $('#tool_save_file').disabled = false;\n } */\n break;\n case 'save-end':\n $.alert(`save complete for pathID ${pathID}!`);\n break;\n default:\n throw new Error('Unexpected WebAppFind event type');\n }\n }\n );\n\n /*\n window.postMessage({\n webappfind: {\n type: readMessage\n }\n }, window.location.origin === 'null'\n // Avoid \"null\" string error for `file:` protocol (even though\n // file protocol not currently supported by Firefox)\n ? '*'\n : window.location.origin\n );\n */\n const buttons = [{\n id: 'webappfind_save', //\n icon: 'webappfind.png',\n type: 'app_menu',\n position: 4, // Before 0-based index position 4 (after the regular \"Save Image (S)\")\n events: {\n click () {\n if (!pathID) { // Not ready yet as haven't received first payload\n return;\n }\n window.postMessage(\n {\n webappfind: {\n type: saveMessage,\n pathID,\n content: svgEditor.canvas.getSvgString()\n }\n }, window.location.origin === 'null'\n // Avoid \"null\" string error for `file:` protocol (even\n // though file protocol not currently supported by add-on)\n ? '*'\n : window.location.origin\n );\n }\n }\n }];\n\n return {\n name: strings.name,\n svgicons: 'webappfind-icon.svg',\n buttons: strings.buttons.map((button, i) => {\n return Object.assign(buttons[i], button);\n })\n };\n }\n};\n"],"names":["name","init","importLocale","$","strings","svgEditor","_this","excludedMessages","saveMessage","canvas","bind","win","type","content","data","origin","webappfind","pathID","location","includes","err","loadFromString","alert","Error","buttons","id","icon","position","events","click","window","postMessage","getSvgString","svgicons","map","button","i","Object","assign"],"mappings":";;;;;;;;AAQA,MAAe,CACbA,KAAM,aACAC,6dAAOC,IAAAA,aAAcC,IAAAA,WACHD,kBAAhBE,SACAC,EAAYC,EAEF,OACdC,EAAmB,CADL,OADVC,EAAc,QAKpBF,EAAKG,OAAOC,KACV,oBAUCC,SAEKC,EAAMC,EAFLC,IAAAA,KAAMC,IAAAA,iBAIkBD,EAAKE,cAA9BJ,IAAAA,KAAMK,IAAAA,OAAQJ,IAAAA,QACZE,IAAWG,SAASH,QACpBR,EAAiBY,SAASP,UAI9B,MAAOQ,iBAIDR,OACH,OAEHP,EAAUgB,eAAeR,aAMtB,WACHV,EAAEmB,yCAAkCL,4BAG9B,IAAIM,MAAM,wCAiBhBC,EAAU,CAAC,CACfC,GAAI,kBACJC,KAAM,iBACNd,KAAM,WACNe,SAAU,EACVC,OAAQ,CACNC,uBACOZ,GAGLa,OAAOC,YACL,CACEf,WAAY,CACVJ,KAAMJ,EACNS,OAAAA,EACAJ,QAASR,EAAUI,OAAOuB,iBAEA,SAA3BF,OAAOZ,SAASH,OAGf,IACAe,OAAOZ,SAASH,8BAMrB,CACLf,KAAMI,EAAQJ,KACdiC,SAAU,sBACVT,QAASpB,EAAQoB,QAAQU,KAAI,SAACC,EAAQC,UAC7BC,OAAOC,OAAOd,EAAQY,GAAID"}
\ No newline at end of file
diff --git a/dist/editor/extensions/ext-webappfind/ext-webappfind.js b/dist/editor/extensions/ext-webappfind/ext-webappfind.js
new file mode 100644
index 00000000..605ee331
--- /dev/null
+++ b/dist/editor/extensions/ext-webappfind/ext-webappfind.js
@@ -0,0 +1,10 @@
+function asyncGeneratorStep(e,n,t,r,a,o,i){try{var c=e[o](i),s=c.value}catch(e){return void t(e)}c.done?n(s):Promise.resolve(s).then(r,a)}
+/**
+* Depends on Firefox add-on and executables from
+* {@link https://github.com/brettz9/webappfind}.
+* @author Brett Zamir
+* @license MIT
+* @todo See WebAppFind Readme for SVG-related todos
+*/
+var e={name:"webappfind",init:function init(e){var n=this;return function _asyncToGenerator(e){return function(){var n=this,t=arguments;return new Promise((function(r,a){var o=e.apply(n,t);function _next(e){asyncGeneratorStep(o,r,a,_next,_throw,"next",e)}function _throw(e){asyncGeneratorStep(o,r,a,_next,_throw,"throw",e)}_next(void 0)}))}}(regeneratorRuntime.mark((function _callee(){var t,r,a,o,i,c,s,p;return regeneratorRuntime.wrap((function _callee$(u){for(;;)switch(u.prev=u.next){case 0:return t=e.$,r=n,u.next=4,import("./locale/".concat(r.curPrefs.lang,".js"));case 4:return a=u.sent,o=a.default,"read",c=["read",i="save"],n.canvas.bind("message",(function(e,n){var a,o,i=n.data,p=n.origin;try{var u=i.webappfind;if(a=u.type,s=u.pathID,o=u.content,p!==location.origin||c.includes(a))return}catch(e){return}switch(a){case"view":r.loadFromString(o);break;case"save-end":t.alert("save complete for pathID ".concat(s,"!"));break;default:throw new Error("Unexpected WebAppFind event type")}})),p=[{id:"webappfind_save",icon:"webappfind.png",type:"app_menu",position:4,events:{click:function click(){s&&window.postMessage({webappfind:{type:i,pathID:s,content:r.canvas.getSvgString()}},"null"===window.location.origin?"*":window.location.origin)}}}],u.abrupt("return",{name:o.name,svgicons:"webappfind-icon.svg",buttons:o.buttons.map((function(e,n){return Object.assign(p[n],e)}))});case 10:case"end":return u.stop()}}),_callee)})))()}};export default e;
+//# sourceMappingURL=ext-webappfind.js.map
diff --git a/dist/editor/extensions/ext-webappfind/ext-webappfind.js.map b/dist/editor/extensions/ext-webappfind/ext-webappfind.js.map
new file mode 100644
index 00000000..9649b0db
--- /dev/null
+++ b/dist/editor/extensions/ext-webappfind/ext-webappfind.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"ext-webappfind.js","sources":["../../../../src/editor/extensions/ext-webappfind/ext-webappfind.js"],"sourcesContent":["/**\n* Depends on Firefox add-on and executables from\n* {@link https://github.com/brettz9/webappfind}.\n* @author Brett Zamir\n* @license MIT\n* @todo See WebAppFind Readme for SVG-related todos\n*/\n\nexport default {\n name: 'webappfind',\n async init ({$}) {\n const svgEditor = this;\n // eslint-disable-next-line node/no-unsupported-features/es-syntax\n const {default: strings} = await import(`./locale/${svgEditor.curPrefs.lang}.js`);\n const saveMessage = 'save',\n readMessage = 'read',\n excludedMessages = [readMessage, saveMessage];\n\n let pathID;\n this.canvas.bind(\n 'message',\n /**\n * @param {external:Window} win\n * @param {PlainObject} info\n * @param {module:svgcanvas.SvgCanvas#event:message} info.data\n * @param {string} info.origin\n * @listens module:svgcanvas.SvgCanvas#event:message\n * @throws {Error} Unexpected event type\n * @returns {void}\n */\n (win, {data, origin}) => { // eslint-disable-line no-shadow\n // console.log('data, origin', data, origin);\n let type, content;\n try {\n ({type, pathID, content} = data.webappfind); // May throw if data is not an object\n if (origin !== location.origin || // We are only interested in a message sent as though within this URL by our browser add-on\n excludedMessages.includes(type) // Avoid our post below (other messages might be possible in the future which may also need to be excluded if your subsequent code makes assumptions on the type of message this is)\n ) {\n return;\n }\n } catch (err) {\n return;\n }\n\n switch (type) {\n case 'view':\n // Populate the contents\n svgEditor.loadFromString(content);\n\n /* if ($('#tool_save_file')) {\n $('#tool_save_file').disabled = false;\n } */\n break;\n case 'save-end':\n $.alert(`save complete for pathID ${pathID}!`);\n break;\n default:\n throw new Error('Unexpected WebAppFind event type');\n }\n }\n );\n\n /*\n window.postMessage({\n webappfind: {\n type: readMessage\n }\n }, window.location.origin === 'null'\n // Avoid \"null\" string error for `file:` protocol (even though\n // file protocol not currently supported by Firefox)\n ? '*'\n : window.location.origin\n );\n */\n const buttons = [{\n id: 'webappfind_save', //\n icon: 'webappfind.png',\n type: 'app_menu',\n position: 4, // Before 0-based index position 4 (after the regular \"Save Image (S)\")\n events: {\n click () {\n if (!pathID) { // Not ready yet as haven't received first payload\n return;\n }\n window.postMessage(\n {\n webappfind: {\n type: saveMessage,\n pathID,\n content: svgEditor.canvas.getSvgString()\n }\n }, window.location.origin === 'null'\n // Avoid \"null\" string error for `file:` protocol (even\n // though file protocol not currently supported by add-on)\n ? '*'\n : window.location.origin\n );\n }\n }\n }];\n\n return {\n name: strings.name,\n svgicons: 'webappfind-icon.svg',\n buttons: strings.buttons.map((button, i) => {\n return Object.assign(buttons[i], button);\n })\n };\n }\n};\n"],"names":["name","init","$","svgEditor","_this","import","curPrefs","lang","strings","excludedMessages","saveMessage","canvas","bind","win","type","content","data","origin","webappfind","pathID","location","includes","err","loadFromString","alert","Error","buttons","id","icon","position","events","click","window","postMessage","getSvgString","svgicons","map","button","i","Object","assign"],"mappings":";;;;;;;;AAQA,MAAe,CACbA,KAAM,aACAC,6dAAOC,IAAAA,EACLC,EAAYC,WAEeC,0BAAmBF,EAAUG,SAASC,oCAAvDC,YAEA,OACdC,EAAmB,CADL,OADVC,EAAc,QAKpBN,EAAKO,OAAOC,KACV,oBAUCC,SAEKC,EAAMC,EAFLC,IAAAA,KAAMC,IAAAA,iBAIkBD,EAAKE,cAA9BJ,IAAAA,KAAMK,IAAAA,OAAQJ,IAAAA,QACZE,IAAWG,SAASH,QACpBR,EAAiBY,SAASP,UAI9B,MAAOQ,iBAIDR,OACH,OAEHX,EAAUoB,eAAeR,aAMtB,WACHb,EAAEsB,yCAAkCL,4BAG9B,IAAIM,MAAM,wCAiBhBC,EAAU,CAAC,CACfC,GAAI,kBACJC,KAAM,iBACNd,KAAM,WACNe,SAAU,EACVC,OAAQ,CACNC,uBACOZ,GAGLa,OAAOC,YACL,CACEf,WAAY,CACVJ,KAAMJ,EACNS,OAAAA,EACAJ,QAASZ,EAAUQ,OAAOuB,iBAEA,SAA3BF,OAAOZ,SAASH,OAGf,IACAe,OAAOZ,SAASH,8BAMrB,CACLjB,KAAMQ,EAAQR,KACdmC,SAAU,sBACVT,QAASlB,EAAQkB,QAAQU,KAAI,SAACC,EAAQC,UAC7BC,OAAOC,OAAOd,EAAQY,GAAID"}
\ No newline at end of file
diff --git a/dist/editor/extensions/ext-xdomain-messaging.js b/dist/editor/extensions/ext-xdomain-messaging.js
deleted file mode 100644
index 1d3b7600..00000000
--- a/dist/editor/extensions/ext-xdomain-messaging.js
+++ /dev/null
@@ -1,2 +0,0 @@
-function _typeof(e){return(_typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function _AwaitValue(e){this.wrapped=e}function _AsyncGenerator(e){var r,t;function resume(r,t){try{var n=e[r](t),o=n.value,a=o instanceof _AwaitValue;Promise.resolve(a?o.wrapped:o).then((function(e){a?resume("return"===r?"return":"next",e):settle(n.done?"return":"normal",e)}),(function(e){resume("throw",e)}))}catch(e){settle("throw",e)}}function settle(e,n){switch(e){case"return":r.resolve({value:n,done:!0});break;case"throw":r.reject(n);break;default:r.resolve({value:n,done:!1})}(r=r.next)?resume(r.key,r.arg):t=null}this._invoke=function send(e,n){return new Promise((function(o,a){var i={key:e,arg:n,resolve:o,reject:a,next:null};t?t=t.next=i:(r=t=i,resume(e,n))}))},"function"!=typeof e.return&&(this.return=void 0)}function _toConsumableArray(e){return function _arrayWithoutHoles(e){if(Array.isArray(e))return _arrayLikeToArray(e)}(e)||_iterableToArray(e)||_unsupportedIterableToArray(e)||function _nonIterableSpread(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function _iterableToArray(e){if("undefined"!=typeof Symbol&&Symbol.iterator in Object(e))return Array.from(e)}function _unsupportedIterableToArray(e,r){if(e){if("string"==typeof e)return _arrayLikeToArray(e,r);var t=Object.prototype.toString.call(e).slice(8,-1);return"Object"===t&&e.constructor&&(t=e.constructor.name),"Map"===t||"Set"===t?Array.from(e):"Arguments"===t||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t)?_arrayLikeToArray(e,r):void 0}}function _arrayLikeToArray(e,r){(null==r||r>e.length)&&(r=e.length);for(var t=0,n=new Array(r);tr.length)&&(t=r.length);for(var e=0,o=new Array(t);eer.length)&&(tr=er.length);for(var rr=0,nr=new Array(tr);rr=er.length?{done:!0}:{done:!1,value:er[nr++]}},e:function(er){throw er},f:F}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var ar,ir=!0,or=!1;return{s:function(){rr=er[Symbol.iterator]()},n:function(){var er=rr.next();return ir=er.done,er},e:function(er){or=!0,ar=er},f:function(){try{ir||null==rr.return||rr.return()}finally{if(or)throw ar}}}}var er="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{};function createCommonjsModule(er,tr,rr){return er(rr={path:tr,exports:{},require:function(er,tr){return function commonjsRequire(){throw new Error("Dynamic requires are not currently supported by @rollup/plugin-commonjs")}(null==tr&&rr.path)}},rr.exports),rr.exports}var tr=function check(er){return er&&er.Math==Math&&er},rr=tr("object"==("undefined"==typeof globalThis?"undefined":_typeof(globalThis))&&globalThis)||tr("object"==("undefined"==typeof window?"undefined":_typeof(window))&&window)||tr("object"==("undefined"==typeof self?"undefined":_typeof(self))&&self)||tr("object"==_typeof(er)&&er)||Function("return this")(),nr=function fails(er){try{return!!er()}catch(er){return!0}},ar=!nr((function(){return 7!=Object.defineProperty({},1,{get:function get(){return 7}})[1]})),ir={}.propertyIsEnumerable,or=Object.getOwnPropertyDescriptor,sr={f:or&&!ir.call({1:2},1)?function propertyIsEnumerable(er){var tr=or(this,er);return!!tr&&tr.enumerable}:ir},lr=function createPropertyDescriptor(er,tr){return{enumerable:!(1&er),configurable:!(2&er),writable:!(4&er),value:tr}},cr={}.toString,ur=function classofRaw(er){return cr.call(er).slice(8,-1)},dr="".split,hr=nr((function(){return!Object("z").propertyIsEnumerable(0)}))?function(er){return"String"==ur(er)?dr.call(er,""):Object(er)}:Object,pr=function requireObjectCoercible(er){if(null==er)throw TypeError("Can't call method on "+er);return er},Ar=function toIndexedObject(er){return hr(pr(er))},fr=function isObject(er){return"object"===_typeof(er)?null!==er:"function"==typeof er},gr=function toPrimitive(er,tr){if(!fr(er))return er;var rr,nr;if(tr&&"function"==typeof(rr=er.toString)&&!fr(nr=rr.call(er)))return nr;if("function"==typeof(rr=er.valueOf)&&!fr(nr=rr.call(er)))return nr;if(!tr&&"function"==typeof(rr=er.toString)&&!fr(nr=rr.call(er)))return nr;throw TypeError("Can't convert object to primitive value")},mr={}.hasOwnProperty,_r=function has(er,tr){return mr.call(er,tr)},vr=rr.document,yr=fr(vr)&&fr(vr.createElement),br=function documentCreateElement(er){return yr?vr.createElement(er):{}},wr=!ar&&!nr((function(){return 7!=Object.defineProperty(br("div"),"a",{get:function get(){return 7}}).a})),xr=Object.getOwnPropertyDescriptor,kr={f:ar?xr:function getOwnPropertyDescriptor(er,tr){if(er=Ar(er),tr=gr(tr,!0),wr)try{return xr(er,tr)}catch(er){}if(_r(er,tr))return lr(!sr.f.call(er,tr),er[tr])}},Sr=function anObject(er){if(!fr(er))throw TypeError(String(er)+" is not an object");return er},Cr=Object.defineProperty,Br={f:ar?Cr:function defineProperty(er,tr,rr){if(Sr(er),tr=gr(tr,!0),Sr(rr),wr)try{return Cr(er,tr,rr)}catch(er){}if("get"in rr||"set"in rr)throw TypeError("Accessors not supported");return"value"in rr&&(er[tr]=rr.value),er}},Er=ar?function(er,tr,rr){return Br.f(er,tr,lr(1,rr))}:function(er,tr,rr){return er[tr]=rr,er},Nr=function setGlobal(er,tr){try{Er(rr,er,tr)}catch(nr){rr[er]=tr}return tr},Lr=rr["__core-js_shared__"]||Nr("__core-js_shared__",{}),Tr=Function.toString;"function"!=typeof Lr.inspectSource&&(Lr.inspectSource=function(er){return Tr.call(er)});var Pr,Fr,Ur,Ir=Lr.inspectSource,Rr=rr.WeakMap,Mr="function"==typeof Rr&&/native code/.test(Ir(Rr)),Qr=createCommonjsModule((function(er){(er.exports=function(er,tr){return Lr[er]||(Lr[er]=void 0!==tr?tr:{})})("versions",[]).push({version:"3.6.5",mode:"global",copyright:"© 2020 Denis Pushkarev (zloirock.ru)"})})),Or=0,Dr=Math.random(),jr=function uid(er){return"Symbol("+String(void 0===er?"":er)+")_"+(++Or+Dr).toString(36)},Hr=Qr("keys"),Gr=function sharedKey(er){return Hr[er]||(Hr[er]=jr(er))},zr={},Vr=rr.WeakMap;if(Mr){var Kr=new Vr,qr=Kr.get,Wr=Kr.has,Xr=Kr.set;Pr=function set(er,tr){return Xr.call(Kr,er,tr),tr},Fr=function get(er){return qr.call(Kr,er)||{}},Ur=function has(er){return Wr.call(Kr,er)}}else{var Yr=Gr("state");zr[Yr]=!0,Pr=function set(er,tr){return Er(er,Yr,tr),tr},Fr=function get(er){return _r(er,Yr)?er[Yr]:{}},Ur=function has$1(er){return _r(er,Yr)}}var Jr,$r={set:Pr,get:Fr,has:Ur,enforce:function enforce(er){return Ur(er)?Fr(er):Pr(er,{})},getterFor:function getterFor(er){return function(tr){var rr;if(!fr(tr)||(rr=Fr(tr)).type!==er)throw TypeError("Incompatible receiver, "+er+" required");return rr}}},Zr=createCommonjsModule((function(er){var tr=$r.get,nr=$r.enforce,ar=String(String).split("String");(er.exports=function(er,tr,ir,or){var sr=!!or&&!!or.unsafe,lr=!!or&&!!or.enumerable,cr=!!or&&!!or.noTargetGet;"function"==typeof ir&&("string"!=typeof tr||_r(ir,"name")||Er(ir,"name",tr),nr(ir).source=ar.join("string"==typeof tr?tr:"")),er!==rr?(sr?!cr&&er[tr]&&(lr=!0):delete er[tr],lr?er[tr]=ir:Er(er,tr,ir)):lr?er[tr]=ir:Nr(tr,ir)})(Function.prototype,"toString",(function toString(){return"function"==typeof this&&tr(this).source||Ir(this)}))})),Tn=rr,Un=function aFunction(er){return"function"==typeof er?er:void 0},Qn=function getBuiltIn(er,tr){return arguments.length<2?Un(Tn[er])||Un(rr[er]):Tn[er]&&Tn[er][tr]||rr[er]&&rr[er][tr]},Dn=Math.ceil,Hn=Math.floor,Gn=function toInteger(er){return isNaN(er=+er)?0:(er>0?Hn:Dn)(er)},zn=Math.min,Vn=function toLength(er){return er>0?zn(Gn(er),9007199254740991):0},Kn=Math.max,Wn=Math.min,Xn=function toAbsoluteIndex(er,tr){var rr=Gn(er);return rr<0?Kn(rr+tr,0):Wn(rr,tr)},Yn=function createMethod(er){return function(tr,rr,nr){var ar,ir=Ar(tr),or=Vn(ir.length),sr=Xn(nr,or);if(er&&rr!=rr){for(;or>sr;)if((ar=ir[sr++])!=ar)return!0}else for(;or>sr;sr++)if((er||sr in ir)&&ir[sr]===rr)return er||sr||0;return!er&&-1}},Jn={includes:Yn(!0),indexOf:Yn(!1)},$n=Jn.indexOf,Zn=function objectKeysInternal(er,tr){var rr,nr=Ar(er),ar=0,ir=[];for(rr in nr)!_r(zr,rr)&&_r(nr,rr)&&ir.push(rr);for(;tr.length>ar;)_r(nr,rr=tr[ar++])&&(~$n(ir,rr)||ir.push(rr));return ir},ea=["constructor","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","toLocaleString","toString","valueOf"],ta=ea.concat("length","prototype"),ra={f:Object.getOwnPropertyNames||function getOwnPropertyNames(er){return Zn(er,ta)}},na={f:Object.getOwnPropertySymbols},aa=Qn("Reflect","ownKeys")||function ownKeys(er){var tr=ra.f(Sr(er)),rr=na.f;return rr?tr.concat(rr(er)):tr},ia=function copyConstructorProperties(er,tr){for(var rr=aa(tr),nr=Br.f,ar=kr.f,ir=0;irir;)Br.f(er,rr=nr[ir++],tr[rr]);return er},ba=Qn("document","documentElement"),wa=Gr("IE_PROTO"),xa=function EmptyConstructor(){},ka=function scriptTag(er){return"