PageSourceSearch

https://mdnkids.com/jssor/jssor.utils.js

js mdnkids.com collected 2026-09-24 09:20:44 UTC 83,627 bytes, 2,522 lines download raw bytes

1/// <reference path="Jssor.Core.js" />
2
3/*
4* Jssor.Utils 17.0
5* http://www.jssor.com/
6* 
7* TERMS OF USE - Jssor.Utils
8* 
9* Copyright 2014 Jssor
10*
11* Permission is hereby granted, free of charge, to any person obtaining
12* a copy of this software and associated documentation files (the
13* "Software"), to deal in the Software without restriction, including
14* without limitation the rights to use, copy, modify, merge, publish,
15* distribute, sublicense, and/or sell copies of the Software, and to
16* permit persons to whom the Software is furnished to do so, subject to
17* the following conditions:
18* 
19* The above copyright notice and this permission notice shall be
20* included in all copies or substantial portions of the Software.
21* 
22* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29*/
30
31
32//$JssorPoint$
33var $JssorPoint$;
34
35(function () {
36
37    $JssorPoint$ = function (x, y) {
38
39        // Properties
40
41        this.x = typeof (x) == "number" ? x : 0;
42        this.y = typeof (y) == "number" ? y : 0;
43
44    };
45
46    // Methods
47
48    var SDPointPrototype = $JssorPoint$.prototype;
49
50    SDPointPrototype.$Plus = function (point) {
51        return new $JssorPoint$(this.x + point.x, this.y + point.y);
52    };
53
54    SDPointPrototype.$Minus = function (point) {
55        return new $JssorPoint$(this.x - point.x, this.y - point.y);
56    };
57
58    SDPointPrototype.$Times = function (factor) {
59        return new $JssorPoint$(this.x * factor, this.y * factor);
60    };
61
62    SDPointPrototype.$Divide = function (factor) {
63        return new $JssorPoint$(this.x / factor, this.y / factor);
64    };
65
66    SDPointPrototype.$Negate = function () {
67        return new $JssorPoint$(-this.x, -this.y);
68    };
69
70    SDPointPrototype.$DistanceTo = function (point) {
71        return Math.sqrt(Math.pow(this.x - point.x, 2) +
72                        Math.pow(this.y - point.y, 2));
73    };
74
75    SDPointPrototype.$Apply = function (func) {
76        return new $JssorPoint$(func(this.x), func(this.y));
77    };
78
79    SDPointPrototype.$Equals = function (point) {
80        return (point instanceof $JssorPoint$) &&
81                (this.x === point.x) && (this.y === point.y);
82    };
83
84    SDPointPrototype.$ToString = function () {
85        return "(" + this.x + "," + this.y + ")";
86    };
87
88})();
89
90//$JssorEasing$
91var $JssorEasing$ = window.$JssorEasing$ = {
92    $EaseLinear: function (t) {
93        return t;
94    },
95    $EaseGoBack: function (t) {
96        return 1 - Math.abs((t *= 2) - 1);
97    },
98    $EaseSwing: function (t) {
99        return -Math.cos(t * Math.PI) / 2 + .5;
100    },
101    $EaseInQuad: function (t) {
102        return t * t;
103    },
104    $EaseOutQuad: function (t) {
105        return -t * (t - 2);
106    },
107    $EaseInOutQuad: function (t) {
108        return (t *= 2) < 1 ? 1 / 2 * t * t : -1 / 2 * (--t * (t - 2) - 1);
109    },
110    $EaseInCubic: function (t) {
111        return t * t * t;
112    },
113    $EaseOutCubic: function (t) {
114        return (t -= 1) * t * t + 1;
115    },
116    $EaseInOutCubic: function (t) {
117        return (t *= 2) < 1 ? 1 / 2 * t * t * t : 1 / 2 * ((t -= 2) * t * t + 2);
118    },
119    $EaseInQuart: function (t) {
120        return t * t * t * t;
121    },
122    $EaseOutQuart: function (t) {
123        return -((t -= 1) * t * t * t - 1);
124    },
125    $EaseInOutQuart: function (t) {
126        return (t *= 2) < 1 ? 1 / 2 * t * t * t * t : -1 / 2 * ((t -= 2) * t * t * t - 2);
127    },
128    $EaseInQuint: function (t) {
129        return t * t * t * t * t;
130    },
131    $EaseOutQuint: function (t) {
132        return (t -= 1) * t * t * t * t + 1;
133    },
134    $EaseInOutQuint: function (t) {
135        return (t *= 2) < 1 ? 1 / 2 * t * t * t * t * t : 1 / 2 * ((t -= 2) * t * t * t * t + 2);
136    },
137    $EaseInSine: function (t) {
138        return 1 - Math.cos(t * Math.PI / 2);
139    },
140    $EaseOutSine: function (t) {
141        return Math.sin(t * Math.PI / 2);
142    },
143    $EaseInOutSine: function (t) {
144        return -1 / 2 * (Math.cos(Math.PI * t) - 1);
145    },
146    $EaseInExpo: function (t) {
147        return t == 0 ? 0 : Math.pow(2, 10 * (t - 1));
148    },
149    $EaseOutExpo: function (t) {
150        return t == 1 ? 1 : -Math.pow(2, -10 * t) + 1;
151    },
152    $EaseInOutExpo: function (t) {
153        return t == 0 || t == 1 ? t : (t *= 2) < 1 ? 1 / 2 * Math.pow(2, 10 * (t - 1)) : 1 / 2 * (-Math.pow(2, -10 * --t) + 2);
154    },
155    $EaseInCirc: function (t) {
156        return -(Math.sqrt(1 - t * t) - 1);
157    },
158    $EaseOutCirc: function (t) {
159        return Math.sqrt(1 - (t -= 1) * t);
160    },
161    $EaseInOutCirc: function (t) {
162        return (t *= 2) < 1 ? -1 / 2 * (Math.sqrt(1 - t * t) - 1) : 1 / 2 * (Math.sqrt(1 - (t -= 2) * t) + 1);
163    },
164    $EaseInElastic: function (t) {
165        if (!t || t == 1)
166            return t;
167        var p = .3, s = .075;
168        return -(Math.pow(2, 10 * (t -= 1)) * Math.sin((t - s) * 2 * Math.PI / p));
169    },
170    $EaseOutElastic: function (t) {
171        if (!t || t == 1)
172            return t;
173        var p = .3, s = .075;
174        return Math.pow(2, -10 * t) * Math.sin((t - s) * 2 * Math.PI / p) + 1;
175    },
176    $EaseInOutElastic: function (t) {
177        if (!t || t == 1)
178            return t;
179        var p = .45, s = .1125;
180        return (t *= 2) < 1 ? -.5 * Math.pow(2, 10 * (t -= 1)) * Math.sin((t - s) * 2 * Math.PI / p) : Math.pow(2, -10 * (t -= 1)) * Math.sin((t - s) * 2 * Math.PI / p) * .5 + 1;
181    },
182    $EaseInBack: function (t) {
183        var s = 1.70158;
184        return t * t * ((s + 1) * t - s);
185    },
186    $EaseOutBack: function (t) {
187        var s = 1.70158;
188        return (t -= 1) * t * ((s + 1) * t + s) + 1;
189    },
190    $EaseInOutBack: function (t) {
191        var s = 1.70158;
192        return (t *= 2) < 1 ? 1 / 2 * t * t * (((s *= 1.525) + 1) * t - s) : 1 / 2 * ((t -= 2) * t * (((s *= 1.525) + 1) * t + s) + 2);
193    },
194    $EaseInBounce: function (t) {
195        return 1 - $JssorEasing$.$EaseOutBounce(1 - t)
196    },
197    $EaseOutBounce: function (t) {
198        return t < 1 / 2.75 ? 7.5625 * t * t : t < 2 / 2.75 ? 7.5625 * (t -= 1.5 / 2.75) * t + .75 : t < 2.5 / 2.75 ? 7.5625 * (t -= 2.25 / 2.75) * t + .9375 : 7.5625 * (t -= 2.625 / 2.75) * t + .984375;
199    },
200    $EaseInOutBounce: function (t) {
201        return t < 1 / 2 ? $JssorEasing$.$EaseInBounce(t * 2) * .5 : $JssorEasing$.$EaseOutBounce(t * 2 - 1) * .5 + .5;
202    },
203    $EaseInWave: function (t) {
204        return 1 - Math.cos(t * Math.PI * 2)
205    },
206    $EaseOutWave: function (t) {
207        return Math.sin(t * Math.PI * 2);
208    },
209    $EaseOutJump: function (t) {
210        return 1 - (((t *= 2) < 1) ? (t = 1 - t) * t * t : (t -= 1) * t * t);
211    },
212    $EaseInJump: function (t) {
213        return ((t *= 2) < 1) ? t * t * t : (t = 2 - t) * t * t;
214    }
215};
216
217var $JssorDirection$ = window.$JssorDirection$ = {
218    $TO_LEFT: 0x0001,
219    $TO_RIGHT: 0x0002,
220    $TO_TOP: 0x0004,
221    $TO_BOTTOM: 0x0008,
222    $HORIZONTAL: 0x0003,
223    $VERTICAL: 0x000C,
224    $LEFTRIGHT: 0x0003,
225    $TOPBOTOM: 0x000C,
226    $TOPLEFT: 0x0005,
227    $TOPRIGHT: 0x0006,
228    $BOTTOMLEFT: 0x0009,
229    $BOTTOMRIGHT: 0x000A,
230    $AROUND: 0x000F,
231
232    $GetDirectionHorizontal: function (direction) {
233        return direction & 0x0003;
234    },
235    $GetDirectionVertical: function (direction) {
236        return direction & 0x000C;
237    },
238    $ChessHorizontal: function (direction) {
239        return (~direction & 0x0003) + (direction & 0x000C);
240    },
241    $ChessVertical: function (direction) {
242        return (~direction & 0x000C) + (direction & 0x0003);
243    },
244    $IsToLeft: function (direction) {
245        return (direction & 0x0003) == 0x0001;
246    },
247    $IsToRight: function (direction) {
248        return (direction & 0x0003) == 0x0002;
249    },
250    $IsToTop: function (direction) {
251        return (direction & 0x000C) == 0x0004;
252    },
253    $IsToBottom: function (direction) {
254        return (direction & 0x000C) == 0x0008;
255    },
256    $IsHorizontal: function (direction) {
257        return (direction & 0x0003) > 0;
258    },
259    $IsVertical: function (direction) {
260        return (direction & 0x000C) > 0;
261    }
262};
263
264var $JssorKeyCode$ = {
265    $BACKSPACE: 8,
266    $COMMA: 188,
267    $DELETE: 46,
268    $DOWN: 40,
269    $END: 35,
270    $ENTER: 13,
271    $ESCAPE: 27,
272    $HOME: 36,
273    $LEFT: 37,
274    $NUMPAD_ADD: 107,
275    $NUMPAD_DECIMAL: 110,
276    $NUMPAD_DIVIDE: 111,
277    $NUMPAD_ENTER: 108,
278    $NUMPAD_MULTIPLY: 106,
279    $NUMPAD_SUBTRACT: 109,
280    $PAGE_DOWN: 34,
281    $PAGE_UP: 33,
282    $PERIOD: 190,
283    $RIGHT: 39,
284    $SPACE: 32,
285    $TAB: 9,
286    $UP: 38
287};
288
289var $JssorAlignment$ = {
290    $TopLeft: 0x11,
291    $TopCenter: 0x12,
292    $TopRight: 0x14,
293    $MiddleLeft: 0x21,
294    $MiddleCenter: 0x22,
295    $MiddleRight: 0x24,
296    $BottomLeft: 0x41,
297    $BottomCenter: 0x42,
298    $BottomRight: 0x44,
299
300    $IsTop: function (aligment) {
301        return aligment & 0x10 > 0;
302    },
303    $IsMiddle: function (alignment) {
304        return alignment & 0x20 > 0;
305    },
306    $IsBottom: function (alignment) {
307        return alignment & 0x40 > 0;
308    },
309    $IsLeft: function (alignment) {
310        return alignment & 0x01 > 0;
311    },
312    $IsCenter: function (alignment) {
313        return alignment & 0x02 > 0;
314    },
315    $IsRight: function (alignment) {
316        return alignment & 0x04 > 0;
317    }
318};
319
320var $JssorMatrix$;
321
322var $JssorBrowser$ = {
323    $UNKNOWN: 0,
324    $IE: 1,
325    $FIREFOX: 2,
326    $SAFARI: 3,
327    $CHROME: 4,
328    $OPERA: 5
329};
330
331var $ROWSER_UNKNOWN$ = 0;
332var $ROWSER_IE$ = 1;
333var $ROWSER_FIREFOX$ = 2;
334var $ROWSER_SAFARI$ = 3;
335var $ROWSER_CHROME$ = 4;
336var $ROWSER_OPERA$ = 5;
337
338var $JssorAnimator$;
339
340// $JssorUtils$ is a static class, so make it singleton instance
341var $JssorUtils$ = window.$JssorUtils$ = new function () {
342
343    // Fields
344
345    var self = this;
346
347    var arrActiveX = ["Msxml2.XMLHTTP", "Msxml3.XMLHTTP", "Microsoft.XMLHTTP"];
348    var supportedImageFormats = {
349        "bmp": false,
350        "jpeg": true,
351        "jpg": true,
352        "png": true,
353        "tif": false,
354        "wdp": false
355    };
356
357    var browser = $JssorBrowser$.$UNKNOWN;
358    var browserRuntimeVersion = 0;
359    var browserEngineVersion = 0;
360    var browserJavascriptVersion = 0;
361    var webkitVersion = 0;
362
363    var app = navigator.appName;
364    var ver = navigator.appVersion;
365    var ua = navigator.userAgent;
366
367    var urlParams = {};
368
369    function DetectBrowser() {
370        if (!browser) {
371            if (app == "Microsoft Internet Explorer" &&
372                !!window.attachEvent && !!window.ActiveXObject) {
373
374                var ieOffset = ua.indexOf("MSIE");
375                browser = $JssorBrowser$.$IE;
376                browserEngineVersion = parseFloat(ua.substring(ieOffset + 5, ua.indexOf(";", ieOffset)));
377
378                //check IE javascript version
379                /*@cc_on
380                browserJavascriptVersion = @_jscript_version;
381                @*/
382
383                // update: for intranet sites and compat view list sites, IE sends
384                // an IE7 User-Agent to the server to be interoperable, and even if
385                // the page requests a later IE version, IE will still report the
386                // IE7 UA to JS. we should be robust to self.
387                //var docMode = document.documentMode;
388                //if (typeof docMode !== "undefined") {
389                //    browserRuntimeVersion = docMode;
390                //}
391
392                browserRuntimeVersion = document.documentMode || browserEngineVersion;
393
394            }
395            else if (app == "Netscape" && !!window.addEventListener) {
396
397                var ffOffset = ua.indexOf("Firefox");
398                var saOffset = ua.indexOf("Safari");
399                var chOffset = ua.indexOf("Chrome");
400                var webkitOffset = ua.indexOf("AppleWebKit");
401
402                if (ffOffset >= 0) {
403                    browser = $JssorBrowser$.$FIREFOX;
404                    browserRuntimeVersion = parseFloat(ua.substring(ffOffset + 8));
405                }
406                else if (saOffset >= 0) {
407                    var slash = ua.substring(0, saOffset).lastIndexOf("/");
408                    browser = (chOffset >= 0) ? $JssorBrowser$.$CHROME : $JssorBrowser$.$SAFARI;
409                    browserRuntimeVersion = parseFloat(ua.substring(slash + 1, saOffset));
410                }
411
412                if (webkitOffset >= 0)
413                    webkitVersion = parseFloat(ua.substring(webkitOffset + 12));
414            }
415            else {
416                var match = /(opera)(?:.*version|)[ \/]([\w.]+)/i.exec(ua);
417                if (match) {
418                    browser = $JssorBrowser$.$OPERA;
419                    browserRuntimeVersion = parseFloat(match[2]);
420                }
421            }
422        }
423    }
424
425    function IsBrowserIE() {
426        DetectBrowser();
427        return browser == $ROWSER_IE$;
428    }
429
430    function IsBrowserIeQuirks() {
431
432        return IsBrowserIE() && (browserRuntimeVersion < 6 || document.compatMode == "BackCompat");   //Composite to "CSS1Compat"
433    }
434
435    function IsBrowserFireFox() {
436        DetectBrowser();
437        return browser == $ROWSER_FIREFOX$;
438    }
439
440    function IsBrowserSafari() {
441        DetectBrowser();
442        return browser == $ROWSER_SAFARI$;
443    }
444
445    function IsBrowserChrome() {
446        DetectBrowser();
447        return browser == $ROWSER_CHROME$;
448    }
449
450    function IsBrowserOpera() {
451        DetectBrowser();
452        return browser == $ROWSER_OPERA$;
453    }
454
455    function IsBrowserBadTransform() {
456        return IsBrowserSafari() && (webkitVersion > 534) && (webkitVersion < 535);
457    }
458
459    function IsBrowserSafeHWA() {
460        return IsBrowserSafari() && (webkitVersion < 535);
461    }
462
463    function IsBrowserIe9Earlier() {
464
465        //IE 8- and chrome 1 won't fade well
466        return IsBrowserIE() && browserRuntimeVersion < 9; // || (IsBrowserChrome() && browserRuntimeVersion < 2);
467    }
468
469    var _TransformProperty;
470    function GetTransformProperty(elmt) {
471
472        if (!_TransformProperty) {
473            // Note that in some versions of IE9 it is critical that
474            // msTransform appear in this list before MozTransform
475
476            each(['transform', 'WebkitTransform', 'msTransform', 'MozTransform', 'OTransform'], function (property) {
477                if (!self.$IsUndefined(elmt.style[property])) {
478                    _TransformProperty = property;
479                    return true;
480                }
481            });
482
483            _TransformProperty = _TransformProperty || "transform";
484        }
485
486        return _TransformProperty;
487    }
488
489    // Constructor
490    {
491        //Ignore urlParams
492        //        // Url parameters
493
494        //        var query = window.location.search.substring(1);    // ignore '?'
495        //        var parts = query.split('&');
496
497        //        for (var i = 0; i < parts.length; i++) {
498        //            var part = parts[i];
499        //            var sep = part.indexOf('=');
500
501        //            if (sep > 0) {
502        //                urlParams[part.substring(0, sep)] =
503        //                        decodeURIComponent(part.substring(sep + 1));
504        //            }
505        //        }
506
507        // Browser behaviors
508
509    }
510
511    // Helpers
512    function getOffsetParent(elmt, isFixed) {
513        // IE and Opera "fixed" position elements don't have offset parents.
514        // regardless, if it's fixed, its offset parent is the body.
515        if (isFixed && elmt != document.body) {
516            return document.body;
517        } else {
518            return elmt.offsetParent;
519        }
520    }
521
522    function toString(obj) {
523        return Object.prototype.toString.call(obj);
524    }
525
526    // [[Class]] -> type pairs
527    var class2type;
528
529    function each(object, callback) {
530        if (toString(object) == "[object Array]") {
531            for (var i = 0; i < object.length; i++) {
532                if (callback(object[i], i, object)) {
533                    break;
534                }
535            }
536        } else {
537            for (var name in object) {
538                if (callback(object[name], name, object)) {
539                    break;
540                }
541            }
542        }
543    }
544
545    function GetClass2Type() {
546        if (!class2type) {
547            class2type = {};
548            each(["Boolean", "Number", "String", "Function", "Array", "Date", "RegExp", "Object"], function (name) {
549                class2type["[object " + name + "]"] = name.toLowerCase();
550            });
551        }
552
553        return class2type;
554    }
555
556    function type(obj) {
557        return obj == null ? String(obj) : GetClass2Type()[toString(obj)] || "object";
558    }
559
560    function isPlainObject(obj) {
561        // Must be an Object.
562        // Because of IE, we also have to check the presence of the constructor property.
563        // Make sure that DOM nodes and window objects don't pass through, as well
564        if (!obj || type(obj) !== "object" || obj.nodeType || self.$IsWindow(obj)) {
565            return false;
566        }
567
568        var hasOwn = Object.prototype.hasOwnProperty;
569
570        try {
571            // Not own constructor property must be Object
572            if (obj.constructor &&
573				!hasOwn.call(obj, "constructor") &&
574				!hasOwn.call(obj.constructor.prototype, "isPrototypeOf")) {
575                return false;
576            }
577        } catch (e) {
578            // IE8,9 Will throw exceptions on certain host objects #9897
579            return false;
580        }
581
582        // Own properties are enumerated firstly, so to speed up,
583        // if last one is own, then all properties are own.
584
585        var key;
586        for (key in obj) { }
587
588        return key === undefined || hasOwn.call(obj, key);
589    }
590
591    function Delay(code, delay) {
592        setTimeout(code, delay || 0);
593    }
594
595    function RemoveByReg(str, reg) {
596        var m = reg.exec(str);
597
598        if (m) {
599            var header = str.substr(0, m.index);
600            var tailer = str.substr(m.lastIndex + 1, str.length - (m.lastIndex + 1));
601            str = header + tailer;
602        }
603
604        return str;
605    }
606
607    function BuildNewCss(oldCss, removeRegs, replaceValue) {
608        var css = (!oldCss || oldCss == "inherit") ? "" : oldCss;
609
610        each(removeRegs, function (removeReg) {
611            var m = removeReg.exec(css);
612
613            if (m) {
614                var header = css.substr(0, m.index);
615                var tailer = css.substr(m.lastIndex + 1, css.length - (m.lastIndex + 1));
616                css = header + tailer;
617            }
618        });
619
620        css = replaceValue + (css.indexOf(" ") != 0 ? " " : "") + css;
621
622        return css;
623    }
624
625    function SetStyleFilterIE(elmt, value) {
626        if (browserRuntimeVersion < 9) {
627            elmt.style.filter = value;
628        }
629    }
630
631    function SetStyleMatrixIE(elmt, matrix, offset) {
632        //matrix is not for ie9+ running in ie8- mode
633        if (browserJavascriptVersion < 9) {
634            var oldFilterValue = elmt.style.filter;
635            var matrixReg = new RegExp(/[\s]*progid:DXImageTransform\.Microsoft\.Matrix\([^\)]*\)/g);
636            var matrixValue = matrix ? "progid:DXImageTransform.Microsoft.Matrix(" + "M11=" + matrix[0][0] + ", M12=" + matrix[0][1] + ", M21=" + matrix[1][0] + ", M22=" + matrix[1][1] + ", SizingMethod='auto expand')" : "";
637
638            var newFilterValue = BuildNewCss(oldFilterValue, [matrixReg], matrixValue);
639
640            SetStyleFilterIE(elmt, newFilterValue);
641
642            self.$CssMarginTop(elmt, offset.y);
643            self.$CssMarginLeft(elmt, offset.x);
644        }
645    }
646
647    // Methods
648
649    self.$IsBrowserIE = IsBrowserIE;
650
651    self.$IsBrowserIeQuirks = IsBrowserIeQuirks;
652
653    self.$IsBrowserFireFox = IsBrowserFireFox;
654
655    self.$IsBrowserSafari = IsBrowserSafari;
656
657    self.$IsBrowserChrome = IsBrowserChrome;
658
659    self.$IsBrowserOpera = IsBrowserOpera;
660
661    self.$IsBrowserBadTransform = IsBrowserBadTransform;
662
663    self.$IsBrowserSafeHWA = IsBrowserSafeHWA;
664
665    self.$IsBrowserIe9Earlier = IsBrowserIe9Earlier;
666
667    self.$GetBrowserVersion = function () {
668        return browserRuntimeVersion;
669    };
670
671    self.$GetBrowserEngineVersion = function () {
672        return browserEngineVersion || browserRuntimeVersion;
673    };
674
675    self.$GetWebKitVersion = function () {
676        return webkitVersion;
677    };
678
679    self.$Delay = Delay;
680
681    self.$GetElement = function (elmt) {
682        if (self.$IsString(elmt)) {
683            elmt = document.getElementById(elmt);
684        }
685
686        return elmt;
687    };
688
689    self.$GetElementPosition = function (elmt) {
690        elmt = self.$GetElement(elmt);
691        var result = new $JssorPoint$();
692
693        // technique from:
694        // http://www.quirksmode.org/js/findpos.html
695        // with special check for "fixed" elements.
696
697        while (elmt) {
698            result.x += elmt.offsetLeft;
699            result.y += elmt.offsetTop;
700
701            var isFixed = self.$GetElementStyle(elmt).position == "fixed";
702
703            if (isFixed) {
704                result = result.$Plus(self.$GetPageScroll(window));
705            }
706
707            elmt = getOffsetParent(elmt, isFixed);
708        }
709
710        return result;
711    };
712
713    self.$GetElementSize = function (elmt) {
714        elmt = self.$GetElement(elmt);
715        return new $JssorPoint$(elmt.clientWidth, elmt.clientHeight);
716    };
717
718    self.$GetEvent = function (event) {
719        return event ? event : window.event;
720    };
721
722    self.$GetEventSrcElement = function (event) {
723        event = self.$GetEvent(event);
724        return event.target || event.srcElement || document;
725    };
726
727    self.$GetEventDstElement = function (event) {
728        event = self.$GetEvent(event);
729        return event.relatedTarget || event.toElement;
730    };
731
732    self.$GetMousePosition = function (event) {
733        event = self.$GetEvent(event);
734        var result = new $JssorPoint$();
735
736        // technique from:
737        // http://www.quirksmode.org/js/events_properties.html
738
739        if (event.type == "DOMMouseScroll" &&
740                IsBrowserFireFox() && browserRuntimeVersion < 3) {
741            // hack for FF2 which reports incorrect position for mouse scroll
742            result.x = event.screenX;
743            result.y = event.screenY;
744        } else if (typeof (event.pageX) == "number") {
745            result.x = event.pageX;
746            result.y = event.pageY;
747        } else if (typeof (event.clientX) == "number") {
748            result.x = event.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
749            result.y = event.clientY + document.body.scrollTop + document.documentElement.scrollTop;
750        } else {
751            $JssorDebug$.$Fail("Unknown event mouse position, no known technique.");
752        }
753
754        return result;
755    };
756
757    self.$GetMouseScroll = function (event) {
758        event = self.$GetEvent(event);
759        var delta = 0; // default value
760
761        // technique from:
762        // http://blog.paranoidferret.com/index.php/2007/10/31/javascript-tutorial-the-scroll-wheel/
763
764        if (typeof (event.wheelDelta) == "number") {
765            delta = event.wheelDelta;
766        } else if (typeof (event.detail) == "number") {
767            delta = event.detail * -1;
768        } else {
769            $JssorDebug$.$Fail("Unknown event mouse scroll, no known technique.");
770        }
771
772        // normalize value to [-1, 1]
773        return delta ? delta / Math.abs(delta) : 0;
774    };
775
776    self.$GetPageScroll = function (window) {
777        var result = new $JssorPoint$();
778        var docElmt = window.document.documentElement || {};
779        var body = window.document.body || {};
780
781        // technique from:
782        // http://www.howtocreate.co.uk/tutorials/javascript/browserwindow
783
784        if (typeof (window.pageXOffset) == "number") {
785            // most browsers
786            result.x = window.pageXOffset;
787            result.y = window.pageYOffset;
788        } else if (body.scrollLeft || body.scrollTop) {
789            // W3C spec, IE6+ in quirks mode
790            result.x = body.scrollLeft;
791            result.y = body.scrollTop;
792        } else if (docElmt.scrollLeft || docElmt.scrollTop) {
793            // IE6+ in standards mode
794            result.x = docElmt.scrollLeft;
795            result.y = docElmt.scrollTop;
796        }
797
798        // note: we specifically aren't testing for typeof here, because IE sets
799        // the appropriate variables undefined instead of 0 under certain
800        // conditions. self means we also shouldn't fail if none of the three
801        // cases are hit; we'll just assume the page scroll is 0.
802
803        return result;
804    };
805
806    self.$GetWindowSize = function (window) {
807        var result = new $JssorPoint$();
808
809        // technique from:
810        // http://www.howtocreate.co.uk/tutorials/javascript/browserwindow
811
812        //jQuery way to get window size, but support ie quirks mode
813        var checkElement = (IsBrowserIeQuirks() ? window.document.body : window.document.documentElement);
814
815        result.x = checkElement.clientWidth;
816        result.y = checkElement.clientHeight;
817
818        return result;
819    };
820
821    //self.$MakeAjaxRequest = function (url, callback) {
822    //    var async = typeof (callback) == "function";
823    //    var req = null;
824
825    //    if (async) {
826    //        var actual = callback;
827    //        var callback = function () {
828    //            Delay($JssorUtils$.$CreateCallback(null, actual, req), 1);
829    //        };
830    //    }
831
832    //    if (window.ActiveXObject) {
833    //        for (var i = 0; i < arrActiveX.length; i++) {
834    //            try {
835    //                req = new ActiveXObject(arrActiveX[i]);
836    //                break;
837    //            } catch (e) {
838    //                continue;
839    //            }
840    //        }
841    //    } else if (window.XMLHttpRequest) {
842    //        req = new XMLHttpRequest();
843    //    }
844
845    //    if (!req) {
846    //        $JssorDebug$.$Fail("Browser doesn't support XMLHttpRequest.");
847    //    }
848
849    //    if (async) {
850    //        req.onreadystatechange = function () {
851    //            if (req.readyState == 4) {
852    //                // prevent memory leaks by breaking circular reference now
853    //                req.onreadystatechange = new Function();
854    //                callback();
855    //            }
856    //        };
857    //    }
858
859    //    try {
860    //        req.open("GET", url, async);
861    //        req.send(null);
862    //    } catch (e) {
863    //        $JssorDebug$.$Log(e.name + " while making AJAX request: " + e.message);
864
865    //        req.onreadystatechange = null;
866    //        req = null;
867
868    //        if (async) {
869    //            callback();
870    //        }
871    //    }
872
873    //    return async ? null : req;
874    //};
875
876    //self.$ParseXml = function (string) {
877    //    var xmlDoc = null;
878
879    //    if (window.ActiveXObject) {
880    //        try {
881    //            xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
882    //            xmlDoc.async = false;
883    //            xmlDoc.loadXML(string);
884    //        } catch (e) {
885    //            $JssorDebug$.$Log(e.name + " while parsing XML (ActiveX): " + e.message);
886    //        }
887    //    } else if (window.DOMParser) {
888    //        try {
889    //            var parser = new DOMParser();
890    //            xmlDoc = parser.parseFromString(string, "text/xml");
891    //        } catch (e) {
892    //            $JssorDebug$.$Log(e.name + " while parsing XML (DOMParser): " + e.message);
893    //        }
894    //    } else {
895    //        $JssorDebug$.$Fail("Browser doesn't support XML DOM.");
896    //    }
897
898    //    return xmlDoc;
899    //};
900
901    function Css(elmt, name, value) {
902        ///	<summary>
903        ///		access css
904        ///     $JssorUtils$.$Css(elmt, name);         //get css value
905        ///     $JssorUtils$.$Css(elmt, name, value);  //set css value
906        ///	</summary>
907        ///	<param name="elmt" type="HTMLElement">
908        ///		the element to access css
909        ///	</param>
910        ///	<param name="name" type="String">
911        ///		the name of css property
912        ///	</param>
913        ///	<param name="value" optional="true">
914        ///		the value to set
915        ///	</param>
916        if (value != undefined) {
917            elmt.style[name] = value;
918        }
919        else {
920            var style = elmt.currentStyle || elmt.style;
921            value = style[name];
922
923            if(value == "" && window.getComputedStyle) {
924                style = elmt.ownerDocument.defaultView.getComputedStyle(elmt, null);
925
926                style && (value = style.getPropertyValue(name) || style[name]);
927            }
928
929            return value;
930        }
931    }
932
933    function CssN(elmt, name, value, isDimensional) {
934        ///	<summary>
935        ///		access css as numeric
936        ///     $JssorUtils$.$CssN(elmt, name);         //get css value
937        ///     $JssorUtils$.$CssN(elmt, name, value);  //set css value
938        ///	</summary>
939        ///	<param name="elmt" type="HTMLElement">
940        ///		the element to access css
941        ///	</param>
942        ///	<param name="name" type="String">
943        ///		the name of css property
944        ///	</param>
945        ///	<param name="value" type="Number" optional="true">
946        ///		the value to set
947        ///	</param>
948        if (value != undefined) {
949            isDimensional && (value += "px");
950            Css(elmt, name, value);
951        }
952        else {
953            return parseFloat(Css(elmt, name));
954        }
955    }
956
957    function CssP(elmt, name, value) {
958        ///	<summary>
959        ///		access css in pixel as numeric, like 'top', 'left', 'width', 'height'
960        ///     $JssorUtils$.$CssP(elmt, name);         //get css value
961        ///     $JssorUtils$.$CssP(elmt, name, value);  //set css value
962        ///	</summary>
963        ///	<param name="elmt" type="HTMLElement">
964        ///		the element to access css
965        ///	</param>
966        ///	<param name="name" type="String">
967        ///		the name of css property
968        ///	</param>
969        ///	<param name="value" type="Number" optional="true">
970        ///		the value to set
971        ///	</param>
972        return CssN(elmt, name, value, true);
973    }
974
975    function CssProxy(name, numericOrDimension) {
976        ///	<summary>
977        ///		create proxy to access css, CssProxy(name[, numericOrDimension]);
978        ///	</summary>
979        ///	<param name="elmt" type="HTMLElement">
980        ///		the element to access css
981        ///	</param>
982        ///	<param name="numericOrDimension" type="Number" optional="true">
983        ///		not set: access original css, 1: access css as numeric, 2: access css in pixel as numeric
984        ///	</param>
985        var isDimensional = numericOrDimension & 2;
986        var cssAccessor = numericOrDimension ? CssN : Css;
987        return function (elmt, value) {
988            return cssAccessor(elmt, name, value, isDimensional);
989        };
990    }
991
992    function GetStyleOpacity(elmt) {
993        if (IsBrowserIE() && browserEngineVersion < 9) {
994            var match = /opacity=([^)]*)/.exec(elmt.style.filter || "");
995            return match ? (parseFloat(match[1]) / 100) : 1;
996        }
997        else
998            return parseFloat(elmt.style.opacity || "1");
999    }
1000
1001    function SetStyleOpacity(elmt, opacity, ie9EarlierForce) {
1002
1003        if (IsBrowserIE() && browserEngineVersion < 9) {
1004            //var filterName = "filter"; // browserEngineVersion < 8 ? "filter" : "-ms-filter";
1005            var finalFilter = elmt.style.filter || "";
1006
1007            // for CSS filter browsers (IE), remove alpha filter if it's unnecessary.
1008            // update: doing self always since IE9 beta seems to have broken the
1009            // behavior if we rely on the programmatic filters collection.
1010            var alphaReg = new RegExp(/[\s]*alpha\([^\)]*\)/g);
1011
1012            // important: note the lazy star! self protects against
1013            // multiple filters; we don't want to delete the other ones.
1014            // update: also trimming extra whitespace around filter.
1015
1016            var ieOpacity = Math.round(100 * opacity);
1017            var alphaFilter = "";
1018            if (ieOpacity < 100 || ie9EarlierForce) {
1019                alphaFilter = "alpha(opacity=" + ieOpacity + ") ";
1020                //elmt.style["-ms-filter"] = "progid:DXImageTransform.Microsoft.Alpha(opacity=" + ieOpacity + ") ";
1021            }
1022
1023            var newFilterValue = BuildNewCss(finalFilter, [alphaReg], alphaFilter);
1024
1025            SetStyleFilterIE(elmt, newFilterValue);
1026        }
1027
1028            //if (!IsBrowserIE() || browserEngineVersion >= 9) 
1029        else {
1030            elmt.style.opacity = opacity == 1 ? "" : Math.round(opacity * 100) / 100;
1031        }
1032    }
1033
1034    function SetStyleTransformInternal(elmt, transform) {
1035        var rotate = transform.$Rotate || 0;
1036        var scale = transform.$Scale == undefined ? 1 : transform.$Scale;
1037
1038        if (IsBrowserIe9Earlier()) {
1039            var matrix = self.$CreateMatrix(rotate / 180 * Math.PI, scale, scale);
1040            SetStyleMatrixIE(elmt, (!rotate && scale == 1) ? null : matrix, self.$GetMatrixOffset(matrix, transform.$OriginalWidth, transform.$OriginalHeight));
1041        }
1042        else {
1043            //rotate(15deg) scale(.5) translateZ(0)
1044            var transformProperty = GetTransformProperty(elmt);
1045            if (transformProperty) {
1046                var transformValue = "rotate(" + rotate % 360 + "deg) scale(" + scale + ")";
1047                if ($JssorUtils$.$IsBrowserChrome() && webkitVersion > 535)
1048                    transformValue += " perspective(2000px)";
1049
1050                elmt.style[transformProperty] = transformValue;
1051            }
1052        }
1053    }
1054
1055    self.$SetStyleTransform = function (elmt, transform) {
1056        if (IsBrowserBadTransform()) {
1057            Delay(self.$CreateCallback(null, SetStyleTransformInternal, elmt, transform));
1058        }
1059        else {
1060            SetStyleTransformInternal(elmt, transform);
1061        }
1062    };
1063
1064    self.$SetStyleTransformOrigin = function (elmt, transformOrigin) {
1065        var transformProperty = GetTransformProperty(elmt);
1066
1067        if (transformProperty)
1068            elmt.style[transformProperty + "Origin"] = transformOrigin;
1069    };
1070
1071    self.$SetStyleScale = function (elmt, scale) {
1072
1073        if (IsBrowserIE() && browserEngineVersion < 9 || (browserEngineVersion < 10 && IsBrowserIeQuirks())) {
1074            elmt.style.zoom = (scale == 1) ? "" : scale;
1075        }
1076        else {
1077            var transformProperty = GetTransformProperty(elmt);
1078
1079            if (transformProperty) {
1080                //rotate(15deg) scale(.5)
1081                var transformValue = "scale(" + scale + ")";
1082
1083                var oldTransformValue = elmt.style[transformProperty];
1084                var scaleReg = new RegExp(/[\s]*scale\(.*?\)/g);
1085
1086                var newTransformValue = BuildNewCss(oldTransformValue, [scaleReg], transformValue);
1087
1088                elmt.style[transformProperty] = newTransformValue;
1089            }
1090        }
1091    };
1092
1093    self.$EnableHWA = function (elmt) {
1094        if (!elmt.style[GetTransformProperty(elmt)] || elmt.style[GetTransformProperty(elmt)] == "none")
1095            elmt.style[GetTransformProperty(elmt)] = "perspective(2000px)";
1096    };
1097
1098    self.$DisableHWA = function (elmt) {
1099        //if (force || elmt.style[GetTransformProperty(elmt)] == "perspective(2000px)")
1100        elmt.style[GetTransformProperty(elmt)] = "none";
1101    };
1102
1103    var ie8OffsetWidth = 0;
1104    var ie8OffsetHeight = 0;
1105    var ie8WindowResizeCallbackHandlers;
1106    //var ie8LastVerticalScrollbar;
1107    //var toggleInfo = "";
1108
1109    function Ie8WindowResizeFilter(window) {
1110
1111        var trigger = true;
1112
1113        var checkElement = (IsBrowserIeQuirks() ? window.document.body : window.document.documentElement);
1114        if (checkElement) {
1115            //check vertical bar
1116            //var hasVerticalBar = checkElement.scrollHeight > checkElement.clientHeight;
1117            //var verticalBarToggle = hasVerticalBar != ie8LastVerticalScrollbar;
1118            //ie8LastVerticalScrollbar = hasVerticalBar;
1119
1120            var widthChange = checkElement.offsetWidth - ie8OffsetWidth;
1121            var heightChange = checkElement.offsetHeight - ie8OffsetHeight;
1122            if (widthChange || heightChange) {
1123
1124                ie8OffsetWidth += widthChange;
1125                ie8OffsetHeight += heightChange;
1126            }
1127            else
1128                trigger = false;
1129        }
1130
1131        trigger && each(ie8WindowResizeCallbackHandlers, function (handler) {
1132            handler();
1133        });
1134    }
1135
1136    self.$OnWindowResize = function (window, handler) {
1137
1138        if (IsBrowserIE() && browserEngineVersion < 9) {
1139            if (!ie8WindowResizeCallbackHandlers) {
1140                ie8WindowResizeCallbackHandlers = [handler];
1141                handler = self.$CreateCallback(null, Ie8WindowResizeFilter, window);
1142            }
1143            else {
1144                ie8WindowResizeCallbackHandlers.push(handler);
1145                return;
1146            }
1147        }
1148
1149        self.$AddEvent(window, "resize", handler);
1150    };
1151
1152    self.$AddEvent = function (elmt, eventName, handler, useCapture) {
1153        elmt = self.$GetElement(elmt);
1154
1155        // technique from:
1156        // http://blog.paranoidferret.com/index.php/2007/08/10/javascript-working-with-events/
1157
1158        if (elmt.addEventListener) {
1159            if (eventName == "mousewheel") {
1160                elmt.addEventListener("DOMMouseScroll", handler, useCapture);
1161            }
1162            // we are still going to add the mousewheel -- not a mistake!
1163            // self is for opera, since it uses onmousewheel but needs addEventListener.
1164            elmt.addEventListener(eventName, handler, useCapture);
1165        }
1166        else if (elmt.attachEvent) {
1167            elmt.attachEvent("on" + eventName, handler);
1168            if (useCapture && elmt.setCapture) {
1169                elmt.setCapture();
1170            }
1171        }
1172
1173        $JssorDebug$.$Execute(function () {
1174            if (!elmt.addEventListener && !elmt.attachEvent) {
1175                $JssorDebug$.$Fail("Unable to attach event handler, no known technique.");
1176            }
1177        });
1178
1179    };
1180
1181    self.$RemoveEvent = function (elmt, eventName, handler, useCapture) {
1182        elmt = self.$GetElement(elmt);
1183
1184        // technique from:
1185        // http://blog.paranoidferret.com/index.php/2007/08/10/javascript-working-with-events/
1186
1187        if (elmt.removeEventListener) {
1188            if (eventName == "mousewheel") {
1189                elmt.removeEventListener("DOMMouseScroll", handler, useCapture);
1190            }
1191            // we are still going to remove the mousewheel -- not a mistake!
1192            // self is for opera, since it uses onmousewheel but needs removeEventListener.
1193            elmt.removeEventListener(eventName, handler, useCapture);
1194        }
1195        else if (elmt.detachEvent) {
1196            elmt.detachEvent("on" + eventName, handler);
1197            if (useCapture && elmt.releaseCapture) {
1198                elmt.releaseCapture();
1199            }
1200        }
1201
1202        $JssorDebug$.$Execute(function () {
1203            if (!elmt.removeEventListener && !elmt.detachEvent) {
1204                $JssorDebug$.$Fail("Unable to detach event handler, no known technique.");
1205            }
1206        });
1207    };
1208
1209    self.$FireEvent = function (elmt, eventName) {
1210        //var document = elmt.document;
1211
1212        $JssorDebug$.$Execute(function () {
1213            if (!document.createEvent && !document.createEventObject) {
1214                $JssorDebug$.$Fail("Unable to fire event, no known technique.");
1215            }
1216
1217            if (!elmt.dispatchEvent && !elmt.fireEvent) {
1218                $JssorDebug$.$Fail("Unable to fire event, no known technique.");
1219            }
1220        });
1221
1222        var evento;
1223
1224        if (document.createEvent) {
1225            evento = document.createEvent("HTMLEvents");
1226            evento.initEvent(eventName, false, false);
1227            elmt.dispatchEvent(evento);
1228        }
1229        else {
1230            var ieEventName = "on" + eventName;
1231            evento = document.createEventObject();
1232            //event.eventType = ieEventName;
1233            //event.eventName = ieEventName;
1234
1235            elmt.fireEvent(ieEventName, evento);
1236        }
1237    };
1238
1239    self.$AddEventBrowserMouseUp = function (handler, userCapture) {
1240        self.$AddEvent((IsBrowserIe9Earlier()) ? document : window, "mouseup", handler, userCapture);
1241    };
1242
1243    self.$RemoveEventBrowserMouseUp = function (handler, userCapture) {
1244        self.$RemoveEvent((IsBrowserIe9Earlier()) ? document : window, "mouseup", handler, userCapture);
1245    };
1246
1247    self.$AddEventBrowserMouseDown = function (handler, userCapture) {
1248        self.$AddEvent((IsBrowserIe9Earlier()) ? document : window, "mousedown", handler, userCapture);
1249    };
1250
1251    self.$RemoveEventBrowserMouseDown = function (handler, userCapture) {
1252        self.$RemoveEvent((IsBrowserIe9Earlier()) ? document : window, "mousedown", handler, userCapture);
1253    };
1254
1255    self.$CancelEvent = function (event) {
1256        event = self.$GetEvent(event);
1257
1258        // technique from:
1259        // http://blog.paranoidferret.com/index.php/2007/08/10/javascript-working-with-events/
1260
1261        if (event.preventDefault) {
1262            event.preventDefault();     // W3C for preventing default
1263        }
1264
1265        event.cancel = true;            // legacy for preventing default
1266        event.returnValue = false;      // IE for preventing default
1267    };
1268
1269    self.$StopEvent = function (event) {
1270        event = self.$GetEvent(event);
1271
1272        // technique from:
1273        // http://blog.paranoidferret.com/index.php/2007/08/10/javascript-working-with-events/
1274
1275        if (event.stopPropagation) {
1276            event.stopPropagation();    // W3C for stopping propagation
1277        }
1278
1279        event.cancelBubble = true;      // IE for stopping propagation
1280    };
1281
1282    self.$CreateCallback = function (object, method) {
1283        // create callback args
1284        var initialArgs = [];
1285        for (var i = 2; i < arguments.length; i++) {
1286            initialArgs.push(arguments[i]);
1287        }
1288
1289        // create closure to apply method
1290        var callback = function () {
1291            // concatenate new args, but make a copy of initialArgs first
1292            var args = initialArgs.concat([]);
1293            for (var i = 0; i < arguments.length; i++) {
1294                args.push(arguments[i]);
1295            }
1296
1297            return method.apply(object, args);
1298        };
1299
1300        $JssorDebug$.$LiveStamp(callback, "callback_" + ($JssorUtils$.$GetNow() & 11111111));
1301
1302        return callback;
1303    };
1304
1305    var _Freeer;
1306    self.$FreeElement = function (elmt) {
1307        if (!_Freeer)
1308            _Freeer = self.$CreateDivElement();
1309
1310        if (elmt) {
1311            $JssorUtils$.$AppendChild(_Freeer, elmt);
1312            $JssorUtils$.$ClearInnerHtml(_Freeer);
1313        }
1314    };
1315
1316    self.$SetInnerText = function (elmt, text) {
1317        var textNode = document.createTextNode(text);
1318        self.$ClearInnerHtml(elmt);
1319        elmt.appendChild(textNode);
1320    };
1321
1322    self.$GetInnerText = function (elmt) {
1323        return elmt.textContent || elmt.innerText;
1324    };
1325
1326    self.$GetInnerHtml = function (elmt) {
1327        return elmt.innerHTML;
1328    };
1329
1330    self.$SetInnerHtml = function (elmt, html) {
1331        elmt.innerHTML = html;
1332    };
1333
1334    self.$ClearInnerHtml = function (elmt) {
1335        elmt.innerHTML = "";
1336    };
1337
1338    self.$EncodeHtml = function (text) {
1339        var div = self.$CreateDivElement();
1340        self.$SetInnerText(div, text);
1341        return self.$GetInnerHtml(div);
1342    };
1343
1344    self.$DecodeHtml = function (html) {
1345        var div = self.$CreateDivElement();
1346        self.$SetInnerHtml(div, html);
1347        return self.$GetInnerText(div);
1348    };
1349
1350    self.$SelectElement = function (elmt) {
1351        var userSelection;
1352        if (window.getSelection) {
1353            //W3C default
1354            userSelection = window.getSelection();
1355        }
1356        var theRange = null;
1357        if (document.createRange) {
1358            theRange = document.createRange();
1359            theRange.selectNode(elmt);
1360        }
1361        else {
1362            theRange = document.body.createTextRange();
1363            theRange.moveToElementText(elmt);
1364            theRange.select();
1365        }
1366        //set user selection
1367        if (userSelection)
1368            userSelection.addRange(theRange);
1369    };
1370
1371    self.$DeselectElements = function () {
1372        if (document.selection) {
1373            document.selection.empty();
1374        } else if (window.getSelection) {
1375            window.getSelection().removeAllRanges();
1376        }
1377    };
1378
1379    self.$GetChildren = function (elmt) {
1380        var children = [];
1381
1382        for (var tmpEl = elmt.firstChild; tmpEl; tmpEl = tmpEl.nextSibling) {
1383            if (tmpEl.nodeType == 1) {
1384                children.push(tmpEl);
1385            }
1386        }
1387
1388        return children;
1389    };
1390
1391    function FindFirstChildByAttribute(elmt, attrValue, attrName, deep) {
1392        if (!attrName)
1393            attrName = "u";
1394
1395        for (elmt = elmt ? elmt.firstChild : null; elmt; elmt = elmt.nextSibling) {
1396            if (elmt.nodeType == 1) {
1397                if (self.$GetAttributeEx(elmt, attrName) == attrValue)
1398                    return elmt;
1399
1400                if (deep) {
1401                    var childRet = FindFirstChildByAttribute(elmt, attrValue, attrName, deep);
1402                    if (childRet)
1403                        return childRet;
1404                }
1405            }
1406        }
1407    }
1408
1409    self.$FindFirstChildByAttribute = FindFirstChildByAttribute;
1410
1411    function FindChildrenByAttribute(elmt, attrValue, attrName, deep) {
1412        if (!attrName)
1413            attrName = "u";
1414
1415        var ret = [];
1416
1417        for (elmt = elmt ? elmt.firstChild : null; elmt; elmt = elmt.nextSibling) {
1418            if (elmt.nodeType == 1) {
1419                if (self.$GetAttributeEx(elmt, attrName) == attrValue)
1420                    ret.push(elmt);
1421
1422                if (deep) {
1423                    var childRet = FindChildrenByAttribute(elmt, attrValue, attrName, deep);
1424                    if (childRet.length)
1425                        ret = ret.concat(childRet);
1426                }
1427            }
1428        }
1429
1430        return ret;
1431    }
1432
1433    self.$FindChildrenByAttribute = FindChildrenByAttribute;
1434
1435    function FindFirstChildByTag(elmt, tagName, deep) {
1436
1437        for (elmt = elmt ? elmt.firstChild : null; elmt; elmt = elmt.nextSibling) {
1438            if (elmt.nodeType == 1) {
1439                if (elmt.tagName == tagName)
1440                    return elmt;
1441
1442                if (deep) {
1443                    var childRet = FindFirstChildByTag(elmt, tagName, deep);
1444                    if (childRet)
1445                        return childRet;
1446                }
1447            }
1448        }
1449    }
1450
1451    self.$FindFirstChildByTag = FindFirstChildByTag;
1452
1453    function FindChildrenByTag(elmt, tagName, deep) {
1454        var ret = [];
1455
1456        for (elmt = elmt ? elmt.firstChild : null; elmt; elmt = elmt.nextSibling) {
1457            if (elmt.nodeType == 1) {
1458                if (!tagName || elmt.tagName == tagName)
1459                    ret.push(elmt);
1460
1461                if (deep) {
1462                    var childRet = FindChildrenByTag(elmt, tagName, true);
1463                    if (childRet.length)
1464                        ret = ret.concat(childRet);
1465                }
1466            }
1467        }
1468
1469        return ret;
1470    }
1471
1472    self.$FindChildrenByTag = FindChildrenByTag;
1473
1474    self.$GetElementsByTagName = function (elmt, tagName) {
1475        return elmt.getElementsByTagName(tagName);
1476    };
1477
1478    self.$Extend = function (target) {
1479        for (var i = 1; i < arguments.length; i++) {
1480
1481            var options = arguments[i];
1482
1483            // Only deal with non-null/undefined values
1484            if (options) {
1485                // Extend the base object
1486                for (var name in options) {
1487                    target[name] = options[name];
1488                }
1489            }
1490        }
1491
1492        // Return the modified object
1493        return target;
1494    };
1495
1496    self.$Unextend = function (target, options) {
1497        $JssorDebug$.$Assert(options);
1498
1499        var unextended = {};
1500
1501        // Extend the base object
1502        for (var name in target) {
1503            if (target[name] != options[name]) {
1504                unextended[name] = target[name];
1505            }
1506        }
1507
1508        // Return the modified object
1509        return unextended;
1510    };
1511
1512    self.$IsUndefined = function (obj) {
1513        return type(obj) == "undefined";
1514    };
1515
1516    self.$IsFunction = function (obj) {
1517        return type(obj) == "function";
1518    };
1519
1520    self.$IsArray = Array.isArray || function (obj) {
1521        return type(obj) == "array";
1522    };
1523
1524    self.$IsString = function (obj) {
1525        return type(obj) == "string";
1526    };
1527
1528    self.$IsNumeric = function (obj) {
1529        return !isNaN(parseFloat(obj)) && isFinite(obj);
1530    };
1531
1532    self.$IsWindow = function (obj) {
1533        return obj != null && obj == obj.window;
1534    };
1535
1536    self.$Type = type;
1537
1538    // args is for internal usage only
1539    self.$Each = each;
1540
1541    self.$IsPlainObject = isPlainObject;
1542
1543    self.$CreateDivElement = function (doc) {
1544        return self.$CreateElement("DIV", doc);
1545    };
1546
1547    self.$CreateSpanElement = function (doc) {
1548        return self.$CreateElement("SPAN", doc);
1549    };
1550
1551    self.$CreateElement = function (tagName, doc) {
1552        doc = doc || document;
1553        return doc.createElement(tagName);
1554    };
1555
1556    self.$EmptyFunction = function () { };
1557
1558    self.$GetAttribute = function (elmt, name) {
1559        return elmt.getAttribute(name);
1560    };
1561
1562    self.$GetAttributeEx = function (elmt, name) {
1563        return self.$GetAttribute(elmt, name) || self.$GetAttribute(elmt, "data-" + name);
1564    };
1565
1566    self.$SetAttribute = function (elmt, name, value) {
1567        elmt.setAttribute(name, value);
1568    };
1569
1570    self.$GetClassName = function (elmt) {
1571        return elmt.className;
1572    };
1573
1574    self.$SetClassName = function (elmt, className) {
1575        elmt.className = className || "";
1576    };
1577
1578    self.$GetParentNode = function (elmt) {
1579        return elmt.parentNode;
1580    };
1581
1582    self.$HideElement = function (elmt) {
1583        self.$CssDisplay(elmt, "none");
1584    };
1585
1586    self.$HideElements = function (elmts) {
1587        for (var i = 0; i < elmts.length; i++) {
1588            self.$HideElement(elmts[i]);
1589        }
1590    };
1591
1592    self.$ShowElement = function (elmt, show) {
1593        self.$CssDisplay(elmt, show == false ? "none" : "");
1594    };
1595
1596    self.$ShowElements = function (elmts) {
1597        for (var i = 0; i < elmts.length; i++) {
1598            self.$ShowElement(elmts[i]);
1599        }
1600    };
1601
1602    self.$RemoveAttribute = function (elmt, attrbuteName) {
1603        elmt.removeAttribute(attrbuteName);
1604    };
1605
1606    self.$CanClearClip = function () {
1607        //return !IsBrowserIE() || browserEngineVersion > 9 || (browserRuntimeVersion > 7 && !IsBrowserIeQuirks());
1608        return IsBrowserIE() && browserRuntimeVersion < 10;
1609    };
1610
1611    self.$SetStyleClip = function (elmt, clip) {
1612        if (clip) {
1613            elmt.style.clip = "rect(" + Math.round(clip.$Top) + "px " + Math.round(clip.$Right) + "px " + Math.round(clip.$Bottom) + "px " + Math.round(clip.$Left) + "px)";
1614        }
1615        else {
1616            var cssText = elmt.style.cssText;
1617            var clipRegs = [
1618                new RegExp(/[\s]*clip: rect\(.*?\)[;]?/i),
1619                new RegExp(/[\s]*cliptop: .*?[;]?/i),
1620                new RegExp(/[\s]*clipright: .*?[;]?/i),
1621                new RegExp(/[\s]*clipbottom: .*?[;]?/i),
1622                new RegExp(/[\s]*clipleft: .*?[;]?/i)
1623            ];
1624
1625            var newCssText = BuildNewCss(cssText, clipRegs, "");
1626
1627            $JssorUtils$.$CssCssText(elmt, newCssText);
1628        }
1629    };
1630
1631    self.$GetNow = function () {
1632        return new Date().getTime();
1633    };
1634
1635    self.$AppendChild = function (elmt, child) {
1636        elmt.appendChild(child);
1637    };
1638
1639    self.$AppendChildren = function (elmt, children) {
1640        each(children, function (child) {
1641            self.$AppendChild(elmt, child);
1642        });
1643    };
1644
1645    self.$InsertBefore = function (elmt, child, refObject) {
1646        elmt.insertBefore(child, refObject);
1647    };
1648
1649    self.$InsertAdjacentHtml = function (elmt, where, text) {
1650        elmt.insertAdjacentHTML(where, text);
1651    };
1652
1653    self.$RemoveChild = function (elmt, child) {
1654        elmt.removeChild(child);
1655    };
1656
1657    self.$RemoveChildren = function (elmt, children) {
1658        each(children, function (child) {
1659            self.$RemoveChild(elmt, child);
1660        });
1661    };
1662
1663    self.$ClearChildren = function (elmt) {
1664        self.$RemoveChildren(elmt, self.$GetChildren(elmt));
1665    };
1666
1667    self.$ParseInt = function (str, radix) {
1668        return parseInt(str, radix || 10);
1669    };
1670
1671    self.$ParseFloat = function (str) {
1672        return parseFloat(str);
1673    };
1674
1675    self.$IsChild = function (elmtA, elmtB) {
1676        var body = document.body;
1677        while (elmtB && elmtA != elmtB && body != elmtB) {
1678            try {
1679                elmtB = elmtB.parentNode;
1680            } catch (e) {
1681                // Firefox sometimes fires events for XUL elements, which throws
1682                // a "permission denied" error. so this is not a child.
1683                return false;
1684            }
1685        }
1686        return elmtA == elmtB;
1687    };
1688
1689    self.$ToLowerCase = function (value) {
1690        if (value)
1691            value = value.toLowerCase();
1692
1693        return value;
1694    };
1695
1696    self.$CloneNode = function (elmt, deep) {
1697        return elmt.cloneNode(deep);
1698    };
1699
1700    function LoadImageCallback(callback, image, abort) {
1701        image.onload = null;
1702        image.abort = null;
1703
1704        if (callback)
1705            callback(image, abort);
1706    }
1707
1708    self.$LoadImage = function (src, callback) {
1709        if (self.$IsBrowserOpera() && browserRuntimeVersion < 11.6 || !src) {
1710            LoadImageCallback(callback, null);
1711        }
1712        else {
1713            var image = new Image();
1714            image.onload = self.$CreateCallback(null, LoadImageCallback, callback, image);
1715            image.onabort = self.$CreateCallback(null, LoadImageCallback, callback, image, true);
1716            image.src = src;
1717        }
1718    };
1719
1720    self.$LoadImages = function (imageElmts, mainImageElmt, callback) {
1721
1722        var _ImageLoading = imageElmts.length + 1;
1723
1724        function LoadImageCompleteEventHandler(image, abort) {
1725            _ImageLoading--;
1726            if (mainImageElmt && image && image.src == mainImageElmt.src)
1727                mainImageElmt = image;
1728            !_ImageLoading && callback && callback(mainImageElmt);
1729        }
1730
1731        $JssorUtils$.$Each(imageElmts, function (imageElmt) {
1732            $JssorUtils$.$LoadImage(imageElmt.src, LoadImageCompleteEventHandler);
1733        });
1734
1735        LoadImageCompleteEventHandler();
1736    };
1737
1738    self.$BuildElement = function (template, tagName, replacer, createCopy) {
1739        if (createCopy)
1740            template = $JssorUtils$.$CloneNode(template, true);
1741
1742        var templateHolders = $JssorUtils$.$GetElementsByTagName(template, tagName);
1743        for (var j = templateHolders.length - 1; j > -1; j--) {
1744            var templateHolder = templateHolders[j];
1745            var replaceItem = $JssorUtils$.$CloneNode(replacer, true);
1746            $JssorUtils$.$SetClassName(replaceItem, $JssorUtils$.$GetClassName(templateHolder));
1747            $JssorUtils$.$CssCssText(replaceItem, templateHolder.style.cssText);
1748
1749            var thumbnailPlaceHolderParent = $JssorUtils$.$GetParentNode(templateHolder);
1750            $JssorUtils$.$InsertBefore(thumbnailPlaceHolderParent, replaceItem, templateHolder);
1751            $JssorUtils$.$RemoveChild(thumbnailPlaceHolderParent, templateHolder);
1752        }
1753
1754        return template;
1755    };
1756
1757    var _MouseDownButtons;
1758    var _MouseOverButtons = [];
1759    function JssorButtonEx(elmt) {
1760        var _Self = this;
1761
1762        var _OriginClassName;
1763
1764        var _IsMouseDown;   //class name 'dn'
1765        var _IsActive;      //class name 'av'
1766
1767        function Highlight() {
1768            var className = _OriginClassName;
1769
1770            if (_IsMouseDown) {
1771                className += 'dn';
1772            }
1773            else if (_IsActive) {
1774                className += "av";
1775            }
1776
1777            $JssorUtils$.$SetClassName(elmt, className);
1778        }
1779
1780        function OnMouseDown(event) {
1781            _MouseDownButtons.push(_Self);
1782
1783            _IsMouseDown = true;
1784
1785            Highlight();
1786        }
1787
1788        _Self.$MouseUp = function () {
1789            ///	<summary>
1790            ///		Internal member function, do not use it.
1791            ///	</summary>
1792            ///	<private />
1793
1794            _IsMouseDown = false;
1795
1796            Highlight();
1797        };
1798
1799        _Self.$Activate = function (activate) {
1800            _IsActive = activate;
1801
1802            Highlight();
1803        };
1804
1805        //JssorButtonEx Constructor
1806        {
1807            elmt = self.$GetElement(elmt);
1808
1809            if (!_MouseDownButtons) {
1810                self.$AddEventBrowserMouseUp(function () {
1811                    var oldMouseDownButtons = _MouseDownButtons;
1812                    _MouseDownButtons = [];
1813
1814                    each(oldMouseDownButtons, function (button) {
1815                        button.$MouseUp();
1816                    });
1817                });
1818
1819                _MouseDownButtons = [];
1820            }
1821
1822            _OriginClassName = self.$GetClassName(elmt);
1823
1824            $JssorUtils$.$AddEvent(elmt, "mousedown", OnMouseDown);
1825        }
1826    }
1827
1828    self.$Buttonize = function (elmt) {
1829        return new JssorButtonEx(elmt);
1830    };
1831
1832    self.$Css = Css;
1833    self.$CssN = CssN;
1834    self.$CssP = CssP;
1835
1836    self.$CssOverflow = CssProxy("overflow");
1837
1838    self.$CssTop = CssProxy("top", 2);
1839    self.$CssLeft = CssProxy("left", 2);
1840    self.$CssWidth = CssProxy("width", 2);
1841    self.$CssHeight = CssProxy("height", 2);
1842    self.$CssMarginLeft = CssProxy("marginLeft", 2);
1843    self.$CssMarginTop = CssProxy("marginTop", 2);
1844    self.$CssPosition = CssProxy("position");
1845    self.$CssDisplay = CssProxy("display");
1846    self.$CssZIndex = CssProxy("zIndex", 1);
1847    self.$CssFloat = function (elmt, float) {
1848        return Css(elmt, IsBrowserIE() ? "styleFloat" : "cssFloat", float);
1849    };
1850    self.$CssOpacity = function (elmt, opacity, ie9EarlierForce) {
1851        if (opacity != undefined) {
1852            SetStyleOpacity(elmt, opacity, ie9EarlierForce);
1853        }
1854        else {
1855            return GetStyleOpacity(elmt);
1856        }
1857    };
1858    self.$CssCssText = function (elmt, text) {
1859        if (text != undefined) {
1860            elmt.style.cssText = text;
1861        }
1862        else {
1863            return elmt.style.cssText;
1864        }
1865    };
1866
1867    var _StyleGetter = {
1868        $Opacity: self.$CssOpacity,
1869        $Top: self.$CssTop,
1870        $Left: self.$CssLeft,
1871        $Width: self.$CssWidth,
1872        $Height: self.$CssHeight,
1873        $Position: self.$CssPosition,
1874        $Display: self.$CssDisplay,
1875        $ZIndex: self.$CssZIndex
1876    };
1877
1878    //var _StyleGetter = {
1879    //    $Opacity: self.$GetStyleOpacity,
1880    //    $Top: self.$GetStyleTop,
1881    //    $Left: self.$GetStyleLeft,
1882    //    $Width: self.$GetStyleWidth,
1883    //    $Height: self.$GetStyleHeight,
1884    //    $Position: self.$GetStylePosition,
1885    //    $Display: self.$GetStyleDisplay,
1886    //    $ZIndex: self.$GetStyleZIndex
1887    //};
1888
1889    var _StyleSetterReserved;
1890
1891    //var _StyleSetterReserved = {
1892    //    $Opacity: self.$SetStyleOpacity,
1893    //    $Top: self.$SetStyleTop,
1894    //    $Left: self.$SetStyleLeft,
1895    //    $Width: self.$SetStyleWidth,
1896    //    $Height: self.$SetStyleHeight,
1897    //    $Display: self.$SetStyleDisplay,
1898    //    $Clip: self.$SetStyleClip,
1899    //    $MarginLeft: self.$SetStyleMarginLeft,
1900    //    $MarginTop: self.$SetStyleMarginTop,
1901    //    $Transform: self.$SetStyleTransform,
1902    //    $Position: self.$SetStylePosition,
1903    //    $ZIndex: self.$SetStyleZIndex
1904    //};
1905
1906    function GetStyleSetter() {
1907        if (!_StyleSetterReserved) {
1908            _StyleSetterReserved = self.$Extend({
1909                $MarginTop: self.$CssMarginTop,
1910                $MarginLeft: self.$CssMarginLeft,
1911                $Clip: self.$SetStyleClip,
1912                $Transform: self.$SetStyleTransform
1913            }, _StyleGetter);
1914        }
1915        return _StyleSetterReserved;
1916    }
1917
1918    function GetStyleSetterEx() {
1919        GetStyleSetter();
1920
1921        //For Compression Only
1922        _StyleSetterReserved.$Transform = _StyleSetterReserved.$Transform;
1923
1924        return _StyleSetterReserved;
1925    }
1926
1927    self.$GetStyleSetter = GetStyleSetter;
1928
1929    self.$GetStyleSetterEx = GetStyleSetterEx;
1930
1931    self.$GetStyles = function (elmt, originStyles) {
1932        GetStyleSetter();
1933
1934        var styles = {};
1935
1936        each(originStyles, function (value, key) {
1937            if (_StyleGetter[key]) {
1938                styles[key] = _StyleGetter[key](elmt);
1939            }
1940        });
1941
1942        return styles;
1943    };
1944
1945    self.$SetStyles = function (elmt, styles) {
1946        var styleSetter = GetStyleSetter();
1947
1948        each(styles, function (value, key) {
1949            styleSetter[key] && styleSetter[key](elmt, value);
1950        });
1951    };
1952
1953    self.$SetStylesEx = function (elmt, styles) {
1954        GetStyleSetterEx();
1955
1956        self.$SetStyles(elmt, styles);
1957    };
1958
1959    $JssorMatrix$ = new function () {
1960        var _This = this;
1961
1962        function Multiply(ma, mb) {
1963            var acs = ma[0].length;
1964            var rows = ma.length;
1965            var cols = mb[0].length;
1966
1967            var matrix = [];
1968
1969            for (var r = 0; r < rows; r++) {
1970                var row = matrix[r] = [];
1971                for (var c = 0; c < cols; c++) {
1972                    var unitValue = 0;
1973
1974                    for (var ac = 0; ac < acs; ac++) {
1975                        unitValue += ma[r][ac] * mb[ac][c];
1976                    }
1977
1978                    row[c] = unitValue;
1979                }
1980            }
1981
1982            return matrix;
1983        }
1984
1985        _This.$ScaleX = function (matrix, sx) {
1986            return _This.$ScaleXY(matrix, sx, 0);
1987        };
1988
1989        _This.$ScaleY = function (matrix, sy) {
1990            return _This.$ScaleXY(matrix, 0, sy);
1991        };
1992
1993        _This.$ScaleXY = function (matrix, sx, sy) {
1994            return Multiply(matrix, [[sx, 0], [0, sy]]);
1995        };
1996
1997        _This.$TransformPoint = function (matrix, p) {
1998            var pMatrix = Multiply(matrix, [[p.x], [p.y]]);
1999
2000            return new $JssorPoint$(pMatrix[0][0], pMatrix[1][0]);
2001        };
2002    };
2003
2004    self.$CreateMatrix = function (alpha, scaleX, scaleY) {
2005        var cos = Math.cos(alpha);
2006        var sin = Math.sin(alpha);
2007        //var r11 = cos;
2008        //var r21 = sin;
2009        //var r12 = -sin;
2010        //var r22 = cos;
2011
2012        //var m11 = cos * scaleX;
2013        //var m12 = -sin * scaleY;
2014        //var m21 = sin * scaleX;
2015        //var m22 = cos * scaleY;
2016
2017        return [[cos * scaleX, -sin * scaleY], [sin * scaleX, cos * scaleY]];
2018    };
2019
2020    self.$GetMatrixOffset = function (matrix, width, height) {
2021        var p1 = $JssorMatrix$.$TransformPoint(matrix, new $JssorPoint$(-width / 2, -height / 2));
2022        var p2 = $JssorMatrix$.$TransformPoint(matrix, new $JssorPoint$(width / 2, -height / 2));
2023        var p3 = $JssorMatrix$.$TransformPoint(matrix, new $JssorPoint$(width / 2, height / 2));
2024        var p4 = $JssorMatrix$.$TransformPoint(matrix, new $JssorPoint$(-width / 2, height / 2));
2025
2026        return new $JssorPoint$(Math.min(p1.x, p2.x, p3.x, p4.x) + width / 2, Math.min(p1.y, p2.y, p3.y, p4.y) + height / 2);
2027    };
2028};
2029
2030$JssorAnimator$ = function (delay, duration, options, elmt, fromStyles, toStyles) {
2031    delay = delay || 0;
2032
2033    var _This = this;
2034    var _AutoPlay;
2035    var _Hiden;
2036    var _CombineMode;
2037    var _PlayToPosition;
2038    var _PlayDirection;
2039    var _NoStop;
2040    var _TimeStampLastFrame = 0;
2041
2042    var _SubEasings;
2043    var _SubRounds;
2044    var _SubDurings;
2045    var _Callback;
2046
2047    var _Position_Current = 0;
2048    var _Position_Display = 0;
2049    var _Hooked;
2050
2051    var _Position_InnerBegin = delay;
2052    var _Position_InnerEnd = delay + duration;
2053    var _Position_OuterBegin;
2054    var _Position_OuterEnd;
2055    var _LoopLength;
2056
2057    var _NestedAnimators = [];
2058    var _StyleSetter;
2059
2060    function GetPositionRange(position, begin, end) {
2061        var range = 0;
2062
2063        if (position < begin)
2064            range = -1;
2065
2066        else if (position > end)
2067            range = 1;
2068
2069        return range;
2070    }
2071
2072    function GetInnerPositionRange(position) {
2073        return GetPositionRange(position, _Position_InnerBegin, _Position_InnerEnd);
2074    }
2075
2076    function GetOuterPositionRange(position) {
2077        return GetPositionRange(position, _Position_OuterBegin, _Position_OuterEnd);
2078    }
2079
2080    function Shift(offset) {
2081        _Position_OuterBegin += offset;
2082        _Position_OuterEnd += offset;
2083        _Position_InnerBegin += offset;
2084        _Position_InnerEnd += offset;
2085
2086        _Position_Current += offset;
2087        _Position_Display += offset;
2088
2089        $JssorUtils$.$Each(_NestedAnimators, function (animator) {
2090            animator, animator.$Shift(offset);
2091        });
2092    }
2093
2094    function Locate(position, relative) {
2095        var offset = position - _Position_OuterBegin + delay * relative;
2096
2097        Shift(offset);
2098
2099        //$JssorDebug$.$Execute(function () {
2100        //    _This.$Position_InnerBegin = _Position_InnerBegin;
2101        //    _This.$Position_InnerEnd = _Position_InnerEnd;
2102        //    _This.$Position_OuterBegin = _Position_OuterBegin;
2103        //    _This.$Position_OuterEnd = _Position_OuterEnd;
2104        //});
2105
2106        return _Position_OuterEnd;
2107    }
2108
2109    function GoToPosition(positionOuter, force) {
2110        var trimedPositionOuter = positionOuter;
2111
2112        if (_LoopLength && (trimedPositionOuter >= _Position_OuterEnd || trimedPositionOuter <= _Position_OuterBegin)) {
2113            trimedPositionOuter = ((trimedPositionOuter - _Position_OuterBegin) % _LoopLength + _LoopLength) % _LoopLength + _Position_OuterBegin;
2114        }
2115
2116        if (!_Hooked || _NoStop || force || _Position_Current != trimedPositionOuter) {
2117
2118            var positionToDisplay = Math.min(trimedPositionOuter, _Position_OuterEnd);
2119            positionToDisplay = Math.max(positionToDisplay, _Position_OuterBegin);
2120
2121            if (!_Hooked || _NoStop || force || positionToDisplay != _Position_Display) {
2122                if (toStyles) {
2123                    var currentStyles = toStyles;
2124
2125                    if (fromStyles) {
2126                        var interPosition = (positionToDisplay - _Position_InnerBegin) / (duration || 1);
2127                        if (options.$Optimize && $JssorUtils$.$IsBrowserChrome() && duration)
2128                            interPosition = Math.round(interPosition * duration / 16) / duration * 16;
2129                        if (options.$Reverse)
2130                            interPosition = 1 - interPosition;
2131
2132                        currentStyles = {};
2133
2134                        for (var key in toStyles) {
2135                            var round = _SubRounds[key] || 1;
2136                            var during = _SubDurings[key] || [0, 1];
2137                            var propertyInterPosition = (interPosition - during[0]) / during[1];
2138                            propertyInterPosition = Math.min(Math.max(propertyInterPosition, 0), 1);
2139                            propertyInterPosition = propertyInterPosition * round;
2140                            var floorPosition = Math.floor(propertyInterPosition);
2141                            if (propertyInterPosition != floorPosition)
2142                                propertyInterPosition -= floorPosition;
2143
2144                            var easing = _SubEasings[key] || _SubEasings.$Default;
2145                            var easingValue = easing(propertyInterPosition);
2146                            var currentPropertyValue;
2147                            var value = fromStyles[key];
2148                            var toValue = toStyles[key];
2149
2150                            if ($JssorUtils$.$IsNumeric(toValue)) {
2151                                currentPropertyValue = value + (toValue - value) * easingValue;
2152                            }
2153                            else {
2154                                currentPropertyValue = $JssorUtils$.$Extend({ $Offset: {} }, fromStyles[key]);
2155
2156                                $JssorUtils$.$Each(toValue.$Offset, function (rectX, n) {
2157                                    var offsetValue = rectX * easingValue;
2158                                    currentPropertyValue.$Offset[n] = offsetValue;
2159                                    currentPropertyValue[n] += offsetValue;
2160                                });
2161                            }
2162                            currentStyles[key] = currentPropertyValue;
2163                        }
2164                    }
2165
2166                    if (fromStyles.$Zoom) {
2167                        currentStyles.$Transform = { $Rotate: currentStyles.$Rotate || 0, $Scale: currentStyles.$Zoom, $OriginalWidth: options.$OriginalWidth, $OriginalHeight: options.$OriginalHeight };
2168                    }
2169
2170                    if (toStyles.$Clip && options.$Move) {
2171                        var styleFrameNClipOffset = currentStyles.$Clip.$Offset;
2172
2173                        var offsetY = (styleFrameNClipOffset.$Top || 0) + (styleFrameNClipOffset.$Bottom || 0);
2174                        var offsetX = (styleFrameNClipOffset.$Left || 0) + (styleFrameNClipOffset.$Right || 0
2174);
2175
2176                        currentStyles.$Left = (currentStyles.$Left || 0) + offsetX;
2177                        currentStyles.$Top = (currentStyles.$Top || 0) + offsetY;
2178                        currentStyles.$Clip.$Left -= offsetX;
2179                        currentStyles.$Clip.$Right -= offsetX;
2180                        currentStyles.$Clip.$Top -= offsetY;
2181                        currentStyles.$Clip.$Bottom -= offsetY;
2182                    }
2183
2184                    if (currentStyles.$Clip && $JssorUtils$.$CanClearClip() && !currentStyles.$Clip.$Top && !currentStyles.$Clip.$Left && (currentStyles.$Clip.$Right == options.$OriginalWidth) && (currentStyles.$Clip.$Bottom == options.$OriginalHeight))
2185                        currentStyles.$Clip = null;
2186
2187                    $JssorUtils$.$Each(currentStyles, function (value, key) {
2188                        _StyleSetter[key] && _StyleSetter[key](elmt, value);
2189                    });
2190                }
2191
2192                _This.$OnInnerOffsetChange(_Position_Display - _Position_InnerBegin, positionToDisplay - _Position_InnerBegin);
2193            }
2194
2195            _Position_Display = positionToDisplay;
2196
2197            $JssorUtils$.$Each(_NestedAnimators, function (animator, i) {
2198                var nestedAnimator = positionOuter < _Position_Current ? _NestedAnimators[_NestedAnimators.length - i - 1] : animator;
2199                nestedAnimator.$GoToPosition(positionOuter, force);
2200            });
2201
2202            var positionOld = _Position_Current;
2203            var positionNew = positionOuter;
2204
2205            _Position_Current = trimedPositionOuter;
2206            _Hooked = true;
2207
2208            _This.$OnPositionChange(positionOld, positionNew);
2209        }
2210    }
2211
2212    function Join(animator, combineMode) {
2213        ///	<summary>
2214        ///		Combine another animator as nested animator
2215        ///	</summary>
2216        ///	<param name="animator" type="$JssorAnimator$">
2217        ///		An instance of $JssorAnimator$
2218        ///	</param>
2219        ///	<param name="combineMode" type="int">
2220        ///		0: parallel - place the animator parallel to this animator.
2221        ///		1: chain - chain the animator at the _Position_InnerEnd of this animator.
2222        ///	</param>
2223        $JssorDebug$.$Execute(function () {
2224            if (combineMode !== 0 && combineMode !== 1)
2225                $JssorDebug$.$Fail("Argument out of range, the value of 'combineMode' should be either 0 or 1.");
2226        });
2227
2228        if (combineMode)
2229            animator.$Locate(_Position_OuterEnd, 1);
2230
2231        _Position_OuterEnd = Math.max(_Position_OuterEnd, animator.$GetPosition_OuterEnd());
2232        _NestedAnimators.push(animator);
2233    }
2234
2235    function PlayFrame() {
2236        if (_AutoPlay) {
2237            var now = $JssorUtils$.$GetNow();
2238            var timeOffset = Math.min(now - _TimeStampLastFrame, $JssorUtils$.$IsBrowserOpera() ? 80 : 20);
2239            var timePosition = _Position_Current + timeOffset * _PlayDirection;
2240            _TimeStampLastFrame = now;
2241
2242            if (timePosition * _PlayDirection >= _PlayToPosition * _PlayDirection)
2243                timePosition = _PlayToPosition;
2244
2245            GoToPosition(timePosition);
2246
2247            if (!_NoStop && timePosition * _PlayDirection >= _PlayToPosition * _PlayDirection) {
2248                Stop(_Callback);
2249            }
2250            else {
2251                $JssorUtils$.$Delay(PlayFrame, options.$Interval);
2252            }
2253        }
2254    }
2255
2256    function PlayToPosition(toPosition, callback, noStop) {
2257        if (!_AutoPlay) {
2258            _AutoPlay = true;
2259            _NoStop = noStop
2260            _Callback = callback;
2261            toPosition = Math.max(toPosition, _Position_OuterBegin);
2262            toPosition = Math.min(toPosition, _Position_OuterEnd);
2263            _PlayToPosition = toPosition;
2264            _PlayDirection = _PlayToPosition < _Position_Current ? -1 : 1;
2265            _This.$OnStart();
2266            _TimeStampLastFrame = $JssorUtils$.$GetNow();
2267            PlayFrame();
2268        }
2269    }
2270
2271    function Stop(callback) {
2272        if (_AutoPlay) {
2273            _NoStop = _AutoPlay = _Callback = false;
2274            _This.$OnStop();
2275
2276            if (callback)
2277                callback();
2278        }
2279    }
2280
2281    _This.$Play = function (positionLength, callback, noStop) {
2282        PlayToPosition(positionLength ? _Position_Current + positionLength : _Position_OuterEnd, callback, noStop);
2283    };
2284
2285    _This.$PlayToPosition = function (position, callback, noStop) {
2286        PlayToPosition(position, callback, noStop);
2287    };
2288
2289    _This.$PlayToBegin = function (callback, noStop) {
2290        PlayToPosition(_Position_OuterBegin, callback, noStop);
2291    };
2292
2293    _This.$PlayToEnd = function (callback, noStop) {
2294        PlayToPosition(_Position_OuterEnd, callback, noStop);
2295    };
2296
2297    _This.$Stop = function () {
2298        Stop();
2299    };
2300
2301    _This.$Continue = function (toPosition) {
2302        PlayToPosition(toPosition);
2303    };
2304
2305    _This.$GetPosition = function () {
2306        return _Position_Current;
2307    };
2308
2309    _This.$GetPlayToPosition = function () {
2310        return _PlayToPosition;
2311    };
2312
2313    _This.$GetPosition_Display = function () {
2314        return _Position_Display;
2315    };
2316
2317    _This.$GoToPosition = GoToPosition;
2318
2319    _This.$GoToBegin = function () {
2320        GoToPosition(_Position_OuterBegin, true);
2321    };
2322
2323    _This.$GoToEnd = function () {
2324        GoToPosition(_Position_OuterEnd, true);
2325    };
2326
2327    _This.$Move = function (offset) {
2328        GoToPosition(_Position_Current + offset);
2329    };
2330
2331    _This.$CombineMode = function () {
2332        return _CombineMode;
2333    };
2334
2335    _This.$GetDuration = function () {
2336        return duration;
2337    };
2338
2339    _This.$IsPlaying = function () {
2340        return _AutoPlay;
2341    };
2342
2343    _This.$IsOnTheWay = function () {
2344        return _Position_Current > _Position_InnerBegin && _Position_Current <= _Position_InnerEnd;
2345    };
2346
2347    _This.$SetLoopLength = function (length) {
2348        _LoopLength = length;
2349    };
2350
2351    _This.$Locate = Locate;
2352
2353    _This.$Shift = Shift;
2354
2355    _This.$Join = Join;
2356
2357    _This.$Combine = function (animator) {
2358        ///	<summary>
2359        ///		Combine another animator parallel to this animator
2360        ///	</summary>
2361        ///	<param name="animator" type="$JssorAnimator$">
2362        ///		An instance of $JssorAnimator$
2363        ///	</param>
2364        Join(animator, 0);
2365    };
2366
2367    _This.$Chain = function (animator) {
2368        ///	<summary>
2369        ///		Chain another animator at the _Position_InnerEnd of this animator
2370        ///	</summary>
2371        ///	<param name="animator" type="$JssorAnimator$">
2372        ///		An instance of $JssorAnimator$
2373        ///	</param>
2374        Join(animator, 1);
2375    };
2376
2377    _This.$GetPosition_InnerBegin = function () {
2378        ///	<summary>
2379        ///		Internal member function, do not use it.
2380        ///	</summary>
2381        ///	<private />
2382        ///	<returns type="int" />
2383        return _Position_InnerBegin;
2384    };
2385
2386    _This.$GetPosition_InnerEnd = function () {
2387        ///	<summary>
2388        ///		Internal member function, do not use it.
2389        ///	</summary>
2390        ///	<private />
2391        ///	<returns type="int" />
2392        return _Position_InnerEnd;
2393    };
2394
2395    _This.$GetPosition_OuterBegin = function () {
2396        ///	<summary>
2397        ///		Internal member function, do not use it.
2398        ///	</summary>
2399        ///	<private />
2400        ///	<returns type="int" />
2401        return _Position_OuterBegin;
2402    };
2403
2404    _This.$GetPosition_OuterEnd = function () {
2405        ///	<summary>
2406        ///		Internal member function, do not use it.
2407        ///	</summary>
2408        ///	<private />
2409        ///	<returns type="int" />
2410        return _Position_OuterEnd;
2411    };
2412
2413    _This.$OnPositionChange = $JssorUtils$.$EmptyFunction;
2414    _This.$OnStart = $JssorUtils$.$EmptyFunction;
2415    _This.$OnStop = $JssorUtils$.$EmptyFunction;
2416    _This.$OnInnerOffsetChange = $JssorUtils$.$EmptyFunction;
2417    _This.$Version = $JssorUtils$.$GetNow();
2418
2419    //Constructor`  1
2420    {
2421        options = $JssorUtils$.$Extend({
2422            $Interval: 16
2423        }, options);
2424
2425        //Sodo statement, for development time intellisence only
2426        $JssorDebug$.$Execute(function () {
2427            options = $JssorUtils$.$Extend({
2428                $LoopLength: undefined,
2429                $Setter: undefined,
2430                $Easing: undefined
2431            }, options);
2432        });
2433
2434        _LoopLength = options.$LoopLength;
2435
2436        _StyleSetter = $JssorUtils$.$Extend({}, $JssorUtils$.$GetStyleSetter(), options.$Setter);
2437
2438        _Position_OuterBegin = _Position_InnerBegin = delay;
2439        _Position_OuterEnd = _Position_InnerEnd = delay + duration;
2440
2441        var _SubRounds = options.$Round || {};
2442        var _SubDurings = options.$During || {};
2443        _SubEasings = $JssorUtils$.$Extend({ $Default: $JssorUtils$.$IsFunction(options.$Easing) && options.$Easing || $JssorEasing$.$EaseSwing }, options.$Easing);
2444    }
2445};
2446
2447function $JssorPlayerClass$() {
2448
2449    var _SelfPlayer = this;
2450    var _PlayerControllers = [];
2451
2452    function PlayerController(playerElement) {
2453        var _SelfPlayerController = this;
2454        var _PlayerInstance;
2455        var _PlayerInstantces = [];
2456
2457        function OnPlayerInstanceDataAvailable(event) {
2458            var srcElement = $JssorUtils$.$GetEventSrcElement(event);
2459            _PlayerInstance = srcElement.pInstance;
2460
2461            $JssorUtils$.$RemoveEvent(srcElement, "dataavailable", OnPlayerInstanceDataAvailable);
2462            $JssorUtils$.$Each(_PlayerInstantces, function (playerInstance) {
2463                if (playerInstance != _PlayerInstance) {
2464                    playerInstance.$Remove();
2465                }
2466            });
2467
2468            playerElement.pTagName = _PlayerInstance.tagName;
2469            _PlayerInstantces = null;
2470        }
2471
2472        function HandlePlayerInstance(playerInstanceElement) {
2473            var playerHandler;
2474
2475            if (!playerInstanceElement.pInstance) {
2476                var playerHandlerAttribute = $JssorUtils$.$GetAttributeEx(playerInstanceElement, "pHandler");
2477
2478                if ($JssorPlayer$[playerHandlerAttribute]) {
2479                    $JssorUtils$.$AddEvent(playerInstanceElement, "dataavailable", OnPlayerInstanceDataAvailable);
2480                    playerHandler = new $JssorPlayer$[playerHandlerAttribute](playerElement, playerInstanceElement);
2481                    _PlayerInstantces.push(playerHandler);
2482
2483                    $JssorDebug$.$Execute(function () {
2484                        if ($JssorUtils$.$Type(playerHandler.$Remove) != "function") {
2485                            $JssorDebug$.$Fail("'pRemove' interface not implemented for player handler '" + playerHandlerAttribute + "'.");
2486                        }
2487                    });
2488                }
2489            }
2490
2491            return playerHandler;
2492        }
2493
2494        _SelfPlayerController.$InitPlayerController = function () {
2495            if (!playerElement.pInstance && !HandlePlayerInstance(playerElement)) {
2496
2497                var playerInstanceElements = $JssorUtils$.$GetChildren(playerElement);
2498
2499                $JssorUtils$.$Each(playerInstanceElements, function (playerInstanceElement) {
2500                    HandlePlayerInstance(playerInstanceElement);
2501                });
2502            }
2503        };
2504    }
2505
2506    _SelfPlayer.$EVT_SWITCH = 21;
2507
2508    _SelfPlayer.$FetchPlayers = function (elmt) {
2509        elmt = elmt || document.body;
2510
2511        var playerElements = $JssorUtils$.$FindChildrenByAttribute(elmt, "player", null, true);
2512
2513        $JssorUtils$.$Each(playerElements, function (playerElement) {
2514            if (!_PlayerControllers[playerElement.pId]) {
2515                playerElement.pId = _PlayerControllers.length;
2516                _PlayerControllers.push(new PlayerController(playerElement));
2517            }
2518            var playerController = _PlayerControllers[playerElement.pId];
2519            playerController.$InitPlayerController();
2520        });
2521    };
2522}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.