', {\n 'id': newHash,\n 'class': 'collapse'\n })\n )\n );\n });\n\n $tabGroup.next().after(collapseDiv);\n $tabGroup.addClass(hidden);\n $('.tab-content.responsive').addClass(hidden);\n\n if (activeTab) {\n $(activeTab).collapse('show');\n }\n });\n\n fakewaffle.checkResize();\n fakewaffle.bindTabToCollapse();\n };\n\n fakewaffle.checkResize = function () {\n\n if ($('.cards-group.responsive').is(':visible') === true && fakewaffle.currentPosition === 'tabs') {\n fakewaffle.tabToPanel();\n fakewaffle.currentPosition = 'panel';\n } else if ($('.cards-group.responsive').is(':visible') === false && fakewaffle.currentPosition === 'panel') {\n fakewaffle.panelToTab();\n fakewaffle.currentPosition = 'tabs';\n }\n\n };\n\n fakewaffle.tabToPanel = function () {\n\n var tabGroups = $('.nav-tabs.responsive');\n\n $.each(tabGroups, function (index, tabGroup) {\n\n // Find the tab\n var tabContents = $(tabGroup).next('.tab-content').find('.tab-pane');\n\n $.each(tabContents, function (index, tabContent) {\n // Find the id to move the element to\n var destinationId = $(tabContent).attr('id').replace(/^/, '#collapse-');\n\n // Convert tab to panel and move to destination\n $(tabContent)\n .removeClass('tab-pane')\n .addClass('card-block fw-previous-tab-pane')\n .appendTo($(destinationId));\n\n });\n\n });\n\n };\n\n fakewaffle.panelToTab = function () {\n\n var panelGroups = $('.cards-group.responsive');\n\n $.each(panelGroups, function (index, panelGroup) {\n\n var destinationId = $(panelGroup).attr('id').replace('collapse-', '#');\n var destination = $(destinationId).next('.tab-content')[0];\n\n // Find the panel contents\n var panelContents = $(panelGroup).find('.card-block.fw-previous-tab-pane');\n\n // Convert to tab and move to destination\n panelContents\n .removeClass('card-block fw-previous-tab-pane')\n .addClass('tab-pane')\n .appendTo($(destination));\n\n });\n\n };\n\n fakewaffle.bindTabToCollapse = function () {\n\n var tabs = $('.nav-tabs.responsive').find('li a');\n var collapse = $('.cards-group.responsive').find('.collapse');\n\n // Toggle the panels when the associated tab is toggled\n tabs.on('shown.bs.tab', function (e) {\n\n if (fakewaffle.currentPosition === 'tabs') {\n var $current = $(e.currentTarget.hash.replace(/#/, '#collapse-'));\n $current.collapse('show');\n\n if (e.relatedTarget) {\n var $previous = $(e.relatedTarget.hash.replace(/#/, '#collapse-'));\n $previous.collapse('hide');\n }\n }\n\n });\n\n // Toggle the tab when the associated panel is toggled\n collapse.on('shown.bs.collapse', function (e) {\n\n if (fakewaffle.currentPosition === 'panel') {\n // Activate current tabs\n var current = $(e.target).context.id.replace(/collapse-/g, '#');\n $('a[href=\"' + current + '\"]').tab('show');\n\n // Update the content with active\n var panelGroup = $(e.currentTarget).closest('.cards-group.responsive');\n $(panelGroup).find('.card-block').removeClass('active');\n $(e.currentTarget).find('.card-block').addClass('active');\n }\n\n });\n };\n\n $(window).resize(function () {\n fakewaffle.checkResize();\n });\n\n return fakewaffle;\n}(window.jQuery, fakewaffle || {}) );\n\n// Spritespin.js file.\n(function (global, factory) {\n typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n typeof define === 'function' && define.amd ? define(['exports'], factory) :\n (factory((global.SpriteSpin = {})));\n}(this, (function (exports) { 'use strict';\n\n var Api = /** @class */ (function () {\n function Api(data) {\n this.data = data;\n }\n return Api;\n }());\n /**\n * Helper method that allows to extend the api with more methods.\n * Receives an object with named functions that are extensions to the API.\n */\n function extendApi(methods) {\n var api = Api.prototype;\n for (var key in methods) {\n if (methods.hasOwnProperty(key)) {\n if (api[key]) {\n throw new Error('API method is already defined: ' + key);\n }\n else {\n api[key] = methods[key];\n }\n }\n }\n return api;\n }\n\n var $$1 = window.jQuery || window.$;\n\n function getCursorPosition(event) {\n var touches = event.touches;\n var source = event;\n // jQuery Event normalization does not preserve the 'event.touches'\n // try to grab touches from the original event\n if (event.touches === undefined && event.originalEvent !== undefined) {\n touches = event.originalEvent.touches;\n }\n // get current touch or mouse position\n if (touches !== undefined && touches.length > 0) {\n source = touches[0];\n }\n return {\n x: source.clientX || 0,\n y: source.clientY || 0\n };\n }\n\n var canvas;\n var context;\n function detectionContext() {\n if (context) {\n return context;\n }\n if (!canvas) {\n canvas = document.createElement('canvas');\n }\n if (!canvas || !canvas.getContext) {\n return null;\n }\n context = canvas.getContext('2d');\n return context;\n }\n /**\n * Idea taken from https://github.com/stomita/ios-imagefile-megapixel\n * Detects whether the image has been sub sampled by the browser and does not have its original dimensions.\n * This method unfortunately does not work for images that have transparent background.\n */\n function detectSubsampling(img, width, height) {\n if (!detectionContext()) {\n return false;\n }\n // sub sampling happens on images above 1 megapixel\n if (width * height <= 1024 * 1024) {\n return false;\n }\n // set canvas to 1x1 pixel size and fill it with magenta color\n canvas.width = canvas.height = 1;\n context.fillStyle = '#FF00FF';\n context.fillRect(0, 0, 1, 1);\n // render the image with a negative offset to the left so that it would\n // fill the canvas pixel with the top right pixel of the image.\n context.drawImage(img, -width + 1, 0);\n // check color value to confirm image is covering edge pixel or not.\n // if color still magenta, the image is assumed to be sub sampled.\n try {\n var dat = context.getImageData(0, 0, 1, 1).data;\n return (dat[0] === 255) && (dat[1] === 0) && (dat[2] === 255);\n }\n catch (err) {\n // avoids cross origin exception for chrome when code runs without a server\n return false;\n }\n }\n\n /**\n *\n */\n function getOuterSize(data) {\n var width = Math.floor(data.width || data.frameWidth || data.target.innerWidth());\n var height = Math.floor(data.height || data.frameHeight || data.target.innerHeight());\n return {\n aspect: width / height,\n height: height,\n width: width\n };\n }\n function getComputedSize(data) {\n var size = getOuterSize(data);\n if (typeof window.getComputedStyle !== 'function') {\n return size;\n }\n var style = window.getComputedStyle(data.target[0]);\n if (!style.width) {\n return size;\n }\n size.width = Math.floor(Number(style.width.replace('px', '')));\n size.height = Math.floor(size.width / size.aspect);\n return size;\n }\n /**\n *\n */\n function getInnerSize(data) {\n var width = Math.floor(data.frameWidth || data.width || data.target.innerWidth());\n var height = Math.floor(data.frameHeight || data.height || data.target.innerHeight());\n return {\n aspect: width / height,\n height: height,\n width: width\n };\n }\n /**\n *\n */\n function getInnerLayout(mode, inner, outer) {\n // get mode\n var isFit = mode === 'fit';\n var isFill = mode === 'fill';\n var isMatch = mode === 'stretch';\n // resulting layout\n var layout = {\n width: '100%',\n height: '100%',\n top: 0,\n left: 0,\n bottom: 0,\n right: 0,\n position: 'absolute',\n overflow: 'hidden'\n };\n // no calculation here\n if (!mode || isMatch) {\n return layout;\n }\n // get size and aspect\n var aspectIsGreater = inner.aspect >= outer.aspect;\n // mode == original\n var width = inner.width;\n var height = inner.height;\n // keep aspect ratio but fit/fill into container\n if (isFit && aspectIsGreater || isFill && !aspectIsGreater) {\n width = outer.width;\n height = outer.width / inner.aspect;\n }\n if (isFill && aspectIsGreater || isFit && !aspectIsGreater) {\n height = outer.height;\n width = outer.height * inner.aspect;\n }\n // floor the numbers\n width = Math.floor(width);\n height = Math.floor(height);\n // position in center\n layout.width = width;\n layout.height = height;\n layout.top = Math.floor((outer.height - height) / 2);\n layout.left = Math.floor((outer.width - width) / 2);\n layout.right = layout.left;\n layout.bottom = layout.top;\n return layout;\n }\n\n var img;\n /**\n * gets the original width and height of an image element\n */\n function naturalSize(image) {\n // for browsers that support naturalWidth and naturalHeight properties\n if (image.naturalWidth) {\n return {\n height: image.naturalHeight,\n width: image.naturalWidth\n };\n }\n // browsers that do not support naturalWidth and naturalHeight properties have to fall back to the width and\n // height properties. However, the image might have a css style applied so width and height would return the\n // css size. To avoid thet create a new Image object that is free of css rules and grab width and height\n // properties\n //\n // assume that the src has already been downloaded, so no onload callback is needed.\n img = img || new Image();\n img.src = image.src;\n return {\n height: img.height,\n width: img.width\n };\n }\n\n /**\n * Measures the image frames that are used in the given data object\n */\n function measure(images, options) {\n if (images.length === 1) {\n return [measureSheet(images[0], options)];\n }\n else {\n return measureFrames(images, options);\n }\n }\n function measureSheet(image, options) {\n var result = { id: 0, sprites: [] };\n measureImage(image, options, result);\n var frames = options.frames;\n var framesX = Number(options.framesX) || frames;\n var framesY = Math.ceil(frames / framesX);\n var frameWidth = Math.floor(result.width / framesX);\n var frameHeight = Math.floor(result.height / framesY);\n var divisor = result.isSubsampled ? 2 : 1;\n for (var i = 0; i < frames; i++) {\n var x = (i % framesX) * frameWidth;\n var y = Math.floor(i / framesX) * frameHeight;\n result.sprites.push({\n id: i,\n x: x, y: y,\n width: frameWidth,\n height: frameHeight,\n sampledX: x / divisor,\n sampledY: y / divisor,\n sampledWidth: frameWidth / divisor,\n sampledHeight: frameHeight / divisor\n });\n }\n return result;\n }\n function measureFrames(images, options) {\n var result = [];\n for (var id = 0; id < images.length; id++) {\n // TODO: optimize\n // dont measure images with same size twice\n var sheet = measureSheet(images[id], { frames: 1, framesX: 1, detectSubsampling: options.detectSubsampling });\n sheet.id = id;\n result.push(sheet);\n }\n return result;\n }\n function measureImage(image, options, result) {\n var size = naturalSize(image);\n result.isSubsampled = options.detectSubsampling && detectSubsampling(image, size.width, size.height);\n result.width = size.width;\n result.height = size.height;\n result.sampledWidth = size.width / (result.isSubsampled ? 2 : 1);\n result.sampledHeight = size.height / (result.isSubsampled ? 2 : 1);\n return result;\n }\n function findSpecs(metrics, frames, frame, lane) {\n var spriteId = lane * frames + frame;\n var sheetId = 0;\n var sprite = null;\n var sheet = null;\n while (true) {\n sheet = metrics[sheetId];\n if (!sheet) {\n break;\n }\n if (spriteId >= sheet.sprites.length) {\n spriteId -= sheet.sprites.length;\n sheetId++;\n continue;\n }\n sprite = sheet.sprites[spriteId];\n break;\n }\n return { sprite: sprite, sheet: sheet };\n }\n\n function indexOf(element, arr) {\n for (var i = 0; i < arr.length; i++) {\n if (arr[i] === element) {\n return i;\n }\n }\n }\n function noop() {\n //\n }\n function preload(opts) {\n var src;\n var input = opts.source;\n src = typeof input === 'string' ? [input] : input;\n // const src: string[] = ? [opts.source] : opts.source\n var images = [];\n var targetCount = (opts.preloadCount || src.length);\n var onInitiated = opts.initiated || noop;\n var onProgress = opts.progress || noop;\n var onComplete = opts.complete || noop;\n var count = 0;\n var completed = false;\n var firstLoaded = false;\n var tick = function () {\n count += 1;\n onProgress({\n index: indexOf(this, images),\n loaded: count,\n total: src.length,\n percent: Math.round((count / src.length) * 100)\n });\n firstLoaded = firstLoaded || (this === images[0]);\n if (firstLoaded && !completed && (count >= targetCount)) {\n completed = true;\n onComplete(images);\n }\n };\n for (var _i = 0, src_1 = src; _i < src_1.length; _i++) {\n var url = src_1[_i];\n var img = new Image();\n // push result\n images.push(img);\n // bind logic, dont care about abort/errors\n img.onload = img.onabort = img.onerror = tick;\n // begin load\n img.src = url;\n }\n onInitiated(images);\n }\n\n function padNumber(num, length, pad) {\n num = String(num);\n while (num.length < length) {\n num = String(pad) + num;\n }\n return num;\n }\n /**\n * Generates an array of source strings\n * - path is a source string where the frame number of the file name is exposed as '{frame}'\n * - start indicates the first frame number\n * - end indicates the last frame number\n * - digits is the number of digits used in the file name for the frame number\n * @example\n * sourceArray('http://example.com/image_{frame}.jpg, { frame: [1, 3], digits: 2 })\n * // -> [ 'http://example.com/image_01.jpg', 'http://example.com/image_02.jpg', 'http://example.com/image_03.jpg' ]\n */\n function sourceArray(path, opts) {\n var fStart = 0, fEnd = 0, lStart = 0, lEnd = 0;\n var digits = opts.digits || 2;\n if (opts.frame) {\n fStart = opts.frame[0];\n fEnd = opts.frame[1];\n }\n if (opts.lane) {\n lStart = opts.lane[0];\n lEnd = opts.lane[1];\n }\n var i, j, temp;\n var result = [];\n for (i = lStart; i <= lEnd; i += 1) {\n for (j = fStart; j <= fEnd; j += 1) {\n temp = path.replace('{lane}', padNumber(i, digits, 0));\n temp = temp.replace('{frame}', padNumber(j, digits, 0));\n result.push(temp);\n }\n }\n return result;\n }\n\n /**\n * The namespace that is used to bind functions to DOM events and store the data object\n */\n var namespace = 'spritespin';\n /**\n * Event names that are recognized by SpriteSpin. A module can implement any of these and they will be bound\n * to the target element on which the plugin is called.\n */\n var eventNames = [\n 'mousedown',\n 'mousemove',\n 'mouseup',\n 'mouseenter',\n 'mouseover',\n 'mouseleave',\n 'dblclick',\n 'mousewheel',\n 'touchstart',\n 'touchmove',\n 'touchend',\n 'touchcancel',\n 'selectstart',\n 'gesturestart',\n 'gesturechange',\n 'gestureend'\n ];\n /**\n *\n */\n var callbackNames = [\n 'onInit',\n 'onProgress',\n 'onLoad',\n 'onFrameChanged',\n 'onFrame',\n 'onDraw',\n 'onComplete',\n 'onDestroy'\n ];\n /**\n * Names of events for that the default behavior should be prevented.\n */\n var eventsToPrevent = [\n 'dragstart'\n ];\n /**\n * Default set of SpriteSpin options. This also represents the majority of data attributes that are used during the\n * lifetime of a SpriteSpin instance. The data is stored inside the target DOM element on which the plugin is called.\n */\n var defaults = {\n source: undefined,\n width: undefined,\n height: undefined,\n frames: undefined,\n framesX: undefined,\n lanes: 1,\n sizeMode: undefined,\n renderer: 'canvas',\n lane: 0,\n frame: 0,\n frameTime: 40,\n animate: true,\n retainAnimate: false,\n reverse: false,\n loop: true,\n stopFrame: 0,\n wrap: true,\n wrapLane: false,\n sense: 1,\n senseLane: undefined,\n orientation: 'horizontal',\n detectSubsampling: true,\n preloadCount: undefined,\n responsive: undefined,\n plugins: [\n '360',\n 'drag'\n ]\n };\n\n function noop$1() {\n // noop\n }\n function wrapConsole(type) {\n return console && console[type] ? function () {\n var args = [];\n for (var _i = 0; _i < arguments.length; _i++) {\n args[_i] = arguments[_i];\n }\n return console.log.apply(console, args);\n } : noop$1;\n }\n var log = wrapConsole('log');\n var warn = wrapConsole('warn');\n var error = wrapConsole('error');\n function toArray(value) {\n return Array.isArray(value) ? value : [value];\n }\n /**\n * clamps the given value by the given min and max values\n */\n function clamp(value, min, max) {\n return (value > max ? max : (value < min ? min : value));\n }\n /**\n *\n */\n function wrap(value, min, max, size) {\n while (value > max) {\n value -= size;\n }\n while (value < min) {\n value += size;\n }\n return value;\n }\n /**\n * prevents default action on the given event\n */\n function prevent(e) {\n e.preventDefault();\n return false;\n }\n /**\n * Binds on the given target and event the given function.\n * The SpriteSpin namespace is attached to the event name\n */\n function bind(target, event, func) {\n if (func) {\n target.bind(event + '.' + namespace, function (e) {\n func.apply(target, [e, target.spritespin('data')]);\n });\n }\n }\n /**\n * Unbinds all SpriteSpin events from given target element\n */\n function unbind(target) {\n target.unbind('.' + namespace);\n }\n /**\n * Checks if given object is a function\n */\n function isFunction(fn) {\n return typeof fn === 'function';\n }\n function pixelRatio(context) {\n var devicePixelRatio = window.devicePixelRatio || 1;\n var backingStoreRatio = context.webkitBackingStorePixelRatio ||\n context.mozBackingStorePixelRatio ||\n context.msBackingStorePixelRatio ||\n context.oBackingStorePixelRatio ||\n context.backingStorePixelRatio || 1;\n return devicePixelRatio / backingStoreRatio;\n }\n\n\n\n var _Utils = Object.freeze({\n $: $$1,\n getCursorPosition: getCursorPosition,\n detectSubsampling: detectSubsampling,\n getOuterSize: getOuterSize,\n getComputedSize: getComputedSize,\n getInnerSize: getInnerSize,\n getInnerLayout: getInnerLayout,\n measure: measure,\n findSpecs: findSpecs,\n naturalSize: naturalSize,\n preload: preload,\n sourceArray: sourceArray,\n noop: noop$1,\n log: log,\n warn: warn,\n error: error,\n toArray: toArray,\n clamp: clamp,\n wrap: wrap,\n prevent: prevent,\n bind: bind,\n unbind: unbind,\n isFunction: isFunction,\n pixelRatio: pixelRatio\n });\n\n /**\n * Applies css attributes to layout the SpriteSpin containers.\n */\n function applyLayout(data) {\n // disable selection\n data.target\n .attr('unselectable', 'on')\n .css({\n width: '',\n height: '',\n '-ms-user-select': 'none',\n '-moz-user-select': 'none',\n '-khtml-user-select': 'none',\n '-webkit-user-select': 'none',\n 'user-select': 'none'\n });\n var size = data.responsive ? getComputedSize(data) : getOuterSize(data);\n var layout = getInnerLayout(data.sizeMode, getInnerSize(data), size);\n // apply layout on target\n data.target.css({\n width: size.width,\n height: size.height,\n position: 'relative',\n overflow: 'hidden'\n });\n // apply layout on stage\n data.stage.css(layout).hide();\n if (!data.canvas) {\n return;\n }\n // apply layout on canvas\n data.canvas.css(layout).hide();\n // apply pixel ratio on canvas\n data.canvasRatio = data.canvasRatio || pixelRatio(data.context);\n if (typeof layout.width === 'number' && typeof layout.height === 'number') {\n data.canvas[0].width = (layout.width * data.canvasRatio) || size.width;\n data.canvas[0].height = (layout.height * data.canvasRatio) || size.height;\n }\n else {\n data.canvas[0].width = (size.width * data.canvasRatio);\n data.canvas[0].height = (size.height * data.canvasRatio);\n }\n // width and height must be set before calling scale\n data.context.scale(data.canvasRatio, data.canvasRatio);\n }\n\n function getState(data, name) {\n data.state = data.state || {};\n data.state[name] = data.state[name] || {};\n return data.state[name];\n }\n function getPluginState(data, name) {\n var state = getState(data, 'plugin');\n state[name] = state[name] || {};\n return state[name];\n }\n function is(data, key) {\n return !!getState(data, 'flags')[key];\n }\n function flag(data, key, value) {\n getState(data, 'flags')[key] = !!value;\n }\n\n function getPlaybackState(data) {\n return getState(data, 'playback');\n }\n function updateLane(data, lane) {\n data.lane = data.wrapLane\n ? wrap(lane, 0, data.lanes - 1, data.lanes)\n : clamp(lane, 0, data.lanes - 1);\n }\n function updateAnimationFrame(data) {\n data.frame += (data.reverse ? -1 : 1);\n // wrap the frame value to fit in range [0, data.frames)\n data.frame = wrap(data.frame, 0, data.frames - 1, data.frames);\n // stop animation if loop is disabled and the stopFrame is reached\n if (!data.loop && (data.frame === data.stopFrame)) {\n stopAnimation(data);\n }\n }\n function updateInputFrame(data, frame) {\n data.frame = Number(frame);\n data.frame = data.wrap\n ? wrap(data.frame, 0, data.frames - 1, data.frames)\n : clamp(data.frame, 0, data.frames - 1);\n }\n function updateAnimation(data) {\n var state = getPlaybackState(data);\n if (state.handler) {\n updateBefore(data);\n updateAnimationFrame(data);\n updateAfter(data);\n }\n }\n function updateBefore(data) {\n var state = getPlaybackState(data);\n state.lastFrame = data.frame;\n state.lastLane = data.lane;\n }\n function updateAfter(data) {\n var state = getPlaybackState(data);\n if (state.lastFrame !== data.frame || state.lastLane !== data.lane) {\n data.target.trigger('onFrameChanged', data);\n }\n data.target.trigger('onFrame', data);\n data.target.trigger('onDraw', data);\n }\n /**\n * Updates the frame number of the SpriteSpin data. Performs an auto increment if no frame number is given.\n */\n function updateFrame(data, frame, lane) {\n updateBefore(data);\n if (frame != null) {\n updateInputFrame(data, frame);\n }\n if (lane != null) {\n updateLane(data, lane);\n }\n updateAfter(data);\n }\n /**\n * Stops the running animation on given SpriteSpin data.\n */\n function stopAnimation(data) {\n data.animate = false;\n var state = getPlaybackState(data);\n if (state.handler != null) {\n window.clearInterval(state.handler);\n state.handler = null;\n }\n }\n /**\n * Starts animation on given SpriteSpin data if animation is enabled.\n */\n function applyAnimation(data) {\n var state = getPlaybackState(data);\n if (state.handler && (!data.animate || state.frameTime !== data.frameTime)) {\n stopAnimation(data);\n }\n if (data.animate && !state.handler) {\n state.frameTime = data.frameTime;\n state.handler = window.setInterval(function () { return updateAnimation(data); }, state.frameTime);\n }\n }\n /**\n * Starts the animation playback\n */\n function startAnimation(data) {\n data.animate = true;\n applyAnimation(data);\n }\n\n var plugins = {};\n /**\n * Registers a module implementation as an available extension to SpriteSpin.\n * Use this to add custom Rendering or Updating modules that can be addressed with the 'module' option.\n */\n function registerPlugin(name, plugin) {\n if (plugins[name]) {\n error(\"Plugin name \\\"\" + name + \"\\\" is already taken\");\n return;\n }\n plugin = plugin || {};\n plugins[name] = plugin;\n return plugin;\n }\n function registerModule(name, plugin) {\n warn('\"registerModule\" is deprecated, use \"registerPlugin\" instead');\n registerPlugin(name, plugin);\n }\n function getPlugin(name) {\n return plugins[name];\n }\n /**\n * Replaces module names on given SpriteSpin data and replaces them with actual implementations.\n */\n function applyPlugins(data) {\n fixPlugins(data);\n for (var i = 0; i < data.plugins.length; i += 1) {\n var name_1 = data.plugins[i];\n if (typeof name_1 !== 'string') {\n continue;\n }\n var plugin = getPlugin(name_1);\n if (!plugin) {\n error('No plugin found with name ' + name_1);\n continue;\n }\n data.plugins[i] = plugin;\n }\n }\n function fixPlugins(data) {\n // tslint:disable no-string-literal\n if (data['mods']) {\n warn('\"mods\" option is deprecated, use \"plugins\" instead');\n data.plugins = data['mods'];\n delete data['mods'];\n }\n if (data['behavior']) {\n warn('\"behavior\" option is deprecated, use \"plugins\" instead');\n data.plugins.push(data['behavior']);\n delete data['behavior'];\n }\n if (data['module']) {\n warn('\"module\" option is deprecated, use \"plugins\" instead');\n data.plugins.push(data['module']);\n delete data['module'];\n }\n }\n\n var $$2 = $$1;\n var counter = 0;\n /**\n * Collection of all SpriteSpin instances\n */\n var instances = {};\n function pushInstance(data) {\n counter += 1;\n data.id = String(counter);\n instances[data.id] = data;\n }\n function popInstance(data) {\n delete instances[data.id];\n }\n function eachInstance(cb) {\n for (var id in instances) {\n if (instances.hasOwnProperty(id)) {\n cb(instances[id]);\n }\n }\n }\n var lazyinit = function () {\n // replace function with a noop\n // this logic must run only once\n lazyinit = function () { };\n function onEvent(eventName, e) {\n eachInstance(function (data) {\n for (var _i = 0, _a = data.plugins; _i < _a.length; _i++) {\n var module_1 = _a[_i];\n if (typeof module_1[eventName] === 'function') {\n module_1[eventName].apply(data.target, [e, data]);\n }\n }\n });\n }\n function onResize() {\n eachInstance(function (data) {\n if (data.responsive) {\n boot(data);\n }\n });\n }\n var _loop_1 = function (eventName) {\n $$2(window.document).bind(eventName + '.' + namespace, function (e) {\n onEvent('document' + eventName, e);\n });\n };\n for (var _i = 0, eventNames_1 = eventNames; _i < eventNames_1.length; _i++) {\n var eventName = eventNames_1[_i];\n _loop_1(eventName);\n }\n var resizeTimeout = null;\n $$2(window).on('resize', function () {\n window.clearTimeout(resizeTimeout);\n resizeTimeout = window.setTimeout(onResize, 100);\n });\n };\n /**\n * (re)binds all spritespin events on the target element\n */\n function applyEvents(data) {\n var target = data.target;\n // Clear all SpriteSpin events on the target element\n unbind(target);\n // disable all default browser behavior on the following events\n // mainly prevents image drag operation\n for (var _i = 0, eventsToPrevent_1 = eventsToPrevent; _i < eventsToPrevent_1.length; _i++) {\n var eName = eventsToPrevent_1[_i];\n bind(target, eName, prevent);\n }\n // Bind module functions to SpriteSpin events\n for (var _a = 0, _b = data.plugins; _a < _b.length; _a++) {\n var plugin = _b[_a];\n for (var _c = 0, eventNames_2 = eventNames; _c < eventNames_2.length; _c++) {\n var eName = eventNames_2[_c];\n bind(target, eName, plugin[eName]);\n }\n for (var _d = 0, callbackNames_1 = callbackNames; _d < callbackNames_1.length; _d++) {\n var eName = callbackNames_1[_d];\n bind(target, eName, plugin[eName]);\n }\n }\n // bind auto start function to load event.\n bind(target, 'onLoad', function (e, d) {\n applyAnimation(d);\n });\n // bind all user events that have been passed on initialization\n for (var _e = 0, callbackNames_2 = callbackNames; _e < callbackNames_2.length; _e++) {\n var eName = callbackNames_2[_e];\n bind(target, eName, data[eName]);\n }\n }\n function applyMetrics(data) {\n if (!data.images) {\n data.metrics = [];\n }\n data.metrics = measure(data.images, data);\n var spec = findSpecs(data.metrics, data.frames, 0, 0);\n if (spec.sprite) {\n // TODO: try to remove frameWidth/frameHeight\n data.frameWidth = spec.sprite.width;\n data.frameHeight = spec.sprite.height;\n }\n }\n /**\n * Runs the boot process. (re)initializes plugins, (re)initializes the layout, (re)binds events and loads source images.\n */\n function boot(data) {\n applyPlugins(data);\n applyEvents(data);\n applyLayout(data);\n data.source = toArray(data.source);\n data.loading = true;\n data.target.addClass('loading').trigger('onInit', data);\n preload({\n source: data.source,\n preloadCount: data.preloadCount,\n progress: function (progress) {\n data.progress = progress;\n data.target.trigger('onProgress', data);\n },\n complete: function (images) {\n data.images = images;\n data.loading = false;\n data.frames = data.frames || images.length;\n applyMetrics(data);\n applyLayout(data);\n data.stage.show();\n data.target\n .removeClass('loading')\n .trigger('onLoad', data)\n .trigger('onFrame', data)\n .trigger('onDraw', data)\n .trigger('onComplete', data);\n }\n });\n }\n /**\n * Creates a new SpriteSpin instance\n */\n function create(options) {\n var _this = this;\n var target = options.target;\n // SpriteSpin is not initialized\n // Create default settings object and extend with given options\n var data = $$2.extend({}, defaults, options);\n // ensure source is set\n data.source = data.source || [];\n // ensure plugins are set\n data.plugins = data.plugins || [];\n // if image tags are contained inside this DOM element\n // use these images as the source files\n target.find('img').each(function () {\n if (!Array.isArray(data.source)) {\n data.source = [];\n }\n data.source.push($$2(_this).attr('src'));\n });\n // build inner html\n //
\n target\n .empty()\n .addClass('spritespin-instance')\n .append(\"
\");\n // add the canvas element if canvas rendering is enabled and supported\n if (data.renderer === 'canvas') {\n var canvas = document.createElement('canvas');\n if (!!(canvas.getContext && canvas.getContext('2d'))) {\n data.canvas = $$2(canvas).addClass('spritespin-canvas');\n data.context = canvas.getContext('2d');\n target.append(data.canvas);\n target.addClass('with-canvas');\n }\n else {\n // fallback to image rendering mode\n data.renderer = 'image';\n }\n }\n // setup references to DOM elements\n data.target = target;\n data.stage = target.find('.spritespin-stage');\n // store the data\n target.data(namespace, data);\n pushInstance(data);\n return data;\n }\n /**\n * Creates a new SpriteSpin instance, or updates it if it is already present\n */\n function createOrUpdate(options) {\n lazyinit();\n var data = options.target.data(namespace);\n if (!data) {\n data = create(options);\n }\n else {\n $$2.extend(data, options);\n }\n boot(data);\n }\n /**\n * Stops running animation, unbinds all events and deletes the data on the target element of the given data object.\n */\n function destroy(data) {\n popInstance(data);\n stopAnimation(data);\n data.target.trigger('onDestroy', data);\n unbind(data.target);\n data.target.removeData(namespace);\n }\n\n function getInputState(data) {\n return getState(data, 'input');\n }\n /**\n * Updates the input state of the SpriteSpin data using the given mouse or touch event.\n */\n function updateInput(e, data) {\n var cursor = getCursorPosition(e);\n var state = getInputState(data);\n // cache positions from previous frame\n state.oldX = state.currentX;\n state.oldY = state.currentY;\n state.currentX = cursor.x;\n state.currentY = cursor.y;\n // Fix old position.\n if (state.oldX === undefined || state.oldY === undefined) {\n state.oldX = state.currentX;\n state.oldY = state.currentY;\n }\n // Cache the initial click/touch position and store the frame number at which the click happened.\n // Useful for different behavior implementations. This must be restored when the click/touch is released.\n if (state.startX === undefined || state.startY === undefined) {\n state.startX = state.currentX;\n state.startY = state.currentY;\n state.clickframe = data.frame;\n state.clicklane = data.lane;\n }\n // Calculate the vector from start position to current pointer position.\n state.dX = state.currentX - state.startX;\n state.dY = state.currentY - state.startY;\n // Calculate the vector from last frame position to current pointer position.\n state.ddX = state.currentX - state.oldX;\n state.ddY = state.currentY - state.oldY;\n // Normalize vectors to range [-1:+1]\n state.ndX = state.dX / data.target.innerWidth();\n state.ndY = state.dY / data.target.innerHeight();\n state.nddX = state.ddX / data.target.innerWidth();\n state.nddY = state.ddY / data.target.innerHeight();\n }\n /**\n * Resets the input state of the SpriteSpin data.\n */\n function resetInput(data) {\n var input = getInputState(data);\n input.startX = input.startY = undefined;\n input.currentX = input.currentY = undefined;\n input.oldX = input.oldY = undefined;\n input.dX = input.dY = 0;\n input.ddX = input.ddY = 0;\n input.ndX = input.ndY = 0;\n input.nddX = input.nddY = 0;\n }\n\n function extension(obj, value) {\n var _this = this;\n if (obj === 'data') {\n return this.data(namespace);\n }\n if (obj === 'api') {\n var data = this.data(namespace);\n data.api = data.api || new Api(data);\n return data.api;\n }\n if (obj === 'destroy') {\n return $$1(this).each(function () {\n var data = $$1(_this).data(namespace);\n if (data) {\n destroy(data);\n }\n });\n }\n if (arguments.length === 2 && typeof obj === 'string') {\n var tmp = {};\n tmp[obj] = value;\n obj = tmp;\n }\n if (typeof obj === 'object') {\n obj.target = obj.target || $$1(this);\n createOrUpdate(obj);\n return obj.target;\n }\n throw new Error('Invalid call to spritespin');\n }\n $$1.fn[namespace] = extension;\n\n// tslint:disable:object-literal-shorthand\n// tslint:disable:only-arrow-functions\n extendApi({\n // Gets a value indicating whether the animation is currently running.\n isPlaying: function () {\n return getPlaybackState(this.data).handler != null;\n },\n // Gets a value indicating whether the animation looping is enabled.\n isLooping: function () {\n return this.data.loop;\n },\n // Starts/Stops the animation playback\n toggleAnimation: function () {\n if (this.isPlaying()) {\n this.stopAnimation();\n }\n else {\n this.startAnimation();\n }\n },\n // Stops animation playback\n stopAnimation: function () {\n this.data.animate = false;\n stopAnimation(this.data);\n },\n // Starts animation playback\n startAnimation: function () {\n this.data.animate = true;\n applyAnimation(this.data);\n },\n // Sets a value indicating whether the animation should be looped or not.\n // This might start the animation (if the 'animate' data attribute is set to true)\n loop: function (value) {\n this.data.loop = value;\n applyAnimation(this.data);\n return this;\n },\n // Gets the current frame number\n currentFrame: function () {\n return this.data.frame;\n },\n // Updates SpriteSpin to the specified frame.\n updateFrame: function (frame) {\n updateFrame(this.data, frame);\n return this;\n },\n // Skips the given number of frames\n skipFrames: function (step) {\n var data = this.data;\n updateFrame(data, data.frame + (data.reverse ? -step : +step));\n return this;\n },\n // Updates SpriteSpin so that the next frame is shown\n nextFrame: function () {\n return this.skipFrames(1);\n },\n // Updates SpriteSpin so that the previous frame is shown\n prevFrame: function () {\n return this.skipFrames(-1);\n },\n // Starts the animations that will play until the given frame number is reached\n // options:\n // force [boolean] starts the animation, even if current frame is the target frame\n // nearest [boolean] animates to the direction with minimum distance to the target frame\n playTo: function (frame, options) {\n var data = this.data;\n options = options || {};\n if (!options.force && data.frame === frame) {\n return;\n }\n if (options.nearest) {\n // distance to the target frame\n var a = frame - data.frame;\n // distance to last frame and the to target frame\n var b = frame > data.frame ? a - data.frames : a + data.frames;\n // minimum distance\n var c = Math.abs(a) < Math.abs(b) ? a : b;\n data.reverse = c < 0;\n }\n data.animate = true;\n data.loop = false;\n data.stopFrame = frame;\n applyAnimation(data);\n return this;\n }\n });\n\n function pick(target, names) {\n for (var _i = 0, names_1 = names; _i < names_1.length; _i++) {\n var name_1 = names_1[_i];\n if (target[name_1] || name_1 in target) {\n return name_1;\n }\n }\n return names[0];\n }\n var browser = {\n requestFullscreen: pick(document.documentElement, [\n 'requestFullscreen',\n 'webkitRequestFullScreen',\n 'mozRequestFullScreen',\n 'msRequestFullscreen'\n ]),\n exitFullscreen: pick(document, [\n 'exitFullscreen',\n 'webkitExitFullscreen',\n 'webkitCancelFullScreen',\n 'mozCancelFullScreen',\n 'msExitFullscreen'\n ]),\n fullscreenElement: pick(document, [\n 'fullscreenElement',\n 'webkitFullscreenElement',\n 'webkitCurrentFullScreenElement',\n 'mozFullScreenElement',\n 'msFullscreenElement'\n ]),\n fullscreenEnabled: pick(document, [\n 'fullscreenEnabled',\n 'webkitFullscreenEnabled',\n 'mozFullScreenEnabled',\n 'msFullscreenEnabled'\n ]),\n fullscreenchange: pick(document, [\n 'onfullscreenchange',\n 'onwebkitfullscreenchange',\n 'onmozfullscreenchange',\n 'onMSFullscreenChange'\n ]).replace(/^on/, ''),\n fullscreenerror: pick(document, [\n 'onfullscreenerror',\n 'onwebkitfullscreenerror',\n 'onmozfullscreenerror',\n 'onMSFullscreenError'\n ]).replace(/^on/, '')\n };\n var changeEvent = browser.fullscreenchange + '.' + namespace + '-fullscreen';\n function unbindChangeEvent() {\n $$1(document).unbind(changeEvent);\n }\n function bindChangeEvent(callback) {\n unbindChangeEvent();\n $$1(document).bind(changeEvent, callback);\n }\n var orientationEvent = 'orientationchange.' + namespace + '-fullscreen';\n function unbindOrientationEvent() {\n $$1(window).unbind(orientationEvent);\n }\n function bindOrientationEvent(callback) {\n unbindOrientationEvent();\n $$1(window).bind(orientationEvent, callback);\n }\n function requestFullscreenNative(e) {\n e = e || document.documentElement;\n e[browser.requestFullscreen]();\n }\n function exitFullscreen() {\n return document[browser.exitFullscreen]();\n }\n function fullscreenEnabled() {\n return document[browser.fullscreenEnabled];\n }\n function fullscreenElement() {\n return document[browser.fullscreenElement];\n }\n function isFullscreen() {\n return !!fullscreenElement();\n }\n function toggleFullscreen(data, opts) {\n if (isFullscreen()) {\n this.apiRequestFullscreen(opts);\n }\n else {\n this.exitFullscreen();\n }\n }\n function requestFullscreen(data, opts) {\n opts = opts || {};\n var oWidth = data.width;\n var oHeight = data.height;\n var oSource = data.source;\n var oSize = data.sizeMode;\n var oResponsive = data.responsive;\n var enter = function () {\n data.width = window.screen.width;\n data.height = window.screen.height;\n data.source = (opts.source || oSource);\n data.sizeMode = opts.sizeMode || 'fit';\n data.responsive = false;\n boot(data);\n };\n var exit = function () {\n data.width = oWidth;\n data.height = oHeight;\n data.source = oSource;\n data.sizeMode = oSize;\n data.responsive = oResponsive;\n boot(data);\n };\n bindChangeEvent(function () {\n if (isFullscreen()) {\n enter();\n bindOrientationEvent(enter);\n }\n else {\n unbindChangeEvent();\n unbindOrientationEvent();\n exit();\n }\n });\n requestFullscreenNative(data.target[0]);\n }\n extendApi({\n fullscreenEnabled: fullscreenEnabled,\n fullscreenElement: fullscreenElement,\n exitFullscreen: exitFullscreen,\n toggleFullscreen: function (opts) {\n toggleFullscreen(this.data, opts);\n },\n requestFullscreen: function (opts) {\n requestFullscreen(this.data, opts);\n }\n });\n\n (function () {\n var NAME = 'click';\n function click(e, data) {\n if (data.loading || !data.stage.is(':visible')) {\n return;\n }\n updateInput(e, data);\n var input = getInputState(data);\n var half, pos;\n var target = data.target, offset = target.offset();\n if (data.orientation === 'horizontal') {\n half = target.innerWidth() / 2;\n pos = input.currentX - offset.left;\n }\n else {\n half = target.innerHeight() / 2;\n pos = input.currentY - offset.top;\n }\n updateFrame(data, data.frame + (pos > half ? 1 : -1));\n }\n registerPlugin(NAME, {\n name: NAME,\n mouseup: click,\n touchend: click\n });\n })();\n\n (function () {\n var NAME = 'drag';\n function getState$$1(data) {\n return getPluginState(data, NAME);\n }\n function getAxis(data) {\n if (typeof data.orientation === 'number') {\n return data.orientation * Math.PI / 180;\n }\n if (data.orientation === 'horizontal') {\n return 0;\n }\n return Math.PI / 2;\n }\n function dragStart(e, data) {\n var state = getState$$1(data);\n if (data.loading || is(data, 'dragging') || !data.stage.is(':visible')) {\n return;\n }\n // allow browser scroll only on double tap\n var now = new Date().getTime();\n if (state.startAt && (now - state.startAt > 200)) {\n e.preventDefault();\n }\n state.startAt = now;\n state.wasPlaying = !!getPlaybackState(data).handler;\n state.frame = data.frame || 0;\n state.lane = data.lane || 0;\n flag(data, 'dragging', true);\n updateInput(e, data);\n }\n function dragEnd(e, data) {\n if (is(data, 'dragging')) {\n flag(data, 'dragging', false);\n resetInput(data);\n if (data.retainAnimate && getState$$1(data).wasPlaying) {\n startAnimation(data);\n }\n }\n }\n function drag(e, data) {\n var state = getState$$1(data);\n var input = getInputState(data);\n if (!is(data, 'dragging')) {\n return;\n }\n updateInput(e, data);\n var rad = getAxis(data);\n var sn = Math.sin(rad);\n var cs = Math.cos(rad);\n var x = ((input.nddX * cs - input.nddY * sn) * data.sense) || 0;\n var y = ((input.nddX * sn + input.nddY * cs) * (data.senseLane || data.sense)) || 0;\n // accumulate\n state.frame += data.frames * x;\n state.lane += data.lanes * y;\n // update spritespin\n var oldFrame = data.frame;\n var oldLane = data.lane;\n updateFrame(data, Math.floor(state.frame), Math.floor(state.lane));\n stopAnimation(data);\n }\n function mousemove(e, data) {\n dragStart(e, data);\n drag(e, data);\n }\n registerPlugin('drag', {\n name: 'drag',\n mousedown: dragStart,\n mousemove: drag,\n mouseup: dragEnd,\n documentmousemove: drag,\n documentmouseup: dragEnd,\n touchstart: dragStart,\n touchmove: drag,\n touchend: dragEnd,\n touchcancel: dragEnd\n });\n registerPlugin('move', {\n name: 'move',\n mousemove: mousemove,\n mouseleave: dragEnd,\n touchstart: dragStart,\n touchmove: drag,\n touchend: dragEnd,\n touchcancel: dragEnd\n });\n })();\n\n (function () {\n var NAME = 'hold';\n function getState$$1(data) {\n return getPluginState(data, NAME);\n }\n function rememberOptions(data) {\n var state = getState$$1(data);\n state.frameTime = data.frameTime;\n state.animate = data.animate;\n state.reverse = data.reverse;\n }\n function restoreOptions(data) {\n var state = getState$$1(data);\n data.frameTime = state.frameTime;\n data.animate = state.animate;\n data.reverse = state.reverse;\n }\n function start(e, data) {\n if (is(data, 'loading') || is(data, 'dragging') || !data.stage.is(':visible')) {\n return;\n }\n rememberOptions(data);\n updateInput(e, data);\n flag(data, 'dragging', true);\n data.animate = true;\n applyAnimation(data);\n }\n function stop(e, data) {\n flag(data, 'dragging', false);\n resetInput(data);\n stopAnimation(data);\n restoreOptions(data);\n applyAnimation(data);\n }\n function update(e, data) {\n if (!is(data, 'dragging')) {\n return;\n }\n updateInput(e, data);\n var input = getInputState(data);\n var half, delta;\n var target = data.target, offset = target.offset();\n if (data.orientation === 'horizontal') {\n half = target.innerWidth() / 2;\n delta = (input.currentX - offset.left - half) / half;\n }\n else {\n half = (data.height / 2);\n delta = (input.currentY - offset.top - half) / half;\n }\n data.reverse = delta < 0;\n delta = delta < 0 ? -delta : delta;\n data.frameTime = 80 * (1 - delta) + 20;\n if (((data.orientation === 'horizontal') && (input.dX < input.dY)) ||\n ((data.orientation === 'vertical') && (input.dX < input.dY))) {\n e.preventDefault();\n }\n }\n function onFrame(e, data) {\n data.animate = true;\n applyAnimation(data);\n }\n registerPlugin(NAME, {\n name: NAME,\n mousedown: start,\n mousemove: update,\n mouseup: stop,\n mouseleave: stop,\n touchstart: start,\n touchmove: update,\n touchend: stop,\n touchcancel: stop,\n onFrame: onFrame\n });\n })();\n\n (function () {\n var NAME = 'swipe';\n function getState$$1(data) {\n return getPluginState(data, NAME);\n }\n function getOption(data, name, fallback) {\n return data[name] || fallback;\n }\n function init(e, data) {\n var state = getState$$1(data);\n state.fling = getOption(data, 'swipeFling', 10);\n state.snap = getOption(data, 'swipeSnap', 0.50);\n }\n function start(e, data) {\n if (!data.loading && !is(data, 'dragging')) {\n updateInput(e, data);\n flag(data, 'dragging', true);\n }\n }\n function update(e, data) {\n if (!is(data, 'dragging')) {\n return;\n }\n updateInput(e, data);\n var frame = data.frame;\n var lane = data.lane;\n updateFrame(data, frame, lane);\n }\n function end(e, data) {\n if (!is(data, 'dragging')) {\n return;\n }\n flag(data, 'dragging', false);\n var state = getState$$1(data);\n var input = getInputState(data);\n var frame = data.frame;\n var lane = data.lane;\n var snap = state.snap;\n var fling = state.fling;\n var dS, dF;\n if (data.orientation === 'horizontal') {\n dS = input.ndX;\n dF = input.ddX;\n }\n else {\n dS = input.ndY;\n dF = input.ddY;\n }\n if (dS >= snap || dF >= fling) {\n frame = data.frame - 1;\n }\n else if (dS <= -snap || dF <= -fling) {\n frame = data.frame + 1;\n }\n resetInput(data);\n updateFrame(data, frame, lane);\n stopAnimation(data);\n }\n registerPlugin(NAME, {\n name: NAME,\n onLoad: init,\n mousedown: start,\n mousemove: update,\n mouseup: end,\n mouseleave: end,\n touchstart: start,\n touchmove: update,\n touchend: end,\n touchcancel: end\n });\n })();\n\n (function () {\n var NAME = '360';\n function onLoad(e, data) {\n data.stage.find('.spritespin-frames').detach();\n if (data.renderer === 'image') {\n $(data.images).addClass('spritespin-frames').appendTo(data.stage);\n }\n }\n function onDraw(e, data) {\n var specs = findSpecs(data.metrics, data.frames, data.frame, data.lane);\n var sheet = specs.sheet;\n var sprite = specs.sprite;\n if (!sheet || !sprite) {\n return;\n }\n var src = data.source[sheet.id];\n var image = data.images[sheet.id];\n if (data.renderer === 'canvas') {\n data.canvas.show();\n var w = data.canvas[0].width / data.canvasRatio;\n var h = data.canvas[0].height / data.canvasRatio;\n data.context.clearRect(0, 0, w, h);\n data.context.drawImage(image, sprite.sampledX, sprite.sampledY, sprite.sampledWidth, sprite.sampledHeight, 0, 0, w, h);\n return;\n }\n var scaleX = sprite.sampledWidth / data.stage.innerWidth();\n var scaleY = sprite.sampledHeight / data.stage.innerHeight();\n var top = Math.floor(-sprite.sampledX * scaleY);\n var left = Math.floor(-sprite.sampledY * scaleX);\n var width = Math.floor(sheet.sampledWidth * scaleX);\n var height = Math.floor(sheet.sampledHeight * scaleY);\n if (data.renderer === 'background') {\n data.stage.css({\n 'background-image': \"url('\" + src + \"')\",\n 'background-position': left + \"px \" + top + \"px\",\n 'background-repeat': 'no-repeat',\n // set custom background size to enable responsive rendering\n '-webkit-background-size': width + \"px \" + height + \"px\",\n '-moz-background-size': width + \"px \" + height + \"px\",\n '-o-background-size': width + \"px \" + height + \"px\",\n 'background-size': width + \"px \" + height + \"px\" /* Chrome, Firefox 4+, IE 9+, Opera, Safari 5+ */\n });\n return;\n }\n $(data.images).hide();\n $(image).show().css({\n position: 'absolute',\n top: top,\n left: left,\n 'max-width': 'initial',\n width: width,\n height: height\n });\n }\n registerPlugin(NAME, {\n name: NAME,\n onLoad: onLoad,\n onDraw: onDraw\n });\n })();\n\n (function () {\n var NAME = 'blur';\n function getState$$1(data) {\n return getPluginState(data, NAME);\n }\n function getOption(data, name, fallback) {\n return data[name] || fallback;\n }\n function init(e, data) {\n var state = getState$$1(data);\n state.canvas = state.canvas || $$1(\"
\");\n state.context = state.context || state.canvas[0].getContext('2d');\n state.steps = state.steps || [];\n state.fadeTime = Math.max(getOption(data, 'blurFadeTime', 200), 1);\n state.frameTime = Math.max(getOption(data, 'blurFrameTime', data.frameTime), 16);\n state.trackTime = null;\n state.cssBlur = !!getOption(data, 'blurCss', data.frameTime);\n var inner = getInnerSize(data);\n var outer = data.responsive ? getComputedSize(data) : getOuterSize(data);\n var css = getInnerLayout(data.sizeMode, inner, outer);\n state.canvas[0].width = data.width * data.canvasRatio;\n state.canvas[0].height = data.height * data.canvasRatio;\n state.canvas.css(css).show();\n state.context.scale(data.canvasRatio, data.canvasRatio);\n data.target.append(state.canvas);\n }\n function onFrame(e, data) {\n var state = getState$$1(data);\n trackFrame(data);\n if (state.timeout == null) {\n loop(data);\n }\n }\n function trackFrame(data) {\n var state = getState$$1(data);\n var ani = getPlaybackState(data);\n // distance between frames\n var d = Math.abs(data.frame - ani.lastFrame);\n // shortest distance\n d = d >= data.frames / 2 ? data.frames - d : d;\n state.steps.unshift({\n frame: data.frame,\n lane: data.lane,\n live: 1,\n step: state.frameTime / state.fadeTime,\n d: d,\n alpha: 0\n });\n }\n var toRemove = [];\n function removeOldFrames(frames) {\n toRemove.length = 0;\n for (var i = 0; i < frames.length; i += 1) {\n if (frames[i].alpha <= 0) {\n toRemove.push(i);\n }\n }\n for (var _i = 0, toRemove_1 = toRemove; _i < toRemove_1.length; _i++) {\n var item = toRemove_1[_i];\n frames.splice(item, 1);\n }\n }\n function loop(data) {\n var state = getState$$1(data);\n state.timeout = window.setTimeout(function () { tick(data); }, state.frameTime);\n }\n function killLoop(data) {\n var state = getState$$1(data);\n window.clearTimeout(state.timeout);\n state.timeout = null;\n }\n function applyCssBlur(canvas, d) {\n var amount = Math.min(Math.max((d / 2) - 4, 0), 1.5);\n var blur = \"blur(\" + amount + \"px)\";\n canvas.css({\n '-webkit-filter': blur,\n filter: blur\n });\n }\n function drawFrame(data, state, step) {\n if (step.alpha <= 0) {\n return;\n }\n var specs = findSpecs(data.metrics, data.frames, data.frame, data.lane);\n var sheet = specs.sheet;\n var sprite = specs.sprite;\n if (!sheet || !sprite) {\n return;\n }\n var src = data.source[sheet.id];\n var image = data.images[sheet.id];\n if (image.complete === false) {\n return;\n }\n state.canvas.show();\n var w = state.canvas[0].width / data.canvasRatio;\n var h = state.canvas[0].height / data.canvasRatio;\n state.context.clearRect(0, 0, w, h);\n state.context.drawImage(image, sprite.sampledX, sprite.sampledY, sprite.sampledWidth, sprite.sampledHeight, 0, 0, w, h);\n }\n function tick(data) {\n var state = getState$$1(data);\n killLoop(data);\n if (!state.context) {\n return;\n }\n var d = 0;\n state.context.clearRect(0, 0, data.width, data.height);\n for (var _i = 0, _a = state.steps; _i < _a.length; _i++) {\n var step = _a[_i];\n step.live = Math.max(step.live - step.step, 0);\n step.alpha = Math.max(step.live - 0.25, 0);\n drawFrame(data, state, step);\n d += step.alpha + step.d;\n }\n if (state.cssBlur) {\n applyCssBlur(state.canvas, d);\n }\n removeOldFrames(state.steps);\n if (state.steps.length) {\n loop(data);\n }\n }\n registerPlugin(NAME, {\n name: NAME,\n onLoad: init,\n onFrameChanged: onFrame\n });\n })();\n\n (function () {\n var max = Math.max;\n var min = Math.min;\n var NAME = 'ease';\n function getState$$1(data) {\n return getPluginState(data, NAME);\n }\n function getOption(data, name, fallback) {\n return data[name] || fallback;\n }\n function init(e, data) {\n var state = getState$$1(data);\n state.maxSamples = max(getOption(data, 'easeMaxSamples', 5), 0);\n state.damping = max(min(getOption(data, 'easeDamping', 0.9), 0.999), 0);\n state.abortTime = max(getOption(data, 'easeAbortTime', 250), 16);\n state.updateTime = max(getOption(data, 'easeUpdateTime', data.frameTime), 16);\n state.samples = [];\n state.steps = [];\n }\n function update(e, data) {\n if (is(data, 'dragging')) {\n killLoop(data);\n sampleInput(data);\n }\n }\n function end(e, data) {\n var state = getState$$1(data);\n var samples = state.samples;\n var last;\n var lanes = 0;\n var frames = 0;\n var time = 0;\n for (var _i = 0, samples_1 = samples; _i < samples_1.length; _i++) {\n var sample = samples_1[_i];\n if (!last) {\n last = sample;\n continue;\n }\n var dt = sample.time - last.time;\n if (dt > state.abortTime) {\n lanes = frames = time = 0;\n return killLoop(data);\n }\n frames += sample.frame - last.frame;\n lanes += sample.lane - last.lane;\n time += dt;\n last = sample;\n }\n samples.length = 0;\n if (!time) {\n return;\n }\n state.lane = data.lane;\n state.lanes = 0;\n state.laneStep = lanes / time * state.updateTime;\n state.frame = data.frame;\n state.frames = 0;\n state.frameStep = frames / time * state.updateTime;\n loop(data);\n }\n function sampleInput(data) {\n var state = getState$$1(data);\n // add a new sample\n state.samples.push({\n time: new Date().getTime(),\n frame: data.frame,\n lane: data.lane\n });\n // drop old samples\n while (state.samples.length > state.maxSamples) {\n state.samples.shift();\n }\n }\n function killLoop(data) {\n var state = getState$$1(data);\n if (state.handler != null) {\n window.clearTimeout(state.handler);\n state.handler = null;\n }\n }\n function loop(data) {\n var state = getState$$1(data);\n state.handler = window.setTimeout(function () { tick(data); }, state.updateTime);\n }\n function tick(data) {\n var state = getState$$1(data);\n state.lanes += state.laneStep;\n state.frames += state.frameStep;\n state.laneStep *= state.damping;\n state.frameStep *= state.damping;\n var frame = Math.floor(state.frame + state.frames);\n var lane = Math.floor(state.lane + state.lanes);\n updateFrame(data, frame, lane);\n if (is(data, 'dragging')) {\n killLoop(data);\n }\n else if (Math.abs(state.frameStep) > 0.005 || Math.abs(state.laneStep) > 0.005) {\n loop(data);\n }\n else {\n killLoop(data);\n }\n }\n registerPlugin(NAME, {\n name: NAME,\n onLoad: init,\n mousemove: update,\n mouseup: end,\n mouseleave: end,\n touchmove: update,\n touchend: end,\n touchcancel: end\n });\n })();\n\n (function () {\n var NAME = 'gallery';\n function getState$$1(data) {\n return getPluginState(data, NAME);\n }\n function getOption(data, name, fallback) {\n return data[name] || fallback;\n }\n function load(e, data) {\n var state = getState$$1(data);\n state.images = [];\n state.offsets = [];\n state.frame = data.frame;\n state.speed = getOption(data, 'gallerySpeed', 500);\n state.opacity = getOption(data, 'galleryOpacity', 0.25);\n state.stage = getOption(data, 'galleryStage', $$1('
'));\n state.stage.empty().addClass('gallery-stage').prependTo(data.stage);\n var size = 0;\n for (var _i = 0, _a = data.images; _i < _a.length; _i++) {\n var image = _a[_i];\n var naturalSize$$1 = naturalSize(image);\n var scale = data.height / naturalSize$$1.height;\n var img = $$1(image);\n state.stage.append(img);\n state.images.push(img);\n state.offsets.push(-size + (data.width - image.width * scale) / 2);\n size += data.width;\n img.css({\n 'max-width': 'initial',\n opacity: state.opacity,\n width: data.width,\n height: data.height\n });\n }\n var innerSize = getInnerSize(data);\n var outerSize = data.responsive ? getComputedSize(data) : getOuterSize(data);\n var layout = getInnerLayout(data.sizeMode, innerSize, outerSize);\n state.stage.css(layout).css({ width: size, left: state.offsets[state.frame] });\n state.images[state.frame].animate({ opacity: 1 }, { duration: state.speed });\n }\n function draw(e, data) {\n var state = getState$$1(data);\n var input = getInputState(data);\n var isDragging = is(data, 'dragging');\n if (state.frame !== data.frame && !isDragging) {\n state.stage.stop(true, false).animate({ left: state.offsets[data.frame] }, { duration: state.speed });\n state.images[state.frame].animate({ opacity: state.opacity }, { duration: state.speed });\n state.frame = data.frame;\n state.images[state.frame].animate({ opacity: 1 }, { duration: state.speed });\n state.stage.animate({ left: state.offsets[state.frame] });\n }\n else if (isDragging || state.dX !== input.dX) {\n state.dX = input.dX;\n state.ddX = input.ddX;\n state.stage.stop(true, true).css({ left: state.offsets[state.frame] + state.dX });\n }\n }\n registerPlugin(NAME, {\n name: NAME,\n onLoad: load,\n onDraw: draw\n });\n })();\n\n (function () {\n var NAME = 'panorama';\n function getState$$1(data) {\n return getPluginState(data, NAME);\n }\n function onLoad(e, data) {\n var state = getState$$1(data);\n var sprite = data.metrics[0];\n if (!sprite) {\n return;\n }\n if (data.orientation === 'horizontal') {\n state.scale = data.target.innerHeight() / sprite.sampledHeight;\n data.frames = sprite.sampledWidth;\n }\n else {\n state.scale = data.target.innerWidth() / sprite.sampledWidth;\n data.frames = sprite.sampledHeight;\n }\n var width = Math.floor(sprite.sampledWidth * state.scale);\n var height = Math.floor(sprite.sampledHeight * state.scale);\n data.stage.css({\n 'background-image': \"url(\" + data.source[sprite.id] + \")\",\n 'background-repeat': 'repeat-both',\n // set custom background size to enable responsive rendering\n '-webkit-background-size': width + \"px \" + height + \"px\",\n '-moz-background-size': width + \"px \" + height + \"px\",\n '-o-background-size': width + \"px \" + height + \"px\",\n 'background-size': width + \"px \" + height + \"px\" /* Chrome, Firefox 4+, IE 9+, Opera, Safari 5+ */\n });\n }\n function onDraw(e, data) {\n var state = getState$$1(data);\n var px = data.orientation === 'horizontal' ? 1 : 0;\n var py = px ? 0 : 1;\n var offset = data.frame % data.frames;\n var left = Math.round(px * offset * state.scale);\n var top = Math.round(py * offset * state.scale);\n data.stage.css({ 'background-position': left + \"px \" + top + \"px\" });\n }\n registerPlugin(NAME, {\n name: NAME,\n onLoad: onLoad,\n onDraw: onDraw\n });\n })();\n\n (function () {\n var NAME = 'zoom';\n function getState$$1(data) {\n return getPluginState(data, NAME);\n }\n function getOption(data, name, fallback) {\n return data[name] || fallback;\n }\n function onInit(e, data) {\n var state = getState$$1(data);\n state.source = getOption(data, 'zoomSource', data.source);\n state.doubleClickTime = getOption(data, 'zoomDoubleClickTime', 500);\n state.stage = state.stage || $$1(\"
\");\n state.stage.css({\n width: '100%',\n height: '100%',\n top: 0,\n left: 0,\n bottom: 0,\n right: 0,\n position: 'absolute'\n })\n .appendTo(data.target)\n .hide();\n }\n function onDestroy(e, data) {\n var state = getState$$1(data);\n if (state.stage) {\n state.stage.remove();\n delete state.stage;\n }\n }\n function updateInput$$1(e, data) {\n var state = getState$$1(data);\n if (!state.stage.is(':visible')) {\n return;\n }\n e.preventDefault();\n // hack into drag/move module and disable dragging\n // prevents frame change during zoom mode\n flag(data, 'dragging', false);\n // grab touch/cursor position\n var cursor = getCursorPosition(e);\n // normalize cursor position into [0:1] range\n var x = cursor.x / data.width;\n var y = cursor.y / data.height;\n if (state.oldX == null) {\n state.oldX = x;\n state.oldY = y;\n }\n if (state.currentX == null) {\n state.currentX = x;\n state.currentY = y;\n }\n // calculate move delta since last frame and remember current position\n var dx = x - state.oldX;\n var dy = y - state.oldY;\n state.oldX = x;\n state.oldY = y;\n // invert drag direction for touch events to enable 'natural' scrolling\n if (e.type.match(/touch/)) {\n dx = -dx;\n dy = -dy;\n }\n // accumulate display coordinates\n state.currentX = clamp(state.currentX + dx, 0, 1);\n state.currentY = clamp(state.currentY + dy, 0, 1);\n updateFrame(data, data.frame, data.lane);\n }\n function onClick(e, data) {\n e.preventDefault();\n var state = getState$$1(data);\n // simulate double click\n var clickTime = new Date().getTime();\n if (!state.clickTime) {\n // on first click\n state.clickTime = clickTime;\n return;\n }\n // on second click\n var timeDelta = clickTime - state.clickTime;\n if (timeDelta > state.doubleClickTime) {\n // took too long, back to first click\n state.clickTime = clickTime;\n return;\n }\n // on valid double click\n state.clickTime = undefined;\n if (toggleZoom(data)) {\n updateInput$$1(e, data);\n }\n }\n function onMove(e, data) {\n var state = getState$$1(data);\n if (state.stage.is(':visible')) {\n updateInput$$1(e, data);\n }\n }\n function onDraw(e, data) {\n var state = getState$$1(data);\n // calculate the frame index\n var index = data.lane * data.frames + data.frame;\n // get the zoom image. Use original frames as fallback. This won't work for spritesheets\n var source = state.source[index];\n var spec = findSpecs(data.metrics, data.frames, data.frame, data.lane);\n // get display position\n var x = state.currentX;\n var y = state.currentY;\n // fallback to centered position\n if (x == null) {\n x = state.currentX = 0.5;\n y = state.currentY = 0.5;\n }\n if (source) {\n // scale up from [0:1] to [0:100] range\n x = Math.floor(x * 100);\n y = Math.floor(y * 100);\n // update background image and position\n state.stage.css({\n 'background-repeat': 'no-repeat',\n 'background-image': \"url('\" + source + \"')\",\n 'background-position': x + \"% \" + y + \"%\"\n });\n }\n else if (spec.sheet && spec.sprite) {\n var sprite = spec.sprite;\n var sheet = spec.sheet;\n var src = data.source[sheet.id];\n var left = -Math.floor(sprite.sampledX + x * (sprite.sampledWidth - data.width));\n var top_1 = -Math.floor(sprite.sampledY + y * (sprite.sampledHeight - data.height));\n var width = sheet.sampledWidth;\n var height = sheet.sampledHeight;\n state.stage.css({\n 'background-image': \"url('\" + src + \"')\",\n 'background-position': left + \"px \" + top_1 + \"px\",\n 'background-repeat': 'no-repeat',\n // set custom background size to enable responsive rendering\n '-webkit-background-size': width + \"px \" + height + \"px\",\n '-moz-background-size': width + \"px \" + height + \"px\",\n '-o-background-size': width + \"px \" + height + \"px\",\n 'background-size': width + \"px \" + height + \"px\" /* Chrome, Firefox 4+, IE 9+, Opera, Safari 5+ */\n });\n }\n }\n function toggleZoom(data) {\n var state = getState$$1(data);\n if (!state.stage) {\n throw new Error('zoom module is not initialized or is not available.');\n }\n if (state.stage.is(':visible')) {\n state.stage.fadeOut();\n data.stage.fadeIn();\n }\n else {\n state.stage.fadeIn();\n data.stage.fadeOut();\n return true;\n }\n return false;\n }\n registerPlugin(NAME, {\n name: NAME,\n mousedown: onClick,\n touchstart: onClick,\n mousemove: onMove,\n touchmove: onMove,\n onInit: onInit,\n onDestroy: onDestroy,\n onDraw: onDraw\n });\n extendApi({\n toggleZoom: function () { toggleZoom(this.data); } // tslint:disable-line\n });\n })();\n\n var Utils = _Utils;\n\n exports.Utils = Utils;\n exports.sourceArray = sourceArray;\n exports.Api = Api;\n exports.extendApi = extendApi;\n exports.instances = instances;\n exports.applyEvents = applyEvents;\n exports.boot = boot;\n exports.create = create;\n exports.createOrUpdate = createOrUpdate;\n exports.destroy = destroy;\n exports.namespace = namespace;\n exports.eventNames = eventNames;\n exports.callbackNames = callbackNames;\n exports.eventsToPrevent = eventsToPrevent;\n exports.defaults = defaults;\n exports.getInputState = getInputState;\n exports.updateInput = updateInput;\n exports.resetInput = resetInput;\n exports.applyLayout = applyLayout;\n exports.getPlaybackState = getPlaybackState;\n exports.updateFrame = updateFrame;\n exports.stopAnimation = stopAnimation;\n exports.applyAnimation = applyAnimation;\n exports.startAnimation = startAnimation;\n exports.registerPlugin = registerPlugin;\n exports.registerModule = registerModule;\n exports.getPlugin = getPlugin;\n exports.applyPlugins = applyPlugins;\n exports.getState = getState;\n exports.getPluginState = getPluginState;\n exports.is = is;\n exports.flag = flag;\n\n Object.defineProperty(exports, '__esModule', { value: true });\n\n})));\n\n\n// Main.js file.\n(function($, document, window, viewport){\n \n var visibilityDivs = {\n 'xs': $('
'),\n 'sm': $('
'),\n 'md': $('
'),\n 'lg': $('
'),\n 'xl': $('
'),\n };\n\n viewport.use('custom', visibilityDivs);\n\n var DoMenuHoverWork = function() {\n //console.log('Current breakpoint: ', viewport.current());\n var $nav = $('.navbarsdesktop'); // 2 navbars in top in desktop only\n var $oe_menu_items = $('.navbar-nav').children('li');\n var $oe_overlay = $('#overlay');\n\n if(viewport.current() == 'lg' || viewport.current() == 'xl'){\n // If mobile menu open - so close it in desktop\n if( $('.navbar-toggler').attr(\"aria-expanded\") === \"true\"){\n $('.navbar-toggler').trigger('click');\n }\n \n $oe_menu_items.bind('mouseenter',function(){\n var $this = $(this);\n $this.addClass('slided selected');\n $this.children('.sub-menu').stop(true,true).slideDown(0,function(){\n $oe_menu_items.not('.slided').children('.sub-menu').hide();\n $this.removeClass('slided');\n });\n }).bind('mouseleave',function(){\n var $this = $(this);\n $this.removeClass('selected').children('.sub-menu').css('z-index','1');\n });\n\n\n $nav.bind('mouseenter',function(){\n var $this = $(this);\n $('.overlay').css({'height' : '100%','zIndex':'49'});\n $oe_overlay.stop(true,true).fadeTo(500, 0.91); \n $('.navbar-front').addClass('main-nav--is-hovered').fadeIn(300);\n $('#topNav').addClass('top-nav--white');\n if (!$('.navbar-front').hasClass('is-sticky') && $('.navbar-front').length ) {\n $('.navbar-front .navbar-brand img').attr('src', '/wp-content/themes/nordiclight/assets/dist/images/logo_dark.svg');\n $('.herrmanslogo img').attr('src', '/wp-content/themes/nordiclight/assets/dist/images/herrmans_logo_black.png'); \n $('.nordiclogo img').attr('src', '/wp-content/themes/nordiclight/assets/dist/images/nordic_logo_black.png'); \n }\n\n }).bind('mouseleave',function(){\n var $this = $(this);\n $('.overlay').css({'height' : '','zIndex':'1'});\n $oe_overlay.stop(true,true).fadeTo(500, 0);\n $oe_menu_items.children('.sub-menu').hide();\n \n $('.navbar-front').removeClass('main-nav--is-hovered').fadeIn(300);\n $('#topNav').removeClass('top-nav--white').fadeIn(300);\n if (!$('.navbar-front').hasClass('is-sticky') && $('.navbar-front').length ) {\n $('.navbar-front .navbar-brand img').attr('src', '/wp-content/themes/nordiclight/assets/dist/images/logo_light.svg');\n $('.herrmanslogo img').attr('src', '/wp-content/themes/nordiclight/assets/dist/images/herrmans_logo_white.png'); \n $('.nordiclogo img').attr('src', '/wp-content/themes/nordiclight/assets/dist/images/nordic_logo_white.png'); \n }\n }) \n\n } // End 'lg' || 'xl'\n else{\n // unbind mouseenter mouseleave.\n $oe_menu_items.unbind('mouseenter');\n $oe_menu_items.unbind('mouseleave');\n $nav.unbind('mouseenter');\n $nav.unbind('mouseleave');\n\n // use click on mobile\n $oe_menu_items.bind('click',function(){\n var $this = $(this);\n $this.addClass('slided selected');\n $this.children('.sub-menu').stop(true,true).slideToggle(0,function(){\n $oe_menu_items.not('.slided').children('.sub-menu').hide();\n $this.removeClass('slided');\n });\n }); \n }\n }\n\n // on resize\n $(window).resize(\n viewport.changed(function() {\n DoMenuHoverWork();\n })\n ).resize();\n\n\n\n // -------------------------------------------------------------------------------------------\n // For Compare lights simulator in Startpage. check GetImageFunction function in functions.php\n // -------------------------------------------------------------------------------------------\n $('.simulator-btn').click(function (e) {\n e.preventDefault();\n var button_id = $(this).attr('id');\n $.ajax({\n type: \"GET\",\n url: \"/wp-admin/admin-ajax.php\",\n dataType: 'html',\n data: ({action: 'GetImageFunction', 'id': button_id}),\n success: function (data) {\n $('#simulator').css('background', \"#111 url(\" + data + \") top\");\n },\n error: function (data) {\n console.log(\"Error!\");\n return false;\n }\n });\n });\n\n\n // Filter Custom changes.\n // Use var (getLangCode) to change the text for differnet languages.\n if ($('li.sf-field-reset').length) { \n $('ul').find('li.sf-field-reset').insertAfter('#custom_html-3 strong');\n $('ul').find('li.sf-field-submit').insertAfter('#custom_html-3 strong');\n }\n\n if ($('li.sf-field-post-meta-source_filter').length) { \n $( \"li.sf-field-post-meta-source_filter\" ).before( '
Source' );\n $( \"li.sf-field-post-meta-source_filter\" ).after( '
' ); \n } \n\n if ($('li.sf-field-post-meta-type_filter').length) { \n $( \"li.sf-field-post-meta-type_filter\" ).before( '
Type' );\n $( \"li.sf-field-post-meta-type_filter\" ).after( '
' ); \n } \n\n if ($('li.sf-field-post-meta-nominal_voltage_filter').length) { \n $( \"li.sf-field-post-meta-nominal_voltage_filter\" ).before( '
Nominal voltage DC' );\n $( \"li.sf-field-post-meta-nominal_voltage_filter\" ).after( '
' ); \n } \n\n if ($('li.sf-field-post-meta-light_pattern_filter').length) { \n $( \"li.sf-field-post-meta-light_pattern_filter\" ).before( '
Light Pattern' );\n $( \"li.sf-field-post-meta-light_pattern_filter\" ).after( '
' ); \n } \n\n if ($('li.sf-field-post-meta-colour_temperature_filter').length) { \n $( \"li.sf-field-post-meta-colour_temperature_filter\" ).before( '
Colour Temperature' );\n $( \"li.sf-field-post-meta-colour_temperature_filter\" ).after( '
' ); \n } \n\n if ($('li.sf-field-post-meta-dampening_filter').length) { \n $( \"li.sf-field-post-meta-dampening_filter\" ).before( '
Dampening' );\n $( \"li.sf-field-post-meta-dampening_filter\" ).after( '
' ); \n } \n\n if ($('li.sf-field-post-meta-power_filter').length) { \n $( \"li.sf-field-post-meta-power_filter\" ).before( '
Power consumption' );\n $( \"li.sf-field-post-meta-power_filter\" ).after( '
' ); \n } \n\n if ($('li.sf-field-post-meta-field_of_work_filter').length) { \n $( \"li.sf-field-post-meta-field_of_work_filter\" ).before( '
Field of work' );\n $( \"li.sf-field-post-meta-field_of_work_filter\" ).after( '
' ); \n } \n\n if ($('li.sf-field-post-meta-lumens_filter').length) { \n $( \"li.sf-field-post-meta-lumens_filter\" ).before( '
Lumens' );\n $( \"li.sf-field-post-meta-lumens_filter\" ).after( '
' ); \n }\n\n if ($('li.sf-field-post-meta-shape_filter').length) { \n $( \"li.sf-field-post-meta-shape_filter\" ).before( '
Shape' );\n $( \"li.sf-field-post-meta-shape_filter\" ).after( '
' ); \n } \n\n if ($('li.sf-field-post-meta-vehicle_filter').length) { \n $( \"li.sf-field-post-meta-vehicle_filter\" ).before( '
Vehicle' );\n $( \"li.sf-field-post-meta-vehicle_filter\" ).after( '
' ); \n } \n\n $(\"[data-acco]\").click(function (e) {\n e.preventDefault();\n var classdata = $(this).attr('data-acco');\n //$(this).siblings().slideToggle();\n $('li.' + classdata).slideToggle();\n $(this).toggleClass('plus');\n $(this).toggleClass('minus');\n });\n\n if ($('.spritespin').length) { \n var item_name = $('.products').attr('data-productid');\n $('.spritespin').spritespin({\n source: SpriteSpin.sourceArray('/wp-content/uploads/360/'+item_name+'/{frame}.png', { frame: [0,39], digits: 3 }),\n width: 388,\n height: 388,\n responsive: true,\n sense: -1,\n loop: false,\n animte: true,\n frameTime: 40,\n frame: 35,\n stopFrame: 34,\n onComplete: showIcon(),\n });\n \n function showIcon(){\n $('#icon-360').show();\n }\n\n }\n\n $(\".readmore-link\").click(function (e) {\n e.preventDefault();\n var data_text = $(\".more-text\").is(':visible') ? $(this).attr('data-more') : $(this).attr('data-less');\n $(this).text(data_text);\n $('.more-text').toggleClass('show');\n });\n\n\n // -------------------------------------------------------------------------------------------\n // For Category dropdown (left sidebar) in mobile\n // ------------------------------------------------------------------------------------------- \n $(function() {\n var mytext1 = { \"en\": 'Series', \"sv\": 'Serier', \"fr\": 'Série', \"es\": 'Serie', \"fi\": 'Sarja', \"de\": 'Serie', \"ru\": 'Серии', \"pt-pt\": 'Series', \"ja\": 'シリーズ', \"zh-hans\": '系列'}; \n var mytext2 = { \"en\": 'Model', \"sv\": 'Modell', \"fr\": 'Modèle', \"es\": 'Modelo', \"fi\": 'Malli', \"de\": 'Modell', \"ru\": 'Модель', \"pt-pt\": 'Modelo', \"ja\": 'モデル', \"zh-hans\": '模型'}; \n var mytext3 = { \"en\": 'Product', \"sv\": 'Produkt', \"fr\": 'Produit', \"es\": 'Producto', \"fi\": 'Tuote', \"de\": 'Produkt', \"ru\": 'Продукт', \"pt-pt\": 'Produtos', \"ja\": '製品', \"zh-hans\": '产品'}; \n\n $('.selectpicker').selectric({\n disableOnMobile: false,\n nativeOnMobile: false,\n });\n $('.maincategories-slist').selectric({\n labelBuilder: function(currItem) {\n return (currItem.value.length ? '
' : '') + '
' + mytext1[getLangCode]+':' + '' + '
' + currItem.text + '';\n }\n }); \n $('.subcategories-slist').selectric({\n labelBuilder: function(currItem) {\n return (currItem.value.length ? '
' : '') + '
'+ mytext2[getLangCode]+':' + '' + '
' + currItem.text + '';\n }\n }); \n $('.products-slist').selectric({\n labelBuilder: function(currItem) {\n return (currItem.value.length ? '
' : '') + '
'+ mytext3[getLangCode]+':' +'' + '
' + currItem.text + '';\n }\n });\n\n });\n\n\n // -------------------------------------------------------------------------------------------\n // Javascript to enable link to tab\n // ------------------------------------------------------------------------------------------- \n // Change hash if click on tabs\n $(\".nav-tabs a\").click(function () {\n window.location.hash = $(this).attr('href');\n });\n\n // Scroll if there is hash.\n $(window).load(function() {\n // check for hash when page has loaded\n if (getHash() != null) {\n checkForScrolling();\n }\n });\n // check for hash when hash has changed\n window.onhashchange = function() {\n checkForScrolling();\n };\n // return hash if so or null if hash is empty\n function getHash() {\n var hash = window.location.hash;\n if (hash != '') {\n return hash;\n } else {\n return null;\n }\n }\n // this function handles your scrolling\n function checkForScrolling() {\n var hash = document.location.hash;\n var prefix = \"tab_\";\n if (hash) {\n $('.nav-tabs a[href=\"'+hash.replace(prefix,\"\")+'\"]').tab('show');\n $('html,body').animate({scrollTop: $('a[href=\"'+hash+'\"]').offset().top - 120},'slow'); \n } \n // first get your element by attribute selector\n var elem = $('a[href=\"'+getHash()+'\"]');\n // cheeck if element exists \n if (elem.length > 0 ) {\n $('html, body').stop().animate({\n scrollTop: elem.offset().top - 120\n }, 1000);\n }\n }\n\n // -------------------------------------------------------------------------------------------\n // For Responsive Tabs in Product page. Features & Options, Technical Data, Light Patterns, Drawings\n // -------------------------------------------------------------------------------------------\n (function($) {\n fakewaffle.responsiveTabs(['sm','md']);\n })(jQuery);\n\n\n // -------------------------------------------------------------------------------------------\n // Polyfill for CSS position: sticky node_modules/stickyfilljs\n // -------------------------------------------------------------------------------------------\n var elements = $('#mainNav');\n Stickyfill.add(elements);\n // $('#mainNav');.Stickyfill();\n // -------------------------------------------------------------------------------------------\n // When Scroll\n // -------------------------------------------------------------------------------------------\n $(window).scroll(function () {\n if ($(this).scrollTop() > 10) {\n $('#mainNav').addClass(\"is-sticky\");\n if ($(window).width() > 992) {\n $('.navbar-front .navbar-brand img').attr('src', '/wp-content/themes/nordiclight/assets/dist/images/logo_dark.svg')\n }\n }\n else {\n $('#mainNav').removeClass(\"is-sticky\");\n $('.navbar-front .navbar-brand img').attr('src', '/wp-content/themes/nordiclight/assets/dist/images/logo_light.svg');\n }\n });\n\n\n\n // -------------------------------------------------------------------------------------------\n // FAQ Button in menu\n // ------------------------------------------------------------------------------------------- \n $(\".sub-menu a:contains('FAQ')\").addClass('faq-link');\n\n \n\n\n // -------------------------------------------------------------------------------------------\n // Video hero\n // ------------------------------------------------------------------------------------------- \n \n // var media;\n // $('#frontpage-video').mediaelementplayer({\n\n // // features: [],\n // // Hide controls when playing and mouse is not over the video\n // // alwaysShowControls: false,\n // loop: true,\n // controls: false,\n // success: function(mediaElement, originalNode, instance) {\n // // do things\n // mediaElement.play();\n // media = mediaElement;\n // },\n // error: function () {\n // alert('Error setting media!');\n // }\n // });\n // $('.video-overlay .btn-labeled').click(function () {\n // // var player = new MediaElementPlayer('video');\n // //\n // // player.enterFullScreen();\n // $('.mejs-container').css('height', '100%');\n // $('.intro-text').hide();\n // $('.mejs-container').addClass('playing-video');\n // $('.mejs-controls').addClass('mejs-controls-show');\n // $('.mejs-controls').removeClass('mejs-controls-hide');\n // $('body, html').css('overflow', 'hidden');\n // $('.close-video').show();\n // });\n\n // $('.close-video').click(function () {\n // $('.mejs-container').css('height', '720px');\n // $('.intro-text').show();\n // $('.mejs-container').removeClass('playing-video');\n // $('.mejs-controls').addClass('mejs-controls-hide');\n // $('.mejs-controls').removeClass('mejs-controls-show');\n // $('body, html').css('overflow', 'auto');\n // $('.close-video').hide();\n // media.play();\n // })\n\n // Get min height of hero\n\n // var imageSrc = $('.hero').style.backgroundImage;\n if ($('body').hasClass('techtalk-template')) {\n var imageSrc = $('.hero').css('background-image').replace(/url\\((['\"])?(.*?)\\1\\)/gi, '$2').split(',')[0];\n\n var image = new Image();\n image.src = imageSrc;\n var height = image.height;\n\n $('.hero').css('min-height', height);\n }\n\n // Front fields of work get height\n //var fields_of_work_height = $('.front-field-of-work .bg-warning').outerHeight(true);\n //$('.front-field-of-work .bg-warning').css('top', '-' + fields_of_work_height / 2 + 'px');\n\n if($(window).width() < 992) {\n $('.footer-widgets .footer_head').click(function () {\n $(this).closest('.col-md-2').find('ul').slideToggle();\n })\n }\n\n $(window).on('resize load', function (e) {\n if ($(window).width() < 992) {\n\n $('.footer-widgets .footer_head').click(function () {\n $(this).closewst('.col-md-2').find('ul').slideToggle();\n })\n }\n\n });\n\n // Reset Popup video if its closed.\n $('.close').click(function () {\n $('#modal-video').hide();\n $('#modal-video iframe').attr(\"src\", jQuery(\"#modal-video iframe\").attr(\"src\"));\n });\n\n\n \n $('#play-video').on('click', function(ev) {\n $('.caption').fadeOut(100);\n $('.front-video').fadeOut(\"100\", function () {\n $('.back-video').fadeIn(100);\n });\n $('.close').fadeIn(100);\n $(\"#video-iframe\")[0].src += \"&autoplay=1\";\n ev.preventDefault();\n });\n \n $('.close').on('click', function(ev) {\n $(this).fadeOut(100);\n $('.back-video').fadeOut(\"100\", function () {\n $('.front-video').fadeIn(100);\n }); \n $('.caption').fadeIn(100);\n ev.preventDefault();\n });\n\n var sitemap_length = $('.wsp-container > *').length;\n\n var first_half = $('.wsp-container > *').slice(0, sitemap_length/2);\n var second_half = $('.wsp-container > *').slice(sitemap_length/2);\n first_half.wrapAll('
');\n second_half.wrapAll('
');\n\n // var sitemap_prod = $('.wsp-productss-list li').length;\n // var prod_first_half = $('.wsp-container > *').slice(0, sitemap_length/2);\n // var prod_second_half = $('.wsp-container > *').slice(sitemap_length/2);\n // prod_first_half.wrapAll('
');\n // prod_second_half.wrapAll('
');\n\n$(document).ready(function(){\n $(\".page-template-esg .content-image-title-esg\").click(function(){\n $(\".post-esg\").removeClass(\"active\");\n $(this).parent(\".post-esg\").addClass(\"active\",1000);\n });\n\n $(\".close-content-text-esg\").click(function(event){\n event.stopPropagation();\n $(\".post-esg\").removeClass(\"active\");\n });\n });\n\n\n\n})(jQuery, document, window, ResponsiveBootstrapToolkit);\n\n\n"],"file":"main.js"}