| Current Path : /proc/thread-self/cwd/static/adminhtml/Magento/backend/it_IT/js/bundle/ |
| Current File : //proc/thread-self/cwd/static/adminhtml/Magento/backend/it_IT/js/bundle/bundle4.js |
require.config({"config": {
"jsbuild":{"Amasty_Rewards/amcharts/plugins/export/libs/fabric.js/fabric.min.js":"var fabric=fabric||{version:\"1.6.2\"};\"undefined\"!=typeof exports&&(exports.fabric=fabric),\"undefined\"!=typeof document&&\"undefined\"!=typeof window?(fabric.document=document,fabric.window=window,window.fabric=fabric):(fabric.document=require(\"jsdom\").jsdom(\"<!DOCTYPE html><html><head></head><body></body></html>\"),fabric.document.createWindow?fabric.window=fabric.document.createWindow():fabric.window=fabric.document.parentWindow),fabric.isTouchSupported=\"ontouchstart\"in fabric.document.documentElement,fabric.isLikelyNode=\"undefined\"!=typeof Buffer&&\"undefined\"==typeof window,fabric.SHARED_ATTRIBUTES=[\"display\",\"transform\",\"fill\",\"fill-opacity\",\"fill-rule\",\"opacity\",\"stroke\",\"stroke-dasharray\",\"stroke-linecap\",\"stroke-linejoin\",\"stroke-miterlimit\",\"stroke-opacity\",\"stroke-width\",\"id\"],fabric.DPI=96,fabric.reNum=\"(?:[-+]?(?:\\\\d+|\\\\d*\\\\.\\\\d+)(?:e[-+]?\\\\d+)?)\",fabric.fontPaths={},fabric.devicePixelRatio=fabric.window.devicePixelRatio||fabric.window.webkitDevicePixelRatio||fabric.window.mozDevicePixelRatio||1,function(){function t(t,e){if(this.__eventListeners[t]){var i=this.__eventListeners[t];e?i[i.indexOf(e)]=!1:fabric.util.array.fill(i,!1)}}function e(t,e){if(this.__eventListeners||(this.__eventListeners={}),1===arguments.length)for(var i in t)this.on(i,t[i]);else this.__eventListeners[t]||(this.__eventListeners[t]=[]),this.__eventListeners[t].push(e);return this}function i(e,i){if(this.__eventListeners){if(0===arguments.length)for(e in this.__eventListeners)t.call(this,e);else if(1===arguments.length&&\"object\"==typeof arguments[0])for(var r in e)t.call(this,r,e[r]);else t.call(this,e,i);return this}}function r(t,e){if(this.__eventListeners){var i=this.__eventListeners[t];if(i){for(var r=0,n=i.length;n>r;r++)i[r]&&i[r].call(this,e||{});return this.__eventListeners[t]=i.filter(function(t){return t!==!1}),this}}}fabric.Observable={observe:e,stopObserving:i,fire:r,on:e,off:i,trigger:r}}(),fabric.Collection={add:function(){this._objects.push.apply(this._objects,arguments);for(var t=0,e=arguments.length;e>t;t++)this._onObjectAdded(arguments[t]);return this.renderOnAddRemove&&this.renderAll(),this},insertAt:function(t,e,i){var r=this.getObjects();return i?r[e]=t:r.splice(e,0,t),this._onObjectAdded(t),this.renderOnAddRemove&&this.renderAll(),this},remove:function(){for(var t,e=this.getObjects(),i=0,r=arguments.length;r>i;i++)t=e.indexOf(arguments[i]),-1!==t&&(e.splice(t,1),this._onObjectRemoved(arguments[i]));return this.renderOnAddRemove&&this.renderAll(),this},forEachObject:function(t,e){for(var i=this.getObjects(),r=i.length;r--;)t.call(e,i[r],r,i);return this},getObjects:function(t){return\"undefined\"==typeof t?this._objects:this._objects.filter(function(e){return e.type===t})},item:function(t){return this.getObjects()[t]},isEmpty:function(){return 0===this.getObjects().length},size:function(){return this.getObjects().length},contains:function(t){return this.getObjects().indexOf(t)>-1},complexity:function(){return this.getObjects().reduce(function(t,e){return t+=e.complexity?e.complexity():0},0)}},function(t){var e=Math.sqrt,i=Math.atan2,r=Math.pow,n=Math.abs,s=Math.PI/180;fabric.util={removeFromArray:function(t,e){var i=t.indexOf(e);return-1!==i&&t.splice(i,1),t},getRandomInt:function(t,e){return Math.floor(Math.random()*(e-t+1))+t},degreesToRadians:function(t){return t*s},radiansToDegrees:function(t){return t/s},rotatePoint:function(t,e,i){t.subtractEquals(e);var r=fabric.util.rotateVector(t,i);return new fabric.Point(r.x,r.y).addEquals(e)},rotateVector:function(t,e){var i=Math.sin(e),r=Math.cos(e),n=t.x*r-t.y*i,s=t.x*i+t.y*r;return{x:n,y:s}},transformPoint:function(t,e,i){return i?new fabric.Point(e[0]*t.x+e[2]*t.y,e[1]*t.x+e[3]*t.y):new fabric.Point(e[0]*t.x+e[2]*t.y+e[4],e[1]*t.x+e[3]*t.y+e[5])},makeBoundingBoxFromPoints:function(t){var e=[t[0].x,t[1].x,t[2].x,t[3].x],i=fabric.util.array.min(e),r=fabric.util.array.max(e),n=Math.abs(i-r),s=[t[0].y,t[1].y,t[2].y,t[3].y],o=fabric.util.array.min(s),a=fabric.util.array.max(s),h=Math.abs(o-a);return{left:i,top:o,width:n,height:h}},invertTransform:function(t){var e=1/(t[0]*t[3]-t[1]*t[2]),i=[e*t[3],-e*t[1],-e*t[2],e*t[0]],r=fabric.util.transformPoint({x:t[4],y:t[5]},i,!0);return i[4]=-r.x,i[5]=-r.y,i},toFixed:function(t,e){return parseFloat(Number(t).toFixed(e))},parseUnit:function(t,e){var i=/\\D{0,2}$/.exec(t),r=parseFloat(t);switch(e||(e=fabric.Text.DEFAULT_SVG_FONT_SIZE),i[0]){case\"mm\":return r*fabric.DPI/25.4;case\"cm\":return r*fabric.DPI/2.54;case\"in\":return r*fabric.DPI;case\"pt\":return r*fabric.DPI/72;case\"pc\":return r*fabric.DPI/72*12;case\"em\":return r*e;default:return r}},falseFunction:function(){return!1},getKlass:function(t,e){return t=fabric.util.string.camelize(t.charAt(0).toUpperCase()+t.slice(1)),fabric.util.resolveNamespace(e)[t]},resolveNamespace:function(e){if(!e)return fabric;for(var i=e.split(\".\"),r=i.length,n=t||fabric.window,s=0;r>s;++s)n=n[i[s]];return n},loadImage:function(t,e,i,r){if(!t)return void(e&&e.call(i,t));var n=fabric.util.createImage();n.onload=function(){e&&e.call(i,n),n=n.onload=n.onerror=null},n.onerror=function(){fabric.log(\"Error loading \"+n.src),e&&e.call(i,null,!0),n=n.onload=n.onerror=null},0!==t.indexOf(\"data\")&&r&&(n.crossOrigin=r),n.src=t},enlivenObjects:function(t,e,i,r){function n(){++o===a&&e&&e(s)}t=t||[];var s=[],o=0,a=t.length;return a?void t.forEach(function(t,e){if(!t||!t.type)return void n();var o=fabric.util.getKlass(t.type,i);o.async?o.fromObject(t,function(i,o){o||(s[e]=i,r&&r(t,s[e])),n()}):(s[e]=o.fromObject(t),r&&r(t,s[e]),n())}):void(e&&e(s))},groupSVGElements:function(t,e,i){var r;return r=new fabric.PathGroup(t,e),\"undefined\"!=typeof i&&r.setSourcePath(i),r},populateWithProperties:function(t,e,i){if(i&&\"[object Array]\"===Object.prototype.toString.call(i))for(var r=0,n=i.length;n>r;r++)i[r]in t&&(e[i[r]]=t[i[r]])},drawDashedLine:function(t,r,n,s,o,a){var h=s-r,c=o-n,l=e(h*h+c*c),u=i(c,h),f=a.length,d=0,g=!0;for(t.save(),t.translate(r,n),t.moveTo(0,0),t.rotate(u),r=0;l>r;)r+=a[d++%f],r>l&&(r=l),t[g?\"lineTo\":\"moveTo\"](r,0),g=!g;t.restore()},createCanvasElement:function(t){return t||(t=fabric.document.createElement(\"canvas\")),t.getContext||\"undefined\"==typeof G_vmlCanvasManager||G_vmlCanvasManager.initElement(t),t},createImage:function(){return fabric.isLikelyNode?new(require(\"canvas\").Image):fabric.document.createElement(\"img\")},createAccessors:function(t){for(var e=t.prototype,i=e.stateProperties.length;i--;){var r=e.stateProperties[i],n=r.charAt(0).toUpperCase()+r.slice(1),s=\"set\"+n,o=\"get\"+n;e[o]||(e[o]=function(t){return new Function('return this.get(\"'+t+'\")')}(r)),e[s]||(e[s]=function(t){return new Function(\"value\",'return this.set(\"'+t+'\", value)')}(r))}},clipContext:function(t,e){e.save(),e.beginPath(),t.clipTo(e),e.clip()},multiplyTransformMatrices:function(t,e,i){return[t[0]*e[0]+t[2]*e[1],t[1]*e[0]+t[3]*e[1],t[0]*e[2]+t[2]*e[3],t[1]*e[2]+t[3]*e[3],i?0:t[0]*e[4]+t[2]*e[5]+t[4],i?0:t[1]*e[4]+t[3]*e[5]+t[5]]},qrDecompose:function(t){var n=i(t[1],t[0]),o=r(t[0],2)+r(t[1],2),a=e(o),h=(t[0]*t[3]-t[2]*t[1])/a,c=i(t[0]*t[2]+t[1]*t[3],o);return{angle:n/s,scaleX:a,scaleY:h,skewX:c/s,skewY:0,translateX:t[4],translateY:t[5]}},customTransformMatrix:function(t,e,i){var r=[1,0,n(Math.tan(i*s)),1],o=[n(t),0,0,n(e)];return fabric.util.multiplyTransformMatrices(o,r,!0)},resetObjectTransform:function(t){t.scaleX=1,t.scaleY=1,t.skewX=0,t.skewY=0,t.flipX=!1,t.flipY=!1,t.setAngle(0)},getFunctionBody:function(t){return(String(t).match(/function[^{]*\\{([\\s\\S]*)\\}/)||{})[1]},isTransparent:function(t,e,i,r){r>0&&(e>r?e-=r:e=0,i>r?i-=r:i=0);for(var n=!0,s=t.getImageData(e,i,2*r||1,2*r||1),o=3,a=s.data.length;a>o;o+=4){var h=s.data[o];if(n=0>=h,n===!1)break}return s=null,n},parsePreserveAspectRatioAttribute:function(t){var e,i=\"meet\",r=\"Mid\",n=\"Mid\",s=t.split(\" \");return s&&s.length&&(i=s.pop(),\"meet\"!==i&&\"slice\"!==i?(e=i,i=\"meet\"):s.length&&(e=s.pop())),r=\"none\"!==e?e.slice(1,4):\"none\",n=\"none\"!==e?e.slice(5,8):\"none\",{meetOrSlice:i,alignX:r,alignY:n}}}}(\"undefined\"!=typeof exports?exports:this),function(){function t(t,r,s,o,h,c,l){var u=a.call(arguments);if(n[u])return n[u];var f=Math.PI,d=l*f/180,g=Math.sin(d),p=Math.cos(d),v=0,b=0;s=Math.abs(s),o=Math.abs(o);var m=-p*t*.5-g*r*.5,y=-p*r*.5+g*t*.5,_=s*s,x=o*o,S=y*y,C=m*m,w=_*x-_*S-x*C,O=0;if(0>w){var T=Math.sqrt(1-w/(_*x));s*=T,o*=T}else O=(h===c?-1:1)*Math.sqrt(w/(_*S+x*C));var k=O*s*y/o,j=-O*o*m/s,A=p*k-g*j+.5*t,M=g*k+p*j+.5*r,P=i(1,0,(m-k)/s,(y-j)/o),L=i((m-k)/s,(y-j)/o,(-m-k)/s,(-y-j)/o);0===c&&L>0?L-=2*f:1===c&&0>L&&(L+=2*f);for(var D=Math.ceil(Math.abs(L/f*2)),E=[],I=L/D,R=8/3*Math.sin(I/4)*Math.sin(I/4)/Math.sin(I/2),B=P+I,F=0;D>F;F++)E[F]=e(P,B,p,g,s,o,A,M,R,v,b),v=E[F][4],b=E[F][5],P=B,B+=I;return n[u]=E,E}function e(t,e,i,r,n,o,h,c,l,u,f){var d=a.call(arguments);if(s[d])return s[d];var g=Math.cos(t),p=Math.sin(t),v=Math.cos(e),b=Math.sin(e),m=i*n*v-r*o*b+h,y=r*n*v+i*o*b+c,_=u+l*(-i*n*p-r*o*g),x=f+l*(-r*n*p+i*o*g),S=m+l*(i*n*b+r*o*v),C=y+l*(r*n*b-i*o*v);return s[d]=[_,x,S,C,m,y],s[d]}function i(t,e,i,r){var n=Math.atan2(e,t),s=Math.atan2(r,i);return s>=n?s-n:2*Math.PI-(n-s)}function r(t,e,i,r,n,s,h,c){var l=a.call(arguments);if(o[l])return o[l];var u,f,d,g,p,v,b,m,y=Math.sqrt,_=Math.min,x=Math.max,S=Math.abs,C=[],w=[[],[]];f=6*t-12*i+6*n,u=-3*t+9*i-9*n+3*h,d=3*i-3*t;for(var O=0;2>O;++O)if(O>0&&(f=6*e-12*r+6*s,u=-3*e+9*r-9*s+3*c,d=3*r-3*e),S(u)<1e-12){if(S(f)<1e-12)continue;g=-d/f,g>0&&1>g&&C.push(g)}else b=f*f-4*d*u,0>b||(m=y(b),p=(-f+m)/(2*u),p>0&&1>p&&C.push(p),v=(-f-m)/(2*u),v>0&&1>v&&C.push(v));for(var T,k,j,A=C.length,M=A;A--;)g=C[A],j=1-g,T=j*j*j*t+3*j*j*g*i+3*j*g*g*n+g*g*g*h,w[0][A]=T,k=j*j*j*e+3*j*j*g*r+3*j*g*g*s+g*g*g*c,w[1][A]=k;w[0][M]=t,w[1][M]=e,w[0][M+1]=h,w[1][M+1]=c;var P=[{x:_.apply(null,w[0]),y:_.apply(null,w[1])},{x:x.apply(null,w[0]),y:x.apply(null,w[1])}];return o[l]=P,P}var n={},s={},o={},a=Array.prototype.join;fabric.util.drawArc=function(e,i,r,n){for(var s=n[0],o=n[1],a=n[2],h=n[3],c=n[4],l=n[5],u=n[6],f=[[],[],[],[]],d=t(l-i,u-r,s,o,h,c,a),g=0,p=d.length;p>g;g++)f[g][0]=d[g][0]+i,f[g][1]=d[g][1]+r,f[g][2]=d[g][2]+i,f[g][3]=d[g][3]+r,f[g][4]=d[g][4]+i,f[g][5]=d[g][5]+r,e.bezierCurveTo.apply(e,f[g])},fabric.util.getBoundsOfArc=function(e,i,n,s,o,a,h,c,l){for(var u=0,f=0,d=[],g=[],p=t(c-e,l-i,n,s,a,h,o),v=[[],[]],b=0,m=p.length;m>b;b++)d=r(u,f,p[b][0],p[b][1],p[b][2],p[b][3],p[b][4],p[b][5]),v[0].x=d[0].x+e,v[0].y=d[0].y+i,v[1].x=d[1].x+e,v[1].y=d[1].y+i,g.push(v[0]),g.push(v[1]),u=p[b][4],f=p[b][5];return g},fabric.util.getBoundsOfCurve=r}(),function(){function t(t,e){for(var i=s.call(arguments,2),r=[],n=0,o=t.length;o>n;n++)r[n]=i.length?t[n][e].apply(t[n],i):t[n][e].call(t[n]);return r}function e(t,e){return n(t,e,function(t,e){return t>=e})}function i(t,e){return n(t,e,function(t,e){return e>t})}function r(t,e){for(var i=t.length;i--;)t[i]=e;return t}function n(t,e,i){if(t&&0!==t.length){var r=t.length-1,n=e?t[r][e]:t[r];if(e)for(;r--;)i(t[r][e],n)&&(n=t[r][e]);else for(;r--;)i(t[r],n)&&(n=t[r]);return n}}var s=Array.prototype.slice;Array.prototype.indexOf||(Array.prototype.indexOf=function(t){if(void 0===this||null===this)throw new TypeError;var e=Object(this),i=e.length>>>0;if(0===i)return-1;var r=0;if(arguments.length>0&&(r=Number(arguments[1]),r!==r?r=0:0!==r&&r!==Number.POSITIVE_INFINITY&&r!==Number.NEGATIVE_INFINITY&&(r=(r>0||-1)*Math.floor(Math.abs(r)))),r>=i)return-1;for(var n=r>=0?r:Math.max(i-Math.abs(r),0);i>n;n++)if(n in e&&e[n]===t)return n;return-1}),Array.prototype.forEach||(Array.prototype.forEach=function(t,e){for(var i=0,r=this.length>>>0;r>i;i++)i in this&&t.call(e,this[i],i,this)}),Array.prototype.map||(Array.prototype.map=function(t,e){for(var i=[],r=0,n=this.length>>>0;n>r;r++)r in this&&(i[r]=t.call(e,this[r],r,this));return i}),Array.prototype.every||(Array.prototype.every=function(t,e){for(var i=0,r=this.length>>>0;r>i;i++)if(i in this&&!t.call(e,this[i],i,this))return!1;return!0}),Array.prototype.some||(Array.prototype.some=function(t,e){for(var i=0,r=this.length>>>0;r>i;i++)if(i in this&&t.call(e,this[i],i,this))return!0;return!1}),Array.prototype.filter||(Array.prototype.filter=function(t,e){for(var i,r=[],n=0,s=this.length>>>0;s>n;n++)n in this&&(i=this[n],t.call(e,i,n,this)&&r.push(i));return r}),Array.prototype.reduce||(Array.prototype.reduce=function(t){var e,i=this.length>>>0,r=0;if(arguments.length>1)e=arguments[1];else for(;;){if(r in this){e=this[r++];break}if(++r>=i)throw new TypeError}for(;i>r;r++)r in this&&(e=t.call(null,e,this[r],r,this));return e}),fabric.util.array={fill:r,invoke:t,min:i,max:e}}(),function(){function t(t,e){for(var i in e)t[i]=e[i];return t}function e(e){return t({},e)}fabric.util.object={extend:t,clone:e}}(),function(){function t(t){return t.replace(/-+(.)?/g,function(t,e){return e?e.toUpperCase():\"\"})}function e(t,e){return t.charAt(0).toUpperCase()+(e?t.slice(1):t.slice(1).toLowerCase())}function i(t){return t.replace(/&/g,\"&\").replace(/\"/g,\""\").replace(/'/g,\"'\").replace(/</g,\"<\").replace(/>/g,\">\")}String.prototype.trim||(String.prototype.trim=function(){return this.replace(/^[\\s\\xA0]+/,\"\").replace(/[\\s\\xA0]+$/,\"\")}),fabric.util.string={camelize:t,capitalize:e,escapeXml:i}}(),function(){var t=Array.prototype.slice,e=Function.prototype.apply,i=function(){};Function.prototype.bind||(Function.prototype.bind=function(r){var n,s=this,o=t.call(arguments,1);return n=o.length?function(){return e.call(s,this instanceof i?this:r,o.concat(t.call(arguments)))}:function(){return e.call(s,this instanceof i?this:r,arguments)},i.prototype=this.prototype,n.prototype=new i,n})}(),function(){function t(){}function e(t){var e=this.constructor.superclass.prototype[t];return arguments.length>1?e.apply(this,r.call(arguments,1)):e.call(this)}function i(){function i(){this.initialize.apply(this,arguments)}var s=null,a=r.call(arguments,0);\"function\"==typeof a[0]&&(s=a.shift()),i.superclass=s,i.subclasses=[],s&&(t.prototype=s.prototype,i.prototype=new t,s.subclasses.push(i));for(var h=0,c=a.length;c>h;h++)o(i,a[h],s);return i.prototype.initialize||(i.prototype.initialize=n),i.prototype.constructor=i,i.prototype.callSuper=e,i}var r=Array.prototype.slice,n=function(){},s=function(){for(var t in{toString:1})if(\"toString\"===t)return!1;return!0}(),o=function(t,e,i){for(var r in e)r in t.prototype&&\"function\"==typeof t.prototype[r]&&(e[r]+\"\").indexOf(\"callSuper\")>-1?t.prototype[r]=function(t){return function(){var r=this.constructor.superclass;this.constructor.superclass=i;var n=e[t].apply(this,arguments);return this.constructor.superclass=r,\"initialize\"!==t?n:void 0}}(r):t.prototype[r]=e[r],s&&(e.toString!==Object.prototype.toString&&(t.prototype.toString=e.toString),e.valueOf!==Object.prototype.valueOf&&(t.prototype.valueOf=e.valueOf))};fabric.util.createClass=i}(),function(){function t(t){var e,i,r=Array.prototype.slice.call(arguments,1),n=r.length;for(i=0;n>i;i++)if(e=typeof t[r[i]],!/^(?:function|object|unknown)$/.test(e))return!1;return!0}function e(t,e){return{handler:e,wrappedHandler:i(t,e)}}function i(t,e){return function(i){e.call(o(t),i||fabric.window.event)}}function r(t,e){return function(i){if(p[t]&&p[t][e])for(var r=p[t][e],n=0,s=r.length;s>n;n++)r[n].call(this,i||fabric.window.event)}}function n(t){t||(t=fabric.window.event);var e=t.target||(typeof t.srcElement!==h?t.srcElement:null),i=fabric.util.getScrollLeftTop(e);return{x:v(t)+i.left,y:b(t)+i.top}}function s(t,e,i){var r=\"touchend\"===t.type?\"changedTouches\":\"touches\";return t[r]&&t[r][0]?t[r][0][e]-(t[r][0][e]-t[r][0][i])||t[i]:t[i]}var o,a,h=\"unknown\",c=function(){var t=0;return function(e){return e.__uniqueID||(e.__uniqueID=\"uniqueID__\"+t++)}}();!function(){var t={};o=function(e){return t[e]},a=function(e,i){t[e]=i}}();var l,u,f=t(fabric.document.documentElement,\"addEventListener\",\"removeEventListener\")&&t(fabric.window,\"addEventListener\",\"removeEventListener\"),d=t(fabric.document.documentElement,\"attachEvent\",\"detachEvent\")&&t(fabric.window,\"attachEvent\",\"detachEvent\"),g={},p={};f?(l=function(t,e,i){t.addEventListener(e,i,!1)},u=function(t,e,i){t.removeEventListener(e,i,!1)}):d?(l=function(t,i,r){var n=c(t);a(n,t),g[n]||(g[n]={}),g[n][i]||(g[n][i]=[]);var s=e(n,r);g[n][i].push(s),t.attachEvent(\"on\"+i,s.wrappedHandler)},u=function(t,e,i){var r,n=c(t);if(g[n]&&g[n][e])for(var s=0,o=g[n][e].length;o>s;s++)r=g[n][e][s],r&&r.handler===i&&(t.detachEvent(\"on\"+e,r.wrappedHandler),g[n][e][s]=null)}):(l=function(t,e,i){var n=c(t);if(p[n]||(p[n]={}),!p[n][e]){p[n][e]=[];var s=t[\"on\"+e];s&&p[n][e].push(s),t[\"on\"+e]=r(n,e)}p[n][e].push(i)},u=function(t,e,i){var r=c(t);if(p[r]&&p[r][e])for(var n=p[r][e],s=0,o=n.length;o>s;s++)n[s]===i&&n.splice(s,1)}),fabric.util.addListener=l,fabric.util.removeListener=u;var v=function(t){return typeof t.clientX!==h?t.clientX:0},b=function(t){return typeof t.clientY!==h?t.clientY:0};fabric.isTouchSupported&&(v=function(t){return s(t,\"pageX\",\"clientX\")},b=function(t){return s(t,\"pageY\",\"clientY\")}),fabric.util.getPointer=n,fabric.util.object.extend(fabric.util,fabric.Observable)}(),function(){function t(t,e){var i=t.style;if(!i)return t;if(\"string\"==typeof e)return t.style.cssText+=\";\"+e,e.indexOf(\"opacity\")>-1?s(t,e.match(/opacity:\\s*(\\d?\\.?\\d*)/)[1]):t;for(var r in e)if(\"opacity\"===r)s(t,e[r]);else{var n=\"float\"===r||\"cssFloat\"===r?\"undefined\"==typeof i.styleFloat?\"cssFloat\":\"styleFloat\":r;i[n]=e[r]}return t}var e=fabric.document.createElement(\"div\"),i=\"string\"==typeof e.style.opacity,r=\"string\"==typeof e.style.filter,n=/alpha\\s*\\(\\s*opacity\\s*=\\s*([^\\)]+)\\)/,s=function(t){return t};i?s=function(t,e){return t.style.opacity=e,t}:r&&(s=function(t,e){var i=t.style;return t.currentStyle&&!t.currentStyle.hasLayout&&(i.zoom=1),n.test(i.filter)?(e=e>=.9999?\"\":\"alpha(opacity=\"+100*e+\")\",i.filter=i.filter.replace(n,e)):i.filter+=\" alpha(opacity=\"+100*e+\")\",t}),fabric.util.setStyle=t}(),function(){function t(t){return\"string\"==typeof t?fabric.document.getElementById(t):t}function e(t,e){var i=fabric.document.createElement(t);for(var r in e)\"class\"===r?i.className=e[r]:\"for\"===r?i.htmlFor=e[r]:i.setAttribute(r,e[r]);return i}function i(t,e){t&&-1===(\" \"+t.className+\" \").indexOf(\" \"+e+\" \")&&(t.className+=(t.className?\" \":\"\")+e)}function r(t,i,r){return\"string\"==typeof i&&(i=e(i,r)),t.parentNode&&t.parentNode.replaceChild(i,t),i.appendChild(t),i}function n(t){for(var e=0,i=0,r=fabric.document.documentElement,n=fabric.document.body||{scrollLeft:0,scrollTop:0};t&&(t.parentNode||t.host)&&(t=t.parentNode||t.host,t===fabric.document?(e=n.scrollLeft||r.scrollLeft||0,i=n.scrollTop||r.scrollTop||0):(e+=t.scrollLeft||0,i+=t.scrollTop||0),1!==t.nodeType||\"fixed\"!==fabric.util.getElementStyle(t,\"position\")););return{left:e,top:i}}function s(t){var e,i,r=t&&t.ownerDocument,s={left:0,top:0},o={left:0,top:0},a={borderLeftWidth:\"left\",borderTopWidth:\"top\",paddingLeft:\"left\",paddingTop:\"top\"};if(!r)return o;for(var h in a)o[a[h]]+=parseInt(l(t,h),10)||0;return e=r.documentElement,\"undefined\"!=typeof t.getBoundingClientRect&&(s=t.getBoundingClientRect()),i=n(t),{left:s.left+i.left-(e.clientLeft||0)+o.left,top:s.top+i.top-(e.clientTop||0)+o.top}}var o,a=Array.prototype.slice,h=function(t){return a.call(t,0)};try{o=h(fabric.document.childNodes)instanceof Array}catch(c){}o||(h=function(t){for(var e=new Array(t.length),i=t.length;i--;)e[i]=t[i];return e});var l;l=fabric.document.defaultView&&fabric.document.defaultView.getComputedStyle?function(t,e){var i=fabric.document.defaultView.getComputedStyle(t,null);return i?i[e]:void 0}:function(t,e){var i=t.style[e];return!i&&t.currentStyle&&(i=t.currentStyle[e]),i},function(){function t(t){return\"undefined\"!=typeof t.onselectstart&&(t.onselectstart=fabric.util.falseFunction),r?t.style[r]=\"none\":\"string\"==typeof t.unselectable&&(t.unselectable=\"on\"),t}function e(t){return\"undefined\"!=typeof t.onselectstart&&(t.onselectstart=null),r?t.style[r]=\"\":\"string\"==typeof t.unselectable&&(t.unselectable=\"\"),t}var i=fabric.document.documentElement.style,r=\"userSelect\"in i?\"userSelect\":\"MozUserSelect\"in i?\"MozUserSelect\":\"WebkitUserSelect\"in i?\"WebkitUserSelect\":\"KhtmlUserSelect\"in i?\"KhtmlUserSelect\":\"\";fabric.util.makeElementUnselectable=t,fabric.util.makeElementSelectable=e}(),function(){function t(t,e){var i=fabric.document.getElementsByTagName(\"head\")[0],r=fabric.document.createElement(\"script\"),n=!0;r.onload=r.onreadystatechange=function(t){if(n){if(\"string\"==typeof this.readyState&&\"loaded\"!==this.readyState&&\"complete\"!==this.readyState)return;n=!1,e(t||fabric.window.event),r=r.onload=r.onreadystatechange=null}},r.src=t,i.appendChild(r)}fabric.util.getScript=t}(),fabric.util.getById=t,fabric.util.toArray=h,fabric.util.makeElement=e,fabric.util.addClass=i,fabric.util.wrapElement=r,fabric.util.getScrollLeftTop=n,fabric.util.getElementOffset=s,fabric.util.getElementStyle=l}(),function(){function t(t,e){return t+(/\\?/.test(t)?\"&\":\"?\")+e}function e(){}function i(i,n){n||(n={});var s,o=n.method?n.method.toUpperCase():\"GET\",a=n.onComplete||function(){},h=r();return h.onreadystatechange=function(){4===h.readyState&&(a(h),h.onreadystatechange=e)},\"GET\"===o&&(s=null,\"string\"==typeof n.parameters&&(i=t(i,n.parameters))),h.open(o,i,!0),\"POST\"!==o&&\"PUT\"!==o||h.setRequestHeader(\"Content-Type\",\"application/x-www-form-urlencoded\"),h.send(s),h}var r=function(){for(var t=[function(){return new ActiveXObject(\"Microsoft.XMLHTTP\")},function(){return new ActiveXObject(\"Msxml2.XMLHTTP\")},function(){return new ActiveXObject(\"Msxml2.XMLHTTP.3.0\")},function(){return new XMLHttpRequest}],e=t.length;e--;)try{var i=t[e]();if(i)return t[e]}catch(r){}}();fabric.util.request=i}(),fabric.log=function(){},fabric.warn=function(){},\"undefined\"!=typeof console&&[\"log\",\"warn\"].forEach(function(t){\"undefined\"!=typeof console[t]&&\"function\"==typeof console[t].apply&&(fabric[t]=function(){return console[t].apply(console,arguments)})}),function(){function t(t){e(function(i){t||(t={});var r,n=i||+new Date,s=t.duration||500,o=n+s,a=t.onChange||function(){},h=t.abort||function(){return!1},c=t.easing||function(t,e,i,r){return-i*Math.cos(t/r*(Math.PI/2))+i+e},l=\"startValue\"in t?t.startValue:0,u=\"endValue\"in t?t.endValue:100,f=t.byValue||u-l;t.onStart&&t.onStart(),function d(i){r=i||+new Date;var u=r>o?s:r-n;return h()?void(t.onComplete&&t.onComplete()):(a(c(u,l,f,s)),r>o?void(t.onComplete&&t.onComplete()):void e(d))}(n)})}function e(){return i.apply(fabric.window,arguments)}var i=fabric.window.requestAnimationFrame||fabric.window.webkitRequestAnimationFrame||fabric.window.mozRequestAnimationFrame||fabric.window.oRequestAnimationFrame||fabric.window.msRequestAnimationFrame||function(t){fabric.window.setTimeout(t,1e3/60)};fabric.util.animate=t,fabric.util.requestAnimFrame=e}(),function(){function t(t,e,i,r){return t<Math.abs(e)?(t=e,r=i/4):r=0===e&&0===t?i/(2*Math.PI)*Math.asin(1):i/(2*Math.PI)*Math.asin(e/t),{a:t,c:e,p:i,s:r}}function e(t,e,i){return t.a*Math.pow(2,10*(e-=1))*Math.sin((e*i-t.s)*(2*Math.PI)/t.p)}function i(t,e,i,r){return i*((t=t/r-1)*t*t+1)+e}function r(t,e,i,r){return t/=r/2,1>t?i/2*t*t*t+e:i/2*((t-=2)*t*t+2)+e}function n(t,e,i,r){return i*(t/=r)*t*t*t+e}function s(t,e,i,r){return-i*((t=t/r-1)*t*t*t-1)+e}function o(t,e,i,r){return t/=r/2,1>t?i/2*t*t*t*t+e:-i/2*((t-=2)*t*t*t-2)+e}function a(t,e,i,r){return i*(t/=r)*t*t*t*t+e}function h(t,e,i,r){return i*((t=t/r-1)*t*t*t*t+1)+e}function c(t,e,i,r){return t/=r/2,1>t?i/2*t*t*t*t*t+e:i/2*((t-=2)*t*t*t*t+2)+e}function l(t,e,i,r){return-i*Math.cos(t/r*(Math.PI/2))+i+e}function u(t,e,i,r){return i*Math.sin(t/r*(Math.PI/2))+e}function f(t,e,i,r){return-i/2*(Math.cos(Math.PI*t/r)-1)+e}function d(t,e,i,r){return 0===t?e:i*Math.pow(2,10*(t/r-1))+e}function g(t,e,i,r){return t===r?e+i:i*(-Math.pow(2,-10*t/r)+1)+e}function p(t,e,i,r){return 0===t?e:t===r?e+i:(t/=r/2,1>t?i/2*Math.pow(2,10*(t-1))+e:i/2*(-Math.pow(2,-10*--t)+2)+e)}function v(t,e,i,r){return-i*(Math.sqrt(1-(t/=r)*t)-1)+e}function b(t,e,i,r){return i*Math.sqrt(1-(t=t/r-1)*t)+e}function m(t,e,i,r){return t/=r/2,1>t?-i/2*(Math.sqrt(1-t*t)-1)+e:i/2*(Math.sqrt(1-(t-=2)*t)+1)+e}function y(i,r,n,s){var o=1.70158,a=0,h=n;if(0===i)return r;if(i/=s,1===i)return r+n;a||(a=.3*s);var c=t(h,n,a,o);return-e(c,i,s)+r}function _(e,i,r,n){var s=1.70158,o=0,a=r;if(0===e)return i;if(e/=n,1===e)return i+r;o||(o=.3*n);var h=t(a,r,o,s);return h.a*Math.pow(2,-10*e)*Math.sin((e*n-h.s)*(2*Math.PI)/h.p)+h.c+i}function x(i,r,n,s){var o=1.70158,a=0,h=n;if(0===i)return r;if(i/=s/2,2===i)return r+n;a||(a=s*(.3*1.5));var c=t(h,n,a,o);return 1>i?-.5*e(c,i,s)+r:c.a*Math.pow(2,-10*(i-=1))*Math.sin((i*s-c.s)*(2*Math.PI)/c.p)*.5+c.c+r}function S(t,e,i,r,n){return void 0===n&&(n=1.70158),i*(t/=r)*t*((n+1)*t-n)+e}function C(t,e,i,r,n){return void 0===n&&(n=1.70158),i*((t=t/r-1)*t*((n+1)*t+n)+1)+e}function w(t,e,i,r,n){return void 0===n&&(n=1.70158),t/=r/2,1>t?i/2*(t*t*(((n*=1.525)+1)*t-n))+e:i/2*((t-=2)*t*(((n*=1.525)+1)*t+n)+2)+e}function O(t,e,i,r){return i-T(r-t,0,i,r)+e}function T(t,e,i,r){return(t/=r)<1/2.75?i*(7.5625*t*t)+e:2/2.75>t?i*(7.5625*(t-=1.5/2.75)*t+.75)+e:2.5/2.75>t?i*(7.5625*(t-=2.25/2.75)*t+.9375)+e:i*(7.5625*(t-=2.625/2.75)*t+.984375)+e}function k(t,e,i,r){return r/2>t?.5*O(2*t,0,i,r)+e:.5*T(2*t-r,0,i,r)+.5*i+e}fabric.util.ease={easeInQuad:function(t,e,i,r){return i*(t/=r)*t+e},easeOutQuad:function(t,e,i,r){return-i*(t/=r)*(t-2)+e},easeInOutQuad:function(t,e,i,r){return t/=r/2,1>t?i/2*t*t+e:-i/2*(--t*(t-2)-1)+e},easeInCubic:function(t,e,i,r){return i*(t/=r)*t*t+e},easeOutCubic:i,easeInOutCubic:r,easeInQuart:n,easeOutQuart:s,easeInOutQuart:o,easeInQuint:a,easeOutQuint:h,easeInOutQuint:c,easeInSine:l,easeOutSine:u,easeInOutSine:f,easeInExpo:d,easeOutExpo:g,easeInOutExpo:p,easeInCirc:v,easeOutCirc:b,easeInOutCirc:m,easeInElastic:y,easeOutElastic:_,easeInOutElastic:x,easeInBack:S,easeOutBack:C,easeInOutBack:w,easeInBounce:O,easeOutBounce:T,easeInOutBounce:k}}(),function(t){\"use strict\";function e(t){return t in T?T[t]:t}function i(t,e,i,r){var n,s=\"[object Array]\"===Object.prototype.toString.call(e);return\"fill\"!==t&&\"stroke\"!==t||\"none\"!==e?\"strokeDashArray\"===t?e=e.replace(/,/g,\" \").split(/\\s+/).map(function(t){return parseFloat(t)}):\"transformMatrix\"===t?e=i&&i.transformMatrix?x(i.transformMatrix,p.parseTransformAttribute(e)):p.parseTransformAttribute(e):\"visible\"===t?(e=\"none\"!==e&&\"hidden\"!==e,i&&i.visible===!1&&(e=!1)):\"originX\"===t?e=\"start\"===e?\"left\":\"end\"===e?\"right\":\"center\":n=s?e.map(_):_(e,r):e=\"\",!s&&isNaN(n)?e:n}function r(t){for(var e in k)if(\"undefined\"!=typeof t[k[e]]&&\"\"!==t[e]){if(\"undefined\"==typeof t[e]){if(!p.Object.prototype[e])continue;t[e]=p.Object.prototype[e]}if(0!==t[e].indexOf(\"url(\")){var i=new p.Color(t[e]);t[e]=i.setAlpha(y(i.getAlpha()*t[k[e]],2)).toRgba()}}return t}function n(t,r){var n,s;t.replace(/;\\s*$/,\"\").split(\";\").forEach(function(t){var o=t.split(\":\");n=e(o[0].trim().toLowerCase()),s=i(n,o[1].trim()),r[n]=s})}function s(t,r){var n,s;for(var o in t)\"undefined\"!=typeof t[o]&&(n=e(o.toLowerCase()),s=i(n,t[o]),r[n]=s)}function o(t,e){var i={};for(var r in p.cssRules[e])if(a(t,r.split(\" \")))for(var n in p.cssRules[e][r])i[n]=p.cssRules[e][r][n];return i}function a(t,e){var i,r=!0;return i=c(t,e.pop()),i&&e.length&&(r=h(t,e)),i&&r&&0===e.length}function h(t,e){for(var i,r=!0;t.parentNode&&1===t.parentNode.nodeType&&e.length;)r&&(i=e.pop()),t=t.parentNode,r=c(t,i);return 0===e.length}function c(t,e){var i,r=t.nodeName,n=t.getAttribute(\"class\"),s=t.getAttribute(\"id\");if(i=new RegExp(\"^\"+r,\"i\"),e=e.replace(i,\"\"),s&&e.length&&(i=new RegExp(\"#\"+s+\"(?![a-zA-Z\\\\-]+)\",\"i\"),e=e.replace(i,\"\")),n&&e.length){n=n.split(\" \");for(var o=n.length;o--;)i=new RegExp(\"\\\\.\"+n[o]+\"(?![a-zA-Z\\\\-]+)\",\"i\"),e=e.replace(i,\"\")}return 0===e.length}function l(t,e){var i;if(t.getElementById&&(i=t.getElementById(e)),i)return i;var r,n,s=t.getElementsByTagName(\"*\");for(n=0;n<s.length;n++)if(r=s[n],e===r.getAttribute(\"id\"))return r}function u(t){for(var e=t.getElementsByTagName(\"use\"),i=0;e.length&&i<e.length;){var r,n,s,o,a,h=e[i],c=h.getAttribute(\"xlink:href\").substr(1),u=h.getAttribute(\"x\")||0,d=h.getAttribute(\"y\")||0,g=l(t,c).cloneNode(!0),p=(g.getAttribute(\"transform\")||\"\")+\" translate(\"+u+\", \"+d+\")\",v=e.length;if(f(g),/^svg$/i.test(g.nodeName)){var b=g.ownerDocument.createElement(\"g\");for(s=0,o=g.attributes,a=o.length;a>s;s++)n=o.item(s),b.setAttribute(n.nodeName,n.nodeValue);for(;null!=g.firstChild;)b.appendChild(g.firstChild);g=b}for(s=0,o=h.attributes,a=o.length;a>s;s++)n=o.item(s),\"x\"!==n.nodeName&&\"y\"!==n.nodeName&&\"xlink:href\"!==n.nodeName&&(\"transform\"===n.nodeName?p=n.nodeValue+\" \"+p:g.setAttribute(n.nodeName,n.nodeValue));g.setAttribute(\"transform\",p),g.setAttribute(\"instantiated_by_use\",\"1\"),g.removeAttribute(\"id\"),r=h.parentNode,r.replaceChild(g,h),e.length===v&&i++}}function f(t){var e,i,r,n,s=t.getAttribute(\"viewBox\"),o=1,a=1,h=0,c=0,l=t.getAttribute(\"width\"),u=t.getAttribute(\"height\"),f=t.getAttribute(\"x\")||0,d=t.getAttribute(\"y\")||0,g=t.getAttribute(\"preserveAspectRatio\")||\"\",v=!s||!C.test(t.tagName)||!(s=s.match(j)),b=!l||!u||\"100%\"===l||\"100%\"===u,m=v&&b,y={},x=\"\";if(y.width=0,y.height=0,y.toBeParsed=m,m)return y;if(v)return y.width=_(l),y.height=_(u),y;if(h=-parseFloat(s[1]),c=-parseFloat(s[2]),e=parseFloat(s[3]),i=parseFloat(s[4]),b?(y.width=e,y.height=i):(y.width=_(l),y.height=_(u),o=y.width/e,a=y.height/i),g=p.util.parsePreserveAspectRatioAttribute(g),\"none\"!==g.alignX&&(a=o=o>a?a:o),1===o&&1===a&&0===h&&0===c&&0===f&&0===d)return y;if((f||d)&&(x=\" translate(\"+_(f)+\" \"+_(d)+\") \"),r=x+\" matrix(\"+o+\" 0 0 \"+a+\" \"+h*o+\" \"+c*a+\") \",\"svg\"===t.tagName){for(n=t.ownerDocument.createElement(\"g\");null!=t.firstChild;)n.appendChild(t.firstChild);t.appendChild(n)}else n=t,r=n.getAttribute(\"transform\")+r;return n.setAttribute(\"transform\",r),y}function d(t){var e=t.objects,i=t.options;return e=e.map(function(t){return p[b(t.type)].fromObject(t)}),{objects:e,options:i}}function g(t,e,i){e[i]&&e[i].toSVG&&t.push('\t<pattern x=\"0\" y=\"0\" id=\"',i,'Pattern\" ','width=\"',e[i].source.width,'\" height=\"',e[i].source.height,'\" patternUnits=\"userSpaceOnUse\">\\n','\t\t<image x=\"0\" y=\"0\" ','width=\"',e[i].source.width,'\" height=\"',e[i].source.height,'\" xlink:href=\"',e[i].source.src,'\"></image>\\n\t</pattern>\\n')}var p=t.fabric||(t.fabric={}),v=p.util.object.extend,b=p.util.string.capitalize,m=p.util.object.clone,y=p.util.toFixed,_=p.util.parseUnit,x=p.util.multiplyTransformMatrices,S=/^(path|circle|polygon|polyline|ellipse|rect|line|image|text)$/i,C=/^(symbol|image|marker|pattern|view|svg)$/i,w=/^(?:pattern|defs|symbol|metadata)$/i,O=/^(symbol|g|a|svg)$/i,T={cx:\"left\",x:\"left\",r:\"radius\",cy:\"top\",y:\"top\",display:\"visible\",visibility:\"visible\",transform:\"transformMatrix\",\"fill-opacity\":\"fillOpacity\",\"fill-rule\":\"fillRule\",\"font-family\":\"fontFamily\",\"font-size\":\"fontSize\",\"font-style\":\"fontStyle\",\"font-weight\":\"fontWeight\",\"stroke-dasharray\":\"strokeDashArray\",\"stroke-linecap\":\"strokeLineCap\",\"stroke-linejoin\":\"strokeLineJoin\",\"stroke-miterlimit\":\"strokeMiterLimit\",\"stroke-opacity\":\"strokeOpacity\",\"stroke-width\":\"strokeWidth\",\"text-decoration\":\"textDecoration\",\"text-anchor\":\"originX\"},k={stroke:\"strokeOpacity\",fill:\"fillOpacity\"};p.cssRules={},p.gradientDefs={},p.parseTransformAttribute=function(){function t(t,e){var i=e[0],r=3===e.length?e[1]:0,n=3===e.length?e[2]:0;t[0]=Math.cos(i),t[1]=Math.sin(i),t[2]=-Math.sin(i),t[3]=Math.cos(i),t[4]=r-(t[0]*r+t[2]*n),t[5]=n-(t[1]*r+t[3]*n)}function e(t,e){var i=e[0],r=2===e.length?e[1]:e[0];t[0]=i,t[3]=r}function i(t,e){t[2]=Math.tan(p.util.degreesToRadians(e[0]))}function r(t,e){t[1]=Math.tan(p.util.degreesToRadians(e[0]))}function n(t,e){t[4]=e[0],2===e.length&&(t[5]=e[1])}var s=[1,0,0,1,0,0],o=p.reNum,a=\"(?:\\\\s+,?\\\\s*|,\\\\s*)\",h=\"(?:(skewX)\\\\s*\\\\(\\\\s*(\"+o+\")\\\\s*\\\\))\",c=\"(?:(skewY)\\\\s*\\\\(\\\\s*(\"+o+\")\\\\s*\\\\))\",l=\"(?:(rotate)\\\\s*\\\\(\\\\s*(\"+o+\")(?:\"+a+\"(\"+o+\")\"+a+\"(\"+o+\"))?\\\\s*\\\\))\",u=\"(?:(scale)\\\\s*\\\\(\\\\s*(\"+o+\")(?:\"+a+\"(\"+o+\"))?\\\\s*\\\\))\",f=\"(?:(translate)\\\\s*\\\\(\\\\s*(\"+o+\")(?:\"+a+\"(\"+o+\"))?\\\\s*\\\\))\",d=\"(?:(matrix)\\\\s*\\\\(\\\\s*(\"+o+\")\"+a+\"(\"+o+\")\"+a+\"(\"+o+\")\"+a+\"(\"+o+\")\"+a+\"(\"+o+\")\"+a+\"(\"+o+\")\\\\s*\\\\))\",g=\"(?:\"+d+\"|\"+f+\"|\"+u+\"|\"+l+\"|\"+h+\"|\"+c+\")\",v=\"(?:\"+g+\"(?:\"+a+\"*\"+g+\")*)\",b=\"^\\\\s*(?:\"+v+\"?)\\\\s*$\",m=new RegExp(b),y=new RegExp(g,\"g\");\nreturn function(o){var a=s.concat(),h=[];if(!o||o&&!m.test(o))return a;o.replace(y,function(o){var c=new RegExp(g).exec(o).filter(function(t){return\"\"!==t&&null!=t}),l=c[1],u=c.slice(2).map(parseFloat);switch(l){case\"translate\":n(a,u);break;case\"rotate\":u[0]=p.util.degreesToRadians(u[0]),t(a,u);break;case\"scale\":e(a,u);break;case\"skewX\":i(a,u);break;case\"skewY\":r(a,u);break;case\"matrix\":a=u}h.push(a.concat()),a=s.concat()});for(var c=h[0];h.length>1;)h.shift(),c=p.util.multiplyTransformMatrices(c,h[0]);return c}}();var j=new RegExp(\"^\\\\s*(\"+p.reNum+\"+)\\\\s*,?\\\\s*(\"+p.reNum+\"+)\\\\s*,?\\\\s*(\"+p.reNum+\"+)\\\\s*,?\\\\s*(\"+p.reNum+\"+)\\\\s*$\");p.parseSVGDocument=function(){function t(t,e){for(;t&&(t=t.parentNode);)if(e.test(t.nodeName)&&!t.getAttribute(\"instantiated_by_use\"))return!0;return!1}return function(e,i,r){if(e){u(e);var n=new Date,s=p.Object.__uid++,o=f(e),a=p.util.toArray(e.getElementsByTagName(\"*\"));if(o.svgUid=s,0===a.length&&p.isLikelyNode){a=e.selectNodes('//*[name(.)!=\"svg\"]');for(var h=[],c=0,l=a.length;l>c;c++)h[c]=a[c];a=h}var d=a.filter(function(e){return f(e),S.test(e.tagName)&&!t(e,w)});if(!d||d&&!d.length)return void(i&&i([],{}));p.gradientDefs[s]=p.getGradientDefs(e),p.cssRules[s]=p.getCSSRules(e),p.parseElements(d,function(t){p.documentParsingTime=new Date-n,i&&i(t,o)},m(o),r)}}}();var A={has:function(t,e){e(!1)},get:function(){},set:function(){}},M=new RegExp(\"(normal|italic)?\\\\s*(normal|small-caps)?\\\\s*(normal|bold|bolder|lighter|100|200|300|400|500|600|700|800|900)?\\\\s*(\"+p.reNum+\"(?:px|cm|mm|em|pt|pc|in)*)(?:\\\\/(normal|\"+p.reNum+\"))?\\\\s+(.*)\");v(p,{parseFontDeclaration:function(t,e){var i=t.match(M);if(i){var r=i[1],n=i[3],s=i[4],o=i[5],a=i[6];r&&(e.fontStyle=r),n&&(e.fontWeight=isNaN(parseFloat(n))?n:parseFloat(n)),s&&(e.fontSize=_(s)),a&&(e.fontFamily=a),o&&(e.lineHeight=\"normal\"===o?1:o)}},getGradientDefs:function(t){var e,i,r,n,s=t.getElementsByTagName(\"linearGradient\"),o=t.getElementsByTagName(\"radialGradient\"),a=0,h=[],c={},l={};for(h.length=s.length+o.length,i=s.length;i--;)h[a++]=s[i];for(i=o.length;i--;)h[a++]=o[i];for(;a--;)e=h[a],n=e.getAttribute(\"xlink:href\"),r=e.getAttribute(\"id\"),n&&(l[r]=n.substr(1)),c[r]=e;for(r in l){var u=c[l[r]].cloneNode(!0);for(e=c[r];u.firstChild;)e.appendChild(u.firstChild)}return c},parseAttributes:function(t,n,s){if(t){var a,h,c={};\"undefined\"==typeof s&&(s=t.getAttribute(\"svgUid\")),t.parentNode&&O.test(t.parentNode.nodeName)&&(c=p.parseAttributes(t.parentNode,n,s)),h=c&&c.fontSize||t.getAttribute(\"font-size\")||p.Text.DEFAULT_SVG_FONT_SIZE;var l=n.reduce(function(r,n){return a=t.getAttribute(n),a&&(n=e(n),a=i(n,a,c,h),r[n]=a),r},{});return l=v(l,v(o(t,s),p.parseStyleAttribute(t))),l.font&&p.parseFontDeclaration(l.font,l),r(v(c,l))}},parseElements:function(t,e,i,r){new p.ElementsParser(t,e,i,r).parse()},parseStyleAttribute:function(t){var e={},i=t.getAttribute(\"style\");return i?(\"string\"==typeof i?n(i,e):s(i,e),e):e},parsePointsAttribute:function(t){if(!t)return null;t=t.replace(/,/g,\" \").trim(),t=t.split(/\\s+/);var e,i,r=[];for(e=0,i=t.length;i>e;e+=2)r.push({x:parseFloat(t[e]),y:parseFloat(t[e+1])});return r},getCSSRules:function(t){for(var r,n=t.getElementsByTagName(\"style\"),s={},o=0,a=n.length;a>o;o++){var h=n[o].textContent||n[o].text;h=h.replace(/\\/\\*[\\s\\S]*?\\*\\//g,\"\"),\"\"!==h.trim()&&(r=h.match(/[^{]*\\{[\\s\\S]*?\\}/g),r=r.map(function(t){return t.trim()}),r.forEach(function(t){for(var r=t.match(/([\\s\\S]*?)\\s*\\{([^}]*)\\}/),n={},o=r[2].trim(),a=o.replace(/;$/,\"\").split(/\\s*;\\s*/),h=0,c=a.length;c>h;h++){var l=a[h].split(/\\s*:\\s*/),u=e(l[0]),f=i(u,l[1],l[0]);n[u]=f}t=r[1],t.split(\",\").forEach(function(t){t=t.replace(/^svg/i,\"\").trim(),\"\"!==t&&(s[t]=p.util.object.clone(n))})}))}return s},loadSVGFromURL:function(t,e,i){function r(r){var n=r.responseXML;n&&!n.documentElement&&p.window.ActiveXObject&&r.responseText&&(n=new ActiveXObject(\"Microsoft.XMLDOM\"),n.async=\"false\",n.loadXML(r.responseText.replace(/<!DOCTYPE[\\s\\S]*?(\\[[\\s\\S]*\\])*?>/i,\"\"))),n&&n.documentElement&&p.parseSVGDocument(n.documentElement,function(i,r){A.set(t,{objects:p.util.array.invoke(i,\"toObject\"),options:r}),e(i,r)},i)}t=t.replace(/^\\n\\s*/,\"\").trim(),A.has(t,function(i){i?A.get(t,function(t){var i=d(t);e(i.objects,i.options)}):new p.util.request(t,{method:\"get\",onComplete:r})})},loadSVGFromString:function(t,e,i){t=t.trim();var r;if(\"undefined\"!=typeof DOMParser){var n=new DOMParser;n&&n.parseFromString&&(r=n.parseFromString(t,\"text/xml\"))}else p.window.ActiveXObject&&(r=new ActiveXObject(\"Microsoft.XMLDOM\"),r.async=\"false\",r.loadXML(t.replace(/<!DOCTYPE[\\s\\S]*?(\\[[\\s\\S]*\\])*?>/i,\"\")));p.parseSVGDocument(r.documentElement,function(t,i){e(t,i)},i)},createSVGFontFacesMarkup:function(t){for(var e,i,r,n,s,o,a,h=\"\",c={},l=p.fontPaths,u=0,f=t.length;f>u;u++)if(e=t[u],i=e.fontFamily,-1!==e.type.indexOf(\"text\")&&!c[i]&&l[i]&&(c[i]=!0,e.styles)){r=e.styles;for(s in r){n=r[s];for(a in n)o=n[a],i=o.fontFamily,!c[i]&&l[i]&&(c[i]=!0)}}for(var d in c)h+=[\"\t\t@font-face {\\n\",\"\t\t\tfont-family: '\",d,\"';\\n\",\"\t\t\tsrc: url('\",l[d],\"');\\n\",\"\t\t}\\n\"].join(\"\");return h&&(h=['\t<style type=\"text/css\">',\"<![CDATA[\\n\",h,\"]]>\",\"</style>\\n\"].join(\"\")),h},createSVGRefElementsMarkup:function(t){var e=[];return g(e,t,\"backgroundColor\"),g(e,t,\"overlayColor\"),e.join(\"\")}})}(\"undefined\"!=typeof exports?exports:this),fabric.ElementsParser=function(t,e,i,r){this.elements=t,this.callback=e,this.options=i,this.reviver=r,this.svgUid=i&&i.svgUid||0},fabric.ElementsParser.prototype.parse=function(){this.instances=new Array(this.elements.length),this.numElements=this.elements.length,this.createObjects()},fabric.ElementsParser.prototype.createObjects=function(){for(var t=0,e=this.elements.length;e>t;t++)this.elements[t].setAttribute(\"svgUid\",this.svgUid),function(t,e){setTimeout(function(){t.createObject(t.elements[e],e)},0)}(this,t)},fabric.ElementsParser.prototype.createObject=function(t,e){var i=fabric[fabric.util.string.capitalize(t.tagName)];if(i&&i.fromElement)try{this._createObject(i,t,e)}catch(r){fabric.log(r)}else this.checkIfDone()},fabric.ElementsParser.prototype._createObject=function(t,e,i){if(t.async)t.fromElement(e,this.createCallback(i,e),this.options);else{var r=t.fromElement(e,this.options);this.resolveGradient(r,\"fill\"),this.resolveGradient(r,\"stroke\"),this.reviver&&this.reviver(e,r),this.instances[i]=r,this.checkIfDone()}},fabric.ElementsParser.prototype.createCallback=function(t,e){var i=this;return function(r){i.resolveGradient(r,\"fill\"),i.resolveGradient(r,\"stroke\"),i.reviver&&i.reviver(e,r),i.instances[t]=r,i.checkIfDone()}},fabric.ElementsParser.prototype.resolveGradient=function(t,e){var i=t.get(e);if(/^url\\(/.test(i)){var r=i.slice(5,i.length-1);fabric.gradientDefs[this.svgUid][r]&&t.set(e,fabric.Gradient.fromElement(fabric.gradientDefs[this.svgUid][r],t))}},fabric.ElementsParser.prototype.checkIfDone=function(){0===--this.numElements&&(this.instances=this.instances.filter(function(t){return null!=t}),this.callback(this.instances))},function(t){\"use strict\";function e(t,e){this.x=t,this.y=e}var i=t.fabric||(t.fabric={});return i.Point?void i.warn(\"fabric.Point is already defined\"):(i.Point=e,void(e.prototype={constructor:e,add:function(t){return new e(this.x+t.x,this.y+t.y)},addEquals:function(t){return this.x+=t.x,this.y+=t.y,this},scalarAdd:function(t){return new e(this.x+t,this.y+t)},scalarAddEquals:function(t){return this.x+=t,this.y+=t,this},subtract:function(t){return new e(this.x-t.x,this.y-t.y)},subtractEquals:function(t){return this.x-=t.x,this.y-=t.y,this},scalarSubtract:function(t){return new e(this.x-t,this.y-t)},scalarSubtractEquals:function(t){return this.x-=t,this.y-=t,this},multiply:function(t){return new e(this.x*t,this.y*t)},multiplyEquals:function(t){return this.x*=t,this.y*=t,this},divide:function(t){return new e(this.x/t,this.y/t)},divideEquals:function(t){return this.x/=t,this.y/=t,this},eq:function(t){return this.x===t.x&&this.y===t.y},lt:function(t){return this.x<t.x&&this.y<t.y},lte:function(t){return this.x<=t.x&&this.y<=t.y},gt:function(t){return this.x>t.x&&this.y>t.y},gte:function(t){return this.x>=t.x&&this.y>=t.y},lerp:function(t,i){return new e(this.x+(t.x-this.x)*i,this.y+(t.y-this.y)*i)},distanceFrom:function(t){var e=this.x-t.x,i=this.y-t.y;return Math.sqrt(e*e+i*i)},midPointFrom:function(t){return new e(this.x+(t.x-this.x)/2,this.y+(t.y-this.y)/2)},min:function(t){return new e(Math.min(this.x,t.x),Math.min(this.y,t.y))},max:function(t){return new e(Math.max(this.x,t.x),Math.max(this.y,t.y))},toString:function(){return this.x+\",\"+this.y},setXY:function(t,e){this.x=t,this.y=e},setFromPoint:function(t){this.x=t.x,this.y=t.y},swap:function(t){var e=this.x,i=this.y;this.x=t.x,this.y=t.y,t.x=e,t.y=i}}))}(\"undefined\"!=typeof exports?exports:this),function(t){\"use strict\";function e(t){this.status=t,this.points=[]}var i=t.fabric||(t.fabric={});return i.Intersection?void i.warn(\"fabric.Intersection is already defined\"):(i.Intersection=e,i.Intersection.prototype={appendPoint:function(t){this.points.push(t)},appendPoints:function(t){this.points=this.points.concat(t)}},i.Intersection.intersectLineLine=function(t,r,n,s){var o,a=(s.x-n.x)*(t.y-n.y)-(s.y-n.y)*(t.x-n.x),h=(r.x-t.x)*(t.y-n.y)-(r.y-t.y)*(t.x-n.x),c=(s.y-n.y)*(r.x-t.x)-(s.x-n.x)*(r.y-t.y);if(0!==c){var l=a/c,u=h/c;l>=0&&1>=l&&u>=0&&1>=u?(o=new e(\"Intersection\"),o.points.push(new i.Point(t.x+l*(r.x-t.x),t.y+l*(r.y-t.y)))):o=new e}else o=new e(0===a||0===h?\"Coincident\":\"Parallel\");return o},i.Intersection.intersectLinePolygon=function(t,i,r){for(var n=new e,s=r.length,o=0;s>o;o++){var a=r[o],h=r[(o+1)%s],c=e.intersectLineLine(t,i,a,h);n.appendPoints(c.points)}return n.points.length>0&&(n.status=\"Intersection\"),n},i.Intersection.intersectPolygonPolygon=function(t,i){for(var r=new e,n=t.length,s=0;n>s;s++){var o=t[s],a=t[(s+1)%n],h=e.intersectLinePolygon(o,a,i);r.appendPoints(h.points)}return r.points.length>0&&(r.status=\"Intersection\"),r},void(i.Intersection.intersectPolygonRectangle=function(t,r,n){var s=r.min(n),o=r.max(n),a=new i.Point(o.x,s.y),h=new i.Point(s.x,o.y),c=e.intersectLinePolygon(s,a,t),l=e.intersectLinePolygon(a,o,t),u=e.intersectLinePolygon(o,h,t),f=e.intersectLinePolygon(h,s,t),d=new e;return d.appendPoints(c.points),d.appendPoints(l.points),d.appendPoints(u.points),d.appendPoints(f.points),d.points.length>0&&(d.status=\"Intersection\"),d}))}(\"undefined\"!=typeof exports?exports:this),function(t){\"use strict\";function e(t){t?this._tryParsingColor(t):this.setSource([0,0,0,1])}function i(t,e,i){return 0>i&&(i+=1),i>1&&(i-=1),1/6>i?t+6*(e-t)*i:.5>i?e:2/3>i?t+(e-t)*(2/3-i)*6:t}var r=t.fabric||(t.fabric={});return r.Color?void r.warn(\"fabric.Color is already defined.\"):(r.Color=e,r.Color.prototype={_tryParsingColor:function(t){var i;t in e.colorNameMap&&(t=e.colorNameMap[t]),\"transparent\"===t&&(i=[255,255,255,0]),i||(i=e.sourceFromHex(t)),i||(i=e.sourceFromRgb(t)),i||(i=e.sourceFromHsl(t)),i||(i=[0,0,0,1]),i&&this.setSource(i)},_rgbToHsl:function(t,e,i){t/=255,e/=255,i/=255;var n,s,o,a=r.util.array.max([t,e,i]),h=r.util.array.min([t,e,i]);if(o=(a+h)/2,a===h)n=s=0;else{var c=a-h;switch(s=o>.5?c/(2-a-h):c/(a+h),a){case t:n=(e-i)/c+(i>e?6:0);break;case e:n=(i-t)/c+2;break;case i:n=(t-e)/c+4}n/=6}return[Math.round(360*n),Math.round(100*s),Math.round(100*o)]},getSource:function(){return this._source},setSource:function(t){this._source=t},toRgb:function(){var t=this.getSource();return\"rgb(\"+t[0]+\",\"+t[1]+\",\"+t[2]+\")\"},toRgba:function(){var t=this.getSource();return\"rgba(\"+t[0]+\",\"+t[1]+\",\"+t[2]+\",\"+t[3]+\")\"},toHsl:function(){var t=this.getSource(),e=this._rgbToHsl(t[0],t[1],t[2]);return\"hsl(\"+e[0]+\",\"+e[1]+\"%,\"+e[2]+\"%)\"},toHsla:function(){var t=this.getSource(),e=this._rgbToHsl(t[0],t[1],t[2]);return\"hsla(\"+e[0]+\",\"+e[1]+\"%,\"+e[2]+\"%,\"+t[3]+\")\"},toHex:function(){var t,e,i,r=this.getSource();return t=r[0].toString(16),t=1===t.length?\"0\"+t:t,e=r[1].toString(16),e=1===e.length?\"0\"+e:e,i=r[2].toString(16),i=1===i.length?\"0\"+i:i,t.toUpperCase()+e.toUpperCase()+i.toUpperCase()},getAlpha:function(){return this.getSource()[3]},setAlpha:function(t){var e=this.getSource();return e[3]=t,this.setSource(e),this},toGrayscale:function(){var t=this.getSource(),e=parseInt((.3*t[0]+.59*t[1]+.11*t[2]).toFixed(0),10),i=t[3];return this.setSource([e,e,e,i]),this},toBlackWhite:function(t){var e=this.getSource(),i=(.3*e[0]+.59*e[1]+.11*e[2]).toFixed(0),r=e[3];return t=t||127,i=Number(i)<Number(t)?0:255,this.setSource([i,i,i,r]),this},overlayWith:function(t){t instanceof e||(t=new e(t));for(var i=[],r=this.getAlpha(),n=.5,s=this.getSource(),o=t.getSource(),a=0;3>a;a++)i.push(Math.round(s[a]*(1-n)+o[a]*n));return i[3]=r,this.setSource(i),this}},r.Color.reRGBa=/^rgba?\\(\\s*(\\d{1,3}(?:\\.\\d+)?\\%?)\\s*,\\s*(\\d{1,3}(?:\\.\\d+)?\\%?)\\s*,\\s*(\\d{1,3}(?:\\.\\d+)?\\%?)\\s*(?:\\s*,\\s*(\\d+(?:\\.\\d+)?)\\s*)?\\)$/,r.Color.reHSLa=/^hsla?\\(\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3}\\%)\\s*,\\s*(\\d{1,3}\\%)\\s*(?:\\s*,\\s*(\\d+(?:\\.\\d+)?)\\s*)?\\)$/,r.Color.reHex=/^#?([0-9a-f]{6}|[0-9a-f]{3})$/i,r.Color.colorNameMap={aqua:\"#00FFFF\",black:\"#000000\",blue:\"#0000FF\",fuchsia:\"#FF00FF\",gray:\"#808080\",grey:\"#808080\",green:\"#008000\",lime:\"#00FF00\",maroon:\"#800000\",navy:\"#000080\",olive:\"#808000\",orange:\"#FFA500\",purple:\"#800080\",red:\"#FF0000\",silver:\"#C0C0C0\",teal:\"#008080\",white:\"#FFFFFF\",yellow:\"#FFFF00\"},r.Color.fromRgb=function(t){return e.fromSource(e.sourceFromRgb(t))},r.Color.sourceFromRgb=function(t){var i=t.match(e.reRGBa);if(i){var r=parseInt(i[1],10)/(/%$/.test(i[1])?100:1)*(/%$/.test(i[1])?255:1),n=parseInt(i[2],10)/(/%$/.test(i[2])?100:1)*(/%$/.test(i[2])?255:1),s=parseInt(i[3],10)/(/%$/.test(i[3])?100:1)*(/%$/.test(i[3])?255:1);return[parseInt(r,10),parseInt(n,10),parseInt(s,10),i[4]?parseFloat(i[4]):1]}},r.Color.fromRgba=e.fromRgb,r.Color.fromHsl=function(t){return e.fromSource(e.sourceFromHsl(t))},r.Color.sourceFromHsl=function(t){var r=t.match(e.reHSLa);if(r){var n,s,o,a=(parseFloat(r[1])%360+360)%360/360,h=parseFloat(r[2])/(/%$/.test(r[2])?100:1),c=parseFloat(r[3])/(/%$/.test(r[3])?100:1);if(0===h)n=s=o=c;else{var l=.5>=c?c*(h+1):c+h-c*h,u=2*c-l;n=i(u,l,a+1/3),s=i(u,l,a),o=i(u,l,a-1/3)}return[Math.round(255*n),Math.round(255*s),Math.round(255*o),r[4]?parseFloat(r[4]):1]}},r.Color.fromHsla=e.fromHsl,r.Color.fromHex=function(t){return e.fromSource(e.sourceFromHex(t))},r.Color.sourceFromHex=function(t){if(t.match(e.reHex)){var i=t.slice(t.indexOf(\"#\")+1),r=3===i.length,n=r?i.charAt(0)+i.charAt(0):i.substring(0,2),s=r?i.charAt(1)+i.charAt(1):i.substring(2,4),o=r?i.charAt(2)+i.charAt(2):i.substring(4,6);return[parseInt(n,16),parseInt(s,16),parseInt(o,16),1]}},void(r.Color.fromSource=function(t){var i=new e;return i.setSource(t),i}))}(\"undefined\"!=typeof exports?exports:this),function(){function t(t){var e,i,r,n=t.getAttribute(\"style\"),s=t.getAttribute(\"offset\")||0;if(s=parseFloat(s)/(/%$/.test(s)?100:1),s=0>s?0:s>1?1:s,n){var o=n.split(/\\s*;\\s*/);\"\"===o[o.length-1]&&o.pop();for(var a=o.length;a--;){var h=o[a].split(/\\s*:\\s*/),c=h[0].trim(),l=h[1].trim();\"stop-color\"===c?e=l:\"stop-opacity\"===c&&(r=l)}}return e||(e=t.getAttribute(\"stop-color\")||\"rgb(0,0,0)\"),r||(r=t.getAttribute(\"stop-opacity\")),e=new fabric.Color(e),i=e.getAlpha(),r=isNaN(parseFloat(r))?1:parseFloat(r),r*=i,{offset:s,color:e.toRgb(),opacity:r}}function e(t){return{x1:t.getAttribute(\"x1\")||0,y1:t.getAttribute(\"y1\")||0,x2:t.getAttribute(\"x2\")||\"100%\",y2:t.getAttribute(\"y2\")||0}}function i(t){return{x1:t.getAttribute(\"fx\")||t.getAttribute(\"cx\")||\"50%\",y1:t.getAttribute(\"fy\")||t.getAttribute(\"cy\")||\"50%\",r1:0,x2:t.getAttribute(\"cx\")||\"50%\",y2:t.getAttribute(\"cy\")||\"50%\",r2:t.getAttribute(\"r\")||\"50%\"}}function r(t,e,i){var r,n=0,s=1,o=\"\";for(var a in e)r=parseFloat(e[a],10),s=\"string\"==typeof e[a]&&/^\\d+%$/.test(e[a])?.01:1,\"x1\"===a||\"x2\"===a||\"r2\"===a?(s*=\"objectBoundingBox\"===i?t.width:1,n=\"objectBoundingBox\"===i?t.left||0:0):\"y1\"!==a&&\"y2\"!==a||(s*=\"objectBoundingBox\"===i?t.height:1,n=\"objectBoundingBox\"===i?t.top||0:0),e[a]=r*s+n;if(\"ellipse\"===t.type&&null!==e.r2&&\"objectBoundingBox\"===i&&t.rx!==t.ry){var h=t.ry/t.rx;o=\" scale(1, \"+h+\")\",e.y1&&(e.y1/=h),e.y2&&(e.y2/=h)}return o}fabric.Gradient=fabric.util.createClass({offsetX:0,offsetY:0,initialize:function(t){t||(t={});var e={};this.id=fabric.Object.__uid++,this.type=t.type||\"linear\",e={x1:t.coords.x1||0,y1:t.coords.y1||0,x2:t.coords.x2||0,y2:t.coords.y2||0},\"radial\"===this.type&&(e.r1=t.coords.r1||0,e.r2=t.coords.r2||0),this.coords=e,this.colorStops=t.colorStops.slice(),t.gradientTransform&&(this.gradientTransform=t.gradientTransform),this.offsetX=t.offsetX||this.offsetX,this.offsetY=t.offsetY||this.offsetY},addColorStop:function(t){for(var e in t){var i=new fabric.Color(t[e]);this.colorStops.push({offset:e,color:i.toRgb(),opacity:i.getAlpha()})}return this},toObject:function(){return{type:this.type,coords:this.coords,colorStops:this.colorStops,offsetX:this.offsetX,offsetY:this.offsetY,gradientTransform:this.gradientTransform?this.gradientTransform.concat():this.gradientTransform}},toSVG:function(t){var e,i,r=fabric.util.object.clone(this.coords);if(this.colorStops.sort(function(t,e){return t.offset-e.offset}),!t.group||\"path-group\"!==t.group.type)for(var n in r)\"x1\"===n||\"x2\"===n||\"r2\"===n?r[n]+=this.offsetX-t.width/2:\"y1\"!==n&&\"y2\"!==n||(r[n]+=this.offsetY-t.height/2);i='id=\"SVGID_'+this.id+'\" gradientUnits=\"userSpaceOnUse\"',this.gradientTransform&&(i+=' gradientTransform=\"matrix('+this.gradientTransform.join(\" \")+')\" '),\"linear\"===this.type?e=[\"<linearGradient \",i,' x1=\"',r.x1,'\" y1=\"',r.y1,'\" x2=\"',r.x2,'\" y2=\"',r.y2,'\">\\n']:\"radial\"===this.type&&(e=[\"<radialGradient \",i,' cx=\"',r.x2,'\" cy=\"',r.y2,'\" r=\"',r.r2,'\" fx=\"',r.x1,'\" fy=\"',r.y1,'\">\\n']);for(var s=0;s<this.colorStops.length;s++)e.push(\"<stop \",'offset=\"',100*this.colorStops[s].offset+\"%\",'\" style=\"stop-color:',this.colorStops[s].color,null!=this.colorStops[s].opacity?\";stop-opacity: \"+this.colorStops[s].opacity:\";\",'\"/>\\n');return e.push(\"linear\"===this.type?\"</linearGradient>\\n\":\"</radialGradient>\\n\"),e.join(\"\")},toLive:function(t,e){var i,r,n=fabric.util.object.clone(this.coords);if(this.type){if(e.group&&\"path-group\"===e.group.type)for(r in n)\"x1\"===r||\"x2\"===r?n[r]+=-this.offsetX+e.width/2:\"y1\"!==r&&\"y2\"!==r||(n[r]+=-this.offsetY+e.height/2);\"linear\"===this.type?i=t.createLinearGradient(n.x1,n.y1,n.x2,n.y2):\"radial\"===this.type&&(i=t.createRadialGradient(n.x1,n.y1,n.r1,n.x2,n.y2,n.r2));for(var s=0,o=this.colorStops.length;o>s;s++){var a=this.colorStops[s].color,h=this.colorStops[s].opacity,c=this.colorStops[s].offset;\"undefined\"!=typeof h&&(a=new fabric.Color(a).setAlpha(h).toRgba()),i.addColorStop(parseFloat(c),a)}return i}}}),fabric.util.object.extend(fabric.Gradient,{fromElement:function(n,s){var o,a=n.getElementsByTagName(\"stop\"),h=\"linearGradient\"===n.nodeName?\"linear\":\"radial\",c=n.getAttribute(\"gradientUnits\")||\"objectBoundingBox\",l=n.getAttribute(\"gradientTransform\"),u=[],f={};\"linear\"===h?f=e(n):\"radial\"===h&&(f=i(n));for(var d=a.length;d--;)u.push(t(a[d]));o=r(s,f,c);var g=new fabric.Gradient({type:h,coords:f,colorStops:u,offsetX:-s.left,offsetY:-s.top});return(l||\"\"!==o)&&(g.gradientTransform=fabric.parseTransformAttribute((l||\"\")+o)),g},forObject:function(t,e){return e||(e={}),r(t,e.coords,\"userSpaceOnUse\"),new fabric.Gradient(e)}})}(),fabric.Pattern=fabric.util.createClass({repeat:\"repeat\",offsetX:0,offsetY:0,initialize:function(t){if(t||(t={}),this.id=fabric.Object.__uid++,t.source)if(\"string\"==typeof t.source)if(\"undefined\"!=typeof fabric.util.getFunctionBody(t.source))this.source=new Function(fabric.util.getFunctionBody(t.source));else{var e=this;this.source=fabric.util.createImage(),fabric.util.loadImage(t.source,function(t){e.source=t})}else this.source=t.source;t.repeat&&(this.repeat=t.repeat),t.offsetX&&(this.offsetX=t.offsetX),t.offsetY&&(this.offsetY=t.offsetY)},toObject:function(){var t;return\"function\"==typeof this.source?t=String(this.source):\"string\"==typeof this.source.src?t=this.source.src:\"object\"==typeof this.source&&this.source.toDataURL&&(t=this.source.toDataURL()),{source:t,repeat:this.repeat,offsetX:this.offsetX,offsetY:this.offsetY}},toSVG:function(t){var e=\"function\"==typeof this.source?this.source():this.source,i=e.width/t.getWidth(),r=e.height/t.getHeight(),n=this.offsetX/t.getWidth(),s=this.offsetY/t.getHeight(),o=\"\";return\"repeat-x\"!==this.repeat&&\"no-repeat\"!==this.repeat||(r=1),\"repeat-y\"!==this.repeat&&\"no-repeat\"!==this.repeat||(i=1),e.src?o=e.src:e.toDataURL&&(o=e.toDataURL()),'<pattern id=\"SVGID_'+this.id+'\" x=\"'+n+'\" y=\"'+s+'\" width=\"'+i+'\" height=\"'+r+'\">\\n<image x=\"0\" y=\"0\" width=\"'+e.width+'\" height=\"'+e.height+'\" xlink:href=\"'+o+'\"></image>\\n</pattern>\\n'},toLive:function(t){var e=\"function\"==typeof this.source?this.source():this.source;if(!e)return\"\";if(\"undefined\"!=typeof e.src){if(!e.complete)return\"\";if(0===e.naturalWidth||0===e.naturalHeight)return\"\"}return t.createPattern(e,this.repeat)}}),function(t){\"use strict\";var e=t.fabric||(t.fabric={}),i=e.util.toFixed;return e.Shadow?void e.warn(\"fabric.Shadow is already defined.\"):(e.Shadow=e.util.createClass({color:\"rgb(0,0,0)\",blur:0,offsetX:0,offsetY:0,affectStroke:!1,includeDefaultValues:!0,initialize:function(t){\"string\"==typeof t&&(t=this._parseShadow(t));for(var i in t)this[i]=t[i];this.id=e.Object.__uid++},_parseShadow:function(t){var i=t.trim(),r=e.Shadow.reOffsetsAndBlur.exec(i)||[],n=i.replace(e.Shadow.reOffsetsAndBlur,\"\")||\"rgb(0,0,0)\";return{color:n.trim(),offsetX:parseInt(r[1],10)||0,offsetY:parseInt(r[2],10)||0,blur:parseInt(r[3],10)||0}},toString:function(){return[this.offsetX,this.offsetY,this.blur,this.color].join(\"px \")},toSVG:function(t){var r=40,n=40,s=e.Object.NUM_FRACTION_DIGITS,o=e.util.rotateVector({x:this.offsetX,y:this.offsetY},e.util.degreesToRadians(-t.angle)),a=20;return t.width&&t.height&&(r=100*i((Math.abs(o.x)+this.blur)/t.width,s)+a,n=100*i((Math.abs(o.y)+this.blur)/t.height,s)+a),t.flipX&&(o.x*=-1),t.flipY&&(o.y*=-1),'<filter id=\"SVGID_'+this.id+'\" y=\"-'+n+'%\" height=\"'+(100+2*n)+'%\" x=\"-'+r+'%\" width=\"'+(100+2*r)+'%\" >\\n\t<feGaussianBlur in=\"SourceAlpha\" stdDeviation=\"'+i(this.blur?this.blur/2:0,s)+'\"></feGaussianBlur>\\n\t<feOffset dx=\"'+i(o.x,s)+'\" dy=\"'+i(o.y,s)+'\" result=\"oBlur\" ></feOffset>\\n\t<feFlood flood-color=\"'+this.color+'\"/>\\n\t<feComposite in2=\"oBlur\" operator=\"in\" />\\n\t<feMerge>\\n\t\t<feMergeNode></feMergeNode>\\n\t\t<feMergeNode in=\"SourceGraphic\"></feMergeNode>\\n\t</feMerge>\\n</filter>\\n'},toObject:function(){if(this.includeDefaultValues)return{color:this.color,blur:this.blur,offsetX:this.offsetX,offsetY:this.offsetY,affectStroke:this.affectStroke};var t={},i=e.Shadow.prototype;return[\"color\",\"blur\",\"offsetX\",\"offsetY\",\"affectStroke\"].forEach(function(e){this[e]!==i[e]&&(t[e]=this[e])},this),t}}),void(e.Shadow.reOffsetsAndBlur=/(?:\\s|^)(-?\\d+(?:px)?(?:\\s?|$))?(-?\\d+(?:px)?(?:\\s?|$))?(\\d+(?:px)?)?(?:\\s?|$)(?:$|\\s)/))}(\"undefined\"!=typeof exports?exports:this),function(){\"use strict\";if(fabric.StaticCanvas)return void fabric.warn(\"fabric.StaticCanvas is already defined.\");var t=fabric.util.object.extend,e=fabric.util.getElementOffset,i=fabric.util.removeFromArray,r=fabric.util.toFixed,n=new Error(\"Could not initialize `canvas` element\");fabric.StaticCanvas=fabric.util.createClass({initialize:function(t,e){e||(e={}),this._initStatic(t,e)},backgroundColor:\"\",backgroundImage:null,overlayColor:\"\",overlayImage:null,includeDefaultValues:!0,stateful:!0,renderOnAddRemove:!0,clipTo:null,controlsAboveOverlay:!1,allowTouchScrolling:!1,imageSmoothingEnabled:!0,preserveObjectStacking:!1,viewportTransform:[1,0,0,1,0,0],onBeforeScaleRotate:function(){},enableRetinaScaling:!0,_initStatic:function(t,e){this._objects=[],this._createLowerCanvas(t),this._initOptions(e),this._setImageSmoothing(),this.interactive||this._initRetinaScaling(),e.overlayImage&&this.setOverlayImage(e.overlayImage,this.renderAll.bind(this)),e.backgroundImage&&this.setBackgroundImage(e.backgroundImage,this.renderAll.bind(this)),e.backgroundColor&&this.setBackgroundColor(e.backgroundColor,this.renderAll.bind(this)),e.overlayColor&&this.setOverlayColor(e.overlayColor,this.renderAll.bind(this)),this.calcOffset()},_isRetinaScaling:function(){return 1!==fabric.devicePixelRatio&&this.enableRetinaScaling},_initRetinaScaling:function(){this._isRetinaScaling()&&(this.lowerCanvasEl.setAttribute(\"width\",this.width*fabric.devicePixelRatio),this.lowerCanvasEl.setAttribute(\"height\",this.height*fabric.devicePixelRatio),this.contextContainer.scale(fabric.devicePixelRatio,fabric.devicePixelRatio))},calcOffset:function(){return this._offset=e(this.lowerCanvasEl),this},setOverlayImage:function(t,e,i){return this.__setBgOverlayImage(\"overlayImage\",t,e,i)},setBackgroundImage:function(t,e,i){return this.__setBgOverlayImage(\"backgroundImage\",t,e,i)},setOverlayColor:function(t,e){return this.__setBgOverlayColor(\"overlayColor\",t,e)},setBackgroundColor:function(t,e){return this.__setBgOverlayColor(\"backgroundColor\",t,e)},_setImageSmoothing:function(){var t=this.getContext();t.imageSmoothingEnabled=t.imageSmoothingEnabled||t.webkitImageSmoothingEnabled||t.mozImageSmoothingEnabled||t.msImageSmoothingEnabled||t.oImageSmoothingEnabled,t.imageSmoothingEnabled=this.imageSmoothingEnabled},__setBgOverlayImage:function(t,e,i,r){return\"string\"==typeof e?fabric.util.loadImage(e,function(e){this[t]=new fabric.Image(e,r),i&&i(e)},this,r&&r.crossOrigin):(r&&e.setOptions(r),this[t]=e,i&&i(e)),this},__setBgOverlayColor:function(t,e,i){if(e&&e.source){var r=this;fabric.util.loadImage(e.source,function(n){r[t]=new fabric.Pattern({source:n,repeat:e.repeat,offsetX:e.offsetX,offsetY:e.offsetY}),i&&i()})}else this[t]=e,i&&i();return this},_createCanvasElement:function(){var t=fabric.document.createElement(\"canvas\");if(t.style||(t.style={}),!t)throw n;return this._initCanvasElement(t),t},_initCanvasElement:function(t){if(fabric.util.createCanvasElement(t),\"undefined\"==typeof t.getContext)throw n},_initOptions:function(t){for(var e in t)this[e]=t[e];this.width=this.width||parseInt(this.lowerCanvasEl.width,10)||0,this.height=this.height||parseInt(this.lowerCanvasEl.height,10)||0,this.lowerCanvasEl.style&&(this.lowerCanvasEl.width=this.width,this.lowerCanvasEl.height=this.height,this.lowerCanvasEl.style.width=this.width+\"px\",this.lowerCanvasEl.style.height=this.height+\"px\",this.viewportTransform=this.viewportTransform.slice())},_createLowerCanvas:function(t){this.lowerCanvasEl=fabric.util.getById(t)||this._createCanvasElement(),this._initCanvasElement(this.lowerCanvasEl),fabric.util.addClass(this.lowerCanvasEl,\"lower-canvas\"),this.interactive&&this._applyCanvasStyle(this.lowerCanvasEl),this.contextContainer=this.lowerCanvasEl.getContext(\"2d\")},getWidth:function(){return this.width},getHeight:function(){return this.height},setWidth:function(t,e){return this.setDimensions({width:t},e)},setHeight:function(t,e){return this.setDimensions({height:t},e)},setDimensions:function(t,e){var i;e=e||{};for(var r in t)i=t[r],e.cssOnly||(this._setBackstoreDimension(r,t[r]),i+=\"px\"),e.backstoreOnly||this._setCssDimension(r,i);return this._initRetinaScaling(),this._setImageSmoothing(),this.calcOffset(),e.cssOnly||this.renderAll(),this},_setBackstoreDimension:function(t,e){return this.lowerCanvasEl[t]=e,this.upperCanvasEl&&(this.upperCanvasEl[t]=e),this.cacheCanvasEl&&(this.cacheCanvasEl[t]=e),this[t]=e,this},_setCssDimension:function(t,e){return this.lowerCanvasEl.style[t]=e,this.upperCanvasEl&&(this.upperCanvasEl.style[t]=e),this.wrapperEl&&(this.wrapperEl.style[t]=e),this},getZoom:function(){return Math.sqrt(this.viewportTransform[0]*this.viewportTransform[3])},setViewportTransform:function(t){var e=this.getActiveGroup();this.viewportTransform=t,this.renderAll();for(var i=0,r=this._objects.length;r>i;i++)this._objects[i].setCoords();return e&&e.setCoords(),this},zoomToPoint:function(t,e){var i=t;t=fabric.util.transformPoint(t,fabric.util.invertTransform(this.viewportTransform)),this.viewportTransform[0]=e,this.viewportTransform[3]=e;var r=fabric.util.transformPoint(t,this.viewportTransform);this.viewportTransform[4]+=i.x-r.x,this.viewportTransform[5]+=i.y-r.y,this.renderAll();for(var n=0,s=this._objects.length;s>n;n++)this._objects[n].setCoords();return this},setZoom:function(t){return this.zoomToPoint(new fabric.Point(0,0),t),this},absolutePan:function(t){this.viewportTransform[4]=-t.x,this.viewportTransform[5]=-t.y,this.renderAll();for(var e=0,i=this._objects.length;i>e;e++)this._objects[e].setCoords();return this},relativePan:function(t){return this.absolutePan(new fabric.Point(-t.x-this.viewportTransform[4],-t.y-this.viewportTransform[5]))},getElement:function(){return this.lowerCanvasEl},getActiveObject:function(){return null},getActiveGroup:function(){return null},_onObjectAdded:function(t){this.stateful&&t.setupState(),t._set(\"canvas\",this),t.setCoords(),this.fire(\"object:added\",{target:t}),t.fire(\"added\")},_onObjectRemoved:function(t){this.getActiveObject()===t&&(this.fire(\"before:selection:cleared\",{target:t}),this._discardActiveObject(),this.fire(\"selection:cleared\")),this.fire(\"object:removed\",{target:t}),t.fire(\"removed\")},clearContext:function(t){return t.clearRect(0,0,this.width,this.height),this},getContext:function(){return this.contextContainer},clear:function(){return this._objects.length=0,this.discardActiveGroup&&this.discardActiveGroup(),this.discardActiveObject&&this.discardActiveObject(),this.clearContext(this.contextContainer),this.contextTop&&this.clearContext(this.contextTop),this.fire(\"canvas:cleared\"),this.renderAll(),this},_chooseObjectsToRender:function(){var t,e=this.getActiveGroup(),i=[],r=[];if(e&&!this.preserveObjectStacking){for(var n=0,s=this._objects.length;s>n;n++)t=this._objects[n],e.contains(t)?r.push(t):i.push(t);e._set(\"_objects\",r)}else i=this._objects;return i},renderAll:function(){var t,e=this.contextContainer;return this.contextTop&&this.selection&&!this._groupSelector&&!this.isDrawingMode&&this.clearContext(this.contextTop),this.clearContext(e),this.fire(\"before:render\"),this.clipTo&&fabric.util.clipContext(this,e),this._renderBackground(e),e.save(),t=this._chooseObjectsToRender(),e.transform.apply(e,this.viewportTransform),this._renderObjects(e,t),this.preserveObjectStacking||this._renderObjects(e,[this.getActiveGroup()]),e.restore(),!this.controlsAboveOverlay&&this.interactive&&this.drawControls(e),this.clipTo&&e.restore(),this._renderOverlay(e),this.controlsAboveOverlay&&this.interactive&&this.drawControls(e),this.fire(\"after:render\"),this},_renderObjects:function(t,e){for(var i=0,r=e.length;r>i;++i)e[i]&&e[i].render(t)},_renderBackgroundOrOverlay:function(t,e){var i=this[e+\"Color\"];i&&(t.fillStyle=i.toLive?i.toLive(t):i,t.fillRect(i.offsetX||0,i.offsetY||0,this.width,this.height)),i=this[e+\"Image\"],i&&i.render(t)},_renderBackground:function(t){this._renderBackgroundOrOverlay(t,\"background\")},_renderOverlay:function(t){this._renderBackgroundOrOverlay(t,\"overlay\")},renderTop:function(){var t=this.contextTop||this.contextContainer;return this.clearContext(t),this.selection&&this._groupSelector&&this._drawSelection(),this.fire(\"after:render\"),this},getCenter:function(){return{top:this.getHeight()/2,left:this.getWidth()/2}},centerObjectH:function(t){return this._centerObject(t,new fabric.Point(this.getCenter().left,t.getCenterPoint().y)),this.renderAll(),this},centerObjectV:function(t){return this._centerObject(t,new fabric.Point(t.getCenterPoint().x,this.getCenter().top)),this.renderAll(),this},centerObject:function(t){var e=this.getCenter();return this._centerObject(t,new fabric.Point(e.left,e.top)),this.renderAll(),this},_centerObject:function(t,e){return t.setPositionByOrigin(e,\"center\",\"center\"),this},toDatalessJSON:function(t){return this.toDatalessObject(t)},toObject:function(t){return this._toObjectMethod(\"toObject\",t)},toDatalessObject:function(t){return this._toObjectMethod(\"toDatalessObject\",t)},_toObjectMethod:function(e,i){var r={objects:this._toObjects(e,i)};return t(r,this.__serializeBgOverlay()),fabric.util.populateWithProperties(this,r,i),r},_toObjects:function(t,e){return this.getObjects().map(function(i){\nreturn this._toObject(i,t,e)},this)},_toObject:function(t,e,i){var r;this.includeDefaultValues||(r=t.includeDefaultValues,t.includeDefaultValues=!1);var n=this._realizeGroupTransformOnObject(t),s=t[e](i);return this.includeDefaultValues||(t.includeDefaultValues=r),this._unwindGroupTransformOnObject(t,n),s},_realizeGroupTransformOnObject:function(t){var e=[\"angle\",\"flipX\",\"flipY\",\"height\",\"left\",\"scaleX\",\"scaleY\",\"top\",\"width\"];if(t.group&&t.group===this.getActiveGroup()){var i={};return e.forEach(function(e){i[e]=t[e]}),this.getActiveGroup().realizeTransform(t),i}return null},_unwindGroupTransformOnObject:function(t,e){e&&t.set(e)},__serializeBgOverlay:function(){var t={background:this.backgroundColor&&this.backgroundColor.toObject?this.backgroundColor.toObject():this.backgroundColor};return this.overlayColor&&(t.overlay=this.overlayColor.toObject?this.overlayColor.toObject():this.overlayColor),this.backgroundImage&&(t.backgroundImage=this.backgroundImage.toObject()),this.overlayImage&&(t.overlayImage=this.overlayImage.toObject()),t},svgViewportTransformation:!0,toSVG:function(t,e){t||(t={});var i=[];return this._setSVGPreamble(i,t),this._setSVGHeader(i,t),this._setSVGBgOverlayColor(i,\"backgroundColor\"),this._setSVGBgOverlayImage(i,\"backgroundImage\"),this._setSVGObjects(i,e),this._setSVGBgOverlayColor(i,\"overlayColor\"),this._setSVGBgOverlayImage(i,\"overlayImage\"),i.push(\"</svg>\"),i.join(\"\")},_setSVGPreamble:function(t,e){e.suppressPreamble||t.push('<?xml version=\"1.0\" encoding=\"',e.encoding||\"UTF-8\",'\" standalone=\"no\" ?>\\n','<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" ','\"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\\n')},_setSVGHeader:function(t,e){var i,n=e.width||this.width,s=e.height||this.height,o='viewBox=\"0 0 '+this.width+\" \"+this.height+'\" ',a=fabric.Object.NUM_FRACTION_DIGITS;e.viewBox?o='viewBox=\"'+e.viewBox.x+\" \"+e.viewBox.y+\" \"+e.viewBox.width+\" \"+e.viewBox.height+'\" ':this.svgViewportTransformation&&(i=this.viewportTransform,o='viewBox=\"'+r(-i[4]/i[0],a)+\" \"+r(-i[5]/i[3],a)+\" \"+r(this.width/i[0],a)+\" \"+r(this.height/i[3],a)+'\" '),t.push(\"<svg \",'xmlns=\"http://www.w3.org/2000/svg\" ','xmlns:xlink=\"http://www.w3.org/1999/xlink\" ','version=\"1.1\" ','width=\"',n,'\" ','height=\"',s,'\" ',this.backgroundColor&&!this.backgroundColor.toLive?'style=\"background-color: '+this.backgroundColor+'\" ':null,o,'xml:space=\"preserve\">\\n',\"<desc>Created with Fabric.js \",fabric.version,\"</desc>\\n\",\"<defs>\",fabric.createSVGFontFacesMarkup(this.getObjects()),fabric.createSVGRefElementsMarkup(this),\"</defs>\\n\")},_setSVGObjects:function(t,e){for(var i=0,r=this.getObjects(),n=r.length;n>i;i++){var s=r[i],o=this._realizeGroupTransformOnObject(s);t.push(s.toSVG(e)),this._unwindGroupTransformOnObject(s,o)}},_setSVGBgOverlayImage:function(t,e){this[e]&&this[e].toSVG&&t.push(this[e].toSVG())},_setSVGBgOverlayColor:function(t,e){this[e]&&this[e].source?t.push('<rect x=\"',this[e].offsetX,'\" y=\"',this[e].offsetY,'\" ','width=\"',\"repeat-y\"===this[e].repeat||\"no-repeat\"===this[e].repeat?this[e].source.width:this.width,'\" height=\"',\"repeat-x\"===this[e].repeat||\"no-repeat\"===this[e].repeat?this[e].source.height:this.height,'\" fill=\"url(#'+e+'Pattern)\"',\"></rect>\\n\"):this[e]&&\"overlayColor\"===e&&t.push('<rect x=\"0\" y=\"0\" ','width=\"',this.width,'\" height=\"',this.height,'\" fill=\"',this[e],'\"',\"></rect>\\n\")},sendToBack:function(t){if(!t)return this;var e,r,n,s=this.getActiveGroup?this.getActiveGroup():null;if(t===s)for(n=s._objects,e=n.length;e--;)r=n[e],i(this._objects,r),this._objects.unshift(r);else i(this._objects,t),this._objects.unshift(t);return this.renderAll&&this.renderAll()},bringToFront:function(t){if(!t)return this;var e,r,n,s=this.getActiveGroup?this.getActiveGroup():null;if(t===s)for(n=s._objects,e=0;e<n.length;e++)r=n[e],i(this._objects,r),this._objects.push(r);else i(this._objects,t),this._objects.push(t);return this.renderAll&&this.renderAll()},sendBackwards:function(t,e){if(!t)return this;var r,n,s,o,a,h=this.getActiveGroup?this.getActiveGroup():null;if(t===h)for(a=h._objects,r=0;r<a.length;r++)n=a[r],s=this._objects.indexOf(n),0!==s&&(o=s-1,i(this._objects,n),this._objects.splice(o,0,n));else s=this._objects.indexOf(t),0!==s&&(o=this._findNewLowerIndex(t,s,e),i(this._objects,t),this._objects.splice(o,0,t));return this.renderAll&&this.renderAll(),this},_findNewLowerIndex:function(t,e,i){var r;if(i){r=e;for(var n=e-1;n>=0;--n){var s=t.intersectsWithObject(this._objects[n])||t.isContainedWithinObject(this._objects[n])||this._objects[n].isContainedWithinObject(t);if(s){r=n;break}}}else r=e-1;return r},bringForward:function(t,e){if(!t)return this;var r,n,s,o,a,h=this.getActiveGroup?this.getActiveGroup():null;if(t===h)for(a=h._objects,r=a.length;r--;)n=a[r],s=this._objects.indexOf(n),s!==this._objects.length-1&&(o=s+1,i(this._objects,n),this._objects.splice(o,0,n));else s=this._objects.indexOf(t),s!==this._objects.length-1&&(o=this._findNewUpperIndex(t,s,e),i(this._objects,t),this._objects.splice(o,0,t));return this.renderAll&&this.renderAll(),this},_findNewUpperIndex:function(t,e,i){var r;if(i){r=e;for(var n=e+1;n<this._objects.length;++n){var s=t.intersectsWithObject(this._objects[n])||t.isContainedWithinObject(this._objects[n])||this._objects[n].isContainedWithinObject(t);if(s){r=n;break}}}else r=e+1;return r},moveTo:function(t,e){return i(this._objects,t),this._objects.splice(e,0,t),this.renderAll&&this.renderAll()},dispose:function(){return this.clear(),this},toString:function(){return\"#<fabric.Canvas (\"+this.complexity()+\"): { objects: \"+this.getObjects().length+\" }>\"}}),t(fabric.StaticCanvas.prototype,fabric.Observable),t(fabric.StaticCanvas.prototype,fabric.Collection),t(fabric.StaticCanvas.prototype,fabric.DataURLExporter),t(fabric.StaticCanvas,{EMPTY_JSON:'{\"objects\": [], \"background\": \"white\"}',supports:function(t){var e=fabric.util.createCanvasElement();if(!e||!e.getContext)return null;var i=e.getContext(\"2d\");if(!i)return null;switch(t){case\"getImageData\":return\"undefined\"!=typeof i.getImageData;case\"setLineDash\":return\"undefined\"!=typeof i.setLineDash;case\"toDataURL\":return\"undefined\"!=typeof e.toDataURL;case\"toDataURLWithQuality\":try{return e.toDataURL(\"image/jpeg\",0),!0}catch(r){}return!1;default:return null}}}),fabric.StaticCanvas.prototype.toJSON=fabric.StaticCanvas.prototype.toObject}(),fabric.BaseBrush=fabric.util.createClass({color:\"rgb(0, 0, 0)\",width:1,shadow:null,strokeLineCap:\"round\",strokeLineJoin:\"round\",strokeDashArray:null,setShadow:function(t){return this.shadow=new fabric.Shadow(t),this},_setBrushStyles:function(){var t=this.canvas.contextTop;t.strokeStyle=this.color,t.lineWidth=this.width,t.lineCap=this.strokeLineCap,t.lineJoin=this.strokeLineJoin,this.strokeDashArray&&fabric.StaticCanvas.supports(\"setLineDash\")&&t.setLineDash(this.strokeDashArray)},_setShadow:function(){if(this.shadow){var t=this.canvas.contextTop;t.shadowColor=this.shadow.color,t.shadowBlur=this.shadow.blur,t.shadowOffsetX=this.shadow.offsetX,t.shadowOffsetY=this.shadow.offsetY}},_resetShadow:function(){var t=this.canvas.contextTop;t.shadowColor=\"\",t.shadowBlur=t.shadowOffsetX=t.shadowOffsetY=0}}),function(){fabric.PencilBrush=fabric.util.createClass(fabric.BaseBrush,{initialize:function(t){this.canvas=t,this._points=[]},onMouseDown:function(t){this._prepareForDrawing(t),this._captureDrawingPath(t),this._render()},onMouseMove:function(t){this._captureDrawingPath(t),this.canvas.clearContext(this.canvas.contextTop),this._render()},onMouseUp:function(){this._finalizeAndAddPath()},_prepareForDrawing:function(t){var e=new fabric.Point(t.x,t.y);this._reset(),this._addPoint(e),this.canvas.contextTop.moveTo(e.x,e.y)},_addPoint:function(t){this._points.push(t)},_reset:function(){this._points.length=0,this._setBrushStyles(),this._setShadow()},_captureDrawingPath:function(t){var e=new fabric.Point(t.x,t.y);this._addPoint(e)},_render:function(){var t=this.canvas.contextTop,e=this.canvas.viewportTransform,i=this._points[0],r=this._points[1];t.save(),t.transform(e[0],e[1],e[2],e[3],e[4],e[5]),t.beginPath(),2===this._points.length&&i.x===r.x&&i.y===r.y&&(i.x-=.5,r.x+=.5),t.moveTo(i.x,i.y);for(var n=1,s=this._points.length;s>n;n++){var o=i.midPointFrom(r);t.quadraticCurveTo(i.x,i.y,o.x,o.y),i=this._points[n],r=this._points[n+1]}t.lineTo(i.x,i.y),t.stroke(),t.restore()},convertPointsToSVGPath:function(t){var e=[],i=new fabric.Point(t[0].x,t[0].y),r=new fabric.Point(t[1].x,t[1].y);e.push(\"M \",t[0].x,\" \",t[0].y,\" \");for(var n=1,s=t.length;s>n;n++){var o=i.midPointFrom(r);e.push(\"Q \",i.x,\" \",i.y,\" \",o.x,\" \",o.y,\" \"),i=new fabric.Point(t[n].x,t[n].y),n+1<t.length&&(r=new fabric.Point(t[n+1].x,t[n+1].y))}return e.push(\"L \",i.x,\" \",i.y,\" \"),e},createPath:function(t){var e=new fabric.Path(t,{fill:null,stroke:this.color,strokeWidth:this.width,strokeLineCap:this.strokeLineCap,strokeLineJoin:this.strokeLineJoin,strokeDashArray:this.strokeDashArray,originX:\"center\",originY:\"center\"});return this.shadow&&(this.shadow.affectStroke=!0,e.setShadow(this.shadow)),e},_finalizeAndAddPath:function(){var t=this.canvas.contextTop;t.closePath();var e=this.convertPointsToSVGPath(this._points).join(\"\");if(\"M 0 0 Q 0 0 0 0 L 0 0\"===e)return void this.canvas.renderAll();var i=this.createPath(e);this.canvas.add(i),i.setCoords(),this.canvas.clearContext(this.canvas.contextTop),this._resetShadow(),this.canvas.renderAll(),this.canvas.fire(\"path:created\",{path:i})}})}(),fabric.CircleBrush=fabric.util.createClass(fabric.BaseBrush,{width:10,initialize:function(t){this.canvas=t,this.points=[]},drawDot:function(t){var e=this.addPoint(t),i=this.canvas.contextTop,r=this.canvas.viewportTransform;i.save(),i.transform(r[0],r[1],r[2],r[3],r[4],r[5]),i.fillStyle=e.fill,i.beginPath(),i.arc(e.x,e.y,e.radius,0,2*Math.PI,!1),i.closePath(),i.fill(),i.restore()},onMouseDown:function(t){this.points.length=0,this.canvas.clearContext(this.canvas.contextTop),this._setShadow(),this.drawDot(t)},onMouseMove:function(t){this.drawDot(t)},onMouseUp:function(){var t=this.canvas.renderOnAddRemove;this.canvas.renderOnAddRemove=!1;for(var e=[],i=0,r=this.points.length;r>i;i++){var n=this.points[i],s=new fabric.Circle({radius:n.radius,left:n.x,top:n.y,originX:\"center\",originY:\"center\",fill:n.fill});this.shadow&&s.setShadow(this.shadow),e.push(s)}var o=new fabric.Group(e,{originX:\"center\",originY:\"center\"});o.canvas=this.canvas,this.canvas.add(o),this.canvas.fire(\"path:created\",{path:o}),this.canvas.clearContext(this.canvas.contextTop),this._resetShadow(),this.canvas.renderOnAddRemove=t,this.canvas.renderAll()},addPoint:function(t){var e=new fabric.Point(t.x,t.y),i=fabric.util.getRandomInt(Math.max(0,this.width-20),this.width+20)/2,r=new fabric.Color(this.color).setAlpha(fabric.util.getRandomInt(0,100)/100).toRgba();return e.radius=i,e.fill=r,this.points.push(e),e}}),fabric.SprayBrush=fabric.util.createClass(fabric.BaseBrush,{width:10,density:20,dotWidth:1,dotWidthVariance:1,randomOpacity:!1,optimizeOverlapping:!0,initialize:function(t){this.canvas=t,this.sprayChunks=[]},onMouseDown:function(t){this.sprayChunks.length=0,this.canvas.clearContext(this.canvas.contextTop),this._setShadow(),this.addSprayChunk(t),this.render()},onMouseMove:function(t){this.addSprayChunk(t),this.render()},onMouseUp:function(){var t=this.canvas.renderOnAddRemove;this.canvas.renderOnAddRemove=!1;for(var e=[],i=0,r=this.sprayChunks.length;r>i;i++)for(var n=this.sprayChunks[i],s=0,o=n.length;o>s;s++){var a=new fabric.Rect({width:n[s].width,height:n[s].width,left:n[s].x+1,top:n[s].y+1,originX:\"center\",originY:\"center\",fill:this.color});this.shadow&&a.setShadow(this.shadow),e.push(a)}this.optimizeOverlapping&&(e=this._getOptimizedRects(e));var h=new fabric.Group(e,{originX:\"center\",originY:\"center\"});h.canvas=this.canvas,this.canvas.add(h),this.canvas.fire(\"path:created\",{path:h}),this.canvas.clearContext(this.canvas.contextTop),this._resetShadow(),this.canvas.renderOnAddRemove=t,this.canvas.renderAll()},_getOptimizedRects:function(t){for(var e,i={},r=0,n=t.length;n>r;r++)e=t[r].left+\"\"+t[r].top,i[e]||(i[e]=t[r]);var s=[];for(e in i)s.push(i[e]);return s},render:function(){var t=this.canvas.contextTop;t.fillStyle=this.color;var e=this.canvas.viewportTransform;t.save(),t.transform(e[0],e[1],e[2],e[3],e[4],e[5]);for(var i=0,r=this.sprayChunkPoints.length;r>i;i++){var n=this.sprayChunkPoints[i];\"undefined\"!=typeof n.opacity&&(t.globalAlpha=n.opacity),t.fillRect(n.x,n.y,n.width,n.width)}t.restore()},addSprayChunk:function(t){this.sprayChunkPoints=[];for(var e,i,r,n=this.width/2,s=0;s<this.density;s++){e=fabric.util.getRandomInt(t.x-n,t.x+n),i=fabric.util.getRandomInt(t.y-n,t.y+n),r=this.dotWidthVariance?fabric.util.getRandomInt(Math.max(1,this.dotWidth-this.dotWidthVariance),this.dotWidth+this.dotWidthVariance):this.dotWidth;var o=new fabric.Point(e,i);o.width=r,this.randomOpacity&&(o.opacity=fabric.util.getRandomInt(0,100)/100),this.sprayChunkPoints.push(o)}this.sprayChunks.push(this.sprayChunkPoints)}}),fabric.PatternBrush=fabric.util.createClass(fabric.PencilBrush,{getPatternSrc:function(){var t=20,e=5,i=fabric.document.createElement(\"canvas\"),r=i.getContext(\"2d\");return i.width=i.height=t+e,r.fillStyle=this.color,r.beginPath(),r.arc(t/2,t/2,t/2,0,2*Math.PI,!1),r.closePath(),r.fill(),i},getPatternSrcFunction:function(){return String(this.getPatternSrc).replace(\"this.color\",'\"'+this.color+'\"')},getPattern:function(){return this.canvas.contextTop.createPattern(this.source||this.getPatternSrc(),\"repeat\")},_setBrushStyles:function(){this.callSuper(\"_setBrushStyles\"),this.canvas.contextTop.strokeStyle=this.getPattern()},createPath:function(t){var e=this.callSuper(\"createPath\",t);return e.stroke=new fabric.Pattern({source:this.source||this.getPatternSrcFunction()}),e}}),function(){var t=fabric.util.getPointer,e=fabric.util.degreesToRadians,i=fabric.util.radiansToDegrees,r=Math.atan2,n=Math.abs,s=.5;fabric.Canvas=fabric.util.createClass(fabric.StaticCanvas,{initialize:function(t,e){e||(e={}),this._initStatic(t,e),this._initInteractive(),this._createCacheCanvas()},uniScaleTransform:!1,uniScaleKey:\"shiftKey\",centeredScaling:!1,centeredRotation:!1,centeredKey:\"altKey\",altActionKey:\"shiftKey\",interactive:!0,selection:!0,selectionKey:\"shiftKey\",selectionColor:\"rgba(100, 100, 255, 0.3)\",selectionDashArray:[],selectionBorderColor:\"rgba(255, 255, 255, 0.3)\",selectionLineWidth:1,hoverCursor:\"move\",moveCursor:\"move\",defaultCursor:\"default\",freeDrawingCursor:\"crosshair\",rotationCursor:\"crosshair\",containerClass:\"canvas-container\",perPixelTargetFind:!1,targetFindTolerance:0,skipTargetFind:!1,isDrawingMode:!1,_initInteractive:function(){this._currentTransform=null,this._groupSelector=null,this._initWrapperElement(),this._createUpperCanvas(),this._initEventListeners(),this._initRetinaScaling(),this.freeDrawingBrush=fabric.PencilBrush&&new fabric.PencilBrush(this),this.calcOffset()},_resetCurrentTransform:function(){var t=this._currentTransform;t.target.set({scaleX:t.original.scaleX,scaleY:t.original.scaleY,skewX:t.original.skewX,skewY:t.original.skewY,left:t.original.left,top:t.original.top}),this._shouldCenterTransform(t.target)?\"rotate\"===t.action?this._setOriginToCenter(t.target):(\"center\"!==t.originX&&(\"right\"===t.originX?t.mouseXSign=-1:t.mouseXSign=1),\"center\"!==t.originY&&(\"bottom\"===t.originY?t.mouseYSign=-1:t.mouseYSign=1),t.originX=\"center\",t.originY=\"center\"):(t.originX=t.original.originX,t.originY=t.original.originY)},containsPoint:function(t,e){var i=this.getPointer(t,!0),r=this._normalizePointer(e,i);return e.containsPoint(r)||e._findTargetCorner(i)},_normalizePointer:function(t,e){var i,r,n=this.getActiveGroup(),s=n&&\"group\"!==t.type&&n.contains(t);return s&&(r=fabric.util.multiplyTransformMatrices(this.viewportTransform,n.calcTransformMatrix()),r=fabric.util.invertTransform(r),e=fabric.util.transformPoint(e,r,!1),i=fabric.util.transformPoint(n.getCenterPoint(),r,!1),e.x-=i.x,e.y-=i.y),{x:e.x,y:e.y}},isTargetTransparent:function(t,e,i){var r=t.hasBorders,n=t.transparentCorners,s=this.contextCache,o=t.group&&t.group===this.getActiveGroup();t.hasBorders=t.transparentCorners=!1,o&&(s.save(),s.transform.apply(s,t.group.calcTransformMatrix())),t.render(s),t.active&&t._renderControls(s),t.hasBorders=r,t.transparentCorners=n;var a=fabric.util.isTransparent(s,e,i,this.targetFindTolerance);return o&&s.restore(),this.clearContext(s),a},_shouldClearSelection:function(t,e){var i=this.getActiveGroup(),r=this.getActiveObject();return!e||e&&i&&!i.contains(e)&&i!==e&&!t[this.selectionKey]||e&&!e.evented||e&&!e.selectable&&r&&r!==e},_shouldCenterTransform:function(t){if(t){var e,i=this._currentTransform;return\"scale\"===i.action||\"scaleX\"===i.action||\"scaleY\"===i.action?e=this.centeredScaling||t.centeredScaling:\"rotate\"===i.action&&(e=this.centeredRotation||t.centeredRotation),e?!i.altKey:i.altKey}},_getOriginFromCorner:function(t,e){var i={x:t.originX,y:t.originY};return\"ml\"===e||\"tl\"===e||\"bl\"===e?i.x=\"right\":\"mr\"!==e&&\"tr\"!==e&&\"br\"!==e||(i.x=\"left\"),\"tl\"===e||\"mt\"===e||\"tr\"===e?i.y=\"bottom\":\"bl\"!==e&&\"mb\"!==e&&\"br\"!==e||(i.y=\"top\"),i},_getActionFromCorner:function(t,e,i){if(!e)return\"drag\";switch(e){case\"mtr\":return\"rotate\";case\"ml\":case\"mr\":return i[this.altActionKey]?\"skewY\":\"scaleX\";case\"mt\":case\"mb\":return i[this.altActionKey]?\"skewX\":\"scaleY\";default:return\"scale\"}},_setupCurrentTransform:function(t,i){if(i){var r=this.getPointer(t),n=i._findTargetCorner(this.getPointer(t,!0)),s=this._getActionFromCorner(i,n,t),o=this._getOriginFromCorner(i,n);this._currentTransform={target:i,action:s,corner:n,scaleX:i.scaleX,scaleY:i.scaleY,skewX:i.skewX,skewY:i.skewY,offsetX:r.x-i.left,offsetY:r.y-i.top,originX:o.x,originY:o.y,ex:r.x,ey:r.y,lastX:r.x,lastY:r.y,left:i.left,top:i.top,theta:e(i.angle),width:i.width*i.scaleX,mouseXSign:1,mouseYSign:1,shiftKey:t.shiftKey,altKey:t[this.centeredKey]},this._currentTransform.original={left:i.left,top:i.top,scaleX:i.scaleX,scaleY:i.scaleY,skewX:i.skewX,skewY:i.skewY,originX:o.x,originY:o.y},this._resetCurrentTransform()}},_translateObject:function(t,e){var i=this._currentTransform,r=i.target,n=t-i.offsetX,s=e-i.offsetY,o=!r.get(\"lockMovementX\")&&r.left!==n,a=!r.get(\"lockMovementY\")&&r.top!==s;return o&&r.set(\"left\",n),a&&r.set(\"top\",s),o||a},_changeSkewTransformOrigin:function(t,e,i){var r=\"originX\",n={0:\"center\"},s=e.target.skewX,o=\"left\",a=\"right\",h=\"mt\"===e.corner||\"ml\"===e.corner?1:-1,c=1;t=t>0?1:-1,\"y\"===i&&(s=e.target.skewY,o=\"top\",a=\"bottom\",r=\"originY\"),n[-1]=o,n[1]=a,e.target.flipX&&(c*=-1),e.target.flipY&&(c*=-1),0===s?(e.skewSign=-h*t*c,e[r]=n[-t]):(s=s>0?1:-1,e.skewSign=s,e[r]=n[s*h*c])},_skewObject:function(t,e,i){var r=this._currentTransform,n=r.target,s=!1,o=n.get(\"lockSkewingX\"),a=n.get(\"lockSkewingY\");if(o&&\"x\"===i||a&&\"y\"===i)return!1;var h,c,l=n.getCenterPoint(),u=n.toLocalPoint(new fabric.Point(t,e),\"center\",\"center\")[i],f=n.toLocalPoint(new fabric.Point(r.lastX,r.lastY),\"center\",\"center\")[i],d=n._getTransformedDimensions();return this._changeSkewTransformOrigin(u-f,r,i),h=n.toLocalPoint(new fabric.Point(t,e),r.originX,r.originY)[i],c=n.translateToOriginPoint(l,r.originX,r.originY),s=this._setObjectSkew(h,r,i,d),r.lastX=t,r.lastY=e,n.setPositionByOrigin(c,r.originX,r.originY),s},_setObjectSkew:function(t,e,i,r){var n,s,o,a,h,c,l,u,f,d=e.target,g=!1,p=e.skewSign;return\"x\"===i?(a=\"y\",h=\"Y\",c=\"X\",u=0,f=d.skewY):(a=\"x\",h=\"X\",c=\"Y\",u=d.skewX,f=0),o=d._getTransformedDimensions(u,f),l=2*Math.abs(t)-o[i],2>=l?n=0:(n=p*Math.atan(l/d[\"scale\"+c]/(o[a]/d[\"scale\"+h])),n=fabric.util.radiansToDegrees(n)),g=d[\"skew\"+c]!==n,d.set(\"skew\"+c,n),0!==d[\"skew\"+h]&&(s=d._getTransformedDimensions(),n=r[a]/s[a]*d[\"scale\"+h],d.set(\"scale\"+h,n)),g},_scaleObject:function(t,e,i){var r=this._currentTransform,n=r.target,s=n.get(\"lockScalingX\"),o=n.get(\"lockScalingY\"),a=n.get(\"lockScalingFlip\");if(s&&o)return!1;var h=n.translateToOriginPoint(n.getCenterPoint(),r.originX,r.originY),c=n.toLocalPoint(new fabric.Point(t,e),r.originX,r.originY),l=n._getTransformedDimensions(),u=!1;return this._setLocalMouse(c,r),u=this._setObjectScale(c,r,s,o,i,a,l),n.setPositionByOrigin(h,r.originX,r.originY),u},_setObjectScale:function(t,e,i,r,n,s,o){var a,h,c,l,u=e.target,f=!1,d=!1,g=!1;return c=t.x*u.scaleX/o.x,l=t.y*u.scaleY/o.y,a=u.scaleX!==c,h=u.scaleY!==l,s&&0>=c&&c<u.scaleX&&(f=!0),s&&0>=l&&l<u.scaleY&&(d=!0),\"equally\"!==n||i||r?n?\"x\"!==n||u.get(\"lockUniScaling\")?\"y\"!==n||u.get(\"lockUniScaling\")||d||r||u.set(\"scaleY\",l)&&(g=g||h):f||i||u.set(\"scaleX\",c)&&(g=g||a):(f||i||u.set(\"scaleX\",c)&&(g=g||a),d||r||u.set(\"scaleY\",l)&&(g=g||h)):f||d||(g=this._scaleObjectEqually(t,u,e,o)),e.newScaleX=c,e.newScaleY=l,f||d||this._flipObject(e,n),g},_scaleObjectEqually:function(t,e,i,r){var n,s=t.y+t.x,o=r.y*i.original.scaleY/e.scaleY+r.x*i.original.scaleX/e.scaleX;return i.newScaleX=i.original.scaleX*s/o,i.newScaleY=i.original.scaleY*s/o,n=i.newScaleX!==e.scaleX||i.newScaleY!==e.scaleY,e.set(\"scaleX\",i.newScaleX),e.set(\"scaleY\",i.newScaleY),n},_flipObject:function(t,e){t.newScaleX<0&&\"y\"!==e&&(\"left\"===t.originX?t.originX=\"right\":\"right\"===t.originX&&(t.originX=\"left\")),t.newScaleY<0&&\"x\"!==e&&(\"top\"===t.originY?t.originY=\"bottom\":\"bottom\"===t.originY&&(t.originY=\"top\"))},_setLocalMouse:function(t,e){var i=e.target;\"right\"===e.originX?t.x*=-1:\"center\"===e.originX&&(t.x*=2*e.mouseXSign,t.x<0&&(e.mouseXSign=-e.mouseXSign)),\"bottom\"===e.originY?t.y*=-1:\"center\"===e.originY&&(t.y*=2*e.mouseYSign,t.y<0&&(e.mouseYSign=-e.mouseYSign)),n(t.x)>i.padding?t.x<0?t.x+=i.padding:t.x-=i.padding:t.x=0,n(t.y)>i.padding?t.y<0?t.y+=i.padding:t.y-=i.padding:t.y=0},_rotateObject:function(t,e){var n=this._currentTransform;if(n.target.get(\"lockRotation\"))return!1;var s=r(n.ey-n.top,n.ex-n.left),o=r(e-n.top,t-n.left),a=i(o-s+n.theta);return 0>a&&(a=360+a),n.target.angle=a%360,!0},setCursor:function(t){this.upperCanvasEl.style.cursor=t},_resetObjectTransform:function(t){t.scaleX=1,t.scaleY=1,t.skewX=0,t.skewY=0,t.setAngle(0)},_drawSelection:function(){var t=this.contextTop,e=this._groupSelector,i=e.left,r=e.top,o=n(i),a=n(r);if(t.fillStyle=this.selectionColor,t.fillRect(e.ex-(i>0?0:-i),e.ey-(r>0?0:-r),o,a),t.lineWidth=this.selectionLineWidth,t.strokeStyle=this.selectionBorderColor,this.selectionDashArray.length>1){var h=e.ex+s-(i>0?0:o),c=e.ey+s-(r>0?0:a);t.beginPath(),fabric.util.drawDashedLine(t,h,c,h+o,c,this.selectionDashArray),fabric.util.drawDashedLine(t,h,c+a-1,h+o,c+a-1,this.selectionDashArray),fabric.util.drawDashedLine(t,h,c,h,c+a,this.selectionDashArray),fabric.util.drawDashedLine(t,h+o-1,c,h+o-1,c+a,this.selectionDashArray),t.closePath(),t.stroke()}else t.strokeRect(e.ex+s-(i>0?0:o),e.ey+s-(r>0?0:a),o,a)},_isLastRenderedObject:function(t){return this.controlsAboveOverlay&&this.lastRenderedObjectWithControlsAboveOverlay&&this.lastRenderedObjectWithControlsAboveOverlay.visible&&this.containsPoint(t,this.lastRenderedObjectWithControlsAboveOverlay)&&this.lastRenderedObjectWithControlsAboveOverlay._findTargetCorner(this.getPointer(t,!0))},findTarget:function(t,e){if(!this.skipTargetFind){if(this._isLastRenderedObject(t))return this.lastRenderedObjectWithControlsAboveOverlay;var i=this.getActiveGroup();if(!e&&this._checkTarget(t,i,this.getPointer(t,!0)))return i;var r=this._searchPossibleTargets(t,e);return this._fireOverOutEvents(r,t),r}},_fireOverOutEvents:function(t,e){t?this._hoveredTarget!==t&&(this._hoveredTarget&&(this.fire(\"mouse:out\",{target:this._hoveredTarget,e:e}),this._hoveredTarget.fire(\"mouseout\")),this.fire(\"mouse:over\",{target:t,e:e}),t.fire(\"mouseover\"),this._hoveredTarget=t):this._hoveredTarget&&(this.fire(\"mouse:out\",{target:this._hoveredTarget,e:e}),this._hoveredTarget.fire(\"mouseout\"),this._hoveredTarget=null)},_checkTarget:function(t,e,i){if(e&&e.visible&&e.evented&&this.containsPoint(t,e)){if(!this.perPixelTargetFind&&!e.perPixelTargetFind||e.isEditing)return!0;var r=this.isTargetTransparent(e,i.x,i.y);if(!r)return!0}},_searchPossibleTargets:function(t,e){for(var i,r=this.getPointer(t,!0),n=this._objects.length;n--;)if((!this._objects[n].group||e)&&this._checkTarget(t,this._objects[n],r)){this.relatedTarget=this._objects[n],i=this._objects[n];break}return i},getPointer:function(e,i,r){r||(r=this.upperCanvasEl);var n,s=t(e),o=r.getBoundingClientRect(),a=o.width||0,h=o.height||0;return a&&h||(\"top\"in o&&\"bottom\"in o&&(h=Math.abs(o.top-o.bottom)),\"right\"in o&&\"left\"in o&&(a=Math.abs(o.right-o.left))),this.calcOffset(),s.x=s.x-this._offset.left,s.y=s.y-this._offset.top,i||(s=fabric.util.transformPoint(s,fabric.util.invertTransform(this.viewportTransform))),n=0===a||0===h?{width:1,height:1}:{width:r.width/a,height:r.height/h},{x:s.x*n.width,y:s.y*n.height}},_createUpperCanvas:function(){var t=this.lowerCanvasEl.className.replace(/\\s*lower-canvas\\s*/,\"\");this.upperCanvasEl=this._createCanvasElement(),fabric.util.addClass(this.upperCanvasEl,\"upper-canvas \"+t),this.wrapperEl.appendChild(this.upperCanvasEl),this._copyCanvasStyle(this.lowerCanvasEl,this.upperCanvasEl),this._applyCanvasStyle(this.upperCanvasEl),this.contextTop=this.upperCanvasEl.getContext(\"2d\")},_createCacheCanvas:function(){this.cacheCanvasEl=this._createCanvasElement(),this.cacheCanvasEl.setAttribute(\"width\",this.width),this.cacheCanvasEl.setAttribute(\"height\",this.height),this.contextCache=this.cacheCanvasEl.getContext(\"2d\")},_initWrapperElement:function(){this.wrapperEl=fabric.util.wrapElement(this.lowerCanvasEl,\"div\",{\"class\":this.containerClass}),fabric.util.setStyle(this.wrapperEl,{width:this.getWidth()+\"px\",height:this.getHeight()+\"px\",position:\"relative\"}),fabric.util.makeElementUnselectable(this.wrapperEl)},_applyCanvasStyle:function(t){var e=this.getWidth()||t.width,i=this.getHeight()||t.height;fabric.util.setStyle(t,{position:\"absolute\",width:e+\"px\",height:i+\"px\",left:0,top:0}),t.width=e,t.height=i,fabric.util.makeElementUnselectable(t)},_copyCanvasStyle:function(t,e){e.style.cssText=t.style.cssText},getSelectionContext:function(){return this.contextTop},getSelectionElement:function(){return this.upperCanvasEl},_setActiveObject:function(t){this._activeObject&&this._activeObject.set(\"active\",!1),this._activeObject=t,t.set(\"active\",!0)},setActiveObject:function(t,e){return this._setActiveObject(t),this.renderAll(),this.fire(\"object:selected\",{target:t,e:e}),t.fire(\"selected\",{e:e}),this},getActiveObject:function(){return this._activeObject},_discardActiveObject:function(){this._activeObject&&this._activeObject.set(\"active\",!1),this._activeObject=null},discardActiveObject:function(t){return this._discardActiveObject(),this.renderAll(),this.fire(\"selection:cleared\",{e:t}),this},_setActiveGroup:function(t){this._activeGroup=t,t&&t.set(\"active\",!0)},setActiveGroup:function(t,e){return this._setActiveGroup(t),t&&(this.fire(\"object:selected\",{target:t,e:e}),t.fire(\"selected\",{e:e})),this},getActiveGroup:function(){return this._activeGroup},_discardActiveGroup:function(){var t=this.getActiveGroup();t&&t.destroy(),this.setActiveGroup(null)},discardActiveGroup:function(t){return this._discardActiveGroup(),this.fire(\"selection:cleared\",{e:t}),this},deactivateAll:function(){for(var t=this.getObjects(),e=0,i=t.length;i>e;e++)t[e].set(\"active\",!1);return this._discardActiveGroup(),this._discardActiveObject(),this},deactivateAllWithDispatch:function(t){var e=this.getActiveGroup()||this.getActiveObject();return e&&this.fire(\"before:selection:cleared\",{target:e,e:t}),this.deactivateAll(),e&&this.fire(\"selection:cleared\",{e:t}),this},dispose:function(){this.callSuper(\"dispose\");var t=this.wrapperEl;return this.removeListeners(),t.removeChild(this.upperCanvasEl),t.removeChild(this.lowerCanvasEl),delete this.upperCanvasEl,t.parentNode&&t.parentNode.replaceChild(this.lowerCanvasEl,this.wrapperEl),delete this.wrapperEl,this},drawControls:function(t){var e=this.getActiveGroup();e?e._renderControls(t):this._drawObjectsControls(t)},_drawObjectsControls:function(t){for(var e=0,i=this._objects.length;i>e;++e)this._objects[e]&&this._objects[e].active&&(this._objects[e]._renderControls(t),this.lastRenderedObjectWithControlsAboveOverlay=this._objects[e])}});for(var o in fabric.StaticCanvas)\"prototype\"!==o&&(fabric.Canvas[o]=fabric.StaticCanvas[o]);fabric.isTouchSupported&&(fabric.Canvas.prototype._setCursorFromEvent=function(){}),fabric.Element=fabric.Canvas}(),function(){var t={mt:0,tr:1,mr:2,br:3,mb:4,bl:5,ml:6,tl:7},e=fabric.util.addListener,i=fabric.util.removeListener;fabric.util.object.extend(fabric.Canvas.prototype,{cursorMap:[\"n-resize\",\"ne-resize\",\"e-resize\",\"se-resize\",\"s-resize\",\"sw-resize\",\"w-resize\",\"nw-resize\"],_initEventListeners:function(){this._bindEvents(),e(fabric.window,\"resize\",this._onResize),e(this.upperCanvasEl,\"mousedown\",this._onMouseDown),e(this.upperCanvasEl,\"mousemove\",this._onMouseMove),e(this.upperCanvasEl,\"mousewheel\",this._onMouseWheel),e(this.upperCanvasEl,\"mouseout\",this._onMouseOut),e(this.upperCanvasEl,\"touchstart\",this._onMouseDown),e(this.upperCanvasEl,\"touchmove\",this._onMouseMove),\"undefined\"!=typeof eventjs&&\"add\"in eventjs&&(eventjs.add(this.upperCanvasEl,\"gesture\",this._onGesture),eventjs.add(this.upperCanvasEl,\"drag\",this._onDrag),eventjs.add(this.upperCanvasEl,\"orientation\",this._onOrientationChange),eventjs.add(this.upperCanvasEl,\"shake\",this._onShake),eventjs.add(this.upperCanvasEl,\"longpress\",this._onLongPress))},_bindEvents:function(){this._onMouseDown=this._onMouseDown.bind(this),this._onMouseMove=this._onMouseMove.bind(this),this._onMouseUp=this._onMouseUp.bind(this),this._onResize=this._onResize.bind(this),this._onGesture=this._onGesture.bind(this),this._onDrag=this._onDrag.bind(this),this._onShake=this._onShake.bind(this),this._onLongPress=this._onLongPress.bind(this),this._onOrientationChange=this._onOrientationChange.bind(this),this._onMouseWheel=this._onMouseWheel.bind(this),this._onMouseOut=this._onMouseOut.bind(this)},removeListeners:function(){i(fabric.window,\"resize\",this._onResize),i(this.upperCanvasEl,\"mousedown\",this._onMouseDown),i(this.upperCanvasEl,\"mousemove\",this._onMouseMove),i(this.upperCanvasEl,\"mousewheel\",this._onMouseWheel),i(this.upperCanvasEl,\"mouseout\",this._onMouseOut),i(this.upperCanvasEl,\"touchstart\",this._onMouseDown),i(this.upperCanvasEl,\"touchmove\",this._onMouseMove),\"undefined\"!=typeof eventjs&&\"remove\"in eventjs&&(eventjs.remove(this.upperCanvasEl,\"gesture\",this._onGesture),eventjs.remove(this.upperCanvasEl,\"drag\",this._onDrag),eventjs.remove(this.upperCanvasEl,\"orientation\",this._onOrientationChange),eventjs.remove(this.upperCanvasEl,\"shake\",this._onShake),eventjs.remove(this.upperCanvasEl,\"longpress\",this._onLongPress))},_onGesture:function(t,e){this.__onTransformGesture&&this.__onTransformGesture(t,e)},_onDrag:function(t,e){this.__onDrag&&this.__onDrag(t,e)},_onMouseWheel:function(t,e){this.__onMouseWheel&&this.__onMouseWheel(t,e)},_onMouseOut:function(t){var e=this._hoveredTarget;this.fire(\"mouse:out\",{target:e,e:t}),this._hoveredTarget=null,e&&e.fire(\"mouseout\",{e:t})},_onOrientationChange:function(t,e){this.__onOrientationChange&&this.__onOrientationChange(t,e)},_onShake:function(t,e){this.__onShake&&this.__onShake(t,e)},_onLongPress:function(t,e){this.__onLongPress&&this.__onLongPress(t,e)},_onMouseDown:function(t){this.__onMouseDown(t),e(fabric.document,\"touchend\",this._onMouseUp),e(fabric.document,\"touchmove\",this._onMouseMove),i(this.upperCanvasEl,\"mousemove\",this._onMouseMove),i(this.upperCanvasEl,\"touchmove\",this._onMouseMove),\"touchstart\"===t.type?i(this.upperCanvasEl,\"mousedown\",this._onMouseDown):(e(fabric.document,\"mouseup\",this._onMouseUp),e(fabric.document,\"mousemove\",this._onMouseMove))},_onMouseUp:function(t){if(this.__onMouseUp(t),i(fabric.document,\"mouseup\",this._onMouseUp),i(fabric.document,\"touchend\",this._onMouseUp),i(fabric.document,\"mousemove\",this._onMouseMove),i(fabric.document,\"touchmove\",this._onMouseMove),e(this.upperCanvasEl,\"mousemove\",this._onMouseMove),e(this.upperCanvasEl,\"touchmove\",this._onMouseMove),\"touchend\"===t.type){var r=this;setTimeout(function(){e(r.upperCanvasEl,\"mousedown\",r._onMouseDown)},400)}},_onMouseMove:function(t){!this.allowTouchScrolling&&t.preventDefault&&t.preventDefault(),\nthis.__onMouseMove(t)},_onResize:function(){this.calcOffset()},_shouldRender:function(t,e){var i=this.getActiveGroup()||this.getActiveObject();return!!(t&&(t.isMoving||t!==i)||!t&&i||!t&&!i&&!this._groupSelector||e&&this._previousPointer&&this.selection&&(e.x!==this._previousPointer.x||e.y!==this._previousPointer.y))},__onMouseUp:function(t){var e,i=!0,r=this._currentTransform;if(this.isDrawingMode&&this._isCurrentlyDrawing)return void this._onMouseUpInDrawingMode(t);r&&(this._finalizeCurrentTransform(),i=!r.actionPerformed),e=i?this.findTarget(t,!0):r.target;var n=this._shouldRender(e,this.getPointer(t));this._maybeGroupObjects(t),e&&(e.isMoving=!1),n&&this.renderAll(),this._handleCursorAndEvent(t,e)},_handleCursorAndEvent:function(t,e){this._setCursorFromEvent(t,e),this.fire(\"mouse:up\",{target:e,e:t}),e&&e.fire(\"mouseup\",{e:t})},_finalizeCurrentTransform:function(){var t=this._currentTransform,e=t.target;e._scaling&&(e._scaling=!1),e.setCoords(),this._restoreOriginXY(e),(t.actionPerformed||this.stateful&&e.hasStateChanged())&&(this.fire(\"object:modified\",{target:e}),e.fire(\"modified\"))},_restoreOriginXY:function(t){if(this._previousOriginX&&this._previousOriginY){var e=t.translateToOriginPoint(t.getCenterPoint(),this._previousOriginX,this._previousOriginY);t.originX=this._previousOriginX,t.originY=this._previousOriginY,t.left=e.x,t.top=e.y,this._previousOriginX=null,this._previousOriginY=null}},_onMouseDownInDrawingMode:function(t){this._isCurrentlyDrawing=!0,this.discardActiveObject(t).renderAll(),this.clipTo&&fabric.util.clipContext(this,this.contextTop);var e=fabric.util.invertTransform(this.viewportTransform),i=fabric.util.transformPoint(this.getPointer(t,!0),e);this.freeDrawingBrush.onMouseDown(i),this.fire(\"mouse:down\",{e:t});var r=this.findTarget(t);\"undefined\"!=typeof r&&r.fire(\"mousedown\",{e:t,target:r})},_onMouseMoveInDrawingMode:function(t){if(this._isCurrentlyDrawing){var e=fabric.util.invertTransform(this.viewportTransform),i=fabric.util.transformPoint(this.getPointer(t,!0),e);this.freeDrawingBrush.onMouseMove(i)}this.setCursor(this.freeDrawingCursor),this.fire(\"mouse:move\",{e:t});var r=this.findTarget(t);\"undefined\"!=typeof r&&r.fire(\"mousemove\",{e:t,target:r})},_onMouseUpInDrawingMode:function(t){this._isCurrentlyDrawing=!1,this.clipTo&&this.contextTop.restore(),this.freeDrawingBrush.onMouseUp(),this.fire(\"mouse:up\",{e:t});var e=this.findTarget(t);\"undefined\"!=typeof e&&e.fire(\"mouseup\",{e:t,target:e})},__onMouseDown:function(t){var e=\"which\"in t?1===t.which:0===t.button;if(e||fabric.isTouchSupported){if(this.isDrawingMode)return void this._onMouseDownInDrawingMode(t);if(!this._currentTransform){var i=this.findTarget(t),r=this.getPointer(t,!0);this._previousPointer=r;var n=this._shouldRender(i,r),s=this._shouldGroup(t,i);this._shouldClearSelection(t,i)?this._clearSelection(t,i,r):s&&(this._handleGrouping(t,i),i=this.getActiveGroup()),i&&(!i.selectable||!i.__corner&&s||(this._beforeTransform(t,i),this._setupCurrentTransform(t,i)),i!==this.getActiveGroup()&&i!==this.getActiveObject()&&(this.deactivateAll(),i.selectable&&this.setActiveObject(i,t))),n&&this.renderAll(),this.fire(\"mouse:down\",{target:i,e:t}),i&&i.fire(\"mousedown\",{e:t})}}},_beforeTransform:function(t,e){this.stateful&&e.saveState(),e._findTargetCorner(this.getPointer(t))&&this.onBeforeScaleRotate(e)},_clearSelection:function(t,e,i){this.deactivateAllWithDispatch(t),e&&e.selectable?this.setActiveObject(e,t):this.selection&&(this._groupSelector={ex:i.x,ey:i.y,top:0,left:0})},_setOriginToCenter:function(t){this._previousOriginX=this._currentTransform.target.originX,this._previousOriginY=this._currentTransform.target.originY;var e=t.getCenterPoint();t.originX=\"center\",t.originY=\"center\",t.left=e.x,t.top=e.y,this._currentTransform.left=t.left,this._currentTransform.top=t.top},_setCenterToOrigin:function(t){var e=t.translateToOriginPoint(t.getCenterPoint(),this._previousOriginX,this._previousOriginY);t.originX=this._previousOriginX,t.originY=this._previousOriginY,t.left=e.x,t.top=e.y,this._previousOriginX=null,this._previousOriginY=null},__onMouseMove:function(t){var e,i;if(this.isDrawingMode)return void this._onMouseMoveInDrawingMode(t);if(!(\"undefined\"!=typeof t.touches&&t.touches.length>1)){var r=this._groupSelector;r?(i=this.getPointer(t,!0),r.left=i.x-r.ex,r.top=i.y-r.ey,this.renderTop()):this._currentTransform?this._transformObject(t):(e=this.findTarget(t),this._setCursorFromEvent(t,e)),this.fire(\"mouse:move\",{target:e,e:t}),e&&e.fire(\"mousemove\",{e:t})}},_transformObject:function(t){var e=this.getPointer(t),i=this._currentTransform;i.reset=!1,i.target.isMoving=!0,this._beforeScaleTransform(t,i),this._performTransformAction(t,i,e),this.renderAll()},_performTransformAction:function(t,e,i){var r=i.x,n=i.y,s=e.target,o=e.action,a=!1;\"rotate\"===o?(a=this._rotateObject(r,n))&&this._fire(\"rotating\",s,t):\"scale\"===o?(a=this._onScale(t,e,r,n))&&this._fire(\"scaling\",s,t):\"scaleX\"===o?(a=this._scaleObject(r,n,\"x\"))&&this._fire(\"scaling\",s,t):\"scaleY\"===o?(a=this._scaleObject(r,n,\"y\"))&&this._fire(\"scaling\",s,t):\"skewX\"===o?(a=this._skewObject(r,n,\"x\"))&&this._fire(\"skewing\",s,t):\"skewY\"===o?(a=this._skewObject(r,n,\"y\"))&&this._fire(\"skewing\",s,t):(a=this._translateObject(r,n),a&&(this._fire(\"moving\",s,t),this.setCursor(s.moveCursor||this.moveCursor))),e.actionPerformed=a},_fire:function(t,e,i){this.fire(\"object:\"+t,{target:e,e:i}),e.fire(t,{e:i})},_beforeScaleTransform:function(t,e){if(\"scale\"===e.action||\"scaleX\"===e.action||\"scaleY\"===e.action){var i=this._shouldCenterTransform(e.target);(i&&(\"center\"!==e.originX||\"center\"!==e.originY)||!i&&\"center\"===e.originX&&\"center\"===e.originY)&&(this._resetCurrentTransform(),e.reset=!0)}},_onScale:function(t,e,i,r){return!t[this.uniScaleKey]&&!this.uniScaleTransform||e.target.get(\"lockUniScaling\")?(e.reset||\"scale\"!==e.currentAction||this._resetCurrentTransform(),e.currentAction=\"scaleEqually\",this._scaleObject(i,r,\"equally\")):(e.currentAction=\"scale\",this._scaleObject(i,r))},_setCursorFromEvent:function(t,e){if(!e)return this.setCursor(this.defaultCursor),!1;var i=e.hoverCursor||this.hoverCursor;if(e.selectable){var r=this.getActiveGroup(),n=e._findTargetCorner&&(!r||!r.contains(e))&&e._findTargetCorner(this.getPointer(t,!0));n?this._setCornerCursor(n,e,t):this.setCursor(i)}else this.setCursor(i);return!0},_setCornerCursor:function(e,i,r){if(e in t)this.setCursor(this._getRotatedCornerCursor(e,i,r));else{if(\"mtr\"!==e||!i.hasRotatingPoint)return this.setCursor(this.defaultCursor),!1;this.setCursor(this.rotationCursor)}},_getRotatedCornerCursor:function(e,i,r){var n=Math.round(i.getAngle()%360/45);return 0>n&&(n+=8),n+=t[e],r[this.altActionKey]&&t[e]%2===0&&(n+=2),n%=8,this.cursorMap[n]}})}(),function(){var t=Math.min,e=Math.max;fabric.util.object.extend(fabric.Canvas.prototype,{_shouldGroup:function(t,e){var i=this.getActiveObject();return t[this.selectionKey]&&e&&e.selectable&&(this.getActiveGroup()||i&&i!==e)&&this.selection},_handleGrouping:function(t,e){e===this.getActiveGroup()&&(e=this.findTarget(t,!0),!e||e.isType(\"group\"))||(this.getActiveGroup()?this._updateActiveGroup(e,t):this._createActiveGroup(e,t),this._activeGroup&&this._activeGroup.saveCoords())},_updateActiveGroup:function(t,e){var i=this.getActiveGroup();if(i.contains(t)){if(i.removeWithUpdate(t),t.set(\"active\",!1),1===i.size())return this.discardActiveGroup(e),void this.setActiveObject(i.item(0))}else i.addWithUpdate(t);this.fire(\"selection:created\",{target:i,e:e}),i.set(\"active\",!0)},_createActiveGroup:function(t,e){if(this._activeObject&&t!==this._activeObject){var i=this._createGroup(t);i.addWithUpdate(),this.setActiveGroup(i),this._activeObject=null,this.fire(\"selection:created\",{target:i,e:e})}t.set(\"active\",!0)},_createGroup:function(t){var e=this.getObjects(),i=e.indexOf(this._activeObject)<e.indexOf(t),r=i?[this._activeObject,t]:[t,this._activeObject];return new fabric.Group(r,{canvas:this})},_groupSelectedObjects:function(t){var e=this._collectObjects();1===e.length?this.setActiveObject(e[0],t):e.length>1&&(e=new fabric.Group(e.reverse(),{canvas:this}),e.addWithUpdate(),this.setActiveGroup(e,t),e.saveCoords(),this.fire(\"selection:created\",{target:e}),this.renderAll())},_collectObjects:function(){for(var i,r=[],n=this._groupSelector.ex,s=this._groupSelector.ey,o=n+this._groupSelector.left,a=s+this._groupSelector.top,h=new fabric.Point(t(n,o),t(s,a)),c=new fabric.Point(e(n,o),e(s,a)),l=n===o&&s===a,u=this._objects.length;u--&&(i=this._objects[u],!(i&&i.selectable&&i.visible&&(i.intersectsWithRect(h,c)||i.isContainedWithinRect(h,c)||i.containsPoint(h)||i.containsPoint(c))&&(i.set(\"active\",!0),r.push(i),l))););return r},_maybeGroupObjects:function(t){this.selection&&this._groupSelector&&this._groupSelectedObjects(t);var e=this.getActiveGroup();e&&(e.setObjectsCoords().setCoords(),e.isMoving=!1,this.setCursor(this.defaultCursor)),this._groupSelector=null,this._currentTransform=null}})}(),fabric.util.object.extend(fabric.StaticCanvas.prototype,{toDataURL:function(t){t||(t={});var e=t.format||\"png\",i=t.quality||1,r=t.multiplier||1,n={left:t.left,top:t.top,width:t.width,height:t.height};return this._isRetinaScaling()&&(r*=fabric.devicePixelRatio),1!==r?this.__toDataURLWithMultiplier(e,i,n,r):this.__toDataURL(e,i,n)},__toDataURL:function(t,e,i){this.renderAll();var r=this.contextContainer.canvas,n=this.__getCroppedCanvas(r,i);\"jpg\"===t&&(t=\"jpeg\");var s=fabric.StaticCanvas.supports(\"toDataURLWithQuality\")?(n||r).toDataURL(\"image/\"+t,e):(n||r).toDataURL(\"image/\"+t);return n&&(n=null),s},__getCroppedCanvas:function(t,e){var i,r,n=\"left\"in e||\"top\"in e||\"width\"in e||\"height\"in e;return n&&(i=fabric.util.createCanvasElement(),r=i.getContext(\"2d\"),i.width=e.width||this.width,i.height=e.height||this.height,r.drawImage(t,-e.left||0,-e.top||0)),i},__toDataURLWithMultiplier:function(t,e,i,r){var n=this.getWidth(),s=this.getHeight(),o=n*r,a=s*r,h=this.getActiveObject(),c=this.getActiveGroup(),l=this.getZoom(),u=l*r/fabric.devicePixelRatio;r>1&&this.setDimensions({width:o,height:a}),this.setZoom(u),i.left&&(i.left*=r),i.top&&(i.top*=r),i.width?i.width*=r:1>r&&(i.width=o),i.height?i.height*=r:1>r&&(i.height=a),c?this._tempRemoveBordersControlsFromGroup(c):h&&this.deactivateAll&&this.deactivateAll();var f=this.__toDataURL(t,e,i);return c?this._restoreBordersControlsOnGroup(c):h&&this.setActiveObject&&this.setActiveObject(h),this.setZoom(l),this.setDimensions({width:n,height:s}),f},toDataURLWithMultiplier:function(t,e,i){return this.toDataURL({format:t,multiplier:e,quality:i})},_tempRemoveBordersControlsFromGroup:function(t){t.origHasControls=t.hasControls,t.origBorderColor=t.borderColor,t.hasControls=!0,t.borderColor=\"rgba(0,0,0,0)\",t.forEachObject(function(t){t.origBorderColor=t.borderColor,t.borderColor=\"rgba(0,0,0,0)\"})},_restoreBordersControlsOnGroup:function(t){t.hideControls=t.origHideControls,t.borderColor=t.origBorderColor,t.forEachObject(function(t){t.borderColor=t.origBorderColor,delete t.origBorderColor})}}),fabric.util.object.extend(fabric.StaticCanvas.prototype,{loadFromDatalessJSON:function(t,e,i){return this.loadFromJSON(t,e,i)},loadFromJSON:function(t,e,i){if(t){var r=\"string\"==typeof t?JSON.parse(t):fabric.util.object.clone(t);this.clear();var n=this;this._enlivenObjects(r.objects,function(){n._setBgOverlay(r,e)},i),delete r.objects,delete r.backgroundImage,delete r.overlayImage,delete r.background,delete r.overlay;for(var s in r)this[s]=r[s];return this}},_setBgOverlay:function(t,e){var i=this,r={backgroundColor:!1,overlayColor:!1,backgroundImage:!1,overlayImage:!1};if(!(t.backgroundImage||t.overlayImage||t.background||t.overlay))return void(e&&e());var n=function(){r.backgroundImage&&r.overlayImage&&r.backgroundColor&&r.overlayColor&&(i.renderAll(),e&&e())};this.__setBgOverlay(\"backgroundImage\",t.backgroundImage,r,n),this.__setBgOverlay(\"overlayImage\",t.overlayImage,r,n),this.__setBgOverlay(\"backgroundColor\",t.background,r,n),this.__setBgOverlay(\"overlayColor\",t.overlay,r,n),n()},__setBgOverlay:function(t,e,i,r){var n=this;return e?void(\"backgroundImage\"===t||\"overlayImage\"===t?fabric.Image.fromObject(e,function(e){n[t]=e,i[t]=!0,r&&r()}):this[\"set\"+fabric.util.string.capitalize(t,!0)](e,function(){i[t]=!0,r&&r()})):void(i[t]=!0)},_enlivenObjects:function(t,e,i){var r=this;if(!t||0===t.length)return void(e&&e());var n=this.renderOnAddRemove;this.renderOnAddRemove=!1,fabric.util.enlivenObjects(t,function(t){t.forEach(function(t,e){r.insertAt(t,e,!0)}),r.renderOnAddRemove=n,e&&e()},null,i)},_toDataURL:function(t,e){this.clone(function(i){e(i.toDataURL(t))})},_toDataURLWithMultiplier:function(t,e,i){this.clone(function(r){i(r.toDataURLWithMultiplier(t,e))})},clone:function(t,e){var i=JSON.stringify(this.toJSON(e));this.cloneWithoutData(function(e){e.loadFromJSON(i,function(){t&&t(e)})})},cloneWithoutData:function(t){var e=fabric.document.createElement(\"canvas\");e.width=this.getWidth(),e.height=this.getHeight();var i=new fabric.Canvas(e);i.clipTo=this.clipTo,this.backgroundImage?(i.setBackgroundImage(this.backgroundImage.src,function(){i.renderAll(),t&&t(i)}),i.backgroundImageOpacity=this.backgroundImageOpacity,i.backgroundImageStretch=this.backgroundImageStretch):t&&t(i)}}),function(t){\"use strict\";var e=t.fabric||(t.fabric={}),i=e.util.object.extend,r=e.util.toFixed,n=e.util.string.capitalize,s=e.util.degreesToRadians,o=e.StaticCanvas.supports(\"setLineDash\");e.Object||(e.Object=e.util.createClass({type:\"object\",originX:\"left\",originY:\"top\",top:0,left:0,width:0,height:0,scaleX:1,scaleY:1,flipX:!1,flipY:!1,opacity:1,angle:0,skewX:0,skewY:0,cornerSize:13,transparentCorners:!0,hoverCursor:null,moveCursor:null,padding:0,borderColor:\"rgba(102,153,255,0.75)\",borderDashArray:null,cornerColor:\"rgba(102,153,255,0.5)\",cornerStrokeColor:null,cornerStyle:\"rect\",cornerDashArray:null,centeredScaling:!1,centeredRotation:!0,fill:\"rgb(0,0,0)\",fillRule:\"nonzero\",globalCompositeOperation:\"source-over\",backgroundColor:\"\",selectionBackgroundColor:\"\",stroke:null,strokeWidth:1,strokeDashArray:null,strokeLineCap:\"butt\",strokeLineJoin:\"miter\",strokeMiterLimit:10,shadow:null,borderOpacityWhenMoving:.4,borderScaleFactor:1,transformMatrix:null,minScaleLimit:.01,selectable:!0,evented:!0,visible:!0,hasControls:!0,hasBorders:!0,hasRotatingPoint:!0,rotatingPointOffset:40,perPixelTargetFind:!1,includeDefaultValues:!0,clipTo:null,lockMovementX:!1,lockMovementY:!1,lockRotation:!1,lockScalingX:!1,lockScalingY:!1,lockUniScaling:!1,lockSkewingX:!1,lockSkewingY:!1,lockScalingFlip:!1,stateProperties:\"top left width height scaleX scaleY flipX flipY originX originY transformMatrix stroke strokeWidth strokeDashArray strokeLineCap strokeLineJoin strokeMiterLimit angle opacity fill fillRule globalCompositeOperation shadow clipTo visible backgroundColor alignX alignY meetOrSlice skewX skewY\".split(\" \"),initialize:function(t){t&&this.setOptions(t)},_initGradient:function(t){!t.fill||!t.fill.colorStops||t.fill instanceof e.Gradient||this.set(\"fill\",new e.Gradient(t.fill)),!t.stroke||!t.stroke.colorStops||t.stroke instanceof e.Gradient||this.set(\"stroke\",new e.Gradient(t.stroke))},_initPattern:function(t){!t.fill||!t.fill.source||t.fill instanceof e.Pattern||this.set(\"fill\",new e.Pattern(t.fill)),!t.stroke||!t.stroke.source||t.stroke instanceof e.Pattern||this.set(\"stroke\",new e.Pattern(t.stroke))},_initClipping:function(t){if(t.clipTo&&\"string\"==typeof t.clipTo){var i=e.util.getFunctionBody(t.clipTo);\"undefined\"!=typeof i&&(this.clipTo=new Function(\"ctx\",i))}},setOptions:function(t){for(var e in t)this.set(e,t[e]);this._initGradient(t),this._initPattern(t),this._initClipping(t)},transform:function(t,e){this.group&&this.canvas.preserveObjectStacking&&this.group===this.canvas._activeGroup&&this.group.transform(t);var i=e?this._getLeftTopCoords():this.getCenterPoint();t.translate(i.x,i.y),t.rotate(s(this.angle)),t.scale(this.scaleX*(this.flipX?-1:1),this.scaleY*(this.flipY?-1:1)),t.transform(1,0,Math.tan(s(this.skewX)),1,0,0),t.transform(1,Math.tan(s(this.skewY)),0,1,0,0)},toObject:function(t){var i=e.Object.NUM_FRACTION_DIGITS,n={type:this.type,originX:this.originX,originY:this.originY,left:r(this.left,i),top:r(this.top,i),width:r(this.width,i),height:r(this.height,i),fill:this.fill&&this.fill.toObject?this.fill.toObject():this.fill,stroke:this.stroke&&this.stroke.toObject?this.stroke.toObject():this.stroke,strokeWidth:r(this.strokeWidth,i),strokeDashArray:this.strokeDashArray?this.strokeDashArray.concat():this.strokeDashArray,strokeLineCap:this.strokeLineCap,strokeLineJoin:this.strokeLineJoin,strokeMiterLimit:r(this.strokeMiterLimit,i),scaleX:r(this.scaleX,i),scaleY:r(this.scaleY,i),angle:r(this.getAngle(),i),flipX:this.flipX,flipY:this.flipY,opacity:r(this.opacity,i),shadow:this.shadow&&this.shadow.toObject?this.shadow.toObject():this.shadow,visible:this.visible,clipTo:this.clipTo&&String(this.clipTo),backgroundColor:this.backgroundColor,fillRule:this.fillRule,globalCompositeOperation:this.globalCompositeOperation,transformMatrix:this.transformMatrix?this.transformMatrix.concat():this.transformMatrix,skewX:r(this.skewX,i),skewY:r(this.skewY,i)};return this.includeDefaultValues||(n=this._removeDefaultValues(n)),e.util.populateWithProperties(this,n,t),n},toDatalessObject:function(t){return this.toObject(t)},_removeDefaultValues:function(t){var i=e.util.getKlass(t.type).prototype,r=i.stateProperties;return r.forEach(function(e){t[e]===i[e]&&delete t[e];var r=\"[object Array]\"===Object.prototype.toString.call(t[e])&&\"[object Array]\"===Object.prototype.toString.call(i[e]);r&&0===t[e].length&&0===i[e].length&&delete t[e]}),t},toString:function(){return\"#<fabric.\"+n(this.type)+\">\"},get:function(t){return this[t]},_setObject:function(t){for(var e in t)this._set(e,t[e])},set:function(t,e){return\"object\"==typeof t?this._setObject(t):\"function\"==typeof e&&\"clipTo\"!==t?this._set(t,e(this.get(t))):this._set(t,e),this},_set:function(t,i){var r=\"scaleX\"===t||\"scaleY\"===t;return r&&(i=this._constrainScale(i)),\"scaleX\"===t&&0>i?(this.flipX=!this.flipX,i*=-1):\"scaleY\"===t&&0>i?(this.flipY=!this.flipY,i*=-1):\"shadow\"!==t||!i||i instanceof e.Shadow||(i=new e.Shadow(i)),this[t]=i,\"width\"!==t&&\"height\"!==t||(this.minScaleLimit=Math.min(.1,1/Math.max(this.width,this.height))),this},setOnGroup:function(){},toggle:function(t){var e=this.get(t);return\"boolean\"==typeof e&&this.set(t,!e),this},setSourcePath:function(t){return this.sourcePath=t,this},getViewportTransform:function(){return this.canvas&&this.canvas.viewportTransform?this.canvas.viewportTransform:[1,0,0,1,0,0]},render:function(t,i){0===this.width&&0===this.height||!this.visible||(t.save(),this._setupCompositeOperation(t),this.drawSelectionBackground(t),i||this.transform(t),this._setStrokeStyles(t),this._setFillStyles(t),this.transformMatrix&&t.transform.apply(t,this.transformMatrix),this._setOpacity(t),this._setShadow(t),this.clipTo&&e.util.clipContext(this,t),this._render(t,i),this.clipTo&&t.restore(),t.restore())},_setOpacity:function(t){this.group&&this.group._setOpacity(t),t.globalAlpha*=this.opacity},_setStrokeStyles:function(t){this.stroke&&(t.lineWidth=this.strokeWidth,t.lineCap=this.strokeLineCap,t.lineJoin=this.strokeLineJoin,t.miterLimit=this.strokeMiterLimit,t.strokeStyle=this.stroke.toLive?this.stroke.toLive(t,this):this.stroke)},_setFillStyles:function(t){this.fill&&(t.fillStyle=this.fill.toLive?this.fill.toLive(t,this):this.fill)},_setLineDash:function(t,e,i){e&&(1&e.length&&e.push.apply(e,e),o?t.setLineDash(e):i&&i(t))},_renderControls:function(t,i){if(!(!this.active||i||this.group&&this.group!==this.canvas.getActiveGroup())){var r,n=this.getViewportTransform(),o=this.calcTransformMatrix();o=e.util.multiplyTransformMatrices(n,o),r=e.util.qrDecompose(o),t.save(),t.translate(r.translateX,r.translateY),t.lineWidth=1/this.borderScaleFactor,t.globalAlpha=this.isMoving?this.borderOpacityWhenMoving:1,this.group&&this.group===this.canvas.getActiveGroup()?(t.rotate(s(r.angle)),this.drawBordersInGroup(t,r)):(t.rotate(s(this.angle)),this.drawBorders(t)),this.drawControls(t),t.restore()}},_setShadow:function(t){if(this.shadow){var i=this.canvas&&this.canvas.viewportTransform[0]||1,r=this.canvas&&this.canvas.viewportTransform[3]||1;this.canvas&&this.canvas._isRetinaScaling()&&(i*=e.devicePixelRatio,r*=e.devicePixelRatio),t.shadowColor=this.shadow.color,t.shadowBlur=this.shadow.blur*(i+r)*(this.scaleX+this.scaleY)/4,t.shadowOffsetX=this.shadow.offsetX*i*this.scaleX,t.shadowOffsetY=this.shadow.offsetY*r*this.scaleY}},_removeShadow:function(t){this.shadow&&(t.shadowColor=\"\",t.shadowBlur=t.shadowOffsetX=t.shadowOffsetY=0)},_renderFill:function(t){if(this.fill){if(t.save(),this.fill.gradientTransform){var e=this.fill.gradientTransform;t.transform.apply(t,e)}this.fill.toLive&&t.translate(-this.width/2+this.fill.offsetX||0,-this.height/2+this.fill.offsetY||0),\"evenodd\"===this.fillRule?t.fill(\"evenodd\"):t.fill(),t.restore()}},_renderStroke:function(t){if(this.stroke&&0!==this.strokeWidth){if(this.shadow&&!this.shadow.affectStroke&&this._removeShadow(t),t.save(),this._setLineDash(t,this.strokeDashArray,this._renderDashedStroke),this.stroke.gradientTransform){var e=this.stroke.gradientTransform;t.transform.apply(t,e)}this.stroke.toLive&&t.translate(-this.width/2+this.stroke.offsetX||0,-this.height/2+this.stroke.offsetY||0),t.stroke(),t.restore()}},clone:function(t,i){return this.constructor.fromObject?this.constructor.fromObject(this.toObject(i),t):new e.Object(this.toObject(i))},cloneAsImage:function(t){var i=this.toDataURL();return e.util.loadImage(i,function(i){t&&t(new e.Image(i))}),this},toDataURL:function(t){t||(t={});var i=e.util.createCanvasElement(),r=this.getBoundingRect();i.width=r.width,i.height=r.height,e.util.wrapElement(i,\"div\");var n=new e.StaticCanvas(i);\"jpg\"===t.format&&(t.format=\"jpeg\"),\"jpeg\"===t.format&&(n.backgroundColor=\"#fff\");var s={active:this.get(\"active\"),left:this.getLeft(),top:this.getTop()};this.set(\"active\",!1),this.setPositionByOrigin(new e.Point(n.getWidth()/2,n.getHeight()/2),\"center\",\"center\");var o=this.canvas;n.add(this);var a=n.toDataURL(t);return this.set(s).setCoords(),this.canvas=o,n.dispose(),n=null,a},isType:function(t){return this.type===t},complexity:function(){return 0},toJSON:function(t){return this.toObject(t)},setGradient:function(t,i){i||(i={});var r={colorStops:[]};r.type=i.type||(i.r1||i.r2?\"radial\":\"linear\"),r.coords={x1:i.x1,y1:i.y1,x2:i.x2,y2:i.y2},(i.r1||i.r2)&&(r.coords.r1=i.r1,r.coords.r2=i.r2),i.gradientTransform&&(r.gradientTransform=i.gradientTransform);for(var n in i.colorStops){var s=new e.Color(i.colorStops[n]);r.colorStops.push({offset:n,color:s.toRgb(),opacity:s.getAlpha()})}return this.set(t,e.Gradient.forObject(this,r))},setPatternFill:function(t){return this.set(\"fill\",new e.Pattern(t))},setShadow:function(t){return this.set(\"shadow\",t?new e.Shadow(t):null)},setColor:function(t){return this.set(\"fill\",t),this},setAngle:function(t){var e=(\"center\"!==this.originX||\"center\"!==this.originY)&&this.centeredRotation;return e&&this._setOriginToCenter(),this.set(\"angle\",t),e&&this._resetOrigin(),this},centerH:function(){return this.canvas.centerObjectH(this),this},centerV:function(){return this.canvas.centerObjectV(this),this},center:function(){return this.canvas.centerObject(this),this},remove:function(){return this.canvas.remove(this),this},getLocalPointer:function(t,i){i=i||this.canvas.getPointer(t);var r=new e.Point(i.x,i.y),n=this._getLeftTopCoords();return this.angle&&(r=e.util.rotatePoint(r,n,e.util.degreesToRadians(-this.angle))),{x:r.x-n.x,y:r.y-n.y}},_setupCompositeOperation:function(t){this.globalCompositeOperation&&(t.globalCompositeOperation=this.globalCompositeOperation)}}),e.util.createAccessors(e.Object),e.Object.prototype.rotate=e.Object.prototype.setAngle,i(e.Object.prototype,e.Observable),e.Object.NUM_FRACTION_DIGITS=2,e.Object.__uid=0)}(\"undefined\"!=typeof exports?exports:this),function(){var t=fabric.util.degreesToRadians,e={left:-.5,center:0,right:.5},i={top:-.5,center:0,bottom:.5};fabric.util.object.extend(fabric.Object.prototype,{translateToGivenOrigin:function(t,r,n,s,o){var a,h=t.x,c=t.y,l=e[s]-e[r],u=i[o]-i[n];return(l||u)&&(a=this._getTransformedDimensions(),h=t.x+l*a.x,c=t.y+u*a.y),new fabric.Point(h,c)},translateToCenterPoint:function(e,i,r){var n=this.translateToGivenOrigin(e,i,r,\"center\",\"center\");return this.angle?fabric.util.rotatePoint(n,e,t(this.angle)):n},translateToOriginPoint:function(e,i,r){var n=this.translateToGivenOrigin(e,\"center\",\"center\",i,r);return this.angle?fabric.util.rotatePoint(n,e,t(this.angle)):n},getCenterPoint:function(){var t=new fabric.Point(this.left,this.top);return this.translateToCenterPoint(t,this.originX,this.originY)},getPointByOrigin:function(t,e){var i=this.getCenterPoint();return this.translateToOriginPoint(i,t,e)},toLocalPoint:function(e,i,r){var n,s,o=this.getCenterPoint();return n=i&&r?this.translateToGivenOrigin(o,\"center\",\"center\",i,r):new fabric.Point(this.left,this.top),s=new fabric.Point(e.x,e.y),this.angle&&(s=fabric.util.rotatePoint(s,o,-t(this.angle))),s.subtractEquals(n)},setPositionByOrigin:function(t,e,i){var r=this.translateToCenterPoint(t,e,i),n=this.translateToOriginPoint(r,this.originX,this.originY);this.set(\"left\",n.x),this.set(\"top\",n.y)},adjustPosition:function(i){var r=t(this.angle),n=this.getWidth(),s=Math.cos(r)*n,o=Math.sin(r)*n;this.left+=s*(e[i]-e[this.originX]),this.top+=o*(e[i]-e[this.originX]),this.setCoords(),this.originX=i},_setOriginToCenter:function(){this._originalOriginX=this.originX,this._originalOriginY=this.originY;var t=this.getCenterPoint();this.originX=\"center\",this.originY=\"center\",this.left=t.x,this.top=t.y},_resetOrigin:function(){var t=this.translateToOriginPoint(this.getCenterPoint(),this._originalOriginX,this._originalOriginY);this.originX=this._originalOriginX,this.originY=this._originalOriginY,this.left=t.x,this.top=t.y,this._originalOriginX=null,this._originalOriginY=null},_getLeftTopCoords:function(){return this.translateToOriginPoint(this.getCenterPoint(),\"left\",\"top\")}})}(),function(){function t(t){return[new fabric.Point(t.tl.x,t.tl.y),new fabric.Point(t.tr.x,t.tr.y),new fabric.Point(t.br.x,t.br.y),new fabric.Point(t.bl.x,t.bl.y)]}var e=fabric.util.degreesToRadians,i=fabric.util.multiplyTransformMatrices;fabric.util.object.extend(fabric.Object.prototype,{oCoords:null,intersectsWithRect:function(e,i){var r=t(this.oCoords),n=fabric.Intersection.intersectPolygonRectangle(r,e,i);return\"Intersection\"===n.status},intersectsWithObject:function(e){var i=fabric.Intersection.intersectPolygonPolygon(t(this.oCoords),t(e.oCoords));return\"Intersection\"===i.status},isContainedWithinObject:function(t){var e=t.getBoundingRect(),i=new fabric.Point(e.left,e.top),r=new fabric.Point(e.left+e.width,e.top+e.height);return this.isContainedWithinRect(i,r)},isContainedWithinRect:function(t,e){var i=this.getBoundingRect();return i.left>=t.x&&i.left+i.width<=e.x&&i.top>=t.y&&i.top+i.height<=e.y},containsPoint:function(t){var e=this._getImageLines(this.oCoords),i=this._findCrossPoints(t,e);return 0!==i&&i%2===1},_getImageLines:function(t){return{topline:{o:t.tl,d:t.tr},rightline:{o:t.tr,d:t.br},bottomline:{o:t.br,d:t.bl},leftline:{o:t.bl,d:t.tl}}},_findCrossPoints:function(t,e){var i,r,n,s,o,a,h,c=0;for(var l in e)if(h=e[l],!(h.o.y<t.y&&h.d.y<t.y||h.o.y>=t.y&&h.d.y>=t.y||(h.o.x===h.d.x&&h.o.x>=t.x?(o=h.o.x,a=t.y):(i=0,r=(h.d.y-h.o.y)/(h.d.x-h.o.x),n=t.y-i*t.x,s=h.o.y-r*h.o.x,o=-(n-s)/(i-r),a=n+i*o),o>=t.x&&(c+=1),2!==c)))break;return c},getBoundingRectWidth:function(){return this.getBoundingRect().width},getBoundingRectHeight:function(){return this.getBoundingRect().height},getBoundingRect:function(){return this.oCoords||this.setCoords(),fabric.util.makeBoundingBoxFromPoints([this.oCoords.tl,this.oCoords.tr,this.oCoords.br,this.oCoords.bl])},getWidth:function(){return this._getTransformedDimensions().x},getHeight:function(){return this._getTransformedDimensions().y},_constrainScale:function(t){return Math.abs(t)<this.minScaleLimit?0>t?-this.minScaleLimit:this.minScaleLimit:t},scale:function(t){return t=this._constrainScale(t),0>t&&(this.flipX=!this.flipX,this.flipY=!this.flipY,t*=-1),this.scaleX=t,this.scaleY=t,this.setCoords(),this},scaleToWidth:function(t){var e=this.getBoundingRect().width/this.getWidth();return this.scale(t/this.width/e)},scaleToHeight:function(t){var e=this.getBoundingRect().height/this.getHeight();return this.scale(t/this.height/e)},setCoords:function(){var t=e(this.angle),i=this.getViewportTransform(),r=this._calculateCurrentDimensions(),n=r.x,s=r.y;0>n&&(n=Math.abs(n));var o=Math.sin(t),a=Math.cos(t),h=n>0?Math.atan(s/n):0,c=n/Math.cos(h)/2,l=Math.cos(h+t)*c,u=Math.sin(h+t)*c,f=fabric.util.transformPoint(this.getCenterPoint(),i),d=new fabric.Point(f.x-l,f.y-u),g=new fabric.Point(d.x+n*a,d.y+n*o),p=new fabric.Point(d.x-s*o,d.y+s*a),v=new fabric.Point(f.x+l,f.y+u),b=new fabric.Point((d.x+p.x)/2,(d.y+p.y)/2),m=new fabric.Point((g.x+d.x)/2,(g.y+d.y)/2),y=new fabric.Point((v.x+g.x)/2,(v.y+g.y)/2),_=new fabric.Point((v.x+p.x)/2,(v.y+p.y)/2),x=new fabric.Point(m.x+o*this.rotatingPointOffset,m.y-a*this.rotatingPointOffset);return this.oCoords={tl:d,tr:g,br:v,bl:p,ml:b,mt:m,mr:y,mb:_,mtr:x},this._setCornerCoords&&this._setCornerCoords(),this},_calcRotateMatrix:function(){if(this.angle){var t=e(this.angle),i=Math.cos(t),r=Math.sin(t);return[i,r,-r,i,0,0]}return[1,0,0,1,0,0]},calcTransformMatrix:function(){var t=this.getCenterPoint(),e=[1,0,0,1,t.x,t.y],r=this._calcRotateMatrix(),n=this._calcDimensionsTransformMatrix(this.skewX,this.skewY,!0),s=this.group?this.group.calcTransformMatrix():[1,0,0,1,0,0];return s=i(s,e),s=i(s,r),s=i(s,n)},_calcDimensionsTransformMatrix:function(t,r,n){var s=[1,0,Math.tan(e(t)),1],o=[1,Math.tan(e(r)),0,1],a=this.scaleX*(n&&this.flipX?-1:1),h=this.scaleY*(n&&this.flipY?-1:1),c=[a,0,0,h],l=i(c,s,!0);return i(l,o,!0)}})}(),fabric.util.object.extend(fabric.Object.prototype,{sendToBack:function(){return this.group?fabric.StaticCanvas.prototype.sendToBack.call(this.group,this):this.canvas.sendToBack(this),this},bringToFront:function(){return this.group?fabric.StaticCanvas.prototype.bringToFront.call(this.group,this):this.canvas.bringToFront(this),this},sendBackwards:function(t){return this.group?fabric.StaticCanvas.prototype.sendBackwards.call(this.group,this,t):this.canvas.sendBackwards(this,t),this},bringForward:function(t){return this.group?fabric.StaticCanvas.prototype.bringForward.call(this.group,this,t):this.canvas.bringForward(this,t),this},moveTo:function(t){return this.group?fabric.StaticCanvas.prototype.moveTo.call(this.group,this,t):this.canvas.moveTo(this,t),this}}),function(){function t(t,e){if(e){if(e.toLive)return t+\": url(#SVGID_\"+e.id+\"); \";var i=new fabric.Color(e),r=t+\": \"+e+\"; \",n=i.getAlpha();return 1!==n&&(r=t+\": \"+i.toRgb()+\"; \",r+=t+\"-opacity: \"+n.toString()+\"; \"),r}return t+\": none; \"}fabric.util.object.extend(fabric.Object.prototype,{getSvgStyles:function(e){var i=this.fillRule,r=this.strokeWidth?this.strokeWidth:\"0\",n=this.strokeDashArray?this.strokeDashArray.join(\" \"):\"none\",s=this.strokeLineCap?this.strokeLineCap:\"butt\",o=this.strokeLineJoin?this.strokeLineJoin:\"miter\",a=this.strokeMiterLimit?this.strokeMiterLimit:\"4\",h=\"undefined\"!=typeof this.opacity?this.opacity:\"1\",c=this.visible?\"\":\" visibility: hidden;\",l=e?\"\":this.getSvgFilter(),u=t(\"fill\",this.fill),f=t(\"stroke\",this.stroke);return[f,\"stroke-width: \",r,\"; \",\"stroke-dasharray: \",n,\"; \",\"stroke-linecap: \",s,\"; \",\"stroke-linejoin: \",o,\"; \",\"stroke-miterlimit: \",a,\"; \",u,\"fill-rule: \",i,\"; \",\"opacity: \",h,\";\",l,c].join(\"\")},getSvgFilter:function(){return this.shadow?\"filter: url(#SVGID_\"+this.shadow.id+\");\":\"\"},getSvgTransform:function(){if(this.group&&\"path-group\"===this.group.type)return\"\";var t=fabric.util.toFixed,e=this.getAngle(),i=this.getSkewX()%360,r=this.getSkewY()%360,n=this.getCenterPoint(),s=fabric.Object.NUM_FRACTION_DIGITS,o=\"path-group\"===this.type?\"\":\"translate(\"+t(n.x,s)+\" \"+t(n.y,s)+\")\",a=0!==e?\" rotate(\"+t(e,s)+\")\":\"\",h=1===this.scaleX&&1===this.scaleY?\"\":\" scale(\"+t(this.scaleX,s)+\" \"+t(this.scaleY,s)+\")\",c=0!==i?\" skewX(\"+t(i,s)+\")\":\"\",l=0!==r?\" skewY(\"+t(r,s)+\")\":\"\",u=\"path-group\"===this.type?this.width:0,f=this.flipX?\" matrix(-1 0 0 1 \"+u+\" 0) \":\"\",d=\"path-group\"===this.type?this.height:0,g=this.flipY?\" matrix(1 0 0 -1 0 \"+d+\")\":\"\";\nreturn[o,a,h,f,g,c,l].join(\"\")},getSvgTransformMatrix:function(){return this.transformMatrix?\" matrix(\"+this.transformMatrix.join(\" \")+\") \":\"\"},_createBaseSVGMarkup:function(){var t=[];return this.fill&&this.fill.toLive&&t.push(this.fill.toSVG(this,!1)),this.stroke&&this.stroke.toLive&&t.push(this.stroke.toSVG(this,!1)),this.shadow&&t.push(this.shadow.toSVG(this)),t}})}(),fabric.util.object.extend(fabric.Object.prototype,{hasStateChanged:function(){return this.stateProperties.some(function(t){return this.get(t)!==this.originalState[t]},this)},saveState:function(t){return this.stateProperties.forEach(function(t){this.originalState[t]=this.get(t)},this),t&&t.stateProperties&&t.stateProperties.forEach(function(t){this.originalState[t]=this.get(t)},this),this},setupState:function(){return this.originalState={},this.saveState(),this}}),function(){var t=fabric.util.degreesToRadians,e=function(){return\"undefined\"!=typeof G_vmlCanvasManager};fabric.util.object.extend(fabric.Object.prototype,{_controlsVisibility:null,_findTargetCorner:function(t){if(!this.hasControls||!this.active)return!1;var e,i,r=t.x,n=t.y;this.__corner=0;for(var s in this.oCoords)if(this.isControlVisible(s)&&(\"mtr\"!==s||this.hasRotatingPoint)&&(!this.get(\"lockUniScaling\")||\"mt\"!==s&&\"mr\"!==s&&\"mb\"!==s&&\"ml\"!==s)&&(i=this._getImageLines(this.oCoords[s].corner),e=this._findCrossPoints({x:r,y:n},i),0!==e&&e%2===1))return this.__corner=s,s;return!1},_setCornerCoords:function(){var e,i,r=this.oCoords,n=t(45-this.angle),s=.707106*this.cornerSize,o=s*Math.cos(n),a=s*Math.sin(n);for(var h in r)e=r[h].x,i=r[h].y,r[h].corner={tl:{x:e-a,y:i-o},tr:{x:e+o,y:i-a},bl:{x:e-o,y:i+a},br:{x:e+a,y:i+o}}},_getNonTransformedDimensions:function(){var t=this.strokeWidth,e=this.width,i=this.height,r=!0,n=!0;return\"line\"===this.type&&\"butt\"===this.strokeLineCap&&(n=e,r=i),n&&(i+=0>i?-t:t),r&&(e+=0>e?-t:t),{x:e,y:i}},_getTransformedDimensions:function(t,e){\"undefined\"==typeof t&&(t=this.skewX),\"undefined\"==typeof e&&(e=this.skewY);var i,r,n=this._getNonTransformedDimensions(),s=n.x/2,o=n.y/2,a=[{x:-s,y:-o},{x:s,y:-o},{x:-s,y:o},{x:s,y:o}],h=this._calcDimensionsTransformMatrix(t,e,!1);for(i=0;i<a.length;i++)a[i]=fabric.util.transformPoint(a[i],h);return r=fabric.util.makeBoundingBoxFromPoints(a),{x:r.width,y:r.height}},_calculateCurrentDimensions:function(){var t=this.getViewportTransform(),e=this._getTransformedDimensions(),i=e.x,r=e.y;return i+=2*this.padding,r+=2*this.padding,fabric.util.transformPoint(new fabric.Point(i,r),t,!0)},drawSelectionBackground:function(e){if(!this.selectionBackgroundColor||!this.active||this.group)return this;e.save();var i=this.getCenterPoint(),r=this._calculateCurrentDimensions();return e.translate(i.x,i.y),e.rotate(t(this.angle)),e.fillStyle=this.selectionBackgroundColor,e.fillRect(-r.x/2,-r.y/2,r.x,r.y),e.restore(),this},drawBorders:function(t){if(!this.hasBorders)return this;var e=this._calculateCurrentDimensions(),i=1/this.borderScaleFactor,r=e.x+i,n=e.y+i;if(t.save(),t.strokeStyle=this.borderColor,this._setLineDash(t,this.borderDashArray,null),t.strokeRect(-r/2,-n/2,r,n),this.hasRotatingPoint&&this.isControlVisible(\"mtr\")&&!this.get(\"lockRotation\")&&this.hasControls){var s=-n/2;t.beginPath(),t.moveTo(0,s),t.lineTo(0,s-this.rotatingPointOffset),t.closePath(),t.stroke()}return t.restore(),this},drawBordersInGroup:function(t,e){if(!this.hasBorders)return this;var i=this._getNonTransformedDimensions(),r=fabric.util.customTransformMatrix(e.scaleX,e.scaleY,e.skewX),n=fabric.util.transformPoint(i,r),s=1/this.borderScaleFactor,o=n.x+s+2*this.padding,a=n.y+s+2*this.padding;return t.save(),this._setLineDash(t,this.borderDashArray,null),t.strokeStyle=this.borderColor,t.strokeRect(-o/2,-a/2,o,a),t.restore(),this},drawControls:function(t){if(!this.hasControls)return this;var e=this._calculateCurrentDimensions(),i=e.x,r=e.y,n=this.cornerSize,s=-(i+n)/2,o=-(r+n)/2,a=this.transparentCorners?\"stroke\":\"fill\";return t.save(),t.strokeStyle=t.fillStyle=this.cornerColor,this.transparentCorners||(t.strokeStyle=this.cornerStrokeColor),this._setLineDash(t,this.cornerDashArray,null),this._drawControl(\"tl\",t,a,s,o),this._drawControl(\"tr\",t,a,s+i,o),this._drawControl(\"bl\",t,a,s,o+r),this._drawControl(\"br\",t,a,s+i,o+r),this.get(\"lockUniScaling\")||(this._drawControl(\"mt\",t,a,s+i/2,o),this._drawControl(\"mb\",t,a,s+i/2,o+r),this._drawControl(\"mr\",t,a,s+i,o+r/2),this._drawControl(\"ml\",t,a,s,o+r/2)),this.hasRotatingPoint&&this._drawControl(\"mtr\",t,a,s+i/2,o-this.rotatingPointOffset),t.restore(),this},_drawControl:function(t,i,r,n,s){if(this.isControlVisible(t)){var o=this.cornerSize,a=!this.transparentCorners&&this.cornerStrokeColor;switch(this.cornerStyle){case\"circle\":i.beginPath(),i.arc(n+o/2,s+o/2,o/2,0,2*Math.PI,!1),i[r](),a&&i.stroke();break;default:e()||this.transparentCorners||i.clearRect(n,s,o,o),i[r+\"Rect\"](n,s,o,o),a&&i.strokeRect(n,s,o,o)}}},isControlVisible:function(t){return this._getControlsVisibility()[t]},setControlVisible:function(t,e){return this._getControlsVisibility()[t]=e,this},setControlsVisibility:function(t){t||(t={});for(var e in t)this.setControlVisible(e,t[e]);return this},_getControlsVisibility:function(){return this._controlsVisibility||(this._controlsVisibility={tl:!0,tr:!0,br:!0,bl:!0,ml:!0,mt:!0,mr:!0,mb:!0,mtr:!0}),this._controlsVisibility}})}(),fabric.util.object.extend(fabric.StaticCanvas.prototype,{FX_DURATION:500,fxCenterObjectH:function(t,e){e=e||{};var i=function(){},r=e.onComplete||i,n=e.onChange||i,s=this;return fabric.util.animate({startValue:t.get(\"left\"),endValue:this.getCenter().left,duration:this.FX_DURATION,onChange:function(e){t.set(\"left\",e),s.renderAll(),n()},onComplete:function(){t.setCoords(),r()}}),this},fxCenterObjectV:function(t,e){e=e||{};var i=function(){},r=e.onComplete||i,n=e.onChange||i,s=this;return fabric.util.animate({startValue:t.get(\"top\"),endValue:this.getCenter().top,duration:this.FX_DURATION,onChange:function(e){t.set(\"top\",e),s.renderAll(),n()},onComplete:function(){t.setCoords(),r()}}),this},fxRemove:function(t,e){e=e||{};var i=function(){},r=e.onComplete||i,n=e.onChange||i,s=this;return fabric.util.animate({startValue:t.get(\"opacity\"),endValue:0,duration:this.FX_DURATION,onStart:function(){t.set(\"active\",!1)},onChange:function(e){t.set(\"opacity\",e),s.renderAll(),n()},onComplete:function(){s.remove(t),r()}}),this}}),fabric.util.object.extend(fabric.Object.prototype,{animate:function(){if(arguments[0]&&\"object\"==typeof arguments[0]){var t,e,i=[];for(t in arguments[0])i.push(t);for(var r=0,n=i.length;n>r;r++)t=i[r],e=r!==n-1,this._animate(t,arguments[0][t],arguments[1],e)}else this._animate.apply(this,arguments);return this},_animate:function(t,e,i,r){var n,s=this;e=e.toString(),i=i?fabric.util.object.clone(i):{},~t.indexOf(\".\")&&(n=t.split(\".\"));var o=n?this.get(n[0])[n[1]]:this.get(t);\"from\"in i||(i.from=o),e=~e.indexOf(\"=\")?o+parseFloat(e.replace(\"=\",\"\")):parseFloat(e),fabric.util.animate({startValue:i.from,endValue:e,byValue:i.by,easing:i.easing,duration:i.duration,abort:i.abort&&function(){return i.abort.call(s)},onChange:function(e){n?s[n[0]][n[1]]=e:s.set(t,e),r||i.onChange&&i.onChange()},onComplete:function(){r||(s.setCoords(),i.onComplete&&i.onComplete())}})}}),function(t){\"use strict\";function e(t,e){var i=t.origin,r=t.axis1,n=t.axis2,s=t.dimension,o=e.nearest,a=e.center,h=e.farthest;return function(){switch(this.get(i)){case o:return Math.min(this.get(r),this.get(n));case a:return Math.min(this.get(r),this.get(n))+.5*this.get(s);case h:return Math.max(this.get(r),this.get(n))}}}var i=t.fabric||(t.fabric={}),r=i.util.object.extend,n={x1:1,x2:1,y1:1,y2:1},s=i.StaticCanvas.supports(\"setLineDash\");return i.Line?void i.warn(\"fabric.Line is already defined\"):(i.Line=i.util.createClass(i.Object,{type:\"line\",x1:0,y1:0,x2:0,y2:0,initialize:function(t,e){e=e||{},t||(t=[0,0,0,0]),this.callSuper(\"initialize\",e),this.set(\"x1\",t[0]),this.set(\"y1\",t[1]),this.set(\"x2\",t[2]),this.set(\"y2\",t[3]),this._setWidthHeight(e)},_setWidthHeight:function(t){t||(t={}),this.width=Math.abs(this.x2-this.x1),this.height=Math.abs(this.y2-this.y1),this.left=\"left\"in t?t.left:this._getLeftToOriginX(),this.top=\"top\"in t?t.top:this._getTopToOriginY()},_set:function(t,e){return this.callSuper(\"_set\",t,e),\"undefined\"!=typeof n[t]&&this._setWidthHeight(),this},_getLeftToOriginX:e({origin:\"originX\",axis1:\"x1\",axis2:\"x2\",dimension:\"width\"},{nearest:\"left\",center:\"center\",farthest:\"right\"}),_getTopToOriginY:e({origin:\"originY\",axis1:\"y1\",axis2:\"y2\",dimension:\"height\"},{nearest:\"top\",center:\"center\",farthest:\"bottom\"}),_render:function(t,e){if(t.beginPath(),e){var i=this.getCenterPoint();t.translate(i.x-this.strokeWidth/2,i.y-this.strokeWidth/2)}if(!this.strokeDashArray||this.strokeDashArray&&s){var r=this.calcLinePoints();t.moveTo(r.x1,r.y1),t.lineTo(r.x2,r.y2)}t.lineWidth=this.strokeWidth;var n=t.strokeStyle;t.strokeStyle=this.stroke||t.fillStyle,this.stroke&&this._renderStroke(t),t.strokeStyle=n},_renderDashedStroke:function(t){var e=this.calcLinePoints();t.beginPath(),i.util.drawDashedLine(t,e.x1,e.y1,e.x2,e.y2,this.strokeDashArray),t.closePath()},toObject:function(t){return r(this.callSuper(\"toObject\",t),this.calcLinePoints())},calcLinePoints:function(){var t=this.x1<=this.x2?-1:1,e=this.y1<=this.y2?-1:1,i=t*this.width*.5,r=e*this.height*.5,n=t*this.width*-.5,s=e*this.height*-.5;return{x1:i,x2:n,y1:r,y2:s}},toSVG:function(t){var e=this._createBaseSVGMarkup(),i={x1:this.x1,x2:this.x2,y1:this.y1,y2:this.y2};return this.group&&\"path-group\"===this.group.type||(i=this.calcLinePoints()),e.push(\"<line \",'x1=\"',i.x1,'\" y1=\"',i.y1,'\" x2=\"',i.x2,'\" y2=\"',i.y2,'\" style=\"',this.getSvgStyles(),'\" transform=\"',this.getSvgTransform(),this.getSvgTransformMatrix(),'\"/>\\n'),t?t(e.join(\"\")):e.join(\"\")},complexity:function(){return 1}}),i.Line.ATTRIBUTE_NAMES=i.SHARED_ATTRIBUTES.concat(\"x1 y1 x2 y2\".split(\" \")),i.Line.fromElement=function(t,e){var n=i.parseAttributes(t,i.Line.ATTRIBUTE_NAMES),s=[n.x1||0,n.y1||0,n.x2||0,n.y2||0];return new i.Line(s,r(n,e))},void(i.Line.fromObject=function(t){var e=[t.x1,t.y1,t.x2,t.y2];return new i.Line(e,t)}))}(\"undefined\"!=typeof exports?exports:this),function(t){\"use strict\";function e(t){return\"radius\"in t&&t.radius>=0}var i=t.fabric||(t.fabric={}),r=Math.PI,n=i.util.object.extend;return i.Circle?void i.warn(\"fabric.Circle is already defined.\"):(i.Circle=i.util.createClass(i.Object,{type:\"circle\",radius:0,startAngle:0,endAngle:2*r,initialize:function(t){t=t||{},this.callSuper(\"initialize\",t),this.set(\"radius\",t.radius||0),this.startAngle=t.startAngle||this.startAngle,this.endAngle=t.endAngle||this.endAngle},_set:function(t,e){return this.callSuper(\"_set\",t,e),\"radius\"===t&&this.setRadius(e),this},toObject:function(t){return n(this.callSuper(\"toObject\",t),{radius:this.get(\"radius\"),startAngle:this.startAngle,endAngle:this.endAngle})},toSVG:function(t){var e=this._createBaseSVGMarkup(),i=0,n=0,s=(this.endAngle-this.startAngle)%(2*r);if(0===s)this.group&&\"path-group\"===this.group.type&&(i=this.left+this.radius,n=this.top+this.radius),e.push(\"<circle \",'cx=\"'+i+'\" cy=\"'+n+'\" ','r=\"',this.radius,'\" style=\"',this.getSvgStyles(),'\" transform=\"',this.getSvgTransform(),\" \",this.getSvgTransformMatrix(),'\"/>\\n');else{var o=Math.cos(this.startAngle)*this.radius,a=Math.sin(this.startAngle)*this.radius,h=Math.cos(this.endAngle)*this.radius,c=Math.sin(this.endAngle)*this.radius,l=s>r?\"1\":\"0\";e.push('<path d=\"M '+o+\" \"+a,\" A \"+this.radius+\" \"+this.radius,\" 0 \",+l+\" 1\",\" \"+h+\" \"+c,'\" style=\"',this.getSvgStyles(),'\" transform=\"',this.getSvgTransform(),\" \",this.getSvgTransformMatrix(),'\"/>\\n')}return t?t(e.join(\"\")):e.join(\"\")},_render:function(t,e){t.beginPath(),t.arc(e?this.left+this.radius:0,e?this.top+this.radius:0,this.radius,this.startAngle,this.endAngle,!1),this._renderFill(t),this._renderStroke(t)},getRadiusX:function(){return this.get(\"radius\")*this.get(\"scaleX\")},getRadiusY:function(){return this.get(\"radius\")*this.get(\"scaleY\")},setRadius:function(t){return this.radius=t,this.set(\"width\",2*t).set(\"height\",2*t)},complexity:function(){return 1}}),i.Circle.ATTRIBUTE_NAMES=i.SHARED_ATTRIBUTES.concat(\"cx cy r\".split(\" \")),i.Circle.fromElement=function(t,r){r||(r={});var s=i.parseAttributes(t,i.Circle.ATTRIBUTE_NAMES);if(!e(s))throw new Error(\"value of `r` attribute is required and can not be negative\");s.left=s.left||0,s.top=s.top||0;var o=new i.Circle(n(s,r));return o.left-=o.radius,o.top-=o.radius,o},void(i.Circle.fromObject=function(t){return new i.Circle(t)}))}(\"undefined\"!=typeof exports?exports:this),function(t){\"use strict\";var e=t.fabric||(t.fabric={});return e.Triangle?void e.warn(\"fabric.Triangle is already defined\"):(e.Triangle=e.util.createClass(e.Object,{type:\"triangle\",initialize:function(t){t=t||{},this.callSuper(\"initialize\",t),this.set(\"width\",t.width||100).set(\"height\",t.height||100)},_render:function(t){var e=this.width/2,i=this.height/2;t.beginPath(),t.moveTo(-e,i),t.lineTo(0,-i),t.lineTo(e,i),t.closePath(),this._renderFill(t),this._renderStroke(t)},_renderDashedStroke:function(t){var i=this.width/2,r=this.height/2;t.beginPath(),e.util.drawDashedLine(t,-i,r,0,-r,this.strokeDashArray),e.util.drawDashedLine(t,0,-r,i,r,this.strokeDashArray),e.util.drawDashedLine(t,i,r,-i,r,this.strokeDashArray),t.closePath()},toSVG:function(t){var e=this._createBaseSVGMarkup(),i=this.width/2,r=this.height/2,n=[-i+\" \"+r,\"0 \"+-r,i+\" \"+r].join(\",\");return e.push(\"<polygon \",'points=\"',n,'\" style=\"',this.getSvgStyles(),'\" transform=\"',this.getSvgTransform(),'\"/>'),t?t(e.join(\"\")):e.join(\"\")},complexity:function(){return 1}}),void(e.Triangle.fromObject=function(t){return new e.Triangle(t)}))}(\"undefined\"!=typeof exports?exports:this),function(t){\"use strict\";var e=t.fabric||(t.fabric={}),i=2*Math.PI,r=e.util.object.extend;return e.Ellipse?void e.warn(\"fabric.Ellipse is already defined.\"):(e.Ellipse=e.util.createClass(e.Object,{type:\"ellipse\",rx:0,ry:0,initialize:function(t){t=t||{},this.callSuper(\"initialize\",t),this.set(\"rx\",t.rx||0),this.set(\"ry\",t.ry||0)},_set:function(t,e){switch(this.callSuper(\"_set\",t,e),t){case\"rx\":this.rx=e,this.set(\"width\",2*e);break;case\"ry\":this.ry=e,this.set(\"height\",2*e)}return this},getRx:function(){return this.get(\"rx\")*this.get(\"scaleX\")},getRy:function(){return this.get(\"ry\")*this.get(\"scaleY\")},toObject:function(t){return r(this.callSuper(\"toObject\",t),{rx:this.get(\"rx\"),ry:this.get(\"ry\")})},toSVG:function(t){var e=this._createBaseSVGMarkup(),i=0,r=0;return this.group&&\"path-group\"===this.group.type&&(i=this.left+this.rx,r=this.top+this.ry),e.push(\"<ellipse \",'cx=\"',i,'\" cy=\"',r,'\" ','rx=\"',this.rx,'\" ry=\"',this.ry,'\" style=\"',this.getSvgStyles(),'\" transform=\"',this.getSvgTransform(),this.getSvgTransformMatrix(),'\"/>\\n'),t?t(e.join(\"\")):e.join(\"\")},_render:function(t,e){t.beginPath(),t.save(),t.transform(1,0,0,this.ry/this.rx,0,0),t.arc(e?this.left+this.rx:0,e?(this.top+this.ry)*this.rx/this.ry:0,this.rx,0,i,!1),t.restore(),this._renderFill(t),this._renderStroke(t)},complexity:function(){return 1}}),e.Ellipse.ATTRIBUTE_NAMES=e.SHARED_ATTRIBUTES.concat(\"cx cy rx ry\".split(\" \")),e.Ellipse.fromElement=function(t,i){i||(i={});var n=e.parseAttributes(t,e.Ellipse.ATTRIBUTE_NAMES);n.left=n.left||0,n.top=n.top||0;var s=new e.Ellipse(r(n,i));return s.top-=s.ry,s.left-=s.rx,s},void(e.Ellipse.fromObject=function(t){return new e.Ellipse(t)}))}(\"undefined\"!=typeof exports?exports:this),function(t){\"use strict\";var e=t.fabric||(t.fabric={}),i=e.util.object.extend;if(e.Rect)return void e.warn(\"fabric.Rect is already defined\");var r=e.Object.prototype.stateProperties.concat();r.push(\"rx\",\"ry\",\"x\",\"y\"),e.Rect=e.util.createClass(e.Object,{stateProperties:r,type:\"rect\",rx:0,ry:0,strokeDashArray:null,initialize:function(t){t=t||{},this.callSuper(\"initialize\",t),this._initRxRy()},_initRxRy:function(){this.rx&&!this.ry?this.ry=this.rx:this.ry&&!this.rx&&(this.rx=this.ry)},_render:function(t,e){if(1===this.width&&1===this.height)return void t.fillRect(-.5,-.5,1,1);var i=this.rx?Math.min(this.rx,this.width/2):0,r=this.ry?Math.min(this.ry,this.height/2):0,n=this.width,s=this.height,o=e?this.left:-this.width/2,a=e?this.top:-this.height/2,h=0!==i||0!==r,c=.4477152502;t.beginPath(),t.moveTo(o+i,a),t.lineTo(o+n-i,a),h&&t.bezierCurveTo(o+n-c*i,a,o+n,a+c*r,o+n,a+r),t.lineTo(o+n,a+s-r),h&&t.bezierCurveTo(o+n,a+s-c*r,o+n-c*i,a+s,o+n-i,a+s),t.lineTo(o+i,a+s),h&&t.bezierCurveTo(o+c*i,a+s,o,a+s-c*r,o,a+s-r),t.lineTo(o,a+r),h&&t.bezierCurveTo(o,a+c*r,o+c*i,a,o+i,a),t.closePath(),this._renderFill(t),this._renderStroke(t)},_renderDashedStroke:function(t){var i=-this.width/2,r=-this.height/2,n=this.width,s=this.height;t.beginPath(),e.util.drawDashedLine(t,i,r,i+n,r,this.strokeDashArray),e.util.drawDashedLine(t,i+n,r,i+n,r+s,this.strokeDashArray),e.util.drawDashedLine(t,i+n,r+s,i,r+s,this.strokeDashArray),e.util.drawDashedLine(t,i,r+s,i,r,this.strokeDashArray),t.closePath()},toObject:function(t){var e=i(this.callSuper(\"toObject\",t),{rx:this.get(\"rx\")||0,ry:this.get(\"ry\")||0});return this.includeDefaultValues||this._removeDefaultValues(e),e},toSVG:function(t){var e=this._createBaseSVGMarkup(),i=this.left,r=this.top;return this.group&&\"path-group\"===this.group.type||(i=-this.width/2,r=-this.height/2),e.push(\"<rect \",'x=\"',i,'\" y=\"',r,'\" rx=\"',this.get(\"rx\"),'\" ry=\"',this.get(\"ry\"),'\" width=\"',this.width,'\" height=\"',this.height,'\" style=\"',this.getSvgStyles(),'\" transform=\"',this.getSvgTransform(),this.getSvgTransformMatrix(),'\"/>\\n'),t?t(e.join(\"\")):e.join(\"\")},complexity:function(){return 1}}),e.Rect.ATTRIBUTE_NAMES=e.SHARED_ATTRIBUTES.concat(\"x y rx ry width height\".split(\" \")),e.Rect.fromElement=function(t,r){if(!t)return null;r=r||{};var n=e.parseAttributes(t,e.Rect.ATTRIBUTE_NAMES);n.left=n.left||0,n.top=n.top||0;var s=new e.Rect(i(r?e.util.object.clone(r):{},n));return s.visible=s.width>0&&s.height>0,s},e.Rect.fromObject=function(t){return new e.Rect(t)}}(\"undefined\"!=typeof exports?exports:this),function(t){\"use strict\";var e=t.fabric||(t.fabric={});return e.Polyline?void e.warn(\"fabric.Polyline is already defined\"):(e.Polyline=e.util.createClass(e.Object,{type:\"polyline\",points:null,minX:0,minY:0,initialize:function(t,i){return e.Polygon.prototype.initialize.call(this,t,i)},_calcDimensions:function(){return e.Polygon.prototype._calcDimensions.call(this)},_applyPointOffset:function(){return e.Polygon.prototype._applyPointOffset.call(this)},toObject:function(t){return e.Polygon.prototype.toObject.call(this,t)},toSVG:function(t){return e.Polygon.prototype.toSVG.call(this,t)},_render:function(t,i){e.Polygon.prototype.commonRender.call(this,t,i)&&(this._renderFill(t),this._renderStroke(t))},_renderDashedStroke:function(t){var i,r;t.beginPath();for(var n=0,s=this.points.length;s>n;n++)i=this.points[n],r=this.points[n+1]||i,e.util.drawDashedLine(t,i.x,i.y,r.x,r.y,this.strokeDashArray)},complexity:function(){return this.get(\"points\").length}}),e.Polyline.ATTRIBUTE_NAMES=e.SHARED_ATTRIBUTES.concat(),e.Polyline.fromElement=function(t,i){if(!t)return null;i||(i={});var r=e.parsePointsAttribute(t.getAttribute(\"points\")),n=e.parseAttributes(t,e.Polyline.ATTRIBUTE_NAMES);return new e.Polyline(r,e.util.object.extend(n,i))},void(e.Polyline.fromObject=function(t){var i=t.points;return new e.Polyline(i,t,!0)}))}(\"undefined\"!=typeof exports?exports:this),function(t){\"use strict\";var e=t.fabric||(t.fabric={}),i=e.util.object.extend,r=e.util.array.min,n=e.util.array.max,s=e.util.toFixed;return e.Polygon?void e.warn(\"fabric.Polygon is already defined\"):(e.Polygon=e.util.createClass(e.Object,{type:\"polygon\",points:null,minX:0,minY:0,initialize:function(t,e){e=e||{},this.points=t||[],this.callSuper(\"initialize\",e),this._calcDimensions(),\"top\"in e||(this.top=this.minY),\"left\"in e||(this.left=this.minX),this.pathOffset={x:this.minX+this.width/2,y:this.minY+this.height/2}},_calcDimensions:function(){var t=this.points,e=r(t,\"x\"),i=r(t,\"y\"),s=n(t,\"x\"),o=n(t,\"y\");this.width=s-e||0,this.height=o-i||0,this.minX=e||0,this.minY=i||0},toObject:function(t){return i(this.callSuper(\"toObject\",t),{points:this.points.concat()})},toSVG:function(t){for(var e,i=[],r=this._createBaseSVGMarkup(),n=0,o=this.points.length;o>n;n++)i.push(s(this.points[n].x,2),\",\",s(this.points[n].y,2),\" \");return this.group&&\"path-group\"===this.group.type||(e=\" translate(\"+-this.pathOffset.x+\", \"+-this.pathOffset.y+\") \"),r.push(\"<\",this.type,\" \",'points=\"',i.join(\"\"),'\" style=\"',this.getSvgStyles(),'\" transform=\"',this.getSvgTransform(),e,\" \",this.getSvgTransformMatrix(),'\"/>\\n'),t?t(r.join(\"\")):r.join(\"\")},_render:function(t,e){this.commonRender(t,e)&&(this._renderFill(t),(this.stroke||this.strokeDashArray)&&(t.closePath(),this._renderStroke(t)))},commonRender:function(t,e){var i,r=this.points.length;if(!r||isNaN(this.points[r-1].y))return!1;e||t.translate(-this.pathOffset.x,-this.pathOffset.y),t.beginPath(),t.moveTo(this.points[0].x,this.points[0].y);for(var n=0;r>n;n++)i=this.points[n],t.lineTo(i.x,i.y);return!0},_renderDashedStroke:function(t){e.Polyline.prototype._renderDashedStroke.call(this,t),t.closePath()},complexity:function(){return this.points.length}}),e.Polygon.ATTRIBUTE_NAMES=e.SHARED_ATTRIBUTES.concat(),e.Polygon.fromElement=function(t,r){if(!t)return null;r||(r={});var n=e.parsePointsAttribute(t.getAttribute(\"points\")),s=e.parseAttributes(t,e.Polygon.ATTRIBUTE_NAMES);return new e.Polygon(n,i(s,r))},void(e.Polygon.fromObject=function(t){return new e.Polygon(t.points,t,!0)}))}(\"undefined\"!=typeof exports?exports:this),function(t){\"use strict\";var e=t.fabric||(t.fabric={}),i=e.util.array.min,r=e.util.array.max,n=e.util.object.extend,s=Object.prototype.toString,o=e.util.drawArc,a={m:2,l:2,h:1,v:1,c:6,s:4,q:4,t:2,a:7},h={m:\"l\",M:\"L\"};return e.Path?void e.warn(\"fabric.Path is already defined\"):(e.Path=e.util.createClass(e.Object,{type:\"path\",path:null,minX:0,minY:0,initialize:function(t,e){e=e||{},this.setOptions(e),t||(t=[]);var i=\"[object Array]\"===s.call(t);this.path=i?t:t.match&&t.match(/[mzlhvcsqta][^mzlhvcsqta]*/gi),this.path&&(i||(this.path=this._parsePath()),this._setPositionDimensions(e),e.sourcePath&&this.setSourcePath(e.sourcePath))},_setPositionDimensions:function(t){var e=this._parseDimensions();this.minX=e.left,this.minY=e.top,this.width=e.width,this.height=e.height,\"undefined\"==typeof t.left&&(this.left=e.left+(\"center\"===this.originX?this.width/2:\"right\"===this.originX?this.width:0)),\"undefined\"==typeof t.top&&(this.top=e.top+(\"center\"===this.originY?this.height/2:\"bottom\"===this.originY?this.height:0)),this.pathOffset=this.pathOffset||{x:this.minX+this.width/2,y:this.minY+this.height/2}},_render:function(t){var e,i,r,n=null,s=0,a=0,h=0,c=0,l=0,u=0,f=-this.pathOffset.x,d=-this.pathOffset.y;this.group&&\"path-group\"===this.group.type&&(f=0,d=0),t.beginPath();for(var g=0,p=this.path.length;p>g;++g){switch(e=this.path[g],e[0]){case\"l\":h+=e[1],c+=e[2],t.lineTo(h+f,c+d);break;case\"L\":h=e[1],c=e[2],t.lineTo(h+f,c+d);break;case\"h\":h+=e[1],t.lineTo(h+f,c+d);break;case\"H\":h=e[1],t.lineTo(h+f,c+d);break;case\"v\":c+=e[1],t.lineTo(h+f,c+d);break;case\"V\":c=e[1],t.lineTo(h+f,c+d);break;case\"m\":h+=e[1],c+=e[2],s=h,a=c,t.moveTo(h+f,c+d);break;case\"M\":h=e[1],c=e[2],s=h,a=c,t.moveTo(h+f,c+d);break;case\"c\":i=h+e[5],r=c+e[6],l=h+e[3],u=c+e[4],t.bezierCurveTo(h+e[1]+f,c+e[2]+d,l+f,u+d,i+f,r+d),h=i,c=r;break;case\"C\":h=e[5],c=e[6],l=e[3],u=e[4],t.bezierCurveTo(e[1]+f,e[2]+d,l+f,u+d,h+f,c+d);break;case\"s\":i=h+e[3],r=c+e[4],null===n[0].match(/[CcSs]/)?(l=h,u=c):(l=2*h-l,u=2*c-u),t.bezierCurveTo(l+f,u+d,h+e[1]+f,c+e[2]+d,i+f,r+d),l=h+e[1],u=c+e[2],h=i,c=r;break;case\"S\":i=e[3],r=e[4],null===n[0].match(/[CcSs]/)?(l=h,u=c):(l=2*h-l,u=2*c-u),t.bezierCurveTo(l+f,u+d,e[1]+f,e[2]+d,i+f,r+d),h=i,c=r,l=e[1],u=e[2];break;case\"q\":i=h+e[3],r=c+e[4],l=h+e[1],u=c+e[2],t.quadraticCurveTo(l+f,u+d,i+f,r+d),h=i,c=r;break;case\"Q\":i=e[3],r=e[4],t.quadraticCurveTo(e[1]+f,e[2]+d,i+f,r+d),h=i,c=r,l=e[1],u=e[2];break;case\"t\":i=h+e[1],r=c+e[2],null===n[0].match(/[QqTt]/)?(l=h,u=c):(l=2*h-l,u=2*c-u),t.quadraticCurveTo(l+f,u+d,i+f,r+d),h=i,c=r;break;case\"T\":i=e[1],r=e[2],null===n[0].match(/[QqTt]/)?(l=h,u=c):(l=2*h-l,u=2*c-u),t.quadraticCurveTo(l+f,u+d,i+f,r+d),h=i,c=r;break;case\"a\":o(t,h+f,c+d,[e[1],e[2],e[3],e[4],e[5],e[6]+h+f,e[7]+c+d]),h+=e[6],c+=e[7];break;case\"A\":o(t,h+f,c+d,[e[1],e[2],e[3],e[4],e[5],e[6]+f,e[7]+d]),h=e[6],c=e[7];break;case\"z\":case\"Z\":h=s,c=a,t.closePath()}n=e}this._renderFill(t),this._renderStroke(t)},toString:function(){return\"#<fabric.Path (\"+this.complexity()+'): { \"top\": '+this.top+', \"left\": '+this.left+\" }>\"},toObject:function(t){var e=n(this.callSuper(\"toObject\",t),{path:this.path.map(function(t){return t.slice()}),pathOffset:this.pathOffset});return this.sourcePath&&(e.sourcePath=this.sourcePath),this.transformMatrix&&(e.transformMatrix=this.transformMatrix),e},toDatalessObject:function(t){var e=this.toObject(t);return this.sourcePath&&(e.path=this.sourcePath),delete e.sourcePath,e},toSVG:function(t){for(var e=[],i=this._createBaseSVGMarkup(),r=\"\",n=0,s=this.path.length;s>n;n++)e.push(this.path[n].join(\" \"));var o=e.join(\" \");return this.group&&\"path-group\"===this.group.type||(r=\" translate(\"+-this.pathOffset.x+\", \"+-this.pathOffset.y+\") \"),i.push(\"<path \",'d=\"',o,'\" style=\"',this.getSvgStyles(),'\" transform=\"',this.getSvgTransform(),r,this.getSvgTransformMatrix(),'\" stroke-linecap=\"round\" ',\"/>\\n\"),t?t(i.join(\"\")):i.join(\"\")},complexity:function(){return this.path.length},_parsePath:function(){for(var t,e,i,r,n,s=[],o=[],c=/([-+]?((\\d+\\.\\d+)|((\\d+)|(\\.\\d+)))(?:e[-+]?\\d+)?)/gi,l=0,u=this.path.length;u>l;l++){for(t=this.path[l],r=t.slice(1).trim(),o.length=0;i=c.exec(r);)o.push(i[0]);n=[t.charAt(0)];for(var f=0,d=o.length;d>f;f++)e=parseFloat(o[f]),isNaN(e)||n.push(e);var g=n[0],p=a[g.toLowerCase()],v=h[g]||g;if(n.length-1>p)for(var b=1,m=n.length;m>b;b+=p)s.push([g].concat(n.slice(b,b+p))),g=v;else s.push(n)}return s},_parseDimensions:function(){for(var t,n,s,o,a=[],h=[],c=null,l=0,u=0,f=0,d=0,g=0,p=0,v=0,b=this.path.length;b>v;++v){switch(t=this.path[v],t[0]){case\"l\":f+=t[1],d+=t[2],o=[];break;case\"L\":f=t[1],d=t[2],o=[];break;case\"h\":f+=t[1],o=[];break;case\"H\":f=t[1],o=[];break;case\"v\":d+=t[1],o=[];break;case\"V\":d=t[1],o=[];break;case\"m\":f+=t[1],d+=t[2],l=f,u=d,o=[];break;case\"M\":f=t[1],d=t[2],l=f,u=d,o=[];break;case\"c\":n=f+t[5],s=d+t[6],g=f+t[3],p=d+t[4],o=e.util.getBoundsOfCurve(f,d,f+t[1],d+t[2],g,p,n,s),f=n,d=s;break;case\"C\":f=t[5],d=t[6],g=t[3],p=t[4],o=e.util.getBoundsOfCurve(f,d,t[1],t[2],g,p,f,d);break;case\"s\":n=f+t[3],s=d+t[4],null===c[0].match(/[CcSs]/)?(g=f,p=d):(g=2*f-g,p=2*d-p),o=e.util.getBoundsOfCurve(f,d,g,p,f+t[1],d+t[2],n,s),g=f+t[1],p=d+t[2],f=n,d=s;break;case\"S\":n=t[3],s=t[4],null===c[0].match(/[CcSs]/)?(g=f,p=d):(g=2*f-g,p=2*d-p),o=e.util.getBoundsOfCurve(f,d,g,p,t[1],t[2],n,s),f=n,d=s,g=t[1],p=t[2];break;case\"q\":n=f+t[3],s=d+t[4],g=f+t[1],p=d+t[2],o=e.util.getBoundsOfCurve(f,d,g,p,g,p,n,s),f=n,d=s;break;case\"Q\":g=t[1],p=t[2],o=e.util.getBoundsOfCurve(f,d,g,p,g,p,t[3],t[4]),f=t[3],d=t[4];break;case\"t\":n=f+t[1],s=d+t[2],null===c[0].match(/[QqTt]/)?(g=f,p=d):(g=2*f-g,p=2*d-p),o=e.util.getBoundsOfCurve(f,d,g,p,g,p,n,s),f=n,d=s;break;case\"T\":n=t[1],s=t[2],null===c[0].match(/[QqTt]/)?(g=f,p=d):(g=2*f-g,p=2*d-p),o=e.util.getBoundsOfCurve(f,d,g,p,g,p,n,s),f=n,d=s;break;case\"a\":o=e.util.getBoundsOfArc(f,d,t[1],t[2],t[3],t[4],t[5],t[6]+f,t[7]+d),f+=t[6],d+=t[7];break;case\"A\":o=e.util.getBoundsOfArc(f,d,t[1],t[2],t[3],t[4],t[5],t[6],t[7]),f=t[6],d=t[7];break;case\"z\":case\"Z\":f=l,d=u}c=t,o.forEach(function(t){a.push(t.x),h.push(t.y)}),a.push(f),h.push(d)}var m=i(a)||0,y=i(h)||0,_=r(a)||0,x=r(h)||0,S=_-m,C=x-y,w={left:m,top:y,width:S,height:C};return w}}),e.Path.fromObject=function(t,i){\"string\"==typeof t.path?e.loadSVGFromURL(t.path,function(r){var n=r[0],s=t.path;delete t.path,e.util.object.extend(n,t),n.setSourcePath(s),i(n)}):i(new e.Path(t.path,t))},e.Path.ATTRIBUTE_NAMES=e.SHARED_ATTRIBUTES.concat([\"d\"]),e.Path.fromElement=function(t,i,r){var s=e.parseAttributes(t,e.Path.ATTRIBUTE_NAMES);i&&i(new e.Path(s.d,n(s,r)))},void(e.Path.async=!0))}(\"undefined\"!=typeof exports?exports:this),function(t){\"use strict\";var e=t.fabric||(t.fabric={}),i=e.util.object.extend,r=e.util.array.invoke,n=e.Object.prototype.toObject;return e.PathGroup?void e.warn(\"fabric.PathGroup is already defined\"):(e.PathGroup=e.util.createClass(e.Path,{type:\"path-group\",fill:\"\",initialize:function(t,e){e=e||{},this.paths=t||[];for(var i=this.paths.length;i--;)this.paths[i].group=this;e.toBeParsed&&(this.parseDimensionsFromPaths(e),delete e.toBeParsed),this.setOptions(e),this.setCoords(),e.sourcePath&&this.setSourcePath(e.sourcePath)},parseDimensionsFromPaths:function(t){for(var i,r,n,s,o,a,h=[],c=[],l=this.paths.length;l--;){n=this.paths[l],s=n.height+n.strokeWidth,o=n.width+n.strokeWidth,i=[{x:n.left,y:n.top},{x:n.left+o,y:n.top},{x:n.left,y:n.top+s},{x:n.left+o,y:n.top+s}],a=this.paths[l].transformMatrix;for(var u=0;u<i.length;u++)r=i[u],a&&(r=e.util.transformPoint(r,a,!1)),h.push(r.x),c.push(r.y)}t.width=Math.max.apply(null,h),t.height=Math.max.apply(null,c)},render:function(t){if(this.visible){t.save(),this.transformMatrix&&t.transform.apply(t,this.transformMatrix),this.transform(t),this._setShadow(t),this.clipTo&&e.util.clipContext(this,t),t.translate(-this.width/2,-this.height/2);for(var i=0,r=this.paths.length;r>i;++i)this.paths[i].render(t,!0);this.clipTo&&t.restore(),t.restore()}},_set:function(t,e){if(\"fill\"===t&&e&&this.isSameColor())for(var i=this.paths.length;i--;)this.paths[i]._set(t,e);return this.callSuper(\"_set\",t,e)},toObject:function(t){var e=i(n.call(this,t),{paths:r(this.getObjects(),\"toObject\",t)});return this.sourcePath&&(e.sourcePath=this.sourcePath),e},toDatalessObject:function(t){var e=this.toObject(t);return this.sourcePath&&(e.paths=this.sourcePath),e},toSVG:function(t){var e=this.getObjects(),i=this.getPointByOrigin(\"left\",\"top\"),r=\"translate(\"+i.x+\" \"+i.y+\")\",n=this._createBaseSVGMarkup();n.push(\"<g \",'style=\"',this.getSvgStyles(),'\" ','transform=\"',this.getSvgTransformMatrix(),r,this.getSvgTransform(),'\" ',\">\\n\");for(var s=0,o=e.length;o>s;s++)n.push(\"\t\",e[s].toSVG(t));return n.push(\"</g>\\n\"),t?t(n.join(\"\")):n.join(\"\")},toString:function(){return\"#<fabric.PathGroup (\"+this.complexity()+\"): { top: \"+this.top+\", left: \"+this.left+\" }>\"},isSameColor:function(){var t=this.getObjects()[0].get(\"fill\")||\"\";return\"string\"!=typeof t?!1:(t=t.toLowerCase(),this.getObjects().every(function(e){var i=e.get(\"fill\")||\"\";return\"string\"==typeof i&&i.toLowerCase()===t}))},complexity:function(){return this.paths.reduce(function(t,e){return t+(e&&e.complexity?e.complexity():0)},0)},getObjects:function(){return this.paths}}),e.PathGroup.fromObject=function(t,i){\"string\"==typeof t.paths?e.loadSVGFromURL(t.paths,function(r){var n=t.paths;delete t.paths;var s=e.util.groupSVGElements(r,t,n);i(s)}):e.util.enlivenObjects(t.paths,function(r){delete t.paths,i(new e.PathGroup(r,t))})},void(e.PathGroup.async=!0))}(\"undefined\"!=typeof exports?exports:this),function(t){\"use strict\";var e=t.fabric||(t.fabric={}),i=e.util.object.extend,r=e.util.array.min,n=e.util.array.max,s=e.util.array.invoke;if(!e.Group){var o={lockMovementX:!0,lockMovementY:!0,lockRotation:!0,lockScalingX:!0,lockScalingY:!0,lockUniScaling:!0};e.Group=e.util.createClass(e.Object,e.Collection,{type:\"group\",strokeWidth:0,initialize:function(t,e,i){e=e||{},this._objects=[],i&&this.callSuper(\"initialize\",e),this._objects=t||[];for(var r=this._objects.length;r--;)this._objects[r].group=this;this.originalState={},e.originX&&(this.originX=e.originX),e.originY&&(this.originY=e.originY),i?this._updateObjectsCoords(!0):(this._calcBounds(),this._updateObjectsCoords(),this.callSuper(\"initialize\",e)),this.setCoords(),this.saveCoords()},_updateObjectsCoords:function(t){for(var e=this._objects.length;e--;)this._updateObjectCoords(this._objects[e],t)},_updateObjectCoords:function(t,e){if(t.__origHasControls=t.hasControls,t.hasControls=!1,!e){var i=t.getLeft(),r=t.getTop(),n=this.getCenterPoint();t.set({originalLeft:i,originalTop:r,\nleft:i-n.x,top:r-n.y}),t.setCoords()}},toString:function(){return\"#<fabric.Group: (\"+this.complexity()+\")>\"},addWithUpdate:function(t){return this._restoreObjectsState(),e.util.resetObjectTransform(this),t&&(this._objects.push(t),t.group=this,t._set(\"canvas\",this.canvas)),this.forEachObject(this._setObjectActive,this),this._calcBounds(),this._updateObjectsCoords(),this},_setObjectActive:function(t){t.set(\"active\",!0),t.group=this},removeWithUpdate:function(t){return this._restoreObjectsState(),e.util.resetObjectTransform(this),this.forEachObject(this._setObjectActive,this),this.remove(t),this._calcBounds(),this._updateObjectsCoords(),this},_onObjectAdded:function(t){t.group=this,t._set(\"canvas\",this.canvas)},_onObjectRemoved:function(t){delete t.group,t.set(\"active\",!1)},delegatedProperties:{fill:!0,stroke:!0,strokeWidth:!0,fontFamily:!0,fontWeight:!0,fontSize:!0,fontStyle:!0,lineHeight:!0,textDecoration:!0,textAlign:!0,backgroundColor:!0},_set:function(t,e){var i=this._objects.length;if(this.delegatedProperties[t]||\"canvas\"===t)for(;i--;)this._objects[i].set(t,e);else for(;i--;)this._objects[i].setOnGroup(t,e);this.callSuper(\"_set\",t,e)},toObject:function(t){return i(this.callSuper(\"toObject\",t),{objects:s(this._objects,\"toObject\",t)})},render:function(t){if(this.visible){t.save(),this.transformMatrix&&t.transform.apply(t,this.transformMatrix),this.transform(t),this._setShadow(t),this.clipTo&&e.util.clipContext(this,t);for(var i=0,r=this._objects.length;r>i;i++)this._renderObject(this._objects[i],t);this.clipTo&&t.restore(),t.restore()}},_renderControls:function(t,e){this.callSuper(\"_renderControls\",t,e);for(var i=0,r=this._objects.length;r>i;i++)this._objects[i]._renderControls(t)},_renderObject:function(t,e){if(t.visible){var i=t.hasRotatingPoint;t.hasRotatingPoint=!1,t.render(e),t.hasRotatingPoint=i}},_restoreObjectsState:function(){return this._objects.forEach(this._restoreObjectState,this),this},realizeTransform:function(t){var i=t.calcTransformMatrix(),r=e.util.qrDecompose(i),n=new e.Point(r.translateX,r.translateY);return t.scaleX=r.scaleX,t.scaleY=r.scaleY,t.skewX=r.skewX,t.skewY=r.skewY,t.angle=r.angle,t.flipX=!1,t.flipY=!1,t.setPositionByOrigin(n,\"center\",\"center\"),t},_restoreObjectState:function(t){return this.realizeTransform(t),t.setCoords(),t.hasControls=t.__origHasControls,delete t.__origHasControls,t.set(\"active\",!1),delete t.group,this},destroy:function(){return this._restoreObjectsState()},saveCoords:function(){return this._originalLeft=this.get(\"left\"),this._originalTop=this.get(\"top\"),this},hasMoved:function(){return this._originalLeft!==this.get(\"left\")||this._originalTop!==this.get(\"top\")},setObjectsCoords:function(){return this.forEachObject(function(t){t.setCoords()}),this},_calcBounds:function(t){for(var e,i,r,n=[],s=[],o=[\"tr\",\"br\",\"bl\",\"tl\"],a=0,h=this._objects.length,c=o.length;h>a;++a)for(e=this._objects[a],e.setCoords(),r=0;c>r;r++)i=o[r],n.push(e.oCoords[i].x),s.push(e.oCoords[i].y);this.set(this._getBounds(n,s,t))},_getBounds:function(t,i,s){var o=e.util.invertTransform(this.getViewportTransform()),a=e.util.transformPoint(new e.Point(r(t),r(i)),o),h=e.util.transformPoint(new e.Point(n(t),n(i)),o),c={width:h.x-a.x||0,height:h.y-a.y||0};return s||(c.left=a.x||0,c.top=a.y||0,\"center\"===this.originX&&(c.left+=c.width/2),\"right\"===this.originX&&(c.left+=c.width),\"center\"===this.originY&&(c.top+=c.height/2),\"bottom\"===this.originY&&(c.top+=c.height)),c},toSVG:function(t){var e=this._createBaseSVGMarkup();e.push('<g transform=\"',this.getSvgTransform(),this.getSvgTransformMatrix(),'\" style=\"',this.getSvgFilter(),'\">\\n');for(var i=0,r=this._objects.length;r>i;i++)e.push(\"\t\",this._objects[i].toSVG(t));return e.push(\"</g>\\n\"),t?t(e.join(\"\")):e.join(\"\")},get:function(t){if(t in o){if(this[t])return this[t];for(var e=0,i=this._objects.length;i>e;e++)if(this._objects[e][t])return!0;return!1}return t in this.delegatedProperties?this._objects[0]&&this._objects[0].get(t):this[t]}}),e.Group.fromObject=function(t,i){e.util.enlivenObjects(t.objects,function(r){delete t.objects,i&&i(new e.Group(r,t,!0))})},e.Group.async=!0}}(\"undefined\"!=typeof exports?exports:this),function(t){\"use strict\";var e=fabric.util.object.extend;return t.fabric||(t.fabric={}),t.fabric.Image?void fabric.warn(\"fabric.Image is already defined.\"):(fabric.Image=fabric.util.createClass(fabric.Object,{type:\"image\",crossOrigin:\"\",alignX:\"none\",alignY:\"none\",meetOrSlice:\"meet\",strokeWidth:0,_lastScaleX:1,_lastScaleY:1,initialize:function(t,e){e||(e={}),this.filters=[],this.resizeFilters=[],this.callSuper(\"initialize\",e),this._initElement(t,e)},getElement:function(){return this._element},setElement:function(t,e,i){return this._element=t,this._originalElement=t,this._initConfig(i),0!==this.filters.length?this.applyFilters(e):e&&e(),this},setCrossOrigin:function(t){return this.crossOrigin=t,this._element.crossOrigin=t,this},getOriginalSize:function(){var t=this.getElement();return{width:t.width,height:t.height}},_stroke:function(t){if(this.stroke&&0!==this.strokeWidth){var e=this.width/2,i=this.height/2;t.beginPath(),t.moveTo(-e,-i),t.lineTo(e,-i),t.lineTo(e,i),t.lineTo(-e,i),t.lineTo(-e,-i),t.closePath()}},_renderDashedStroke:function(t){var e=-this.width/2,i=-this.height/2,r=this.width,n=this.height;t.save(),this._setStrokeStyles(t),t.beginPath(),fabric.util.drawDashedLine(t,e,i,e+r,i,this.strokeDashArray),fabric.util.drawDashedLine(t,e+r,i,e+r,i+n,this.strokeDashArray),fabric.util.drawDashedLine(t,e+r,i+n,e,i+n,this.strokeDashArray),fabric.util.drawDashedLine(t,e,i+n,e,i,this.strokeDashArray),t.closePath(),t.restore()},toObject:function(t){var i=[],r=[],n=this._originalElement,s=1,o=1;this.filters.forEach(function(t){t&&(\"Resize\"===t.type&&(s*=t.scaleX,o*=t.scaleY),i.push(t.toObject()))}),this.resizeFilters.forEach(function(t){t&&r.push(t.toObject())});var a=e(this.callSuper(\"toObject\",t),{src:n?n.src||n._src:\"\",filters:i,resizeFilters:r,crossOrigin:this.crossOrigin,alignX:this.alignX,alignY:this.alignY,meetOrSlice:this.meetOrSlice});return a.width/=s,a.height/=o,this.includeDefaultValues||this._removeDefaultValues(a),a},toSVG:function(t){var e=this._createBaseSVGMarkup(),i=-this.width/2,r=-this.height/2,n=\"none\";if(this.group&&\"path-group\"===this.group.type&&(i=this.left,r=this.top),\"none\"!==this.alignX&&\"none\"!==this.alignY&&(n=\"x\"+this.alignX+\"Y\"+this.alignY+\" \"+this.meetOrSlice),e.push('<g transform=\"',this.getSvgTransform(),this.getSvgTransformMatrix(),'\">\\n','<image xlink:href=\"',this.getSvgSrc(),'\" x=\"',i,'\" y=\"',r,'\" style=\"',this.getSvgStyles(),'\" width=\"',this.width,'\" height=\"',this.height,'\" preserveAspectRatio=\"',n,'\"',\"></image>\\n\"),this.stroke||this.strokeDashArray){var s=this.fill;this.fill=null,e.push(\"<rect \",'x=\"',i,'\" y=\"',r,'\" width=\"',this.width,'\" height=\"',this.height,'\" style=\"',this.getSvgStyles(),'\"/>\\n'),this.fill=s}return e.push(\"</g>\\n\"),t?t(e.join(\"\")):e.join(\"\")},getSrc:function(){return this.getElement()?this.getElement().src||this.getElement()._src:void 0},setSrc:function(t,e,i){fabric.util.loadImage(t,function(t){return this.setElement(t,e,i)},this,i&&i.crossOrigin)},toString:function(){return'#<fabric.Image: { src: \"'+this.getSrc()+'\" }>'},clone:function(t,e){this.constructor.fromObject(this.toObject(e),t)},applyFilters:function(t,e,i,r){if(e=e||this.filters,i=i||this._originalElement){var n=i,s=fabric.util.createCanvasElement(),o=fabric.util.createImage(),a=this;return s.width=n.width,s.height=n.height,s.getContext(\"2d\").drawImage(n,0,0,n.width,n.height),0===e.length?(this._element=i,t&&t(),s):(e.forEach(function(t){t&&t.applyTo(s,t.scaleX||a.scaleX,t.scaleY||a.scaleY),!r&&t&&\"Resize\"===t.type&&(a.width*=t.scaleX,a.height*=t.scaleY)}),o.width=s.width,o.height=s.height,fabric.isLikelyNode?(o.src=s.toBuffer(void 0,fabric.Image.pngCompression),a._element=o,!r&&(a._filteredEl=o),t&&t()):(o.onload=function(){a._element=o,!r&&(a._filteredEl=o),t&&t(),o.onload=s=n=null},o.src=s.toDataURL(\"image/png\")),s)}},_render:function(t,e){var i,r,n,s=this._findMargins();i=e?this.left:-this.width/2,r=e?this.top:-this.height/2,\"slice\"===this.meetOrSlice&&(t.beginPath(),t.rect(i,r,this.width,this.height),t.clip()),this.isMoving===!1&&this.resizeFilters.length&&this._needsResize()?(this._lastScaleX=this.scaleX,this._lastScaleY=this.scaleY,n=this.applyFilters(null,this.resizeFilters,this._filteredEl||this._originalElement,!0)):n=this._element,n&&t.drawImage(n,i+s.marginX,r+s.marginY,s.width,s.height),this._stroke(t),this._renderStroke(t)},_needsResize:function(){return this.scaleX!==this._lastScaleX||this.scaleY!==this._lastScaleY},_findMargins:function(){var t,e,i=this.width,r=this.height,n=0,s=0;return\"none\"===this.alignX&&\"none\"===this.alignY||(t=[this.width/this._element.width,this.height/this._element.height],e=\"meet\"===this.meetOrSlice?Math.min.apply(null,t):Math.max.apply(null,t),i=this._element.width*e,r=this._element.height*e,\"Mid\"===this.alignX&&(n=(this.width-i)/2),\"Max\"===this.alignX&&(n=this.width-i),\"Mid\"===this.alignY&&(s=(this.height-r)/2),\"Max\"===this.alignY&&(s=this.height-r)),{width:i,height:r,marginX:n,marginY:s}},_resetWidthHeight:function(){var t=this.getElement();this.set(\"width\",t.width),this.set(\"height\",t.height)},_initElement:function(t,e){this.setElement(fabric.util.getById(t),null,e),fabric.util.addClass(this.getElement(),fabric.Image.CSS_CANVAS)},_initConfig:function(t){t||(t={}),this.setOptions(t),this._setWidthHeight(t),this._element&&this.crossOrigin&&(this._element.crossOrigin=this.crossOrigin)},_initFilters:function(t,e){t&&t.length?fabric.util.enlivenObjects(t,function(t){e&&e(t)},\"fabric.Image.filters\"):e&&e()},_setWidthHeight:function(t){this.width=\"width\"in t?t.width:this.getElement()?this.getElement().width||0:0,this.height=\"height\"in t?t.height:this.getElement()?this.getElement().height||0:0},complexity:function(){return 1}}),fabric.Image.CSS_CANVAS=\"canvas-img\",fabric.Image.prototype.getSvgSrc=fabric.Image.prototype.getSrc,fabric.Image.fromObject=function(t,e){fabric.util.loadImage(t.src,function(i){fabric.Image.prototype._initFilters.call(t,t.filters,function(r){t.filters=r||[],fabric.Image.prototype._initFilters.call(t,t.resizeFilters,function(r){t.resizeFilters=r||[];var n=new fabric.Image(i,t);e&&e(n)})})},null,t.crossOrigin)},fabric.Image.fromURL=function(t,e,i){fabric.util.loadImage(t,function(t){e&&e(new fabric.Image(t,i))},null,i&&i.crossOrigin)},fabric.Image.ATTRIBUTE_NAMES=fabric.SHARED_ATTRIBUTES.concat(\"x y width height preserveAspectRatio xlink:href\".split(\" \")),fabric.Image.fromElement=function(t,i,r){var n,s=fabric.parseAttributes(t,fabric.Image.ATTRIBUTE_NAMES);s.preserveAspectRatio&&(n=fabric.util.parsePreserveAspectRatioAttribute(s.preserveAspectRatio),e(s,n)),fabric.Image.fromURL(s[\"xlink:href\"],i,e(r?fabric.util.object.clone(r):{},s))},fabric.Image.async=!0,void(fabric.Image.pngCompression=1))}(\"undefined\"!=typeof exports?exports:this),fabric.util.object.extend(fabric.Object.prototype,{_getAngleValueForStraighten:function(){var t=this.getAngle()%360;return t>0?90*Math.round((t-1)/90):90*Math.round(t/90)},straighten:function(){return this.setAngle(this._getAngleValueForStraighten()),this},fxStraighten:function(t){t=t||{};var e=function(){},i=t.onComplete||e,r=t.onChange||e,n=this;return fabric.util.animate({startValue:this.get(\"angle\"),endValue:this._getAngleValueForStraighten(),duration:this.FX_DURATION,onChange:function(t){n.setAngle(t),r()},onComplete:function(){n.setCoords(),i()},onStart:function(){n.set(\"active\",!1)}}),this}}),fabric.util.object.extend(fabric.StaticCanvas.prototype,{straightenObject:function(t){return t.straighten(),this.renderAll(),this},fxStraightenObject:function(t){return t.fxStraighten({onChange:this.renderAll.bind(this)}),this}}),fabric.Image.filters=fabric.Image.filters||{},fabric.Image.filters.BaseFilter=fabric.util.createClass({type:\"BaseFilter\",initialize:function(t){t&&this.setOptions(t)},setOptions:function(t){for(var e in t)this[e]=t[e]},toObject:function(){return{type:this.type}},toJSON:function(){return this.toObject()}}),function(t){\"use strict\";var e=t.fabric||(t.fabric={}),i=e.util.object.extend;e.Image.filters.Brightness=e.util.createClass(e.Image.filters.BaseFilter,{type:\"Brightness\",initialize:function(t){t=t||{},this.brightness=t.brightness||0},applyTo:function(t){for(var e=t.getContext(\"2d\"),i=e.getImageData(0,0,t.width,t.height),r=i.data,n=this.brightness,s=0,o=r.length;o>s;s+=4)r[s]+=n,r[s+1]+=n,r[s+2]+=n;e.putImageData(i,0,0)},toObject:function(){return i(this.callSuper(\"toObject\"),{brightness:this.brightness})}}),e.Image.filters.Brightness.fromObject=function(t){return new e.Image.filters.Brightness(t)}}(\"undefined\"!=typeof exports?exports:this),function(t){\"use strict\";var e=t.fabric||(t.fabric={}),i=e.util.object.extend;e.Image.filters.Convolute=e.util.createClass(e.Image.filters.BaseFilter,{type:\"Convolute\",initialize:function(t){t=t||{},this.opaque=t.opaque,this.matrix=t.matrix||[0,0,0,0,1,0,0,0,0]},applyTo:function(t){for(var e,i,r,n,s,o,a,h,c,l=this.matrix,u=t.getContext(\"2d\"),f=u.getImageData(0,0,t.width,t.height),d=Math.round(Math.sqrt(l.length)),g=Math.floor(d/2),p=f.data,v=f.width,b=f.height,m=u.createImageData(v,b),y=m.data,_=this.opaque?1:0,x=0;b>x;x++)for(var S=0;v>S;S++){s=4*(x*v+S),e=0,i=0,r=0,n=0;for(var C=0;d>C;C++)for(var w=0;d>w;w++)a=x+C-g,o=S+w-g,0>a||a>b||0>o||o>v||(h=4*(a*v+o),c=l[C*d+w],e+=p[h]*c,i+=p[h+1]*c,r+=p[h+2]*c,n+=p[h+3]*c);y[s]=e,y[s+1]=i,y[s+2]=r,y[s+3]=n+_*(255-n)}u.putImageData(m,0,0)},toObject:function(){return i(this.callSuper(\"toObject\"),{opaque:this.opaque,matrix:this.matrix})}}),e.Image.filters.Convolute.fromObject=function(t){return new e.Image.filters.Convolute(t)}}(\"undefined\"!=typeof exports?exports:this),function(t){\"use strict\";var e=t.fabric||(t.fabric={}),i=e.util.object.extend;e.Image.filters.GradientTransparency=e.util.createClass(e.Image.filters.BaseFilter,{type:\"GradientTransparency\",initialize:function(t){t=t||{},this.threshold=t.threshold||100},applyTo:function(t){for(var e=t.getContext(\"2d\"),i=e.getImageData(0,0,t.width,t.height),r=i.data,n=this.threshold,s=r.length,o=0,a=r.length;a>o;o+=4)r[o+3]=n+255*(s-o)/s;e.putImageData(i,0,0)},toObject:function(){return i(this.callSuper(\"toObject\"),{threshold:this.threshold})}}),e.Image.filters.GradientTransparency.fromObject=function(t){return new e.Image.filters.GradientTransparency(t)}}(\"undefined\"!=typeof exports?exports:this),function(t){\"use strict\";var e=t.fabric||(t.fabric={});e.Image.filters.Grayscale=e.util.createClass(e.Image.filters.BaseFilter,{type:\"Grayscale\",applyTo:function(t){for(var e,i=t.getContext(\"2d\"),r=i.getImageData(0,0,t.width,t.height),n=r.data,s=r.width*r.height*4,o=0;s>o;)e=(n[o]+n[o+1]+n[o+2])/3,n[o]=e,n[o+1]=e,n[o+2]=e,o+=4;i.putImageData(r,0,0)}}),e.Image.filters.Grayscale.fromObject=function(){return new e.Image.filters.Grayscale}}(\"undefined\"!=typeof exports?exports:this),function(t){\"use strict\";var e=t.fabric||(t.fabric={});e.Image.filters.Invert=e.util.createClass(e.Image.filters.BaseFilter,{type:\"Invert\",applyTo:function(t){var e,i=t.getContext(\"2d\"),r=i.getImageData(0,0,t.width,t.height),n=r.data,s=n.length;for(e=0;s>e;e+=4)n[e]=255-n[e],n[e+1]=255-n[e+1],n[e+2]=255-n[e+2];i.putImageData(r,0,0)}}),e.Image.filters.Invert.fromObject=function(){return new e.Image.filters.Invert}}(\"undefined\"!=typeof exports?exports:this),function(t){\"use strict\";var e=t.fabric||(t.fabric={}),i=e.util.object.extend;e.Image.filters.Mask=e.util.createClass(e.Image.filters.BaseFilter,{type:\"Mask\",initialize:function(t){t=t||{},this.mask=t.mask,this.channel=[0,1,2,3].indexOf(t.channel)>-1?t.channel:0},applyTo:function(t){if(this.mask){var i,r=t.getContext(\"2d\"),n=r.getImageData(0,0,t.width,t.height),s=n.data,o=this.mask.getElement(),a=e.util.createCanvasElement(),h=this.channel,c=n.width*n.height*4;a.width=t.width,a.height=t.height,a.getContext(\"2d\").drawImage(o,0,0,t.width,t.height);var l=a.getContext(\"2d\").getImageData(0,0,t.width,t.height),u=l.data;for(i=0;c>i;i+=4)s[i+3]=u[i+h];r.putImageData(n,0,0)}},toObject:function(){return i(this.callSuper(\"toObject\"),{mask:this.mask.toObject(),channel:this.channel})}}),e.Image.filters.Mask.fromObject=function(t,i){e.util.loadImage(t.mask.src,function(r){t.mask=new e.Image(r,t.mask),i&&i(new e.Image.filters.Mask(t))})},e.Image.filters.Mask.async=!0}(\"undefined\"!=typeof exports?exports:this),function(t){\"use strict\";var e=t.fabric||(t.fabric={}),i=e.util.object.extend;e.Image.filters.Noise=e.util.createClass(e.Image.filters.BaseFilter,{type:\"Noise\",initialize:function(t){t=t||{},this.noise=t.noise||0},applyTo:function(t){for(var e,i=t.getContext(\"2d\"),r=i.getImageData(0,0,t.width,t.height),n=r.data,s=this.noise,o=0,a=n.length;a>o;o+=4)e=(.5-Math.random())*s,n[o]+=e,n[o+1]+=e,n[o+2]+=e;i.putImageData(r,0,0)},toObject:function(){return i(this.callSuper(\"toObject\"),{noise:this.noise})}}),e.Image.filters.Noise.fromObject=function(t){return new e.Image.filters.Noise(t)}}(\"undefined\"!=typeof exports?exports:this),function(t){\"use strict\";var e=t.fabric||(t.fabric={}),i=e.util.object.extend;e.Image.filters.Pixelate=e.util.createClass(e.Image.filters.BaseFilter,{type:\"Pixelate\",initialize:function(t){t=t||{},this.blocksize=t.blocksize||4},applyTo:function(t){var e,i,r,n,s,o,a,h=t.getContext(\"2d\"),c=h.getImageData(0,0,t.width,t.height),l=c.data,u=c.height,f=c.width;for(i=0;u>i;i+=this.blocksize)for(r=0;f>r;r+=this.blocksize){e=4*i*f+4*r,n=l[e],s=l[e+1],o=l[e+2],a=l[e+3];for(var d=i,g=i+this.blocksize;g>d;d++)for(var p=r,v=r+this.blocksize;v>p;p++)e=4*d*f+4*p,l[e]=n,l[e+1]=s,l[e+2]=o,l[e+3]=a}h.putImageData(c,0,0)},toObject:function(){return i(this.callSuper(\"toObject\"),{blocksize:this.blocksize})}}),e.Image.filters.Pixelate.fromObject=function(t){return new e.Image.filters.Pixelate(t)}}(\"undefined\"!=typeof exports?exports:this),function(t){\"use strict\";var e=t.fabric||(t.fabric={}),i=e.util.object.extend;e.Image.filters.RemoveWhite=e.util.createClass(e.Image.filters.BaseFilter,{type:\"RemoveWhite\",initialize:function(t){t=t||{},this.threshold=t.threshold||30,this.distance=t.distance||20},applyTo:function(t){for(var e,i,r,n=t.getContext(\"2d\"),s=n.getImageData(0,0,t.width,t.height),o=s.data,a=this.threshold,h=this.distance,c=255-a,l=Math.abs,u=0,f=o.length;f>u;u+=4)e=o[u],i=o[u+1],r=o[u+2],e>c&&i>c&&r>c&&l(e-i)<h&&l(e-r)<h&&l(i-r)<h&&(o[u+3]=0);n.putImageData(s,0,0)},toObject:function(){return i(this.callSuper(\"toObject\"),{threshold:this.threshold,distance:this.distance})}}),e.Image.filters.RemoveWhite.fromObject=function(t){return new e.Image.filters.RemoveWhite(t)}}(\"undefined\"!=typeof exports?exports:this),function(t){\"use strict\";var e=t.fabric||(t.fabric={});e.Image.filters.Sepia=e.util.createClass(e.Image.filters.BaseFilter,{type:\"Sepia\",applyTo:function(t){var e,i,r=t.getContext(\"2d\"),n=r.getImageData(0,0,t.width,t.height),s=n.data,o=s.length;for(e=0;o>e;e+=4)i=.3*s[e]+.59*s[e+1]+.11*s[e+2],s[e]=i+100,s[e+1]=i+50,s[e+2]=i+255;r.putImageData(n,0,0)}}),e.Image.filters.Sepia.fromObject=function(){return new e.Image.filters.Sepia}}(\"undefined\"!=typeof exports?exports:this),function(t){\"use strict\";var e=t.fabric||(t.fabric={});e.Image.filters.Sepia2=e.util.createClass(e.Image.filters.BaseFilter,{type:\"Sepia2\",applyTo:function(t){var e,i,r,n,s=t.getContext(\"2d\"),o=s.getImageData(0,0,t.width,t.height),a=o.data,h=a.length;for(e=0;h>e;e+=4)i=a[e],r=a[e+1],n=a[e+2],a[e]=(.393*i+.769*r+.189*n)/1.351,a[e+1]=(.349*i+.686*r+.168*n)/1.203,a[e+2]=(.272*i+.534*r+.131*n)/2.14;s.putImageData(o,0,0)}}),e.Image.filters.Sepia2.fromObject=function(){return new e.Image.filters.Sepia2}}(\"undefined\"!=typeof exports?exports:this),function(t){\"use strict\";var e=t.fabric||(t.fabric={}),i=e.util.object.extend;e.Image.filters.Tint=e.util.createClass(e.Image.filters.BaseFilter,{type:\"Tint\",initialize:function(t){t=t||{},this.color=t.color||\"#000000\",this.opacity=\"undefined\"!=typeof t.opacity?t.opacity:new e.Color(this.color).getAlpha()},applyTo:function(t){var i,r,n,s,o,a,h,c,l,u=t.getContext(\"2d\"),f=u.getImageData(0,0,t.width,t.height),d=f.data,g=d.length;for(l=new e.Color(this.color).getSource(),r=l[0]*this.opacity,n=l[1]*this.opacity,s=l[2]*this.opacity,c=1-this.opacity,i=0;g>i;i+=4)o=d[i],a=d[i+1],h=d[i+2],d[i]=r+o*c,d[i+1]=n+a*c,d[i+2]=s+h*c;u.putImageData(f,0,0)},toObject:function(){return i(this.callSuper(\"toObject\"),{color:this.color,opacity:this.opacity})}}),e.Image.filters.Tint.fromObject=function(t){return new e.Image.filters.Tint(t)}}(\"undefined\"!=typeof exports?exports:this),function(t){\"use strict\";var e=t.fabric||(t.fabric={}),i=e.util.object.extend;e.Image.filters.Multiply=e.util.createClass(e.Image.filters.BaseFilter,{type:\"Multiply\",initialize:function(t){t=t||{},this.color=t.color||\"#000000\"},applyTo:function(t){var i,r,n=t.getContext(\"2d\"),s=n.getImageData(0,0,t.width,t.height),o=s.data,a=o.length;for(r=new e.Color(this.color).getSource(),i=0;a>i;i+=4)o[i]*=r[0]/255,o[i+1]*=r[1]/255,o[i+2]*=r[2]/255;n.putImageData(s,0,0)},toObject:function(){return i(this.callSuper(\"toObject\"),{color:this.color})}}),e.Image.filters.Multiply.fromObject=function(t){return new e.Image.filters.Multiply(t)}}(\"undefined\"!=typeof exports?exports:this),function(t){\"use strict\";var e=t.fabric;e.Image.filters.Blend=e.util.createClass(e.Image.filters.BaseFilter,{type:\"Blend\",initialize:function(t){t=t||{},this.color=t.color||\"#000\",this.image=t.image||!1,this.mode=t.mode||\"multiply\",this.alpha=t.alpha||1},applyTo:function(t){var i,r,n,s,o,a,h,c,l,u,f=t.getContext(\"2d\"),d=f.getImageData(0,0,t.width,t.height),g=d.data,p=!1;if(this.image){p=!0;var v=e.util.createCanvasElement();v.width=this.image.width,v.height=this.image.height;var b=new e.StaticCanvas(v);b.add(this.image);var m=b.getContext(\"2d\");u=m.getImageData(0,0,b.width,b.height).data}else u=new e.Color(this.color).getSource(),i=u[0]*this.alpha,r=u[1]*this.alpha,n=u[2]*this.alpha;for(var y=0,_=g.length;_>y;y+=4)switch(s=g[y],o=g[y+1],a=g[y+2],p&&(i=u[y]*this.alpha,r=u[y+1]*this.alpha,n=u[y+2]*this.alpha),this.mode){case\"multiply\":g[y]=s*i/255,g[y+1]=o*r/255,g[y+2]=a*n/255;break;case\"screen\":g[y]=1-(1-s)*(1-i),g[y+1]=1-(1-o)*(1-r),g[y+2]=1-(1-a)*(1-n);break;case\"add\":g[y]=Math.min(255,s+i),g[y+1]=Math.min(255,o+r),g[y+2]=Math.min(255,a+n);break;case\"diff\":case\"difference\":g[y]=Math.abs(s-i),g[y+1]=Math.abs(o-r),g[y+2]=Math.abs(a-n);break;case\"subtract\":h=s-i,c=o-r,l=a-n,g[y]=0>h?0:h,g[y+1]=0>c?0:c,g[y+2]=0>l?0:l;break;case\"darken\":g[y]=Math.min(s,i),g[y+1]=Math.min(o,r),g[y+2]=Math.min(a,n);break;case\"lighten\":g[y]=Math.max(s,i),g[y+1]=Math.max(o,r),g[y+2]=Math.max(a,n)}f.putImageData(d,0,0)},toObject:function(){return{color:this.color,image:this.image,mode:this.mode,alpha:this.alpha}}}),e.Image.filters.Blend.fromObject=function(t){return new e.Image.filters.Blend(t)}}(\"undefined\"!=typeof exports?exports:this),function(t){\"use strict\";var e=t.fabric||(t.fabric={}),i=Math.pow,r=Math.floor,n=Math.sqrt,s=Math.abs,o=Math.max,a=Math.round,h=Math.sin,c=Math.ceil;e.Image.filters.Resize=e.util.createClass(e.Image.filters.BaseFilter,{type:\"Resize\",resizeType:\"hermite\",scaleX:0,scaleY:0,lanczosLobes:3,applyTo:function(t,e,i){this.rcpScaleX=1/e,this.rcpScaleY=1/i;var r,n=t.width,s=t.height,o=a(n*e),h=a(s*i);\"sliceHack\"===this.resizeType&&(r=this.sliceByTwo(t,n,s,o,h)),\"hermite\"===this.resizeType&&(r=this.hermiteFastResize(t,n,s,o,h)),\"bilinear\"===this.resizeType&&(r=this.bilinearFiltering(t,n,s,o,h)),\"lanczos\"===this.resizeType&&(r=this.lanczosResize(t,n,s,o,h)),t.width=o,t.height=h,t.getContext(\"2d\").putImageData(r,0,0)},sliceByTwo:function(t,i,n,s,a){var h,c=t.getContext(\"2d\"),l=.5,u=.5,f=1,d=1,g=!1,p=!1,v=i,b=n,m=e.util.createCanvasElement(),y=m.getContext(\"2d\");for(s=r(s),a=r(a),m.width=o(s,i),m.height=o(a,n),s>i&&(l=2,f=-1),a>n&&(u=2,d=-1),h=c.getImageData(0,0,i,n),t.width=o(s,i),t.height=o(a,n),c.putImageData(h,0,0);!g||!p;)i=v,n=b,s*f<r(v*l*f)?v=r(v*l):(v=s,g=!0),a*d<r(b*u*d)?b=r(b*u):(b=a,p=!0),h=c.getImageData(0,0,i,n),y.putImageData(h,0,0),c.clearRect(0,0,v,b),c.drawImage(m,0,0,i,n,0,0,v,b);return c.getImageData(0,0,s,a)},lanczosResize:function(t,e,o,a,l){function u(t){return function(e){if(e>t)return 0;if(e*=Math.PI,s(e)<1e-16)return 1;var i=e/t;return h(e)*h(i)/e/i}}function f(t){var h,c,u,d,g,j,A,M,P,L,D;for(T.x=(t+.5)*y,k.x=r(T.x),h=0;l>h;h++){for(T.y=(h+.5)*_,k.y=r(T.y),g=0,j=0,A=0,M=0,P=0,c=k.x-C;c<=k.x+C;c++)if(!(0>c||c>=e)){L=r(1e3*s(c-T.x)),O[L]||(O[L]={});for(var E=k.y-w;E<=k.y+w;E++)0>E||E>=o||(D=r(1e3*s(E-T.y)),O[L][D]||(O[L][D]=m(n(i(L*x,2)+i(D*S,2))/1e3)),u=O[L][D],u>0&&(d=4*(E*e+c),g+=u,j+=u*v[d],A+=u*v[d+1],M+=u*v[d+2],P+=u*v[d+3]))}d=4*(h*a+t),b[d]=j/g,b[d+1]=A/g,b[d+2]=M/g,b[d+3]=P/g}return++t<a?f(t):p}var d=t.getContext(\"2d\"),g=d.getImageData(0,0,e,o),p=d.getImageData(0,0,a,l),v=g.data,b=p.data,m=u(this.lanczosLobes),y=this.rcpScaleX,_=this.rcpScaleY,x=2/this.rcpScaleX,S=2/this.rcpScaleY,C=c(y*this.lanczosLobes/2),w=c(_*this.lanczosLobes/2),O={},T={},k={};return f(0)},bilinearFiltering:function(t,e,i,n,s){var o,a,h,c,l,u,f,d,g,p,v,b,m,y=0,_=this.rcpScaleX,x=this.rcpScaleY,S=t.getContext(\"2d\"),C=4*(e-1),w=S.getImageData(0,0,e,i),O=w.data,T=S.getImageData(0,0,n,s),k=T.data;for(f=0;s>f;f++)for(d=0;n>d;d++)for(l=r(_*d),u=r(x*f),g=_*d-l,p=x*f-u,m=4*(u*e+l),v=0;4>v;v++)o=O[m+v],a=O[m+4+v],h=O[m+C+v],c=O[m+C+4+v],b=o*(1-g)*(1-p)+a*g*(1-p)+h*p*(1-g)+c*g*p,k[y++]=b;return T},hermiteFastResize:function(t,e,i,o,a){for(var h=this.rcpScaleX,l=this.rcpScaleY,u=c(h/2),f=c(l/2),d=t.getContext(\"2d\"),g=d.getImageData(0,0,e,i),p=g.data,v=d.getImageData(0,0,o,a),b=v.data,m=0;a>m;m++)for(var y=0;o>y;y++){for(var _=4*(y+m*o),x=0,S=0,C=0,w=0,O=0,T=0,k=0,j=(m+.5)*l,A=r(m*l);(m+1)*l>A;A++)for(var M=s(j-(A+.5))/f,P=(y+.5)*h,L=M*M,D=r(y*h);(y+1)*h>D;D++){var E=s(P-(D+.5))/u,I=n(L+E*E);I>1&&-1>I||(x=2*I*I*I-3*I*I+1,x>0&&(E=4*(D+A*e),k+=x*p[E+3],C+=x,p[E+3]<255&&(x=x*p[E+3]/250),w+=x*p[E],O+=x*p[E+1],T+=x*p[E+2],S+=x))}b[_]=w/S,b[_+1]=O/S,b[_+2]=T/S,b[_+3]=k/C}return v},toObject:function(){return{type:this.type,scaleX:this.scaleX,scaleY:this.scaleY,resizeType:this.resizeType,lanczosLobes:this.lanczosLobes}}}),e.Image.filters.Resize.fromObject=function(t){return new e.Image.filters.Resize(t)}}(\"undefined\"!=typeof exports?exports:this),function(t){\"use strict\";var e=t.fabric||(t.fabric={}),i=e.util.object.extend,r=e.util.object.clone,n=e.util.toFixed,s=e.StaticCanvas.supports(\"setLineDash\"),o=e.Object.NUM_FRACTION_DIGITS;if(e.Text)return void e.warn(\"fabric.Text is already defined\");var a=e.Object.prototype.stateProperties.concat();a.push(\"fontFamily\",\"fontWeight\",\"fontSize\",\"text\",\"textDecoration\",\"textAlign\",\"fontStyle\",\"lineHeight\",\"textBackgroundColor\"),e.Text=e.util.createClass(e.Object,{_dimensionAffectingProps:{fontSize:!0,fontWeight:!0,fontFamily:!0,fontStyle:!0,lineHeight:!0,stroke:!0,strokeWidth:!0,text:!0,textAlign:!0},_reNewline:/\\r?\\n/,_reSpacesAndTabs:/[ \\t\\r]+/g,type:\"text\",fontSize:40,fontWeight:\"normal\",fontFamily:\"Times New Roman\",textDecoration:\"\",textAlign:\"left\",fontStyle:\"\",lineHeight:1.16,textBackgroundColor:\"\",stateProperties:a,stroke:null,shadow:null,_fontSizeFraction:.25,_fontSizeMult:1.13,initialize:function(t,e){e=e||{},this.text=t,this.__skipDimension=!0,this.setOptions(e),this.__skipDimension=!1,this._initDimensions()},_initDimensions:function(t){this.__skipDimension||(t||(t=e.util.createCanvasElement().getContext(\"2d\"),this._setTextStyles(t)),this._textLines=this._splitTextIntoLines(),this._clearCache(),this.width=this._getTextWidth(t),this.height=this._getTextHeight(t))},toString:function(){return\"#<fabric.Text (\"+this.complexity()+'): { \"text\": \"'+this.text+'\", \"fontFamily\": \"'+this.fontFamily+'\" }>'},_render:function(t){this.clipTo&&e.util.clipContext(this,t),this._setOpacity(t),this._setShadow(t),this._setupCompositeOperation(t),this._renderTextBackground(t),this._setStrokeStyles(t),this._setFillStyles(t),this._renderText(t),this._renderTextDecoration(t),this.clipTo&&t.restore()},_renderText:function(t){this._translateForTextAlign(t),this._renderTextFill(t),this._renderTextStroke(t),this._translateForTextAlign(t,!0)},_translateForTextAlign:function(t,e){if(\"left\"!==this.textAlign&&\"justify\"!==this.textAlign){var i=e?-1:1;t.translate(\"center\"===this.textAlign?i*this.width/2:i*this.width,0)}},_setTextStyles:function(t){t.textBaseline=\"alphabetic\",this.skipTextAlign||(t.textAlign=this.textAlign),t.font=this._getFontDeclaration()},_getTextHeight:function(){return this._textLines.length*this._getHeightOfLine()},_getTextWidth:function(t){for(var e=this._getLineWidth(t,0),i=1,r=this._textLines.length;r>i;i++){var n=this._getLineWidth(t,i);n>e&&(e=n)}return e},_renderChars:function(t,e,i,r,n){var s=t.slice(0,-4);if(this[s].toLive){var o=-this.width/2+this[s].offsetX||0,a=-this.height/2+this[s].offsetY||0;e.save(),e.translate(o,a),r-=o,n-=a}e[t](i,r,n),this[s].toLive&&e.restore()},_renderTextLine:function(t,e,i,r,n,s){n-=this.fontSize*this._fontSizeFraction;var o=this._getLineWidth(e,s);if(\"justify\"!==this.textAlign||this.width<o)return void this._renderChars(t,e,i,r,n,s);for(var a,h=i.split(/\\s+/),c=0,l=this._getWidthOfWords(e,i,s,0),u=this.width-l,f=h.length-1,d=f>0?u/f:0,g=0,p=0,v=h.length;v>p;p++){for(;\" \"===i[c]&&c<i.length;)c++;a=h[p],this._renderChars(t,e,a,r+g,n,s,c),g+=this._getWidthOfWords(e,a,s,c)+d,c+=a.length}},_getWidthOfWords:function(t,e){return t.measureText(e.replace(/\\s+/g,\"\")).width},_getLeftOffset:function(){return-this.width/2},_getTopOffset:function(){return-this.height/2},isEmptyStyles:function(){return!0},_renderTextFill:function(t){if(this.fill||!this.isEmptyStyles())for(var e=0,i=0,r=this._textLines.length;r>i;i++){var n=this._getHeightOfLine(t,i),s=n/this.lineHeight;this._renderTextLine(\"fillText\",t,this._textLines[i],this._getLeftOffset(),this._getTopOffset()+e+s,i),e+=n}},_renderTextStroke:function(t){if(this.stroke&&0!==this.strokeWidth||!this.isEmptyStyles()){var e=0;this.shadow&&!this.shadow.affectStroke&&this._removeShadow(t),t.save(),this.strokeDashArray&&(1&this.strokeDashArray.length&&this.strokeDashArray.push.apply(this.strokeDashArray,this.strokeDashArray),s&&t.setLineDash(this.strokeDashArray)),t.beginPath();for(var i=0,r=this._textLines.length;r>i;i++){var n=this._getHeightOfLine(t,i),o=n/this.lineHeight;this._renderTextLine(\"strokeText\",t,this._textLines[i],this._getLeftOffset(),this._getTopOffset()+e+o,i),e+=n}t.closePath(),t.restore()}},_getHeightOfLine:function(){return this.fontSize*this._fontSizeMult*this.lineHeight},_renderTextBackground:function(t){this._renderTextBoxBackground(t),this._renderTextLinesBackground(t)},_renderTextBoxBackground:function(t){this.backgroundColor&&(t.fillStyle=this.backgroundColor,t.fillRect(this._getLeftOffset(),this._getTopOffset(),this.width,this.height),this._removeShadow(t))},_renderTextLinesBackground:function(t){if(this.textBackgroundColor){var e,i,r,n=0;t.fillStyle=this.textBackgroundColor;for(var s=0,o=this._textLines.length;o>s;s++)e=this._getHeightOfLine(t,s),i=this._getLineWidth(t,s),i>0&&(r=this._getLineLeftOffset(i),t.fillRect(this._getLeftOffset()+r,this._getTopOffset()+n,i,e/this.lineHeight)),n+=e;this._removeShadow(t)}},_getLineLeftOffset:function(t){return\"center\"===this.textAlign?(this.width-t)/2:\"right\"===this.textAlign?this.width-t:0},_clearCache:function(){this.__lineWidths=[],this.__lineHeights=[]},_shouldClearCache:function(){var t=!1;if(this._forceClearCache)return this._forceClearCache=!1,!0;for(var e in this._dimensionAffectingProps)this[\"__\"+e]!==this[e]&&(this[\"__\"+e]=this[e],t=!0);return t},_getLineWidth:function(t,e){if(this.__lineWidths[e])return-1===this.__lineWidths[e]?this.width:this.__lineWidths[e];var i,r,n=this._textLines[e];return i=\"\"===n?0:this._measureLine(t,e),this.__lineWidths[e]=i,i&&\"justify\"===this.textAlign&&(r=n.split(/\\s+/),r.length>1&&(this.__lineWidths[e]=-1)),i},_measureLine:function(t,e){return t.measureText(this._textLines[e]).width},_renderTextDecoration:function(t){function e(e){var n,s,o,a,h,c,l,u=0;for(n=0,s=r._textLines.length;s>n;n++){for(h=r._getLineWidth(t,n),c=r._getLineLeftOffset(h),\nl=r._getHeightOfLine(t,n),o=0,a=e.length;a>o;o++)t.fillRect(r._getLeftOffset()+c,u+(r._fontSizeMult-1+e[o])*r.fontSize-i,h,r.fontSize/15);u+=l}}if(this.textDecoration){var i=this.height/2,r=this,n=[];this.textDecoration.indexOf(\"underline\")>-1&&n.push(.85),this.textDecoration.indexOf(\"line-through\")>-1&&n.push(.43),this.textDecoration.indexOf(\"overline\")>-1&&n.push(-.12),n.length>0&&e(n)}},_getFontDeclaration:function(){return[e.isLikelyNode?this.fontWeight:this.fontStyle,e.isLikelyNode?this.fontStyle:this.fontWeight,this.fontSize+\"px\",e.isLikelyNode?'\"'+this.fontFamily+'\"':this.fontFamily].join(\" \")},render:function(t,e){this.visible&&(t.save(),this._setTextStyles(t),this._shouldClearCache()&&this._initDimensions(t),this.drawSelectionBackground(t),e||this.transform(t),this.transformMatrix&&t.transform.apply(t,this.transformMatrix),this.group&&\"path-group\"===this.group.type&&t.translate(this.left,this.top),this._render(t),t.restore())},_splitTextIntoLines:function(){return this.text.split(this._reNewline)},toObject:function(t){var e=i(this.callSuper(\"toObject\",t),{text:this.text,fontSize:this.fontSize,fontWeight:this.fontWeight,fontFamily:this.fontFamily,fontStyle:this.fontStyle,lineHeight:this.lineHeight,textDecoration:this.textDecoration,textAlign:this.textAlign,textBackgroundColor:this.textBackgroundColor});return this.includeDefaultValues||this._removeDefaultValues(e),e},toSVG:function(t){var e=this._createBaseSVGMarkup(),i=this._getSVGLeftTopOffsets(this.ctx),r=this._getSVGTextAndBg(i.textTop,i.textLeft);return this._wrapSVGTextAndBg(e,r),t?t(e.join(\"\")):e.join(\"\")},_getSVGLeftTopOffsets:function(t){var e=this._getHeightOfLine(t,0),i=-this.width/2,r=0;return{textLeft:i+(this.group&&\"path-group\"===this.group.type?this.left:0),textTop:r+(this.group&&\"path-group\"===this.group.type?-this.top:0),lineTop:e}},_wrapSVGTextAndBg:function(t,e){var i=!0,r=this.getSvgFilter(),n=\"\"===r?\"\":' style=\"'+r+'\"';t.push('\t<g transform=\"',this.getSvgTransform(),this.getSvgTransformMatrix(),'\"',n,\">\\n\",e.textBgRects.join(\"\"),\"\t\t<text \",this.fontFamily?'font-family=\"'+this.fontFamily.replace(/\"/g,\"'\")+'\" ':\"\",this.fontSize?'font-size=\"'+this.fontSize+'\" ':\"\",this.fontStyle?'font-style=\"'+this.fontStyle+'\" ':\"\",this.fontWeight?'font-weight=\"'+this.fontWeight+'\" ':\"\",this.textDecoration?'text-decoration=\"'+this.textDecoration+'\" ':\"\",'style=\"',this.getSvgStyles(i),'\" >\\n',e.textSpans.join(\"\"),\"\t\t</text>\\n\",\"\t</g>\\n\")},_getSVGTextAndBg:function(t,e){var i=[],r=[],n=0;this._setSVGBg(r);for(var s=0,o=this._textLines.length;o>s;s++)this.textBackgroundColor&&this._setSVGTextLineBg(r,s,e,t,n),this._setSVGTextLineText(s,i,n,e,t,r),n+=this._getHeightOfLine(this.ctx,s);return{textSpans:i,textBgRects:r}},_setSVGTextLineText:function(t,i,r,s,a){var h=this.fontSize*(this._fontSizeMult-this._fontSizeFraction)-a+r-this.height/2;return\"justify\"===this.textAlign?void this._setSVGTextLineJustifed(t,i,h,s):void i.push('\t\t\t<tspan x=\"',n(s+this._getLineLeftOffset(this._getLineWidth(this.ctx,t)),o),'\" ','y=\"',n(h,o),'\" ',this._getFillAttributes(this.fill),\">\",e.util.string.escapeXml(this._textLines[t]),\"</tspan>\\n\")},_setSVGTextLineJustifed:function(t,i,r,s){var a=e.util.createCanvasElement().getContext(\"2d\");this._setTextStyles(a);var h,c,l=this._textLines[t],u=l.split(/\\s+/),f=this._getWidthOfWords(a,l),d=this.width-f,g=u.length-1,p=g>0?d/g:0,v=this._getFillAttributes(this.fill);for(s+=this._getLineLeftOffset(this._getLineWidth(a,t)),t=0,c=u.length;c>t;t++)h=u[t],i.push('\t\t\t<tspan x=\"',n(s,o),'\" ','y=\"',n(r,o),'\" ',v,\">\",e.util.string.escapeXml(h),\"</tspan>\\n\"),s+=this._getWidthOfWords(a,h)+p},_setSVGTextLineBg:function(t,e,i,r,s){t.push(\"\t\t<rect \",this._getFillAttributes(this.textBackgroundColor),' x=\"',n(i+this._getLineLeftOffset(this._getLineWidth(this.ctx,e)),o),'\" y=\"',n(s-this.height/2,o),'\" width=\"',n(this._getLineWidth(this.ctx,e),o),'\" height=\"',n(this._getHeightOfLine(this.ctx,e)/this.lineHeight,o),'\"></rect>\\n')},_setSVGBg:function(t){this.backgroundColor&&t.push(\"\t\t<rect \",this._getFillAttributes(this.backgroundColor),' x=\"',n(-this.width/2,o),'\" y=\"',n(-this.height/2,o),'\" width=\"',n(this.width,o),'\" height=\"',n(this.height,o),'\"></rect>\\n')},_getFillAttributes:function(t){var i=t&&\"string\"==typeof t?new e.Color(t):\"\";return i&&i.getSource()&&1!==i.getAlpha()?'opacity=\"'+i.getAlpha()+'\" fill=\"'+i.setAlpha(1).toRgb()+'\"':'fill=\"'+t+'\"'},_set:function(t,e){this.callSuper(\"_set\",t,e),t in this._dimensionAffectingProps&&(this._initDimensions(),this.setCoords())},complexity:function(){return 1}}),e.Text.ATTRIBUTE_NAMES=e.SHARED_ATTRIBUTES.concat(\"x y dx dy font-family font-style font-weight font-size text-decoration text-anchor\".split(\" \")),e.Text.DEFAULT_SVG_FONT_SIZE=16,e.Text.fromElement=function(t,i){if(!t)return null;var r=e.parseAttributes(t,e.Text.ATTRIBUTE_NAMES);i=e.util.object.extend(i?e.util.object.clone(i):{},r),i.top=i.top||0,i.left=i.left||0,\"dx\"in r&&(i.left+=r.dx),\"dy\"in r&&(i.top+=r.dy),\"fontSize\"in i||(i.fontSize=e.Text.DEFAULT_SVG_FONT_SIZE),i.originX||(i.originX=\"left\");var n=\"\";\"textContent\"in t?n=t.textContent:\"firstChild\"in t&&null!==t.firstChild&&\"data\"in t.firstChild&&null!==t.firstChild.data&&(n=t.firstChild.data),n=n.replace(/^\\s+|\\s+$|\\n+/g,\"\").replace(/\\s+/g,\" \");var s=new e.Text(n,i),o=0;return\"left\"===s.originX&&(o=s.getWidth()/2),\"right\"===s.originX&&(o=-s.getWidth()/2),s.set({left:s.getLeft()+o,top:s.getTop()-s.getHeight()/2+s.fontSize*(.18+s._fontSizeFraction)}),s},e.Text.fromObject=function(t){return new e.Text(t.text,r(t))},e.util.createAccessors(e.Text)}(\"undefined\"!=typeof exports?exports:this),function(){var t=fabric.util.object.clone;fabric.IText=fabric.util.createClass(fabric.Text,fabric.Observable,{type:\"i-text\",selectionStart:0,selectionEnd:0,selectionColor:\"rgba(17,119,255,0.3)\",isEditing:!1,editable:!0,editingBorderColor:\"rgba(102,153,255,0.25)\",cursorWidth:2,cursorColor:\"#333\",cursorDelay:1e3,cursorDuration:600,styles:null,caching:!0,_reSpace:/\\s|\\n/,_currentCursorOpacity:0,_selectionDirection:null,_abortCursorAnimation:!1,_charWidthsCache:{},__widthOfSpace:[],initialize:function(t,e){this.styles=e?e.styles||{}:{},this.callSuper(\"initialize\",t,e),this.initBehavior()},_clearCache:function(){this.callSuper(\"_clearCache\"),this.__widthOfSpace=[]},isEmptyStyles:function(){if(!this.styles)return!0;var t=this.styles;for(var e in t)for(var i in t[e])for(var r in t[e][i])return!1;return!0},setSelectionStart:function(t){t=Math.max(t,0),this.selectionStart!==t&&(this.fire(\"selection:changed\"),this.canvas&&this.canvas.fire(\"text:selection:changed\",{target:this}),this.selectionStart=t),this._updateTextarea()},setSelectionEnd:function(t){t=Math.min(t,this.text.length),this.selectionEnd!==t&&(this.fire(\"selection:changed\"),this.canvas&&this.canvas.fire(\"text:selection:changed\",{target:this}),this.selectionEnd=t),this._updateTextarea()},getSelectionStyles:function(t,e){if(2===arguments.length){for(var i=[],r=t;e>r;r++)i.push(this.getSelectionStyles(r));return i}var n=this.get2DCursorLocation(t),s=this._getStyleDeclaration(n.lineIndex,n.charIndex);return s||{}},setSelectionStyles:function(t){if(this.selectionStart===this.selectionEnd)this._extendStyles(this.selectionStart,t);else for(var e=this.selectionStart;e<this.selectionEnd;e++)this._extendStyles(e,t);return this._forceClearCache=!0,this},_extendStyles:function(t,e){var i=this.get2DCursorLocation(t);this._getLineStyle(i.lineIndex)||this._setLineStyle(i.lineIndex,{}),this._getStyleDeclaration(i.lineIndex,i.charIndex)||this._setStyleDeclaration(i.lineIndex,i.charIndex,{}),fabric.util.object.extend(this._getStyleDeclaration(i.lineIndex,i.charIndex),e)},_render:function(t){this.callSuper(\"_render\",t),this.ctx=t,this.isEditing&&this.renderCursorOrSelection()},renderCursorOrSelection:function(){if(this.active){var t,e,i=this.text.split(\"\");this.canvas.contextTop?(e=this.canvas.contextTop,e.save(),e.transform.apply(e,this.canvas.viewportTransform),this.transform(e),this.transformMatrix&&e.transform.apply(e,this.transformMatrix)):(e=this.ctx,e.save()),this.selectionStart===this.selectionEnd?(t=this._getCursorBoundaries(i,\"cursor\"),this.renderCursor(t,e)):(t=this._getCursorBoundaries(i,\"selection\"),this.renderSelection(i,t,e)),e.restore()}},get2DCursorLocation:function(t){\"undefined\"==typeof t&&(t=this.selectionStart);for(var e=this._textLines.length,i=0;e>i;i++){if(t<=this._textLines[i].length)return{lineIndex:i,charIndex:t};t-=this._textLines[i].length+1}return{lineIndex:i-1,charIndex:this._textLines[i-1].length<t?this._textLines[i-1].length:t}},getCurrentCharStyle:function(t,e){var i=this._getStyleDeclaration(t,0===e?0:e-1);return{fontSize:i&&i.fontSize||this.fontSize,fill:i&&i.fill||this.fill,textBackgroundColor:i&&i.textBackgroundColor||this.textBackgroundColor,textDecoration:i&&i.textDecoration||this.textDecoration,fontFamily:i&&i.fontFamily||this.fontFamily,fontWeight:i&&i.fontWeight||this.fontWeight,fontStyle:i&&i.fontStyle||this.fontStyle,stroke:i&&i.stroke||this.stroke,strokeWidth:i&&i.strokeWidth||this.strokeWidth}},getCurrentCharFontSize:function(t,e){var i=this._getStyleDeclaration(t,0===e?0:e-1);return i&&i.fontSize?i.fontSize:this.fontSize},getCurrentCharColor:function(t,e){var i=this._getStyleDeclaration(t,0===e?0:e-1);return i&&i.fill?i.fill:this.cursorColor},_getCursorBoundaries:function(t,e){var i=Math.round(this._getLeftOffset()),r=this._getTopOffset(),n=this._getCursorBoundariesOffsets(t,e);return{left:i,top:r,leftOffset:n.left+n.lineLeft,topOffset:n.top}},_getCursorBoundariesOffsets:function(t,e){for(var i=0,r=0,n=0,s=0,o=0,a=0;a<this.selectionStart;a++)\"\\n\"===t[a]?(o=0,s+=this._getHeightOfLine(this.ctx,r),r++,n=0):(o+=this._getWidthOfChar(this.ctx,t[a],r,n),n++),i=this._getLineLeftOffset(this._getLineWidth(this.ctx,r));return\"cursor\"===e&&(s+=(1-this._fontSizeFraction)*this._getHeightOfLine(this.ctx,r)/this.lineHeight-this.getCurrentCharFontSize(r,n)*(1-this._fontSizeFraction)),{top:s,left:o,lineLeft:i}},renderCursor:function(t,e){var i=this.get2DCursorLocation(),r=i.lineIndex,n=i.charIndex,s=this.getCurrentCharFontSize(r,n),o=0===r&&0===n?this._getLineLeftOffset(this._getLineWidth(e,r)):t.leftOffset;e.fillStyle=this.getCurrentCharColor(r,n),e.globalAlpha=this.__isMousedown?1:this._currentCursorOpacity,e.fillRect(t.left+o,t.top+t.topOffset,this.cursorWidth/this.scaleX,s)},renderSelection:function(t,e,i){i.fillStyle=this.selectionColor;for(var r=this.get2DCursorLocation(this.selectionStart),n=this.get2DCursorLocation(this.selectionEnd),s=r.lineIndex,o=n.lineIndex,a=s;o>=a;a++){var h=this._getLineLeftOffset(this._getLineWidth(i,a))||0,c=this._getHeightOfLine(this.ctx,a),l=0,u=this._textLines[a];if(a===s)for(var f=0,d=u.length;d>f;f++)f>=r.charIndex&&(a!==o||f<n.charIndex)&&(l+=this._getWidthOfChar(i,u[f],a,f)),f<r.charIndex&&(h+=this._getWidthOfChar(i,u[f],a,f));else if(a>s&&o>a)l+=this._getLineWidth(i,a)||5;else if(a===o)for(var g=0,p=n.charIndex;p>g;g++)l+=this._getWidthOfChar(i,u[g],a,g);i.fillRect(e.left+h,e.top+e.topOffset,l,c),e.topOffset+=c}},_renderChars:function(t,e,i,r,n,s,o){if(this.isEmptyStyles())return this._renderCharsFast(t,e,i,r,n);o=o||0,this.skipTextAlign=!0,r-=\"center\"===this.textAlign?this.width/2:\"right\"===this.textAlign?this.width:0;var a,h,c=this._getHeightOfLine(e,s),l=this._getLineLeftOffset(this._getLineWidth(e,s)),u=\"\";r+=l||0,e.save(),n-=c/this.lineHeight*this._fontSizeFraction;for(var f=o,d=i.length+o;d>=f;f++)a=a||this.getCurrentCharStyle(s,f),h=this.getCurrentCharStyle(s,f+1),(this._hasStyleChanged(a,h)||f===d)&&(this._renderChar(t,e,s,f-1,u,r,n,c),u=\"\",a=h),u+=i[f-o];e.restore()},_renderCharsFast:function(t,e,i,r,n){this.skipTextAlign=!1,\"fillText\"===t&&this.fill&&this.callSuper(\"_renderChars\",t,e,i,r,n),\"strokeText\"===t&&(this.stroke&&this.strokeWidth>0||this.skipFillStrokeCheck)&&this.callSuper(\"_renderChars\",t,e,i,r,n)},_renderChar:function(t,e,i,r,n,s,o,a){var h,c,l,u,f,d,g=this._getStyleDeclaration(i,r);g?(c=this._getHeightOfChar(e,n,i,r),u=g.stroke,l=g.fill,d=g.textDecoration):c=this.fontSize,u=(u||this.stroke)&&\"strokeText\"===t,l=(l||this.fill)&&\"fillText\"===t,g&&e.save(),h=this._applyCharStylesGetWidth(e,n,i,r,g||{}),d=d||this.textDecoration,g&&g.textBackgroundColor&&this._removeShadow(e),l&&e.fillText(n,s,o),u&&e.strokeText(n,s,o),(d||\"\"!==d)&&(f=this._fontSizeFraction*a/this.lineHeight,this._renderCharDecoration(e,d,s,o,f,h,c)),g&&e.restore(),e.translate(h,0)},_hasStyleChanged:function(t,e){return t.fill!==e.fill||t.fontSize!==e.fontSize||t.textBackgroundColor!==e.textBackgroundColor||t.textDecoration!==e.textDecoration||t.fontFamily!==e.fontFamily||t.fontWeight!==e.fontWeight||t.fontStyle!==e.fontStyle||t.stroke!==e.stroke||t.strokeWidth!==e.strokeWidth},_renderCharDecoration:function(t,e,i,r,n,s,o){if(e){var a,h,c=o/15,l={underline:r+o/10,\"line-through\":r-o*(this._fontSizeFraction+this._fontSizeMult-1)+c,overline:r-(this._fontSizeMult-this._fontSizeFraction)*o},u=[\"underline\",\"line-through\",\"overline\"];for(a=0;a<u.length;a++)h=u[a],e.indexOf(h)>-1&&t.fillRect(i,l[h],s,c)}},_renderTextLine:function(t,e,i,r,n,s){this.isEmptyStyles()||(n+=this.fontSize*(this._fontSizeFraction+.03)),this.callSuper(\"_renderTextLine\",t,e,i,r,n,s)},_renderTextDecoration:function(t){return this.isEmptyStyles()?this.callSuper(\"_renderTextDecoration\",t):void 0},_renderTextLinesBackground:function(t){this.callSuper(\"_renderTextLinesBackground\",t);for(var e,i,r,n,s,o,a=0,h=this._getLeftOffset(),c=this._getTopOffset(),l=0,u=this._textLines.length;u>l;l++)if(e=this._getHeightOfLine(t,l),n=this._textLines[l],\"\"!==n&&this.styles&&this._getLineStyle(l)){i=this._getLineWidth(t,l),r=this._getLineLeftOffset(i);for(var f=0,d=n.length;d>f;f++)o=this._getStyleDeclaration(l,f),o&&o.textBackgroundColor&&(s=n[f],t.fillStyle=o.textBackgroundColor,t.fillRect(h+r+this._getWidthOfCharsAt(t,l,f),c+a,this._getWidthOfChar(t,s,l,f)+1,e/this.lineHeight));a+=e}else a+=e},_getCacheProp:function(t,e){return t+e.fontFamily+e.fontSize+e.fontWeight+e.fontStyle+e.shadow},_applyCharStylesGetWidth:function(e,i,r,n,s){var o,a=this._getStyleDeclaration(r,n),h=s&&t(s)||t(a);this._applyFontStyles(h);var c=this._getCacheProp(i,h);if(!a&&this._charWidthsCache[c]&&this.caching)return this._charWidthsCache[c];\"string\"==typeof h.shadow&&(h.shadow=new fabric.Shadow(h.shadow));var l=h.fill||this.fill;return e.fillStyle=l.toLive?l.toLive(e,this):l,h.stroke&&(e.strokeStyle=h.stroke&&h.stroke.toLive?h.stroke.toLive(e,this):h.stroke),e.lineWidth=h.strokeWidth||this.strokeWidth,e.font=this._getFontDeclaration.call(h),h.shadow&&(h.scaleX=this.scaleX,h.scaleY=this.scaleY,h.canvas=this.canvas,this._setShadow.call(h,e)),this.caching&&this._charWidthsCache[c]?this._charWidthsCache[c]:(o=e.measureText(i).width,this.caching&&(this._charWidthsCache[c]=o),o)},_applyFontStyles:function(t){t.fontFamily||(t.fontFamily=this.fontFamily),t.fontSize||(t.fontSize=this.fontSize),t.fontWeight||(t.fontWeight=this.fontWeight),t.fontStyle||(t.fontStyle=this.fontStyle)},_getStyleDeclaration:function(e,i,r){return r?this.styles[e]&&this.styles[e][i]?t(this.styles[e][i]):{}:this.styles[e]&&this.styles[e][i]?this.styles[e][i]:null},_setStyleDeclaration:function(t,e,i){this.styles[t][e]=i},_deleteStyleDeclaration:function(t,e){delete this.styles[t][e]},_getLineStyle:function(t){return this.styles[t]},_setLineStyle:function(t,e){this.styles[t]=e},_deleteLineStyle:function(t){delete this.styles[t]},_getWidthOfChar:function(t,e,i,r){if(!this._isMeasuring&&\"justify\"===this.textAlign&&this._reSpacesAndTabs.test(e))return this._getWidthOfSpace(t,i);var n=this._getStyleDeclaration(i,r,!0);this._applyFontStyles(n);var s=this._getCacheProp(e,n);if(this._charWidthsCache[s]&&this.caching)return this._charWidthsCache[s];if(t){t.save();var o=this._applyCharStylesGetWidth(t,e,i,r);return t.restore(),o}},_getHeightOfChar:function(t,e,i){var r=this._getStyleDeclaration(e,i);return r&&r.fontSize?r.fontSize:this.fontSize},_getWidthOfCharsAt:function(t,e,i){var r,n,s=0;for(r=0;i>r;r++)n=this._textLines[e][r],s+=this._getWidthOfChar(t,n,e,r);return s},_measureLine:function(t,e){this._isMeasuring=!0;var i=this._getWidthOfCharsAt(t,e,this._textLines[e].length);return this._isMeasuring=!1,i},_getWidthOfSpace:function(t,e){if(this.__widthOfSpace[e])return this.__widthOfSpace[e];var i=this._textLines[e],r=this._getWidthOfWords(t,i,e,0),n=this.width-r,s=i.length-i.replace(this._reSpacesAndTabs,\"\").length,o=Math.max(n/s,t.measureText(\" \").width);return this.__widthOfSpace[e]=o,o},_getWidthOfWords:function(t,e,i,r){for(var n=0,s=0;s<e.length;s++){var o=e[s];o.match(/\\s/)||(n+=this._getWidthOfChar(t,o,i,s+r))}return n},_getHeightOfLine:function(t,e){if(this.__lineHeights[e])return this.__lineHeights[e];for(var i=this._textLines[e],r=this._getHeightOfChar(t,e,0),n=1,s=i.length;s>n;n++){var o=this._getHeightOfChar(t,e,n);o>r&&(r=o)}return this.__lineHeights[e]=r*this.lineHeight*this._fontSizeMult,this.__lineHeights[e]},_getTextHeight:function(t){for(var e=0,i=0,r=this._textLines.length;r>i;i++)e+=this._getHeightOfLine(t,i);return e},toObject:function(e){var i,r,n,s={};for(i in this.styles){n=this.styles[i],s[i]={};for(r in n)s[i][r]=t(n[r])}return fabric.util.object.extend(this.callSuper(\"toObject\",e),{styles:s})}}),fabric.IText.fromObject=function(e){return new fabric.IText(e.text,t(e))}}(),function(){var t=fabric.util.object.clone;fabric.util.object.extend(fabric.IText.prototype,{initBehavior:function(){this.initAddedHandler(),this.initRemovedHandler(),this.initCursorSelectionHandlers(),this.initDoubleClickSimulation()},initSelectedHandler:function(){this.on(\"selected\",function(){var t=this;setTimeout(function(){t.selected=!0},100)})},initAddedHandler:function(){var t=this;this.on(\"added\",function(){this.canvas&&!this.canvas._hasITextHandlers&&(this.canvas._hasITextHandlers=!0,this._initCanvasHandlers()),t.canvas&&(t.canvas._iTextInstances=t.canvas._iTextInstances||[],t.canvas._iTextInstances.push(t))})},initRemovedHandler:function(){var t=this;this.on(\"removed\",function(){t.canvas&&(t.canvas._iTextInstances=t.canvas._iTextInstances||[],fabric.util.removeFromArray(t.canvas._iTextInstances,t))})},_initCanvasHandlers:function(){var t=this;this.canvas.on(\"selection:cleared\",function(){fabric.IText.prototype.exitEditingOnOthers(t.canvas)}),this.canvas.on(\"mouse:up\",function(){t.canvas._iTextInstances&&t.canvas._iTextInstances.forEach(function(t){t.__isMousedown=!1})}),this.canvas.on(\"object:selected\",function(){fabric.IText.prototype.exitEditingOnOthers(t.canvas)})},_tick:function(){this._currentTickState=this._animateCursor(this,1,this.cursorDuration,\"_onTickComplete\")},_animateCursor:function(t,e,i,r){var n;return n={isAborted:!1,abort:function(){this.isAborted=!0}},t.animate(\"_currentCursorOpacity\",e,{duration:i,onComplete:function(){n.isAborted||t[r]()},onChange:function(){t.canvas&&(t.canvas.clearContext(t.canvas.contextTop||t.ctx),t.renderCursorOrSelection())},abort:function(){return n.isAborted}}),n},_onTickComplete:function(){var t=this;this._cursorTimeout1&&clearTimeout(this._cursorTimeout1),this._cursorTimeout1=setTimeout(function(){t._currentTickCompleteState=t._animateCursor(t,0,this.cursorDuration/2,\"_tick\")},100)},initDelayedCursor:function(t){var e=this,i=t?0:this.cursorDelay;this._currentTickState&&this._currentTickState.abort(),this._currentTickCompleteState&&this._currentTickCompleteState.abort(),clearTimeout(this._cursorTimeout1),this._currentCursorOpacity=1,this.canvas&&(this.canvas.clearContext(this.canvas.contextTop||this.ctx),this.renderCursorOrSelection()),this._cursorTimeout2&&clearTimeout(this._cursorTimeout2),this._cursorTimeout2=setTimeout(function(){e._tick()},i)},abortCursorAnimation:function(){this._currentTickState&&this._currentTickState.abort(),this._currentTickCompleteState&&this._currentTickCompleteState.abort(),clearTimeout(this._cursorTimeout1),clearTimeout(this._cursorTimeout2),this._currentCursorOpacity=0,this.canvas&&this.canvas.clearContext(this.canvas.contextTop||this.ctx)},selectAll:function(){this.setSelectionStart(0),this.setSelectionEnd(this.text.length)},getSelectedText:function(){return this.text.slice(this.selectionStart,this.selectionEnd)},findWordBoundaryLeft:function(t){var e=0,i=t-1;if(this._reSpace.test(this.text.charAt(i)))for(;this._reSpace.test(this.text.charAt(i));)e++,i--;for(;/\\S/.test(this.text.charAt(i))&&i>-1;)e++,i--;return t-e},findWordBoundaryRight:function(t){var e=0,i=t;if(this._reSpace.test(this.text.charAt(i)))for(;this._reSpace.test(this.text.charAt(i));)e++,i++;for(;/\\S/.test(this.text.charAt(i))&&i<this.text.length;)e++,i++;return t+e},findLineBoundaryLeft:function(t){for(var e=0,i=t-1;!/\\n/.test(this.text.charAt(i))&&i>-1;)e++,i--;return t-e},findLineBoundaryRight:function(t){for(var e=0,i=t;!/\\n/.test(this.text.charAt(i))&&i<this.text.length;)e++,i++;return t+e},getNumNewLinesInSelectedText:function(){for(var t=this.getSelectedText(),e=0,i=0,r=t.length;r>i;i++)\"\\n\"===t[i]&&e++;return e},searchWordBoundary:function(t,e){for(var i=this._reSpace.test(this.text.charAt(t))?t-1:t,r=this.text.charAt(i),n=/[ \\n\\.,;!\\?\\-]/;!n.test(r)&&i>0&&i<this.text.length;)i+=e,r=this.text.charAt(i);return n.test(r)&&\"\\n\"!==r&&(i+=1===e?0:1),i},selectWord:function(t){var e=this.searchWordBoundary(t,-1),i=this.searchWordBoundary(t,1);this.setSelectionStart(e),this.setSelectionEnd(i)},selectLine:function(t){var e=this.findLineBoundaryLeft(t),i=this.findLineBoundaryRight(t);this.setSelectionStart(e),this.setSelectionEnd(i)},enterEditing:function(t){return!this.isEditing&&this.editable?(this.canvas&&this.exitEditingOnOthers(this.canvas),this.isEditing=!0,this.initHiddenTextarea(t),this.hiddenTextarea.focus(),this._updateTextarea(),this._saveEditingProps(),this._setEditingProps(),this._textBeforeEdit=this.text,this._tick(),this.fire(\"editing:entered\"),this.canvas?(this.canvas.renderAll(),this.canvas.fire(\"text:editing:entered\",{target:this}),this.initMouseMoveHandler(),this):this):void 0},exitEditingOnOthers:function(t){t._iTextInstances&&t._iTextInstances.forEach(function(t){t.selected=!1,t.isEditing&&t.exitEditing()})},initMouseMoveHandler:function(){var t=this;this.canvas.on(\"mouse:move\",function(e){if(t.__isMousedown&&t.isEditing){var i=t.getSelectionStartFromPointer(e.e);i>=t.__selectionStartOnMouseDown?(t.setSelectionStart(t.__selectionStartOnMouseDown),t.setSelectionEnd(i)):(t.setSelectionStart(i),t.setSelectionEnd(t.__selectionStartOnMouseDown))}})},_setEditingProps:function(){this.hoverCursor=\"text\",this.canvas&&(this.canvas.defaultCursor=this.canvas.moveCursor=\"text\"),this.borderColor=this.editingBorderColor,this.hasControls=this.selectable=!1,this.lockMovementX=this.lockMovementY=!0},_updateTextarea:function(){if(this.hiddenTextarea&&!this.inCompositionMode&&(this.hiddenTextarea.value=this.text,this.hiddenTextarea.selectionStart=this.selectionStart,this.hiddenTextarea.selectionEnd=this.selectionEnd,this.selectionStart===this.selectionEnd)){var t=this._calcTextareaPosition();this.hiddenTextarea.style.left=t.x+\"px\",this.hiddenTextarea.style.top=t.y+\"px\"}},_calcTextareaPosition:function(){var t=this.text.split(\"\"),e=this._getCursorBoundaries(t,\"cursor\"),i=this.get2DCursorLocation(),r=i.lineIndex,n=i.charIndex,s=this.getCurrentCharFontSize(r,n),o=0===r&&0===n?this._getLineLeftOffset(this._getLineWidth(this.ctx,r)):e.leftOffset,a=this.calcTransformMatrix(),h={x:e.left+o,y:e.top+e.topOffset+s};return this.hiddenTextarea.style.fontSize=s+\"px\",fabric.util.transformPoint(h,a)},_saveEditingProps:function(){this._savedProps={hasControls:this.hasControls,borderColor:this.borderColor,lockMovementX:this.lockMovementX,lockMovementY:this.lockMovementY,hoverCursor:this.hoverCursor,defaultCursor:this.canvas&&this.canvas.defaultCursor,moveCursor:this.canvas&&this.canvas.moveCursor}},_restoreEditingProps:function(){this._savedProps&&(this.hoverCursor=this._savedProps.overCursor,this.hasControls=this._savedProps.hasControls,this.borderColor=this._savedProps.borderColor,this.lockMovementX=this._savedProps.lockMovementX,this.lockMovementY=this._savedProps.lockMovementY,this.canvas&&(this.canvas.defaultCursor=this._savedProps.defaultCursor,this.canvas.moveCursor=this._savedProps.moveCursor))},exitEditing:function(){var t=this._textBeforeEdit!==this.text;return this.selected=!1,this.isEditing=!1,this.selectable=!0,this.selectionEnd=this.selectionStart,this.hiddenTextarea&&this.canvas&&this.hiddenTextarea.parentNode.removeChild(this.hiddenTextarea),this.hiddenTextarea=null,this.abortCursorAnimation(),this._restoreEditingProps(),this._currentCursorOpacity=0,this.fire(\"editing:exited\"),t&&this.fire(\"modified\"),this.canvas&&(this.canvas.fire(\"text:editing:exited\",{target:this}),t&&this.canvas.fire(\"object:modified\",{target:this})),this},_removeExtraneousStyles:function(){for(var t in this.styles)this._textLines[t]||delete this.styles[t]},_removeCharsFromTo:function(t,e){for(;e!==t;)this._removeSingleCharAndStyle(t+1),e--;this.setSelectionStart(t)},_removeSingleCharAndStyle:function(t){var e=\"\\n\"===this.text[t-1],i=e?t:t-1;this.removeStyleObject(e,i),this.text=this.text.slice(0,t-1)+this.text.slice(t),this._textLines=this._splitTextIntoLines()},insertChars:function(t,e){var i;if(this.selectionEnd-this.selectionStart>1&&(this._removeCharsFromTo(this.selectionStart,this.selectionEnd),this.setSelectionEnd(this.selectionStart)),!e&&this.isEmptyStyles())return void this.insertChar(t,!1);for(var r=0,n=t.length;n>r;r++)e&&(i=fabric.copiedTextStyle[r]),this.insertChar(t[r],n-1>r,i)},insertChar:function(t,e,i){var r=\"\\n\"===this.text[this.selectionStart];this.text=this.text.slice(0,this.selectionStart)+t+this.text.slice(this.selectionEnd),this._textLines=this._splitTextIntoLines(),this.insertStyleObjects(t,r,i),this.selectionStart+=t.length,this.selectionEnd=this.selectionStart,e||(this._updateTextarea(),this.canvas&&this.canvas.renderAll(),this.setCoords(),this.fire(\"changed\"),this.canvas&&this.canvas.fire(\"text:changed\",{target:this}))},insertNewlineStyleObject:function(e,i,r){this.shiftLineStyles(e,1),this.styles[e+1]||(this.styles[e+1]={});var n={},s={};if(this.styles[e]&&this.styles[e][i-1]&&(n=this.styles[e][i-1]),r)s[0]=t(n),this.styles[e+1]=s;else{for(var o in this.styles[e])parseInt(o,10)>=i&&(s[parseInt(o,10)-i]=this.styles[e][o],delete this.styles[e][o]);this.styles[e+1]=s}this._forceClearCache=!0},insertCharStyleObject:function(e,i,r){var n=this.styles[e],s=t(n);0!==i||r||(i=1);for(var o in s){var a=parseInt(o,10);a>=i&&(n[a+1]=s[a],s[a-1]||delete n[a])}this.styles[e][i]=r||t(n[i-1]),this._forceClearCache=!0},insertStyleObjects:function(t,e,i){var r=this.get2DCursorLocation(),n=r.lineIndex,s=r.charIndex;this._getLineStyle(n)||this._setLineStyle(n,{}),\"\\n\"===t?this.insertNewlineStyleObject(n,s,e):this.insertCharStyleObject(n,s,i)},shiftLineStyles:function(e,i){var r=t(this.styles);for(var n in this.styles){var s=parseInt(n,10);s>e&&(this.styles[s+i]=r[s],r[s-i]||delete this.styles[s])}},removeStyleObject:function(t,e){var i=this.get2DCursorLocation(e),r=i.lineIndex,n=i.charIndex;this._removeStyleObject(t,i,r,n)},_getTextOnPreviousLine:function(t){return this._textLines[t-1]},_removeStyleObject:function(e,i,r,n){if(e){var s=this._getTextOnPreviousLine(i.lineIndex),o=s?s.length:0;this.styles[r-1]||(this.styles[r-1]={});for(n in this.styles[r])this.styles[r-1][parseInt(n,10)+o]=this.styles[r][n];this.shiftLineStyles(i.lineIndex,-1)}else{var a=this.styles[r];a&&delete a[n];var h=t(a);for(var c in h){var l=parseInt(c,10);l>=n&&0!==l&&(a[l-1]=h[l],delete a[l])}}},insertNewline:function(){this.insertChars(\"\\n\")}})}(),fabric.util.object.extend(fabric.IText.prototype,{initDoubleClickSimulation:function(){this.__lastClickTime=+new Date,this.__lastLastClickTime=+new Date,this.__lastPointer={},this.on(\"mousedown\",this.onMouseDown.bind(this))},onMouseDown:function(t){this.__newClickTime=+new Date;var e=this.canvas.getPointer(t.e);this.isTripleClick(e)?(this.fire(\"tripleclick\",t),this._stopEvent(t.e)):this.isDoubleClick(e)&&(this.fire(\"dblclick\",t),this._stopEvent(t.e)),this.__lastLastClickTime=this.__lastClickTime,this.__lastClickTime=this.__newClickTime,this.__lastPointer=e,this.__lastIsEditing=this.isEditing,this.__lastSelected=this.selected},isDoubleClick:function(t){return this.__newClickTime-this.__lastClickTime<500&&this.__lastPointer.x===t.x&&this.__lastPointer.y===t.y&&this.__lastIsEditing},isTripleClick:function(t){return this.__newClickTime-this.__lastClickTime<500&&this.__lastClickTime-this.__lastLastClickTime<500&&this.__lastPointer.x===t.x&&this.__lastPointer.y===t.y},_stopEvent:function(t){t.preventDefault&&t.preventDefault(),t.stopPropagation&&t.stopPropagation()},initCursorSelectionHandlers:function(){this.initSelectedHandler(),this.initMousedownHandler(),this.initMouseupHandler(),this.initClicks()},initClicks:function(){this.on(\"dblclick\",function(t){this.selectWord(this.getSelectionStartFromPointer(t.e))}),this.on(\"tripleclick\",function(t){this.selectLine(this.getSelectionStartFromPointer(t.e))})},initMousedownHandler:function(){this.on(\"mousedown\",function(t){if(this.editable){var e=this.canvas.getPointer(t.e);this.__mousedownX=e.x,this.__mousedownY=e.y,this.__isMousedown=!0,this.hiddenTextarea&&this.canvas&&this.canvas.wrapperEl.appendChild(this.hiddenTextarea),this.selected&&this.setCursorByClick(t.e),this.isEditing&&(this.__selectionStartOnMouseDown=this.selectionStart,this.initDelayedCursor(!0))}})},_isObjectMoved:function(t){var e=this.canvas.getPointer(t);return this.__mousedownX!==e.x||this.__mousedownY!==e.y},initMouseupHandler:function(){this.on(\"mouseup\",function(t){this.__isMousedown=!1,this.editable&&!this._isObjectMoved(t.e)&&(this.__lastSelected&&!this.__corner&&(this.enterEditing(t.e),this.initDelayedCursor(!0)),this.selected=!0)})},setCursorByClick:function(t){var e=this.getSelectionStartFromPointer(t);t.shiftKey?e<this.selectionStart?(this.setSelectionEnd(this.selectionStart),this.setSelectionStart(e)):this.setSelectionEnd(e):(this.setSelectionStart(e),this.setSelectionEnd(e))},getSelectionStartFromPointer:function(t){for(var e,i,r=this.getLocalPointer(t),n=0,s=0,o=0,a=0,h=0,c=this._textLines.length;c>h;h++){i=this._textLines[h],o+=this._getHeightOfLine(this.ctx,h)*this.scaleY;var l=this._getLineWidth(this.ctx,h),u=this._getLineLeftOffset(l);s=u*this.scaleX;for(var f=0,d=i.length;d>f;f++){if(n=s,s+=this._getWidthOfChar(this.ctx,i[f],h,this.flipX?d-f:f)*this.scaleX,!(o<=r.y||s<=r.x))return this._getNewSelectionStartFromOffset(r,n,s,a+h,d);a++}if(r.y<o)return this._getNewSelectionStartFromOffset(r,n,s,a+h-1,d)}return\"undefined\"==typeof e?this.text.length:void 0},_getNewSelectionStartFromOffset:function(t,e,i,r,n){var s=t.x-e,o=i-t.x,a=o>s?0:1,h=r+a;return this.flipX&&(h=n-h),h>this.text.length&&(h=this.text.length),h}}),fabric.util.object.extend(fabric.IText.prototype,{initHiddenTextarea:function(t){var e;t&&this.canvas?e=this.canvas.getPointer(t):(this.oCoords||this.setCoords(),e=this.oCoords.tl),this.hiddenTextarea=fabric.document.createElement(\"textarea\"),this.hiddenTextarea.setAttribute(\"autocapitalize\",\"off\"),this.hiddenTextarea.style.cssText=\"position: absolute; top: \"+e.y+\"px; left: \"+e.x+\"px; opacity: 0; width: 0px; height: 0px; z-index: -999;\",this.canvas?this.canvas.lowerCanvasEl.parentNode.appendChild(this.hiddenTextarea):fabric.document.body.appendChild(this.hiddenTextarea),fabric.util.addListener(this.hiddenTextarea,\"keydown\",this.onKeyDown.bind(this)),fabric.util.addListener(this.hiddenTextarea,\"keyup\",this.onKeyUp.bind(this)),fabric.util.addListener(this.hiddenTextarea,\"input\",this.onInput.bind(this)),fabric.util.addListener(this.hiddenTextarea,\"copy\",this.copy.bind(this)),fabric.util.addListener(this.hiddenTextarea,\"cut\",this.cut.bind(this)),fabric.util.addListener(this.hiddenTextarea,\"paste\",this.paste.bind(this)),fabric.util.addListener(this.hiddenTextarea,\"compositionstart\",this.onCompositionStart.bind(this)),fabric.util.addListener(this.hiddenTextarea,\"compositionupdate\",this.onCompositionUpdate.bind(this)),fabric.util.addListener(this.hiddenTextarea,\"compositionend\",this.onCompositionEnd.bind(this)),\n!this._clickHandlerInitialized&&this.canvas&&(fabric.util.addListener(this.canvas.upperCanvasEl,\"click\",this.onClick.bind(this)),this._clickHandlerInitialized=!0)},_keysMap:{8:\"removeChars\",9:\"exitEditing\",27:\"exitEditing\",13:\"insertNewline\",33:\"moveCursorUp\",34:\"moveCursorDown\",35:\"moveCursorRight\",36:\"moveCursorLeft\",37:\"moveCursorLeft\",38:\"moveCursorUp\",39:\"moveCursorRight\",40:\"moveCursorDown\",46:\"forwardDelete\"},_ctrlKeysMapUp:{67:\"copy\",88:\"cut\"},_ctrlKeysMapDown:{65:\"selectAll\"},onClick:function(){this.hiddenTextarea&&this.hiddenTextarea.focus()},onKeyDown:function(t){if(this.isEditing){if(t.keyCode in this._keysMap)this[this._keysMap[t.keyCode]](t);else{if(!(t.keyCode in this._ctrlKeysMapDown&&(t.ctrlKey||t.metaKey)))return;this[this._ctrlKeysMapDown[t.keyCode]](t)}t.stopImmediatePropagation(),t.preventDefault(),this.canvas&&this.canvas.renderAll()}},onKeyUp:function(t){return!this.isEditing||this._copyDone?void(this._copyDone=!1):void(t.keyCode in this._ctrlKeysMapUp&&(t.ctrlKey||t.metaKey)&&(this[this._ctrlKeysMapUp[t.keyCode]](t),t.stopImmediatePropagation(),t.preventDefault(),this.canvas&&this.canvas.renderAll()))},onInput:function(t){if(this.isEditing&&!this.inCompositionMode){var e,i,r,n=this.selectionStart||0,s=this.selectionEnd||0,o=this.text.length,a=this.hiddenTextarea.value.length;a>o?(r=\"left\"===this._selectionDirection?s:n,e=a-o,i=this.hiddenTextarea.value.slice(r,r+e)):(e=a-o+s-n,i=this.hiddenTextarea.value.slice(n,n+e)),this.insertChars(i),t.stopPropagation()}},onCompositionStart:function(){this.inCompositionMode=!0,this.prevCompositionLength=0,this.compositionStart=this.selectionStart},onCompositionEnd:function(){this.inCompositionMode=!1},onCompositionUpdate:function(t){var e=t.data;this.selectionStart=this.compositionStart,this.selectionEnd=this.selectionEnd===this.selectionStart?this.compositionStart+this.prevCompositionLength:this.selectionEnd,this.insertChars(e,!1),this.prevCompositionLength=e.length},forwardDelete:function(t){if(this.selectionStart===this.selectionEnd){if(this.selectionStart===this.text.length)return;this.moveCursorRight(t)}this.removeChars(t)},copy:function(t){if(this.selectionStart!==this.selectionEnd){var e=this.getSelectedText(),i=this._getClipboardData(t);i&&i.setData(\"text\",e),fabric.copiedText=e,fabric.copiedTextStyle=this.getSelectionStyles(this.selectionStart,this.selectionEnd),t.stopImmediatePropagation(),t.preventDefault(),this._copyDone=!0}},paste:function(t){var e=null,i=this._getClipboardData(t),r=!0;i?(e=i.getData(\"text\").replace(/\\r/g,\"\"),fabric.copiedTextStyle&&fabric.copiedText===e||(r=!1)):e=fabric.copiedText,e&&this.insertChars(e,r),t.stopImmediatePropagation(),t.preventDefault()},cut:function(t){this.selectionStart!==this.selectionEnd&&(this.copy(t),this.removeChars(t))},_getClipboardData:function(t){return t&&t.clipboardData||fabric.window.clipboardData},getDownCursorOffset:function(t,e){var i,r,n=e?this.selectionEnd:this.selectionStart,s=this.get2DCursorLocation(n),o=s.lineIndex,a=this._textLines[o].slice(0,s.charIndex),h=this._textLines[o].slice(s.charIndex),c=this._textLines[o+1]||\"\";if(o===this._textLines.length-1||t.metaKey||34===t.keyCode)return this.text.length-n;var l=this._getLineWidth(this.ctx,o);r=this._getLineLeftOffset(l);for(var u=r,f=0,d=a.length;d>f;f++)i=a[f],u+=this._getWidthOfChar(this.ctx,i,o,f);var g=this._getIndexOnNextLine(s,c,u);return h.length+1+g},_getIndexOnNextLine:function(t,e,i){for(var r,n=t.lineIndex+1,s=this._getLineWidth(this.ctx,n),o=this._getLineLeftOffset(s),a=o,h=0,c=0,l=e.length;l>c;c++){var u=e[c],f=this._getWidthOfChar(this.ctx,u,n,c);if(a+=f,a>i){r=!0;var d=a-f,g=a,p=Math.abs(d-i),v=Math.abs(g-i);h=p>v?c+1:c;break}}return r||(h=e.length),h},moveCursorDown:function(t){this.abortCursorAnimation(),this._currentCursorOpacity=1;var e=this.getDownCursorOffset(t,\"right\"===this._selectionDirection);t.shiftKey?this.moveCursorDownWithShift(e):this.moveCursorDownWithoutShift(e),this.initDelayedCursor()},moveCursorDownWithoutShift:function(t){this._selectionDirection=\"right\",this.setSelectionStart(this.selectionStart+t),this.setSelectionEnd(this.selectionStart)},swapSelectionPoints:function(){var t=this.selectionEnd;this.setSelectionEnd(this.selectionStart),this.setSelectionStart(t)},moveCursorDownWithShift:function(t){this.selectionEnd===this.selectionStart&&(this._selectionDirection=\"right\"),\"right\"===this._selectionDirection?this.setSelectionEnd(this.selectionEnd+t):this.setSelectionStart(this.selectionStart+t),this.selectionEnd<this.selectionStart&&\"left\"===this._selectionDirection&&(this.swapSelectionPoints(),this._selectionDirection=\"right\"),this.selectionEnd>this.text.length&&this.setSelectionEnd(this.text.length)},getUpCursorOffset:function(t,e){var i=e?this.selectionEnd:this.selectionStart,r=this.get2DCursorLocation(i),n=r.lineIndex;if(0===n||t.metaKey||33===t.keyCode)return i;for(var s,o=this._textLines[n].slice(0,r.charIndex),a=this._textLines[n-1]||\"\",h=this._getLineWidth(this.ctx,r.lineIndex),c=this._getLineLeftOffset(h),l=c,u=0,f=o.length;f>u;u++)s=o[u],l+=this._getWidthOfChar(this.ctx,s,n,u);var d=this._getIndexOnPrevLine(r,a,l);return a.length-d+o.length},_getIndexOnPrevLine:function(t,e,i){for(var r,n=t.lineIndex-1,s=this._getLineWidth(this.ctx,n),o=this._getLineLeftOffset(s),a=o,h=0,c=0,l=e.length;l>c;c++){var u=e[c],f=this._getWidthOfChar(this.ctx,u,n,c);if(a+=f,a>i){r=!0;var d=a-f,g=a,p=Math.abs(d-i),v=Math.abs(g-i);h=p>v?c:c-1;break}}return r||(h=e.length-1),h},moveCursorUp:function(t){this.abortCursorAnimation(),this._currentCursorOpacity=1;var e=this.getUpCursorOffset(t,\"right\"===this._selectionDirection);t.shiftKey?this.moveCursorUpWithShift(e):this.moveCursorUpWithoutShift(e),this.initDelayedCursor()},moveCursorUpWithShift:function(t){this.selectionEnd===this.selectionStart&&(this._selectionDirection=\"left\"),\"right\"===this._selectionDirection?this.setSelectionEnd(this.selectionEnd-t):this.setSelectionStart(this.selectionStart-t),this.selectionEnd<this.selectionStart&&\"right\"===this._selectionDirection&&(this.swapSelectionPoints(),this._selectionDirection=\"left\")},moveCursorUpWithoutShift:function(t){this.selectionStart===this.selectionEnd&&this.setSelectionStart(this.selectionStart-t),this.setSelectionEnd(this.selectionStart),this._selectionDirection=\"left\"},moveCursorLeft:function(t){0===this.selectionStart&&0===this.selectionEnd||(this.abortCursorAnimation(),this._currentCursorOpacity=1,t.shiftKey?this.moveCursorLeftWithShift(t):this.moveCursorLeftWithoutShift(t),this.initDelayedCursor())},_move:function(t,e,i){var r=\"selectionStart\"===e?\"setSelectionStart\":\"setSelectionEnd\";t.altKey?this[r](this[\"findWordBoundary\"+i](this[e])):t.metaKey||35===t.keyCode||36===t.keyCode?this[r](this[\"findLineBoundary\"+i](this[e])):this[r](this[e]+(\"Left\"===i?-1:1))},_moveLeft:function(t,e){this._move(t,e,\"Left\")},_moveRight:function(t,e){this._move(t,e,\"Right\")},moveCursorLeftWithoutShift:function(t){this._selectionDirection=\"left\",this.selectionEnd===this.selectionStart&&this._moveLeft(t,\"selectionStart\"),this.setSelectionEnd(this.selectionStart)},moveCursorLeftWithShift:function(t){\"right\"===this._selectionDirection&&this.selectionStart!==this.selectionEnd?this._moveLeft(t,\"selectionEnd\"):(this._selectionDirection=\"left\",this._moveLeft(t,\"selectionStart\"))},moveCursorRight:function(t){this.selectionStart>=this.text.length&&this.selectionEnd>=this.text.length||(this.abortCursorAnimation(),this._currentCursorOpacity=1,t.shiftKey?this.moveCursorRightWithShift(t):this.moveCursorRightWithoutShift(t),this.initDelayedCursor())},moveCursorRightWithShift:function(t){\"left\"===this._selectionDirection&&this.selectionStart!==this.selectionEnd?this._moveRight(t,\"selectionStart\"):(this._selectionDirection=\"right\",this._moveRight(t,\"selectionEnd\"))},moveCursorRightWithoutShift:function(t){this._selectionDirection=\"right\",this.selectionStart===this.selectionEnd?(this._moveRight(t,\"selectionStart\"),this.setSelectionEnd(this.selectionStart)):(this.setSelectionEnd(this.selectionEnd+this.getNumNewLinesInSelectedText()),this.setSelectionStart(this.selectionEnd))},removeChars:function(t){this.selectionStart===this.selectionEnd?this._removeCharsNearCursor(t):this._removeCharsFromTo(this.selectionStart,this.selectionEnd),this.setSelectionEnd(this.selectionStart),this._removeExtraneousStyles(),this.canvas&&this.canvas.renderAll(),this.setCoords(),this.fire(\"changed\"),this.canvas&&this.canvas.fire(\"text:changed\",{target:this})},_removeCharsNearCursor:function(t){if(0!==this.selectionStart)if(t.metaKey){var e=this.findLineBoundaryLeft(this.selectionStart);this._removeCharsFromTo(e,this.selectionStart),this.setSelectionStart(e)}else if(t.altKey){var i=this.findWordBoundaryLeft(this.selectionStart);this._removeCharsFromTo(i,this.selectionStart),this.setSelectionStart(i)}else this._removeSingleCharAndStyle(this.selectionStart),this.setSelectionStart(this.selectionStart-1)}}),function(){var t=fabric.util.toFixed,e=fabric.Object.NUM_FRACTION_DIGITS;fabric.util.object.extend(fabric.IText.prototype,{_setSVGTextLineText:function(t,e,i,r,n,s){this._getLineStyle(t)?this._setSVGTextLineChars(t,e,i,r,s):fabric.Text.prototype._setSVGTextLineText.call(this,t,e,i,r,n)},_setSVGTextLineChars:function(t,e,i,r,n){for(var s=this._textLines[t],o=0,a=this._getLineLeftOffset(this._getLineWidth(this.ctx,t))-this.width/2,h=this._getSVGLineTopOffset(t),c=this._getHeightOfLine(this.ctx,t),l=0,u=s.length;u>l;l++){var f=this._getStyleDeclaration(t,l)||{};e.push(this._createTextCharSpan(s[l],f,a,h.lineTop+h.offset,o));var d=this._getWidthOfChar(this.ctx,s[l],t,l);f.textBackgroundColor&&n.push(this._createTextCharBg(f,a,h.lineTop,c,d,o)),o+=d}},_getSVGLineTopOffset:function(t){for(var e=0,i=0,r=0;t>r;r++)e+=this._getHeightOfLine(this.ctx,r);return i=this._getHeightOfLine(this.ctx,r),{lineTop:e,offset:(this._fontSizeMult-this._fontSizeFraction)*i/(this.lineHeight*this._fontSizeMult)}},_createTextCharBg:function(i,r,n,s,o,a){return['\t\t<rect fill=\"',i.textBackgroundColor,'\" x=\"',t(r+a,e),'\" y=\"',t(n-this.height/2,e),'\" width=\"',t(o,e),'\" height=\"',t(s/this.lineHeight,e),'\"></rect>\\n'].join(\"\")},_createTextCharSpan:function(i,r,n,s,o){var a=this.getSvgStyles.call(fabric.util.object.extend({visible:!0,fill:this.fill,stroke:this.stroke,type:\"text\",getSvgFilter:fabric.Object.prototype.getSvgFilter},r));return['\t\t\t<tspan x=\"',t(n+o,e),'\" y=\"',t(s-this.height/2,e),'\" ',r.fontFamily?'font-family=\"'+r.fontFamily.replace(/\"/g,\"'\")+'\" ':\"\",r.fontSize?'font-size=\"'+r.fontSize+'\" ':\"\",r.fontStyle?'font-style=\"'+r.fontStyle+'\" ':\"\",r.fontWeight?'font-weight=\"'+r.fontWeight+'\" ':\"\",r.textDecoration?'text-decoration=\"'+r.textDecoration+'\" ':\"\",'style=\"',a,'\">',fabric.util.string.escapeXml(i),\"</tspan>\\n\"].join(\"\")}})}(),function(t){\"use strict\";var e=t.fabric||(t.fabric={}),i=e.util.object.clone;e.Textbox=e.util.createClass(e.IText,e.Observable,{type:\"textbox\",minWidth:20,dynamicMinWidth:0,__cachedLines:null,lockScalingY:!0,lockScalingFlip:!0,initialize:function(t,i){this.ctx=e.util.createCanvasElement().getContext(\"2d\"),this.callSuper(\"initialize\",t,i),this.setControlsVisibility(e.Textbox.getTextboxControlVisibility()),this._dimensionAffectingProps.width=!0},_initDimensions:function(t){this.__skipDimension||(t||(t=e.util.createCanvasElement().getContext(\"2d\"),this._setTextStyles(t)),this.dynamicMinWidth=0,this._textLines=this._splitTextIntoLines(),this.dynamicMinWidth>this.width&&this._set(\"width\",this.dynamicMinWidth),this._clearCache(),this.height=this._getTextHeight(t))},_generateStyleMap:function(){for(var t=0,e=0,i=0,r={},n=0;n<this._textLines.length;n++)\"\\n\"===this.text[i]?(e=0,i++,t++):\" \"===this.text[i]&&(e++,i++),r[n]={line:t,offset:e},i+=this._textLines[n].length,e+=this._textLines[n].length;return r},_getStyleDeclaration:function(t,e,i){if(this._styleMap){var r=this._styleMap[t];if(!r)return i?{}:null;t=r.line,e=r.offset+e}return this.callSuper(\"_getStyleDeclaration\",t,e,i)},_setStyleDeclaration:function(t,e,i){var r=this._styleMap[t];t=r.line,e=r.offset+e,this.styles[t][e]=i},_deleteStyleDeclaration:function(t,e){var i=this._styleMap[t];t=i.line,e=i.offset+e,delete this.styles[t][e]},_getLineStyle:function(t){var e=this._styleMap[t];return this.styles[e.line]},_setLineStyle:function(t,e){var i=this._styleMap[t];this.styles[i.line]=e},_deleteLineStyle:function(t){var e=this._styleMap[t];delete this.styles[e.line]},_wrapText:function(t,e){var i,r=e.split(this._reNewline),n=[];for(i=0;i<r.length;i++)n=n.concat(this._wrapLine(t,r[i],i));return n},_measureText:function(t,e,i,r){var n=0;r=r||0;for(var s=0,o=e.length;o>s;s++)n+=this._getWidthOfChar(t,e[s],i,s+r);return n},_wrapLine:function(t,e,i){for(var r=0,n=[],s=\"\",o=e.split(\" \"),a=\"\",h=0,c=\" \",l=0,u=0,f=0,d=!0,g=0;g<o.length;g++)a=o[g],l=this._measureText(t,a,i,h),h+=a.length,r+=u+l,r>=this.width&&!d&&(n.push(s),s=\"\",r=l,d=!0),d||(s+=c),s+=a,u=this._measureText(t,c,i,h),h++,d=!1,l>f&&(f=l);return g&&n.push(s),f>this.dynamicMinWidth&&(this.dynamicMinWidth=f),n},_splitTextIntoLines:function(){var t=this.textAlign;this.ctx.save(),this._setTextStyles(this.ctx),this.textAlign=\"left\";var e=this._wrapText(this.ctx,this.text);return this.textAlign=t,this.ctx.restore(),this._textLines=e,this._styleMap=this._generateStyleMap(),e},setOnGroup:function(t,e){\"scaleX\"===t&&(this.set(\"scaleX\",Math.abs(1/e)),this.set(\"width\",this.get(\"width\")*e/(\"undefined\"==typeof this.__oldScaleX?1:this.__oldScaleX)),this.__oldScaleX=e)},get2DCursorLocation:function(t){\"undefined\"==typeof t&&(t=this.selectionStart);for(var e=this._textLines.length,i=0,r=0;e>r;r++){var n=this._textLines[r],s=n.length;if(i+s>=t)return{lineIndex:r,charIndex:t-i};i+=s,\"\\n\"!==this.text[i]&&\" \"!==this.text[i]||i++}return{lineIndex:e-1,charIndex:this._textLines[e-1].length}},_getCursorBoundariesOffsets:function(t,e){for(var i=0,r=0,n=this.get2DCursorLocation(),s=this._textLines[n.lineIndex].split(\"\"),o=this._getLineLeftOffset(this._getLineWidth(this.ctx,n.lineIndex)),a=0;a<n.charIndex;a++)r+=this._getWidthOfChar(this.ctx,s[a],n.lineIndex,a);for(a=0;a<n.lineIndex;a++)i+=this._getHeightOfLine(this.ctx,a);return\"cursor\"===e&&(i+=(1-this._fontSizeFraction)*this._getHeightOfLine(this.ctx,n.lineIndex)/this.lineHeight-this.getCurrentCharFontSize(n.lineIndex,n.charIndex)*(1-this._fontSizeFraction)),{top:i,left:r,lineLeft:o}},getMinWidth:function(){return Math.max(this.minWidth,this.dynamicMinWidth)},toObject:function(t){return e.util.object.extend(this.callSuper(\"toObject\",t),{minWidth:this.minWidth})}}),e.Textbox.fromObject=function(t){return new e.Textbox(t.text,i(t))},e.Textbox.getTextboxControlVisibility=function(){return{tl:!1,tr:!1,br:!1,bl:!1,ml:!0,mt:!1,mr:!0,mb:!1,mtr:!0}},e.Textbox.instances=[]}(\"undefined\"!=typeof exports?exports:this),function(){var t=fabric.Canvas.prototype._setObjectScale;fabric.Canvas.prototype._setObjectScale=function(e,i,r,n,s,o,a){var h=i.target;if(!(h instanceof fabric.Textbox))return t.call(fabric.Canvas.prototype,e,i,r,n,s,o,a);var c=h.width*(e.x/i.scaleX/(h.width+h.strokeWidth));return c>=h.getMinWidth()?(h.set(\"width\",c),!0):void 0},fabric.Group.prototype._refreshControlsVisibility=function(){if(\"undefined\"!=typeof fabric.Textbox)for(var t=this._objects.length;t--;)if(this._objects[t]instanceof fabric.Textbox)return void this.setControlsVisibility(fabric.Textbox.getTextboxControlVisibility())};var e=fabric.util.object.clone;fabric.util.object.extend(fabric.Textbox.prototype,{_removeExtraneousStyles:function(){for(var t in this._styleMap)this._textLines[t]||delete this.styles[this._styleMap[t].line]},insertCharStyleObject:function(t,e,i){var r=this._styleMap[t];t=r.line,e=r.offset+e,fabric.IText.prototype.insertCharStyleObject.apply(this,[t,e,i])},insertNewlineStyleObject:function(t,e,i){var r=this._styleMap[t];t=r.line,e=r.offset+e,fabric.IText.prototype.insertNewlineStyleObject.apply(this,[t,e,i])},shiftLineStyles:function(t,i){var r=e(this.styles),n=this._styleMap[t];t=n.line;for(var s in this.styles){var o=parseInt(s,10);o>t&&(this.styles[o+i]=r[o],r[o-i]||delete this.styles[o])}},_getTextOnPreviousLine:function(t){for(var e=this._textLines[t-1];this._styleMap[t-2]&&this._styleMap[t-2].line===this._styleMap[t-1].line;)e=this._textLines[t-2]+e,t--;return e},removeStyleObject:function(t,e){var i=this.get2DCursorLocation(e),r=this._styleMap[i.lineIndex],n=r.line,s=r.offset+i.charIndex;this._removeStyleObject(t,i,n,s)}})}(),function(){var t=fabric.IText.prototype._getNewSelectionStartFromOffset;fabric.IText.prototype._getNewSelectionStartFromOffset=function(e,i,r,n,s){n=t.call(this,e,i,r,n,s);for(var o=0,a=0,h=0;h<this._textLines.length&&(o+=this._textLines[h].length,!(o+a>=n));h++)\"\\n\"!==this.text[o+a]&&\" \"!==this.text[o+a]||a++;return n-h+a}}(),function(){function request(t,e,i){var r=URL.parse(t);r.port||(r.port=0===r.protocol.indexOf(\"https:\")?443:80);var n=0===r.protocol.indexOf(\"https:\")?HTTPS:HTTP,s=n.request({hostname:r.hostname,port:r.port,path:r.path,method:\"GET\"},function(t){var r=\"\";e&&t.setEncoding(e),t.on(\"end\",function(){i(r)}),t.on(\"data\",function(e){200===t.statusCode&&(r+=e)})});s.on(\"error\",function(t){t.errno===process.ECONNREFUSED?fabric.log(\"ECONNREFUSED: connection refused to \"+r.hostname+\":\"+r.port):fabric.log(t.message),i(null)}),s.end()}function requestFs(t,e){var i=require(\"fs\");i.readFile(t,function(t,i){if(t)throw fabric.log(t),t;e(i)})}if(\"undefined\"==typeof document||\"undefined\"==typeof window){var DOMParser=require(\"xmldom\").DOMParser,URL=require(\"url\"),HTTP=require(\"http\"),HTTPS=require(\"https\"),Canvas=require(\"canvas\"),Image=require(\"canvas\").Image;fabric.util.loadImage=function(t,e,i){function r(r){r?(n.src=new Buffer(r,\"binary\"),n._src=t,e&&e.call(i,n)):(n=null,e&&e.call(i,null,!0))}var n=new Image;t&&(t instanceof Buffer||0===t.indexOf(\"data\"))?(n.src=n._src=t,e&&e.call(i,n)):t&&0!==t.indexOf(\"http\")?requestFs(t,r):t?request(t,\"binary\",r):e&&e.call(i,t)},fabric.loadSVGFromURL=function(t,e,i){t=t.replace(/^\\n\\s*/,\"\").replace(/\\?.*$/,\"\").trim(),0!==t.indexOf(\"http\")?requestFs(t,function(t){fabric.loadSVGFromString(t.toString(),e,i)}):request(t,\"\",function(t){fabric.loadSVGFromString(t,e,i)})},fabric.loadSVGFromString=function(t,e,i){var r=(new DOMParser).parseFromString(t);fabric.parseSVGDocument(r.documentElement,function(t,i){e&&e(t,i)},i)},fabric.util.getScript=function(url,callback){request(url,\"\",function(body){eval(body),callback&&callback()})},fabric.Image.fromObject=function(t,e){fabric.util.loadImage(t.src,function(i){var r=new fabric.Image(i);r._initConfig(t),r._initFilters(t.filters,function(i){r.filters=i||[],r._initFilters(t.resizeFilters,function(t){r.resizeFilters=t||[],e&&e(r)})})})},fabric.createCanvasForNode=function(t,e,i,r){r=r||i;var n=fabric.document.createElement(\"canvas\"),s=new Canvas(t||600,e||600,r);n.style={},n.width=s.width,n.height=s.height;var o=fabric.Canvas||fabric.StaticCanvas,a=new o(n,i);return a.contextContainer=s.getContext(\"2d\"),a.nodeCanvas=s,a.Font=Canvas.Font,a},fabric.StaticCanvas.prototype.createPNGStream=function(){return this.nodeCanvas.createPNGStream()},fabric.StaticCanvas.prototype.createJPEGStream=function(t){return this.nodeCanvas.createJPEGStream(t)};var origSetWidth=fabric.StaticCanvas.prototype.setWidth;fabric.StaticCanvas.prototype.setWidth=function(t,e){return origSetWidth.call(this,t,e),this.nodeCanvas.width=t,this},fabric.Canvas&&(fabric.Canvas.prototype.setWidth=fabric.StaticCanvas.prototype.setWidth);var origSetHeight=fabric.StaticCanvas.prototype.setHeight;fabric.StaticCanvas.prototype.setHeight=function(t,e){return origSetHeight.call(this,t,e),this.nodeCanvas.height=t,this},fabric.Canvas&&(fabric.Canvas.prototype.setHeight=fabric.StaticCanvas.prototype.setHeight)}}();","Amasty_Rewards/amcharts/plugins/export/lang/en.js":"AmCharts.translations[ \"export\" ][ \"en\" ] = {\n\t\"fallback.save.text\": \"CTRL + C to copy the data into the clipboard.\",\n\t\"fallback.save.image\": \"Rightclick -> Save picture as... to save the image.\",\n\n\t\"capturing.delayed.menu.label\": \"{{duration}}\",\n\t\"capturing.delayed.menu.title\": \"Click to cancel\",\n\n\t\"menu.label.print\": \"Print\",\n\t\"menu.label.undo\": \"Undo\",\n\t\"menu.label.redo\": \"Redo\",\n\t\"menu.label.cancel\": \"Cancel\",\n\n\t\"menu.label.save.image\": \"Download as ...\",\n\t\"menu.label.save.data\": \"Save as ...\",\n\n\t\"menu.label.draw\": \"Annotate ...\",\n\t\"menu.label.draw.change\": \"Change ...\",\n\t\"menu.label.draw.add\": \"Add ...\",\n\t\"menu.label.draw.shapes\": \"Shape ...\",\n\t\"menu.label.draw.colors\": \"Color ...\",\n\t\"menu.label.draw.widths\": \"Size ...\",\n\t\"menu.label.draw.opacities\": \"Opacity ...\",\n\t\"menu.label.draw.text\": \"Text\",\n\n\t\"menu.label.draw.modes\": \"Mode ...\",\n\t\"menu.label.draw.modes.pencil\": \"Pencil\",\n\t\"menu.label.draw.modes.line\": \"Line\",\n\t\"menu.label.draw.modes.arrow\": \"Arrow\",\n\n\t\"label.saved.from\": \"Saved from: \"\n}","Amasty_Rewards/amcharts/plugins/export/lang/lt.js":"AmCharts.translations[ \"export\" ][ \"lt\" ] = {\n\t\"fallback.save.text\": \"Spauskite CTRL + C jei norite nukopijuoti paveiksliuk\u0105.\",\n\t\"fallback.save.image\": \"Spragtelkite de\u0161in\u012f klavi\u0161\u0105 ir pasirinkite \\\"Save picture as...\\\" jei norite i\u0161saugoti paveiksliuk\u0105.\",\n\n\t\"capturing.delayed.menu.label\": \"{{duration}}\",\n\t\"capturing.delayed.menu.title\": \"Nutraukti\",\n\n\t\"menu.label.print\": \"Spausdinti\",\n\t\"menu.label.undo\": \"At\u0161aukti\",\n\t\"menu.label.redo\": \"Pakartoti\",\n\t\"menu.label.cancel\": \"Nutraukti\",\n\n\t\"menu.label.save.image\": \"Atsisi\u0173sti ...\",\n\t\"menu.label.save.data\": \"I\u0161saugoti ...\",\n\n\t\"menu.label.draw\": \"Anotuoti ...\",\n\t\"menu.label.draw.change\": \"Keisti ...\",\n\t\"menu.label.draw.add\": \"Prid\u0117ti ...\",\n\t\"menu.label.draw.shapes\": \"Ikon\u0117l\u0119 ...\",\n\t\"menu.label.draw.colors\": \"Spalv\u0105 ...\",\n\t\"menu.label.draw.widths\": \"Teptuk\u0105 ...\",\n\t\"menu.label.draw.opacities\": \"Nepermatomumas ...\",\n\t\"menu.label.draw.text\": \"Tekst\u0105\",\n\n\t\"menu.label.draw.modes\": \"Re\u017eimas ...\",\n\t\"menu.label.draw.modes.pencil\": \"Tekst\u0105\",\n\t\"menu.label.draw.modes.line\": \"Linija\",\n\t\"menu.label.draw.modes.arrow\": \"Rodykl\u0117\",\n\n\t\"label.saved.from\": \"I\u0161saugoti nuo: \"\n}","Amasty_Rewards/amcharts/plugins/export/lang/cs.js":"AmCharts.translations[ \"export\" ][ \"cs\" ] = {\n\t\"fallback.save.text\": \"Stiskn\u011bte CTRL + C pro zkop\u00edrov\u00e1n\u00ed dat do schr\u00e1nky.\",\n\t\"fallback.save.image\": \"Klikn\u011bte prav\u00fdm tla\u010d\u00edtkem a zvolte Save picture as... k ulo\u017een\u00ed obr\u00e1zku.\",\n\n\t\"capturing.delayed.menu.label\": \"{{duration}}\",\n\t\"capturing.delayed.menu.title\": \"Kliknut\u00edm zru\u0161\u00edte\",\n\n\t\"menu.label.print\": \"Tisk\",\n\t\"menu.label.undo\": \"Zp\u011bt\",\n\t\"menu.label.redo\": \"Dop\u0159edu\",\n\t\"menu.label.cancel\": \"Zru\u0161it\",\n\n\t\"menu.label.save.image\": \"St\u00e1hnout obr\u00e1zek ...\",\n\t\"menu.label.save.data\": \"St\u00e1hnout data ...\",\n\n\t\"menu.label.draw\": \"Nakreslit ...\",\n\t\"menu.label.draw.change\": \"Zm\u011bnit ...\",\n\t\"menu.label.draw.add\": \"P\u0159idat ...\",\n\t\"menu.label.draw.shapes\": \"Tvar ...\",\n\t\"menu.label.draw.colors\": \"Barva ...\",\n\t\"menu.label.draw.widths\": \"Velikost ...\",\n\t\"menu.label.draw.opacities\": \"Pr\u016fhlednost ...\",\n\t\"menu.label.draw.text\": \"Text\",\n\n\t\"menu.label.draw.modes\": \"Re\u017eim kreslen\u00ed ...\",\n\t\"menu.label.draw.modes.pencil\": \"Tu\u017eka\",\n\t\"menu.label.draw.modes.line\": \"\u010c\u00e1ra\",\n\t\"menu.label.draw.modes.arrow\": \"\u0160ipka\",\n\n\t\"label.saved.from\": \"Ulo\u017eeno ze str\u00e1nky: \"\n}","Amasty_Rewards/amcharts/plugins/export/lang/fr.js":"AmCharts.translations[ \"export\" ][ \"fr\" ] = {\n \"fallback.save.text\": \"CTRL + C pour copier dans le presse-papier.\",\n \"fallback.save.image\": \"Clic-droit -> Enregistrer sous... pour sauvegarder l'image.\",\n\n \"capturing.delayed.menu.label\": \"{{duration}}\",\n \"capturing.delayed.menu.title\": \"Cliquez pour annuler\",\n\n \"menu.label.print\": \"Imprimer\",\n \"menu.label.undo\": \"Retour\",\n \"menu.label.redo\": \"Refaire\",\n \"menu.label.cancel\": \"Annuler\",\n\n \"menu.label.save.image\": \"T\u00e9l\u00e9chargez en ...\",\n \"menu.label.save.data\": \"Sauvegarder en ...\",\n\n \"menu.label.draw\": \"Annoter ...\",\n \"menu.label.draw.change\": \"Changer le ...\",\n \"menu.label.draw.add\": \"Ajouter ...\",\n \"menu.label.draw.shapes\": \"Formes ...\",\n \"menu.label.draw.colors\": \"Couleurs ...\",\n \"menu.label.draw.widths\": \"Taille ...\",\n \"menu.label.draw.opacities\": \"Opacit\u00e9 ...\",\n \"menu.label.draw.text\": \"Texte\",\n\n \"menu.label.draw.modes\": \"Mode ...\",\n \"menu.label.draw.modes.pencil\": \"Crayon\",\n \"menu.label.draw.modes.line\": \"Ligne\",\n \"menu.label.draw.modes.arrow\": \"Fl\u00e8che\",\n\n \"label.saved.from\": \"Sauv\u00e9 de la: \"\n}\n","Amasty_Rewards/amcharts/plugins/export/lang/pt.js":"/*\n ** Vers\u00e3o em Portugu\u00eas\n ** Traduzido por \u00c9lton Reisdorfer\n ** WebSite: http://eltonrst.tk\n ** Facebook : http://facebook.com/elton.reisdorfer\n */\nAmCharts.translations[\"export\"][\"pt\"] = {\n \"fallback.save.text\": \"CTRL + C para copiar os dados para a \u00e1rea de transfer\u00eancia.\",\n \"fallback.save.image\": \"Clique Direito -> Salvar imagem como... para salvar a imagem.\",\n\n \"capturing.delayed.menu.label\": \"{{duration}}\",\n \"capturing.delayed.menu.title\": \"Clique para cancelar\",\n\n \"menu.label.print\": \"Imprimir\",\n \"menu.label.undo\": \"Desfazer\",\n \"menu.label.redo\": \"Refazer\",\n \"menu.label.cancel\": \"Cancelar\",\n\n \"menu.label.save.image\": \"Baixar Como\",\n \"menu.label.save.data\": \"Salvar Como\",\n\n \"menu.label.draw\": \"Editar\",\n \"menu.label.draw.change\": \"Alterar\",\n \"menu.label.draw.add\": \"Adicionar\",\n \"menu.label.draw.shapes\": \"Forma\",\n \"menu.label.draw.colors\": \"Cor\",\n \"menu.label.draw.widths\": \"Tamanho\",\n \"menu.label.draw.opacities\": \"Tranpar\u00eancia\",\n \"menu.label.draw.text\": \"Texto\",\n\n \"menu.label.draw.modes\": \"Ferramenta\",\n \"menu.label.draw.modes.pencil\": \"Pincel\",\n \"menu.label.draw.modes.line\": \"Linha\",\n \"menu.label.draw.modes.arrow\": \"Seta\",\n\n \"label.saved.from\": \"Salvar de: \"\n}\n","Amasty_Rewards/amcharts/plugins/export/lang/de.js":"AmCharts.translations[ \"export\" ][ \"de\" ] = {\n\t\"fallback.save.text\": \"CTRL + C um die Daten in die Zwischenablage zu kopieren.\",\n\t\"fallback.save.image\": \"Rechtsklick -> Bild speichern unter... um das Bild zu speichern.\",\n\n\t\"capturing.delayed.menu.label\": \"{{duration}}\",\n\t\"capturing.delayed.menu.title\": \"Klicken zum Abbrechen.\",\n\n\t\"menu.label.print\": \"Drucken\",\n\t\"menu.label.undo\": \"R\u00fcckg\u00e4ngig\",\n\t\"menu.label.redo\": \"Wiederherstellen\",\n\t\"menu.label.cancel\": \"Abbrechen\",\n\n\t\"menu.label.save.image\": \"Herunterladen als ...\",\n\t\"menu.label.save.data\": \"Speichern als ...\",\n\n\t\"menu.label.draw\": \"Notieren ...\",\n\t\"menu.label.draw.change\": \"\u00c4ndern ...\",\n\t\"menu.label.draw.add\": \"Hinzuf\u00fcgen ...\",\n\t\"menu.label.draw.shapes\": \"Form ...\",\n\t\"menu.label.draw.colors\": \"Farbe ...\",\n\t\"menu.label.draw.widths\": \"Gr\u00f6\u00dfe ...\",\n\t\"menu.label.draw.opacities\": \"Deckkraft ...\",\n\t\"menu.label.draw.text\": \"Text\",\n\n\t\"menu.label.draw.modes\": \"Modus...\",\n\t\"menu.label.draw.modes.pencil\": \"Stift\",\n\t\"menu.label.draw.modes.line\": \"Linie\",\n\t\"menu.label.draw.modes.arrow\": \"Pfeil\",\n\n\t\"label.saved.from\": \"Gespeichert von: \"\n}","Amasty_Rewards/amcharts/plugins/export/lang/ko.js":"AmCharts.translations[ \"export\" ][ \"ko\" ] = {\n\t\"fallback.save.text\": \"CTRL + C \ub97c \ub20c\ub7ec \ud074\ub9bd\ubcf4\ub4dc\ub85c \ub370\uc774\ud130\ub97c \ubcf5\uc0ac\ud569\ub2c8\ub2e4.\",\n\t\"fallback.save.image\": \"\ub9c8\uc6b0\uc2a4 \uc624\ub978\ucabd \ud074\ub9ad -> \ub2e4\ub978 \uc774\ub984\uc73c\ub85c \uc800\uc7a5... \uc73c\ub85c \uc774\ubbf8\uc9c0\ub97c \uc800\uc7a5\ud569\ub2c8\ub2e4.\",\n\n\t\"capturing.delayed.menu.label\": \"{{duration}}\",\n\t\"capturing.delayed.menu.title\": \"\ucde8\uc18c\ud558\ub824\uba74 \ud074\ub9ad\",\n\n\t\"menu.label.print\": \"\ucd9c\ub825\",\n\t\"menu.label.undo\": \"\uc2e4\ud589 \ucde8\uc18c\",\n\t\"menu.label.redo\": \"\ub2e4\uc2dc \uc2e4\ud589\",\n\t\"menu.label.cancel\": \"\ucde8\uc18c\",\n\n\t\"menu.label.save.image\": \"\ub2e4\uc6b4\ub85c\ub4dc ...\",\n\t\"menu.label.save.data\": \"\ub370\uc774\ud130\ub85c \uc800\uc7a5 ...\",\n\n\t\"menu.label.draw\": \"\uadf8\ub9ac\uae30\",\n\t\"menu.label.draw.change\": \"\ubc14\uafb8\uae30 ...\",\n\t\"menu.label.draw.add\": \"\uc0bd\uc785\ud558\uae30 ...\",\n\t\"menu.label.draw.shapes\": \"\ubaa8\uc591 ...\",\n\t\"menu.label.draw.colors\": \"\uc0c9 \ubcc0\uacbd ...\",\n\t\"menu.label.draw.widths\": \"\ud06c\uae30 \ubcc0\uacbd ...\",\n\t\"menu.label.draw.opacities\": \"\ud22c\uba85\ub3c4 \ubcc0\uacbd ...\",\n\t\"menu.label.draw.text\": \"\ud14d\uc2a4\ud2b8\",\n\n\t\"menu.label.draw.modes\": \"\ubaa8\ub4dc \ubcc0\uacbd ...\",\n\t\"menu.label.draw.modes.pencil\": \"\ud39c\",\n\t\"menu.label.draw.modes.line\": \"\uc120\",\n\t\"menu.label.draw.modes.arrow\": \"\ud654\uc0b4\ud45c\",\n\n \"label.saved.from\": \"\uc5d0\uc11c \uc800\uc7a5: \"\n}","Amasty_Rewards/amcharts/plugins/export/lang/pl.js":"AmCharts.translations[ \"export\" ][ \"pl\" ] = {\n \"fallback.save.text\": \"Naci\u015bnij CTRL + C by skopiowa\u0107 dane do schowka.\",\n \"fallback.save.image\": \"Prawy przycisk myszy -> Zapisz obrazek jako... by zapisa\u0107 obrazek.\",\n\n \"capturing.delayed.menu.label\": \"{{duration}}\",\n \"capturing.delayed.menu.title\": \"Kliknij by anulowa\u0107\",\n\n \"menu.label.print\": \"Drukuj\",\n \"menu.label.undo\": \"Cofnij\",\n \"menu.label.redo\": \"Przywr\u00f3\u0107\",\n \"menu.label.cancel\": \"Anuluj\",\n\n \"menu.label.save.image\": \"Pobierz jako ...\",\n \"menu.label.save.data\": \"Zapisz jako ...\",\n\n \"menu.label.draw\": \"Rysuj ...\",\n \"menu.label.draw.change\": \"Zmie\u0144 ...\",\n \"menu.label.draw.add\": \"Dodaj ...\",\n \"menu.label.draw.shapes\": \"Kszta\u0142t ...\",\n \"menu.label.draw.colors\": \"Kolor ...\",\n \"menu.label.draw.widths\": \"Rozmiar ...\",\n \"menu.label.draw.opacities\": \"Prze\u017aroczysto\u015b\u0107 ...\",\n \"menu.label.draw.text\": \"Tekst\",\n\n \"menu.label.draw.modes\": \"Tryb ...\",\n \"menu.label.draw.modes.pencil\": \"O\u0142\u00f3wek\",\n \"menu.label.draw.modes.line\": \"Linia\",\n \"menu.label.draw.modes.arrow\": \"Strza\u0142ka\",\n\n \"label.saved.from\": \"Ocali\u0107 od: \"\n}","Amasty_Rewards/amcharts/lang/id.js":"AmCharts.translations.id = {\"monthNames\":[\"Januari\",\"Pebruari\",\"Maret\",\"April\",\"Mei\",\"Juni\",\"Juli\",\"Agustus\",\"September\",\"Oktober\",\"November\",\"Desember\"],\"shortMonthNames\":[\"Jan\",\"Peb\",\"Mar\",\"Apr\",\"Mei\",\"Jun\",\"Jul\",\"Agu\",\"Sep\",\"Okt\",\"Nov\",\"Des\"],\"dayNames\":[\"Minggu\",\"Senin\",\"Selasa\",\"Rabu\",\"Kamis\",\"Jumat\",\"Sabtu\"],\"shortDayNames\":[\"Min\",\"Sen\",\"Sel\",\"Rab\",\"Kam\",\"Jum\",\"Sab\"],\"zoomOutText\":\"Tampilkan semua\"}","Amasty_Rewards/amcharts/lang/th.js":"AmCharts.translations.th = {\"monthNames\":[\"\u0e21\u0e01\u0e23\u0e32\u0e04\u0e21\",\"\u0e01\u0e38\u0e21\u0e20\u0e32\u0e1e\u0e31\u0e19\u0e18\u0e4c\",\"\u0e21\u0e35\u0e19\u0e32\u0e04\u0e21\",\"\u0e40\u0e21\u0e29\u0e32\u0e22\u0e19\",\"\u0e1e\u0e24\u0e29\u0e20\u0e32\u0e04\u0e21\",\"\u0e21\u0e34\u0e16\u0e38\u0e19\u0e32\u0e22\u0e19\",\"\u0e01\u0e23\u0e01\u0e0e\u0e32\u0e04\u0e21\",\"\u0e2a\u0e34\u0e07\u0e2b\u0e32\u0e04\u0e21\",\"\u0e01\u0e31\u0e19\u0e22\u0e32\u0e22\u0e19\",\"\u0e15\u0e38\u0e25\u0e32\u0e04\u0e21\",\"\u0e1e\u0e24\u0e28\u0e08\u0e34\u0e01\u0e32\u0e22\u0e19\",\"\u0e18\u0e31\u0e19\u0e27\u0e32\u0e04\u0e21\"],\"shortMonthNames\":[\"\u0e21.\u0e04.\",\"\u0e01.\u0e1e.\",\"\u0e21\u0e35.\u0e04.\",\"\u0e40\u0e21.\u0e22.\",\"\u0e1e.\u0e04.\",\"\u0e21\u0e34.\u0e22.\",\"\u0e01.\u0e04.\",\"\u0e2a.\u0e04.\",\"\u0e01.\u0e22.\",\"\u0e15.\u0e04.\",\"\u0e1e.\u0e22.\",\"\u0e18.\u0e04.\"],\"dayNames\":[\"\u0e2d\u0e32\u0e17\u0e34\u0e15\u0e22\u0e4c\",\"\u0e08\u0e31\u0e19\u0e17\u0e23\u0e4c\",\"\u0e2d\u0e31\u0e07\u0e04\u0e32\u0e23\",\"\u0e1e\u0e38\u0e18\",\"\u0e1e\u0e24\u0e2b\u0e31\u0e2a\u0e1a\u0e14\u0e35\",\"\u0e28\u0e38\u0e01\u0e23\u0e4c\",\"\u0e40\u0e2a\u0e32\u0e23\u0e4c\"],\"shortDayNames\":[\"\u0e2d\u0e32.\",\"\u0e08.\",\"\u0e2d.\",\"\u0e1e.\",\"\u0e1e\u0e24.\",\"\u0e28.\",\"\u0e2a.\"],\"zoomOutText\":\"\u0e41\u0e2a\u0e14\u0e07\u0e17\u0e31\u0e49\u0e07\u0e2b\u0e21\u0e14\"}","Amasty_Rewards/amcharts/lang/it.js":"AmCharts.translations.it = {\"monthNames\":[\"Gennaio\",\"Febbraio\",\"Marzo\",\"Aprile\",\"Maggio\",\"Giugno\",\"Luglio\",\"Agosto\",\"Settembre\",\"Ottobre\",\"Novembre\",\"Dicembre\"],\"shortMonthNames\":[\"Gen\",\"Feb\",\"Mar\",\"Apr\",\"Mag\",\"Giu\",\"Lug\",\"Ago\",\"Set\",\"Ott\",\"Nov\",\"Dic\"],\"dayNames\":[\"Domenica\",\"Luned\u00ec\",\"Marted\u00ec\",\"Mercoled\u00ec\",\"Gioved\u00ec\",\"Venerd\u00ec\",\"Sabato\"],\"shortDayNames\":[\"Dom\",\"Lun\",\"Mar\",\"Mer\",\"Gio\",\"Ven\",\"Sab\"],\"zoomOutText\":\"Mostra tutti\"}","Amasty_Rewards/amcharts/lang/is.js":"AmCharts.translations.is = {\"monthNames\":[\"Jan\u00faar\",\"Febr\u00faar\",\"Mars\",\"Apr\u00edl\",\"Ma\u00ed\",\"J\u00fan\u00ed\",\"J\u00fal\u00ed\",\"\u00c1g\u00fast\",\"September\",\"Okt\u00f3ber\",\"N\u00f3vember\",\"Desember\"],\"shortMonthNames\":[\"Jan\",\"Feb\",\"Mar\",\"Apr\",\"Ma\u00ed\",\"J\u00fan\",\"J\u00fal\",\"\u00c1g\u00fa\",\"Sep\",\"Okt\",\"N\u00f3v\",\"Des\"],\"dayNames\":[\"Sunnudagur\",\"M\u00e1nudagur\",\"\u00deri\u00f0judagur\",\"Mi\u00f0vikudagur\",\"Fimmtudagur\",\"F\u00f6studagur\",\"Laugardagur\"],\"shortDayNames\":[\"Sun\",\"M\u00e1n\",\"\u00deri\",\"Mi\u00f0\",\"Fim\",\"F\u00f6s\",\"Lau\"],\"zoomOutText\":\"S\u00fdna allt\"}","Amasty_Rewards/amcharts/lang/ja.js":"AmCharts.translations.ja = {\"monthNames\":[\"1\u6708\",\"2\u6708\",\"3\u6708\",\"4\u6708\",\"5\u6708\",\"6\u6708\",\"7\u6708\",\"8\u6708\",\"9\u6708\",\"10\u6708\",\"11\u6708\",\"12\u6708\"],\"shortMonthNames\":[\"1\u6708\",\"2\u6708\",\"3\u6708\",\"4\u6708\",\"5\u6708\",\"6\u6708\",\"7\u6708\",\"8\u6708\",\"9\u6708\",\"10\u6708\",\"11\u6708\",\"12\u6708\"],\"dayNames\":[\"\u65e5\u66dc\u65e5\",\"\u6708\u66dc\u65e5\",\"\u706b\u66dc\u65e5\",\"\u6c34\u66dc\u65e5\",\"\u6728\u66dc\u65e5\",\"\u91d1\u66dc\u65e5\",\"\u571f\u66dc\u65e5\"],\"shortDayNames\":[\"\u65e5\",\"\u6708\",\"\u706b\",\"\u6c34\",\"\u6728\",\"\u91d1\",\"\u571f\"],\"zoomOutText\":\"\u3059\u3079\u3066\u8868\u793a\"};","Amasty_Rewards/amcharts/lang/mn.js":"AmCharts.translations.mn = {\"monthNames\":[\"\u0425\u0443\u043b\u0433\u0430\u043d\u0430 \u0441\u0430\u0440\u044b\u043d\",\"\u04ae\u0445\u044d\u0440 \u0441\u0430\u0440\u044b\u043d\",\"\u0411\u0430\u0440 \u0441\u0430\u0440\u044b\u043d\",\"\u0422\u0443\u0443\u043b\u0430\u0439 \u0441\u0430\u0440\u044b\u043d\",\"\u041b\u0443\u0443 \u0441\u0430\u0440\u044b\u043d\",\"\u041c\u043e\u0433\u043e\u0439 \u0441\u0430\u0440\u044b\u043d\",\"\u041c\u043e\u0440\u044c \u0441\u0430\u0440\u044b\u043d\",\"\u0425\u043e\u043d\u044c \u0441\u0430\u0440\u044b\u043d\",\"\u0411\u0438\u0447 \u0441\u0430\u0440\u044b\u043d\",\"\u0422\u0430\u0445\u0438\u0430 \u0441\u0430\u0440\u044b\u043d\",\"\u041d\u043e\u0445\u043e\u0439 \u0441\u0430\u0440\u044b\u043d\",\"\u0413\u0430\u0445\u0430\u0439 \u0441\u0430\u0440\u044b\u043d\"],\"shortMonthNames\":[\"\u0425\u0443\u043b\",\"\u04ae\u0445\u044d\",\"\u0411\u0430\u0440\",\"\u0422\u0443\u0443\",\"\u041b\u0443\u0443\",\"\u041c\u043e\u0433\",\"\u041c\u043e\u0440\",\"\u0425\u043e\u043d\",\"\u0411\u0438\u0447\",\"\u0422\u0430\u0445\",\"\u041d\u043e\u0445\",\"\u0413\u0430\u0445\"],\"dayNames\":[\"\u041d\u044f\u043c\",\"\u0414\u0430\u0432\u0430\u0430\",\"\u041c\u044f\u0433\u043c\u0430\u0440\",\"\u041b\u0445\u0430\u0433\u0432\u0430\",\"\u041f\u04af\u0440\u044d\u0432\",\"\u0411\u0430\u0430\u0441\u0430\u043d\",\"\u0411\u044f\u043c\u0431\u0430\"],\"shortDayNames\":[\"\u041d\u044f\",\"\u0414\u0430\",\"\u041c\u044f\",\"\u041b\u0445\",\"\u041f\u04af\",\"\u0411\u0430\",\"\u0411\u044f\"],\"zoomOutText\":\"\u0411\u04af\u0445 \u0445\u0430\u0440\u0443\u0443\u043b\u0430\u0445\"}","Amasty_Rewards/amcharts/lang/mt.js":"AmCharts.translations.mt = {\"monthNames\":[\"Jannar\",\"Frar\",\"Marzu\",\"April\",\"Mejju\",\"\u0120unju\",\"Lulju\",\"Awwissu\",\"Settembru\",\"Ottubru\",\"Novembru\",\"Di\u010bembru \"],\"shortMonthNames\":[\"Jan\",\"Fra\",\"Mar\",\"Apr\",\"Mej\",\"\u0120un\",\"Lul\",\"Aww\",\"Set\",\"Ott\",\"Nov\",\"Di\u010b\"],\"dayNames\":[\"Il-\u0127add\",\"It-tnejn\",\"It-tlieta\",\"L-erbg\u0127a\",\"Il-\u0127amis\",\"Il-\u0121img\u0127a\",\"Is-sibt\"],\"shortDayNames\":[\"\u0126ad\",\"Tne\",\"Tli\",\"Erb\",\"\u0126am\",\"\u0120im\",\"Sib\"],\"zoomOutText\":\"Turi kollha\"}","Amasty_Rewards/amcharts/lang/fi.js":"AmCharts.translations.fi = {\"monthNames\":[\"Tammikuu\",\"Helmikuu\",\"Maaliskuu\",\"Huhtikuu\",\"Toukokuu\",\"Kes\u00e4kuu\",\"Hein\u00e4kuu\",\"Elokuu\",\"Syyskuu\",\"Lokakuu\",\"Marraskuu\",\"Joulukuu\"],\"shortMonthNames\":[\"Tammi\u00a0\",\"Helmi\u00a0\",\"Maalis\",\"Huhti\u00a0\",\"Touko\u00a0\",\"Kes\u00e4\u00a0\u00a0\",\"Hein\u00e4\u00a0\",\"Elo\u00a0\u00a0\u00a0\",\"Syys\u00a0\u00a0\",\"Loka\u00a0\u00a0\",\"Marras\",\"Joulu\u00a0\"],\"dayNames\":[\"Sunnuntai\",\"Maanantai\",\"Tiistai\",\"Keskiviikko\",\"Torstai\",\"Perjantai\",\"Lauantai\"],\"shortDayNames\":[\"Su\",\"Ma\",\"Ti\",\"Ke\",\"To\",\"Pe\",\"La\"],\"zoomOutText\":\"N\u00e4yt\u00e4 kaikki\"}","Amasty_Rewards/amcharts/lang/no.js":"AmCharts.translations.no = {\"monthNames\":[\"Januar\",\"Februar\",\"Mars\",\"April\",\"Mai\",\"Juni\",\"Juli\",\"August\",\"September\",\"Oktober\",\"November\",\"Desember\"],\"shortMonthNames\":[\"Jan.\",\"Feb.\",\"Mars\",\"April\",\"Mai\",\"Juni\",\"Juli\",\"Aug.\",\"Sep.\",\"Okt.\",\"Nov.\",\"Des.\"],\"dayNames\":[\"S\u00f8ndag\",\"Mandag\",\"Tirsdag\",\"Onsdag\",\"Torsdag\",\"Fredag\",\"L\u00f8rdag\"],\"shortDayNames\":[\"S\u00f8.\",\"Ma.\",\"Ti.\",\"On.\",\"To.\",\"Fr.\",\"L\u00f8.\"],\"zoomOutText\":\"Vis alle\"}","Amasty_Rewards/amcharts/lang/hu.js":"AmCharts.translations.hu = {\"monthNames\":[\"Janu\u00e1r\",\"Febru\u00e1r\",\"M\u00e1rcius\",\"\u00c1prilis\",\"M\u00e1jus\",\"J\u00fanius\",\"J\u00falius\",\"Augusztus\",\"Szeptember\",\"Okt\u00f3ber\",\"November\",\"December\"],\"shortMonthNames\":[\"Jan\",\"Febr\",\"M\u00e1rc\",\"\u00c1pr\",\"M\u00e1j\",\"J\u00fan\",\"J\u00fal\",\"Aug\",\"Szept\",\"Okt\",\"Nov\",\"Dec\"],\"dayNames\":[\"Vas\u00e1rnap\",\"H\u00e9tf\u0151\",\"Kedd\",\"Szerda\",\"Cs\u00fct\u00f6rt\u00f6k\",\"P\u00e9ntek\",\"Szombat\"],\"shortDayNames\":[\"V\",\"H\",\"K\",\"Sze\",\"Cs\",\"P\",\"Szo\"],\"zoomOutText\":\"\u00d6sszes\"}","Amasty_Rewards/amcharts/lang/bg.js":"AmCharts.translations.bg = {\"monthNames\":[\"\u042f\u043d\u0443\u0430\u0440\u0438\",\"\u0424\u0435\u0432\u0440\u0443\u0430\u0440\u0438\",\"\u041c\u0430\u0440\u0442\",\"\u0410\u043f\u0440\u0438\u043b\",\"\u041c\u0430\u0439\",\"\u042e\u043d\u0438\",\"\u042e\u043b\u0438\",\"\u0410\u0432\u0433\u0443\u0441\u0442\",\"\u0421\u0435\u043f\u0442\u0435\u043c\u0432\u0440\u0438\",\"\u041e\u043a\u0442\u043e\u043c\u0432\u0440\u0438\",\"\u041d\u043e\u0435\u043c\u0432\u0440\u0438\",\"\u0414\u0435\u043a\u0435\u043c\u0432\u0440\u0438\"],\"shortMonthNames\":[\"\u042f\u043d\u0443\",\"\u0424\u0435\u0432\",\"\u041c\u0430\u0440\",\"\u0410\u043f\u0440\",\"\u041c\u0430\u0439\",\"\u042e\u043d\u0438\",\"\u042e\u043b\u0438\",\"\u0410\u0432\u0433\",\"\u0421\u0435\u043f\",\"\u041e\u043a\u0442\",\"\u041d\u043e\u0435\",\"\u0414\u0435\u043a\"],\"dayNames\":[\"\u041d\u0435\u0434\u0435\u043b\u044f\",\"\u041f\u043e\u043d\u0435\u0434\u0435\u043b\u043d\u0438\u043a\",\"\u0412\u0442\u043e\u0440\u043d\u0438\u043a\",\"\u0421\u0440\u044f\u0434\u0430\",\"\u0427\u0435\u0442\u0432\u044a\u0440\u0442\u044a\u043a\",\"\u041f\u0435\u0442\u044a\u043a\",\"\u0421\u044a\u0431\u043e\u0442\u0430\"],\"shortDayNames\":[\"\u041d\u0434\",\"\u041f\u043d\",\"\u0412\u0442\",\"\u0421\u0440\",\"\u0427\u0442\",\"\u041f\u0442\",\"\u0421\u0431\"],\"zoomOutText\":\"\u041f\u043e\u043a\u0430\u0436\u0438 \u0432\u0441\u0438\u0447\u043a\u0438\"}","Amasty_Rewards/amcharts/lang/mk.js":"AmCharts.translations.mk = {\"monthNames\":[\"\u0408\u0430\u043d\u0443\u0430\u0440\u0438\",\"\u0424\u0435\u0432\u0440\u0443\u0430\u0440\u0438\",\"\u041c\u0430\u0440\u0442\",\"\u0410\u043f\u0440\u0438\u043b\",\"\u041c\u0430\u0458\",\"\u0408\u0443\u043d\u0438\",\"\u0408\u0443\u043b\u0438\",\"\u0410\u0432\u0433\u0443\u0441\u0442\",\"\u0421\u0435\u043f\u0442\u0435\u043c\u0432\u0440\u0438\",\"\u041e\u043a\u0442\u043e\u043c\u0432\u0440\u0438\",\"\u041d\u043e\u0435\u043c\u0432\u0440\u0438\",\"\u0414\u0435\u043a\u0435\u043c\u0432\u0440\u0438\"],\"shortMonthNames\":[\"\u0408\u0430\u043d\",\"\u0424\u0435\u0432\",\"\u041c\u0430\u0440\",\"\u0410\u043f\u0440\",\"\u041c\u0430\u0458\",\"\u0408\u0443\u043d\",\"\u0408\u0443\u043b\",\"\u0410\u0432\u0433\",\"\u0421\u0435\u043f\",\"\u041e\u043a\u0442\",\"\u041d\u043e\u0435\",\"\u0414\u0435\u043a\"],\"dayNames\":[\"\u041d\u0435\u0434\u0435\u043b\u0430\",\"\u041f\u043e\u043d\u0435\u0434\u0435\u043b\u043d\u0438\u043a\",\"\u0412\u0442\u043e\u0440\u043d\u0438\u043a\",\"\u0421\u0440\u0435\u0434\u0430\",\"\u0427\u0435\u0442\u0432\u0440\u0442\u043e\u043a\",\"\u041f\u0435\u0442\u043e\u043a\",\"\u0421\u0430\u0431\u043e\u0442\u0430\"],\"shortDayNames\":[\"\u041d\u0435\u0434\",\"\u041f\u043e\u043d\",\"\u0412\u0442\u043e\",\"\u0421\u0440\u0435\",\"\u0427\u0435\u0442\",\"\u041f\u0435\u0442\",\"\u0421\u0430\u0431\"],\"zoomOutText\":\"\u041f\u0440\u0438\u043a\u0430\u0436\u0438 \u0433\u0438 \u0441\u0438\u0442\u0435\"}","Amasty_Rewards/amcharts/lang/ro.js":"AmCharts.translations.ro = {\"monthNames\":[\"Ianuarie\",\"Februarie\",\"Martie\",\"Aprilie\",\"Mai\",\"Iunie\",\"Iulie\",\"August\",\"Septembrie\",\"Octombrie\",\"Noiembrie\",\"Decembrie\"],\"shortMonthNames\":[\"Ian\",\"Feb\",\"Mar\",\"Apr\",\"Mai\",\"Iun\",\"Iul\",\"Aug\",\"Sep\",\"Oct\",\"Nov\",\"Dec\"],\"dayNames\":[\"Duminic\u0103\",\"Luni\",\"Mar\u0163i\",\"Miercuri\",\"Joi\",\"Vineri\",\"S\u00e2mb\u0103t\u0103\"],\"shortDayNames\":[\"Du\",\"Lu\",\"Ma\",\"Mi\",\"Jo\",\"Vi\",\"Sb\"],\"zoomOutText\":\"Arat\u0103 tot\"}","Amasty_Rewards/amcharts/lang/lt.js":"AmCharts.translations.lt = {\"monthNames\":[\"Sausio\",\"Vasario\",\"Kovo\",\"Baland\u017eio\",\"Gegu\u017e\u0117s\",\"Bir\u017eelio\",\"Liepos\",\"Rugpj\u016b\u010dio\",\"Rugs\u0117jo\",\"Spalio\",\"Lapkri\u010dio\",\"Gruod\u017eio\"],\"shortMonthNames\":[\"Sau\",\"Vas\",\"Kov\",\"Bal\",\"Geg\",\"Bir\",\"Lie\",\"Rgp\",\"Rgs\",\"Spa\",\"Lap\",\"Grd\"],\"dayNames\":[\"Sekmadienis\",\"Pirmadienis\",\"Antradienis\",\"Tre\u010diadienis\",\"Ketvirtadienis\",\"Penktadienis\",\"\u0160e\u0161tadienis\"],\"shortDayNames\":[\"Sk\",\"Pr\",\"An\",\"Tr\",\"Kt\",\"Pn\",\"\u0160t\"],\"zoomOutText\":\"Rodyti visk\u0105\"}","Amasty_Rewards/amcharts/lang/cs.js":"AmCharts.translations.cs = {\"monthNames\":[\"Leden\",\"\u00danor\",\"B\u0159ezen\",\"Duben\",\"Kv\u011bten\",\"\u010cerven\",\"\u010cervenec\",\"Srpen\",\"Z\u00e1\u0159\u00ed\",\"\u0158\u00edjen\",\"Listopad\",\"Prosinec\"],\"shortMonthNames\":[\"Led\",\"\u00dano\",\"B\u0159e\",\"Dub\",\"Kv\u011b\",\"\u010cer\",\"\u010cec\",\"Srp\",\"Z\u00e1\u0159\",\"\u0158\u00edj\",\"Lis\",\"Pro\"],\"dayNames\":[\"Ned\u011ble\",\"Pond\u011bl\u00ed\",\"\u00dater\u00fd\",\"St\u0159eda\",\"\u010ctvrtek\",\"P\u00e1tek\",\"Sobota\"],\"shortDayNames\":[\"Ne\",\"Po\",\"\u00dat\",\"St\",\"\u010ct\",\"P\u00e1\",\"So\"],\"zoomOutText\":\"Zobrazit v\u0161e\"}","Amasty_Rewards/amcharts/lang/lv.js":"AmCharts.translations.lv = {\"monthNames\":[\"Janv\u0101ris\",\"Febru\u0101ris\",\"Marts\",\"Apr\u012blis\",\"Maijs\",\"J\u016bnijs\",\"J\u016blijs\",\"Augusts\",\"Septembris\",\"Oktobris\",\"Novembris\",\"Decembris\"],\"shortMonthNames\":[\"Jan\",\"Feb\",\"Mar\",\"Apr\",\"Mai\",\"J\u016bn\",\"J\u016bl\",\"Aug\",\"Sep\",\"Okt\",\"Nov\",\"Dec\"],\"dayNames\":[\"Sv\u0113tdiena\",\"Pirmdiena\",\"Otrdiena\",\"Tre\u0161diena\",\"Ceturtdiena\",\"Piektdiena\",\"Sestdiena\"],\"shortDayNames\":[\"Sv\",\"P\u00a0\",\"O\u00a0\",\"T\u00a0\",\"C\u00a0\",\"Pk\",\"S\u00a0\"],\"zoomOutText\":\"Par\u0101d\u012bt visu\"}","Amasty_Rewards/amcharts/lang/fr.js":"AmCharts.translations.fr = {\"monthNames\":[\"Janvier\",\"F\u00e9vrier\",\"Mars\",\"Avril\",\"Mai\",\"Juin\",\"Juillet\",\"Ao\u00fbt\",\"Septembre\",\"Octobre\",\"Novembre\",\"D\u00e9cembre\"],\"shortMonthNames\":[\"Janv.\",\"F\u00e9vr.\",\"Mars\",\"Avril\",\"Mai\",\"Juin\",\"Juil.\",\"Ao\u00fbt\",\"Sept.\",\"Oct.\",\"Nov.\",\"D\u00e9c.\"],\"dayNames\":[\"Dimanche\",\"Lundi\",\"Mardi\",\"Mercredi\",\"Jeudi\",\"Vendredi\",\"Samedi\"],\"shortDayNames\":[\"Dim.\",\"Lun.\",\"Mar.\",\"Mer.\",\"Jeu.\",\"Ven.\",\"Sam.\"],\"zoomOutText\":\"Voir tous\"}","Amasty_Rewards/amcharts/lang/zh.js":"AmCharts.translations.zh = {\n \"monthNames\": [ \"1\u6708\", \"2\u6708\", \"3\u6708\", \"4\u6708\", \"5\u6708\", \"6\u6708\", \"7\u6708\", \"8\u6708\", \"9\u6708\", \"10\u6708\", \"11\u6708\", \"12\u6708\" ],\n \"shortMonthNames\": [ \"1\u6708\", \"2\u6708\", \"3\u6708\", \"4\u6708\", \"5\u6708\", \"6\u6708\", \"7\u6708\", \"8\u6708\", \"9\u6708\", \"10\u6708\", \"11\u6708\", \"12\u6708\" ],\n \"dayNames\": [ \"\u661f\u671f\u65e5\", \"\u661f\u671f\u4e00\", \"\u661f\u671f\u4e8c\", \"\u661f\u671f\u4e09\", \"\u661f\u671f\u56db\", \"\u661f\u671f\u4e94\", \"\u661f\u671f\u516d\" ],\n \"shortDayNames\": [ \"\u661f\u671f\u65e5\", \"\u661f\u671f\u4e00\", \"\u661f\u671f\u4e8c\", \"\u661f\u671f\u4e09\", \"\u661f\u671f\u56db\", \"\u661f\u671f\u4e94\", \"\u661f\u671f\u516d\" ],\n \"zoomOutText\": \"\u663e\u793a\u6240\u6709\",\n \"am\": \"\u4e0a\u5348\",\n \"pm\": \"\u4e0b\u5348\"\n}","Amasty_Rewards/amcharts/lang/ru.js":"AmCharts.translations.ru = {\"monthNames\":[\"\u042f\u043d\u0432\u0430\u0440\u044c\",\"\u0424\u0435\u0432\u0440\u0430\u043b\u044c\",\"\u041c\u0430\u0440\u0442\",\"\u0410\u043f\u0440\u0435\u043b\u044c\",\"\u041c\u0430\u0439\",\"\u0418\u044e\u043d\u044c\",\"\u0418\u044e\u043b\u044c\",\"\u0410\u0432\u0433\u0443\u0441\u0442\",\"\u0421\u0435\u043d\u0442\u044f\u0431\u0440\u044c\",\"\u041e\u043a\u0442\u044f\u0431\u0440\u044c\",\"\u041d\u043e\u044f\u0431\u0440\u044c\",\"\u0414\u0435\u043a\u0430\u0431\u0440\u044c\"],\"shortMonthNames\":[\"\u042f\u043d\u0432\",\"\u0424\u0435\u0432\",\"\u041c\u0430\u0440\",\"\u0410\u043f\u0440\",\"\u041c\u0430\u0439\",\"\u0418\u044e\u043d\",\"\u0418\u044e\u043b\",\"\u0410\u0432\u0433\",\"\u0421\u0435\u043d\",\"\u041e\u043a\u0442\",\"\u041d\u043e\u044f\",\"\u0414\u0435\u043a\"],\"dayNames\":[\"\u0412\u043e\u0441\u043a\u0440\u0435\u0441\u0435\u043d\u044c\u0435\",\"\u041f\u043e\u043d\u0435\u0434\u0435\u043b\u044c\u043d\u0438\u043a\",\"\u0412\u0442\u043e\u0440\u043d\u0438\u043a\",\"\u0421\u0440\u0435\u0434\u0430\",\"\u0427\u0435\u0442\u0432\u0435\u0440\u0433\",\"\u041f\u044f\u0442\u043d\u0438\u0446\u0430\",\"\u0421\u0443\u0431\u0431\u043e\u0442\u0430\"],\"shortDayNames\":[\"\u0412\u0441\u043a\",\"\u041f\u043d\u0434\",\"\u0412\u0442\u0440\",\"\u0421\u0440\u0434\",\"\u0427\u0442\u0432\",\"\u041f\u0442\u043d\",\"\u0421\u0431\u0442\"],\"zoomOutText\":\"\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u0432\u0441\u0435\"}","Amasty_Rewards/amcharts/lang/so.js":"AmCharts.translations.so = {\"monthNames\":[\"Bisha koobaad\",\"Bisha labaad\",\"Bisha saddexaad\",\"Bisha afraad\",\"Bisha shanaad\",\"Bisha lixaad\",\"Bisha todobaad\",\"Bisha sideedaad\",\"Bisha sagaalaad\",\"Bisha tobnaad\",\"Bisha kow iyo tobnaad\",\"Bisha laba iyo tobnaad\"],\"shortMonthNames\":[\"Kob\",\"Lab\",\"Sad\",\"Afr\",\"Sha\",\"Lix\",\"Tod\",\"Sid\",\"Sag\",\"Tob\",\"Kit\",\"Lit\"],\"dayNames\":[\"Axad\",\"Isniin\",\"Salaaso\",\"Arbaco\",\"Khamiis\",\"Jimco\",\"Sabti\"],\"shortDayNames\":[\"Axa\",\"Isn\",\"Sal\",\"Arb\",\"Kha\",\"Jim\",\"Sab\"],\"zoomOutText\":\"Tus dhammaan\"}","Amasty_Rewards/amcharts/lang/tr.js":"AmCharts.translations.tr = {\"monthNames\":[\"Ocak\",\"\u015eubat\",\"Mart\",\"Nisan\",\"May\u0131s\",\"Haziran\",\"Temmuz\",\"A\u011fustos\",\"Eyl\u00fcl\",\"Ekim\",\"Kas\u0131m\",\"Aral\u0131k\"],\"shortMonthNames\":[\"Oca\",\"\u015eub\",\"Mar\",\"Nis\",\"May\",\"Haz\",\"Tem\",\"A\u011fu\",\"Eyl\",\"Eki\",\"Kas\",\"Ara\"],\"dayNames\":[\"Pazar\",\"Pazartesi\",\"Sal\u0131\",\"\u00c7ar\u015famba\",\"Per\u015fembe\",\"Cuma\",\"Cumartesi\"],\"shortDayNames\":[\"Paz\",\"Pzt\",\"Sal\",\"\u00c7r\u015f\",\"Pr\u015f\",\"Cum\",\"Cts\"],\"zoomOutText\":\"T\u00fcm\u00fcn\u00fc g\u00f6ster\"}","Amasty_Rewards/amcharts/lang/sk.js":"AmCharts.translations.sk = {\"monthNames\":[\"Janu\u00e1r\",\"Febru\u00e1r\",\"Marec\",\"Apr\u00edl\",\"M\u00e1j\",\"J\u00fan\",\"J\u00fal\",\"August\",\"September\",\"Okt\u00f3ber\",\"November\",\"December\"],\"shortMonthNames\":[\"Jan\",\"Feb\",\"Mar\",\"Apr\",\"M\u00e1j\",\"J\u00fan\",\"J\u00fal\",\"Aug\",\"Sep\",\"Okt\",\"Nov\",\"Dec\"],\"dayNames\":[\"Nede\u013ea\",\"Pondelok\",\"Utorok\",\"Streda\",\"\u0160tvrtok\",\"Piatok\",\"Sobota\"],\"shortDayNames\":[\"Ne\",\"Po\",\"Ut\",\"St\",\"\u0160t\",\"Pi\",\"So\"],\"zoomOutText\":\"Zobrazi\u0165 v\u0161etky\"}","Amasty_Rewards/amcharts/lang/nl.js":"AmCharts.translations.nl = {\"monthNames\":[\"Januari\",\"Februari\",\"Maart\",\"April\",\"Mei\",\"Juni\",\"Juli\",\"Augustus\",\"September\",\"Oktober\",\"November\",\"December\"],\"shortMonthNames\":[\"Jan\",\"Feb\",\"Mrt\",\"Apr\",\"Mei\",\"Jun\",\"Jul\",\"Aug\",\"Sep\",\"Okt\",\"Nov\",\"Dec\"],\"dayNames\":[\"Zondag\",\"Maandag\",\"Dinsdag\",\"Woensdag\",\"Donderdag\",\"Vrijdag\",\"Zaterdag\"],\"shortDayNames\":[\"Zo\",\"Ma\",\"Di\",\"Wo\",\"Do\",\"Vr\",\"Za\"],\"zoomOutText\":\"Alles weergeven\"}","Amasty_Rewards/amcharts/lang/fo.js":"AmCharts.translations.fo = {\"monthNames\":[\"Januar\",\"Februar\",\"Mars\",\"Apr\u00edl\",\"Mai\",\"Juni\",\"Juli\",\"August\",\"September\",\"Oktober\",\"November\",\"Desember\"],\"shortMonthNames\":[\"Jan\",\"Feb\",\"Mar\",\"Apr\",\"Mai\",\"Jun\",\"Jul\",\"Aug\",\"Sep\",\"Okt\",\"Nov\",\"Des\"],\"dayNames\":[\"Sunnudagur\",\"M\u00e1nadagur\",\"T\u00fdsdagur\",\"Mikudagur\",\"H\u00f3sdagur\",\"Fr\u00edggjadagur\",\"Leygardagur\"],\"shortDayNames\":[\"Sun\",\"M\u00e1n\",\"T\u00fds\",\"Mik\",\"H\u00f3s\",\"Fr\u00ed\",\"Ley\"],\"zoomOutText\":\"Show all\"}","Amasty_Rewards/amcharts/lang/pt.js":"AmCharts.translations.pt = {\"monthNames\":[\"Janeiro\",\"Fevereiro\",\"Mar\u00e7o\",\"Abril\",\"Maio\",\"Junho\",\"Julho\",\"Agosto\",\"Setembro\",\"Outubro\",\"Novembro\",\"Dezembro\"],\"shortMonthNames\":[\"Jan\",\"Fev\",\"Mar\",\"Abr\",\"Mai\",\"Jun\",\"Jul\",\"Ago\",\"Set\",\"Out\",\"Nov\",\"Dez\"],\"dayNames\":[\"Domingo\",\"Segunda\",\"Ter\u00e7a\",\"Quarta\",\"Quinta\",\"Sexta\",\"S\u00e1bado\"],\"shortDayNames\":[\"Dom\",\"Seg\",\"Ter\",\"Qua\",\"Qui\",\"Sex\",\"S\u00e1b\"],\"zoomOutText\":\"Mostrar todos\"}","Amasty_Rewards/amcharts/lang/az.js":"AmCharts.translations.az = {\"monthNames\":[\"Yanvar\",\"Fevral\",\"Mart\",\"Aprel\",\"May\",\"Iyun\",\"Iyul\",\"Avqust\",\"Sentyabr\",\"Oktyabr\",\"Noyabr\",\"Dekabr\"],\"shortMonthNames\":[\"Yan\",\"Fev\",\"Mar\",\"Apr\",\"May\",\"Iyn\",\"Iyl\",\"Avq\",\"Sen\",\"Okt\",\"Noy\",\"Dek\"],\"dayNames\":[\"Bazar g\u00fcn\u00fc\",\"Bazar ert\u0259si\",\"\u00c7\u0259r\u015f\u0259nb\u0259 ax\u015fam\u0131\",\"\u00c7\u0259r\u015f\u0259nb\u0259\",\"C\u00fcm\u0259 ax\u015fam\u0131\",\"C\u00fcm\u0259\",\"\u015e\u0259nb\u0259\"],\"shortDayNames\":[\"Baz\",\"Ber\",\"\u00c7ax\",\"\u00c7\u0259r\",\"Cax\",\"C\u00fcm\",\"\u015enb\"],\"zoomOutText\":\"B\u00fct\u00fcn g\u00f6st\u0259r\"}","Amasty_Rewards/amcharts/lang/es.js":"AmCharts.translations.es = {\"monthNames\":[\"Enero\",\"Febrero\",\"Marzo\",\"Abril\",\"Mayo\",\"Junio\",\"Julio\",\"Agosto\",\"Septiembre\",\"Octubre\",\"Noviembre\",\"Diciembre\"],\"shortMonthNames\":[\"Ene\",\"Feb\",\"Mar\",\"Abr\",\"May\",\"Jun\",\"Jul\",\"Ago\",\"Sep\",\"Oct\",\"Nov\",\"Dic\"],\"dayNames\":[\"Domingo\",\"Lunes\",\"Martes\",\"Mi\u00e9rcoles\",\"Jueves\",\"Viernes\",\"S\u00e1bado\"],\"shortDayNames\":[\"Dom\",\"Lun\",\"Mar\",\"Mi\u00e9\",\"Jue\",\"Vie\",\"S\u00e1b\"],\"zoomOutText\":\"Mostrar todos\"}","Amasty_Rewards/amcharts/lang/de.js":"AmCharts.translations.de = {\"monthNames\":[\"Januar\",\"Februar\",\"M\u00e4rz\",\"April\",\"Mai\",\"Juni\",\"Juli\",\"August\",\"September\",\"Oktober\",\"November\",\"Dezember\"],\"shortMonthNames\":[\"Jan\",\"Feb\",\"M\u00e4r\",\"Apr\",\"Mai\",\"Jun\",\"Jul\",\"Aug\",\"Sep\",\"Okt\",\"Nov\",\"Dez\"],\"dayNames\":[\"Sonntag\",\"Montag\",\"Dienstag\",\"Mittwoch\",\"Donnerstag\",\"Freitag\",\"Samstag\"],\"shortDayNames\":[\"So\",\"Mo\",\"Di\",\"Mi\",\"Do\",\"Fr\",\"Sa\"],\"zoomOutText\":\"Alle anzeigen\"}","Amasty_Rewards/amcharts/lang/ko.js":"AmCharts.translations.ko = {\"monthNames\":[\"1\uc6d4\",\"2\uc6d4\",\"3\uc6d4\",\"4\uc6d4\",\"5\uc6d4\",\"6\uc6d4\",\"7\uc6d4\",\"8\uc6d4\",\"9\uc6d4\",\"10\uc6d4\",\"11\uc6d4\",\"12\uc6d4\"],\"shortMonthNames\":[\"1\uc6d4\",\"2\uc6d4\",\"3\uc6d4\",\"4\uc6d4\",\"5\uc6d4\",\"6\uc6d4\",\"7\uc6d4\",\"8\uc6d4\",\"9\uc6d4\",\"10\uc6d4\",\"11\uc6d4\",\"12\uc6d4\"],\"dayNames\":[\"\uc77c\uc694\uc77c\",\"\uc6d4\uc694\uc77c\",\"\ud654\uc694\uc77c\",\"\uc218\uc694\uc77c\",\"\ubaa9\uc694\uc77c\",\"\uae08\uc694\uc77c\",\"\ud1a0\uc694\uc77c\"],\"shortDayNames\":[\"\uc77c\",\"\uc6d4\",\"\ud654\",\"\uc218\",\"\ubaa9\",\"\uae08\",\"\ud1a0\"],\"zoomOutText\":\"\ubaa8\ub450 \ubcf4\uae30\"};","Amasty_Rewards/amcharts/lang/hr.js":"AmCharts.translations.hr = {\"monthNames\":[\"Sije\u010danj\",\"Velja\u010da\",\"O\u017eujak\",\"Travanj\",\"Svibanj\",\"Lipanj\",\"Srpanj\",\"Kolovoz\",\"Rujan\",\"Listopad\",\"Studeni\",\"Prosinac\"],\"shortMonthNames\":[\"Sij\",\"Vel\",\"O\u017eu\",\"Tra\",\"Svi\",\"Lip\",\"Srp\",\"Kol\",\"Ruj\",\"Lis\",\"Stu\",\"Pro\"],\"dayNames\":[\"Nedjelja\",\"Ponedjeljak\",\"Utorak\",\"Srijeda\",\"\u010cetvrtak\",\"Petak\",\"Subota\"],\"shortDayNames\":[\"Ned\",\"Pon\",\"Uto\",\"Sri\",\"\u010cet\",\"Pet\",\"Sub\"],\"zoomOutText\":\"Prika\u017ei sve\"}","Amasty_Rewards/amcharts/lang/rw.js":"AmCharts.translations.rw = {\"monthNames\":[\"Mutarama\",\"Gashyantare\",\"Werurwe\",\"Mata\",\"Gicuransi\",\"Kamena\",\"Nyakanga\",\"Kanama\",\"Nzeli\",\"Ukwakira\",\"Ugushyingo\",\"Ukuboza\"],\"shortMonthNames\":[\"Mut\",\"Gas\",\"Wer\",\"Mat\",\"Gic\",\"Kam\",\"Nya\",\"Kan\",\"Nze\",\"Ukw\",\"Ugu\",\"Uku\"],\"dayNames\":[\"Ku cyumweru\",\"Kuwa mbere\",\"Kuwa kabiri\",\"Kuwa gatatu\",\"Kuwa kane\",\"Kuwa gatanu\",\"Kuwa gatandatu\"],\"shortDayNames\":[\"Mwe\",\"Mbe\",\"Kab\",\"Gtu\",\"Kan\",\"Gnu\",\"Gnd\"],\"zoomOutText\":\"Show all\"}","Amasty_Rewards/amcharts/lang/pl.js":"AmCharts.translations.pl = {\"monthNames\":[\"Stycze\u0144\",\"Luty\",\"Marzec\",\"Kwiecie\u0144\",\"Maj\",\"Czerwiec\",\"Lipiec\",\"Sierpie\u0144\",\"Wrzesie\u0144\",\"Pa\u017adziernik\",\"Listopad\",\"Grudzie\u0144\"],\"shortMonthNames\":[\"Sty\",\"Lut\",\"Mar\",\"Kwi\",\"Maj\",\"Cze\",\"Lip\",\"Sie\",\"Wrz\",\"Pa\u017a\",\"Lis\",\"Gru\"],\"dayNames\":[\"Niedziela\",\"Poniedzia\u0142ek\",\"Wtorek\",\"\u015aroda\",\"Czwartek\",\"Pi\u0105tek\",\"Sobota\"],\"shortDayNames\":[\"Nie\",\"Pon\",\"Wto\",\"\u015aro\",\"Czw\",\"Pi\u0105\",\"Sob\"],\"zoomOutText\":\"Poka\u017c wszystko\"}","Amasty_Rewards/js/validation.js":"require([\n 'jquery',\n 'mage/translate',\n 'jquery/validate'\n ],\n function ($) {\n $.validator.addMethod(\n 'validate-length-of-numbers-after-comma',\n function (v) {\n return /^\\d+(\\.\\d{0,2})?$/.test(v);\n },\n $.mage.__('The field should contain no more than 2 decimal places.')\n );\n }\n);\n","Amasty_Rewards/js/reports.js":"define([\n 'jquery',\n 'mage/translate'\n], function ($) {\n 'use strict';\n var updateUrl = null;\n\n function checkPeriodVisibility() {\n if ($('#rewards_reports_date_range').val() === \"0\") {\n $('#rewards_reports_date_from, #rewards_reports_date_to').parent().show().find('*').show();\n } else {\n $('#rewards_reports_date_from, #rewards_reports_date_to').parent().hide();\n }\n }\n\n function refresh() {\n $.ajax({\n showLoader: true,\n url: updateUrl,\n dataType: 'JSON',\n data: $('.entry-edit.form-inline :input').serializeArray(),\n type: \"POST\",\n success: function (response) {\n if (response) {\n if (response.type === 'error' || response.type === 'warning') {\n $('.amrewards-report-statistics, .amrewards-report-chart').hide();\n $('.amrewards-report-error').text(response.message).show();\n\n if (response.type === 'warning') {\n $('.amrewards-report-error').removeClass('message-error error');\n $('.amrewards-report-error').addClass('message-info info');\n } else if (response.type === 'error') {\n $('.amrewards-report-error').removeClass('message-info info');\n $('.amrewards-report-error').addClass('message-error error');\n }\n } else if (response.type === 'success') {\n $('.amrewards-report-statistics, .amrewards-report-chart').show();\n $('.amrewards-report-error').hide();\n setData(response.data);\n }\n }\n }\n });\n }\n\n function setData(data) {\n $('[data-amrewards-js=\"rewarded-points\"]').text(data.total.rewarded);\n $('[data-amrewards-js=\"redeemed-points\"]').text(data.total.redeemed);\n $('[data-amrewards-js=\"average-rewarded\"]').text(data.average.rewarded);\n $('[data-amrewards-js=\"average-redeemed\"]').text(data.average.redeemed);\n $('[data-amrewards-js=\"total-expired\"]').text(data.total.expired);\n\n amRewardsReportChart.dataProvider = data.graph;\n amRewardsReportChart.parseData();\n amRewardsReportChart.zoomOut()\n }\n\n return function (config) {\n updateUrl = config.ajaxUrl;\n\n checkPeriodVisibility();\n\n $('#rewards_reports_date_range').on('change', checkPeriodVisibility);\n $('#rewards_reports_submit').on('click', refresh);\n\n $(document).ready(function() {\n refresh();\n });\n }\n});\n","Amasty_Rewards/js/color.js":"define([\n \"jquery\",\n \"jquery/colorpicker/js/colorpicker\"\n], function ($) {\n 'use strict';\n\n return function (config) {\n $(document).ready(function () {\n var input = $(\"#\" + config.htmlId);\n\n function inverse(color) {\n return (0xFFFFFF - (\"0x\" + color)).toString(16).padStart(6, \"0\").toUpperCase();\n }\n\n if (config.inverseHex !== '') {\n input.css({\"backgroundColor\" : config.value, \"color\": config.inverseHex});\n }\n\n input.ColorPicker({\n color: \"' . $value . '\",\n onChange: function (hsb, hex) {\n input.css({\"backgroundColor\": \"#\" + hex, \"color\": \"#\" + inverse(hex)}).val(\"#\" + hex);\n }\n });\n });\n };\n});\n","Amasty_Rewards/js/add-points-dialog.js":"/*jshint browser:true jquery:true*/\n/*global FORM_KEY*/\ndefine([\n 'jquery',\n 'uiRegistry',\n 'Magento_Ui/js/modal/modal',\n 'mage/translate',\n 'mage/backend/tree-suggest',\n 'mage/backend/validation'\n], function ($, registry) {\n 'use strict';\n\n window.block_amrewards = registry.get('customer_form.areas.block_amrewards.block_amrewards');\n window.block_amrewards_history = registry.get('customer_form.areas.block_amrewardsHistory.block_amrewardsHistory');\n\n actionChange();\n\n $.widget('mage.newRewardsDialog', {\n _create: function () {\n var widget = this;\n var newRewardsForm = $('#new_rewards_form');\n newRewardsForm.mage('validation', {\n errorPlacement: function (error, element) {\n error.insertAfter(element.is('#new_rewards_parent') ?\n $('#new_rewards_parent-suggest').closest('.mage-suggest') :\n element);\n },\n ignore: '.ignore-validate'\n }).on('highlight.validate', function (e) {\n var options = $(this).validation('option');\n if ($(e.target).is('#new_rewards_parent')) {\n options.highlight($('#new_rewards_parent-suggest').get(0),\n options.errorClass, options.validClass || '');\n }\n });\n this.element.modal({\n type: 'slide',\n modalClass: 'mage-new-rewards-dialog form-inline',\n title: $.mage.__('Add or Deduct Points'),\n closed: function () {\n $('#new_rewards_messages').empty();\n $('#new_rewards_amount').val('');\n $('#new_rewards_amount').focus();\n $('#new_rewards_comment').val('');\n },\n buttons: [{\n text: $.mage.__('Apply'),\n class: 'action-primary',\n click: function (e) {\n if (!newRewardsForm.valid()) {\n return;\n }\n var thisButton = $(e.currentTarget);\n thisButton.prop('disabled', true);\n var postData = {\n amount: $('#new_rewards_amount').val(),\n comment: $('#new_rewards_comment').val(),\n action: $('#new_rewards_action').val(),\n expiration: {\n is_expire: $('#new_rewards_expiration_behavior').val(),\n days: $('#new_rewards_expiration_period').val()\n },\n form_key: FORM_KEY,\n customer_id: widget.options.customerId,\n return_session_messages_only: 1,\n visible_for_customer: $('#visible_for_customer').val()\n };\n\n $.ajax({\n type: 'POST',\n url: widget.options.saveCategoryUrl,\n data: postData,\n dataType: 'json',\n context: $('body'),\n success: function (data) {\n if (!data.error) {\n $('#new_rewards_amount, #new_rewards_comment').val('');\n $(widget.element).modal('closeModal');\n } else {\n $('#new_rewards_messages').html(data.messages);\n }\n },\n complete: function () {\n thisButton.prop('disabled', false);\n window.block_amrewards.loadData();\n window.block_amrewards_history.loadData();\n }\n });\n }\n }]\n });\n }\n });\n\n function actionChange() {\n if ($('#new_rewards_action').val() === 'add') {\n $('.field-new_rewards_expiration_behavior').show();\n expirationBehaviorChange();\n } else {\n $('.field-new_rewards_expiration_behavior').hide();\n $('.field-new_rewards_expiration_period').hide();\n $('#new_rewards_expiration_period').addClass('ignore-validate');\n }\n }\n\n function expirationBehaviorChange() {\n if ($('#new_rewards_expiration_behavior').val() === '1') {\n $('.field-new_rewards_expiration_period').show();\n $('#new_rewards_expiration_period').removeClass('ignore-validate');\n } else {\n $('.field-new_rewards_expiration_period').hide();\n $('#new_rewards_expiration_period').addClass('ignore-validate');\n }\n }\n\n $('#new_rewards_action').on('change', actionChange);\n\n $('#new_rewards_expiration_behavior').on('change', expirationBehaviorChange);\n\n return $.mage.newRewardsDialog;\n});\n","Amasty_Rewards/js/form/conditions-fieldset.js":"define([\n 'Magento_Ui/js/form/components/fieldset',\n 'uiRegistry',\n 'jquery'\n], function (Fieldset, registry, $) {\n 'use strict';\n\n return Fieldset.extend({\n defaults: {\n conditionActions: [],\n listens: {\n '${ $.parentName }.actions.action:value': 'onChange'\n }\n },\n\n initialize: function () {\n this._super();\n registry.get(this.parentName + '.actions.action', function (component) {\n this.checkVisibility(component.value());\n }.bind(this));\n },\n\n onChange: function (value) {\n this.checkVisibility(value);\n },\n\n checkVisibility: function (value) {\n if (_.contains(this.conditionActions, value)) {\n this.visible(true);\n } else {\n this.visible(false);\n }\n }\n });\n});\n","Amasty_Rewards/js/form/labels-fieldset.js":"define([\n 'Magento_Ui/js/form/components/fieldset',\n 'uiRegistry',\n 'Magento_Ui/js/lib/view/utils/async',\n 'jquery'\n], function (Fieldset, registry, async, $) {\n 'use strict';\n\n return Fieldset.extend({\n defaults: {\n initializeFieldsetDataByDefault: false,\n actionComments: {\n 'ordercompleted': $.mage.__('Purchase is made bonus for order'),\n 'subscription': $.mage.__('Newsletter subscription bonus'),\n 'birthday': $.mage.__('Birthday points'),\n 'moneyspent': $.mage.__('Spending every $X amount bonus'),\n 'registration': $.mage.__('Registration bonus'),\n 'visit': $.mage.__('Inactive for a long time bonus'),\n 'review': $.mage.__('Review written bonus'),\n },\n listens: {\n '${ $.parentName }.actions.action:value': 'onChange'\n },\n modules: {\n defaultLabel: '${ $.parentName }.labels.store_labels[0]'\n }\n },\n\n initialize: function () {\n this._super();\n\n async.async('input[name=\"store_labels[0]\"]', function () {\n registry.get(this.parentName + '.actions.action', function (component) {\n this.setDefaultValue(component.value(), true);\n }.bind(this));\n }.bind(this));\n },\n\n onChange: function (value) {\n this.setDefaultValue(value);\n },\n\n setDefaultValue: function (value, init = false) {\n require(['jquery'], function ($) {\n var labels = $('input[name*=store_labels]').get();\n\n if (labels.length) {\n for (var label in labels) {\n if (labels.hasOwnProperty(label)\n && this.actionComments.hasOwnProperty(value)\n ) {\n if (label == 0 && this.defaultLabel()) {\n if (init && this.defaultLabel().value()) {\n continue;\n }\n this.defaultLabel().value(this.actionComments[value]);\n } else {\n if (init && labels[label].value) {\n continue;\n }\n labels[label].value = this.actionComments[value];\n }\n }\n }\n }\n }.bind(this));\n }\n });\n});\n","Amasty_Rewards/js/form/element/validation.js":"define([\n 'Magento_Ui/js/form/element/abstract',\n 'jquery',\n 'Magento_Ui/js/lib/validation/validator',\n 'mage/translate'\n], function (Abstract, $, validator) {\n 'use strict';\n\n validator.addRule(\n 'validate-length-of-numbers-after-comma',\n function (value) {\n return /^\\d+(\\.\\d{0,2})?$/.test(value);\n },\n $.mage.__('The field should contain no more than 2 decimal places.')\n );\n\n return Abstract.extend({\n 'validate-length-of-numbers-after-comma': function () {\n return validator('validate-length-of-numbers-after-comma', this.value()).passed;\n }\n });\n});","Amasty_Rewards/js/system/config/note-changer.js":"define ([\n 'jquery'\n], function ($) {\n\n function reload(map, selectedValue) {\n if (map[selectedValue]) {\n $.each(map[selectedValue], function (fieldToUpdate, note) {\n var fieldElement = $('#row_' + fieldToUpdate),\n noteElement = fieldElement.find('.note');\n\n if (!noteElement.length) {\n noteElement = $('<p class=\"note\"></p>').insertAfter(fieldElement.find('.tooltip'));\n }\n\n noteElement.html('<span>' + note + '</span>');\n });\n }\n }\n\n return function (config, element) {\n $(element).on('change', function (event) {\n reload(config.map, event.currentTarget.value);\n });\n reload(config.map, $(element).val());\n };\n});\n","Amasty_Rewards/js/validation/notification-days-mixin.js":"define([\n 'jquery',\n 'mage/translate'\n], function ($, $t) {\n 'use strict';\n\n var MAX_VALUES_LIMIT = 10;\n\n var validate = function (value) {\n if (value.split(';').length > 1 || value.match(/^\\s*(\\w\\s*){2,}$/)) {\n return $t('Use a comma-separated list.');\n }\n\n var days = value.split(',');\n\n if (days.length > MAX_VALUES_LIMIT) {\n return $t('Limited to %1 N values.').replace('%1', MAX_VALUES_LIMIT);\n }\n\n var invalidNumberMessage = $t('Please enter a number greater than 0 in this field.');\n for (var i = 0; i < days.length; i++) {\n var day = days[i].trim();\n\n if (!day.match(/^\\d+$/)) {\n return invalidNumberMessage;\n }\n\n day = parseInt(day);\n if (isNaN(day)) {\n return invalidNumberMessage;\n }\n\n if (day < 1) {\n return invalidNumberMessage;\n }\n }\n\n return null;\n };\n\n return function () {\n $.validator.addMethod(\n 'validate-notification-days',\n function (value) {\n return validate(value) === null;\n },\n function (value, element) {\n return validate($(element).val());\n }\n )\n }\n});\n","Magento_ConfigurableProduct/js/configurable-type-handler.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n 'jquery',\n 'Magento_Catalog/catalog/type-events',\n 'collapsible',\n 'Magento_Ui/js/modal/modal',\n 'mage/translate',\n 'domReady!'\n], function ($, productType) {\n 'use strict';\n\n return {\n $block: null,\n hasVariations: null,\n configurationSectionMessageHandler: (function () {\n var title = $('[data-role=\"product-create-configuration-info\"]'),\n buttons = $('[data-action=\"product-create-configuration-buttons\"]'),\n newText = 'Configurations cannot be created for a standard product with downloadable files.' +\n ' To create configurations, first remove all downloadable files.',\n oldText = title.text();\n\n return function (change) {\n if (change) {\n title.text(newText);\n buttons.hide();\n } else {\n title.text(oldText);\n buttons.show();\n }\n };\n }()),\n\n /**\n * Set element disabled\n * @param {Object} $element - jquery instance element\n * @param {Bool} state\n * @param {Bool} triggerEvent\n * @private\n */\n _setElementDisabled: function ($element, state, triggerEvent) {\n if (!$element.is('[data-locked]')) {\n $element.prop('disabled', state);\n\n if (triggerEvent) {\n $element.trigger('change');\n }\n }\n },\n\n /**\n * Show\n */\n show: function () {\n this.configurationSectionMessageHandler(false);\n },\n\n /**\n * Hide\n */\n hide: function () {\n this.configurationSectionMessageHandler(true);\n },\n\n /**\n * Bind all\n */\n bindAll: function () {\n $(document).on('changeConfigurableTypeProduct', function (event, isConfigurable) {\n $(document).trigger('setTypeProduct', isConfigurable ?\n 'configurable' :\n productType.type.init === 'configurable' ? 'simple' : productType.type.init\n );\n });\n $(document).on('changeTypeProduct', this._initType.bind(this));\n },\n\n /**\n * Init type\n * @private\n */\n _initType: function () {\n\n /*var suggestContainer = $('#product-template-suggest-container .action-dropdown > .action-toggle');\n\n\n if (productType.type.current === 'configurable') {\n this._setElementDisabled(suggestContainer.addClass('disabled'), true);\n this._setElementDisabled($('#inventory_qty'), true);\n this._setElementDisabled($('#inventory_stock_availability'), false);\n this._setElementDisabled($('#qty'), true, true);\n this._setElementDisabled($('#quantity_and_stock_status'), false, false);\n } else {\n this._setElementDisabled(suggestContainer.removeClass('disabled'), false);\n this._setElementDisabled($('#inventory_qty'), false);\n this._setElementDisabled($('#inventory_stock_availability'), true);\n this._setElementDisabled($('#qty'), false, true);\n }\n */\n\n /*if (['simple', 'virtual', 'configurable'].indexOf(productType.type.current) < 0) {\n this.hide();\n } else {\n this.show();\n }*/\n\n this.show();\n },\n\n /**\n * Constructor component\n * @param {Object} data - this backend data\n */\n 'Magento_ConfigurableProduct/js/configurable-type-handler': function (data) {\n this.$block = $(data.blockId + ' input[name=\"attributes[]\"]');\n this.hasVariations = data.hasVariations;\n\n //advancedPricingHandler.init();\n //priceTypeHandler.init();\n\n /*if (productType.type.init === 'configurable' && !this.hasVariations) {\n $(document).trigger('setTypeProduct', 'simple');\n }*/\n $(document).trigger('setTypeProduct', 'simple');\n\n this.bindAll();\n this._initType();\n }\n };\n});\n","Magento_ConfigurableProduct/js/configurable.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**************************** CONFIGURABLE PRODUCT **************************/\n/* global Product, optionsPrice */\ndefine([\n 'jquery',\n 'mage/template',\n 'mage/translate',\n 'prototype'\n], function (jQuery, mageTemplate) {\n 'use strict';\n\n if (typeof Product == 'undefined') {\n window.Product = {};\n }\n\n Product.Config = Class.create();\n Product.Config.prototype = {\n /**\n * Initialize function.\n *\n * @param {Object} config\n */\n initialize: function (config) {\n var separatorIndex, paramsStr, urlValues, i, childSettings, prevSetting, nextSetting;\n\n // Magic preprocessing\n // TODO MAGETWO-31539\n config.taxConfig = {\n showBothPrices: false,\n inclTaxTitle: jQuery.mage.__('Incl. Tax')\n };\n\n this.config = config;\n this.taxConfig = this.config.taxConfig;\n\n if (config.containerId) {\n this.settings = $$('#' + config.containerId + ' ' + '.super-attribute-select');\n } else {\n this.settings = $$('.super-attribute-select');\n }\n this.state = new Hash();\n this.priceTemplate = mageTemplate(this.config.template);\n this.prices = config.prices;\n this.values = {};\n\n // Set default values from config\n if (config.defaultValues) {\n this.values = config.defaultValues;\n }\n\n // Overwrite defaults by url\n separatorIndex = window.location.href.indexOf('#');\n\n if (separatorIndex != -1) { //eslint-disable-line eqeqeq\n paramsStr = window.location.href.substr(separatorIndex + 1);\n urlValues = paramsStr.toQueryParams();\n\n for (i in urlValues) { //eslint-disable-line guard-for-in\n this.values[i] = urlValues[i];\n }\n }\n\n // Overwrite defaults by inputs values if needed\n if (config.inputsInitialized) {\n this.values = {};\n this.settings.each(function (element) {\n var attributeId;\n\n if (element.value) {\n attributeId = element.id.replace(/[a-z]*/, '');\n this.values[attributeId] = element.value;\n }\n }.bind(this));\n }\n\n // Put events to check select reloads\n this.settings.each(function (element) {\n Event.observe(element, 'change', this.configure.bind(this));\n }.bind(this));\n\n // fill state\n this.settings.each(function (element) {\n var attributeId = element.id.replace(/[a-z]*/, '');\n\n if (attributeId && this.config.attributes[attributeId]) {\n element.config = this.config.attributes[attributeId];\n element.attributeId = attributeId;\n this.state[attributeId] = false;\n }\n }.bind(this));\n\n // Init settings dropdown\n childSettings = [];\n\n for (i = this.settings.length - 1; i >= 0; i--) {\n prevSetting = this.settings[i - 1] ? this.settings[i - 1] : false;\n nextSetting = this.settings[i + 1] ? this.settings[i + 1] : false;\n\n if (i === 0) {\n this.fillSelect(this.settings[i]);\n } else {\n this.settings[i].disabled = true;\n }\n $(this.settings[i]).childSettings = childSettings.clone();\n $(this.settings[i]).prevSetting = prevSetting;\n $(this.settings[i]).nextSetting = nextSetting;\n childSettings.push(this.settings[i]);\n }\n\n // Set values to inputs\n this.configureForValues();\n document.observe('dom:loaded', this.configureForValues.bind(this));\n },\n\n /**\n * Configure for values.\n */\n configureForValues: function () {\n if (this.values) {\n this.settings.each(function (element) {\n var attributeId = element.attributeId;\n\n element.value = typeof this.values[attributeId] === 'undefined' ? '' : this.values[attributeId];\n this.configureElement(element);\n }.bind(this));\n }\n },\n\n /**\n * @param {Object} event\n */\n configure: function (event) {\n var element = Event.element(event);\n\n this.configureElement(element);\n },\n\n /**\n * @param {Object} element\n */\n configureElement: function (element) {\n this.reloadOptionLabels(element);\n\n if (element.value) {\n this.state[element.config.id] = element.value;\n\n if (element.nextSetting) {\n element.nextSetting.disabled = false;\n this.fillSelect(element.nextSetting);\n this.resetChildren(element.nextSetting);\n }\n } else {\n this.resetChildren(element);\n }\n this.reloadPrice();\n },\n\n /**\n * @param {Object} element\n */\n reloadOptionLabels: function (element) {\n var selectedPrice = 0,\n option, i;\n\n if (element.options[element.selectedIndex] && element.options[element.selectedIndex].config) {\n option = element.options[element.selectedIndex].config;\n selectedPrice = parseFloat(this.config.optionPrices[option.allowedProducts[0]].finalPrice.amount);\n }\n element.setAttribute('price', selectedPrice);\n\n for (i = 0; i < element.options.length; i++) {\n if (element.options[i].config) {\n element.options[i].setAttribute('price', selectedPrice);\n element.options[i].setAttribute('summarizePrice', 0);\n element.options[i].text = this.getOptionLabel(element.options[i].config, selectedPrice);\n }\n }\n },\n\n /* eslint-disable max-depth */\n /**\n * @param {Object} element\n */\n resetChildren: function (element) {\n var i;\n\n if (element.childSettings) {\n for (i = 0; i < element.childSettings.length; i++) {\n element.childSettings[i].selectedIndex = 0;\n element.childSettings[i].disabled = true;\n\n if (element.config) {\n this.state[element.config.id] = false;\n }\n }\n }\n },\n\n /**\n * @param {Object} element\n */\n fillSelect: function (element) {\n var attributeId = element.id.replace(/[a-z]*/, ''),\n options = this.getAttributeOptions(attributeId),\n prevConfig = false,\n index = 1,\n i, j, allowedProducts;\n\n this.clearSelect(element);\n element.options[0] = new Option('', '');\n element.options[0].innerHTML = this.config.chooseText;\n\n if (element.prevSetting) {\n prevConfig = element.prevSetting.options[element.prevSetting.selectedIndex];\n }\n\n if (options) {\n for (i = 0; i < options.length; i++) {\n allowedProducts = [];\n\n if (prevConfig) {\n for (j = 0; j < options[i].products.length; j++) {\n if (prevConfig.config.allowedProducts &&\n prevConfig.config.allowedProducts.indexOf(options[i].products[j]) > -1\n ) {\n allowedProducts.push(options[i].products[j]);\n }\n }\n } else {\n allowedProducts = options[i].products.clone();\n }\n\n if (allowedProducts.size() > 0) {\n options[i].allowedProducts = allowedProducts;\n element.options[index] = new Option(this.getOptionLabel(options[i]), options[i].id);\n\n if (typeof options[i].price != 'undefined') {\n element.options[index].setAttribute('price', options[i].price);\n }\n element.options[index].config = options[i];\n index++;\n }\n }\n }\n },\n\n //eslint-enable max-depth\n /**\n * @param {Object} option\n */\n getOptionLabel: function (option) {\n return option.label;\n },\n\n /**\n * @param {*} price\n * @param {Boolean} showSign\n * @return {String}\n */\n formatPrice: function (price, showSign) {\n var str = '',\n roundedPrice;\n\n price = parseFloat(price);\n\n if (showSign) {\n if (price < 0) {\n str += '-';\n price = -price;\n } else {\n str += '+';\n }\n }\n\n roundedPrice = Number(Math.round(price + 'e+2') + 'e-2').toString();\n\n if (this.prices && this.prices[roundedPrice]) {\n str += this.prices[roundedPrice];\n } else {\n str += this.priceTemplate({\n data: {\n price: price.toFixed(2)\n }\n });\n }\n\n return str;\n },\n\n /**\n * @param {Object} element\n */\n clearSelect: function (element) {\n var i;\n\n for (i = element.options.length - 1; i >= 0; i--) {\n element.remove(i);\n }\n },\n\n /**\n * @param {*} attributeId\n * @return {*|undefined}\n */\n getAttributeOptions: function (attributeId) {\n if (this.config.attributes[attributeId]) {\n return this.config.attributes[attributeId].options;\n }\n },\n\n /**\n * Reload price.\n *\n * @return {undefined|Number}\n */\n reloadPrice: function () {\n var price = 0,\n oldPrice = 0,\n inclTaxPrice = 0,\n exclTaxPrice = 0,\n i, selected;\n\n if (this.config.disablePriceReload) {\n return undefined;\n }\n\n for (i = this.settings.length - 1; i >= 0; i--) {\n selected = this.settings[i].options[this.settings[i].selectedIndex];\n\n if (selected.config) {\n price += parseFloat(selected.config.price);\n oldPrice += parseFloat(selected.config.oldPrice);\n inclTaxPrice += parseFloat(selected.config.inclTaxPrice);\n exclTaxPrice += parseFloat(selected.config.exclTaxPrice);\n }\n }\n\n optionsPrice.changePrice(\n 'config', {\n 'price': price,\n 'oldPrice': oldPrice,\n 'inclTaxPrice': inclTaxPrice,\n 'exclTaxPrice': exclTaxPrice\n }\n );\n optionsPrice.reload();\n\n return price;\n },\n\n /**\n * Reload old price.\n */\n reloadOldPrice: function () {\n var price, i, selected;\n\n if (this.config.disablePriceReload) {\n return;\n }\n\n if ($('old-price-' + this.config.productId)) {\n\n price = parseFloat(this.config.oldPrice);\n\n for (i = this.settings.length - 1; i >= 0; i--) {\n selected = this.settings[i].options[this.settings[i].selectedIndex];\n\n if (selected.config) {\n price += parseFloat(selected.config.price);\n }\n }\n\n if (price < 0) {\n price = 0;\n }\n price = this.formatPrice(price);\n\n if ($('old-price-' + this.config.productId)) {\n $('old-price-' + this.config.productId).innerHTML = price;\n }\n\n }\n }\n };\n});\n","Magento_ConfigurableProduct/js/variations/product-grid.js":"// jscs:disable requireDotNotation\n/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'uiComponent',\n 'jquery',\n 'Magento_Ui/js/core/app',\n 'underscore',\n 'notification',\n 'mage/translate'\n], function (Component, $, bootstrap, _) {\n 'use strict';\n\n return Component.extend({\n defaults: {\n productsGridUrl: null,\n productAttributes: [],\n productsModal: null,\n button: '',\n gridSelector: '[data-grid-id=associated-products-container]',\n modules: {\n productsFilter: '${ $.productsFilter }',\n productsProvider: '${ $.productsProvider }',\n productsMassAction: '${ $.productsMassAction }',\n productsColumns: '${ $.productsColumns }',\n variationsComponent: '${ $.configurableVariations }'\n },\n listens: {\n '${ $.productsProvider }:data': '_showMessageAssociatedGrid _handleManualGridOpening',\n '${ $.productsMassAction }:selected': '_handleManualGridSelect',\n '${ $.configurableVariations }:productMatrix': '_showButtonAddManual _switchProductType'\n }\n },\n\n /**\n * Initialize\n *\n * @param {Array} options\n */\n initialize: function (options) {\n this._super(options);\n this.productsModal = $(this.gridSelector).modal({\n title: $.mage.__('Select Associated Product'),\n type: 'slide',\n buttons: [\n {\n text: $.mage.__('Cancel'),\n\n /** Close modal */\n click: function () {\n this.closeModal();\n }\n }, {\n text: $.mage.__('Done'),\n click: this.close.bind(this, null)\n }\n ]\n });\n\n this.productsProvider(function () {\n this.productsModal.notification();\n }.bind(this));\n this.variationsComponent(function (variation) {\n this._showButtonAddManual(variation.productMatrix());\n }.bind(this));\n\n this._initGrid = _.once(this._initGrid);\n this._switchProductType = _.wrap(this._switchProductType.bind(this), function (func, params) {\n if (!!params.length !== !!this.init) {\n this.init = !!params.length;\n func(params);\n }\n }.bind(this._switchProductType));\n },\n\n /**\n * Initial observerable\n * @returns {*}\n */\n initObservable: function () {\n this._super().observe('button');\n\n return this;\n },\n\n /**\n * init Grid\n * @private\n */\n _initGrid: function (filterData) {\n $.ajax({\n type: 'GET',\n url: this._buildGridUrl(filterData),\n context: $('body')\n }).done(function (data) {\n bootstrap(JSON.parse(data));\n });\n },\n\n /**\n * Select different product in configurations section\n * @see configurable_associated_product_listing.xml\n * @param {Integer} rowIndex\n */\n selectProduct: function (rowIndex) {\n this.close(rowIndex);\n },\n\n /**\n * Open\n * @param {Object} filterData - filter data\n * @param {Object|*} filterData.filters - attribute name\n * @param {Object|*} filterData.filters_modifier - modifier value\n * @param {String} callbackName\n * @param {Boolean} showMassActionColumn\n */\n open: function (filterData, callbackName, showMassActionColumn) {\n this.callbackName = callbackName;\n this.productsMassAction(function (massActionComponent) {\n this.productsColumns().elems().each(function (rowElement) {\n rowElement.disableAction = showMassActionColumn;\n });\n massActionComponent.visible = showMassActionColumn;\n }.bind(this));\n this._setFilter(filterData);\n this._initGrid(filterData);\n this.productsModal.trigger('openModal');\n },\n\n /**\n * Close\n */\n close: function (rowIndex) {\n try {\n if (this.productsMassAction().selected.getLength()) {\n this.variationsComponent()[this.callbackName](this.productsMassAction()\n .selected.map(this.getProductById.bind(this)));\n this.productsMassAction().deselectAll();\n } else if (!_.isNull(rowIndex)) {\n this.variationsComponent()[this.callbackName]([this.getProductByIndex(rowIndex)]);\n }\n this.productsModal.trigger('closeModal');\n } catch (e) {\n if (e.name === 'UserException') {\n this.productsModal.notification('clear');\n this.productsModal.notification('add', {\n message: e.message,\n messageContainer: this.gridSelector\n });\n } else {\n throw e;\n }\n }\n },\n\n /**\n * Get product by id\n * @param {Integer} productId\n * @returns {*}\n */\n getProductById: function (productId) {\n return _.findWhere(this.productsProvider().data.items, {\n 'entity_id': productId\n });\n },\n\n /**\n * Get product\n * @param {Integer} rowIndex\n * @returns {*}\n */\n getProductByIndex: function (rowIndex) {\n return this.productsProvider().data.items[rowIndex];\n },\n\n /**\n * Build grid url\n * @private\n */\n _buildGridUrl: function (filterData) {\n var params = '?' + $.param({\n 'filters': filterData.filters,\n 'attributes_codes': this._getAttributesCodes(),\n 'filters_modifier': filterData['filters_modifier']\n });\n\n return this.productsGridUrl + params;\n },\n\n /**\n * Show button add manual\n * @param {Array} variations\n * @returns {*}\n * @private\n */\n _showButtonAddManual: function (variations) {\n return this.button(variations.length);\n },\n\n /**\n * @param {Array} variations\n * @private\n */\n _switchProductType: function (variations) {\n $(document).trigger('changeConfigurableTypeProduct', variations.length);\n },\n\n /**\n * Get attributes codes used for configurable\n * @private\n */\n _getAttributesCodes: function () {\n return this.variationsComponent().attributes.pluck('code');\n },\n\n /**\n * Show data associated grid\n * @private\n */\n _showMessageAssociatedGrid: function (data) {\n this.productsModal.notification('clear');\n\n if (data.items.length) {\n this.productsModal.notification('add', {\n message: $.mage.__('Choose a new product to delete and replace the current product configuration.'),\n messageContainer: this.gridSelector\n });\n } else {\n this.productsModal.notification('add', {\n message: $.mage.__('For better results, add attributes and attribute values to your products.'),\n messageContainer: this.gridSelector\n });\n }\n },\n\n /**\n * Show manually grid\n */\n showManuallyGrid: function () {\n var filterModifier = _.mapObject(_.object(this._getAttributesCodes(), []), function () {\n return {\n 'condition_type': 'notnull'\n };\n }),\n usedProductIds = _.values(this.variationsComponent().productAttributesMap);\n\n if (usedProductIds && usedProductIds.length > 0) {\n filterModifier['entity_id'] = {\n 'condition_type': 'nin', value: usedProductIds\n };\n }\n\n this.open(\n {\n 'filters_modifier': filterModifier\n },\n 'appendProducts',\n true\n );\n },\n\n /**\n * Handle manual grid after opening\n * @private\n */\n _handleManualGridOpening: function (data) {\n if (data.items.length && this.callbackName == 'appendProducts') { //eslint-disable-line eqeqeq\n this.productsColumns().elems().each(function (rowElement) {\n rowElement.disableAction = true;\n });\n\n this._disableRows(data.items);\n }\n },\n\n /**\n * Disable rows in grid for products with the same variation key\n *\n * @param {Array} items\n * @param {Array} selectedVariationKeys\n * @param {Array} selected\n * @private\n */\n _disableRows: function (items, selectedVariationKeys, selected) {\n selectedVariationKeys = selectedVariationKeys === undefined ? [] : selectedVariationKeys;\n selected = selected === undefined ? [] : selected;\n this.productsMassAction(function (massaction) {\n var configurableVariationKeys = _.union(\n selectedVariationKeys,\n _.pluck(this.variationsComponent().productMatrix(), 'variationKey')\n ),\n variationKeyMap = this._getVariationKeyMap(items),\n rowsForDisable = _.keys(_.pick(\n variationKeyMap,\n function (variationKey) {\n return configurableVariationKeys.indexOf(variationKey) !== -1;\n }\n ));\n\n massaction.disabled(_.difference(rowsForDisable, selected));\n }.bind(this));\n },\n\n /**\n * @private\n */\n _handleManualGridSelect: function (selected) {\n var selectedRows, selectedVariationKeys;\n\n if (this.callbackName == 'appendProducts') { //eslint-disable-line eqeqeq\n selectedRows = _.filter(this.productsProvider().data.items, function (row) {\n return selected.indexOf(row['entity_id']) !== -1;\n });\n selectedVariationKeys = _.values(this._getVariationKeyMap(selectedRows));\n this._disableRows(this.productsProvider().data.items, selectedVariationKeys, selected);\n }\n },\n\n /**\n * Get variation key map used in manual grid.\n *\n * @param {Object} items\n * @returns {Array} [{entity_id: variation-key}, ...]\n * @private\n */\n _getVariationKeyMap: function (items) {\n this._variationKeyMap = {};\n\n _.each(items, function (row) {\n this._variationKeyMap[row['entity_id']] = _.values(\n _.pick(row, this._getAttributesCodes())\n ).sort().join('-');\n\n }, this);\n\n return this._variationKeyMap;\n },\n\n /**\n * Set filter\n * @private\n */\n _setFilter: function (filterData) {\n this.productsProvider(function (provider) {\n provider.params['filters_modifier'] = filterData['filters_modifier'];\n provider.params['attributes_codes'] = this._getAttributesCodes();\n }.bind(this));\n\n this.productsFilter(function (filter) {\n filter.set('filters', _.extend({\n 'filters_modifier': filterData['filters_modifier']\n }, filterData.filters))\n .apply();\n });\n }\n });\n});\n","Magento_ConfigurableProduct/js/variations/variations.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'uiComponent',\n 'jquery',\n 'ko',\n 'underscore',\n 'Magento_Ui/js/modal/alert',\n 'uiRegistry',\n 'mage/translate'\n], function (Component, $, ko, _, alert, registry, $t) {\n 'use strict';\n\n /**\n * @param {*} message\n * @constructor\n */\n function UserException(message) {\n this.message = message;\n this.name = 'UserException';\n }\n UserException.prototype = Object.create(Error.prototype);\n\n return Component.extend({\n defaults: {\n opened: false,\n attributes: [],\n usedAttributes: [],\n attributeCodes: [],\n attributesData: {},\n productMatrix: [],\n variations: [],\n formSaveParams: [],\n productAttributes: [],\n disabledAttributes: [],\n fullAttributes: [],\n rowIndexToEdit: false,\n productAttributesMap: null,\n value: [],\n modules: {\n associatedProductGrid: '${ $.configurableProductGrid }',\n wizardButtonElement: '${ $.wizardModalButtonName }',\n formElement: '${ $.formName }',\n attributeSetHandlerModal: '${ $.attributeSetHandler }'\n },\n imports: {\n attributeSetName: '${ $.provider }:configurableNewAttributeSetName',\n attributeSetId: '${ $.provider }:configurableExistingAttributeSetId',\n attributeSetSelection: '${ $.provider }:configurableAffectedAttributeSet',\n productPrice: '${ $.provider }:data.product.price'\n },\n links: {\n value: '${ $.provider }:${ $.dataScopeVariations }',\n usedAttributes: '${ $.provider }:${ $.dataScopeAttributes }',\n attributesData: '${ $.provider }:${ $.dataScopeAttributesData }',\n attributeCodes: '${ $.provider }:${ $.dataScopeAttributeCodes }',\n skeletonAttributeSet: '${ $.provider }:data.new-variations-attribute-set-id'\n }\n },\n\n /** @inheritdoc */\n initialize: function () {\n this._super();\n\n this.changeButtonWizard();\n this.initProductAttributesMap();\n this.disableConfigurableAttributes(this.productAttributes);\n },\n\n /** @inheritdoc */\n initObservable: function () {\n this._super().observe(\n 'actions opened attributes productMatrix value usedAttributes attributesData attributeCodes'\n );\n\n return this;\n },\n\n /**\n * @param {Object} product\n * @return {Object}\n * @private\n */\n _makeProduct: function (product) {\n var productId = product['entity_id'] || product.productId || null,\n attributes = _.pick(product, this.attributes.pluck('code')),\n options = _.map(attributes, function (option, attribute) {\n var oldOptions = _.findWhere(this.attributes(), {\n code: attribute\n }).options,\n result;\n\n if (_.isFunction(oldOptions)) {\n result = oldOptions.findWhere({\n value: option\n });\n } else {\n result = _.findWhere(oldOptions, {\n value: option\n });\n }\n\n return result;\n }.bind(this));\n\n return {\n attribute: JSON.stringify(attributes),\n editable: false,\n images: {\n preview: product['thumbnail_src']\n },\n name: product.name || product.sku,\n options: options,\n price: parseFloat(Math.round(product.price.replace(/[^\\d.]+/g, '') + 'e+4') + 'e-4').toFixed(4),\n productId: productId,\n productUrl: this.buildProductUrl(productId),\n quantity: product.quantity || null,\n sku: product.sku,\n status: product.status === undefined ? 1 : parseInt(product.status, 10),\n variationKey: this.getVariationKey(options),\n weight: product.weight || null\n };\n },\n\n /**\n * @param {String} name\n * @return {String|Number|Array}\n */\n getProductValue: function (name) {\n var value;\n\n name = name.split('/').join('][');\n value = $('[name=\"product[' + name + ']\"]:enabled:not(.ignore-validate)', this.productForm).val();\n if (value === undefined) {\n value = this.source.get('data.product.' + name);\n }\n return value;\n },\n\n /**\n * @param {Object} data\n * @param {String} field\n * @return {String}\n */\n getRowId: function (data, field) {\n var key = data.variationKey;\n\n return 'variations-matrix-' + key + '-' + field;\n },\n\n /**\n * @param {Object} variation\n * @param {String} field\n * @return {String}\n */\n getVariationRowName: function (variation, field) {\n var result;\n\n if (variation.productId) {\n result = 'configurations[' + variation.productId + '][' + field.split('/').join('][') + ']';\n } else {\n result = 'variations-matrix[' + variation.variationKey + '][' + field.split('/').join('][') + ']';\n }\n\n return result;\n },\n\n /**\n * @param {*} variations\n * @param {*} attributes\n */\n render: function (variations, attributes) {\n this.changeButtonWizard();\n this.populateVariationMatrix(variations);\n this.attributes(attributes);\n this.disableConfigurableAttributes(attributes);\n this.handleValue(variations);\n this.handleAttributes();\n },\n\n /**\n * Change button wizard.\n */\n changeButtonWizard: function () {\n if (this.variations.length) {\n this.wizardButtonElement().title(this.wizardModalButtonTitle);\n }\n },\n\n /**\n * @param {Array} variations\n */\n handleValue: function (variations) {\n var tmpArray = [];\n\n _.each(variations, function (variation) {\n var attributes = _.reduce(variation.options, function (memo, option) {\n var attribute = {};\n\n attribute[option['attribute_code']] = option.value;\n\n return _.extend(memo, attribute);\n }, {}),\n gallery = {\n images: {}\n },\n types = {};\n\n _.each(variation.images.images, function (image) {\n gallery.images[image['file_id']] = {\n position: image.position,\n file: image.file,\n disabled: image.disabled,\n label: image.label || ''\n };\n _.each(image.galleryTypes, function (type) {\n types[type] = image.file;\n });\n }, this);\n\n tmpArray.push(_.extend(variation, types, {\n productId: variation.productId || null,\n name: variation.name || variation.sku,\n priceCurrency: this.currencySymbol,\n weight: variation.weight,\n attribute: JSON.stringify(attributes),\n variationKey: this.getVariationKey(variation.options),\n editable: variation.editable === undefined ? 0 : 1,\n productUrl: this.buildProductUrl(variation.productId),\n status: variation.status === undefined ? 1 : parseInt(variation.status, 10),\n newProduct: variation.productId ? 0 : 1,\n 'media_gallery': gallery\n }));\n }, this);\n\n this.value(tmpArray);\n },\n\n /**\n * Handle attributes.\n */\n handleAttributes: function () {\n var tmpArray = [],\n codesArray = [],\n tmpOptions = {},\n option = {},\n position = 0,\n values = {};\n\n _.each(this.attributes(), function (attribute) {\n tmpArray.push(attribute.id);\n codesArray.push(attribute.code);\n values = {};\n _.each(attribute.chosen, function (row) {\n values[row.value] = {\n 'include': '1',\n 'value_index': row.value\n };\n }, this);\n option = {\n 'attribute_id': attribute.id,\n 'code': attribute.code,\n 'label': attribute.label,\n 'position': position,\n 'values': values\n };\n tmpOptions[attribute.id] = option;\n position++;\n }, this);\n\n this.attributesData(tmpOptions);\n this.usedAttributes(tmpArray);\n this.attributeCodes(codesArray);\n },\n\n /**\n * Get attributes options\n * @see use in matrix.phtml\n *\n * @returns {Array}\n */\n getAttributesOptions: function () {\n return this.showVariations() ? this.productMatrix()[0].options : [];\n },\n\n /**\n * @return {Boolean}\n */\n showVariations: function () {\n return this.productMatrix().length > 0;\n },\n\n /**\n * @param {Array} variations\n */\n populateVariationMatrix: function (variations) {\n this.productMatrix([]);\n _.each(variations, function (variation) {\n var attributes = _.reduce(variation.options, function (memo, option) {\n var attribute = {};\n\n attribute[option['attribute_code']] = option.value;\n\n return _.extend(memo, attribute);\n }, {});\n\n this.productMatrix.push(_.extend(variation, {\n productId: variation.productId || null,\n name: variation.name || variation.sku,\n weight: variation.weight,\n attribute: JSON.stringify(attributes),\n variationKey: this.getVariationKey(variation.options),\n editable: variation.editable === undefined ? !variation.productId : variation.editable,\n productUrl: this.buildProductUrl(variation.productId),\n status: variation.status === undefined ? 1 : parseInt(variation.status, 10)\n }));\n }, this);\n },\n\n /**\n * @param {*} productId\n */\n buildProductUrl: function (productId) {\n return this.productUrl.replace('%id%', productId);\n },\n\n /**\n * @param {Object} options\n * @return {String}\n */\n getVariationKey: function (options) {\n return _.pluck(options, 'value').sort().join('-');\n },\n\n /**\n * @param {*} options\n * @return {*|null}\n */\n getProductIdByOptions: function (options) {\n return this.productAttributesMap[this.getVariationKey(options)] || null;\n },\n\n /**\n * Init product attributes map\n */\n initProductAttributesMap: function () {\n if (this.productAttributesMap === null) {\n this.productAttributesMap = {};\n _.each(this.variations, function (product) {\n this.productAttributesMap[this.getVariationKey(product.options)] = product.productId;\n }.bind(this));\n }\n },\n\n /**\n * @param {Array} attributes\n */\n disableConfigurableAttributes: function (attributes) {\n var element;\n\n _.each(this.disabledAttributes, function (attribute) {\n registry.get('inputName = ' + 'product[' + attribute + ']').disabled(false);\n });\n this.disabledAttributes = [];\n\n _.each(attributes, function (attribute) {\n element = registry.get('inputName = ' + 'product[' + attribute.code + ']');\n\n if (!_.isUndefined(element)) {\n element.disabled(true);\n this.disabledAttributes.push(attribute.code);\n }\n }, this);\n },\n\n /**\n * Get currency symbol\n * @returns {String}\n */\n getCurrencySymbol: function () {\n return this.currencySymbol;\n },\n\n /**\n * Chose action for the form save button\n */\n saveFormHandler: function () {\n this.formElement().validate();\n\n if (this.formElement().source.get('params.invalid') === false) {\n this.serializeData();\n }\n\n if (this.checkForNewAttributes()) {\n this.formSaveParams = arguments;\n this.attributeSetHandlerModal().openModal();\n } else {\n if (this.validateForm(this.formElement())) {\n this.clearOutdatedData();\n }\n this.formElement().save(arguments[0], arguments[1]);\n\n if (this.formElement().source.get('params.invalid')) {\n this.unserializeData();\n }\n }\n },\n\n /**\n * @param {Object} formElement\n *\n * Validates each form element and returns true, if all elements are valid.\n */\n validateForm: function (formElement) {\n formElement.validate();\n\n return !formElement.additionalInvalid && !formElement.source.get('params.invalid');\n },\n\n /**\n * Serialize data for specific form fields\n *\n * Serializes some complex data fields\n *\n * Original fields:\n * - configurable-matrix;\n * - associated_product_ids.\n *\n * Serialized fields in request:\n * - configurable-matrix-serialized;\n * - associated_product_ids_serialized.\n */\n serializeData: function () {\n if (this.source.data['configurable-matrix']) {\n this.source.data['configurable-matrix-serialized'] =\n JSON.stringify(this.source.data['configurable-matrix']);\n }\n\n if (this.source.data['associated_product_ids']) {\n this.source.data['associated_product_ids_serialized'] =\n JSON.stringify(this.source.data['associated_product_ids']);\n }\n },\n\n /**\n * Clear outdated data for specific form fields\n *\n * Outdated fields:\n * - configurable-matrix;\n * - associated_product_ids.\n */\n clearOutdatedData: function () {\n if (this.source.data['configurable-matrix']) {\n delete this.source.data['configurable-matrix'];\n }\n\n if (this.source.data['associated_product_ids']) {\n delete this.source.data['associated_product_ids'];\n }\n },\n\n /**\n * Unserialize data for specific form fields\n *\n * Unserializes some fields that were serialized this.serializeData\n */\n unserializeData: function () {\n if (this.source.data['configurable-matrix-serialized']) {\n this.source.data['configurable-matrix'] =\n JSON.parse(this.source.data['configurable-matrix-serialized']);\n delete this.source.data['configurable-matrix-serialized'];\n }\n\n if (this.source.data['associated_product_ids_serialized']) {\n this.source.data['associated_product_ids'] =\n JSON.parse(this.source.data['associated_product_ids_serialized']);\n delete this.source.data['associated_product_ids_serialized'];\n }\n },\n\n /**\n * Check for newly added attributes\n * @returns {Boolean}\n */\n checkForNewAttributes: function () {\n var element, newAttributes = false;\n\n _.each(this.source.get('data.attribute_codes'), function (attribute) {\n element = registry.get('index = ' + attribute);\n\n if (_.isUndefined(element)) {\n newAttributes = true;\n }\n }, this);\n\n return newAttributes;\n },\n\n /**\n * New attributes handler\n * @returns {Boolean}\n */\n addNewAttributeSetHandler: function () {\n var chosenAttributeSetOption;\n\n this.formElement().validate();\n\n if (this.formElement().source.get('params.invalid') === false) {\n chosenAttributeSetOption = this.attributeSetSelection;\n\n if (chosenAttributeSetOption === 'new') {\n this.createNewAttributeSet();\n\n return false;\n }\n\n if (chosenAttributeSetOption === 'existing') {\n this.set(\n 'skeletonAttributeSet',\n this.attributeSetId\n );\n }\n\n this.closeDialogAndProcessForm();\n\n return true;\n }\n\n this.unserializeData();\n\n return false;\n },\n\n /**\n * Handles new attribute set creation\n * @returns {Boolean}\n */\n createNewAttributeSet: function () {\n var messageBoxElement = registry.get('index = affectedAttributeSetError');\n\n messageBoxElement.visible(false);\n\n $.ajax({\n type: 'POST',\n url: this.attributeSetCreationUrl,\n data: {\n gotoEdit: 1,\n 'attribute_set_name': this.attributeSetName,\n 'skeleton_set': this.skeletonAttributeSet,\n 'return_session_messages_only': 1\n },\n dataType: 'json',\n showLoader: true,\n context: this\n }).done(function (data) {\n if (!data.error) {\n this.set(\n 'skeletonAttributeSet',\n data.id\n );\n messageBoxElement.content(data.messages);\n messageBoxElement.visible(true);\n this.closeDialogAndProcessForm();\n } else {\n messageBoxElement.content(data.messages);\n messageBoxElement.visible(true);\n }\n\n return false;\n }).fail(function (xhr) {\n if (xhr.statusText === 'abort') {\n return;\n }\n\n alert({\n content: $t('Something went wrong.')\n });\n });\n\n return false;\n },\n\n /**\n * Closes attribute set handler modal and process product form\n */\n closeDialogAndProcessForm: function () {\n this.attributeSetHandlerModal().closeModal();\n this.formElement().save(this.formSaveParams[0], this.formSaveParams[1]);\n },\n\n /**\n * Retrieves product price\n * @returns {*}\n */\n getProductPrice: function () {\n return this.productPrice;\n }\n });\n});\n","Magento_ConfigurableProduct/js/variations/paging/sizes.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n 'Magento_Ui/js/grid/paging/sizes'\n], function (Sizes) {\n 'use strict';\n\n return Sizes.extend({\n defaults: {\n options: {\n '20': {\n value: 20,\n label: 20\n },\n '30': {\n value: 30,\n label: 30\n },\n '50': {\n value: 50,\n label: 50\n }\n },\n value: 20\n }\n });\n});\n","Magento_ConfigurableProduct/js/variations/steps/summary.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'uiComponent',\n 'jquery',\n 'ko',\n 'underscore',\n 'Magento_Ui/js/grid/paging/paging',\n 'mage/translate'\n], function (Component, $, ko, _, paging) {\n 'use strict';\n\n return Component.extend({\n defaults: {\n modules: {\n variationsComponent: '${ $.variationsComponent }',\n modalComponent: '${ $.modalComponent }',\n matrixGridComponent: '${ $.matrixGridComponent }'\n },\n notificationMessage: {\n text: null,\n error: null\n },\n gridExisting: [],\n gridNew: [],\n gridDeleted: [],\n variationsExisting: [],\n variationsNew: [],\n variationsDeleted: [],\n pagingExisting: paging({\n name: 'configurableWizard.pagingExisting',\n sizesConfig: {\n component: 'Magento_ConfigurableProduct/js/variations/paging/sizes',\n name: 'configurableWizard.pagingExisting_sizes'\n }\n }),\n pagingNew: paging({\n name: 'configurableWizard.pagingNew',\n sizesConfig: {\n component: 'Magento_ConfigurableProduct/js/variations/paging/sizes',\n name: 'configurableWizard.pagingNew_sizes'\n }\n }),\n pagingDeleted: paging({\n name: 'configurableWizard.pagingDeleted',\n sizesConfig: {\n component: 'Magento_ConfigurableProduct/js/variations/paging/sizes',\n name: 'configurableWizard.pagingDeleted_sizes'\n }\n }),\n attributes: [],\n attributesName: [$.mage.__('Images'), $.mage.__('SKU'), $.mage.__('Quantity'), $.mage.__('Price')],\n sections: [],\n gridTemplate: 'Magento_ConfigurableProduct/variations/steps/summary-grid',\n quantityFieldName: 'quantity'\n },\n\n /** @inheritdoc */\n initObservable: function () {\n var pagingObservables = {\n currentNew: ko.getObservable(this.pagingNew, 'current'),\n currentExisting: ko.getObservable(this.pagingExisting, 'current'),\n currentDeleted: ko.getObservable(this.pagingDeleted, 'current'),\n pageSizeNew: ko.getObservable(this.pagingNew, 'pageSize'),\n pageSizeExisting: ko.getObservable(this.pagingExisting, 'pageSize'),\n pageSizeDeleted: ko.getObservable(this.pagingDeleted, 'pageSize')\n };\n\n this._super().observe('gridExisting gridNew gridDeleted attributes sections');\n this.gridExisting.columns = ko.observableArray();\n this.gridNew.columns = ko.observableArray();\n this.gridDeleted.columns = ko.observableArray();\n\n _.each(pagingObservables, function (observable) {\n observable.subscribe(function () {\n this.generateGrid();\n }, this);\n }, this);\n\n return this;\n },\n nextLabelText: $.mage.__('Generate Products'),\n variations: [],\n\n /**\n * @param {*} variations\n * @param {Function} getSectionValue\n */\n calculate: function (variations, getSectionValue) {\n var productSku = this.variationsComponent().getProductValue('sku'),\n productPrice = this.variationsComponent().getProductPrice(),\n productWeight = this.variationsComponent().getProductValue('weight'),\n productName = this.variationsComponent().getProductValue('name'),\n variationsKeys = [],\n gridExisting = [],\n gridNew = [],\n gridDeleted = [],\n matrixGridData = this.matrixGridComponent() ?\n _.indexBy(this.matrixGridComponent().getUnionInsertData(), 'variationKey') : {};\n\n this.variations = [];\n _.each(variations, function (options) {\n var product, images, sku, name, quantity, price, variation,\n variationsKey = this.variationsComponent().getVariationKey(options),\n productDataFromGrid = matrixGridData[variationsKey] || {},\n productDataFromWizard = {},\n productId = this.variationsComponent().getProductIdByOptions(options);\n\n if (productId) {\n product = _.findWhere(this.variationsComponent().variations, {\n productId: productId\n });\n }\n images = getSectionValue('images', options);\n sku = productSku + _.reduce(options, function (memo, option) {\n return memo + '-' + option.label;\n }, '');\n name = productName + _.reduce(options, function (memo, option) {\n return memo + '-' + option.label;\n }, '');\n quantity = getSectionValue(this.quantityFieldName, options);\n\n if (quantity) {\n productDataFromWizard[this.quantityFieldName] = quantity;\n }\n price = getSectionValue('price', options);\n\n if (price) {\n productDataFromWizard.price = price;\n }\n\n if (productId && !images.file) {\n images = product.images;\n }\n productDataFromGrid = this.prepareProductDataFromGrid(productDataFromGrid);\n\n product = _.pick(\n product || {},\n 'sku',\n 'name',\n 'weight',\n 'status',\n 'price',\n this.quantityFieldName\n );\n variation = {\n options: options,\n images: images,\n sku: sku,\n name: name,\n price: productPrice,\n productId: productId,\n weight: productWeight,\n editable: true\n };\n variation[this.quantityFieldName] = quantity;\n variation = _.extend(variation, product, productDataFromGrid, productDataFromWizard);\n\n if (productId) {\n gridExisting.push(this.prepareRowForGrid(variation));\n } else {\n gridNew.push(this.prepareRowForGrid(variation));\n }\n this.variations.push(variation);\n variationsKeys.push(variationsKey);\n }, this);\n\n _.each(_.omit(this.variationsComponent().productAttributesMap, variationsKeys), function (productId) {\n gridDeleted.push(this.prepareRowForGrid(\n _.findWhere(this.variationsComponent().variations, {\n productId: productId\n })\n ));\n }.bind(this));\n\n this.variationsExisting = gridExisting;\n this.variationsNew = gridNew;\n this.variationsDeleted = gridDeleted;\n },\n\n /**\n * Generate grid.\n */\n generateGrid: function () {\n var pageExisting = this.pagingExisting.pageSize * this.pagingExisting.current,\n pageNew = this.pagingNew.pageSize * this.pagingNew.current,\n pageDeleted = this.pagingDeleted.pageSize * this.pagingDeleted.current;\n\n this.pagingExisting.totalRecords = this.variationsExisting.length;\n this.gridExisting(this.variationsExisting.slice(pageExisting - this.pagingExisting.pageSize, pageExisting));\n\n this.pagingNew.totalRecords = this.variationsNew.length;\n this.gridNew(this.variationsNew.slice(pageNew - this.pagingNew.pageSize, pageNew));\n\n this.pagingDeleted.totalRecords = this.variationsDeleted.length;\n this.gridDeleted(this.variationsDeleted.slice(pageDeleted - this.pagingDeleted.pageSize, pageDeleted));\n },\n\n /**\n * @param {Object} variation\n * @return {Array}\n */\n prepareRowForGrid: function (variation) {\n var row = [];\n\n row.push(_.extend({\n images: []\n }, variation.images));\n row.push(variation.sku);\n row.push(variation[this.quantityFieldName]);\n _.each(variation.options, function (option) {\n row.push(option.label);\n });\n row.push(this.variationsComponent().getCurrencySymbol() + ' ' + variation.price);\n\n return row;\n },\n\n /**\n * @return {String|*}\n */\n getGridTemplate: function () {\n return this.gridTemplate;\n },\n\n /**\n * @return {*|String}\n */\n getGridId: function () {\n return _.uniqueId('grid_');\n },\n\n /**\n * @param {*} attributes\n * @return {Array}\n */\n getColumnsName: function (attributes) {\n var columns = this.attributesName.slice(0);\n\n attributes.each(function (attribute, index) {\n columns.splice(3 + index, 0, attribute.label);\n }, this);\n\n return columns;\n },\n\n /**\n * @param {Object} wizard\n */\n render: function (wizard) {\n this.wizard = wizard;\n this.sections(wizard.data.sections());\n this.attributes(wizard.data.attributes());\n this.gridNew([]);\n this.gridExisting([]);\n this.gridDeleted([]);\n this.gridExisting.columns(this.getColumnsName(this.wizard.data.attributes));\n this.gridNew.columns(this.getColumnsName(this.wizard.data.attributes));\n this.gridDeleted.columns(this.getColumnsName(this.variationsComponent().productAttributes));\n this.calculate(wizard.data.variations, wizard.data.sectionHelper);\n this.generateGrid();\n },\n\n /**\n * Force.\n */\n force: function () {\n this.variationsComponent().render(this.variations, this.attributes());\n this.modalComponent().closeModal();\n },\n\n /**\n * Back.\n */\n back: function () {\n },\n\n /**\n * Prepare product data from grid to have all the current fields values\n *\n * @param {Object} productDataFromGrid\n * @return {Object}\n */\n prepareProductDataFromGrid: function (productDataFromGrid) {\n productDataFromGrid = _.pick(\n productDataFromGrid,\n 'sku',\n 'name',\n 'weight',\n 'status',\n 'price',\n 'qty'\n );\n\n if (productDataFromGrid.hasOwnProperty('qty')) {\n productDataFromGrid[this.quantityFieldName] = productDataFromGrid.qty;\n }\n\n delete productDataFromGrid.qty;\n\n return productDataFromGrid;\n }\n });\n});\n","Magento_ConfigurableProduct/js/variations/steps/select_attributes.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'uiComponent',\n 'jquery',\n 'underscore',\n 'mage/translate'\n], function (Component, $, _) {\n 'use strict';\n\n /**\n * @param {Function} provider\n */\n var initNewAttributeListener = function (provider) {\n $('[data-role=product-variations-matrix]').on('add', function () {\n provider().reload();\n });\n };\n\n return Component.extend({\n attributesLabels: {},\n stepInitialized: false,\n defaults: {\n modules: {\n multiselect: '${ $.multiselectName }',\n attributeProvider: '${ $.providerName }'\n },\n listens: {\n '${ $.multiselectName }:selected': 'doSelectedAttributesLabels',\n '${ $.multiselectName }:rows': 'doSelectSavedAttributes'\n },\n notificationMessage: {\n text: null,\n error: null\n },\n selectedAttributes: []\n },\n\n /** @inheritdoc */\n initialize: function () {\n this._super();\n this.selected = [];\n\n initNewAttributeListener(this.attributeProvider);\n },\n\n /** @inheritdoc */\n initObservable: function () {\n this._super().observe(['selectedAttributes']);\n\n return this;\n },\n\n /**\n * @param {Object} wizard\n */\n render: function (wizard) {\n this.wizard = wizard;\n this.setNotificationMessage();\n },\n\n /**\n * Set notification message.\n */\n setNotificationMessage: function () {\n /*eslint-disable max-len*/\n var msg = $.mage.__('When you remove or add an attribute, we automatically update all configurations and you will need to recreate current configurations manually.');\n\n /*eslint-enable max-len*/\n\n if (this.mode === 'edit') {\n this.wizard.setNotificationMessage(msg);\n }\n },\n\n /**\n * Do select saved attributes.\n */\n doSelectSavedAttributes: function () {\n if (this.stepInitialized === false) {\n this.stepInitialized = true;\n //cache attributes labels, which can be present on the 2nd page\n _.each(this.initData.attributes, function (attribute) {\n this.attributesLabels[attribute.id] = attribute.label;\n }.bind(this));\n this.multiselect().selected(_.pluck(this.initData.attributes, 'id'));\n }\n },\n\n /**\n * @param {*} selected\n */\n doSelectedAttributesLabels: function (selected) {\n var labels = [];\n\n this.selected = selected;\n _.each(selected, function (attributeId) {\n var attribute;\n\n if (!this.attributesLabels[attributeId]) {\n attribute = _.findWhere(this.multiselect().rows(), {\n 'attribute_id': attributeId\n });\n\n if (attribute) {\n this.attributesLabels[attribute['attribute_id']] = attribute['frontend_label'];\n }\n }\n labels.push(this.attributesLabels[attributeId]);\n }.bind(this));\n this.selectedAttributes(labels.join(', '));\n },\n\n /**\n * @param {Object} wizard\n */\n force: function (wizard) {\n wizard.data.attributesIds = this.multiselect().selected;\n\n if (!wizard.data.attributesIds() || wizard.data.attributesIds().length === 0) {\n throw new Error($.mage.__('Please select attribute(s).'));\n }\n this.setNotificationMessage();\n },\n\n /**\n * Back.\n */\n back: function () {\n }\n });\n});\n","Magento_ConfigurableProduct/js/variations/steps/bulk.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/* eslint-disable no-undef */\n\n/* global FORM_KEY, byteConvert */\ndefine([\n 'uiComponent',\n 'jquery',\n 'ko',\n 'underscore',\n 'Magento_Ui/js/lib/collapsible',\n 'mage/template',\n 'Magento_Ui/js/modal/alert',\n 'Magento_Catalog/js/product-gallery',\n 'jquery/uppy-core',\n 'mage/translate',\n 'Magento_ConfigurableProduct/js/variations/variations'\n], function (Component, $, ko, _, Collapsible, mageTemplate, alert) {\n 'use strict';\n\n return Component.extend({\n defaults: {\n modules: {\n variationsComponent: '${ $.variationsComponent }'\n },\n countVariations: 0,\n attributes: [],\n sections: {},\n images: null,\n price: '',\n quantity: '',\n notificationMessage: {\n text: null,\n error: null\n }\n },\n\n /** @inheritdoc */\n initObservable: function () {\n this._super().observe('countVariations attributes sections');\n\n return this;\n },\n\n /** @inheritdoc */\n initialize: function () {\n var self = this;\n\n this._super();\n this.sections({\n images: {\n label: 'images',\n type: ko.observable('none'),\n value: ko.observable(),\n attribute: ko.observable()\n },\n price: {\n label: 'price',\n type: ko.observable('none'),\n value: ko.observable(),\n attribute: ko.observable(),\n currencySymbol: ''\n },\n quantity: {\n label: 'quantity',\n type: ko.observable('none'),\n value: ko.observable(),\n attribute: ko.observable()\n }\n });\n\n this.variationsComponent(function (variationsComponent) {\n this.sections().price.currencySymbol = variationsComponent.getCurrencySymbol();\n }.bind(this));\n\n /**\n * Make options sections.\n */\n this.makeOptionSections = function () {\n return {\n images: new this.makeImages(null),\n price: this.price,\n quantity: this.quantity\n };\n }.bind(this);\n\n /**\n * @param {Object} images\n * @param {*} typePreview\n */\n this.makeImages = function (images, typePreview) {\n var preview;\n\n if (!images) {\n this.images = [];\n this.preview = self.noImage;\n this.file = null;\n } else {\n this.images = images;\n preview = _.find(this.images, function (image) {\n return _.contains(image.galleryTypes, typePreview);\n });\n\n if (preview) {\n this.file = preview.file;\n this.preview = preview.url;\n } else {\n this.file = null;\n this.preview = self.noImage;\n }\n }\n };\n this.images = new this.makeImages();\n _.each(this.sections(), function (section) {\n section.type.subscribe(function () {\n this.setWizardNotifyMessageDependOnSectionType();\n }.bind(this));\n }, this);\n },\n types: ['each', 'single', 'none'],\n\n /**\n * Set Wizard notify message depend on section type\n */\n setWizardNotifyMessageDependOnSectionType: function () {\n var flag = false;\n\n _.each(this.sections(), function (section) {\n if (section.type() !== 'none') {\n flag = true;\n }\n }, this);\n\n if (flag) {\n this.wizard.setNotificationMessage(\n $.mage.__('Choose this option to delete and replace extension data for all past configurations.')\n );\n } else {\n this.wizard.cleanNotificationMessage();\n }\n },\n\n /**\n * @param {Object} wizard\n */\n render: function (wizard) {\n this.wizard = wizard;\n this.attributes(wizard.data.attributes());\n\n if (this.mode === 'edit') {\n this.setWizardNotifyMessageDependOnSectionType();\n }\n //fill option section data\n this.attributes.each(function (attribute) {\n attribute.chosen.each(function (option) {\n option.sections = ko.observable(this.makeOptionSections());\n }, this);\n }, this);\n //reset section.attribute\n _.each(this.sections(), function (section) {\n section.attribute(null);\n });\n\n this.initCountVariations();\n this.bindGalleries();\n },\n\n /**\n * Init count variations.\n */\n initCountVariations: function () {\n var variations = this.generateVariation(this.attributes()),\n newVariations = _.map(variations, function (options) {\n return this.variationsComponent().getVariationKey(options);\n }.bind(this)),\n existingVariations = _.keys(this.variationsComponent().productAttributesMap);\n\n this.countVariations(_.difference(newVariations, existingVariations).length);\n },\n\n /**\n * @param {Object} attributes - example [['b1', 'b2'],['a1', 'a2', 'a3'],['c1', 'c2', 'c3'],['d1']]\n * @returns {*} example [['b1','a1','c1','d1'],['b1','a1','c2','d1']...]\n */\n generateVariation: function (attributes) {\n return _.reduce(attributes, function (matrix, attribute) {\n var tmp = [];\n\n _.each(matrix, function (variations) {\n _.each(attribute.chosen, function (option) {\n option['attribute_code'] = attribute.code;\n option['attribute_label'] = attribute.label;\n tmp.push(_.union(variations, [option]));\n });\n });\n\n if (!tmp.length) {\n return _.map(attribute.chosen, function (option) {\n option['attribute_code'] = attribute.code;\n option['attribute_label'] = attribute.label;\n\n return [option];\n });\n }\n\n return tmp;\n }, []);\n },\n\n /**\n * @param {*} section\n * @param {Object} options\n * @return {*}\n */\n getSectionValue: function (section, options) {\n switch (this.sections()[section].type()) {\n case 'each':\n return _.find(this.sections()[section].attribute().chosen, function (chosen) {\n return _.find(options, function (option) {\n return chosen.id == option.id; //eslint-disable-line eqeqeq\n });\n }).sections()[section];\n\n case 'single':\n return this.sections()[section].value();\n\n case 'none':\n return this[section];\n }\n },\n\n /**\n * @param {*} node\n * @return {Promise|*}\n */\n getImageProperty: function (node) {\n var types = node.find('[data-role=gallery]').productGallery('option').types,\n images = _.map(node.find('[data-role=image]'), function (image) {\n var imageData = $(image).data('imageData'),\n positionElement;\n\n imageData.galleryTypes = _.pluck(_.filter(types, function (type) {\n return type.value === imageData.file;\n }), 'code');\n\n //jscs:disable requireCamelCaseOrUpperCaseIdentifiers\n positionElement =\n $(image).find('[name=\"product[media_gallery][images][' + imageData.file_id + '][position]\"]');\n //jscs:enable requireCamelCaseOrUpperCaseIdentifiers\n if (!_.isEmpty(positionElement.val())) {\n imageData.position = positionElement.val();\n }\n\n return imageData;\n });\n\n return _.reject(images, function (image) {\n return !!image.isRemoved;\n });\n },\n\n /**\n * Fill images section.\n */\n fillImagesSection: function () {\n switch (this.sections().images.type()) {\n case 'each':\n if (this.sections().images.attribute()) {\n this.sections().images.attribute().chosen.each(function (option) {\n option.sections().images = new this.makeImages(\n this.getImageProperty($('[data-role=step-gallery-option-' + option.id + ']')),\n 'thumbnail'\n );\n }, this);\n }\n break;\n\n case 'single':\n this.sections().images.value(new this.makeImages(\n this.getImageProperty($('[data-role=step-gallery-single]')),\n 'thumbnail'\n ));\n break;\n\n default:\n this.sections().images.value(new this.makeImages());\n break;\n }\n },\n\n /**\n * @param {Object} wizard\n */\n force: function (wizard) {\n this.fillImagesSection();\n this.validate();\n this.validateImage();\n wizard.data.sections = this.sections;\n wizard.data.sectionHelper = this.getSectionValue.bind(this);\n wizard.data.variations = this.generateVariation(this.attributes());\n },\n\n /**\n * Validate.\n */\n validate: function () {\n var formValid;\n\n _.each(this.sections(), function (section) {\n switch (section.type()) {\n case 'each':\n if (!section.attribute()) {\n throw new Error($.mage.__('Please select attribute for {section} section.')\n .replace('{section}', section.label));\n }\n break;\n\n case 'single':\n if (!section.value()) {\n throw new Error($.mage.__('Please fill in the values for {section} section.')\n .replace('{section}', section.label));\n }\n break;\n }\n }, this);\n formValid = true;\n _.each($('[data-role=attributes-values-form]'), function (form) {\n formValid = $(form).valid() && formValid;\n });\n\n if (!formValid) {\n throw new Error($.mage.__('Please fill-in correct values.'));\n }\n },\n\n /**\n * Validate image.\n */\n validateImage: function () {\n switch (this.sections().images.type()) {\n case 'each':\n _.each(this.sections().images.attribute().chosen, function (option) {\n if (!option.sections().images.images.length) {\n throw new Error($.mage.__('Please select image(s) for your attribute.'));\n }\n });\n break;\n\n case 'single':\n if (this.sections().images.value().file == null) {\n throw new Error($.mage.__('Please choose image(s).'));\n }\n break;\n }\n },\n\n /**\n * Back.\n */\n back: function () {\n this.setWizardNotifyMessageDependOnSectionType();\n },\n\n /**\n * Bind galleries.\n */\n bindGalleries: function () {\n $('[data-role=bulk-step] [data-role=gallery]').each(function (index, element) {\n var gallery = $(element),\n uploadInput = $(gallery.find('.uploader'))[0],\n uploadUrl = $(gallery.find('.browse-file')).attr('data-url'),\n dropZone = $(gallery).find('.image-placeholder')[0];\n\n if (!gallery.data('gallery-initialized')) {\n gallery.mage('productGallery', {\n template: '[data-template=gallery-content]',\n dialogTemplate: '.dialog-template',\n dialogContainerTmpl: '[data-role=img-dialog-container-tmpl]'\n });\n\n // uppy implementation\n let targetElement = uploadInput,\n fileId = null,\n arrayFromObj = Array.from,\n options = {\n proudlyDisplayPoweredByUppy: false,\n target: targetElement,\n hideUploadButton: true,\n hideRetryButton: true,\n hideCancelButton: true,\n inline: true,\n debug:true,\n showRemoveButtonAfterComplete: true,\n showProgressDetails: false,\n showSelectedFiles: false,\n allowMultipleUploads: false,\n hideProgressAfterFinish: true\n };\n\n gallery.find('.product-image-wrapper').on('click', function () {\n gallery.find('.uppy-Dashboard-browse').trigger('click');\n });\n\n const uppy = new Uppy.Uppy({\n autoProceed: true,\n\n onBeforeFileAdded: (currentFile) => {\n let progressTmpl = mageTemplate('[data-template=uploader]'),\n fileSize,\n tmpl;\n\n fileSize = typeof currentFile.size == 'undefined' ?\n $.mage.__('We could not detect a size.') :\n byteConvert(currentFile.size);\n\n fileId = Math.random().toString(33).substr(2, 18);\n\n tmpl = progressTmpl({\n data: {\n name: currentFile.name,\n size: fileSize,\n id: fileId\n }\n });\n\n // code to allow duplicate files from same folder\n const modifiedFile = {\n ...currentFile,\n id: currentFile.id + '-' + fileId,\n tempFileId: fileId\n };\n\n $(tmpl).appendTo(gallery.find('[data-role=uploader]'));\n return modifiedFile;\n },\n\n meta: {\n 'form_key': FORM_KEY\n }\n });\n\n // initialize Uppy upload\n uppy.use(Uppy.Dashboard, options);\n\n // drop area for file upload\n uppy.use(Uppy.DropTarget, {\n target: dropZone,\n onDragOver: () => {\n // override Array.from method of legacy-build.min.js file\n Array.from = null;\n },\n onDragLeave: () => {\n Array.from = arrayFromObj;\n }\n });\n\n // upload files on server\n uppy.use(Uppy.XHRUpload, {\n endpoint: uploadUrl,\n fieldName: 'image'\n });\n\n uppy.on('upload-success', (file, response) => {\n if (response.body && !response.body.error) {\n gallery.trigger('addItem', response.body);\n } else {\n $('#' + file.tempFileId)\n .delay(2000)\n .hide('highlight');\n alert({\n content: $.mage.__('We don\\'t recognize or support this file extension type.')\n });\n }\n $('#' + file.tempFileId).remove();\n });\n\n uppy.on('upload-progress', (file, progress) => {\n let progressWidth = parseInt(progress.bytesUploaded / progress.bytesTotal * 100, 10),\n progressSelector = '#' + file.tempFileId + ' .progressbar-container .progressbar';\n\n $(progressSelector).css('width', progressWidth + '%');\n });\n\n uppy.on('upload-error', (error, file) => {\n let progressSelector = '#' + file.tempFileId;\n\n $(progressSelector).removeClass('upload-progress').addClass('upload-failure')\n .delay(2000)\n .hide('highlight')\n .remove();\n });\n\n uppy.on('complete', () => {\n Array.from = arrayFromObj;\n });\n\n gallery.data('gallery-initialized', 1);\n }\n });\n }\n });\n});\n","Magento_ConfigurableProduct/js/variations/steps/attributes_values.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'uiComponent',\n 'jquery',\n 'ko',\n 'underscore',\n 'mageUtils',\n 'Magento_Ui/js/lib/collapsible',\n 'mage/translate'\n], function (Component, $, ko, _, utils, Collapsible) {\n 'use strict';\n\n //connect items with observableArrays\n ko.bindingHandlers.sortableList = {\n /** @inheritdoc */\n init: function (element, valueAccessor) {\n var list = valueAccessor();\n\n $(element).sortable({\n axis: 'y',\n handle: '[data-role=\"draggable\"]',\n tolerance: 'pointer',\n\n /** @inheritdoc */\n update: function (event, ui) {\n var item = ko.contextFor(ui.item[0]).$data,\n position = ko.utils.arrayIndexOf(ui.item.parent().children(), ui.item[0]);\n\n if (ko.contextFor(ui.item[0]).$index() != position) { //eslint-disable-line eqeqeq\n if (position >= 0) {\n list.remove(item);\n list.splice(position, 0, item);\n }\n ui.item.remove();\n }\n }\n });\n }\n };\n\n return Collapsible.extend({\n defaults: {\n notificationMessage: {\n text: null,\n error: null\n },\n createOptionsUrl: null,\n attributes: [],\n stepInitialized: false\n },\n\n /** @inheritdoc */\n initialize: function () {\n this._super();\n this.createAttribute = _.wrap(this.createAttribute, function () {\n var args = _.toArray(arguments),\n createAttribute = args.shift();\n\n return this.doInitSavedOptions(createAttribute.apply(this, args));\n });\n this.createAttribute = _.memoize(this.createAttribute.bind(this), _.property('id'));\n },\n\n /** @inheritdoc */\n initObservable: function () {\n this._super().observe(['attributes']);\n\n return this;\n },\n\n /**\n * Create option.\n */\n createOption: function () {\n // this - current attribute\n this.options.push({\n value: 0,\n label: '',\n id: utils.uniqueid(),\n 'attribute_id': this.id,\n 'is_new': true\n });\n },\n\n /**\n * @param {Object} option\n */\n saveOption: function (option) {\n if (this.isValidOption(option)) {\n this.options.remove(option);\n this.options.push(option);\n this.chosenOptions.push(option.id);\n }\n },\n\n /**\n * @param {Object} newOption\n * @return boolean\n */\n isValidOption: function (newOption) {\n var duplicatedOptions = [],\n errorOption,\n allOptions = [];\n\n newOption.label = newOption.label.trim();\n\n if (_.isEmpty(newOption.label)) {\n return false;\n }\n\n _.each(this.options(), function (option) {\n if (!_.isUndefined(allOptions[option.label]) && newOption.label === option.label) {\n duplicatedOptions.push(option);\n }\n\n allOptions[option.label] = option.label;\n });\n\n if (duplicatedOptions.length) {\n _.each(duplicatedOptions, function (duplicatedOption) {\n errorOption = $('[data-role=\"' + duplicatedOption.id + '\"]');\n errorOption.addClass('_error');\n });\n\n return false;\n }\n\n return true;\n },\n\n /**\n * @param {Object} option\n */\n removeOption: function (option) {\n this.options.remove(option);\n },\n\n /**\n * @param {String} attribute\n */\n removeAttribute: function (attribute) {\n this.attributes.remove(attribute);\n this.wizard.setNotificationMessage(\n $.mage.__('An attribute has been removed. This attribute will no longer appear in your configurations.')\n );\n },\n\n /**\n * @param {Object} attribute\n * @param {*} index\n * @return {Object}\n */\n createAttribute: function (attribute, index) {\n attribute.chosenOptions = ko.observableArray([]);\n attribute.options = ko.observableArray(_.map(attribute.options, function (option) {\n option.id = utils.uniqueid();\n\n return option;\n }));\n attribute.opened = ko.observable(this.initialOpened(index));\n attribute.collapsible = ko.observable(true);\n attribute.isValidOption = this.isValidOption;\n\n return attribute;\n },\n\n /**\n * First 3 attribute panels must be open.\n *\n * @param {Number} index\n * @return {Boolean}\n */\n initialOpened: function (index) {\n return index < 3;\n },\n\n /**\n * Save attribute.\n */\n saveAttribute: function () {\n var errorMessage = $.mage.__('Select options for all attributes or remove unused attributes.');\n\n if (!this.attributes().length) {\n throw new Error(errorMessage);\n }\n\n _.each(this.attributes(), function (attribute) {\n attribute.chosen = [];\n\n if (!attribute.chosenOptions.getLength()) {\n throw new Error(errorMessage);\n }\n _.each(attribute.chosenOptions(), function (id) {\n attribute.chosen.push(attribute.options.findWhere({\n id: id\n }));\n });\n });\n },\n\n /**\n * @param {Object} attribute\n */\n selectAllAttributes: function (attribute) {\n this.chosenOptions(_.pluck(attribute.options(), 'id'));\n },\n\n /**\n * @param {Object} attribute\n */\n deSelectAllAttributes: function (attribute) {\n attribute.chosenOptions.removeAll();\n },\n\n /**\n * @return {Boolean}\n */\n saveOptions: function () {\n var newOptions = [];\n\n _.each(this.attributes(), function (attribute) {\n _.each(attribute.options(), function (element) {\n var option = attribute.options.findWhere({\n id: element.id\n });\n\n if (option['is_new'] === true) {\n if (!attribute.isValidOption(option)) {\n throw new Error(\n $.mage.__('The value of attribute \"\"%1\"\" must be unique')\n .replace('\"%1\"', attribute.label)\n );\n }\n\n newOptions.push(option);\n }\n });\n });\n\n if (!newOptions.length) {\n return false;\n }\n\n $.ajax({\n type: 'POST',\n url: this.createOptionsUrl,\n data: {\n options: newOptions\n },\n showLoader: true\n }).done(function (savedOptions) {\n if (savedOptions.error) {\n this.notificationMessage.error = savedOptions.error;\n this.notificationMessage.text = savedOptions.message;\n\n return;\n }\n\n _.each(this.attributes(), function (attribute) {\n _.each(savedOptions, function (newOptionId, oldOptionId) {\n var option = attribute.options.findWhere({\n id: oldOptionId\n });\n\n if (option) {\n attribute.options.remove(option);\n option['is_new'] = false;\n option.value = newOptionId;\n attribute.options.push(option);\n }\n });\n });\n\n }.bind(this));\n },\n\n /**\n * @param {*} attributeIds\n */\n requestAttributes: function (attributeIds) {\n $.ajax({\n type: 'GET',\n url: this.optionsUrl,\n data: {\n attributes: attributeIds\n },\n showLoader: true\n }).done(function (attributes) {\n attributes = _.sortBy(attributes, function (attribute) {\n return this.wizard.data.attributesIds.indexOf(attribute.id);\n }.bind(this));\n this.attributes(_.map(attributes, this.createAttribute));\n }.bind(this));\n },\n\n /**\n * @param {*} attribute\n * @return {*}\n */\n doInitSavedOptions: function (attribute) {\n var selectedOptions, selectedOptionsIds, selectedAttribute = _.findWhere(this.initData.attributes, {\n id: attribute.id\n });\n\n if (selectedAttribute) {\n selectedOptions = _.pluck(selectedAttribute.chosen, 'value');\n selectedOptionsIds = _.pluck(_.filter(attribute.options(), function (option) {\n return _.contains(selectedOptions, option.value);\n }), 'id');\n attribute.chosenOptions(selectedOptionsIds);\n this.initData.attributes = _.without(this.initData.attributes, selectedAttribute);\n }\n\n return attribute;\n },\n\n /**\n * @param {Object} wizard\n */\n render: function (wizard) {\n this.wizard = wizard;\n this.requestAttributes(wizard.data.attributesIds());\n },\n\n /**\n * @param {Object} wizard\n */\n force: function (wizard) {\n this.saveOptions();\n this.saveAttribute(wizard);\n\n wizard.data.attributes = this.attributes;\n },\n\n /**\n * @param {Object} wizard\n */\n back: function (wizard) {\n wizard.data.attributesIds(this.attributes().pluck('id'));\n }\n });\n});\n","Magento_ConfigurableProduct/js/options/price-type-handler.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/*\ndefine([\n 'jquery',\n 'Magento_Catalog/catalog/type-events',\n 'notification',\n 'mage/translate'\n], function ($, productType) {\n 'use strict';\n\n return {\n isConfigurable: false,\n messageInited: false,\n messageSelector: '[data-role=product-custom-options-content]',\n isPercentPriceTypeExist: function () {\n var productOptionsContainer = $('#product_options_container_top');\n\n return !!productOptionsContainer.length;\n },\n showWarning: function () {\n if (!this.messageInited) {\n $(this.messageSelector).notification();\n this.messageInited = true;\n }\n this.hideWarning();\n $(this.messageSelector).notification('add', {\n message: $.mage.__('Custom options with price type \"percent\" is not available for ' +\n 'configurable product.'),\n error: false,\n messageContainer: this.messageSelector\n });\n },\n hideWarning: function () {\n $(this.messageSelector).notification('clear');\n },\n init: function () {\n $(document).on('changeTypeProduct', this._initType.bind(this));\n\n $('#product-edit-form-tabs').on('change', '.opt-type > select', function () {\n var selected = $('.opt-type > select :selected'),\n optGroup = selected.parent().attr('label');\n\n if (optGroup === 'Select') {\n $('#product-edit-form-tabs').on(\n 'click',\n '[data-ui-id=\"admin-product-options-options-box-select-option-type-add-select-row-button\"]',\n function () {\n this.percentPriceTypeHandler();\n }.bind(this)\n );\n } else {\n this.percentPriceTypeHandler();\n }\n }.bind(this));\n\n this._initType();\n },\n _initType: function () {\n this.isConfigurable = productType.type.current === 'configurable';\n if (this.isPercentPriceTypeExist()) {\n this.percentPriceTypeHandler();\n }\n },\n percentPriceTypeHandler: function () {\n var priceType = $('[data-attr=\"price-type\"]'),\n optionPercentPriceType = priceType.find('option[value=\"percent\"]');\n\n if (this.isConfigurable) {\n this.showWarning();\n optionPercentPriceType.hide();\n optionPercentPriceType.parent().val() === 'percent' ? optionPercentPriceType.parent().val('fixed') : '';\n } else {\n $(this.messageSelector).notification();\n optionPercentPriceType.show();\n this.hideWarning();\n }\n }\n };\n});\n*/\n","Magento_ConfigurableProduct/js/components/modal-configurable.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'Magento_Ui/js/modal/modal-component',\n 'uiRegistry',\n 'underscore'\n], function (Modal, registry, _) {\n 'use strict';\n\n return Modal.extend({\n defaults: {\n stepWizard: '',\n modules: {\n form: '${ $.formName }'\n }\n },\n\n /**\n * Open modal\n */\n openModal: function () {\n var stepWizard = {};\n\n this.form().validate();\n\n if (this.form().source.get('params.invalid') === false) {\n stepWizard = registry.get('index = ' + this.stepWizard);\n\n if (!_.isUndefined(stepWizard)) {\n stepWizard.open();\n }\n\n this._super();\n } else {\n this.form().focusInvalid();\n }\n }\n });\n});\n","Magento_ConfigurableProduct/js/components/file-uploader.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n 'Magento_Ui/js/form/element/file-uploader',\n 'underscore'\n], function (Element, _) {\n 'use strict';\n\n return Element.extend({\n processedFile: {},\n actionsListOpened: false,\n thumbnailUrl: '',\n thumbnail: null,\n smallImage: null,\n defaults: {\n fileInputName: ''\n },\n\n /**\n * Initialize observables.\n *\n * @returns {Object} Chainable.\n */\n initObservable: function () {\n this._super().observe(['processedFile', 'actionsListOpened', 'thumbnailUrl', 'thumbnail', 'smallImage']);\n\n return this;\n },\n\n /** @inheritdoc */\n setInitialValue: function () {\n var value = this.getInitialValue();\n\n if (!_.isString(value)) {\n this._super();\n }\n\n return this;\n },\n\n /**\n * Adds provided file to the files list.\n *\n * @param {Object} file\n * @returns {Object} Chainable.\n */\n addFile: function (file) {\n this.processedFile(this.processFile(file));\n\n this.value(this.processedFile().file);\n\n return this;\n },\n\n /**\n * Toggle actions list.\n *\n * @returns {Object} Chainable.\n */\n toggleActionsList: function () {\n if (this.actionsListOpened()) {\n this.actionsListOpened(false);\n } else {\n this.actionsListOpened(true);\n }\n\n return this;\n },\n\n /**\n * Close action list.\n *\n * @returns {Object} Chainable\n */\n closeList: function () {\n if (this.actionsListOpened()) {\n this.actionsListOpened(false);\n }\n\n return this;\n },\n\n /**\n * Delete Image\n *\n * @returns {Object} Chainable\n */\n deleteImage: function () {\n this.processedFile({});\n this.value(null);\n this.thumbnail(null);\n this.thumbnailUrl(null);\n this.smallImage(null);\n\n return this;\n }\n });\n});\n","Magento_ConfigurableProduct/js/components/associated-product-insert-listing.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'underscore',\n 'Magento_Ui/js/form/components/insert-listing'\n], function (_, insertListing) {\n 'use strict';\n\n return insertListing.extend({\n defaults: {\n gridInitialized: false,\n paramsUpdated: false,\n showMassActionColumn: true,\n currentProductId: 0,\n dataScopeAssociatedProduct: 'data.associated_product_ids',\n typeGrid: '',\n product: {},\n rowIndexForChange: undefined,\n changeProductData: [],\n modules: {\n productsProvider: '${ $.productsProvider }',\n productsColumns: '${ $.productsColumns }',\n productsMassAction: '${ $.productsMassAction }',\n modalWithGrid: '${ $.modalWithGrid }',\n productsFilters: '${ $.productsFilters }'\n },\n exports: {\n externalProviderParams: '${ $.externalProvider }:params'\n },\n links: {\n changeProductData: '${ $.provider }:${ $.changeProductProvider }'\n },\n listens: {\n '${ $.externalProvider }:params': '_setFilters _setVisibilityMassActionColumn',\n '${ $.productsProvider }:data': '_handleManualGridOpening',\n '${ $.productsMassAction }:selected': '_handleManualGridSelect'\n }\n },\n\n /**\n * Initialize observables.\n *\n * @returns {Object} Chainable.\n */\n initObservable: function () {\n this._super().observe(\n 'changeProductData'\n );\n\n return this;\n },\n\n /**\n * Get ids of used products.\n *\n * @returns {Array}\n */\n getUsedProductIds: function () {\n var usedProductsIds = this.source.get(this.dataScopeAssociatedProduct);\n\n return usedProductsIds.slice();\n },\n\n /**\n * Request for render content.\n *\n * @returns {Object}\n */\n doRender: function (showMassActionColumn, typeGrid) {\n this.typeGrid = typeGrid;\n this.showMassActionColumn = showMassActionColumn;\n\n if (this.gridInitialized) {\n this.paramsUpdated = false;\n this.productsFilters().clear();\n this._setFilters(this.externalProviderParams);\n this._setVisibilityMassActionColumn();\n }\n\n return this.render();\n },\n\n /**\n * Show grid with assigned product.\n *\n * @returns {Object}\n */\n showGridAssignProduct: function () {\n this.product = {};\n this.rowIndexForChange = undefined;\n\n return this.doRender(true, 'assignProduct');\n },\n\n /**\n * Show grid with changed product.\n *\n * @param {String} rowIndex\n * @param {String} product\n */\n showGridChangeProduct: function (rowIndex, product) {\n this.rowIndexForChange = rowIndex;\n this.product = product;\n this.doRender(false, 'changeProduct');\n },\n\n /**\n * Select product.\n *\n * @param {String} rowIndex\n */\n selectProduct: function (rowIndex) {\n this.changeProductData({\n rowIndex: this.rowIndexForChange,\n product: this.productsProvider().data.items[rowIndex]\n });\n this.modalWithGrid().closeModal();\n },\n\n /**\n * Set visibility state for mass action column\n *\n * @private\n */\n _setVisibilityMassActionColumn: function () {\n this.productsMassAction(function (massActionComponent) {\n this.productsColumns().elems().each(function (rowElement) {\n rowElement.disableAction = this.showMassActionColumn;\n }, this);\n massActionComponent.visible = this.showMassActionColumn;\n }.bind(this));\n },\n\n /**\n * Set filters.\n *\n * @param {Object} params\n * @private\n */\n _setFilters: function (params) {\n var filterModifier = {},\n attrCodes,\n usedProductIds,\n attributes;\n\n params = _.omit(params);\n\n if (!this.paramsUpdated) {\n this.gridInitialized = true;\n this.paramsUpdated = true;\n\n attrCodes = this._getAttributesCodes();\n usedProductIds = this.getUsedProductIds();\n\n if (this.currentProductId) {\n usedProductIds.push(this.currentProductId);\n }\n\n filterModifier['entity_id'] = {\n 'condition_type': 'nin', value: usedProductIds\n };\n attrCodes.each(function (code) {\n filterModifier[code] = {\n 'condition_type': 'notnull'\n };\n });\n\n if (this.typeGrid === 'changeProduct') {\n attributes = JSON.parse(this.product.attributes);\n\n filterModifier = _.extend(filterModifier, _.mapObject(attributes, function (value) {\n return {\n 'condition_type': 'eq',\n 'value': value\n };\n }));\n\n params.filters = attributes;\n } else {\n params.filters = {};\n }\n\n params['attributes_codes'] = attrCodes;\n\n this.set('externalProviderParams', params);\n this.set('externalFiltersModifier', filterModifier);\n }\n },\n\n /**\n * Get attribute codes.\n *\n * @returns {Array}\n * @private\n */\n _getAttributesCodes: function () {\n var attrCodes = this.source.get('data.attribute_codes');\n\n return attrCodes ? attrCodes : [];\n },\n\n /**\n * Get product variations.\n *\n * @returns {Array}\n * @private\n */\n _getProductVariations: function () {\n var matrix = this.source.get('data.configurable-matrix');\n\n return matrix ? matrix : [];\n },\n\n /**\n * Handle manual grid after opening\n * @private\n */\n _handleManualGridOpening: function (data) {\n if (data.items.length && this.typeGrid === 'assignProduct') {\n this.productsColumns().elems().each(function (rowElement) {\n rowElement.disableAction = true;\n });\n\n this._disableRows(data.items);\n }\n },\n\n /**\n * Handle manual selection.\n *\n * @param {Array} selected\n * @private\n */\n _handleManualGridSelect: function (selected) {\n var selectedRows,\n selectedVariationKeys;\n\n if (this.typeGrid === 'assignProduct') {\n selectedRows = _.filter(this.productsProvider().data.items, function (row) {\n return selected.indexOf(row['entity_id']) !== -1;\n });\n selectedVariationKeys = _.values(this._getVariationKeyMap(selectedRows));\n this._disableRows(this.productsProvider().data.items, selectedVariationKeys, selected);\n }\n },\n\n /**\n * Disable rows in grid for products with the same variation key\n *\n * @param {Array} items\n * @param {Array} selectedVariationKeys\n * @param {Array} selected\n * @private\n */\n _disableRows: function (items, selectedVariationKeys, selected) {\n selectedVariationKeys = selectedVariationKeys === undefined ? [] : selectedVariationKeys;\n selected = selected === undefined ? [] : selected;\n this.productsMassAction(function (massaction) {\n var configurableVariationKeys = _.union(\n selectedVariationKeys,\n _.pluck(this._getProductVariations(), 'variationKey')\n ),\n variationKeyMap = this._getVariationKeyMap(items),\n rowsForDisable = _.keys(_.pick(\n variationKeyMap,\n function (variationKey) {\n return configurableVariationKeys.indexOf(variationKey) !== -1;\n }\n ));\n\n massaction.disabled(_.difference(rowsForDisable, selected));\n }.bind(this));\n },\n\n /**\n * Get variation key map used in manual grid.\n *\n * @param {Array} items\n * @returns {Array} [{entity_id: variation-key}, ...]\n * @private\n */\n _getVariationKeyMap: function (items) {\n var variationKeyMap = {};\n\n _.each(items, function (row) {\n variationKeyMap[row['entity_id']] = _.values(\n _.pick(row, this._getAttributesCodes())\n ).sort().join('-');\n\n }, this);\n\n return variationKeyMap;\n }\n });\n});\n","Magento_ConfigurableProduct/js/components/custom-options-price-type.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'underscore',\n 'Magento_Catalog/js/components/custom-options-price-type'\n], function (_, PriceType) {\n 'use strict';\n\n return PriceType.extend({\n defaults: {\n isConfigurable: false,\n isFiltered: null,\n defaultOptions: null,\n filteredOptions: null,\n bannedOptions: []\n },\n\n /**\n * Updates options.\n *\n * @param {Boolean} variationsEmpty\n * @returns {Boolean}\n */\n updateOptions: function (variationsEmpty) {\n var isFiltered = this.isConfigurable || !variationsEmpty,\n value;\n\n if (this.isFiltered !== isFiltered) {\n value = this.value();\n\n this.options(isFiltered ? this.getFilteredOptions() : this.getDefaultOptions());\n this.value(value);\n }\n\n return isFiltered;\n },\n\n /**\n * Get default list of options.\n *\n * @returns {Array}\n */\n getDefaultOptions: function () {\n if (this.defaultOptions === null) {\n this.defaultOptions = this.options();\n }\n\n return this.defaultOptions;\n },\n\n /**\n * Get filtered list of options.\n *\n * @returns {Array}\n */\n getFilteredOptions: function () {\n var defaultOptions;\n\n if (this.filteredOptions === null) {\n defaultOptions = this.getDefaultOptions();\n this.filteredOptions = [];\n\n _.each(defaultOptions, function (option) {\n if (this.bannedOptions.indexOf(option.value) === -1) {\n this.filteredOptions.push(option);\n }\n }, this);\n }\n\n return this.filteredOptions;\n }\n });\n});\n","Magento_ConfigurableProduct/js/components/custom-options-warning.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'Magento_Ui/js/form/components/html'\n], function (Html) {\n 'use strict';\n\n return Html.extend({\n defaults: {\n isConfigurable: false\n },\n\n /**\n * Updates component visibility state.\n *\n * @param {Boolean} variationsEmpty\n * @returns {Boolean}\n */\n updateVisibility: function (variationsEmpty) {\n var isVisible = this.isConfigurable || !variationsEmpty;\n\n this.visible(isVisible);\n\n return isVisible;\n }\n });\n});\n","Magento_ConfigurableProduct/js/components/qty-configurable.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n 'Magento_Ui/js/form/element/abstract'\n], function (Abstract) {\n 'use strict';\n\n return Abstract.extend({\n defaults: {\n imports: {\n isConfigurable: '!ns = ${ $.ns }, index = configurable-matrix:isEmpty'\n }\n },\n\n /** @inheritdoc */\n initialize: function () {\n this._super();\n // resolve initial disable state\n this.handleQtyValue(this.isConfigurable);\n\n /** important to set this listener in initialize because of a different order of processing.\n * Do not move to defaults->listens section */\n this.setListeners({\n isConfigurable: 'handleQtyValue'\n });\n\n return this;\n },\n\n /**\n * Disable and clear Qty if product type changed to configurable\n *\n * @param {String} isConfigurable\n */\n handleQtyValue: function (isConfigurable) {\n this.disabled(!!this.isUseDefault() || isConfigurable);\n\n if (isConfigurable) {\n this.clear();\n }\n }\n });\n});\n","Magento_ConfigurableProduct/js/components/dynamic-rows-configurable.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'underscore',\n 'uiRegistry',\n 'Magento_Ui/js/dynamic-rows/dynamic-rows',\n 'jquery'\n], function (_, registry, dynamicRows, $) {\n 'use strict';\n\n return dynamicRows.extend({\n defaults: {\n actionsListOpened: false,\n canEditField: 'canEdit',\n newProductField: 'newProduct',\n dataScopeAssociatedProduct: 'data.associated_product_ids',\n dataProviderFromGrid: '',\n dataProviderChangeFromGrid: '',\n insertDataFromGrid: [],\n changeDataFromGrid: [],\n dataProviderFromWizard: '',\n insertDataFromWizard: [],\n map: null,\n isEmpty: true,\n isShowAddProductButton: false,\n cacheGridData: [],\n unionInsertData: [],\n deleteProperty: false,\n dataLength: 0,\n identificationProperty: 'id',\n 'attribute_set_id': '',\n attributesTmp: [],\n changedFlag: 'was_changed',\n listens: {\n 'insertDataFromGrid': 'processingInsertDataFromGrid',\n 'insertDataFromWizard': 'processingInsertDataFromWizard',\n 'unionInsertData': 'processingUnionInsertData',\n 'changeDataFromGrid': 'processingChangeDataFromGrid',\n 'isEmpty': 'changeVisibility'\n },\n imports: {\n 'attribute_set_id': '${$.provider}:data.product.attribute_set_id'\n },\n 'exports': {\n 'attribute_set_id': '${$.provider}:data.new-variations-attribute-set-id'\n },\n modules: {\n modalWithGrid: '${ $.modalWithGrid }',\n gridWithProducts: '${ $.gridWithProducts}'\n }\n },\n\n /**\n * Invokes initialize method of parent class,\n * contains initialization logic\n */\n initialize: function () {\n this._super()\n .changeVisibility(this.isEmpty());\n\n return this;\n },\n\n /**\n * Change visibility\n *\n * When isEmpty = true, then visbible = false\n *\n * @param {Boolean} isEmpty\n */\n changeVisibility: function (isEmpty) {\n this.visible(!isEmpty);\n },\n\n /**\n * Open modal with grid.\n *\n * @param {String} rowIndex\n */\n openModalWithGrid: function (rowIndex) {\n var productSource = this.source.get(this.dataScope + '.' + this.index + '.' + rowIndex),\n product = {\n 'id': productSource.id,\n 'attributes': productSource['configurable_attribute']\n };\n\n this.modalWithGrid().openModal();\n this.gridWithProducts().showGridChangeProduct(rowIndex, product);\n },\n\n /**\n * Initialize children\n *\n * @returns {Object} Chainable.\n */\n initChildren: function () {\n var tmpArray = [];\n\n this.recordData.each(function (recordData) {\n tmpArray.push(recordData);\n }, this);\n\n this.unionInsertData(tmpArray);\n\n return this;\n },\n\n /**\n * Delete record\n *\n * @param {Number} index - row index\n */\n deleteRecord: function (index) {\n var tmpArray,\n lastRecord;\n\n this.reRender = false;\n tmpArray = this.getUnionInsertData();\n tmpArray.splice(index, 1);\n\n if (!tmpArray.length) {\n this.attributesTmp = this.source.get('data.attributes');\n this.source.set('data.attributes', []);\n this.cacheGridData = [];\n }\n\n if (parseInt(this.currentPage(), 10) === this.pages()) {\n lastRecord =\n _.findWhere(this.elems(), {\n index: this.startIndex + this.getChildItems().length - 1\n }) ||\n _.findWhere(this.elems(), {\n index: (this.startIndex + this.getChildItems().length - 1).toString()\n });\n\n lastRecord.destroy();\n }\n\n this.unionInsertData(tmpArray);\n\n if (this.pages() < parseInt(this.currentPage(), 10)) {\n this.currentPage(this.pages());\n }\n\n this.reRender = true;\n this.showSpinner(false);\n },\n\n /**\n * Generate associated products\n */\n generateAssociatedProducts: function () {\n var productsIds = [];\n\n this.getUnionInsertData().forEach(function (data) {\n if (data.id !== null) {\n productsIds.push(data.id);\n }\n });\n\n this.source.set(this.dataScopeAssociatedProduct, productsIds);\n },\n\n /**\n * Calls 'initObservable' of parent\n *\n * @returns {Object} Chainable.\n */\n initObservable: function () {\n this._super()\n .observe([\n 'insertDataFromGrid', 'unionInsertData', 'isEmpty', 'isShowAddProductButton', 'actionsListOpened'\n ]);\n\n return this;\n },\n\n /**\n * Get union insert data from source\n *\n * @returns {Array}\n */\n getUnionInsertData: function () {\n var source = this.source.get(this.dataScope + '.' + this.index),\n result = [];\n\n _.each(source, function (data) {\n result.push(data);\n });\n\n return result;\n },\n\n /**\n * Process union insert data.\n *\n * @param {Array} data\n */\n processingUnionInsertData: function (data) {\n var dataCount,\n elemsCount,\n tmpData,\n path,\n attributeCodes = this.source.get('data.attribute_codes');\n\n this.isEmpty(data.length === 0);\n this.isShowAddProductButton(\n (!attributeCodes || data.length > 0 ? data.length : attributeCodes.length) > 0\n );\n\n tmpData = data.slice(this.pageSize * (this.currentPage() - 1),\n this.pageSize * (this.currentPage() - 1) + parseInt(this.pageSize, 10));\n\n this.source.set(this.dataScope + '.' + this.index, []);\n\n _.each(tmpData, function (row, index) {\n path = this.dataScope + '.' + this.index + '.' + (this.startIndex + index);\n row.attributes = $('<i></i>').text(row.attributes).html();\n this.source.set(path, row);\n }, this);\n\n this.source.set(this.dataScope + '.' + this.index, data);\n this.parsePagesData(data);\n\n // Render\n dataCount = tmpData.length;\n elemsCount = this.elems().length;\n\n if (dataCount > elemsCount) {\n tmpData.each(function (elemData, index) {\n this.addChild(elemData, this.startIndex + index);\n }, this);\n } else {\n for (elemsCount; elemsCount > dataCount; elemsCount--) {\n this.elems()[elemsCount - 1].destroy();\n }\n }\n\n this.generateAssociatedProducts();\n },\n\n /**\n * Set initial property to records data\n *\n * @returns {Object} Chainable.\n */\n setInitialProperty: function () {\n return this;\n },\n\n /**\n * Parsed data\n *\n * @param {Array} data - array with data\n * about selected records\n */\n processingInsertDataFromGrid: function (data) {\n var changes,\n tmpArray;\n\n if (!data.length) {\n return;\n }\n\n tmpArray = this.getUnionInsertData();\n\n changes = this._checkGridData(data);\n this.cacheGridData = data;\n\n changes.each(function (changedObject) {\n var mappedData = this.mappingValue(changedObject);\n\n mappedData[this.canEditField] = 0;\n mappedData[this.newProductField] = 0;\n mappedData.variationKey = this._getVariationKey(changedObject);\n mappedData['configurable_attribute'] = this._getConfigurableAttribute(changedObject);\n tmpArray.push(mappedData);\n }, this);\n\n // Attributes cannot be changed before regeneration thought wizard\n if (!this.source.get('data.attributes').length) {\n this.source.set('data.attributes', this.attributesTmp);\n }\n this.unionInsertData(tmpArray);\n },\n\n /**\n * Process changes from grid.\n *\n * @param {Object} data\n */\n processingChangeDataFromGrid: function (data) {\n var tmpArray = this.getUnionInsertData(),\n mappedData = this.mappingValue(data.product);\n\n mappedData[this.canEditField] = 0;\n mappedData[this.newProductField] = 0;\n mappedData.variationKey = this._getVariationKey(data.product);\n mappedData['configurable_attribute'] = this._getConfigurableAttribute(data.product);\n tmpArray[data.rowIndex] = mappedData;\n\n this.unionInsertData(tmpArray);\n },\n\n /**\n * Get variation key.\n *\n * @param {Object} data\n * @returns {String}\n * @private\n */\n _getVariationKey: function (data) {\n var attrCodes = this.source.get('data.attribute_codes'),\n key = [];\n\n attrCodes.each(function (code) {\n key.push(data[code]);\n });\n\n return key.sort().join('-');\n },\n\n /**\n * Get configurable attribute.\n *\n * @param {Object} data\n * @returns {String}\n * @private\n */\n _getConfigurableAttribute: function (data) {\n var attrCodes = this.source.get('data.attribute_codes'),\n confAttrs = {};\n\n attrCodes.each(function (code) {\n confAttrs[code] = data[code];\n });\n\n return JSON.stringify(confAttrs);\n },\n\n /**\n * Process data insertion from wizard\n *\n * @param {Object} data\n */\n processingInsertDataFromWizard: function (data) {\n var tmpArray = this.getUnionInsertData(),\n productIdsToDelete = this.source.get(this.dataScopeAssociatedProduct),\n index,\n product = {};\n\n tmpArray = this.unsetArrayItem(\n tmpArray,\n {\n id: null\n }\n );\n\n _.each(data, function (row) {\n if (row.productId) {\n index = _.indexOf(productIdsToDelete, row.productId);\n\n if (index > -1) {\n productIdsToDelete.splice(index, 1);\n tmpArray = this.unsetArrayItem(\n tmpArray,\n {\n id: row.productId\n }\n );\n }\n }\n product = this.getProductData(row);\n\n product[this.changedFlag] = true;\n product[this.canEditField] = row.editable;\n product[this.newProductField] = row.newProduct;\n tmpArray.push(product);\n }, this);\n\n _.each(productIdsToDelete, function (id) {\n tmpArray = this.unsetArrayItem(\n tmpArray,\n {\n id: id\n }\n );\n }, this);\n\n this.unionInsertData(tmpArray);\n },\n\n /**\n *\n * @param {Object} row\n * @returns {Object}\n */\n getProductData: function (row) {\n var product,\n attributesText = '';\n\n _.each(row.options, function (attribute) {\n if (attributesText) {\n attributesText += ', ';\n }\n attributesText += attribute['attribute_label'] + ': ' + attribute.label;\n }, this);\n\n product = {\n 'id': row.productId,\n 'product_link': row.productUrl,\n 'name': row.name,\n 'sku': row.sku,\n 'status': row.status,\n 'price': row.price,\n 'price_currency': row.priceCurrency,\n 'price_string': row.priceCurrency + row.price,\n 'weight': row.weight,\n 'qty': row.quantity,\n 'variationKey': row.variationKey,\n 'configurable_attribute': row.attribute,\n 'thumbnail_image': row.images.preview,\n 'media_gallery': row['media_gallery'],\n 'swatch_image': row['swatch_image'],\n 'small_image': row['small_image'],\n image: row.image,\n 'thumbnail': row.thumbnail,\n 'attributes': attributesText\n };\n\n return product;\n },\n\n /**\n * Remove array items matching condition.\n *\n * @param {Array} data\n * @param {Object} condition\n * @returns {Array}\n */\n unsetArrayItem: function (data, condition) {\n var objs = _.where(data, condition);\n\n _.each(objs, function (obj) {\n var index = _.indexOf(data, obj);\n\n if (index > -1) {\n data.splice(index, 1);\n }\n });\n\n return data;\n },\n\n /**\n * Check changed records\n *\n * @param {Array} data - array with records data\n * @returns {Array} Changed records\n */\n _checkGridData: function (data) {\n var cacheLength = this.cacheGridData.length,\n curData = data.length,\n max = cacheLength > curData ? this.cacheGridData : data,\n changes = [],\n obj = {};\n\n max.each(function (record, index) {\n obj[this.map.id] = record[this.map.id];\n\n if (!_.where(this.cacheGridData, obj).length) {\n changes.push(data[index]);\n }\n }, this);\n\n return changes;\n },\n\n /**\n * Mapped value\n */\n mappingValue: function (data) {\n var result = {};\n\n _.each(this.map, function (prop, index) {\n result[index] = data[prop];\n });\n\n return result;\n },\n\n /**\n * Toggle actions list.\n *\n * @param {Number} rowIndex\n * @returns {Object} Chainable.\n */\n toggleActionsList: function (rowIndex) {\n var state = false;\n\n if (rowIndex !== this.actionsListOpened()) {\n state = rowIndex;\n }\n this.actionsListOpened(state);\n\n return this;\n },\n\n /**\n * Close action list.\n *\n * @param {Number} rowIndex\n * @returns {Object} Chainable\n */\n closeList: function (rowIndex) {\n if (this.actionsListOpened() === rowIndex) {\n this.actionsListOpened(false);\n }\n\n return this;\n },\n\n /**\n * Toggle product status.\n *\n * @param {Number} rowIndex\n */\n toggleStatusProduct: function (rowIndex) {\n var tmpArray = this.getUnionInsertData(),\n status = parseInt(tmpArray[rowIndex].status, 10);\n\n if (status === 1) {\n tmpArray[rowIndex].status = 2;\n } else {\n tmpArray[rowIndex].status = 1;\n }\n\n tmpArray[rowIndex][this.changedFlag] = true;\n this.unionInsertData(tmpArray);\n }\n });\n});\n","Magento_ConfigurableProduct/js/components/container-configurable-handler.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'uiComponent'\n], function (Element) {\n 'use strict';\n\n return Element.extend({\n defaults: {\n listens: {\n '${ $.provider }:data.is_downloadable': 'handleProductType'\n },\n links: {\n isDownloadable: '${ $.provider }:data.is_downloadable'\n },\n modules: {\n createConfigurableButton: '${$.createConfigurableButton}'\n }\n },\n\n /**\n * Invokes initialize method of parent class,\n * contains initialization logic\n */\n initialize: function () {\n this._super();\n this.handleProductType(this.isDownloadable);\n\n return this;\n },\n\n /**\n * Calls 'initObservable' of parent\n *\n * @returns {Object} Chainable.\n */\n initObservable: function () {\n this._super()\n .observe(['content']);\n\n return this;\n },\n\n /**\n * Change content for container and visibility for button\n *\n * @param {String} isDownloadable\n */\n handleProductType: function (isDownloadable) {\n if (isDownloadable === '1') {\n this.content(this.content2);\n\n if (this.createConfigurableButton()) {\n this.createConfigurableButton().visible(false);\n }\n } else {\n this.content(this.content1);\n\n if (this.createConfigurableButton()) {\n this.createConfigurableButton().visible(true);\n }\n }\n }\n });\n});\n","Magento_ConfigurableProduct/js/components/price-configurable.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n 'underscore',\n 'uiRegistry',\n 'Magento_Ui/js/form/element/abstract'\n], function (_, registry, Abstract) {\n 'use strict';\n\n return Abstract.extend({\n defaults: {\n imports: {\n isConfigurable: '!ns = ${ $.ns }, index = configurable-matrix:isEmpty'\n },\n modules: {\n createConfigurableButton: '${$.createConfigurableButton}'\n }\n },\n\n /** @inheritdoc */\n initialize: function () {\n this._super();\n // resolve initial disable state\n this.handlePriceValue(this.isConfigurable);\n // add listener to track \"configurable\" type\n this.setListeners({\n isConfigurable: 'handlePriceValue'\n });\n\n return this;\n },\n\n /**\n * Calls 'initObservable' of parent\n *\n * @returns {Object} Chainable.\n */\n initObservable: function () {\n this._super()\n .observe(['content']);\n\n return this;\n },\n\n /**\n * Disable and clear price if product type changed to configurable\n *\n * @param {String} isConfigurable\n */\n handlePriceValue: function (isConfigurable) {\n this.disabled(!!this.isUseDefault() || isConfigurable);\n this.required(!!this.isUseDefault() || !isConfigurable);\n\n if (isConfigurable) {\n this.clear();\n }\n }\n });\n});\n","Magento_InventoryGroupedProductAdminUi/js/form/element/quantity-per-source.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n 'mage/translate',\n 'Magento_Ui/js/form/element/abstract'\n], function ($t, Abstract) {\n 'use strict';\n\n return Abstract.extend({\n defaults: {\n elementTmpl: 'Magento_InventoryGroupedProductAdminUi/dynamic-rows/cells/cell-source',\n itemsToDisplay: 3,\n isFullList: true,\n showFullListDescription: $t('Show more...'),\n listens: {\n value: 'updateItems'\n }\n },\n\n /**\n * Observe elements.\n *\n * @returns {exports}\n */\n initObservable: function () {\n this._super()\n .observe(['items', 'isFullList']);\n\n return this;\n },\n\n /**\n * Prepare data to use.\n *\n * @param {Object} data\n * @private\n */\n updateItems: function (data) {\n this.isFullList(data.length > this.itemsToDisplay);\n this.isFullList() ? this.items(data.slice(0, this.itemsToDisplay)) : this.items(data);\n }\n });\n});\n","Magento_InventoryGroupedProductAdminUi/js/form/element/grid-column-quantity-per-source.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n 'mage/translate',\n 'Magento_Ui/js/grid/columns/column'\n], function ($t, Column) {\n 'use strict';\n\n return Column.extend({\n defaults: {\n bodyTmpl: 'Magento_InventoryGroupedProductAdminUi/grid/column/quantity-per-source',\n itemsToDisplay: 3,\n showFullListDescription: $t('Show more...')\n },\n\n /**\n * Get source items from product data.\n *\n * @param {Object} rowData\n * @returns {Array}\n */\n getSourceItemsData: function (rowData) {\n return rowData['quantity_per_source'];\n }\n });\n});\n","Magento_Bundle/js/bundle-product.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/*global FORM_KEY*/\n/*global bSelection*/\n/**\n * @api\n */\ndefine([\n 'jquery',\n 'Magento_Catalog/js/product/weight-handler',\n 'Magento_Ui/js/modal/modal',\n 'jquery/ui',\n 'mage/translate',\n 'Magento_Theme/js/sortable',\n 'prototype'\n], function ($, weightHandler) {\n 'use strict';\n\n $.widget('mage.bundleProduct', {\n /** @inheritdoc */\n _create: function () {\n this._initOptionBoxes()\n ._initSortableSelections()\n ._bindCheckboxHandlers()\n ._initCheckboxState()\n ._bindAddSelectionDialog()\n ._hideProductTypeSwitcher();\n },\n\n /**\n * @return {Object}\n * @private\n */\n _initOptionBoxes: function () {\n var syncOptionTitle;\n\n this.element.sortable({\n axis: 'y',\n handle: '[data-role=draggable-handle]',\n items: '.option-box',\n update: this._updateOptionBoxPositions,\n tolerance: 'pointer'\n });\n\n /**\n * @param {jQuery.Event} event\n */\n syncOptionTitle = function (event) {\n var originalValue = $(event.target).attr('data-original-value'),\n currentValue = $(event.target).val(),\n optionBoxTitle = $('.title > span', $(event.target).closest('.option-box')),\n newOptionTitle = $.mage.__('New Option');\n\n optionBoxTitle.text(currentValue === '' && !originalValue.length ? newOptionTitle : currentValue);\n };\n this._on({\n 'change .field-option-title input[name$=\"[title]\"]': syncOptionTitle,\n 'keyup .field-option-title input[name$=\"[title]\"]': syncOptionTitle,\n 'paste .field-option-title input[name$=\"[title]\"]': syncOptionTitle\n });\n\n return this;\n },\n\n /**\n * @return {Object}\n * @private\n */\n _initSortableSelections: function () {\n this.element.find('.option-box .form-list tbody').sortable({\n axis: 'y',\n handle: '[data-role=draggable-handle]',\n\n /**\n * @param {jQuery.Event} event\n * @param {jQuery} ui\n * @return {jQuery}\n */\n helper: function (event, ui) {\n ui.children().each(function () {\n $(this).width($(this).width());\n });\n\n return ui;\n },\n update: this._updateSelectionsPositions,\n tolerance: 'pointer'\n });\n\n return this;\n },\n\n /**\n * @return {Object}\n * @private\n */\n _initCheckboxState: function () {\n this.element.find('.is-required').each(function () {\n $(this).prop('checked', $(this).closest('.option-box').find('[name$=\"[required]\"]').val() > 0);\n });\n\n this.element.find('.is-user-defined-qty').each(function () {\n $(this).prop('checked', $(this).closest('.qty-box').find('.select').val() > 0);\n });\n\n return this;\n },\n\n /**\n * @return {Object}\n * @private\n */\n _bindAddSelectionDialog: function () {\n var widget = this;\n\n this._on({\n /**\n * @param {jQuery.Event} event\n */\n 'click .add-selection': function (event) {\n var $optionBox = $(event.target).closest('.option-box'),\n $selectionGrid = $optionBox.find('.selection-search').clone(),\n optionIndex = $optionBox.attr('id').replace('bundle_option_', ''),\n productIds = [],\n productSkus = [],\n selectedProductList = {};\n\n $optionBox.find('[name$=\"[product_id]\"]').each(function () {\n if (!$(this).closest('tr').find('[name$=\"[delete]\"]').val()) {\n productIds.push($(this).val());\n productSkus.push($(this).closest('tr').find('.col-sku').text());\n }\n });\n\n bSelection.gridSelection.set(optionIndex, $H({}));\n bSelection.gridRemoval = $H({});\n bSelection.gridSelectedProductSkus = productSkus;\n\n $selectionGrid.on('contentUpdated', bSelection.gridUpdateCallback);\n $selectionGrid.on('change', '.col-id input', function () {\n var tr = $(this).closest('tr');\n\n if ($(this).is(':checked')) {\n selectedProductList[$(this).val()] = {\n name: tr.find('.col-name').html().trim(),\n sku: tr.find('.col-sku').html().trim(),\n 'product_id': $(this).val(),\n 'option_id': $('bundle_selection_id_' + optionIndex).val(),\n 'selection_price_value': 0,\n 'selection_qty': 1\n };\n } else {\n delete selectedProductList[$(this).val()];\n }\n });\n\n $selectionGrid.modal({\n title: $optionBox.find('input[name$=\"[title]\"]').val() === '' ?\n $.mage.__('Add Products to New Option') :\n $.mage.__('Add Products to Option \"%1\"').replace(\n '%1',\n $('<div>').text($optionBox.find('input[name$=\"[title]\"]').val()).html()\n ),\n modalClass: 'bundle',\n type: 'slide',\n\n /**\n * @param {jQuery.Event} e\n * @param {Object} modalWindow\n */\n closed: function (e, modalWindow) {\n modalWindow.modal.remove();\n },\n buttons: [{\n text: $.mage.__('Add Selected Products'),\n 'class': 'action-primary action-add',\n\n /** Click action. */\n click: function () {\n $.each(selectedProductList, function () {\n window.bSelection.addRow(optionIndex, this);\n });\n bSelection.gridRemoval.each(function (pair) {\n $optionBox.find('.col-sku').filter(function () {\n let text = $(this).text();\n\n return text.trim() === pair.key; // find row by SKU\n }).closest('tr').find('button.delete').trigger('click');\n });\n widget.refreshSortableElements();\n widget._updateSelectionsPositions.apply(widget.element);\n $selectionGrid.modal('closeModal');\n }\n }]\n });\n $.ajax({\n url: bSelection.selectionSearchUrl,\n dataType: 'html',\n data: {\n index: optionIndex,\n products: productIds,\n 'selected_products': productIds,\n 'form_key': FORM_KEY\n },\n\n /**\n * @param {*} data\n */\n success: function (data) {\n $selectionGrid.html(data).modal('openModal');\n },\n context: $('body'),\n showLoader: true\n });\n }\n });\n\n return this;\n },\n\n /**\n * @private\n */\n _hideProductTypeSwitcher: function () {\n weightHandler.hideWeightSwitcher();\n },\n\n /**\n * @return {Object}\n * @private\n */\n _bindCheckboxHandlers: function () {\n this._on({\n /**\n * @param {jQuery.Event} event\n */\n 'change .is-required': function (event) {\n var $this = $(event.target);\n\n $this.closest('.option-box').find('[name$=\"[required]\"]').val($this.is(':checked') ? 1 : 0);\n },\n\n /**\n * @param {jQuery.Event} event\n */\n 'change .is-user-defined-qty': function (event) {\n var $this = $(event.target);\n\n $this.closest('.qty-box').find('.select').val($this.is(':checked') ? 1 : 0);\n }\n });\n\n return this;\n },\n\n /**\n * @return {Object}\n * @private\n */\n _updateOptionBoxPositions: function () {\n $(this).find('[name^=bundle_options][name$=\"[position]\"]').each(function (index) {\n $(this).val(index);\n });\n\n return this;\n },\n\n /**\n * @return {Object}\n * @private\n */\n _updateSelectionsPositions: function () {\n $(this).find('[name^=bundle_selections][name$=\"[position]\"]').each(function (index) {\n $(this).val(index);\n });\n\n return this;\n },\n\n /**\n *\n * @return {Object}\n */\n refreshSortableElements: function () {\n this.element.sortable('refresh');\n this._updateOptionBoxPositions.apply(this.element);\n this._initSortableSelections();\n this._initCheckboxState();\n\n return this;\n }\n });\n\n});\n","Magento_Bundle/js/price-bundle.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n 'jquery',\n 'underscore',\n 'mage/template',\n 'priceUtils',\n 'jquery/jquery.parsequery',\n 'priceBox'\n], function ($, _, mageTemplate, utils) {\n 'use strict';\n\n var globalOptions = {\n optionConfig: null,\n productBundleSelector: 'input.bundle.option, select.bundle.option, textarea.bundle.option',\n qtyFieldSelector: 'input.qty',\n priceBoxSelector: '.price-box',\n optionHandlers: {},\n optionTemplate: '<%- data.label %>' +\n '<% if (data.finalPrice.value) { %>' +\n ' +<%- data.finalPrice.formatted %>' +\n '<% } %>',\n controlContainer: 'dd', // should be eliminated\n priceFormat: {},\n isFixedPrice: false,\n optionTierPricesBlocksSelector: '#option-tier-prices-{1} [data-role=\"selection-tier-prices\"]',\n isOptionsInitialized: false\n };\n\n $.widget('mage.priceBundle', {\n options: globalOptions,\n\n /**\n * @private\n */\n _init: function initPriceBundle() {\n var form = this.element,\n options = $(this.options.productBundleSelector, form),\n qty = $(this.options.qtyFieldSelector, form);\n\n // Override defaults with URL query parameters and/or inputs values\n this._overrideDefaults();\n\n options.trigger('change');\n qty.trigger('change');\n },\n\n /**\n * @private\n */\n _create: function createPriceBundle() {\n var form = this.element,\n options = $(this.options.productBundleSelector, form),\n priceBox = $(this.options.priceBoxSelector, form),\n qty = $(this.options.qtyFieldSelector, form);\n\n this._updatePriceBox();\n priceBox.on('price-box-initialized', this._updatePriceBox.bind(this));\n options.on('change', this._onBundleOptionChanged.bind(this));\n qty.on('change', this._onQtyFieldChanged.bind(this));\n },\n\n /**\n * Override default options values settings with either URL query parameters or\n * initialized inputs values.\n * @private\n */\n _overrideDefaults: function () {\n var hashIndex = window.location.href.indexOf('#');\n\n if (hashIndex !== -1) {\n this._parseQueryParams(window.location.href.substr(hashIndex + 1));\n }\n },\n\n /**\n * Parse query parameters from a query string and set options values based on the\n * key value pairs of the parameters.\n * @param {*} queryString - URL query string containing query parameters.\n * @private\n */\n _parseQueryParams: function (queryString) {\n var queryParams = $.parseQuery({\n query: queryString\n }),\n selectedValues = [],\n form = this.element,\n options = $(this.options.productBundleSelector, form),\n qtys = $(this.options.qtyFieldSelector, form);\n\n $.each(queryParams, $.proxy(function (key, value) {\n qtys.each(function (index, qty) {\n if (qty.name === key) {\n $(qty).val(value);\n }\n });\n options.each(function (index, option) {\n let optionType = $(option).prop('type');\n\n if (option.name === key ||\n optionType === 'select-multiple'\n && key.indexOf(option.name.substr(0, option.name.length - 2)) !== false\n ) {\n\n switch (optionType) {\n case 'radio':\n $(option).val() === value ? $(option).prop('checked', true) : '';\n break;\n case 'checkbox':\n $(option).prop('checked', true);\n break;\n case 'hidden':\n case 'select-one':\n $(option).val(value);\n break;\n case 'select-multiple':\n selectedValues.push(value);\n break;\n }\n if (optionType === 'select-multiple' && selectedValues.length) {\n $(option).val(selectedValues);\n }\n }\n });\n }, this));\n },\n\n /**\n * Update price box config with bundle option prices\n * @private\n */\n _updatePriceBox: function () {\n var form = this.element,\n options = $(this.options.productBundleSelector, form),\n priceBox = $(this.options.priceBoxSelector, form);\n\n if (!this.options.isOptionsInitialized) {\n if (priceBox.data('magePriceBox') &&\n priceBox.priceBox('option') &&\n priceBox.priceBox('option').priceConfig\n ) {\n if (priceBox.priceBox('option').priceConfig.optionTemplate) { //eslint-disable-line max-depth\n this._setOption('optionTemplate', priceBox.priceBox('option').priceConfig.optionTemplate);\n }\n this._setOption('priceFormat', priceBox.priceBox('option').priceConfig.priceFormat);\n priceBox.priceBox('setDefault', this.options.optionConfig.prices);\n this.options.isOptionsInitialized = true;\n }\n this._applyOptionNodeFix(options);\n }\n\n return this;\n },\n\n /**\n * Handle change on bundle option inputs\n * @param {jQuery.Event} event\n * @private\n */\n _onBundleOptionChanged: function onBundleOptionChanged(event) {\n var changes,\n bundleOption = $(event.target),\n priceBox = $(this.options.priceBoxSelector, this.element),\n handler = this.options.optionHandlers[bundleOption.data('role')];\n\n bundleOption.data('optionContainer', bundleOption.closest(this.options.controlContainer));\n bundleOption.data('qtyField', bundleOption.data('optionContainer').find(this.options.qtyFieldSelector));\n\n if (handler && handler instanceof Function) {\n changes = handler(bundleOption, this.options.optionConfig, this);\n } else {\n changes = defaultGetOptionValue(bundleOption, this.options.optionConfig);//eslint-disable-line\n }\n\n // eslint-disable-next-line no-use-before-define\n if (isValidQty(bundleOption)) {\n if (changes) {\n priceBox.trigger('updatePrice', changes);\n }\n\n this._displayTierPriceBlock(bundleOption);\n this.updateProductSummary();\n }\n },\n\n /**\n * Handle change on qty inputs near bundle option\n * @param {jQuery.Event} event\n * @private\n */\n _onQtyFieldChanged: function onQtyFieldChanged(event) {\n var field = $(event.target),\n optionInstance,\n optionConfig;\n\n if (field.data('optionId') && field.data('optionValueId')) {\n optionInstance = field.data('option');\n optionConfig = this.options.optionConfig\n .options[field.data('optionId')]\n .selections[field.data('optionValueId')];\n optionConfig.qty = field.val();\n\n // eslint-disable-next-line no-use-before-define\n if (isValidQty(optionInstance)) {\n optionInstance.trigger('change');\n }\n }\n },\n\n /**\n * Helper to fix backend behavior:\n * - if default qty large than 1 then backend multiply price in config\n *\n * @deprecated\n * @private\n */\n _applyQtyFix: function applyQtyFix() {\n var config = this.options.optionConfig;\n\n if (config.isFixedPrice) {\n _.each(config.options, function (option) {\n _.each(option.selections, function (item) {\n if (item.qty && item.qty !== 1) {\n _.each(item.prices, function (price) {\n price.amount /= item.qty;\n });\n }\n });\n });\n }\n },\n\n /**\n * Helper to fix issue with option nodes:\n * - you can't place any html in option ->\n * so you can't style it via CSS\n * @param {jQuery} options\n * @private\n */\n _applyOptionNodeFix: function applyOptionNodeFix(options) {\n var config = this.options,\n format = config.priceFormat,\n template = config.optionTemplate;\n\n template = mageTemplate(template);\n options.filter('select').each(function (index, element) {\n var $element = $(element),\n optionId = utils.findOptionId($element),\n optionConfig = config.optionConfig && config.optionConfig.options[optionId].selections,\n value;\n\n $element.find('option').each(function (idx, option) {\n var $option,\n optionValue,\n toTemplate,\n prices;\n\n $option = $(option);\n optionValue = $option.val();\n\n if (!optionValue && optionValue !== 0) {\n return;\n }\n\n toTemplate = {\n data: {\n label: optionConfig[optionValue] && optionConfig[optionValue].name\n }\n };\n prices = optionConfig[optionValue].prices;\n\n _.each(prices, function (price, type) {\n value = +price.amount;\n value += _.reduce(price.adjustments, function (sum, x) {//eslint-disable-line\n return sum + x;\n }, 0);\n toTemplate.data[type] = {\n value: value,\n formatted: utils.formatPriceLocale(value, format)\n };\n });\n\n $option.html(template(toTemplate));\n });\n });\n },\n\n /**\n * Custom behavior on getting options:\n * now widget able to deep merge accepted configuration with instance options.\n * @param {Object} options\n * @return {$.Widget}\n */\n _setOptions: function setOptions(options) {\n $.extend(true, this.options, options);\n\n this._super(options);\n\n return this;\n },\n\n /**\n * Show or hide option tier prices block\n *\n * @param {Object} optionElement\n * @private\n */\n _displayTierPriceBlock: function (optionElement) {\n var optionType = optionElement.prop('type'),\n optionId,\n optionValue,\n optionTierPricesElements;\n\n if (optionType === 'select-one') {\n optionId = utils.findOptionId(optionElement[0]);\n optionValue = optionElement.val() || null;\n optionTierPricesElements = $(this.options.optionTierPricesBlocksSelector.replace('{1}', optionId));\n\n _.each(optionTierPricesElements, function (tierPriceElement) {\n var selectionId = $(tierPriceElement).data('selection-id') + '';\n\n if (selectionId === optionValue) {\n $(tierPriceElement).show();\n } else {\n $(tierPriceElement).hide();\n }\n });\n }\n },\n\n /**\n * Handler to update productSummary box\n */\n updateProductSummary: function updateProductSummary() {\n this.element.trigger('updateProductSummary', {\n config: this.options.optionConfig\n });\n }\n });\n\n return $.mage.priceBundle;\n\n /**\n * Converts option value to priceBox object\n *\n * @param {jQuery} element\n * @param {Object} config\n * @returns {Object|null} - priceBox object with additional prices\n */\n function defaultGetOptionValue(element, config) {\n var changes = {},\n optionHash,\n tempChanges,\n qtyField,\n optionId = utils.findOptionId(element[0]),\n optionValue = element.val() || null,\n optionName = element.prop('name'),\n optionType = element.prop('type'),\n optionConfig = config.options[optionId].selections,\n optionQty = 0,\n canQtyCustomize = false,\n selectedIds = config.selected;\n\n switch (optionType) {\n case 'radio':\n case 'select-one':\n\n if (optionType === 'radio' && !element.is(':checked')) {\n return null;\n }\n\n qtyField = element.data('qtyField');\n qtyField.data('option', element);\n\n if (optionValue) {\n optionQty = optionConfig[optionValue].qty || 0;\n canQtyCustomize = optionConfig[optionValue].customQty === '1';\n toggleQtyField(qtyField, optionQty, optionId, optionValue, canQtyCustomize);//eslint-disable-line\n tempChanges = utils.deepClone(optionConfig[optionValue].prices);\n tempChanges = applyTierPrice(//eslint-disable-line\n tempChanges,\n optionQty,\n optionConfig[optionValue]\n );\n tempChanges = applyQty(tempChanges, optionQty);//eslint-disable-line\n } else {\n tempChanges = {};\n toggleQtyField(qtyField, '0', optionId, optionValue, false);//eslint-disable-line\n }\n optionHash = 'bundle-option-' + optionName;\n changes[optionHash] = tempChanges;\n selectedIds[optionId] = [optionValue];\n break;\n\n case 'select-multiple':\n optionValue = _.compact(optionValue);\n\n _.each(optionConfig, function (row, optionValueCode) {\n optionHash = 'bundle-option-' + optionName + '##' + optionValueCode;\n optionQty = row.qty || 0;\n tempChanges = utils.deepClone(row.prices);\n tempChanges = applyTierPrice(tempChanges, optionQty, optionConfig);//eslint-disable-line\n tempChanges = applyQty(tempChanges, optionQty);//eslint-disable-line\n changes[optionHash] = _.contains(optionValue, optionValueCode) ? tempChanges : {};\n });\n\n selectedIds[optionId] = optionValue || [];\n break;\n\n case 'checkbox':\n optionHash = 'bundle-option-' + optionName + '##' + optionValue;\n optionQty = optionConfig[optionValue].qty || 0;\n tempChanges = utils.deepClone(optionConfig[optionValue].prices);\n tempChanges = applyTierPrice(tempChanges, optionQty, optionConfig);//eslint-disable-line\n tempChanges = applyQty(tempChanges, optionQty);//eslint-disable-line\n changes[optionHash] = element.is(':checked') ? tempChanges : {};\n\n selectedIds[optionId] = selectedIds[optionId] || [];\n\n if (!_.contains(selectedIds[optionId], optionValue) && element.is(':checked')) {\n selectedIds[optionId].push(optionValue);\n } else if (!element.is(':checked')) {\n selectedIds[optionId] = _.without(selectedIds[optionId], optionValue);\n }\n break;\n\n case 'hidden':\n optionHash = 'bundle-option-' + optionName + '##' + optionValue;\n optionQty = optionConfig[optionValue].qty || 0;\n canQtyCustomize = optionConfig[optionValue].customQty === '1';\n qtyField = element.data('qtyField');\n qtyField.data('option', element);\n toggleQtyField(qtyField, optionQty, optionId, optionValue, canQtyCustomize);//eslint-disable-line\n tempChanges = utils.deepClone(optionConfig[optionValue].prices);\n tempChanges = applyTierPrice(tempChanges, optionQty, optionConfig);//eslint-disable-line\n tempChanges = applyQty(tempChanges, optionQty);//eslint-disable-line\n\n optionHash = 'bundle-option-' + optionName;\n changes[optionHash] = tempChanges;\n selectedIds[optionId] = [optionValue];\n break;\n }\n\n return changes;\n }\n\n /**\n * Check the quantity field if negative value occurs.\n *\n * @param {Object} bundleOption\n */\n function isValidQty(bundleOption) {\n var isValid = true,\n qtyElem = bundleOption.data('qtyField'),\n bundleOptionType = bundleOption.prop('type');\n\n if (['radio', 'select-one'].includes(bundleOptionType) && qtyElem.val() < 0) {\n isValid = false;\n }\n\n return isValid;\n }\n\n /**\n * Helper to toggle qty field\n * @param {jQuery} element\n * @param {String|Number} value\n * @param {String|Number} optionId\n * @param {String|Number} optionValueId\n * @param {Boolean} canEdit\n */\n function toggleQtyField(element, value, optionId, optionValueId, canEdit) {\n element\n .val(value)\n .data('optionId', optionId)\n .data('optionValueId', optionValueId)\n .attr('disabled', !canEdit);\n\n if (canEdit) {\n element.removeClass('qty-disabled');\n } else {\n element.addClass('qty-disabled');\n }\n }\n\n /**\n * Helper to multiply on qty\n *\n * @param {Object} prices\n * @param {Number} qty\n * @returns {Object}\n */\n function applyQty(prices, qty) {\n _.each(prices, function (everyPrice) {\n everyPrice.amount *= qty;\n _.each(everyPrice.adjustments, function (el, index) {\n everyPrice.adjustments[index] *= qty;\n });\n });\n\n return prices;\n }\n\n /**\n * Helper to limit price with tier price\n *\n * @param {Object} oneItemPrice\n * @param {Number} qty\n * @param {Object} optionConfig\n * @returns {Object}\n */\n function applyTierPrice(oneItemPrice, qty, optionConfig) {\n var tiers = optionConfig.tierPrice,\n magicKey = _.keys(oneItemPrice)[0],\n tiersFirstKey = _.keys(optionConfig)[0],\n lowest = false;\n\n if (!tiers) {//tiers is undefined when options has only one option\n tiers = optionConfig[tiersFirstKey].tierPrice;\n }\n\n tiers.sort(function (a, b) {//sorting based on \"price_qty\"\n return a['price_qty'] - b['price_qty'];\n });\n\n _.each(tiers, function (tier, index) {\n if (tier['price_qty'] > qty) {\n return;\n }\n\n if (tier.prices[magicKey].amount < oneItemPrice[magicKey].amount) {\n lowest = index;\n }\n });\n\n if (lowest !== false) {\n oneItemPrice = utils.deepClone(tiers[lowest].prices);\n }\n\n return oneItemPrice;\n }\n});\n","Magento_Bundle/js/bundle-type-handler.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'jquery',\n 'Magento_Catalog/catalog/type-events',\n 'Magento_Catalog/js/product/weight-handler'\n], function ($, productType, weight) {\n 'use strict';\n\n return {\n\n /**\n * Constructor component\n */\n 'Magento_Bundle/js/bundle-type-handler': function () {\n this.bindAll();\n this._initType();\n },\n\n /**\n * Bind all\n */\n bindAll: function () {\n $(document).on('changeTypeProduct', this._initType.bind(this));\n },\n\n /**\n * Init type\n * @private\n */\n _initType: function () {\n if (\n productType.type.init === 'bundle' &&\n productType.type.current !== 'bundle' &&\n !weight.isLocked()\n ) {\n weight.switchWeight();\n }\n }\n };\n});\n","Magento_Bundle/js/components/bundle-option-qty.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'Magento_Ui/js/form/element/abstract'\n], function (Abstract) {\n 'use strict';\n\n return Abstract.extend({\n defaults: {\n valueUpdate: 'input',\n isInteger: true,\n validation: {\n 'validate-number': true\n }\n },\n\n /**\n * @inheritdoc\n */\n setInitialValue: function () {\n this.initialValue = this.getInitialValue();\n\n if (this.initialValue === undefined || this.initialValue === '') {\n this.initialValue = 1;\n }\n\n if (this.value.peek() !== this.initialValue) {\n this.value(this.initialValue);\n }\n\n this.on('value', this.onUpdate.bind(this));\n this.isUseDefault(this.disabled());\n\n return this;\n },\n\n /**\n * @inheritdoc\n */\n onUpdate: function () {\n this.validation['validate-digits'] = this.isInteger;\n this._super();\n },\n\n /**\n * @inheritdoc\n */\n hasChanged: function () {\n var notEqual = this.value() !== this.initialValue.toString();\n\n return !this.visible() ? false : notEqual;\n }\n });\n});\n","Magento_Bundle/js/components/bundle-checkbox.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'Magento_Ui/js/form/element/single-checkbox',\n 'uiRegistry'\n], function (Checkbox, registry) {\n 'use strict';\n\n return Checkbox.extend({\n defaults: {\n clearing: false,\n parentContainer: '',\n parentSelections: '',\n changer: '',\n exports: {\n value: '${$.parentName}:isDefaultValue'\n }\n },\n\n /**\n * @inheritdoc\n */\n initObservable: function () {\n this._super().\n observe('elementTmpl');\n\n return this;\n },\n\n /**\n * @inheritdoc\n */\n initConfig: function () {\n this._super();\n this.imports.changeType = this.retrieveParentName(this.parentContainer) + '.' + this.changer + ':value';\n\n return this;\n },\n\n /**\n * @inheritdoc\n */\n onUpdate: function () {\n if (this.prefer === 'radio' && this.checked() && !this.clearing) {\n this.clearValues();\n }\n\n this._super();\n },\n\n /**\n * Checkbox to radio type changer.\n *\n * @param {String} type - type to change.\n */\n changeType: function (type) {\n var typeMap = registry.get(this.retrieveParentName(this.parentContainer) + '.' + this.changer).typeMap;\n\n this.prefer = typeMap[type];\n this.elementTmpl(this.templates[typeMap[type]]);\n },\n\n /**\n * Clears values in components like this.\n */\n clearValues: function () {\n var records = registry.get(this.retrieveParentName(this.parentSelections)),\n index = this.index,\n uid = this.uid;\n\n records.elems.each(function (record) {\n record.elems.filter(function (comp) {\n return comp.index === index && comp.uid !== uid;\n }).each(function (comp) {\n comp.clearing = true;\n comp.clear();\n comp.clearing = false;\n });\n });\n },\n\n /**\n * Retrieve name for the most global parent with provided index.\n *\n * @param {String} parent - parent name.\n * @returns {String}\n */\n retrieveParentName: function (parent) {\n return this.name.replace(new RegExp('^(.+?\\\\.)?' + parent + '\\\\..+'), '$1' + parent);\n }\n });\n});\n","Magento_Bundle/js/components/bundle-user-defined-checkbox.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'Magento_Ui/js/form/element/single-checkbox'\n], function (Checkbox) {\n 'use strict';\n\n return Checkbox.extend({\n defaults: {\n listens: {\n inputType: 'onInputTypeChange'\n }\n },\n\n /**\n * Handler for \"inputType\" property\n *\n * @param {String} data\n */\n onInputTypeChange: function (data) {\n data === 'checkbox' || data === 'multi' ?\n this.clear()\n .visible(false) :\n this.visible(true);\n }\n });\n});\n","Magento_Bundle/js/components/bundle-dynamic-rows-grid.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'underscore',\n 'Magento_Ui/js/dynamic-rows/dynamic-rows-grid',\n 'uiLayout',\n 'rjsResolver'\n], function (_, dynamicRowsGrid, layout, resolver) {\n 'use strict';\n\n return dynamicRowsGrid.extend({\n defaults: {\n label: '',\n columnsHeader: false,\n columnsHeaderAfterRender: true,\n addButton: false,\n isDefaultFieldScope: 'is_default',\n defaultRecords: {\n use: [],\n moreThanOne: false,\n state: {}\n },\n listens: {\n inputType: 'onInputTypeChange',\n isDefaultValue: 'onIsDefaultValue',\n pageSize: 'onPageSizeChange'\n },\n sizesConfig: {\n component: 'Magento_Ui/js/grid/paging/sizes',\n name: '${ $.name }_sizes',\n options: {\n '20': {\n value: 20,\n label: 20\n },\n '30': {\n value: 30,\n label: 30\n },\n '50': {\n value: 50,\n label: 50\n },\n '100': {\n value: 100,\n label: 100\n },\n '200': {\n value: 200,\n label: 200\n }\n },\n storageConfig: {\n provider: '${ $.storageConfig.provider }',\n namespace: '${ $.storageConfig.namespace }'\n },\n enabled: false\n },\n links: {\n options: '${ $.sizesConfig.name }:options',\n pageSize: '${ $.sizesConfig.name }:value'\n },\n modules: {\n sizes: '${ $.sizesConfig.name }'\n }\n },\n\n /**\n * Initializes paging component.\n *\n * @returns {Paging} Chainable.\n */\n initialize: function () {\n this._super()\n .initSizes();\n\n return this;\n },\n\n /**\n * Initializes sizes component.\n *\n * @returns {Paging} Chainable.\n */\n initSizes: function () {\n if (this.sizesConfig.enabled) {\n layout([this.sizesConfig]);\n }\n\n return this;\n },\n\n /**\n * Handler for type select.\n *\n * @param {String} inputType - changed.\n */\n onInputTypeChange: function (inputType) {\n if (this.defaultRecords.moreThanOne && (inputType === 'radio' || inputType === 'select')) {\n _.each(this.defaultRecords.use, function (index, counter) {\n this.source.set(\n this.dataScope + '.bundle_selections.' + index + '.' + this.isDefaultFieldScope,\n counter ? '0' : '1'\n );\n }.bind(this));\n }\n },\n\n /**\n * Handler for is_default field.\n *\n * @param {Object} data - changed data.\n */\n onIsDefaultValue: function (data) {\n var cb,\n use = 0;\n\n this.defaultRecords.use = [];\n\n cb = function (elem, key) {\n\n if (~~elem) {\n this.defaultRecords.use.push(key);\n use++;\n }\n\n this.defaultRecords.moreThanOne = use > 1;\n }.bind(this);\n\n _.each(data, cb);\n },\n\n /**\n * Initialize elements from grid\n *\n * @param {Array} data\n *\n * @returns {Object} Chainable.\n */\n initElements: function (data) {\n var newData = this.getNewData(data),\n recordIndex;\n\n this.parsePagesData(data);\n\n if (newData.length) {\n if (this.insertData().length) {\n recordIndex = data.length - newData.length - 1;\n\n _.each(newData, function (newRecord) {\n this.processingAddChild(newRecord, ++recordIndex, newRecord[this.identificationProperty]);\n }, this);\n }\n }\n\n return this;\n },\n\n /**\n * Mapping value from grid\n *\n * @param {Array} data\n */\n mappingValue: function (data) {\n if (_.isEmpty(data)) {\n return;\n }\n\n this._super();\n },\n\n /**\n * Handles changes of the page size.\n */\n onPageSizeChange: function () {\n resolver(function () {\n if (this.elems().length) {\n this.reload();\n }\n }, this);\n }\n });\n});\n","Magento_Bundle/js/components/bundle-dynamic-rows.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'underscore',\n 'mageUtils',\n 'uiRegistry',\n 'Magento_Ui/js/dynamic-rows/dynamic-rows'\n], function (_, utils, registry, dynamicRows) {\n 'use strict';\n\n return dynamicRows.extend({\n defaults: {\n label: '',\n collapsibleHeader: true,\n columnsHeader: false,\n deleteProperty: false,\n addButton: false\n },\n\n /**\n * Set new data to dataSource,\n * delete element\n *\n * @param {Array} data - record data\n */\n _updateData: function (data) {\n var elems = _.clone(this.elems()),\n path,\n dataArr,\n optionBaseData;\n\n dataArr = this.recordData.splice(this.startIndex, this.recordData().length - this.startIndex);\n dataArr.splice(0, this.pageSize);\n elems = _.sortBy(this.elems(), function (elem) {\n return ~~elem.index;\n });\n\n data.concat(dataArr).forEach(function (rec, idx) {\n if (elems[idx]) {\n elems[idx].recordId = rec[this.identificationProperty];\n }\n\n if (!rec.position) {\n rec.position = this.maxPosition;\n this.setMaxPosition();\n }\n\n path = this.dataScope + '.' + this.index + '.' + (this.startIndex + idx);\n optionBaseData = _.pick(rec, function (value) {\n return !_.isObject(value);\n });\n this.source.set(path, optionBaseData);\n this.source.set(path + '.bundle_button_proxy', []);\n this.source.set(path + '.bundle_selections', []);\n this.removeBundleItemsFromOption(idx);\n _.each(rec['bundle_selections'], function (obj, index) {\n this.source.set(path + '.bundle_button_proxy' + '.' + index, rec['bundle_button_proxy'][index]);\n this.source.set(path + '.bundle_selections' + '.' + index, obj);\n }, this);\n }, this);\n\n this.elems(elems);\n },\n\n /**\n * Removes nested dynamic-rows-grid rendered records from option\n *\n * @param {Number|String} index - element index\n */\n removeBundleItemsFromOption: function (index) {\n var bundleSelections = registry.get(this.name + '.' + index + '.' + this.bundleSelectionsName),\n bundleSelectionsLength = (bundleSelections.elems() || []).length,\n i;\n\n if (bundleSelectionsLength) {\n for (i = 0; i < bundleSelectionsLength; i++) {\n bundleSelections.elems()[0].destroy();\n }\n }\n },\n\n /**\n * {@inheritdoc}\n */\n processingAddChild: function (ctx, index, prop) {\n var recordIds = _.map(this.recordData(), function (rec) {\n return parseInt(rec['record_id'], 10);\n }),\n maxRecordId = _.max(recordIds);\n\n prop = maxRecordId > -1 ? maxRecordId + 1 : prop;\n this._super(ctx, index, prop);\n }\n });\n});\n","Magento_Bundle/js/components/bundle-input-type.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @deprecated Not used anymore\n * @see Magento_Bundle/js/components/bundle-record\n * @see Magento_Bundle/js/components/bundle-checkbox\n */\ndefine([\n 'Magento_Ui/js/form/element/select',\n 'uiRegistry'\n], function (Select, registry) {\n 'use strict';\n\n return Select.extend({\n defaults: {\n previousType: '',\n parentContainer: '',\n selections: '',\n targetIndex: '',\n typeMap: {}\n },\n\n /**\n * @inheritdoc\n */\n onUpdate: function () {\n var type = this.typeMap[this.value()];\n\n if (type !== this.previousType) {\n this.previousType = type;\n this.processSelections(type === 'radio');\n }\n\n this._super();\n },\n\n /**\n * Toggle 'User Defined' column and clears values\n * @param {Boolean} isRadio\n */\n processSelections: function (isRadio) {\n var records = registry.get(this.retrieveParentName(this.parentContainer) + '.' + this.selections),\n checkedFound = false;\n\n records.elems.each(function (record) {\n record.elems.filter(function (comp) {\n return comp.index === this.userDefinedIndex;\n }, this).each(function (comp) {\n comp.visible(isRadio);\n });\n\n if (isRadio) {\n record.elems.filter(function (comp) {\n return comp.index === this.isDefaultIndex;\n }, this).each(function (comp) {\n if (comp.checked()) {\n if (checkedFound) {\n comp.clearing = true;\n comp.clear();\n comp.clearing = false;\n }\n\n checkedFound = true;\n }\n });\n }\n }, this);\n },\n\n /**\n * Retrieve name for the most global parent with provided index.\n *\n * @param {String} parent - parent name.\n * @returns {String}\n */\n retrieveParentName: function (parent) {\n return this.name.replace(new RegExp('^(.+?\\\\.)?' + parent + '\\\\..+'), '$1' + parent);\n }\n });\n});\n","Magento_Bundle/js/components/bundle-record.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n 'Magento_Ui/js/dynamic-rows/record',\n 'uiRegistry'\n], function (Record, registry) {\n 'use strict';\n\n return Record.extend({\n /**\n * @param {String} val - type of Input Type\n */\n onTypeChanged: function (val) {\n var columnVisibility = !(val === 'multi' || val === 'checkbox');\n\n registry.async(this.name + '.' + 'selection_can_change_qty')(function (elem) {\n elem.visible(columnVisibility);\n });\n }\n });\n});\n","Magento_Email/js/variables.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/* global Variables, updateElementAtCursor */\ndefine([\n 'jquery',\n 'mage/translate',\n 'Magento_Ui/js/modal/modal',\n 'jquery/ui',\n 'prototype'\n], function (jQuery, $t) {\n 'use strict';\n\n window.Variables = {\n textareaElementId: null,\n variablesContent: null,\n dialogWindow: null,\n dialogWindowId: 'variables-chooser',\n overlayShowEffectOptions: null,\n overlayHideEffectOptions: null,\n insertFunction: 'Variables.insertVariable',\n variablesValue: [],\n\n /**\n * @param {*} textareaElementId\n * @param {Function} insertFunction\n */\n init: function (textareaElementId, insertFunction) {\n if ($(textareaElementId)) {\n this.textareaElementId = textareaElementId;\n }\n\n if (insertFunction) {\n this.insertFunction = insertFunction;\n }\n },\n\n /**\n * reset data.\n */\n resetData: function () {\n this.variablesContent = null;\n this.dialogWindow = null;\n },\n\n /**\n * @param {Object} variables\n */\n openVariableChooser: function (variables) {\n if (this.variablesContent == null && variables) {\n this.variablesContent = '<ul class=\"insert-variable\">';\n variables.each(function (variableGroup) {\n if (variableGroup.label && variableGroup.value) {\n this.variablesContent += '<li><b>' + variableGroup.label.escapeHTML() + '</b></li>';\n variableGroup.value.each(function (variable) {\n if (variable.value && variable.label) {\n this.variablesValue.push(variable.value);\n this.variablesContent += '<li>' +\n this.prepareVariableRow(this.variablesValue.length, variable.label) + '</li>';\n }\n }.bind(this));\n }\n }.bind(this));\n this.variablesContent += '</ul>';\n }\n\n if (this.variablesContent) {\n this.openDialogWindow(this.variablesContent);\n }\n },\n\n /**\n * @param {*} variablesContent\n */\n openDialogWindow: function (variablesContent) {\n var windowId = this.dialogWindowId;\n\n jQuery('<div id=\"' + windowId + '\">' + variablesContent + '</div>').modal({\n title: $t('Insert Variable...'),\n type: 'slide',\n buttons: [],\n\n /** @inheritdoc */\n closed: function (e, modal) {\n modal.modal.remove();\n }\n });\n\n jQuery('#' + windowId).modal('openModal');\n },\n\n /**\n * Close dialog window.\n */\n closeDialogWindow: function () {\n jQuery('#' + this.dialogWindowId).modal('closeModal');\n },\n\n /**\n * @param {Number} index\n * @param {*} varLabel\n * @return {String}\n */\n prepareVariableRow: function (index, varLabel) {\n return '<a href=\"#\" onclick=\"' +\n this.insertFunction +\n '(' +\n index +\n ');return false;\">' +\n varLabel.escapeHTML() +\n '</a>';\n },\n\n /**\n * @param {*} variable\n */\n insertVariable: function (variable) {\n var windowId = this.dialogWindowId,\n textareaElm, scrollPos;\n\n jQuery('#' + windowId).modal('closeModal');\n textareaElm = $(this.textareaElementId);\n\n if (textareaElm) {\n scrollPos = textareaElm.scrollTop;\n\n if (!isNaN(variable)) {\n updateElementAtCursor(textareaElm, Variables.variablesValue[variable - 1]);\n } else {\n updateElementAtCursor(textareaElm, variable);\n }\n textareaElm.focus();\n textareaElm.scrollTop = scrollPos;\n jQuery(textareaElm).trigger('change');\n textareaElm = null;\n }\n }\n };\n\n window.MagentovariablePlugin = {\n editor: null,\n variables: null,\n textareaId: null,\n\n /**\n * @param {*} editor\n */\n setEditor: function (editor) {\n this.editor = editor;\n },\n\n /**\n * @param {String} url\n * @param {*} textareaId\n */\n loadChooser: function (url, textareaId) {\n this.textareaId = textareaId;\n\n if (this.variables == null) {\n new Ajax.Request(url, {\n parameters: {},\n onComplete: function (transport) {\n if (transport.responseText.isJSON()) {\n Variables.init(null, 'MagentovariablePlugin.insertVariable');\n this.variables = transport.responseText.evalJSON();\n this.openChooser(this.variables);\n }\n }.bind(this)\n });\n } else {\n this.openChooser(this.variables);\n }\n },\n\n /**\n * @param {*} variables\n */\n openChooser: function (variables) {\n Variables.openVariableChooser(variables);\n },\n\n /**\n * @param {*} value\n */\n insertVariable: function (value) {\n if (this.textareaId) {\n Variables.init(this.textareaId);\n Variables.insertVariable(value);\n } else {\n Variables.closeDialogWindow();\n this.editor.execCommand('mceInsertContent', false, value);\n }\n }\n };\n});\n","Magento_Ui/js/block-loader.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'ko',\n 'jquery',\n 'Magento_Ui/js/lib/knockout/template/loader',\n 'mage/template'\n], function (ko, $, templateLoader, template) {\n 'use strict';\n\n var blockLoaderTemplatePath = 'ui/block-loader',\n blockContentLoadingClass = '_block-content-loading',\n blockLoader,\n blockLoaderClass,\n blockLoaderElement = $.Deferred(),\n loaderImageHref = $.Deferred();\n\n templateLoader.loadTemplate(blockLoaderTemplatePath).done(function (blockLoaderTemplate) {\n loaderImageHref.done(function (loaderHref) {\n blockLoader = template(blockLoaderTemplate.trim(), {\n loaderImageHref: loaderHref\n });\n blockLoader = $(blockLoader);\n blockLoaderClass = '.' + blockLoader.attr('class');\n blockLoaderElement.resolve();\n });\n });\n\n /**\n * Helper function to check if blockContentLoading class should be applied.\n * @param {Object} element\n * @returns {Boolean}\n */\n function isLoadingClassRequired(element) {\n var position = element.css('position');\n\n if (position === 'absolute' || position === 'fixed') {\n return false;\n }\n\n return true;\n }\n\n /**\n * Add loader to block.\n * @param {Object} element\n */\n function addBlockLoader(element) {\n element.find(':focus').trigger('blur');\n element.find('input:disabled, select:disabled').addClass('_disabled');\n element.find('input, select').prop('disabled', true);\n\n if (isLoadingClassRequired(element)) {\n element.addClass(blockContentLoadingClass);\n }\n element.append(blockLoader.clone());\n }\n\n /**\n * Remove loader from block.\n * @param {Object} element\n */\n function removeBlockLoader(element) {\n if (!element.has(blockLoaderClass).length) {\n return;\n }\n element.find(blockLoaderClass).remove();\n element.find('input:not(\"._disabled\"), select:not(\"._disabled\")').prop('disabled', false);\n element.find('input:disabled, select:disabled').removeClass('_disabled');\n element.removeClass(blockContentLoadingClass);\n }\n\n return function (loaderHref) {\n loaderImageHref.resolve(loaderHref);\n ko.bindingHandlers.blockLoader = {\n /**\n * Process loader for block\n * @param {String} element\n * @param {Boolean} displayBlockLoader\n */\n update: function (element, displayBlockLoader) {\n element = $(element);\n\n if (ko.unwrap(displayBlockLoader())) {\n blockLoaderElement.done(addBlockLoader(element));\n } else {\n blockLoaderElement.done(removeBlockLoader(element));\n }\n }\n };\n };\n});\n","Magento_Ui/js/form/button-adapter.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n 'uiClass',\n 'jquery',\n 'underscore',\n 'uiRegistry'\n], function (Class, $, _, registry) {\n 'use strict';\n\n return Class.extend({\n\n /**\n * Initialize actions and adapter.\n *\n * @param {Object} config\n * @param {Element} elem\n * @returns {Object}\n */\n initialize: function (config, elem) {\n return this._super()\n .initActions()\n .initAdapter(elem);\n },\n\n /**\n * Creates callback from declared actions.\n *\n * @returns {Object}\n */\n initActions: function () {\n var callbacks = [];\n\n _.each(this.actions, function (action) {\n callbacks.push({\n action: registry.async(action.targetName),\n args: _.union([action.actionName], action.params)\n });\n });\n\n /**\n * Callback function.\n */\n this.callback = function () {\n _.each(callbacks, function (callback) {\n callback.action.apply(callback.action, callback.args);\n });\n };\n\n return this;\n },\n\n /**\n * Attach callback handler on button.\n *\n * @param {Element} elem\n */\n initAdapter: function (elem) {\n $(elem).on('click', this.callback);\n\n return this;\n }\n });\n});\n","Magento_Ui/js/form/switcher.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n 'underscore',\n 'uiRegistry',\n 'uiClass'\n], function (_, registry, Class) {\n 'use strict';\n\n return Class.extend({\n defaults: {\n rules: []\n },\n\n /**\n * Initializes instance of a DataSwitcher.\n *\n * @returns {DataSwitcher} Chainable.\n */\n initialize: function () {\n this._super()\n .initRules();\n\n return this;\n },\n\n /**\n *\n * @returns {DataSwitcher} Chainable.\n */\n initRules: function () {\n this.rules.forEach(this.initRule, this);\n\n return this;\n },\n\n /**\n *\n * @param {Object} rule - Rule definition.\n * @returns {DataSwitcher} Chainable.\n */\n initRule: function (rule) {\n var handler = this.onValueChange.bind(this, rule);\n\n if (!rule.target) {\n rule.target = this.target;\n }\n\n if (!rule.property) {\n rule.property = this.property;\n }\n\n registry.get(rule.target, function (target) {\n this.applyRule(rule, target.get(rule.property));\n target.on(rule.property, handler);\n }.bind(this));\n\n return this;\n },\n\n /**\n *\n * @param {Object} rule - Rule definition.\n * @returns {DataSwitcher} Chainable.\n */\n addRule: function (rule) {\n this.rules.push(rule);\n this.initRule(rule);\n\n return this;\n },\n\n /**\n *\n * @param {Object} rule - Rule object.\n * @param {*} value - Current value associated with a rule.\n */\n applyRule: function (rule, value) {\n var actions = rule.actions;\n\n //TODO Refactor this logic in scope of MAGETWO-48585\n /* eslint-disable eqeqeq */\n if (rule.value != value) {\n return;\n } else if (rule.strict) {\n return;\n }\n\n /* eslint-enable eqeqeq */\n actions.forEach(this.applyAction, this);\n },\n\n /**\n *\n * @param {Object} action - Action object.\n */\n applyAction: function (action) {\n registry.get(action.target, function (target) {\n var callback = target[action.callback];\n\n callback.apply(target, action.params || []);\n });\n },\n\n /**\n *\n * @param {Object} rule - Rules object.\n * @param {*} value - Current value associated with a rule.\n */\n onValueChange: function (rule, value) {\n this.applyRule(rule, value);\n }\n });\n});\n","Magento_Ui/js/form/form.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n 'underscore',\n 'Magento_Ui/js/lib/spinner',\n 'rjsResolver',\n './adapter',\n 'uiCollection',\n 'mageUtils',\n 'jquery',\n 'Magento_Ui/js/core/app',\n 'mage/validation'\n], function (_, loader, resolver, adapter, Collection, utils, $, app) {\n 'use strict';\n\n /**\n * Format params\n *\n * @param {Object} params\n * @returns {Array}\n */\n function prepareParams(params) {\n var result = '?';\n\n _.each(params, function (value, key) {\n result += key + '=' + value + '&';\n });\n\n return result.slice(0, -1);\n }\n\n /**\n * Collect form data.\n *\n * @param {Array} items\n * @returns {Object}\n */\n function collectData(items) {\n var result = {},\n name;\n\n items = Array.prototype.slice.call(items);\n\n items.forEach(function (item) {\n switch (item.type) {\n case 'checkbox':\n result[item.name] = +!!item.checked;\n break;\n\n case 'radio':\n if (item.checked) {\n result[item.name] = item.value;\n }\n break;\n\n case 'select-multiple':\n name = item.name.substring(0, item.name.length - 2); //remove [] from the name ending\n result[name] = _.pluck(item.selectedOptions, 'value');\n break;\n\n default:\n result[item.name] = item.value;\n }\n });\n\n return result;\n }\n\n /**\n * Makes ajax request\n *\n * @param {Object} params\n * @param {Object} data\n * @param {String} url\n * @returns {*}\n */\n function makeRequest(params, data, url) {\n var save = $.Deferred();\n\n data = utils.serialize(data);\n data['form_key'] = window.FORM_KEY;\n\n if (!url) {\n save.resolve();\n }\n\n $('body').trigger('processStart');\n\n $.ajax({\n url: url + prepareParams(params),\n data: data,\n dataType: 'json',\n\n /**\n * Success callback.\n * @param {Object} resp\n * @returns {Boolean}\n */\n success: function (resp) {\n if (resp.ajaxExpired) {\n window.location.href = resp.ajaxRedirect;\n }\n\n if (!resp.error) {\n save.resolve(resp);\n\n return true;\n }\n\n $('body').notification('clear');\n $.each(resp.messages, function (key, message) {\n $('body').notification('add', {\n error: resp.error,\n message: message,\n\n /**\n * Inserts message on page\n * @param {String} msg\n */\n insertMethod: function (msg) {\n $('.page-main-actions').after(msg);\n }\n });\n });\n },\n\n /**\n * Complete callback.\n */\n complete: function () {\n $('body').trigger('processStop');\n }\n });\n\n return save.promise();\n }\n\n /**\n * Check if fields is valid.\n *\n * @param {Array}items\n * @returns {Boolean}\n */\n function isValidFields(items) {\n var result = true;\n\n _.each(items, function (item) {\n if (!$.validator.validateSingleElement(item)) {\n result = false;\n }\n });\n\n return result;\n }\n\n return Collection.extend({\n defaults: {\n additionalFields: [],\n additionalInvalid: false,\n selectorPrefix: '.page-content',\n messagesClass: 'messages',\n errorClass: '.admin__field._error',\n eventPrefix: '.${ $.index }',\n ajaxSave: false,\n ajaxSaveType: 'default',\n imports: {\n reloadUrl: '${ $.provider}:reloadUrl'\n },\n listens: {\n selectorPrefix: 'destroyAdapter initAdapter',\n '${ $.name }.${ $.reloadItem }': 'params.set reload'\n },\n exports: {\n selectorPrefix: '${ $.provider }:client.selectorPrefix',\n messagesClass: '${ $.provider }:client.messagesClass'\n }\n },\n\n /** @inheritdoc */\n initialize: function () {\n this._super()\n .initAdapter();\n\n resolver(this.hideLoader, this);\n\n return this;\n },\n\n /** @inheritdoc */\n initObservable: function () {\n return this._super()\n .observe([\n 'responseData',\n 'responseStatus'\n ]);\n },\n\n /** @inheritdoc */\n initConfig: function () {\n this._super();\n\n this.selector = '[data-form-part=' + this.namespace + ']';\n\n return this;\n },\n\n /**\n * Initialize adapter handlers.\n *\n * @returns {Object}\n */\n initAdapter: function () {\n adapter.on({\n 'reset': this.reset.bind(this),\n 'save': this.save.bind(this, true, {}),\n 'saveAndContinue': this.save.bind(this, false, {})\n }, this.selectorPrefix, this.eventPrefix);\n\n return this;\n },\n\n /**\n * Destroy adapter handlers.\n *\n * @returns {Object}\n */\n destroyAdapter: function () {\n adapter.off([\n 'reset',\n 'save',\n 'saveAndContinue'\n ], this.eventPrefix);\n\n return this;\n },\n\n /**\n * Hide loader.\n *\n * @returns {Object}\n */\n hideLoader: function () {\n loader.get(this.name).hide();\n\n return this;\n },\n\n /**\n * Validate and save form.\n *\n * @param {String} redirect\n * @param {Object} data\n */\n save: function (redirect, data) {\n this.validate();\n\n if (!this.additionalInvalid && !this.source.get('params.invalid')) {\n this.setAdditionalData(data)\n .submit(redirect);\n } else {\n this.focusInvalid();\n }\n },\n\n /**\n * Tries to set focus on first invalid form field.\n *\n * @returns {Object}\n */\n focusInvalid: function () {\n var invalidField = _.find(this.delegate('checkInvalid'));\n\n if (!_.isUndefined(invalidField) && _.isFunction(invalidField.focused)) {\n invalidField.focused(true);\n }\n\n return this;\n },\n\n /**\n * Set additional data to source before form submit and after validation.\n *\n * @param {Object} data\n * @returns {Object}\n */\n setAdditionalData: function (data) {\n _.each(data, function (value, name) {\n this.source.set('data.' + name, value);\n }, this);\n\n return this;\n },\n\n /**\n * Submits form\n *\n * @param {String} redirect\n */\n submit: function (redirect) {\n var additional = collectData(this.additionalFields),\n source = this.source;\n\n _.each(additional, function (value, name) {\n source.set('data.' + name, value);\n });\n\n source.save({\n redirect: redirect,\n ajaxSave: this.ajaxSave,\n ajaxSaveType: this.ajaxSaveType,\n response: {\n data: this.responseData,\n status: this.responseStatus\n },\n attributes: {\n id: this.namespace\n }\n });\n },\n\n /**\n * Validates each element and returns true, if all elements are valid.\n */\n validate: function () {\n this.additionalFields = document.querySelectorAll(this.selector);\n this.source.set('params.invalid', false);\n this.source.trigger('data.validate');\n this.set('additionalInvalid', !isValidFields(this.additionalFields));\n },\n\n /**\n * Trigger reset form data.\n */\n reset: function () {\n this.source.trigger('data.reset');\n $('[data-bind*=datepicker]').val('');\n },\n\n /**\n * Trigger overload form data.\n */\n overload: function () {\n this.source.trigger('data.overload');\n },\n\n /**\n * Updates data from server.\n */\n reload: function () {\n makeRequest(this.params, this.data, this.reloadUrl).then(function (data) {\n app(data, true);\n });\n }\n });\n});\n","Magento_Ui/js/form/client.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'jquery',\n 'underscore',\n 'mageUtils',\n 'uiClass'\n], function ($, _, utils, Class) {\n 'use strict';\n\n /**\n * Before save validate request.\n *\n * @param {Object} data\n * @param {String} url\n * @param {String} selectorPrefix\n * @param {String} messagesClass\n * @returns {*}\n */\n function beforeSave(data, url, selectorPrefix, messagesClass) {\n var save = $.Deferred();\n\n data = utils.serialize(utils.filterFormData(data));\n data['form_key'] = window.FORM_KEY;\n\n if (!url || url === 'undefined') {\n return save.resolve();\n }\n\n $('body').trigger('processStart');\n\n $.ajax({\n url: url,\n data: data,\n\n /**\n * Success callback.\n * @param {Object} resp\n * @returns {Boolean}\n */\n success: function (resp) {\n if (!resp.error) {\n save.resolve();\n\n return true;\n }\n\n $('body').notification('clear');\n $.each(resp.messages || [resp.message] || [], function (key, message) {\n $('body').notification('add', {\n error: resp.error,\n message: message,\n\n /**\n * Insert method.\n *\n * @param {String} msg\n */\n insertMethod: function (msg) {\n var $wrapper = $('<div></div>').addClass(messagesClass).html(msg);\n\n $('.page-main-actions', selectorPrefix).after($wrapper);\n $('html, body').animate({\n scrollTop: $('.page-main-actions', selectorPrefix).offset().top\n });\n }\n });\n });\n },\n\n /**\n * Complete callback.\n */\n complete: function () {\n $('body').trigger('processStop');\n }\n });\n\n return save.promise();\n }\n\n return Class.extend({\n\n /**\n * Assembles data and submits it using 'utils.submit' method\n */\n save: function (data, options) {\n var url = this.urls.beforeSave,\n save = this._save.bind(this, data, options);\n\n beforeSave(data, url, this.selectorPrefix, this.messagesClass).then(save);\n\n return this;\n },\n\n /**\n * Save data.\n *\n * @param {Object} data\n * @param {Object} options\n * @returns {Object}\n * @private\n */\n _save: function (data, options) {\n var url = this.urls.save;\n\n $('body').trigger('processStart');\n options = options || {};\n\n if (!options.redirect) {\n url += 'back/edit';\n }\n\n if (options.ajaxSave) {\n utils.ajaxSubmit({\n url: url,\n data: data\n }, options);\n\n $('body').trigger('processStop');\n\n return this;\n }\n\n utils.submit({\n url: url,\n data: data\n }, options.attributes);\n\n return this;\n }\n });\n});\n","Magento_Ui/js/form/adapter.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n 'jquery',\n 'underscore',\n 'Magento_Ui/js/form/adapter/buttons'\n], function ($, _, buttons) {\n 'use strict';\n\n var selectorPrefix = '',\n eventPrefix;\n\n /**\n * Initialize listener.\n *\n * @param {Function} callback\n * @param {String} action\n */\n function initListener(callback, action) {\n var selector = selectorPrefix ? selectorPrefix + ' ' + buttons[action] : buttons[action],\n elem = $(selector)[0];\n\n if (!elem) {\n return;\n }\n\n if (elem.onclick) {\n elem.onclick = null;\n }\n\n $(elem).on('click' + eventPrefix, callback);\n }\n\n /**\n * Destroy listener.\n *\n * @param {String} action\n */\n function destroyListener(action) {\n var selector = selectorPrefix ? selectorPrefix + ' ' + buttons[action] : buttons[action],\n elem = $(selector)[0];\n\n if (!elem) {\n return;\n }\n\n if (elem.onclick) {\n elem.onclick = null;\n }\n\n $(elem).off('click' + eventPrefix);\n }\n\n return {\n\n /**\n * Attaches events handlers.\n *\n * @param {Object} handlers\n * @param {String} selectorPref\n * @param {String} eventPref\n */\n on: function (handlers, selectorPref, eventPref) {\n selectorPrefix = selectorPrefix || selectorPref;\n eventPrefix = eventPref;\n _.each(handlers, initListener);\n selectorPrefix = '';\n },\n\n /**\n * Removes events handlers.\n *\n * @param {Object} handlers\n * @param {String} eventPref\n */\n off: function (handlers, eventPref) {\n eventPrefix = eventPref;\n _.each(handlers, destroyListener);\n }\n };\n});\n","Magento_Ui/js/form/provider.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n 'underscore',\n 'uiElement',\n './client',\n 'mageUtils'\n], function (_, Element, Client, utils) {\n 'use strict';\n\n return Element.extend({\n defaults: {\n clientConfig: {\n urls: {\n save: '${ $.submit_url }',\n beforeSave: '${ $.validate_url }'\n }\n },\n ignoreTmpls: {\n data: true\n }\n },\n\n /**\n * Initializes provider component.\n *\n * @returns {Provider} Chainable.\n */\n initialize: function () {\n this._super()\n .initClient();\n\n return this;\n },\n\n /**\n * Initializes client component.\n *\n * @returns {Provider} Chainable.\n */\n initClient: function () {\n this.client = new Client(this.clientConfig);\n\n return this;\n },\n\n /**\n * Saves currently available data.\n *\n * @param {Object} [options] - Addtitional request options.\n * @returns {Provider} Chainable.\n */\n save: function (options) {\n var data = this.get('data');\n\n this.client.save(data, options);\n\n return this;\n },\n\n /**\n * Update data that stored in provider.\n *\n * @param {Boolean} isProvider\n * @param {Object} newData\n * @param {Object} oldData\n *\n * @returns {Provider}\n */\n updateConfig: function (isProvider, newData, oldData) {\n if (isProvider === true) {\n this.setData(oldData, newData, this);\n }\n\n return this;\n },\n\n /**\n * Set data to provider based on current data.\n *\n * @param {Object} oldData\n * @param {Object} newData\n * @param {Provider} current\n * @param {String} parentPath\n */\n setData: function (oldData, newData, current, parentPath) {\n _.each(newData, function (val, key) {\n if (_.isObject(val) || _.isArray(val)) {\n this.setData(oldData[key], val, current[key], utils.fullPath(parentPath, key));\n } else if (val != oldData[key] && oldData[key] == current[key]) {//eslint-disable-line eqeqeq\n this.set(utils.fullPath(parentPath, key), val);\n }\n }, this);\n }\n });\n});\n","Magento_Ui/js/form/adapter/buttons.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine(function () {\n 'use strict';\n\n return {\n 'reset': '#reset',\n 'save': '#save',\n 'saveAndContinue': '#save_and_continue'\n };\n});\n","Magento_Ui/js/form/components/fieldset.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n 'Magento_Ui/js/lib/collapsible',\n 'underscore'\n], function (Collapsible, _) {\n 'use strict';\n\n return Collapsible.extend({\n defaults: {\n template: 'ui/form/fieldset',\n collapsible: false,\n changed: false,\n loading: false,\n error: false,\n opened: false,\n level: 0,\n visible: true,\n initializeFieldsetDataByDefault: false, /* Data in some fieldsets should be initialized before open */\n disabled: false,\n listens: {\n 'opened': 'onVisibilityChange'\n },\n additionalClasses: {}\n },\n\n /**\n * Extends instance with defaults. Invokes parent initialize method.\n * Calls initListeners and pushParams methods.\n */\n initialize: function () {\n _.bindAll(this, 'onChildrenUpdate', 'onChildrenError', 'onContentLoading');\n\n return this._super()\n ._setClasses();\n },\n\n /**\n * Initializes components' configuration.\n *\n * @returns {Fieldset} Chainable.\n */\n initConfig: function () {\n this._super();\n this._wasOpened = this.opened || !this.collapsible;\n\n return this;\n },\n\n /**\n * Calls initObservable of parent class.\n * Defines observable properties of instance.\n *\n * @returns {Object} Reference to instance\n */\n initObservable: function () {\n this._super()\n .observe('changed loading error visible');\n\n return this;\n },\n\n /**\n * Calls parent's initElement method.\n * Assigns callbacks on various events of incoming element.\n *\n * @param {Object} elem\n * @return {Object} - reference to instance\n */\n initElement: function (elem) {\n elem.initContainer(this);\n\n elem.on({\n 'update': this.onChildrenUpdate,\n 'loading': this.onContentLoading,\n 'error': this.onChildrenError\n });\n\n if (this.disabled) {\n try {\n elem.disabled(true);\n }\n catch (e) {\n\n }\n }\n\n return this;\n },\n\n /**\n * Is being invoked on children update.\n * Sets changed property to one incoming.\n *\n * @param {Boolean} hasChanged\n */\n onChildrenUpdate: function (hasChanged) {\n if (!hasChanged) {\n hasChanged = _.some(this.delegate('hasChanged'));\n }\n\n this.bubble('update', hasChanged);\n this.changed(hasChanged);\n },\n\n /**\n * Extends 'additionalClasses' object.\n *\n * @returns {Group} Chainable.\n */\n _setClasses: function () {\n var additional = this.additionalClasses,\n classes;\n\n if (_.isString(additional)) {\n additional = this.additionalClasses.split(' ');\n classes = this.additionalClasses = {};\n\n additional.forEach(function (name) {\n classes[name] = true;\n }, this);\n }\n\n _.extend(this.additionalClasses, {\n 'admin__collapsible-block-wrapper': this.collapsible,\n _show: this.opened,\n _hide: !this.opened,\n _disabled: this.disabled\n });\n\n return this;\n },\n\n /**\n * Handler of the \"opened\" property changes.\n *\n * @param {Boolean} isOpened\n */\n onVisibilityChange: function (isOpened) {\n if (!this._wasOpened) {\n this._wasOpened = isOpened;\n }\n },\n\n /**\n * Is being invoked on children validation error.\n * Sets error property to one incoming.\n *\n * @param {String} message - error message.\n */\n onChildrenError: function (message) {\n var hasErrors = false;\n\n if (!message) {\n hasErrors = this._isChildrenHasErrors(hasErrors, this);\n }\n\n this.error(hasErrors || message);\n\n if (hasErrors || message) {\n this.open();\n }\n },\n\n /**\n * Returns errors of children if exist\n *\n * @param {Boolean} hasErrors\n * @param {*} container\n * @return {Boolean}\n * @private\n */\n _isChildrenHasErrors: function (hasErrors, container) {\n var self = this;\n\n if (hasErrors === false && container.hasOwnProperty('elems')) {\n hasErrors = container.elems.some('error');\n\n if (hasErrors === false && container.hasOwnProperty('_elems')) {\n container._elems.forEach(function (child) {\n\n if (hasErrors === false) {\n hasErrors = self._isChildrenHasErrors(hasErrors, child);\n }\n });\n }\n }\n\n return hasErrors;\n },\n\n /**\n * Callback that sets loading property to true.\n */\n onContentLoading: function (isLoading) {\n this.loading(isLoading);\n }\n });\n});\n","Magento_Ui/js/form/components/button.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n 'uiElement',\n 'uiRegistry',\n 'uiLayout',\n 'mageUtils',\n 'underscore'\n], function (Element, registry, layout, utils, _) {\n 'use strict';\n\n return Element.extend({\n defaults: {\n buttonClasses: {},\n additionalClasses: {},\n displayArea: 'outsideGroup',\n displayAsLink: false,\n elementTmpl: 'ui/form/element/button',\n template: 'ui/form/components/button/simple',\n visible: true,\n disabled: false,\n title: '',\n buttonTextId: '',\n ariLabelledby: ''\n },\n\n /**\n * Initializes component.\n *\n * @returns {Object} Chainable.\n */\n initialize: function () {\n return this._super()\n ._setClasses()\n ._setButtonClasses();\n },\n\n /** @inheritdoc */\n initObservable: function () {\n return this._super()\n .observe([\n 'visible',\n 'disabled',\n 'title',\n 'childError'\n ]);\n },\n\n /**\n * Performs configured actions\n */\n action: function () {\n this.actions.forEach(this.applyAction, this);\n },\n\n /**\n * Apply action on target component,\n * but previously create this component from template if it is not existed\n *\n * @param {Object} action - action configuration\n */\n applyAction: function (action) {\n var targetName = action.targetName,\n params = utils.copy(action.params) || [],\n actionName = action.actionName,\n target;\n\n if (!registry.has(targetName)) {\n this.getFromTemplate(targetName);\n }\n target = registry.async(targetName);\n\n if (target && typeof target === 'function' && actionName) {\n params.unshift(actionName);\n target.apply(target, params);\n }\n },\n\n /**\n * Create target component from template\n *\n * @param {Object} targetName - name of component,\n * that supposed to be a template and need to be initialized\n */\n getFromTemplate: function (targetName) {\n var parentName = targetName.split('.'),\n index = parentName.pop(),\n child;\n\n parentName = parentName.join('.');\n child = utils.template({\n parent: parentName,\n name: index,\n nodeTemplate: targetName\n });\n layout([child]);\n },\n\n /**\n * Extends 'additionalClasses' object.\n *\n * @returns {Object} Chainable.\n */\n _setClasses: function () {\n if (typeof this.additionalClasses === 'string') {\n if (this.additionalClasses === '') {\n this.additionalClasses = {};\n\n return this;\n }\n\n this.additionalClasses = this.additionalClasses\n .trim()\n .split(' ')\n .reduce(function (classes, name) {\n classes[name] = true;\n\n return classes;\n }, {}\n );\n }\n\n return this;\n },\n\n /**\n * Extends 'buttonClasses' object.\n *\n * @returns {Object} Chainable.\n */\n _setButtonClasses: function () {\n var additional = this.buttonClasses;\n\n if (_.isString(additional)) {\n this.buttonClasses = {};\n\n if (additional.trim().length) {\n additional = additional.trim().split(' ');\n\n additional.forEach(function (name) {\n if (name.length) {\n this.buttonClasses[name] = true;\n }\n }, this);\n }\n }\n\n _.extend(this.buttonClasses, {\n 'action-basic': !this.displayAsLink,\n 'action-additional': this.displayAsLink\n });\n\n return this;\n }\n });\n});\n","Magento_Ui/js/form/components/tab.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n 'uiCollection'\n], function (Collection) {\n 'use strict';\n\n return Collection.extend({\n defaults: {\n uniqueProp: 'active',\n active: false,\n wasActivated: false\n },\n\n /**\n * Extends instance with defaults. Invokes parent initialize method.\n * Calls initListeners and pushParams methods.\n */\n initialize: function () {\n this._super()\n .setUnique();\n },\n\n /**\n * Calls initObservable of parent class.\n * Defines observable properties of instance.\n * @return {Object} - reference to instance\n */\n initObservable: function () {\n this._super()\n .observe('active wasActivated');\n\n return this;\n },\n\n /**\n * Sets active property to true, then invokes pushParams method.\n */\n activate: function () {\n this.active(true);\n this.wasActivated(true);\n\n this.setUnique();\n\n return true;\n }\n });\n});\n","Magento_Ui/js/form/components/html.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n 'jquery',\n 'underscore',\n 'uiComponent'\n], function ($, _, Component) {\n 'use strict';\n\n return Component.extend({\n defaults: {\n content: '',\n showSpinner: false,\n loading: false,\n visible: true,\n template: 'ui/content/content',\n additionalClasses: {},\n ignoreTmpls: {\n content: true\n }\n },\n\n /**\n * Extends instance with default config, calls 'initialize' method of\n * parent, calls 'initAjaxConfig'\n */\n initialize: function () {\n _.bindAll(this, 'onContainerToggle', 'onDataLoaded');\n\n this._super()\n ._setClasses()\n .initAjaxConfig();\n\n return this;\n },\n\n /**\n * Calls 'initObservable' method of parent, initializes observable\n * properties of instance\n *\n * @return {Object} - reference to instance\n */\n initObservable: function () {\n this._super()\n .observe('content loading visible');\n\n return this;\n },\n\n /**\n * Extends 'additionalClasses' object.\n *\n * @returns {Group} Chainable.\n */\n _setClasses: function () {\n var additional = this.additionalClasses,\n classes;\n\n if (_.isString(additional)) {\n additional = this.additionalClasses.split(' ');\n classes = this.additionalClasses = {};\n\n additional.forEach(function (name) {\n classes[name] = true;\n }, this);\n }\n\n _.extend(this.additionalClasses, {\n 'admin__scope-old': !!additional\n });\n\n return this;\n },\n\n /** @inheritdoc */\n initContainer: function (parent) {\n this._super();\n\n parent.on('active', this.onContainerToggle);\n\n return this;\n },\n\n /**\n * Initializes default ajax config on instance\n *\n * @return {Object} - reference to instance\n */\n initAjaxConfig: function () {\n this.ajaxConfig = {\n url: this.url,\n data: {\n FORM_KEY: window.FORM_KEY\n },\n success: this.onDataLoaded\n };\n\n return this;\n },\n\n /**\n * Calls 'loadData' if both 'active' variable and 'shouldLoad'\n * property are truthy\n *\n * @param {Boolean} active\n */\n onContainerToggle: function (active) {\n if (active && this.shouldLoad()) {\n this.loadData();\n }\n },\n\n /**\n * Defines if instance has 'content' property defined.\n *\n * @return {Boolean} [description]\n */\n hasData: function () {\n return !!this.content();\n },\n\n /**\n * Defines if instance should load external data\n *\n * @return {Boolean}\n */\n shouldLoad: function () {\n return this.url && !this.hasData() && !this.loading();\n },\n\n /**\n * Sets loading property to true, makes ajax call\n *\n * @return {Object} - reference to instance\n */\n loadData: function () {\n this.loading(true);\n\n $.ajax(this.ajaxConfig);\n\n return this;\n },\n\n /**\n * Ajax's request success handler. Calls 'updateContent' passing 'data'\n * to it, then sets 'loading' property to false.\n *\n * @param {String} data\n */\n onDataLoaded: function (data) {\n this.updateContent(data)\n .loading(false);\n },\n\n /**\n * Sets incoming data 'content' property's value\n *\n * @param {String} content\n * @return {Object} - reference to instance\n */\n updateContent: function (content) {\n this.content(content);\n\n return this;\n },\n\n /**\n * Content getter\n *\n * @returns {String}\n */\n getContentUnsanitizedHtml: function () {\n return this.content();\n }\n });\n});\n","Magento_Ui/js/form/components/multiline.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n './group'\n], function (Group) {\n 'use strict';\n\n return Group.extend({\n defaults: {\n links: {\n value: '${ $.provider }:${ $.dataScope }'\n }\n },\n\n /**\n * Initialize Multiline component.\n *\n * @returns {Object}\n */\n initialize: function () {\n return this._super()\n ._prepareValue();\n },\n\n /**\n * {@inheritdoc}\n */\n initObservable: function () {\n this._super()\n .observe('value');\n\n return this;\n },\n\n /**\n * Prepare value for Multiline options.\n *\n * @returns {Object} Chainable.\n * @private\n */\n _prepareValue: function () {\n var value = this.value();\n\n if (typeof value === 'string') {\n this.value(value.split('\\n'));\n }\n\n return this;\n }\n });\n});\n","Magento_Ui/js/form/components/collection.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n 'underscore',\n 'mageUtils',\n 'uiRegistry',\n 'uiComponent',\n 'uiLayout',\n 'Magento_Ui/js/modal/confirm'\n], function (_, utils, registry, Component, layout, confirm) {\n 'use strict';\n\n var childTemplate = {\n parent: '${ $.$data.name }',\n name: '${ $.$data.childIndex }',\n dataScope: '${ $.name }',\n nodeTemplate: '${ $.$data.name }.${ $.$data.itemTemplate }'\n };\n\n return Component.extend({\n defaults: {\n lastIndex: 0,\n template: 'ui/form/components/collection'\n },\n\n /**\n * Extends instance with default config, calls initialize of parent\n * class, calls initChildren method.\n */\n initialize: function () {\n this._super()\n .initChildren();\n\n return this;\n },\n\n /**\n * Activates the incoming child and triggers the update event.\n *\n * @param {Object} elem - Incoming child.\n */\n initElement: function (elem) {\n this._super();\n\n elem.activate();\n\n this.bubble('update');\n\n return this;\n },\n\n /**\n * Loops over corresponding data in data storage,\n * creates child for each and pushes it's identifier to initialItems array.\n *\n * @returns {Collection} Chainable.\n */\n initChildren: function () {\n var children = this.source.get(this.dataScope),\n initial = this.initialItems = [];\n\n _.each(children, function (item, index) {\n initial.push(index);\n this.addChild(index);\n }, this);\n\n return this;\n },\n\n /**\n * Creates new item of collection, based on incoming 'index'.\n * If not passed creates one with 'new_' prefix.\n *\n * @param {String|Object} [index] - Index of a child.\n * @returns {Collection} Chainable.\n */\n addChild: function (index) {\n this.childIndex = !_.isString(index) ?\n 'new_' + this.lastIndex++ :\n index;\n\n layout([utils.template(childTemplate, this)]);\n\n return this;\n },\n\n /**\n * Returns true if current set of items differ from initial one,\n * or if some child has been changed.\n *\n * @returns {Boolean}\n */\n hasChanged: function () {\n var initial = this.initialItems,\n current = this.elems.pluck('index'),\n changed = !utils.equalArrays(initial, current);\n\n return changed || this.elems.some(function (elem) {\n return _.some(elem.delegate('hasChanged'));\n });\n },\n\n /**\n * Initiates validation of its' children components.\n *\n * @returns {Array} An array of validation results.\n */\n validate: function () {\n var elems;\n\n this.allValid = true;\n\n elems = this.elems.sortBy(function (elem) {\n return !elem.active();\n });\n\n elems = elems.map(this._validate, this);\n\n return _.flatten(elems);\n },\n\n /**\n * Iterator function for components validation.\n * Activates first invalid child component.\n *\n * @param {Object} elem - Element to run validation on.\n * @returns {Array} An array of validation results.\n */\n _validate: function (elem) {\n var result = elem.delegate('validate'),\n invalid;\n\n invalid = _.some(result, function (item) {\n return !item.valid;\n });\n\n if (this.allValid && invalid) {\n this.allValid = false;\n\n elem.activate();\n }\n\n return result;\n },\n\n /**\n * Creates function that removes element\n * from collection using '_removeChild' method.\n * @param {Object} elem - Element that should be removed.\n * @deprecated Not used anymore\n */\n removeAddress: function (elem) {\n var self = this;\n\n confirm({\n content: this.removeMessage,\n actions: {\n /** @inheritdoc */\n confirm: function () {\n self._removeAddress(elem);\n }\n }\n });\n },\n\n /**\n * Removes element from both collection and data storage,\n * activates first element if removed one was active,\n * triggers 'update' event.\n *\n * @param {Object} elem - Element to remove.\n */\n _removeAddress: function (elem) {\n var isActive = elem.active(),\n first;\n\n elem.destroy();\n\n first = this.elems.first();\n\n if (first && isActive) {\n first.activate();\n }\n\n this.bubble('update');\n }\n });\n});\n","Magento_Ui/js/form/components/area.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n 'underscore',\n './tab'\n], function (_, Tab) {\n 'use strict';\n\n return Tab.extend({\n defaults: {\n uniqueNs: 'params.activeArea',\n template: 'ui/area',\n changed: false,\n loading: false\n },\n\n /**\n * Extends instance with defaults. Invokes parent initialize method.\n * Calls initListeners and pushParams methods.\n */\n initialize: function () {\n _.bindAll(this, 'onChildrenUpdate', 'onContentLoading');\n\n return this._super();\n },\n\n /**\n * Calls initObservable of parent class.\n * Defines observable properties of instance.\n * @return {Object} - reference to instance\n */\n initObservable: function () {\n this._super()\n .observe('changed loading');\n\n return this;\n },\n\n /**\n * Calls parent's initElement method.\n * Assigns callbacks on various events of incoming element.\n * @param {Object} elem\n * @return {Object} - reference to instance\n */\n initElement: function (elem) {\n this._super();\n\n elem.on({\n 'update': this.onChildrenUpdate,\n 'loading': this.onContentLoading\n });\n\n return this;\n },\n\n /**\n * Is being invoked on children update.\n * Sets changed property to one incoming.\n * Invokes setActive method if settings\n * contain makeVisible property set to true.\n *\n * @param {Boolean} hasChanged\n */\n onChildrenUpdate: function (hasChanged) {\n if (!hasChanged) {\n hasChanged = _.some(this.delegate('hasChanged'));\n }\n\n this.changed(hasChanged);\n },\n\n /**\n * Callback that sets loading property to true.\n */\n onContentLoading: function (isLoading) {\n this.loading(isLoading);\n }\n });\n});\n","Magento_Ui/js/form/components/insert-form.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n './insert',\n 'mageUtils',\n 'jquery'\n], function (Insert, utils, $) {\n 'use strict';\n\n /**\n * Get page actions element.\n *\n * @param {String} elem\n * @param {String} actionsClass\n * @returns {String}\n */\n function getPageActions(elem, actionsClass) {\n var el = document.createElement('div');\n\n el.innerHTML = elem;\n\n return el.getElementsByClassName(actionsClass)[0];\n }\n\n /**\n * Return element without page actions toolbar\n *\n * @param {String} elem\n * @param {String} actionsClass\n * @returns {String}\n */\n function removePageActions(elem, actionsClass) {\n var el = document.createElement('div'),\n actions;\n\n el.innerHTML = elem;\n actions = el.getElementsByClassName(actionsClass)[0];\n\n if (actions) {\n el.removeChild(actions);\n }\n\n return el.innerHTML;\n }\n\n return Insert.extend({\n defaults: {\n externalFormName: '${ $.ns }.${ $.ns }',\n pageActionsClass: 'page-actions',\n actionsContainerClass: 'page-main-actions',\n exports: {\n prefix: '${ $.externalFormName }:selectorPrefix'\n },\n imports: {\n toolbarSection: '${ $.toolbarContainer }:toolbarSection',\n prefix: '${ $.toolbarContainer }:rootSelector',\n messagesClass: '${ $.externalFormName }:messagesClass'\n },\n settings: {\n ajax: {\n ajaxSave: true,\n exports: {\n ajaxSave: '${ $.externalFormName }:ajaxSave'\n },\n imports: {\n responseStatus: '${ $.externalFormName }:responseStatus',\n responseData: '${ $.externalFormName }:responseData'\n }\n }\n },\n modules: {\n externalForm: '${ $.externalFormName }'\n }\n },\n\n /** @inheritdoc */\n initObservable: function () {\n return this._super()\n .observe('responseStatus');\n },\n\n /** @inheritdoc */\n initConfig: function (config) {\n var defaults = this.constructor.defaults;\n\n utils.extend(defaults, defaults.settings[config.formSubmitType] || {});\n\n return this._super();\n },\n\n /** @inheritdoc*/\n destroyInserted: function () {\n if (this.isRendered && this.externalForm()) {\n this.externalForm().delegate('destroy');\n this.removeActions();\n this.responseStatus(undefined);\n this.responseData = {};\n }\n\n return this._super();\n },\n\n /** @inheritdoc */\n onRender: function (data) {\n var actions = getPageActions(data, this.pageActionsClass);\n\n if (!data.length) {\n return this;\n }\n data = removePageActions(data, this.pageActionsClass);\n this.renderActions(actions);\n this._super(data);\n },\n\n /**\n * Insert actions in toolbar.\n *\n * @param {String} actions\n */\n renderActions: function (actions) {\n var $container = $('<div></div>');\n\n $container\n .addClass(this.actionsContainerClass)\n .append(actions);\n\n this.formHeader = $container;\n\n $(this.toolbarSection).append(this.formHeader);\n },\n\n /**\n * Remove actions toolbar.\n */\n removeActions: function () {\n $(this.formHeader).siblings('.' + this.messagesClass).remove();\n $(this.formHeader).remove();\n this.formHeader = $();\n },\n\n /**\n * Reset external form data.\n */\n resetForm: function () {\n if (this.externalSource()) {\n this.externalSource().trigger('data.reset');\n this.responseStatus(undefined);\n }\n }\n });\n});\n","Magento_Ui/js/form/components/tab_group.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n 'underscore',\n 'Magento_Ui/js/lib/collapsible'\n], function (_, Collapsible) {\n 'use strict';\n\n return Collapsible.extend({\n defaults: {\n listens: {\n '${ $.provider }:data.validate': 'onValidate'\n },\n collapsible: false,\n opened: true\n },\n\n /**\n * Invokes initElement method of parent class, calls 'initActivation' method\n * passing element to it.\n * @param {Object} elem\n * @returns {Object} - reference to instance\n */\n initElement: function (elem) {\n this._super()\n .initActivation(elem);\n\n return this;\n },\n\n /**\n * Activates element if one is first or if one has 'active' propert\n * set to true.\n *\n * @param {Object} elem\n * @returns {Object} - reference to instance\n */\n initActivation: function (elem) {\n var elems = this.elems(),\n isFirst = !elems.indexOf(elem);\n\n if (isFirst || elem.active()) {\n elem.activate();\n }\n\n return this;\n },\n\n /**\n * Delegates 'validate' method on element, then reads 'invalid' property\n * of params storage, and if defined, activates element, sets\n * 'allValid' property of instance to false and sets invalid's\n * 'focused' property to true.\n *\n * @param {Object} elem\n */\n validate: function (elem) {\n var result = elem.delegate('validate'),\n invalid;\n\n invalid = _.find(result, function (item) {\n return typeof item !== 'undefined' && !item.valid;\n });\n\n if (invalid) {\n elem.activate();\n invalid.target.focused(true);\n }\n\n return invalid;\n },\n\n /**\n * Sets 'allValid' property of instance to true, then calls 'validate' method\n * of instance for each element.\n */\n onValidate: function () {\n this.elems.sortBy(function (elem) {\n return !elem.active();\n }).some(this.validate, this);\n }\n });\n});\n","Magento_Ui/js/form/components/group.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n 'underscore',\n 'uiCollection'\n], function (_, Collection) {\n 'use strict';\n\n return Collection.extend({\n defaults: {\n visible: true,\n label: '',\n showLabel: true,\n required: false,\n template: 'ui/group/group',\n fieldTemplate: 'ui/form/field',\n breakLine: true,\n validateWholeGroup: false,\n additionalClasses: {}\n },\n\n /**\n * Extends this with defaults and config.\n * Then calls initObservable, iniListenes and extractData methods.\n */\n initialize: function () {\n this._super()\n ._setClasses();\n\n return this;\n },\n\n /**\n * Calls initObservable of parent class.\n * Defines observable properties of instance.\n *\n * @return {Object} - reference to instance\n */\n initObservable: function () {\n this._super()\n .observe('visible')\n .observe({\n required: !!+this.required\n });\n\n return this;\n },\n\n /**\n * Extends 'additionalClasses' object.\n *\n * @returns {Group} Chainable.\n */\n _setClasses: function () {\n var additional = this.additionalClasses,\n classes;\n\n if (_.isString(additional)) {\n additional = this.additionalClasses.split(' ');\n classes = this.additionalClasses = {};\n\n additional.forEach(function (name) {\n classes[name] = true;\n }, this);\n }\n\n _.extend(this.additionalClasses, {\n 'admin__control-grouped': !this.breakLine,\n 'admin__control-fields': this.breakLine,\n required: this.required,\n _error: this.error,\n _disabled: this.disabled\n });\n\n return this;\n },\n\n /**\n * Defines if group has only one element.\n * @return {Boolean}\n */\n isSingle: function () {\n return this.elems.getLength() === 1;\n },\n\n /**\n * Defines if group has multiple elements.\n * @return {Boolean}\n */\n isMultiple: function () {\n return this.elems.getLength() > 1;\n },\n\n /**\n * Returns an array of child components previews.\n *\n * @returns {Array}\n */\n getPreview: function () {\n return this.elems.map('getPreview');\n }\n });\n});\n","Magento_Ui/js/form/components/collection/item.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n 'underscore',\n 'mageUtils',\n '../tab'\n], function (_, utils, Tab) {\n 'use strict';\n\n var previewConfig = {\n separator: ' ',\n prefix: ''\n };\n\n /**\n * Parses incoming data and returns result merged with default preview config\n *\n * @param {Object|String} data\n * @return {Object}\n */\n function parsePreview(data) {\n if (typeof data == 'string') {\n data = {\n items: data\n };\n }\n\n data.items = utils.stringToArray(data.items);\n\n return _.defaults(data, previewConfig);\n }\n\n return Tab.extend({\n defaults: {\n label: '',\n uniqueNs: 'activeCollectionItem',\n previewTpl: 'ui/form/components/collection/preview'\n },\n\n /**\n * Extends instance with default config, calls initializes of parent class\n */\n initialize: function () {\n _.bindAll(this, 'buildPreview', 'hasPreview');\n\n return this._super();\n },\n\n /**\n * Calls initProperties of parent class, initializes properties\n * of instance.\n *\n * @return {Object} - reference to instance\n */\n initConfig: function () {\n this._super();\n\n this.displayed = [];\n\n return this;\n },\n\n /**\n * Calls initObservable of parent class, initializes observable\n * properties of instance.\n *\n * @return {Object} - reference to instance\n */\n initObservable: function () {\n this._super()\n .observe({\n noPreview: true,\n indexed: {}\n });\n\n return this;\n },\n\n /**\n * Is being called when child element has been initialized,\n * calls initElement of parent class, binds to element's update event,\n * calls insertToArea and insertToIndexed methods passing element to it\n *\n * @param {Object} elem\n */\n initElement: function (elem) {\n this._super()\n .insertToIndexed(elem);\n\n return this;\n },\n\n /**\n * Adds element to observable indexed object of instance\n *\n * @param {Object} elem\n * @return {Object} - reference to instance\n */\n insertToIndexed: function (elem) {\n var indexed = this.indexed();\n\n indexed[elem.index] = elem;\n\n this.indexed(indexed);\n\n return this;\n },\n\n /**\n * Destroys current instance along with all of its' children.\n * Overrides base method to clear data when this method is called.\n */\n destroy: function () {\n this._super();\n this._clearData();\n },\n\n /**\n * Clears all data associated with component.\n * @private\n *\n * @returns {Item} Chainable.\n */\n _clearData: function () {\n this.source.remove(this.dataScope);\n\n return this;\n },\n\n /**\n * Formats incoming previews array via parsePreview function.\n *\n * @param {Array} previews\n * @return {Array} - formatted previews\n */\n formatPreviews: function (previews) {\n return previews.map(parsePreview);\n },\n\n /**\n * Creates string view of previews\n *\n * @param {Object} data\n * @return {Strict} - formatted preview string\n */\n buildPreview: function (data) {\n var preview = this.getPreview(data.items),\n prefix = data.prefix;\n\n return prefix + preview.join(data.separator);\n },\n\n /**\n * Defines if instance has preview for incoming data\n *\n * @param {Object} data\n * @return {Boolean}\n */\n hasPreview: function (data) {\n return !!this.getPreview(data.items).length;\n },\n\n /**\n * Creates an array of previews for elements specified in incoming\n * items array, calls updatePreview afterwards.\n *\n * @param {Array} items - An array of element's indexes.\n * @returns {Array} An array of previews.\n */\n getPreview: function (items) {\n var elems = this.indexed(),\n displayed = this.displayed,\n preview;\n\n items = items.map(function (index) {\n var elem = elems[index];\n\n preview = elem && elem.visible() ? elem.getPreview() : '';\n\n preview = Array.isArray(preview) ?\n _.compact(preview).join(', ') :\n preview;\n\n utils.toggle(displayed, index, !!preview);\n\n return preview;\n });\n\n this.noPreview(!displayed.length);\n\n return _.compact(items);\n }\n });\n});\n","Magento_Ui/js/form/element/multiselect.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n 'underscore',\n 'mageUtils',\n './select'\n], function (_, utils, Select) {\n 'use strict';\n\n return Select.extend({\n defaults: {\n size: 5,\n elementTmpl: 'ui/form/element/multiselect',\n listens: {\n value: 'setDifferedFromDefault setPrepareToSendData'\n }\n },\n\n /**\n * @inheritdoc\n */\n setInitialValue: function () {\n this._super();\n\n this.initialValue = utils.copy(this.initialValue);\n\n return this;\n },\n\n /**\n * @inheritdoc\n */\n normalizeData: function (value) {\n if (utils.isEmpty(value)) {\n value = [];\n }\n\n return _.isString(value) ? value.split(',') : value;\n },\n\n /**\n * Sets the prepared data to dataSource\n * by path, where key is component link to dataSource with\n * suffix \"-prepared-for-send\"\n *\n * @param {Array} data - current component value\n */\n setPrepareToSendData: function (data) {\n if (_.isUndefined(data) || !data.length) {\n data = '';\n }\n\n this.source.set(this.dataScope + '-prepared-for-send', data);\n },\n\n /**\n * @inheritdoc\n */\n getInitialValue: function () {\n var values = [\n this.normalizeData(this.source.get(this.dataScope)),\n this.normalizeData(this.default)\n ],\n value;\n\n values.some(function (v) {\n return _.isArray(v) && (value = utils.copy(v)) && !_.isEmpty(v);\n });\n\n return value;\n },\n\n /**\n * @inheritdoc\n */\n hasChanged: function () {\n var value = this.value(),\n initial = this.initialValue;\n\n return !utils.equalArrays(value, initial);\n },\n\n /**\n * @inheritdoc\n */\n reset: function () {\n this.value(utils.copy(this.initialValue));\n this.error(false);\n\n return this;\n },\n\n /**\n * @inheritdoc\n */\n clear: function () {\n this.value([]);\n this.error(false);\n\n return this;\n }\n });\n});\n","Magento_Ui/js/form/element/url-input.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n 'underscore',\n 'uiLayout',\n 'mage/translate',\n 'Magento_Ui/js/form/element/abstract'\n], function (_, layout, $t, Abstract) {\n 'use strict';\n\n return Abstract.extend({\n defaults: {\n linkedElement: {},\n settingTemplate: 'ui/form/element/urlInput/setting',\n typeSelectorTemplate: 'ui/form/element/urlInput/typeSelector',\n options: [],\n linkedElementInstances: {},\n //checkbox\n isDisplayAdditionalSettings: true,\n settingValue: false,\n settingLabel: $t('Open in new tab'),\n tracks: {\n linkedElement: true\n },\n baseLinkSetting: {\n namePrefix: '${$.name}.',\n dataScopePrefix: '${$.dataScope}.',\n provider: '${$.provider}'\n },\n urlTypes: {},\n listens: {\n settingValue: 'checked',\n disabled: 'hideLinkedElement',\n linkType: 'createChildUrlInputComponent'\n },\n links: {\n linkType: '${$.provider}:${$.dataScope}.type',\n settingValue: '${$.provider}:${$.dataScope}.setting'\n }\n },\n\n /** @inheritdoc */\n initConfig: function (config) {\n var processedLinkTypes = {},\n baseLinkType = this.constructor.defaults.baseLinkSetting;\n\n _.each(config.urlTypes, function (linkSettingsArray, linkName) {\n //add link name by link type\n linkSettingsArray.name = baseLinkType.namePrefix + linkName;\n linkSettingsArray.dataScope = baseLinkType.dataScopePrefix + linkName;\n linkSettingsArray.type = linkName;\n linkSettingsArray.disabled = config.disabled;\n linkSettingsArray.visible = config.visible;\n processedLinkTypes[linkName] = {};\n _.extend(processedLinkTypes[linkName], baseLinkType, linkSettingsArray);\n });\n _.extend(this.constructor.defaults.urlTypes, processedLinkTypes);\n\n this._super();\n },\n\n /**\n * Initializes observable properties of instance\n *\n * @returns {Abstract} Chainable.\n */\n initObservable: function () {\n this._super()\n .observe('componentTemplate options value linkType settingValue checked isDisplayAdditionalSettings')\n .setOptions();\n\n return this;\n },\n\n /**\n * Set options to select based on link types configuration\n *\n * @return {Object}\n */\n setOptions: function () {\n var result = [];\n\n _.each(this.urlTypes, function (option, key) {\n result.push({\n value: key,\n label: option.label,\n sortOrder: option.sortOrder || 0\n });\n });\n\n //sort options by sortOrder\n result.sort(function (a, b) {\n return a.sortOrder > b.sortOrder ? 1 : -1;\n });\n\n this.options(result);\n\n return this;\n },\n\n /** @inheritdoc */\n setPreview: function (visible) {\n this.linkedElement().visible(visible);\n },\n\n /**\n * Initializes observable properties of instance\n *\n * @param {Boolean} disabled\n */\n hideLinkedElement: function (disabled) {\n this.linkedElement().disabled(disabled);\n },\n\n /** @inheritdoc */\n destroy: function () {\n _.each(this.linkedElementInstances, function (value) {\n value().destroy();\n });\n this._super();\n },\n\n /**\n * Create child component by value\n *\n * @param {String} value\n * @return void\n */\n createChildUrlInputComponent: function (value) {\n var elementConfig;\n\n if (!_.isEmpty(value) && _.isUndefined(this.linkedElementInstances[value])) {\n elementConfig = this.urlTypes[value];\n layout([elementConfig]);\n this.linkedElementInstances[value] = this.requestModule(elementConfig.name);\n }\n this.linkedElement = this.linkedElementInstances[value];\n\n },\n\n /**\n * Returns linked element to display related field in template\n * @return String\n */\n getLinkedElementName: function () {\n return this.linkedElement;\n },\n\n /**\n * Add ability to choose check box by clicking on label\n */\n checkboxClick: function () {\n if (!this.disabled()) {\n this.settingValue(!this.settingValue());\n }\n }\n });\n});\n","Magento_Ui/js/form/element/media.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n 'mageUtils',\n './abstract'\n], function (utils, Abstract) {\n 'use strict';\n\n return Abstract.extend({\n defaults: {\n links: {\n value: ''\n }\n },\n\n /**\n * Initializes file component.\n *\n * @returns {Media} Chainable.\n */\n initialize: function () {\n this._super()\n .initFormId();\n\n return this;\n },\n\n /**\n * Defines form ID with which file input will be associated.\n *\n * @returns {Media} Chainable.\n */\n initFormId: function () {\n var namespace;\n\n if (this.formId) {\n return this;\n }\n\n namespace = this.name.split('.');\n this.formId = namespace[0];\n\n return this;\n }\n });\n});\n","Magento_Ui/js/form/element/abstract.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n 'underscore',\n 'mageUtils',\n 'uiLayout',\n 'uiElement',\n 'Magento_Ui/js/lib/validation/validator'\n], function (_, utils, layout, Element, validator) {\n 'use strict';\n\n return Element.extend({\n defaults: {\n visible: true,\n preview: '',\n focused: false,\n required: false,\n disabled: false,\n valueChangedByUser: false,\n elementTmpl: 'ui/form/element/input',\n tooltipTpl: 'ui/form/element/helper/tooltip',\n fallbackResetTpl: 'ui/form/element/helper/fallback-reset',\n 'input_type': 'input',\n placeholder: false,\n description: '',\n labelVisible: true,\n label: '',\n error: '',\n warn: '',\n notice: '',\n customScope: '',\n default: '',\n isDifferedFromDefault: false,\n showFallbackReset: false,\n additionalClasses: {},\n isUseDefault: '',\n serviceDisabled: false,\n valueUpdate: false, // ko binding valueUpdate\n\n switcherConfig: {\n component: 'Magento_Ui/js/form/switcher',\n name: '${ $.name }_switcher',\n target: '${ $.name }',\n property: 'value'\n },\n listens: {\n visible: 'setPreview',\n value: 'setDifferedFromDefault',\n '${ $.provider }:data.reset': 'reset',\n '${ $.provider }:data.overload': 'overload',\n '${ $.provider }:${ $.customScope ? $.customScope + \".\" : \"\"}data.validate': 'validate',\n 'isUseDefault': 'toggleUseDefault'\n },\n ignoreTmpls: {\n value: true\n },\n\n links: {\n value: '${ $.provider }:${ $.dataScope }'\n }\n },\n\n /**\n * Invokes initialize method of parent class,\n * contains initialization logic\n */\n initialize: function () {\n _.bindAll(this, 'reset');\n\n this._super()\n .setInitialValue()\n ._setClasses()\n .initSwitcher();\n\n return this;\n },\n\n /**\n * Checks if component has error.\n *\n * @returns {Object}\n */\n checkInvalid: function () {\n return this.error() && this.error().length ? this : null;\n },\n\n /**\n * Initializes observable properties of instance\n *\n * @returns {Abstract} Chainable.\n */\n initObservable: function () {\n var rules = this.validation = this.validation || {};\n\n this._super();\n\n this.observe('error disabled focused preview visible value warn notice isDifferedFromDefault')\n .observe('isUseDefault serviceDisabled')\n .observe({\n 'required': !!rules['required-entry']\n });\n\n return this;\n },\n\n /**\n * Initializes regular properties of instance.\n *\n * @returns {Abstract} Chainable.\n */\n initConfig: function () {\n var uid = utils.uniqueid(),\n name,\n valueUpdate,\n scope;\n\n this._super();\n\n scope = this.dataScope.split('.');\n name = scope.length > 1 ? scope.slice(1) : scope;\n\n valueUpdate = this.showFallbackReset ? 'afterkeydown' : this.valueUpdate;\n\n _.extend(this, {\n uid: uid,\n noticeId: 'notice-' + uid,\n errorId: 'error-' + uid,\n tooltipId: 'tooltip-' + uid,\n inputName: utils.serializeName(name.join('.')),\n valueUpdate: valueUpdate\n });\n\n return this;\n },\n\n /**\n * Initializes switcher element instance.\n *\n * @returns {Abstract} Chainable.\n */\n initSwitcher: function () {\n if (this.switcherConfig.enabled) {\n layout([this.switcherConfig]);\n }\n\n return this;\n },\n\n /**\n * Sets initial value of the element and subscribes to it's changes.\n *\n * @returns {Abstract} Chainable.\n */\n setInitialValue: function () {\n this.initialValue = this.getInitialValue();\n\n if (this.value.peek() !== this.initialValue) {\n this.value(this.initialValue);\n }\n\n this.on('value', this.onUpdate.bind(this));\n this.isUseDefault(this.disabled());\n\n return this;\n },\n\n /**\n * Extends 'additionalClasses' object.\n *\n * @returns {Abstract} Chainable.\n */\n _setClasses: function () {\n var additional = this.additionalClasses;\n\n if (_.isString(additional)) {\n this.additionalClasses = {};\n\n if (additional.trim().length) {\n additional = additional.trim().split(' ');\n\n additional.forEach(function (name) {\n if (name.length) {\n this.additionalClasses[name] = true;\n }\n }, this);\n }\n }\n\n _.extend(this.additionalClasses, {\n _required: this.required,\n _error: this.error,\n _warn: this.warn,\n _disabled: this.disabled\n });\n\n return this;\n },\n\n /**\n * Gets initial value of element\n *\n * @returns {*} Elements' value.\n */\n getInitialValue: function () {\n var values = [this.value(), this.default],\n value;\n\n values.some(function (v) {\n if (v !== null && v !== undefined) {\n value = v;\n\n return true;\n }\n\n return false;\n });\n\n return this.normalizeData(value);\n },\n\n /**\n * Sets 'value' as 'hidden' property's value, triggers 'toggle' event,\n * sets instance's hidden identifier in params storage based on\n * 'value'.\n *\n * @returns {Abstract} Chainable.\n */\n setVisible: function (isVisible) {\n this.visible(isVisible);\n\n return this;\n },\n\n /**\n * Show element.\n *\n * @returns {Abstract} Chainable.\n */\n show: function () {\n this.visible(true);\n\n return this;\n },\n\n /**\n * Hide element.\n *\n * @returns {Abstract} Chainable.\n */\n hide: function () {\n this.visible(false);\n\n return this;\n },\n\n /**\n * Disable element.\n *\n * @returns {Abstract} Chainable.\n */\n disable: function () {\n this.disabled(true);\n\n return this;\n },\n\n /**\n * Enable element.\n *\n * @returns {Abstract} Chainable.\n */\n enable: function () {\n this.disabled(false);\n\n return this;\n },\n\n /**\n *\n * @param {(String|Object)} rule\n * @param {(Object|Boolean)} [options]\n * @returns {Abstract} Chainable.\n */\n setValidation: function (rule, options) {\n var rules = utils.copy(this.validation),\n changed;\n\n if (_.isObject(rule)) {\n _.extend(this.validation, rule);\n } else {\n this.validation[rule] = options;\n }\n\n changed = !utils.compare(rules, this.validation).equal;\n\n if (changed) {\n this.required(!!rules['required-entry']);\n this.validate();\n }\n\n return this;\n },\n\n /**\n * Returns unwrapped preview observable.\n *\n * @returns {String} Value of the preview observable.\n */\n getPreview: function () {\n return this.value();\n },\n\n /**\n * Checks if element has addons\n *\n * @returns {Boolean}\n */\n hasAddons: function () {\n return this.addbefore || this.addafter;\n },\n\n /**\n * Checks if element has service setting\n *\n * @returns {Boolean}\n */\n hasService: function () {\n return this.service && this.service.template;\n },\n\n /**\n * Defines if value has changed.\n *\n * @returns {Boolean}\n */\n hasChanged: function () {\n var notEqual = this.value() !== this.initialValue;\n\n return !this.visible() ? false : notEqual;\n },\n\n /**\n * Checks if 'value' is not empty.\n *\n * @returns {Boolean}\n */\n hasData: function () {\n return !utils.isEmpty(this.value());\n },\n\n /**\n * Sets value observable to initialValue property.\n *\n * @returns {Abstract} Chainable.\n */\n reset: function () {\n this.value(this.initialValue);\n this.error(false);\n\n return this;\n },\n\n /**\n * Sets current state as initial.\n */\n overload: function () {\n this.setInitialValue();\n this.bubble('update', this.hasChanged());\n },\n\n /**\n * Clears 'value' property.\n *\n * @returns {Abstract} Chainable.\n */\n clear: function () {\n this.value('');\n\n return this;\n },\n\n /**\n * Converts values like 'null' or 'undefined' to an empty string.\n *\n * @param {*} value - Value to be processed.\n * @returns {*}\n */\n normalizeData: function (value) {\n return utils.isEmpty(value) ? '' : value;\n },\n\n /**\n * Validates itself by it's validation rules using validator object.\n * If validation of a rule did not pass, writes it's message to\n * 'error' observable property.\n *\n * @returns {Object} Validate information.\n */\n validate: function () {\n var value = this.value(),\n result = validator(this.validation, value, this.validationParams),\n message = !this.disabled() && this.visible() ? result.message : '',\n isValid = this.disabled() || !this.visible() || result.passed;\n\n this.error(message);\n this.error.valueHasMutated();\n this.bubble('error', message);\n\n //TODO: Implement proper result propagation for form\n if (this.source && !isValid) {\n this.source.set('params.invalid', true);\n }\n\n return {\n valid: isValid,\n target: this\n };\n },\n\n /**\n * Callback that fires when 'value' property is updated.\n */\n onUpdate: function () {\n this.bubble('update', this.hasChanged());\n\n this.validate();\n },\n\n /**\n * Restore value to default\n */\n restoreToDefault: function () {\n this.value(this.default);\n this.focused(true);\n },\n\n /**\n * Update whether value differs from default value\n */\n setDifferedFromDefault: function () {\n var value = typeof this.value() != 'undefined' && this.value() !== null ? this.value() : '',\n defaultValue = typeof this.default != 'undefined' && this.default !== null ? this.default : '';\n\n this.isDifferedFromDefault(value !== defaultValue);\n },\n\n /**\n * @param {Boolean} state\n */\n toggleUseDefault: function (state) {\n this.disabled(state);\n\n if (this.source && this.hasService()) {\n this.source.set('data.use_default.' + this.index, Number(state));\n }\n },\n\n /**\n * Callback when value is changed by user\n */\n userChanges: function () {\n this.valueChangedByUser = true;\n },\n\n /**\n * Returns correct id for 'aria-describedby' accessibility attribute\n *\n * @returns {Boolean|String}\n */\n getDescriptionId: function () {\n var id = false;\n\n if (this.error()) {\n id = this.errorId;\n } else if (this.notice()) {\n id = this.noticeId;\n }\n\n return id;\n }\n });\n});\n","Magento_Ui/js/form/element/boolean.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n './abstract'\n], function (Abstract) {\n 'use strict';\n\n return Abstract.extend({\n defaults: {\n checked: false,\n links: {\n checked: 'value'\n }\n },\n\n /**\n * @returns {*|void|Element}\n */\n initObservable: function () {\n return this._super()\n .observe('checked');\n },\n\n /**\n * Converts provided value to boolean.\n *\n * @returns {Boolean}\n */\n normalizeData: function () {\n return !!+this._super();\n },\n\n /**\n * Calls 'onUpdate' method of parent, if value is defined and instance's\n * 'unique' property set to true, calls 'setUnique' method\n *\n * @return {Object} - reference to instance\n */\n onUpdate: function () {\n if (this.hasUnique) {\n this.setUnique();\n }\n\n return this._super();\n }\n });\n});\n","Magento_Ui/js/form/element/select.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n 'underscore',\n 'mageUtils',\n 'uiRegistry',\n './abstract',\n 'uiLayout'\n], function (_, utils, registry, Abstract, layout) {\n 'use strict';\n\n var inputNode = {\n parent: '${ $.$data.parentName }',\n component: 'Magento_Ui/js/form/element/abstract',\n template: '${ $.$data.template }',\n provider: '${ $.$data.provider }',\n name: '${ $.$data.index }_input',\n dataScope: '${ $.$data.customEntry }',\n customScope: '${ $.$data.customScope }',\n sortOrder: {\n after: '${ $.$data.name }'\n },\n displayArea: 'body',\n label: '${ $.$data.label }'\n };\n\n /**\n * Parses incoming options, considers options with undefined value property\n * as caption\n *\n * @param {Array} nodes\n * @return {Object}\n */\n function parseOptions(nodes, captionValue) {\n var caption,\n value;\n\n nodes = _.map(nodes, function (node) {\n value = node.value;\n\n if (value === null || value === captionValue) {\n if (_.isUndefined(caption)) {\n caption = node.label;\n }\n } else {\n return node;\n }\n });\n\n return {\n options: _.compact(nodes),\n caption: _.isString(caption) ? caption : false\n };\n }\n\n /**\n * Recursively loops over data to find non-undefined, non-array value\n *\n * @param {Array} data\n * @return {*} - first non-undefined value in array\n */\n function findFirst(data) {\n var value;\n\n data.some(function (node) {\n value = node.value;\n\n if (Array.isArray(value)) {\n value = findFirst(value);\n }\n\n return !_.isUndefined(value);\n });\n\n return value;\n }\n\n /**\n * Recursively set to object item like value and item.value like key.\n *\n * @param {Array} data\n * @param {Object} result\n * @returns {Object}\n */\n function indexOptions(data, result) {\n var value;\n\n result = result || {};\n\n data.forEach(function (item) {\n value = item.value;\n\n if (Array.isArray(value)) {\n indexOptions(value, result);\n } else {\n result[value] = item;\n }\n });\n\n return result;\n }\n\n return Abstract.extend({\n defaults: {\n customName: '${ $.parentName }.${ $.index }_input',\n elementTmpl: 'ui/form/element/select',\n caption: '',\n options: []\n },\n\n /**\n * Extends instance with defaults, extends config with formatted values\n * and options, and invokes initialize method of AbstractElement class.\n * If instance's 'customEntry' property is set to true, calls 'initInput'\n */\n initialize: function () {\n this._super();\n\n if (this.customEntry) {\n registry.get(this.name, this.initInput.bind(this));\n }\n\n if (this.filterBy) {\n this.initFilter();\n }\n\n return this;\n },\n\n /**\n * Calls 'initObservable' of parent, initializes 'options' and 'initialOptions'\n * properties, calls 'setOptions' passing options to it\n *\n * @returns {Object} Chainable.\n */\n initObservable: function () {\n this._super();\n\n this.initialOptions = this.options;\n\n this.observe('options caption')\n .setOptions(this.options());\n\n return this;\n },\n\n /**\n * Set link for filter.\n *\n * @returns {Object} Chainable\n */\n initFilter: function () {\n var filter = this.filterBy;\n\n this.filter(this.default, filter.field);\n this.setLinks({\n filter: filter.target\n }, 'imports');\n\n return this;\n },\n\n /**\n * Creates input from template, renders it via renderer.\n *\n * @returns {Object} Chainable.\n */\n initInput: function () {\n layout([utils.template(inputNode, this)]);\n\n return this;\n },\n\n /**\n * Matches specified value with existing options\n * or, if value is not specified, returns value of the first option.\n *\n * @returns {*}\n */\n normalizeData: function () {\n var value = this._super(),\n option;\n\n if (value !== '') {\n option = this.getOption(value);\n\n return option && option.value;\n }\n\n if (!this.caption()) {\n return findFirst(this.options);\n }\n },\n\n /**\n * Filters 'initialOptions' property by 'field' and 'value' passed,\n * calls 'setOptions' passing the result to it\n *\n * @param {*} value\n * @param {String} field\n */\n filter: function (value, field) {\n var source = this.initialOptions,\n result;\n\n field = field || this.filterBy.field;\n\n result = _.filter(source, function (item) {\n return item[field] === value || item.value === '';\n });\n\n this.setOptions(result);\n },\n\n /**\n * Change visibility for input.\n *\n * @param {Boolean} isVisible\n */\n toggleInput: function (isVisible) {\n registry.get(this.customName, function (input) {\n input.setVisible(isVisible);\n });\n },\n\n /**\n * Sets 'data' to 'options' observable array, if instance has\n * 'customEntry' property set to true, calls 'setHidden' method\n * passing !options.length as a parameter\n *\n * @param {Array} data\n * @returns {Object} Chainable\n */\n setOptions: function (data) {\n var captionValue = this.captionValue || '',\n result = parseOptions(data, captionValue),\n isVisible;\n\n this.indexedOptions = indexOptions(result.options);\n\n this.options(result.options);\n\n if (!this.caption()) {\n this.caption(result.caption);\n }\n\n if (this.customEntry) {\n isVisible = !!result.options.length;\n\n this.setVisible(isVisible);\n this.toggleInput(!isVisible);\n }\n\n return this;\n },\n\n /**\n * Processes preview for option by it's value, and sets the result\n * to 'preview' observable\n *\n * @returns {Object} Chainable.\n */\n getPreview: function () {\n var value = this.value(),\n option = this.indexedOptions[value],\n preview = option ? option.label : '';\n\n this.preview(preview);\n\n return preview;\n },\n\n /**\n * Get option from indexedOptions list.\n *\n * @param {Number} value\n * @returns {Object} Chainable\n */\n getOption: function (value) {\n return this.indexedOptions[value];\n },\n\n /**\n * Select first available option\n *\n * @returns {Object} Chainable.\n */\n clear: function () {\n var value = this.caption() ? '' : findFirst(this.options);\n\n this.value(value);\n\n return this;\n },\n\n /**\n * Initializes observable properties of instance\n *\n * @returns {Object} Chainable.\n */\n setInitialValue: function () {\n if (_.isUndefined(this.value()) && !this.default) {\n this.clear();\n }\n\n return this._super();\n }\n });\n});\n","Magento_Ui/js/form/element/single-checkbox.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n 'Magento_Ui/js/form/element/abstract',\n 'underscore',\n 'mage/translate'\n], function (AbstractField, _, $t) {\n 'use strict';\n\n return AbstractField.extend({\n defaults: {\n template: 'ui/form/components/single/field',\n checked: false,\n initialChecked: false,\n multiple: false,\n prefer: 'checkbox', // 'radio' | 'checkbox' | 'toggle'\n valueMap: {},\n\n templates: {\n radio: 'ui/form/components/single/radio',\n checkbox: 'ui/form/components/single/checkbox',\n toggle: 'ui/form/components/single/switcher'\n },\n\n listens: {\n 'checked': 'onCheckedChanged',\n 'value': 'onExtendedValueChanged'\n }\n },\n\n /**\n * @inheritdoc\n */\n initConfig: function (config) {\n this._super();\n\n if (!config.elementTmpl) {\n if (!this.prefer && !this.multiple) {\n this.elementTmpl = this.templates.radio;\n } else if (this.prefer === 'radio') {\n this.elementTmpl = this.templates.radio;\n } else if (this.prefer === 'checkbox') {\n this.elementTmpl = this.templates.checkbox;\n } else if (this.prefer === 'toggle') {\n this.elementTmpl = this.templates.toggle;\n } else {\n this.elementTmpl = this.templates.checkbox;\n }\n }\n\n if (this.prefer === 'toggle' && _.isEmpty(this.toggleLabels)) {\n this.toggleLabels = {\n 'on': $t('Yes'),\n 'off': $t('No')\n };\n }\n\n if (typeof this.default === 'undefined' || this.default === null) {\n this.default = '';\n }\n\n if (typeof this.value === 'undefined' || this.value === null) {\n this.value = _.isEmpty(this.valueMap) || this.default !== '' ? this.default : this.valueMap.false;\n this.initialValue = this.value;\n } else {\n this.initialValue = this.value;\n }\n\n if (this.multiple && !_.isArray(this.value)) {\n this.value = []; // needed for correct observable assignment\n }\n\n this.initialChecked = this.checked;\n\n return this;\n },\n\n /**\n * @inheritdoc\n */\n initObservable: function () {\n return this\n ._super()\n .observe('checked');\n },\n\n /**\n * Get true/false key from valueMap by value.\n *\n * @param {*} value\n * @returns {Boolean|undefined}\n */\n getReverseValueMap: function getReverseValueMap(value) {\n var bool = false;\n\n _.some(this.valueMap, function (iValue, iBool) {\n if (iValue === value) {\n bool = iBool === 'true';\n\n return true;\n }\n });\n\n return bool;\n },\n\n /**\n * @inheritdoc\n */\n setInitialValue: function () {\n if (_.isEmpty(this.valueMap)) {\n this.on('value', this.onUpdate.bind(this));\n } else {\n this._super();\n this.checked(this.getReverseValueMap(this.value()));\n }\n\n return this;\n },\n\n /**\n * Handle dataScope changes for checkbox / radio button.\n *\n * @param {*} newExportedValue\n */\n onExtendedValueChanged: function (newExportedValue) {\n var isMappedUsed = !_.isEmpty(this.valueMap),\n oldChecked = this.checked.peek(),\n oldValue = this.initialValue,\n newChecked;\n\n if (this.multiple) {\n newChecked = newExportedValue.indexOf(oldValue) !== -1;\n } else if (isMappedUsed) {\n newChecked = this.getReverseValueMap(newExportedValue);\n } else if (typeof newExportedValue === 'boolean') {\n newChecked = newExportedValue;\n } else {\n newChecked = newExportedValue === oldValue;\n }\n\n if (newChecked !== oldChecked) {\n this.checked(newChecked);\n }\n },\n\n /**\n * Handle checked state changes for checkbox / radio button.\n *\n * @param {Boolean} newChecked\n */\n onCheckedChanged: function (newChecked) {\n var isMappedUsed = !_.isEmpty(this.valueMap),\n oldValue = this.initialValue,\n newValue;\n\n if (isMappedUsed) {\n newValue = this.valueMap[newChecked];\n } else {\n newValue = oldValue;\n }\n\n if (!this.multiple && newChecked) {\n this.value(newValue);\n } else if (!this.multiple && !newChecked) {\n if (typeof newValue === 'boolean') {\n this.value(newChecked);\n } else if (newValue === this.value.peek()) {\n this.value('');\n }\n\n if (isMappedUsed) {\n this.value(newValue);\n }\n } else if (this.multiple && newChecked && this.value.indexOf(newValue) === -1) {\n this.value.push(newValue);\n } else if (this.multiple && !newChecked && this.value.indexOf(newValue) !== -1) {\n this.value.splice(this.value.indexOf(newValue), 1);\n }\n },\n\n /**\n * @inheritdoc\n */\n onUpdate: function () {\n if (this.hasUnique) {\n this.setUnique();\n }\n\n return this._super();\n },\n\n /**\n * @inheritdoc\n */\n reset: function () {\n if (this.multiple && this.initialChecked) {\n this.value.push(this.initialValue);\n } else if (this.multiple && !this.initialChecked) {\n this.value.splice(this.value.indexOf(this.initialValue), 1);\n } else {\n this.value(this.initialValue);\n }\n\n this.error(false);\n\n return this;\n },\n\n /**\n * @inheritdoc\n */\n clear: function () {\n if (this.multiple) {\n this.value([]);\n } else {\n this.value('');\n }\n\n this.error(false);\n\n return this;\n }\n });\n});\n","Magento_Ui/js/form/element/website.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n 'underscore',\n 'uiRegistry',\n './select'\n], function (_, registry, Select) {\n 'use strict';\n\n return Select.extend({\n defaults: {\n customerId: null,\n isGlobalScope: 0\n },\n\n /**\n * Website component constructor.\n * @returns {exports}\n */\n initialize: function () {\n this._super();\n\n return this;\n }\n });\n});\n","Magento_Ui/js/form/element/wysiwyg.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n 'wysiwygAdapter',\n 'Magento_Ui/js/lib/view/utils/async',\n 'underscore',\n 'ko',\n './abstract',\n 'mage/adminhtml/events',\n 'Magento_Variable/variables'\n], function (wysiwyg, $, _, ko, Abstract, varienGlobalEvents) {\n 'use strict';\n\n return Abstract.extend({\n currentWysiwyg: undefined,\n defaults: {\n elementSelector: 'textarea',\n suffixRegExpPattern: '${ $.wysiwygUniqueSuffix }',\n $wysiwygEditorButton: '',\n links: {\n value: '${ $.provider }:${ $.dataScope }'\n },\n template: 'ui/form/field',\n elementTmpl: 'ui/form/element/wysiwyg',\n content: '',\n showSpinner: false,\n loading: false,\n listens: {\n disabled: 'setDisabled'\n }\n },\n\n /**\n *\n * @returns {} Chainable.\n */\n initialize: function () {\n this._super()\n .initNodeListener();\n\n $.async({\n component: this,\n selector: 'button'\n }, function (element) {\n this.$wysiwygEditorButton = this.$wysiwygEditorButton ?\n this.$wysiwygEditorButton.add($(element)) : $(element);\n }.bind(this));\n\n // disable editor completely after initialization is field is disabled\n varienGlobalEvents.attachEventHandler('wysiwygEditorInitialized', function () {\n if (!_.isUndefined(window.tinyMceEditors)) {\n this.currentWysiwyg = window.tinyMceEditors[this.wysiwygId];\n }\n\n if (this.disabled()) {\n this.setDisabled(true);\n }\n }.bind(this));\n\n return this;\n },\n\n /** @inheritdoc */\n initConfig: function (config) {\n var pattern = config.suffixRegExpPattern || this.constructor.defaults.suffixRegExpPattern;\n\n pattern = pattern.replace(/\\$/g, '\\\\$&');\n config.content = config.content.replace(new RegExp(pattern, 'g'), this.getUniqueSuffix(config));\n this._super();\n\n return this;\n },\n\n /**\n * Build unique id based on name, underscore separated.\n *\n * @param {Object} config\n */\n getUniqueSuffix: function (config) {\n return config.name.replace(/(\\.|-)/g, '_');\n },\n\n /**\n * @inheritdoc\n */\n destroy: function () {\n this._super();\n wysiwyg.removeEvents(this.wysiwygId);\n },\n\n /**\n *\n * @returns {exports}\n */\n initObservable: function () {\n this._super()\n .observe(['value', 'content']);\n\n return this;\n },\n\n /**\n *\n * @returns {} Chainable.\n */\n initNodeListener: function () {\n $.async({\n component: this,\n selector: this.elementSelector\n }, this.setElementNode.bind(this));\n\n return this;\n },\n\n /**\n *\n * @param {HTMLElement} node\n */\n setElementNode: function (node) {\n $(node).bindings({\n value: this.value\n });\n },\n\n /**\n * Set disabled property to wysiwyg component\n *\n * @param {Boolean} disabled\n */\n setDisabled: function (disabled) {\n if (this.$wysiwygEditorButton && disabled) {\n this.$wysiwygEditorButton.prop('disabled', 'disabled');\n } else if (this.$wysiwygEditorButton) {\n this.$wysiwygEditorButton.prop('disabled', false);\n }\n\n /* eslint-disable no-undef */\n if (!_.isUndefined(this.currentWysiwyg) && this.currentWysiwyg.activeEditor()) {\n this.currentWysiwyg.setEnabledStatus(!disabled);\n this.currentWysiwyg.getPluginButtons().prop('disabled', disabled);\n }\n },\n\n /**\n * Content getter\n *\n * @returns {String}\n */\n getContentUnsanitizedHtml: function () {\n return this.content();\n }\n });\n});\n","Magento_Ui/js/form/element/single-checkbox-use-config.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n 'Magento_Ui/js/form/element/single-checkbox'\n], function (Component) {\n 'use strict';\n\n return Component.extend({\n defaults: {\n isUseDefault: false,\n isUseConfig: false,\n listens: {\n 'isUseConfig': 'toggleElement',\n 'isUseDefault': 'toggleElement'\n }\n },\n\n /**\n * @inheritdoc\n */\n initObservable: function () {\n\n return this\n ._super()\n .observe('isUseConfig');\n },\n\n /**\n * Toggle element\n */\n toggleElement: function () {\n this.disabled(this.isUseDefault() || this.isUseConfig());\n\n if (this.source) {\n this.source.set('data.use_default.' + this.index, Number(this.isUseDefault()));\n }\n }\n });\n});\n","Magento_Ui/js/form/element/region.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n 'underscore',\n 'uiRegistry',\n './select',\n 'Magento_Checkout/js/model/default-post-code-resolver'\n], function (_, registry, Select, defaultPostCodeResolver) {\n 'use strict';\n\n return Select.extend({\n defaults: {\n skipValidation: false,\n imports: {\n countryOptions: '${ $.parentName }.country_id:indexedOptions',\n update: '${ $.parentName }.country_id:value'\n }\n },\n\n /**\n * {@inheritdoc}\n */\n initialize: function () {\n var option;\n\n this._super();\n\n option = _.find(this.countryOptions, function (row) {\n return row['is_default'] === true;\n });\n this.hideRegion(option);\n\n return this;\n },\n\n /**\n * Method called every time country selector's value gets changed.\n * Updates all validations and requirements for certain country.\n * @param {String} value - Selected country ID.\n */\n update: function (value) {\n var isRegionRequired,\n option;\n\n if (!value) {\n return;\n }\n\n option = _.isObject(this.countryOptions) && this.countryOptions[value];\n\n if (!option) {\n return;\n }\n\n this.hideRegion(option);\n\n defaultPostCodeResolver.setUseDefaultPostCode(!option['is_zipcode_optional']);\n\n isRegionRequired = !this.skipValidation && !!option['is_region_required'];\n\n if (!isRegionRequired) {\n this.error(false);\n }\n\n this.required(isRegionRequired);\n this.validation['required-entry'] = isRegionRequired;\n\n registry.get(this.customName, function (input) {\n input.required(isRegionRequired);\n input.validation['required-entry'] = isRegionRequired;\n input.validation['validate-not-number-first'] = !this.options().length;\n }.bind(this));\n },\n\n /**\n * Hide select and corresponding text input field if region must not be shown for selected country.\n *\n * @private\n * @param {Object}option\n */\n hideRegion: function (option) {\n if (!option || option['is_region_visible'] !== false) {\n return;\n }\n\n this.setVisible(false);\n\n if (this.customEntry) {\n this.toggleInput(false);\n }\n }\n });\n});\n","Magento_Ui/js/form/element/single-checkbox-toggle-notice.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n 'Magento_Ui/js/form/element/single-checkbox'\n], function (SingleCheckbox) {\n 'use strict';\n\n return SingleCheckbox.extend({\n defaults: {\n notices: [],\n tracks: {\n notice: true\n }\n },\n\n /**\n * Choose notice on initialization\n *\n * @returns {*|void|Element}\n */\n initialize: function () {\n this._super()\n .chooseNotice();\n\n return this;\n },\n\n /**\n * Choose notice function\n *\n * @returns void\n */\n chooseNotice: function () {\n var checkedNoticeNumber = Number(this.checked());\n\n this.notice = this.notices[checkedNoticeNumber];\n },\n\n /**\n * Choose notice on update\n *\n * @returns void\n */\n onUpdate: function () {\n this._super();\n this.chooseNotice();\n }\n });\n});\n","Magento_Ui/js/form/element/text.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n 'uiElement',\n 'mageUtils'\n], function (Element, utils) {\n 'use strict';\n\n return Element.extend({\n defaults: {\n visible: true,\n label: '',\n error: '',\n uid: utils.uniqueid(),\n disabled: false,\n links: {\n value: '${ $.provider }:${ $.dataScope }'\n }\n },\n\n /**\n * Has service\n *\n * @returns {Boolean} false.\n */\n hasService: function () {\n return false;\n },\n\n /**\n * Has addons\n *\n * @returns {Boolean} false.\n */\n hasAddons: function () {\n return false;\n },\n\n /**\n * Calls 'initObservable' of parent\n *\n * @returns {Object} Chainable.\n */\n initObservable: function () {\n this._super()\n .observe('disabled visible value');\n\n return this;\n }\n });\n});\n","Magento_Ui/js/form/element/date.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n 'moment',\n 'mageUtils',\n './abstract',\n 'moment-timezone-with-data'\n], function (moment, utils, Abstract) {\n 'use strict';\n\n return Abstract.extend({\n defaults: {\n options: {},\n\n storeTimeZone: 'UTC',\n\n validationParams: {\n dateFormat: '${ $.outputDateFormat }'\n },\n\n /**\n * Format of date that comes from the\n * server (ICU Date Format).\n *\n * Used only in date picker mode\n * (this.options.showsTime == false).\n *\n * @type {String}\n */\n inputDateFormat: 'y-MM-dd',\n\n /**\n * Format of date that should be sent to the\n * server (ICU Date Format).\n *\n * Used only in date picker mode\n * (this.options.showsTime == false).\n *\n * @type {String}\n */\n outputDateFormat: 'MM/dd/y',\n\n /**\n * Date/time format that is used to display date in\n * the input field.\n *\n * @type {String}\n */\n pickerDateTimeFormat: '',\n\n pickerDefaultDateFormat: 'MM/dd/y', // ICU Date Format\n pickerDefaultTimeFormat: 'h:mm a', // ICU Time Format\n\n elementTmpl: 'ui/form/element/date',\n\n /**\n * Format needed by moment timezone for conversion\n */\n timezoneFormat: 'YYYY-MM-DD HH:mm',\n\n listens: {\n 'value': 'onValueChange',\n 'shiftedValue': 'onShiftedValueChange'\n },\n\n /**\n * Date/time value shifted to corresponding timezone\n * according to this.storeTimeZone property. This value\n * will be sent to the server.\n *\n * @type {String}\n */\n shiftedValue: ''\n },\n\n /**\n * Initializes regular properties of instance.\n *\n * @returns {Object} Chainable.\n */\n initConfig: function () {\n this._super();\n\n if (!this.options.dateFormat) {\n this.options.dateFormat = this.pickerDefaultDateFormat;\n }\n\n if (!this.options.timeFormat) {\n this.options.timeFormat = this.pickerDefaultTimeFormat;\n }\n\n this.prepareDateTimeFormats();\n\n return this;\n },\n\n /**\n * @inheritdoc\n */\n initObservable: function () {\n return this._super().observe(['shiftedValue']);\n },\n\n /**\n * @inheritdoc\n */\n getPreview: function () {\n return this.shiftedValue();\n },\n\n /**\n * Prepares and sets date/time value that will be displayed\n * in the input field.\n *\n * @param {String} value\n */\n onValueChange: function (value) {\n var shiftedValue;\n\n if (value) {\n if (this.options.showsTime && !this.options.timeOnly) {\n shiftedValue = moment.tz(value, 'UTC').tz(this.storeTimeZone);\n } else {\n shiftedValue = moment(value, this.outputDateFormat, true);\n }\n\n if (!shiftedValue.isValid()) {\n shiftedValue = moment(value, this.inputDateFormat);\n }\n shiftedValue = shiftedValue.format(this.pickerDateTimeFormat);\n } else {\n shiftedValue = '';\n }\n\n if (shiftedValue !== this.shiftedValue()) {\n this.shiftedValue(shiftedValue);\n }\n },\n\n /**\n * Prepares and sets date/time value that will be sent\n * to the server.\n *\n * @param {String} shiftedValue\n */\n onShiftedValueChange: function (shiftedValue) {\n var value,\n formattedValue,\n momentValue;\n\n if (shiftedValue) {\n momentValue = moment(shiftedValue, this.pickerDateTimeFormat);\n\n if (this.options.showsTime && !this.options.timeOnly) {\n formattedValue = moment(momentValue).format(this.timezoneFormat);\n value = moment.tz(formattedValue, this.storeTimeZone).tz('UTC').toISOString();\n } else {\n value = momentValue.format(this.outputDateFormat);\n }\n } else {\n value = '';\n }\n\n if (value !== this.value()) {\n this.value(value);\n }\n },\n\n /**\n * Prepares and converts all date/time formats to be compatible\n * with moment.js library.\n */\n prepareDateTimeFormats: function () {\n if (this.options.timeOnly) {\n this.pickerDateTimeFormat = this.options.timeFormat;\n } else {\n this.pickerDateTimeFormat = this.options.dateFormat;\n\n if (this.options.showsTime) {\n this.pickerDateTimeFormat += ' ' + this.options.timeFormat;\n }\n }\n\n this.pickerDateTimeFormat = utils.convertToMomentFormat(this.pickerDateTimeFormat);\n\n if (this.options.dateFormat) {\n this.outputDateFormat = this.options.dateFormat;\n }\n\n this.inputDateFormat = this.options.timeOnly ?\n utils.convertToMomentFormat(this.pickerDefaultTimeFormat) :\n utils.convertToMomentFormat(this.inputDateFormat);\n this.outputDateFormat = this.options.timeOnly ?\n utils.convertToMomentFormat(this.options.timeFormat) :\n utils.convertToMomentFormat(this.outputDateFormat);\n\n this.validationParams.dateFormat = this.outputDateFormat;\n }\n });\n});\n","Magento_Ui/js/form/element/color-picker.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n 'mage/translate',\n 'Magento_Ui/js/form/element/abstract',\n 'Magento_Ui/js/form/element/color-picker-palette'\n], function ($t, Abstract, palette) {\n 'use strict';\n\n return Abstract.extend({\n\n defaults: {\n colorPickerConfig: {\n chooseText: $t('Apply'),\n cancelText: $t('Cancel'),\n maxSelectionSize: 8,\n clickoutFiresChange: true,\n allowEmpty: true,\n localStorageKey: 'magento.spectrum',\n palette: palette\n }\n },\n\n /**\n * Invokes initialize method of parent class,\n * contains initialization logic\n */\n initialize: function () {\n this._super();\n\n this.colorPickerConfig.value = this.value;\n\n return this;\n }\n });\n});\n","Magento_Ui/js/form/element/image-uploader.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/* global Base64 */\ndefine([\n 'jquery',\n 'underscore',\n 'mageUtils',\n 'Magento_Ui/js/modal/alert',\n 'Magento_Ui/js/lib/validation/validator',\n 'Magento_Ui/js/form/element/file-uploader',\n 'mage/adminhtml/browser'\n], function ($, _, utils, uiAlert, validator, Element, browser) {\n 'use strict';\n\n return Element.extend({\n /**\n * {@inheritDoc}\n */\n initialize: function () {\n this._super();\n\n // Listen for file deletions from the media browser\n $(window).on('fileDeleted.mediabrowser', this.onDeleteFile.bind(this));\n },\n\n /**\n * Assign uid for media gallery\n *\n * @return {ImageUploader} Chainable.\n */\n initConfig: function () {\n var mediaGalleryUid = utils.uniqueid();\n\n this._super();\n\n _.extend(this, {\n mediaGalleryUid: mediaGalleryUid\n });\n\n return this;\n },\n\n /**\n * Add file event callback triggered from media gallery\n *\n * @param {ImageUploader} imageUploader - UI Class\n * @param {Event} e\n */\n addFileFromMediaGallery: function (imageUploader, e) {\n var $buttonEl = $(e.target),\n fileSize = $buttonEl.data('size'),\n fileMimeType = $buttonEl.data('mime-type'),\n filePathname = $buttonEl.val(),\n fileBasename = filePathname.split('/').pop();\n\n this.addFile({\n type: fileMimeType,\n name: fileBasename,\n size: fileSize,\n url: filePathname\n });\n },\n\n /**\n * Open the media browser dialog\n *\n * @param {ImageUploader} imageUploader - UI Class\n * @param {Event} e\n */\n openMediaBrowserDialog: function (imageUploader, e) {\n var $buttonEl = $(e.target),\n openDialogUrl = this.mediaGallery.openDialogUrl +\n 'target_element_id/' + $buttonEl.attr('id') +\n '/store/' + this.mediaGallery.storeId +\n '/type/image/?isAjax=true';\n\n if (this.mediaGallery.initialOpenSubpath) {\n openDialogUrl += '¤t_tree_path=' + Base64.idEncode(this.mediaGallery.initialOpenSubpath);\n }\n\n browser.openDialog(\n openDialogUrl,\n null,\n null,\n this.mediaGallery.openDialogTitle,\n {\n targetElementId: $buttonEl.attr('id')\n }\n );\n },\n\n /**\n * @param {jQuery.event} e\n * @param {Object} data\n * @returns {Object} Chainables\n */\n onDeleteFile: function (e, data) {\n var fileId = this.getFileId(),\n deletedFileIds = data.ids;\n\n if (fileId && $.inArray(fileId, deletedFileIds) > -1) {\n this.clear();\n }\n\n return this;\n },\n\n /**\n * {@inheritDoc}\n */\n clear: function () {\n this.value([]);\n\n return this;\n },\n\n /**\n * Gets the ID of the file used if set\n *\n * @return {String|Null} ID\n */\n getFileId: function () {\n return this.hasData() ? this.value()[0].id : null;\n },\n\n /**\n * Trigger native browser file upload UI via clicking on 'Upload' button\n *\n * @param {ImageUploader} imageUploader - UI Class\n * @param {Event} e\n */\n triggerImageUpload: function (imageUploader, e) {\n $(e.target).closest('.file-uploader').find('.uppy-Dashboard-browse').trigger('click');\n },\n\n /**\n * Get list of file extensions allowed in comma delimited format\n *\n * @return {String}\n */\n getAllowedFileExtensionsInCommaDelimitedFormat: function () {\n var allowedExtensions = this.allowedExtensions.toUpperCase().split(' ');\n\n // if jpg and jpeg in allowed extensions, remove jpeg from list\n if (allowedExtensions.indexOf('JPG') !== -1 && allowedExtensions.indexOf('JPEG') !== -1) {\n allowedExtensions.splice(allowedExtensions.indexOf('JPEG'), 1);\n }\n\n return allowedExtensions.join(', ');\n }\n });\n});\n","Magento_Ui/js/form/element/textarea.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n './abstract'\n], function (Abstract) {\n 'use strict';\n\n return Abstract.extend({\n defaults: {\n cols: 15,\n rows: 2,\n elementTmpl: 'ui/form/element/textarea'\n }\n });\n});\n","Magento_Ui/js/form/element/post-code.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n 'underscore',\n './abstract'\n], function (_, Abstract) {\n 'use strict';\n\n return Abstract.extend({\n defaults: {\n imports: {\n countryOptions: '${ $.parentName }.country_id:indexedOptions',\n update: '${ $.parentName }.country_id:value'\n }\n },\n\n /**\n * Initializes observable properties of instance\n *\n * @returns {Abstract} Chainable.\n */\n initObservable: function () {\n this._super();\n\n /**\n * equalityComparer function\n *\n * @returns boolean.\n */\n this.value.equalityComparer = function (oldValue, newValue) {\n return !oldValue && !newValue || oldValue === newValue;\n };\n\n return this;\n },\n\n /**\n * Method called every time country selector's value gets changed.\n * Updates all validations and requirements for certain country.\n * @param {String} value - Selected country ID.\n */\n update: function (value) {\n var isZipCodeOptional,\n option;\n\n if (!value) {\n return;\n }\n\n option = _.isObject(this.countryOptions) && this.countryOptions[value];\n\n if (!option) {\n return;\n }\n\n isZipCodeOptional = !!option['is_zipcode_optional'];\n\n if (isZipCodeOptional) {\n this.error(false);\n }\n\n this.validation['required-entry'] = !isZipCodeOptional;\n this.required(!isZipCodeOptional);\n }\n });\n});\n","Magento_Ui/js/form/element/checkbox-set.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n 'underscore',\n 'mageUtils',\n './abstract'\n], function (_, utils, Abstract) {\n 'use strict';\n\n return Abstract.extend({\n defaults: {\n template: 'ui/form/element/checkbox-set',\n multiple: false,\n multipleScopeValue: null\n },\n\n /**\n * @inheritdoc\n */\n initConfig: function () {\n this._super();\n\n this.value = this.normalizeData(this.value);\n\n return this;\n },\n\n /**\n * @inheritdoc\n */\n initLinks: function () {\n var scope = this.source.get(this.dataScope);\n\n this.multipleScopeValue = this.multiple && _.isArray(scope) ? utils.copy(scope) : undefined;\n\n return this._super();\n },\n\n /**\n * @inheritdoc\n */\n reset: function () {\n this.value(utils.copy(this.initialValue));\n this.error(false);\n\n return this;\n },\n\n /**\n * @inheritdoc\n */\n clear: function () {\n var value = this.multiple ? [] : '';\n\n this.value(value);\n this.error(false);\n\n return this;\n },\n\n /**\n * @inheritdoc\n */\n normalizeData: function (value) {\n if (!this.multiple) {\n return this._super();\n }\n\n return _.isArray(value) ? utils.copy(value) : [];\n },\n\n /**\n * @inheritdoc\n */\n setInitialValue: function () {\n this._super();\n\n this.initialValue = utils.copy(this.initialValue);\n\n return this;\n },\n\n /**\n * @inheritdoc\n */\n getInitialValue: function () {\n var values = [this.multipleScopeValue, this.default, this.value.peek(), []],\n value;\n\n if (!this.multiple) {\n return this._super();\n }\n\n values.some(function (v) {\n return _.isArray(v) && (value = utils.copy(v));\n });\n\n return value;\n },\n\n /**\n * Returns labels which matches current value.\n *\n * @returns {String|Array}\n */\n getPreview: function () {\n var option;\n\n if (!this.multiple) {\n option = this.getOption(this.value());\n\n return option ? option.label : '';\n }\n\n return this.value.map(function (value) {\n return this.getOption(value).label;\n }, this);\n },\n\n /**\n * Returns option object associated with provided value.\n *\n * @param {String} value\n * @returns {Object}\n */\n getOption: function (value) {\n return _.findWhere(this.options, {\n value: value\n });\n },\n\n /**\n * @inheritdoc\n */\n hasChanged: function () {\n var value = this.value(),\n initial = this.initialValue;\n\n return this.multiple ?\n !utils.equalArrays(value, initial) :\n this._super();\n }\n });\n});\n","Magento_Ui/js/form/element/country.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n 'underscore',\n 'uiRegistry',\n './select'\n], function (_, registry, Select) {\n 'use strict';\n\n return Select.extend({\n defaults: {\n imports: {\n update: '${ $.parentName }.website_id:value'\n }\n },\n\n /**\n * Filters 'initialOptions' property by 'field' and 'value' passed,\n * calls 'setOptions' passing the result to it\n *\n * @param {*} value\n * @param {String} field\n */\n filter: function (value, field) {\n var result, defaultCountry, defaultValue;\n\n if (!field) { //validate field, if we are on update\n field = this.filterBy.field;\n }\n\n this._super(value, field);\n result = _.filter(this.initialOptions, function (item) {\n\n if (item[field]) {\n return ~item[field].indexOf(value);\n }\n\n return false;\n });\n\n this.setOptions(result);\n this.reset();\n\n if (!this.value()) {\n defaultCountry = _.filter(result, function (item) {\n return item['is_default'] && _.contains(item['is_default'], value);\n });\n\n if (defaultCountry.length) {\n defaultValue = defaultCountry.shift();\n this.value(defaultValue.value);\n }\n }\n }\n });\n});\n\n","Magento_Ui/js/form/element/color-picker-palette.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n/**\n * @api\n */\ndefine([], function () {\n 'use strict';\n\n return [\n [\n 'rgb(0,0,0)', 'rgb(52,52,52)', 'rgb(83,83,83)', 'rgb(135,135,135)', 'rgb(193,193,193)',\n 'rgb(234,234,234)', 'rgb(240,240,240)', 'rgb(255,255,255)'\n ],\n [\n 'rgb(252,0,9)', 'rgb(253,135,10)', 'rgb(255,255,13)', 'rgb(35,255,9)', 'rgb(33,255,255)',\n 'rgb(0,0,254)', 'rgb(132,0,254)', 'rgb(251,0,255)'\n ],\n [\n 'rgb(240,192,194)', 'rgb(251,223,194)', 'rgb(255,241,193)', 'rgb(210,230,201)',\n 'rgb(199,217,220)', 'rgb(197,219,240)', 'rgb(208,200,227)', 'rgb(229,199,212)'\n ],\n [\n 'rgb(228,133,135)', 'rgb(246,193,139)', 'rgb(254,225,136)', 'rgb(168,208,152)',\n 'rgb(146,184,190)', 'rgb(143,184,227)', 'rgb(165,148,204)', 'rgb(202,147,175)'\n ],\n [\n 'rgb(214,78,83)', 'rgb(243,163,88)', 'rgb(254,211,83)', 'rgb(130,187,106)',\n 'rgb(99,149,159)', 'rgb(93,150,211)', 'rgb(123,100,182)', 'rgb(180,100,142)'\n ],\n [\n 'rgb(190,0,5)', 'rgb(222,126,44)', 'rgb(236,183,39)', 'rgb(89,155,61)', 'rgb(55,110,123)',\n 'rgb(49,112,185)', 'rgb(83,55,150)', 'rgb(147,55,101)'\n ],\n [\n 'rgb(133,0,3)', 'rgb(163,74,10)', 'rgb(177,127,7)', 'rgb(45,101,23)', 'rgb(18,62,74)',\n 'rgb(14,62,129)', 'rgb(40,15,97)', 'rgb(95,16,55)'\n ],\n [\n 'rgb(81,0,1)', 'rgb(100,48,7)', 'rgb(107,78,3)', 'rgb(31,63,16)',\n 'rgb(13,39,46)', 'rgb(10,40,79)', 'rgb(24,12,59)', 'rgb(59,10,36)'\n ]\n ];\n});\n","Magento_Ui/js/core/app.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n './renderer/types',\n './renderer/layout',\n '../lib/knockout/bootstrap'\n], function (types, layout) {\n 'use strict';\n\n return function (data, merge) {\n types.set(data.types);\n layout(data.components, undefined, true, merge);\n };\n});\n","Magento_Ui/js/core/renderer/types.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'underscore',\n 'mageUtils'\n], function (_, utils) {\n 'use strict';\n\n var store = {};\n\n /**\n * Flatten a nested data.\n *\n * @param {Object} data\n * @returns {Object}\n */\n function flatten(data) {\n var extender = data.extends || [],\n result = {};\n\n extender = utils.stringToArray(extender);\n\n extender.push(data);\n\n extender.forEach(function (item) {\n if (_.isString(item)) {\n item = store[item] || {};\n }\n\n utils.extend(result, item);\n });\n\n delete result.extends;\n\n return result;\n }\n\n return {\n /**\n * Set types to store object.\n *\n * @param {Object} types\n */\n set: function (types) {\n types = types || {};\n\n utils.extend(store, types);\n\n _.each(types, function (data, type) {\n store[type] = flatten(data);\n });\n },\n\n /**\n * Get type from store object.\n *\n * @param {String} type\n * @returns {*|{}}\n */\n get: function (type) {\n return store[type] || {};\n }\n };\n});\n","Magento_Ui/js/core/renderer/layout.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'underscore',\n 'jquery',\n 'mageUtils',\n 'uiRegistry',\n './types',\n '../../lib/logger/console-logger'\n], function (_, $, utils, registry, types, consoleLogger) {\n 'use strict';\n\n var templates = registry.create(),\n layout = {},\n cachedConfig = {};\n\n /**\n * Build name from parent name and node name\n *\n * @param {Object} parent\n * @param {Object} node\n * @param {String} [name]\n * @returns {String}\n */\n function getNodeName(parent, node, name) {\n var parentName = parent && parent.name;\n\n if (typeof name !== 'string') {\n name = node.name || name;\n }\n\n return utils.fullPath(parentName, name);\n }\n\n /**\n * Get node type from node or parent.\n *\n * @param {Object} parent\n * @param {Object} node\n * @returns {String}\n */\n function getNodeType(parent, node) {\n return node.type || parent && parent.childType;\n }\n\n /**\n * Get data scope based on parent data scope and node data scope.\n *\n * @param {Object} parent\n * @param {Object} node\n * @returns {String}\n */\n function getDataScope(parent, node) {\n var dataScope = node.dataScope,\n parentScope = parent && parent.dataScope;\n\n return !utils.isEmpty(parentScope) ?\n !utils.isEmpty(dataScope) ?\n parentScope + '.' + dataScope :\n parentScope :\n dataScope || '';\n }\n\n /**\n * Load node dependencies on other instances.\n *\n * @param {Object} node\n * @returns {jQueryPromise}\n */\n function loadDeps(node) {\n var loaded = $.Deferred(),\n loggerUtils = consoleLogger.utils;\n\n if (node.deps) {\n consoleLogger.utils.asyncLog(\n loaded,\n {\n data: {\n component: node.name,\n deps: node.deps\n },\n messages: loggerUtils.createMessages(\n 'depsStartRequesting',\n 'depsFinishRequesting',\n 'depsLoadingFail'\n )\n }\n );\n }\n\n registry.get(node.deps, function (deps) {\n node.provider = node.extendProvider ? deps && deps.name : node.provider;\n loaded.resolve(node);\n });\n\n return loaded.promise();\n }\n\n /**\n * Load node component file via requirejs.\n *\n * @param {Object} node\n * @returns {jQueryPromise}\n */\n function loadSource(node) {\n var loaded = $.Deferred(),\n source = node.component;\n\n consoleLogger.info('componentStartLoading', {\n component: node.component\n });\n\n require([source], function (constr) {\n consoleLogger.info('componentFinishLoading', {\n component: node.component\n });\n loaded.resolve(node, constr);\n }, function () {\n consoleLogger.error('componentLoadingFail', {\n component: node.component\n });\n });\n\n return loaded.promise();\n }\n\n /**\n * Create a new component instance and set it to the registry.\n *\n * @param {Object} node\n * @param {Function} Constr\n */\n function initComponent(node, Constr) {\n var component = new Constr(_.omit(node, 'children'));\n\n consoleLogger.info('componentStartInitialization', {\n component: node.component,\n componentName: node.name\n });\n\n registry.set(node.name, component);\n }\n\n /**\n * Application entry point.\n *\n * @param {Object} nodes\n * @param {Object} parent\n * @param {Boolean} cached\n * @param {Boolean} merge\n * @returns {Boolean|undefined}\n */\n function run(nodes, parent, cached, merge) {\n if (_.isBoolean(merge) && merge) {\n layout.merge(nodes);\n\n return false;\n }\n\n if (cached) {\n cachedConfig[_.keys(nodes)[0]] = JSON.parse(JSON.stringify(nodes));\n }\n\n _.each(nodes || [], layout.iterator.bind(layout, parent));\n }\n\n _.extend(layout, {\n /**\n * Determines if node ready to be added or process it.\n *\n * @param {Object} parent\n * @param {Object|String} node\n */\n iterator: function (parent, node) {\n var action = _.isString(node) ?\n this.addChild :\n this.process;\n\n action.apply(this, arguments);\n },\n\n /**\n * Prepare component.\n *\n * @param {Object} parent\n * @param {Object} node\n * @param {String} name\n * @returns {Object}\n */\n process: function (parent, node, name) {\n if (!parent && node.parent) {\n return this.waitParent(node, name);\n }\n\n if (node.nodeTemplate) {\n return this.waitTemplate.apply(this, arguments);\n }\n\n node = this.build.apply(this, arguments);\n\n if (!registry.has(node.name)) {\n this.addChild(parent, node)\n .manipulate(node)\n .initComponent(node);\n }\n\n if (node) {\n run(node.children, node);\n }\n\n return this;\n },\n\n /**\n * Detailed processing of component config.\n *\n * @param {Object} parent\n * @param {Object} node\n * @param {String} name\n * @returns {Boolean|Object}\n */\n build: function (parent, node, name) {\n var defaults = parent && parent.childDefaults || {},\n children = this.filterDisabledChildren(node.children),\n type = getNodeType(parent, node),\n dataScope = getDataScope(parent, node),\n component,\n extendDeps = true,\n nodeName;\n\n node.children = false;\n node.extendProvider = true;\n\n if (node.config && node.config.provider || node.provider) {\n node.extendProvider = false;\n }\n\n if (node.config && node.config.deps || node.deps) {\n extendDeps = false;\n }\n\n node = utils.extend({\n }, types.get(type), defaults, node);\n\n nodeName = getNodeName(parent, node, name);\n\n if (registry.has(nodeName)) {\n component = registry.get(nodeName);\n component.children = children;\n\n return component;\n }\n\n if (extendDeps && parent && parent.deps && type) {\n node.deps = parent.deps;\n }\n\n _.extend(node, node.config || {}, {\n index: node.name || name,\n name: nodeName,\n dataScope: dataScope,\n parentName: utils.getPart(nodeName, -2),\n parentScope: utils.getPart(dataScope, -2)\n });\n\n node.children = children;\n node.componentType = node.type;\n\n delete node.type;\n delete node.config;\n\n if (children) {\n node.initChildCount = _.size(children);\n }\n\n if (node.isTemplate) {\n node.isTemplate = false;\n\n templates.set(node.name, node);\n registry.get(node.parentName, function (parentComp) {\n parentComp.childTemplate = node;\n });\n\n return false;\n }\n\n if (node.componentDisabled === true) {\n return false;\n }\n\n return node;\n },\n\n /**\n * Filter out all disabled components.\n *\n * @param {Object} children\n * @returns {*}\n */\n filterDisabledChildren: function (children) {\n var cIds;\n\n //cleanup children config.componentDisabled = true\n if (children && typeof children === 'object') {\n cIds = Object.keys(children);\n\n if (cIds) {\n _.each(cIds, function (cId) {\n if (typeof children[cId] === 'object' &&\n children[cId].hasOwnProperty('config') &&\n typeof children[cId].config === 'object' &&\n children[cId].config.hasOwnProperty('componentDisabled') &&\n children[cId].config.componentDisabled === true) {\n delete children[cId];\n }\n });\n }\n }\n\n return children;\n },\n\n /**\n * Init component.\n *\n * @param {Object} node\n * @returns {Object}\n */\n initComponent: function (node) {\n if (!node.component) {\n return this;\n }\n\n loadDeps(node)\n .then(loadSource)\n .done(initComponent);\n\n return this;\n }\n });\n\n _.extend(layout, {\n /**\n * Loading component marked as isTemplate.\n *\n * @param {Object} parent\n * @param {Object} node\n * @returns {Object}\n */\n waitTemplate: function (parent, node) {\n var args = _.toArray(arguments);\n\n templates.get(node.nodeTemplate, function () {\n this.applyTemplate.apply(this, args);\n }.bind(this));\n\n return this;\n },\n\n /**\n * Waiting for parent component and process provided component.\n *\n * @param {Object} node\n * @param {String} name\n * @returns {Object}\n */\n waitParent: function (node, name) {\n var process = this.process.bind(this);\n\n registry.get(node.parent, function (parent) {\n process(parent, node, name);\n });\n\n return this;\n },\n\n /**\n * Processing component marked as isTemplate.\n *\n * @param {Object} parent\n * @param {Object} node\n * @param {String} name\n */\n applyTemplate: function (parent, node, name) {\n var template = templates.get(node.nodeTemplate);\n\n node = utils.extend({}, template, node);\n\n delete node.nodeTemplate;\n\n this.process(parent, node, name);\n }\n });\n\n _.extend(layout, {\n /**\n * Determines inserting strategy.\n *\n * @param {Object} node\n * @returns {Object}\n */\n manipulate: function (node) {\n var name = node.name;\n\n if (node.appendTo) {\n this.insert(name, node.appendTo, -1);\n }\n\n if (node.prependTo) {\n this.insert(name, node.prependTo, 0);\n }\n\n if (node.insertTo) {\n this.insertTo(name, node.insertTo);\n }\n\n return this;\n },\n\n /**\n * Insert component to provide target and position.\n *\n * @param {Object|String} item\n * @param {Object} target\n * @param {Number} position\n * @returns {Object}\n */\n insert: function (item, target, position) {\n registry.get(target, function (container) {\n container.insertChild(item, position);\n });\n\n return this;\n },\n\n /**\n * Insert component into multiple targets.\n *\n * @param {Object} item\n * @param {Array} targets\n * @returns {Object}\n */\n insertTo: function (item, targets) {\n _.each(targets, function (info, target) {\n this.insert(item, target, info.position);\n }, this);\n\n return this;\n },\n\n /**\n * Add provided child to parent.\n *\n * @param {Object} parent\n * @param {Object|String} child\n * @returns {Object}\n */\n addChild: function (parent, child) {\n var name;\n\n if (parent && parent.component) {\n name = child.name || child;\n\n this.insert(name, parent.name, child.sortOrder);\n }\n\n return this;\n },\n\n /**\n * Merge components configuration with cached configuration.\n *\n * @param {Array} components\n */\n merge: function (components) {\n var cachedKey = _.keys(components)[0],\n compared = utils.compare(cachedConfig[cachedKey], components),\n remove = this.filterComponents(this.getByProperty(compared.changes, 'type', 'remove'), true),\n update = this.getByProperty(compared.changes, 'type', 'update'),\n dataSources = this.getDataSources(components),\n names, index, name, component;\n\n _.each(dataSources, function (val, key) {\n name = key.replace(/\\.children|\\.config/g, '');\n component = registry.get(name);\n\n component.cacheData();\n component.updateConfig(\n true,\n this.getFullConfig(key, components),\n this.getFullConfig(key, cachedConfig[cachedKey])\n );\n }, this);\n\n _.each(remove, function (val) {\n component = registry.get(val.path);\n\n if (component) {\n component.destroy();\n }\n });\n\n update = _.compact(_.filter(update, function (val) {\n return !_.isEqual(val.oldValue, val.value);\n }));\n\n _.each(update, function (val) {\n names = val.path.split('.');\n index = Math.max(_.lastIndexOf(names, 'config'), _.lastIndexOf(names, 'children') + 2);\n name = _.without(names.splice(0, index), 'children', 'config').join('.');\n component = registry.get(name);\n\n if (val.name === 'sortOrder' && component) {\n registry.get(component.parentName).insertChild(component, val.value);\n } else if (component) {\n component.updateConfig(\n val.oldValue,\n val.value,\n val.path\n );\n }\n }, this);\n\n run(components, undefined, true);\n },\n\n /**\n * Recursive dataSource assignment.\n *\n * @param {Object} config\n * @param {String} parentPath\n * @returns {Object}\n */\n getDataSources: function (config, parentPath) {\n var dataSources = {},\n key, obj;\n\n /* eslint-disable no-loop-func, max-depth */\n for (key in config) {\n if (config.hasOwnProperty(key)) {\n if (\n key === 'type' &&\n config[key] === 'dataSource' &&\n config.hasOwnProperty('config')\n ) {\n dataSources[parentPath + '.config'] = config.config;\n } else if (_.isObject(config[key])) {\n obj = this.getDataSources(config[key], utils.fullPath(parentPath, key));\n\n _.each(obj, function (value, path) {\n dataSources[path] = value;\n });\n }\n }\n }\n\n /* eslint-enable no-loop-func, max-depth */\n\n return dataSources;\n },\n\n /**\n * Configuration getter.\n *\n * @param {String} path\n * @param {Object} config\n * @returns {Boolean|Object}\n */\n getFullConfig: function (path, config) {\n var index;\n\n path = path.split('.');\n index = _.lastIndexOf(path, 'config');\n\n if (!~index) {\n return false;\n }\n path = path.splice(0, index);\n\n _.each(path, function (val) {\n config = config[val];\n });\n\n return config.config;\n },\n\n /**\n * Filter data by property and value.\n *\n * @param {Object} data\n * @param {String} prop\n * @param {*} propValue\n */\n getByProperty: function (data, prop, propValue) {\n return _.filter(data, function (value) {\n return value[prop] === propValue;\n });\n },\n\n /**\n * Filter components.\n *\n * @param {Array} data\n * @param {Boolean} splitPath\n * @param {Number} index\n * @param {String} separator\n * @param {String} keyName\n * @returns {Array}\n */\n filterComponents: function (data, splitPath, index, separator, keyName) {\n var result = [],\n names, length;\n\n index = -2;\n separator = '.' || separator;\n keyName = 'children' || keyName;\n\n _.each(data, function (val) {\n names = val.path.split(separator);\n length = names.length;\n\n if (names[length + index] === keyName) {\n val.path = splitPath ? _.without(names, keyName).join(separator) : val.path;\n result.push(val);\n }\n });\n\n return result;\n }\n });\n\n return run;\n});\n","Magento_Ui/js/lib/key-codes.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([], function () {\n 'use strict';\n\n return {\n 13: 'enterKey',\n 27: 'escapeKey',\n 40: 'pageDownKey',\n 38: 'pageUpKey',\n 32: 'spaceKey',\n 9: 'tabKey',\n 37: 'pageLeftKey',\n 39: 'pageRightKey',\n 17: 'ctrlKey',\n 18: 'altKey',\n 16: 'shiftKey',\n 191: 'forwardSlashKey',\n 66: 'bKey',\n 73: 'iKey',\n 85: 'uKey'\n };\n});\n","Magento_Ui/js/lib/spinner.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'jquery'\n], function ($) {\n 'use strict';\n\n var selector = '[data-role=\"spinner\"]',\n spinner = $(selector);\n\n return {\n /**\n * Show spinner.\n */\n show: function () {\n spinner.show();\n },\n\n /**\n * Hide spinner.\n */\n hide: function () {\n spinner.hide();\n },\n\n /**\n * Get spinner by selector.\n *\n * @param {String} id\n * @return {jQuery}\n */\n get: function (id) {\n return $(selector + '[data-component=\"' + id + '\"]');\n }\n };\n});\n","Magento_Ui/js/lib/collapsible.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n 'uiComponent'\n], function (Component) {\n 'use strict';\n\n return Component.extend({\n defaults: {\n opened: false,\n collapsible: true\n },\n\n /**\n * Initializes observable properties.\n *\n * @returns {Collapsible} Chainable.\n */\n initObservable: function () {\n this._super()\n .observe('opened');\n\n return this;\n },\n\n /**\n * Toggles value of the 'opened' property.\n *\n * @returns {Collapsible} Chainable.\n */\n toggleOpened: function () {\n this.opened() ?\n this.close() :\n this.open();\n\n return this;\n },\n\n /**\n * Sets 'opened' flag to false.\n *\n * @returns {Collapsible} Chainable.\n */\n close: function () {\n if (this.collapsible) {\n this.opened(false);\n }\n\n return this;\n },\n\n /**\n * Sets 'opened' flag to true.\n *\n * @returns {Collapsible} Chainable.\n */\n open: function () {\n if (this.collapsible) {\n this.opened(true);\n }\n\n return this;\n }\n });\n});\n","Magento_Ui/js/lib/knockout/bootstrap.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n/** Loads all available knockout bindings, sets custom template engine, initializes knockout on page */\n\ndefine([\n 'ko',\n './template/engine',\n 'knockoutjs/knockout-es5',\n './bindings/bootstrap',\n './extender/observable_array',\n './extender/bound-nodes',\n 'domReady!'\n], function (ko, templateEngine) {\n 'use strict';\n\n ko.uid = 0;\n\n ko.setTemplateEngine(templateEngine);\n ko.applyBindings();\n});\n","Magento_Ui/js/lib/knockout/extender/observable_array.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'ko',\n 'underscore'\n], function (ko, _) {\n 'use strict';\n\n /**\n * Iterator function.\n *\n * @param {String} callback\n * @param {Array} args\n * @param {Object} elem\n * @returns {*}\n */\n function iterator(callback, args, elem) {\n callback = elem[callback];\n\n if (_.isFunction(callback)) {\n return callback.apply(elem, args);\n }\n\n return callback;\n }\n\n /**\n * Wrapper function.\n *\n * @param {String} method\n * @returns {Function}\n */\n function wrapper(method) {\n return function (iteratee) {\n var callback = iteratee,\n elems = this(),\n args = _.toArray(arguments);\n\n if (_.isString(iteratee)) {\n callback = iterator.bind(null, iteratee, args.slice(1));\n\n args.unshift(callback);\n }\n\n args.unshift(elems);\n\n return _[method].apply(_, args);\n };\n }\n\n _.extend(ko.observableArray.fn, {\n each: wrapper('each'),\n\n map: wrapper('map'),\n\n filter: wrapper('filter'),\n\n some: wrapper('some'),\n\n every: wrapper('every'),\n\n groupBy: wrapper('groupBy'),\n\n sortBy: wrapper('sortBy'),\n\n /**\n * Wrapper for underscore findWhere function.\n *\n * @param {Object} properties\n * @return {Object}\n */\n findWhere: function (properties) {\n return _.findWhere(this(), properties);\n },\n\n /**\n * Wrapper for underscore contains function.\n *\n * @param {*} value\n * @return {Boolean}\n */\n contains: function (value) {\n return _.contains(this(), value);\n },\n\n /**\n * Inverse contains call.\n *\n * @return {Boolean}\n */\n hasNo: function () {\n return !this.contains.apply(this, arguments);\n },\n\n /**\n * Getter for length property.\n *\n * @return {Number}\n */\n getLength: function () {\n return this().length;\n },\n\n /**\n * Create object with keys that gets from each object property.\n *\n * @return {Object}\n */\n indexBy: function (key) {\n return _.indexBy(this(), key);\n },\n\n /**\n * Returns a copy of the array with all instances of the values removed.\n *\n * @return {Array}\n */\n without: function () {\n var args = Array.prototype.slice.call(arguments);\n\n args.unshift(this());\n\n return _.without.apply(_, args);\n },\n\n /**\n * Returns the first element of an array.\n *\n * @return {*}\n */\n first: function () {\n return _.first(this());\n },\n\n /**\n * Returns the last element of an array\n *\n * @return {*}\n */\n last: function () {\n return _.last(this());\n },\n\n /**\n * Iterate and pick provided properties.\n *\n * @return {Array}\n */\n pluck: function () {\n var args = Array.prototype.slice.call(arguments);\n\n args.unshift(this());\n\n return _.pluck.apply(_, args);\n }\n });\n});\n","Magento_Ui/js/lib/knockout/extender/bound-nodes.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'ko',\n 'underscore',\n 'mage/utils/wrapper',\n 'uiEvents'\n], function (ko, _, wrapper, Events) {\n 'use strict';\n\n var nodesMap = new WeakMap();\n\n /**\n * Returns a array of nodes associated with a specified model.\n *\n * @param {Object} model\n * @returns {Undefined|Array}\n */\n function getBounded(model) {\n return nodesMap.get(model);\n }\n\n /**\n * Removes specified node to models' associations list, if it's\n * a root node (node is not a descendant of any previously added nodes).\n * Triggers 'addNode' event.\n *\n * @param {Object} model\n * @param {HTMLElement} node\n */\n function addBounded(model, node) {\n var nodes = getBounded(model),\n isRoot;\n\n if (!nodes) {\n nodesMap.set(model, [node]);\n\n Events.trigger.call(model, 'addNode', node);\n\n return;\n }\n\n isRoot = nodes.every(function (bounded) {\n return !bounded.contains(node);\n });\n\n if (isRoot) {\n nodes.push(node);\n\n Events.trigger.call(model, 'addNode', node);\n }\n }\n\n /**\n * Removes specified node from models' associations list.\n * Triggers 'removeNode' event.\n *\n * @param {Object} model\n * @param {HTMLElement} node\n */\n function removeBounded(model, node) {\n var nodes = getBounded(model),\n index;\n\n if (!nodes) {\n return;\n }\n\n index = nodes.indexOf(node);\n\n if (~index) {\n nodes.splice(index, 0);\n\n Events.trigger.call(model, 'removeNode', node);\n }\n\n if (!nodes.length) {\n nodesMap.delete(model);\n }\n }\n\n /**\n * Returns node's first sibling of 'element' type within the common component scope\n *\n * @param {HTMLElement} node\n * @param {*} data\n * @returns {HTMLElement}\n */\n function getElement(node, data) {\n var elem;\n\n while (node.nextElementSibling) {\n node = node.nextElementSibling;\n\n if (node.nodeType === 1 && ko.dataFor(node) === data) {\n elem = node;\n break;\n }\n }\n\n return elem;\n }\n\n wrapper.extend(ko, {\n\n /**\n * Extends knockouts' 'applyBindings'\n * to track nodes associated with model.\n *\n * @param {Function} orig - Original 'applyBindings' method.\n * @param {Object} ctx\n * @param {HTMLElement} node - Original 'applyBindings' method.\n */\n applyBindings: function (orig, ctx, node) {\n var result = orig(),\n data = ctx && (ctx.$data || ctx);\n\n if (node && node.nodeType === 8) {\n node = getElement(node, data);\n }\n\n if (!node || node.nodeType !== 1) {\n return result;\n }\n\n if (data && data.registerNodes) {\n addBounded(data, node);\n }\n\n return result;\n },\n\n /**\n * Extends knockouts' cleanNode\n * to track nodes associated with model.\n *\n * @param {Function} orig - Original 'cleanNode' method.\n * @param {HTMLElement} node - Original 'cleanNode' method.\n */\n cleanNode: function (orig, node) {\n var result = orig(),\n data;\n\n if (node.nodeType !== 1) {\n return result;\n }\n\n data = ko.dataFor(node);\n\n if (data && data.registerNodes) {\n removeBounded(data, node);\n }\n\n return result;\n }\n });\n\n return {\n\n /**\n * Returns root nodes associated with a model. If callback is provided,\n * will iterate through all of the present nodes triggering callback\n * for each of it. Also it will subscribe to the 'addNode' event.\n *\n * @param {Object} model\n * @param {Function} [callback]\n * @returns {Array|Undefined}\n */\n get: function (model, callback) {\n var nodes = getBounded(model) || [];\n\n if (!_.isFunction(callback)) {\n return nodes;\n }\n\n nodes.forEach(function (node) {\n callback(node);\n });\n\n this.add.apply(this, arguments);\n },\n\n /**\n * Subscribes to adding of nodes associated with a model.\n *\n * @param {Object} model\n */\n add: function (model) {\n var args = _.toArray(arguments).slice(1);\n\n args.unshift('addNode');\n\n Events.on.apply(model, args);\n },\n\n /**\n * Subscribes to removal of nodes associated with a model.\n *\n * @param {Object} model\n */\n remove: function (model) {\n var args = _.toArray(arguments).slice(1);\n\n args.unshift('removeNode');\n\n Events.on.apply(model, args);\n },\n\n /**\n * Removes subscriptions from the model.\n *\n * @param {Object} model\n */\n off: function (model) {\n var args = _.toArray(arguments).slice(1);\n\n Events.off.apply(model, args);\n }\n };\n});\n","Magento_Ui/js/lib/knockout/template/observable_source.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n/**\n * Is being used by knockout template engine to store template to.\n */\ndefine([\n 'ko',\n 'uiClass'\n], function (ko, Class) {\n 'use strict';\n\n return Class.extend({\n\n /**\n * Initializes templateName, _data, nodes properties.\n *\n * @param {template} template - identifier of template\n */\n initialize: function (template) {\n this.templateName = template;\n this._data = {};\n this.nodes = ko.observable([]);\n },\n\n /**\n * Data setter. If only one arguments passed, returns corresponding value.\n * Else, writes into it.\n * @param {String} key - key to write to or to read from\n * @param {*} value\n * @return {*} - if 1 arg provided, Returns _data[key] property\n */\n data: function (key, value) {\n if (arguments.length === 1) {\n return this._data[key];\n }\n\n this._data[key] = value;\n }\n });\n});\n","Magento_Ui/js/lib/knockout/template/renderer.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n 'jquery',\n 'underscore',\n './loader'\n], function ($, _, loader) {\n 'use strict';\n\n var colonReg = /\\\\:/g,\n renderedTemplatePromises = {},\n attributes = {},\n elements = {},\n globals = [],\n renderer,\n preset;\n\n renderer = {\n\n /**\n * Loads template by provided path and\n * than converts it's content to html.\n *\n * @param {String} tmplPath - Path to the template.\n * @returns {jQueryPromise}\n * @alias getRendered\n */\n render: function (tmplPath) {\n var cachedPromise = renderedTemplatePromises[tmplPath];\n\n if (!cachedPromise) {\n cachedPromise = renderedTemplatePromises[tmplPath] = loader\n .loadTemplate(tmplPath)\n .then(renderer.parseTemplate);\n }\n\n return cachedPromise;\n },\n\n /**\n * @ignore\n */\n getRendered: function (tmplPath) {\n return renderer.render(tmplPath);\n },\n\n /**\n * Parses provided string as html content\n * and returns an array of DOM elements.\n *\n * @param {String} html - String to be processed.\n * @returns {Array}\n */\n parseTemplate: function (html) {\n var fragment = document.createDocumentFragment();\n\n $(fragment).append(html);\n\n return renderer.normalize(fragment);\n },\n\n /**\n * Processes custom attributes and nodes of provided DOM element.\n *\n * @param {HTMLElement} content - Element to be processed.\n * @returns {Array} An array of content's child nodes.\n */\n normalize: function (content) {\n globals.forEach(function (handler) {\n handler(content);\n });\n\n return _.toArray(content.childNodes);\n },\n\n /**\n * Adds new global content handler.\n *\n * @param {Function} handler - Function which will be invoked for\n * an every content passed to 'normalize' method.\n * @returns {Renderer} Chainable.\n */\n addGlobal: function (handler) {\n if (!_.contains(globals, handler)) {\n globals.push(handler);\n }\n\n return this;\n },\n\n /**\n * Removes specified global content handler.\n *\n * @param {Function} handler - Handler to be removed.\n * @returns {Renderer} Chainable.\n */\n removeGlobal: function (handler) {\n var index = globals.indexOf(handler);\n\n if (~index) {\n globals.splice(index, 1);\n }\n\n return this;\n },\n\n /**\n * Adds new custom attribute handler.\n *\n * @param {String} id - Attribute identifier.\n * @param {(Object|Function)} [config={}]\n * @returns {Renderer} Chainable.\n */\n addAttribute: function (id, config) {\n var data = {\n name: id,\n binding: id,\n handler: renderer.handlers.attribute\n };\n\n if (_.isFunction(config)) {\n data.handler = config;\n } else if (_.isObject(config)) {\n _.extend(data, config);\n }\n\n data.id = id;\n attributes[id] = data;\n\n return this;\n },\n\n /**\n * Removes specified attribute handler.\n *\n * @param {String} id - Attribute identifier.\n * @returns {Renderer} Chainable.\n */\n removeAttribute: function (id) {\n delete attributes[id];\n\n return this;\n },\n\n /**\n * Adds new custom node handler.\n *\n * @param {String} id - Node identifier.\n * @param {(Object|Function)} [config={}]\n * @returns {Renderer} Chainable.\n */\n addNode: function (id, config) {\n var data = {\n name: id,\n binding: id,\n handler: renderer.handlers.node\n };\n\n if (_.isFunction(config)) {\n data.handler = config;\n } else if (_.isObject(config)) {\n _.extend(data, config);\n }\n\n data.id = id;\n elements[id] = data;\n\n return this;\n },\n\n /**\n * Removes specified custom node handler.\n *\n * @param {String} id - Node identifier.\n * @returns {Renderer} Chainable.\n */\n removeNode: function (id) {\n delete elements[id];\n\n return this;\n },\n\n /**\n * Checks if provided DOM element is a custom node.\n *\n * @param {HTMLElement} node - Node to be checked.\n * @returns {Boolean}\n */\n isCustomNode: function (node) {\n return _.some(elements, function (elem) {\n return elem.name.toUpperCase() === node.tagName;\n });\n },\n\n /**\n * Processes custom attributes of a content's child nodes.\n *\n * @param {HTMLElement} content - DOM element to be processed.\n */\n processAttributes: function (content) {\n var repeat;\n\n repeat = _.some(attributes, function (attr) {\n var attrName = attr.name,\n nodes = content.querySelectorAll('[' + attrName + ']'),\n handler = attr.handler;\n\n return _.toArray(nodes).some(function (node) {\n var data = node.getAttribute(attrName);\n\n return handler(node, data, attr) === true;\n });\n });\n\n if (repeat) {\n renderer.processAttributes(content);\n }\n },\n\n /**\n * Processes custom nodes of a provided content.\n *\n * @param {HTMLElement} content - DOM element to be processed.\n */\n processNodes: function (content) {\n var repeat;\n\n repeat = _.some(elements, function (element) {\n var nodes = content.querySelectorAll(element.name),\n handler = element.handler;\n\n return _.toArray(nodes).some(function (node) {\n var data = node.getAttribute('args');\n\n return handler(node, data, element) === true;\n });\n });\n\n if (repeat) {\n renderer.processNodes(content);\n }\n },\n\n /**\n * Wraps provided string in curly braces if it's necessary.\n *\n * @param {String} args - String to be wrapped.\n * @returns {String} Wrapped string.\n */\n wrapArgs: function (args) {\n if (~args.indexOf('\\\\:')) {\n args = args.replace(colonReg, ':');\n } else if (~args.indexOf(':') && !~args.indexOf('}')) {\n args = '{' + args + '}';\n }\n\n return args;\n },\n\n /**\n * Wraps child nodes of provided DOM element\n * with knockout's comment tag.\n *\n * @param {HTMLElement} node - Node whose children should be wrapped.\n * @param {String} binding - Name of the binding for the opener comment tag.\n * @param {String} data - Data associated with a binding.\n *\n * @example\n * <div id=\"example\"><span/></div>\n * wrapChildren(document.getElementById('example'), 'foreach', 'data');\n * =>\n * <div id=\"example\">\n * <!-- ko foreach: data -->\n * <span></span>\n * <!-- /ko -->\n * </div>\n */\n wrapChildren: function (node, binding, data) {\n var tag = this.createComment(binding, data),\n $node = $(node);\n\n $node.prepend(tag.open);\n $node.append(tag.close);\n },\n\n /**\n * Wraps specified node with knockout's comment tag.\n *\n * @param {HTMLElement} node - Node to be wrapped.\n * @param {String} binding - Name of the binding for the opener comment tag.\n * @param {String} data - Data associated with a binding.\n *\n * @example\n * <div id=\"example\"></div>\n * wrapNode(document.getElementById('example'), 'foreach', 'data');\n * =>\n * <!-- ko foreach: data -->\n * <div id=\"example\"></div>\n * <!-- /ko -->\n */\n wrapNode: function (node, binding, data) {\n var tag = this.createComment(binding, data),\n $node = $(node);\n\n $node.before(tag.open);\n $node.after(tag.close);\n },\n\n /**\n * Creates knockouts' comment tag for the provided binding.\n *\n * @param {String} binding - Name of the binding.\n * @param {String} data - Data associated with a binding.\n * @returns {Object} Object with an open and close comment elements.\n */\n createComment: function (binding, data) {\n return {\n open: document.createComment(' ko ' + binding + ': ' + data + ' '),\n close: document.createComment(' /ko ')\n };\n }\n };\n\n renderer.handlers = {\n\n /**\n * Basic node handler. Replaces custom nodes\n * with a corresponding knockout's comment tag.\n *\n * @param {HTMLElement} node - Node to be processed.\n * @param {String} data\n * @param {Object} element\n * @returns {Boolean} True\n *\n * @example Sample syntaxes conversions.\n * <with args=\"model\">\n * <span/>\n * </with>\n * =>\n * <!-- ko with: model-->\n * <span/>\n * <!-- /ko -->\n */\n node: function (node, data, element) {\n data = renderer.wrapArgs(data);\n\n renderer.wrapNode(node, element.binding, data);\n $(node).replaceWith(node.childNodes);\n\n return true;\n },\n\n /**\n * Base attribute handler. Replaces custom attributes with\n * a corresponding knockouts' data binding.\n *\n * @param {HTMLElement} node - Node to be processed.\n * @param {String} data - Data associated with a binding.\n * @param {Object} attr - Attribute definition.\n *\n * @example Sample syntaxes conversions.\n * <div text=\"label\"></div>\n * =>\n * <div data-bind=\"text: label\"></div>\n */\n attribute: function (node, data, attr) {\n data = renderer.wrapArgs(data);\n\n renderer.bindings.add(node, attr.binding, data);\n node.removeAttribute(attr.name);\n },\n\n /**\n * Wraps provided node with a knockouts' comment tag.\n *\n * @param {HTMLElement} node - Node that will be wrapped.\n * @param {String} data - Data associated with a binding.\n * @param {Object} attr - Attribute definition.\n *\n * @example\n * <div outereach=\"data\" class=\"test\"></div>\n * =>\n * <!-- ko foreach: data -->\n * <div class=\"test\"></div>\n * <!-- /ko -->\n */\n wrapAttribute: function (node, data, attr) {\n data = renderer.wrapArgs(data);\n\n renderer.wrapNode(node, attr.binding, data);\n node.removeAttribute(attr.name);\n }\n };\n\n renderer.bindings = {\n\n /**\n * Appends binding string to the current\n * 'data-bind' attribute of provided node.\n *\n * @param {HTMLElement} node - DOM element whose 'data-bind' attribute will be extended.\n * @param {String} name - Name of a binding.\n * @param {String} data - Data associated with the binding.\n */\n add: function (node, name, data) {\n var bindings = this.get(node);\n\n if (bindings) {\n bindings += ', ';\n }\n\n bindings += name;\n\n if (data) {\n bindings += ': ' + data;\n }\n\n this.set(node, bindings);\n },\n\n /**\n * Extracts value of a 'data-bind' attribute from provided node.\n *\n * @param {HTMLElement} node - Node whose attribute to be extracted.\n * @returns {String}\n */\n get: function (node) {\n return node.getAttribute('data-bind') || '';\n },\n\n /**\n * Sets 'data-bind' attribute of the specified node\n * to the provided value.\n *\n * @param {HTMLElement} node - Node whose attribute will be altered.\n * @param {String} bindings - New value of 'data-bind' attribute.\n */\n set: function (node, bindings) {\n node.setAttribute('data-bind', bindings);\n }\n };\n\n renderer\n .addGlobal(renderer.processAttributes)\n .addGlobal(renderer.processNodes);\n\n /**\n * Collection of default binding conversions.\n */\n preset = {\n nodes: _.object([\n 'if',\n 'text',\n 'with',\n 'scope',\n 'ifnot',\n 'foreach',\n 'component'\n ], Array.prototype),\n attributes: _.object([\n 'css',\n 'attr',\n 'html',\n 'with',\n 'text',\n 'click',\n 'event',\n 'submit',\n 'enable',\n 'disable',\n 'options',\n 'visible',\n 'template',\n 'hasFocus',\n 'textInput',\n 'component',\n 'uniqueName',\n 'optionsText',\n 'optionsValue',\n 'checkedValue',\n 'selectedOptions'\n ], Array.prototype)\n };\n\n _.extend(preset.attributes, {\n if: renderer.handlers.wrapAttribute,\n ifnot: renderer.handlers.wrapAttribute,\n innerif: {\n binding: 'if'\n },\n innerifnot: {\n binding: 'ifnot'\n },\n outereach: {\n binding: 'foreach',\n handler: renderer.handlers.wrapAttribute\n },\n foreach: {\n name: 'each'\n },\n value: {\n name: 'ko-value'\n },\n style: {\n name: 'ko-style'\n },\n checked: {\n name: 'ko-checked'\n },\n disabled: {\n name: 'ko-disabled',\n binding: 'disable'\n },\n focused: {\n name: 'ko-focused',\n binding: 'hasFocus'\n },\n\n /**\n * Custom 'render' attribute handler function. Wraps child elements\n * of a node with knockout's 'ko template:' comment tag.\n *\n * @param {HTMLElement} node - Element to be processed.\n * @param {String} data - Data specified in 'render' attribute of a node.\n */\n render: function (node, data) {\n data = data || 'getTemplate()';\n data = renderer.wrapArgs(data);\n\n renderer.wrapChildren(node, 'template', data);\n node.removeAttribute('render');\n }\n });\n\n _.extend(preset.nodes, {\n foreach: {\n name: 'each'\n },\n\n /**\n * Custom 'render' node handler function.\n * Replaces node with knockout's 'ko template:' comment tag.\n *\n * @param {HTMLElement} node - Element to be processed.\n * @param {String} data - Data specified in 'args' attribute of a node.\n */\n render: function (node, data) {\n data = data || 'getTemplate()';\n data = renderer.wrapArgs(data);\n\n renderer.wrapNode(node, 'template', data);\n $(node).replaceWith(node.childNodes);\n }\n });\n\n _.each(preset.attributes, function (data, id) {\n renderer.addAttribute(id, data);\n });\n\n _.each(preset.nodes, function (data, id) {\n renderer.addNode(id, data);\n });\n\n return renderer;\n});\n","Magento_Ui/js/lib/knockout/template/engine.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n 'jquery',\n 'ko',\n 'underscore',\n './observable_source',\n './renderer',\n '../../logger/console-logger'\n], function ($, ko, _, Source, renderer, consoleLogger) {\n 'use strict';\n\n var RemoteTemplateEngine,\n NativeTemplateEngine = ko.nativeTemplateEngine,\n sources = {};\n\n /**\n * Remote template engine class. Is used to be able to load remote templates via knockout template binding.\n */\n RemoteTemplateEngine = function () {\n // Instance reference for closure.\n var engine = this,\n // Decorate the builtin Knockout \"template\" binding to track synchronous template renders.\n origUpdate = ko.bindingHandlers.template.update;\n\n /**\n * Counter to track the number of currently running render tasks (both synchronous and asynchronous).\n * @type {Number}\n * @private\n */\n this._rendersOutstanding = 0;\n\n /**\n * Use a jQuery object as an event bus (but any event emitter with on/off/emit methods could work)\n * @type {jQuery}\n * @private\n */\n this._events = $(this);\n\n /**\n * Rendered templates\n * @type {Object}\n * @private\n */\n this._templatesRendered = {};\n\n /*eslint-disable no-unused-vars*/\n /**\n * Decorate update method\n *\n * @param {HTMLElement} element\n * @param {Function} valueAccessor\n * @param {Object} allBindings\n * @param {Object} viewModel\n * @param {ko.bindingContext} bindingContext\n * @returns {*}\n */\n ko.bindingHandlers.template.update = function (element, valueAccessor, allBindings, viewModel, bindingContext) {\n /*eslint-enable no-unused-vars*/\n var options = ko.utils.peekObservable(valueAccessor()),\n templateName,\n isSync,\n updated;\n\n if (typeof options === 'object') {\n if (options.templateEngine && options.templateEngine !== engine) {\n return origUpdate.apply(this, arguments);\n }\n\n if (!options.name) {\n consoleLogger.error('Could not find template name', options);\n }\n templateName = options.name;\n } else if (typeof options === 'string') {\n templateName = options;\n } else {\n consoleLogger.error('Could not build a template binding', options);\n }\n engine._trackRender(templateName);\n isSync = engine._hasTemplateLoaded(templateName);\n updated = origUpdate.apply(this, arguments);\n\n if (isSync) {\n engine._releaseRender(templateName, 'sync');\n }\n\n return updated;\n };\n };\n\n /**\n * Creates unique template identifier based on template name and it's extenders (optional)\n * @param {String} templateName\n * @return {String} - unique template identifier\n */\n function createTemplateIdentifier(templateName) {\n return templateName;\n }\n\n RemoteTemplateEngine.prototype = new NativeTemplateEngine;\n RemoteTemplateEngine.prototype.constructor = RemoteTemplateEngine;\n\n /**\n * When an asynchronous render task begins, increment the internal counter for tracking when renders are complete.\n * @private\n */\n RemoteTemplateEngine.prototype._trackRender = function (templateName) {\n var rendersForTemplate = this._templatesRendered[templateName] !== undefined ?\n this._templatesRendered[templateName] : 0;\n\n this._rendersOutstanding++;\n this._templatesRendered[templateName] = rendersForTemplate + 1;\n this._resolveRenderWaits();\n };\n\n /**\n * When an asynchronous render task ends, decrement the internal counter for tracking when renders are complete.\n * @private\n */\n RemoteTemplateEngine.prototype._releaseRender = function (templateName) {\n var rendersForTemplate = this._templatesRendered[templateName];\n\n this._rendersOutstanding--;\n this._templatesRendered[templateName] = rendersForTemplate - 1;\n this._resolveRenderWaits();\n };\n\n /**\n * Check to see if renders are complete and trigger events for listeners.\n * @private\n */\n RemoteTemplateEngine.prototype._resolveRenderWaits = function () {\n if (this._rendersOutstanding === 0) {\n this._events.triggerHandler('finishrender');\n }\n };\n\n /**\n * Get a promise for the end of the current run of renders, both sync and async.\n * @return {jQueryPromise} - promise that resolves when render completes\n */\n RemoteTemplateEngine.prototype.waitForFinishRender = function () {\n var defer = $.Deferred();\n\n this._events.one('finishrender', defer.resolve);\n\n return defer.promise();\n };\n\n /**\n * Returns true if this template has already been asynchronously loaded and will be synchronously rendered.\n * @param {String} templateName\n * @returns {Boolean}\n * @private\n */\n RemoteTemplateEngine.prototype._hasTemplateLoaded = function (templateName) {\n // Sources object will have cached template once makeTemplateSource has run\n return sources.hasOwnProperty(templateName);\n };\n\n /**\n * Overrided method of native knockout template engine.\n * Caches template after it's unique name and renders in once.\n * If template name is not typeof string, delegates work to knockout.templateSources.anonymousTemplate.\n * @param {*} template\n * @param {HTMLElement} templateDocument - document\n * @param {Object} options - options, passed to template binding\n * @param {ko.bindingContext} bindingContext\n * @returns {TemplateSource} Object with methods 'nodes' and 'data'.\n */\n RemoteTemplateEngine.prototype.makeTemplateSource = function (template, templateDocument, options, bindingContext) {\n var engine = this,\n source,\n templateId;\n\n if (typeof template === 'string') {\n templateId = createTemplateIdentifier(template);\n source = sources[templateId];\n\n if (!source) {\n source = new Source(template);\n source.requestedBy = bindingContext.$data.name;\n sources[templateId] = source;\n\n consoleLogger.info('templateStartLoading', {\n template: templateId,\n component: bindingContext.$data.name\n });\n\n renderer.render(template).then(function (rendered) {\n consoleLogger.info('templateLoadedFromServer', {\n template: templateId,\n component: bindingContext.$data.name\n });\n source.nodes(rendered);\n engine._releaseRender(templateId, 'async');\n }).fail(function () {\n consoleLogger.error('templateLoadingFail', {\n template: templateId,\n component: bindingContext.$data.name\n });\n });\n }\n\n if (source.requestedBy !== bindingContext.$data.name) {\n consoleLogger.info('templateLoadedFromCache', {\n template: templateId,\n component: bindingContext.$data.name\n });\n }\n\n return source;\n } else if (template.nodeType === 1 || template.nodeType === 8) {\n source = new ko.templateSources.anonymousTemplate(template);\n\n return source;\n }\n\n throw new Error('Unknown template type: ' + template);\n };\n\n /**\n * Overrided method of native knockout template engine.\n * Should return array of html elements.\n * @param {TemplateSource} templateSource - object with methods 'nodes' and 'data'.\n * @return {Array} - array of html elements\n */\n RemoteTemplateEngine.prototype.renderTemplateSource = function (templateSource) {\n var nodes = templateSource.nodes();\n\n return ko.utils.cloneNodes(nodes);\n };\n\n /**\n * Overrided method of native knockout template engine.\n * Created in order to invoke makeTemplateSource method with custom set of params.\n * @param {*} template - template identifier\n * @param {ko.bindingContext} bindingContext\n * @param {Object} options - options, passed to template binding\n * @param {HTMLElement} templateDocument - document\n * @return {Array} - array of html elements\n */\n RemoteTemplateEngine.prototype.renderTemplate = function (template, bindingContext, options, templateDocument) {\n var templateSource = this.makeTemplateSource(template, templateDocument, options, bindingContext);\n\n return this.renderTemplateSource(templateSource);\n };\n\n return new RemoteTemplateEngine;\n});\n","Magento_Ui/js/lib/knockout/template/loader.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n 'jquery'\n], function ($) {\n 'use strict';\n\n var licenseRegExp = /<!--[\\s\\S]*?-->/,\n defaultPlugin = 'text',\n defaultExt = 'html';\n\n /**\n * Checks of provided string contains a file extension.\n *\n * @param {String} str - String to be checked.\n * @returns {Boolean}\n */\n function hasFileExtension(str) {\n return !!~str.indexOf('.') && !!str.split('.').pop();\n }\n\n /**\n * Checks if provided string contains a requirejs's plugin reference.\n *\n * @param {String} str - String to be checked.\n * @returns {Boolean}\n */\n function hasPlugin(str) {\n return !!~str.indexOf('!');\n }\n\n /**\n * Checks if provided string is a full path to the file.\n *\n * @param {String} str - String to be checked.\n * @returns {Boolean}\n */\n function isFullPath(str) {\n return !!~str.indexOf('://');\n }\n\n /**\n * Removes license comment from the provided string.\n *\n * @param {String} content - String to be processed.\n * @returns {String}\n */\n function removeLicense(content) {\n return content.replace(licenseRegExp, function (match) {\n return ~match.indexOf('/**') ? '' : match;\n });\n }\n\n return {\n\n /**\n * Attempts to extract template by provided path from\n * a DOM element and falls back to a file loading if\n * none of the DOM nodes was found.\n *\n * @param {String} path - Path to the template or a DOM selector.\n * @returns {jQueryPromise}\n */\n loadTemplate: function (path) {\n var content = this.loadFromNode(path),\n defer;\n\n if (content) {\n defer = $.Deferred();\n\n defer.resolve(content);\n\n return defer.promise();\n }\n\n return this.loadFromFile(path);\n },\n\n /**\n * Loads template from external file by provided\n * path, which will be preliminary formatted.\n *\n * @param {String} path - Path to the template.\n * @returns {jQueryPromise}\n */\n loadFromFile: function (path) {\n var loading = $.Deferred();\n\n path = this.formatPath(path);\n\n require([path], function (template) {\n template = removeLicense(template);\n loading.resolve(template);\n }, function (err) {\n loading.reject(err);\n });\n\n return loading.promise();\n },\n\n /**\n * Attempts to extract content of a node found by provided selector.\n *\n * @param {String} selector - Node's selector (not necessary valid).\n * @returns {String|Boolean} If specified node doesn't exists\n * 'false' will be returned, otherwise returns node's content.\n */\n loadFromNode: function (selector) {\n var node;\n\n try {\n node =\n document.getElementById(selector) ||\n document.querySelector(selector);\n\n return node ? node.innerHTML : false;\n } catch (e) {\n return false;\n }\n },\n\n /**\n * Adds requirejs's plugin and file extension to\n * to the provided string if it's necessary.\n *\n * @param {String} path - Path to be processed.\n * @returns {String} Formatted path.\n */\n formatPath: function (path) {\n var result = path;\n\n if (!hasPlugin(path)) {\n result = defaultPlugin + '!' + result;\n }\n\n if (isFullPath(path)) {\n return result;\n }\n\n if (!hasFileExtension(path)) {\n result += '.' + defaultExt;\n }\n\n return result.replace(/^([^\\/]+)/g, '$1/template');\n }\n };\n});\n","Magento_Ui/js/lib/knockout/bindings/keyboard.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n 'ko',\n '../template/renderer'\n], function (ko, renderer) {\n 'use strict';\n\n ko.bindingHandlers.keyboard = {\n\n /**\n * Attaches keypress handlers to element\n * @param {HTMLElement} el - Element, that binding is applied to\n * @param {Function} valueAccessor - Function that returns value, passed to binding\n * @param {Object} allBindings - all bindings object\n * @param {Object} viewModel - reference to viewmodel\n */\n init: function (el, valueAccessor, allBindings, viewModel) {\n var map = valueAccessor();\n\n ko.utils.registerEventHandler(el, 'keyup', function (e) {\n var callback = map[e.keyCode];\n\n if (callback) {\n return callback.call(viewModel, e);\n }\n });\n }\n };\n\n renderer.addAttribute('keyboard');\n});\n","Magento_Ui/js/lib/knockout/bindings/tooltip.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'jquery',\n 'ko',\n 'underscore',\n 'mage/template',\n 'text!ui/template/tooltip/tooltip.html',\n '../template/renderer'\n], function ($, ko, _, template, tooltipTmpl, renderer) {\n 'use strict';\n\n var tooltip,\n defaults,\n positions,\n transformProp,\n checkedPositions = {},\n iterator = 0,\n previousTooltip,\n tooltipData,\n positionData = {},\n tooltipsCollection = {},\n isTouchDevice = (function () {\n return 'ontouchstart' in document.documentElement;\n })(),\n CLICK_EVENT = (function () {\n return isTouchDevice ? 'touchstart' : 'click';\n })();\n\n defaults = {\n tooltipWrapper: '[data-tooltip=tooltip-wrapper]',\n tooltipContentBlock: 'data-tooltip-content',\n closeButtonClass: 'action-close',\n tailClass: 'data-tooltip-tail',\n action: 'hover',\n delay: 300,\n track: false,\n step: 20,\n position: 'top',\n closeButton: false,\n showed: false,\n strict: true,\n center: false,\n closeOnScroll: true\n };\n\n tooltipData = {\n tooltipClasses: '',\n trigger: false,\n timeout: 0,\n element: false,\n event: false,\n targetElement: {},\n showed: false,\n currentID: 0\n };\n\n /**\n * Polyfill for css transform\n */\n transformProp = (function () {\n var style = document.createElement('div').style,\n base = 'Transform',\n vendors = ['webkit', 'moz', 'ms', 'o'],\n vi = vendors.length,\n property;\n\n if (typeof style.transform !== 'undefined') {\n return 'transform';\n }\n\n while (vi--) {\n property = vendors[vi] + base;\n\n if (typeof style[property] !== 'undefined') {\n return property;\n }\n }\n })();\n\n positions = {\n\n /*eslint max-depth: [0, 0]*/\n\n map: {\n horizontal: {\n s: 'w',\n p: 'left'\n },\n vertical: {\n s: 'h',\n p: 'top'\n }\n },\n\n /**\n * Wrapper function to get tooltip data (position, className, etc)\n *\n * @param {Object} s - object with sizes and positions elements\n * @returns {Object} tooltip data (position, className, etc)\n */\n top: function (s) {\n return positions._topLeftChecker(s, positions.map, 'vertical', '_bottom', 'top', 'right');\n },\n\n /**\n * Wrapper function to get tooltip data (position, className, etc)\n *\n * @param {Object} s - object with sizes and positions elements\n * @returns {Object} tooltip data (position, className, etc)\n */\n left: function (s) {\n return positions._topLeftChecker(s, positions.map, 'horizontal', '_right', 'left', 'top');\n },\n\n /**\n * Wrapper function to get tooltip data (position, className, etc)\n *\n * @param {Object} s - object with sizes and positions elements\n * @returns {Object} tooltip data (position, className, etc)\n */\n bottom: function (s) {\n return positions._bottomRightChecker(s, positions.map, 'vertical', '_top', 'bottom', 'left');\n },\n\n /**\n * Wrapper function to get tooltip data (position, className, etc)\n *\n * @param {Object} s - object with sizes and positions elements\n * @returns {Object} tooltip data (position, className, etc)\n */\n right: function (s) {\n return positions._bottomRightChecker(s, positions.map, 'horizontal', '_left', 'right', 'bottom');\n },\n\n /**\n * Check can tooltip setted on current position or not. If can't setted - delegate call.\n *\n * @param {Object} s - object with sizes and positions elements\n * @param {Object} map - mapping for get direction positions\n * @param {String} direction - vertical or horizontal\n * @param {String} className - class whats should be setted to tooltip\n * @param {String} side - parent method name\n * @param {String} delegate - method name if tooltip can't be setted in current position\n * @returns {Object} tooltip data (position, className, etc)\n */\n _topLeftChecker: function (s, map, direction, className, side, delegate) {\n var result = {\n position: {}\n },\n config = tooltip.getTooltip(tooltipData.currentID),\n startPosition = !config.strict ? s.eventPosition : s.elementPosition,\n changedDirection;\n\n checkedPositions[side] = true;\n\n if (\n startPosition[map[direction].p] - s.tooltipSize[map[direction].s] - config.step >\n s.scrollPosition[map[direction].p]\n ) {\n result.position[map[direction].p] = startPosition[map[direction].p] - s.tooltipSize[map[direction].s] -\n config.step;\n result.className = className;\n result.side = side;\n changedDirection = direction === 'vertical' ? 'horizontal' : 'vertical';\n result = positions._normalize(s, result, config, delegate, map, changedDirection);\n } else if (!checkedPositions[delegate]) {\n result = positions[delegate].apply(null, arguments);\n } else {\n result = positions.positionCenter(s, result);\n }\n\n return result;\n },\n\n /**\n * Check can tooltip setted on current position or not. If can't setted - delegate call.\n *\n * @param {Object} s - object with sizes and positions elements\n * @param {Object} map - mapping for get direction positions\n * @param {String} direction - vertical or horizontal\n * @param {String} className - class whats should be setted to tooltip\n * @param {String} side - parent method name\n * @param {String} delegate - method name if tooltip can't be setted in current position\n * @returns {Object} tooltip data (position, className, etc)\n */\n _bottomRightChecker: function (s, map, direction, className, side, delegate) {\n var result = {\n position: {}\n },\n config = tooltip.getTooltip(tooltipData.currentID),\n startPosition = !config.strict ? s.eventPosition : {\n top: s.elementPosition.top + s.elementSize.h,\n left: s.elementPosition.left + s.elementSize.w\n },\n changedDirection;\n\n checkedPositions[side] = true;\n\n if (\n startPosition[map[direction].p] + s.tooltipSize[map[direction].s] + config.step <\n s.scrollPosition[map[direction].p] + s.windowSize[map[direction].s]\n ) {\n result.position[map[direction].p] = startPosition[map[direction].p] + config.step;\n result.className = className;\n result.side = side;\n changedDirection = direction === 'vertical' ? 'horizontal' : 'vertical';\n result = positions._normalize(s, result, config, delegate, map, changedDirection);\n } else if (!checkedPositions[delegate]) {\n result = positions[delegate].apply(null, arguments);\n } else {\n result = positions.positionCenter(s, result);\n }\n\n return result;\n },\n\n /**\n * Centered tooltip if tooltip does not fit in window\n *\n * @param {Object} s - object with sizes and positions elements\n * @param {Object} data - current data (position, className, etc)\n * @returns {Object} tooltip data (position, className, etc)\n */\n positionCenter: function (s, data) {\n data = positions._positionCenter(s, data, 'horizontal', positions.map);\n data = positions._positionCenter(s, data, 'vertical', positions.map);\n\n return data;\n },\n\n /**\n * Centered tooltip side\n *\n * @param {Object} s - object with sizes and positions elements\n * @param {Object} data - current data (position, className, etc)\n * @param {String} direction - vertical or horizontal\n * @param {Object} map - mapping for get direction positions\n * @returns {Object} tooltip data (position, className, etc)\n */\n _positionCenter: function (s, data, direction, map) {\n if (s.tooltipSize[map[direction].s] < s.windowSize[map[direction].s]) {\n data.position[map[direction].p] = (s.windowSize[map[direction].s] -\n s.tooltipSize[map[direction].s]) / 2 + s.scrollPosition[map[direction].p];\n } else {\n data.position[map[direction].p] = s.scrollPosition[map[direction].p];\n data.tooltipSize = {};\n data.tooltipSize[map[direction].s] = s.windowSize[map[direction].s];\n }\n\n return data;\n },\n\n /**\n * Normalize horizontal or vertical position.\n *\n * @param {Object} s - object with sizes and positions elements\n * @param {Object} data - current data (position, className, etc)\n * @param {Object} config - tooltip config\n * @param {String} delegate - method name if tooltip can't be setted in current position\n * @param {Object} map - mapping for get direction positions\n * @param {String} direction - vertical or horizontal\n * @returns {Object} tooltip data (position, className, etc)\n */\n _normalize: function (s, data, config, delegate, map, direction) {\n var startPosition = !config.center ? s.eventPosition : {\n left: s.elementPosition.left + s.elementSize.w / 2,\n top: s.elementPosition.top + s.elementSize.h / 2\n },\n depResult;\n\n if (startPosition[map[direction].p] - s.tooltipSize[map[direction].s] / 2 >\n s.scrollPosition[map[direction].p] && startPosition[map[direction].p] +\n s.tooltipSize[map[direction].s] / 2 <\n s.scrollPosition[map[direction].p] + s.windowSize[map[direction].s]\n ) {\n data.position[map[direction].p] = startPosition[map[direction].p] - s.tooltipSize[map[direction].s] / 2;\n } else {\n\n /*eslint-disable no-lonely-if*/\n if (!checkedPositions[delegate]) {\n depResult = positions[delegate].apply(null, arguments);\n\n if (depResult.hasOwnProperty('className')) {\n data = depResult;\n } else {\n data = positions._normalizeTail(s, data, config, delegate, map, direction, startPosition);\n }\n } else {\n data = positions._normalizeTail(s, data, config, delegate, map, direction, startPosition);\n }\n }\n\n return data;\n },\n\n /**\n * Calc tail position.\n *\n * @param {Object} s - object with sizes and positions elements\n * @param {Object} data - current data (position, className, etc)\n * @param {Object} config - tooltip config\n * @param {String} delegate - method name if tooltip can't be setted in current position\n * @param {Object} map - mapping for get direction positions\n * @param {String} direction - vertical or horizontal\n * @param {Object} startPosition - start position\n * @returns {Object} tooltip data (position, className, etc)\n */\n _normalizeTail: function (s, data, config, delegate, map, direction, startPosition) {\n data.tail = {};\n\n if (s.tooltipSize[map[direction].s] < s.windowSize[map[direction].s]) {\n\n if (\n startPosition[map[direction].p] >\n s.windowSize[map[direction].s] / 2 + s.scrollPosition[map[direction].p]\n ) {\n data.position[map[direction].p] = s.windowSize[map[direction].s] +\n s.scrollPosition[map[direction].p] - s.tooltipSize[map[direction].s];\n data.tail[map[direction].p] = startPosition[map[direction].p] -\n s.tooltipSize[map[direction].s] / 2 - data.position[map[direction].p];\n } else {\n data.position[map[direction].p] = s.scrollPosition[map[direction].p];\n data.tail[map[direction].p] = startPosition[map[direction].p] -\n s.tooltipSize[map[direction].s] / 2 - data.position[map[direction].p];\n }\n } else {\n data.position[map[direction].p] = s.scrollPosition[map[direction].p];\n data.tail[map[direction].p] = s.eventPosition[map[direction].p] - s.windowSize[map[direction].s] / 2;\n data.tooltipSize = {};\n data.tooltipSize[map[direction].s] = s.windowSize[map[direction].s];\n }\n\n return data;\n }\n };\n\n tooltip = {\n\n /**\n * Set new tooltip to tooltipCollection, save config, and add unic id\n *\n * @param {Object} config - tooltip config\n * @returns {String} tooltip id\n */\n setTooltip: function (config) {\n var property = 'id-' + iterator;\n\n tooltipsCollection[property] = config;\n iterator++;\n\n return property;\n },\n\n /**\n * Get tooltip config by id\n *\n * @param {String} id - tooltip id\n * @returns {Object} tooltip config\n */\n getTooltip: function (id) {\n return tooltipsCollection[id];\n },\n\n /**\n * Set content to current tooltip\n *\n * @param {Object} tooltipElement - tooltip element\n * @param {Object} viewModel - tooltip view model\n * @param {String} id - tooltip id\n * @param {Object} bindingCtx - tooltip context\n * @param {Object} event - action event\n */\n setContent: function (tooltipElement, viewModel, id, bindingCtx, event) {\n var html = $(tooltipElement).html(),\n config = tooltip.getTooltip(id),\n body = $('body');\n\n tooltipData.currentID = id;\n tooltipData.trigger = $(event.currentTarget);\n tooltip.setTargetData(event);\n body.on('mousemove.setTargetData', tooltip.setTargetData);\n tooltip.clearTimeout(id);\n\n tooltipData.timeout = _.delay(function () {\n body.off('mousemove.setTargetData', tooltip.setTargetData);\n\n if (tooltipData.trigger[0] === tooltipData.targetElement) {\n tooltip.destroy(id);\n event.stopPropagation();\n tooltipElement = tooltip.createTooltip(id);\n tooltipElement.find('.' + defaults.tooltipContentBlock).append(html);\n tooltipElement.applyBindings(bindingCtx);\n tooltip.setHandlers(id);\n tooltip.setPosition(tooltipElement, id);\n previousTooltip = id;\n }\n\n }, config.delay);\n },\n\n /**\n * Set position to current tooltip\n *\n * @param {Object} tooltipElement - tooltip element\n * @param {String} id - tooltip id\n */\n setPosition: function (tooltipElement, id) {\n var config = tooltip.getTooltip(id);\n\n tooltip.sizeData = {\n windowSize: {\n h: $(window).outerHeight(),\n w: $(window).outerWidth()\n },\n scrollPosition: {\n top: $(window).scrollTop(),\n left: $(window).scrollLeft()\n },\n tooltipSize: {\n h: tooltipElement.outerHeight(),\n w: tooltipElement.outerWidth()\n },\n elementSize: {\n h: tooltipData.trigger.outerHeight(),\n w: tooltipData.trigger.outerWidth()\n },\n elementPosition: tooltipData.trigger.offset(),\n eventPosition: this.getEventPosition(tooltipData.event)\n };\n\n _.extend(positionData, positions[config.position](tooltip.sizeData));\n tooltipElement.css(positionData.position);\n tooltipElement.addClass(positionData.className);\n tooltip._setTooltipSize(positionData, tooltipElement);\n tooltip._setTailPosition(positionData, tooltipElement);\n checkedPositions = {};\n },\n\n /**\n * Check position data and change tooltip size if needs\n *\n * @param {Object} data - position data\n * @param {Object} tooltipElement - tooltip element\n */\n _setTooltipSize: function (data, tooltipElement) {\n if (data.tooltipSize) {\n data.tooltipSize.w ?\n tooltipElement.css('width', data.tooltipSize.w) :\n tooltipElement.css('height', data.tooltipSize.h);\n }\n },\n\n /**\n * Check position data and set position to tail\n *\n * @param {Object} data - position data\n * @param {Object} tooltipElement - tooltip element\n */\n _setTailPosition: function (data, tooltipElement) {\n var tail,\n tailMargin;\n\n if (data.tail) {\n tail = tooltipElement.find('.' + defaults.tailClass);\n\n if (data.tail.left) {\n tailMargin = parseInt(tail.css('margin-left'), 10);\n tail.css('margin-left', tailMargin + data.tail.left);\n } else {\n tailMargin = parseInt(tail.css('margin-top'), 10);\n tail.css('margin-top', tailMargin + data.tail.top);\n }\n }\n },\n\n /**\n * Resolves position for tooltip\n *\n * @param {Object} event\n * @returns {Object}\n */\n getEventPosition: function (event) {\n var position = {\n left: event.originalEvent && event.originalEvent.pageX || 0,\n top: event.originalEvent && event.originalEvent.pageY || 0\n };\n\n if (position.left === 0 && position.top === 0) {\n _.extend(position, event.target.getBoundingClientRect());\n }\n\n return position;\n },\n\n /**\n * Close tooltip if action happened outside handler and tooltip element\n *\n * @param {String} id - tooltip id\n * @param {Object} event - action event\n */\n outerClick: function (id, event) {\n var tooltipElement = $(event.target).parents(defaults.tooltipWrapper)[0],\n isTrigger = event.target === tooltipData.trigger[0] || $.contains(tooltipData.trigger[0], event.target);\n\n if (tooltipData.showed && tooltipElement !== tooltipData.element[0] && !isTrigger) {\n tooltip.destroy(id);\n }\n },\n\n /**\n * Parse keydown event and if event trigger is escape key - close tooltip\n *\n * @param {Object} event - action event\n */\n keydownHandler: function (event) {\n if (tooltipData.showed && event.keyCode === 27) {\n tooltip.destroy(tooltipData.currentID);\n }\n },\n\n /**\n * Change tooltip position when track is enabled\n *\n * @param {Object} event - current event\n */\n track: function (event) {\n var inequality = {},\n map = positions.map,\n translate = {\n left: 'translateX',\n top: 'translateY'\n },\n eventPosition = {\n left: event.pageX,\n top: event.pageY\n },\n tooltipSize = {\n w: tooltipData.element.outerWidth(),\n h: tooltipData.element.outerHeight()\n },\n direction = positionData.side === 'bottom' || positionData.side === 'top' ? 'horizontal' : 'vertical';\n\n inequality[map[direction].p] = eventPosition[map[direction].p] - (positionData.position[map[direction].p] +\n tooltipSize[map[direction].s] / 2);\n\n if (positionData.position[map[direction].p] + inequality[map[direction].p] +\n tooltip.sizeData.tooltipSize[map[direction].s] >\n tooltip.sizeData.windowSize[map[direction].s] + tooltip.sizeData.scrollPosition[map[direction].p] ||\n inequality[map[direction].p] + positionData.position[map[direction].p] <\n tooltip.sizeData.scrollPosition[map[direction].p]) {\n\n return false;\n }\n\n tooltipData.element[0].style[transformProp] = translate[map[direction].p] +\n '(' + inequality[map[direction].p] + 'px)';\n },\n\n /**\n * Set handlers to tooltip\n *\n * @param {String} id - tooltip id\n */\n setHandlers: function (id) {\n var config = tooltip.getTooltip(id);\n\n if (config.track) {\n tooltipData.trigger.on('mousemove.track', tooltip.track);\n }\n\n if (config.action === 'click') {\n $(window).on(CLICK_EVENT + '.outerClick', tooltip.outerClick.bind(null, id));\n }\n\n if (config.closeButton) {\n $('.' + config.closeButtonClass).on('click.closeButton', tooltip.destroy.bind(null, id));\n }\n\n if (config.closeOnScroll) {\n document.addEventListener('scroll', tooltip.destroy, true);\n $(window).on('scroll.tooltip', tooltip.outerClick.bind(null, id));\n }\n\n $(window).on('keydown.tooltip', tooltip.keydownHandler);\n $(window).on('resize.outerClick', tooltip.outerClick.bind(null, id));\n },\n\n /**\n * Toggle tooltip\n *\n * @param {Object} tooltipElement - tooltip element\n * @param {Object} viewModel - tooltip view model\n * @param {String} id - tooltip id\n */\n toggleTooltip: function (tooltipElement, viewModel, id) {\n if (previousTooltip === id && tooltipData.showed) {\n tooltip.destroy(id);\n\n return false;\n }\n\n tooltip.setContent.apply(null, arguments);\n\n return false;\n },\n\n /**\n * Create tooltip and append to DOM\n *\n * @param {String} id - tooltip id\n * @returns {Object} tooltip element\n */\n createTooltip: function (id) {\n var body = $('body'),\n config = tooltip.getTooltip(id);\n\n $(template(tooltipTmpl, {\n data: config\n })).appendTo(body);\n\n tooltipData.showed = true;\n tooltipData.element = $(config.tooltipWrapper);\n\n return tooltipData.element;\n },\n\n /**\n * Check action and clean timeout\n *\n * @param {String} id - tooltip id\n */\n clearTimeout: function (id) {\n var config = tooltip.getTooltip(id);\n\n if (config.action === 'hover') {\n clearTimeout(tooltipData.timeout);\n }\n },\n\n /**\n * Check previous tooltip\n */\n checkPreviousTooltip: function () {\n if (!tooltipData.timeout) {\n tooltip.destroy();\n }\n },\n\n /**\n * Destroy tooltip instance\n */\n destroy: function () {\n if (tooltipData.element) {\n tooltipData.element.remove();\n tooltipData.showed = false;\n }\n\n positionData = {};\n tooltipData.timeout = false;\n tooltip.removeHandlers();\n },\n\n /**\n * Remove tooltip handlers\n */\n removeHandlers: function () {\n $('.' + defaults.closeButtonClass).off('click.closeButton');\n tooltipData.trigger.off('mousemove.track');\n document.removeEventListener('scroll', tooltip.destroy, true);\n $(window).off('scroll.tooltip');\n $(window).off(CLICK_EVENT + '.outerClick');\n $(window).off('keydown.tooltip');\n $(window).off('resize.outerClick');\n },\n\n /**\n * Set target element\n *\n * @param {Object} event - current event\n */\n setTargetData: function (event) {\n tooltipData.event = event;\n\n //TODO: bug chrome v.49; Link to issue https://bugs.chromium.org/p/chromium/issues/detail?id=161464\n if (event.timeStamp - (tooltipData.timestamp || 0) < 1) {\n return;\n }\n\n if (event.type === 'mousemove') {\n tooltipData.targetElement = event.target;\n } else {\n tooltipData.targetElement = event.currentTarget;\n tooltipData.timestamp = event.timeStamp;\n }\n },\n\n /**\n * Merged user config with defaults configuration\n *\n * @param {Object} config - user config\n * @returns {Object} merged config\n */\n processingConfig: function (config) {\n return _.extend({}, defaults, config);\n }\n };\n\n ko.bindingHandlers.tooltip = {\n\n /**\n * Initialize tooltip\n *\n * @param {Object} elem - tooltip DOM element\n * @param {Function} valueAccessor - ko observable property, tooltip data\n * @param {Object} allBindings - all bindings on current element\n * @param {Object} viewModel - current element viewModel\n * @param {Object} bindingCtx - current element binding context\n */\n init: function (elem, valueAccessor, allBindings, viewModel, bindingCtx) {\n var config = tooltip.processingConfig(valueAccessor()),\n $parentScope = config.parentScope ? $(config.parentScope) : $(elem).parent(),\n tooltipId;\n\n $(elem).addClass('hidden');\n\n if (isTouchDevice) {\n config.action = 'click';\n }\n tooltipId = tooltip.setTooltip(config);\n\n if (config.action === 'hover') {\n $parentScope.on(\n 'mouseenter',\n config.trigger,\n tooltip.setContent.bind(null, elem, viewModel, tooltipId, bindingCtx)\n );\n $parentScope.on(\n 'mouseleave',\n config.trigger,\n tooltip.checkPreviousTooltip.bind(null, tooltipId)\n );\n } else if (config.action === 'click') {\n $parentScope.on(\n 'click',\n config.trigger,\n tooltip.toggleTooltip.bind(null, elem, viewModel, tooltipId, bindingCtx)\n );\n }\n\n return {\n controlsDescendantBindings: true\n };\n }\n };\n\n renderer.addAttribute('tooltip');\n});\n","Magento_Ui/js/lib/knockout/bindings/staticChecked.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n 'ko',\n '../template/renderer'\n], function (ko, renderer) {\n 'use strict';\n\n ko.bindingHandlers.staticChecked = {\n 'after': ['value', 'attr'],\n\n /**\n * Implements same functionality as a standard 'checked' binding,\n * but with a difference that it wont' change values array if\n * value of DOM element changes.\n */\n init: function (element, valueAccessor, allBindings) {\n var isCheckbox = element.type === 'checkbox',\n isRadio = element.type === 'radio',\n isValueArray,\n oldElemValue,\n useCheckedValue,\n checkedValue,\n updateModel,\n updateView;\n\n if (!isCheckbox && !isRadio) {\n return;\n }\n\n checkedValue = ko.pureComputed(function () {\n if (allBindings.has('checkedValue')) {\n return ko.utils.unwrapObservable(allBindings.get('checkedValue'));\n } else if (allBindings.has('value')) {\n return ko.utils.unwrapObservable(allBindings.get('value'));\n }\n\n return element.value;\n });\n\n isValueArray = isCheckbox && ko.utils.unwrapObservable(valueAccessor()) instanceof Array;\n oldElemValue = isValueArray ? checkedValue() : undefined;\n useCheckedValue = isRadio || isValueArray;\n\n /**\n * Updates values array if it's necessary.\n */\n updateModel = function () {\n var isChecked = element.checked,\n elemValue = useCheckedValue ? checkedValue() : isChecked,\n modelValue;\n\n if (ko.computedContext.isInitial()) {\n return;\n }\n\n if (isRadio && !isChecked) {\n return;\n }\n\n modelValue = ko.dependencyDetection.ignore(valueAccessor);\n\n if (isValueArray) {\n if (oldElemValue !== elemValue) {\n oldElemValue = elemValue;\n } else {\n ko.utils.addOrRemoveItem(modelValue, elemValue, isChecked);\n }\n } else {\n ko.expressionRewriting.writeValueToProperty(modelValue, allBindings, 'checked', elemValue, true);\n }\n };\n\n /**\n * Updates checkbox state.\n */\n updateView = function () {\n var modelValue = ko.utils.unwrapObservable(valueAccessor());\n\n if (isValueArray) {\n element.checked = ko.utils.arrayIndexOf(modelValue, checkedValue()) >= 0;\n } else if (isCheckbox) {\n element.checked = modelValue;\n } else {\n element.checked = checkedValue() === modelValue;\n }\n };\n\n ko.computed(updateModel, null, {\n disposeWhenNodeIsRemoved: element\n });\n\n ko.utils.registerEventHandler(element, 'click', updateModel);\n\n ko.computed(updateView, null, {\n disposeWhenNodeIsRemoved: element\n });\n }\n };\n\n ko.expressionRewriting._twoWayBindings.staticChecked = true;\n\n renderer.addAttribute('staticChecked');\n});\n","Magento_Ui/js/lib/knockout/bindings/bootstrap.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine(function (require) {\n 'use strict';\n\n var renderer = require('../template/renderer');\n\n renderer.addAttribute('repeat', renderer.handlers.wrapAttribute);\n\n renderer.addAttribute('outerfasteach', {\n binding: 'fastForEach',\n handler: renderer.handlers.wrapAttribute\n });\n\n renderer\n .addNode('repeat')\n .addNode('fastForEach');\n\n return {\n resizable: require('./resizable'),\n i18n: require('./i18n'),\n scope: require('./scope'),\n range: require('./range'),\n mageInit: require('./mage-init'),\n keyboard: require('./keyboard'),\n optgroup: require('./optgroup'),\n afterRender: require('./after-render'),\n autoselect: require('./autoselect'),\n datepicker: require('./datepicker'),\n outerClick: require('./outer_click'),\n fadeVisible: require('./fadeVisible'),\n collapsible: require('./collapsible'),\n staticChecked: require('./staticChecked'),\n simpleChecked: require('./simple-checked'),\n bindHtml: require('./bind-html'),\n tooltip: require('./tooltip'),\n repeat: require('knockoutjs/knockout-repeat'),\n fastForEach: require('knockoutjs/knockout-fast-foreach'),\n colorPicker: require('./color-picker')\n };\n});\n","Magento_Ui/js/lib/knockout/bindings/simple-checked.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n 'ko',\n '../template/renderer'\n], function (ko, renderer) {\n 'use strict';\n\n ko.bindingHandlers.simpleChecked = {\n 'after': ['attr'],\n\n /**\n * Implements same functionality as a standard 'simpleChecked' binding,\n * but with a difference that it wont' change values array if\n * value of DOM element changes.\n */\n init: function (element, valueAccessor) {\n var isCheckbox = element.type === 'checkbox',\n isRadio = element.type === 'radio',\n updateView,\n updateModel;\n\n if (!isCheckbox && !isRadio) {\n return;\n }\n\n /**\n * Updates checked observable\n */\n updateModel = function () {\n var modelValue = ko.dependencyDetection.ignore(valueAccessor),\n isChecked = element.checked;\n\n if (ko.computedContext.isInitial()) {\n return;\n }\n\n if (modelValue.peek() === isChecked) {\n return;\n }\n\n if (isRadio && !isChecked) {\n return;\n }\n\n modelValue(isChecked);\n };\n\n /**\n * Updates checkbox state\n */\n updateView = function () {\n var modelValue = ko.utils.unwrapObservable(valueAccessor());\n\n element.checked = !!modelValue;\n };\n\n ko.utils.registerEventHandler(element, 'change', updateModel);\n\n ko.computed(updateModel, null, {\n disposeWhenNodeIsRemoved: element\n });\n ko.computed(updateView, null, {\n disposeWhenNodeIsRemoved: element\n });\n }\n };\n\n ko.expressionRewriting._twoWayBindings.simpleChecked = true;\n\n renderer.addAttribute('simpleChecked');\n renderer.addAttribute('simple-checked', {\n binding: 'simpleChecked'\n });\n});\n","Magento_Ui/js/lib/knockout/bindings/range.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'ko',\n 'jquery',\n 'underscore',\n '../template/renderer'\n], function (ko, $, _, renderer) {\n 'use strict';\n\n var isTouchDevice = !_.isUndefined(document.ontouchstart),\n sliderFn = 'slider',\n sliderModule = 'jquery-ui-modules/slider';\n\n if (isTouchDevice) {\n sliderFn = 'touchSlider';\n sliderModule = 'mage/touch-slider';\n }\n\n ko.bindingHandlers.range = {\n\n /**\n * Initializes binding and a slider update.\n *\n * @param {HTMLElement} element\n * @param {Function} valueAccessor\n */\n init: function (element, valueAccessor) {\n var config = valueAccessor(),\n value = config.value;\n\n _.extend(config, {\n value: value(),\n\n /**\n * Callback which is being called when sliders' value changes.\n *\n * @param {Event} event\n * @param {Object} ui\n */\n slide: function (event, ui) {\n value(ui.value);\n }\n });\n\n require([sliderModule], function () {\n $(element)[sliderFn](config);\n });\n },\n\n /**\n * Updates sliders' plugin configuration.\n *\n * @param {HTMLElement} element\n * @param {Function} valueAccessor\n */\n update: function (element, valueAccessor) {\n var config = valueAccessor();\n\n config.value = ko.unwrap(config.value);\n\n require([sliderModule], function () {\n $(element)[sliderFn]('option', config);\n });\n }\n };\n\n renderer.addAttribute('range');\n});\n","Magento_Ui/js/lib/knockout/bindings/datepicker.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n/** Creates datepicker binding and registers in to ko.bindingHandlers object */\ndefine([\n 'ko',\n 'underscore',\n 'jquery',\n 'mage/translate'\n], function (ko, _, $, $t) {\n 'use strict';\n\n var defaults = {\n dateFormat: 'mm\\/dd\\/yyyy',\n showsTime: false,\n timeFormat: null,\n buttonImage: null,\n buttonImageOnly: null,\n buttonText: $t('Select Date')\n };\n\n ko.bindingHandlers.datepicker = {\n /**\n * Initializes calendar widget on element and stores it's value to observable property.\n * Datepicker binding takes either observable property or object\n * { storage: {ko.observable}, options: {Object} }.\n * For more info about options take a look at \"mage/calendar\" and jquery.ui.datepicker widget.\n * @param {HTMLElement} el - Element, that binding is applied to\n * @param {Function} valueAccessor - Function that returns value, passed to binding\n * @param {object} allBindings\n * @param {object} viewModel\n * @param {object} bindingContext\n */\n init: function (el, valueAccessor, allBindings, viewModel, bindingContext) {\n var config = valueAccessor(),\n observable,\n options = {};\n\n _.extend(options, defaults);\n\n if (typeof config === 'object') {\n observable = config.storage;\n _.extend(options, config.options);\n } else {\n observable = config;\n }\n\n require(['mage/calendar'], function () {\n $(el).calendar(options);\n\n ko.utils.registerEventHandler(el, 'change', function () {\n observable(this.value);\n });\n });\n\n if (bindingContext.$data) {\n bindingContext.$data.value.subscribe(function (newVal) {\n if (!newVal) {\n $(el).val('');\n }\n }, this);\n }\n\n\n },\n\n /**\n * Update calendar widget on element and stores it's value to observable property.\n * Datepicker binding takes either observable property or object\n * { storage: {ko.observable}, options: {Object} }.\n * @param {HTMLElement} element - Element, that binding is applied to\n * @param {Function} valueAccessor - Function that returns value, passed to binding\n */\n update: function (element, valueAccessor) {\n var config = valueAccessor(),\n $element = $(element),\n observable,\n options = {},\n newVal;\n\n _.extend(options, defaults);\n\n if (typeof config === 'object') {\n observable = config.storage;\n _.extend(options, config.options);\n } else {\n observable = config;\n }\n\n require(['moment', 'mage/utils/misc', 'mage/calendar'], function (moment, utils) {\n if (_.isEmpty(observable())) {\n newVal = null;\n } else {\n newVal = moment(\n observable(),\n utils.convertToMomentFormat(\n options.dateFormat + (options.showsTime ? ' ' + options.timeFormat : '')\n )\n ).toDate();\n }\n\n if (!options.timeOnly) {\n $element.datepicker('setDate', newVal);\n $element.trigger('blur');\n }\n });\n }\n };\n});\n","Magento_Ui/js/lib/knockout/bindings/optgroup.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'ko',\n 'mageUtils'\n ], function (ko, utils) {\n 'use strict';\n\n var captionPlaceholder = {},\n optgroupTmpl = '<optgroup label=\"${ $.label }\"></optgroup>',\n nbspRe = / /g,\n optionsText,\n optionsValue,\n optionTitle;\n\n ko.bindingHandlers.optgroup = {\n /**\n * @param {*} element\n */\n init: function (element) {\n if (ko.utils.tagNameLower(element) !== 'select') {\n throw new Error('options binding applies only to SELECT elements');\n }\n\n // Remove all existing <option>s.\n while (element.length > 0) {\n element.remove(0);\n }\n },\n\n /**\n * @param {*} element\n * @param {*} valueAccessor\n * @param {*} allBindings\n */\n update: function (element, valueAccessor, allBindings) {\n var selectWasPreviouslyEmpty = element.length === 0,\n previousScrollTop = !selectWasPreviouslyEmpty && element.multiple ? element.scrollTop : null,\n includeDestroyed = allBindings.get('optionsIncludeDestroyed'),\n arrayToDomNodeChildrenOptions = {},\n captionValue,\n unwrappedArray = ko.utils.unwrapObservable(valueAccessor()),\n filteredArray,\n previousSelectedValues,\n itemUpdate = false,\n callback = setSelectionCallback,//eslint-disable-line no-use-before-define\n nestedOptionsLevel = -1;\n\n optionsText = ko.utils.unwrapObservable(allBindings.get('optionsText')) || 'text';\n optionsValue = ko.utils.unwrapObservable(allBindings.get('optionsValue')) || 'value';\n optionTitle = optionsText + 'title';\n\n if (element.multiple) {\n previousSelectedValues = ko.utils.arrayMap(\n selectedOptions(),//eslint-disable-line no-use-before-define\n ko.selectExtensions.readValue\n );\n } else {\n previousSelectedValues = element.selectedIndex >= 0 ?\n [ko.selectExtensions.readValue(element.options[element.selectedIndex])] :\n [];\n }\n\n if (unwrappedArray) {\n if (typeof unwrappedArray.length === 'undefined') { // Coerce single value into array\n unwrappedArray = [unwrappedArray];\n }\n\n // Filter out any entries marked as destroyed\n filteredArray = ko.utils.arrayFilter(unwrappedArray, function (item) {\n if (item && !item.label) {\n return false;\n }\n\n return includeDestroyed ||\n item === undefined ||\n item === null ||\n !ko.utils.unwrapObservable(item._destroy);\n });\n filteredArray.map(recursivePathBuilder, null);//eslint-disable-line no-use-before-define\n }\n\n /**\n * @param {*} option\n */\n arrayToDomNodeChildrenOptions.beforeRemove = function (option) {\n element.removeChild(option);\n };\n\n if (allBindings.has('optionsAfterRender')) {\n\n /**\n * @param {*} arrayEntry\n * @param {*} newOptions\n */\n callback = function (arrayEntry, newOptions) {\n setSelectionCallback(arrayEntry, newOptions);//eslint-disable-line no-use-before-define\n ko.dependencyDetection.ignore(\n allBindings.get('optionsAfterRender'),\n null,\n [newOptions[0],\n arrayEntry !== captionPlaceholder ? arrayEntry : undefined]\n );\n };\n }\n\n filteredArray = formatOptions(filteredArray);//eslint-disable-line no-use-before-define\n ko.utils.setDomNodeChildrenFromArrayMapping(\n element,\n filteredArray,\n optionNodeFromArray,//eslint-disable-line no-use-before-define\n arrayToDomNodeChildrenOptions,\n callback\n );\n\n ko.dependencyDetection.ignore(function () {\n var selectionChanged;\n\n if (allBindings.get('valueAllowUnset') && allBindings.has('value')) {\n // The model value is authoritative, so make sure its value is the one selected\n ko.selectExtensions.writeValue(\n element,\n ko.utils.unwrapObservable(allBindings.get('value')),\n true /* allowUnset */\n );\n } else {\n // Determine if the selection has changed as a result of updating the options list\n if (element.multiple) {\n // For a multiple-select box, compare the new selection count to the previous one\n // But if nothing was selected before, the selection can't have changed\n selectionChanged = previousSelectedValues.length &&\n selectedOptions().length < //eslint-disable-line no-use-before-define\n previousSelectedValues.length;\n } else {\n // For a single-select box, compare the current value to the previous value\n // But if nothing was selected before or nothing is selected now,\n // just look for a change in selection\n selectionChanged = previousSelectedValues.length && element.selectedIndex >= 0 ?\n ko.selectExtensions.readValue(element.options[element.selectedIndex]) !==\n previousSelectedValues[0] : previousSelectedValues.length || element.selectedIndex >= 0;\n }\n\n // Ensure consistency between model value and selected option.\n // If the dropdown was changed so that selection is no longer the same,\n // notify the value or selectedOptions binding.\n if (selectionChanged) {\n ko.utils.triggerEvent(element, 'change');\n }\n }\n });\n\n /*eslint-enable max-len, no-use-before-define*/\n\n if (previousScrollTop && Math.abs(previousScrollTop - element.scrollTop) > 20) {\n element.scrollTop = previousScrollTop;\n }\n\n /**\n * @returns {*}\n */\n function selectedOptions() {\n return ko.utils.arrayFilter(element.options, function (node) {\n return node.selected;\n });\n }\n\n /**\n * @param {*} object\n * @param {*} predicate\n * @param {*} defaultValue\n * @returns {*}\n */\n function applyToObject(object, predicate, defaultValue) {\n var predicateType = typeof predicate;\n\n if (predicateType === 'function') { // run it against the data value\n return predicate(object);\n } else if (predicateType === 'string') { // treat it as a property name on the data value\n return object[predicate];\n }\n\n return defaultValue;\n }\n\n /**\n * @param {*} obj\n */\n function recursivePathBuilder(obj) {\n\n obj[optionTitle] = (this && this[optionTitle] ? this[optionTitle] + '/' : '') + obj[optionsText].trim();\n\n if (Array.isArray(obj[optionsValue])) {\n obj[optionsValue].map(recursivePathBuilder, obj);\n }\n }\n\n /**\n * @param {Array} arrayEntry\n * @param {*} oldOptions\n * @returns {*[]}\n */\n function optionNodeFromArray(arrayEntry, oldOptions) {\n var option;\n\n if (oldOptions.length) {\n previousSelectedValues = oldOptions[0].selected ?\n [ko.selectExtensions.readValue(oldOptions[0])] : [];\n itemUpdate = true;\n }\n\n if (arrayEntry === captionPlaceholder) { // empty value, label === caption\n option = element.ownerDocument.createElement('option');\n ko.utils.setTextContent(option, allBindings.get('optionsCaption'));\n ko.selectExtensions.writeValue(option, undefined);\n } else if (typeof arrayEntry[optionsValue] === 'undefined') { // empty value === optgroup\n if (arrayEntry.__disableTmpl) {\n option = '<optgroup label=\"' + arrayEntry[optionsText] + '\"></optgroup>';\n } else {\n option = utils.template(optgroupTmpl, {\n label: arrayEntry[optionsText],\n title: arrayEntry[optionsText + 'title']\n });\n }\n option = ko.utils.parseHtmlFragment(option)[0];\n\n } else {\n option = element.ownerDocument.createElement('option');\n option.setAttribute('data-title', arrayEntry[optionsText + 'title']);\n ko.selectExtensions.writeValue(option, arrayEntry[optionsValue]);\n ko.utils.setTextContent(option, arrayEntry[optionsText]);\n }\n\n return [option];\n }\n\n /**\n * @param {*} newOptions\n */\n function setSelectionCallback(newOptions) {\n var isSelected;\n\n // IE6 doesn't like us to assign selection to OPTION nodes before they're added to the document.\n // That's why we first added them without selection. Now it's time to set the selection.\n if (previousSelectedValues.length && newOptions.value) {\n isSelected = ko.utils.arrayIndexOf(\n previousSelectedValues,\n ko.selectExtensions.readValue(newOptions.value)\n ) >= 0;\n\n ko.utils.setOptionNodeSelectionState(newOptions.value, isSelected);\n\n // If this option was changed from being selected during a single-item update, notify the change\n if (itemUpdate && !isSelected) {\n ko.dependencyDetection.ignore(ko.utils.triggerEvent, null, [element, 'change']);\n }\n }\n }\n\n /**\n * @param {*} string\n * @param {Number} times\n * @returns {Array}\n */\n function strPad(string, times) {\n return new Array(times + 1).join(string);\n }\n\n /**\n * @param {*} options\n * @returns {Array}\n */\n function formatOptions(options) {\n var res = [];\n\n nestedOptionsLevel++;\n\n if (!nestedOptionsLevel) { // zero level\n // If caption is included, add it to the array\n if (allBindings.has('optionsCaption')) {\n captionValue = ko.utils.unwrapObservable(allBindings.get('optionsCaption'));\n // If caption value is null or undefined, don't show a caption\n if (//eslint-disable-line max-depth\n captionValue !== null &&\n captionValue !== undefined &&\n captionValue !== false\n ) {\n res.push(captionPlaceholder);\n }\n }\n }\n\n ko.utils.arrayForEach(options, function (option) {\n var value = applyToObject(option, optionsValue, option),\n label = applyToObject(option, optionsText, value) || '',\n disabled = applyToObject(option, 'disabled', false) || false,\n obj = {},\n space = '\\u2007\\u2007\\u2007';\n\n obj[optionTitle] = applyToObject(option, optionsText + 'title', value);\n\n if (disabled) {\n obj.disabled = disabled;\n }\n\n if (option.hasOwnProperty('__disableTmpl')) {\n obj.__disableTmpl = option.__disableTmpl;\n }\n\n label = label.replace(nbspRe, '').trim();\n\n if (Array.isArray(value)) {\n obj[optionsText] = strPad(' ', nestedOptionsLevel * 4) + label;\n res.push(obj);\n res = res.concat(formatOptions(value));\n } else {\n obj[optionsText] = strPad(space, nestedOptionsLevel * 2) + label;\n obj[optionsValue] = value;\n res.push(obj);\n }\n });\n nestedOptionsLevel--;\n\n return res;\n }\n }\n };\n});\n","Magento_Ui/js/lib/knockout/bindings/fadeVisible.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'jquery',\n 'ko'\n], function ($, ko) {\n 'use strict';\n\n ko.bindingHandlers.fadeVisible = {\n /**\n * Initially set the element to be instantly visible/hidden depending on the value.\n *\n * @param {HTMLElement} element\n * @param {Function} valueAccessor\n */\n init: function (element, valueAccessor) {\n var value = valueAccessor();\n\n // Use \"unwrapObservable\" so we can handle values that may or may not be observable\n $(element).toggle(ko.unwrap(value));\n },\n\n /**\n * Whenever the value subsequently changes, slowly fade the element in or out.\n *\n * @param {HTMLElement} element\n * @param {Function} valueAccessor\n */\n update: function (element, valueAccessor) {\n var value = valueAccessor();\n\n ko.unwrap(value) ? $(element).fadeIn() : $(element).fadeOut();\n }\n };\n});\n","Magento_Ui/js/lib/knockout/bindings/after-render.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n 'ko',\n '../template/renderer'\n], function (ko, renderer) {\n 'use strict';\n\n ko.bindingHandlers.afterRender = {\n\n /**\n * Binding init callback.\n */\n init: function (element, valueAccessor, allBindings, viewModel) {\n var callback = valueAccessor();\n\n if (typeof callback === 'function') {\n callback.call(viewModel, element, viewModel);\n }\n }\n };\n\n renderer.addAttribute('afterRender');\n});\n","Magento_Ui/js/lib/knockout/bindings/mage-init.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'ko',\n 'underscore',\n 'mage/apply/main'\n], function (ko, _, mage) {\n 'use strict';\n\n ko.bindingHandlers.mageInit = {\n /**\n * Initializes components assigned to HTML elements.\n *\n * @param {HTMLElement} el\n * @param {Function} valueAccessor\n */\n init: function (el, valueAccessor) {\n var data = valueAccessor();\n\n _.each(data, function (config, component) {\n mage.applyFor(el, config, component);\n });\n }\n };\n});\n","Magento_Ui/js/lib/knockout/bindings/bind-html.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'ko',\n 'underscore',\n 'mage/apply/main',\n '../template/renderer'\n], function (ko, _, mage, renderer) {\n 'use strict';\n\n /**\n * Set html to node element.\n *\n * @param {HTMLElement} el - Element to apply bindings to.\n * @param {Function} html - Observable html content.\n */\n function setHtml(el, html) {\n ko.utils.emptyDomNode(el);\n html = ko.utils.unwrapObservable(html);\n\n if (!_.isNull(html) && !_.isUndefined(html)) {\n if (!_.isString(html)) {\n html = html.toString();\n }\n\n el.innerHTML = html;\n }\n }\n\n /**\n * Apply bindings and call magento attributes parser.\n *\n * @param {HTMLElement} el - Element to apply bindings to.\n * @param {ko.bindingContext} ctx - Instance of ko.bindingContext, passed to binding initially.\n */\n function applyComponents(el, ctx) {\n ko.utils.arrayForEach(el.childNodes, ko.cleanNode);\n ko.applyBindingsToDescendants(ctx, el);\n mage.apply();\n }\n\n ko.bindingHandlers.bindHtml = {\n /**\n * Scope binding's init method.\n *\n * @returns {Object} - Knockout declaration for it to let binding control descendants.\n */\n init: function () {\n return {\n controlsDescendantBindings: true\n };\n },\n\n /**\n * Reads params passed to binding.\n * Set html to node element, apply bindings and call magento attributes parser.\n *\n * @param {HTMLElement} el - Element to apply bindings to.\n * @param {Function} valueAccessor - Function that returns value, passed to binding.\n * @param {Object} allBindings - Object, which represents all bindings applied to element.\n * @param {Object} viewModel - Object, which represents view model binded to el.\n * @param {ko.bindingContext} bindingContext - Instance of ko.bindingContext, passed to binding initially.\n */\n update: function (el, valueAccessor, allBindings, viewModel, bindingContext) {\n setHtml(el, valueAccessor());\n applyComponents(el, bindingContext);\n }\n };\n\n renderer.addAttribute('bindHtml');\n});\n","Magento_Ui/js/lib/knockout/bindings/resizable.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n 'ko',\n 'jquery',\n 'Magento_Ui/js/lib/view/utils/async',\n 'uiRegistry',\n 'underscore',\n '../template/renderer'\n], function (ko, $, async, registry, _, renderer) {\n 'use strict';\n\n var sizeOptions = [\n 'minHeight',\n 'maxHeight',\n 'minWidth',\n 'maxWidth'\n ],\n\n handles = {\n height: '.ui-resizable-s, .ui-resizable-n',\n width: '.ui-resizable-w, .ui-resizable-e'\n };\n\n /**\n * Recalcs visibility of handles, width and height of resizable based on content\n * @param {HTMLElement} element\n */\n function adjustSize(element) {\n var maxHeight,\n maxWidth;\n\n element = $(element);\n maxHeight = element.resizable('option').maxHeight;\n maxWidth = element.resizable('option').maxWidth;\n\n if (maxHeight && element.height() > maxHeight) {\n element.height(maxHeight + 1);\n $(handles.height).hide();\n } else {\n $(handles.height).show();\n }\n\n if (maxWidth && element.width() > maxWidth) {\n element.width(maxWidth + 1);\n $(handles.width).hide();\n } else {\n $(handles.width).show();\n }\n }\n\n /**\n * Recalcs allowed min, max width and height based on configured selectors\n * @param {Object} sizeConstraints\n * @param {String} componentName\n * @param {HTMLElement} element\n * @param {Boolean} hasWidthUpdate\n */\n function recalcAllowedSize(sizeConstraints, componentName, element, hasWidthUpdate) {\n var size;\n\n element = $(element);\n\n if (!element.data('resizable')) {\n return;\n }\n\n if (!hasWidthUpdate) {\n element.css('width', 'auto');\n }\n\n _.each(sizeConstraints, function (selector, key) {\n async.async({\n component: componentName,\n selector: selector\n }, function (elem) {\n size = key.indexOf('Height') !== -1 ? $(elem).outerHeight(true) : $(elem).outerWidth(true);\n\n if (element.data('resizable')) {\n element.resizable('option', key, size + 1);\n }\n });\n }, this);\n\n adjustSize(element);\n }\n\n /**\n * Preprocess config to separate options,\n * which must be processed further before applying\n *\n * @param {Object} config\n * @param {Object} viewModel\n * @param {*} element\n * @return {Object} config\n */\n function processConfig(config, viewModel, element) {\n var sizeConstraint,\n sizeConstraints = {},\n recalc,\n hasWidthUpdate;\n\n if (_.isEmpty(config)) {\n return {};\n }\n _.each(sizeOptions, function (key) {\n sizeConstraint = config[key];\n\n if (sizeConstraint && !_.isNumber(sizeConstraint)) {\n sizeConstraints[key] = sizeConstraint;\n delete config[key];\n }\n });\n hasWidthUpdate = _.some(sizeConstraints, function (value, key) {\n return key.indexOf('Width') !== -1;\n });\n\n recalc = recalcAllowedSize.bind(null, sizeConstraints, viewModel.name, element, hasWidthUpdate);\n config.start = recalc;\n $(window).on('resize.resizable', recalc);\n registry.get(viewModel.provider).on('reloaded', recalc);\n\n return config;\n }\n\n ko.bindingHandlers.resizable = {\n\n /**\n * Binding init callback.\n *\n * @param {*} element\n * @param {Function} valueAccessor\n * @param {Function} allBindings\n * @param {Object} viewModel\n */\n init: function (element, valueAccessor, allBindings, viewModel) {\n var config = processConfig(valueAccessor(), viewModel, element);\n\n require(['jquery-ui-modules/resizable'], function () {\n if ($.fn.resizable) {\n $(element).resizable(config);\n }\n });\n }\n };\n\n renderer.addAttribute('resizable');\n});\n","Magento_Ui/js/lib/knockout/bindings/outer_click.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n/** Creates outerClick binding and registers in to ko.bindingHandlers object */\ndefine([\n 'ko',\n 'jquery',\n 'underscore',\n '../template/renderer'\n], function (ko, $, _, renderer) {\n 'use strict';\n\n var defaults = {\n onlyIfVisible: true\n };\n\n /**\n * Checks if element sis visible.\n *\n * @param {Element} el\n * @returns {Boolean}\n */\n function isVisible(el) {\n var style = window.getComputedStyle(el),\n visibility = {\n display: 'none',\n visibility: 'hidden',\n opacity: '0'\n },\n visible = true;\n\n _.each(visibility, function (val, key) {\n if (style[key] === val) {\n visible = false;\n }\n });\n\n return visible;\n }\n\n /**\n * Document click handler which in case if event target is not\n * a descendant of provided container element,\n * invokes specified in configuration callback.\n *\n * @param {HTMLElement} container\n * @param {Object} config\n * @param {EventObject} e\n */\n function onOuterClick(container, config, e) {\n var target = e.target,\n callback = config.callback;\n\n if (container === target || container.contains(target)) {\n return;\n }\n\n if (config.onlyIfVisible) {\n if (!_.isNull(container.offsetParent) && isVisible(container)) {\n callback();\n }\n } else {\n callback();\n }\n }\n\n /**\n * Prepares configuration for the binding based\n * on a default properties and provided options.\n *\n * @param {(Object|Function)} [options={}]\n * @returns {Object}\n */\n function buildConfig(options) {\n var config = {};\n\n if (_.isFunction(options)) {\n options = {\n callback: options\n };\n } else if (!_.isObject(options)) {\n options = {};\n }\n\n return _.extend(config, defaults, options);\n }\n\n ko.bindingHandlers.outerClick = {\n\n /**\n * Initializes outer click binding.\n */\n init: function (element, valueAccessor) {\n var config = buildConfig(valueAccessor()),\n outerClick = onOuterClick.bind(null, element, config),\n isTouchDevice = typeof document.ontouchstart !== 'undefined';\n\n if (isTouchDevice) {\n $(document).on('touchstart', outerClick);\n\n ko.utils.domNodeDisposal.addDisposeCallback(element, function () {\n $(document).off('touchstart', outerClick);\n });\n } else {\n $(document).on('click', outerClick);\n\n ko.utils.domNodeDisposal.addDisposeCallback(element, function () {\n $(document).off('click', outerClick);\n });\n }\n }\n };\n\n renderer.addAttribute('outerClick');\n});\n","Magento_Ui/js/lib/knockout/bindings/autoselect.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n 'ko',\n 'jquery',\n '../template/renderer'\n], function (ko, $, renderer) {\n 'use strict';\n\n /**\n * 'Focus' event handler.\n *\n * @param {EventObject} e\n */\n function onFocus(e) {\n e.target.select();\n }\n\n ko.bindingHandlers.autoselect = {\n\n /**\n * Adds event handler which automatically\n * selects inputs' element text when field gets focused.\n */\n init: function (element, valueAccessor) {\n var enabled = ko.unwrap(valueAccessor());\n\n if (enabled !== false) {\n $(element).on('focus', onFocus);\n }\n }\n };\n\n renderer.addAttribute('autoselect');\n});\n","Magento_Ui/js/lib/knockout/bindings/color-picker.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n 'ko',\n 'jquery',\n '../template/renderer',\n 'spectrum',\n 'tinycolor'\n], function (ko, $, renderer, spectrum, tinycolor) {\n 'use strict';\n\n /**\n * Change color picker status to be enabled or disabled\n *\n * @param {HTMLElement} element - Element to apply colorpicker enable/disable status to.\n * @param {Object} viewModel - Object, which represents view model binded to el.\n */\n function changeColorPickerStateBasedOnViewModel(element, viewModel) {\n $(element).spectrum(viewModel.disabled() ? 'disable' : 'enable');\n }\n\n ko.bindingHandlers.colorPicker = {\n /**\n * Binding init callback.\n *\n * @param {*} element\n * @param {Function} valueAccessor\n * @param {Function} allBindings\n * @param {Object} viewModel\n */\n init: function (element, valueAccessor, allBindings, viewModel) {\n var config = valueAccessor(),\n\n /** change value */\n changeValue = function (value) {\n if (value == null) {\n value = '';\n }\n config.value(value.toString());\n };\n\n config.change = changeValue;\n\n config.hide = changeValue;\n\n /** show value */\n config.show = function () {\n if (!viewModel.focused()) {\n viewModel.focused(true);\n }\n\n return true;\n };\n\n $(element).spectrum(config);\n\n changeColorPickerStateBasedOnViewModel(element, viewModel);\n },\n\n /**\n * Reads params passed to binding, parses component declarations.\n * Fetches for those found and attaches them to the new context.\n *\n * @param {HTMLElement} element - Element to apply bindings to.\n * @param {Function} valueAccessor - Function that returns value, passed to binding.\n * @param {Object} allBindings - Object, which represents all bindings applied to element.\n * @param {Object} viewModel - Object, which represents view model binded to element.\n */\n update: function (element, valueAccessor, allBindings, viewModel) {\n var config = valueAccessor();\n\n /** Initialise value as empty if it is undefined when color picker input is reset **/\n if (config.value() === undefined) {\n config.value('');\n }\n\n if (tinycolor(config.value()).isValid() || config.value() === '') {\n $(element).spectrum('set', config.value());\n\n if (config.value() !== '') {\n config.value($(element).spectrum('get').toString());\n }\n }\n\n changeColorPickerStateBasedOnViewModel(element, viewModel);\n }\n };\n\n renderer.addAttribute('colorPicker');\n});\n","Magento_Ui/js/lib/knockout/bindings/scope.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n/** Creates scope binding and registers in to ko.bindingHandlers object */\ndefine([\n 'ko',\n 'uiRegistry',\n 'mage/translate',\n '../template/renderer',\n 'jquery',\n '../../logger/console-logger'\n], function (ko, registry, $t, renderer, $, consoleLogger) {\n 'use strict';\n\n /**\n * Creates child context with passed component param as $data. Extends context with $t helper.\n * Applies bindings to descendant nodes.\n * @param {HTMLElement} el - element to apply bindings to.\n * @param {ko.bindingContext} bindingContext - instance of ko.bindingContext, passed to binding initially.\n * @param {Promise} promise - instance of jQuery promise\n * @param {Object} component - component instance to attach to new context\n */\n function applyComponents(el, bindingContext, promise, component) {\n promise.resolve();\n component = bindingContext.createChildContext(component);\n\n ko.utils.extend(component, {\n $t: $t\n });\n\n ko.utils.arrayForEach(ko.virtualElements.childNodes(el), ko.cleanNode);\n\n ko.applyBindingsToDescendants(component, el);\n }\n\n ko.bindingHandlers.scope = {\n\n /**\n * Scope binding's init method.\n * @returns {Object} - Knockout declaration for it to let binding control descendants.\n */\n init: function () {\n return {\n controlsDescendantBindings: true\n };\n },\n\n /**\n * Reads params passed to binding, parses component declarations.\n * Fetches for those found and attaches them to the new context.\n * @param {HTMLElement} el - Element to apply bindings to.\n * @param {Function} valueAccessor - Function that returns value, passed to binding.\n * @param {Object} allBindings - Object, which represents all bindings applied to element.\n * @param {Object} viewModel - Object, which represents view model binded to el.\n * @param {ko.bindingContext} bindingContext - Instance of ko.bindingContext, passed to binding initially.\n */\n update: function (el, valueAccessor, allBindings, viewModel, bindingContext) {\n var component = valueAccessor(),\n promise = $.Deferred(),\n apply = applyComponents.bind(this, el, bindingContext, promise),\n loggerUtils = consoleLogger.utils;\n\n if (typeof component === 'string') {\n loggerUtils.asyncLog(\n promise,\n {\n data: {\n component: component\n },\n messages: loggerUtils.createMessages(\n 'requestingComponent',\n 'requestingComponentIsLoaded',\n 'requestingComponentIsFailed'\n )\n }\n );\n\n registry.get(component, apply);\n } else if (typeof component === 'function') {\n component(apply);\n }\n }\n };\n\n ko.virtualElements.allowedBindings.scope = true;\n\n renderer\n .addNode('scope')\n .addAttribute('scope', {\n name: 'ko-scope'\n });\n});\n","Magento_Ui/js/lib/knockout/bindings/collapsible.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n 'ko',\n 'jquery',\n 'underscore',\n '../template/renderer'\n], function (ko, $, _, renderer) {\n 'use strict';\n\n var collapsible,\n defaults;\n\n defaults = {\n closeOnOuter: true,\n onTarget: false,\n openClass: '_active',\n as: '$collapsible'\n };\n\n collapsible = {\n\n /**\n * Sets 'opened' property to true.\n */\n open: function () {\n this.opened(true);\n },\n\n /**\n * Sets 'opened' property to false.\n */\n close: function () {\n this.opened(false);\n },\n\n /**\n * Toggles value of the 'opened' property.\n */\n toggle: function () {\n this.opened(!this.opened());\n }\n };\n\n /**\n * Document click handler which in case if event target is not\n * a descendant of provided container element, closes collapsible model.\n *\n * @param {HTMLElement} container\n * @param {Object} model\n * @param {EventObject} e\n */\n function onOuterClick(container, model, e) {\n var target = e.target;\n\n if (target !== container && !container.contains(target)) {\n model.close();\n }\n }\n\n /**\n * Creates 'css' binding which toggles\n * class specified in 'name' parameter.\n *\n * @param {Object} model\n * @param {String} name\n * @returns {Object}\n */\n function getClassBinding(model, name) {\n var binding = {};\n\n binding[name] = model.opened;\n\n return {\n css: binding\n };\n }\n\n /**\n * Prepares configuration for the binding based\n * on a default properties and provided options.\n *\n * @param {Object} [options={}]\n * @returns {Object} Complete instance configuration.\n */\n function buildConfig(options) {\n if (typeof options !== 'object') {\n options = {};\n }\n\n return _.extend({}, defaults, options);\n }\n\n ko.bindingHandlers.collapsible = {\n\n /**\n * Initializes 'collapsible' binding.\n */\n init: function (element, valueAccessor, allBindings, viewModel, bindingCtx) {\n var $collapsible = Object.create(collapsible),\n config = buildConfig(valueAccessor()),\n outerClick,\n bindings;\n\n _.bindAll($collapsible, 'open', 'close', 'toggle');\n\n $collapsible.opened = ko.observable(!!config.opened);\n\n bindingCtx[config.as] = $collapsible;\n\n if (config.closeOnOuter) {\n outerClick = onOuterClick.bind(null, element, $collapsible);\n\n $(document).on('click', outerClick);\n\n ko.utils.domNodeDisposal.addDisposeCallback(element, function () {\n $(document).off('click', outerClick);\n });\n }\n\n if (config.openClass) {\n bindings = getClassBinding($collapsible, config.openClass);\n\n ko.applyBindingsToNode(element, bindings, bindingCtx);\n }\n\n if (config.onTarget) {\n $(element).on('click', $collapsible.toggle);\n }\n\n if (viewModel && _.isFunction(viewModel.on)) {\n viewModel.on({\n close: $collapsible.close,\n open: $collapsible.open,\n toggleOpened: $collapsible.toggle\n });\n }\n }\n };\n\n ko.bindingHandlers.closeCollapsible = {\n\n /**\n * Creates listener for the click event on provided DOM element,\n * which closes associated with it collapsible model.\n */\n init: function (element, valueAccessor, allBindings, viewModel, bindingCtx) {\n var name = valueAccessor() || defaults.as,\n $collapsible = bindingCtx[name];\n\n if ($collapsible) {\n $(element).on('click', $collapsible.close);\n }\n }\n };\n\n ko.bindingHandlers.openCollapsible = {\n\n /**\n * Creates listener for the click event on provided DOM element,\n * which opens associated with it collapsible model.\n */\n init: function (element, valueAccessor, allBindings, viewModel, bindingCtx) {\n var name = valueAccessor() || defaults.as,\n $collapsible = bindingCtx[name];\n\n if ($collapsible) {\n $(element).on('click', $collapsible.open);\n }\n }\n };\n\n ko.bindingHandlers.toggleCollapsible = {\n\n /**\n * Creates listener for the click event on provided DOM element,\n * which toggles associated with it collapsible model.\n */\n init: function (element, valueAccessor, allBindings, viewModel, bindingCtx) {\n var name = valueAccessor() || defaults.as,\n $collapsible = bindingCtx[name];\n\n if ($collapsible) {\n $(element).on('click', $collapsible.toggle);\n }\n }\n };\n\n renderer\n .addAttribute('collapsible')\n .addAttribute('openCollapsible')\n .addAttribute('closeCollapsible')\n .addAttribute('toggleCollapsible');\n});\n","Magento_Ui/js/lib/knockout/bindings/i18n.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'jquery',\n 'ko',\n 'module',\n '../template/renderer',\n 'mage/translate'\n], function ($, ko, module, renderer) {\n 'use strict';\n\n var locations = {\n 'legend': 'Caption for the fieldset element',\n 'label': 'Label for an input element.',\n 'button': 'Push button',\n 'a': 'Link label',\n 'b': 'Bold text',\n 'strong': 'Strong emphasized text',\n 'i': 'Italic text',\n 'em': 'Emphasized text',\n 'u': 'Underlined text',\n 'sup': 'Superscript text',\n 'sub': 'Subscript text',\n 'span': 'Span element',\n 'small': 'Smaller text',\n 'big': 'Bigger text',\n 'address': 'Contact information',\n 'blockquote': 'Long quotation',\n 'q': 'Short quotation',\n 'cite': 'Citation',\n 'caption': 'Table caption',\n 'abbr': 'Abbreviated phrase',\n 'acronym': 'An acronym',\n 'var': 'Variable part of a text',\n 'dfn': 'Term',\n 'strike': 'Strikethrough text',\n 'del': 'Deleted text',\n 'ins': 'Inserted text',\n 'h1': 'Heading level 1',\n 'h2': 'Heading level 2',\n 'h3': 'Heading level 3',\n 'h4': 'Heading level 4',\n 'h5': 'Heading level 5',\n 'h6': 'Heading level 6',\n 'center': 'Centered text',\n 'select': 'List options',\n 'img': 'Image',\n 'input': 'Form element'\n },\n\n /**\n * Generates [data-translate] attribute's value\n * @param {Object} translationData\n * @param {String} location\n */\n composeTranslateAttr = function (translationData, location) {\n var obj = [{\n 'shown': translationData.shown,\n 'translated': translationData.translated,\n 'original': translationData.original,\n 'location': locations[location] || 'Text'\n }];\n\n return JSON.stringify(obj);\n },\n\n /**\n * Sets text for the element\n * @param {Object} el\n * @param {String} text\n */\n setText = function (el, text) {\n $(el).text(text);\n },\n\n /**\n * Sets [data-translate] attribute for the element\n * @param {Object} el - The element which is binded\n * @param {String} original - The original value of the element\n */\n setTranslateProp = function (el, original) {\n var location = $(el).prop('tagName').toLowerCase(),\n translated = $.mage.__(original),\n translationData = {\n shown: translated,\n translated: translated,\n original: original\n },\n translateAttr = composeTranslateAttr(translationData, location);\n\n $(el).attr('data-translate', translateAttr);\n\n setText(el, translationData.shown);\n },\n\n /**\n * Checks if node represents ko virtual node (nodeType === 8, nodeName === '#comment').\n *\n * @param {HTMLElement} node\n * @returns {Boolean}\n */\n isVirtualElement = function (node) {\n return node.nodeType === 8;\n },\n\n /**\n * Checks if it's real DOM element\n * in case of virtual element, returns span wrapper\n * @param {Object} el\n * @param {bool} isUpdate\n * @return {Object} el\n */\n getRealElement = function (el, isUpdate) {\n if (isVirtualElement(el)) {\n if (isUpdate) {\n return $(el).next('span');\n }\n\n return $('<span></span>').insertAfter(el);\n }\n\n return el;\n },\n\n /**\n * execute i18n binding\n * @param {Object} element\n * @param {Function} valueAccessor\n * @param {bool} isUpdate\n */\n execute = function (element, valueAccessor, isUpdate) {\n var original = ko.unwrap(valueAccessor() || ''),\n el = getRealElement(element, isUpdate),\n inlineTranslation = (module.config() || {}).inlineTranslation;\n\n if (inlineTranslation) {\n setTranslateProp(el, original);\n } else {\n setText(el, $.mage.__(original));\n }\n };\n\n /**\n * i18n binding\n * @property {Function} init\n * @property {Function} update\n */\n ko.bindingHandlers.i18n = {\n\n /**\n * init i18n binding\n * @param {Object} element\n * @param {Function} valueAccessor\n */\n init: function (element, valueAccessor) {\n execute(element, valueAccessor);\n },\n\n /**\n * update i18n binding\n * @param {Object} element\n * @param {Function} valueAccessor\n */\n update: function (element, valueAccessor) {\n execute(element, valueAccessor, true);\n }\n };\n\n ko.virtualElements.allowedBindings.i18n = true;\n\n renderer\n .addNode('translate', {\n binding: 'i18n'\n })\n .addAttribute('translate', {\n binding: 'i18n'\n });\n});\n","Magento_Ui/js/lib/registry/registry.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n 'jquery',\n 'underscore'\n], function ($, _) {\n 'use strict';\n\n var privateData = new WeakMap();\n\n /**\n * Extracts private item storage associated\n * with a provided registry instance.\n *\n * @param {Object} container\n * @returns {Object}\n */\n function getItems(container) {\n return privateData.get(container).items;\n }\n\n /**\n * Extracts private requests array associated\n * with a provided registry instance.\n *\n * @param {Object} container\n * @returns {Array}\n */\n function getRequests(container) {\n return privateData.get(container).requests;\n }\n\n /**\n * Wrapper function used for convenient access to the elements.\n * See 'async' method for examples of usage and comparison\n * with a regular 'get' method.\n *\n * @param {(String|Object|Function)} name - Key of the requested element.\n * @param {Registry} registry - Instance of a registry\n * where to search for the element.\n * @param {(Function|String)} [method] - Optional callback function\n * or a name of the elements' method which\n * will be invoked when element is available in registry.\n * @returns {*}\n */\n function async(name, registry, method) {\n var args = _.toArray(arguments).slice(3);\n\n if (_.isString(method)) {\n registry.get(name, function (component) {\n component[method].apply(component, args);\n });\n } else if (_.isFunction(method)) {\n registry.get(name, method);\n } else if (!args.length) {\n return registry.get(name);\n }\n }\n\n /**\n * Checks that every property of the query object\n * is present and equal to the corresponding\n * property in target object.\n * Note that non-strict comparison is used.\n *\n * @param {Object} query - Query object.\n * @param {Object} target - Target object.\n * @returns {Boolean}\n */\n function compare(query, target) {\n var matches = true,\n index,\n keys,\n key;\n\n if (!_.isObject(query) || !_.isObject(target)) {\n return false;\n }\n\n keys = Object.getOwnPropertyNames(query);\n index = keys.length;\n\n while (matches && index--) {\n key = keys[index];\n\n /* eslint-disable eqeqeq */\n if (target[key] != query[key]) {\n matches = false;\n }\n\n /* eslint-enable eqeqeq */\n }\n\n return matches;\n }\n\n /**\n * Explodes incoming string into object if\n * string is defined as a set of key = value pairs.\n *\n * @param {(String|*)} query - String to be processed.\n * @returns {Object|*} Either created object or an unmodified incoming\n * value if conversion was not possible.\n * @example Sample conversions.\n * 'key = value, key2 = value2'\n * => {key: 'value', key2: 'value2'}\n */\n function explode(query) {\n var result = {},\n index,\n data;\n\n if (typeof query !== 'string' || !~query.indexOf('=')) {\n return query;\n }\n\n query = query.split(',');\n index = query.length;\n\n while (index--) {\n data = query[index].split('=');\n\n result[data[0].trim()] = data[1].trim();\n }\n\n return result;\n }\n\n /**\n * Extracts items from the provided data object\n * which matches specified search criteria.\n *\n * @param {Object} data - Data object where to perform a lookup.\n * @param {(String|Object|Function)} query - Search criteria.\n * @param {Boolean} findAll - Flag that defines whether to\n * search for all applicable items or to stop on a first found entry.\n * @returns {Array|Object|*}\n */\n function find(data, query, findAll) {\n var iterator,\n item;\n\n query = explode(query);\n\n if (typeof query === 'string') {\n item = data[query];\n\n if (findAll) {\n return item ? [item] : [];\n }\n\n return item;\n }\n\n iterator = !_.isFunction(query) ?\n compare.bind(null, query) :\n query;\n\n return findAll ?\n _.filter(data, iterator) :\n _.find(data, iterator);\n }\n\n /**\n * @constructor\n */\n function Registry() {\n var data = {\n items: {},\n requests: []\n };\n\n this._updateRequests = _.debounce(this._updateRequests.bind(this), 10);\n privateData.set(this, data);\n }\n\n Registry.prototype = {\n constructor: Registry,\n\n /**\n * Retrieves item from registry which matches specified search criteria.\n *\n * @param {(Object|String|Function|Array)} query - Search condition (see examples).\n * @param {Function} [callback] - Callback that will be invoked when\n * all of the requested items are available.\n * @returns {*}\n *\n * @example Requesting item by it's name.\n * var obj = {index: 'test', sample: true};\n *\n * registry.set('first', obj);\n * registry.get('first') === obj;\n * => true\n *\n * @example Requesting item with a specific properties.\n * registry.get('sample = 1, index = test') === obj;\n * => true\n * registry.get('sample = 0, index = foo') === obj;\n * => false\n *\n * @example Declaring search criteria as an object.\n * registry.get({sample: true}) === obj;\n * => true;\n *\n * @example Providing custom search handler.\n * registry.get(function (item) { return item.sample === true; }) === obj;\n * => true\n *\n * @example Sample asynchronous request declaration.\n * registry.get('index = test', function (item) {});\n *\n * @example Requesting multiple elements.\n * registry.set('second', {index: 'test2'});\n * registry.get(['first', 'second'], function (first, second) {});\n */\n get: function (query, callback) {\n if (typeof callback !== 'function') {\n return find(getItems(this), query);\n }\n\n this._addRequest(query, callback);\n },\n\n /**\n * Sets provided item to the registry.\n *\n * @param {String} id - Item's identifier.\n * @param {*} item - Item's data.\n * returns {Registry} Chainable.\n */\n set: function (id, item) {\n getItems(this)[id] = item;\n\n this._updateRequests();\n\n return this;\n },\n\n /**\n * Removes specified item from registry.\n * Note that search query is not applicable.\n *\n * @param {String} id - Item's identifier.\n * @returns {Registry} Chainable.\n */\n remove: function (id) {\n delete getItems(this)[id];\n\n return this;\n },\n\n /**\n * Retrieves a collection of elements that match\n * provided search criteria.\n *\n * @param {(Object|String|Function)} query - Search query.\n * See 'get' method for the syntax examples.\n * @returns {Array} Found elements.\n */\n filter: function (query) {\n return find(getItems(this), query, true);\n },\n\n /**\n * Checks that at least one element in collection\n * matches provided search criteria.\n *\n * @param {(Object|String|Function)} query - Search query.\n * See 'get' method for the syntax examples.\n * @returns {Boolean}\n */\n has: function (query) {\n return !!this.get(query);\n },\n\n /**\n * Checks that registry contains a provided item.\n *\n * @param {*} item - Item to be checked.\n * @returns {Boolean}\n */\n contains: function (item) {\n return _.contains(getItems(this), item);\n },\n\n /**\n * Extracts identifier of an item if it's present in registry.\n *\n * @param {*} item - Item whose identifier will be extracted.\n * @returns {String|Undefined}\n */\n indexOf: function (item) {\n return _.findKey(getItems(this), function (elem) {\n return item === elem;\n });\n },\n\n /**\n * Same as a 'get' method except that it returns\n * a promise object instead of invoking provided callback.\n *\n * @param {(String|Function|Object|Array)} query - Search query.\n * See 'get' method for the syntax examples.\n * @returns {jQueryPromise}\n */\n promise: function (query) {\n var defer = $.Deferred(),\n callback = defer.resolve.bind(defer);\n\n this.get(query, callback);\n\n return defer.promise();\n },\n\n /**\n * Creates a wrapper function over the provided search query\n * in order to provide somehow more convenient access to the\n * registry's items.\n *\n * @param {(String|Object|Function)} query - Search criteria.\n * See 'get' method for the syntax examples.\n * @returns {Function}\n *\n * @example Comparison with a 'get' method on retrieving items.\n * var module = registry.async('name');\n *\n * module();\n * => registry.get('name');\n *\n * @example Asynchronous request.\n * module(function (component) {});\n * => registry.get('name', function (component) {});\n *\n * @example Requesting item and invoking it's method with specified parameters.\n * module('trigger', true);\n * => registry.get('name', function (component) {\n * component.trigger(true);\n * });\n */\n async: function (query) {\n return async.bind(null, query, this);\n },\n\n /**\n * Creates new instance of a Registry.\n *\n * @returns {Registry} New instance.\n */\n create: function () {\n return new Registry;\n },\n\n /**\n * Adds new request to the queue or resolves it immediately\n * if all of the required items are available.\n *\n * @private\n * @param {(Object|String|Function|Array)} queries - Search criteria.\n * See 'get' method for the syntax examples.\n * @param {Function} callback - Callback that will be invoked when\n * all of the requested items are available.\n * @returns {Registry}\n */\n _addRequest: function (queries, callback) {\n var request;\n\n if (!Array.isArray(queries)) {\n queries = queries ? [queries] : [];\n }\n\n request = {\n queries: queries.map(explode),\n callback: callback\n };\n\n this._canResolve(request) ?\n this._resolveRequest(request) :\n getRequests(this).push(request);\n\n return this;\n },\n\n /**\n * Updates requests list resolving applicable items.\n *\n * @private\n * @returns {Registry} Chainable.\n */\n _updateRequests: function () {\n getRequests(this)\n .filter(this._canResolve, this)\n .forEach(this._resolveRequest, this);\n\n return this;\n },\n\n /**\n * Resolves provided request invoking it's callback\n * with items specified in query parameters.\n *\n * @private\n * @param {Object} request - Request object.\n * @returns {Registry} Chainable.\n */\n _resolveRequest: function (request) {\n var requests = getRequests(this),\n items = request.queries.map(this.get, this),\n index = requests.indexOf(request);\n\n request.callback.apply(null, items);\n\n if (~index) {\n requests.splice(index, 1);\n }\n\n return this;\n },\n\n /**\n * Checks if provided request can be resolved.\n *\n * @private\n * @param {Object} request - Request object.\n * @returns {Boolean}\n */\n _canResolve: function (request) {\n var queries = request.queries;\n\n return queries.every(this.has, this);\n }\n };\n\n return new Registry;\n});\n","Magento_Ui/js/lib/view/utils/dom-observer.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n 'jquery',\n 'underscore',\n 'domReady!'\n], function ($, _) {\n 'use strict';\n\n var counter = 1,\n watchers,\n globalObserver,\n disabledNodes = [];\n\n watchers = {\n selectors: {},\n nodes: {}\n };\n\n /**\n * Checks if node represents an element node (nodeType === 1).\n *\n * @param {HTMLElement} node\n * @returns {Boolean}\n */\n function isElementNode(node) {\n return node.nodeType === 1;\n }\n\n /**\n * Extracts all child descendant\n * elements of a specified node.\n *\n * @param {HTMLElement} node\n * @returns {Array}\n */\n function extractChildren(node) {\n var children = node.querySelectorAll('*');\n\n return _.toArray(children);\n }\n\n /**\n * Extracts node identifier. If ID is not specified,\n * then it will be created for the provided node.\n *\n * @param {HTMLElement} node\n * @returns {Number}\n */\n function getNodeId(node) {\n var id = node._observeId;\n\n if (!id) {\n id = node._observeId = counter++;\n }\n\n return id;\n }\n\n /**\n * Invokes callback passing node to it.\n *\n * @param {HTMLElement} node\n * @param {Object} data\n */\n function trigger(node, data) {\n var id = getNodeId(node),\n ids = data.invoked;\n\n if (_.contains(ids, id)) {\n return;\n }\n\n data.callback(node);\n data.invoked.push(id);\n }\n\n /**\n * Adds node to the observer list.\n *\n * @param {HTMLElement} node\n * @returns {Object}\n */\n function createNodeData(node) {\n var nodes = watchers.nodes,\n id = getNodeId(node);\n\n nodes[id] = nodes[id] || {};\n\n return nodes[id];\n }\n\n /**\n * Returns data associated with a specified node.\n *\n * @param {HTMLElement} node\n * @returns {Object|Undefined}\n */\n function getNodeData(node) {\n var nodeId = node._observeId;\n\n return watchers.nodes[nodeId];\n }\n\n /**\n * Removes data associated with a specified node.\n *\n * @param {HTMLElement} node\n */\n function removeNodeData(node) {\n var nodeId = node._observeId;\n\n delete watchers.nodes[nodeId];\n }\n\n /**\n * Adds removal listener for a specified node.\n *\n * @param {HTMLElement} node\n * @param {Object} data\n */\n function addRemovalListener(node, data) {\n var nodeData = createNodeData(node);\n\n (nodeData.remove = nodeData.remove || []).push(data);\n }\n\n /**\n * Adds listener for the nodes which matches specified selector.\n *\n * @param {String} selector - CSS selector.\n * @param {Object} data\n */\n function addSelectorListener(selector, data) {\n var storage = watchers.selectors;\n\n (storage[selector] = storage[selector] || []).push(data);\n }\n\n /**\n * Calls handlers associated with an added node.\n * Adds listeners for the node removal.\n *\n * @param {HTMLElement} node - Added node.\n */\n function processAdded(node) {\n _.each(watchers.selectors, function (listeners, selector) {\n for (let data of listeners) {\n if (!data.ctx.contains(node) || !$(node, data.ctx).is(selector)) {\n break;\n }\n\n if (data.type === 'add') {\n trigger(node, data);\n } else if (data.type === 'remove') {\n addRemovalListener(node, data);\n }\n }\n });\n }\n\n /**\n * Calls handlers associated with a removed node.\n *\n * @param {HTMLElement} node - Removed node.\n */\n function processRemoved(node) {\n var nodeData = getNodeData(node),\n listeners = nodeData && nodeData.remove;\n\n\n if (!listeners) {\n return;\n }\n\n for (let data of listeners) {\n trigger(node, data);\n }\n removeNodeData(node);\n }\n\n /**\n * Removes all non-element nodes from provided array\n * and appends to it descendant elements.\n *\n * @param {Array} nodes\n * @returns {Array}\n */\n function formNodesList(nodes) {\n var result = [],\n children;\n\n nodes = _.toArray(nodes).filter(isElementNode);\n\n for (let node of nodes) {\n result.push(node);\n\n children = extractChildren(node);\n result.push(...children);\n }\n\n return result;\n }\n\n /**\n * Collects all removed and added nodes from\n * mutation records into separate arrays\n * while removing duplicates between both types of changes.\n *\n * @param {Array} mutations - An array of mutation records.\n * @returns {Object} Object with 'removed' and 'added' nodes arrays.\n */\n function formChangesLists(mutations) {\n var removed = [],\n added = [];\n\n for (let record of mutations) {\n removed.push(...record.removedNodes);\n added.push(...record.addedNodes);\n }\n\n removed = removed.filter(function (node) {\n var addIndex = added.indexOf(node),\n wasAdded = !!~addIndex;\n\n if (wasAdded) {\n added.splice(addIndex, 1);\n }\n\n return !wasAdded;\n });\n\n return {\n removed: formNodesList(removed),\n added: formNodesList(added)\n };\n }\n\n /**\n * Verify if the DOM node is a child of a defined disabled node, if so we shouldn't observe provided mutation.\n *\n * @param {Object} mutation - a single mutation\n * @returns {Boolean}\n */\n function shouldObserveMutation(mutation) {\n var isDisabled;\n\n if (disabledNodes.length > 0) {\n // Iterate through the disabled nodes and determine if this mutation is occurring inside one of them\n isDisabled = _.find(disabledNodes, function (node) {\n return node === mutation.target || $.contains(node, mutation.target);\n });\n\n // If we find a matching node we should not observe the mutation\n return !isDisabled;\n }\n\n return true;\n }\n\n /**\n * Should we observe these mutations? Check the first and last mutation to determine if this is a disabled mutation,\n * we check both the first and last in case one has been removed from the DOM during the process of the mutation.\n *\n * @param {Array} mutations - An array of mutation records.\n * @returns {Boolean}\n */\n function shouldObserveMutations(mutations) {\n var firstMutation,\n lastMutation;\n\n if (mutations.length > 0) {\n firstMutation = mutations[0];\n lastMutation = mutations[mutations.length - 1];\n\n return shouldObserveMutation(firstMutation) && shouldObserveMutation(lastMutation);\n }\n\n return true;\n }\n\n globalObserver = new MutationObserver(function (mutations) {\n var changes;\n\n if (shouldObserveMutations(mutations)) {\n let node;\n\n changes = formChangesLists(mutations);\n\n for (node of changes.removed) {\n processRemoved(node);\n }\n for (node of changes.added) {\n processAdded(node);\n }\n }\n });\n\n globalObserver.observe(document.body, {\n subtree: true,\n childList: true\n });\n\n return {\n /**\n * Disable a node from being observed by the mutations, you may want to disable specific aspects of the\n * application which are heavy on DOM changes. The observer running on some actions could cause significant\n * delays and degrade the performance of that specific part of the application exponentially.\n *\n * @param {HTMLElement} node - a HTML node within the document\n */\n disableNode: function (node) {\n disabledNodes.push(node);\n },\n\n /**\n * Adds listener for the appearance of nodes that matches provided\n * selector and which are inside of the provided context. Callback will be\n * also invoked on elements which a currently present.\n *\n * @param {String} selector - CSS selector.\n * @param {Function} callback - Function that will invoked when node appears.\n * @param {HTMLElement} [ctx=document.body] - Context inside of which to search for the node.\n */\n get: function (selector, callback, ctx) {\n var data,\n nodes;\n\n data = {\n ctx: ctx || document.body,\n type: 'add',\n callback: callback,\n invoked: []\n };\n\n nodes = $(selector, data.ctx).toArray();\n\n for (let node of nodes) {\n trigger(node, data);\n }\n addSelectorListener(selector, data);\n },\n\n /**\n * Adds listener for the nodes removal.\n *\n * @param {(jQueryObject|HTMLElement|Array|String)} selector\n * @param {Function} callback - Function that will invoked when node is removed.\n * @param {HTMLElement} [ctx=document.body] - Context inside of which to search for the node.\n */\n remove: function (selector, callback, ctx) {\n var nodes = [],\n data;\n\n data = {\n ctx: ctx || document.body,\n type: 'remove',\n callback: callback,\n invoked: []\n };\n\n if (typeof selector === 'object') {\n nodes = !_.isUndefined(selector.length) ?\n _.toArray(selector) :\n [selector];\n } else if (_.isString(selector)) {\n nodes = $(selector, ctx).toArray();\n\n addSelectorListener(selector, data);\n }\n\n for (let node of nodes) {\n addRemovalListener(node, data);\n }\n },\n\n /**\n * Removes listeners.\n *\n * @param {String} selector\n * @param {Function} [fn]\n */\n off: function (selector, fn) {\n var selectors = watchers.selectors,\n listeners = selectors[selector];\n\n if (selector && !fn) {\n delete selectors[selector];\n } else if (listeners && fn) {\n selectors[selector] = listeners.filter(function (data) {\n return data.callback !== fn;\n });\n }\n }\n };\n});\n","Magento_Ui/js/lib/view/utils/bindings.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n 'ko',\n 'jquery',\n 'underscore'\n], function (ko, $, _) {\n 'use strict';\n\n /**\n * Checks if provided value is a dom element.\n *\n * @param {*} node - Value to be checked.\n * @returns {Boolean}\n */\n function isDomElement(node) {\n return typeof node === 'object' && node.tagName && node.nodeType;\n }\n\n /**\n * Removes from the provided array all non-root nodes located inside\n * of the comment element as long as the closing comment tags.\n *\n * @param {(Array|ArrayLike)} nodes - An array of nodes to be processed.\n * @returns {Array}\n */\n function normalize(nodes) {\n var result;\n\n nodes = _.toArray(nodes);\n result = nodes.slice();\n\n nodes.forEach(function (node) {\n if (node.nodeType === 8) {\n result = !ko.virtualElements.hasBindingValue(node) ?\n _.without(result, node) :\n _.difference(result, ko.virtualElements.childNodes(node));\n }\n });\n\n return result;\n }\n\n /**\n * Extends binding context of each item in the collection.\n *\n * @param {...Object} extenders - Multiple extender objects to be applied to the context.\n * @returns {jQueryCollection} Chainable.\n */\n $.fn.extendCtx = function () {\n var nodes = normalize(this),\n extenders = _.toArray(arguments);\n\n nodes.forEach(function (node) {\n var ctx = ko.contextFor(node),\n data = [ctx].concat(extenders);\n\n _.extend.apply(_, data);\n });\n\n return this;\n };\n\n /**\n * Evaluates bindings specified in each DOM element of collection.\n *\n * @param {(HTMLElement|Object)} [ctx] - Context to use for bindings evaluation.\n * If not specified then current context of a collections' item will be used.\n * @returns {jQueryCollection} Chainable.\n */\n $.fn.applyBindings = function (ctx) {\n var nodes = normalize(this),\n nodeCtx;\n\n if (isDomElement(ctx)) {\n ctx = ko.contextFor(ctx);\n }\n\n nodes.forEach(function (node) {\n nodeCtx = ctx || ko.contextFor(node);\n\n ko.applyBindings(nodeCtx, node);\n });\n\n return this;\n };\n\n /**\n * Adds specified bindings to each DOM element in\n * collection and evaluates them with provided context.\n *\n * @param {(Object|Function)} data - Either bindings object or a function\n * which returns bindings data for each element in collection.\n * @param {(HTMLElement|Object)} [ctx] - Context to use for bindings evaluation.\n * If not specified then current context of a collections' item will be used.\n * @returns {jQueryCollection} Chainable.\n */\n $.fn.bindings = function (data, ctx) {\n var nodes = normalize(this),\n bindings = data,\n nodeCtx;\n\n if (isDomElement(ctx)) {\n ctx = ko.contextFor(ctx);\n }\n\n nodes.forEach(function (node) {\n nodeCtx = ctx || ko.contextFor(node);\n\n if (_.isFunction(data)) {\n bindings = data(nodeCtx, node);\n }\n\n ko.applyBindingsToNode(node, bindings, nodeCtx);\n });\n\n return this;\n };\n});\n","Magento_Ui/js/lib/view/utils/raf.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([], function () {\n 'use strict';\n\n var processMap = new WeakMap(),\n origRaf,\n raf;\n\n origRaf = window.requestAnimationFrame ||\n window.webkitRequestAnimationFrame ||\n window.mozRequestAnimationFrame ||\n window.onRequestAnimationFrame ||\n window.msRequestAnimationFrame ||\n function (callback) {\n if (typeof callback != 'function') {\n throw new Error('raf argument \"callback\" must be of type function');\n }\n window.setTimeout(callback, 1000 / 60);\n };\n\n /**\n * Creates new process object or extracts the\n * the existing one.\n *\n * @param {*} id - Process identifier.\n * @param {Number} fps - Required FPS count.\n * @returns {Object}\n */\n function getProcess(id, fps) {\n var process = processMap.get(id);\n\n if (!process) {\n process = {};\n processMap.set(id, process);\n }\n\n if (process.fps !== fps) {\n process.fps = fps;\n process.interval = 1000 / fps;\n process.update = Date.now();\n }\n\n return process;\n }\n\n /**\n * Proxy method which delegates call to the 'requestAnimationFrame'\n * function and optionally can keep track of the FPS with which\n * provided function is called.\n *\n * @param {Function} callback - Callback function to be passed to 'requestAnimationFrame'.\n * @param {Number} [fps] - If specified, will update FPS counter for the provided function.\n * @returns {Number|Boolean} ID of request or a flag which indicates\n * whether callback fits specified FPS.\n */\n raf = function (callback, fps) {\n var rafId = origRaf(callback);\n\n return fps ? raf.tick(callback, fps) : rafId;\n };\n\n /**\n * Updates FPS counter for the specified process\n * and returns a flag which indicates whether\n * counter value is equal or greater than the required FPS.\n *\n * @param {*} id - Process identifier.\n * @param {Number} fps - Required FPS count.\n * @returns {Boolean}\n */\n raf.tick = function (id, fps) {\n var process = getProcess(id, fps),\n now = Date.now(),\n delta = now - process.update,\n interval = process.interval;\n\n if (fps >= 60 || delta >= interval) {\n process.update = now - delta % interval;\n\n return true;\n }\n\n return false;\n };\n\n return raf;\n});\n","Magento_Ui/js/lib/view/utils/async.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n 'ko',\n 'jquery',\n 'underscore',\n 'uiRegistry',\n './dom-observer',\n 'Magento_Ui/js/lib/knockout/extender/bound-nodes',\n './bindings'\n], function (ko, $, _, registry, domObserver, boundedNodes) {\n 'use strict';\n\n /**\n * Checks if provided value is a dom element.\n *\n * @param {*} node - Value to be checked.\n * @returns {Boolean}\n */\n function isDomElement(node) {\n return typeof node === 'object' && node.tagName && node.nodeType;\n }\n\n /**\n * Parses provided string and extracts\n * component, context and selector data from it.\n *\n * @param {String} str - String to be processed.\n * @returns {Object} Data retrieved from string.\n *\n * @example Sample format.\n * '{{component}}:{{ctx}} -> {{selector}}'\n *\n * component - Name of component.\n * ctx - Selector of the root node upon which component is binded.\n * selector - Selector of DOM elements located\n * inside of a previously specified context.\n */\n function parseSelector(str) {\n var data = str.trim().split('->'),\n result = {},\n componentData;\n\n if (data.length === 1) {\n if (!~data[0].indexOf(':')) {\n result.selector = data[0];\n } else {\n componentData = data[0];\n }\n } else {\n componentData = data[0];\n result.selector = data[1];\n }\n\n if (componentData) {\n componentData = componentData.split(':');\n\n result.component = componentData[0];\n result.ctx = componentData[1];\n }\n\n _.each(result, function (value, key) {\n result[key] = value.trim();\n });\n\n return result;\n }\n\n /**\n * Internal method used to normalize argumnets passed\n * to 'async' module methods.\n *\n * @param {(String|Object)} selector\n * @param {(HTMLElement|Object|String)} [ctx]\n * @returns {Object}\n */\n function parseData(selector, ctx) {\n var data = {};\n\n if (arguments.length === 2) {\n data.selector = selector;\n\n if (isDomElement(ctx)) {\n data.ctx = ctx;\n } else {\n data.component = ctx;\n data.ctx = '*';\n }\n } else {\n data = _.isString(selector) ?\n parseSelector(selector) :\n selector;\n }\n\n return data;\n }\n\n /**\n * Creates promise that will be resolved\n * when requested component is registred.\n *\n * @param {String} name - Name of component.\n * @returns {jQueryPromise}\n */\n function waitComponent(name) {\n var deffer = $.Deferred();\n\n if (_.isString(name)) {\n registry.get(name, function (component) {\n deffer.resolve(component);\n });\n } else {\n deffer.resolve(name);\n }\n\n return deffer.promise();\n }\n\n /**\n * Creates listener for the nodes binded to provided component.\n *\n * @param {Object} data - Listener data.\n * @param {Object} component - Associated with nodes component.\n */\n function setRootListener(data, component) {\n boundedNodes.get(component, function (root) {\n if (!$(root).is(data.ctx || '*')) {\n return;\n }\n\n data.selector ?\n domObserver.get(data.selector, data.fn, root) :\n data.fn(root);\n });\n }\n\n /*eslint-disable no-unused-vars*/\n /**\n * Sets listener for the appearance of elements which\n * matches specified selector data.\n *\n * @param {(String|Object)} selector - Valid css selector or a string\n * in format acceptable by 'parseSelector' method or an object with\n * 'component', 'selector' and 'ctx' properties.\n * @param {(HTMLElement|Object|String)} [ctx] - Optional context parameter\n * which might be a DOM element, component instance or components' name.\n * @param {Function} fn - Callback that will be invoked\n * when required DOM element appears.\n *\n * @example\n * Creating listener of the 'span' nodes appearance,\n * located inside of 'div' nodes, which are binded to 'cms_page_listing' component:\n *\n * $.async('cms_page_listing:div -> span', function (node) {});\n *\n * @example Another syntaxes of the previous example.\n * $.async({\n * component: 'cms_page_listing',\n * ctx: 'div',\n * selector: 'span'\n * }, function (node) {});\n *\n * @example Listens for appearance of any child node inside of specified component.\n * $.async('> *', 'cms_page_lsiting', function (node) {});\n *\n * @example Listens for appearance of 'span' nodes inside of specific context.\n * $.async('span', document.getElementById('test'), function (node) {});\n */\n $.async = function (selector, ctx, fn) {\n var args = _.toArray(arguments),\n data = parseData.apply(null, _.initial(args));\n\n data.fn = _.last(args);\n\n if (data.component) {\n waitComponent(data.component)\n .then(setRootListener.bind(null, data));\n } else {\n domObserver.get(data.selector, data.fn, data.ctx);\n }\n };\n\n /*eslint-enable no-unused-vars*/\n\n _.extend($.async, {\n\n /*eslint-disable no-unused-vars*/\n /**\n * Returns collection of elements found by provided selector data.\n *\n * @param {(String|Object)} selector - See 'async' definition.\n * @param {(HTMLElement|Object|String)} [ctx] - See 'async' definition.\n * @returns {Array} An array of DOM elements.\n */\n get: function (selector, ctx) {\n var data = parseData.apply(null, arguments),\n component = data.component,\n nodes;\n\n if (!component) {\n return $(data.selector, data.ctx).toArray();\n } else if (_.isString(component)) {\n component = registry.get(component);\n }\n\n if (!component) {\n return [];\n }\n\n nodes = boundedNodes.get(component);\n nodes = $(nodes).filter(data.ctx).toArray();\n\n return data.selector ?\n $(data.selector, nodes).toArray() :\n nodes;\n },\n\n /*eslint-enable no-unused-vars*/\n\n /**\n * Sets removal listener of the specified nodes.\n *\n * @param {(HTMLElement|Array|ArrayLike)} nodes - Nodes whose removal to track.\n * @param {Function} fn - Callback that will be invoked when node is removed.\n */\n remove: function (nodes, fn) {\n domObserver.remove(nodes, fn);\n },\n\n parseSelector: parseSelector\n });\n\n return $;\n});\n","Magento_Ui/js/lib/logger/console-output-handler.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n './levels-pool'\n], function (logLevels) {\n 'use strict';\n\n var levels = logLevels.getLevels();\n\n /**\n * @param {LogFormatter} formatter\n */\n function ConsoleOutputHandler(formatter) {\n /**\n * @protected\n * @type {LogFormatter}\n */\n this.formatter_ = formatter;\n }\n\n /**\n * Display data of the provided entry to the console.\n *\n * @param {LogEntry} entry - Entry to be displayed.\n */\n ConsoleOutputHandler.prototype.show = function (entry) {\n var displayString = this.formatter_.process(entry);\n\n switch (entry.level) {\n case levels.ERROR:\n console.error(displayString);\n break;\n\n case levels.WARN:\n console.warn(displayString);\n break;\n\n case levels.INFO:\n console.info(displayString);\n break;\n\n case levels.DEBUG:\n console.log(displayString);\n break;\n }\n };\n\n /**\n * Displays the array of entries.\n *\n * @param {Array<LogEntry>} entries\n */\n ConsoleOutputHandler.prototype.dump = function (entries) {\n entries.forEach(this.show, this);\n };\n\n return ConsoleOutputHandler;\n});\n","Magento_Ui/js/lib/logger/logger.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n './levels-pool'\n], function (logLevels) {\n 'use strict';\n\n var levels = logLevels.getLevels();\n\n /**\n * @param {LogOutputHandler} outputHandler\n * @param {LogEntryFactory} entryFactory\n */\n function Logger(outputHandler, entryFactory) {\n /**\n * An array of log entries.\n *\n * @protected\n * @type {Array<LogEntry>}\n */\n this.entries_ = [];\n\n /**\n * Current display level.\n *\n * @protected\n * @type {Number}\n */\n this.displayLevel_ = levels.ERROR;\n\n /**\n * An array of display criteria.\n *\n * @protected\n * @type {Array<LogCriteria>}\n */\n this.displayCriteria_ = [];\n\n /**\n * @protected\n * @type {LogEntryFactory}\n */\n this.entryFactory_ = entryFactory;\n\n /**\n * @protected\n * @type {Array<LogOutputHandler>}\n */\n this.outputHandlers_ = [outputHandler];\n\n this.addDisplayCriteria(this.matchesLevel_);\n }\n\n /**\n * Swaps current display level with the provided one.\n *\n * @param {Number} level - Level's code.\n */\n Logger.prototype.setDisplayLevel = function (level) {\n var levelName = logLevels.getNameByCode(level);\n\n if (!levelName) {\n throw new TypeError('The provided level is not defined in the levels list.');\n }\n\n this.displayLevel_ = level;\n };\n\n /**\n * Sets up the criteria by which log entries will be filtered out from the output.\n *\n * @param {LogCriteria} criteria\n */\n Logger.prototype.addDisplayCriteria = function (criteria) {\n this.displayCriteria_.push(criteria);\n };\n\n /**\n * Removes previously defined criteria.\n *\n * @param {LogCriteria} criteria\n */\n Logger.prototype.removeDisplayCriteria = function (criteria) {\n var index = this.displayCriteria_.indexOf(criteria);\n\n if (~index) {\n this.displayCriteria_.splice(index, 1);\n }\n };\n\n /**\n * @param {String} message\n * @param {Object} [messageData]\n * @returns {LogEntry}\n */\n Logger.prototype.error = function (message, messageData) {\n return this.log_(message, levels.ERROR, messageData);\n };\n\n /**\n * @param {String} message\n * @param {Object} [messageData]\n * @returns {LogEntry}\n */\n Logger.prototype.warn = function (message, messageData) {\n return this.log_(message, levels.WARN, messageData);\n };\n\n /**\n * @param {String} message\n * @param {Object} [messageData]\n * @returns {LogEntry}\n */\n Logger.prototype.info = function (message, messageData) {\n return this.log_(message, levels.INFO, messageData);\n };\n\n /**\n * @param {String} message\n * @param {Object} [messageData]\n * @returns {LogEntry}\n */\n Logger.prototype.debug = function (message, messageData) {\n return this.log_(message, levels.DEBUG, messageData);\n };\n\n /**\n * @protected\n * @param {String} message\n * @param {Number} level\n * @param {Object} [messageData]\n * @returns {LogEntry}\n */\n Logger.prototype.log_ = function (message, level, messageData) {\n var entry = this.createEntry_(message, level, messageData);\n\n this.entries_.push(entry);\n\n if (this.matchesCriteria_(entry)) {\n this.processOutput_(entry);\n }\n\n return entry;\n };\n\n /**\n * @protected\n * @param {String} message\n * @param {Number} level\n * @param {Object} [messageData]\n * @returns {LogEntry}\n */\n Logger.prototype.createEntry_ = function (message, level, messageData) {\n return this.entryFactory_.createEntry(message, level, messageData);\n };\n\n /**\n * Returns an array of log entries that have been added to the logger.\n *\n * @param {LogCriteria} [criteria] - Optional filter criteria.\n * @returns {Array<LogEntry>}\n */\n Logger.prototype.getEntries = function (criteria) {\n if (criteria) {\n return this.entries_.filter(criteria);\n }\n\n return this.entries_;\n };\n\n /**\n * @param {LogCriteria} [criteria]\n */\n Logger.prototype.dump = function (criteria) {\n var entries;\n\n if (!criteria) {\n criteria = this.matchesCriteria_;\n }\n\n entries = this.entries_.filter(criteria, this);\n\n this.outputHandlers_.forEach(function (handler) {\n handler.dump(entries);\n });\n };\n\n /**\n * @protected\n * @param {LogEntry} entry\n */\n Logger.prototype.processOutput_ = function (entry) {\n this.outputHandlers_.forEach(function (handler) {\n handler.show(entry);\n });\n };\n\n /**\n * @protected\n * @param {LogEntry} entry\n * @returns {Boolean}\n */\n Logger.prototype.matchesCriteria_ = function (entry) {\n return this.displayCriteria_.every(function (criteria) {\n return criteria.call(this, entry);\n }, this);\n };\n\n /**\n * Checks that the level of provided entry passes the \"displayLevel_\" threshold.\n *\n * @protected\n * @param {LogEntry} entry - Entry to be checked.\n * @returns {Boolean}\n */\n Logger.prototype.matchesLevel_ = function (entry) {\n return entry.level <= this.displayLevel_;\n };\n\n return Logger;\n});\n","Magento_Ui/js/lib/logger/console-logger.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n './logger',\n './entry-factory',\n './console-output-handler',\n './formatter',\n './message-pool',\n './levels-pool',\n 'Magento_Ui/js/lib/core/storage/local',\n 'underscore',\n './logger-utils'\n], function (Logger, entryFactory, ConsoleHandler, Formatter, messagePoll, levelsPoll, storage, _, LoggerUtils) {\n 'use strict';\n\n var STORAGE_NAMESPACE = 'CONSOLE_LOGGER';\n\n /**\n * Singleton Logger's sub-class instance of which is configured to display its\n * messages to the console. It also provides the support of predefined messages\n * and persists its display level.\n */\n function ConsoleLogger() {\n var formatter = new Formatter(),\n consoleHandler = new ConsoleHandler(formatter),\n savedLevel = storage.get(STORAGE_NAMESPACE),\n utils = new LoggerUtils(this);\n\n Logger.call(this, consoleHandler, entryFactory);\n\n if (savedLevel) {\n this.displayLevel_ = savedLevel;\n }\n\n this.utils = utils;\n this.messages = messagePoll;\n this.levels = levelsPoll.getLevels();\n }\n\n _.extend(ConsoleLogger, Logger);\n\n ConsoleLogger.prototype = Object.create(Logger.prototype);\n ConsoleLogger.prototype.constructor = ConsoleLogger;\n\n /**\n * Overrides parent method to save the provided display level.\n *\n * @override\n */\n ConsoleLogger.prototype.setDisplayLevel = function (level) {\n Logger.prototype.setDisplayLevel.call(this, level);\n\n storage.set(STORAGE_NAMESPACE, level);\n };\n\n /**\n * Adds the support of predefined messages.\n *\n * @protected\n * @override\n */\n ConsoleLogger.prototype.createEntry_ = function (message, level, data) {\n var code;\n\n if (messagePoll.hasMessage(message)) {\n data = data || {};\n code = message;\n message = messagePoll.getMessage(code);\n\n data.messageCode = code;\n }\n\n return Logger.prototype.createEntry_.call(this, message, level, data);\n };\n\n return new ConsoleLogger();\n});\n","Magento_Ui/js/lib/logger/entry.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n './levels-pool'\n], function (logLevels) {\n 'use strict';\n\n /**\n * @param {String} message\n * @param {Number} level\n * @param {Object} [data]\n */\n function LogEntry(message, level, data) {\n /**\n * @readonly\n * @type {Number}\n */\n this.timestamp = Date.now();\n\n /**\n * @readonly\n * @type {Number}\n */\n this.level = level;\n\n /**\n * @readonly\n * @type {String}\n */\n this.levelName = logLevels.getNameByCode(level);\n\n /**\n * @readonly\n * @type {Object}\n */\n this.data = data;\n\n /**\n * @readonly\n * @type {String}\n */\n this.message = message;\n }\n\n return LogEntry;\n});\n","Magento_Ui/js/lib/logger/levels-pool.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'underscore'\n], function (_) {\n 'use strict';\n\n var LEVELS,\n CODE_MAP;\n\n LEVELS = {\n NONE: 0,\n ERROR: 1,\n WARN: 2,\n INFO: 3,\n DEBUG: 4,\n ALL: 5\n };\n\n CODE_MAP = _.invert(LEVELS);\n\n return {\n /**\n * Returns the list of available log levels.\n *\n * @returns {Object}\n */\n getLevels: function () {\n return LEVELS;\n },\n\n /**\n * Returns name of the log level that matches to the provided code.\n *\n * @returns {String}\n */\n getNameByCode: function (code) {\n return CODE_MAP[code];\n }\n };\n});\n","Magento_Ui/js/lib/logger/formatter.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'moment',\n 'mage/utils/template'\n], function (moment, mageTemplate) {\n 'use strict';\n\n /**\n * @param {String} dateFormat\n * @param {String} template\n */\n function LogFormatter(dateFormat, template) {\n /**\n * @protected\n * @type {String}\n */\n this.dateFormat_ = 'YYYY-MM-DD hh:mm:ss';\n\n /**\n * @protected\n * @type {String}\n */\n this.template_ = '[${ $.date }] [${ $.entry.levelName }] ${ $.message }';\n\n if (dateFormat) {\n this.dateFormat_ = dateFormat;\n }\n\n if (template) {\n this.template_ = template;\n }\n }\n\n /**\n * @param {LogEntry} entry\n * @returns {String}\n */\n LogFormatter.prototype.process = function (entry) {\n var message = mageTemplate.template(entry.message, entry.data),\n date = moment(entry.timestamp).format(this.dateFormat_);\n\n return mageTemplate.template(this.template_, {\n date: date,\n entry: entry,\n message: message\n });\n };\n\n return LogFormatter;\n});\n","Magento_Ui/js/lib/logger/entry-factory.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n './entry'\n], function (LogEntry) {\n 'use strict';\n\n return {\n /**\n * @param {String} message\n * @param {Number} level\n * @param {Object} [messageData]\n * @returns {LogEntry}\n */\n createEntry: function (message, level, messageData) {\n return new LogEntry(message, level, messageData);\n }\n };\n});\n","Magento_Ui/js/lib/logger/message-pool.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine(function () {\n 'use strict';\n\n var MESSAGES = {\n templateStartLoading:\n 'The \"${ $.template }\" template requested by the \"${$.component}\" component started loading.',\n templateLoadedFromServer:\n 'The \"${ $.template }\" template requested by the \"${$.component}\" component was loaded from server.\"',\n templateLoadedFromCache:\n 'The \"${ $.template }\" template requested by the \"${$.component}\" component was loaded from cache.\"',\n templateLoadingFail: 'Failed to load the \"${ $.template }\" template requested by \"${$.component}\".',\n componentStartInitialization:\n 'Component \"${$.component}\" start initialization with instance name \"${$.componentName}\".',\n componentStartLoading: ' Started loading the \"${$.component}\" component.',\n componentFinishLoading: 'The \"${$.component}\" component was loaded.',\n componentLoadingFail: 'Failed to load the \"${$.component}\" component.',\n depsLoadingFail: 'Could not get the declared \"${$.deps}\" dependency for the \"${$.component}\" instance.',\n depsStartRequesting: 'Requesting the \"${$.deps}\" dependency for the \"${$.component}\" instance.',\n depsFinishRequesting: 'The \"${$.deps}\" dependency for the \"${$.component}\" instance was received.',\n requestingComponent: 'Requesting the \"${$.component}\" component.',\n requestingComponentIsLoaded: 'The requested \"${$.component}\" component was received.',\n requestingComponentIsFailed: 'Could not get the requested \"${$.component}\" component.'\n };\n\n return {\n /**\n * Returns message that matches the provided code.\n *\n * @param {String} code - Message's identifier\n * @returns {String}\n */\n getMessage: function (code) {\n return MESSAGES[code];\n },\n\n /**\n * Adds a new message to the poll.\n *\n * @param {String} code - Message's identifier.\n * @param {String} message - Text of the message\n */\n addMessage: function (code, message) {\n MESSAGES[code] = message;\n },\n\n /**\n * Tells whether message with provide code exists in the poll.\n *\n * @param {String} code - Message's identifier.\n * @returns {Boolean}\n */\n hasMessage: function (code) {\n return MESSAGES.hasOwnProperty(code);\n }\n };\n});\n","Magento_Ui/js/lib/logger/logger-utils.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([], function () {\n 'use strict';\n\n /**\n * Utils methods for logger\n * @param {Logger} logger\n */\n function LogUtils(logger) {\n this.logger = logger;\n\n }\n\n /**\n * Method for logging asynchronous operations\n * @param {Promise} promise\n * @param {Object} config\n */\n LogUtils.prototype.asyncLog = function (promise, config) {\n var levels,\n messages,\n wait;\n\n config = config || {};\n levels = config.levels || this.createLevels();\n messages = config.messages || this.createMessages();\n wait = config.wait || 5000;\n\n this.logger[levels.requested](messages.requested, config.data);\n setTimeout(function () {\n promise.state() === 'pending' ?\n this.logger[levels.failed](messages.failed, config.data) :\n this.logger[levels.loaded](messages.loaded, config.data);\n }.bind(this), wait);\n };\n\n /**\n * Method that creates object of messages\n * @param {String} requested - log message that showing that request for class is started\n * @param {String} loaded - log message that show when requested class is loaded\n * @param {String} failed - log message that show when requested class is failed\n * @returns {Object}\n */\n LogUtils.prototype.createMessages = function (requested, loaded, failed) {\n return {\n requested: requested || '',\n loaded: loaded || '',\n failed: failed || ''\n };\n };\n\n /**\n * Method that creates object of log levels\n * @param {String} requested - log message that showing that request for class is started\n * @param {String} loaded - log message that show when requested class is loaded\n * @param {String} failed - log message that show when requested class is failed\n * @returns {Object}\n */\n LogUtils.prototype.createLevels = function (requested, loaded, failed) {\n return {\n requested: requested || 'info',\n loaded: loaded || 'info',\n failed: failed || 'warn'\n };\n };\n\n return LogUtils;\n});\n","Magento_Ui/js/lib/core/events.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'ko',\n 'underscore'\n], function (ko, _) {\n 'use strict';\n\n var eventsMap = new WeakMap();\n\n /**\n * Returns events map or a specific event\n * data associated with a provided object.\n *\n * @param {Object} obj - Key in the events weakmap.\n * @param {String} [name] - Name of the event.\n * @returns {Map|Array|Boolean}\n */\n function getEvents(obj, name) {\n var events = eventsMap.get(obj);\n\n if (!events) {\n return false;\n }\n\n return name ? events.get(name) : events;\n }\n\n /**\n * Adds new event handler.\n *\n * @param {Object} obj - Key in the events weakmap.\n * @param {String} ns - Callback namespace.\n * @param {Function} callback - Event callback.\n * @param {String} name - Name of the event.\n */\n function addHandler(obj, ns, callback, name) {\n var events = getEvents(obj),\n observable,\n data;\n\n observable = !ko.isObservable(obj[name]) ?\n ko.getObservable(obj, name) :\n obj[name];\n\n if (observable) {\n observable.subscribe(callback);\n\n return;\n }\n\n if (!events) {\n events = new Map();\n\n eventsMap.set(obj, events);\n }\n\n data = {\n callback: callback,\n ns: ns\n };\n\n events.has(name) ?\n events.get(name).push(data) :\n events.set(name, [data]);\n }\n\n /**\n * Invokes provided callbacks with a specified arguments.\n *\n * @param {Array} handlers\n * @param {Array} args\n * @returns {Boolean}\n */\n function trigger(handlers, args) {\n var bubble = true,\n callback;\n\n handlers.forEach(function (handler) {\n callback = handler.callback;\n\n if (callback.apply(null, args) === false) {\n bubble = false;\n }\n });\n\n return bubble;\n }\n\n return {\n\n /**\n * Calls callback when name event is triggered.\n * @param {String} events\n * @param {Function} callback\n * @param {Function} ns\n * @return {Object} reference to this\n */\n on: function (events, callback, ns) {\n var iterator;\n\n if (arguments.length < 2) {\n ns = callback;\n }\n\n iterator = addHandler.bind(null, this, ns);\n\n _.isObject(events) ?\n _.each(events, iterator) :\n iterator(callback, events);\n\n return this;\n },\n\n /**\n * Removed callback from listening to target event\n * @param {String} ns\n * @return {Object} reference to this\n */\n off: function (ns) {\n var storage = getEvents(this);\n\n if (!storage) {\n return this;\n }\n\n storage.forEach(function (handlers, name) {\n handlers = handlers.filter(function (handler) {\n return !ns ? false : handler.ns !== ns;\n });\n\n handlers.length ?\n storage.set(name, handlers) :\n storage.delete(name);\n });\n\n return this;\n },\n\n /**\n * Triggers event and executes all attached callbacks.\n *\n * @param {String} name - Name of the event to be triggered.\n * @returns {Boolean}\n */\n trigger: function (name) {\n var handlers,\n args;\n\n handlers = getEvents(this, name),\n args = _.toArray(arguments).slice(1);\n\n if (!handlers || !name) {\n return true;\n }\n\n return trigger(handlers, args);\n }\n };\n});\n","Magento_Ui/js/lib/core/class.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n 'underscore',\n 'mageUtils',\n 'mage/utils/wrapper'\n], function (_, utils, wrapper) {\n 'use strict';\n\n var Class;\n\n /**\n * Returns property of an object if\n * it's his own property.\n *\n * @param {Object} obj - Object whose property should be retrieved.\n * @param {String} prop - Name of the property.\n * @returns {*} Value of the property or false.\n */\n function getOwn(obj, prop) {\n return _.isObject(obj) && obj.hasOwnProperty(prop) && obj[prop];\n }\n\n /**\n * Creates constructor function which allows\n * initialization without usage of a 'new' operator.\n *\n * @param {Object} protoProps - Prototypal properties of a new constructor.\n * @param {Function} constructor\n * @returns {Function} Created constructor.\n */\n function createConstructor(protoProps, constructor) {\n var UiClass = constructor;\n\n if (!UiClass) {\n\n /**\n * Default constructor function.\n */\n UiClass = function () {\n var obj = this;\n\n if (!_.isObject(obj) || Object.getPrototypeOf(obj) !== UiClass.prototype) {\n obj = Object.create(UiClass.prototype);\n }\n\n obj.initialize.apply(obj, arguments);\n\n return obj;\n };\n }\n\n UiClass.prototype = protoProps;\n UiClass.prototype.constructor = UiClass;\n\n return UiClass;\n }\n\n Class = createConstructor({\n\n /**\n * Entry point to the initialization of constructor's instance.\n *\n * @param {Object} [options={}]\n * @returns {Class} Chainable.\n */\n initialize: function (options) {\n this.initConfig(options);\n\n return this;\n },\n\n /**\n * Recursively extends data specified in constructors' 'defaults'\n * property with provided options object. Evaluates resulting\n * object using string templates (see: mage/utils/template.js).\n *\n * @param {Object} [options={}]\n * @returns {Class} Chainable.\n */\n initConfig: function (options) {\n var defaults = this.constructor.defaults,\n config = utils.extend({}, defaults, options || {}),\n ignored = config.ignoreTmpls || {},\n cached = utils.omit(config, ignored);\n\n config = utils.template(config, this, false, true);\n\n _.each(cached, function (value, key) {\n utils.nested(config, key, value);\n });\n\n return _.extend(this, config);\n }\n });\n\n _.extend(Class, {\n defaults: {\n ignoreTmpls: {\n templates: true\n }\n },\n\n /**\n * Creates new constructor based on a current prototype properties,\n * extending them with properties specified in 'exender' object.\n *\n * @param {Object} [extender={}]\n * @returns {Function} New constructor.\n */\n extend: function (extender) {\n var parent = this,\n parentProto = parent.prototype,\n childProto = Object.create(parentProto),\n child = createConstructor(childProto, getOwn(extender, 'constructor')),\n defaults;\n\n extender = extender || {};\n defaults = extender.defaults;\n\n delete extender.defaults;\n\n _.each(extender, function (method, name) {\n childProto[name] = wrapper.wrapSuper(parentProto[name], method);\n });\n\n child.defaults = utils.extend({}, parent.defaults || {});\n\n if (defaults) {\n utils.extend(child.defaults, defaults);\n extender.defaults = defaults;\n }\n\n return _.extend(child, {\n __super__: parentProto,\n extend: parent.extend\n });\n }\n });\n\n return Class;\n});\n","Magento_Ui/js/lib/core/collection.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n 'underscore',\n 'mageUtils',\n 'uiRegistry',\n 'uiElement'\n], function (_, utils, registry, Element) {\n 'use strict';\n\n /**\n * Removes non plain object items from the specified array.\n *\n * @param {Array} container - Array whose value should be filtered.\n * @returns {Array}\n */\n function compact(container) {\n return _.values(container).filter(utils.isObject);\n }\n\n /**\n * Defines index of an item in a specified container.\n *\n * @param {*} item - Item whose index should be defined.\n * @param {Array} container - Container upon which to perform search.\n * @returns {Number}\n */\n function _findIndex(item, container) {\n var index = _.findKey(container, function (value) {\n return value === item;\n });\n\n if (typeof index === 'undefined') {\n index = _.findKey(container, function (value) {\n return value && value.name === item;\n });\n }\n\n return typeof index === 'undefined' ? -1 : index;\n }\n\n /**\n * Inserts specified item into container at a specified position.\n *\n * @param {*} item - Item to be inserted into container.\n * @param {Array} container - Container of items.\n * @param {*} [position=-1] - Position at which item should be inserted.\n * Position can represent:\n * - specific index in container\n * - item which might already be present in container\n * - structure with one of these properties: after, before\n * @returns {Boolean|*}\n * - true if element has changed its' position\n * - false if nothing has changed\n * - inserted value if it wasn't present in container\n */\n function _insertAt(item, container, position) {\n var currentIndex = _findIndex(item, container),\n newIndex,\n target;\n\n if (typeof position === 'undefined') {\n position = -1;\n } else if (typeof position === 'string') {\n position = isNaN(+position) ? position : +position;\n }\n\n newIndex = position;\n\n if (~currentIndex) {\n target = container.splice(currentIndex, 1)[0];\n\n if (typeof item === 'string') {\n item = target;\n }\n }\n\n if (typeof position !== 'number') {\n target = position.after || position.before || position;\n\n newIndex = _findIndex(target, container);\n\n if (~newIndex && (position.after || newIndex >= currentIndex)) {\n newIndex++;\n }\n }\n\n if (newIndex < 0) {\n newIndex += container.length + 1;\n }\n\n container[newIndex] ?\n container.splice(newIndex, 0, item) :\n container[newIndex] = item;\n\n return !~currentIndex ? item : currentIndex !== newIndex;\n }\n\n return Element.extend({\n defaults: {\n template: 'ui/collection',\n _elems: [],\n ignoreTmpls: {\n childDefaults: true\n }\n },\n\n /**\n * Initializes observable properties.\n *\n * @returns {Model} Chainable.\n */\n initObservable: function () {\n this._super()\n .observe({\n elems: []\n });\n\n return this;\n },\n\n /**\n * Called when another element was added to current component.\n *\n * @param {Object} elem - Instance of an element that was added.\n * @returns {Collection} Chainable.\n */\n initElement: function (elem) {\n elem.initContainer(this);\n\n return this;\n },\n\n /**\n * Returns instance of a child found by provided index.\n *\n * @param {String} index - Index of a child.\n * @returns {Object}\n */\n getChild: function (index) {\n return _.findWhere(this.elems(), {\n index: index\n });\n },\n\n /**\n * Requests specified components to insert\n * them into 'elems' array starting from provided position.\n *\n * @param {(String|Array)} elems - Name of the component to insert.\n * @param {Number} [position=-1] - Position at which to insert elements.\n * @returns {Collection} Chainable.\n */\n insertChild: function (elems, position) {\n var container = this._elems,\n insert = this._insert.bind(this),\n update;\n\n if (!Array.isArray(elems)) {\n elems = [elems];\n }\n\n elems.map(function (item) {\n return item.elem ?\n _insertAt(item.elem, container, item.position) :\n _insertAt(item, container, position);\n }).forEach(function (item) {\n if (item === true) {\n update = true;\n } else if (_.isString(item)) {\n registry.get(item, insert);\n } else if (utils.isObject(item)) {\n insert(item);\n }\n });\n\n if (update) {\n this._updateCollection();\n }\n\n return this;\n },\n\n /**\n * Removes specified child from collection.\n *\n * @param {(Object|String)} elem - Child or index of a child to be removed.\n * @param {Boolean} skipUpdate - skip collection update when element to be destroyed.\n *\n * @returns {Collection} Chainable.\n */\n removeChild: function (elem, skipUpdate) {\n if (_.isString(elem)) {\n elem = this.getChild(elem);\n }\n\n if (elem) {\n utils.remove(this._elems, elem);\n\n if (!skipUpdate) {\n this._updateCollection();\n }\n }\n\n return this;\n },\n\n /**\n * Destroys collection children with its' elements.\n */\n destroyChildren: function () {\n this.elems.each(function (elem) {\n elem.destroy(true);\n });\n\n this._updateCollection();\n },\n\n /**\n * Clear data. Call method \"clear\"\n * in child components\n *\n * @returns {Object} Chainable.\n */\n clear: function () {\n var elems = this.elems();\n\n _.each(elems, function (elem) {\n if (_.isFunction(elem.clear)) {\n elem.clear();\n }\n }, this);\n\n return this;\n },\n\n /**\n * Checks if specified child exists in collection.\n *\n * @param {String} index - Index of a child.\n * @returns {Boolean}\n */\n hasChild: function (index) {\n return !!this.getChild(index);\n },\n\n /**\n * Creates 'async' wrapper for the specified child\n * using uiRegistry 'async' method and caches it\n * in a '_requested' components object.\n *\n * @param {String} index - Index of a child.\n * @returns {Function} Async module wrapper.\n */\n requestChild: function (index) {\n var name = this.formChildName(index);\n\n return this.requestModule(name);\n },\n\n /**\n * Creates complete child name based on a provided index.\n *\n * @param {String} index - Index of a child.\n * @returns {String}\n */\n formChildName: function (index) {\n return this.name + '.' + index;\n },\n\n /**\n * Retrieves requested region.\n * Creates region if it was not created yet\n *\n * @returns {ObservableArray}\n */\n getRegion: function (name) {\n var regions = this.regions = this.regions || {};\n\n if (!regions[name]) {\n regions[name] = [];\n\n this.observe.call(regions, name);\n }\n\n return regions[name];\n },\n\n /**\n * Checks if the specified region has any elements\n * associated with it.\n *\n * @param {String} name\n * @returns {Boolean}\n */\n regionHasElements: function (name) {\n var region = this.getRegion(name);\n\n return region().length > 0;\n },\n\n /**\n * Replaces specified regions' data with a provided one.\n * Creates region if it was not created yet.\n *\n * @param {Array} items - New regions' data.\n * @param {String} name - Name of the region.\n * @returns {Collection} Chainable.\n */\n updateRegion: function (items, name) {\n this.getRegion(name)(items);\n\n return this;\n },\n\n /**\n * Destroys collection along with its' elements.\n */\n destroy: function () {\n this._super();\n\n this.elems.each('destroy');\n },\n\n /**\n * Inserts provided component into 'elems' array at a specified position.\n * @private\n *\n * @param {Object} elem - Element to insert.\n */\n _insert: function (elem) {\n var index = _.findKey(this._elems, function (value) {\n return value === elem.name;\n });\n\n if (typeof index !== 'undefined') {\n this._elems[index] = elem;\n }\n\n this._updateCollection()\n .initElement(elem);\n },\n\n /**\n * Synchronizes multiple elements arrays with a core '_elems' container.\n * Performs elemets grouping by theirs 'displayArea' property.\n * @private\n *\n * @returns {Collection} Chainable.\n */\n _updateCollection: function () {\n var _elems = compact(this._elems),\n grouped;\n\n grouped = _elems.filter(function (elem) {\n return elem.displayArea && _.isString(elem.displayArea);\n });\n grouped = _.groupBy(grouped, 'displayArea');\n\n _.each(grouped, this.updateRegion, this);\n\n _.each(this.regions, function (items) {\n var hasObsoleteComponents = items().length && !_.intersection(_elems, items()).length;\n\n if (hasObsoleteComponents) {\n items.removeAll();\n }\n });\n\n this.elems(_elems);\n\n return this;\n },\n\n /**\n * Tries to call specified method of a current component,\n * otherwise delegates attempt to its' children.\n *\n * @param {String} target - Name of the method.\n * @param {...*} parameters - Arguments that will be passed to method.\n * @returns {*} Result of the method calls.\n */\n delegate: function (target) {\n var args = _.toArray(arguments);\n\n target = this[target];\n\n if (_.isFunction(target)) {\n return target.apply(this, args.slice(1));\n }\n\n return this._delegate(args);\n },\n\n /**\n * Calls 'delegate' method of all of it's children components.\n * @private\n *\n * @param {Array} args - An array of arguments to pass to the next delegation call.\n * @returns {Array} An array of delegation results.\n */\n _delegate: function (args) {\n var result;\n\n result = this.elems.map(function (elem) {\n var target;\n\n if (!_.isFunction(elem.delegate)) {\n target = elem[args[0]];\n\n if (_.isFunction(target)) {\n return target.apply(elem, args.slice(1));\n }\n } else {\n return elem.delegate.apply(elem, args);\n }\n });\n\n return _.flatten(result);\n }\n });\n});\n","Magento_Ui/js/lib/core/storage/local.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n 'underscore',\n 'uiRegistry',\n 'mageUtils',\n 'uiEvents'\n], function (_, registry, utils, EventsBus) {\n 'use strict';\n\n var root = 'appData',\n localStorage,\n hasSupport,\n storage;\n\n /**\n * Flag which indicates whether localStorage is supported.\n */\n hasSupport = (function () {\n var key = '_storageSupported';\n\n try {\n localStorage = window.localStorage;\n localStorage.setItem(key, 'true');\n\n if (localStorage.getItem(key) === 'true') {\n localStorage.removeItem(key);\n\n return true;\n }\n\n return false;\n } catch (e) {\n return false;\n }\n })();\n\n if (!hasSupport) {\n localStorage = {\n _data: {},\n\n /**\n * Sets value of the specified item.\n *\n * @param {String} key - Key of the property.\n * @param {*} value - Properties' value.\n */\n setItem: function (key, value) {\n this._data[key] = value + '';\n },\n\n /**\n * Retrieves specified item.\n *\n * @param {String} key - Key of the property to be retrieved.\n */\n getItem: function (key) {\n return this._data[key];\n },\n\n /**\n * Removes specified item.\n *\n * @param {String} key - Key of the property to be removed.\n */\n removeItem: function (key) {\n delete this._data[key];\n },\n\n /**\n * Removes all items.\n */\n clear: function () {\n this._data = {};\n }\n };\n }\n\n /**\n * Extracts and parses data stored in localStorage by the\n * key specified in 'root' variable.\n *\n * @returns {Object}\n */\n function getRoot() {\n var data = localStorage.getItem(root),\n result = {};\n\n if (!_.isNull(data) && typeof data != 'undefined') {\n result = JSON.parse(data);\n }\n\n return result;\n }\n\n /**\n * Writes provided data to the localStorage.\n *\n * @param {*} data - Data to be stored.\n */\n function setRoot(data) {\n localStorage.setItem(root, JSON.stringify(data));\n }\n\n /**\n * Provides methods to work with a localStorage\n * as a single nested structure.\n */\n storage = _.extend({\n\n /**\n * Retrieves value of the specified property.\n *\n * @param {String} path - Path to the property.\n *\n * @example Retrieving data.\n * localStorage =>\n * 'appData' => '\n * \"one\": {\"two\": \"three\"}\n * '\n * storage.get('one.two')\n * => \"three\"\n *\n * storage.get('one')\n * => {\"two\": \"three\"}\n */\n get: function (path) {\n var data = getRoot();\n\n return utils.nested(data, path);\n },\n\n /**\n * Sets specified data to the localStorage.\n *\n * @param {String} path - Path of the property.\n * @param {*} value - Value of the property.\n *\n * @example Setting data.\n * storage.set('one.two', 'four');\n * => localStorage =>\n * 'appData' => '\n * \"one\": {\"two\": \"four\"}\n * '\n */\n set: function (path, value) {\n var data = getRoot();\n\n utils.nested(data, path, value);\n\n setRoot(data);\n },\n\n /**\n * Removes specified data from the localStorage.\n *\n * @param {String} path - Path to the property that should be removed.\n *\n * @example Removing data.\n * storage.remove('one.two', 'four');\n * => localStorage =>\n * 'appData' => '\n * \"one\": {}\n * '\n */\n remove: function (path) {\n var data = getRoot();\n\n utils.nestedRemove(data, path);\n\n setRoot(data);\n }\n }, EventsBus);\n\n registry.set('localStorage', storage);\n\n return storage;\n});\n","Magento_Ui/js/lib/core/element/element.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n 'ko',\n 'underscore',\n 'mageUtils',\n 'uiRegistry',\n 'uiEvents',\n 'uiClass',\n './links',\n '../storage/local'\n], function (ko, _, utils, registry, Events, Class, links) {\n 'use strict';\n\n var Element;\n\n /**\n * Creates observable property using knockouts'\n * 'observableArray' or 'observable' methods,\n * depending on a type of 'value' parameter.\n *\n * @param {Object} obj - Object to whom property belongs.\n * @param {String} key - Key of the property.\n * @param {*} value - Initial value.\n */\n function observable(obj, key, value) {\n var method = Array.isArray(value) ? 'observableArray' : 'observable';\n\n if (_.isFunction(obj[key]) && !ko.isObservable(obj[key])) {\n return;\n }\n\n if (ko.isObservable(value)) {\n value = value();\n }\n\n ko.isObservable(obj[key]) ?\n obj[key](value) :\n obj[key] = ko[method](value);\n }\n\n /**\n * Creates observable property using 'track' method.\n *\n * @param {Object} obj - Object to whom property belongs.\n * @param {String} key - Key of the property.\n * @param {*} value - Initial value.\n */\n function accessor(obj, key, value) {\n if (_.isFunction(obj[key]) || ko.isObservable(obj[key])) {\n return;\n }\n\n obj[key] = value;\n\n if (!ko.es5.isTracked(obj, key)) {\n ko.track(obj, [key]);\n }\n }\n\n Element = _.extend({\n defaults: {\n _requested: {},\n containers: [],\n exports: {},\n imports: {},\n links: {},\n listens: {},\n name: '',\n ns: '${ $.name.split(\".\")[0] }',\n provider: '',\n registerNodes: true,\n source: null,\n statefull: {},\n template: '',\n tracks: {},\n storageConfig: {\n provider: 'localStorage',\n namespace: '${ $.name }',\n path: '${ $.storageConfig.provider }:${ $.storageConfig.namespace }'\n },\n maps: {\n imports: {},\n exports: {}\n },\n modules: {\n storage: '${ $.storageConfig.provider }'\n }\n },\n\n /**\n * Initializes model instance.\n *\n * @returns {Element} Chainable.\n */\n initialize: function () {\n this._super()\n .initObservable()\n .initModules()\n .initStatefull()\n .initLinks()\n .initUnique();\n\n return this;\n },\n\n /**\n * Initializes observable properties.\n *\n * @returns {Element} Chainable.\n */\n initObservable: function () {\n _.each(this.tracks, function (enabled, key) {\n if (enabled) {\n this.track(key);\n }\n }, this);\n\n return this;\n },\n\n /**\n * Parses 'modules' object and creates\n * async wrappers for specified components.\n *\n * @returns {Element} Chainable.\n */\n initModules: function () {\n _.each(this.modules, function (name, property) {\n if (name) {\n this[property] = this.requestModule(name);\n }\n }, this);\n\n if (!_.isFunction(this.source)) {\n this.source = registry.get(this.provider);\n }\n\n return this;\n },\n\n /**\n * Called when current element was injected to another component.\n *\n * @param {Object} parent - Instance of a 'parent' component.\n * @returns {Collection} Chainable.\n */\n initContainer: function (parent) {\n this.containers.push(parent);\n\n return this;\n },\n\n /**\n * Initializes statefull properties\n * based on the keys of 'statefull' object.\n *\n * @returns {Element} Chainable.\n */\n initStatefull: function () {\n _.each(this.statefull, function (path, key) {\n if (path) {\n this.setStatefull(key, path);\n }\n }, this);\n\n return this;\n },\n\n /**\n * Initializes links between properties.\n *\n * @returns {Element} Chainbale.\n */\n initLinks: function () {\n return this.setListeners(this.listens)\n .setLinks(this.links, 'imports')\n .setLinks(this.links, 'exports')\n .setLinks(this.exports, 'exports')\n .setLinks(this.imports, 'imports');\n },\n\n /**\n * Initializes listeners of the unique property.\n *\n * @returns {Element} Chainable.\n */\n initUnique: function () {\n var update = this.onUniqueUpdate.bind(this),\n uniqueNs = this.uniqueNs;\n\n this.hasUnique = this.uniqueProp && uniqueNs;\n\n if (this.hasUnique) {\n this.source.on(uniqueNs, update, this.name);\n }\n\n return this;\n },\n\n /**\n * Makes specified property to be stored automatically.\n *\n * @param {String} key - Name of the property\n * that will be stored.\n * @param {String} [path=key] - Path to the property in storage.\n * @returns {Element} Chainable.\n */\n setStatefull: function (key, path) {\n var link = {};\n\n path = !_.isString(path) || !path ? key : path;\n link[key] = this.storageConfig.path + '.' + path;\n\n this.setLinks(link, 'imports')\n .setLinks(link, 'exports');\n\n return this;\n },\n\n /**\n * Updates property specified in uniqueNs\n * if elements' unique property is set to 'true'.\n *\n * @returns {Element} Chainable.\n */\n setUnique: function () {\n var property = this.uniqueProp;\n\n if (this[property]()) {\n this.source.set(this.uniqueNs, this.name);\n }\n\n return this;\n },\n\n /**\n * Creates 'async' wrapper for the specified component\n * using uiRegistry 'async' method and caches it\n * in a '_requested' components object.\n *\n * @param {String} name - Name of requested component.\n * @returns {Function} Async module wrapper.\n */\n requestModule: function (name) {\n var requested = this._requested;\n\n if (!requested[name]) {\n requested[name] = registry.async(name);\n }\n\n return requested[name];\n },\n\n /**\n * Returns path to elements' template.\n *\n * @returns {String}\n */\n getTemplate: function () {\n return this.template;\n },\n\n /**\n * Checks if template was specified for an element.\n *\n * @returns {Boolean}\n */\n hasTemplate: function () {\n return !!this.template;\n },\n\n /**\n * Returns value of the nested property.\n *\n * @param {String} path - Path to the property.\n * @returns {*} Value of the property.\n */\n get: function (path) {\n return utils.nested(this, path);\n },\n\n /**\n * Sets provided value as a value of the specified nested property.\n * Triggers changes notifications, if value has mutated.\n *\n * @param {String} path - Path to property.\n * @param {*} value - New value of the property.\n * @returns {Element} Chainable.\n */\n set: function (path, value) {\n var data = this.get(path),\n diffs;\n\n diffs = !_.isFunction(data) && !this.isTracked(path) ?\n utils.compare(data, value, path) :\n false;\n\n utils.nested(this, path, value);\n\n if (diffs) {\n this._notifyChanges(diffs);\n }\n\n return this;\n },\n\n /**\n * Removes nested property from the object.\n *\n * @param {String} path - Path to the property.\n * @returns {Element} Chainable.\n */\n remove: function (path) {\n var data = utils.nested(this, path),\n diffs;\n\n if (_.isUndefined(data) || _.isFunction(data)) {\n return this;\n }\n\n diffs = utils.compare(data, undefined, path);\n\n utils.nestedRemove(this, path);\n\n this._notifyChanges(diffs);\n\n return this;\n },\n\n /**\n * Creates observable properties for the current object.\n *\n * If 'useTrack' flag is set to 'true' then each property will be\n * created with a ES5 get/set accessor descriptors, instead of\n * making them an observable functions.\n * See 'knockout-es5' library for more information.\n *\n * @param {Boolean} [useAccessors=false] - Whether to create an\n * observable function or to use property accesessors.\n * @param {(Object|String|Array)} properties - List of observable properties.\n * @returns {Element} Chainable.\n *\n * @example Sample declaration and equivalent knockout methods.\n * this.key = 'value';\n * this.array = ['value'];\n *\n * this.observe(['key', 'array']);\n * =>\n * this.key = ko.observable('value');\n * this.array = ko.observableArray(['value']);\n *\n * @example Another syntaxes of the previous example.\n * this.observe({\n * key: 'value',\n * array: ['value']\n * });\n */\n observe: function (useAccessors, properties) {\n var model = this,\n trackMethod;\n\n if (typeof useAccessors !== 'boolean') {\n properties = useAccessors;\n useAccessors = false;\n }\n\n trackMethod = useAccessors ? accessor : observable;\n\n if (_.isString(properties)) {\n properties = properties.split(' ');\n }\n\n if (Array.isArray(properties)) {\n properties.forEach(function (key) {\n trackMethod(model, key, model[key]);\n });\n } else if (typeof properties === 'object') {\n _.each(properties, function (value, key) {\n trackMethod(model, key, value);\n });\n }\n\n return this;\n },\n\n /**\n * Delegates call to 'observe' method but\n * with a predefined 'useAccessors' flag.\n *\n * @param {(String|Array|Object)} properties - List of observable properties.\n * @returns {Element} Chainable.\n */\n track: function (properties) {\n this.observe(true, properties);\n\n return this;\n },\n\n /**\n * Checks if specified property is tracked.\n *\n * @param {String} property - Property to be checked.\n * @returns {Boolean}\n */\n isTracked: function (property) {\n return ko.es5.isTracked(this, property);\n },\n\n /**\n * Invokes subscribers for the provided changes.\n *\n * @param {Object} diffs - Object with changes descriptions.\n * @returns {Element} Chainable.\n */\n _notifyChanges: function (diffs) {\n diffs.changes.forEach(function (change) {\n this.trigger(change.path, change.value, change);\n }, this);\n\n _.each(diffs.containers, function (changes, name) {\n var value = utils.nested(this, name);\n\n this.trigger(name, value, changes);\n }, this);\n\n return this;\n },\n\n /**\n * Extracts all stored data and sets it to element.\n *\n * @returns {Element} Chainable.\n */\n restore: function () {\n var ns = this.storageConfig.namespace,\n storage = this.storage();\n\n if (storage) {\n utils.extend(this, storage.get(ns));\n }\n\n return this;\n },\n\n /**\n * Stores value of the specified property in components' storage module.\n *\n * @param {String} property\n * @param {*} [data=this[property]]\n * @returns {Element} Chainable.\n */\n store: function (property, data) {\n var ns = this.storageConfig.namespace,\n path = utils.fullPath(ns, property);\n\n if (arguments.length < 2) {\n data = this.get(property);\n }\n\n this.storage('set', path, data);\n\n return this;\n },\n\n /**\n * Extracts specified property from storage.\n *\n * @param {String} [property] - Name of the property\n * to be extracted. If not specified then all of the\n * stored will be returned.\n * @returns {*}\n */\n getStored: function (property) {\n var ns = this.storageConfig.namespace,\n path = utils.fullPath(ns, property),\n storage = this.storage(),\n data;\n\n if (storage) {\n data = storage.get(path);\n }\n\n return data;\n },\n\n /**\n * Removes stored property.\n *\n * @param {String} property - Property to be removed from storage.\n * @returns {Element} Chainable.\n */\n removeStored: function (property) {\n var ns = this.storageConfig.namespace,\n path = utils.fullPath(ns, property);\n\n this.storage('remove', path);\n\n return this;\n },\n\n /**\n * Destroys current instance along with all of its' children.\n * @param {Boolean} skipUpdate - skip collection update when element to be destroyed.\n */\n destroy: function (skipUpdate) {\n this._dropHandlers()\n ._clearRefs(skipUpdate);\n },\n\n /**\n * Removes events listeners.\n * @private\n *\n * @returns {Element} Chainable.\n */\n _dropHandlers: function () {\n this.off();\n\n if (_.isFunction(this.source)) {\n this.source().off(this.name);\n } else if (this.source) {\n this.source.off(this.name);\n }\n\n return this;\n },\n\n /**\n * Removes all references to current instance and\n * calls 'destroy' method on all of its' children.\n * @private\n * @param {Boolean} skipUpdate - skip collection update when element to be destroyed.\n *\n * @returns {Element} Chainable.\n */\n _clearRefs: function (skipUpdate) {\n registry.remove(this.name);\n\n this.containers.forEach(function (parent) {\n parent.removeChild(this, skipUpdate);\n }, this);\n\n return this;\n },\n\n /**\n * Overrides 'EventsBus.trigger' method to implement events bubbling.\n *\n * @param {...*} arguments - Any number of arguments that should be passed to the events' handler.\n * @returns {Boolean} False if event bubbling was canceled.\n */\n bubble: function () {\n var args = _.toArray(arguments),\n bubble = this.trigger.apply(this, args),\n result;\n\n if (!bubble) {\n return false;\n }\n\n this.containers.forEach(function (parent) {\n result = parent.bubble.apply(parent, args);\n\n if (result === false) {\n bubble = false;\n }\n });\n\n return !!bubble;\n },\n\n /**\n * Callback which fires when property under uniqueNs has changed.\n */\n onUniqueUpdate: function (name) {\n var active = name === this.name,\n property = this.uniqueProp;\n\n this[property](active);\n },\n\n /**\n * Clean data form data source.\n *\n * @returns {Element}\n */\n cleanData: function () {\n if (this.source && this.source.componentType === 'dataSource') {\n if (this.elems) {\n _.each(this.elems(), function (val) {\n val.cleanData();\n });\n } else {\n this.source.remove(this.dataScope);\n }\n }\n\n return this;\n },\n\n /**\n * Fallback data.\n */\n cacheData: function () {\n this.cachedComponent = utils.copy(this);\n },\n\n /**\n * Update configuration in component.\n *\n * @param {*} oldValue\n * @param {*} newValue\n * @param {String} path - path to value.\n * @returns {Element}\n */\n updateConfig: function (oldValue, newValue, path) {\n var names = path.split('.'),\n index = _.lastIndexOf(names, 'config') + 1;\n\n names = names.splice(index, names.length - index).join('.');\n this.set(names, newValue);\n\n return this;\n }\n }, Events, links);\n\n return Class.extend(Element);\n});\n","Magento_Ui/js/lib/core/element/links.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'ko',\n 'underscore',\n 'mageUtils',\n 'uiRegistry'\n], function (ko, _, utils, registry) {\n 'use strict';\n\n /**\n * Parse provided data.\n *\n * @param {String} placeholder\n * @param {String} data\n * @param {String} direction\n * @returns {Boolean|Object}\n */\n function parseData(placeholder, data, direction) {\n if (typeof data !== 'string') {\n return false;\n }\n\n data = data.split(':');\n\n if (!data[0]) {\n return false;\n }\n\n if (!data[1]) {\n data[1] = data[0];\n data[0] = placeholder;\n }\n\n return {\n target: data[0],\n property: data[1],\n direction: direction\n };\n }\n\n /**\n * Check if value not empty.\n *\n * @param {*} value\n * @returns {Boolean}\n */\n function notEmpty(value) {\n return typeof value !== 'undefined' && value != null;\n }\n\n /**\n * Update value for linked component.\n *\n * @param {Object} data\n * @param {Object} owner\n * @param {Object} target\n * @param {*} value\n */\n function updateValue(data, owner, target, value) {\n var component = target.component,\n property = target.property,\n linked = data.linked;\n\n if (data.mute) {\n return;\n }\n\n if (linked) {\n linked.mute = true;\n }\n\n if (owner.component !== target.component) {\n value = data.inversionValue ? !utils.copy(value) : utils.copy(value);\n }\n\n component.set(property, value, owner);\n\n if (property === 'disabled' && value) {\n component.set('validate', value, owner);\n }\n\n if (linked) {\n linked.mute = false;\n }\n }\n\n /**\n * Get value form owner component property.\n *\n * @param {Object} owner\n * @returns {*}\n */\n function getValue(owner) {\n var component = owner.component,\n property = owner.property;\n\n return component.get(property);\n }\n\n /**\n * Format provided params to object.\n *\n * @param {String} ownerComponent\n * @param {String} targetComponent\n * @param {String} ownerProp\n * @param {String} targetProp\n * @param {String} direction\n * @returns {Object}\n */\n function form(ownerComponent, targetComponent, ownerProp, targetProp, direction) {\n var result,\n tmp;\n\n result = {\n owner: {\n component: ownerComponent,\n property: ownerProp\n },\n target: {\n component: targetComponent,\n property: targetProp\n }\n };\n\n if (direction === 'exports') {\n tmp = result.owner;\n result.owner = result.target;\n result.target = tmp;\n }\n\n return result;\n }\n\n /**\n * Set data to linked property.\n *\n * @param {Object} map\n * @param {Object} data\n */\n function setLinked(map, data) {\n var match;\n\n if (!map) {\n return;\n }\n\n match = _.findWhere(map, {\n linked: false,\n target: data.target,\n property: data.property\n });\n\n if (match) {\n match.linked = data;\n data.linked = match;\n }\n }\n\n /**\n * Set data by direction.\n *\n * @param {Object} maps\n * @param {String} property\n * @param {Object} data\n */\n function setData(maps, property, data) {\n var direction = data.direction,\n map = maps[direction];\n\n data.linked = false;\n\n (map[property] = map[property] || []).push(data);\n\n direction = direction === 'imports' ? 'exports' : 'imports';\n\n setLinked(maps[direction][property], data);\n }\n\n /**\n * Set links for components.\n *\n * @param {String} target\n * @param {String} owner\n * @param {Object} data\n * @param {String} property\n * @param {Boolean} immediate\n */\n function setLink(target, owner, data, property, immediate) {\n var direction = data.direction,\n formated = form(target, owner, data.property, property, direction),\n callback,\n value;\n\n owner = formated.owner;\n target = formated.target;\n\n callback = updateValue.bind(null, data, owner, target);\n\n owner.component.on(owner.property, callback, target.component.name);\n\n if (immediate) {\n value = getValue(owner);\n\n if (notEmpty(value)) {\n updateValue(data, owner, target, value);\n }\n }\n }\n\n /**\n * Transfer data between components.\n *\n * @param {Object} owner\n * @param {Object} data\n */\n function transfer(owner, data) {\n var args = _.toArray(arguments);\n\n if (data.target.substr(0, 1) === '!') {\n data.target = data.target.substr(1);\n data.inversionValue = true;\n }\n\n if (owner.name === data.target) {\n args.unshift(owner);\n\n setLink.apply(null, args);\n } else {\n registry.get(data.target, function (target) {\n args.unshift(target);\n\n setLink.apply(null, args);\n });\n }\n }\n\n return {\n /**\n * Assign listeners.\n *\n * @param {Object} listeners\n * @returns {Object} Chainable\n */\n setListeners: function (listeners) {\n var owner = this,\n data;\n\n _.each(listeners, function (callbacks, sources) {\n sources = sources.split(' ');\n callbacks = callbacks.split(' ');\n\n sources.forEach(function (target) {\n callbacks.forEach(function (callback) {//eslint-disable-line max-nested-callbacks\n data = parseData(owner.name, target, 'imports');\n\n if (data) {\n setData(owner.maps, callback, data);\n transfer(owner, data, callback);\n }\n });\n });\n });\n\n return this;\n },\n\n /**\n * Set links in provided direction.\n *\n * @param {Object} links\n * @param {String} direction\n * @returns {Object} Chainable\n */\n setLinks: function (links, direction) {\n var owner = this,\n property,\n data;\n\n for (property in links) {\n if (links.hasOwnProperty(property)) {\n data = parseData(owner.name, links[property], direction);\n\n if (data) {//eslint-disable-line max-depth\n setData(owner.maps, property, data);\n transfer(owner, data, property, true);\n }\n }\n }\n\n return this;\n }\n };\n});\n","Magento_Ui/js/lib/validation/validator.js":"/*\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n 'underscore',\n './rules'\n], function (_, rulesList) {\n 'use strict';\n\n /**\n * Validates provided value be the specified rule.\n *\n * @param {String} id - Rule identifier.\n * @param {*} value - Value to be checked.\n * @param {*} [params]\n * @param {*} additionalParams - additional validation params set by method caller\n * @returns {Object}\n */\n function validate(id, value, params, additionalParams) {\n var rule,\n message,\n valid,\n result = {\n rule: id,\n passed: true,\n message: ''\n };\n\n if (_.isObject(params)) {\n message = params.message || '';\n }\n\n if (!rulesList[id]) {\n return result;\n }\n\n rule = rulesList[id];\n message = message || rule.message;\n valid = rule.handler(value, params, additionalParams);\n\n if (!valid) {\n params = Array.isArray(params) ?\n params :\n [params];\n\n if (typeof message === 'function') {\n message = message.call(rule);\n }\n\n message = params.reduce(function (msg, param, idx) {\n return msg.replace(new RegExp('\\\\{' + idx + '\\\\}', 'g'), param);\n }, message);\n\n result.passed = false;\n result.message = message;\n }\n\n return result;\n }\n\n /**\n * Validates provided value by a specified set of rules.\n *\n * @param {(String|Object)} rules - One or many validation rules.\n * @param {*} value - Value to be checked.\n * @param {*} additionalParams - additional validation params set by method caller\n * @returns {Object}\n */\n function validator(rules, value, additionalParams) {\n var result;\n\n if (typeof rules === 'object') {\n result = {\n passed: true\n };\n\n _.every(rules, function (ruleParams, id) {\n if (ruleParams.validate || ruleParams !== false || additionalParams) {\n result = validate(id, value, ruleParams, additionalParams);\n\n return result.passed;\n }\n\n return true;\n });\n\n return result;\n }\n\n return validate.apply(null, arguments);\n }\n\n /**\n * Adds new validation rule.\n *\n * @param {String} id - Rule identifier.\n * @param {Function} handler - Validation function.\n * @param {String} message - Error message.\n */\n validator.addRule = function (id, handler, message) {\n rulesList[id] = {\n handler: handler,\n message: message\n };\n };\n\n /**\n * Returns rule object found by provided identifier.\n *\n * @param {String} id - Rule identifier.\n * @returns {Object}\n */\n validator.getRule = function (id) {\n return rulesList[id];\n };\n\n return validator;\n});\n","Magento_Ui/js/lib/validation/rules.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n 'jquery',\n 'underscore',\n './utils',\n 'moment',\n 'tinycolor',\n 'jquery/validate',\n 'mage/translate'\n], function ($, _, utils, moment, tinycolor) {\n 'use strict';\n\n /**\n * validate credit card number using mod10\n * @param {String} s\n * @return {Boolean}\n */\n function validateCreditCard(s) {\n // remove non-numerics\n var v = '0123456789',\n w = '',\n i, j, k, m, c, a, x;\n\n for (i = 0; i < s.length; i++) {\n x = s.charAt(i);\n\n if (v.indexOf(x, 0) !== -1) {\n w += x;\n }\n }\n // validate number\n j = w.length / 2;\n k = Math.floor(j);\n m = Math.ceil(j) - k;\n c = 0;\n\n for (i = 0; i < k; i++) {\n a = w.charAt(i * 2 + m) * 2;\n c += a > 9 ? Math.floor(a / 10 + a % 10) : a;\n }\n\n for (i = 0; i < k + m; i++) {\n c += w.charAt(i * 2 + 1 - m) * 1;\n }\n\n return c % 10 === 0;\n }\n\n /**\n * Collection of validation rules including rules from additional-methods.js\n * @type {Object}\n */\n return _.mapObject({\n 'min_text_length': [\n function (value, params) {\n return _.isUndefined(value) || value.length === 0 || value.length >= +params;\n },\n $.mage.__('Please enter more or equal than {0} symbols.')\n ],\n 'max_text_length': [\n function (value, params) {\n return !_.isUndefined(value) && value.length <= +params;\n },\n $.mage.__('Please enter less or equal than {0} symbols.')\n ],\n 'max-words': [\n function (value, params) {\n return utils.isEmpty(value) || utils.stripHtml(value).match(/\\b\\w+\\b/g).length < params;\n },\n $.mage.__('Please enter {0} words or less.')\n ],\n 'min-words': [\n function (value, params) {\n return utils.isEmpty(value) || utils.stripHtml(value).match(/\\b\\w+\\b/g).length >= params;\n },\n $.mage.__('Please enter at least {0} words.')\n ],\n 'range-words': [\n function (value, params) {\n var match = utils.stripHtml(value).match(/\\b\\w+\\b/g) || [];\n\n return utils.isEmpty(value) || match.length >= params[0] &&\n match.length <= params[1];\n },\n $.mage.__('Please enter between {0} and {1} words.')\n ],\n 'letters-with-basic-punc': [\n function (value) {\n return utils.isEmpty(value) || /^[a-z\\-.,()\\u0027\\u0022\\s]+$/i.test(value);\n },\n $.mage.__('Letters or punctuation only please')\n ],\n 'alphanumeric': [\n function (value) {\n return utils.isEmpty(value) || /^\\w+$/i.test(value);\n },\n $.mage.__('Letters, numbers, spaces or underscores only please')\n ],\n 'letters-only': [\n function (value) {\n return utils.isEmpty(value) || /^[a-z]+$/i.test(value);\n },\n $.mage.__('Letters only please')\n ],\n 'no-whitespace': [\n function (value) {\n return utils.isEmpty(value) || /^\\S+$/i.test(value);\n },\n $.mage.__('No white space please')\n ],\n 'no-marginal-whitespace': [\n function (value) {\n return !/^\\s+|\\s+$/i.test(value);\n },\n $.mage.__('No marginal white space please')\n ],\n 'zip-range': [\n function (value) {\n return utils.isEmpty(value) || /^90[2-5]-\\d{2}-\\d{4}$/.test(value);\n },\n $.mage.__('Your ZIP-code must be in the range 902xx-xxxx to 905-xx-xxxx')\n ],\n 'integer': [\n function (value) {\n return utils.isEmpty(value) || /^-?\\d+$/.test(value);\n },\n $.mage.__('A positive or negative non-decimal number please')\n ],\n 'vinUS': [\n function (value) {\n if (utils.isEmpty(value)) {\n return true;\n }\n\n if (value.length !== 17) {\n return false;\n }\n var i, n, d, f, cd, cdv,//eslint-disable-line vars-on-top\n LL = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K', 'L', 'M', 'N', 'P', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'],//eslint-disable-line max-len\n VL = [1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 7, 9, 2, 3, 4, 5, 6, 7, 8, 9],\n FL = [8, 7, 6, 5, 4, 3, 2, 10, 0, 9, 8, 7, 6, 5, 4, 3, 2],\n rs = 0;\n\n for (i = 0; i < 17; i++) {\n f = FL[i];\n d = value.slice(i, i + 1);\n\n if (i === 8) {\n cdv = d;\n }\n\n if (!isNaN(d)) {\n d *= f;\n } else {\n for (n = 0; n < LL.length; n++) {//eslint-disable-line max-depth\n if (d.toUpperCase() === LL[n]) {//eslint-disable-line max-depth\n d = VL[n];\n d *= f;\n\n if (isNaN(cdv) && n === 8) {//eslint-disable-line max-depth\n cdv = LL[n];\n }\n break;\n }\n }\n }\n rs += d;\n }\n cd = rs % 11;\n\n if (cd === 10) {\n cd = 'X';\n }\n\n if (cd === cdv) {\n return true;\n }\n\n return false;\n },\n $.mage.__('The specified vehicle identification number (VIN) is invalid.')\n ],\n 'dateITA': [\n function (value) {\n var check = false,\n re = /^\\d{1,2}\\/\\d{1,2}\\/\\d{4}$/,\n adata, gg, mm, aaaa, xdata;\n\n if (re.test(value)) {\n adata = value.split('/');\n gg = parseInt(adata[0], 10);\n mm = parseInt(adata[1], 10);\n aaaa = parseInt(adata[2], 10);\n xdata = new Date(aaaa, mm - 1, gg);\n\n if (xdata.getFullYear() === aaaa &&\n xdata.getMonth() === mm - 1 &&\n xdata.getDate() === gg\n ) {\n check = true;\n } else {\n check = false;\n }\n } else {\n check = false;\n }\n\n return check;\n },\n $.mage.__('Please enter a correct date')\n ],\n 'dateNL': [\n function (value) {\n return /^\\d\\d?[\\.\\/-]\\d\\d?[\\.\\/-]\\d\\d\\d?\\d?$/.test(value);\n },\n $.mage.__('Vul hier een geldige datum in.')\n ],\n 'time': [\n function (value) {\n return utils.isEmpty(value) || /^([01]\\d|2[0-3])(:[0-5]\\d){0,2}$/.test(value);\n },\n $.mage.__('Please enter a valid time, between 00:00 and 23:59')\n ],\n 'time12h': [\n function (value) {\n return utils.isEmpty(value) || /^((0?[1-9]|1[012])(:[0-5]\\d){0,2}(\\s[AP]M))$/i.test(value);\n },\n $.mage.__('Please enter a valid time, between 00:00 am and 12:00 pm')\n ],\n 'phoneUS': [\n function (value) {\n value = value.replace(/\\s+/g, '');\n\n return utils.isEmpty(value) || value.length > 9 &&\n value.match(/^(1-?)?(\\([2-9]\\d{2}\\)|[2-9]\\d{2})-?[2-9]\\d{2}-?\\d{4}$/);\n },\n $.mage.__('Please specify a valid phone number')\n ],\n 'phoneUK': [\n function (value) {\n return utils.isEmpty(value) || value.length > 9 &&\n value.match(/^(\\(?(0|\\+44)[1-9]{1}\\d{1,4}?\\)?\\s?\\d{3,4}\\s?\\d{3,4})$/);\n },\n $.mage.__('Please specify a valid phone number')\n ],\n 'mobileUK': [\n function (value) {\n return utils.isEmpty(value) || value.length > 9 && value.match(/^((0|\\+44)7\\d{3}\\s?\\d{6})$/);\n },\n $.mage.__('Please specify a valid mobile number')\n ],\n 'stripped-min-length': [\n function (value, param) {\n return _.isUndefined(value) || value.length === 0 || utils.stripHtml(value).length >= param;\n },\n $.mage.__('Please enter at least {0} characters')\n ],\n 'email2': [\n function (value) {\n return utils.isEmpty(value) || /^((([a-z]|\\d|[!#\\$%&\\u0027\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+(\\.([a-z]|\\d|[!#\\$%&\\u0027\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+)*)|((\\u0022)((((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(([\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]|\\x21|[\\x23-\\x5b]|[\\x5d-\\x7e]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(\\\\([\\x01-\\x09\\x0b\\x0c\\x0d-\\x7f]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF]))))*(((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(\\u0022)))@((([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.)*(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.?$/i.test(value);//eslint-disable-line max-len\n },\n $.validator.messages.email\n ],\n 'url2': [\n function (value) {\n return utils.isEmpty(value) || /^(https?|ftp):\\/\\/(((([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&\\u0027\\(\\)\\*\\+,;=]|:)*@)?(((\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5]))|((([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.)*(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.?)(:\\d*)?)(\\/((([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&\\u0027\\(\\)\\*\\+,;=]|:|@)+(\\/(([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&\\u0027\\(\\)\\*\\+,;=]|:|@)*)*)?)?(\\?((([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&\\u0027\\(\\)\\*\\+,;=]|:|@)|[\\uE000-\\uF8FF]|\\/|\\?)*)?(\\#((([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&\\u0027\\(\\)\\*\\+,;=]|:|@)|\\/|\\?)*)?$/i.test(value);//eslint-disable-line max-len\n },\n $.validator.messages.url\n ],\n 'credit-card-types': [\n function (value, param) {\n var validTypes;\n\n if (utils.isEmpty(value)) {\n return true;\n }\n\n if (/[^0-9-]+/.test(value)) {\n return false;\n }\n value = value.replace(/\\D/g, '');\n validTypes = 0x0000;\n\n if (param.mastercard) {\n validTypes |= 0x0001;\n }\n\n if (param.visa) {\n validTypes |= 0x0002;\n }\n\n if (param.amex) {\n validTypes |= 0x0004;\n }\n\n if (param.dinersclub) {\n validTypes |= 0x0008;\n }\n\n if (param.enroute) {\n validTypes |= 0x0010;\n }\n\n if (param.discover) {\n validTypes |= 0x0020;\n }\n\n if (param.jcb) {\n validTypes |= 0x0040;\n }\n\n if (param.unknown) {\n validTypes |= 0x0080;\n }\n\n if (param.all) {\n validTypes = 0x0001 | 0x0002 | 0x0004 | 0x0008 | 0x0010 | 0x0020 | 0x0040 | 0x0080;\n }\n\n if (validTypes & 0x0001 && /^(51|52|53|54|55)/.test(value)) { //mastercard\n return value.length === 16;\n }\n\n if (validTypes & 0x0002 && /^(4)/.test(value)) { //visa\n return value.length === 16;\n }\n\n if (validTypes & 0x0004 && /^(34|37)/.test(value)) { //amex\n return value.length === 15;\n }\n\n if (validTypes & 0x0008 && /^(300|301|302|303|304|305|36|38)/.test(value)) { //dinersclub\n return value.length === 14;\n }\n\n if (validTypes & 0x0010 && /^(2014|2149)/.test(value)) { //enroute\n return value.length === 15;\n }\n\n if (validTypes & 0x0020 && /^(6011)/.test(value)) { //discover\n return value.length === 16;\n }\n\n if (validTypes & 0x0040 && /^(3)/.test(value)) { //jcb\n return value.length === 16;\n }\n\n if (validTypes & 0x0040 && /^(2131|1800)/.test(value)) { //jcb\n return value.length === 15;\n }\n\n if (validTypes & 0x0080) { //unknown\n return true;\n }\n\n return false;\n },\n $.mage.__('Please enter a valid credit card number.')\n ],\n 'ipv4': [\n function (value) {\n return utils.isEmpty(value) || /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/i.test(value);//eslint-disable-line max-len\n },\n $.mage.__('Please enter a valid IP v4 address.')\n ],\n 'ipv6': [\n function (value) {\n return utils.isEmpty(value) || /^((([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}:[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){5}:([0-9A-Fa-f]{1,4}:)?[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){4}:([0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){3}:([0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){2}:([0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}((\\b((25[0-5])|(1\\d{2})|(2[0-4]\\d)|(\\d{1,2}))\\b)\\.){3}(\\b((25[0-5])|(1\\d{2})|(2[0-4]\\d)|(\\d{1,2}))\\b))|(([0-9A-Fa-f]{1,4}:){0,5}:((\\b((25[0-5])|(1\\d{2})|(2[0-4]\\d)|(\\d{1,2}))\\b)\\.){3}(\\b((25[0-5])|(1\\d{2})|(2[0-4]\\d)|(\\d{1,2}))\\b))|(::([0-9A-Fa-f]{1,4}:){0,5}((\\b((25[0-5])|(1\\d{2})|(2[0-4]\\d)|(\\d{1,2}))\\b)\\.){3}(\\b((25[0-5])|(1\\d{2})|(2[0-4]\\d)|(\\d{1,2}))\\b))|([0-9A-Fa-f]{1,4}::([0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})|(::([0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){1,7}:))$/i.test(value);//eslint-disable-line max-len\n },\n $.mage.__('Please enter a valid IP v6 address.')\n ],\n 'pattern': [\n function (value, param) {\n return utils.isEmpty(value) || new RegExp(param).test(value);\n },\n $.mage.__('Invalid format.')\n ],\n 'validate-no-html-tags': [\n function (value) {\n return !/<(\\/)?\\w+/.test(value);\n },\n $.mage.__('HTML tags are not allowed.')\n ],\n 'validate-select': [\n function (value) {\n return value !== 'none' && value != null && value.length !== 0;\n },\n $.mage.__('Please select an option.')\n ],\n 'validate-no-empty': [\n function (value) {\n return !utils.isEmpty(value);\n },\n $.mage.__('Empty Value.')\n ],\n 'validate-alphanum-with-spaces': [\n function (value) {\n return utils.isEmptyNoTrim(value) || /^[a-zA-Z0-9 ]+$/.test(value);\n },\n $.mage.__('Please use only letters (a-z or A-Z), numbers (0-9) or spaces only in this field.')\n ],\n 'validate-data': [\n function (value) {\n return utils.isEmptyNoTrim(value) || /^[A-Za-z]+[A-Za-z0-9_]+$/.test(value);\n },\n $.mage.__('Please use only letters (a-z or A-Z), numbers (0-9) or underscore (_) in this field, and the first character should be a letter.')//eslint-disable-line max-len\n ],\n 'validate-street': [\n function (value) {\n return utils.isEmptyNoTrim(value) ||\n /^[ \\w]{3,}([A-Za-z]\\.)?([ \\w]*\\#\\d+)?(\\r\\n| )[ \\w]{3,}/.test(value);\n },\n $.mage.__('Please use only letters (a-z or A-Z), numbers (0-9), spaces and \"#\" in this field.')\n ],\n 'validate-phoneStrict': [\n function (value) {\n return utils.isEmptyNoTrim(value) || /^(\\()?\\d{3}(\\))?(-|\\s)?\\d{3}(-|\\s)\\d{4}$/.test(value);\n },\n $.mage.__('Please enter a valid phone number. For example (123) 456-7890 or 123-456-7890.')\n ],\n 'validate-phoneLax': [\n function (value) {\n return utils.isEmptyNoTrim(value) ||\n /^((\\d[\\-. ]?)?((\\(\\d{3}\\))|\\d{3}))?[\\-. ]?\\d{3}[\\-. ]?\\d{4}$/.test(value);\n },\n $.mage.__('Please enter a valid phone number. For example (123) 456-7890 or 123-456-7890.')\n ],\n 'validate-fax': [\n function (value) {\n return utils.isEmptyNoTrim(value) || /^(\\()?\\d{3}(\\))?(-|\\s)?\\d{3}(-|\\s)\\d{4}$/.test(value);\n },\n $.mage.__('Please enter a valid fax number (Ex: 123-456-7890).')\n ],\n 'validate-email': [\n function (value) {\n return utils.isEmptyNoTrim(value) || /^([a-z0-9,!\\#\\$%&'\\*\\+\\/=\\?\\^_`\\{\\|\\}~-]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+(\\.([a-z0-9,!\\#\\$%&'\\*\\+\\/=\\?\\^_`\\{\\|\\}~-]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+)*@([a-z0-9-]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+(\\.([a-z0-9-]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+)*\\.(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF]){2,})$/i.test(value);//eslint-disable-line max-len\n },\n $.mage.__('Please enter a valid email address (Ex: johndoe@domain.com).')\n ],\n 'validate-emailSender': [\n function (value) {\n return utils.isEmptyNoTrim(value) || /^[\\S ]+$/.test(value);\n },\n $.mage.__('Please enter a valid email address (Ex: johndoe@domain.com).')\n ],\n 'validate-password': [\n function (value) {\n var pass;\n\n if (value == null) {\n return false;\n }\n\n pass = value.trim();\n\n if (!pass.length) {\n return true;\n }\n\n return !(pass.length > 0 && pass.length < 6);\n },\n $.mage.__('Please enter 6 or more characters. Leading and trailing spaces will be ignored.')\n ],\n 'validate-admin-password': [\n function (value) {\n var pass;\n\n if (value == null) {\n return false;\n }\n\n pass = value.trim();\n\n if (pass.length === 0) {\n return true;\n }\n\n if (!/[a-z]/i.test(value) || !/[0-9]/.test(value)) {\n return false;\n }\n\n if (pass.length < 7) {\n return false;\n }\n\n return true;\n },\n $.mage.__('Please enter 7 or more characters, using both numeric and alphabetic.')\n ],\n 'validate-customer-password': [\n function (v, elm) {\n var validator = this,\n counter = 0,\n passwordMinLength = $(elm).data('password-min-length'),\n passwordMinCharacterSets = $(elm).data('password-min-character-sets'),\n pass = v.trim(),\n result = pass.length >= passwordMinLength;\n\n if (result === false) {\n validator.passwordErrorMessage = $.mage.__('Minimum length of this field must be equal or greater than %1 symbols. Leading and trailing spaces will be ignored.').replace('%1', passwordMinLength);//eslint-disable-line max-len\n\n return result;\n }\n\n if (pass.match(/\\d+/)) {\n counter++;\n }\n\n if (pass.match(/[a-z]+/)) {\n counter++;\n }\n\n if (pass.match(/[A-Z]+/)) {\n counter++;\n }\n\n if (pass.match(/[^a-zA-Z0-9]+/)) {\n counter++;\n }\n\n if (counter < passwordMinCharacterSets) {\n result = false;\n validator.passwordErrorMessage = $.mage.__('Minimum of different classes of characters in password is %1. Classes of characters: Lower Case, Upper Case, Digits, Special Characters.').replace('%1', passwordMinCharacterSets);//eslint-disable-line max-len\n }\n\n return result;\n }, function () {\n return this.passwordErrorMessage;\n }\n ],\n 'validate-url': [\n function (value) {\n if (utils.isEmptyNoTrim(value)) {\n return true;\n }\n value = (value || '').replace(/^\\s+/, '').replace(/\\s+$/, '');\n\n return (/^(http|https|ftp):\\/\\/(([A-Z0-9]([A-Z0-9_-]*[A-Z0-9]|))(\\.[A-Z0-9]([A-Z0-9_-]*[A-Z0-9]|))*)(:(\\d+))?(\\/[A-Z0-9~](([A-Z0-9_~-]|\\.)*[A-Z0-9~]|))*\\/?(.*)?$/i).test(value);//eslint-disable-line max-len\n\n },\n $.mage.__('Please enter a valid URL. Protocol is required (http://, https:// or ftp://).')\n ],\n 'validate-clean-url': [\n function (value) {\n return utils.isEmptyNoTrim(value) || /^(http|https|ftp):\\/\\/(([A-Z0-9][A-Z0-9_-]*)(\\.[A-Z0-9][A-Z0-9_-]*)+.(com|org|net|dk|at|us|tv|info|uk|co.uk|biz|se)$)(:(\\d+))?\\/?/i.test(value) || /^(www)((\\.[A-Z0-9][A-Z0-9_-]*)+.(com|org|net|dk|at|us|tv|info|uk|co.uk|biz|se)$)(:(\\d+))?\\/?/i.test(value);//eslint-disable-line max-len\n\n },\n $.mage.__('Please enter a valid URL. For example http://www.example.com or www.example.com.')\n ],\n 'validate-xml-identifier': [\n function (value) {\n return utils.isEmptyNoTrim(value) || /^[A-Z][A-Z0-9_\\/-]*$/i.test(value);\n\n },\n $.mage.__('Please enter a valid XML-identifier (Ex: something_1, block5, id-4).')\n ],\n 'validate-ssn': [\n function (value) {\n return utils.isEmptyNoTrim(value) || /^\\d{3}-?\\d{2}-?\\d{4}$/.test(value);\n\n },\n $.mage.__('Please enter a valid social security number (Ex: 123-45-6789).')\n ],\n 'validate-zip-us': [\n function (value) {\n return utils.isEmptyNoTrim(value) || /(^\\d{5}$)|(^\\d{5}-\\d{4}$)/.test(value);\n\n },\n $.mage.__('Please enter a valid zip code (Ex: 90602 or 90602-1234).')\n ],\n 'validate-date-au': [\n function (value) {\n var regex = /^(\\d{2})\\/(\\d{2})\\/(\\d{4})$/,\n d;\n\n if (utils.isEmptyNoTrim(value)) {\n return true;\n }\n\n if (utils.isEmpty(value) || !regex.test(value)) {\n return false;\n }\n d = new Date(value.replace(regex, '$2/$1/$3'));\n\n return parseInt(RegExp.$2, 10) === 1 + d.getMonth() &&\n parseInt(RegExp.$1, 10) === d.getDate() &&\n parseInt(RegExp.$3, 10) === d.getFullYear();\n\n },\n $.mage.__('Please use this date format: dd/mm/yyyy. For example 17/03/2006 for the 17th of March, 2006.')\n ],\n 'validate-currency-dollar': [\n function (value) {\n return utils.isEmptyNoTrim(value) || /^\\$?\\-?([1-9]{1}[0-9]{0,2}(\\,[0-9]{3})*(\\.[0-9]{0,2})?|[1-9]{1}\\d*(\\.[0-9]{0,2})?|0(\\.[0-9]{0,2})?|(\\.[0-9]{1,2})?)$/.test(value);//eslint-disable-line max-len\n\n },\n $.mage.__('Please enter a valid $ amount. For example $100.00.')\n ],\n 'validate-not-negative-number': [\n function (value) {\n return utils.isEmptyNoTrim(value) || !isNaN(utils.parseNumber(value))\n && value >= 0 && (/^\\s*-?\\d+([,.]\\d+)*\\s*%?\\s*$/).test(value);\n\n },\n $.mage.__('Please enter a number 0 or greater, without comma in this field.')\n ],\n // validate-not-negative-number should be replaced in all places with this one and then removed\n 'validate-zero-or-greater': [\n function (value) {\n return utils.isEmptyNoTrim(value) || !isNaN(utils.parseNumber(value))\n && value >= 0 && (/^\\s*-?\\d+([,.]\\d+)*\\s*%?\\s*$/).test(value);\n },\n $.mage.__('Please enter a number 0 or greater, without comma in this field.')\n ],\n 'validate-greater-than-zero': [\n function (value) {\n return utils.isEmptyNoTrim(value) || !isNaN(utils.parseNumber(value))\n && value > 0 && (/^\\s*-?\\d+([,.]\\d+)*\\s*%?\\s*$/).test(value);\n },\n $.mage.__('Please enter a number greater than 0, without comma in this field.')\n ],\n 'validate-css-length': [\n function (value) {\n if (value !== '') {\n return (/^[0-9]*\\.*[0-9]+(px|pc|pt|ex|em|mm|cm|in|%)?$/).test(value);\n }\n\n return true;\n },\n $.mage.__('Please input a valid CSS-length (Ex: 100px, 77pt, 20em, .5ex or 50%).')\n ],\n 'validate-number': [\n function (value) {\n return utils.isEmptyNoTrim(value) ||\n !isNaN(utils.parseNumber(value)) &&\n /^\\s*-?\\d*(?:[.,|'|\\s]\\d+)*(?:[.,|'|\\s]\\d{2})?-?\\s*$/.test(value);\n },\n $.mage.__('Please enter a valid number in this field.')\n ],\n 'validate-integer': [\n function (value) {\n return utils.isEmptyNoTrim(value) || !isNaN(utils.parseNumber(value)) && /^\\s*-?\\d*\\s*$/.test(value);\n },\n $.mage.__('Please enter a valid integer in this field.')\n ],\n 'validate-number-range': [\n function (value, param) {\n var numValue, dataAttrRange, result, range, m;\n\n if (utils.isEmptyNoTrim(value)) {\n return true;\n }\n\n numValue = utils.parseNumber(value);\n\n if (isNaN(numValue)) {\n return false;\n }\n\n dataAttrRange = /^(-?[\\d.,]+)?-(-?[\\d.,]+)?$/;\n result = true;\n range = param;\n\n if (range) {\n m = dataAttrRange.exec(range);\n\n if (m) {\n result = result && utils.isBetween(numValue, m[1], m[2]);\n }\n }\n\n return result;\n },\n $.mage.__('The value is not within the specified range.')\n ],\n 'validate-positive-percent-decimal': [\n function (value) {\n var numValue;\n\n if (utils.isEmptyNoTrim(value) || !/^\\s*-?\\d*(\\.\\d*)?\\s*$/.test(value)) {\n return false;\n }\n\n numValue = utils.parseNumber(value);\n\n if (isNaN(numValue)) {\n return false;\n }\n\n return utils.isBetween(numValue, 0.01, 100);\n },\n $.mage.__('Please enter a valid percentage discount value greater than 0.')\n ],\n 'validate-digits': [\n function (value) {\n return utils.isEmptyNoTrim(value) || !/[^\\d]/.test(value);\n },\n $.mage.__('Please enter a valid number in this field.')\n ],\n 'validate-digits-range': [\n function (value, param) {\n var numValue, dataAttrRange, result, range, m;\n\n if (utils.isEmptyNoTrim(value)) {\n return true;\n }\n\n numValue = utils.parseNumber(value);\n\n if (isNaN(numValue)) {\n return false;\n }\n\n dataAttrRange = /^(-?\\d+)?-(-?\\d+)?$/;\n result = true;\n range = param;\n\n if (range) {\n m = dataAttrRange.exec(range);\n\n if (m) {\n result = result && utils.isBetween(numValue, m[1], m[2]);\n }\n }\n\n return result;\n },\n $.mage.__('The value is not within the specified range.')\n ],\n 'validate-range': [\n function (value) {\n var minValue, maxValue, ranges;\n\n if (utils.isEmptyNoTrim(value)) {\n return true;\n } else if ($.validator.methods['validate-digits'] && $.validator.methods['validate-digits'](value)) {\n minValue = maxValue = utils.parseNumber(value);\n } else {\n ranges = /^(-?\\d+)?-(-?\\d+)?$/.exec(value);\n\n if (ranges) {\n minValue = utils.parseNumber(ranges[1]);\n maxValue = utils.parseNumber(ranges[2]);\n\n if (minValue > maxValue) {//eslint-disable-line max-depth\n return false;\n }\n } else {\n return false;\n }\n }\n },\n $.mage.__('The value is not within the specified range.')\n ],\n 'validate-alpha': [\n function (value) {\n return utils.isEmptyNoTrim(value) || /^[a-zA-Z]+$/.test(value);\n },\n $.mage.__('Please use letters only (a-z or A-Z) in this field.')\n ],\n 'validate-code': [\n function (value) {\n return utils.isEmptyNoTrim(value) || /^[a-z]+[a-z0-9_]+$/.test(value);\n },\n $.mage.__('Please use only lowercase letters (a-z), numbers (0-9) or underscore (_) in this field, and the first character should be a letter.')//eslint-disable-line max-len\n ],\n 'validate-alphanum': [\n function (value) {\n return utils.isEmptyNoTrim(value) || /^[a-zA-Z0-9]+$/.test(value);\n },\n $.mage.__('Please use only letters (a-z or A-Z) or numbers (0-9) in this field. No spaces or other characters are allowed.')//eslint-disable-line max-len\n ],\n 'validate-not-number-first': [\n function (value) {\n return utils.isEmptyNoTrim(value) || /^[^0-9-\\.].*$/.test(value.trim());\n },\n $.mage.__('First character must be letter.')\n ],\n 'validate-date': [\n function (value, params, additionalParams) {\n var test = moment(value, additionalParams.dateFormat);\n\n return utils.isEmptyNoTrim(value) || test.isValid();\n },\n $.mage.__('Please enter a valid date.')\n ],\n 'validate-date-range': [\n function (value, params) {\n var fromDate = $('input[name*=\"' + params + '\"]').val();\n\n return moment.utc(value).unix() >= moment.utc(fromDate).unix() || isNaN(moment.utc(value).unix());\n },\n $.mage.__('Make sure the To Date is later than or the same as the From Date.')\n ],\n 'validate-identifier': [\n function (value) {\n return utils.isEmptyNoTrim(value) || /^[a-z0-9][a-z0-9_\\/-]+(\\.[a-z0-9_-]+)?$/.test(value);\n },\n $.mage.__('Please enter a valid URL Key (Ex: \"example-page\", \"example-page.html\" or \"anotherlevel/example-page\").')//eslint-disable-line max-len\n ],\n 'validate-trailing-hyphen': [\n function (value) {\n return utils.isEmptyNoTrim(value) || /^(?!-)(?!.*-$).+$/.test(value);\n },\n $.mage.__('Trailing hyphens are not allowed.')\n ],\n 'validate-zip-international': [\n\n /*function(v) {\n // @TODO: Cleanup\n return Validation.get('IsEmpty').test(v) || /(^[A-z0-9]{2,10}([\\s]{0,1}|[\\-]{0,1})[A-z0-9]{2,10}$)/.test(v);\n }*/\n function () {\n return true;\n },\n $.mage.__('Please enter a valid zip code.')\n ],\n 'validate-state': [\n function (value) {\n return value !== 0;\n },\n $.mage.__('Please select State/Province.')\n ],\n 'less-than-equals-to': [\n function (value, params) {\n value = utils.parseNumber(value);\n\n if (isNaN(parseFloat(params))) {\n params = $(params).val();\n }\n\n params = utils.parseNumber(params);\n\n if (!isNaN(params) && !isNaN(value)) {\n this.lteToVal = params;\n\n return value <= params;\n }\n\n return true;\n },\n function () {\n return $.mage.__('Please enter a value less than or equal to %s.').replace('%s', this.lteToVal);\n }\n ],\n 'greater-than-equals-to': [\n function (value, params) {\n value = utils.parseNumber(value);\n\n if (isNaN(parseFloat(params))) {\n params = $(params).val();\n }\n\n params = utils.parseNumber(params);\n\n if (!isNaN(params) && !isNaN(value)) {\n this.gteToVal = params;\n\n return value >= params;\n }\n\n return true;\n },\n function () {\n return $.mage.__('Please enter a value greater than or equal to %s.').replace('%s', this.gteToVal);\n }\n ],\n 'validate-emails': [\n function (value) {\n var validRegexp, emails, i;\n\n if (utils.isEmpty(value)) {\n return true;\n }\n validRegexp = /^[a-z0-9\\._-]{1,30}@([a-z0-9_-]{1,30}\\.){1,5}[a-z]{2,4}$/i;\n emails = value.split(/[\\s\\n\\,]+/g);\n\n for (i = 0; i < emails.length; i++) {\n if (!validRegexp.test(emails[i].strip())) {\n return false;\n }\n }\n\n return true;\n },\n $.mage.__('Please enter valid email addresses, separated by commas. For example, johndoe@domain.com, johnsmith@domain.com.')//eslint-disable-line max-len\n ],\n 'validate-cc-number': [\n\n /**\n * Validate credit card number based on mod 10.\n *\n * @param {String} value - credit card number\n * @return {Boolean}\n */\n function (value) {\n if (value) {\n return validateCreditCard(value);\n }\n\n return true;\n },\n $.mage.__('Please enter a valid credit card number.')\n ],\n 'validate-cc-ukss': [\n\n /**\n * Validate Switch/Solo/Maestro issue number and start date is filled.\n *\n * @param {String} value - input field value\n * @return {*}\n */\n function (value) {\n return value;\n },\n $.mage.__('Please enter issue number or start date for switch/solo card type.')\n ],\n 'required-entry': [\n function (value) {\n return !utils.isEmpty(value);\n },\n $.mage.__('This is a required field.')\n ],\n 'checked': [\n function (value) {\n return value;\n },\n $.mage.__('This is a required field.')\n ],\n 'not-negative-amount': [\n function (value) {\n if (value.length) {\n return (/^\\s*\\d+([,.]\\d+)*\\s*%?\\s*$/).test(value);\n }\n\n return true;\n },\n $.mage.__('Please enter positive number in this field.')\n ],\n 'validate-per-page-value-list': [\n function (value) {\n var isValid = true,\n values = value.split(','),\n i;\n\n if (utils.isEmpty(value)) {\n return isValid;\n }\n\n for (i = 0; i < values.length; i++) {\n if (!/^[0-9]+$/.test(values[i])) {\n isValid = false;\n }\n }\n\n return isValid;\n },\n $.mage.__('Please enter a valid value, ex: 10,20,30')\n ],\n 'validate-new-password': [\n function (value) {\n if ($.validator.methods['validate-password'] && !$.validator.methods['validate-password'](value)) {\n return false;\n }\n\n if (utils.isEmpty(value) && value !== '') {\n return false;\n }\n\n return true;\n },\n $.mage.__('Please enter 6 or more characters. Leading and trailing spaces will be ignored.')\n ],\n 'validate-item-quantity': [\n function (value, params) {\n var validator = this,\n result = false,\n // obtain values for validation\n qty = utils.parseNumber(value),\n isMinAllowedValid = typeof params.minAllowed === 'undefined' ||\n qty >= utils.parseNumber(params.minAllowed),\n isMaxAllowedValid = typeof params.maxAllowed === 'undefined' ||\n qty <= utils.parseNumber(params.maxAllowed),\n isQtyIncrementsValid = typeof params.qtyIncrements === 'undefined' ||\n qty % utils.parseNumber(params.qtyIncrements) === 0;\n\n result = qty > 0;\n\n if (result === false) {\n validator.itemQtyErrorMessage = $.mage.__('Please enter a quantity greater than 0.');//eslint-disable-line max-len\n\n return result;\n }\n\n result = isMinAllowedValid;\n\n if (result === false) {\n validator.itemQtyErrorMessage = $.mage.__('The fewest you may purchase is %1.').replace('%1', params.minAllowed);//eslint-disable-line max-len\n\n return result;\n }\n\n result = isMaxAllowedValid;\n\n if (result === false) {\n validator.itemQtyErrorMessage = $.mage.__('The maximum you may purchase is %1.').replace('%1', params.maxAllowed);//eslint-disable-line max-len\n\n return result;\n }\n\n result = isQtyIncrementsValid;\n\n if (result === false) {\n validator.itemQtyErrorMessage = $.mage.__('You can buy this product only in quantities of %1 at a time.').replace('%1', params.qtyIncrements);//eslint-disable-line max-len\n\n return result;\n }\n\n return result;\n }, function () {\n return this.itemQtyErrorMessage;\n }\n ],\n 'equalTo': [\n function (value, param) {\n return value === $(param).val();\n },\n $.validator.messages.equalTo\n ],\n 'validate-file-type': [\n function (name, types) {\n var extension = name.split('.').pop().toLowerCase();\n\n if (types && typeof types === 'string') {\n types = types.split(' ');\n }\n\n return !types || !types.length || ~types.indexOf(extension);\n },\n $.mage.__('We don\\'t recognize or support this file extension type.')\n ],\n 'validate-max-size': [\n function (size, maxSize) {\n return maxSize === false || size < maxSize;\n },\n $.mage.__('File you are trying to upload exceeds maximum file size limit.')\n ],\n 'validate-if-tag-script-exist': [\n function (value) {\n return !value || (/<script\\b[^>]*>([\\s\\S]*?)<\\/script>$/ig).test(value);\n },\n $.mage.__('Please use tag SCRIPT with SRC attribute or with proper content to include JavaScript to the document.')//eslint-disable-line max-len\n ],\n 'date_range_min': [\n function (value, minValue, params) {\n return moment.utc(value, params.dateFormat).unix() >= minValue;\n },\n $.mage.__('The date is not within the specified range.')\n ],\n 'date_range_max': [\n function (value, maxValue, params) {\n return moment.utc(value, params.dateFormat).unix() <= maxValue;\n },\n $.mage.__('The date is not within the specified range.')\n ],\n 'validate-color': [\n function (value) {\n if (value === '') {\n return true;\n }\n\n return tinycolor(value).isValid();\n },\n $.mage.__('Wrong color format. Please specify color in HEX, RGBa, HSVa, HSLa or use color name.')\n ],\n 'blacklist-url': [\n function (value, param) {\n return new RegExp(param).test(value);\n },\n $.mage.__('This link is not allowed.')\n ],\n 'validate-dob': [\n function (value, param, params) {\n if (value === '') {\n return true;\n }\n\n return moment.utc(value, params.dateFormat).isSameOrBefore(moment.utc());\n },\n $.mage.__('The Date of Birth should not be greater than today.')\n ],\n 'validate-no-utf8mb4-characters': [\n function (value) {\n var validator = this,\n message = $.mage.__('Please remove invalid characters: {0}.'),\n matches = value.match(/(?:[\\uD800-\\uDBFF][\\uDC00-\\uDFFF])/g),\n result = matches === null;\n\n if (!result) {\n validator.charErrorMessage = message.replace('{0}', matches.join());\n }\n\n return result;\n }, function () {\n return this.charErrorMessage;\n }\n ]\n }, function (data) {\n return {\n handler: data[0],\n message: data[1]\n };\n });\n});\n","Magento_Ui/js/lib/validation/utils.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine(function () {\n 'use strict';\n\n var utils = {\n /**\n * Check if string is empty with trim.\n *\n * @param {String} value\n * @return {Boolean}\n */\n isEmpty: function (value) {\n return value === '' || value == null || value.length === 0 || /^\\s+$/.test(value);\n },\n\n /**\n * Check if string is empty no trim.\n *\n * @param {String} value\n * @return {Boolean}\n */\n isEmptyNoTrim: function (value) {\n return value === '' || value == null || value.length === 0;\n },\n\n /**\n * Checks if {value} is between numbers {from} and {to}.\n *\n * @param {String} value\n * @param {String} from\n * @param {String} to\n * @return {Boolean}\n */\n isBetween: function (value, from, to) {\n return (from === null || from === '' || value >= utils.parseNumber(from)) &&\n (to === null || to === '' || value <= utils.parseNumber(to));\n },\n\n /**\n * Parse price string.\n *\n * @param {String} value\n * @return {Number}\n */\n parseNumber: function (value) {\n var isDot, isComa;\n\n if (typeof value !== 'string') {\n return parseFloat(value);\n }\n isDot = value.indexOf('.');\n isComa = value.indexOf(',');\n\n if (isDot !== -1 && isComa !== -1) {\n if (isComa > isDot) {\n value = value.replace('.', '').replace(',', '.');\n } else {\n value = value.replace(',', '');\n }\n } else if (isComa !== -1) {\n value = value.replace(',', '.');\n }\n\n return parseFloat(value);\n },\n\n /**\n * Removes HTML tags and space characters, numbers and punctuation.\n *\n * @param {String} value - Value being stripped.\n * @return {String}\n */\n stripHtml: function (value) {\n return value.replace(/<.[^<>]*?>/g, ' ').replace(/ | /gi, ' ')\n .replace(/[0-9.(),;:!?%#$'\"_+=\\/-]*/g, '');\n }\n };\n\n return utils;\n});\n","Magento_Ui/js/modal/modalToggle.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n 'jquery',\n 'Magento_Ui/js/modal/modal'\n], function ($) {\n 'use strict';\n\n return function (config, el) {\n var widget,\n content;\n\n if (config.contentSelector) {\n content = $(config.contentSelector);\n } else if (config.content) {\n content = $('<div></div>').html(config.content);\n } else {\n content = $('<div></div>');\n }\n\n widget = content.modal(config);\n\n $(el).on(config.toggleEvent, function () {\n var state = widget.data('mage-modal').options.isOpen;\n\n if (state) {\n widget.modal('closeModal');\n } else {\n widget.modal('openModal');\n }\n\n return false;\n });\n\n return widget;\n };\n});\n","Magento_Ui/js/modal/modal-component.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n 'Magento_Ui/js/lib/view/utils/async',\n 'uiCollection',\n 'uiRegistry',\n 'underscore',\n './modal'\n], function ($, Collection, registry, _) {\n 'use strict';\n\n return Collection.extend({\n defaults: {\n template: 'ui/modal/modal-component',\n title: '',\n subTitle: '',\n options: {\n modalClass: '',\n title: '',\n subTitle: '',\n buttons: [],\n keyEventHandlers: {}\n },\n valid: true,\n links: {\n title: 'options.title',\n subTitle: 'options.subTitle'\n },\n listens: {\n state: 'onState',\n title: 'setTitle',\n 'options.subTitle': 'setSubTitle'\n },\n modalClass: 'modal-component',\n onCancel: 'closeModal'\n },\n\n /**\n * Initializes component.\n *\n * @returns {Object} Chainable.\n */\n initialize: function () {\n this._super();\n _.bindAll(this,\n 'initModal',\n 'openModal',\n 'closeModal',\n 'toggleModal',\n 'setPrevValues',\n 'validate');\n this.initializeContent();\n\n return this;\n },\n\n /**\n * Initializes modal configuration\n *\n * @returns {Object} Chainable.\n */\n initConfig: function () {\n return this._super()\n .initSelector()\n .initModalEvents();\n },\n\n /**\n * Configure modal selector\n *\n * @returns {Object} Chainable.\n */\n initSelector: function () {\n var modalClass = this.name.replace(/\\./g, '_');\n\n this.contentSelector = '.' + this.modalClass;\n this.options.modalClass = this.options.modalClass + ' ' + modalClass;\n this.rootSelector = '.' + modalClass;\n\n return this;\n },\n\n /**\n * Configure modal keyboard handlers\n * and outer click\n *\n * @returns {Object} Chainable.\n */\n initModalEvents: function () {\n this.options.keyEventHandlers.escapeKey = this.options.outerClickHandler = this[this.onCancel].bind(this);\n\n return this;\n },\n\n /**\n * Initialize modal's content components\n */\n initializeContent: function () {\n $.async({\n component: this.name\n }, this.initModal);\n },\n\n /**\n * Init toolbar section so other components will be able to place something in it\n */\n initToolbarSection: function () {\n this.set('toolbarSection', this.modal.data('mage-modal').modal.find('header').get(0));\n },\n\n /**\n * Initializes observable properties.\n *\n * @returns {Object} Chainable.\n */\n initObservable: function () {\n this._super();\n this.observe(['state', 'focused']);\n\n return this;\n },\n\n /**\n * Wrap content in a modal of certain type\n *\n * @param {HTMLElement} element\n * @returns {Object} Chainable.\n */\n initModal: function (element) {\n if (!this.modal) {\n this.overrideModalButtonCallback();\n this.options.modalCloseBtnHandler = this[this.onCancel].bind(this);\n this.modal = $(element).modal(this.options);\n this.initToolbarSection();\n\n if (this.waitCbk) {\n this.waitCbk();\n this.waitCbk = null;\n }\n }\n\n return this;\n },\n\n /**\n * Open modal\n */\n openModal: function () {\n if (this.modal) {\n this.state(true);\n } else {\n this.waitCbk = this.openModal;\n }\n },\n\n /**\n * Close modal\n */\n closeModal: function () {\n if (this.modal) {\n this.state(false);\n } else {\n this.waitCbk = this.closeModal;\n }\n },\n\n /**\n * Toggle modal\n */\n toggleModal: function () {\n if (this.modal) {\n this.state(!this.state());\n } else {\n this.waitCbk = this.toggleModal;\n }\n },\n\n /**\n * Sets title for modal\n *\n * @param {String} title\n */\n setTitle: function (title) {\n if (this.title !== title) {\n this.title = title;\n }\n\n if (this.modal) {\n this.modal.modal('setTitle', title);\n }\n },\n\n /**\n * Sets subTitle for modal\n *\n * @param {String} subTitle\n */\n setSubTitle: function (subTitle) {\n if (this.subTitle !== subTitle) {\n this.subTitle = subTitle;\n }\n\n if (this.modal) {\n this.modal.modal('setSubTitle', subTitle);\n }\n },\n\n /**\n * Wrap content in a modal of certain type\n *\n * @param {Boolean} state\n */\n onState: function (state) {\n if (state) {\n this.modal.modal('openModal');\n this.applyData();\n } else {\n this.modal.modal('closeModal');\n }\n },\n\n /**\n * Validate everything validatable in modal\n */\n validate: function (elem) {\n if (typeof elem === 'undefined') {\n return;\n }\n\n if (typeof elem.validate === 'function') {\n this.valid &= elem.validate().valid;\n } else if (elem.elems) {\n elem.elems().forEach(this.validate, this);\n }\n },\n\n /**\n * Reset data from provider\n */\n resetData: function () {\n this.elems().forEach(this.resetValue, this);\n },\n\n /**\n * Update 'applied' property with data from modal content\n */\n applyData: function () {\n var applied = {};\n\n this.elems().forEach(this.gatherValues.bind(this, applied), this);\n this.applied = applied;\n },\n\n /**\n * Gather values from modal content\n *\n * @param {Array} applied\n * @param {HTMLElement} elem\n */\n gatherValues: function (applied, elem) {\n if (typeof elem.value === 'function') {\n applied[elem.name] = elem.value();\n } else if (elem.elems) {\n elem.elems().forEach(this.gatherValues.bind(this, applied), this);\n }\n },\n\n /**\n * Set to previous values from modal content\n *\n * @param {HTMLElement} elem\n */\n setPrevValues: function (elem) {\n if (typeof elem.value === 'function') {\n this.modal.focus();\n elem.value(this.applied[elem.name]);\n } else if (elem.elems) {\n elem.elems().forEach(this.setPrevValues, this);\n }\n },\n\n /**\n * Triggers some method in every modal child elem, if this method is defined\n *\n * @param {Object} action - action configuration,\n * must contain actionName and targetName and\n * can contain params\n */\n triggerAction: function (action) {\n var targetName = action.targetName,\n params = action.params || [],\n actionName = action.actionName,\n target;\n\n target = registry.async(targetName);\n\n if (target && typeof target === 'function' && actionName) {\n params.unshift(actionName);\n target.apply(target, params);\n }\n },\n\n /**\n * Override modal buttons callback placeholders with real callbacks\n */\n overrideModalButtonCallback: function () {\n var buttons = this.options.buttons;\n\n if (buttons && buttons.length) {\n buttons.forEach(function (button) {\n button.click = this.getButtonClickHandler(button.actions);\n }, this);\n }\n },\n\n /**\n * Generate button click handler based on button's 'actions' configuration\n */\n getButtonClickHandler: function (actionsConfig) {\n var actions = actionsConfig.map(\n function (actionConfig) {\n if (_.isObject(actionConfig)) {\n return this.triggerAction.bind(this, actionConfig);\n }\n\n return this[actionConfig] ? this[actionConfig].bind(this) : function () {};\n }, this);\n\n return function () {\n actions.forEach(\n function (action) {\n action();\n }\n );\n };\n },\n\n /**\n * Cancels changes in modal:\n * returning elems values to the previous state,\n * and close modal\n */\n actionCancel: function () {\n this.elems().forEach(this.setPrevValues, this);\n this.closeModal();\n },\n\n /**\n * Accept changes in modal by not preventing them.\n * Can be extended by exporting 'gatherValues' result somewhere\n */\n actionDone: function () {\n this.valid = true;\n this.elems().forEach(this.validate, this);\n\n if (this.valid) {\n this.closeModal();\n }\n }\n });\n});\n","Magento_Ui/js/modal/confirm.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n 'jquery',\n 'underscore',\n 'mage/translate',\n 'jquery-ui-modules/widget',\n 'Magento_Ui/js/modal/modal'\n], function ($, _, $t) {\n 'use strict';\n\n $.widget('mage.confirm', $.mage.modal, {\n options: {\n modalClass: 'confirm',\n title: '',\n focus: '.action-accept',\n actions: {\n\n /**\n * Callback always - called on all actions.\n */\n always: function () {},\n\n /**\n * Callback confirm.\n */\n confirm: function () {},\n\n /**\n * Callback cancel.\n */\n cancel: function () {}\n },\n buttons: [{\n text: $t('Cancel'),\n class: 'action-secondary action-dismiss',\n\n /**\n * Click handler.\n */\n click: function (event) {\n this.closeModal(event);\n }\n }, {\n text: $t('OK'),\n class: 'action-primary action-accept',\n\n /**\n * Click handler.\n */\n click: function (event) {\n this.closeModal(event, true);\n }\n }]\n },\n\n /**\n * Create widget.\n */\n _create: function () {\n this._super();\n this.modal.find(this.options.modalCloseBtn).off().on('click', _.bind(this.closeModal, this));\n this.openModal();\n },\n\n /**\n * Remove modal window.\n */\n _remove: function () {\n this.modal.remove();\n },\n\n /**\n * Open modal window.\n */\n openModal: function () {\n return this._super();\n },\n\n /**\n * Close modal window.\n */\n closeModal: function (event, result) {\n result = result || false;\n\n if (result) {\n this.options.actions.confirm(event);\n } else {\n this.options.actions.cancel(event);\n }\n this.options.actions.always(event);\n this.element.on('confirmclosed', _.bind(this._remove, this));\n\n return this._super();\n }\n });\n\n return function (config) {\n return $('<div></div>').html(config.content).confirm(config);\n };\n});\n","Magento_Ui/js/modal/prompt.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n 'jquery',\n 'underscore',\n 'mage/template',\n 'text!ui/template/modal/modal-prompt-content.html',\n 'jquery-ui-modules/widget',\n 'Magento_Ui/js/modal/modal',\n 'mage/translate'\n], function ($, _, template, promptContentTmpl) {\n 'use strict';\n\n $.widget('mage.prompt', $.mage.modal, {\n options: {\n modalClass: 'prompt',\n promptContentTmpl: promptContentTmpl,\n promptField: '[data-role=\"promptField\"]',\n attributesForm: {},\n attributesField: {},\n value: '',\n validation: false,\n validationRules: [],\n keyEventHandlers: {\n\n /**\n * Enter key press handler,\n * submit result and close modal window\n * @param {Object} event - event\n */\n enterKey: function (event) {\n if (this.options.isOpen && this.modal.find(document.activeElement).length ||\n this.options.isOpen && this.modal[0] === document.activeElement) {\n this.closeModal(true);\n event.preventDefault();\n }\n },\n\n /**\n * Tab key press handler,\n * set focus to elements\n */\n tabKey: function () {\n if (document.activeElement === this.modal[0]) {\n this._setFocus('start');\n }\n },\n\n /**\n * Escape key press handler,\n * cancel and close modal window\n * @param {Object} event - event\n */\n escapeKey: function (event) {\n if (this.options.isOpen && this.modal.find(document.activeElement).length ||\n this.options.isOpen && this.modal[0] === document.activeElement) {\n this.closeModal();\n event.preventDefault();\n }\n }\n },\n actions: {\n\n /**\n * Callback always - called on all actions.\n */\n always: function () {},\n\n /**\n * Callback confirm.\n */\n confirm: function () {},\n\n /**\n * Callback cancel.\n */\n cancel: function () {}\n },\n buttons: [{\n text: $.mage.__('Cancel'),\n class: 'action-secondary action-dismiss',\n\n /**\n * Click handler.\n */\n click: function () {\n this.closeModal();\n }\n }, {\n text: $.mage.__('OK'),\n class: 'action-primary action-accept',\n\n /**\n * Click handler.\n */\n click: function () {\n this.closeModal(true);\n }\n }]\n },\n\n /**\n * Create widget.\n */\n _create: function () {\n this.options.focus = this.options.promptField;\n this.options.validation = this.options.validation && this.options.validationRules.length;\n this.options.outerClickHandler = this.options.outerClickHandler || _.bind(this.closeModal, this, false);\n this._super();\n this.modal.find(this.options.modalContent).append(this.getFormTemplate());\n this.modal.find(this.options.modalCloseBtn).off().on('click', _.bind(this.closeModal, this, false));\n\n if (this.options.validation) {\n this.setValidationClasses();\n }\n\n this.openModal();\n },\n\n /**\n * Form template getter.\n *\n * @returns {Object} Form template.\n */\n getFormTemplate: function () {\n var formTemplate,\n formAttr = '',\n inputAttr = '',\n attributeName;\n\n for (attributeName in this.options.attributesForm) {\n if (this.options.attributesForm.hasOwnProperty(attributeName)) {\n formAttr = formAttr + ' ' + attributeName + '=\"' +\n this.options.attributesForm[attributeName] + '\"';\n }\n }\n\n for (attributeName in this.options.attributesField) {\n if (this.options.attributesField.hasOwnProperty(attributeName)) {\n inputAttr = inputAttr + ' ' + attributeName + '=\"' +\n this.options.attributesField[attributeName] + '\"';\n }\n }\n\n formTemplate = $(template(this.options.promptContentTmpl, {\n data: this.options,\n formAttr: formAttr,\n inputAttr: inputAttr\n }));\n\n return formTemplate;\n },\n\n /**\n * Remove widget\n */\n _remove: function () {\n this.modal.remove();\n },\n\n /**\n * Validate prompt field\n */\n validate: function () {\n return $.validator.validateSingleElement(this.options.promptField);\n },\n\n /**\n * Add validation classes to prompt field\n */\n setValidationClasses: function () {\n this.modal.find(this.options.promptField).attr('class', $.proxy(function (i, val) {\n return val + ' ' + this.options.validationRules.join(' ');\n }, this));\n },\n\n /**\n * Open modal window\n */\n openModal: function () {\n this._super();\n this.modal.find(this.options.promptField).val(this.options.value);\n },\n\n /**\n * Close modal window\n */\n closeModal: function (result) {\n var value;\n\n if (result) {\n if (this.options.validation && !this.validate()) {\n return false;\n }\n\n value = this.modal.find(this.options.promptField).val();\n this.options.actions.confirm.call(this, value);\n } else {\n this.options.actions.cancel.call(this, result);\n }\n\n this.options.actions.always();\n this.element.on('promptclosed', _.bind(this._remove, this));\n\n return this._super();\n }\n });\n\n return function (config) {\n return $('<div class=\"prompt-message\"></div>').html(config.content).prompt(config);\n };\n});\n","Magento_Ui/js/modal/modal.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n 'jquery',\n 'underscore',\n 'mage/template',\n 'text!ui/template/modal/modal-popup.html',\n 'text!ui/template/modal/modal-slide.html',\n 'text!ui/template/modal/modal-custom.html',\n 'Magento_Ui/js/lib/key-codes',\n 'jquery-ui-modules/widget',\n 'jquery-ui-modules/core',\n 'mage/translate',\n 'jquery/z-index'\n], function ($, _, template, popupTpl, slideTpl, customTpl, keyCodes) {\n 'use strict';\n\n /**\n * Detect browser transition end event.\n * @return {String|undefined} - transition event.\n */\n var transitionEvent = (function () {\n var transition,\n elementStyle = document.createElement('div').style,\n transitions = {\n 'transition': 'transitionend',\n 'OTransition': 'oTransitionEnd',\n 'MozTransition': 'transitionend',\n 'WebkitTransition': 'webkitTransitionEnd'\n };\n\n for (transition in transitions) {\n if (elementStyle[transition] !== undefined && transitions.hasOwnProperty(transition)) {\n return transitions[transition];\n }\n }\n })();\n\n /**\n * Modal Window Widget\n */\n $.widget('mage.modal', {\n options: {\n id: null,\n type: 'popup',\n title: '',\n subTitle: '',\n modalClass: '',\n focus: '[data-role=\"closeBtn\"]',\n autoOpen: false,\n clickableOverlay: true,\n popupTpl: popupTpl,\n slideTpl: slideTpl,\n customTpl: customTpl,\n modalVisibleClass: '_show',\n parentModalClass: '_has-modal',\n innerScrollClass: '_inner-scroll',\n responsive: false,\n innerScroll: false,\n modalTitle: '[data-role=\"title\"]',\n modalSubTitle: '[data-role=\"subTitle\"]',\n modalBlock: '[data-role=\"modal\"]',\n modalCloseBtn: '[data-role=\"closeBtn\"]',\n modalContent: '[data-role=\"content\"]',\n modalAction: '[data-role=\"action\"]',\n focusableScope: '[data-role=\"focusable-scope\"]',\n focusableStart: '[data-role=\"focusable-start\"]',\n focusableEnd: '[data-role=\"focusable-end\"]',\n appendTo: 'body',\n wrapperClass: 'modals-wrapper',\n overlayClass: 'modals-overlay',\n responsiveClass: 'modal-slide',\n trigger: '',\n modalLeftMargin: 45,\n closeText: $.mage.__('Close'),\n buttons: [{\n text: $.mage.__('Ok'),\n class: '',\n attr: {},\n\n /**\n * Default action on button click\n */\n click: function (event) {\n this.closeModal(event);\n }\n }],\n keyEventHandlers: {\n\n /**\n * Tab key press handler,\n * set focus to elements\n */\n tabKey: function () {\n if (document.activeElement === this.modal[0]) {\n this._setFocus('start');\n }\n },\n\n /**\n * Escape key press handler,\n * close modal window\n * @param {Object} event - event\n */\n escapeKey: function (event) {\n if (this.options.isOpen && this.modal.find(document.activeElement).length ||\n this.options.isOpen && this.modal[0] === document.activeElement) {\n this.closeModal(event);\n }\n }\n }\n },\n\n /**\n * Creates modal widget.\n */\n _create: function () {\n _.bindAll(\n this,\n 'keyEventSwitcher',\n '_tabSwitcher',\n 'closeModal'\n );\n\n this.options.id = this.uuid;\n this.options.transitionEvent = transitionEvent;\n this._createWrapper();\n this._renderModal();\n this._createButtons();\n\n if (this.options.trigger) {\n $(document).on('click', this.options.trigger, _.bind(this.toggleModal, this));\n }\n this._on(this.modal.find(this.options.modalCloseBtn), {\n 'click': this.options.modalCloseBtnHandler ? this.options.modalCloseBtnHandler : this.closeModal\n });\n this._on(this.element, {\n 'openModal': this.openModal,\n 'closeModal': this.closeModal\n });\n this.options.autoOpen ? this.openModal() : false;\n },\n\n /**\n * Returns element from modal node.\n * @return {Object} - element.\n */\n _getElem: function (elem) {\n return this.modal.find(elem);\n },\n\n /**\n * Gets visible modal count.\n * * @return {Number} - visible modal count.\n */\n _getVisibleCount: function () {\n var modals = this.modalWrapper.find(this.options.modalBlock);\n\n return modals.filter('.' + this.options.modalVisibleClass).length;\n },\n\n /**\n * Gets count of visible modal by slide type.\n * * @return {Number} - visible modal count.\n */\n _getVisibleSlideCount: function () {\n var elems = this.modalWrapper.find('[data-type=\"slide\"]');\n\n return elems.filter('.' + this.options.modalVisibleClass).length;\n },\n\n /**\n * Listener key events.\n * Call handler function if it exists\n */\n keyEventSwitcher: function (event) {\n var key = keyCodes[event.keyCode];\n\n if (this.options.keyEventHandlers.hasOwnProperty(key)) {\n this.options.keyEventHandlers[key].apply(this, arguments);\n }\n },\n\n /**\n * Set title for modal.\n *\n * @param {String} title\n */\n setTitle: function (title) {\n var $title = this.modal.find(this.options.modalTitle),\n $subTitle = this.modal.find(this.options.modalSubTitle);\n\n $title.text(title);\n $title.append($subTitle);\n },\n\n /**\n * Set sub title for modal.\n *\n * @param {String} subTitle\n */\n setSubTitle: function (subTitle) {\n this.options.subTitle = subTitle;\n this.modal.find(this.options.modalSubTitle).html(subTitle);\n },\n\n /**\n * Toggle modal.\n * * @return {Element} - current element.\n */\n toggleModal: function () {\n if (this.options.isOpen === true) {\n this.closeModal();\n } else {\n this.openModal();\n }\n },\n\n /**\n * Open modal.\n * * @return {Element} - current element.\n */\n openModal: function () {\n this.options.isOpen = true;\n this.focussedElement = document.activeElement;\n this._createOverlay();\n this._setActive();\n this._setKeyListener();\n this.modal.one(this.options.transitionEvent, _.bind(this._setFocus, this, 'end', 'opened'));\n this.modal.one(this.options.transitionEvent, _.bind(this._trigger, this, 'opened'));\n this.modal.addClass(this.options.modalVisibleClass);\n\n if (!this.options.transitionEvent) {\n this._trigger('opened');\n }\n\n return this.element;\n },\n\n /**\n * Set focus to element.\n * @param {String} position - can be \"start\" and \"end\"\n * positions.\n * If position is \"end\" - sets focus to first\n * focusable element in modal window scope.\n * If position is \"start\" - sets focus to last\n * focusable element in modal window scope\n *\n * @param {String} type - can be \"opened\" or false\n * If type is \"opened\" - looks to \"this.options.focus\"\n * property and sets focus\n */\n _setFocus: function (position, type) {\n var focusableElements,\n infelicity;\n\n if (type === 'opened' && this.options.focus) {\n this.modal.find($(this.options.focus)).trigger('focus');\n } else if (type === 'opened' && !this.options.focus) {\n this.modal.find(this.options.focusableScope).trigger('focus');\n } else if (position === 'end') {\n this.modal.find(this.options.modalCloseBtn).trigger('focus');\n } else if (position === 'start') {\n infelicity = 2; //Constant for find last focusable element\n focusableElements = this.modal.find(':focusable');\n focusableElements.eq(focusableElements.length - infelicity).trigger('focus');\n }\n },\n\n /**\n * Set events listener when modal is opened.\n */\n _setKeyListener: function () {\n this.modal.find(this.options.focusableStart).on('focusin', this._tabSwitcher);\n this.modal.find(this.options.focusableEnd).on('focusin', this._tabSwitcher);\n this.modal.on('keydown', this.keyEventSwitcher);\n },\n\n /**\n * Remove events listener when modal is closed.\n */\n _removeKeyListener: function () {\n this.modal.find(this.options.focusableStart).off('focusin', this._tabSwitcher);\n this.modal.find(this.options.focusableEnd).off('focusin', this._tabSwitcher);\n this.modal.off('keydown', this.keyEventSwitcher);\n },\n\n /**\n * Switcher for focus event.\n * @param {Object} e - event\n */\n _tabSwitcher: function (e) {\n var target = $(e.target);\n\n if (target.is(this.options.focusableStart)) {\n this._setFocus('start');\n } else if (target.is(this.options.focusableEnd)) {\n this._setFocus('end');\n }\n },\n\n /**\n * Close modal.\n * * @return {Element} - current element.\n */\n closeModal: function () {\n var that = this;\n\n this._removeKeyListener();\n this.options.isOpen = false;\n this.modal.one(this.options.transitionEvent, function () {\n that._close();\n });\n this.modal.removeClass(this.options.modalVisibleClass);\n\n if (!this.options.transitionEvent) {\n that._close();\n }\n\n return this.element;\n },\n\n /**\n * Helper for closeModal function.\n */\n _close: function () {\n var trigger = _.bind(this._trigger, this, 'closed', this.modal);\n\n $(this.focussedElement).trigger('focus');\n this._destroyOverlay();\n this._unsetActive();\n _.defer(trigger, this);\n },\n\n /**\n * Set z-index and margin for modal and overlay.\n */\n _setActive: function () {\n var zIndex = this.modal.zIndex(),\n baseIndex = zIndex + this._getVisibleCount();\n\n if (this.modal.data('active')) {\n return;\n }\n\n this.modal.data('active', true);\n\n this.overlay.zIndex(++baseIndex);\n this.prevOverlayIndex = this.overlay.zIndex();\n this.modal.zIndex(this.overlay.zIndex() + 1);\n\n if (this._getVisibleSlideCount()) {\n this.modal.css('marginLeft', this.options.modalLeftMargin * this._getVisibleSlideCount());\n }\n },\n\n /**\n * Unset styles for modal and set z-index for previous modal.\n */\n _unsetActive: function () {\n this.modal.removeAttr('style');\n this.modal.data('active', false);\n\n if (this.overlay) {\n this.overlay.zIndex(this.prevOverlayIndex - 1);\n }\n },\n\n /**\n * Creates wrapper to hold all modals.\n */\n _createWrapper: function () {\n this.modalWrapper = $(this.options.appendTo).find('.' + this.options.wrapperClass);\n\n if (!this.modalWrapper.length) {\n this.modalWrapper = $('<div></div>')\n .addClass(this.options.wrapperClass)\n .appendTo(this.options.appendTo);\n }\n },\n\n /**\n * Compile template and append to wrapper.\n */\n _renderModal: function () {\n $(template(\n this.options[this.options.type + 'Tpl'],\n {\n data: this.options\n })).appendTo(this.modalWrapper);\n this.modal = this.modalWrapper.find(this.options.modalBlock).last();\n this.element.appendTo(this._getElem(this.options.modalContent));\n\n if (this.element.is(':hidden')) {\n this.element.show();\n }\n },\n\n /**\n * Creates buttons pane.\n */\n _createButtons: function () {\n this.buttons = this._getElem(this.options.modalAction);\n _.each(this.options.buttons, function (btn, key) {\n var button = this.buttons[key];\n\n if (btn.attr) {\n $(button).attr(btn.attr);\n }\n\n if (btn.class) {\n $(button).addClass(btn.class);\n }\n\n if (!btn.click) {\n btn.click = this.closeModal;\n }\n $(button).on('click', _.bind(btn.click, this));\n }, this);\n },\n\n /**\n * Creates overlay, append it to wrapper, set previous click event on overlay.\n */\n _createOverlay: function () {\n var events,\n outerClickHandler = this.options.outerClickHandler || this.closeModal;\n\n this.overlay = $('.' + this.options.overlayClass);\n\n if (!this.overlay.length) {\n $(this.options.appendTo).addClass(this.options.parentModalClass);\n this.overlay = $('<div></div>')\n .addClass(this.options.overlayClass)\n .appendTo(this.modalWrapper);\n }\n events = $._data(this.overlay.get(0), 'events');\n events ? this.prevOverlayHandler = events.click[0].handler : false;\n this.options.clickableOverlay ? this.overlay.off().on('click', outerClickHandler) : false;\n },\n\n /**\n * Destroy overlay.\n */\n _destroyOverlay: function () {\n if (this._getVisibleCount()) {\n this.overlay.off().on('click', this.prevOverlayHandler);\n } else {\n $(this.options.appendTo).removeClass(this.options.parentModalClass);\n this.overlay.remove();\n this.overlay = null;\n }\n }\n });\n\n return $.mage.modal;\n});\n","Magento_Ui/js/modal/alert.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n 'jquery',\n 'underscore',\n 'jquery-ui-modules/widget',\n 'Magento_Ui/js/modal/confirm',\n 'mage/translate'\n], function ($, _) {\n 'use strict';\n\n $.widget('mage.alert', $.mage.confirm, {\n options: {\n modalClass: 'confirm',\n title: $.mage.__('Attention'),\n actions: {\n\n /**\n * Callback always - called on all actions.\n */\n always: function () {}\n },\n buttons: [{\n text: $.mage.__('OK'),\n class: 'action-primary action-accept',\n\n /**\n * Click handler.\n */\n click: function () {\n this.closeModal(true);\n }\n }]\n },\n\n /**\n * Close modal window.\n */\n closeModal: function () {\n this.options.actions.always();\n this.element.on('alertclosed', _.bind(this._remove, this));\n\n return this._super();\n }\n });\n\n return function (config) {\n return $('<div></div>').html(config.content).alert(config);\n };\n});\n","Magento_Eav/js/input-types.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n 'jquery',\n 'mage/translate'\n], function ($) {\n 'use strict';\n\n return function (config) {\n $('select#frontend_input').each(function () {\n var select = $(this),\n currentValue = select.find('option:selected').val(),\n compatibleTypes = config.inputTypes,\n enabledTypes = [],\n iterator,\n warning = $('<label>')\n .hide()\n .text($.mage.__('These changes affect all related products.'))\n .addClass('mage-error')\n .attr({\n generated: true, for: select.attr('id')\n }),\n hint = $('<p>')\n .hide()\n .addClass('note')\n .attr({\n generated: true\n }),\n hints = config.hints,\n\n /**\n * Toggle hint about changes types\n */\n toggleWarning = function () {\n if (select.find('option:selected').val() === currentValue) {\n warning.hide();\n } else {\n warning.show();\n }\n },\n\n /**\n * Toggle hint\n */\n toggleHint = function () {\n if (typeof hints[select.find('option:selected').val()] !== 'undefined') {\n select.after(hint.show().text(hints[select.find('option:selected').val()]));\n } else {\n hint.hide();\n }\n },\n\n /**\n * Remove unsupported options\n */\n removeOption = function () {\n if (!~enabledTypes.indexOf($(this).val())) {\n $(this).remove();\n }\n };\n\n // find enabled types for switching dor current input type\n for (iterator = 0; iterator < compatibleTypes.length; iterator++) {\n if (compatibleTypes[iterator].indexOf(currentValue) >= 0) {\n enabledTypes = compatibleTypes[iterator];\n }\n }\n\n // Check current type (allow only compatible types)\n if (~enabledTypes.indexOf(currentValue)) {\n // Enable select and keep only available options (all other will be removed)\n select.prop('disabled', false).find('option').each(removeOption);\n // Add warning on page and event for show/hide it\n select.after(warning).on('change', toggleWarning);\n }\n //bind hint toggling on change event\n select.on('change', toggleHint);\n //show hint for currently selected value\n toggleHint();\n });\n };\n});\n","Mageplaza_Smtp/js/abandonedcart.js":"/**\r\n * Mageplaza\r\n *\r\n * NOTICE OF LICENSE\r\n *\r\n * This source file is subject to the Mageplaza.com license that is\r\n * available through the world-wide-web at this URL:\r\n * https://www.mageplaza.com/LICENSE.txt\r\n *\r\n * DISCLAIMER\r\n *\r\n * Do not edit or add to this file if you wish to upgrade this extension to newer\r\n * version in the future.\r\n *\r\n * @category Mageplaza\r\n * @package Mageplaza_SMTP\r\n * @copyright Copyright (c) Mageplaza (http://www.mageplaza.com/)\r\n * @license https://www.mageplaza.com/LICENSE.txt\r\n */\r\ndefine([\r\n 'jquery',\r\n 'Magento_Ui/js/modal/modal'\r\n], function ($, modal) {\r\n \"use strict\";\r\n\r\n $.widget('mageplaza.abandonedcarts', {\r\n\r\n _create: function () {\r\n this.initObserve();\r\n },\r\n\r\n /**\r\n * Init observe\r\n */\r\n initObserve: function () {\r\n var self = this,\r\n popupSendEmailElement = $('#popup-send-email'),\r\n copyElement = $('#copy');\r\n\r\n $(\"#send\").click(function () {\r\n $('#popup-send-email-details').show();\r\n $('#popup-send-email-preview').show();\r\n $('#preview').hide();\r\n $('#popup-send-email-back').hide();\r\n\r\n modal({\r\n type: 'popup',\r\n responsive: true,\r\n innerScroll: true,\r\n title: '',\r\n buttons: []\r\n }, popupSendEmailElement);\r\n\r\n popupSendEmailElement.modal('openModal');\r\n });\r\n\r\n $('#popup-send-email-preview').click(function () {\r\n self.preview();\r\n });\r\n\r\n $('#popup-send-email form').submit(function(){\r\n $(this).find(':submit').attr('disabled','disabled');\r\n });\r\n\r\n\r\n $('#popup-send-email-back').click(function () {\r\n $('#popup-send-email-details').show();\r\n $('#popup-send-email-preview').show();\r\n $('#preview').hide();\r\n this.hide();\r\n });\r\n\r\n copyElement.click(function () {\r\n self.copyToClipboard();\r\n $('#link-tooltip').text(self.options.copied_message);\r\n\r\n });\r\n\r\n copyElement.mouseout(function () {\r\n $('#link-tooltip').text(self.options.tooltip);\r\n })\r\n\r\n },\r\n copyToClipboard: function(){\r\n var temp = $('<input>');\r\n\r\n $('body').append(temp);\r\n temp.val($('#recovery_link > span').text()).select();\r\n document.execCommand('copy');\r\n temp.remove();\r\n },\r\n\r\n /**\r\n * @param type\r\n * @param message\r\n * @returns {string}\r\n */\r\n getMessageHtml: function (type, message) {\r\n return '<div class=\"message message-' + type + '\"> <span>' + message + '</span> </div>';\r\n },\r\n getParams: function () {\r\n return {\r\n from: $('#sender').val(),\r\n quote_id: this.options.quote_id,\r\n template_id: $('#email-template').val(),\r\n customer_name: this.options.customer_name,\r\n additional_message: $('#additional-message').val()\r\n }\r\n },\r\n preview: function () {\r\n var self = this;\r\n\r\n $.ajax({\r\n url: this.options.preview_url,\r\n data: this.getParams(),\r\n dataType: 'json',\r\n showLoader: true,\r\n success: function (result) {\r\n if (result.status) {\r\n var dstFrame = document.getElementById('iframe-preview'),\r\n dstDoc = dstFrame.contentDocument || dstFrame.contentWindow.document;\r\n\r\n dstDoc.write(result.content);\r\n dstDoc.close();\r\n $('#popup-send-email-details').hide();\r\n $('#popup-send-email-back').show();\r\n $('#preview').show();\r\n $('#popup-send-email-preview').hide();\r\n $('#subject strong').text(result.subject);\r\n $('#preview-from').text(result.from.email);\r\n } else {\r\n $('#popup-send-email #messages').html(self.getMessageHtml('error error', result.message));\r\n }\r\n }\r\n });\r\n }\r\n });\r\n\r\n return $.mageplaza.abandonedcarts;\r\n});\r\n","Mageplaza_Smtp/js/testconnection.js":"/**\r\n * Mageplaza\r\n *\r\n * NOTICE OF LICENSE\r\n *\r\n * This source file is subject to the Mageplaza.com license that is\r\n * available through the world-wide-web at this URL:\r\n * https://www.mageplaza.com/LICENSE.txt\r\n *\r\n * DISCLAIMER\r\n *\r\n * Do not edit or add to this file if you wish to upgrade this extension to newer\r\n * version in the future.\r\n *\r\n * @category Mageplaza\r\n * @package Mageplaza_Smtp\r\n * @copyright Copyright (c) Mageplaza (https://www.mageplaza.com/)\r\n * @license https://www.mageplaza.com/LICENSE.txt\r\n */\r\ndefine([\r\n \"jquery\",\r\n \"Magento_Ui/js/modal/alert\",\r\n \"mage/translate\",\r\n \"jquery/ui\"\r\n], function ($, alert, $t) {\r\n \"use strict\";\r\n\r\n $.widget('mageplaza.testconnection', {\r\n options: {\r\n ajaxUrl: '',\r\n testConnection: '#email_marketing_general_test_connection',\r\n appID: '#email_marketing_general_app_id',\r\n secretKey: '#email_marketing_general_secret_key',\r\n },\r\n _create: function () {\r\n var self = this;\r\n\r\n $(this.options.testConnection).click(function (e) {\r\n e.preventDefault();\r\n self._ajaxSubmit();\r\n });\r\n },\r\n\r\n _ajaxSubmit: function () {\r\n $.ajax({\r\n url: this.options.ajaxUrl,\r\n data: {\r\n appID: $(this.options.appID).val(),\r\n secretKey: $(this.options.secretKey).val()\r\n },\r\n dataType: 'json',\r\n showLoader: true,\r\n success: function (result) {\r\n alert({\r\n title: result.status ? $t('Success') : $t('Error'),\r\n content: result.content\r\n });\r\n }\r\n });\r\n }\r\n });\r\n\r\n return $.mageplaza.testconnection;\r\n});\r\n","Mageplaza_Smtp/js/testemail.js":"/**\r\n * Mageplaza\r\n *\r\n * NOTICE OF LICENSE\r\n *\r\n * This source file is subject to the Mageplaza.com license that is\r\n * available through the world-wide-web at this URL:\r\n * https://www.mageplaza.com/LICENSE.txt\r\n *\r\n * DISCLAIMER\r\n *\r\n * Do not edit or add to this file if you wish to upgrade this extension to newer\r\n * version in the future.\r\n *\r\n * @category Mageplaza\r\n * @package Mageplaza_Smtp\r\n * @copyright Copyright (c) Mageplaza (https://www.mageplaza.com/)\r\n * @license https://www.mageplaza.com/LICENSE.txt\r\n */\r\ndefine([\r\n \"jquery\",\r\n \"Magento_Ui/js/modal/alert\",\r\n \"mage/translate\",\r\n \"jquery/ui\"\r\n], function ($, alert, $t) {\r\n \"use strict\";\r\n\r\n $.widget('mageplaza.testEmail', {\r\n options: {\r\n ajaxUrl: '',\r\n testEmail: '#smtp_configuration_option_test_email_sent',\r\n fromEmailElem: '#smtp_configuration_option_test_email_from',\r\n hostElem: '#smtp_configuration_option_host',\r\n portElem: '#smtp_configuration_option_port',\r\n authenticationElem: '#smtp_configuration_option_authentication',\r\n protocolElem: '#smtp_configuration_option_protocol',\r\n usernameElem: '#smtp_configuration_option_username',\r\n passwordElem: '#smtp_configuration_option_password',\r\n rerutnPathElem: '#smtp_configuration_option_return_path_email'\r\n },\r\n _create: function () {\r\n var self = this;\r\n\r\n $(this.options.testEmail).click(function (e) {\r\n e.preventDefault();\r\n if (self.element.val()) {\r\n self._ajaxSubmit();\r\n }\r\n });\r\n },\r\n\r\n _ajaxSubmit: function () {\r\n $.ajax({\r\n url: this.options.ajaxUrl,\r\n data: {\r\n from: $(this.options.fromEmailElem).val(),\r\n to: this.element.val(),\r\n host: $(this.options.hostElem).val(),\r\n port: $(this.options.portElem).val(),\r\n authentication: $(this.options.authenticationElem).val(),\r\n protocol: $(this.options.protocolElem).val(),\r\n username: $(this.options.usernameElem).val(),\r\n password: $(this.options.passwordElem).val(),\r\n returnpath: $(this.options.rerutnPathElem).val()\r\n },\r\n dataType: 'json',\r\n showLoader: true,\r\n success: function (result) {\r\n alert({\r\n title: result.status ? $t('Success') : $t('Error'),\r\n content: result.content\r\n });\r\n }\r\n });\r\n }\r\n });\r\n\r\n return $.mageplaza.testEmail;\r\n});\r\n","Mageplaza_Smtp/js/grid/columns/actions.js":"/**\n * Mageplaza\n *\n * NOTICE OF LICENSE\n *\n * This source file is subject to the Mageplaza.com license sliderConfig is\n * available through the world-wide-web at this URL:\n * https://www.mageplaza.com/LICENSE.txt\n *\n * DISCLAIMER\n *\n * Do not edit or add to this file if you wish to upgrade this extension to newer\n * version in the future.\n *\n * @category Mageplaza\n * @package Mageplaza_Smtp\n * @copyright Copyright (c) Mageplaza (http://www.mageplaza.com/)\n * @license https://www.mageplaza.com/LICENSE.txt\n */\n\ndefine([\n 'jquery',\n 'Magento_Ui/js/grid/columns/actions',\n 'Magento_Ui/js/modal/modal'\n], function ($, Column) {\n 'use strict';\n\n function strip(html){\n var doc = new DOMParser().parseFromString(html, 'text/html');\n\n return doc.body.textContent || \"\";\n }\n\n return Column.extend({\n modal: {},\n\n /**\n * @inheritDoc\n */\n defaultCallback: function (actionIndex, recordId, action) {\n if (actionIndex !== 'view') {\n return this._super();\n }\n\n if (typeof this.modal[action.rowIndex] === 'undefined' || typeof this.modal[action.rowIndex] === 'object') {\n var row = this.rows[action.rowIndex],\n modalHtml = '<iframe srcdoc=\"' + row['email_content'] + '\" style=\"width: 100%; height: 100%\"></iframe>';\n\n this.modal[action.rowIndex] = $('<div>')\n .html(modalHtml)\n .modal({\n type: 'slide',\n title: strip(row['subject']),\n modalClass: 'mpsmtp-modal-email',\n innerScroll: true,\n buttons: []\n });\n }\n\n this.modal[action.rowIndex].trigger('openModal');\n }\n });\n});\n\n","Mageplaza_Smtp/js/grid/columns/status.js":"/**\r\n * Mageplaza\r\n *\r\n * NOTICE OF LICENSE\r\n *\r\n * This source file is subject to the Mageplaza.com license sliderConfig is\r\n * available through the world-wide-web at this URL:\r\n * https://www.mageplaza.com/LICENSE.txt\r\n *\r\n * DISCLAIMER\r\n *\r\n * Do not edit or add to this file if you wish to upgrade this extension to newer\r\n * version in the future.\r\n *\r\n * @category Mageplaza\r\n * @package Mageplaza_Smtp\r\n * @copyright Copyright (c) Mageplaza (http://www.mageplaza.com/)\r\n * @license https://www.mageplaza.com/LICENSE.txt\r\n */\r\n\r\ndefine([\r\n 'Magento_Ui/js/grid/columns/select'\r\n], function (Column) {\r\n 'use strict';\r\n\r\n return Column.extend({\r\n defaults: {\r\n bodyTmpl: 'ui/grid/cells/html'\r\n },\r\n getLabel: function (record) {\r\n var label = this._super(record);\r\n\r\n if (label !== '') {\r\n if (record.status == 1) {\r\n label = '<span class=\"grid-severity-notice\"><span>' + label + '</span></span>';\r\n } else {\r\n label = '<span class=\"grid-severity-minor\"><span>' + label + '</span></span>';\r\n }\r\n }\r\n\r\n return label;\r\n }\r\n });\r\n});\r\n\r\n","Mageplaza_Smtp/js/sync/sync.js":"/**\n * Mageplaza\n *\n * NOTICE OF LICENSE\n *\n * This source file is subject to the Mageplaza.com license that is\n * available through the world-wide-web at this URL:\n * https://www.mageplaza.com/LICENSE.txt\n *\n * DISCLAIMER\n *\n * Do not edit or add to this file if you wish to upgrade this extension to newer\n * version in the future.\n *\n * @category Mageplaza\n * @package Mageplaza_Smtp\n * @copyright Copyright (c) Mageplaza (https://www.mageplaza.com/)\n * @license https://www.mageplaza.com/LICENSE.txt\n */\ndefine([\n 'jquery',\n 'Mageplaza_Smtp/js/model/sync'\n], function ($, Sync) {\n 'use strict';\n\n $.widget('mageplaza.sync', {\n options: {\n ajaxUrl: '',\n websiteId: '',\n storeId: '',\n estimateUrl: '',\n buttonElement: '#email_marketing_general_synchronization_sync',\n saveLog: '#email_marketing_general_synchronization_sync_log',\n prefix: '#mp-synchronize',\n console: '.email_marketing_general_synchronization_sync_console'\n },\n _create: function () {\n var self = this;\n\n $(this.options.buttonElement).click(function (e) {\n e.preventDefault();\n Sync.process(self.options);\n });\n\n $(this.options.saveLog).click(function (e) {\n e.preventDefault();\n Sync.saveLog(self.options.console);\n });\n },\n });\n\n return $.mageplaza.sync;\n});\n","Mageplaza_Smtp/js/model/sync.js":"/**\n * Mageplaza\n *\n * NOTICE OF LICENSE\n *\n * This source file is subject to the Mageplaza.com license that is\n * available through the world-wide-web at this URL:\n * https://www.mageplaza.com/LICENSE.txt\n *\n * DISCLAIMER\n *\n * Do not edit or add to this file if you wish to upgrade this extension to newer\n * version in the future.\n *\n * @category Mageplaza\n * @package Mageplaza_Smtp\n * @copyright Copyright (c) Mageplaza (https://www.mageplaza.com/)\n * @license https://www.mageplaza.com/LICENSE.txt\n */\n\ndefine([\n 'jquery',\n 'underscore',\n 'mage/translate'\n], function ($, _, $t) {\n \"use strict\";\n\n return {\n options: {},\n currentResult: {},\n totalSync: 0,\n\n /**\n * @param classCss\n * @param message\n */\n showMessage: function (classCss, message) {\n var messageElement = this.getElement(\".message\");\n\n messageElement.removeClass('message-error message-success message-notice');\n this.getElement(\".message-text strong\").text(message);\n messageElement.addClass(classCss).show();\n },\n\n /**\n * @param value\n * @returns {*|n.fn.init|r.fn.init|jQuery.fn.init|jQuery|HTMLElement}\n */\n getElement: function (value) {\n return $(this.options.prefix + ' ' + value);\n },\n\n /**\n * @param start\n * @param i\n */\n syncData: function (start, i) {\n var end = start + 100,\n ids = this.currentResult.ids.slice(start, end),\n self = this,\n createdFrom = $('#datepicker-from').val(),\n createdTo = $('#datepicker-to').val(),\n daysRange = $('#email_marketing_general_synchronization_days_range').val(),\n type = $('#email_marketing_general_synchronization_sync_type').val(),\n syncOptions = $('#email_marketing_general_synchronization_sync_options').val(),\n percent, percentText;\n\n $.ajax({\n url: this.options.ajaxUrl,\n type: 'post',\n dataType: 'json',\n data: {\n type: i ? i : type,\n syncOptions: syncOptions,\n ids: ids,\n from: createdFrom,\n to: createdTo,\n daysRange: daysRange\n },\n success: function (result) {\n var inputLog = self.getElement('#mp-log-data').val();\n\n inputLog += JSON.stringify(result.log) + '|';\n\n if (result.status) {\n percent = ids.length / self.currentResult.total * 100;\n self.totalSync += result.total;\n percent = percent.toFixed(2);\n\n self.currentResult.percent += parseFloat(percent);\n if (self.currentResult.percent > 100) {\n self.currentResult.percent = 100;\n }\n self.getElement('#mp-log-data').val(inputLog);\n self.getElement('#mp-console-log').val(self.formatLog(result.log, self));\n percentText = self.currentResult.percent.toFixed(2) + '%';\n if (percentText === '100.00%' || self.totalSync === self.currentResult.total) {\n percentText = '100%';\n $(self.options.buttonElement).removeClass('disabled');\n }\n\n self.getElement('.progress-bar').css('width', percentText);\n self.getElement('#sync-percent').text(\n percentText + ' (' + self.totalSync + '/' + self.currentResult.total + ')'\n );\n\n if (i && i >= 1 && i <= 3) {\n self.getElement('.progress-bar-' + i).css('width', percentText);\n self.getElement('#sync-percent-' + i).text(\n percentText + ' (' + self.totalSync + '/' + self.currentResult.total + ')'\n );\n }\n\n if (end < self.currentResult.total) {\n self.syncData(end, i);\n } else {\n self.getElement('.syncing').hide();\n if (type === 'all') {\n self.showMultiMessages('message message-success', self.options.successMessage[i]);\n } else {\n self.showMessage('message-success', self.options.successMessage[type]);\n }\n if (i !== null) {\n self.estimateSyncAll(i + 1, syncOptions, createdFrom, createdTo, daysRange);\n }\n }\n } else {\n self.getElement('#mp-console-log').val(self.formatLog(result.log, self));\n self.getElement('#mp-log-data').val(inputLog);\n if (type === 'all') {\n self.showMultiMessages('message message-error', result.message);\n } else {\n self.showMessage('message-error', result.message);\n }\n $(self.options.buttonElement).removeClass('disabled');\n }\n }\n });\n },\n\n formatLog: function (log, self) {\n var rs = self.getElement('#mp-console-log').val();\n\n rs += log.message + '\\n';\n\n _.each(log.data, function (item, index) {\n if (index === 'success') {\n rs += ($t('Success: ') + item + '\\n')\n }\n\n if (index === 'error') {\n rs += ($t('Error: ') + item + '\\n')\n }\n\n if (index === 'error_details') {\n _.each(item, function (detail) {\n rs += ($t('Item ID: ' + detail.id + '\\n'))\n rs += ($t('Error: ' + detail.message + '\\n\\n'))\n })\n }\n });\n\n return rs;\n },\n\n /**\n * @param options\n */\n process: function (options) {\n var self = this,\n type = $('#email_marketing_general_synchronization_sync_type').val(),\n syncOptions = $('#email_marketing_general_synchronization_sync_options').val(),\n createdFrom = $('#datepicker-from').val(),\n createdTo = $('#datepicker-to').val(),\n daysRange = $('#email_marketing_general_synchronization_days_range').val();\n\n options.buttonElement = '#email_marketing_general_synchronization button';\n this.options = options;\n this.currentResult = {};\n\n self.getElement('.progress-content').hide();\n\n if (type !== 'all') {\n self.estimateSync(type, syncOptions, createdFrom, createdTo, daysRange);\n } else {\n self.getElement('#mp-console-log').val('');\n self.getElement('#mp-log-data').val('');\n self.estimateSyncAll(null, syncOptions, createdFrom, createdTo, daysRange);\n }\n },\n\n estimateSync: function (type, syncOptions, createdFrom, createdTo, daysRange) {\n var self = this;\n\n $.ajax({\n url: this.options.estimateUrl,\n data: {\n websiteId: this.options.websiteId,\n storeId: this.options.storeId,\n type: type,\n syncOptions: syncOptions,\n from: createdFrom,\n to: createdTo,\n daysRange: daysRange\n },\n dataType: 'json',\n showLoader: true,\n success: function (result) {\n window.onbeforeunload = (e) => {\n e.preventDefault();\n e.returnValue = $t('Changes you made may not be saved.');\n };\n\n self.getElement('.multi-messages').hide();\n\n if (result.status) {\n self.currentResult = result;\n self.getElement('.message').hide();\n if (self.currentResult.total > 0) {\n self.getElement('#console-log').show();\n }\n self.getElement('#mp-console-log').val('');\n self.getElement('#mp-log-data').val('');\n\n if (self.currentResult.total > 0) {\n self.getElement('#sync-percent').text('0%');\n self.getElement('.progress-bar').removeAttr('style');\n self.currentResult.percent = 0;\n self.getElement('#progress-content').show();\n self.totalSync = 0;\n self.getElement('.syncing').hide();\n self.getElement('#syncing').show();\n $(self.options.buttonElement).addClass('disabled');\n self.syncData(0, null);\n } else {\n self.showMessage('message-notice', result.message);\n $(self.options.buttonElement).removeClass('disabled');\n self.getElement('#progress-content').hide();\n }\n } else {\n self.showMessage('message-error', result.message);\n $(self.options.buttonElement).removeClass('disabled');\n self.getElement('#progress-content').hide();\n }\n }\n });\n },\n\n estimateSyncAll: function (i = null, syncOptions, createdFrom, createdTo, daysRange) {\n var self = this;\n\n if (i === null) {\n self.getElement('.multi-messages').html('');\n i = 1;\n }\n\n if (i <= 3) {\n $.ajax({\n url: this.options.estimateUrl,\n data: {\n websiteId: this.options.websiteId,\n storeId: this.options.storeId,\n type: i,\n syncOptions: syncOptions,\n from: createdFrom,\n to: createdTo,\n daysRange: daysRange\n },\n dataType: 'json',\n showLoader: true,\n success: function (result) {\n window.onbeforeunload = (e) => {\n e.preventDefault();\n e.returnValue = $t('Changes you made may not be saved.');\n };\n\n if (result.status) {\n self.currentResult = result;\n self.getElement('.message').hide();\n self.getElement('.multi-messages').show();\n self.getElement('.multi-messages .message').show();\n if (self.currentResult.total > 0) {\n self.getElement('#console-log').show();\n }\n\n if (self.currentResult.total > 0) {\n self.getElement('#sync-percent-' + i).text('0%');\n self.getElement('.progress-bar-' + i).removeAttr('style');\n self.currentResult.percent = 0;\n self.getElement('#progress-content-' + i).show();\n self.totalSync = 0;\n self.getElement('.syncing').hide();\n self.getElement('#syncing-' + i).show();\n $(self.options.buttonElement).addClass('disabled');\n self.syncData(0, i);\n } else {\n self.showMultiMessages('message message-notice', result.message);\n $(self.options.buttonElement).removeClass('disabled');\n self.getElement('#progress-content-' + i).hide();\n self.estimateSyncAll(i + 1, syncOptions, createdFrom, createdTo, daysRange);\n }\n } else {\n self.showMultiMessages('message message-error', result.message);\n $(self.options.buttonElement).removeClass('disabled');\n self.getElement('#progress-content-' + i).hide();\n }\n }\n });\n }\n },\n\n showMultiMessages: function (classCss, message) {\n var messageElement = this.getElement('.multi-messages'),\n html = '<div class=\"' + classCss + '\"><span class=\"message-text\"><strong>'\n + message + '</strong></span><br></div>';\n\n messageElement.append(html);\n messageElement.find('.message').show();\n },\n\n saveLog: function (console) {\n var log = $(console).val(),\n content = 'status,message,success,error,detail' + '\\n',\n arrLog = log.split('|');\n\n _.each(arrLog, function (item) {\n if (item) {\n var data = JSON.parse(item),\n detail = '';\n\n content += data.success + ',' + data.message + ',' + data.data.success + ',' + data.data.error + ',';\n _.each(data.data.error_details, function (error) {\n if (error) {\n detail += JSON.stringify(error) + '\\n';\n }\n });\n var newDetail = detail.replace(',', ';');\n newDetail = newDetail.replace(/['\"]+/g, '');\n content += '\"' + newDetail + '\"' + '\\n';\n }\n });\n\n var hiddenElement = document.createElement('a');\n hiddenElement.href = 'data:text/csv;charset=utf-8,' + encodeURI(content);\n hiddenElement.target = '_blank';\n hiddenElement.download = 'mp-console-log.csv';\n hiddenElement.click();\n }\n };\n});\n","Magento_Swatches/js/swatch-renderer.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'jquery',\n 'underscore',\n 'mage/template',\n 'mage/smart-keyboard-handler',\n 'mage/translate',\n 'priceUtils',\n 'jquery-ui-modules/widget',\n 'jquery/jquery.parsequery',\n 'mage/validation/validation'\n], function ($, _, mageTemplate, keyboardHandler, $t, priceUtils) {\n 'use strict';\n\n /**\n * Extend form validation to support swatch accessibility\n */\n $.widget('mage.validation', $.mage.validation, {\n /**\n * Handle form with swatches validation. Focus on first invalid swatch block.\n *\n * @param {jQuery.Event} event\n * @param {Object} validation\n */\n listenFormValidateHandler: function (event, validation) {\n var swatchWrapper, firstActive, swatches, swatch, successList, errorList, firstSwatch;\n\n this._superApply(arguments);\n\n swatchWrapper = '.swatch-attribute-options';\n swatches = $(event.target).find(swatchWrapper);\n\n if (!swatches.length) {\n return;\n }\n\n swatch = '.swatch-attribute';\n firstActive = $(validation.errorList[0].element || []);\n successList = validation.successList;\n errorList = validation.errorList;\n firstSwatch = $(firstActive).parent(swatch).find(swatchWrapper);\n\n keyboardHandler.focus(swatches);\n\n $.each(successList, function (index, item) {\n $(item).parent(swatch).find(swatchWrapper).attr('aria-invalid', false);\n });\n\n $.each(errorList, function (index, item) {\n $(item.element).parent(swatch).find(swatchWrapper).attr('aria-invalid', true);\n });\n\n if (firstSwatch.length) {\n $(firstSwatch).trigger('focus');\n }\n }\n });\n\n /**\n * Render tooltips by attributes (only to up).\n * Required element attributes:\n * - data-option-type (integer, 0-3)\n * - data-option-label (string)\n * - data-option-tooltip-thumb\n * - data-option-tooltip-value\n * - data-thumb-width\n * - data-thumb-height\n */\n $.widget('mage.SwatchRendererTooltip', {\n options: {\n delay: 200, //how much ms before tooltip to show\n tooltipClass: 'swatch-option-tooltip' //configurable, but remember about css\n },\n\n /**\n * @private\n */\n _init: function () {\n var $widget = this,\n $this = this.element,\n $element = $('.' + $widget.options.tooltipClass),\n timer,\n type = parseInt($this.data('option-type'), 10),\n label = $this.data('option-label'),\n thumb = $this.data('option-tooltip-thumb'),\n value = $this.data('option-tooltip-value'),\n width = $this.data('thumb-width'),\n height = $this.data('thumb-height'),\n $image,\n $title,\n $corner;\n\n if (!$element.length) {\n $element = $('<div class=\"' +\n $widget.options.tooltipClass +\n '\"><div class=\"image\"></div><div class=\"title\"></div><div class=\"corner\"></div></div>'\n );\n $('body').append($element);\n }\n\n $image = $element.find('.image');\n $title = $element.find('.title');\n $corner = $element.find('.corner');\n\n $this.on('mouseenter', function () {\n if (!$this.hasClass('disabled')) {\n timer = setTimeout(\n function () {\n var leftOpt = null,\n leftCorner = 0,\n left,\n $window;\n\n if (type === 2) {\n // Image\n $image.css({\n 'background': 'url(\"' + thumb + '\") no-repeat center', //Background case\n 'background-size': 'initial',\n 'width': width + 'px',\n 'height': height + 'px'\n });\n $image.show();\n } else if (type === 1) {\n // Color\n $image.css({\n background: value\n });\n $image.show();\n } else if (type === 0 || type === 3) {\n // Default\n $image.hide();\n }\n\n $title.text(label);\n\n leftOpt = $this.offset().left;\n left = leftOpt + $this.width() / 2 - $element.width() / 2;\n $window = $(window);\n\n // the numbers (5 and 5) is magick constants for offset from left or right page\n if (left < 0) {\n left = 5;\n } else if (left + $element.width() > $window.width()) {\n left = $window.width() - $element.width() - 5;\n }\n\n // the numbers (6, 3 and 18) is magick constants for offset tooltip\n leftCorner = 0;\n\n if ($element.width() < $this.width()) {\n leftCorner = $element.width() / 2 - 3;\n } else {\n leftCorner = (leftOpt > left ? leftOpt - left : left - leftOpt) + $this.width() / 2 - 6;\n }\n\n $corner.css({\n left: leftCorner\n });\n $element.css({\n left: left,\n top: $this.offset().top - $element.height() - $corner.height() - 18\n }).show();\n },\n $widget.options.delay\n );\n }\n });\n\n $this.on('mouseleave', function () {\n $element.hide();\n clearTimeout(timer);\n });\n\n $(document).on('tap', function () {\n $element.hide();\n clearTimeout(timer);\n });\n\n $this.on('tap', function (event) {\n event.stopPropagation();\n });\n }\n });\n\n /**\n * Render swatch controls with options and use tooltips.\n * Required two json:\n * - jsonConfig (magento's option config)\n * - jsonSwatchConfig (swatch's option config)\n *\n * Tuning:\n * - numberToShow (show \"more\" button if options are more)\n * - onlySwatches (hide selectboxes)\n * - moreButtonText (text for \"more\" button)\n * - selectorProduct (selector for product container)\n * - selectorProductPrice (selector for change price)\n */\n $.widget('mage.SwatchRenderer', {\n options: {\n classes: {\n attributeClass: 'swatch-attribute',\n attributeLabelClass: 'swatch-attribute-label',\n attributeSelectedOptionLabelClass: 'swatch-attribute-selected-option',\n attributeOptionsWrapper: 'swatch-attribute-options',\n attributeInput: 'swatch-input',\n optionClass: 'swatch-option',\n selectClass: 'swatch-select',\n moreButton: 'swatch-more',\n loader: 'swatch-option-loading'\n },\n // option's json config\n jsonConfig: {},\n\n // swatch's json config\n jsonSwatchConfig: {},\n\n // selector of parental block of prices and swatches (need to know where to seek for price block)\n selectorProduct: '.product-info-main',\n\n // selector of price wrapper (need to know where set price)\n selectorProductPrice: '[data-role=priceBox]',\n\n //selector of product images gallery wrapper\n mediaGallerySelector: '[data-gallery-role=gallery-placeholder]',\n\n // selector of category product tile wrapper\n selectorProductTile: '.product-item',\n\n // number of controls to show (false or zero = show all)\n numberToShow: false,\n\n // show only swatch controls\n onlySwatches: false,\n\n // enable label for control\n enableControlLabel: true,\n\n // control label id\n controlLabelId: '',\n\n // text for more button\n moreButtonText: $t('More'),\n\n // Callback url for media\n mediaCallback: '',\n\n // Local media cache\n mediaCache: {},\n\n // Cache for BaseProduct images. Needed when option unset\n mediaGalleryInitial: [{}],\n\n // Use ajax to get image data\n useAjax: false,\n\n /**\n * Defines the mechanism of how images of a gallery should be\n * updated when user switches between configurations of a product.\n *\n * As for now value of this option can be either 'replace' or 'prepend'.\n *\n * @type {String}\n */\n gallerySwitchStrategy: 'replace',\n\n // whether swatches are rendered in product list or on product page\n inProductList: false,\n\n // sly-old-price block selector\n slyOldPriceSelector: '.sly-old-price',\n\n // tier prise selectors start\n tierPriceTemplateSelector: '#tier-prices-template',\n tierPriceBlockSelector: '[data-role=\"tier-price-block\"]',\n tierPriceTemplate: '',\n // tier prise selectors end\n\n // A price label selector\n normalPriceLabelSelector: '.normal-price .price-label',\n qtyInfo: '#qty'\n },\n\n /**\n * Get chosen product\n *\n * @returns int|null\n */\n getProduct: function () {\n var products = this._CalcProducts();\n\n return _.isArray(products) ? products[0] : null;\n },\n\n /**\n * Get chosen product id\n *\n * @returns int|null\n */\n getProductId: function () {\n var products = this._CalcProducts();\n\n return _.isArray(products) && products.length === 1 ? products[0] : null;\n },\n\n /**\n * @private\n */\n _init: function () {\n // Don't render the same set of swatches twice\n if ($(this.element).attr('data-rendered')) {\n return;\n }\n\n $(this.element).attr('data-rendered', true);\n\n if (_.isEmpty(this.options.jsonConfig.images)) {\n this.options.useAjax = true;\n // creates debounced variant of _LoadProductMedia()\n // to use it in events handlers instead of _LoadProductMedia()\n this._debouncedLoadProductMedia = _.debounce(this._LoadProductMedia.bind(this), 500);\n }\n\n this.options.tierPriceTemplate = $(this.options.tierPriceTemplateSelector).html();\n\n if (this.options.jsonConfig !== '' && this.options.jsonSwatchConfig !== '') {\n // store unsorted attributes\n this.options.jsonConfig.mappedAttributes = _.clone(this.options.jsonConfig.attributes);\n this._sortAttributes();\n this._RenderControls();\n this._setPreSelectedGallery();\n $(this.element).trigger('swatch.initialized');\n } else {\n console.log('SwatchRenderer: No input data received');\n }\n },\n\n /**\n * @private\n */\n _sortAttributes: function () {\n this.options.jsonConfig.attributes = _.sortBy(this.options.jsonConfig.attributes, function (attribute) {\n return parseInt(attribute.position, 10);\n });\n },\n\n /**\n * @private\n */\n _create: function () {\n var options = this.options,\n gallery = $('[data-gallery-role=gallery-placeholder]', '.column.main'),\n productData = this._determineProductData(),\n $main = productData.isInProductView ?\n this.element.parents('.column.main') :\n this.element.parents('.product-item-info');\n\n if (productData.isInProductView) {\n gallery.data('gallery') ?\n this._onGalleryLoaded(gallery) :\n gallery.on('gallery:loaded', this._onGalleryLoaded.bind(this, gallery));\n } else {\n options.mediaGalleryInitial = [{\n 'img': $main.find('.product-image-photo').attr('src')\n }];\n }\n\n this.productForm = this.element.parents(this.options.selectorProductTile).find('form:first');\n this.inProductList = this.productForm.length > 0;\n $(this.options.qtyInfo).on('input', this._onQtyChanged.bind(this));\n },\n\n /**\n * Determine product id and related data\n *\n * @returns {{productId: *, isInProductView: bool}}\n * @private\n */\n _determineProductData: function () {\n // Check if product is in a list of products.\n var productId,\n isInProductView = false;\n\n productId = this.element.parents('.product-item-details')\n .find('.price-box.price-final_price').attr('data-product-id');\n\n if (!productId) {\n // Check individual product.\n productId = $('[name=product]').val();\n isInProductView = productId > 0;\n }\n\n return {\n productId: productId,\n isInProductView: isInProductView\n };\n },\n\n /**\n * Render controls\n *\n * @private\n */\n _RenderControls: function () {\n var $widget = this,\n container = this.element,\n classes = this.options.classes,\n chooseText = this.options.jsonConfig.chooseText,\n showTooltip = this.options.showTooltip;\n\n $widget.optionsMap = {};\n\n $.each(this.options.jsonConfig.attributes, function () {\n var item = this,\n controlLabelId = 'option-label-' + item.code + '-' + item.id,\n options = $widget._RenderSwatchOptions(item, controlLabelId),\n select = $widget._RenderSwatchSelect(item, chooseText),\n input = $widget._RenderFormInput(item),\n listLabel = '',\n label = '';\n\n // Show only swatch controls\n if ($widget.options.onlySwatches && !$widget.options.jsonSwatchConfig.hasOwnProperty(item.id)) {\n return;\n }\n\n if ($widget.options.enableControlLabel) {\n label +=\n '<span id=\"' + controlLabelId + '\" class=\"' + classes.attributeLabelClass + '\">' +\n $('<i></i>').text(item.label).html() +\n '</span>' +\n '<span class=\"' + classes.attributeSelectedOptionLabelClass + '\"></span>';\n }\n\n if ($widget.inProductList) {\n $widget.productForm.append(input);\n input = '';\n listLabel = 'aria-label=\"' + $('<i></i>').text(item.label).html() + '\"';\n } else {\n listLabel = 'aria-labelledby=\"' + controlLabelId + '\"';\n }\n\n // Create new control\n container.append(\n '<div class=\"' + classes.attributeClass + ' ' + item.code + '\" ' +\n 'data-attribute-code=\"' + item.code + '\" ' +\n 'data-attribute-id=\"' + item.id + '\">' +\n label +\n '<div aria-activedescendant=\"\" ' +\n 'tabindex=\"0\" ' +\n 'aria-invalid=\"false\" ' +\n 'aria-required=\"true\" ' +\n 'role=\"listbox\" ' + listLabel +\n 'class=\"' + classes.attributeOptionsWrapper + ' clearfix\">' +\n options + select +\n '</div>' + input +\n '</div>'\n );\n\n $widget.optionsMap[item.id] = {};\n\n // Aggregate options array to hash (key => value)\n $.each(item.options, function () {\n if (this.products.length > 0) {\n let salableProducts = this.products;\n\n if ($widget.options.jsonConfig.canDisplayShowOutOfStockStatus) {\n salableProducts = $widget.options.jsonConfig.salable[item.id][this.id];\n }\n $widget.optionsMap[item.id][this.id] = {\n price: parseInt(\n $widget.options.jsonConfig.optionPrices[this.products[0]].finalPrice.amount,\n 10\n ),\n products: salableProducts\n };\n }\n });\n });\n\n if (showTooltip === 1) {\n // Connect Tooltip\n container\n .find('[data-option-type=\"1\"], [data-option-type=\"2\"],' +\n ' [data-option-type=\"0\"], [data-option-type=\"3\"]')\n .SwatchRendererTooltip();\n }\n\n // Hide all elements below more button\n $('.' + classes.moreButton).nextAll().hide();\n\n // Handle events like click or change\n $widget._EventListener();\n\n // Rewind options\n $widget._Rewind(container);\n\n //Emulate click on all swatches from Request\n $widget._EmulateSelected($.parseQuery());\n $widget._EmulateSelected($widget._getSelectedAttributes());\n },\n\n disableSwatchForOutOfStockProducts: function () {\n let $widget = this, container = this.element;\n\n $.each(this.options.jsonConfig.attributes, function () {\n let item = this;\n\n if ($widget.options.jsonConfig.canDisplayShowOutOfStockStatus) {\n let salableProducts = $widget.options.jsonConfig.salable[item.id],\n swatchOptions = $(container).find(`[data-attribute-id='${item.id}']`).find('.swatch-option');\n\n swatchOptions.each(function (key, value) {\n let optionId = $(value).data('option-id');\n\n if (!salableProducts.hasOwnProperty(optionId)) {\n $(value).attr('disabled', true).addClass('disabled');\n }\n });\n }\n });\n },\n\n /**\n * Render swatch options by part of config\n *\n * @param {Object} config\n * @param {String} controlId\n * @returns {String}\n * @private\n */\n _RenderSwatchOptions: function (config, controlId) {\n var optionConfig = this.options.jsonSwatchConfig[config.id],\n optionClass = this.options.classes.optionClass,\n sizeConfig = this.options.jsonSwatchImageSizeConfig,\n moreLimit = parseInt(this.options.numberToShow, 10),\n moreClass = this.options.classes.moreButton,\n moreText = this.options.moreButtonText,\n countAttributes = 0,\n html = '';\n\n if (!this.options.jsonSwatchConfig.hasOwnProperty(config.id)) {\n return '';\n }\n\n $.each(config.options, function (index) {\n var id,\n type,\n value,\n thumb,\n label,\n width,\n height,\n attr,\n swatchImageWidth,\n swatchImageHeight;\n\n if (!optionConfig.hasOwnProperty(this.id)) {\n return '';\n }\n\n // Add more button\n if (moreLimit === countAttributes++) {\n html += '<a href=\"#\" class=\"' + moreClass + '\"><span>' + moreText + '</span></a>';\n }\n\n id = this.id;\n type = parseInt(optionConfig[id].type, 10);\n value = optionConfig[id].hasOwnProperty('value') ?\n $('<i></i>').text(optionConfig[id].value).html() : '';\n thumb = optionConfig[id].hasOwnProperty('thumb') ? optionConfig[id].thumb : '';\n width = _.has(sizeConfig, 'swatchThumb') ? sizeConfig.swatchThumb.width : 110;\n height = _.has(sizeConfig, 'swatchThumb') ? sizeConfig.swatchThumb.height : 90;\n label = this.label ? $('<i></i>').text(this.label).html() : '';\n attr =\n ' id=\"' + controlId + '-item-' + id + '\"' +\n ' index=\"' + index + '\"' +\n ' aria-checked=\"false\"' +\n ' aria-describedby=\"' + controlId + '\"' +\n ' tabindex=\"0\"' +\n ' data-option-type=\"' + type + '\"' +\n ' data-option-id=\"' + id + '\"' +\n ' data-option-label=\"' + label + '\"' +\n ' aria-label=\"' + label + '\"' +\n ' role=\"option\"' +\n ' data-thumb-width=\"' + width + '\"' +\n ' data-thumb-height=\"' + height + '\"';\n\n attr += thumb !== '' ? ' data-option-tooltip-thumb=\"' + thumb + '\"' : '';\n attr += value !== '' ? ' data-option-tooltip-value=\"' + value + '\"' : '';\n\n swatchImageWidth = _.has(sizeConfig, 'swatchImage') ? sizeConfig.swatchImage.width : 30;\n swatchImageHeight = _.has(sizeConfig, 'swatchImage') ? sizeConfig.swatchImage.height : 20;\n\n if (!this.hasOwnProperty('products') || this.products.length <= 0) {\n attr += ' data-option-empty=\"true\"';\n }\n\n if (type === 0) {\n // Text\n html += '<div class=\"' + optionClass + ' text\" ' + attr + '>' + (value ? value : label) +\n '</div>';\n } else if (type === 1) {\n // Color\n html += '<div class=\"' + optionClass + ' color\" ' + attr +\n ' style=\"background: ' + value +\n ' no-repeat center; background-size: initial;\">' + '' +\n '</div>';\n } else if (type === 2) {\n // Image\n html += '<div class=\"' + optionClass + ' image\" ' + attr +\n ' style=\"background: url(' + value + ') no-repeat center; background-size: initial;width:' +\n swatchImageWidth + 'px; height:' + swatchImageHeight + 'px\">' + '' +\n '</div>';\n } else if (type === 3) {\n // Clear\n html += '<div class=\"' + optionClass + '\" ' + attr + '></div>';\n } else {\n // Default\n html += '<div class=\"' + optionClass + '\" ' + attr + '>' + label + '</div>';\n }\n });\n\n return html;\n },\n\n /**\n * Render select by part of config\n *\n * @param {Object} config\n * @param {String} chooseText\n * @returns {String}\n * @private\n */\n _RenderSwatchSelect: function (config, chooseText) {\n var html;\n\n if (this.options.jsonSwatchConfig.hasOwnProperty(config.id)) {\n return '';\n }\n\n html =\n '<select class=\"' + this.options.classes.selectClass + ' ' + config.code + '\">' +\n '<option value=\"0\" data-option-id=\"0\">' + chooseText + '</option>';\n\n $.each(config.options, function () {\n var label = this.label,\n attr = ' value=\"' + this.id + '\" data-option-id=\"' + this.id + '\"';\n\n if (!this.hasOwnProperty('products') || this.products.length <= 0) {\n attr += ' data-option-empty=\"true\"';\n }\n\n html += '<option ' + attr + '>' + label + '</option>';\n });\n\n html += '</select>';\n\n return html;\n },\n\n /**\n * Input for submit form.\n * This control shouldn't have \"type=hidden\", \"display: none\" for validation work :(\n *\n * @param {Object} config\n * @private\n */\n _RenderFormInput: function (config) {\n return '<input class=\"' + this.options.classes.attributeInput + ' super-attribute-select\" ' +\n 'name=\"super_attribute[' + config.id + ']\" ' +\n 'type=\"text\" ' +\n 'value=\"\" ' +\n 'data-selector=\"super_attribute[' + config.id + ']\" ' +\n 'data-validate=\"{required: true}\" ' +\n 'aria-required=\"true\" ' +\n 'aria-invalid=\"false\">';\n },\n\n /**\n * Event listener\n *\n * @private\n */\n _EventListener: function () {\n var $widget = this,\n options = this.options.classes,\n target;\n\n $widget.element.on('click', '.' + options.optionClass, function () {\n return $widget._OnClick($(this), $widget);\n });\n\n $widget.element.on('change', '.' + options.selectClass, function () {\n return $widget._OnChange($(this), $widget);\n });\n\n $widget.element.on('click', '.' + options.moreButton, function (e) {\n e.preventDefault();\n\n return $widget._OnMoreClick($(this));\n });\n\n $widget.element.on('keydown', function (e) {\n if (e.which === 13) {\n target = $(e.target);\n\n if (target.is('.' + options.optionClass)) {\n return $widget._OnClick(target, $widget);\n } else if (target.is('.' + options.selectClass)) {\n return $widget._OnChange(target, $widget);\n } else if (target.is('.' + options.moreButton)) {\n e.preventDefault();\n\n return $widget._OnMoreClick(target);\n }\n }\n });\n },\n\n /**\n * Load media gallery using ajax or json config.\n *\n * @private\n */\n _loadMedia: function () {\n var $main = this.inProductList ?\n this.element.parents('.product-item-info') :\n this.element.parents('.column.main'),\n images;\n\n if (this.options.useAjax) {\n this._debouncedLoadProductMedia();\n } else {\n images = this.options.jsonConfig.images[this.getProduct()];\n\n if (!images) {\n images = this.options.mediaGalleryInitial;\n }\n this.updateBaseImage(this._sortImages(images), $main, !this.inProductList);\n }\n },\n\n /**\n * Sorting images array\n *\n * @private\n */\n _sortImages: function (images) {\n return _.sortBy(images, function (image) {\n return parseInt(image.position, 10);\n });\n },\n\n /**\n * Event for swatch options\n *\n * @param {Object} $this\n * @param {Object} $widget\n * @private\n */\n _OnClick: function ($this, $widget) {\n var $parent = $this.parents('.' + $widget.options.classes.attributeClass),\n $wrapper = $this.parents('.' + $widget.options.classes.attributeOptionsWrapper),\n $label = $parent.find('.' + $widget.options.classes.attributeSelectedOptionLabelClass),\n attributeId = $parent.data('attribute-id'),\n $input = $parent.find('.' + $widget.options.classes.attributeInput),\n checkAdditionalData = JSON.parse(this.options.jsonSwatchConfig[attributeId]['additional_data']),\n $priceBox = $widget.element.parents($widget.options.selectorProduct)\n .find(this.options.selectorProductPrice);\n\n if ($widget.inProductList) {\n $input = $widget.productForm.find(\n '.' + $widget.options.classes.attributeInput + '[name=\"super_attribute[' + attributeId + ']\"]'\n );\n }\n\n if ($this.hasClass('disabled')) {\n return;\n }\n\n if ($this.hasClass('selected')) {\n $parent.removeAttr('data-option-selected').find('.selected').removeClass('selected');\n $input.val('');\n $label.text('');\n $this.attr('aria-checked', false);\n } else {\n $parent.attr('data-option-selected', $this.data('option-id')).find('.selected').removeClass('selected');\n $label.text($this.data('option-label'));\n $input.val($this.data('option-id'));\n $input.attr('data-attr-name', this._getAttributeCodeById(attributeId));\n $this.addClass('selected');\n $widget._toggleCheckedAttributes($this, $wrapper);\n }\n\n $widget._Rebuild();\n\n if ($priceBox.is(':data(mage-priceBox)')) {\n $widget._UpdatePrice();\n }\n\n $(document).trigger('updateMsrpPriceBlock',\n [\n this._getSelectedOptionPriceIndex(),\n $widget.options.jsonConfig.optionPrices,\n $priceBox\n ]);\n\n if (parseInt(checkAdditionalData['update_product_preview_image'], 10) === 1) {\n $widget._loadMedia();\n }\n\n $input.trigger('change');\n },\n\n /**\n * Get selected option price index\n *\n * @return {String|undefined}\n * @private\n */\n _getSelectedOptionPriceIndex: function () {\n var allowedProduct = this._getAllowedProductWithMinPrice(this._CalcProducts());\n\n if (_.isEmpty(allowedProduct)) {\n return undefined;\n }\n\n return allowedProduct;\n },\n\n /**\n * Get human readable attribute code (eg. size, color) by it ID from configuration\n *\n * @param {Number} attributeId\n * @returns {*}\n * @private\n */\n _getAttributeCodeById: function (attributeId) {\n var attribute = this.options.jsonConfig.mappedAttributes[attributeId];\n\n return attribute ? attribute.code : attributeId;\n },\n\n /**\n * Toggle accessibility attributes\n *\n * @param {Object} $this\n * @param {Object} $wrapper\n * @private\n */\n _toggleCheckedAttributes: function ($this, $wrapper) {\n $wrapper.attr('aria-activedescendant', $this.attr('id'))\n .find('.' + this.options.classes.optionClass).attr('aria-checked', false);\n $this.attr('aria-checked', true);\n },\n\n /**\n * Event for select\n *\n * @param {Object} $this\n * @param {Object} $widget\n * @private\n */\n _OnChange: function ($this, $widget) {\n var $parent = $this.parents('.' + $widget.options.classes.attributeClass),\n attributeId = $parent.data('attribute-id'),\n $input = $parent.find('.' + $widget.options.classes.attributeInput);\n\n if ($widget.productForm.length > 0) {\n $input = $widget.productForm.find(\n '.' + $widget.options.classes.attributeInput + '[name=\"super_attribute[' + attributeId + ']\"]'\n );\n }\n\n if ($this.val() > 0) {\n $parent.attr('data-option-selected', $this.val());\n $input.val($this.val());\n } else {\n $parent.removeAttr('data-option-selected');\n $input.val('');\n }\n\n $widget._Rebuild();\n $widget._UpdatePrice();\n $widget._loadMedia();\n $input.trigger('change');\n },\n\n /**\n * Event for more switcher\n *\n * @param {Object} $this\n * @private\n */\n _OnMoreClick: function ($this) {\n $this.nextAll().show();\n $this.trigger('blur').remove();\n },\n\n /**\n * Rewind options for controls\n *\n * @private\n */\n _Rewind: function (controls) {\n controls.find('div[data-option-id], option[data-option-id]')\n .removeClass('disabled')\n .prop('disabled', false);\n controls.find('div[data-option-empty], option[data-option-empty]')\n .attr('disabled', true)\n .addClass('disabled')\n .attr('tabindex', '-1');\n this.disableSwatchForOutOfStockProducts();\n },\n\n /**\n * Rebuild container\n *\n * @private\n */\n _Rebuild: function () {\n var $widget = this,\n controls = $widget.element.find('.' + $widget.options.classes.attributeClass + '[data-attribute-id]'),\n selected = controls.filter('[data-option-selected]');\n\n // Enable all options\n $widget._Rewind(controls);\n\n // done if nothing selected\n if (selected.length <= 0) {\n return;\n }\n\n // Disable not available options\n controls.each(function () {\n var $this = $(this),\n id = $this.data('attribute-id'),\n products = $widget._CalcProducts(id);\n\n if (selected.length === 1 && selected.first().data('attribute-id') === id) {\n return;\n }\n\n $this.find('[data-option-id]').each(function () {\n var $element = $(this),\n option = $element.data('option-id');\n\n if (!$widget.optionsMap.hasOwnProperty(id) || !$widget.optionsMap[id].hasOwnProperty(option) ||\n $element.hasClass('selected') ||\n $element.is(':selected')) {\n return;\n }\n\n if (_.intersection(products, $widget.optionsMap[id][option].products).length <= 0) {\n $element.attr('disabled', true).addClass('disabled');\n }\n });\n });\n },\n\n /**\n * Get selected product list\n *\n * @returns {Array}\n * @private\n */\n _CalcProducts: function ($skipAttributeId) {\n var $widget = this,\n selectedOptions = '.' + $widget.options.classes.attributeClass + '[data-option-selected]',\n products = [];\n\n // Generate intersection of products\n $widget.element.find(selectedOptions).each(function () {\n var id = $(this).data('attribute-id'),\n option = $(this).attr('data-option-selected');\n\n if ($skipAttributeId !== undefined && $skipAttributeId === id) {\n return;\n }\n\n if (!$widget.optionsMap.hasOwnProperty(id) || !$widget.optionsMap[id].hasOwnProperty(option)) {\n return;\n }\n\n if (products.length === 0) {\n products = $widget.optionsMap[id][option].products;\n } else {\n products = _.intersection(products, $widget.optionsMap[id][option].products);\n }\n });\n\n return products;\n },\n\n /**\n * Update total price\n *\n * @private\n */\n _UpdatePrice: function () {\n var $widget = this,\n $product = $widget.element.parents($widget.options.selectorProduct),\n $productPrice = $product.find(this.options.selectorProductPrice),\n result = $widget._getNewPrices(),\n tierPriceHtml,\n isShow;\n\n $productPrice.trigger(\n 'updatePrice',\n {\n 'prices': $widget._getPrices(result, $productPrice.priceBox('option').prices)\n }\n );\n\n isShow = typeof result != 'undefined' && result.oldPrice.amount !== result.finalPrice.amount;\n\n $productPrice.find('span:first').toggleClass('special-price', isShow);\n\n $product.find(this.options.slyOldPriceSelector)[isShow ? 'show' : 'hide']();\n\n if (typeof result != 'undefined' && result.tierPrices && result.tierPrices.length) {\n if (this.options.tierPriceTemplate) {\n tierPriceHtml = mageTemplate(\n this.options.tierPriceTemplate,\n {\n 'tierPrices': result.tierPrices,\n '$t': $t,\n 'currencyFormat': this.options.jsonConfig.currencyFormat,\n 'priceUtils': priceUtils\n }\n );\n $(this.options.tierPriceBlockSelector).html(tierPriceHtml).show();\n }\n } else {\n $(this.options.tierPriceBlockSelector).hide();\n }\n\n $product.find(this.options.normalPriceLabelSelector).hide();\n\n _.each(this.element.find('.' + this.options.classes.attributeOptionsWrapper), function (attribute) {\n if ($(attribute).find('.' + this.options.classes.optionClass + '.selected').length === 0) {\n if ($(attribute).find('.' + this.options.classes.selectClass).length > 0) {\n _.each($(attribute).find('.' + this.options.classes.selectClass), function (dropdown) {\n if ($(dropdown).val() === '0') {\n $product.find(this.options.normalPriceLabelSelector).show();\n }\n }.bind(this));\n } else {\n $product.find(this.options.normalPriceLabelSelector).show();\n }\n }\n }.bind(this));\n },\n\n /**\n * Get new prices for selected options\n *\n * @returns {*}\n * @private\n */\n _getNewPrices: function () {\n var $widget = this,\n newPrices = $widget.options.jsonConfig.prices,\n allowedProduct = this._getAllowedProductWithMinPrice(this._CalcProducts());\n\n if (!_.isEmpty(allowedProduct)) {\n newPrices = this.options.jsonConfig.optionPrices[allowedProduct];\n }\n\n return newPrices;\n },\n\n /**\n * Get prices\n *\n * @param {Object} newPrices\n * @param {Object} displayPrices\n * @returns {*}\n * @private\n */\n _getPrices: function (newPrices, displayPrices) {\n var $widget = this;\n\n if (_.isEmpty(newPrices)) {\n newPrices = $widget._getNewPrices();\n }\n _.each(displayPrices, function (price, code) {\n\n if (newPrices[code]) {\n displayPrices[code].amount = newPrices[code].amount - displayPrices[code].amount;\n }\n });\n\n return displayPrices;\n },\n\n /**\n * Get product with minimum price from selected options.\n *\n * @param {Array} allowedProducts\n * @returns {String}\n * @private\n */\n _getAllowedProductWithMinPrice: function (allowedProducts) {\n var optionPrices = this.options.jsonConfig.optionPrices,\n product = {},\n optionFinalPrice, optionMinPrice;\n\n _.each(allowedProducts, function (allowedProduct) {\n optionFinalPrice = parseFloat(optionPrices[allowedProduct].finalPrice.amount);\n\n if (_.isEmpty(product) || optionFinalPrice < optionMinPrice) {\n optionMinPrice = optionFinalPrice;\n product = allowedProduct;\n }\n }, this);\n\n return product;\n },\n\n /**\n * Gets all product media and change current to the needed one\n *\n * @private\n */\n _LoadProductMedia: function () {\n var $widget = this,\n $this = $widget.element,\n productData = this._determineProductData(),\n mediaCallData,\n mediaCacheKey,\n\n /**\n * Processes product media data\n *\n * @param {Object} data\n * @returns void\n */\n mediaSuccessCallback = function (data) {\n if (!(mediaCacheKey in $widget.options.mediaCache)) {\n $widget.options.mediaCache[mediaCacheKey] = data;\n }\n $widget._ProductMediaCallback($this, data, productData.isInProductView);\n setTimeout(function () {\n $widget._DisableProductMediaLoader($this);\n }, 300);\n };\n\n if (!$widget.options.mediaCallback) {\n return;\n }\n\n mediaCallData = {\n 'product_id': this.getProduct()\n };\n\n mediaCacheKey = JSON.stringify(mediaCallData);\n\n if (mediaCacheKey in $widget.options.mediaCache) {\n $widget._XhrKiller();\n $widget._EnableProductMediaLoader($this);\n mediaSuccessCallback($widget.options.mediaCache[mediaCacheKey]);\n } else {\n mediaCallData.isAjax = true;\n $widget._XhrKiller();\n $widget._EnableProductMediaLoader($this);\n $widget.xhr = $.ajax({\n url: $widget.options.mediaCallback,\n cache: true,\n type: 'GET',\n dataType: 'json',\n data: mediaCallData,\n success: mediaSuccessCallback\n }).done(function () {\n $widget._XhrKiller();\n });\n }\n },\n\n /**\n * Enable loader\n *\n * @param {Object} $this\n * @private\n */\n _EnableProductMediaLoader: function ($this) {\n var $widget = this;\n\n if ($('body.catalog-product-view').length > 0) {\n $this.parents('.column.main').find('.photo.image')\n .addClass($widget.options.classes.loader);\n } else {\n //Category View\n $this.parents('.product-item-info').find('.product-image-photo')\n .addClass($widget.options.classes.loader);\n }\n },\n\n /**\n * Disable loader\n *\n * @param {Object} $this\n * @private\n */\n _DisableProductMediaLoader: function ($this) {\n var $widget = this;\n\n if ($('body.catalog-product-view').length > 0) {\n $this.parents('.column.main').find('.photo.image')\n .removeClass($widget.options.classes.loader);\n } else {\n //Category View\n $this.parents('.product-item-info').find('.product-image-photo')\n .removeClass($widget.options.classes.loader);\n }\n },\n\n /**\n * Callback for product media\n *\n * @param {Object} $this\n * @param {String} response\n * @param {Boolean} isInProductView\n * @private\n */\n _ProductMediaCallback: function ($this, response, isInProductView) {\n var $main = isInProductView ? $this.parents('.column.main') : $this.parents('.product-item-info'),\n $widget = this,\n images = [],\n\n /**\n * Check whether object supported or not\n *\n * @param {Object} e\n * @returns {*|Boolean}\n */\n support = function (e) {\n return e.hasOwnProperty('large') && e.hasOwnProperty('medium') && e.hasOwnProperty('small');\n };\n\n if (_.size($widget) < 1 || !support(response)) {\n this.updateBaseImage(this.options.mediaGalleryInitial, $main, isInProductView);\n\n return;\n }\n\n images.push({\n full: response.large,\n img: response.medium,\n thumb: response.small,\n isMain: true\n });\n\n if (response.hasOwnProperty('gallery')) {\n $.each(response.gallery, function () {\n if (!support(this) || response.large === this.large) {\n return;\n }\n images.push({\n full: this.large,\n img: this.medium,\n thumb: this.small\n });\n });\n }\n\n this.updateBaseImage(images, $main, isInProductView);\n },\n\n /**\n * Check if images to update are initial and set their type\n * @param {Array} images\n */\n _setImageType: function (images) {\n\n images.map(function (img) {\n if (!img.type) {\n img.type = 'image';\n }\n });\n\n return images;\n },\n\n /**\n * Update [gallery-placeholder] or [product-image-photo]\n * @param {Array} images\n * @param {jQuery} context\n * @param {Boolean} isInProductView\n */\n updateBaseImage: function (images, context, isInProductView) {\n var justAnImage = images[0],\n initialImages = this.options.mediaGalleryInitial,\n imagesToUpdate,\n gallery = context.find(this.options.mediaGallerySelector).data('gallery'),\n isInitial;\n\n if (isInProductView) {\n if (_.isUndefined(gallery)) {\n context.find(this.options.mediaGallerySelector).on('gallery:loaded', function () {\n this.updateBaseImage(images, context, isInProductView);\n }.bind(this));\n\n return;\n }\n\n imagesToUpdate = images.length ? this._setImageType($.extend(true, [], images)) : [];\n isInitial = _.isEqual(\n imagesToUpdate.map(({thumb, img, full, type, videoUrl}) => ({thumb, img, full, type, videoUrl})),\n initialImages.map(({thumb, img, full, type, videoUrl}) => ({thumb, img, full, type, videoUrl}))\n );\n\n if (this.options.gallerySwitchStrategy === 'prepend' && !isInitial) {\n imagesToUpdate = imagesToUpdate.concat(initialImages);\n }\n\n imagesToUpdate = this._setImageIndex(imagesToUpdate);\n\n gallery.updateData(imagesToUpdate);\n this._addFotoramaVideoEvents(isInitial);\n } else if (justAnImage && justAnImage.img) {\n context.find('.product-image-photo').attr('src', justAnImage.img);\n }\n },\n\n /**\n * Add video events\n *\n * @param {Boolean} isInitial\n * @private\n */\n _addFotoramaVideoEvents: function (isInitial) {\n if (_.isUndefined($.mage.AddFotoramaVideoEvents)) {\n return;\n }\n\n if (isInitial) {\n $(this.options.mediaGallerySelector).AddFotoramaVideoEvents();\n\n return;\n }\n\n $(this.options.mediaGallerySelector).AddFotoramaVideoEvents({\n selectedOption: this.getProduct(),\n dataMergeStrategy: this.options.gallerySwitchStrategy\n });\n },\n\n /**\n * Set correct indexes for image set.\n *\n * @param {Array} images\n * @private\n */\n _setImageIndex: function (images) {\n var length = images.length,\n i;\n\n for (i = 0; length > i; i++) {\n images[i].i = i + 1;\n }\n\n return images;\n },\n\n /**\n * Kill doubled AJAX requests\n *\n * @private\n */\n _XhrKiller: function () {\n var $widget = this;\n\n if ($widget.xhr !== undefined && $widget.xhr !== null) {\n $widget.xhr.abort();\n $widget.xhr = null;\n }\n },\n\n /**\n * Emulate mouse click on all swatches that should be selected\n * @param {Object} [selectedAttributes]\n * @private\n */\n _EmulateSelected: function (selectedAttributes) {\n $.each(selectedAttributes, $.proxy(function (attributeCode, optionId) {\n var elem = this.element.find('.' + this.options.classes.attributeClass +\n '[data-attribute-code=\"' + attributeCode + '\"] [data-option-id=\"' + optionId + '\"]'),\n parentInput = elem.parent();\n\n if (elem.hasClass('selected')) {\n return;\n }\n\n if (parentInput.hasClass(this.options.classes.selectClass)) {\n parentInput.val(optionId);\n parentInput.trigger('change');\n } else {\n elem.trigger('click');\n }\n }, this));\n },\n\n /**\n * Emulate mouse click or selection change on all swatches that should be selected\n * @param {Object} [selectedAttributes]\n * @private\n */\n _EmulateSelectedByAttributeId: function (selectedAttributes) {\n $.each(selectedAttributes, $.proxy(function (attributeId, optionId) {\n var elem = this.element.find('.' + this.options.classes.attributeClass +\n '[data-attribute-id=\"' + attributeId + '\"] [data-option-id=\"' + optionId + '\"]'),\n parentInput = elem.parent();\n\n if (elem.hasClass('selected')) {\n return;\n }\n\n if (parentInput.hasClass(this.options.classes.selectClass)) {\n parentInput.val(optionId);\n parentInput.trigger('change');\n } else {\n elem.trigger('click');\n }\n }, this));\n },\n\n /**\n * Get default options values settings with either URL query parameters\n * @private\n */\n _getSelectedAttributes: function () {\n var hashIndex = window.location.href.indexOf('#'),\n selectedAttributes = {},\n params;\n\n if (hashIndex !== -1) {\n params = $.parseQuery(window.location.href.substr(hashIndex + 1));\n\n selectedAttributes = _.invert(_.mapObject(_.invert(params), function (attributeId) {\n var attribute = this.options.jsonConfig.mappedAttributes[attributeId];\n\n return attribute ? attribute.code : attributeId;\n }.bind(this)));\n }\n\n return selectedAttributes;\n },\n\n /**\n * Callback which fired after gallery gets initialized.\n *\n * @param {HTMLElement} element - DOM element associated with a gallery.\n */\n _onGalleryLoaded: function (element) {\n var galleryObject = element.data('gallery');\n\n this.options.mediaGalleryInitial = galleryObject.returnCurrentImages();\n },\n\n /**\n * Sets mediaCache for cases when jsonConfig contains preSelectedGallery on layered navigation result pages\n *\n * @private\n */\n _setPreSelectedGallery: function () {\n var mediaCallData;\n\n if (this.options.jsonConfig.preSelectedGallery) {\n mediaCallData = {\n 'product_id': this.getProduct()\n };\n\n this.options.mediaCache[JSON.stringify(mediaCallData)] = this.options.jsonConfig.preSelectedGallery;\n }\n },\n\n /**\n * Callback for quantity change event.\n */\n _onQtyChanged: function () {\n var $price = this.element.parents(this.options.selectorProduct)\n .find(this.options.selectorProductPrice);\n\n $price.trigger(\n 'updatePrice',\n {\n 'prices': this._getPrices(this._getNewPrices(), $price.priceBox('option').prices)\n }\n );\n }\n });\n\n return $.mage.SwatchRenderer;\n});\n","Magento_Swatches/js/product-attributes.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n 'jquery',\n 'Magento_Ui/js/modal/alert',\n 'Magento_Ui/js/modal/prompt',\n 'uiRegistry',\n 'collapsable'\n], function ($, alert, prompt, rg) {\n 'use strict';\n\n return function (optionConfig) {\n var activePanelClass = 'selected-type-options',\n swatchProductAttributes = {\n frontendInput: $('#frontend_input'),\n isFilterable: $('#is_filterable'),\n isFilterableInSearch: $('#is_filterable_in_search'),\n backendType: $('#backend_type'),\n usedForSortBy: $('#used_for_sort_by'),\n frontendClass: $('#frontend_class'),\n isWysiwygEnabled: $('#is_wysiwyg_enabled'),\n isHtmlAllowedOnFront: $('#is_html_allowed_on_front'),\n isRequired: $('#is_required'),\n isUnique: $('#is_unique'),\n defaultValueText: $('#default_value_text'),\n defaultValueTextarea: $('#default_value_textarea'),\n defaultValueDate: $('#default_value_date'),\n defaultValueDatetime: $('#default_value_datetime'),\n defaultValueYesno: $('#default_value_yesno'),\n isGlobal: $('#is_global'),\n useProductImageForSwatch: $('#use_product_image_for_swatch'),\n updateProductPreviewImage: $('#update_product_preview_image'),\n usedInProductListing: $('#used_in_product_listing'),\n isVisibleOnFront: $('#is_visible_on_front'),\n position: $('#position'),\n attrTabsFront: $('#product_attribute_tabs_front'),\n\n /**\n * @returns {*|jQuery|HTMLElement}\n */\n get tabsFront() {\n return this.attrTabsFront.length ? this.attrTabsFront.closest('li') : $('#front_fieldset-wrapper');\n },\n selectFields: ['boolean', 'select', 'multiselect', 'price', 'swatch_text', 'swatch_visual'],\n\n /**\n * @this {swatchProductAttributes}\n */\n toggleApplyVisibility: function (select) {\n if ($(select).val() === 1) {\n $(select).next('select').removeClass('no-display');\n $(select).next('select').removeClass('ignore-validate');\n } else {\n $(select).next('select').addClass('no-display');\n $(select).next('select').addClass('ignore-validate');\n $(select).next('select option:selected').each(function () {\n this.selected = false;\n });\n }\n },\n\n /**\n * @this {swatchProductAttributes}\n */\n checkOptionsPanelVisibility: function () {\n var selectOptionsPanel = $('#manage-options-panel'),\n visualOptionsPanel = $('#swatch-visual-options-panel'),\n textOptionsPanel = $('#swatch-text-options-panel');\n\n this._hidePanel(selectOptionsPanel);\n this._hidePanel(visualOptionsPanel);\n this._hidePanel(textOptionsPanel);\n\n switch (this.frontendInput.val()) {\n case 'swatch_visual':\n this._showPanel(visualOptionsPanel);\n break;\n\n case 'swatch_text':\n this._showPanel(textOptionsPanel);\n break;\n\n case 'select':\n case 'multiselect':\n this._showPanel(selectOptionsPanel);\n break;\n }\n },\n\n /**\n * @this {swatchProductAttributes}\n */\n bindAttributeInputType: function () {\n this.checkOptionsPanelVisibility();\n this.switchDefaultValueField();\n\n if (!~$.inArray(this.frontendInput.val(), this.selectFields)) {\n // not in array\n this.isFilterable.selectedIndex = 0;\n this._disable(this.isFilterable);\n this._disable(this.isFilterableInSearch);\n } else {\n // in array\n this._enable(this.isFilterable);\n this._enable(this.isFilterableInSearch);\n this.backendType.val('int');\n }\n\n if (this.frontendInput.val() === 'multiselect' ||\n this.frontendInput.val() === 'gallery' ||\n this.frontendInput.val() === 'textarea'\n ) {\n this._disable(this.usedForSortBy);\n } else {\n this._enable(this.usedForSortBy);\n }\n\n if (this.frontendInput.val() === 'swatch_text') {\n $('.swatch-text-field-0').addClass('required-option');\n } else {\n $('.swatch-text-field-0').removeClass('required-option');\n }\n\n this.setRowVisibility(this.isWysiwygEnabled, false);\n this.setRowVisibility(this.isHtmlAllowedOnFront, false);\n\n switch (this.frontendInput.val()) {\n case 'textarea':\n this.setRowVisibility(this.isWysiwygEnabled, true);\n\n if (this.isWysiwygEnabled.val() === '0') {\n this._enable(this.isHtmlAllowedOnFront);\n }\n this.frontendClass.val('');\n this._disable(this.frontendClass);\n break;\n\n case 'text':\n this.setRowVisibility(this.isHtmlAllowedOnFront, true);\n this._enable(this.frontendClass);\n break;\n\n case 'select':\n case 'multiselect':\n this.setRowVisibility(this.isHtmlAllowedOnFront, true);\n this.frontendClass.val('');\n this._disable(this.frontendClass);\n break;\n default:\n this.frontendClass.val('');\n this._disable(this.frontendClass);\n }\n\n this.switchIsFilterable();\n },\n\n /**\n * @this {swatchProductAttributes}\n */\n switchIsFilterable: function () {\n if (this.isFilterable.selectedIndex === 0) {\n this._disable(this.position);\n } else {\n this._enable(this.position);\n }\n },\n\n /**\n * @this {swatchProductAttributes}\n */\n switchDefaultValueField: function () {\n var currentValue = this.frontendInput.val(),\n defaultValueTextVisibility = false,\n defaultValueTextareaVisibility = false,\n defaultValueDateVisibility = false,\n defaultValueDatetimeVisibility = false,\n defaultValueYesnoVisibility = false,\n scopeVisibility = true,\n useProductImageForSwatch = false,\n defaultValueUpdateImage = false,\n optionDefaultInputType = '',\n isFrontTabHidden = false,\n thing = this;\n\n if (!this.frontendInput.length) {\n return;\n }\n\n switch (currentValue) {\n case 'select':\n optionDefaultInputType = 'radio';\n break;\n\n case 'multiselect':\n optionDefaultInputType = 'checkbox';\n break;\n\n case 'date':\n defaultValueDateVisibility = true;\n break;\n\n case 'datetime':\n defaultValueDatetimeVisibility = true;\n break;\n\n case 'boolean':\n defaultValueYesnoVisibility = true;\n break;\n\n case 'textarea':\n case 'texteditor':\n defaultValueTextareaVisibility = true;\n break;\n\n case 'media_image':\n defaultValueTextVisibility = false;\n break;\n\n case 'price':\n scopeVisibility = false;\n break;\n\n case 'swatch_visual':\n useProductImageForSwatch = true;\n defaultValueUpdateImage = true;\n defaultValueTextVisibility = false;\n break;\n\n case 'swatch_text':\n useProductImageForSwatch = false;\n defaultValueUpdateImage = true;\n defaultValueTextVisibility = false;\n break;\n default:\n defaultValueTextVisibility = true;\n break;\n }\n\n delete optionConfig.hiddenFields['swatch_visual'];\n delete optionConfig.hiddenFields['swatch_text'];\n\n if (currentValue === 'media_image') {\n this.tabsFront.hide();\n this.setRowVisibility(this.isRequired, false);\n this.setRowVisibility(this.isUnique, false);\n this.setRowVisibility(this.frontendClass, false);\n } else if (optionConfig.hiddenFields[currentValue]) {\n $.each(optionConfig.hiddenFields[currentValue], function (key, option) {\n switch (option) {\n case '_front_fieldset':\n thing.tabsFront.hide();\n isFrontTabHidden = true;\n break;\n\n case '_default_value':\n defaultValueTextVisibility = false;\n defaultValueTextareaVisibility = false;\n defaultValueDateVisibility = false;\n defaultValueDatetimeVisibility = false;\n defaultValueYesnoVisibility = false;\n break;\n\n case '_scope':\n scopeVisibility = false;\n break;\n default:\n thing.setRowVisibility($('#' + option), false);\n }\n });\n\n if (!isFrontTabHidden) {\n thing.tabsFront.show();\n }\n\n } else {\n this.tabsFront.show();\n this.showDefaultRows();\n }\n\n this.setRowVisibility(this.defaultValueText, defaultValueTextVisibility);\n this.setRowVisibility(this.defaultValueTextarea, defaultValueTextareaVisibility);\n this.setRowVisibility(this.defaultValueDate, defaultValueDateVisibility);\n this.setRowVisibility(this.defaultValueDatetime, defaultValueDatetimeVisibility);\n this.setRowVisibility(this.defaultValueYesno, defaultValueYesnoVisibility);\n this.setRowVisibility(this.isGlobal, scopeVisibility);\n\n /* swatch attributes */\n this.setRowVisibility(this.useProductImageForSwatch, useProductImageForSwatch);\n this.setRowVisibility(this.updateProductPreviewImage, defaultValueUpdateImage);\n\n $('input[name=\\'default[]\\']').each(function () {\n $(this).attr('type', optionDefaultInputType);\n });\n },\n\n /**\n * @this {swatchProductAttributes}\n */\n showDefaultRows: function () {\n this.setRowVisibility(this.isRequired, true);\n this.setRowVisibility(this.isUnique, true);\n this.setRowVisibility(this.frontendClass, true);\n },\n\n /**\n * @param {Object} el\n * @param {Boolean} isVisible\n * @this {swatchProductAttributes}\n */\n setRowVisibility: function (el, isVisible) {\n if (isVisible) {\n el.show();\n el.closest('.field').show();\n } else {\n el.hide();\n el.closest('.field').hide();\n }\n },\n\n /**\n * @param {Object} el\n * @this {swatchProductAttributes}\n */\n _disable: function (el) {\n el.attr('disabled', 'disabled');\n },\n\n /**\n * @param {jQuery} el\n * @this {swatchProductAttributes}\n */\n _enable: function (el) {\n if (!el.attr('readonly')) {\n el.prop('disabled', false);\n }\n },\n\n /**\n * @param {Object} el\n * @this {swatchProductAttributes}\n */\n _showPanel: function (el) {\n el.closest('.fieldset').show();\n el.addClass(activePanelClass);\n this._render(el.attr('id'));\n },\n\n /**\n * @param {Object} el\n * @this {swatchProductAttributes}\n */\n _hidePanel: function (el) {\n el.closest('.fieldset').hide();\n el.removeClass(activePanelClass);\n },\n\n /**\n * @param {String} id\n * @this {swatchProductAttributes}\n */\n _render: function (id) {\n rg.get(id, function () {\n $('#' + id).trigger('render');\n });\n },\n\n /**\n * @param {String} promptMessage\n * @this {swatchProductAttributes}\n */\n saveAttributeInNewSet: function (promptMessage) {\n\n prompt({\n content: promptMessage,\n actions: {\n\n /**\n * @param {String} val\n * @this {actions}\n */\n confirm: function (val) {\n var rules = ['required-entry', 'validate-no-html-tags'],\n newAttributeSetNameInputId = $('#new_attribute_set_name'),\n editForm = $('#edit_form'),\n newAttributeSetName = val,\n i;\n\n if (!newAttributeSetName) {\n return;\n }\n\n for (i = 0; i < rules.length; i++) {\n if (!$.validator.methods[rules[i]](newAttributeSetName)) {\n alert({\n content: $.validator.messages[rules[i]]\n });\n\n return;\n }\n }\n\n if (newAttributeSetNameInputId.length) {\n newAttributeSetNameInputId.val(newAttributeSetName);\n } else {\n editForm.append(new Element('input', {\n type: 'hidden',\n id: newAttributeSetNameInputId,\n name: 'new_attribute_set_name',\n value: newAttributeSetName\n })\n );\n }\n // Temporary solution will replaced after refactoring of attributes functionality\n editForm.triggerHandler('save');\n }\n }\n });\n }\n };\n\n $(function () {\n var editForm = $('#edit_form'),\n swatchVisualPanel = $('#swatch-visual-options-panel'),\n swatchTextPanel = $('#swatch-text-options-panel'),\n tableBody = $(),\n activePanel = $();\n\n $('#frontend_input').on('change', function () {\n swatchProductAttributes.bindAttributeInputType();\n });\n $('#is_filterable').on('change', function () {\n swatchProductAttributes.switchIsFilterable();\n });\n\n swatchProductAttributes.bindAttributeInputType();\n\n // @todo: refactor collapsible component\n $('.attribute-popup .collapse, [data-role=\"advanced_fieldset-content\"]')\n .collapsable()\n .collapse('hide');\n\n editForm.on('beforeSubmit', function () {\n var optionContainer, optionsValues;\n\n activePanel = swatchTextPanel.hasClass(activePanelClass) ? swatchTextPanel : swatchVisualPanel;\n optionContainer = activePanel.find('table tbody');\n\n if (activePanel.hasClass(activePanelClass)) {\n optionsValues = $.map(\n optionContainer.find('tr'),\n function (row) {\n return $(row).find('input, select, textarea').serialize();\n }\n );\n $('<input>')\n .attr({\n type: 'hidden',\n name: 'serialized_options'\n })\n .val(JSON.stringify(optionsValues))\n .prependTo(editForm);\n }\n\n tableBody = optionContainer.detach();\n });\n\n editForm.on('afterValidate.error highlight.validate', function () {\n if (activePanel.hasClass(activePanelClass)) {\n activePanel.find('table').append(tableBody);\n $('input[name=\"serialized_options\"]').remove();\n }\n });\n });\n\n window.saveAttributeInNewSet = swatchProductAttributes.saveAttributeInNewSet;\n window.toggleApplyVisibility = swatchProductAttributes.toggleApplyVisibility;\n };\n});\n"}
}});