{"version":3,"sources":["jquery.syotimer.js","syotimer.lang.js","jquery.syotimer.min.js"],"names":["$","DAY","HOUR","MINUTE","SECOND","DAY_IN_SEC","HOUR_IN_SEC","MINUTE_IN_SEC","LAYOUT_TYPES","d","h","m","s","UNIT_LINKED_LIST","list","next","current","currentIndex","this","indexOf","length","prev","DEFAULTS","year","month","day","hour","minute","second","timeZone","ignoreTransferTime","layout","periodic","periodInterval","periodUnit","doubleNumbers","effectType","lang","headTitle","footTitle","afterDeadline","timerBlock","bodyBlock","html","ITEMS_HAS_OPTIONS","SyoTimer","init","settings","options","extend","itemTypes","staticMethod","getItemTypesByLayout","_itemsHas","i","each","elementBox","data","_render","apply","_perSecondHandler","timerItem","getTimerItem","headBlock","class","footBlock","itemBlocks","item","clone","addClass","append","timerBlocks","css","currentDate","Date","deadLineDate","differenceInMilliSec","getDifferenceWithTimezone","secondsToDeadLine","getSecondsToDeadLine","_refreshUnitsDom","_applyEffectSwitch","unitList","unitsToDeadLine","getUnitsToDeadLine","unit","unitValue","itemBlock","format2","syotimerLang","getNumeral","element","setTimeout","unitItemBlock","nextUnit","animate","opacity","timerCellValue","text","timerCellUnit","timerCell","push","differenceInSeconds","Math","floor","additionalInUnit","differenceInUnit","periodUnitInSeconds","getPeriodUnit","fullTimeUnitsBetween","ceil","abs","unitInMilliSec","given_period_unit","amendment","differenceByLocalTimezone","getTime","amendmentOnTimezone","amendmentOnTransferTime","timezoneOffset","parseFloat","localTimezoneOffset","getTimezoneOffset","currentTimezoneOffset","deadLineTimezoneOffset","number","isUse","methods","setOption","name","value","hasOwnProperty","fn","syotimer","otherArgs","Array","prototype","slice","call","arguments","error","rus","handler","eng","por","spa","heb","universal","rusNumeral","index","cases","handlerName","jQuery"],"mappings":"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","file":"jquery.syotimer.min.js","sourcesContent":[" var DAY = \"day\",\n HOUR = \"hour\",\n MINUTE = \"minute\",\n SECOND = \"second\";\n var DAY_IN_SEC = 24 * 60 * 60;\n var HOUR_IN_SEC = 60 * 60;\n var MINUTE_IN_SEC = 60;\n var LAYOUT_TYPES = {\n d: DAY,\n h: HOUR,\n m: MINUTE,\n s: SECOND\n };\n var UNIT_LINKED_LIST = {\n list: [SECOND, MINUTE, HOUR, DAY],\n next: function(current) {\n var currentIndex = this.list.indexOf(current);\n return (currentIndex < this.list.length ) ? this.list[currentIndex + 1] : false;\n },\n prev: function(current) {\n var currentIndex = this.list.indexOf(current);\n return (currentIndex > 0 ) ? this.list[currentIndex - 1] : false;\n }\n };\n\n var DEFAULTS = {\n year: 2014,\n month: 7,\n day: 31,\n hour: 0,\n minute: 0,\n second: 0,\n timeZone: 'local', // setting the time zone of deadline.\n // If 'local' then the time zone is ignored and\n // the deadline is determined by local time of the user.\n // Otherwise, specifies the offset from the UTC\n ignoreTransferTime: false, // If `true` then transfer to summer/winter time will not be considered.\n layout: 'dhms', // sets an order of layout of units of the timer:\n // days (d) of hours ('h'), minute ('m'), second ('s').\n periodic: false, //`true` - the timer is periodic.\n // If the date until which counts the timer is reached,\n // the next value date which will count down\n // the timer is incremented by the value `periodInterval`\n periodInterval: 7, // the period of the timer in `periodUnit`\n // (if `periodic` is set to `true`)\n periodUnit: 'd', // the unit of measurement period timer\n\n doubleNumbers: true, // `true` - show hours, minutes and seconds with leading zeros\n // (2 hours 5 minutes 4 seconds = 02:05:04)\n effectType: 'none', // The effect of changing the value of seconds\n lang: 'eng', // localization of a countdown signatures (days, hours, minutes, seconds)\n headTitle: '', // text above the countdown (may be as html string)\n footTitle: '', // text under the countdown (may be as html string)\n afterDeadline: function(timerBlock){\n timerBlock.bodyBlock.html('

The countdown is finished!

');\n }\n };\n\n var ITEMS_HAS_OPTIONS = {\n second: false,\n minute: false,\n hour: false,\n day: false\n };\n\n var SyoTimer = {\n /**\n * Init syotimer on DOM\n * @param settings\n * @returns {Array|Object|*}\n */\n init: function(settings) {\n var options = $.extend({}, DEFAULTS, settings || {});\n options.itemTypes = staticMethod.getItemTypesByLayout(options.layout);\n options._itemsHas = $.extend({}, ITEMS_HAS_OPTIONS);\n for (var i = 0; i < options.itemTypes.length; i++) {\n options._itemsHas[options.itemTypes[i]] = true;\n }\n return this.each(function() {\n var elementBox = $(this);\n elementBox.data('syotimer-options', options);\n SyoTimer._render.apply(this, []);\n SyoTimer._perSecondHandler.apply(this, []);\n });\n },\n\n /**\n * Rendering base elements of countdown\n * @private\n */\n _render: function() {\n var elementBox = $(this),\n options = elementBox.data('syotimer-options');\n\n var timerItem = staticMethod.getTimerItem(),\n headBlock = $('
', {\"class\": 'syotimer__head'})\n .html(options.headTitle),\n bodyBlock = $('
', {\"class\": 'syotimer__body'}),\n footBlock = $('
', {\"class\": 'syotimer__footer'})\n .html(options.footTitle),\n itemBlocks = {};\n\n for (var i = 0; i < options.itemTypes.length; i++) {\n var item = timerItem.clone();\n item.addClass('syotimer-cell_type_' + options.itemTypes[i]);\n bodyBlock.append(item);\n itemBlocks[options.itemTypes[i]] = item;\n }\n var timerBlocks = {\n headBlock: headBlock,\n bodyBlock: bodyBlock,\n footBlock: footBlock\n };\n elementBox.data('syotimer-blocks', timerBlocks)\n .data('syotimer-items', itemBlocks)\n .addClass('syotimer')\n .append(headBlock)\n .append(bodyBlock)\n .append(footBlock);\n },\n\n /**\n * Handler called per seconds while countdown is not over\n * @private\n */\n _perSecondHandler: function() {\n var elementBox = $(this),\n options = elementBox.data('syotimer-options');\n $('.syotimer-cell > .syotimer-cell__value', elementBox).css( 'opacity', 1 );\n var currentDate = new Date(),\n deadLineDate = new Date(\n options.year,\n options.month - 1,\n options.day,\n options.hour,\n options.minute,\n options.second\n ),\n differenceInMilliSec = staticMethod.getDifferenceWithTimezone(currentDate, deadLineDate, options),\n secondsToDeadLine = staticMethod.getSecondsToDeadLine(differenceInMilliSec, options);\n if ( secondsToDeadLine >= 0 ) {\n SyoTimer._refreshUnitsDom.apply(this, [secondsToDeadLine]);\n SyoTimer._applyEffectSwitch.apply(this, [options.effectType]);\n } else {\n elementBox = $.extend(elementBox, elementBox.data('syotimer-blocks'));\n options.afterDeadline( elementBox );\n }\n },\n\n /**\n * Refresh unit DOM of countdown\n * @param secondsToDeadLine\n * @private\n */\n _refreshUnitsDom: function(secondsToDeadLine) {\n var elementBox = $(this),\n options = elementBox.data('syotimer-options'),\n itemBlocks = elementBox.data('syotimer-items'),\n unitList = options.itemTypes,\n unitsToDeadLine = staticMethod.getUnitsToDeadLine( secondsToDeadLine );\n\n if ( !options._itemsHas.day ) {\n unitsToDeadLine.hour += unitsToDeadLine.day * 24;\n }\n if ( !options._itemsHas.hour ) {\n unitsToDeadLine.minute += unitsToDeadLine.hour * 60;\n }\n if ( !options._itemsHas.minute ) {\n unitsToDeadLine.second += unitsToDeadLine.minute * 60;\n }\n for(var i = 0; i < unitList.length; i++) {\n var unit = unitList[i],\n unitValue = unitsToDeadLine[unit],\n itemBlock = itemBlocks[unit];\n itemBlock.data('syotimer-unit-value', unitValue);\n $('.syotimer-cell__value', itemBlock).html(staticMethod.format2(\n unitValue,\n (unit !== DAY) ? options.doubleNumbers : false\n ));\n $('.syotimer-cell__unit', itemBlock).html($.syotimerLang.getNumeral(\n unitValue,\n options.lang,\n unit\n ));\n }\n },\n\n /**\n * Applying effect of changing numbers\n * @param effectType\n * @param unit\n * @private\n */\n _applyEffectSwitch: function(effectType, unit) {\n unit = unit || SECOND;\n var element = this,\n elementBox = $(element);\n if ( effectType === 'none' ) {\n setTimeout(function () {\n SyoTimer._perSecondHandler.apply(element, []);\n }, 1000);\n } else if ( effectType === 'opacity' ) {\n var itemBlocks = elementBox.data('syotimer-items'),\n unitItemBlock = itemBlocks[unit];\n if (unitItemBlock) {\n var nextUnit = UNIT_LINKED_LIST.next(unit),\n unitValue = unitItemBlock.data('syotimer-unit-value');\n $('.syotimer-cell__value', unitItemBlock).animate(\n {opacity: 0.1},\n 1000,\n 'linear',\n function () {\n SyoTimer._perSecondHandler.apply(element, []);\n }\n );\n if (nextUnit && unitValue === 0) {\n SyoTimer._applyEffectSwitch.apply(element, [effectType, nextUnit]);\n }\n }\n }\n }\n };\n\n var staticMethod = {\n /**\n * Return once cell DOM of countdown: day, hour, minute, second\n * @returns {object}\n */\n getTimerItem: function() {\n var timerCellValue = $('
', {\n \"class\": 'syotimer-cell__value',\n \"text\": '0'\n }),\n timerCellUnit = $('
', {\"class\": 'syotimer-cell__unit'}),\n timerCell = $('
', {\"class\": 'syotimer-cell'});\n timerCell.append(timerCellValue)\n .append(timerCellUnit);\n return timerCell;\n },\n\n getItemTypesByLayout: function(layout) {\n var itemTypes = [];\n for (var i = 0; i < layout.length; i++) {\n itemTypes.push(LAYOUT_TYPES[layout[i]]);\n }\n return itemTypes;\n },\n\n /**\n * Getting count of seconds to deadline\n * @param differenceInMilliSec\n * @param options\n * @returns {*}\n */\n getSecondsToDeadLine: function(differenceInMilliSec, options) {\n var secondsToDeadLine,\n differenceInSeconds = differenceInMilliSec / 1000;\n differenceInSeconds = Math.floor( differenceInSeconds );\n if ( options.periodic ) {\n var additionalInUnit,\n differenceInUnit,\n periodUnitInSeconds = staticMethod.getPeriodUnit(options.periodUnit),\n fullTimeUnitsBetween = differenceInMilliSec / (periodUnitInSeconds * 1000);\n fullTimeUnitsBetween = Math.ceil( fullTimeUnitsBetween );\n fullTimeUnitsBetween = Math.abs( fullTimeUnitsBetween );\n if ( differenceInSeconds >= 0 ) {\n differenceInUnit = fullTimeUnitsBetween % options.periodInterval;\n differenceInUnit = ( differenceInUnit === 0 )? options.periodInterval : differenceInUnit;\n differenceInUnit -= 1;\n } else {\n differenceInUnit = options.periodInterval - fullTimeUnitsBetween % options.periodInterval;\n }\n additionalInUnit = differenceInSeconds % periodUnitInSeconds;\n\n // fix когда дедлайн раньше текущей даты,\n // возникает баг с неправильным расчетом интервала при different пропорциональной periodUnit\n if ( ( additionalInUnit === 0 ) && ( differenceInSeconds < 0 ) ) {\n differenceInUnit--;\n }\n secondsToDeadLine = Math.abs( differenceInUnit * periodUnitInSeconds + additionalInUnit );\n } else {\n secondsToDeadLine = differenceInSeconds;\n }\n return secondsToDeadLine;\n },\n\n /**\n * Getting count of units to deadline\n * @param secondsToDeadLine\n * @returns {{}}\n */\n getUnitsToDeadLine: function(secondsToDeadLine) {\n var unit = DAY,\n unitsToDeadLine = {};\n do {\n var unitInMilliSec = staticMethod.getPeriodUnit(unit);\n unitsToDeadLine[unit] = Math.floor(secondsToDeadLine / unitInMilliSec);\n secondsToDeadLine = secondsToDeadLine % unitInMilliSec;\n } while (unit = UNIT_LINKED_LIST.prev(unit));\n return unitsToDeadLine;\n },\n\n /**\n * Determine a unit of period in milliseconds\n * @param given_period_unit\n * @returns {number}\n */\n getPeriodUnit: function(given_period_unit) {\n switch (given_period_unit) {\n case 'd':\n case DAY:\n return DAY_IN_SEC;\n case 'h':\n case HOUR:\n return HOUR_IN_SEC;\n case 'm':\n case MINUTE:\n return MINUTE_IN_SEC;\n case 's':\n case SECOND:\n return 1;\n }\n },\n\n getDifferenceWithTimezone: function(currentDate, deadLineDate, options) {\n var differenceByLocalTimezone = deadLineDate.getTime() - currentDate.getTime(),\n amendmentOnTimezone = 0,\n amendmentOnTransferTime = 0,\n amendment;\n if ( options.timeZone !== 'local' ) {\n var timezoneOffset = parseFloat(options.timeZone) * staticMethod.getPeriodUnit(HOUR),\n localTimezoneOffset = - currentDate.getTimezoneOffset() * staticMethod.getPeriodUnit(MINUTE);\n amendmentOnTimezone = (timezoneOffset - localTimezoneOffset) * 1000;\n }\n if ( options.ignoreTransferTime ) {\n var currentTimezoneOffset = -currentDate.getTimezoneOffset() * staticMethod.getPeriodUnit(MINUTE),\n deadLineTimezoneOffset = -deadLineDate.getTimezoneOffset() * staticMethod.getPeriodUnit(MINUTE);\n amendmentOnTransferTime = (currentTimezoneOffset - deadLineTimezoneOffset) * 1000;\n }\n amendment = amendmentOnTimezone + amendmentOnTransferTime;\n return differenceByLocalTimezone - amendment;\n },\n\n /**\n * Formation of numbers with leading zeros\n * @param number\n * @param isUse\n * @returns {string}\n */\n format2: function(number, isUse) {\n isUse = (isUse !== false);\n return ( ( number <= 9 ) && isUse ) ? ( \"0\" + number ) : ( \"\" + number );\n }\n };\n\n var methods = {\n setOption: function(name, value) {\n var elementBox = $(this),\n options = elementBox.data('syotimer-options');\n if ( options.hasOwnProperty( name ) ) {\n options[name] = value;\n elementBox.data('syotimer-options', options);\n }\n }\n };\n\n $.fn.syotimer = function(options){\n if ( typeof options === 'string' && ( options === \"setOption\" ) ) {\n var otherArgs = Array.prototype.slice.call(arguments, 1);\n return this.each(function() {\n methods[options].apply( this, otherArgs );\n });\n } else if (options === null || typeof options === 'object'){\n return SyoTimer.init.apply(this, [options]);\n } else {\n $.error('SyoTimer. Error in call methods: methods is not exist');\n }\n };\n"," $.syotimerLang = {\n rus: {\n second: ['секунда', 'секунды', 'секунд'],\n minute: ['минута', 'минуты', 'минут'],\n hour: ['час', 'часа', 'часов'],\n day: ['день', 'дня', 'дней'],\n handler: 'rusNumeral'\n },\n eng: {\n second: ['second', 'seconds'],\n minute: ['minute', 'minutes'],\n hour: ['hour', 'hours'],\n day: ['day', 'days']\n },\n por: {\n second: ['segundo', 'segundos'],\n minute: ['minuto', 'minutos'],\n hour: ['hora', 'horas'],\n day: ['dia', 'dias']\n },\n spa: {\n second: ['segundo', 'segundos'],\n minute: ['minuto', 'minutos'],\n hour: ['hora', 'horas'],\n day: ['día', 'días']\n },\n heb: {\n second: ['שניה', 'שניות'],\n minute: ['דקה', 'דקות'],\n hour: ['שעה', 'שעות'],\n day: ['יום', 'ימים']\n },\n\n /**\n * Universal function for get correct inducement of nouns after a numeral (`number`)\n * @param number\n * @returns {number}\n */\n universal: function(number) {\n return ( number === 1 ) ? 0 : 1;\n },\n\n /**\n * Get correct inducement of nouns after a numeral for Russian language (rus)\n * @param number\n * @returns {number}\n */\n rusNumeral: function(number) {\n var cases = [2, 0, 1, 1, 1, 2],\n index;\n if ( number % 100 > 4 && number % 100 < 20 ) {\n index = 2;\n } else {\n index = cases[(number % 10 < 5) ? number % 10 : 5];\n }\n return index;\n },\n\n /**\n * Getting the correct declension of words after numerals\n * @param number\n * @param lang\n * @param unit\n * @returns {string}\n */\n getNumeral: function(number, lang, unit) {\n var handlerName = $.syotimerLang[lang].handler || 'universal',\n index = this[handlerName](number);\n return $.syotimerLang[lang][unit][index];\n }\n };\n","(function($){\n var DAY = \"day\",\n HOUR = \"hour\",\n MINUTE = \"minute\",\n SECOND = \"second\";\n var DAY_IN_SEC = 24 * 60 * 60;\n var HOUR_IN_SEC = 60 * 60;\n var MINUTE_IN_SEC = 60;\n var LAYOUT_TYPES = {\n d: DAY,\n h: HOUR,\n m: MINUTE,\n s: SECOND\n };\n var UNIT_LINKED_LIST = {\n list: [SECOND, MINUTE, HOUR, DAY],\n next: function(current) {\n var currentIndex = this.list.indexOf(current);\n return (currentIndex < this.list.length ) ? this.list[currentIndex + 1] : false;\n },\n prev: function(current) {\n var currentIndex = this.list.indexOf(current);\n return (currentIndex > 0 ) ? this.list[currentIndex - 1] : false;\n }\n };\n\n var DEFAULTS = {\n year: 2014,\n month: 7,\n day: 31,\n hour: 0,\n minute: 0,\n second: 0,\n timeZone: 'local', // setting the time zone of deadline.\n // If 'local' then the time zone is ignored and\n // the deadline is determined by local time of the user.\n // Otherwise, specifies the offset from the UTC\n ignoreTransferTime: false, // If `true` then transfer to summer/winter time will not be considered.\n layout: 'dhms', // sets an order of layout of units of the timer:\n // days (d) of hours ('h'), minute ('m'), second ('s').\n periodic: false, //`true` - the timer is periodic.\n // If the date until which counts the timer is reached,\n // the next value date which will count down\n // the timer is incremented by the value `periodInterval`\n periodInterval: 7, // the period of the timer in `periodUnit`\n // (if `periodic` is set to `true`)\n periodUnit: 'd', // the unit of measurement period timer\n\n doubleNumbers: true, // `true` - show hours, minutes and seconds with leading zeros\n // (2 hours 5 minutes 4 seconds = 02:05:04)\n effectType: 'none', // The effect of changing the value of seconds\n lang: 'eng', // localization of a countdown signatures (days, hours, minutes, seconds)\n headTitle: '', // text above the countdown (may be as html string)\n footTitle: '', // text under the countdown (may be as html string)\n afterDeadline: function(timerBlock){\n timerBlock.bodyBlock.html('

The countdown is finished!

');\n }\n };\n\n var ITEMS_HAS_OPTIONS = {\n second: false,\n minute: false,\n hour: false,\n day: false\n };\n\n var SyoTimer = {\n /**\n * Init syotimer on DOM\n * @param settings\n * @returns {Array|Object|*}\n */\n init: function(settings) {\n var options = $.extend({}, DEFAULTS, settings || {});\n options.itemTypes = staticMethod.getItemTypesByLayout(options.layout);\n options._itemsHas = $.extend({}, ITEMS_HAS_OPTIONS);\n for (var i = 0; i < options.itemTypes.length; i++) {\n options._itemsHas[options.itemTypes[i]] = true;\n }\n return this.each(function() {\n var elementBox = $(this);\n elementBox.data('syotimer-options', options);\n SyoTimer._render.apply(this, []);\n SyoTimer._perSecondHandler.apply(this, []);\n });\n },\n\n /**\n * Rendering base elements of countdown\n * @private\n */\n _render: function() {\n var elementBox = $(this),\n options = elementBox.data('syotimer-options');\n\n var timerItem = staticMethod.getTimerItem(),\n headBlock = $('
', {\"class\": 'syotimer__head'})\n .html(options.headTitle),\n bodyBlock = $('
', {\"class\": 'syotimer__body'}),\n footBlock = $('
', {\"class\": 'syotimer__footer'})\n .html(options.footTitle),\n itemBlocks = {};\n\n for (var i = 0; i < options.itemTypes.length; i++) {\n var item = timerItem.clone();\n item.addClass('syotimer-cell_type_' + options.itemTypes[i]);\n bodyBlock.append(item);\n itemBlocks[options.itemTypes[i]] = item;\n }\n var timerBlocks = {\n headBlock: headBlock,\n bodyBlock: bodyBlock,\n footBlock: footBlock\n };\n elementBox.data('syotimer-blocks', timerBlocks)\n .data('syotimer-items', itemBlocks)\n .addClass('syotimer')\n .append(headBlock)\n .append(bodyBlock)\n .append(footBlock);\n },\n\n /**\n * Handler called per seconds while countdown is not over\n * @private\n */\n _perSecondHandler: function() {\n var elementBox = $(this),\n options = elementBox.data('syotimer-options');\n $('.syotimer-cell > .syotimer-cell__value', elementBox).css( 'opacity', 1 );\n var currentDate = new Date(),\n deadLineDate = new Date(\n options.year,\n options.month - 1,\n options.day,\n options.hour,\n options.minute,\n options.second\n ),\n differenceInMilliSec = staticMethod.getDifferenceWithTimezone(currentDate, deadLineDate, options),\n secondsToDeadLine = staticMethod.getSecondsToDeadLine(differenceInMilliSec, options);\n if ( secondsToDeadLine >= 0 ) {\n SyoTimer._refreshUnitsDom.apply(this, [secondsToDeadLine]);\n SyoTimer._applyEffectSwitch.apply(this, [options.effectType]);\n } else {\n elementBox = $.extend(elementBox, elementBox.data('syotimer-blocks'));\n options.afterDeadline( elementBox );\n }\n },\n\n /**\n * Refresh unit DOM of countdown\n * @param secondsToDeadLine\n * @private\n */\n _refreshUnitsDom: function(secondsToDeadLine) {\n var elementBox = $(this),\n options = elementBox.data('syotimer-options'),\n itemBlocks = elementBox.data('syotimer-items'),\n unitList = options.itemTypes,\n unitsToDeadLine = staticMethod.getUnitsToDeadLine( secondsToDeadLine );\n\n if ( !options._itemsHas.day ) {\n unitsToDeadLine.hour += unitsToDeadLine.day * 24;\n }\n if ( !options._itemsHas.hour ) {\n unitsToDeadLine.minute += unitsToDeadLine.hour * 60;\n }\n if ( !options._itemsHas.minute ) {\n unitsToDeadLine.second += unitsToDeadLine.minute * 60;\n }\n for(var i = 0; i < unitList.length; i++) {\n var unit = unitList[i],\n unitValue = unitsToDeadLine[unit],\n itemBlock = itemBlocks[unit];\n itemBlock.data('syotimer-unit-value', unitValue);\n $('.syotimer-cell__value', itemBlock).html(staticMethod.format2(\n unitValue,\n (unit !== DAY) ? options.doubleNumbers : false\n ));\n $('.syotimer-cell__unit', itemBlock).html($.syotimerLang.getNumeral(\n unitValue,\n options.lang,\n unit\n ));\n }\n },\n\n /**\n * Applying effect of changing numbers\n * @param effectType\n * @param unit\n * @private\n */\n _applyEffectSwitch: function(effectType, unit) {\n unit = unit || SECOND;\n var element = this,\n elementBox = $(element);\n if ( effectType === 'none' ) {\n setTimeout(function () {\n SyoTimer._perSecondHandler.apply(element, []);\n }, 1000);\n } else if ( effectType === 'opacity' ) {\n var itemBlocks = elementBox.data('syotimer-items'),\n unitItemBlock = itemBlocks[unit];\n if (unitItemBlock) {\n var nextUnit = UNIT_LINKED_LIST.next(unit),\n unitValue = unitItemBlock.data('syotimer-unit-value');\n $('.syotimer-cell__value', unitItemBlock).animate(\n {opacity: 0.1},\n 1000,\n 'linear',\n function () {\n SyoTimer._perSecondHandler.apply(element, []);\n }\n );\n if (nextUnit && unitValue === 0) {\n SyoTimer._applyEffectSwitch.apply(element, [effectType, nextUnit]);\n }\n }\n }\n }\n };\n\n var staticMethod = {\n /**\n * Return once cell DOM of countdown: day, hour, minute, second\n * @returns {object}\n */\n getTimerItem: function() {\n var timerCellValue = $('
', {\n \"class\": 'syotimer-cell__value',\n \"text\": '0'\n }),\n timerCellUnit = $('
', {\"class\": 'syotimer-cell__unit'}),\n timerCell = $('
', {\"class\": 'syotimer-cell'});\n timerCell.append(timerCellValue)\n .append(timerCellUnit);\n return timerCell;\n },\n\n getItemTypesByLayout: function(layout) {\n var itemTypes = [];\n for (var i = 0; i < layout.length; i++) {\n itemTypes.push(LAYOUT_TYPES[layout[i]]);\n }\n return itemTypes;\n },\n\n /**\n * Getting count of seconds to deadline\n * @param differenceInMilliSec\n * @param options\n * @returns {*}\n */\n getSecondsToDeadLine: function(differenceInMilliSec, options) {\n var secondsToDeadLine,\n differenceInSeconds = differenceInMilliSec / 1000;\n differenceInSeconds = Math.floor( differenceInSeconds );\n if ( options.periodic ) {\n var additionalInUnit,\n differenceInUnit,\n periodUnitInSeconds = staticMethod.getPeriodUnit(options.periodUnit),\n fullTimeUnitsBetween = differenceInMilliSec / (periodUnitInSeconds * 1000);\n fullTimeUnitsBetween = Math.ceil( fullTimeUnitsBetween );\n fullTimeUnitsBetween = Math.abs( fullTimeUnitsBetween );\n if ( differenceInSeconds >= 0 ) {\n differenceInUnit = fullTimeUnitsBetween % options.periodInterval;\n differenceInUnit = ( differenceInUnit === 0 )? options.periodInterval : differenceInUnit;\n differenceInUnit -= 1;\n } else {\n differenceInUnit = options.periodInterval - fullTimeUnitsBetween % options.periodInterval;\n }\n additionalInUnit = differenceInSeconds % periodUnitInSeconds;\n\n // fix когда дедлайн раньше текущей даты,\n // возникает баг с неправильным расчетом интервала при different пропорциональной periodUnit\n if ( ( additionalInUnit === 0 ) && ( differenceInSeconds < 0 ) ) {\n differenceInUnit--;\n }\n secondsToDeadLine = Math.abs( differenceInUnit * periodUnitInSeconds + additionalInUnit );\n } else {\n secondsToDeadLine = differenceInSeconds;\n }\n return secondsToDeadLine;\n },\n\n /**\n * Getting count of units to deadline\n * @param secondsToDeadLine\n * @returns {{}}\n */\n getUnitsToDeadLine: function(secondsToDeadLine) {\n var unit = DAY,\n unitsToDeadLine = {};\n do {\n var unitInMilliSec = staticMethod.getPeriodUnit(unit);\n unitsToDeadLine[unit] = Math.floor(secondsToDeadLine / unitInMilliSec);\n secondsToDeadLine = secondsToDeadLine % unitInMilliSec;\n } while (unit = UNIT_LINKED_LIST.prev(unit));\n return unitsToDeadLine;\n },\n\n /**\n * Determine a unit of period in milliseconds\n * @param given_period_unit\n * @returns {number}\n */\n getPeriodUnit: function(given_period_unit) {\n switch (given_period_unit) {\n case 'd':\n case DAY:\n return DAY_IN_SEC;\n case 'h':\n case HOUR:\n return HOUR_IN_SEC;\n case 'm':\n case MINUTE:\n return MINUTE_IN_SEC;\n case 's':\n case SECOND:\n return 1;\n }\n },\n\n getDifferenceWithTimezone: function(currentDate, deadLineDate, options) {\n var differenceByLocalTimezone = deadLineDate.getTime() - currentDate.getTime(),\n amendmentOnTimezone = 0,\n amendmentOnTransferTime = 0,\n amendment;\n if ( options.timeZone !== 'local' ) {\n var timezoneOffset = parseFloat(options.timeZone) * staticMethod.getPeriodUnit(HOUR),\n localTimezoneOffset = - currentDate.getTimezoneOffset() * staticMethod.getPeriodUnit(MINUTE);\n amendmentOnTimezone = (timezoneOffset - localTimezoneOffset) * 1000;\n }\n if ( options.ignoreTransferTime ) {\n var currentTimezoneOffset = -currentDate.getTimezoneOffset() * staticMethod.getPeriodUnit(MINUTE),\n deadLineTimezoneOffset = -deadLineDate.getTimezoneOffset() * staticMethod.getPeriodUnit(MINUTE);\n amendmentOnTransferTime = (currentTimezoneOffset - deadLineTimezoneOffset) * 1000;\n }\n amendment = amendmentOnTimezone + amendmentOnTransferTime;\n return differenceByLocalTimezone - amendment;\n },\n\n /**\n * Formation of numbers with leading zeros\n * @param number\n * @param isUse\n * @returns {string}\n */\n format2: function(number, isUse) {\n isUse = (isUse !== false);\n return ( ( number <= 9 ) && isUse ) ? ( \"0\" + number ) : ( \"\" + number );\n }\n };\n\n var methods = {\n setOption: function(name, value) {\n var elementBox = $(this),\n options = elementBox.data('syotimer-options');\n if ( options.hasOwnProperty( name ) ) {\n options[name] = value;\n elementBox.data('syotimer-options', options);\n }\n }\n };\n\n $.fn.syotimer = function(options){\n if ( typeof options === 'string' && ( options === \"setOption\" ) ) {\n var otherArgs = Array.prototype.slice.call(arguments, 1);\n return this.each(function() {\n methods[options].apply( this, otherArgs );\n });\n } else if (options === null || typeof options === 'object'){\n return SyoTimer.init.apply(this, [options]);\n } else {\n $.error('SyoTimer. Error in call methods: methods is not exist');\n }\n };\n\n $.syotimerLang = {\n rus: {\n second: ['секунда', 'секунды', 'секунд'],\n minute: ['минута', 'минуты', 'минут'],\n hour: ['час', 'часа', 'часов'],\n day: ['день', 'дня', 'дней'],\n handler: 'rusNumeral'\n },\n eng: {\n second: ['second', 'seconds'],\n minute: ['minute', 'minutes'],\n hour: ['hour', 'hours'],\n day: ['day', 'days']\n },\n por: {\n second: ['segundo', 'segundos'],\n minute: ['minuto', 'minutos'],\n hour: ['hora', 'horas'],\n day: ['dia', 'dias']\n },\n spa: {\n second: ['segundo', 'segundos'],\n minute: ['minuto', 'minutos'],\n hour: ['hora', 'horas'],\n day: ['día', 'días']\n },\n heb: {\n second: ['שניה', 'שניות'],\n minute: ['דקה', 'דקות'],\n hour: ['שעה', 'שעות'],\n day: ['יום', 'ימים']\n },\n\n /**\n * Universal function for get correct inducement of nouns after a numeral (`number`)\n * @param number\n * @returns {number}\n */\n universal: function(number) {\n return ( number === 1 ) ? 0 : 1;\n },\n\n /**\n * Get correct inducement of nouns after a numeral for Russian language (rus)\n * @param number\n * @returns {number}\n */\n rusNumeral: function(number) {\n var cases = [2, 0, 1, 1, 1, 2],\n index;\n if ( number % 100 > 4 && number % 100 < 20 ) {\n index = 2;\n } else {\n index = cases[(number % 10 < 5) ? number % 10 : 5];\n }\n return index;\n },\n\n /**\n * Getting the correct declension of words after numerals\n * @param number\n * @param lang\n * @param unit\n * @returns {string}\n */\n getNumeral: function(number, lang, unit) {\n var handlerName = $.syotimerLang[lang].handler || 'universal',\n index = this[handlerName](number);\n return $.syotimerLang[lang][unit][index];\n }\n };\n})(jQuery);\n"]}