               + language.hours + '</figcaption></figure>' + dot2
                        : '')
                        + '<figure>$1<figcaption' + fsStyle + '>' + language.min
                        + '</figcaption></figure>' + dot2
                        + '<figure>$1<figcaption' + fsStyle + '>' + language.sec
                        + '</figcaption></figure>'
                    : (data.displayHours ? '$1' + dot2 : '') + '$1' + dot2 + '$1'
                ).replace(/\$1/g, dhtml1 + dhtml2);

                if (data.displayDays > 0) {
                    marginRight = Math.round(data.fontSize * 0.4 || defaults.gap);
                    dhtml = dhtml1;

                    for (i = data.displayDays - 1; i > 0; i -= 1) {
                        dhtml += i === 1
                            ? dhtml2.replace('">', 'margin-right:' + marginRight + 'px">')
                            : dhtml2;
                    }

                    if (data.displayDays === 1) {
                        dhtml = dhtml.replace('">', 'margin-right:' + marginRight + 'px">');
                    }

                    thtml = (data.displayCaptions
                        ? '<figure>$1'
                            + '<figcaption style="' + fsStyleVal + 'padding-right:' + marginRight + 'px">'
                            + language.days + '</figcaption></figure>'
                        : '$1')
                        .replace(/\$1/, dhtml) + thtml;
                }
                $this.html(thtml);
            } else if (method !== 'reset') {
                // exists clock
                $.extend(data, options);
            }

            $digits = $this.find('div');

            if ($digits.length < data.vals.length) {
                dif = data.vals.length - $digits.length;
                vals = data.vals;
                limits = data.limits;

                data.vals = [];
                data.limits = [];
                for (i = 0; i < $digits.length; i += 1) {
                    data.vals[i] = vals[dif + i];
                    data.limits[i] = limits[dif + i];
                }
                data.iSec = data.vals.length - 1;
                data.iHour = data.vals.length - 5;
            }
            data.sec = data.seconds;
            $this.data(data);

            if (method && methods[method]) {
                methods[method].call($this, data.seconds);
            } else if (data.start) {
                methods.start.call($this, data.seconds);
            } else {
                init.call($this, data.seconds);
            }
        });
    };


    function init(sec, force) {
        var data = this.data();
        var $digits = this.find('ul');
        var isInterval = false;
        var days, rest, hours, minutes, secs, str, i, j, val;

        if (!data.vals || $digits.length === 0) {
            return;
        }

        if (!sec) {
            sec = data.seconds;
        }

        if (data.intervalId) {
            isInterval = true;
            clearTimeout(data.intervalId);
        }


        days = Math.floor(sec / SECONDS_PER_DAY);
        rest = days * SECONDS_PER_DAY;
        hours = Math.floor((sec - rest) / SECONDS_PER_HOUR);

        rest += hours * SECONDS_PER_HOUR;

        minutes = Math.floor((sec - rest) / 60);

        rest += minutes * 60;

        secs = sec - rest;
        str = (days < 100 ? '0' + (days < 10 ? '0' : '') : '')
            + days + (hours < 10 ? '0' : '') + hours + (minutes < 10 ? '0' : '')
            + minutes + (secs < 10 ? '0' : '') + secs;


        for (i = data.vals.length - 1, j = str.length - 1; i >= 0; i -= 1, j -= 1) {
            val = parseInt(str.substr(j, 1), 10);
            data.vals[i] = val;
            $digits.eq(i).children().html(val);
        }
        if (isInterval || force) {
            data.ttStartTime = Date.now();
            data.intervalId = setTimeout(tick.bind(this), 1000);
            this.data('intervalId', data.intervalId);
        }
    }

    /**
     * Switch specified digit by digit index
     * @param {number} - digit index
     */
    function tick(digit) {
        var me = this;
        var $digits = this.find('ul');
        var data = this.data();
        var n, $ul, $li, step, tickTimeout, timeDiff;

        if (!data.vals || $digits.length === 0) {
            if (data.intervalId) {
                clearTimeout(data.intervalId);
                this.data('intervalId', null);
            }
            if (data.callback) {
                data.callback();
            }
            return;
        }
        if (typeof digit === 'undefined') {
            digit = data.iSec;
        }


        this.data('tickCount', data.tickCount + 1);

        n = data.vals[digit];
        $ul = $digits.eq(digit);
        $li = $ul.children();
        step = data.countdown ? -1 : 1;

        $li.eq(1).html(n);
        n += step;


        if (typeof data.step === 'function' && data.tickCount % data.stepCount === 0) { // simplified if-block
            this.data('tickCount', 0); // prevent number overload
            data.step();
        }

        if (digit === data.iSec) {
            tickTimeout = data.tickTimeout;
            timeDiff = Date.now() - data.ttStartTime;

            data.sec += step;

            tickTimeout += (Math.abs(data.seconds - data.sec) * tickTimeout) - timeDiff;

            data.intervalId = setTimeout(tick.bind(this), tickTimeout);
        }

        if (n < 0 || n > data.limits[digit]) {
            if (n < 0) {
                n = data.limits[digit];
                // fix for hours when day changing
                if (digit === data.iHour
                    && data.displayDays > 0
                    && data.vals[digit - 1] === 0) {
                    n = 3;
                }
            } else {
                n = 0;
            }

            if (digit > 0) {
                tick.call(this, digit - 1);
            }
        } else if (!data.countdown // fix for hours when day changing in clock mode
            && digit === data.iHour
            && data.displayDays > 0
            && data.vals[digit - 1] === 2 && data.vals[digit] === 3) {
            n = 0;
            tick.call(this, digit - 1);
        }
        $li.eq(0).html(n);

        if ($.support.transition) {
            $ul.addClass('transition');
            $ul.css({ top: 0 });

            setTimeout(function () {
                $ul.removeClass('transition');
                $li.eq(1).html(n);
                $ul.css({ top: '-' + data.height + 'px' });

                if (step > 0 || digit !== data.iSec) {
                    return;
                }

                if (data.sec === data.countdownAlertLimit) {
                    $digits.parent().addClass('timeTo-alert');
                }

                if (data.sec === 0) {
                    $digits.parent().removeClass('timeTo-alert');

                    if (data.intervalId) {
                        clearTimeout(data.intervalId);
                        me.data('intervalId', null);
                    }

                    if (typeof data.callback === 'function') {
                        data.callback();
                    }
                }
            }, 410);
        } else {
            $ul.stop().animate({ top: 0 }, 400, digit !== data.iSec ? null : function () {
                $li.eq(1).html(n);
                $ul.css({ top: '-' + data.height + 'px' });

                if (step > 0 || digit !== data.iSec) {
                    return;
                }

                if (data.sec === data.countdownAlertLimit) {
                    $digits.parent().addClass('timeTo-alert');
                } else if (data.sec === 0) {
                    $digits.parent().removeClass('timeTo-alert');

                    if (data.intervalId) {
                        clearTimeout(data.intervalId);
                        me.data('intervalId', null);
                    }

                    if (typeof data.callback === 'function') {
                        data.callback();
                    }
                }
            });
        }
        data.vals[digit] = n;
    }

    return $;
}));
Ә