![]() Server : Apache System : Linux server2.corals.io 4.18.0-348.2.1.el8_5.x86_64 #1 SMP Mon Nov 15 09:17:08 EST 2021 x86_64 User : corals ( 1002) PHP Version : 7.4.33 Disable Function : exec,passthru,shell_exec,system Directory : /home/corals/cartforge.co/pub/static/adminhtml/Magento/backend/en_US/js/bundle/ |
require.config({"config": { "jsbuild":{"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/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/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/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/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/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/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/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/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/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/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/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_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/grid/massactions.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 'mageUtils',\n 'Magento_Ui/js/lib/collapsible',\n 'Magento_Ui/js/modal/confirm',\n 'Magento_Ui/js/modal/alert',\n 'mage/translate'\n], function (_, registry, utils, Collapsible, confirm, alert, $t) {\n 'use strict';\n\n return Collapsible.extend({\n defaults: {\n template: 'ui/grid/actions',\n stickyTmpl: 'ui/grid/sticky/actions',\n selectProvider: 'ns = ${ $.ns }, index = ids',\n actions: [],\n noItemsMsg: $t('You haven\\'t selected any items!'),\n modules: {\n selections: '${ $.selectProvider }'\n }\n },\n\n /**\n * Initializes observable properties.\n *\n * @returns {Massactions} Chainable.\n */\n initObservable: function () {\n this._super()\n .observe('actions');\n\n return this;\n },\n\n /**\n * Applies specified action.\n *\n * @param {String} actionIndex - Actions' identifier.\n * @returns {Massactions} Chainable.\n */\n applyAction: function (actionIndex) {\n var data = this.getSelections(),\n action,\n callback;\n\n if (!data.total) {\n alert({\n content: this.noItemsMsg\n });\n\n return this;\n }\n\n action = this.getAction(actionIndex);\n callback = this._getCallback(action, data);\n\n action.confirm ?\n this._confirm(action, callback) :\n callback();\n\n return this;\n },\n\n /**\n * Retrieves selections data from the selections provider.\n *\n * @returns {Object|Undefined}\n */\n getSelections: function () {\n var provider = this.selections(),\n selections = provider && provider.getSelections();\n\n return selections;\n },\n\n /**\n * Retrieves action object associated with a specified index.\n *\n * @param {String} actionIndex - Actions' identifier.\n * @returns {Object} Action object.\n */\n getAction: function (actionIndex) {\n return _.findWhere(this.actions(), {\n type: actionIndex\n });\n },\n\n /**\n * Adds new action. If action with a specified identifier\n * already exists, than the original one will be overrided.\n *\n * @param {Object} action - Action object.\n * @returns {Massactions} Chainable.\n */\n addAction: function (action) {\n var actions = this.actions(),\n index = _.findIndex(actions, {\n type: action.type\n });\n\n ~index ?\n actions[index] = action :\n actions.push(action);\n\n this.actions(actions);\n\n return this;\n },\n\n /**\n * Creates action callback based on its' data. If action doesn't spicify\n * a callback function than the default one will be used.\n *\n * @private\n * @param {Object} action - Actions' object.\n * @param {Object} selections - Selections data.\n * @returns {Function} Callback function.\n */\n _getCallback: function (action, selections) {\n var callback = action.callback,\n args = [action, selections];\n\n if (utils.isObject(callback)) {\n args.unshift(callback.target);\n\n callback = registry.async(callback.provider);\n } else if (typeof callback != 'function') {\n callback = this.defaultCallback.bind(this);\n }\n\n return function () {\n callback.apply(null, args);\n };\n },\n\n /**\n * Default action callback. Sends selections data\n * via POST request.\n *\n * @param {Object} action - Action data.\n * @param {Object} data - Selections data.\n */\n defaultCallback: function (action, data) {\n var itemsType = data.excludeMode ? 'excluded' : 'selected',\n selections = {};\n\n selections[itemsType] = data[itemsType];\n\n if (!selections[itemsType].length) {\n selections[itemsType] = false;\n }\n\n _.extend(selections, data.params || {});\n\n utils.submit({\n url: action.url,\n data: selections\n });\n },\n\n /**\n * Shows actions' confirmation window.\n *\n * @param {Object} action - Actions' data.\n * @param {Function} callback - Callback that will be\n * invoked if action is confirmed.\n */\n _confirm: function (action, callback) {\n var confirmData = action.confirm,\n data = this.getSelections(),\n total = data.total ? data.total : 0,\n confirmMessage = confirmData.message + (data.showTotalRecords || data.showTotalRecords === undefined ?\n ' (' + total + ' record' + (total > 1 ? 's' : '') + ')'\n : '');\n\n confirm({\n title: confirmData.title,\n content: confirmMessage,\n actions: {\n confirm: callback\n }\n });\n }\n });\n});\n","Magento_Ui/js/grid/data-storage.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 'mageUtils',\n 'uiClass'\n], function ($, _, utils, Class) {\n 'use strict';\n\n return Class.extend({\n defaults: {\n cacheRequests: true,\n cachedRequestDelay: 50,\n indexField: 'entity_id',\n requestConfig: {\n url: '${ $.updateUrl }',\n method: 'GET',\n dataType: 'json'\n },\n dataScope: '',\n data: {}\n },\n\n /**\n * Initializes dataStorage configuration.\n *\n * @returns {DataStorage} Chainable.\n */\n initConfig: function () {\n var scope;\n\n this._super();\n\n scope = this.dataScope;\n\n if (typeof scope === 'string') {\n this.dataScope = scope ? [scope] : [];\n }\n\n this._requests = [];\n\n return this;\n },\n\n /**\n * Extracts data which matches specified set of identifiers.\n *\n * @param {Array} ids - Records identifiers.\n * @returns {Array|Boolean}\n */\n getByIds: function (ids) {\n var result = [],\n hasData;\n\n hasData = ids.every(function (id) {\n var item = this.data[id];\n\n return item ? result.push(item) : false;\n }, this);\n\n return hasData ? result : false;\n },\n\n /**\n * Extracts identifiers of provided records.\n * If no records were provided then full list of\n * current data id's will be returned.\n *\n * @param {Object|Array} [data=this.data]\n * @returns {Array}\n */\n getIds: function (data) {\n data = data || this.data;\n\n return _.pluck(data, this.indexField);\n },\n\n /**\n * Extracts data which matches specified parameters.\n *\n * @param {Object} params - Request parameters.\n * @param {Object} [options={}]\n * @returns {jQueryPromise}\n */\n getData: function (params, options) {\n var cachedRequest;\n\n if (this.hasScopeChanged(params)) {\n this.clearRequests();\n } else {\n cachedRequest = this.getRequest(params);\n }\n\n options = options || {};\n\n return !options.refresh && cachedRequest ?\n this.getRequestData(cachedRequest) :\n this.requestData(params);\n },\n\n /**\n * Tells whether one of the parameters defined in the \"dataScope\" has\n * changed since the last request.\n *\n * @param {Object} params - Request parameters.\n * @returns {Boolean}\n */\n hasScopeChanged: function (params) {\n var lastRequest = _.last(this._requests),\n keys,\n diff;\n\n if (!lastRequest) {\n return false;\n }\n\n diff = utils.compare(lastRequest.params, params);\n\n keys = _.pluck(diff.changes, 'path');\n keys = keys.concat(Object.keys(diff.containers));\n\n return _.intersection(this.dataScope, keys).length > 0;\n },\n\n /**\n * Extends records of current data object\n * with the provided records collection.\n *\n * @param {Array} data - An array of records.\n * @returns {DataStorage} Chainable.\n */\n updateData: function (data) {\n var records = _.indexBy(data || [], this.indexField);\n\n _.extend(this.data, records);\n\n return this;\n },\n\n /**\n * Sends request to the server with provided parameters.\n *\n * @param {Object} params - Request parameters.\n * @returns {jQueryPromise}\n */\n requestData: function (params) {\n var query = utils.copy(params),\n handler = this.onRequestComplete.bind(this, query),\n request;\n\n this.requestConfig.data = query;\n request = $.ajax(this.requestConfig).done(handler);\n\n return request;\n },\n\n /**\n * Returns request's instance which\n * contains provided parameters.\n *\n * @param {Object} params - Request parameters.\n * @returns {Object} Instance of request.\n */\n getRequest: function (params) {\n return _.find(this._requests, function (request) {\n return _.isEqual(params, request.params);\n }, this);\n },\n\n /**\n * Forms data object associated with provided request.\n *\n * @param {Object} request - Request object.\n * @returns {jQueryPromise}\n */\n getRequestData: function (request) {\n var defer = $.Deferred(),\n resolve = defer.resolve.bind(defer),\n delay = this.cachedRequestDelay,\n result;\n\n if (request.showTotalRecords === undefined) {\n request.showTotalRecords = true;\n }\n\n result = {\n items: this.getByIds(request.ids),\n totalRecords: request.totalRecords,\n showTotalRecords: request.showTotalRecords,\n errorMessage: request.errorMessage\n };\n\n delay ?\n _.delay(resolve, delay, result) :\n resolve(result);\n\n return defer.promise();\n },\n\n /**\n * Caches requests object with provided parameters\n * and data object associated with it.\n *\n * @param {Object} data - Data associated with request.\n * @param {Object} params - Request parameters.\n * @returns {DataStorage} Chainable.\n */\n cacheRequest: function (data, params) {\n var cached = this.getRequest(params);\n\n if (cached) {\n this.removeRequest(cached);\n }\n\n if (data.showTotalRecords === undefined) {\n data.showTotalRecords = true;\n }\n\n this._requests.push({\n ids: this.getIds(data.items),\n params: params,\n totalRecords: data.totalRecords,\n showTotalRecords: data.showTotalRecords,\n errorMessage: data.errorMessage\n });\n\n return this;\n },\n\n /**\n * Clears all cached requests.\n *\n * @returns {DataStorage} Chainable.\n */\n clearRequests: function () {\n this._requests.splice(0);\n\n return this;\n },\n\n /**\n * Removes provided request object from cached requests list.\n *\n * @param {Object} request - Request object.\n * @returns {DataStorage} Chainable.\n */\n removeRequest: function (request) {\n var requests = this._requests,\n index = requests.indexOf(request);\n\n if (~index) {\n requests.splice(index, 1);\n }\n\n return this;\n },\n\n /**\n * Checks if request with a specified parameters was cached.\n *\n * @param {Object} params - Parameters of the request.\n * @returns {Boolean}\n */\n wasRequested: function (params) {\n return !!this.getRequest(params);\n },\n\n /**\n * Handles successful data request.\n *\n * @param {Object} params - Request parameters.\n * @param {Object} data - Response data.\n */\n onRequestComplete: function (params, data) {\n this.updateData(data.items);\n\n if (this.cacheRequests) {\n this.cacheRequest(data, params);\n }\n }\n });\n});\n","Magento_Ui/js/grid/dnd.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 'Magento_Ui/js/lib/view/utils/async',\n 'underscore',\n 'uiRegistry',\n 'uiClass'\n], function (ko, $, _, registry, Class) {\n 'use strict';\n\n var isTouchDevice = typeof document.ontouchstart !== 'undefined',\n transformProp;\n\n /**\n * Defines supported css 'transform' property.\n *\n * @returns {String|Undefined}\n */\n transformProp = (function () {\n var style = document.body.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 /**\n * Returns first touch data if it's available.\n *\n * @param {(MouseEvent|TouchEvent)} e - Event object.\n * @returns {Object}\n */\n function getTouch(e) {\n return e.touches ? e.touches[0] : e;\n }\n\n /**\n * Moves specified DOM element to the x and y coordinates.\n *\n * @param {HTMLElement} elem - Element to be relocated.\n * @param {Number} x - X coordinate.\n * @param {Number} y - Y coordinate.\n */\n function locate(elem, x, y) {\n var value = 'translate(' + x + 'px,' + y + 'px)';\n\n elem.style[transformProp] = value;\n }\n\n /*eslint-disable no-extra-parens*/\n /**\n * Checks if specified coordinate is inside of the provided area.\n *\n * @param {Number} x - X coordinate.\n * @param {Number} y - Y coordinate.\n * @param {Object} area - Object which represents area.\n * @returns {Boolean}\n */\n function isInside(x, y, area) {\n return (\n area &&\n x >= area.left && x <= area.right &&\n y >= area.top && y <= area.bottom\n );\n }\n\n /*eslint-enable no-extra-parens*/\n\n /**\n * Calculates distance between two points.\n *\n * @param {Number} x1 - X coordinate of a first point.\n * @param {Number} y1 - Y coordinate of a first point.\n * @param {Number} x2 - X coordinate of a second point.\n * @param {Number} y2 - Y coordinate of a second point.\n * @returns {Number} Distance between points.\n */\n function distance(x1, y1, x2, y2) {\n var dx = x2 - x1,\n dy = y2 - y1;\n\n dx *= dx;\n dy *= dy;\n\n return Math.sqrt(dx + dy);\n }\n\n /**\n * Returns viewModel associated with a provided DOM element.\n *\n * @param {HTMLElement} elem\n * @returns {Object|Array}\n */\n function getModel(elem) {\n return ko.dataFor(elem);\n }\n\n /**\n * Checks whether cols are identical\n *\n * @param {HTMLElement} c1\n * @param {HTMLElement} c2\n * @returns {Boolean}\n */\n function compareCols(c1, c2) {\n return c1.cellIndex === c2.cellIndex;\n }\n\n return Class.extend({\n defaults: {\n rootSelector: '${ $.columnsProvider }:.admin__data-grid-wrap',\n tableSelector: '${ $.rootSelector } -> table.data-grid',\n mainTableSelector: '[data-role=\"grid\"]',\n columnSelector: '${ $.tableSelector } thead tr th',\n noSelectClass: '_no-select',\n hiddenClass: '_hidden',\n fixedX: false,\n fixedY: true,\n minDistance: 2,\n columns: []\n },\n\n /**\n * Initializes Dnd component.\n *\n * @returns {Dnd} Chainable.\n */\n initialize: function () {\n _.bindAll(\n this,\n 'initTable',\n 'initColumn',\n 'removeColumn',\n 'onMouseMove',\n 'onMouseUp',\n 'onMouseDown'\n );\n\n this.$body = $('body');\n\n this._super()\n .initListeners();\n\n $.async(this.tableSelector, this.initTable);\n $.async(this.columnSelector, this.initColumn);\n\n return this;\n },\n\n /**\n * Binds necessary events listeners.\n *\n * @returns {Dnd} Chainbale.\n */\n initListeners: function () {\n if (isTouchDevice) {\n $(document).on({\n touchmove: this.onMouseMove,\n touchend: this.onMouseUp,\n touchleave: this.onMouseUp\n });\n } else {\n $(document).on({\n mousemove: this.onMouseMove,\n mouseup: this.onMouseUp\n });\n }\n\n return this;\n },\n\n /**\n * Defines specified table element as a main container.\n *\n * @param {HTMLTableElement} table\n * @returns {Dnd} Chainable.\n */\n initTable: function (table) {\n this.table = $(table).is(this.mainTableSelector) ? table : this.table;\n\n $(table).addClass('data-grid-draggable');\n\n return this;\n },\n\n /**\n * Sets specified column as a draggable element.\n *\n * @param {HTMLTableHeaderCellElement} column - Columns header element.\n * @returns {Dnd} Chainable.\n */\n initColumn: function (column) {\n var model = getModel(column),\n eventName;\n\n if (!model || !model.draggable) {\n return this;\n }\n\n if (!ko.es5.isTracked(model, 'dragover')) {\n model.track('dragover');\n }\n\n this.columns.push(column);\n\n $(column).bindings({\n css: {\n '_dragover-left': ko.computed(function () {\n return model.dragover === 'right';\n }),\n '_dragover-right': ko.computed(function () {\n return model.dragover === 'left';\n })\n }\n });\n\n eventName = isTouchDevice ?\n 'touchstart' :\n 'mousedown';\n\n $(column).on(eventName, this.onMouseDown);\n $.async.remove(column, this.removeColumn);\n\n return this;\n },\n\n /**\n * Removes specified column element from the columns array.\n *\n * @param {HTMLTableHeaderCellElement} column - Columns header element.\n * @returns {Dnd} Chainable.\n */\n removeColumn: function (column) {\n var columns = this.columns,\n index = columns.indexOf(column);\n\n if (~index) {\n columns.splice(index, 1);\n }\n\n return this;\n },\n\n /**\n * Returns index of column.\n *\n * @param {HTMLTableHeaderCellElement} elem\n * @returns {Number}\n */\n _getColumnIndex: function (elem) {\n return _.toArray(elem.parentNode.cells).indexOf(elem);\n },\n\n /**\n * Calculates coordinates of draggable elements.\n *\n * @returns {Dnd} Chainbale.\n */\n _cacheCoords: function () {\n var container = this.table.getBoundingClientRect(),\n bodyRect = document.body.getBoundingClientRect(),\n grabbed = this.grabbed,\n dragElem = grabbed.elem,\n cells = _.toArray(dragElem.parentNode.cells),\n rect;\n\n this.coords = this.columns.map(function (column) {\n var data,\n colIndex = _.findIndex(cells, function (cell) {\n return compareCols(cell, column);\n });\n\n rect = column.getBoundingClientRect();\n\n data = {\n index: colIndex,\n target: column,\n orig: rect,\n left: rect.left - bodyRect.left,\n right: rect.right - bodyRect.left,\n top: rect.top - bodyRect.top,\n bottom: container.bottom - bodyRect.top\n };\n\n if (column === dragElem) {\n this.dragArea = data;\n\n grabbed.shiftX = rect.left - grabbed.x;\n grabbed.shiftY = rect.top - grabbed.y;\n }\n\n return data;\n }, this);\n\n return this;\n },\n\n /**\n * Creates clone of a target table with only specified column visible.\n *\n * @param {HTMLTableHeaderCellElement} elem - Dragging column.\n * @returns {Dnd} Chainbale.\n */\n _cloneTable: function (elem) {\n var clone = this.table.cloneNode(true),\n columnIndex = this._getColumnIndex(elem),\n headRow = clone.tHead.firstElementChild,\n headCells = _.toArray(headRow.cells),\n tableBody = clone.tBodies[0],\n bodyRows = _.toArray(tableBody.children),\n origTrs = this.table.tBodies[0].children;\n\n clone.style.width = elem.offsetWidth + 'px';\n\n headCells.forEach(function (th, index) {\n if (index !== columnIndex) {\n headRow.removeChild(th);\n }\n });\n\n headRow.cells[0].style.height = elem.offsetHeight + 'px';\n\n bodyRows.forEach(function (row, rowIndex) {\n var cells = row.cells,\n cell;\n\n if (cells.length !== headCells.length) {\n tableBody.removeChild(row);\n\n return;\n }\n\n cell = row.cells[columnIndex].cloneNode(true);\n\n while (row.firstElementChild) {\n row.removeChild(row.firstElementChild);\n }\n\n cell.style.height = origTrs[rowIndex].cells[columnIndex].offsetHeight + 'px';\n\n row.appendChild(cell);\n });\n\n this.dragTable = clone;\n\n $(clone)\n .addClass('_dragging-copy')\n .appendTo('body');\n\n return this;\n },\n\n /**\n * Matches provided coordinates to available areas.\n *\n * @param {Number} x - X coordinate of a mouse pointer.\n * @param {Number} y - Y coordinate of a mouse pointer.\n * @returns {Object|Undefined} Matched area.\n */\n _getDropArea: function (x, y) {\n return _.find(this.coords, function (area) {\n return isInside(x, y, area);\n });\n },\n\n /**\n * Updates state of hovered areas.\n *\n * @param {Number} x - X coordinate of a mouse pointer.\n * @param {Number} y - Y coordinate of a mouse pointer.\n */\n _updateAreas: function (x, y) {\n var leavedArea = this.dropArea,\n area = this.dropArea = this._getDropArea(x, y);\n\n if (leavedArea) {\n this.dragleave(leavedArea);\n }\n\n if (area && !compareCols(area.target, this.dragArea.target)) {\n this.dragenter(area);\n }\n },\n\n /**\n * Grab action handler.\n *\n * @param {Number} x - X coordinate of a grabbed point.\n * @param {Number} y - Y coordinate of a grabbed point.\n * @param {HTMLElement} elem - Grabbed element.\n */\n grab: function (x, y, elem) {\n this.initDrag = true;\n\n this.grabbed = {\n x: x,\n y: y,\n elem: elem\n };\n\n this.$body.addClass(this.noSelectClass);\n },\n\n /**\n * Dragstart action handler.\n *\n * @param {HTMLTableHeaderCellElement} elem - Element which is dragging.\n */\n dragstart: function (elem) {\n this.initDrag = false;\n this.dropArea = false;\n this.dragging = true;\n\n getModel(elem).dragging(true);\n\n this._cacheCoords()\n ._cloneTable(elem);\n },\n\n /**\n * Drag action handler. Locates draggable\n * grid at a specified coordinates.\n *\n * @param {Number} x - X coordinate.\n * @param {Number} y - Y coordinate.\n */\n drag: function (x, y) {\n var grabbed = this.grabbed,\n dragArea = this.dragArea,\n posX = x + grabbed.shiftX,\n posY = y + grabbed.shiftY;\n\n if (this.fixedX) {\n x = dragArea.left;\n posX = dragArea.orig.left;\n }\n\n if (this.fixedY) {\n y = dragArea.top;\n posY = dragArea.orig.top;\n }\n\n locate(this.dragTable, posX, posY);\n\n if (!isInside(x, y, this.dropArea)) {\n this._updateAreas(x, y);\n }\n },\n\n /**\n * Dragenter action handler.\n *\n * @param {Object} dropArea\n */\n dragenter: function (dropArea) {\n var direction = this.dragArea.index < dropArea.index ?\n 'left' :\n 'right';\n\n getModel(dropArea.target).dragover = direction;\n },\n\n /**\n * Dragleave action handler.\n *\n * @param {Object} dropArea\n */\n dragleave: function (dropArea) {\n getModel(dropArea.target).dragover = false;\n },\n\n /**\n * Dragend action handler.\n *\n * @param {Object} dragArea\n */\n dragend: function (dragArea) {\n var dropArea = this.dropArea,\n dragElem = dragArea.target;\n\n this.dragging = false;\n\n document.body.removeChild(this.dragTable);\n\n getModel(dragElem).dragging(false);\n\n if (dropArea && !compareCols(dropArea.target, dragElem)) {\n this.drop(dropArea, dragArea);\n }\n },\n\n /**\n * Drop action handler.\n *\n * @param {Object} dropArea\n * @param {Object} dragArea\n */\n drop: function (dropArea, dragArea) {\n var dropModel = getModel(dropArea.target),\n dragModel = getModel(dragArea.target);\n\n getModel(this.table).insertChild(dragModel, dropModel);\n dropModel.dragover = false;\n },\n\n /**\n * Documents' 'mousemove' event handler.\n *\n * @param {(MouseEvent|TouchEvent)} e - Event object.\n */\n onMouseMove: function (e) {\n var grab = this.grabbed,\n touch = getTouch(e),\n x = touch.pageX,\n y = touch.pageY;\n\n if (this.initDrag || this.dragging) {\n e.preventDefault();\n }\n\n if (this.initDrag && distance(x, y, grab.x, grab.y) >= this.minDistance) {\n this.dragstart(grab.elem);\n }\n\n if (this.dragging) {\n this.drag(x, y);\n }\n },\n\n /**\n * Documents' 'mouseup' event handler.\n */\n onMouseUp: function () {\n if (this.initDrag || this.dragging) {\n this.initDrag = false;\n this.$body.removeClass(this.noSelectClass);\n }\n\n if (this.dragging) {\n this.dragend(this.dragArea);\n }\n },\n\n /**\n * Columns' 'mousedown' event handler.\n *\n * @param {(MouseEvent|TouchEvent)} e - Event object.\n */\n onMouseDown: function (e) {\n var touch = getTouch(e);\n\n this.grab(touch.pageX, touch.pageY, e.currentTarget);\n }\n });\n});\n","Magento_Ui/js/grid/sortBy.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n 'uiElement'\n], function (Element) {\n 'use strict';\n\n return Element.extend({\n defaults: {\n template: 'ui/grid/sortBy',\n options: [],\n applied: {},\n sorting: 'asc',\n columnsProvider: 'ns = ${ $.ns }, componentType = columns',\n selectedOption: '',\n isVisible: true,\n listens: {\n 'selectedOption': 'applyChanges'\n },\n statefull: {\n selectedOption: true,\n applied: true\n },\n exports: {\n applied: '${ $.provider }:params.sorting'\n },\n imports: {\n preparedOptions: '${ $.columnsProvider }:elems'\n },\n modules: {\n columns: '${ $.columnsProvider }'\n }\n },\n\n /**\n * @inheritdoc\n */\n initObservable: function () {\n return this._super()\n .observe([\n 'applied',\n 'selectedOption',\n 'isVisible'\n ]);\n },\n\n /**\n * Prepared sort order options\n */\n preparedOptions: function (columns) {\n if (columns && columns.length > 0) {\n columns.map(function (column) {\n if (column.sortable === true) {\n this.options.push({\n value: column.index,\n label: column.label\n });\n this.isVisible(true);\n } else {\n this.isVisible(false);\n }\n }.bind(this));\n }\n },\n\n /**\n * Apply changes\n */\n applyChanges: function () {\n this.applied({\n field: this.selectedOption(),\n direction: this.sorting\n });\n }\n });\n});\n","Magento_Ui/js/grid/url-filter-applier.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'uiComponent',\n 'underscore',\n 'jquery'\n], function (Component, _, $) {\n 'use strict';\n\n return Component.extend({\n defaults: {\n listingNamespace: null,\n bookmarkProvider: 'componentType = bookmark, ns = ${ $.listingNamespace }',\n filterProvider: 'componentType = filters, ns = ${ $.listingNamespace }',\n filterKey: 'filters',\n searchString: location.search,\n modules: {\n bookmarks: '${ $.bookmarkProvider }',\n filterComponent: '${ $.filterProvider }'\n }\n },\n\n /**\n * Init component\n *\n * @return {exports}\n */\n initialize: function () {\n this._super();\n this.apply();\n\n return this;\n },\n\n /**\n * Apply filter\n */\n apply: function () {\n var urlFilter = this.getFilterParam(this.searchString),\n applied,\n filters;\n\n if (_.isUndefined(this.filterComponent())) {\n setTimeout(function () {\n this.apply();\n }.bind(this), 100);\n\n return;\n }\n\n if (!_.isUndefined(this.bookmarks())) {\n if (!_.size(this.bookmarks().getViewData(this.bookmarks().defaultIndex))) {\n setTimeout(function () {\n this.apply();\n }.bind(this), 500);\n\n return;\n }\n }\n\n if (Object.keys(urlFilter).length) {\n applied = this.filterComponent().get('applied');\n filters = $.extend({}, applied, urlFilter);\n this.filterComponent().set('applied', filters);\n }\n },\n\n /**\n * Get filter param from url\n *\n * @returns {Object}\n */\n getFilterParam: function (url) {\n var searchString = decodeURI(url),\n itemArray;\n\n return _.chain(searchString.slice(1).split('&'))\n .map(function (item) {\n\n if (item && item.search(this.filterKey) !== -1) {\n itemArray = item.split('=');\n\n if (itemArray[1].search('\\\\[') === 0) {\n itemArray[1] = itemArray[1].replace(/[\\[\\]]/g, '').split(',');\n }\n\n itemArray[0] = itemArray[0].replace(this.filterKey, '')\n .replace(/[\\[\\]]/g, '');\n\n return itemArray;\n }\n }.bind(this))\n .compact()\n .object()\n .value();\n }\n });\n});\n","Magento_Ui/js/grid/masonry.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n 'Magento_Ui/js/grid/listing',\n 'Magento_Ui/js/lib/view/utils/raf',\n 'jquery',\n 'ko',\n 'underscore'\n], function (Listing, raf, $, ko, _) {\n 'use strict';\n\n return Listing.extend({\n defaults: {\n template: 'ui/grid/masonry',\n imports: {\n rows: '${ $.provider }:data.items',\n errorMessage: '${ $.provider }:data.errorMessage'\n },\n listens: {\n rows: 'initComponent'\n },\n\n /**\n * Images container id\n * @param string\n */\n containerId: null,\n\n /**\n * Minimum aspect ratio for each image\n * @param int\n */\n minRatio: null,\n\n /**\n * Container width\n * @param int\n */\n containerWidth: window.innerWidth,\n\n /**\n * Margin between images\n * @param int\n */\n imageMargin: 20,\n\n /**\n * Maximum image height value\n * @param int\n */\n maxImageHeight: 240,\n\n /**\n * The value is minimum image width to height ratio when container width is less than the key\n * @param {Object}\n */\n containerWidthToMinRatio: {\n 640: 3,\n 1280: 5,\n 1920: 8\n },\n\n /**\n * Default minimal image width to height ratio.\n * Applied when container width is greater than max width in the containerWidthToMinRatio matrix.\n * @param int\n */\n defaultMinRatio: 10,\n\n /**\n * Layout update FPS during window resizing\n */\n refreshFPS: 60\n },\n\n /**\n * Init observable variables\n * @return {Object}\n */\n initObservable: function () {\n this._super()\n .observe([\n 'rows',\n 'errorMessage'\n ]);\n\n return this;\n },\n\n /**\n * Init component handler\n * @param {Object} rows\n * @return {Object}\n */\n initComponent: function (rows) {\n if (!rows.length) {\n return;\n }\n this.imageMargin = parseInt(this.imageMargin, 10);\n this.container = $('[data-id=\"' + this.containerId + '\"]')[0];\n\n this.setLayoutStyles();\n this.setEventListener();\n\n return this;\n },\n\n /**\n * Set event listener to track resize event\n */\n setEventListener: function () {\n window.addEventListener('resize', function () {\n this.updateStyles();\n }.bind(this));\n },\n\n /**\n * Updates styles for component.\n */\n updateStyles: function () {\n raf(function () {\n this.containerWidth = window.innerWidth;\n this.setLayoutStyles();\n }.bind(this), this.refreshFPS);\n },\n\n /**\n * Set layout styles inside the container\n */\n setLayoutStyles: function () {\n var containerWidth = parseInt(this.container.clientWidth, 10),\n rowImages = [],\n ratio = 0,\n rowHeight = 0,\n calcHeight = 0,\n isLastRow = false,\n rowNumber = 1;\n\n this.setMinRatio();\n\n this.rows().forEach(function (image, index) {\n ratio += parseFloat((image.width / image.height).toFixed(2));\n rowImages.push(image);\n\n if (ratio < this.minRatio && index + 1 !== this.rows().length) {\n // Row has more space for images and the image is not the last one - proceed to the next iteration\n return;\n }\n\n ratio = Math.max(ratio, this.minRatio);\n calcHeight = (containerWidth - this.imageMargin * rowImages.length) / ratio;\n rowHeight = calcHeight < this.maxImageHeight ? calcHeight : this.maxImageHeight;\n isLastRow = index + 1 === this.rows().length;\n\n this.assignImagesToRow(rowImages, rowNumber, rowHeight, isLastRow);\n\n rowImages = [];\n ratio = 0;\n rowNumber++;\n\n }.bind(this));\n },\n\n /**\n * Apply styles, css classes and add properties for images in the row\n *\n * @param {Object[]} images\n * @param {Number} rowNumber\n * @param {Number} rowHeight\n * @param {Boolean} isLastRow\n */\n assignImagesToRow: function (images, rowNumber, rowHeight, isLastRow) {\n var imageWidth;\n\n images.forEach(function (img) {\n imageWidth = rowHeight * (img.width / img.height).toFixed(2);\n this.setImageStyles(img, imageWidth, rowHeight);\n this.setImageClass(img, {\n bottom: isLastRow\n });\n img.rowNumber = rowNumber;\n }.bind(this));\n\n images[0].firstInRow = true;\n images[images.length - 1].lastInRow = true;\n },\n\n /**\n * Wait for container to initialize\n */\n waitForContainer: function (callback) {\n if (typeof this.container === 'undefined') {\n setTimeout(function () {\n this.waitForContainer(callback);\n }.bind(this), 500);\n } else {\n setTimeout(callback, 0);\n }\n },\n\n /**\n * Set layout styles when container element is loaded.\n */\n setLayoutStylesWhenLoaded: function () {\n this.waitForContainer(function () {\n this.setLayoutStyles();\n }.bind(this));\n },\n\n /**\n * Set styles for every image in layout\n *\n * @param {Object} img\n * @param {Number} width\n * @param {Number} height\n */\n setImageStyles: function (img, width, height) {\n if (!img.styles) {\n img.styles = ko.observable();\n }\n img.styles({\n width: parseInt(width, 10) + 'px',\n height: parseInt(height, 10) + 'px'\n });\n },\n\n /**\n * Set css classes to and an image\n *\n * @param {Object} image\n * @param {Object} classes\n */\n setImageClass: function (image, classes) {\n if (!image.css) {\n image.css = ko.observable(classes);\n }\n image.css(classes);\n },\n\n /**\n * Set min ratio for images in layout\n */\n setMinRatio: function () {\n var minRatio = _.find(\n this.containerWidthToMinRatio,\n\n /**\n * Find the minimal ratio for container width in the matrix\n *\n * @param {Number} ratio\n * @param {Number} width\n * @returns {Boolean}\n */\n function (ratio, width) {\n return this.containerWidth <= width;\n },\n this\n );\n\n this.minRatio = minRatio ? minRatio : this.defaultMinRatio;\n },\n\n /**\n * Checks if grid has data.\n *\n * @returns {Boolean}\n */\n hasData: function () {\n return !!this.rows() && !!this.rows().length;\n },\n\n /**\n * Returns error message returned by the data provider\n *\n * @returns {String|null}\n */\n getErrorMessageUnsanitizedHtml: function () {\n return this.errorMessage();\n }\n });\n});\n","Magento_Ui/js/grid/resize.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 'ko',\n 'underscore',\n 'mageUtils',\n 'uiRegistry',\n 'Magento_Ui/js/lib/knockout/extender/bound-nodes',\n 'uiElement'\n], function ($, ko, _, utils, registry, boundedNodes, Element) {\n 'use strict';\n\n return Element.extend({\n defaults: {\n rootSelector: '${ $.columnsProvider }:.admin__data-grid-wrap',\n tableSelector: '${ $.rootSelector } -> table.data-grid',\n mainTableSelector: '[data-role=\"grid\"]',\n columnSelector: '${ $.tableSelector } thead tr th',\n fieldSelector: '${ $.tableSelector } tbody tr td',\n\n imports: {\n storageColumnsData: '${ $.storageConfig.path }.storageColumnsData'\n },\n storageColumnsData: {},\n columnsElements: {},\n tableWidth: 0,\n sumColumnsWidth: 0,\n showLines: 4,\n resizableElementClass: 'shadow-div',\n resizingColumnClass: '_resizing',\n fixedLayoutClass: '_layout-fixed',\n inResizeClass: '_in-resize',\n visibleClass: '_resize-visible',\n cellContentElement: 'div.data-grid-cell-content',\n minColumnWidth: 40,\n layoutFixedPolyfillIterator: 0,\n windowResize: false,\n resizable: false,\n resizeConfig: {\n maxRowsHeight: [],\n curResizeElem: {},\n depResizeElem: {},\n previousWidth: null\n }\n },\n\n /**\n * Initialize application -\n * binding functions context,\n * set handlers for table elements\n *\n * @returns {Object} Chainable\n */\n initialize: function () {\n _.bindAll(\n this,\n 'initTable',\n 'initColumn',\n 'mousedownHandler',\n 'mousemoveHandler',\n 'mouseupHandler',\n 'refreshLastColumn',\n 'refreshMaxRowHeight',\n 'preprocessingWidth',\n '_eventProxy',\n 'checkAfterResize'\n );\n\n this._super();\n this.observe(['maxRowsHeight']);\n this.maxRowsHeight([]);\n\n $.async(this.tableSelector, this.initTable);\n $.async(this.columnSelector, this.initColumn);\n\n return this;\n },\n\n /**\n * Set table element and adds handler to mousedown on headers\n *\n * @returns {Object} Chainable\n */\n initTable: function (table) {\n if ($(table).is(this.mainTableSelector)) {\n this.table = table;\n this.tableWidth = $(table).outerWidth();\n $(window).on('resize', this.checkAfterResize);\n }\n\n //TODO - Must be deleted when Firefox fixed problem with table-layout: fixed\n //ticket to Firefox: https://bugs.webkit.org/show_bug.cgi?id=90068\n if (navigator.userAgent.search(/Firefox/) > -1) {\n this._layoutFixedPolyfill();\n }\n\n $(table).addClass(this.fixedLayoutClass);\n\n return this;\n },\n\n /**\n * Window resize handler,\n * check changes on table width and\n * set new width to variable\n * after window resize start preprocessingWidth method\n */\n checkAfterResize: function () {\n var tableWidth,\n self = this;\n\n setTimeout(function () {\n tableWidth = $(self.table).outerWidth();\n\n if (self.tableWidth !== tableWidth) {\n self.tableWidth = tableWidth;\n } else {\n self.preprocessingWidth();\n }\n }, 300);\n },\n\n /**\n * Check conditions to set minimal width\n */\n checkSumColumnsWidth: function () {\n var table = $(this.table),\n elems = table.find('th:not([style*=\"width: auto\"]):visible'),\n elemsWidthMin = table.find('th[style*=\"width: ' + (this.minColumnWidth - 1) + 'px\"]:visible'),\n elemsWidthAuto = table.find('th[style*=\"width: auto\"]:visible'),\n model;\n\n this.sumColumnsWidth = 0;\n _.each(elems, function (elem) {\n model = ko.dataFor(elem);\n model.width && model.width !== 'auto' ? this.sumColumnsWidth += model.width : false;\n }, this);\n\n if (\n this.sumColumnsWidth + elemsWidthAuto.length *\n this.minColumnWidth + elemsWidthMin.length *\n this.minColumnWidth > this.tableWidth\n ) {\n return true;\n }\n\n return false;\n },\n\n /**\n * Set minimal width to element with \"auto\" width\n */\n setWidthToColumnsWidthAuto: function () {\n var elemsWidthAuto = $(this.table).find('th[style*=\"width: auto\"]:visible');\n\n _.each(elemsWidthAuto, function (elem) {\n $(elem).outerWidth(this.minColumnWidth - 1);\n }, this);\n },\n\n /**\n * Check conditions to set auto width\n */\n hasMinimal: function () {\n var table = $(this.table),\n elemsWidthMin = table.find('th[style*=\"width: ' + (this.minColumnWidth - 1) + 'px\"]:visible'),\n elemsWidthAuto = table.find('th[style*=\"width: auto\"]:visible');\n\n if (\n elemsWidthAuto && this.sumColumnsWidth + elemsWidthAuto.length *\n this.minColumnWidth + elemsWidthMin.length * this.minColumnWidth + 5 < this.tableWidth\n ) {\n return true;\n }\n\n return false;\n },\n\n /**\n * Set \"auto\" width to element with minimal width\n */\n setAuto: function () {\n var elemsWidthAuto = $(this.table).find('th[style*=\"width: ' + (this.minColumnWidth - 1) + 'px\"]:visible');\n\n _.each(elemsWidthAuto, function (elem) {\n $(elem).outerWidth('auto');\n }, this);\n },\n\n /**\n * Check columns width and preprocessing\n */\n preprocessingWidth: function () {\n if (this.checkSumColumnsWidth()) {\n this.setWidthToColumnsWidthAuto();\n } else if (this.hasMinimal()) {\n this.setAuto();\n }\n },\n\n /**\n * Init columns elements,\n * set width to current column element,\n * add resizable element to columns header,\n * check and add no-resize class to last column,\n * stop parents events,\n * add handler to visibility column\n *\n * @param {Object} column - columns header element (th)\n */\n initColumn: function (column) {\n var model = ko.dataFor(column),\n ctxIndex = this.getCtxIndex(ko.contextFor(column));\n\n model.width = this.getDefaultWidth(column);\n\n if (!this.hasColumn(model, ctxIndex, false)) {\n this.columnsElements[model.index] = this.columnsElements[model.index] || {};\n this.columnsElements[model.index][ctxIndex] = column;\n this.initResizableElement(column);\n this.setStopPropagationHandler(column);\n $(column).outerWidth(model.width);\n }\n\n this.refreshLastColumn(column);\n this.preprocessingWidth();\n\n model.on('visible', this.refreshLastColumn.bind(this, column));\n model.on('visible', this.preprocessingWidth.bind(this));\n },\n\n /**\n * Hack for mozilla firefox\n */\n _layoutFixedPolyfill: function () {\n var self = this;\n\n setTimeout(function () {\n if (self.layoutFixedPolyfillIterator < 20) {\n $(window).trigger('resize');\n self.layoutFixedPolyfillIterator++;\n self._layoutFixedPolyfill();\n } else {\n return false;\n }\n }, 500);\n },\n\n /**\n * Check element is resizable or not\n * and append resizable element to DOM\n *\n * @param {Object} column - columns header element (th)\n * @returns {Boolean}\n */\n initResizableElement: function (column) {\n var model = ko.dataFor(column),\n templateDragElement = '<div class=\"' + this.resizableElementClass + '\"></div>';\n\n if (_.isUndefined(model.resizeEnabled) || model.resizeEnabled) {\n $(column).append(templateDragElement);\n\n return true;\n }\n\n return false;\n },\n\n /**\n * Check event target and if need stop parents event,\n *\n * @param {Object} column - columns header element (th)\n * @returns {Boolean}\n */\n setStopPropagationHandler: function (column) {\n var events,\n click,\n mousedown;\n\n $(column).on('click', this._eventProxy);\n $(column).on('mousedown', this._eventProxy);\n\n events = $._data(column, 'events');\n\n click = events.click;\n mousedown = events.mousedown;\n click.unshift(click.pop());\n mousedown.unshift(mousedown.pop());\n\n return this;\n },\n\n /**\n * Check event target and stop event if need\n *\n * @param {Object} event\n */\n _eventProxy: function (event) {\n if ($(event.target).is('.' + this.resizableElementClass)) {\n\n if (event.type === 'click') {\n event.stopImmediatePropagation();\n } else if (event.type === 'mousedown') {\n this.mousedownHandler(event);\n }\n }\n },\n\n /**\n * Check visible columns and set disable class to resizable elements,\n *\n * @param {Object} column - columns header element (th)\n */\n refreshLastColumn: function (column) {\n var i = 0,\n columns = $(column).parent().children().not(':hidden'),\n length = columns.length;\n\n $('.' + this.visibleClass).removeClass(this.visibleClass);\n\n $(column).parent().children().not(':hidden').last().addClass(this.visibleClass);\n\n for (i; i < length; i++) {\n\n if (!columns.eq(i).find('.' + this.resizableElementClass).length && i) {\n columns.eq(i - 1).addClass(this.visibleClass);\n }\n }\n\n },\n\n /**\n * Refresh max height to row elements,\n *\n * @param {Object} elem - (td)\n */\n refreshMaxRowHeight: function (elem) {\n var rowsH = this.maxRowsHeight(),\n curEL = $(elem).find('div'),\n height,\n obj = this.hasRow($(elem).parent()[0], true);\n\n curEL.css('white-space', 'nowrap');\n height = curEL.height() * this.showLines;\n curEL.css('white-space', 'normal');\n\n if (obj) {\n if (obj.maxHeight < height) {\n rowsH[_.indexOf(rowsH, obj)].maxHeight = height;\n } else {\n return false;\n }\n } else {\n rowsH.push({\n elem: $(elem).parent()[0],\n maxHeight: height\n });\n }\n\n $(elem).parent().children().find(this.cellContentElement).css('max-height', height + 'px');\n this.maxRowsHeight(rowsH);\n },\n\n /**\n * Set resize class to elements when resizable\n */\n _setResizeClass: function () {\n var rowElements = $(this.table).find('tr');\n\n rowElements\n .find('td:eq(' + this.resizeConfig.curResizeElem.ctx.$index() + ')')\n .addClass(this.resizingColumnClass);\n rowElements\n .find('td:eq(' + this.resizeConfig.depResizeElem.ctx.$index() + ')')\n .addClass(this.resizingColumnClass);\n },\n\n /**\n * Remove resize class to elements when resizable\n */\n _removeResizeClass: function () {\n var rowElements = $(this.table).find('tr');\n\n rowElements\n .find('td:eq(' + this.resizeConfig.curResizeElem.ctx.$index() + ')')\n .removeClass(this.resizingColumnClass);\n rowElements\n .find('td:eq(' + this.resizeConfig.depResizeElem.ctx.$index() + ')')\n .removeClass(this.resizingColumnClass);\n },\n\n /**\n * Check conditions to resize\n *\n * @returns {Boolean}\n */\n _canResize: function (column) {\n if (\n $(column).hasClass(this.visibleClass) ||\n !$(this.resizeConfig.depResizeElem.elems[0]).find('.' + this.resizableElementClass).length\n ) {\n return false;\n }\n\n return true;\n },\n\n /**\n * Mouse down event handler,\n * find current and dep column to resize\n *\n * @param {Object} event\n */\n mousedownHandler: function (event) {\n var target = event.target,\n column = $(target).parent()[0],\n cfg = this.resizeConfig,\n body = $('body');\n\n event.stopImmediatePropagation();\n cfg.curResizeElem.model = ko.dataFor(column);\n cfg.curResizeElem.ctx = ko.contextFor(column);\n cfg.curResizeElem.elems = this.hasColumn(cfg.curResizeElem.model, false, true);\n cfg.curResizeElem.position = event.pageX;\n cfg.depResizeElem.elems = this.getNextElements(cfg.curResizeElem.elems[0]);\n cfg.depResizeElem.model = ko.dataFor(cfg.depResizeElem.elems[0]);\n cfg.depResizeElem.ctx = ko.contextFor(cfg.depResizeElem.elems[0]);\n\n this._setResizeClass();\n\n if (!this._canResize(column)) {\n return false;\n }\n\n event.stopPropagation();\n this.resizable = true;\n cfg.curResizeElem.model.width = $(cfg.curResizeElem.elems[0]).outerWidth();\n cfg.depResizeElem.model.width = $(cfg.depResizeElem.elems[0]).outerWidth();\n body.addClass(this.inResizeClass);\n body.on('mousemove', this.mousemoveHandler);\n $(window).on('mouseup', this.mouseupHandler);\n },\n\n /**\n * Mouse move event handler,\n * change columns width\n *\n * @param {Object} event\n */\n mousemoveHandler: function (event) {\n var cfg = this.resizeConfig,\n width = event.pageX - cfg.curResizeElem.position,\n self = this;\n\n event.stopPropagation();\n event.preventDefault();\n\n if (\n this.resizable &&\n this.minColumnWidth < cfg.curResizeElem.model.width + width &&\n this.minColumnWidth < cfg.depResizeElem.model.width - width &&\n cfg.previousWidth !== width\n ) {\n cfg.curResizeElem.model.width += width;\n cfg.depResizeElem.model.width -= width;\n\n cfg.curResizeElem.elems.forEach(function (el) {\n $(el).outerWidth(cfg.curResizeElem.model.width);\n });\n cfg.depResizeElem.elems.forEach(function (el) {\n $(el).outerWidth(cfg.depResizeElem.model.width);\n });\n\n cfg.previousWidth = width;\n cfg.curResizeElem.position = event.pageX;\n } else if (width <= -(cfg.curResizeElem.model.width - this.minColumnWidth)) {\n\n cfg.curResizeElem.elems.forEach(function (el) {\n $(el).outerWidth(self.minColumnWidth);\n });\n cfg.depResizeElem.elems.forEach(function (el) {\n $(el).outerWidth(\n cfg.depResizeElem.model.width +\n cfg.curResizeElem.model.width -\n self.minColumnWidth);\n });\n\n } else if (width >= cfg.depResizeElem.model.width - this.minColumnWidth) {\n\n cfg.depResizeElem.elems.forEach(function (el) {\n $(el).outerWidth(self.minColumnWidth);\n });\n cfg.curResizeElem.elems.forEach(function (el) {\n $(el).outerWidth(\n cfg.curResizeElem.model.width +\n cfg.depResizeElem.model.width -\n self.minColumnWidth\n );\n });\n }\n },\n\n /**\n * Mouse up event handler,\n * change columns width\n *\n * @param {Object} event\n */\n mouseupHandler: function (event) {\n var cfg = this.resizeConfig,\n body = $('body');\n\n event.stopPropagation();\n event.preventDefault();\n\n this._removeResizeClass();\n this.storageColumnsData[cfg.curResizeElem.model.index] = cfg.curResizeElem.model.width;\n this.storageColumnsData[cfg.depResizeElem.model.index] = cfg.depResizeElem.model.width;\n this.resizable = false;\n\n this.store('storageColumnsData');\n\n body.removeClass(this.inResizeClass);\n body.off('mousemove', this.mousemoveHandler);\n $(window).off('mouseup', this.mouseupHandler);\n },\n\n /**\n * Find dependency element\n *\n * @param {Object} element - current element\n * @returns {Object} next element data\n */\n getNextElements: function (element) {\n var nextElem = $(element).next()[0],\n nextElemModel = ko.dataFor(nextElem),\n nextElemData = this.hasColumn(nextElemModel, false, true);\n\n if (nextElemData) {\n if (nextElemModel.visible) {\n return nextElemData;\n }\n\n return this.getNextElements(nextElem);\n }\n },\n\n /**\n * Get default width\n *\n * @param {Object} column - (th) element\n * @return {String} width for current column\n */\n getDefaultWidth: function (column) {\n var model = ko.dataFor(column);\n\n if (this.storageColumnsData[model.index]) {\n return this.storageColumnsData[model.index];\n }\n\n if (model.resizeDefaultWidth) {\n return parseInt(model.resizeDefaultWidth, 10);\n }\n\n return 'auto';\n },\n\n /**\n * Check column is render or not\n *\n * @param {Object} model - cur column model\n * @param {String|Boolean} ctxIndex - index of context, or false, if want to get cols from all ctx\n * @param {Boolean} returned - need return column object or not\n * @return {Boolean} if returned param is false, returned boolean value, else return current object data\n */\n hasColumn: function (model, ctxIndex, returned) {\n var colElem = this.columnsElements[model.index] || {},\n getFromAllCtx = ctxIndex === false;\n\n if (colElem && (getFromAllCtx || colElem.hasOwnProperty(ctxIndex))) {\n\n if (returned) {\n return getFromAllCtx ?\n _.values(colElem) :\n colElem[ctxIndex];\n }\n\n return true;\n }\n\n return false;\n },\n\n /**\n * Check row is render or not\n *\n * @param {Object} elem - cur column element\n * @param {Boolean} returned - need return column object or not\n * @return {Boolean|Object} if returned param is false, returned boolean value, else return current object data\n */\n hasRow: function (elem, returned) {\n var i = 0,\n el = this.maxRowsHeight(),\n length = el.length;\n\n for (i; i < length; i++) {\n if (this.maxRowsHeight()[i].elem === elem) {\n if (returned) {//eslint-disable-line max-depth\n return this.maxRowsHeight()[i];\n }\n\n return true;\n }\n }\n\n return false;\n },\n\n /**\n * Generate index that will identify context\n *\n * @param {Object} ctx\n * @return {String}\n */\n getCtxIndex: function (ctx) {\n return ctx ? ctx.$parents.reduce(function (pv, cv) {\n return (pv.index || pv) + (cv || {}).index;\n }) : ctx;\n }\n });\n});\n","Magento_Ui/js/grid/listing.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 'Magento_Ui/js/lib/spinner',\n 'rjsResolver',\n 'uiLayout',\n 'uiCollection'\n], function (ko, _, loader, resolver, layout, Collection) {\n 'use strict';\n\n return Collection.extend({\n defaults: {\n template: 'ui/grid/listing',\n listTemplate: 'ui/list/listing',\n stickyTmpl: 'ui/grid/sticky/listing',\n viewSwitcherTmpl: 'ui/grid/view-switcher',\n positions: false,\n displayMode: 'grid',\n displayModes: {\n grid: {\n value: 'grid',\n label: 'Grid',\n template: '${ $.template }'\n },\n list: {\n value: 'list',\n label: 'List',\n template: '${ $.listTemplate }'\n }\n },\n dndConfig: {\n name: '${ $.name }_dnd',\n component: 'Magento_Ui/js/grid/dnd',\n columnsProvider: '${ $.name }',\n enabled: true\n },\n editorConfig: {\n name: '${ $.name }_editor',\n component: 'Magento_Ui/js/grid/editing/editor',\n columnsProvider: '${ $.name }',\n dataProvider: '${ $.provider }',\n enabled: false\n },\n resizeConfig: {\n name: '${ $.name }_resize',\n columnsProvider: '${ $.name }',\n component: 'Magento_Ui/js/grid/resize',\n enabled: false\n },\n imports: {\n rows: '${ $.provider }:data.items'\n },\n listens: {\n elems: 'updatePositions updateVisible',\n '${ $.provider }:reload': 'onBeforeReload',\n '${ $.provider }:reloaded': 'onDataReloaded'\n },\n modules: {\n dnd: '${ $.dndConfig.name }',\n resize: '${ $.resizeConfig.name }'\n },\n tracks: {\n displayMode: true\n },\n statefull: {\n displayMode: true\n }\n },\n\n /**\n * Initializes Listing component.\n *\n * @returns {Listing} Chainable.\n */\n initialize: function () {\n _.bindAll(this, 'updateVisible');\n\n this._super()\n .initDnd()\n .initEditor()\n .initResize();\n\n return this;\n },\n\n /**\n * Initializes observable properties.\n *\n * @returns {Listing} Chainable.\n */\n initObservable: function () {\n this._super()\n .track({\n rows: [],\n visibleColumns: []\n });\n\n return this;\n },\n\n /**\n * Creates drag&drop widget instance.\n *\n * @returns {Listing} Chainable.\n */\n initDnd: function () {\n if (this.dndConfig.enabled) {\n layout([this.dndConfig]);\n }\n\n return this;\n },\n\n /**\n * Initializes resize component.\n *\n * @returns {Listing} Chainable.\n */\n initResize: function () {\n if (this.resizeConfig.enabled) {\n layout([this.resizeConfig]);\n }\n\n return this;\n },\n\n /**\n * Creates inline editing component.\n *\n * @returns {Listing} Chainable.\n */\n initEditor: function () {\n if (this.editorConfig.enabled) {\n layout([this.editorConfig]);\n }\n\n return this;\n },\n\n /**\n * Called when another element was added to current component.\n *\n * @returns {Listing} Chainable.\n */\n initElement: function (element) {\n var currentCount = this.elems().length,\n totalCount = this.initChildCount;\n\n if (totalCount === currentCount) {\n this.initPositions();\n }\n\n element.on('visible', this.updateVisible);\n\n return this._super();\n },\n\n /**\n * Defines initial order of child elements.\n *\n * @returns {Listing} Chainable.\n */\n initPositions: function () {\n this.on('positions', this.applyPositions.bind(this));\n\n this.setStatefull('positions');\n\n return this;\n },\n\n /**\n * Updates current state of child positions.\n *\n * @returns {Listing} Chainable.\n */\n updatePositions: function () {\n var positions = {};\n\n this.elems.each(function (elem, index) {\n positions[elem.index] = index;\n });\n\n this.set('positions', positions);\n\n return this;\n },\n\n /**\n * Resorts child elements array according to provided positions.\n *\n * @param {Object} positions - Object where key represents child\n * index and value is its' position.\n * @returns {Listing} Chainable.\n */\n applyPositions: function (positions) {\n var sorting;\n\n sorting = this.elems.map(function (elem) {\n return {\n elem: elem,\n position: positions[elem.index]\n };\n });\n\n this.insertChild(sorting);\n\n return this;\n },\n\n /**\n * Returns reference to 'visibleColumns' array.\n *\n * @returns {Array}\n */\n getVisible: function () {\n var observable = ko.getObservable(this, 'visibleColumns');\n\n return observable || this.visibleColumns;\n },\n\n /**\n * Returns path to the template\n * defined for a current display mode.\n *\n * @returns {String} Path to the template.\n */\n getTemplate: function () {\n var mode = this.displayModes[this.displayMode];\n\n return mode.template;\n },\n\n /**\n * Returns an array of available display modes.\n *\n * @returns {Array<Object>}\n */\n getDisplayModes: function () {\n var modes = this.displayModes;\n\n return _.values(modes);\n },\n\n /**\n * Sets display mode to provided value.\n *\n * @param {String} index\n * @returns {Listing} Chainable\n */\n setDisplayMode: function (index) {\n this.displayMode = index;\n\n return this;\n },\n\n /**\n * Returns total number of displayed columns in grid.\n *\n * @returns {Number}\n */\n countVisible: function () {\n return this.visibleColumns.length;\n },\n\n /**\n * Updates array of visible columns.\n *\n * @returns {Listing} Chainable.\n */\n updateVisible: function () {\n this.visibleColumns = this.elems.filter('visible');\n\n return this;\n },\n\n /**\n * Checks if grid has data.\n *\n * @returns {Boolean}\n */\n hasData: function () {\n return !!this.rows && !!this.rows.length;\n },\n\n /**\n * Hides loader.\n */\n hideLoader: function () {\n loader.get(this.name).hide();\n },\n\n /**\n * Shows loader.\n */\n showLoader: function () {\n loader.get(this.name).show();\n },\n\n /**\n * Handler of the data providers' 'reload' event.\n */\n onBeforeReload: function () {\n this.showLoader();\n },\n\n /**\n * Handler of the data providers' 'reloaded' event.\n */\n onDataReloaded: function () {\n resolver(this.hideLoader, this);\n }\n });\n});\n","Magento_Ui/js/grid/export.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 'uiElement'\n], function ($, _, Element) {\n 'use strict';\n\n return Element.extend({\n defaults: {\n template: 'ui/grid/exportButton',\n selectProvider: 'ns = ${ $.ns }, index = ids',\n checked: '',\n additionalParams: [],\n modules: {\n selections: '${ $.selectProvider }'\n }\n },\n\n /** @inheritdoc */\n initialize: function () {\n this._super()\n .initChecked();\n },\n\n /** @inheritdoc */\n initConfig: function () {\n this._super();\n\n _.each(this.additionalParams, function (value, key) {\n key = 'additionalParams.' + key;\n this.imports[key] = value;\n }, this);\n\n return this;\n },\n\n /** @inheritdoc */\n initObservable: function () {\n this._super()\n .observe('checked');\n\n return this;\n },\n\n /**\n * Checks first option if checked not defined.\n *\n * @returns {Object}\n */\n initChecked: function () {\n if (!this.checked()) {\n this.checked(\n this.options[0].value\n );\n }\n\n return this;\n },\n\n /**\n * Compose params object that will be added to request.\n *\n * @returns {Object}\n */\n getParams: function () {\n var selections = this.selections(),\n data = selections ? selections.getSelections() : null,\n itemsType,\n result = {};\n\n if (data) {\n itemsType = data.excludeMode ? 'excluded' : 'selected';\n result.filters = data.params.filters;\n result.search = data.params.search;\n result.namespace = data.params.namespace;\n result[itemsType] = data[itemsType];\n _.each(this.additionalParams, function (param, key) {\n result[key] = param;\n });\n\n if (!result[itemsType].length) {\n result[itemsType] = false;\n }\n }\n\n return result;\n },\n\n /**\n * Find checked option.\n *\n * @returns {Object}\n */\n getActiveOption: function () {\n return _.findWhere(this.options, {\n value: this.checked()\n });\n },\n\n /**\n * Build option url.\n *\n * @param {Object} option\n * @returns {String}\n */\n buildOptionUrl: function (option) {\n var params = this.getParams();\n\n if (!params) {\n return 'javascript:void(0);';\n }\n\n return option.url + '?' + $.param(params);\n //TODO: MAGETWO-40250\n },\n\n /**\n * Redirect to built option url.\n */\n applyOption: function () {\n var option = this.getActiveOption(),\n url = this.buildOptionUrl(option);\n\n location.href = url;\n\n }\n });\n});\n","Magento_Ui/js/grid/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 'jquery',\n 'underscore',\n 'mageUtils',\n 'rjsResolver',\n 'uiLayout',\n 'Magento_Ui/js/modal/alert',\n 'mage/translate',\n 'uiElement',\n 'uiRegistry',\n 'Magento_Ui/js/grid/data-storage'\n], function ($, _, utils, resolver, layout, alert, $t, Element, registry) {\n 'use strict';\n\n return Element.extend({\n defaults: {\n firstLoad: true,\n lastError: false,\n storageConfig: {\n component: 'Magento_Ui/js/grid/data-storage',\n provider: '${ $.storageConfig.name }',\n name: '${ $.name }_storage',\n updateUrl: '${ $.update_url }'\n },\n listens: {\n params: 'onParamsChange',\n requestConfig: 'updateRequestConfig'\n },\n ignoreTmpls: {\n data: true\n },\n triggerDataReload: false\n },\n\n /**\n * Initializes provider component.\n *\n * @returns {Provider} Chainable.\n */\n initialize: function () {\n utils.limit(this, 'onParamsChange', 5);\n _.bindAll(this, 'onReload');\n\n this._super()\n .initStorage()\n .clearData();\n\n // Load data when there will\n // be no more pending assets.\n resolver(this.reload, this);\n\n return this;\n },\n\n /**\n * Initializes storage component.\n *\n * @returns {Provider} Chainable.\n */\n initStorage: function () {\n layout([this.storageConfig]);\n\n return this;\n },\n\n /**\n * Clears provider's data properties.\n *\n * @returns {Provider} Chainable.\n */\n clearData: function () {\n this.setData({\n items: [],\n totalRecords: 0,\n showTotalRecords: true\n });\n\n return this;\n },\n\n /**\n * Overrides current data with a provided one.\n *\n * @param {Object} data - New data object.\n * @returns {Provider} Chainable.\n */\n setData: function (data) {\n data = this.processData(data);\n\n this.set('data', data);\n\n return this;\n },\n\n /**\n * Processes data before applying it.\n *\n * @param {Object} data - Data to be processed.\n * @returns {Object}\n */\n processData: function (data) {\n var items = data.items;\n\n _.each(items, function (record, index) {\n record._rowIndex = index;\n });\n\n return data;\n },\n\n /**\n * Reloads data with current parameters.\n *\n * @returns {Promise} Reload promise object.\n */\n reload: function (options) {\n var request = this.storage().getData(this.params, options);\n\n this.trigger('reload');\n\n request\n .done(this.onReload)\n .fail(this.onError.bind(this));\n\n return request;\n },\n\n /**\n * Handles changes of 'params' object.\n */\n onParamsChange: function () {\n // It's necessary to make a reload only\n // after the initial loading has been made.\n if (!this.firstLoad) {\n this.reload();\n } else {\n this.triggerDataReload = true;\n }\n },\n\n /**\n * Handles reload error.\n */\n onError: function (xhr) {\n if (xhr.statusText === 'abort') {\n return;\n }\n\n this.set('lastError', true);\n\n this.firstLoad = false;\n this.triggerDataReload = false;\n\n alert({\n content: $t('Something went wrong.')\n });\n },\n\n /**\n * Handles successful data reload.\n *\n * @param {Object} data - Retrieved data object.\n */\n onReload: function (data) {\n this.firstLoad = false;\n this.set('lastError', false);\n this.setData(data)\n .trigger('reloaded');\n\n if (this.triggerDataReload) {\n this.triggerDataReload = false;\n this.reload();\n }\n },\n\n /**\n * Updates storage's request configuration\n *\n * @param {Object} requestConfig\n */\n updateRequestConfig: function (requestConfig) {\n registry.get(this.storageConfig.provider, function (storage) {\n _.extend(storage.requestConfig, requestConfig);\n });\n }\n });\n});\n","Magento_Ui/js/grid/toolbar.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/view/utils/async',\n 'Magento_Ui/js/lib/view/utils/raf',\n 'rjsResolver',\n 'uiCollection'\n], function (_, $, raf, resolver, Collection) {\n 'use strict';\n\n var transformProp;\n\n /**\n * Defines supported css 'transform' property.\n *\n * @returns {String|Undefined}\n */\n transformProp = (function () {\n var style = document.documentElement.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 /**\n * Moves specified DOM element to the x and y coordinates.\n *\n * @param {HTMLElement} elem - Element to be relocated.\n * @param {Number} x - X coordinate.\n * @param {Number} y - Y coordinate.\n */\n function locate(elem, x, y) {\n var value = 'translate(' + x + 'px,' + y + 'px)';\n\n elem.style[transformProp] = value;\n }\n\n return Collection.extend({\n defaults: {\n template: 'ui/grid/toolbar',\n stickyTmpl: 'ui/grid/sticky/sticky',\n tableSelector: 'table',\n columnsProvider: 'ns = ${ $.ns }, componentType = columns',\n refreshFPS: 15,\n sticky: false,\n visible: false,\n _resized: true,\n _scrolled: true,\n _tableScrolled: true,\n _requiredNodes: {\n '$stickyToolbar': true,\n '$stickyTable': true,\n '$table': true,\n '$sticky': true\n },\n stickyClass: {\n 'sticky-header': true\n }\n },\n\n /**\n * Initializes sticky toolbar component.\n *\n * @returns {Sticky} Chainable.\n */\n initialize: function () {\n this._super();\n\n if (this.sticky) {\n this.waitDOMElements()\n .then(this.run.bind(this));\n }\n\n return this;\n },\n\n /**\n * Establishes DOM elements wait process.\n *\n * @returns {jQueryPromise} Promise which will be resolved\n * when all of the required DOM elements are defined.\n */\n waitDOMElements: function () {\n var _domPromise = $.Deferred();\n\n _.bindAll(this, 'setStickyTable', 'setTableNode');\n\n $.async({\n ctx: ':not([data-role=\"sticky-el-root\"])',\n component: this.columnsProvider,\n selector: this.tableSelector\n }, this.setTableNode);\n\n $.async({\n ctx: '[data-role=\"sticky-el-root\"]',\n component: this.columnsProvider,\n selector: this.tableSelector\n }, this.setStickyTable);\n\n this._domPromise = _domPromise;\n\n return _domPromise.promise();\n },\n\n /**\n * Defines left caption element.\n *\n * @param {HTMLElement} node\n */\n setLeftCap: function (node) {\n this.$leftCap = node;\n },\n\n /**\n * Defines right caption element.\n *\n * @param {HTMLElement} node\n */\n setRightCap: function (node) {\n this.$rightCap = node;\n },\n\n /**\n * Defines original table element.\n *\n * @param {HTMLTableElement} node\n */\n setTableNode: function (node) {\n this.$cols = node.tHead.children[0].cells;\n this.$tableContainer = node.parentNode;\n\n this.setNode('$table', node);\n },\n\n /**\n * Defines sticky table element.\n *\n * @param {HTMLTableElement} node\n */\n setStickyTable: function (node) {\n this.$stickyCols = node.tHead.children[0].cells;\n\n this.setNode('$stickyTable', node);\n },\n\n /**\n * Defines sticky toolbar node.\n *\n * @param {HTMLElement} node\n */\n setStickyToolbarNode: function (node) {\n this.setNode('$stickyToolbar', node);\n },\n\n /**\n * Defines sticky element container.\n *\n * @param {HTMLElement} node\n */\n setStickyNode: function (node) {\n this.setNode('$sticky', node);\n },\n\n /**\n * Defines toolbar element container.\n *\n * @param {HTMLElement} node\n */\n setToolbarNode: function (node) {\n this.$toolbar = node;\n },\n\n /**\n * Sets provided node as a value of 'key' property and\n * performs check for required DOM elements.\n *\n * @param {String} key - Properties key.\n * @param {HTMLElement} node - DOM element.\n */\n setNode: function (key, node) {\n var nodes = this._requiredNodes,\n promise = this._domPromise,\n defined;\n\n this[key] = node;\n\n defined = _.every(nodes, function (enabled, name) {\n return enabled ? this[name] : true;\n }, this);\n\n if (defined) {\n resolver(promise.resolve, promise);\n }\n },\n\n /**\n * Starts refresh process of the sticky element\n * and assigns DOM elements events handlers.\n */\n run: function () {\n _.bindAll(\n this,\n 'refresh',\n '_onWindowResize',\n '_onWindowScroll',\n '_onTableScroll'\n );\n\n $(window).on({\n scroll: this._onWindowScroll,\n resize: this._onWindowResize\n });\n\n $(this.$tableContainer).on('scroll', this._onTableScroll);\n\n this.refresh();\n this.checkTableWidth();\n },\n\n /**\n * Refreshes state of the sticky element and\n * invokes DOM elements events handlers\n * if corresponding event has been triggered.\n */\n refresh: function () {\n if (!raf(this.refresh, this.refreshFPS)) {\n return;\n }\n\n if (this._scrolled) {\n this.onWindowScroll();\n }\n\n if (this._tableScrolled) {\n this.onTableScroll();\n }\n\n if (this._resized) {\n this.onWindowResize();\n }\n\n if (this.visible) {\n this.checkTableWidth();\n }\n },\n\n /**\n * Shows sticky toolbar.\n *\n * @returns {Sticky} Chainable.\n */\n show: function () {\n this.visible = true;\n //Check admin grid button has addedr not\n if ($('.page-main-actions').length === 0) {\n this.$sticky.style.top = 0;\n }\n this.$sticky.style.display = '';\n this.$toolbar.style.visibility = 'hidden';\n\n return this;\n },\n\n /**\n * Hides sticky toolbar.\n *\n * @returns {Sticky} Chainable.\n */\n hide: function () {\n this.visible = false;\n\n this.$sticky.style.display = 'none';\n this.$toolbar.style.visibility = '';\n\n return this;\n },\n\n /**\n * Checks if sticky toolbar covers original elements.\n *\n * @returns {Boolean}\n */\n isCovered: function () {\n var stickyTop = this._stickyTableTop + this._wScrollTop;\n\n return stickyTop > this._tableTop;\n },\n\n /**\n * Updates offset of the sticky table element.\n *\n * @returns {Sticky} Chainable.\n */\n updateStickyTableOffset: function () {\n var style,\n top;\n\n if (this.visible) {\n top = this.$stickyTable.getBoundingClientRect().top;\n } else {\n style = this.$sticky.style;\n\n style.visibility = 'hidden';\n style.display = '';\n\n top = this.$stickyTable.getBoundingClientRect().top;\n\n style.display = 'none';\n style.visibility = '';\n }\n\n this._stickyTableTop = top;\n\n return this;\n },\n\n /**\n * Updates offset of the original table element.\n *\n * @returns {Sticky} Chainable.\n */\n updateTableOffset: function () {\n var box = this.$table.getBoundingClientRect(),\n top = box.top + this._wScrollTop;\n\n if (this._tableTop !== top) {\n this._tableTop = top;\n\n this.onTableTopChange(top);\n }\n\n return this;\n },\n\n /**\n * Checks if width of the table or it's columns has changed.\n *\n * @returns {Sticky} Chainable.\n */\n checkTableWidth: function () {\n var cols = this.$cols,\n total = cols.length,\n rightBorder = cols[total - 2].offsetLeft,\n tableWidth = this.$table.offsetWidth;\n\n if (this._tableWidth !== tableWidth) {\n this._tableWidth = tableWidth;\n\n this.onTableWidthChange(tableWidth);\n }\n\n if (this._rightBorder !== rightBorder) {\n this._rightBorder = rightBorder;\n\n this.onColumnsWidthChange();\n }\n\n return this;\n },\n\n /**\n * Updates width of the sticky table.\n *\n * @returns {Sticky} Chainable.\n */\n updateTableWidth: function () {\n this.$stickyTable.style.width = this._tableWidth + 'px';\n\n if (this._tableWidth < this._toolbarWidth) {\n this.checkToolbarSize();\n }\n\n return this;\n },\n\n /**\n * Updates width of the sticky columns.\n *\n * @returns {Sticky} Chainable.\n */\n updateColumnsWidth: function () {\n var cols = this.$cols,\n index = cols.length,\n stickyCols = this.$stickyCols;\n\n while (index--) {\n stickyCols[index].width = cols[index].offsetWidth;\n }\n\n return this;\n },\n\n /**\n * Upadates size of the sticky toolbar element\n * and invokes corresponding 'change' event handlers.\n *\n * @returns {Sticky} Chainable.\n */\n checkToolbarSize: function () {\n var width = this.$tableContainer.offsetWidth;\n\n if (this._toolbarWidth !== width) {\n this._toolbarWidth = width;\n\n this.onToolbarWidthChange(width);\n }\n\n return this;\n },\n\n /**\n * Toggles sticky toolbar visibility if it's necessary.\n *\n * @returns {Sticky} Chainable.\n */\n updateVisibility: function () {\n if (this.visible !== this.isCovered()) {\n this.visible ? this.hide() : this.show();\n }\n\n return this;\n },\n\n /**\n * Updates position of the left cover area.\n *\n * @returns {Sticky} Chainable.\n */\n updateLeftCap: function () {\n locate(this.$leftCap, -this._wScrollLeft, 0);\n\n return this;\n },\n\n /**\n * Updates position of the right cover area.\n *\n * @returns {Sticky} Chainable.\n */\n updateRightCap: function () {\n var left = this._toolbarWidth - this._wScrollLeft;\n\n locate(this.$rightCap, left, 0);\n\n return this;\n },\n\n /**\n * Updates position of the sticky table.\n *\n * @returns {Sticky} Chainable.\n */\n updateTableScroll: function () {\n var container = this.$tableContainer,\n left = container.scrollLeft + this._wScrollLeft;\n\n locate(this.$stickyTable, -left, 0);\n\n return this;\n },\n\n /**\n * Updates width of the toolbar element.\n *\n * @returns {Sticky} Chainable.\n */\n updateToolbarWidth: function () {\n this.$stickyToolbar.style.width = this._toolbarWidth + 'px';\n\n return this;\n },\n\n /**\n * Handles changes of the toolbar element's width.\n */\n onToolbarWidthChange: function () {\n this.updateToolbarWidth()\n .updateRightCap();\n },\n\n /**\n * Handles changes of the table top position.\n */\n onTableTopChange: function () {\n this.updateStickyTableOffset();\n },\n\n /**\n * Handles change of the table width.\n */\n onTableWidthChange: function () {\n this.updateTableWidth();\n },\n\n /**\n * Handles change of the table columns width.\n */\n onColumnsWidthChange: function () {\n this.updateColumnsWidth();\n },\n\n /**\n * Handles changes of the window's size.\n */\n onWindowResize: function () {\n this.checkToolbarSize();\n\n this._resized = false;\n },\n\n /**\n * Handles changes of the original table scroll position.\n */\n onTableScroll: function () {\n this.updateTableScroll();\n\n this._tableScrolled = false;\n },\n\n /**\n * Handles changes of window's scroll position.\n */\n onWindowScroll: function () {\n var scrollTop = window.pageYOffset,\n scrollLeft = window.pageXOffset;\n\n if (this._wScrollTop !== scrollTop) {\n this._wScrollTop = scrollTop;\n\n this.onWindowScrollTop(scrollTop);\n }\n\n if (this._wScrollLeft !== scrollLeft) {\n this._wScrollLeft = scrollLeft;\n\n this.onWindowScrollLeft(scrollLeft);\n }\n\n this._scrolled = false;\n },\n\n /**\n * Handles changes of windows' top scroll position.\n */\n onWindowScrollTop: function () {\n this.updateTableOffset()\n .updateVisibility();\n },\n\n /**\n * Handles changes of windows' left scroll position.\n */\n onWindowScrollLeft: function () {\n this.updateRightCap()\n .updateLeftCap()\n .updateTableScroll();\n },\n\n /**\n * Original window 'scroll' event handler.\n * Sets 'scrolled' flag to 'true'.\n *\n * @private\n */\n _onWindowScroll: function () {\n this._scrolled = true;\n },\n\n /**\n * Original window 'resize' event handler.\n * Sets 'resized' flag to 'true'.\n *\n * @private\n */\n _onWindowResize: function () {\n this._resized = true;\n },\n\n /**\n * Original table 'scroll' event handler.\n * Sets '_tableScrolled' flag to 'true'.\n *\n * @private\n */\n _onTableScroll: function () {\n this._tableScrolled = true;\n }\n });\n});\n","Magento_Ui/js/grid/tree-massactions.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 'Magento_Ui/js/grid/massactions'\n], function (ko, _, Massactions) {\n 'use strict';\n\n return Massactions.extend({\n defaults: {\n template: 'ui/grid/tree-massactions',\n submenuTemplate: 'ui/grid/submenu',\n listens: {\n opened: 'hideSubmenus'\n }\n },\n\n /**\n * Initializes observable properties.\n *\n * @returns {Massactions} Chainable.\n */\n initObservable: function () {\n this._super()\n .recursiveObserveActions(this.actions());\n\n return this;\n },\n\n /**\n * Recursive initializes observable actions.\n *\n * @param {Array} actions - Action objects.\n * @param {String} [prefix] - An optional string that will be prepended\n * to the \"type\" field of all child actions.\n * @returns {Massactions} Chainable.\n */\n recursiveObserveActions: function (actions, prefix) {\n _.each(actions, function (action) {\n if (prefix) {\n action.type = prefix + '.' + action.type;\n }\n\n if (action.actions) {\n action.visible = ko.observable(false);\n action.parent = actions;\n this.recursiveObserveActions(action.actions, action.type);\n }\n }, this);\n\n return this;\n },\n\n /**\n * Applies specified action.\n *\n * @param {String} actionIndex - Actions' identifier.\n * @returns {Massactions} Chainable.\n */\n applyAction: function (actionIndex) {\n var action = this.getAction(actionIndex),\n visibility;\n\n if (action.visible) {\n visibility = action.visible();\n\n this.hideSubmenus(action.parent);\n action.visible(!visibility);\n\n return this;\n }\n\n return this._super(actionIndex);\n },\n\n /**\n * Retrieves action object associated with a specified index.\n *\n * @param {String} actionIndex - Actions' identifier.\n * @param {Array} actions - Action objects.\n * @returns {Object} Action object.\n */\n getAction: function (actionIndex, actions) {\n var currentActions = actions || this.actions(),\n result = false;\n\n _.find(currentActions, function (action) {\n if (action.type === actionIndex) {\n result = action;\n\n return true;\n }\n\n if (action.actions) {\n result = this.getAction(actionIndex, action.actions);\n\n return result;\n }\n }, this);\n\n return result;\n },\n\n /**\n * Recursive hide all sub folders in given array.\n *\n * @param {Array} actions - Action objects.\n * @returns {Massactions} Chainable.\n */\n hideSubmenus: function (actions) {\n var currentActions = actions || this.actions();\n\n _.each(currentActions, function (action) {\n if (action.visible && action.visible()) {\n action.visible(false);\n }\n\n if (action.actions) {\n this.hideSubmenus(action.actions);\n }\n }, this);\n\n return this;\n }\n });\n});\n","Magento_Ui/js/grid/editing/record.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 'uiCollection'\n], function (_, utils, layout, Collection) {\n 'use strict';\n\n return Collection.extend({\n defaults: {\n active: true,\n hasChanges: false,\n fields: [],\n errorsCount: 0,\n fieldTmpl: 'ui/grid/editing/field',\n rowTmpl: 'ui/grid/editing/row',\n templates: {\n fields: {\n base: {\n parent: '${ $.$data.record.name }',\n name: '${ $.$data.column.index }',\n provider: '${ $.$data.record.name }',\n dataScope: 'data.${ $.$data.column.index }',\n imports: {\n disabled: '${ $.$data.record.parentName }:fields.${ $.$data.column.index }.disabled'\n },\n isEditor: true\n },\n text: {\n component: 'Magento_Ui/js/form/element/abstract',\n template: 'ui/form/element/input'\n },\n date: {\n component: 'Magento_Ui/js/form/element/date',\n template: 'ui/form/element/date',\n dateFormat: 'MMM d, y h:mm:ss a'\n },\n select: {\n component: 'Magento_Ui/js/form/element/select',\n template: 'ui/form/element/select',\n options: '${ JSON.stringify($.$data.column.options) }'\n }\n }\n },\n ignoreTmpls: {\n data: true\n },\n listens: {\n elems: 'updateFields',\n data: 'updateState'\n },\n imports: {\n onColumnsUpdate: '${ $.columnsProvider }:elems'\n },\n modules: {\n columns: '${ $.columnsProvider }',\n editor: '${ $.editorProvider }'\n }\n },\n\n /**\n * Initializes record component.\n *\n * @returns {Record} Chainable.\n */\n initialize: function () {\n _.bindAll(this, 'countErrors');\n utils.limit(this, 'updateState', 10);\n\n return this._super();\n },\n\n /**\n * Initializes observable properties.\n *\n * @returns {Record} Chainable.\n */\n initObservable: function () {\n this._super()\n .track('errorsCount hasChanges')\n .observe('active fields');\n\n return this;\n },\n\n /**\n * Adds listeners on a field.\n *\n * @returns {Record} Chainable.\n */\n initElement: function (field) {\n field.on('error', this.countErrors);\n\n return this._super();\n },\n\n /**\n * Creates new instance of a field.\n *\n * @param {Column} column - Column instance which contains field definition.\n * @returns {Record} Chainable.\n */\n initField: function (column) {\n var field = this.buildField(column);\n\n layout([field]);\n\n return this;\n },\n\n /**\n * Builds fields' configuration described in a provided column.\n *\n * @param {Column} column - Column instance which contains field definition.\n * @returns {Object} Complete fields' configuration.\n */\n buildField: function (column) {\n var fields = this.templates.fields,\n field = column.editor;\n\n if (_.isObject(field) && field.editorType) {\n field = utils.extend({}, fields[field.editorType], field);\n } else if (_.isString(field)) {\n field = fields[field];\n }\n\n field = utils.extend({}, fields.base, field);\n\n return utils.template(field, {\n record: this,\n column: column\n }, true, true);\n },\n\n /**\n * Creates fields for the specified columns.\n *\n * @param {Array} columns - An array of column instances.\n * @returns {Record} Chainable.\n */\n createFields: function (columns) {\n columns.forEach(function (column) {\n if (column.editor && !this.hasChild(column.index)) {\n this.initField(column);\n }\n }, this);\n\n return this;\n },\n\n /**\n * Returns instance of a column found by provided index.\n *\n * @param {String} index - Index of a column (e.g. 'title').\n * @returns {Column}\n */\n getColumn: function (index) {\n return this.columns().getChild(index);\n },\n\n /**\n * Returns records' current data object.\n *\n * @returns {Object}\n */\n getData: function () {\n return this.filterData(this.data);\n },\n\n /**\n * Returns saved records' data. Data will be processed\n * with a 'filterData' and 'normalizeData' methods.\n *\n * @returns {Object} Saved records' data.\n */\n getSavedData: function () {\n var editor = this.editor(),\n savedData = editor.getRowData(this.index);\n\n savedData = this.filterData(savedData);\n\n return this.normalizeData(savedData);\n },\n\n /**\n * Replaces current records' data with the provided one.\n *\n * @param {Object} data - New records data.\n * @param {Boolean} [partial=false] - Flag that defines whether\n * to completely replace current data or to extend it.\n * @returns {Record} Chainable.\n */\n setData: function (data, partial) {\n var currentData = partial ? this.data : {};\n\n data = this.normalizeData(data);\n data = utils.extend({}, currentData, data);\n\n this.set('data', data)\n .updateState();\n\n return this;\n },\n\n /**\n * Filters provided object extracting from it values\n * that can be matched with an existing fields.\n *\n * @param {Object} data - Object to be processed.\n * @returns {Object}\n */\n filterData: function (data) {\n var fields = _.pluck(this.elems(), 'index');\n\n _.each(this.preserveFields, function (enabled, field) {\n if (enabled && !_.contains(fields, field)) {\n fields.push(field);\n }\n });\n\n return _.pick(data, fields);\n },\n\n /**\n * Parses values of a provided object with\n * a 'normalizeData' method of a corresponding field.\n *\n * @param {Object} data - Data to be processed.\n * @returns {Object}\n */\n normalizeData: function (data) {\n var index;\n\n this.elems.each(function (elem) {\n index = elem.index;\n\n if (data.hasOwnProperty(index)) {\n data[index] = elem.normalizeData(data[index]);\n }\n });\n\n return data;\n },\n\n /**\n * Clears values of all fields.\n *\n * @returns {Record} Chainable.\n */\n clear: function () {\n this.elems.each('clear');\n\n return this;\n },\n\n /**\n * Validates all of the available fields.\n *\n * @returns {Array} An array with validation results.\n */\n validate: function () {\n return this.elems.map('validate');\n },\n\n /**\n * Checks if all fields are valid.\n *\n * @returns {Boolean}\n */\n isValid: function () {\n return _.every(this.validate(), 'valid');\n },\n\n /**\n * Counts total errors amount across all fields.\n *\n * @returns {Number}\n */\n countErrors: function () {\n var errorsCount = this.elems.filter('error').length;\n\n this.errorsCount = errorsCount;\n\n return errorsCount;\n },\n\n /**\n * Returns difference between current data and its'\n * initial state, retrieved from the records collection.\n *\n * @returns {Object} Object with changes descriptions.\n */\n checkChanges: function () {\n var savedData = this.getSavedData(),\n data = this.normalizeData(this.getData());\n\n return utils.compare(savedData, data);\n },\n\n /**\n * Updates 'fields' array filling it with available editors\n * or with column instances if associated field is not present.\n *\n * @returns {Record} Chainable.\n */\n updateFields: function () {\n var fields;\n\n fields = this.columns().elems.map(function (column) {\n return this.getChild(column.index) || column;\n }, this);\n\n this.fields(fields);\n\n return this;\n },\n\n /**\n * Updates state of a 'hasChanges' property.\n *\n * @returns {Record} Chainable.\n */\n updateState: function () {\n var diff = this.checkChanges(),\n changed = {};\n\n this.hasChanges = !diff.equal;\n changed[this.index] = this.data;\n this.editor().set('changed', [changed]);\n\n return this;\n },\n\n /**\n * Checks if provided column is an actions column.\n *\n * @param {Column} column - Column to be checked.\n * @returns {Boolean}\n */\n isActionsColumn: function (column) {\n return column.dataType === 'actions';\n },\n\n /**\n * Listener of columns provider child array changes.\n *\n * @param {Array} columns - Modified child elements array.\n */\n onColumnsUpdate: function (columns) {\n this.createFields(columns)\n .updateFields();\n }\n });\n});\n","Magento_Ui/js/grid/editing/client.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 'mageUtils',\n 'uiClass'\n], function ($, _, utils, Class) {\n 'use strict';\n\n return Class.extend({\n defaults: {\n validateBeforeSave: true,\n requestConfig: {\n dataType: 'json',\n type: 'POST'\n }\n },\n\n /**\n * Initializes client instance.\n *\n * @returns {Client} Chainable.\n */\n initialize: function () {\n _.bindAll(this, 'onSuccess', 'onError');\n\n return this._super();\n },\n\n /**\n * Sends XMLHttpRequest with a provided configuration.\n *\n * @param {Object} config - Configuration of request.\n * @returns {jQueryPromise}\n */\n send: function (config) {\n var deffer = $.Deferred();\n\n config = utils.extend({}, this.requestConfig, config);\n\n $.ajax(config)\n .done(_.partial(this.onSuccess, deffer))\n .fail(_.partial(this.onError, deffer));\n\n return deffer.promise();\n },\n\n /**\n * Proxy save method which might invoke\n * data validation prior to its' saving.\n *\n * @param {Object} data - Data to be processed.\n * @returns {jQueryPromise}\n */\n save: function (data) {\n var save = this._save.bind(this, data);\n\n return this.validateBeforeSave ?\n this.validate(data).pipe(save) :\n save();\n },\n\n /**\n * Sends request to validate provided data.\n *\n * @param {Object} data - Data to be validated.\n * @returns {jQueryPromise}\n */\n validate: function (data) {\n return this.send({\n url: this.validateUrl,\n data: data\n });\n },\n\n /**\n * Sends request to save provided data.\n *\n * @private\n * @param {Object} data - Data to be validated.\n * @returns {jQueryPromise}\n */\n _save: function (data) {\n return this.send({\n url: this.saveUrl,\n data: data\n });\n },\n\n /**\n * Creates error object with a provided message.\n *\n * @param {String} msg - Errors' message.\n * @returns {Object}\n */\n createError: function (msg) {\n return {\n type: 'error',\n message: msg\n };\n },\n\n /**\n * Handles ajax error callback.\n *\n * @param {jQueryPromise} promise - Promise to be rejected.\n * @param {jQueryXHR} xhr - See 'jquery' ajax error callback.\n * @param {String} status - See 'jquery' ajax error callback.\n * @param {(String|Object)} err - See 'jquery' ajax error callback.\n */\n onError: function (promise, xhr, status, err) {\n var msg;\n\n msg = xhr.status !== 200 ?\n xhr.status + ' (' + xhr.statusText + ')' :\n err;\n\n promise.reject(this.createError(msg));\n },\n\n /**\n * Handles ajax success callback.\n *\n * @param {jQueryPromise} promise - Promise to be resolved.\n * @param {*} data - See 'jquery' ajax success callback.\n */\n onSuccess: function (promise, data) {\n var errors;\n\n if (data.error) {\n errors = _.map(data.messages, this.createError, this);\n\n promise.reject(errors);\n } else {\n promise.resolve(data);\n }\n }\n });\n});\n","Magento_Ui/js/grid/editing/editor-view.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 'Magento_Ui/js/lib/view/utils/async',\n 'underscore',\n 'uiRegistry',\n 'uiClass'\n], function (ko, $, _, registry, Class) {\n 'use strict';\n\n return Class.extend({\n defaults: {\n rootSelector: '${ $.columnsProvider }:.admin__data-grid-wrap',\n tableSelector: '${ $.rootSelector } -> table',\n rowSelector: '${ $.tableSelector } tbody tr.data-row',\n headerButtonsTmpl:\n '<!-- ko template: headerButtonsTmpl --><!-- /ko -->',\n bulkTmpl:\n '<!-- ko scope: bulk -->' +\n '<!-- ko template: getTemplate() --><!-- /ko -->' +\n '<!-- /ko -->',\n rowTmpl:\n '<!-- ko with: _editor -->' +\n '<!-- ko if: isActive($row()._rowIndex, true) -->' +\n '<!-- ko with: getRecord($row()._rowIndex, true) -->' +\n '<!-- ko template: rowTmpl --><!-- /ko -->' +\n '<!-- /ko -->' +\n '<!-- ko if: isSingleEditing && singleEditingButtons -->' +\n '<!-- ko template: rowButtonsTmpl --><!-- /ko -->' +\n '<!-- /ko -->' +\n '<!-- /ko -->' +\n '<!-- /ko -->'\n },\n\n /**\n * Initializes view component.\n *\n * @returns {View} Chainable.\n */\n initialize: function () {\n _.bindAll(\n this,\n 'initRoot',\n 'initTable',\n 'initRow',\n 'rowBindings',\n 'tableBindings'\n );\n\n this._super();\n\n this.model = registry.get(this.model);\n\n $.async(this.rootSelector, this.initRoot);\n $.async(this.tableSelector, this.initTable);\n $.async(this.rowSelector, this.initRow);\n\n return this;\n },\n\n /**\n * Initializes columns root container.\n *\n * @param {HTMLElement} node\n * @returns {View} Chainable.\n */\n initRoot: function (node) {\n $(this.headerButtonsTmpl)\n .insertBefore(node)\n .applyBindings(this.model);\n\n return this;\n },\n\n /**\n * Initializes table element.\n *\n * @param {HTMLTableElement} table\n * @returns {View} Chainable.\n */\n initTable: function (table) {\n $(table).bindings(this.tableBindings);\n\n this.initBulk(table);\n\n return this;\n },\n\n /**\n * Initializes bulk editor element\n * for the provided table.\n *\n * @param {HTMLTableElement} table\n * @returns {View} Chainable.\n */\n initBulk: function (table) {\n var tableBody = $('tbody', table)[0];\n\n $(this.bulkTmpl)\n .prependTo(tableBody)\n .applyBindings(this.model);\n\n return this;\n },\n\n /**\n * Initializes table row.\n *\n * @param {HTMLTableRowElement} row\n * @returns {View} Chainable.\n */\n initRow: function (row) {\n var $editingRow;\n\n $(row).extendCtx({\n _editor: this.model\n }).bindings(this.rowBindings);\n\n $editingRow = $(this.rowTmpl)\n .insertBefore(row)\n .applyBindings(row);\n\n ko.utils.domNodeDisposal.addDisposeCallback(row, this.removeEditingRow.bind(this, $editingRow));\n\n return this;\n },\n\n /**\n * Returns row bindings.\n *\n * @param {Object} ctx - Current context of a row.\n * @returns {Object}\n */\n rowBindings: function (ctx) {\n var model = this.model;\n\n return {\n visible: ko.computed(function () {\n var record = ctx.$row(),\n index = record && record._rowIndex;\n\n return !model.isActive(index, true);\n })\n };\n },\n\n /**\n * Returns table bindings.\n *\n * @returns {Object}\n */\n tableBindings: function () {\n var model = this.model;\n\n return {\n css: {\n '_in-edit': ko.computed(function () {\n return model.hasActive() && !model.permanentlyActive;\n })\n }\n };\n },\n\n /**\n * Removes specified array of nodes.\n *\n * @param {ArrayLike} row\n */\n removeEditingRow: function (row) {\n _.toArray(row).forEach(ko.removeNode);\n }\n });\n});\n","Magento_Ui/js/grid/editing/editor.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 'mage/translate',\n 'uiCollection'\n], function (_, utils, layout, $t, Collection) {\n 'use strict';\n\n return Collection.extend({\n defaults: {\n rowButtonsTmpl: 'ui/grid/editing/row-buttons',\n headerButtonsTmpl: 'ui/grid/editing/header-buttons',\n successMsg: $t('You have successfully saved your edits.'),\n errorsCount: 0,\n bulkEnabled: true,\n multiEditingButtons: true,\n singleEditingButtons: true,\n isMultiEditing: false,\n isSingleEditing: false,\n permanentlyActive: false,\n rowsData: [],\n fields: {},\n\n templates: {\n record: {\n parent: '${ $.$data.editor.name }',\n name: '${ $.$data.recordId }',\n component: 'Magento_Ui/js/grid/editing/record',\n columnsProvider: '${ $.$data.editor.columnsProvider }',\n editorProvider: '${ $.$data.editor.name }',\n preserveFields: {\n '${ $.$data.editor.indexField }': true\n }\n }\n },\n bulkConfig: {\n component: 'Magento_Ui/js/grid/editing/bulk',\n name: '${ $.name }_bulk',\n editorProvider: '${ $.name }',\n columnsProvider: '${ $.columnsProvider }'\n },\n clientConfig: {\n component: 'Magento_Ui/js/grid/editing/client',\n name: '${ $.name }_client'\n },\n viewConfig: {\n component: 'Magento_Ui/js/grid/editing/editor-view',\n name: '${ $.name }_view',\n model: '${ $.name }',\n columnsProvider: '${ $.columnsProvider }'\n },\n imports: {\n rowsData: '${ $.dataProvider }:data.items'\n },\n listens: {\n '${ $.dataProvider }:reloaded': 'cancel',\n '${ $.selectProvider }:selected': 'onSelectionsChange'\n },\n modules: {\n source: '${ $.dataProvider }',\n client: '${ $.clientConfig.name }',\n columns: '${ $.columnsProvider }',\n bulk: '${ $.bulkConfig.name }',\n selections: '${ $.selectProvider }'\n }\n },\n\n /**\n * Initializes editor component.\n *\n * @returns {Editor} Chainable.\n */\n initialize: function () {\n _.bindAll(this, 'updateState', 'countErrors', 'onDataSaved', 'onSaveError');\n\n this._super()\n .initBulk()\n .initClient()\n .initView();\n\n return this;\n },\n\n /**\n * Initializes observable properties.\n *\n * @returns {Editor} Chainable.\n */\n initObservable: function () {\n this._super()\n .track([\n 'errorsCount',\n 'isMultiEditing',\n 'isSingleEditing',\n 'isSingleColumnEditing',\n 'changed'\n ])\n .observe({\n canSave: true,\n activeRecords: [],\n messages: []\n });\n\n return this;\n },\n\n /**\n * Initializes bulk editing component.\n *\n * @returns {Editor} Chainable.\n */\n initBulk: function () {\n if (this.bulkEnabled) {\n layout([this.bulkConfig]);\n }\n\n return this;\n },\n\n /**\n * Initializes editors' view component.\n *\n * @returns {Editor} Chainable.\n */\n initView: function () {\n layout([this.viewConfig]);\n\n return this;\n },\n\n /**\n * Initializes client component.\n *\n * @returns {Editor} Chainable.\n */\n initClient: function () {\n layout([this.clientConfig]);\n\n return this;\n },\n\n /**\n * Creates instance of a new record.\n *\n * @param {(Number|String)} id - See 'getId' method.\n * @param {Boolean} [isIndex=false] - See 'getId' method.\n * @returns {Editor} Chainable.\n */\n initRecord: function (id, isIndex) {\n var record = this.buildRecord(id, isIndex);\n\n layout([record]);\n\n return this;\n },\n\n /**\n * Adds listeners on a new record.\n *\n * @param {Record} record\n * @returns {Editor} Chainable.\n */\n initElement: function (record) {\n record.on({\n 'active': this.updateState,\n 'errorsCount': this.countErrors\n });\n\n this.updateState();\n\n return this._super();\n },\n\n /**\n * Creates configuration for a new record associated with a row data.\n *\n * @param {(Number|String)} id - See 'getId' method.\n * @param {Boolean} [isIndex=false] - See 'getId' method.\n * @returns {Object} Record configuration.\n */\n buildRecord: function (id, isIndex) {\n var recordId = this.getId(id, isIndex),\n recordTmpl = this.templates.record,\n record;\n\n if (this.getRecord(recordId)) {\n return this;\n }\n\n record = utils.template(recordTmpl, {\n editor: this,\n recordId: id\n });\n\n record.recordId = id;\n record.data = this.getRowData(id);\n\n return record;\n },\n\n /**\n * Starts editing of a specified record. If records'\n * instance doesn't exist, than it will be created.\n *\n * @param {(Number|String)} id - See 'getId' method.\n * @param {Boolean} [isIndex=false] - See 'getId' method.\n * @returns {Editor} Chainable.\n */\n edit: function (id, isIndex) {\n var recordId = this.getId(id, isIndex),\n record = this.getRecord(recordId);\n\n record ?\n record.active(true) :\n this.initRecord(recordId);\n\n return this;\n },\n\n /**\n * Drops list of selections while activating only the specified record.\n *\n * @param {(Number|String)} id - See 'getId' method.\n * @param {Boolean} [isIndex=false] - See 'getId' method.\n * @returns {Editor} Chainable.\n */\n startEdit: function (id, isIndex) {\n var recordId = this.getId(id, isIndex);\n\n this.selections()\n .deselectAll()\n .select(recordId);\n\n return this.edit(recordId);\n },\n\n /**\n * Hides records and resets theirs data.\n *\n * @returns {Editor} Chainable.\n */\n cancel: function () {\n this.reset()\n .hide()\n .clearMessages()\n .bulk('clear');\n\n return this;\n },\n\n /**\n * Hides records.\n *\n * @returns {Editor} Chainable.\n */\n hide: function () {\n this.activeRecords.each('active', false);\n\n return this;\n },\n\n /**\n * Resets active records.\n *\n * @returns {Editor} Chainable.\n */\n reset: function () {\n this.elems.each(function (record) {\n this.resetRecord(record.recordId);\n }, this);\n\n return this;\n },\n\n /**\n * Validates and saves data of active records.\n *\n * @returns {Editor} Chainable.\n */\n save: function () {\n var data;\n\n if (!this.isValid()) {\n return this;\n }\n\n data = {\n items: this.getData()\n };\n\n this.clearMessages()\n .columns('showLoader');\n\n this.client()\n .save(data)\n .done(this.onDataSaved)\n .fail(this.onSaveError);\n\n return this;\n },\n\n /**\n * Validates all active records.\n *\n * @returns {Array} An array of records and theirs validation results.\n */\n validate: function () {\n return this.activeRecords.map(function (record) {\n return {\n target: record,\n valid: record.isValid()\n };\n });\n },\n\n /**\n * Checks if all active records are valid.\n *\n * @returns {Boolean}\n */\n isValid: function () {\n return _.every(this.validate(), 'valid');\n },\n\n /**\n * Returns active records data, indexed by a theirs ids.\n *\n * @returns {Object} Collection of records data.\n */\n getData: function () {\n var data = this.activeRecords.map(function (record) {\n var elemKey,\n recordData = record.getData();\n\n for (elemKey in recordData) {\n if (_.isUndefined(recordData[elemKey])) {\n recordData[elemKey] = null;\n }\n }\n\n return recordData;\n });\n\n return _.indexBy(data, this.indexField);\n },\n\n /**\n * Sets provided data to all active records.\n *\n * @param {Object} data - See 'setData' method of a 'Record'.\n * @param {Boolean} partial - See 'setData' method of a 'Record'.\n * @returns {Editor} Chainable.\n */\n setData: function (data, partial) {\n this.activeRecords.each('setData', data, partial);\n\n return this;\n },\n\n /**\n * Resets specific records' data\n * to the data present in associated row.\n *\n * @param {(Number|String)} id - See 'getId' method.\n * @param {Boolean} [isIndex=false] - See 'getId' method.\n * @returns {Editor} Chainable.\n */\n resetRecord: function (id, isIndex) {\n var record = this.getRecord(id, isIndex),\n data = this.getRowData(id, isIndex);\n\n if (record && data) {\n record.setData(data);\n }\n\n return this;\n },\n\n /**\n * Returns instance of a specified record.\n *\n * @param {(Number|String)} id - See 'getId' method.\n * @param {Boolean} [isIndex=false] - See 'getId' method.\n * @returns {Record}\n */\n getRecord: function (id, isIndex) {\n return this.elems.findWhere({\n recordId: this.getId(id, isIndex)\n });\n },\n\n /**\n * Creates record name based on a provided id.\n *\n * @param {(Number|String)} id - See 'getId' method.\n * @param {Boolean} [isIndex=false] - See 'getId' method.\n * @returns {String}\n */\n formRecordName: function (id, isIndex) {\n id = this.getId(id, isIndex);\n\n return this.name + '.' + id;\n },\n\n /**\n * Disables editing of specified fields.\n *\n * @param {Array} fields - An array of fields indexes to be disabled.\n * @returns {Editor} Chainable.\n */\n disableFields: function (fields) {\n var columns = this.columns().elems(),\n data = utils.copy(this.fields);\n\n columns.forEach(function (column) {\n var index = column.index,\n field = data[index] = data[index] || {};\n\n field.disabled = _.contains(fields, index);\n });\n\n this.set('fields', data);\n\n return this;\n },\n\n /**\n * Converts index of a row into the record id.\n *\n * @param {(Number|String)} id - Records' identifier or its' index in the rows array.\n * @param {Boolean} [isIndex=false] - Flag that indicates if first\n * parameter is an index or identifier.\n * @returns {String} Records' id.\n */\n getId: function (id, isIndex) {\n var rowsData = this.rowsData,\n record;\n\n if (isIndex === true) {\n record = rowsData[id];\n id = record ? record[this.indexField] : false;\n }\n\n return id;\n },\n\n /**\n * Returns data of a specified row.\n *\n * @param {(Number|String)} id - See 'getId' method.\n * @param {Boolean} [isIndex=false] - See 'getId' method.\n * @returns {Object}\n */\n getRowData: function (id, isIndex) {\n id = this.getId(id, isIndex);\n\n return _.find(this.rowsData, function (row) {\n return row[this.indexField] === id;\n }, this);\n },\n\n /**\n * Checks if specified record is active.\n *\n * @param {(Number|String)} id - See 'getId' method.\n * @param {Boolean} [isIndex=false] - See'getId' method.\n * @returns {Boolean}\n */\n isActive: function (id, isIndex) {\n var record = this.getRecord(id, isIndex);\n\n return _.contains(this.activeRecords(), record);\n },\n\n /**\n * Checks if editor has active records.\n *\n * @returns {Boolean}\n */\n hasActive: function () {\n return !!this.activeRecords().length || this.permanentlyActive;\n },\n\n /**\n * Counts number of active records.\n *\n * @returns {Number}\n */\n countActive: function () {\n return this.activeRecords().length;\n },\n\n /**\n * Counts number of invalid fields across all active records.\n *\n * @returns {Number}\n */\n countErrors: function () {\n var errorsCount = 0;\n\n this.activeRecords.each(function (record) {\n errorsCount += record.errorsCount;\n });\n\n this.errorsCount = errorsCount;\n\n return errorsCount;\n },\n\n /**\n * Translatable error message text.\n *\n * @returns {String}\n */\n countErrorsMessage: function () {\n return $t('There are {placeholder} messages requires your attention.')\n .replace('{placeholder}', this.countErrors());\n },\n\n /**\n * Checks if editor has any errors.\n *\n * @returns {Boolean}\n */\n hasErrors: function () {\n return !!this.countErrors();\n },\n\n /**\n * Handles changes of the records 'active' property.\n *\n * @returns {Editor} Chainable.\n */\n updateState: function () {\n var active = this.elems.filter('active'),\n activeCount = active.length,\n columns = this.columns().elems;\n\n columns.each('disableAction', !!activeCount);\n\n this.isMultiEditing = activeCount > 1;\n this.isSingleEditing = activeCount === 1;\n\n this.activeRecords(active);\n\n return this;\n },\n\n /**\n * Returns list of selections from a current page.\n *\n * @returns {Array}\n */\n getSelections: function () {\n return this.selections().getPageSelections();\n },\n\n /**\n * Starts editing of selected records. If record\n * is not in the selections list, then it will get hidden.\n *\n * @returns {Editor} Chainable.\n */\n editSelected: function () {\n var selections = this.getSelections();\n\n this.elems.each(function (record) {\n if (!_.contains(selections, record.recordId)) {\n record.active(false);\n }\n });\n\n selections.forEach(function (id) {\n this.edit(id);\n }, this);\n\n return this;\n },\n\n /**\n * Checks if there is any additional messages.\n *\n * @returns {Boolean}\n */\n hasMessages: function () {\n return this.messages().length;\n },\n\n /**\n * Adds new additional message or a set of messages.\n *\n * @param {(Object|Array)} message - Messages to be added.\n * @returns {Editor} Chainable.\n */\n addMessage: function (message) {\n var messages = this.messages();\n\n Array.isArray(message) ?\n messages.push.apply(messages, message) :\n messages.push(message);\n\n this.messages(messages);\n\n return this;\n },\n\n /**\n * Removes all additional messages.\n *\n * @returns {Editor} Chainable.\n */\n clearMessages: function () {\n this.messages.removeAll();\n\n return this;\n },\n\n /**\n * Listener of the selections data changes.\n */\n onSelectionsChange: function () {\n if (this.hasActive()) {\n this.editSelected();\n }\n },\n\n /**\n * Handles successful save request.\n */\n onDataSaved: function () {\n var msg = {\n type: 'success',\n message: this.successMsg\n };\n\n this.addMessage(msg)\n .source('reload', {\n refresh: true\n });\n },\n\n /**\n * Handles failed save request.\n *\n * @param {(Array|Object)} errors - List of errors or a single error object.\n */\n onSaveError: function (errors) {\n this.addMessage(errors)\n .columns('hideLoader');\n }\n });\n});\n","Magento_Ui/js/grid/editing/bulk.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 './record'\n], function (_, utils, Record) {\n 'use strict';\n\n /**\n * Removes empty properties from the provided object.\n *\n * @param {Object} data - Object to be processed.\n * @returns {Object}\n */\n function removeEmpty(data) {\n data = utils.flatten(data);\n data = _.omit(data, utils.isEmpty);\n\n return utils.unflatten(data);\n }\n\n return Record.extend({\n defaults: {\n template: 'ui/grid/editing/bulk',\n active: false,\n templates: {\n fields: {\n select: {\n caption: ' '\n }\n }\n },\n imports: {\n active: '${ $.editorProvider }:isMultiEditing'\n },\n listens: {\n data: 'updateState',\n active: 'updateState'\n }\n },\n\n /**\n * Initializes observable properties.\n *\n * @returns {Bulk} Chainable.\n */\n initObservable: function () {\n this._super()\n .track({\n hasData: false\n });\n\n return this;\n },\n\n /**\n * Extends original method to disable possible\n * 'required-entry' validation rule.\n *\n * @returns {Object} Columns' field definition.\n */\n buildField: function () {\n var field = this._super(),\n rules = field.validation;\n\n if (rules) {\n delete rules['required-entry'];\n }\n\n return field;\n },\n\n /**\n * Applies current data to all active records.\n *\n * @returns {Bulk} Chainable.\n */\n apply: function () {\n if (this.isValid()) {\n this.applyData()\n .clear();\n }\n\n return this;\n },\n\n /**\n * Sets available data to all active records.\n *\n * @param {Object} [data] - If not specified, then current fields data will be used.\n * @returns {Bulk} Chainable.\n */\n applyData: function (data) {\n data = data || this.getData();\n\n this.editor('setData', data, true);\n\n return this;\n },\n\n /**\n * Returns data of all non-empty fields.\n *\n * @returns {Object} Fields data without empty values.\n */\n getData: function () {\n return removeEmpty(this._super());\n },\n\n /**\n * Updates own 'hasData' property and defines\n * whether regular rows editing can be resumed.\n *\n * @returns {Bulk} Chainable.\n */\n updateState: function () {\n var fields = _.keys(this.getData()),\n hasData = !!fields.length;\n\n this.hasData = hasData;\n\n if (!this.active()) {\n fields = [];\n }\n\n this.editor('disableFields', fields);\n this.editor('canSave', !fields.length);\n\n return this;\n }\n });\n});\n","Magento_Ui/js/grid/paging/sizes.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 'uiElement'\n], function (ko, _, utils, Element) {\n 'use strict';\n\n return Element.extend({\n defaults: {\n template: 'ui/grid/paging/sizes',\n minSize: 1,\n maxSize: 999,\n statefull: {\n options: true,\n value: true\n },\n listens: {\n value: 'onValueChange',\n options: 'onSizesChange'\n }\n },\n\n /**\n * Initializes sizes component.\n *\n * @returns {Sizes} Chainable.\n */\n initialize: function () {\n this._super()\n .updateArray();\n\n return this;\n },\n\n /**\n * Initializes observable properties.\n *\n * @returns {Sizes} Chainable.\n */\n initObservable: function () {\n this._super()\n .track([\n 'value',\n 'editing',\n 'customVisible',\n 'customValue'\n ])\n .track({\n optionsArray: []\n });\n\n this._value = ko.pureComputed({\n read: ko.getObservable(this, 'value'),\n\n /**\n * Validates input field prior to updating 'value' property.\n */\n write: function (value) {\n value = this.normalize(value);\n\n this.value = value;\n this._value.notifySubscribers(value);\n },\n\n owner: this\n });\n\n return this;\n },\n\n /**\n * Starts editing of the specified size.\n *\n * @param {Number} value - Value of the size.\n * @returns {Sizes} Chainable.\n */\n edit: function (value) {\n this.editing = value;\n\n return this;\n },\n\n /**\n * Discards changes made to the currently editable size.\n *\n * @returns {Sizes} Chainable.\n */\n discardEditing: function () {\n var value = this.editing;\n\n if (value) {\n this.updateSize(value, value);\n }\n\n return this;\n },\n\n /**\n * Invokes 'discardEditing' and 'discardCustom' actions.\n *\n * @returns {Sizes} Chainable.\n */\n discardAll: function () {\n this.discardEditing()\n .discardCustom();\n\n return this;\n },\n\n /**\n * Returns value of the first size.\n *\n * @returns {Number}\n */\n getFirst: function () {\n return this.optionsArray[0].value;\n },\n\n /**\n * Returns size which matches specified value.\n *\n * @param {Number} value - Value of the item.\n * @returns {Object|Undefined}\n */\n getSize: function (value) {\n return this.options[value];\n },\n\n /**\n * Sets current size to the specified value.\n *\n * @param {Number} value - Value of the size.\n * @returns {Sizes} Chainable.\n */\n setSize: function (value) {\n this.value = value;\n\n return this;\n },\n\n /**\n * Adds a new value to sizes list.\n *\n * @param {Number} value - Value to be added.\n * @returns {Sizes} Chainable.\n */\n addSize: function (value) {\n var size;\n\n if (!this.hasSize(value)) {\n size = this.createSize(value);\n\n this.set('options.' + value, size);\n }\n\n return this;\n },\n\n /**\n * Removes provided value from the sizes list.\n *\n * @param {Number} value - Value to be removed.\n * @returns {Sizes} Chainable.\n */\n removeSize: function (value) {\n if (!this.hasSize(value)) {\n return this;\n }\n\n this.remove('options.' + value);\n\n if (this.isSelected(value)) {\n this.setSize(this.getFirst());\n }\n\n return this;\n },\n\n /**\n * Updates existing value to the provided one. If new value\n * is not specified, then sizes' '_value' property will be taken.\n *\n * @param {Number} value - Existing value that should be updated.\n * @param {(Number|String)} [newValue=size._value] - New size value.\n * @returns {Sizes} Chainable.\n */\n updateSize: function (value, newValue) {\n var size = this.getSize(value);\n\n if (!size) {\n return this;\n }\n\n newValue = newValue || size._value;\n\n if (isNaN(+newValue)) {\n this.discardEditing();\n\n return this;\n }\n\n newValue = this.normalize(newValue);\n\n this.remove('options.' + value)\n .addSize(newValue);\n\n if (this.isSelected(value)) {\n this.setSize(newValue);\n }\n\n return this;\n },\n\n /**\n * Creates new editable size instance with the provided value.\n *\n * @param {Number} value - Value of the size.\n * @returns {Object}\n */\n createSize: function (value) {\n return {\n value: value,\n label: value,\n _value: value,\n editable: true\n };\n },\n\n /**\n * Checks if provided value exists in the sizes list.\n *\n * @param {Number} value - Value to be checked.\n * @returns {Boolean}\n */\n hasSize: function (value) {\n return !!this.getSize(value);\n },\n\n /**\n * Hides and clears custom field.\n *\n * @returns {Sizes} Chainable.\n */\n discardCustom: function () {\n this.hideCustom()\n .clearCustom();\n\n return this;\n },\n\n /**\n * Shows custom field.\n *\n * @returns {Sizes} Chainable.\n */\n showCustom: function () {\n this.customVisible = true;\n\n return this;\n },\n\n /**\n * Hides custom field.\n *\n * @returns {Sizes} Chainable.\n */\n hideCustom: function () {\n this.customVisible = false;\n\n return this;\n },\n\n /**\n * Empties value of the custom field.\n *\n * @returns {Sizes} Chainable.\n */\n clearCustom: function () {\n this.customValue = '';\n\n return this;\n },\n\n /**\n * Adds a new size specified in the custom field.\n *\n * @returns {Sizes} Chainable.\n */\n applyCustom: function () {\n var value = this.customValue;\n\n value = this.normalize(value);\n\n this.addSize(value)\n .setSize(value)\n .discardCustom();\n\n return this;\n },\n\n /**\n * Checks if custom field is visible.\n *\n * @returns {Boolean}\n */\n isCustomVisible: function () {\n return this.customVisible;\n },\n\n /**\n * Converts provided value to a number and puts\n * it in range between 'minSize' and 'maxSize' properties.\n *\n * @param {(Number|String)} value - Value to be normalized.\n * @returns {Number}\n */\n normalize: function (value) {\n value = +value;\n\n if (isNaN(value)) {\n return this.getFirst();\n }\n\n return utils.inRange(Math.round(value), this.minSize, this.maxSize);\n },\n\n /**\n * Updates the array of options.\n *\n * @returns {Sizes} Chainable.\n */\n updateArray: function () {\n var array = _.values(this.options);\n\n this.optionsArray = _.sortBy(array, 'value');\n\n return this;\n },\n\n /**\n * Checks if provided value is in editing state.\n *\n * @param {Number} value - Value to be checked.\n * @returns {Boolean}\n */\n isEditing: function (value) {\n return this.editing === value;\n },\n\n /**\n * Checks if provided value is selected.\n *\n * @param {Number} value - Value to be checked.\n * @returns {Boolean}\n */\n isSelected: function (value) {\n return this.value === value;\n },\n\n /**\n * Listener of the 'value' property changes.\n */\n onValueChange: function () {\n this.discardAll()\n .trigger('close');\n },\n\n /**\n * Listener of the 'options' object changes.\n */\n onSizesChange: function () {\n this.editing = false;\n\n this.updateArray();\n }\n });\n});\n","Magento_Ui/js/grid/paging/paging.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 'uiLayout',\n 'uiElement'\n], function (ko, _, utils, layout, Element) {\n 'use strict';\n\n return Element.extend({\n defaults: {\n template: 'ui/grid/paging/paging',\n totalTmpl: 'ui/grid/paging-total',\n totalRecords: 0,\n showTotalRecords: true,\n pages: 1,\n current: 1,\n selectProvider: 'ns = ${ $.ns }, index = ids',\n\n sizesConfig: {\n component: 'Magento_Ui/js/grid/paging/sizes',\n name: '${ $.name }_sizes',\n storageConfig: {\n provider: '${ $.storageConfig.provider }',\n namespace: '${ $.storageConfig.namespace }'\n }\n },\n\n imports: {\n totalSelected: '${ $.selectProvider }:totalSelected',\n totalRecords: '${ $.provider }:data.totalRecords',\n showTotalRecords: '${ $.provider }:data.showTotalRecords',\n filters: '${ $.provider }:params.filters',\n keywordUpdated: '${ $.provider }:params.keywordUpdated'\n },\n\n exports: {\n pageSize: '${ $.provider }:params.paging.pageSize',\n current: '${ $.provider }:params.paging.current'\n },\n\n links: {\n options: '${ $.sizesConfig.name }:options',\n pageSize: '${ $.sizesConfig.name }:value'\n },\n\n statefull: {\n pageSize: true,\n current: true\n },\n\n listens: {\n 'pages': 'onPagesChange',\n 'pageSize': 'onPageSizeChange',\n 'totalRecords': 'updateCounter',\n 'showTotalRecords': 'updateShowTotalRecords',\n '${ $.provider }:params.filters': 'goFirst',\n '${ $.provider }:params.search': 'onSearchUpdate'\n },\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 .updateCounter();\n\n return this;\n },\n\n /**\n * Initializes observable properties.\n *\n * @returns {Paging} Chainable.\n */\n initObservable: function () {\n this._super()\n .track([\n 'totalSelected',\n 'totalRecords',\n 'showTotalRecords',\n 'pageSize',\n 'pages',\n 'current'\n ]);\n\n this._current = ko.pureComputed({\n read: ko.getObservable(this, 'current'),\n\n /**\n * Validates page change according to user's input.\n * Sets current observable to result of validation.\n * Calls reload method then.\n */\n write: function (value) {\n this.setPage(value)\n ._current.notifySubscribers(this.current);\n },\n\n owner: this\n });\n\n return this;\n },\n\n /**\n * Initializes sizes component.\n *\n * @returns {Paging} Chainable.\n */\n initSizes: function () {\n layout([this.sizesConfig]);\n\n return this;\n },\n\n /**\n * Gets first item index on current page.\n *\n * @returns {Number}\n */\n getFirstItemIndex: function () {\n return this.pageSize * (this.current - 1) + 1;\n },\n\n /**\n * Gets last item index on current page.\n *\n * @returns {Number}\n */\n getLastItemIndex: function () {\n var lastItem = this.getFirstItemIndex() + this.pageSize - 1;\n\n return this.totalRecords < lastItem ? this.totalRecords : lastItem;\n },\n\n /**\n * Sets cursor to the provied value.\n *\n * @param {(Number|String)} value - New value of the cursor.\n * @returns {Paging} Chainable.\n */\n setPage: function (value) {\n this.current = this.normalize(value);\n\n return this;\n },\n\n /**\n * Increments current page value.\n *\n * @returns {Paging} Chainable.\n */\n next: function () {\n this.setPage(this.current + 1);\n\n return this;\n },\n\n /**\n * Decrements current page value.\n *\n * @returns {Paging} Chainable.\n */\n prev: function () {\n this.setPage(this.current - 1);\n\n return this;\n },\n\n /**\n * Goes to the first page.\n *\n * @returns {Paging} Chainable.\n */\n goFirst: function () {\n if (!_.isUndefined(this.filters)) {\n this.current = 1;\n }\n\n return this;\n },\n\n /**\n * Goes to the last page.\n *\n * @returns {Paging} Chainable.\n */\n goLast: function () {\n this.current = this.pages;\n\n return this;\n },\n\n /**\n * Checks if current page is the first one.\n *\n * @returns {Boolean}\n */\n isFirst: function () {\n return this.current === 1;\n },\n\n /**\n * Checks if current page is the last one.\n *\n * @returns {Boolean}\n */\n isLast: function () {\n return this.current === this.pages;\n },\n\n /**\n * Updates number of pages.\n */\n updateCounter: function () {\n this.pages = Math.ceil(this.totalRecords / this.pageSize) || 1;\n\n return this;\n },\n\n /**\n * Updates show total records flag.\n */\n updateShowTotalRecords: function () {\n if (this.showTotalRecords === undefined) {\n this.showTotalRecords = true;\n }\n return this;\n },\n\n /**\n * Calculates new page cursor based on the\n * previous and current page size values.\n */\n updateCursor: function () {\n var cursor = this.current - 1,\n size = this.pageSize,\n oldSize = _.isUndefined(this.previousSize) ? this.pageSize : this.previousSize,\n delta = cursor * (oldSize - size) / size;\n\n delta = size > oldSize ?\n Math.ceil(delta) :\n Math.floor(delta);\n\n cursor += delta + 1;\n\n this.previousSize = size;\n\n this.setPage(cursor);\n\n return this;\n },\n\n /**\n * Converts provided value to a number and puts\n * it in range between 1 and total amount of pages.\n *\n * @param {(Number|String)} value - Value to be normalized.\n * @returns {Number}\n */\n normalize: function (value) {\n value = +value;\n\n if (isNaN(value)) {\n return 1;\n }\n\n return utils.inRange(Math.round(value), 1, this.pages);\n },\n\n /**\n * Handles changes of the page size.\n */\n onPageSizeChange: function () {\n this.updateCounter()\n .updateCursor();\n },\n\n /**\n * Handles changes of the pages amount.\n */\n onPagesChange: function () {\n this.updateCursor();\n },\n\n /**\n * Resent the pagination to Page 1 on search keyword update\n */\n onSearchUpdate: function () {\n if (!_.isUndefined(this.keywordUpdated) && this.keywordUpdated) {\n this.goFirst();\n }\n\n return this;\n }\n });\n});\n","Magento_Ui/js/grid/sticky/sticky.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 'underscore',\n 'uiComponent',\n 'Magento_Ui/js/lib/view/utils/raf'\n], function ($, _, Component, raf) {\n 'use strict';\n\n return Component.extend({\n defaults: {\n listingSelector: '${ $.listingProvider }::not([data-role = \"sticky-el-root\"])',\n toolbarSelector: '${ $.toolbarProvider }::not([data-role = \"sticky-el-root\"])',\n bulkRowSelector: '[data-role = \"data-grid-bulk-row\"]',\n bulkRowHeaderSelector: '.data-grid-info-panel:visible',\n tableSelector: 'table',\n columnSelector: 'thead tr th',\n rowSelector: 'tbody tr',\n toolbarCollapsiblesSelector: '[data-role=\"toolbar-menu-item\"]',\n toolbarCollapsiblesActiveClass: '_active',\n template: 'ui/grid/sticky/sticky',\n stickyContainerSelector: '.sticky-header',\n stickyElementSelector: '[data-role = \"sticky-el-root\"]',\n leftDataGridCapSelector: '.data-grid-cap-left',\n rightDataGridCapSelector: '.data-grid-cap-right',\n visible: false,\n enableToolbar: true,\n enableHeader: true,\n modules: {\n toolbar: '${ $.toolbarProvider }',\n listing: '${ $.listingProvider }'\n },\n otherStickyElsSize: 77,\n containerNode: null,\n listingNode: null,\n toolbarNode: null,\n stickyListingNode: null,\n stickyToolbarNode: null,\n storedOriginalToolbarElements: [],\n cache: {},\n flags: {},\n dirtyFlag: 'dirty'\n },\n\n /**\n * Initializes Sticky component.\n *\n * @returns {Object} Chainable.\n */\n initialize: function () {\n this._super();\n _.bindAll(this,\n 'adjustStickyElems',\n 'initListingNode',\n 'initToolbarNode',\n 'initContainerNode',\n 'initColumns',\n 'initStickyListingNode',\n 'initStickyToolbarNode',\n 'initLeftDataGridCap',\n 'initRightDataGridCap'\n );\n\n $.async(this.listingSelector,\n this.initListingNode);\n $.async(this.toolbarSelector,\n this.initToolbarNode);\n\n $.async(this.stickyContainerSelector,\n this,\n this.initContainerNode);\n\n return this;\n },\n\n /**\n * Init observables\n *\n * @returns {Object} Chainable.\n */\n initObservable: function () {\n this._super()\n .track('visible');\n\n return this;\n },\n\n /**\n * Init original listing node\n *\n * @param {HTMLElement} node\n */\n initListingNode: function (node) {\n if ($(node).is(this.stickyElementSelector)) {\n return;\n }\n this.listingNode = $(node);\n $.async(this.columnSelector, node, this.initColumns);\n },\n\n /**\n * Init original toolbar node\n *\n * @param {HTMLElement} node\n */\n initToolbarNode: function (node) {\n if ($(node).is(this.stickyElementSelector)) {\n return;\n }\n this.toolbarNode = $(node);\n },\n\n /**\n * Init sticky listing node\n *\n * @param {HTMLElement} node\n */\n initStickyListingNode: function (node) {\n this.stickyListingNode = $(node);\n this.checkPos();\n this.initListeners();\n },\n\n /**\n * Init sticky toolbar node\n *\n * @param {HTMLElement} node\n */\n initStickyToolbarNode: function (node) {\n this.stickyToolbarNode = $(node);\n },\n\n /**\n * Init sticky header container node\n *\n * @param {HTMLElement} node\n */\n initContainerNode: function (node) {\n this.containerNode = $(node);\n\n $.async(this.leftDataGridCapSelector,\n node,\n this.initLeftDataGridCap);\n $.async(this.rightDataGridCapSelector,\n node,\n this.initRightDataGridCap);\n\n $.async(this.stickyElementSelector,\n this.listing(),\n this.initStickyListingNode);\n $.async(this.stickyElementSelector,\n this.toolbar(),\n this.initStickyToolbarNode);\n },\n\n /**\n * Init columns (each time when amount of columns is changed)\n *\n */\n initColumns: function () {\n this.columns = this.listingNode.find(this.columnSelector);\n },\n\n /**\n * Init left DataGridCap\n *\n * @param {HTMLElement} node\n */\n initLeftDataGridCap: function (node) {\n this.leftDataGridCap = $(node);\n },\n\n /**\n * Init right DataGridCap\n *\n * @param {HTMLElement} node\n */\n initRightDataGridCap: function (node) {\n this.rightDataGridCap = $(node);\n },\n\n /**\n * Init listeners\n *\n * @returns {Object} Chainable.\n */\n initListeners: function () {\n this.adjustStickyElems();\n this.initOnResize()\n .initOnScroll()\n .initOnListingScroll();\n\n return this;\n },\n\n /**\n * Start to listen to window scroll event\n *\n * @returns {Object} Chainable.\n */\n initOnScroll: function () {\n this.lastHorizontalScrollPos = $(window).scrollLeft();\n document.addEventListener('scroll', function () {\n this.flags.scrolled = true;\n }.bind(this));\n\n return this;\n },\n\n /**\n * Start to listen to original listing scroll event\n *\n * @returns {Object} Chainable.\n */\n initOnListingScroll: function () {\n $(this.listingNode).on('scroll', function (e) {\n this.flags.listingScrolled = true;\n this.flags.listingScrolledValue = $(e.target).scrollLeft();\n }.bind(this));\n\n return this;\n },\n\n /**\n * Start to listen to window resize event\n *\n * @returns {Object} Chainable.\n */\n initOnResize: function () {\n $(window).on('resize', function () {\n this.flags.resized = true;\n }.bind(this));\n\n return this;\n },\n\n /**\n * Adjust sticky header elements according to flags of the events that have happened in the endless RAF loop\n */\n adjustStickyElems: function () {\n if (this.flags.resized ||\n this.flags.scrolled) {\n this.checkPos();\n }\n\n if (this.visible) {\n this.checkTableElemsWidth();\n\n if (this.flags.originalWidthChanged) {\n this.adjustContainerElemsWidth();\n }\n\n if (this.flags.resized) {\n this.onResize();\n }\n\n if (this.flags.scrolled) {\n this.onWindowScroll();\n }\n\n if (this.flags.listingScrolled) {\n this.onListingScroll(this.flags.listingScrolledValue);\n }\n }\n _.each(this.flags, function (val, key) {\n if (val === this.dirtyFlag) {\n this.flags[key] = false;\n } else if (val) {\n this.flags[key] = this.dirtyFlag;\n }\n }, this);\n\n raf(this.adjustStickyElems);\n },\n\n /**\n * Handles window scroll\n */\n onWindowScroll: function () {\n var scrolled = $(window).scrollLeft(),\n horizontal = this.lastHorizontalScrollPos !== scrolled;\n\n if (horizontal) {\n this.adjustOffset()\n .adjustDataGridCapPositions();\n this.lastHorizontalScrollPos = scrolled;\n } else {\n this.checkPos();\n }\n },\n\n /**\n * Handles original listing scroll\n *\n * @param {Number} scrolled\n */\n onListingScroll: function (scrolled) {\n this.adjustOffset(scrolled);\n },\n\n /**\n * Handles window resize\n */\n onResize: function () {\n this.checkPos();\n this.adjustContainerElemsWidth()\n .adjustDataGridCapPositions();\n },\n\n /**\n * Check if original table or columns change it dimensions and sets appropriate flag\n */\n checkTableElemsWidth: function () {\n var newWidth = this.getTableWidth();\n\n if (this.cache.tableWidth !== newWidth) {\n this.cache.tableWidth = newWidth;\n this.flags.originalWidthChanged = true;\n } else if (this.cache.colChecksum !== this.getColsChecksum()) {\n this.cache.colChecksum = this.getColsChecksum();\n this.flags.originalWidthChanged = true;\n }\n },\n\n /**\n * Get the checksum of original columns width\n *\n * @returns {Number}.\n */\n getColsChecksum: function () {\n return _.reduce(this.columns,\n function (pv, cv) {\n return ($(pv).width() || pv) + '' + $(cv).width();\n });\n },\n\n /**\n * Get the width of the sticky table wrapper\n *\n * @returns {Number}.\n */\n getListingWidth: function () {\n return this.listingNode.width();\n },\n\n /**\n * Get the width of the original table\n *\n * @returns {Number}.\n */\n getTableWidth: function () {\n return this.listingNode.find(this.tableSelector).width();\n },\n\n /**\n * Get the top elem: header or toolbar\n *\n * @returns {HTMLElement}.\n */\n getTopElement: function () {\n return this.toolbarNode || this.listingNode;\n },\n\n /**\n * Get the height of the other sticky elem (Page header)\n *\n * @returns {Number}.\n */\n getOtherStickyElementsSize: function () {\n return this.otherStickyElsSize;\n },\n\n /**\n * Get original bulk row height, if is visible\n *\n * @returns {Number}.\n */\n getBulkRowHeight: function () {\n return this.listingNode.find(this.bulkRowSelector).filter(':visible').height();\n },\n\n /**\n * Get top Y coord of the sticky header\n *\n * @returns {Number}.\n */\n getListingTopYCoord: function () {\n var bulkRowHeight = this.getBulkRowHeight();\n\n return this.listingNode.find('tbody').offset().top -\n this.containerNode.height() -\n $(window).scrollTop() +\n bulkRowHeight;\n },\n\n /**\n * Check if sticky header must be visible\n *\n * @returns {Boolean}.\n */\n getMustBeSticky: function () {\n var stickyTopCondition = this.getListingTopYCoord() - this.getOtherStickyElementsSize(),\n stickyBottomCondition = this.listingNode.offset().top +\n this.listingNode.height() -\n $(window).scrollTop() +\n this.getBulkRowHeight() -\n this.getOtherStickyElementsSize();\n\n return stickyTopCondition < 0 && stickyBottomCondition > 0;\n },\n\n /**\n * Resize sticky header and cols\n *\n * @returns {Object} Chainable.\n */\n adjustContainerElemsWidth: function () {\n this.resizeContainer()\n .resizeCols()\n .resizeBulk();\n\n return this;\n },\n\n /**\n * Resize sticky header\n *\n * @returns {Object} Chainable.\n */\n resizeContainer: function () {\n var listingWidth = this.getListingWidth();\n\n this.stickyListingNode.innerWidth(listingWidth);\n this.stickyListingNode.find(this.tableSelector).innerWidth(this.getTableWidth());\n\n if (this.stickyToolbarNode) {\n this.stickyToolbarNode.innerWidth(listingWidth);\n }\n\n return this;\n },\n\n /**\n * Resize sticky cols\n *\n * @returns {Object} Chainable.\n */\n resizeCols: function () {\n var cols = this.listingNode.find(this.columnSelector);\n\n this.stickyListingNode.find(this.columnSelector).each(function (ind) {\n var originalColWidth = $(cols[ind]).width();\n\n $(this).width(originalColWidth);\n });\n\n return this;\n },\n\n /**\n * Resize bulk row header\n *\n * @returns {Object} Chainable.\n */\n resizeBulk: function () {\n var bulk = this.containerNode.find(this.bulkRowHeaderSelector)[0];\n\n if (bulk) {\n $(bulk).innerWidth(this.getListingWidth());\n }\n\n return this;\n },\n\n /**\n * Reset viewport to the top of listing\n */\n resetToTop: function () {\n var posOfTopEl = this.getTopElement().offset().top - this.getOtherStickyElementsSize() || 0;\n\n $(window).scrollTop(posOfTopEl);\n },\n\n /**\n * Adjust sticky header offset\n *\n * @param {Number} val\n * @returns {Object} Chainable.\n */\n adjustOffset: function (val) {\n val = val || this.listingNode.scrollLeft();\n this.stickyListingNode.offset({\n left: this.listingNode.offset().left - val\n });\n\n return this;\n },\n\n /**\n * Adjust both DataGridCap position\n *\n * @returns {Object} Chainable.\n */\n adjustDataGridCapPositions: function () {\n this.adjustLeftDataGridCapPos()\n .adjustRightDataGridCapPos();\n\n return this;\n },\n\n /**\n * Adjust left DataGridCap position\n *\n * @returns {Object} Chainable.\n */\n adjustLeftDataGridCapPos: function () {\n this.leftDataGridCap.offset({\n left: this.listingNode.offset().left - this.leftDataGridCap.width()\n });\n\n return this;\n },\n\n /**\n * Adjust right DataGridCap position\n *\n * @returns {Object} Chainable.\n */\n adjustRightDataGridCapPos: function () {\n this.rightDataGridCap.offset({\n left: this.listingNode.offset().left + this.listingNode.width()\n });\n\n return this;\n },\n\n /**\n * Hides the oiginal toolbar opened dropdowns/collapsibles etc\n */\n collapseOriginalElements: function () {\n this.toolbarNode\n .find(this.toolbarCollapsiblesSelector)\n .css('visibility', 'hidden');\n $(this.listingNode.find(this.bulkRowSelector)[0]).css('visibility', 'hidden');\n },\n\n /**\n * Restores the oiginal toolbar opened dropdowns/collapsibles etc\n */\n restoreOriginalElements: function () {\n this.toolbarNode\n .find(this.toolbarCollapsiblesSelector)\n .css('visibility', 'visible');\n $(this.listingNode.find(this.bulkRowSelector)[0]).css('visibility', 'visible');\n },\n\n /**\n * Toggle the visibility of sticky header\n *\n * @returns {Object} Chainable.\n */\n toggleContainerVisibility: function () {\n this.visible = !this.visible;\n\n return this;\n },\n\n /**\n * Checks position of the listing to know if need to show/hide sticky header\n *\n * @returns {Boolean} whether the visibility of the sticky header was toggled.\n */\n checkPos: function () {\n var isSticky = this.visible,\n mustBeSticky = this.getMustBeSticky(),\n needChange = isSticky !== mustBeSticky;\n\n if (needChange) {\n if (mustBeSticky) {\n this.collapseOriginalElements();\n this.toggleContainerVisibility();\n this.adjustContainerElemsWidth()\n .adjustOffset()\n .adjustDataGridCapPositions();\n\n } else {\n this.toggleContainerVisibility();\n this.restoreOriginalElements();\n }\n }\n\n return needChange;\n }\n });\n});\n","Magento_Ui/js/grid/filters/chips.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 template: 'ui/grid/filters/chips',\n componentType: 'filtersChips'\n },\n\n /**\n * Defines if some of components' children has available previews.\n *\n * @returns {Boolean}\n */\n hasPreviews: function () {\n return this.elems().some(function (elem) {\n return !!elem.previews.length;\n });\n },\n\n /**\n * Calls clear method on all of its' children.\n *\n * @returns {Chips} Chainable.\n */\n clear: function () {\n _.invoke(this.elems(), 'clear');\n\n return this;\n }\n });\n});\n","Magento_Ui/js/grid/filters/filters.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 'uiCollection',\n 'mage/translate',\n 'jquery'\n], function (_, utils, layout, Collection, $t, $) {\n 'use strict';\n\n /**\n * Extracts and formats preview of an element.\n *\n * @param {Object} elem - Element whose preview should be extracted.\n * @returns {Object} Formatted data.\n */\n function extractPreview(elem) {\n return {\n label: elem.label,\n preview: elem.getPreview(),\n elem: elem\n };\n }\n\n /**\n * Removes empty properties from the provided object.\n *\n * @param {Object} data - Object to be processed.\n * @returns {Object}\n */\n function removeEmpty(data) {\n var result = utils.mapRecursive(data, utils.removeEmptyValues.bind(utils));\n\n return utils.mapRecursive(result, function (value) {\n return _.isString(value) ? value.trim() : value;\n });\n }\n\n return Collection.extend({\n defaults: {\n template: 'ui/grid/filters/filters',\n stickyTmpl: 'ui/grid/sticky/filters',\n _processed: [],\n columnsProvider: 'ns = ${ $.ns }, componentType = columns',\n bookmarksProvider: 'ns = ${ $.ns }, componentType = bookmark',\n applied: {\n placeholder: true\n },\n filters: {\n placeholder: true\n },\n templates: {\n filters: {\n base: {\n parent: '${ $.$data.filters.name }',\n name: '${ $.$data.column.index }',\n provider: '${ $.$data.filters.name }',\n dataScope: '${ $.$data.column.index }',\n label: '${ $.$data.column.label }',\n imports: {\n visible: '${ $.$data.column.name }:visible'\n }\n },\n text: {\n component: 'Magento_Ui/js/form/element/abstract',\n template: 'ui/grid/filters/field'\n },\n select: {\n component: 'Magento_Ui/js/form/element/select',\n template: 'ui/grid/filters/field',\n options: '${ JSON.stringify($.$data.column.options) }',\n caption: ' '\n },\n dateRange: {\n component: 'Magento_Ui/js/grid/filters/range',\n rangeType: 'date'\n },\n datetimeRange: {\n component: 'Magento_Ui/js/grid/filters/range',\n rangeType: 'datetime'\n },\n textRange: {\n component: 'Magento_Ui/js/grid/filters/range',\n rangeType: 'text'\n }\n }\n },\n chipsConfig: {\n name: '${ $.name }_chips',\n provider: '${ $.chipsConfig.name }',\n component: 'Magento_Ui/js/grid/filters/chips'\n },\n listens: {\n active: 'updatePreviews',\n applied: 'cancel updateActive'\n },\n statefull: {\n applied: true\n },\n exports: {\n applied: '${ $.provider }:params.filters'\n },\n imports: {\n onColumnsUpdate: '${ $.columnsProvider }:elems',\n onBackendError: '${ $.provider }:lastError',\n bookmarksActiveIndex: '${ $.bookmarksProvider }:activeIndex'\n },\n modules: {\n columns: '${ $.columnsProvider }',\n chips: '${ $.chipsConfig.provider }'\n }\n },\n\n /**\n * Initializes filters component.\n *\n * @returns {Filters} Chainable.\n */\n initialize: function (config) {\n if (typeof config.options !== 'undefined' && config.options.dateFormat) {\n this.constructor.defaults.templates.filters.dateRange.dateFormat = config.options.dateFormat;\n }\n _.bindAll(this, 'updateActive');\n\n this._super()\n .initChips()\n .cancel();\n\n return this;\n },\n\n /**\n * Initializes observable properties.\n *\n * @returns {Filters} Chainable.\n */\n initObservable: function () {\n this._super()\n .track({\n active: [],\n previews: []\n });\n\n return this;\n },\n\n /**\n * Initializes chips component.\n *\n * @returns {Filters} Chainable.\n */\n initChips: function () {\n layout([this.chipsConfig]);\n\n this.chips('insertChild', this.name);\n\n return this;\n },\n\n /**\n * Called when another element was added to filters collection.\n *\n * @returns {Filters} Chainable.\n */\n initElement: function (elem) {\n this._super();\n\n elem.on('elems', this.updateActive);\n\n this.updateActive();\n\n return this;\n },\n\n /**\n * Clears filters data.\n *\n * @param {Object} [filter] - If provided, then only specified\n * filter will be cleared. Otherwise, clears all data.\n * @returns {Filters} Chainable.\n */\n clear: function (filter) {\n filter ?\n filter.clear() :\n _.invoke(this.active, 'clear');\n\n this.apply();\n\n return this;\n },\n\n /**\n * Sets filters data to the applied state.\n *\n * @returns {Filters} Chainable.\n */\n apply: function () {\n if (typeof $('body').notification === 'function') {\n $('body').notification('clear');\n }\n this.set('applied', removeEmpty(this.filters));\n return this;\n },\n\n /**\n * Resets filters to the last applied state.\n *\n * @returns {Filters} Chainable.\n */\n cancel: function () {\n this.set('filters', utils.copy(this.applied));\n\n return this;\n },\n\n /**\n * Sets provided data to filter components (without applying it).\n *\n * @param {Object} data - Filters data.\n * @param {Boolean} [partial=false] - Flag that defines whether\n * to completely replace current filters data or to extend it.\n * @returns {Filters} Chainable.\n */\n setData: function (data, partial) {\n var filters = partial ? this.filters : {};\n\n data = utils.extend({}, filters, data);\n\n this.set('filters', data);\n\n return this;\n },\n\n /**\n * Creates instance of a filter associated with the provided column.\n *\n * @param {Column} column - Column component for which to create a filter.\n * @returns {Filters} Chainable.\n */\n addFilter: function (column) {\n var index = column.index,\n processed = this._processed,\n filter;\n\n if (!column.filter || _.contains(processed, index)) {\n return this;\n }\n\n filter = this.buildFilter(column);\n\n processed.push(index);\n\n layout([filter]);\n\n return this;\n },\n\n /**\n * Creates filter component configuration associated with the provided column.\n *\n * @param {Column} column - Column component with a basic filter declaration.\n * @returns {Object} Filters' configuration.\n */\n buildFilter: function (column) {\n var filters = this.templates.filters,\n filter = column.filter,\n type = filters[filter.filterType];\n\n if (_.isObject(filter) && type) {\n filter = utils.extend({}, type, filter);\n } else if (_.isString(filter)) {\n filter = filters[filter];\n }\n\n filter = utils.extend({}, filters.base, filter);\n //Accepting labels as is.\n filter.__disableTmpl = {\n label: 1,\n options: 1\n };\n\n filter = utils.template(filter, {\n filters: this,\n column: column\n }, true, true);\n\n filter.__disableTmpl = {\n label: true\n };\n\n return filter;\n },\n\n /**\n * Returns an array of range filters.\n *\n * @returns {Array}\n */\n getRanges: function () {\n return this.elems.filter(function (filter) {\n return filter.isRange;\n });\n },\n\n /**\n * Returns an array of non-range filters.\n *\n * @returns {Array}\n */\n getPlain: function () {\n return this.elems.filter(function (filter) {\n return !filter.isRange;\n });\n },\n\n /**\n * Tells wether specified filter should be visible.\n *\n * @param {Object} filter\n * @returns {Boolean}\n */\n isFilterVisible: function (filter) {\n return filter.visible() || this.isFilterActive(filter);\n },\n\n /**\n * Checks if specified filter is active.\n *\n * @param {Object} filter\n * @returns {Boolean}\n */\n isFilterActive: function (filter) {\n return _.contains(this.active, filter);\n },\n\n /**\n * Checks if collection has visible filters.\n *\n * @returns {Boolean}\n */\n hasVisible: function () {\n return this.elems.some(this.isFilterVisible, this);\n },\n\n /**\n * Finds filters with a not empty data\n * and sets them to the 'active' filters array.\n *\n * @returns {Filters} Chainable.\n */\n updateActive: function () {\n var applied = _.keys(this.applied);\n\n this.active = this.elems.filter(function (elem) {\n return _.contains(applied, elem.index);\n });\n\n return this;\n },\n\n /**\n * Returns number of applied filters.\n *\n * @returns {Number}\n */\n countActive: function () {\n return this.active.length;\n },\n\n /**\n * Extract previews of a specified filters.\n *\n * @param {Array} filters - Filters to be processed.\n * @returns {Filters} Chainable.\n */\n updatePreviews: function (filters) {\n var previews = filters.map(extractPreview);\n\n this.previews = _.compact(previews);\n\n return this;\n },\n\n /**\n * Listener of the columns provider children array changes.\n *\n * @param {Array} columns - Current columns list.\n */\n onColumnsUpdate: function (columns) {\n columns.forEach(this.addFilter, this);\n },\n\n /**\n * Provider ajax error listener.\n *\n * @param {bool} isError - Selected index of the filter.\n */\n onBackendError: function (isError) {\n var defaultMessage = 'Something went wrong with processing the default view and we have restored the ' +\n 'filter to its original state.',\n customMessage = 'Something went wrong with processing current custom view and filters have been ' +\n 'reset to its original state. Please edit filters then click apply.';\n\n if (isError) {\n this.clear();\n\n $('body').notification('clear')\n .notification('add', {\n error: true,\n message: $.mage.__(this.bookmarksActiveIndex !== 'default' ? customMessage : defaultMessage),\n\n /**\n * @param {String} message\n */\n insertMethod: function (message) {\n var $wrapper = $('<div></div>').html(message);\n\n $('.page-main-actions').after($wrapper);\n }\n });\n }\n }\n });\n});\n","Magento_Ui/js/grid/filters/range.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 'mageUtils',\n 'Magento_Ui/js/form/components/group',\n 'mage/translate'\n], function (_, layout, utils, Group, $t) {\n 'use strict';\n\n return Group.extend({\n defaults: {\n template: 'ui/grid/filters/elements/group',\n isRange: true,\n templates: {\n base: {\n parent: '${ $.$data.group.name }',\n provider: '${ $.$data.group.provider }',\n template: 'ui/grid/filters/field'\n },\n date: {\n component: 'Magento_Ui/js/form/element/date',\n dateFormat: 'MM/dd/YYYY',\n shiftedValue: 'filter'\n },\n datetime: {\n component: 'Magento_Ui/js/form/element/date',\n dateFormat: 'MM/dd/YYYY',\n shiftedValue: 'filter',\n options: {\n showsTime: true\n }\n },\n text: {\n component: 'Magento_Ui/js/form/element/abstract'\n },\n ranges: {\n from: {\n label: $t('from'),\n dataScope: 'from'\n },\n to: {\n label: $t('to'),\n dataScope: 'to'\n }\n }\n }\n },\n\n /**\n * Initializes range component.\n *\n * @returns {Range} Chainable.\n */\n initialize: function (config) {\n if (config.dateFormat) {\n this.constructor.defaults.templates.date.pickerDefaultDateFormat = config.dateFormat;\n }\n this._super()\n .initChildren();\n\n return this;\n },\n\n /**\n * Creates instances of child components.\n *\n * @returns {Range} Chainable.\n */\n initChildren: function () {\n var children = this.buildChildren();\n\n layout(children);\n\n return this;\n },\n\n /**\n * Creates configuration for the child components.\n *\n * @returns {Object}\n */\n buildChildren: function () {\n var templates = this.templates,\n typeTmpl = templates[this.rangeType],\n tmpl = utils.extend({}, templates.base, typeTmpl),\n children = {};\n\n _.each(templates.ranges, function (range, key) {\n children[key] = utils.extend({}, tmpl, range);\n });\n\n return utils.template(children, {\n group: this\n }, true, true);\n },\n\n /**\n * Clears childrens data.\n *\n * @returns {Range} Chainable.\n */\n clear: function () {\n this.elems.each('clear');\n\n return this;\n },\n\n /**\n * Checks if some children has data.\n *\n * @returns {Boolean}\n */\n hasData: function () {\n return this.elems.some('hasData');\n }\n });\n});\n","Magento_Ui/js/grid/filters/elements/ui-select.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/ui-select',\n 'jquery',\n 'underscore'\n], function (Select, $, _) {\n 'use strict';\n\n return Select.extend({\n defaults: {\n bookmarkProvider: 'ns = ${ $.ns }, index = bookmarks',\n filterChipsProvider: 'componentType = filters, ns = ${ $.ns }',\n validationUrl: false,\n loadedOption: [],\n validationLoading: true,\n imports: {\n applied: '${ $.filterChipsProvider }:applied',\n activeIndex: '${ $.bookmarkProvider }:activeIndex'\n },\n modules: {\n filterChips: '${ $.filterChipsProvider }'\n },\n listens: {\n activeIndex: 'validateInitialValue',\n applied: 'validateInitialValue'\n }\n\n },\n\n /**\n * Initializes UiSelect component.\n *\n * @returns {UiSelect} Chainable.\n */\n initialize: function () {\n this._super();\n\n this.validateInitialValue();\n\n return this;\n },\n\n /**\n * Validate initial value actually exists\n */\n validateInitialValue: function () {\n if (_.isEmpty(this.value())) {\n this.validationLoading(false);\n\n return;\n }\n\n $.ajax({\n url: this.validationUrl,\n type: 'GET',\n dataType: 'json',\n context: this,\n data: {\n ids: this.value()\n },\n\n /** @param {Object} response */\n success: function (response) {\n if (!_.isEmpty(response)) {\n this.options([]);\n this.success({\n options: response\n });\n }\n this.filterChips().updateActive();\n },\n\n /** set empty array if error occurs */\n error: function () {\n this.options([]);\n },\n\n /** stop loader */\n complete: function () {\n this.validationLoading(false);\n this.setCaption();\n }\n });\n }\n });\n});\n","Magento_Ui/js/grid/search/search.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 'mageUtils',\n 'uiElement',\n 'jquery'\n], function (_, layout, $t, utils, Element, $) {\n 'use strict';\n\n return Element.extend({\n defaults: {\n template: 'ui/grid/search/search',\n placeholder: $t('Search by keyword'),\n label: $t('Keyword'),\n value: '',\n keywordUpdated: false,\n previews: [],\n chipsProvider: 'componentType = filtersChips, ns = ${ $.ns }',\n statefull: {\n value: true\n },\n tracks: {\n value: true,\n previews: true,\n inputValue: true,\n focused: true,\n keywordUpdated: true\n },\n imports: {\n inputValue: 'value',\n updatePreview: 'value',\n focused: false\n },\n exports: {\n value: '${ $.provider }:params.search',\n keywordUpdated: '${ $.provider }:params.keywordUpdated'\n },\n modules: {\n chips: '${ $.chipsProvider }'\n }\n },\n\n /**\n * Initializes search component.\n *\n * @returns {Search} Chainable.\n */\n initialize: function () {\n var urlParams = window.location.href.slice(window.location.href.search('[\\&\\?](search=)')).split('&'),\n searchTerm = [];\n\n this._super()\n .initChips();\n\n if (urlParams[0]) {\n searchTerm = urlParams[0].split('=');\n\n if (searchTerm[1]) {\n this.apply(decodeURIComponent(searchTerm[1]));\n }\n }\n\n return this;\n },\n\n /**\n * Initializes chips component.\n *\n * @returns {Search} Chainbale.\n */\n initChips: function () {\n this.chips('insertChild', this, 0);\n\n return this;\n },\n\n /**\n * Clears search.\n *\n * @returns {Search} Chainable.\n */\n clear: function () {\n this.value = '';\n\n return this;\n },\n\n /**\n * Click To ScrollTop.\n */\n scrollTo: function ($data) {\n $('html, body').animate({\n scrollTop: 0\n }, 'slow', function () {\n $data.focused = false;\n $data.focused = true;\n });\n },\n\n /**\n * Resets input value to the last applied state.\n *\n * @returns {Search} Chainable.\n */\n cancel: function () {\n this.inputValue = this.value;\n\n return this;\n },\n\n /**\n * Applies search query.\n *\n * @param {String} [value=inputValue] - If not specified, then\n * value of the input field will be used.\n * @returns {Search} Chainable.\n */\n apply: function (value) {\n value = value || this.inputValue;\n\n this.keywordUpdated = this.value !== value;\n this.value = this.inputValue = value.trim();\n\n return this;\n },\n\n /**\n * Updates preview data.\n *\n * @returns {Search} Chainable.\n */\n updatePreview: function () {\n var preview = [];\n\n if (this.value) {\n preview.push({\n elem: this,\n label: this.label,\n preview: this.value\n });\n }\n\n this.previews = preview;\n\n return this;\n }\n });\n});\n","Magento_Ui/js/grid/columns/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 'mageUtils',\n 'moment',\n './column',\n 'underscore',\n 'moment-timezone-with-data'\n], function (utils, moment, Column, _) {\n 'use strict';\n\n return Column.extend({\n defaults: {\n dateFormat: 'MMM d, YYYY h:mm:ss A',\n calendarConfig: []\n },\n\n /**\n * Overrides base method to normalize date format\n *\n * @returns {DateColumn} Chainable\n */\n initConfig: function () {\n this._super();\n\n this.dateFormat = utils.normalizeDate(this.dateFormat ? this.dateFormat : this.options.dateFormat);\n\n return this;\n },\n\n /**\n * Formats incoming date based on the 'dateFormat' property.\n *\n * @returns {String} Formatted date.\n */\n getLabel: function (value, format) {\n var date;\n\n if (this.storeLocale !== undefined) {\n moment.locale(this.storeLocale, utils.extend({}, this.calendarConfig));\n }\n\n date = moment.utc(this._super());\n\n if (!_.isUndefined(this.timezone) && moment.tz.zone(this.timezone) !== null) {\n date = date.tz(this.timezone);\n }\n\n date = date.isValid() && value[this.index] ?\n date.format(format || this.dateFormat) :\n '';\n\n return date;\n }\n });\n});\n","Magento_Ui/js/grid/columns/column.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 'mageUtils',\n 'uiElement'\n], function (_, registry, utils, Element) {\n 'use strict';\n\n return Element.extend({\n defaults: {\n headerTmpl: 'ui/grid/columns/text',\n bodyTmpl: 'ui/grid/cells/text',\n disableAction: false,\n controlVisibility: true,\n sortable: true,\n sorting: false,\n visible: true,\n draggable: true,\n fieldClass: {},\n ignoreTmpls: {\n fieldAction: true\n },\n statefull: {\n visible: true,\n sorting: true\n },\n imports: {\n exportSorting: 'sorting'\n },\n listens: {\n '${ $.provider }:params.sorting.field': 'onSortChange'\n },\n modules: {\n source: '${ $.provider }'\n }\n },\n\n /**\n * Initializes column component.\n *\n * @returns {Column} Chainable.\n */\n initialize: function () {\n this._super()\n .initFieldClass();\n\n return this;\n },\n\n /**\n * Initializes observable properties.\n *\n * @returns {Column} Chainable.\n */\n initObservable: function () {\n this._super()\n .track([\n 'visible',\n 'sorting',\n 'disableAction'\n ])\n .observe([\n 'dragging'\n ]);\n\n return this;\n },\n\n /**\n * Extends list of field classes.\n *\n * @returns {Column} Chainable.\n */\n initFieldClass: function () {\n _.extend(this.fieldClass, {\n _dragging: this.dragging\n });\n\n return this;\n },\n\n /**\n * Applies specified stored state of a column or one of its' properties.\n *\n * @param {String} state - Defines what state should be used: saved or default.\n * @param {String} [property] - Defines what columns' property should be applied.\n * If not specified, then all columns stored properties will be used.\n * @returns {Column} Chainable.\n */\n applyState: function (state, property) {\n var namespace = this.storageConfig.root;\n\n if (property) {\n namespace += '.' + property;\n }\n\n this.storage('applyStateOf', state, namespace);\n\n return this;\n },\n\n /**\n * Sets columns' sorting. If column is currently sorted,\n * than its' direction will be toggled.\n *\n * @param {*} [enable=true] - If false, than sorting will\n * be removed from a column.\n * @returns {Column} Chainable.\n */\n sort: function (enable) {\n if (!this.sortable) {\n return this;\n }\n\n enable !== false ?\n this.toggleSorting() :\n this.sorting = false;\n\n return this;\n },\n\n /**\n * Sets descending columns' sorting.\n *\n * @returns {Column} Chainable.\n */\n sortDescending: function () {\n if (this.sortable) {\n this.sorting = 'desc';\n }\n\n return this;\n },\n\n /**\n * Sets ascending columns' sorting.\n *\n * @returns {Column} Chainable.\n */\n sortAscending: function () {\n if (this.sortable) {\n this.sorting = 'asc';\n }\n\n return this;\n },\n\n /**\n * Toggles sorting direction.\n *\n * @returns {Column} Chainable.\n */\n toggleSorting: function () {\n this.sorting === 'asc' ?\n this.sortDescending() :\n this.sortAscending();\n\n return this;\n },\n\n /**\n * Checks if column is sorted.\n *\n * @returns {Boolean}\n */\n isSorted: function () {\n return !!this.sorting;\n },\n\n /**\n * Exports sorting data to the dataProvider if\n * sorting of a column is enabled.\n */\n exportSorting: function () {\n if (!this.sorting) {\n return;\n }\n\n this.source('set', 'params.sorting', {\n field: this.index,\n direction: this.sorting\n });\n },\n\n /**\n * Checks if column has an assigned action that will\n * be performed when clicking on one of its' fields.\n *\n * @returns {Boolean}\n */\n hasFieldAction: function () {\n return !!this.fieldAction || !!this.fieldActions;\n },\n\n /**\n * Applies action described in a 'fieldAction' property\n * or actions described in 'fieldActions' property.\n *\n * @param {Number} rowIndex - Index of a row which initiates action.\n * @returns {Column} Chainable.\n *\n * @example Example of fieldAction definition, which is equivalent to\n * referencing to external component named 'listing.multiselect'\n * and calling its' method 'toggleSelect' with params [rowIndex, true] =>\n *\n * {\n * provider: 'listing.multiselect',\n * target: 'toggleSelect',\n * params: ['${ $.$data.rowIndex }', true]\n * }\n */\n applyFieldAction: function (rowIndex) {\n if (!this.hasFieldAction() || this.disableAction) {\n return this;\n }\n\n if (this.fieldActions) {\n this.fieldActions.forEach(this.applySingleAction.bind(this, rowIndex), this);\n } else {\n this.applySingleAction(rowIndex);\n }\n\n return this;\n },\n\n /**\n * Applies single action\n *\n * @param {Number} rowIndex - Index of a row which initiates action.\n * @param {Object} action - Action (fieldAction) to be applied\n *\n */\n applySingleAction: function (rowIndex, action) {\n var callback;\n\n action = action || this.fieldAction;\n action = utils.template(action, {\n column: this,\n rowIndex: rowIndex\n }, true);\n\n callback = this._getFieldCallback(action);\n\n if (_.isFunction(callback)) {\n callback();\n }\n },\n\n /**\n * Returns field action handler if it was specified.\n *\n * @param {Object} record - Record object with which action is associated.\n * @returns {Function|Undefined}\n */\n getFieldHandler: function (record) {\n if (this.hasFieldAction()) {\n return this.applyFieldAction.bind(this, record._rowIndex);\n }\n },\n\n /**\n * Creates action callback based on its' data.\n *\n * @param {Object} action - Actions' object.\n * @returns {Function|Boolean} Callback function or false\n * value if it was impossible create a callback.\n */\n _getFieldCallback: function (action) {\n var args = action.params || [],\n callback = action.target;\n\n if (action.provider && action.target) {\n args.unshift(action.target);\n\n callback = registry.async(action.provider);\n }\n\n if (!_.isFunction(callback)) {\n return false;\n }\n\n return function () {\n callback.apply(callback, args);\n };\n },\n\n /**\n * Ment to preprocess data associated with a current columns' field.\n *\n * @param {Object} record - Data to be preprocessed.\n * @returns {String}\n */\n getLabel: function (record) {\n return record[this.index];\n },\n\n /**\n * UnsanitizedHtml version of getLabel.\n *\n * @param {Object} record - Data to be preprocessed.\n * @returns {String}\n */\n getLabelUnsanitizedHtml: function (record) {\n return this.getLabel(record);\n },\n\n /**\n * Returns list of classes that should be applied to a field.\n *\n * @returns {Object}\n */\n getFieldClass: function () {\n return this.fieldClass;\n },\n\n /**\n * Returns path to the columns' header template.\n *\n * @returns {String}\n */\n getHeader: function () {\n return this.headerTmpl;\n },\n\n /**\n * Returns path to the columns' body template.\n *\n * @returns {String}\n */\n getBody: function () {\n return this.bodyTmpl;\n },\n\n /**\n * Listener of the providers' sorting state changes.\n *\n * @param {Srting} field - Field by which current sorting is performed.\n */\n onSortChange: function (field) {\n if (field !== this.index) {\n this.sort(false);\n }\n }\n });\n});\n","Magento_Ui/js/grid/columns/actions.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 './column',\n 'Magento_Ui/js/modal/confirm',\n 'mage/dataPost'\n], function (_, utils, registry, Column, confirm, dataPost) {\n 'use strict';\n\n return Column.extend({\n defaults: {\n bodyTmpl: 'ui/grid/cells/actions',\n sortable: false,\n draggable: false,\n actions: [],\n rows: [],\n rowsProvider: '${ $.parentName }',\n fieldClass: {\n 'data-grid-actions-cell': true\n },\n templates: {\n actions: {}\n },\n imports: {\n rows: '${ $.rowsProvider }:rows'\n },\n listens: {\n rows: 'updateActions'\n }\n },\n\n /**\n * Initializes observable properties.\n *\n * @returns {ActionsColumn} Chainable.\n */\n initObservable: function () {\n this._super()\n .track('actions');\n\n return this;\n },\n\n /**\n * Returns specific action of a specified row\n * or all action objects associated with it.\n *\n * @param {Number} rowIndex - Index of a row.\n * @param {String} [actionIndex] - Action identifier.\n * @returns {Array|Object}\n */\n getAction: function (rowIndex, actionIndex) {\n var rowActions = this.actions[rowIndex];\n\n return rowActions && actionIndex ?\n rowActions[actionIndex] :\n rowActions;\n },\n\n /**\n * Returns visible actions for a specified row.\n *\n * @param {Number} rowIndex - Index of a row.\n * @returns {Array} Visible actions.\n */\n getVisibleActions: function (rowIndex) {\n var rowActions = this.getAction(rowIndex);\n\n return _.filter(rowActions, this.isActionVisible, this);\n },\n\n /**\n * Adds new action. If an action with the specified identifier\n * already exists, then the original will be overridden.\n *\n * @param {String} index - Actions' identifier.\n * @param {Object} action - Actions' data.\n * @returns {ActionsColumn} Chainable.\n */\n addAction: function (index, action) {\n var actionTmpls = this.templates.actions;\n\n actionTmpls[index] = action;\n\n this.updateActions();\n\n return this;\n },\n\n /**\n * Recreates actions for each row.\n *\n * @returns {ActionsColumn} Chainable.\n */\n updateActions: function () {\n this.actions = this.rows.map(this._formatActions, this);\n\n return this;\n },\n\n /**\n * Processes actions, setting additional information to them and\n * evaluating their properties as string templates.\n *\n * @private\n * @param {Object} row - Row object.\n * @param {Number} rowIndex - Index of a row.\n * @returns {Array}\n */\n _formatActions: function (row, rowIndex) {\n var rowActions = row[this.index] || {},\n recordId = row[this.indexField],\n customActions = this.templates.actions;\n\n /**\n * Actions iterator.\n */\n function iterate(action, index) {\n action = utils.extend({\n index: index,\n rowIndex: rowIndex,\n recordId: recordId\n }, action);\n\n return utils.template(action, row, true);\n }\n\n rowActions = _.mapObject(rowActions, iterate);\n customActions = _.map(customActions, iterate);\n\n customActions.forEach(function (action) {\n rowActions[action.index] = action;\n });\n\n return rowActions;\n },\n\n /**\n * Applies specified action.\n *\n * @param {String} actionIndex - Actions' identifier.\n * @param {Number} rowIndex - Index of a row.\n * @returns {ActionsColumn} Chainable.\n */\n applyAction: function (actionIndex, rowIndex) {\n var action = this.getAction(rowIndex, actionIndex),\n callback = this._getCallback(action);\n\n action.confirm ?\n this._confirm(action, callback) :\n callback();\n\n return this;\n },\n\n /**\n * Creates handler for the provided action if it's required.\n *\n * @param {Object} action - Action object.\n * @returns {Function|Undefined}\n */\n getActionHandler: function (action) {\n var index = action.index,\n rowIndex = action.rowIndex;\n\n if (this.isHandlerRequired(index, rowIndex)) {\n return this.applyAction.bind(this, index, rowIndex);\n }\n },\n\n /**\n * Returns target of action if it's been set.\n *\n * @param {Object} action - Action object.\n * @returns {String}\n */\n getTarget: function (action) {\n if (action.target) {\n return action.target;\n }\n\n return '_self';\n },\n\n /**\n * Checks if specified action requires a handler function.\n *\n * @param {String} actionIndex - Actions' identifier.\n * @param {Number} rowIndex - Index of a row.\n * @returns {Boolean}\n */\n isHandlerRequired: function (actionIndex, rowIndex) {\n var action = this.getAction(rowIndex, actionIndex);\n\n return _.isObject(action.callback) || action.confirm || !action.href;\n },\n\n /**\n * Creates action callback based on it's data. If the action doesn't specify\n * a callback function than the default one will be used.\n *\n * @private\n * @param {Object} action - Action's object.\n * @returns {Function} Callback function.\n */\n _getCallback: function (action) {\n var args = [action.index, action.recordId, action],\n callback = action.callback;\n\n if (utils.isObject(callback)) {\n args.unshift(callback.target);\n\n callback = registry.async(callback.provider);\n } else if (_.isArray(callback)) {\n return this._getCallbacks(action);\n } else if (!_.isFunction(callback)) {\n callback = this.defaultCallback.bind(this);\n }\n\n return function () {\n callback.apply(callback, args);\n };\n },\n\n /**\n * Creates action callback for multiple actions.\n *\n * @private\n * @param {Object} action - Action's object.\n * @returns {Function} Callback function.\n */\n _getCallbacks: function (action) {\n var callback = action.callback,\n callbacks = [],\n tmpCallback;\n\n _.each(callback, function (cb) {\n tmpCallback = {\n action: registry.async(cb.provider),\n args: _.compact([cb.target, cb.params])\n };\n callbacks.push(tmpCallback);\n });\n\n return function () {\n _.each(callbacks, function (cb) {\n cb.action.apply(cb.action, cb.args);\n });\n };\n },\n\n /**\n * Default action callback. Redirects to\n * the specified in action's data url.\n *\n * @param {String} actionIndex - Action's identifier.\n * @param {(Number|String)} recordId - Id of the record associated\n * with a specified action.\n * @param {Object} action - Action's data.\n */\n defaultCallback: function (actionIndex, recordId, action) {\n if (action.post) {\n dataPost().postData({\n action: action.href,\n data: {}\n });\n } else {\n window.location.href = action.href;\n }\n },\n\n /**\n * Shows actions' confirmation window.\n *\n * @param {Object} action - Action's data.\n * @param {Function} callback - Callback that will be\n * invoked if action is confirmed.\n */\n _confirm: function (action, callback) {\n var confirmData = action.confirm;\n\n confirm({\n title: confirmData.title,\n content: confirmData.message,\n actions: {\n confirm: callback\n }\n });\n },\n\n /**\n * Checks if row has only one visible action.\n *\n * @param {Number} rowIndex - Row index.\n * @returns {Boolean}\n */\n isSingle: function (rowIndex) {\n return this.getVisibleActions(rowIndex).length === 1;\n },\n\n /**\n * Checks if row has more than one visible action.\n *\n * @param {Number} rowIndex - Row index.\n * @returns {Boolean}\n */\n isMultiple: function (rowIndex) {\n return this.getVisibleActions(rowIndex).length > 1;\n },\n\n /**\n * Checks if action should be displayed.\n *\n * @param {Object} action - Action object.\n * @returns {Boolean}\n */\n isActionVisible: function (action) {\n return action.hidden !== true;\n },\n\n /**\n * Overrides base method, because this component\n * can't have global field action.\n *\n * @returns {Boolean} False.\n */\n hasFieldAction: function () {\n return false;\n }\n });\n});\n","Magento_Ui/js/grid/columns/thumbnail.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n './column',\n 'jquery',\n 'mage/template',\n 'text!Magento_Ui/templates/grid/cells/thumbnail/preview.html',\n 'underscore',\n 'Magento_Ui/js/modal/modal',\n 'mage/translate'\n], function (Column, $, mageTemplate, thumbnailPreviewTemplate, _) {\n 'use strict';\n\n return Column.extend({\n defaults: {\n bodyTmpl: 'ui/grid/cells/thumbnail',\n fieldClass: {\n 'data-grid-thumbnail-cell': true\n }\n },\n\n /**\n * Get image source data per row.\n *\n * @param {Object} row\n * @returns {String}\n */\n getSrc: function (row) {\n return row[this.index + '_src'];\n },\n\n /**\n * Get original image source data per row.\n *\n * @param {Object} row\n * @returns {String}\n */\n getOrigSrc: function (row) {\n return row[this.index + '_orig_src'];\n },\n\n /**\n * Get link data per row.\n *\n * @param {Object} row\n * @returns {String}\n */\n getLink: function (row) {\n return row[this.index + '_link'];\n },\n\n /**\n * Get alternative text data per row.\n *\n * @param {Object} row\n * @returns {String}\n */\n getAlt: function (row) {\n return _.escape(row[this.index + '_alt']);\n },\n\n /**\n * Check if preview available.\n *\n * @returns {Boolean}\n */\n isPreviewAvailable: function () {\n return this['has_preview'] || false;\n },\n\n /**\n * Build preview.\n *\n * @param {Object} row\n */\n preview: function (row) {\n var modalHtml = mageTemplate(\n thumbnailPreviewTemplate,\n {\n src: this.getOrigSrc(row), alt: this.getAlt(row), link: this.getLink(row),\n linkText: $.mage.__('Go to Details Page')\n }\n ),\n previewPopup = $('<div></div>').html(modalHtml);\n\n previewPopup.modal({\n title: this.getAlt(row),\n innerScroll: true,\n modalClass: '_image-box',\n buttons: []\n }).trigger('openModal');\n },\n\n /**\n * Get field handler per row.\n *\n * @param {Object} row\n * @returns {Function}\n */\n getFieldHandler: function (row) {\n if (this.isPreviewAvailable()) {\n return this.preview.bind(this, row);\n }\n }\n });\n});\n","Magento_Ui/js/grid/columns/image.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n 'Magento_Ui/js/grid/columns/column'\n], function (Column) {\n 'use strict';\n\n return Column.extend({\n defaults: {\n bodyTmpl: 'ui/grid/columns/image',\n modules: {\n masonry: '${ $.parentName }',\n previewComponent: '${ $.parentName }.preview'\n },\n previewRowId: null,\n previewHeight: 0,\n fields: {\n id: 'id',\n url: 'url'\n }\n },\n\n /**\n * Init observable variables\n * @return {Object}\n */\n initObservable: function () {\n this._super()\n .observe([\n 'previewRowId',\n 'previewHeight'\n ]);\n\n return this;\n },\n\n /**\n * Updates styles when image loaded.\n *\n * @param {Object} record\n */\n updateStyles: function (record) {\n !record.lastInRow || this.masonry().updateStyles();\n },\n\n /**\n * Returns url to given record.\n *\n * @param {Object} record - Data to be preprocessed.\n * @returns {String}\n */\n getUrl: function (record) {\n return record[this.fields.url];\n },\n\n /**\n * Returns id to given record.\n *\n * @param {Object} record - Data to be preprocessed.\n * @returns {Number}\n */\n getId: function (record) {\n return record[this.fields.id];\n },\n\n /**\n * Returns container styles to given record.\n *\n * @param {Object} record - Data to be preprocessed.\n * @returns {Object}\n */\n getStyles: function (record) {\n var styles = record.styles();\n\n styles['margin-bottom'] = this.previewRowId() === record.rowNumber ? this.previewHeight : 0;\n record.styles(styles);\n\n return record.styles;\n },\n\n /**\n * Returns class list to given record.\n *\n * @param {Object} record - Data to be preprocessed.\n * @returns {Object}\n */\n getClasses: function (record) {\n return record.css || {};\n },\n\n /**\n * Get is active record\n *\n * @param {Object} record - Data to be preprocessed.\n *\n * @returns {Boolean}\n */\n getIsActive: function (record) {\n return this.previewComponent().visibleRecord() === record._rowIndex || false;\n },\n\n /**\n * Expand image preview\n */\n expandPreview: function (record) {\n this.previewComponent().show(record);\n }\n });\n});\n","Magento_Ui/js/grid/columns/link.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n './column',\n 'mageUtils'\n], function (Column, utils) {\n 'use strict';\n\n return Column.extend({\n defaults: {\n link: 'link',\n bodyTmpl: 'ui/grid/cells/link'\n },\n\n /**\n * Returns link to given record.\n *\n * @param {Object} record - Data to be preprocessed.\n * @returns {String}\n */\n getLink: function (record) {\n return utils.nested(record, this.link);\n },\n\n /**\n * Check if link parameter exist in record.\n * @param {Object} record - Data to be preprocessed.\n * @returns {Boolean}\n */\n isLink: function (record) {\n return !!utils.nested(record, this.link);\n }\n });\n});\n","Magento_Ui/js/grid/columns/onoff.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 'mage/translate',\n './multiselect',\n 'uiRegistry'\n], function (_, $t, Column, registry) {\n 'use strict';\n\n return Column.extend({\n defaults: {\n headerTmpl: 'ui/grid/columns/onoff',\n bodyTmpl: 'ui/grid/cells/onoff',\n fieldClass: {\n 'admin__scope-old': true,\n 'data-grid-onoff-cell': true,\n 'data-grid-checkbox-cell': false\n },\n imports: {\n selectedData: '${ $.provider }:data.selectedData'\n },\n listens: {\n '${ $.provider }:reloaded': 'setDefaultSelections'\n }\n },\n\n /**\n * @param {Number} id\n * @returns {*}\n */\n getLabel: function (id) {\n return this.selected.indexOf(id) !== -1 ? $t('On') : $t('Off');\n },\n\n /**\n * Sets the ids for preselected elements\n * @returns void\n */\n setDefaultSelections: function () {\n var positionCacheValid = registry.get('position_cache_valid'),\n selectedFromCache = registry.get('selected_cache'),\n key,\n i;\n\n if (positionCacheValid && this.selected().length === 0) {\n // Check selected data\n selectedFromCache = JSON.parse(selectedFromCache);\n\n for (i = 0; i < selectedFromCache.length; i++) {\n this.selected.push(selectedFromCache[i]);\n }\n\n registry.set('position_cache_valid', true);\n registry.set('selected_cache', JSON.stringify(this.selected()));\n\n return;\n }\n\n if (positionCacheValid && this.selected().length > 0) {\n registry.set('position_cache_valid', true);\n registry.set('selected_cache', JSON.stringify(this.selected()));\n\n return;\n }\n\n if (this.selectedData.length === 0) {\n registry.set('position_cache_valid', true);\n registry.set('selected_cache', JSON.stringify([]));\n\n return;\n }\n\n // Check selected data\n for (key in this.selectedData) {\n if (this.selectedData.hasOwnProperty(key) && this.selected().indexOf(key) === -1) {\n this.selected.push(key);\n }\n }\n // Uncheck unselected data\n for (i = 0; i < this.selected().length; i++) {\n key = this.selected()[i];\n this.selectedData.hasOwnProperty(key) || this.selected.splice(this.selected().indexOf(key), 1);\n this.selectedData.hasOwnProperty(key) || i--;\n }\n registry.set('position_cache_valid', true);\n registry.set('selected_cache', JSON.stringify(this.selected()));\n },\n\n /**\n * Show/hide action in the massaction menu\n * @param {Number} actionId\n * @returns {Boolean}\n */\n isActionRelevant: function (actionId) {\n var relevant = true;\n\n switch (actionId) {\n case 'selectPage':\n relevant = !this.isPageSelected(true);\n break;\n\n case 'deselectPage':\n relevant = this.isPageSelected();\n break;\n }\n\n return relevant;\n },\n\n /**\n * Updates values of the 'allSelected'\n * and 'indetermine' properties.\n *\n * @returns {Object} Chainable.\n */\n updateState: function () {\n var positionCacheValid = registry.get('position_cache_valid'),\n totalRecords = this.totalRecords(),\n selected = this.selected().length,\n excluded = this.excluded().length,\n totalSelected = this.totalSelected(),\n allSelected;\n\n if (positionCacheValid && this.selected().length > 0) {\n registry.set('position_cache_valid', true);\n registry.set('selected_cache', JSON.stringify(this.selected()));\n }\n\n // When filters are enabled then totalRecords is unknown\n if (this.getFiltering()) {\n if (this.getFiltering().search !== '') {\n totalRecords = -1;\n }\n }\n\n allSelected = totalRecords && totalSelected === totalRecords;\n\n if (this.excludeMode()) {\n if (excluded === totalRecords) {\n this.deselectAll();\n }\n } else if (totalRecords && selected === totalRecords) {\n this.selectAll();\n }\n\n this.allSelected(allSelected);\n this.indetermine(totalSelected && !allSelected);\n\n return this;\n }\n });\n});\n","Magento_Ui/js/grid/columns/overlay.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n 'Magento_Ui/js/grid/columns/column'\n], function (Column) {\n 'use strict';\n\n return Column.extend({\n defaults: {\n bodyTmpl: 'ui/grid/columns/overlay'\n },\n\n /**\n * If overlay should be visible\n *\n * @param {Object} row\n * @returns {Boolean}\n */\n isVisible: function (row) {\n return !!row[this.index];\n },\n\n /**\n * Get overlay label\n *\n * @param {Object} row\n * @returns {String}\n */\n getLabel: function (row) {\n return row[this.index];\n }\n });\n});\n","Magento_Ui/js/grid/columns/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 './column'\n], function (_, Column) {\n 'use strict';\n\n return Column.extend({\n /**\n * Retrieves label associated with a provided value.\n *\n * @returns {String}\n */\n getLabel: function () {\n var options = this.options || [],\n values = this._super(),\n label = [];\n\n if (_.isString(values)) {\n values = values.split(',');\n }\n\n if (!_.isArray(values)) {\n values = [values];\n }\n\n values = values.map(function (value) {\n return value + '';\n });\n\n options = this.flatOptions(options);\n\n options.forEach(function (item) {\n if (_.contains(values, item.value + '')) {\n label.push(item.label);\n }\n });\n\n return label.join(', ');\n },\n\n /**\n * Transformation tree options structure to liner array.\n *\n * @param {Array} options\n * @returns {Array}\n */\n flatOptions: function (options) {\n var self = this;\n\n if (!_.isArray(options)) {\n options = _.values(options);\n }\n\n return options.reduce(function (opts, option) {\n if (_.isArray(option.value)) {\n opts = opts.concat(self.flatOptions(option.value));\n } else {\n opts.push(option);\n }\n\n return opts;\n }, []);\n }\n });\n});\n","Magento_Ui/js/grid/columns/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 'mage/translate',\n './column'\n], function (_, $t, Column) {\n 'use strict';\n\n return Column.extend({\n defaults: {\n headerTmpl: 'ui/grid/columns/multiselect',\n bodyTmpl: 'ui/grid/cells/multiselect',\n controlVisibility: false,\n sortable: false,\n draggable: false,\n menuVisible: false,\n excludeMode: false,\n allSelected: false,\n indetermine: false,\n preserveSelectionsOnFilter: false,\n disabled: [],\n selected: [],\n excluded: [],\n fieldClass: {\n 'data-grid-checkbox-cell': true\n },\n actions: [{\n value: 'selectAll',\n label: $t('Select All')\n }, {\n value: 'deselectAll',\n label: $t('Deselect All')\n }, {\n value: 'selectPage',\n label: $t('Select All on This Page')\n }, {\n value: 'deselectPage',\n label: $t('Deselect All on This Page')\n }],\n\n imports: {\n totalRecords: '${ $.provider }:data.totalRecords',\n showTotalRecords: '${ $.provider }:data.showTotalRecords',\n rows: '${ $.provider }:data.items'\n },\n\n listens: {\n '${ $.provider }:params.filters': 'onFilter',\n '${ $.provider }:params.search': 'onSearch',\n selected: 'onSelectedChange',\n rows: 'onRowsChange'\n },\n\n modules: {\n source: '${ $.provider }'\n }\n },\n\n /**\n * Initializes observable properties.\n *\n * @returns {Multiselect} Chainable.\n */\n initObservable: function () {\n this._super()\n .observe([\n 'disabled',\n 'selected',\n 'excluded',\n 'excludeMode',\n 'totalSelected',\n 'allSelected',\n 'indetermine',\n 'totalRecords',\n 'showTotalRecords',\n 'rows'\n ]);\n\n return this;\n },\n\n /**\n * Selects specified record.\n *\n * @param {*} id - See definition of 'getId' method.\n * @param {Boolean} [isIndex=false] - See definition of 'getId' method.\n * @returns {Multiselect} Chainable.\n */\n select: function (id, isIndex) {\n this._setSelection(id, isIndex, true);\n\n return this;\n },\n\n /**\n * Deselects specified record.\n *\n * @param {*} id - See definition of 'getId' method.\n * @param {Boolean} [isIndex=false] - See definition of 'getId' method.\n * @returns {Multiselect} Chainable.\n */\n deselect: function (id, isIndex) {\n this._setSelection(id, isIndex, false);\n\n return this;\n },\n\n /**\n * Toggles selection of a specified record.\n *\n * @param {*} id - See definition of 'getId' method.\n * @param {Boolean} [isIndex=false] - See definition of 'getId' method.\n * @returns {Multiselect} Chainable.\n */\n toggleSelect: function (id, isIndex) {\n this._setSelection(id, isIndex, !this.isSelected(id, isIndex));\n\n return this;\n },\n\n /**\n * Checks if specified record is selected.\n *\n * @param {*} id - See definition of 'getId' method.\n * @param {Boolean} [isIndex=false] - See definition of 'getId' method.\n * @returns {Boolean}\n */\n isSelected: function (id, isIndex) {\n id = this.getId(id, isIndex);\n\n return this.selected.contains(id);\n },\n\n /**\n * Selects/deselects specified record base on a 'select' parameter value.\n *\n * @param {*} id - See definition of 'getId' method.\n * @param {Boolean} [isIndex=false] - See definition of 'getId' method.\n * @param {Boolean} select - Whether to select/deselect record.\n * @returns {Multiselect} Chainable.\n */\n _setSelection: function (id, isIndex, select) {\n var selected = this.selected;\n\n id = this.getId(id, isIndex);\n\n if (!select && this.isSelected(id)) {\n selected.remove(id);\n } else if (select) {\n selected.push(id);\n }\n\n return this;\n },\n\n /**\n * Selects all records, even those that\n * are not visible on the page.\n *\n * @returns {Multiselect} Chainable.\n */\n selectAll: function () {\n this.excludeMode(true);\n\n this.clearExcluded()\n .selectPage();\n\n return this;\n },\n\n /**\n * Deselects all records.\n *\n * @returns {Multiselect} Chainable.\n */\n deselectAll: function () {\n this.excludeMode(false);\n\n this.clearExcluded();\n this.selected.removeAll();\n\n return this;\n },\n\n /**\n * Selects or deselects all records.\n *\n * @returns {Multiselect} Chainable.\n */\n toggleSelectAll: function () {\n this.allSelected() ?\n this.deselectAll() :\n this.selectAll();\n\n return this;\n },\n\n /**\n * Selects all records on the current page.\n *\n * @returns {Multiselect} Chainable.\n */\n selectPage: function () {\n var selected = _.union(this.selected(), this.getIds());\n\n selected = _.difference(selected, this.disabled());\n\n this.selected(selected);\n\n return this;\n },\n\n /**\n * Deselects all records on the current page.\n *\n * @returns {Multiselect} Chainable.\n */\n deselectPage: function () {\n var pageIds = this.getIds();\n\n this.selected.remove(function (value) {\n return !!~pageIds.indexOf(value);\n });\n\n return this;\n },\n\n /**\n * Selects or deselects all records on the current page.\n *\n * @returns {Multiselect} Chainable.\n */\n togglePage: function () {\n return this.isPageSelected() && !this.excluded().length ? this.deselectPage() : this.selectPage();\n },\n\n /**\n * Clears the array of not selected records.\n *\n * @returns {Multiselect} Chainable.\n */\n clearExcluded: function () {\n this.excluded.removeAll();\n\n return this;\n },\n\n /**\n * Retrieve all id's from available records.\n *\n * @param {Boolean} [exclude] - Whether to exclude not selected ids' from result.\n * @returns {Array} An array of ids'.\n */\n getIds: function (exclude) {\n var items = this.rows(),\n ids = _.pluck(items, this.indexField);\n\n return exclude ?\n _.difference(ids, this.excluded()) :\n ids;\n },\n\n /**\n * Returns identifier of a record.\n *\n * @param {*} id - Id of a record or its' index in a rows array.\n * @param {Boolean} [isIndex=false] - Flag that specifies with what\n * kind of identifier we are dealing with.\n * @returns {*}\n */\n getId: function (id, isIndex) {\n var record = this.rows()[id];\n\n if (isIndex && record) {\n id = record[this.indexField];\n }\n\n return id;\n },\n\n /**\n * Recalculates list of the excluded records.\n * Changes value of `excluded`.\n *\n * @param {Array} selected - List of the currently selected records.\n * @returns {Multiselect} Chainable.\n */\n updateExcluded: function (selected) {\n var excluded = this.excluded(),\n fromPage = _.difference(this.getIds(), selected);\n\n excluded = _.union(excluded, fromPage);\n excluded = _.difference(excluded, selected);\n\n this.excluded(excluded);\n\n return this;\n },\n\n /**\n * Calculates number of selected records and\n * updates 'totalSelected' property.\n *\n * @returns {Multiselect} Chainable.\n */\n countSelected: function () {\n var total = this.totalRecords(),\n excluded = this.excluded().length,\n selected = this.selected().length;\n\n if (this.excludeMode()) {\n selected = total - excluded;\n }\n\n this.totalSelected(selected);\n\n return this;\n },\n\n /**\n * Returns selected items on a current page.\n *\n * @returns {Array}\n */\n getPageSelections: function () {\n var ids = this.getIds();\n\n return this.selected.filter(function (id) {\n return _.contains(ids, id);\n });\n },\n\n /**\n * Returns selections data.\n *\n * @returns {Object}\n */\n getSelections: function () {\n return {\n excluded: this.excluded(),\n selected: this.selected(),\n total: this.totalSelected(),\n showTotalRecords: this.showTotalRecords(),\n excludeMode: this.excludeMode(),\n params: this.getFiltering()\n };\n },\n\n /**\n * Extracts filtering data from data provider.\n *\n * @returns {Object} Current filters state.\n */\n getFiltering: function () {\n var source = this.source(),\n keys = ['filters', 'search', 'namespace'];\n\n if (!source) {\n return {};\n }\n\n return _.pick(source.get('params'), keys);\n },\n\n /**\n * Defines if provided select/deselect actions is relevant.\n * E.g. there is no need in a 'select page' action if only one\n * page is available.\n *\n * @param {String} actionId - Id of the action to be checked.\n * @returns {Boolean}\n */\n isActionRelevant: function (actionId) {\n var pageIds = this.getIds().length,\n multiplePages = pageIds < this.totalRecords(),\n relevant = true;\n\n switch (actionId) {\n case 'selectPage':\n relevant = multiplePages && !this.isPageSelected(true);\n break;\n\n case 'deselectPage':\n relevant = multiplePages && this.isPageSelected();\n break;\n\n case 'selectAll':\n relevant = !this.allSelected();\n break;\n\n case 'deselectAll':\n relevant = this.totalSelected() > 0;\n }\n\n return relevant;\n },\n\n /**\n * Checks if current page has selected records.\n *\n * @param {Boolean} [all=false] - If set to 'true' checks that every\n * record on the page is selected. Otherwise checks that\n * page has some selected records.\n * @returns {Boolean}\n */\n isPageSelected: function (all) {\n var pageIds = this.getIds(),\n selected = this.selected(),\n excluded = this.excluded(),\n iterator = all ? 'every' : 'some';\n\n if (this.allSelected()) {\n return true;\n }\n\n if (this.excludeMode()) {\n return pageIds[iterator](function (id) {\n return !~excluded.indexOf(id);\n });\n }\n\n return pageIds[iterator](function (id) {\n return !!~selected.indexOf(id);\n });\n },\n\n /**\n * Updates values of the 'allSelected'\n * and 'indetermine' properties.\n *\n * @returns {Multiselect} Chainable.\n */\n updateState: function () {\n var selected = this.selected().length,\n excluded = this.excluded().length,\n totalSelected = this.totalSelected(),\n totalRecords = this.totalRecords(),\n allSelected = totalRecords && totalSelected === totalRecords;\n\n if (this.excludeMode()) {\n if (excluded === totalRecords && !this.preserveSelectionsOnFilter) {\n this.deselectAll();\n }\n } else if (totalRecords && selected === totalRecords && !this.preserveSelectionsOnFilter) {\n this.selectAll();\n }\n\n this.allSelected(allSelected);\n this.indetermine(totalSelected && !allSelected);\n\n return this;\n },\n\n /**\n * Overrides base method, because this component\n * can't have global field action.\n *\n * @returns {Boolean} False.\n */\n hasFieldAction: function () {\n return false;\n },\n\n /**\n * Callback method to handle changes of selected items.\n *\n * @param {Array} selected - An array of currently selected items.\n */\n onSelectedChange: function (selected) {\n this.updateExcluded(selected)\n .countSelected()\n .updateState();\n },\n\n /**\n * Is invoked when rows has changed. Recalculates selected items\n * based on \"selectMode\" property.\n */\n onRowsChange: function () {\n var newSelections;\n\n if (this.excludeMode()) {\n newSelections = _.union(this.getIds(true), this.selected());\n\n this.selected(newSelections);\n }\n },\n\n /**\n * Is invoked when filtration is applied or removed\n */\n onFilter: function () {\n if (!this.preserveSelectionsOnFilter) {\n this.deselectAll();\n }\n },\n\n /**\n * Is invoked when search is applied or removed\n */\n onSearch: function () {\n this.onFilter();\n }\n });\n});\n","Magento_Ui/js/grid/columns/expandable.js":"/**\n * Copyright \u00a9 2016 Magento. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n './column',\n 'underscore'\n], function (Column, _) {\n 'use strict';\n\n return Column.extend({\n defaults: {\n bodyTmpl: 'ui/grid/cells/expandable',\n tooltipTmpl: 'ui/grid/cells/expandable/content',\n visibeItemsLimit: 5,\n tooltipTitle: ''\n },\n\n /**\n * Gets label from full options array.\n *\n * @param {Object} record - Record object.\n * @returns {String}\n */\n getFullLabel: function (record) {\n return this.getLabelsArray(record).join(', ');\n },\n\n /**\n * Gets label from options array limited by 'visibeItemsLimit'.\n *\n * @param {Object} record - Record object.\n * @returns {String}\n */\n getShortLabel: function (record) {\n return this.getLabelsArray(record).slice(0, this.visibeItemsLimit).join(', ');\n },\n\n /**\n * Extracts array of labels associated with provided values and sort it alphabetically.\n *\n * @param {Object} record - Record object.\n * @returns {Array}\n */\n getLabelsArray: function (record) {\n var values = this.getLabel(record),\n options = this.options || [],\n labels = [];\n\n if (_.isString(values)) {\n values = values.split(',');\n }\n\n if (!Array.isArray(values)) {\n values = [values];\n }\n\n values = values.map(function (value) {\n return value + '';\n });\n\n options = this.flatOptions(options);\n\n options.forEach(function (item) {\n if (_.contains(values, item.value + '')) {\n labels.push(item.label);\n }\n });\n\n return labels.sort(\n function (labelFirst, labelSecond) {\n return labelFirst.toLowerCase().localeCompare(labelSecond.toLowerCase());\n }\n );\n },\n\n /**\n * Transformation tree options structure to liner array.\n *\n * @param {Array} options\n * @returns {Array}\n */\n flatOptions: function (options) {\n var self = this;\n\n return options.reduce(function (opts, option) {\n if (_.isArray(option.value)) {\n opts = opts.concat(self.flatOptions(option.value));\n } else {\n opts.push(option);\n }\n\n return opts;\n }, []);\n },\n\n /**\n * Checks if amount of options is more than limit value.\n *\n * @param {Object} record - Data to be preprocessed.\n * @returns {Boolean}\n */\n isExpandable: function (record) {\n return this.getLabel(record).length > this.visibeItemsLimit;\n }\n });\n});\n","Magento_Ui/js/grid/columns/image-preview.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n/* eslint-disable no-undef */\ndefine([\n 'jquery',\n 'underscore',\n 'Magento_Ui/js/grid/columns/column',\n 'Magento_Ui/js/lib/key-codes'\n], function ($, _, Column, keyCodes) {\n 'use strict';\n\n return Column.extend({\n defaults: {\n bodyTmpl: 'ui/grid/columns/image-preview',\n previewImageSelector: '[data-image-preview]',\n visibleRecord: null,\n height: 0,\n displayedRecord: {},\n lastOpenedImage: false,\n fields: {\n previewUrl: 'preview_url',\n title: 'title'\n },\n modules: {\n masonry: '${ $.parentName }',\n thumbnailComponent: '${ $.parentName }.thumbnail_url'\n },\n statefull: {\n sorting: true,\n lastOpenedImage: true\n },\n listens: {\n '${ $.provider }:params.filters': 'hide',\n '${ $.provider }:params.search': 'hide',\n '${ $.provider }:params.paging': 'hide',\n '${ $.provider }:data.items': 'updateDisplayedRecord'\n },\n exports: {\n height: '${ $.parentName }.thumbnail_url:previewHeight'\n }\n },\n\n /**\n * Initialize image preview component\n *\n * @returns {Object}\n */\n initialize: function () {\n this._super();\n $(document).on('keydown', this.handleKeyDown.bind(this));\n\n this.lastOpenedImage.subscribe(function (newValue) {\n\n if (newValue === false && _.isNull(this.visibleRecord())) {\n return;\n }\n\n if (newValue === this.visibleRecord()) {\n return;\n }\n\n if (newValue === false) {\n this.hide();\n\n return;\n }\n\n this.show(this.masonry().rows()[newValue]);\n }.bind(this));\n\n return this;\n },\n\n /**\n * Init observable variables\n * @return {Object}\n */\n initObservable: function () {\n this._super()\n .observe([\n 'visibleRecord',\n 'height',\n 'displayedRecord',\n 'lastOpenedImage'\n ]);\n\n return this;\n },\n\n /**\n * Next image preview\n *\n * @param {Object} record\n */\n next: function (record) {\n var recordToShow;\n\n if (record._rowIndex + 1 === this.masonry().rows().length) {\n return;\n }\n\n recordToShow = this.getRecord(record._rowIndex + 1);\n recordToShow.rowNumber = record.lastInRow ? record.rowNumber + 1 : record.rowNumber;\n this.show(recordToShow);\n },\n\n /**\n * Previous image preview\n *\n * @param {Object} record\n */\n prev: function (record) {\n var recordToShow;\n\n if (record._rowIndex === 0) {\n return;\n }\n recordToShow = this.getRecord(record._rowIndex - 1);\n\n recordToShow.rowNumber = record.firstInRow ? record.rowNumber - 1 : record.rowNumber;\n this.show(recordToShow);\n },\n\n /**\n * Get record\n *\n * @param {Integer} recordIndex\n *\n * @return {Object}\n */\n getRecord: function (recordIndex) {\n return this.masonry().rows()[recordIndex];\n },\n\n /**\n * Set selected row id\n *\n * @param {Number} rowId\n * @private\n */\n _selectRow: function (rowId) {\n this.thumbnailComponent().previewRowId(rowId);\n },\n\n /**\n * Show image preview\n *\n * @param {Object} record\n */\n show: function (record) {\n if (record._rowIndex === this.visibleRecord()) {\n this.hide();\n\n return;\n }\n\n this.hide();\n this.displayedRecord(record);\n this._selectRow(record.rowNumber || null);\n this.visibleRecord(record._rowIndex);\n\n this.lastOpenedImage(record._rowIndex);\n this.updateImageData();\n },\n\n /**\n * Update image data when image preview is opened\n */\n updateImageData: function () {\n var img = $(this.previewImageSelector + ' img'), self;\n\n if (!img.get(0)) {\n setTimeout(function () {\n this.updateImageData();\n }.bind(this), 100);\n } else if (img.get(0).complete) {\n this.updateHeight();\n this.scrollToPreview();\n } else {\n self = this;\n\n img.on('load', function () {\n self.updateHeight();\n self.scrollToPreview();\n });\n }\n },\n\n /**\n * Update preview displayed record data from the new items data if the preview is expanded\n *\n * @param {Array} items\n */\n updateDisplayedRecord: function (items) {\n if (!_.isNull(this.visibleRecord())) {\n this.displayedRecord(items[this.visibleRecord()]);\n }\n },\n\n /**\n * Update image preview section height\n */\n updateHeight: function () {\n this.height($(this.previewImageSelector).height() + 'px');\n },\n\n /**\n * Close image preview\n */\n hide: function () {\n this.lastOpenedImage(false);\n this.visibleRecord(null);\n this.height(0);\n this._selectRow(null);\n },\n\n /**\n * Returns visibility for given record.\n *\n * @param {Object} record\n * @return {*|bool}\n */\n isVisible: function (record) {\n if (this.lastOpenedImage() === record._rowIndex &&\n this.visibleRecord() === null\n ) {\n this.show(record);\n }\n\n return this.visibleRecord() === record._rowIndex || false;\n },\n\n /**\n * Returns preview image url for a given record.\n *\n * @param {Object} record\n * @return {String}\n */\n getUrl: function (record) {\n return record[this.fields.previewUrl];\n },\n\n /**\n * Returns image title for a given record.\n *\n * @param {Object} record\n * @return {String}\n */\n getTitle: function (record) {\n return record[this.fields.title];\n },\n\n /**\n * Get styles for preview\n *\n * @returns {Object}\n */\n getStyles: function () {\n return {\n 'margin-top': '-' + this.height()\n };\n },\n\n /**\n * Scroll to preview window\n */\n scrollToPreview: function () {\n $(this.previewImageSelector).get(0).scrollIntoView({\n behavior: 'smooth',\n block: 'center',\n inline: 'nearest'\n });\n },\n\n /**\n * Handle keyboard navigation for image preview\n *\n * @param {Object} e\n */\n handleKeyDown: function (e) {\n var key = keyCodes[e.keyCode];\n\n if (this.visibleRecord() !== null && document.activeElement.tagName !== 'INPUT') {\n if (key === 'pageLeftKey') {\n this.prev(this.displayedRecord());\n } else if (key === 'pageRightKey') {\n this.next(this.displayedRecord());\n }\n }\n }\n });\n});\n","Magento_Ui/js/grid/cells/sanitizedHtml.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'Magento_Ui/js/grid/columns/column',\n 'escaper'\n], function (Column, escaper) {\n 'use strict';\n\n return Column.extend({\n defaults: {\n allowedTags: ['div', 'span', 'b', 'strong', 'i', 'em', 'u', 'a']\n },\n\n /**\n * Name column.\n *\n * @param {String} label\n * @returns {String}\n */\n getSafeHtml: function (label) {\n return escaper.escapeHtml(label, this.allowedTags);\n },\n\n /**\n * UnsanitizedHtml version of getSafeHtml.\n *\n * @param {String} label\n * @returns {String}\n */\n getSafeUnsanitizedHtml: function (label) {\n return this.getSafeHtml(label);\n }\n });\n});\n","Magento_Ui/js/grid/controls/columns.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 'mage/translate',\n 'uiCollection'\n], function (_, utils, $t, Collection) {\n 'use strict';\n\n return Collection.extend({\n defaults: {\n template: 'ui/grid/controls/columns',\n minVisible: 1,\n maxVisible: 30,\n viewportSize: 18,\n displayArea: 'dataGridActions',\n columnsProvider: 'ns = ${ $.ns }, componentType = columns',\n imports: {\n addColumns: '${ $.columnsProvider }:elems'\n },\n templates: {\n headerMsg: $t('${ $.visible } out of ${ $.total } visible')\n }\n },\n\n /**\n * Resets columns visibility to theirs default state.\n *\n * @returns {Columns} Chainable.\n */\n reset: function () {\n this.elems.each('applyState', 'default', 'visible');\n\n return this;\n },\n\n /**\n * Applies last saved state of columns visibility.\n *\n * @returns {Columns} Chainable.\n */\n cancel: function () {\n this.elems.each('applyState', '', 'visible');\n\n return this;\n },\n\n /**\n * Adds columns whose visibility can be controlled to the component.\n *\n * @param {Array} columns - Elements array that will be added to component.\n * @returns {Columns} Chainable.\n */\n addColumns: function (columns) {\n columns = _.where(columns, {\n controlVisibility: true\n });\n\n this.insertChild(columns);\n\n return this;\n },\n\n /**\n * Defines whether child elements array length\n * is greater than the 'viewportSize' property.\n *\n * @returns {Boolean}\n */\n hasOverflow: function () {\n return this.elems().length > this.viewportSize;\n },\n\n /**\n * Helper, checks\n * - if less than one item choosen\n * - if more then viewportMaxSize choosen\n *\n * @param {Object} elem\n * @returns {Boolean}\n */\n isDisabled: function (elem) {\n var visible = this.countVisible();\n\n return elem.visible ?\n visible === this.minVisible :\n visible === this.maxVisible;\n },\n\n /**\n * Counts number of visible columns.\n *\n * @returns {Number}\n */\n countVisible: function () {\n return this.elems.filter('visible').length;\n },\n\n /**\n * Compile header message from headerMessage setting.\n *\n * @returns {String}\n */\n getHeaderMessage: function () {\n return utils.template(this.templates.headerMsg, {\n visible: this.countVisible(),\n total: this.elems().length\n });\n }\n });\n});\n","Magento_Ui/js/grid/controls/button/split.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 return function (data, element) {\n\n $(element).on('click.splitDefault', '.action-default', function () {\n $(this).siblings('.dropdown-menu').find('.item-default').trigger('click');\n });\n };\n});\n","Magento_Ui/js/grid/controls/bookmarks/storage.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 'mageUtils',\n 'Magento_Ui/js/lib/core/storage/local',\n 'uiClass'\n], function ($, utils, storage, Class) {\n 'use strict';\n\n /**\n * Removes ns prefix for path.\n *\n * @param {String} ns\n * @param {String} path\n * @returns {String}\n */\n function removeNs(ns, path) {\n return path.replace(ns + '.', '');\n }\n\n return Class.extend({\n defaults: {\n ajaxSettings: {\n method: 'POST',\n data: {\n namespace: '${ $.namespace }'\n }\n }\n },\n\n /**\n * Delegates call to the localStorage adapter.\n */\n get: function () {\n return {};\n },\n\n /**\n * Sends request to store specified data.\n *\n * @param {String} path - Path by which data should be stored.\n * @param {*} value - Value to be sent.\n */\n set: function (path, value) {\n var property = removeNs(this.namespace, path),\n data = {},\n config;\n\n utils.nested(data, property, value);\n\n config = utils.extend({\n url: this.saveUrl,\n data: {\n data: JSON.stringify(data)\n }\n }, this.ajaxSettings);\n\n $.ajax(config);\n },\n\n /**\n * Sends request to remove specified data.\n *\n * @param {String} path - Path to the property to be removed.\n */\n remove: function (path) {\n var property = removeNs(this.namespace, path),\n config;\n\n config = utils.extend({\n url: this.deleteUrl,\n data: {\n data: property\n }\n }, this.ajaxSettings);\n\n $.ajax(config);\n }\n });\n});\n","Magento_Ui/js/grid/controls/bookmarks/bookmarks.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 'mage/translate',\n 'rjsResolver',\n 'uiLayout',\n 'uiCollection'\n], function (_, utils, $t, resolver, layout, Collection) {\n 'use strict';\n\n /**\n * Removes 'current' namespace from a 'path' string.\n *\n * @param {String} path\n * @returns {String} Path without namespace.\n */\n function removeStateNs(path) {\n path = typeof path == 'string' ? path.split('.') : [];\n\n if (path[0] === 'current') {\n path.shift();\n }\n\n return path.join('.');\n }\n\n return Collection.extend({\n defaults: {\n template: 'ui/grid/controls/bookmarks/bookmarks',\n viewTmpl: 'ui/grid/controls/bookmarks/view',\n newViewLabel: $t('New View'),\n defaultIndex: 'default',\n activeIndex: 'default',\n viewsArray: [],\n storageConfig: {\n provider: '${ $.storageConfig.name }',\n name: '${ $.name }_storage',\n component: 'Magento_Ui/js/grid/controls/bookmarks/storage'\n },\n views: {\n default: {\n label: $t('Default View'),\n index: 'default',\n editable: false\n }\n },\n tracks: {\n editing: true,\n viewsArray: true,\n activeView: true,\n hasChanges: true,\n customLabel: true,\n customVisible: true\n },\n listens: {\n activeIndex: 'onActiveIndexChange',\n activeView: 'checkState',\n current: 'onStateChange'\n }\n },\n\n /**\n * Initializes bookmarks component.\n *\n * @returns {Bookmarks} Chainable.\n */\n initialize: function () {\n utils.limit(this, 'checkState', 5);\n utils.limit(this, 'saveState', 2000);\n\n this._super()\n .restore()\n .initStorage()\n .initViews();\n\n return this;\n },\n\n /**\n * Creates custom storage instance.\n *\n * @returns {Bookmarks} Chainable.\n */\n initStorage: function () {\n layout([this.storageConfig]);\n\n return this;\n },\n\n /**\n * Defines default data if it wasn't gathered previously.\n *\n * @private\n * @returns {Bookmarks} Chainbale.\n */\n initDefaultView: function () {\n var data = this.getViewData(this.defaultIndex);\n\n if (!_.size(data) && (this.current.columns && this.current.positions)) {\n this.setViewData(this.defaultIndex, this.current)\n .saveView(this.defaultIndex);\n this.defaultDefined = true;\n }\n\n return this;\n },\n\n /**\n * Creates instances of a previously saved views.\n *\n * @returns {Bookmarks} Chainable.\n */\n initViews: function () {\n _.each(this.views, function (config) {\n this.addView(config);\n }, this);\n\n this.activeView = this.getActiveView();\n\n return this;\n },\n\n /**\n * Creates complete configuration for a view.\n *\n * @param {Object} [config] - Additional configuration object.\n * @returns {Object}\n */\n buildView: function (config) {\n var view = {\n label: this.newViewLabel,\n index: '_' + Date.now(),\n editable: true\n };\n\n utils.extend(view, config || {});\n\n view.data = view.data || utils.copy(this.current);\n view.value = view.label;\n\n this.observe.call(view, true, 'label value');\n\n return view;\n },\n\n /**\n * Creates instance of a view with a provided configuration.\n *\n * @param {Object} [config] - View configuration.\n * @param {Boolean} [saveView=false] - Whether to save created view automatically or not.\n * @param {Boolean} [applyView=false] - Whether to apply created view automatically or not.\n * @returns {View} Created view.\n */\n addView: function (config, saveView, applyView) {\n var view = this.buildView(config),\n index = view.index;\n\n this.views[index] = view;\n\n if (saveView) {\n this.saveView(index);\n }\n\n if (applyView) {\n this.applyView(index);\n }\n\n this.updateArray();\n\n return view;\n },\n\n /**\n * Removes specified view.\n *\n * @param {String} index - Index of a view to be removed.\n * @returns {Bookmarks} Chainable.\n */\n removeView: function (index) {\n var viewPath = this.getViewPath(index);\n\n if (this.isViewActive(index)) {\n this.applyView(this.defaultIndex);\n }\n\n this.endEdit(index)\n .remove(viewPath)\n .removeStored(viewPath)\n .updateArray();\n\n return this;\n },\n\n /**\n * Saves data of a specified view.\n *\n * @param {String} index - Index of a view to be saved.\n * @returns {Bookmarks} Chainable.\n */\n saveView: function (index) {\n var viewPath = this.getViewPath(index);\n\n this.updateViewLabel(index)\n .endEdit(index)\n .store(viewPath)\n .checkState();\n\n return this;\n },\n\n /**\n * Sets specified view as active\n * and applies its' state.\n *\n * @param {String} index - Index of a view to be applied.\n * @returns {Bookmarks} Chainable.\n */\n applyView: function (index) {\n this.applyStateOf(index)\n .set('activeIndex', index);\n\n return this;\n },\n\n /**\n * Updates data of a specified view if it's\n * currently active and saves its' data.\n *\n * @param {String} index - Index of a view.\n * @returns {Bookmarks} Chainable.\n */\n updateAndSave: function (index) {\n if (this.isViewActive(index)) {\n this.updateActiveView(index);\n }\n\n this.saveView(index);\n\n return this;\n },\n\n /**\n * Returns instance of a specified view.\n *\n * @param {String} index - Index of a view to be retrieved.\n * @returns {View}\n */\n getView: function (index) {\n return this.views[index];\n },\n\n /**\n * Returns instance of an active view.\n *\n * @returns {View}\n */\n getActiveView: function () {\n return this.views[this.activeIndex];\n },\n\n /**\n * Checks if specified view is active.\n *\n * @param {String} index - Index of a view to be checked.\n * @returns {Boolean}\n */\n isViewActive: function (index) {\n return this.activeView === this.getView(index);\n },\n\n /**\n * Sets current state as a data of an active view.\n *\n * @returns {Bookmarks} Chainable.\n */\n updateActiveView: function () {\n this.setViewData(this.activeIndex, this.current);\n\n return this;\n },\n\n /**\n * Replaces label a view with a provided one.\n * If new label is not specified, then views'\n * 'value' property will be taken.\n *\n * @param {String} index - Index of a view.\n * @param {String} [label=view.value] - New labels' value.\n * @returns {Bookmarks} Chainable.\n */\n updateViewLabel: function (index, label) {\n var view = this.getView(index),\n current = view.label;\n\n label = (label || view.value).trim() || current;\n label = this.uniqueLabel(label, current);\n\n view.label = view.value = label;\n\n return this;\n },\n\n /**\n * Retrieves data of a specified view.\n *\n * @param {String} index - Index of a view whose data should be retrieved.\n * @param {String} [property] - If not specified then whole views' data will be retrieved.\n * @returns {Object} Views' data.\n */\n getViewData: function (index, property) {\n var view = this.getView(index),\n data = view.data;\n\n if (property) {\n data = utils.nested(data, property);\n }\n\n return utils.copy(data);\n },\n\n /**\n * Sets data to the specified view.\n *\n * @param {String} index - Index of a view whose data will be replaced.\n * @param {Object} data - New view data.\n * @returns {Bookmarks} Chainable.\n */\n setViewData: function (index, data) {\n var path = this.getViewPath(index) + '.data';\n\n this.set(path, utils.copy(data));\n\n return this;\n },\n\n /**\n * Starts editing of a specified view.\n *\n * @param {String} index - Index of a view.\n * @returns {Bookmarks} Chainable.\n */\n editView: function (index) {\n this.editing = index;\n\n return this;\n },\n\n /**\n * Ends editing of specified view\n * and restores its' label.\n *\n * @param {String} index - Index of a view.\n * @returns {Bookmarks} Chainable.\n */\n endEdit: function (index) {\n var view;\n\n if (!this.isEditing(index)) {\n return this;\n }\n\n index = index || this.editing;\n view = this.getView(index);\n\n view.value = view.label;\n\n this.editing = false;\n\n return this;\n },\n\n /**\n * Checks if specified view is in editing state.\n *\n * @param {String} index - Index of a view to be checked.\n * @returns {Boolean}\n */\n isEditing: function (index) {\n return this.editing === index;\n },\n\n /**\n * Generates label unique among present views, based\n * on the incoming label pattern.\n *\n * @param {String} [label=this.newViewLabel] - Label pattern.\n * @param {String} [exclude]\n * @returns {String}\n */\n uniqueLabel: function (label, exclude) {\n var labels = _.pluck(this.views, 'label'),\n hasParenth = _.last(label) === ')',\n index = 2,\n result,\n suffix;\n\n labels = _.without(labels, exclude);\n result = label = label || this.newViewLabel;\n\n for (index = 2; _.contains(labels, result); index++) {\n suffix = '(' + index + ')';\n\n if (!hasParenth) {\n suffix = ' ' + suffix;\n }\n\n result = label + suffix;\n }\n\n return result;\n },\n\n /**\n * Applies state of a specified view, without\n * making it active.\n *\n * @param {String} [state=this.activeIndex]\n * @param {String} [property]\n * @returns {Bookmarks} Chainable.\n */\n applyStateOf: function (state, property) {\n var index = state || this.activeIndex,\n dataPath = removeStateNs(property),\n viewData = this.getViewData(index, dataPath);\n\n dataPath = dataPath ?\n 'current.' + dataPath :\n 'current';\n\n this.set(dataPath, viewData);\n\n return this;\n },\n\n /**\n * Saves current state.\n *\n * @returns {Bookmarks} Chainable.\n */\n saveState: function () {\n this.store('current');\n return this;\n },\n\n /**\n * Applies state of an active view.\n *\n * @returns {Bookmarks} Chainable.\n */\n resetState: function () {\n this.applyStateOf(this.activeIndex);\n\n return this;\n },\n\n /**\n * Checks if current state is different\n * from the state of an active view.\n *\n * @returns {Bookmarks} Chainable.\n */\n checkState: function () {\n var viewData = this.getViewData(this.activeIndex),\n diff = utils.compare(viewData, this.current);\n\n this.hasChanges = !diff.equal;\n\n return this;\n },\n\n /**\n * Returns path to the view instance,\n * based on a provided index.\n *\n * @param {String} index - Index of a view.\n * @returns {String}\n */\n getViewPath: function (index) {\n return 'views.' + index;\n },\n\n /**\n * Updates the array of views.\n *\n * @returns {Bookmarks} Chainable\n */\n updateArray: function () {\n this.viewsArray = _.values(this.views);\n\n return this;\n },\n\n /**\n * Shows custom view field and creates unique label for it.\n *\n * @returns {Bookmarks} Chainable.\n */\n showCustom: function () {\n this.customLabel = this.uniqueLabel();\n this.customVisible = true;\n\n return this;\n },\n\n /**\n * Hides custom view field.\n *\n * @returns {Bookmarks} Chainable.\n */\n hideCustom: function () {\n this.customVisible = false;\n\n return this;\n },\n\n /**\n * Checks if custom view field is visible.\n *\n * @returns {Boolean}\n */\n isCustomVisible: function () {\n return this.customVisible;\n },\n\n /**\n * Creates new view instance with a label specified\n * in a custom view field.\n *\n * @returns {Bookmarks} Chainable.\n */\n applyCustom: function () {\n var label = this.customLabel.trim();\n\n this.hideCustom()\n .addView({\n label: this.uniqueLabel(label)\n }, true, true);\n\n return this;\n },\n\n /**\n * Listener of the activeIndex property.\n */\n onActiveIndexChange: function () {\n this.activeView = this.getActiveView();\n this.updateActiveView();\n this.store('activeIndex');\n },\n\n /**\n * Listener of the activeIndex property.\n */\n onStateChange: function () {\n this.checkState();\n this.saveState();\n\n if (!this.defaultDefined) {\n resolver(this.initDefaultView, this);\n }\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/timeline/timeline-view.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 'Magento_Ui/js/lib/view/utils/async',\n 'underscore',\n 'Magento_Ui/js/lib/view/utils/raf',\n 'uiRegistry',\n 'uiClass'\n], function (ko, $, _, raf, registry, Class) {\n 'use strict';\n\n var hasClassList = (function () {\n var list = document.createElement('_').classList;\n\n return !!list && !list.toggle('_test', false);\n })();\n\n /**\n * Polyfill of the 'classList.toggle' method.\n *\n * @param {HTMLElement} elem\n */\n function toggleClass(elem) {\n var classList = elem.classList,\n args = Array.prototype.slice.call(arguments, 1),\n $elem;\n\n if (hasClassList) {\n classList.toggle.apply(classList, args);\n } else {\n $elem = $(elem);\n $elem.toggleClass.apply($elem, args);\n }\n }\n\n return Class.extend({\n defaults: {\n selectors: {\n content: '.timeline-content',\n timeUnit: '.timeline-unit',\n item: '.timeline-item:not([data-role=no-data-msg])',\n event: '.timeline-event'\n }\n },\n\n /**\n * Initializes TimelineView component.\n *\n * @returns {TimelineView} Chainable.\n */\n initialize: function () {\n _.bindAll(\n this,\n 'refresh',\n 'initContent',\n 'initItem',\n 'initTimeUnit',\n 'getItemBindings',\n 'updateItemsPosition',\n 'onScaleChange',\n 'onEventElementRender',\n 'onWindowResize',\n 'onContentScroll',\n 'onDataReloaded',\n 'onToStartClick',\n 'onToEndClick'\n );\n\n this._super()\n .initModel()\n .waitContent();\n\n return this;\n },\n\n /**\n * Applies listeners for the model properties changes.\n *\n * @returns {TimelineView} Chainable.\n */\n initModel: function () {\n var model = registry.get(this.model);\n\n model.on('scale', this.onScaleChange);\n model.source.on('reloaded', this.onDataReloaded);\n\n this.model = model;\n\n return this;\n },\n\n /**\n * Applies DOM watcher for the\n * content element rendering.\n *\n * @returns {TimelineView} Chainable.\n */\n waitContent: function () {\n $.async({\n selector: this.selectors.content,\n component: this.model\n }, this.initContent);\n\n return this;\n },\n\n /**\n * Initializes timelines' content element.\n *\n * @param {HTMLElement} content\n * @returns {TimelineView} Chainable.\n */\n initContent: function (content) {\n this.$content = content;\n\n $(content).on('scroll', this.onContentScroll);\n $(window).on('resize', this.onWindowResize);\n\n $.async(this.selectors.item, content, this.initItem);\n $.async(this.selectors.event, content, this.onEventElementRender);\n $.async(this.selectors.timeUnit, content, this.initTimeUnit);\n\n this.refresh();\n\n return this;\n },\n\n /**\n * Initializes timeline item element,\n * e.g. establishes event listeners and applies data bindings.\n *\n * @param {HTMLElement} elem\n * @returns {TimelineView} Chainable.\n */\n initItem: function (elem) {\n $(elem)\n .bindings(this.getItemBindings)\n .on('click', '._toend', this.onToEndClick)\n .on('click', '._tostart', this.onToStartClick);\n\n return this;\n },\n\n /**\n * Initializes timeline unit element.\n *\n * @param {HTMLElement} elem\n * @returns {TimelineView} Chainable.\n */\n initTimeUnit: function (elem) {\n $(elem).bindings(this.getTimeUnitBindings());\n\n return this;\n },\n\n /**\n * Updates items positions in a\n * loop if state of a view has changed.\n */\n refresh: function () {\n raf(this.refresh);\n\n if (this._update) {\n this._update = false;\n\n this.updateItemsPosition();\n }\n },\n\n /**\n * Returns object width additional bindings\n * for a timeline unit element.\n *\n * @returns {Object}\n */\n getTimeUnitBindings: function () {\n return {\n style: {\n width: ko.computed(function () {\n return this.getTimeUnitWidth() + '%';\n }.bind(this))\n }\n };\n },\n\n /**\n * Returns object with additional\n * bindings for a timeline item element.\n *\n * @param {Object} ctx\n * @returns {Object}\n */\n getItemBindings: function (ctx) {\n return {\n style: {\n width: ko.computed(function () {\n return this.getItemWidth(ctx.$row()) + '%';\n }.bind(this)),\n\n 'margin-left': ko.computed(function () {\n return this.getItemMargin(ctx.$row()) + '%';\n }.bind(this))\n }\n };\n },\n\n /**\n * Calculates width in percents of a timeline unit element.\n *\n * @returns {Number}\n */\n getTimeUnitWidth: function () {\n return 100 / this.model.scale;\n },\n\n /**\n * Calculates width of a record in percents.\n *\n * @param {Object} record\n * @returns {String}\n */\n getItemWidth: function (record) {\n var days = 0;\n\n if (record) {\n days = this.model.getDaysLength(record);\n }\n\n return this.getTimeUnitWidth() * days;\n },\n\n /**\n * Calculates left margin value for provided record.\n *\n * @param {Object} record\n * @returns {String}\n */\n getItemMargin: function (record) {\n var offset = 0;\n\n if (record) {\n offset = this.model.getStartDelta(record);\n }\n\n return this.getTimeUnitWidth() * offset;\n },\n\n /**\n * Returns collection of currently available\n * timeline item elements.\n *\n * @returns {Array<HTMLElement>}\n */\n getItems: function () {\n var items = this.$content.querySelectorAll(this.selectors.item);\n\n return _.toArray(items);\n },\n\n /**\n * Updates positions of timeline elements.\n *\n * @returns {TimelineView} Chainable.\n */\n updateItemsPosition: function () {\n this.getItems()\n .forEach(this.updatePositionFor, this);\n\n return this;\n },\n\n /**\n * Updates position of provided timeline element.\n *\n * @param {HTMLElement} $elem\n * @returns {TimelineView} Chainable.\n */\n updatePositionFor: function ($elem) {\n var $event = $elem.querySelector(this.selectors.event),\n leftEdge = this.getLeftEdgeFor($elem),\n rightEdge = this.getRightEdgeFor($elem);\n\n if ($event) {\n $event.style.left = Math.max(-leftEdge, 0) + 'px';\n $event.style.right = Math.max(rightEdge, 0) + 'px';\n }\n\n toggleClass($elem, '_scroll-start', leftEdge < 0);\n toggleClass($elem, '_scroll-end', rightEdge > 0);\n\n return this;\n },\n\n /**\n * Scrolls content area to the start of provided element.\n *\n * @param {HTMLElement} elem\n * @returns {TimelineView}\n */\n toStartOf: function (elem) {\n var leftEdge = this.getLeftEdgeFor(elem);\n\n this.$content.scrollLeft += leftEdge;\n\n return this;\n },\n\n /**\n * Scrolls content area to the end of provided element.\n *\n * @param {HTMLElement} elem\n * @returns {TimelineView}\n */\n toEndOf: function (elem) {\n var rightEdge = this.getRightEdgeFor(elem);\n\n this.$content.scrollLeft += rightEdge + 1;\n\n return this;\n },\n\n /**\n * Calculates location of the left edge of an element\n * relative to the contents' left edge.\n *\n * @param {HTMLElement} elem\n * @returns {Number}\n */\n getLeftEdgeFor: function (elem) {\n var leftOffset = elem.getBoundingClientRect().left;\n\n return leftOffset - this.$content.getBoundingClientRect().left;\n },\n\n /**\n * Calculates location of the right edge of an element\n * relative to the contents' right edge.\n *\n * @param {HTMLElement} elem\n * @returns {Number}\n */\n getRightEdgeFor: function (elem) {\n var elemWidth = elem.offsetWidth,\n leftEdge = this.getLeftEdgeFor(elem);\n\n return leftEdge + elemWidth - this.$content.offsetWidth;\n },\n\n /**\n * 'To Start' button 'click' event handler.\n *\n * @param {jQueryEvent} event\n */\n onToStartClick: function (event) {\n var elem = event.originalEvent.currentTarget;\n\n event.stopPropagation();\n\n this.toStartOf(elem);\n },\n\n /**\n * 'To End' button 'click' event handler.\n *\n * @param {jQueryEvent} event\n */\n onToEndClick: function (event) {\n var elem = event.originalEvent.currentTarget;\n\n event.stopPropagation();\n\n this.toEndOf(elem);\n },\n\n /**\n * Handler of the scale value 'change' event.\n */\n onScaleChange: function () {\n this._update = true;\n },\n\n /**\n * Callback function which is invoked\n * when event element was rendered.\n */\n onEventElementRender: function () {\n this._update = true;\n },\n\n /**\n * Window 'resize' event handler.\n */\n onWindowResize: function () {\n this._update = true;\n },\n\n /**\n * Content container 'scroll' event handler.\n */\n onContentScroll: function () {\n this._update = true;\n },\n\n /**\n * Data 'reload' event handler.\n */\n onDataReloaded: function () {\n this._update = true;\n }\n });\n});\n","Magento_Ui/js/timeline/timeline.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 'moment',\n 'uiLayout',\n 'Magento_Ui/js/grid/listing'\n], function (_, moment, layout, Listing) {\n 'use strict';\n\n var ONE_DAY = 86400000;\n\n return Listing.extend({\n defaults: {\n recordTmpl: 'ui/timeline/record',\n dateFormat: 'YYYY-MM-DD HH:mm:ss',\n headerFormat: 'ddd MM/DD',\n detailsFormat: 'DD/MM/YYYY HH:mm:ss',\n scale: 7,\n scaleStep: 1,\n minScale: 7,\n maxScale: 28,\n minDays: 28,\n displayMode: 'timeline',\n displayModes: {\n timeline: {\n label: 'Timeline',\n value: 'timeline',\n template: 'ui/timeline/timeline'\n }\n },\n viewConfig: {\n component: 'Magento_Ui/js/timeline/timeline-view',\n name: '${ $.name }_view',\n model: '${ $.name }'\n },\n tracks: {\n scale: true\n },\n statefull: {\n scale: true\n },\n range: {}\n },\n\n /**\n * Initializes Timeline component.\n *\n * @returns {Timeline} Chainable.\n */\n initialize: function () {\n this._super()\n .initView()\n .updateRange();\n\n return this;\n },\n\n /**\n * Initializes components configuration.\n *\n * @returns {Timeline} Chainable.\n */\n initConfig: function () {\n this._super();\n\n this.maxScale = Math.min(this.minDays, this.maxScale);\n this.minScale = Math.min(this.maxScale, this.minScale);\n\n return this;\n },\n\n /**\n * Initializes observable properties.\n *\n * @returns {Timeline} Chainable.\n */\n initObservable: function () {\n this._super()\n .observe.call(this.range, true, 'hasToday');\n\n return this;\n },\n\n /**\n * Initializes TimelineView component.\n *\n * @returns {Timeline} Chainable.\n */\n initView: function () {\n layout([this.viewConfig]);\n\n return this;\n },\n\n /**\n * Checks if provided event record is active,\n * i.e. it has already started.\n *\n * @param {Object} record\n * @returns {Boolean}\n */\n isActive: function (record) {\n return Number(record.status) === 1;\n },\n\n /**\n * Checks if provided event record is upcoming,\n * i.e. it will start later on.\n *\n * @param {Object} record\n * @returns {Boolean}\n */\n isUpcoming: function (record) {\n return Number(record.status) === 2;\n },\n\n /**\n * Checks if provided event record is permanent,\n * i.e. it has no ending time.\n *\n * @param {Object} record\n * @returns {Boolean}\n */\n isPermanent: function (record) {\n return !this.getEndDate(record);\n },\n\n /**\n * Checks if provided date indicates current day.\n *\n * @param {(Number|Moment)} date\n * @returns {Boolenan}\n */\n isToday: function (date) {\n return moment().isSame(date, 'day');\n },\n\n /**\n * Checks if range object contains todays date.\n *\n * @returns {Boolean}\n */\n hasToday: function () {\n return this.range.hasToday;\n },\n\n /**\n * Returns start date of provided record.\n *\n * @param {Object} record\n * @returns {String}\n */\n getStartDate: function (record) {\n return record['start_time'];\n },\n\n /**\n * Returns end date of provided record.\n *\n * @param {Object} record\n * @returns {String}\n */\n getEndDate: function (record) {\n return record['end_time'];\n },\n\n /**\n * Returns difference in days between records' start date\n * and a first day of a range.\n *\n * @param {Object} record\n * @returns {Number}\n */\n getStartDelta: function (record) {\n var start = this.createDate(this.getStartDate(record)),\n firstDay = this.range.firstDay;\n\n return start.diff(firstDay, 'days', true);\n },\n\n /**\n * Calculates the amount of days that provided event lasts.\n *\n * @param {Object} record\n * @returns {Number}\n */\n getDaysLength: function (record) {\n var start = this.createDate(this.getStartDate(record)),\n end = this.createDate(this.getEndDate(record));\n\n if (!end.isValid()) {\n end = this.range.lastDay.endOf('day');\n }\n\n return end.diff(start, 'days', true);\n },\n\n /**\n * Creates new date object based on provided date string value.\n *\n * @param {String} dateStr\n * @returns {Moment}\n */\n createDate: function (dateStr) {\n return moment(dateStr, this.dateFormat);\n },\n\n /**\n * Converts days to weeks.\n *\n * @param {Number} days\n * @returns {Number}\n */\n daysToWeeks: function (days) {\n var weeks = days / 7;\n\n if (weeks % 1) {\n weeks = weeks.toFixed(1);\n }\n\n return weeks;\n },\n\n /**\n * Updates data of a range object,\n * e.g. total days, first day and last day, etc.\n *\n * @returns {Object} Range instance.\n */\n updateRange: function () {\n var firstDay = this._getFirstDay(),\n lastDay = this._getLastDay(),\n totalDays = lastDay.diff(firstDay, 'days'),\n days = [],\n i = -1;\n\n if (totalDays < this.minDays) {\n totalDays += this.minDays - totalDays - 1;\n }\n\n while (++i <= totalDays) {\n days.push(+firstDay + ONE_DAY * i);\n }\n\n return _.extend(this.range, {\n days: days,\n totalDays: totalDays,\n firstDay: firstDay,\n lastDay: moment(_.last(days)),\n hasToday: this.isToday(firstDay)\n });\n },\n\n /**\n *\n * @private\n * @param {String} key\n * @returns {Array<Moment>}\n */\n _getDates: function (key) {\n var dates = [];\n\n this.rows.forEach(function (record) {\n if (record[key]) {\n dates.push(this.createDate(record[key]));\n }\n }, this);\n\n return dates;\n },\n\n /**\n * Returns date which is closest to the current day.\n *\n * @private\n * @returns {Moment}\n */\n _getFirstDay: function () {\n var dates = this._getDates('start_time'),\n first = moment.min(dates).subtract(1, 'day'),\n today = moment();\n\n if (!first.isValid() || first < today) {\n first = today;\n }\n\n return first.startOf('day');\n },\n\n /**\n * Returns the most distant date\n * specified in available records.\n *\n * @private\n * @returns {Moment}\n */\n _getLastDay: function () {\n var startDates = this._getDates('start_time'),\n endDates = this._getDates('end_time'),\n last = moment.max(startDates.concat(endDates));\n\n return last.add(1, 'day').startOf('day');\n },\n\n /**\n * TODO: remove after integration with date binding.\n *\n * @param {Number} timestamp\n * @returns {String}\n */\n formatHeader: function (timestamp) {\n return moment(timestamp).format(this.headerFormat);\n },\n\n /**\n * TODO: remove after integration with date binding.\n *\n * @param {String} date\n * @returns {String}\n */\n formatDetails: function (date) {\n return moment(date).format(this.detailsFormat);\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/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/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/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.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/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/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/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/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/insert.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 'jquery',\n 'mage/translate',\n 'mageUtils',\n 'underscore',\n 'Magento_Ui/js/modal/alert',\n 'Magento_Ui/js/lib/view/utils/bindings',\n 'Magento_Ui/js/lib/view/utils/async'\n], function (Element, $, $t, utils, _, alert) {\n 'use strict';\n\n return Element.extend({\n defaults: {\n content: '',\n template: 'ui/form/insert',\n showSpinner: true,\n loading: false,\n autoRender: true,\n visible: true,\n contentSelector: '${$.name}',\n externalData: [],\n params: {\n namespace: '${ $.ns }'\n },\n renderSettings: {\n url: '${ $.render_url }',\n dataType: 'html'\n },\n updateSettings: {\n url: '${ $.update_url }',\n dataType: 'json'\n },\n imports: {},\n exports: {},\n listens: {},\n links: {\n value: '${ $.provider }:${ $.dataScope}'\n },\n modules: {\n externalSource: '${ $.externalProvider }'\n }\n },\n\n /** @inheritdoc */\n initialize: function () {\n this._super();\n _.bindAll(this, 'onRender', 'onUpdate');\n\n if (this.autoRender) {\n this.render();\n }\n\n return this;\n },\n\n /** @inheritdoc */\n initObservable: function () {\n return this._super()\n .observe([\n 'visible',\n 'content',\n 'value',\n 'loading'\n ]);\n },\n\n /** @inheritdoc */\n initConfig: function (config) {\n this.initDataLink(config)._super();\n this.contentSelector = this.contentSelector.replace(/\\./g, '_');\n\n return this;\n },\n\n /**\n * Sync data with external provider.\n *\n * @param {Object} config\n * @returns {Object}\n */\n initDataLink: function (config) {\n var key, value;\n\n if (config.dataLinks) {\n _.each(config.externalData, function (val) {\n value = val;\n key = 'externalValue.' + val.replace('data.', '');\n\n if (config.dataLinks.imports) {\n this.imports[key] = '${ $.externalProvider }:' + value;\n }\n\n if (config.dataLinks.exports) {\n this.exports[key] = '${ $.externalProvider }:' + value;\n }\n this.links[key] = '${ $.externalProvider }:' + value;\n }, this.constructor.defaults);\n }\n\n if (config.realTimeLink) {\n this.constructor.defaults.links.externalValue = 'value';\n }\n\n return this;\n },\n\n /**\n * Request for render content.\n *\n * @returns {Object}\n */\n render: function (params) {\n var self = this,\n request;\n\n if (this.isRendered) {\n return this;\n }\n\n self.previousParams = params || {};\n\n $.async({\n component: this.name,\n ctx: '.' + this.contentSelector\n }, function (el) {\n self.contentEl = $(el);\n self.startRender = true;\n params = _.extend({}, self.params, params || {});\n request = self.requestData(params, self.renderSettings);\n request\n .done(self.onRender)\n .fail(self.onError);\n });\n\n return this;\n },\n\n /** @inheritdoc */\n destroy: function () {\n this.destroyInserted()\n ._super();\n },\n\n /**\n * Destroy inserted components.\n *\n * @returns {Object}\n */\n destroyInserted: function () {\n if (this.isRendered) {\n this.isRendered = false;\n this.content('');\n\n if (this.externalSource()) {\n this.externalSource().destroy();\n }\n this.initExternalLinks();\n }\n\n return this;\n },\n\n /**\n * Initialize links on external components.\n *\n * @returns {Object}\n */\n initExternalLinks: function () {\n var imports = this.filterExternalLinks(this.imports, this.ns),\n exports = this.filterExternalLinks(this.exports, this.ns),\n links = this.filterExternalLinks(this.links, this.ns);\n\n this.setLinks(links, 'imports')\n .setLinks(links, 'exports');\n\n _.each({\n exports: exports,\n imports: imports\n }, this.setLinks, this);\n\n return this;\n },\n\n /**\n * Filter external links.\n *\n * @param {Object} data\n * @param {String }ns\n * @returns {Object}\n */\n filterExternalLinks: function (data, ns) {\n var links = {};\n\n _.each(data, function (value, key) {\n if (typeof value === 'string' && value.split('.')[0] === ns) {\n links[key] = value;\n }\n });\n\n return links;\n },\n\n /**\n * Request with configurable params and settings.\n *\n * @param {Object} params\n * @param {Object} ajaxSettings\n * @returns {Object}\n */\n requestData: function (params, ajaxSettings) {\n var query = utils.copy(params);\n\n ajaxSettings = _.extend({\n url: this['update_url'],\n method: 'GET',\n data: query,\n dataType: 'json'\n }, ajaxSettings);\n\n this.loading(true);\n\n return $.ajax(ajaxSettings);\n },\n\n /**\n * Callback that render content.\n *\n * @param {*} data\n */\n onRender: function (data) {\n var resp;\n\n this.loading(false);\n\n try {\n resp = JSON.parse(data);\n\n if (resp.ajaxExpired) {\n window.location.href = resp.ajaxRedirect;\n }\n } catch (e) {\n this.set('content', data);\n this.isRendered = true;\n this.startRender = false;\n }\n },\n\n /**\n * Error callback.\n *\n * @param {Object} xhr\n */\n onError: function (xhr) {\n if (xhr.statusText === 'abort') {\n return;\n }\n\n alert({\n content: $t('Something went wrong.')\n });\n },\n\n /**\n * Getter for external data.\n *\n * @returns {Object}\n */\n getExternalData: function () {\n var data = {};\n\n _.each(this.externalData, function (path) {\n utils.nested(data, path.replace('data.', ''), this.externalSource().get(path));\n }, this);\n\n return data;\n },\n\n /**\n * Request for update data.\n *\n * @returns {*|Object}\n */\n updateData: function (params) {\n var request;\n\n params = _.extend(params || {}, this.params);\n\n if (!this.startRender && !this.isRendered) {\n return this.render(params);\n }\n\n request = this.requestData(params, this.updateSettings);\n request\n .done(this.onUpdate)\n .fail(this.onError);\n\n return request;\n },\n\n /**\n * Set data to external provider, clear changes.\n *\n * @param {*} data\n */\n onUpdate: function (data) {\n this.externalSource().set('data', data);\n this.externalSource().trigger('data.overload');\n this.loading(false);\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/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/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/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/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/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/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-listing.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 './insert',\n 'mageUtils',\n 'underscore'\n], function ($, Insert, utils, _) {\n 'use strict';\n\n return Insert.extend({\n defaults: {\n externalListingName: '${ $.ns }.${ $.ns }',\n behaviourType: 'simple',\n externalFilterMode: false,\n requestConfig: {\n method: 'POST'\n },\n externalCondition: 'nin',\n settings: {\n edit: {\n imports: {\n 'onChangeRecord': '${ $.editorProvider }:changed'\n }\n },\n filter: {\n exports: {\n 'requestConfig': '${ $.externalProvider }:requestConfig'\n }\n }\n },\n imports: {\n onSelectedChange: '${ $.selectionsProvider }:selected',\n 'update_url': '${ $.externalProvider }:update_url',\n 'indexField': '${ $.selectionsProvider }:indexField'\n },\n exports: {\n externalFiltersModifier: '${ $.externalProvider }:params.filters_modifier'\n },\n listens: {\n externalValue: 'updateExternalFiltersModifier updateSelections',\n indexField: 'initialUpdateListing'\n },\n modules: {\n selections: '${ $.selectionsProvider }',\n externalListing: '${ $.externalListingName }'\n }\n },\n\n /**\n * Invokes initialize method of parent class,\n * contains initialization logic\n */\n initialize: function () {\n this._super();\n _.bindAll(this, 'updateValue', 'updateExternalValueByEditableData');\n\n return this;\n },\n\n /** @inheritdoc */\n initConfig: function (config) {\n var defaults = this.constructor.defaults;\n\n if (config.behaviourType === 'edit') {\n defaults.editableData = {};\n _.map(defaults.settings.edit.imports, function (value, key) {\n this.imports[key] = value;\n }, defaults);\n }\n\n if (config.externalFilterMode === true) {\n _.map(defaults.settings.filter.exports, function (value, key) {\n this.exports[key] = value;\n }, defaults);\n }\n\n return this._super();\n },\n\n /** @inheritdoc */\n initObservable: function () {\n return this._super()\n .observe([\n 'externalValue'\n ]);\n },\n\n /** @inheritdoc */\n destroyInserted: function () {\n if (this.isRendered && this.externalListing()) {\n this.externalListing().source.storage().clearRequests();\n this.externalListing().delegate('destroy');\n }\n\n return this._super();\n },\n\n /**\n * Store data from edited record\n *\n * @param {Object} record\n */\n onChangeRecord: function (record) {\n this.updateEditableData(record);\n\n if (!this.dataLinks.imports) {\n return;\n }\n\n this.updateExternalValueByEditableData();\n },\n\n /**\n * Updates externalValue every time row is selected,\n * if it is configured by 'dataLinks.imports'\n * Also suppress dataLinks so import/export of selections will not activate each other in circle\n *\n */\n onSelectedChange: function () {\n if (!this.dataLinks.imports ||\n this.suppressDataLinks ||\n _.isBoolean(this.initialExportDone) && !this.initialExportDone\n ) {\n this.suppressDataLinks = false;\n\n return;\n }\n\n this.suppressDataLinks = true;\n this.updateExternalValue();\n },\n\n /**\n * Stores data from editor in editableData\n * @param {Object} record\n *\n */\n updateEditableData: function (record) {\n var id = _.keys(record[0])[0];\n\n this.editableData[id] = record[0][id];\n },\n\n /**\n * Updates externalValue by data from editor (already stored in editableData)\n *\n */\n updateExternalValueByEditableData: function () {\n var updatedExtValue;\n\n if (!(this.behaviourType === 'edit') || _.isEmpty(this.editableData) || _.isEmpty(this.externalValue())) {\n return;\n }\n\n updatedExtValue = this.externalValue();\n updatedExtValue.map(function (item) {\n _.extend(item, this.editableData[item[this.indexField]]);\n }, this);\n this.setExternalValue(updatedExtValue);\n },\n\n /**\n * Updates externalValue, from selectionsProvider data (if it is enough)\n * or ajax request to server\n *\n * @returns {Object} result - deferred that will be resolved when value is updated\n */\n updateExternalValue: function () {\n var result = $.Deferred(),\n provider = this.selections(),\n selections,\n totalSelected,\n itemsType,\n rows;\n\n if (!provider) {\n return result;\n }\n\n selections = provider && provider.getSelections();\n totalSelected = provider.totalSelected();\n itemsType = selections && selections.excludeMode ? 'excluded' : 'selected';\n rows = provider && provider.rows();\n\n if (this.canUpdateFromClientData(totalSelected, selections.selected, rows)) {\n this.updateFromClientData(selections.selected, rows);\n this.updateExternalValueByEditableData();\n result.resolve();\n } else {\n this.updateFromServerData(selections, itemsType).done(function () {\n this.updateExternalValueByEditableData();\n result.resolve();\n }.bind(this));\n }\n\n return result;\n },\n\n /**\n * Check if the selected rows data can be taken from selectionsProvider data\n * (which only stores data of the current page rows)\n * + from already saved data\n *\n * @param {Boolean} totalSelected - total rows selected (include rows that were filtered out)\n * @param {Array} selected - ids of selected rows\n * @param {Object} rows\n */\n canUpdateFromClientData: function (totalSelected, selected, rows) {\n var alreadySavedSelectionsIds = _.pluck(this.externalValue(), this.indexField),\n rowsOnCurrentPageIds = _.pluck(rows, this.indexField);\n\n return totalSelected === selected.length &&\n _.intersection(_.union(alreadySavedSelectionsIds, rowsOnCurrentPageIds), selected).length ===\n selected.length;\n },\n\n /**\n * Updates externalValue, from selectionsProvider data\n * (which only stores data of the current page rows)\n * + from already saved data\n * so we can avoid request to server\n *\n * @param {Array} selected - ids of selected rows\n * @param {Object} rows\n */\n updateFromClientData: function (selected, rows) {\n var value,\n rowIds,\n valueIds;\n\n if (!selected || !selected.length) {\n this.setExternalValue([]);\n\n return;\n }\n\n value = this.externalValue();\n rowIds = _.pluck(rows, this.indexField);\n valueIds = _.pluck(value, this.indexField);\n\n value = _.map(selected, function (item) {\n if (_.contains(rowIds, item)) {\n return _.find(rows, function (row) {\n return row[this.indexField] === item;\n }, this);\n } else if (_.contains(valueIds, item)) {\n return _.find(value, function (row) {\n return row[this.indexField] === item;\n }, this);\n }\n }, this);\n\n this.setExternalValue(value);\n },\n\n /**\n * Updates externalValue, from ajax request to grab selected rows data\n *\n * @param {Object} selections\n * @param {String} itemsType\n *\n * @returns {Object} request - deferred that will be resolved when ajax is done\n */\n updateFromServerData: function (selections, itemsType) {\n var filterType = selections && selections.excludeMode ? 'nin' : 'in',\n selectionsData = {},\n request;\n\n _.extend(selectionsData, this.params || {}, selections.params);\n\n if (selections[itemsType] && selections[itemsType].length) {\n selectionsData.filters = {};\n selectionsData['filters_modifier'] = {};\n selectionsData['filters_modifier'][this.indexField] = {\n 'condition_type': filterType,\n value: selections[itemsType]\n };\n }\n\n selectionsData.paging = {\n notLimits: 1\n };\n\n request = this.requestData(selectionsData, {\n method: this.requestConfig.method\n });\n request\n .done(function (data) {\n this.setExternalValue(data.items || data);\n this.loading(false);\n }.bind(this))\n .fail(this.onError);\n\n return request;\n },\n\n /**\n * Set listing rows data to the externalValue,\n * or if externalData is configured with the names of particular columns,\n * filter rows data to have only these columns, and then set to the externalValue\n *\n * @param {Object} newValue - rows data\n *\n */\n setExternalValue: function (newValue) {\n var keys = this.externalData,\n value = this.externalValue(),\n selectedIds = _.pluck(newValue, this.indexField);\n\n if (_.isArray(keys) && !_.isEmpty(keys)) {\n newValue = _.map(newValue, function (item) {\n return _.pick(item, keys);\n }, this);\n } else if (keys && _.isString(keys) && !_.isEmpty(newValue)) {\n newValue = newValue[0][keys];\n }\n\n if (this.externalFilterMode) {\n newValue = _.union(newValue, _.filter(value,\n function (item) {\n return !_.contains(selectedIds, item[this.indexField]);\n }, this));\n }\n\n this.set('externalValue', newValue);\n },\n\n /**\n * Updates external filter (if externalFilterMode is on)\n * every time, when value is updated,\n * so grid is re-filtered to exclude or include selected rows only\n *\n * @param {Object} items\n */\n updateExternalFiltersModifier: function (items) {\n var provider,\n filter = {};\n\n if (!this.externalFilterMode) {\n return;\n }\n\n provider = this.selections();\n\n if (!provider) {\n this.needInitialListingUpdate = true;\n\n return;\n }\n\n filter[this.indexField] = {\n 'condition_type': this.externalCondition,\n value: _.pluck(items, this.indexField)\n };\n this.set('externalFiltersModifier', filter);\n },\n\n /**\n * Updates grid selections\n * every time, when extenalValue is updated,\n * so grid is re-selected according to externalValue updated\n * Also suppress dataLinks so import/export of selections will not activate each other in circle\n *\n * @param {Object} items\n */\n updateSelections: function (items) {\n var provider,\n ids;\n\n if (!this.dataLinks.exports || this.suppressDataLinks) {\n this.suppressDataLinks = false;\n this.initialExportDone = true;\n\n return;\n }\n\n provider = this.selections();\n\n if (!provider) {\n this.needInitialListingUpdate = true;\n\n return;\n }\n\n this.suppressDataLinks = true;\n provider.deselectAll();\n\n if (_.isString(items)) {\n provider.selected([items] || []);\n } else {\n ids = _.pluck(items || [], this.indexField)\n .map(function (item) {\n return item.toString();\n });\n\n provider.selected(ids || []);\n }\n this.initialExportDone = true;\n },\n\n /**\n * initial update of the listing\n * with rows that must be checked/filtered\n * by the indexes\n */\n initialUpdateListing: function () {\n var items = this.externalValue();\n\n if (this.needInitialListingUpdate && items) {\n this.updateExternalFiltersModifier(items);\n this.updateSelections(items);\n this.needInitialListingUpdate = false;\n }\n },\n\n /**\n * Reload source\n */\n reload: function () {\n this.externalSource().set('params.t', new Date().getTime());\n },\n\n /**\n * Updates value from external value\n *\n */\n updateValue: function () {\n this.set('value', this.externalValue());\n },\n\n /**\n * Updates external value, then updates value from external value\n *\n */\n save: function () {\n this.updateExternalValue().done(\n function () {\n if (!this.realTimeLink) {\n this.updateValue();\n }\n }.bind(this)\n );\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/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/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/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/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/ui-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 './abstract',\n 'Magento_Ui/js/lib/key-codes',\n 'mage/translate',\n 'ko',\n 'jquery',\n 'Magento_Ui/js/lib/view/utils/async'\n], function (_, Abstract, keyCodes, $t, ko, $) {\n 'use strict';\n\n var isTouchDevice = typeof document.ontouchstart !== 'undefined';\n\n /**\n * Processing options list\n *\n * @param {Array} array - Property array\n * @param {String} separator - Level separator\n * @param {Array} created - list to add new options\n *\n * @return {Array} Plain options list\n */\n function flattenCollection(array, separator, created) {\n var i = 0,\n length,\n childCollection;\n\n array = _.compact(array);\n length = array.length;\n created = created || [];\n\n for (i; i < length; i++) {\n created.push(array[i]);\n\n if (array[i].hasOwnProperty(separator)) {\n childCollection = array[i][separator];\n delete array[i][separator];\n flattenCollection.call(this, childCollection, separator, created);\n }\n }\n\n return created;\n }\n\n /**\n * Set levels to options list\n *\n * @param {Array} array - Property array\n * @param {String} separator - Level separator\n * @param {Number} level - Starting level\n * @param {String} path - path to root\n *\n * @returns {Array} Array with levels\n */\n function setProperty(array, separator, level, path) {\n var i = 0,\n length,\n nextLevel,\n nextPath;\n\n array = _.compact(array);\n length = array.length;\n level = level || 0;\n path = path || '';\n\n for (i; i < length; i++) {\n if (array[i]) {\n _.extend(array[i], {\n level: level,\n path: path\n });\n }\n\n if (array[i].hasOwnProperty(separator)) {\n nextLevel = level + 1;\n nextPath = path ? path + '.' + array[i].label : array[i].label;\n setProperty.call(this, array[i][separator], separator, nextLevel, nextPath);\n }\n }\n\n return array;\n }\n\n /**\n * Preprocessing options list\n *\n * @param {Array} nodes - Options list\n *\n * @return {Object} Object with property - options(options list)\n * and cache options with plain and tree list\n */\n function parseOptions(nodes) {\n var caption,\n value,\n cacheNodes,\n copyNodes;\n\n nodes = setProperty(nodes, 'optgroup');\n copyNodes = JSON.parse(JSON.stringify(nodes));\n cacheNodes = flattenCollection(copyNodes, 'optgroup');\n\n nodes = _.map(nodes, function (node) {\n value = node.value;\n\n if (value == null || value === '') {\n if (_.isUndefined(caption)) {\n caption = node.label;\n }\n } else {\n return node;\n }\n });\n\n return {\n options: _.compact(nodes),\n cacheOptions: {\n plain: _.compact(cacheNodes),\n tree: _.compact(nodes)\n }\n };\n }\n\n return Abstract.extend({\n defaults: {\n options: [],\n total: 0,\n listVisible: false,\n value: [],\n filterOptions: false,\n chipsEnabled: true,\n itemsQuantity: '',\n filterInputValue: '',\n filterOptionsFocus: false,\n multiselectFocus: false,\n multiple: true,\n selectType: 'tree',\n lastSelectable: false,\n showFilteredQuantity: true,\n showCheckbox: true,\n levelsVisibility: true,\n openLevelsAction: true,\n showOpenLevelsActionIcon: true,\n optgroupLabels: false,\n closeBtn: true,\n showPath: true,\n labelsDecoration: false,\n disableLabel: false,\n filterRateLimit: 500,\n filterRateLimitMethod: 'notifyAtFixedRate',\n closeBtnLabel: $t('Done'),\n optgroupTmpl: 'ui/grid/filters/elements/ui-select-optgroup',\n quantityPlaceholder: $t('options'),\n hoverClass: '_hover',\n rootListSelector: 'ul.admin__action-multiselect-menu-inner._root',\n visibleOptionSelector: 'li.admin__action-multiselect-menu-inner-item:visible',\n actionTargetSelector: '.action-menu-item',\n selectedPlaceholders: {\n defaultPlaceholder: $t('Select...'),\n lotPlaceholders: $t('Selected')\n },\n separator: 'optgroup',\n searchOptions: false,\n loading: false,\n searchUrl: false,\n lastSearchKey: '',\n lastSearchPage: 1,\n filterPlaceholder: '',\n emptyOptionsHtml: '',\n cachedSearchResults: {},\n pageLimit: 50,\n deviation: 30,\n validationLoading: false,\n isRemoveSelectedIcon: false,\n debounce: 300,\n missingValuePlaceholder: $t('Entity with ID: %s doesn\\'t exist'),\n isDisplayMissingValuePlaceholder: false,\n currentSearchKey: '',\n listens: {\n listVisible: 'cleanHoveredElement',\n filterInputValue: 'filterOptionsList',\n options: 'checkOptionsList'\n },\n presets: {\n single: {\n showCheckbox: false,\n chipsEnabled: false,\n closeBtn: false\n },\n optgroup: {\n showCheckbox: false,\n lastSelectable: true,\n optgroupLabels: true,\n openLevelsAction: false,\n labelsDecoration: true,\n showOpenLevelsActionIcon: false\n }\n }\n },\n\n /**\n * Initializes UISelect component.\n *\n * @returns {UISelect} Chainable.\n */\n initialize: function () {\n this._super();\n\n $.async(\n this.rootListSelector,\n this,\n this.onRootListRender.bind(this)\n );\n\n return this;\n },\n\n /**\n * Parses options and merges the result with instance\n * Set defaults according to mode and levels configuration\n *\n * @param {Object} config\n * @returns {Object} Chainable.\n */\n initConfig: function (config) {\n var result = parseOptions(config.options),\n defaults = this.constructor.defaults,\n multiple = _.isBoolean(config.multiple) ? config.multiple : defaults.multiple,\n type = config.selectType || defaults.selectType,\n showOpenLevelsActionIcon = _.isBoolean(config.showOpenLevelsActionIcon) ?\n config.showOpenLevelsActionIcon :\n defaults.showOpenLevelsActionIcon,\n openLevelsAction = _.isBoolean(config.openLevelsAction) ?\n config.openLevelsAction :\n defaults.openLevelsAction;\n\n multiple = !multiple ? 'single' : false;\n config.showOpenLevelsActionIcon = showOpenLevelsActionIcon && openLevelsAction;\n _.extend(config, result, defaults.presets[multiple], defaults.presets[type]);\n this._super();\n\n return this;\n },\n\n /**\n * Check child optgroup\n */\n hasChildList: function () {\n return _.find(this.options(), function (option) {\n return !!option[this.separator];\n }, this);\n },\n\n /**\n * Check tree mode\n */\n isTree: function () {\n return this.hasChildList() && this.selectType !== 'optgroup';\n },\n\n /**\n * Add option to lastOptions array\n *\n * @param {Object} data\n * @returns {Boolean}\n */\n addLastElement: function (data) {\n if (!data.hasOwnProperty(this.separator)) {\n !this.cacheOptions.lastOptions ? this.cacheOptions.lastOptions = [] : false;\n\n if (!_.findWhere(\n this.cacheOptions.lastOptions,\n {\n value: data.value\n }\n )\n ) {\n this.cacheOptions.lastOptions.push(data);\n }\n\n return true;\n }\n\n return false;\n },\n\n /**\n * Return empty options html\n */\n getEmptyOptionsUnsanitizedHtml: function () {\n return this.emptyOptionsHtml;\n },\n\n /**\n * Check options length and set to cache\n * if some options is added\n *\n * @param {Array} options - ui select options\n */\n checkOptionsList: function (options) {\n if (options.length > this.cacheOptions.plain.length) {\n this.cacheOptions.plain = options;\n this.setCaption();\n }\n },\n\n /**\n * Check label decoration\n */\n isLabelDecoration: function (data) {\n return data.hasOwnProperty(this.separator) && this.labelsDecoration;\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 this.observe([\n 'listVisible',\n 'placeholder',\n 'multiselectFocus',\n 'options',\n 'itemsQuantity',\n 'filterInputValue',\n 'filterOptionsFocus',\n 'loading',\n 'validationLoading',\n 'isDisplayMissingValuePlaceholder'\n ]);\n\n this.filterInputValue.extend({\n rateLimit: {\n timeout: this.filterRateLimit,\n method: this.filterRateLimitMethod\n }\n });\n\n return this;\n },\n\n /**\n * object with key - keyname and value - handler function for this key\n *\n * @returns {Object} Object with handlers function name.\n */\n keyDownHandlers: function () {\n return {\n enterKey: this.enterKeyHandler,\n escapeKey: this.escapeKeyHandler,\n spaceKey: this.enterKeyHandler,\n pageUpKey: this.pageUpKeyHandler,\n pageDownKey: this.pageDownKeyHandler\n };\n },\n\n /**\n * Processing level visibility for levels\n *\n * @param {Object} data - element data\n *\n * @returns {Boolean} level visibility.\n */\n showLevels: function (data) {\n var curLevel = ++data.level,\n isVisible;\n\n if (data.visible) {\n isVisible = data.visible();\n } else {\n isVisible = !!data.hasOwnProperty(this.separator) &&\n _.isBoolean(this.levelsVisibility) &&\n this.levelsVisibility ||\n data.hasOwnProperty(this.separator) && parseInt(this.levelsVisibility, 10) >= curLevel;\n\n data.visible = ko.observable(isVisible);\n data.isVisited = isVisible;\n }\n\n return isVisible;\n },\n\n /**\n * Processing level visibility for levels\n *\n * @param {Object} data - element data\n *\n * @returns {Boolean} level visibility.\n */\n getLevelVisibility: function (data) {\n if (data.visible) {\n return data.visible();\n }\n\n return this.showLevels(data);\n },\n\n /**\n * Set option to options array.\n *\n * @param {Object} option\n * @param {Array} options\n */\n setOption: function (option, options) {\n var copyOptionsTree;\n\n options = options || this.cacheOptions.tree;\n\n _.each(options, function (opt) {\n if (opt.value == option.parent) { //eslint-disable-line eqeqeq\n delete option.parent;\n opt[this.separator] ? opt[this.separator].push(option) : opt[this.separator] = [option];\n copyOptionsTree = JSON.parse(JSON.stringify(this.cacheOptions.tree));\n this.cacheOptions.plain = flattenCollection(copyOptionsTree, this.separator);\n this.options(this.cacheOptions.tree);\n } else if (opt[this.separator]) {\n this.setOption(option, opt[this.separator]);\n }\n }, this);\n },\n\n /**\n * Handler outerClick event. Closed options list\n */\n outerClick: function () {\n this.listVisible() ? this.listVisible(false) : false;\n\n if (isTouchDevice) {\n this.multiselectFocus(false);\n }\n },\n\n /**\n * Handler keydown event to filter options input\n *\n * @returns {Boolean} Returned true for emersion events\n */\n filterOptionsKeydown: function (data, event) {\n var key = keyCodes[event.keyCode];\n\n !this.isTabKey(event) ? event.stopPropagation() : false;\n\n if (key === 'pageDownKey' || key === 'pageUpKey') {\n event.preventDefault();\n this.filterOptionsFocus(false);\n this.cacheUiSelect.focus();\n }\n\n this.keydownSwitcher(data, event);\n\n return true;\n },\n\n /**\n * Filtered options list by value from filter options list\n */\n filterOptionsList: function () {\n var value = this.filterInputValue().trim().toLowerCase(),\n array = [];\n\n if (this.searchOptions) {\n return this.loadOptions(value);\n }\n\n this.cleanHoveredElement();\n\n if (!value) {\n this.renderPath = false;\n this.options(this.cacheOptions.tree);\n this._setItemsQuantity(false);\n\n return false;\n }\n\n this.showPath ? this.renderPath = true : false;\n\n if (this.filterInputValue()) {\n\n array = this.selectType === 'optgroup' ?\n this._getFilteredArray(this.cacheOptions.lastOptions, value) :\n this._getFilteredArray(this.cacheOptions.plain, value);\n\n if (!value.length) {\n this.options(this.cacheOptions.plain);\n this._setItemsQuantity(this.cacheOptions.plain.length);\n } else {\n this.options(array);\n this._setItemsQuantity(array.length);\n }\n\n return false;\n }\n\n this.options(this.cacheOptions.plain);\n },\n\n /**\n * Filtered options list by value from filter options list\n *\n * @param {Array} list - option list\n * @param {String} value\n *\n * @returns {Array} filters result\n */\n _getFilteredArray: function (list, value) {\n var i = 0,\n array = [],\n curOption;\n\n for (i; i < list.length; i++) {\n curOption = list[i].label.toLowerCase();\n\n if (curOption.indexOf(value) > -1) {\n array.push(list[i]); /*eslint max-depth: [2, 4]*/\n }\n }\n\n return array;\n },\n\n /**\n * Get path to current option\n *\n * @param {Object} data - option data\n * @returns {String} path\n */\n getPath: function (data) {\n var pathParts,\n createdPath = '';\n\n if (this.renderPath) {\n pathParts = data.path.split('.');\n _.each(pathParts, function (curData) {\n createdPath = createdPath ? createdPath + ' / ' + curData : curData;\n });\n\n return createdPath;\n }\n },\n\n /**\n * Set filtered items quantity\n *\n * @param {Object} data - option data\n */\n _setItemsQuantity: function (data) {\n if (this.showFilteredQuantity) {\n data || parseInt(data, 10) === 0 ?\n this.itemsQuantity(this.getItemsPlaceholder(data)) :\n this.itemsQuantity('');\n }\n },\n\n /**\n * Return formatted items placeholder.\n *\n * @param {Object} data - option data\n * @returns {String}\n */\n getItemsPlaceholder: function (data) {\n return data + ' ' + this.quantityPlaceholder;\n },\n\n /**\n * Remove element from selected array\n */\n removeSelected: function (value, data, event) {\n event ? event.stopPropagation() : false;\n this.value.remove(value);\n },\n\n /**\n * Checked key name\n *\n * @returns {Boolean}\n */\n isTabKey: function (event) {\n return keyCodes[event.keyCode] === 'tabKey';\n },\n\n /**\n * Clean hoveredElement variable\n *\n * @returns {Object} Chainable\n */\n cleanHoveredElement: function () {\n if (this.hoveredElement) {\n $(this.hoveredElement)\n .children(this.actionTargetSelector)\n .removeClass(this.hoverClass);\n\n this.hoveredElement = null;\n }\n\n return this;\n },\n\n /**\n * Check selected option\n *\n * @param {String} value - option value\n * @return {Boolean}\n */\n isSelected: function (value) {\n return this.multiple ? _.contains(this.value(), value) : this.value() === value;\n },\n\n /**\n * Check selected option\n *\n * @param {Object} option - option value\n * @return {Boolean}\n */\n isSelectedValue: function (option) {\n if (_.isUndefined(option)) {\n return false;\n }\n\n return this.isSelected(option.value);\n },\n\n /**\n * Check optgroup label\n *\n * @param {Object} data - element data\n * @return {Boolean}\n */\n isOptgroupLabels: function (data) {\n return data.hasOwnProperty(this.separator) && this.optgroupLabels;\n },\n\n /**\n * Check hovered option\n *\n * @param {Object} data - element data\n * @return {Boolean}\n */\n isHovered: function (data) {\n var element = this.hoveredElement,\n elementData;\n\n if (!element) {\n return false;\n }\n\n elementData = ko.dataFor(this.hoveredElement);\n\n if (_.isUndefined(elementData)) {\n return false;\n }\n\n return data.value === elementData.value;\n },\n\n /**\n * Toggle list visibility\n *\n * @returns {Object} Chainable\n */\n toggleListVisible: function () {\n this.listVisible(!this.disabled() && !this.listVisible());\n\n return this;\n },\n\n /**\n * Get selected element labels\n *\n * @returns {Array} array labels\n */\n getSelected: function () {\n var selected = this.value();\n\n return this.cacheOptions.plain.filter(function (opt) {\n return _.isArray(selected) ?\n _.contains(selected, opt.value) :\n selected == opt.value;//eslint-disable-line eqeqeq\n });\n },\n\n /**\n * Toggle activity list element\n *\n * @param {Object} data - selected option data\n * @returns {Object} Chainable\n */\n toggleOptionSelected: function (data) {\n var isSelected = this.isSelected(data.value);\n\n if (this.lastSelectable && data.hasOwnProperty(this.separator)) {\n return this;\n }\n\n if (!this.multiple) {\n if (!isSelected) {\n this.value(data.value);\n }\n this.listVisible(false);\n } else {\n if (!isSelected) { /*eslint no-lonely-if: 0*/\n this.value.push(data.value);\n } else {\n this.value(_.without(this.value(), data.value));\n }\n }\n\n return this;\n },\n\n /**\n * Change visibility to child level\n *\n * @param {Object} data - element data\n */\n openChildLevel: function (data) {\n var contextElement = data,\n isVisible;\n\n if (\n this.openLevelsAction &&\n data.hasOwnProperty(this.separator) && _.isBoolean(this.levelsVisibility) ||\n this.openLevelsAction &&\n data.hasOwnProperty(this.separator) && parseInt(this.levelsVisibility, 10) <= data.level\n ) {\n isVisible = !contextElement.visible();\n\n if (isVisible && !contextElement.isVisited) {\n contextElement.isVisited = true;\n }\n\n contextElement.visible(isVisible);\n }\n },\n\n /**\n * Check selected elements\n *\n * @returns {Boolean}\n */\n hasData: function () {\n if (!this.value()) {\n this.value([]);\n }\n\n return this.value() ? !!this.value().length : false;\n },\n\n /**\n * Handles hover on list items.\n *\n * @param {Object} event - mousemove event\n */\n onDelegatedMouseMove: function (event) {\n var target = $(event.currentTarget).closest(this.visibleOptionSelector)[0];\n\n if (this.isCursorPositionChange(event) || this.hoveredElement === target) {\n return;\n }\n\n this._hoverTo(target);\n this.setCursorPosition(event);\n },\n\n /**\n * Get option index\n *\n * @param {Object} data - object with data about this element\n *\n * @returns {Number}\n */\n getOptionIndex: function (data) {\n var index;\n\n _.each(this.cacheOptions.plain, function (opt, id) {\n if (data.value === opt.value) {\n index = id;\n }\n });\n\n return index;\n },\n\n /**\n * Set X and Y cursor position\n *\n * @param {Object} event - mousemove event\n */\n setCursorPosition: function (event) {\n this.cursorPosition = {\n x: event.pageX,\n y: event.pageY\n };\n },\n\n /**\n * Check previous and current cursor position\n *\n * @param {Object} event - mousemove event\n * @returns {Boolean}\n */\n isCursorPositionChange: function (event) {\n return this.cursorPosition &&\n this.cursorPosition.x === event.pageX &&\n this.cursorPosition.y === event.pageY;\n },\n\n /**\n * Set true to observable variable multiselectFocus\n * @param {Object} ctx\n * @param {Object} event - focus event\n */\n onFocusIn: function (ctx, event) {\n !this.cacheUiSelect ? this.cacheUiSelect = event.target : false;\n this.multiselectFocus(true);\n },\n\n /**\n * Set false to observable variable multiselectFocus\n * and close list\n */\n onFocusOut: function () {\n this.multiselectFocus(false);\n },\n\n /**\n * Handler enter key, if select list is closed - open select,\n * if select list is open toggle selected current option\n */\n enterKeyHandler: function () {\n\n if (this.filterOptionsFocus()) {\n return false;\n }\n\n if (this.listVisible()) {\n if (this.hoveredElement) {\n this.toggleOptionSelected(ko.dataFor(this.hoveredElement));\n }\n } else {\n this.setListVisible(true);\n }\n },\n\n /**\n * Handler escape key, if select list is open - closes it,\n */\n escapeKeyHandler: function () {\n this.listVisible() ? this.setListVisible(false) : false;\n },\n\n /**\n * Handler pageDown key, selected next option in list, if current option is last\n * selected first option in list\n */\n pageDownKeyHandler: function () {\n this._setHoverToElement(1);\n },\n\n /**\n * Get jQuery element by option data\n *\n * @param {Object} data - option data\n *\n * @returns {Object} jQuery element\n */\n _getElemByData: function (data) {\n var i = 0,\n list = $(this.cacheUiSelect).find('li'),\n length = this.options().length,\n result;\n\n for (i; i < length; i++) {\n if (this.options()[i].value === data.value) {\n result = $(list[i]);\n }\n }\n\n return result;\n },\n\n /**\n * Set hover to visible element\n *\n * @param {Number} direction - iterator\n */\n _setHoverToElement: function (direction) {\n var element;\n\n if (direction === 1) {\n element = this._getNextElement();\n } else if (direction === -1) {\n element = this._getPreviousElement();\n }\n\n if (element) {\n this._hoverTo(element);\n this._scrollTo(element);\n }\n },\n\n /**\n * Find current hovered element\n * and change scroll position\n *\n * @param {Number} element - element index\n */\n _scrollTo: function (element) {\n var curEl = $(element).children(this.actionTargetSelector),\n wrapper = $(this.rootList),\n curElPos = {},\n wrapperPos = {};\n\n curElPos.start = curEl.offset().top;\n curElPos.end = curElPos.start + curEl.outerHeight();\n\n wrapperPos.start = wrapper.offset().top;\n wrapperPos.end = wrapperPos.start + wrapper.height();\n\n if (curElPos.start < wrapperPos.start) {\n wrapper.scrollTop(wrapper.scrollTop() - (wrapperPos.start - curElPos.start));\n } else if (curElPos.end > wrapperPos.end) {\n wrapper.scrollTop(wrapper.scrollTop() + curElPos.end - wrapperPos.end);\n }\n },\n\n /**\n * Handler pageUp key, selected previous option in list, if current option is first -\n * selected last option in list\n */\n pageUpKeyHandler: function () {\n this._setHoverToElement(-1);\n },\n\n /**\n * Switcher to parse keydown event and delegate event to needful method\n *\n * @param {Object} data - element data\n * @param {Object} event - keydown event\n * @returns {Boolean} if handler for this event doesn't found return true\n */\n keydownSwitcher: function (data, event) {\n var keyName = keyCodes[event.keyCode];\n\n if (this.isTabKey(event)) {\n if (!this.filterOptionsFocus() && this.listVisible() && this.filterOptions) {\n this.cacheUiSelect.trigger('blur');\n this.filterOptionsFocus(true);\n this.cleanHoveredElement();\n\n return false;\n }\n this.listVisible(false);\n\n return true;\n }\n\n if (this.keyDownHandlers().hasOwnProperty(keyName)) {\n this.keyDownHandlers()[keyName].apply(this, arguments);\n } else {\n return true;\n }\n },\n\n /**\n * Set caption\n */\n setCaption: function () {\n var length, caption = '';\n\n if (!_.isArray(this.value()) && this.value()) {\n length = 1;\n } else if (this.value()) {\n length = this.value().length;\n } else {\n this.value([]);\n length = 0;\n }\n this.warn(caption);\n\n //check if option was removed\n if (this.isDisplayMissingValuePlaceholder && length && !this.getSelected().length) {\n caption = this.missingValuePlaceholder.replace('%s', this.value());\n this.placeholder(caption);\n this.warn(caption);\n\n return this.placeholder();\n }\n\n if (length > 1) {\n this.placeholder(length + ' ' + this.selectedPlaceholders.lotPlaceholders);\n } else if (length && this.getSelected().length) {\n this.placeholder(this.getSelected()[0].label);\n } else {\n this.placeholder(this.selectedPlaceholders.defaultPlaceholder);\n }\n\n return this.placeholder();\n },\n\n /**\n * Set list status, open or close\n *\n * @param {Boolean} value - variable for set list visible status\n */\n setListVisible: function (value) {\n this.listVisible(value);\n },\n\n /**\n * Processes preview for option by it's value, and sets the result\n * to 'preview' observable\n *\n * @returns {String}\n */\n getPreview: function () {\n var selected = this.getSelected();\n\n return selected.map(function (option) {\n return option.label;\n }).join(', ');\n },\n\n /**\n * Defines previous option element to\n * the one that is currently hovered.\n *\n * @returns {Element}\n */\n _getPreviousElement: function () {\n var currentElement = this.hoveredElement,\n lastElement = this._getLastIn(this.rootList),\n previousElement;\n\n if (!currentElement) {\n return lastElement;\n }\n\n previousElement = $(currentElement).prev()[0];\n\n return this._getLastIn(previousElement) ||\n previousElement ||\n this._getFirstParentOf(currentElement) ||\n lastElement;\n },\n\n /**\n * Defines next option element to\n * the one that is currently hovered.\n *\n * @returns {Element}\n */\n _getNextElement: function () {\n var currentElement = this.hoveredElement,\n firstElement = this._getFirstIn(this.rootList);\n\n if (!currentElement) {\n return firstElement;\n }\n\n return this._getFirstIn(currentElement) ||\n $(currentElement).next()[0] ||\n this._getParentsOf(currentElement).next()[0] ||\n firstElement;\n },\n\n /**\n * Returns first option element in provided scope.\n *\n * @param {Element} scope\n * @returns {Element}\n */\n _getFirstIn: function (scope) {\n return $(scope).find(this.visibleOptionSelector)[0];\n },\n\n /**\n * Returns last descendant option element in provided scope.\n *\n * @param {Element} scope\n * @returns {Element}\n */\n _getLastIn: function (scope) {\n return $(scope).find(this.visibleOptionSelector).last()[0];\n },\n\n /**\n * Returns a collection of parent option elements.\n *\n * @param {Element} scope\n * @returns {jQueryCollection}\n */\n _getParentsOf: function (scope) {\n return $(scope).parents(this.visibleOptionSelector);\n },\n\n /**\n * Returns first parent option element.\n *\n * @param {Element} scope\n * @returns {Element}\n */\n _getFirstParentOf: function (scope) {\n return this._getParentsOf(scope)[0];\n },\n\n /**\n * Sets hover class to provided option element.\n *\n * @param {Element} element\n */\n _hoverTo: function (element) {\n if (this.hoveredElement) {\n $(this.hoveredElement)\n .children(this.actionTargetSelector)\n .removeClass(this.hoverClass);\n }\n\n $(element)\n .children(this.actionTargetSelector)\n .addClass(this.hoverClass);\n\n this.hoveredElement = element;\n },\n\n /**\n * Callback which fires when root list element is rendered.\n *\n * @param {Element} element\n */\n onRootListRender: function (element) {\n var targetSelector = 'li > ' + this.actionTargetSelector;\n\n this.rootList = element;\n\n $(this.rootList).on(\n 'mousemove',\n targetSelector,\n this.onDelegatedMouseMove.bind(this)\n );\n },\n\n /**\n * Returns options from cache or send request\n *\n * @param {String} searchKey\n */\n loadOptions: function (searchKey) {\n var currentPage = searchKey === this.lastSearchKey ? this.lastSearchPage + 1 : 1,\n cachedSearchResult;\n\n this.renderPath = !!this.showPath;\n\n if (this.isSearchKeyCached(searchKey)) {\n cachedSearchResult = this.getCachedSearchResults(searchKey);\n this.cacheOptions.plain = cachedSearchResult.options;\n this.options(cachedSearchResult.options);\n this.afterLoadOptions(searchKey, cachedSearchResult.lastPage, cachedSearchResult.total);\n\n return;\n }\n\n if (currentPage === 1) {\n this.options([]);\n }\n this.processRequest(searchKey, currentPage);\n },\n\n /**\n * Load more options on scroll down\n * @param {Object} data\n * @param {Event} event\n */\n onScrollDown: function (data, event) {\n var clientHight = event.target.scrollTop + event.target.clientHeight,\n scrollHeight = event.target.scrollHeight;\n\n if (!this.searchOptions) {\n return;\n }\n\n if (clientHight > scrollHeight - this.deviation && !this.isSearchKeyCached(data.filterInputValue())) {\n this.loadOptions(data.filterInputValue());\n }\n },\n\n /**\n * Returns cached search result by search key\n *\n * @param {String} searchKey\n * @return {Object}\n */\n getCachedSearchResults: function (searchKey) {\n if (this.cachedSearchResults.hasOwnProperty(searchKey)) {\n return this.cachedSearchResults[searchKey];\n }\n\n return {\n options: [],\n lastPage: 1,\n total: 0\n };\n },\n\n /**\n * Cache loaded data\n *\n * @param {String} searchKey\n * @param {Array} optionsArray\n * @param {Number} page\n * @param {Number} total\n */\n setCachedSearchResults: function (searchKey, optionsArray, page, total) {\n var cachedData = {};\n\n cachedData.options = optionsArray;\n cachedData.lastPage = page;\n cachedData.total = total;\n this.cachedSearchResults[searchKey] = cachedData;\n },\n\n /**\n * Check if search key cached\n *\n * @param {String} searchKey\n * @return {Boolean}\n */\n isSearchKeyCached: function (searchKey) {\n var totalCached = this.cachedSearchResults.hasOwnProperty(searchKey) ?\n this.deviation * this.cachedSearchResults[searchKey].lastPage :\n 0;\n\n return totalCached > 0 && totalCached >= this.cachedSearchResults[searchKey].total;\n },\n\n /**\n * Submit request to load data\n *\n * @param {String} searchKey\n * @param {Number} page\n */\n processRequest: function (searchKey, page) {\n this.loading(true);\n this.currentSearchKey = searchKey;\n $.ajax({\n url: this.searchUrl,\n type: 'get',\n dataType: 'json',\n context: this,\n data: {\n searchKey: searchKey,\n page: page,\n limit: this.pageLimit\n },\n success: $.proxy(this.success, this),\n error: $.proxy(this.error, this),\n beforeSend: $.proxy(this.beforeSend, this),\n complete: $.proxy(this.complete, this, searchKey, page)\n });\n },\n\n /** @param {Object} response */\n success: function (response) {\n var existingOptions = this.options();\n\n _.each(response.options, function (opt) {\n existingOptions.push(opt);\n });\n\n this.total = response.total;\n this.cacheOptions.plain = existingOptions;\n this.options(existingOptions);\n },\n\n /** add actions before ajax request */\n beforeSend: function () {\n\n },\n\n /** set empty array if error occurs */\n error: function () {\n this.options([]);\n },\n\n /** cache options and stop loading*/\n complete: function (searchKey, page) {\n this.setCachedSearchResults(searchKey, this.options(), page, this.total);\n this.afterLoadOptions(searchKey, page, this.total);\n },\n\n /**\n * Stop loading and update data after options were updated\n *\n * @param {String} searchKey\n * @param {Number} page\n * @param {Number} total\n */\n afterLoadOptions: function (searchKey, page, total) {\n this.lastSearchKey = searchKey;\n this.lastSearchPage = page;\n this._setItemsQuantity(total);\n this.loading(false);\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/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/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/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/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/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('input[type=\"file\"]').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/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/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/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/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/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/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/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/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/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/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/file-uploader.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\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/abstract',\n 'mage/backend/notification',\n 'mage/translate',\n 'jquery/file-uploader',\n 'mage/adminhtml/tools'\n], function ($, _, utils, uiAlert, validator, Element, notification, $t) {\n 'use strict';\n\n return Element.extend({\n defaults: {\n value: [],\n aggregatedErrors: [],\n maxFileSize: false,\n isMultipleFiles: false,\n placeholderType: 'document', // 'image', 'video'\n allowedExtensions: false,\n previewTmpl: 'ui/form/element/uploader/preview',\n dropZone: '[data-role=drop-zone]',\n isLoading: false,\n uploaderConfig: {\n dataType: 'json',\n sequentialUploads: true,\n formData: {\n 'form_key': window.FORM_KEY\n }\n },\n tracks: {\n isLoading: true\n }\n },\n\n /**\n * Initializes file uploader plugin on provided input element.\n *\n * @param {HTMLInputElement} fileInput\n * @returns {FileUploader} Chainable.\n */\n initUploader: function (fileInput) {\n this.$fileInput = fileInput;\n\n _.extend(this.uploaderConfig, {\n dropZone: $(fileInput).closest(this.dropZone),\n change: this.onFilesChoosed.bind(this),\n drop: this.onFilesChoosed.bind(this),\n add: this.onBeforeFileUpload.bind(this),\n fail: this.onFail.bind(this),\n done: this.onFileUploaded.bind(this),\n start: this.onLoadingStart.bind(this),\n stop: this.onLoadingStop.bind(this)\n });\n\n $(fileInput).fileupload(this.uploaderConfig);\n\n return this;\n },\n\n /**\n * Defines initial value of the instance.\n *\n * @returns {FileUploader} Chainable.\n */\n setInitialValue: function () {\n var value = this.getInitialValue();\n\n value = value.map(this.processFile, this);\n\n this.initialValue = value.slice();\n\n this.value(value);\n this.on('value', this.onUpdate.bind(this));\n this.isUseDefault(this.disabled());\n\n return this;\n },\n\n /**\n * Empties files list.\n *\n * @returns {FileUploader} Chainable.\n */\n clear: function () {\n this.value.removeAll();\n\n return this;\n },\n\n /**\n * Checks if files list contains any items.\n *\n * @returns {Boolean}\n */\n hasData: function () {\n return !!this.value().length;\n },\n\n /**\n * Resets files list to its' initial value.\n *\n * @returns {FileUploader}\n */\n reset: function () {\n var value = this.initialValue.slice();\n\n this.value(value);\n\n return this;\n },\n\n /**\n * Adds provided file to the files list.\n *\n * @param {Object} file\n * @returns {FileUploader} Chainable.\n */\n addFile: function (file) {\n file = this.processFile(file);\n\n this.isMultipleFiles ?\n this.value.push(file) :\n this.value([file]);\n\n return this;\n },\n\n /**\n * Retrieves from the list file which matches\n * search criteria implemented in itertor function.\n *\n * @param {Function} fn - Function that will be invoked\n * for each file in the list.\n * @returns {Object}\n */\n getFile: function (fn) {\n return _.find(this.value(), fn);\n },\n\n /**\n * Removes provided file from thes files list.\n *\n * @param {Object} file\n * @returns {FileUploader} Chainable.\n */\n removeFile: function (file) {\n this.value.remove(file);\n\n return this;\n },\n\n /**\n * May perform modifications on the provided\n * file object before adding it to the files list.\n *\n * @param {Object} file\n * @returns {Object} Modified file object.\n */\n processFile: function (file) {\n file.previewType = this.getFilePreviewType(file);\n\n if (!file.id && file.name) {\n file.id = Base64.mageEncode(file.name);\n }\n\n this.observe.call(file, true, [\n 'previewWidth',\n 'previewHeight'\n ]);\n\n return file;\n },\n\n /**\n * Formats incoming bytes value to a readable format.\n *\n * @param {Number} bytes\n * @returns {String}\n */\n formatSize: function (bytes) {\n var sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'],\n i;\n\n if (bytes === 0) {\n return '0 Byte';\n }\n\n i = window.parseInt(Math.floor(Math.log(bytes) / Math.log(1024)));\n\n return Math.round(bytes / Math.pow(1024, i), 2) + ' ' + sizes[i];\n },\n\n /**\n * Returns path to the files' preview image.\n *\n * @param {Object} file\n * @returns {String}\n */\n getFilePreview: function (file) {\n return file.url;\n },\n\n /**\n * Returns path to the file's preview template.\n *\n * @returns {String}\n */\n getPreviewTmpl: function () {\n return this.previewTmpl;\n },\n\n /**\n * Checks if provided file is allowed to be uploaded.\n *\n * @param {Object} file\n * @returns {Object} Validation result.\n */\n isFileAllowed: function (file) {\n var result;\n\n _.every([\n this.isExtensionAllowed(file),\n this.isSizeExceeded(file)\n ], function (value) {\n result = value;\n\n return value.passed;\n });\n\n return result;\n },\n\n /**\n * Checks if extension of provided file is allowed.\n *\n * @param {Object} file - File to be checked.\n * @returns {Boolean}\n */\n isExtensionAllowed: function (file) {\n return validator('validate-file-type', file.name, this.allowedExtensions);\n },\n\n /**\n * Get simplified file type.\n *\n * @param {Object} file - File to be checked.\n * @returns {String}\n */\n getFilePreviewType: function (file) {\n var type;\n\n if (!file.type) {\n return 'document';\n }\n\n type = file.type.split('/')[0];\n\n return type !== 'image' && type !== 'video' ? 'document' : type;\n },\n\n /**\n * Checks if size of provided file exceeds\n * defined in configuration size limits.\n *\n * @param {Object} file - File to be checked.\n * @returns {Boolean}\n */\n isSizeExceeded: function (file) {\n return validator('validate-max-size', file.size, this.maxFileSize);\n },\n\n /**\n * Displays provided error message.\n *\n * @param {String} msg\n * @returns {FileUploader} Chainable.\n */\n notifyError: function (msg) {\n var data = {\n content: msg\n };\n\n if (this.isMultipleFiles) {\n data.modalClass = '_image-box';\n }\n\n uiAlert(data);\n\n return this;\n },\n\n /**\n * Performs data type conversions.\n *\n * @param {*} value\n * @returns {Array}\n */\n normalizeData: function (value) {\n return utils.isEmpty(value) ? [] : value;\n },\n\n /**\n * Checks if files list is different\n * from its' initial value.\n *\n * @returns {Boolean}\n */\n hasChanged: function () {\n var value = this.value(),\n initial = this.initialValue;\n\n return !utils.equalArrays(value, initial);\n },\n\n /**\n * Handler which is invoked when files are choosed for upload.\n * May be used for implementation of additional validation rules,\n * e.g. total files and a total size rules.\n *\n * @param {Event} event - Event object.\n * @param {Object} data - File data that will be uploaded.\n */\n onFilesChoosed: function (event, data) {\n // no option exists in file uploader for restricting upload chains to single files\n // this enforces that policy\n if (!this.isMultipleFiles) {\n data.files.splice(1);\n }\n },\n\n /**\n * Handler which is invoked prior to the start of a file upload.\n *\n * @param {Event} event - Event object.\n * @param {Object} data - File data that will be uploaded.\n */\n onBeforeFileUpload: function (event, data) {\n var file = data.files[0],\n allowed = this.isFileAllowed(file),\n target = $(event.target);\n\n if (this.disabled()) {\n this.notifyError($t('The file upload field is disabled.'));\n\n return;\n }\n\n if (allowed.passed) {\n target.on('fileuploadsend', function (eventBound, postData) {\n postData.data.append('param_name', this.paramName);\n }.bind(data));\n\n target.fileupload('process', data).done(function () {\n data.submit();\n });\n } else {\n this.aggregateError(file.name, allowed.message);\n\n // if all files in upload chain are invalid, stop callback is never called; this resolves promise\n if (this.aggregatedErrors.length === data.originalFiles.length) {\n this.uploaderConfig.stop();\n }\n }\n },\n\n /**\n * Add error message associated with filename for display when upload chain is complete\n *\n * @param {String} filename\n * @param {String} message\n */\n aggregateError: function (filename, message) {\n this.aggregatedErrors.push({\n filename: filename,\n message: message\n });\n },\n\n /**\n * @param {Event} event\n * @param {Object} data\n */\n onFail: function (event, data) {\n console.error(data.jqXHR.responseText);\n console.error(data.jqXHR.status);\n },\n\n /**\n * Handler of the file upload complete event.\n *\n * @param {Event} event\n * @param {Object} data\n */\n onFileUploaded: function (event, data) {\n var uploadedFilename = data.files[0].name,\n file = data.result,\n error = file.error;\n\n error ?\n this.aggregateError(uploadedFilename, error) :\n this.addFile(file);\n },\n\n /**\n * Load start event handler.\n */\n onLoadingStart: function () {\n this.isLoading = true;\n },\n\n /**\n * Load stop event handler.\n */\n onLoadingStop: function () {\n var aggregatedErrorMessages = [];\n\n this.isLoading = false;\n\n if (!this.aggregatedErrors.length) {\n return;\n }\n\n if (!this.isMultipleFiles) { // only single file upload occurred; use first file's error message\n aggregatedErrorMessages.push(this.aggregatedErrors[0].message);\n } else { // construct message from all aggregatedErrors\n _.each(this.aggregatedErrors, function (error) {\n notification().add({\n error: true,\n message: '%s' + error.message, // %s to be used as placeholder for html injection\n\n /**\n * Adds constructed error notification to aggregatedErrorMessages\n *\n * @param {String} constructedMessage\n */\n insertMethod: function (constructedMessage) {\n var escapedFileName = $('<div>').text(error.filename).html(),\n errorMsgBodyHtml = '<strong>%s</strong> %s.<br>'\n .replace('%s', escapedFileName)\n .replace('%s', $t('was not uploaded'));\n\n // html is escaped in message body for notification widget; prepend unescaped html here\n constructedMessage = constructedMessage.replace('%s', errorMsgBodyHtml);\n\n aggregatedErrorMessages.push(constructedMessage);\n }\n });\n });\n }\n\n this.notifyError(aggregatedErrorMessages.join(''));\n\n // clear out aggregatedErrors array for this completed upload chain\n this.aggregatedErrors = [];\n },\n\n /**\n * Handler function which is supposed to be invoked when\n * file input element has been rendered.\n *\n * @param {HTMLInputElement} fileInput\n */\n onElementRender: function (fileInput) {\n this.initUploader(fileInput);\n },\n\n /**\n * Handler of the preview image load event.\n *\n * @param {Object} file - File associated with an image.\n * @param {Event} event\n */\n onPreviewLoad: function (file, event) {\n var img = event.currentTarget;\n\n file.previewWidth = img.naturalWidth;\n file.previewHeight = img.naturalHeight;\n },\n\n /**\n * Restore value to default\n */\n restoreToDefault: function () {\n var defaultValue = utils.copy(this.default);\n\n defaultValue.map(this.processFile, this);\n this.value(defaultValue);\n },\n\n /**\n * Update whether value differs from default value\n */\n setDifferedFromDefault: function () {\n var value = utils.copy(this.value());\n\n this.isDifferedFromDefault(!_.isEqual(value, this.default));\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_Tax/js/bootstrap.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\nrequire([\n 'mage/backend/editablemultiselect'\n]);\n","Magento_Tax/js/price/adjustment.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'Magento_Ui/js/grid/columns/column',\n 'mage/translate'\n], function (Element, $t) {\n 'use strict';\n\n return Element.extend({\n defaults: {\n bodyTmpl: 'Magento_Tax/price/adjustment',\n taxPriceType: 'final_price',\n taxPriceCssClass: 'price-including-tax',\n bothPrices: 3,\n inclTax: 2,\n exclTax: 1,\n modules: {\n price: '${ $.parentName }'\n },\n listens: {\n price: 'initializePriceAttributes'\n }\n },\n\n /**\n * {@inheritdoc}\n */\n initialize: function () {\n this._super()\n .initializePriceAttributes();\n\n return this;\n },\n\n /**\n * Update parent price.\n *\n * @returns {Object} Chainable.\n */\n initializePriceAttributes: function () {\n if (this.displayBothPrices && this.price()) {\n this.price().priceWrapperCssClasses = this.taxPriceCssClass;\n this.price().priceWrapperAttr = {\n 'data-label': $t('Incl. Tax')\n };\n }\n\n return this;\n },\n\n /**\n * Get price tax adjustment.\n *\n * @param {Object} row\n * @return {HTMLElement} tax html\n */\n getTax: function (row) {\n return row['price_info']['extension_attributes']['tax_adjustments']['formatted_prices'][this.taxPriceType];\n },\n\n /**\n * UnsanitizedHtml version of getTax.\n *\n * @param {Object} row\n * @return {HTMLElement} tax html\n */\n getTaxUnsanitizedHtml: function (row) {\n return this.getTax(row);\n },\n\n /**\n * Set price tax type.\n *\n * @param {String} priceType\n * @return {Object}\n */\n setPriceType: function (priceType) {\n this.taxPriceType = priceType;\n\n return this;\n },\n\n /**\n * Return whether display setting is to display\n * both price including tax and price excluding tax.\n *\n * @return {Boolean}\n */\n displayBothPrices: function () {\n return +this.source.data.displayTaxes === this.bothPrices;\n },\n\n /**\n * Return whether display setting is to display price including tax.\n *\n * @return {Boolean}\n */\n displayPriceIncludeTax: function () {\n return +this.source.data.displayTaxes === this.inclTax;\n },\n\n /**\n * Return whether display setting is to display price excluding tax.\n *\n * @return {Boolean}\n */\n displayPriceExclTax: function () {\n return +this.source.data.displayTaxes === this.exclTax;\n }\n });\n});\n","Magento_Payment/js/transparent.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/* global FORM_KEY */\n/* @api */\ndefine([\n 'jquery',\n 'mage/template',\n 'Magento_Ui/js/modal/alert',\n 'Magento_Payment/js/model/credit-card-validation/validator'\n], function ($, mageTemplate, alert) {\n 'use strict';\n\n $.widget('mage.transparent', {\n options: {\n editFormSelector: '#edit_form',\n hiddenFormTmpl:\n '<form target=\"<%= data.target %>\" action=\"<%= data.action %>\"' +\n 'method=\"POST\" hidden' +\n 'enctype=\"application/x-www-form-urlencoded\" class=\"no-display\">' +\n '<% _.each(data.inputs, function(val, key){ %>' +\n '<input value=\"<%= val %>\" name=\"<%= key %>\" type=\"hidden\">' +\n '<% }); %>' +\n '</form>',\n cgiUrl: null,\n orderSaveUrl: null,\n controller: null,\n gateway: null,\n dateDelim: null,\n cardFieldsMap: null,\n expireYearLength: 2\n },\n\n /**\n * @private\n */\n _create: function () {\n this.hiddenFormTmpl = mageTemplate(this.options.hiddenFormTmpl);\n\n $(this.options.editFormSelector).on('changePaymentMethod', this._setPlaceOrderHandler.bind(this));\n $(this.options.editFormSelector).trigger('changePaymentMethod', [\n $(this.options.editFormSelector).find(':radio[name=\"payment[method]\"]:checked').val()\n ]);\n },\n\n /**\n * Handler for form submit.\n *\n * @param {Object} event\n * @param {String} method\n */\n _setPlaceOrderHandler: function (event, method) {\n var $editForm = $(this.options.editFormSelector);\n\n $editForm.off('beforeSubmitOrder.' + this.options.gateway);\n\n if (method === this.options.gateway) {\n $editForm.on('beforeSubmitOrder.' + this.options.gateway, this._placeOrderHandler.bind(this));\n }\n },\n\n /**\n * Handler for form submit to call gateway for credit card validation.\n *\n * @param {Event} event\n * @return {Boolean}\n * @private\n */\n _placeOrderHandler: function (event) {\n if ($(this.options.editFormSelector).valid()) {\n this._orderSave();\n } else {\n $('body').trigger('processStop');\n }\n event.stopImmediatePropagation();\n\n return false;\n },\n\n /**\n * Handler for Place Order button to call gateway for credit card validation.\n * Save order and generate post data for gateway call.\n *\n * @private\n */\n _orderSave: function () {\n var postData = {\n 'form_key': FORM_KEY,\n 'cc_type': this.ccType()\n };\n\n $.ajax({\n url: this.options.orderSaveUrl,\n type: 'post',\n context: this,\n data: postData,\n dataType: 'json',\n\n /**\n * Success callback\n * @param {Object} response\n */\n success: function (response) {\n if (response.success && response[this.options.gateway]) {\n this._postPaymentToGateway(response);\n } else {\n this._processErrors(response);\n }\n },\n\n /** @inheritdoc */\n complete: function () {\n $('body').trigger('processStop');\n }\n });\n },\n\n /**\n * Post data to gateway for credit card validation.\n *\n * @param {Object} response\n * @private\n */\n _postPaymentToGateway: function (response) {\n var $iframeSelector = $('[data-container=\"' + this.options.gateway + '-transparent-iframe\"]'),\n data,\n tmpl,\n iframe;\n\n data = this._preparePaymentData(response);\n tmpl = this.hiddenFormTmpl({\n data: {\n target: $iframeSelector.attr('name'),\n action: this.options.cgiUrl,\n inputs: data\n }\n });\n\n iframe = $iframeSelector\n .on('submit', function (event) {\n event.stopPropagation();\n });\n $(tmpl).appendTo(iframe).trigger('submit');\n iframe.html('');\n },\n\n /**\n * @returns {String}\n */\n ccType: function () {\n return this.element.find(\n '[data-container=\"' + this.options.gateway + '-cc-type\"]'\n ).val();\n },\n\n /**\n * Add credit card fields to post data for gateway.\n *\n * @param {Object} response\n * @private\n */\n _preparePaymentData: function (response) {\n var ccfields,\n data,\n preparedata;\n\n data = response[this.options.gateway].fields;\n ccfields = this.options.cardFieldsMap;\n\n if (this.element.find('[data-container=\"' + this.options.gateway + '-cc-cvv\"]').length) {\n data[ccfields.cccvv] = this.element.find(\n '[data-container=\"' + this.options.gateway + '-cc-cvv\"]'\n ).val();\n }\n preparedata = this._prepareExpDate();\n data[ccfields.ccexpdate] = preparedata.month + this.options.dateDelim + preparedata.year;\n data[ccfields.ccnum] = this.element.find(\n '[data-container=\"' + this.options.gateway + '-cc-number\"]'\n ).val();\n\n return data;\n },\n\n /**\n * Grab Month and Year into one\n * @returns {Object}\n * @private\n */\n _prepareExpDate: function () {\n var year = this.element.find('[data-container=\"' + this.options.gateway + '-cc-year\"]').val(),\n month = parseInt(\n this.element.find('[data-container=\"' + this.options.gateway + '-cc-month\"]').val(), 10\n );\n\n if (year.length > this.options.expireYearLength) {\n year = year.substring(year.length - this.options.expireYearLength);\n }\n\n if (month < 10) {\n month = '0' + month;\n }\n\n return {\n month: month, year: year\n };\n },\n\n /**\n * Processing errors\n *\n * @param {Object} response\n * @private\n */\n _processErrors: function (response) {\n var msg = response['error_messages'];\n\n if (typeof msg === 'object') {\n alert({\n content: msg.join('\\n')\n });\n }\n\n if (msg) {\n alert({\n content: msg\n });\n }\n }\n });\n\n return $.mage.transparent;\n});\n","Magento_Payment/js/model/credit-card-validation/credit-card-data.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/* @api */\ndefine([], function () {\n 'use strict';\n\n return {\n creditCard: null,\n creditCardNumber: null,\n expirationMonth: null,\n expirationYear: null,\n cvvCode: null\n };\n});\n","Magento_Payment/js/model/credit-card-validation/credit-card-number-validator.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/* @api */\ndefine([\n 'mageUtils',\n 'Magento_Payment/js/model/credit-card-validation/credit-card-number-validator/luhn10-validator',\n 'Magento_Payment/js/model/credit-card-validation/credit-card-number-validator/credit-card-type'\n], function (utils, luhn10, creditCardTypes) {\n 'use strict';\n\n /**\n * @param {*} card\n * @param {*} isPotentiallyValid\n * @param {*} isValid\n * @return {Object}\n */\n function resultWrapper(card, isPotentiallyValid, isValid) {\n return {\n card: card,\n isValid: isValid,\n isPotentiallyValid: isPotentiallyValid\n };\n }\n\n return function (value) {\n var potentialTypes,\n cardType,\n valid,\n i,\n maxLength;\n\n if (utils.isEmpty(value)) {\n return resultWrapper(null, false, false);\n }\n\n value = value.replace(/\\s+/g, '');\n\n if (!/^\\d*$/.test(value)) {\n return resultWrapper(null, false, false);\n }\n\n potentialTypes = creditCardTypes.getCardTypes(value);\n\n if (potentialTypes.length === 0) {\n return resultWrapper(null, false, false);\n } else if (potentialTypes.length !== 1) {\n return resultWrapper(null, true, false);\n }\n\n cardType = potentialTypes[0];\n\n if (cardType.type === 'unionpay') { // UnionPay is not Luhn 10 compliant\n valid = true;\n } else {\n valid = luhn10(value);\n }\n\n for (i = 0; i < cardType.lengths.length; i++) {\n if (cardType.lengths[i] === value.length) {\n return resultWrapper(cardType, valid, valid);\n }\n }\n\n maxLength = Math.max.apply(null, cardType.lengths);\n\n if (value.length < maxLength) {\n return resultWrapper(cardType, true, false);\n }\n\n return resultWrapper(cardType, false, false);\n };\n});\n","Magento_Payment/js/model/credit-card-validation/expiration-date-validator.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/* @api */\ndefine([\n 'mageUtils',\n 'Magento_Payment/js/model/credit-card-validation/expiration-date-validator/parse-date',\n 'Magento_Payment/js/model/credit-card-validation/expiration-date-validator/expiration-month-validator',\n 'Magento_Payment/js/model/credit-card-validation/expiration-date-validator/expiration-year-validator'\n], function (utils, parseDate, expirationMonth, expirationYear) {\n 'use strict';\n\n /**\n * @param {*} isValid\n * @param {*} isPotentiallyValid\n * @param {*} month\n * @param {*} year\n * @return {Object}\n */\n function resultWrapper(isValid, isPotentiallyValid, month, year) {\n return {\n isValid: isValid,\n isPotentiallyValid: isPotentiallyValid,\n month: month,\n year: year\n };\n }\n\n return function (value) {\n var date,\n monthValid,\n yearValid;\n\n if (utils.isEmpty(value)) {\n return resultWrapper(false, false, null, null);\n }\n\n value = value.replace(/^(\\d\\d) (\\d\\d(\\d\\d)?)$/, '$1/$2');\n date = parseDate(value);\n monthValid = expirationMonth(date.month);\n yearValid = expirationYear(date.year);\n\n if (monthValid.isValid && yearValid.isValid) {\n return resultWrapper(true, true, date.month, date.year);\n }\n\n if (monthValid.isPotentiallyValid && yearValid.isPotentiallyValid) {\n return resultWrapper(false, true, null, null);\n }\n\n return resultWrapper(false, false, null, null);\n };\n});\n","Magento_Payment/js/model/credit-card-validation/validator.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/* @api */\ndefine([\n 'jquery',\n 'Magento_Payment/js/model/credit-card-validation/cvv-validator',\n 'Magento_Payment/js/model/credit-card-validation/credit-card-number-validator',\n 'Magento_Payment/js/model/credit-card-validation/expiration-date-validator/expiration-year-validator',\n 'Magento_Payment/js/model/credit-card-validation/expiration-date-validator/expiration-month-validator',\n 'Magento_Payment/js/model/credit-card-validation/credit-card-data',\n 'mage/translate'\n], function ($, cvvValidator, creditCardNumberValidator, yearValidator, monthValidator, creditCardData) {\n 'use strict';\n\n $('.payment-method-content input[type=\"number\"]').on('keyup', function () {\n if ($(this).val() < 0) {\n $(this).val($(this).val().replace(/^-/, ''));\n }\n });\n\n $.each({\n 'validate-card-type': [\n function (number, item, allowedTypes) {\n var cardInfo,\n i,\n l;\n\n if (!creditCardNumberValidator(number).isValid) {\n return false;\n }\n\n cardInfo = creditCardNumberValidator(number).card;\n\n for (i = 0, l = allowedTypes.length; i < l; i++) {\n if (cardInfo.title == allowedTypes[i].type) { //eslint-disable-line eqeqeq\n return true;\n }\n }\n\n return false;\n },\n $.mage.__('Please enter a valid credit card type number.')\n ],\n 'validate-card-number': [\n\n /**\n * Validate credit card number based on mod 10\n *\n * @param {*} number - credit card number\n * @return {Boolean}\n */\n function (number) {\n return creditCardNumberValidator(number).isValid;\n },\n $.mage.__('Please enter a valid credit card number.')\n ],\n 'validate-card-date': [\n\n /**\n * Validate credit card expiration month\n *\n * @param {String} date - month\n * @return {Boolean}\n */\n function (date) {\n return monthValidator(date).isValid;\n },\n $.mage.__('Incorrect credit card expiration month.')\n ],\n 'validate-card-cvv': [\n\n /**\n * Validate cvv\n *\n * @param {String} cvv - card verification value\n * @return {Boolean}\n */\n function (cvv) {\n var maxLength = creditCardData.creditCard ? creditCardData.creditCard.code.size : 3;\n\n return cvvValidator(cvv, maxLength).isValid;\n },\n $.mage.__('Please enter a valid credit card verification number.')\n ],\n 'validate-card-year': [\n\n /**\n * Validate credit card expiration year\n *\n * @param {String} date - year\n * @return {Boolean}\n */\n function (date) {\n return yearValidator(date).isValid;\n },\n $.mage.__('Incorrect credit card expiration year.')\n ]\n\n }, function (i, rule) {\n rule.unshift(i);\n $.validator.addMethod.apply($.validator, rule);\n });\n});\n","Magento_Payment/js/model/credit-card-validation/cvv-validator.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/* @api */\ndefine([], function () {\n 'use strict';\n\n /**\n * @param {*} isValid\n * @param {*} isPotentiallyValid\n * @return {Object}\n */\n function resultWrapper(isValid, isPotentiallyValid) {\n return {\n isValid: isValid,\n isPotentiallyValid: isPotentiallyValid\n };\n }\n\n /**\n * CVV number validation.\n * Validate digit count for CVV code.\n *\n * @param {*} value\n * @param {Number} maxLength\n * @return {Object}\n */\n return function (value, maxLength) {\n var DEFAULT_LENGTH = 3;\n\n maxLength = maxLength || DEFAULT_LENGTH;\n\n if (!/^\\d*$/.test(value)) {\n return resultWrapper(false, false);\n }\n\n if (value.length === maxLength) {\n return resultWrapper(true, true);\n }\n\n if (value.length < maxLength) {\n return resultWrapper(false, true);\n }\n\n if (value.length > maxLength) {\n return resultWrapper(false, false);\n }\n };\n});\n","Magento_Payment/js/model/credit-card-validation/expiration-date-validator/expiration-year-validator.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 * @param {*} isValid\n * @param {*} isPotentiallyValid\n * @return {Object}\n */\n function resultWrapper(isValid, isPotentiallyValid) {\n return {\n isValid: isValid,\n isPotentiallyValid: isPotentiallyValid\n };\n }\n\n return function (value) {\n var currentYear = new Date().getFullYear(),\n len = value.length,\n valid,\n expMaxLifetime = 19;\n\n if (value.replace(/\\s/g, '') === '') {\n return resultWrapper(false, true);\n }\n\n if (!/^\\d*$/.test(value)) {\n return resultWrapper(false, false);\n }\n\n if (len !== 4) {\n return resultWrapper(false, true);\n }\n\n value = parseInt(value, 10);\n valid = value >= currentYear && value <= currentYear + expMaxLifetime;\n\n return resultWrapper(valid, valid);\n };\n});\n","Magento_Payment/js/model/credit-card-validation/expiration-date-validator/parse-date.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 return function (value) {\n var month, len;\n\n if (value.match('/')) {\n value = value.split(/\\s*\\/\\s*/g);\n\n return {\n month: value[0],\n year: value.slice(1).join()\n };\n }\n\n len = value[0] === '0' || value.length > 5 || value.length === 4 || value.length === 3 ? 2 : 1;\n month = value.substr(0, len);\n\n return {\n month: month,\n year: value.substr(month.length, 4)\n };\n };\n});\n","Magento_Payment/js/model/credit-card-validation/expiration-date-validator/expiration-month-validator.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 * @param {*} isValid\n * @param {*} isPotentiallyValid\n * @return {Object}\n */\n function resultWrapper(isValid, isPotentiallyValid) {\n return {\n isValid: isValid,\n isPotentiallyValid: isPotentiallyValid\n };\n }\n\n return function (value) {\n var month,\n monthValid;\n\n if (value.replace(/\\s/g, '') === '' || value === '0') {\n return resultWrapper(false, true);\n }\n\n if (!/^\\d*$/.test(value)) {\n return resultWrapper(false, false);\n }\n\n if (isNaN(value)) {\n return resultWrapper(false, false);\n }\n\n month = parseInt(value, 10);\n monthValid = month > 0 && month < 13;\n\n return resultWrapper(monthValid, monthValid);\n };\n});\n","Magento_Payment/js/model/credit-card-validation/credit-card-number-validator/credit-card-type.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/* @api */\ndefine([\n 'jquery',\n 'mageUtils'\n], function ($, utils) {\n 'use strict';\n\n var types = [\n {\n title: 'Visa',\n type: 'VI',\n pattern: '^4\\\\d*$',\n gaps: [4, 8, 12],\n lengths: [16],\n code: {\n name: 'CVV',\n size: 3\n }\n },\n {\n title: 'MasterCard',\n type: 'MC',\n pattern: '^(?:5[1-5][0-9]{2}|222[1-9]|22[3-9][0-9]|2[3-6][0-9]{2}|27[01][0-9]|2720)[0-9]{12}$',\n gaps: [4, 8, 12],\n lengths: [16],\n code: {\n name: 'CVC',\n size: 3\n }\n },\n {\n title: 'American Express',\n type: 'AE',\n pattern: '^3([47]\\\\d*)?$',\n isAmex: true,\n gaps: [4, 10],\n lengths: [15],\n code: {\n name: 'CID',\n size: 4\n }\n },\n {\n title: 'Diners',\n type: 'DN',\n pattern: '^(3(0[0-5]|095|6|[8-9]))\\\\d*$',\n gaps: [4, 10],\n lengths: [14, 16, 17, 18, 19],\n code: {\n name: 'CVV',\n size: 3\n }\n },\n {\n title: 'Discover',\n type: 'DI',\n pattern: '^(6011(0|[2-4]|74|7[7-9]|8[6-9]|9)|6(4[4-9]|5))\\\\d*$',\n gaps: [4, 8, 12],\n lengths: [16, 17, 18, 19],\n code: {\n name: 'CID',\n size: 3\n }\n },\n {\n title: 'JCB',\n type: 'JCB',\n pattern: '^35(2[8-9]|[3-8])\\\\d*$',\n gaps: [4, 8, 12],\n lengths: [16, 17, 18, 19],\n code: {\n name: 'CVV',\n size: 3\n }\n },\n {\n title: 'UnionPay',\n type: 'UN',\n pattern: '^(622(1(2[6-9]|[3-9])|[3-8]|9([[0-1]|2[0-5]))|62[4-6]|628([2-8]))\\\\d*?$',\n gaps: [4, 8, 12],\n lengths: [16, 17, 18, 19],\n code: {\n name: 'CVN',\n size: 3\n }\n },\n {\n title: 'Maestro International',\n type: 'MI',\n pattern: '^(5(0|[6-9])|63|67(?!59|6770|6774))\\\\d*$',\n gaps: [4, 8, 12],\n lengths: [12, 13, 14, 15, 16, 17, 18, 19],\n code: {\n name: 'CVC',\n size: 3\n }\n },\n {\n title: 'Maestro Domestic',\n type: 'MD',\n pattern: '^6759(?!24|38|40|6[3-9]|70|76)|676770|676774\\\\d*$',\n gaps: [4, 8, 12],\n lengths: [12, 13, 14, 15, 16, 17, 18, 19],\n code: {\n name: 'CVC',\n size: 3\n }\n },\n {\n title: 'Hipercard',\n type: 'HC',\n pattern: '^((606282)|(637095)|(637568)|(637599)|(637609)|(637612))\\\\d*$',\n gaps: [4, 8, 12],\n lengths: [13, 16],\n code: {\n name: 'CVC',\n size: 3\n }\n },\n {\n title: 'Elo',\n type: 'ELO',\n pattern: '^((509091)|(636368)|(636297)|(504175)|(438935)|(40117[8-9])|(45763[1-2])|' +\n '(457393)|(431274)|(50990[0-2])|(5099[7-9][0-9])|(50996[4-9])|(509[1-8][0-9][0-9])|' +\n '(5090(0[0-2]|0[4-9]|1[2-9]|[24589][0-9]|3[1-9]|6[0-46-9]|7[0-24-9]))|' +\n '(5067(0[0-24-8]|1[0-24-9]|2[014-9]|3[0-379]|4[0-9]|5[0-3]|6[0-5]|7[0-8]))|' +\n '(6504(0[5-9]|1[0-9]|2[0-9]|3[0-9]))|' +\n '(6504(8[5-9]|9[0-9])|6505(0[0-9]|1[0-9]|2[0-9]|3[0-8]))|' +\n '(6505(4[1-9]|5[0-9]|6[0-9]|7[0-9]|8[0-9]|9[0-8]))|' +\n '(6507(0[0-9]|1[0-8]))|(65072[0-7])|(6509(0[1-9]|1[0-9]|20))|' +\n '(6516(5[2-9]|6[0-9]|7[0-9]))|(6550(0[0-9]|1[0-9]))|' +\n '(6550(2[1-9]|3[0-9]|4[0-9]|5[0-8])))\\\\d*$',\n gaps: [4, 8, 12],\n lengths: [16],\n code: {\n name: 'CVC',\n size: 3\n }\n },\n {\n title: 'Aura',\n type: 'AU',\n pattern: '^5078\\\\d*$',\n gaps: [4, 8, 12],\n lengths: [19],\n code: {\n name: 'CVC',\n size: 3\n }\n }\n ];\n\n return {\n /**\n * @param {*} cardNumber\n * @return {Array}\n */\n getCardTypes: function (cardNumber) {\n var i, value,\n result = [];\n\n if (utils.isEmpty(cardNumber)) {\n return result;\n }\n\n if (cardNumber === '') {\n return $.extend(true, {}, types);\n }\n\n for (i = 0; i < types.length; i++) {\n value = types[i];\n\n if (new RegExp(value.pattern).test(cardNumber)) {\n result.push($.extend(true, {}, value));\n }\n }\n\n return result;\n }\n };\n});\n","Magento_Payment/js/model/credit-card-validation/credit-card-number-validator/luhn10-validator.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 * Luhn algorithm verification\n */\n return function (a, b, c, d, e) {\n for (d = +a[b = a.length - 1], e = 0; b--;) {\n c = +a[b];\n d += ++e % 2 ? 2 * c % 10 + (c > 4) : c;\n }\n\n return !(d % 10);\n };\n});\n","Magento_Msrp/js/msrp.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n 'jquery',\n 'Magento_Catalog/js/price-utils',\n 'underscore',\n 'jquery-ui-modules/widget',\n 'mage/dropdown',\n 'mage/template'\n], function ($, priceUtils, _) {\n 'use strict';\n\n $.widget('mage.addToCart', {\n options: {\n showAddToCart: true,\n submitUrl: '',\n cartButtonId: '',\n singleOpenDropDown: true,\n dialog: {}, // Options for mage/dropdown\n dialogDelay: 500, // Delay in ms after resize dropdown shown again\n origin: '', //Required, type of popup: 'msrp', 'tier' or 'info' popup\n\n // Selectors\n cartForm: '.form.map.checkout',\n msrpLabelId: '#map-popup-msrp',\n msrpPriceElement: '#map-popup-msrp .price-wrapper',\n priceLabelId: '#map-popup-price',\n priceElement: '#map-popup-price .price',\n mapInfoLinks: '.map-show-info',\n displayPriceElement: '.old-price.map-old-price .price-wrapper',\n fallbackPriceElement: '.normal-price.map-fallback-price .price-wrapper',\n displayPriceContainer: '.old-price.map-old-price',\n fallbackPriceContainer: '.normal-price.map-fallback-price',\n popUpAttr: '[data-role=msrp-popup-template]',\n popupCartButtonId: '#map-popup-button',\n paypalCheckoutButons: '[data-action=checkout-form-submit]',\n popupId: '',\n realPrice: '',\n isSaleable: '',\n msrpPrice: '',\n helpLinkId: '',\n addToCartButton: '',\n\n // Text options\n productName: '',\n addToCartUrl: ''\n },\n\n openDropDown: null,\n triggerClass: 'dropdown-active',\n\n popUpOptions: {\n appendTo: 'body',\n dialogContentClass: 'active',\n closeOnMouseLeave: false,\n autoPosition: true,\n closeOnClickOutside: false,\n 'dialogClass': 'popup map-popup-wrapper',\n position: {\n my: 'left top',\n collision: 'fit none',\n at: 'left bottom',\n within: 'body'\n },\n shadowHinter: 'popup popup-pointer'\n },\n popupOpened: false,\n wasOpened: false,\n\n /**\n * Creates widget instance\n *\n * @private\n */\n _create: function () {\n if (this.options.origin === 'msrp') {\n this.initMsrpPopup();\n } else if (this.options.origin === 'info') {\n this.initInfoPopup();\n } else if (this.options.origin === 'tier') {\n this.initTierPopup();\n }\n $(this.options.cartButtonId).on('click', this._addToCartSubmit.bind(this));\n $(document).on('updateMsrpPriceBlock', this.onUpdateMsrpPrice.bind(this));\n $(this.options.cartForm).on('submit', this._onSubmitForm.bind(this));\n },\n\n /**\n * Init msrp popup\n *\n * @private\n */\n initMsrpPopup: function () {\n var popupDOM = $(this.options.popUpAttr)[0],\n $msrpPopup = $(popupDOM.innerHTML.trim());\n\n $msrpPopup.find(this.options.productIdInput).val(this.options.productId);\n $('body').append($msrpPopup);\n $msrpPopup.trigger('contentUpdated');\n\n $msrpPopup.find('button')\n .on('click',\n this.handleMsrpAddToCart.bind(this))\n .filter(this.options.popupCartButtonId)\n .text($(this.options.addToCartButton).text());\n\n $msrpPopup.find(this.options.paypalCheckoutButons).on('click',\n this.handleMsrpPaypalCheckout.bind(this));\n\n $(this.options.popupId).on('click',\n this.openPopup.bind(this));\n\n this.$popup = $msrpPopup;\n },\n\n /**\n * Init info popup\n *\n * @private\n */\n initInfoPopup: function () {\n var infoPopupDOM = $('[data-role=msrp-info-template]')[0],\n $infoPopup = $(infoPopupDOM.innerHTML.trim());\n\n $('body').append($infoPopup);\n\n $(this.options.helpLinkId).on('click', function (e) {\n this.popUpOptions.position.of = $(e.target);\n $infoPopup.dropdownDialog(this.popUpOptions).dropdownDialog('open');\n this._toggle($infoPopup);\n }.bind(this));\n\n this.$popup = $infoPopup;\n },\n\n /**\n * Init tier price popup\n * @private\n */\n initTierPopup: function () {\n var popupDOM = $(this.options.popUpAttr)[0],\n $tierPopup = $(popupDOM.innerHTML.trim());\n\n $('body').append($tierPopup);\n $tierPopup.find(this.options.productIdInput).val(this.options.productId);\n this.popUpOptions.position.of = $(this.options.helpLinkId);\n\n $tierPopup.find('button').on('click',\n this.handleTierAddToCart.bind(this))\n .filter(this.options.popupCartButtonId)\n .text($(this.options.addToCartButton).text());\n\n $tierPopup.find(this.options.paypalCheckoutButons).on('click',\n this.handleTierPaypalCheckout.bind(this));\n\n $(this.options.attr).on('click', function (e) {\n this.$popup = $tierPopup;\n this.tierOptions = $(e.target).data('tier-price');\n this.openPopup(e);\n }.bind(this));\n },\n\n /**\n * handle 'AddToCart' click on Msrp popup\n * @param {Object} ev\n *\n * @private\n */\n handleMsrpAddToCart: function (ev) {\n ev.preventDefault();\n\n if (this.options.addToCartButton) {\n $(this.options.addToCartButton).trigger('click');\n this.closePopup(this.$popup);\n }\n },\n\n /**\n * handle 'paypal checkout buttons' click on Msrp popup\n *\n * @private\n */\n handleMsrpPaypalCheckout: function () {\n this.closePopup(this.$popup);\n },\n\n /**\n * handle 'AddToCart' click on Tier popup\n *\n * @param {Object} ev\n * @private\n */\n handleTierAddToCart: function (ev) {\n ev.preventDefault();\n\n if (this.options.addToCartButton &&\n this.options.inputQty && !isNaN(this.tierOptions.qty)\n ) {\n $(this.options.inputQty).val(this.tierOptions.qty);\n $(this.options.addToCartButton).trigger('click');\n this.closePopup(this.$popup);\n }\n },\n\n /**\n * handle 'paypal checkout buttons' click on Tier popup\n *\n * @private\n */\n handleTierPaypalCheckout: function () {\n if (this.options.inputQty && !isNaN(this.tierOptions.qty)\n ) {\n $(this.options.inputQty).val(this.tierOptions.qty);\n this.closePopup(this.$popup);\n }\n },\n\n /**\n * Open and set up popup\n *\n * @param {Object} event\n */\n openPopup: function (event) {\n var options = this.tierOptions || this.options;\n\n this.popUpOptions.position.of = $(event.target);\n\n if (!this.wasOpened) {\n this.$popup.find(this.options.msrpLabelId).html(options.msrpPrice);\n this.$popup.find(this.options.priceLabelId).html(options.realPrice);\n this.wasOpened = true;\n }\n this.$popup.dropdownDialog(this.popUpOptions).dropdownDialog('open');\n this._toggle(this.$popup);\n\n if (!this.options.isSaleable) {\n this.$popup.find('form').hide();\n }\n },\n\n /**\n * Toggle MAP popup visibility\n *\n * @param {HTMLElement} $elem\n * @private\n */\n _toggle: function ($elem) {\n $(document).on('mouseup.msrp touchend.msrp', function (e) {\n if (!$elem.is(e.target) && $elem.has(e.target).length === 0) {\n this.closePopup($elem);\n }\n }.bind(this));\n $(window).on('resize', function () {\n this.closePopup($elem);\n }.bind(this));\n },\n\n /**\n * Close MAP information popup\n *\n * @param {HTMLElement} $elem\n */\n closePopup: function ($elem) {\n $elem.dropdownDialog('close');\n $(document).off('mouseup.msrp touchend.msrp');\n },\n\n /**\n * Handler for addToCart action\n *\n * @param {Object} e\n */\n _addToCartSubmit: function (e) {\n this.element.trigger('addToCart', this.element);\n\n if (this.element.data('stop-processing')) {\n return false;\n }\n\n if (this.options.addToCartButton) {\n $(this.options.addToCartButton).trigger('click');\n\n return false;\n }\n\n if (this.options.addToCartUrl) {\n $('.mage-dropdown-dialog > .ui-dialog-content').dropdownDialog('close');\n }\n\n e.preventDefault();\n $(this.options.cartForm).trigger('submit');\n },\n\n /**\n * Call on event updatePrice. Proxy to updateMsrpPrice method.\n *\n * @param {Event} event\n * @param {mixed} priceIndex\n * @param {Object} prices\n * @param {Object|undefined} $priceBox\n */\n onUpdateMsrpPrice: function onUpdateMsrpPrice(event, priceIndex, prices, $priceBox) {\n\n var defaultMsrp,\n defaultPrice,\n msrpPrice,\n finalPrice;\n\n defaultMsrp = _.chain(prices).map(function (price) {\n return price.msrpPrice.amount;\n }).reject(function (p) {\n return p === null;\n }).max().value();\n\n defaultPrice = _.chain(prices).map(function (p) {\n return p.finalPrice.amount;\n }).min().value();\n\n if (typeof priceIndex !== 'undefined') {\n msrpPrice = prices[priceIndex].msrpPrice.amount;\n finalPrice = prices[priceIndex].finalPrice.amount;\n\n if (msrpPrice === null || msrpPrice <= finalPrice) {\n this.updateNonMsrpPrice(priceUtils.formatPriceLocale(finalPrice), $priceBox);\n } else {\n this.updateMsrpPrice(\n priceUtils.formatPriceLocale(finalPrice),\n priceUtils.formatPriceLocale(msrpPrice),\n false,\n $priceBox);\n }\n } else {\n this.updateMsrpPrice(\n priceUtils.formatPriceLocale(defaultPrice),\n priceUtils.formatPriceLocale(defaultMsrp),\n true,\n $priceBox);\n }\n },\n\n /**\n * Update prices for configurable product with MSRP enabled\n *\n * @param {String} finalPrice\n * @param {String} msrpPrice\n * @param {Boolean} useDefaultPrice\n * @param {Object|undefined} $priceBox\n */\n updateMsrpPrice: function (finalPrice, msrpPrice, useDefaultPrice, $priceBox) {\n var options = this.tierOptions || this.options;\n\n $(this.options.fallbackPriceContainer, $priceBox).hide();\n $(this.options.displayPriceContainer, $priceBox).show();\n $(this.options.mapInfoLinks, $priceBox).show();\n\n if (useDefaultPrice || !this.wasOpened) {\n if (this.$popup) {\n this.$popup.find(this.options.msrpLabelId).html(options.msrpPrice);\n this.$popup.find(this.options.priceLabelId).html(options.realPrice);\n }\n\n $(this.options.displayPriceElement, $priceBox).html(msrpPrice);\n this.wasOpened = true;\n }\n\n if (!useDefaultPrice) {\n this.$popup.find(this.options.msrpPriceElement).html(msrpPrice);\n this.$popup.find(this.options.priceElement).html(finalPrice);\n $(this.options.displayPriceElement, $priceBox).html(msrpPrice);\n }\n },\n\n /**\n * Display non MAP price for irrelevant products\n *\n * @param {String} price\n * @param {Object|undefined} $priceBox\n */\n updateNonMsrpPrice: function (price, $priceBox) {\n $(this.options.fallbackPriceElement, $priceBox).html(price);\n $(this.options.displayPriceContainer, $priceBox).hide();\n $(this.options.mapInfoLinks, $priceBox).hide();\n $(this.options.fallbackPriceContainer, $priceBox).show();\n },\n\n /**\n * Handler for submit form\n *\n * @private\n */\n _onSubmitForm: function () {\n if ($(this.options.cartForm).valid()) {\n $(this.options.cartButtonId).prop('disabled', true);\n }\n }\n\n });\n\n return $.mage.addToCart;\n});\n","Magento_GroupedProduct/js/grouped-product.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 'mage/template',\n 'jquery/ui',\n 'Magento_Ui/js/modal/modal',\n 'mage/translate',\n 'mage/adminhtml/grid'\n], function ($, mageTemplate) {\n 'use strict';\n\n $.widget('mage.groupedProduct', {\n /**\n * Create widget\n * @private\n */\n _create: function () {\n this.$grid = this.element.find('[data-role=grouped-product-grid]');\n this.$grid.sortable({\n distance: 8,\n items: '[data-role=row]',\n tolerance: 'pointer',\n cancel: ':input',\n update: $.proxy(function () {\n this.element.trigger('resort');\n }, this)\n });\n\n this.productTmpl = mageTemplate('#group-product-template');\n\n $.each(\n this.$grid.data('products'),\n $.proxy(function (index, product) {\n this._add(null, product);\n }, this)\n );\n\n this._on({\n 'add': '_add',\n 'resort': '_resort',\n 'click [data-column=actions] [data-role=delete]': '_remove'\n });\n\n this._bindDialog();\n this._updateGridVisibility();\n },\n\n /**\n * Add product to grouped grid\n * @param {EventObject} event\n * @param {Object} product\n * @private\n */\n _add: function (event, product) {\n var tmpl,\n productExists;\n\n productExists = this.$grid.find('[data-role=id]')\n .filter(function (index, element) {\n return $(element).val() == product.id; //eslint-disable-line eqeqeq\n }).length;\n\n if (!productExists) {\n tmpl = this.productTmpl({\n data: product\n });\n\n $(tmpl).appendTo(this.$grid.find('tbody'));\n }\n },\n\n /**\n * Remove product\n * @param {EventObject} event\n * @private\n */\n _remove: function (event) {\n $(event.target).closest('[data-role=row]').remove();\n this.element.trigger('resort');\n this._updateGridVisibility();\n },\n\n /**\n * Resort products\n * @private\n */\n _resort: function () {\n this.element.find('[data-role=position]').each($.proxy(function (index, element) {\n $(element).val(index + 1);\n }, this));\n },\n\n /**\n * Create modal for show product\n *\n * @private\n */\n _bindDialog: function () {\n var widget = this,\n selectedProductList = {},\n popup = $('[data-role=add-product-dialog]'),\n gridPopup;\n\n popup.modal({\n type: 'slide',\n innerScroll: true,\n title: $.mage.__('Add Products to Group'),\n modalClass: 'grouped',\n\n /** @inheritdoc */\n open: function () {\n $(this).addClass('admin__scope-old'); // ToDo UI: remove with old styles removal\n },\n buttons: [{\n id: 'grouped-product-dialog-apply-button',\n text: $.mage.__('Add Selected Products'),\n 'class': 'action-primary action-add',\n\n /** @inheritdoc */\n click: function () {\n $.each(selectedProductList, function (index, product) {\n widget._add(null, product);\n });\n widget._resort();\n widget._updateGridVisibility();\n popup.modal('closeModal');\n }\n }]\n });\n\n popup.on('click', '[data-role=row]', function (event) {\n var target = $(event.target);\n\n if (!target.is('input')) {\n target.closest('[data-role=row]')\n .find('[data-column=entity_ids] input')\n .prop('checked', function (element, value) {\n return !value;\n })\n .trigger('change');\n }\n });\n\n popup.on(\n 'change',\n '[data-role=row] [data-column=entity_ids] input',\n $.proxy(function (event) {\n var element = $(event.target),\n product = {};\n\n if (element.is(':checked')) {\n product.id = element.val();\n product.qty = 0;\n element.closest('[data-role=row]').find('[data-column]').each(function (index, el) {\n let text = $(el).text();\n\n product[$(el).data('column')] = text.trim();\n });\n selectedProductList[product.id] = product;\n } else {\n delete selectedProductList[element.val()];\n }\n }, this)\n );\n\n gridPopup = $(this.options.gridPopup).data('gridObject');\n\n $('[data-role=add-product]').on('click', function (event) {\n event.preventDefault();\n popup.modal('openModal');\n gridPopup.reload();\n selectedProductList = {};\n });\n\n $('#' + gridPopup.containerId).on('gridajaxsettings', function (event, ajaxSettings) {\n var ids = widget.$grid.find('[data-role=id]').map(function (index, element) {\n return $(element).val();\n }).toArray();\n\n ajaxSettings.data.filter = $.extend(ajaxSettings.data.filter || {}, {\n 'entity_ids': ids\n });\n }).on('gridajax', function (event, ajaxRequest) {\n ajaxRequest.done(function () {\n popup.find('[data-role=row] [data-column=entity_ids] input').each(function (index, element) {\n var $element = $(element);\n\n $element.prop('checked', !!selectedProductList[$element.val()]);\n });\n });\n });\n },\n\n /**\n * Show or hide message\n * @private\n */\n _updateGridVisibility: function () {\n var showGrid = this.element.find('[data-role=id]').length > 0;\n\n this.element.find('.grid-container').toggle(showGrid);\n this.element.find('.no-products-message').toggle(!showGrid);\n }\n });\n\n return $.mage.groupedProduct;\n});\n","Magento_GroupedProduct/js/grouped-product-grid.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-grid'\n], function (_, registry, dynamicRowsGrid) {\n 'use strict';\n\n return dynamicRowsGrid.extend({\n\n /**\n * Set max element position\n *\n * @param {Number} position - element position\n * @param {Object} elem - instance\n */\n setMaxPosition: function (position, elem) {\n\n if (position || position === 0) {\n this.checkMaxPosition(position);\n this.sort(position, elem);\n\n if (~~position === this.maxPosition && ~~position > this.getDefaultPageBoundary() + 1) {\n this.shiftNextPagesPositions(position);\n }\n } else {\n this.maxPosition += 1;\n }\n },\n\n /**\n * Shift positions for next page elements\n *\n * @param {Number} position\n */\n shiftNextPagesPositions: function (position) {\n\n var recordData = this.recordData(),\n startIndex = ~~this.currentPage() * this.pageSize,\n offset = position - startIndex + 1,\n index = startIndex;\n\n if (~~this.currentPage() === this.pages()) {\n return false;\n }\n\n for (index; index < recordData.length; index++) {\n recordData[index].position = index + offset;\n }\n this.recordData(recordData);\n },\n\n /**\n * Update position for element after position from another page is entered\n *\n * @param {Object} data\n * @param {Object} event\n */\n updateGridPosition: function (data, event) {\n var inputValue = parseInt(event.target.value, 10),\n recordData = this.recordData(),\n record,\n previousValue,\n updatedRecord;\n\n record = this.elems().find(function (obj) {\n return obj.dataScope === data.parentScope;\n });\n\n previousValue = this.getCalculatedPosition(record);\n\n if (isNaN(inputValue) || inputValue < 0 || inputValue === previousValue) {\n return false;\n }\n\n this.elems([]);\n\n updatedRecord = this.getUpdatedRecordIndex(recordData, record.data().id);\n\n if (inputValue >= this.recordData().size() - 1) {\n recordData[updatedRecord].position = this.getGlobalMaxPosition() + 1;\n } else {\n recordData.forEach(function (value, index) {\n if (~~value.id === ~~record.data().id) {\n recordData[index].position = inputValue;\n } else if (inputValue > previousValue && index <= inputValue) {\n recordData[index].position = index - 1;\n } else if (inputValue < previousValue && index >= inputValue) {\n recordData[index].position = index + 1;\n }\n });\n }\n\n this.reloadGridData(recordData);\n\n },\n\n /**\n * Get updated record index\n *\n * @param {Array} recordData\n * @param {Number} recordId\n * @return {Number}\n */\n getUpdatedRecordIndex: function (recordData, recordId) {\n return recordData.map(function (o) {\n return ~~o.id;\n }).indexOf(~~recordId);\n },\n\n /**\n *\n * @param {Array} recordData - to reprocess\n */\n reloadGridData: function (recordData) {\n this.recordData(recordData.sort(function (a, b) {\n return ~~a.position - ~~b.position;\n }));\n this._updateCollection();\n this.reload();\n },\n\n /**\n * Event handler for \"Send to bottom\" button\n *\n * @param {Object} positionObj\n * @return {Boolean}\n */\n sendToBottom: function (positionObj) {\n\n var objectToUpdate = this.getObjectToUpdate(positionObj),\n recordData = this.recordData(),\n updatedRecord;\n\n if (~~this.currentPage() === this.pages) {\n objectToUpdate.position = this.maxPosition;\n } else {\n this.elems([]);\n updatedRecord = this.getUpdatedRecordIndex(recordData, objectToUpdate.data().id);\n recordData[updatedRecord].position = this.getGlobalMaxPosition() + 1;\n this.reloadGridData(recordData);\n }\n\n return false;\n },\n\n /**\n * Event handler for \"Send to top\" button\n *\n * @param {Object} positionObj\n * @return {Boolean}\n */\n sendToTop: function (positionObj) {\n var objectToUpdate = this.getObjectToUpdate(positionObj),\n recordData = this.recordData(),\n updatedRecord;\n\n //isFirst\n if (~~this.currentPage() === 1) {\n objectToUpdate.position = 0;\n } else {\n this.elems([]);\n updatedRecord = this.getUpdatedRecordIndex(recordData, objectToUpdate.data().id);\n recordData.forEach(function (value, index) {\n recordData[index].position = index === updatedRecord ? 0 : value.position + 1;\n });\n this.reloadGridData(recordData);\n }\n\n return false;\n },\n\n /**\n * Get element from grid for update\n *\n * @param {Object} object\n * @return {*}\n */\n getObjectToUpdate: function (object) {\n return this.elems().filter(function (item) {\n return item.name === object.parentName;\n })[0];\n },\n\n /**\n * Value function for position input\n *\n * @param {Object} data\n * @return {Number}\n */\n getCalculatedPosition: function (data) {\n return (~~this.currentPage() - 1) * this.pageSize + this.elems().pluck('name').indexOf(data.name);\n },\n\n /**\n * Return Page Boundary\n *\n * @return {Number}\n */\n getDefaultPageBoundary: function () {\n return ~~this.currentPage() * this.pageSize - 1;\n },\n\n /**\n * Returns position for last element to be moved after\n *\n * @return {Number}\n */\n getGlobalMaxPosition: function () {\n return _.max(this.recordData().map(function (r) {\n return ~~r.position;\n }));\n }\n });\n});\n","Magento_Variable/variables.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/* global Variables, updateElementAtCursor, MagentovariablePlugin, Base64 */\ndefine([\n 'jquery',\n 'mage/backend/notification',\n 'mage/translate',\n 'wysiwygAdapter',\n 'uiRegistry',\n 'mage/apply/main',\n 'mageUtils',\n 'Magento_Variable/js/config-directive-generator',\n 'Magento_Variable/js/custom-directive-generator',\n 'Magento_Ui/js/lib/spinner',\n 'jquery/ui',\n 'prototype',\n 'mage/adminhtml/tools'\n], function (jQuery, notification, $t, wysiwyg, registry, mageApply, utils, configGenerator, customGenerator, loader) {\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 selectedPlaceholder: null,\n isEditMode: null,\n editor: null,\n\n /**\n * Initialize Variables handler.\n *\n * @param {*} textareaElementId\n * @param {Function} insertFunction\n * @param {Object} editor\n * @param {Object} selectedPlaceholder\n */\n init: function (textareaElementId, insertFunction, editor, selectedPlaceholder) {\n if ($(textareaElementId)) {\n this.textareaElementId = textareaElementId;\n }\n\n if (insertFunction) {\n this.insertFunction = insertFunction;\n }\n\n if (selectedPlaceholder) {\n this.selectedPlaceholder = selectedPlaceholder;\n }\n\n if (editor) {\n this.editor = editor;\n }\n },\n\n /**\n * Reset data.\n */\n resetData: function () {\n this.variablesContent = null;\n this.dialogWindow = null;\n },\n\n /**\n * Open variables chooser slideout.\n *\n * @param {Object} variables\n */\n openVariableChooser: function (variables) {\n if (variables) {\n this.openDialogWindow(variables);\n }\n },\n\n /**\n * Close variables chooser slideout dialog window.\n */\n closeDialogWindow: function () {\n jQuery('#' + this.dialogWindowId).modal('closeModal');\n },\n\n /**\n * Init ui component grid on the form\n *\n * @return void\n */\n initUiGrid: function () {\n mageApply.apply(document.getElementById(this.dialogWindow));\n jQuery('#' + this.dialogWindowId).applyBindings();\n loader.get('variables_modal.variables_modal.variables').hide();\n },\n\n /**\n * Open slideout dialog window.\n *\n * @param {*} variablesContent\n * @param {Object} selectedElement\n */\n openDialogWindow: function (variablesContent, selectedElement) {\n\n var html = utils.copy(variablesContent),\n self = this;\n\n jQuery('<div id=\"' + this.dialogWindowId + '\">' + html + '</div>').modal({\n title: self.isEditMode ? $t('Edit Variable') : $t('Insert Variable'),\n type: 'slide',\n buttons: self.getButtonsConfig(self.isEditMode),\n\n /**\n * @param {jQuery.Event} e\n * @param {Object} modal\n */\n closed: function (e, modal) {\n modal.modal.remove();\n registry.get(\n 'variables_modal.variables_modal.variables.variable_selector',\n function (radioSelect) {\n radioSelect.selectedVariableCode('');\n }\n );\n }\n });\n\n this.selectedPlaceholder = selectedElement;\n\n this.addNotAvailableMessage(selectedElement);\n\n jQuery('#' + this.dialogWindowId).modal('openModal');\n\n if (typeof selectedElement !== 'undefined') {\n registry.get(\n 'variables_modal.variables_modal.variables.variable_selector',\n function (radioSelect) {\n radioSelect.selectedVariableCode(MagentovariablePlugin.getElementVariablePath(selectedElement));\n }\n );\n }\n },\n\n /**\n * Add message to slide out that variable is no longer available\n *\n * @param {Object} selectedElement\n */\n addNotAvailableMessage: function (selectedElement) {\n var name,\n msg,\n variablePath,\n $wrapper,\n lostVariableClass = 'magento-placeholder-error';\n\n if (\n this.isEditMode &&\n typeof selectedElement !== 'undefined' &&\n jQuery(selectedElement).hasClass(lostVariableClass)\n ) {\n\n variablePath = MagentovariablePlugin.getElementVariablePath(selectedElement);\n name = variablePath.split(':');\n msg = $t('The variable %1 is no longer available. Select a different variable.')\n .replace('%1', name[1]);\n\n jQuery('body').notification('clear')\n .notification('add', {\n error: true,\n message: msg,\n\n /**\n * @param {String} message\n */\n insertMethod: function (message) {\n $wrapper = jQuery('<div></div>').html(message);\n\n jQuery('.modal-header .page-main-actions').after($wrapper);\n }\n });\n }\n },\n\n /**\n * Get selected variable directive.\n *\n * @returns {*}\n */\n getVariableCode: function () {\n var code = registry.get('variables_modal.variables_modal.variables.variable_selector')\n .selectedVariableCode(),\n directive = code;\n\n // processing switch here as content must contain only path/code without type\n if (typeof code !== 'undefined') {\n if (code.match('^default:')) {\n directive = configGenerator.processConfig(code.replace('default:', ''));\n } else if (code.match('^custom:')) {\n directive = customGenerator.processConfig(code.replace('custom:', ''));\n }\n\n return directive;\n }\n },\n\n /**\n * Get buttons configuration for slideout dialog.\n *\n * @param {Boolean} isEditMode\n *\n * @returns {Array}\n */\n getButtonsConfig: function (isEditMode) {\n\n var self = this,\n buttonsData;\n\n buttonsData = [\n {\n\n text: $t('Cancel'),\n 'class': 'action-scalable cancel',\n\n /**\n * @param {jQuery.Event} event\n */\n click: function (event) {\n this.closeModal(event);\n }\n },\n {\n\n text: isEditMode ? $t('Save') : $t('Insert Variable'),\n class: 'action-primary ' + (isEditMode ? '' : 'disabled'),\n attr: {\n 'id': 'insert_variable'\n },\n\n /**\n * Insert Variable\n */\n click: function () {\n self.insertVariable(self.getVariableCode());\n }\n }\n ];\n\n return buttonsData;\n },\n\n /**\n * Prepare variables row.\n *\n * @param {String} varValue\n * @param {*} varLabel\n * @return {String}\n * @deprecated This method isn't relevant after ui changes\n */\n prepareVariableRow: function (varValue, varLabel) {\n var value = varValue.replace(/\"/g, '"').replace(/'/g, '\\\\'');\n\n return '<a href=\"#\" onclick=\"' +\n this.insertFunction +\n '(\\'' +\n value +\n '\\');return false;\">' +\n varLabel +\n '</a>';\n },\n\n /**\n * Insert variable into WYSIWYG editor.\n *\n * @param {*} value\n * @return {Object}\n */\n insertVariable: function (value) {\n var windowId = this.dialogWindowId,\n textareaElm, scrollPos, wysiwygEditorFocused;\n\n jQuery('#' + windowId).modal('closeModal');\n textareaElm = $(this.textareaElementId);\n\n //to support switching between wysiwyg editors\n wysiwygEditorFocused = wysiwyg && wysiwyg.activeEditor();\n\n if (wysiwygEditorFocused && wysiwyg.get(this.textareaElementId)) {\n if (jQuery(this.selectedPlaceholder).hasClass('magento-placeholder')) {\n wysiwyg.setCaretOnElement(this.selectedPlaceholder, 1);\n }\n wysiwyg.insertContent(value, false);\n\n if (this.selectedPlaceholder && jQuery(this.selectedPlaceholder).hasClass('magento-placeholder')) {\n this.selectedPlaceholder.remove();\n }\n\n } else if (textareaElm) {\n scrollPos = textareaElm.scrollTop;\n updateElementAtCursor(textareaElm, value);\n textareaElm.focus();\n textareaElm.scrollTop = scrollPos;\n jQuery(textareaElm).trigger('change');\n textareaElm = null;\n }\n\n return this;\n }\n\n };\n\n window.MagentovariablePlugin = {\n editor: null,\n variables: null,\n textareaId: null,\n\n /**\n * Bind editor.\n *\n * @param {*} editor\n */\n setEditor: function (editor) {\n this.editor = editor;\n },\n\n /**\n * Load variables chooser.\n *\n * @param {String} url\n * @param {*} textareaId\n * @param {Object} selectedElement\n *\n * @return {Object}\n */\n loadChooser: function (url, textareaId, selectedElement) {\n this.textareaId = textareaId;\n\n new Ajax.Request(url, {\n parameters: {},\n onComplete: function (transport) {\n Variables.init(this.textareaId, 'MagentovariablePlugin.insertVariable', this.editor);\n Variables.isEditMode = !!this.getElementVariablePath(selectedElement);\n this.variablesContent = transport.responseText;\n Variables.openDialogWindow(this.variablesContent, selectedElement);\n Variables.initUiGrid();\n }.bind(this)\n });\n\n return this;\n },\n\n /**\n * Open variables chooser window.\n *\n * @param {*} variables\n * @deprecated This method isn't relevant after ui changes\n */\n openChooser: function (variables) {\n Variables.openVariableChooser(variables);\n },\n\n /**\n * Insert variable.\n *\n * @param {*} value\n *\n * @return {Object}\n */\n insertVariable: function (value) {\n if (this.textareaId) {\n Variables.init(this.textareaId);\n Variables.insertVariable(value);\n } else {\n Variables.closeDialogWindow();\n Variables.insertVariable(value);\n }\n\n return this;\n },\n\n /**\n * Get element variable path.\n *\n * @param {Object} element\n * @returns {String}\n */\n getElementVariablePath: function (element) {\n var type, code;\n\n if (!element || !jQuery(element).hasClass('magento-variable')) {\n return '';\n }\n type = jQuery(element).hasClass('magento-custom-var') ? 'custom' : 'default';\n code = Base64.idDecode(element.getAttribute('id'));\n\n return type + ':' + code;\n }\n };\n});\n","Magento_Variable/js/config-directive-generator.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 return _.extend({\n directiveTemplate: '{{config path=\"%s\"}}',\n\n /**\n * @param {String} path\n * @return {String}\n */\n processConfig: function (path) {\n return this.directiveTemplate.replace('%s', path);\n\n }\n\n });\n\n});\n","Magento_Variable/js/custom-directive-generator.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 return _.extend({\n directiveTemplate: '{{customVar code=%s}}',\n\n /**\n * @param {String} path\n * @return {String}\n */\n processConfig: function (path) {\n return this.directiveTemplate.replace('%s', path);\n }\n\n });\n\n});\n","Magento_Variable/js/grid/columns/radioselect.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'underscore',\n 'mage/translate',\n 'Magento_Ui/js/grid/columns/column',\n 'jquery'\n], function (_, $t, Column, jQuery) {\n 'use strict';\n\n return Column.extend({\n defaults: {\n bodyTmpl: 'Magento_Variable/grid/cells/radioselect',\n draggable: false,\n sortable: false,\n selectedVariableCode: null,\n selectedVariableType: null\n },\n\n /**\n * Calls 'initObservable' of parent\n *\n * @returns {Object} Chainable.\n */\n initObservable: function () {\n this._super().observe(['selectedVariableCode']);\n\n return this;\n },\n\n /**\n * Remove disable class from Insert Variable button after Variable has been chosen.\n *\n * @return {Boolean}\n */\n selectVariable: function () {\n if (jQuery('#insert_variable').hasClass('disabled')) {\n jQuery('#insert_variable').removeClass('disabled');\n }\n\n return true;\n }\n });\n});\n","Magento_Security/js/escaper.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * A loose JavaScript version of Magento\\Framework\\Escaper\n *\n * Due to differences in how XML/HTML is processed in PHP vs JS there are a couple of minor differences in behavior\n * from the PHP counterpart.\n *\n * The first difference is that the default invocation of escapeHtml without allowedTags will double-escape existing\n * entities as the intention of such an invocation is that the input isn't supposed to contain any HTML.\n *\n * The second difference is that escapeHtml will not escape quotes. Since the input is actually being processed by the\n * DOM there is no chance of quotes being mixed with HTML syntax. And, since escapeHtml is not\n * intended to be used with raw injection into a HTML attribute, this is acceptable.\n *\n * @api\n */\ndefine([], function () {\n 'use strict';\n\n return {\n neverAllowedElements: ['script', 'img', 'embed', 'iframe', 'video', 'source', 'object', 'audio'],\n generallyAllowedAttributes: ['id', 'class', 'href', 'title', 'style'],\n forbiddenAttributesByElement: {\n a: ['style']\n },\n\n /**\n * Escape a string for safe injection into HTML\n *\n * @param {String} data\n * @param {Array|null} allowedTags\n * @returns {String}\n */\n escapeHtml: function (data, allowedTags) {\n var domParser = new DOMParser(),\n fragment = domParser.parseFromString('<div></div>', 'text/html');\n\n fragment = fragment.body.childNodes[0];\n allowedTags = typeof allowedTags === 'object' && allowedTags.length ? allowedTags : null;\n\n if (allowedTags) {\n fragment.innerHTML = data || '';\n allowedTags = this._filterProhibitedTags(allowedTags);\n\n this._removeComments(fragment);\n this._removeNotAllowedElements(fragment, allowedTags);\n this._removeNotAllowedAttributes(fragment);\n\n return fragment.innerHTML;\n }\n\n fragment.textContent = data || '';\n\n return fragment.innerHTML;\n },\n\n /**\n * Remove the always forbidden tags from a list of provided tags\n *\n * @param {Array} tags\n * @returns {Array}\n * @private\n */\n _filterProhibitedTags: function (tags) {\n return tags.filter(function (n) {\n return this.neverAllowedElements.indexOf(n) === -1;\n }.bind(this));\n },\n\n /**\n * Remove comment nodes from the given node\n *\n * @param {Node} node\n * @private\n */\n _removeComments: function (node) {\n var treeWalker = node.ownerDocument.createTreeWalker(\n node,\n NodeFilter.SHOW_COMMENT,\n function () {\n return NodeFilter.FILTER_ACCEPT;\n },\n false\n ),\n nodesToRemove = [];\n\n while (treeWalker.nextNode()) {\n nodesToRemove.push(treeWalker.currentNode);\n }\n\n nodesToRemove.forEach(function (nodeToRemove) {\n nodeToRemove.parentNode.removeChild(nodeToRemove);\n });\n },\n\n /**\n * Strip the given node of all disallowed tags while permitting any nested text nodes\n *\n * @param {Node} node\n * @param {Array|null} allowedTags\n * @private\n */\n _removeNotAllowedElements: function (node, allowedTags) {\n var treeWalker = node.ownerDocument.createTreeWalker(\n node,\n NodeFilter.SHOW_ELEMENT,\n function (currentNode) {\n return allowedTags.indexOf(currentNode.nodeName.toLowerCase()) === -1 ?\n NodeFilter.FILTER_ACCEPT\n // SKIP instead of REJECT because REJECT also rejects child nodes\n : NodeFilter.FILTER_SKIP;\n },\n false\n ),\n nodesToRemove = [];\n\n while (treeWalker.nextNode()) {\n if (allowedTags.indexOf(treeWalker.currentNode.nodeName.toLowerCase()) === -1) {\n nodesToRemove.push(treeWalker.currentNode);\n }\n }\n\n nodesToRemove.forEach(function (nodeToRemove) {\n nodeToRemove.parentNode.replaceChild(\n node.ownerDocument.createTextNode(nodeToRemove.textContent),\n nodeToRemove\n );\n });\n },\n\n /**\n * Remove any invalid attributes from the given node\n *\n * @param {Node} node\n * @private\n */\n _removeNotAllowedAttributes: function (node) {\n var treeWalker = node.ownerDocument.createTreeWalker(\n node,\n NodeFilter.SHOW_ELEMENT,\n function () {\n return NodeFilter.FILTER_ACCEPT;\n },\n false\n ),\n i,\n attribute,\n nodeName,\n attributesToRemove = [];\n\n while (treeWalker.nextNode()) {\n for (i = 0; i < treeWalker.currentNode.attributes.length; i++) {\n attribute = treeWalker.currentNode.attributes[i];\n nodeName = treeWalker.currentNode.nodeName.toLowerCase();\n\n if (this.generallyAllowedAttributes.indexOf(attribute.name) === -1 || // eslint-disable-line max-depth,max-len\n this._checkHrefValue(attribute) ||\n this.forbiddenAttributesByElement[nodeName] &&\n this.forbiddenAttributesByElement[nodeName].indexOf(attribute.name) !== -1\n ) {\n attributesToRemove.push(attribute);\n }\n }\n }\n\n attributesToRemove.forEach(function (attributeToRemove) {\n attributeToRemove.ownerElement.removeAttribute(attributeToRemove.name);\n });\n },\n\n /**\n * Check that attribute contains script content\n *\n * @param {Object} attribute\n * @private\n */\n _checkHrefValue: function (attribute) {\n return attribute.nodeName === 'href' && attribute.nodeValue.startsWith('javascript');\n }\n };\n});\n","Magento_Security/js/confirm-redirect.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n/*eslint-disable no-undef*/\ndefine(\n ['jquery'],\n function ($) {\n 'use strict';\n\n return function (config, element) {\n $(element).on('click', config, function () {\n confirmSetLocation(config.message, config.url);\n });\n };\n }\n);\n","Magento_Security/js/system/config/session-size.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'jquery',\n 'mage/translate',\n 'Magento_Ui/js/modal/confirm',\n 'domReady!'\n], function ($, $t, confirm) {\n 'use strict';\n\n return function (config, inputEl) {\n var $inputEl = $(inputEl);\n\n $inputEl.on('blur', function () {\n var inputVal = parseInt($inputEl.val(), 10);\n\n if (inputVal < 256000) {\n confirm({\n title: $t(config.modalTitleText),\n content: $t(config.modalContentBody),\n buttons: [{\n text: $t('No'),\n class: 'action-secondary action-dismiss',\n\n /**\n * Close modal and trigger 'cancel' action on click\n */\n click: function (event) {\n this.closeModal(event);\n }\n }, {\n text: $t('Yes'),\n class: 'action-primary action-accept',\n\n /**\n * Close modal and trigger 'confirm' action on click\n */\n click: function (event) {\n this.closeModal(event, true);\n }\n }],\n actions: {\n\n /**\n * Revert back to original value\n */\n cancel: function () {\n $inputEl.val(256000);\n }\n }\n });\n }\n });\n };\n});\n","Magento_PageBuilder/js/widget-initializer.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 'jquery',\n 'mage/apply/main',\n 'Magento_Ui/js/lib/view/utils/dom-observer'\n], function (_, $, mage, domObserver) {\n 'use strict';\n\n /**\n * Initializes components assigned to HTML elements.\n *\n *\n * @param {HTMLElement} el\n * @param {Array} data\n * @param {Object} breakpoints\n * @param {Object} currentViewport\n */\n function initializeWidget(el, data, breakpoints, currentViewport) {\n _.each(data, function (config, component) {\n config = config || {};\n config.breakpoints = breakpoints;\n config.currentViewport = currentViewport;\n mage.applyFor(el, config, component);\n });\n }\n\n return function (data, contextElement) {\n _.each(data.config, function (componentConfiguration, elementPath) {\n domObserver.get(\n elementPath,\n function (element) {\n var $element = $(element);\n\n if (contextElement) {\n $element = $(contextElement).find(element);\n }\n\n if ($element.length) {\n initializeWidget($element, componentConfiguration, data.breakpoints, data.currentViewport);\n }\n }\n );\n });\n };\n});\n","Magento_PageBuilder/js/events.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine(['uiEvents'], function (uiEvents) {\n 'use strict';\n\n return {\n\n /**\n * Calls callback when name event is triggered\n *\n * @param {String} events\n * @param {Function} callback\n * @param {Function} ns\n * @return {Object}\n */\n on: function (events, callback, ns) {\n uiEvents.on('pagebuilder:' + events, callback, 'pagebuilder:' + ns);\n\n return this;\n },\n\n /**\n * Removed callback from listening to target event\n *\n * @param {String} ns\n * @return {Object}\n */\n off: function (ns) {\n uiEvents.off('pagebuilder:' + ns);\n\n return this;\n },\n\n /**\n * Triggers event and executes all attached callbacks\n *\n * @param {String} name\n * @param {any} args\n * @returns {Boolean}\n */\n trigger: function (name, args) {\n return uiEvents.trigger('pagebuilder:' + name, args);\n }\n };\n});\n","Magento_PageBuilder/js/stage.js":"/*eslint-disable */\n/* jscs:disable */\ndefine([\"jquery\", \"knockout\", \"Magento_PageBuilder/js/events\", \"Magento_PageBuilder/js/resource/jquery/ui/jquery.ui.touch-punch\", \"mageUtils\", \"underscore\", \"Magento_PageBuilder/js/binding/sortable\", \"Magento_PageBuilder/js/collection\", \"Magento_PageBuilder/js/data-store\", \"Magento_PageBuilder/js/drag-drop/matrix\", \"Magento_PageBuilder/js/master-format/render\", \"Magento_PageBuilder/js/stage-builder\", \"Magento_PageBuilder/js/utils/editor\", \"Magento_PageBuilder/js/utils/promise-deferred\"], function (_jquery, _knockout, _events, _jqueryUi, _mageUtils, _underscore, _sortable, _collection, _dataStore, _matrix, _render, _stageBuilder, _editor, _promiseDeferred) {\n /**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n var Stage = /*#__PURE__*/function () {\n \"use strict\";\n\n /**\n * We always complete a single render when the stage is first loaded, so we can set the lock when the stage is\n * created. The lock is used to halt the parent forms submission when Page Builder is rendering.\n */\n\n /**\n * Debounce the applyBindings call by 500ms to stop duplicate calls\n *\n * @type {(() => void) & _.Cancelable}\n */\n\n /**\n * @param {PageBuilderInterface} pageBuilder\n * @param {ContentTypeCollectionInterface} rootContainer\n */\n function Stage(pageBuilder, rootContainer) {\n var _this = this;\n\n this.loading = _knockout.observable(true);\n this.showBorders = _knockout.observable(false);\n this.interacting = _knockout.observable(false);\n this.userSelect = _knockout.observable(true);\n this.focusChild = _knockout.observable(false);\n this.dataStore = new _dataStore();\n this.afterRenderDeferred = (0, _promiseDeferred)();\n this.renderingLocks = [];\n this.template = \"Magento_PageBuilder/content-type/preview\";\n this.collection = new _collection();\n this.applyBindingsDebounce = _underscore.debounce(function (renderId) {\n _this.render.applyBindings(_this.rootContainer).then(function (renderedOutput) {\n if (_this.lastRenderId === renderId) {\n _events.trigger(\"stage:\" + _this.id + \":masterFormatRenderAfter\", {\n value: (0, _editor.unescapeDoubleQuoteWithinWidgetDirective)(renderedOutput)\n });\n\n _this.renderingLocks.forEach(function (lock) {\n lock.resolve(renderedOutput);\n });\n }\n }).catch(function (error) {\n if (error) {\n console.error(error);\n }\n });\n }, 500);\n this.pageBuilder = pageBuilder;\n this.id = pageBuilder.id;\n this.render = new _render(pageBuilder.id);\n this.rootContainer = rootContainer;\n (0, _matrix.generateAllowedParents)(); // Fire an event after the DOM has rendered\n\n this.afterRenderDeferred.promise.then(function () {\n _this.render.setupChannel();\n\n _events.trigger(\"stage:\" + _this.id + \":renderAfter\", {\n stage: _this\n });\n }); // Wait for the stage to be built alongside the stage being rendered\n\n Promise.all([(0, _stageBuilder)(this, (0, _editor.escapeDoubleQuoteWithinWidgetDirective)(this.pageBuilder.initialValue)), this.afterRenderDeferred.promise]).then(this.ready.bind(this)).catch(function (error) {\n console.error(error);\n });\n }\n /**\n * Get template.\n *\n * @returns {string}\n */\n\n\n var _proto = Stage.prototype;\n\n _proto.getTemplate = function getTemplate() {\n return this.template;\n }\n /**\n * The stage has been initiated fully and is ready\n */\n ;\n\n _proto.ready = function ready() {\n _events.trigger(\"stage:\" + this.id + \":readyAfter\", {\n stage: this\n });\n\n this.loading(false);\n this.initListeners(); // Ensure we complete an initial save of the data within the stage once we're ready\n\n _events.trigger(\"stage:updateAfter\", {\n stageId: this.id\n });\n }\n /**\n * Init listeners\n */\n ;\n\n _proto.initListeners = function initListeners() {\n var _this2 = this;\n\n this.collection.getChildren().subscribe(function () {\n return _events.trigger(\"stage:updateAfter\", {\n stageId: _this2.id\n });\n }); // ContentType being removed from container\n\n _events.on(\"contentType:removeAfter\", function (args) {\n if (args.stageId === _this2.id) {\n _this2.onContentTypeRemoved(args);\n }\n }); // Any store state changes trigger a stage update event\n\n\n this.dataStore.subscribe(function () {\n return _events.trigger(\"stage:updateAfter\", {\n stageId: _this2.id\n });\n }); // Watch for stage update events & manipulations to the store, debounce for 50ms as multiple stage changes\n // can occur concurrently.\n\n _events.on(\"stage:updateAfter\", function (args) {\n if (args.stageId === _this2.id) {\n // Create the rendering lock straight away\n _this2.createLock();\n\n var renderId = _mageUtils.uniqueid();\n\n _this2.lastRenderId = renderId;\n\n _this2.applyBindingsDebounce(renderId);\n }\n });\n\n var interactionLevel = 0;\n\n _events.on(\"stage:interactionStart\", function () {\n ++interactionLevel;\n\n _this2.interacting(true);\n });\n\n _events.on(\"stage:interactionStop\", function (args) {\n var forced = _underscore.isObject(args) && args.force === true;\n interactionLevel = Math.max(interactionLevel - 1, 0);\n\n if (interactionLevel === 0 || forced) {\n _this2.interacting(false);\n\n if (forced) {\n interactionLevel = 0;\n }\n }\n });\n\n _events.on(\"stage:childFocusStart\", function () {\n return _this2.focusChild(true);\n });\n\n _events.on(\"stage:childFocusStop\", function () {\n return _this2.focusChild(false);\n });\n }\n /**\n * Create a new lock for rendering\n */\n ;\n\n _proto.createLock = function createLock() {\n this.renderingLocks.push(_jquery.Deferred());\n }\n /**\n * On content type removed\n *\n * @param params\n */\n ;\n\n _proto.onContentTypeRemoved = function onContentTypeRemoved(params) {\n if (params.parentContentType) {\n params.parentContentType.removeChild(params.contentType);\n }\n };\n\n return Stage;\n }();\n\n Stage.rootContainerName = \"root-container\";\n return Stage;\n});\n//# sourceMappingURL=stage.js.map","Magento_PageBuilder/js/content-type.js":"/*eslint-disable */\n/* jscs:disable */\ndefine([\"Magento_PageBuilder/js/events\", \"mageUtils\", \"underscore\", \"Magento_PageBuilder/js/config\", \"Magento_PageBuilder/js/data-store\"], function (_events, _mageUtils, _underscore, _config, _dataStore) {\n /**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n var ContentType = /*#__PURE__*/function () {\n \"use strict\";\n\n /**\n * @param {ContentTypeInterface} parentContentType\n * @param {ContentTypeConfigInterface} config\n * @param {string} stageId\n */\n function ContentType(parentContentType, config, stageId) {\n this.id = _mageUtils.uniqueid();\n this.dataStore = new _dataStore();\n this.dataStores = {};\n this.dropped = false;\n this.parentContentType = parentContentType;\n this.config = config;\n this.stageId = stageId;\n this.initDataStores();\n this.bindEvents();\n }\n /**\n * Destroys current instance\n */\n\n\n var _proto = ContentType.prototype;\n\n _proto.destroy = function destroy() {\n var params = {\n contentType: this,\n index: this.parentContentType ? this.parentContentType.getChildren().indexOf(this) : null,\n parentContentType: this.parentContentType,\n stageId: this.stageId\n };\n this.preview ? this.preview.destroy() : this.content.destroy();\n\n _events.trigger(\"contentType:removeAfter\", params);\n\n _events.trigger(this.config.name + \":removeAfter\", params);\n }\n /**\n * Get viewport fields.\n *\n * @param {string} viewport\n * @param {DataObject} data\n */\n ;\n\n _proto.getViewportFields = function getViewportFields(viewport, data) {\n var viewportConfig = this.config.breakpoints[viewport];\n\n if (!viewportConfig) {\n return {};\n }\n\n return viewportConfig.fields[data.appearance + \"-appearance\"] || viewportConfig.fields.default;\n }\n /**\n * Get data stores states only for viewport fields\n */\n ;\n\n _proto.getDataStoresStates = function getDataStoresStates() {\n var _this = this;\n\n var result = {};\n\n _underscore.each(this.dataStores, function (dataStore, name) {\n if (_config.getConfig(\"defaultViewport\") !== name) {\n var dataStoreFields = _underscore.keys(_this.getDiffViewportFields(name, dataStore.getState()));\n\n result[name] = _underscore.pick(dataStore.getState(), dataStoreFields);\n } else {\n result[name] = dataStore.getState();\n }\n });\n\n return result;\n }\n /**\n * Set data to dataStore from dataStores base on current viewport.\n *\n * @param {String} viewport\n */\n ;\n\n _proto.setViewportDataToDataStore = function setViewportDataToDataStore(viewport) {\n var defaultViewport = _config.getConfig(\"defaultViewport\");\n\n var currentViewportState = this.dataStores[viewport].getState();\n var defaultViewportState = this.dataStores[defaultViewport].getState();\n\n var viewportFields = _underscore.keys(this.getDiffViewportFields(viewport, currentViewportState)); // Filter viewport specific data for states\n\n\n this.dataStore.setState(_underscore.extend({}, defaultViewportState, _underscore.pick(currentViewportState, viewportFields)));\n };\n\n _proto.bindEvents = function bindEvents() {\n var _this2 = this;\n\n var eventName = this.config.name + \":\" + this.id + \":updateAfter\";\n var paramObj = {};\n paramObj[this.id] = this;\n this.dataStore.subscribe(function (state) {\n var defaultViewport = _config.getConfig(\"defaultViewport\");\n\n var viewport = _config.getConfig(\"viewport\") || defaultViewport;\n\n if (viewport !== defaultViewport) {\n var viewportFields = _underscore.keys(_this2.getViewportFields(viewport, state));\n\n var diffViewportFields = _underscore.keys(_this2.getDiffViewportFields(viewport, state));\n\n _this2.dataStores[defaultViewport].setState(_underscore.extend(_this2.dataStores[defaultViewport].getState(), _underscore.omit(state, viewportFields)));\n\n _this2.dataStores[viewport].setState(_underscore.extend(_this2.dataStores[viewport].getState(), _underscore.pick(state, diffViewportFields)));\n } else {\n _this2.dataStores[viewport].setState(state);\n }\n\n return _events.trigger(eventName, paramObj);\n });\n this.dataStore.subscribe(function () {\n return _events.trigger(\"stage:updateAfter\", {\n stageId: _this2.stageId\n });\n });\n\n _events.on(\"stage:\" + this.stageId + \":viewportChangeAfter\", this.onViewportSwitch.bind(this));\n }\n /**\n * Change data stores on viewport change.\n * @param {Object} args\n */\n ;\n\n _proto.onViewportSwitch = function onViewportSwitch(args) {\n this.setViewportDataToDataStore(args.viewport);\n }\n /**\n * Init data store for each viewport.\n */\n ;\n\n _proto.initDataStores = function initDataStores() {\n var _this3 = this;\n\n _underscore.each(_config.getConfig(\"viewports\"), function (value, name) {\n _this3.dataStores[name] = new _dataStore();\n });\n }\n /**\n * Get viewport fields that is different from default.\n *\n * @param {string} viewport\n * @param {DataObject} data\n */\n ;\n\n _proto.getDiffViewportFields = function getDiffViewportFields(viewport, data) {\n var fields = this.getViewportFields(viewport, data);\n\n var defaultData = this.dataStores[_config.getConfig(\"defaultViewport\")].getState();\n\n var excludedFields = [];\n\n _underscore.each(fields, function (field, key) {\n var comparison = _mageUtils.compare(data[key], defaultData[key]);\n\n var isEmpty = !_underscore.find(comparison.changes, function (change) {\n return !_underscore.isEmpty(change.oldValue);\n });\n\n if (comparison.equal || isEmpty) {\n excludedFields.push(key);\n }\n });\n\n return _underscore.omit(fields, excludedFields);\n };\n\n return ContentType;\n }();\n\n return ContentType;\n});\n//# sourceMappingURL=content-type.js.map","Magento_PageBuilder/js/content-type-toolbar.js":"/*eslint-disable */\n/* jscs:disable */\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\ndefine([\"jquery\", \"knockout\", \"Magento_PageBuilder/js/events\", \"Magento_PageBuilder/js/utils/check-stage-full-screen\", \"Magento_PageBuilder/js/utils/pagebuilder-header-height\", \"Magento_PageBuilder/js/utils/promise-deferred\"], function (_jquery, _knockout, _events, _checkStageFullScreen, _pagebuilderHeaderHeight, _promiseDeferred) {\n /**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n /**\n * @api\n */\n var Toolbar = /*#__PURE__*/function () {\n \"use strict\";\n\n /**\n * Toolbar Options constructor\n *\n * @param preview\n * @param options\n */\n function Toolbar(preview, options) {\n this.options = _knockout.observableArray([]);\n this.afterRenderDeferred = (0, _promiseDeferred)();\n this.preview = preview;\n this.options(options);\n }\n /**\n * Toolbar template\n *\n * @returns {string}\n */\n\n\n var _proto = Toolbar.prototype;\n\n /**\n * On render init the toolbar\n *\n * @param {Element} element\n */\n _proto.afterRender = function afterRender(element) {\n this.element = element;\n this.afterRenderDeferred.resolve(element);\n }\n /**\n * Upon clicking the option update the value as directed\n * When user toggles the option off, set the value back to default\n *\n * @param {OptionInterface} option\n * @param {ValueInterface} value\n */\n ;\n\n _proto.onOptionClick = function onOptionClick(option, value) {\n var appearance = this.preview.appearance() + \"-appearance\";\n var fields = this.preview.config.fields[appearance] || this.preview.config.fields.default;\n var defaultValue = fields[option.key].default;\n var currentValue = this.preview.contentType.dataStore.get(option.key);\n this.preview.updateData(option.key, currentValue === value.value ? defaultValue : value.value);\n }\n /**\n * Set state based on toolbar focusin event for the preview\n *\n * @param {ContentTypeToolbarPreviewInterface} context\n * @param {Event} event\n */\n ;\n\n _proto.onFocusIn = function onFocusIn(context, event) {\n var currentContentTypeTarget = context.toolbar.getCurrentContentTypeTarget();\n var toolbarOptions = currentContentTypeTarget.find(\".pagebuilder-toolbar-options\");\n var currentContentTypeTargetClientRectTop = currentContentTypeTarget[0].getBoundingClientRect().top - (0, _pagebuilderHeaderHeight)(context.contentType.stageId); // Change toolbar orientation if overflow on full screen mode\n\n if ((0, _checkStageFullScreen)(context.contentType.stageId) && currentContentTypeTargetClientRectTop < toolbarOptions.outerHeight()) {\n context.toolbar.observer = new MutationObserver(function () {\n toolbarOptions.css(\"transform\", \"translateY(\" + currentContentTypeTarget.outerHeight() + \"px)\");\n });\n context.toolbar.observer.observe(currentContentTypeTarget[0], {\n attributes: true,\n childList: true,\n subtree: true\n });\n toolbarOptions.css(\"transform\", \"translateY(\" + currentContentTypeTarget.outerHeight() + \"px)\");\n } else {\n toolbarOptions.css(\"transform\", \"translateY(-100%)\");\n }\n\n (0, _jquery)(currentContentTypeTarget).addClass(\"pagebuilder-toolbar-active\");\n\n _events.trigger(\"stage:interactionStart\");\n }\n /**\n * Set state based on toolbar focusout event for the preview\n *\n * @param {ContentTypeToolbarPreviewInterface} context\n * @param {Event} event\n */\n ;\n\n _proto.onFocusOut = function onFocusOut(context, event) {\n var currentContentTypeTarget = context.toolbar.getCurrentContentTypeTarget();\n currentContentTypeTarget.removeClass(\"pagebuilder-toolbar-active\");\n currentContentTypeTarget.find(\".pagebuilder-toolbar-options\").css(\"transform\", \"\");\n\n if (typeof context.toolbar.observer !== \"undefined\") {\n context.toolbar.observer.disconnect();\n }\n\n _events.trigger(\"stage:interactionStop\");\n }\n /**\n * Get fixed toolbar container element referenced as selector in wysiwyg adapter settings\n *\n * @returns {jQuery}\n */\n ;\n\n _proto.getCurrentContentTypeTarget = function getCurrentContentTypeTarget() {\n return (0, _jquery)(\"#\" + this.preview.contentType.id).find(\".pagebuilder-content-type\");\n };\n\n _createClass(Toolbar, [{\n key: \"template\",\n get: function get() {\n return \"Magento_PageBuilder/content-type-toolbar\";\n }\n }]);\n\n return Toolbar;\n }();\n /**\n * Preview interface for preview instances implementation the toolbar functionality\n */\n\n\n return Toolbar;\n});\n//# sourceMappingURL=content-type-toolbar.js.map","Magento_PageBuilder/js/content-type-factory.js":"/*eslint-disable */\n/* jscs:disable */\ndefine([\"Magento_PageBuilder/js/events\", \"underscore\", \"Magento_PageBuilder/js/config\", \"Magento_PageBuilder/js/content-type/master-factory\", \"Magento_PageBuilder/js/content-type/preview-factory\", \"Magento_PageBuilder/js/utils/loader\"], function (_events, _underscore, _config, _masterFactory, _previewFactory, _loader) {\n /**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n /**\n * Create new content type\n *\n * @param {ContentTypeConfigInterface} config\n * @param {ContentTypeInterface} parentContentType\n * @param {string} stageId\n * @param {object} data\n * @param {number} childrenLength\n * * @param {object} viewportsData\n * @returns {Promise<ContentTypeInterface>}\n * @api\n */\n function createContentType(config, parentContentType, stageId, data, childrenLength, viewportsData) {\n if (data === void 0) {\n data = {};\n }\n\n if (childrenLength === void 0) {\n childrenLength = 0;\n }\n\n if (viewportsData === void 0) {\n viewportsData = {};\n }\n\n return new Promise(function (resolve, reject) {\n (0, _loader)([config.component], function (contentTypeComponent) {\n try {\n var _contentType = new contentTypeComponent(parentContentType, config, stageId);\n\n var viewFactory = _config.getMode() === \"Preview\" ? _previewFactory : _masterFactory;\n viewFactory(_contentType, config).then(function (viewComponent) {\n var viewName = _config.getMode() === \"Preview\" ? \"preview\" : \"content\"; // @ts-ignore\n\n _contentType[viewName] = viewComponent;\n assignDataToDataStores(_contentType, config, data, viewportsData);\n resolve(_contentType);\n }).catch(function (error) {\n reject(error);\n });\n } catch (error) {\n reject(\"Error within component (\" + config.component + \") for \" + config.name + \".\");\n console.error(error);\n }\n }, function (error) {\n reject(\"Unable to load component (\" + config.component + \") for \" + config.name + \". Please check component exists\" + \" and content type configuration is correct.\");\n console.error(error);\n });\n }).then(function (contentType) {\n _events.trigger(\"contentType:createAfter\", {\n id: contentType.id,\n contentType: contentType\n });\n\n _events.trigger(config.name + \":createAfter\", {\n id: contentType.id,\n contentType: contentType\n });\n\n fireContentTypeReadyEvent(contentType, childrenLength);\n return contentType;\n }).catch(function (error) {\n console.error(error);\n return null;\n });\n }\n\n function assignDataToDataStores(contentType, config, data, viewportsData) {\n var defaultData = prepareData(config, data);\n\n var currentViewport = _config.getConfig(\"viewport\") || _config.getConfig(\"defaultViewport\");\n\n _underscore.each(_config.getConfig(\"viewports\"), function (viewport, name) {\n var viewportData = {};\n var breakpoint = config.breakpoints[name];\n var viewportConfig = breakpoint && breakpoint.fields ? _underscore.extend({}, breakpoint, {\n name: config.name\n }) : {};\n\n if (!_underscore.isEmpty(viewportConfig)) {\n viewportsData[name] = viewportsData[name] || {};\n viewportData = prepareData(viewportConfig, viewportsData[name]);\n }\n\n contentType.dataStores[name].setState(_underscore.extend({}, defaultData, viewportData));\n });\n\n contentType.setViewportDataToDataStore(currentViewport);\n }\n /**\n * Merge defaults and content type data\n *\n * @param {ContentTypeConfigInterface} config\n * @param {object} data\n * @returns {any}\n */\n\n\n function prepareData(config, data) {\n var appearance = data.appearance + \"-appearance\";\n var fields = config.fields[appearance] || config.fields.default;\n var defaults = prepareDefaults(fields || {}); // Set all content types to be displayed by default\n\n defaults.display = true;\n return _underscore.extend(defaults, data, {\n name: config.name\n });\n }\n /**\n * Prepare the default values for fields within the form\n *\n * @param {ConfigFieldInterface} fields\n * @returns {FieldDefaultsInterface}\n */\n\n\n function prepareDefaults(fields) {\n if (_underscore.isEmpty(fields)) {\n return {};\n }\n\n return _underscore.mapObject(fields, function (field) {\n if (!_underscore.isUndefined(field.default)) {\n return field.default;\n } else if (_underscore.isObject(field)) {\n return prepareDefaults(field);\n }\n });\n }\n /**\n * A content type is ready once all of its children have mounted\n *\n * @param {ContentTypeInterface | ContentTypeCollectionInterface} contentType\n * @param {number} childrenLength\n */\n\n\n function fireContentTypeReadyEvent(contentType, childrenLength) {\n if (childrenLength === void 0) {\n childrenLength = 0;\n }\n\n var fire = function fire() {\n var params = {\n id: contentType.id,\n contentType: contentType,\n expectChildren: childrenLength\n };\n\n _events.trigger(\"contentType:mountAfter\", params);\n\n _events.trigger(contentType.config.name + \":mountAfter\", params);\n };\n\n if (childrenLength === 0) {\n fire();\n } else {\n var mountCounter = 0;\n\n _events.on(\"contentType:mountAfter\", function (args) {\n if (args.contentType.parentContentType.id === contentType.id) {\n mountCounter++;\n\n if (mountCounter === childrenLength) {\n mountCounter = 0;\n fire();\n\n _events.off(\"contentType:\" + contentType.id + \":mountAfter\");\n }\n }\n }, \"contentType:\" + contentType.id + \":mountAfter\");\n }\n }\n /**\n * @api\n */\n\n\n return createContentType;\n});\n//# sourceMappingURL=content-type-factory.js.map","Magento_PageBuilder/js/content-type-collection.js":"/*eslint-disable */\n/* jscs:disable */\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\nfunction _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); }\n\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n\ndefine([\"Magento_PageBuilder/js/events\", \"underscore\", \"Magento_PageBuilder/js/collection\", \"Magento_PageBuilder/js/content-type\"], function (_events, _underscore, _collection, _contentType) {\n /**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n var ContentTypeCollection = /*#__PURE__*/function (_contentType2) {\n \"use strict\";\n\n _inheritsLoose(ContentTypeCollection, _contentType2);\n\n /**\n * @param {ContentTypeInterface} parentContentType\n * @param {ContentTypeConfigInterface} config\n * @param {string} stageId\n */\n function ContentTypeCollection(parentContentType, config, stageId) {\n var _this;\n\n _this = _contentType2.call(this, parentContentType, config, stageId) || this;\n _this.collection = new _collection();\n\n _this.collection.getChildren().subscribe(function () {\n return _events.trigger(\"stage:updateAfter\", {\n stageId: _this.stageId\n });\n });\n\n return _this;\n }\n /**\n * Return the children of the current element\n *\n * @returns {KnockoutObservableArray<ContentTypeInterface | ContentTypeCollectionInterface>}\n */\n\n\n var _proto = ContentTypeCollection.prototype;\n\n _proto.getChildren = function getChildren() {\n return this.collection.getChildren();\n }\n /**\n * Add a child into the observable array\n *\n * @param {ContentTypeInterface | ContentTypeCollectionInterface} child\n * @param {number} index\n */\n ;\n\n _proto.addChild = function addChild(child, index) {\n child.parentContentType = this;\n this.collection.addChild(child, index); // Trigger a mount event when a child is added into a container content type, meaning it'll be re-rendered\n\n _underscore.defer(function () {\n _events.trigger(\"contentType:mountAfter\", {\n id: child.id,\n contentType: child\n });\n\n _events.trigger(child.config.name + \":mountAfter\", {\n id: child.id,\n contentType: child\n });\n });\n }\n /**\n * Remove a child from the observable array\n *\n * @param {ContentTypeInterface} child\n */\n ;\n\n _proto.removeChild = function removeChild(child) {\n this.collection.removeChild(child);\n }\n /**\n * Destroys current instance and all children\n */\n ;\n\n _proto.destroy = function destroy() {\n [].concat(this.getChildren()()).forEach(function (contentType) {\n contentType.destroy();\n });\n\n _contentType2.prototype.destroy.call(this);\n }\n /**\n * Set the children observable array into the class\n *\n * @param {KnockoutObservableArray<ContentTypeInterface>} children\n */\n ;\n\n _proto.setChildren = function setChildren(children) {\n this.collection.setChildren(children);\n };\n\n _createClass(ContentTypeCollection, [{\n key: \"children\",\n get: function get() {\n return this.collection.getChildren();\n }\n }]);\n\n return ContentTypeCollection;\n }(_contentType);\n\n return ContentTypeCollection;\n});\n//# sourceMappingURL=content-type-collection.js.map","Magento_PageBuilder/js/config.js":"/*eslint-disable */\n/* jscs:disable */\ndefine([\"underscore\"], function (_underscore) {\n /**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n var Config = /*#__PURE__*/function () {\n \"use strict\";\n\n function Config() {}\n\n /**\n * Set the initial config\n *\n * @param config\n */\n Config.setConfig = function setConfig(config) {\n Config.config = _underscore.extend(Config.config, config);\n }\n /**\n * Set the current instances mode, this differs between preview or master depending on whether we're rendering the\n * admins preview or rendering the master format.\n *\n * @param {\"Preview\" | \"Master\"} mode\n */\n ;\n\n Config.setMode = function setMode(mode) {\n Config.mode = mode;\n }\n /**\n * Retrieve the current instances mode\n */\n ;\n\n Config.getMode = function getMode() {\n return Config.mode;\n }\n /**\n * Retrieve the init config\n *\n * @param {string} key\n * @returns {T}\n */\n ;\n\n Config.getConfig = function getConfig(key) {\n if (key) {\n if (typeof Config.config[key] !== \"undefined\") {\n return Config.config[key];\n }\n\n return null;\n }\n\n return Config.config;\n }\n /**\n * Retrieve a content type from the configuration\n *\n * @param {string} contentType\n * @returns {any}\n */\n ;\n\n Config.getContentTypeConfig = function getContentTypeConfig(contentType) {\n if (typeof Config.getConfig(\"content_types\")[contentType] !== \"undefined\") {\n return Config.getConfig(\"content_types\")[contentType];\n }\n\n return null;\n };\n\n return Config;\n }();\n\n Config.config = {\n dataContentTypeAttributeName: \"data-content-type\",\n bodyId: \"html-body\"\n };\n return Config;\n});\n//# sourceMappingURL=config.js.map","Magento_PageBuilder/js/stage-builder.js":"/*eslint-disable */\n/* jscs:disable */\ndefine([\"mage/translate\", \"Magento_PageBuilder/js/events\", \"Magento_Ui/js/modal/alert\", \"underscore\", \"Magento_PageBuilder/js/config\", \"Magento_PageBuilder/js/content-type-collection\", \"Magento_PageBuilder/js/content-type-factory\", \"Magento_PageBuilder/js/content-type/appearance-config\", \"Magento_PageBuilder/js/content-type/style-registry\", \"Magento_PageBuilder/js/master-format/validator\", \"Magento_PageBuilder/js/utils/directives\", \"Magento_PageBuilder/js/utils/loader\", \"Magento_PageBuilder/js/utils/object\"], function (_translate, _events, _alert, _, _config, _contentTypeCollection, _contentTypeFactory, _appearanceConfig, _styleRegistry, _validator, _directives, _loader, _object) {\n function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== \"function\") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }\n\n /**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n /**\n * Build the stage with the provided value\n *\n * @param {stage} stage\n * @param {string} value\n * @returns {Promise<void>}\n */\n function buildFromContent(stage, value) {\n var stageDocument = new DOMParser().parseFromString(value, \"text/html\");\n stageDocument.body.setAttribute(_config.getConfig(\"dataContentTypeAttributeName\"), \"stage\");\n stageDocument.body.id = _config.getConfig(\"bodyId\");\n convertToInlineStyles(stageDocument);\n return buildElementIntoStage(stageDocument.body, stage.rootContainer, stage);\n }\n /**\n * Convert styles to block to inline styles.\n *\n * @param document\n */\n\n\n function convertToInlineStyles(document) {\n var styleBlocks = document.getElementsByTagName(\"style\");\n var viewportStyles = {};\n\n _.each(_config.getConfig(\"viewports\"), function (viewport, name) {\n return viewportStyles[name] = {};\n });\n\n if (styleBlocks.length > 0) {\n Array.from(styleBlocks).forEach(function (styleBlock) {\n var cssRules = styleBlock.sheet.cssRules;\n processCssRules(cssRules, viewportStyles, _config.getConfig(\"defaultViewport\"));\n styleBlock.remove();\n });\n }\n\n _.each(viewportStyles, function (styles, name) {\n _.each(styles, function (stylesArray, selector) {\n var element = document.querySelector(selector);\n\n _.each(stylesArray, function (style) {\n element.setAttribute(\"data-\" + name + \"-style\", element.getAttribute(\"data-\" + name + \"-style\") ? element.getAttribute(\"data-\" + name + \"-style\") + style.cssText : style.cssText);\n });\n });\n });\n\n document.querySelectorAll(\"[\" + _styleRegistry.pbStyleAttribute + \"]\").forEach(function (element) {\n element.removeAttribute(_styleRegistry.pbStyleAttribute);\n });\n }\n /**\n * Process styles and assign them to corespondent style object.\n *\n * @param cssRules\n * @param styles\n * @param scope\n */\n\n\n function processCssRules(cssRules, styles, scope) {\n Array.from(cssRules).forEach(function (rule) {\n if (rule instanceof CSSStyleRule) {\n var selectors = rule.selectorText.split(\",\").map(function (selector) {\n return selector.trim();\n });\n selectors.forEach(function (selector) {\n if (!styles[scope][selector]) {\n styles[scope][selector] = [];\n }\n\n styles[scope][selector].push(rule.style);\n });\n } else if (rule instanceof CSSMediaRule) {\n var mediaCssRules = rule.cssRules;\n\n var mediaScope = _.findKey(_config.getConfig(\"viewports\"), function (viewport) {\n return rule.conditionText === viewport.media;\n });\n\n if (mediaScope) {\n processCssRules(mediaCssRules, styles, mediaScope);\n }\n }\n });\n }\n /**\n * Build an element and it's children into the stage\n *\n * @param {Element} element\n * @param {ContentTypeCollectionInterface} contentType\n * @param {stage} stage\n * @returns {Promise<void>}\n */\n\n\n function buildElementIntoStage(element, contentType, stage) {\n if (element instanceof HTMLElement && element.getAttribute(_config.getConfig(\"dataContentTypeAttributeName\"))) {\n var childPromises = [];\n var childElements = [];\n var children = getElementChildren(element);\n\n if (children.length > 0) {\n _.forEach(children, function (childElement) {\n childPromises.push(createElementContentType(childElement, stage, contentType));\n childElements.push(childElement);\n });\n } // Wait for all the promises to finish and add the instances to the stage\n\n\n return Promise.all(childPromises).then(function (childrenPromises) {\n return Promise.all(childrenPromises.map(function (child, index) {\n contentType.addChild(child); // Only render children if the content type implements the collection\n\n if (child instanceof _contentTypeCollection) {\n return buildElementIntoStage(childElements[index], child, stage);\n }\n }));\n });\n }\n }\n /**\n * Parse an element in the structure and build the required element\n *\n * @param {Element} element\n * @param {ContentTypeCollectionInterface} contentType\n * @param {stage} stage\n * @returns {Promise<ContentTypeInterface>}\n */\n\n\n function createElementContentType(element, stage, contentType) {\n contentType = contentType || stage.rootContainer;\n var role = element.getAttribute(_config.getConfig(\"dataContentTypeAttributeName\"));\n\n if (!role) {\n return Promise.reject(\"Invalid master format: Content type element does not contain\\n \" + _config.getConfig(\"dataContentTypeAttributeName\") + \" attribute.\");\n }\n\n var config = _config.getContentTypeConfig(role);\n\n if (!config) {\n return Promise.reject(\"Unable to load Page Builder configuration for content type \\\"\" + role + \"\\\".\");\n }\n\n return getElementData(element, config).then( // @ts-ignore\n function (data) {\n return (0, _contentTypeFactory)(config, contentType, stage.id, data[_config.getConfig(\"defaultViewport\")], getElementChildren(element).length, data);\n });\n }\n /**\n * Retrieve the elements data\n *\n * @param {HTMLElement} element\n * @param {ContentTypeConfigInterface} config\n * @returns {Promise<{[p: string]: any}>}\n */\n\n\n function getElementData(element, config) {\n // Create an object with all fields for the content type with an empty value\n var appearance = element.dataset.appearance + \"-appearance\";\n var fields = config.fields[appearance] || config.fields.default;\n var result = createInitialElementData(fields);\n return new Promise(function (resolve) {\n var role = element.getAttribute(_config.getConfig(\"dataContentTypeAttributeName\"));\n\n if (!_config.getConfig(\"content_types\").hasOwnProperty(role)) {\n resolve(result);\n } else {\n var readerComponents = (0, _appearanceConfig)(role, element.dataset.appearance).reader;\n (0, _loader)([readerComponents], function () {\n for (var _len = arguments.length, readers = new Array(_len), _key = 0; _key < _len; _key++) {\n readers[_key] = arguments[_key];\n }\n\n var ReaderComponent = readers.pop();\n var reader = new ReaderComponent();\n reader.read(element).then(function (readerData) {\n /**\n * Iterate through the reader data and set the values onto the result array to ensure dot notation\n * keys are properly handled.\n */\n _.each(readerData[_config.getConfig(\"defaultViewport\")], function (value, key) {\n (0, _object.set)(result, key, value);\n });\n\n readerData[_config.getConfig(\"defaultViewport\")] = result;\n resolve(readerData);\n });\n });\n }\n });\n }\n /**\n * Create the initial object for storing the elements data\n *\n * @param {ConfigFieldInterface} fields\n * @returns {FieldDefaultsInterface}\n */\n\n\n function createInitialElementData(fields) {\n return _.mapObject(fields, function (field) {\n if (!_.isUndefined(field.default)) {\n return \"\";\n } else if (_.isObject(field)) {\n return createInitialElementData(field);\n }\n });\n }\n /**\n * Return elements children, search for direct descendants, or traverse through to find deeper children\n *\n * @param {HTMLElement} element\n * @returns {Array<HTMLElement>}\n */\n\n\n function getElementChildren(element) {\n if (element.hasChildNodes()) {\n var children = []; // Find direct children of the element\n\n _.forEach(element.childNodes, function (child) {\n if (child.nodeType === Node.ELEMENT_NODE) {\n if (child.hasAttribute(_config.getConfig(\"dataContentTypeAttributeName\"))) {\n children.push(child);\n } else {\n children = getElementChildren(child);\n }\n }\n });\n\n return children;\n }\n\n return [];\n }\n /**\n * Build a new instance of stage, add row & text content types if needed\n *\n * @param {Stage} stage\n * @param {string} initialValue\n * @returns {Promise<any>}\n */\n\n\n function buildEmpty(stage, initialValue) {\n var stageConfig = _config.getConfig(\"stage_config\");\n\n var rootContainer = stage.rootContainer;\n\n var rootContentTypeConfig = _config.getContentTypeConfig(stageConfig.root_content_type);\n\n var htmlDisplayContentTypeConfig = _config.getContentTypeConfig(stageConfig.html_display_content_type); // @ts-ignore\n\n\n var promise = Promise.resolve();\n\n if (stageConfig.root_content_type && stageConfig.root_content_type !== \"none\") {\n promise = (0, _contentTypeFactory)(rootContentTypeConfig, rootContainer, stage.id);\n promise.then(function (rootContentType) {\n if (!rootContentType) {\n return Promise.reject(\"Unable to create initial \" + stageConfig.root_content_type + \" content type \" + \" within stage.\");\n }\n\n rootContainer.addChild(rootContentType);\n });\n }\n\n promise.then(function (rootContentType) {\n if (htmlDisplayContentTypeConfig && initialValue) {\n return (0, _contentTypeFactory)(htmlDisplayContentTypeConfig, rootContainer, stage.id, {\n html: initialValue\n }).then(function (html) {\n if (rootContentType) {\n rootContentType.addChild(html);\n } else {\n rootContainer.addChild(html);\n }\n });\n }\n });\n return promise;\n }\n /**\n * Build a stage with the provided content type, content observable and initial value\n *\n * @param {Stage} stage\n * @param {string} content\n * @returns {Promise}\n */\n\n\n function build(stage, content) {\n var currentBuild;\n content = (0, _directives.removeQuotesInMediaDirectives)(content); // Determine if we're building from existing page builder content\n\n if ((0, _validator)(content)) {\n currentBuild = buildFromContent(stage, content).catch(function (error) {\n console.error(error);\n stage.rootContainer.children([]);\n currentBuild = buildEmpty(stage, content);\n });\n } else {\n currentBuild = buildEmpty(stage, content);\n } // Once the build process is finished the stage is ready\n\n\n return currentBuild.catch(function (error) {\n (0, _alert)({\n content: (0, _translate)(\"An error has occurred while initiating Page Builder. Please consult with your technical \" + \"support contact.\"),\n title: (0, _translate)(\"Page Builder Error\")\n });\n\n _events.trigger(\"stage:error\", error);\n\n console.error(error);\n });\n }\n\n return build;\n});\n//# sourceMappingURL=stage-builder.js.map","Magento_PageBuilder/js/collection.js":"/*eslint-disable */\n/* jscs:disable */\ndefine([\"knockout\", \"Magento_PageBuilder/js/utils/array\"], function (_knockout, _array) {\n /**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n /**\n * @api\n */\n var Collection = /*#__PURE__*/function () {\n \"use strict\";\n\n function Collection(children) {\n this.children = children ? children : _knockout.observableArray([]);\n }\n /**\n * Return the children of the current element\n *\n * @returns {KnockoutObservableArray<ContentTypeInterface | ContentTypeCollectionInterface>}\n */\n\n\n var _proto = Collection.prototype;\n\n _proto.getChildren = function getChildren() {\n return this.children;\n }\n /**\n * Add a child into the observable array\n *\n * @param child\n * @param index\n */\n ;\n\n _proto.addChild = function addChild(child, index) {\n if (typeof index === \"number\") {\n // Use the arrayUtil function to add the item in the correct place within the array\n (0, _array.moveArrayItemIntoArray)(child, this.children, index);\n } else {\n this.children.push(child);\n }\n }\n /**\n * Remove a child from the observable array\n *\n * @param child\n */\n ;\n\n _proto.removeChild = function removeChild(child) {\n (0, _array.removeArrayItem)(this.children, child);\n }\n /**\n * Set the children observable array into the class\n *\n * @param children\n */\n ;\n\n _proto.setChildren = function setChildren(children) {\n this.children = children;\n };\n\n return Collection;\n }();\n\n return Collection;\n});\n//# sourceMappingURL=collection.js.map","Magento_PageBuilder/js/template-manager.js":"/*eslint-disable */\n/* jscs:disable */\ndefine([\"html2canvas\", \"jquery\", \"mage/translate\", \"Magento_PageBuilder/js/modal/confirm-alert\", \"Magento_PageBuilder/js/modal/template-manager-save\", \"text!Magento_PageBuilder/template/modal/template-manager/save-content-modal.html\", \"uiRegistry\", \"underscore\", \"Magento_PageBuilder/js/acl\", \"Magento_PageBuilder/js/config\"], function (_html2canvas, _jquery, _translate, _confirmAlert, _templateManagerSave, _saveContentModal, _uiRegistry, _underscore, _acl, _config) {\n /**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n /**\n * Save the current stage contents as a template\n *\n * @param stage\n */\n function saveAsTemplate(stage) {\n if (!(0, _acl.isAllowed)(_acl.resources.TEMPLATE_SAVE)) {\n (0, _confirmAlert)({\n content: (0, _translate)(\"You do not have permission to save new templates.\"),\n title: (0, _translate)(\"Permission Error\")\n });\n return false;\n }\n\n var capture = createCapture(stage);\n var prompt = (0, _templateManagerSave)({\n title: (0, _translate)(\"Save Content as Template\"),\n promptContentTmpl: _saveContentModal,\n templateTypes: _config.getConfig(\"stage_config\").template_types,\n createdForNote: (0, _translate)(\"Created For is to help with filtering templates. This does not restrict where this template can be used.\"),\n typeLabel: (0, _translate)(\"Created For\"),\n label: (0, _translate)(\"Template Name\"),\n validation: true,\n modalClass: \"template-manager-save\",\n validationRules: [\"required-entry\"],\n attributesForm: {\n novalidate: \"novalidate\",\n action: \"\"\n },\n attributesField: {\n \"name\": \"name\",\n \"data-validate\": \"{required:true}\",\n \"maxlength\": \"255\"\n },\n actions: {\n /**\n * Handle confirmation of the prompt\n *\n * @param {String} name\n * @param {String} createdFor\n * @this {actions}\n */\n confirm: function confirm(name, createdFor) {\n return new Promise(function (resolve, reject) {\n // Wait for the screenshot and the rendering lock to complete before making the request\n var renderingLock = stage.renderingLocks[stage.renderingLocks.length - 1];\n\n _jquery.when(capture, renderingLock).then(function (imageSrc, content) {\n _jquery.ajax({\n url: _config.getConfig(\"template_save_url\"),\n data: {\n name: name,\n template: content,\n previewImage: imageSrc,\n createdFor: createdFor\n },\n method: \"POST\",\n dataType: \"json\"\n }).done(function (data) {\n if (data.status === \"ok\") {\n (0, _confirmAlert)({\n content: (0, _translate)(\"The current contents of Page Builder has been successfully saved as a template.\"),\n title: (0, _translate)(\"Template Saved\")\n });\n refreshGrid();\n resolve();\n } else if (data.status === \"error\") {\n (0, _confirmAlert)({\n content: data.message || (0, _translate)(\"An issue occurred while attempting to save \" + \"the template, please try again.\"),\n title: (0, _translate)(\"An error occurred\")\n });\n reject();\n }\n }).fail(function () {\n (0, _confirmAlert)({\n content: (0, _translate)(\"An issue occurred while attempting to save the template, \" + \"please try again.\"),\n title: (0, _translate)(\"Template Save Error\")\n });\n reject();\n });\n });\n });\n }\n }\n }); // Update the UI with the preview image once available\n\n capture.then(function (imageSrc) {\n // @ts-ignore\n prompt.templateManagerSave(\"setPreviewImage\", imageSrc);\n });\n }\n /**\n * Refresh the grid if it exists\n */\n\n\n function refreshGrid() {\n var templateStageGrid = _uiRegistry.get(\"pagebuilder_stage_template_grid.pagebuilder_stage_template_grid_data_source\");\n\n if (templateStageGrid) {\n templateStageGrid.storage().clearRequests();\n templateStageGrid.reload();\n }\n }\n /**\n * Create a capture of the stage\n *\n * @param stage\n */\n\n\n function createCapture(stage) {\n var scrollY = window.scrollY;\n var stageElement = document.querySelector(\"#\" + stage.id);\n\n var deferred = _jquery.Deferred(); // Wait for the stage to complete rendering before taking the capture\n\n\n var renderingLock = stage.renderingLocks[stage.renderingLocks.length - 1];\n renderingLock.then(function () {\n // Resolve issues with Parallax\n var parallaxRestore = disableParallax(stageElement);\n stageElement.style.height = (0, _jquery)(stageElement).outerHeight(false) + \"px\";\n stageElement.classList.add(\"capture\");\n stageElement.classList.add(\"interacting\");\n\n if (stage.pageBuilder.isFullScreen()) {\n window.scrollTo({\n top: 0\n });\n }\n\n _underscore.defer(function () {\n (0, _html2canvas)(document.querySelector(\"#\" + stage.id + \" .pagebuilder-canvas\"), {\n scale: 1,\n useCORS: true,\n scrollY: window.pageYOffset * -1\n }).then(function (canvas) {\n var imageSrc = canvas.toDataURL(\"image/jpeg\", 0.85);\n deferred.resolve(imageSrc);\n\n if (stage.pageBuilder.isFullScreen()) {\n window.scrollTo({\n top: scrollY\n });\n }\n\n stageElement.style.height = null;\n stageElement.classList.remove(\"capture\");\n stageElement.classList.remove(\"interacting\");\n restoreParallax(parallaxRestore);\n });\n });\n });\n return deferred;\n }\n /**\n * Disable the parallax elements in the stage\n *\n * @param {Element} stageElement\n */\n\n\n function disableParallax(stageElement) {\n var rowsToReset = [];\n var parallaxRows = stageElement.querySelectorAll(\"[data-jarallax-original-styles]\");\n\n _underscore.each(parallaxRows, function (row) {\n var originalStyles = row.getAttribute(\"data-jarallax-original-styles\");\n var jarallaxStyle = row.style.cssText;\n row.style.cssText = originalStyles;\n var jarallaxContainer = row.querySelector('div[id*=\"jarallax-container\"]');\n jarallaxContainer.style.display = \"none\";\n rowsToReset.push({\n element: row,\n styles: jarallaxStyle,\n container: jarallaxContainer\n });\n });\n\n return rowsToReset;\n }\n /**\n * Restore parallax on modified nodes\n *\n * @param rows\n */\n\n\n function restoreParallax(rows) {\n _underscore.each(rows, function (_ref) {\n var element = _ref.element,\n styles = _ref.styles,\n container = _ref.container;\n element.style.cssText = styles;\n container.style.display = \"\";\n });\n }\n\n return {\n saveAsTemplate: saveAsTemplate\n };\n});\n//# sourceMappingURL=template-manager.js.map","Magento_PageBuilder/js/data-store.js":"/*eslint-disable */\n/* jscs:disable */\ndefine([\"jquery\", \"Magento_PageBuilder/js/utils/object\"], function (_jquery, _object) {\n /**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n var DataStore = /*#__PURE__*/function () {\n \"use strict\";\n\n function DataStore() {\n this.state = {};\n this.events = (0, _jquery)({});\n this.previousState = {};\n }\n\n var _proto = DataStore.prototype;\n\n /**\n * Retrieve specific data from the data store\n *\n * @param {string} key\n * @param defaultValue\n * @returns {T}\n */\n _proto.get = function get(key, defaultValue) {\n return (0, _object.get)(this.state, key, defaultValue);\n }\n /**\n * Retrieve the entire state of the data object\n *\n * @returns {DataObject}\n */\n ;\n\n _proto.getState = function getState() {\n return this.state;\n }\n /**\n * Retrieve the entire previous state of the data object\n *\n * @returns {DataObject}\n */\n ;\n\n _proto.getPreviousState = function getPreviousState() {\n return this.previousState;\n }\n /**\n * Set a specific keys value in the data store\n *\n * @param {string} key\n * @param value\n */\n ;\n\n _proto.set = function set(key, value) {\n this.previousState = Object.assign({}, this.state);\n (0, _object.set)(this.state, key, value);\n this.emitState();\n }\n /**\n * Update the entire state for the content type\n *\n * @param {DataObject} state\n */\n ;\n\n _proto.setState = function setState(state) {\n this.previousState = Object.assign({}, this.state);\n this.state = state;\n this.emitState();\n }\n /**\n * Remove item from DataStore\n *\n * @param {string | number} key\n */\n ;\n\n _proto.unset = function unset(key) {\n var storeState = this.state;\n delete storeState[key];\n this.setState(storeState);\n }\n /**\n * Subscribe to data changes within the data store of a content type\n *\n * @param {(state: DataObject, event: Event) => void} handler\n * @param {string | number} key\n */\n ;\n\n _proto.subscribe = function subscribe(handler, key) {\n var _this = this;\n\n this.events.on(\"state\", function (event, data) {\n if (key) {\n if (_this.previousState[key] !== data.state[key]) {\n handler(data.state, event);\n }\n } else {\n if (_this.previousState !== data.state) {\n handler(data.state, event);\n }\n }\n });\n }\n /**\n * Emit state updates through events\n */\n ;\n\n _proto.emitState = function emitState() {\n this.events.trigger(\"state\", {\n state: this.state\n });\n };\n\n return DataStore;\n }();\n\n return DataStore;\n});\n//# sourceMappingURL=data-store.js.map","Magento_PageBuilder/js/panel.js":"/*eslint-disable */\n/* jscs:disable */\ndefine([\"consoleLogger\", \"jquery\", \"knockout\", \"mage/translate\", \"Magento_PageBuilder/js/events\", \"underscore\", \"Magento_PageBuilder/js/binding/draggable\", \"Magento_PageBuilder/js/config\", \"Magento_PageBuilder/js/drag-drop/drop-indicators\", \"Magento_PageBuilder/js/drag-drop/registry\", \"Magento_PageBuilder/js/panel/menu\", \"Magento_PageBuilder/js/panel/menu/content-type\", \"Magento_PageBuilder/js/utils/position-sticky\"], function (_consoleLogger, _jquery, _knockout, _translate, _events, _underscore, _draggable, _config, _dropIndicators, _registry, _menu, _contentType, _positionSticky) {\n /**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n /**\n * @api\n */\n var Panel = /*#__PURE__*/function () {\n \"use strict\";\n\n function Panel(pageBuilder) {\n this.menuSections = _knockout.observableArray([]);\n this.searchResults = _knockout.observableArray([]);\n this.isVisible = _knockout.observable(false);\n this.isStickyBottom = _knockout.observable(false);\n this.isStickyTop = _knockout.observable(false);\n this.searching = _knockout.observable(false);\n this.searchValue = _knockout.observable(\"\");\n this.searchPlaceholder = (0, _translate)(\"Find items\");\n this.searchNoResult = (0, _translate)(\"Nothing found\");\n this.searchTitle = (0, _translate)(\"Clear Search\");\n this.template = \"Magento_PageBuilder/panel\";\n this.pageBuilder = pageBuilder;\n this.id = this.pageBuilder.id;\n this.initListeners();\n }\n /**\n * On render init the panel\n *\n * @param {Element} element\n */\n\n\n var _proto = Panel.prototype;\n\n _proto.afterRender = function afterRender(element) {\n this.element = element;\n }\n /**\n * Init listeners\n */\n ;\n\n _proto.initListeners = function initListeners() {\n var _this = this;\n\n _events.on(\"stage:\" + this.id + \":readyAfter\", function () {\n _this.populateContentTypes();\n\n if (!(0, _positionSticky.supportsPositionSticky)()) {\n _this.onScroll();\n }\n\n _this.isVisible(true);\n });\n }\n /**\n * Return the template string\n *\n * @returns {string}\n */\n ;\n\n _proto.getTemplate = function getTemplate() {\n return this.template;\n }\n /**\n * Conduct a search on the available content types,\n * and find matches for beginning of words.\n *\n * @param self\n * @param event\n */\n ;\n\n _proto.search = function search(self, event) {\n var _this2 = this;\n\n this.searchValue(event.currentTarget.value.toLowerCase());\n\n if (this.searchValue() === \"\") {\n this.searching(false);\n } else {\n this.searching(true);\n this.searchResults(_underscore.map(_underscore.filter(_config.getConfig(\"content_types\"), function (contentType) {\n if (contentType.is_system !== true) {\n return false;\n }\n\n var escapedSearchValue = self.searchValue().replace(/[-\\/\\\\^$*+?.()|[\\]{}]/g, \"\\\\$&\");\n var regEx = new RegExp(\"\\\\b\" + escapedSearchValue, \"gi\");\n return regEx.test(contentType.label.toLowerCase());\n }), function (contentType, identifier) {\n // Create a new instance of GroupContentType for each result\n return new _contentType.ContentType(identifier, contentType, _this2.pageBuilder.stage.id);\n }));\n }\n }\n /**\n * Clear Search Results\n */\n ;\n\n _proto.clearSearch = function clearSearch() {\n this.searchValue(\"\");\n this.searching(false);\n }\n /**\n * Toggle stickiness of panel based on browser scroll position and height of panel\n * Enable panel stickiness if panel and stage are available\n * Only stick when panel height is smaller than stage height\n * Stick panel to top when scroll reaches top position of stage\n * Stick panel to bottom when scroll reaches bottom position of stage\n */\n ;\n\n _proto.onScroll = function onScroll() {\n var self = this;\n var pageActions = (0, _jquery)(\".page-actions\");\n var panel = (0, _jquery)(this.element);\n panel.addClass(\"no-position-sticky\");\n var stage = panel.siblings(\".pagebuilder-stage\");\n (0, _jquery)(window).scroll(function () {\n if (panel && panel.offset()) {\n var panelOffsetTop = panel.offset().top;\n var stageOffsetTop = stage.offset().top;\n var panelHeight = panel.outerHeight();\n var stageHeight = stage.outerHeight();\n var currentPanelBottom = Math.round(panelOffsetTop + panel.outerHeight(true) - (0, _jquery)(this).scrollTop());\n var currentStageBottom = Math.round(stageOffsetTop + stage.outerHeight(true) - (0, _jquery)(this).scrollTop());\n var currentPanelTop = Math.round(panelOffsetTop - (0, _jquery)(this).scrollTop());\n var currentStageTop = Math.round(stageOffsetTop - (0, _jquery)(this).scrollTop()); // When panel height is less than stage, begin stickiness\n\n if (panelHeight <= stageHeight && pageActions.hasClass(\"_fixed\")) {\n var pageActionsHeight = pageActions.outerHeight() + 15; // When scroll reaches top of stage, stick panel to top\n\n if (currentStageTop <= pageActionsHeight) {\n // When panel reaches bottom of stage, stick panel to bottom of stage\n if (currentPanelBottom >= currentStageBottom && currentPanelTop <= pageActionsHeight) {\n self.isStickyBottom(true);\n self.isStickyTop(false);\n } else {\n self.isStickyBottom(false);\n self.isStickyTop(true);\n }\n } else {\n self.isStickyBottom(false);\n self.isStickyTop(false);\n }\n } else {\n self.isStickyBottom(false);\n self.isStickyTop(false);\n }\n }\n });\n }\n /**\n * Retrieve the draggable options for the panel items\n *\n * @returns {JQueryUI.DraggableOptions}\n */\n ;\n\n _proto.getDraggableOptions = function getDraggableOptions(element) {\n // If we're within a modal make the containment be the current modal\n var containment;\n\n if ((0, _jquery)(element).parents(\".modal-inner-wrap\").length > 0) {\n containment = (0, _jquery)(element).parents(\".modal-inner-wrap\");\n }\n\n var self = this;\n return {\n appendTo: \"body\",\n cursor: \"-webkit-grabbing\",\n connectToSortable: \".content-type-drop\",\n containment: containment || \"document\",\n scroll: true,\n helper: function helper() {\n return (0, _jquery)(this).clone().css({\n width: (0, _jquery)(this).width(),\n height: (0, _jquery)(this).height(),\n zIndex: 10001,\n pointerEvents: \"none\"\n });\n },\n start: function start() {\n var block = _knockout.dataFor(this);\n\n if (block && block.config) {\n // Blur any focused element\n if (document.querySelector(\":focus\")) {\n document.querySelector(\":focus\").blur();\n }\n /**\n * Swap all sortable instances to use intersect, as the item from the left panel is a predictable\n * size this yields better results when dragging\n */\n\n\n (0, _jquery)(\".content-type-container.ui-sortable\").each(function () {\n if ((0, _jquery)(this).data(\"ui-sortable\")) {\n (0, _jquery)(this).sortable(\"option\", \"tolerance\", \"intersect\");\n }\n });\n (0, _dropIndicators.showDropIndicators)(block.config.name, self.pageBuilder.stage.id);\n (0, _registry.setDraggedContentTypeConfig)(block.config);\n\n _events.trigger(\"stage:interactionStart\", {\n stage: self.pageBuilder.stage\n });\n }\n },\n stop: function stop() {\n (0, _jquery)(\".content-type-container.ui-sortable\").each(function () {\n if ((0, _jquery)(this).data(\"ui-sortable\")) {\n (0, _jquery)(this).sortable(\"option\", \"tolerance\", \"pointer\");\n }\n });\n (0, _dropIndicators.hideDropIndicators)();\n (0, _registry.setDraggedContentTypeConfig)(null);\n\n _events.trigger(\"stage:interactionStop\", {\n stage: self.pageBuilder.stage\n });\n }\n };\n }\n /**\n * Populate the panel with the content types\n */\n ;\n\n _proto.populateContentTypes = function populateContentTypes() {\n var _this3 = this;\n\n var menuSections = _config.getConfig(\"menu_sections\");\n\n var contentTypes = _config.getConfig(\"content_types\"); // Verify the configuration contains the required information\n\n\n if (menuSections && contentTypes) {\n // Iterate through the menu sections creating new instances with their associated content types\n _underscore.each(menuSections, function (menuSection, id) {\n // Push the menu section instance into the observable array to update the UI\n _this3.menuSections.push(new _menu.Menu(id, menuSection, _underscore.map(_underscore.where(contentTypes, {\n menu_section: id,\n is_system: true\n }),\n /* Retrieve content types with menu section id */\n function (contentType, identifier) {\n return new _contentType.ContentType(identifier, contentType, _this3.pageBuilder.stage.id);\n }), _this3.pageBuilder.stage.id));\n }); // Display the panel\n\n\n this.isVisible(true); // Open first menu section\n\n var hasGroups = (0 in this.menuSections());\n\n if (hasGroups) {\n this.menuSections()[0].active(true);\n }\n } else {\n _consoleLogger.error(\"Unable to retrieve content types from server, please inspect network requests \" + \"response.\");\n }\n };\n\n return Panel;\n }();\n\n return Panel;\n});\n//# sourceMappingURL=panel.js.map","Magento_PageBuilder/js/page-builder.js":"/*eslint-disable */\n/* jscs:disable */\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\ndefine([\"jquery\", \"knockout\", \"mage/translate\", \"Magento_PageBuilder/js/events\", \"Magento_Ui/js/lib/knockout/template/loader\", \"Magento_Ui/js/modal/alert\", \"mageUtils\", \"underscore\", \"Magento_PageBuilder/js/acl\", \"Magento_PageBuilder/js/binding/style\", \"Magento_PageBuilder/js/config\", \"Magento_PageBuilder/js/content-type-factory\", \"Magento_PageBuilder/js/panel\", \"Magento_PageBuilder/js/stage\", \"Magento_PageBuilder/js/template-manager\"], function (_jquery, _knockout, _translate, _events, _loader, _alert, _mageUtils, _underscore, _acl, _style, _config, _contentTypeFactory, _panel, _stage, _templateManager) {\n /**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n var PageBuilder = /*#__PURE__*/function () {\n \"use strict\";\n\n function PageBuilder(config, initialValue) {\n var _this = this;\n\n this.template = \"Magento_PageBuilder/page-builder\";\n this.isStageReady = _knockout.observable(false);\n this.id = _mageUtils.uniqueid();\n this.originalScrollTop = 0;\n this.isFullScreen = _knockout.observable(false);\n this.isSnapshot = _knockout.observable(false);\n this.isSnapshotTransition = _knockout.observable(false);\n this.loading = _knockout.observable(true);\n this.wrapperStyles = _knockout.observable({});\n this.stageStyles = _knockout.observable({});\n this.viewport = _knockout.observable(\"\");\n this.viewports = {};\n this.viewportClasses = {};\n this.previousStyles = {};\n\n _config.setConfig(config);\n\n _config.setMode(\"Preview\");\n\n this.preloadTemplates(config);\n this.initialValue = initialValue;\n this.initViewports(config);\n this.isFullScreen(config.isFullScreen);\n this.isSnapshot(!!config.pagebuilder_content_snapshot);\n this.isSnapshotTransition(false);\n this.snapshot = !!config.pagebuilder_content_snapshot;\n this.config = config;\n this.isAllowedTemplateApply = (0, _acl.isAllowed)(_acl.resources.TEMPLATE_APPLY);\n this.isAllowedTemplateSave = (0, _acl.isAllowed)(_acl.resources.TEMPLATE_SAVE); // Create the required root container for the stage\n\n (0, _contentTypeFactory)(_config.getContentTypeConfig(_stage.rootContainerName), null, this.id).then(function (rootContainer) {\n _this.stage = new _stage(_this, rootContainer);\n\n _this.isStageReady(true);\n });\n this.panel = new _panel(this);\n this.initListeners();\n }\n /**\n * Destroy rootContainer instance.\n */\n\n\n var _proto = PageBuilder.prototype;\n\n _proto.destroy = function destroy() {\n this.stage.rootContainer.destroy();\n }\n /**\n * Init listeners.\n */\n ;\n\n _proto.initListeners = function initListeners() {\n var _this2 = this;\n\n _events.on(\"stage:\" + this.id + \":toggleFullscreen\", this.toggleFullScreen.bind(this));\n\n this.isFullScreen.subscribe(function () {\n return _this2.onFullScreenChange();\n });\n }\n /**\n * Tells the stage wrapper to expand to fullScreen\n *\n * @param {StageToggleFullScreenParamsInterface} args\n */\n ;\n\n _proto.toggleFullScreen = function toggleFullScreen(args) {\n var _this3 = this;\n\n if (args.animate === false) {\n this.isFullScreen(!this.isFullScreen());\n return;\n }\n\n var stageWrapper = (0, _jquery)(\"#\" + this.stage.id).parent();\n var pageBuilderWrapper = stageWrapper.parents(\".pagebuilder-wysiwyg-wrapper\");\n var panel = stageWrapper.find(\".pagebuilder-panel\");\n\n if (this.snapshot) {\n stageWrapper.scrollTop(0);\n }\n\n if (!this.isFullScreen()) {\n pageBuilderWrapper.css(\"height\", pageBuilderWrapper.outerHeight());\n /**\n * Fix the stage in the exact place it is when it's part of the content and allow it to transition to full\n * screen.\n */\n\n var xPosition = parseInt(stageWrapper.offset().top.toString(), 10) - parseInt((0, _jquery)(window).scrollTop().toString(), 10) - (this.snapshot ? 63 : 0);\n var yPosition = stageWrapper.offset().left - (this.snapshot ? 150 : 0);\n this.previousStyles = {\n position: this.snapshot ? \"relative\" : \"fixed\",\n top: xPosition + \"px\",\n left: yPosition + \"px\",\n zIndex: \"800\",\n width: stageWrapper.outerWidth().toString() + \"px\"\n };\n\n if (this.snapshot) {\n this.isSnapshot(false);\n this.stageStyles(this.previousStyles);\n } else {\n this.previousPanelHeight = panel.outerHeight();\n panel.css(\"height\", this.previousPanelHeight + \"px\");\n this.wrapperStyles(this.previousStyles);\n }\n\n this.isFullScreen(true);\n\n _underscore.defer(function () {\n // Remove all styles we applied to fix the position once we're transitioning\n panel.css(\"height\", \"\");\n\n if (_this3.snapshot) {\n _this3.stageStyles(Object.keys(_this3.previousStyles).reduce(function (object, styleName) {\n var _Object$assign;\n\n return Object.assign(object, (_Object$assign = {}, _Object$assign[styleName] = \"\", _Object$assign));\n }, {}));\n } else {\n _this3.wrapperStyles(Object.keys(_this3.previousStyles).reduce(function (object, styleName) {\n var _Object$assign2;\n\n return Object.assign(object, (_Object$assign2 = {}, _Object$assign2[styleName] = \"\", _Object$assign2));\n }, {}));\n }\n });\n } else {\n // When leaving full screen mode just transition back to the original state\n if (this.snapshot) {\n this.isSnapshotTransition(true);\n this.stageStyles(this.previousStyles);\n } else {\n this.wrapperStyles(this.previousStyles);\n this.isFullScreen(false);\n }\n\n panel.css(\"height\", this.previousPanelHeight + \"px\"); // Wait for the 350ms animation to complete before changing these properties back\n\n _underscore.delay(function () {\n if (_this3.snapshot) {\n _this3.isSnapshot(true);\n\n _this3.isSnapshotTransition(false);\n\n _this3.stageStyles(Object.keys(_this3.previousStyles).reduce(function (object, styleName) {\n var _Object$assign3;\n\n return Object.assign(object, (_Object$assign3 = {}, _Object$assign3[styleName] = \"\", _Object$assign3));\n }, {}));\n\n _this3.isFullScreen(false);\n } else {\n _this3.wrapperStyles(Object.keys(_this3.previousStyles).reduce(function (object, styleName) {\n var _Object$assign4;\n\n return Object.assign(object, (_Object$assign4 = {}, _Object$assign4[styleName] = \"\", _Object$assign4));\n }, {}));\n }\n\n panel.css(\"height\", \"\");\n pageBuilderWrapper.css(\"height\", \"\");\n _this3.previousStyles = {};\n _this3.previousPanelHeight = null;\n }, 350);\n }\n\n return true;\n }\n /**\n * Change window scroll base on full screen mode.\n */\n ;\n\n _proto.onFullScreenChange = function onFullScreenChange() {\n if (this.isFullScreen()) {\n (0, _jquery)(\"body\").css(\"overflow\", \"hidden\");\n } else {\n (0, _jquery)(\"body\").css(\"overflow\", \"\");\n }\n\n _events.trigger(\"stage:\" + this.id + \":fullScreenModeChangeAfter\", {\n fullScreen: this.isFullScreen()\n });\n\n _events.trigger(\"stage:fullScreenModeChangeAfter\", {\n pageBuilderId: this.id,\n fullScreen: this.isFullScreen()\n });\n }\n /**\n * Get template.\n *\n * @returns {string}\n */\n ;\n\n _proto.getTemplate = function getTemplate() {\n return this.template;\n };\n\n /**\n * Toggle template manager\n */\n _proto.toggleTemplateManger = function toggleTemplateManger() {\n if (!(0, _acl.isAllowed)(_acl.resources.TEMPLATE_APPLY)) {\n (0, _alert)({\n content: (0, _translate)(\"You do not have permission to apply templates.\"),\n title: (0, _translate)(\"Permission Error\")\n });\n return false;\n }\n\n _events.trigger(\"stage:templateManager:open\", {\n stage: this.stage\n });\n }\n /**\n * Enable saving the current stage as a template\n */\n ;\n\n _proto.saveAsTemplate = function saveAsTemplate() {\n return (0, _templateManager.saveAsTemplate)(this.stage);\n };\n\n _proto.toggleViewport = function toggleViewport(viewport) {\n var previousViewport = this.viewport();\n this.viewport(viewport);\n\n _underscore.each(this.viewportClasses, function (viewportClass) {\n viewportClass(false);\n });\n\n this.viewportClasses[viewport + \"-viewport\"](true);\n\n _config.setConfig({\n viewport: viewport\n });\n\n _events.trigger(\"stage:\" + this.id + \":viewportChangeAfter\", {\n viewport: viewport,\n previousViewport: previousViewport\n });\n\n _events.trigger(\"stage:viewportChangeAfter\", {\n viewport: viewport,\n previousViewport: previousViewport\n });\n }\n /**\n * Preload all templates into the window to reduce calls later in the app\n *\n * @param config\n */\n ;\n\n _proto.preloadTemplates = function preloadTemplates(config) {\n var previewTemplates = _underscore.values(config.content_types).map(function (contentType) {\n return _underscore.values(contentType.appearances).map(function (appearance) {\n return appearance.preview_template;\n });\n }).reduce(function (array, value) {\n return array.concat(value);\n }, []).map(function (value) {\n return (0, _loader.formatPath)(value);\n });\n\n _underscore.defer(function () {\n require(previewTemplates);\n });\n };\n\n _proto.initViewports = function initViewports(config) {\n var _this4 = this;\n\n this.viewports = config.viewports;\n this.defaultViewport = config.defaultViewport;\n this.viewport(this.defaultViewport);\n\n _config.setConfig({\n viewport: this.defaultViewport\n });\n\n _underscore.each(this.viewports, function (viewport, name) {\n _this4.viewportClasses[name + \"-viewport\"] = _knockout.observable(name === _this4.defaultViewport);\n });\n };\n\n _createClass(PageBuilder, [{\n key: \"viewportTemplate\",\n get: function get() {\n return \"Magento_PageBuilder/viewport/switcher\";\n }\n }]);\n\n return PageBuilder;\n }();\n\n return PageBuilder;\n});\n//# sourceMappingURL=page-builder.js.map","Magento_PageBuilder/js/acl.js":"/*eslint-disable */\n/* jscs:disable */\ndefine([\"Magento_PageBuilder/js/config\"], function (_config) {\n var resources = {\n TEMPLATE_SAVE: \"template_save\",\n TEMPLATE_APPLY: \"template_apply\"\n };\n /**\n * Determine if the current user is allowed to access this resource\n *\n * Usage: isAllowed(resources.TEMPLATE_SAVE)\n *\n * @param resource\n */\n\n function isAllowed(resource) {\n return _config.getConfig(\"acl\")[resource] === true;\n }\n\n return {\n isAllowed: isAllowed,\n resources: resources\n };\n});\n//# sourceMappingURL=acl.js.map","Magento_PageBuilder/js/uploader.js":"/*eslint-disable */\n/* jscs:disable */\ndefine([\"Magento_PageBuilder/js/events\", \"uiLayout\", \"uiRegistry\"], function (_events, _uiLayout, _uiRegistry) {\n /**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n /**\n * @api\n */\n var Uploader = /*#__PURE__*/function () {\n \"use strict\";\n\n /**\n * Config data of uploader instance\n */\n\n /**\n * The supplied data store\n */\n\n /**\n * @param {String} name Name to use for lookup reference in registry\n * @param {Object} uploaderConfig The config used when initializing the Uploader UI component\n * @param {String} contentTypeId The id of the content type this will be used in\n * @param {DataStore} dataStore The datastore that the selected image should be stored in.\n * @param {Object[]} initialValue The value that should be used for the initial state of the component.\n * @param {Function} onChangeCallback Called when image is added or updated\n * @param {Function} onDeleteCallback Called when currently set image is deleted from storage\n */\n function Uploader(name, uploaderConfig, contentTypeId, dataStore, initialValue, onChangeCallback, onDeleteCallback) {\n if (onChangeCallback === void 0) {\n onChangeCallback = null;\n }\n\n if (onDeleteCallback === void 0) {\n onDeleteCallback = null;\n }\n\n var config = Object.assign({}, uploaderConfig, {\n value: initialValue\n });\n config.id = contentTypeId;\n config.name = name;\n this.dataStore = dataStore;\n\n _events.on(\"image:\" + contentTypeId + \":uploadAfter\", onChangeCallback ? onChangeCallback : this.onImageChanged.bind(this));\n\n _events.on(\"image:\" + contentTypeId + \":deleteFileAfter\", onDeleteCallback ? onDeleteCallback : this.onImageDeleted.bind(this));\n\n this.config = config; // Render uploader\n\n this.render();\n }\n /**\n * Default callback for upload event\n * @param {object[]} data\n */\n\n\n var _proto = Uploader.prototype;\n\n _proto.onImageChanged = function onImageChanged(data) {\n this.dataStore.set(this.config.dataScope.toString(), data);\n }\n /**\n * Default callback for image deleted event\n */\n ;\n\n _proto.onImageDeleted = function onImageDeleted() {\n this.dataStore.set(this.config.dataScope.toString(), \"\");\n }\n /**\n * Get registry callback reference to uploader UI component\n *\n * @returns {Function}\n */\n ;\n\n _proto.getUiComponent = function getUiComponent() {\n return _uiRegistry.async(this.config.name);\n }\n /**\n * Instantiate uploader through layout UI component renderer\n */\n ;\n\n _proto.render = function render() {\n (0, _uiLayout)([this.config]);\n };\n\n return Uploader;\n }();\n\n return Uploader;\n});\n//# sourceMappingURL=uploader.js.map","Magento_PageBuilder/js/content-type-menu.js":"/*eslint-disable */\n/* jscs:disable */\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\ndefine([\"knockout\", \"underscore\"], function (_knockout, _underscore) {\n /**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n /**\n * @api\n */\n var ContentTypeMenu = /*#__PURE__*/function () {\n \"use strict\";\n\n /**\n * Options constructor\n *\n * @param preview\n * @param options\n */\n function ContentTypeMenu(preview, options) {\n var _this = this;\n\n this.options = _knockout.observableArray([]);\n this.preview = preview;\n\n var codes = _underscore.keys(options);\n\n _underscore.values(options).forEach(function (option, index) {\n option.code = codes[index];\n\n _this.options.push(option);\n });\n\n this.sort();\n }\n\n var _proto = ContentTypeMenu.prototype;\n\n /**\n * Get an option from the options array\n *\n * @param {string} code\n * @returns {OptionInterface}\n */\n _proto.getOption = function getOption(code) {\n return this.options().find(function (option) {\n return option.code === code;\n });\n }\n /**\n * Sort the options\n */\n ;\n\n _proto.sort = function sort() {\n this.options.sort(function (a, b) {\n return a.sort === b.sort ? 0 : a.sort < b.sort ? -1 : 1;\n });\n };\n\n _createClass(ContentTypeMenu, [{\n key: \"template\",\n get: function get() {\n return \"Magento_PageBuilder/content-type/menu\";\n }\n }]);\n\n return ContentTypeMenu;\n }();\n\n return ContentTypeMenu;\n});\n//# sourceMappingURL=content-type-menu.js.map","Magento_PageBuilder/js/content-type/observable-updater.js":"/*eslint-disable */\n/* jscs:disable */\n\nfunction _createForOfIteratorHelperLoose(o, allowArrayLike) { var it = typeof Symbol !== \"undefined\" && o[Symbol.iterator] || o[\"@@iterator\"]; if (it) return (it = it.call(o)).next.bind(it); if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === \"number\") { if (it) o = it; var i = 0; return function () { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }; } throw new TypeError(\"Invalid attempt to iterate non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\"); }\n\nfunction _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === \"string\") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === \"Object\" && o.constructor) n = o.constructor.name; if (n === \"Map\" || n === \"Set\") return Array.from(o); if (n === \"Arguments\" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }\n\nfunction _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }\n\ndefine([\"consoleLogger\", \"knockout\", \"underscore\", \"Magento_PageBuilder/js/config\", \"Magento_PageBuilder/js/content-type/appearance-config\", \"Magento_PageBuilder/js/content-type/observable-updater/attributes\", \"Magento_PageBuilder/js/content-type/observable-updater/css\", \"Magento_PageBuilder/js/content-type/observable-updater/html\", \"Magento_PageBuilder/js/content-type/observable-updater/style\"], function (_consoleLogger, _knockout, _underscore, _config, _appearanceConfig, _attributes, _css, _html, _style) {\n /**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n var ObservableUpdater = /*#__PURE__*/function () {\n \"use strict\";\n\n /**\n * @param {typeof ConverterPool} converterPool\n * @param {typeof MassConverterPool} massConverterPool\n * @param {(config: object) => string} converterResolver\n */\n function ObservableUpdater(converterPool, massConverterPool, converterResolver) {\n this.previousData = {};\n this.bindingGenerators = {\n attributes: _attributes,\n css: _css,\n html: _html,\n style: _style\n };\n this.converterPool = converterPool;\n this.massConverterPool = massConverterPool;\n this.converterResolver = converterResolver;\n }\n /**\n * Update the associated viewModel with the generated data\n *\n * We create an API for each potential binding and make it available in the master and preview templates through\n * the data variable. Each data variable will have associated observables that are updated on a data change.\n *\n * @param {Preview} viewModel\n * @param {DataObject} data\n * @param {DataObject} dataStores\n */\n\n\n var _proto = ObservableUpdater.prototype;\n\n _proto.update = function update(viewModel, data, dataStores) {\n var appearance = data && data.appearance !== undefined ? data.appearance : undefined;\n var appearanceConfiguration = (0, _appearanceConfig)(viewModel.contentType.config.name, appearance);\n\n if (undefined === appearanceConfiguration || undefined === appearanceConfiguration.elements) {\n return;\n } // Generate Knockout bindings in objects for usage in preview and master templates\n\n\n var generatedBindings = this.generateKnockoutBindings(appearanceConfiguration.elements, appearanceConfiguration.converters, data, dataStores);\n\n var _loop = function _loop(element) {\n if (generatedBindings.hasOwnProperty(element)) {\n // Ensure every element is represented by an object\n if (viewModel.data[element] === undefined) {\n viewModel.data[element] = {};\n }\n /**\n * Iterate through each elements data (css, style, attributes) and apply data updates within the\n * observable. If no observable already exists create a new one.\n */\n\n\n Object.keys(generatedBindings[element]).forEach(function (key) {\n var elementBindings = viewModel.data[element][key];\n\n if (elementBindings !== undefined && _knockout.isObservable(elementBindings)) {\n elementBindings(generatedBindings[element][key]);\n } else {\n viewModel.data[element][key] = _knockout.observable(generatedBindings[element][key]);\n }\n });\n }\n };\n\n for (var element in generatedBindings) {\n _loop(element);\n }\n }\n /**\n * Generate binding object to be applied to master format\n *\n * This function iterates through each element defined in the content types XML and generates a nested object of\n * the associated Knockout binding data. We support 5 bindings attributes, style, css, html & tag.\n *\n * @param elements\n * @param converters\n * @param data\n * @param dataStoreStates\n */\n ;\n\n _proto.generateKnockoutBindings = function generateKnockoutBindings(elements, converters, data, dataStoreStates) {\n var convertedData = this.convertData(data, converters);\n var generatedData = {};\n\n for (var _i = 0, _Object$keys = Object.keys(elements); _i < _Object$keys.length; _i++) {\n var elementName = _Object$keys[_i];\n var elementConfig = elements[elementName];\n\n if (this.previousData[elementName] === undefined) {\n this.previousData[elementName] = {};\n }\n\n generatedData[elementName] = {\n attributes: this.generateKnockoutBinding(\"attributes\", elementName, elementConfig, data),\n style: _config.getMode() === \"Preview\" ? this.generateKnockoutBinding(\"style\", elementName, elementConfig, data) : this.generateKnockoutBindingForBreakpoints(\"style\", elementName, elementConfig, data, dataStoreStates),\n css: elementConfig.css.var in convertedData ? this.generateKnockoutBinding(\"css\", elementName, elementConfig, data) : {},\n html: this.generateKnockoutBinding(\"html\", elementName, elementConfig, data)\n };\n\n if (elementConfig.tag !== undefined && elementConfig.tag.var !== undefined) {\n if (generatedData[elementName][elementConfig.tag.var] === undefined) {\n generatedData[elementName][elementConfig.tag.var] = \"\";\n }\n\n generatedData[elementName][elementConfig.tag.var] = convertedData[elementConfig.tag.var];\n }\n }\n\n return generatedData;\n }\n /**\n * Process data for elements before its converted to knockout format\n *\n * @param {object} data\n * @param {ConverterInterface[]} convertersConfig\n * @returns {object}\n */\n ;\n\n _proto.convertData = function convertData(data, convertersConfig) {\n for (var _iterator = _createForOfIteratorHelperLoose(convertersConfig), _step; !(_step = _iterator()).done;) {\n var converterConfig = _step.value;\n this.massConverterPool.get(converterConfig.component).toDom(data, converterConfig.config);\n }\n\n return data;\n }\n /**\n * Generate an individual knockout binding\n *\n * @param binding\n * @param elementName\n * @param config\n * @param data\n */\n ;\n\n _proto.generateKnockoutBinding = function generateKnockoutBinding(binding, elementName, config, data) {\n if (config[binding] === undefined) {\n return {};\n }\n\n var previousData = {};\n\n if (this.previousData[elementName][binding] !== undefined) {\n previousData = this.previousData[elementName][binding];\n }\n\n if (this.bindingGenerators[binding] === undefined) {\n _consoleLogger.error(\"Unable to find Knockout binding generator for \" + binding);\n\n return {};\n } // Generate the associated binding using our dedicated generators\n\n\n var generatedBindingData = this.bindingGenerators[binding](elementName, config, data, this.converterResolver, this.converterPool, previousData);\n this.previousData[elementName][binding] = generatedBindingData;\n return generatedBindingData;\n }\n /**\n * Generate an individual knockout binding for breakpoints\n *\n * @param binding\n * @param elementName\n * @param config\n * @param data\n * @param dataStoreStates\n */\n ;\n\n _proto.generateKnockoutBindingForBreakpoints = function generateKnockoutBindingForBreakpoints(binding, elementName, config, data, dataStoreStates) {\n var _this = this;\n\n var result = {};\n Object.keys(dataStoreStates).forEach(function (name) {\n result[name] = _underscore.isEmpty(dataStoreStates[name]) ? {} : _this.generateKnockoutBinding(binding, elementName, config, dataStoreStates[name]);\n });\n return result;\n };\n\n return ObservableUpdater;\n }();\n\n return ObservableUpdater;\n});\n//# sourceMappingURL=observable-updater.js.map","Magento_PageBuilder/js/content-type/observable-updater-factory.js":"/*eslint-disable */\n/* jscs:disable */\ndefine([\"Magento_PageBuilder/js/converter/converter-pool-factory\", \"Magento_PageBuilder/js/mass-converter/converter-pool-factory\", \"Magento_PageBuilder/js/content-type/observable-updater\"], function (_converterPoolFactory, _converterPoolFactory2, _observableUpdater) {\n /**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n /**\n * Create new observable updater instance\n *\n * @param {ContentTypeConfigInterface} config\n * @param {Function} converterResolver\n * @returns {Promise<ObservableUpdater>}\n */\n function create(config, converterResolver) {\n var promises = [(0, _converterPoolFactory)(config.name), (0, _converterPoolFactory2)(config.name)];\n return new Promise(function (resolve) {\n Promise.all(promises).then(function (resolvedPromises) {\n var converterPool = resolvedPromises[0],\n massConverterPool = resolvedPromises[1];\n resolve(new _observableUpdater(converterPool, massConverterPool, converterResolver));\n }).catch(function (error) {\n console.error(error);\n return null;\n });\n });\n }\n\n return create;\n});\n//# sourceMappingURL=observable-updater-factory.js.map","Magento_PageBuilder/js/content-type/preview-collection.js":"/*eslint-disable */\n/* jscs:disable */\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\nfunction _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); }\n\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n\ndefine([\"Magento_PageBuilder/js/config\", \"Magento_PageBuilder/js/content-type-factory\", \"Magento_PageBuilder/js/content-type/preview\"], function (_config, _contentTypeFactory, _preview) {\n /**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n var PreviewCollection = /*#__PURE__*/function (_preview2) {\n \"use strict\";\n\n _inheritsLoose(PreviewCollection, _preview2);\n\n function PreviewCollection() {\n return _preview2.apply(this, arguments) || this;\n }\n\n var _proto = PreviewCollection.prototype;\n\n /**\n * Duplicate a collection content type\n *\n * @param {ContentTypeCollectionInterface} contentType\n * @param {boolean} autoAppend\n * @param {boolean} direct\n * @returns {Promise<ContentTypeCollectionInterface> | void}\n */\n _proto.clone = function clone(contentType, autoAppend, direct) {\n var _this = this;\n\n if (autoAppend === void 0) {\n autoAppend = true;\n }\n\n if (direct === void 0) {\n direct = false;\n }\n\n var defaultViewport = _config.getConfig(\"defaultViewport\");\n\n var index = contentType.parentContentType.getChildren().indexOf(contentType) + 1 || null;\n var childrenLength = contentType.children ? contentType.children().length : 0;\n return new Promise(function (resolve, reject) {\n (0, _contentTypeFactory)(contentType.config, contentType.parentContentType, contentType.stageId, contentType.dataStores[defaultViewport].getState(), childrenLength, contentType.getDataStoresStates()).then(function (duplicate) {\n if (contentType.children && contentType.children().length > 0) {\n // Duplicate the instances children into the new duplicate\n contentType.children().forEach(function (subChild) {\n var subChildClone = duplicate.preview.clone(subChild, false);\n\n if (subChildClone) {\n subChildClone.then(function (duplicateSubChild) {\n duplicateSubChild.parentContentType = duplicate;\n duplicate.addChild(duplicateSubChild);\n });\n } else {\n reject(\"Unable to duplicate sub child.\");\n }\n });\n }\n\n if (autoAppend) {\n contentType.parentContentType.addChild(duplicate, index);\n }\n\n _this.dispatchContentTypeCloneEvents(contentType, duplicate, index, direct);\n\n resolve(duplicate);\n });\n });\n }\n /**\n * Tries to call specified method of a current content type,\n * and delegates attempt to its' children.\n * @param args\n */\n ;\n\n _proto.delegate = function delegate() {\n var _preview2$prototype$d;\n\n for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n args[_key] = arguments[_key];\n }\n\n (_preview2$prototype$d = _preview2.prototype.delegate).call.apply(_preview2$prototype$d, [this].concat(args));\n\n this.contentType.getChildren()().forEach(function (elem) {\n elem.preview.delegate.apply(elem.preview, args);\n });\n }\n /**\n * Does the current instance have any children or values different from the default for it's type?\n *\n * @returns {boolean}\n */\n ;\n\n _proto.isConfigured = function isConfigured() {\n if (this.contentType.children().length > 0) {\n return true;\n }\n\n return _preview2.prototype.isConfigured.call(this);\n };\n\n _createClass(PreviewCollection, [{\n key: \"childTemplate\",\n get:\n /**\n * Retrieve the preview child template\n *\n * @returns {string}\n */\n function get() {\n return \"Magento_PageBuilder/content-type/preview-collection\";\n }\n }]);\n\n return PreviewCollection;\n }(_preview);\n\n return PreviewCollection;\n});\n//# sourceMappingURL=preview-collection.js.map","Magento_PageBuilder/js/content-type/master.js":"/*eslint-disable */\n/* jscs:disable */\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\ndefine([\"underscore\", \"Magento_PageBuilder/js/utils/object\", \"Magento_PageBuilder/js/content-type/appearance-config\"], function (_underscore, _object, _appearanceConfig) {\n /**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n /**\n * @api\n */\n var Master = /*#__PURE__*/function () {\n \"use strict\";\n\n /**\n * @param {ContentTypeInterface} contentType\n * @param {ObservableUpdater} observableUpdater\n */\n function Master(contentType, observableUpdater) {\n this.data = {};\n this.contentType = contentType;\n this.observableUpdater = observableUpdater;\n this.bindEvents();\n }\n /**\n * Retrieve the render template\n *\n * @returns {string}\n */\n\n\n var _proto = Master.prototype;\n\n /**\n * Get content type data\n *\n * @param {string} element\n * @returns {DataObject}\n * @deprecated\n */\n _proto.getData = function getData(element) {\n var data = _underscore.extend({}, this.contentType.dataStore.getState());\n\n if (undefined === element) {\n return data;\n }\n\n var appearanceConfiguration = (0, _appearanceConfig)(this.contentType.config.name, data.appearance);\n var config = appearanceConfiguration.elements;\n data = this.observableUpdater.convertData(data, appearanceConfiguration.converters);\n var result = {};\n\n if (undefined !== config[element].tag.var) {\n result[config[element].tag.var] = (0, _object.get)(data, config[element].tag.var);\n }\n\n return result;\n }\n /**\n * Destroys current instance\n */\n ;\n\n _proto.destroy = function destroy() {\n return;\n }\n /**\n * Attach event to updating data in data store to update observables\n */\n ;\n\n _proto.bindEvents = function bindEvents() {\n var _this = this;\n\n this.contentType.dataStore.subscribe(function () {\n _this.updateObservables();\n });\n }\n /**\n * After observables updated, allows to modify observables\n */\n ;\n\n _proto.afterObservablesUpdated = function afterObservablesUpdated() {\n return;\n }\n /**\n * Update observables\n *\n * @deprecated\n */\n ;\n\n _proto.updateObservables = function updateObservables() {\n this.observableUpdater.update(this, _underscore.extend({\n name: this.contentType.config.name\n }, this.contentType.dataStore.getState()), this.contentType.getDataStoresStates());\n this.afterObservablesUpdated();\n };\n\n _createClass(Master, [{\n key: \"template\",\n get: function get() {\n return (0, _appearanceConfig)(this.contentType.config.name, this.getData().appearance).master_template;\n }\n }]);\n\n return Master;\n }();\n\n return Master;\n});\n//# sourceMappingURL=master.js.map","Magento_PageBuilder/js/content-type/converter-resolver.js":"/*eslint-disable */\n/* jscs:disable */\ndefine([], function () {\n /**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n /**\n * Resolve converter\n *\n * @param {DataMappingInterface} config\n * @return string\n */\n function resolve(config) {\n return config.converter;\n }\n\n return resolve;\n});\n//# sourceMappingURL=converter-resolver.js.map","Magento_PageBuilder/js/content-type/preview-styles.js":"/*eslint-disable */\n/* jscs:disable */\ndefine([\"knockout\", \"Magento_PageBuilder/js/events\", \"Magento_PageBuilder/js/content-type/style-registry\"], function (_knockout, _events, _styleRegistry) {\n /**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n var PreviewStyles =\n /*#__PURE__*/\n function () {\n \"use strict\";\n\n function PreviewStyles(stageId) {\n var _this = this;\n\n this.styleBlocks = _knockout.observableArray([]);\n this.template = \"Magento_PageBuilder/content-type/preview-styles\";\n this.stageId = stageId;\n\n _events.on(\"styles:update\", function (args) {\n if (args.stageId === _this.stageId) {\n var css = (0, _styleRegistry.generateCssBlock)(args.className, args.styles); // Remove any existing style blocks for the current class name\n\n var existingBlock = _this.styleBlocks().find(function (block) {\n return block.className === args.className;\n });\n\n if (existingBlock) {\n // Don't do an update if the CSS matches\n if (existingBlock.css === css) {\n return;\n }\n\n _this.styleBlocks.splice(_this.styleBlocks().indexOf(existingBlock), 1);\n }\n\n _this.styleBlocks.push({\n className: args.className,\n css: css\n });\n }\n });\n }\n /**\n * Get template.\n *\n * @returns {string}\n */\n\n\n var _proto = PreviewStyles.prototype;\n\n _proto.getTemplate = function getTemplate() {\n return this.template;\n };\n\n return PreviewStyles;\n }();\n\n return PreviewStyles;\n});\n//# sourceMappingURL=preview-styles.js.map","Magento_PageBuilder/js/content-type/preview.js":"/*eslint-disable */\n/* jscs:disable */\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\ndefine([\"jquery\", \"knockout\", \"mage/translate\", \"Magento_PageBuilder/js/events\", \"Magento_PageBuilder/js/modal/dismissible-confirm\", \"underscore\", \"Magento_PageBuilder/js/binding/live-edit\", \"Magento_PageBuilder/js/binding/sortable\", \"Magento_PageBuilder/js/binding/sortable-children\", \"Magento_PageBuilder/js/config\", \"Magento_PageBuilder/js/content-type-collection\", \"Magento_PageBuilder/js/content-type-factory\", \"Magento_PageBuilder/js/content-type-menu\", \"Magento_PageBuilder/js/content-type-menu/edit\", \"Magento_PageBuilder/js/content-type-menu/option\", \"Magento_PageBuilder/js/content-type-menu/title-option\", \"Magento_PageBuilder/js/drag-drop/registry\", \"Magento_PageBuilder/js/drag-drop/sortable\", \"Magento_PageBuilder/js/utils/check-stage-full-screen\", \"Magento_PageBuilder/js/utils/object\", \"Magento_PageBuilder/js/content-type/appearance-config\"], function (_jquery, _knockout, _translate, _events, _dismissibleConfirm, _underscore, _liveEdit, _sortable, _sortableChildren, _config, _contentTypeCollection, _contentTypeFactory, _contentTypeMenu, _edit, _option, _titleOption, _registry, _sortable2, _checkStageFullScreen, _object, _appearanceConfig) {\n /**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n /**\n * @api\n */\n var Preview = /*#__PURE__*/function () {\n \"use strict\";\n\n /**\n * Provide preview data as an object which can be queried\n *\n * @deprecated please use getOptionValue directly\n */\n\n /**\n * Fields that should not be considered when evaluating whether an object has been configured.\n *\n * @see {Preview.isConfigured}\n * @type {[string]}\n */\n\n /**\n * @param {ContentTypeInterface} contentType\n * @param {ContentTypeConfigInterface} config\n * @param {ObservableUpdater} observableUpdater\n */\n function Preview(contentType, config, observableUpdater) {\n this.data = {};\n this.displayLabel = _knockout.observable();\n this.display = _knockout.observable(true);\n this.appearance = _knockout.observable();\n this.isPlaceholderVisible = _knockout.observable(true);\n this.isEmpty = _knockout.observable(true);\n this.viewport = _knockout.observable(\"\");\n this.previewData = {};\n this.fieldsToIgnoreOnRemove = [];\n this.events = {};\n this.isSnapshot = _knockout.observable(false);\n this.mouseover = false;\n this.contentType = contentType;\n this.config = config;\n this.edit = new _edit(this.contentType, this.contentType.dataStore);\n this.optionsMenu = new _contentTypeMenu(this, this.retrieveOptions());\n this.observableUpdater = observableUpdater;\n this.displayLabel(this.config.label);\n this.placeholderCss = _knockout.observable({\n \"visible\": this.isEmpty,\n \"empty-placeholder-background\": this.isPlaceholderVisible\n });\n\n if (_config.getConfig(\"pagebuilder_content_snapshot\")) {\n this.isSnapshot(!(0, _checkStageFullScreen)(this.contentType.stageId));\n }\n\n this.viewport(_config.getConfig(\"viewport\"));\n this.bindEvents();\n this.populatePreviewData();\n }\n /**\n * Retrieve the preview template\n *\n * @returns {string}\n */\n\n\n var _proto = Preview.prototype;\n\n /**\n * Calls methods by event name.\n *\n * @param {string} eventName\n * @param {any} params\n */\n _proto.trigger = function trigger(eventName, params) {\n var _this = this;\n\n if (this.events[eventName]) {\n var methods = this.events[eventName];\n\n _underscore.each(methods.split(\" \"), function (methodName) {\n var method = _this[methodName];\n\n if (method) {\n method.call(_this, params);\n }\n }, this);\n }\n }\n /**\n * Tries to call specified method of a current content type.\n *\n * @param args\n */\n ;\n\n _proto.delegate = function delegate() {\n for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n args[_key] = arguments[_key];\n }\n\n var methodName = args.slice(0, 1)[0];\n var method = this[methodName];\n\n if (method) {\n method.apply(this, args.slice(1, args.length));\n }\n }\n /**\n * Open the edit form for this content type\n */\n ;\n\n _proto.openEdit = function openEdit() {\n return this.edit.open();\n }\n /**\n * Update data store\n *\n * @param {string} key\n * @param {string} value\n */\n ;\n\n _proto.updateData = function updateData(key, value) {\n this.contentType.dataStore.set(key, value);\n }\n /**\n * Retrieve the value for an option\n *\n * @param key\n */\n ;\n\n _proto.getOptionValue = function getOptionValue(key) {\n return this.contentType.dataStore.get(key);\n }\n /**\n * Set state based on mouseover event for the preview\n *\n * @param {Preview} context\n * @param {Event} event\n */\n ;\n\n _proto.onMouseOver = function onMouseOver(context, event) {\n if (this.mouseover || (0, _registry.getDraggedContentTypeConfig)()) {\n return;\n } // Ensure no other options panel is displayed\n\n\n (0, _jquery)(\".pagebuilder-options-visible\").removeClass(\"pagebuilder-options-visible\");\n this.mouseover = true;\n this.mouseoverContext = context;\n var currentTarget = event.currentTarget;\n var optionsMenu = (0, _jquery)(currentTarget).find(\".pagebuilder-options-wrapper\");\n\n if (!(0, _jquery)(currentTarget).hasClass(\"type-nested\")) {\n optionsMenu = optionsMenu.first();\n }\n\n var middleOfPreview = currentTarget.getBoundingClientRect().left + currentTarget.offsetWidth / 2; // Check for space for option menu\n\n if (window.innerWidth - middleOfPreview > optionsMenu.width() / 2) {\n optionsMenu.parent().addClass(\"pagebuilder-options-middle\");\n } else {\n optionsMenu.parent().removeClass(\"pagebuilder-options-middle\");\n }\n\n optionsMenu.parent().addClass(\"pagebuilder-options-visible\");\n (0, _jquery)(currentTarget).addClass(\"pagebuilder-content-type-active\");\n }\n /**\n * Set state based on mouseout event for the preview\n *\n * @param {Preview} context\n * @param {Event} event\n */\n ;\n\n _proto.onMouseOut = function onMouseOut(context, event) {\n var _this2 = this;\n\n this.mouseover = false;\n\n if ((0, _registry.getDraggedContentTypeConfig)()) {\n return;\n }\n\n _underscore.delay(function () {\n if (!_this2.mouseover && _this2.mouseoverContext === context) {\n var currentTarget = event.currentTarget;\n var optionsMenu = (0, _jquery)(currentTarget).find(\".pagebuilder-options-wrapper\");\n\n if (!(0, _jquery)(currentTarget).hasClass(\"type-nested\")) {\n optionsMenu = optionsMenu.first();\n }\n\n optionsMenu.parent().removeClass(\"pagebuilder-options-visible\");\n (0, _jquery)(currentTarget).removeClass(\"pagebuilder-content-type-active\");\n }\n }, 100); // 100 ms delay to allow for users hovering over other elements\n\n }\n /**\n * After children render fire an event\n *\n * @param {Element} element\n * @deprecated\n */\n ;\n\n _proto.afterChildrenRender = function afterChildrenRender(element) {\n _events.trigger(\"contentType:childrenRenderAfter\", {\n id: this.contentType.id,\n contentType: this.contentType,\n element: element\n });\n\n _events.trigger(this.contentType.config.name + \":childrenRenderAfter\", {\n contentType: this.contentType,\n element: element,\n id: this.contentType.id\n });\n }\n /**\n * Dispatch an after render event for individual content types\n *\n * @param {Element[]} elements\n */\n ;\n\n _proto.dispatchAfterRenderEvent = function dispatchAfterRenderEvent(elements) {\n var elementNodes = elements.filter(function (renderedElement) {\n return renderedElement.nodeType === Node.ELEMENT_NODE;\n });\n\n if (elementNodes.length > 0) {\n var element = elementNodes[0];\n this.wrapperElement = element;\n\n _events.trigger(\"contentType:renderAfter\", {\n id: this.contentType.id,\n contentType: this.contentType,\n element: element\n });\n\n _events.trigger(this.contentType.config.name + \":renderAfter\", {\n contentType: this.contentType,\n element: element,\n id: this.contentType.id\n });\n\n this.disableImageUploadOnHide(element);\n }\n }\n /**\n * Get the options instance\n *\n * @returns {ContentTypeMenu}\n */\n ;\n\n _proto.getOptions = function getOptions() {\n return this.optionsMenu;\n }\n /**\n * Handle user editing an instance\n */\n ;\n\n _proto.onOptionEdit = function onOptionEdit() {\n this.openEdit();\n }\n /**\n * Reverse the display data currently in the data store\n */\n ;\n\n _proto.onOptionVisibilityToggle = function onOptionVisibilityToggle() {\n var display = this.contentType.dataStore.get(\"display\");\n this.contentType.dataStore.set(\"display\", !display);\n this.dispatchContentTypeVisibilityEvents(this.contentType, !display);\n }\n /**\n * Handle duplicate of items\n */\n ;\n\n _proto.onOptionDuplicate = function onOptionDuplicate() {\n this.clone(this.contentType, true, true);\n }\n /**\n * Duplicate content type\n *\n * @param {ContentTypeInterface | ContentTypeCollectionInterface} contentType\n * @param {boolean} autoAppend\n * @param {boolean} direct\n * @returns {Promise<ContentTypeInterface> | void}\n */\n ;\n\n _proto.clone = function clone(contentType, autoAppend, direct) {\n var _this3 = this;\n\n if (autoAppend === void 0) {\n autoAppend = true;\n }\n\n if (direct === void 0) {\n direct = false;\n }\n\n var defaultViewport = _config.getConfig(\"defaultViewport\");\n\n var contentTypeData = contentType.dataStores[defaultViewport].getState();\n var index = contentType.parentContentType.getChildren()().indexOf(contentType) + 1 || null;\n return (0, _contentTypeFactory)(contentType.config, contentType.parentContentType, contentType.stageId, contentTypeData, 0, contentType.getDataStoresStates()).then(function (duplicateContentType) {\n if (autoAppend) {\n contentType.parentContentType.addChild(duplicateContentType, index);\n }\n\n _this3.dispatchContentTypeCloneEvents(contentType, duplicateContentType, index, direct);\n\n return duplicateContentType;\n });\n }\n /**\n * Handle content type removal\n */\n ;\n\n _proto.onOptionRemove = function onOptionRemove() {\n var _this4 = this;\n\n var removeContentType = function removeContentType() {\n if (_this4.wrapperElement) {\n // Fade out the content type\n (0, _jquery)(_this4.wrapperElement).fadeOut(350 / 2, function () {\n _this4.contentType.destroy();\n });\n } else {\n _this4.contentType.destroy();\n }\n };\n\n if (this.isConfigured()) {\n (0, _dismissibleConfirm)({\n actions: {\n confirm: function confirm() {\n // Call the parent to remove the child element\n removeContentType();\n }\n },\n content: (0, _translate)(\"Are you sure you want to remove this item? The data within this item is not recoverable once removed.\"),\n // tslint:disable-line:max-line-length\n dismissKey: \"pagebuilder_modal_dismissed\",\n dismissible: true,\n title: (0, _translate)(\"Confirm Item Removal\")\n });\n } else {\n removeContentType();\n }\n }\n /**\n * Determine if the container can receive drop events? With the current matrix system everything can unless\n * specified in an inherited preview instance.\n *\n * @returns {boolean}\n */\n ;\n\n _proto.isContainer = function isContainer() {\n return true;\n }\n /**\n * Return the sortable options\n *\n * @returns {JQueryUI.SortableOptions}\n */\n ;\n\n _proto.getSortableOptions = function getSortableOptions() {\n return (0, _sortable2.getSortableOptions)(this);\n }\n /**\n * Destroys current instance\n */\n ;\n\n _proto.destroy = function destroy() {\n return;\n }\n /**\n * Get the CSS classes for the children element, as we dynamically create this class name it can't sit in the DOM\n * without causing browser issues\n *\n * @returns {{[p: string]: boolean}}\n */\n ;\n\n _proto.getChildrenCss = function getChildrenCss() {\n var _ref;\n\n return _ref = {}, _ref[this.config.name + \"-container\"] = true, _ref;\n }\n /**\n * Return an array of options\n *\n * @returns {OptionsInterface}\n */\n ;\n\n _proto.retrieveOptions = function retrieveOptions() {\n var options = {\n move: new _option({\n preview: this,\n icon: \"<i class='icon-admin-pagebuilder-handle'></i>\",\n title: (0, _translate)(\"Move\"),\n classes: [\"move-structural\"],\n sort: 10\n }),\n title: new _titleOption({\n preview: this,\n title: this.config.label,\n template: \"Magento_PageBuilder/content-type/title\",\n sort: 20\n }),\n edit: new _option({\n preview: this,\n icon: \"<i class='icon-admin-pagebuilder-systems'></i>\",\n title: (0, _translate)(\"Edit\"),\n action: this.onOptionEdit,\n classes: [\"edit-content-type\"],\n sort: 30\n }),\n duplicate: new _option({\n preview: this,\n icon: \"<i class='icon-pagebuilder-copy'></i>\",\n title: (0, _translate)(\"Duplicate\"),\n action: this.onOptionDuplicate,\n classes: [\"duplicate-structural\"],\n sort: 50\n }),\n remove: new _option({\n preview: this,\n icon: \"<i class='icon-admin-pagebuilder-remove'></i>\",\n title: (0, _translate)(\"Remove\"),\n action: this.onOptionRemove,\n classes: [\"remove-structural\"],\n sort: 60\n })\n };\n return options;\n }\n /**\n * Dispatch content type clone events\n *\n * @param {ContentTypeInterface | ContentTypeCollectionInterface} originalContentType\n * @param {ContentTypeInterface | ContentTypeCollectionInterface} duplicateContentType\n * @param {number} index\n * @param {boolean} direct\n */\n ;\n\n _proto.dispatchContentTypeCloneEvents = function dispatchContentTypeCloneEvents(originalContentType, duplicateContentType, index, direct) {\n var duplicateEventParams = {\n originalContentType: originalContentType,\n duplicateContentType: duplicateContentType,\n index: index,\n direct: direct\n };\n\n _events.trigger(\"contentType:duplicateAfter\", duplicateEventParams);\n\n _events.trigger(originalContentType.config.name + \":duplicateAfter\", duplicateEventParams);\n }\n /**\n * Dispatch content type visibility events\n *\n * @param {ContentTypeInterface | ContentTypeCollectionInterface} contentType\n * @param {boolean} visibility\n */\n ;\n\n _proto.dispatchContentTypeVisibilityEvents = function dispatchContentTypeVisibilityEvents(contentType, visibility) {\n var visibilityEventParams = {\n contentType: contentType,\n visibility: visibility\n };\n\n _events.trigger(\"contentType:visibilityAfter\", visibilityEventParams);\n\n _events.trigger(contentType.config.name + \":visibilityAfter\", visibilityEventParams);\n }\n /**\n * Bind events\n */\n ;\n\n _proto.bindEvents = function bindEvents() {\n var _this5 = this;\n\n var fullScreenModeChangeAfterEvent = \"stage:\" + this.contentType.stageId + \":fullScreenModeChangeAfter\";\n this.contentType.dataStore.subscribe(function (data) {\n _this5.updateObservables();\n\n _this5.updatePlaceholderVisibility(data); // Keep a reference to the display state in an observable for adding classes to the wrapper\n\n\n _this5.display(!!data.display);\n\n _this5.appearance(data.appearance);\n });\n\n if (this.contentType instanceof _contentTypeCollection) {\n this.contentType.children.subscribe(function (children) {\n _this5.isEmpty(!children.length);\n });\n }\n\n _events.on(fullScreenModeChangeAfterEvent, this.toggleSnapshot.bind(this));\n\n _events.on(\"stage:\" + this.contentType.stageId + \":viewportChangeAfter\", function (args) {\n _this5.viewport(args.viewport);\n });\n }\n /**\n * After observables updated, allows to modify observables\n */\n ;\n\n _proto.afterObservablesUpdated = function afterObservablesUpdated() {\n return;\n }\n /**\n * Does the current instance have any children or values different from the default for it's type?\n *\n * @returns {boolean}\n */\n ;\n\n _proto.isConfigured = function isConfigured() {\n var _this6 = this;\n\n var data = this.contentType.dataStore.getState();\n var fields = this.contentType.config.fields[this.appearance() + \"-appearance\"] || this.contentType.config.fields.default;\n var hasDataChanges = false;\n\n _underscore.each(fields, function (field, key) {\n if (_this6.fieldsToIgnoreOnRemove && _this6.fieldsToIgnoreOnRemove.includes(key)) {\n return;\n }\n\n var fieldValue = (0, _object.get)(data, key);\n\n if (!fieldValue) {\n fieldValue = \"\";\n } // Default values can only ever be strings\n\n\n if (_underscore.isObject(fieldValue)) {\n // Empty arrays as default values appear as empty strings\n if (_underscore.isArray(fieldValue) && fieldValue.length === 0) {\n fieldValue = \"\";\n } else {\n fieldValue = JSON.stringify(fieldValue);\n }\n }\n\n if (_underscore.isObject(field.default)) {\n if (JSON.stringify(field.default) !== fieldValue) {\n hasDataChanges = true;\n }\n } else if (field.default !== fieldValue) {\n hasDataChanges = true;\n }\n\n return;\n });\n\n return hasDataChanges;\n }\n /**\n * Any hidden element should block drag / drop events from uploading images from the OS. We have to block this for\n * all elements as underlying elements could still receive the events if a parent is hidden.\n *\n * @param {Element} element\n */\n ;\n\n _proto.disableImageUploadOnHide = function disableImageUploadOnHide(element) {\n var _this7 = this;\n\n (0, _jquery)(element).on(\"drag dragstart dragend dragover dragenter dragleave drop\", function (event) {\n if (_this7.display() === false) {\n event.preventDefault();\n event.stopPropagation();\n }\n });\n }\n /**\n * Update observables\n */\n ;\n\n _proto.updateObservables = function updateObservables() {\n this.observableUpdater.update(this, _underscore.extend({}, this.contentType.dataStore.getState()));\n this.afterObservablesUpdated();\n }\n /**\n * Update placeholder background visibility base on height and padding\n *\n * @param {DataObject} data\n */\n ;\n\n _proto.updatePlaceholderVisibility = function updatePlaceholderVisibility(data) {\n var minHeight = !_underscore.isEmpty(data.min_height) ? parseFloat(data.min_height) : 130;\n var marginsAndPadding = _underscore.isString(data.margins_and_padding) && data.margins_and_padding ? JSON.parse(data.margins_and_padding) : data.margins_and_padding || {};\n var padding = marginsAndPadding.padding || {};\n var paddingBottom = parseFloat(padding.bottom) || 0;\n var paddingTop = parseFloat(padding.top) || 0;\n this.isPlaceholderVisible(paddingBottom + paddingTop + minHeight >= 130);\n }\n /**\n * Populate the preview data with calls to the supported getOptionValue method\n *\n * @deprecated this function is only included to preserve backwards compatibility, use getOptionValue directly\n */\n ;\n\n _proto.populatePreviewData = function populatePreviewData() {\n var _this8 = this;\n\n if (this.config.fields) {\n _underscore.each(this.config.fields, function (fields) {\n _underscore.keys(fields).forEach(function (key) {\n _this8.previewData[key] = _knockout.observable(\"\");\n });\n });\n } // Subscribe to this content types data in the store\n\n\n this.contentType.dataStore.subscribe(function (data) {\n _underscore.forEach(data, function (value, key) {\n var optionValue = _this8.getOptionValue(key);\n\n if (_knockout.isObservable(_this8.previewData[key])) {\n _this8.previewData[key](optionValue);\n } else {\n if (_underscore.isArray(optionValue)) {\n _this8.previewData[key] = _knockout.observableArray(optionValue);\n } else {\n _this8.previewData[key] = _knockout.observable(optionValue);\n }\n }\n });\n });\n }\n /**\n * Enable snapshot mode.\n * @param args\n */\n ;\n\n _proto.toggleSnapshot = function toggleSnapshot(args) {\n if (_config.getConfig(\"pagebuilder_content_snapshot\")) {\n this.isSnapshot(!args.fullScreen);\n }\n };\n\n _createClass(Preview, [{\n key: \"template\",\n get: function get() {\n return (0, _appearanceConfig)(this.config.name, this.appearance()).preview_template;\n }\n }]);\n\n return Preview;\n }();\n\n return Preview;\n});\n//# sourceMappingURL=preview.js.map","Magento_PageBuilder/js/content-type/master-collection.js":"/*eslint-disable */\n/* jscs:disable */\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\nfunction _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); }\n\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n\ndefine([\"Magento_PageBuilder/js/content-type/master\"], function (_master) {\n /**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n var MasterCollection = /*#__PURE__*/function (_master2) {\n \"use strict\";\n\n _inheritsLoose(MasterCollection, _master2);\n\n function MasterCollection() {\n return _master2.apply(this, arguments) || this;\n }\n\n _createClass(MasterCollection, [{\n key: \"masterTemplate\",\n get:\n /**\n * Retrieve the child template\n *\n * @returns {string}\n */\n function get() {\n return \"Magento_PageBuilder/content-type/master-collection\";\n }\n }]);\n\n return MasterCollection;\n }(_master);\n\n return MasterCollection;\n});\n//# sourceMappingURL=master-collection.js.map","Magento_PageBuilder/js/content-type/style-registry.js":"/*eslint-disable */\n/* jscs:disable */\ndefine([\"underscore\", \"Magento_PageBuilder/js/utils/string\"], function (_underscore, _string) {\n /**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n var styleRegistries = {};\n var pbStyleAttribute = \"data-pb-style\";\n var styleDataAttribute = \"data-style-id\";\n\n var StyleRegistry = /*#__PURE__*/function () {\n \"use strict\";\n\n function StyleRegistry(identifier) {\n this.styles = {};\n\n if (identifier) {\n styleRegistries[identifier] = this;\n }\n }\n /**\n * Update styles for selector\n *\n * @param selector\n * @param styles\n */\n\n\n var _proto = StyleRegistry.prototype;\n\n _proto.setStyles = function setStyles(selector, styles) {\n this.styles[selector] = styles;\n }\n /**\n * Retrieve styles for a selector\n *\n * @param selector\n */\n ;\n\n _proto.getStyles = function getStyles(selector) {\n if (this.styles[selector]) {\n return this.styles[selector];\n }\n\n return {};\n }\n /**\n * Retrieve all styles\n */\n ;\n\n _proto.getAllStyles = function getAllStyles() {\n return this.styles;\n };\n\n return StyleRegistry;\n }();\n /**\n * Return the style registry\n *\n * @param id\n */\n\n\n function getStyleRegistry(id) {\n return styleRegistries[id] !== undefined ? styleRegistries[id] : null;\n }\n /**\n * Delete the style registry\n *\n * @param id\n */\n\n\n function deleteStyleRegistry(id) {\n if (styleRegistries[id]) {\n delete styleRegistries[id];\n }\n }\n /**\n * Generate CSS from styles\n *\n * @param styles\n */\n\n\n function generateCss(styles) {\n var generatedCss = \"\";\n Object.keys(styles).forEach(function (selector) {\n if (!_underscore.isEmpty(styles[selector])) {\n generatedCss += generateCssBlock(selector, styles[selector]);\n }\n });\n return generatedCss;\n }\n /**\n * Generate styles from an object\n *\n * @param selector\n * @param styles\n */\n\n\n function generateCssBlock(selector, styles) {\n var generatedStyles = \"\";\n Object.keys(styles).forEach(function (key) {\n if (!_underscore.isEmpty(styles[key])) {\n generatedStyles += (0, _string.fromCamelCaseToDash)(key) + \": \" + styles[key] + \"; \";\n }\n });\n return selector + \" { \" + generatedStyles + \" }\";\n }\n\n return Object.assign(StyleRegistry, {\n getStyleRegistry: getStyleRegistry,\n deleteStyleRegistry: deleteStyleRegistry,\n generateCss: generateCss,\n generateCssBlock: generateCssBlock,\n pbStyleAttribute: pbStyleAttribute,\n styleDataAttribute: styleDataAttribute\n });\n});\n//# sourceMappingURL=style-registry.js.map","Magento_PageBuilder/js/content-type/appearance-config.js":"/*eslint-disable */\n/* jscs:disable */\ndefine([\"Magento_PageBuilder/js/config\"], function (_config) {\n /**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n /**\n * Get config for appearance\n *\n * @param {string} contentType\n * @param {string} appearance\n * @returns {ContentTypeConfigAppearanceInterface}\n * @api\n */\n function getAppearanceConfig(contentType, appearance) {\n var contentTypeConfig = _config.getContentTypeConfig(contentType);\n\n var config;\n\n if (contentTypeConfig.appearances !== undefined) {\n if (!appearance) {\n for (var key in contentTypeConfig.appearances) {\n if (!!contentTypeConfig.appearances[key].default) {\n appearance = key;\n break;\n }\n }\n }\n\n if (appearance) {\n config = contentTypeConfig.appearances[appearance];\n }\n }\n\n return config;\n }\n\n return getAppearanceConfig;\n});\n//# sourceMappingURL=appearance-config.js.map","Magento_PageBuilder/js/content-type/preview-converter-resolver.js":"/*eslint-disable */\n/* jscs:disable */\ndefine([], function () {\n /**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n /**\n * Resolve converter\n *\n * @param {DataMappingStyleInterface} config\n * @return string\n */\n function resolve(config) {\n return config.preview_converter ? config.preview_converter : config.converter;\n }\n\n return resolve;\n});\n//# sourceMappingURL=preview-converter-resolver.js.map","Magento_PageBuilder/js/content-type/preview-factory.js":"/*eslint-disable */\n/* jscs:disable */\ndefine([\"Magento_PageBuilder/js/utils/loader\", \"Magento_PageBuilder/js/content-type/observable-updater-factory\", \"Magento_PageBuilder/js/content-type/preview-converter-resolver\"], function (_loader, _observableUpdaterFactory, _previewConverterResolver) {\n /**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n /**\n * Create new preview instance\n *\n * @param {ContentTypeInterface | ContentTypeCollectionInterface} contentType\n * @param {ContentTypeConfigInterface} config\n * @returns {Promise<Preview | PreviewCollection>}\n */\n function create(contentType, config) {\n return new Promise(function (resolve, reject) {\n (0, _observableUpdaterFactory)(config, _previewConverterResolver).then(function (observableUpdater) {\n (0, _loader)([config.preview_component], function (previewComponent) {\n try {\n var preview = new previewComponent(contentType, config, observableUpdater);\n resolve(preview);\n } catch (error) {\n reject(\"Error within preview component (\" + config.preview_component + \") for \" + config.name + \".\");\n console.error(error);\n }\n }, function (error) {\n reject(\"Unable to load preview component (\" + config.preview_component + \") for \" + config.name + \". Please \" + \"check preview component exists and content type configuration is correct.\");\n console.error(error);\n });\n }).catch(function (error) {\n console.error(error);\n return null;\n });\n });\n }\n\n return create;\n});\n//# sourceMappingURL=preview-factory.js.map","Magento_PageBuilder/js/content-type/master-factory.js":"/*eslint-disable */\n/* jscs:disable */\ndefine([\"Magento_PageBuilder/js/utils/loader\", \"Magento_PageBuilder/js/content-type/converter-resolver\", \"Magento_PageBuilder/js/content-type/observable-updater-factory\"], function (_loader, _converterResolver, _observableUpdaterFactory) {\n /**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n /**\n * Create new content instance\n *\n * @param {ContentTypeInterface | ContentTypeCollectionInterface} contentType\n * @param {ContentTypeConfigInterface} config\n * @returns {Promise<ContentTypeInterface>}\n */\n function create(contentType, config) {\n return new Promise(function (resolve, reject) {\n (0, _observableUpdaterFactory)(config, _converterResolver).then(function (observableUpdater) {\n (0, _loader)([config.master_component], function (masterComponent) {\n try {\n var master = new masterComponent(contentType, observableUpdater);\n resolve(master);\n } catch (error) {\n reject(\"Error within master component (\" + config.master_component + \") for \" + config.name + \".\");\n console.error(error);\n }\n }, function (error) {\n reject(\"Unable to load preview component (\" + config.master_component + \") for \" + config.name + \". Please \" + \"check preview component exists and content type configuration is correct.\");\n console.error(error);\n });\n }).catch(function (error) {\n console.error(error);\n return null;\n });\n });\n }\n\n return create;\n});\n//# sourceMappingURL=master-factory.js.map","Magento_PageBuilder/js/content-type/banner/preview.js":"/*eslint-disable */\n/* jscs:disable */\n\nfunction _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); }\n\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n\ndefine([\"jarallax\", \"jarallaxVideo\", \"jquery\", \"jquery/z-index\", \"mage/translate\", \"Magento_PageBuilder/js/events\", \"mageUtils\", \"underscore\", \"vimeoWrapper\", \"Magento_PageBuilder/js/content-type-menu/hide-show-option\", \"Magento_PageBuilder/js/uploader\", \"Magento_PageBuilder/js/utils/delay-until\", \"Magento_PageBuilder/js/utils/editor\", \"Magento_PageBuilder/js/utils/nesting-link-dialog\", \"Magento_PageBuilder/js/utils/nesting-widget-dialog\", \"Magento_PageBuilder/js/wysiwyg/factory\", \"Magento_PageBuilder/js/content-type/preview\"], function (_jarallax, _jarallaxVideo, _jquery, _zIndex, _translate, _events, _mageUtils, _underscore, _vimeoWrapper, _hideShowOption, _uploader, _delayUntil, _editor, _nestingLinkDialog, _nestingWidgetDialog, _factory, _preview) {\n /**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n /**\n * @api\n */\n var Preview = /*#__PURE__*/function (_preview2) {\n \"use strict\";\n\n _inheritsLoose(Preview, _preview2);\n\n function Preview() {\n var _this;\n\n for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n args[_key] = arguments[_key];\n }\n\n _this = _preview2.call.apply(_preview2, [this].concat(args)) || this;\n _this.buttonPlaceholder = (0, _translate)(\"Edit Button Text\");\n _this.wysiwygDeferred = _jquery.Deferred();\n _this.handledDoubleClick = false;\n _this.videoUpdateProperties = [\"background_type\", \"video_fallback_image\", \"video_lazy_load\", \"video_loop\", \"video_play_only_visible\", \"video_source\"];\n _this.bannerOverlaySelector = \".pagebuilder-overlay\";\n _this.defaultOverlayZIndex = 2;\n _this.activeEditorOverlayZIndex = 3;\n _this.buildJarallax = _underscore.debounce(function () {\n // Destroy all instances of the plugin prior\n try {\n jarallax(_this.wrapper, \"destroy\");\n } catch (e) {// Failure of destroying is acceptable\n }\n\n if (_this.wrapper && _this.wrapper.dataset.backgroundType === \"video\" && _this.wrapper.dataset.videoSrc.length) {\n _underscore.defer(function () {\n // Build Parallax on elements with the correct class\n jarallax(_this.wrapper, {\n videoSrc: _this.wrapper.dataset.videoSrc,\n imgSrc: _this.wrapper.dataset.videoFallbackSrc,\n videoLoop: _this.contentType.dataStore.get(\"video_loop\") === \"true\",\n speed: 1,\n videoPlayOnlyVisible: _this.contentType.dataStore.get(\"video_play_only_visible\") === \"true\",\n videoLazyLoading: _this.contentType.dataStore.get(\"video_lazy_load\") === \"true\"\n }); // @ts-ignore\n\n if (_this.wrapper.jarallax && _this.wrapper.jarallax.video) {\n // @ts-ignore\n _this.wrapper.jarallax.video.on(\"started\", function () {\n // @ts-ignore\n if (_this.wrapper.jarallax && _this.wrapper.jarallax.$video) {\n // @ts-ignore\n _this.wrapper.jarallax.$video.style.visibility = \"visible\";\n }\n });\n }\n });\n }\n }, 50);\n return _this;\n }\n\n var _proto = Preview.prototype;\n\n /**\n * Get background image url base on the viewport.\n *\n * @returns {string}\n */\n _proto.getBackgroundImage = function getBackgroundImage() {\n var mobileImage = this.contentType.dataStore.get(\"mobile_image\");\n var desktopImage = this.contentType.dataStore.get(\"background_image\");\n var backgroundImage = this.viewport() === \"mobile\" && mobileImage.length ? mobileImage : desktopImage;\n return backgroundImage.length ? \"url(\\\"\" + backgroundImage[0].url + \"\\\")\" : \"none\";\n }\n /**\n * Return an array of options\n *\n * @returns {OptionsInterface}\n */\n ;\n\n _proto.retrieveOptions = function retrieveOptions() {\n var options = _preview2.prototype.retrieveOptions.call(this);\n\n options.hideShow = new _hideShowOption({\n preview: this,\n icon: _hideShowOption.showIcon,\n title: _hideShowOption.showText,\n action: this.onOptionVisibilityToggle,\n classes: [\"hide-show-content-type\"],\n sort: 40\n });\n return options;\n }\n /**\n * Get registry callback reference to uploader UI component\n *\n * @returns {Uploader}\n */\n ;\n\n _proto.getUploader = function getUploader() {\n var initialImageValue = this.contentType.dataStore.get(this.config.additional_data.uploaderConfig.dataScope, \"\"); // Create uploader\n\n return new _uploader(\"imageuploader_\" + this.contentType.id, this.config.additional_data.uploaderConfig, this.contentType.id, this.contentType.dataStore, initialImageValue);\n }\n /**\n * @param {HTMLElement} element\n */\n ;\n\n _proto.afterRenderWysiwyg = function afterRenderWysiwyg(element) {\n var _this2 = this;\n\n this.element = element;\n element.id = this.contentType.id + \"-editor\"; // Set the innerHTML manually so we don't upset Knockout & TinyMCE\n\n element.innerHTML = this.data.content.html();\n this.contentType.dataStore.subscribe(function () {\n // If we're not focused into TinyMCE inline, update the value when it changes in the data store\n if (!_this2.wysiwyg || _this2.wysiwyg && _this2.wysiwyg.getAdapter().id !== (0, _editor.getActiveEditor)().id) {\n element.innerHTML = _this2.data.content.html();\n }\n }, \"message\");\n /**\n * afterRenderWysiwyg is called whenever Knockout causes a DOM re-render. This occurs frequently within Slider\n * due to Slick's inability to perform a refresh with Knockout managing the DOM. Due to this the original\n * WYSIWYG instance will be detached from this slide and we need to re-initialize on click.\n */\n\n this.wysiwyg = null;\n }\n /**\n * Stop event to prevent execution of action when editing textarea.\n *\n * @param {Preview} preview\n * @param {JQueryEventObject} event\n * @returns {Boolean}\n */\n ;\n\n _proto.stopEvent = function stopEvent(preview, event) {\n event.stopPropagation();\n return true;\n }\n /**\n * Init WYSIWYG on load\n *\n * @param element\n * @deprecated please use activateEditor & initWysiwygFromClick\n */\n ;\n\n _proto.initWysiwyg = function initWysiwyg(element) {\n this.element = element;\n element.id = this.contentType.id + \"-editor\";\n this.wysiwyg = null;\n return this.initWysiwygFromClick(false);\n }\n /**\n * Init the WYSIWYG\n *\n * @param {boolean} focus Should wysiwyg focus after initialization?\n * @returns Promise\n */\n ;\n\n _proto.initWysiwygFromClick = function initWysiwygFromClick(focus) {\n var _this3 = this;\n\n if (focus === void 0) {\n focus = false;\n }\n\n if (this.wysiwyg) {\n return Promise.resolve(this.wysiwyg);\n }\n\n var wysiwygConfig = this.config.additional_data.wysiwygConfig.wysiwygConfigData;\n\n if (focus) {\n wysiwygConfig.adapter.settings.auto_focus = this.element.id;\n\n wysiwygConfig.adapter.settings.init_instance_callback = function (editor) {\n editor.on(\"focus\", function () {\n (0, _jquery)(_this3.element).parents(_this3.bannerOverlaySelector).zIndex(_this3.activeEditorOverlayZIndex);\n });\n editor.on(\"blur\", function () {\n (0, _jquery)(_this3.element).parents(_this3.bannerOverlaySelector).zIndex(_this3.defaultOverlayZIndex);\n (0, _nestingLinkDialog)(_this3.contentType.dataStore, _this3.wysiwyg, \"message\", \"link_url\");\n (0, _nestingWidgetDialog)(_this3.contentType.dataStore, _this3.wysiwyg, \"message\", \"link_url\");\n });\n\n _underscore.defer(function () {\n _this3.element.blur();\n\n _this3.element.focus();\n });\n };\n }\n\n wysiwygConfig.adapter.settings.fixed_toolbar_container = \"#\" + this.contentType.id + \" .pagebuilder-banner-text-content\";\n return (0, _factory)(this.contentType.id, this.element.id, this.config.name, wysiwygConfig, this.contentType.dataStore, \"message\", this.contentType.stageId).then(function (wysiwyg) {\n _this3.wysiwyg = wysiwyg;\n return wysiwyg;\n });\n }\n /**\n * Makes WYSIWYG active\n *\n * @param {Preview} preview\n * @param {JQueryEventObject} event\n * @returns {Boolean}\n */\n ;\n\n _proto.activateEditor = function activateEditor(preview, event) {\n var _this4 = this;\n\n if (this.element && !this.wysiwyg) {\n var bookmark = (0, _editor.createBookmark)(event);\n (0, _editor.lockImageSize)(this.element);\n this.element.removeAttribute(\"contenteditable\");\n\n _underscore.defer(function () {\n _this4.initWysiwygFromClick(true).then(function () {\n return (0, _delayUntil)(function () {\n // We no longer need to handle double click once it's initialized\n _this4.handledDoubleClick = true;\n\n _this4.wysiwygDeferred.resolve();\n\n (0, _editor.moveToBookmark)(bookmark);\n (0, _editor.unlockImageSize)(_this4.element);\n }, function () {\n return _this4.element.classList.contains(\"mce-edit-focus\");\n }, 10);\n }).catch(function (error) {\n // If there's an error with init of WYSIWYG editor push into the console to aid support\n console.error(error);\n });\n });\n } else if (this.element && this.wysiwyg) {\n var element = this.element || this.textarea;\n\n if (event.currentTarget !== event.target && event.target !== element && !element.contains(event.target)) {\n return;\n }\n\n element.focus();\n }\n }\n /**\n * If a user double clicks prior to initializing TinyMCE, forward the event\n *\n * @param preview\n * @param event\n */\n ;\n\n _proto.handleDoubleClick = function handleDoubleClick(preview, event) {\n var _this5 = this;\n\n if (this.handledDoubleClick) {\n return;\n }\n\n event.preventDefault();\n var targetIndex = (0, _editor.findNodeIndex)(this.element, event.target.tagName, event.target);\n this.handledDoubleClick = true;\n this.wysiwygDeferred.then(function () {\n var target = document.getElementById(event.target.id);\n\n if (!target) {\n target = (0, _editor.getNodeByIndex)(_this5.element, event.target.tagName, targetIndex);\n }\n\n if (target) {\n target.dispatchEvent((0, _editor.createDoubleClickEvent)());\n }\n });\n }\n /**\n * Set state based on overlay mouseover event for the preview\n */\n ;\n\n _proto.onMouseOverWrapper = function onMouseOverWrapper() {\n if (this.data.main.attributes()[\"data-show-overlay\"] === \"hover\") {\n this.data.overlay.attributes(Object.assign(this.data.overlay.attributes(), {\n \"data-background-color-orig\": this.data.overlay.style().backgroundColor\n }));\n this.data.overlay.style(Object.assign(this.data.overlay.style(), {\n backgroundColor: this.data.overlay.attributes()[\"data-overlay-color\"]\n }));\n }\n\n if (this.data.main.attributes()[\"data-show-button\"] === \"hover\") {\n this.data.button.style(Object.assign(this.data.button.style(), {\n opacity: 1,\n visibility: \"visible\"\n }));\n }\n }\n /**\n * Set state based on overlay mouseout event for the preview\n */\n ;\n\n _proto.onMouseOutWrapper = function onMouseOutWrapper() {\n if (this.data.main.attributes()[\"data-show-overlay\"] === \"hover\") {\n this.data.overlay.style(Object.assign(this.data.overlay.style(), {\n backgroundColor: this.data.overlay.attributes()[\"data-background-color-orig\"]\n }));\n }\n\n if (this.data.main.attributes()[\"data-show-button\"] === \"hover\") {\n this.data.button.style(Object.assign(this.data.button.style(), {\n opacity: 0,\n visibility: \"hidden\"\n }));\n }\n }\n /**\n * @returns {Boolean}\n */\n ;\n\n _proto.isWysiwygSupported = function isWysiwygSupported() {\n return (0, _editor.isWysiwygSupported)();\n }\n /**\n * @param {HTMLTextAreaElement} element\n */\n ;\n\n _proto.initTextarea = function initTextarea(element) {\n var _this6 = this;\n\n this.textarea = element; // set initial value of textarea based on data store\n\n this.textarea.value = this.contentType.dataStore.get(\"message\");\n this.adjustTextareaHeightBasedOnScrollHeight(); // Update content in our stage preview textarea after its slideout counterpart gets updated\n\n _events.on(\"form:\" + this.contentType.id + \":saveAfter\", function () {\n _this6.textarea.value = _this6.contentType.dataStore.get(\"message\");\n\n _this6.adjustTextareaHeightBasedOnScrollHeight();\n });\n }\n /**\n * Save current value of textarea in data store\n */\n ;\n\n _proto.onTextareaKeyUp = function onTextareaKeyUp() {\n this.adjustTextareaHeightBasedOnScrollHeight();\n this.contentType.dataStore.set(\"message\", this.textarea.value);\n }\n /**\n * Start stage interaction on textarea blur\n */\n ;\n\n _proto.onTextareaFocus = function onTextareaFocus() {\n (0, _jquery)(this.textarea).closest(\".pagebuilder-banner-text-content\").addClass(\"pagebuilder-toolbar-active\");\n\n _events.trigger(\"stage:interactionStart\");\n }\n /**\n * Stop stage interaction on textarea blur\n */\n ;\n\n _proto.onTextareaBlur = function onTextareaBlur() {\n (0, _jquery)(this.textarea).closest(\".pagebuilder-banner-text-content\").removeClass(\"pagebuilder-toolbar-active\");\n\n _events.trigger(\"stage:interactionStop\");\n }\n /**\n * Init the parallax element\n *\n * @param {HTMLElement} element\n */\n ;\n\n _proto.initParallax = function initParallax(element) {\n var _this7 = this;\n\n this.wrapper = element;\n\n _underscore.defer(function () {\n _this7.buildJarallax();\n });\n }\n /**\n * Destroy jarallax instance.\n */\n ;\n\n _proto.destroy = function destroy() {\n _preview2.prototype.destroy.call(this);\n\n if (this.wrapper) {\n jarallax(this.wrapper, \"destroy\");\n }\n }\n /**\n * @inheritDoc\n */\n ;\n\n _proto.bindEvents = function bindEvents() {\n var _this8 = this;\n\n _preview2.prototype.bindEvents.call(this);\n\n _events.on(\"banner:mountAfter\", function (args) {\n if (args.id === _this8.contentType.id) {\n _this8.buildJarallax();\n\n _this8.isSnapshot.subscribe(function (value) {\n _this8.changeUploaderControlsVisibility();\n });\n\n _this8.changeUploaderControlsVisibility();\n }\n });\n\n _events.on(this.config.name + \":\" + this.contentType.id + \":updateAfter\", function () {\n var dataStore = _this8.contentType.dataStore.getState();\n\n var imageObject = dataStore[_this8.config.additional_data.uploaderConfig.dataScope][0] || {}; // Resolves issue when tinyMCE injects a non-breaking space on reinitialization and removes placeholder.\n\n if (dataStore.message === \"<div data-bind=\\\"html: data.content.html\\\"> </div>\") {\n _this8.contentType.dataStore.set(\"message\", \"\");\n }\n\n _events.trigger(\"image:\" + _this8.contentType.id + \":assignAfter\", imageObject);\n });\n\n this.contentType.dataStore.subscribe(function (data) {\n if (this.shouldUpdateVideo(data)) {\n this.buildJarallax();\n }\n }.bind(this));\n\n _events.on(\"image:\" + this.contentType.id + \":uploadAfter\", function () {\n _this8.contentType.dataStore.set(\"background_type\", \"image\");\n });\n\n _events.on(\"stage:\" + this.contentType.stageId + \":viewportChangeAfter\", function (args) {\n _this8.buildJarallax();\n });\n }\n /**\n * Change uploader controls visibility\n */\n ;\n\n _proto.changeUploaderControlsVisibility = function changeUploaderControlsVisibility() {\n var _this9 = this;\n\n this.getUploader().getUiComponent()(function (uploader) {\n uploader.visibleControls = !_this9.isSnapshot();\n });\n }\n /**\n * Adjust textarea's height based on scrollHeight\n */\n ;\n\n _proto.adjustTextareaHeightBasedOnScrollHeight = function adjustTextareaHeightBasedOnScrollHeight() {\n this.textarea.style.height = \"\";\n var scrollHeight = this.textarea.scrollHeight;\n var minHeight = parseInt((0, _jquery)(this.textarea).css(\"min-height\"), 10);\n\n if (scrollHeight === minHeight) {\n // leave height at 'auto'\n return;\n }\n\n (0, _jquery)(this.textarea).height(scrollHeight);\n }\n /**\n * Check if video options has been updated.\n *\n * @return boolean\n */\n ;\n\n _proto.shouldUpdateVideo = function shouldUpdateVideo(state) {\n var _this10 = this;\n\n var previousState = this.contentType.dataStore.getPreviousState();\n\n var diff = _mageUtils.compare(previousState, state).changes;\n\n if (diff.length > 0) {\n return _underscore.some(diff, function (element) {\n if (element.name === \"video_fallback_image\") {\n return (!_underscore.isEmpty(previousState.video_fallback_image) && previousState.video_fallback_image) !== (!_underscore.isEmpty(state.video_fallback_image) && state.video_fallback_image);\n }\n\n return _this10.videoUpdateProperties.indexOf(element.name) !== -1;\n });\n }\n };\n\n return Preview;\n }(_preview);\n\n return Preview;\n});\n//# sourceMappingURL=preview.js.map","Magento_PageBuilder/js/content-type/banner/appearance/default/widget.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n 'Magento_PageBuilder/js/widget/show-on-hover',\n 'Magento_PageBuilder/js/widget/video-background'\n], function (showOnHover, videoBackground) {\n 'use strict';\n\n return function (config, element) {\n var videoElement = element[0].querySelector('[data-background-type=video]');\n\n showOnHover(config);\n\n if (videoElement) {\n videoBackground(config, videoElement);\n }\n };\n});\n","Magento_PageBuilder/js/content-type/banner/wysiwyg/tinymce/component-initializer.js":"/*eslint-disable */\n/* jscs:disable */\ndefine([\"jquery\", \"mage/adminhtml/wysiwyg/events\"], function (_jquery, _events) {\n /**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n var ComponentInitializer = /*#__PURE__*/function () {\n \"use strict\";\n\n function ComponentInitializer() {}\n\n var _proto = ComponentInitializer.prototype;\n\n /**\n * The editor element\n */\n\n /**\n * The configuration of the wysiwyg content type\n */\n\n /**\n * Initialize the instance\n *\n * @param {Wysiwyg} wysiwyg\n */\n _proto.initialize = function initialize(wysiwyg) {\n this.$element = (0, _jquery)(\"#\" + wysiwyg.elementId);\n this.config = wysiwyg.config;\n var tinymce = wysiwyg.getAdapter();\n tinymce.eventBus.attachEventHandler(_events.afterFocus, this.onFocus.bind(this));\n tinymce.eventBus.attachEventHandler(_events.afterBlur, this.onBlur.bind(this));\n }\n /**\n * Called when tinymce is focused\n */\n ;\n\n _proto.onFocus = function onFocus() {\n var _this = this;\n\n // If there isn't enough room for a left-aligned toolbar, right align it\n if ((0, _jquery)(window).width() < this.$element.offset().left + parseInt(this.config.adapter_config.minToolbarWidth, 10)) {\n this.$element.addClass(\"_right-aligned-toolbar\");\n } else {\n this.$element.removeClass(\"_right-aligned-toolbar\");\n }\n\n _jquery.each(this.config.adapter_config.parentSelectorsToUnderlay, function (i, selector) {\n _this.$element.closest(selector).css(\"z-index\", 100);\n });\n }\n /**\n * Called when tinymce is blurred\n */\n ;\n\n _proto.onBlur = function onBlur() {\n var _this2 = this;\n\n _jquery.each(this.config.adapter_config.parentSelectorsToUnderlay, function (i, selector) {\n _this2.$element.closest(selector).css(\"z-index\", \"\");\n });\n };\n\n return ComponentInitializer;\n }();\n\n return ComponentInitializer;\n});\n//# sourceMappingURL=component-initializer.js.map","Magento_PageBuilder/js/content-type/banner/converter/style/button-visibility.js":"/*eslint-disable */\n/* jscs:disable */\ndefine([], function () {\n /**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n var ButtonVisibility = /*#__PURE__*/function () {\n \"use strict\";\n\n function ButtonVisibility() {}\n\n var _proto = ButtonVisibility.prototype;\n\n /**\n * Convert value to internal format\n *\n * @param value string\n * @returns {string | object}\n */\n _proto.fromDom = function fromDom(value) {\n return value;\n }\n /**\n * Convert value to knockout format\n *\n * @param {string} name\n * @param {DataObject} data\n * @returns {string | object}\n */\n ;\n\n _proto.toDom = function toDom(name, data) {\n return data.show_button === \"always\" ? \"visible\" : \"hidden\";\n };\n\n return ButtonVisibility;\n }();\n\n return ButtonVisibility;\n});\n//# sourceMappingURL=button-visibility.js.map","Magento_PageBuilder/js/content-type/banner/converter/style/button-opacity.js":"/*eslint-disable */\n/* jscs:disable */\ndefine([], function () {\n /**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n var ButtonOpacity = /*#__PURE__*/function () {\n \"use strict\";\n\n function ButtonOpacity() {}\n\n var _proto = ButtonOpacity.prototype;\n\n /**\n * Convert value to internal format\n *\n * @param value string\n * @returns {string | object}\n */\n _proto.fromDom = function fromDom(value) {\n return value;\n }\n /**\n * Convert value to knockout format\n *\n * @param {string} name\n * @param {DataObject} data\n * @returns {string | object}\n */\n ;\n\n _proto.toDom = function toDom(name, data) {\n return data.show_button === \"always\" ? \"1\" : \"0\";\n };\n\n return ButtonOpacity;\n }();\n\n return ButtonOpacity;\n});\n//# sourceMappingURL=button-opacity.js.map","Magento_PageBuilder/js/content-type/banner/converter/style/overlay-background-color.js":"/*eslint-disable */\n/* jscs:disable */\ndefine([\"Magento_PageBuilder/js/utils/object\"], function (_object) {\n /**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n var OverlayBackgroundColor = /*#__PURE__*/function () {\n \"use strict\";\n\n function OverlayBackgroundColor() {}\n\n var _proto = OverlayBackgroundColor.prototype;\n\n /**\n * Convert value to internal format\n *\n * @param value string\n * @returns {string | object}\n */\n _proto.fromDom = function fromDom(value) {\n return value;\n }\n /**\n * Convert value to knockout format\n *\n * @param name string\n * @param data Object\n * @returns {string | object}\n */\n ;\n\n _proto.toDom = function toDom(name, data) {\n var value = (0, _object.get)(data, name);\n\n if (data.show_overlay === \"always\" && value !== \"\" && value !== undefined) {\n return value;\n }\n\n return \"transparent\";\n };\n\n return OverlayBackgroundColor;\n }();\n\n return OverlayBackgroundColor;\n});\n//# sourceMappingURL=overlay-background-color.js.map","Magento_PageBuilder/js/content-type/banner/converter/attribute/overlay-color.js":"/*eslint-disable */\n/* jscs:disable */\ndefine([], function () {\n /**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n var OverlayColor = /*#__PURE__*/function () {\n \"use strict\";\n\n function OverlayColor() {}\n\n var _proto = OverlayColor.prototype;\n\n /**\n * Convert value to internal format\n *\n * @param value string\n * @returns {string | object}\n */\n _proto.fromDom = function fromDom(value) {\n return value === \"transparent\" ? \"\" : value;\n }\n /**\n * Convert value to knockout format\n *\n * @param {string} name\n * @param {DataObject} data\n * @returns {string | object}\n */\n ;\n\n _proto.toDom = function toDom(name, data) {\n if (data.overlay_color) {\n return data.overlay_color.toString();\n }\n\n return \"\";\n };\n\n return OverlayColor;\n }();\n\n return OverlayColor;\n});\n//# sourceMappingURL=overlay-color.js.map","Magento_PageBuilder/js/content-type/tabs/preview.js":"/*eslint-disable */\n/* jscs:disable */\n\nfunction _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); }\n\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n\ndefine([\"jquery\", \"knockout\", \"mage/translate\", \"Magento_PageBuilder/js/events\", \"tabs\", \"underscore\", \"Magento_PageBuilder/js/config\", \"Magento_PageBuilder/js/content-type-factory\", \"Magento_PageBuilder/js/content-type-menu/hide-show-option\", \"Magento_PageBuilder/js/content-type-menu/option\", \"Magento_PageBuilder/js/utils/delay-until\", \"Magento_PageBuilder/js/utils/promise-deferred\", \"Magento_PageBuilder/js/content-type/preview-collection\"], function (_jquery, _knockout, _translate, _events, _tabs, _underscore, _config, _contentTypeFactory, _hideShowOption, _option, _delayUntil, _promiseDeferred, _previewCollection) {\n /**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n /**\n * @api\n */\n var Preview = /*#__PURE__*/function (_previewCollection2) {\n \"use strict\";\n\n _inheritsLoose(Preview, _previewCollection2);\n\n /**\n * @param {ContentTypeCollectionInterface} contentType\n * @param {ContentTypeConfigInterface} config\n * @param {ObservableUpdater} observableUpdater\n */\n function Preview(contentType, config, observableUpdater) {\n var _this;\n\n _this = _previewCollection2.call(this, contentType, config, observableUpdater) || this; // Wait for the tabs instance to mount and the container to be ready\n\n _this.focusedTab = _knockout.observable(null);\n _this.activeTab = _knockout.observable(0);\n _this.onContainerRenderDeferred = (0, _promiseDeferred)();\n _this.mountAfterDeferred = (0, _promiseDeferred)();\n Promise.all([_this.onContainerRenderDeferred.promise, _this.mountAfterDeferred.promise]).then(function (_ref) {\n var element = _ref[0],\n expectedChildren = _ref[1];\n // We always create 1 tab when dropping tabs into the instance\n expectedChildren = expectedChildren || 1; // Wait until all children's DOM elements are present before building the tabs instance\n\n (0, _delayUntil)(function () {\n _this.element = element;\n\n _this.buildTabs();\n }, function () {\n return (0, _jquery)(element).find(\".pagebuilder-tab-item\").length === expectedChildren;\n });\n }); // Resolve our deferred when the tabs item mounts with expect children\n\n _events.on(\"tabs:mountAfter\", function (args) {\n if (args.contentType.id === _this.contentType.id && args.expectChildren !== undefined) {\n _this.mountAfterDeferred.resolve(args.expectChildren);\n }\n });\n\n _events.on(\"tab-item:mountAfter\", function (args) {\n if (_this.element && args.contentType.parentContentType.id === _this.contentType.id) {\n _this.refreshTabs();\n }\n });\n\n _events.on(\"tab-item:renderAfter\", function (args) {\n if (_this.element && args.contentType.parentContentType.id === _this.contentType.id) {\n _underscore.defer(function () {\n _this.refreshTabs();\n });\n }\n }); // Set the active tab to the new position of the sorted tab\n\n\n _events.on(\"tab-item:removeAfter\", function (args) {\n if (args.parentContentType && args.parentContentType.id === _this.contentType.id) {\n _this.refreshTabs(); // We need to wait for the tabs to refresh before executing the focus\n\n\n _underscore.defer(function () {\n var newPosition = args.index > 0 ? args.index - 1 : 0;\n\n _this.setFocusedTab(newPosition, true);\n });\n }\n }); // Refresh tab contents and set the focus to the new position of the sorted tab\n\n\n _events.on(\"childContentType:sortUpdate\", function (args) {\n if (args.instance.id === _this.contentType.id) {\n _this.refreshTabs(args.newPosition, true);\n /**\n * Update the default active tab if its position was affected by the sorting\n */\n\n\n var defaultActiveTab = +_this.activeTab();\n var newDefaultActiveTab = defaultActiveTab;\n\n if (args.originalPosition === defaultActiveTab) {\n newDefaultActiveTab = args.newPosition;\n } else if (args.originalPosition < defaultActiveTab && args.newPosition >= defaultActiveTab) {\n // a tab was moved from the left of the default active tab the right of it, changing its index\n newDefaultActiveTab--;\n } else if (args.originalPosition > defaultActiveTab && args.newPosition <= defaultActiveTab) {\n // a tab was moved from the right of the default active tab the left of it, changing its index\n newDefaultActiveTab++;\n }\n\n _this.updateData(\"default_active\", newDefaultActiveTab.toString());\n }\n }); // Monitor focus tab to start / stop interaction on the stage, debounce to avoid duplicate calls\n\n\n _this.focusedTab.subscribe(_underscore.debounce(function (index) {\n if (index !== null) {\n _events.trigger(\"stage:interactionStart\");\n\n (0, _delayUntil)(function () {\n return (0, _jquery)((0, _jquery)(_this.wrapperElement).find(\".tab-header\")[index]).find(\"[contenteditable]\").focus();\n }, function () {\n return (0, _jquery)((0, _jquery)(_this.wrapperElement).find(\".tab-header\")[index]).find(\"[contenteditable]\").length > 0;\n }, 10);\n } else {\n // We have to force the stop as the event firing is inconsistent for certain operations\n _events.trigger(\"stage:interactionStop\", {\n force: true\n });\n }\n }, 1));\n\n return _this;\n }\n /**\n * Remove focused tab\n */\n\n\n var _proto = Preview.prototype;\n\n _proto.destroy = function destroy() {\n var _this2 = this;\n\n _previewCollection2.prototype.destroy.call(this);\n\n _underscore.defer(function () {\n return _this2.setFocusedTab(null);\n });\n }\n /**\n * Refresh the tabs instance when new content appears\n *\n * @param {number} focusIndex\n * @param {boolean} forceFocus\n * @param {number} activeIndex\n */\n ;\n\n _proto.refreshTabs = function refreshTabs(focusIndex, forceFocus, activeIndex) {\n try {\n (0, _jquery)(this.element).tabs(\"refresh\");\n\n if (focusIndex >= 0) {\n this.setFocusedTab(focusIndex, forceFocus);\n } else if (activeIndex) {\n this.setActiveTab(activeIndex);\n } // update sortability of tabs\n\n\n var sortableElement = (0, _jquery)(this.element).find(\".tabs-navigation\");\n\n if (sortableElement.hasClass(\"ui-sortable\")) {\n if (this.contentType.children().length <= 1) {\n sortableElement.sortable(\"disable\");\n } else {\n sortableElement.sortable(\"enable\");\n }\n }\n } catch (e) {\n this.buildTabs();\n }\n }\n /**\n * Set the active tab, we maintain a reference to it in an observable for when we rebuild the tab instance\n *\n * @param {number} index\n */\n ;\n\n _proto.setActiveTab = function setActiveTab(index) {\n var _this3 = this;\n\n if (index !== null) {\n // Added to prevent mismatched fragment error caused by not yet rendered tab-item\n index = parseInt(index.toString(), 10);\n (0, _delayUntil)(function () {\n (0, _jquery)(_this3.element).tabs(\"option\", \"active\", index);\n\n _this3.activeTab(index);\n\n _events.trigger(\"contentType:redrawAfter\", {\n id: _this3.contentType.id,\n contentType: _this3\n });\n }, function () {\n return (0, _jquery)(_this3.element).find(\".pagebuilder-tab-item\").length >= index + 1;\n });\n }\n }\n /**\n * Set the focused tab\n *\n * @param {number} index\n * @param {boolean} force\n */\n ;\n\n _proto.setFocusedTab = function setFocusedTab(index, force) {\n if (force === void 0) {\n force = false;\n }\n\n this.setActiveTab(index);\n\n if (force) {\n this.focusedTab(null);\n }\n\n this.focusedTab(index);\n }\n /**\n * Return an array of options\n *\n * @returns {OptionsInterface}\n */\n ;\n\n _proto.retrieveOptions = function retrieveOptions() {\n var options = _previewCollection2.prototype.retrieveOptions.call(this);\n\n options.add = new _option({\n preview: this,\n icon: \"<i class='icon-pagebuilder-add'></i>\",\n title: (0, _translate)(\"Add\"),\n action: this.addTab,\n classes: [\"add-child\"],\n sort: 10\n });\n options.hideShow = new _hideShowOption({\n preview: this,\n icon: _hideShowOption.showIcon,\n title: _hideShowOption.showText,\n action: this.onOptionVisibilityToggle,\n classes: [\"hide-show-content-type\"],\n sort: 40\n });\n return options;\n }\n /**\n * Add a tab\n */\n ;\n\n _proto.addTab = function addTab() {\n var _this4 = this;\n\n (0, _contentTypeFactory)(_config.getContentTypeConfig(\"tab-item\"), this.contentType, this.contentType.stageId).then(function (tab) {\n _events.on(\"tab-item:mountAfter\", function (args) {\n if (args.id === tab.id) {\n _this4.setFocusedTab(_this4.contentType.children().length - 1);\n\n _events.off(\"tab-item:\" + tab.id + \":mountAfter\");\n }\n }, \"tab-item:\" + tab.id + \":mountAfter\");\n\n _this4.contentType.addChild(tab, _this4.contentType.children().length); // Update the default tab title when adding a new tab\n\n\n tab.dataStore.set(\"tab_name\", (0, _translate)(\"Tab\") + \" \" + (_this4.contentType.children.indexOf(tab) + 1));\n });\n }\n /**\n * On render init the tabs widget\n *\n * @param {Element} element\n */\n ;\n\n _proto.onContainerRender = function onContainerRender(element) {\n this.element = element;\n this.onContainerRenderDeferred.resolve(element);\n }\n /**\n * Copy over border styles to the tab headers\n *\n * @returns {any}\n */\n ;\n\n _proto.getTabHeaderStyles = function getTabHeaderStyles() {\n var headerStyles = this.data.headers.style();\n return _extends({}, headerStyles, {\n marginBottom: \"-\" + headerStyles.borderWidth,\n marginLeft: \"-\" + headerStyles.borderWidth\n });\n }\n /**\n * Get the sortable options for the tab heading sorting\n *\n * @returns {JQueryUI.SortableOptions}\n */\n ;\n\n _proto.getSortableOptions = function getSortableOptions() {\n var self = this;\n var borderWidth;\n return {\n handle: \".tab-drag-handle\",\n tolerance: \"pointer\",\n cursor: \"grabbing\",\n cursorAt: {\n left: 8,\n top: 25\n },\n\n /**\n * Provide custom helper element\n *\n * @param {Event} event\n * @param {JQueryUI.Sortable} element\n * @returns {Element}\n */\n helper: function helper(event, element) {\n var helper = (0, _jquery)(element).clone().css(\"opacity\", \"0.7\");\n helper[0].querySelector(\".pagebuilder-options\").remove();\n return helper[0];\n },\n\n /**\n * Add a padding to the navigation UL to resolve issues of negative margins when sorting\n *\n * @param {Event} event\n * @param {JQueryUI.SortableUIParams} ui\n */\n start: function start(event, ui) {\n /**\n * Due to the way we use negative margins to overlap the borders we need to apply a padding to the\n * container when we're moving the first item to ensure the tabs remain in the same place.\n */\n if (ui.item.index() === 0) {\n borderWidth = parseInt(ui.item.css(\"borderWidth\"), 10) || 1;\n (0, _jquery)(this).css(\"paddingLeft\", borderWidth);\n }\n\n ui.helper.css(\"width\", \"\");\n\n _events.trigger(\"stage:interactionStart\");\n\n self.disableInteracting = true;\n },\n\n /**\n * Remove the padding once the operation is completed\n *\n * @param {Event} event\n * @param {JQueryUI.SortableUIParams} ui\n */\n stop: function stop(event, ui) {\n (0, _jquery)(this).css(\"paddingLeft\", \"\");\n\n _events.trigger(\"stage:interactionStop\");\n\n self.disableInteracting = false;\n },\n placeholder: {\n /**\n * Provide custom placeholder element\n *\n * @param {JQuery} item\n * @returns {JQuery}\n */\n element: function element(item) {\n var placeholder = item.clone().css({\n display: \"inline-block\",\n opacity: \"0.3\"\n }).removeClass(\"focused\").addClass(\"sortable-placeholder\");\n placeholder[0].querySelector(\".pagebuilder-options\").remove();\n return placeholder[0];\n },\n update: function update() {\n return;\n }\n }\n };\n }\n /**\n * Bind events\n */\n ;\n\n _proto.bindEvents = function bindEvents() {\n var _this5 = this;\n\n _previewCollection2.prototype.bindEvents.call(this); // ContentType being mounted onto container\n\n\n _events.on(\"tabs:dropAfter\", function (args) {\n if (args.id === _this5.contentType.id && _this5.contentType.children().length === 0) {\n _this5.addTab();\n }\n }); // ContentType being removed from container\n\n\n _events.on(\"tab-item:removeAfter\", function (args) {\n if (args.parentContentType && args.parentContentType.id === _this5.contentType.id) {\n // Mark the previous tab as active\n var newIndex = args.index - 1 >= 0 ? args.index - 1 : 0;\n\n _this5.refreshTabs(newIndex, true);\n }\n }); // Capture when a content type is duplicated within the container\n\n\n var duplicatedTab;\n var duplicatedTabIndex;\n\n _events.on(\"tab-item:duplicateAfter\", function (args) {\n if (_this5.contentType.id === args.duplicateContentType.parentContentType.id && args.direct) {\n var tabData = args.duplicateContentType.dataStore.getState();\n args.duplicateContentType.dataStore.set(\"tab_name\", tabData.tab_name.toString() + \" copy\");\n duplicatedTab = args.duplicateContentType;\n duplicatedTabIndex = args.index;\n }\n });\n\n _events.on(\"tab-item:mountAfter\", function (args) {\n if (duplicatedTab && args.id === duplicatedTab.id) {\n _this5.refreshTabs(duplicatedTabIndex, true);\n\n duplicatedTab = duplicatedTabIndex = null;\n }\n\n if (_this5.contentType.id === args.contentType.parentContentType.id) {\n _this5.updateTabNamesInDataStore();\n\n args.contentType.dataStore.subscribe(function () {\n _this5.updateTabNamesInDataStore();\n });\n }\n });\n\n this.contentType.dataStore.subscribe(function (data) {\n _this5.activeTab(data.default_active);\n });\n }\n /**\n * Update data store with active options\n */\n ;\n\n _proto.updateTabNamesInDataStore = function updateTabNamesInDataStore() {\n var activeOptions = [];\n this.contentType.children().forEach(function (tab, index) {\n var tabData = tab.dataStore.getState();\n activeOptions.push({\n label: tabData.tab_name.toString(),\n labeltitle: tabData.tab_name.toString(),\n value: index\n });\n });\n this.contentType.dataStore.set(\"_default_active_options\", activeOptions);\n }\n /**\n * Assign a debounce and delay to the init of tabs to ensure the DOM has updated\n *\n * @type {(() => void) & _.Cancelable}\n */\n ;\n\n _proto.buildTabs = function buildTabs(activeTabIndex) {\n var _this6 = this;\n\n if (activeTabIndex === void 0) {\n activeTabIndex = this.activeTab() || 0;\n }\n\n this.ready = false;\n\n if (this.element && this.element.children.length > 0) {\n var focusedTab = this.focusedTab();\n\n try {\n (0, _jquery)(this.element).tabs(\"destroy\");\n } catch (e) {// We aren't concerned if this fails, tabs throws an Exception when we cannot destroy\n }\n\n (0, _jquery)(this.element).tabs({\n create: function create() {\n _this6.ready = true; // Ensure focus tab is restored after a rebuild cycle\n\n if (focusedTab !== null) {\n _this6.setFocusedTab(focusedTab, true);\n } else {\n _this6.setFocusedTab(null);\n\n if (activeTabIndex) {\n _this6.setActiveTab(activeTabIndex);\n }\n }\n },\n\n /**\n * Trigger redraw event since new content is being displayed\n */\n activate: function activate() {\n _events.trigger(\"contentType:redrawAfter\", {\n element: _this6.element\n });\n }\n });\n }\n };\n\n return Preview;\n }(_previewCollection); // Resolve issue with jQuery UI tabs content typing events on content editable areas\n\n\n var originalTabKeyDown = _jquery.ui.tabs.prototype._tabKeydown;\n\n _jquery.ui.tabs.prototype._tabKeydown = function (event) {\n // If the target is content editable don't handle any events\n if ((0, _jquery)(event.target).attr(\"contenteditable\")) {\n return;\n }\n\n originalTabKeyDown.call(this, event);\n };\n\n return Preview;\n});\n//# sourceMappingURL=preview.js.map","Magento_PageBuilder/js/content-type/tabs/appearance/default/widget.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n 'jquery',\n 'Magento_PageBuilder/js/events',\n 'jquery-ui-modules/tabs'\n], function ($, events) {\n 'use strict';\n\n return function (config, element) {\n var $element = $(element);\n\n // Ignore stage builder preview tabs\n if ($element.is('.pagebuilder-tabs')) {\n return;\n }\n\n // Disambiguate between the mage/tabs component which is loaded randomly depending on requirejs order.\n $.ui.tabs({\n active: $element.data('activeTab') || 0,\n create:\n\n /**\n * Adjust the margin bottom of the navigation to correctly display the active tab\n */\n function () {\n var borderWidth = parseInt($element.find('.tabs-content').css('borderWidth').toString(), 10);\n\n $element.find('.tabs-navigation').css('marginBottom', -borderWidth);\n $element.find('.tabs-navigation li:not(:first-child)').css('marginLeft', -borderWidth);\n },\n activate:\n\n /**\n * Trigger redraw event since new content is being displayed\n */\n function () {\n events.trigger('contentType:redrawAfter', {\n element: element\n });\n }\n }, element);\n };\n});\n","Magento_PageBuilder/js/content-type/tabs/mass-converter/header-alignment.js":"/*eslint-disable */\n/* jscs:disable */\ndefine([\"Magento_PageBuilder/js/utils/object\"], function (_object) {\n /**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n var HeaderAlignment = /*#__PURE__*/function () {\n \"use strict\";\n\n function HeaderAlignment() {}\n\n var _proto = HeaderAlignment.prototype;\n\n /**\n * Process data after it's read and converted by element converters\n *\n * @param {ConverterDataInterface} data\n * @param {ConverterConfigInterface} config\n * @returns {object}\n */\n _proto.fromDom = function fromDom(data, config) {\n return data;\n }\n /**\n * Add our tab alignment class into the data for the tabs\n *\n * @param {ConverterDataInterface} data\n * @param {ConverterConfigInterface} config\n * @returns {object}\n */\n ;\n\n _proto.toDom = function toDom(data, config) {\n data.css_classes += \" tab-align-\" + (0, _object.get)(data, config.navigation_alignment_variable, \"left\");\n return data;\n };\n\n return HeaderAlignment;\n }();\n\n return HeaderAlignment;\n});\n//# sourceMappingURL=header-alignment.js.map","Magento_PageBuilder/js/content-type/buttons/preview.js":"/*eslint-disable */\n/* jscs:disable */\n\nfunction _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); }\n\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n\ndefine([\"jquery\", \"knockout\", \"mage/translate\", \"Magento_PageBuilder/js/events\", \"underscore\", \"Magento_PageBuilder/js/config\", \"Magento_PageBuilder/js/content-type-factory\", \"Magento_PageBuilder/js/content-type-menu/hide-show-option\", \"Magento_PageBuilder/js/content-type-menu/option\", \"Magento_PageBuilder/js/utils/delay-until\", \"Magento_PageBuilder/js/content-type/preview-collection\"], function (_jquery, _knockout, _translate, _events, _underscore, _config, _contentTypeFactory, _hideShowOption, _option, _delayUntil, _previewCollection) {\n /**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n /**\n * @api\n */\n var Preview = /*#__PURE__*/function (_previewCollection2) {\n \"use strict\";\n\n _inheritsLoose(Preview, _previewCollection2);\n\n /**\n * @param {ContentTypeCollectionInterface} contentType\n * @param {ContentTypeConfigInterface} config\n * @param {ObservableUpdater} observableUpdater\n */\n function Preview(contentType, config, observableUpdater) {\n var _this;\n\n _this = _previewCollection2.call(this, contentType, config, observableUpdater) || this; // Keeps track of number of button item to disable sortable if there is only 1.\n\n _this.focusedButton = _knockout.observable();\n _this.debouncedResizeHandler = _underscore.debounce(function () {\n _this.resizeChildButtons();\n }, 350);\n\n _this.contentType.children.subscribe(function () {\n var sortableElement = (0, _jquery)(_this.wrapperElement).find(\".buttons-container\");\n\n if (!sortableElement.data(\"ui-sortable\")) {\n return;\n }\n\n if (_this.contentType.children().length <= 1) {\n sortableElement.sortable(\"disable\");\n } else {\n sortableElement.sortable(\"enable\");\n }\n }); // Monitor focus tab to start / stop interaction on the stage, debounce to avoid duplicate calls\n\n\n _this.focusedButton.subscribe(_underscore.debounce(function (index) {\n if (index !== null) {\n _events.trigger(\"stage:interactionStart\");\n\n var focusedButton = _this.contentType.children()[index];\n\n (0, _delayUntil)(function () {\n return (0, _jquery)(focusedButton.preview.wrapperElement).find(\"[contenteditable]\").focus();\n }, function () {\n return typeof focusedButton.preview.wrapperElement !== \"undefined\";\n }, 10);\n } else {\n // We have to force the stop as the event firing is inconsistent for certain operations\n _events.trigger(\"stage:interactionStop\", {\n force: true\n });\n }\n }, 1));\n\n return _this;\n }\n /**\n * Bind events\n */\n\n\n var _proto = Preview.prototype;\n\n _proto.bindEvents = function bindEvents() {\n var _this2 = this;\n\n _previewCollection2.prototype.bindEvents.call(this);\n\n _events.on(\"buttons:dropAfter\", function (args) {\n if (args.id === _this2.contentType.id && _this2.contentType.children().length === 0) {\n _this2.addButton();\n }\n });\n\n _events.on(\"buttons:renderAfter\", function (args) {\n if (args.contentType.id === _this2.contentType.id) {\n _this2.debouncedResizeHandler();\n }\n });\n\n _events.on(\"button-item:renderAfter\", function (args) {\n if (args.contentType.parentContentType.id === _this2.contentType.id) {\n _this2.debouncedResizeHandler();\n }\n });\n\n _events.on(\"stage:updateAfter\", function () {\n _this2.debouncedResizeHandler();\n });\n\n _events.on(\"contentType:redrawAfter\", function () {\n _this2.debouncedResizeHandler();\n }); // Capture when a content type is duplicated within the container\n\n\n var duplicatedButton;\n var duplicatedButtonIndex;\n\n _events.on(\"button-item:duplicateAfter\", function (args) {\n if (_this2.contentType.id === args.duplicateContentType.parentContentType.id && args.direct) {\n duplicatedButton = args.duplicateContentType;\n duplicatedButtonIndex = args.index;\n }\n });\n\n _events.on(\"button-item:mountAfter\", function (args) {\n if (duplicatedButton && args.id === duplicatedButton.id) {\n _this2.focusedButton(duplicatedButtonIndex);\n }\n });\n }\n /**\n * Return an array of options\n *\n * @returns {OptionsInterface}\n */\n ;\n\n _proto.retrieveOptions = function retrieveOptions() {\n var options = _previewCollection2.prototype.retrieveOptions.call(this);\n\n options.add = new _option({\n preview: this,\n icon: \"<i class='icon-pagebuilder-add'></i>\",\n title: (0, _translate)(\"Add Button\"),\n action: this.addButton,\n classes: [\"add-child\"],\n sort: 10\n });\n options.hideShow = new _hideShowOption({\n preview: this,\n icon: _hideShowOption.showIcon,\n title: _hideShowOption.showText,\n action: this.onOptionVisibilityToggle,\n classes: [\"hide-show-content-type\"],\n sort: 40\n });\n return options;\n }\n /**\n * Add button-item to buttons children array\n */\n ;\n\n _proto.addButton = function addButton() {\n var _this3 = this;\n\n var createButtonItemPromise = (0, _contentTypeFactory)(_config.getContentTypeConfig(\"button-item\"), this.contentType, this.contentType.stageId, {});\n createButtonItemPromise.then(function (button) {\n _this3.contentType.addChild(button);\n\n var buttonIndex = _this3.contentType.children().indexOf(button);\n\n _this3.focusedButton(buttonIndex > -1 ? buttonIndex : null);\n\n return button;\n }).catch(function (error) {\n console.error(error);\n });\n }\n /**\n * Get the sortable options for the buttons sorting\n *\n * @param {string} orientation\n * @param {string} tolerance\n * @returns {JQueryUI.Sortable}\n */\n ;\n\n _proto.getSortableOptions = function getSortableOptions(orientation, tolerance) {\n if (orientation === void 0) {\n orientation = \"width\";\n }\n\n if (tolerance === void 0) {\n tolerance = \"intersect\";\n }\n\n return {\n handle: \".button-item-drag-handle\",\n items: \".pagebuilder-content-type-wrapper\",\n cursor: \"grabbing\",\n containment: \"parent\",\n tolerance: tolerance,\n revert: 200,\n disabled: this.contentType.children().length <= 1,\n\n /**\n * Provide custom helper element\n *\n * @param {Event} event\n * @param {JQueryUI.Sortable} element\n * @returns {Element}\n */\n helper: function helper(event, element) {\n var helper = (0, _jquery)(element).clone().css({\n opacity: \"0.7\",\n width: \"auto\"\n });\n helper[0].querySelector(\".pagebuilder-options\").remove();\n return helper[0];\n },\n placeholder: {\n /**\n * Provide custom placeholder element\n *\n * @param {JQuery} item\n * @returns {JQuery}\n */\n element: function element(item) {\n var placeholder = item.clone().css({\n display: \"inline-block\",\n opacity: \"0.3\"\n }).removeClass(\"focused\").addClass(\"sortable-placeholder\");\n placeholder[0].querySelector(\".pagebuilder-options\").remove();\n return placeholder[0];\n },\n update: function update() {\n return;\n }\n },\n\n /**\n * Trigger interaction start on sort\n */\n start: function start() {\n _events.trigger(\"stage:interactionStart\");\n },\n\n /**\n * Stop stage interaction on stop\n */\n stop: function stop() {\n _events.trigger(\"stage:interactionStop\");\n }\n };\n }\n /**\n * Resize width of all child buttons. Dependently make them the same width if configured.\n */\n ;\n\n _proto.resizeChildButtons = function resizeChildButtons() {\n if (this.wrapperElement) {\n var buttonItems = (0, _jquery)(this.wrapperElement).find(\".pagebuilder-button-item > a\");\n var buttonResizeValue = 0;\n\n if (this.contentType.dataStore.get(\"is_same_width\") === \"true\") {\n if (buttonItems.length > 0) {\n var currentLargestButtonWidth = this.findLargestButtonWidth(buttonItems);\n var parentWrapperWidth = (0, _jquery)(this.wrapperElement).find(\".buttons-container\").width();\n\n if (currentLargestButtonWidth === 0) {\n return;\n }\n\n buttonResizeValue = Math.min(currentLargestButtonWidth, parentWrapperWidth);\n }\n }\n\n buttonItems.css(\"min-width\", buttonResizeValue);\n }\n }\n /**\n * Find the largest button width for calculating same size value.\n *\n * @param {JQuery} buttonItems\n * @returns {number}\n */\n ;\n\n _proto.findLargestButtonWidth = function findLargestButtonWidth(buttonItems) {\n var _this4 = this;\n\n return _underscore.max(_underscore.map(buttonItems, function (buttonItem) {\n return _this4.calculateButtonWidth((0, _jquery)(buttonItem));\n }));\n }\n /**\n * Manually calculate button width using content plus box widths (padding, border)\n *\n * @param {JQuery} buttonItem\n * @returns {number}\n */\n ;\n\n _proto.calculateButtonWidth = function calculateButtonWidth(buttonItem) {\n if (buttonItem.is(\":visible\") === false) {\n return 0;\n }\n\n var widthProperties = [\"paddingLeft\", \"paddingRight\", \"borderLeftWidth\", \"borderRightWidth\"];\n var buttonText = buttonItem.find(\"[data-element='link_text']\");\n var textWidth = buttonText.css(\"display\", \"inline-block\").width();\n buttonText.css(\"display\", \"\");\n return widthProperties.reduce(function (accumulatedWidth, widthProperty) {\n return accumulatedWidth + (parseInt(buttonItem.css(widthProperty), 10) || 0);\n }, textWidth);\n };\n\n return Preview;\n }(_previewCollection);\n\n return Preview;\n});\n//# sourceMappingURL=preview.js.map","Magento_PageBuilder/js/content-type/buttons/appearance/inline/widget.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n 'jquery',\n 'Magento_PageBuilder/js/events'\n], function ($, events) {\n 'use strict';\n\n /**\n * Equalize the width of a list of button-item components\n *\n * @param {JQuery} buttonList\n */\n var equalizeButtonWidth = function (buttonList) {\n var buttonMinWidth = 0;\n\n buttonList.css('min-width', buttonMinWidth);\n buttonList.each(function () {\n var buttonWidth = this.offsetWidth;\n\n if (buttonWidth > buttonMinWidth) {\n buttonMinWidth = buttonWidth;\n }\n });\n buttonList.css('min-width', buttonMinWidth);\n };\n\n return function (config, element) {\n var $element = $(element),\n buttonSelector = '[data-element=\"link\"], [data-element=\"empty_link\"]';\n\n if ($element.data('sameWidth')) {\n equalizeButtonWidth($element.find(buttonSelector));\n $(window).on('resize', function () {\n equalizeButtonWidth($element.find(buttonSelector));\n });\n events.on('contentType:redrawAfter', function (eventData) {\n if ($element.closest(eventData.element).length > 0) {\n equalizeButtonWidth($element.find(buttonSelector));\n }\n });\n }\n };\n});\n","Magento_PageBuilder/js/content-type/buttons/converter/style/display/flex.js":"/*eslint-disable */\n/* jscs:disable */\ndefine([\"underscore\", \"Magento_PageBuilder/js/utils/object\"], function (_underscore, _object) {\n /**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n /**\n * @api\n */\n var Flex = /*#__PURE__*/function () {\n \"use strict\";\n\n function Flex() {}\n\n var _proto = Flex.prototype;\n\n /**\n * Convert value to internal format\n *\n * @param value string\n * @returns {string | object}\n */\n _proto.fromDom = function fromDom(value) {\n return !(value === \"none\");\n }\n /**\n * Convert value to knockout format, if buttons are displayed they should be inline block\n *\n * @param {string} name\n * @param {DataObject} data\n * @returns {string}\n */\n ;\n\n _proto.toDom = function toDom(name, data) {\n var value = (0, _object.get)(data, name);\n\n if (!_underscore.isUndefined(value) && value === false) {\n return \"none\";\n }\n\n return \"flex\";\n };\n\n return Flex;\n }();\n\n return Flex;\n});\n//# sourceMappingURL=flex.js.map","Magento_PageBuilder/js/content-type/buttons/converter/style/display/boolean.js":"/*eslint-disable */\n/* jscs:disable */\ndefine([\"underscore\", \"Magento_PageBuilder/js/utils/object\"], function (_underscore, _object) {\n /**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n /**\n * @api\n */\n var Boolean = /*#__PURE__*/function () {\n \"use strict\";\n\n function Boolean() {}\n\n var _proto = Boolean.prototype;\n\n /**\n * Convert value to internal format\n *\n * @param value string\n * @returns {string | object}\n */\n _proto.fromDom = function fromDom(value) {\n return !(value === \"none\");\n }\n /**\n * Convert value to knockout format, if buttons are displayed they should be reset to default\n *\n * @param {string} name\n * @param {DataObject} data\n * @returns {string}\n */\n ;\n\n _proto.toDom = function toDom(name, data) {\n var value = (0, _object.get)(data, name);\n\n if (!_underscore.isUndefined(value) && value === false) {\n return \"none\";\n }\n\n return \"\";\n };\n\n return Boolean;\n }();\n\n return Boolean;\n});\n//# sourceMappingURL=boolean.js.map","Magento_PageBuilder/js/content-type/buttons/converter/style/preview/display/flex.js":"/*eslint-disable */\n/* jscs:disable */\ndefine([], function () {\n /**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n /**\n * @api\n */\n var Display = /*#__PURE__*/function () {\n \"use strict\";\n\n function Display() {}\n\n var _proto = Display.prototype;\n\n /**\n * Ensure the display none property doesn't persist to the preview\n *\n * @param value string\n * @returns {string | object}\n */\n _proto.fromDom = function fromDom(value) {\n return;\n }\n /**\n * Ensure the display none property doesn't persist to the preview\n *\n * @param name string\n * @param data Object\n * @returns {string}\n */\n ;\n\n _proto.toDom = function toDom(name, data) {\n return \"flex\";\n };\n\n return Display;\n }();\n\n return Display;\n});\n//# sourceMappingURL=flex.js.map","Magento_PageBuilder/js/content-type/row/preview.js":"/*eslint-disable */\n/* jscs:disable */\n\nfunction _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return self; }\n\nfunction _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); }\n\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n\ndefine([\"jarallax\", \"jarallaxVideo\", \"jquery\", \"knockout\", \"Magento_PageBuilder/js/events\", \"Magento_PageBuilder/js/resource/resize-observer/ResizeObserver\", \"underscore\", \"vimeoWrapper\", \"Magento_PageBuilder/js/content-type-menu/hide-show-option\", \"Magento_PageBuilder/js/content-type/preview-collection\"], function (_jarallax, _jarallaxVideo, _jquery, _knockout, _events, _ResizeObserver, _underscore, _vimeoWrapper, _hideShowOption, _previewCollection) {\n /**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n /**\n * @api\n */\n var Preview = /*#__PURE__*/function (_previewCollection2) {\n \"use strict\";\n\n _inheritsLoose(Preview, _previewCollection2);\n\n /**\n * Debounce and defer the init of Jarallax\n *\n * @type {(() => void) & _.Cancelable}\n */\n\n /**\n * @param {ContentTypeInterface} contentType\n * @param {ContentTypeConfigInterface} config\n * @param {ObservableUpdater} observableUpdater\n */\n function Preview(contentType, config, observableUpdater) {\n var _this;\n\n _this = _previewCollection2.call(this, contentType, config, observableUpdater) || this;\n _this.wrapClass = _knockout.observable(false);\n _this.buildJarallax = _underscore.debounce(function () {\n // Destroy all instances of the plugin prior\n try {\n jarallax(_this.element, \"destroy\");\n } catch (e) {// Failure of destroying is acceptable\n }\n\n if (_this.element && (0, _jquery)(_this.element).hasClass(\"jarallax\") && _this.contentType.dataStore.get(\"background_type\") !== \"video\" && _this.contentType.dataStore.get(\"background_image\").length) {\n _underscore.defer(function () {\n // Build Parallax on elements with the correct class\n var parallaxSpeed = Number.parseFloat(_this.contentType.dataStore.get(\"parallax_speed\"));\n jarallax(_this.element, {\n imgPosition: _this.contentType.dataStore.get(\"background_position\") || \"50% 50%\",\n imgRepeat: _this.contentType.dataStore.get(\"background_repeat\") || \"no-repeat\",\n imgSize: _this.contentType.dataStore.get(\"background_size\") || \"cover\",\n speed: !isNaN(parallaxSpeed) ? parallaxSpeed : 0.5\n });\n jarallax(_this.element, \"onResize\");\n });\n }\n\n if (_this.element && _this.element.dataset.backgroundType === \"video\" && _this.element.dataset.videoSrc.length) {\n var parallaxSpeed = _this.contentType.dataStore.get(\"enable_parallax\") === \"1\" ? Number.parseFloat(_this.contentType.dataStore.get(\"parallax_speed\")) : 1;\n\n _underscore.defer(function () {\n // Build Parallax on elements with the correct class\n jarallax(_this.element, {\n videoSrc: _this.element.dataset.videoSrc,\n imgSrc: _this.element.dataset.videoFallbackSrc,\n videoLoop: _this.contentType.dataStore.get(\"video_loop\") === \"true\",\n speed: !isNaN(parallaxSpeed) ? parallaxSpeed : 0.5,\n videoPlayOnlyVisible: _this.contentType.dataStore.get(\"video_play_only_visible\") === \"true\",\n videoLazyLoading: _this.contentType.dataStore.get(\"video_lazy_load\") === \"true\"\n }); // @ts-ignore\n\n if (_this.element.jarallax && _this.element.jarallax.video) {\n // @ts-ignore\n _this.element.jarallax.video.on(\"started\", function () {\n // @ts-ignore\n if (_this.element.jarallax.$video) {\n // @ts-ignore\n _this.element.jarallax.$video.style.visibility = \"visible\";\n }\n });\n }\n });\n }\n }, 50);\n\n _this.contentType.dataStore.subscribe(_this.buildJarallax);\n\n _events.on(\"row:mountAfter\", function (args) {\n if (args.id === _this.contentType.id) {\n _this.buildJarallax();\n }\n });\n\n _events.on(\"contentType:mountAfter\", function (args) {\n if (args.contentType.parentContentType && args.contentType.parentContentType.id === _this.contentType.id) {\n _this.buildJarallax();\n }\n });\n\n _events.on(\"stage:\" + _this.contentType.stageId + \":fullScreenModeChangeAfter\", _this.toggleFullScreen.bind(_assertThisInitialized(_this)));\n\n _events.on(\"stage:\" + _this.contentType.stageId + \":viewportChangeAfter\", function (args) {\n _this.buildJarallax();\n });\n\n return _this;\n }\n /**\n * Get background image url base on the viewport.\n *\n * @returns {string}\n */\n\n\n var _proto = Preview.prototype;\n\n _proto.getBackgroundImage = function getBackgroundImage() {\n var mobileImage = this.contentType.dataStore.get(\"mobile_image\");\n var desktopImage = this.contentType.dataStore.get(\"background_image\");\n var backgroundImage = this.viewport() === \"mobile\" && mobileImage.length ? mobileImage : desktopImage;\n return backgroundImage.length ? \"url(\\\"\" + backgroundImage[0].url + \"\\\")\" : \"none\";\n }\n /**\n * Toggle fullscreen\n */\n ;\n\n _proto.toggleFullScreen = function toggleFullScreen() {\n if ((0, _jquery)(this.element).hasClass(\"jarallax\")) {\n this.buildJarallax();\n }\n }\n /**\n * Use the conditional remove to disable the option when the content type has a single child\n *\n * @returns {OptionsInterface}\n */\n ;\n\n _proto.retrieveOptions = function retrieveOptions() {\n var options = _previewCollection2.prototype.retrieveOptions.call(this);\n\n options.hideShow = new _hideShowOption({\n preview: this,\n icon: _hideShowOption.showIcon,\n title: _hideShowOption.showText,\n action: this.onOptionVisibilityToggle,\n classes: [\"hide-show-content-type\"],\n sort: 40\n });\n return options;\n }\n /**\n * Init the parallax element\n *\n * @param {HTMLElement} element\n */\n ;\n\n _proto.initParallax = function initParallax(element) {\n var _this2 = this;\n\n this.element = element;\n\n _underscore.defer(function () {\n _this2.buildJarallax();\n });\n\n new _ResizeObserver(function () {\n // Observe for resizes of the element and force jarallax to display correctly\n if ((0, _jquery)(_this2.element).hasClass(\"jarallax\") && _this2.contentType.dataStore.get(\"background_image\").length) {\n jarallax(_this2.element, \"onResize\");\n jarallax(_this2.element, \"onScroll\");\n }\n }).observe(this.element);\n }\n /**\n * Destroy jarallax instance.\n */\n ;\n\n _proto.destroy = function destroy() {\n _previewCollection2.prototype.destroy.call(this);\n\n if (this.element) {\n jarallax(this.element, \"destroy\");\n }\n }\n /**\n * Return selected element styles\n *\n * @param element\n * @param styleProperties\n */\n ;\n\n _proto.getStyle = function getStyle(element, styleProperties) {\n var stylesObject = element.style();\n return styleProperties.reduce(function (obj, key) {\n var _extends2;\n\n return _extends({}, obj, (_extends2 = {}, _extends2[key] = stylesObject[key], _extends2));\n }, {});\n }\n /**\n * Return element styles without selected\n *\n * @param element\n * @param styleProperties\n */\n ;\n\n _proto.getStyleWithout = function getStyleWithout(element, styleProperties) {\n var stylesObject = element.style();\n return Object.keys(stylesObject).filter(function (key) {\n return !styleProperties.includes(key);\n }).reduce(function (obj, key) {\n var _extends3;\n\n return _extends({}, obj, (_extends3 = {}, _extends3[key] = stylesObject[key], _extends3));\n }, {});\n };\n\n return Preview;\n }(_previewCollection);\n\n return Preview;\n});\n//# sourceMappingURL=preview.js.map","Magento_PageBuilder/js/content-type/row/appearance/default/widget.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n 'jquery',\n 'Magento_PageBuilder/js/widget/video-background',\n 'jarallax'\n], function ($, videoBackground) {\n 'use strict';\n\n return function (config, element) {\n var $element = $(element),\n parallaxSpeed = null,\n elementStyle = null;\n\n if ($element.data('appearance') === 'contained') {\n $element = $(element).find('[data-element=\"inner\"]');\n }\n\n if ($element.data('background-type') === 'video') {\n videoBackground(config, $element[0]);\n\n return;\n }\n\n if ($element.data('enableParallax') !== 1) {\n return;\n }\n\n $element.addClass('jarallax');\n $element.attr('data-jarallax', '');\n\n parallaxSpeed = parseFloat($element.data('parallaxSpeed'));\n elementStyle = window.getComputedStyle($element[0]);\n\n window.jarallax($element[0], {\n imgPosition: elementStyle.backgroundPosition || '50% 50%',\n imgRepeat: elementStyle.backgroundRepeat || 'no-repeat',\n imgSize: elementStyle.backgroundSize || 'cover',\n speed: !isNaN(parallaxSpeed) ? parallaxSpeed : 0.5\n });\n };\n});\n","Magento_PageBuilder/js/content-type/row/appearance/default/widget-mixin.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine(['underscore', 'jquery', 'Magento_PageBuilder/js/events'], function (_, $, events) {\n 'use strict';\n\n return function (target) {\n return function (config, element) {\n var result = target(config, element),\n stageId = $(element).parents('[data-role=\"pagebuilder-stage\"]').attr('id'),\n $element = $(element);\n\n if ($element.data('appearance') === 'contained') {\n $element = $(element).find('[data-element=\"inner\"]');\n }\n\n // If Parallax isn't enabled, let's not attach the event\n if ($element.data('enableParallax') !== 1) {\n return result;\n }\n\n // Listen for full screen events and destroy and rebuild jarallax\n events.on('stage:' + stageId + ':fullScreenModeChangeAfter', function () {\n _.delay(function () {\n $element.jarallax('destroy');\n target(config, element);\n }, 350);\n });\n\n return result;\n };\n };\n});\n","Magento_PageBuilder/js/content-type/row/converter/style/paddings.js":"/*eslint-disable */\n/* jscs:disable */\ndefine([\"underscore\", \"Magento_PageBuilder/js/utils/object\"], function (_underscore, _object) {\n /**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n var Paddings = /*#__PURE__*/function () {\n \"use strict\";\n\n function Paddings() {}\n\n var _proto = Paddings.prototype;\n\n /**\n * @param {string} value\n * @returns {Object | string}\n */\n _proto.fromDom = function fromDom(value) {\n return value;\n }\n /**\n * Convert value to knockout format\n *\n * @param {string} name\n * @param {DataObject} data\n * @returns {string | object}\n */\n ;\n\n _proto.toDom = function toDom(name, data) {\n var result = {};\n var value = (0, _object.get)(data, name);\n\n if (value && _underscore.isString(value)) {\n value = JSON.parse(value);\n }\n\n if (value && undefined !== value.padding) {\n result.paddingLeft = value.padding.left ? value.padding.left + \"px\" : \"\";\n result.paddingTop = value.padding.top ? value.padding.top + \"px\" : \"\";\n result.paddingRight = value.padding.right ? value.padding.right + \"px\" : \"\";\n result.paddingBottom = value.padding.bottom ? value.padding.bottom + \"px\" : \"\";\n }\n\n return result;\n };\n\n return Paddings;\n }();\n\n return Paddings;\n});\n//# sourceMappingURL=paddings.js.map","Magento_PageBuilder/js/content-type/row/converter/style/margins.js":"/*eslint-disable */\n/* jscs:disable */\ndefine([\"underscore\", \"Magento_PageBuilder/js/utils/object\"], function (_underscore, _object) {\n /**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n var Margins = /*#__PURE__*/function () {\n \"use strict\";\n\n function Margins() {}\n\n var _proto = Margins.prototype;\n\n /**\n * @param {string} value\n * @returns {Object | string}\n */\n _proto.fromDom = function fromDom(value) {\n return value;\n }\n /**\n * Convert value to knockout format\n *\n * @param {string} name\n * @param {DataObject} data\n * @returns {string | object}\n */\n ;\n\n _proto.toDom = function toDom(name, data) {\n var result = {};\n var value = (0, _object.get)(data, name);\n\n if (value && _underscore.isString(value)) {\n value = JSON.parse(value);\n }\n\n if (value && undefined !== value.margin) {\n result.marginLeft = value.margin.left ? value.margin.left + \"px\" : \"\";\n result.marginTop = value.margin.top ? value.margin.top + \"px\" : \"\";\n result.marginRight = value.margin.right ? value.margin.right + \"px\" : \"\";\n result.marginBottom = (parseInt(value.margin.bottom, 10) > 0 ? value.margin.bottom : 1) + \"px\";\n }\n\n return result;\n };\n\n return Margins;\n }();\n\n return Margins;\n});\n//# sourceMappingURL=margins.js.map","Magento_PageBuilder/js/content-type/slider/preview.js":"/*eslint-disable */\n/* jscs:disable */\n\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return self; }\n\nfunction _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); }\n\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n\ndefine([\"jquery\", \"knockout\", \"mage/translate\", \"Magento_PageBuilder/js/events\", \"slick\", \"underscore\", \"Magento_PageBuilder/js/binding/focus\", \"Magento_PageBuilder/js/config\", \"Magento_PageBuilder/js/content-type-factory\", \"Magento_PageBuilder/js/content-type-menu/hide-show-option\", \"Magento_PageBuilder/js/content-type-menu/option\", \"Magento_PageBuilder/js/utils/delay-until\", \"Magento_PageBuilder/js/utils/promise-deferred\", \"Magento_PageBuilder/js/content-type/preview-collection\"], function (_jquery, _knockout, _translate, _events, _slick, _underscore, _focus, _config, _contentTypeFactory, _hideShowOption, _option, _delayUntil, _promiseDeferred, _previewCollection) {\n /**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n /**\n * @api\n */\n var Preview = /*#__PURE__*/function (_previewCollection2) {\n \"use strict\";\n\n _inheritsLoose(Preview, _previewCollection2);\n\n /**\n * Define keys which when changed should not trigger the slider to be rebuilt\n *\n * @type {string[]}\n */\n\n /**\n * @param {ContentTypeCollectionInterface} contentType\n * @param {ContentTypeConfigInterface} config\n * @param {ObservableUpdater} observableUpdater\n */\n function Preview(contentType, config, observableUpdater) {\n var _this;\n\n _this = _previewCollection2.call(this, contentType, config, observableUpdater) || this; // Wait for the tabs instance to mount and the container to be ready\n\n _this.focusedSlide = _knockout.observable();\n _this.activeSlide = _knockout.observable(0);\n _this.events = {\n columnWidthChangeAfter: \"onColumnResize\"\n };\n _this.ready = false;\n _this.mountAfterDeferred = (0, _promiseDeferred)();\n _this.afterChildrenRenderDeferred = (0, _promiseDeferred)();\n _this.buildSlickDebounce = _underscore.debounce(_this.buildSlick.bind(_assertThisInitialized(_this)), 10);\n _this.ignoredKeysForBuild = [\"display\", \"margins_and_padding\", \"border\", \"border_color\", \"border_radius\", \"border_width\", \"css_classes\", \"name\", \"text_align\"];\n Promise.all([_this.afterChildrenRenderDeferred.promise, _this.mountAfterDeferred.promise]).then(function (_ref) {\n var element = _ref[0],\n expectedChildren = _ref[1];\n // We always create 1 tab when dropping tabs into the instance\n expectedChildren = expectedChildren || 1; // Wait until all children's DOM elements are present before building the tabs instance\n\n (0, _delayUntil)(function () {\n _this.element = element;\n _this.childSubscribe = _this.contentType.children.subscribe(_this.buildSlickDebounce);\n _this.previousData = _this.contentType.dataStore.getState();\n\n _this.contentType.dataStore.subscribe(function (data) {\n if (_this.hasDataChanged(_this.previousData, data)) {\n _this.buildSlickDebounce();\n }\n\n _this.previousData = data;\n });\n\n _this.buildSlick(); // Redraw slide after content type gets redrawn\n\n\n _events.on(\"contentType:redrawAfter\", function (args) {\n var $element = (0, _jquery)(_this.element);\n\n if (args.element && _this.element && $element.closest(args.element).length) {\n $element.slick(\"setPosition\");\n }\n }); // Set the stage to interacting when a slide is focused\n\n\n _this.focusedSlideSubscriber = _this.focusedSlide.subscribe(function (value) {\n if (value !== null) {\n _events.trigger(\"stage:interactionStart\");\n } else {\n _events.trigger(\"stage:interactionStop\");\n }\n });\n\n _events.on(\"stage:\" + _this.contentType.stageId + \":fullScreenModeChangeAfter\", _this.onColumnResize.bind(_assertThisInitialized(_this), [true]));\n\n _events.on(\"stage:\" + _this.contentType.stageId + \":viewportChangeAfter\", function () {\n if (_this.element) {\n (0, _jquery)(_this.element).slick(\"setPosition\");\n\n _this.checkWidth();\n }\n });\n }, function () {\n return (0, _jquery)(element).find(\".pagebuilder-slide\").length === expectedChildren;\n });\n });\n return _this;\n }\n /**\n * Return an array of options\n *\n * @returns {OptionsInterface}\n */\n\n\n var _proto = Preview.prototype;\n\n _proto.retrieveOptions = function retrieveOptions() {\n var options = _previewCollection2.prototype.retrieveOptions.call(this);\n\n options.add = new _option({\n preview: this,\n icon: \"<i class='icon-pagebuilder-add'></i>\",\n title: (0, _translate)(\"Add\"),\n action: this.addSlide,\n classes: [\"add-child\"],\n sort: 10\n });\n options.hideShow = new _hideShowOption({\n preview: this,\n icon: _hideShowOption.showIcon,\n title: _hideShowOption.showText,\n action: this.onOptionVisibilityToggle,\n classes: [\"hide-show-content-type\"],\n sort: 40\n });\n return options;\n }\n /**\n * Set an active slide for navigation dot\n *\n * @param slideIndex\n */\n ;\n\n _proto.setActiveSlide = function setActiveSlide(slideIndex) {\n this.activeSlide(slideIndex);\n }\n /**\n * Set the focused slide\n *\n * @param {number} slideIndex\n * @param {boolean} force\n */\n ;\n\n _proto.setFocusedSlide = function setFocusedSlide(slideIndex, force) {\n if (force === void 0) {\n force = false;\n }\n\n if (force) {\n this.focusedSlide(null);\n }\n\n this.focusedSlide(slideIndex);\n }\n /**\n * Unset focused slide on focusout event.\n *\n * @param {PreviewCollection} data\n * @param {JQueryEventObject} event\n */\n ;\n\n _proto.onFocusOut = function onFocusOut(data, event) {\n var relatedTarget = event.relatedTarget;\n\n if (!relatedTarget && document.activeElement && !(document.activeElement instanceof HTMLBodyElement)) {\n relatedTarget = document.activeElement;\n }\n\n if (!relatedTarget) {\n this.setFocusedSlide(null);\n return;\n }\n\n var $relatedTarget = (0, _jquery)(relatedTarget);\n var isRelatedTargetDescendantOfNavigation = $relatedTarget.closest(this.navigationElement).length;\n var isFocusedOnAnotherSlideInThisSlider = $relatedTarget.hasClass(\"navigation-dot-anchor\") && isRelatedTargetDescendantOfNavigation;\n\n if (isFocusedOnAnotherSlideInThisSlider) {\n _events.trigger(\"stage:interactionStop\");\n } else if (!isRelatedTargetDescendantOfNavigation) {\n this.setFocusedSlide(null);\n }\n }\n /**\n * Set reference to navigation element in template\n *\n * @param {HTMLElement} navigationElement\n */\n ;\n\n _proto.afterNavigationRender = function afterNavigationRender(navigationElement) {\n this.navigationElement = navigationElement;\n }\n /**\n * Navigate to a slide\n *\n * @param {number} slideIndex\n * @param {boolean} dontAnimate\n * @param {boolean} force\n */\n ;\n\n _proto.navigateToSlide = function navigateToSlide(slideIndex, dontAnimate, force) {\n if (dontAnimate === void 0) {\n dontAnimate = false;\n }\n\n if (force === void 0) {\n force = false;\n }\n\n if ((0, _jquery)(this.element).hasClass(\"slick-initialized\")) {\n (0, _jquery)(this.element).slick(\"slickGoTo\", slideIndex, dontAnimate);\n this.setActiveSlide(slideIndex);\n this.setFocusedSlide(slideIndex, force);\n }\n }\n /**\n * After child render record element\n *\n * @param {HTMLElement} element\n */\n ;\n\n _proto.afterChildrenRender = function afterChildrenRender(element) {\n this.element = element; // if slider has been re-rendered previously on this element, re-build\n\n if (this.ready) {\n this.buildSlick();\n }\n\n _previewCollection2.prototype.afterChildrenRender.call(this, element);\n\n this.afterChildrenRenderDeferred.resolve(element);\n }\n /**\n * On sort start force the container height, also focus to that slide\n *\n * @param {Event} event\n * @param {JQueryUI.SortableUIParams} params\n */\n ;\n\n _proto.onSortStart = function onSortStart(event, params) {\n this.forceContainerHeight();\n\n if (this.activeSlide() !== params.item.index() || this.focusedSlide() !== params.item.index()) {\n this.navigateToSlide(params.item.index(), false, true); // As we've completed a navigation request we need to ensure we don't remove the forced height\n\n this.contentTypeHeightReset = true;\n }\n }\n /**\n * On sort stop ensure the focused slide and the active slide are in sync, as the focus can be lost in this\n * operation\n */\n ;\n\n _proto.onSortStop = function onSortStop(event, params) {\n var _this2 = this;\n\n if (this.activeSlide() !== this.focusedSlide()) {\n this.setFocusedSlide(this.activeSlide(), true);\n }\n\n if (params.item.index() !== -1) {\n _underscore.defer(this.focusElement.bind(this, event, params.item.index()));\n }\n\n _underscore.defer(function () {\n (0, _jquery)(_this2.element).css({\n height: \"\",\n overflow: \"\"\n });\n });\n }\n /**\n * Add a slide into the slider\n */\n ;\n\n _proto.addSlide = function addSlide() {\n var _this3 = this;\n\n (0, _contentTypeFactory)(_config.getConfig(\"content_types\").slide, this.contentType, this.contentType.stageId).then(function (slide) {\n _events.on(\"slide:mountAfter\", function (args) {\n if (args.id === slide.id) {\n _underscore.defer(function () {\n // Wait until slick is initialized before trying to navigate\n (0, _delayUntil)(function () {\n return _this3.navigateToSlide(_this3.contentType.children().length - 1);\n }, function () {\n return (0, _jquery)(_this3.element).hasClass(\"slick-initialized\");\n }, 10);\n });\n\n _events.off(\"slide:\" + slide.id + \":mountAfter\");\n }\n }, \"slide:\" + slide.id + \":mountAfter\");\n\n _this3.contentType.addChild(slide, _this3.contentType.children().length);\n });\n }\n /**\n * Slider can not receive drops by default\n *\n * @returns {boolean}\n */\n ;\n\n _proto.isContainer = function isContainer() {\n return false;\n }\n /**\n * Slider navigation click handler.\n *\n * @param {number} index\n * @param {Preview} context\n * @param {Event} event\n */\n ;\n\n _proto.onControlClick = function onControlClick(index, context, event) {\n (0, _jquery)(event.target).focus();\n this.navigateToSlide(index);\n this.setFocusedSlide(index);\n }\n /**\n * @inheritdoc\n */\n ;\n\n _proto.destroy = function destroy() {\n _previewCollection2.prototype.destroy.call(this);\n\n if (this.focusedSlideSubscriber) {\n this.focusedSlideSubscriber.dispose();\n }\n }\n /**\n * Bind events\n */\n ;\n\n _proto.bindEvents = function bindEvents() {\n var _this4 = this;\n\n _previewCollection2.prototype.bindEvents.call(this);\n\n _events.on(\"slider:mountAfter\", function (args) {\n if (args.id === _this4.contentType.id) {\n if (args.expectChildren !== undefined) {\n _this4.mountAfterDeferred.resolve(args.expectChildren);\n }\n }\n }); // Set the active slide to the new position of the sorted slide\n\n\n _events.on(\"childContentType:sortUpdate\", function (args) {\n if (args.instance.id === _this4.contentType.id) {\n (0, _jquery)(args.ui.item).remove(); // Remove the item as the container's children is controlled by knockout\n\n _this4.setActiveSlide(args.newPosition);\n\n _underscore.defer(_this4.focusElement.bind(_this4, args.event, args.newPosition));\n }\n }); // When a slide content type is removed\n // we need to force update the content of the slider due to KO rendering issues\n\n\n var newItemIndex;\n\n _events.on(\"slide:removeAfter\", function (args) {\n if (args.parentContentType && args.parentContentType.id === _this4.contentType.id) {\n // Mark the previous slide as active\n newItemIndex = args.index - 1 >= 0 ? args.index - 1 : 0;\n\n _this4.forceContainerHeight();\n\n var data = _this4.contentType.children().slice(0);\n\n _this4.contentType.children([]);\n\n _this4.contentType.children(data);\n\n _underscore.defer(function () {\n _this4.buildSlick();\n });\n }\n });\n\n _events.on(\"slide:renderAfter\", function (args) {\n var itemIndex = args.contentType.parentContentType.getChildren()().indexOf(args.contentType);\n\n if (args.contentType.parentContentType.id === _this4.contentType.id && newItemIndex !== null && newItemIndex === itemIndex) {\n _underscore.defer(function () {\n if (newItemIndex !== null) {\n newItemIndex = null;\n\n _this4.navigateToSlide(itemIndex, true, true);\n\n _underscore.defer(function () {\n _this4.focusedSlide(null);\n\n _this4.focusedSlide(itemIndex);\n });\n }\n });\n }\n }); // On a slide content types creation we need to lock the height of the slider to ensure a smooth transition\n\n\n _events.on(\"slide:createAfter\", function (args) {\n if (_this4.element && _this4.ready && args.contentType.parentContentType.id === _this4.contentType.id) {\n _this4.forceContainerHeight();\n\n _underscore.defer(function () {\n (0, _jquery)(_this4.element).css({\n height: \"\",\n overflow: \"\"\n });\n });\n }\n }); // ContentType being mounted onto container\n\n\n _events.on(\"slider:dropAfter\", function (args) {\n if (args.id === _this4.contentType.id && _this4.contentType.children().length === 0) {\n _this4.addSlide();\n }\n }); // Capture when a content type is duplicated within the container\n\n\n var duplicatedSlide;\n var duplicatedSlideIndex;\n\n _events.on(\"slide:duplicateAfter\", function (args) {\n if (args.duplicateContentType.parentContentType.id === _this4.contentType.id && args.direct) {\n duplicatedSlide = args.duplicateContentType;\n duplicatedSlideIndex = args.index;\n }\n });\n\n _events.on(\"slide:mountAfter\", function (args) {\n if (duplicatedSlide && args.id === duplicatedSlide.id) {\n _underscore.defer(function () {\n // Mark the new duplicate slide as active\n _this4.navigateToSlide(duplicatedSlideIndex, true, true);\n\n duplicatedSlide = duplicatedSlideIndex = null;\n });\n }\n });\n }\n /**\n * Determine if the data has changed, whilst ignoring certain keys which don't require a rebuild\n *\n * @param {DataObject} previousData\n * @param {DataObject} newData\n * @returns {boolean}\n */\n ;\n\n _proto.hasDataChanged = function hasDataChanged(previousData, newData) {\n previousData = _underscore.omit(previousData, this.ignoredKeysForBuild);\n newData = _underscore.omit(newData, this.ignoredKeysForBuild);\n return !_underscore.isEqual(previousData, newData);\n }\n /**\n * Build our instance of slick\n */\n ;\n\n _proto.buildSlick = function buildSlick() {\n var _this5 = this;\n\n if (this.element && this.element.children.length > 0) {\n try {\n (0, _jquery)(this.element).slick(\"unslick\");\n } catch (e) {// We aren't concerned if this fails, slick throws an Exception when we cannot unslick\n } // Dispose current subscription in order to prevent infinite loop\n\n\n if (this.childSubscribe) {\n this.childSubscribe.dispose();\n } // Force an update on all children, ko tries to intelligently re-render but fails\n\n\n var data = this.contentType.children().slice(0);\n this.contentType.children([]);\n (0, _jquery)(this.element).empty();\n this.contentType.children(data); // Re-subscribe original event\n\n this.childSubscribe = this.contentType.children.subscribe(this.buildSlickDebounce); // Bind our init event for slick\n\n (0, _jquery)(this.element).on(\"init\", function () {\n _this5.ready = true;\n }); // Build slick\n\n (0, _jquery)(this.element).slick(Object.assign({\n initialSlide: this.activeSlide() || 0\n }, this.buildSlickConfig())); // Update our KO pointer to the active slide on change\n\n (0, _jquery)(this.element).on(\"beforeChange\", function (event, slick, currentSlide, nextSlide) {\n (0, _jquery)(_this5.element).css(\"pointer-events\", \"none\");\n\n _this5.setActiveSlide(nextSlide);\n }).on(\"afterChange\", function () {\n if (!_this5.contentTypeHeightReset) {\n (0, _jquery)(_this5.element).css({\n height: \"\",\n overflow: \"\"\n });\n _this5.contentTypeHeightReset = null;\n }\n\n (0, _jquery)(_this5.element).css(\"pointer-events\", \"\");\n });\n }\n }\n /**\n * Take dropped element on focus.\n *\n * @param {JQueryEventObject} event\n * @param {number} index\n */\n ;\n\n _proto.focusElement = function focusElement(event, index) {\n var handleClassName = (0, _jquery)(event.target).data(\"ui-sortable\").options.handle;\n (0, _jquery)((0, _jquery)(event.target).find(handleClassName)[index]).focus();\n }\n /**\n * To ensure smooth animations we need to lock the container height\n */\n ;\n\n _proto.forceContainerHeight = function forceContainerHeight() {\n (0, _jquery)(this.element).css({\n height: (0, _jquery)(this.element).outerHeight(),\n overflow: \"hidden\"\n });\n }\n /**\n * Build the slick config object\n *\n * @returns {{autoplay: boolean; autoplaySpeed: (any | number);\n * fade: boolean; infinite: boolean; arrows: boolean; dots: boolean}}\n */\n ;\n\n _proto.buildSlickConfig = function buildSlickConfig() {\n var data = this.contentType.dataStore.getState();\n return {\n arrows: data.show_arrows === \"true\",\n autoplay: data.autoplay === \"true\",\n autoplaySpeed: data.autoplay_speed,\n dots: false,\n // We have our own dots implemented\n fade: data.fade === \"true\",\n infinite: data.is_infinite === \"true\",\n waitForAnimate: false,\n swipe: false\n };\n }\n /**\n * Fit slider in column container\n *\n * @param params\n */\n ;\n\n _proto.onColumnResize = function onColumnResize(params) {\n var _this6 = this;\n\n setTimeout(function () {\n if (_this6.element) {\n (0, _jquery)(_this6.element).slick(\"setPosition\");\n\n _this6.checkWidth();\n }\n }, 450);\n }\n /**\n * Check width and add class that marks element as small\n */\n ;\n\n _proto.checkWidth = function checkWidth() {\n if (this.element.offsetWidth < 410) {\n this.element.classList.add(\"slider-small-width\");\n } else {\n this.element.classList.remove(\"slider-small-width\");\n }\n };\n\n return Preview;\n }(_previewCollection);\n\n return Preview;\n});\n//# sourceMappingURL=preview.js.map","Magento_PageBuilder/js/content-type/slider/appearance/default/widget.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'jquery',\n 'Magento_PageBuilder/js/events',\n 'slick'\n], function ($, events) {\n 'use strict';\n\n return function (config, sliderElement) {\n var $element = $(sliderElement);\n\n /**\n * Prevent each slick slider from being initialized more than once which could throw an error.\n */\n if ($element.hasClass('slick-initialized')) {\n $element.slick('unslick');\n }\n\n $element.slick({\n autoplay: $element.data('autoplay'),\n autoplaySpeed: $element.data('autoplay-speed') || 0,\n fade: $element.data('fade'),\n infinite: $element.data('infinite-loop'),\n arrows: $element.data('show-arrows'),\n dots: $element.data('show-dots')\n });\n\n // Redraw slide after content type gets redrawn\n events.on('contentType:redrawAfter', function (args) {\n if ($element.closest(args.element).length) {\n $element.slick('setPosition');\n }\n });\n // eslint-disable-next-line jquery-no-bind-unbind\n events.on('stage:viewportChangeAfter', $element.slick.bind($element, 'setPosition'));\n };\n});\n","Magento_PageBuilder/js/content-type/map/preview.js":"/*eslint-disable */\n/* jscs:disable */\n\nfunction _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); }\n\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n\ndefine([\"knockout\", \"Magento_PageBuilder/js/events\", \"Magento_PageBuilder/js/utils/map\", \"module\", \"Magento_PageBuilder/js/content-type-menu/hide-show-option\", \"Magento_PageBuilder/js/content-type/preview\"], function (_knockout, _events, _map, _module, _hideShowOption, _preview) {\n /**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n /**\n * @api\n */\n var Preview = /*#__PURE__*/function (_preview2) {\n \"use strict\";\n\n _inheritsLoose(Preview, _preview2);\n\n function Preview() {\n var _this;\n\n for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n args[_key] = arguments[_key];\n }\n\n _this = _preview2.call.apply(_preview2, [this].concat(args)) || this;\n _this.apiKeyValid = _knockout.observable(!!_module.config().apiKey);\n _this.apiKeyErrorMessage = _module.config().apiKeyErrorMessage;\n return _this;\n }\n\n var _proto = Preview.prototype;\n\n /**\n * Return an array of options\n *\n * @returns {OptionsInterface}\n */\n _proto.retrieveOptions = function retrieveOptions() {\n var options = _preview2.prototype.retrieveOptions.call(this);\n\n options.hideShow = new _hideShowOption({\n preview: this,\n icon: _hideShowOption.showIcon,\n title: _hideShowOption.showText,\n action: this.onOptionVisibilityToggle,\n classes: [\"hide-show-content-type\"],\n sort: 40\n });\n return options;\n }\n /**\n * Open edit menu on map content type drop with a delay of 300ms\n */\n ;\n\n _proto.bindEvents = function bindEvents() {\n var _this2 = this;\n\n _preview2.prototype.bindEvents.call(this); // When the map api key fails, empties out the content type and adds the placeholder\n\n\n _events.on(\"googleMaps:authFailure\", function () {\n _this2.apiKeyValid(false);\n });\n }\n /**\n * Renders the map and subscribe to position for updates\n *\n * @param {Element} element\n * @returns {void}\n */\n ;\n\n _proto.renderMap = function renderMap(element) {\n var _this3 = this;\n\n if (!this.apiKeyValid()) {\n return;\n }\n\n this.generateMap(element);\n this.element = element;\n\n if (this.mapElement && this.mapElement.map) {\n this.data.main.attributes.subscribe(function () {\n _this3.updateMap();\n });\n }\n }\n /**\n * Generate maps\n *\n * @param {Element} element\n * @returns {void}\n */\n ;\n\n _proto.generateMap = function generateMap(element) {\n var currentLocations = this.data.main.attributes()[\"data-locations\"] || \"[]\";\n var controls = this.data.main.attributes()[\"data-show-controls\"] || \"true\";\n var locations = [];\n var options = {\n disableDefaultUI: controls !== \"true\",\n mapTypeControl: controls === \"true\"\n };\n\n if (currentLocations !== \"[]\") {\n var mapData = this.getMapData();\n locations = mapData.locations;\n options = mapData.options;\n }\n\n this.mapElement = new _map(element, locations, options);\n }\n /**\n * Updates map\n *\n * @returns {void}\n */\n ;\n\n _proto.updateMap = function updateMap() {\n var mapData = this.getMapData();\n this.mapElement.onUpdate(mapData.locations, mapData.options);\n }\n /**\n * Get locations, center coordinates, and zoom from data.position\n *\n * @returns {Object}\n */\n ;\n\n _proto.getMapData = function getMapData() {\n var attributes = this.data.main.attributes();\n var controls = attributes[\"data-show-controls\"];\n var options = {\n disableDefaultUI: controls !== \"true\",\n mapTypeControl: controls === \"true\"\n };\n var locations = attributes[\"data-locations\"];\n\n if (locations !== \"\" && typeof locations === \"string\") {\n locations = JSON.parse(locations);\n }\n\n locations.forEach(function (location) {\n location.position.latitude = parseFloat(location.position.latitude);\n location.position.longitude = parseFloat(location.position.longitude);\n });\n return {\n locations: locations,\n options: options\n };\n };\n\n return Preview;\n }(_preview);\n\n return Preview;\n});\n//# sourceMappingURL=preview.js.map","Magento_PageBuilder/js/content-type/map/appearance/default/widget.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n 'jquery',\n 'Magento_PageBuilder/js/utils/map'\n], function ($, GoogleMap) {\n 'use strict';\n\n return function (config, element) {\n var locations,\n controls,\n mapOptions = {};\n\n element = element[0];\n\n if (element !== undefined && element.hasAttribute('data-locations')) {\n\n /**\n * Set map display to none if no locations\n */\n if (element.getAttribute('data-locations') === '[]') {\n $(element).hide();\n\n return;\n }\n locations = JSON.parse(element.getAttribute('data-locations'));\n locations.forEach(function (location) {\n location.position.latitude = parseFloat(location.position.latitude);\n location.position.longitude = parseFloat(location.position.longitude);\n });\n controls = element.getAttribute('data-show-controls');\n mapOptions.disableDefaultUI = controls !== 'true';\n mapOptions.mapTypeControl = controls === 'true';\n new GoogleMap(element, locations, mapOptions);\n }\n };\n});\n","Magento_PageBuilder/js/content-type/map/converter/attribute/locations.js":"/*eslint-disable */\n/* jscs:disable */\ndefine([\"underscore\", \"Magento_PageBuilder/js/utils/object\"], function (_underscore, _object) {\n /**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n var Locations = /*#__PURE__*/function () {\n \"use strict\";\n\n function Locations() {}\n\n var _proto = Locations.prototype;\n\n /**\n * Convert value to internal format\n *\n * @param value string\n * @returns {string | object}\n */\n _proto.fromDom = function fromDom(value) {\n if (value && value !== \"\") {\n return JSON.parse(value);\n }\n\n return [];\n }\n /**\n * Convert value to knockout format\n *\n * @param name string\n * @param data Object\n * @returns {string | object}\n */\n ;\n\n _proto.toDom = function toDom(name, data) {\n var content = (0, _object.get)(data, name);\n\n if (_underscore.isString(content) && content !== \"\") {\n content = JSON.parse(content);\n }\n\n if (content && Object.keys(content).length) {\n content.forEach(function (marker) {\n if (marker.position) {\n marker.position.latitude = parseFloat(marker.position.latitude);\n marker.position.longitude = parseFloat(marker.position.longitude);\n }\n });\n return JSON.stringify(content);\n }\n\n return JSON.stringify([]);\n };\n\n return Locations;\n }();\n\n return Locations;\n});\n//# sourceMappingURL=locations.js.map","Magento_PageBuilder/js/content-type/products/preview.js":"/*eslint-disable */\n/* jscs:disable */\n\nfunction _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); }\n\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n\ndefine([\"jquery\", \"knockout\", \"mage/translate\", \"Magento_PageBuilder/js/events\", \"slick\", \"underscore\", \"Magento_PageBuilder/js/config\", \"Magento_PageBuilder/js/content-type-menu/hide-show-option\", \"Magento_PageBuilder/js/content-type/preview\"], function (_jquery, _knockout, _translate, _events, _slick, _underscore, _config, _hideShowOption, _preview) {\n /**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n /**\n * @api\n */\n var Preview = /*#__PURE__*/function (_preview2) {\n \"use strict\";\n\n _inheritsLoose(Preview, _preview2);\n\n /**\n * Define keys which when changed should not trigger the slider to be rebuilt\n *\n * @type {string[]}\n */\n\n /**\n * @inheritdoc\n */\n function Preview(contentType, config, observableUpdater) {\n var _this;\n\n _this = _preview2.call(this, contentType, config, observableUpdater) || this;\n _this.displayPreview = _knockout.observable(false);\n _this.previewElement = _jquery.Deferred();\n _this.widgetUnsanitizedHtml = _knockout.observable();\n _this.slidesToShow = 5;\n _this.productItemSelector = \".product-item\";\n _this.centerModeClass = \"center-mode\";\n _this.messages = {\n EMPTY: (0, _translate)(\"Empty Products\"),\n NO_RESULTS: (0, _translate)(\"No products were found matching your condition\"),\n LOADING: (0, _translate)(\"Loading...\"),\n UNKNOWN_ERROR: (0, _translate)(\"An unknown error occurred. Please try again.\")\n };\n _this.ignoredKeysForBuild = [\"margins_and_padding\", \"border\", \"border_color\", \"border_radius\", \"border_width\", \"css_classes\", \"text_align\"];\n _this.placeholderText = _knockout.observable(_this.messages.EMPTY); // Redraw slider after content type gets redrawn\n\n _events.on(\"contentType:redrawAfter\", function (args) {\n if (_this.element && _this.element.children) {\n var $element = (0, _jquery)(_this.element.children);\n\n if (args.element && $element.closest(args.element).length) {\n $element.slick(\"setPosition\");\n }\n }\n });\n\n _events.on(\"stage:\" + _this.contentType.stageId + \":viewportChangeAfter\", function (args) {\n var viewports = _config.getConfig(\"viewports\");\n\n if (_this.element && _this.appearance() === \"carousel\") {\n _this.slidesToShow = parseFloat(viewports[args.viewport].options.products.default.slidesToShow);\n\n _this.destroySlider();\n\n _this.initSlider();\n }\n });\n\n return _this;\n }\n /**\n * Return an array of options\n *\n * @returns {OptionsInterface}\n */\n\n\n var _proto = Preview.prototype;\n\n _proto.retrieveOptions = function retrieveOptions() {\n var options = _preview2.prototype.retrieveOptions.call(this);\n\n options.hideShow = new _hideShowOption({\n preview: this,\n icon: _hideShowOption.showIcon,\n title: _hideShowOption.showText,\n action: this.onOptionVisibilityToggle,\n classes: [\"hide-show-content-type\"],\n sort: 40\n });\n return options;\n }\n /**\n * On afterRender callback.\n *\n * @param {Element} element\n */\n ;\n\n _proto.onAfterRender = function onAfterRender(element) {\n this.element = element;\n this.previewElement.resolve(element);\n this.initSlider();\n }\n /**\n * @inheritdoc\n */\n ;\n\n _proto.afterObservablesUpdated = function afterObservablesUpdated() {\n var _this2 = this;\n\n _preview2.prototype.afterObservablesUpdated.call(this);\n\n var data = this.contentType.dataStore.getState();\n\n if (this.hasDataChanged(this.previousData, data)) {\n this.displayPreview(false);\n\n if (typeof data.conditions_encoded !== \"string\" || data.conditions_encoded.length === 0) {\n this.placeholderText(this.messages.EMPTY);\n return;\n }\n\n var url = _config.getConfig(\"preview_url\");\n\n var requestConfig = {\n // Prevent caching\n method: \"POST\",\n data: {\n role: this.config.name,\n directive: this.data.main.html()\n }\n };\n this.placeholderText(this.messages.LOADING);\n\n _jquery.ajax(url, requestConfig).done(function (response) {\n if (typeof response.data !== \"object\" || !Boolean(response.data.content)) {\n _this2.placeholderText(_this2.messages.NO_RESULTS);\n\n return;\n }\n\n if (response.data.error) {\n _this2.widgetUnsanitizedHtml(response.data.error);\n } else {\n _this2.widgetUnsanitizedHtml(response.data.content);\n\n _this2.displayPreview(true);\n }\n\n _this2.previewElement.done(function () {\n (0, _jquery)(_this2.element).trigger(\"contentUpdated\");\n });\n }).fail(function () {\n _this2.placeholderText(_this2.messages.UNKNOWN_ERROR);\n });\n }\n\n this.previousData = Object.assign({}, data);\n };\n\n _proto.initSlider = function initSlider() {\n if (this.element && this.appearance() === \"carousel\") {\n (0, _jquery)(this.element.children).slick(this.buildSlickConfig());\n }\n };\n\n _proto.destroySlider = function destroySlider() {\n (0, _jquery)(this.element.children).slick(\"unslick\");\n }\n /**\n * Build the slick config object\n *\n * @returns {{autoplay: boolean; autoplay: number; infinite: boolean; arrows: boolean; dots: boolean;\n * centerMode: boolean; slidesToScroll: number; slidesToShow: number;}}\n */\n ;\n\n _proto.buildSlickConfig = function buildSlickConfig() {\n var attributes = this.data.main.attributes();\n var productCount = (0, _jquery)(this.widgetUnsanitizedHtml()).find(this.productItemSelector).length;\n\n var viewports = _config.getConfig(\"viewports\");\n\n var currentViewport = this.viewport();\n var carouselMode = attributes[\"data-carousel-mode\"];\n var config = {\n slidesToShow: this.slidesToShow,\n slidesToScroll: this.slidesToShow,\n dots: attributes[\"data-show-dots\"] === \"true\",\n arrows: attributes[\"data-show-arrows\"] === \"true\",\n autoplay: attributes[\"data-autoplay\"] === \"true\",\n autoplaySpeed: parseFloat(attributes[\"data-autoplay-speed\"])\n };\n var slidesToShow = viewports[currentViewport].options.products[carouselMode] ? viewports[currentViewport].options.products[carouselMode].slidesToShow : viewports[currentViewport].options.products.default.slidesToShow;\n config.slidesToShow = parseFloat(slidesToShow);\n\n if (attributes[\"data-carousel-mode\"] === \"continuous\" && productCount > config.slidesToShow) {\n config.centerPadding = attributes[\"data-center-padding\"];\n config.centerMode = true;\n (0, _jquery)(this.element).addClass(this.centerModeClass);\n } else {\n config.infinite = attributes[\"data-infinite-loop\"] === \"true\";\n (0, _jquery)(this.element).removeClass(this.centerModeClass);\n }\n\n return config;\n }\n /**\n * Determine if the data has changed, whilst ignoring certain keys which don't require a rebuild\n *\n * @param {DataObject} previousData\n * @param {DataObject} newData\n * @returns {boolean}\n */\n ;\n\n _proto.hasDataChanged = function hasDataChanged(previousData, newData) {\n previousData = _underscore.omit(previousData, this.ignoredKeysForBuild);\n newData = _underscore.omit(newData, this.ignoredKeysForBuild);\n return !_underscore.isEqual(previousData, newData);\n };\n\n return Preview;\n }(_preview);\n\n return Preview;\n});\n//# sourceMappingURL=preview.js.map","Magento_PageBuilder/js/content-type/products/appearance/carousel/widget.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'jquery',\n 'underscore',\n 'matchMedia',\n 'Magento_PageBuilder/js/utils/breakpoints',\n 'Magento_PageBuilder/js/events',\n 'slick'\n], function ($, _, mediaCheck, breakpointsUtils, events) {\n 'use strict';\n\n /**\n * Build slick\n *\n * @param {jQuery} $carouselElement\n * @param {Object} config\n */\n function buildSlick($carouselElement, config) {\n /**\n * Prevent each slick slider from being initialized more than once which could throw an error.\n */\n if ($carouselElement.hasClass('slick-initialized')) {\n $carouselElement.slick('unslick');\n }\n\n config.slidesToScroll = config.slidesToShow;\n $carouselElement.slick(config);\n }\n\n /**\n * Initialize slider.\n *\n * @param {jQuery} $element\n * @param {Object} slickConfig\n * @param {Object} breakpoint\n */\n function initSlider($element, slickConfig, breakpoint) {\n var productCount = $element.find('.product-item').length,\n $carouselElement = $($element.children()),\n centerModeClass = 'center-mode',\n carouselMode = $element.data('carousel-mode'),\n slidesToShow = breakpoint.options.products[carouselMode] ?\n breakpoint.options.products[carouselMode].slidesToShow :\n breakpoint.options.products.default.slidesToShow;\n\n slickConfig.slidesToShow = parseFloat(slidesToShow);\n\n if (carouselMode === 'continuous' && productCount > slickConfig.slidesToShow) {\n $element.addClass(centerModeClass);\n slickConfig.centerPadding = $element.data('center-padding');\n slickConfig.centerMode = true;\n } else {\n $element.removeClass(centerModeClass);\n slickConfig.infinite = $element.data('infinite-loop');\n }\n\n buildSlick($carouselElement, slickConfig);\n }\n\n return function (config, element) {\n var $element = $(element),\n $carouselElement = $($element.children()),\n currentViewport = config.currentViewport,\n currentBreakpoint = config.breakpoints[currentViewport],\n slickConfig = {\n autoplay: $element.data('autoplay'),\n autoplaySpeed: $element.data('autoplay-speed') || 0,\n arrows: $element.data('show-arrows'),\n dots: $element.data('show-dots')\n };\n\n _.each(config.breakpoints, function (breakpoint) {\n mediaCheck({\n media: breakpointsUtils.buildMedia(breakpoint.conditions),\n\n /** @inheritdoc */\n entry: function () {\n initSlider($element, slickConfig, breakpoint);\n }\n });\n });\n\n //initialize slider when content type is added in mobile viewport\n if (currentViewport === 'mobile') {\n initSlider($element, slickConfig, currentBreakpoint);\n }\n\n // Redraw slide after content type gets redrawn\n events.on('contentType:redrawAfter', function (args) {\n if ($carouselElement.closest(args.element).length) {\n $carouselElement.slick('setPosition');\n }\n });\n\n events.on('stage:viewportChangeAfter', function (args) {\n var breakpoint = config.breakpoints[args.viewport];\n\n initSlider($element, slickConfig, breakpoint);\n });\n };\n});\n","Magento_PageBuilder/js/content-type/products/mass-converter/carousel-widget-directive.js":"/*eslint-disable */\n/* jscs:disable */\n\nfunction _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); }\n\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n\ndefine([\"Magento_PageBuilder/js/mass-converter/widget-directive-abstract\", \"Magento_PageBuilder/js/utils/object\"], function (_widgetDirectiveAbstract, _object) {\n /**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n /**\n * @api\n */\n var WidgetDirective = /*#__PURE__*/function (_widgetDirectiveAbstr) {\n \"use strict\";\n\n _inheritsLoose(WidgetDirective, _widgetDirectiveAbstr);\n\n function WidgetDirective() {\n return _widgetDirectiveAbstr.apply(this, arguments) || this;\n }\n\n var _proto = WidgetDirective.prototype;\n\n /**\n * Convert value to internal format\n *\n * @param {object} data\n * @param {object} config\n * @returns {object}\n */\n _proto.fromDom = function fromDom(data, config) {\n var attributes = _widgetDirectiveAbstr.prototype.fromDom.call(this, data, config);\n\n data.carousel_products_count = attributes.products_count;\n data.sort_order = attributes.sort_order;\n data.condition_option = attributes.condition_option || \"condition\";\n data[data.condition_option] = this.decodeWysiwygCharacters(attributes.condition_option_value || \"\");\n data.conditions_encoded = this.decodeWysiwygCharacters(attributes.conditions_encoded || \"\");\n data[data.condition_option + \"_source\"] = data.conditions_encoded;\n return data;\n }\n /**\n * Convert value to knockout format\n *\n * @param {object} data\n * @param {object} config\n * @returns {object}\n */\n ;\n\n _proto.toDom = function toDom(data, config) {\n var attributes = {\n type: \"Magento\\\\CatalogWidget\\\\Block\\\\Product\\\\ProductsList\",\n template: \"Magento_PageBuilder::catalog/product/widget/content/carousel.phtml\",\n anchor_text: \"\",\n id_path: \"\",\n show_pager: 0,\n products_count: data.carousel_products_count,\n condition_option: data.condition_option,\n condition_option_value: \"\",\n type_name: \"Catalog Products Carousel\",\n conditions_encoded: this.encodeWysiwygCharacters(data.conditions_encoded || \"\")\n };\n\n if (data.sort_order) {\n attributes.sort_order = data.sort_order;\n }\n\n if (typeof data[data.condition_option] === \"string\") {\n attributes.condition_option_value = this.encodeWysiwygCharacters(data[data.condition_option]);\n }\n\n if (attributes.conditions_encoded.length === 0) {\n return data;\n }\n\n (0, _object.set)(data, config.html_variable, this.buildDirective(attributes));\n return data;\n }\n /**\n * @param {string} content\n * @returns {string}\n */\n ;\n\n _proto.encodeWysiwygCharacters = function encodeWysiwygCharacters(content) {\n return content.replace(/\\{/g, \"^[\").replace(/\\}/g, \"^]\").replace(/\"/g, \"`\").replace(/\\\\/g, \"|\").replace(/</g, \"<\").replace(/>/g, \">\");\n }\n /**\n * @param {string} content\n * @returns {string}\n */\n ;\n\n _proto.decodeWysiwygCharacters = function decodeWysiwygCharacters(content) {\n return content.replace(/\\^\\[/g, \"{\").replace(/\\^\\]/g, \"}\").replace(/`/g, \"\\\"\").replace(/\\|/g, \"\\\\\").replace(/</g, \"<\").replace(/>/g, \">\");\n };\n\n return WidgetDirective;\n }(_widgetDirectiveAbstract);\n\n return WidgetDirective;\n});\n//# sourceMappingURL=carousel-widget-directive.js.map","Magento_PageBuilder/js/content-type/products/mass-converter/widget-directive.js":"/*eslint-disable */\n/* jscs:disable */\n\nfunction _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); }\n\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n\ndefine([\"Magento_PageBuilder/js/mass-converter/widget-directive-abstract\", \"Magento_PageBuilder/js/utils/object\"], function (_widgetDirectiveAbstract, _object) {\n /**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n /**\n * @api\n */\n var WidgetDirective = /*#__PURE__*/function (_widgetDirectiveAbstr) {\n \"use strict\";\n\n _inheritsLoose(WidgetDirective, _widgetDirectiveAbstr);\n\n function WidgetDirective() {\n return _widgetDirectiveAbstr.apply(this, arguments) || this;\n }\n\n var _proto = WidgetDirective.prototype;\n\n /**\n * Convert value to internal format\n *\n * @param {object} data\n * @param {object} config\n * @returns {object}\n */\n _proto.fromDom = function fromDom(data, config) {\n var attributes = _widgetDirectiveAbstr.prototype.fromDom.call(this, data, config);\n\n data.products_count = attributes.products_count;\n data.sort_order = attributes.sort_order;\n data.condition_option = attributes.condition_option || \"condition\";\n data[data.condition_option] = this.decodeWysiwygCharacters(attributes.condition_option_value || \"\");\n data.conditions_encoded = this.decodeWysiwygCharacters(attributes.conditions_encoded || \"\");\n data[data.condition_option + \"_source\"] = data.conditions_encoded;\n return data;\n }\n /**\n * Convert value to knockout format\n *\n * @param {object} data\n * @param {object} config\n * @returns {object}\n */\n ;\n\n _proto.toDom = function toDom(data, config) {\n var attributes = {\n type: \"Magento\\\\CatalogWidget\\\\Block\\\\Product\\\\ProductsList\",\n template: \"Magento_CatalogWidget::product/widget/content/grid.phtml\",\n anchor_text: \"\",\n id_path: \"\",\n show_pager: 0,\n products_count: data.products_count,\n condition_option: data.condition_option,\n condition_option_value: \"\",\n type_name: \"Catalog Products List\",\n conditions_encoded: this.encodeWysiwygCharacters(data.conditions_encoded || \"\")\n };\n\n if (data.sort_order) {\n attributes.sort_order = data.sort_order;\n }\n\n if (typeof data[data.condition_option] === \"string\") {\n attributes.condition_option_value = this.encodeWysiwygCharacters(data[data.condition_option]);\n }\n\n if (attributes.conditions_encoded.length === 0) {\n return data;\n }\n\n (0, _object.set)(data, config.html_variable, this.buildDirective(attributes));\n return data;\n }\n /**\n * @param {string} content\n * @returns {string}\n */\n ;\n\n _proto.encodeWysiwygCharacters = function encodeWysiwygCharacters(content) {\n return content.replace(/\\{/g, \"^[\").replace(/\\}/g, \"^]\").replace(/\"/g, \"`\").replace(/\\\\/g, \"|\").replace(/</g, \"<\").replace(/>/g, \">\");\n }\n /**\n * @param {string} content\n * @returns {string}\n */\n ;\n\n _proto.decodeWysiwygCharacters = function decodeWysiwygCharacters(content) {\n return content.replace(/\\^\\[/g, \"{\").replace(/\\^\\]/g, \"}\").replace(/`/g, \"\\\"\").replace(/\\|/g, \"\\\\\").replace(/</g, \"<\").replace(/>/g, \">\");\n };\n\n return WidgetDirective;\n }(_widgetDirectiveAbstract);\n\n return WidgetDirective;\n});\n//# sourceMappingURL=widget-directive.js.map","Magento_PageBuilder/js/content-type/products/form/provider.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'Magento_PageBuilder/js/form/provider',\n 'Magento_PageBuilder/js/form/provider/conditions-data-processor'\n], function (Provider, conditionsDataProcessor) {\n 'use strict';\n\n return Provider.extend({\n /** @inheritdoc **/\n save: function () {\n var data = this.get('data');\n\n conditionsDataProcessor(data, data['condition_option'] + '_source');\n\n return this._super();\n }\n });\n});\n","Magento_PageBuilder/js/content-type/slide/preview.js":"/*eslint-disable */\n/* jscs:disable */\n\nfunction _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); }\n\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n\ndefine([\"jarallax\", \"jarallaxVideo\", \"jquery\", \"knockout\", \"mage/translate\", \"Magento_PageBuilder/js/events\", \"mageUtils\", \"underscore\", \"vimeoWrapper\", \"Magento_PageBuilder/js/content-type-menu/conditional-remove-option\", \"Magento_PageBuilder/js/uploader\", \"Magento_PageBuilder/js/utils/delay-until\", \"Magento_PageBuilder/js/utils/editor\", \"Magento_PageBuilder/js/utils/nesting-link-dialog\", \"Magento_PageBuilder/js/utils/nesting-widget-dialog\", \"Magento_PageBuilder/js/wysiwyg/factory\", \"Magento_PageBuilder/js/content-type/preview\"], function (_jarallax, _jarallaxVideo, _jquery, _knockout, _translate, _events, _mageUtils, _underscore, _vimeoWrapper, _conditionalRemoveOption, _uploader, _delayUntil, _editor, _nestingLinkDialog, _nestingWidgetDialog, _factory, _preview) {\n /**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n /**\n * @api\n */\n var Preview = /*#__PURE__*/function (_preview2) {\n \"use strict\";\n\n _inheritsLoose(Preview, _preview2);\n\n function Preview() {\n var _this;\n\n for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n args[_key] = arguments[_key];\n }\n\n _this = _preview2.call.apply(_preview2, [this].concat(args)) || this;\n _this.buttonPlaceholder = (0, _translate)(\"Edit Button Text\");\n _this.slideName = _knockout.observable();\n _this.wysiwygDeferred = _jquery.Deferred();\n _this.slideChanged = true;\n _this.handledDoubleClick = false;\n _this.videoUpdateProperties = [\"background_type\", \"video_fallback_image\", \"video_lazy_load\", \"video_loop\", \"video_play_only_visible\", \"video_source\"];\n _this.buildJarallax = _underscore.debounce(function () {\n // Destroy all instances of the plugin prior\n try {\n jarallax(_this.wrapper, \"destroy\");\n } catch (e) {// Failure of destroying is acceptable\n }\n\n if (_this.wrapper && _this.wrapper.dataset.backgroundType === \"video\" && _this.wrapper.dataset.videoSrc.length) {\n _underscore.defer(function () {\n // Build Parallax on elements with the correct class\n var viewportElement = (0, _jquery)(\"<div/>\").addClass(\"jarallax-viewport-element\");\n (0, _jquery)(_this.wrapper).append((0, _jquery)(\".jarallax-viewport-element\", _this.wrapper).length ? \"\" : viewportElement);\n jarallax(_this.wrapper, {\n videoSrc: _this.wrapper.dataset.videoSrc,\n imgSrc: _this.wrapper.dataset.videoFallbackSrc,\n videoLoop: _this.contentType.dataStore.get(\"video_loop\") === \"true\",\n speed: 1,\n videoPlayOnlyVisible: _this.contentType.dataStore.get(\"video_play_only_visible\") === \"true\",\n elementInViewport: (0, _jquery)(\".jarallax-viewport-element\", _this.wrapper),\n videoLazyLoading: _this.contentType.dataStore.get(\"video_lazy_load\") === \"true\"\n }); // @ts-ignore\n\n if (_this.wrapper.jarallax && _this.wrapper.jarallax.video) {\n // @ts-ignore\n _this.wrapper.jarallax.video.on(\"started\", function () {\n // @ts-ignore\n if (_this.wrapper.jarallax && _this.wrapper.jarallax.$video) {\n // @ts-ignore\n _this.wrapper.jarallax.$video.style.visibility = \"visible\";\n }\n });\n }\n });\n }\n }, 50);\n return _this;\n }\n\n var _proto = Preview.prototype;\n\n /**\n * Get background image url base on the viewport.\n *\n * @returns {string}\n */\n _proto.getBackgroundImage = function getBackgroundImage() {\n var mobileImage = this.contentType.dataStore.get(\"mobile_image\");\n var desktopImage = this.contentType.dataStore.get(\"background_image\");\n var backgroundImage = this.viewport() === \"mobile\" && mobileImage.length ? mobileImage : desktopImage;\n return backgroundImage.length ? \"url(\\\"\" + backgroundImage[0].url + \"\\\")\" : \"none\";\n }\n /**\n * @param {HTMLElement} element\n */\n ;\n\n _proto.afterRenderWysiwyg = function afterRenderWysiwyg(element) {\n var _this2 = this;\n\n this.element = element;\n element.id = this.contentType.id + \"-editor\"; // Set the innerHTML manually so we don't upset Knockout & TinyMCE\n\n element.innerHTML = this.data.content.html();\n this.contentType.dataStore.subscribe(function () {\n // If we're not focused into TinyMCE inline, update the value when it changes in the data store\n if (!_this2.wysiwyg || _this2.wysiwyg && _this2.wysiwyg.getAdapter().id !== (0, _editor.getActiveEditor)().id) {\n element.innerHTML = _this2.data.content.html();\n }\n }, \"content\");\n /**\n * afterRenderWysiwyg is called whenever Knockout causes a DOM re-render. This occurs frequently within Slider\n * due to Slick's inability to perform a refresh with Knockout managing the DOM. Due to this the original\n * WYSIWYG instance will be detached from this slide and we need to re-initialize on click.\n */\n\n this.wysiwyg = null;\n }\n /**\n * Set state based on overlay mouseover event for the preview\n */\n ;\n\n _proto.onMouseOverWrapper = function onMouseOverWrapper() {\n // Triggers the visibility of the overlay content to show\n if (this.data.main.attributes()[\"data-show-overlay\"] === \"hover\") {\n this.data.overlay.attributes(Object.assign(this.data.overlay.attributes(), {\n \"data-background-color-orig\": this.data.overlay.style().backgroundColor\n }));\n this.data.overlay.style(Object.assign(this.data.overlay.style(), {\n backgroundColor: this.data.overlay.attributes()[\"data-overlay-color\"]\n }));\n }\n\n if (this.data.main.attributes()[\"data-show-button\"] === \"hover\") {\n this.data.button.style(Object.assign(this.data.button.style(), {\n opacity: 1,\n visibility: \"visible\"\n }));\n }\n }\n /**\n * Set state based on overlay mouseout event for the preview\n */\n ;\n\n _proto.onMouseOutWrapper = function onMouseOutWrapper() {\n // Triggers the visibility of the overlay content to hide\n if (this.data.main.attributes()[\"data-show-overlay\"] === \"hover\") {\n this.data.overlay.style(Object.assign(this.data.overlay.style(), {\n backgroundColor: this.data.overlay.attributes()[\"data-background-color-orig\"]\n }));\n }\n\n if (this.data.main.attributes()[\"data-show-button\"] === \"hover\") {\n this.data.button.style(Object.assign(this.data.button.style(), {\n opacity: 0,\n visibility: \"hidden\"\n }));\n }\n }\n /**\n * Get the options instance\n *\n * @returns {OptionsInterface}\n */\n ;\n\n _proto.retrieveOptions = function retrieveOptions() {\n var options = _preview2.prototype.retrieveOptions.call(this);\n\n delete options.move;\n options.remove = new _conditionalRemoveOption(_extends({}, options.remove.config, {\n preview: this\n }));\n return options;\n }\n /**\n * Get registry callback reference to uploader UI component\n *\n * @returns {Uploader}\n */\n ;\n\n _proto.getUploader = function getUploader() {\n var initialImageValue = this.contentType.dataStore.get(this.config.additional_data.uploaderConfig.dataScope, \"\"); // Create uploader\n\n return new _uploader(\"imageuploader_\" + this.contentType.id, this.config.additional_data.uploaderConfig, this.contentType.id, this.contentType.dataStore, initialImageValue);\n }\n /**\n * Makes WYSIWYG active\n *\n * @param {Preview} preview\n * @param {JQueryEventObject} event\n * @returns {Boolean}\n */\n ;\n\n _proto.activateEditor = function activateEditor(preview, event) {\n var _this3 = this;\n\n if (this.element && !this.wysiwyg) {\n var bookmark = (0, _editor.createBookmark)(event);\n (0, _editor.lockImageSize)(this.element);\n this.element.removeAttribute(\"contenteditable\");\n\n _underscore.defer(function () {\n _this3.initWysiwygFromClick(true).then(function () {\n return (0, _delayUntil)(function () {\n // We no longer need to handle double click once it's initialized\n _this3.handledDoubleClick = true;\n\n _this3.wysiwygDeferred.resolve();\n\n (0, _editor.moveToBookmark)(bookmark);\n (0, _editor.unlockImageSize)(_this3.element);\n }, function () {\n return _this3.element.classList.contains(\"mce-edit-focus\");\n }, 10);\n }).catch(function (error) {\n // If there's an error with init of WYSIWYG editor push into the console to aid support\n console.error(error);\n });\n });\n } else if (this.element && this.wysiwyg) {\n var element = this.element || this.textarea;\n\n if (event.currentTarget !== event.target && event.target !== element && !element.contains(event.target)) {\n return;\n }\n\n element.focus();\n }\n }\n /**\n * If a user double clicks prior to initializing TinyMCE, forward the event\n *\n * @param preview\n * @param event\n */\n ;\n\n _proto.handleDoubleClick = function handleDoubleClick(preview, event) {\n var _this4 = this;\n\n if (this.handledDoubleClick) {\n return;\n }\n\n event.preventDefault();\n var targetIndex = (0, _editor.findNodeIndex)(this.element, event.target.tagName, event.target);\n this.handledDoubleClick = true;\n this.wysiwygDeferred.then(function () {\n var target = document.getElementById(event.target.id);\n\n if (!target) {\n target = (0, _editor.getNodeByIndex)(_this4.element, event.target.tagName, targetIndex);\n }\n\n if (target) {\n target.dispatchEvent((0, _editor.createDoubleClickEvent)());\n }\n });\n }\n /**\n * Stop event to prevent execution of action when editing textarea.\n *\n * @param {Preview} preview\n * @param {JQueryEventObject} event\n * @returns {Boolean}\n */\n ;\n\n _proto.stopEvent = function stopEvent(preview, event) {\n event.stopPropagation();\n return true;\n }\n /**\n * @returns {Boolean}\n */\n ;\n\n _proto.isWysiwygSupported = function isWysiwygSupported() {\n return (0, _editor.isWysiwygSupported)();\n }\n /**\n * @param {HTMLTextAreaElement} element\n */\n ;\n\n _proto.initTextarea = function initTextarea(element) {\n var _this5 = this;\n\n this.textarea = element; // set initial value of textarea based on data store\n\n this.textarea.value = this.contentType.dataStore.get(\"content\");\n this.adjustTextareaHeightBasedOnScrollHeight(); // Update content in our stage preview textarea after its slideout counterpart gets updated\n\n _events.on(\"form:\" + this.contentType.id + \":saveAfter\", function () {\n _this5.textarea.value = _this5.contentType.dataStore.get(\"content\");\n\n _this5.adjustTextareaHeightBasedOnScrollHeight();\n });\n }\n /**\n * Save current value of textarea in data store\n */\n ;\n\n _proto.onTextareaKeyUp = function onTextareaKeyUp() {\n this.adjustTextareaHeightBasedOnScrollHeight();\n this.contentType.dataStore.set(\"content\", this.textarea.value);\n }\n /**\n * Start stage interaction on textarea blur\n */\n ;\n\n _proto.onTextareaFocus = function onTextareaFocus() {\n (0, _jquery)(this.textarea).closest(\".pagebuilder-content-type\").addClass(\"pagebuilder-toolbar-active\");\n\n _events.trigger(\"stage:interactionStart\");\n }\n /**\n * Stop stage interaction on textarea blur\n */\n ;\n\n _proto.onTextareaBlur = function onTextareaBlur() {\n (0, _jquery)(this.textarea).closest(\".pagebuilder-content-type\").removeClass(\"pagebuilder-toolbar-active\");\n\n _events.trigger(\"stage:interactionStop\");\n }\n /**\n * Init WYSIWYG on load\n *\n * @param element\n * @deprecated please use activateEditor & initWysiwygFromClick\n */\n ;\n\n _proto.initWysiwyg = function initWysiwyg(element) {\n this.element = element;\n element.id = this.contentType.id + \"-editor\";\n this.wysiwyg = null;\n return this.initWysiwygFromClick(true);\n }\n /**\n * Init the WYSIWYG\n *\n * @param {boolean} focus Should wysiwyg focus after initialization?\n * @returns Promise\n */\n ;\n\n _proto.initWysiwygFromClick = function initWysiwygFromClick(focus) {\n var _this6 = this;\n\n if (focus === void 0) {\n focus = false;\n }\n\n if (this.wysiwyg) {\n return Promise.resolve(this.wysiwyg);\n }\n\n var wysiwygConfig = this.config.additional_data.wysiwygConfig.wysiwygConfigData;\n\n if (focus) {\n wysiwygConfig.adapter.settings.auto_focus = this.element.id;\n\n wysiwygConfig.adapter.settings.init_instance_callback = function (editor) {\n editor.on(\"blur\", function () {\n (0, _nestingLinkDialog)(_this6.contentType.dataStore, _this6.wysiwyg, \"content\", \"link_url\");\n (0, _nestingWidgetDialog)(_this6.contentType.dataStore, _this6.wysiwyg, \"content\", \"link_url\");\n });\n\n _underscore.defer(function () {\n _this6.element.blur();\n\n _this6.element.focus();\n });\n };\n }\n\n return (0, _factory)(this.contentType.id, this.element.id, this.config.name, wysiwygConfig, this.contentType.dataStore, \"content\", this.contentType.stageId).then(function (wysiwyg) {\n _this6.wysiwyg = wysiwyg;\n return wysiwyg;\n });\n }\n /**\n * Init the parallax element\n *\n * @param {HTMLElement} element\n */\n ;\n\n _proto.initParallax = function initParallax(element) {\n var _this7 = this;\n\n this.wrapper = element;\n\n _underscore.defer(function () {\n _this7.buildJarallax();\n });\n }\n /**\n * Destroy jarallax instance.\n */\n ;\n\n _proto.destroy = function destroy() {\n _preview2.prototype.destroy.call(this);\n\n if (this.wrapper) {\n jarallax(this.wrapper, \"destroy\");\n }\n }\n /**\n * @inheritDoc\n */\n ;\n\n _proto.bindEvents = function bindEvents() {\n var _this8 = this;\n\n _preview2.prototype.bindEvents.call(this);\n\n _events.on(\"slide:mountAfter\", function (args) {\n if (args.id === _this8.contentType.id) {\n _this8.buildJarallax();\n\n _this8.isSnapshot.subscribe(function (value) {\n _this8.changeUploaderControlsVisibility();\n });\n\n _this8.changeUploaderControlsVisibility();\n }\n });\n\n _events.on(this.config.name + \":\" + this.contentType.id + \":updateAfter\", function () {\n var dataStore = _this8.contentType.dataStore.getState();\n\n var imageObject = dataStore[_this8.config.additional_data.uploaderConfig.dataScope][0] || {};\n\n _events.trigger(\"image:\" + _this8.contentType.id + \":assignAfter\", imageObject);\n }); // Remove wysiwyg before assign new instance.\n\n\n _events.on(\"childContentType:sortUpdate\", function (args) {\n if (args.instance.id === _this8.contentType.parentContentType.id) {\n _this8.wysiwyg = null;\n }\n });\n\n _events.on(this.config.name + \":mountAfter\", function (args) {\n if (args.id === _this8.contentType.id) {\n // Update the display label for the slide\n var slider = _this8.contentType.parentContentType;\n\n _this8.displayLabel((0, _translate)(\"Slide \" + (slider.children().indexOf(_this8.contentType) + 1)));\n\n slider.children.subscribe(function (children) {\n var index = children.indexOf(_this8.contentType);\n\n _this8.displayLabel((0, _translate)(\"Slide \" + (slider.children().indexOf(_this8.contentType) + 1)));\n });\n }\n });\n\n _events.on(this.config.name + \":renderAfter\", function (args) {\n if (args.id === _this8.contentType.id) {\n var slider = _this8.contentType.parentContentType;\n (0, _jquery)(slider.preview.element).on(\"beforeChange\", function () {\n _this8.slideChanged = false;\n });\n (0, _jquery)(slider.preview.element).on(\"afterChange\", function (event, slick) {\n (0, _jquery)(slick.$slides).each(function (index, slide) {\n var videoSlide = slide.querySelector(\".jarallax\");\n\n if (videoSlide) {\n jarallax(videoSlide, \"onScroll\");\n }\n });\n _this8.slideChanged = true;\n });\n }\n });\n\n this.contentType.dataStore.subscribe(function (data) {\n _this8.slideName(data.slide_name);\n\n if (_this8.shouldUpdateVideo(data)) {\n _this8.buildJarallax();\n }\n });\n\n _events.on(\"image:\" + this.contentType.id + \":uploadAfter\", function () {\n _this8.contentType.dataStore.set(\"background_type\", \"image\");\n });\n\n _events.on(\"stage:\" + this.contentType.stageId + \":viewportChangeAfter\", function (args) {\n if (_this8.contentType.dataStore.get(\"background_type\") === \"video\") {\n _this8.buildJarallax();\n }\n });\n }\n /**\n * Change uploader controls visibility\n */\n ;\n\n _proto.changeUploaderControlsVisibility = function changeUploaderControlsVisibility() {\n var _this9 = this;\n\n this.getUploader().getUiComponent()(function (uploader) {\n uploader.visibleControls = !_this9.isSnapshot();\n });\n }\n /**\n * Update image data inside data store\n *\n * @param {Array} data - list of each files' data\n */\n ;\n\n _proto.onImageUploaded = function onImageUploaded(data) {\n this.contentType.dataStore.set(this.config.additional_data.uploaderConfig.dataScope, data);\n }\n /**\n * Adjust textarea's height based on scrollHeight\n */\n ;\n\n _proto.adjustTextareaHeightBasedOnScrollHeight = function adjustTextareaHeightBasedOnScrollHeight() {\n this.textarea.style.height = \"\";\n var scrollHeight = this.textarea.scrollHeight;\n var minHeight = parseInt((0, _jquery)(this.textarea).css(\"min-height\"), 10);\n\n if (scrollHeight === minHeight) {\n // leave height at 'auto'\n return;\n }\n\n (0, _jquery)(this.textarea).height(scrollHeight);\n }\n /**\n * Check if video options has been updated.\n *\n * @return boolean\n */\n ;\n\n _proto.shouldUpdateVideo = function shouldUpdateVideo(state) {\n var _this10 = this;\n\n var previousState = this.contentType.dataStore.getPreviousState();\n\n var diff = _mageUtils.compare(previousState, state).changes;\n\n if (diff.length > 0) {\n return _underscore.some(diff, function (element) {\n if (element.name === \"video_fallback_image\") {\n return (!_underscore.isEmpty(previousState.video_fallback_image) && previousState.video_fallback_image) !== (!_underscore.isEmpty(state.video_fallback_image) && state.video_fallback_image);\n }\n\n return _this10.videoUpdateProperties.indexOf(element.name) !== -1;\n });\n }\n };\n\n return Preview;\n }(_preview);\n\n return Preview;\n});\n//# sourceMappingURL=preview.js.map","Magento_PageBuilder/js/content-type/slide/appearance/default/widget.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n 'jquery',\n 'underscore',\n 'Magento_PageBuilder/js/widget/show-on-hover',\n 'Magento_PageBuilder/js/widget/video-background'\n], function ($, _, showOnHover, videoBackground) {\n 'use strict';\n\n return function (config, element) {\n var videoElement = element[0].querySelector('[data-background-type=video]'),\n viewportElement = document.createElement('div'),\n $slider = null;\n\n showOnHover(config);\n\n if (videoElement) {\n $slider = $(element).closest('[data-content-type=slider]');\n viewportElement.classList.add('jarallax-viewport-element');\n videoElement.setAttribute('data-element-in-viewport', '.jarallax-viewport-element');\n videoElement.appendChild(viewportElement);\n videoBackground(config, videoElement);\n\n if ($slider.data('afterChangeIsSet')) {\n return;\n }\n\n $slider.on('afterChange init', function () {\n var videoSlides = $slider[0].querySelectorAll('.jarallax');\n\n _.each(videoSlides, function (videoSlide) {\n videoSlide.jarallax && videoSlide.jarallax.onScroll();\n });\n });\n $slider.data('afterChangeIsSet', true);\n }\n };\n});\n","Magento_PageBuilder/js/content-type/slide/wysiwyg/tinymce/component-initializer.js":"/*eslint-disable */\n/* jscs:disable */\ndefine([\"jquery\", \"mage/adminhtml/wysiwyg/events\", \"Magento_PageBuilder/js/utils/delay-until\"], function (_jquery, _events, _delayUntil) {\n /**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n var ComponentInitializer = /*#__PURE__*/function () {\n \"use strict\";\n\n function ComponentInitializer() {\n this.sliderSelector = \".slick-list\";\n this.sliderContentSelector = \".slick-track\";\n this.slideSelector = \".slick-slide\";\n this.activeSlideSelector = \".slick-current\";\n this.slideChanging = false;\n }\n\n var _proto = ComponentInitializer.prototype;\n\n /**\n * Initialize the instance\n *\n * @param {Wysiwyg} wysiwyg\n */\n _proto.initialize = function initialize(wysiwyg) {\n var _this = this;\n\n this.$element = (0, _jquery)(\"#\" + wysiwyg.elementId);\n this.config = wysiwyg.config;\n var tinymce = wysiwyg.getAdapter();\n tinymce.eventBus.attachEventHandler(_events.afterFocus, this.onFocus.bind(this));\n tinymce.eventBus.attachEventHandler(_events.afterBlur, this.onBlur.bind(this)); // Update our KO pointer to the active slide on change\n\n (0, _jquery)(this.$element.parents(this.sliderSelector)).parent().on(\"beforeChange\", function () {\n _this.slideChanging = true;\n }).on(\"afterChange\", function () {\n _this.slideChanging = false;\n });\n }\n /**\n * Event handler for wysiwyg focus\n * Fixes z-index issues for tabs and column\n * Fixes slider\n */\n ;\n\n _proto.onFocus = function onFocus() {\n var _this2 = this;\n\n var $slider = (0, _jquery)(this.$element.parents(this.sliderSelector));\n var sliderContent = this.$element.parents(this.sliderContentSelector)[0];\n var $notActiveSlides = $slider.find(this.slideSelector).not(this.activeSlideSelector); // If there isn't enough room for a left-aligned toolbar, right align it\n\n if ((0, _jquery)(window).width() < this.$element.offset().left + parseInt(this.config.adapter_config.minToolbarWidth, 10)) {\n this.$element.addClass(\"_right-aligned-toolbar\");\n } else {\n this.$element.removeClass(\"_right-aligned-toolbar\");\n }\n\n (0, _delayUntil)(function () {\n _jquery.each(_this2.config.adapter_config.parentSelectorsToUnderlay, function (i, selector) {\n _this2.$element.closest(selector).css(\"z-index\", 100);\n }); // Disable slider keyboard events and fix problem with overflow hidden issue\n\n\n $slider.parent().slick(\"slickSetOption\", \"accessibility\", false);\n _this2.autoplay = $slider.parent().slick(\"slickGetOption\", \"autoplay\");\n _this2.fade = $slider.parent().slick(\"slickGetOption\", \"fade\");\n\n if (_this2.autoplay) {\n $slider.parent().slick(\"slickPause\");\n }\n\n if (!_this2.fade) {\n $notActiveSlides.css(\"display\", \"none\");\n }\n\n _this2.sliderTransform = sliderContent.style.transform;\n sliderContent.style.transform = \"\";\n $slider.css(\"overflow\", \"visible\");\n }, function () {\n return !_this2.slideChanging;\n }, 10);\n }\n /**\n * Event handler for wysiwyg blur\n * Fixes z-index issues for tabs and column\n * Fixes slider\n */\n ;\n\n _proto.onBlur = function onBlur() {\n var _this3 = this;\n\n var $slider = (0, _jquery)(this.$element.parents(this.sliderSelector));\n var sliderContent = this.$element.parents(this.sliderContentSelector)[0];\n var $notActiveSlides = $slider.find(this.slideSelector).not(this.activeSlideSelector);\n\n _jquery.each(this.config.adapter_config.parentSelectorsToUnderlay, function (i, selector) {\n _this3.$element.closest(selector).css(\"z-index\", \"\");\n }); // Enable slider keyboard events and revert changes made in onFocus\n\n\n $slider.css(\"overflow\", \"hidden\");\n sliderContent.style.transform = this.sliderTransform;\n $notActiveSlides.css(\"display\", \"block\");\n $slider.parent().slick(\"slickSetOption\", \"accessibility\", true);\n\n if (this.autoplay) {\n $slider.parent().slick(\"slickPlay\");\n }\n };\n\n return ComponentInitializer;\n }();\n\n return ComponentInitializer;\n});\n//# sourceMappingURL=component-initializer.js.map","Magento_PageBuilder/js/content-type/slide/wysiwyg/tinymce/config-modifier.js":"/*eslint-disable */\n/* jscs:disable */\ndefine([], function () {\n /**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n var ConfigModifier = /*#__PURE__*/function () {\n \"use strict\";\n\n function ConfigModifier() {}\n\n var _proto = ConfigModifier.prototype;\n\n /**\n * Initialize the config\n *\n * @param {String} contentTypeId\n * @param {Object} config\n */\n _proto.modify = function modify(contentTypeId, config) {\n if (config.adapter_config.mode === \"inline\") {\n config.adapter.settings.fixed_toolbar_container = \"#\" + contentTypeId + \" .wysiwyg-container\";\n }\n };\n\n return ConfigModifier;\n }();\n\n return ConfigModifier;\n});\n//# sourceMappingURL=config-modifier.js.map","Magento_PageBuilder/js/content-type/slide/converter/style/button-visibility.js":"/*eslint-disable */\n/* jscs:disable */\ndefine([], function () {\n /**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n var ButtonVisibility = /*#__PURE__*/function () {\n \"use strict\";\n\n function ButtonVisibility() {}\n\n var _proto = ButtonVisibility.prototype;\n\n /**\n * Convert value to internal format\n *\n * @param value string\n * @returns {string | object}\n */\n _proto.fromDom = function fromDom(value) {\n return value;\n }\n /**\n * Convert value to knockout format\n *\n * @param {string} name\n * @param {DataObject} data\n * @returns {string | object}\n */\n ;\n\n _proto.toDom = function toDom(name, data) {\n return data.show_button === \"always\" ? \"visible\" : \"hidden\";\n };\n\n return ButtonVisibility;\n }();\n\n return ButtonVisibility;\n});\n//# sourceMappingURL=button-visibility.js.map","Magento_PageBuilder/js/content-type/slide/converter/style/paddings.js":"/*eslint-disable */\n/* jscs:disable */\ndefine([\"underscore\", \"Magento_PageBuilder/js/utils/object\"], function (_underscore, _object) {\n /**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n var Paddings = /*#__PURE__*/function () {\n \"use strict\";\n\n function Paddings() {}\n\n var _proto = Paddings.prototype;\n\n /**\n * Convert value to internal format\n *\n * @param value string\n * @returns {string | object}\n */\n _proto.fromDom = function fromDom(value) {\n var result = {};\n\n if (undefined !== value.padding) {\n result.padding = {\n bottom: value.padding.bottom.replace(\"px\", \"\"),\n left: value.padding.left.replace(\"px\", \"\"),\n right: value.padding.right.replace(\"px\", \"\"),\n top: value.padding.top.replace(\"px\", \"\")\n };\n }\n\n if (result.padding.right[0] === \"c\") {\n result.padding.right = parseInt(result.padding.right.split(\"+\")[1].trim(), 10);\n }\n\n if (result.padding.left[0] === \"c\") {\n result.padding.left = parseInt(result.padding.left.split(\"+\")[1].trim(), 10);\n }\n\n return result;\n }\n /**\n * Convert value to knockout format\n *\n * @param {string} name\n * @param {DataObject} data\n * @returns {string | object}\n */\n ;\n\n _proto.toDom = function toDom(name, data) {\n var result = {};\n var value = (0, _object.get)(data, name);\n\n if (value && _underscore.isString(value)) {\n value = JSON.parse(value);\n }\n\n if (value && undefined !== value.padding) {\n result.paddingLeft = value.padding.left ? value.padding.left + \"px\" : \"\";\n result.paddingTop = value.padding.top ? value.padding.top + \"px\" : \"\";\n result.paddingRight = value.padding.right ? value.padding.right + \"px\" : \"\";\n result.paddingBottom = value.padding.bottom ? value.padding.bottom + \"px\" : \"\";\n }\n\n return result;\n };\n\n return Paddings;\n }();\n\n return Paddings;\n});\n//# sourceMappingURL=paddings.js.map","Magento_PageBuilder/js/content-type/slide/converter/style/button-opacity.js":"/*eslint-disable */\n/* jscs:disable */\ndefine([], function () {\n /**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n var ButtonOpacity = /*#__PURE__*/function () {\n \"use strict\";\n\n function ButtonOpacity() {}\n\n var _proto = ButtonOpacity.prototype;\n\n /**\n * Convert value to internal format\n *\n * @param value string\n * @returns {string | object}\n */\n _proto.fromDom = function fromDom(value) {\n return value;\n }\n /**\n * Convert value to knockout format\n *\n * @param {string} name\n * @param {DataObject} data\n * @returns {string | object}\n */\n ;\n\n _proto.toDom = function toDom(name, data) {\n return data.show_button === \"always\" ? \"1\" : \"0\";\n };\n\n return ButtonOpacity;\n }();\n\n return ButtonOpacity;\n});\n//# sourceMappingURL=button-opacity.js.map","Magento_PageBuilder/js/content-type/slide/converter/style/margins.js":"/*eslint-disable */\n/* jscs:disable */\ndefine([\"underscore\", \"Magento_PageBuilder/js/utils/object\"], function (_underscore, _object) {\n /**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n var Margins = /*#__PURE__*/function () {\n \"use strict\";\n\n function Margins() {}\n\n var _proto = Margins.prototype;\n\n /**\n * Convert value to internal format\n *\n * @param value string\n * @returns {string | object}\n */\n _proto.fromDom = function fromDom(value) {\n if (undefined !== value.margin) {\n return {\n margin: {\n top: value.margin.top.replace(\"px\", \"\"),\n left: value.margin.left.replace(\"px\", \"\"),\n right: value.margin.right.replace(\"px\", \"\"),\n bottom: value.margin.bottom.replace(\"px\", \"\")\n }\n };\n }\n\n return {};\n }\n /**\n * Convert value to knockout format\n *\n * @param {string} name\n * @param {DataObject} data\n * @returns {string | object}\n */\n ;\n\n _proto.toDom = function toDom(name, data) {\n var result = {};\n var value = (0, _object.get)(data, name);\n\n if (value && _underscore.isString(value)) {\n value = JSON.parse(value);\n }\n\n if (value && undefined !== value.margin) {\n result.marginLeft = value.margin.left ? value.margin.left + \"px\" : \"\";\n result.marginTop = value.margin.top ? value.margin.top + \"px\" : \"\";\n result.marginRight = value.margin.right ? value.margin.right + \"px\" : \"\";\n result.marginBottom = value.margin.bottom ? value.margin.bottom + \"px\" : \"\";\n }\n\n return result;\n };\n\n return Margins;\n }();\n\n return Margins;\n});\n//# sourceMappingURL=margins.js.map","Magento_PageBuilder/js/content-type/slide/converter/style/overlay-background-color.js":"/*eslint-disable */\n/* jscs:disable */\ndefine([\"Magento_PageBuilder/js/utils/object\"], function (_object) {\n /**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n var OverlayBackgroundColor = /*#__PURE__*/function () {\n \"use strict\";\n\n function OverlayBackgroundColor() {}\n\n var _proto = OverlayBackgroundColor.prototype;\n\n /**\n * Convert value to internal format\n *\n * @param value string\n * @returns {string | object}\n */\n _proto.fromDom = function fromDom(value) {\n return value;\n }\n /**\n * Convert value to knockout format\n *\n * @param name string\n * @param data Object\n * @returns {string | object}\n */\n ;\n\n _proto.toDom = function toDom(name, data) {\n var value = (0, _object.get)(data, name);\n\n if (data.show_overlay === \"always\" && value !== \"\" && value !== undefined) {\n return value;\n }\n\n return \"transparent\";\n };\n\n return OverlayBackgroundColor;\n }();\n\n return OverlayBackgroundColor;\n});\n//# sourceMappingURL=overlay-background-color.js.map","Magento_PageBuilder/js/content-type/slide/converter/attribute/overlay-color.js":"/*eslint-disable */\n/* jscs:disable */\ndefine([], function () {\n /**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n var OverlayColor = /*#__PURE__*/function () {\n \"use strict\";\n\n function OverlayColor() {}\n\n var _proto = OverlayColor.prototype;\n\n /**\n * Convert value to internal format\n *\n * @param value string\n * @returns {string | object}\n */\n _proto.fromDom = function fromDom(value) {\n return value === \"transparent\" ? \"\" : value;\n }\n /**\n * Convert value to knockout format\n *\n * @param {string} name\n * @param {DataObject} data\n * @returns {string | object}\n */\n ;\n\n _proto.toDom = function toDom(name, data) {\n if (data.overlay_color) {\n return data.overlay_color.toString();\n }\n\n return \"\";\n };\n\n return OverlayColor;\n }();\n\n return OverlayColor;\n});\n//# sourceMappingURL=overlay-color.js.map","Magento_PageBuilder/js/content-type/block/preview.js":"/*eslint-disable */\n/* jscs:disable */\n\nfunction _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); }\n\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n\ndefine([\"jquery\", \"knockout\", \"mage/translate\", \"Magento_PageBuilder/js/widget-initializer\", \"mageUtils\", \"underscore\", \"Magento_PageBuilder/js/config\", \"Magento_PageBuilder/js/content-type-menu/hide-show-option\", \"Magento_PageBuilder/js/content-type/style-registry\", \"Magento_PageBuilder/js/utils/object\", \"Magento_PageBuilder/js/content-type/preview\"], function (_jquery, _knockout, _translate, _widgetInitializer, _mageUtils, _underscore, _config, _hideShowOption, _styleRegistry, _object, _preview) {\n /**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n /**\n * @api\n */\n var Preview = /*#__PURE__*/function (_preview2) {\n \"use strict\";\n\n _inheritsLoose(Preview, _preview2);\n\n /**\n * @inheritdoc\n */\n function Preview(contentType, config, observableUpdater) {\n var _this;\n\n _this = _preview2.call(this, contentType, config, observableUpdater) || this;\n _this.displayingBlockPreview = _knockout.observable(false);\n _this.loading = _knockout.observable(false);\n _this.messages = {\n NOT_SELECTED: (0, _translate)(\"Empty Block\"),\n UNKNOWN_ERROR: (0, _translate)(\"An unknown error occurred. Please try again.\")\n };\n _this.placeholderText = _knockout.observable(_this.messages.NOT_SELECTED);\n return _this;\n }\n /**\n * Return an array of options\n *\n * @returns {OptionsInterface}\n */\n\n\n var _proto = Preview.prototype;\n\n _proto.retrieveOptions = function retrieveOptions() {\n var options = _preview2.prototype.retrieveOptions.call(this);\n\n options.hideShow = new _hideShowOption({\n preview: this,\n icon: _hideShowOption.showIcon,\n title: _hideShowOption.showText,\n action: this.onOptionVisibilityToggle,\n classes: [\"hide-show-content-type\"],\n sort: 40\n });\n return options;\n }\n /**\n * Runs the widget initializer for each configured widget\n */\n ;\n\n _proto.initializeWidgets = function initializeWidgets(element) {\n if (element) {\n this.element = element;\n (0, _widgetInitializer)({\n config: _config.getConfig(\"widgets\"),\n breakpoints: _config.getConfig(\"breakpoints\"),\n currentViewport: _config.getConfig(\"viewport\")\n }, element);\n }\n }\n /**\n * Updates the view state using the data provided\n * @param {DataObject} data\n */\n ;\n\n _proto.processBlockData = function processBlockData(data) {\n // Only load if something changed\n this.displayPreviewPlaceholder(data, \"block_id\");\n\n if (data.block_id && data.template.length !== 0) {\n this.processRequest(data, \"block_id\", \"title\");\n }\n }\n /**\n * @inheritdoc\n */\n ;\n\n _proto.afterObservablesUpdated = function afterObservablesUpdated() {\n _preview2.prototype.afterObservablesUpdated.call(this);\n\n var data = this.contentType.dataStore.getState(); // Only load if something changed\n\n this.processBlockData(data);\n }\n /**\n * Display preview placeholder\n *\n * @param {DataObject} data\n * @param {string} identifierName\n */\n ;\n\n _proto.displayPreviewPlaceholder = function displayPreviewPlaceholder(data, identifierName) {\n var blockId = (0, _object.get)(data, identifierName); // Only load if something changed\n\n if (this.lastBlockId === blockId && this.lastTemplate === data.template) {\n // The mass converter will have transformed the HTML property into a directive\n if (this.lastRenderedHtml) {\n this.data.main.html(this.lastRenderedHtml);\n this.showBlockPreview(true);\n this.initializeWidgets(this.element);\n }\n } else {\n this.showBlockPreview(false);\n this.placeholderText(\"\");\n }\n\n if (!blockId || blockId && blockId.toString().length === 0 || data.template.length === 0) {\n this.showBlockPreview(false);\n this.placeholderText(this.messages.NOT_SELECTED);\n return;\n }\n }\n /**\n *\n * @param {DataObject} data\n * @param {string} identifierName\n * @param {string} labelKey\n */\n ;\n\n _proto.processRequest = function processRequest(data, identifierName, labelKey) {\n var _this2 = this;\n\n var url = _config.getConfig(\"preview_url\");\n\n var identifier = (0, _object.get)(data, identifierName);\n var requestConfig = {\n // Prevent caching\n method: \"POST\",\n data: {\n role: this.config.name,\n block_id: identifier,\n directive: this.data.main.html()\n }\n };\n this.loading(true); // Retrieve a state object representing the block from the preview controller and process it on the stage\n\n _jquery.ajax(url, requestConfig) // The state object will contain the block name and either html or a message why there isn't any.\n .done(function (response) {\n // Empty content means something bad happened in the controller that didn't trigger a 5xx\n if (typeof response.data !== \"object\") {\n _this2.showBlockPreview(false);\n\n _this2.placeholderText(_this2.messages.UNKNOWN_ERROR);\n\n return;\n } // Update the stage content type label with the real block title if provided\n\n\n _this2.displayLabel(response.data[labelKey] ? response.data[labelKey] : _this2.config.label);\n\n var content = \"\";\n\n if (response.data.content) {\n content = _this2.processContent(response.data.content);\n\n _this2.data.main.html(content);\n\n _this2.showBlockPreview(true);\n\n _this2.initializeWidgets(_this2.element);\n } else if (response.data.error) {\n _this2.showBlockPreview(false);\n\n _this2.placeholderText(response.data.error);\n }\n\n _this2.lastBlockId = parseInt(identifier.toString(), 10);\n _this2.lastTemplate = data.template.toString();\n _this2.lastRenderedHtml = content;\n }).fail(function () {\n _this2.showBlockPreview(false);\n\n _this2.placeholderText(_this2.messages.UNKNOWN_ERROR);\n }).always(function () {\n _this2.loading(false);\n });\n }\n /**\n * Toggle display of block preview. If showing block preview, add hidden mode to PB preview.\n * @param {boolean} isShow\n */\n ;\n\n _proto.showBlockPreview = function showBlockPreview(isShow) {\n this.displayingBlockPreview(isShow);\n }\n /**\n * Adapt content to view it on stage.\n *\n * @param content\n */\n ;\n\n _proto.processContent = function processContent(content) {\n var processedContent = this.processBackgroundImages(content);\n processedContent = this.processBreakpointStyles(processedContent);\n return processedContent;\n }\n /**\n * Generate styles for background images.\n *\n * @param {string} content\n * @return string\n */\n ;\n\n _proto.processBackgroundImages = function processBackgroundImages(content) {\n var document = new DOMParser().parseFromString(content, \"text/html\");\n var elements = document.querySelectorAll(\"[data-background-images]\");\n var styleBlock = document.createElement(\"style\");\n\n var viewports = _config.getConfig(\"viewports\");\n\n elements.forEach(function (element) {\n var rawAttrValue = element.getAttribute(\"data-background-images\").replace(/\\\\(.)/mg, \"$1\");\n var attrValue = JSON.parse(rawAttrValue);\n\n var elementClass = \"background-image-\" + _mageUtils.uniqueid(13);\n\n var rules = \"\";\n Object.keys(attrValue).forEach(function (imageName) {\n var imageUrl = attrValue[imageName];\n var viewportName = imageName.replace(\"_image\", \"\");\n\n if (viewports[viewportName].stage && imageUrl) {\n rules += \".\" + viewportName + \"-viewport .\" + elementClass + \" {\\n background-image: url(\\\"\" + imageUrl + \"\\\");\\n }\";\n }\n });\n\n if (rules.length) {\n styleBlock.append(rules);\n element.classList.add(elementClass);\n }\n });\n\n if (elements.length && styleBlock.innerText.length) {\n document.body.append(styleBlock);\n content = document.head.innerHTML + document.body.innerHTML;\n }\n\n return content;\n }\n /**\n * Replace media queries with viewport classes.\n *\n * @param {string} content\n * @return string\n */\n ;\n\n _proto.processBreakpointStyles = function processBreakpointStyles(content) {\n var document = new DOMParser().parseFromString(content, \"text/html\");\n var styleBlocks = document.querySelectorAll(\"style\");\n var mediaStyleBlock = document.createElement(\"style\");\n\n var viewports = _config.getConfig(\"viewports\");\n\n styleBlocks.forEach(function (styleBlock) {\n var cssRules = styleBlock.sheet.cssRules;\n Array.from(cssRules).forEach(function (rule) {\n var mediaScope = rule instanceof CSSMediaRule && _underscore.findKey(viewports, function (viewport) {\n return rule.conditionText === viewport.media;\n });\n\n if (mediaScope) {\n Array.from(rule.cssRules).forEach(function (mediaRule, index) {\n if (mediaRule.selectorText.indexOf(_styleRegistry.pbStyleAttribute) !== -1) {\n var searchPattern = new RegExp(_config.getConfig(\"bodyId\") + \" \", \"g\");\n var replaceValue = _config.getConfig(\"bodyId\") + \" .\" + mediaScope + \"-viewport \";\n var selector = mediaRule.selectorText.replace(searchPattern, replaceValue);\n mediaStyleBlock.append(selector + \" {\" + mediaRule.style.cssText + \"}\");\n }\n });\n }\n });\n });\n\n if (mediaStyleBlock.innerText.length) {\n document.body.append(mediaStyleBlock);\n content = document.head.innerHTML + document.body.innerHTML;\n }\n\n return content;\n };\n\n return Preview;\n }(_preview);\n\n return Preview;\n});\n//# sourceMappingURL=preview.js.map","Magento_PageBuilder/js/content-type/block/mass-converter/widget-directive.js":"/*eslint-disable */\n/* jscs:disable */\n\nfunction _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); }\n\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n\ndefine([\"Magento_PageBuilder/js/mass-converter/widget-directive-abstract\", \"Magento_PageBuilder/js/utils/object\"], function (_widgetDirectiveAbstract, _object) {\n /**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n /**\n * Enables the settings of the content type to be stored as a widget directive.\n *\n * @api\n */\n var WidgetDirective = /*#__PURE__*/function (_widgetDirectiveAbstr) {\n \"use strict\";\n\n _inheritsLoose(WidgetDirective, _widgetDirectiveAbstr);\n\n function WidgetDirective() {\n return _widgetDirectiveAbstr.apply(this, arguments) || this;\n }\n\n var _proto = WidgetDirective.prototype;\n\n /**\n * Convert value to internal format\n *\n * @param {object} data\n * @param {object} config\n * @returns {object}\n */\n _proto.fromDom = function fromDom(data, config) {\n var attributes = _widgetDirectiveAbstr.prototype.fromDom.call(this, data, config);\n\n data.template = attributes.template;\n data.block_id = attributes.block_id;\n return data;\n }\n /**\n * Convert value to knockout format\n *\n * @param {object} data\n * @param {object} config\n * @returns {object}\n */\n ;\n\n _proto.toDom = function toDom(data, config) {\n var attributes = {\n type: \"Magento\\\\Cms\\\\Block\\\\Widget\\\\Block\",\n template: data.template,\n block_id: data.block_id,\n type_name: \"CMS Static Block\"\n };\n\n if (!attributes.block_id || !attributes.template) {\n return data;\n }\n\n (0, _object.set)(data, config.html_variable, this.buildDirective(attributes));\n return data;\n };\n\n return WidgetDirective;\n }(_widgetDirectiveAbstract);\n\n return WidgetDirective;\n});\n//# sourceMappingURL=widget-directive.js.map","Magento_PageBuilder/js/content-type/heading/preview.js":"/*eslint-disable */\n/* jscs:disable */\n\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return self; }\n\nfunction _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); }\n\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n\ndefine([\"jquery\", \"Magento_PageBuilder/js/events\", \"underscore\", \"Magento_PageBuilder/js/content-type-menu/hide-show-option\", \"Magento_PageBuilder/js/content-type-toolbar\", \"Magento_PageBuilder/js/utils/promise-deferred\", \"Magento_PageBuilder/js/content-type/preview\"], function (_jquery, _events, _underscore, _hideShowOption, _contentTypeToolbar, _promiseDeferred, _preview) {\n /**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n /**\n * @api\n */\n var Preview = /*#__PURE__*/function (_preview2) {\n \"use strict\";\n\n _inheritsLoose(Preview, _preview2);\n\n /**\n * @param {ContentTypeInterface} contentType\n * @param {ContentTypeConfigInterface} config\n * @param {ObservableUpdater} observableUpdater\n */\n function Preview(contentType, config, observableUpdater) {\n var _this;\n\n _this = _preview2.call(this, contentType, config, observableUpdater) || this;\n _this.afterRenderDeferred = (0, _promiseDeferred)();\n _this.toolbar = new _contentTypeToolbar(_assertThisInitialized(_this), _this.getToolbarOptions());\n return _this;\n }\n /**\n * Return an array of options\n *\n * @returns {OptionsInterface}\n */\n\n\n var _proto = Preview.prototype;\n\n _proto.retrieveOptions = function retrieveOptions() {\n var options = _preview2.prototype.retrieveOptions.call(this);\n\n options.hideShow = new _hideShowOption({\n preview: this,\n icon: _hideShowOption.showIcon,\n title: _hideShowOption.showText,\n action: this.onOptionVisibilityToggle,\n classes: [\"hide-show-content-type\"],\n sort: 40\n });\n return options;\n }\n /**\n * On render init the heading\n *\n * @param {Element} element\n */\n ;\n\n _proto.afterRender = function afterRender(element) {\n this.element = element;\n this.afterRenderDeferred.resolve(element);\n };\n\n _proto.bindEvents = function bindEvents() {\n var _this2 = this;\n\n _preview2.prototype.bindEvents.call(this); // When a heading is dropped for the first time show heading toolbar\n\n\n _events.on(\"heading:dropAfter\", function (args) {\n if (args.id === _this2.contentType.id) {\n Promise.all([_this2.afterRenderDeferred.promise, _this2.toolbar.afterRenderDeferred.promise]).then(function (_ref) {\n var element = _ref[0];\n\n _underscore.defer(function () {\n (0, _jquery)(element).focus();\n });\n });\n }\n });\n }\n /**\n * Get option value from observable data.\n *\n * @param {string} key\n * @return {*}\n */\n ;\n\n _proto.getOptionValue = function getOptionValue(key) {\n if (key === \"heading_type\") {\n return this.data.main.heading_type();\n } else if (key === \"text_align\") {\n return this.data.main.style().textAlign;\n }\n\n return;\n }\n /**\n * Build and return the tool bar options for heading\n *\n * @returns {OptionInterface[]}\n */\n ;\n\n _proto.getToolbarOptions = function getToolbarOptions() {\n return [{\n key: \"heading_type\",\n type: \"select\",\n values: [{\n value: \"h1\",\n label: \"H1\",\n icon: \"\"\n }, {\n value: \"h2\",\n label: \"H2\",\n icon: \"\"\n }, {\n value: \"h3\",\n label: \"H3\",\n icon: \"\"\n }, {\n value: \"h4\",\n label: \"H4\",\n icon: \"\"\n }, {\n value: \"h5\",\n label: \"H5\",\n icon: \"\"\n }, {\n value: \"h6\",\n label: \"H6\",\n icon: \"\"\n }]\n }, {\n key: \"text_align\",\n type: \"select\",\n values: [{\n value: \"left\",\n label: \"Left\",\n icon: \"icon-pagebuilder-align-left\"\n }, {\n value: \"center\",\n label: \"Center\",\n icon: \"icon-pagebuilder-align-center\"\n }, {\n value: \"right\",\n label: \"Right\",\n icon: \"icon-pagebuilder-align-right\"\n }]\n }];\n };\n\n return Preview;\n }(_preview);\n\n return Preview;\n});\n//# sourceMappingURL=preview.js.map","Magento_PageBuilder/js/content-type/divider/preview.js":"/*eslint-disable */\n/* jscs:disable */\n\nfunction _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); }\n\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n\ndefine([\"Magento_PageBuilder/js/content-type-menu/hide-show-option\", \"Magento_PageBuilder/js/content-type/preview\"], function (_hideShowOption, _preview) {\n /**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n /**\n * @api\n */\n var Preview = /*#__PURE__*/function (_preview2) {\n \"use strict\";\n\n _inheritsLoose(Preview, _preview2);\n\n function Preview() {\n return _preview2.apply(this, arguments) || this;\n }\n\n var _proto = Preview.prototype;\n\n /**\n * Return an array of options\n *\n * @returns {OptionsInterface}\n */\n _proto.retrieveOptions = function retrieveOptions() {\n var options = _preview2.prototype.retrieveOptions.call(this);\n\n options.hideShow = new _hideShowOption({\n preview: this,\n icon: _hideShowOption.showIcon,\n title: _hideShowOption.showText,\n action: this.onOptionVisibilityToggle,\n classes: [\"hide-show-content-type\"],\n sort: 40\n });\n return options;\n };\n\n return Preview;\n }(_preview);\n\n return Preview;\n});\n//# sourceMappingURL=preview.js.map","Magento_PageBuilder/js/content-type/tab-item/preview.js":"/*eslint-disable */\n/* jscs:disable */\n\nfunction _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); }\n\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n\ndefine([\"jquery\", \"knockout\", \"Magento_PageBuilder/js/content-type-menu/conditional-remove-option\", \"Magento_PageBuilder/js/content-type/preview-collection\"], function (_jquery, _knockout, _conditionalRemoveOption, _previewCollection) {\n /**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n /**\n * @api\n */\n var Preview = /*#__PURE__*/function (_previewCollection2) {\n \"use strict\";\n\n _inheritsLoose(Preview, _previewCollection2);\n\n function Preview() {\n var _this;\n\n for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n args[_key] = arguments[_key];\n }\n\n _this = _previewCollection2.call.apply(_previewCollection2, [this].concat(args)) || this;\n _this.fieldsToIgnoreOnRemove = [\"tab_name\"];\n return _this;\n }\n\n var _proto = Preview.prototype;\n\n /**\n * Get background image url base on the viewport.\n *\n * @returns {string}\n */\n _proto.getBackgroundImage = function getBackgroundImage() {\n var mobileImage = this.contentType.dataStore.get(\"mobile_image\");\n var desktopImage = this.contentType.dataStore.get(\"background_image\");\n var backgroundImage = this.viewport() === \"mobile\" && mobileImage.length ? mobileImage : desktopImage;\n return backgroundImage.length ? \"url(\\\"\" + backgroundImage[0].url + \"\\\")\" : \"none\";\n }\n /**\n * Force the focus on the clicked tab header\n *\n * @param {number} index\n * @param {JQueryEventObject} event\n */\n ;\n\n _proto.onClick = function onClick(index, event) {\n (0, _jquery)(event.currentTarget).find(\"[contenteditable]\").focus();\n event.stopPropagation();\n }\n /**\n * On focus in set the focused button\n *\n * @param {number} index\n * @param {Event} event\n */\n ;\n\n _proto.onFocusIn = function onFocusIn(index, event) {\n var parentPreview = this.contentType.parentContentType.preview;\n\n if (parentPreview.focusedTab() !== index) {\n parentPreview.setFocusedTab(index, true);\n }\n }\n /**\n * On focus out set the focused tab to null\n *\n * @param {number} index\n * @param {JQueryEventObject} event\n */\n ;\n\n _proto.onFocusOut = function onFocusOut(index, event) {\n if (this.contentType && this.contentType.parentContentType) {\n var parentPreview = this.contentType.parentContentType.preview;\n\n var unfocus = function unfocus() {\n window.getSelection().removeAllRanges();\n parentPreview.focusedTab(null);\n };\n\n if (event.relatedTarget && _jquery.contains(parentPreview.wrapperElement, event.relatedTarget)) {\n // Verify the focus was not onto the options menu\n if ((0, _jquery)(event.relatedTarget).closest(\".pagebuilder-options\").length > 0) {\n unfocus();\n } else {\n // Have we moved the focus onto another button in the current group?\n var tabItem = _knockout.dataFor(event.relatedTarget);\n\n if (tabItem && tabItem.contentType && tabItem.contentType.parentContentType && tabItem.contentType.parentContentType.id === this.contentType.parentContentType.id) {\n var newIndex = tabItem.contentType.parentContentType.children().indexOf(tabItem.contentType);\n parentPreview.setFocusedTab(newIndex, true);\n } else {\n unfocus();\n }\n }\n } else if (parentPreview.focusedTab() === index) {\n unfocus();\n }\n }\n }\n /**\n * Get the options instance\n *\n * @returns {OptionsInterface}\n */\n ;\n\n _proto.retrieveOptions = function retrieveOptions() {\n var options = _previewCollection2.prototype.retrieveOptions.call(this);\n\n delete options.move;\n delete options.title;\n options.remove = new _conditionalRemoveOption(_extends({}, options.remove.config, {\n preview: this\n }));\n return options;\n };\n\n return Preview;\n }(_previewCollection);\n\n return Preview;\n});\n//# sourceMappingURL=preview.js.map","Magento_PageBuilder/js/content-type/column-group/grid-size.js":"/*eslint-disable */\n/* jscs:disable */\n\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return self; }\n\nfunction _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); }\n\nfunction _wrapNativeSuper(Class) { var _cache = typeof Map === \"function\" ? new Map() : undefined; _wrapNativeSuper = function _wrapNativeSuper(Class) { if (Class === null || !_isNativeFunction(Class)) return Class; if (typeof Class !== \"function\") { throw new TypeError(\"Super expression must either be null or a function\"); } if (typeof _cache !== \"undefined\") { if (_cache.has(Class)) return _cache.get(Class); _cache.set(Class, Wrapper); } function Wrapper() { return _construct(Class, arguments, _getPrototypeOf(this).constructor); } Wrapper.prototype = Object.create(Class.prototype, { constructor: { value: Wrapper, enumerable: false, writable: true, configurable: true } }); return _setPrototypeOf(Wrapper, Class); }; return _wrapNativeSuper(Class); }\n\nfunction _construct(Parent, args, Class) { if (_isNativeReflectConstruct()) { _construct = Reflect.construct; } else { _construct = function _construct(Parent, args, Class) { var a = [null]; a.push.apply(a, args); var Constructor = Function.bind.apply(Parent, a); var instance = new Constructor(); if (Class) _setPrototypeOf(instance, Class.prototype); return instance; }; } return _construct.apply(null, arguments); }\n\nfunction _isNativeReflectConstruct() { if (typeof Reflect === \"undefined\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \"function\") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }\n\nfunction _isNativeFunction(fn) { return Function.toString.call(fn).indexOf(\"[native code]\") !== -1; }\n\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n\nfunction _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }\n\nfunction _createForOfIteratorHelperLoose(o, allowArrayLike) { var it = typeof Symbol !== \"undefined\" && o[Symbol.iterator] || o[\"@@iterator\"]; if (it) return (it = it.call(o)).next.bind(it); if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === \"number\") { if (it) o = it; var i = 0; return function () { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }; } throw new TypeError(\"Invalid attempt to iterate non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\"); }\n\nfunction _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === \"string\") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === \"Object\" && o.constructor) n = o.constructor.name; if (n === \"Map\" || n === \"Set\") return Array.from(o); if (n === \"Arguments\" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }\n\nfunction _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }\n\ndefine([\"mage/translate\", \"Magento_PageBuilder/js/config\", \"Magento_PageBuilder/js/content-type/column/resize\"], function (_translate, _config, _resize) {\n /**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n /**\n * Retrieve default grid size\n *\n * @returns {number}\n */\n function getDefaultGridSize() {\n return parseInt(_config.getConfig(\"column_grid_default\"), 10);\n }\n /**\n * Retrieve the max grid size\n *\n * @returns {number}\n */\n\n\n function getMaxGridSize() {\n return parseInt(_config.getConfig(\"column_grid_max\"), 10);\n }\n /**\n * Apply the new grid size, adjusting the existing columns as needed.\n *\n * Rules for resizing the grid:\n * - The grid size can be increased up to the configured maximum value.\n * - The grid size can be decreased only if the number of non-empty columns is less than or equal to the new size.\n * - If the new grid size is less than the number of columns currently in the grid, empty columns will be deleted\n * to accommodate the new size.\n *\n * @param {ContentTypeCollectionInterface<Preview>} columnGroup\n * @param {number} newGridSize\n * @param {Map<number, number[]>} gridSizeHistory\n */\n\n\n function resizeGrid(columnGroup, newGridSize, gridSizeHistory) {\n if (newGridSize === columnGroup.preview.getResizeUtils().getInitialGridSize()) {\n return;\n }\n\n validateNewGridSize(columnGroup, newGridSize);\n columnGroup.getChildren()().forEach(function (columnLine, index) {\n // if we have more columns than the new grid size allows, remove empty columns till the correct size\n console.log(columnLine.getChildren()().length);\n\n if (newGridSize < columnLine.getChildren()().length) {\n removeEmptyColumnsToFit(columnLine, newGridSize);\n }\n }); // update column widths\n\n redistributeColumnWidths(columnGroup, newGridSize, gridSizeHistory);\n }\n /**\n * Validate that the new grid size is within the configured limits and can be achieved.\n *\n * @param {ContentTypeCollectionInterface<Preview>} columnGroup\n * @param {number} newGridSize\n */\n\n\n function validateNewGridSize(columnGroup, newGridSize) {\n // Validate against the max grid size\n if (newGridSize > getMaxGridSize()) {\n throw new GridSizeError((0, _translate)(\"The maximum grid size supported is \" + getMaxGridSize() + \".\"));\n } else if (newGridSize < 2) {\n throw new GridSizeError((0, _translate)(\"The minimum grid size supported is 2.\"));\n } // Validate that the operation will be successful\n\n\n var doThrowException = false;\n columnGroup.getChildren()().forEach(function (columnLine, index) {\n var numEmptyColumns = 0;\n var numCols = columnLine.getChildren()().length;\n var currentGridSize = columnLine.preview.getResizeUtils().getInitialGridSize();\n\n if (newGridSize < currentGridSize && numCols > newGridSize) {\n columnLine.getChildren()().forEach(function (column) {\n if (column.getChildren()().length === 0) {\n numEmptyColumns++;\n }\n });\n\n if (newGridSize < numCols - numEmptyColumns) {\n doThrowException = true;\n }\n }\n });\n\n if (doThrowException) {\n throw new Error((0, _translate)(\"Grid size cannot be smaller than the current total amount of columns, minus any empty columns.\"));\n }\n }\n /**\n * Remove empty columns so we can accommodate the new grid size\n *\n * @param {ContentTypeCollectionInterface<Preview>} columnGroup\n * @param {number} newGridSize\n */\n\n\n function removeEmptyColumnsToFit(columnLine, newGridSize) {\n var columns = columnLine.getChildren()();\n var numColumns = columns.length;\n var i;\n\n for (i = numColumns - 1; i >= 0; i--) {\n var column = columns[i];\n\n if (newGridSize < numColumns && column.getChildren()().length === 0) {\n columnLine.removeChild(column);\n numColumns--;\n }\n }\n }\n /**\n * Adjust columns widths across the new grid size, making sure each column is at least one grid size in width\n * and the entire grid size is distributed.\n *\n * @param {ContentTypeCollectionInterface<Preview>} columnGroup\n * @param {number} newGridSize\n * @param {Map<number, number[]>} gridSizeHistory\n */\n\n\n function redistributeColumnWidths(columnGroup, newGridSize, gridSizeHistory) {\n // apply known column widths if we have resized before\n if (gridSizeHistory.has(newGridSize) && gridSizeHistory.get(newGridSize).length === columnGroup.getChildren()().length) {\n var columnWidths = gridSizeHistory.get(newGridSize);\n columnGroup.getChildren()().forEach(function (column, index) {\n (0, _resize.updateColumnWidth)(column, columnWidths[index]);\n });\n columnGroup.dataStore.set(\"grid_size\", newGridSize);\n columnGroup.dataStore.unset(\"initial_grid_size\");\n return;\n }\n\n var columnGroupResizeUtil = columnGroup.preview.getResizeUtils();\n var existingGridSize = columnGroupResizeUtil.getInitialGridSize();\n var minColWidth = parseFloat((100 / newGridSize).toString()).toFixed(Math.round(100 / newGridSize) !== 100 / newGridSize ? 8 : 0);\n columnGroup.getChildren()().forEach(function (columnLine, columnLineIndex) {\n var totalNewWidths = 0;\n var remainingWidth = 0;\n var numColumns = columnLine.getChildren()().length;\n var resizeUtils = columnLine.preview.getResizeUtils();\n columnLine.getChildren()().forEach(function (column, index) {\n var existingWidth = resizeUtils.getColumnWidth(column);\n var fractionColumnWidth = Math.round(existingWidth / (100 / existingGridSize));\n /**\n * Determine if the grid & column are directly compatible with the new defined grid size, this will\n * directly convert fractions to their equivalent of the new grid size.\n *\n * For instance changing a 12 column grid with 2 x 6 / 12 columns to a 6 grid is fully compatible.\n *\n * Check the existing grid size and new grid size are divisible, verify the amount of columns will fit\n * in the new grid size and finally check the calculation to convert the existing column width results\n * in a positive integer.\n */\n\n if ((existingGridSize > newGridSize && existingGridSize % newGridSize === 0 || existingGridSize < newGridSize && newGridSize % existingGridSize === 0) && newGridSize % numColumns === 0 && newGridSize / existingGridSize * fractionColumnWidth % 1 === 0) {\n // We don't need to modify the columns width as it's compatible, we will however increment the\n // width counter as some other columns may not be compatible.\n totalNewWidths += existingWidth;\n } else {\n var newWidth = (100 * Math.floor(existingWidth / 100 * newGridSize) / newGridSize).toFixed(Math.round(100 / newGridSize) !== 100 / newGridSize ? 8 : 0); // make sure the column is at least one grid size wide\n\n if (parseFloat(newWidth) < parseFloat(minColWidth)) {\n newWidth = minColWidth;\n } // make sure we leave enough space for other columns\n\n\n var widthTaken = totalNewWidths + (numColumns - index - 1) * parseFloat(minColWidth);\n var maxAvailableWidth = 100 - totalNewWidths;\n\n if (parseFloat(newWidth) > maxAvailableWidth) {\n var gridWidth = Math.round(100 / newGridSize) !== 100 / newGridSize ? 8 : 0;\n newWidth = maxAvailableWidth.toFixed(gridWidth);\n } // Calculate any width lost from the column, if a 5 / 12 is becoming a 2 / 6 then it's lost 1 / 12\n\n\n remainingWidth += existingWidth - parseFloat(newWidth);\n /**\n * Determine if we have enough remaining width, and apply it to the current column, this results in\n * a subsequent column always receiving any additional width from the previous column\n */\n\n if (resizeUtils.getSmallestColumnWidth(newGridSize) === resizeUtils.getAcceptedColumnWidth(remainingWidth.toString(), newGridSize)) {\n var widthWithRemaining = resizeUtils.getAcceptedColumnWidth((parseFloat(newWidth) + remainingWidth).toString(), newGridSize);\n\n if (widthWithRemaining > 0) {\n newWidth = widthWithRemaining.toFixed(Math.round(100 / widthWithRemaining) !== 100 / widthWithRemaining ? 8 : 0);\n remainingWidth = 0;\n }\n }\n\n totalNewWidths += parseFloat(newWidth);\n (0, _resize.updateColumnWidth)(column, parseFloat(newWidth));\n }\n\n column.preview.updateDisplayLabel();\n });\n });\n columnGroup.dataStore.set(\"grid_size\", newGridSize);\n columnGroup.dataStore.unset(\"initial_grid_size\");\n columnGroup.getChildren()().forEach(function (columnLine, index) {\n var resizeUtils = columnLine.preview.getResizeUtils();\n\n if (Math.round(resizeUtils.getColumnsWidth()) < 100) {\n applyLeftoverColumnsInColumnLine(columnLine, newGridSize);\n }\n });\n }\n /**\n * Make sure the full grid size is distributed across the columns\n *\n * @param {ContentTypeCollectionInterface<Preview>} columnGroup\n * @param {number} newGridSize\n */\n\n\n function applyLeftoverColumns(columnGroup, newGridSize) {\n var resizeUtils = columnGroup.preview.getResizeUtils();\n var minColWidth = parseFloat((100 / newGridSize).toString()).toFixed(Math.round(100 / newGridSize) !== 100 / newGridSize ? 8 : 0);\n var column;\n\n for (var _iterator = _createForOfIteratorHelperLoose(columnGroup.getChildren()()), _step; !(_step = _iterator()).done;) {\n column = _step.value;\n\n if (Math.round(resizeUtils.getColumnsWidth()) < 100) {\n (0, _resize.updateColumnWidth)(column, parseFloat(resizeUtils.getColumnWidth(column).toString()) + parseFloat(minColWidth));\n } else {\n break;\n }\n }\n }\n /**\n * Make sure the full grid size is distributed across the columns\n *\n * @param {ContentTypeCollectionInterface<Preview>} columnGroup\n * @param {number} newGridSize\n */\n\n\n function applyLeftoverColumnsInColumnLine(columnLine, newGridSize) {\n var resizeUtils = columnLine.preview.getResizeUtils();\n var minColWidth = parseFloat((100 / newGridSize).toString()).toFixed(Math.round(100 / newGridSize) !== 100 / newGridSize ? 8 : 0);\n var column;\n\n for (var _iterator2 = _createForOfIteratorHelperLoose(columnLine.getChildren()()), _step2; !(_step2 = _iterator2()).done;) {\n column = _step2.value;\n\n if (Math.round(resizeUtils.getColumnsWidth()) < 100) {\n (0, _resize.updateColumnWidth)(column, parseFloat(resizeUtils.getColumnWidth(column).toString()) + parseFloat(minColWidth));\n } else {\n break;\n }\n }\n }\n\n var GridSizeError = /*#__PURE__*/function (_Error) {\n \"use strict\";\n\n _inheritsLoose(GridSizeError, _Error);\n\n function GridSizeError(m) {\n var _this;\n\n _this = _Error.call(this, m) || this;\n Object.setPrototypeOf(_assertThisInitialized(_this), GridSizeError.prototype);\n return _this;\n }\n\n return GridSizeError;\n }( /*#__PURE__*/_wrapNativeSuper(Error));\n\n return {\n getDefaultGridSize: getDefaultGridSize,\n getMaxGridSize: getMaxGridSize,\n resizeGrid: resizeGrid,\n GridSizeError: GridSizeError\n };\n});\n//# sourceMappingURL=grid-size.js.map"} }});